microsoft/vscode-react-native

Public

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

CodeCommitsIssuesPull requestsActionsInsightsSecurity
0.3.1

Branches

Tags

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

Clone

HTTPS

Download ZIP

src/test/resources/reactNative022.ts

177lines · modeblame

c7f1165cdigeff10 years ago1// 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 * as path from "path";
6import * as assert from "assert";
7
8import {PromiseUtil} from "../../common/node/promise";
9
10import * as reactNative from "../../common/reactNative";
11import {ISpawnResult} from "../../common/node/childProcess";
12import {FileSystem} from "../../common/node/fileSystem";
13import {Package} from "../../common/node/package";
14import {Recording, Simulator} from "./processExecution/simulator";
c51e2d6bdigeff10 years ago15import {AdbSimulator} from "./simulators/adbSimulator";
c7f1165cdigeff10 years ago16import {APKSerializer} from "./simulators/apkSerializer";
17
18const resourcesPath = path.join(__dirname, "../../../src/test/resources/");
19const sampleRNProjectPath = path.join(resourcesPath, "sampleReactNative022Project");
20const processExecutionsRecordingsPath = path.join(resourcesPath, "processExecutionsRecordings");
21
22export type IReactNative = reactNative.IReactNative;
23
24/* This class simulates calling the React-Native CLI v0.22. It currently supports react-native init
f0008229digeff10 years ago25and react-native run-android. */
c7f1165cdigeff10 years ago26export class ReactNative022 implements IReactNative {
27private static ANDROID_APK_RELATIVE_PATH = "android/app/build/outputs/apk/app-debug.apk";
28
29private simulator: Simulator = new Simulator({
30beforeStart: () => this.readAndroidPackageName(), // 1. We read the package.json to verify this is a RN project
31outputBased: [
32{
33eventPattern: /:app:assembleDebug/,
34action: () => this.createAPK(), // 2. We compile the application.
35},
36{
37eventPattern: /Installed on [0-9]+ devices*\./,
38action: () => this.installAppInAllDevices(), // 3. We install it on all available devices.
39},
40],
41beforeSuccess: (stdout: string, stderr: string) => // 4. If we didn't had any errors after starting to launch the app,
42this.launchApp(stdout, stderr), // it means we were succesful
43});
44
45private recording: Recording;
46
47private androidPackageName: string;
48private projectRoot: string;
49private androidAPKPath: string;
50
c51e2d6bdigeff10 years ago51constructor(private adb: AdbSimulator, private fileSystem: FileSystem) {
52f3873ddigeff10 years ago52assert(this.adb, "adb shouldn't be null");
c7f1165cdigeff10 years ago53assert(this.fileSystem, "fileSystem shouldn't be null");
54}
55
56public loadRecordingFromName(recordingName: string): Q.Promise<void> {
57return this.loadRecordingFromFile(path.join(processExecutionsRecordingsPath, `${recordingName}.json`));
58}
59
60public loadRecordingFromFile(recordingPath: string): Q.Promise<void> {
61return Q({})
62.then(() => {
63return new FileSystem().readFile(recordingPath);
64}).then(fileContents => {
65this.loadRecording(JSON.parse(fileContents));
66});
67}
68
69public loadRecording(recording: Recording): void {
70assert(recording, "recording shouldn't be null");
71this.recording = recording;
72}
73
74public createProject(projectRoot: string, projectName: string): Q.Promise<void> {
75return Q({})
76.then(() => {
77this.fileSystem.makeDirectoryRecursiveSync(projectRoot);
78return this.readDefaultProjectFile("package.json");
79}).then(defaultContents => {
80const reactNativeConfiguration = JSON.parse(defaultContents);
81reactNativeConfiguration.name = projectName;
82const reactNativeConfigurationFormatted = JSON.stringify(reactNativeConfiguration);
83return this.fileSystem.writeFile(this.getPackageJsonPath(projectRoot), reactNativeConfigurationFormatted);
84}).then(() => {
85return this.fileSystem.mkDir(this.getAndroidProjectPath(projectRoot));
86});
87}
88
89public runAndroid(projectRoot: string): ISpawnResult {
90this.projectRoot = projectRoot;
91this.simulator.simulate(this.recording).done();
92return this.simulator.spawn();
93}
94
95private getAndroidProjectPath(projectRoot = this.projectRoot): string {
96return path.join(projectRoot, "android");
97}
98
99private getPackageJsonPath(projectRoot: string): string {
100return new Package(projectRoot, { fileSystem: this.fileSystem }).informationJsonFilePath();
101}
102
103private readAndroidPackageName(): Q.Promise<void> {
104return new Package(this.projectRoot, { fileSystem: this.fileSystem }).name().then(name => {
105this.androidPackageName = `com.${name.toLowerCase()}`;
106});
107}
108
109private createAPK(): Q.Promise<void> {
110return this.isAndroidProjectPresent().then(isPresent => {
111if (!isPresent) {
112return Q.reject<void>(new Error("The recording expects the Android project to be present, but it's not"));
113}
114}).then(() => {
115this.androidAPKPath = path.join(this.projectRoot, ReactNative022.ANDROID_APK_RELATIVE_PATH);
116return new APKSerializer(this.fileSystem).writeApk(this.androidAPKPath, { packageName: this.androidPackageName });
117});
118}
119
120private isAndroidProjectPresent(): Q.Promise<boolean> {
121// TODO: Make more checks as neccesary for the tests
122return this.fileSystem.directoryExists(this.getAndroidProjectPath());
123}
124
125private installAppInAllDevices(): Q.Promise<void> {
52f3873ddigeff10 years ago126return new PromiseUtil().reduce(this.adb.getConnectedDevices(), device => this.installAppInDevice(device.id));
c7f1165cdigeff10 years ago127}
128
129private installAppInDevice(deviceId: string): Q.Promise<void> {
52f3873ddigeff10 years ago130return this.adb.isDeviceOnline(deviceId).then(isOnline => {
c7f1165cdigeff10 years ago131if (isOnline) {
52f3873ddigeff10 years ago132return this.adb.installApp(this.androidAPKPath, deviceId);
c7f1165cdigeff10 years ago133} else {
f0008229digeff10 years ago134// TODO: Figure out what's the right thing to do here, if we ever need this for the tests
c7f1165cdigeff10 years ago135}
136});
137}
138
139private launchApp(stdout: string, stderr: string): Q.Promise<void> {
140/*
141Sample output we want to accept:
142BUILD SUCCESSFUL
143
144Total time: 9.052 secs
145Starting the app (C:\Program Files (x86)\Android\android-sdk/platform-tools/adb shell am start -n com.sampleapplication/.MainActivity)...
146Starting: Intent { cmp=com.sampleapplication/.MainActivity }
147
148
149Sample output we don't to accept:
150BUILD SUCCESSFUL
151
152Total time: 9.052 secs
153Starting the app (C:\Program Files (x86)\Android\android-sdk/platform-tools/adb shell am start -n com.sampleapplication/.MainActivity)...
154Starting: Intent { cmp=com.sampleapplication/.MainActivity }
155Error: some error happened
156**/
157const succesfulOutputEnd = `Starting the app \\(.*adb shell am start -n ([^ /]+)\/\\.MainActivity\\)\\.\\.\\.\\s+`
158+ `Starting: Intent { cmp=([^ /]+)\/\\.MainActivity }\\s+$`;
159const matches = stdout.match(new RegExp(succesfulOutputEnd));
160if (matches) {
161if (matches.length === 3 && matches[1] === this.androidPackageName && matches[2] === this.androidPackageName) {
52f3873ddigeff10 years ago162return this.adb.launchApp(this.projectRoot, this.androidPackageName);
c7f1165cdigeff10 years ago163} else {
164return Q.reject<void>(new Error("There was an error while trying to match the Starting the app messages."
165+ "Expected to match the pattern and recognize the expected android package name, but it failed."
166+ `Expected android package name: ${this.androidPackageName}. Actual matches: ${JSON.stringify(matches)}`));
167}
168} else {
169// The record doesn't indicate that the app was launched, so we don't do anything
170}
171}
172
173private readDefaultProjectFile(relativeFilePath: string): Q.Promise<string> {
174const realFileSystem = new FileSystem(); // We always use the real file system (not the mock one) to read the sample project
175return realFileSystem.readFile(path.join(sampleRNProjectPath, relativeFilePath));
176}
177}