Repository navigation
smart-nav-menu: one pinned-list resolver, not two (DEFECTS #18) - #167
Merged
Merged
Conversation
The suite's branch total varied by +/-1 between identical runs. Diffing two
disagreeing coverage-final.json artifacts named the site in one step:
addon/components/layout/header/smart-nav-menu.js
branches 82 vs 83
branch id 21 path 1 @ line 344: runA=0 runB=1 (if)
That is `if (item) pinned.push(item)` — the "a pinned id matches no item" path.
The cause is duplication, not flakiness. The same "resolve pinned IDs in saved
order, dropping stale ones" loop existed in two methods:
- _distributeFromAllItems() runs on render, and the existing test "stale ids
in the saved list are skipped" covers its copy deterministically.
- _recalculate() carried its own copy, reached only when a ResizeObserver
fires through scheduleOnce('afterRender') — browser layout timing, which no
test can force.
So the branch was genuinely exercised, in two places, one of them a coin flip.
Extracted _pinnedItems(pinnedIds, allItems); both callers use it. One branch
where there were two, covered by the test that already existed.
Worth doing on its own merits: two copies of stale-ID handling is the shape
where someone fixes one and leaves the other quietly wrong. The stable branch
count is a consequence of removing the duplication rather than the point of it.
Verified over two full runs:
run C: 5196 pass, 0 fail, branches 5908/6332
run D: 5196 pass, 0 fail, branches 5908/6332
per-file diff: no differences at all — not merely matching totals
The branch total drops from 6334 to 6332, which is exactly the two paths of the
removed duplicate.
Method noted for next time: #4 cost two wrong diagnoses by reasoning about
mechanism first. Here the artifact diff named the file, the method and the
branch id before I had formed a theory at all.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes DEFECTS #18 — the last known blocker to a stable 100% gate.
The symptom
The suite's branch total varied by ±1 between identical runs. All 5,196 tests passing, identical statement totals, different branch counts. A hard 100% gate flaps on that with no code change, exactly as #4 did.
Diagnosis — the artifact named it in one step
Rather than reasoning about mechanism, I captured
coverage-final.jsonfrom two runs that disagreed and diffed them per-file, per-branch:That is
if (item) pinned.push(item)— the "a pinned id matches no item" path.The cause is duplication, not flakiness
The same "resolve pinned IDs in the user's saved order, dropping stale ones" loop existed in two methods:
_distributeFromAllItems()runs on render, and the existing test "stale ids in the saved list are skipped" covers its copy deterministically._recalculate()carried its own copy, reached only when aResizeObserverfires throughscheduleOnce('afterRender')— browser layout timing, which no test can force.So the branch was genuinely exercised, in two places, one of them a coin flip.
The fix
Extracted
_pinnedItems(pinnedIds, allItems); both callers use it. One branch where there were two, covered by the test that already existed.This is worth doing on its own merits. Two copies of stale-ID handling is the shape where someone fixes one and leaves the other quietly wrong. The stable branch count is a consequence of removing the duplication, not the point of it.
Verification
Not merely matching totals — the diff compares every file's counts and then every individual branch id, so nothing can cancel out. Lint exits 0.
The branch total drops 6334 → 6332, which is exactly the two paths of the removed duplicate.
Note on method
#4 — the previous nondeterminism — cost two wrong diagnoses because I reasoned about the mechanism first and was confidently wrong twice, once applying a "fix" that made it strictly worse. #18's entry was written to say: diff two disagreeing artifacts and let them name the file before forming a theory. That is what happened here, and it took one step.