Skip to content

Commit

Permalink
Add tests for watch mode and extract KEYS to contstants module
Browse files Browse the repository at this point in the history
  • Loading branch information
rogeliog committed Jan 8, 2017
1 parent 4a91dd6 commit 7909aeb
Show file tree
Hide file tree
Showing 4 changed files with 205 additions and 30 deletions.
8 changes: 5 additions & 3 deletions packages/jest-cli/src/__tests__/TestRunner-test.js
Expand Up @@ -14,7 +14,6 @@ const TestRunner = require('../TestRunner');
const TestWatcher = require('../TestWatcher');
const SummaryReporter = require('../reporters/SummaryReporter');

let worker;
let workerFarmMock;

jest.mock('worker-farm', () => {
Expand Down Expand Up @@ -56,9 +55,10 @@ describe('_createInBandTestRun()', () => {
).then(() => {
expect(workerFarmMock.mock.calls).toEqual([
[{config, path: './file-test.js', rawModuleMap}, jasmine.any(Function)],
// eslint-disable-next-line max-len
[{config, path: './file2-test.js', rawModuleMap}, jasmine.any(Function)],
]);
})
});
});

test('does not inject the rawModuleMap in non watch mode', () => {
Expand All @@ -73,9 +73,11 @@ describe('_createInBandTestRun()', () => {
() => {},
).then(() => {
expect(workerFarmMock.mock.calls).toEqual([
/* eslint-disable max-len */
[{config, path: './file-test.js', rawModuleMap: null}, jasmine.any(Function)],
[{config, path: './file2-test.js', rawModuleMap: null}, jasmine.any(Function)],
/* eslint-enable max-len */
]);
})
});
});
});
158 changes: 158 additions & 0 deletions packages/jest-cli/src/__tests__/watch-test.js
@@ -0,0 +1,158 @@
/**
* Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*
* @emails oncall+jsinfra
*/

'use strict';

const chalk = require('chalk');
const TestWatcher = require('../TestWatcher');
const {KEYS} = require('../constants');

const runJestMock = jest.fn();

jest.mock('jest-util', () => ({clearLine: () => {}}));
jest.doMock('chalk', () => new chalk.constructor({enabled: false}));
jest.doMock('../constants', () => ({CLEAR: '', KEYS}));
jest.doMock('../runJest', () => (...args) => {
runJestMock(...args);

// Call the callback
args[args.length - 1]({snapshot: {}});

return Promise.resolve();
});

const watch = require('../watch');

const USAGE_MESSAGE = `
Watch Usage
› Press o to only run tests related to changed files.
› Press p to filter by a filename regex pattern.
› Press q to quit watch mode.
› Press Enter to trigger a test run.`;

afterEach(runJestMock.mockReset);

describe('Watch mode flows', () => {
let pipe;
let hasteMap;
let argv;
let hasteContext;
let config;
let stdin;

beforeEach(() => {
pipe = {write: jest.fn()};
hasteMap = {on: () => {}};
argv = {};
hasteContext = {};
config = {};
stdin = new MockStdin();
});

it('Runs Jest once by default and shows usage', () => {
watch(config, pipe, argv, hasteMap, hasteContext, stdin);
expect(runJestMock).toBeCalledWith(hasteContext, config, argv, pipe,
new TestWatcher({isWatchMode: true}), jasmine.any(Function));
expect(pipe.write).toBeCalledWith(USAGE_MESSAGE);
});

it('Pressing "o" runs test in "only changed files" mode', () => {
watch(config, pipe, argv, hasteMap, hasteContext, stdin);
runJestMock.mockReset();

stdin.emit(KEYS.O);

expect(runJestMock).toBeCalled();
expect(argv).toEqual({
'_': '',
onlyChanged: true,
watch: true,
watchAll: false,
});
});

it('Pressing "a" runs test in "watch all" mode', () => {
watch(config, pipe, argv, hasteMap, hasteContext, stdin);
runJestMock.mockReset();

stdin.emit(KEYS.A);

expect(runJestMock).toBeCalled();
expect(argv).toEqual({
'_': '',
onlyChanged: false,
watch: false,
watchAll: true,
});
});

it('Pressing "P" enters pattern mode', () => {
watch(config, pipe, argv, hasteMap, hasteContext, stdin);

// Write a enter pattern mode
stdin.emit(KEYS.P);
expect(pipe.write).toBeCalledWith(' pattern › ');

// Write a pattern
stdin.emit(KEYS.P);
stdin.emit(KEYS.O);
stdin.emit(KEYS.A);
expect(pipe.write).toBeCalledWith(' pattern › poa');

//Runs Jest again
runJestMock.mockReset();
stdin.emit(KEYS.ENTER);
expect(runJestMock).toBeCalled();

//Argv is updated with the current pattern
expect(argv).toEqual({
'_': ['poa'],
onlyChanged: false,
watch: true,
watchAll: false,
});
});

it('Pressing "ENTER" reruns the tests', () => {
watch(config, pipe, argv, hasteMap, hasteContext, stdin);
expect(runJestMock).toHaveBeenCalledTimes(1);
stdin.emit(KEYS.ENTER);
expect(runJestMock).toHaveBeenCalledTimes(2);
});

it('Pressing "u" reruns the tests in "update snapshot" mode', () => {
watch(config, pipe, argv, hasteMap, hasteContext, stdin);
runJestMock.mockReset();

stdin.emit(KEYS.U);

expect(runJestMock.mock.calls[0][1]).toEqual({updateSnapshot: true});
});
});

class MockStdin {
constructor() {
this._callbacks = [];
}

setRawMode() {}

resume() {}

setEncoding() {}

on(evt, callback) {
this._callbacks.push(callback);
}

emit(key) {
this._callbacks.forEach(cb => cb(key));
}
}
33 changes: 33 additions & 0 deletions packages/jest-cli/src/constants.js
@@ -0,0 +1,33 @@
/**
* Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*
* @flow
*/

'use strict';

const CLEAR = process.platform === 'win32' ? '\x1Bc' : '\x1B[2J\x1B[3J\x1B[H';

const KEYS = {
A: '61',
ARROW_DOWN: '1b5b42',
ARROW_LEFT: '1b5b44',
ARROW_RIGHT: '1b5b43',
ARROW_UP: '1b5b41',
BACKSPACE: process.platform === 'win32' ? '08' : '7f',
CONTROL_C: '03',
CONTROL_D: '04',
ENTER: '0d',
ESCAPE: '1b',
O: '6f',
P: '70',
Q: '71',
QUESTION_MARK: '3f',
U: '75',
};

module.exports = {CLEAR, KEYS};
36 changes: 9 additions & 27 deletions packages/jest-cli/src/watch.js
Expand Up @@ -21,33 +21,15 @@ const preRunMessage = require('./preRunMessage');
const runJest = require('./runJest');
const setWatchMode = require('./lib/setWatchMode');
const TestWatcher = require('./TestWatcher');

const CLEAR = process.platform === 'win32' ? '\x1Bc' : '\x1B[2J\x1B[3J\x1B[H';
const KEYS = {
A: '61',
ARROW_DOWN: '1b5b42',
ARROW_LEFT: '1b5b44',
ARROW_RIGHT: '1b5b43',
ARROW_UP: '1b5b41',
BACKSPACE: process.platform === 'win32' ? '08' : '7f',
CONTROL_C: '03',
CONTROL_D: '04',
ENTER: '0d',
ESCAPE: '1b',
O: '6f',
P: '70',
Q: '71',
QUESTION_MARK: '3f',
U: '75',
};

const {KEYS, CLEAR} = require('./constants');

const watch = (
config: Config,
pipe: stream$Writable | tty$WriteStream,
argv: Object,
hasteMap: HasteMap,
hasteContext: HasteContext,
stdin?: stream$Readable | tty$ReadStream = process.stdin
) => {
setWatchMode(argv, argv.watch ? 'watch' : 'watchAll', {
pattern: argv._,
Expand Down Expand Up @@ -93,7 +75,7 @@ const watch = (
// and prevent test runs from the previous run.
testWatcher = new TestWatcher({isWatchMode: true});
if (displayHelp) {
console.log(usage(argv, hasSnapshotFailure));
pipe.write(usage(argv, hasSnapshotFailure));
displayHelp = !process.env.JEST_HIDE_USAGE;
}
},
Expand Down Expand Up @@ -174,17 +156,17 @@ const watch = (
break;
case KEYS.QUESTION_MARK:
if (process.env.JEST_HIDE_USAGE) {
console.log(usage(argv, hasSnapshotFailure));
pipe.write(usage(argv, hasSnapshotFailure));
}
break;
}
};

if (typeof process.stdin.setRawMode === 'function') {
process.stdin.setRawMode(true);
process.stdin.resume();
process.stdin.setEncoding('hex');
process.stdin.on('data', onKeypress);
if (typeof stdin.setRawMode === 'function') {
stdin.setRawMode(true);
stdin.resume();
stdin.setEncoding('hex');
stdin.on('data', onKeypress);
}

startRun();
Expand Down

0 comments on commit 7909aeb

Please sign in to comment.