| name | testing-guide |
| description | Design, write, run, and diagnose Synergy tests with Bun, temporary Scope isolation, deterministic fixtures, and behavior-first assertions. Use for TDD, bug regressions, feature tests, migration tests, flaky tests, coverage, package tests, frontend tests, and selecting verification gates. |
Test Synergy Behavior
Define the Invariant First
- State the observable contract and the failure that would violate it.
- For a bug or new behavior, write the smallest failing test before the implementation. Skip a new test only for a pure refactor whose existing tests already cover unchanged behavior.
- Assert public results, state transitions, emitted contracts, permissions, or recovery behavior. Avoid source-text assertions, private call counts, and snapshots of irrelevant structure.
Choose the Lowest Useful Level
- pure function/schema: inline data and direct calls
- tool/domain behavior: real implementation plus isolated temp directory and Scope context
- persistence/migration: real storage, fresh-install and upgrade fixtures, restart/readback where relevant
- route/SDK: call the route or generated client contract
- session/LLM loop: real session state with deterministic provider/model fixtures
- Web/UI: component/context behavior plus the smallest browser or integration check needed
- package/release: build, pack, and validate the published artifact rather than source layout alone
Inspect two nearby tests and packages/synergy/test/preload.ts before introducing a new harness pattern.
Use Real Isolation
Use tmpdir() and ScopeContext instead of mocking Storage, Session, or the filesystem. Restore environment variables and singleton state in cleanup hooks. Honor abort signals and dispose processes, Browser pages, servers, and timers.
Provider/model tests use the pinned test/tool/fixtures/models-api.json catalog. Update that fixture deliberately; never make deterministic tests depend on the live model catalog or real API keys.
Use a fake or local boundary only where the external system is not the subject of the test. Do not add Jest/Vitest mocks to the Bun suite without an established package-specific reason.
Run Narrow to Broad
Core runtime commands run from packages/synergy:
bun test test/<domain>/<file>.test.ts
bun run test:changed
bun test
bun run test:coverage
Repository gates run from the root:
bun run typecheck
bun run quality:quick
bun turbo test
bun run quality
Run the narrow failing test during iteration, then the affected package/domain suite, then quality:quick. Run the full suite when the change crosses shared abstractions, persistence, generated contracts, package publication, or release boundaries, or when the user requests it.
Use Development reference and Open-source quality for current command ownership. Do not invent a root bun test; the root script intentionally rejects that ambiguous command.
Diagnose Failures
- Re-run the narrow test alone and capture the first causal failure.
- Check isolation leaks, stale generated files, timeouts, open handles, environment restoration, ordering, and platform assumptions.
- Distinguish a product regression from a brittle expectation. Change the test only when the intended public contract is wrong or was asserted at the wrong level.
- Do not skip, weaken, or quarantine a relevant test merely to make the gate green.
Handoff
Report the invariant, test location, red/green evidence, commands run, pass/fail counts, unrun gates, platform limitations, and any remaining nondeterminism.