Skip to content

test: reset shared mock state so unit tests pass under --randomize - #101

Merged
dknauss merged 2 commits into
mainfrom
fix/randomized-test-order-leaks
Sep 26, 2026
Merged

dknauss merged 2 commits into
mainfrom
fix/randomized-test-order-leaks

Conversation

@dknauss

@dknauss dknauss commented Sep 26, 2026 •

Copy link
Copy Markdown
Owner

Summary

npx wp-scripts test-unit-js --randomize (Jest 29 shuffles tests within each file) failed on main because of shared mock state. This PR resets that state where it's created. It adds no retries and pins no test order.

  • src/edit.test.js: the mocked @wordpress/data notices store is module-level state. Only the "Edit focus management" block reset it, so a notice left by an earlier test added a second Dismiss button. That broke OSCOLA inspector notice › hides OSCOLA notice after dismissal and soft-cap notice › hides warning after dismissal. __unstableResetNotices() now runs in a file-level beforeEach.
  • src/lib/parser.test.js: PMID fallback resolution calls jest.resetModules() and doMock. After that, parsePastedInput's lazy await import('./formatting/csl') loaded a fresh mock that the file-level formatBibliographyEntries binding never saw, so it recorded 0 calls. That broke passes the requested style key through the formatting boundary and can still opt in to parser-owned formatting explicitly. The block's afterEach also left @wordpress/api-fetch un-mocked through dontMock. The afterEach now points the registry back at the original mock instances, captured with jest.requireMock.
  • src/hooks/use-citation-editor-state.test.js: a fifth order dependence that random seeds (e.g. --seed=1) exposed. The race tests queue formatBibliographyEntries.mockReturnValueOnce(pending) but cancel before the save reaches the formatter. jest.clearAllMocks() doesn't clear Once queues, so a stale, already-resolved promise went to does not commit when cancel fires while formatting is pending. beforeEach now calls mockReset() before setting the implementation again.

Risk: low. The change is test-only and weakens no assertions.

Verification

  • Full suite with --randomize on 20 seeds, including -1645434887, 1761699380, 1, 42, 12345, 2024, 31337, 555, -424242 and 1000001: all green (827 passed, 2 skipped). Before this change the two reported seeds failed 4 tests, and 8 of 15 other seeds failed the hook test.
  • npx wp-scripts lint-js on the changed files: clean.
  • Pre-commit gate (npm test -- --runInBand, lint, build): passed.

Related

The cross-file --runInBand failures (about 40 tests in save.test.js, deprecated.test.js and parse-store-render.integration.test.js) were a separate virtual-mock leak, fixed in #100. With this branch updated to main, the full suite passes both --runInBand and --randomize (seeds -1645434887, 1761699380, 1, 42, 777, 99999, -31337, 2026; 845 passed, 2 skipped).

🤖 Generated with Claude Code

Three within-file order dependencies surfaced by `wp-scripts test-unit-js
--randomize` (e.g. seeds -1645434887, 1761699380, 1):

- edit.test.js: the mocked @wordpress/data notices store was reset only in
  the "Edit focus management" block, so a leftover notice added a second
  Dismiss button to the OSCOLA and soft-cap dismissal tests. Reset it in a
  file-level beforeEach.
- parser.test.js: "PMID fallback resolution" resets the module registry,
  so parser's lazy import('./formatting/csl') later got a fresh mock the
  file's assertions never saw, and api-fetch was left un-mocked. Its
  afterEach now re-points the registry at the original mock instances.
- use-citation-editor-state.test.js: race tests queue a pending
  formatBibliographyEntries once-value the save never reaches, and
  clearAllMocks does not drop once-queues. mockReset it in beforeEach.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@codecov

codecov Bot commented Sep 26, 2026 •

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 86.65%. Comparing base (cd4a381) to head (8dee37b).

Additional details and impacted files
@@           Coverage Diff           @@
##             main     #101   +/-   ##
=======================================
  Coverage   86.65%   86.65%           
=======================================
  Files          52       52           
  Lines        5367     5367           
  Branches      597      597           
=======================================
  Hits         4651     4651           
  Misses        235      235           
  Partials      481      481           

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@dknauss
dknauss merged commit 3937411 into main Sep 26, 2026
16 checks passed
@dknauss
dknauss deleted the fix/randomized-test-order-leaks branch September 26, 2026 17:18
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