@rezless/vitest 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +202 -0
- package/NOTICE +32 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +140 -0
- package/dist/cli.js.map +1 -0
- package/dist/coverage-aggregate.d.ts +22 -0
- package/dist/coverage-aggregate.d.ts.map +1 -0
- package/dist/coverage-aggregate.js +65 -0
- package/dist/coverage-aggregate.js.map +1 -0
- package/dist/coverage-config.d.ts +10 -0
- package/dist/coverage-config.d.ts.map +1 -0
- package/dist/coverage-config.js +12 -0
- package/dist/coverage-config.js.map +1 -0
- package/dist/coverage-registry.d.ts +13 -0
- package/dist/coverage-registry.d.ts.map +1 -0
- package/dist/coverage-registry.js +111 -0
- package/dist/coverage-registry.js.map +1 -0
- package/dist/coverage-setup.d.ts +25 -0
- package/dist/coverage-setup.d.ts.map +1 -0
- package/dist/coverage-setup.js +42 -0
- package/dist/coverage-setup.js.map +1 -0
- package/dist/format/console.d.ts +7 -0
- package/dist/format/console.d.ts.map +1 -0
- package/dist/format/console.js +93 -0
- package/dist/format/console.js.map +1 -0
- package/dist/format/html.d.ts +11 -0
- package/dist/format/html.d.ts.map +1 -0
- package/dist/format/html.js +291 -0
- package/dist/format/html.js.map +1 -0
- package/dist/format/istanbul.d.ts +47 -0
- package/dist/format/istanbul.d.ts.map +1 -0
- package/dist/format/istanbul.js +50 -0
- package/dist/format/istanbul.js.map +1 -0
- package/dist/format/lcov.d.ts +19 -0
- package/dist/format/lcov.d.ts.map +1 -0
- package/dist/format/lcov.js +74 -0
- package/dist/format/lcov.js.map +1 -0
- package/dist/format/summary.d.ts +25 -0
- package/dist/format/summary.d.ts.map +1 -0
- package/dist/format/summary.js +48 -0
- package/dist/format/summary.js.map +1 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +10 -0
- package/dist/index.js.map +1 -0
- package/dist/loadLinkset.d.ts +38 -0
- package/dist/loadLinkset.d.ts.map +1 -0
- package/dist/loadLinkset.js +77 -0
- package/dist/loadLinkset.js.map +1 -0
- package/dist/loadScript.d.ts +24 -0
- package/dist/loadScript.d.ts.map +1 -0
- package/dist/loadScript.js +45 -0
- package/dist/loadScript.js.map +1 -0
- package/dist/matchers.d.ts +34 -0
- package/dist/matchers.d.ts.map +1 -0
- package/dist/matchers.js +120 -0
- package/dist/matchers.js.map +1 -0
- package/dist/reporter.d.ts +82 -0
- package/dist/reporter.d.ts.map +1 -0
- package/dist/reporter.js +166 -0
- package/dist/reporter.js.map +1 -0
- package/package.json +69 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"coverage-registry.js","sourceRoot":"","sources":["../src/coverage-registry.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Vitest setup file that runs in every test worker. Registers a top-level
|
|
3
|
+
* `afterAll` hook so each test file drains its accumulated coverage
|
|
4
|
+
* snapshots to disk before the worker finishes the file.
|
|
5
|
+
*
|
|
6
|
+
* Relying on `process.on('exit')` alone is not reliable under Vitest's
|
|
7
|
+
* thread pool: the main process can finish reporting before the worker's
|
|
8
|
+
* exit hooks fire (and thread workers may stay warm across files). This
|
|
9
|
+
* setup file pulls coverage at known points in the test lifecycle, which
|
|
10
|
+
* the reporter can read deterministically at end-of-run.
|
|
11
|
+
*
|
|
12
|
+
* The reporter wires this file in via `vitest.config.setupFiles` when it
|
|
13
|
+
* activates; users don't have to import it themselves.
|
|
14
|
+
*
|
|
15
|
+
* Caveat — `test: { isolate: false }`: with isolation off, Vitest reuses
|
|
16
|
+
* the same module graph across test files in a worker, so this setup
|
|
17
|
+
* file is evaluated once and the `afterAll` registers exactly once — for
|
|
18
|
+
* the first file's root suite only. Later files' coverage then has to
|
|
19
|
+
* fall back to the `process.on('exit')` handler in
|
|
20
|
+
* `coverage-registry.ts`, which under the thread pool fires after
|
|
21
|
+
* `onTestRunEnd` and may be missing from the rendered report. If full
|
|
22
|
+
* LSL coverage matters with `isolate: false`, prefer `pool: 'forks'`.
|
|
23
|
+
*/
|
|
24
|
+
export {};
|
|
25
|
+
//# sourceMappingURL=coverage-setup.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"coverage-setup.d.ts","sourceRoot":"","sources":["../src/coverage-setup.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Vitest setup file that runs in every test worker. Registers a top-level
|
|
3
|
+
* `afterAll` hook so each test file drains its accumulated coverage
|
|
4
|
+
* snapshots to disk before the worker finishes the file.
|
|
5
|
+
*
|
|
6
|
+
* Relying on `process.on('exit')` alone is not reliable under Vitest's
|
|
7
|
+
* thread pool: the main process can finish reporting before the worker's
|
|
8
|
+
* exit hooks fire (and thread workers may stay warm across files). This
|
|
9
|
+
* setup file pulls coverage at known points in the test lifecycle, which
|
|
10
|
+
* the reporter can read deterministically at end-of-run.
|
|
11
|
+
*
|
|
12
|
+
* The reporter wires this file in via `vitest.config.setupFiles` when it
|
|
13
|
+
* activates; users don't have to import it themselves.
|
|
14
|
+
*
|
|
15
|
+
* Caveat — `test: { isolate: false }`: with isolation off, Vitest reuses
|
|
16
|
+
* the same module graph across test files in a worker, so this setup
|
|
17
|
+
* file is evaluated once and the `afterAll` registers exactly once — for
|
|
18
|
+
* the first file's root suite only. Later files' coverage then has to
|
|
19
|
+
* fall back to the `process.on('exit')` handler in
|
|
20
|
+
* `coverage-registry.ts`, which under the thread pool fires after
|
|
21
|
+
* `onTestRunEnd` and may be missing from the rendered report. If full
|
|
22
|
+
* LSL coverage matters with `isolate: false`, prefer `pool: 'forks'`.
|
|
23
|
+
*/
|
|
24
|
+
import { afterAll } from 'vitest';
|
|
25
|
+
import * as fs from 'node:fs';
|
|
26
|
+
import * as path from 'node:path';
|
|
27
|
+
import { drainSnapshots } from './coverage-registry.js';
|
|
28
|
+
afterAll(() => {
|
|
29
|
+
const reports = drainSnapshots();
|
|
30
|
+
if (reports.length === 0)
|
|
31
|
+
return;
|
|
32
|
+
try {
|
|
33
|
+
const dir = process.env['LSL_COVERAGE_DIR'] ?? path.join(process.cwd(), '.rezless-coverage');
|
|
34
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
35
|
+
const file = path.join(dir, `${process.pid}-${Date.now()}-${Math.random().toString(36).slice(2, 8)}.json`);
|
|
36
|
+
fs.writeFileSync(file, JSON.stringify(reports));
|
|
37
|
+
}
|
|
38
|
+
catch {
|
|
39
|
+
// afterAll failures shouldn't break the test run; coverage is best-effort.
|
|
40
|
+
}
|
|
41
|
+
});
|
|
42
|
+
//# sourceMappingURL=coverage-setup.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"coverage-setup.js","sourceRoot":"","sources":["../src/coverage-setup.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAEH,OAAO,EAAE,QAAQ,EAAE,MAAM,QAAQ,CAAA;AACjC,OAAO,KAAK,EAAE,MAAM,SAAS,CAAA;AAC7B,OAAO,KAAK,IAAI,MAAM,WAAW,CAAA;AACjC,OAAO,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAA;AAEvD,QAAQ,CAAC,GAAG,EAAE;IACZ,MAAM,OAAO,GAAG,cAAc,EAAE,CAAA;IAChC,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC;QAAE,OAAM;IAChC,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC,kBAAkB,CAAC,IAAI,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,mBAAmB,CAAC,CAAA;QAC5F,EAAE,CAAC,SAAS,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAA;QACtC,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CACpB,GAAG,EACH,GAAG,OAAO,CAAC,GAAG,IAAI,IAAI,CAAC,GAAG,EAAE,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,OAAO,CAC9E,CAAA;QACD,EAAE,CAAC,aAAa,CAAC,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,CAAA;IACjD,CAAC;IAAC,MAAM,CAAC;QACP,2EAA2E;IAC7E,CAAC;AACH,CAAC,CAAC,CAAA"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { CoverageReport } from '@rezless/vm';
|
|
2
|
+
/**
|
|
3
|
+
* Format a per-file coverage summary as a multi-line ASCII table. Returned
|
|
4
|
+
* as a string so callers can write it to stdout, a file, or a logger.
|
|
5
|
+
*/
|
|
6
|
+
export declare function renderConsoleSummary(reports: ReadonlyArray<CoverageReport>): string;
|
|
7
|
+
//# sourceMappingURL=console.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"console.d.ts","sourceRoot":"","sources":["../../src/format/console.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAA;AAuCjD;;;GAGG;AACH,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,aAAa,CAAC,cAAc,CAAC,GAAG,MAAM,CAoDnF"}
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
/** Right-aligned 7-char field — matches the `pad(name, 7)` headers below. */
|
|
2
|
+
function pct(hit, total) {
|
|
3
|
+
if (total === 0)
|
|
4
|
+
return ' n/a ';
|
|
5
|
+
const v = (hit / total) * 100;
|
|
6
|
+
return `${v.toFixed(1)}%`.padStart(7);
|
|
7
|
+
}
|
|
8
|
+
function summarize(r) {
|
|
9
|
+
return {
|
|
10
|
+
filename: r.filename,
|
|
11
|
+
stmts: {
|
|
12
|
+
hit: r.statements.filter((s) => s.hits > 0).length,
|
|
13
|
+
total: r.statements.length,
|
|
14
|
+
},
|
|
15
|
+
branches: {
|
|
16
|
+
hit: r.branches.reduce((a, b) => a + (b.hits[0] > 0 ? 1 : 0) + (b.hits[1] > 0 ? 1 : 0), 0),
|
|
17
|
+
total: r.branches.length * 2,
|
|
18
|
+
},
|
|
19
|
+
functions: {
|
|
20
|
+
hit: r.functions.filter((f) => f.hits > 0).length,
|
|
21
|
+
total: r.functions.length,
|
|
22
|
+
},
|
|
23
|
+
states: {
|
|
24
|
+
hit: r.states.filter((s) => s.hits > 0).length,
|
|
25
|
+
total: r.states.length,
|
|
26
|
+
},
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Format a per-file coverage summary as a multi-line ASCII table. Returned
|
|
31
|
+
* as a string so callers can write it to stdout, a file, or a logger.
|
|
32
|
+
*/
|
|
33
|
+
export function renderConsoleSummary(reports) {
|
|
34
|
+
if (reports.length === 0)
|
|
35
|
+
return 'No LSL coverage collected.\n';
|
|
36
|
+
const rows = reports.map(summarize);
|
|
37
|
+
// Total row aggregates across all files.
|
|
38
|
+
const total = {
|
|
39
|
+
filename: 'all files',
|
|
40
|
+
stmts: { hit: 0, total: 0 },
|
|
41
|
+
branches: { hit: 0, total: 0 },
|
|
42
|
+
functions: { hit: 0, total: 0 },
|
|
43
|
+
states: { hit: 0, total: 0 },
|
|
44
|
+
};
|
|
45
|
+
for (const r of rows) {
|
|
46
|
+
total.stmts.hit += r.stmts.hit;
|
|
47
|
+
total.stmts.total += r.stmts.total;
|
|
48
|
+
total.branches.hit += r.branches.hit;
|
|
49
|
+
total.branches.total += r.branches.total;
|
|
50
|
+
total.functions.hit += r.functions.hit;
|
|
51
|
+
total.functions.total += r.functions.total;
|
|
52
|
+
total.states.hit += r.states.hit;
|
|
53
|
+
total.states.total += r.states.total;
|
|
54
|
+
}
|
|
55
|
+
const fileColW = Math.max(...rows.map((r) => r.filename.length), total.filename.length, 'File'.length);
|
|
56
|
+
const header = pad('File', fileColW) +
|
|
57
|
+
' | ' +
|
|
58
|
+
pad('Stmts', 7) +
|
|
59
|
+
' | ' +
|
|
60
|
+
pad('Branch', 7) +
|
|
61
|
+
' | ' +
|
|
62
|
+
pad('Fns', 7) +
|
|
63
|
+
' | ' +
|
|
64
|
+
pad('States', 7);
|
|
65
|
+
const sep = '-'.repeat(header.length);
|
|
66
|
+
const lines = [];
|
|
67
|
+
lines.push('LSL coverage');
|
|
68
|
+
lines.push(sep);
|
|
69
|
+
lines.push(header);
|
|
70
|
+
lines.push(sep);
|
|
71
|
+
for (const r of rows) {
|
|
72
|
+
lines.push(formatRow(r, fileColW));
|
|
73
|
+
}
|
|
74
|
+
lines.push(sep);
|
|
75
|
+
lines.push(formatRow(total, fileColW));
|
|
76
|
+
lines.push(sep);
|
|
77
|
+
return lines.join('\n') + '\n';
|
|
78
|
+
}
|
|
79
|
+
function formatRow(r, fileColW) {
|
|
80
|
+
return (pad(r.filename, fileColW) +
|
|
81
|
+
' | ' +
|
|
82
|
+
pct(r.stmts.hit, r.stmts.total) +
|
|
83
|
+
' | ' +
|
|
84
|
+
pct(r.branches.hit, r.branches.total) +
|
|
85
|
+
' | ' +
|
|
86
|
+
pct(r.functions.hit, r.functions.total) +
|
|
87
|
+
' | ' +
|
|
88
|
+
pct(r.states.hit, r.states.total));
|
|
89
|
+
}
|
|
90
|
+
function pad(s, w) {
|
|
91
|
+
return s.length >= w ? s : s + ' '.repeat(w - s.length);
|
|
92
|
+
}
|
|
93
|
+
//# sourceMappingURL=console.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"console.js","sourceRoot":"","sources":["../../src/format/console.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { CoverageReport } from '@rezless/vm';
|
|
2
|
+
/**
|
|
3
|
+
* Render a self-contained HTML coverage report — `index.html` summary plus
|
|
4
|
+
* one `<file>.html` per script with line-by-line annotation (green for
|
|
5
|
+
* hit, red for miss, gray for non-statement lines).
|
|
6
|
+
*
|
|
7
|
+
* Returns a map of relative output path → file contents for the caller to
|
|
8
|
+
* write. Pure function, no I/O — easier to test.
|
|
9
|
+
*/
|
|
10
|
+
export declare function renderHtml(reports: ReadonlyArray<CoverageReport>): Map<string, string>;
|
|
11
|
+
//# sourceMappingURL=html.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"html.d.ts","sourceRoot":"","sources":["../../src/format/html.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAA;AAEjD;;;;;;;GAOG;AACH,wBAAgB,UAAU,CAAC,OAAO,EAAE,aAAa,CAAC,cAAc,CAAC,GAAG,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAsBtF"}
|
|
@@ -0,0 +1,291 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Render a self-contained HTML coverage report — `index.html` summary plus
|
|
3
|
+
* one `<file>.html` per script with line-by-line annotation (green for
|
|
4
|
+
* hit, red for miss, gray for non-statement lines).
|
|
5
|
+
*
|
|
6
|
+
* Returns a map of relative output path → file contents for the caller to
|
|
7
|
+
* write. Pure function, no I/O — easier to test.
|
|
8
|
+
*/
|
|
9
|
+
export function renderHtml(reports) {
|
|
10
|
+
const out = new Map();
|
|
11
|
+
const summary = [];
|
|
12
|
+
// Two filenames can produce the same slug after `slugFor` collapses path
|
|
13
|
+
// separators (e.g. `/a/b/x.lsl` and `/a_b/x.lsl` both become `a_b_x.lsl`).
|
|
14
|
+
// Append a `-<n>` suffix on collision so each file gets its own page and
|
|
15
|
+
// each index link resolves correctly.
|
|
16
|
+
const slugCounts = new Map();
|
|
17
|
+
for (const r of reports) {
|
|
18
|
+
const base = slugFor(r.filename);
|
|
19
|
+
const n = slugCounts.get(base) ?? 0;
|
|
20
|
+
slugCounts.set(base, n + 1);
|
|
21
|
+
const slug = n === 0 ? base : `${base}-${n}`;
|
|
22
|
+
const detail = renderFile(r);
|
|
23
|
+
out.set(`${slug}.html`, detail);
|
|
24
|
+
summary.push({ filename: r.filename, slug, ...summarize(r) });
|
|
25
|
+
}
|
|
26
|
+
out.set('index.html', renderIndex(summary));
|
|
27
|
+
out.set('style.css', STYLE_CSS);
|
|
28
|
+
return out;
|
|
29
|
+
}
|
|
30
|
+
function summarize(r) {
|
|
31
|
+
return {
|
|
32
|
+
stmts: {
|
|
33
|
+
hit: r.statements.filter((s) => s.hits > 0).length,
|
|
34
|
+
total: r.statements.length,
|
|
35
|
+
},
|
|
36
|
+
branches: {
|
|
37
|
+
hit: r.branches.reduce((a, b) => a + (b.hits[0] > 0 ? 1 : 0) + (b.hits[1] > 0 ? 1 : 0), 0),
|
|
38
|
+
total: r.branches.length * 2,
|
|
39
|
+
},
|
|
40
|
+
functions: {
|
|
41
|
+
hit: r.functions.filter((f) => f.hits > 0).length,
|
|
42
|
+
total: r.functions.length,
|
|
43
|
+
},
|
|
44
|
+
states: {
|
|
45
|
+
hit: r.states.filter((s) => s.hits > 0).length,
|
|
46
|
+
total: r.states.length,
|
|
47
|
+
},
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
function pct(hit, total) {
|
|
51
|
+
if (total === 0)
|
|
52
|
+
return { text: 'n/a', cls: 'na' };
|
|
53
|
+
const v = (hit / total) * 100;
|
|
54
|
+
const cls = v >= 90 ? 'good' : v >= 60 ? 'medium' : 'bad';
|
|
55
|
+
return { text: `${v.toFixed(1)}%`, cls };
|
|
56
|
+
}
|
|
57
|
+
function renderIndex(rows) {
|
|
58
|
+
const total = {
|
|
59
|
+
stmts: { hit: 0, total: 0 },
|
|
60
|
+
branches: { hit: 0, total: 0 },
|
|
61
|
+
functions: { hit: 0, total: 0 },
|
|
62
|
+
states: { hit: 0, total: 0 },
|
|
63
|
+
};
|
|
64
|
+
for (const r of rows) {
|
|
65
|
+
total.stmts.hit += r.stmts.hit;
|
|
66
|
+
total.stmts.total += r.stmts.total;
|
|
67
|
+
total.branches.hit += r.branches.hit;
|
|
68
|
+
total.branches.total += r.branches.total;
|
|
69
|
+
total.functions.hit += r.functions.hit;
|
|
70
|
+
total.functions.total += r.functions.total;
|
|
71
|
+
total.states.hit += r.states.hit;
|
|
72
|
+
total.states.total += r.states.total;
|
|
73
|
+
}
|
|
74
|
+
const headerRow = (label, t) => {
|
|
75
|
+
const s = pct(t.stmts.hit, t.stmts.total);
|
|
76
|
+
const b = pct(t.branches.hit, t.branches.total);
|
|
77
|
+
const f = pct(t.functions.hit, t.functions.total);
|
|
78
|
+
const st = pct(t.states.hit, t.states.total);
|
|
79
|
+
return `<tr class="totals">
|
|
80
|
+
<th>${esc(label)}</th>
|
|
81
|
+
<td class="${s.cls}">${s.text}</td>
|
|
82
|
+
<td class="${b.cls}">${b.text}</td>
|
|
83
|
+
<td class="${f.cls}">${f.text}</td>
|
|
84
|
+
<td class="${st.cls}">${st.text}</td>
|
|
85
|
+
</tr>`;
|
|
86
|
+
};
|
|
87
|
+
const fileRows = rows
|
|
88
|
+
.map((r) => {
|
|
89
|
+
const s = pct(r.stmts.hit, r.stmts.total);
|
|
90
|
+
const b = pct(r.branches.hit, r.branches.total);
|
|
91
|
+
const f = pct(r.functions.hit, r.functions.total);
|
|
92
|
+
const st = pct(r.states.hit, r.states.total);
|
|
93
|
+
return `<tr>
|
|
94
|
+
<td><a href="${esc(r.slug)}.html">${esc(r.filename)}</a></td>
|
|
95
|
+
<td class="${s.cls}">${s.text} <span class="frac">${r.stmts.hit}/${r.stmts.total}</span></td>
|
|
96
|
+
<td class="${b.cls}">${b.text} <span class="frac">${r.branches.hit}/${r.branches.total}</span></td>
|
|
97
|
+
<td class="${f.cls}">${f.text} <span class="frac">${r.functions.hit}/${r.functions.total}</span></td>
|
|
98
|
+
<td class="${st.cls}">${st.text} <span class="frac">${r.states.hit}/${r.states.total}</span></td>
|
|
99
|
+
</tr>`;
|
|
100
|
+
})
|
|
101
|
+
.join('\n');
|
|
102
|
+
return `<!doctype html>
|
|
103
|
+
<html lang="en">
|
|
104
|
+
<head>
|
|
105
|
+
<meta charset="utf-8">
|
|
106
|
+
<title>LSL coverage</title>
|
|
107
|
+
<link rel="stylesheet" href="style.css">
|
|
108
|
+
</head>
|
|
109
|
+
<body>
|
|
110
|
+
<header>
|
|
111
|
+
<h1>LSL coverage</h1>
|
|
112
|
+
</header>
|
|
113
|
+
<main>
|
|
114
|
+
<table class="summary">
|
|
115
|
+
<thead>
|
|
116
|
+
<tr>
|
|
117
|
+
<th>File</th>
|
|
118
|
+
<th>Statements</th>
|
|
119
|
+
<th>Branches</th>
|
|
120
|
+
<th>Functions</th>
|
|
121
|
+
<th>States</th>
|
|
122
|
+
</tr>
|
|
123
|
+
</thead>
|
|
124
|
+
<tbody>
|
|
125
|
+
${headerRow('All files', total)}
|
|
126
|
+
${fileRows}
|
|
127
|
+
</tbody>
|
|
128
|
+
</table>
|
|
129
|
+
</main>
|
|
130
|
+
</body>
|
|
131
|
+
</html>
|
|
132
|
+
`;
|
|
133
|
+
}
|
|
134
|
+
function renderFile(r) {
|
|
135
|
+
const lines = r.source.split('\n');
|
|
136
|
+
// Build per-line max hit-count from statements. A line with only
|
|
137
|
+
// hits=0 statements still gets recorded as 0, which renders as a miss.
|
|
138
|
+
const lineHits = new Map();
|
|
139
|
+
for (const s of r.statements) {
|
|
140
|
+
const prev = lineHits.get(s.line) ?? 0;
|
|
141
|
+
lineHits.set(s.line, Math.max(prev, s.hits));
|
|
142
|
+
}
|
|
143
|
+
// Per-line branch state: 'partial' if any branch on the line is missed.
|
|
144
|
+
const lineBranchPartial = new Set();
|
|
145
|
+
for (const b of r.branches) {
|
|
146
|
+
if (b.hits[0] === 0 || b.hits[1] === 0)
|
|
147
|
+
lineBranchPartial.add(b.line);
|
|
148
|
+
}
|
|
149
|
+
const sum = summarize(r);
|
|
150
|
+
const s = pct(sum.stmts.hit, sum.stmts.total);
|
|
151
|
+
const b = pct(sum.branches.hit, sum.branches.total);
|
|
152
|
+
const f = pct(sum.functions.hit, sum.functions.total);
|
|
153
|
+
const st = pct(sum.states.hit, sum.states.total);
|
|
154
|
+
const rendered = lines
|
|
155
|
+
.map((text, i) => {
|
|
156
|
+
const lineNo = i + 1;
|
|
157
|
+
const hits = lineHits.get(lineNo);
|
|
158
|
+
let cls = 'noncode';
|
|
159
|
+
let countLabel = '';
|
|
160
|
+
if (hits !== undefined) {
|
|
161
|
+
if (hits > 0) {
|
|
162
|
+
cls = lineBranchPartial.has(lineNo) ? 'partial' : 'hit';
|
|
163
|
+
countLabel = String(hits);
|
|
164
|
+
}
|
|
165
|
+
else {
|
|
166
|
+
cls = 'miss';
|
|
167
|
+
countLabel = '0';
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
return `<tr class="${cls}"><td class="ln">${lineNo}</td><td class="ct">${countLabel}</td><td class="src">${esc(text) || ' '}</td></tr>`;
|
|
171
|
+
})
|
|
172
|
+
.join('\n');
|
|
173
|
+
return `<!doctype html>
|
|
174
|
+
<html lang="en">
|
|
175
|
+
<head>
|
|
176
|
+
<meta charset="utf-8">
|
|
177
|
+
<title>${esc(r.filename)} — LSL coverage</title>
|
|
178
|
+
<link rel="stylesheet" href="style.css">
|
|
179
|
+
</head>
|
|
180
|
+
<body>
|
|
181
|
+
<header>
|
|
182
|
+
<h1><a href="index.html">LSL coverage</a> » ${esc(r.filename)}</h1>
|
|
183
|
+
<ul class="meta">
|
|
184
|
+
<li>Statements <span class="${s.cls}">${s.text}</span> <span class="frac">${sum.stmts.hit}/${sum.stmts.total}</span></li>
|
|
185
|
+
<li>Branches <span class="${b.cls}">${b.text}</span> <span class="frac">${sum.branches.hit}/${sum.branches.total}</span></li>
|
|
186
|
+
<li>Functions <span class="${f.cls}">${f.text}</span> <span class="frac">${sum.functions.hit}/${sum.functions.total}</span></li>
|
|
187
|
+
<li>States <span class="${st.cls}">${st.text}</span> <span class="frac">${sum.states.hit}/${sum.states.total}</span></li>
|
|
188
|
+
</ul>
|
|
189
|
+
</header>
|
|
190
|
+
<main>
|
|
191
|
+
<table class="source">
|
|
192
|
+
<tbody>
|
|
193
|
+
${rendered}
|
|
194
|
+
</tbody>
|
|
195
|
+
</table>
|
|
196
|
+
</main>
|
|
197
|
+
</body>
|
|
198
|
+
</html>
|
|
199
|
+
`;
|
|
200
|
+
}
|
|
201
|
+
function esc(s) {
|
|
202
|
+
return s
|
|
203
|
+
.replace(/&/g, '&')
|
|
204
|
+
.replace(/</g, '<')
|
|
205
|
+
.replace(/>/g, '>')
|
|
206
|
+
.replace(/"/g, '"');
|
|
207
|
+
}
|
|
208
|
+
function slugFor(filename) {
|
|
209
|
+
return filename.replace(/[^a-zA-Z0-9._-]+/g, '_').replace(/^_+|_+$/g, '') || 'inline';
|
|
210
|
+
}
|
|
211
|
+
const STYLE_CSS = `
|
|
212
|
+
:root {
|
|
213
|
+
color-scheme: light dark;
|
|
214
|
+
--bg: #fff;
|
|
215
|
+
--fg: #111;
|
|
216
|
+
--muted: #666;
|
|
217
|
+
--hit: #c8e6c9;
|
|
218
|
+
--miss: #ffcdd2;
|
|
219
|
+
--partial: #fff59d;
|
|
220
|
+
--noncode: transparent;
|
|
221
|
+
--frac: #888;
|
|
222
|
+
--good: #2e7d32;
|
|
223
|
+
--medium: #f9a825;
|
|
224
|
+
--bad: #c62828;
|
|
225
|
+
--na: #888;
|
|
226
|
+
--link: #1565c0;
|
|
227
|
+
--border: #e0e0e0;
|
|
228
|
+
}
|
|
229
|
+
@media (prefers-color-scheme: dark) {
|
|
230
|
+
:root {
|
|
231
|
+
--bg: #1a1a1a;
|
|
232
|
+
--fg: #e0e0e0;
|
|
233
|
+
--muted: #999;
|
|
234
|
+
--hit: #1b3a1f;
|
|
235
|
+
--miss: #3a1b1b;
|
|
236
|
+
--partial: #3a361b;
|
|
237
|
+
--frac: #777;
|
|
238
|
+
--good: #66bb6a;
|
|
239
|
+
--medium: #ffd54f;
|
|
240
|
+
--bad: #ef5350;
|
|
241
|
+
--na: #888;
|
|
242
|
+
--link: #64b5f6;
|
|
243
|
+
--border: #333;
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
* { box-sizing: border-box; }
|
|
247
|
+
body {
|
|
248
|
+
margin: 0;
|
|
249
|
+
background: var(--bg);
|
|
250
|
+
color: var(--fg);
|
|
251
|
+
font: 14px/1.4 -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
|
|
252
|
+
}
|
|
253
|
+
header {
|
|
254
|
+
border-bottom: 1px solid var(--border);
|
|
255
|
+
padding: 16px 24px;
|
|
256
|
+
}
|
|
257
|
+
header h1 { margin: 0 0 8px; font-size: 18px; font-weight: 600; }
|
|
258
|
+
header h1 a { color: var(--link); text-decoration: none; }
|
|
259
|
+
header h1 a:hover { text-decoration: underline; }
|
|
260
|
+
.meta { list-style: none; padding: 0; margin: 0; display: flex; gap: 24px; flex-wrap: wrap; color: var(--muted); }
|
|
261
|
+
.meta li { font-size: 13px; }
|
|
262
|
+
main { padding: 16px 24px; }
|
|
263
|
+
table.summary { border-collapse: collapse; width: 100%; }
|
|
264
|
+
table.summary th, table.summary td { padding: 8px 12px; text-align: left; border-bottom: 1px solid var(--border); }
|
|
265
|
+
table.summary th { font-weight: 600; font-size: 12px; text-transform: uppercase; color: var(--muted); }
|
|
266
|
+
table.summary td a { color: var(--link); text-decoration: none; }
|
|
267
|
+
table.summary td a:hover { text-decoration: underline; }
|
|
268
|
+
table.summary tr.totals { font-weight: 600; background: rgba(0, 0, 0, 0.03); }
|
|
269
|
+
@media (prefers-color-scheme: dark) {
|
|
270
|
+
table.summary tr.totals { background: rgba(255, 255, 255, 0.05); }
|
|
271
|
+
}
|
|
272
|
+
.frac { color: var(--frac); font-size: 11px; }
|
|
273
|
+
.good { color: var(--good); }
|
|
274
|
+
.medium { color: var(--medium); }
|
|
275
|
+
.bad { color: var(--bad); }
|
|
276
|
+
.na { color: var(--na); }
|
|
277
|
+
table.source {
|
|
278
|
+
border-collapse: collapse;
|
|
279
|
+
width: 100%;
|
|
280
|
+
font: 13px/1.5 ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace;
|
|
281
|
+
}
|
|
282
|
+
table.source td { padding: 0 8px; vertical-align: top; }
|
|
283
|
+
table.source td.ln { width: 4em; text-align: right; color: var(--muted); user-select: none; }
|
|
284
|
+
table.source td.ct { width: 4em; text-align: right; color: var(--muted); user-select: none; }
|
|
285
|
+
table.source td.src { white-space: pre; }
|
|
286
|
+
table.source tr.hit { background: var(--hit); }
|
|
287
|
+
table.source tr.miss { background: var(--miss); }
|
|
288
|
+
table.source tr.partial { background: var(--partial); }
|
|
289
|
+
table.source tr.noncode { background: var(--noncode); }
|
|
290
|
+
`;
|
|
291
|
+
//# sourceMappingURL=html.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"html.js","sourceRoot":"","sources":["../../src/format/html.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import type { CoverageReport } from '@rezless/vm';
|
|
2
|
+
/**
|
|
3
|
+
* Render an Istanbul `coverage-final.json` document.
|
|
4
|
+
*
|
|
5
|
+
* Shape per file:
|
|
6
|
+
* { path, statementMap, fnMap, branchMap, s, f, b }
|
|
7
|
+
*
|
|
8
|
+
* Our `SourceLocation` carries only line/col/offset, no end position. We
|
|
9
|
+
* mirror start to end so renderers that expect both keep working.
|
|
10
|
+
*/
|
|
11
|
+
export interface IstanbulFileCoverage {
|
|
12
|
+
path: string;
|
|
13
|
+
statementMap: Record<string, {
|
|
14
|
+
start: Pos;
|
|
15
|
+
end: Pos;
|
|
16
|
+
}>;
|
|
17
|
+
fnMap: Record<string, {
|
|
18
|
+
name: string;
|
|
19
|
+
decl: {
|
|
20
|
+
start: Pos;
|
|
21
|
+
end: Pos;
|
|
22
|
+
};
|
|
23
|
+
loc: {
|
|
24
|
+
start: Pos;
|
|
25
|
+
end: Pos;
|
|
26
|
+
};
|
|
27
|
+
line: number;
|
|
28
|
+
}>;
|
|
29
|
+
branchMap: Record<string, {
|
|
30
|
+
line: number;
|
|
31
|
+
type: string;
|
|
32
|
+
locations: Array<{
|
|
33
|
+
start: Pos;
|
|
34
|
+
end: Pos;
|
|
35
|
+
}>;
|
|
36
|
+
}>;
|
|
37
|
+
s: Record<string, number>;
|
|
38
|
+
f: Record<string, number>;
|
|
39
|
+
b: Record<string, [number, number]>;
|
|
40
|
+
}
|
|
41
|
+
interface Pos {
|
|
42
|
+
line: number;
|
|
43
|
+
column: number;
|
|
44
|
+
}
|
|
45
|
+
export declare function renderIstanbul(reports: ReadonlyArray<CoverageReport>): Record<string, IstanbulFileCoverage>;
|
|
46
|
+
export {};
|
|
47
|
+
//# sourceMappingURL=istanbul.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"istanbul.d.ts","sourceRoot":"","sources":["../../src/format/istanbul.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAA;AAEjD;;;;;;;;GAQG;AACH,MAAM,WAAW,oBAAoB;IACnC,IAAI,EAAE,MAAM,CAAA;IACZ,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE;QAAE,KAAK,EAAE,GAAG,CAAC;QAAC,GAAG,EAAE,GAAG,CAAA;KAAE,CAAC,CAAA;IACtD,KAAK,EAAE,MAAM,CACX,MAAM,EACN;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE;YAAE,KAAK,EAAE,GAAG,CAAC;YAAC,GAAG,EAAE,GAAG,CAAA;SAAE,CAAC;QAAC,GAAG,EAAE;YAAE,KAAK,EAAE,GAAG,CAAC;YAAC,GAAG,EAAE,GAAG,CAAA;SAAE,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAC9F,CAAA;IACD,SAAS,EAAE,MAAM,CACf,MAAM,EACN;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,KAAK,CAAC;YAAE,KAAK,EAAE,GAAG,CAAC;YAAC,GAAG,EAAE,GAAG,CAAA;SAAE,CAAC,CAAA;KAAE,CAC3E,CAAA;IACD,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IACzB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IACzB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAA;CACpC;AAED,UAAU,GAAG;IACX,IAAI,EAAE,MAAM,CAAA;IACZ,MAAM,EAAE,MAAM,CAAA;CACf;AAED,wBAAgB,cAAc,CAC5B,OAAO,EAAE,aAAa,CAAC,cAAc,CAAC,GACrC,MAAM,CAAC,MAAM,EAAE,oBAAoB,CAAC,CAmDtC"}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
export function renderIstanbul(reports) {
|
|
2
|
+
const out = {};
|
|
3
|
+
for (const r of reports) {
|
|
4
|
+
const statementMap = {};
|
|
5
|
+
const s = {};
|
|
6
|
+
r.statements.forEach((stmt, i) => {
|
|
7
|
+
const pos = { line: stmt.line, column: Math.max(0, stmt.col - 1) };
|
|
8
|
+
statementMap[String(i)] = { start: pos, end: pos };
|
|
9
|
+
s[String(i)] = stmt.hits;
|
|
10
|
+
});
|
|
11
|
+
const fnMap = {};
|
|
12
|
+
const f = {};
|
|
13
|
+
r.functions.forEach((fn, i) => {
|
|
14
|
+
const pos = { line: fn.line, column: Math.max(0, fn.col - 1) };
|
|
15
|
+
const label = fn.kind === 'event' ? `${fn.state ?? ''}::${fn.name}` : fn.name;
|
|
16
|
+
fnMap[String(i)] = {
|
|
17
|
+
name: label,
|
|
18
|
+
decl: { start: pos, end: pos },
|
|
19
|
+
loc: { start: pos, end: pos },
|
|
20
|
+
line: fn.line,
|
|
21
|
+
};
|
|
22
|
+
f[String(i)] = fn.hits;
|
|
23
|
+
});
|
|
24
|
+
const branchMap = {};
|
|
25
|
+
const b = {};
|
|
26
|
+
r.branches.forEach((br, i) => {
|
|
27
|
+
const pos = { line: br.line, column: Math.max(0, br.col - 1) };
|
|
28
|
+
branchMap[String(i)] = {
|
|
29
|
+
line: br.line,
|
|
30
|
+
type: br.kind === 'if' ? 'if' : 'loop',
|
|
31
|
+
locations: [
|
|
32
|
+
{ start: pos, end: pos },
|
|
33
|
+
{ start: pos, end: pos },
|
|
34
|
+
],
|
|
35
|
+
};
|
|
36
|
+
b[String(i)] = [br.hits[0], br.hits[1]];
|
|
37
|
+
});
|
|
38
|
+
out[r.filename] = {
|
|
39
|
+
path: r.filename,
|
|
40
|
+
statementMap,
|
|
41
|
+
fnMap,
|
|
42
|
+
branchMap,
|
|
43
|
+
s,
|
|
44
|
+
f,
|
|
45
|
+
b,
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
return out;
|
|
49
|
+
}
|
|
50
|
+
//# sourceMappingURL=istanbul.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"istanbul.js","sourceRoot":"","sources":["../../src/format/istanbul.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { CoverageReport } from '@rezless/vm';
|
|
2
|
+
/**
|
|
3
|
+
* Render an LCOV `lcov.info` file body for one or more coverage reports.
|
|
4
|
+
*
|
|
5
|
+
* LCOV record reference: https://manpages.debian.org/unstable/lcov/geninfo.1.en.html
|
|
6
|
+
*
|
|
7
|
+
* Per file we emit:
|
|
8
|
+
* SF:<path>
|
|
9
|
+
* FN:<line>,<name> — one per function/event
|
|
10
|
+
* FNDA:<hits>,<name>
|
|
11
|
+
* FNF:<total> FNH:<hit>
|
|
12
|
+
* DA:<line>,<count> — one per source line that has at least one statement
|
|
13
|
+
* BRDA:<line>,<block>,<branch>,<taken> — one per (if/loop) outcome
|
|
14
|
+
* BRF:<total> BRH:<hit>
|
|
15
|
+
* LF:<lines> LH:<lines hit>
|
|
16
|
+
* end_of_record
|
|
17
|
+
*/
|
|
18
|
+
export declare function renderLcov(reports: ReadonlyArray<CoverageReport>): string;
|
|
19
|
+
//# sourceMappingURL=lcov.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"lcov.d.ts","sourceRoot":"","sources":["../../src/format/lcov.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAA;AAEjD;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,UAAU,CAAC,OAAO,EAAE,aAAa,CAAC,cAAc,CAAC,GAAG,MAAM,CAwDzE"}
|