microsoft/vscode-react-native

Public

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

CodeCommitsIssuesPull requestsActionsInsightsSecurity
7b48f26eb8caae7ed9cc1a09249195dfed76fa76

Branches

Tags

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

Clone

HTTPS

Download ZIP

test/common/packageLoader.test.ts

235lines · 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 assert = require("assert");
5import * as path from "path";
6import rimraf = require("rimraf");
7import * as sinon from "sinon";
8import * as extensionHelper from "../../src/common/extensionHelper";
9import { Package } from "../../src/common/node/package";
10import * as XDL from "../../src/extension/exponent/xdlInterface";
11import { PackageLoader, PackageConfig } from "../../src/common/packageLoader";
12import { CommandExecutor } from "../../src/common/commandExecutor";
13import { HostPlatform } from "../../src/common/hostPlatform";
14
15const packageLoaderTestTimeout = 4 * 60 * 1000;
16// We need to import xdlInterface to import PackageLoad correctly.
17// Probably a problem is related to import of static functions into test files
18console.log(XDL);
19
20suite("packageLoader", async () => {
21 async function getPackageVersionsFromNodeModules(
22 projectRoot: string,
23 packageName: string,
24 ): Promise<string | null> {
25 try {
26 return await new Package(projectRoot).getPackageVersionFromNodeModules(packageName);
27 } catch (error) {
28 return null;
29 }
30 }
31
32 function isNotEmptyPackage(pck: any): boolean {
33 return pck && (Object.keys(pck).length !== 0 || typeof pck === "function");
34 }
35
36 suite("localNodeModules", async () => {
37 const sampleProjectPath = path.resolve(
38 __dirname,
39 "..",
40 "resources",
41 "sampleReactNativeProject",
42 );
43 const sampleProjectNodeModulesPath = path.join(sampleProjectPath, "node_modules");
44 const sampleProjectPackageLockJsonPath = path.join(sampleProjectPath, "package-lock.json");
45
46 const commandExecutor = new CommandExecutor(sampleProjectPath, sampleProjectPath);
47
48 let findFileInFolderHierarchyStub: Sinon.SinonStub | undefined;
49 let getVersionFromExtensionNodeModulesStub: Sinon.SinonStub | undefined;
50 let tryToRequireAfterInstallSpy: Sinon.SinonSpy | undefined;
51
52 const mkdirpPackageConfig = new PackageConfig("mkdirp", "1.0.4");
53
54 const rimrafPackageFirst = new PackageConfig("rimraf", "3.0.1");
55 const rimrafPackageSecond = new PackageConfig("rimraf", "3.0.2");
56
57 const chalkPackageConfig = new PackageConfig("chalk", "4.1.1", "./source/util.js");
58
59 suiteSetup(async function () {
60 rimraf.sync(sampleProjectNodeModulesPath);
61 rimraf.sync(sampleProjectPackageLockJsonPath);
62 findFileInFolderHierarchyStub = sinon.stub(
63 extensionHelper,
64 "findFileInFolderHierarchy",
65 () => {
66 return sampleProjectNodeModulesPath;
67 },
68 );
69 getVersionFromExtensionNodeModulesStub = sinon.stub(
70 extensionHelper,
71 "getVersionFromExtensionNodeModules",
72 (packageName: string) => {
73 return getPackageVersionsFromNodeModules(sampleProjectPath, packageName);
74 },
75 );
76 tryToRequireAfterInstallSpy = sinon.spy(
77 PackageLoader.getInstance(),
78 "tryToRequireAfterInstall",
79 );
80 });
81
82 suiteTeardown(function () {
83 this.timeout(packageLoaderTestTimeout);
84 findFileInFolderHierarchyStub?.restore();
85 getVersionFromExtensionNodeModulesStub?.restore();
86 tryToRequireAfterInstallSpy?.restore();
87 sinon.restore(extensionHelper);
88
89 rimraf.sync(sampleProjectNodeModulesPath);
90 rimraf.sync(sampleProjectPackageLockJsonPath);
91 });
92
93 teardown(function () {
94 this.timeout(packageLoaderTestTimeout);
95 findFileInFolderHierarchyStub?.reset();
96 getVersionFromExtensionNodeModulesStub?.reset();
97 tryToRequireAfterInstallSpy?.reset();
98
99 rimraf.sync(sampleProjectNodeModulesPath);
100 rimraf.sync(sampleProjectPackageLockJsonPath);
101 });
102
103 test("The package loader should install packages in node_modules where these packages are not present", async function () {
104 this.timeout(packageLoaderTestTimeout);
105 // There is the problem with '--no-save' flag for 'npm install' command for npm v6.
106 // Installing npm dependencies with the `--no-save` flag will remove
107 // other dependencies that were installed in the same manner (https://github.com/npm/cli/issues/1460).
108 // So we should workaround it passing all packages for install to only one npm install command
109 const getMkdrip = PackageLoader.getInstance().generateGetPackageFunction<any>(
110 mkdirpPackageConfig,
111 rimrafPackageFirst,
112 );
113 const getRimraf = PackageLoader.getInstance().generateGetPackageFunction<any>(
114 rimrafPackageFirst,
115 mkdirpPackageConfig,
116 );
117
118 const [mkdirpPackage, rimrafPackage] = await Promise.all([getMkdrip(), getRimraf()]);
119
120 assert.strictEqual(
121 isNotEmptyPackage(rimrafPackage) && isNotEmptyPackage(mkdirpPackage),
122 true,
123 "Not all packages has been installed and required",
124 );
125
126 const installedVersionOfMkdirp = await getPackageVersionsFromNodeModules(
127 sampleProjectPath,
128 mkdirpPackageConfig.getPackageName(),
129 );
130 const installedVersionOfRimraf = await getPackageVersionsFromNodeModules(
131 sampleProjectPath,
132 rimrafPackageFirst.getPackageName(),
133 );
134 assert.strictEqual(
135 installedVersionOfMkdirp,
136 mkdirpPackageConfig.getVersion(),
137 `Wrong installed version of ${mkdirpPackageConfig.getPackageName()} package`,
138 );
139 assert.strictEqual(
140 installedVersionOfRimraf,
141 rimrafPackageFirst.getVersion(),
142 `Wrong installed version of ${rimrafPackageFirst.getPackageName()} package`,
143 );
144 });
145
146 test("The package loader should not execute installation for packages that are already present in node_modules", async function () {
147 this.timeout(packageLoaderTestTimeout);
148 await commandExecutor.spawn(HostPlatform.getNpmCliCommand("npm"), [
149 "install",
150 rimrafPackageFirst.getStringForInstall(),
151 "--no-save",
152 ]);
153 assert.strictEqual(
154 await getPackageVersionsFromNodeModules(
155 sampleProjectPath,
156 rimrafPackageFirst.getPackageName(),
157 ),
158 rimrafPackageFirst.getVersion(),
159 "Package was preinstalled with wrong version",
160 );
161
162 const getRimraf =
163 PackageLoader.getInstance().generateGetPackageFunction<any>(rimrafPackageFirst);
164 assert.strictEqual(
165 isNotEmptyPackage(await getRimraf()),
166 true,
167 "Package was not required",
168 );
169
170 assert.strictEqual(
171 tryToRequireAfterInstallSpy?.notCalled,
172 true,
173 "Package loader executes installation for packages that already exist in node_modules",
174 );
175 tryToRequireAfterInstallSpy?.reset();
176 });
177
178 test("The package loader should install a package with the specific version if the package is already installed but with another version", async function () {
179 this.timeout(packageLoaderTestTimeout);
180
181 await commandExecutor.spawn(HostPlatform.getNpmCliCommand("npm"), [
182 "install",
183 rimrafPackageFirst.getStringForInstall(),
184 "--no-save",
185 ]);
186 assert.strictEqual(
187 await getPackageVersionsFromNodeModules(
188 sampleProjectPath,
189 rimrafPackageFirst.getPackageName(),
190 ),
191 rimrafPackageFirst.getVersion(),
192 "Package was preinstalled with wrong version",
193 );
194
195 const getRimraf =
196 PackageLoader.getInstance().generateGetPackageFunction<any>(rimrafPackageSecond);
197 assert.strictEqual(
198 isNotEmptyPackage(await getRimraf()),
199 true,
200 "Package was not required",
201 );
202
203 assert.strictEqual(
204 tryToRequireAfterInstallSpy?.calledOnce,
205 true,
206 "Package loader not execute installation for packages that are already present in node_modules but with wrong version",
207 );
208 tryToRequireAfterInstallSpy?.reset();
209
210 const installedVersionOfRimraf = await getPackageVersionsFromNodeModules(
211 sampleProjectPath,
212 rimrafPackageSecond.getPackageName(),
213 );
214 assert.strictEqual(
215 installedVersionOfRimraf,
216 rimrafPackageSecond.getVersion(),
217 `Wrong installed version of ${rimrafPackageSecond.getPackageName()} package`,
218 );
219 });
220
221 test("The package loader should install package and require specific subpath for this package", async function () {
222 this.timeout(packageLoaderTestTimeout);
223
224 const getChalk =
225 PackageLoader.getInstance().generateGetPackageFunction<any>(chalkPackageConfig);
226 const chalkPackage = await getChalk();
227 assert.strictEqual(isNotEmptyPackage(chalkPackage), true, "Package was not required");
228 assert.strictEqual(
229 !!(chalkPackage.stringReplaceAll && chalkPackage.stringEncaseCRLFWithFirstIndex),
230 true,
231 "Required package subpath does not contains all members. It means what there are problems with subpath requiring",
232 );
233 });
234 });
235});
236