From a47cacdaaa8d6654d150ccd27b4b4010b7cfad2a Mon Sep 17 00:00:00 2001 From: Moshe Atlow Date: Mon, 2 Jan 2023 23:22:54 +0200 Subject: [PATCH] feat: report `file` in test runner events PR-URL: https://github.com/nodejs/node/pull/46030 Reviewed-By: Benjamin Gruenbaum Reviewed-By: Antoine du Hamel Reviewed-By: Colin Ihrig (cherry picked from commit 9eb363a3e00dbba572756c7ed314273f17ea8e2e) --- README.md | 10 ++++++ lib/internal/test_runner/runner.js | 12 ++++--- lib/internal/test_runner/test.js | 31 ++++++++++--------- lib/internal/test_runner/tests_stream.js | 22 ++++++------- .../test-runner/custom_reporters/custom.js | 7 ++++- 5 files changed, 50 insertions(+), 32 deletions(-) diff --git a/README.md b/README.md index 6c93b27..28dceaf 100644 --- a/README.md +++ b/README.md @@ -1128,6 +1128,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. @@ -1139,6 +1141,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. @@ -1152,6 +1156,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. @@ -1163,6 +1169,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. @@ -1171,6 +1179,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 2f22949..ef846a9 100644 --- a/lib/internal/test_runner/runner.js +++ b/lib/internal/test_runner/runner.js @@ -1,4 +1,4 @@ -// https://github.com/nodejs/node/blob/a1b27b25bb01aadd3fd2714e4b136db11b7eb85a/lib/internal/test_runner/runner.js +// https://github.com/nodejs/node/blob/9eb363a3e00dbba572756c7ed314273f17ea8e2e/lib/internal/test_runner/runner.js 'use strict' const { ArrayFrom, @@ -133,11 +133,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: @@ -157,6 +157,7 @@ class FileTest extends Test { if (pass) { this.reporter.ok( nesting, + this.name, node.id, node.description, YAMLToJs(node.diagnostics), @@ -165,6 +166,7 @@ class FileTest extends Test { } else { this.reporter.fail( nesting, + this.name, node.id, node.description, YAMLToJs(node.diagnostics), @@ -178,11 +180,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 f1d15ad..784a9c2 100644 --- a/lib/internal/test_runner/test.js +++ b/lib/internal/test_runner/test.js @@ -1,4 +1,4 @@ -// https://github.com/nodejs/node/blob/a1b27b25bb01aadd3fd2714e4b136db11b7eb85a/lib/internal/test_runner/test.js +// https://github.com/nodejs/node/blob/9eb363a3e00dbba572756c7ed314273f17ea8e2e/lib/internal/test_runner/test.js 'use strict' @@ -79,6 +79,7 @@ const testNamePatterns = testNamePatternFlag?.length > 0 ) : 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) @@ -622,19 +623,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) } } @@ -670,7 +671,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() } @@ -684,14 +685,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]) } } @@ -701,7 +702,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 c2cfb62..b8b5b09 100644 --- a/lib/internal/test_runner/tests_stream.js +++ b/lib/internal/test_runner/tests_stream.js @@ -1,4 +1,4 @@ -// https://github.com/nodejs/node/blob/a1b27b25bb01aadd3fd2714e4b136db11b7eb85a/lib/internal/test_runner/tests_stream.js +// https://github.com/nodejs/node/blob/9eb363a3e00dbba572756c7ed314273f17ea8e2e/lib/internal/test_runner/tests_stream.js 'use strict' const { ArrayPrototypePush, @@ -28,16 +28,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) { @@ -48,12 +48,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 a84c4b8..bdde0d2 100644 --- a/test/fixtures/test-runner/custom_reporters/custom.js +++ b/test/fixtures/test-runner/custom_reporters/custom.js @@ -1,7 +1,12 @@ -// https://github.com/nodejs/node/blob/a1b27b25bb01aadd3fd2714e4b136db11b7eb85a/test/fixtures/test-runner/custom_reporters/custom.js +// https://github.com/nodejs/node/blob/9eb363a3e00dbba572756c7ed314273f17ea8e2e/test/fixtures/test-runner/custom_reporters/custom.js +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 '