Skip to content

Commit 5d3754e

Browse files
committed
fix(test_runner): fix lint errors, update tests for statement coverage
- Replace non-ASCII em dash with ASCII in coverage.js comments - Remove disallowed string literals from assert.strictEqual() 3rd arg - Inline visitor object per review feedback - Add --test-coverage-statements to doc/node.1 manpage - Update coverage report strings in test files to include stmts % column
1 parent e1cf6c7 commit 5d3754e

File tree

7 files changed

+187
-184
lines changed

7 files changed

+187
-184
lines changed

doc/node.1

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1331,6 +1331,10 @@ files must meet \fBboth\fR criteria to be included in the coverage report.
13311331
Require a minimum percent of covered lines. If code coverage does not reach
13321332
the threshold specified, the process will exit with code \fB1\fR.
13331333
.
1334+
.It Fl -test-coverage-statements Ns = Ns Ar threshold
1335+
Require a minimum percent of covered statements. If code coverage does not reach
1336+
the threshold specified, the process will exit with code \fB1\fR.
1337+
.
13341338
.It Fl -test-force-exit
13351339
Configures the test runner to exit the process once all known tests have
13361340
finished executing even if the event loop would otherwise remain active.
@@ -2025,6 +2029,8 @@ one is included in the list below.
20252029
.It
20262030
\fB--test-coverage-lines\fR
20272031
.It
2032+
\fB--test-coverage-statements\fR
2033+
.It
20282034
\fB--test-global-setup\fR
20292035
.It
20302036
\fB--test-isolation\fR

lib/internal/test_runner/coverage.js

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@ class TestCoverage {
9696

9797
const statements = [];
9898

99-
// Parse as script with permissive flags script mode is non-strict,
99+
// Parse as script with permissive flags -- script mode is non-strict,
100100
// so it handles legacy CJS (e.g. `with` statements) while the
101101
// allow* flags enable ESM syntax (import/export/top-level await).
102102
let ast;
@@ -112,15 +112,14 @@ class TestCoverage {
112112
});
113113
} catch {
114114
// Acorn could not parse the file (e.g. non-JS syntax, TypeScript).
115-
// Degrade gracefully the file will report no statement coverage.
115+
// Degrade gracefully -- the file will report no statement coverage.
116116
this.#sourceStatements.set(fileUrl, null);
117117
return null;
118118
}
119119

120120
// acorn-walk's simple() fires a generic "Statement" visitor for every
121121
// node dispatched in a statement position (Program body, block bodies,
122-
// if/for/while bodies, etc.). This automatically covers all current and
123-
// future ESTree statement types without hardcoding a list.
122+
// if/for/while bodies, etc.).
124123
acornWalkSimple(ast, {
125124
__proto__: null,
126125
Statement(node) {
@@ -252,8 +251,9 @@ class TestCoverage {
252251
try {
253252
source = readFileSync(fileURLToPath(url), 'utf8');
254253
} catch {
255-
// The file can no longer be read. Skip it entirely.
256-
continue;
254+
// The file may not exist on disk (e.g. source-mapped files
255+
// whose content comes from sourcesContent). Fall through to
256+
// getLines which may already have it cached.
257257
}
258258

259259
const lines = this.getLines(url, source);

test/parallel/test-runner-coverage-default-exclusion.mjs

Lines changed: 26 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -24,18 +24,18 @@ describe('test runner coverage default exclusion', skipIfNoInspector, () => {
2424
it('should override default exclusion setting --test-coverage-exclude', async () => {
2525
const report = [
2626
'# start of coverage report',
27-
'# ---------------------------------------------------------------------------',
28-
'# file | line % | branch % | funcs % | uncovered lines',
29-
'# ---------------------------------------------------------------------------',
30-
'# file-test.js | 100.00 | 100.00 | 100.00 | ',
31-
'# file.test.mjs | 100.00 | 100.00 | 100.00 | ',
32-
'# logic-file.js | 66.67 | 100.00 | 50.00 | 5-7',
33-
'# test.cjs | 100.00 | 100.00 | 100.00 | ',
34-
'# test | | | | ',
35-
'# not-matching-test-name.js | 100.00 | 100.00 | 100.00 | ',
36-
'# ---------------------------------------------------------------------------',
37-
'# all files | 91.89 | 100.00 | 83.33 | ',
38-
'# ---------------------------------------------------------------------------',
27+
'# -------------------------------------------------------------------------------------',
28+
'# file | stmts % | line % | branch % | funcs % | uncovered lines',
29+
'# -------------------------------------------------------------------------------------',
30+
'# file-test.js | 100.00 | 100.00 | 100.00 | 100.00 | ',
31+
'# file.test.mjs | 100.00 | 100.00 | 100.00 | 100.00 | ',
32+
'# logic-file.js | 60.00 | 66.67 | 100.00 | 50.00 | 5-7',
33+
'# test.cjs | 100.00 | 100.00 | 100.00 | 100.00 | ',
34+
'# test | | | | | ',
35+
'# not-matching-test-name.js | 100.00 | 100.00 | 100.00 | 100.00 | ',
36+
'# -------------------------------------------------------------------------------------',
37+
'# all files | 90.91 | 91.89 | 100.00 | 83.33 | ',
38+
'# -------------------------------------------------------------------------------------',
3939
'# end of coverage report',
4040
].join('\n');
4141

@@ -60,13 +60,13 @@ describe('test runner coverage default exclusion', skipIfNoInspector, () => {
6060
it('should exclude test files from coverage by default', async () => {
6161
const report = [
6262
'# start of coverage report',
63-
'# --------------------------------------------------------------',
64-
'# file | line % | branch % | funcs % | uncovered lines',
65-
'# --------------------------------------------------------------',
66-
'# logic-file.js | 66.67 | 100.00 | 50.00 | 5-7',
67-
'# --------------------------------------------------------------',
68-
'# all files | 66.67 | 100.00 | 50.00 | ',
69-
'# --------------------------------------------------------------',
63+
'# ------------------------------------------------------------------------',
64+
'# file | stmts % | line % | branch % | funcs % | uncovered lines',
65+
'# ------------------------------------------------------------------------',
66+
'# logic-file.js | 60.00 | 66.67 | 100.00 | 50.00 | 5-7',
67+
'# ------------------------------------------------------------------------',
68+
'# all files | 60.00 | 66.67 | 100.00 | 50.00 | ',
69+
'# ------------------------------------------------------------------------',
7070
'# end of coverage report',
7171
].join('\n');
7272

@@ -89,13 +89,13 @@ describe('test runner coverage default exclusion', skipIfNoInspector, () => {
8989
it('should exclude ts test files', async () => {
9090
const report = [
9191
'# start of coverage report',
92-
'# --------------------------------------------------------------',
93-
'# file | line % | branch % | funcs % | uncovered lines',
94-
'# --------------------------------------------------------------',
95-
'# logic-file.js | 66.67 | 100.00 | 50.00 | 5-7',
96-
'# --------------------------------------------------------------',
97-
'# all files | 66.67 | 100.00 | 50.00 | ',
98-
'# --------------------------------------------------------------',
92+
'# ------------------------------------------------------------------------',
93+
'# file | stmts % | line % | branch % | funcs % | uncovered lines',
94+
'# ------------------------------------------------------------------------',
95+
'# logic-file.js | 60.00 | 66.67 | 100.00 | 50.00 | 5-7',
96+
'# ------------------------------------------------------------------------',
97+
'# all files | 60.00 | 66.67 | 100.00 | 50.00 | ',
98+
'# ------------------------------------------------------------------------',
9999
'# end of coverage report',
100100
].join('\n');
101101

test/parallel/test-runner-coverage-source-map.js

Lines changed: 31 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -31,16 +31,16 @@ const flags = [
3131
describe('Coverage with source maps', async () => {
3232
await it('should work with source maps', async (t) => {
3333
const report = generateReport([
34-
'# --------------------------------------------------------------',
35-
'# file | line % | branch % | funcs % | uncovered lines',
36-
'# --------------------------------------------------------------',
37-
'# a.test.ts | 53.85 | 100.00 | 100.00 | 8-13', // part of a bundle
38-
'# b.test.ts | 55.56 | 100.00 | 100.00 | 1 7-9', // part of a bundle
39-
'# index.test.js | 71.43 | 66.67 | 100.00 | 6-7', // no source map
40-
'# stdin.test.ts | 57.14 | 100.00 | 100.00 | 4-6', // Source map without original file
41-
'# --------------------------------------------------------------',
42-
'# all files | 58.33 | 87.50 | 100.00 | ',
43-
'# --------------------------------------------------------------',
34+
'# ------------------------------------------------------------------------',
35+
'# file | stmts % | line % | branch % | funcs % | uncovered lines',
36+
'# ------------------------------------------------------------------------',
37+
'# a.test.ts | 37.50 | 53.85 | 100.00 | 100.00 | 8-13', // part of a bundle
38+
'# b.test.ts | 28.57 | 55.56 | 100.00 | 100.00 | 1 7-9', // part of a bundle
39+
'# index.test.js | 80.00 | 71.43 | 66.67 | 100.00 | 6-7', // no source map
40+
'# stdin.test.ts | 100.00 | 57.14 | 100.00 | 100.00 | 4-6', // Source map without original file
41+
'# ------------------------------------------------------------------------',
42+
'# all files | 45.00 | 58.33 | 87.50 | 100.00 | ',
43+
'# ------------------------------------------------------------------------',
4444
]);
4545

4646
const spawned = await common.spawnPromisified(process.execPath, flags, {
@@ -54,15 +54,15 @@ describe('Coverage with source maps', async () => {
5454

5555
await it('should only work with --enable-source-maps', async (t) => {
5656
const report = generateReport([
57-
'# --------------------------------------------------------------',
58-
'# file | line % | branch % | funcs % | uncovered lines',
59-
'# --------------------------------------------------------------',
60-
'# a.test.mjs | 100.00 | 100.00 | 100.00 | ',
61-
'# index.test.js | 71.43 | 66.67 | 100.00 | 6-7',
62-
'# stdin.test.js | 100.00 | 100.00 | 100.00 | ',
63-
'# --------------------------------------------------------------',
64-
'# all files | 85.71 | 87.50 | 100.00 | ',
65-
'# --------------------------------------------------------------',
57+
'# ------------------------------------------------------------------------',
58+
'# file | stmts % | line % | branch % | funcs % | uncovered lines',
59+
'# ------------------------------------------------------------------------',
60+
'# a.test.mjs | 100.00 | 100.00 | 100.00 | 100.00 | ',
61+
'# index.test.js | 80.00 | 71.43 | 66.67 | 100.00 | 6-7',
62+
'# stdin.test.js | 100.00 | 100.00 | 100.00 | 100.00 | ',
63+
'# ------------------------------------------------------------------------',
64+
'# all files | 92.31 | 85.71 | 87.50 | 100.00 | ',
65+
'# ------------------------------------------------------------------------',
6666
]);
6767

6868
const spawned = await common.spawnPromisified(process.execPath, flags.slice(1), {
@@ -75,18 +75,18 @@ describe('Coverage with source maps', async () => {
7575

7676
await it('properly accounts for line endings in source maps', async (t) => {
7777
const report = generateReport([
78-
'# ------------------------------------------------------------------',
79-
'# file | line % | branch % | funcs % | uncovered lines',
80-
'# ------------------------------------------------------------------',
81-
'# test | | | | ',
82-
'# fixtures | | | | ',
83-
'# test-runner | | | | ',
84-
'# source-maps | | | | ',
85-
'# line-lengths | | | | ',
86-
'# index.ts | 100.00 | 100.00 | 100.00 | ',
87-
'# ------------------------------------------------------------------',
88-
'# all files | 100.00 | 100.00 | 100.00 | ',
89-
'# ------------------------------------------------------------------',
78+
'# ----------------------------------------------------------------------------',
79+
'# file | stmts % | line % | branch % | funcs % | uncovered lines',
80+
'# ----------------------------------------------------------------------------',
81+
'# test | | | | | ',
82+
'# fixtures | | | | | ',
83+
'# test-runner | | | | | ',
84+
'# source-maps | | | | | ',
85+
'# line-lengths | | | | | ',
86+
'# index.ts | 100.00 | 100.00 | 100.00 | 100.00 | ',
87+
'# ----------------------------------------------------------------------------',
88+
'# all files | 100.00 | 100.00 | 100.00 | 100.00 | ',
89+
'# ----------------------------------------------------------------------------',
9090
]);
9191

9292
const spawned = await common.spawnPromisified(process.execPath, [

test/parallel/test-runner-coverage-statements.js

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -227,12 +227,9 @@ test('unparseable files degrade gracefully to zero statements', () => {
227227
// The file uses top-level `using` which is valid at runtime (CJS wrapper)
228228
// but acorn cannot parse as sourceType:'script'. Statement coverage
229229
// degrades to 0 total statements while other metrics still work.
230-
assert.strictEqual(file.totalStatementCount, 0,
231-
'unparseable file should have 0 statements');
232-
assert.strictEqual(file.coveredStatementCount, 0,
233-
'unparseable file should have 0 covered statements');
234-
assert.strictEqual(file.coveredStatementPercent, 100,
235-
'unparseable file should degrade to 100% statement coverage');
230+
assert.strictEqual(file.totalStatementCount, 0);
231+
assert.strictEqual(file.coveredStatementCount, 0);
232+
assert.strictEqual(file.coveredStatementPercent, 100);
236233
assert.ok(Array.isArray(file.statements) && file.statements.length === 0,
237234
'unparseable file should have empty statements array');
238235

test/parallel/test-runner-coverage-thresholds.js

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,19 +22,19 @@ function findCoverageFileForPid(pid) {
2222
function getTapCoverageFixtureReport() {
2323
const report = [
2424
'# start of coverage report',
25-
'# --------------------------------------------------------------------------------------------------------',
25+
'# ------------------------------------------------------------------------------------------------------',
2626
'# file | stmts % | line % | branch % | funcs % | uncovered lines',
27-
'# --------------------------------------------------------------------------------------------------------',
27+
'# ------------------------------------------------------------------------------------------------------',
2828
'# test | | | | | ',
2929
'# fixtures | | | | | ',
3030
'# test-runner | | | | | ',
3131
'# coverage.js | 75.00 | 78.65 | 38.46 | 60.00 | 12-13 16-22 27 39 43-44 61-62 66-67 71-72',
3232
'# invalid-tap.js | 100.00 | 100.00 | 100.00 | 100.00 | ',
3333
'# v8-coverage | | | | | ',
3434
'# throw.js | 80.00 | 71.43 | 50.00 | 100.00 | 5-6',
35-
'# --------------------------------------------------------------------------------------------------------',
35+
'# ------------------------------------------------------------------------------------------------------',
3636
'# all files | 76.00 | 78.35 | 43.75 | 60.00 | ',
37-
'# --------------------------------------------------------------------------------------------------------',
37+
'# ------------------------------------------------------------------------------------------------------',
3838
'# end of coverage report',
3939
].join('\n');
4040

0 commit comments

Comments
 (0)