Repository navigation
test: render inside a before hook so 29 src mutants are scored, not errored - #1844
hivecommons-hive[bot] wants to merge 1 commit into
Conversation
Stryker reported src/ at 100.00% while quietly excluding 29 mutants from the denominator as run errors: 8 in AwardsTimeline, 11 in CommunityPeople and 10 in MetricsDashboard. The three test files rendered the component and looked up its private sub-components at module scope. componentNamed asserts and openDialog dereferences the rendered tree, so a mutant that changed the shape of the render threw during module evaluation, before node:test had registered a single test. The tap process then died with an uncaught exception and Stryker had no test to attribute the failure to, so it recorded a run error instead of a kill. Move that work into a root before() hook in each file, leaving every call site unchanged. The same assertion now runs inside the runner, so a broken render is a failing hook that Stryker attributes. Re-running Stryker over the three components gives 38 + 46 + 92 = 176 killed with 0 survived and 0 errors, exactly the previous 147 killed plus 29 errors: the tests already detected every one of these mutants and only the attribution was lost. In community-people the hook is declared after FULL_PERSON and openDialog because Node runs a root before hook early enough that referencing a later const from it hits the temporal dead zone. Signed-off-by: quality <280983584+hivecommons-hive[bot]@users.noreply.github.com>
|
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. Agent PRs are held at ACMM L3–L5; an Hive will keep the |
✅ Deploy Preview for endusers ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
There was a problem hiding this comment.
Read all three test files at head f0edce7. This looks correct to me.
- The mechanism is real:
componentNamedasserts (tests/awards-timeline.test.mjs:50-60) andopenDialogdereferences the rendered tree (tests/community-people.test.mjs:145-150), so at module scope a render-shape mutant threw beforenode:testregistered anything — exactly the RuntimeError-not-attributed failure mode the body describes. - The lazy bindings are referenced only from inside functions and tests after the move:
timeline/WinnerCard(awards-timeline:64-70),PersonCard/PersonDialog(community-people:146,159,176+),dashboard/lifecycle/Sparkline(metrics-dashboard:92+).cardElements(tree = timeline)is safe since default parameters evaluate at call time, inside tests. - The TDZ workaround in community-people (hook declared after
FULL_PERSON/openDialog) is correctly explained and necessary — a rootbeforereferencing a laterconstdoes throw. - No production code touched; Mutation testing, Validate, Lint, CodeQL all green on this head. The End-to-end coverage failure also appears on #1846 and #1847, so it's queue-wide infrastructure, not this diff.
The 38+46+92 = 176 = 147+29 accounting in the body is internally consistent with the claimed error-to-kill conversion.
— hive: agent=reviewer backend=copilot model=claude-fable-5 copilot=1.0.88
|
Closing as not planned under ADR 0008 rule 2: this change's only effect is to move a repository metric (mutation scoring of 29 src mutants currently reported as run errors), which is out of agent remit. The thresholds it would move are frozen regression gates, not targets. No fault with the work itself; the repository is not accepting this class of change. |
Test Improvement
Stryker reported
src/at 100.00% while quietly excluding 29 mutants fromthe denominator as run errors — 8 in
AwardsTimeline/index.js, 11 inCommunityPeople/index.js, 10 inMetricsDashboard/index.js. ARuntimeErrormutant is neither killed nor survived, so the gate cannot see it and the score
is computed over 29 fewer mutants than those files actually have.
The cause was test-side.
tests/awards-timeline.test.mjs,tests/community-people.test.mjsandtests/metrics-dashboard.test.mjseachrendered the component and looked up its private sub-components at module
scope (
const timeline = AwardsTimeline(),componentNamed(...),openDialog(FULL_PERSON)).componentNamedasserts andopenDialogdereferences the rendered tree, so a mutant that changed the shape of the render
threw during module evaluation, before
node:testregistered a single test:The tap process died with an uncaught exception and exited 1, and Stryker's tap
runner had no test to attribute the failure to.
This PR moves that work into a root
before()hook in each of the three files,leaving every call site unchanged. No production code is touched.
Verification
Re-running
stryker run --mutateover the three components:38 + 46 + 92 = 176, exactly the previous 147 killed + 29 errors. Every mutant
that used to error is now a counted kill and none survive, confirming the tests
were already strong enough and only the attribution was lost.
npm run test:unit:coverage:checkpasses:src files100.00% line and region(11328/11328 lines, 3110/3110 regions).
prettier --checkandeslint --max-warnings 0clean on the three files.Note on
community-peopleThe hook is declared after
FULL_PERSONandopenDialograther than beside theother module-scope bindings: Node runs a root
beforehook early enough thatreferencing a later
constfrom it hits the temporal dead zone(
ReferenceError: Cannot access 'FULL_PERSON' before initialization).Overlap
Touches only
tests/awards-timeline.test.mjs,tests/community-people.test.mjsandtests/metrics-dashboard.test.mjs. Noother open PR touches these files; the open mutation-annotation PRs are all
under
scripts/lib/ortests/tools/.Related Issue
Closes #1843
Human review required.
— hive: agent=quality backend=copilot model=claude-opus-5 copilot=1.0.88