Skip to content

Commit

Permalink
feat(react): official quick create for --react app (#5336)
Browse files Browse the repository at this point in the history
  • Loading branch information
NathanWalker authored Jun 27, 2020
1 parent 6583943 commit 5d3f3a4
Show file tree
Hide file tree
Showing 9 changed files with 64 additions and 10 deletions.
1 change: 1 addition & 0 deletions docs/man_pages/project/creation/create.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ Template | Command
`Angular - Hello World`, `--ng`, `--angular` | tns create --template tns-template-hello-world-ng
`Angular - SideDrawer` | tns create --template tns-template-drawer-navigation-ng
`Angular - Tabs` | tns create --template tns-template-tab-navigation-ng
`React - Hello World`, `--react`, `--reactjs` | tns create --template tns-template-blank-react
`Vue.js - Blank`, `--vue`, `--vuejs` | tns create --template tns-template-blank-vue
`Vue.js - SideDrawer`, | tns create --template tns-template-drawer-navigation-vue
`Vue.js - Tabs` | tns create --template tns-template-tab-navigation-vue
Expand Down
20 changes: 18 additions & 2 deletions lib/commands/create-project.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,8 @@ export class CreateProjectCommand implements ICommand {
selectedTemplate = constants.ANGULAR_NAME;
} else if (this.$options.vue) {
selectedTemplate = constants.VUE_NAME;
} else if (this.$options.react) {
selectedTemplate = constants.REACT_NAME;
} else {
selectedTemplate = this.$options.template;
}
Expand Down Expand Up @@ -82,6 +84,7 @@ export class CreateProjectCommand implements ICommand {
private async interactiveFlavorSelection(adverb: string) {
const flavorSelection = await this.$prompter.promptForDetailedChoice(`${adverb}, which style of NativeScript project would you like to use:`, [
{ key: constants.NgFlavorName, description: "Learn more at https://nativescript.org/angular" },
{ key: constants.ReactFlavorName, description: "Learn more at https://github.com/shirakaba/react-nativescript" },
{ key: constants.VueFlavorName, description: "Learn more at https://nativescript.org/vue" },
{ key: constants.TsFlavorName, description: "Learn more at https://nativescript.org/typescript" },
{ key: constants.JsFlavorName, description: "Use NativeScript without any framework" },
Expand All @@ -96,8 +99,7 @@ export class CreateProjectCommand implements ICommand {
this.$logger.printMarkdown(`# Let’s create a NativeScript app!`);
this.$logger.printMarkdown(`
Answer the following questions to help us build the right app for you. (Note: you
can skip this prompt next time using the --template option, or the --ng, --vue, --ts,
or --js flags.)
can skip this prompt next time using the --template option, or the --ng, --react, --vue, --ts, or --js flags.)
`);
}
}
Expand All @@ -114,6 +116,10 @@ or --js flags.)
selectedFlavorTemplates.push(...this.getNgTemplates());
break;
}
case constants.ReactFlavorName: {
selectedFlavorTemplates.push(...this.getReactTemplates());
break;
}
case constants.VueFlavorName: {
selectedFlavorTemplates.push(...this.getVueTemplates());
break;
Expand Down Expand Up @@ -200,6 +206,16 @@ or --js flags.)
return templates;
}

private getReactTemplates() {
const templates = [{
key: CreateProjectCommand.HelloWorldTemplateKey,
value: constants.RESERVED_TEMPLATE_NAMES.react,
description: CreateProjectCommand.HelloWorldTemplateDescription
}];

return templates;
}

private getVueTemplates() {
const templates = [{
key: CreateProjectCommand.BlankTemplateKey,
Expand Down
8 changes: 4 additions & 4 deletions lib/common/commands/preuninstall.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { doesCurrentNpmCommandMatch, isInteractive } from "../helpers";
import { TrackActionNames, AnalyticsEventLabelDelimiter } from "../../constants";

export class PreUninstallCommand implements ICommand {
// disabled for now (6/24/2020)
// disabled for now (6/24/2020)
// private static FEEDBACK_FORM_URL = "https://www.nativescript.org/uninstall-feedback";

public allowedParameters: ICommandParameter[] = [];
Expand Down Expand Up @@ -38,11 +38,11 @@ export class PreUninstallCommand implements ICommand {
}

private async handleFeedbackForm(): Promise<void> {
// disabled for now (6/24/2020)
// disabled for now (6/24/2020)
// if (isInteractive()) {
// this.$opener.open(PreUninstallCommand.FEEDBACK_FORM_URL);
// }
return Promise.resolve();
// }
return Promise.resolve();
}
}

Expand Down
2 changes: 1 addition & 1 deletion lib/common/test/unit-tests/preuninstall.ts
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ describe("preuninstall", () => {
assert.isTrue(isClearInspectorCacheCalled, "When uninstall is called, `clearInspectorCache` method must be called");
});

// disabled (6/24/2020)
// disabled (6/24/2020)
// it("opens the uninstall feedback form when terminal is interactive and uninstall is called", async () => {
// helpers.doesCurrentNpmCommandMatch = () => true;
// helpers.isInteractive = () => true;
Expand Down
6 changes: 5 additions & 1 deletion lib/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,9 @@ export const RESERVED_TEMPLATE_NAMES: IStringDictionary = {
"vue": "tns-template-blank-vue",
"typescript": "tns-template-hello-world-ts",
"ng": "tns-template-hello-world-ng",
"angular": "tns-template-hello-world-ng"
"angular": "tns-template-hello-world-ng",
"react": "tns-template-blank-react",
"reactjs": "tns-template-blank-react"
};

export const ANALYTICS_LOCAL_TEMPLATE_PREFIX = "localTemplate_";
Expand Down Expand Up @@ -138,8 +140,10 @@ export const VUE_NAME = "vue";
export const ANGULAR_NAME = "angular";
export const JAVASCRIPT_NAME = "javascript";
export const TYPESCRIPT_NAME = "typescript";
export const REACT_NAME = "react";
export const NgFlavorName = "Angular";
export const VueFlavorName = "Vue.js";
export const ReactFlavorName = "React";
export const TsFlavorName = "Plain TypeScript";
export const JsFlavorName = "Plain JavaScript";
export class ProjectTypes {
Expand Down
1 change: 1 addition & 0 deletions lib/declarations.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -567,6 +567,7 @@ interface IOptions extends IRelease, IDeviceIdentifier, IJustLaunch, IAvd, IAvai
typescript: boolean;
ng: boolean;
angular: boolean;
react: boolean;
vue: boolean;
vuejs: boolean;
js: boolean;
Expand Down
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@
},
"main": "./lib/nativescript-cli-lib.js",
"scripts": {
"grunt": "grunt",
"build": "grunt",
"build.all": "grunt test",
"setup": "npm i --ignore-scripts && ./node_modules/.bin/grunt",
"test": "istanbul cover ./node_modules/mocha/bin/_mocha",
"postinstall": "node postinstall.js",
Expand Down
31 changes: 31 additions & 0 deletions test/project-commands.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ let validateProjectCallsCount: number;
const dummyArgs = ["dummyArgsString"];
const expectedFlavorChoices = [
{ key: "Angular", description: "Learn more at https://nativescript.org/angular" },
{ key: "React", description: "Learn more at https://github.com/shirakaba/react-nativescript" },
{ key: "Vue.js", description: "Learn more at https://nativescript.org/vue" },
{ key: "Plain TypeScript", description: "Learn more at https://nativescript.org/typescript" },
{ key: "Plain JavaScript", description: "Use NativeScript without any framework" }
Expand Down Expand Up @@ -126,6 +127,16 @@ describe("Project commands tests", () => {
assert.isTrue(createProjectCalledWithForce);
});

it("should not fail when using only --react.", async () => {
options.react = true;

await createProjectCommand.execute(dummyArgs);

assert.isTrue(isProjectCreated);
assert.equal(validateProjectCallsCount, 1);
assert.isTrue(createProjectCalledWithForce);
});

it("should not fail when using only --tsc.", async () => {
options.tsc = true;

Expand Down Expand Up @@ -156,6 +167,16 @@ describe("Project commands tests", () => {
assert.isTrue(createProjectCalledWithForce);
});

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

await createProjectCommand.execute(dummyArgs);

assert.deepEqual(selectedTemplateName, constants.REACT_NAME);
assert.equal(validateProjectCallsCount, 1);
assert.isTrue(createProjectCalledWithForce);
});

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

Expand Down Expand Up @@ -219,5 +240,15 @@ describe("Project commands tests", () => {
assert.equal(validateProjectCallsCount, 1);
assert.isTrue(createProjectCalledWithForce);
});

it("should ask for a template when react flavor is selected.", async () => {
setupAnswers({ flavorAnswer: constants.ReactFlavorName, templateAnswer: "Hello World" });

await createProjectCommand.execute(dummyArgs);

assert.deepEqual(selectedTemplateName, "tns-template-blank-react");
assert.equal(validateProjectCallsCount, 1);
assert.isTrue(createProjectCalledWithForce);
});
});
});
2 changes: 1 addition & 1 deletion test/project-data.ts
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ describe("projectData", () => {
assertProjectType({ "react-nativescript": "*" }, null, "React");
});

it("detects project as Svelte when react-nativescript exists as dependency and typescript is devDependency", () => {
it("detects project as Svelte when svelte-native exists as dependency and typescript is devDependency", () => {
assertProjectType({ "svelte-native": "*" }, null, "Svelte");
});

Expand Down

0 comments on commit 5d3f3a4

Please sign in to comment.