From 12684451db1ab037eafedba49aab35f87f9c5b87 Mon Sep 17 00:00:00 2001 From: Rogelio Guzman Date: Thu, 31 May 2018 17:10:03 -0700 Subject: [PATCH 1/7] Config watch plugin --- .../__snapshots__/watch.test.js.snap | 15 +++++ packages/jest-cli/src/__tests__/watch.test.js | 58 ++++++++++++++++--- packages/jest-cli/src/watch.js | 6 +- packages/jest-config/src/normalize.js | 28 ++++++--- types/Config.js | 4 +- 5 files changed, 92 insertions(+), 19 deletions(-) diff --git a/packages/jest-cli/src/__tests__/__snapshots__/watch.test.js.snap b/packages/jest-cli/src/__tests__/__snapshots__/watch.test.js.snap index 38f4a2d573ad..ab823b378aac 100644 --- a/packages/jest-cli/src/__tests__/__snapshots__/watch.test.js.snap +++ b/packages/jest-cli/src/__tests__/__snapshots__/watch.test.js.snap @@ -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 configured prompt. + › Press Enter to trigger a test run. +", +] +`; + exports[`Watch mode flows allows WatchPlugins to override internal plugins 1`] = ` Array [ " diff --git a/packages/jest-cli/src/__tests__/watch.test.js b/packages/jest-cli/src/__tests__/watch.test.js index 7b374b2f07b5..7c29bda06ba5 100644 --- a/packages/jest-cli/src/__tests__/watch.test.js +++ b/packages/jest-cli/src/__tests__/watch.test.js @@ -176,7 +176,7 @@ describe('Watch mode flows', () => { await watch( Object.assign({}, globalConfig, { rootDir: __dirname, - watchPlugins: [watchPluginPath], + watchPlugins: [{config: {}, path: watchPluginPath}], }), contexts, pipe, @@ -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, @@ -302,7 +305,7 @@ describe('Watch mode flows', () => { watch( Object.assign({}, globalConfig, { rootDir: __dirname, - watchPlugins: [pluginPath], + watchPlugins: [{config: {}, path: pluginPath}], }), contexts, pipe, @@ -338,7 +341,7 @@ describe('Watch mode flows', () => { watch( Object.assign({}, globalConfig, { rootDir: __dirname, - watchPlugins: [pluginPath], + watchPlugins: [{config: {}, path: pluginPath}], }), contexts, pipe, @@ -356,6 +359,44 @@ 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: 'configured 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`; @@ -373,7 +414,7 @@ describe('Watch mode flows', () => { watch( Object.assign({}, globalConfig, { rootDir: __dirname, - watchPlugins: [pluginPath], + watchPlugins: [{config: {}, path: pluginPath}], }), contexts, pipe, @@ -414,7 +455,7 @@ describe('Watch mode flows', () => { watch( Object.assign({}, globalConfig, { rootDir: __dirname, - watchPlugins: [pluginPath], + watchPlugins: [{config: {}, path: pluginPath}], }), contexts, pipe, @@ -474,7 +515,10 @@ describe('Watch mode flows', () => { watch( Object.assign({}, globalConfig, { rootDir: __dirname, - watchPlugins: [pluginPath, pluginPath2], + watchPlugins: [ + {config: {}, path: pluginPath}, + {config: {}, path: pluginPath2}, + ], }), contexts, pipe, diff --git a/packages/jest-cli/src/watch.js b/packages/jest-cli/src/watch.js index e6ae3d1cb081..0a0c71f32d0b 100644 --- a/packages/jest-cli/src/watch.js +++ b/packages/jest-cli/src/watch.js @@ -106,7 +106,6 @@ export default function watch( const watchPlugins: Array = INTERNAL_PLUGINS.map( InternalPlugin => new InternalPlugin({stdin, stdout: outputStream}), ); - watchPlugins.forEach((plugin: WatchPlugin) => { const hookSubscriber = hooks.getSubscriber(); if (plugin.apply) { @@ -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, }); diff --git a/packages/jest-config/src/normalize.js b/packages/jest-config/src/normalize.js index 769874db3c48..6863022e0870 100644 --- a/packages/jest-config/src/normalize.js +++ b/packages/jest-config/src/normalize.js @@ -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; diff --git a/types/Config.js b/types/Config.js index 29c1bf891188..2c8932310c7a 100644 --- a/types/Config.js +++ b/types/Config.js @@ -178,7 +178,7 @@ export type InitialOptions = { watch?: boolean, watchAll?: boolean, watchman?: boolean, - watchPlugins?: Array, + watchPlugins?: Array, }; export type SnapshotUpdateState = 'all' | 'new' | 'none'; @@ -235,7 +235,7 @@ export type GlobalConfig = {| watch: boolean, watchAll: boolean, watchman: boolean, - watchPlugins: ?Array, + watchPlugins: ?Array, |}; export type ProjectConfig = {| From e3760656ee3abb71d108700903865bf9bdaf6a76 Mon Sep 17 00:00:00 2001 From: Rogelio Guzman Date: Mon, 2 Jul 2018 21:04:47 -0700 Subject: [PATCH 2/7] Update changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 39021d60caf7..6b3354026a67 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -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)) ### Chore & Maintenance From b35e82008c743d79553e9b77e0914baf89d3f21e Mon Sep 17 00:00:00 2001 From: Rogelio Guzman Date: Mon, 2 Jul 2018 21:54:34 -0700 Subject: [PATCH 3/7] Fix test and change snapshot text for custom prompts --- .../jest-cli/src/__tests__/__snapshots__/watch.test.js.snap | 2 +- packages/jest-cli/src/__tests__/watch.test.js | 5 ++++- packages/jest-config/src/__tests__/normalize.test.js | 4 ++-- 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/packages/jest-cli/src/__tests__/__snapshots__/watch.test.js.snap b/packages/jest-cli/src/__tests__/__snapshots__/watch.test.js.snap index ab823b378aac..88ce3867a970 100644 --- a/packages/jest-cli/src/__tests__/__snapshots__/watch.test.js.snap +++ b/packages/jest-cli/src/__tests__/__snapshots__/watch.test.js.snap @@ -30,7 +30,7 @@ Watch Usage › 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 configured prompt. + › Press k to filter with a custom prompt. › Press Enter to trigger a test run. ", ] diff --git a/packages/jest-cli/src/__tests__/watch.test.js b/packages/jest-cli/src/__tests__/watch.test.js index 7c29bda06ba5..0107973cbd31 100644 --- a/packages/jest-cli/src/__tests__/watch.test.js +++ b/packages/jest-cli/src/__tests__/watch.test.js @@ -385,7 +385,10 @@ describe('Watch mode flows', () => { Object.assign({}, globalConfig, { rootDir: __dirname, watchPlugins: [ - {config: {key: 'k', prompt: 'configured prompt'}, path: pluginPath}, + { + config: {key: 'k', prompt: 'filter with a custom prompt'}, + path: pluginPath, + }, ], }), contexts, diff --git a/packages/jest-config/src/__tests__/normalize.test.js b/packages/jest-config/src/__tests__/normalize.test.js index bc2b5a759231..a1f0f610ec4c 100644 --- a/packages/jest-config/src/__tests__/normalize.test.js +++ b/packages/jest-config/src/__tests__/normalize.test.js @@ -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'}, ]); }); }); From 28267ffcb6226d4a02db49220b0bc38dc3cf4082 Mon Sep 17 00:00:00 2001 From: Rogelio Guzman Date: Mon, 2 Jul 2018 21:59:30 -0700 Subject: [PATCH 4/7] Fix Flow --- types/Config.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/types/Config.js b/types/Config.js index 2c8932310c7a..4d4abf994e6f 100644 --- a/types/Config.js +++ b/types/Config.js @@ -235,7 +235,7 @@ export type GlobalConfig = {| watch: boolean, watchAll: boolean, watchman: boolean, - watchPlugins: ?Array, + watchPlugins: ?Array<{path: string, config: Object}>, |}; export type ProjectConfig = {| From 66eecf2baa4d28feb7b67f96e36cf66231ce6ba2 Mon Sep 17 00:00:00 2001 From: Rogelio Guzman Date: Mon, 2 Jul 2018 22:32:18 -0700 Subject: [PATCH 5/7] Add docs --- .../version-23.0/WatchPlugins.md | 32 +++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/website/versioned_docs/version-23.0/WatchPlugins.md b/website/versioned_docs/version-23.0/WatchPlugins.md index c2bad1742624..b59dde21f044 100644 --- a/website/versioned_docs/version-23.0/WatchPlugins.md +++ b/website/versioned_docs/version-23.0/WatchPlugins.md @@ -148,3 +148,35 @@ 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 }) { + } +} +``` \ No newline at end of file From 05997af86095d11b5f4ee96d81c59dec9c4a2f07 Mon Sep 17 00:00:00 2001 From: Simen Bekkhus Date: Tue, 3 Jul 2018 18:18:16 +0200 Subject: [PATCH 6/7] move docs --- docs/WatchPlugins.md | 32 +++++++++++++++++++ .../version-23.0/WatchPlugins.md | 32 ------------------- 2 files changed, 32 insertions(+), 32 deletions(-) diff --git a/docs/WatchPlugins.md b/docs/WatchPlugins.md index 8536bda66afa..61593b420def 100644 --- a/docs/WatchPlugins.md +++ b/docs/WatchPlugins.md @@ -148,3 +148,35 @@ 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 }) { + } +} +``` diff --git a/website/versioned_docs/version-23.0/WatchPlugins.md b/website/versioned_docs/version-23.0/WatchPlugins.md index b59dde21f044..c2bad1742624 100644 --- a/website/versioned_docs/version-23.0/WatchPlugins.md +++ b/website/versioned_docs/version-23.0/WatchPlugins.md @@ -148,35 +148,3 @@ 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 }) { - } -} -``` \ No newline at end of file From e9197fc71c9d20a3b6bd0322d385be05018df4f2 Mon Sep 17 00:00:00 2001 From: Simen Bekkhus Date: Tue, 3 Jul 2018 18:19:37 +0200 Subject: [PATCH 7/7] fix lint errors in docs --- docs/WatchPlugins.md | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/docs/WatchPlugins.md b/docs/WatchPlugins.md index 61593b420def..7e731cdb53fc 100644 --- a/docs/WatchPlugins.md +++ b/docs/WatchPlugins.md @@ -152,6 +152,7 @@ class MyWatchPlugin { ## Customization Plugins can be customized via your Jest configuration. + ```javascript // jest.config.js module.exports = { @@ -160,15 +161,16 @@ module.exports = { [ 'path/to/yourWatchPlugin', { - key: 'k' // <- your custom key + 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. @@ -176,7 +178,6 @@ If the user provided a custom configuration, it will be passed as an argument to ```javascript class MyWatchPlugin { - constructor({ config }) { - } + constructor({config}) {} } ```