Skip to content

Commit

Permalink
Testing the cli functionality
Browse files Browse the repository at this point in the history
  • Loading branch information
ksa committed Oct 2, 2016
1 parent 9e56c7d commit 30f4659
Show file tree
Hide file tree
Showing 6 changed files with 174 additions and 64 deletions.
2 changes: 1 addition & 1 deletion bin/jest-codemods.js
@@ -1,2 +1,2 @@
#!/usr/bin/env node #!/usr/bin/env node
require('../dist/cli'); require('../dist/cli/index');
27 changes: 27 additions & 0 deletions src/cli/git-status.js
@@ -0,0 +1,27 @@
import isGitClean from 'is-git-clean';

export default function checkGitStatus(force) {
let clean = false;
let errorMessage = 'Unable to determine if git directory is clean';
try {
clean = isGitClean.sync(process.cwd());
errorMessage = 'Git directory is not clean';
} catch (err) {
if (err && err.stderr && err.stderr.indexOf('Not a git repository') >= 0) {
clean = true;
}
}

if (!clean) {
if (force) {
console.log(`WARNING: ${errorMessage}. Forcibly continuing.`);
} else {
console.log(
`ERROR: ${errorMessage}. Refusing to continue.`,
'Ensure you have a backup of your tests or commit the latest changes before continuing.',
'You may use the --force flag to override this safety check.'
);
process.exit(1);
}
}
}
62 changes: 62 additions & 0 deletions src/cli/git-status.test.js
@@ -0,0 +1,62 @@
/* eslint-env jest */

let gitStatusReturnValue;
jest.setMock('is-git-clean', {
sync: () => {
if (typeof gitStatusReturnValue === 'boolean') {
return gitStatusReturnValue;
}
throw gitStatusReturnValue;
},
});

const checkGitStatus = require('./git-status').default;

it('does not exit and output any logs when git repo is clean', () => {
gitStatusReturnValue = true;
console.log = jest.fn();
process.exit = jest.fn();
checkGitStatus();
expect(console.log).not.toBeCalled();
expect(process.exit).not.toBeCalled();
});

it('does not exit and output any logs when not a git repo', () => {
const err = new Error();
err.stderr = 'Not a git repository';
gitStatusReturnValue = err;
console.log = jest.fn();
process.exit = jest.fn();
checkGitStatus();
expect(console.log).not.toBeCalled();
expect(process.exit).not.toBeCalled();
});

it('exits and output logs when git repo is dirty', () => {
gitStatusReturnValue = false;
console.log = jest.fn();
process.exit = jest.fn();
checkGitStatus();
expect(console.log).toBeCalled();
expect(process.exit).toBeCalled();
});

it('exits and output logs when git detection fail', () => {
gitStatusReturnValue = new Error('bum');
console.log = jest.fn();
process.exit = jest.fn();
checkGitStatus();
expect(console.log).toBeCalled();
expect(process.exit).toBeCalled();
});

it('does not exit when git repo is dirty and force flag is given', () => {
gitStatusReturnValue = false;
console.log = jest.fn();
process.exit = jest.fn();
checkGitStatus(true);
expect(console.log).toBeCalledWith(
'WARNING: Git directory is not clean. Forcibly continuing.'
);
expect(process.exit).not.toBeCalled();
});
66 changes: 3 additions & 63 deletions src/cli.js → src/cli/index.js
@@ -1,69 +1,11 @@
#!/usr/bin/env node #!/usr/bin/env node
import path from 'path';

import execa from 'execa';
import globby from 'globby'; import globby from 'globby';
import inquirer from 'inquirer'; import inquirer from 'inquirer';
import isGitClean from 'is-git-clean';
import meow from 'meow'; import meow from 'meow';
import updateNotifier from 'update-notifier'; import updateNotifier from 'update-notifier';


function checkGitStatus(force) { import checkGitStatus from './git-status';
let clean = false; import { executeTransformations } from './transformers';
let errorMessage = 'Unable to determine if git directory is clean';
try {
clean = isGitClean.sync(process.cwd());
errorMessage = 'Git directory is not clean';
} catch (err) {
if (err && err.stderr && err.stderr.indexOf('Not a git repository') >= 0) {
clean = true;
}
}

const ENSURE_BACKUP_MESSAGE = 'Ensure you have a backup of your tests or commit the latest changes before continuing.';

if (!clean) {
if (force) {
console.log(`WARNING: ${errorMessage}. Forcibly continuing.`, ENSURE_BACKUP_MESSAGE);
} else {
console.log(
`ERROR: ${errorMessage}. Refusing to continue.`,
ENSURE_BACKUP_MESSAGE,
'You may use the --force flag to override this safety check.'
);
process.exit(1);
}
}
}

function executeTransformation(files, flags, transformer) {
const transformerPath = path.join(__dirname, 'transformers', `${transformer}.js`);

const args = ['-t', transformerPath].concat(files);
if (flags.dry) {
args.push('--dry');
}
if (['babel', 'babylon', 'flow'].indexOf(flags.parser) >= 0) {
args.push('--parser', flags.parser);
}

console.log(`Executing command: jscodeshift ${args.join(' ')}`);

const result = execa.sync(require.resolve('.bin/jscodeshift'), args, {
stdio: 'inherit',
stripEof: false,
});

if (result.error) {
throw result.error;
}
}

function executeTransformations(files, flags, transformers) {
transformers.forEach(t => {
executeTransformation(files, flags, t);
});
}


const cli = meow( const cli = meow(
{ {
Expand Down Expand Up @@ -150,8 +92,6 @@ if (cli.input.length) {
} }


const transformers = transformer === 'all' ? ['tape', 'ava'] : [transformer]; const transformers = transformer === 'all' ? ['tape', 'ava'] : [transformer];
transformers.forEach(t => { executeTransformations(filesExpanded, cli.flags, transformers);
executeTransformation(filesExpanded, cli.flags, t);
});
}); });
} }
34 changes: 34 additions & 0 deletions src/cli/transformers.js
@@ -0,0 +1,34 @@
import path from 'path';
import execa from 'execa';

export const transformerDirectory = path.join(__dirname, '../', 'transformers');
export const jscodeshiftExecutable = require.resolve('.bin/jscodeshift');

function executeTransformation(files, flags, transformer) {
const transformerPath = path.join(transformerDirectory, `${transformer}.js`);

const args = ['-t', transformerPath].concat(files);
if (flags.dry) {
args.push('--dry');
}
if (['babel', 'babylon', 'flow'].indexOf(flags.parser) >= 0) {
args.push('--parser', flags.parser);
}

console.log(`Executing command: jscodeshift ${args.join(' ')}`);

const result = execa.sync(jscodeshiftExecutable, args, {
stdio: 'inherit',
stripEof: false,
});

if (result.error) {
throw result.error;
}
}

export function executeTransformations(files, flags, transformers) {
transformers.forEach(t => {
executeTransformation(files, flags, t);
});
}
47 changes: 47 additions & 0 deletions src/cli/transformers.test.js
@@ -0,0 +1,47 @@
/* eslint-env jest */

let execaReturnValue;
jest.setMock('execa', {
sync: () => execaReturnValue,
});

const fs = require('fs');
const path = require('path');
const {
executeTransformations, jscodeshiftExecutable, transformerDirectory,
} = require('./transformers');

it('finds transformer directory', () => {
fs.lstatSync(transformerDirectory);
});

it('finds jscodeshift executable', () => {
fs.lstatSync(jscodeshiftExecutable);
});

it('runs jscodeshift for the given transformer', () => {
execaReturnValue = { error: null };
console.log = jest.fn();
executeTransformations('src', {}, ['tape']);
expect(console.log).toBeCalledWith(
`Executing command: jscodeshift -t ${path.join(transformerDirectory, 'tape.js')} src`
);
});

it('supports jscodeshift flags', () => {
execaReturnValue = { error: null };
console.log = jest.fn();
executeTransformations('folder', { dry: true, parser: 'flow' }, ['ava']);
expect(console.log).toBeCalledWith(
`Executing command: jscodeshift -t ${path.join(transformerDirectory, 'ava.js')} folder --dry --parser flow`
);
});

it('rethrows jscodeshift errors', () => {
const transformerError = new Error('bum');
execaReturnValue = { error: transformerError };
console.log = jest.fn();
expect(() => {
executeTransformations('src', {}, ['tape']);
}).toThrowError(transformerError);
});

0 comments on commit 30f4659

Please sign in to comment.