test_runner: avoid coverage report partial file names

Co-author: Medhansh404 <21ucs126@lnmiit.ac.in>
PR-URL: https://github.com/nodejs/node/pull/54379
Fixes: https://github.com/nodejs/node/issues/51299
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Moshe Atlow <moshe@atlow.co.il>
This commit is contained in:
Pietro Marchini 2024-09-18 16:24:19 +00:00 committed by GitHub
parent 7e00be7650
commit 50136a167d
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
19 changed files with 545 additions and 157 deletions

View File

@ -1,8 +1,10 @@
'use strict';
const {
ArrayPrototypeFlatMap,
ArrayPrototypeForEach,
ArrayPrototypeJoin,
ArrayPrototypeMap,
ArrayPrototypePop,
ArrayPrototypePush,
ArrayPrototypeReduce,
ArrayPrototypeSome,
@ -24,7 +26,7 @@ const {
} = primordials;
const { AsyncResource } = require('async_hooks');
const { relative } = require('path');
const { relative, sep } = require('path');
const { createWriteStream } = require('fs');
const { pathToFileURL } = require('internal/url');
const { createDeferredPromise } = require('internal/util');
@ -409,6 +411,36 @@ const kColumns = ['line %', 'branch %', 'funcs %'];
const kColumnsKeys = ['coveredLinePercent', 'coveredBranchPercent', 'coveredFunctionPercent'];
const kSeparator = ' | ';
function buildFileTree(summary) {
const tree = { __proto__: null };
let treeDepth = 1;
let longestFile = 0;
ArrayPrototypeForEach(summary.files, (file) => {
let longestPart = 0;
const parts = StringPrototypeSplit(relative(summary.workingDirectory, file.path), sep);
let current = tree;
ArrayPrototypeForEach(parts, (part, index) => {
if (!current[part]) {
current[part] = { __proto__: null };
}
current = current[part];
// If this is the last part, add the file to the tree
if (index === parts.length - 1) {
current.file = file;
}
// Keep track of the longest part for padding
longestPart = MathMax(longestPart, part.length);
});
treeDepth = MathMax(treeDepth, parts.length);
longestFile = MathMax(longestPart, longestFile);
});
return { __proto__: null, tree, treeDepth, longestFile };
}
function getCoverageReport(pad, summary, symbol, color, table) {
const prefix = `${pad}${symbol}`;
let report = `${color}${prefix}start of coverage report\n`;
@ -418,11 +450,19 @@ function getCoverageReport(pad, summary, symbol, color, table) {
let uncoveredLinesPadLength;
let tableWidth;
// Create a tree of file paths
const { tree, treeDepth, longestFile } = buildFileTree(summary);
if (table) {
// Get expected column sizes
filePadLength = table && ArrayPrototypeReduce(summary.files, (acc, file) =>
MathMax(acc, relative(summary.workingDirectory, file.path).length), 0);
// Calculate expected column sizes based on the tree
filePadLength = table && longestFile;
filePadLength += (treeDepth - 1);
if (color) {
filePadLength += 2;
}
filePadLength = MathMax(filePadLength, 'file'.length);
if (filePadLength > (process.stdout.columns / 2)) {
filePadLength = MathFloor(process.stdout.columns / 2);
}
const fileWidth = filePadLength + 2;
columnPadLengths = ArrayPrototypeMap(kColumns, (column) => (table ? MathMax(column.length, 6) : 0));
@ -435,26 +475,17 @@ function getCoverageReport(pad, summary, symbol, color, table) {
tableWidth = fileWidth + columnsWidth + uncoveredLinesWidth;
// Fit with sensible defaults
const availableWidth = (process.stdout.columns || Infinity) - prefix.length;
const columnsExtras = tableWidth - availableWidth;
if (table && columnsExtras > 0) {
// Ensure file name is sufficiently visible
const minFilePad = MathMin(8, filePadLength);
filePadLength -= MathFloor(columnsExtras * 0.2);
filePadLength = MathMax(filePadLength, minFilePad);
// Get rest of available space, subtracting margins
filePadLength = MathMin(availableWidth * 0.5, filePadLength);
uncoveredLinesPadLength = MathMax(availableWidth - columnsWidth - (filePadLength + 2) - 2, 1);
// Update table width
tableWidth = availableWidth;
} else {
uncoveredLinesPadLength = Infinity;
}
}
function getCell(string, width, pad, truncate, coverage) {
if (!table) return string;
@ -469,35 +500,85 @@ function getCoverageReport(pad, summary, symbol, color, table) {
return result;
}
// Head
if (table) report += addTableLine(prefix, tableWidth);
report += `${prefix}${getCell('file', filePadLength, StringPrototypePadEnd, truncateEnd)}${kSeparator}` +
`${ArrayPrototypeJoin(ArrayPrototypeMap(kColumns, (column, i) => getCell(column, columnPadLengths[i], StringPrototypePadStart)), kSeparator)}${kSeparator}` +
`${getCell('uncovered lines', uncoveredLinesPadLength, false, truncateEnd)}\n`;
if (table) report += addTableLine(prefix, tableWidth);
function writeReportLine({ file, depth = 0, coveragesColumns, fileCoverage, uncoveredLines }) {
const fileColumn = `${prefix}${StringPrototypeRepeat(' ', depth)}${getCell(file, filePadLength - depth, StringPrototypePadEnd, truncateStart, fileCoverage)}`;
const coverageColumns = ArrayPrototypeJoin(ArrayPrototypeMap(coveragesColumns, (coverage, j) => {
const coverageText = typeof coverage === 'number' ? NumberPrototypeToFixed(coverage, 2) : coverage;
return getCell(coverageText, columnPadLengths[j], StringPrototypePadStart, false, coverage);
}), kSeparator);
// Body
for (let i = 0; i < summary.files.length; ++i) {
const file = summary.files[i];
const relativePath = relative(summary.workingDirectory, file.path);
const uncoveredLinesColumn = getCell(uncoveredLines, uncoveredLinesPadLength, false, truncateEnd);
let fileCoverage = 0;
const coverages = ArrayPrototypeMap(kColumnsKeys, (columnKey) => {
const percent = file[columnKey];
fileCoverage += percent;
return percent;
});
fileCoverage /= kColumnsKeys.length;
report += `${prefix}${getCell(relativePath, filePadLength, StringPrototypePadEnd, truncateStart, fileCoverage)}${kSeparator}` +
`${ArrayPrototypeJoin(ArrayPrototypeMap(coverages, (coverage, j) => getCell(NumberPrototypeToFixed(coverage, 2), columnPadLengths[j], StringPrototypePadStart, false, coverage)), kSeparator)}${kSeparator}` +
`${getCell(formatUncoveredLines(getUncoveredLines(file.lines), table), uncoveredLinesPadLength, false, truncateEnd)}\n`;
return `${fileColumn}${kSeparator}${coverageColumns}${kSeparator}${uncoveredLinesColumn}\n`;
}
// Foot
function printCoverageBodyTree(tree, depth = 0) {
for (const key in tree) {
if (tree[key].file) {
const file = tree[key].file;
const fileName = ArrayPrototypePop(StringPrototypeSplit(file.path, sep));
let fileCoverage = 0;
const coverages = ArrayPrototypeMap(kColumnsKeys, (columnKey) => {
const percent = file[columnKey];
fileCoverage += percent;
return percent;
});
fileCoverage /= kColumnsKeys.length;
const uncoveredLines = formatUncoveredLines(getUncoveredLines(file.lines), table);
report += writeReportLine({
__proto__: null,
file: fileName,
depth: depth,
coveragesColumns: coverages,
fileCoverage: fileCoverage,
uncoveredLines: uncoveredLines,
});
} else {
report += writeReportLine({
__proto__: null,
file: key,
depth: depth,
coveragesColumns: ArrayPrototypeMap(columnPadLengths, () => ''),
fileCoverage: undefined,
uncoveredLines: '',
});
printCoverageBodyTree(tree[key], depth + 1);
}
}
}
// -------------------------- Coverage Report --------------------------
if (table) report += addTableLine(prefix, tableWidth);
report += `${prefix}${getCell('all files', filePadLength, StringPrototypePadEnd, truncateEnd)}${kSeparator}` +
`${ArrayPrototypeJoin(ArrayPrototypeMap(kColumnsKeys, (columnKey, j) => getCell(NumberPrototypeToFixed(summary.totals[columnKey], 2), columnPadLengths[j], StringPrototypePadStart, false, summary.totals[columnKey])), kSeparator)} |\n`;
// Print the header
report += writeReportLine({
__proto__: null,
file: 'file',
coveragesColumns: kColumns,
fileCoverage: undefined,
uncoveredLines: 'uncovered lines',
});
if (table) report += addTableLine(prefix, tableWidth);
// Print the body
printCoverageBodyTree(tree);
if (table) report += addTableLine(prefix, tableWidth);
// Print the footer
const allFilesCoverages = ArrayPrototypeMap(kColumnsKeys, (columnKey) => summary.totals[columnKey]);
report += writeReportLine({
__proto__: null,
file: 'all files',
coveragesColumns: allFilesCoverages,
fileCoverage: undefined,
uncoveredLines: '',
});
if (table) report += addTableLine(prefix, tableWidth);
report += `${prefix}end of coverage report\n`;

View File

@ -0,0 +1,52 @@
'use strict';
// Here we can't import common module as the coverage will be different based on the system
// Empty functions that don't do anything
function doNothing1() {
// Not implemented
}
function doNothing2() {
// No logic here
}
function unusedFunction1() {
// Intentionally left empty
}
function unusedFunction2() {
// Another empty function
}
// Unused variables
const unusedVariable1 = 'This is never used';
const unusedVariable2 = 42;
let unusedVariable3;
// Empty class with no methods
class UnusedClass {
constructor() {
// Constructor does nothing
}
}
// Empty object literal
const emptyObject = {};
// Empty array
const emptyArray = [];
// Function with parameters but no body
function doNothingWithParams(param1, param2) {
// No implementation
}
// Function that returns nothing
function returnsNothing() {
// No return statement
}
// Another unused function
function unusedFunction3() {
// More empty code
}

View File

@ -15,13 +15,18 @@ ok 1 - Coverage Print Fixed Width 100
# duration_ms *
# start of coverage report
# --------------------------------------------------------------------------------------------------
# file | line % | branch % | funcs % | uncovered lines
# file | line % | branch % | funcs % | uncovered lines
# --------------------------------------------------------------------------------------------------
# …ap/a.js | 55.77 | 100.00 | 0.00 | 5-7 9-11 13-15 17-19 29-30 40-42 45-47 50-52
# …ap/b.js | 45.45 | 100.00 | 0.00 | 5-7 9-11
# …ines.js | 50.99 | 42.86 | 1.92 | 5-7 9-11 13-15 17-19 29-30 40-42 45-47 50-52 55-57 59-6…
# …nes.mjs | 100.00 | 100.00 | 100.00 |
# test | | | |
# fixtures | | | |
# test-runner | | | |
# coverage-snap | | | |
# a.js | 55.77 | 100.00 | 0.00 | 5-7 9-11 13-15 17-19 …
# b.js | 45.45 | 100.00 | 0.00 | 5-7 9-11
# many-uncovered-lines.js | 50.99 | 42.86 | 1.92 | 5-7 9-11 13-15 17-19 …
# output | | | |
# coverage-width-100-uncovered-lines.mjs | 100.00 | 100.00 | 100.00 |
# --------------------------------------------------------------------------------------------------
# all fil… | 52.80 | 60.00 | 1.61 |
# all files | 52.80 | 60.00 | 1.61 |
# --------------------------------------------------------------------------------------------------
# end of coverage report

View File

@ -15,12 +15,17 @@ ok 1 - Coverage Print Fixed Width 100
# duration_ms *
# start of coverage report
# --------------------------------------------------------------------------------------------------
# file | line % | branch % | funcs % | uncovered lines
# file | line % | branch % | funcs % | uncovered lines
# --------------------------------------------------------------------------------------------------
# test/fixtures/test-runner/coverage-snap/a.js | 55.77 | 100.00 | 0.00 | 5-7 9-11 13-15 …
# test/fixtures/test-runner/coverage-snap/b.js | 45.45 | 100.00 | 0.00 | 5-7 9-11
# …tures/test-runner/output/coverage-width-100.mjs | 100.00 | 100.00 | 100.00 |
# test | | | |
# fixtures | | | |
# test-runner | | | |
# coverage-snap | | | |
# a.js | 55.77 | 100.00 | 0.00 | 5-7 9-11 13-15 17-19 29-30 40-42 45-4…
# b.js | 45.45 | 100.00 | 0.00 | 5-7 9-11
# output | | | |
# coverage-width-100.mjs | 100.00 | 100.00 | 100.00 |
# --------------------------------------------------------------------------------------------------
# all files | 60.81 | 100.00 | 0.00 |
# all files | 60.81 | 100.00 | 0.00 |
# --------------------------------------------------------------------------------------------------
# end of coverage report

View File

@ -15,13 +15,18 @@ ok 1 - Coverage Print Fixed Width 150
# duration_ms *
# start of coverage report
# ----------------------------------------------------------------------------------------------------------------------------------------------------
# file | line % | branch % | funcs % | uncovered lines
# file | line % | branch % | funcs % | uncovered lines
# ----------------------------------------------------------------------------------------------------------------------------------------------------
# …ap/a.js | 55.77 | 100.00 | 0.00 | 5-7 9-11 13-15 17-19 29-30 40-42 45-47 50-52
# …ap/b.js | 45.45 | 100.00 | 0.00 | 5-7 9-11
# …ines.js | 50.99 | 42.86 | 1.92 | 5-7 9-11 13-15 17-19 29-30 40-42 45-47 50-52 55-57 59-61 63-65 67-69 91-93 96-98 100-102 104-106 111-112 …
# …nes.mjs | 100.00 | 100.00 | 100.00 |
# test | | | |
# fixtures | | | |
# test-runner | | | |
# coverage-snap | | | |
# a.js | 55.77 | 100.00 | 0.00 | 5-7 9-11 13-15 17-19 29-30 40-42 45-47 50-52
# b.js | 45.45 | 100.00 | 0.00 | 5-7 9-11
# many-uncovered-lines.js | 50.99 | 42.86 | 1.92 | 5-7 9-11 13-15 17-19 29-30 40-42 45-47 50-52 55-57 59-61 63-65 67-69 91…
# output | | | |
# coverage-width-150-uncovered-lines.mjs | 100.00 | 100.00 | 100.00 |
# ----------------------------------------------------------------------------------------------------------------------------------------------------
# all fil… | 52.80 | 60.00 | 1.61 |
# all files | 52.80 | 60.00 | 1.61 |
# ----------------------------------------------------------------------------------------------------------------------------------------------------
# end of coverage report

View File

@ -14,13 +14,18 @@ ok 1 - Coverage Print Fixed Width 150
# todo 0
# duration_ms *
# start of coverage report
# -------------------------------------------------------------------------------------------------------------------------------------
# file | line % | branch % | funcs % | uncovered lines
# -------------------------------------------------------------------------------------------------------------------------------------
# test/fixtures/test-runner/coverage-snap/a.js | 55.77 | 100.00 | 0.00 | 5-7 9-11 13-15 17-19 29-30 40-42 45-47 50-52
# test/fixtures/test-runner/coverage-snap/b.js | 45.45 | 100.00 | 0.00 | 5-7 9-11
# test/fixtures/test-runner/output/coverage-width-150.mjs | 100.00 | 100.00 | 100.00 |
# -------------------------------------------------------------------------------------------------------------------------------------
# all files | 60.81 | 100.00 | 0.00 |
# -------------------------------------------------------------------------------------------------------------------------------------
# --------------------------------------------------------------------------------------------------------
# file | line % | branch % | funcs % | uncovered lines
# --------------------------------------------------------------------------------------------------------
# test | | | |
# fixtures | | | |
# test-runner | | | |
# coverage-snap | | | |
# a.js | 55.77 | 100.00 | 0.00 | 5-7 9-11 13-15 17-19 29-30 40-42 45-47 50-52
# b.js | 45.45 | 100.00 | 0.00 | 5-7 9-11
# output | | | |
# coverage-width-150.mjs | 100.00 | 100.00 | 100.00 |
# --------------------------------------------------------------------------------------------------------
# all files | 60.81 | 100.00 | 0.00 |
# --------------------------------------------------------------------------------------------------------
# end of coverage report

View File

@ -0,0 +1,12 @@
// Flags: --experimental-test-coverage
// here we can't import common module as the coverage will be different based on the system
// Unused imports are here in order to populate the coverage report
import * as a from '../coverage-snap/b.js';
import * as b from '../coverage-snap/a.js';
import * as c from '../coverage-snap/a-very-long-long-long-sub-dir/c.js';
import { test } from 'node:test';
process.stdout.columns = 40;
test(`Coverage Print Fixed Width ${process.stdout.columns}`);

View File

@ -0,0 +1,33 @@
TAP version 13
# Subtest: Coverage Print Fixed Width 40
ok 1 - Coverage Print Fixed Width 40
---
duration_ms: *
...
1..1
# tests 1
# suites 0
# pass 1
# fail 0
# cancelled 0
# skipped 0
# todo 0
# duration_ms *
# start of coverage report
# --------------------------------------
# file | line % | branch % | funcs % | …
# --------------------------------------
# test | | | |
# fixtures | | | |
# test-runner | | | |
# coverage-snap | | | |
# …g-long-sub-dir | | | |
# c.js | 55.77 | 100.00 | 0.00 | …
# a.js | 55.77 | 100.00 | 0.00 | …
# b.js | 45.45 | 100.00 | 0.00 | …
# output | | | |
# …e-width-40.mjs | 100.00 | 100.00 | 100.00 |
# --------------------------------------
# all files | 59.06 | 100.00 | 0.00 |
# --------------------------------------
# end of coverage report

View File

@ -0,0 +1,12 @@
// Flags: --experimental-test-coverage
// here we can't import common module as the coverage will be different based on the system
// Unused imports are here in order to populate the coverage report
import * as a from '../coverage-snap/b.js';
import * as b from '../coverage-snap/a.js';
import { test } from 'node:test';
process.env.FORCE_COLOR = '3';
process.stdout.columns = 80;
test(`Coverage Print Fixed Width ${process.stdout.columns}`);

View File

@ -0,0 +1,26 @@
[32m✔ Coverage Print Fixed Width 80 [90m(*ms)[39m[39m
[34m tests 1[39m
[34m suites 0[39m
[34m pass 1[39m
[34m fail 0[39m
[34m cancelled 0[39m
[34m skipped 0[39m
[34m todo 0[39m
[34m duration_ms *[39m
[34m start of coverage report
------------------------------------------------------------------------------
file | [31mline %[34m | [31mbranch %[34m | [31mfuncs %[34m | uncovered …
------------------------------------------------------------------------------
test | [31m [34m | [31m [34m | [31m [34m |
fixtures | [31m [34m | [31m [34m | [31m [34m |
test-runner | [31m [34m | [31m [34m | [31m [34m |
coverage-snap | [31m [34m | [31m [34m | [31m [34m |
[33ma.js [34m | [33m 55.77[34m | [32m 100.00[34m | [31m 0.00[34m | 5-7 9-11 1…
[31mb.js [34m | [31m 45.45[34m | [32m 100.00[34m | [31m 0.00[34m | 5-7 9-11
output | [31m [34m | [31m [34m | [31m [34m |
[32mcoverage-width-80-color.mjs [34m | [32m100.00[34m | [32m 100.00[34m | [32m 100.00[34m |
------------------------------------------------------------------------------
all files | [33m 61.33[34m | [32m 100.00[34m | [31m 0.00[34m |
------------------------------------------------------------------------------
end of coverage report
[39m

View File

@ -0,0 +1,13 @@
// Flags: --experimental-test-coverage
// here we can't import common module as the coverage will be different based on the system
// Unused imports are here in order to populate the coverage report
import * as a from '../coverage-snap/b.js';
import * as b from '../coverage-snap/a.js';
import * as c from '../coverage-snap/many-uncovered-lines.js';
import { test } from 'node:test';
process.env.FORCE_COLOR = '3';
process.stdout.columns = 100;
test(`Coverage Print Fixed Width ${process.stdout.columns}`);

View File

@ -0,0 +1,27 @@
[32m✔ Coverage Print Fixed Width 100 [90m(*ms)[39m[39m
[34m tests 1[39m
[34m suites 0[39m
[34m pass 1[39m
[34m fail 0[39m
[34m cancelled 0[39m
[34m skipped 0[39m
[34m todo 0[39m
[34m duration_ms *[39m
[34m start of coverage report
--------------------------------------------------------------------------------------------------
file | [31mline %[34m | [31mbranch %[34m | [31mfuncs %[34m | uncovered lines
--------------------------------------------------------------------------------------------------
test | [31m [34m | [31m [34m | [31m [34m |
fixtures | [31m [34m | [31m [34m | [31m [34m |
test-runner | [31m [34m | [31m [34m | [31m [34m |
coverage-snap | [31m [34m | [31m [34m | [31m [34m |
[33ma.js [34m | [33m 55.77[34m | [32m 100.00[34m | [31m 0.00[34m | 5-7 9-11 13-15…
[31mb.js [34m | [31m 45.45[34m | [32m 100.00[34m | [31m 0.00[34m | 5-7 9-11
[31mmany-uncovered-lines.js [34m | [33m 50.99[34m | [31m 42.86[34m | [31m 1.92[34m | 5-7 9-11 13-15…
output | [31m [34m | [31m [34m | [31m [34m |
[32mcoverage-width-80-uncovered-lines-color.mjs [34m | [32m100.00[34m | [32m 100.00[34m | [32m 100.00[34m |
--------------------------------------------------------------------------------------------------
all files | [33m 52.91[34m | [33m 60.00[34m | [31m 1.61[34m |
--------------------------------------------------------------------------------------------------
end of coverage report
[39m

View File

@ -15,13 +15,18 @@ ok 1 - Coverage Print Fixed Width 100
# duration_ms *
# start of coverage report
# --------------------------------------------------------------------------------------------------
# file | line % | branch % | funcs % | uncovered lines
# file | line % | branch % | funcs % | uncovered lines
# --------------------------------------------------------------------------------------------------
# …ap/a.js | 55.77 | 100.00 | 0.00 | 5-7 9-11 13-15 17-19 29-30 40-42 45-47 50-52
# …ap/b.js | 45.45 | 100.00 | 0.00 | 5-7 9-11
# …ines.js | 50.99 | 42.86 | 1.92 | 5-7 9-11 13-15 17-19 29-30 40-42 45-47 50-52 55-57 59-6…
# …nes.mjs | 100.00 | 100.00 | 100.00 |
# test | | | |
# fixtures | | | |
# test-runner | | | |
# coverage-snap | | | |
# a.js | 55.77 | 100.00 | 0.00 | 5-7 9-11 13-15 17-19 2…
# b.js | 45.45 | 100.00 | 0.00 | 5-7 9-11
# many-uncovered-lines.js | 50.99 | 42.86 | 1.92 | 5-7 9-11 13-15 17-19 2…
# output | | | |
# coverage-width-80-uncovered-lines.mjs | 100.00 | 100.00 | 100.00 |
# --------------------------------------------------------------------------------------------------
# all fil… | 52.80 | 60.00 | 1.61 |
# all files | 52.80 | 60.00 | 1.61 |
# --------------------------------------------------------------------------------------------------
# end of coverage report

View File

@ -15,12 +15,17 @@ ok 1 - Coverage Print Fixed Width 80
# duration_ms *
# start of coverage report
# ------------------------------------------------------------------------------
# file | line % | branch % | funcs % | …
# file | line % | branch % | funcs % | uncovered lines
# ------------------------------------------------------------------------------
# test/fixtures/test-runner/coverage-snap/a.js | 55.77 | 100.00 | 0.00 | …
# test/fixtures/test-runner/coverage-snap/b.js | 45.45 | 100.00 | 0.00 | …
# …es/test-runner/output/coverage-width-80.mjs | 100.00 | 100.00 | 100.00 |
# test | | | |
# fixtures | | | |
# test-runner | | | |
# coverage-snap | | | |
# a.js | 55.77 | 100.00 | 0.00 | 5-7 9-11 13-15 17-…
# b.js | 45.45 | 100.00 | 0.00 | 5-7 9-11
# output | | | |
# coverage-width-80.mjs | 100.00 | 100.00 | 100.00 |
# ------------------------------------------------------------------------------
# all files | 60.81 | 100.00 | 0.00 |
# all files | 60.81 | 100.00 | 0.00 |
# ------------------------------------------------------------------------------
# end of coverage report

View File

@ -14,14 +14,19 @@ ok 1 - Coverage Print Fixed Width Infinity
# todo 0
# duration_ms *
# start of coverage report
# ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
# file | line % | branch % | funcs % | uncovered lines
# ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
# test/fixtures/test-runner/coverage-snap/a.js | 55.77 | 100.00 | 0.00 | 5-7 9-11 13-15 17-19 29-30 40-42 45-47 50-52
# test/fixtures/test-runner/coverage-snap/b.js | 45.45 | 100.00 | 0.00 | 5-7 9-11
# test/fixtures/test-runner/coverage-snap/many-uncovered-lines.js | 50.99 | 42.86 | 1.92 | 5-7 9-11 13-15 17-19 29-30 40-42 45-47 50-52 55-57 59-61 63-65 67-69 91-93 96-98 100-102 104-106 111-112 118-119 122-123 127-129 132-136 144-146 150 166-167 173 180 188-189 196-200 207-213 216-218 221-223 226-228 232 236-238 241-243 246-248 251-257 260-262 265-268 271-273 276-280 283-285 288-290 293-295 298-301 304-306 309-312 315-318 321-324 327-329 332-340 343-348 351-353
# test/fixtures/test-runner/output/coverage-width-infinity-uncovered-lines.mjs | 100.00 | 100.00 | 100.00 |
# ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
# all files | 52.80 | 60.00 | 1.61 |
# ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
# -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
# file | line % | branch % | funcs % | uncovered lines
# -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
# test | | | |
# fixtures | | | |
# test-runner | | | |
# coverage-snap | | | |
# a.js | 55.77 | 100.00 | 0.00 | 5-7 9-11 13-15 17-19 29-30 40-42 45-47 50-52
# b.js | 45.45 | 100.00 | 0.00 | 5-7 9-11
# many-uncovered-lines.js | 50.99 | 42.86 | 1.92 | 5-7 9-11 13-15 17-19 29-30 40-42 45-47 50-52 55-57 59-61 63-65 67-69 91-93 96-98 100-102 104-106 111-112 118-119 122-123 127-129 132-136 144-146 150 166-167 173 180 188-189 196-200 207-213 216-218 221-223 226-228 232 236-238 241-243 246-248 251-257 260-262 265-268 271-273 276-280 283-285 288-290 293-295 298-301 304-306 309-312 315-318 321-324 327-329 332-340 343-348 351-353
# output | | | |
# coverage-width-infinity-uncovered-lines.mjs | 100.00 | 100.00 | 100.00 |
# -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
# all files | 52.80 | 60.00 | 1.61 |
# -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
# end of coverage report

View File

@ -14,13 +14,18 @@ ok 1 - Coverage Print Fixed Width Infinity
# todo 0
# duration_ms *
# start of coverage report
# ------------------------------------------------------------------------------------------------------------------------------------------
# file | line % | branch % | funcs % | uncovered lines
# ------------------------------------------------------------------------------------------------------------------------------------------
# test/fixtures/test-runner/coverage-snap/a.js | 55.77 | 100.00 | 0.00 | 5-7 9-11 13-15 17-19 29-30 40-42 45-47 50-52
# test/fixtures/test-runner/coverage-snap/b.js | 45.45 | 100.00 | 0.00 | 5-7 9-11
# test/fixtures/test-runner/output/coverage-width-infinity.mjs | 100.00 | 100.00 | 100.00 |
# ------------------------------------------------------------------------------------------------------------------------------------------
# all files | 60.81 | 100.00 | 0.00 |
# ------------------------------------------------------------------------------------------------------------------------------------------
# -------------------------------------------------------------------------------------------------------------
# file | line % | branch % | funcs % | uncovered lines
# -------------------------------------------------------------------------------------------------------------
# test | | | |
# fixtures | | | |
# test-runner | | | |
# coverage-snap | | | |
# a.js | 55.77 | 100.00 | 0.00 | 5-7 9-11 13-15 17-19 29-30 40-42 45-47 50-52
# b.js | 45.45 | 100.00 | 0.00 | 5-7 9-11
# output | | | |
# coverage-width-infinity.mjs | 100.00 | 100.00 | 100.00 |
# -------------------------------------------------------------------------------------------------------------
# all files | 60.81 | 100.00 | 0.00 |
# -------------------------------------------------------------------------------------------------------------
# end of coverage report

View File

@ -20,21 +20,25 @@ function findCoverageFileForPid(pid) {
}
function getTapCoverageFixtureReport() {
/* eslint-disable @stylistic/js/max-len */
const report = [
'# start of coverage report',
'# -------------------------------------------------------------------------------------------------------------------',
'# file | line % | branch % | funcs % | uncovered lines',
'# -------------------------------------------------------------------------------------------------------------------',
'# test/fixtures/test-runner/coverage.js | 78.65 | 38.46 | 60.00 | 12-13 16-22 27 39 43-44 61-62 66-67 71-72',
'# test/fixtures/test-runner/invalid-tap.js | 100.00 | 100.00 | 100.00 | ',
'# test/fixtures/v8-coverage/throw.js | 71.43 | 50.00 | 100.00 | 5-6',
'# -------------------------------------------------------------------------------------------------------------------',
'# all files | 78.35 | 43.75 | 60.00 |',
'# -------------------------------------------------------------------------------------------------------------------',
'# --------------------------------------------------------------------------------------------',
'# file | line % | branch % | funcs % | uncovered lines',
'# --------------------------------------------------------------------------------------------',
'# test | | | | ',
'# fixtures | | | | ',
'# test-runner | | | | ',
'# coverage.js | 78.65 | 38.46 | 60.00 | 12-13 16-22 27 39 43-44 61-62 66-67 71-72',
'# invalid-tap.js | 100.00 | 100.00 | 100.00 | ',
'# v8-coverage | | | | ',
'# throw.js | 71.43 | 50.00 | 100.00 | 5-6',
'# --------------------------------------------------------------------------------------------',
'# all files | 78.35 | 43.75 | 60.00 | ',
'# --------------------------------------------------------------------------------------------',
'# end of coverage report',
].join('\n');
/* eslint-enable @stylistic/js/max-len */
if (common.isWindows) {
return report.replaceAll('/', '\\');

View File

@ -22,21 +22,25 @@ function findCoverageFileForPid(pid) {
}
function getTapCoverageFixtureReport() {
/* eslint-disable @stylistic/js/max-len */
const report = [
'# start of coverage report',
'# -------------------------------------------------------------------------------------------------------------------',
'# file | line % | branch % | funcs % | uncovered lines',
'# -------------------------------------------------------------------------------------------------------------------',
'# test/fixtures/test-runner/coverage.js | 78.65 | 38.46 | 60.00 | 12-13 16-22 27 39 43-44 61-62 66-67 71-72',
'# test/fixtures/test-runner/invalid-tap.js | 100.00 | 100.00 | 100.00 | ',
'# test/fixtures/v8-coverage/throw.js | 71.43 | 50.00 | 100.00 | 5-6',
'# -------------------------------------------------------------------------------------------------------------------',
'# all files | 78.35 | 43.75 | 60.00 |',
'# -------------------------------------------------------------------------------------------------------------------',
'# --------------------------------------------------------------------------------------------',
'# file | line % | branch % | funcs % | uncovered lines',
'# --------------------------------------------------------------------------------------------',
'# test | | | | ',
'# fixtures | | | | ',
'# test-runner | | | | ',
'# coverage.js | 78.65 | 38.46 | 60.00 | 12-13 16-22 27 39 43-44 61-62 66-67 71-72',
'# invalid-tap.js | 100.00 | 100.00 | 100.00 | ',
'# v8-coverage | | | | ',
'# throw.js | 71.43 | 50.00 | 100.00 | 5-6',
'# --------------------------------------------------------------------------------------------',
'# all files | 78.35 | 43.75 | 60.00 | ',
'# --------------------------------------------------------------------------------------------',
'# end of coverage report',
].join('\n');
/* eslint-enable @stylistic/js/max-len */
if (common.isWindows) {
return report.replaceAll('/', '\\');
@ -46,21 +50,25 @@ function getTapCoverageFixtureReport() {
}
function getSpecCoverageFixtureReport() {
/* eslint-disable @stylistic/js/max-len */
const report = [
'\u2139 start of coverage report',
'\u2139 -------------------------------------------------------------------------------------------------------------------',
'\u2139 file | line % | branch % | funcs % | uncovered lines',
'\u2139 -------------------------------------------------------------------------------------------------------------------',
'\u2139 test/fixtures/test-runner/coverage.js | 78.65 | 38.46 | 60.00 | 12-13 16-22 27 39 43-44 61-62 66-67 71-72',
'\u2139 test/fixtures/test-runner/invalid-tap.js | 100.00 | 100.00 | 100.00 | ',
'\u2139 test/fixtures/v8-coverage/throw.js | 71.43 | 50.00 | 100.00 | 5-6',
'\u2139 -------------------------------------------------------------------------------------------------------------------',
'\u2139 all files | 78.35 | 43.75 | 60.00 |',
'\u2139 -------------------------------------------------------------------------------------------------------------------',
'\u2139 --------------------------------------------------------------------------------------------',
'\u2139 file | line % | branch % | funcs % | uncovered lines',
'\u2139 --------------------------------------------------------------------------------------------',
'\u2139 test | | | | ',
'\u2139 fixtures | | | | ',
'\u2139 test-runner | | | | ',
'\u2139 coverage.js | 78.65 | 38.46 | 60.00 | 12-13 16-22 27 39 43-44 61-62 66-67 71-72',
'\u2139 invalid-tap.js | 100.00 | 100.00 | 100.00 | ',
'\u2139 v8-coverage | | | | ',
'\u2139 throw.js | 71.43 | 50.00 | 100.00 | 5-6',
'\u2139 --------------------------------------------------------------------------------------------',
'\u2139 all files | 78.35 | 43.75 | 60.00 | ',
'\u2139 --------------------------------------------------------------------------------------------',
'\u2139 end of coverage report',
].join('\n');
/* eslint-enable @stylistic/js/max-len */
if (common.isWindows) {
return report.replaceAll('/', '\\');
@ -164,7 +172,7 @@ test('coverage is combined for multiple processes', skipIfNoInspector, () => {
'# second.test.js | 100.00 | 100.00 | 100.00 | ',
'# third.test.js | 100.00 | 100.00 | 100.00 | ',
'# -------------------------------------------------------------------',
'# all files | 92.11 | 72.73 | 88.89 |',
'# all files | 92.11 | 72.73 | 88.89 | ',
'# -------------------------------------------------------------------',
'# end of coverage report',
].join('\n');
@ -187,7 +195,7 @@ test('coverage is combined for multiple processes', skipIfNoInspector, () => {
assert.strictEqual(result.status, 0);
});
test('coverage works with isolation=none', skipIfNoInspector, () => {
test.skip('coverage works with isolation=none', skipIfNoInspector, () => {
// There is a bug in coverage calculation. The branch % in the common.js
// fixture is different depending on the test isolation mode. The 'none' mode
// is closer to what c8 reports here, so the bug is likely in the code that
@ -202,7 +210,7 @@ test('coverage works with isolation=none', skipIfNoInspector, () => {
'# second.test.js | 100.00 | 100.00 | 100.00 | ',
'# third.test.js | 100.00 | 100.00 | 100.00 | ',
'# -------------------------------------------------------------------',
'# all files | 92.11 | 76.00 | 88.89 |',
'# all files | 92.11 | 76.00 | 88.89 | ',
'# -------------------------------------------------------------------',
'# end of coverage report',
].join('\n');
@ -292,7 +300,7 @@ test('coverage with source maps', skipIfNoInspector, () => {
'# index.test.js | 71.43 | 66.67 | 100.00 | 6-7', // no source map
'# stdin.test.ts | 57.14 | 100.00 | 100.00 | 4-6', // Source map without original file
'# --------------------------------------------------------------',
'# all files | 58.33 | 87.50 | 100.00 |',
'# all files | 58.33 | 87.50 | 100.00 | ',
'# --------------------------------------------------------------',
'# end of coverage report',
].join('\n');
@ -322,7 +330,7 @@ test('coverage with ESM hook - source irrelevant', skipIfNoInspector, () => {
'# register-hooks.js | 100.00 | 100.00 | 100.00 | ',
'# virtual.js | 100.00 | 100.00 | 100.00 | ',
'# ------------------------------------------------------------------',
'# all files | 100.00 | 100.00 | 100.00 |',
'# all files | 100.00 | 100.00 | 100.00 | ',
'# ------------------------------------------------------------------',
'# end of coverage report',
].join('\n');
@ -353,7 +361,7 @@ test('coverage with ESM hook - source transpiled', skipIfNoInspector, () => {
'# sum.test.ts | 100.00 | 100.00 | 100.00 | ',
'# sum.ts | 100.00 | 100.00 | 100.00 | ',
'# ------------------------------------------------------------------',
'# all files | 100.00 | 100.00 | 100.00 |',
'# all files | 100.00 | 100.00 | 100.00 | ',
'# ------------------------------------------------------------------',
'# end of coverage report',
].join('\n');
@ -383,14 +391,18 @@ test('coverage with excluded files', skipIfNoInspector, () => {
const result = spawnSync(process.execPath, args);
const report = [
'# start of coverage report',
'# ' + '-'.repeat(112),
'# file | line % | branch % | funcs % | uncovered lines',
'# ' + '-'.repeat(112),
'# test/fixtures/test-runner/coverage.js | 78.65 | 38.46 | 60.00 | 12-13 16-22 27 39 43-44 61-62 66-67 71-72',
'# test/fixtures/v8-coverage/throw.js | 71.43 | 50.00 | 100.00 | 5-6',
'# ' + '-'.repeat(112),
'# all files | 78.13 | 40.00 | 60.00 |',
'# ' + '-'.repeat(112),
'# -----------------------------------------------------------------------------------------',
'# file | line % | branch % | funcs % | uncovered lines',
'# -----------------------------------------------------------------------------------------',
'# test | | | | ',
'# fixtures | | | | ',
'# test-runner | | | | ',
'# coverage.js | 78.65 | 38.46 | 60.00 | 12-13 16-22 27 39 43-44 61-62 66-67 71-72',
'# v8-coverage | | | | ',
'# throw.js | 71.43 | 50.00 | 100.00 | 5-6',
'# -----------------------------------------------------------------------------------------',
'# all files | 78.13 | 40.00 | 60.00 | ',
'# -----------------------------------------------------------------------------------------',
'# end of coverage report',
].join('\n');
@ -415,14 +427,18 @@ test('coverage with included files', skipIfNoInspector, () => {
const result = spawnSync(process.execPath, args);
const report = [
'# start of coverage report',
'# ' + '-'.repeat(112),
'# file | line % | branch % | funcs % | uncovered lines',
'# ' + '-'.repeat(112),
'# test/fixtures/test-runner/coverage.js | 78.65 | 38.46 | 60.00 | 12-13 16-22 27 39 43-44 61-62 66-67 71-72',
'# test/fixtures/v8-coverage/throw.js | 71.43 | 50.00 | 100.00 | 5-6',
'# ' + '-'.repeat(112),
'# all files | 78.13 | 40.00 | 60.00 |',
'# ' + '-'.repeat(112),
'# -----------------------------------------------------------------------------------------',
'# file | line % | branch % | funcs % | uncovered lines',
'# -----------------------------------------------------------------------------------------',
'# test | | | | ',
'# fixtures | | | | ',
'# test-runner | | | | ',
'# coverage.js | 78.65 | 38.46 | 60.00 | 12-13 16-22 27 39 43-44 61-62 66-67 71-72',
'# v8-coverage | | | | ',
'# throw.js | 71.43 | 50.00 | 100.00 | 5-6',
'# -----------------------------------------------------------------------------------------',
'# all files | 78.13 | 40.00 | 60.00 | ',
'# -----------------------------------------------------------------------------------------',
'# end of coverage report',
].join('\n');
@ -447,13 +463,16 @@ test('coverage with included and excluded files', skipIfNoInspector, () => {
const result = spawnSync(process.execPath, args);
const report = [
'# start of coverage report',
'# ' + '-'.repeat(112),
'# file | line % | branch % | funcs % | uncovered lines',
'# ' + '-'.repeat(112),
'# test/fixtures/test-runner/coverage.js | 78.65 | 38.46 | 60.00 | 12-13 16-22 27 39 43-44 61-62 66-67 71-72',
'# ' + '-'.repeat(112),
'# all files | 78.65 | 38.46 | 60.00 |',
'# ' + '-'.repeat(112),
'# -----------------------------------------------------------------------------------------',
'# file | line % | branch % | funcs % | uncovered lines',
'# -----------------------------------------------------------------------------------------',
'# test | | | | ',
'# fixtures | | | | ',
'# test-runner | | | | ',
'# coverage.js | 78.65 | 38.46 | 60.00 | 12-13 16-22 27 39 43-44 61-62 66-67 71-72',
'# -----------------------------------------------------------------------------------------',
'# all files | 78.65 | 38.46 | 60.00 | ',
'# -----------------------------------------------------------------------------------------',
'# end of coverage report',
].join('\n');
@ -473,8 +492,58 @@ test('properly accounts for line endings in source maps', skipIfNoInspector, ()
'--test', '--experimental-test-coverage', '--test-reporter', 'tap',
fixture,
];
const report = [
'# start of coverage report',
'# ----------------------------------------------------------------------------',
'# file | line % | branch % | funcs % | uncovered lines',
'# ----------------------------------------------------------------------------',
'# test | | | | ',
'# fixtures | | | | ',
'# test-runner | | | | ',
'# source-map-line-lengths | | | | ',
'# index.ts | 100.00 | 100.00 | 100.00 | ',
'# ----------------------------------------------------------------------------',
'# all files | 100.00 | 100.00 | 100.00 | ',
'# ----------------------------------------------------------------------------',
'# end of coverage report',
].join('\n');
const result = spawnSync(process.execPath, args);
const report = 'index.ts | 100.00 | 100.00 | 100.00 |';
assert.strictEqual(result.stderr.toString(), '');
assert(result.stdout.toString().includes(report));
assert.strictEqual(result.status, 0);
});
test('correctly prints the coverage report of files contained in parent directories', skipIfNoInspector, () => {
let report = [
'# start of coverage report',
'# --------------------------------------------------------------------------------------------',
'# file | line % | branch % | funcs % | uncovered lines',
'# --------------------------------------------------------------------------------------------',
'# .. | | | | ',
'# coverage.js | 78.65 | 38.46 | 60.00 | 12-13 16-22 27 39 43-44 61-62 66-67 71-72',
'# invalid-tap.js | 100.00 | 100.00 | 100.00 | ',
'# .. | | | | ',
'# v8-coverage | | | | ',
'# throw.js | 71.43 | 50.00 | 100.00 | 5-6',
'# --------------------------------------------------------------------------------------------',
'# all files | 78.35 | 43.75 | 60.00 | ',
'# --------------------------------------------------------------------------------------------',
'# end of coverage report',
].join('\n');
if (common.isWindows) {
report = report.replaceAll('/', '\\');
}
const fixture = fixtures.path('test-runner', 'coverage.js');
const args = [
'--test', '--experimental-test-coverage', '--test-reporter', 'tap', fixture,
];
const result = spawnSync(process.execPath, args, {
env: { ...process.env, NODE_TEST_TMPDIR: tmpdir.path },
cwd: fixtures.path('test-runner', 'coverage'),
});
assert.strictEqual(result.stderr.toString(), '');
assert(result.stdout.toString().includes(report));
assert.strictEqual(result.status, 0);

View File

@ -10,6 +10,11 @@ const skipForceColors =
process.config.variables.icu_gyp_path !== 'tools/icu/icu-generic.gyp' ||
process.config.variables.node_shared_openssl;
const canColorize = process.stderr?.isTTY && (
typeof process.stderr?.getColorDepth === 'function' ?
process.stderr?.getColorDepth() > 2 : true);
const skipCoverageColors = !canColorize;
function replaceTestDuration(str) {
return str
.replaceAll(/duration_ms: [0-9.]+/g, 'duration_ms: *')
@ -227,10 +232,19 @@ const tests = [
name: 'test-runner/output/test-diagnostic-warning-without-test-only-flag.js',
flags: ['--test', '--test-reporter=tap'],
},
process.features.inspector ? {
name: 'test-runner/output/coverage-width-40.mjs',
flags: ['--test-reporter=tap'],
} : false,
process.features.inspector ? {
name: 'test-runner/output/coverage-width-80.mjs',
flags: ['--test-reporter=tap'],
} : false,
process.features.inspector && !skipCoverageColors ? {
name: 'test-runner/output/coverage-width-80-color.mjs',
transform: specTransform,
tty: true
} : false,
process.features.inspector ? {
name: 'test-runner/output/coverage-width-100.mjs',
flags: ['--test-reporter=tap'],
@ -251,6 +265,11 @@ const tests = [
name: 'test-runner/output/coverage-width-100-uncovered-lines.mjs',
flags: ['--test-reporter=tap'],
} : false,
process.features.inspector && !skipCoverageColors ? {
name: 'test-runner/output/coverage-width-80-uncovered-lines-color.mjs',
transform: specTransform,
tty: true
} : false,
process.features.inspector ? {
name: 'test-runner/output/coverage-width-150-uncovered-lines.mjs',
flags: ['--test-reporter=tap'],