From efdc95fbc0b7bb149bc95062faf9524bd3c0f17c Mon Sep 17 00:00:00 2001 From: cjihrig Date: Sun, 30 Jul 2023 18:17:39 -0400 Subject: [PATCH] test_runner: expose location of tests This commit adds each test's line and column number to the reporter output. This will aid in debugging test suite failures when error stacks are not helpful, test suites are large, or tests have the same name. This data is also exposed on the spec reporter. This commit also replaces the filename that was previously being reported, with the filename where the test actually exists. These are normally correct, but could be wrong if tests were run from a file other than the user's entrypoint. PR-URL: https://github.com/nodejs/node/pull/48975 Backport-PR-URL: https://github.com/nodejs/node/pull/49225 Fixes: https://github.com/nodejs/node/issues/48457 Reviewed-By: Yagiz Nizipli Reviewed-By: Matteo Collina Reviewed-By: Chemi Atlow Reviewed-By: Moshe Atlow --- doc/api/test.md | 36 ++++++ lib/internal/test_runner/harness.js | 28 ++++- lib/internal/test_runner/reporter/spec.js | 12 +- lib/internal/test_runner/reporter/tap.js | 16 ++- lib/internal/test_runner/test.js | 110 +++++++++++------ lib/internal/test_runner/tests_stream.js | 94 ++++++++++---- src/node_util.cc | 23 ++++ .../test-runner/output/abort.snapshot | 14 +++ .../test-runner/output/abort_hooks.snapshot | 10 ++ .../test-runner/output/abort_suite.snapshot | 7 ++ .../output/default_output.snapshot | 3 + .../test-runner/output/describe_it.js | 9 -- .../test-runner/output/describe_it.snapshot | 102 ++++++++------- .../test-runner/output/dot_reporter.snapshot | 5 +- ...global_after_should_fail_the_test.snapshot | 1 + .../test-runner/output/hooks.snapshot | 30 +++++ .../test-runner/output/no_refs.snapshot | 2 + test/fixtures/test-runner/output/output.js | 14 --- .../test-runner/output/output.snapshot | 114 +++++++++-------- .../test-runner/output/output_cli.snapshot | 116 ++++++++++-------- .../test-runner/output/spec_reporter.snapshot | 42 +++++-- .../output/spec_reporter_cli.snapshot | 42 +++++-- .../fixtures/test-runner/output/tap_escape.js | 19 +++ .../test-runner/output/tap_escape.snapshot | 31 +++++ ...h_should_not_affect_further_tests.snapshot | 4 + .../output/unresolved_promise.snapshot | 2 + test/parallel/test-runner-output.mjs | 24 ++-- 27 files changed, 637 insertions(+), 273 deletions(-) create mode 100644 test/fixtures/test-runner/output/tap_escape.js create mode 100644 test/fixtures/test-runner/output/tap_escape.snapshot diff --git a/doc/api/test.md b/doc/api/test.md index 375cd41c949e8b..7da36a2080558b 100644 --- a/doc/api/test.md +++ b/doc/api/test.md @@ -2049,8 +2049,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. @@ -2059,8 +2063,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. @@ -2069,8 +2077,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. @@ -2079,6 +2091,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. @@ -2087,6 +2101,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. @@ -2098,12 +2114,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. @@ -2115,8 +2135,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. @@ -2125,8 +2149,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. @@ -2137,7 +2165,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`. @@ -2146,7 +2178,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 dc2c730fdf042c..e8cb28969621fb 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(); @@ -363,6 +383,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); @@ -450,6 +471,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 }) => ({