From 4fdafdeaef67b776e96ecb7d41f8d165100de1fa Mon Sep 17 00:00:00 2001 From: rosen-vladimirov Date: Wed, 5 Nov 2014 14:47:57 +0200 Subject: [PATCH] Add validation for command parameters Add validation for the parameters that each command accepts. Add logic to check if command has mandatory parameters and all of them are provided - if any of them is missing, command is not executed. Add logic to validate all arguments passed to command - if the command does not accept arguments, but there are some passed to it, it is not executed. Add ICommandParameter interface to describe command parameter. Add allowedParameters property to ICommand interface. Add canExecute method to ICommand interface. It is not mandatory to implement it and it is used when the command will validate the parameters on its own. The common validation is implemented in CommandsService. ICommandParameter describes one parameter that the command accepts. It can be mandatory for the command or not. That's why I've added mandatory boolean parameter to the interface. Each parameter have its own logic for valid values, that's why ICommandParameter has validate method. It is called from the CommandsService when the arguments are validated. CommandsService itself tries to validate all command arguments. One special case is when the command is hierarchical. In this situation the root command is validated first, but it doesn't have own definition, so it doesn't have allowed parameters. That's why CommandsService checks if the command is valid hierarchical command. If command has canExecute method implemented, CommandsService will use it to validate the arguments. If not, it will try to validate all passed command line arguments with the allowed parameters of the command, by checking their count, calling validate method, etc. Each command has different number of allowed parameters. In most of the cases the command parameter is string and the only requirement for it is to be non-empty. That's why new StringCommandParameter class is added. It is used to define such parameters. In case the parameter has more complicated logic, new class, that implements ICommandParameter is added for it. Remove some tests as the validation logic is moved outside of some methods - in the command parameters. Add new unit tests. https://huboard.com/NativeScript/nativescript-cli#/issues/48065867 --- lib/bootstrap.ts | 1 + lib/commands/add-platform.ts | 18 +- lib/commands/build.ts | 6 +- lib/commands/create-project.ts | 23 ++- lib/commands/deploy.ts | 8 +- lib/commands/emulate.ts | 9 +- lib/commands/list-devices.ts | 5 +- lib/commands/list-platforms.ts | 2 + lib/commands/post-install.ts | 2 + lib/commands/prepare.ts | 5 +- lib/commands/remove-platform.ts | 18 +- lib/commands/run.ts | 6 +- lib/commands/update-platform.ts | 18 +- lib/common | 2 +- lib/definitions/platform.d.ts | 2 + lib/platform-command-param.ts | 14 ++ lib/services/platform-service.ts | 20 +-- test/platform-commands.ts | 297 +++++++++++++++++++++++++++++++ test/platform-service.ts | 32 +--- test/stubs.ts | 11 +- 20 files changed, 435 insertions(+), 64 deletions(-) create mode 100644 lib/platform-command-param.ts create mode 100644 test/platform-commands.ts diff --git a/lib/bootstrap.ts b/lib/bootstrap.ts index 65a957a78f..c26c2acf3f 100644 --- a/lib/bootstrap.ts +++ b/lib/bootstrap.ts @@ -18,6 +18,7 @@ $injector.require("analyticsSettingsService", "./services/analytics-settings-ser $injector.require("emulatorSettingsService", "./services/emulator-settings-service"); +$injector.require("platformCommandParameter", "./platform-command-param"); $injector.requireCommand("create", "./commands/create-project"); $injector.requireCommand("platform|*list", "./commands/list-platforms"); $injector.requireCommand("platform|add", "./commands/add-platform"); diff --git a/lib/commands/add-platform.ts b/lib/commands/add-platform.ts index 85923e452a..ad1164df3c 100644 --- a/lib/commands/add-platform.ts +++ b/lib/commands/add-platform.ts @@ -1,12 +1,28 @@ /// +"use strict"; export class AddPlatformCommand implements ICommand { - constructor(private $platformService: IPlatformService) { } + constructor(private $platformService: IPlatformService, + private $errors: IErrors) { } execute(args: string[]): IFuture { return (() => { this.$platformService.addPlatforms(args).wait(); }).future()(); } + + allowedParameters: ICommandParameter[] = []; + + canExecute(args: string[]): IFuture { + return (() => { + if(!args || args.length === 0) { + this.$errors.fail("No platform specified. Please specify a platform to add"); + } + + _.each(args, arg => this.$platformService.validatePlatform(arg)); + + return true; + }).future()(); + } } $injector.registerCommand("platform|add", AddPlatformCommand); \ No newline at end of file diff --git a/lib/commands/build.ts b/lib/commands/build.ts index d483add028..3c81042226 100644 --- a/lib/commands/build.ts +++ b/lib/commands/build.ts @@ -1,12 +1,16 @@ /// +"use strict"; export class BuildCommand implements ICommand { - constructor(private $platformService: IPlatformService) { } + constructor(private $platformService: IPlatformService, + private $platformCommandParameter: ICommandParameter) { } execute(args: string[]): IFuture { return (() => { this.$platformService.buildPlatform(args[0]).wait(); }).future()(); } + + allowedParameters = [this.$platformCommandParameter]; } $injector.registerCommand("build", BuildCommand); \ No newline at end of file diff --git a/lib/commands/create-project.ts b/lib/commands/create-project.ts index 4333a5dace..5aeb363d7f 100644 --- a/lib/commands/create-project.ts +++ b/lib/commands/create-project.ts @@ -1,7 +1,26 @@ /// +"use strict"; + +export class ProjectCommandParameter implements ICommandParameter { + constructor(private $errors: IErrors, + private $projectNameValidator: IProjectNameValidator) { } + + mandatory = true; + validate(value: string): IFuture { + return (() => { + if(!value) { + this.$errors.fail("You must specify when creating a new project."); + } + + return this.$projectNameValidator.validate(value); + }).future()(); + } +} export class CreateProjectCommand implements ICommand { - constructor(private $projectService: IProjectService) { } + constructor(private $projectService: IProjectService, + private $errors: IErrors, + private $projectNameValidator: IProjectNameValidator) { } public enableHooks = false; @@ -10,5 +29,7 @@ export class CreateProjectCommand implements ICommand { this.$projectService.createProject(args[0]).wait(); }).future()(); } + + allowedParameters = [new ProjectCommandParameter(this.$errors, this.$projectNameValidator) ] } $injector.registerCommand("create", CreateProjectCommand); diff --git a/lib/commands/deploy.ts b/lib/commands/deploy.ts index a2893c3a72..5c0d29d011 100644 --- a/lib/commands/deploy.ts +++ b/lib/commands/deploy.ts @@ -1,10 +1,14 @@ /// +"use strict"; export class DeployOnDeviceCommand implements ICommand { - constructor(private $platformService: IPlatformService) { } + constructor(private $platformService: IPlatformService, + private $platformCommandParameter: ICommandParameter) { } execute(args: string[]): IFuture { return this.$platformService.deployOnDevice(args[0]); } + + allowedParameters = [this.$platformCommandParameter]; } -$injector.registerCommand("deploy", DeployOnDeviceCommand); \ No newline at end of file +$injector.registerCommand("deploy", DeployOnDeviceCommand); diff --git a/lib/commands/emulate.ts b/lib/commands/emulate.ts index 5dc69cc936..9344392a20 100644 --- a/lib/commands/emulate.ts +++ b/lib/commands/emulate.ts @@ -1,8 +1,11 @@ /// export class EmulateCommand implements ICommand { - constructor(private $platformService: IPlatformService) { } + constructor(private $platformService: IPlatformService, + private $platformCommandParameter: ICommandParameter) { } - execute(args: string[]): IFuture { return this.$platformService.deployOnEmulator(args[0]);} + execute(args: string[]): IFuture { return this.$platformService.deployOnEmulator(args[0]); } + + allowedParameters = [this.$platformCommandParameter]; } -$injector.registerCommand("emulate", EmulateCommand); \ No newline at end of file +$injector.registerCommand("emulate", EmulateCommand); diff --git a/lib/commands/list-devices.ts b/lib/commands/list-devices.ts index ba4a548b90..c957999749 100644 --- a/lib/commands/list-devices.ts +++ b/lib/commands/list-devices.ts @@ -4,7 +4,8 @@ import util = require("util") export class ListDevicesCommand implements ICommand { constructor(private $devicesServices: Mobile.IDevicesServices, - private $logger: ILogger) { } + private $logger: ILogger, + private $stringParameter: ICommandParameter) { } execute(args: string[]): IFuture { return (() => { @@ -17,5 +18,7 @@ export class ListDevicesCommand implements ICommand { this.$devicesServices.execute(action, undefined, {allowNoDevices: true}).wait(); }).future()(); } + + allowedParameters = [this.$stringParameter]; } $injector.registerCommand("list-devices", ListDevicesCommand); diff --git a/lib/commands/list-platforms.ts b/lib/commands/list-platforms.ts index 22f261dfc4..6c73dfa08e 100644 --- a/lib/commands/list-platforms.ts +++ b/lib/commands/list-platforms.ts @@ -24,5 +24,7 @@ export class ListPlatformsCommand implements ICommand { } }).future()(); } + + allowedParameters: ICommandParameter[] = []; } $injector.registerCommand("platform|*list", ListPlatformsCommand); diff --git a/lib/commands/post-install.ts b/lib/commands/post-install.ts index d1b0dc1fbb..9e84028643 100644 --- a/lib/commands/post-install.ts +++ b/lib/commands/post-install.ts @@ -21,5 +21,7 @@ export class PostInstallCommand implements ICommand { this.$autoCompletionService.enableAutoCompletion().wait(); }).future()(); } + + public allowedParameters: ICommandParameter[] = []; } $injector.registerCommand("dev-post-install", PostInstallCommand); \ No newline at end of file diff --git a/lib/commands/prepare.ts b/lib/commands/prepare.ts index 4821ff66e9..8b1c1b012f 100644 --- a/lib/commands/prepare.ts +++ b/lib/commands/prepare.ts @@ -1,12 +1,15 @@ /// export class PrepareCommand implements ICommand { - constructor(private $platformService: IPlatformService) { } + constructor(private $platformService: IPlatformService, + private $platformCommandParameter: ICommandParameter) { } execute(args: string[]): IFuture { return (() => { this.$platformService.preparePlatform(args[0]).wait(); }).future()(); } + + allowedParameters = [this.$platformCommandParameter]; } $injector.registerCommand("prepare", PrepareCommand); diff --git a/lib/commands/remove-platform.ts b/lib/commands/remove-platform.ts index c45586470d..e7b34df76a 100644 --- a/lib/commands/remove-platform.ts +++ b/lib/commands/remove-platform.ts @@ -1,12 +1,28 @@ /// +"use strict"; export class RemovePlatformCommand implements ICommand { - constructor(private $platformService: IPlatformService) { } + constructor(private $platformService: IPlatformService, + private $errors: IErrors) { } execute(args: string[]): IFuture { return (() => { this.$platformService.removePlatforms(args).wait(); }).future()(); } + + canExecute(args: string[]): IFuture { + return (() => { + if(!args || args.length === 0) { + this.$errors.fail("No platform specified. Please specify a platform to remove"); + } + + _.each(args, arg => this.$platformService.validatePlatformInstalled(arg)); + + return true; + }).future()(); + } + + allowedParameters: ICommandParameter[] = []; } $injector.registerCommand("platform|remove", RemovePlatformCommand); \ No newline at end of file diff --git a/lib/commands/run.ts b/lib/commands/run.ts index 39292de7c5..ac3de494e3 100644 --- a/lib/commands/run.ts +++ b/lib/commands/run.ts @@ -1,12 +1,16 @@ /// +"use strict"; export class RunCommand implements ICommand { - constructor(private $platformService: IPlatformService) { } + constructor(private $platformService: IPlatformService, + private $platformCommandParameter: ICommandParameter) { } execute(args: string[]): IFuture { return (() => { this.$platformService.runPlatform(args[0]).wait(); }).future()(); } + + allowedParameters = [this.$platformCommandParameter]; } $injector.registerCommand("run", RunCommand); diff --git a/lib/commands/update-platform.ts b/lib/commands/update-platform.ts index 021b614d16..1c7dc22ae4 100644 --- a/lib/commands/update-platform.ts +++ b/lib/commands/update-platform.ts @@ -1,12 +1,28 @@ /// +"use strict"; export class UpdatePlatformCommand implements ICommand { - constructor(private $platformService: IPlatformService) { } + constructor(private $platformService: IPlatformService, + private $errors:IErrors) { } execute(args: string[]): IFuture { return (() => { this.$platformService.updatePlatforms(args).wait(); }).future()(); } + + canExecute(args: string[]): IFuture { + return (() => { + if(!args || args.length === 0) { + this.$errors.fail("No platform specified. Please specify platforms to update."); + } + + _.each(args, arg => this.$platformService.validatePlatformInstalled(arg)); + + return true; + }).future()(); + } + + allowedParameters: ICommandParameter[] = []; } $injector.registerCommand("platform|update", UpdatePlatformCommand); \ No newline at end of file diff --git a/lib/common b/lib/common index 8426225275..885bdcd12a 160000 --- a/lib/common +++ b/lib/common @@ -1 +1 @@ -Subproject commit 8426225275bc36770ea536008230a62059be3219 +Subproject commit 885bdcd12afaf3bfa82a5633c704a1c77634fb6a diff --git a/lib/definitions/platform.d.ts b/lib/definitions/platform.d.ts index 4be0764857..e60e4c0634 100644 --- a/lib/definitions/platform.d.ts +++ b/lib/definitions/platform.d.ts @@ -10,6 +10,8 @@ interface IPlatformService { buildPlatform(platform: string): IFuture; deployOnDevice(platform: string): IFuture; deployOnEmulator(platform: string): IFuture; + validatePlatformInstalled(platform: string): void; + validatePlatform(platform: string): void; } interface IPlatformData { diff --git a/lib/platform-command-param.ts b/lib/platform-command-param.ts new file mode 100644 index 0000000000..1e5389d7fc --- /dev/null +++ b/lib/platform-command-param.ts @@ -0,0 +1,14 @@ +/// +"use strict"; + +export class PlatformCommandParameter implements ICommandParameter { + constructor(private $platformService: IPlatformService) { } + mandatory = true; + validate(value: string): IFuture { + return (() => { + this.$platformService.validatePlatformInstalled(value); + return true; + }).future()(); + } +} +$injector.register("platformCommandParameter", PlatformCommandParameter); \ No newline at end of file diff --git a/lib/services/platform-service.ts b/lib/services/platform-service.ts index 0c74c5b82c..6598df3a92 100644 --- a/lib/services/platform-service.ts +++ b/lib/services/platform-service.ts @@ -21,10 +21,6 @@ export class PlatformService implements IPlatformService { public addPlatforms(platforms: string[]): IFuture { return (() => { - if(!platforms || platforms.length === 0) { - this.$errors.fail("No platform specified. Please specify a platform to add"); - } - var platformsDir = this.$projectData.platformsDir; this.$fs.ensureDirectoryExists(platformsDir).wait(); @@ -136,7 +132,6 @@ export class PlatformService implements IPlatformService { public preparePlatform(platform: string): IFuture { return (() => { - this.validatePlatformInstalled(platform); platform = platform.toLowerCase(); var platformData = this.$platformsData.getPlatformData(platform); @@ -166,7 +161,6 @@ export class PlatformService implements IPlatformService { public buildPlatform(platform: string): IFuture { return (() => { - this.validatePlatformInstalled(platform); platform = platform.toLowerCase(); var platformData = this.$platformsData.getPlatformData(platform); @@ -177,7 +171,6 @@ export class PlatformService implements IPlatformService { public runPlatform(platform: string): IFuture { return (() => { - this.validatePlatformInstalled(platform); platform = platform.toLowerCase(); this.preparePlatform(platform).wait(); @@ -191,10 +184,6 @@ export class PlatformService implements IPlatformService { public removePlatforms(platforms: string[]): IFuture { return (() => { - if(!platforms || platforms.length === 0) { - this.$errors.fail("No platform specified. Please specify a platform to remove"); - } - _.each(platforms, platform => { this.validatePlatformInstalled(platform); @@ -207,10 +196,6 @@ export class PlatformService implements IPlatformService { public updatePlatforms(platforms: string[]): IFuture { return (() => { - if(!platforms || platforms.length === 0) { - this.$errors.fail("No platform specified. Please specify a platform to remove"); - } - _.each(platforms, platform => { var parts = platform.split("@"); platform = parts[0].toLowerCase(); @@ -224,7 +209,6 @@ export class PlatformService implements IPlatformService { public deployOnDevice(platform: string): IFuture { return (() => { - this.validatePlatformInstalled(platform); platform = platform.toLowerCase(); var platformData = this.$platformsData.getPlatformData(platform); @@ -267,7 +251,7 @@ export class PlatformService implements IPlatformService { }).future()(); } - private validatePlatform(platform: string): void { + public validatePlatform(platform: string): void { if(!platform) { this.$errors.fail("No platform specified.") } @@ -283,7 +267,7 @@ export class PlatformService implements IPlatformService { } } - private validatePlatformInstalled(platform: string): void { + public validatePlatformInstalled(platform: string): void { this.validatePlatform(platform); if (!this.isPlatformInstalled(platform).wait()) { diff --git a/test/platform-commands.ts b/test/platform-commands.ts new file mode 100644 index 0000000000..b23fcd75f8 --- /dev/null +++ b/test/platform-commands.ts @@ -0,0 +1,297 @@ +/// +"use strict"; + +import yok = require('../lib/common/yok'); +import stubs = require('./stubs'); +import PlatformAddCommandLib = require("../lib/commands/add-platform"); +import PlatformRemoveCommandLib = require("../lib/commands/remove-platform"); +import PlatformUpdateCommandLib = require("../lib/commands/update-platform"); +import PlatformServiceLib = require('../lib/services/platform-service'); +import StaticConfigLib = require("../lib/config"); +import CommandsServiceLib = require("../lib/common/services/commands-service"); +import path = require("path"); +import Future = require("fibers/future"); +var assert = require("chai").assert; +var options: any = require("./../lib/options"); +var isCommandExecuted = true; + +class PlatformData implements IPlatformData { + frameworkPackageName = "tns-android"; + normalizedPlatformName = "Android"; + platformProjectService: IPlatformProjectService = null; + emulatorServices: Mobile.IEmulatorPlatformServices = null; + projectRoot = ""; + deviceBuildOutputPath = ""; + validPackageNamesForDevice: string[] = []; + frameworkFilesExtensions = [".jar", ".dat"]; +} + +class ErrorsNoFailStub implements IErrors { + fail(formatStr: string, ...args: any[]): void; + fail(opts: { formatStr?: string; errorCode?: number; suppressCommandHelp?: boolean }, ...args: any[]): void; + + fail(...args: any[]) { throw new Error(); } + + beginCommand(action: () => IFuture, printHelpCommand: () => IFuture): IFuture { + return (() => { + try { + var result = action().wait(); + } catch(ex) { + return false; + } + + return result; + }).future()(); + } + + verifyHeap(message: string): void { } +} + +class PlatformsData implements IPlatformsData { + platformsNames = ["android", "ios"]; + getPlatformData(platform: string): IPlatformData { + if(_.contains(this.platformsNames, platform)) { + return new PlatformData(); + } + + return null; + } +} + +function createTestInjector() { + var testInjector = new yok.Yok(); + + testInjector.register("injector", testInjector); + testInjector.register("hooksService", stubs.HooksServiceStub); + testInjector.register("staticConfig", StaticConfigLib.StaticConfig); + testInjector.register('platformService', PlatformServiceLib.PlatformService); + testInjector.register('errors', ErrorsNoFailStub); + testInjector.register('logger', stubs.LoggerStub); + testInjector.register('npm', stubs.NPMStub); + testInjector.register('projectData', stubs.ProjectDataStub); + testInjector.register('platformsData', PlatformsData); + testInjector.register('devicesServices', {}); + testInjector.register('projectDataService', stubs.ProjectDataService); + testInjector.register('prompter', {}); + testInjector.register('commands-service', CommandsServiceLib.CommandsService); + testInjector.registerCommand("platform|add", PlatformAddCommandLib.AddPlatformCommand); + testInjector.registerCommand("platform|remove", PlatformRemoveCommandLib.RemovePlatformCommand); + testInjector.registerCommand("platform|update", PlatformUpdateCommandLib.UpdatePlatformCommand); + + + return testInjector; +} + +describe('Platform Service Tests', () => { + var platformService: IPlatformService, testInjector: IInjector; + var commandsService: ICommandsService; + beforeEach(() => { + testInjector = createTestInjector(); + testInjector.register("fs", stubs.FileSystemStub); + commandsService = testInjector.resolve("commands-service"); + platformService = testInjector.resolve("platformService"); + }); + + describe("platform commands tests", () => { + describe("#AddPlatformCommand", () => { + it("is not executed when platform is not passed", () => { + isCommandExecuted = false; + commandsService.executeCommandUnchecked = (): IFuture => { + return (() => { + isCommandExecuted = true; + return false; + }).future()(); + } + + commandsService.tryExecuteCommand("platform|add", []).wait(); + assert.isFalse(isCommandExecuted); + }); + + it("is not executed when platform is not valid", () => { + isCommandExecuted = false; + commandsService.executeCommandUnchecked = (): IFuture => { + return (() => { + isCommandExecuted = true; + return false; + }).future()(); + } + + commandsService.tryExecuteCommand("platform|add", ["invalidPlatform"]).wait(); + assert.isFalse(isCommandExecuted); + }); + + it("is executed when platform is valid", () => { + isCommandExecuted = false; + commandsService.executeCommandUnchecked = (): IFuture => { + return (() => { + isCommandExecuted = true; + return false; + }).future()(); + } + + commandsService.tryExecuteCommand("platform|add", ["android"]).wait(); + assert.isTrue(isCommandExecuted); + }); + + it("is executed when all platforms are valid", () => { + isCommandExecuted = false; + commandsService.executeCommandUnchecked = (): IFuture => { + return (() => { + isCommandExecuted = true; + return false; + }).future()(); + } + + commandsService.tryExecuteCommand("platform|add", ["android", "ios"]).wait(); + assert.isTrue(isCommandExecuted); + }); + + it("is not executed when at least one platform is not valid", () => { + isCommandExecuted = false; + commandsService.executeCommandUnchecked = (): IFuture => { + return (() => { + isCommandExecuted = true; + return false; + }).future()(); + } + + commandsService.tryExecuteCommand("platform|add", ["ios", "invalid"]).wait(); + assert.isFalse(isCommandExecuted); + }); + }); + + describe("#RemovePlatformCommand", () => { + it("is not executed when platform is not passed", () => { + isCommandExecuted = false; + commandsService.executeCommandUnchecked = (): IFuture => { + return (() => { + isCommandExecuted = true; + return false; + }).future()(); + } + + commandsService.tryExecuteCommand("platform|remove", []).wait(); + assert.isFalse(isCommandExecuted); + }); + + it("is not executed when platform is not valid", () => { + isCommandExecuted = false; + commandsService.executeCommandUnchecked = (): IFuture => { + return (() => { + isCommandExecuted = true; + return false; + }).future()(); + } + + commandsService.tryExecuteCommand("platform|remove", ["invalidPlatform"]).wait(); + assert.isFalse(isCommandExecuted); + }); + + it("is executed when platform is valid", () => { + isCommandExecuted = false; + commandsService.executeCommandUnchecked = (): IFuture => { + return (() => { + isCommandExecuted = true; + return false; + }).future()(); + } + + commandsService.tryExecuteCommand("platform|remove", ["android"]).wait(); + assert.isTrue(isCommandExecuted); + }); + + it("is executed when all platforms are valid", () => { + isCommandExecuted = false; + commandsService.executeCommandUnchecked = (): IFuture => { + return (() => { + isCommandExecuted = true; + return false; + }).future()(); + } + + commandsService.tryExecuteCommand("platform|remove", ["android", "ios"]).wait(); + assert.isTrue(isCommandExecuted); + }); + + it("is not executed when at least one platform is not valid", () => { + isCommandExecuted = false; + commandsService.executeCommandUnchecked = (): IFuture => { + return (() => { + isCommandExecuted = true; + return false; + }).future()(); + } + + commandsService.tryExecuteCommand("platform|remove", ["ios", "invalid"]).wait(); + assert.isFalse(isCommandExecuted); + }); + }); + + describe("#UpdatePlatformCommand", () => { + it("is not executed when platform is not passed", () => { + isCommandExecuted = false; + commandsService.executeCommandUnchecked = (): IFuture => { + return (() => { + isCommandExecuted = true; + return false; + }).future()(); + } + + commandsService.tryExecuteCommand("platform|update", []).wait(); + assert.isFalse(isCommandExecuted); + }); + + it("is not executed when platform is not valid", () => { + isCommandExecuted = false; + commandsService.executeCommandUnchecked = (): IFuture => { + return (() => { + isCommandExecuted = true; + return false; + }).future()(); + } + + commandsService.tryExecuteCommand("platform|update", ["invalidPlatform"]).wait(); + assert.isFalse(isCommandExecuted); + }); + + it("is executed when platform is valid", () => { + isCommandExecuted = false; + commandsService.executeCommandUnchecked = (): IFuture => { + return (() => { + isCommandExecuted = true; + return false; + }).future()(); + } + + commandsService.tryExecuteCommand("platform|update", ["android"]).wait(); + assert.isTrue(isCommandExecuted); + }); + + it("is executed when all platforms are valid", () => { + isCommandExecuted = false; + commandsService.executeCommandUnchecked = (): IFuture => { + return (() => { + isCommandExecuted = true; + return false; + }).future()(); + } + + commandsService.tryExecuteCommand("platform|update", ["android", "ios"]).wait(); + assert.isTrue(isCommandExecuted); + }); + + it("is not executed when at least one platform is not valid", () => { + isCommandExecuted = false; + commandsService.executeCommandUnchecked = (): IFuture => { + return (() => { + isCommandExecuted = true; + return false; + }).future()(); + } + + commandsService.tryExecuteCommand("platform|update", ["ios", "invalid"]).wait(); + assert.isFalse(isCommandExecuted); + }); + }); + }); +}); \ No newline at end of file diff --git a/test/platform-service.ts b/test/platform-service.ts index 324d6de6a4..c483e4e395 100644 --- a/test/platform-service.ts +++ b/test/platform-service.ts @@ -51,14 +51,6 @@ describe('Platform Service Tests', () => { describe("add platform unit tests", () => { describe("#add platform()", () => { - it("should fail if platform is null or undefined", () => { - (() => platformService.addPlatforms(null).wait()).should.throw(); - (() => platformService.addPlatforms(undefined).wait()).should.throw(); - }); - it("should fail if platform not supported", () => { - (() => platformService.addPlatforms(["fdhf"]).wait()).should.throw(); - (() => platformService.addPlatforms(["test"]).wait()).should.throw(); - }); it("should not fail if platform is not normalized", () => { var fs = testInjector.resolve("fs"); fs.exists = () => Future.fromResult(false); @@ -134,13 +126,8 @@ describe('Platform Service Tests', () => { }); describe("remove platform unit tests", () => { - it("should fail if platform null or undefined", () => { - (() => platformService.removePlatforms(null).wait()).should.throw(); - (() => platformService.removePlatforms(undefined).wait()).should.throw(); - }); it("should fail when platforms are not added", () => { testInjector.resolve("fs").exists = () => Future.fromResult(false); - (() => platformService.removePlatforms(["android"]).wait()).should.throw(); (() => platformService.removePlatforms(["ios"]).wait()).should.throw(); }); @@ -160,25 +147,8 @@ describe('Platform Service Tests', () => { }); describe("update Platform", () => { - - describe('#updatePlatforms()', function(){ - it('should fail when no services provided', () => { - (() => platformService.updatePlatforms([]).wait()).should.throw(); - }); - }); - describe("#updatePlatform(platform)", () => { - it ("should fail if platform null or undefined", () => { - (() => platformService.updatePlatforms(null).wait()).should.throw(); - (() => platformService.updatePlatforms(undefined).wait()).should.throw(); - }); - - it ("should fail if platform not supported", () => { - (() => platformService.updatePlatforms(["unsupported"]).wait()).should.throw(); - (() => platformService.updatePlatforms(["aaa"]).wait()).should.throw(); - }); - - it ("should fail when the versions are the same", () => { + it("should fail when the versions are the same", () => { var npm: INodePackageManager = testInjector.resolve("npm"); npm.getLatestVersion = () => (() => "0.2.0").future()(); npm.getCacheRootPath = () => (() => "").future()(); diff --git a/test/stubs.ts b/test/stubs.ts index 0f4f89b0aa..dc8fa0aef8 100644 --- a/test/stubs.ts +++ b/test/stubs.ts @@ -255,4 +255,13 @@ export class ProjectTemplatesService implements IProjectTemplatesService { } } - +export class HooksServiceStub implements IHooksService { + initialize(commandName: string): void { + } + executeBeforeHooks(): IFuture { + return (() => { }).future()(); + } + executeAfterHooks(): IFuture { + return (() => { }).future()(); + } +}