From 32d168a0a2332fe75c808895bffdeeb106430756 Mon Sep 17 00:00:00 2001 From: Fatme Havaluova Date: Fri, 26 Jun 2015 10:14:52 +0300 Subject: [PATCH 1/2] Fix symlinks that are added to output package and points to not existing location --- lib/services/platform-service.ts | 21 ++-- lib/tools/broccoli/broccoli.d.ts | 3 +- lib/tools/broccoli/builder.ts | 80 +++++++++++--- lib/tools/broccoli/node-modules-dest-copy.ts | 103 +++++++++---------- package.json | 3 + 5 files changed, 134 insertions(+), 76 deletions(-) diff --git a/lib/services/platform-service.ts b/lib/services/platform-service.ts index 969a9c0045..2e780a8f29 100644 --- a/lib/services/platform-service.ts +++ b/lib/services/platform-service.ts @@ -149,17 +149,26 @@ export class PlatformService implements IPlatformService { platform = platform.toLowerCase(); var platformData = this.$platformsData.getPlatformData(platform); + let appDestinationDirectoryPath = path.join(platformData.appDestinationDirectoryPath, constants.APP_FOLDER_NAME); + let lastModifiedTime = this.$fs.exists(appDestinationDirectoryPath).wait() ? + this.$fs.getFsStats(appDestinationDirectoryPath).wait().mtime : null; // Copy app folder to native project + this.$fs.ensureDirectoryExists(appDestinationDirectoryPath).wait(); var appSourceDirectoryPath = path.join(this.$projectData.projectDir, constants.APP_FOLDER_NAME); - + // Delete the destination app in order to prevent EEXIST errors when symlinks are used. - this.$fs.deleteDirectory(path.join(platformData.appDestinationDirectoryPath, constants.APP_FOLDER_NAME)).wait(); - shell.cp("-R", appSourceDirectoryPath, platformData.appDestinationDirectoryPath); + let contents = this.$fs.readDirectory(appDestinationDirectoryPath).wait(); + + _(contents) + .filter(directoryName => directoryName !== "tns_modules") + .each(directoryName => this.$fs.deleteDirectory(path.join(appDestinationDirectoryPath, directoryName)).wait()) + .value(); + shell.cp("-Rf", appSourceDirectoryPath, platformData.appDestinationDirectoryPath); // Copy App_Resources to project root folder - var appResourcesDirectoryPath = path.join(platformData.appDestinationDirectoryPath, constants.APP_FOLDER_NAME, constants.APP_RESOURCES_FOLDER_NAME); - this.$fs.ensureDirectoryExists(platformData.appResourcesDestinationDirectoryPath).wait(); + this.$fs.ensureDirectoryExists(platformData.appResourcesDestinationDirectoryPath).wait(); // Should be deleted + var appResourcesDirectoryPath = path.join(appDestinationDirectoryPath, constants.APP_RESOURCES_FOLDER_NAME); if (this.$fs.exists(appResourcesDirectoryPath).wait()) { platformData.platformProjectService.prepareAppResources(appResourcesDirectoryPath).wait(); shell.cp("-R", path.join(appResourcesDirectoryPath, platformData.normalizedPlatformName, "*"), platformData.appResourcesDestinationDirectoryPath); @@ -176,7 +185,7 @@ export class PlatformService implements IPlatformService { // Process node_modules folder this.$pluginsService.ensureAllDependenciesAreInstalled().wait(); var tnsModulesDestinationPath = path.join(platformData.appDestinationDirectoryPath, constants.APP_FOLDER_NAME, PlatformService.TNS_MODULES_FOLDER_NAME); - this.$broccoliBuilder.prepareNodeModules(tnsModulesDestinationPath, this.$projectData.projectDir).wait(); + this.$broccoliBuilder.prepareNodeModules(tnsModulesDestinationPath, this.$projectData.projectDir, lastModifiedTime).wait(); this.$logger.out("Project successfully prepared"); }).future()(); diff --git a/lib/tools/broccoli/broccoli.d.ts b/lib/tools/broccoli/broccoli.d.ts index 4ca05877c3..93ae00eca4 100644 --- a/lib/tools/broccoli/broccoli.d.ts +++ b/lib/tools/broccoli/broccoli.d.ts @@ -152,7 +152,7 @@ interface BroccoliNode { } interface IBroccoliBuilder { - prepareNodeModules(outputPath: string, projectDir: string): IFuture; + prepareNodeModules(outputPath: string, projectDir: string, lastModifiedTime?: Date): IFuture; } interface IDiffResult { @@ -162,6 +162,7 @@ interface IDiffResult { interface IBroccoliPlugin { rebuild(diff: IDiffResult): any; + rebuildChangedDirectories?(changedDirectories: string[]): void; cleanup? () : void; } diff --git a/lib/tools/broccoli/builder.ts b/lib/tools/broccoli/builder.ts index 070b5259b8..2e5bc64330 100644 --- a/lib/tools/broccoli/builder.ts +++ b/lib/tools/broccoli/builder.ts @@ -5,29 +5,81 @@ let broccoli = require('broccoli'); let path = require('path'); import Future = require("fibers/future"); import {TreeDiffer} from './tree-differ'; -import destCopy = require('./node-modules-dest-copy'); +import destCopyLib = require('./node-modules-dest-copy'); + +var gulp = require("gulp"); +var vinylFilterSince = require('vinyl-filter-since') +var through = require("through2"); export class Builder implements IBroccoliBuilder { + private nodeModules: any = {}; + constructor(private $fs: IFileSystem, private $nodeModulesTree: INodeModulesTree, private $projectDataService: IProjectDataService, + private $injector: IInjector, private $logger: ILogger) { } - public prepareNodeModules(absoluteOutputPath: string, projectDir: string): IFuture { + public prepareNodeModules(absoluteOutputPath: string, projectDir: string, lastModifiedTime?: Date): IFuture { return (() => { - // TODO: figure out a better way for doing this - this.$projectDataService.initialize(projectDir); - let cachedNodeModulesPath = this.$projectDataService.getValue("node-modules-cache-path").wait(); - if (cachedNodeModulesPath && this.$fs.exists(cachedNodeModulesPath).wait()) { - let diffTree = new TreeDiffer(cachedNodeModulesPath); - let diffTreeResult = diffTree.diffTree(path.join(projectDir, absoluteOutputPath, "node_modules")); - - if(diffTreeResult.changedDirectories.length > 0 || diffTreeResult.removedDirectories.length > 0) { - this.rebuildNodeModulesTree(absoluteOutputPath, projectDir).wait(); - } - } else { - this.rebuildNodeModulesTree(absoluteOutputPath, projectDir).wait(); + let isNodeModulesModified = false; + let nodeModulesPath = path.join(projectDir, "node_modules"); + + if(lastModifiedTime) { + let pipeline = gulp.src(path.join(projectDir, "node_modules/**")) + .pipe(vinylFilterSince(lastModifiedTime)) + .pipe(through.obj( (chunk: any, enc: any, cb: Function) => { + if(chunk.path === nodeModulesPath) { + isNodeModulesModified = true; + } + + if(!isNodeModulesModified) { + let rootModuleName = chunk.path.split(nodeModulesPath)[1].split(path.sep)[1]; + let rootModuleFullPath = path.join(nodeModulesPath, rootModuleName); + this.nodeModules[rootModuleFullPath] = rootModuleFullPath; + } + + cb(null); + })) + .pipe(gulp.dest(absoluteOutputPath)); + + let future = new Future(); + + pipeline.on('end', (err: any, data: any) => { + if(err) { + future.throw(err); + } else { + future.return(); + } + }); + + future.wait(); + } + + if(isNodeModulesModified && this.$fs.exists(absoluteOutputPath).wait()) { + let currentPreparedTnsModules = this.$fs.readDirectory(absoluteOutputPath).wait(); + let tnsModulesInApp = this.$fs.readDirectory(path.join(projectDir, "app", "tns_modules")).wait(); + let modulesToDelete = _.difference(currentPreparedTnsModules, tnsModulesInApp); + _.each(modulesToDelete, moduleName => this.$fs.deleteDirectory(path.join(absoluteOutputPath, moduleName)).wait()) + } + + if(!lastModifiedTime || isNodeModulesModified) { + let nodeModulesDirectories = this.$fs.readDirectory(nodeModulesPath).wait(); + _.each(nodeModulesDirectories, nodeModuleDirectoryName => { + let nodeModuleFullPath = path.join(nodeModulesPath, nodeModuleDirectoryName); + this.nodeModules[nodeModuleFullPath] = nodeModuleFullPath; + }); } + + let destCopy = this.$injector.resolve(destCopyLib.DestCopy, { + inputPath: projectDir, + cachePath: "", + outputRoot: absoluteOutputPath, + projectDir: projectDir + }); + + destCopy.rebuildChangedDirectories(_.keys(this.nodeModules)); + }).future()(); } diff --git a/lib/tools/broccoli/node-modules-dest-copy.ts b/lib/tools/broccoli/node-modules-dest-copy.ts index 61b0f3e801..07fd62e4b5 100644 --- a/lib/tools/broccoli/node-modules-dest-copy.ts +++ b/lib/tools/broccoli/node-modules-dest-copy.ts @@ -14,57 +14,66 @@ import constants = require("./../../constants"); * and tees a copy to the given path outside the tmp dir. */ export class DestCopy implements IBroccoliPlugin { - constructor(private inputPath: string, private cachePath: string, private outputRoot: string, private projectDir: string) {} - - public rebuild(treeDiff: IDiffResult): void { - let dependencies = this.getDependencies(); - let devDependencies = this.getDevDependencies(this.projectDir); - - treeDiff.changedDirectories.forEach(changedDirectory => { - let changedDirectoryAbsolutePath = path.join(this.inputPath, constants.NODE_MODULES_FOLDER_NAME, changedDirectory); - let packageJsonFiles = [path.join(changedDirectoryAbsolutePath, "package.json")]; - let nodeModulesFolderPath = path.join(changedDirectoryAbsolutePath, "node_modules"); - packageJsonFiles = packageJsonFiles.concat(this.enumeratePackageJsonFilesSync(nodeModulesFolderPath)); - - _.each(packageJsonFiles, packageJsonFilePath => { - let fileContent = require(packageJsonFilePath); - let isPlugin = fileContent.nativescript; + private dependencies: IDictionary = null; + private devDependencies: IDictionary = null; - if(!devDependencies[fileContent.name]) { // Don't flatten dev dependencies - - let currentDependency = { - name: fileContent.name, - version: fileContent.version, - directory: path.dirname(packageJsonFilePath), - isPlugin: isPlugin - }; + constructor(private inputPath: string, private cachePath: string, private outputRoot: string, private projectDir: string) { + this.dependencies = Object.create(null); + this.devDependencies = this.getDevDependencies(projectDir); + } + + public rebuildChangedDirectories(changedDirectories: string[]): void { + _.each(changedDirectories, changedDirectoryAbsolutePath => { + let pathToPackageJson = path.join(changedDirectoryAbsolutePath, "package.json"); + if(fs.existsSync(pathToPackageJson)) { + let packageJsonFiles = [pathToPackageJson]; + let nodeModulesFolderPath = path.join(changedDirectoryAbsolutePath, "node_modules"); + packageJsonFiles = packageJsonFiles.concat(this.enumeratePackageJsonFilesSync(nodeModulesFolderPath)); - let addedDependency = dependencies[currentDependency.name]; - if (addedDependency) { - if (semver.gt(currentDependency.version, addedDependency.version)) { - let currentDependencyMajorVersion = semver.major(currentDependency.version); - let addedDependencyMajorVersion = semver.major(addedDependency.version); + _.each(packageJsonFiles, packageJsonFilePath => { + let fileContent = require(packageJsonFilePath); + let isPlugin = fileContent.nativescript; - let message = `The depedency located at ${addedDependency.directory} with version ${addedDependency.version} will be replaced with dependency located at ${currentDependency.directory} with version ${currentDependency.version}`; - let logger = $injector.resolve("$logger"); - currentDependencyMajorVersion === addedDependencyMajorVersion ? logger.out(message) : logger.warn(message); - - dependencies[currentDependency.name] = currentDependency; + if(!this.devDependencies[fileContent.name]) { // Don't flatten dev dependencies + + let currentDependency = { + name: fileContent.name, + version: fileContent.version, + directory: path.dirname(packageJsonFilePath), + isPlugin: isPlugin + }; + + let addedDependency = this.dependencies[currentDependency.name]; + if (addedDependency) { + if (semver.gt(currentDependency.version, addedDependency.version)) { + let currentDependencyMajorVersion = semver.major(currentDependency.version); + let addedDependencyMajorVersion = semver.major(addedDependency.version); + + let message = `The depedency located at ${addedDependency.directory} with version ${addedDependency.version} will be replaced with dependency located at ${currentDependency.directory} with version ${currentDependency.version}`; + let logger = $injector.resolve("$logger"); + currentDependencyMajorVersion === addedDependencyMajorVersion ? logger.out(message) : logger.warn(message); + + this.dependencies[currentDependency.name] = currentDependency; + } + } else { + this.dependencies[currentDependency.name] = currentDependency; } - } else { - dependencies[currentDependency.name] = currentDependency; } - } - }); + }); + } }); - _.each(dependencies, dependency => { - shelljs.cp("-R", dependency.directory, this.outputRoot); + _.each(this.dependencies, dependency => { + shelljs.cp("-Rf", dependency.directory, this.outputRoot); shelljs.rm("-rf", path.join(this.outputRoot, dependency.name, "node_modules")); if(dependency.isPlugin) { shelljs.rm("-rf", path.join(this.outputRoot, dependency.name, "platforms")); } }); + } + + public rebuild(treeDiff: IDiffResult): void { + this.rebuildChangedDirectories(treeDiff.changedDirectories); // Cache input tree let projectFilePath = path.join(this.projectDir, constants.PACKAGE_JSON_FILE_NAME); @@ -73,22 +82,6 @@ export class DestCopy implements IBroccoliPlugin { fs.writeFileSync(projectFilePath, JSON.stringify(projectFileContent, null, "\t"), { encoding: "utf8" }); } - private getDependencies(): IDictionary { - let result = Object.create(null); - if(fs.existsSync(this.outputRoot)) { - let dirs = fs.readdirSync(this.outputRoot); - _.each(dirs, dir => { - let filePath = path.join(dir, constants.PACKAGE_JSON_FILE_NAME); - if(fs.existsSync(filePath)) { - let fileContent = require(filePath); - result[fileContent.name] = fileContent; - } - }); - } - - return result; - } - private getDevDependencies(projectDir: string): IDictionary { let projectFilePath = path.join(projectDir, constants.PACKAGE_JSON_FILE_NAME); let projectFileContent = require(projectFilePath); diff --git a/package.json b/package.json index af3e11c8fe..c6919fbd43 100644 --- a/package.json +++ b/package.json @@ -37,6 +37,7 @@ "fibers": "https://github.com/icenium/node-fibers/tarball/v1.0.5.1", "filesize": "2.0.3", "gaze": "0.5.1", + "gulp": "3.9.0", "iconv-lite": "0.4.4", "inquirer": "0.8.2", "ios-sim-portable": "1.0.8", @@ -65,7 +66,9 @@ "shelljs": "0.3.0", "tabtab": "https://github.com/Icenium/node-tabtab/tarball/master", "temp": "0.8.1", + "through2": "2.0.0", "utf-8-validate": "https://github.com/telerik/utf-8-validate/tarball/master", + "vinyl-filter-since": "2.0.0", "winreg": "0.0.12", "ws": "0.7.1", "xcode": "https://github.com/NativeScript/node-xcode/archive/NativeScript-1.1.tar.gz", From 7513ad641783020b847c7ca8e4b8e63380e7a0e5 Mon Sep 17 00:00:00 2001 From: Fatme Havaluova Date: Fri, 26 Jun 2015 19:32:11 +0300 Subject: [PATCH 2/2] Unit tests --- lib/services/platform-service.ts | 2 +- lib/tools/broccoli/broccoli.d.ts | 4 +- lib/tools/broccoli/builder.ts | 5 +- lib/tools/broccoli/node-modules-dest-copy.ts | 78 +++++++++++--------- test/npm-support.ts | 54 +++++++++++--- 5 files changed, 92 insertions(+), 51 deletions(-) diff --git a/lib/services/platform-service.ts b/lib/services/platform-service.ts index 2e780a8f29..e47f318a92 100644 --- a/lib/services/platform-service.ts +++ b/lib/services/platform-service.ts @@ -185,7 +185,7 @@ export class PlatformService implements IPlatformService { // Process node_modules folder this.$pluginsService.ensureAllDependenciesAreInstalled().wait(); var tnsModulesDestinationPath = path.join(platformData.appDestinationDirectoryPath, constants.APP_FOLDER_NAME, PlatformService.TNS_MODULES_FOLDER_NAME); - this.$broccoliBuilder.prepareNodeModules(tnsModulesDestinationPath, this.$projectData.projectDir, lastModifiedTime).wait(); + this.$broccoliBuilder.prepareNodeModules(tnsModulesDestinationPath, this.$projectData.projectDir, platform, lastModifiedTime).wait(); this.$logger.out("Project successfully prepared"); }).future()(); diff --git a/lib/tools/broccoli/broccoli.d.ts b/lib/tools/broccoli/broccoli.d.ts index 93ae00eca4..7d4ba88820 100644 --- a/lib/tools/broccoli/broccoli.d.ts +++ b/lib/tools/broccoli/broccoli.d.ts @@ -152,7 +152,7 @@ interface BroccoliNode { } interface IBroccoliBuilder { - prepareNodeModules(outputPath: string, projectDir: string, lastModifiedTime?: Date): IFuture; + prepareNodeModules(outputPath: string, projectDir: string, platform: string, lastModifiedTime?: Date): IFuture; } interface IDiffResult { @@ -162,7 +162,7 @@ interface IDiffResult { interface IBroccoliPlugin { rebuild(diff: IDiffResult): any; - rebuildChangedDirectories?(changedDirectories: string[]): void; + rebuildChangedDirectories?(changedDirectories: string[], platform: string): void; cleanup? () : void; } diff --git a/lib/tools/broccoli/builder.ts b/lib/tools/broccoli/builder.ts index 2e5bc64330..9d8fba9437 100644 --- a/lib/tools/broccoli/builder.ts +++ b/lib/tools/broccoli/builder.ts @@ -20,7 +20,7 @@ export class Builder implements IBroccoliBuilder { private $injector: IInjector, private $logger: ILogger) { } - public prepareNodeModules(absoluteOutputPath: string, projectDir: string, lastModifiedTime?: Date): IFuture { + public prepareNodeModules(absoluteOutputPath: string, projectDir: string, platform: string, lastModifiedTime?: Date): IFuture { return (() => { let isNodeModulesModified = false; let nodeModulesPath = path.join(projectDir, "node_modules"); @@ -75,7 +75,8 @@ export class Builder implements IBroccoliBuilder { inputPath: projectDir, cachePath: "", outputRoot: absoluteOutputPath, - projectDir: projectDir + projectDir: projectDir, + platform: platform }); destCopy.rebuildChangedDirectories(_.keys(this.nodeModules)); diff --git a/lib/tools/broccoli/node-modules-dest-copy.ts b/lib/tools/broccoli/node-modules-dest-copy.ts index 07fd62e4b5..9f33ee8e8a 100644 --- a/lib/tools/broccoli/node-modules-dest-copy.ts +++ b/lib/tools/broccoli/node-modules-dest-copy.ts @@ -17,63 +17,68 @@ export class DestCopy implements IBroccoliPlugin { private dependencies: IDictionary = null; private devDependencies: IDictionary = null; - constructor(private inputPath: string, private cachePath: string, private outputRoot: string, private projectDir: string) { + constructor(private inputPath: string, + private cachePath: string, + private outputRoot: string, + private projectDir: string, + private platform: string, + private $fs: IFileSystem, + private $projectFilesManager: IProjectFilesManager) { this.dependencies = Object.create(null); this.devDependencies = this.getDevDependencies(projectDir); } - public rebuildChangedDirectories(changedDirectories: string[]): void { + public rebuildChangedDirectories(changedDirectories: string[], platform: string): void { _.each(changedDirectories, changedDirectoryAbsolutePath => { let pathToPackageJson = path.join(changedDirectoryAbsolutePath, "package.json"); - if(fs.existsSync(pathToPackageJson)) { - let packageJsonFiles = [pathToPackageJson]; - let nodeModulesFolderPath = path.join(changedDirectoryAbsolutePath, "node_modules"); - packageJsonFiles = packageJsonFiles.concat(this.enumeratePackageJsonFilesSync(nodeModulesFolderPath)); + let packageJsonFiles = fs.existsSync(pathToPackageJson) ? [pathToPackageJson] : []; + let nodeModulesFolderPath = path.join(changedDirectoryAbsolutePath, "node_modules"); + packageJsonFiles = packageJsonFiles.concat(this.enumeratePackageJsonFilesSync(nodeModulesFolderPath)); + + _.each(packageJsonFiles, packageJsonFilePath => { + let fileContent = require(packageJsonFilePath); + let isPlugin = fileContent.nativescript; + + if(!this.devDependencies[fileContent.name]) { // Don't flatten dev dependencies + + let currentDependency = { + name: fileContent.name, + version: fileContent.version, + directory: path.dirname(packageJsonFilePath), + isPlugin: isPlugin + }; - _.each(packageJsonFiles, packageJsonFilePath => { - let fileContent = require(packageJsonFilePath); - let isPlugin = fileContent.nativescript; + let addedDependency = this.dependencies[currentDependency.name]; + if (addedDependency) { + if (semver.gt(currentDependency.version, addedDependency.version)) { + let currentDependencyMajorVersion = semver.major(currentDependency.version); + let addedDependencyMajorVersion = semver.major(addedDependency.version); + + let message = `The depedency located at ${addedDependency.directory} with version ${addedDependency.version} will be replaced with dependency located at ${currentDependency.directory} with version ${currentDependency.version}`; + let logger = $injector.resolve("$logger"); + currentDependencyMajorVersion === addedDependencyMajorVersion ? logger.out(message) : logger.warn(message); - if(!this.devDependencies[fileContent.name]) { // Don't flatten dev dependencies - - let currentDependency = { - name: fileContent.name, - version: fileContent.version, - directory: path.dirname(packageJsonFilePath), - isPlugin: isPlugin - }; - - let addedDependency = this.dependencies[currentDependency.name]; - if (addedDependency) { - if (semver.gt(currentDependency.version, addedDependency.version)) { - let currentDependencyMajorVersion = semver.major(currentDependency.version); - let addedDependencyMajorVersion = semver.major(addedDependency.version); - - let message = `The depedency located at ${addedDependency.directory} with version ${addedDependency.version} will be replaced with dependency located at ${currentDependency.directory} with version ${currentDependency.version}`; - let logger = $injector.resolve("$logger"); - currentDependencyMajorVersion === addedDependencyMajorVersion ? logger.out(message) : logger.warn(message); - - this.dependencies[currentDependency.name] = currentDependency; - } - } else { this.dependencies[currentDependency.name] = currentDependency; } + } else { + this.dependencies[currentDependency.name] = currentDependency; } - }); - } + } + }); }); _.each(this.dependencies, dependency => { shelljs.cp("-Rf", dependency.directory, this.outputRoot); shelljs.rm("-rf", path.join(this.outputRoot, dependency.name, "node_modules")); if(dependency.isPlugin) { + this.$projectFilesManager.processPlatformSpecificFiles(path.join(this.outputRoot, dependency.name), platform).wait(); shelljs.rm("-rf", path.join(this.outputRoot, dependency.name, "platforms")); } }); } public rebuild(treeDiff: IDiffResult): void { - this.rebuildChangedDirectories(treeDiff.changedDirectories); + this.rebuildChangedDirectories(treeDiff.changedDirectories, ""); // Cache input tree let projectFilePath = path.join(this.projectDir, constants.PACKAGE_JSON_FILE_NAME); @@ -93,7 +98,10 @@ export class DestCopy implements IBroccoliPlugin { if(fs.existsSync(nodeModulesDirectoryPath)) { let contents = fs.readdirSync(nodeModulesDirectoryPath); for (let i = 0; i < contents.length; ++i) { - foundFiles.push(path.join(nodeModulesDirectoryPath, contents[i], "package.json")); + let packageJsonFilePath = path.join(nodeModulesDirectoryPath, contents[i], "package.json"); + if (fs.existsSync(packageJsonFilePath)) { + foundFiles.push(packageJsonFilePath); + } var directoryPath = path.join(nodeModulesDirectoryPath, contents[i], "node_modules"); if (fs.existsSync(directoryPath)) { diff --git a/test/npm-support.ts b/test/npm-support.ts index ff5d00cda6..24888880a0 100644 --- a/test/npm-support.ts +++ b/test/npm-support.ts @@ -88,15 +88,10 @@ function createProject(testInjector: IInjector, dependencies?: any): string { return tempFolder; } -describe("Npm support tests", () => { - it("Ensures that the installed dependencies are prepared correctly", () => { - let dependencies = { - "bplist": "0.0.4", - "lodash": "3.9.3" - }; - +function setupProject(): IFuture { + return (() => { let testInjector = createTestInjector(); - let projectFolder = createProject(testInjector, dependencies); + let projectFolder = createProject(testInjector); let fs = testInjector.resolve("fs"); @@ -112,7 +107,6 @@ describe("Npm support tests", () => { let androidFolderPath = path.join(projectFolder, "platforms", "android"); fs.ensureDirectoryExists(androidFolderPath).wait(); - // Mock platform data let appDestinationFolderPath = path.join(androidFolderPath, "assets"); let platformsData = testInjector.resolve("platformsData"); @@ -129,8 +123,45 @@ describe("Npm support tests", () => { } }; - let platformService = testInjector.resolve("platformService"); - platformService.preparePlatform("android").wait(); + return { + testInjector: testInjector, + projectFolder: projectFolder, + appDestinationFolderPath: appDestinationFolderPath, + }; + }).future()(); +} + +function addDependencies(testInjector: IInjector, projectFolder: string, dependencies: any): IFuture { + return (() => { + let fs = testInjector.resolve("fs"); + let packageJsonPath = path.join(projectFolder, "package.json"); + let packageJsonData = fs.readJson(packageJsonPath).wait(); + + let currentDependencies = packageJsonData.dependencies; + _.extend(currentDependencies, dependencies); + fs.writeJson(packageJsonPath, packageJsonData).wait(); + }).future()(); +} + +function preparePlatform(testInjector: IInjector): IFuture { + let platformService = testInjector.resolve("platformService"); + return platformService.preparePlatform("android"); +} + +describe("Npm support tests", () => { + let testInjector: IInjector, projectFolder: string, appDestinationFolderPath: string; + before(() => { + let projectSetup = setupProject().wait(); + testInjector = projectSetup.testInjector; + projectFolder = projectSetup.projectFolder; + appDestinationFolderPath = projectSetup.appDestinationFolderPath; + }); + it("Ensures that the installed dependencies are prepared correctly", () => { + // Setup + addDependencies(testInjector, projectFolder, {"bplist": "0.0.4"}).wait(); + + // Act + preparePlatform(testInjector).wait(); // Assert let tnsModulesFolderPath = path.join(appDestinationFolderPath, "app", "tns_modules"); @@ -139,6 +170,7 @@ describe("Npm support tests", () => { let bplistCreatorFolderPath = path.join(tnsModulesFolderPath, "bplist-creator"); let bplistParserFolderPath = path.join(tnsModulesFolderPath, "bplist-parser"); + let fs = testInjector.resolve("fs"); assert.isTrue(fs.exists(lodashFolderPath).wait()); assert.isTrue(fs.exists(bplistFolderPath).wait()); assert.isTrue(fs.exists(bplistCreatorFolderPath).wait());