src/db.test.ts
Rama main · réplica de lectura del repositorio original.
import { beforeEach, describe, expect, it, vi } from "vitest";
const mocks = vi.hoisted(() => {
const sqlite = {
pragma: vi.fn(),
close: vi.fn(),
};
return {
sqlite,
Database: vi.fn(() => sqlite),
drizzle: vi.fn(() => ({ $client: sqlite })),
migrate: vi.fn(),
fs: {
existsSync: vi.fn(),
statSync: vi.fn(),
unlinkSync: vi.fn(),
mkdirSync: vi.fn(),
},
getUserDataPath: vi.fn(() => "/mock/user-data"),
};
});
vi.mock("better-sqlite3", () => ({
default: mocks.Database,
}));
vi.mock("drizzle-orm/better-sqlite3", () => ({
drizzle: mocks.drizzle,
}));
vi.mock("drizzle-orm/better-sqlite3/migrator", () => ({
migrate: mocks.migrate,
}));
vi.mock("node:fs", () => ({
default: mocks.fs,
}));
vi.mock("@/paths/paths", () => ({
getUserDataPath: mocks.getUserDataPath,
}));
vi.mock("electron-log", () => ({
default: {
scope: () => ({
log: vi.fn(),
warn: vi.fn(),
error: vi.fn(),
}),
},
}));
async function loadDbModule() {
vi.resetModules();
return import("@/db");
}
describe("initializeDatabase", () => {
beforeEach(() => {
vi.clearAllMocks();
mocks.fs.existsSync.mockImplementation((filePath) =>
String(filePath).includes("drizzle"),
);
});
it("closes the sqlite handle and clears the singleton when migrations fail", async () => {
const migrationError = new Error("migration failed");
mocks.migrate.mockImplementation(() => {
throw migrationError;
});
const { initializeDatabase, getDb } = await loadDbModule();
expect(() => initializeDatabase()).toThrow(migrationError);
expect(mocks.sqlite.close).toHaveBeenCalled();
expect(() => getDb()).toThrow("Database not initialized");
});
});