Expand description
Patch (changed-line) coverage (Python — #132; TypeScript — #135; parent #46).
Enforces the README Coverage rule’s changed-line guarantee: every line a diff
touches must be covered by the unit suite. Where crate::coverage measures
the whole suite against a floor (#26) and the #131 ratchet against a
baseline, this measures only the lines <base>...HEAD added or modified —
failing when any changed, executable line is left uncovered.
Two inputs are combined:
- the diff —
changed_linesrunsgit diff --unified=0 <base>...HEADand returns the new-side line numbers each file gained. This diff machinery is language-agnostic, shared by both arms (and the forthcoming Rust twin). - the coverage — per the language. Python (
check) reads coverage.py’s per-filemissing_lines/missing_branches(crate::coverage::measure_patch_report); a changed line is uncovered when it is a missing line or the source of a branch the suite never took (uncovered_changed_lines). TypeScript (check_typescript) reads vitest’s per-file v8 coverage reduced to one uncovered-line set per file (crate::coverage::measure_patch_typescript) and intersects it directly (uncovered_changed_lines_ts). Either way, non-executable changed lines (comments, blanks) andcoverage-exempt files have nothing to cover and are skipped.
Relationship to the commit-scoped co-change rule (crate::co_change, #33):
co-change enforces that a changed source and its colocated test move
together; patch coverage enforces that the changed lines are actually
exercised. They are complementary, not overlapping — co-change can pass (the
test file changed) while patch coverage fails (the change isn’t covered), and
vice versa.
Structs§
- Uncovered
- A changed source line the unit suite doesn’t cover — a
root-relative path and the 1-based new-side line number.
Functions§
- changed_
lines - The new-side lines each file gained in
repo’s<base>...HEADdiff, keyed byrepo-relative path. The diff machinery shared by the TS / Rust twins. - check
- Every line added or modified in
root’s<base>...HEADdiff that the unit suite doesn’t cover, sorted for deterministic output.omitis thecoverage-rule exemptions (as incrate::coverage::measure) — an exempt file is omitted from the run, so its changed lines are lifted. - check_
typescript - Every line added or modified in
root’s<base>...HEADdiff that the TypeScript unit suite (vitest) doesn’t cover, sorted for deterministic output.excludeis thecoverage-rule exemptions (as incrate::coverage::measure_typescript) — an excluded file is left out of the run, so its changed lines are lifted. - uncovered_
changed_ lines - Pure: every changed line the coverage report marks uncovered — a
missing_line, or the source of amissing_branch(a branch out of the line the suite never took). A changed file absent fromfileswas not measured (a test file, or acoverage-exempt file omitted from the run) and contributes nothing; a changed line that is neither missing nor a branch source (a comment or blank) has nothing to cover.filesis keyed byroot-relative path, aschangedis. - uncovered_
changed_ lines_ ts - Pure: every changed line a TypeScript coverage report marks uncovered.
uncoveredis the per-file set of uncovered lines (crate::coverage::measure_patch_typescript) — statements the suite never ran and the source lines of branches a path of which it never took — keyed byroot-relative path, aschangedis. A changed file absent fromuncoveredwas not measured (a test file, a declaration file, or acoverage-exempt file excluded from the run) and contributes nothing; a changed line not in its set (a comment or blank) has nothing to cover.