From 79f4b426fe5e24e9e7a52c234b4e84690c7afee6 Mon Sep 17 00:00:00 2001 From: Moshe Atlow Date: Mon, 2 Jan 2023 23:22:54 +0200 Subject: [PATCH] test_runner: report `file` in test runner events PR-URL: https://github.com/nodejs/node/pull/46030 Backport-PR-URL: https://github.com/nodejs/node/pull/46839 Reviewed-By: Benjamin Gruenbaum Reviewed-By: Antoine du Hamel Reviewed-By: Colin Ihrig --- doc/api/test.md | 10 +++++++ lib/internal/test_runner/runner.js | 10 ++++--- lib/internal/test_runner/test.js | 29 ++++++++++--------- lib/internal/test_runner/tests_stream.js | 20 ++++++------- .../test-runner/custom_reporters/custom.js | 6 ++++ 5 files changed, 47 insertions(+), 28 deletions(-) diff --git a/doc/api/test.md b/doc/api/test.md index 464c73b292c8ec..d5978408510c34 100644 --- a/doc/api/test.md +++ b/doc/api/test.md @@ -1204,6 +1204,8 @@ object, streaming a series of events representing the execution of the tests. ### Event: `'test:diagnostic'` * `data` {Object} + * `file` {string|undefined} The path of the test file, + undefined if test is not ran through a file. * `message` {string} The diagnostic message. * `nesting` {number} The nesting level of the test. @@ -1215,6 +1217,8 @@ Emitted when [`context.diagnostic`][] is called. * `details` {Object} Additional execution metadata. * `duration` {number} The duration of the test in milliseconds. * `error` {Error} The error thrown by the test. + * `file` {string|undefined} The path of the test file, + undefined if test is not ran through a file. * `name` {string} The test name. * `nesting` {number} The nesting level of the test. * `testNumber` {number} The ordinal number of the test. @@ -1228,6 +1232,8 @@ Emitted when a test fails. * `data` {Object} * `details` {Object} Additional execution metadata. * `duration` {number} The duration of the test in milliseconds. + * `file` {string|undefined} The path of the test file, + undefined if test is not ran through a file. * `name` {string} The test name. * `nesting` {number} The nesting level of the test. * `testNumber` {number} The ordinal number of the test. @@ -1239,6 +1245,8 @@ Emitted when a test passes. ### Event: `'test:plan'` * `data` {Object} + * `file` {string|undefined} The path of the test file, + undefined if test is not ran through a file. * `nesting` {number} The nesting level of the test. * `count` {number} The number of subtests that have ran. @@ -1247,6 +1255,8 @@ Emitted when all subtests have completed for a given test. ### Event: `'test:start'` * `data` {Object} + * `file` {string|undefined} The path of the test file, + undefined if test is not ran through a file. * `name` {string} The test name. * `nesting` {number} The nesting level of the test. diff --git a/lib/internal/test_runner/runner.js b/lib/internal/test_runner/runner.js index 4659073bfb61b4..94d7242bb3a433 100644 --- a/lib/internal/test_runner/runner.js +++ b/lib/internal/test_runner/runner.js @@ -139,11 +139,11 @@ class FileTest extends Test { break; case TokenKind.TAP_PLAN: - this.reporter.plan(nesting, node.end - node.start + 1); + this.reporter.plan(nesting, this.name, node.end - node.start + 1); break; case TokenKind.TAP_SUBTEST_POINT: - this.reporter.start(nesting, node.name); + this.reporter.start(nesting, this.name, node.name); break; case TokenKind.TAP_TEST_POINT: @@ -163,6 +163,7 @@ class FileTest extends Test { if (pass) { this.reporter.ok( nesting, + this.name, node.id, node.description, YAMLToJs(node.diagnostics), @@ -171,6 +172,7 @@ class FileTest extends Test { } else { this.reporter.fail( nesting, + this.name, node.id, node.description, YAMLToJs(node.diagnostics), @@ -184,11 +186,11 @@ class FileTest extends Test { // Ignore file top level diagnostics break; } - this.reporter.diagnostic(nesting, node.comment); + this.reporter.diagnostic(nesting, this.name, node.comment); break; case TokenKind.UNKNOWN: - this.reporter.diagnostic(nesting, node.value); + this.reporter.diagnostic(nesting, this.name, node.value); break; } } diff --git a/lib/internal/test_runner/test.js b/lib/internal/test_runner/test.js index 14ddb96d1155be..984a9a416bba03 100644 --- a/lib/internal/test_runner/test.js +++ b/lib/internal/test_runner/test.js @@ -74,6 +74,7 @@ const testNamePatterns = testNamePatternFlag?.length > 0 ? (re) => convertStringToRegExp(re, '--test-name-pattern') ) : null; const kShouldAbort = Symbol('kShouldAbort'); +const kFilename = process.argv?.[1]; const kHookNames = ObjectSeal(['before', 'after', 'beforeEach', 'afterEach']); const kUnwrapErrors = new SafeSet() .add(kTestCodeFailure).add(kHookFailure) @@ -632,19 +633,19 @@ class Test extends AsyncResource { this.parent.processPendingSubtests(); } else if (!this.reported) { this.reported = true; - this.reporter.plan(this.nesting, this.subtests.length); + this.reporter.plan(this.nesting, kFilename, this.subtests.length); for (let i = 0; i < this.diagnostics.length; i++) { - this.reporter.diagnostic(this.nesting, this.diagnostics[i]); + this.reporter.diagnostic(this.nesting, kFilename, this.diagnostics[i]); } - this.reporter.diagnostic(this.nesting, `tests ${this.subtests.length}`); - this.reporter.diagnostic(this.nesting, `pass ${counters.passed}`); - this.reporter.diagnostic(this.nesting, `fail ${counters.failed}`); - this.reporter.diagnostic(this.nesting, `cancelled ${counters.cancelled}`); - this.reporter.diagnostic(this.nesting, `skipped ${counters.skipped}`); - this.reporter.diagnostic(this.nesting, `todo ${counters.todo}`); - this.reporter.diagnostic(this.nesting, `duration_ms ${this.#duration()}`); + this.reporter.diagnostic(this.nesting, kFilename, `tests ${this.subtests.length}`); + this.reporter.diagnostic(this.nesting, kFilename, `pass ${counters.passed}`); + this.reporter.diagnostic(this.nesting, kFilename, `fail ${counters.failed}`); + this.reporter.diagnostic(this.nesting, kFilename, `cancelled ${counters.cancelled}`); + this.reporter.diagnostic(this.nesting, kFilename, `skipped ${counters.skipped}`); + this.reporter.diagnostic(this.nesting, kFilename, `todo ${counters.todo}`); + this.reporter.diagnostic(this.nesting, kFilename, `duration_ms ${this.#duration()}`); this.reporter.push(null); } } @@ -680,7 +681,7 @@ class Test extends AsyncResource { report() { if (this.subtests.length > 0) { - this.reporter.plan(this.subtests[0].nesting, this.subtests.length); + this.reporter.plan(this.subtests[0].nesting, kFilename, this.subtests.length); } else { this.reportStarted(); } @@ -694,14 +695,14 @@ class Test extends AsyncResource { } if (this.passed) { - this.reporter.ok(this.nesting, this.testNumber, this.name, details, directive); + this.reporter.ok(this.nesting, kFilename, this.testNumber, this.name, details, directive); } else { details.error = this.error; - this.reporter.fail(this.nesting, this.testNumber, this.name, details, directive); + this.reporter.fail(this.nesting, kFilename, this.testNumber, this.name, details, directive); } for (let i = 0; i < this.diagnostics.length; i++) { - this.reporter.diagnostic(this.nesting, this.diagnostics[i]); + this.reporter.diagnostic(this.nesting, kFilename, this.diagnostics[i]); } } @@ -711,7 +712,7 @@ class Test extends AsyncResource { } this.#reportedSubtest = true; this.parent.reportStarted(); - this.reporter.start(this.nesting, this.name); + this.reporter.start(this.nesting, kFilename, this.name); } } diff --git a/lib/internal/test_runner/tests_stream.js b/lib/internal/test_runner/tests_stream.js index b016d316154807..2614cab16daf64 100644 --- a/lib/internal/test_runner/tests_stream.js +++ b/lib/internal/test_runner/tests_stream.js @@ -27,16 +27,16 @@ class TestsStream extends Readable { } } - fail(nesting, testNumber, name, details, directive) { - this.#emit('test:fail', { __proto__: null, name, nesting, testNumber, details, ...directive }); + fail(nesting, file, testNumber, name, details, directive) { + this.#emit('test:fail', { __proto__: null, name, nesting, file, testNumber, details, ...directive }); } - ok(nesting, testNumber, name, details, directive) { - this.#emit('test:pass', { __proto__: null, name, nesting, testNumber, details, ...directive }); + ok(nesting, file, testNumber, name, details, directive) { + this.#emit('test:pass', { __proto__: null, name, nesting, file, testNumber, details, ...directive }); } - plan(nesting, count) { - this.#emit('test:plan', { __proto__: null, nesting, count }); + plan(nesting, file, count) { + this.#emit('test:plan', { __proto__: null, nesting, file, count }); } getSkip(reason = undefined) { @@ -47,12 +47,12 @@ class TestsStream extends Readable { return { __proto__: null, todo: reason ?? true }; } - start(nesting, name) { - this.#emit('test:start', { __proto__: null, nesting, name }); + start(nesting, file, name) { + this.#emit('test:start', { __proto__: null, nesting, file, name }); } - diagnostic(nesting, message) { - this.#emit('test:diagnostic', { __proto__: null, nesting, message }); + diagnostic(nesting, file, message) { + this.#emit('test:diagnostic', { __proto__: null, nesting, file, message }); } #emit(type, data) { diff --git a/test/fixtures/test-runner/custom_reporters/custom.js b/test/fixtures/test-runner/custom_reporters/custom.js index 62690f115b7ae1..aa85eab14acff4 100644 --- a/test/fixtures/test-runner/custom_reporters/custom.js +++ b/test/fixtures/test-runner/custom_reporters/custom.js @@ -1,6 +1,12 @@ +const assert = require('assert'); +const path = require('path'); + module.exports = async function * customReporter(source) { const counters = {}; for await (const event of source) { + if (event.data.file) { + assert.strictEqual(event.data.file, path.resolve(__dirname, '../reporters.js')); + } counters[event.type] = (counters[event.type] ?? 0) + 1; } yield "custom.js ";