Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 1daec9a

Browse filesBrowse files
pmarchinitargos
authored andcommitted
test_runner: avoid coverage report partial file names
Co-author: Medhansh404 <21ucs126@lnmiit.ac.in> PR-URL: #54379 Fixes: #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>
1 parent c8b7a64 commit 1daec9a
Copy full SHA for 1daec9a
Expand file treeCollapse file tree

19 files changed

+544
-156
lines changed
Open diff view settings
Collapse file

‎lib/internal/test_runner/utils.js‎

Copy file name to clipboardExpand all lines: lib/internal/test_runner/utils.js
+118-37Lines changed: 118 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
'use strict';
22
const {
33
ArrayPrototypeFlatMap,
4+
ArrayPrototypeForEach,
45
ArrayPrototypeJoin,
56
ArrayPrototypeMap,
7+
ArrayPrototypePop,
68
ArrayPrototypePush,
79
ArrayPrototypeReduce,
810
ArrayPrototypeSome,
@@ -24,7 +26,7 @@ const {
2426
} = primordials;
2527

2628
const { AsyncResource } = require('async_hooks');
27-
const { relative } = require('path');
29+
const { relative, sep } = require('path');
2830
const { createWriteStream } = require('fs');
2931
const { pathToFileURL } = require('internal/url');
3032
const { createDeferredPromise } = require('internal/util');
@@ -409,6 +411,36 @@ const kColumns = ['line %', 'branch %', 'funcs %'];
409411
const kColumnsKeys = ['coveredLinePercent', 'coveredBranchPercent', 'coveredFunctionPercent'];
410412
const kSeparator = ' | ';
411413

414+
function buildFileTree(summary) {
415+
const tree = { __proto__: null };
416+
let treeDepth = 1;
417+
let longestFile = 0;
418+
419+
ArrayPrototypeForEach(summary.files, (file) => {
420+
let longestPart = 0;
421+
const parts = StringPrototypeSplit(relative(summary.workingDirectory, file.path), sep);
422+
let current = tree;
423+
424+
ArrayPrototypeForEach(parts, (part, index) => {
425+
if (!current[part]) {
426+
current[part] = { __proto__: null };
427+
}
428+
current = current[part];
429+
// If this is the last part, add the file to the tree
430+
if (index === parts.length - 1) {
431+
current.file = file;
432+
}
433+
// Keep track of the longest part for padding
434+
longestPart = MathMax(longestPart, part.length);
435+
});
436+
437+
treeDepth = MathMax(treeDepth, parts.length);
438+
longestFile = MathMax(longestPart, longestFile);
439+
});
440+
441+
return { __proto__: null, tree, treeDepth, longestFile };
442+
}
443+
412444
function getCoverageReport(pad, summary, symbol, color, table) {
413445
const prefix = `${pad}${symbol}`;
414446
let report = `${color}${prefix}start of coverage report\n`;
@@ -418,11 +450,19 @@ function getCoverageReport(pad, summary, symbol, color, table) {
418450
let uncoveredLinesPadLength;
419451
let tableWidth;
420452

453+
// Create a tree of file paths
454+
const { tree, treeDepth, longestFile } = buildFileTree(summary);
421455
if (table) {
422-
// Get expected column sizes
423-
filePadLength = table && ArrayPrototypeReduce(summary.files, (acc, file) =>
424-
MathMax(acc, relative(summary.workingDirectory, file.path).length), 0);
456+
// Calculate expected column sizes based on the tree
457+
filePadLength = table && longestFile;
458+
filePadLength += (treeDepth - 1);
459+
if (color) {
460+
filePadLength += 2;
461+
}
425462
filePadLength = MathMax(filePadLength, 'file'.length);
463+
if (filePadLength > (process.stdout.columns / 2)) {
464+
filePadLength = MathFloor(process.stdout.columns / 2);
465+
}
426466
const fileWidth = filePadLength + 2;
427467

428468
columnPadLengths = ArrayPrototypeMap(kColumns, (column) => (table ? MathMax(column.length, 6) : 0));
@@ -435,26 +475,17 @@ function getCoverageReport(pad, summary, symbol, color, table) {
435475

436476
tableWidth = fileWidth + columnsWidth + uncoveredLinesWidth;
437477

438-
// Fit with sensible defaults
439478
const availableWidth = (process.stdout.columns || Infinity) - prefix.length;
440479
const columnsExtras = tableWidth - availableWidth;
441480
if (table && columnsExtras > 0) {
442-
// Ensure file name is sufficiently visible
443-
const minFilePad = MathMin(8, filePadLength);
444-
filePadLength -= MathFloor(columnsExtras * 0.2);
445-
filePadLength = MathMax(filePadLength, minFilePad);
446-
447-
// Get rest of available space, subtracting margins
481+
filePadLength = MathMin(availableWidth * 0.5, filePadLength);
448482
uncoveredLinesPadLength = MathMax(availableWidth - columnsWidth - (filePadLength + 2) - 2, 1);
449-
450-
// Update table width
451483
tableWidth = availableWidth;
452484
} else {
453485
uncoveredLinesPadLength = Infinity;
454486
}
455487
}
456488

457-
458489
function getCell(string, width, pad, truncate, coverage) {
459490
if (!table) return string;
460491

@@ -469,35 +500,85 @@ function getCoverageReport(pad, summary, symbol, color, table) {
469500
return result;
470501
}
471502

472-
// Head
473-
if (table) report += addTableLine(prefix, tableWidth);
474-
report += `${prefix}${getCell('file', filePadLength, StringPrototypePadEnd, truncateEnd)}${kSeparator}` +
475-
`${ArrayPrototypeJoin(ArrayPrototypeMap(kColumns, (column, i) => getCell(column, columnPadLengths[i], StringPrototypePadStart)), kSeparator)}${kSeparator}` +
476-
`${getCell('uncovered lines', uncoveredLinesPadLength, false, truncateEnd)}\n`;
477-
if (table) report += addTableLine(prefix, tableWidth);
503+
function writeReportLine({ file, depth = 0, coveragesColumns, fileCoverage, uncoveredLines }) {
504+
const fileColumn = `${prefix}${StringPrototypeRepeat(' ', depth)}${getCell(file, filePadLength - depth, StringPrototypePadEnd, truncateStart, fileCoverage)}`;
505+
const coverageColumns = ArrayPrototypeJoin(ArrayPrototypeMap(coveragesColumns, (coverage, j) => {
506+
const coverageText = typeof coverage === 'number' ? NumberPrototypeToFixed(coverage, 2) : coverage;
507+
return getCell(coverageText, columnPadLengths[j], StringPrototypePadStart, false, coverage);
508+
}), kSeparator);
478509

479-
// Body
480-
for (let i = 0; i < summary.files.length; ++i) {
481-
const file = summary.files[i];
482-
const relativePath = relative(summary.workingDirectory, file.path);
510+
const uncoveredLinesColumn = getCell(uncoveredLines, uncoveredLinesPadLength, false, truncateEnd);
483511

484-
let fileCoverage = 0;
485-
const coverages = ArrayPrototypeMap(kColumnsKeys, (columnKey) => {
486-
const percent = file[columnKey];
487-
fileCoverage += percent;
488-
return percent;
489-
});
490-
fileCoverage /= kColumnsKeys.length;
512+
return `${fileColumn}${kSeparator}${coverageColumns}${kSeparator}${uncoveredLinesColumn}\n`;
513+
}
491514

492-
report += `${prefix}${getCell(relativePath, filePadLength, StringPrototypePadEnd, truncateStart, fileCoverage)}${kSeparator}` +
493-
`${ArrayPrototypeJoin(ArrayPrototypeMap(coverages, (coverage, j) => getCell(NumberPrototypeToFixed(coverage, 2), columnPadLengths[j], StringPrototypePadStart, false, coverage)), kSeparator)}${kSeparator}` +
494-
`${getCell(formatUncoveredLines(getUncoveredLines(file.lines), table), uncoveredLinesPadLength, false, truncateEnd)}\n`;
515+
function printCoverageBodyTree(tree, depth = 0) {
516+
for (const key in tree) {
517+
if (tree[key].file) {
518+
const file = tree[key].file;
519+
const fileName = ArrayPrototypePop(StringPrototypeSplit(file.path, sep));
520+
521+
let fileCoverage = 0;
522+
const coverages = ArrayPrototypeMap(kColumnsKeys, (columnKey) => {
523+
const percent = file[columnKey];
524+
fileCoverage += percent;
525+
return percent;
526+
});
527+
fileCoverage /= kColumnsKeys.length;
528+
529+
const uncoveredLines = formatUncoveredLines(getUncoveredLines(file.lines), table);
530+
531+
report += writeReportLine({
532+
__proto__: null,
533+
file: fileName,
534+
depth: depth,
535+
coveragesColumns: coverages,
536+
fileCoverage: fileCoverage,
537+
uncoveredLines: uncoveredLines,
538+
});
539+
} else {
540+
report += writeReportLine({
541+
__proto__: null,
542+
file: key,
543+
depth: depth,
544+
coveragesColumns: ArrayPrototypeMap(columnPadLengths, () => ''),
545+
fileCoverage: undefined,
546+
uncoveredLines: '',
547+
});
548+
printCoverageBodyTree(tree[key], depth + 1);
549+
}
550+
}
495551
}
496552

497-
// Foot
553+
// -------------------------- Coverage Report --------------------------
554+
if (table) report += addTableLine(prefix, tableWidth);
555+
556+
// Print the header
557+
report += writeReportLine({
558+
__proto__: null,
559+
file: 'file',
560+
coveragesColumns: kColumns,
561+
fileCoverage: undefined,
562+
uncoveredLines: 'uncovered lines',
563+
});
564+
565+
if (table) report += addTableLine(prefix, tableWidth);
566+
567+
// Print the body
568+
printCoverageBodyTree(tree);
569+
498570
if (table) report += addTableLine(prefix, tableWidth);
499-
report += `${prefix}${getCell('all files', filePadLength, StringPrototypePadEnd, truncateEnd)}${kSeparator}` +
500-
`${ArrayPrototypeJoin(ArrayPrototypeMap(kColumnsKeys, (columnKey, j) => getCell(NumberPrototypeToFixed(summary.totals[columnKey], 2), columnPadLengths[j], StringPrototypePadStart, false, summary.totals[columnKey])), kSeparator)} |\n`;
571+
572+
// Print the footer
573+
const allFilesCoverages = ArrayPrototypeMap(kColumnsKeys, (columnKey) => summary.totals[columnKey]);
574+
report += writeReportLine({
575+
__proto__: null,
576+
file: 'all files',
577+
coveragesColumns: allFilesCoverages,
578+
fileCoverage: undefined,
579+
uncoveredLines: '',
580+
});
581+
501582
if (table) report += addTableLine(prefix, tableWidth);
502583

503584
report += `${prefix}end of coverage report\n`;
Collapse file
+52Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
'use strict';
2+
// Here we can't import common module as the coverage will be different based on the system
3+
4+
// Empty functions that don't do anything
5+
function doNothing1() {
6+
// Not implemented
7+
}
8+
9+
function doNothing2() {
10+
// No logic here
11+
}
12+
13+
function unusedFunction1() {
14+
// Intentionally left empty
15+
}
16+
17+
function unusedFunction2() {
18+
// Another empty function
19+
}
20+
21+
// Unused variables
22+
const unusedVariable1 = 'This is never used';
23+
const unusedVariable2 = 42;
24+
let unusedVariable3;
25+
26+
// Empty class with no methods
27+
class UnusedClass {
28+
constructor() {
29+
// Constructor does nothing
30+
}
31+
}
32+
33+
// Empty object literal
34+
const emptyObject = {};
35+
36+
// Empty array
37+
const emptyArray = [];
38+
39+
// Function with parameters but no body
40+
function doNothingWithParams(param1, param2) {
41+
// No implementation
42+
}
43+
44+
// Function that returns nothing
45+
function returnsNothing() {
46+
// No return statement
47+
}
48+
49+
// Another unused function
50+
function unusedFunction3() {
51+
// More empty code
52+
}
Collapse file

‎test/fixtures/test-runner/output/coverage-width-100-uncovered-lines.snapshot‎

Copy file name to clipboardExpand all lines: test/fixtures/test-runner/output/coverage-width-100-uncovered-lines.snapshot
+11-6Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -15,13 +15,18 @@ ok 1 - Coverage Print Fixed Width 100
1515
# duration_ms *
1616
# start of coverage report
1717
# --------------------------------------------------------------------------------------------------
18-
# file | line % | branch % | funcs % | uncovered lines
18+
# file | line % | branch % | funcs % | uncovered lines
1919
# --------------------------------------------------------------------------------------------------
20-
# …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
21-
# …ap/b.js | 45.45 | 100.00 | 0.00 | 5-7 9-11
22-
# …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…
23-
# …nes.mjs | 100.00 | 100.00 | 100.00 |
20+
# test | | | |
21+
# fixtures | | | |
22+
# test-runner | | | |
23+
# coverage-snap | | | |
24+
# a.js | 55.77 | 100.00 | 0.00 | 5-7 9-11 13-15 17-19 …
25+
# b.js | 45.45 | 100.00 | 0.00 | 5-7 9-11
26+
# many-uncovered-lines.js | 50.99 | 42.86 | 1.92 | 5-7 9-11 13-15 17-19 …
27+
# output | | | |
28+
# coverage-width-100-uncovered-lines.mjs | 100.00 | 100.00 | 100.00 |
2429
# --------------------------------------------------------------------------------------------------
25-
# all fil… | 52.80 | 60.00 | 1.61 |
30+
# all files | 52.80 | 60.00 | 1.61 |
2631
# --------------------------------------------------------------------------------------------------
2732
# end of coverage report
Collapse file

‎test/fixtures/test-runner/output/coverage-width-100.snapshot‎

Copy file name to clipboardExpand all lines: test/fixtures/test-runner/output/coverage-width-100.snapshot
+10-5Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,12 +15,17 @@ ok 1 - Coverage Print Fixed Width 100
1515
# duration_ms *
1616
# start of coverage report
1717
# --------------------------------------------------------------------------------------------------
18-
# file | line % | branch % | funcs % | uncovered lines
18+
# file | line % | branch % | funcs % | uncovered lines
1919
# --------------------------------------------------------------------------------------------------
20-
# test/fixtures/test-runner/coverage-snap/a.js | 55.77 | 100.00 | 0.00 | 5-7 9-11 13-15 …
21-
# test/fixtures/test-runner/coverage-snap/b.js | 45.45 | 100.00 | 0.00 | 5-7 9-11
22-
# …tures/test-runner/output/coverage-width-100.mjs | 100.00 | 100.00 | 100.00 |
20+
# test | | | |
21+
# fixtures | | | |
22+
# test-runner | | | |
23+
# coverage-snap | | | |
24+
# a.js | 55.77 | 100.00 | 0.00 | 5-7 9-11 13-15 17-19 29-30 40-42 45-4…
25+
# b.js | 45.45 | 100.00 | 0.00 | 5-7 9-11
26+
# output | | | |
27+
# coverage-width-100.mjs | 100.00 | 100.00 | 100.00 |
2328
# --------------------------------------------------------------------------------------------------
24-
# all files | 60.81 | 100.00 | 0.00 |
29+
# all files | 60.81 | 100.00 | 0.00 |
2530
# --------------------------------------------------------------------------------------------------
2631
# end of coverage report
Collapse file

‎test/fixtures/test-runner/output/coverage-width-150-uncovered-lines.snapshot‎

Copy file name to clipboardExpand all lines: test/fixtures/test-runner/output/coverage-width-150-uncovered-lines.snapshot
+11-6Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -15,13 +15,18 @@ ok 1 - Coverage Print Fixed Width 150
1515
# duration_ms *
1616
# start of coverage report
1717
# ----------------------------------------------------------------------------------------------------------------------------------------------------
18-
# file | line % | branch % | funcs % | uncovered lines
18+
# file | line % | branch % | funcs % | uncovered lines
1919
# ----------------------------------------------------------------------------------------------------------------------------------------------------
20-
# …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
21-
# …ap/b.js | 45.45 | 100.00 | 0.00 | 5-7 9-11
22-
# …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 …
23-
# …nes.mjs | 100.00 | 100.00 | 100.00 |
20+
# test | | | |
21+
# fixtures | | | |
22+
# test-runner | | | |
23+
# coverage-snap | | | |
24+
# a.js | 55.77 | 100.00 | 0.00 | 5-7 9-11 13-15 17-19 29-30 40-42 45-47 50-52
25+
# b.js | 45.45 | 100.00 | 0.00 | 5-7 9-11
26+
# 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…
27+
# output | | | |
28+
# coverage-width-150-uncovered-lines.mjs | 100.00 | 100.00 | 100.00 |
2429
# ----------------------------------------------------------------------------------------------------------------------------------------------------
25-
# all fil… | 52.80 | 60.00 | 1.61 |
30+
# all files | 52.80 | 60.00 | 1.61 |
2631
# ----------------------------------------------------------------------------------------------------------------------------------------------------
2732
# end of coverage report
Collapse file

‎test/fixtures/test-runner/output/coverage-width-150.snapshot‎

Copy file name to clipboardExpand all lines: test/fixtures/test-runner/output/coverage-width-150.snapshot
+14-9Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -14,13 +14,18 @@ ok 1 - Coverage Print Fixed Width 150
1414
# todo 0
1515
# duration_ms *
1616
# start of coverage report
17-
# -------------------------------------------------------------------------------------------------------------------------------------
18-
# file | line % | branch % | funcs % | uncovered lines
19-
# -------------------------------------------------------------------------------------------------------------------------------------
20-
# 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
21-
# test/fixtures/test-runner/coverage-snap/b.js | 45.45 | 100.00 | 0.00 | 5-7 9-11
22-
# test/fixtures/test-runner/output/coverage-width-150.mjs | 100.00 | 100.00 | 100.00 |
23-
# -------------------------------------------------------------------------------------------------------------------------------------
24-
# all files | 60.81 | 100.00 | 0.00 |
25-
# -------------------------------------------------------------------------------------------------------------------------------------
17+
# --------------------------------------------------------------------------------------------------------
18+
# file | line % | branch % | funcs % | uncovered lines
19+
# --------------------------------------------------------------------------------------------------------
20+
# test | | | |
21+
# fixtures | | | |
22+
# test-runner | | | |
23+
# coverage-snap | | | |
24+
# a.js | 55.77 | 100.00 | 0.00 | 5-7 9-11 13-15 17-19 29-30 40-42 45-47 50-52
25+
# b.js | 45.45 | 100.00 | 0.00 | 5-7 9-11
26+
# output | | | |
27+
# coverage-width-150.mjs | 100.00 | 100.00 | 100.00 |
28+
# --------------------------------------------------------------------------------------------------------
29+
# all files | 60.81 | 100.00 | 0.00 |
30+
# --------------------------------------------------------------------------------------------------------
2631
# end of coverage report
Collapse file
+12Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
// Flags: --experimental-test-coverage
2+
// here we can't import common module as the coverage will be different based on the system
3+
// Unused imports are here in order to populate the coverage report
4+
import * as a from '../coverage-snap/b.js';
5+
import * as b from '../coverage-snap/a.js';
6+
import * as c from '../coverage-snap/a-very-long-long-long-sub-dir/c.js';
7+
8+
import { test } from 'node:test';
9+
10+
process.stdout.columns = 40;
11+
12+
test(`Coverage Print Fixed Width ${process.stdout.columns}`);

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.