Skip to content

test(e2e-coverage): assert splitRangeAtBoundaries' never-empty postcondition - #1303

Merged
mrbobbytables merged 2 commits into
mainfrom
quality/test-split-range-invariant
Oct 11, 2026
Merged

mrbobbytables merged 2 commits into
mainfrom
quality/test-split-range-invariant

Conversation

@hivecommons-hive

Copy link
Copy Markdown
Contributor

Test Improvement

splitRangeAtBoundaries (tests/tools/e2e-coverage-report.mjs) is the cut that keeps a
V8 range inside the module it started in. v8-to-istanbul abandons any range whose start
and end map to different originals, so "the split never returns the unsplit range" is a
postcondition the rest of convertScript leans on — and nothing asserted it.

The function's last line cannot take its own fallback arm:

  if (range.endOffset > start) {
    parts.push({ ...range, startOffset: start, endOffset: range.endOffset });
  }
  return parts.length === 0 ? [range] : parts;

cuts is built under offset > range.startOffset && offset < range.endOffset, and the
cuts.length === 0 guard returns early, so on this path start is the last cut and sits
strictly below range.endOffset. The tail part is always pushed; parts.length === 0 is
never true. An edit that made it true would return the straddling range, v8-to-istanbul
would drop it, and the two specs that exercise this cut today
(tests/e2e-coverage-source-boundary.test.mjs,
tests/e2e-coverage-source-boundary-segments.test.mjs) would stay green — both drive a
whole fixture bundle and assert on a rendered region count several transformations
downstream, which one dropped range need not move.

This PR therefore:

  • exports splitRangeAtBoundaries beside the existing
    getLineCoverage / getRegionCoverage / isPhantomRegion / isContradictedRegion
    block, so postconditions can be stated on the offsets rather than on a report;
  • adds tests/e2e-coverage-split-range.test.mjs — the no-cut identity, the strict
    endpoint comparisons (a boundary on an endpoint must not cut), the deliberate
    cut - 1 gap and why it exists, property preservation through the ...range spread,
    the tiling (ascending, non-overlapping, ending at range.endOffset), and —
    exhaustively over every cut list of a 7-offset space — the invariant that a
    non-empty cut list always leaves at least the tail part. The exhaustive test also
    asserts its own non-vacuity, so it cannot pass by never reaching the cut path;
  • records at the fallback that it is unreachable, why, and which test holds it that way,
    so the zero region reads as a documented residual rather than a missing fixture. That
    is the form 4184f33 settled on for the e2e side; deleting the arm would recover one
    region but delete the statement of the invariant from the code.

Tests only. No production code and no workflow file is touched.

Verification

At 4184f33, node v26.10.0, TZ=UTC:

  • node --test tests/e2e-coverage-split-range.test.mjs → 8 tests, 0 failures.
  • Non-vacuity, against the real function (mutated, asserted, reverted): weakening the
    tail guard to range.endOffset > start + 100 fails 5 of the 8, including
    every cut list leaves at least the tail part. Before this PR, that mutation leaves the
    entire suite green.
  • npm run test:unit:coverage:check (full gate flags) → exit 0;
    src files | 100.00 | 100.00 | 9135/9135 lines | 2753/2753 regions unchanged,
    harness files | 100.00 | 99.33 | 3921/3921 lines | 1473/1483 regions.
  • npx prettier --check clean on both files; npm run check:spelling → 0 issues.

Related Issue

Refs #1232 — this lands the folded finding carried on that issue
(<!-- hive-finding-folded -->: splitRangeAtBoundaries' empty-parts fallback is
unreachable and its postcondition is unasserted
) and nothing else. #1232's own Half 2 —
adding --check-source-file-regions to the e2e-coverage render step in
.github/workflows/ci.yml — is deliberately not in this PR and remains open
(needs-human: the change is inside .github/workflows/, which this agent's token tier
cannot push; GitHub rejects it server-side for want of the workflows permission, so it
needs a human or a merge-tier agent to land, and the floor it sets has to be measured
against a real browser run first).


Filed by quality agent (hold-gated mode). Human review required.

— hive: agent=quality backend=copilot model=claude-opus-5 copilot=1.0.88

…ndition

`splitRangeAtBoundaries` is the cut that keeps a V8 range inside the module it
started in; `v8-to-istanbul` abandons any range whose start and end map to
different originals, so "the split never returns the unsplit range" is a
postcondition the rest of the conversion leans on. Nothing asserted it.

The function's last line, `parts.length === 0 ? [range] : parts`, cannot take
its `[range]` arm: `cuts` is built strictly below `range.endOffset` and the
`cuts.length === 0` guard returns early, so `start` always sits below
`range.endOffset` and the tail part is always pushed. An edit that broke that
would return the straddling range, `v8-to-istanbul` would drop it, and the two
specs that exercise the cut today -- source-boundary and
source-boundary-segments -- would stay green, because both assert on a rendered
region count several transformations downstream.

Export the function alongside the existing getLineCoverage/getRegionCoverage
block and pin the arithmetic directly: the no-cut identity, the strict endpoint
comparisons, the deliberate `cut - 1` gap, property preservation, the tiling,
and -- exhaustively over every cut list of a 7-offset space -- the invariant
that a non-empty cut list always leaves at least the tail part. Record at the
fallback that it is unreachable, why, and which test holds it that way, so the
zero region reads as a documented residual rather than a missing fixture; that
is the form 4184f33 settled on for the e2e side.

Tests only. No production code and no workflow is touched.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Signed-off-by: quality <quality@hive.kubestellar.io>
@hivecommons-hive

Copy link
Copy Markdown
Contributor Author

Important

Held for human review by the hive's ACMM level gate.

This PR was opened by the "quality" agent while Hive policy required a human checkpoint for that agent. Non-outreach agents are held at ACMM L3–L5; the outreach agent is always held because it publishes project-facing communication.

Hive will keep the hold label until a human removes it. Operators can make a deliberate one-off release during an ACMM level change with release_level_holds=true, but level changes never release this hold automatically.

…dual list

The in-place comment restated the header entry from #1253 and attributed the
region to #1232; reference the list instead so there is one place to shorten
when a probe lands.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Signed-off-by: Bob Killen <bkillen@linuxfoundation.org>
@mrbobbytables
mrbobbytables added this pull request to the merge queue Oct 11, 2026
Merged via the queue into main with commit 6f2329d Oct 11, 2026
7 checks passed
@mrbobbytables
mrbobbytables deleted the quality/test-split-range-invariant branch October 12, 2026 13:11
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant