diff --git a/CHANGELOG.md b/CHANGELOG.md index e7ce33a18db0..dd908cf69363 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,7 @@ - `[jest-config]` [**BREAKING**] Update `testMatch` and `testRegex` default option for supporting `mjs`, `cjs`, `mts`, and `cts` ([#14584](https://github.com/jestjs/jest/pull/14584)) - `[@jest/core]` [**BREAKING**] Group together open handles with the same stack trace ([#13417](https://github.com/jestjs/jest/pull/13417), & [#14543](https://github.com/jestjs/jest/pull/14543)) - `[@jest/core]` Add `perfStats` to surface test setup overhead ([#14622](https://github.com/jestjs/jest/pull/14622)) +- `[@jest/core]` [**BREAKING**] Changed `--filter` to accept an object with shape `{ filtered: Array }` to match [documentation](https://jestjs.io/docs/cli#--filterfile) ([#13319](https://github.com/jestjs/jest/pull/13319)) - `[@jest/core, @jest/test-sequencer]` [**BREAKING**] Exposes `globalConfig` & `contexts` to `TestSequencer` ([#14535](https://github.com/jestjs/jest/pull/14535), & [#14543](https://github.com/jestjs/jest/pull/14543)) - `[jest-environment-jsdom]` [**BREAKING**] Upgrade JSDOM to v22 ([#13825](https://github.com/jestjs/jest/pull/13825)) - `[@jest/fake-timers]` [**BREAKING**] Upgrade `@sinonjs/fake-timers` to v11 ([#14544](https://github.com/jestjs/jest/pull/14544)) diff --git a/docs/CLI.md b/docs/CLI.md index e092a9e65332..de66a17e6034 100644 --- a/docs/CLI.md +++ b/docs/CLI.md @@ -194,13 +194,14 @@ Alias: `-e`. Use this flag to show full diffs and errors instead of a patch. ### `--filter=` -Path to a module exporting a filtering function. This asynchronous function receives a list of test paths which can be manipulated to exclude tests from running by returning an object with shape `{ filtered: Array<{ test: string }> }`. Especially useful when used in conjunction with a testing infrastructure to filter known broken tests, e.g. +Path to a module exporting a filtering function. This asynchronous function receives a list of test paths which can be manipulated to exclude tests from running and must return an object with shape `{ filtered: Array }` containing the tests that should be run by Jest. Especially useful when used in conjunction with a testing infrastructure to filter known broken tests. ```js title="my-filter.js" +// This filter when applied will only run tests ending in .spec.js (not the best way to do it, but it's just an example): +const filteringFunction = testPath => testPath.endsWith('.spec.js'); + module.exports = testPaths => { - const allowedPaths = testPaths - .filter(filteringFunction) - .map(test => ({test})); // [{ test: "path1.spec.js" }, { test: "path2.spec.js" }, etc] + const allowedPaths = testPaths.filter(filteringFunction); // ["path1.spec.js", "path2.spec.js", etc] return { filtered: allowedPaths, diff --git a/e2e/filter/my-filter.js b/e2e/filter/my-filter.js index 10c71b83630c..da0e2c761a00 100644 --- a/e2e/filter/my-filter.js +++ b/e2e/filter/my-filter.js @@ -11,9 +11,7 @@ module.exports = function (tests) { return new Promise(resolve => { setTimeout(() => { resolve({ - filtered: tests - .filter(t => t.includes('foo')) - .map(test => ({message: 'some message', test})), + filtered: tests.filter(t => t.includes('foo')), }); }, 100); }); diff --git a/e2e/filter/my-secondary-filter.js b/e2e/filter/my-secondary-filter.js index b6551712ee42..f729832e74d7 100644 --- a/e2e/filter/my-secondary-filter.js +++ b/e2e/filter/my-secondary-filter.js @@ -9,6 +9,6 @@ module.exports = function (tests) { return { - filtered: tests.filter(t => t.includes('foo')).map(test => ({test})), + filtered: tests.filter(t => t.includes('foo')), }; }; diff --git a/e2e/filter/my-setup-filter.js b/e2e/filter/my-setup-filter.js index 751568123d9e..02d797bb2aba 100644 --- a/e2e/filter/my-setup-filter.js +++ b/e2e/filter/my-setup-filter.js @@ -13,9 +13,7 @@ const setupData = { module.exports = function (tests) { return { - filtered: tests - .filter(t => t.includes(setupData.filterText)) - .map(test => ({test})), + filtered: tests.filter(t => t.includes(setupData.filterText)), }; }; diff --git a/packages/jest-core/src/SearchSource.ts b/packages/jest-core/src/SearchSource.ts index 681464ec7f44..abfc62de1566 100644 --- a/packages/jest-core/src/SearchSource.ts +++ b/packages/jest-core/src/SearchSource.ts @@ -339,9 +339,7 @@ export default class SearchSource { ); } - const filteredSet = new Set( - filterResult.filtered.map(result => result.test), - ); + const filteredSet = new Set(filterResult.filtered); return { ...searchResult, diff --git a/packages/jest-core/src/__tests__/SearchSource.test.ts b/packages/jest-core/src/__tests__/SearchSource.test.ts index fc93a8f03d7f..1ec593bbf37d 100644 --- a/packages/jest-core/src/__tests__/SearchSource.test.ts +++ b/packages/jest-core/src/__tests__/SearchSource.test.ts @@ -12,6 +12,7 @@ import type {Config} from '@jest/types'; import {normalize} from 'jest-config'; import Runtime from 'jest-runtime'; import SearchSource from '../SearchSource'; +import type {Filter} from '../types'; jest.setTimeout(15_000); @@ -105,13 +106,20 @@ describe('SearchSource', () => { }); describe('getTestPaths', () => { - const getTestPaths = async (initialOptions: Config.InitialOptions) => { + const getTestPaths = async ( + initialOptions: Config.InitialOptions, + filter?: Filter, + ) => { const {searchSource, config} = await initSearchSource(initialOptions); - const {tests: paths} = await searchSource.getTestPaths({ - ...config, - ...initialOptions, - testPathPatterns: [], - }); + const {tests: paths} = await searchSource.getTestPaths( + { + ...config, + ...initialOptions, + testPathPatterns: [], + }, + null, + filter, + ); return paths.map(({path: p}) => path.relative(rootDir, p)).sort(); }; @@ -292,6 +300,23 @@ describe('SearchSource', () => { path.normalize('__testtests__/test.jsx'), ]); }); + + it('filter tests based on an optional filter method', async () => { + const filterFunction = (testPaths: Array) => + Promise.resolve({ + filtered: testPaths.filter(testPath => testPath.includes('test.jsx')), + }); + const paths = await getTestPaths( + { + id, + rootDir, + }, + filterFunction, + ); + + expect(paths).toHaveLength(1); + expect(paths[0]).toStrictEqual(path.normalize('__testtests__/test.jsx')); + }); }); describe('filterPathsWin32', () => { diff --git a/packages/jest-core/src/types.ts b/packages/jest-core/src/types.ts index 3aaece51f060..25776017166e 100644 --- a/packages/jest-core/src/types.ts +++ b/packages/jest-core/src/types.ts @@ -34,11 +34,6 @@ export type TestPathCasesWithPathPattern = TestPathCases & { testPathPatterns: (path: string) => boolean; }; -export type FilterResult = { - test: string; - message: string; -}; - export type Filter = (testPaths: Array) => Promise<{ - filtered: Array; + filtered: Array; }>;