import "@testing-library/jest-dom/vitest"; import { afterEach, beforeEach, describe, expect, it, vi } from "vitest"; // The store is a module singleton constructed on first import: it reads // localStorage and `matchMedia` in its constructor. Each test therefore // stubs `matchMedia` and resets the module registry, then imports a // freshly-constructed store via `freshStore`. const STORAGE_KEY = "galaxy-theme"; function stubMatchMedia(prefersLight: boolean): void { Object.defineProperty(window, "matchMedia", { writable: true, configurable: true, value: (query: string) => ({ matches: query.includes("light") ? prefersLight : false, media: query, onchange: null, addListener: () => {}, removeListener: () => {}, addEventListener: () => {}, removeEventListener: () => {}, dispatchEvent: () => false, }), }); } async function freshStore( prefersLight = false, ): Promise { stubMatchMedia(prefersLight); vi.resetModules(); return import("../src/lib/theme/theme.svelte"); } describe("theme store", () => { beforeEach(() => { localStorage.clear(); delete document.documentElement.dataset.theme; }); afterEach(() => { vi.restoreAllMocks(); }); it("defaults to system and applies the resolved theme", async () => { const { theme } = await freshStore(); expect(theme.choice).toBe("system"); // freshStore() leaves the OS at dark (prefersLight = false). expect(theme.resolved).toBe("dark"); expect(document.documentElement.dataset.theme).toBe("dark"); }); it("persists an explicit choice and writes data-theme", async () => { const { theme, THEME_STORAGE_KEY } = await freshStore(); expect(THEME_STORAGE_KEY).toBe(STORAGE_KEY); theme.setChoice("light"); expect(theme.choice).toBe("light"); expect(theme.resolved).toBe("light"); expect(document.documentElement.dataset.theme).toBe("light"); expect(localStorage.getItem(STORAGE_KEY)).toBe("light"); theme.setChoice("dark"); expect(theme.resolved).toBe("dark"); expect(document.documentElement.dataset.theme).toBe("dark"); expect(localStorage.getItem(STORAGE_KEY)).toBe("dark"); }); it("reads the stored choice on construction", async () => { localStorage.setItem(STORAGE_KEY, "light"); const { theme } = await freshStore(); expect(theme.choice).toBe("light"); expect(theme.resolved).toBe("light"); }); it("resolves system to the OS preference", async () => { const { theme } = await freshStore(true); theme.setChoice("system"); expect(theme.choice).toBe("system"); expect(theme.resolved).toBe("light"); expect(document.documentElement.dataset.theme).toBe("light"); }); it("falls back to system for an unrecognised stored value", async () => { localStorage.setItem(STORAGE_KEY, "neon"); const { theme } = await freshStore(); expect(theme.choice).toBe("system"); }); });