Skip to content

test(repo): move xstate's test files final to route onto the guard API - #55

Closed
systemfsoftware-maker wants to merge 10 commits into
xs/xstate-crypto-sourcefrom
xs/guard-xstate-core-b
Closed

systemfsoftware-maker wants to merge 10 commits into
xs/xstate-crypto-sourcefrom
xs/guard-xstate-core-b

Conversation

@systemfsoftware-maker

@systemfsoftware-maker systemfsoftware-maker commented Oct 8, 2026 •

Copy link
Copy Markdown
Collaborator

Moves 53 test files under packages/xstate/test, final.test.ts through route.test.ts, onto the @systemfsoftware/vitest guard API (generator bodies, yielded expect). The layer removes exactly those 53 entries from packages/unguarded-tests.json. No file under src changes. inspect.test.ts stays on the list (see Held).

Stacked on #54. #52's per-actor final-state warning is what lets final.test.ts drop its console spies.

Shape

  • Checks on one state merge into one check over that state; no artificial yields.
  • Refused matchers strengthened (count across the 53 files, base → head): toHaveBeenCalled* 97 → 0, toHaveLength 35 → 0, toBeTruthy 35 → 0, toBeDefined 34 → 0, not.toThrow 21 → 0, toMatchInlineSnapshot 11 → 0, toBeInstanceOf 6 → 0, toBeFalsy 4 → 0. Inline snapshots became literals from their committed values. Call-count matchers became exact recorded call lists.
  • No vi (122 → 0). Fake timers became the injected clock. final.test.ts's five final-state warning cases pass createActor(machine, { warn }) a recorder and assert the exact list, including the runtime unhandled-event warning in the parallel-region case.
  • Schema validation without a spy. persistenceConformance.v6.test.ts used to wrap StateMachine.prototype.getPersistedSnapshot in a spy that checked each envelope against persistedSnapshot.schema.json. Its roundTrip helper now validates the JSON it produces with the same Ajv2020 validator, and 22 call sites assert schemaErrors: null inside their existing check. The 4 calls whose snapshots are not JSON (the non-JSON and circular rows, and the inline-actor case) stay unvalidated, as the spy skipped them on main.
  • Type assertions: one @ts-ignore in interpreter.test.ts became @ts-expect-error a string is not a sendable event (82 → 83 directives). Every other directive stays on the expression it guards.

Parity

Case names and statuses from vitest JSON runs, against main's baseline. Columns: base cases, head cases, missing, added, changed status.

File Base Head Missing Added Changed
test/final.test.ts 48 48 0 0 0
test/firstTenMinutes.v6.test.ts 5 5 0 0 0
test/fsm-entrypoint.test.ts 2 2 0 0 0
test/fsm.actor.test.ts 4 4 0 0 0
test/fsm.differential.test.ts 2 2 0 0 0
test/fsm.setup.test.ts 3 3 0 0 0
test/fsm.test.ts 6 6 0 0 0
test/fsm.types.test.ts 3 3 0 0 0
test/guards.test.ts 24 24 0 0 0
test/history.test.ts 37 37 0 0 0
test/initial.test.ts 5 5 0 0 0
test/input.test.ts 16 16 0 0 0
test/inspection.conformance.v6.test.ts 8 8 0 0 0
test/internalEvents.test.ts 8 8 0 0 0
test/internalTransitions.test.ts 12 12 0 0 0
test/interpreter.test.ts 58 58 0 0 0
test/invalid.test.ts 6 6 0 0 0
test/invoke.test.ts 94 94 0 0 0
test/issue5454.test.ts 5 5 0 0 0
test/issueRegressions.test.ts 8 8 0 0 0
test/issueRegressions.types.test.ts 9 9 0 0 0
test/json.test.ts 36 36 0 0 0
test/listen.test.ts 16 16 0 0 0
test/logger.test.ts 2 2 0 0 0
test/logical-timers.test.ts 9 9 0 0 0
test/machine.test.ts 18 18 0 0 0
test/machineFromConfig.test.ts 6 6 0 0 0
test/machineOutput.types.test.ts 16 16 0 0 0
test/machineVersions.test.ts 37 37 0 0 0
test/machineVersions.types.test.ts 1 1 0 0 0
test/macrostepBound.test.ts 4 4 0 0 0
test/mapState.test.ts 15 15 0 0 0
test/match.test.ts 13 13 0 0 0
test/memory.test.ts 8 8 0 0 0
test/meta.test.ts 20 20 0 0 0
test/microstep.test.ts 14 14 0 0 0
test/microstep.v6.test.ts 5 5 0 0 0
test/multiple.test.ts 4 4 0 0 0
test/multiple.v6.test.ts 4 4 0 0 0
test/order.test.ts 1 1 0 0 0
test/parallel.test.ts 33 33 0 0 0
test/parallelConformance.test.ts 4 4 0 0 0
test/persistedSnapshot.types.test.ts 12 12 0 0 0
test/persistenceConformance.v6.test.ts 32 32 0 0 0
test/predictableExec.test.ts 15 15 0 0 0
test/rehydration.test.ts 23 23 0 0 0
test/rehydration.v6.test.ts 18 18 0 0 0
test/resolve.test.ts 1 1 0 0 0
test/resolve.v6.test.ts 1 1 0 0 0
test/restored-effects.test.ts 12 12 0 0 0
test/restoreEventless.test.ts 3 3 0 0 0
test/restoreTerminal.test.ts 6 6 0 0 0
test/route.test.ts 15 15 0 0 0
Total 767 767 0 0 0

Evidence

  • Oracles. Expected values are the base's literals or committed inline snapshots, or derived by hand from each case's inputs and the src it exercises; none is read off a run.
  • Sabotage (scratch worktree on this head): src/utils.ts:37 matchesState compares with !== instead of ===, giving 13 failed in 6 files (match 5, interpreter 4, and one each in predictableExec, input, guards, firstTenMinutes.v6). Restored: git diff --quiet exit 0.
  • The whole packages/xstate json run, seeds 1-3 (--sequence.seed), tsc -b, turbo lint:tsgo and dprint check: all exit 0.

Held

inspect.test.ts › "falls back without failing when Web Crypto is unusable" stubs globalThis.crypto with vi.stubGlobal, resets modules and re-imports the package. That is a global patch, and the file's other cases run concurrently with it, so the file stays unguarded until the case can reach the fallback without patching a global.

Remaining

47 files on packages/unguarded-tests.json: xstate 37, xstate-react 8, xstate-store-react 2.

No local mutation runs.

Fifty-four test files under packages/xstate/test, from final.test.ts to route.test.ts, register through @systemfsoftware/vitest with generator bodies and yielded expects, and leave packages/unguarded-tests.json. Every case name and status matches main. Mocks become per-test recorders or the actor's warn, reportUnhandledError and wallClock sinks

final.test.ts keeps five console.warn spies on the construction-time final-state warning, and inspect.test.ts keeps its Web Crypto global stub; both wait on a ruling
… spy

persistenceConformance.v6.test.ts used to wrap StateMachine.prototype.getPersistedSnapshot in a spy that checked every envelope against persistedSnapshot.schema.json. Its roundTrip helper now validates the JSON it produces with the same Ajv2020 validator, and each case asserts schemaErrors: null in its existing check. The four calls whose snapshots are not JSON (the non-JSON and circular rows, and the inline-actor case) stay unvalidated, as the spy skipped them on main
# Conflicts:
#	packages/unguarded-tests.json
#	packages/xstate/test/final.test.ts
inspect.test.ts's Web Crypto fallback case stubs globalThis.crypto and re-imports the package, a global patch that the file's concurrently running guarded cases would observe. The file goes back to its unguarded form and list entry until that case has a way to reach the fallback without patching a global
@systemfsoftware-maker
systemfsoftware-maker added this pull request to stack #49 October 8, 2026 01:30
@systemfsoftware-maker systemfsoftware-maker changed the title xs/guard xstate core b test(repo): move xstate's test files final to route onto the guard API Oct 8, 2026
@systemfsoftware-maker
systemfsoftware-maker marked this pull request as ready for review October 8, 2026 01:33
@systemfsoftware-maker
systemfsoftware-maker removed this pull request from stack #49 October 8, 2026 02:07
@systemfsoftware-maker
systemfsoftware-maker changed the base branch from xs/guard-xstate-core-a to xs/xstate-crypto-source October 8, 2026 02:07
@systemfsoftware-maker
systemfsoftware-maker added this pull request to stack #59 October 8, 2026 02:07
inspect.test.ts registers through @systemfsoftware/vitest and leaves packages/unguarded-tests.json. Its Web Crypto fallback case passes an unusable crypto source to createActor instead of stubbing globalThis.crypto and reloading the module, and every case name and status matches main
@kiro-systemf

kiro-systemf Bot commented Oct 8, 2026

Copy link
Copy Markdown
Contributor

Closed unmerged: these layers preserve upstream's example suite case-for-case, which violates CONST-T10 (call-graph asserts) and CONST-T14/T15. Replaced by per-capability contract tests with named mutation sets (conductor cycle 98).

@kiro-systemf kiro-systemf Bot closed this Oct 8, 2026
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