diff --git a/doc/api/test.md b/doc/api/test.md index 69caf099fbf9b8..36f6851c6acf17 100644 --- a/doc/api/test.md +++ b/doc/api/test.md @@ -2034,8 +2034,12 @@ Emitted when code coverage is enabled and all tests have completed. ### Event: `'test:dequeue'` * `data` {Object} + * `column` {number|undefined} The column number where the test is defined, or + `undefined` if the test was run through the REPL. * `file` {string|undefined} The path of the test file, `undefined` if test was run through the REPL. + * `line` {number|undefined} The line number where the test is defined, or + `undefined` if the test was run through the REPL. * `name` {string} The test name. * `nesting` {number} The nesting level of the test. @@ -2044,8 +2048,12 @@ Emitted when a test is dequeued, right before it is executed. ### Event: `'test:diagnostic'` * `data` {Object} + * `column` {number|undefined} The column number where the test is defined, or + `undefined` if the test was run through the REPL. * `file` {string|undefined} The path of the test file, `undefined` if test was run through the REPL. + * `line` {number|undefined} The line number where the test is defined, or + `undefined` if the test was run through the REPL. * `message` {string} The diagnostic message. * `nesting` {number} The nesting level of the test. @@ -2054,8 +2062,12 @@ Emitted when [`context.diagnostic`][] is called. ### Event: `'test:enqueue'` * `data` {Object} + * `column` {number|undefined} The column number where the test is defined, or + `undefined` if the test was run through the REPL. * `file` {string|undefined} The path of the test file, `undefined` if test was run through the REPL. + * `line` {number|undefined} The line number where the test is defined, or + `undefined` if the test was run through the REPL. * `name` {string} The test name. * `nesting` {number} The nesting level of the test. @@ -2064,6 +2076,8 @@ Emitted when a test is enqueued for execution. ### Event: `'test:fail'` * `data` {Object} + * `column` {number|undefined} The column number where the test is defined, or + `undefined` if the test was run through the REPL. * `details` {Object} Additional execution metadata. * `duration_ms` {number} The duration of the test in milliseconds. * `error` {Error} An error wrapping the error thrown by the test. @@ -2072,6 +2086,8 @@ Emitted when a test is enqueued for execution. this is a suite. * `file` {string|undefined} The path of the test file, `undefined` if test was run through the REPL. + * `line` {number|undefined} The line number where the test is defined, or + `undefined` if the test was run through the REPL. * `name` {string} The test name. * `nesting` {number} The nesting level of the test. * `testNumber` {number} The ordinal number of the test. @@ -2083,12 +2099,16 @@ Emitted when a test fails. ### Event: `'test:pass'` * `data` {Object} + * `column` {number|undefined} The column number where the test is defined, or + `undefined` if the test was run through the REPL. * `details` {Object} Additional execution metadata. * `duration_ms` {number} The duration of the test in milliseconds. * `type` {string|undefined} The type of the test, used to denote whether this is a suite. * `file` {string|undefined} The path of the test file, `undefined` if test was run through the REPL. + * `line` {number|undefined} The line number where the test is defined, or + `undefined` if the test was run through the REPL. * `name` {string} The test name. * `nesting` {number} The nesting level of the test. * `testNumber` {number} The ordinal number of the test. @@ -2100,8 +2120,12 @@ Emitted when a test passes. ### Event: `'test:plan'` * `data` {Object} + * `column` {number|undefined} The column number where the test is defined, or + `undefined` if the test was run through the REPL. * `file` {string|undefined} The path of the test file, `undefined` if test was run through the REPL. + * `line` {number|undefined} The line number where the test is defined, or + `undefined` if the test was run through the REPL. * `nesting` {number} The nesting level of the test. * `count` {number} The number of subtests that have ran. @@ -2110,8 +2134,12 @@ Emitted when all subtests have completed for a given test. ### Event: `'test:start'` * `data` {Object} + * `column` {number|undefined} The column number where the test is defined, or + `undefined` if the test was run through the REPL. * `file` {string|undefined} The path of the test file, `undefined` if test was run through the REPL. + * `line` {number|undefined} The line number where the test is defined, or + `undefined` if the test was run through the REPL. * `name` {string} The test name. * `nesting` {number} The nesting level of the test. @@ -2122,7 +2150,11 @@ defined. ### Event: `'test:stderr'` * `data` {Object} + * `column` {number|undefined} The column number where the test is defined, or + `undefined` if the test was run through the REPL. * `file` {string} The path of the test file. + * `line` {number|undefined} The line number where the test is defined, or + `undefined` if the test was run through the REPL. * `message` {string} The message written to `stderr`. Emitted when a running test writes to `stderr`. @@ -2131,7 +2163,11 @@ This event is only emitted if `--test` flag is passed. ### Event: `'test:stdout'` * `data` {Object} + * `column` {number|undefined} The column number where the test is defined, or + `undefined` if the test was run through the REPL. * `file` {string} The path of the test file. + * `line` {number|undefined} The line number where the test is defined, or + `undefined` if the test was run through the REPL. * `message` {string} The message written to `stdout`. Emitted when a running test writes to `stdout`. diff --git a/lib/internal/test_runner/harness.js b/lib/internal/test_runner/harness.js index 36c36f2de14b04..4eb6458b23e47d 100644 --- a/lib/internal/test_runner/harness.js +++ b/lib/internal/test_runner/harness.js @@ -5,6 +5,7 @@ const { PromiseResolve, SafeMap, } = primordials; +const { getCallerLocation } = internalBinding('util'); const { createHook, executionAsyncId, @@ -217,9 +218,24 @@ function runInParentContext(Factory) { return PromiseResolve(); } - const test = (name, options, fn) => run(name, options, fn); + const test = (name, options, fn) => { + const overrides = { + __proto__: null, + loc: getCallerLocation(), + }; + + return run(name, options, fn, overrides); + }; ArrayPrototypeForEach(['skip', 'todo', 'only'], (keyword) => { - test[keyword] = (name, options, fn) => run(name, options, fn, { __proto__: null, [keyword]: true }); + test[keyword] = (name, options, fn) => { + const overrides = { + __proto__: null, + [keyword]: true, + loc: getCallerLocation(), + }; + + return run(name, options, fn, overrides); + }; }); return test; } @@ -227,7 +243,13 @@ function runInParentContext(Factory) { function hook(hook) { return (fn, options) => { const parent = testResources.get(executionAsyncId()) || getGlobalRoot(); - parent.createHook(hook, fn, options); + parent.createHook(hook, fn, { + __proto__: null, + ...options, + parent, + hookType: hook, + loc: getCallerLocation(), + }); }; } diff --git a/lib/internal/test_runner/reporter/spec.js b/lib/internal/test_runner/reporter/spec.js index f15b3eaa40aa27..0c5a3e95c7c75a 100644 --- a/lib/internal/test_runner/reporter/spec.js +++ b/lib/internal/test_runner/reporter/spec.js @@ -17,6 +17,7 @@ const { inspectWithNoCustomRetry } = require('internal/errors'); const { green, blue, red, white, gray, shouldColorize } = require('internal/util/colors'); const { kSubtestsFailed } = require('internal/test_runner/test'); const { getCoverageReport } = require('internal/test_runner/utils'); +const { relative } = require('path'); const inspectOptions = { __proto__: null, colors: shouldColorize(process.stdout), breakLength: Infinity }; @@ -40,6 +41,7 @@ class SpecReporter extends Transform { #reported = []; #indentMemo = new SafeMap(); #failedTests = []; + #cwd = process.cwd(); constructor() { super({ __proto__: null, writableObjectMode: true }); @@ -142,10 +144,12 @@ class SpecReporter extends Transform { } const results = [`\n${colors['test:fail']}${symbols['test:fail']}failing tests:${white}\n`]; for (let i = 0; i < this.#failedTests.length; i++) { - ArrayPrototypePush(results, this.#formatTestReport( - 'test:fail', - this.#failedTests[i], - )); + const test = this.#failedTests[i]; + const relPath = relative(this.#cwd, test.file); + const formattedErr = this.#formatTestReport('test:fail', test); + const location = `test at ${relPath}:${test.line}:${test.column}`; + + ArrayPrototypePush(results, location, formattedErr); } callback(null, ArrayPrototypeJoin(results, '\n')); } diff --git a/lib/internal/test_runner/reporter/tap.js b/lib/internal/test_runner/reporter/tap.js index de8188c58dd31e..1f60cfa619886e 100644 --- a/lib/internal/test_runner/reporter/tap.js +++ b/lib/internal/test_runner/reporter/tap.js @@ -31,13 +31,14 @@ async function * tapReporter(source) { yield `TAP version ${kDefaultTAPVersion}\n`; for await (const { type, data } of source) { switch (type) { - case 'test:fail': + case 'test:fail': { yield reportTest(data.nesting, data.testNumber, 'not ok', data.name, data.skip, data.todo); - yield reportDetails(data.nesting, data.details); + const location = `${data.file}:${data.line}:${data.column}`; + yield reportDetails(data.nesting, data.details, location); break; - case 'test:pass': + } case 'test:pass': yield reportTest(data.nesting, data.testNumber, 'ok', data.name, data.skip, data.todo); - yield reportDetails(data.nesting, data.details); + yield reportDetails(data.nesting, data.details, null); break; case 'test:plan': yield `${indent(data.nesting)}1..${data.count}\n`; @@ -81,13 +82,18 @@ function reportTest(nesting, testNumber, status, name, skip, todo) { return line; } -function reportDetails(nesting, data = kEmptyObject) { +function reportDetails(nesting, data = kEmptyObject, location) { const { error, duration_ms } = data; const _indent = indent(nesting); let details = `${_indent} ---\n`; details += jsToYaml(_indent, 'duration_ms', duration_ms); details += jsToYaml(_indent, 'type', data.type); + + if (location) { + details += jsToYaml(_indent, 'location', location); + } + details += jsToYaml(_indent, null, error, new SafeSet()); details += `${_indent} ...\n`; return details; diff --git a/lib/internal/test_runner/test.js b/lib/internal/test_runner/test.js index cc7c81cad88c0d..58f1de711f38f4 100644 --- a/lib/internal/test_runner/test.js +++ b/lib/internal/test_runner/test.js @@ -24,6 +24,7 @@ const { ObjectDefineProperty, Symbol, } = primordials; +const { getCallerLocation } = internalBinding('util'); const { addAbortListener } = require('events'); const { AsyncResource } = require('async_hooks'); const { AbortController } = require('internal/abort_controller'); @@ -153,8 +154,15 @@ class TestContext { } test(name, options, fn) { - // eslint-disable-next-line no-use-before-define - const subtest = this.#test.createSubtest(Test, name, options, fn); + const overrides = { + __proto__: null, + loc: getCallerLocation(), + }; + + const subtest = this.#test.createSubtest( + // eslint-disable-next-line no-use-before-define + Test, name, options, fn, overrides, + ); return subtest.start(); } @@ -201,7 +209,7 @@ class Test extends AsyncResource { super('Test'); let { fn, name, parent, skip } = options; - const { concurrency, only, timeout, todo, signal } = options; + const { concurrency, loc, only, timeout, todo, signal } = options; if (typeof fn !== 'function') { fn = noop; @@ -332,6 +340,17 @@ class Test extends AsyncResource { "'only' and 'runOnly' require the --test-only command-line option."; this.diagnostic(warning); } + + if (loc === undefined || kFilename === undefined) { + this.loc = undefined; + } else { + this.loc = { + __proto__: null, + line: loc[0], + column: loc[1], + file: loc[2], + }; + } } matchesTestNamePatterns() { @@ -351,7 +370,7 @@ class Test extends AsyncResource { while (this.pendingSubtests.length > 0 && this.hasConcurrency()) { const deferred = ArrayPrototypeShift(this.pendingSubtests); const test = deferred.test; - this.reporter.dequeue(test.nesting, kFilename, test.name); + this.reporter.dequeue(test.nesting, test.loc, test.name); await test.run(); deferred.resolve(); } @@ -510,7 +529,7 @@ class Test extends AsyncResource { // If there is enough available concurrency to run the test now, then do // it. Otherwise, return a Promise to the caller and mark the test as // pending for later execution. - this.reporter.enqueue(this.nesting, kFilename, this.name); + this.reporter.enqueue(this.nesting, this.loc, this.name); if (!this.parent.hasConcurrency()) { const deferred = createDeferredPromise(); @@ -519,7 +538,7 @@ class Test extends AsyncResource { return deferred.promise; } - this.reporter.dequeue(this.nesting, kFilename, this.name); + this.reporter.dequeue(this.nesting, this.loc, this.name); return this.run(); } @@ -688,37 +707,37 @@ class Test extends AsyncResource { this.parent.processReadySubtestRange(false); this.parent.processPendingSubtests(); } else if (!this.reported) { - if (!this.passed && failed === 0 && this.error) { - this.reporter.fail(0, kFilename, this.subtests.length + 1, kFilename, { - __proto__: null, - duration_ms: this.#duration(), - error: this.error, - }, undefined); - } + const { + diagnostics, + harness, + loc, + nesting, + reporter, + } = this; this.reported = true; - this.reporter.plan(this.nesting, kFilename, this.root.harness.counters.topLevel); + reporter.plan(nesting, loc, harness.counters.topLevel); - for (let i = 0; i < this.diagnostics.length; i++) { - this.reporter.diagnostic(this.nesting, kFilename, this.diagnostics[i]); + for (let i = 0; i < diagnostics.length; i++) { + reporter.diagnostic(nesting, loc, diagnostics[i]); } - this.reporter.diagnostic(this.nesting, kFilename, `tests ${this.root.harness.counters.all}`); - this.reporter.diagnostic(this.nesting, kFilename, `suites ${this.root.harness.counters.suites}`); - this.reporter.diagnostic(this.nesting, kFilename, `pass ${this.root.harness.counters.passed}`); - this.reporter.diagnostic(this.nesting, kFilename, `fail ${this.root.harness.counters.failed}`); - this.reporter.diagnostic(this.nesting, kFilename, `cancelled ${this.root.harness.counters.cancelled}`); - this.reporter.diagnostic(this.nesting, kFilename, `skipped ${this.root.harness.counters.skipped}`); - this.reporter.diagnostic(this.nesting, kFilename, `todo ${this.root.harness.counters.todo}`); - this.reporter.diagnostic(this.nesting, kFilename, `duration_ms ${this.#duration()}`); + reporter.diagnostic(nesting, loc, `tests ${harness.counters.all}`); + reporter.diagnostic(nesting, loc, `suites ${harness.counters.suites}`); + reporter.diagnostic(nesting, loc, `pass ${harness.counters.passed}`); + reporter.diagnostic(nesting, loc, `fail ${harness.counters.failed}`); + reporter.diagnostic(nesting, loc, `cancelled ${harness.counters.cancelled}`); + reporter.diagnostic(nesting, loc, `skipped ${harness.counters.skipped}`); + reporter.diagnostic(nesting, loc, `todo ${harness.counters.todo}`); + reporter.diagnostic(nesting, loc, `duration_ms ${this.duration()}`); - const coverage = this.harness.coverage(); + const coverage = harness.coverage(); if (coverage) { - this.reporter.coverage(this.nesting, kFilename, coverage); + reporter.coverage(nesting, loc, coverage); } - this.reporter.end(); + reporter.end(); } } @@ -746,7 +765,7 @@ class Test extends AsyncResource { this.finished = true; } - #duration() { + duration() { // Duration is recorded in BigInt nanoseconds. Convert to milliseconds. return Number(this.endTime - this.startTime) / 1_000_000; } @@ -754,12 +773,12 @@ class Test extends AsyncResource { report() { countCompletedTest(this); if (this.subtests.length > 0) { - this.reporter.plan(this.subtests[0].nesting, kFilename, this.subtests.length); + this.reporter.plan(this.subtests[0].nesting, this.loc, this.subtests.length); } else { this.reportStarted(); } let directive; - const details = { __proto__: null, duration_ms: this.#duration() }; + const details = { __proto__: null, duration_ms: this.duration() }; if (this.skipped) { directive = this.reporter.getSkip(this.message); @@ -772,14 +791,14 @@ class Test extends AsyncResource { } if (this.passed) { - this.reporter.ok(this.nesting, kFilename, this.testNumber, this.name, details, directive); + this.reporter.ok(this.nesting, this.loc, this.testNumber, this.name, details, directive); } else { details.error = this.error; - this.reporter.fail(this.nesting, kFilename, this.testNumber, this.name, details, directive); + this.reporter.fail(this.nesting, this.loc, this.testNumber, this.name, details, directive); } for (let i = 0; i < this.diagnostics.length; i++) { - this.reporter.diagnostic(this.nesting, kFilename, this.diagnostics[i]); + this.reporter.diagnostic(this.nesting, this.loc, this.diagnostics[i]); } } @@ -789,7 +808,7 @@ class Test extends AsyncResource { } this.#reportedSubtest = true; this.parent.reportStarted(); - this.reporter.start(this.nesting, kFilename, this.name); + this.reporter.start(this.nesting, this.loc, this.name); } } @@ -799,8 +818,11 @@ class TestHook extends Test { if (options === null || typeof options !== 'object') { options = kEmptyObject; } - const { timeout, signal } = options; - super({ __proto__: null, fn, timeout, signal }); + const { loc, timeout, signal } = options; + super({ __proto__: null, fn, loc, timeout, signal }); + + this.parentTest = options.parent ?? null; + this.hookType = options.hookType; } run(args) { if (this.error && !this.outerSignal?.aborted) { @@ -821,6 +843,22 @@ class TestHook extends Test { return true; } postRun() { + const { error, loc, parentTest: parent } = this; + + // Report failures in the root test's after() hook. + if (error && parent !== null && + parent === parent.root && this.hookType === 'after') { + + if (isTestFailureError(error)) { + error.failureType = kHookFailure; + } + + parent.reporter.fail(0, loc, parent.subtests.length + 1, loc.file, { + __proto__: null, + duration_ms: this.duration(), + error, + }, undefined); + } } } diff --git a/lib/internal/test_runner/tests_stream.js b/lib/internal/test_runner/tests_stream.js index 901987681f319b..f7730caac00fa7 100644 --- a/lib/internal/test_runner/tests_stream.js +++ b/lib/internal/test_runner/tests_stream.js @@ -29,16 +29,37 @@ class TestsStream extends Readable { } } - fail(nesting, file, testNumber, name, details, directive) { - this[kEmitMessage]('test:fail', { __proto__: null, name, nesting, file, testNumber, details, ...directive }); - } - - ok(nesting, file, testNumber, name, details, directive) { - this[kEmitMessage]('test:pass', { __proto__: null, name, nesting, file, testNumber, details, ...directive }); - } - - plan(nesting, file, count) { - this[kEmitMessage]('test:plan', { __proto__: null, nesting, file, count }); + fail(nesting, loc, testNumber, name, details, directive) { + this[kEmitMessage]('test:fail', { + __proto__: null, + name, + nesting, + testNumber, + details, + ...loc, + ...directive, + }); + } + + ok(nesting, loc, testNumber, name, details, directive) { + this[kEmitMessage]('test:pass', { + __proto__: null, + name, + nesting, + testNumber, + details, + ...loc, + ...directive, + }); + } + + plan(nesting, loc, count) { + this[kEmitMessage]('test:plan', { + __proto__: null, + nesting, + count, + ...loc, + }); } getSkip(reason = undefined) { @@ -49,32 +70,57 @@ class TestsStream extends Readable { return { __proto__: null, todo: reason ?? true }; } - enqueue(nesting, file, name) { - this[kEmitMessage]('test:enqueue', { __proto__: null, nesting, file, name }); + enqueue(nesting, loc, name) { + this[kEmitMessage]('test:enqueue', { + __proto__: null, + nesting, + name, + ...loc, + }); } - dequeue(nesting, file, name) { - this[kEmitMessage]('test:dequeue', { __proto__: null, nesting, file, name }); + dequeue(nesting, loc, name) { + this[kEmitMessage]('test:dequeue', { + __proto__: null, + nesting, + name, + ...loc, + }); } - start(nesting, file, name) { - this[kEmitMessage]('test:start', { __proto__: null, nesting, file, name }); + start(nesting, loc, name) { + this[kEmitMessage]('test:start', { + __proto__: null, + nesting, + name, + ...loc, + }); } - diagnostic(nesting, file, message) { - this[kEmitMessage]('test:diagnostic', { __proto__: null, nesting, file, message }); + diagnostic(nesting, loc, message) { + this[kEmitMessage]('test:diagnostic', { + __proto__: null, + nesting, + message, + ...loc, + }); } - stderr(file, message) { - this[kEmitMessage]('test:stderr', { __proto__: null, file, message }); + stderr(loc, message) { + this[kEmitMessage]('test:stderr', { __proto__: null, message, ...loc }); } - stdout(file, message) { - this[kEmitMessage]('test:stdout', { __proto__: null, file, message }); + stdout(loc, message) { + this[kEmitMessage]('test:stdout', { __proto__: null, message, ...loc }); } - coverage(nesting, file, summary) { - this[kEmitMessage]('test:coverage', { __proto__: null, nesting, file, summary }); + coverage(nesting, loc, summary) { + this[kEmitMessage]('test:coverage', { + __proto__: null, + nesting, + summary, + ...loc, + }); } end() { diff --git a/src/node_util.cc b/src/node_util.cc index 2af3b5a7276aae..d138df86ac3b3f 100644 --- a/src/node_util.cc +++ b/src/node_util.cc @@ -34,6 +34,8 @@ using v8::PropertyFilter; using v8::Proxy; using v8::SKIP_STRINGS; using v8::SKIP_SYMBOLS; +using v8::StackFrame; +using v8::StackTrace; using v8::String; using v8::Uint32; using v8::Value; @@ -140,6 +142,24 @@ static void GetProxyDetails(const FunctionCallbackInfo& args) { } } +static void GetCallerLocation(const FunctionCallbackInfo& args) { + Isolate* isolate = args.GetIsolate(); + Local trace = StackTrace::CurrentStackTrace(isolate, 2); + + // This function is frame zero. The caller is frame one. If there aren't two + // stack frames, return undefined. + if (trace->GetFrameCount() != 2) { + return; + } + + Local frame = trace->GetFrame(isolate, 1); + Local ret[] = {Integer::New(isolate, frame->GetLineNumber()), + Integer::New(isolate, frame->GetColumn()), + frame->GetScriptNameOrSourceURL()}; + + args.GetReturnValue().Set(Array::New(args.GetIsolate(), ret, arraysize(ret))); +} + static void IsArrayBufferDetached(const FunctionCallbackInfo& args) { if (args[0]->IsArrayBuffer()) { auto buffer = args[0].As(); @@ -393,6 +413,7 @@ static void ToUSVString(const FunctionCallbackInfo& args) { void RegisterExternalReferences(ExternalReferenceRegistry* registry) { registry->Register(GetPromiseDetails); registry->Register(GetProxyDetails); + registry->Register(GetCallerLocation); registry->Register(IsArrayBufferDetached); registry->Register(PreviewEntries); registry->Register(GetOwnNonIndexProperties); @@ -494,6 +515,8 @@ void Initialize(Local target, SetMethodNoSideEffect( context, target, "getPromiseDetails", GetPromiseDetails); SetMethodNoSideEffect(context, target, "getProxyDetails", GetProxyDetails); + SetMethodNoSideEffect( + context, target, "getCallerLocation", GetCallerLocation); SetMethodNoSideEffect( context, target, "isArrayBufferDetached", IsArrayBufferDetached); SetMethodNoSideEffect(context, target, "previewEntries", PreviewEntries); diff --git a/test/fixtures/test-runner/output/abort.snapshot b/test/fixtures/test-runner/output/abort.snapshot index f756377172da65..ceca09da14bfb1 100644 --- a/test/fixtures/test-runner/output/abort.snapshot +++ b/test/fixtures/test-runner/output/abort.snapshot @@ -24,6 +24,7 @@ TAP version 13 not ok 5 - not ok 1 --- duration_ms: * + location: '/test/fixtures/test-runner/output/abort.js:(LINE):7' failureType: 'cancelledByParent' error: 'test did not finish before its parent and was cancelled' code: 'ERR_TEST_FAILURE' @@ -32,6 +33,7 @@ TAP version 13 not ok 6 - not ok 2 --- duration_ms: ZERO + location: '/test/fixtures/test-runner/output/abort.js:(LINE):7' failureType: 'cancelledByParent' error: 'test did not finish before its parent and was cancelled' code: 'ERR_TEST_FAILURE' @@ -40,6 +42,7 @@ TAP version 13 not ok 7 - not ok 3 --- duration_ms: ZERO + location: '/test/fixtures/test-runner/output/abort.js:(LINE):7' failureType: 'testAborted' error: 'This operation was aborted' code: 20 @@ -60,6 +63,7 @@ TAP version 13 not ok 8 - not ok 4 --- duration_ms: ZERO + location: '/test/fixtures/test-runner/output/abort.js:(LINE):7' failureType: 'testAborted' error: 'This operation was aborted' code: 20 @@ -80,6 +84,7 @@ TAP version 13 not ok 9 - not ok 5 --- duration_ms: ZERO + location: '/test/fixtures/test-runner/output/abort.js:(LINE):7' failureType: 'testAborted' error: 'This operation was aborted' code: 20 @@ -100,6 +105,7 @@ TAP version 13 not ok 1 - promise timeout signal --- duration_ms: * + location: '/test/fixtures/test-runner/output/abort.js:(LINE):1' failureType: 'testAborted' error: 'The operation was aborted due to timeout' code: 23 @@ -114,6 +120,7 @@ not ok 1 - promise timeout signal not ok 2 - promise abort signal --- duration_ms: * + location: '/test/fixtures/test-runner/output/abort.js:(LINE):1' failureType: 'testAborted' error: 'This operation was aborted' code: 20 @@ -154,6 +161,7 @@ not ok 2 - promise abort signal not ok 5 - not ok 1 --- duration_ms: * + location: '/test/fixtures/test-runner/output/abort.js:(LINE):5' failureType: 'cancelledByParent' error: 'test did not finish before its parent and was cancelled' code: 'ERR_TEST_FAILURE' @@ -162,6 +170,7 @@ not ok 2 - promise abort signal not ok 6 - not ok 2 --- duration_ms: ZERO + location: '/test/fixtures/test-runner/output/abort.js:(LINE):5' failureType: 'cancelledByParent' error: 'test did not finish before its parent and was cancelled' code: 'ERR_TEST_FAILURE' @@ -170,6 +179,7 @@ not ok 2 - promise abort signal not ok 7 - not ok 3 --- duration_ms: ZERO + location: '/test/fixtures/test-runner/output/abort.js:(LINE):5' failureType: 'testAborted' error: 'This operation was aborted' code: 20 @@ -190,6 +200,7 @@ not ok 2 - promise abort signal not ok 8 - not ok 4 --- duration_ms: ZERO + location: '/test/fixtures/test-runner/output/abort.js:(LINE):5' failureType: 'testAborted' error: 'This operation was aborted' code: 20 @@ -210,6 +221,7 @@ not ok 2 - promise abort signal not ok 9 - not ok 5 --- duration_ms: ZERO + location: '/test/fixtures/test-runner/output/abort.js:(LINE):5' failureType: 'testAborted' error: 'This operation was aborted' code: 20 @@ -230,6 +242,7 @@ not ok 2 - promise abort signal not ok 3 - callback timeout signal --- duration_ms: * + location: '/test/fixtures/test-runner/output/abort.js:(LINE):1' failureType: 'testAborted' error: 'The operation was aborted due to timeout' code: 23 @@ -244,6 +257,7 @@ not ok 3 - callback timeout signal not ok 4 - callback abort signal --- duration_ms: * + location: '/test/fixtures/test-runner/output/abort.js:(LINE):1' failureType: 'testAborted' error: 'This operation was aborted' code: 20 diff --git a/test/fixtures/test-runner/output/abort_hooks.snapshot b/test/fixtures/test-runner/output/abort_hooks.snapshot index a1b5ddcd5f1908..d0b567bb6a22cd 100644 --- a/test/fixtures/test-runner/output/abort_hooks.snapshot +++ b/test/fixtures/test-runner/output/abort_hooks.snapshot @@ -12,6 +12,7 @@ TAP version 13 not ok 1 - test 1 --- duration_ms: ZERO + location: '/test/fixtures/test-runner/output/abort_hooks.js:(LINE):3' failureType: 'cancelledByParent' error: 'test did not finish before its parent and was cancelled' code: 'ERR_TEST_FAILURE' @@ -20,6 +21,7 @@ TAP version 13 not ok 2 - test 2 --- duration_ms: ZERO + location: '/test/fixtures/test-runner/output/abort_hooks.js:(LINE):3' failureType: 'cancelledByParent' error: 'test did not finish before its parent and was cancelled' code: 'ERR_TEST_FAILURE' @@ -29,6 +31,7 @@ not ok 1 - 1 before describe --- duration_ms: * type: 'suite' + location: '/test/fixtures/test-runner/output/abort_hooks.js:(LINE):1' failureType: 'hookFailed' error: 'This operation was aborted' code: 20 @@ -61,6 +64,7 @@ not ok 2 - 2 after describe --- duration_ms: * type: 'suite' + location: '/test/fixtures/test-runner/output/abort_hooks.js:(LINE):1' failureType: 'hookFailed' error: 'This operation was aborted' code: 20 @@ -82,6 +86,7 @@ not ok 2 - 2 after describe not ok 1 - test 1 --- duration_ms: * + location: '/test/fixtures/test-runner/output/abort_hooks.js:(LINE):3' failureType: 'hookFailed' error: 'This operation was aborted' code: 20 @@ -102,6 +107,7 @@ not ok 2 - 2 after describe not ok 2 - test 2 --- duration_ms: * + location: '/test/fixtures/test-runner/output/abort_hooks.js:(LINE):3' failureType: 'hookFailed' error: 'This operation was aborted' code: 20 @@ -123,6 +129,7 @@ not ok 3 - 3 beforeEach describe --- duration_ms: * type: 'suite' + location: '/test/fixtures/test-runner/output/abort_hooks.js:(LINE):1' failureType: 'subtestsFailed' error: '2 subtests failed' code: 'ERR_TEST_FAILURE' @@ -132,6 +139,7 @@ not ok 3 - 3 beforeEach describe not ok 1 - test 1 --- duration_ms: * + location: '/test/fixtures/test-runner/output/abort_hooks.js:(LINE):3' failureType: 'hookFailed' error: 'This operation was aborted' code: 20 @@ -152,6 +160,7 @@ not ok 3 - 3 beforeEach describe not ok 2 - test 2 --- duration_ms: * + location: '/test/fixtures/test-runner/output/abort_hooks.js:(LINE):3' failureType: 'hookFailed' error: 'This operation was aborted' code: 20 @@ -173,6 +182,7 @@ not ok 4 - 4 afterEach describe --- duration_ms: * type: 'suite' + location: '/test/fixtures/test-runner/output/abort_hooks.js:(LINE):1' failureType: 'subtestsFailed' error: '2 subtests failed' code: 'ERR_TEST_FAILURE' diff --git a/test/fixtures/test-runner/output/abort_suite.snapshot b/test/fixtures/test-runner/output/abort_suite.snapshot index e2abdadaf5a4b7..e7e8c4f4e2360f 100644 --- a/test/fixtures/test-runner/output/abort_suite.snapshot +++ b/test/fixtures/test-runner/output/abort_suite.snapshot @@ -24,6 +24,7 @@ TAP version 13 not ok 5 - not ok 1 --- duration_ms: * + location: '/test/fixtures/test-runner/output/abort_suite.js:(LINE):3' failureType: 'cancelledByParent' error: 'test did not finish before its parent and was cancelled' code: 'ERR_TEST_FAILURE' @@ -32,6 +33,7 @@ TAP version 13 not ok 6 - not ok 2 --- duration_ms: ZERO + location: '/test/fixtures/test-runner/output/abort_suite.js:(LINE):3' failureType: 'cancelledByParent' error: 'test did not finish before its parent and was cancelled' code: 'ERR_TEST_FAILURE' @@ -40,6 +42,7 @@ TAP version 13 not ok 7 - not ok 3 --- duration_ms: ZERO + location: '/test/fixtures/test-runner/output/abort_suite.js:(LINE):3' failureType: 'testAborted' error: 'This operation was aborted' code: 20 @@ -60,6 +63,7 @@ TAP version 13 not ok 8 - not ok 4 --- duration_ms: ZERO + location: '/test/fixtures/test-runner/output/abort_suite.js:(LINE):3' failureType: 'testAborted' error: 'This operation was aborted' code: 20 @@ -80,6 +84,7 @@ TAP version 13 not ok 9 - not ok 5 --- duration_ms: ZERO + location: '/test/fixtures/test-runner/output/abort_suite.js:(LINE):3' failureType: 'testAborted' error: 'This operation was aborted' code: 20 @@ -101,6 +106,7 @@ not ok 1 - describe timeout signal --- duration_ms: * type: 'suite' + location: '/test/fixtures/test-runner/output/abort_suite.js:(LINE):1' failureType: 'testAborted' error: 'The operation was aborted due to timeout' code: 23 @@ -116,6 +122,7 @@ not ok 2 - describe abort signal --- duration_ms: * type: 'suite' + location: '/test/fixtures/test-runner/output/abort_suite.js:(LINE):1' failureType: 'testAborted' error: 'This operation was aborted' code: 20 diff --git a/test/fixtures/test-runner/output/default_output.snapshot b/test/fixtures/test-runner/output/default_output.snapshot index dca844bb8402aa..b003f9299c4418 100644 --- a/test/fixtures/test-runner/output/default_output.snapshot +++ b/test/fixtures/test-runner/output/default_output.snapshot @@ -35,6 +35,7 @@ [31m✖ failing tests:[39m +* [31m✖ should fail [90m(*ms)[39m[39m Error: fail *[39m @@ -45,6 +46,7 @@ *[39m *[39m +* [31m✖ should fail [90m(*ms)[39m[39m Error: fail *[39m @@ -53,5 +55,6 @@ *[39m *[39m +* [31m✖ should pass but parent fail [90m(*ms)[39m[39m [32m'test did not finish before its parent and was cancelled'[39m diff --git a/test/fixtures/test-runner/output/describe_it.js b/test/fixtures/test-runner/output/describe_it.js index 942b1c5317abab..ba6a1aed064614 100644 --- a/test/fixtures/test-runner/output/describe_it.js +++ b/test/fixtures/test-runner/output/describe_it.js @@ -196,15 +196,6 @@ it('test with a name and options provided', { skip: true }); // A test with only options and a function provided. it({ skip: true }, function functionAndOptions() {}); -// A test whose description needs to be escaped. -it('escaped description \\ # \\#\\'); - -// A test whose skip message needs to be escaped. -it('escaped skip message', { skip: '#skip' }); - -// A test whose todo message needs to be escaped. -it('escaped todo message', { todo: '#todo' }); - it('callback pass', (t, done) => { setImmediate(done); }); diff --git a/test/fixtures/test-runner/output/describe_it.snapshot b/test/fixtures/test-runner/output/describe_it.snapshot index 0d07851e2a1fa9..be345f11575c8d 100644 --- a/test/fixtures/test-runner/output/describe_it.snapshot +++ b/test/fixtures/test-runner/output/describe_it.snapshot @@ -13,6 +13,7 @@ ok 2 - sync pass todo with message # TODO this is a passing todo not ok 3 - sync todo # TODO --- duration_ms: * + location: '/test/fixtures/test-runner/output/describe_it.js:(LINE):4' failureType: 'testCodeFailure' error: 'should not count as a failure' code: 'ERR_TEST_FAILURE' @@ -29,6 +30,7 @@ not ok 3 - sync todo # TODO not ok 4 - sync todo with message # TODO this is a failing todo --- duration_ms: * + location: '/test/fixtures/test-runner/output/describe_it.js:(LINE):1' failureType: 'testCodeFailure' error: 'should not count as a failure' code: 'ERR_TEST_FAILURE' @@ -60,6 +62,7 @@ ok 7 - sync pass not ok 8 - sync throw fail --- duration_ms: * + location: '/test/fixtures/test-runner/output/describe_it.js:(LINE):1' failureType: 'testCodeFailure' error: 'thrown from sync throw fail' code: 'ERR_TEST_FAILURE' @@ -91,6 +94,7 @@ ok 11 - mixing describe/it and test should work not ok 12 - async throw fail --- duration_ms: * + location: '/test/fixtures/test-runner/output/describe_it.js:(LINE):1' failureType: 'testCodeFailure' error: 'thrown from async throw fail' code: 'ERR_TEST_FAILURE' @@ -107,6 +111,7 @@ not ok 12 - async throw fail not ok 13 - async skip fail # SKIP --- duration_ms: * + location: '/test/fixtures/test-runner/output/describe_it.js:(LINE):1' failureType: 'callbackAndPromisePresent' error: 'passed a callback but also returned a Promise' code: 'ERR_TEST_FAILURE' @@ -115,6 +120,7 @@ not ok 13 - async skip fail # SKIP not ok 14 - async assertion fail --- duration_ms: * + location: '/test/fixtures/test-runner/output/describe_it.js:(LINE):1' failureType: 'testCodeFailure' error: |- Expected values to be strictly equal: @@ -144,6 +150,7 @@ ok 15 - resolve pass not ok 16 - reject fail --- duration_ms: * + location: '/test/fixtures/test-runner/output/describe_it.js:(LINE):1' failureType: 'testCodeFailure' error: 'rejected from reject fail' code: 'ERR_TEST_FAILURE' @@ -186,6 +193,7 @@ ok 21 - immediate resolve pass not ok 1 - +sync throw fail --- duration_ms: * + location: '/test/fixtures/test-runner/output/describe_it.js:(LINE):3' failureType: 'testCodeFailure' error: 'thrown from subtest sync throw fail' code: 'ERR_TEST_FAILURE' @@ -211,6 +219,7 @@ not ok 22 - subtest sync throw fail --- duration_ms: * type: 'suite' + location: '/test/fixtures/test-runner/output/describe_it.js:(LINE):1' failureType: 'subtestsFailed' error: '1 subtest failed' code: 'ERR_TEST_FAILURE' @@ -219,6 +228,7 @@ not ok 22 - subtest sync throw fail not ok 23 - sync throw non-error fail --- duration_ms: * + location: '/test/fixtures/test-runner/output/describe_it.js:(LINE):1' failureType: 'testCodeFailure' error: 'Symbol(thrown symbol from sync throw non-error fail)' code: 'ERR_TEST_FAILURE' @@ -270,6 +280,7 @@ ok 27 - sync skip option with message # SKIP this is skipped not ok 28 - sync skip option is false fail --- duration_ms: * + location: '/test/fixtures/test-runner/output/describe_it.js:(LINE):1' failureType: 'testCodeFailure' error: 'this should be executed' code: 'ERR_TEST_FAILURE' @@ -322,30 +333,16 @@ ok 36 - functionAndOptions # SKIP --- duration_ms: * ... -# Subtest: escaped description \\ \# \\\#\\ -ok 37 - escaped description \\ \# \\\#\\ - --- - duration_ms: * - ... -# Subtest: escaped skip message -ok 38 - escaped skip message # SKIP \#skip - --- - duration_ms: * - ... -# Subtest: escaped todo message -ok 39 - escaped todo message # TODO \#todo - --- - duration_ms: * - ... # Subtest: callback pass -ok 40 - callback pass +ok 37 - callback pass --- duration_ms: * ... # Subtest: callback fail -not ok 41 - callback fail +not ok 38 - callback fail --- duration_ms: * + location: '/test/fixtures/test-runner/output/describe_it.js:(LINE):1' failureType: 'testCodeFailure' error: 'callback failure' code: 'ERR_TEST_FAILURE' @@ -354,32 +351,34 @@ not ok 41 - callback fail * ... # Subtest: sync t is this in test -ok 42 - sync t is this in test +ok 39 - sync t is this in test --- duration_ms: * ... # Subtest: async t is this in test -ok 43 - async t is this in test +ok 40 - async t is this in test --- duration_ms: * ... # Subtest: callback t is this in test -ok 44 - callback t is this in test +ok 41 - callback t is this in test --- duration_ms: * ... # Subtest: callback also returns a Promise -not ok 45 - callback also returns a Promise +not ok 42 - callback also returns a Promise --- duration_ms: * + location: '/test/fixtures/test-runner/output/describe_it.js:(LINE):1' failureType: 'callbackAndPromisePresent' error: 'passed a callback but also returned a Promise' code: 'ERR_TEST_FAILURE' ... # Subtest: callback throw -not ok 46 - callback throw +not ok 43 - callback throw --- duration_ms: * + location: '/test/fixtures/test-runner/output/describe_it.js:(LINE):1' failureType: 'testCodeFailure' error: 'thrown from callback throw' code: 'ERR_TEST_FAILURE' @@ -393,9 +392,10 @@ not ok 46 - callback throw * ... # Subtest: callback called twice -not ok 47 - callback called twice +not ok 44 - callback called twice --- duration_ms: * + location: '/test/fixtures/test-runner/output/describe_it.js:(LINE):1' failureType: 'multipleCallbackInvocations' error: 'callback invoked multiple times' code: 'ERR_TEST_FAILURE' @@ -404,14 +404,15 @@ not ok 47 - callback called twice * ... # Subtest: callback called twice in different ticks -ok 48 - callback called twice in different ticks +ok 45 - callback called twice in different ticks --- duration_ms: * ... # Subtest: callback called twice in future tick -not ok 49 - callback called twice in future tick +not ok 46 - callback called twice in future tick --- duration_ms: * + location: '/test/fixtures/test-runner/output/describe_it.js:(LINE):1' failureType: 'uncaughtException' error: 'callback invoked multiple times' code: 'ERR_TEST_FAILURE' @@ -419,9 +420,10 @@ not ok 49 - callback called twice in future tick * ... # Subtest: callback async throw -not ok 50 - callback async throw +not ok 47 - callback async throw --- duration_ms: * + location: '/test/fixtures/test-runner/output/describe_it.js:(LINE):1' failureType: 'uncaughtException' error: 'thrown from callback async throw' code: 'ERR_TEST_FAILURE' @@ -430,22 +432,24 @@ not ok 50 - callback async throw * ... # Subtest: callback async throw after done -ok 51 - callback async throw after done +ok 48 - callback async throw after done --- duration_ms: * ... # Subtest: custom inspect symbol fail -not ok 52 - custom inspect symbol fail +not ok 49 - custom inspect symbol fail --- duration_ms: * + location: '/test/fixtures/test-runner/output/describe_it.js:(LINE):1' failureType: 'testCodeFailure' error: 'customized' code: 'ERR_TEST_FAILURE' ... # Subtest: custom inspect symbol that throws fail -not ok 53 - custom inspect symbol that throws fail +not ok 50 - custom inspect symbol that throws fail --- duration_ms: * + location: '/test/fixtures/test-runner/output/describe_it.js:(LINE):1' failureType: 'testCodeFailure' error: |- { @@ -459,6 +463,7 @@ not ok 53 - custom inspect symbol that throws fail not ok 1 - sync throw fails at first --- duration_ms: * + location: '/test/fixtures/test-runner/output/describe_it.js:(LINE):3' failureType: 'testCodeFailure' error: 'thrown from subtest sync throw fails at first' code: 'ERR_TEST_FAILURE' @@ -478,6 +483,7 @@ not ok 53 - custom inspect symbol that throws fail not ok 2 - sync throw fails at second --- duration_ms: * + location: '/test/fixtures/test-runner/output/describe_it.js:(LINE):3' failureType: 'testCodeFailure' error: 'thrown from subtest sync throw fails at second' code: 'ERR_TEST_FAILURE' @@ -494,10 +500,11 @@ not ok 53 - custom inspect symbol that throws fail async Promise.all (index 0) ... 1..2 -not ok 54 - subtest sync throw fails +not ok 51 - subtest sync throw fails --- duration_ms: * type: 'suite' + location: '/test/fixtures/test-runner/output/describe_it.js:(LINE):1' failureType: 'subtestsFailed' error: '2 subtests failed' code: 'ERR_TEST_FAILURE' @@ -507,15 +514,17 @@ not ok 54 - subtest sync throw fails not ok 1 - should not run --- duration_ms: ZERO + location: '/test/fixtures/test-runner/output/describe_it.js:(LINE):3' failureType: 'cancelledByParent' error: 'test did not finish before its parent and was cancelled' code: 'ERR_TEST_FAILURE' ... 1..1 -not ok 55 - describe sync throw fails +not ok 52 - describe sync throw fails --- duration_ms: * type: 'suite' + location: '/test/fixtures/test-runner/output/describe_it.js:(LINE):1' failureType: 'testCodeFailure' error: 'thrown from describe' code: 'ERR_TEST_FAILURE' @@ -536,15 +545,17 @@ not ok 55 - describe sync throw fails not ok 1 - should not run --- duration_ms: ZERO + location: '/test/fixtures/test-runner/output/describe_it.js:(LINE):3' failureType: 'cancelledByParent' error: 'test did not finish before its parent and was cancelled' code: 'ERR_TEST_FAILURE' ... 1..1 -not ok 56 - describe async throw fails +not ok 53 - describe async throw fails --- duration_ms: * type: 'suite' + location: '/test/fixtures/test-runner/output/describe_it.js:(LINE):1' failureType: 'testCodeFailure' error: 'thrown from describe' code: 'ERR_TEST_FAILURE' @@ -565,6 +576,7 @@ not ok 56 - describe async throw fails not ok 1 - timed out async test --- duration_ms: * + location: '/test/fixtures/test-runner/output/describe_it.js:(LINE):3' failureType: 'testTimeoutFailure' error: 'test timed out after 5ms' code: 'ERR_TEST_FAILURE' @@ -575,6 +587,7 @@ not ok 56 - describe async throw fails not ok 2 - timed out callback test --- duration_ms: * + location: '/test/fixtures/test-runner/output/describe_it.js:(LINE):3' failureType: 'testTimeoutFailure' error: 'test timed out after 5ms' code: 'ERR_TEST_FAILURE' @@ -590,10 +603,11 @@ not ok 56 - describe async throw fails duration_ms: * ... 1..4 -not ok 57 - timeouts +not ok 54 - timeouts --- duration_ms: * type: 'suite' + location: '/test/fixtures/test-runner/output/describe_it.js:(LINE):1' failureType: 'subtestsFailed' error: '2 subtests failed' code: 'ERR_TEST_FAILURE' @@ -608,6 +622,7 @@ not ok 57 - timeouts not ok 2 - rejected thenable --- duration_ms: * + location: '/test/fixtures/test-runner/output/describe_it.js:(LINE):3' failureType: 'testCodeFailure' error: 'custom error' code: 'ERR_TEST_FAILURE' @@ -616,19 +631,21 @@ not ok 57 - timeouts * ... 1..2 -not ok 58 - successful thenable +not ok 55 - successful thenable --- duration_ms: * type: 'suite' + location: '/test/fixtures/test-runner/output/describe_it.js:(LINE):1' failureType: 'subtestsFailed' error: '1 subtest failed' code: 'ERR_TEST_FAILURE' ... # Subtest: rejected thenable -not ok 59 - rejected thenable +not ok 56 - rejected thenable --- duration_ms: * type: 'suite' + location: '/test/fixtures/test-runner/output/describe_it.js:(LINE):1' failureType: 'testCodeFailure' error: 'custom error' code: 'ERR_TEST_FAILURE' @@ -659,33 +676,34 @@ not ok 59 - rejected thenable type: 'suite' ... 1..3 -ok 60 - async describe function +ok 57 - async describe function --- duration_ms: * type: 'suite' ... # Subtest: invalid subtest fail -not ok 61 - invalid subtest fail +not ok 58 - invalid subtest fail --- duration_ms: * + location: '/test/fixtures/test-runner/output/describe_it.js:(LINE):5' failureType: 'parentAlreadyFinished' error: 'test could not be started because its parent finished' code: 'ERR_TEST_FAILURE' stack: |- * ... -1..61 +1..58 # Warning: Test "unhandled rejection - passes but warns" generated asynchronous activity after the test ended. This activity created the error "Error: rejected from unhandled rejection fail" and would have caused the test to fail, but instead triggered an unhandledRejection event. # Warning: Test "async unhandled rejection - passes but warns" generated asynchronous activity after the test ended. This activity created the error "Error: rejected from async unhandled rejection fail" and would have caused the test to fail, but instead triggered an unhandledRejection event. # Warning: Test "immediate throw - passes but warns" generated asynchronous activity after the test ended. This activity created the error "Error: thrown from immediate throw fail" and would have caused the test to fail, but instead triggered an uncaughtException event. # Warning: Test "immediate reject - passes but warns" generated asynchronous activity after the test ended. This activity created the error "Error: rejected from immediate reject fail" and would have caused the test to fail, but instead triggered an unhandledRejection event. # Warning: Test "callback called twice in different ticks" generated asynchronous activity after the test ended. This activity created the error "Error [ERR_TEST_FAILURE]: callback invoked multiple times" and would have caused the test to fail, but instead triggered an uncaughtException event. # Warning: Test "callback async throw after done" generated asynchronous activity after the test ended. This activity created the error "Error: thrown from callback async throw after done" and would have caused the test to fail, but instead triggered an uncaughtException event. -# tests 70 +# tests 67 # suites 11 -# pass 32 +# pass 31 # fail 19 # cancelled 4 -# skipped 10 -# todo 5 +# skipped 9 +# todo 4 # duration_ms * diff --git a/test/fixtures/test-runner/output/dot_reporter.snapshot b/test/fixtures/test-runner/output/dot_reporter.snapshot index 5a74119b3887e5..7c6b0ff2356b77 100644 --- a/test/fixtures/test-runner/output/dot_reporter.snapshot +++ b/test/fixtures/test-runner/output/dot_reporter.snapshot @@ -1,5 +1,4 @@ ..XX...X..XXX.X..... XXX.....X..X...X.... -.........X...XXX.XX. -.....XXXXXXX...XXXXX - +.....X...XXX.XX..... +.XXXXXXX...XXXXX diff --git a/test/fixtures/test-runner/output/global_after_should_fail_the_test.snapshot b/test/fixtures/test-runner/output/global_after_should_fail_the_test.snapshot index 16693c1a8a964b..845aba58eddd32 100644 --- a/test/fixtures/test-runner/output/global_after_should_fail_the_test.snapshot +++ b/test/fixtures/test-runner/output/global_after_should_fail_the_test.snapshot @@ -8,6 +8,7 @@ ok 1 - this is a test not ok 2 - /test/fixtures/test-runner/output/global_after_should_fail_the_test.js --- duration_ms: * + location: '/test/fixtures/test-runner/output/global_after_should_fail_the_test.js:(LINE):1' failureType: 'hookFailed' error: 'this should fail the test' code: 'ERR_TEST_FAILURE' diff --git a/test/fixtures/test-runner/output/hooks.snapshot b/test/fixtures/test-runner/output/hooks.snapshot index 676e1c7a3287e3..5afe398ed3d0ea 100644 --- a/test/fixtures/test-runner/output/hooks.snapshot +++ b/test/fixtures/test-runner/output/hooks.snapshot @@ -38,6 +38,7 @@ ok 1 - describe hooks not ok 1 - 1 --- duration_ms: ZERO + location: '/test/fixtures/test-runner/output/hooks.js:(LINE):3' failureType: 'cancelledByParent' error: 'test did not finish before its parent and was cancelled' code: 'ERR_TEST_FAILURE' @@ -46,6 +47,7 @@ ok 1 - describe hooks not ok 2 - 2 --- duration_ms: ZERO + location: '/test/fixtures/test-runner/output/hooks.js:(LINE):3' failureType: 'cancelledByParent' error: 'test did not finish before its parent and was cancelled' code: 'ERR_TEST_FAILURE' @@ -55,6 +57,7 @@ not ok 2 - before throws --- duration_ms: * type: 'suite' + location: '/test/fixtures/test-runner/output/hooks.js:(LINE):1' failureType: 'hookFailed' error: 'before' code: 'ERR_TEST_FAILURE' @@ -85,6 +88,7 @@ not ok 3 - after throws --- duration_ms: * type: 'suite' + location: '/test/fixtures/test-runner/output/hooks.js:(LINE):1' failureType: 'hookFailed' error: 'after' code: 'ERR_TEST_FAILURE' @@ -104,6 +108,7 @@ not ok 3 - after throws not ok 1 - 1 --- duration_ms: * + location: '/test/fixtures/test-runner/output/hooks.js:(LINE):3' failureType: 'hookFailed' error: 'beforeEach' code: 'ERR_TEST_FAILURE' @@ -123,6 +128,7 @@ not ok 3 - after throws not ok 2 - 2 --- duration_ms: * + location: '/test/fixtures/test-runner/output/hooks.js:(LINE):3' failureType: 'hookFailed' error: 'beforeEach' code: 'ERR_TEST_FAILURE' @@ -141,6 +147,7 @@ not ok 4 - beforeEach throws --- duration_ms: * type: 'suite' + location: '/test/fixtures/test-runner/output/hooks.js:(LINE):1' failureType: 'subtestsFailed' error: '2 subtests failed' code: 'ERR_TEST_FAILURE' @@ -150,6 +157,7 @@ not ok 4 - beforeEach throws not ok 1 - 1 --- duration_ms: * + location: '/test/fixtures/test-runner/output/hooks.js:(LINE):3' failureType: 'hookFailed' error: 'afterEach' code: 'ERR_TEST_FAILURE' @@ -169,6 +177,7 @@ not ok 4 - beforeEach throws not ok 2 - 2 --- duration_ms: * + location: '/test/fixtures/test-runner/output/hooks.js:(LINE):3' failureType: 'hookFailed' error: 'afterEach' code: 'ERR_TEST_FAILURE' @@ -188,6 +197,7 @@ not ok 5 - afterEach throws --- duration_ms: * type: 'suite' + location: '/test/fixtures/test-runner/output/hooks.js:(LINE):1' failureType: 'subtestsFailed' error: '2 subtests failed' code: 'ERR_TEST_FAILURE' @@ -197,6 +207,7 @@ not ok 5 - afterEach throws not ok 1 - 1 --- duration_ms: * + location: '/test/fixtures/test-runner/output/hooks.js:(LINE):3' failureType: 'testCodeFailure' error: 'test' code: 'ERR_TEST_FAILURE' @@ -222,6 +233,7 @@ not ok 6 - afterEach when test fails --- duration_ms: * type: 'suite' + location: '/test/fixtures/test-runner/output/hooks.js:(LINE):1' failureType: 'subtestsFailed' error: '1 subtest failed' code: 'ERR_TEST_FAILURE' @@ -231,6 +243,7 @@ not ok 6 - afterEach when test fails not ok 1 - 1 --- duration_ms: * + location: '/test/fixtures/test-runner/output/hooks.js:(LINE):3' failureType: 'testCodeFailure' error: 'test' code: 'ERR_TEST_FAILURE' @@ -250,6 +263,7 @@ not ok 6 - afterEach when test fails not ok 2 - 2 --- duration_ms: * + location: '/test/fixtures/test-runner/output/hooks.js:(LINE):3' failureType: 'hookFailed' error: 'afterEach' code: 'ERR_TEST_FAILURE' @@ -269,6 +283,7 @@ not ok 7 - afterEach throws and test fails --- duration_ms: * type: 'suite' + location: '/test/fixtures/test-runner/output/hooks.js:(LINE):1' failureType: 'subtestsFailed' error: '2 subtests failed' code: 'ERR_TEST_FAILURE' @@ -310,6 +325,7 @@ ok 8 - test hooks not ok 1 - 1 --- duration_ms: * + location: '/test/fixtures/test-runner/output/hooks.js:(LINE):11' failureType: 'hookFailed' error: 'before' code: 'ERR_TEST_FAILURE' @@ -329,6 +345,7 @@ ok 8 - test hooks not ok 2 - 2 --- duration_ms: * + location: '/test/fixtures/test-runner/output/hooks.js:(LINE):11' failureType: 'hookFailed' error: 'before' code: 'ERR_TEST_FAILURE' @@ -348,6 +365,7 @@ ok 8 - test hooks not ok 9 - t.before throws --- duration_ms: * + location: '/test/fixtures/test-runner/output/hooks.js:(LINE):1' failureType: 'subtestsFailed' error: '2 subtests failed' code: 'ERR_TEST_FAILURE' @@ -357,6 +375,7 @@ not ok 9 - t.before throws not ok 1 - 1 --- duration_ms: * + location: '/test/fixtures/test-runner/output/hooks.js:(LINE):11' failureType: 'hookFailed' error: 'beforeEach' code: 'ERR_TEST_FAILURE' @@ -376,6 +395,7 @@ not ok 9 - t.before throws not ok 2 - 2 --- duration_ms: * + location: '/test/fixtures/test-runner/output/hooks.js:(LINE):11' failureType: 'hookFailed' error: 'beforeEach' code: 'ERR_TEST_FAILURE' @@ -395,6 +415,7 @@ not ok 9 - t.before throws not ok 10 - t.beforeEach throws --- duration_ms: * + location: '/test/fixtures/test-runner/output/hooks.js:(LINE):1' failureType: 'subtestsFailed' error: '2 subtests failed' code: 'ERR_TEST_FAILURE' @@ -404,6 +425,7 @@ not ok 10 - t.beforeEach throws not ok 1 - 1 --- duration_ms: * + location: '/test/fixtures/test-runner/output/hooks.js:(LINE):11' failureType: 'hookFailed' error: 'afterEach' code: 'ERR_TEST_FAILURE' @@ -423,6 +445,7 @@ not ok 10 - t.beforeEach throws not ok 2 - 2 --- duration_ms: * + location: '/test/fixtures/test-runner/output/hooks.js:(LINE):11' failureType: 'hookFailed' error: 'afterEach' code: 'ERR_TEST_FAILURE' @@ -442,6 +465,7 @@ not ok 10 - t.beforeEach throws not ok 11 - t.afterEach throws --- duration_ms: * + location: '/test/fixtures/test-runner/output/hooks.js:(LINE):1' failureType: 'subtestsFailed' error: '2 subtests failed' code: 'ERR_TEST_FAILURE' @@ -451,6 +475,7 @@ not ok 11 - t.afterEach throws not ok 1 - 1 --- duration_ms: * + location: '/test/fixtures/test-runner/output/hooks.js:(LINE):11' failureType: 'testCodeFailure' error: 'test' code: 'ERR_TEST_FAILURE' @@ -474,6 +499,7 @@ not ok 11 - t.afterEach throws not ok 12 - afterEach when test fails --- duration_ms: * + location: '/test/fixtures/test-runner/output/hooks.js:(LINE):1' failureType: 'subtestsFailed' error: '1 subtest failed' code: 'ERR_TEST_FAILURE' @@ -483,6 +509,7 @@ not ok 12 - afterEach when test fails not ok 1 - 1 --- duration_ms: * + location: '/test/fixtures/test-runner/output/hooks.js:(LINE):11' failureType: 'testCodeFailure' error: 'test' code: 'ERR_TEST_FAILURE' @@ -501,6 +528,7 @@ not ok 12 - afterEach when test fails not ok 2 - 2 --- duration_ms: * + location: '/test/fixtures/test-runner/output/hooks.js:(LINE):11' failureType: 'hookFailed' error: 'afterEach' code: 'ERR_TEST_FAILURE' @@ -520,6 +548,7 @@ not ok 12 - afterEach when test fails not ok 13 - afterEach throws and test fails --- duration_ms: * + location: '/test/fixtures/test-runner/output/hooks.js:(LINE):1' failureType: 'subtestsFailed' error: '2 subtests failed' code: 'ERR_TEST_FAILURE' @@ -528,6 +557,7 @@ not ok 13 - afterEach throws and test fails not ok 14 - t.after() is called if test body throws --- duration_ms: * + location: '/test/fixtures/test-runner/output/hooks.js:(LINE):1' failureType: 'testCodeFailure' error: 'bye' code: 'ERR_TEST_FAILURE' diff --git a/test/fixtures/test-runner/output/no_refs.snapshot b/test/fixtures/test-runner/output/no_refs.snapshot index 49c51af41caec3..5756f5ebf87a0a 100644 --- a/test/fixtures/test-runner/output/no_refs.snapshot +++ b/test/fixtures/test-runner/output/no_refs.snapshot @@ -4,6 +4,7 @@ TAP version 13 not ok 1 - +does not keep event loop alive --- duration_ms: * + location: '/test/fixtures/test-runner/output/no_refs.js:(LINE):11' failureType: 'cancelledByParent' error: 'Promise resolution is still pending but the event loop has already resolved' code: 'ERR_TEST_FAILURE' @@ -14,6 +15,7 @@ TAP version 13 not ok 1 - does not keep event loop alive --- duration_ms: * + location: '/test/fixtures/test-runner/output/no_refs.js:(LINE):1' failureType: 'cancelledByParent' error: 'Promise resolution is still pending but the event loop has already resolved' code: 'ERR_TEST_FAILURE' diff --git a/test/fixtures/test-runner/output/output.js b/test/fixtures/test-runner/output/output.js index 47d99d1c8d4984..f37d3495030950 100644 --- a/test/fixtures/test-runner/output/output.js +++ b/test/fixtures/test-runner/output/output.js @@ -212,20 +212,6 @@ test('test with a name and options provided', { skip: true }); // A test with only options and a function provided. test({ skip: true }, function functionAndOptions() {}); -// A test whose description needs to be escaped. -test('escaped description \\ # \\#\\ \n \t \f \v \b \r'); - -// A test whose skip message needs to be escaped. -test('escaped skip message', { skip: '#skip' }); - -// A test whose todo message needs to be escaped. -test('escaped todo message', { todo: '#todo' }); - -// A test with a diagnostic message that needs to be escaped. -test('escaped diagnostic', (t) => { - t.diagnostic('#diagnostic'); -}); - test('callback pass', (t, done) => { setImmediate(done); }); diff --git a/test/fixtures/test-runner/output/output.snapshot b/test/fixtures/test-runner/output/output.snapshot index db19d8ca549a38..18f030dab361ab 100644 --- a/test/fixtures/test-runner/output/output.snapshot +++ b/test/fixtures/test-runner/output/output.snapshot @@ -13,6 +13,7 @@ ok 2 - sync pass todo with message # TODO this is a passing todo not ok 3 - sync fail todo # TODO --- duration_ms: * + location: '/test/fixtures/test-runner/output/output.js:(LINE):1' failureType: 'testCodeFailure' error: 'thrown from sync fail todo' code: 'ERR_TEST_FAILURE' @@ -29,6 +30,7 @@ not ok 3 - sync fail todo # TODO not ok 4 - sync fail todo with message # TODO this is a failing todo --- duration_ms: * + location: '/test/fixtures/test-runner/output/output.js:(LINE):1' failureType: 'testCodeFailure' error: 'thrown from sync fail todo with message' code: 'ERR_TEST_FAILURE' @@ -61,6 +63,7 @@ ok 7 - sync pass not ok 8 - sync throw fail --- duration_ms: * + location: '/test/fixtures/test-runner/output/output.js:(LINE):1' failureType: 'testCodeFailure' error: 'thrown from sync throw fail' code: 'ERR_TEST_FAILURE' @@ -87,6 +90,7 @@ ok 10 - async pass not ok 11 - async throw fail --- duration_ms: * + location: '/test/fixtures/test-runner/output/output.js:(LINE):1' failureType: 'testCodeFailure' error: 'thrown from async throw fail' code: 'ERR_TEST_FAILURE' @@ -103,6 +107,7 @@ not ok 11 - async throw fail not ok 12 - async skip fail # SKIP --- duration_ms: * + location: '/test/fixtures/test-runner/output/output.js:(LINE):1' failureType: 'testCodeFailure' error: 'thrown from async throw fail' code: 'ERR_TEST_FAILURE' @@ -119,6 +124,7 @@ not ok 12 - async skip fail # SKIP not ok 13 - async assertion fail --- duration_ms: * + location: '/test/fixtures/test-runner/output/output.js:(LINE):1' failureType: 'testCodeFailure' error: |- Expected values to be strictly equal: @@ -148,6 +154,7 @@ ok 14 - resolve pass not ok 15 - reject fail --- duration_ms: * + location: '/test/fixtures/test-runner/output/output.js:(LINE):1' failureType: 'testCodeFailure' error: 'rejected from reject fail' code: 'ERR_TEST_FAILURE' @@ -190,6 +197,7 @@ ok 20 - immediate resolve pass not ok 1 - +sync throw fail --- duration_ms: * + location: '/test/fixtures/test-runner/output/output.js:(LINE):11' failureType: 'testCodeFailure' error: 'thrown from subtest sync throw fail' code: 'ERR_TEST_FAILURE' @@ -210,6 +218,7 @@ ok 20 - immediate resolve pass not ok 21 - subtest sync throw fail --- duration_ms: * + location: '/test/fixtures/test-runner/output/output.js:(LINE):1' failureType: 'subtestsFailed' error: '1 subtest failed' code: 'ERR_TEST_FAILURE' @@ -218,6 +227,7 @@ not ok 21 - subtest sync throw fail not ok 22 - sync throw non-error fail --- duration_ms: * + location: '/test/fixtures/test-runner/output/output.js:(LINE):1' failureType: 'testCodeFailure' error: 'Symbol(thrown symbol from sync throw non-error fail)' code: 'ERR_TEST_FAILURE' @@ -253,6 +263,7 @@ ok 23 - level 0a not ok 1 - +long running --- duration_ms: * + location: '/test/fixtures/test-runner/output/output.js:(LINE):5' failureType: 'cancelledByParent' error: 'test did not finish before its parent and was cancelled' code: 'ERR_TEST_FAILURE' @@ -272,6 +283,7 @@ ok 23 - level 0a not ok 24 - top level --- duration_ms: * + location: '/test/fixtures/test-runner/output/output.js:(LINE):1' failureType: 'subtestsFailed' error: '1 subtest failed' code: 'ERR_TEST_FAILURE' @@ -295,6 +307,7 @@ ok 27 - sync skip option with message # SKIP this is skipped not ok 28 - sync skip option is false fail --- duration_ms: * + location: '/test/fixtures/test-runner/output/output.js:(LINE):1' failureType: 'testCodeFailure' error: 'this should be executed' code: 'ERR_TEST_FAILURE' @@ -347,36 +360,16 @@ ok 36 - functionAndOptions # SKIP --- duration_ms: * ... -# Subtest: escaped description \\ \# \\\#\\ \\n \\t \\f \\v \\b \\r -ok 37 - escaped description \\ \# \\\#\\ \\n \\t \\f \\v \\b \\r - --- - duration_ms: * - ... -# Subtest: escaped skip message -ok 38 - escaped skip message # SKIP \#skip - --- - duration_ms: * - ... -# Subtest: escaped todo message -ok 39 - escaped todo message # TODO \#todo - --- - duration_ms: * - ... -# Subtest: escaped diagnostic -ok 40 - escaped diagnostic - --- - duration_ms: * - ... -# \#diagnostic # Subtest: callback pass -ok 41 - callback pass +ok 37 - callback pass --- duration_ms: * ... # Subtest: callback fail -not ok 42 - callback fail +not ok 38 - callback fail --- duration_ms: * + location: '/test/fixtures/test-runner/output/output.js:(LINE):1' failureType: 'testCodeFailure' error: 'callback failure' code: 'ERR_TEST_FAILURE' @@ -385,32 +378,34 @@ not ok 42 - callback fail * ... # Subtest: sync t is this in test -ok 43 - sync t is this in test +ok 39 - sync t is this in test --- duration_ms: * ... # Subtest: async t is this in test -ok 44 - async t is this in test +ok 40 - async t is this in test --- duration_ms: * ... # Subtest: callback t is this in test -ok 45 - callback t is this in test +ok 41 - callback t is this in test --- duration_ms: * ... # Subtest: callback also returns a Promise -not ok 46 - callback also returns a Promise +not ok 42 - callback also returns a Promise --- duration_ms: * + location: '/test/fixtures/test-runner/output/output.js:(LINE):1' failureType: 'callbackAndPromisePresent' error: 'passed a callback but also returned a Promise' code: 'ERR_TEST_FAILURE' ... # Subtest: callback throw -not ok 47 - callback throw +not ok 43 - callback throw --- duration_ms: * + location: '/test/fixtures/test-runner/output/output.js:(LINE):1' failureType: 'testCodeFailure' error: 'thrown from callback throw' code: 'ERR_TEST_FAILURE' @@ -424,9 +419,10 @@ not ok 47 - callback throw * ... # Subtest: callback called twice -not ok 48 - callback called twice +not ok 44 - callback called twice --- duration_ms: * + location: '/test/fixtures/test-runner/output/output.js:(LINE):1' failureType: 'multipleCallbackInvocations' error: 'callback invoked multiple times' code: 'ERR_TEST_FAILURE' @@ -435,14 +431,15 @@ not ok 48 - callback called twice * ... # Subtest: callback called twice in different ticks -ok 49 - callback called twice in different ticks +ok 45 - callback called twice in different ticks --- duration_ms: * ... # Subtest: callback called twice in future tick -not ok 50 - callback called twice in future tick +not ok 46 - callback called twice in future tick --- duration_ms: * + location: '/test/fixtures/test-runner/output/output.js:(LINE):1' failureType: 'uncaughtException' error: 'callback invoked multiple times' code: 'ERR_TEST_FAILURE' @@ -450,9 +447,10 @@ not ok 50 - callback called twice in future tick * ... # Subtest: callback async throw -not ok 51 - callback async throw +not ok 47 - callback async throw --- duration_ms: * + location: '/test/fixtures/test-runner/output/output.js:(LINE):1' failureType: 'uncaughtException' error: 'thrown from callback async throw' code: 'ERR_TEST_FAILURE' @@ -461,7 +459,7 @@ not ok 51 - callback async throw * ... # Subtest: callback async throw after done -ok 52 - callback async throw after done +ok 48 - callback async throw after done --- duration_ms: * ... @@ -489,23 +487,25 @@ ok 52 - callback async throw after done duration_ms: * ... 1..4 -ok 53 - only is set but not in only mode +ok 49 - only is set but not in only mode --- duration_ms: * ... # 'only' and 'runOnly' require the --test-only command-line option. # Subtest: custom inspect symbol fail -not ok 54 - custom inspect symbol fail +not ok 50 - custom inspect symbol fail --- duration_ms: * + location: '/test/fixtures/test-runner/output/output.js:(LINE):1' failureType: 'testCodeFailure' error: 'customized' code: 'ERR_TEST_FAILURE' ... # Subtest: custom inspect symbol that throws fail -not ok 55 - custom inspect symbol that throws fail +not ok 51 - custom inspect symbol that throws fail --- duration_ms: * + location: '/test/fixtures/test-runner/output/output.js:(LINE):1' failureType: 'testCodeFailure' error: |- { @@ -519,6 +519,7 @@ not ok 55 - custom inspect symbol that throws fail not ok 1 - sync throw fails at first --- duration_ms: * + location: '/test/fixtures/test-runner/output/output.js:(LINE):11' failureType: 'testCodeFailure' error: 'thrown from subtest sync throw fails at first' code: 'ERR_TEST_FAILURE' @@ -538,6 +539,7 @@ not ok 55 - custom inspect symbol that throws fail not ok 2 - sync throw fails at second --- duration_ms: * + location: '/test/fixtures/test-runner/output/output.js:(LINE):11' failureType: 'testCodeFailure' error: 'thrown from subtest sync throw fails at second' code: 'ERR_TEST_FAILURE' @@ -554,56 +556,61 @@ not ok 55 - custom inspect symbol that throws fail * ... 1..2 -not ok 56 - subtest sync throw fails +not ok 52 - subtest sync throw fails --- duration_ms: * + location: '/test/fixtures/test-runner/output/output.js:(LINE):1' failureType: 'subtestsFailed' error: '2 subtests failed' code: 'ERR_TEST_FAILURE' ... # Subtest: timed out async test -not ok 57 - timed out async test +not ok 53 - timed out async test --- duration_ms: * + location: '/test/fixtures/test-runner/output/output.js:(LINE):1' failureType: 'testTimeoutFailure' error: 'test timed out after 5ms' code: 'ERR_TEST_FAILURE' ... # Subtest: timed out callback test -not ok 58 - timed out callback test +not ok 54 - timed out callback test --- duration_ms: * + location: '/test/fixtures/test-runner/output/output.js:(LINE):1' failureType: 'testTimeoutFailure' error: 'test timed out after 5ms' code: 'ERR_TEST_FAILURE' ... # Subtest: large timeout async test is ok -ok 59 - large timeout async test is ok +ok 55 - large timeout async test is ok --- duration_ms: * ... # Subtest: large timeout callback test is ok -ok 60 - large timeout callback test is ok +ok 56 - large timeout callback test is ok --- duration_ms: * ... # Subtest: successful thenable -ok 61 - successful thenable +ok 57 - successful thenable --- duration_ms: * ... # Subtest: rejected thenable -not ok 62 - rejected thenable +not ok 58 - rejected thenable --- duration_ms: * + location: '/test/fixtures/test-runner/output/output.js:(LINE):1' failureType: 'testCodeFailure' error: 'custom error' code: 'ERR_TEST_FAILURE' ... # Subtest: unfinished test with uncaughtException -not ok 63 - unfinished test with uncaughtException +not ok 59 - unfinished test with uncaughtException --- duration_ms: * + location: '/test/fixtures/test-runner/output/output.js:(LINE):1' failureType: 'uncaughtException' error: 'foo' code: 'ERR_TEST_FAILURE' @@ -613,9 +620,10 @@ not ok 63 - unfinished test with uncaughtException * ... # Subtest: unfinished test with unhandledRejection -not ok 64 - unfinished test with unhandledRejection +not ok 60 - unfinished test with unhandledRejection --- duration_ms: * + location: '/test/fixtures/test-runner/output/output.js:(LINE):1' failureType: 'unhandledRejection' error: 'bar' code: 'ERR_TEST_FAILURE' @@ -625,9 +633,10 @@ not ok 64 - unfinished test with unhandledRejection * ... # Subtest: assertion errors display actual and expected properly -not ok 65 - assertion errors display actual and expected properly +not ok 61 - assertion errors display actual and expected properly --- duration_ms: * + location: '/test/fixtures/test-runner/output/output.js:(LINE):1' failureType: 'testCodeFailure' error: |- Expected values to be loosely deep-equal: @@ -656,16 +665,17 @@ not ok 65 - assertion errors display actual and expected properly * ... # Subtest: invalid subtest fail -not ok 66 - invalid subtest fail +not ok 62 - invalid subtest fail --- duration_ms: * + location: '/test/fixtures/test-runner/output/output.js:(LINE):7' failureType: 'parentAlreadyFinished' error: 'test could not be started because its parent finished' code: 'ERR_TEST_FAILURE' stack: |- * ... -1..66 +1..62 # Warning: Test "unhandled rejection - passes but warns" generated asynchronous activity after the test ended. This activity created the error "Error: rejected from unhandled rejection fail" and would have caused the test to fail, but instead triggered an unhandledRejection event. # Warning: Test "async unhandled rejection - passes but warns" generated asynchronous activity after the test ended. This activity created the error "Error: rejected from async unhandled rejection fail" and would have caused the test to fail, but instead triggered an unhandledRejection event. # Warning: A resource generated asynchronous activity after the test ended. This activity created the error "Error: uncaught from outside of a test" which triggered an uncaughtException event, caught by the test runner. @@ -673,11 +683,11 @@ not ok 66 - invalid subtest fail # Warning: Test "immediate reject - passes but warns" generated asynchronous activity after the test ended. This activity created the error "Error: rejected from immediate reject fail" and would have caused the test to fail, but instead triggered an unhandledRejection event. # Warning: Test "callback called twice in different ticks" generated asynchronous activity after the test ended. This activity created the error "Error [ERR_TEST_FAILURE]: callback invoked multiple times" and would have caused the test to fail, but instead triggered an uncaughtException event. # Warning: Test "callback async throw after done" generated asynchronous activity after the test ended. This activity created the error "Error: thrown from callback async throw after done" and would have caused the test to fail, but instead triggered an uncaughtException event. -# tests 80 +# tests 76 # suites 0 -# pass 37 +# pass 35 # fail 25 # cancelled 3 -# skipped 10 -# todo 5 +# skipped 9 +# todo 4 # duration_ms * diff --git a/test/fixtures/test-runner/output/output_cli.snapshot b/test/fixtures/test-runner/output/output_cli.snapshot index fe192625e1f8b6..3cef8f29b253b9 100644 --- a/test/fixtures/test-runner/output/output_cli.snapshot +++ b/test/fixtures/test-runner/output/output_cli.snapshot @@ -13,6 +13,7 @@ ok 2 - sync pass todo with message # TODO this is a passing todo not ok 3 - sync fail todo # TODO --- duration_ms: * + location: '/test/fixtures/test-runner/output/output.js:(LINE):1' failureType: 'testCodeFailure' error: 'thrown from sync fail todo' code: 'ERR_TEST_FAILURE' @@ -29,6 +30,7 @@ not ok 3 - sync fail todo # TODO not ok 4 - sync fail todo with message # TODO this is a failing todo --- duration_ms: * + location: '/test/fixtures/test-runner/output/output.js:(LINE):1' failureType: 'testCodeFailure' error: 'thrown from sync fail todo with message' code: 'ERR_TEST_FAILURE' @@ -61,6 +63,7 @@ ok 7 - sync pass not ok 8 - sync throw fail --- duration_ms: * + location: '/test/fixtures/test-runner/output/output.js:(LINE):1' failureType: 'testCodeFailure' error: 'thrown from sync throw fail' code: 'ERR_TEST_FAILURE' @@ -87,6 +90,7 @@ ok 10 - async pass not ok 11 - async throw fail --- duration_ms: * + location: '/test/fixtures/test-runner/output/output.js:(LINE):1' failureType: 'testCodeFailure' error: 'thrown from async throw fail' code: 'ERR_TEST_FAILURE' @@ -103,6 +107,7 @@ not ok 11 - async throw fail not ok 12 - async skip fail # SKIP --- duration_ms: * + location: '/test/fixtures/test-runner/output/output.js:(LINE):1' failureType: 'testCodeFailure' error: 'thrown from async throw fail' code: 'ERR_TEST_FAILURE' @@ -119,6 +124,7 @@ not ok 12 - async skip fail # SKIP not ok 13 - async assertion fail --- duration_ms: * + location: '/test/fixtures/test-runner/output/output.js:(LINE):1' failureType: 'testCodeFailure' error: |- Expected values to be strictly equal: @@ -148,6 +154,7 @@ ok 14 - resolve pass not ok 15 - reject fail --- duration_ms: * + location: '/test/fixtures/test-runner/output/output.js:(LINE):1' failureType: 'testCodeFailure' error: 'rejected from reject fail' code: 'ERR_TEST_FAILURE' @@ -190,6 +197,7 @@ ok 20 - immediate resolve pass not ok 1 - +sync throw fail --- duration_ms: * + location: '/test/fixtures/test-runner/output/output.js:(LINE):11' failureType: 'testCodeFailure' error: 'thrown from subtest sync throw fail' code: 'ERR_TEST_FAILURE' @@ -210,6 +218,7 @@ ok 20 - immediate resolve pass not ok 21 - subtest sync throw fail --- duration_ms: * + location: '/test/fixtures/test-runner/output/output.js:(LINE):1' failureType: 'subtestsFailed' error: '1 subtest failed' code: 'ERR_TEST_FAILURE' @@ -218,6 +227,7 @@ not ok 21 - subtest sync throw fail not ok 22 - sync throw non-error fail --- duration_ms: * + location: '/test/fixtures/test-runner/output/output.js:(LINE):1' failureType: 'testCodeFailure' error: 'Symbol(thrown symbol from sync throw non-error fail)' code: 'ERR_TEST_FAILURE' @@ -253,6 +263,7 @@ ok 23 - level 0a not ok 1 - +long running --- duration_ms: * + location: '/test/fixtures/test-runner/output/output.js:(LINE):5' failureType: 'cancelledByParent' error: 'test did not finish before its parent and was cancelled' code: 'ERR_TEST_FAILURE' @@ -272,6 +283,7 @@ ok 23 - level 0a not ok 24 - top level --- duration_ms: * + location: '/test/fixtures/test-runner/output/output.js:(LINE):1' failureType: 'subtestsFailed' error: '1 subtest failed' code: 'ERR_TEST_FAILURE' @@ -295,6 +307,7 @@ ok 27 - sync skip option with message # SKIP this is skipped not ok 28 - sync skip option is false fail --- duration_ms: * + location: '/test/fixtures/test-runner/output/output.js:(LINE):1' failureType: 'testCodeFailure' error: 'this should be executed' code: 'ERR_TEST_FAILURE' @@ -347,36 +360,16 @@ ok 36 - functionAndOptions # SKIP --- duration_ms: * ... -# Subtest: escaped description \\ \# \\\#\\ \\n \\t \\f \\v \\b \\r -ok 37 - escaped description \\ \# \\\#\\ \\n \\t \\f \\v \\b \\r - --- - duration_ms: * - ... -# Subtest: escaped skip message -ok 38 - escaped skip message # SKIP \#skip - --- - duration_ms: * - ... -# Subtest: escaped todo message -ok 39 - escaped todo message # TODO \#todo - --- - duration_ms: * - ... -# Subtest: escaped diagnostic -ok 40 - escaped diagnostic - --- - duration_ms: * - ... -# \#diagnostic # Subtest: callback pass -ok 41 - callback pass +ok 37 - callback pass --- duration_ms: * ... # Subtest: callback fail -not ok 42 - callback fail +not ok 38 - callback fail --- duration_ms: * + location: '/test/fixtures/test-runner/output/output.js:(LINE):1' failureType: 'testCodeFailure' error: 'callback failure' code: 'ERR_TEST_FAILURE' @@ -385,32 +378,34 @@ not ok 42 - callback fail * ... # Subtest: sync t is this in test -ok 43 - sync t is this in test +ok 39 - sync t is this in test --- duration_ms: * ... # Subtest: async t is this in test -ok 44 - async t is this in test +ok 40 - async t is this in test --- duration_ms: * ... # Subtest: callback t is this in test -ok 45 - callback t is this in test +ok 41 - callback t is this in test --- duration_ms: * ... # Subtest: callback also returns a Promise -not ok 46 - callback also returns a Promise +not ok 42 - callback also returns a Promise --- duration_ms: * + location: '/test/fixtures/test-runner/output/output.js:(LINE):1' failureType: 'callbackAndPromisePresent' error: 'passed a callback but also returned a Promise' code: 'ERR_TEST_FAILURE' ... # Subtest: callback throw -not ok 47 - callback throw +not ok 43 - callback throw --- duration_ms: * + location: '/test/fixtures/test-runner/output/output.js:(LINE):1' failureType: 'testCodeFailure' error: 'thrown from callback throw' code: 'ERR_TEST_FAILURE' @@ -424,9 +419,10 @@ not ok 47 - callback throw * ... # Subtest: callback called twice -not ok 48 - callback called twice +not ok 44 - callback called twice --- duration_ms: * + location: '/test/fixtures/test-runner/output/output.js:(LINE):1' failureType: 'multipleCallbackInvocations' error: 'callback invoked multiple times' code: 'ERR_TEST_FAILURE' @@ -435,14 +431,15 @@ not ok 48 - callback called twice * ... # Subtest: callback called twice in different ticks -ok 49 - callback called twice in different ticks +ok 45 - callback called twice in different ticks --- duration_ms: * ... # Subtest: callback called twice in future tick -not ok 50 - callback called twice in future tick +not ok 46 - callback called twice in future tick --- duration_ms: * + location: '/test/fixtures/test-runner/output/output.js:(LINE):1' failureType: 'uncaughtException' error: 'callback invoked multiple times' code: 'ERR_TEST_FAILURE' @@ -450,9 +447,10 @@ not ok 50 - callback called twice in future tick * ... # Subtest: callback async throw -not ok 51 - callback async throw +not ok 47 - callback async throw --- duration_ms: * + location: '/test/fixtures/test-runner/output/output.js:(LINE):1' failureType: 'uncaughtException' error: 'thrown from callback async throw' code: 'ERR_TEST_FAILURE' @@ -461,7 +459,7 @@ not ok 51 - callback async throw * ... # Subtest: callback async throw after done -ok 52 - callback async throw after done +ok 48 - callback async throw after done --- duration_ms: * ... @@ -489,23 +487,25 @@ ok 52 - callback async throw after done duration_ms: * ... 1..4 -ok 53 - only is set but not in only mode +ok 49 - only is set but not in only mode --- duration_ms: * ... # 'only' and 'runOnly' require the --test-only command-line option. # Subtest: custom inspect symbol fail -not ok 54 - custom inspect symbol fail +not ok 50 - custom inspect symbol fail --- duration_ms: * + location: '/test/fixtures/test-runner/output/output.js:(LINE):1' failureType: 'testCodeFailure' error: 'customized' code: 'ERR_TEST_FAILURE' ... # Subtest: custom inspect symbol that throws fail -not ok 55 - custom inspect symbol that throws fail +not ok 51 - custom inspect symbol that throws fail --- duration_ms: * + location: '/test/fixtures/test-runner/output/output.js:(LINE):1' failureType: 'testCodeFailure' error: |- { @@ -519,6 +519,7 @@ not ok 55 - custom inspect symbol that throws fail not ok 1 - sync throw fails at first --- duration_ms: * + location: '/test/fixtures/test-runner/output/output.js:(LINE):11' failureType: 'testCodeFailure' error: 'thrown from subtest sync throw fails at first' code: 'ERR_TEST_FAILURE' @@ -538,6 +539,7 @@ not ok 55 - custom inspect symbol that throws fail not ok 2 - sync throw fails at second --- duration_ms: * + location: '/test/fixtures/test-runner/output/output.js:(LINE):11' failureType: 'testCodeFailure' error: 'thrown from subtest sync throw fails at second' code: 'ERR_TEST_FAILURE' @@ -554,56 +556,61 @@ not ok 55 - custom inspect symbol that throws fail * ... 1..2 -not ok 56 - subtest sync throw fails +not ok 52 - subtest sync throw fails --- duration_ms: * + location: '/test/fixtures/test-runner/output/output.js:(LINE):1' failureType: 'subtestsFailed' error: '2 subtests failed' code: 'ERR_TEST_FAILURE' ... # Subtest: timed out async test -not ok 57 - timed out async test +not ok 53 - timed out async test --- duration_ms: * + location: '/test/fixtures/test-runner/output/output.js:(LINE):1' failureType: 'testTimeoutFailure' error: 'test timed out after 5ms' code: 'ERR_TEST_FAILURE' ... # Subtest: timed out callback test -not ok 58 - timed out callback test +not ok 54 - timed out callback test --- duration_ms: * + location: '/test/fixtures/test-runner/output/output.js:(LINE):1' failureType: 'testTimeoutFailure' error: 'test timed out after 5ms' code: 'ERR_TEST_FAILURE' ... # Subtest: large timeout async test is ok -ok 59 - large timeout async test is ok +ok 55 - large timeout async test is ok --- duration_ms: * ... # Subtest: large timeout callback test is ok -ok 60 - large timeout callback test is ok +ok 56 - large timeout callback test is ok --- duration_ms: * ... # Subtest: successful thenable -ok 61 - successful thenable +ok 57 - successful thenable --- duration_ms: * ... # Subtest: rejected thenable -not ok 62 - rejected thenable +not ok 58 - rejected thenable --- duration_ms: * + location: '/test/fixtures/test-runner/output/output.js:(LINE):1' failureType: 'testCodeFailure' error: 'custom error' code: 'ERR_TEST_FAILURE' ... # Subtest: unfinished test with uncaughtException -not ok 63 - unfinished test with uncaughtException +not ok 59 - unfinished test with uncaughtException --- duration_ms: * + location: '/test/fixtures/test-runner/output/output.js:(LINE):1' failureType: 'uncaughtException' error: 'foo' code: 'ERR_TEST_FAILURE' @@ -613,9 +620,10 @@ not ok 63 - unfinished test with uncaughtException * ... # Subtest: unfinished test with unhandledRejection -not ok 64 - unfinished test with unhandledRejection +not ok 60 - unfinished test with unhandledRejection --- duration_ms: * + location: '/test/fixtures/test-runner/output/output.js:(LINE):1' failureType: 'unhandledRejection' error: 'bar' code: 'ERR_TEST_FAILURE' @@ -625,9 +633,10 @@ not ok 64 - unfinished test with unhandledRejection * ... # Subtest: assertion errors display actual and expected properly -not ok 65 - assertion errors display actual and expected properly +not ok 61 - assertion errors display actual and expected properly --- duration_ms: * + location: '/test/fixtures/test-runner/output/output.js:(LINE):1' failureType: 'testCodeFailure' error: |- Expected values to be loosely deep-equal: @@ -656,9 +665,10 @@ not ok 65 - assertion errors display actual and expected properly * ... # Subtest: invalid subtest fail -not ok 66 - invalid subtest fail +not ok 62 - invalid subtest fail --- duration_ms: * + location: '/test/fixtures/test-runner/output/output.js:(LINE):7' failureType: 'parentAlreadyFinished' error: 'test could not be started because its parent finished' code: 'ERR_TEST_FAILURE' @@ -673,16 +683,16 @@ not ok 66 - invalid subtest fail # Warning: Test "callback called twice in different ticks" generated asynchronous activity after the test ended. This activity created the error "Error [ERR_TEST_FAILURE]: callback invoked multiple times" and would have caused the test to fail, but instead triggered an uncaughtException event. # Warning: Test "callback async throw after done" generated asynchronous activity after the test ended. This activity created the error "Error: thrown from callback async throw after done" and would have caused the test to fail, but instead triggered an uncaughtException event. # Subtest: last test -ok 67 - last test +ok 63 - last test --- duration_ms: * ... -1..67 -# tests 81 +1..63 +# tests 77 # suites 0 -# pass 38 +# pass 36 # fail 25 # cancelled 3 -# skipped 10 -# todo 5 +# skipped 9 +# todo 4 # duration_ms * diff --git a/test/fixtures/test-runner/output/spec_reporter.snapshot b/test/fixtures/test-runner/output/spec_reporter.snapshot index 13f3618d38c28d..5dc05d5b43c12d 100644 --- a/test/fixtures/test-runner/output/spec_reporter.snapshot +++ b/test/fixtures/test-runner/output/spec_reporter.snapshot @@ -149,12 +149,6 @@ (*ms) # SKIP test with a name and options provided (*ms) # SKIP functionAndOptions (*ms) # SKIP - escaped description \ # \#\ -  (*ms) - escaped skip message (*ms) # #skip - escaped todo message (*ms) # #todo - escaped diagnostic (*ms) - #diagnostic callback pass (*ms) callback fail (*ms) Error: callback failure @@ -296,17 +290,18 @@ Warning: Test "immediate reject - passes but warns" generated asynchronous activity after the test ended. This activity created the error "Error: rejected from immediate reject fail" and would have caused the test to fail, but instead triggered an unhandledRejection event. Warning: Test "callback called twice in different ticks" generated asynchronous activity after the test ended. This activity created the error "Error [ERR_TEST_FAILURE]: callback invoked multiple times" and would have caused the test to fail, but instead triggered an uncaughtException event. Warning: Test "callback async throw after done" generated asynchronous activity after the test ended. This activity created the error "Error: thrown from callback async throw after done" and would have caused the test to fail, but instead triggered an uncaughtException event. - tests 80 + tests 76 suites 0 - pass 37 + pass 35 fail 25 cancelled 3 - skipped 10 - todo 5 + skipped 9 + todo 4 duration_ms * failing tests: +* sync fail todo (*ms) # TODO Error: thrown from sync fail todo * @@ -317,6 +312,7 @@ * * +* sync fail todo with message (*ms) # this is a failing todo Error: thrown from sync fail todo with message * @@ -327,6 +323,7 @@ * * +* sync throw fail (*ms) Error: thrown from sync throw fail * @@ -337,6 +334,7 @@ * * +* async throw fail (*ms) Error: thrown from async throw fail * @@ -347,6 +345,7 @@ * * +* async skip fail (*ms) # SKIP Error: thrown from async throw fail * @@ -357,6 +356,7 @@ * * +* async assertion fail (*ms) AssertionError [ERR_ASSERTION]: Expected values to be strictly equal: @@ -376,6 +376,7 @@ operator: 'strictEqual' } +* reject fail (*ms) Error: rejected from reject fail * @@ -386,6 +387,7 @@ * * +* +sync throw fail (*ms) Error: thrown from subtest sync throw fail * @@ -399,12 +401,15 @@ * * +* sync throw non-error fail (*ms) Symbol(thrown symbol from sync throw non-error fail) +* +long running (*ms) 'test did not finish before its parent and was cancelled' +* sync skip option is false fail (*ms) Error: this should be executed * @@ -415,14 +420,17 @@ * * +* callback fail (*ms) Error: callback failure * * +* callback also returns a Promise (*ms) 'passed a callback but also returned a Promise' +* callback throw (*ms) Error: thrown from callback throw * @@ -433,9 +441,11 @@ * * +* callback called twice (*ms) 'callback invoked multiple times' +* callback called twice in future tick (*ms) Error [ERR_TEST_FAILURE]: callback invoked multiple times * { @@ -444,17 +454,21 @@ code: 'ERR_TEST_FAILURE' } +* callback async throw (*ms) Error: thrown from callback async throw * * +* custom inspect symbol fail (*ms) customized +* custom inspect symbol that throws fail (*ms) { foo: 1, [Symbol(nodejs.util.inspect.custom)]: [Function: [nodejs.util.inspect.custom]] } +* sync throw fails at first (*ms) Error: thrown from subtest sync throw fails at first * @@ -468,6 +482,7 @@ * * +* sync throw fails at second (*ms) Error: thrown from subtest sync throw fails at second * @@ -481,27 +496,33 @@ * * +* timed out async test (*ms) 'test timed out after *ms' +* timed out callback test (*ms) 'test timed out after *ms' +* rejected thenable (*ms) 'custom error' +* unfinished test with uncaughtException (*ms) Error: foo * * * +* unfinished test with unhandledRejection (*ms) Error: bar * * * +* assertion errors display actual and expected properly (*ms) AssertionError [ERR_ASSERTION]: Expected values to be loosely deep-equal: @@ -524,5 +545,6 @@ operator: 'deepEqual' } +* invalid subtest fail (*ms) 'test could not be started because its parent finished' diff --git a/test/fixtures/test-runner/output/spec_reporter_cli.snapshot b/test/fixtures/test-runner/output/spec_reporter_cli.snapshot index 22c9a9174574a1..25c22069c3b8e7 100644 --- a/test/fixtures/test-runner/output/spec_reporter_cli.snapshot +++ b/test/fixtures/test-runner/output/spec_reporter_cli.snapshot @@ -149,12 +149,6 @@ (*ms) # SKIP test with a name and options provided (*ms) # SKIP functionAndOptions (*ms) # SKIP - escaped description \ # \#\ -  (*ms) - escaped skip message (*ms) # #skip - escaped todo message (*ms) # #todo - escaped diagnostic (*ms) - #diagnostic callback pass (*ms) callback fail (*ms) Error: callback failure @@ -296,17 +290,18 @@ Warning: Test "immediate reject - passes but warns" generated asynchronous activity after the test ended. This activity created the error "Error: rejected from immediate reject fail" and would have caused the test to fail, but instead triggered an unhandledRejection event. Warning: Test "callback called twice in different ticks" generated asynchronous activity after the test ended. This activity created the error "Error [ERR_TEST_FAILURE]: callback invoked multiple times" and would have caused the test to fail, but instead triggered an uncaughtException event. Warning: Test "callback async throw after done" generated asynchronous activity after the test ended. This activity created the error "Error: thrown from callback async throw after done" and would have caused the test to fail, but instead triggered an uncaughtException event. - tests 80 + tests 76 suites 0 - pass 37 + pass 35 fail 25 cancelled 3 - skipped 10 - todo 5 + skipped 9 + todo 4 duration_ms * failing tests: +* sync fail todo (*ms) # TODO Error: thrown from sync fail todo * @@ -317,6 +312,7 @@ * * +* sync fail todo with message (*ms) # this is a failing todo Error: thrown from sync fail todo with message * @@ -327,6 +323,7 @@ * * +* sync throw fail (*ms) Error: thrown from sync throw fail * @@ -337,6 +334,7 @@ * * +* async throw fail (*ms) Error: thrown from async throw fail * @@ -347,6 +345,7 @@ * * +* async skip fail (*ms) # SKIP Error: thrown from async throw fail * @@ -357,6 +356,7 @@ * * +* async assertion fail (*ms) AssertionError [ERR_ASSERTION]: Expected values to be strictly equal: @@ -376,6 +376,7 @@ operator: 'strictEqual' } +* reject fail (*ms) Error: rejected from reject fail * @@ -386,6 +387,7 @@ * * +* +sync throw fail (*ms) Error: thrown from subtest sync throw fail * @@ -399,12 +401,15 @@ * * +* sync throw non-error fail (*ms) Symbol(thrown symbol from sync throw non-error fail) +* +long running (*ms) 'test did not finish before its parent and was cancelled' +* sync skip option is false fail (*ms) Error: this should be executed * @@ -415,14 +420,17 @@ * * +* callback fail (*ms) Error: callback failure * * +* callback also returns a Promise (*ms) 'passed a callback but also returned a Promise' +* callback throw (*ms) Error: thrown from callback throw * @@ -433,9 +441,11 @@ * * +* callback called twice (*ms) 'callback invoked multiple times' +* callback called twice in future tick (*ms) Error [ERR_TEST_FAILURE]: callback invoked multiple times * { @@ -444,17 +454,21 @@ code: 'ERR_TEST_FAILURE' } +* callback async throw (*ms) Error: thrown from callback async throw * * +* custom inspect symbol fail (*ms) customized +* custom inspect symbol that throws fail (*ms) { foo: 1 } +* sync throw fails at first (*ms) Error: thrown from subtest sync throw fails at first * @@ -468,6 +482,7 @@ * * +* sync throw fails at second (*ms) Error: thrown from subtest sync throw fails at second * @@ -481,27 +496,33 @@ * * +* timed out async test (*ms) 'test timed out after *ms' +* timed out callback test (*ms) 'test timed out after *ms' +* rejected thenable (*ms) 'custom error' +* unfinished test with uncaughtException (*ms) Error: foo * * * +* unfinished test with unhandledRejection (*ms) Error: bar * * * +* assertion errors display actual and expected properly (*ms) AssertionError [ERR_ASSERTION]: Expected values to be loosely deep-equal: @@ -524,5 +545,6 @@ operator: 'deepEqual' } +* invalid subtest fail (*ms) 'test could not be started because its parent finished' diff --git a/test/fixtures/test-runner/output/tap_escape.js b/test/fixtures/test-runner/output/tap_escape.js new file mode 100644 index 00000000000000..029ebea164e1ee --- /dev/null +++ b/test/fixtures/test-runner/output/tap_escape.js @@ -0,0 +1,19 @@ +'use strict'; +require('../../../common'); +const { test } = require('node:test'); + +// Do not include any failing tests in this file. + +// A test whose description needs to be escaped. +test('escaped description \\ # \\#\\ \n \t \f \v \b \r'); + +// A test whose skip message needs to be escaped. +test('escaped skip message', { skip: '#skip' }); + +// A test whose todo message needs to be escaped. +test('escaped todo message', { todo: '#todo' }); + +// A test with a diagnostic message that needs to be escaped. +test('escaped diagnostic', (t) => { + t.diagnostic('#diagnostic'); +}); diff --git a/test/fixtures/test-runner/output/tap_escape.snapshot b/test/fixtures/test-runner/output/tap_escape.snapshot new file mode 100644 index 00000000000000..722cd0ca427ec7 --- /dev/null +++ b/test/fixtures/test-runner/output/tap_escape.snapshot @@ -0,0 +1,31 @@ +TAP version 13 +# Subtest: escaped description \\ \# \\\#\\ \\n \\t \\f \\v \\b \\r +ok 1 - escaped description \\ \# \\\#\\ \\n \\t \\f \\v \\b \\r + --- + duration_ms: * + ... +# Subtest: escaped skip message +ok 2 - escaped skip message # SKIP \#skip + --- + duration_ms: * + ... +# Subtest: escaped todo message +ok 3 - escaped todo message # TODO \#todo + --- + duration_ms: * + ... +# Subtest: escaped diagnostic +ok 4 - escaped diagnostic + --- + duration_ms: * + ... +# \#diagnostic +1..4 +# tests 4 +# suites 0 +# pass 2 +# fail 0 +# cancelled 0 +# skipped 1 +# todo 1 +# duration_ms * diff --git a/test/fixtures/test-runner/output/timeout_in_before_each_should_not_affect_further_tests.snapshot b/test/fixtures/test-runner/output/timeout_in_before_each_should_not_affect_further_tests.snapshot index cac7facf893309..b3579da789470b 100644 --- a/test/fixtures/test-runner/output/timeout_in_before_each_should_not_affect_further_tests.snapshot +++ b/test/fixtures/test-runner/output/timeout_in_before_each_should_not_affect_further_tests.snapshot @@ -9,6 +9,7 @@ gonna timeout not ok 1 - first describe first test --- duration_ms: * + location: '/test/fixtures/test-runner/output/timeout_in_before_each_should_not_affect_further_tests.js:(LINE):3' failureType: 'hookFailed' error: 'failed running beforeEach hook' code: 'ERR_TEST_FAILURE' @@ -25,6 +26,7 @@ not ok 1 - before each timeout --- duration_ms: * type: 'suite' + location: '/test/fixtures/test-runner/output/timeout_in_before_each_should_not_affect_further_tests.js:(LINE):1' failureType: 'subtestsFailed' error: '1 subtest failed' code: 'ERR_TEST_FAILURE' @@ -36,6 +38,7 @@ not gonna timeout not ok 1 - second describe first test --- duration_ms: * + location: '/test/fixtures/test-runner/output/timeout_in_before_each_should_not_affect_further_tests.js:(LINE):3' failureType: 'hookFailed' error: 'failed running afterEach hook' code: 'ERR_TEST_FAILURE' @@ -52,6 +55,7 @@ not ok 2 - after each timeout --- duration_ms: * type: 'suite' + location: '/test/fixtures/test-runner/output/timeout_in_before_each_should_not_affect_further_tests.js:(LINE):1' failureType: 'subtestsFailed' error: '1 subtest failed' code: 'ERR_TEST_FAILURE' diff --git a/test/fixtures/test-runner/output/unresolved_promise.snapshot b/test/fixtures/test-runner/output/unresolved_promise.snapshot index 4b1593c3365798..839ec311a65e04 100644 --- a/test/fixtures/test-runner/output/unresolved_promise.snapshot +++ b/test/fixtures/test-runner/output/unresolved_promise.snapshot @@ -8,6 +8,7 @@ ok 1 - pass not ok 2 - never resolving promise --- duration_ms: * + location: '/test/fixtures/test-runner/output/unresolved_promise.js:(LINE):1' failureType: 'cancelledByParent' error: 'Promise resolution is still pending but the event loop has already resolved' code: 'ERR_TEST_FAILURE' @@ -18,6 +19,7 @@ not ok 2 - never resolving promise not ok 3 - fail --- duration_ms: ZERO + location: '/test/fixtures/test-runner/output/unresolved_promise.js:(LINE):1' failureType: 'cancelledByParent' error: 'Promise resolution is still pending but the event loop has already resolved' code: 'ERR_TEST_FAILURE' diff --git a/test/parallel/test-runner-output.mjs b/test/parallel/test-runner-output.mjs index 8d5233d2de2441..85d3131490a3db 100644 --- a/test/parallel/test-runner-output.mjs +++ b/test/parallel/test-runner-output.mjs @@ -29,23 +29,24 @@ function removeWindowsPathEscaping(str) { return common.isWindows ? str.replaceAll(/\\\\/g, '\\') : str; } +function replaceTestLocationLine(str) { + return str.replaceAll(/(js:)(\d+)(:\d+)/g, '$1(LINE)$3'); +} + const defaultTransform = snapshot.transform( snapshot.replaceWindowsLineEndings, snapshot.replaceStackTrace, + removeWindowsPathEscaping, + snapshot.replaceFullPaths, + snapshot.replaceWindowsPaths, replaceTestDuration, + replaceTestLocationLine, ); const specTransform = snapshot.transform( replaceSpecDuration, snapshot.replaceWindowsLineEndings, snapshot.replaceStackTrace, ); -const withFileNameTransform = snapshot.transform( - defaultTransform, - removeWindowsPathEscaping, - snapshot.replaceFullPaths, - snapshot.replaceWindowsPaths, -); - const tests = [ { name: 'test-runner/output/abort.js' }, @@ -58,7 +59,7 @@ const tests = [ { name: 'test-runner/output/hooks-with-no-global-test.js' }, { name: 'test-runner/output/before-and-after-each-too-many-listeners.js' }, { name: 'test-runner/output/before-and-after-each-with-timeout-too-many-listeners.js' }, - { name: 'test-runner/output/global_after_should_fail_the_test.js', transform: withFileNameTransform }, + { name: 'test-runner/output/global_after_should_fail_the_test.js' }, { name: 'test-runner/output/no_refs.js' }, { name: 'test-runner/output/no_tests.js' }, { name: 'test-runner/output/only_tests.js' }, @@ -78,6 +79,13 @@ const tests = [ transform: snapshot.transform(specTransform, replaceTestDuration), tty: true } : false, { name: 'test-runner/output/dot_output_custom_columns.js', transform: specTransform, tty: true }, + { + name: 'test-runner/output/tap_escape.js', + transform: snapshot.transform( + snapshot.replaceWindowsLineEndings, + replaceTestDuration, + ), + }, ] .filter(Boolean) .map(({ name, tty, transform }) => ({