From 344bc43203f83c870b07a0501f0cc8e4c1e81764 Mon Sep 17 00:00:00 2001 From: Brandon Chinn Date: Tue, 25 Apr 2023 19:02:02 -0700 Subject: [PATCH 01/22] Factor out toString() call --- .../jest-config/src/__tests__/normalize.test.ts | 14 +++++++------- packages/jest-config/src/normalize.ts | 12 +++--------- 2 files changed, 10 insertions(+), 16 deletions(-) diff --git a/packages/jest-config/src/__tests__/normalize.test.ts b/packages/jest-config/src/__tests__/normalize.test.ts index 5ea19763d85a..319fdaa1520b 100644 --- a/packages/jest-config/src/__tests__/normalize.test.ts +++ b/packages/jest-config/src/__tests__/normalize.test.ts @@ -1631,13 +1631,6 @@ describe('testPathPattern', () => { expect(options.testPathPattern).toBe('a/b|c/d'); }); - it('coerces all patterns to strings', async () => { - const argv = {[opt.property]: [1]} as Config.Argv; - const {options} = await normalize(initialOptions, argv); - - expect(options.testPathPattern).toBe('1'); - }); - describe('posix', () => { it('should not escape the pattern', async () => { const argv = { @@ -1694,6 +1687,13 @@ describe('testPathPattern', () => { }); } + it('coerces patterns to strings', async () => { + const argv = {_: [1]} as Config.Argv; + const {options} = await normalize(initialOptions, argv); + + expect(options.testPathPattern).toBe('1'); + }); + it('joins multiple --testPathPatterns and ', async () => { const {options} = await normalize(initialOptions, { _: ['a', 'b'], diff --git a/packages/jest-config/src/normalize.ts b/packages/jest-config/src/normalize.ts index 25ef99b2e954..8f36190a03cb 100644 --- a/packages/jest-config/src/normalize.ts +++ b/packages/jest-config/src/normalize.ts @@ -395,20 +395,14 @@ const buildTestPathPattern = (argv: Config.Argv): string => { const patterns = []; if (argv._) { - patterns.push(...argv._); + patterns.push(...argv._.map(x => x.toString())); } if (argv.testPathPattern) { patterns.push(...argv.testPathPattern); } - const replacePosixSep = (pattern: string | number) => { - // yargs coerces positional args into numbers - const patternAsString = pattern.toString(); - if (path.sep === '/') { - return patternAsString; - } - return patternAsString.replace(/\//g, '\\\\'); - }; + const replacePosixSep = (pattern: string) => + path.sep === '/' ? pattern : pattern.replace(/\//g, '\\\\'); const testPathPattern = patterns.map(replacePosixSep).join('|'); if (validatePattern(testPathPattern)) { From 317d0794a9a926daf475eea969700ca1d4364655 Mon Sep 17 00:00:00 2001 From: Brandon Chinn Date: Tue, 25 Apr 2023 19:02:02 -0700 Subject: [PATCH 02/22] Remove redundant 'globalConfig.testPathPattern == null' check --- packages/jest-core/src/SearchSource.ts | 2 -- 1 file changed, 2 deletions(-) diff --git a/packages/jest-core/src/SearchSource.ts b/packages/jest-core/src/SearchSource.ts index b9227587868b..619c396c15b5 100644 --- a/packages/jest-core/src/SearchSource.ts +++ b/packages/jest-core/src/SearchSource.ts @@ -287,8 +287,6 @@ export default class SearchSource { paths, globalConfig.collectCoverage, ); - } else if (globalConfig.testPathPattern == null) { - return {tests: []}; } else { return this.findMatchingTests(globalConfig.testPathPattern); } From 86993d4a1930996a730aa712ec875877acaffb76 Mon Sep 17 00:00:00 2001 From: Brandon Chinn Date: Tue, 25 Apr 2023 19:02:02 -0700 Subject: [PATCH 03/22] Consolidate testPathPatterns logic --- .../src/__tests__/normalize.test.ts | 54 ------- .../src/__tests__/validatePattern.test.ts | 35 ----- packages/jest-config/src/normalize.ts | 13 +- packages/jest-config/src/validatePattern.ts | 19 --- packages/jest-util/src/TestPathPatterns.ts | 74 ++++++++++ .../src/__tests__/TestPathPatterns.test.ts | 134 ++++++++++++++++++ .../TestPathPatterns.test.ts.snap | 3 + packages/jest-util/src/index.ts | 1 + 8 files changed, 217 insertions(+), 116 deletions(-) delete mode 100644 packages/jest-config/src/__tests__/validatePattern.test.ts delete mode 100644 packages/jest-config/src/validatePattern.ts create mode 100644 packages/jest-util/src/TestPathPatterns.ts create mode 100644 packages/jest-util/src/__tests__/TestPathPatterns.test.ts create mode 100644 packages/jest-util/src/__tests__/__snapshots__/TestPathPatterns.test.ts.snap diff --git a/packages/jest-config/src/__tests__/normalize.test.ts b/packages/jest-config/src/__tests__/normalize.test.ts index 319fdaa1520b..4a8cc08c3439 100644 --- a/packages/jest-config/src/__tests__/normalize.test.ts +++ b/packages/jest-config/src/__tests__/normalize.test.ts @@ -1630,60 +1630,6 @@ describe('testPathPattern', () => { expect(options.testPathPattern).toBe('a/b|c/d'); }); - - describe('posix', () => { - it('should not escape the pattern', async () => { - const argv = { - [opt.property]: ['a\\/b', 'a/b', 'a\\b', 'a\\\\b'], - } as Config.Argv; - const {options} = await normalize(initialOptions, argv); - - expect(options.testPathPattern).toBe('a\\/b|a/b|a\\b|a\\\\b'); - }); - }); - - describe('win32', () => { - beforeEach(() => { - jest.mock( - 'path', - () => jest.requireActual('path').win32, - ); - ( - require('jest-resolve') as typeof import('jest-resolve') - ).default.findNodeModule = findNodeModule; - }); - - afterEach(() => { - jest.resetModules(); - }); - - it('preserves any use of "\\"', async () => { - const argv = {[opt.property]: ['a\\b', 'c\\\\d']} as Config.Argv; - const {options} = await ( - require('../normalize') as typeof import('../normalize') - ).default(initialOptions, argv); - - expect(options.testPathPattern).toBe('a\\b|c\\\\d'); - }); - - it('replaces POSIX path separators', async () => { - const argv = {[opt.property]: ['a/b']} as Config.Argv; - const {options} = await ( - require('../normalize') as typeof import('../normalize') - ).default(initialOptions, argv); - - expect(options.testPathPattern).toBe('a\\\\b'); - }); - - it('replaces POSIX paths in multiple args', async () => { - const argv = {[opt.property]: ['a/b', 'c/d']} as Config.Argv; - const {options} = await ( - require('../normalize') as typeof import('../normalize') - ).default(initialOptions, argv); - - expect(options.testPathPattern).toBe('a\\\\b|c\\\\d'); - }); - }); }); } diff --git a/packages/jest-config/src/__tests__/validatePattern.test.ts b/packages/jest-config/src/__tests__/validatePattern.test.ts deleted file mode 100644 index e664f70bfa7b..000000000000 --- a/packages/jest-config/src/__tests__/validatePattern.test.ts +++ /dev/null @@ -1,35 +0,0 @@ -/** - * Copyright (c) Meta Platforms, Inc. and affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - * - */ - -import validatePattern from '../validatePattern'; - -describe('validate pattern function', () => { - it('without passed args returns true', () => { - const isValid = validatePattern(); - - expect(isValid).toBeTruthy(); - }); - - it('returns true for empty pattern', () => { - const isValid = validatePattern(''); - - expect(isValid).toBeTruthy(); - }); - - it('returns true for valid pattern', () => { - const isValid = validatePattern('abc+'); - - expect(isValid).toBeTruthy(); - }); - - it('returns false for invalid pattern', () => { - const isValid = validatePattern('\\'); - - expect(isValid).toBeFalsy(); - }); -}); diff --git a/packages/jest-config/src/normalize.ts b/packages/jest-config/src/normalize.ts index 8f36190a03cb..983d77edf2e6 100644 --- a/packages/jest-config/src/normalize.ts +++ b/packages/jest-config/src/normalize.ts @@ -22,6 +22,7 @@ import Resolver, { resolveWatchPlugin, } from 'jest-resolve'; import { + TestPathPatterns, clearLine, replacePathSepForGlob, requireOrImportModule, @@ -49,7 +50,6 @@ import { replaceRootDirInPath, resolve, } from './utils'; -import validatePattern from './validatePattern'; const ERROR = `${BULLET}Validation Error`; const PRESET_EXTENSIONS = ['.json', '.js', '.cjs', '.mjs']; @@ -401,14 +401,11 @@ const buildTestPathPattern = (argv: Config.Argv): string => { patterns.push(...argv.testPathPattern); } - const replacePosixSep = (pattern: string) => - path.sep === '/' ? pattern : pattern.replace(/\//g, '\\\\'); - - const testPathPattern = patterns.map(replacePosixSep).join('|'); - if (validatePattern(testPathPattern)) { - return testPathPattern; + const testPathPatterns = new TestPathPatterns(patterns); + if (testPathPatterns.isValid()) { + return testPathPatterns.regexString; } else { - showTestPathPatternError(testPathPattern); + showTestPathPatternError(testPathPatterns.regexString); return ''; } }; diff --git a/packages/jest-config/src/validatePattern.ts b/packages/jest-config/src/validatePattern.ts deleted file mode 100644 index 90f3a2c3abe3..000000000000 --- a/packages/jest-config/src/validatePattern.ts +++ /dev/null @@ -1,19 +0,0 @@ -/** - * Copyright (c) Meta Platforms, Inc. and affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - */ - -export default function validatePattern(pattern?: string): boolean { - if (pattern) { - try { - // eslint-disable-next-line no-new - new RegExp(pattern, 'i'); - } catch { - return false; - } - } - - return true; -} diff --git a/packages/jest-util/src/TestPathPatterns.ts b/packages/jest-util/src/TestPathPatterns.ts new file mode 100644 index 000000000000..142d86192a58 --- /dev/null +++ b/packages/jest-util/src/TestPathPatterns.ts @@ -0,0 +1,74 @@ +/** + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +import {replacePathSepForRegex} from 'jest-regex-util'; + +export default class TestPathPatterns { + readonly patterns: Array; + + private _regexString: string | null = null; + + constructor(patterns: Array) { + this.patterns = patterns; + } + + get regexString(): string { + if (this._regexString !== null) { + return this._regexString; + } + const regexString = this.patterns + .map(replacePathSepForRegex) + .join('|'); + this._regexString = regexString; + return regexString; + } + + private get regex(): RegExp { + return new RegExp(this.regexString, 'i'); + } + + /** + * Return true if there are any patterns. + */ + isSet(): boolean { + return this.patterns.length > 0; + } + + /** + * Return true if the patterns form a valid regex. + */ + isValid(): boolean { + try { + // @ts-expect-error noUnusedLocals + // eslint-disable-next-line @typescript-eslint/no-unused-vars + const _ = this.regex; + return true; + } catch { + return false; + } + } + + /** + * Return true if the given ABSOLUTE path matches the patterns. + * + * Throws an error if the patterns form an invalid regex (see `isValid`). + */ + isMatch(path: string): boolean { + return this.regex.test(path); + } + + /** + * Return a human-friendly version of the pattern regex. + * + * Does no normalization or anything, just a naive joining of the regex, + * for simplicity. + */ + toPretty(): string { + const regex = this.patterns.map(p => p.replace(/\//g, '\\/')).join('|'); + return `/${regex}/i`; + } +} diff --git a/packages/jest-util/src/__tests__/TestPathPatterns.test.ts b/packages/jest-util/src/__tests__/TestPathPatterns.test.ts new file mode 100644 index 000000000000..b5be21943629 --- /dev/null +++ b/packages/jest-util/src/__tests__/TestPathPatterns.test.ts @@ -0,0 +1,134 @@ +/** + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +import type * as path from 'path'; +import TestPathPatterns from '../TestPathPatterns'; + +const mockSep = jest.fn(); +jest.mock('path', () => { + return { + ...(jest.requireActual('path') as typeof path), + get sep() { + return mockSep() || '/'; + }, + }; +}); +beforeEach(() => { + jest.resetAllMocks(); +}); + +describe('TestPathPatterns', () => { + describe('isSet', () => { + it('returns false if no patterns specified', () => { + const testPathPatterns = new TestPathPatterns([]); + expect(testPathPatterns.isSet()).toBe(false); + }); + + it('returns true if patterns specified', () => { + const testPathPatterns = new TestPathPatterns(['a']); + expect(testPathPatterns.isSet()).toBe(true); + }); + }); + + describe('isValid', () => { + it('returns true for empty patterns', () => { + const testPathPatterns = new TestPathPatterns([]); + expect(testPathPatterns.isValid()).toBe(true); + }); + + it('returns true for valid patterns', () => { + const testPathPatterns = new TestPathPatterns(['abc+', 'z.*']); + expect(testPathPatterns.isValid()).toBe(true); + }); + + it('returns false for at least one invalid pattern', () => { + const testPathPatterns = new TestPathPatterns(['abc+', '(', 'z.*']); + expect(testPathPatterns.isValid()).toBe(false); + }); + }); + + describe('isMatch', () => { + it('returns true with no patterns', () => { + const testPathPatterns = new TestPathPatterns([]); + expect(testPathPatterns.isMatch('/a/b')).toBe(true); + }); + + it('returns true for same path', () => { + const testPathPatterns = new TestPathPatterns(['/a/b']); + expect(testPathPatterns.isMatch('/a/b')).toBe(true); + }); + + it('returns true for same path with case insensitive', () => { + const testPathPatternsUpper = new TestPathPatterns(['/A/B']); + expect(testPathPatternsUpper.isMatch('/a/b')).toBe(true); + expect(testPathPatternsUpper.isMatch('/A/B')).toBe(true); + + const testPathPatternsLower = new TestPathPatterns(['/a/b']); + expect(testPathPatternsLower.isMatch('/A/B')).toBe(true); + expect(testPathPatternsLower.isMatch('/a/b')).toBe(true); + }); + + it('returns true for contained path', () => { + const testPathPatterns = new TestPathPatterns(['b/c']); + expect(testPathPatterns.isMatch('/a/b/c/d')).toBe(true); + }); + + it('returns true for partial file match', () => { + const testPathPatterns = new TestPathPatterns(['aaa']); + expect(testPathPatterns.isMatch('/foo/..aaa..')).toBe(true); + expect(testPathPatterns.isMatch('/foo/..aaa')).toBe(true); + expect(testPathPatterns.isMatch('/foo/aaa..')).toBe(true); + }); + + it('returns true for path suffix', () => { + const testPathPatterns = new TestPathPatterns(['c/d']); + expect(testPathPatterns.isMatch('/a/b/c/d')).toBe(true); + }); + + it('returns true if regex matches', () => { + const testPathPatterns = new TestPathPatterns(['ab*c?']); + + expect(testPathPatterns.isMatch('/foo/a')).toBe(true); + expect(testPathPatterns.isMatch('/foo/ab')).toBe(true); + expect(testPathPatterns.isMatch('/foo/abb')).toBe(true); + expect(testPathPatterns.isMatch('/foo/ac')).toBe(true); + expect(testPathPatterns.isMatch('/foo/abc')).toBe(true); + expect(testPathPatterns.isMatch('/foo/abbc')).toBe(true); + + expect(testPathPatterns.isMatch('/foo/bc')).toBe(false); + }); + + it('returns true if match any paths', () => { + const testPathPatterns = new TestPathPatterns(['a/b', 'c/d']); + + expect(testPathPatterns.isMatch('/foo/a/b')).toBe(true); + expect(testPathPatterns.isMatch('/foo/c/d')).toBe(true); + + expect(testPathPatterns.isMatch('/foo/a')).toBe(false); + expect(testPathPatterns.isMatch('/foo/b/c')).toBe(false); + }); + + it('does not normalize Windows paths on POSIX', () => { + mockSep.mockReturnValue('/'); + const testPathPatterns = new TestPathPatterns(['a\\z', 'a\\\\z']); + expect(testPathPatterns.isMatch('/foo/a/z')).toBe(false); + }); + + it('normalizes paths for Windows', () => { + mockSep.mockReturnValue('\\'); + const testPathPatterns = new TestPathPatterns(['a/b']); + expect(testPathPatterns.isMatch('\\foo\\a\\b')).toBe(true); + }); + }); + + describe('toPretty', () => { + it('renders a human-readable string', () => { + const testPathPatterns = new TestPathPatterns(['a/b', 'c/d']); + expect(testPathPatterns.toPretty()).toMatchSnapshot(); + }); + }); +}); diff --git a/packages/jest-util/src/__tests__/__snapshots__/TestPathPatterns.test.ts.snap b/packages/jest-util/src/__tests__/__snapshots__/TestPathPatterns.test.ts.snap new file mode 100644 index 000000000000..e845164fb162 --- /dev/null +++ b/packages/jest-util/src/__tests__/__snapshots__/TestPathPatterns.test.ts.snap @@ -0,0 +1,3 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`TestPathPatterns toPretty renders a human-readable string 1`] = `"/a\\/b|c\\/d/i"`; diff --git a/packages/jest-util/src/index.ts b/packages/jest-util/src/index.ts index 531acfe4aa3a..850d96c213f1 100644 --- a/packages/jest-util/src/index.ts +++ b/packages/jest-util/src/index.ts @@ -21,6 +21,7 @@ export {default as deepCyclicCopy} from './deepCyclicCopy'; export {default as convertDescriptorToString} from './convertDescriptorToString'; export {specialChars}; export {default as replacePathSepForGlob} from './replacePathSepForGlob'; +export {default as TestPathPatterns} from './TestPathPatterns'; export {default as testPathPatternToRegExp} from './testPathPatternToRegExp'; export {default as globsToMatcher} from './globsToMatcher'; export {preRunMessage}; From ecd979f7710814d70d290bfb8fe1fba10cf7d536 Mon Sep 17 00:00:00 2001 From: Brandon Chinn Date: Tue, 25 Apr 2023 19:02:02 -0700 Subject: [PATCH 04/22] Return TestPathPatterns in normalize helper --- .../__snapshots__/normalize.test.ts.snap | 4 ++-- packages/jest-config/src/normalize.ts | 20 +++++++++---------- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/packages/jest-config/src/__tests__/__snapshots__/normalize.test.ts.snap b/packages/jest-config/src/__tests__/__snapshots__/normalize.test.ts.snap index 3a7d0dff6d45..5d309a3ae54d 100644 --- a/packages/jest-config/src/__tests__/__snapshots__/normalize.test.ts.snap +++ b/packages/jest-config/src/__tests__/__snapshots__/normalize.test.ts.snap @@ -482,9 +482,9 @@ exports[`testMatch throws if testRegex and testMatch are both specified 1`] = ` " `; -exports[`testPathPattern ignores invalid regular expressions and logs a warning 1`] = `" Invalid testPattern a( supplied. Running all tests instead."`; +exports[`testPathPattern ignores invalid regular expressions and logs a warning 1`] = `" Invalid testPattern /a(/i 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."`; +exports[`testPathPattern --testPathPattern ignores invalid regular expressions and logs a warning 1`] = `" Invalid testPattern /a(/i supplied. Running all tests instead."`; exports[`testTimeout should throw an error if timeout is a negative number 1`] = ` "Validation Error: diff --git a/packages/jest-config/src/normalize.ts b/packages/jest-config/src/normalize.ts index 983d77edf2e6..586b7d119def 100644 --- a/packages/jest-config/src/normalize.ts +++ b/packages/jest-config/src/normalize.ts @@ -391,7 +391,7 @@ const normalizeReporters = ({ }); }; -const buildTestPathPattern = (argv: Config.Argv): string => { +const buildTestPathPatterns = (argv: Config.Argv): TestPathPatterns => { const patterns = []; if (argv._) { @@ -402,21 +402,20 @@ const buildTestPathPattern = (argv: Config.Argv): string => { } const testPathPatterns = new TestPathPatterns(patterns); - if (testPathPatterns.isValid()) { - return testPathPatterns.regexString; - } else { - showTestPathPatternError(testPathPatterns.regexString); - return ''; + if (!testPathPatterns.isValid()) { + showTestPathPatternsError(testPathPatterns); + return new TestPathPatterns([]); } + return testPathPatterns; }; -const showTestPathPatternError = (testPathPattern: string) => { +const showTestPathPatternsError = (testPathPatterns: TestPathPatterns) => { clearLine(process.stdout); // eslint-disable-next-line no-console console.log( chalk.red( - ` Invalid testPattern ${testPathPattern} supplied. ` + + ` Invalid testPattern ${testPathPatterns.toPretty()} supplied. ` + 'Running all tests instead.', ), ); @@ -998,7 +997,8 @@ export default async function normalize( } newOptions.nonFlagArgs = argv._?.map(arg => `${arg}`); - newOptions.testPathPattern = buildTestPathPattern(argv); + const testPathPatterns = buildTestPathPatterns(argv); + newOptions.testPathPattern = testPathPatterns.regexString; newOptions.json = !!argv.json; newOptions.testFailureExitCode = parseInt( @@ -1017,7 +1017,7 @@ export default async function normalize( if (argv.all) { newOptions.onlyChanged = false; newOptions.onlyFailures = false; - } else if (newOptions.testPathPattern) { + } else if (testPathPatterns.isSet()) { // When passing a test path pattern we don't want to only monitor changed // files unless `--watch` is also passed. newOptions.onlyChanged = newOptions.watch; From 4caaa456d3e7227e0e8884d44b7449caff66b1a4 Mon Sep 17 00:00:00 2001 From: Brandon Chinn Date: Tue, 25 Apr 2023 19:02:02 -0700 Subject: [PATCH 05/22] Store parsed patterns in global config --- e2e/__tests__/__snapshots__/showConfig.test.ts.snap | 1 + packages/jest-config/src/index.ts | 1 + packages/jest-config/src/normalize.ts | 1 + packages/jest-core/src/__tests__/SearchSource.test.ts | 1 + .../__snapshots__/watchFilenamePatternMode.test.js.snap | 3 +++ .../jest-core/src/__tests__/getNoTestsFoundMessage.test.ts | 1 + packages/jest-core/src/__tests__/watch.test.js | 3 +++ .../__tests__/__snapshots__/logDebugMessages.test.ts.snap | 1 + packages/jest-core/src/plugins/FailedTestsInteractive.ts | 1 + packages/jest-core/src/plugins/TestPathPattern.ts | 2 +- packages/jest-core/src/plugins/UpdateSnapshotsInteractive.ts | 1 + .../src/plugins/__tests__/FailedTestsInteractive.test.js | 1 + packages/jest-core/src/watch.ts | 5 +++++ packages/jest-types/src/Config.ts | 1 + packages/jest-watcher/src/types.ts | 1 + packages/test-utils/src/config.ts | 1 + 16 files changed, 24 insertions(+), 1 deletion(-) diff --git a/e2e/__tests__/__snapshots__/showConfig.test.ts.snap b/e2e/__tests__/__snapshots__/showConfig.test.ts.snap index 332667b5f4fc..fad9b1278dc3 100644 --- a/e2e/__tests__/__snapshots__/showConfig.test.ts.snap +++ b/e2e/__tests__/__snapshots__/showConfig.test.ts.snap @@ -139,6 +139,7 @@ exports[`--showConfig outputs config info and exits 1`] = ` }, "testFailureExitCode": 1, "testPathPattern": "", + "testPathPatterns": [], "testSequencer": "<>/jest-test-sequencer/build/index.js", "updateSnapshot": "none", "useStderr": false, diff --git a/packages/jest-config/src/index.ts b/packages/jest-config/src/index.ts index 886e32003df9..66fd142c4b41 100644 --- a/packages/jest-config/src/index.ts +++ b/packages/jest-config/src/index.ts @@ -132,6 +132,7 @@ const groupOptions = ( testFailureExitCode: options.testFailureExitCode, testNamePattern: options.testNamePattern, testPathPattern: options.testPathPattern, + testPathPatterns: options.testPathPatterns, testResultsProcessor: options.testResultsProcessor, testSequencer: options.testSequencer, testTimeout: options.testTimeout, diff --git a/packages/jest-config/src/normalize.ts b/packages/jest-config/src/normalize.ts index 586b7d119def..b21e5ad2eed5 100644 --- a/packages/jest-config/src/normalize.ts +++ b/packages/jest-config/src/normalize.ts @@ -998,6 +998,7 @@ export default async function normalize( newOptions.nonFlagArgs = argv._?.map(arg => `${arg}`); const testPathPatterns = buildTestPathPatterns(argv); + newOptions.testPathPatterns = testPathPatterns.patterns; newOptions.testPathPattern = testPathPatterns.regexString; newOptions.json = !!argv.json; diff --git a/packages/jest-core/src/__tests__/SearchSource.test.ts b/packages/jest-core/src/__tests__/SearchSource.test.ts index 575bceffeab9..01b013505929 100644 --- a/packages/jest-core/src/__tests__/SearchSource.test.ts +++ b/packages/jest-core/src/__tests__/SearchSource.test.ts @@ -110,6 +110,7 @@ describe('SearchSource', () => { const {tests: paths} = await searchSource.getTestPaths({ ...config, testPathPattern: '', + testPathPatterns: [], }); return paths.map(({path: p}) => path.relative(rootDir, p)).sort(); }; diff --git a/packages/jest-core/src/__tests__/__snapshots__/watchFilenamePatternMode.test.js.snap b/packages/jest-core/src/__tests__/__snapshots__/watchFilenamePatternMode.test.js.snap index 9e5b82d69a78..e505641b8604 100644 --- a/packages/jest-core/src/__tests__/__snapshots__/watchFilenamePatternMode.test.js.snap +++ b/packages/jest-core/src/__tests__/__snapshots__/watchFilenamePatternMode.test.js.snap @@ -93,6 +93,9 @@ Object { "onlyChanged": false, "passWithNoTests": true, "testPathPattern": "p.*3", + "testPathPatterns": Array [ + "p.*3", + ], "watch": true, "watchAll": false, } diff --git a/packages/jest-core/src/__tests__/getNoTestsFoundMessage.test.ts b/packages/jest-core/src/__tests__/getNoTestsFoundMessage.test.ts index 994db8068d8b..f0f026c802bf 100644 --- a/packages/jest-core/src/__tests__/getNoTestsFoundMessage.test.ts +++ b/packages/jest-core/src/__tests__/getNoTestsFoundMessage.test.ts @@ -19,6 +19,7 @@ describe('getNoTestsFoundMessage', () => { return makeGlobalConfig({ rootDir: '/root/dir', testPathPattern: '/path/pattern', + testPathPatterns: ['/path/pattern'], ...options, }); } diff --git a/packages/jest-core/src/__tests__/watch.test.js b/packages/jest-core/src/__tests__/watch.test.js index f8988d256c95..e11dbe59d097 100644 --- a/packages/jest-core/src/__tests__/watch.test.js +++ b/packages/jest-core/src/__tests__/watch.test.js @@ -672,6 +672,7 @@ describe('Watch mode flows', () => { ${'✖︎'} | ${'testFailureExitCode'} ${'✔︎'} | ${'testNamePattern'} ${'✔︎'} | ${'testPathPattern'} + ${'✔︎'} | ${'testPathPatterns'} ${'✖︎'} | ${'testResultsProcessor'} ${'✔︎'} | ${'updateSnapshot'} ${'✖︎'} | ${'useStderr'} @@ -899,6 +900,7 @@ describe('Watch mode flows', () => { expect(runJestMock.mock.calls[0][0].globalConfig).toMatchObject({ testPathPattern: 'file', + testPathPatterns: ['file'], watch: true, watchAll: false, }); @@ -923,6 +925,7 @@ describe('Watch mode flows', () => { expect(runJestMock.mock.calls[1][0].globalConfig).toMatchObject({ testNamePattern: 'test', testPathPattern: 'file', + testPathPatterns: ['file'], watch: true, watchAll: false, }); diff --git a/packages/jest-core/src/lib/__tests__/__snapshots__/logDebugMessages.test.ts.snap b/packages/jest-core/src/lib/__tests__/__snapshots__/logDebugMessages.test.ts.snap index 1f288c9a76d1..8621ebf28bc5 100644 --- a/packages/jest-core/src/lib/__tests__/__snapshots__/logDebugMessages.test.ts.snap +++ b/packages/jest-core/src/lib/__tests__/__snapshots__/logDebugMessages.test.ts.snap @@ -110,6 +110,7 @@ exports[`prints the config object 1`] = ` "testFailureExitCode": 1, "testNamePattern": "", "testPathPattern": "", + "testPathPatterns": [], "testSequencer": "@jest/test-sequencer", "testTimeout": 5000, "updateSnapshot": "none", diff --git a/packages/jest-core/src/plugins/FailedTestsInteractive.ts b/packages/jest-core/src/plugins/FailedTestsInteractive.ts index 39dd8756e8c8..6effde8159c0 100644 --- a/packages/jest-core/src/plugins/FailedTestsInteractive.ts +++ b/packages/jest-core/src/plugins/FailedTestsInteractive.ts @@ -59,6 +59,7 @@ export default class FailedTestsInteractivePlugin extends BaseWatchPlugin { mode: 'watch', testNamePattern: failure ? `^${failure.fullName}$` : '', testPathPattern: failure?.path || '', + testPathPatterns: failure ? [failure.path] : [], }); if (!this._manager.isActive()) { diff --git a/packages/jest-core/src/plugins/TestPathPattern.ts b/packages/jest-core/src/plugins/TestPathPattern.ts index a57d76488f68..8242e83e67fa 100644 --- a/packages/jest-core/src/plugins/TestPathPattern.ts +++ b/packages/jest-core/src/plugins/TestPathPattern.ts @@ -48,7 +48,7 @@ class TestPathPatternPlugin extends BaseWatchPlugin { testPathPatternPrompt.run( (value: string) => { - updateConfigAndRun({mode: 'watch', testPathPattern: value}); + updateConfigAndRun({mode: 'watch', testPathPattern: value, testPathPatterns: [value]}); res(); }, rej, diff --git a/packages/jest-core/src/plugins/UpdateSnapshotsInteractive.ts b/packages/jest-core/src/plugins/UpdateSnapshotsInteractive.ts index 25c8d3516cd9..16b3ecbe4579 100644 --- a/packages/jest-core/src/plugins/UpdateSnapshotsInteractive.ts +++ b/packages/jest-core/src/plugins/UpdateSnapshotsInteractive.ts @@ -71,6 +71,7 @@ class UpdateSnapshotInteractivePlugin extends BaseWatchPlugin { mode: 'watch', testNamePattern: assertion ? `^${assertion.fullName}$` : '', testPathPattern: assertion ? assertion.path : '', + testPathPatterns: assertion ? [assertion.path] : [], updateSnapshot: shouldUpdateSnapshot ? 'all' : 'none', }); diff --git a/packages/jest-core/src/plugins/__tests__/FailedTestsInteractive.test.js b/packages/jest-core/src/plugins/__tests__/FailedTestsInteractive.test.js index c416c423d1cd..379b919a79cf 100644 --- a/packages/jest-core/src/plugins/__tests__/FailedTestsInteractive.test.js +++ b/packages/jest-core/src/plugins/__tests__/FailedTestsInteractive.test.js @@ -41,6 +41,7 @@ describe('FailedTestsInteractive', () => { mode: 'watch', testNamePattern: `^${testAggregate.testResults[0].testResults[0].fullName}$`, testPathPattern: testAggregate.testResults[0].testFilePath, + testPathPatterns: [testAggregate.testResults[0].testFilePath], }); }); }); diff --git a/packages/jest-core/src/watch.ts b/packages/jest-core/src/watch.ts index 9237d5a78220..909595e8fe0b 100644 --- a/packages/jest-core/src/watch.ts +++ b/packages/jest-core/src/watch.ts @@ -121,6 +121,7 @@ export default async function watch( reporters, testNamePattern, testPathPattern, + testPathPatterns, updateSnapshot, verbose, }: AllowedConfigOptions = {}) => { @@ -141,6 +142,7 @@ export default async function watch( reporters, testNamePattern, testPathPattern, + testPathPatterns, updateSnapshot, verbose, }); @@ -405,6 +407,7 @@ export default async function watch( mode: 'watchAll', testNamePattern: '', testPathPattern: '', + testPathPatterns: [], }); startRun(globalConfig); break; @@ -413,6 +416,7 @@ export default async function watch( mode: 'watch', testNamePattern: '', testPathPattern: '', + testPathPatterns: [], }); break; case 'f': @@ -426,6 +430,7 @@ export default async function watch( mode: 'watch', testNamePattern: '', testPathPattern: '', + testPathPatterns: [], }); startRun(globalConfig); break; diff --git a/packages/jest-types/src/Config.ts b/packages/jest-types/src/Config.ts index 589e7b6cd3f3..7f16de8f9c78 100644 --- a/packages/jest-types/src/Config.ts +++ b/packages/jest-types/src/Config.ts @@ -413,6 +413,7 @@ export type GlobalConfig = { testFailureExitCode: number; testNamePattern?: string; testPathPattern: string; + testPathPatterns: Array; testResultsProcessor?: string; testSequencer: string; testTimeout?: number; diff --git a/packages/jest-watcher/src/types.ts b/packages/jest-watcher/src/types.ts index ed3c1950f6ef..718b5534c46f 100644 --- a/packages/jest-watcher/src/types.ts +++ b/packages/jest-watcher/src/types.ts @@ -63,6 +63,7 @@ export type AllowedConfigOptions = Partial< | 'reporters' | 'testNamePattern' | 'testPathPattern' + | 'testPathPatterns' | 'updateSnapshot' | 'verbose' > & {mode: 'watch' | 'watchAll'} diff --git a/packages/test-utils/src/config.ts b/packages/test-utils/src/config.ts index a27bf9c874b1..1e66e86e604b 100644 --- a/packages/test-utils/src/config.ts +++ b/packages/test-utils/src/config.ts @@ -56,6 +56,7 @@ const DEFAULT_GLOBAL_CONFIG: Config.GlobalConfig = { testFailureExitCode: 1, testNamePattern: '', testPathPattern: '', + testPathPatterns: [], testResultsProcessor: undefined, testSequencer: '@jest/test-sequencer', testTimeout: 5000, From 225b6fee82ac606c8d0552f08c9a5207b778eb88 Mon Sep 17 00:00:00 2001 From: Brandon Chinn Date: Tue, 25 Apr 2023 19:02:02 -0700 Subject: [PATCH 06/22] Change normalize tests to test testPathPatterns --- .../__tests__/__snapshots__/normalize.test.ts.snap | 4 ++-- .../jest-config/src/__tests__/normalize.test.ts | 14 +++++++------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/packages/jest-config/src/__tests__/__snapshots__/normalize.test.ts.snap b/packages/jest-config/src/__tests__/__snapshots__/normalize.test.ts.snap index 5d309a3ae54d..5c2f1af3ecd2 100644 --- a/packages/jest-config/src/__tests__/__snapshots__/normalize.test.ts.snap +++ b/packages/jest-config/src/__tests__/__snapshots__/normalize.test.ts.snap @@ -482,9 +482,9 @@ exports[`testMatch throws if testRegex and testMatch are both specified 1`] = ` " `; -exports[`testPathPattern ignores invalid regular expressions and logs a warning 1`] = `" Invalid testPattern /a(/i supplied. Running all tests instead."`; +exports[`testPathPatterns ignores invalid regular expressions and logs a warning 1`] = `" Invalid testPattern /a(/i supplied. Running all tests instead."`; -exports[`testPathPattern --testPathPattern ignores invalid regular expressions and logs a warning 1`] = `" Invalid testPattern /a(/i supplied. Running all tests instead."`; +exports[`testPathPatterns --testPathPattern ignores invalid regular expressions and logs a warning 1`] = `" Invalid testPattern /a(/i supplied. Running all tests instead."`; exports[`testTimeout should throw an error if timeout is a negative number 1`] = ` "Validation Error: diff --git a/packages/jest-config/src/__tests__/normalize.test.ts b/packages/jest-config/src/__tests__/normalize.test.ts index 4a8cc08c3439..f05d74ac6a9d 100644 --- a/packages/jest-config/src/__tests__/normalize.test.ts +++ b/packages/jest-config/src/__tests__/normalize.test.ts @@ -1585,7 +1585,7 @@ describe('watchPlugins', () => { }); }); -describe('testPathPattern', () => { +describe('testPathPatterns', () => { const initialOptions = {rootDir: '/root'}; const consoleLog = console.log; @@ -1600,7 +1600,7 @@ describe('testPathPattern', () => { it('defaults to empty', async () => { const {options} = await normalize(initialOptions, {} as Config.Argv); - expect(options.testPathPattern).toBe(''); + expect(options.testPathPatterns).toEqual([]); }); const cliOptions = [ @@ -1613,14 +1613,14 @@ describe('testPathPattern', () => { const argv = {[opt.property]: ['a/b']} as Config.Argv; const {options} = await normalize(initialOptions, argv); - expect(options.testPathPattern).toBe('a/b'); + expect(options.testPathPatterns).toEqual(['a/b']); }); it('ignores invalid regular expressions and logs a warning', async () => { const argv = {[opt.property]: ['a(']} as Config.Argv; const {options} = await normalize(initialOptions, argv); - expect(options.testPathPattern).toBe(''); + expect(options.testPathPatterns).toEqual([]); expect(jest.mocked(console.log).mock.calls[0][0]).toMatchSnapshot(); }); @@ -1628,7 +1628,7 @@ describe('testPathPattern', () => { const argv = {[opt.property]: ['a/b', 'c/d']} as Config.Argv; const {options} = await normalize(initialOptions, argv); - expect(options.testPathPattern).toBe('a/b|c/d'); + expect(options.testPathPatterns).toEqual(['a/b', 'c/d']); }); }); } @@ -1637,7 +1637,7 @@ describe('testPathPattern', () => { const argv = {_: [1]} as Config.Argv; const {options} = await normalize(initialOptions, argv); - expect(options.testPathPattern).toBe('1'); + expect(options.testPathPatterns).toEqual(['1']); }); it('joins multiple --testPathPatterns and ', async () => { @@ -1645,7 +1645,7 @@ describe('testPathPattern', () => { _: ['a', 'b'], testPathPattern: ['c', 'd'], } as Config.Argv); - expect(options.testPathPattern).toBe('a|b|c|d'); + expect(options.testPathPatterns).toEqual(['a', 'b', 'c', 'd']); }); it('gives precedence to --all', async () => { From 993fc509512a6c4f5340ba6fb17179f999e37905 Mon Sep 17 00:00:00 2001 From: Brandon Chinn Date: Tue, 25 Apr 2023 19:02:02 -0700 Subject: [PATCH 07/22] Replace testPathPatternToRegExp with TestPathPatterns --- packages/jest-core/src/SearchSource.ts | 19 +++++++++---------- packages/jest-core/src/watch.ts | 6 +++++- .../jest-reporters/src/SummaryReporter.ts | 11 +++++------ packages/jest-util/src/TestPathPatterns.ts | 14 +++++++++++++- packages/jest-util/src/index.ts | 1 - .../jest-util/src/testPathPatternToRegExp.ts | 17 ----------------- 6 files changed, 32 insertions(+), 36 deletions(-) delete mode 100644 packages/jest-util/src/testPathPatternToRegExp.ts diff --git a/packages/jest-core/src/SearchSource.ts b/packages/jest-core/src/SearchSource.ts index 619c396c15b5..a225904251dc 100644 --- a/packages/jest-core/src/SearchSource.ts +++ b/packages/jest-core/src/SearchSource.ts @@ -15,7 +15,7 @@ import {replaceRootDirInPath} from 'jest-config'; import {escapePathForRegex} from 'jest-regex-util'; import {DependencyResolver} from 'jest-resolve-dependencies'; import {buildSnapshotResolver} from 'jest-snapshot'; -import {globsToMatcher, testPathPatternToRegExp} from 'jest-util'; +import {TestPathPatterns, globsToMatcher} from 'jest-util'; import type {Filter, Stats, TestPathCases} from './types'; export type SearchResult = { @@ -110,7 +110,7 @@ export default class SearchSource { private _filterTestPathsWithStats( allPaths: Array, - testPathPattern: string, + testPathPatterns: TestPathPatterns, ): SearchResult { const data: { stats: Stats; @@ -128,10 +128,9 @@ export default class SearchSource { }; const testCases = Array.from(this._testPathCases); // clone - if (testPathPattern) { - const regex = testPathPatternToRegExp(testPathPattern); + if (testPathPatterns.isSet()) { testCases.push({ - isMatch: (path: string) => regex.test(path), + isMatch: (path: string) => testPathPatterns.isMatch(path), stat: 'testPathPattern', }); data.stats.testPathPattern = 0; @@ -152,10 +151,10 @@ export default class SearchSource { return data; } - private _getAllTestPaths(testPathPattern: string): SearchResult { + private _getAllTestPaths(testPathPatterns: TestPathPatterns): SearchResult { return this._filterTestPathsWithStats( toTests(this._context, this._context.hasteFS.getAllFiles()), - testPathPattern, + testPathPatterns, ); } @@ -163,8 +162,8 @@ export default class SearchSource { return this._testPathCases.every(testCase => testCase.isMatch(path)); } - findMatchingTests(testPathPattern: string): SearchResult { - return this._getAllTestPaths(testPathPattern); + findMatchingTests(testPathPatterns: TestPathPatterns): SearchResult { + return this._getAllTestPaths(testPathPatterns); } async findRelatedTests( @@ -288,7 +287,7 @@ export default class SearchSource { globalConfig.collectCoverage, ); } else { - return this.findMatchingTests(globalConfig.testPathPattern); + return this.findMatchingTests(new TestPathPatterns(globalConfig)); } } diff --git a/packages/jest-core/src/watch.ts b/packages/jest-core/src/watch.ts index 909595e8fe0b..1da48b3e0cb8 100644 --- a/packages/jest-core/src/watch.ts +++ b/packages/jest-core/src/watch.ts @@ -15,6 +15,7 @@ import type {Config} from '@jest/types'; import type {IHasteMap as HasteMap} from 'jest-haste-map'; import {formatExecError} from 'jest-message-util'; import { + TestPathPatterns, isInteractive, preRunMessage, requireOrImportModule, @@ -229,9 +230,12 @@ export default async function watch( const emitFileChange = () => { if (hooks.isUsed('onFileChange')) { + const testPathPatterns = new TestPathPatterns([]); const projects = searchSources.map(({context, searchSource}) => ({ config: context.config, - testPaths: searchSource.findMatchingTests('').tests.map(t => t.path), + testPaths: searchSource + .findMatchingTests(testPathPatterns) + .tests.map(t => t.path), })); hooks.getEmitter().onFileChange({projects}); } diff --git a/packages/jest-reporters/src/SummaryReporter.ts b/packages/jest-reporters/src/SummaryReporter.ts index 3c43b62367d9..6fe345842843 100644 --- a/packages/jest-reporters/src/SummaryReporter.ts +++ b/packages/jest-reporters/src/SummaryReporter.ts @@ -12,7 +12,7 @@ import type { TestContext, } from '@jest/test-result'; import type {Config} from '@jest/types'; -import {testPathPatternToRegExp} from 'jest-util'; +import {TestPathPatterns} from 'jest-util'; import BaseReporter from './BaseReporter'; import getResultHeader from './getResultHeader'; import getSnapshotSummary from './getSnapshotSummary'; @@ -212,15 +212,14 @@ export default class SummaryReporter extends BaseReporter { testContexts: Set, globalConfig: Config.GlobalConfig, ) { + const testPathPatterns = new TestPathPatterns(globalConfig); + const getMatchingTestsInfo = () => { const prefix = globalConfig.findRelatedTests ? ' related to files matching ' : ' matching '; - return ( - chalk.dim(prefix) + - testPathPatternToRegExp(globalConfig.testPathPattern).toString() - ); + return chalk.dim(prefix) + testPathPatterns.toPretty(); }; let testInfo = ''; @@ -229,7 +228,7 @@ export default class SummaryReporter extends BaseReporter { testInfo = chalk.dim(' within paths'); } else if (globalConfig.onlyChanged) { testInfo = chalk.dim(' related to changed files'); - } else if (globalConfig.testPathPattern) { + } else if (testPathPatterns.isSet()) { testInfo = getMatchingTestsInfo(); } diff --git a/packages/jest-util/src/TestPathPatterns.ts b/packages/jest-util/src/TestPathPatterns.ts index 142d86192a58..fb20d9762ff3 100644 --- a/packages/jest-util/src/TestPathPatterns.ts +++ b/packages/jest-util/src/TestPathPatterns.ts @@ -5,14 +5,26 @@ * LICENSE file in the root directory of this source tree. */ +import type {Config} from '@jest/types'; import {replacePathSepForRegex} from 'jest-regex-util'; +type PatternsFullConfig = Pick; + export default class TestPathPatterns { readonly patterns: Array; private _regexString: string | null = null; - constructor(patterns: Array) { + constructor(patterns: Array); + constructor(config: PatternsFullConfig); + constructor(patternsOrConfig: Array | PatternsFullConfig) { + let patterns; + if (Array.isArray(patternsOrConfig)) { + patterns = patternsOrConfig; + } else { + patterns = patternsOrConfig.testPathPatterns; + } + this.patterns = patterns; } diff --git a/packages/jest-util/src/index.ts b/packages/jest-util/src/index.ts index 850d96c213f1..ca4ea9ec29d1 100644 --- a/packages/jest-util/src/index.ts +++ b/packages/jest-util/src/index.ts @@ -22,7 +22,6 @@ export {default as convertDescriptorToString} from './convertDescriptorToString' export {specialChars}; export {default as replacePathSepForGlob} from './replacePathSepForGlob'; export {default as TestPathPatterns} from './TestPathPatterns'; -export {default as testPathPatternToRegExp} from './testPathPatternToRegExp'; export {default as globsToMatcher} from './globsToMatcher'; export {preRunMessage}; export {default as pluralize} from './pluralize'; diff --git a/packages/jest-util/src/testPathPatternToRegExp.ts b/packages/jest-util/src/testPathPatternToRegExp.ts deleted file mode 100644 index 433779ab206d..000000000000 --- a/packages/jest-util/src/testPathPatternToRegExp.ts +++ /dev/null @@ -1,17 +0,0 @@ -/** - * Copyright (c) Meta Platforms, Inc. and affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - */ - -import type {Config} from '@jest/types'; - -// Because we serialize/deserialize globalConfig when we spawn workers, -// we can't pass regular expression. Using this shared function on both sides -// will ensure that we produce consistent regexp for testPathPattern. -export default function testPathPatternToRegExp( - testPathPattern: Config.GlobalConfig['testPathPattern'], -): RegExp { - return new RegExp(testPathPattern, 'i'); -} From 518c357538c4c996823d2d41a620ba8443ca0a8c Mon Sep 17 00:00:00 2001 From: Brandon Chinn Date: Tue, 25 Apr 2023 19:02:03 -0700 Subject: [PATCH 08/22] Update testPathPatterns in updateGlobalConfig --- packages/jest-core/src/lib/updateGlobalConfig.ts | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/packages/jest-core/src/lib/updateGlobalConfig.ts b/packages/jest-core/src/lib/updateGlobalConfig.ts index a81990358755..bfe03f26b790 100644 --- a/packages/jest-core/src/lib/updateGlobalConfig.ts +++ b/packages/jest-core/src/lib/updateGlobalConfig.ts @@ -6,7 +6,7 @@ */ import type {Config} from '@jest/types'; -import {replacePathSepForRegex} from 'jest-regex-util'; +import {TestPathPatterns} from 'jest-util'; import type {AllowedConfigOptions} from 'jest-watcher'; type ExtraConfigOptions = Partial< @@ -31,15 +31,14 @@ export default function updateGlobalConfig( newConfig.testNamePattern = options.testNamePattern || ''; } - if (options.testPathPattern !== undefined) { - newConfig.testPathPattern = - replacePathSepForRegex(options.testPathPattern) || ''; + if (options.testPathPatterns !== undefined) { + newConfig.testPathPatterns = options.testPathPatterns; } newConfig.onlyChanged = !newConfig.watchAll && !newConfig.testNamePattern && - !newConfig.testPathPattern; + !new TestPathPatterns(newConfig).isSet(); if (typeof options.bail === 'boolean') { newConfig.bail = options.bail ? 1 : 0; From e347e724d9a379d10588ef9988e98a7134bfc24a Mon Sep 17 00:00:00 2001 From: Brandon Chinn Date: Tue, 25 Apr 2023 19:02:03 -0700 Subject: [PATCH 09/22] Update docs + tests to use globalConfig.testPathPatterns --- docs/Configuration.md | 4 ++-- docs/WatchPlugins.md | 2 +- e2e/__tests__/globalSetup.test.ts | 12 ++++-------- e2e/__tests__/globalTeardown.test.ts | 10 ++++------ e2e/global-setup/invalidSetupWithNamedExport.js | 2 +- e2e/global-setup/setupWithConfig.js | 2 +- e2e/global-setup/setupWithDefaultExport.js | 2 +- .../invalidTeardownWithNamedExport.js | 2 +- e2e/global-teardown/teardownWithConfig.js | 2 +- e2e/global-teardown/teardownWithDefaultExport.js | 2 +- packages/jest-core/src/__tests__/watch.test.js | 2 +- 11 files changed, 18 insertions(+), 24 deletions(-) diff --git a/docs/Configuration.md b/docs/Configuration.md index 813dd8c33c45..6f682a932593 100644 --- a/docs/Configuration.md +++ b/docs/Configuration.md @@ -787,7 +787,7 @@ While code transformation is applied to the linked setup-file, Jest will **not** ```js title="setup.js" module.exports = async function (globalConfig, projectConfig) { - console.log(globalConfig.testPathPattern); + console.log(globalConfig.testPathPatterns); console.log(projectConfig.cache); // Set reference to mongod in order to close the server during teardown. @@ -797,7 +797,7 @@ module.exports = async function (globalConfig, projectConfig) { ```js title="teardown.js" module.exports = async function (globalConfig, projectConfig) { - console.log(globalConfig.testPathPattern); + console.log(globalConfig.testPathPatterns); console.log(projectConfig.cache); await globalThis.__MONGOD__.stop(); diff --git a/docs/WatchPlugins.md b/docs/WatchPlugins.md index 57ddeaec07e4..ff7378860f8e 100644 --- a/docs/WatchPlugins.md +++ b/docs/WatchPlugins.md @@ -172,7 +172,7 @@ For stability and safety reasons, only part of the global configuration keys can - [`onlyFailures`](configuration#onlyfailures-boolean) - [`reporters`](configuration#reporters-arraymodulename--modulename-options) - [`testNamePattern`](cli#--testnamepatternregex) -- [`testPathPattern`](cli#--testpathpatternregex) +- [`testPathPatterns`](cli#--testpathpatternregex) - [`updateSnapshot`](cli#--updatesnapshot) - [`verbose`](configuration#verbose-boolean) diff --git a/e2e/__tests__/globalSetup.test.ts b/e2e/__tests__/globalSetup.test.ts index f7c4a29eb641..d85dc352aa85 100644 --- a/e2e/__tests__/globalSetup.test.ts +++ b/e2e/__tests__/globalSetup.test.ts @@ -83,15 +83,13 @@ test('jest throws an error when globalSetup does not export a function', () => { test('globalSetup function gets global config object and project config as parameters', () => { const setupPath = path.resolve(e2eDir, 'setupWithConfig.js'); - const testPathPattern = 'pass'; - const result = runJest(e2eDir, [ `--globalSetup=${setupPath}`, - `--testPathPattern=${testPathPattern}`, + '--testPathPattern=pass', '--cache=true', ]); - expect(result.stdout).toBe(`${testPathPattern}\ntrue`); + expect(result.stdout).toBe("[ 'pass' ]\ntrue"); }); test('should call globalSetup function of multiple projects', () => { @@ -140,15 +138,13 @@ test('should not call any globalSetup if there are no tests to run', () => { test('globalSetup works with default export', () => { const setupPath = path.resolve(e2eDir, 'setupWithDefaultExport.js'); - const testPathPattern = 'pass'; - const result = runJest(e2eDir, [ `--globalSetup=${setupPath}`, - `--testPathPattern=${testPathPattern}`, + '--testPathPattern=pass', '--cache=true', ]); - expect(result.stdout).toBe(`${testPathPattern}\ntrue`); + expect(result.stdout).toBe("[ 'pass' ]\ntrue"); }); test('globalSetup throws with named export', () => { diff --git a/e2e/__tests__/globalTeardown.test.ts b/e2e/__tests__/globalTeardown.test.ts index 360200f0a583..152b83d255b2 100644 --- a/e2e/__tests__/globalTeardown.test.ts +++ b/e2e/__tests__/globalTeardown.test.ts @@ -67,15 +67,13 @@ test('jest throws an error when globalTeardown does not export a function', () = test('globalSetup function gets global config object and project config as parameters', () => { const teardownPath = path.resolve(e2eDir, 'teardownWithConfig.js'); - const testPathPattern = 'pass'; - const result = runJest(e2eDir, [ `--globalTeardown=${teardownPath}`, - `--testPathPattern=${testPathPattern}`, + '--testPathPattern=pass', '--cache=true', ]); - expect(result.stdout).toBe(`${testPathPattern}\ntrue`); + expect(result.stdout).toBe("[ 'pass' ]\ntrue"); }); test('should call globalTeardown function of multiple projects', () => { @@ -112,11 +110,11 @@ test('globalTeardown works with default export', () => { const result = runJest(e2eDir, [ `--globalTeardown=${teardownPath}`, - `--testPathPattern=${testPathPattern}`, + '--testPathPattern=pass', '--cache=true', ]); - expect(result.stdout).toBe(`${testPathPattern}\ntrue`); + expect(result.stdout).toBe("[ 'pass' ]\ntrue"); }); test('globalTeardown throws with named export', () => { diff --git a/e2e/global-setup/invalidSetupWithNamedExport.js b/e2e/global-setup/invalidSetupWithNamedExport.js index 1ba0caead847..5501dc11d1c2 100644 --- a/e2e/global-setup/invalidSetupWithNamedExport.js +++ b/e2e/global-setup/invalidSetupWithNamedExport.js @@ -6,7 +6,7 @@ */ function invalidSetupWithNamedExport(jestConfig): void { - console.log(jestConfig.testPathPattern); + console.log(jestConfig.testPathPatterns); } export {invalidSetupWithNamedExport}; diff --git a/e2e/global-setup/setupWithConfig.js b/e2e/global-setup/setupWithConfig.js index 465ea45407c5..ff9b308107b1 100644 --- a/e2e/global-setup/setupWithConfig.js +++ b/e2e/global-setup/setupWithConfig.js @@ -6,6 +6,6 @@ */ module.exports = function (globalConfig, projectConfig) { - console.log(globalConfig.testPathPattern); + console.log(globalConfig.testPathPatterns); console.log(projectConfig.cache); }; diff --git a/e2e/global-setup/setupWithDefaultExport.js b/e2e/global-setup/setupWithDefaultExport.js index 4f5b9b90f4e6..85b2c298a4d7 100644 --- a/e2e/global-setup/setupWithDefaultExport.js +++ b/e2e/global-setup/setupWithDefaultExport.js @@ -6,6 +6,6 @@ */ export default function (globalConfig, projectConfig): void { - console.log(globalConfig.testPathPattern); + console.log(globalConfig.testPathPatterns); console.log(projectConfig.cache); } diff --git a/e2e/global-teardown/invalidTeardownWithNamedExport.js b/e2e/global-teardown/invalidTeardownWithNamedExport.js index 718656b4bddf..cc1abef111cd 100644 --- a/e2e/global-teardown/invalidTeardownWithNamedExport.js +++ b/e2e/global-teardown/invalidTeardownWithNamedExport.js @@ -6,7 +6,7 @@ */ function invalidTeardownWithNamedExport(jestConfig): void { - console.log(jestConfig.testPathPattern); + console.log(jestConfig.testPathPatterns); } export {invalidTeardownWithNamedExport}; diff --git a/e2e/global-teardown/teardownWithConfig.js b/e2e/global-teardown/teardownWithConfig.js index 465ea45407c5..ff9b308107b1 100644 --- a/e2e/global-teardown/teardownWithConfig.js +++ b/e2e/global-teardown/teardownWithConfig.js @@ -6,6 +6,6 @@ */ module.exports = function (globalConfig, projectConfig) { - console.log(globalConfig.testPathPattern); + console.log(globalConfig.testPathPatterns); console.log(projectConfig.cache); }; diff --git a/e2e/global-teardown/teardownWithDefaultExport.js b/e2e/global-teardown/teardownWithDefaultExport.js index 4f5b9b90f4e6..85b2c298a4d7 100644 --- a/e2e/global-teardown/teardownWithDefaultExport.js +++ b/e2e/global-teardown/teardownWithDefaultExport.js @@ -6,6 +6,6 @@ */ export default function (globalConfig, projectConfig): void { - console.log(globalConfig.testPathPattern); + console.log(globalConfig.testPathPatterns); console.log(projectConfig.cache); } diff --git a/packages/jest-core/src/__tests__/watch.test.js b/packages/jest-core/src/__tests__/watch.test.js index e11dbe59d097..07385b59a808 100644 --- a/packages/jest-core/src/__tests__/watch.test.js +++ b/packages/jest-core/src/__tests__/watch.test.js @@ -152,7 +152,7 @@ describe('Watch mode flows', () => { }); it('Correctly passing test path pattern', async () => { - globalConfig.testPathPattern = 'test-*'; + globalConfig.testPathPatterns = ['test-*']; await watch(globalConfig, contexts, pipe, hasteMapInstances, stdin); From 6713c2ca79a1056112dd8a3092f5aa353d557bef Mon Sep 17 00:00:00 2001 From: Brandon Chinn Date: Wed, 20 Sep 2023 17:54:38 -0700 Subject: [PATCH 10/22] Replace remaining usages of globalConfig.testPathPattern --- e2e/__tests__/multiProjectRunner.test.ts | 2 +- .../__snapshots__/getNoTestsFoundMessage.test.ts.snap | 6 +++--- packages/jest-core/src/getNoTestFound.ts | 5 +++-- packages/jest-core/src/getNoTestFoundVerbose.ts | 5 +++-- packages/jest-core/src/lib/activeFiltersMessage.ts | 11 ++++++----- packages/jest-core/src/watch.ts | 5 +++-- 6 files changed, 19 insertions(+), 15 deletions(-) diff --git a/e2e/__tests__/multiProjectRunner.test.ts b/e2e/__tests__/multiProjectRunner.test.ts index 84a4e79dd928..b9dea4a2fadd 100644 --- a/e2e/__tests__/multiProjectRunner.test.ts +++ b/e2e/__tests__/multiProjectRunner.test.ts @@ -155,7 +155,7 @@ test('"No tests found" message for projects', () => { 'project1', 'project2', ]); - expect(verboseOutput).toContain('Pattern: xyz321 - 0 matches'); + expect(verboseOutput).toContain('Pattern: /xyz321/i - 0 matches'); const {stdout} = runJest(DIR, [ '--no-watchman', 'xyz321', diff --git a/packages/jest-core/src/__tests__/__snapshots__/getNoTestsFoundMessage.test.ts.snap b/packages/jest-core/src/__tests__/__snapshots__/getNoTestsFoundMessage.test.ts.snap index 059aa966f758..2d6a1af3e481 100644 --- a/packages/jest-core/src/__tests__/__snapshots__/getNoTestsFoundMessage.test.ts.snap +++ b/packages/jest-core/src/__tests__/__snapshots__/getNoTestsFoundMessage.test.ts.snap @@ -23,7 +23,7 @@ Object { Run with \`--passWithNoTests\` to exit with code 0 In /root/dir 0 files checked across 0 projects. Run with \`--verbose\` for more details. -Pattern: /path/pattern - 0 matches", +Pattern: /\\/path\\/pattern/i - 0 matches", } `; @@ -47,7 +47,7 @@ Object { "message": "No tests found, exiting with code 1 Run with \`--passWithNoTests\` to exit with code 0 -Pattern: /path/pattern - 0 matches", +Pattern: /\\/path\\/pattern/i - 0 matches", } `; @@ -58,6 +58,6 @@ Object { Run with \`--passWithNoTests\` to exit with code 0 In /root/dir 0 files checked across 0 projects. Run with \`--verbose\` for more details. -Pattern: /path/pattern - 0 matches", +Pattern: /\\/path\\/pattern/i - 0 matches", } `; diff --git a/packages/jest-core/src/getNoTestFound.ts b/packages/jest-core/src/getNoTestFound.ts index 931de697aa24..3d5a187e3cff 100644 --- a/packages/jest-core/src/getNoTestFound.ts +++ b/packages/jest-core/src/getNoTestFound.ts @@ -7,7 +7,7 @@ import chalk = require('chalk'); import type {Config} from '@jest/types'; -import {pluralize} from 'jest-util'; +import {TestPathPatterns, pluralize} from 'jest-util'; import type {TestRunData} from './types'; export default function getNoTestFound( @@ -26,8 +26,9 @@ export default function getNoTestFound( .map(p => `"${p}"`) .join(', ')}`; } else { + const testPathPatterns = new TestPathPatterns(globalConfig); dataMessage = `Pattern: ${chalk.yellow( - globalConfig.testPathPattern, + testPathPatterns.toPretty(), )} - 0 matches`; } diff --git a/packages/jest-core/src/getNoTestFoundVerbose.ts b/packages/jest-core/src/getNoTestFoundVerbose.ts index 0f9ef7f1de00..ca98f60075e6 100644 --- a/packages/jest-core/src/getNoTestFoundVerbose.ts +++ b/packages/jest-core/src/getNoTestFoundVerbose.ts @@ -7,7 +7,7 @@ import chalk = require('chalk'); import type {Config} from '@jest/types'; -import {pluralize} from 'jest-util'; +import {TestPathPatterns, pluralize} from 'jest-util'; import type {Stats, TestRunData} from './types'; export default function getNoTestFoundVerbose( @@ -56,8 +56,9 @@ export default function getNoTestFoundVerbose( .map(p => `"${p}"`) .join(', ')}`; } else { + const testPathPatterns = new TestPathPatterns(globalConfig); dataMessage = `Pattern: ${chalk.yellow( - globalConfig.testPathPattern, + testPathPatterns.toPretty(), )} - 0 matches`; } diff --git a/packages/jest-core/src/lib/activeFiltersMessage.ts b/packages/jest-core/src/lib/activeFiltersMessage.ts index 714adcff7d86..0b44c259f673 100644 --- a/packages/jest-core/src/lib/activeFiltersMessage.ts +++ b/packages/jest-core/src/lib/activeFiltersMessage.ts @@ -7,14 +7,15 @@ import chalk = require('chalk'); import type {Config} from '@jest/types'; -import {isNonNullable} from 'jest-util'; +import {TestPathPatterns, isNonNullable} from 'jest-util'; const activeFilters = (globalConfig: Config.GlobalConfig): string => { - const {testNamePattern, testPathPattern} = globalConfig; - if (testNamePattern || testPathPattern) { + const {testNamePattern} = globalConfig; + const testPathPatterns = new TestPathPatterns(globalConfig); + if (testNamePattern || testPathPatterns.isSet()) { const filters = [ - testPathPattern - ? chalk.dim('filename ') + chalk.yellow(`/${testPathPattern}/`) + testPathPatterns.isSet() + ? chalk.dim('filename ') + chalk.yellow(testPathPatterns.toPretty()) : null, testNamePattern ? chalk.dim('test name ') + chalk.yellow(`/${testNamePattern}/`) diff --git a/packages/jest-core/src/watch.ts b/packages/jest-core/src/watch.ts index 1da48b3e0cb8..c0c6e36954f6 100644 --- a/packages/jest-core/src/watch.ts +++ b/packages/jest-core/src/watch.ts @@ -537,10 +537,11 @@ const usage = ( watchPlugins: Array, delimiter = '\n', ) => { + const testPathPatterns = new TestPathPatterns(globalConfig); const messages = [ activeFilters(globalConfig), - globalConfig.testPathPattern || globalConfig.testNamePattern + testPathPatterns.isSet() || globalConfig.testNamePattern ? `${chalk.dim(' \u203A Press ')}c${chalk.dim(' to clear filters.')}` : null, `\n${chalk.bold('Watch Usage')}`, @@ -558,7 +559,7 @@ const usage = ( )}`, (globalConfig.watchAll || - globalConfig.testPathPattern || + testPathPatterns.isSet() || globalConfig.testNamePattern) && !globalConfig.noSCM ? `${chalk.dim(' \u203A Press ')}o${chalk.dim( From a4efd8782ff3bc5238140c645de0e83594744a16 Mon Sep 17 00:00:00 2001 From: Brandon Chinn Date: Tue, 25 Apr 2023 19:02:03 -0700 Subject: [PATCH 11/22] Remove testPathPattern from GlobalConfig --- e2e/__tests__/__snapshots__/showConfig.test.ts.snap | 1 - packages/jest-config/src/index.ts | 1 - packages/jest-config/src/normalize.ts | 1 - packages/jest-core/src/__tests__/SearchSource.test.ts | 1 - .../__snapshots__/watchFilenamePatternMode.test.js.snap | 1 - .../jest-core/src/__tests__/getNoTestsFoundMessage.test.ts | 1 - packages/jest-core/src/__tests__/watch.test.js | 3 --- .../__tests__/__snapshots__/logDebugMessages.test.ts.snap | 1 - packages/jest-core/src/plugins/FailedTestsInteractive.ts | 1 - packages/jest-core/src/plugins/TestPathPattern.ts | 2 +- packages/jest-core/src/plugins/UpdateSnapshotsInteractive.ts | 1 - .../src/plugins/__tests__/FailedTestsInteractive.test.js | 1 - packages/jest-core/src/watch.ts | 5 ----- packages/jest-types/src/Config.ts | 1 - packages/jest-util/src/TestPathPatterns.ts | 2 +- packages/jest-watcher/src/types.ts | 1 - packages/test-utils/src/config.ts | 1 - 17 files changed, 2 insertions(+), 23 deletions(-) diff --git a/e2e/__tests__/__snapshots__/showConfig.test.ts.snap b/e2e/__tests__/__snapshots__/showConfig.test.ts.snap index fad9b1278dc3..c50c1778805d 100644 --- a/e2e/__tests__/__snapshots__/showConfig.test.ts.snap +++ b/e2e/__tests__/__snapshots__/showConfig.test.ts.snap @@ -138,7 +138,6 @@ exports[`--showConfig outputs config info and exits 1`] = ` "printBasicPrototype": false }, "testFailureExitCode": 1, - "testPathPattern": "", "testPathPatterns": [], "testSequencer": "<>/jest-test-sequencer/build/index.js", "updateSnapshot": "none", diff --git a/packages/jest-config/src/index.ts b/packages/jest-config/src/index.ts index 66fd142c4b41..7be4d3708258 100644 --- a/packages/jest-config/src/index.ts +++ b/packages/jest-config/src/index.ts @@ -131,7 +131,6 @@ const groupOptions = ( snapshotFormat: options.snapshotFormat, testFailureExitCode: options.testFailureExitCode, testNamePattern: options.testNamePattern, - testPathPattern: options.testPathPattern, testPathPatterns: options.testPathPatterns, testResultsProcessor: options.testResultsProcessor, testSequencer: options.testSequencer, diff --git a/packages/jest-config/src/normalize.ts b/packages/jest-config/src/normalize.ts index b21e5ad2eed5..dd1bccb6d5ab 100644 --- a/packages/jest-config/src/normalize.ts +++ b/packages/jest-config/src/normalize.ts @@ -999,7 +999,6 @@ export default async function normalize( newOptions.nonFlagArgs = argv._?.map(arg => `${arg}`); const testPathPatterns = buildTestPathPatterns(argv); newOptions.testPathPatterns = testPathPatterns.patterns; - newOptions.testPathPattern = testPathPatterns.regexString; newOptions.json = !!argv.json; newOptions.testFailureExitCode = parseInt( diff --git a/packages/jest-core/src/__tests__/SearchSource.test.ts b/packages/jest-core/src/__tests__/SearchSource.test.ts index 01b013505929..21ef1683e5fa 100644 --- a/packages/jest-core/src/__tests__/SearchSource.test.ts +++ b/packages/jest-core/src/__tests__/SearchSource.test.ts @@ -109,7 +109,6 @@ describe('SearchSource', () => { const {searchSource, config} = await initSearchSource(initialOptions); const {tests: paths} = await searchSource.getTestPaths({ ...config, - testPathPattern: '', testPathPatterns: [], }); return paths.map(({path: p}) => path.relative(rootDir, p)).sort(); diff --git a/packages/jest-core/src/__tests__/__snapshots__/watchFilenamePatternMode.test.js.snap b/packages/jest-core/src/__tests__/__snapshots__/watchFilenamePatternMode.test.js.snap index e505641b8604..2f831f62a006 100644 --- a/packages/jest-core/src/__tests__/__snapshots__/watchFilenamePatternMode.test.js.snap +++ b/packages/jest-core/src/__tests__/__snapshots__/watchFilenamePatternMode.test.js.snap @@ -92,7 +92,6 @@ exports[`Watch mode flows Pressing "P" enters pattern mode 9`] = ` Object { "onlyChanged": false, "passWithNoTests": true, - "testPathPattern": "p.*3", "testPathPatterns": Array [ "p.*3", ], diff --git a/packages/jest-core/src/__tests__/getNoTestsFoundMessage.test.ts b/packages/jest-core/src/__tests__/getNoTestsFoundMessage.test.ts index f0f026c802bf..19fd684dea0a 100644 --- a/packages/jest-core/src/__tests__/getNoTestsFoundMessage.test.ts +++ b/packages/jest-core/src/__tests__/getNoTestsFoundMessage.test.ts @@ -18,7 +18,6 @@ describe('getNoTestsFoundMessage', () => { function createGlobalConfig(options?: Partial) { return makeGlobalConfig({ rootDir: '/root/dir', - testPathPattern: '/path/pattern', testPathPatterns: ['/path/pattern'], ...options, }); diff --git a/packages/jest-core/src/__tests__/watch.test.js b/packages/jest-core/src/__tests__/watch.test.js index 07385b59a808..8920963123a1 100644 --- a/packages/jest-core/src/__tests__/watch.test.js +++ b/packages/jest-core/src/__tests__/watch.test.js @@ -671,7 +671,6 @@ describe('Watch mode flows', () => { ${'✖︎'} | ${'skipFilter'} ${'✖︎'} | ${'testFailureExitCode'} ${'✔︎'} | ${'testNamePattern'} - ${'✔︎'} | ${'testPathPattern'} ${'✔︎'} | ${'testPathPatterns'} ${'✖︎'} | ${'testResultsProcessor'} ${'✔︎'} | ${'updateSnapshot'} @@ -899,7 +898,6 @@ describe('Watch mode flows', () => { await nextTick(); expect(runJestMock.mock.calls[0][0].globalConfig).toMatchObject({ - testPathPattern: 'file', testPathPatterns: ['file'], watch: true, watchAll: false, @@ -924,7 +922,6 @@ describe('Watch mode flows', () => { expect(runJestMock.mock.calls[1][0].globalConfig).toMatchObject({ testNamePattern: 'test', - testPathPattern: 'file', testPathPatterns: ['file'], watch: true, watchAll: false, diff --git a/packages/jest-core/src/lib/__tests__/__snapshots__/logDebugMessages.test.ts.snap b/packages/jest-core/src/lib/__tests__/__snapshots__/logDebugMessages.test.ts.snap index 8621ebf28bc5..0087fa7f5351 100644 --- a/packages/jest-core/src/lib/__tests__/__snapshots__/logDebugMessages.test.ts.snap +++ b/packages/jest-core/src/lib/__tests__/__snapshots__/logDebugMessages.test.ts.snap @@ -109,7 +109,6 @@ exports[`prints the config object 1`] = ` "snapshotFormat": {}, "testFailureExitCode": 1, "testNamePattern": "", - "testPathPattern": "", "testPathPatterns": [], "testSequencer": "@jest/test-sequencer", "testTimeout": 5000, diff --git a/packages/jest-core/src/plugins/FailedTestsInteractive.ts b/packages/jest-core/src/plugins/FailedTestsInteractive.ts index 6effde8159c0..864f78a7d86c 100644 --- a/packages/jest-core/src/plugins/FailedTestsInteractive.ts +++ b/packages/jest-core/src/plugins/FailedTestsInteractive.ts @@ -58,7 +58,6 @@ export default class FailedTestsInteractivePlugin extends BaseWatchPlugin { updateConfigAndRun({ mode: 'watch', testNamePattern: failure ? `^${failure.fullName}$` : '', - testPathPattern: failure?.path || '', testPathPatterns: failure ? [failure.path] : [], }); diff --git a/packages/jest-core/src/plugins/TestPathPattern.ts b/packages/jest-core/src/plugins/TestPathPattern.ts index 8242e83e67fa..c777b7183027 100644 --- a/packages/jest-core/src/plugins/TestPathPattern.ts +++ b/packages/jest-core/src/plugins/TestPathPattern.ts @@ -48,7 +48,7 @@ class TestPathPatternPlugin extends BaseWatchPlugin { testPathPatternPrompt.run( (value: string) => { - updateConfigAndRun({mode: 'watch', testPathPattern: value, testPathPatterns: [value]}); + updateConfigAndRun({mode: 'watch', testPathPatterns: [value]}); res(); }, rej, diff --git a/packages/jest-core/src/plugins/UpdateSnapshotsInteractive.ts b/packages/jest-core/src/plugins/UpdateSnapshotsInteractive.ts index 16b3ecbe4579..44eeaf20c572 100644 --- a/packages/jest-core/src/plugins/UpdateSnapshotsInteractive.ts +++ b/packages/jest-core/src/plugins/UpdateSnapshotsInteractive.ts @@ -70,7 +70,6 @@ class UpdateSnapshotInteractivePlugin extends BaseWatchPlugin { updateConfigAndRun({ mode: 'watch', testNamePattern: assertion ? `^${assertion.fullName}$` : '', - testPathPattern: assertion ? assertion.path : '', testPathPatterns: assertion ? [assertion.path] : [], updateSnapshot: shouldUpdateSnapshot ? 'all' : 'none', diff --git a/packages/jest-core/src/plugins/__tests__/FailedTestsInteractive.test.js b/packages/jest-core/src/plugins/__tests__/FailedTestsInteractive.test.js index 379b919a79cf..4b64a2a2c3dc 100644 --- a/packages/jest-core/src/plugins/__tests__/FailedTestsInteractive.test.js +++ b/packages/jest-core/src/plugins/__tests__/FailedTestsInteractive.test.js @@ -40,7 +40,6 @@ describe('FailedTestsInteractive', () => { expect(mockUpdate).toHaveBeenCalledWith({ mode: 'watch', testNamePattern: `^${testAggregate.testResults[0].testResults[0].fullName}$`, - testPathPattern: testAggregate.testResults[0].testFilePath, testPathPatterns: [testAggregate.testResults[0].testFilePath], }); }); diff --git a/packages/jest-core/src/watch.ts b/packages/jest-core/src/watch.ts index c0c6e36954f6..be3d042aa194 100644 --- a/packages/jest-core/src/watch.ts +++ b/packages/jest-core/src/watch.ts @@ -121,7 +121,6 @@ export default async function watch( onlyFailures, reporters, testNamePattern, - testPathPattern, testPathPatterns, updateSnapshot, verbose, @@ -142,7 +141,6 @@ export default async function watch( onlyFailures, reporters, testNamePattern, - testPathPattern, testPathPatterns, updateSnapshot, verbose, @@ -410,7 +408,6 @@ export default async function watch( globalConfig = updateGlobalConfig(globalConfig, { mode: 'watchAll', testNamePattern: '', - testPathPattern: '', testPathPatterns: [], }); startRun(globalConfig); @@ -419,7 +416,6 @@ export default async function watch( updateConfigAndRun({ mode: 'watch', testNamePattern: '', - testPathPattern: '', testPathPatterns: [], }); break; @@ -433,7 +429,6 @@ export default async function watch( globalConfig = updateGlobalConfig(globalConfig, { mode: 'watch', testNamePattern: '', - testPathPattern: '', testPathPatterns: [], }); startRun(globalConfig); diff --git a/packages/jest-types/src/Config.ts b/packages/jest-types/src/Config.ts index 7f16de8f9c78..b444716e4c6a 100644 --- a/packages/jest-types/src/Config.ts +++ b/packages/jest-types/src/Config.ts @@ -412,7 +412,6 @@ export type GlobalConfig = { errorOnDeprecated: boolean; testFailureExitCode: number; testNamePattern?: string; - testPathPattern: string; testPathPatterns: Array; testResultsProcessor?: string; testSequencer: string; diff --git a/packages/jest-util/src/TestPathPatterns.ts b/packages/jest-util/src/TestPathPatterns.ts index fb20d9762ff3..2770b8728b8d 100644 --- a/packages/jest-util/src/TestPathPatterns.ts +++ b/packages/jest-util/src/TestPathPatterns.ts @@ -28,7 +28,7 @@ export default class TestPathPatterns { this.patterns = patterns; } - get regexString(): string { + private get regexString(): string { if (this._regexString !== null) { return this._regexString; } diff --git a/packages/jest-watcher/src/types.ts b/packages/jest-watcher/src/types.ts index 718b5534c46f..fe69d836187b 100644 --- a/packages/jest-watcher/src/types.ts +++ b/packages/jest-watcher/src/types.ts @@ -62,7 +62,6 @@ export type AllowedConfigOptions = Partial< | 'onlyFailures' | 'reporters' | 'testNamePattern' - | 'testPathPattern' | 'testPathPatterns' | 'updateSnapshot' | 'verbose' diff --git a/packages/test-utils/src/config.ts b/packages/test-utils/src/config.ts index 1e66e86e604b..5aff9e0a15af 100644 --- a/packages/test-utils/src/config.ts +++ b/packages/test-utils/src/config.ts @@ -55,7 +55,6 @@ const DEFAULT_GLOBAL_CONFIG: Config.GlobalConfig = { snapshotFormat: {}, testFailureExitCode: 1, testNamePattern: '', - testPathPattern: '', testPathPatterns: [], testResultsProcessor: undefined, testSequencer: '@jest/test-sequencer', From ae8ee58f4b8bc3bfc9568595d51861c526606116 Mon Sep 17 00:00:00 2001 From: Brandon Chinn Date: Tue, 25 Apr 2023 19:02:03 -0700 Subject: [PATCH 12/22] Add failing tests for matching outside relative path --- packages/jest-util/src/TestPathPatterns.ts | 6 ++++-- .../src/__tests__/TestPathPatterns.test.ts | 20 +++++++++++++++++++ 2 files changed, 24 insertions(+), 2 deletions(-) diff --git a/packages/jest-util/src/TestPathPatterns.ts b/packages/jest-util/src/TestPathPatterns.ts index 2770b8728b8d..587c13c24901 100644 --- a/packages/jest-util/src/TestPathPatterns.ts +++ b/packages/jest-util/src/TestPathPatterns.ts @@ -8,14 +8,16 @@ import type {Config} from '@jest/types'; import {replacePathSepForRegex} from 'jest-regex-util'; -type PatternsFullConfig = Pick; +type PatternsConfig = Pick; +type PatternsFullConfig = PatternsConfig & + Pick; export default class TestPathPatterns { readonly patterns: Array; private _regexString: string | null = null; - constructor(patterns: Array); + constructor(patterns: Array, config?: PatternsConfig); constructor(config: PatternsFullConfig); constructor(patternsOrConfig: Array | PatternsFullConfig) { let patterns; diff --git a/packages/jest-util/src/__tests__/TestPathPatterns.test.ts b/packages/jest-util/src/__tests__/TestPathPatterns.test.ts index b5be21943629..0ecdb932393e 100644 --- a/packages/jest-util/src/__tests__/TestPathPatterns.test.ts +++ b/packages/jest-util/src/__tests__/TestPathPatterns.test.ts @@ -77,6 +77,11 @@ describe('TestPathPatterns', () => { expect(testPathPatterns.isMatch('/a/b/c/d')).toBe(true); }); + it('returns true for explicit relative path', () => { + const testPathPatterns = new TestPathPatterns(['./b/c']); + expect(testPathPatterns.isMatch('/a/b/c')).toBe(true); + }); + it('returns true for partial file match', () => { const testPathPatterns = new TestPathPatterns(['aaa']); expect(testPathPatterns.isMatch('/foo/..aaa..')).toBe(true); @@ -102,6 +107,21 @@ describe('TestPathPatterns', () => { expect(testPathPatterns.isMatch('/foo/bc')).toBe(false); }); + it('returns true only if matches relative path', () => { + const testPathPatterns = new TestPathPatterns(['home'], { + rootDir: '/home/myuser/', + }); + expect(testPathPatterns.isMatch('/home/myuser/LoginPage.js')).toBe(false); + expect(testPathPatterns.isMatch('/home/myuser/HomePage.js')).toBe(true); + }); + + it('matches absolute paths regardless of rootDir', () => { + const testPathPatterns = new TestPathPatterns(['/a/b'], { + rootDir: '/foo/bar', + }); + expect(testPathPatterns.isMatch('/a/b')).toBe(true); + }); + it('returns true if match any paths', () => { const testPathPatterns = new TestPathPatterns(['a/b', 'c/d']); From 191175025dda7b2d5adc54f3722c8ebf1a69e64a Mon Sep 17 00:00:00 2001 From: Brandon Chinn Date: Tue, 25 Apr 2023 19:02:03 -0700 Subject: [PATCH 13/22] Only match within relative path --- packages/jest-config/src/normalize.ts | 12 ++++-- .../src/__tests__/SearchSource.test.ts | 1 + packages/jest-core/src/watch.ts | 2 +- packages/jest-util/src/TestPathPatterns.ts | 30 +++++++++++-- .../src/__tests__/TestPathPatterns.test.ts | 43 +++++++++++-------- 5 files changed, 61 insertions(+), 27 deletions(-) diff --git a/packages/jest-config/src/normalize.ts b/packages/jest-config/src/normalize.ts index dd1bccb6d5ab..295afd2a0aee 100644 --- a/packages/jest-config/src/normalize.ts +++ b/packages/jest-config/src/normalize.ts @@ -391,7 +391,10 @@ const normalizeReporters = ({ }); }; -const buildTestPathPatterns = (argv: Config.Argv): TestPathPatterns => { +const buildTestPathPatterns = ( + argv: Config.Argv, + rootDir: string, +): TestPathPatterns => { const patterns = []; if (argv._) { @@ -401,10 +404,11 @@ const buildTestPathPatterns = (argv: Config.Argv): TestPathPatterns => { patterns.push(...argv.testPathPattern); } - const testPathPatterns = new TestPathPatterns(patterns); + const config = {rootDir}; + const testPathPatterns = new TestPathPatterns(patterns, config); if (!testPathPatterns.isValid()) { showTestPathPatternsError(testPathPatterns); - return new TestPathPatterns([]); + return new TestPathPatterns([], config); } return testPathPatterns; }; @@ -997,7 +1001,7 @@ export default async function normalize( } newOptions.nonFlagArgs = argv._?.map(arg => `${arg}`); - const testPathPatterns = buildTestPathPatterns(argv); + const testPathPatterns = buildTestPathPatterns(argv, options.rootDir); newOptions.testPathPatterns = testPathPatterns.patterns; newOptions.json = !!argv.json; diff --git a/packages/jest-core/src/__tests__/SearchSource.test.ts b/packages/jest-core/src/__tests__/SearchSource.test.ts index 21ef1683e5fa..4a8e0e2f2277 100644 --- a/packages/jest-core/src/__tests__/SearchSource.test.ts +++ b/packages/jest-core/src/__tests__/SearchSource.test.ts @@ -109,6 +109,7 @@ describe('SearchSource', () => { const {searchSource, config} = await initSearchSource(initialOptions); const {tests: paths} = await searchSource.getTestPaths({ ...config, + ...initialOptions, testPathPatterns: [], }); return paths.map(({path: p}) => path.relative(rootDir, p)).sort(); diff --git a/packages/jest-core/src/watch.ts b/packages/jest-core/src/watch.ts index be3d042aa194..0a64cc6e886c 100644 --- a/packages/jest-core/src/watch.ts +++ b/packages/jest-core/src/watch.ts @@ -228,7 +228,7 @@ export default async function watch( const emitFileChange = () => { if (hooks.isUsed('onFileChange')) { - const testPathPatterns = new TestPathPatterns([]); + const testPathPatterns = new TestPathPatterns([], globalConfig); const projects = searchSources.map(({context, searchSource}) => ({ config: context.config, testPaths: searchSource diff --git a/packages/jest-util/src/TestPathPatterns.ts b/packages/jest-util/src/TestPathPatterns.ts index 587c13c24901..46452b631acb 100644 --- a/packages/jest-util/src/TestPathPatterns.ts +++ b/packages/jest-util/src/TestPathPatterns.ts @@ -6,7 +6,7 @@ */ import type {Config} from '@jest/types'; -import {replacePathSepForRegex} from 'jest-regex-util'; +import {escapePathForRegex, replacePathSepForRegex} from 'jest-regex-util'; type PatternsConfig = Pick; type PatternsFullConfig = PatternsConfig & @@ -14,27 +14,49 @@ type PatternsFullConfig = PatternsConfig & export default class TestPathPatterns { readonly patterns: Array; + private readonly rootDir: string; private _regexString: string | null = null; - constructor(patterns: Array, config?: PatternsConfig); + constructor(patterns: Array, config: PatternsConfig); constructor(config: PatternsFullConfig); - constructor(patternsOrConfig: Array | PatternsFullConfig) { - let patterns; + constructor( + patternsOrConfig: Array | PatternsFullConfig, + configArg?: PatternsConfig, + ) { + let patterns, config; if (Array.isArray(patternsOrConfig)) { patterns = patternsOrConfig; + config = configArg!; } else { patterns = patternsOrConfig.testPathPatterns; + config = patternsOrConfig; } this.patterns = patterns; + this.rootDir = config.rootDir.replace(/\/*$/, '/'); } private get regexString(): string { if (this._regexString !== null) { return this._regexString; } + const rootDirRegex = escapePathForRegex(this.rootDir); const regexString = this.patterns + .map(p => { + // absolute paths passed on command line should stay same + if (p.match(/^\//)) { + return p; + } + + // explicit relative paths should resolve against rootDir + if (p.match(/^\.\//)) { + return p.replace(/^\.\//, rootDirRegex); + } + + // all other patterns should only match the relative part of the test + return `${rootDirRegex}(.*)?${p}`; + }) .map(replacePathSepForRegex) .join('|'); this._regexString = regexString; diff --git a/packages/jest-util/src/__tests__/TestPathPatterns.test.ts b/packages/jest-util/src/__tests__/TestPathPatterns.test.ts index 0ecdb932393e..26e997d74213 100644 --- a/packages/jest-util/src/__tests__/TestPathPatterns.test.ts +++ b/packages/jest-util/src/__tests__/TestPathPatterns.test.ts @@ -21,81 +21,88 @@ beforeEach(() => { jest.resetAllMocks(); }); +const config = {rootDir: ''}; + describe('TestPathPatterns', () => { describe('isSet', () => { it('returns false if no patterns specified', () => { - const testPathPatterns = new TestPathPatterns([]); + const testPathPatterns = new TestPathPatterns([], config); expect(testPathPatterns.isSet()).toBe(false); }); it('returns true if patterns specified', () => { - const testPathPatterns = new TestPathPatterns(['a']); + const testPathPatterns = new TestPathPatterns(['a'], config); expect(testPathPatterns.isSet()).toBe(true); }); }); describe('isValid', () => { it('returns true for empty patterns', () => { - const testPathPatterns = new TestPathPatterns([]); + const testPathPatterns = new TestPathPatterns([], config); expect(testPathPatterns.isValid()).toBe(true); }); it('returns true for valid patterns', () => { - const testPathPatterns = new TestPathPatterns(['abc+', 'z.*']); + const testPathPatterns = new TestPathPatterns(['abc+', 'z.*'], config); expect(testPathPatterns.isValid()).toBe(true); }); it('returns false for at least one invalid pattern', () => { - const testPathPatterns = new TestPathPatterns(['abc+', '(', 'z.*']); + const testPathPatterns = new TestPathPatterns( + ['abc+', '(', 'z.*'], + config, + ); expect(testPathPatterns.isValid()).toBe(false); }); }); describe('isMatch', () => { it('returns true with no patterns', () => { - const testPathPatterns = new TestPathPatterns([]); + const testPathPatterns = new TestPathPatterns([], config); expect(testPathPatterns.isMatch('/a/b')).toBe(true); }); it('returns true for same path', () => { - const testPathPatterns = new TestPathPatterns(['/a/b']); + const testPathPatterns = new TestPathPatterns(['/a/b'], config); expect(testPathPatterns.isMatch('/a/b')).toBe(true); }); it('returns true for same path with case insensitive', () => { - const testPathPatternsUpper = new TestPathPatterns(['/A/B']); + const testPathPatternsUpper = new TestPathPatterns(['/A/B'], config); expect(testPathPatternsUpper.isMatch('/a/b')).toBe(true); expect(testPathPatternsUpper.isMatch('/A/B')).toBe(true); - const testPathPatternsLower = new TestPathPatterns(['/a/b']); + const testPathPatternsLower = new TestPathPatterns(['/a/b'], config); expect(testPathPatternsLower.isMatch('/A/B')).toBe(true); expect(testPathPatternsLower.isMatch('/a/b')).toBe(true); }); it('returns true for contained path', () => { - const testPathPatterns = new TestPathPatterns(['b/c']); + const testPathPatterns = new TestPathPatterns(['b/c'], config); expect(testPathPatterns.isMatch('/a/b/c/d')).toBe(true); }); it('returns true for explicit relative path', () => { - const testPathPatterns = new TestPathPatterns(['./b/c']); + const testPathPatterns = new TestPathPatterns(['./b/c'], { + rootDir: '/a', + }); expect(testPathPatterns.isMatch('/a/b/c')).toBe(true); }); it('returns true for partial file match', () => { - const testPathPatterns = new TestPathPatterns(['aaa']); + const testPathPatterns = new TestPathPatterns(['aaa'], config); expect(testPathPatterns.isMatch('/foo/..aaa..')).toBe(true); expect(testPathPatterns.isMatch('/foo/..aaa')).toBe(true); expect(testPathPatterns.isMatch('/foo/aaa..')).toBe(true); }); it('returns true for path suffix', () => { - const testPathPatterns = new TestPathPatterns(['c/d']); + const testPathPatterns = new TestPathPatterns(['c/d'], config); expect(testPathPatterns.isMatch('/a/b/c/d')).toBe(true); }); it('returns true if regex matches', () => { - const testPathPatterns = new TestPathPatterns(['ab*c?']); + const testPathPatterns = new TestPathPatterns(['ab*c?'], config); expect(testPathPatterns.isMatch('/foo/a')).toBe(true); expect(testPathPatterns.isMatch('/foo/ab')).toBe(true); @@ -123,7 +130,7 @@ describe('TestPathPatterns', () => { }); it('returns true if match any paths', () => { - const testPathPatterns = new TestPathPatterns(['a/b', 'c/d']); + const testPathPatterns = new TestPathPatterns(['a/b', 'c/d'], config); expect(testPathPatterns.isMatch('/foo/a/b')).toBe(true); expect(testPathPatterns.isMatch('/foo/c/d')).toBe(true); @@ -134,20 +141,20 @@ describe('TestPathPatterns', () => { it('does not normalize Windows paths on POSIX', () => { mockSep.mockReturnValue('/'); - const testPathPatterns = new TestPathPatterns(['a\\z', 'a\\\\z']); + const testPathPatterns = new TestPathPatterns(['a\\z', 'a\\\\z'], config); expect(testPathPatterns.isMatch('/foo/a/z')).toBe(false); }); it('normalizes paths for Windows', () => { mockSep.mockReturnValue('\\'); - const testPathPatterns = new TestPathPatterns(['a/b']); + const testPathPatterns = new TestPathPatterns(['a/b'], config); expect(testPathPatterns.isMatch('\\foo\\a\\b')).toBe(true); }); }); describe('toPretty', () => { it('renders a human-readable string', () => { - const testPathPatterns = new TestPathPatterns(['a/b', 'c/d']); + const testPathPatterns = new TestPathPatterns(['a/b', 'c/d'], config); expect(testPathPatterns.toPretty()).toMatchSnapshot(); }); }); From 5fd3eda64c45a490af470d6423ea87e7d9b2b394 Mon Sep 17 00:00:00 2001 From: Brandon Chinn Date: Tue, 25 Apr 2023 19:02:03 -0700 Subject: [PATCH 14/22] Fix tests using partial GlobalConfigs --- .../__snapshots__/watchFilenamePatternMode.test.js.snap | 1 + packages/jest-core/src/__tests__/runJest.test.js | 2 ++ packages/jest-core/src/__tests__/watch.test.js | 6 +++++- .../src/__tests__/watchFilenamePatternMode.test.js | 6 +++++- .../src/__tests__/watchTestNamePatternMode.test.js | 2 ++ .../jest-reporters/src/__tests__/SummaryReporter.test.js | 1 + 6 files changed, 16 insertions(+), 2 deletions(-) diff --git a/packages/jest-core/src/__tests__/__snapshots__/watchFilenamePatternMode.test.js.snap b/packages/jest-core/src/__tests__/__snapshots__/watchFilenamePatternMode.test.js.snap index 2f831f62a006..724b415277b6 100644 --- a/packages/jest-core/src/__tests__/__snapshots__/watchFilenamePatternMode.test.js.snap +++ b/packages/jest-core/src/__tests__/__snapshots__/watchFilenamePatternMode.test.js.snap @@ -92,6 +92,7 @@ exports[`Watch mode flows Pressing "P" enters pattern mode 9`] = ` Object { "onlyChanged": false, "passWithNoTests": true, + "rootDir": "", "testPathPatterns": Array [ "p.*3", ], diff --git a/packages/jest-core/src/__tests__/runJest.test.js b/packages/jest-core/src/__tests__/runJest.test.js index 7661503ae95a..559a8bdb8baf 100644 --- a/packages/jest-core/src/__tests__/runJest.test.js +++ b/packages/jest-core/src/__tests__/runJest.test.js @@ -22,6 +22,8 @@ describe('runJest', () => { changedFilesPromise: Promise.resolve({repos: {git: {size: 0}}}), contexts: [], globalConfig: { + rootDir: '', + testPathPatterns: [], testSequencer: require.resolve('@jest/test-sequencer'), watch: true, }, diff --git a/packages/jest-core/src/__tests__/watch.test.js b/packages/jest-core/src/__tests__/watch.test.js index 8920963123a1..9b34759c4639 100644 --- a/packages/jest-core/src/__tests__/watch.test.js +++ b/packages/jest-core/src/__tests__/watch.test.js @@ -140,7 +140,11 @@ describe('Watch mode flows', () => { testRegex: [], }; pipe = {write: jest.fn()}; - globalConfig = {watch: true}; + globalConfig = { + rootDir: '', + testPathPatterns: [], + watch: true, + }; hasteMapInstances = [{on: () => {}}]; contexts = [{config}]; stdin = new MockStdin(); diff --git a/packages/jest-core/src/__tests__/watchFilenamePatternMode.test.js b/packages/jest-core/src/__tests__/watchFilenamePatternMode.test.js index 9d84afe3c8df..2900fe6d02e8 100644 --- a/packages/jest-core/src/__tests__/watchFilenamePatternMode.test.js +++ b/packages/jest-core/src/__tests__/watchFilenamePatternMode.test.js @@ -70,7 +70,11 @@ const watch = require('../watch').default; const nextTick = () => new Promise(res => process.nextTick(res)); -const globalConfig = {watch: true}; +const globalConfig = { + rootDir: '', + testPathPatterns: [], + watch: true, +}; afterEach(runJestMock.mockReset); diff --git a/packages/jest-core/src/__tests__/watchTestNamePatternMode.test.js b/packages/jest-core/src/__tests__/watchTestNamePatternMode.test.js index c07e78f65d38..0763d17bf0a0 100644 --- a/packages/jest-core/src/__tests__/watchTestNamePatternMode.test.js +++ b/packages/jest-core/src/__tests__/watchTestNamePatternMode.test.js @@ -83,6 +83,8 @@ jest.doMock( const watch = require('../watch').default; const globalConfig = { + rootDir: '', + testPathPatterns: [], watch: true, }; diff --git a/packages/jest-reporters/src/__tests__/SummaryReporter.test.js b/packages/jest-reporters/src/__tests__/SummaryReporter.test.js index fb83c448194a..6ace91cd6c5f 100644 --- a/packages/jest-reporters/src/__tests__/SummaryReporter.test.js +++ b/packages/jest-reporters/src/__tests__/SummaryReporter.test.js @@ -13,6 +13,7 @@ const now = Date.now; const write = process.stderr.write; const globalConfig = { rootDir: 'root', + testPathPatterns: [], watch: false, }; From 0225d226c0734ebdf648aa80ba1bb350b51216ac Mon Sep 17 00:00:00 2001 From: Brandon Chinn Date: Tue, 25 Apr 2023 19:02:03 -0700 Subject: [PATCH 15/22] Update CHANGELOG --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 87390ddbfaa8..f07e23180121 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -19,6 +19,8 @@ - `[jest-leak-detector]` Make leak-detector more aggressive when running GC ([#14526](https://github.com/jestjs/jest/pull/14526)) - `[jest-util]` Make sure `isInteractive` works in a browser ([#14552](https://github.com/jestjs/jest/pull/14552)) - `[pretty-format]` [**BREAKING**] Print `ArrayBuffer` and `DataView` correctly ([#14290](https://github.com/facebook/jest/pull/14290)) +- `[jest-cli]` When specifying paths on the command line, only match against the relative paths of the test files ([#12519](https://github.com/facebook/jest/pull/12519)) + - [**BREAKING**] Changes `testPathPattern` configuration option to `testPathPatterns`, which now takes a list of patterns instead of the regex. ### Performance From e228478d6d03f272ce60626997ada1d933f4b61d Mon Sep 17 00:00:00 2001 From: Brandon Chinn Date: Tue, 25 Apr 2023 19:02:03 -0700 Subject: [PATCH 16/22] Fix --testPathPattern => --testPathPatterns --- CHANGELOG.md | 1 + e2e/__tests__/globalSetup.test.ts | 12 ++++++------ e2e/__tests__/globalTeardown.test.ts | 14 ++++++-------- e2e/__tests__/noTestsFound.test.ts | 4 ++-- e2e/__tests__/onlyChanged.test.ts | 2 +- .../testPathPatternReporterMessage.test.ts | 4 ++-- packages/jest-cli/src/args.ts | 6 +++--- .../__tests__/__snapshots__/normalize.test.ts.snap | 2 +- .../jest-config/src/__tests__/normalize.test.ts | 4 ++-- packages/jest-config/src/normalize.ts | 4 ++-- packages/jest-core/src/SearchSource.ts | 4 ++-- packages/jest-core/src/types.ts | 4 ++-- packages/jest-types/src/Config.ts | 2 +- 13 files changed, 31 insertions(+), 32 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f07e23180121..6da73dad3647 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -21,6 +21,7 @@ - `[pretty-format]` [**BREAKING**] Print `ArrayBuffer` and `DataView` correctly ([#14290](https://github.com/facebook/jest/pull/14290)) - `[jest-cli]` When specifying paths on the command line, only match against the relative paths of the test files ([#12519](https://github.com/facebook/jest/pull/12519)) - [**BREAKING**] Changes `testPathPattern` configuration option to `testPathPatterns`, which now takes a list of patterns instead of the regex. + - [**BREAKING**] `--testPathPattern` is now `--testPathPatterns` ### Performance diff --git a/e2e/__tests__/globalSetup.test.ts b/e2e/__tests__/globalSetup.test.ts index d85dc352aa85..454b5f76e8bf 100644 --- a/e2e/__tests__/globalSetup.test.ts +++ b/e2e/__tests__/globalSetup.test.ts @@ -56,7 +56,7 @@ test('globalSetup is triggered once before all test suites', () => { const setupPath = path.join(e2eDir, 'setup.js'); const result = runWithJson(e2eDir, [ `--globalSetup=${setupPath}`, - '--testPathPattern=__tests__', + '--testPathPatterns=__tests__', ]); expect(result.exitCode).toBe(0); @@ -70,7 +70,7 @@ test('jest throws an error when globalSetup does not export a function', () => { const setupPath = path.resolve(__dirname, '../global-setup/invalidSetup.js'); const {exitCode, stderr} = runJest(e2eDir, [ `--globalSetup=${setupPath}`, - '--testPathPattern=__tests__', + '--testPathPatterns=__tests__', ]); expect(exitCode).toBe(1); @@ -85,7 +85,7 @@ test('globalSetup function gets global config object and project config as param const result = runJest(e2eDir, [ `--globalSetup=${setupPath}`, - '--testPathPattern=pass', + '--testPathPatterns=pass', '--cache=true', ]); @@ -109,7 +109,7 @@ test('should not call a globalSetup of a project if there are no tests to run fr const result = runWithJson(e2eDir, [ `--config=${configPath}`, - '--testPathPattern=project-1', + '--testPathPatterns=project-1', ]); expect(result.exitCode).toBe(0); @@ -140,7 +140,7 @@ test('globalSetup works with default export', () => { const result = runJest(e2eDir, [ `--globalSetup=${setupPath}`, - '--testPathPattern=pass', + '--testPathPatterns=pass', '--cache=true', ]); @@ -152,7 +152,7 @@ test('globalSetup throws with named export', () => { const {exitCode, stderr} = runJest(e2eDir, [ `--globalSetup=${setupPath}`, - '--testPathPattern=__tests__', + '--testPathPatterns=__tests__', ]); expect(exitCode).toBe(1); diff --git a/e2e/__tests__/globalTeardown.test.ts b/e2e/__tests__/globalTeardown.test.ts index 152b83d255b2..cefd7e88accb 100644 --- a/e2e/__tests__/globalTeardown.test.ts +++ b/e2e/__tests__/globalTeardown.test.ts @@ -40,7 +40,7 @@ test('globalTeardown is triggered once after all test suites', () => { const teardownPath = path.resolve(e2eDir, 'teardown.js'); const result = runWithJson('global-teardown', [ `--globalTeardown=${teardownPath}`, - '--testPathPattern=__tests__', + '--testPathPatterns=__tests__', ]); expect(result.exitCode).toBe(0); @@ -54,7 +54,7 @@ test('jest throws an error when globalTeardown does not export a function', () = const teardownPath = path.resolve(e2eDir, 'invalidTeardown.js'); const {exitCode, stderr} = runJest(e2eDir, [ `--globalTeardown=${teardownPath}`, - '--testPathPattern=__tests__', + '--testPathPatterns=__tests__', ]); expect(exitCode).toBe(1); @@ -69,7 +69,7 @@ test('globalSetup function gets global config object and project config as param const result = runJest(e2eDir, [ `--globalTeardown=${teardownPath}`, - '--testPathPattern=pass', + '--testPathPatterns=pass', '--cache=true', ]); @@ -93,7 +93,7 @@ test('should not call a globalTeardown of a project if there are no tests to run const result = runWithJson('global-teardown', [ `--config=${configPath}`, - '--testPathPattern=project-1', + '--testPathPatterns=project-1', ]); expect(result.exitCode).toBe(0); @@ -106,11 +106,9 @@ test('should not call a globalTeardown of a project if there are no tests to run test('globalTeardown works with default export', () => { const teardownPath = path.resolve(e2eDir, 'teardownWithDefaultExport.js'); - const testPathPattern = 'pass'; - const result = runJest(e2eDir, [ `--globalTeardown=${teardownPath}`, - '--testPathPattern=pass', + '--testPathPatterns=pass', '--cache=true', ]); @@ -125,7 +123,7 @@ test('globalTeardown throws with named export', () => { const {exitCode, stderr} = runJest(e2eDir, [ `--globalTeardown=${teardownPath}`, - '--testPathPattern=__tests__', + '--testPathPatterns=__tests__', ]); expect(exitCode).toBe(1); diff --git a/e2e/__tests__/noTestsFound.test.ts b/e2e/__tests__/noTestsFound.test.ts index 0c90d3f240dc..f65d01b4f4a4 100644 --- a/e2e/__tests__/noTestsFound.test.ts +++ b/e2e/__tests__/noTestsFound.test.ts @@ -13,7 +13,7 @@ const DIR = path.resolve(__dirname, '../no-tests-found-test'); describe('No tests are found', () => { test('fails the test suite in standard situation', () => { const {exitCode, stdout} = runJest(DIR, [ - '--testPathPattern', + '--testPathPatterns', '/non/existing/path/', ]); @@ -26,7 +26,7 @@ describe('No tests are found', () => { test("doesn't fail the test suite if --passWithNoTests passed", () => { const {exitCode, stdout} = runJest(DIR, [ - '--testPathPattern', + '--testPathPatterns', '/non/existing/path/', '--passWithNoTests', ]); diff --git a/e2e/__tests__/onlyChanged.test.ts b/e2e/__tests__/onlyChanged.test.ts index be77ee63a5c6..b40619f26dc6 100644 --- a/e2e/__tests__/onlyChanged.test.ts +++ b/e2e/__tests__/onlyChanged.test.ts @@ -246,7 +246,7 @@ test('collect test coverage when using onlyChanged', () => { expect(exitCode).toBe(0); }); -test('onlyChanged in config is overwritten by --all or testPathPattern', () => { +test('onlyChanged in config is overwritten by --all or testPathPatterns', () => { writeFiles(DIR, { '.watchmanconfig': '', '__tests__/file1.test.js': "require('../file1'); test('file1', () => {});", diff --git a/e2e/__tests__/testPathPatternReporterMessage.test.ts b/e2e/__tests__/testPathPatternReporterMessage.test.ts index 6349dc087e82..5a2f79fa3b94 100644 --- a/e2e/__tests__/testPathPatternReporterMessage.test.ts +++ b/e2e/__tests__/testPathPatternReporterMessage.test.ts @@ -30,9 +30,9 @@ test('prints a message with path pattern at the end', () => { ({stderr} = runJest(DIR, ['a', 'b'])); expect(stderr).toMatch('Ran all test suites matching /a|b/i'); - ({stderr} = runJest(DIR, ['--testPathPattern', 'a'])); + ({stderr} = runJest(DIR, ['--testPathPatterns', 'a'])); expect(stderr).toMatch('Ran all test suites matching /a/i'); - ({stderr} = runJest(DIR, ['--testPathPattern', 'a|b'])); + ({stderr} = runJest(DIR, ['--testPathPatterns', 'a|b'])); expect(stderr).toMatch('Ran all test suites matching /a|b/i'); }); diff --git a/packages/jest-cli/src/args.ts b/packages/jest-cli/src/args.ts index 869f1a0a707f..4f5b13d7c718 100644 --- a/packages/jest-cli/src/args.ts +++ b/packages/jest-cli/src/args.ts @@ -97,7 +97,7 @@ export function check(argv: Config.Argv): true { } export const usage = - 'Usage: $0 [--config=] [TestPathPattern]'; + 'Usage: $0 [--config=] [TestPathPatterns]'; export const docs = 'Documentation: https://jestjs.io/'; // The default values are all set in jest-config @@ -431,7 +431,7 @@ export const options: {[key: string]: Options} = { }, passWithNoTests: { description: - 'Will not fail if no tests are found (for example while using `--testPathPattern`.)', + 'Will not fail if no tests are found (for example while using `--testPathPatterns`.)', type: 'boolean', }, preset: { @@ -609,7 +609,7 @@ export const options: {[key: string]: Options} = { string: true, type: 'array', }, - testPathPattern: { + testPathPatterns: { description: 'A regexp pattern string that is matched against all tests ' + 'paths before executing the test.', diff --git a/packages/jest-config/src/__tests__/__snapshots__/normalize.test.ts.snap b/packages/jest-config/src/__tests__/__snapshots__/normalize.test.ts.snap index 5c2f1af3ecd2..ac0a7cfacf49 100644 --- a/packages/jest-config/src/__tests__/__snapshots__/normalize.test.ts.snap +++ b/packages/jest-config/src/__tests__/__snapshots__/normalize.test.ts.snap @@ -484,7 +484,7 @@ exports[`testMatch throws if testRegex and testMatch are both specified 1`] = ` exports[`testPathPatterns ignores invalid regular expressions and logs a warning 1`] = `" Invalid testPattern /a(/i supplied. Running all tests instead."`; -exports[`testPathPatterns --testPathPattern ignores invalid regular expressions and logs a warning 1`] = `" Invalid testPattern /a(/i supplied. Running all tests instead."`; +exports[`testPathPatterns --testPathPatterns ignores invalid regular expressions and logs a warning 1`] = `" Invalid testPattern /a(/i supplied. Running all tests instead."`; exports[`testTimeout should throw an error if timeout is a negative number 1`] = ` "Validation Error: diff --git a/packages/jest-config/src/__tests__/normalize.test.ts b/packages/jest-config/src/__tests__/normalize.test.ts index f05d74ac6a9d..2a36c507886f 100644 --- a/packages/jest-config/src/__tests__/normalize.test.ts +++ b/packages/jest-config/src/__tests__/normalize.test.ts @@ -1604,7 +1604,7 @@ describe('testPathPatterns', () => { }); const cliOptions = [ - {name: '--testPathPattern', property: 'testPathPattern'}, + {name: '--testPathPatterns', property: 'testPathPatterns'}, {name: '', property: '_'}, ]; for (const opt of cliOptions) { @@ -1643,7 +1643,7 @@ describe('testPathPatterns', () => { it('joins multiple --testPathPatterns and ', async () => { const {options} = await normalize(initialOptions, { _: ['a', 'b'], - testPathPattern: ['c', 'd'], + testPathPatterns: ['c', 'd'], } as Config.Argv); expect(options.testPathPatterns).toEqual(['a', 'b', 'c', 'd']); }); diff --git a/packages/jest-config/src/normalize.ts b/packages/jest-config/src/normalize.ts index 295afd2a0aee..d9e07c5db1d1 100644 --- a/packages/jest-config/src/normalize.ts +++ b/packages/jest-config/src/normalize.ts @@ -400,8 +400,8 @@ const buildTestPathPatterns = ( if (argv._) { patterns.push(...argv._.map(x => x.toString())); } - if (argv.testPathPattern) { - patterns.push(...argv.testPathPattern); + if (argv.testPathPatterns) { + patterns.push(...argv.testPathPatterns); } const config = {rootDir}; diff --git a/packages/jest-core/src/SearchSource.ts b/packages/jest-core/src/SearchSource.ts index a225904251dc..9532cbfcab7c 100644 --- a/packages/jest-core/src/SearchSource.ts +++ b/packages/jest-core/src/SearchSource.ts @@ -131,9 +131,9 @@ export default class SearchSource { if (testPathPatterns.isSet()) { testCases.push({ isMatch: (path: string) => testPathPatterns.isMatch(path), - stat: 'testPathPattern', + stat: 'testPathPatterns', }); - data.stats.testPathPattern = 0; + data.stats.testPathPatterns = 0; } data.tests = allPaths.filter(test => { diff --git a/packages/jest-core/src/types.ts b/packages/jest-core/src/types.ts index 378cfde4973e..3aaece51f060 100644 --- a/packages/jest-core/src/types.ts +++ b/packages/jest-core/src/types.ts @@ -12,7 +12,7 @@ export type Stats = { testMatch: number; testPathIgnorePatterns: number; testRegex: number; - testPathPattern?: number; + testPathPatterns?: number; }; export type TestRunData = Array<{ @@ -31,7 +31,7 @@ export type TestPathCases = Array<{ }>; export type TestPathCasesWithPathPattern = TestPathCases & { - testPathPattern: (path: string) => boolean; + testPathPatterns: (path: string) => boolean; }; export type FilterResult = { diff --git a/packages/jest-types/src/Config.ts b/packages/jest-types/src/Config.ts index b444716e4c6a..34afe821412e 100644 --- a/packages/jest-types/src/Config.ts +++ b/packages/jest-types/src/Config.ts @@ -569,7 +569,7 @@ export type Argv = Arguments< testMatch: Array; testNamePattern: string; testPathIgnorePatterns: Array; - testPathPattern: Array; + testPathPatterns: Array; testRegex: string | Array; testResultsProcessor: string; testRunner: string; From de9edca131f44778b3a3b0e26d953f5cdd85725d Mon Sep 17 00:00:00 2001 From: Brandon Chinn Date: Sun, 24 Sep 2023 17:07:54 -0700 Subject: [PATCH 17/22] Don't overload TestPathPatterns constructor --- packages/jest-core/src/SearchSource.ts | 4 ++- packages/jest-core/src/getNoTestFound.ts | 2 +- .../jest-core/src/getNoTestFoundVerbose.ts | 2 +- .../jest-core/src/lib/activeFiltersMessage.ts | 2 +- .../jest-core/src/lib/updateGlobalConfig.ts | 2 +- packages/jest-core/src/watch.ts | 2 +- .../jest-reporters/src/SummaryReporter.ts | 2 +- packages/jest-util/src/TestPathPatterns.ts | 35 +++++++------------ 8 files changed, 22 insertions(+), 29 deletions(-) diff --git a/packages/jest-core/src/SearchSource.ts b/packages/jest-core/src/SearchSource.ts index 9532cbfcab7c..681464ec7f44 100644 --- a/packages/jest-core/src/SearchSource.ts +++ b/packages/jest-core/src/SearchSource.ts @@ -287,7 +287,9 @@ export default class SearchSource { globalConfig.collectCoverage, ); } else { - return this.findMatchingTests(new TestPathPatterns(globalConfig)); + return this.findMatchingTests( + TestPathPatterns.fromGlobalConfig(globalConfig), + ); } } diff --git a/packages/jest-core/src/getNoTestFound.ts b/packages/jest-core/src/getNoTestFound.ts index 3d5a187e3cff..cbfe05cbf6e9 100644 --- a/packages/jest-core/src/getNoTestFound.ts +++ b/packages/jest-core/src/getNoTestFound.ts @@ -26,7 +26,7 @@ export default function getNoTestFound( .map(p => `"${p}"`) .join(', ')}`; } else { - const testPathPatterns = new TestPathPatterns(globalConfig); + const testPathPatterns = TestPathPatterns.fromGlobalConfig(globalConfig); dataMessage = `Pattern: ${chalk.yellow( testPathPatterns.toPretty(), )} - 0 matches`; diff --git a/packages/jest-core/src/getNoTestFoundVerbose.ts b/packages/jest-core/src/getNoTestFoundVerbose.ts index ca98f60075e6..9c80b38a4e5f 100644 --- a/packages/jest-core/src/getNoTestFoundVerbose.ts +++ b/packages/jest-core/src/getNoTestFoundVerbose.ts @@ -56,7 +56,7 @@ export default function getNoTestFoundVerbose( .map(p => `"${p}"`) .join(', ')}`; } else { - const testPathPatterns = new TestPathPatterns(globalConfig); + const testPathPatterns = TestPathPatterns.fromGlobalConfig(globalConfig); dataMessage = `Pattern: ${chalk.yellow( testPathPatterns.toPretty(), )} - 0 matches`; diff --git a/packages/jest-core/src/lib/activeFiltersMessage.ts b/packages/jest-core/src/lib/activeFiltersMessage.ts index 0b44c259f673..170760456cda 100644 --- a/packages/jest-core/src/lib/activeFiltersMessage.ts +++ b/packages/jest-core/src/lib/activeFiltersMessage.ts @@ -11,7 +11,7 @@ import {TestPathPatterns, isNonNullable} from 'jest-util'; const activeFilters = (globalConfig: Config.GlobalConfig): string => { const {testNamePattern} = globalConfig; - const testPathPatterns = new TestPathPatterns(globalConfig); + const testPathPatterns = TestPathPatterns.fromGlobalConfig(globalConfig); if (testNamePattern || testPathPatterns.isSet()) { const filters = [ testPathPatterns.isSet() diff --git a/packages/jest-core/src/lib/updateGlobalConfig.ts b/packages/jest-core/src/lib/updateGlobalConfig.ts index bfe03f26b790..a05dc5ae9fcd 100644 --- a/packages/jest-core/src/lib/updateGlobalConfig.ts +++ b/packages/jest-core/src/lib/updateGlobalConfig.ts @@ -38,7 +38,7 @@ export default function updateGlobalConfig( newConfig.onlyChanged = !newConfig.watchAll && !newConfig.testNamePattern && - !new TestPathPatterns(newConfig).isSet(); + !TestPathPatterns.fromGlobalConfig(newConfig).isSet(); if (typeof options.bail === 'boolean') { newConfig.bail = options.bail ? 1 : 0; diff --git a/packages/jest-core/src/watch.ts b/packages/jest-core/src/watch.ts index 0a64cc6e886c..fad345e2c764 100644 --- a/packages/jest-core/src/watch.ts +++ b/packages/jest-core/src/watch.ts @@ -532,7 +532,7 @@ const usage = ( watchPlugins: Array, delimiter = '\n', ) => { - const testPathPatterns = new TestPathPatterns(globalConfig); + const testPathPatterns = TestPathPatterns.fromGlobalConfig(globalConfig); const messages = [ activeFilters(globalConfig), diff --git a/packages/jest-reporters/src/SummaryReporter.ts b/packages/jest-reporters/src/SummaryReporter.ts index 6fe345842843..9a34e1cb7a9f 100644 --- a/packages/jest-reporters/src/SummaryReporter.ts +++ b/packages/jest-reporters/src/SummaryReporter.ts @@ -212,7 +212,7 @@ export default class SummaryReporter extends BaseReporter { testContexts: Set, globalConfig: Config.GlobalConfig, ) { - const testPathPatterns = new TestPathPatterns(globalConfig); + const testPathPatterns = TestPathPatterns.fromGlobalConfig(globalConfig); const getMatchingTestsInfo = () => { const prefix = globalConfig.findRelatedTests diff --git a/packages/jest-util/src/TestPathPatterns.ts b/packages/jest-util/src/TestPathPatterns.ts index 46452b631acb..c295682c58fd 100644 --- a/packages/jest-util/src/TestPathPatterns.ts +++ b/packages/jest-util/src/TestPathPatterns.ts @@ -8,40 +8,30 @@ import type {Config} from '@jest/types'; import {escapePathForRegex, replacePathSepForRegex} from 'jest-regex-util'; -type PatternsConfig = Pick; -type PatternsFullConfig = PatternsConfig & - Pick; +type PatternsConfig = { + rootDir: string; +}; export default class TestPathPatterns { - readonly patterns: Array; - private readonly rootDir: string; - private _regexString: string | null = null; - constructor(patterns: Array, config: PatternsConfig); - constructor(config: PatternsFullConfig); constructor( - patternsOrConfig: Array | PatternsFullConfig, - configArg?: PatternsConfig, - ) { - let patterns, config; - if (Array.isArray(patternsOrConfig)) { - patterns = patternsOrConfig; - config = configArg!; - } else { - patterns = patternsOrConfig.testPathPatterns; - config = patternsOrConfig; - } + readonly patterns: Array, + private readonly config: PatternsConfig, + ) {} - this.patterns = patterns; - this.rootDir = config.rootDir.replace(/\/*$/, '/'); + static fromGlobalConfig(globalConfig: Config.GlobalConfig): TestPathPatterns { + return new TestPathPatterns(globalConfig.testPathPatterns, globalConfig); } private get regexString(): string { if (this._regexString !== null) { return this._regexString; } - const rootDirRegex = escapePathForRegex(this.rootDir); + + const rootDir = this.config.rootDir.replace(/\/*$/, '/'); + const rootDirRegex = escapePathForRegex(rootDir); + const regexString = this.patterns .map(p => { // absolute paths passed on command line should stay same @@ -59,6 +49,7 @@ export default class TestPathPatterns { }) .map(replacePathSepForRegex) .join('|'); + this._regexString = regexString; return regexString; } From 042fddd47df71e4d89ed8fba2ed3b1ad463f3099 Mon Sep 17 00:00:00 2001 From: Brandon Chinn Date: Sun, 24 Sep 2023 17:20:31 -0700 Subject: [PATCH 18/22] Update docs --- docs/CLI.md | 4 ++-- docs/WatchPlugins.md | 2 +- packages/jest-util/Readme.md | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/docs/CLI.md b/docs/CLI.md index 033fa6a83069..c8cb41e6bf11 100644 --- a/docs/CLI.md +++ b/docs/CLI.md @@ -481,11 +481,11 @@ The regex is matched against the full name, which is a combination of the test n ### `--testPathIgnorePatterns=|[array]` -A single or array of regexp pattern strings that are tested against all tests paths before executing the test. Contrary to `--testPathPattern`, it will only run those tests with a path that does not match with the provided regexp expressions. +A single or array of regexp pattern strings that are tested against all tests paths before executing the test. Contrary to `--testPathPatterns`, it will only run those tests with a path that does not match with the provided regexp expressions. To pass as an array use escaped parentheses and space delimited regexps such as `\(/node_modules/ /tests/e2e/\)`. Alternatively, you can omit parentheses by combining regexps into a single regexp like `/node_modules/|/tests/e2e/`. These two examples are equivalent. -### `--testPathPattern=` +### `--testPathPatterns=` A regexp pattern string that is matched against all tests paths before executing the test. On Windows, you will need to use `/` as a path separator or escape `\` as `\\`. diff --git a/docs/WatchPlugins.md b/docs/WatchPlugins.md index ff7378860f8e..451834499593 100644 --- a/docs/WatchPlugins.md +++ b/docs/WatchPlugins.md @@ -172,7 +172,7 @@ For stability and safety reasons, only part of the global configuration keys can - [`onlyFailures`](configuration#onlyfailures-boolean) - [`reporters`](configuration#reporters-arraymodulename--modulename-options) - [`testNamePattern`](cli#--testnamepatternregex) -- [`testPathPatterns`](cli#--testpathpatternregex) +- [`testPathPatterns`](cli#--testpathpatternsregex) - [`updateSnapshot`](cli#--updatesnapshot) - [`verbose`](configuration#verbose-boolean) diff --git a/packages/jest-util/Readme.md b/packages/jest-util/Readme.md index 15f6daa4ad81..8b03e1ef7862 100644 --- a/packages/jest-util/Readme.md +++ b/packages/jest-util/Readme.md @@ -78,9 +78,9 @@ Used to set properties with specified values within a global object. It is desig It defines constants and conditional values for handling platform-specific behaviors in a terminal environment. It determines if the current platform is Windows ('win32') and sets up constants for various symbols and terminal screen clearing escape sequences accordingly, ensuring proper display and behavior on both Windows and non-Windows operating systems. -## `testPathPatternToRegExp` +## `TestPathPatterns` -This function is used for consistency when serializing/deserializing global configurations and ensures that consistent regular expressions are produced for matching test paths. +This class takes test patterns and provides the API for deciding if a test matches any of the patterns. ## `tryRealpath` From a52fc2f3ce22a28eb4726a1114b819ad785a7b88 Mon Sep 17 00:00:00 2001 From: Brandon Chinn Date: Sun, 24 Sep 2023 17:49:17 -0700 Subject: [PATCH 19/22] Add deprecation error for --testPathPattern --- packages/jest-config/src/Deprecated.ts | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/packages/jest-config/src/Deprecated.ts b/packages/jest-config/src/Deprecated.ts index be90f76d75d6..81dd9dc68cd8 100644 --- a/packages/jest-config/src/Deprecated.ts +++ b/packages/jest-config/src/Deprecated.ts @@ -8,6 +8,15 @@ import chalk = require('chalk'); import type {DeprecatedOptions} from 'jest-validate'; +function formatDeprecation(message: string): string { + const lines = [ + message.replace(/\*(.+?)\*/g, (_, s) => chalk.bold(`"${s}"`)), + '', + 'Please update your configuration.', + ]; + return lines.map(s => ` ${s}`).join('\n'); +} + const deprecatedOptions: DeprecatedOptions = { browser: () => ` Option ${chalk.bold( @@ -78,6 +87,11 @@ const deprecatedOptions: DeprecatedOptions = { Please update your configuration. `, + testPathPattern: () => + formatDeprecation( + 'Option *testPathPattern* was replaced by *testPathPatterns*.', + ), + testURL: (_options: {testURL?: string}) => ` Option ${chalk.bold( '"testURL"', )} was replaced by passing the URL via ${chalk.bold( From 70a3999c92c065282d80cf3fc442c4772819ada9 Mon Sep 17 00:00:00 2001 From: Brandon Chinn Date: Sun, 24 Sep 2023 17:01:59 -0700 Subject: [PATCH 20/22] Convert isValid() to validate() --- packages/jest-config/src/normalize.ts | 29 ++++++++++--------- packages/jest-util/src/TestPathPatterns.ts | 19 ++++-------- .../src/__tests__/TestPathPatterns.test.ts | 16 +++++----- 3 files changed, 30 insertions(+), 34 deletions(-) diff --git a/packages/jest-config/src/normalize.ts b/packages/jest-config/src/normalize.ts index d9e07c5db1d1..0a13aa8d298e 100644 --- a/packages/jest-config/src/normalize.ts +++ b/packages/jest-config/src/normalize.ts @@ -406,23 +406,24 @@ const buildTestPathPatterns = ( const config = {rootDir}; const testPathPatterns = new TestPathPatterns(patterns, config); - if (!testPathPatterns.isValid()) { - showTestPathPatternsError(testPathPatterns); + + try { + testPathPatterns.validate(); + } catch { + clearLine(process.stdout); + + // eslint-disable-next-line no-console + console.log( + chalk.red( + ` Invalid testPattern ${testPathPatterns.toPretty()} supplied. ` + + 'Running all tests instead.', + ), + ); + return new TestPathPatterns([], config); } - return testPathPatterns; -}; - -const showTestPathPatternsError = (testPathPatterns: TestPathPatterns) => { - clearLine(process.stdout); - // eslint-disable-next-line no-console - console.log( - chalk.red( - ` Invalid testPattern ${testPathPatterns.toPretty()} supplied. ` + - 'Running all tests instead.', - ), - ); + return testPathPatterns; }; function validateExtensionsToTreatAsEsm( diff --git a/packages/jest-util/src/TestPathPatterns.ts b/packages/jest-util/src/TestPathPatterns.ts index c295682c58fd..d8a3997e4ec0 100644 --- a/packages/jest-util/src/TestPathPatterns.ts +++ b/packages/jest-util/src/TestPathPatterns.ts @@ -54,7 +54,7 @@ export default class TestPathPatterns { return regexString; } - private get regex(): RegExp { + private toRegex(): RegExp { return new RegExp(this.regexString, 'i'); } @@ -66,26 +66,19 @@ export default class TestPathPatterns { } /** - * Return true if the patterns form a valid regex. + * Throw an error if the patterns don't form a valid regex. */ - isValid(): boolean { - try { - // @ts-expect-error noUnusedLocals - // eslint-disable-next-line @typescript-eslint/no-unused-vars - const _ = this.regex; - return true; - } catch { - return false; - } + validate(): void { + this.toRegex(); } /** * Return true if the given ABSOLUTE path matches the patterns. * - * Throws an error if the patterns form an invalid regex (see `isValid`). + * Throws an error if the patterns form an invalid regex (see `validate`). */ isMatch(path: string): boolean { - return this.regex.test(path); + return this.toRegex().test(path); } /** diff --git a/packages/jest-util/src/__tests__/TestPathPatterns.test.ts b/packages/jest-util/src/__tests__/TestPathPatterns.test.ts index 26e997d74213..39c8f272efa1 100644 --- a/packages/jest-util/src/__tests__/TestPathPatterns.test.ts +++ b/packages/jest-util/src/__tests__/TestPathPatterns.test.ts @@ -36,23 +36,25 @@ describe('TestPathPatterns', () => { }); }); - describe('isValid', () => { - it('returns true for empty patterns', () => { + describe('validate', () => { + it('succeeds for empty patterns', () => { const testPathPatterns = new TestPathPatterns([], config); - expect(testPathPatterns.isValid()).toBe(true); + expect(() => testPathPatterns.validate()).not.toThrow(); }); - it('returns true for valid patterns', () => { + it('succeeds for valid patterns', () => { const testPathPatterns = new TestPathPatterns(['abc+', 'z.*'], config); - expect(testPathPatterns.isValid()).toBe(true); + expect(() => testPathPatterns.validate()).not.toThrow(); }); - it('returns false for at least one invalid pattern', () => { + it('fails for at least one invalid pattern', () => { const testPathPatterns = new TestPathPatterns( ['abc+', '(', 'z.*'], config, ); - expect(testPathPatterns.isValid()).toBe(false); + expect(() => testPathPatterns.validate()).toThrow( + 'Invalid regular expression', + ); }); }); From 3c22ef31dde1b7b0df43dd088e2de018b7a055d1 Mon Sep 17 00:00:00 2001 From: Brandon Chinn Date: Fri, 29 Sep 2023 17:02:01 -0700 Subject: [PATCH 21/22] Make toPretty() render prettier output --- .../cliHandlesExactFilenames.test.ts.snap | 2 +- .../__snapshots__/customReporters.test.ts.snap | 2 +- .../emptyDescribeWithHooks.test.ts.snap | 8 ++++---- .../__snapshots__/findRelatedFiles.test.ts.snap | 4 ++-- e2e/__tests__/__snapshots__/nativeEsm.test.ts.snap | 14 +++++++------- .../promiseAsyncHandling.test.ts.snap | 12 ++++++------ e2e/__tests__/__snapshots__/snapshot.test.ts.snap | 14 +++++++------- .../__snapshots__/stackTrace.test.ts.snap | 14 +++++++------- e2e/__tests__/__snapshots__/testTodo.test.ts.snap | 2 +- .../__snapshots__/watchModePatterns.test.ts.snap | 2 +- e2e/__tests__/findRelatedFiles.test.ts | 8 ++++---- e2e/__tests__/multiProjectRunner.test.ts | 2 +- .../testPathPatternReporterMessage.test.ts | 8 ++++---- .../__tests__/__snapshots__/normalize.test.ts.snap | 4 ++-- .../getNoTestsFoundMessage.test.ts.snap | 6 +++--- packages/jest-util/src/TestPathPatterns.ts | 6 +----- .../__snapshots__/TestPathPatterns.test.ts.snap | 2 +- 17 files changed, 53 insertions(+), 57 deletions(-) diff --git a/e2e/__tests__/__snapshots__/cliHandlesExactFilenames.test.ts.snap b/e2e/__tests__/__snapshots__/cliHandlesExactFilenames.test.ts.snap index 4eb172dc686b..e8c3c1073714 100644 --- a/e2e/__tests__/__snapshots__/cliHandlesExactFilenames.test.ts.snap +++ b/e2e/__tests__/__snapshots__/cliHandlesExactFilenames.test.ts.snap @@ -13,5 +13,5 @@ exports[`CLI accepts exact file names if matchers matched 2`] = ` Tests: 1 passed, 1 total Snapshots: 0 total Time: <> -Ran all test suites matching /.\\/foo\\/bar.spec.js/i." +Ran all test suites matching ./foo/bar.spec.js." `; diff --git a/e2e/__tests__/__snapshots__/customReporters.test.ts.snap b/e2e/__tests__/__snapshots__/customReporters.test.ts.snap index 7506630b07d2..d3fa7a739372 100644 --- a/e2e/__tests__/__snapshots__/customReporters.test.ts.snap +++ b/e2e/__tests__/__snapshots__/customReporters.test.ts.snap @@ -82,7 +82,7 @@ exports[`Custom Reporters Integration default reporters enabled 2`] = ` Tests: 1 passed, 1 total Snapshots: 0 total Time: <> -Ran all test suites matching /add.test.js/i." +Ran all test suites matching add.test.js." `; exports[`Custom Reporters Integration default reporters enabled 3`] = ` diff --git a/e2e/__tests__/__snapshots__/emptyDescribeWithHooks.test.ts.snap b/e2e/__tests__/__snapshots__/emptyDescribeWithHooks.test.ts.snap index ad2f6318c6ed..71a0140e2a86 100644 --- a/e2e/__tests__/__snapshots__/emptyDescribeWithHooks.test.ts.snap +++ b/e2e/__tests__/__snapshots__/emptyDescribeWithHooks.test.ts.snap @@ -7,7 +7,7 @@ Object { Tests: 1 skipped, 1 total Snapshots: 0 total Time: <> -Ran all test suites matching /hookInDescribeWithSkippedTest.test.js/i.", +Ran all test suites matching hookInDescribeWithSkippedTest.test.js.", } `; @@ -34,7 +34,7 @@ Object { Tests: 1 passed, 1 total Snapshots: 0 total Time: <> -Ran all test suites matching /hookInEmptyDescribe.test.js/i.", +Ran all test suites matching hookInEmptyDescribe.test.js.", } `; @@ -61,7 +61,7 @@ Object { Tests: 1 passed, 1 total Snapshots: 0 total Time: <> -Ran all test suites matching /hookInEmptyNestedDescribe.test.js/i.", +Ran all test suites matching hookInEmptyNestedDescribe.test.js.", } `; @@ -133,6 +133,6 @@ Object { Tests: 1 passed, 1 total Snapshots: 0 total Time: <> -Ran all test suites matching /multipleHooksInEmptyDescribe.test.js/i.", +Ran all test suites matching multipleHooksInEmptyDescribe.test.js.", } `; diff --git a/e2e/__tests__/__snapshots__/findRelatedFiles.test.ts.snap b/e2e/__tests__/__snapshots__/findRelatedFiles.test.ts.snap index d21e158b8bf1..7c1eb192a715 100644 --- a/e2e/__tests__/__snapshots__/findRelatedFiles.test.ts.snap +++ b/e2e/__tests__/__snapshots__/findRelatedFiles.test.ts.snap @@ -5,7 +5,7 @@ exports[`--findRelatedTests flag coverage configuration is applied correctly 1`] Tests: 1 passed, 1 total Snapshots: 0 total Time: <> -Ran all test suites related to files matching /a.js|b.js/i." +Ran all test suites related to files matching a.js|b.js." `; exports[`--findRelatedTests flag coverage configuration is applied correctly 2`] = ` @@ -50,7 +50,7 @@ exports[`--findRelatedTests flag generates coverage report for filename 4`] = ` Tests: 1 passed, 1 total Snapshots: 0 total Time: <> -Ran all test suites related to files matching /a.js/i." +Ran all test suites related to files matching a.js." `; exports[`--findRelatedTests flag generates coverage report for filename 5`] = ` diff --git a/e2e/__tests__/__snapshots__/nativeEsm.test.ts.snap b/e2e/__tests__/__snapshots__/nativeEsm.test.ts.snap index c1b2cee1867c..9fdb7076fde4 100644 --- a/e2e/__tests__/__snapshots__/nativeEsm.test.ts.snap +++ b/e2e/__tests__/__snapshots__/nativeEsm.test.ts.snap @@ -5,7 +5,7 @@ exports[`does not enforce import assertions 1`] = ` Tests: 2 passed, 2 total Snapshots: 0 total Time: <> -Ran all test suites matching /native-esm-missing-import-assertions.test/i." +Ran all test suites matching native-esm-missing-import-assertions.test." `; exports[`on node >=16.9.0 support re-exports from CJS of dual packages 1`] = ` @@ -13,7 +13,7 @@ exports[`on node >=16.9.0 support re-exports from CJS of dual packages 1`] = ` Tests: 1 passed, 1 total Snapshots: 0 total Time: <> -Ran all test suites matching /native-esm-deep-cjs-reexport.test.js/i." +Ran all test suites matching native-esm-deep-cjs-reexport.test.js." `; exports[`on node >=16.12.0 supports import assertions 1`] = ` @@ -21,7 +21,7 @@ exports[`on node >=16.12.0 supports import assertions 1`] = ` Tests: 2 passed, 2 total Snapshots: 0 total Time: <> -Ran all test suites matching /native-esm-import-assertions.test/i." +Ran all test suites matching native-esm-import-assertions.test." `; exports[`runs WebAssembly (Wasm) test with native ESM 1`] = ` @@ -29,7 +29,7 @@ exports[`runs WebAssembly (Wasm) test with native ESM 1`] = ` Tests: 6 passed, 6 total Snapshots: 0 total Time: <> -Ran all test suites matching /native-esm-wasm.test.js/i." +Ran all test suites matching native-esm-wasm.test.js." `; exports[`runs test with native ESM 1`] = ` @@ -37,7 +37,7 @@ exports[`runs test with native ESM 1`] = ` Tests: 33 passed, 33 total Snapshots: 0 total Time: <> -Ran all test suites matching /native-esm.test.js/i." +Ran all test suites matching native-esm.test.js." `; exports[`support re-exports from CJS of core module 1`] = ` @@ -45,7 +45,7 @@ exports[`support re-exports from CJS of core module 1`] = ` Tests: 1 passed, 1 total Snapshots: 0 total Time: <> -Ran all test suites matching /native-esm-core-cjs-reexport.test.js/i." +Ran all test suites matching native-esm-core-cjs-reexport.test.js." `; exports[`supports top-level await 1`] = ` @@ -53,5 +53,5 @@ exports[`supports top-level await 1`] = ` Tests: 1 passed, 1 total Snapshots: 0 total Time: <> -Ran all test suites matching /native-esm.tla.test.js/i." +Ran all test suites matching native-esm.tla.test.js." `; diff --git a/e2e/__tests__/__snapshots__/promiseAsyncHandling.test.ts.snap b/e2e/__tests__/__snapshots__/promiseAsyncHandling.test.ts.snap index 402a65e570c7..1ff8ca9e0dba 100644 --- a/e2e/__tests__/__snapshots__/promiseAsyncHandling.test.ts.snap +++ b/e2e/__tests__/__snapshots__/promiseAsyncHandling.test.ts.snap @@ -22,7 +22,7 @@ Object { Tests: 1 passed, 1 total Snapshots: 0 total Time: <> -Ran all test suites matching /unhandledRejectionAfterAll.test.js/i.", +Ran all test suites matching unhandledRejectionAfterAll.test.js.", } `; @@ -63,7 +63,7 @@ Object { Tests: 2 failed, 2 total Snapshots: 0 total Time: <> -Ran all test suites matching /unhandledRejectionAfterEach.test.js/i.", +Ran all test suites matching unhandledRejectionAfterEach.test.js.", } `; @@ -89,7 +89,7 @@ Object { Tests: 1 failed, 1 total Snapshots: 0 total Time: <> -Ran all test suites matching /unhandledRejectionBeforeAll.test.js/i.", +Ran all test suites matching unhandledRejectionBeforeAll.test.js.", } `; @@ -130,7 +130,7 @@ Object { Tests: 2 failed, 2 total Snapshots: 0 total Time: <> -Ran all test suites matching /unhandledRejectionBeforeEach.test.js/i.", +Ran all test suites matching unhandledRejectionBeforeEach.test.js.", } `; @@ -217,7 +217,7 @@ Object { Tests: 4 failed, 4 total Snapshots: 0 total Time: <> -Ran all test suites matching /unhandledRejectionTest.test.js/i.", +Ran all test suites matching unhandledRejectionTest.test.js.", } `; @@ -231,6 +231,6 @@ Object { Tests: 3 passed, 3 total Snapshots: 0 total Time: <> -Ran all test suites matching /rejectionHandled.test.js/i.", +Ran all test suites matching rejectionHandled.test.js.", } `; diff --git a/e2e/__tests__/__snapshots__/snapshot.test.ts.snap b/e2e/__tests__/__snapshots__/snapshot.test.ts.snap index 811a7727b08a..e6d85efff184 100644 --- a/e2e/__tests__/__snapshots__/snapshot.test.ts.snap +++ b/e2e/__tests__/__snapshots__/snapshot.test.ts.snap @@ -85,7 +85,7 @@ exports[`Snapshot works with escaped characters 1`] = ` Tests: 1 passed, 1 total Snapshots: 1 written, 1 total Time: <> -Ran all test suites matching /snapshot.test.js/i." +Ran all test suites matching snapshot.test.js." `; exports[`Snapshot works with escaped characters 2`] = ` @@ -93,7 +93,7 @@ exports[`Snapshot works with escaped characters 2`] = ` Tests: 2 passed, 2 total Snapshots: 1 written, 1 passed, 2 total Time: <> -Ran all test suites matching /snapshot.test.js/i." +Ran all test suites matching snapshot.test.js." `; exports[`Snapshot works with escaped characters 3`] = ` @@ -101,7 +101,7 @@ exports[`Snapshot works with escaped characters 3`] = ` Tests: 2 passed, 2 total Snapshots: 2 passed, 2 total Time: <> -Ran all test suites matching /snapshot.test.js/i." +Ran all test suites matching snapshot.test.js." `; exports[`Snapshot works with escaped regex 1`] = ` @@ -109,7 +109,7 @@ exports[`Snapshot works with escaped regex 1`] = ` Tests: 2 passed, 2 total Snapshots: 2 written, 2 total Time: <> -Ran all test suites matching /snapshotEscapeRegex.js/i." +Ran all test suites matching snapshotEscapeRegex.js." `; exports[`Snapshot works with escaped regex 2`] = ` @@ -117,7 +117,7 @@ exports[`Snapshot works with escaped regex 2`] = ` Tests: 2 passed, 2 total Snapshots: 2 passed, 2 total Time: <> -Ran all test suites matching /snapshotEscapeRegex.js/i." +Ran all test suites matching snapshotEscapeRegex.js." `; exports[`Snapshot works with template literal substitutions 1`] = ` @@ -125,7 +125,7 @@ exports[`Snapshot works with template literal substitutions 1`] = ` Tests: 1 passed, 1 total Snapshots: 1 written, 1 total Time: <> -Ran all test suites matching /snapshotEscapeSubstitution.test.js/i." +Ran all test suites matching snapshotEscapeSubstitution.test.js." `; exports[`Snapshot works with template literal substitutions 2`] = ` @@ -133,5 +133,5 @@ exports[`Snapshot works with template literal substitutions 2`] = ` Tests: 1 passed, 1 total Snapshots: 1 passed, 1 total Time: <> -Ran all test suites matching /snapshotEscapeSubstitution.test.js/i." +Ran all test suites matching snapshotEscapeSubstitution.test.js." `; diff --git a/e2e/__tests__/__snapshots__/stackTrace.test.ts.snap b/e2e/__tests__/__snapshots__/stackTrace.test.ts.snap index e06101e24809..ecc0b1cbf61c 100644 --- a/e2e/__tests__/__snapshots__/stackTrace.test.ts.snap +++ b/e2e/__tests__/__snapshots__/stackTrace.test.ts.snap @@ -5,7 +5,7 @@ exports[`Stack Trace does not print a stack trace for errors when --noStackTrace Tests: 3 failed, 3 total Snapshots: 0 total Time: <> -Ran all test suites matching /testError.test.js/i." +Ran all test suites matching testError.test.js." `; exports[`Stack Trace does not print a stack trace for matching errors when --noStackTrace is given 1`] = ` @@ -13,7 +13,7 @@ exports[`Stack Trace does not print a stack trace for matching errors when --noS Tests: 1 failed, 1 total Snapshots: 0 total Time: <> -Ran all test suites matching /stackTrace.test.js/i." +Ran all test suites matching stackTrace.test.js." `; exports[`Stack Trace does not print a stack trace for runtime errors when --noStackTrace is given 1`] = ` @@ -21,7 +21,7 @@ exports[`Stack Trace does not print a stack trace for runtime errors when --noSt Tests: 0 total Snapshots: 0 total Time: <> -Ran all test suites matching /runtimeError.test.js/i." +Ran all test suites matching runtimeError.test.js." `; exports[`Stack Trace prints a stack trace for errors 1`] = ` @@ -29,7 +29,7 @@ exports[`Stack Trace prints a stack trace for errors 1`] = ` Tests: 3 failed, 3 total Snapshots: 0 total Time: <> -Ran all test suites matching /testError.test.js/i." +Ran all test suites matching testError.test.js." `; exports[`Stack Trace prints a stack trace for errors without message in stack trace 1`] = ` @@ -37,7 +37,7 @@ exports[`Stack Trace prints a stack trace for errors without message in stack tr Tests: 1 failed, 1 total Snapshots: 0 total Time: <> -Ran all test suites matching /stackTraceWithoutMessage.test.js/i." +Ran all test suites matching stackTraceWithoutMessage.test.js." `; exports[`Stack Trace prints a stack trace for matching errors 1`] = ` @@ -45,7 +45,7 @@ exports[`Stack Trace prints a stack trace for matching errors 1`] = ` Tests: 1 failed, 1 total Snapshots: 0 total Time: <> -Ran all test suites matching /stackTrace.test.js/i." +Ran all test suites matching stackTrace.test.js." `; exports[`Stack Trace prints a stack trace for runtime errors 1`] = ` @@ -53,5 +53,5 @@ exports[`Stack Trace prints a stack trace for runtime errors 1`] = ` Tests: 0 total Snapshots: 0 total Time: <> -Ran all test suites matching /runtimeError.test.js/i." +Ran all test suites matching runtimeError.test.js." `; diff --git a/e2e/__tests__/__snapshots__/testTodo.test.ts.snap b/e2e/__tests__/__snapshots__/testTodo.test.ts.snap index a9e1ff123e2b..3f5f1d950276 100644 --- a/e2e/__tests__/__snapshots__/testTodo.test.ts.snap +++ b/e2e/__tests__/__snapshots__/testTodo.test.ts.snap @@ -11,7 +11,7 @@ Test Suites: 1 passed, 1 total Tests: 2 todo, 1 passed, 3 total Snapshots: 0 total Time: <> -Ran all test suites matching /only-todo.test.js/i." +Ran all test suites matching only-todo.test.js." `; exports[`shows error messages when called with invalid argument 1`] = ` diff --git a/e2e/__tests__/__snapshots__/watchModePatterns.test.ts.snap b/e2e/__tests__/__snapshots__/watchModePatterns.test.ts.snap index 1a0e4d7b91ae..185caf8c8f20 100644 --- a/e2e/__tests__/__snapshots__/watchModePatterns.test.ts.snap +++ b/e2e/__tests__/__snapshots__/watchModePatterns.test.ts.snap @@ -66,7 +66,7 @@ exports[`can press "p" to filter by file name: test summary 2`] = ` Tests: 2 passed, 2 total Snapshots: 0 total Time: <> -Ran all test suites matching /bar/i." +Ran all test suites matching bar." `; exports[`can press "t" to filter by test name 1`] = ` diff --git a/e2e/__tests__/findRelatedFiles.test.ts b/e2e/__tests__/findRelatedFiles.test.ts index f889ac8a4573..525fadf59394 100644 --- a/e2e/__tests__/findRelatedFiles.test.ts +++ b/e2e/__tests__/findRelatedFiles.test.ts @@ -33,7 +33,7 @@ describe('--findRelatedTests flag', () => { const {stderr} = runJest(DIR, ['--findRelatedTests', 'a.js']); expect(stderr).toMatch('PASS __tests__/test.test.js'); - const summaryMsg = 'Ran all test suites related to files matching /a.js/i.'; + const summaryMsg = 'Ran all test suites related to files matching a.js.'; expect(stderr).toMatch(summaryMsg); }); @@ -59,7 +59,7 @@ describe('--findRelatedTests flag', () => { const {stderr} = runJest(DIR, ['--findRelatedTests', 'A.JS']); expect(stderr).toMatch('PASS __tests__/test.test.js'); - const summaryMsg = 'Ran all test suites related to files matching /A.JS/i.'; + const summaryMsg = 'Ran all test suites related to files matching A.JS.'; expect(stderr).toMatch(summaryMsg); }); @@ -112,7 +112,7 @@ describe('--findRelatedTests flag', () => { expect(stderr).toMatch('PASS __tests__/test.test.js'); expect(stderr).not.toMatch('PASS __tests__/test-skip-deps.test.js'); - const summaryMsg = 'Ran all test suites related to files matching /a.js/i.'; + const summaryMsg = 'Ran all test suites related to files matching a.js.'; expect(stderr).toMatch(summaryMsg); }); @@ -162,7 +162,7 @@ describe('--findRelatedTests flag', () => { expect(stderr).toMatch('PASS __tests__/test.test.js'); expect(stderr).not.toMatch('PASS __tests__/test-skip-deps.test.js'); - const summaryMsg = 'Ran all test suites related to files matching /a.js/i.'; + const summaryMsg = 'Ran all test suites related to files matching a.js.'; expect(stderr).toMatch(summaryMsg); }); diff --git a/e2e/__tests__/multiProjectRunner.test.ts b/e2e/__tests__/multiProjectRunner.test.ts index b9dea4a2fadd..84a4e79dd928 100644 --- a/e2e/__tests__/multiProjectRunner.test.ts +++ b/e2e/__tests__/multiProjectRunner.test.ts @@ -155,7 +155,7 @@ test('"No tests found" message for projects', () => { 'project1', 'project2', ]); - expect(verboseOutput).toContain('Pattern: /xyz321/i - 0 matches'); + expect(verboseOutput).toContain('Pattern: xyz321 - 0 matches'); const {stdout} = runJest(DIR, [ '--no-watchman', 'xyz321', diff --git a/e2e/__tests__/testPathPatternReporterMessage.test.ts b/e2e/__tests__/testPathPatternReporterMessage.test.ts index 5a2f79fa3b94..2f9a2d3c5714 100644 --- a/e2e/__tests__/testPathPatternReporterMessage.test.ts +++ b/e2e/__tests__/testPathPatternReporterMessage.test.ts @@ -25,14 +25,14 @@ test('prints a message with path pattern at the end', () => { let stderr; ({stderr} = runJest(DIR, ['a'])); - expect(stderr).toMatch('Ran all test suites matching /a/i'); + expect(stderr).toMatch('Ran all test suites matching a'); ({stderr} = runJest(DIR, ['a', 'b'])); - expect(stderr).toMatch('Ran all test suites matching /a|b/i'); + expect(stderr).toMatch('Ran all test suites matching a|b'); ({stderr} = runJest(DIR, ['--testPathPatterns', 'a'])); - expect(stderr).toMatch('Ran all test suites matching /a/i'); + expect(stderr).toMatch('Ran all test suites matching a'); ({stderr} = runJest(DIR, ['--testPathPatterns', 'a|b'])); - expect(stderr).toMatch('Ran all test suites matching /a|b/i'); + expect(stderr).toMatch('Ran all test suites matching a|b'); }); diff --git a/packages/jest-config/src/__tests__/__snapshots__/normalize.test.ts.snap b/packages/jest-config/src/__tests__/__snapshots__/normalize.test.ts.snap index ac0a7cfacf49..990000454eeb 100644 --- a/packages/jest-config/src/__tests__/__snapshots__/normalize.test.ts.snap +++ b/packages/jest-config/src/__tests__/__snapshots__/normalize.test.ts.snap @@ -482,9 +482,9 @@ exports[`testMatch throws if testRegex and testMatch are both specified 1`] = ` " `; -exports[`testPathPatterns ignores invalid regular expressions and logs a warning 1`] = `" Invalid testPattern /a(/i supplied. Running all tests instead."`; +exports[`testPathPatterns ignores invalid regular expressions and logs a warning 1`] = `" Invalid testPattern a( supplied. Running all tests instead."`; -exports[`testPathPatterns --testPathPatterns ignores invalid regular expressions and logs a warning 1`] = `" Invalid testPattern /a(/i supplied. Running all tests instead."`; +exports[`testPathPatterns --testPathPatterns ignores invalid regular expressions and logs a warning 1`] = `" Invalid testPattern a( supplied. Running all tests instead."`; exports[`testTimeout should throw an error if timeout is a negative number 1`] = ` "Validation Error: diff --git a/packages/jest-core/src/__tests__/__snapshots__/getNoTestsFoundMessage.test.ts.snap b/packages/jest-core/src/__tests__/__snapshots__/getNoTestsFoundMessage.test.ts.snap index 2d6a1af3e481..059aa966f758 100644 --- a/packages/jest-core/src/__tests__/__snapshots__/getNoTestsFoundMessage.test.ts.snap +++ b/packages/jest-core/src/__tests__/__snapshots__/getNoTestsFoundMessage.test.ts.snap @@ -23,7 +23,7 @@ Object { Run with \`--passWithNoTests\` to exit with code 0 In /root/dir 0 files checked across 0 projects. Run with \`--verbose\` for more details. -Pattern: /\\/path\\/pattern/i - 0 matches", +Pattern: /path/pattern - 0 matches", } `; @@ -47,7 +47,7 @@ Object { "message": "No tests found, exiting with code 1 Run with \`--passWithNoTests\` to exit with code 0 -Pattern: /\\/path\\/pattern/i - 0 matches", +Pattern: /path/pattern - 0 matches", } `; @@ -58,6 +58,6 @@ Object { Run with \`--passWithNoTests\` to exit with code 0 In /root/dir 0 files checked across 0 projects. Run with \`--verbose\` for more details. -Pattern: /\\/path\\/pattern/i - 0 matches", +Pattern: /path/pattern - 0 matches", } `; diff --git a/packages/jest-util/src/TestPathPatterns.ts b/packages/jest-util/src/TestPathPatterns.ts index d8a3997e4ec0..2c5856e4932a 100644 --- a/packages/jest-util/src/TestPathPatterns.ts +++ b/packages/jest-util/src/TestPathPatterns.ts @@ -83,12 +83,8 @@ export default class TestPathPatterns { /** * Return a human-friendly version of the pattern regex. - * - * Does no normalization or anything, just a naive joining of the regex, - * for simplicity. */ toPretty(): string { - const regex = this.patterns.map(p => p.replace(/\//g, '\\/')).join('|'); - return `/${regex}/i`; + return this.patterns.join('|'); } } diff --git a/packages/jest-util/src/__tests__/__snapshots__/TestPathPatterns.test.ts.snap b/packages/jest-util/src/__tests__/__snapshots__/TestPathPatterns.test.ts.snap index e845164fb162..5b97f3ca2f59 100644 --- a/packages/jest-util/src/__tests__/__snapshots__/TestPathPatterns.test.ts.snap +++ b/packages/jest-util/src/__tests__/__snapshots__/TestPathPatterns.test.ts.snap @@ -1,3 +1,3 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`TestPathPatterns toPretty renders a human-readable string 1`] = `"/a\\/b|c\\/d/i"`; +exports[`TestPathPatterns toPretty renders a human-readable string 1`] = `"a/b|c/d"`; From 09aed7d4c65fcf03f00b7bac3bd5fbd4fb803b21 Mon Sep 17 00:00:00 2001 From: Simen Bekkhus Date: Mon, 2 Oct 2023 14:21:48 +0200 Subject: [PATCH 22/22] oops --- e2e/__tests__/__snapshots__/nativeEsm.test.ts.snap | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/e2e/__tests__/__snapshots__/nativeEsm.test.ts.snap b/e2e/__tests__/__snapshots__/nativeEsm.test.ts.snap index 2133484b3c4a..96bf4cb3c3f9 100644 --- a/e2e/__tests__/__snapshots__/nativeEsm.test.ts.snap +++ b/e2e/__tests__/__snapshots__/nativeEsm.test.ts.snap @@ -21,12 +21,7 @@ exports[`on node >=16.12.0 supports import assertions 1`] = ` Tests: 2 passed, 2 total Snapshots: 0 total Time: <> -<<<<<<< HEAD -Ran all test suites matching native-esm-import-assertions.test." -||||||| b4c9587d19 -Ran all test suites matching /native-esm-import-assertions.test/i." -======= -Ran all test suites matching /native-esm-import-assertions.test.js/i." +Ran all test suites matching native-esm-import-assertions.test.js." `; exports[`properly handle re-exported native modules in ESM via CJS 1`] = `