Skip to content

test: raise coverage to ~98% via grammar drift guard; bump to 2.0.1#998

Merged
dekobon merged 7 commits into
mainfrom
test/coverage-enum-roundtrip
Jul 1, 2026
Merged

test: raise coverage to ~98% via grammar drift guard; bump to 2.0.1#998
dekobon merged 7 commits into
mainfrom
test/coverage-enum-roundtrip

Conversation

@dekobon

@dekobon dekobon commented Jun 30, 2026

Copy link
Copy Markdown
Owner

Summary

Raises code coverage from 86.6% → 98.6% (root-crate line coverage) and bumps the version to 2.0.1. No production bugs were found — the codebase is well-maintained; the gaps were untested-but-correct code, plus generated lookup tables that dominated the "missing" lines.

The key insight

The reported 86% was largely a generated-code artifact: ~88% of the missed root-crate lines were in the auto-generated From<u16> / From<Lang> for &str enum tables in src/languages/language_*.rs. Those arms only execute when a fixture contains a node of that exact kind, so most never ran. Hand-written code was already ~98% covered.

What's in here

Coverage

  • test(languages): a grammar drift-guard test — per language, round-trips every node-kind id u16 → Lang → &str and asserts the enum name matches the live grammar for visible kinds. Lifts the generated tables from 1–9% → 99–100% and doubles as regression protection against grammar-bump renumbering.
  • test(error): covers FromPathError Display / source / From (~22% → covered).
  • test(alterator): per-language string-flattening for 8 languages (Objc, Mozcpp, Csharp, Lua, Tcl, iRules, Ruby, Elixir) that had no AST-dump test.
  • test(metrics): Display + per-space accessor tests for wmc/npm/npa, asserting nonzero values on the owning class/interface subspace and pinning SpaceKind (per lesson test(npm,npa): tighten interface tests against is_func_space revert #311). A first ==0-on-root version was vacuous — caught during review and strengthened; verified non-vacuous by test-via-revert.
  • refactor(test): macro-ized the 8 alterator cases to match the roundtrip_tests! pattern.

Docs

  • docs(codecov): documents the big-code-analysis-py 49% measurement artifact — its PyO3 Rust layer is exercised by pytest but never instrumented by cargo-llvm-cov nextest, so don't "fix" it with redundant cargo tests.

Release

  • chore(release): lockstep version bump 2.0.0 → 2.0.1 (manifests, langs.rs grammar literals, doc pins, all 7 Cargo.locks, man pages, SARIF snapshots). check-versions.py passes. Not tagged/published.

Validation

make pre-commit passes on every commit (fmt, clippy ×2, full workspace tests, doc, self-scan + headroom, enums-codegen-drift, man-drift, snapshot-anchors, actionlint, Python stack). Reviewed across /code-review, /audit-tests, /review, and /rust-optimize.

🤖 Generated with Claude Code

dekobon added 7 commits June 30, 2026 12:44
The generated `From<u16>` / `From<Enum> for &'static str` tables in
`language_*.rs` are pure lookup tables, so most arms only execute when a
fixture contains a node of that exact kind — leaving them at a few
percent line coverage and letting a grammar-bump renumbering drift
silently.

Add a hand-written crate-root test that, per language, round-trips every
`0..node_kind_count` id through both tables and asserts the enum name
agrees with the live grammar for each visible kind. It lives at the crate
root, not under `src/languages/`, because that directory is owned by the
`enums/` codegen and the drift gate rejects hand-written files there.

This pins the mapping against drift (the same fear behind the
`grammar_version` guard) and lifts the generated tables from ~1-9% to
~99-100% line coverage, moving the root crate from ~86.6% to ~98%.
`FromPathError`'s `Display`, `Error::source` chaining, and the
`From<MetricsError>` conversion are part of the stable error surface but
were only reachable on `from_path` failure paths no test drives, leaving
the impls at ~22% line coverage. Pin the message shape (substring) and
the `source` chaining contract callers rely on.
Eight languages (Objc, Mozcpp, Csharp, Lua, Tcl, iRules, Ruby, Elixir)
had no AST-dump test reaching their `Alterator::alterate` impl, leaving
the string-flattening arms uncovered. Add a behavioural test that dumps a
minimal snippet per language and asserts the string-like literal survives
as a single verbatim leaf — the observable effect of the flatten arm, and
non-vacuous since an unflattened literal splits into delimiter/content
children.
The class-based metrics wmc, npm, and npa each carry a `Display` impl and
per-space `class_*` / `interface_*` accessors that no test reached, unlike
the sibling metrics (nom, nargs, halstead) which all pin their `Display`.

Add a `Display`-plus-accessor test per metric driven by a real Java
fixture (a class and an interface) with empirically verified values. Per
lesson #311, each test asserts both halves: the structural side (the named
subspace opens with the expected `SpaceKind`) and the value side. The
singular per-space accessors are asserted on the owning class / interface
subspace, where they are nonzero, rather than on the always-zero file-unit
root — an accessor that always returned 0 or read the wrong field is
caught (verified by reverting `class_wmc` to a constant 0). Adds a shared
`child_space` test helper in `tools.rs` next to `assert_child_space_kind`;
its +6 SLOC nudges tools.rs into the soft headroom band, so the baseline
is refreshed in the same commit.
The python flag measures only the pure-Python surface; the PyO3 Rust layer
is exercised by pytest but never instrumented by cargo-llvm-cov (the crate
has no cargo tests), so its standalone Rust-line number understates how
well it is tested. Document this so a future reader does not paper over the
gap with redundant cargo tests.
The eight per-language flattening tests were near-identical
`assert_flattened` calls wrapped in `#[test]` boilerplate. Collapse them
into a `flatten_cases!` macro (one line per case), mirroring the
`roundtrip_tests!` macro in `src/language_enum_roundtrip.rs` and hoisting
the iRules rationale above its case per the macro-comments rule. Names and
behavior are unchanged (`#[track_caller]` on `assert_flattened` keeps panic
locations at the case); −35 lines.
Lockstep version bump 2.0.0 → 2.0.1 across every owned crate and the
references that must track it, per RELEASING.md's lockstep policy:

- [workspace.package] version + enums/ and the five bca-tree-sitter-*
  leaf [package] versions, and every internal =2.0.0 path-dep pin
  (root + enums grammar pins, the cli/web big-code-analysis pins).
- The vendored grammar_version literals in src/langs.rs.
- User-facing install/version references in README, STABILITY, and the
  book (quick-start, cargo-features, stability, the CI recipe pins);
  the non-gated CI cache key and historical/semver-spec references are
  left as-is.
- Regenerated derived artifacts: Cargo.lock, the man pages
  (cargo run -p xtask), and the SARIF driver-version snapshots.

check-versions.py passes (every owned crate at 2.0.1). This is the
number bump only — no tag, no publish, no CHANGELOG release section.
@codecov

codecov Bot commented Jun 30, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 97.85714% with 3 lines in your changes missing coverage. Please review.
✅ Project coverage is 98.03%. Comparing base (abc812c) to head (e90d2d9).
⚠️ Report is 1 commits behind head on main.

Files with missing lines Patch % Lines
src/error.rs 97.43% 1 Missing ⚠️
src/language_enum_roundtrip.rs 94.73% 1 Missing ⚠️
src/tools.rs 90.00% 0 Missing and 1 partial ⚠️
Additional details and impacted files

Impacted file tree graph

@@             Coverage Diff             @@
##             main     #998       +/-   ##
===========================================
+ Coverage   85.91%   98.03%   +12.11%     
===========================================
  Files         266      267        +1     
  Lines       65831    65971      +140     
  Branches    65401    65541      +140     
===========================================
+ Hits        56560    64673     +8113     
+ Misses       8831      857     -7974     
- Partials      440      441        +1     
Flag Coverage Δ
python 100.00% <ø> (ø)
rust 98.01% <97.85%> (+12.19%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

Files with missing lines Coverage Δ
src/langs.rs 92.53% <ø> (ø)
src/metrics/npa.rs 99.30% <100.00%> (+0.97%) ⬆️
src/metrics/npm.rs 98.10% <100.00%> (+1.11%) ⬆️
src/metrics/wmc.rs 97.32% <100.00%> (+0.53%) ⬆️
src/error.rs 98.38% <97.43%> (+72.30%) ⬆️
src/language_enum_roundtrip.rs 94.73% <94.73%> (ø)
src/tools.rs 94.15% <90.00%> (-0.13%) ⬇️

... and 26 files with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@dekobon dekobon merged commit 7e1721a into main Jul 1, 2026
49 checks passed
@dekobon dekobon deleted the test/coverage-enum-roundtrip branch July 1, 2026 00:01
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant