Skip to content

Commit

Permalink
test_runner: allow subtest filtering via --test-name-pattern
Browse files Browse the repository at this point in the history
  • Loading branch information
richiemccoll committed Feb 28, 2023
1 parent d953049 commit 66a9f16
Show file tree
Hide file tree
Showing 3 changed files with 165 additions and 5 deletions.
34 changes: 29 additions & 5 deletions lib/internal/test_runner/test.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
'use strict';
const {
ArrayPrototypeMap,
ArrayPrototypePush,
ArrayPrototypeReduce,
ArrayPrototypeShift,
Expand All @@ -13,11 +14,15 @@ const {
PromisePrototypeThen,
PromiseResolve,
ReflectApply,
RegExp,
RegExpPrototypeExec,
SafeMap,
SafeSet,
SafePromiseAll,
SafePromiseRace,
StringPrototype,
StringPrototypeReplace,
StringPrototypeTrim,
Symbol,
} = primordials;
const { AsyncResource } = require('async_hooks');
Expand Down Expand Up @@ -225,11 +230,30 @@ class Test extends AsyncResource {
}

if (testNamePatterns !== null) {
// eslint-disable-next-line no-use-before-define
const match = this instanceof TestHook || ArrayPrototypeSome(
testNamePatterns,
(re) => RegExpPrototypeExec(re, name) !== null,
);
const match =
// eslint-disable-next-line no-use-before-define
this instanceof TestHook ||
ArrayPrototypeSome(testNamePatterns, (re) => {
const scopedTestNamePatterns = StringPrototype.split.call(re, '>');
if (name !== '<root>' && scopedTestNamePatterns.length > 1) {
const patterns = ArrayPrototypeMap(
scopedTestNamePatterns,
(pattern) => {
const text = StringPrototypeReplace(pattern, '/', '');
return new RegExp(StringPrototypeTrim(text));
},
);

for (let p = 0; p < patterns.length; p++) {
if (RegExpPrototypeExec(patterns[p], name)) {
return (
p === 0 || RegExpPrototypeExec(patterns[p - 1], parent?.name)
);
}
}
}
return RegExpPrototypeExec(re, name) !== null;
});

if (!match) {
skip = 'test name does not match pattern';
Expand Down
63 changes: 63 additions & 0 deletions test/message/test_runner_test_name_pattern_filtering.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
// Flags: --no-warnings --test-name-pattern=suite-one>suite-two>subtest-one
'use strict';
const common = require('../common');
const {
after,
afterEach,
before,
beforeEach,
describe,
it,
test,
} = require('node:test');

describe('suite-one', () => {
before(common.mustCall());
beforeEach(common.mustCall(3));
afterEach(common.mustCall(3));
after(common.mustCall());

it('subtest-one', common.mustNotCall());
describe(
'suite-two',
common.mustCall(() => {
it('subtest-one', common.mustCall());
}),
);
describe('suite-three', common.mustNotCall());
});

test(
'suite-one',
common.mustCall(async (t) => {
t.beforeEach(common.mustCall(3));
t.afterEach(common.mustCall(3));

await t.test('subtest-one', common.mustNotCall());
await t.test(
'suite-two',
common.mustCall(async (t) => {
await t.test('subtest-one', common.mustCall());
}),
);
await t.test('suite-three', common.mustNotCall());
}),
);

describe('excluded', () => {
before(common.mustNotCall());
beforeEach(common.mustNotCall());
afterEach(common.mustNotCall());
after(common.mustNotCall());

it('subtest-one', common.mustNotCall());
describe('suite-two', common.mustNotCall());
});

test('excluded', (t) => {
t.beforeEach(common.mustNotCall());
t.afterEach(common.mustNotCall());

t.test('subtest-one', common.mustNotCall());
t.test('suite-two', common.mustNotCall());
});
73 changes: 73 additions & 0 deletions test/message/test_runner_test_name_pattern_filtering.out
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
TAP version 13
# Subtest: suite-one
# Subtest: subtest-one
ok 1 - subtest-one # SKIP test name does not match pattern
---
duration_ms: *
...
# Subtest: suite-two
# Subtest: subtest-one
ok 1 - subtest-one
---
duration_ms: *
...
1..1
ok 2 - suite-two
---
duration_ms: *
...
# Subtest: suite-three
ok 3 - suite-three # SKIP test name does not match pattern
---
duration_ms: *
...
1..3
ok 1 - suite-one
---
duration_ms: *
...
# Subtest: suite-one
# Subtest: subtest-one
ok 1 - subtest-one # SKIP test name does not match pattern
---
duration_ms: *
...
# Subtest: suite-two
# Subtest: subtest-one
ok 1 - subtest-one
---
duration_ms: *
...
1..1
ok 2 - suite-two
---
duration_ms: *
...
# Subtest: suite-three
ok 3 - suite-three # SKIP test name does not match pattern
---
duration_ms: *
...
1..3
ok 2 - suite-one
---
duration_ms: *
...
# Subtest: excluded
ok 3 - excluded # SKIP test name does not match pattern
---
duration_ms: *
...
# Subtest: excluded
ok 4 - excluded # SKIP test name does not match pattern
---
duration_ms: *
...
1..4
# tests 4
# pass 2
# fail 0
# cancelled 0
# skipped 2
# todo 0
# duration_ms *

0 comments on commit 66a9f16

Please sign in to comment.