Upload Kmake

This commit is contained in:
Gorochu
2026-05-26 23:36:42 -07:00
parent ba051b2f74
commit 555ec72358
41615 changed files with 13344630 additions and 1 deletions

View File

@ -0,0 +1,40 @@
'use strict';
const {
ArrayPrototypePush,
MathMax,
} = primordials;
const colors = require('internal/util/colors');
const { formatTestReport } = require('internal/test_runner/reporter/utils');
module.exports = async function* dot(source) {
let count = 0;
let columns = getLineLength();
const failedTests = [];
for await (const { type, data } of source) {
if (type === 'test:pass') {
yield `${colors.green}.${colors.reset}`;
}
if (type === 'test:fail') {
yield `${colors.red}X${colors.reset}`;
ArrayPrototypePush(failedTests, data);
}
if ((type === 'test:fail' || type === 'test:pass') && ++count === columns) {
yield '\n';
// Getting again in case the terminal was resized.
columns = getLineLength();
count = 0;
}
}
yield '\n';
if (failedTests.length > 0) {
yield `\n${colors.red}Failed tests:${colors.white}\n\n`;
for (const test of failedTests) {
yield formatTestReport('test:fail', test);
}
}
};
function getLineLength() {
return MathMax(process.stdout.columns ?? 20, 20);
}

View File

@ -0,0 +1,160 @@
'use strict';
const {
ArrayPrototypeFilter,
ArrayPrototypeJoin,
ArrayPrototypeMap,
ArrayPrototypePush,
ArrayPrototypeSome,
NumberPrototypeToFixed,
ObjectEntries,
RegExpPrototypeSymbolReplace,
String,
StringPrototypeRepeat,
} = primordials;
const { inspectWithNoCustomRetry } = require('internal/errors');
const { hostname } = require('os');
const inspectOptions = { __proto__: null, colors: false, breakLength: Infinity };
const HOSTNAME = hostname();
function escapeAttribute(s = '') {
return escapeContent(RegExpPrototypeSymbolReplace(/"/g, RegExpPrototypeSymbolReplace(/\n/g, s, ''), '"'));
}
function escapeContent(s = '') {
return RegExpPrototypeSymbolReplace(/</g, RegExpPrototypeSymbolReplace(/&/g, s, '&amp;'), '&lt;');
}
function escapeComment(s = '') {
return RegExpPrototypeSymbolReplace(/--/g, s, '&#45;&#45;');
}
function treeToXML(tree) {
if (typeof tree === 'string') {
return `${escapeContent(tree)}\n`;
}
const {
tag, attrs, nesting, children, comment,
} = tree;
const indent = StringPrototypeRepeat('\t', nesting + 1);
if (comment) {
return `${indent}<!-- ${escapeComment(comment)} -->\n`;
}
const attrsString = ArrayPrototypeJoin(
ArrayPrototypeMap(
ObjectEntries(attrs),
({ 0: key, 1: value }) => `${key}="${escapeAttribute(String(value))}"`),
' ');
if (!children?.length) {
return `${indent}<${tag} ${attrsString}/>\n`;
}
const childrenString = ArrayPrototypeJoin(ArrayPrototypeMap(children ?? [], treeToXML), '');
return `${indent}<${tag} ${attrsString}>\n${childrenString}${indent}</${tag}>\n`;
}
function isFailure(node) {
return (node?.children && ArrayPrototypeSome(node.children, (c) => c.tag === 'failure')) || node?.attrs?.failures;
}
function isSkipped(node) {
return (node?.children && ArrayPrototypeSome(node.children, (c) => c.tag === 'skipped')) || node?.attrs?.failures;
}
module.exports = async function* junitReporter(source) {
yield '<?xml version="1.0" encoding="utf-8"?>\n';
yield '<testsuites>\n';
let currentSuite = null;
const roots = [];
function startTest(event) {
const originalSuite = currentSuite;
currentSuite = {
__proto__: null,
attrs: { __proto__: null, name: event.data.name },
nesting: event.data.nesting,
parent: currentSuite,
children: [],
};
if (originalSuite?.children) {
ArrayPrototypePush(originalSuite.children, currentSuite);
}
if (!currentSuite.parent) {
ArrayPrototypePush(roots, currentSuite);
}
}
for await (const event of source) {
switch (event.type) {
case 'test:start': {
startTest(event);
break;
}
case 'test:pass':
case 'test:fail': {
if (!currentSuite) {
startTest({ __proto__: null, data: { __proto__: null, name: 'root', nesting: 0 } });
}
if (currentSuite.attrs.name !== event.data.name ||
currentSuite.nesting !== event.data.nesting) {
startTest(event);
}
const currentTest = currentSuite;
if (currentSuite?.nesting === event.data.nesting) {
currentSuite = currentSuite.parent;
}
currentTest.attrs.time = NumberPrototypeToFixed(event.data.details.duration_ms / 1000, 6);
const nonCommentChildren = ArrayPrototypeFilter(currentTest.children, (c) => c.comment == null);
if (nonCommentChildren.length > 0) {
currentTest.tag = 'testsuite';
currentTest.attrs.disabled = 0;
currentTest.attrs.errors = 0;
currentTest.attrs.tests = nonCommentChildren.length;
currentTest.attrs.failures = ArrayPrototypeFilter(currentTest.children, isFailure).length;
currentTest.attrs.skipped = ArrayPrototypeFilter(currentTest.children, isSkipped).length;
currentTest.attrs.hostname = HOSTNAME;
} else {
currentTest.tag = 'testcase';
currentTest.attrs.classname = event.data.classname ?? 'test';
if (event.data.skip) {
ArrayPrototypePush(currentTest.children, {
__proto__: null, nesting: event.data.nesting + 1, tag: 'skipped',
attrs: { __proto__: null, type: 'skipped', message: event.data.skip },
});
}
if (event.data.todo) {
ArrayPrototypePush(currentTest.children, {
__proto__: null, nesting: event.data.nesting + 1, tag: 'skipped',
attrs: { __proto__: null, type: 'todo', message: event.data.todo },
});
}
if (event.type === 'test:fail') {
const error = event.data.details?.error;
currentTest.children.push({
__proto__: null,
nesting: event.data.nesting + 1,
tag: 'failure',
attrs: { __proto__: null, type: error?.failureType || error?.code, message: error?.message ?? '' },
children: [inspectWithNoCustomRetry(error, inspectOptions)],
});
currentTest.failures = 1;
currentTest.attrs.failure = error?.message ?? '';
}
}
break;
}
case 'test:diagnostic': {
const parent = currentSuite?.children ?? roots;
ArrayPrototypePush(parent, {
__proto__: null, nesting: event.data.nesting, comment: event.data.message,
});
break;
} default:
break;
}
}
for (const suite of roots) {
yield treeToXML(suite);
}
yield '</testsuites>\n';
};

View File

@ -0,0 +1,107 @@
'use strict';
const { relative } = require('path');
const Transform = require('internal/streams/transform');
// This reporter is based on the LCOV format, as described here:
// https://ltp.sourceforge.net/coverage/lcov/geninfo.1.php
// Excerpts from this documentation are included in the comments that make up
// the _transform function below.
class LcovReporter extends Transform {
constructor(options) {
super({ ...options, writableObjectMode: true, __proto__: null });
}
_transform(event, _encoding, callback) {
if (event.type !== 'test:coverage') {
return callback(null);
}
let lcov = '';
// A tracefile is made up of several human-readable lines of text, divided
// into sections. If available, a tracefile begins with the testname which
// is stored in the following format:
// ## TN:\<test name\>
lcov += 'TN:\n';
const {
data: {
summary: { workingDirectory },
},
} = event;
try {
for (let i = 0; i < event.data.summary.files.length; i++) {
const file = event.data.summary.files[i];
// For each source file referenced in the .da file, there is a section
// containing filename and coverage data:
// ## SF:\<path to the source file\>
lcov += `SF:${relative(workingDirectory, file.path)}\n`;
// Following is a list of line numbers for each function name found in
// the source file:
// ## FN:\<line number of function start\>,\<function name\>
//
// After, there is a list of execution counts for each instrumented
// function:
// ## FNDA:\<execution count\>,\<function name\>
//
// This loop adds the FN lines to the lcov variable as it goes and
// gathers the FNDA lines to be added later. This way we only loop
// through the list of functions once.
let fnda = '';
for (let j = 0; j < file.functions.length; j++) {
const func = file.functions[j];
const name = func.name || `anonymous_${j}`;
lcov += `FN:${func.line},${name}\n`;
fnda += `FNDA:${func.count},${name}\n`;
}
lcov += fnda;
// This list is followed by two lines containing the number of
// functions found and hit:
// ## FNF:\<number of functions found\>
// ## FNH:\<number of function hit\>
lcov += `FNF:${file.totalFunctionCount}\n`;
lcov += `FNH:${file.coveredFunctionCount}\n`;
// Branch coverage information is stored which one line per branch:
// ## BRDA:\<line number\>,\<block number\>,\<branch number\>,\<taken\>
// Block number and branch number are gcc internal IDs for the branch.
// Taken is either '-' if the basic block containing the branch was
// never executed or a number indicating how often that branch was
// taken.
for (let j = 0; j < file.branches.length; j++) {
lcov += `BRDA:${file.branches[j].line},${j},0,${file.branches[j].count}\n`;
}
// Branch coverage summaries are stored in two lines:
// ## BRF:\<number of branches found\>
// ## BRH:\<number of branches hit\>
lcov += `BRF:${file.totalBranchCount}\n`;
lcov += `BRH:${file.coveredBranchCount}\n`;
// Then there is a list of execution counts for each instrumented line
// (i.e. a line which resulted in executable code):
// ## DA:\<line number\>,\<execution count\>[,\<checksum\>]
const sortedLines = file.lines.toSorted((a, b) => a.line - b.line);
for (let j = 0; j < sortedLines.length; j++) {
lcov += `DA:${sortedLines[j].line},${sortedLines[j].count}\n`;
}
// At the end of a section, there is a summary about how many lines
// were found and how many were actually instrumented:
// ## LH:\<number of lines with a non-zero execution count\>
// ## LF:\<number of instrumented lines\>
lcov += `LH:${file.coveredLineCount}\n`;
lcov += `LF:${file.totalLineCount}\n`;
// Each sections ends with:
// end_of_record
lcov += 'end_of_record\n';
}
} catch (error) {
return callback(error);
}
return callback(null, lcov);
}
}
module.exports = LcovReporter;

View File

@ -0,0 +1,119 @@
'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();
}
#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);
}
this.#failedTests = []; // Clean up the failed tests
return ArrayPrototypeJoin(results, '\n'); ;
}
#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, false)}\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':{
const diagnosticColor = reporterColorMap[data.level] || reporterColorMap['test:diagnostic'];
return `${diagnosticColor}${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);
case 'test:summary':
// We report only the root test summary
if (data.file === undefined) {
return this.#formatFailedTestResults();
}
}
}
_transform({ type, data }, encoding, callback) {
callback(null, this.#handleEvent({ __proto__: null, type, data }));
}
_flush(callback) {
callback(null, this.#formatFailedTestResults());
}
}
module.exports = SpecReporter;

View File

@ -0,0 +1,281 @@
'use strict';
const {
ArrayPrototypeForEach,
ArrayPrototypeJoin,
ArrayPrototypePush,
DatePrototypeToISOString,
ObjectEntries,
RegExpPrototypeSymbolReplace,
RegExpPrototypeSymbolSplit,
SafeMap,
SafeSet,
StringPrototypeRepeat,
StringPrototypeReplaceAll,
} = primordials;
const { inspectWithNoCustomRetry } = require('internal/errors');
const { isError, kEmptyObject } = require('internal/util');
const { getCoverageReport } = require('internal/test_runner/utils');
const kDefaultIndent = ' '; // 4 spaces
const kFrameStartRegExp = /^ {4}at /;
const kLineBreakRegExp = /\n|\r\n/;
const kDefaultTAPVersion = 13;
const inspectOptions = { __proto__: null, colors: false, breakLength: Infinity };
let testModule; // Lazy loaded due to circular dependency.
function lazyLoadTest() {
testModule ??= require('internal/test_runner/test');
return testModule;
}
async function * tapReporter(source) {
yield `TAP version ${kDefaultTAPVersion}\n`;
for await (const { type, data } of source) {
switch (type) {
case 'test:fail': {
yield reportTest(data.nesting, data.testNumber, 'not ok', data.name, data.skip, data.todo);
const location = data.file ? `${data.file}:${data.line}:${data.column}` : null;
yield reportDetails(data.nesting, data.details, location);
break;
} case 'test:pass':
yield reportTest(data.nesting, data.testNumber, 'ok', data.name, data.skip, data.todo);
yield reportDetails(data.nesting, data.details, null);
break;
case 'test:plan':
yield `${indent(data.nesting)}1..${data.count}\n`;
break;
case 'test:start':
yield `${indent(data.nesting)}# Subtest: ${tapEscape(data.name)}\n`;
break;
case 'test:stderr':
case 'test:stdout': {
const lines = RegExpPrototypeSymbolSplit(kLineBreakRegExp, data.message);
for (let i = 0; i < lines.length; i++) {
if (lines[i].length === 0) continue;
yield `# ${tapEscape(lines[i])}\n`;
}
break;
} case 'test:diagnostic':
yield `${indent(data.nesting)}# ${tapEscape(data.message)}\n`;
break;
case 'test:coverage':
yield getCoverageReport(indent(data.nesting), data.summary, '# ', '', true);
break;
}
}
}
function reportTest(nesting, testNumber, status, name, skip, todo) {
let line = `${indent(nesting)}${status} ${testNumber}`;
if (name) {
line += ` ${tapEscape(`- ${name}`)}`;
}
if (skip !== undefined) {
line += ` # SKIP${typeof skip === 'string' && skip.length ? ` ${tapEscape(skip)}` : ''}`;
} else if (todo !== undefined) {
line += ` # TODO${typeof todo === 'string' && todo.length ? ` ${tapEscape(todo)}` : ''}`;
}
line += '\n';
return line;
}
function reportDetails(nesting, data = kEmptyObject, location) {
const { error, duration_ms } = data;
const _indent = indent(nesting);
let details = `${_indent} ---\n`;
details += jsToYaml(_indent, 'duration_ms', duration_ms);
details += jsToYaml(_indent, 'type', data.type);
if (location) {
details += jsToYaml(_indent, 'location', location);
}
details += jsToYaml(_indent, null, error, new SafeSet());
details += `${_indent} ...\n`;
return details;
}
const memo = new SafeMap();
function indent(nesting) {
let value = memo.get(nesting);
if (value === undefined) {
value = StringPrototypeRepeat(kDefaultIndent, nesting);
memo.set(nesting, value);
}
return value;
}
// In certain places, # and \ need to be escaped as \# and \\.
function tapEscape(input) {
let result = StringPrototypeReplaceAll(input, '\b', '\\b');
result = StringPrototypeReplaceAll(result, '\f', '\\f');
result = StringPrototypeReplaceAll(result, '\t', '\\t');
result = StringPrototypeReplaceAll(result, '\n', '\\n');
result = StringPrototypeReplaceAll(result, '\r', '\\r');
result = StringPrototypeReplaceAll(result, '\v', '\\v');
result = StringPrototypeReplaceAll(result, '\\', '\\\\');
result = StringPrototypeReplaceAll(result, '#', '\\#');
return result;
}
function jsToYaml(indent, name, value, seen) {
if (value === undefined) {
return '';
}
const prefix = `${indent} ${name}:`;
if (value === null) {
return `${prefix} ~\n`;
}
if (typeof value !== 'object') {
if (typeof value !== 'string') {
return `${prefix} ${inspectWithNoCustomRetry(value, inspectOptions)}\n`;
}
const lines = RegExpPrototypeSymbolSplit(kLineBreakRegExp, value);
if (lines.length === 1) {
return `${prefix} ${inspectWithNoCustomRetry(value, inspectOptions)}\n`;
}
let str = `${prefix} |-\n`;
for (let i = 0; i < lines.length; i++) {
str += `${indent} ${lines[i]}\n`;
}
return str;
}
seen.add(value);
const entries = ObjectEntries(value);
const isErrorObj = isError(value);
let propsIndent = indent;
let result = '';
if (name != null) {
result += prefix;
if (internalBinding('types').isDate(value)) {
// YAML uses the ISO-8601 standard to express dates.
result += ' ' + DatePrototypeToISOString(value);
}
result += '\n';
propsIndent += ' ';
}
for (let i = 0; i < entries.length; i++) {
const { 0: key, 1: value } = entries[i];
if (isErrorObj && (key === 'cause' || key === 'code')) {
continue;
}
if (seen.has(value)) {
result += `${propsIndent} ${key}: <Circular>\n`;
continue;
}
result += jsToYaml(propsIndent, key, value, seen);
}
if (isErrorObj) {
const { kUnwrapErrors } = lazyLoadTest();
const {
cause,
code,
failureType,
message,
expected,
actual,
operator,
stack,
name,
} = value;
let errMsg = message ?? '<unknown error>';
let errName = name;
let errStack = stack;
let errCode = code;
let errExpected = expected;
let errActual = actual;
let errOperator = operator;
let errIsAssertion = isAssertionLike(value);
// If the ERR_TEST_FAILURE came from an error provided by user code,
// then try to unwrap the original error message and stack.
if (code === 'ERR_TEST_FAILURE' && kUnwrapErrors.has(failureType)) {
errStack = cause?.stack ?? errStack;
errCode = cause?.code ?? errCode;
errName = cause?.name ?? errName;
errMsg = cause?.message ?? errMsg;
if (isAssertionLike(cause)) {
errExpected = cause.expected;
errActual = cause.actual;
errOperator = cause.operator ?? errOperator;
errIsAssertion = true;
}
}
result += jsToYaml(indent, 'error', errMsg, seen);
if (errCode) {
result += jsToYaml(indent, 'code', errCode, seen);
}
if (errName && errName !== 'Error') {
result += jsToYaml(indent, 'name', errName, seen);
}
if (errIsAssertion) {
// Note that we're deliberately creating shallow copies of the `seen`
// set here in order to isolate the discovery of circular references
// within the expected and actual properties respectively.
result += jsToYaml(indent, 'expected', errExpected, new SafeSet(seen));
result += jsToYaml(indent, 'actual', errActual, new SafeSet(seen));
if (errOperator) {
result += jsToYaml(indent, 'operator', errOperator, seen);
}
}
if (typeof errStack === 'string') {
const frames = [];
ArrayPrototypeForEach(
RegExpPrototypeSymbolSplit(kLineBreakRegExp, errStack),
(frame) => {
const processed = RegExpPrototypeSymbolReplace(
kFrameStartRegExp,
frame,
'',
);
if (processed.length > 0 && processed.length !== frame.length) {
ArrayPrototypePush(frames, processed);
}
},
);
if (frames.length > 0) {
const frameDelimiter = `\n${indent} `;
result += `${indent} stack: |-${frameDelimiter}`;
result += `${ArrayPrototypeJoin(frames, frameDelimiter)}\n`;
}
}
}
return result;
}
function isAssertionLike(value) {
return value && typeof value === 'object' && 'expected' in value && 'actual' in value;
}
module.exports = tapReporter;

View File

@ -0,0 +1,102 @@
'use strict';
const {
ArrayPrototypeJoin,
RegExpPrototypeSymbolSplit,
SafeMap,
StringPrototypeRepeat,
hardenRegExp,
} = primordials;
const colors = require('internal/util/colors');
const { inspectWithNoCustomRetry } = require('internal/errors');
const indentMemo = new SafeMap();
const inspectOptions = {
__proto__: null,
colors: colors.shouldColorize(process.stdout),
breakLength: Infinity,
};
const reporterUnicodeSymbolMap = {
'__proto__': null,
'test:fail': '\u2716 ',
'test:pass': '\u2714 ',
'test:diagnostic': '\u2139 ',
'test:coverage': '\u2139 ',
'arrow:right': '\u25B6 ',
'hyphen:minus': '\uFE63 ',
};
const reporterColorMap = {
'__proto__': null,
get 'test:fail'() {
return colors.red;
},
get 'test:pass'() {
return colors.green;
},
get 'test:diagnostic'() {
return colors.blue;
},
get 'info'() {
return colors.blue;
},
get 'warn'() {
return colors.yellow;
},
get 'error'() {
return colors.red;
},
};
function indent(nesting) {
let value = indentMemo.get(nesting);
if (value === undefined) {
value = StringPrototypeRepeat(' ', nesting);
indentMemo.set(nesting, value);
}
return value;
}
function formatError(error, indent) {
if (!error) return '';
const err = error.code === 'ERR_TEST_FAILURE' ? error.cause : error;
const message = ArrayPrototypeJoin(
RegExpPrototypeSymbolSplit(
hardenRegExp(/\r?\n/),
inspectWithNoCustomRetry(err, inspectOptions),
), `\n${indent} `);
return `\n${indent} ${message}\n`;
}
function formatTestReport(type, data, prefix = '', indent = '', hasChildren = false, showErrorDetails = true) {
let color = reporterColorMap[type] ?? colors.white;
let symbol = reporterUnicodeSymbolMap[type] ?? ' ';
const { skip, todo } = data;
const duration_ms = data.details?.duration_ms ? ` ${colors.gray}(${data.details.duration_ms}ms)${colors.white}` : '';
let title = `${data.name}${duration_ms}`;
if (skip !== undefined) {
title += ` # ${typeof skip === 'string' && skip.length ? skip : 'SKIP'}`;
} else if (todo !== undefined) {
title += ` # ${typeof todo === 'string' && todo.length ? todo : 'TODO'}`;
}
const error = showErrorDetails ? formatError(data.details?.error, indent) : '';
const err = hasChildren ?
(!error || data.details?.error?.failureType === 'subtestsFailed' ? '' : `\n${error}`) :
error;
if (skip !== undefined) {
color = colors.gray;
symbol = reporterUnicodeSymbolMap['hyphen:minus'];
}
return `${prefix}${indent}${color}${symbol}${title}${colors.white}${err}`;
}
module.exports = {
__proto__: null,
reporterUnicodeSymbolMap,
reporterColorMap,
formatTestReport,
indent,
};

View File

@ -0,0 +1,45 @@
'use strict';
const {
TypedArrayPrototypeGetLength,
} = primordials;
const { DefaultSerializer } = require('v8');
const { Buffer } = require('buffer');
const { serializeError } = require('internal/error_serdes');
module.exports = async function* v8Reporter(source) {
const serializer = new DefaultSerializer();
serializer.writeHeader();
const headerLength = TypedArrayPrototypeGetLength(serializer.releaseBuffer());
for await (const item of source) {
const originalError = item.data.details?.error;
if (originalError) {
// Error is overridden with a serialized version, so that it can be
// deserialized in the parent process.
// Error is restored after serialization.
item.data.details.error = serializeError(originalError);
}
serializer.writeHeader();
// Add 4 bytes, to later populate with message length
serializer.writeRawBytes(Buffer.allocUnsafe(4));
serializer.writeHeader();
serializer.writeValue(item);
if (originalError) {
item.data.details.error = originalError;
}
const serializedMessage = serializer.releaseBuffer();
const serializedMessageLength = serializedMessage.length - (4 + headerLength);
serializedMessage.set([
serializedMessageLength >> 24 & 0xFF,
serializedMessageLength >> 16 & 0xFF,
serializedMessageLength >> 8 & 0xFF,
serializedMessageLength & 0xFF,
], headerLength);
yield serializedMessage;
}
};