microsoft/vscode-react-native

Public

mirrored from https://github.com/microsoft/vscode-react-nativeAvailable

CodeCommitsIssuesPull requestsActionsInsightsSecurity
020085cfb3089f94af2a72a92f48be66a6ef322f

Branches

Tags

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

Clone

HTTPS

Download ZIP

src/common/outputVerifier.ts

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