skills/bun-test-fix/SKILL.md
Fix a test file to comply with Bun test rules from AGENTS.md. Use when: 'fix this test', 'make this test compliant', 'bun test fix', 'audit this test file'.
npx skillsauth add ryan-mahoney/ryan-llm-skills bun-test-fixInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Take a single test file, audit it against the Test Rules in AGENTS.md, and rewrite it to be fully compliant. The goal is to eliminate mock leaking, remove legacy assertion libraries, and prefer deps injection over mock.module() wherever possible.
path — Absolute or repo-relative path to the test file to fix (e.g., app/test/contexts/foo.test.js)## Test Rules section (starting from "### Location") to confirm the current rules. Do not rely solely on this skill document — the rules may have been updated.await import(...) calls.deps parameter. This is the single most important check — it decides the entire rewrite strategy.Work through every item. For each violation found, note the line numbers and the fix required.
| Check | Rule |
|-------|------|
| A1 | No chai imports (expect from chai, assert from chai, should from chai). Replace with expect from bun:test. |
| A2 | No mocha imports (describe/it from mocha). Replace with bun:test. |
| A3 | No bare Node assert module. Replace with bun:test expect. |
| A4 | The file imports describe, it, expect, mock, beforeEach, afterEach, afterAll etc. only from "bun:test". |
deps Injection Preference| Check | Rule |
|-------|------|
| B1 | If the subject function accepts deps, the test MUST use deps injection — not mock.module() for those dependencies. |
| B2 | When using deps, import the subject directly (no dynamic await import()), pass mock functions through deps, and assert on those mocks. |
| B3 | Follow the pattern in app/test/contexts/job-manager-candidate.test.js: create mocks inline per test, pass via deps, assert on calls. |
mock.module() Rules (only when deps is unavailable)| Check | Rule |
|-------|------|
| C1 | Register both module paths: mock.module("path/mod.js", factory) AND mock.module("path/mod", factory). Use the mockBoth helper. |
| C2 | Import the subject AFTER all mock.module() calls, using await import(). Never use static import for the subject when mocks are in play. |
| C3 | Never call real.default(...) (or other real module functions) inside a mock.module() factory for the same module. Snapshot the module first with await import("path?snapshot"), then spread the snapshot. |
| C4 | For model default exports, prefer explicit minimal stubs: default: () => ({ methodUnderTest: mockFn }). |
| C5 | Never re-register mock.module() inside beforeEach or afterEach. Only reset mock implementations there (mockFn.mockImplementation(...), mockFn.mockReset()). |
| C6 | Call mock.restore() once in afterAll. |
| C7 | Restore all mocked modules in afterAll using restoreBoth with the original snapshots. |
| C8 | Don't mock what you don't call. Remove mocks for modules that no test case actually exercises. |
| Check | Rule |
|-------|------|
| D1 | File lives in app/test/, mirroring the source structure. |
| D2 | File uses .test.js extension. |
| D3 | No /* eslint-disable */ broader than necessary. Prefer targeted disables. |
| Check | Rule |
|-------|------|
| E1 | expect.fail("Should have thrown") in try/catch is acceptable but expect(...).rejects.toThrow(...) is preferred for cleaner error assertions. |
| E2 | Tests are deterministic — no reliance on real clock, random values, or external state unless it's an integration test in app/test/integration/. |
| E3 | Each it block tests one behavior. |
Based on the audit, choose the appropriate strategy:
deps injection (preferred)Use when the subject accepts deps. This is the cleanest path.
mock.module() calls and related snapshot/restore machinery.await import() or static import.it block, create mock functions inline and pass them via deps.Pattern reference: Follow the structure in app/test/contexts/job-manager-candidate.test.js.
mock.module() usageUse when the subject does NOT accept deps and module mocking is required.
mockBoth / restoreBoth helpers at the top of the file.mock.module()..js and extensionless paths.await import().afterAll with restoreBoth for every mocked module, plus mock.restore().mock.module() calls out of beforeEach — use mockFn.mockImplementation() / mockFn.mockReset() there instead.Pattern reference: Follow the structure in app/test/contexts/rejection-message.test.js.
Use when the test intentionally hits a real database.
app/test/integration/ or is clearly a DB-backed context test.bun:test imports only.afterEach — delete in reverse dependency order.mock.module() unless absolutely necessary for non-DB concerns.Pattern reference: Follow the structure in app/test/contexts/candidate-stage.test.js.
bun test <path-to-test-file>deps property that the subject expectsawaitsbun testmock() from bun:test to create mock functions (not sinon.stub() in new code, though sinon.stub() is acceptable in existing deps-injection tests).expect(...).rejects.toThrow(...) over try/catch with expect.fail.deps, always test through deps — never reach for mock.module() as a shortcut.beforeEach for resetting mock state, not for re-registering mocks./* eslint-disable no-undef */ pragma is acceptable when mock, describe, etc. come from bun:test globals.testing
This skill should be used when the user asks to "run the spec", "implement the spec", or "execute the spec". Implements every step in a SpecOps implementation spec by delegating each step (or logical group of adjacent steps) to a sequential subagent, conventional-committing each one independently, and — when `roborev` is on the path — running `roborev check` on every commit and `roborev fix` (with spec context, so the fix cannot silently drift the implementation away from the spec) on any commit that fails.
development
Exhaustively audit a top-level UI implementation component against an HTML prototype and produce a grouped markdown checklist of corrections. Use when a user asks for UI parity review, visual QA, design implementation audit, pixel-level drift detection, or behavior/style mismatch analysis between prototype HTML and shipped component code.
development
Audit a SpecOps implementation spec against its source analysis spec to find requirements, policies, contracts, edge cases, error modes, invariants, defaults, side effects, or implementation steps that the implementation has dropped, weakened, contradicted, or silently changed — then patch the implementation spec to restore them. Use this skill whenever the user mentions auditing, comparing, conforming, reconciling, or checking an implementation spec against an analysis spec, finding gaps between two specs, ensuring an implementation spec preserves analysis behavior, or verifying spec derivation or traceability. Also trigger when the user describes "did the implementation spec lose anything from the analysis," "does the implementation match the analysis," "verify the implementation spec covers everything," or asks to confirm one spec is faithful to another. Run this before generating code from an implementation spec and after either spec is edited.
development
Audit a set of SpecOps analysis specs for cross-spec coherence — establish a dependency-ordered implementation sequence, then verify pairwise integration contracts at module boundaries plus three cross-cutting consistency dimensions (shared data models, side-effect ownership, terminology) — and patch the affected specs to resolve gaps. Use this skill whenever the user mentions cross-spec consistency, integration gaps between specs, conflicts between specs, duplicate work across specs, implementation order, dependency order for migration, building an implementation-order checklist, ensuring specs interoperate, terminology drift across specs, or shared data model conflicts. Also trigger when the user describes "do my specs agree with each other," "what order should I implement these in," "find inconsistencies across all my specs," or asks to audit a folder of analysis specs as a set rather than individually. Run this once after generating a full set of analysis specs, before deriving implementation specs.