Skip to content

test(debugger): pin the source-map wait debugger-status promises - #706

Draft
latekvo wants to merge 1 commit into
mainfrom
fix/pin-status-source-map-wait
Draft

test(debugger): pin the source-map wait debugger-status promises#706
latekvo wants to merge 1 commit into
mainfrom
fix/pin-status-source-map-wait

Conversation

@latekvo

@latekvo latekvo commented Aug 3, 2026

Copy link
Copy Markdown
Member

Found while reviewing #610 and set aside as out of scope: the code and the prose it comes from are byte-identical at that PR's merge base, and the same mutant survives there too.

The gap

debugger-status returns sourceMapReady: true as a hardcoded literal (debugger-status.ts:57). The only thing that makes the literal true is the line above it:

await api.sourceMaps.waitForPending();

and the description sells exactly that: "sourceMapReady (always true — waits for pending source maps before returning; no-op on Chromium)".

Nothing pins it. Deleting the await:

existing suite (test/debugger test/metro test/flows test/utils)
unmutated 856 passed
await deleted 856 passed

So a status that reports readiness it never established would ship green.

Scope, stated honestly

This is a test-only change; the shipped behaviour is correct. The impact of a regression is narrow but real: js-runtime-debugger.ts:214 already drains the registry once while the service is being created, so the await in the tool is what covers maps registered after that point - a Fast Refresh, or a lazily loaded bundle chunk. In that window a non-awaiting status would return sourceMapReady: true while SourceMapsRegistry.pendingRegistrations is non-empty, and a debugger-inspect-element issued straight after can miss the file:line it would otherwise resolve.

I did not manufacture a user-visible failure end to end, and I am not claiming one - the finding is that the single promised behaviour of this field has no test.

The tests

Both assert the ordering, not the literal - a test that only checked sourceMapReady === true would pass on the mutant, since the literal is unconditional.

  1. does not resolve until the pending source-map registration settles - hands the tool a waitForPending that returns a deferred promise, drains several macrotask turns, asserts the tool has not returned, then releases it.
  2. reports sourceMapReady only after the wait - records ["maps-settled", "status-returned"] and asserts that exact order.
new tests
on main as shipped 2 passed
with the await deleted 2 failed

eslint --max-warnings 0, tsc --noEmit -p tsconfig.test.json and prettier all clean.

`sourceMapReady` is a hardcoded `true`, so the await above it is the entire
content of the promise the tool's description makes — "always true — waits
for pending source maps before returning". Deleting the await leaves the
whole package green, which means nothing would notice a status that reports
readiness it never established.

The blueprint drains the registry once while the service is created, so the
await in the tool covers the scripts parsed after that: a Fast Refresh, or a
lazily loaded bundle chunk. These tests pin the ordering rather than the
literal.
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