Commit5c54f77unknown_key
test(import-verify): defensive mock.module fallthrough
test(import-verify): defensive mock.module fallthrough Bun's mock.module registry is shared across the whole bun test run and mock.restore() doesn't un-register a mock.module() call. Use a resettable _nextRow with an afterAll fallthrough so unrelated tests that happen to db.select().limit(1) after these tests don't regress (keeps ai-explain's DB-unavailable tests green). https://claude.ai/code/session_017Do52tMX1P9jPTWXhEohXH
1 file changed+23−35c54f778bdd96a28a3bbbc9ba617ed232f269658
1 changed file+23−3
Modifiedsrc/__tests__/import-verify.test.ts+23−3View fileUnifiedSplit
@@ -5,9 +5,17 @@
55 * The fake `db.select(...)` chain returns whatever the per-test closure
66 * decides — either undefined (repo not found) or a plausible row whose
77 * on-disk path points somewhere that doesn't exist.
8 *
9 * Bun 1.3's `bun test` shares a single module registry across every test
10 * file in a run and `mock.restore()` does NOT un-mock `mock.module(...)`
11 * registrations. To avoid leaking our stub into other test files, we use a
12 * defensive fake: `_nextRow` defaults to `undefined` (so any library code
13 * that does `select().from().where().limit(1)` sees an empty result and
14 * falls through to its DB-unavailable branch), and we reset the row back
15 * to `undefined` in `afterAll`.
816 */
917
10import { describe, it, expect, mock } from "bun:test";
18import { describe, it, expect, mock, afterAll } from "bun:test";
1119
1220// Per-test mutable row — each test assigns its own value before calling
1321// verifyMigration. The chained Drizzle-style select builder ends in
@@ -20,18 +28,30 @@ let _nextRow: { repoName: string; ownerName: string | null } | undefined;
2028const _chain: any = {
2129 from: () => _chain,
2230 leftJoin: () => _chain,
31 innerJoin: () => _chain,
32 rightJoin: () => _chain,
2333 where: () => _chain,
34 orderBy: () => _chain,
35 groupBy: () => _chain,
2436 limit: async () => (_nextRow ? [_nextRow] : []),
2537};
2638
2739// Mock `../db` at module scope so the dynamic import of ../lib/import-verify
2840// below picks up the stub instead of the real Neon-backed proxy.
2941const _fakeDb = {
30 db: { select: () => _chain },
31 getDb: () => ({ select: () => _chain }),
42 db: { select: () => _chain, insert: () => _chain, update: () => _chain, delete: () => _chain },
43 getDb: () => ({ select: () => _chain, insert: () => _chain, update: () => _chain, delete: () => _chain }),
3244};
3345mock.module("../db", () => _fakeDb);
3446
47// Reset the fake row after our tests finish so any later test file whose
48// code happens to run `db.select()...limit(1)` sees an empty result (and
49// falls through to its real null/empty branch) rather than inheriting the
50// half-built row from our "git dir missing" test.
51afterAll(() => {
52 _nextRow = undefined;
53});
54
3555// Point GIT_REPOS_PATH at a directory that definitely doesn't contain
3656// any of the fake repos we'll reference, so `clonable` checks fail.
3757process.env.GIT_REPOS_PATH = "/tmp/gluecron-import-verify-does-not-exist";
3858