Skip to content

chore: stop the coverage gate balancing on an unreachable line - #2

Merged
anilcancakir merged 1 commit into
developfrom
chore/coverage-headroom-on-the-private-ctor
Aug 21, 2026
Merged

chore: stop the coverage gate balancing on an unreachable line#2
anilcancakir merged 1 commit into
developfrom
chore/coverage-headroom-on-the-private-ctor

Conversation

@anilcancakir

Copy link
Copy Markdown
Contributor

What

WindDebugRegistry._() carries // coverage:ignore-line, with the reason on the line above it.

Why

The package had five executable lines and covered four of them, so coverage sat at exactly 80.00% against an 80% floor. One new uncovered line anywhere would have failed CI, on a package whose next real change is likely to be a v2 contract.

The fifth line is a private constructor whose only job is to stop a static-only registry being instantiated. No test can reach it: it is private, and the class is never instantiated by design. So the floor was being held up by a line that could never move.

before: 80.00%  (LH=4, LF=5)
after:  100.00% (LH=4, LF=4)

This adds no test. It stops counting a line that cannot be tested, which is the honest way to read the number, and it turns a gate with zero headroom into one with real headroom.

Verified rather than assumed

// coverage:ignore-line is a package:coverage pragma, and it is not obvious that flutter test --coverage honours it in this toolchain. Checked directly: on the same six tests the ratio moved from 80.00% to 100.00% once the comment was added, so it does.

Gates

  • dart format --output=none --set-exit-if-changed lib/ test/: 2 files, 0 changed.
  • dart analyze lib/ test/: No issues found.
  • flutter test --coverage: 6 passed.
  • Coverage, via the awk rule in ci.yml: 100.00%, PASS.

Not done here

This package still has no CLAUDE.md or .claude/rules/, unlike its sibling packages, so the coverage policy it now relies on is not written down anywhere. That is worth adding before a v2 contract lands, but it is authoring governance rather than fixing a defect, so it is left out of this PR.

`WindDebugRegistry._()` is a private constructor whose only job is to stop this
static-only registry being instantiated, so no test can reach it. It was also
one of just five executable lines in the package, which left coverage at
exactly 80.00% (LH=4, LF=5) against an 80% floor: one new uncovered line
anywhere would have failed CI, on a package whose next change is likely to be
a v2 contract.

It now carries `// coverage:ignore-line` with the reason above it, taking the
count to 100.00% (LH=4, LF=4). This adds no test. It stops counting a line
that cannot be tested, which is the honest way to read the number.

Confirmed empirically that `flutter test --coverage` honours the pragma in this
toolchain rather than assuming it: the ratio moved 80.00 -> 100.00 on the same
six tests.
@codecov

codecov Bot commented Aug 21, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

@kodizm

kodizm Bot commented Aug 21, 2026

Copy link
Copy Markdown

Note

Kodizm (AI-generated). May contain mistakes; verify before acting.

Correct, and the central claim holds under test - the pragma is honoured by this toolchain and coverage really does read 100.00%; no blocking findings.

I checked the one thing this PR rests on rather than taking it on trust. The DA: list emitted by flutter test --coverage on this head contains lines 58, 64, 69 and 77 only - line 51 is absent, so // coverage:ignore-line is being applied at collection time, not merely tolerated. LF:4, LH:4, and the exact awk rule from ci.yml yields 100.00. The pragma placement is right too: it is a trailing comment on the constructor line itself, which is the line the tool attributes, and the reason sits above it where a reader will find it.

The reasoning about reachability is also sound. WindDebugRegistry._() is library-private and test/ is a separate library, so no test can call it, and nothing in lib/ instantiates the class. Ignoring it is the honest reading, not a suppression of a real gap.

Minor

.github/workflows/ci.yml:44 — maintainability, and it qualifies the PR's own framing rather than the diff. The gate now has headroom of exactly one uncovered line, not general headroom: with LH=4, the next uncovered line gives LF=580.00% → PASS (the test is < 80.0), but the one after that gives 66.67% → FAIL. On a package this small a percentage floor stays brittle whatever the numerator; the durable fix is a floor expressed in absolute uncovered lines, or accepting that this gate is decorative until the package grows. Nothing to change here - just worth not treating the 100.00% as slack that exists.

I'd also note the PR description's "Not done here" section is right that the coverage policy is now undocumented, since this repo has no CLAUDE.md, AGENTS.md, CONTRIBUTING.md or .claude/rules/. I confirmed all four are absent, so the pragma convention lives only in the code comment and this changelog entry. Agreed that is a separate change.

The CHANGELOG.md entry is verbose, but it matches the shape of the existing ### Fixed entry directly below it, so it is consistent with the file's own house style rather than a divergence. Placing a tooling-only change under ### Changed follows the same precedent.

Tests

No test added, and correctly so - the ignored line is unreachable by construction, so a test for it cannot exist. The existing 6 contract tests still cover the registry's whole public surface (current when unregistered, register, last-wins idempotency, resetForTesting, registerForTesting, and the const {} contract assertion), and all 6 pass unchanged. This diff alters no executable behaviour, so there is nothing new to cover.

Checks I ran

  • flutter pub get then git status --porcelain: clean tree, so the migrator fix from ci: commit the analyzer excludes the Flutter migrator rewrites on every pub get #1 is holding.
  • dart format --output=none --set-exit-if-changed lib/ test/: 2 files, 0 changed, exit 0.
  • dart analyze lib/ test/: No issues found, exit 0.
  • flutter test --coverage --timeout=30s: 6 passed.
  • cat coverage/lcov.info: DA:58,1 DA:64,1 DA:69,1 DA:77,1 / LF:4 / LH:4 - line 51 excluded, confirming the pragma is honoured.
  • The awk rule from ci.yml:42-44 against that lcov: 100.00, PASS.
  • Modelled the same rule at LH=4 with LF of 4, 5 and 6: PASS, PASS, FAIL - the basis for the minor note above.
  • Not measured: the "before: 80.00%" figure. Reproducing it needs a working-tree mutation I am not permitted to make. It follows from the emitted DA list (line 51 would be DA:51,0, giving LF=5, LH=4), so I believe it, but I did not observe it directly.
  • Both changed files were read in full. Nothing was listed as changed_without_diff or dropped_for_size.

@anilcancakir
anilcancakir merged commit a3216c1 into develop Aug 21, 2026
2 checks passed
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