Skip to content

Commit

Permalink
Merge pull request #1638 from NativeScript/milanov/add-angular-and-ng…
Browse files Browse the repository at this point in the history
…-template-parameters

Simplified creating angular template project
  • Loading branch information
TsvetanMilanov committed Mar 23, 2016
2 parents 219a1ad + 28202a7 commit 111a986
Show file tree
Hide file tree
Showing 10 changed files with 172 additions and 25 deletions.
4 changes: 3 additions & 1 deletion docs/man_pages/project/creation/create.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@ create
Usage | Synopsis
---|---
Create from default JavaScript template | `$ tns create <App Name> [--path <Directory>] [--appid <App ID>]`
Create from default TypeScript template | `$ tns create <App Name> [--path <Directory>] [--appid <App ID> --template typescript` OR `$ tns create <App Name> [--path <Directory>] [--appid <App ID> --template tsc`
Create from default TypeScript template | `$ tns create <App Name> --template typescript [--path <Directory>] [--appid <App ID>]` OR `$ tns create <App Name> --template tsc [--path <Directory>] [--appid <App ID>]`
Create from default Angular template | `$ tns create <App Name> --template angular [--path <Directory>] [--appid <App ID>]` OR `$ tns create <App Name> --template ng [--path <Directory>] [--appid <App ID>]` OR `$ tns create <App Name> --ng [--path <Directory>] [--appid <App ID>]`
Copy from existing project | `$ tns create <App Name> [--path <Directory>] [--appid <App ID>] --copy-from <Directory>`
Create from custom template | `$ tns create <App Name> [--path <Directory>] [--appid <App ID>] --template <Template>`

Expand All @@ -15,6 +16,7 @@ Creates a new project for native development with NativeScript.
* `--appid` - Sets the application identifier for your project.
* `--copy-from` - Specifies a directory which contains an existing NativeScript project. If `--copy-from` and `--template` are not set, the NativeScript CLI creates the project from the default JavaScript hello-world template.
* `--template` - Specifies a valid npm package which you want to use to create your project. If `--copy-from` and `--template` are not set, the NativeScript CLI creates the project from the default JavaScript hello-world template.<% if(isHtml) { %> If one or more application assets are missing from the `App_Resources` directory in the package, the CLI adds them using the assets available in the default hello-world template.<% } %>
* `--ng` - Sets the template for your project to the Angular template.

### Attributes
* `<App Name>` is the name of project. The specified name must meet the requirements of all platforms that you want to target. <% if(isConsole) { %>For more information about the `<App Name>` requirements, run `$ tns help create`<% } %><% if(isHtml) { %>For projects that target Android, you can use uppercase or lowercase letters, numbers, and underscores. The name must start with a letter.
Expand Down
12 changes: 10 additions & 2 deletions lib/commands/create-project.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
///<reference path="../.d.ts"/>
"use strict";

import * as constants from "../constants";

export class ProjectCommandParameter implements ICommandParameter {
constructor(private $errors: IErrors,
private $logger: ILogger,
Expand All @@ -27,13 +29,19 @@ export class CreateProjectCommand implements ICommand {
private $errors: IErrors,
private $logger: ILogger,
private $projectNameValidator: IProjectNameValidator,
private $options: ICommonOptions) { }
private $options: IOptions) { }

public enableHooks = false;

execute(args: string[]): IFuture<void> {
return (() => {
this.$projectService.createProject(args[0], this.$options.template).wait();
if (this.$options.ng && this.$options.template) {
this.$errors.fail("You cannot use --ng and --template simultaneously.");
}

let selectedTemplate = this.$options.ng ? constants.ANGULAR_NAME : this.$options.template;

this.$projectService.createProject(args[0], selectedTemplate).wait();
}).future<void>()();
}

Expand Down
2 changes: 2 additions & 0 deletions lib/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,3 +43,5 @@ class ItunesConnectApplicationTypesClass implements IiTunesConnectApplicationTyp
}

export let ItunesConnectApplicationTypes = new ItunesConnectApplicationTypesClass();

export let ANGULAR_NAME = "angular";
39 changes: 20 additions & 19 deletions lib/declarations.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,32 +58,33 @@ interface ILiveSyncService {
}

interface IOptions extends ICommonOptions {
ipa: string;
frameworkPath: string;
frameworkName: string;
framework: string;
frameworkVersion: string;
baseConfig: string;
client: boolean;
compileSdk: number;
copyFrom: string;
linkTo: string;
copyTo: string;
debugTransport: boolean;
emulator: boolean;
symlink: boolean;
forDevice: boolean;
client: boolean;
production: boolean;
keyStorePath: string;
keyStorePassword: string;
framework: string;
frameworkName: string;
frameworkPath: string;
frameworkVersion: string;
ignoreScripts: boolean;
ipa: string;
keyStoreAlias: string;
keyStoreAliasPassword: string;
keyStorePassword: string;
keyStorePath: string;
linkTo: string;
ng: boolean;
platformTemplate: string;
port: Number;
production: boolean;
sdk: string;
debugTransport: boolean;
ignoreScripts: boolean;
tnsModulesVersion: string;
staticBindings: boolean;
compileSdk: number;
port: Number;
copyTo: string;
baseConfig: string;
platformTemplate: string;
symlink: boolean;
tnsModulesVersion: string;
}

interface IInitService {
Expand Down
3 changes: 2 additions & 1 deletion lib/npm-installation-manager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,8 @@ export class NpmInstallationManager implements INpmInstallationManager {
"tns-ios": constants.PROJECT_FRAMEWORK_FOLDER_NAME,
"tns-ios-inspector": "WebInspectorUI",
"tns-template-hello-world": constants.APP_RESOURCES_FOLDER_NAME,
"tns-template-hello-world-ts": constants.APP_RESOURCES_FOLDER_NAME
"tns-template-hello-world-ts": constants.APP_RESOURCES_FOLDER_NAME,
"tns-template-hello-world-ng": constants.APP_RESOURCES_FOLDER_NAME
};

constructor(private $npm: INodePackageManager,
Expand Down
3 changes: 2 additions & 1 deletion lib/options.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,8 @@ export class Options extends commonOptionsLibPath.OptionsBase {
port: { type: OptionType.Number },
copyTo: { type: OptionType.String },
baseConfig: { type: OptionType.String },
platformTemplate: { type: OptionType.String }
platformTemplate: { type: OptionType.String },
ng: {type: OptionType.Boolean }
},
path.join($hostInfo.isWindows ? process.env.AppData : path.join(osenv.home(), ".local/share"), ".nativescript-cli"),
$errors, $staticConfig);
Expand Down
2 changes: 2 additions & 0 deletions lib/services/project-service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,8 @@ export class ProjectService implements IProjectService {
this.$fs.symlink(appSourcePath, appDestinationPath).wait();
} else {
shelljs.cp('-R', path.join(appSourcePath, "*"), appDestinationPath);
// Copy hidden files.
shelljs.cp('-R', path.join(appSourcePath, ".*"), appDestinationPath);
}

this.createBasicProjectStructure(projectDir, projectId).wait();
Expand Down
4 changes: 3 additions & 1 deletion lib/services/project-templates-service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,9 @@ export class ProjectTemplatesService implements IProjectTemplatesService {
private static RESERVED_TEMPLATE_NAMES: IStringDictionary = {
"default": "tns-template-hello-world",
"tsc": "tns-template-hello-world-ts",
"typescript": "tns-template-hello-world-ts"
"typescript": "tns-template-hello-world-ts",
"ng": "tns-template-hello-world-ng",
"angular": "tns-template-hello-world-ng"
};

public constructor(private $errors: IErrors,
Expand Down
102 changes: 102 additions & 0 deletions test/project-commands.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
/// <reference path=".d.ts" />
"use strict";

import { Yok } from "../lib/common/yok";
import * as stubs from "./stubs";
import { CreateProjectCommand } from "../lib/commands/create-project";
import * as constants from "../lib/constants";
import {assert} from "chai";

let selectedTemplateName: string;
let isProjectCreated: boolean;
let dummyArgs = ["dummyArgsString"];

class ProjectServiceMock implements IProjectService {
createProject(projectName: string, selectedTemplate?: string): IFuture<void> {
return (() => {
selectedTemplateName = selectedTemplate;
isProjectCreated = true;
}).future<void>()();
}
}

class ProjectNameValidatorMock implements IProjectNameValidator {
public validate(name: string): boolean {
return true;
}
}

function createTestInjector() {
let testInjector = new Yok();

testInjector.register("injector", testInjector);
testInjector.register("staticConfig", {});
testInjector.register("projectService", ProjectServiceMock);
testInjector.register("errors", stubs.ErrorsStub);
testInjector.register("logger", stubs.LoggerStub);
testInjector.register("projectNameValidator", ProjectNameValidatorMock);
testInjector.register("options", {
ng: false,
template: undefined
});
testInjector.register("createCommand", CreateProjectCommand);

return testInjector;
}

describe("Project commands tests", () => {
let testInjector: IInjector;
let options: IOptions;
let createProjectCommand: ICommand;

beforeEach(() => {
testInjector = createTestInjector();
isProjectCreated = false;
selectedTemplateName = undefined;
options = testInjector.resolve("$options");
createProjectCommand = testInjector.resolve("$createCommand");
});

describe("#CreateProjectCommand", () => {
it("should not fail when using only --ng.", () => {
options.ng = true;

createProjectCommand.execute(dummyArgs).wait();

assert.isTrue(isProjectCreated);
});

it("should not fail when using only --template.", () => {
options.template = "ng";

createProjectCommand.execute(dummyArgs).wait();

assert.isTrue(isProjectCreated);
});

it("should set the template name correctly when used --ng.", () => {
options.ng = true;

createProjectCommand.execute(dummyArgs).wait();

assert.deepEqual(selectedTemplateName, constants.ANGULAR_NAME);
});

it("should not set the template name when --ng is not used.", () => {
options.ng = false;

createProjectCommand.execute(dummyArgs).wait();

assert.isUndefined(selectedTemplateName);
});

it("should fail when --ng and --template are used simultaneously.", () => {
options.ng = true;
options.template = "ng";

assert.throws(() => {
createProjectCommand.execute(dummyArgs).wait();
});
});
});
});
26 changes: 26 additions & 0 deletions test/project-service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -210,6 +210,32 @@ describe("Project Service Tests", () => {
projectIntegrationTest.assertProject(tempFolder, projectName, "org.nativescript.myapp", projectTemplatesService.prepareTemplate("tsc").wait()).wait();
});

it("creates valid project from angular template", () => {
let projectIntegrationTest = new ProjectIntegrationTest();
let tempFolder = temp.mkdirSync("projectAngular");
let projectName = "myapp";
let options = projectIntegrationTest.testInjector.resolve("options");

options.path = tempFolder;
projectIntegrationTest.createProject(projectName, "angular").wait();

let projectTemplatesService: IProjectTemplatesService = projectIntegrationTest.testInjector.resolve("projectTemplatesService");
projectIntegrationTest.assertProject(tempFolder, projectName, "org.nativescript.myapp", projectTemplatesService.prepareTemplate("angular").wait()).wait();
});

it("creates valid project from ng template", () => {
let projectIntegrationTest = new ProjectIntegrationTest();
let tempFolder = temp.mkdirSync("projectNg");
let projectName = "myapp";
let options = projectIntegrationTest.testInjector.resolve("options");

options.path = tempFolder;
projectIntegrationTest.createProject(projectName, "ng").wait();

let projectTemplatesService: IProjectTemplatesService = projectIntegrationTest.testInjector.resolve("projectTemplatesService");
projectIntegrationTest.assertProject(tempFolder, projectName, "org.nativescript.myapp", projectTemplatesService.prepareTemplate("ng").wait()).wait();
});

it("creates valid project from local directory template", () => {
let projectIntegrationTest = new ProjectIntegrationTest();
let tempFolder = temp.mkdirSync("projectLocalDir");
Expand Down

0 comments on commit 111a986

Please sign in to comment.