Files
optima/ui/src/lib/theme.spec.ts
T

82 lines
1.8 KiB
TypeScript

import { beforeEach, describe, expect, it, vi } from "vitest";
const { mockBrowser } = vi.hoisted(() => ({
mockBrowser: { value: true },
}));
vi.mock("$app/environment", () => ({
get browser() {
return mockBrowser.value;
},
}));
// Mock localStorage and document before importing theme
const mockLocalStorage: Record<string, string> = {};
vi.stubGlobal("localStorage", {
getItem: vi.fn((key: string) => mockLocalStorage[key] ?? null),
setItem: vi.fn((key: string, value: string) => {
mockLocalStorage[key] = value;
}),
});
vi.stubGlobal("document", {
documentElement: {
setAttribute: vi.fn(),
},
});
describe("theme store", () => {
beforeEach(() => {
vi.clearAllMocks();
Object.keys(mockLocalStorage).forEach((k) => delete mockLocalStorage[k]);
mockBrowser.value = true;
});
it("defaults to dark theme", async () => {
// Re-import to get a fresh store
const { theme } = await import("./theme");
let value: string | undefined;
const unsub = theme.subscribe((v) => {
value = v;
});
expect(value).toBe("dark");
unsub();
});
it("toggle switches between dark and light", async () => {
const { theme } = await import("./theme");
let value: string | undefined;
const unsub = theme.subscribe((v) => {
value = v;
});
theme.toggle();
expect(value).toBe("light");
theme.toggle();
expect(value).toBe("dark");
unsub();
});
it("set updates the theme directly", async () => {
const { theme } = await import("./theme");
let value: string | undefined;
const unsub = theme.subscribe((v) => {
value = v;
});
theme.set("light");
expect(value).toBe("light");
theme.set("dark");
expect(value).toBe("dark");
unsub();
});
});