refactor(daemon): relocate the handler tests by what they assert
Summary
Batch handlers of the daemon test redesign (no test exports of any kind). The 13 root tests under src/__tests__/daemon-composition/handlers/ are placed by what they assert; the directory is gone. Stacked on #3652 for its runtime-deps fixture and the backend-forwarding command surface fake; it retargets to main when #3652 merges.
Daemon halves (a) run against the package fakes (hostDiagnosticsFixture, providerCredentialsFixture, platformResourceCleanupFixture, the forwarding surface, the services port). Assertions about what real adapters or command-family code do (c) moved to tests beside that code. The snapshot-interactor-capture, device-ready and provider-device-runtime mocks are all gone: handler tests go through the bound captureSnapshot operation and DaemonPlatformServices.ensureLocalDeviceReady.
a / c split and test-count parity
Before = exact count on the source file at its old path (vitest JSON reporter); after = run count per destination on this head.
| Source (before) | Daemon half (a) | Root / package half (c) |
|---|---|---|
lease-provider-credentials (10) | sessions/handlers/lease-provider-credentials.test.ts (13) | src/provider-credential-fingerprint.test.ts (+1: bundled TestMu manifest; Limrun cases were already there) |
session-doctor-warmup (9) | sessions/handlers/session-doctor-warmup.test.ts (8) | src/platform-runtime-host-diagnostics.test.ts (2) |
session-relaunch-guards (5) | sessions/handlers/__tests__/session-relaunch-guards.test.ts (3 → 6) | src/platform-runtime-open-target-relaunch.test.ts (4) |
session-device-claims-cancellation (1) | sessions/handlers/__tests__/session-device-claims.test.ts (10 → 11) | packages/platform-android/src/lifecycle.test.ts (+1: IME activated after launch dispatch) |
session-close-runner-retention (3) | session-lifecycle/internal/session-close-lifecycle-teardown.test.ts (7, shared) | src/platform-runtime-resource-cleanup-retention.test.ts (5) |
session-relaunch-close (15) | session-lifecycle/internal/session-open-execution-relaunch.test.ts (6) | packages/platform-apple/src/lifecycle-relaunch-close.test.ts (9), src/platform-runtime-apple-application-tools-close-alerts.test.ts (4) |
snapshot-alert-android-occlusion (2) | none | src/core/interactors/android-alert-occlusion.test.ts (2), pure git mv (97% similarity) |
snapshot-handler (13) | sessions/handlers/snapshot-handler.test.ts (13), git mv (78%) | none |
snapshot-handler-freshness (9) | sessions/handlers/snapshot-handler-freshness.test.ts (4), core/__tests__/snapshot-capture.test.ts (6 → 8) | src/commands/capture/runtime/snapshot-freshness.test.ts (6), src/commands/capture/output.test.ts (5 → 6) |
snapshot-handler-wait (8) | sessions/handlers/snapshot-handler-wait.test.ts (5), execution/wait-current-surface.test.ts (4 → 6) | src/commands/interaction/runtime/wait-capture-options.test.ts (2) |
snapshot-scoped-refs (3) | sessions/handlers/snapshot-scoped-refs.test.ts (3), git mv (89%) | none |
snapshot-session-cleanup (3) | core/snapshot-session.test.ts (5) | src/platform-runtime-resource-cleanup-sessionless-host.test.ts (3) |
wait-landmark-recording (5) | execution/wait-runtime-landmark.test.ts (6), git mv (53%) | none |
86 tests before; 118 declared across the destinations including tests added to existing twins. No test disappeared without a named owner. The assertions that were dropped because an existing test already pins them:
session-relaunch-close:totalDurationMs(asserted inserver/__tests__/request-router-open.test.ts); Android relaunch sequencing (platform-android/lifecycle.test.ts); physical-iOS ordering (platform-apple/lifecycle.test.ts); runner release on close (platform-apple/lifecycle.test.ts).session-doctor-warmup: the non-macOS skip and the non-simulator/provider skips (platform-apple/src/__tests__/doctor.test.ts).snapshot-handler: filtered-to-zero guidance text (src/commands/capture/runtime/snapshot.test.ts).wait-landmark-recording: polling-loop landmark semantics (runtime/wait-selector.test.ts, two named tests).
The macOS close claim in test/integration/command-coverage/declarations.ts named the deleted session-relaunch-close test; it now names platform-apple/lifecycle-relaunch-close.test.ts "close finalization releases the runner before it dismisses close alerts" (the ordering owner), and its note says the daemon close tests own session deletion. smoke-macos-coverage passes.
Selection
All destinations are packages/*/src/**/*.test.ts or src/**/*.test.ts, so unit-core selects them (pnpm test:unit, test:coverage); the sources were already in unit-core, so no test changes project. check:affected --run runs the vitest related leg over them and passes.
vi.mock (all target an external package or the exact module the code imports)
session-open-execution-relaunch.test.ts,device-selection/dispatch-resolve: "relaunches without a session…" and "ambient provider claim…" get a non-emptyopenedlist only because the mocked device resolves.snapshot-handler.test.ts,core/ios-app-session-hint.ts: the hint test asserts the response hint equals the mocked value andtoHaveBeenCalledWith(iosSimulatorDevice, platformServices).platform-runtime-host-diagnostics.test.ts,platform-apple/doctor:toEqual(check)andtoHaveBeenCalledWith(IOS_SIMULATOR, context).platform-runtime-apple-application-tools-close-alerts.test.ts,platform-apple/macos:runMacOsAlertActioncalled with'dismiss'in three tests, not called in the fourth.platform-runtime-resource-cleanup-sessionless-host.test.ts,runner/operationsandapp-lifecycle:stopIosRunnerSession/closeIosAppasserted called and not called.android-alert-occlusion.test.ts,platform-android/mechanics:snapshotAndroidresolves the covered capture, the alert isnull,pressAndroidis not called.- Existing twin
session-device-claims.test.tskeeps its own mocks unchanged.
Subpath exports
| Package | Before (#3652) | After |
|---|---|---|
daemon | 96 | 89 |
Deleted: __tests__/support/provider-device-admission-fixture, handlers/session-doctor, handlers/session-doctor-app, handlers/session-doctor-metro, session-lifecycle/index, snapshot-capture, snapshot-session. No other package changed; no new subpath, barrel or export *.
Notes
- Fixtures: no new fake family. The shared
forwardingCreateCommandSurface(#3652) now stores the backend'ssnapshot(flat-nodes fallback) and forwardsdiffSnapshotthe same way;command-surface-fake.test.tspins both. - Edits outside
packages/daemonand the daemon-composition tree (c halves, additive):platform-android/lifecycle.test.ts, newplatform-apple/lifecycle-relaunch-close.test.ts,src/commands/**tests,src/provider-credential-fingerprint.test.ts,test/integration/command-coverage/declarations.ts. - Aspect suffixes (
-relaunch,-retention,-sessionless-host,-landmark) keep the new files from colliding with parallel moves ofwait-runtime,platform-runtime-resource-cleanupandplatform-runtime-open-targettests.
Validation
check:quick, check:layering, check:fallow, check:gate-manifest and check:affected --run passed on the first head (the run caught the stale coverage claim above). After the review fixes, check:quick and the touched suites pass; the full gates rerun on the final head are recorded in the thread.
🤖 Generated with Claude Code