From 30f465935ccf53e65cb83becb149bbec62c6943b Mon Sep 17 00:00:00 2001 From: ksa Date: Sun, 2 Oct 2016 14:47:51 +0200 Subject: [PATCH] Testing the cli functionality --- bin/jest-codemods.js | 2 +- src/cli/git-status.js | 27 +++++++++++++++ src/cli/git-status.test.js | 62 +++++++++++++++++++++++++++++++++ src/{cli.js => cli/index.js} | 66 ++---------------------------------- src/cli/transformers.js | 34 +++++++++++++++++++ src/cli/transformers.test.js | 47 +++++++++++++++++++++++++ 6 files changed, 174 insertions(+), 64 deletions(-) create mode 100644 src/cli/git-status.js create mode 100644 src/cli/git-status.test.js rename src/{cli.js => cli/index.js} (58%) create mode 100644 src/cli/transformers.js create mode 100644 src/cli/transformers.test.js diff --git a/bin/jest-codemods.js b/bin/jest-codemods.js index d1c523a9..9988cd44 100755 --- a/bin/jest-codemods.js +++ b/bin/jest-codemods.js @@ -1,2 +1,2 @@ #!/usr/bin/env node -require('../dist/cli'); +require('../dist/cli/index'); diff --git a/src/cli/git-status.js b/src/cli/git-status.js new file mode 100644 index 00000000..da4a767e --- /dev/null +++ b/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); + } + } +} diff --git a/src/cli/git-status.test.js b/src/cli/git-status.test.js new file mode 100644 index 00000000..1103b6bb --- /dev/null +++ b/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(); +}); diff --git a/src/cli.js b/src/cli/index.js similarity index 58% rename from src/cli.js rename to src/cli/index.js index bdc622f7..ff4ede19 100644 --- a/src/cli.js +++ b/src/cli/index.js @@ -1,69 +1,11 @@ #!/usr/bin/env node -import path from 'path'; - -import execa from 'execa'; import globby from 'globby'; import inquirer from 'inquirer'; -import isGitClean from 'is-git-clean'; import meow from 'meow'; import updateNotifier from 'update-notifier'; -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; - } - } - - 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); - }); -} +import checkGitStatus from './git-status'; +import { executeTransformations } from './transformers'; const cli = meow( { @@ -150,8 +92,6 @@ if (cli.input.length) { } const transformers = transformer === 'all' ? ['tape', 'ava'] : [transformer]; - transformers.forEach(t => { - executeTransformation(filesExpanded, cli.flags, t); - }); + executeTransformations(filesExpanded, cli.flags, transformers); }); } diff --git a/src/cli/transformers.js b/src/cli/transformers.js new file mode 100644 index 00000000..ef26caca --- /dev/null +++ b/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); + }); +} diff --git a/src/cli/transformers.test.js b/src/cli/transformers.test.js new file mode 100644 index 00000000..11027b43 --- /dev/null +++ b/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); +});