mirror of
https://github.com/zebrajr/node.git
synced 2025-12-06 12:20:27 +01:00
test_runner: add level parameter to reporter.diagnostic
Added a parameter to allow severity-based formatting for diagnostic messages. Defaults to 'info'. This update enables better control over message presentation (e.g., coloring) based on severity levels such as 'info', 'warn', and 'error'. Refs: https://github.com/nodejs/node/issues/55922 PR-URL: https://github.com/nodejs/node/pull/57923 Reviewed-By: Pietro Marchini <pietro.marchini94@gmail.com> Reviewed-By: James M Snell <jasnell@gmail.com>
This commit is contained in:
parent
7c74205aa7
commit
38757c906d
|
|
@ -3016,6 +3016,11 @@ defined. The corresponding declaration ordered event is `'test:start'`.
|
||||||
`undefined` if the test was run through the REPL.
|
`undefined` if the test was run through the REPL.
|
||||||
* `message` {string} The diagnostic message.
|
* `message` {string} The diagnostic message.
|
||||||
* `nesting` {number} The nesting level of the test.
|
* `nesting` {number} The nesting level of the test.
|
||||||
|
* `level` {string} The severity level of the diagnostic message.
|
||||||
|
Possible values are:
|
||||||
|
* `'info'`: Informational messages.
|
||||||
|
* `'warn'`: Warnings.
|
||||||
|
* `'error'`: Errors.
|
||||||
|
|
||||||
Emitted when [`context.diagnostic`][] is called.
|
Emitted when [`context.diagnostic`][] is called.
|
||||||
This event is guaranteed to be emitted in the same order as the tests are
|
This event is guaranteed to be emitted in the same order as the tests are
|
||||||
|
|
|
||||||
|
|
@ -94,8 +94,10 @@ class SpecReporter extends Transform {
|
||||||
case 'test:stderr':
|
case 'test:stderr':
|
||||||
case 'test:stdout':
|
case 'test:stdout':
|
||||||
return data.message;
|
return data.message;
|
||||||
case 'test:diagnostic':
|
case 'test:diagnostic':{
|
||||||
return `${reporterColorMap[type]}${indent(data.nesting)}${reporterUnicodeSymbolMap[type]}${data.message}${colors.white}\n`;
|
const diagnosticColor = reporterColorMap[data.level] || reporterColorMap['test:diagnostic'];
|
||||||
|
return `${diagnosticColor}${indent(data.nesting)}${reporterUnicodeSymbolMap[type]}${data.message}${colors.white}\n`;
|
||||||
|
}
|
||||||
case 'test:coverage':
|
case 'test:coverage':
|
||||||
return getCoverageReport(indent(data.nesting), data.summary,
|
return getCoverageReport(indent(data.nesting), data.summary,
|
||||||
reporterUnicodeSymbolMap['test:coverage'], colors.blue, true);
|
reporterUnicodeSymbolMap['test:coverage'], colors.blue, true);
|
||||||
|
|
|
||||||
|
|
@ -37,6 +37,15 @@ const reporterColorMap = {
|
||||||
get 'test:diagnostic'() {
|
get 'test:diagnostic'() {
|
||||||
return colors.blue;
|
return colors.blue;
|
||||||
},
|
},
|
||||||
|
get 'info'() {
|
||||||
|
return colors.blue;
|
||||||
|
},
|
||||||
|
get 'warn'() {
|
||||||
|
return colors.yellow;
|
||||||
|
},
|
||||||
|
get 'error'() {
|
||||||
|
return colors.red;
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
function indent(nesting) {
|
function indent(nesting) {
|
||||||
|
|
|
||||||
|
|
@ -1235,7 +1235,7 @@ class Test extends AsyncResource {
|
||||||
if (actual < threshold) {
|
if (actual < threshold) {
|
||||||
harness.success = false;
|
harness.success = false;
|
||||||
process.exitCode = kGenericUserError;
|
process.exitCode = kGenericUserError;
|
||||||
reporter.diagnostic(nesting, loc, `Error: ${NumberPrototypeToFixed(actual, 2)}% ${name} coverage does not meet threshold of ${threshold}%.`);
|
reporter.diagnostic(nesting, loc, `Error: ${NumberPrototypeToFixed(actual, 2)}% ${name} coverage does not meet threshold of ${threshold}%.`, 'error');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -116,11 +116,12 @@ class TestsStream extends Readable {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
diagnostic(nesting, loc, message) {
|
diagnostic(nesting, loc, message, level = 'info') {
|
||||||
this[kEmitMessage]('test:diagnostic', {
|
this[kEmitMessage]('test:diagnostic', {
|
||||||
__proto__: null,
|
__proto__: null,
|
||||||
nesting,
|
nesting,
|
||||||
message,
|
message,
|
||||||
|
level,
|
||||||
...loc,
|
...loc,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -90,6 +90,26 @@ for (const coverage of coverages) {
|
||||||
assert(!findCoverageFileForPid(result.pid));
|
assert(!findCoverageFileForPid(result.pid));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test(`test failing ${coverage.flag} with red color`, () => {
|
||||||
|
const result = spawnSync(process.execPath, [
|
||||||
|
'--test',
|
||||||
|
'--experimental-test-coverage',
|
||||||
|
'--test-coverage-exclude=!test/**',
|
||||||
|
`${coverage.flag}=99`,
|
||||||
|
'--test-reporter', 'spec',
|
||||||
|
fixture,
|
||||||
|
], {
|
||||||
|
env: { ...process.env, FORCE_COLOR: '3' },
|
||||||
|
});
|
||||||
|
|
||||||
|
const stdout = result.stdout.toString();
|
||||||
|
// eslint-disable-next-line no-control-regex
|
||||||
|
const redColorRegex = /\u001b\[31mℹ Error: \d{2}\.\d{2}% \w+ coverage does not meet threshold of 99%/;
|
||||||
|
assert.match(stdout, redColorRegex, 'Expected red color code not found in diagnostic message');
|
||||||
|
assert.strictEqual(result.status, 1);
|
||||||
|
assert(!findCoverageFileForPid(result.pid));
|
||||||
|
});
|
||||||
|
|
||||||
test(`test failing ${coverage.flag}`, () => {
|
test(`test failing ${coverage.flag}`, () => {
|
||||||
const result = spawnSync(process.execPath, [
|
const result = spawnSync(process.execPath, [
|
||||||
'--test',
|
'--test',
|
||||||
|
|
|
||||||
|
|
@ -33,6 +33,24 @@ describe('require(\'node:test\').run', { concurrency: true }, () => {
|
||||||
for await (const _ of stream);
|
for await (const _ of stream);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should emit diagnostic events with level parameter', async () => {
|
||||||
|
const diagnosticEvents = [];
|
||||||
|
|
||||||
|
const stream = run({
|
||||||
|
files: [join(testFixtures, 'coverage.js')],
|
||||||
|
reporter: 'spec',
|
||||||
|
});
|
||||||
|
|
||||||
|
stream.on('test:diagnostic', (event) => {
|
||||||
|
diagnosticEvents.push(event);
|
||||||
|
});
|
||||||
|
// eslint-disable-next-line no-unused-vars
|
||||||
|
for await (const _ of stream);
|
||||||
|
assert(diagnosticEvents.length > 0, 'No diagnostic events were emitted');
|
||||||
|
const infoEvent = diagnosticEvents.find((e) => e.level === 'info');
|
||||||
|
assert(infoEvent, 'No diagnostic events with level "info" were emitted');
|
||||||
|
});
|
||||||
|
|
||||||
const argPrintingFile = join(testFixtures, 'print-arguments.js');
|
const argPrintingFile = join(testFixtures, 'print-arguments.js');
|
||||||
it('should allow custom arguments via execArgv', async () => {
|
it('should allow custom arguments via execArgv', async () => {
|
||||||
const result = await run({ files: [argPrintingFile], execArgv: ['-p', '"Printed"'] }).compose(spec).toArray();
|
const result = await run({ files: [argPrintingFile], execArgv: ['-p', '"Printed"'] }).compose(spec).toArray();
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user