diff --git a/lib/internal/test_runner/reporter/spec.js b/lib/internal/test_runner/reporter/spec.js index 0c5a3e95c7c75a..a6273466f51a8b 100644 --- a/lib/internal/test_runner/reporter/spec.js +++ b/lib/internal/test_runner/reporter/spec.js @@ -11,8 +11,8 @@ const { SafeMap, StringPrototypeRepeat, } = primordials; + const assert = require('assert'); -const Transform = require('internal/streams/transform'); const { inspectWithNoCustomRetry } = require('internal/errors'); const { green, blue, red, white, gray, shouldColorize } = require('internal/util/colors'); const { kSubtestsFailed } = require('internal/test_runner/test'); @@ -27,6 +27,7 @@ const colors = { 'test:pass': green, 'test:diagnostic': blue, }; + const symbols = { '__proto__': null, 'test:fail': '\u2716 ', @@ -36,27 +37,25 @@ const symbols = { 'arrow:right': '\u25B6 ', 'hyphen:minus': '\uFE63 ', }; -class SpecReporter extends Transform { - #stack = []; - #reported = []; - #indentMemo = new SafeMap(); - #failedTests = []; - #cwd = process.cwd(); - - constructor() { - super({ __proto__: null, writableObjectMode: true }); - } - #indent(nesting) { - let value = this.#indentMemo.get(nesting); +module.exports = async function* specReporter(source) { + let stack = []; + let reported = []; + let indentMemo = new SafeMap(); + let failedTests = []; + let cwd = process.cwd(); + + function indent(nesting) { + let value = indentMemo.get(nesting); if (value === undefined) { value = StringPrototypeRepeat(' ', nesting); - this.#indentMemo.set(nesting, value); + indentMemo.set(nesting, value); } return value; } - #formatError(error, indent) { + + function formatError(error, indent) { if (!error) return ''; const err = error.code === 'ERR_TEST_FAILURE' ? error.cause : error; const message = ArrayPrototypeJoin( @@ -66,7 +65,8 @@ class SpecReporter extends Transform { ), `\n${indent} `); return `\n${indent} ${message}\n`; } - #formatTestReport(type, data, prefix = '', indent = '', hasChildren = false) { + + function formatTestReport(type, data, prefix = '', indent = '', hasChildren = false) { let color = colors[type] ?? white; let symbol = symbols[type] ?? ' '; const { skip, todo } = data; @@ -89,7 +89,8 @@ class SpecReporter extends Transform { } return `${prefix}${indent}${color}${symbol}${title}${white}${error}`; } - #handleTestReportEvent(type, data) { + + function handleTestReportEvent(type, data) { const subtest = ArrayPrototypeShift(this.#stack); // This is the matching `test:start` event if (subtest) { assert(subtest.type === 'test:start'); @@ -113,7 +114,8 @@ class SpecReporter extends Transform { const indent = this.#indent(data.nesting); return `${this.#formatTestReport(type, data, prefix, indent, hasChildren)}\n`; } - #handleEvent({ type, data }) { + + function handleEvent({ type, data }) { switch (type) { case 'test:fail': if (data.details?.error?.failureType !== kSubtestsFailed) { @@ -134,25 +136,21 @@ class SpecReporter extends Transform { return getCoverageReport(this.#indent(data.nesting), data.summary, symbols['test:coverage'], blue, true); } } - _transform({ type, data }, encoding, callback) { - callback(null, this.#handleEvent({ __proto__: null, type, data })); + + for await (const event of source) { + yield handleEvent(event); } - _flush(callback) { - if (this.#failedTests.length === 0) { - callback(null, ''); - return; - } + + if (failedTests.length !== 0) { const results = [`\n${colors['test:fail']}${symbols['test:fail']}failing tests:${white}\n`]; - for (let i = 0; i < this.#failedTests.length; i++) { - const test = this.#failedTests[i]; - const relPath = relative(this.#cwd, test.file); - const formattedErr = this.#formatTestReport('test:fail', test); + for (let i = 0; i < failedTests.length; i++) { + const test = failedTests[i]; + const relPath = relative(cwd, test.file); + const formattedErr = formatTestReport('test:fail', test); const location = `test at ${relPath}:${test.line}:${test.column}`; ArrayPrototypePush(results, location, formattedErr); } - callback(null, ArrayPrototypeJoin(results, '\n')); + yield ArrayPrototypeJoin(results, '\n'); } -} - -module.exports = SpecReporter; +};