diff --git a/.gitignore b/.gitignore index 05679ace79..3181cc2e10 100644 --- a/.gitignore +++ b/.gitignore @@ -29,9 +29,12 @@ results scratch/ .idea/ .settings/ -.vscode/ +.vscode/** +!.vscode/launch.json test-reports.xml npm-debug.log node_modules -docs/html \ No newline at end of file +docs/html + +!test-scripts/*.js \ No newline at end of file diff --git a/.npmignore b/.npmignore index 3d793de8cb..5fa204816d 100644 --- a/.npmignore +++ b/.npmignore @@ -21,6 +21,7 @@ lib/**/*.ts lib/**/*.js.map test/ +test-scripts/ .vscode lib/common/test/ coverage/ @@ -28,4 +29,4 @@ scratch/ *.suo .travis.yml docs/html/ -dev/ \ No newline at end of file +dev/ diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 0000000000..1e31432536 --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,70 @@ +{ + // Use IntelliSense to learn about possible Node.js debug attributes. + // Hover to view descriptions of existing attributes. + // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0", + "configurations": [ + { + "type": "node", + "request": "launch", + "name": "Launch Program (Node 6+)", + "program": "${workspaceRoot}/lib/nativescript-cli.js", + "cwd": "${workspaceRoot}", + "sourceMaps": true, + // define the arguments that you would like to pass to CLI, for example + // "args": [ "build", "android", "--justlaunch" ] + "args": [ + + ] + }, + + { + // in case you want to debug a single test, modify it's code to be `it.only(...` instead of `it(...` + "type": "node", + "request": "launch", + "name": "Launch Tests (Node 6+)", + "program": "${workspaceRoot}/node_modules/mocha/bin/_mocha", + "cwd": "${workspaceRoot}", + "sourceMaps": true + }, + + { + "type": "node", + "runtimeArgs": [ + "--harmony" + ], + "request": "launch", + "name": "Launch Program (Node 4, Node 5)", + "program": "${workspaceRoot}/lib/nativescript-cli.js", + "cwd": "${workspaceRoot}", + "sourceMaps": true, + // define the arguments that you would like to pass to CLI, for example + // "args": [ "build", "android", "--justlaunch" ] + "args": [ + + ] + }, + + { + // in case you want to debug a single test, modify it's code to be `it.only(...` instead of `it(...` + "type": "node", + "runtimeArgs": [ + "--harmony" + ], + "request": "launch", + "name": "Launch Tests (Node 4, Node 5)", + "program": "${workspaceRoot}/node_modules/mocha/bin/_mocha", + "cwd": "${workspaceRoot}", + "sourceMaps": true + }, + + { + "type": "node", + "request": "attach", + "name": "Attach to Process", + "port": 5858, + "sourceMaps": true + } + + ] +} \ No newline at end of file diff --git a/Gruntfile.js b/Gruntfile.js index 1b0adb041c..1eaaaade39 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -28,15 +28,7 @@ module.exports = function(grunt) { pkg: grunt.file.readJSON("package.json"), ts: { - options: { - target: 'es5', - module: 'commonjs', - sourceMap: true, - declaration: false, - removeComments: false, - noImplicitAny: true, - experimentalDecorators: true - }, + options: grunt.file.readJSON("tsconfig.json").compilerOptions, devlib: { src: ["lib/**/*.ts", "!lib/common/node_modules/**/*.ts"], @@ -131,7 +123,17 @@ module.exports = function(grunt) { }, clean: { - src: ["test/**/*.js*", "lib/**/*.js*", "!lib/common/vendor/*.js", "!lib/common/**/*.json", "!lib/common/Gruntfile.js", "!lib/common/node_modules/**/*", "!lib/common/hooks/**/*.js", "!lib/common/bin/*.js", "*.tgz"] + src: ["test/**/*.js*", + "lib/**/*.js*", + "!test-scripts/**/*", + "!lib/common/vendor/*.js", + "!lib/common/**/*.json", + "!lib/common/Gruntfile.js", + "!lib/common/node_modules/**/*", + "!lib/common/hooks/**/*.js", + "!lib/common/bin/*.js", + "!lib/common/test-scripts/**/*", + "*.tgz"] } }); diff --git a/bin/nativescript b/bin/nativescript index ebdd8eea3c..67e68db21a 100755 --- a/bin/nativescript +++ b/bin/nativescript @@ -1,4 +1,19 @@ #!/bin/sh AB_DIR="`dirname \"$0\"`" -node "$AB_DIR/nativescript.js" "$@" +NODE_VERSION=`node --version` +NODE4_VERSION_PREFIX="v4." +NODE5_VERSION_PREFIX="v5." + +# check if Node.js version is 4.x.x or 5.x.x - both of them do not support some of required features +# so we have to pass --harmony flag for them in order to enable spread opearator usage +# Use POSIX substring parameter expansion, so the code will work on all shells. + +if [ "${NODE_VERSION#$NODE4_VERSION_PREFIX*}" != "$NODE_VERSION" -o "${NODE_VERSION#$NODE5_VERSION_PREFIX*}" != "$NODE_VERSION" ] +then + # Node is 4.x.x or 5.x.x + node --harmony "$AB_DIR/nativescript.js" "$@" +else + # Node is NOT 4.x.x or 5.x.x + node "$AB_DIR/nativescript.js" "$@" +fi diff --git a/bin/nativescript.cmd b/bin/nativescript.cmd index 9074113019..0ecd2c8c87 100644 --- a/bin/nativescript.cmd +++ b/bin/nativescript.cmd @@ -1 +1,18 @@ -@node %~dp0\nativescript.js %* \ No newline at end of file +@for /F "delims=" %%i IN ('@node --version') DO @set node_ver=%%i + +@echo %node_ver% | @findstr /b /c:"v4." +@set is_node_4=%errorlevel% + +@echo %node_ver% | @findstr /b /c:"v5." +@set is_node_5=%errorlevel% + +@set use_harmony_flag=0 + +@if %is_node_4% == 0 @set use_harmony_flag=1 +@if %is_node_5% == 0 @set use_harmony_flag=1 + +@if %use_harmony_flag% == 1 ( + return @node --harmony %~dp0\nativescript.js %* +) else ( + @node %~dp0\nativescript.js %* +) \ No newline at end of file diff --git a/bin/tns b/bin/tns index ebdd8eea3c..67e68db21a 100755 --- a/bin/tns +++ b/bin/tns @@ -1,4 +1,19 @@ #!/bin/sh AB_DIR="`dirname \"$0\"`" -node "$AB_DIR/nativescript.js" "$@" +NODE_VERSION=`node --version` +NODE4_VERSION_PREFIX="v4." +NODE5_VERSION_PREFIX="v5." + +# check if Node.js version is 4.x.x or 5.x.x - both of them do not support some of required features +# so we have to pass --harmony flag for them in order to enable spread opearator usage +# Use POSIX substring parameter expansion, so the code will work on all shells. + +if [ "${NODE_VERSION#$NODE4_VERSION_PREFIX*}" != "$NODE_VERSION" -o "${NODE_VERSION#$NODE5_VERSION_PREFIX*}" != "$NODE_VERSION" ] +then + # Node is 4.x.x or 5.x.x + node --harmony "$AB_DIR/nativescript.js" "$@" +else + # Node is NOT 4.x.x or 5.x.x + node "$AB_DIR/nativescript.js" "$@" +fi diff --git a/bin/tns.cmd b/bin/tns.cmd index 9074113019..0ecd2c8c87 100644 --- a/bin/tns.cmd +++ b/bin/tns.cmd @@ -1 +1,18 @@ -@node %~dp0\nativescript.js %* \ No newline at end of file +@for /F "delims=" %%i IN ('@node --version') DO @set node_ver=%%i + +@echo %node_ver% | @findstr /b /c:"v4." +@set is_node_4=%errorlevel% + +@echo %node_ver% | @findstr /b /c:"v5." +@set is_node_5=%errorlevel% + +@set use_harmony_flag=0 + +@if %is_node_4% == 0 @set use_harmony_flag=1 +@if %is_node_5% == 0 @set use_harmony_flag=1 + +@if %use_harmony_flag% == 1 ( + return @node --harmony %~dp0\nativescript.js %* +) else ( + @node %~dp0\nativescript.js %* +) \ No newline at end of file diff --git a/lib/common b/lib/common index f6199c1aba..3925c26ed8 160000 --- a/lib/common +++ b/lib/common @@ -1 +1 @@ -Subproject commit f6199c1aba146f269251ef42f551d180869ddf9a +Subproject commit 3925c26ed8271b43d89da68276b321672d254a33 diff --git a/lib/device-sockets/ios/socket-request-executor.ts b/lib/device-sockets/ios/socket-request-executor.ts index dd46f7090b..756c18d860 100644 --- a/lib/device-sockets/ios/socket-request-executor.ts +++ b/lib/device-sockets/ios/socket-request-executor.ts @@ -13,8 +13,11 @@ export class IOSSocketRequestExecutor implements IiOSSocketRequestExecutor { return (() => { let npc = new iOSProxyServices.NotificationProxyClient(device, this.$injector); - let [alreadyConnected, readyForAttach, attachAvailable] = [this.$iOSNotification.alreadyConnected, this.$iOSNotification.readyForAttach, this.$iOSNotification.attachAvailable] - .map((notification) => this.$iOSNotificationService.awaitNotification(npc, notification, timeout)); + let data = [this.$iOSNotification.alreadyConnected, this.$iOSNotification.readyForAttach, this.$iOSNotification.attachAvailable] + .map((notification) => this.$iOSNotificationService.awaitNotification(npc, notification, timeout)), + alreadyConnected = data[0], + readyForAttach = data[1], + attachAvailable = data[2]; npc.postNotificationAndAttachForData(this.$iOSNotification.attachAvailabilityQuery); diff --git a/lib/services/platform-service.ts b/lib/services/platform-service.ts index 11744387f1..98d3ca2712 100644 --- a/lib/services/platform-service.ts +++ b/lib/services/platform-service.ts @@ -53,7 +53,9 @@ export class PlatformService implements IPlatformService { private addPlatform(platformParam: string): IFuture { return (() => { - let [platform, version] = platformParam.split("@"); + let data = platformParam.split("@"), + platform = data[0], + version = data[1]; this.validatePlatform(platform); @@ -427,7 +429,10 @@ export class PlatformService implements IPlatformService { public updatePlatforms(platforms: string[]): IFuture { return (() => { _.each(platforms, platformParam => { - let [platform, version] = platformParam.split("@"); + let data = platformParam.split("@"), + platform = data[0], + version = data[1]; + if (this.isPlatformInstalled(platform).wait()) { this.updatePlatform(platform, version).wait(); } else { diff --git a/lib/services/plugins-service.ts b/lib/services/plugins-service.ts index d1fc1440e2..e9c99c665f 100644 --- a/lib/services/plugins-service.ts +++ b/lib/services/plugins-service.ts @@ -163,7 +163,7 @@ export class PluginsService implements IPluginsService { .filter(dependencyName => _.startsWith(dependencyName, "@")) .each(scopedDependencyDir => { let contents = this.$fs.readDirectory(path.join(this.nodeModulesPath, scopedDependencyDir)).wait(); - installedDependencies = installedDependencies.concat(...contents.map(dependencyName => `${scopedDependencyDir}/${dependencyName}`)); + installedDependencies = installedDependencies.concat(contents.map(dependencyName => `${scopedDependencyDir}/${dependencyName}`)); }); let packageJsonContent = this.$fs.readJson(this.getPackageJsonFilePath()).wait(); diff --git a/lib/services/project-templates-service.ts b/lib/services/project-templates-service.ts index 5d21533644..d6d842c98f 100644 --- a/lib/services/project-templates-service.ts +++ b/lib/services/project-templates-service.ts @@ -18,7 +18,10 @@ export class ProjectTemplatesService implements IProjectTemplatesService { let templateName = originalTemplateName.toLowerCase(); // support @ syntax - let [name, version] = templateName.split("@"); + let data = templateName.split("@"), + name = data[0], + version = data[1]; + if(constants.RESERVED_TEMPLATE_NAMES[name]) { realTemplatePath = this.prepareNativeScriptTemplate(constants.RESERVED_TEMPLATE_NAMES[name], version, projectDir).wait(); } else { diff --git a/package.json b/package.json index 567d56a0d4..c348ccc425 100644 --- a/package.json +++ b/package.json @@ -10,10 +10,10 @@ }, "main": "./lib/nativescript-cli.js", "scripts": { - "test": "node_modules/.bin/istanbul cover node_modules/mocha/bin/_mocha", + "test": "node test-scripts/istanbul.js", "postinstall": "node postinstall.js", "preuninstall": "node preuninstall.js", - "mocha": "mocha", + "mocha": "node test-scripts/mocha.js", "tsc": "tsc", "test-watch": "node ./dev/tsc-to-mocha-watch.js" }, @@ -27,7 +27,6 @@ "mobile" ], "dependencies": { - "bluebird": "2.9.34", "bplist-parser": "0.1.0", "bufferpack": "0.0.6", "bufferutil": "https://github.com/telerik/bufferutil/tarball/v1.0.1.4", @@ -90,7 +89,7 @@ "grunt-ts": "6.0.0-beta.3", "grunt-tslint": "3.3.0", "istanbul": "0.4.5", - "mocha": "2.5.3", + "mocha": "3.1.2", "mocha-fibers": "https://github.com/NativeScript/mocha-fibers.git", "mocha-typescript": "^1.0.4", "should": "7.0.2", diff --git a/test-scripts/istanbul.js b/test-scripts/istanbul.js new file mode 100644 index 0000000000..ce0d201851 --- /dev/null +++ b/test-scripts/istanbul.js @@ -0,0 +1,18 @@ +"use strict"; + +const childProcess = require("child_process"); +const path = require("path"); +const pathToIstanbul = path.join(__dirname, "..", "node_modules", "istanbul", "lib", "cli.js"); +const pathToMocha = path.join(__dirname, "..", "node_modules", "mocha", "bin", "_mocha"); + +const istanbulArgs = [ pathToIstanbul, "cover", pathToMocha ]; + +const nodeArgs = require("../lib/common/test-scripts/node-args").getNodeArgs(); + +const args = nodeArgs.concat(istanbulArgs); + +const nodeProcess = childProcess.spawn("node", args, { stdio: "inherit"}); +nodeProcess.on("close", (code) => { + // We need this handler so if any test fails, we'll exit with same exit code as istanbul. + process.exit(code); +}); \ No newline at end of file diff --git a/test-scripts/mocha.js b/test-scripts/mocha.js new file mode 100644 index 0000000000..87121193bc --- /dev/null +++ b/test-scripts/mocha.js @@ -0,0 +1,15 @@ +"use strict"; + +const childProcess = require("child_process"); +const path = require("path"); +const pathToMocha = path.join(__dirname, "..", "node_modules", "mocha", "bin", "_mocha"); + +const nodeArgs = require("../lib/common/test-scripts/node-args").getNodeArgs(); + +const args = nodeArgs.concat(pathToMocha); + +const nodeProcess = childProcess.spawn("node", args, { stdio: "inherit"}); +nodeProcess.on("close", (code) => { + // We need this handler so if any test fails, we'll exit with same exit code as mocha. + process.exit(code); +}); diff --git a/test/platform-service.ts b/test/platform-service.ts index bceea61989..2a15d16b5b 100644 --- a/test/platform-service.ts +++ b/test/platform-service.ts @@ -226,14 +226,14 @@ describe('Platform Service Tests', () => { } function testPreparePlatform(platformToTest: string, release?: boolean) { - let { tempFolder, appFolderPath, app1FolderPath, appDestFolderPath, appResourcesFolderPath } = prepareDirStructure(); + let testDirData = prepareDirStructure(); // Add platform specific files to app and app1 folders let platformSpecificFiles = [ "test1.ios.js", "test1-ios-js", "test2.android.js", "test2-android-js" ]; - let destinationDirectories = [appFolderPath, app1FolderPath]; + let destinationDirectories = [testDirData.appFolderPath, testDirData.app1FolderPath]; _.each(destinationDirectories, directoryPath => { _.each(platformSpecificFiles, filePath => { @@ -246,10 +246,10 @@ describe('Platform Service Tests', () => { platformsData.platformsNames = ["ios", "android"]; platformsData.getPlatformData = (platform: string) => { return { - appDestinationDirectoryPath: appDestFolderPath, - appResourcesDestinationDirectoryPath: appResourcesFolderPath, + appDestinationDirectoryPath: testDirData.appDestFolderPath, + appResourcesDestinationDirectoryPath: testDirData.appResourcesFolderPath, normalizedPlatformName: platformToTest, - projectRoot: tempFolder, + projectRoot: testDirData.tempFolder, platformProjectService: { prepareProject: () => Future.fromResult(), validate: () => Future.fromResult(), @@ -266,7 +266,7 @@ describe('Platform Service Tests', () => { }; let projectData = testInjector.resolve("projectData"); - projectData.projectDir = tempFolder; + projectData.projectDir = testDirData.tempFolder; platformService = testInjector.resolve("platformService"); let options : IOptions = testInjector.resolve("options"); @@ -277,18 +277,18 @@ describe('Platform Service Tests', () => { let test2FileName = platformToTest.toLowerCase() === "ios" ? "test2.js" : "test1.js"; // Asserts that the files in app folder are process as platform specific - assert.isTrue(fs.exists(path.join(appDestFolderPath, "app", test1FileName)).wait()); - assert.isFalse(fs.exists(path.join(appDestFolderPath, "app", "test1-js")).wait()); + assert.isTrue(fs.exists(path.join(testDirData.appDestFolderPath, "app", test1FileName)).wait()); + assert.isFalse(fs.exists(path.join(testDirData.appDestFolderPath, "app", "test1-js")).wait()); - assert.isFalse(fs.exists(path.join(appDestFolderPath, "app", test2FileName)).wait()); - assert.isFalse(fs.exists(path.join(appDestFolderPath, "app", "test2-js")).wait()); + assert.isFalse(fs.exists(path.join(testDirData.appDestFolderPath, "app", test2FileName)).wait()); + assert.isFalse(fs.exists(path.join(testDirData.appDestFolderPath, "app", "test2-js")).wait()); // Asserts that the files in app1 folder aren't process as platform specific - assert.isFalse(fs.exists(path.join(appDestFolderPath, "app1")).wait(), "Asserts that the files in app1 folder aren't process as platform specific"); + assert.isFalse(fs.exists(path.join(testDirData.appDestFolderPath, "app1")).wait(), "Asserts that the files in app1 folder aren't process as platform specific"); if (release) { // Asserts that the files in tests folder aren't copied - assert.isFalse(fs.exists(path.join(appDestFolderPath, "tests")).wait(), "Asserts that the files in tests folder aren't copied"); + assert.isFalse(fs.exists(path.join(testDirData.appDestFolderPath, "tests")).wait(), "Asserts that the files in tests folder aren't copied"); } } @@ -310,20 +310,20 @@ describe('Platform Service Tests', () => { it("invalid xml is caught", () => { require("colors"); - let { tempFolder, appFolderPath, appDestFolderPath, appResourcesFolderPath } = prepareDirStructure(); + let testDirData = prepareDirStructure(); // generate invalid xml - let fileFullPath = path.join(appFolderPath, "file.xml"); + let fileFullPath = path.join(testDirData.appFolderPath, "file.xml"); fs.writeFile(fileFullPath, "").wait(); let platformsData = testInjector.resolve("platformsData"); platformsData.platformsNames = ["android"]; platformsData.getPlatformData = (platform: string) => { return { - appDestinationDirectoryPath: appDestFolderPath, - appResourcesDestinationDirectoryPath: appResourcesFolderPath, + appDestinationDirectoryPath: testDirData.appDestFolderPath, + appResourcesDestinationDirectoryPath: testDirData.appResourcesFolderPath, normalizedPlatformName: "Android", - projectRoot: tempFolder, + projectRoot: testDirData.tempFolder, platformProjectService: { prepareProject: () => Future.fromResult(), validate: () => Future.fromResult(), @@ -340,7 +340,7 @@ describe('Platform Service Tests', () => { }; let projectData = testInjector.resolve("projectData"); - projectData.projectDir = tempFolder; + projectData.projectDir = testDirData.tempFolder; platformService = testInjector.resolve("platformService"); let oldLoggerWarner = testInjector.resolve("$logger").warn; diff --git a/tsconfig.json b/tsconfig.json index b1a8406486..d4c2f54f5b 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,6 +1,6 @@ { "compilerOptions": { - "target": "es5", + "target": "es6", "module": "commonjs", "sourceMap": true, "declaration": false,