Browse Source

♻️ refactor cli tests

pull/58/head
Nicolas Beaussart 6 years ago
parent
commit
5d53332921
  1. 190
      src/tests/add/dep.spec.ts
  2. 153
      src/tests/test-helpers.spec.ts

190
src/tests/add/dep.spec.ts

@ -1,145 +1,99 @@
import { filesystem, system } from 'gluegun';
const stripANSI = require('strip-ansi');
import { filesystem } from 'gluegun';
import * as latestVersion from 'latest-version';
import Dep from '../../commands/add/dep';
import {
createDefaultNbxConfig,
expectFailCli,
expectGitCommits,
testCli,
} 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', {});
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('dep', () => {
it('should print help correctly', async () => {
try {
await Dep.run(['-h']);
} catch {}
expect(consoleLogOutput).toMatchSnapshot();
});
it('should fail if no package.json found', async () => {
expect.assertions(1);
try {
testCli({
runCommand: (args: string[]) => Dep.run(args),
name: 'nbx add:dep',
defaultArgs: ['--no-spinner'],
tests: [
{
name: 'fail if no package.json found',
runner: expectFailCli({
args: ['chalk'],
errorMessage: 'There is no package.json not found in the current folder',
before: async () => {
filesystem.remove('package.json');
await Dep.run(['chalk', '--no-spinner']);
// eslint-disable-next-line unicorn/catch-error-name
} catch (e) {
expect(e).toMatchSnapshot();
}
});
it('should fail if dependancy is already in package.json', async () => {
expect.assertions(1);
try {
},
}),
},
{
name: 'fail if dependancy is already in package.json',
runner: expectFailCli({
args: ['chalk'],
errorMessage: 'chalk is already installed in this project',
before: async () => {
await createDefaultNbxConfig();
filesystem.write('package.json', { dependencies: { chalk: '2.3.2' } });
await Dep.run(['chalk', '--no-spinner']);
// eslint-disable-next-line unicorn/catch-error-name
} catch (e) {
expect(e).toMatchSnapshot();
}
});
it('should fail if dev dependancy is already in package.json', async () => {
expect.assertions(1);
try {
},
}),
},
{
name: 'fail if dev dependancy is already in package.json',
runner: expectFailCli({
args: ['chalk', '-D'],
errorMessage: 'chalk is already installed in this project',
before: async () => {
await createDefaultNbxConfig();
filesystem.write('package.json', { devDependencies: { chalk: '2.3.2' } });
await Dep.run(['chalk', '--dev', '--no-spinner']);
// eslint-disable-next-line unicorn/catch-error-name
} catch (e) {
expect(e).toMatchSnapshot();
}
});
it('should work with dependency', async () => {
await initWithConfigAndCommit();
},
}),
},
{
name: 'work with dependency',
runner: expectGitCommits({
args: ['chalk'],
expectGitLog: async () => {
const latestChalk = await latestVersion('chalk');
return [
`:heavy_plus_sign: add chalk@${latestChalk} as a dependency`,
'M\tpackage.json',
'M\tyarn.lock',
];
},
checks: async () => {
const latestChalk = await latestVersion('chalk');
await Dep.run(['chalk', '--no-spinner']);
const packageJson = filesystem.read('package.json', 'json');
expect(consoleLogOutput).toMatchSnapshot();
expect(packageJson).toStrictEqual({
dependencies: {
chalk: latestChalk,
},
});
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([
`:heavy_plus_sign: add chalk@${latestChalk} as a dependency`,
},
}),
},
{
name: 'work with a dev dependency',
runner: expectGitCommits({
args: ['chalk', '-D'],
expectGitLog: async () => {
const latestChalk = await latestVersion('chalk');
return [
`:heavy_plus_sign: add chalk@${latestChalk} as a dev dependency`,
'M\tpackage.json',
'M\tyarn.lock',
'init state',
'A\t.gitignore',
'A\t.nbxrc',
'A\tpackage.json',
'A\tyarn.lock',
]);
});
it('should work with a dev dependency', async () => {
await initWithConfigAndCommit();
];
},
checks: async () => {
const latestChalk = await latestVersion('chalk');
await Dep.run(['chalk', '-D', '--no-spinner']);
const packageJson = filesystem.read('package.json', 'json');
expect(consoleLogOutput).toMatchSnapshot();
expect(packageJson).toStrictEqual({
devDependencies: {
chalk: latestChalk,
},
});
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([
`:heavy_plus_sign: add chalk@${latestChalk} as a dev dependency`,
'M\tpackage.json',
'M\tyarn.lock',
'init state',
'A\t.gitignore',
'A\t.nbxrc',
'A\tpackage.json',
'A\tyarn.lock',
]);
});
},
}),
},
],
});

153
src/tests/test-helpers.spec.ts

@ -0,0 +1,153 @@
import { Command } from '@oclif/command';
const stripANSI = require('strip-ansi');
import { filesystem, system } from 'gluegun';
export type TestRun = (args: { exec: Function; defaultArgs?: string[] }) => Promise<any>;
export interface TestCase {
name: string;
runner: TestRun;
}
export interface TestCliParams {
tests: TestCase[];
runCommand: (args: string[]) => PromiseLike<any>;
name: string;
defaultArgs?: string[];
}
export const createDefaultNbxConfig = async () => {
filesystem.write('.nbxrc', { git: { user: 'aaa', email: 'bbb' } });
};
export const initWithConfigAndCommit = async () => {
await system.run('git init');
await createDefaultNbxConfig();
filesystem.write('package.json', {});
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"');
};
export const expectGitCommits = ({
before,
args,
expectGitLog,
checks,
}: {
args: string[];
expectGitLog: string[] | (() => Promise<any>);
before?: () => Promise<any>;
checks?: () => Promise<any>;
}): TestRun => async ({ exec, defaultArgs = [] }) => {
await initWithConfigAndCommit();
await before?.();
try {
await exec([...args, ...defaultArgs]);
} catch {
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 !== '');
if (expectGitLog instanceof Function) {
expect(afterSlitted).toStrictEqual([
...(await expectGitLog()),
'init state',
'A\t.gitignore',
'A\t.nbxrc',
'A\tpackage.json',
'A\tyarn.lock',
]);
} else {
expect(afterSlitted).toStrictEqual([
...expectGitLog,
'init state',
'A\t.gitignore',
'A\t.nbxrc',
'A\tpackage.json',
'A\tyarn.lock',
]);
}
await checks?.();
};
export const expectFailCli = ({
assertions = 4,
before,
args,
errorMessage,
}: {
assertions?: number;
before?: () => Promise<any>;
args: string[];
errorMessage: string;
}): TestRun => async ({ exec, defaultArgs = [] }) => {
expect.assertions(assertions);
try {
await before?.();
await exec([...args, ...defaultArgs]);
// eslint-disable-next-line unicorn/catch-error-name
} catch (e) {
expect(e).toBeDefined();
expect(e.message).toBeDefined();
expect(e.message).toBe(errorMessage);
}
};
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;
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);
});
describe(name, () => {
it('should print help correctly', async () => {
try {
await runCommand(['-h']);
} catch {}
expect(consoleLogOutput).toMatchSnapshot();
});
tests.forEach(testCase => {
it(`should ${testCase.name}`, async () => {
await testCase.runner({ exec: runCommand, defaultArgs: defaultArgs });
expect(consoleLogOutput).toMatchSnapshot();
});
});
});
};
const testHelp = (command: Command) => {
it('');
};
Loading…
Cancel
Save