Skip to content

Commit

Permalink
Allow watch plugin to be configured (#6603)
Browse files Browse the repository at this point in the history
  • Loading branch information
rogeliog authored and SimenB committed Jul 3, 2018
1 parent 2208288 commit de21fd4
Show file tree
Hide file tree
Showing 8 changed files with 131 additions and 21 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

### Features

- `[jest-cli]` Allow watch plugin to be configured ([#6603](https://github.com/facebook/jest/pull/6603))
- `[jest-snapshot]` Introduce `toMatchInlineSnapshot` and `toThrowErrorMatchingInlineSnapshot` matchers ([#6380](https://github.com/facebook/jest/pull/6380))

### Fixes
Expand Down
33 changes: 33 additions & 0 deletions docs/WatchPlugins.md
Original file line number Diff line number Diff line change
Expand Up @@ -148,3 +148,36 @@ class MyWatchPlugin {
}
}
```

## Customization

Plugins can be customized via your Jest configuration.

```javascript
// jest.config.js
module.exports = {
// ...
watchPlugins: [
[
'path/to/yourWatchPlugin',
{
key: 'k', // <- your custom key
prompt: 'show a custom prompt',
},
],
],
};
```

Recommended config names:

- `key`: Modifies the plugin key.
- `prompt`: Allows user to customize the text in the plugin prompt.

If the user provided a custom configuration, it will be passed as an argument to the plugin constructor.

```javascript
class MyWatchPlugin {
constructor({config}) {}
}
```
15 changes: 15 additions & 0 deletions packages/jest-cli/src/__tests__/__snapshots__/watch.test.js.snap
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,21 @@ Watch Usage
]
`;

exports[`Watch mode flows allows WatchPlugins to be configured 1`] = `
Array [
"
Watch Usage
› Press a to run all tests.
› Press f to run only failed tests.
› Press p to filter by a filename regex pattern.
› Press t to filter by a test name regex pattern.
› Press q to quit watch mode.
› Press k to filter with a custom prompt.
› Press Enter to trigger a test run.
",
]
`;

exports[`Watch mode flows allows WatchPlugins to override internal plugins 1`] = `
Array [
"
Expand Down
61 changes: 54 additions & 7 deletions packages/jest-cli/src/__tests__/watch.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,7 @@ describe('Watch mode flows', () => {
await watch(
Object.assign({}, globalConfig, {
rootDir: __dirname,
watchPlugins: [watchPluginPath],
watchPlugins: [{config: {}, path: watchPluginPath}],
}),
contexts,
pipe,
Expand All @@ -195,7 +195,10 @@ describe('Watch mode flows', () => {
ci_watch(
Object.assign({}, globalConfig, {
rootDir: __dirname,
watchPlugins: [watchPlugin2Path, watchPluginPath],
watchPlugins: [
{config: {}, path: watchPluginPath},
{config: {}, path: watchPlugin2Path},
],
}),
contexts,
pipe,
Expand Down Expand Up @@ -302,7 +305,7 @@ describe('Watch mode flows', () => {
watch(
Object.assign({}, globalConfig, {
rootDir: __dirname,
watchPlugins: [pluginPath],
watchPlugins: [{config: {}, path: pluginPath}],
}),
contexts,
pipe,
Expand Down Expand Up @@ -338,7 +341,7 @@ describe('Watch mode flows', () => {
watch(
Object.assign({}, globalConfig, {
rootDir: __dirname,
watchPlugins: [pluginPath],
watchPlugins: [{config: {}, path: pluginPath}],
}),
contexts,
pipe,
Expand All @@ -356,6 +359,47 @@ describe('Watch mode flows', () => {
expect(run).toHaveBeenCalled();
});

it('allows WatchPlugins to be configured', async () => {
const pluginPath = `${__dirname}/__fixtures__/plugin_path_with_config`;
jest.doMock(
pluginPath,
() =>
class WatchPlugin {
constructor({config}) {
this._key = config.key;
this._prompt = config.prompt;
}
onKey() {}
run() {}
getUsageInfo() {
return {
key: this._key || 'z',
prompt: this._prompt || 'default prompt',
};
}
},
{virtual: true},
);

watch(
Object.assign({}, globalConfig, {
rootDir: __dirname,
watchPlugins: [
{
config: {key: 'k', prompt: 'filter with a custom prompt'},
path: pluginPath,
},
],
}),
contexts,
pipe,
hasteMapInstances,
stdin,
);

expect(pipe.write.mock.calls.reverse()[0]).toMatchSnapshot();
});

it('allows WatchPlugins to hook into file system changes', async () => {
const onFileChange = jest.fn();
const pluginPath = `${__dirname}/__fixtures__/plugin_path_fs_change`;
Expand All @@ -373,7 +417,7 @@ describe('Watch mode flows', () => {
watch(
Object.assign({}, globalConfig, {
rootDir: __dirname,
watchPlugins: [pluginPath],
watchPlugins: [{config: {}, path: pluginPath}],
}),
contexts,
pipe,
Expand Down Expand Up @@ -414,7 +458,7 @@ describe('Watch mode flows', () => {
watch(
Object.assign({}, globalConfig, {
rootDir: __dirname,
watchPlugins: [pluginPath],
watchPlugins: [{config: {}, path: pluginPath}],
}),
contexts,
pipe,
Expand Down Expand Up @@ -474,7 +518,10 @@ describe('Watch mode flows', () => {
watch(
Object.assign({}, globalConfig, {
rootDir: __dirname,
watchPlugins: [pluginPath, pluginPath2],
watchPlugins: [
{config: {}, path: pluginPath},
{config: {}, path: pluginPath2},
],
}),
contexts,
pipe,
Expand Down
6 changes: 3 additions & 3 deletions packages/jest-cli/src/watch.js
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,6 @@ export default function watch(
const watchPlugins: Array<WatchPlugin> = INTERNAL_PLUGINS.map(
InternalPlugin => new InternalPlugin({stdin, stdout: outputStream}),
);

watchPlugins.forEach((plugin: WatchPlugin) => {
const hookSubscriber = hooks.getSubscriber();
if (plugin.apply) {
Expand All @@ -115,10 +114,11 @@ export default function watch(
});

if (globalConfig.watchPlugins != null) {
for (const pluginModulePath of globalConfig.watchPlugins) {
for (const pluginWithConfig of globalConfig.watchPlugins) {
// $FlowFixMe dynamic require
const ThirdPartyPlugin = require(pluginModulePath);
const ThirdPartyPlugin = require(pluginWithConfig.path);
const plugin: WatchPlugin = new ThirdPartyPlugin({
config: pluginWithConfig.config,
stdin,
stdout: outputStream,
});
Expand Down
4 changes: 2 additions & 2 deletions packages/jest-config/src/__tests__/normalize.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -1127,8 +1127,8 @@ describe('watchPlugins', () => {
);

expect(options.watchPlugins).toEqual([
'/node_modules/my-watch-plugin',
'/root/path/to/plugin',
{config: {}, path: '/node_modules/my-watch-plugin'},
{config: {}, path: '/root/path/to/plugin'},
]);
});
});
Expand Down
28 changes: 21 additions & 7 deletions packages/jest-config/src/normalize.js
Original file line number Diff line number Diff line change
Expand Up @@ -579,13 +579,27 @@ export default function normalize(options: InitialOptions, argv: Argv) {
value = options[key];
break;
case 'watchPlugins':
value = (options[key] || []).map(watchPlugin =>
resolve(newOptions.resolver, {
filePath: watchPlugin,
key,
rootDir: options.rootDir,
}),
);
value = (options[key] || []).map(watchPlugin => {
if (typeof watchPlugin === 'string') {
return {
config: {},
path: resolve(newOptions.resolver, {
filePath: watchPlugin,
key,
rootDir: options.rootDir,
}),
};
} else {
return {
config: watchPlugin[1] || {},
path: resolve(newOptions.resolver, {
filePath: watchPlugin[0],
key,
rootDir: options.rootDir,
}),
};
}
});
break;
}
newOptions[key] = value;
Expand Down
4 changes: 2 additions & 2 deletions types/Config.js
Original file line number Diff line number Diff line change
Expand Up @@ -178,7 +178,7 @@ export type InitialOptions = {
watch?: boolean,
watchAll?: boolean,
watchman?: boolean,
watchPlugins?: Array<string>,
watchPlugins?: Array<string | [string, Object]>,
};

export type SnapshotUpdateState = 'all' | 'new' | 'none';
Expand Down Expand Up @@ -235,7 +235,7 @@ export type GlobalConfig = {|
watch: boolean,
watchAll: boolean,
watchman: boolean,
watchPlugins: ?Array<string>,
watchPlugins: ?Array<{path: string, config: Object}>,
|};

export type ProjectConfig = {|
Expand Down

0 comments on commit de21fd4

Please sign in to comment.