9 changed files with 713 additions and 182 deletions
-
7.releaserc.js
-
2package.json
-
270src/tests/add/__snapshots__/prettier.spec.ts.snap
-
2src/tests/add/__snapshots__/tailwind.spec.ts.snap
-
3src/tests/add/dep.spec.ts
-
516src/tests/add/prettier.spec.ts
-
33src/tests/add/tailwind.spec.ts
-
54src/tests/test-helpers.spec.ts
-
8src/tests/wall.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', '<html><body><a>testokiii</a></body></html>'); |
|||
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'], |
|||
}, |
|||
}), |
|||
}, |
|||
], |
|||
}); |
|||
Write
Preview
Loading…
Cancel
Save
Reference in new issue