Skip to content

refactor(runtime): deduplicate backend fixtures in ai-sdk-backend.test.ts (scavenger T1 slice) #4945

Description

@orangeCatDeveloper

Claim

Part of T1 — Runtime backend and kernel tests (scavenger sweep 2026-09), scoped to one file: packages/runtime/src/__tests__/ai-sdk-backend.test.ts. Cross-checked against open claims: this slice is unclaimed — #3909 decomposes the source file, not its tests.

The redundancy (measured)

Baseline commit 2310035a3 (current main), file SHA-256 9770d5ff…, 16,608 lines:

Metric Count
createTestAiSdkBackend call sites 196
Eligible object-literal calls (all six default keys present; no spread, duplicate, or computed keys) 181
Intentionally excluded calls 15
Removable repeated property lines 993

181 calls repeat the same six fixture properties byte-for-byte (sessionId: 'session-1', header: header(), appendMessage: async () => {}, apiKey: 'sk-test', newId: idGenerator(), now: monotonicClock()). The 15 exclusions stay on the real constructor: 8 type-asserted inputs, 4 Codex checkpoint calls that deliberately omit newId/now (the backend's own defaults are the subject there), and 3 spread-based inputs whose override order is behavior.

The plan (two PRs)

PR 1 — fixture-only deduplication (up as #4946)

One suite-local createBackend wrapper (17 lines) supplies the six defaults; every eligible call passes only its scenario-specific input; a final spread keeps explicit overrides authoritative. Nothing else moves.

  • Measured result (the sweep's acceptance shape: a fixture that existed in N places now exists once): 181 → 1; net −976 lines (16,608 → 15,632); runtime leaf count 222 → 222 with byte-identical leaf-name lists; no test deleted; no assertion, test name, or scenario value changed.
  • Input preservation evidence: every migrated input expanded with its omitted defaults was compared against the original input at the AST level — all 196 constructor inputs equivalent (per-call assertion over the whole file).
  • Gates: build, full target suite (222 pass / 0 fail), typecheck, biome format/lint (no fixes needed), git diff --check.

PR 2 — scenario consolidation (planned; lands after PR 1 merges)

  1. The two stream-watchdog pause tests share one scenario row table and one body, remaining two independently registered tests with unchanged names, semantics, and result payloads.
  2. The two manual-compaction availability tests become one case table of three independently registered tests, each omitting exactly one capability (context budget / durable writer / summarizer). Today's fixtures omit several capabilities at once, so operation_unavailable is reachable through any guard — the masks hide which branch a test proves. Present callbacks count invocations and throw distinct sentinels so a fabricated compaction cannot pass. This adds the currently missing no-summarizer case.
  • Measured result: leaf count 222 → 223; the three availability guards become individually assertable.

Part B acceptance mapping

  1. Coverage may not fall. PR 1: leaf-count delta 0 with identical leaf-name lists. PR 2: +1 test. No test is deleted anywhere.
  2. Every test touched must fail without the code it tests. For PR 2's touched tests, five named mutants were validated during planning and will be re-run and recorded in that PR: removing the execution-time pauseTarget?.pause() or its matching resume() fails both watchdog tests; deleting !policy, || !recorder, or || !summarizer from the compaction availability condition fails exactly its corresponding case, with the other four tests passing. Open question for PR 1: it touches 181 tests' fixture lines but changes no assertion, and the AST-level equivalence above proves each test's input set is unchanged. Applying rule 2 per-test to a fixture-only migration would mean ~181 mutants; we propose family-grouped mutants (one production mutant per behavioral suite, recorded named failures) as a follow-up commit to PR 1 if that grouping is acceptable — raised here before review rather than after.
  3. Prefer driving the real entry point. Unchanged: every test drives the same backend.send / backend.compactHistory / runtimeExecute entry points; the wrapper only replaces repeated fixture construction.

Rules check

  • One PR per coherent change ✓ — fixture dedup and scenario consolidation are independently reviewable and sequenced.
  • No behaviour change ✓ — test-only; leaf-name diff and input equivalence above.
  • Existing gates decide the argument ✓ — format, lint, typecheck, protocol epoch, ASF headers all pass locally.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Labels

No labels
No labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions