Expand description
Coverage rule (Python — issue #26; TypeScript — issue #31; Rust — issue #37; exemptions — issue #32).
Enforces the README’s Coverage rule: a library’s unit suite must meet the
configured floor, with test files excluded from the denominator. This module
is the deterministic core — given a parsed coverage report and the thresholds
from config, an evaluate function decides pass/fail. Producing the report
(shelling out to the language’s coverage tool) is a thin layer on top, kept
separate so the guarantee is testable without that toolchain installed.
Python (#26) uses coverage.py: a single total, branch coverage on. Given a
CoverageReport and Thresholds, evaluate decides pass/fail, and
measure shells out to coverage. TypeScript (#31) is the twin: vitest
reports four independent metrics (lines / branches / functions / statements),
so it carries its own TypeScriptThresholds, VitestReport, and
evaluate_typescript / measure_typescript pair — sharing only the
Outcome type. Its subprocess layer shells out to vitest. Rust (#37) is
the third twin: cargo llvm-cov reports regions/lines (branch coverage is
experimental), so it carries RustThresholds, LlvmCovReport, and
evaluate_rust / measure_rust; its subprocess layer shells out to
cargo llvm-cov.
Files exempted from coverage in config (issue #32) are omitted from the
denominator alongside the test files; the caller resolves them
(crate::config::resolve_exempt) and passes their paths to measure /
measure_typescript / measure_rust.
Structs§
- Coverage
Report - A coverage.py JSON report (
coverage json), pared to what the checks need: thetotals(the floor) and the per-filefilesblock (patch coverage, #132). Unmodeled fields (metadata, per-function/class data) are ignored. - File
Coverage - Per-file coverage detail from a coverage.py report (one
filesentry) — what patch coverage (#132) reads to decide whether a changed line is covered. Unmodeled fields (the summary, per-function/class data) are ignored. - Llvm
CovData - One export entry — only its
totalsare needed (--summary-onlyomits the per-file and per-function detail). - Llvm
CovMetric - One metric’s totals from an llvm-cov export, pared to what the check needs: the denominator size and the covered percent.
- Llvm
CovReport - A
cargo llvm-cov --jsonexport (LLVM’sllvm.coverage.json.export), pared to the totals the check needs. A single run produces onedataentry; unmodeled fields (per-file/per-function detail,type,version) are ignored. - Llvm
CovTotals - The
totalsblock of an llvm-cov export — the two metrics this rule enforces. llvm-cov also reportsfunctions,instantiations, and (experimental)branches, which the check ignores. - Rust
Thresholds - The two
cargo llvm-covcoverage floors, from a[rust].coveragetable. Branch coverage is still experimental, so only regions and lines are enforced. - Thresholds
- The coverage floor to enforce, from a
[<language>].coveragetable. - Totals
- The
totalsblock of a coverage.py report. - Type
Script Thresholds - The four vitest coverage floors, from a
[typescript].coveragetable. Each is an independent percent the unit suite must meet — vitest measures all four. - Vitest
Metric - One metric’s totals from a vitest json-summary block, pared to what the check needs: the covered percent and the denominator size.
- Vitest
Report - A vitest
coverage-summary.jsonreport, pared to thetotalblock the check needs. Per-file entries and unmodeled fields are ignored. - Vitest
Totals - The
totalblock of a vitest json-summary report — the four metrics this rule enforces. vitest also emitsbranchesTrue, which the check ignores.
Enums§
- Outcome
- The result of checking a report against the thresholds.
Functions§
- evaluate
- Decide whether
reportmeetsthresholds. - evaluate_
rust - Decide whether
reportmeets both thresholds. - evaluate_
typescript - Decide whether
reportmeets every threshold inthresholds. - measure
- Run the unit suite under coverage.py in
rootand check it againstthresholds. - measure_
patch_ report - Run the Python unit suite under coverage.py in
rootwith every source underrootmeasured (coverage run --source=.) and return the parsed report — so an untested source shows in thefilesblock as wholly uncovered rather than vanishing. The per-file detail is what patch coverage (#132) reads;omitis as inmeasure(an exempt file stays out of the run, so its changed lines are lifted). - measure_
patch_ rust - Run the Rust unit suite under
cargo llvm-covinrootand return the uncovered lines per file — keyed by the absolute path llvm-cov reports, the caller re-keying toroot-relative to match the diff. A line is uncovered when llvm-cov records no execution for it (an LCOVDA:<line>,0). What patch coverage (#136,crate::patch_coverage::check_rust) reads;ignoreis thecoverage-rule exemptions, dropped from the run so an exempt file’s changed lines are lifted.cargo-llvm-covmust be installed. - measure_
patch_ typescript - Run the TypeScript unit suite under vitest in
rootand return the uncovered lines per file — keyed by the absolute path vitest reports, the caller re-keying toroot-relative to match the diff. A line is uncovered when it carries a statement the suite never executed, or the source of a branch a path of which the suite never took (the v8 analogue of the Python arm’s missing line / missing branch).excludeis thecoverage-rule exemptions, dropped from the run so an exempt file’s changed lines are lifted.npxresolves the project-localvitest, so it and@vitest/coverage-v8must be installed underroot. - measure_
rust - Run the unit suite under
cargo llvm-covinrootand check it againstthresholds. - measure_
typescript - Run the unit suite under vitest coverage in
rootand check it againstthresholds. - parse_
llvm_ cov_ report - Parse a
cargo llvm-cov --jsonexport. - parse_
report - Parse a coverage.py JSON report (the output of
coverage json). - parse_
vitest_ report - Parse a vitest json-summary report (
coverage-summary.json).