@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.
Files changed (63) hide show
  1. package/LICENSE +202 -0
  2. package/NOTICE +32 -0
  3. package/dist/cli.d.ts +3 -0
  4. package/dist/cli.d.ts.map +1 -0
  5. package/dist/cli.js +140 -0
  6. package/dist/cli.js.map +1 -0
  7. package/dist/coverage-aggregate.d.ts +22 -0
  8. package/dist/coverage-aggregate.d.ts.map +1 -0
  9. package/dist/coverage-aggregate.js +65 -0
  10. package/dist/coverage-aggregate.js.map +1 -0
  11. package/dist/coverage-config.d.ts +10 -0
  12. package/dist/coverage-config.d.ts.map +1 -0
  13. package/dist/coverage-config.js +12 -0
  14. package/dist/coverage-config.js.map +1 -0
  15. package/dist/coverage-registry.d.ts +13 -0
  16. package/dist/coverage-registry.d.ts.map +1 -0
  17. package/dist/coverage-registry.js +111 -0
  18. package/dist/coverage-registry.js.map +1 -0
  19. package/dist/coverage-setup.d.ts +25 -0
  20. package/dist/coverage-setup.d.ts.map +1 -0
  21. package/dist/coverage-setup.js +42 -0
  22. package/dist/coverage-setup.js.map +1 -0
  23. package/dist/format/console.d.ts +7 -0
  24. package/dist/format/console.d.ts.map +1 -0
  25. package/dist/format/console.js +93 -0
  26. package/dist/format/console.js.map +1 -0
  27. package/dist/format/html.d.ts +11 -0
  28. package/dist/format/html.d.ts.map +1 -0
  29. package/dist/format/html.js +291 -0
  30. package/dist/format/html.js.map +1 -0
  31. package/dist/format/istanbul.d.ts +47 -0
  32. package/dist/format/istanbul.d.ts.map +1 -0
  33. package/dist/format/istanbul.js +50 -0
  34. package/dist/format/istanbul.js.map +1 -0
  35. package/dist/format/lcov.d.ts +19 -0
  36. package/dist/format/lcov.d.ts.map +1 -0
  37. package/dist/format/lcov.js +74 -0
  38. package/dist/format/lcov.js.map +1 -0
  39. package/dist/format/summary.d.ts +25 -0
  40. package/dist/format/summary.d.ts.map +1 -0
  41. package/dist/format/summary.js +48 -0
  42. package/dist/format/summary.js.map +1 -0
  43. package/dist/index.d.ts +7 -0
  44. package/dist/index.d.ts.map +1 -0
  45. package/dist/index.js +10 -0
  46. package/dist/index.js.map +1 -0
  47. package/dist/loadLinkset.d.ts +38 -0
  48. package/dist/loadLinkset.d.ts.map +1 -0
  49. package/dist/loadLinkset.js +77 -0
  50. package/dist/loadLinkset.js.map +1 -0
  51. package/dist/loadScript.d.ts +24 -0
  52. package/dist/loadScript.d.ts.map +1 -0
  53. package/dist/loadScript.js +45 -0
  54. package/dist/loadScript.js.map +1 -0
  55. package/dist/matchers.d.ts +34 -0
  56. package/dist/matchers.d.ts.map +1 -0
  57. package/dist/matchers.js +120 -0
  58. package/dist/matchers.js.map +1 -0
  59. package/dist/reporter.d.ts +82 -0
  60. package/dist/reporter.d.ts.map +1 -0
  61. package/dist/reporter.js +166 -0
  62. package/dist/reporter.js.map +1 -0
  63. 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) || '&nbsp;'}</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> &raquo; ${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, '&amp;')
204
+ .replace(/</g, '&lt;')
205
+ .replace(/>/g, '&gt;')
206
+ .replace(/"/g, '&quot;');
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"}