Skip to content

Commit

Permalink
feat: add jest-watch package (#6318)
Browse files Browse the repository at this point in the history
* feat: add jest-watch package

* cleanup constants

* lint
  • Loading branch information
SimenB authored and cpojer committed May 28, 2018
1 parent 0d9e8b1 commit 7c78f3d
Show file tree
Hide file tree
Showing 38 changed files with 235 additions and 184 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
## master

### Features

* `[jest-watch]` create new package `jest-watch` to ease custom watch plugin development ([#6318](https://github.com/facebook/jest/pull/6318))

### Fixes

* `[expect]` toMatchObject throws TypeError when a source property is null ([#6313](https://github.com/facebook/jest/pull/6313))
Expand Down
1 change: 1 addition & 0 deletions packages/jest-cli/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
"jest-snapshot": "^23.0.1",
"jest-util": "^23.0.1",
"jest-validate": "^23.0.1",
"jest-watch": "^23.0.1",
"jest-worker": "^23.0.1",
"micromatch": "^2.3.11",
"node-notifier": "^5.2.1",
Expand Down
43 changes: 18 additions & 25 deletions packages/jest-cli/src/__tests__/snapshot_interactive_mode.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,9 @@
*/

import chalk from 'chalk';
import {KEYS} from '../constants';
import {KEYS} from 'jest-watch';
import SnapshotInteractiveMode from '../snapshot_interactive_mode';

jest.mock('../lib/terminal_utils', () => ({
getTerminalWidth: () => 80,
rightPad: () => {
'';
},
}));

jest.mock('ansi-escapes', () => ({
clearScreen: '[MOCK - eraseDown]',
cursorRestorePosition: '[MOCK - cursorRestorePosition]',
Expand Down Expand Up @@ -86,7 +79,7 @@ describe('SnapshotInteractiveMode', () => {

test('press Q or ESC triggers an abort', () => {
instance.abort = jest.fn();
instance.put(KEYS.Q);
instance.put('q');
instance.put(KEYS.ESCAPE);
expect(instance.abort).toHaveBeenCalledTimes(2);
});
Expand All @@ -107,12 +100,12 @@ describe('SnapshotInteractiveMode', () => {
expect(pipe.write.mock.calls.join('\n')).toMatchSnapshot();
pipe.write.mockClear();

instance.put(KEYS.S);
instance.put('s');
expect(mockCallback).toHaveBeenCalledTimes(1);
expect(pipe.write.mock.calls.join('\n')).toMatchSnapshot();
pipe.write.mockClear();

instance.put(KEYS.R);
instance.put('r');
expect(instance.getSkippedNum()).toBe(0);
expect(mockCallback).nthCalledWith(2, assertions[0], false);
expect(mockCallback).toHaveBeenCalledTimes(2);
Expand All @@ -127,12 +120,12 @@ describe('SnapshotInteractiveMode', () => {
expect(pipe.write.mock.calls.join('\n')).toMatchSnapshot();
pipe.write.mockClear();

instance.put(KEYS.S);
instance.put('s');
expect(mockCallback).toHaveBeenCalledTimes(1);
expect(pipe.write.mock.calls.join('\n')).toMatchSnapshot();
pipe.write.mockClear();

instance.put(KEYS.Q);
instance.put('q');
expect(instance.getSkippedNum()).toBe(0);
expect(mockCallback).nthCalledWith(2, null, false);
expect(mockCallback).toHaveBeenCalledTimes(2);
Expand All @@ -157,7 +150,7 @@ describe('SnapshotInteractiveMode', () => {
expect(pipe.write.mock.calls.join('\n')).toMatchSnapshot();
pipe.write.mockClear();

instance.put(KEYS.U);
instance.put('u');
expect(mockCallback).nthCalledWith(2, assertions[0], true);
expect(mockCallback).toHaveBeenCalledTimes(2);
expect(pipe.write.mock.calls.join('\n')).toMatchSnapshot();
Expand All @@ -177,18 +170,18 @@ describe('SnapshotInteractiveMode', () => {
expect(pipe.write.mock.calls.join('\n')).toMatchSnapshot();
pipe.write.mockClear();

instance.put(KEYS.S);
instance.put('s');
expect(mockCallback).nthCalledWith(2, assertions[1], false);
expect(mockCallback).toHaveBeenCalledTimes(2);
expect(pipe.write.mock.calls.join('\n')).toMatchSnapshot();
pipe.write.mockClear();

instance.put(KEYS.S);
instance.put('s');
expect(mockCallback).toHaveBeenCalledTimes(2);
expect(pipe.write.mock.calls.join('\n')).toMatchSnapshot();
pipe.write.mockClear();

instance.put(KEYS.R);
instance.put('r');
expect(instance.getSkippedNum()).toBe(0);
expect(mockCallback).nthCalledWith(3, assertions[0], false);
expect(mockCallback).toHaveBeenCalledTimes(3);
Expand Down Expand Up @@ -224,14 +217,14 @@ describe('SnapshotInteractiveMode', () => {
expect(pipe.write.mock.calls.join('\n')).toMatchSnapshot();
pipe.write.mockClear();

instance.put(KEYS.U);
instance.put('u');
expect(mockCallback).nthCalledWith(2, assertions[0], true);
expect(mockCallback).nthCalledWith(3, assertions[1], false);
expect(mockCallback).toHaveBeenCalledTimes(3);
expect(pipe.write.mock.calls.join('\n')).toMatchSnapshot();
pipe.write.mockClear();

instance.put(KEYS.U);
instance.put('u');
expect(mockCallback).nthCalledWith(4, assertions[1], true);
expect(mockCallback).toHaveBeenCalledTimes(4);
expect(pipe.write.mock.calls.join('\n')).toMatchSnapshot();
Expand Down Expand Up @@ -272,19 +265,19 @@ describe('SnapshotInteractiveMode', () => {
expect(pipe.write.mock.calls.join('\n')).toMatchSnapshot();
pipe.write.mockClear();

instance.put(KEYS.U);
instance.put('u');
expect(mockCallback).nthCalledWith(2, assertions[0], true);
expect(mockCallback).nthCalledWith(3, assertions[1], false);
expect(mockCallback).toHaveBeenCalledTimes(3);
expect(pipe.write.mock.calls.join('\n')).toMatchSnapshot();
pipe.write.mockClear();

instance.put(KEYS.S);
instance.put('s');
expect(mockCallback).toHaveBeenCalledTimes(3);
expect(pipe.write.mock.calls.join('\n')).toMatchSnapshot();
pipe.write.mockClear();

instance.put(KEYS.R);
instance.put('r');
expect(instance.getSkippedNum()).toBe(0);
expect(mockCallback).nthCalledWith(4, assertions[1], false);
expect(mockCallback).toHaveBeenCalledTimes(4);
Expand Down Expand Up @@ -320,19 +313,19 @@ describe('SnapshotInteractiveMode', () => {
expect(pipe.write.mock.calls.join('\n')).toMatchSnapshot();
pipe.write.mockClear();

instance.put(KEYS.S);
instance.put('s');
expect(mockCallback).nthCalledWith(2, assertions[1], false);
expect(mockCallback).toHaveBeenCalledTimes(2);
expect(pipe.write.mock.calls.join('\n')).toMatchSnapshot();
pipe.write.mockClear();

instance.put(KEYS.U);
instance.put('u');
expect(mockCallback).nthCalledWith(3, assertions[1], true);
expect(mockCallback).toHaveBeenCalledTimes(3);
expect(pipe.write.mock.calls.join('\n')).toMatchSnapshot();
pipe.write.mockClear();

instance.put(KEYS.R);
instance.put('r');
expect(instance.getSkippedNum()).toBe(0);
expect(mockCallback).nthCalledWith(4, assertions[0], false);
expect(mockCallback).toHaveBeenCalledTimes(4);
Expand Down
37 changes: 18 additions & 19 deletions packages/jest-cli/src/__tests__/watch.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,7 @@

import chalk from 'chalk';
import TestWatcher from '../test_watcher';
import JestHooks from '../jest_hooks';
import {KEYS} from '../constants';
import {JestHook, KEYS} from 'jest-watch';

const runJestMock = jest.fn();
const watchPluginPath = `${__dirname}/__fixtures__/watch_plugin`;
Expand Down Expand Up @@ -286,7 +285,7 @@ describe('Watch mode flows', () => {
expect(pipeMockCalls.slice(determiningTestsToRun + 1)).toMatchSnapshot();
});

it('allows WatchPlugins to hook into JestHooks', async () => {
it('allows WatchPlugins to hook into JestHook', async () => {
const apply = jest.fn();
const pluginPath = `${__dirname}/__fixtures__/plugin_path_register`;
jest.doMock(
Expand Down Expand Up @@ -498,7 +497,7 @@ describe('Watch mode flows', () => {
watch(globalConfig, contexts, pipe, hasteMapInstances, stdin);
runJestMock.mockReset();

stdin.emit(KEYS.O);
stdin.emit('o');

expect(runJestMock).toBeCalled();
expect(runJestMock.mock.calls[0][0].globalConfig).toMatchObject({
Expand All @@ -512,7 +511,7 @@ describe('Watch mode flows', () => {
watch(globalConfig, contexts, pipe, hasteMapInstances, stdin);
runJestMock.mockReset();

stdin.emit(KEYS.A);
stdin.emit('a');

expect(runJestMock).toBeCalled();
expect(runJestMock.mock.calls[0][0].globalConfig).toMatchObject({
Expand All @@ -530,12 +529,12 @@ describe('Watch mode flows', () => {
});

it('Pressing "t" reruns the tests in "test name pattern" mode', async () => {
const hooks = new JestHooks();
const hooks = new JestHook();

watch(globalConfig, contexts, pipe, hasteMapInstances, stdin, hooks);
runJestMock.mockReset();

stdin.emit(KEYS.T);
stdin.emit('t');
['t', 'e', 's', 't'].forEach(key => stdin.emit(key));
stdin.emit(KEYS.ENTER);
await nextTick();
Expand All @@ -549,12 +548,12 @@ describe('Watch mode flows', () => {
});

it('Pressing "p" reruns the tests in "filename pattern" mode', async () => {
const hooks = new JestHooks();
const hooks = new JestHook();

watch(globalConfig, contexts, pipe, hasteMapInstances, stdin, hooks);
runJestMock.mockReset();

stdin.emit(KEYS.P);
stdin.emit('p');
['f', 'i', 'l', 'e'].forEach(key => stdin.emit(key));
stdin.emit(KEYS.ENTER);
await nextTick();
Expand All @@ -568,17 +567,17 @@ describe('Watch mode flows', () => {
});

it('Can combine "p" and "t" filters', async () => {
const hooks = new JestHooks();
const hooks = new JestHook();

watch(globalConfig, contexts, pipe, hasteMapInstances, stdin, hooks);
runJestMock.mockReset();

stdin.emit(KEYS.P);
stdin.emit('p');
['f', 'i', 'l', 'e'].forEach(key => stdin.emit(key));
stdin.emit(KEYS.ENTER);
await nextTick();

stdin.emit(KEYS.T);
stdin.emit('t');
['t', 'e', 's', 't'].forEach(key => stdin.emit(key));
stdin.emit(KEYS.ENTER);
await nextTick();
Expand All @@ -592,7 +591,7 @@ describe('Watch mode flows', () => {
});

it('Pressing "u" reruns the tests in "update snapshot" mode', async () => {
const hooks = new JestHooks();
const hooks = new JestHook();

globalConfig.updateSnapshot = 'new';

Expand All @@ -601,7 +600,7 @@ describe('Watch mode flows', () => {

hooks.getEmitter().onTestRunComplete({snapshot: {failure: true}});

stdin.emit(KEYS.U);
stdin.emit('u');
await nextTick();

expect(runJestMock.mock.calls[0][0].globalConfig).toMatchObject({
Expand All @@ -610,7 +609,7 @@ describe('Watch mode flows', () => {
watchAll: false,
});

stdin.emit(KEYS.A);
stdin.emit('a');

await nextTick();
// updateSnapshot is not sticky after a run.
Expand All @@ -622,11 +621,11 @@ describe('Watch mode flows', () => {

results = {snapshot: {failure: true}};

stdin.emit(KEYS.A);
stdin.emit('a');
await nextTick();

runJestMock.mockReset();
stdin.emit(KEYS.U);
stdin.emit('u');
await nextTick();

expect(runJestMock.mock.calls[0][0].globalConfig).toMatchObject({
Expand All @@ -652,8 +651,8 @@ describe('Watch mode flows', () => {
const ci_watch = require('../watch').default;
ci_watch(globalConfig, contexts, pipe, hasteMapInstances, stdin);

stdin.emit(KEYS.F);
stdin.emit(KEYS.W);
stdin.emit('f');
stdin.emit('w');

const lastWatchDisplay = pipe.write.mock.calls.reverse()[0][0];
expect(lastWatchDisplay).toMatch('Press a to run all tests.');
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,10 @@
'use strict';

import chalk from 'chalk';
import {KEYS} from '../constants';
import {KEYS} from 'jest-watch';

const runJestMock = jest.fn();

let terminalWidth;

jest.mock('ansi-escapes', () => ({
clearScreen: '[MOCK - clearScreen]',
cursorDown: (count = 1) => `[MOCK - cursorDown(${count})]`,
Expand Down Expand Up @@ -79,10 +77,6 @@ jest.doMock(
},
);

jest.doMock('../lib/terminal_utils', () => ({
getTerminalWidth: () => terminalWidth,
}));

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

const nextTick = () => new Promise(res => process.nextTick(res));
Expand All @@ -98,7 +92,6 @@ describe('Watch mode flows', () => {
let stdin;

beforeEach(() => {
terminalWidth = 80;
pipe = {write: jest.fn()};
hasteMapInstances = [{on: () => {}}];
contexts = [{config: {}}];
Expand All @@ -110,7 +103,7 @@ describe('Watch mode flows', () => {
watch(globalConfig, contexts, pipe, hasteMapInstances, stdin);

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

const assertPattern = hex => {
Expand Down Expand Up @@ -146,26 +139,26 @@ describe('Watch mode flows', () => {
contexts[0].config = {rootDir: ''};
watch(globalConfig, contexts, pipe, hasteMapInstances, stdin);

stdin.emit(KEYS.P);
stdin.emit('p');
await nextTick();

['p', '.', '*', '1', '0']

.concat(KEYS.ENTER)
.forEach(key => stdin.emit(key));

stdin.emit(KEYS.T);
stdin.emit('t');
await nextTick();

['t', 'e', 's', 't'].concat(KEYS.ENTER).forEach(key => stdin.emit(key));

await nextTick();

stdin.emit(KEYS.C);
stdin.emit('c');
await nextTick();

pipe.write.mockReset();
stdin.emit(KEYS.P);
stdin.emit('p');
await nextTick();

expect(pipe.write.mock.calls.join('\n')).toMatchSnapshot();
Expand Down
Loading

0 comments on commit 7c78f3d

Please sign in to comment.