test_runner: flatten TAP output when running using --test
PR-URL: https://github.com/nodejs/node/pull/46440 Fixes: https://github.com/nodejs/node/issues/45833 Refs: https://github.com/nodejs/node/issues/45833 Reviewed-By: Colin Ihrig <cjihrig@gmail.com> Reviewed-By: Benjamin Gruenbaum <benjamingr@gmail.com>
This commit is contained in:
parent
9e840deecc
commit
3354f89dcf
@ -8,9 +8,11 @@ const {
|
||||
ArrayPrototypeSlice,
|
||||
ArrayPrototypeSome,
|
||||
ArrayPrototypeSort,
|
||||
FunctionPrototypeCall,
|
||||
Number,
|
||||
ObjectAssign,
|
||||
ObjectKeys,
|
||||
PromisePrototypeThen,
|
||||
SafePromiseAll,
|
||||
SafePromiseAllReturnVoid,
|
||||
SafePromiseAllSettledReturnVoid,
|
||||
SafeMap,
|
||||
@ -35,7 +37,14 @@ const { validateArray, validateBoolean } = require('internal/validators');
|
||||
const { getInspectPort, isUsingInspector, isInspectorMessage } = require('internal/util/inspector');
|
||||
const { kEmptyObject } = require('internal/util');
|
||||
const { createTestTree } = require('internal/test_runner/harness');
|
||||
const { kSubtestsFailed, Test } = require('internal/test_runner/test');
|
||||
const {
|
||||
kAborted,
|
||||
kCancelledByParent,
|
||||
kSubtestsFailed,
|
||||
kTestCodeFailure,
|
||||
kTestTimeoutFailure,
|
||||
Test,
|
||||
} = require('internal/test_runner/test');
|
||||
const { TapParser } = require('internal/test_runner/tap_parser');
|
||||
const { YAMLToJs } = require('internal/test_runner/yaml_to_js');
|
||||
const { TokenKind } = require('internal/test_runner/tap_lexer');
|
||||
@ -55,6 +64,9 @@ const kFilterArgs = ['--test', '--experimental-test-coverage', '--watch'];
|
||||
const kFilterArgValues = ['--test-reporter', '--test-reporter-destination'];
|
||||
const kDiagnosticsFilterArgs = ['tests', 'pass', 'fail', 'cancelled', 'skipped', 'todo', 'duration_ms'];
|
||||
|
||||
const kCanceledTests = new SafeSet()
|
||||
.add(kCancelledByParent).add(kAborted).add(kTestTimeoutFailure);
|
||||
|
||||
// TODO(cjihrig): Replace this with recursive readdir once it lands.
|
||||
function processPath(path, testFiles, options) {
|
||||
const stats = statSync(path);
|
||||
@ -133,6 +145,11 @@ function getRunArgs({ path, inspectPort }) {
|
||||
|
||||
class FileTest extends Test {
|
||||
#buffer = [];
|
||||
#counters = { __proto__: null, all: 0, failed: 0, passed: 0, cancelled: 0, skipped: 0, todo: 0, totalFailed: 0 };
|
||||
failedSubtests = false;
|
||||
#skipReporting() {
|
||||
return this.#counters.all > 0 && (!this.error || this.error.failureType === kSubtestsFailed);
|
||||
}
|
||||
#checkNestedComment({ comment }) {
|
||||
const firstSpaceIndex = StringPrototypeIndexOf(comment, ' ');
|
||||
if (firstSpaceIndex === -1) return false;
|
||||
@ -141,8 +158,6 @@ class FileTest extends Test {
|
||||
ArrayPrototypeIncludes(kDiagnosticsFilterArgs, StringPrototypeSlice(comment, 0, firstSpaceIndex));
|
||||
}
|
||||
#handleReportItem({ kind, node, comments, nesting = 0 }) {
|
||||
nesting += 1;
|
||||
|
||||
if (comments) {
|
||||
ArrayPrototypeForEach(comments, (comment) => this.reporter.diagnostic(nesting, this.name, comment));
|
||||
}
|
||||
@ -153,6 +168,9 @@ class FileTest extends Test {
|
||||
break;
|
||||
|
||||
case TokenKind.TAP_PLAN:
|
||||
if (nesting === 0 && this.#skipReporting()) {
|
||||
break;
|
||||
}
|
||||
this.reporter.plan(nesting, this.name, node.end - node.start + 1);
|
||||
break;
|
||||
|
||||
@ -160,10 +178,10 @@ class FileTest extends Test {
|
||||
this.reporter.start(nesting, this.name, node.name);
|
||||
break;
|
||||
|
||||
case TokenKind.TAP_TEST_POINT:
|
||||
// eslint-disable-next-line no-case-declarations
|
||||
case TokenKind.TAP_TEST_POINT: {
|
||||
|
||||
const { todo, skip, pass } = node.status;
|
||||
// eslint-disable-next-line no-case-declarations
|
||||
|
||||
let directive;
|
||||
|
||||
if (skip) {
|
||||
@ -174,29 +192,22 @@ class FileTest extends Test {
|
||||
directive = kEmptyObject;
|
||||
}
|
||||
|
||||
if (pass) {
|
||||
this.reporter.ok(
|
||||
nesting,
|
||||
this.name,
|
||||
node.id,
|
||||
node.description,
|
||||
YAMLToJs(node.diagnostics),
|
||||
directive,
|
||||
);
|
||||
} else {
|
||||
this.reporter.fail(
|
||||
nesting,
|
||||
this.name,
|
||||
node.id,
|
||||
node.description,
|
||||
YAMLToJs(node.diagnostics),
|
||||
directive,
|
||||
);
|
||||
const diagnostics = YAMLToJs(node.diagnostics);
|
||||
const cancelled = kCanceledTests.has(diagnostics.error?.failureType);
|
||||
const testNumber = nesting === 0 ? (Number(node.id) + this.testNumber - 1) : node.id;
|
||||
const method = pass ? 'ok' : 'fail';
|
||||
this.reporter[method](nesting, this.name, testNumber, node.description, diagnostics, directive);
|
||||
if (nesting === 0) {
|
||||
FunctionPrototypeCall(super.countSubtest,
|
||||
{ finished: true, skipped: skip, isTodo: todo, passed: pass, cancelled },
|
||||
this.#counters);
|
||||
this.failedSubtests ||= !pass;
|
||||
}
|
||||
break;
|
||||
|
||||
}
|
||||
case TokenKind.COMMENT:
|
||||
if (nesting === 1 && this.#checkNestedComment(node)) {
|
||||
if (nesting === 0 && this.#checkNestedComment(node)) {
|
||||
// Ignore file top level diagnostics
|
||||
break;
|
||||
}
|
||||
@ -216,10 +227,24 @@ class FileTest extends Test {
|
||||
this.reportStarted();
|
||||
this.#handleReportItem(ast);
|
||||
}
|
||||
countSubtest(counters) {
|
||||
if (this.#counters.all === 0) {
|
||||
return super.countSubtest(counters);
|
||||
}
|
||||
ArrayPrototypeForEach(ObjectKeys(counters), (key) => {
|
||||
counters[key] += this.#counters[key];
|
||||
});
|
||||
}
|
||||
reportStarted() {}
|
||||
report() {
|
||||
this.reportStarted();
|
||||
const skipReporting = this.#skipReporting();
|
||||
if (!skipReporting) {
|
||||
super.reportStarted();
|
||||
}
|
||||
ArrayPrototypeForEach(this.#buffer, (ast) => this.#handleReportItem(ast));
|
||||
super.report();
|
||||
if (!skipReporting) {
|
||||
super.report();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -274,16 +299,14 @@ function runTestFile(path, root, inspectPort, filesWatcher) {
|
||||
subtest.addToReport(ast);
|
||||
});
|
||||
|
||||
const { 0: { 0: code, 1: signal } } = await SafePromiseAll([
|
||||
once(child, 'exit', { signal: t.signal }),
|
||||
child.stdout.toArray({ signal: t.signal }),
|
||||
]);
|
||||
const { 0: code, 1: signal } = await once(child, 'exit', { signal: t.signal });
|
||||
|
||||
runningProcesses.delete(path);
|
||||
runningSubtests.delete(path);
|
||||
if (code !== 0 || signal !== null) {
|
||||
if (!err) {
|
||||
err = ObjectAssign(new ERR_TEST_FAILURE('test failed', kSubtestsFailed), {
|
||||
const failureType = subtest.failedSubtests ? kSubtestsFailed : kTestCodeFailure;
|
||||
err = ObjectAssign(new ERR_TEST_FAILURE('test failed', failureType), {
|
||||
__proto__: null,
|
||||
exitCode: code,
|
||||
signal: signal,
|
||||
|
@ -57,6 +57,7 @@ const { availableParallelism } = require('os');
|
||||
const { bigint: hrtime } = process.hrtime;
|
||||
const kCallbackAndPromisePresent = 'callbackAndPromisePresent';
|
||||
const kCancelledByParent = 'cancelledByParent';
|
||||
const kAborted = 'testAborted';
|
||||
const kParentAlreadyFinished = 'parentAlreadyFinished';
|
||||
const kSubtestsFailed = 'subtestsFailed';
|
||||
const kTestCodeFailure = 'testCodeFailure';
|
||||
@ -390,10 +391,12 @@ class Test extends AsyncResource {
|
||||
}
|
||||
|
||||
#abortHandler = () => {
|
||||
this.cancel(this.#outerSignal?.reason || new AbortError('The test was aborted'));
|
||||
const error = this.#outerSignal?.reason || new AbortError('The test was aborted');
|
||||
error.failureType = kAborted;
|
||||
this.#cancel(error);
|
||||
};
|
||||
|
||||
cancel(error) {
|
||||
#cancel(error) {
|
||||
if (this.endTime !== null) {
|
||||
return;
|
||||
}
|
||||
@ -470,7 +473,7 @@ class Test extends AsyncResource {
|
||||
return true;
|
||||
}
|
||||
if (this.#outerSignal?.aborted) {
|
||||
this.cancel(this.#outerSignal.reason || new AbortError('The test was aborted'));
|
||||
this.#abortHandler();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@ -563,7 +566,7 @@ class Test extends AsyncResource {
|
||||
try { await afterEach(); } catch { /* test is already failing, let's the error */ }
|
||||
if (isTestFailureError(err)) {
|
||||
if (err.failureType === kTestTimeoutFailure) {
|
||||
this.cancel(err);
|
||||
this.#cancel(err);
|
||||
} else {
|
||||
this.fail(err);
|
||||
}
|
||||
@ -577,9 +580,31 @@ class Test extends AsyncResource {
|
||||
this.postRun();
|
||||
}
|
||||
|
||||
postRun(pendingSubtestsError) {
|
||||
const counters = { __proto__: null, failed: 0, passed: 0, cancelled: 0, skipped: 0, todo: 0, totalFailed: 0 };
|
||||
countSubtest(counters) {
|
||||
// Check SKIP and TODO tests first, as those should not be counted as
|
||||
// failures.
|
||||
if (this.skipped) {
|
||||
counters.skipped++;
|
||||
} else if (this.isTodo) {
|
||||
counters.todo++;
|
||||
} else if (this.cancelled) {
|
||||
counters.cancelled++;
|
||||
} else if (!this.passed) {
|
||||
counters.failed++;
|
||||
} else {
|
||||
counters.passed++;
|
||||
}
|
||||
|
||||
if (!this.passed) {
|
||||
counters.totalFailed++;
|
||||
}
|
||||
counters.all++;
|
||||
}
|
||||
|
||||
postRun(pendingSubtestsError) {
|
||||
const counters = {
|
||||
__proto__: null, all: 0, failed: 0, passed: 0, cancelled: 0, skipped: 0, todo: 0, totalFailed: 0,
|
||||
};
|
||||
// If the test was failed before it even started, then the end time will
|
||||
// be earlier than the start time. Correct that here.
|
||||
if (this.endTime < this.startTime) {
|
||||
@ -594,27 +619,10 @@ class Test extends AsyncResource {
|
||||
const subtest = this.subtests[i];
|
||||
|
||||
if (!subtest.finished) {
|
||||
subtest.cancel(pendingSubtestsError);
|
||||
subtest.#cancel(pendingSubtestsError);
|
||||
subtest.postRun(pendingSubtestsError);
|
||||
}
|
||||
|
||||
// Check SKIP and TODO tests first, as those should not be counted as
|
||||
// failures.
|
||||
if (subtest.skipped) {
|
||||
counters.skipped++;
|
||||
} else if (subtest.isTodo) {
|
||||
counters.todo++;
|
||||
} else if (subtest.cancelled) {
|
||||
counters.cancelled++;
|
||||
} else if (!subtest.passed) {
|
||||
counters.failed++;
|
||||
} else {
|
||||
counters.passed++;
|
||||
}
|
||||
|
||||
if (!subtest.passed) {
|
||||
counters.totalFailed++;
|
||||
}
|
||||
subtest.countSubtest(counters);
|
||||
}
|
||||
|
||||
if ((this.passed || this.parent === null) && counters.totalFailed > 0) {
|
||||
@ -634,13 +642,13 @@ class Test extends AsyncResource {
|
||||
this.parent.processPendingSubtests();
|
||||
} else if (!this.reported) {
|
||||
this.reported = true;
|
||||
this.reporter.plan(this.nesting, kFilename, this.subtests.length);
|
||||
this.reporter.plan(this.nesting, kFilename, counters.all);
|
||||
|
||||
for (let i = 0; i < this.diagnostics.length; i++) {
|
||||
this.reporter.diagnostic(this.nesting, kFilename, this.diagnostics[i]);
|
||||
}
|
||||
|
||||
this.reporter.diagnostic(this.nesting, kFilename, `tests ${this.subtests.length}`);
|
||||
this.reporter.diagnostic(this.nesting, kFilename, `tests ${counters.all}`);
|
||||
this.reporter.diagnostic(this.nesting, kFilename, `pass ${counters.passed}`);
|
||||
this.reporter.diagnostic(this.nesting, kFilename, `fail ${counters.failed}`);
|
||||
this.reporter.diagnostic(this.nesting, kFilename, `cancelled ${counters.cancelled}`);
|
||||
@ -825,6 +833,8 @@ module.exports = {
|
||||
kCancelledByParent,
|
||||
kSubtestsFailed,
|
||||
kTestCodeFailure,
|
||||
kTestTimeoutFailure,
|
||||
kAborted,
|
||||
kUnwrapErrors,
|
||||
Suite,
|
||||
Test,
|
||||
|
@ -40,6 +40,7 @@ TAP version 13
|
||||
not ok 7 - not ok 3
|
||||
---
|
||||
duration_ms: *
|
||||
failureType: 'testAborted'
|
||||
error: 'This operation was aborted'
|
||||
code: 20
|
||||
stack: |-
|
||||
@ -58,6 +59,7 @@ TAP version 13
|
||||
not ok 8 - not ok 4
|
||||
---
|
||||
duration_ms: *
|
||||
failureType: 'testAborted'
|
||||
error: 'This operation was aborted'
|
||||
code: 20
|
||||
stack: |-
|
||||
@ -76,6 +78,7 @@ TAP version 13
|
||||
not ok 9 - not ok 5
|
||||
---
|
||||
duration_ms: *
|
||||
failureType: 'testAborted'
|
||||
error: 'This operation was aborted'
|
||||
code: 20
|
||||
stack: |-
|
||||
@ -94,6 +97,7 @@ TAP version 13
|
||||
not ok 1 - promise timeout signal
|
||||
---
|
||||
duration_ms: *
|
||||
failureType: 'testAborted'
|
||||
error: 'The operation was aborted due to timeout'
|
||||
code: 23
|
||||
stack: |-
|
||||
@ -106,6 +110,7 @@ not ok 1 - promise timeout signal
|
||||
not ok 2 - promise abort signal
|
||||
---
|
||||
duration_ms: *
|
||||
failureType: 'testAborted'
|
||||
error: 'This operation was aborted'
|
||||
code: 20
|
||||
stack: |-
|
||||
@ -160,6 +165,7 @@ not ok 2 - promise abort signal
|
||||
not ok 7 - not ok 3
|
||||
---
|
||||
duration_ms: *
|
||||
failureType: 'testAborted'
|
||||
error: 'This operation was aborted'
|
||||
code: 20
|
||||
stack: |-
|
||||
@ -178,6 +184,7 @@ not ok 2 - promise abort signal
|
||||
not ok 8 - not ok 4
|
||||
---
|
||||
duration_ms: *
|
||||
failureType: 'testAborted'
|
||||
error: 'This operation was aborted'
|
||||
code: 20
|
||||
stack: |-
|
||||
@ -196,6 +203,7 @@ not ok 2 - promise abort signal
|
||||
not ok 9 - not ok 5
|
||||
---
|
||||
duration_ms: *
|
||||
failureType: 'testAborted'
|
||||
error: 'This operation was aborted'
|
||||
code: 20
|
||||
stack: |-
|
||||
@ -214,6 +222,7 @@ not ok 2 - promise abort signal
|
||||
not ok 3 - callback timeout signal
|
||||
---
|
||||
duration_ms: *
|
||||
failureType: 'testAborted'
|
||||
error: 'The operation was aborted due to timeout'
|
||||
code: 23
|
||||
stack: |-
|
||||
@ -226,6 +235,7 @@ not ok 3 - callback timeout signal
|
||||
not ok 4 - callback abort signal
|
||||
---
|
||||
duration_ms: *
|
||||
failureType: 'testAborted'
|
||||
error: 'This operation was aborted'
|
||||
code: 20
|
||||
stack: |-
|
||||
|
@ -64,6 +64,7 @@ TAP version 13
|
||||
not ok 1 - describe timeout signal
|
||||
---
|
||||
duration_ms: *
|
||||
failureType: 'testAborted'
|
||||
error: 'The operation was aborted due to timeout'
|
||||
code: 23
|
||||
stack: |-
|
||||
@ -76,6 +77,7 @@ not ok 1 - describe timeout signal
|
||||
not ok 2 - describe abort signal
|
||||
---
|
||||
duration_ms: *
|
||||
failureType: 'testAborted'
|
||||
error: 'This operation was aborted'
|
||||
code: 20
|
||||
stack: |-
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -28,11 +28,10 @@ const testFixtures = fixtures.path('test-runner');
|
||||
assert.strictEqual(child.signal, null);
|
||||
assert.strictEqual(child.stderr.toString(), '');
|
||||
const stdout = child.stdout.toString();
|
||||
assert.match(stdout, /ok 1 - .+index\.test\.js/);
|
||||
assert.match(stdout, /not ok 2 - .+random\.test\.mjs/);
|
||||
assert.match(stdout, /not ok 1 - this should fail/);
|
||||
assert.match(stdout, /ok 1 - this should pass/);
|
||||
assert.match(stdout, /not ok 2 - this should fail/);
|
||||
assert.match(stdout, /ok 3 - .+subdir.+subdir_test\.js/);
|
||||
assert.match(stdout, /ok 4 - .+random\.cjs/);
|
||||
assert.match(stdout, /ok 4 - this should pass/);
|
||||
}
|
||||
|
||||
{
|
||||
@ -41,11 +40,10 @@ const testFixtures = fixtures.path('test-runner');
|
||||
const child = spawnSync(process.execPath, args);
|
||||
|
||||
const stdout = child.stdout.toString();
|
||||
assert.match(stdout, /ok 1 - .+index\.test\.js/);
|
||||
assert.match(stdout, /not ok 2 - .+random\.test\.mjs/);
|
||||
assert.match(stdout, /not ok 1 - this should fail/);
|
||||
assert.match(stdout, /ok 1 - this should pass/);
|
||||
assert.match(stdout, /not ok 2 - this should fail/);
|
||||
assert.match(stdout, /ok 3 - .+subdir.+subdir_test\.js/);
|
||||
assert.match(stdout, /ok 4 - .+random\.cjs/);
|
||||
assert.match(stdout, /ok 4 - this should pass/);
|
||||
assert.strictEqual(child.status, 1);
|
||||
assert.strictEqual(child.signal, null);
|
||||
assert.strictEqual(child.stderr.toString(), '');
|
||||
@ -61,10 +59,10 @@ const testFixtures = fixtures.path('test-runner');
|
||||
assert.strictEqual(child.stderr.toString(), '');
|
||||
const stdout = child.stdout.toString();
|
||||
assert.match(stdout, /not ok 1 - .+index\.js/);
|
||||
assert.match(stdout, /ok 2 - .+index\.test\.js/);
|
||||
assert.match(stdout, /not ok 3 - .+random\.test\.mjs/);
|
||||
assert.match(stdout, /not ok 1 - this should fail/);
|
||||
assert.match(stdout, /ok 2 - this should pass/);
|
||||
assert.match(stdout, /not ok 3 - this should fail/);
|
||||
assert.match(stdout, /ok 4 - .+subdir.+subdir_test\.js/);
|
||||
assert.match(stdout, /ok 5 - this should pass/);
|
||||
}
|
||||
|
||||
{
|
||||
@ -89,11 +87,10 @@ const testFixtures = fixtures.path('test-runner');
|
||||
assert.strictEqual(child.signal, null);
|
||||
assert.strictEqual(child.stderr.toString(), '');
|
||||
const stdout = child.stdout.toString();
|
||||
assert.match(stdout, /ok 1 - .+index\.test\.js/);
|
||||
assert.match(stdout, /not ok 2 - .+random\.test\.mjs/);
|
||||
assert.match(stdout, /not ok 1 - this should fail/);
|
||||
assert.match(stdout, /ok 1 - this should pass/);
|
||||
assert.match(stdout, /not ok 2 - this should fail/);
|
||||
assert.match(stdout, /ok 3 - .+subdir.+subdir_test\.js/);
|
||||
assert.match(stdout, /ok 4 - .+random\.cjs/);
|
||||
assert.match(stdout, /ok 4 - this should pass/);
|
||||
}
|
||||
|
||||
{
|
||||
@ -131,42 +128,36 @@ const testFixtures = fixtures.path('test-runner');
|
||||
assert.strictEqual(child.signal, null);
|
||||
assert.strictEqual(child.stderr.toString(), '');
|
||||
const stdout = child.stdout.toString();
|
||||
assert.match(stdout, /# Subtest: .+index\.test\.js/);
|
||||
assert.match(stdout, / {4}# Subtest: this should pass/);
|
||||
assert.match(stdout, / {4}ok 1 - this should pass/);
|
||||
assert.match(stdout, / {6}---/);
|
||||
assert.match(stdout, / {6}duration_ms: .*/);
|
||||
assert.match(stdout, / {6}\.\.\./);
|
||||
assert.match(stdout, / {4}1\.\.1/);
|
||||
|
||||
assert.match(stdout, /ok 1 - .+index\.test\.js/);
|
||||
assert.match(stdout, /# Subtest: this should pass/);
|
||||
assert.match(stdout, /ok 1 - this should pass/);
|
||||
assert.match(stdout, / {2}---/);
|
||||
assert.match(stdout, / {2}duration_ms: .*/);
|
||||
assert.match(stdout, / {2}\.\.\./);
|
||||
|
||||
assert.match(stdout, /# Subtest: .+invalid-tap\.js/);
|
||||
assert.match(stdout, / {4}# invalid tap output/);
|
||||
assert.match(stdout, /# invalid tap output/);
|
||||
assert.match(stdout, /ok 2 - .+invalid-tap\.js/);
|
||||
|
||||
assert.match(stdout, /# Subtest: .+nested\.js/);
|
||||
assert.match(stdout, / {4}# Subtest: level 0a/);
|
||||
assert.match(stdout, / {8}# Subtest: level 1a/);
|
||||
assert.match(stdout, / {8}ok 1 - level 1a/);
|
||||
assert.match(stdout, / {8}# Subtest: level 1b/);
|
||||
assert.match(stdout, / {8}not ok 2 - level 1b/);
|
||||
assert.match(stdout, / {10}code: 'ERR_TEST_FAILURE'/);
|
||||
assert.match(stdout, / {10}stack: |-'/);
|
||||
assert.match(stdout, / {12}TestContext\.<anonymous> .*/);
|
||||
assert.match(stdout, / {8}# Subtest: level 1c/);
|
||||
assert.match(stdout, / {8}ok 3 - level 1c # SKIP aaa/);
|
||||
assert.match(stdout, / {8}# Subtest: level 1d/);
|
||||
assert.match(stdout, / {8}ok 4 - level 1d/);
|
||||
assert.match(stdout, / {4}not ok 1 - level 0a/);
|
||||
assert.match(stdout, / {6}error: '1 subtest failed'/);
|
||||
assert.match(stdout, / {4}# Subtest: level 0b/);
|
||||
assert.match(stdout, / {4}not ok 2 - level 0b/);
|
||||
assert.match(stdout, / {6}error: 'level 0b error'/);
|
||||
assert.match(stdout, /not ok 3 - .+nested\.js/);
|
||||
assert.match(stdout, /# tests 3/);
|
||||
assert.match(stdout, /# Subtest: level 0a/);
|
||||
assert.match(stdout, / {4}# Subtest: level 1a/);
|
||||
assert.match(stdout, / {4}ok 1 - level 1a/);
|
||||
assert.match(stdout, / {4}# Subtest: level 1b/);
|
||||
assert.match(stdout, / {4}not ok 2 - level 1b/);
|
||||
assert.match(stdout, / {6}code: 'ERR_TEST_FAILURE'/);
|
||||
assert.match(stdout, / {6}stack: |-'/);
|
||||
assert.match(stdout, / {8}TestContext\.<anonymous> .*/);
|
||||
assert.match(stdout, / {4}# Subtest: level 1c/);
|
||||
assert.match(stdout, / {4}ok 3 - level 1c # SKIP aaa/);
|
||||
assert.match(stdout, / {4}# Subtest: level 1d/);
|
||||
assert.match(stdout, / {4}ok 4 - level 1d/);
|
||||
assert.match(stdout, /not ok 3 - level 0a/);
|
||||
assert.match(stdout, / {2}error: '1 subtest failed'/);
|
||||
assert.match(stdout, /# Subtest: level 0b/);
|
||||
assert.match(stdout, /not ok 4 - level 0b/);
|
||||
assert.match(stdout, / {2}error: 'level 0b error'/);
|
||||
assert.match(stdout, /# tests 4/);
|
||||
assert.match(stdout, /# pass 2/);
|
||||
assert.match(stdout, /# fail 1/);
|
||||
assert.match(stdout, /# fail 2/);
|
||||
}
|
||||
|
||||
{
|
||||
@ -181,16 +172,15 @@ const testFixtures = fixtures.path('test-runner');
|
||||
assert.strictEqual(child.signal, null);
|
||||
assert.strictEqual(child.stderr.toString(), '');
|
||||
const stdout = child.stdout.toString();
|
||||
assert.match(stdout, /# Subtest: .+user-logs\.js/);
|
||||
assert.match(stdout, / {4}# stderr 1/);
|
||||
assert.match(stdout, / {4}# stderr 2/);
|
||||
assert.match(stdout, / {4}# stdout 3/);
|
||||
assert.match(stdout, / {4}# stderr 6/);
|
||||
assert.match(stdout, / {4}# not ok 1 - fake test/);
|
||||
assert.match(stdout, / {4}# stderr 5/);
|
||||
assert.match(stdout, / {4}# stdout 4/);
|
||||
assert.match(stdout, / {4}# Subtest: a test/);
|
||||
assert.match(stdout, / {4}ok 1 - a test/);
|
||||
assert.match(stdout, /# stderr 1/);
|
||||
assert.match(stdout, /# stderr 2/);
|
||||
assert.match(stdout, /# stdout 3/);
|
||||
assert.match(stdout, /# stderr 6/);
|
||||
assert.match(stdout, /# not ok 1 - fake test/);
|
||||
assert.match(stdout, /# stderr 5/);
|
||||
assert.match(stdout, /# stdout 4/);
|
||||
assert.match(stdout, /# Subtest: a test/);
|
||||
assert.match(stdout, /ok 1 - a test/);
|
||||
assert.match(stdout, /# tests 1/);
|
||||
assert.match(stdout, /# pass 1/);
|
||||
}
|
||||
|
@ -10,8 +10,9 @@ const { spawnSync } = require('child_process');
|
||||
fixtures.path('test-runner', 'extraneous_set_immediate_async.mjs'),
|
||||
]);
|
||||
const stdout = child.stdout.toString();
|
||||
assert.match(stdout, /^# pass 0$/m);
|
||||
assert.match(stdout, /^# fail 1$/m);
|
||||
assert.match(stdout, /^# Warning: Test "extraneous async activity test" generated asynchronous activity after the test ended/m);
|
||||
assert.match(stdout, /^# pass 1/m);
|
||||
assert.match(stdout, /^# fail 0$/m);
|
||||
assert.match(stdout, /^# cancelled 0$/m);
|
||||
assert.strictEqual(child.status, 1);
|
||||
assert.strictEqual(child.signal, null);
|
||||
@ -23,8 +24,9 @@ const { spawnSync } = require('child_process');
|
||||
fixtures.path('test-runner', 'extraneous_set_timeout_async.mjs'),
|
||||
]);
|
||||
const stdout = child.stdout.toString();
|
||||
assert.match(stdout, /^# pass 0$/m);
|
||||
assert.match(stdout, /^# fail 1$/m);
|
||||
assert.match(stdout, /^# Warning: Test "extraneous async activity test" generated asynchronous activity after the test ended/m);
|
||||
assert.match(stdout, /^# pass 1$/m);
|
||||
assert.match(stdout, /^# fail 0$/m);
|
||||
assert.match(stdout, /^# cancelled 0$/m);
|
||||
assert.strictEqual(child.status, 1);
|
||||
assert.strictEqual(child.signal, null);
|
||||
|
@ -26,7 +26,7 @@ describe('node:test reporters', { concurrency: true }, () => {
|
||||
it('should default destination to stdout when passing a single reporter', async () => {
|
||||
const child = spawnSync(process.execPath, ['--test', '--test-reporter', 'dot', testFile]);
|
||||
assert.strictEqual(child.stderr.toString(), '');
|
||||
assert.strictEqual(child.stdout.toString(), '.XX.X\n');
|
||||
assert.strictEqual(child.stdout.toString(), '.XX.\n');
|
||||
});
|
||||
|
||||
it('should throw when passing reporters without a destination', async () => {
|
||||
@ -45,13 +45,13 @@ describe('node:test reporters', { concurrency: true }, () => {
|
||||
const child = spawnSync(process.execPath,
|
||||
['--test', '--test-reporter', 'dot', '--test-reporter-destination', 'stdout', testFile]);
|
||||
assert.strictEqual(child.stderr.toString(), '');
|
||||
assert.strictEqual(child.stdout.toString(), '.XX.X\n');
|
||||
assert.strictEqual(child.stdout.toString(), '.XX.\n');
|
||||
});
|
||||
|
||||
it('should support stderr as a destination', async () => {
|
||||
const child = spawnSync(process.execPath,
|
||||
['--test', '--test-reporter', 'dot', '--test-reporter-destination', 'stderr', testFile]);
|
||||
assert.strictEqual(child.stderr.toString(), '.XX.X\n');
|
||||
assert.strictEqual(child.stderr.toString(), '.XX.\n');
|
||||
assert.strictEqual(child.stdout.toString(), '');
|
||||
});
|
||||
|
||||
@ -61,7 +61,7 @@ describe('node:test reporters', { concurrency: true }, () => {
|
||||
['--test', '--test-reporter', 'dot', '--test-reporter-destination', file, testFile]);
|
||||
assert.strictEqual(child.stderr.toString(), '');
|
||||
assert.strictEqual(child.stdout.toString(), '');
|
||||
assert.strictEqual(fs.readFileSync(file, 'utf8'), '.XX.X\n');
|
||||
assert.strictEqual(fs.readFileSync(file, 'utf8'), '.XX.\n');
|
||||
});
|
||||
|
||||
it('should support multiple reporters', async () => {
|
||||
@ -75,7 +75,7 @@ describe('node:test reporters', { concurrency: true }, () => {
|
||||
testFile]);
|
||||
assert.match(child.stdout.toString(), /TAP version 13/);
|
||||
assert.match(child.stdout.toString(), /# duration_ms/);
|
||||
assert.strictEqual(fs.readFileSync(file, 'utf8'), '.XX.X\n');
|
||||
assert.strictEqual(fs.readFileSync(file, 'utf8'), '.XX.\n');
|
||||
const file2Contents = fs.readFileSync(file2, 'utf8');
|
||||
assert.match(file2Contents, /▶ nested/);
|
||||
assert.match(file2Contents, /✔ ok/);
|
||||
@ -90,7 +90,7 @@ describe('node:test reporters', { concurrency: true }, () => {
|
||||
testFile]);
|
||||
assert.strictEqual(child.stderr.toString(), '');
|
||||
const stdout = child.stdout.toString();
|
||||
assert.match(stdout, /{"test:start":5,"test:pass":2,"test:fail":3,"test:plan":3,"test:diagnostic":\d+}$/);
|
||||
assert.match(stdout, /{"test:start":4,"test:pass":2,"test:fail":2,"test:plan":2,"test:diagnostic":\d+}$/);
|
||||
assert.strictEqual(stdout.slice(0, filename.length + 2), `${filename} {`);
|
||||
});
|
||||
});
|
||||
@ -102,7 +102,7 @@ describe('node:test reporters', { concurrency: true }, () => {
|
||||
assert.strictEqual(child.stderr.toString(), '');
|
||||
assert.match(
|
||||
child.stdout.toString(),
|
||||
/^package: reporter-cjs{"test:start":5,"test:pass":2,"test:fail":3,"test:plan":3,"test:diagnostic":\d+}$/,
|
||||
/^package: reporter-cjs{"test:start":4,"test:pass":2,"test:fail":2,"test:plan":2,"test:diagnostic":\d+}$/,
|
||||
);
|
||||
});
|
||||
|
||||
@ -113,7 +113,7 @@ describe('node:test reporters', { concurrency: true }, () => {
|
||||
assert.strictEqual(child.stderr.toString(), '');
|
||||
assert.match(
|
||||
child.stdout.toString(),
|
||||
/^package: reporter-esm{"test:start":5,"test:pass":2,"test:fail":3,"test:plan":3,"test:diagnostic":\d+}$/,
|
||||
/^package: reporter-esm{"test:start":4,"test:pass":2,"test:fail":2,"test:plan":2,"test:diagnostic":\d+}$/,
|
||||
);
|
||||
});
|
||||
});
|
||||
|
@ -27,7 +27,7 @@ describe('require(\'node:test\').run', { concurrency: true }, () => {
|
||||
it('should succeed with a file', async () => {
|
||||
const stream = run({ files: [join(testFixtures, 'test/random.cjs')] });
|
||||
stream.on('test:fail', common.mustNotCall());
|
||||
stream.on('test:pass', common.mustCall(2));
|
||||
stream.on('test:pass', common.mustCall(1));
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
for await (const _ of stream);
|
||||
});
|
||||
@ -35,7 +35,7 @@ describe('require(\'node:test\').run', { concurrency: true }, () => {
|
||||
it('should run same file twice', async () => {
|
||||
const stream = run({ files: [join(testFixtures, 'test/random.cjs'), join(testFixtures, 'test/random.cjs')] });
|
||||
stream.on('test:fail', common.mustNotCall());
|
||||
stream.on('test:pass', common.mustCall(4));
|
||||
stream.on('test:pass', common.mustCall(2));
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
for await (const _ of stream);
|
||||
});
|
||||
|
Loading…
x
Reference in New Issue
Block a user