Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions lib/internal/test_runner/runner.js
Original file line number Diff line number Diff line change
Expand Up @@ -284,6 +284,12 @@ class FileTest extends Test {
this.timeout = null;
}

willBeFilteredByName() {
// A FileTest represents a test file, not a named test. Name filters are
// applied to the tests inside of the file by the child process.
return false;
}

#skipReporting() {
return this.#reportedChildren > 0 && (!this.error || this.error.failureType === kSubtestsFailed);
}
Expand Down Expand Up @@ -936,6 +942,15 @@ function run(options = kEmptyObject) {
testTagFilters,
};

if (isolation === 'none') {
// Tests run in this process, so the name filters must be applied to the
// root test's configuration. Under isolation 'process' the filters are
// forwarded to each child process via --test-name-pattern and
// --test-skip-pattern instead.
globalOptions.testNamePatterns = testNamePatterns ?? globalOptions.testNamePatterns;
globalOptions.testSkipPatterns = testSkipPatterns ?? globalOptions.testSkipPatterns;
}

const root = createTestTree(rootTestOptions, globalOptions);
let testFiles = files ?? createTestFileList(globPatterns, cwd);
const { isTestRunner } = globalOptions;
Expand Down
37 changes: 37 additions & 0 deletions test/parallel/test-runner-run.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -213,6 +213,43 @@ describe('require(\'node:test\').run', { concurrency: true }, () => {
assert.strictEqual(result[5], '# tests 1\n');
});

it('should apply testNamePatterns and testSkipPatterns with isolation \'none\'', async () => {
const stream = run({
files: [join(testFixtures, 'default-behavior/test/skip_by_name.cjs')],
isolation: 'none',
testNamePatterns: [/should/],
testSkipPatterns: [/skipped/],
});
stream.on('test:fail', common.mustNotCall());
stream.on('test:pass', common.mustCall((event) => {
assert.strictEqual(event.name, 'this should be executed');
}, 1));
// eslint-disable-next-line no-unused-vars
for await (const _ of stream);
});

it('should run tests with testNamePatterns in watch mode with isolation \'none\'', async () => {
// The name filters must not be applied to the file level test that wraps
// the spawned process. Without this, no test ever runs.
const controller = new AbortController();
const passes = [];
const stream = run({
files: [join(testFixtures, 'default-behavior/test/skip_by_name.cjs')],
watch: true,
isolation: 'none',
signal: controller.signal,
testNamePatterns: [/executed/],
});
stream.on('test:pass', (event) => {
passes.push(event.name);
controller.abort();
});
// eslint-disable-next-line no-unused-vars
for await (const _ of stream);
assert.ok(passes.length > 0);
assert.ok(!passes.includes('this should be skipped'));
});

it('should pass only to children', async () => {
const result = await run({
files: [join(testFixtures, 'test_only.js')],
Expand Down
Loading