Skip to content

Commit

Permalink
test_runner: print formatted errors on summary
Browse files Browse the repository at this point in the history
  • Loading branch information
pmarchini committed Feb 4, 2025
1 parent 2bd5694 commit 72e82e9
Show file tree
Hide file tree
Showing 4 changed files with 112 additions and 19 deletions.
51 changes: 32 additions & 19 deletions lib/internal/test_runner/reporter/spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,32 @@ class SpecReporter extends Transform {
colors.refresh();
}

#formatFailedTestResults() {
if (this.#failedTests.length === 0) {
return '';
}

const results = [
`\n${reporterColorMap['test:fail']}${reporterUnicodeSymbolMap['test:fail']}failing tests:${colors.white}\n`,
];

for (let i = 0; i < this.#failedTests.length; i++) {
const test = this.#failedTests[i];
const formattedErr = formatTestReport('test:fail', test);

if (test.file) {
const relPath = relative(this.#cwd, test.file);
const location = `test at ${relPath}:${test.line}:${test.column}`;
ArrayPrototypePush(results, location);
}

ArrayPrototypePush(results, formattedErr);
}

const output = ArrayPrototypeJoin(results, '\n');
this.#failedTests = []; // Clean up the failed tests
return output;
}
#handleTestReportEvent(type, data) {
const subtest = ArrayPrototypeShift(this.#stack); // This is the matching `test:start` event
if (subtest) {
Expand Down Expand Up @@ -74,31 +100,18 @@ class SpecReporter extends Transform {
case 'test:coverage':
return getCoverageReport(indent(data.nesting), data.summary,
reporterUnicodeSymbolMap['test:coverage'], colors.blue, true);
case 'test:summary':
// We report only the root test summary
if (data.file === undefined){

Check failure on line 105 in lib/internal/test_runner/reporter/spec.js

View workflow job for this annotation

GitHub Actions / lint-js-and-md

Missing space before opening brace
return this.#formatFailedTestResults();
}
}
}
_transform({ type, data }, encoding, callback) {
callback(null, this.#handleEvent({ __proto__: null, type, data }));
}
_flush(callback) {
if (this.#failedTests.length === 0) {
callback(null, '');
return;
}
const results = [`\n${reporterColorMap['test:fail']}${reporterUnicodeSymbolMap['test:fail']}failing tests:${colors.white}\n`];
for (let i = 0; i < this.#failedTests.length; i++) {
const test = this.#failedTests[i];
const formattedErr = formatTestReport('test:fail', test);

if (test.file) {
const relPath = relative(this.#cwd, test.file);
const location = `test at ${relPath}:${test.line}:${test.column}`;

ArrayPrototypePush(results, location);
}

ArrayPrototypePush(results, formattedErr);
}
callback(null, ArrayPrototypeJoin(results, '\n'));
callback(null, this.#formatFailedTestResults());
}
}

Expand Down
46 changes: 46 additions & 0 deletions test/fixtures/test-runner/output/test-runner-watch-spec.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import { run } from 'node:test';
import { spec } from 'node:test/reporters';
import tmpdir from '../../../common/tmpdir.js';
import { writeFileSync } from 'node:fs';


const fixtureContent = {
'dependency.js': 'module.exports = {};',
'dependency.mjs': 'export const a = 1;',
'test.js': `
const test = require('node:test');
require('./dependency.js');
import('./dependency.mjs');
import('data:text/javascript,');
test('test has ran');`,
'failing-test.js': `
const test = require('node:test');
test('failing test', () => {
throw new Error('failed');
});`,
};

tmpdir.refresh();

const fixturePaths = Object.keys(fixtureContent)
.reduce((acc, file) => ({ ...acc, [file]: tmpdir.resolve(file) }), {});
Object.entries(fixtureContent)
.forEach(([file, content]) => writeFileSync(fixturePaths[file], content));

const controller = new AbortController();
const { signal } = controller;

const stream = run({
watch: true,
cwd: tmpdir.path,
signal,
});


stream.compose(spec).pipe(process.stdout);

for await (const event of stream) {
if (event.type === 'test:watch:drained') {
controller.abort();
}
}
30 changes: 30 additions & 0 deletions test/fixtures/test-runner/output/test-runner-watch-spec.snapshot
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
✖ failing test (*ms)
✔ test has ran (*ms)
ℹ tests 2
ℹ suites 0
ℹ pass 1
ℹ fail 1
ℹ cancelled 0
ℹ skipped 0
ℹ todo 0
ℹ duration_ms *

✖ failing tests:

*
✖ failing test (*ms)
Error: failed
*
*
*
*
*
*
ℹ tests 0
ℹ suites 0
ℹ pass 0
ℹ fail 0
ℹ cancelled 0
ℹ skipped 0
ℹ todo 0
ℹ duration_ms *
4 changes: 4 additions & 0 deletions test/parallel/test-runner-output.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -235,6 +235,10 @@ const tests = [
name: 'test-runner/output/test-runner-plan.js',
flags: ['--test-reporter=tap'],
},
{
name: 'test-runner/output/test-runner-watch-spec.mjs',
transform: specTransform,
},
process.features.inspector ? {
name: 'test-runner/output/coverage_failure.js',
flags: ['--test-reporter=tap', '--test-coverage-exclude=!test/**'],
Expand Down

0 comments on commit 72e82e9

Please sign in to comment.