diff --git a/.releaserc.js b/.releaserc.js index 7cdd4a0..bd24422 100644 --- a/.releaserc.js +++ b/.releaserc.js @@ -1,7 +1,9 @@ const { readFileSync } = require('fs'); const path = require('path'); -const releaseTemplate = readFileSync(path.join('.', '.github', 'release-template.hbs')); +const releaseTemplate = readFileSync( + path.join('.', '.github', 'release-template.hbs'), +); module.exports = { plugins: [ @@ -60,7 +62,8 @@ module.exports = { '@semantic-release/git', { assets: ['CHANGELOG.md', 'package.json', 'README.md'], - message: ':bookmark: ${nextRelease.version} [skip ci]\n\n${nextRelease.notes}', + message: + ':bookmark: ${nextRelease.version} [skip ci]\n\n${nextRelease.notes}', }, ], ], diff --git a/package.json b/package.json index 22abdc2..99250a6 100644 --- a/package.json +++ b/package.json @@ -102,4 +102,4 @@ "pre-commit": "pretty-quick --staged" } } -} \ No newline at end of file +} diff --git a/src/tests/add/__snapshots__/prettier.spec.ts.snap b/src/tests/add/__snapshots__/prettier.spec.ts.snap index a7c0d1f..4941338 100644 --- a/src/tests/add/__snapshots__/prettier.spec.ts.snap +++ b/src/tests/add/__snapshots__/prettier.spec.ts.snap @@ -1,6 +1,10 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`prettier should print help correctly 1`] = ` +exports[`nbx add:tailwind should fail if no package.json found 1`] = `Array []`; + +exports[`nbx add:tailwind should fail if prettier is found in package.json 1`] = `Array []`; + +exports[`nbx add:tailwind should print help correctly 1`] = ` Array [ "add prettier to project and format it ", @@ -15,7 +19,170 @@ OPTIONS ] `; -exports[`prettier should work with commits 1`] = ` +exports[`nbx add:tailwind should work with commits 1`] = ` +" + + testokiii + + +" +`; + +exports[`nbx add:tailwind should work with commits 2`] = ` +Array [ + "Adding prettier as a dev dependency", + "The step was done without any error.", + "Adding husky as a dev dependency", + "The step was done without any error.", + "Adding pretty-quick as a dev dependency", + "The step was done without any error.", + "Adding package.json scripts", + "The step was done without any error.", + "Adding .prettierrc config file", + "The step was done without any error.", + "Updating code to match prettier style", + "The step was done without any error.", +] +`; + +exports[`nbx add:tailwind should work with eslint and commits and with an empty .eslintrc 1`] = ` +" + + testokiii + + +" +`; + +exports[`nbx add:tailwind should work with eslint and commits and with an empty .eslintrc 2`] = ` +Array [ + "Adding prettier as a dev dependency", + "The step was done without any error.", + "Adding husky as a dev dependency", + "The step was done without any error.", + "Adding pretty-quick as a dev dependency", + "The step was done without any error.", + "Adding package.json scripts", + "The step was done without any error.", + "Adding .prettierrc config file", + "The step was done without any error.", + "Updating code to match prettier style", + "The step was done without any error.", + "Adding eslint-config-prettier as a dev dependency", + "The step was done without any error.", + "Adding eslint-plugin-prettier as a dev dependency", + "The step was done without any error.", + "Updating .eslintrc", + "The step was done without any error.", +] +`; + +exports[`nbx add:tailwind should work with eslint and commits and with extends as array .eslintrc 1`] = ` +" + + testokiii + + +" +`; + +exports[`nbx add:tailwind should work with eslint and commits and with extends as array .eslintrc 2`] = ` +Array [ + "Adding prettier as a dev dependency", + "The step was done without any error.", + "Adding husky as a dev dependency", + "The step was done without any error.", + "Adding pretty-quick as a dev dependency", + "The step was done without any error.", + "Adding package.json scripts", + "The step was done without any error.", + "Adding .prettierrc config file", + "The step was done without any error.", + "Updating code to match prettier style", + "The step was done without any error.", + "Adding eslint-config-prettier as a dev dependency", + "The step was done without any error.", + "Adding eslint-plugin-prettier as a dev dependency", + "The step was done without any error.", + "Updating .eslintrc", + "The step was done without any error.", +] +`; + +exports[`nbx add:tailwind should work with eslint and commits and with extends as array .eslintrc.json 1`] = ` +" + + testokiii + + +" +`; + +exports[`nbx add:tailwind should work with eslint and commits and with extends as array .eslintrc.json 2`] = ` +Array [ + "Adding prettier as a dev dependency", + "The step was done without any error.", + "Adding husky as a dev dependency", + "The step was done without any error.", + "Adding pretty-quick as a dev dependency", + "The step was done without any error.", + "Adding package.json scripts", + "The step was done without any error.", + "Adding .prettierrc config file", + "The step was done without any error.", + "Updating code to match prettier style", + "The step was done without any error.", + "Adding eslint-config-prettier as a dev dependency", + "The step was done without any error.", + "Adding eslint-plugin-prettier as a dev dependency", + "The step was done without any error.", + "Updating .eslintrc.json", + "The step was done without any error.", +] +`; + +exports[`nbx add:tailwind should work with eslint and commits and with extends as string .eslintrc 1`] = ` +" + + testokiii + + +" +`; + +exports[`nbx add:tailwind should work with eslint and commits and with extends as string .eslintrc 2`] = ` +Array [ + "Adding prettier as a dev dependency", + "The step was done without any error.", + "Adding husky as a dev dependency", + "The step was done without any error.", + "Adding pretty-quick as a dev dependency", + "The step was done without any error.", + "Adding package.json scripts", + "The step was done without any error.", + "Adding .prettierrc config file", + "The step was done without any error.", + "Updating code to match prettier style", + "The step was done without any error.", + "Adding eslint-config-prettier as a dev dependency", + "The step was done without any error.", + "Adding eslint-plugin-prettier as a dev dependency", + "The step was done without any error.", + "Updating .eslintrc", + "The step was done without any error.", +] +`; + +exports[`nbx add:tailwind should work with tslint and commits and with an empty config 1`] = ` +" + + testokiii + + +" +`; + +exports[`nbx add:tailwind should work with tslint and commits and with an empty config 2`] = ` Array [ "Adding prettier as a dev dependency", "The step was done without any error.", @@ -29,10 +196,16 @@ Array [ "The step was done without any error.", "Updating code to match prettier style", "The step was done without any error.", + "Adding tslint-config-prettier as a dev dependency", + "The step was done without any error.", + "Adding tslint-plugin-prettier as a dev dependency", + "The step was done without any error.", + "Updating tslint.json", + "The step was done without any error.", ] `; -exports[`prettier should work with commits 2`] = ` +exports[`nbx add:tailwind should work with tslint and commits and with an existing extends as array 1`] = ` " testokiii @@ -41,7 +214,7 @@ exports[`prettier should work with commits 2`] = ` " `; -exports[`prettier should work without commits 1`] = ` +exports[`nbx add:tailwind should work with tslint and commits and with an existing extends as array 2`] = ` Array [ "Adding prettier as a dev dependency", "The step was done without any error.", @@ -55,10 +228,16 @@ Array [ "The step was done without any error.", "Updating code to match prettier style", "The step was done without any error.", + "Adding tslint-config-prettier as a dev dependency", + "The step was done without any error.", + "Adding tslint-plugin-prettier as a dev dependency", + "The step was done without any error.", + "Updating tslint.json", + "The step was done without any error.", ] `; -exports[`prettier should work without commits 2`] = ` +exports[`nbx add:tailwind should work with tslint and commits and with an existing extends as string 1`] = ` " testokiii @@ -66,3 +245,84 @@ exports[`prettier should work without commits 2`] = ` " `; + +exports[`nbx add:tailwind should work with tslint and commits and with an existing extends as string 2`] = ` +Array [ + "Adding prettier as a dev dependency", + "The step was done without any error.", + "Adding husky as a dev dependency", + "The step was done without any error.", + "Adding pretty-quick as a dev dependency", + "The step was done without any error.", + "Adding package.json scripts", + "The step was done without any error.", + "Adding .prettierrc config file", + "The step was done without any error.", + "Updating code to match prettier style", + "The step was done without any error.", + "Adding tslint-config-prettier as a dev dependency", + "The step was done without any error.", + "Adding tslint-plugin-prettier as a dev dependency", + "The step was done without any error.", + "Updating tslint.json", + "The step was done without any error.", +] +`; + +exports[`nbx add:tailwind should work with tslint and commits and with an existing rules config 1`] = ` +" + + testokiii + + +" +`; + +exports[`nbx add:tailwind should work with tslint and commits and with an existing rules config 2`] = ` +Array [ + "Adding prettier as a dev dependency", + "The step was done without any error.", + "Adding husky as a dev dependency", + "The step was done without any error.", + "Adding pretty-quick as a dev dependency", + "The step was done without any error.", + "Adding package.json scripts", + "The step was done without any error.", + "Adding .prettierrc config file", + "The step was done without any error.", + "Updating code to match prettier style", + "The step was done without any error.", + "Adding tslint-config-prettier as a dev dependency", + "The step was done without any error.", + "Adding tslint-plugin-prettier as a dev dependency", + "The step was done without any error.", + "Updating tslint.json", + "The step was done without any error.", +] +`; + +exports[`nbx add:tailwind should work without commits 1`] = ` +" + + testokiii + + +" +`; + +exports[`nbx add:tailwind should work without commits 2`] = ` +Array [ + "Adding prettier as a dev dependency", + "The step was done without any error.", + "Adding husky as a dev dependency", + "The step was done without any error.", + "Adding pretty-quick as a dev dependency", + "The step was done without any error.", + "Adding package.json scripts", + "The step was done without any error.", + "Adding .prettierrc config file", + "The step was done without any error.", + "Updating code to match prettier style", + "The step was done without any error.", +] +`; diff --git a/src/tests/add/__snapshots__/tailwind.spec.ts.snap b/src/tests/add/__snapshots__/tailwind.spec.ts.snap index 590e6bc..8e183a8 100644 --- a/src/tests/add/__snapshots__/tailwind.spec.ts.snap +++ b/src/tests/add/__snapshots__/tailwind.spec.ts.snap @@ -2,6 +2,8 @@ exports[`nbx add:tailwind should error if no react is found 1`] = `Array []`; +exports[`nbx add:tailwind should error if tailwind is found 1`] = `Array []`; + exports[`nbx add:tailwind should fail if no package.json found 1`] = `Array []`; exports[`nbx add:tailwind should print help correctly 1`] = ` diff --git a/src/tests/add/dep.spec.ts b/src/tests/add/dep.spec.ts index 6959dda..7f84eec 100644 --- a/src/tests/add/dep.spec.ts +++ b/src/tests/add/dep.spec.ts @@ -14,7 +14,8 @@ testCli({ name: 'fail if no package.json found', runner: expectFailCli({ args: ['chalk'], - errorMessage: 'There is no package.json not found in the current folder', + errorMessage: + 'There is no package.json not found in the current folder', before: async () => { filesystem.remove('package.json'); }, diff --git a/src/tests/add/prettier.spec.ts b/src/tests/add/prettier.spec.ts index 6d1ac73..689dd29 100644 --- a/src/tests/add/prettier.spec.ts +++ b/src/tests/add/prettier.spec.ts @@ -1,157 +1,391 @@ -import { filesystem, system } from 'gluegun'; -const stripANSI = require('strip-ansi'); +import { filesystem } from 'gluegun'; import * as prompts from 'prompts'; import * as latestVersion from 'latest-version'; import Prettier from '../../commands/add/prettier'; +import { + expectFailCli, + expectFailGitCommits, + expectGitCommits, + testCli, + TestRun, +} from '../test-helpers.spec'; jest.setTimeout(90000); -/* eslint-disable no-console,max-nested-callbacks,@typescript-eslint/ban-ts-ignore */ -let consoleLogOutput: string[]; -let execPath: string; -const originalCwd = process.cwd(); -const originalLog = console.log; - -beforeEach(async () => { - consoleLogOutput = []; - console.log = (x: any) => consoleLogOutput.push(stripANSI(x)); - - const tmpDirName = `${new Date().getTime()}-${Math.random() * 100}-add-nbx-test`; - execPath = filesystem.path('/', 'tmp', tmpDirName); - filesystem.dir(execPath); - process.chdir(execPath); -}); -afterEach(() => { - console.log = originalLog; - process.chdir(originalCwd); - jest.restoreAllMocks(); - filesystem.remove(execPath); -}); - -const initWithConfigAndCommit = async () => { - await system.run('git init'); - filesystem.write('.nbxrc', { git: { user: 'aaa', email: 'bbb' } }); - filesystem.write('package.json', {}); +const beforeCreateHtml = async () => { filesystem.write('test.html', 'testokiii'); - await system.run('touch yarn.lock'); - await system.run('echo node_modules > .gitignore'); - await system.run('git add * .nbxrc .gitignore'); - try { - await system.run('git config user.email "you@example.com"'); - await system.run('git config user.name "Your Name"'); - } catch {} - await system.run('git commit -m "init state"'); }; -describe('prettier', () => { - it('should print help correctly', async () => { - try { - await Prettier.run(['-h']); - } catch {} - expect(consoleLogOutput).toMatchSnapshot(); - }); - - it('should work without commits', async () => { - await initWithConfigAndCommit(); - prompts.inject(['**/*.{js,vue,json,ts,tsx,md,yml,html}', false]); - const [latestHusky, latestPrettier, latestPrettyQuick] = await Promise.all([ - latestVersion('husky'), - latestVersion('prettier'), - latestVersion('pretty-quick'), - ]); - - await Prettier.run(['--no-spinner']); - - const packageJson = filesystem.read('package.json', 'json'); - const htmlFile = filesystem.read('test.html', 'utf8'); - expect(consoleLogOutput).toMatchSnapshot(); - expect(packageJson).toStrictEqual({ - devDependencies: { - 'husky': latestHusky, - 'prettier': latestPrettier, - 'pretty-quick': latestPrettyQuick, +const checkFiles = async (extraDevDeps = {}) => { + const [latestHusky, latestPrettier, latestPrettyQuick] = await Promise.all([ + latestVersion('husky'), + latestVersion('prettier'), + latestVersion('pretty-quick'), + ]); + const packageJson = filesystem.read('package.json', 'json'); + const htmlFile = filesystem.read('test.html', 'utf8'); + expect(packageJson).toStrictEqual({ + devDependencies: { + ...extraDevDeps, + 'husky': latestHusky, + 'prettier': latestPrettier, + 'pretty-quick': latestPrettyQuick, + }, + husky: { + hooks: { + 'pre-commit': 'pretty-quick --staged', }, - husky: { - hooks: { - 'pre-commit': 'pretty-quick --staged', - }, - }, - scripts: { - 'format:check': 'prettier --list-different "**/*.{js,vue,json,ts,tsx,md,yml,html}"', - 'format:write': 'prettier --write "**/*.{js,vue,json,ts,tsx,md,yml,html}"', - }, - }); - expect(htmlFile).toMatchSnapshot(); - const after = await system.run('git log --name-status --format="%s"'); - const afterSlitted = after - .split('\n') - .map(val => val.trim()) - .map(val => stripANSI(val)) - .filter(val => val !== ''); + }, + scripts: { + 'format:check': + 'prettier --list-different "**/*.{js,vue,json,ts,tsx,md,yml,html}"', + 'format:write': + 'prettier --write "**/*.{js,vue,json,ts,tsx,md,yml,html}"', + }, + }); + expect(htmlFile).toMatchSnapshot(); +}; - expect(afterSlitted).toHaveLength(6); +export const expectEslintWithParams = ({ + eslintName, + eslintJson, + expectedEslint, +}: { + eslintName: string; + eslintJson: object | string; + expectedEslint: object; +}): TestRun => + expectGitCommits({ + before: async () => { + await beforeCreateHtml(); + filesystem.write(eslintName, eslintJson); + prompts.inject(['**/*.{js,vue,json,ts,tsx,md,yml,html}', true, true]); + }, + checks: async () => { + const [ + latestEslintPluginPrettier, + latestEslintConfigPrettier, + ] = await Promise.all([ + latestVersion('eslint-plugin-prettier'), + latestVersion('eslint-config-prettier'), + ]); + await checkFiles({ + 'eslint-plugin-prettier': latestEslintPluginPrettier, + 'eslint-config-prettier': latestEslintConfigPrettier, + }); + const eslintOutput = filesystem.read(eslintName, 'json'); + expect(eslintOutput).toStrictEqual(expectedEslint); + }, + expectGitLog: async () => { + const [ + latestHusky, + latestPrettier, + latestPrettyQuick, + latestEslintPluginPrettier, + latestEslintConfigPrettier, + ] = await Promise.all([ + latestVersion('husky'), + latestVersion('prettier'), + latestVersion('pretty-quick'), + latestVersion('eslint-plugin-prettier'), + latestVersion('eslint-config-prettier'), + ]); + return [ + ':wrench: update eslint to use prettier', + `M\t${eslintName}`, + `:heavy_plus_sign: add eslint-plugin-prettier@${latestEslintPluginPrettier} as a dev dependency`, + 'M\tpackage.json', + 'M\tyarn.lock', + `:heavy_plus_sign: add eslint-config-prettier@${latestEslintConfigPrettier} as a dev dependency`, + 'M\tpackage.json', + 'M\tyarn.lock', + ':art: apply prettier style to project', + 'M\tpackage.json', + 'M\ttest.html', + ':wrench: add prettierrc config file', + 'A\t.prettierrc', + ':wrench: add script and husky to package.json', + 'M\tpackage.json', + `:heavy_plus_sign: add pretty-quick@${latestPrettyQuick} as a dev dependency`, + 'M\tpackage.json', + 'M\tyarn.lock', + `:heavy_plus_sign: add husky@${latestHusky} as a dev dependency`, + 'M\tpackage.json', + 'M\tyarn.lock', + `:heavy_plus_sign: add prettier@${latestPrettier} as a dev dependency`, + 'M\tpackage.json', + 'M\tyarn.lock', + ]; + }, }); - it('should work with commits', async () => { - await initWithConfigAndCommit(); - prompts.inject(['**/*.{js,vue,json,ts,tsx,md,yml,html}', true]); - const [latestHusky, latestPrettier, latestPrettyQuick] = await Promise.all([ - latestVersion('husky'), - latestVersion('prettier'), - latestVersion('pretty-quick'), - ]); - await Prettier.run(['--no-spinner']); +export const expectTslintWithParams = ({ + tslintJson, + expectedTslint, +}: { + tslintJson: object | string; + expectedTslint: object; +}): TestRun => + expectGitCommits({ + before: async () => { + await beforeCreateHtml(); + filesystem.write('tslint.json', tslintJson); + prompts.inject(['**/*.{js,vue,json,ts,tsx,md,yml,html}', true, true]); + }, + checks: async () => { + const [ + latestTslintConfigPrettier, + latestTslintPluginPrettier, + ] = await Promise.all([ + latestVersion('tslint-config-prettier'), + latestVersion('tslint-plugin-prettier'), + ]); + await checkFiles({ + 'tslint-config-prettier': latestTslintConfigPrettier, + 'tslint-plugin-prettier': latestTslintPluginPrettier, + }); + const tslintOutput = filesystem.read('tslint.json', 'json'); + expect(tslintOutput).toStrictEqual(expectedTslint); + }, + expectGitLog: async () => { + const [ + latestHusky, + latestPrettier, + latestPrettyQuick, + latestTslintPluginPrettier, + latestTslintConfigPrettier, + ] = await Promise.all([ + latestVersion('husky'), + latestVersion('prettier'), + latestVersion('pretty-quick'), + latestVersion('tslint-config-prettier'), + latestVersion('tslint-plugin-prettier'), + ]); + return [ + ':wrench: update tslint to use prettier', + `M\ttslint.json`, + `:heavy_plus_sign: add tslint-plugin-prettier@${latestTslintConfigPrettier} as a dev dependency`, + 'M\tpackage.json', + 'M\tyarn.lock', + `:heavy_plus_sign: add tslint-config-prettier@${latestTslintPluginPrettier} as a dev dependency`, + 'M\tpackage.json', + 'M\tyarn.lock', + ':art: apply prettier style to project', + 'M\tpackage.json', + 'M\ttest.html', + 'M\ttslint.json', + ':wrench: add prettierrc config file', + 'A\t.prettierrc', + ':wrench: add script and husky to package.json', + 'M\tpackage.json', + `:heavy_plus_sign: add pretty-quick@${latestPrettyQuick} as a dev dependency`, + 'M\tpackage.json', + 'M\tyarn.lock', + `:heavy_plus_sign: add husky@${latestHusky} as a dev dependency`, + 'M\tpackage.json', + 'M\tyarn.lock', + `:heavy_plus_sign: add prettier@${latestPrettier} as a dev dependency`, + 'M\tpackage.json', + 'M\tyarn.lock', + ]; + }, + }); - const packageJson = filesystem.read('package.json', 'json'); - const htmlFile = filesystem.read('test.html', 'utf8'); - expect(consoleLogOutput).toMatchSnapshot(); - expect(packageJson).toStrictEqual({ - devDependencies: { - 'husky': latestHusky, - 'prettier': latestPrettier, - 'pretty-quick': latestPrettyQuick, - }, - husky: { - hooks: { - 'pre-commit': 'pretty-quick --staged', +testCli({ + runCommand: (args: string[]) => Prettier.run(args), + name: 'nbx add:tailwind', + defaultArgs: ['--no-spinner'], + tests: [ + { + name: 'fail if no package.json found', + runner: expectFailCli({ + errorMessage: + 'There is no package.json not found in the current folder', + before: async () => { + filesystem.remove('package.json'); }, - }, - scripts: { - 'format:check': 'prettier --list-different "**/*.{js,vue,json,ts,tsx,md,yml,html}"', - 'format:write': 'prettier --write "**/*.{js,vue,json,ts,tsx,md,yml,html}"', - }, - }); - expect(htmlFile).toMatchSnapshot(); - const after = await system.run('git log --name-status --format="%s"'); - const afterSlitted = after - .split('\n') - .map(val => val.trim()) - .map(val => stripANSI(val)) - .filter(val => val !== ''); - - expect(afterSlitted).toStrictEqual([ - ':art: apply prettier style to project', - 'M\tpackage.json', - 'M\ttest.html', - ':wrench: add prettierrc config file', - 'A\t.prettierrc', - ':wrench: add script and husky to package.json', - 'M\tpackage.json', - `:heavy_plus_sign: add pretty-quick@${latestPrettyQuick} as a dev dependency`, - 'M\tpackage.json', - 'M\tyarn.lock', - `:heavy_plus_sign: add husky@${latestHusky} as a dev dependency`, - 'M\tpackage.json', - 'M\tyarn.lock', - `:heavy_plus_sign: add prettier@${latestPrettier} as a dev dependency`, - 'M\tpackage.json', - 'M\tyarn.lock', - 'init state', - 'A\t.gitignore', - 'A\t.nbxrc', - 'A\tpackage.json', - 'A\ttest.html', - 'A\tyarn.lock', - ]); - }); + }), + }, + { + name: 'fail if prettier is found in package.json', + runner: expectFailGitCommits({ + errorMessage: 'Prettier is already installed in this project.', + packageJson: { + devDependencies: { + prettier: '2.0.0', + }, + }, + }), + }, + { + name: 'work without commits', + runner: expectGitCommits({ + expectGitLog: [], + checks: checkFiles, + before: async () => { + await beforeCreateHtml(); + prompts.inject(['**/*.{js,vue,json,ts,tsx,md,yml,html}', false]); + }, + }), + }, + { + name: 'work with commits', + runner: expectGitCommits({ + expectGitLog: async () => { + const [ + latestHusky, + latestPrettier, + latestPrettyQuick, + ] = await Promise.all([ + latestVersion('husky'), + latestVersion('prettier'), + latestVersion('pretty-quick'), + ]); + return [ + ':art: apply prettier style to project', + 'M\tpackage.json', + 'M\ttest.html', + ':wrench: add prettierrc config file', + 'A\t.prettierrc', + ':wrench: add script and husky to package.json', + 'M\tpackage.json', + `:heavy_plus_sign: add pretty-quick@${latestPrettyQuick} as a dev dependency`, + 'M\tpackage.json', + 'M\tyarn.lock', + `:heavy_plus_sign: add husky@${latestHusky} as a dev dependency`, + 'M\tpackage.json', + 'M\tyarn.lock', + `:heavy_plus_sign: add prettier@${latestPrettier} as a dev dependency`, + 'M\tpackage.json', + 'M\tyarn.lock', + ]; + }, + checks: checkFiles, + before: async () => { + await beforeCreateHtml(); + prompts.inject(['**/*.{js,vue,json,ts,tsx,md,yml,html}', true]); + }, + }), + }, + { + name: 'work with tslint and commits and with an empty config', + runner: expectTslintWithParams({ + tslintJson: {}, + expectedTslint: { + extends: ['tslint-plugin-prettier', 'tslint-config-prettier'], + rules: { + prettier: true, + }, + }, + }), + }, + { + name: 'work with tslint and commits and with an existing rules config', + runner: expectTslintWithParams({ + tslintJson: { + rules: { + toto: true, + }, + }, + expectedTslint: { + extends: ['tslint-plugin-prettier', 'tslint-config-prettier'], + rules: { + toto: true, + prettier: true, + }, + }, + }), + }, + { + name: + 'work with tslint and commits and with an existing extends as string', + runner: expectTslintWithParams({ + tslintJson: { + extends: 'my-think', + rules: { + toto: true, + }, + }, + expectedTslint: { + extends: [ + 'my-think', + 'tslint-plugin-prettier', + 'tslint-config-prettier', + ], + rules: { + toto: true, + prettier: true, + }, + }, + }), + }, + { + name: + 'work with tslint and commits and with an existing extends as array', + runner: expectTslintWithParams({ + tslintJson: { + extends: ['my-think'], + rules: { + toto: true, + }, + }, + expectedTslint: { + extends: [ + 'my-think', + 'tslint-plugin-prettier', + 'tslint-config-prettier', + ], + rules: { + toto: true, + prettier: true, + }, + }, + }), + }, + { + name: 'work with eslint and commits and with an empty .eslintrc', + runner: expectEslintWithParams({ + eslintName: '.eslintrc', + eslintJson: {}, + expectedEslint: { + extends: ['plugin:prettier/recommended'], + }, + }), + }, + { + name: 'work with eslint and commits and with extends as array .eslintrc', + runner: expectEslintWithParams({ + eslintJson: { + extends: ['test'], + }, + eslintName: '.eslintrc', + expectedEslint: { + extends: ['test', 'plugin:prettier/recommended'], + }, + }), + }, + { + name: + 'work with eslint and commits and with extends as array .eslintrc.json', + runner: expectEslintWithParams({ + eslintJson: '{}\n', + eslintName: '.eslintrc.json', + expectedEslint: { + extends: ['plugin:prettier/recommended'], + }, + }), + }, + { + name: 'work with eslint and commits and with extends as string .eslintrc', + runner: expectEslintWithParams({ + eslintJson: { + extends: 'test', + }, + eslintName: '.eslintrc', + expectedEslint: { + extends: ['test', 'plugin:prettier/recommended'], + }, + }), + }, + ], }); diff --git a/src/tests/add/tailwind.spec.ts b/src/tests/add/tailwind.spec.ts index 5840155..f4873b3 100644 --- a/src/tests/add/tailwind.spec.ts +++ b/src/tests/add/tailwind.spec.ts @@ -12,7 +12,13 @@ import { jest.setTimeout(90000); const checkPackgeAndPostcssConfig = async () => { - const [tailwind, purgecss, autoprefixer, npmRunAll, postcss] = await Promise.all([ + const [ + tailwind, + purgecss, + autoprefixer, + npmRunAll, + postcss, + ] = await Promise.all([ latestVersion('tailwindcss'), latestVersion('@fullhuman/postcss-purgecss'), latestVersion('autoprefixer'), @@ -41,7 +47,8 @@ const checkPackgeAndPostcssConfig = async () => { 'start:css': 'postcss src/css/tailwind.src.css -o src/tailwind.css -w', 'start:js': 'react-scripts start', 'build': 'npm-run-all build:css build:js', - 'build:css': 'postcss src/css/tailwind.src.css -o src/tailwind.css --env production', + 'build:css': + 'postcss src/css/tailwind.src.css -o src/tailwind.css --env production', 'build:js': 'react-scripts build', 'test': 'react-scripts test', 'eject': 'react-scripts eject', @@ -57,7 +64,8 @@ testCli({ { name: 'fail if no package.json found', runner: expectFailCli({ - errorMessage: 'There is no package.json not found in the current folder', + errorMessage: + 'There is no package.json not found in the current folder', before: async () => { filesystem.remove('package.json'); }, @@ -69,6 +77,17 @@ testCli({ errorMessage: 'This script support only for now create react apps.', }), }, + { + name: 'error if tailwind is found', + runner: expectFailGitCommits({ + packageJson: { + dependencies: { + tailwind: '2.0.0', + }, + }, + errorMessage: 'Tailwind is already installed in this project.', + }), + }, { name: 'work on a react application without commits', runner: expectGitCommits({ @@ -111,7 +130,13 @@ testCli({ }, }, expectGitLog: async () => { - const [tailwind, purgecss, autoprefixer, npmRunAll, postcss] = await Promise.all([ + const [ + tailwind, + purgecss, + autoprefixer, + npmRunAll, + postcss, + ] = await Promise.all([ latestVersion('tailwindcss'), latestVersion('@fullhuman/postcss-purgecss'), latestVersion('autoprefixer'), diff --git a/src/tests/test-helpers.spec.ts b/src/tests/test-helpers.spec.ts index c4a651e..1062e07 100644 --- a/src/tests/test-helpers.spec.ts +++ b/src/tests/test-helpers.spec.ts @@ -1,7 +1,10 @@ const stripANSI = require('strip-ansi'); import { filesystem, system } from 'gluegun'; -export type TestRun = (args: { exec: Function; defaultArgs?: string[] }) => Promise; +export type TestRun = (args: { + exec: Function; + defaultArgs?: string[]; +}) => Promise; export interface TestCase { name: string; @@ -25,7 +28,7 @@ export const initWithConfigAndCommit = async (packageJson = {}) => { filesystem.write('package.json', packageJson); await system.run('touch yarn.lock'); await system.run('echo node_modules > .gitignore'); - await system.run('git add * .nbxrc .gitignore'); + await system.run('git add -A'); try { await system.run('git config user.email "you@example.com"'); await system.run('git config user.name "Your Name"'); @@ -46,40 +49,32 @@ export const expectGitCommits = ({ checks?: () => Promise; packageJson?: object; }): TestRun => async ({ exec, defaultArgs = [] }) => { - await initWithConfigAndCommit(packageJson); await before?.(); + await initWithConfigAndCommit(packageJson); try { await exec([...args, ...defaultArgs]); - } catch { + } catch (e) { + console.error(e); fail('Cli errored'); } const after = await system.run('git log --name-status --format="%s"'); const afterSlitted = after .split('\n') - .map(val => val.trim()) - .map(val => stripANSI(val)) - .filter(val => val !== ''); + .map((val) => val.trim()) + .map((val) => stripANSI(val)) + .filter((val) => val !== ''); + + const initState = afterSlitted.slice(afterSlitted.indexOf('init state')); if (expectGitLog instanceof Function) { expect(afterSlitted).toStrictEqual([ ...(await expectGitLog()), - 'init state', - 'A\t.gitignore', - 'A\t.nbxrc', - 'A\tpackage.json', - 'A\tyarn.lock', + ...initState, ]); } else { - expect(afterSlitted).toStrictEqual([ - ...expectGitLog, - 'init state', - 'A\t.gitignore', - 'A\t.nbxrc', - 'A\tpackage.json', - 'A\tyarn.lock', - ]); + expect(afterSlitted).toStrictEqual([...expectGitLog, ...initState]); } await checks?.(); @@ -115,9 +110,9 @@ export const expectFailGitCommits = ({ const after = await system.run('git log --name-status --format="%s"'); const afterSlitted = after .split('\n') - .map(val => val.trim()) - .map(val => stripANSI(val)) - .filter(val => val !== ''); + .map((val) => val.trim()) + .map((val) => stripANSI(val)) + .filter((val) => val !== ''); expect(afterSlitted).toStrictEqual([ 'init state', @@ -161,7 +156,12 @@ export const expectFailCli = ({ } }; -export const testCli = ({ tests, runCommand, name, defaultArgs }: TestCliParams) => { +export const testCli = ({ + tests, + runCommand, + name, + defaultArgs, +}: TestCliParams) => { /* eslint-disable no-console,max-nested-callbacks,@typescript-eslint/ban-ts-ignore */ let consoleLogOutput: string[]; let execPath: string; @@ -172,7 +172,9 @@ export const testCli = ({ tests, runCommand, name, defaultArgs }: TestCliParams) consoleLogOutput = []; console.log = (x: any) => consoleLogOutput.push(stripANSI(x)); - const tmpDirName = `${new Date().getTime()}-${Math.random() * 100}-add-nbx-test`; + const tmpDirName = `${new Date().getTime()}-${ + Math.random() * 100 + }-add-nbx-test`; execPath = filesystem.path('/', 'tmp', tmpDirName); filesystem.dir(execPath); process.chdir(execPath); @@ -192,7 +194,7 @@ export const testCli = ({ tests, runCommand, name, defaultArgs }: TestCliParams) expect(consoleLogOutput).toMatchSnapshot(); }); - tests.forEach(testCase => { + tests.forEach((testCase) => { it(`should ${testCase.name}`, async () => { await testCase.runner({ exec: runCommand, defaultArgs: defaultArgs }); expect(consoleLogOutput).toMatchSnapshot(); diff --git a/src/tests/wall.spec.ts b/src/tests/wall.spec.ts index fce8218..a7b5e6e 100644 --- a/src/tests/wall.spec.ts +++ b/src/tests/wall.spec.ts @@ -13,7 +13,9 @@ beforeEach(() => { consoleLogOutput = []; console.log = (x: any) => consoleLogOutput.push(stripANSI(x)); - const tmpDirName = `${new Date().getTime()}-${Math.random() * 100}-add-nbx-test`; + const tmpDirName = `${new Date().getTime()}-${ + Math.random() * 100 + }-add-nbx-test`; execPath = filesystem.path('/', 'tmp', tmpDirName); filesystem.dir(execPath); process.chdir(execPath); @@ -80,7 +82,9 @@ describe('wall command', () => { expect(consoleLogOutput).toMatchSnapshot(); const files = filesystem.list('.'); expect(files && files[0]).toBe('wall.jpg'); - expect(filesystem.read('wall.jpg', 'json')).toStrictEqual({ name: 'hello' }); + expect(filesystem.read('wall.jpg', 'json')).toStrictEqual({ + name: 'hello', + }); }); it('should print a warning when output exists with the force flag', async () => {