From c2c23f020a892a4cc3b811c762e36caa824672c6 Mon Sep 17 00:00:00 2001 From: Jamie Treworgy Date: Thu, 18 Oct 2018 14:20:53 -0400 Subject: [PATCH 1/5] Allow array of regexp strings for testRegex --- .vscode/settings.json | 6 ++- CHANGELOG.md | 1 + TestUtils.js | 2 +- docs/Configuration.md | 6 +-- .../__snapshots__/show_config.test.js.snap | 2 +- packages/jest-cli/src/SearchSource.js | 9 ++--- .../src/__tests__/runJestWithCoverage.test.js | 2 +- packages/jest-cli/src/__tests__/watch.test.js | 2 +- packages/jest-cli/src/cli/args.js | 5 ++- .../__tests__/__snapshots__/init.test.js.snap | 4 +- packages/jest-config/src/Defaults.js | 2 +- packages/jest-config/src/Descriptions.js | 3 +- packages/jest-config/src/ValidConfig.js | 6 ++- .../src/__tests__/normalize.test.js | 38 ++++++++++++++++++- packages/jest-config/src/normalize.js | 10 +++-- packages/jest-editor-support/src/Settings.js | 4 +- .../src/__tests__/should_instrument.test.js | 18 +++++++-- .../jest-runtime/src/should_instrument.js | 5 ++- packages/jest-validate/src/condition.js | 2 +- types/Argv.js | 2 +- types/Config.js | 6 +-- 21 files changed, 99 insertions(+), 36 deletions(-) diff --git a/.vscode/settings.json b/.vscode/settings.json index c4951686b125..0b867bdd9628 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,11 +1,13 @@ { - "editor.rulers": [80], + "editor.rulers": [ + 80 + ], "files.exclude": { "**/.git": true, "**/node_modules": true, "**/build": true }, - "editor.formatOnSave": true, + "editor.formatOnSave": false, "flow.useNPMPackagedFlow": true, "javascript.validate.enable": false, "jest.pathToJest": "yarn jest --", diff --git a/CHANGELOG.md b/CHANGELOG.md index 5bec3ba38444..bea61eba8b7a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,6 +16,7 @@ - `[jest-haste-map]` Make `ignorePattern` optional ([#7166](https://github.com/facebook/jest/pull/7166)) - `[jest-runtime]` Remove `cacheDirectory` from `ignorePattern` for `HasteMap` if not necessary ([#7166](https://github.com/facebook/jest/pull/7166)) - `[jest-validate]` Add syntax to validate multiple permitted types ([#7207](https://github.com/facebook/jest/pull/7207)) +- `[jest-config]` Accept an array as as well as a string for `testRegex` ### Fixes diff --git a/TestUtils.js b/TestUtils.js index 3cd6e43ecb3e..c179cc13a9de 100644 --- a/TestUtils.js +++ b/TestUtils.js @@ -109,7 +109,7 @@ const DEFAULT_PROJECT_CONFIG: ProjectConfig = { testLocationInResults: false, testMatch: [], testPathIgnorePatterns: [], - testRegex: '.test.js$', + testRegex: ['.test.js$'], testRunner: 'jest-jasmine2', testURL: '', timers: 'real', diff --git a/docs/Configuration.md b/docs/Configuration.md index 4cb938e87af2..bef4ec88cbbd 100644 --- a/docs/Configuration.md +++ b/docs/Configuration.md @@ -804,7 +804,7 @@ The glob patterns Jest uses to detect test files. By default it looks for `.js` See the [micromatch](https://github.com/jonschlinkert/micromatch) package for details of the patterns you can specify. -See also [`testRegex` [string]](#testregex-string), but note that you cannot specify both options. +See also [`testRegex` [string | Array]](#testregex-string), but note that you cannot specify both options. ### `testPathIgnorePatterns` [array] @@ -814,11 +814,11 @@ An array of regexp pattern strings that are matched against all test paths befor These pattern strings match against the full path. Use the `` string token to include the path to your project's root directory to prevent it from accidentally ignoring all of your files in different environments that may have different root directories. Example: `["/build/", "/node_modules/"]`. -### `testRegex` [string] +### `testRegex` [string | Array] Default: `(/__tests__/.*|(\\.|/)(test|spec))\\.jsx?$` -The pattern Jest uses to detect test files. By default it looks for `.js` and `.jsx` files inside of `__tests__` folders, as well as any files with a suffix of `.test` or `.spec` (e.g. `Component.test.js` or `Component.spec.js`). It will also find files called `test.js` or `spec.js`. See also [`testMatch` [array]](#testmatch-array-string), but note that you cannot specify both options. +The pattern or patterns Jest uses to detect test files. By default it looks for `.js` and `.jsx` files inside of `__tests__` folders, as well as any files with a suffix of `.test` or `.spec` (e.g. `Component.test.js` or `Component.spec.js`). It will also find files called `test.js` or `spec.js`. See also [`testMatch` [array]](#testmatch-array-string), but note that you cannot specify both options. The following is a visualization of the default regex: diff --git a/e2e/__tests__/__snapshots__/show_config.test.js.snap b/e2e/__tests__/__snapshots__/show_config.test.js.snap index 64bb26ca8e28..2e4b59ee8531 100644 --- a/e2e/__tests__/__snapshots__/show_config.test.js.snap +++ b/e2e/__tests__/__snapshots__/show_config.test.js.snap @@ -58,7 +58,7 @@ exports[`--showConfig outputs config info and exits 1`] = ` \\"testPathIgnorePatterns\\": [ \\"/node_modules/\\" ], - \\"testRegex\\": \\"\\", + \\"testRegex\\": [], \\"testRunner\\": \\"<>/jest-jasmine2/build/index.js\\", \\"testURL\\": \\"http://localhost\\", \\"timers\\": \\"real\\", diff --git a/packages/jest-cli/src/SearchSource.js b/packages/jest-cli/src/SearchSource.js index 020425067b5a..91c93e1d2ac5 100644 --- a/packages/jest-cli/src/SearchSource.js +++ b/packages/jest-cli/src/SearchSource.js @@ -51,13 +51,12 @@ const globsToMatcher = (globs: ?Array) => { return path => micromatch([path], globs, {dot: true}).length > 0; }; -const regexToMatcher = (testRegex: string) => { - if (!testRegex) { +const regexToMatcher = (testRegex: Array) => { + if (!testRegex.length) { return () => true; } - - const regex = new RegExp(testRegex); - return path => regex.test(path); + const testRegexParsed = testRegex.map(e => new RegExp(e)); + return path => testRegexParsed.some(e => e.test(path)); }; const toTests = (context, tests) => diff --git a/packages/jest-cli/src/__tests__/runJestWithCoverage.test.js b/packages/jest-cli/src/__tests__/runJestWithCoverage.test.js index 4081497655ba..247fcf2c7b11 100644 --- a/packages/jest-cli/src/__tests__/runJestWithCoverage.test.js +++ b/packages/jest-cli/src/__tests__/runJestWithCoverage.test.js @@ -51,7 +51,7 @@ jest.mock( }, ); -const config = {roots: [], testPathIgnorePatterns: [], testRegex: ''}; +const config = {roots: [], testPathIgnorePatterns: [], testRegex: []}; let globalConfig; const defaults = { changedFilesPromise: Promise.resolve({ diff --git a/packages/jest-cli/src/__tests__/watch.test.js b/packages/jest-cli/src/__tests__/watch.test.js index 3607381f684d..4acc234db99e 100644 --- a/packages/jest-cli/src/__tests__/watch.test.js +++ b/packages/jest-cli/src/__tests__/watch.test.js @@ -105,7 +105,7 @@ describe('Watch mode flows', () => { let stdin; beforeEach(() => { - const config = {roots: [], testPathIgnorePatterns: [], testRegex: ''}; + const config = {roots: [], testPathIgnorePatterns: [], testRegex: []}; pipe = {write: jest.fn()}; globalConfig = {watch: true}; hasteMapInstances = [{on: () => {}}]; diff --git a/packages/jest-cli/src/cli/args.js b/packages/jest-cli/src/cli/args.js index c758ff14e56e..b374adeba2ef 100644 --- a/packages/jest-cli/src/cli/args.js +++ b/packages/jest-cli/src/cli/args.js @@ -576,8 +576,9 @@ export const options = { type: 'array', }, testRegex: { - description: 'The regexp pattern Jest uses to detect test files.', - type: 'string', + description: + 'A string or array of string regexp patterns that Jest uses to detect test files.', + type: 'array', }, testResultsProcessor: { description: diff --git a/packages/jest-cli/src/lib/__tests__/__snapshots__/init.test.js.snap b/packages/jest-cli/src/lib/__tests__/__snapshots__/init.test.js.snap index adf63d20d15c..9ec33fc8447b 100644 --- a/packages/jest-cli/src/lib/__tests__/__snapshots__/init.test.js.snap +++ b/packages/jest-cli/src/lib/__tests__/__snapshots__/init.test.js.snap @@ -164,8 +164,8 @@ module.exports = { // \\"/node_modules/\\" // ], - // The regexp pattern Jest uses to detect test files - // testRegex: \\"\\", + // The regexp pattern or array of patterns that Jest uses to detect test files + // testRegex: [], // This option allows the use of a custom results processor // testResultsProcessor: null, diff --git a/packages/jest-config/src/Defaults.js b/packages/jest-config/src/Defaults.js index fefe239a189a..1b549e1059e1 100644 --- a/packages/jest-config/src/Defaults.js +++ b/packages/jest-config/src/Defaults.js @@ -70,7 +70,7 @@ export default ({ testLocationInResults: false, testMatch: ['**/__tests__/**/*.js?(x)', '**/?(*.)+(spec|test).js?(x)'], testPathIgnorePatterns: [NODE_MODULES_REGEXP], - testRegex: '', + testRegex: [], testResultsProcessor: null, testRunner: 'jasmine2', testURL: 'http://localhost', diff --git a/packages/jest-config/src/Descriptions.js b/packages/jest-config/src/Descriptions.js index fc8cafb8e785..6989be5e1dad 100644 --- a/packages/jest-config/src/Descriptions.js +++ b/packages/jest-config/src/Descriptions.js @@ -71,7 +71,8 @@ export default ({ testMatch: 'The glob patterns Jest uses to detect test files', testPathIgnorePatterns: 'An array of regexp pattern strings that are matched against all test paths, matched tests are skipped', - testRegex: 'The regexp pattern Jest uses to detect test files', + testRegex: + 'The regexp pattern or array of patterns that Jest uses to detect test files', testResultsProcessor: 'This option allows the use of a custom results processor', testRunner: 'This option allows use of a custom test runner', diff --git a/packages/jest-config/src/ValidConfig.js b/packages/jest-config/src/ValidConfig.js index edd84404cff3..8b675b90b7c8 100644 --- a/packages/jest-config/src/ValidConfig.js +++ b/packages/jest-config/src/ValidConfig.js @@ -10,6 +10,7 @@ import type {InitialOptions} from 'types/Config'; import {replacePathSepForRegex} from 'jest-regex-util'; +import {MultipleValidOptions} from 'jest-validate'; import {NODE_MODULES} from './constants'; const NODE_MODULES_REGEXP = replacePathSepForRegex(NODE_MODULES); @@ -100,7 +101,10 @@ export default ({ testMatch: ['**/__tests__/**/*.js?(x)', '**/?(*.)+(spec|test).js?(x)'], testNamePattern: 'test signature', testPathIgnorePatterns: [NODE_MODULES_REGEXP], - testRegex: '(/__tests__/.*|(\\.|/)(test|spec))\\.jsx?$', + testRegex: MultipleValidOptions( + '(/__tests__/.*|(\\.|/)(test|spec))\\.jsx?$', + ['/__tests__/\\.test\\.jsx?$', '/__tests__/\\.spec\\.jsx?$'], + ), testResultsProcessor: 'processor-node-module', testRunner: 'jasmine2', testURL: 'http://localhost', diff --git a/packages/jest-config/src/__tests__/normalize.test.js b/packages/jest-config/src/__tests__/normalize.test.js index 801ab1f0318b..e39f98ee48d5 100644 --- a/packages/jest-config/src/__tests__/normalize.test.js +++ b/packages/jest-config/src/__tests__/normalize.test.js @@ -804,6 +804,42 @@ describe('Upgrade help', () => { }); }); +describe('testRegex', () => { + it('testRegex empty string is mapped to empty array', () => { + const {options} = normalize( + { + rootDir: '/root', + testRegex: '', + }, + {}, + ); + + expect(options.testRegex).toEqual([]); + }); + it('testRegex string is mapped to array', () => { + const {options} = normalize( + { + rootDir: '/root', + testRegex: '.*', + }, + {}, + ); + + expect(options.testRegex).toEqual(['.*']); + }); + it('testRegex array is passed through', () => { + const {options} = normalize( + { + rootDir: '/root', + testRegex: ['.*'], + }, + {}, + ); + + expect(options.testRegex).toEqual(['.*']); + }); +}); + describe('testMatch', () => { it('testMatch default not applied if testRegex is set', () => { const {options} = normalize( @@ -826,7 +862,7 @@ describe('testMatch', () => { {}, ); - expect(options.testRegex).toBe(''); + expect(options.testRegex).toEqual([]); }); it('throws if testRegex and testMatch are both specified', () => { diff --git a/packages/jest-config/src/normalize.js b/packages/jest-config/src/normalize.js index a7da8a1a41d7..36c4f01a36ca 100644 --- a/packages/jest-config/src/normalize.js +++ b/packages/jest-config/src/normalize.js @@ -547,7 +547,11 @@ export default function normalize(options: InitialOptions, argv: Argv) { ); break; case 'testRegex': - value = options[key] && replacePathSepForRegex(options[key]); + const valueOrEmptyArray = options[key] || []; + const valueArray = Array.isArray(valueOrEmptyArray) + ? valueOrEmptyArray + : [valueOrEmptyArray]; + value = valueArray.map(replacePathSepForRegex); break; case 'moduleFileExtensions': { value = options[key]; @@ -701,14 +705,14 @@ export default function normalize(options: InitialOptions, argv: Argv) { } } - if (options.testRegex && options.testMatch) { + if (newOptions.testRegex.length && options.testMatch) { throw createConfigError( ` Configuration options ${chalk.bold('testMatch')} and` + ` ${chalk.bold('testRegex')} cannot be used together.`, ); } - if (options.testRegex && !options.testMatch) { + if (newOptions.testRegex.length && !options.testMatch) { // Prevent the default testMatch conflicting with any explicitly // configured `testRegex` value newOptions.testMatch = []; diff --git a/packages/jest-editor-support/src/Settings.js b/packages/jest-editor-support/src/Settings.js index d9cac96c91a4..d11da69ab998 100644 --- a/packages/jest-editor-support/src/Settings.js +++ b/packages/jest-editor-support/src/Settings.js @@ -28,7 +28,7 @@ import {createProcess} from './Process'; type Glob = string; type ConfigRepresentation = { - testRegex: string, + testRegex: string | Array, testMatch: Array, }; @@ -59,7 +59,7 @@ export default class Settings extends EventEmitter { // Defaults for a Jest project this.settings = { testMatch: ['**/__tests__/**/*.js?(x)', '**/?(*.)+(spec|test).js?(x)'], - testRegex: '(/__tests__/.*|\\.(test|spec))\\.jsx?$', + testRegex: ['(/__tests__/.*|\\.(test|spec))\\.jsx?$'], }; this.configs = [this.settings]; diff --git a/packages/jest-runtime/src/__tests__/should_instrument.test.js b/packages/jest-runtime/src/__tests__/should_instrument.test.js index a6891c48f15d..47d84a96994e 100644 --- a/packages/jest-runtime/src/__tests__/should_instrument.test.js +++ b/packages/jest-runtime/src/__tests__/should_instrument.test.js @@ -29,7 +29,13 @@ describe('should_instrument', () => { it('when testRegex provided and file is not a test file', () => { testShouldInstrument('source_file.js', defaultOptions, { - testRegex: '.*\\.(test)\\.(js)$', + testRegex: ['.*\\.(test)\\.(js)$'], + }); + }); + + it('when more than one testRegex is provided and filename is not a test file', () => { + testShouldInstrument('source_file.js', defaultOptions, { + testRegex: ['.*\\_(test)\\.(js)$', '.*\\.(test)\\.(js)$', 'never'], }); }); @@ -88,7 +94,7 @@ describe('should_instrument', () => { testShouldInstrument('do/collect/sum.coverage.test.js', defaultOptions, { forceCoverageMatch: ['**/*.(coverage).(test).js'], rootDir: '/', - testRegex: '.*\\.(test)\\.(js)$', + testRegex: ['.*\\.(test)\\.(js)$'], }); }); }); @@ -115,7 +121,13 @@ describe('should_instrument', () => { it('when testRegex provided and filename is a test file', () => { testShouldInstrument(defaultFilename, defaultOptions, { - testRegex: '.*\\.(test)\\.(js)$', + testRegex: ['.*\\.(test)\\.(js)$'], + }); + }); + + it('when more than one testRegex is provided and filename matches one of the patterns', () => { + testShouldInstrument(defaultFilename, defaultOptions, { + testRegex: ['.*\\_(test)\\.(js)$', '.*\\.(test)\\.(js)$', 'never'], }); }); diff --git a/packages/jest-runtime/src/should_instrument.js b/packages/jest-runtime/src/should_instrument.js index 7d9f76e6ee90..a0b300c56abe 100644 --- a/packages/jest-runtime/src/should_instrument.js +++ b/packages/jest-runtime/src/should_instrument.js @@ -35,7 +35,10 @@ export default function shouldInstrument( return true; } - if (config.testRegex && filename.match(config.testRegex)) { + if ( + config.testRegex && + config.testRegex.some(regex => filename.match(regex)) + ) { return false; } diff --git a/packages/jest-validate/src/condition.js b/packages/jest-validate/src/condition.js index d3dc05c36d55..e28de2f2e7ef 100644 --- a/packages/jest-validate/src/condition.js +++ b/packages/jest-validate/src/condition.js @@ -34,6 +34,6 @@ export function validationCondition(option: any, validOption: any): boolean { return getValues(validOption).some(e => validationConditionSingle(option, e)); } -export function MultipleValidOptions(...args: Array) { +export function MultipleValidOptions(...args: any) { return [MultipleValidOptionsSymbol, ...args]; } diff --git a/types/Argv.js b/types/Argv.js index ef157f155dfd..cc552d883996 100644 --- a/types/Argv.js +++ b/types/Argv.js @@ -81,7 +81,7 @@ export type Argv = {| testNamePattern: string, testPathIgnorePatterns: Array, testPathPattern: Array, - testRegex: string, + testRegex: string | Array, testResultsProcessor: ?string, testRunner: string, testURL: string, diff --git a/types/Config.js b/types/Config.js index b08323e950bb..53d6577a0a24 100644 --- a/types/Config.js +++ b/types/Config.js @@ -74,7 +74,7 @@ export type DefaultOptions = {| testLocationInResults: boolean, testMatch: Array, testPathIgnorePatterns: Array, - testRegex: string, + testRegex: Array, testResultsProcessor: ?string, testRunner: ?string, testURL: string, @@ -165,7 +165,7 @@ export type InitialOptions = { testNamePattern?: string, testPathDirs?: Array, testPathIgnorePatterns?: Array, - testRegex?: string, + testRegex?: string | Array, testResultsProcessor?: ?string, testRunner?: string, testURL?: string, @@ -282,7 +282,7 @@ export type ProjectConfig = {| testMatch: Array, testLocationInResults: boolean, testPathIgnorePatterns: Array, - testRegex: string, + testRegex: Array, testRunner: string, testURL: string, timers: 'real' | 'fake', From f08508d1f7c26556e3569b51c6413e0b6b05cc83 Mon Sep 17 00:00:00 2001 From: Jamie Treworgy Date: Thu, 18 Oct 2018 16:58:20 -0400 Subject: [PATCH 2/5] Code review; store in as Array --- CHANGELOG.md | 2 +- TestUtils.js | 2 +- packages/jest-cli/src/SearchSource.js | 6 +++--- packages/jest-config/src/__tests__/normalize.test.js | 10 +++++----- packages/jest-config/src/normalize.js | 2 +- .../src/__tests__/should_instrument.test.js | 8 ++++---- packages/jest-runtime/src/should_instrument.js | 2 +- types/Config.js | 6 +++--- 8 files changed, 19 insertions(+), 19 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index bea61eba8b7a..d3f459c9f4bb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,7 +16,7 @@ - `[jest-haste-map]` Make `ignorePattern` optional ([#7166](https://github.com/facebook/jest/pull/7166)) - `[jest-runtime]` Remove `cacheDirectory` from `ignorePattern` for `HasteMap` if not necessary ([#7166](https://github.com/facebook/jest/pull/7166)) - `[jest-validate]` Add syntax to validate multiple permitted types ([#7207](https://github.com/facebook/jest/pull/7207)) -- `[jest-config]` Accept an array as as well as a string for `testRegex` +- `[jest-config]` Accept an array as as well as a string for `testRegex`([#7209]https://github.com/facebook/jest/pull/7209)) ### Fixes diff --git a/TestUtils.js b/TestUtils.js index c179cc13a9de..8ec57581b94f 100644 --- a/TestUtils.js +++ b/TestUtils.js @@ -109,7 +109,7 @@ const DEFAULT_PROJECT_CONFIG: ProjectConfig = { testLocationInResults: false, testMatch: [], testPathIgnorePatterns: [], - testRegex: ['.test.js$'], + testRegex: [/\.test\.js$/], testRunner: 'jest-jasmine2', testURL: '', timers: 'real', diff --git a/packages/jest-cli/src/SearchSource.js b/packages/jest-cli/src/SearchSource.js index 91c93e1d2ac5..af000440a0c0 100644 --- a/packages/jest-cli/src/SearchSource.js +++ b/packages/jest-cli/src/SearchSource.js @@ -51,12 +51,12 @@ const globsToMatcher = (globs: ?Array) => { return path => micromatch([path], globs, {dot: true}).length > 0; }; -const regexToMatcher = (testRegex: Array) => { +const regexToMatcher = (testRegex: Array) => { if (!testRegex.length) { return () => true; } - const testRegexParsed = testRegex.map(e => new RegExp(e)); - return path => testRegexParsed.some(e => e.test(path)); + + return path => testRegex.some(e => e.test(path)); }; const toTests = (context, tests) => diff --git a/packages/jest-config/src/__tests__/normalize.test.js b/packages/jest-config/src/__tests__/normalize.test.js index e39f98ee48d5..4d69793652ec 100644 --- a/packages/jest-config/src/__tests__/normalize.test.js +++ b/packages/jest-config/src/__tests__/normalize.test.js @@ -816,7 +816,7 @@ describe('testRegex', () => { expect(options.testRegex).toEqual([]); }); - it('testRegex string is mapped to array', () => { + it('testRegex string is mapped to array of RegExp objects', () => { const {options} = normalize( { rootDir: '/root', @@ -825,18 +825,18 @@ describe('testRegex', () => { {}, ); - expect(options.testRegex).toEqual(['.*']); + expect(options.testRegex).toEqual([/.*/]); }); - it('testRegex array is passed through', () => { + it('testRegex array is mapped to array of RegExp objects', () => { const {options} = normalize( { rootDir: '/root', - testRegex: ['.*'], + testRegex: ['.*', 'foo\\.bar'], }, {}, ); - expect(options.testRegex).toEqual(['.*']); + expect(options.testRegex).toEqual([/.*/, /foo\.bar/]); }); }); diff --git a/packages/jest-config/src/normalize.js b/packages/jest-config/src/normalize.js index 36c4f01a36ca..7db39007304c 100644 --- a/packages/jest-config/src/normalize.js +++ b/packages/jest-config/src/normalize.js @@ -551,7 +551,7 @@ export default function normalize(options: InitialOptions, argv: Argv) { const valueArray = Array.isArray(valueOrEmptyArray) ? valueOrEmptyArray : [valueOrEmptyArray]; - value = valueArray.map(replacePathSepForRegex); + value = valueArray.map(replacePathSepForRegex).map(e => new RegExp(e)); break; case 'moduleFileExtensions': { value = options[key]; diff --git a/packages/jest-runtime/src/__tests__/should_instrument.test.js b/packages/jest-runtime/src/__tests__/should_instrument.test.js index 47d84a96994e..9003579b427d 100644 --- a/packages/jest-runtime/src/__tests__/should_instrument.test.js +++ b/packages/jest-runtime/src/__tests__/should_instrument.test.js @@ -29,13 +29,13 @@ describe('should_instrument', () => { it('when testRegex provided and file is not a test file', () => { testShouldInstrument('source_file.js', defaultOptions, { - testRegex: ['.*\\.(test)\\.(js)$'], + testRegex: [/.*\.(test)\\.(js)$'/], }); }); it('when more than one testRegex is provided and filename is not a test file', () => { testShouldInstrument('source_file.js', defaultOptions, { - testRegex: ['.*\\_(test)\\.(js)$', '.*\\.(test)\\.(js)$', 'never'], + testRegex: [/.*\_(test)\.(js)$/, /.*\.(test)\.(js)$/, /never/], }); }); @@ -121,13 +121,13 @@ describe('should_instrument', () => { it('when testRegex provided and filename is a test file', () => { testShouldInstrument(defaultFilename, defaultOptions, { - testRegex: ['.*\\.(test)\\.(js)$'], + testRegex: [/.*\.(test)\.(js)$/], }); }); it('when more than one testRegex is provided and filename matches one of the patterns', () => { testShouldInstrument(defaultFilename, defaultOptions, { - testRegex: ['.*\\_(test)\\.(js)$', '.*\\.(test)\\.(js)$', 'never'], + testRegex: [/.*\_(test)\.(js)$/, /.*\.(test)\.(js)$/, /never/], }); }); diff --git a/packages/jest-runtime/src/should_instrument.js b/packages/jest-runtime/src/should_instrument.js index a0b300c56abe..1f0317f8d715 100644 --- a/packages/jest-runtime/src/should_instrument.js +++ b/packages/jest-runtime/src/should_instrument.js @@ -37,7 +37,7 @@ export default function shouldInstrument( if ( config.testRegex && - config.testRegex.some(regex => filename.match(regex)) + config.testRegex.some(regex => regex.test(filename)) ) { return false; } diff --git a/types/Config.js b/types/Config.js index 53d6577a0a24..569c49b55d61 100644 --- a/types/Config.js +++ b/types/Config.js @@ -74,7 +74,7 @@ export type DefaultOptions = {| testLocationInResults: boolean, testMatch: Array, testPathIgnorePatterns: Array, - testRegex: Array, + testRegex: Array, testResultsProcessor: ?string, testRunner: ?string, testURL: string, @@ -165,7 +165,7 @@ export type InitialOptions = { testNamePattern?: string, testPathDirs?: Array, testPathIgnorePatterns?: Array, - testRegex?: string | Array, + testRegex?: string | Array, testResultsProcessor?: ?string, testRunner?: string, testURL?: string, @@ -282,7 +282,7 @@ export type ProjectConfig = {| testMatch: Array, testLocationInResults: boolean, testPathIgnorePatterns: Array, - testRegex: Array, + testRegex: Array, testRunner: string, testURL: string, timers: 'real' | 'fake', From c4f189bdf51a7dc3f0d37e8646d74879b7b3c4bf Mon Sep 17 00:00:00 2001 From: Jamie Treworgy Date: Thu, 18 Oct 2018 18:02:57 -0400 Subject: [PATCH 3/5] Some things that slipped through --- .vscode/settings.json | 2 +- packages/jest-validate/src/condition.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.vscode/settings.json b/.vscode/settings.json index 0b867bdd9628..5157e7476d63 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -7,7 +7,7 @@ "**/node_modules": true, "**/build": true }, - "editor.formatOnSave": false, + "editor.formatOnSave": true, "flow.useNPMPackagedFlow": true, "javascript.validate.enable": false, "jest.pathToJest": "yarn jest --", diff --git a/packages/jest-validate/src/condition.js b/packages/jest-validate/src/condition.js index e28de2f2e7ef..d3dc05c36d55 100644 --- a/packages/jest-validate/src/condition.js +++ b/packages/jest-validate/src/condition.js @@ -34,6 +34,6 @@ export function validationCondition(option: any, validOption: any): boolean { return getValues(validOption).some(e => validationConditionSingle(option, e)); } -export function MultipleValidOptions(...args: any) { +export function MultipleValidOptions(...args: Array) { return [MultipleValidOptionsSymbol, ...args]; } From eb8355f75b52e3140d04f147bfb53eebb13f22cb Mon Sep 17 00:00:00 2001 From: Jamie Treworgy Date: Thu, 18 Oct 2018 18:06:01 -0400 Subject: [PATCH 4/5] Fix settings.json --- .vscode/settings.json | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/.vscode/settings.json b/.vscode/settings.json index 5157e7476d63..c4951686b125 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,7 +1,5 @@ { - "editor.rulers": [ - 80 - ], + "editor.rulers": [80], "files.exclude": { "**/.git": true, "**/node_modules": true, From e25d89c4948824b0876c3c927183a6b8387d089e Mon Sep 17 00:00:00 2001 From: Jamie Treworgy Date: Fri, 19 Oct 2018 09:53:14 -0400 Subject: [PATCH 5/5] Code review: Provide useful message on failed regexp parsing; add test --- .../__tests__/__snapshots__/normalize.test.js.snap | 11 +++++++++++ .../jest-config/src/__tests__/normalize.test.js | 12 ++++++++++++ packages/jest-config/src/normalize.js | 14 +++++++++++++- 3 files changed, 36 insertions(+), 1 deletion(-) diff --git a/packages/jest-config/src/__tests__/__snapshots__/normalize.test.js.snap b/packages/jest-config/src/__tests__/__snapshots__/normalize.test.js.snap index 19770435b020..ef754afc331b 100644 --- a/packages/jest-config/src/__tests__/__snapshots__/normalize.test.js.snap +++ b/packages/jest-config/src/__tests__/__snapshots__/normalize.test.js.snap @@ -67,6 +67,17 @@ exports[`testMatch throws if testRegex and testMatch are both specified 1`] = ` " `; +exports[`testMatch throws if testRegex is provided an invalid regex string 1`] = ` +"Validation Error: + +Error parsing configuration for testRegex: \\"foo(bar\\" could not be parsed. +Error: Invalid regular expression: /foo(bar/: Unterminated group + + Configuration Documentation: + https://jestjs.io/docs/configuration.html +" +`; + exports[`testPathPattern ignores invalid regular expressions and logs a warning 1`] = `" Invalid testPattern a( supplied. Running all tests instead."`; exports[`testPathPattern --testPathPattern ignores invalid regular expressions and logs a warning 1`] = `" Invalid testPattern a( supplied. Running all tests instead."`; diff --git a/packages/jest-config/src/__tests__/normalize.test.js b/packages/jest-config/src/__tests__/normalize.test.js index 4d69793652ec..ff45c3036203 100644 --- a/packages/jest-config/src/__tests__/normalize.test.js +++ b/packages/jest-config/src/__tests__/normalize.test.js @@ -878,6 +878,18 @@ describe('testMatch', () => { }).toThrowErrorMatchingSnapshot(); }); + it('throws if testRegex is provided an invalid regex string', () => { + expect(() => { + normalize( + { + rootDir: '/root', + testRegex: 'foo(bar', + }, + {}, + ); + }).toThrowErrorMatchingSnapshot(); + }); + it('normalizes testMatch', () => { const {options} = normalize( { diff --git a/packages/jest-config/src/normalize.js b/packages/jest-config/src/normalize.js index 7db39007304c..0bbd7af6b80b 100644 --- a/packages/jest-config/src/normalize.js +++ b/packages/jest-config/src/normalize.js @@ -551,7 +551,19 @@ export default function normalize(options: InitialOptions, argv: Argv) { const valueArray = Array.isArray(valueOrEmptyArray) ? valueOrEmptyArray : [valueOrEmptyArray]; - value = valueArray.map(replacePathSepForRegex).map(e => new RegExp(e)); + + value = valueArray.map(replacePathSepForRegex).map(pattern => { + try { + return new RegExp(pattern); + } catch (err) { + throw createConfigError( + `Error parsing configuration for ${chalk.bold( + key, + )}: "${pattern}" could not be parsed.\n` + + `Error: ${err.message}`, + ); + } + }); break; case 'moduleFileExtensions': { value = options[key];