Skip to content

Commit

Permalink
feat: --filter module returns array of strings, not objects (#13319)
Browse files Browse the repository at this point in the history
  • Loading branch information
brunocabral88 committed Nov 16, 2023
1 parent c04d13d commit 3e86cf3
Show file tree
Hide file tree
Showing 8 changed files with 42 additions and 26 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Expand Up @@ -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<string> }` 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))
Expand Down
9 changes: 5 additions & 4 deletions docs/CLI.md
Expand Up @@ -194,13 +194,14 @@ Alias: `-e`. Use this flag to show full diffs and errors instead of a patch.

### `--filter=<file>`

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<string> }` 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,
Expand Down
4 changes: 1 addition & 3 deletions e2e/filter/my-filter.js
Expand Up @@ -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);
});
Expand Down
2 changes: 1 addition & 1 deletion e2e/filter/my-secondary-filter.js
Expand Up @@ -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')),
};
};
4 changes: 1 addition & 3 deletions e2e/filter/my-setup-filter.js
Expand Up @@ -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)),
};
};

Expand Down
4 changes: 1 addition & 3 deletions packages/jest-core/src/SearchSource.ts
Expand Up @@ -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,
Expand Down
37 changes: 31 additions & 6 deletions packages/jest-core/src/__tests__/SearchSource.test.ts
Expand Up @@ -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);

Expand Down Expand Up @@ -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();
};

Expand Down Expand Up @@ -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<string>) =>
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', () => {
Expand Down
7 changes: 1 addition & 6 deletions packages/jest-core/src/types.ts
Expand Up @@ -34,11 +34,6 @@ export type TestPathCasesWithPathPattern = TestPathCases & {
testPathPatterns: (path: string) => boolean;
};

export type FilterResult = {
test: string;
message: string;
};

export type Filter = (testPaths: Array<string>) => Promise<{
filtered: Array<FilterResult>;
filtered: Array<string>;
}>;

0 comments on commit 3e86cf3

Please sign in to comment.