Skip to content

Commit

Permalink
Break out TestPathPatternsExecutor
Browse files Browse the repository at this point in the history
  • Loading branch information
brandonchinn178 committed Mar 7, 2024
1 parent c124aaf commit 831e3a9
Show file tree
Hide file tree
Showing 17 changed files with 157 additions and 81 deletions.
2 changes: 1 addition & 1 deletion e2e/runJest.ts
Original file line number Diff line number Diff line change
Expand Up @@ -288,6 +288,6 @@ export function getConfig(

return {
...globalConfig,
testPathPatterns: new TestPathPatterns(testPathPatterns, {rootDir: '/'}),
testPathPatterns: new TestPathPatterns(testPathPatterns),
};
}
12 changes: 4 additions & 8 deletions packages/jest-config/src/normalize.ts
Original file line number Diff line number Diff line change
Expand Up @@ -392,10 +392,7 @@ const normalizeReporters = ({
});
};

const buildTestPathPatterns = (
argv: Config.Argv,
rootDir: string,
): TestPathPatterns => {
const buildTestPathPatterns = (argv: Config.Argv): TestPathPatterns => {
const patterns = [];

if (argv._) {
Expand All @@ -405,8 +402,7 @@ const buildTestPathPatterns = (
patterns.push(...argv.testPathPatterns);
}

const config = {rootDir};
const testPathPatterns = new TestPathPatterns(patterns, config);
const testPathPatterns = new TestPathPatterns(patterns);

if (!testPathPatterns.isValid()) {
clearLine(process.stdout);
Expand All @@ -419,7 +415,7 @@ const buildTestPathPatterns = (
),
);

return new TestPathPatterns([], config);
return new TestPathPatterns([]);
}

return testPathPatterns;
Expand Down Expand Up @@ -1009,7 +1005,7 @@ export default async function normalize(
}

newOptions.nonFlagArgs = argv._?.map(arg => `${arg}`);
const testPathPatterns = buildTestPathPatterns(argv, options.rootDir);
const testPathPatterns = buildTestPathPatterns(argv);
newOptions.testPathPatterns = testPathPatterns;
newOptions.json = !!argv.json;

Expand Down
26 changes: 17 additions & 9 deletions packages/jest-core/src/SearchSource.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import * as os from 'os';
import * as path from 'path';
import micromatch = require('micromatch');
import type {Test, TestContext} from '@jest/test-result';
import type {Config, TestPathPatterns} from '@jest/types';
import type {Config, TestPathPatternsExecutor} from '@jest/types';
import type {ChangedFiles} from 'jest-changed-files';
import {replaceRootDirInPath} from 'jest-config';
import {escapePathForRegex} from 'jest-regex-util';
Expand Down Expand Up @@ -114,7 +114,7 @@ export default class SearchSource {

private _filterTestPathsWithStats(
allPaths: Array<Test>,
testPathPatterns: TestPathPatterns,
testPathPatternsExecutor: TestPathPatternsExecutor,
): SearchResult {
const data: {
stats: Stats;
Expand All @@ -132,9 +132,9 @@ export default class SearchSource {
};

const testCases = [...this._testPathCases]; // clone
if (testPathPatterns.isSet()) {
if (testPathPatternsExecutor.isSet()) {
testCases.push({
isMatch: (path: string) => testPathPatterns.isMatch(path),
isMatch: (path: string) => testPathPatternsExecutor.isMatch(path),
stat: 'testPathPatterns',
});
data.stats.testPathPatterns = 0;
Expand All @@ -155,19 +155,23 @@ export default class SearchSource {
return data;
}

private _getAllTestPaths(testPathPatterns: TestPathPatterns): SearchResult {
private _getAllTestPaths(
testPathPatternsExecutor: TestPathPatternsExecutor,
): SearchResult {
return this._filterTestPathsWithStats(
toTests(this._context, this._context.hasteFS.getAllFiles()),
testPathPatterns,
testPathPatternsExecutor,
);
}

isTestFilePath(path: string): boolean {
return this._testPathCases.every(testCase => testCase.isMatch(path));
}

findMatchingTests(testPathPatterns: TestPathPatterns): SearchResult {
return this._getAllTestPaths(testPathPatterns);
findMatchingTests(
testPathPatternsExecutor: TestPathPatternsExecutor,
): SearchResult {
return this._getAllTestPaths(testPathPatternsExecutor);
}

async findRelatedTests(
Expand Down Expand Up @@ -291,7 +295,11 @@ export default class SearchSource {
globalConfig.collectCoverage,
);
} else {
return this.findMatchingTests(globalConfig.testPathPatterns);
return this.findMatchingTests(
globalConfig.testPathPatterns.toExecutor({
rootDir: globalConfig.rootDir,
}),
);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ describe('getNoTestsFoundMessage', () => {
function createGlobalConfig(options?: Partial<Config.GlobalConfig>) {
return makeGlobalConfig({
rootDir: '/root/dir',
testPathPatterns: new TestPathPatterns(['/path/pattern'], {rootDir: '/'}),
testPathPatterns: new TestPathPatterns(['/path/pattern']),
...options,
});
}
Expand Down
2 changes: 1 addition & 1 deletion packages/jest-core/src/__tests__/runJest.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ describe('runJest', () => {
contexts: [],
globalConfig: {
rootDir: '',
testPathPatterns: new TestPathPatterns([], {rootDir: '/'}),
testPathPatterns: new TestPathPatterns([]),
testSequencer: require.resolve('@jest/test-sequencer'),
watch: true,
},
Expand Down
8 changes: 3 additions & 5 deletions packages/jest-core/src/__tests__/watch.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@ describe('Watch mode flows', () => {
pipe = {write: jest.fn()};
globalConfig = {
rootDir: '',
testPathPatterns: new TestPathPatterns([], {rootDir: '/'}),
testPathPatterns: new TestPathPatterns([]),
watch: true,
};
hasteMapInstances = [{on: () => {}}];
Expand All @@ -157,9 +157,7 @@ describe('Watch mode flows', () => {
});

it('Correctly passing test path pattern', async () => {
globalConfig.testPathPatterns = new TestPathPatterns(['test-*'], {
rootDir: '/',
});
globalConfig.testPathPatterns = new TestPathPatterns(['test-*']);

await watch(globalConfig, contexts, pipe, hasteMapInstances, stdin);

Expand Down Expand Up @@ -695,7 +693,7 @@ describe('Watch mode flows', () => {

const newVal = (() => {
if (option === 'testPathPatterns') {
return new TestPathPatterns(['a/b', 'c'], {rootDir: '/'});
return new TestPathPatterns(['a/b', 'c']);
}

return '__JUST_TRYING__';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ const nextTick = () => new Promise(resolve => process.nextTick(resolve));

const globalConfig = {
rootDir: '',
testPathPatterns: new TestPathPatterns([], {rootDir: '/'}),
testPathPatterns: new TestPathPatterns([]),
watch: true,
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ const watch = require('../watch').default;

const globalConfig = {
rootDir: '',
testPathPatterns: new TestPathPatterns([], {rootDir: '/'}),
testPathPatterns: new TestPathPatterns([]),
watch: true,
};

Expand Down
2 changes: 1 addition & 1 deletion packages/jest-core/src/lib/updateGlobalConfig.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ export default function updateGlobalConfig(
}

if (options.testPathPatterns !== undefined) {
newConfig.testPathPatterns = new TestPathPatterns(options.testPathPatterns, {rootDir: globalConfig.rootDir});
newConfig.testPathPatterns = new TestPathPatterns(options.testPathPatterns);
}

newConfig.onlyChanged =
Expand Down
6 changes: 4 additions & 2 deletions packages/jest-core/src/watch.ts
Original file line number Diff line number Diff line change
Expand Up @@ -229,11 +229,13 @@ export default async function watch(

const emitFileChange = () => {
if (hooks.isUsed('onFileChange')) {
const testPathPatterns = new TestPathPatterns([], globalConfig);
const testPathPatternsExecutor = new TestPathPatterns([]).toExecutor({
rootDir: globalConfig.rootDir,
});
const projects = searchSources.map(({context, searchSource}) => ({
config: context.config,
testPaths: searchSource
.findMatchingTests(testPathPatterns)
.findMatchingTests(testPathPatternsExecutor)
.tests.map(t => t.path),
}));
hooks.getEmitter().onFileChange({projects});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ const now = Date.now;
const write = process.stderr.write;
const globalConfig = {
rootDir: 'root',
testPathPatterns: new TestPathPatterns([], {rootDir: '/'}),
testPathPatterns: new TestPathPatterns([]),
watch: false,
};

Expand Down
2 changes: 1 addition & 1 deletion packages/jest-types/src/Config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import type {ForegroundColor} from 'chalk';
import type {ReportOptions} from 'istanbul-reports';
import type {Arguments} from 'yargs';
import type {InitialOptions, SnapshotFormat} from '@jest/schemas';
import type TestPathPatterns from './TestPathPatterns';
import type {TestPathPatterns} from './TestPathPatterns';

export type {InitialOptions} from '@jest/schemas';

Expand Down
70 changes: 54 additions & 16 deletions packages/jest-types/src/TestPathPatterns.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,27 +7,73 @@

import {escapePathForRegex, replacePathSepForRegex} from 'jest-regex-util';

type PatternsConfig = {
export class TestPathPatterns {
constructor(readonly patterns: Array<string>) {}

/**
* Return true if there are any patterns.
*/
isSet(): boolean {
return this.patterns.length > 0;
}

/**
* Return true if the patterns are valid.
*/
isValid(): boolean {
return this.toExecutor({
// isValid() doesn't require rootDir to be accurate, so just
// specify a dummy rootDir here
rootDir: '/',
}).isValid();
}

/**
* Return a human-friendly version of the pattern regex.
*/
toPretty(): string {
return this.patterns.join('|');
}

/**
* Return a TestPathPatternsExecutor that can execute the patterns.
*/
toExecutor(
options: TestPathPatternsExecutorOptions,
): TestPathPatternsExecutor {
return new TestPathPatternsExecutor(this, options);
}

/** For jest serializers */
toJSON(): any {
return {
patterns: this.patterns,
type: 'TestPathPatterns',
};
}
}

export type TestPathPatternsExecutorOptions = {
rootDir: string;
};

export default class TestPathPatterns {
export class TestPathPatternsExecutor {
private _regexString: string | null = null;

constructor(
readonly patterns: Array<string>,
private readonly config: PatternsConfig,
readonly patterns: TestPathPatterns,
private readonly options: TestPathPatternsExecutorOptions,
) {}

private get regexString(): string {
if (this._regexString !== null) {
return this._regexString;
}

const rootDir = this.config.rootDir.replace(/\/*$/, '/');
const rootDir = this.options.rootDir.replace(/\/*$/, '/');
const rootDirRegex = escapePathForRegex(rootDir);

const regexString = this.patterns
const regexString = this.patterns.patterns
.map(p => {
// absolute paths passed on command line should stay same
if (p.startsWith('/')) {
Expand Down Expand Up @@ -57,7 +103,7 @@ export default class TestPathPatterns {
* Return true if there are any patterns.
*/
isSet(): boolean {
return this.patterns.length > 0;
return this.patterns.isSet();
}

/**
Expand Down Expand Up @@ -85,14 +131,6 @@ export default class TestPathPatterns {
* Return a human-friendly version of the pattern regex.
*/
toPretty(): string {
return this.patterns.join('|');
}

/** For jest serializers */
toJSON(): any {
return {
patterns: this.patterns,
type: 'TestPathPatterns',
};
return this.patterns.toPretty();
}
}
Loading

0 comments on commit 831e3a9

Please sign in to comment.