95 lines
2.9 KiB
TypeScript
95 lines
2.9 KiB
TypeScript
import { test, expect } from "bun:test";
|
|
import {
|
|
createDb,
|
|
setDb,
|
|
getDb,
|
|
hasDb,
|
|
registerDb,
|
|
registerLazyDb,
|
|
databaseNames,
|
|
closeDatabases,
|
|
} from "../src/index.ts";
|
|
import { sqlite } from "../src/adapters/sqlite.ts";
|
|
import type { Db } from "../src/index.ts";
|
|
|
|
test("multi-database registry: default + named connections", async () => {
|
|
await closeDatabases(); // isolate from any prior state
|
|
|
|
const main = createDb(sqlite(":memory:"));
|
|
const analytics = createDb(sqlite(":memory:"));
|
|
|
|
setDb(main); // default
|
|
registerDb("analytics", analytics); // named
|
|
|
|
expect(getDb()).toBe(main);
|
|
expect(getDb("analytics")).toBe(analytics);
|
|
expect(hasDb()).toBe(true);
|
|
expect(hasDb("analytics")).toBe(true);
|
|
expect(hasDb("missing")).toBe(false);
|
|
expect(databaseNames().sort()).toEqual(["analytics", "default"]);
|
|
|
|
// Each connection is independent — a table in one is not in the other.
|
|
await main.exec("CREATE TABLE a (id INTEGER)");
|
|
await analytics.exec("CREATE TABLE b (id INTEGER)");
|
|
await getDb().exec("INSERT INTO a (id) VALUES (1)");
|
|
await getDb("analytics").exec("INSERT INTO b (id) VALUES (2)");
|
|
expect((await getDb().all("SELECT id FROM a")).length).toBe(1);
|
|
expect((await getDb("analytics").all("SELECT id FROM b")).length).toBe(1);
|
|
|
|
await closeDatabases();
|
|
expect(hasDb()).toBe(false);
|
|
expect(databaseNames()).toEqual([]);
|
|
});
|
|
|
|
test("getDb throws a helpful error for an unknown named database", async () => {
|
|
await closeDatabases();
|
|
setDb(createDb(sqlite(":memory:")));
|
|
expect(() => getDb("nope")).toThrow(/No database named 'nope'/);
|
|
await closeDatabases();
|
|
});
|
|
|
|
test("named databases can be registered without opening a connection", async () => {
|
|
await closeDatabases();
|
|
let calls = 0;
|
|
const analytics = createDb(sqlite(":memory:"));
|
|
|
|
registerLazyDb("analytics", () => {
|
|
calls++;
|
|
return analytics;
|
|
});
|
|
|
|
expect(hasDb("analytics")).toBe(true);
|
|
expect(databaseNames()).toEqual(["analytics"]);
|
|
expect(calls).toBe(0);
|
|
expect(getDb("analytics")).toBe(analytics);
|
|
expect(getDb("analytics")).toBe(analytics);
|
|
expect(calls).toBe(1);
|
|
|
|
await closeDatabases();
|
|
});
|
|
|
|
test("closing the registry does not instantiate unused lazy databases", async () => {
|
|
await closeDatabases();
|
|
let calls = 0;
|
|
registerLazyDb("unused", () => {
|
|
calls++;
|
|
return createDb(sqlite(":memory:"));
|
|
});
|
|
|
|
await closeDatabases();
|
|
expect(calls).toBe(0);
|
|
});
|
|
|
|
test("registry closes every database and clears itself when one close fails", async () => {
|
|
await closeDatabases();
|
|
let secondClosed = false;
|
|
const broken = { close: async () => Promise.reject(new Error("close failed")) } as Db;
|
|
const healthy = { close: () => void (secondClosed = true) } as Db;
|
|
setDb(broken);
|
|
registerDb("healthy", healthy);
|
|
|
|
await expect(closeDatabases()).rejects.toThrow("databases failed to close");
|
|
expect(secondClosed).toBe(true);
|
|
expect(databaseNames()).toEqual([]);
|
|
});
|