microsoft/vscode-react-native

Public

mirrored fromhttps://github.com/microsoft/vscode-react-nativeAvailable

CodeCommitsIssuesPull requestsActionsInsightsSecurity
14ebf4e6fdee5f69a41d9a7deea4dc164dd28b7e

Branches

Tags

  • No tags available.
0Branches0Tags
Go to file
Add file
Code

Clone

HTTPS

Download ZIP

src/common/outputVerifier.ts

82lines · modecode

1// Copyright (c) Microsoft Corporation. All rights reserved.
2// Licensed under the MIT license. See LICENSE file in the project root for details.
3
4import * as Q from "q";
5import {ISpawnResult} from "./node/childProcess";
6
7export type PatternToFailure = {
8 pattern: string | RegExp,
9 message: string
10};
11
12/* This class transforms a spawn process to only succeed if all defined success patterns
13 are found on stdout, and none of the failure patterns were found on stderr */
14export class OutputVerifier {
15 private generatePatternsForSuccess: () => Q.Promise<string[]>;
16 private generatePatternToFailure: () => Q.Promise<PatternToFailure[]>;
17 private platformName: string;
18
19 private output = "";
20 private errors = "";
21
22 constructor(generatePatternsForSuccess: () => Q.Promise<string[]>, generatePatternToFailure: () => Q.Promise<PatternToFailure[]>, platformName: string) {
23 this.generatePatternsForSuccess = generatePatternsForSuccess;
24 this.generatePatternToFailure = generatePatternToFailure;
25 this.platformName = platformName;
26 }
27
28 public process(spawnResult: ISpawnResult): Q.Promise<void> {
29 // Store all output
30 this.store(spawnResult.stdout, new_content =>
31 this.output += new_content);
32 this.store(spawnResult.stderr, new_content =>
33 this.errors += new_content);
34
35 return spawnResult.outcome // Wait for the process to finish
36 .then(this.generatePatternToFailure) // Generate the failure patterns to check
37 .then(patterns => {
38 const failureMessage = this.findAnyFailurePattern(patterns);
39 if (failureMessage) {
40 return Q.reject<string[]>(new Error(failureMessage)); // If at least one failure happened, we fail
41 } else {
42 return this.generatePatternsForSuccess(); // If not we generate the success patterns
43 }
44 }).then(successPatterns => {
45 if (!this.areAllSuccessPatternsPresent(successPatterns)) { // If we don't find all the success patterns, we also fail
46 const message =
47 `Unknown error: not all success patterns were matched.
48It means that "react-native run-${this.platformName}" command failed. \
49Please, check the View -> Toggle Output -> React Native, \
50View -> Toggle Output -> React Native: Run ${this.platformName} output windows.`;
51 return Q.reject<void>(new Error(message));
52 } // else we found all the success patterns, so we succeed
53 return Q.resolve(void 0);
54 });
55 }
56
57 private store(stream: NodeJS.ReadableStream, append: (new_content: string) => void) {
58 stream.on("data", (data: Buffer) => {
59 append(data.toString());
60 });
61 }
62
63 // We check the failure patterns one by one, to see if any of those appeared on the errors. If they did, we return the associated error
64 private findAnyFailurePattern(patterns: PatternToFailure[]): string | null {
65 const errorsAndOutput = this.errors + this.output;
66 const patternThatAppeared = patterns.find(pattern => {
67 return pattern.pattern instanceof RegExp ?
68 (pattern.pattern as RegExp).test(errorsAndOutput) :
69 errorsAndOutput.indexOf(pattern.pattern as string) !== -1;
70 });
71
72 return patternThatAppeared ? patternThatAppeared.message : null;
73 }
74
75 // We check that all the patterns appeared on the output
76 private areAllSuccessPatternsPresent(successPatterns: string[]): boolean {
77 return successPatterns.every(pattern => {
78 let patternRe = new RegExp(pattern, "i");
79 return patternRe.test(this.output);
80 });
81 }
82}
83