Skip to content

test(geometry): pin which edge gap_boundary's half_thickness read uses (#3013) - #3050

Merged
louistrue merged 2 commits into
mainfrom
fix/3013-gap-boundary-half-thickness
Aug 22, 2026
Merged

test(geometry): pin which edge gap_boundary's half_thickness read uses (#3013)#3050
louistrue merged 2 commits into
mainfrom
fix/3013-gap-boundary-half-thickness

Conversation

@BIMvoice

Copy link
Copy Markdown
Collaborator

Closes #3013. Test-only — the read is correct as written; nothing observed which edge it pointed at.

Path correction: the issue says rust/processing/src/space_dcel/mod.rs:1202. Line 1202 is right, the crate is not — it is rust/geometry/src/space_dcel/mod.rs.

The issue's own question, answered: untested, not dead

The read is reached on every run — build_from_wall_rects calls gap_boundary(f, 1.0) for its stage-2 axis lift — and it genuinely moves output: zeroing it drops the axis outline onto the net gap, which the existing suite does catch.

What nothing caught is which edge it reads. Every fixture in that file boxes its room with four walls of identical thickness, so permuting half_thickness around the cycle moves nothing.

RED, confirmed before writing anything — with cycle[i] rewritten to cycle[(i + 1) % n]:

test result: ok. 708 passed; 0 failed; 1 ignored

The fix shape, and why area could not do it

This is #2913's lesson applied directly: area cannot separate these cases. Offsetting a rectangle by a permutation of the same four numbers only permutes which side each lands on — and the opposite-edge swap cycle[(i + 2) % n] is exactly area-preserving, since width stays 4.8 and height 3.5 either way.

So the test asserts position: four distinct half-thicknesses (0.10 / 0.25 / 0.40 / 0.55) on a 4×3 centreline room, one assertion per side of the offset rectangle, each side displaced by exactly one edge's value. Bounds are min/max rather than by vertex index, so it pins geometry rather than which corner the cycle happens to start at. And the fixture asserts its own four values stay distinct, so a later edit making them uniform cannot silently restore the blind spot.

Six mutants, six killed, each verified individually

mutant observed wanted
cycle[(i + 1) % n] −0.10 −0.55
cycle[(i + n - 1) % n] −0.40 −0.55
cycle[(i + 2) % n] — area-neutral −0.25 −0.55
half_thickness * 0.0 0 −0.55
factor dropped (let off = half) −0.55 at factor 2 −1.10
inward normal ([-uy * off, ux * off]) +0.55 −0.55

None argued equivalent.

ifc-lite-geometry lib 708 → 709 passed, 0 failed. cargo clippy -p ifc-lite-geometry --all-targets -- -D warnings clean. Module-size ratchet 5/5 with ALLOWLIST_DIGEST unmoved (test files are exempt). No changeset — per AGENTS.md those cover published packages/*, and the maintainer's own analogous test-only commit shipped without one.

🤖 Generated with Claude Code

The surviving mutation was a question, not a verdict, and the answer is
"untested", not "dead": `gap_boundary` is reached on every run --
`build_from_wall_rects` calls it at `factor = 1.0` for its axis lift --
and the read genuinely moves the output. Zeroing it drops the axis
outline back onto the net gap, which the existing suite does catch.

What nothing caught is WHICH edge the read points at. Every fixture in
this file boxes its room with four walls of the SAME thickness, so
permuting `half_thickness` around the cycle moves nothing at all.
Verified on current main: rewriting the read as `cycle[(i + 1) % n]`
leaves the crate at 708 passed, 0 failed.

Area could not have closed this, which is the lesson #2913 recorded.
Offsetting a rectangle by a permutation of the same four numbers only
permutes which side each lands on, and the opposite-edge swap
(`cycle[(i + 2) % n]`) is exactly area-preserving: width stays 4.8 and
height stays 3.5 either way. So assert POSITION -- four distinct
half-thicknesses and one assertion per side of the offset rectangle,
each side displaced by exactly one edge's value, so any misrouting moves
at least one of them.

Bounds are taken as min/max rather than by vertex index, so the test
pins the geometry rather than which corner the face cycle starts at, and
the fixture asserts its own four values stay distinct -- a later edit
making them uniform would silently restore the blind spot.

Mutants killed (each verified individually, all six):
  - `cycle[(i + 1) % n]`      -> left side at -0.10, want -0.55
  - `cycle[(i + n - 1) % n]`  -> left side at -0.40, want -0.55
  - `cycle[(i + 2) % n]`      -> left side at -0.25, want -0.55 (area-neutral)
  - `.half_thickness * 0.0`   -> left side at 0, want -0.55
  - `let off = half`          -> factor=2 left side at -0.55, want -1.10
  - `[-uy * off, ux * off]`   -> left side at +0.55, want -0.55 (inset, not outset)

Test-only: the read is correct as written, so there is no production
change to make. `ifc-lite-geometry` lib 708 -> 709 passed, 0 failed;
`cargo clippy -p ifc-lite-geometry --all-targets -- -D warnings` clean;
module-size ratchet 5/5 (test files are exempt, ALLOWLIST_DIGEST
unmoved).
@BIMvoice
BIMvoice requested a review from louistrue as a code owner August 21, 2026 15:29
@coderabbitai

coderabbitai Bot commented Aug 21, 2026

Copy link
Copy Markdown

Warning

Review limit reached

@louistrue, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 55 minutes

Limit details: You’ve used all 2 included reviews currently available.

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

How can I continue?

Wait for the limit to reset, then comment @coderabbitai review or push new commits to the PR.

An organization admin can change what happens after included review limits in Billing.

How do review limits work?

CodeRabbit enforces per-developer PR review limits within each organization.

For paid Pro and Pro+ reviews, CodeRabbit uses a developer's included PR review attempts over the past 7 days to set the current hourly allowance. At typical activity levels, the full plan allowance applies. Higher sustained activity can lower the allowance until earlier attempts leave the 7-day window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: c9543590-ed1e-4a15-96f7-189b2cf0c269

📥 Commits

Reviewing files that changed from the base of the PR and between fe38b33 and a02cb67.

📒 Files selected for processing (1)
  • rust/geometry/src/space_dcel/tests.rs

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actions

github-actions Bot commented Aug 21, 2026

Copy link
Copy Markdown
Contributor

Viewer benchmark

✅ No threshold regressions detected.

01_Snowdon_Towers_Sample_Structural(1).ifc

Baseline recorded 2026-07-01T20:31:05.538Z on github-actions ubuntu-latest, viewer-benchmark-ci (headless Chrome, SwiftShader ANGLE), production build.

Metric Current Baseline Delta Threshold Status
firstBatchWaitMs 1722ms 2905ms -40.7% +50%
firstVisibleGeometryMs 2737ms 3652ms -25.1% +50%
streamCompleteMs 2901ms 3598ms -19.4% +50%
spatialReadyMs 1234ms 1032ms +19.6% +50%
metadataCompleteMs 1789ms 3063ms -41.6% +50%
totalWallClockMs 3400ms 3700ms -8.1% +50%

AC20-FZK-Haus.ifc

Baseline recorded 2026-07-01T20:30:59.972Z on github-actions ubuntu-latest, viewer-benchmark-ci (headless Chrome, SwiftShader ANGLE), production build.

Metric Current Baseline Delta Threshold Status
firstBatchWaitMs 350ms 1075ms -67.4% +50%
firstVisibleGeometryMs 1230ms 1572ms -21.8% +50%
streamCompleteMs 1037ms 1980ms -47.6% +50%
spatialReadyMs 1064ms 915ms +16.3% +50%
metadataCompleteMs 1161ms 1392ms -16.6% +50%
totalWallClockMs 1300ms 3300ms -60.6% +50%

Refresh the baseline from a CI run: dispatch the Benchmark workflow with record_baseline, download the benchmark-baseline artifact, and commit baseline.json (see tests/benchmark/README.md).

@vercel

vercel Bot commented Aug 21, 2026

Copy link
Copy Markdown
Contributor

The latest updates on your projects. Learn more about Vercel for GitHub.

2 Skipped Deployments
Project Deployment Actions Updated (UTC)
ifc-lite-dev Ignored Ignored Preview Aug 21, 2026 9:07pm
ifc-lite-viewer-embed Ignored Ignored Aug 21, 2026 9:07pm

@louistrue

Copy link
Copy Markdown
Collaborator

Merge review: HOLD as superseded, not as defective.

The test itself is genuine. At this PR's head (a02cb67) I mutated the read at rust/geometry/src/space_dcel/mod.rs from cycle[i] to cycle[(i + 1) % n] and the new test went red. No complaints about its construction: distinct halves, position bounds, factor 1 and 2, a centreline control.

The problem is that main already pins exactly this. #3047 merged today (e07a395) and closed #3013 with two tests in the same file, rust/geometry/src/space_dcel/tests.rs:965 (gap_boundary_pushes_each_edge_out_by_its_own_thickness) and :1043 (build_from_wall_rects_lifts_each_wall_by_its_own_half_thickness). Because this branch has merged main, both are present at head, and the mutations show they carry the coverage on their own:

#3047 also covers ground this test does not: an area assertion that catches a diamond inscribed in the same bounding box, a factor 0 control, an argument covering all index maps on the quad, and a caller-reachability test through build_from_wall_rects with four rectangles of different thickness. I could not find a mutant this PR's test kills that #3047's do not.

So merging adds a 94-line near-duplicate of coverage that landed on main a few hours after this PR was opened. Suggest closing as superseded by #3047, unless there is a detection here I missed.

@BIMvoice

Copy link
Copy Markdown
Collaborator Author

Agreed — superseded. I checked rather than taking it on trust, and I could not find a detection you missed either.

Read both of #3047's tests on main (rust/geometry/src/space_dcel/tests.rs:965 and :1043). gap_boundary_pushes_each_edge_out_by_its_own_thickness uses four distinct per-edge halves across factors 1 and 2, with factor 0 as a control — which is the same discriminating construction mine uses, and it additionally carries the area assertion catching a diamond inscribed in the same bounding box, plus the argument over all index maps on the quad. build_from_wall_rects_lifts_each_wall_by_its_own_half_thickness covers caller reachability with four rectangles of different thickness, which mine does not.

So your mutation results are what I would expect: the (i + 2) % n opposite-edge swap is the one I built mine around, because it is exactly area-preserving on a rectangle — and #3047's test kills it with mine filtered out entirely. That was the only thing I thought might be unique here, and it is not.

Merging this would add a 94-line near-duplicate. Your call to close it — I do not close PRs — but there is no objection from me, and nothing in it needs preserving elsewhere.

One note for the record since the timing is the whole story: this was opened against #3013 at 15:35 and #3047 merged as e07a395d3 a few hours later. That is the second time in two days I have built something you had already fixed or were fixing. #3040 is the answer to it and I have been running the assignee-plus-PR-search check since — this PR predates my doing that.

@BIMvoice

Copy link
Copy Markdown
Collaborator Author

Supersession confirmed independently — I did not take my own earlier agreement on trust, and ran the mutants against main with only #3047 present.

Three mutants that appear in this PR's table and not in #3047's:

mutant on rust/geometry/src/space_dcel/mod.rs result on main (#3047 only)
d = [-uy*off, ux*off] — inward normal 4 failed
let off = half — factor dropped 1 failed
cycle[(i+2) % n] — opposite edge, area-neutral 2 failed

Every distinctive mutant is already killed. And #3047 is strictly stronger: same four-distinct-halves fixture, plus an area assertion, a factor = 0 control, build_from_wall_rects_lifts_each_wall_by_its_own_half_thickness proving the production caller reaches the read, and a tighter tolerance (1e-9 against this PR's 1e-6).

No mutant found that this kills and #3047 does not. The branch is green — ifc-lite-geometry lib 711 passed / 0 failed — it just adds a near-duplicate.

So your hold was right and I have nothing to add in its defence. Your call to close; I do not close PRs, and there is nothing in here worth preserving elsewhere.

@louistrue
louistrue merged commit 833cce7 into main Aug 22, 2026
37 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.

gap_boundary's half_thickness read is not covered by any test

2 participants