From 5e8c8b983cfc7f893cd327a6dfb38a49f26a82e6 Mon Sep 17 00:00:00 2001 From: Eric Liu Date: Sat, 12 Apr 2025 13:33:30 -0700 Subject: [PATCH] test(local-storage): extract shared global mock --- tests/LocalStorage/LocalStorage.test.ts | 36 +++-------------- .../LocalStoragePrimitive.test.ts | 39 ++++--------------- tests/setup-tests.ts | 38 ++++++++++++++++++ 3 files changed, 50 insertions(+), 63 deletions(-) diff --git a/tests/LocalStorage/LocalStorage.test.ts b/tests/LocalStorage/LocalStorage.test.ts index 679b1142..d20aaaae 100644 --- a/tests/LocalStorage/LocalStorage.test.ts +++ b/tests/LocalStorage/LocalStorage.test.ts @@ -1,35 +1,9 @@ import { render } from "@testing-library/svelte"; +import { setupLocalStorageMock } from "../setup-tests"; import LocalStorage from "./LocalStorage.test.svelte"; describe("LocalStorage", () => { - let localStorageMock: { [key: string]: string }; - let originalLocalStorage: Storage; - - beforeEach(() => { - originalLocalStorage = global.localStorage; - localStorageMock = {}; - global.localStorage = { - getItem: vi.fn((key) => localStorageMock[key] || null), - setItem: vi.fn((key, value) => { - localStorageMock[key] = value; - }), - removeItem: vi.fn((key) => { - delete localStorageMock[key]; - }), - clear: vi.fn(() => { - localStorageMock = {}; - }), - length: 0, - key: vi.fn(), - }; - }); - - afterEach(() => { - global.localStorage = originalLocalStorage; - localStorage.clear(); - vi.restoreAllMocks(); - localStorageMock = {}; - }); + const { setMockItem } = setupLocalStorageMock(); it("saves primitive value to localStorage on mount", () => { render(LocalStorage); @@ -50,7 +24,7 @@ describe("LocalStorage", () => { }); it("loads existing primitive value from localStorage", () => { - localStorageMock["local-storage-key"] = "existing-value"; + setMockItem("local-storage-key", "existing-value"); render(LocalStorage); expect(localStorage.getItem).toHaveBeenCalledWith("local-storage-key"); @@ -59,7 +33,7 @@ describe("LocalStorage", () => { it("loads existing object value from localStorage", () => { // Set up existing value const existingSettings = { theme: "light", fontSize: 14 }; - localStorageMock["theme-settings"] = JSON.stringify(existingSettings); + setMockItem("theme-settings", JSON.stringify(existingSettings)); render(LocalStorage); expect(localStorage.getItem).toHaveBeenCalledWith("theme-settings"); @@ -87,7 +61,7 @@ describe("LocalStorage", () => { it("handles JSON parse errors gracefully", () => { // Set up invalid JSON - localStorageMock["local-storage-key"] = "{invalid-json}"; + setMockItem("local-storage-key", "{invalid-json}"); render(LocalStorage); expect(localStorage.getItem).toHaveBeenCalledWith("local-storage-key"); diff --git a/tests/LocalStorage/LocalStoragePrimitive.test.ts b/tests/LocalStorage/LocalStoragePrimitive.test.ts index 6a80e626..f20a32df 100644 --- a/tests/LocalStorage/LocalStoragePrimitive.test.ts +++ b/tests/LocalStorage/LocalStoragePrimitive.test.ts @@ -1,47 +1,22 @@ import { render } from "@testing-library/svelte"; +import { setupLocalStorageMock } from "../setup-tests"; import LocalStoragePrimitive from "./LocalStoragePrimitive.test.svelte"; describe("LocalStorage - Primitive Values", () => { - let localStorageMock: { [key: string]: string }; - let originalLocalStorage: Storage; - let consoleSpy: any; + const { setMockItem } = setupLocalStorageMock(); + let consoleLog: ReturnType; beforeEach(() => { - originalLocalStorage = global.localStorage; - localStorageMock = {}; - consoleSpy = vi.spyOn(console, "log"); - - global.localStorage = { - getItem: vi.fn((key) => localStorageMock[key] || null), - setItem: vi.fn((key, value) => { - localStorageMock[key] = value; - }), - removeItem: vi.fn((key) => { - delete localStorageMock[key]; - }), - clear: vi.fn(() => { - localStorageMock = {}; - }), - length: 0, - key: vi.fn(), - }; - }); - - afterEach(() => { - global.localStorage = originalLocalStorage; - localStorage.clear(); - vi.restoreAllMocks(); - localStorageMock = {}; + consoleLog = vi.spyOn(console, "log"); }); it("saves primitive value to localStorage on mount", () => { render(LocalStoragePrimitive); - expect(localStorage.setItem).toHaveBeenCalledWith("test-key", "test-value"); }); it("loads existing primitive value from localStorage", () => { - localStorageMock["test-key"] = "existing-value"; + setMockItem("test-key", "existing-value"); render(LocalStoragePrimitive); expect(localStorage.getItem).toHaveBeenCalledWith("test-key"); @@ -49,11 +24,11 @@ describe("LocalStorage - Primitive Values", () => { it("dispatches save event when setting initial value", () => { render(LocalStoragePrimitive); - expect(consoleSpy).toHaveBeenCalledWith("save event"); + expect(consoleLog).toHaveBeenCalledWith("save event"); }); it("handles invalid values gracefully", () => { - localStorageMock["test-key"] = "{invalid-value}"; + setMockItem("test-key", "{invalid-value}"); render(LocalStoragePrimitive); expect(localStorage.getItem).toHaveBeenCalledWith("test-key"); diff --git a/tests/setup-tests.ts b/tests/setup-tests.ts index 9b36ceec..018fda20 100644 --- a/tests/setup-tests.ts +++ b/tests/setup-tests.ts @@ -43,3 +43,41 @@ class ResizeObserverMock { global.ResizeObserver = ResizeObserverMock; export const user = userEvent.setup(); + +export const setupLocalStorageMock = () => { + let localStorageMock: { [key: string]: string } = {}; + let originalLocalStorage: Storage; + + beforeEach(() => { + originalLocalStorage = global.localStorage; + localStorageMock = {}; + global.localStorage = { + getItem: vi.fn((key) => localStorageMock[key] || null), + setItem: vi.fn((key, value) => { + localStorageMock[key] = value; + }), + removeItem: vi.fn((key) => { + delete localStorageMock[key]; + }), + clear: vi.fn(() => { + localStorageMock = {}; + }), + length: 0, + key: vi.fn(), + }; + }); + + afterEach(() => { + global.localStorage = originalLocalStorage; + localStorage.clear(); + vi.restoreAllMocks(); + localStorageMock = {}; + }); + + return { + setMockItem: (key: string, value: string) => { + localStorageMock[key] = value; + }, + getMockItem: (key: string) => localStorageMock[key], + }; +};