Expand description
bynkc test --coverage — remap V8 line coverage onto .bynk source.
The test runner already owns the two artefacts a coverage tool needs and a
user cannot reconstruct: it launches the node process that executes the
suite, and it holds the source maps from .bynk → emitted .ts. This module
is the “one genuinely new piece” the coverage proposal (issue #854, ADR
recorded at merge) calls out: it reads the raw V8 coverage the runtime writes
to NODE_V8_COVERAGE, and attributes each executed / unexecuted line back to
.bynk source through two line-level source-map hops:
out-js/**/*.js.map— tsc’s map,.jsline → emitted.tsline.tscdoes not chain input maps, so this hop only reaches the.ts.out/**/*.ts.map— the emitter’s map (ADR 0103),.tsline →.bynkline. Statement-anchored and line-level (generated column always 0).
Composed, a covered .js line lands on a .bynk line. Emitted glue with no
.bynk origin (codec wrappers, capability injection, the module header) is
unmapped in hop 2, so it contributes nothing — it is counted as
out-of-scope, never as uncovered user code (the proposal’s map-fidelity
mitigation, for free).
Decisions realised here (recorded in the ADR): line/statement coverage
only, no branch coverage (DECISION B) — a .bynk line is covered if any
generated line mapping to it executed; and the measured set excludes the
tests/ tree and the workers scaffold (DECISION D), filtered once on the
out-js-relative path of the executed .js — the emitted tree’s own
top-level tests//workers/ dirs — before the maps are even consulted. The
.bynk side is deliberately not re-filtered, so a user source that merely
lives under a dir named tests/workers is still measured.
Structs§
- Coverage
Report - A whole-run coverage report: one
FileCoverageper measured.bynkfile, sorted by path, plus the derived totals. - File
Coverage - Per-
.bynk-file line coverage, keyed by a project-relative display path.
Functions§
- collect_
coverage - Collect coverage from a finished run and attribute it to
.bynksource. - format_
ranges - Compress a sorted line list into comma-separated ranges:
[6,7,8,51]→"6-8, 51". - percent
- Coverage percentage of
covered/total, rounded;total == 0→ 100. Only a genuinely complete run reads 100%: round-half-up would report995/1000as100%while lines are still uncovered — self-contradicting in the table and a false green for a CI gate keyed on the JSONpercent— so a run with any uncovered line is clamped to at most 99. - render_
rich - Render the human coverage summary — a per-file bar, percentage, covered/total line count, and the uncovered-line ranges — plus a total row. Trailing newline. An empty report renders a single “no coverage attributed” note.