import { Database } from "bun:sqlite"; import { describe, expect, test } from "bun:test"; import { ScopedStore } from "./store"; /** Just enough of DurableObjectStorage for ScopedStore, on bun:sqlite. */ function fakeStorage() { const db = new Database(":memory:"); const kv = new Map(); const sql = { exec(query: string, ...params: unknown[]) { const statement = db.query(query); const rows = /^\s*(SELECT|PRAGMA|WITH)/i.test(query) ? (statement.all(...(params as never[])) as unknown[]) : []; if (rows.length === 0 && !/^\s*(SELECT|WITH)/i.test(query)) statement.run(...(params as never[])); return { toArray: () => rows, one: () => { if (rows.length !== 1) throw new Error("expected one row"); return rows[0]; }, }; }, }; return { sql, get: async (key: string) => kv.get(key), put: async (key: string, value: unknown) => void kv.set(key, value), deleteAll: async () => kv.clear(), transactionSync: (fn: () => T) => db.transaction(fn)(), } as unknown as DurableObjectStorage; } const SCHEMA = ["CREATE TABLE IF NOT EXISTS items (id TEXT PRIMARY KEY, title TEXT)"]; describe("ScopedStore", () => { test("applies the schema once and re-applies it when the DDL changes", async () => { const storage = fakeStorage(); const store = new ScopedStore(storage, SCHEMA); await store.prepare(); expect(store.run("INSERT INTO items VALUES ('a', 'one')", []).changes).toBe(1); const grown = new ScopedStore(storage, [...SCHEMA, "CREATE TABLE IF NOT EXISTS tags (id TEXT PRIMARY KEY)"]); await grown.prepare(); expect(grown.all("SELECT id FROM items", [])).toEqual([{ id: "a" }]); expect(grown.run("INSERT INTO tags VALUES ('t')", []).changes).toBe(1); }); test("run reports changes and batches are atomic", async () => { const store = new ScopedStore(fakeStorage(), SCHEMA); await store.prepare(); expect(store.run("INSERT INTO items VALUES ('x', 'one')", []).changes).toBe(1); expect(() => store.batch([ { sql: "INSERT INTO items VALUES ('y', 'two')", params: [] }, { sql: "INSERT INTO items VALUES ('x', 'dupe')", params: [] }, ]), ).toThrow(); expect(store.all("SELECT id FROM items ORDER BY id", [])).toEqual([{ id: "x" }]); }); });