From cfa2f60cfb74441fa86d364abdeb4b56009a4ca8 Mon Sep 17 00:00:00 2001 From: Jamon Holmgren Date: Tue, 18 Dec 2018 15:47:47 -0800 Subject: [PATCH 1/2] Improves generated CLI, adds example tests --- src/cli/commands/new.ts | 11 +++++-- src/cli/templates/cli/.prettierrc.ejs | 10 ------ .../cli/__tests__/cli-integration.test.js.ejs | 33 +++++++++++++++++++ src/cli/templates/cli/package.json.ejs | 29 ++++++++++++---- .../cli/src/commands/generate.js.ejs | 14 +++++--- src/cli/templates/cli/tslint.json.ejs | 9 +++++ 6 files changed, 83 insertions(+), 23 deletions(-) delete mode 100644 src/cli/templates/cli/.prettierrc.ejs create mode 100644 src/cli/templates/cli/__tests__/cli-integration.test.js.ejs create mode 100644 src/cli/templates/cli/tslint.json.ejs diff --git a/src/cli/commands/new.ts b/src/cli/commands/new.ts index 6b003439..ee7c78ad 100644 --- a/src/cli/commands/new.ts +++ b/src/cli/commands/new.ts @@ -45,6 +45,7 @@ export default { ) const files = [ + '__tests__/cli-integration.test.js.ejs', 'docs/commands.md.ejs', 'docs/plugins.md.ejs', 'src/commands/generate.js.ejs', @@ -53,7 +54,6 @@ export default { 'src/templates/model.js.ejs.ejs', 'src/cli.js.ejs', 'LICENSE.ejs', - '.prettierrc.ejs', 'package.json.ejs', 'readme.md.ejs', '.gitignore.ejs', @@ -61,6 +61,7 @@ export default { if (props.typescript) { files.push('tsconfig.json.ejs') + files.push('tslint.json.ejs') } active = files.reduce((prev, file) => { @@ -84,7 +85,10 @@ export default { const ext = props.typescript ? 'ts' : 'js' filesystem.rename(`${props.name}/src/commands/default.${ext}`, `${props.name}.${ext}`) - await system.spawn(`cd ${props.name} && npm install --quiet && npm run --quiet format`, { + // install with yarn or npm i + const yarnOrNpm = system.which('yarn') ? 'yarn' : 'npm' + + await system.spawn(`cd ${props.name} && ${yarnOrNpm} install --silent && ${yarnOrNpm} run --quiet format`, { shell: true, stdio: 'inherit', stderr: 'inherit', @@ -94,7 +98,8 @@ export default { print.info(``) print.info(`Next:`) print.info(` $ cd ${props.name}`) - print.info(` $ npm link`) + print.info(` $ ${yarnOrNpm} test`) + print.info(` $ ${yarnOrNpm} link`) print.info(` $ ${props.name}`) print.info(``) diff --git a/src/cli/templates/cli/.prettierrc.ejs b/src/cli/templates/cli/.prettierrc.ejs deleted file mode 100644 index 6bf8f5dc..00000000 --- a/src/cli/templates/cli/.prettierrc.ejs +++ /dev/null @@ -1,10 +0,0 @@ -{ - "semi": false, - "trailingComma": "all", - "printWidth": 100, - "tabWidth": 2, - "singleQuote": true, - "bracketSpacing": true, - "jsxBracketSameLine": false, - "useTabs": false -} diff --git a/src/cli/templates/cli/__tests__/cli-integration.test.js.ejs b/src/cli/templates/cli/__tests__/cli-integration.test.js.ejs new file mode 100644 index 00000000..5bb55ef2 --- /dev/null +++ b/src/cli/templates/cli/__tests__/cli-integration.test.js.ejs @@ -0,0 +1,33 @@ +const { system, filesystem } = require('gluegun') +const { resolve } = require('path') + +const src = resolve(__dirname, '..') + +const cli = async cmd => system.run(resolve(src, 'bin', '<%= props.name %>') + ` ${cmd}`) + +test('outputs version', async () => { + const output = await cli('--version') + expect(output).toContain('0.0.1') +}) + +test('outputs help', async () => { + const output = await cli('--help') + expect(output).toContain('0.0.1') +}) + +test('generates file', async () => { + const output = await cli('generate foo') + <% if (props.typescript) { %> + expect(output).toContain('Generated file at models/foo-model.ts') + const foomodel = filesystem.read('models/foo-model.ts') + <% } else { %> + expect(output).toContain('Generated file at models/foo-model.js') + const foomodel = filesystem.read('models/foo-model.js') + <% } %> + + expect(foomodel).toContain(`module.exports = {`) + expect(foomodel).toContain(`name: 'foo'`) + + // cleanup artifact + filesystem.remove('models') +}) diff --git a/src/cli/templates/cli/package.json.ejs b/src/cli/templates/cli/package.json.ejs index 2802b9ae..a8721c87 100644 --- a/src/cli/templates/cli/package.json.ejs +++ b/src/cli/templates/cli/package.json.ejs @@ -9,6 +9,7 @@ "scripts": { <% if (props.typescript) { %> "format": "prettier --write **/*.{js,ts,tsx,json}", + "lint": "tslint -p .", <% } else { %> "format": "prettier --write **/*.{js,json} && standard --fix", "lint": "standard", @@ -21,6 +22,7 @@ "files": [ <% if (props.typescript) { %> "tsconfig.json", + "tslint.json", <% } %> "LICENSE", "readme.md", @@ -39,17 +41,32 @@ "devDependencies": { <% if (props.typescript) { %> "@types/node": "^10.12.12", + "@types/jest": "^23.3.10", "ts-jest": "^23.10.5", + "tslint": "^5.12.0", + "tslint-config-prettier": "^1.17.0", + "tslint-config-standard": "^8.0.1", <% } else { %> "standard": "^12.0.1", - "babel-eslint": "^10.0.1", <% } %> "prettier": "^1.12.1", "jest": "^23.6.0" - } - <% if (!props.typescript) { %>, - "standard": { - "parser": "babel-eslint" - } + }, + "jest": { + <% if (props.typescript) { %> + "preset": "ts-jest", + <% } %> + "testEnvironment": "node" + }, + <% if (!props.typescript) { %> + "standard": { + "env": [ + "jest" + ] + }, <% } %> + "prettier": { + "semi": false, + "singleQuote": true + } } diff --git a/src/cli/templates/cli/src/commands/generate.js.ejs b/src/cli/templates/cli/src/commands/generate.js.ejs index 80b666b6..f7a90b0f 100644 --- a/src/cli/templates/cli/src/commands/generate.js.ejs +++ b/src/cli/templates/cli/src/commands/generate.js.ejs @@ -1,15 +1,21 @@ module.exports = { name: 'generate', alias: ['g'], - run: async (context) => { - const { parameters, template: { generate } } = context + run: async context => { + const { + parameters, + template: { generate }, + print: { info }, + } = context const name = parameters.first await generate({ template: 'model.<%= props.extension %>.ejs', target: `models/${name}-model.<%= props.extension %>`, - props: { name } + props: { name }, }) - } + + info(`Generated file at models/${name}-model.<%= props.extension %>`) + }, } diff --git a/src/cli/templates/cli/tslint.json.ejs b/src/cli/templates/cli/tslint.json.ejs new file mode 100644 index 00000000..8e988a8e --- /dev/null +++ b/src/cli/templates/cli/tslint.json.ejs @@ -0,0 +1,9 @@ +{ + "extends": ["tslint-config-standard", "tslint-config-prettier"], + "rules": { + "strict-type-predicates": false + }, + "env": { + "jest": true + } +} From 89b8f44081461fa6f6114d0dccc062cfc60293ba Mon Sep 17 00:00:00 2001 From: Jamon Holmgren Date: Tue, 18 Dec 2018 15:54:02 -0800 Subject: [PATCH 2/2] Fix tests --- src/cli/commands/new.test.ts | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/cli/commands/new.test.ts b/src/cli/commands/new.test.ts index 2a10f068..64bb97fe 100644 --- a/src/cli/commands/new.test.ts +++ b/src/cli/commands/new.test.ts @@ -17,6 +17,7 @@ function createFakeToolbox(): Toolbox { } fakeContext.system = { spawn: sinon.stub(), + which: sinon.stub(), } fakeContext.template = { generate: sinon.stub() } fakeContext.print = { @@ -93,6 +94,7 @@ test('generates properly', async () => { }) const DEFAULT_FILES = [ + ['__tests__/cli-integration.test.js.ejs', '__tests__/cli-integration.test.js'], ['docs/commands.md.ejs', 'docs/commands.md'], ['docs/plugins.md.ejs', 'docs/plugins.md'], ['src/commands/generate.js.ejs', 'src/commands/generate.js'], @@ -101,7 +103,6 @@ test('generates properly', async () => { ['src/templates/model.js.ejs.ejs', 'src/templates/model.js.ejs'], ['src/cli.js.ejs', 'src/cli.js'], ['LICENSE.ejs', 'LICENSE'], - ['.prettierrc.ejs', '.prettierrc'], ['package.json.ejs', 'package.json'], ['readme.md.ejs', 'readme.md'], ['.gitignore.ejs', '.gitignore'], @@ -121,7 +122,7 @@ test('generates properly', async () => { // test package installation expect(spawn.firstCall.args).toEqual([ - `cd ${props.name} && npm install --quiet && npm run --quiet format`, + `cd ${props.name} && npm install --silent && npm run --quiet format`, { shell: true, stdio: 'inherit', stderr: 'inherit' }, ]) @@ -159,6 +160,7 @@ test('generates with typescript', async () => { }) const DEFAULT_FILES = [ + ['__tests__/cli-integration.test.js.ejs', '__tests__/cli-integration.test.ts'], ['docs/commands.md.ejs', 'docs/commands.md'], ['docs/plugins.md.ejs', 'docs/plugins.md'], ['src/commands/generate.js.ejs', 'src/commands/generate.ts'], @@ -167,7 +169,6 @@ test('generates with typescript', async () => { ['src/templates/model.js.ejs.ejs', 'src/templates/model.ts.ejs'], ['src/cli.js.ejs', 'src/cli.ts'], ['LICENSE.ejs', 'LICENSE'], - ['.prettierrc.ejs', '.prettierrc'], ['package.json.ejs', 'package.json'], ['readme.md.ejs', 'readme.md'], ['.gitignore.ejs', '.gitignore'], @@ -187,7 +188,7 @@ test('generates with typescript', async () => { // test package installation expect(spawn.firstCall.args).toEqual([ - `cd ${props.name} && npm install --quiet && npm run --quiet format`, + `cd ${props.name} && npm install --silent && npm run --quiet format`, { shell: true, stdio: 'inherit', stderr: 'inherit' }, ])