mirror of
https://github.com/nodejs/node.git
synced 2025-08-15 13:48:44 +02:00

PR-URL: https://github.com/nodejs/node/pull/52655 Reviewed-By: Matteo Collina <matteo.collina@gmail.com> Reviewed-By: Moshe Atlow <moshe@atlow.co.il> Reviewed-By: Chemi Atlow <chemi@atlow.co.il>
105 lines
3.6 KiB
JavaScript
105 lines
3.6 KiB
JavaScript
'use strict';
|
|
const {
|
|
ArrayPrototypeJoin,
|
|
ArrayPrototypePop,
|
|
ArrayPrototypePush,
|
|
ArrayPrototypeShift,
|
|
ArrayPrototypeUnshift,
|
|
} = primordials;
|
|
const assert = require('assert');
|
|
const Transform = require('internal/streams/transform');
|
|
const colors = require('internal/util/colors');
|
|
const { kSubtestsFailed } = require('internal/test_runner/test');
|
|
const { getCoverageReport } = require('internal/test_runner/utils');
|
|
const { relative } = require('path');
|
|
const {
|
|
formatTestReport,
|
|
indent,
|
|
reporterColorMap,
|
|
reporterUnicodeSymbolMap,
|
|
} = require('internal/test_runner/reporter/utils');
|
|
|
|
class SpecReporter extends Transform {
|
|
#stack = [];
|
|
#reported = [];
|
|
#failedTests = [];
|
|
#cwd = process.cwd();
|
|
|
|
constructor() {
|
|
super({ __proto__: null, writableObjectMode: true });
|
|
colors.refresh();
|
|
}
|
|
|
|
#handleTestReportEvent(type, data) {
|
|
const subtest = ArrayPrototypeShift(this.#stack); // This is the matching `test:start` event
|
|
if (subtest) {
|
|
assert(subtest.type === 'test:start');
|
|
assert(subtest.data.nesting === data.nesting);
|
|
assert(subtest.data.name === data.name);
|
|
}
|
|
let prefix = '';
|
|
while (this.#stack.length) {
|
|
// Report all the parent `test:start` events
|
|
const parent = ArrayPrototypePop(this.#stack);
|
|
assert(parent.type === 'test:start');
|
|
const msg = parent.data;
|
|
ArrayPrototypeUnshift(this.#reported, msg);
|
|
prefix += `${indent(msg.nesting)}${reporterUnicodeSymbolMap['arrow:right']}${msg.name}\n`;
|
|
}
|
|
let hasChildren = false;
|
|
if (this.#reported[0] && this.#reported[0].nesting === data.nesting && this.#reported[0].name === data.name) {
|
|
ArrayPrototypeShift(this.#reported);
|
|
hasChildren = true;
|
|
}
|
|
const indentation = indent(data.nesting);
|
|
return `${formatTestReport(type, data, prefix, indentation, hasChildren)}\n`;
|
|
}
|
|
#handleEvent({ type, data }) {
|
|
switch (type) {
|
|
case 'test:fail':
|
|
if (data.details?.error?.failureType !== kSubtestsFailed) {
|
|
ArrayPrototypePush(this.#failedTests, data);
|
|
}
|
|
return this.#handleTestReportEvent(type, data);
|
|
case 'test:pass':
|
|
return this.#handleTestReportEvent(type, data);
|
|
case 'test:start':
|
|
ArrayPrototypeUnshift(this.#stack, { __proto__: null, data, type });
|
|
break;
|
|
case 'test:stderr':
|
|
case 'test:stdout':
|
|
return data.message;
|
|
case 'test:diagnostic':
|
|
return `${reporterColorMap[type]}${indent(data.nesting)}${reporterUnicodeSymbolMap[type]}${data.message}${colors.white}\n`;
|
|
case 'test:coverage':
|
|
return getCoverageReport(indent(data.nesting), data.summary,
|
|
reporterUnicodeSymbolMap['test:coverage'], colors.blue, true);
|
|
}
|
|
}
|
|
_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'));
|
|
}
|
|
}
|
|
|
|
module.exports = SpecReporter;
|