diff --git a/lib/declarations.d.ts b/lib/declarations.d.ts index 7afd8d6e9b..d32c64800c 100644 --- a/lib/declarations.d.ts +++ b/lib/declarations.d.ts @@ -368,6 +368,8 @@ interface IDependencyData { * Dependencies of the current module. */ dependencies?: string[]; + + version: string; } interface INpmsResult { @@ -1071,4 +1073,4 @@ interface IWatchIgnoreListService { interface INpmConfigService { getConfig(): IDictionary; -} \ No newline at end of file +} diff --git a/lib/definitions/plugins.d.ts b/lib/definitions/plugins.d.ts index 3ab41f3a89..9cc8be5360 100644 --- a/lib/definitions/plugins.d.ts +++ b/lib/definitions/plugins.d.ts @@ -14,7 +14,6 @@ interface IPluginsService { */ getDependenciesFromPackageJson(projectDir: string): IPackageJsonDepedenciesResult; preparePluginNativeCode(preparePluginNativeCodeData: IPreparePluginNativeCodeData): Promise; - convertToPluginData(cacheData: any, projectDir: string): IPluginData; isNativeScriptPlugin(pluginPackageJsonPath: string): boolean; } @@ -44,7 +43,7 @@ interface IPluginData extends INodeModuleData { interface INodeModuleData extends IBasePluginData { fullPath: string; isPlugin: boolean; - moduleInfo: any; + nativescript: any; } interface IPluginPlatformsData { diff --git a/lib/services/plugins-service.ts b/lib/services/plugins-service.ts index 3b95776bd9..8c887a4740 100644 --- a/lib/services/plugins-service.ts +++ b/lib/services/plugins-service.ts @@ -9,6 +9,9 @@ export class PluginsService implements IPluginsService { private static NPM_CONFIG = { save: true }; + + private static LOCK_FILES = ["package-lock.json", "npm-shrinkwrap.json", "yarn.lock", "pnpm-lock.yaml"]; + private get $platformsDataService(): IPlatformsDataService { return this.$injector.resolve("platformsDataService"); } @@ -169,24 +172,17 @@ export class PluginsService implements IPluginsService { return _.filter(nodeModules, nodeModuleData => nodeModuleData && nodeModuleData.isPlugin); } - //This method will traverse all non dev dependencies (not only the root/installed ones) and filter the plugins. public getAllProductionPlugins(projectData: IProjectData, dependencies?: IDependencyData[]): IPluginData[] { - const allProductionPlugins: IPluginData[] = []; dependencies = dependencies || this.$nodeModulesDependenciesBuilder.getProductionDependencies(projectData.projectDir); if (_.isEmpty(dependencies)) { - return allProductionPlugins; + return []; } - _.forEach(dependencies, dependency => { - const isPlugin = !!dependency.nativescript; - if (isPlugin) { - const pluginData = this.convertToPluginData(dependency, projectData.projectDir); - allProductionPlugins.push(pluginData); - } - }); - - return allProductionPlugins; + let productionPlugins: IDependencyData[] = dependencies.filter(d => !!d.nativescript); + productionPlugins = this.ensureValidProductionPlugins(productionPlugins, projectData.projectDir); + const pluginData = productionPlugins.map(plugin => this.convertToPluginData(plugin, projectData.projectDir)); + return pluginData; } public getDependenciesFromPackageJson(projectDir: string): IPackageJsonDepedenciesResult { @@ -206,14 +202,71 @@ export class PluginsService implements IPluginsService { return pluginPackageJsonContent && pluginPackageJsonContent.nativescript; } - public convertToPluginData(cacheData: any, projectDir: string): IPluginData { + private ensureValidProductionPlugins = _.memoize<(productionDependencies: IDependencyData[], projectDir: string) => IDependencyData[]>(this._ensureValidProductionPlugins, (productionDependencies: IDependencyData[], projectDir: string) => { + let key = _.sortBy(productionDependencies, p => p.directory).map(d => JSON.stringify(d, null, 2)).join("\n"); + key += projectDir; + return key; + }); + + private _ensureValidProductionPlugins(productionDependencies: IDependencyData[], projectDir: string): IDependencyData[] { + const clonedProductionDependencies = _.cloneDeep(productionDependencies); + const dependenciesGroupedByName = _.groupBy(clonedProductionDependencies, p => p.name); + _.each(dependenciesGroupedByName, (dependencyOccurrences, dependencyName) => { + if (dependencyOccurrences.length > 1) { + // the dependency exists multiple times in node_modules + const dependencyOccurrencesGroupedByVersion = _.groupBy(dependencyOccurrences, g => g.version); + const versions = _.keys(dependencyOccurrencesGroupedByVersion); + if (versions.length === 1) { + // all dependencies with this name have the same version + this.$logger.warn(`Detected same versions (${_.first(versions)}) of the ${dependencyName} installed at locations: ${_.map(dependencyOccurrences, d => d.directory).join(", ")}`); + const selectedPackage = _.minBy(dependencyOccurrences, d => d.depth); + this.$logger.info(`CLI will use only the native code from '${selectedPackage.directory}'.`.green); + _.each(dependencyOccurrences, dependency => { + if (dependency !== selectedPackage) { + clonedProductionDependencies.splice(clonedProductionDependencies.indexOf(dependency), 1); + } + }); + } else { + const message = this.getFailureMessageForDifferentDependencyVersions(dependencyName, dependencyOccurrencesGroupedByVersion, projectDir); + this.$errors.fail(message); + } + } + }); + + return clonedProductionDependencies; + } + + private getFailureMessageForDifferentDependencyVersions(dependencyName: string, dependencyOccurrencesGroupedByVersion: IDictionary, projectDir: string): string { + let message = `Cannot use different versions of a NativeScript plugin in your application. +${dependencyName} plugin occurs multiple times in node_modules:\n`; + _.each(dependencyOccurrencesGroupedByVersion, (dependencies, version) => { + message += dependencies.map(d => `* Path: ${d.directory}, version: ${d.version}\n`); + }); + + const existingLockFiles: string[] = []; + PluginsService.LOCK_FILES.forEach(lockFile => { + if (this.$fs.exists(path.join(projectDir, lockFile))) { + existingLockFiles.push(lockFile); + } + }); + + let msgForLockFiles: string = ""; + if (existingLockFiles.length) { + msgForLockFiles += ` and ${existingLockFiles.join(", ")}`; + } + + message += `Probably you need to update your dependencies, remove node_modules${msgForLockFiles} and try again.`; + return message; + } + + private convertToPluginData(cacheData: IDependencyData | INodeModuleData, projectDir: string): IPluginData { const pluginData: any = {}; pluginData.name = cacheData.name; pluginData.version = cacheData.version; - pluginData.fullPath = cacheData.directory || path.dirname(this.getPackageJsonFilePathForModule(cacheData.name, projectDir)); - pluginData.isPlugin = !!cacheData.nativescript || !!cacheData.moduleInfo; + pluginData.fullPath = (cacheData).directory || path.dirname(this.getPackageJsonFilePathForModule(cacheData.name, projectDir)); + pluginData.isPlugin = !!cacheData.nativescript; pluginData.pluginPlatformsFolderPath = (platform: string) => path.join(pluginData.fullPath, "platforms", platform.toLowerCase()); - const data = cacheData.nativescript || cacheData.moduleInfo; + const data = cacheData.nativescript; if (pluginData.isPlugin) { pluginData.platformsData = data.platforms; @@ -280,7 +333,7 @@ export class PluginsService implements IPluginsService { version: data.version, fullPath: path.dirname(module), isPlugin: data.nativescript !== undefined, - moduleInfo: data.nativescript + nativescript: data.nativescript }; } diff --git a/lib/tools/node-modules/node-modules-dependencies-builder.ts b/lib/tools/node-modules/node-modules-dependencies-builder.ts index 53dd1bcfb1..6f05b60e38 100644 --- a/lib/tools/node-modules/node-modules-dependencies-builder.ts +++ b/lib/tools/node-modules/node-modules-dependencies-builder.ts @@ -93,7 +93,8 @@ export class NodeModulesDependenciesBuilder implements INodeModulesDependenciesB const dependency: IDependencyData = { name, directory, - depth + depth, + version: null }; const packageJsonPath = path.join(directory, PACKAGE_JSON_FILE_NAME); @@ -102,6 +103,7 @@ export class NodeModulesDependenciesBuilder implements INodeModulesDependenciesB if (packageJsonExists) { const packageJsonContents = this.$fs.readJson(packageJsonPath); + dependency.version = packageJsonContents.version; if (!!packageJsonContents.nativescript) { // add `nativescript` property, necessary for resolving plugins dependency.nativescript = packageJsonContents.nativescript; diff --git a/test/plugins-service.ts b/test/plugins-service.ts index fa15c86f45..a928ab0caa 100644 --- a/test/plugins-service.ts +++ b/test/plugins-service.ts @@ -37,10 +37,18 @@ import { PLUGINS_BUILD_DATA_FILENAME } from '../lib/constants'; import { GradleCommandService } from '../lib/services/android/gradle-command-service'; import { GradleBuildService } from '../lib/services/android/gradle-build-service'; import { GradleBuildArgsService } from '../lib/services/android/gradle-build-args-service'; +import * as util from "util"; temp.track(); let isErrorThrown = false; +interface ITestCase { + testName: string; + inputDependencies: any[]; + expectedOutput: any[] | Error; + expectedWarning?: string; +} + function createTestInjector() { const testInjector = new Yok(); testInjector.register("messagesService", MessagesService); @@ -571,23 +579,25 @@ describe("Plugins service", () => { }); }); - describe("convertToPluginData", () => { - const createUnitTestsInjector = () => { - const unitTestsInjector = new Yok(); - unitTestsInjector.register("platformsDataService", {}); - unitTestsInjector.register("filesHashService", {}); - unitTestsInjector.register("fs", {}); - unitTestsInjector.register("packageManager", {}); - unitTestsInjector.register("options", {}); - unitTestsInjector.register("logger", {}); - unitTestsInjector.register("errors", {}); - unitTestsInjector.register("injector", unitTestsInjector); - unitTestsInjector.register("mobileHelper", MobileHelper); - unitTestsInjector.register("devicePlatformsConstants", DevicePlatformsConstants); - unitTestsInjector.register("nodeModulesDependenciesBuilder", {}); - return unitTestsInjector; - }; + const createUnitTestsInjector = () => { + const unitTestsInjector = new Yok(); + unitTestsInjector.register("platformsDataService", {}); + unitTestsInjector.register("filesHashService", {}); + unitTestsInjector.register("fs", { + exists: (filePath: string) => false + }); + unitTestsInjector.register("packageManager", {}); + unitTestsInjector.register("options", {}); + unitTestsInjector.register("logger", stubs.LoggerStub); + unitTestsInjector.register("errors", stubs.ErrorsStub); + unitTestsInjector.register("injector", unitTestsInjector); + unitTestsInjector.register("mobileHelper", MobileHelper); + unitTestsInjector.register("devicePlatformsConstants", DevicePlatformsConstants); + unitTestsInjector.register("nodeModulesDependenciesBuilder", {}); + return unitTestsInjector; + }; + describe("convertToPluginData", () => { const pluginDir = "pluginDir"; const dataFromPluginPackageJson = { name: "name", @@ -604,7 +614,7 @@ describe("Plugins service", () => { it("returns correct pluginData", () => { const unitTestsInjector = createUnitTestsInjector(); const pluginsService: PluginsService = unitTestsInjector.resolve(PluginsService); - const pluginData = pluginsService.convertToPluginData(dataFromPluginPackageJson, "my project dir"); + const pluginData = (pluginsService).convertToPluginData(dataFromPluginPackageJson, "my project dir"); // Remove the comparison of a function delete pluginData["pluginPlatformsFolderPath"]; assert.deepEqual(pluginData, { @@ -620,7 +630,7 @@ describe("Plugins service", () => { it("always returns lowercased platform in the path to plugins dir", () => { const unitTestsInjector = createUnitTestsInjector(); const pluginsService: PluginsService = unitTestsInjector.resolve(PluginsService); - const pluginData = pluginsService.convertToPluginData(dataFromPluginPackageJson, "my project dir"); + const pluginData = (pluginsService).convertToPluginData(dataFromPluginPackageJson, "my project dir"); const expectediOSPath = path.join(pluginDir, "platforms", "ios"); const expectedAndroidPath = path.join(pluginDir, "platforms", "android"); @@ -633,4 +643,288 @@ describe("Plugins service", () => { assert.equal(pluginData.pluginPlatformsFolderPath("ANDROID"), expectedAndroidPath); }); }); + + describe("getAllProductionPlugins", () => { + const testCases: ITestCase[] = [ + { + testName: "returns empty array when none of the dependencies is nativescript plugin", + inputDependencies: [ + { + "name": "css-tree", + "directory": "/Users/username/projectDir/node_modules/css-tree", + "depth": 0, + "version": "1.0.0-alpha.39", + "dependencies": [ + "mdn-data", + "source-map" + ] + }, + { + "name": "nativescript-hook", + "directory": "/Users/username/projectDir/node_modules/nativescript-hook", + "depth": 0, + "version": "0.2.5", + "dependencies": [ + "glob", + "mkdirp" + ] + } + ], + expectedOutput: [] + }, + { + testName: "returns correct data when there's no duplication of plugins", + inputDependencies: [ + { + "name": "tns-core-modules", + "directory": "/Users/username/projectDir/node_modules/tns-core-modules", + "depth": 0, + "version": "6.3.2", + "nativescript": { + "platforms": { + "ios": "5.0.0", + "android": "5.0.0" + } + }, + "dependencies": [ + "@nativescript/core" + ] + }, + { + "name": "@nativescript/theme", + "directory": "/Users/username/projectDir/node_modules/@nativescript/theme", + "depth": 0, + "version": "2.2.1", + "nativescript": { + "platforms": { + "android": "6.2.0", + "ios": "6.2.0" + } + }, + "dependencies": [] + }, + ], + expectedOutput: [ + { + "fullPath": "/Users/username/projectDir/node_modules/tns-core-modules", + "isPlugin": true, + "name": "tns-core-modules", + "platformsData": { + "android": "5.0.0", + "ios": "5.0.0", + }, + "version": "6.3.2", + }, + { + "fullPath": "/Users/username/projectDir/node_modules/@nativescript/theme", + "isPlugin": true, + "name": "@nativescript/theme", + "platformsData": { + "android": "6.2.0", + "ios": "6.2.0", + }, + "version": "2.2.1", + } + ] + }, + { + testName: "prints warning when same version of plugin is installed multiple times", + inputDependencies: [ + { + "name": "nativescript-ui-listview", + "directory": "/Users/username/projectDir/node_modules/nativescript-ui-listview", + "depth": 0, + "version": "8.0.1", + "nativescript": { + "platforms": { + "android": "6.0.0", + "ios": "6.0.0" + } + }, + "dependencies": [ + "nativescript-ui-core" + ] + }, + { + "name": "nativescript-ui-core", + "directory": "/Users/username/projectDir/node_modules/nativescript-ui-core", + "depth": 0, + "version": "4.0.0", + "nativescript": { + "platforms": { + "android": "6.0.0", + "ios": "6.0.0" + } + }, + "dependencies": [] + }, + { + "name": "nativescript-ui-core", + "directory": "/Users/username/projectDir/node_modules/nativescript-ui-listview/node_modules/nativescript-ui-core", + "depth": 1, + "version": "4.0.0", + "nativescript": { + "platforms": { + "android": "6.0.0", + "ios": "6.0.0" + } + }, + "dependencies": [] + }, + ], + expectedOutput: [ + { + "fullPath": "/Users/username/projectDir/node_modules/nativescript-ui-listview", + "isPlugin": true, + "name": "nativescript-ui-listview", + "platformsData": { + "android": "6.0.0", + "ios": "6.0.0", + }, + "version": "8.0.1", + }, + { + "fullPath": "/Users/username/projectDir/node_modules/nativescript-ui-core", + "isPlugin": true, + "name": "nativescript-ui-core", + "platformsData": { + "android": "6.0.0", + "ios": "6.0.0", + }, + "version": "4.0.0", + } + ], + expectedWarning: "Detected same versions (4.0.0) of the nativescript-ui-core installed at locations: /Users/username/projectDir/node_modules/nativescript-ui-core, " + + "/Users/username/projectDir/node_modules/nativescript-ui-listview/node_modules/nativescript-ui-core" + }, + { + testName: "fails when different versions of the same plugin are detected", + inputDependencies: [ + { + "name": "nativescript-ui-listview", + "directory": "/Users/username/projectDir/node_modules/nativescript-ui-listview", + "depth": 0, + "version": "8.0.1", + "nativescript": { + "platforms": { + "android": "6.0.0", + "ios": "6.0.0" + } + }, + "dependencies": [ + "nativescript-ui-core" + ] + }, + { + "name": "nativescript-ui-core", + "directory": "/Users/username/projectDir/node_modules/nativescript-ui-core", + "depth": 0, + "version": "3.0.0", + "nativescript": { + "platforms": { + "android": "6.0.0", + "ios": "6.0.0" + } + }, + "dependencies": [] + }, + { + "name": "nativescript-ui-core", + "directory": "/Users/username/projectDir/node_modules/nativescript-ui-listview/node_modules/nativescript-ui-core", + "depth": 1, + "version": "4.0.0", + "nativescript": { + "platforms": { + "android": "6.0.0", + "ios": "6.0.0" + } + }, + "dependencies": [] + }, + ], + expectedOutput: new Error(`Cannot use different versions of a NativeScript plugin in your application. +nativescript-ui-core plugin occurs multiple times in node_modules:\n` + + "* Path: /Users/username/projectDir/node_modules/nativescript-ui-core, version: 3.0.0\n" + + "* Path: /Users/username/projectDir/node_modules/nativescript-ui-listview/node_modules/nativescript-ui-core, version: 4.0.0\n" + + `Probably you need to update your dependencies, remove node_modules and try again.`), + } + ]; + + for (const testCase of testCases) { + it(testCase.testName, () => { + const unitTestsInjector: IInjector = createUnitTestsInjector(); + const pluginsService: IPluginsService = unitTestsInjector.resolve(PluginsService); + + if (testCase.expectedOutput instanceof Error) { + assert.throws(() => pluginsService.getAllProductionPlugins({ projectDir: "projectDir" }, testCase.inputDependencies), testCase.expectedOutput.message); + } else { + const plugins = pluginsService.getAllProductionPlugins({ projectDir: "projectDir" }, testCase.inputDependencies); + + if (testCase.expectedWarning) { + const logger = unitTestsInjector.resolve("logger"); + assert.equal(testCase.expectedWarning + '\n', logger.warnOutput); + } + + for (const plugin of plugins) { + // deepEqual does not compare functions + delete plugin.pluginPlatformsFolderPath; + // pluginVariables is a legacy feature and out of the scope for current tests + delete plugin.pluginVariables; + } + + assert.deepEqual(plugins, testCase.expectedOutput); + } + }); + } + + it(`caches result based on dependencies`, () => { + const unitTestsInjector: IInjector = createUnitTestsInjector(); + const pluginsService: IPluginsService = unitTestsInjector.resolve(PluginsService); + const inputDependencies = [ + { + "name": "tns-core-modules", + "directory": "/Users/username/projectDir/node_modules/tns-core-modules", + "depth": 0, + "version": "6.3.0", + "nativescript": { + "platforms": { + "ios": "5.0.0", + "android": "5.0.0" + } + }, + "dependencies": [ + "@nativescript/core" + ] + }, + { + "name": "tns-core-modules", + "directory": "/Users/username/projectDir/node_modules/some-package/tns-core-modules", + "depth": 1, + "version": "6.3.0", + "nativescript": { + "platforms": { + "ios": "5.0.0", + "android": "5.0.0" + } + }, + "dependencies": [ + "@nativescript/core" + ] + }, + ]; + + _.range(3).forEach(() => { + pluginsService.getAllProductionPlugins({ projectDir: "projectDir" }, inputDependencies); + }); + + const logger = unitTestsInjector.resolve("logger"); + + const expectedWarnMessage = "Detected same versions (%s) of the tns-core-modules installed at locations: /Users/username/projectDir/node_modules/tns-core-modules, /Users/username/projectDir/node_modules/some-package/tns-core-modules\n"; + assert.equal(logger.warnOutput, util.format(expectedWarnMessage, "6.3.0"), "The warn message must be shown only once - the result of the private method must be cached as input dependencies have not changed"); + inputDependencies[0].version = "1.0.0"; + inputDependencies[1].version = "1.0.0"; + pluginsService.getAllProductionPlugins({ projectDir: "projectDir" }, inputDependencies); + assert.equal(logger.warnOutput, util.format(expectedWarnMessage, "6.3.0") + util.format(expectedWarnMessage, "1.0.0"), "When something in input dependencies change, the cached value shouldn't be taken into account"); + }); + }); }); diff --git a/test/stubs.ts b/test/stubs.ts index af3d18a719..9d287d3bd7 100644 --- a/test/stubs.ts +++ b/test/stubs.ts @@ -17,7 +17,9 @@ export class LoggerStub implements ILogger { getLevel(): string { return undefined; } fatal(...args: string[]): void { } error(...args: string[]): void { } - warn(...args: string[]): void { } + warn(...args: string[]): void { + this.warnOutput += util.format.apply(null, args) + "\n"; + } info(...args: string[]): void { this.output += util.format.apply(null, args) + "\n"; } @@ -29,6 +31,7 @@ export class LoggerStub implements ILogger { public output = ""; public traceOutput = ""; + public warnOutput = ""; prepare(item: any): string { return ""; diff --git a/test/tools/node-modules/node-modules-dependencies-builder.ts b/test/tools/node-modules/node-modules-dependencies-builder.ts index 0884817c87..7a59c7ad7a 100644 --- a/test/tools/node-modules/node-modules-dependencies-builder.ts +++ b/test/tools/node-modules/node-modules-dependencies-builder.ts @@ -59,13 +59,14 @@ describe("nodeModulesDependenciesBuilder", () => { return path.join(parentDir || pathToProject, constants.NODE_MODULES_FOLDER_NAME, dependencyName); }; - const getNodeModuleInfoForExpecteDependency = (dir: string, depth: number, nativescript?: any, dependencies?: string[], name?: string): IDependencyData => { + const getNodeModuleInfoForExpecteDependency = (dir: string, depth: number, nativescript?: any, dependencies?: string[], name?: string, version?: string): IDependencyData => { const packageName = name || path.basename(dir); const result: IDependencyData = { name: packageName, directory: getPathToDependencyInNodeModules(dir), depth, - dependencies: dependencies || [] + dependencies: dependencies || [], + version: version }; if (nativescript) { @@ -79,7 +80,7 @@ describe("nodeModulesDependenciesBuilder", () => { return path.join(getPathToDependencyInNodeModules(dependencyName, parentDir), constants.PACKAGE_JSON_FILE_NAME); }; - const getDependenciesObjectFromDependencyInfo = (depInfos: IDependencyInfo[], nativescript: any): { dependencies: IStringDictionary, nativescript?: any, devDependencies: IStringDictionary } => { + const getDependenciesObjectFromDependencyInfo = (depInfos: IDependencyInfo[], nativescript: any, version: string): { dependencies: IStringDictionary, nativescript?: any, devDependencies: IStringDictionary, version: string } => { const dependencies: any = {}; const devDepdencies: any = {}; _.each(depInfos, innerDependency => { @@ -99,6 +100,10 @@ describe("nodeModulesDependenciesBuilder", () => { result.nativescript = nativescript; } + if (version) { + result.version = version; + } + return result; }; @@ -107,7 +112,7 @@ describe("nodeModulesDependenciesBuilder", () => { for (const dependencyInfo of deps) { const pathToPackageJson = getPathToPackageJsonOfDependency(dependencyInfo.name, parentDir); if (filename === pathToPackageJson) { - return getDependenciesObjectFromDependencyInfo(dependencyInfo.dependencies, dependencyInfo.nativescript); + return getDependenciesObjectFromDependencyInfo(dependencyInfo.dependencies, dependencyInfo.nativescript, dependencyInfo.version); } if (dependencyInfo.dependencies) { @@ -128,7 +133,7 @@ describe("nodeModulesDependenciesBuilder", () => { fs.readJson = (filename: string, encoding?: string): any => { const innerDependency = getDependenciesObject(filename, rootDeps, pathToProject); - return innerDependency || getDependenciesObjectFromDependencyInfo(rootDeps, null); + return innerDependency || getDependenciesObjectFromDependencyInfo(rootDeps, null, null); }; const isDirectory = (searchedPath: string, currentRootPath: string, deps: IDependencyInfo[], currentDepthLevel: number): boolean => { @@ -221,8 +226,8 @@ describe("nodeModulesDependenciesBuilder", () => { const actualResult = await nodeModulesDependenciesBuilder.getProductionDependencies(pathToProject); const expectedResult: IDependencyData[] = [ - getNodeModuleInfoForExpecteDependency(firstPackage, 0), - getNodeModuleInfoForExpecteDependency(secondPackage, 0) + getNodeModuleInfoForExpecteDependency(firstPackage, 0, null, null, null, "1.0.0"), + getNodeModuleInfoForExpecteDependency(secondPackage, 0, null, null, null, "1.1.0") ]; assert.deepEqual(actualResult, expectedResult); @@ -241,7 +246,7 @@ describe("nodeModulesDependenciesBuilder", () => { ]; const expectedResult: IDependencyData[] = [ - getNodeModuleInfoForExpecteDependency(secondPackage, 0), + getNodeModuleInfoForExpecteDependency(secondPackage, 0, null, null, null, "1.1.0"), ]; const nodeModulesDependenciesBuilder = generateTest(rootDeps); @@ -264,9 +269,9 @@ describe("nodeModulesDependenciesBuilder", () => { ]; const expectedResult: IDependencyData[] = [ - getNodeModuleInfoForExpecteDependency(scopedPackageName, 0, null, [secondPackage], scopedPackageName), - getNodeModuleInfoForExpecteDependency(secondPackage, 0), - getNodeModuleInfoForExpecteDependency(path.join(scopedPackageName, constants.NODE_MODULES_FOLDER_NAME, secondPackage), 1) + getNodeModuleInfoForExpecteDependency(scopedPackageName, 0, null, [secondPackage], scopedPackageName, "1.0.0"), + getNodeModuleInfoForExpecteDependency(secondPackage, 0, null, null, null, "1.1.0"), + getNodeModuleInfoForExpecteDependency(path.join(scopedPackageName, constants.NODE_MODULES_FOLDER_NAME, secondPackage), 1, null, null, null, "1.2.0") ]; const nodeModulesDependenciesBuilder = generateTest(rootDeps); @@ -288,9 +293,9 @@ describe("nodeModulesDependenciesBuilder", () => { ]; const expectedResult: IDependencyData[] = [ - getNodeModuleInfoForExpecteDependency(firstPackage, 0, null, [scopedPackageName]), - getNodeModuleInfoForExpecteDependency(thirdPackage, 0), - getNodeModuleInfoForExpecteDependency(path.join(firstPackage, constants.NODE_MODULES_FOLDER_NAME, scopedPackageName), 1, null, null, scopedPackageName) + getNodeModuleInfoForExpecteDependency(firstPackage, 0, null, [scopedPackageName], null, "1.0.0"), + getNodeModuleInfoForExpecteDependency(thirdPackage, 0, null, null, null, "1.1.0"), + getNodeModuleInfoForExpecteDependency(path.join(firstPackage, constants.NODE_MODULES_FOLDER_NAME, scopedPackageName), 1, null, null, scopedPackageName, "1.2.0") ]; const nodeModulesDependenciesBuilder = generateTest(rootDeps); @@ -315,9 +320,9 @@ describe("nodeModulesDependenciesBuilder", () => { const actualResult = await nodeModulesDependenciesBuilder.getProductionDependencies(pathToProject); const expectedResult: IDependencyData[] = [ - getNodeModuleInfoForExpecteDependency(firstPackage, 0), - getNodeModuleInfoForExpecteDependency(secondPackage, 0), - getNodeModuleInfoForExpecteDependency(thirdPackage, 0) + getNodeModuleInfoForExpecteDependency(firstPackage, 0, null, null, null, "1.0.0"), + getNodeModuleInfoForExpecteDependency(secondPackage, 0, null, null, null, "1.1.0"), + getNodeModuleInfoForExpecteDependency(thirdPackage, 0, null, null, null, "1.2.0") ]; assert.deepEqual(actualResult, expectedResult); @@ -336,9 +341,9 @@ describe("nodeModulesDependenciesBuilder", () => { ]; const expectedResult: IDependencyData[] = [ - getNodeModuleInfoForExpecteDependency(firstPackage, 0, null, [secondPackage]), - getNodeModuleInfoForExpecteDependency(secondPackage, 0), - getNodeModuleInfoForExpecteDependency(path.join(firstPackage, constants.NODE_MODULES_FOLDER_NAME, secondPackage), 1) + getNodeModuleInfoForExpecteDependency(firstPackage, 0, null, [secondPackage], null, "1.0.0"), + getNodeModuleInfoForExpecteDependency(secondPackage, 0, null, null, null, "1.1.0"), + getNodeModuleInfoForExpecteDependency(path.join(firstPackage, constants.NODE_MODULES_FOLDER_NAME, secondPackage), 1, null, null, null, "1.2.0") ]; const nodeModulesDependenciesBuilder = generateTest(rootDeps); @@ -369,12 +374,12 @@ describe("nodeModulesDependenciesBuilder", () => { const pathToSecondPackageInsideFirstPackage = path.join(firstPackage, constants.NODE_MODULES_FOLDER_NAME, secondPackage); const expectedResult: IDependencyData[] = [ - getNodeModuleInfoForExpecteDependency(firstPackage, 0, null, [secondPackage, thirdPackage]), - getNodeModuleInfoForExpecteDependency(secondPackage, 0), - getNodeModuleInfoForExpecteDependency(thirdPackage, 0), - getNodeModuleInfoForExpecteDependency(pathToSecondPackageInsideFirstPackage, 1, null, [thirdPackage]), - getNodeModuleInfoForExpecteDependency(path.join(firstPackage, constants.NODE_MODULES_FOLDER_NAME, thirdPackage), 1), - getNodeModuleInfoForExpecteDependency(path.join(pathToSecondPackageInsideFirstPackage, constants.NODE_MODULES_FOLDER_NAME, thirdPackage), 2), + getNodeModuleInfoForExpecteDependency(firstPackage, 0, null, [secondPackage, thirdPackage], null, "1.0.0"), + getNodeModuleInfoForExpecteDependency(secondPackage, 0, null, null, null, "1.0.0"), + getNodeModuleInfoForExpecteDependency(thirdPackage, 0, null, null, null, "1.0.0"), + getNodeModuleInfoForExpecteDependency(pathToSecondPackageInsideFirstPackage, 1, null, [thirdPackage], null, "1.1.0"), + getNodeModuleInfoForExpecteDependency(path.join(firstPackage, constants.NODE_MODULES_FOLDER_NAME, thirdPackage), 1, null, null, null, "1.1.0"), + getNodeModuleInfoForExpecteDependency(path.join(pathToSecondPackageInsideFirstPackage, constants.NODE_MODULES_FOLDER_NAME, thirdPackage), 2, null, null, null, "1.2.0"), ]; const nodeModulesDependenciesBuilder = generateTest(rootDeps); @@ -410,9 +415,9 @@ describe("nodeModulesDependenciesBuilder", () => { const actualResult = await nodeModulesDependenciesBuilder.getProductionDependencies(pathToProject); const expectedResult: IDependencyData[] = [ - getNodeModuleInfoForExpecteDependency(firstPackage, 0, getNativeScriptDataForPlugin(firstPackage)), - getNodeModuleInfoForExpecteDependency(secondPackage, 0, getNativeScriptDataForPlugin(secondPackage)), - getNodeModuleInfoForExpecteDependency(thirdPackage, 0, getNativeScriptDataForPlugin(thirdPackage)) + getNodeModuleInfoForExpecteDependency(firstPackage, 0, getNativeScriptDataForPlugin(firstPackage), null, null, "1.0.0"), + getNodeModuleInfoForExpecteDependency(secondPackage, 0, getNativeScriptDataForPlugin(secondPackage), null, null, "1.1.0"), + getNodeModuleInfoForExpecteDependency(thirdPackage, 0, getNativeScriptDataForPlugin(thirdPackage), null, null, "1.2.0") ]; assert.deepEqual(actualResult, expectedResult);