test(local-storage): add unit tests

This commit is contained in:
Eric Liu 2025-03-16 12:32:53 -07:00
commit f28bfe307e
7 changed files with 274 additions and 22 deletions

View file

@ -0,0 +1,19 @@
<svelte:options accessors />
<script lang="ts">
import { LocalStorage } from "carbon-components-svelte";
// Example values for testing
const primitiveValue = "test-value";
const objectValue = { theme: "dark", fontSize: 16 };
</script>
<!-- Default local storage -->
<div data-testid="default-storage">
<LocalStorage value={primitiveValue} />
</div>
<!-- Local storage with object value -->
<div data-testid="storage-object">
<LocalStorage key="theme-settings" value={objectValue} />
</div>

View file

@ -0,0 +1,103 @@
import { render } from "@testing-library/svelte";
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 = {};
});
it("saves primitive value to localStorage on mount", () => {
render(LocalStorage);
expect(localStorage.setItem).toHaveBeenCalledWith(
"local-storage-key",
"test-value",
);
});
it("saves object value as JSON string", () => {
render(LocalStorage);
expect(localStorage.setItem).toHaveBeenCalledWith(
"theme-settings",
JSON.stringify({ theme: "dark", fontSize: 16 }),
);
});
it("loads existing primitive value from localStorage", () => {
localStorageMock["local-storage-key"] = "existing-value";
render(LocalStorage);
expect(localStorage.getItem).toHaveBeenCalledWith("local-storage-key");
});
it("loads existing object value from localStorage", () => {
// Set up existing value
const existingSettings = { theme: "light", fontSize: 14 };
localStorageMock["theme-settings"] = JSON.stringify(existingSettings);
render(LocalStorage);
expect(localStorage.getItem).toHaveBeenCalledWith("theme-settings");
});
it("clears specific item from localStorage", () => {
const { component } = render(LocalStorage);
const storage = component.storage;
if (storage) {
storage.clearItem();
expect(localStorage.removeItem).toHaveBeenCalledWith("programmatic-key");
}
});
it("clears all items from localStorage", () => {
const { component } = render(LocalStorage);
const storage = component.storage;
if (storage) {
storage.clearAll();
expect(localStorage.clear).toHaveBeenCalled();
}
});
it("handles JSON parse errors gracefully", () => {
// Set up invalid JSON
localStorageMock["local-storage-key"] = "{invalid-json}";
render(LocalStorage);
expect(localStorage.getItem).toHaveBeenCalledWith("local-storage-key");
});
it("uses default key if none provided", () => {
render(LocalStorage);
expect(localStorage.getItem).toHaveBeenCalledWith(
expect.stringContaining("local-storage-key"),
);
});
});

View file

@ -0,0 +1,15 @@
<script lang="ts">
import { LocalStorage } from "carbon-components-svelte";
const objectValue = { theme: "dark", fontSize: 16 };
</script>
<div data-testid="object-storage">
<LocalStorage
key="theme-settings"
value={objectValue}
on:update={({ detail }) => {
console.log("update event", detail);
}}
/>
</div>

View file

@ -0,0 +1,58 @@
import { render } from "@testing-library/svelte";
import LocalStorageObject from "./LocalStorageObject.test.svelte";
describe("LocalStorage - Object Values", () => {
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 = {};
});
it("saves object value as JSON string", () => {
render(LocalStorageObject);
expect(localStorage.setItem).toHaveBeenCalledWith(
"theme-settings",
JSON.stringify({ theme: "dark", fontSize: 16 }),
);
});
it("loads existing object value from localStorage", () => {
const existingSettings = { theme: "light", fontSize: 14 };
localStorageMock["theme-settings"] = JSON.stringify(existingSettings);
render(LocalStorageObject);
expect(localStorage.getItem).toHaveBeenCalledWith("theme-settings");
});
it("handles malformed JSON gracefully", () => {
localStorageMock["theme-settings"] = "{malformed-json}";
render(LocalStorageObject);
expect(localStorage.getItem).toHaveBeenCalledWith("theme-settings");
});
});

View file

@ -0,0 +1,18 @@
<script lang="ts">
import { LocalStorage } from "carbon-components-svelte";
const primitiveValue = "test-value";
</script>
<div data-testid="primitive-storage">
<LocalStorage
key="test-key"
value={primitiveValue}
on:save={() => {
console.log("save event");
}}
on:update={({ detail }) => {
console.log("update event", detail);
}}
/>
</div>

View file

@ -0,0 +1,61 @@
import { render } from "@testing-library/svelte";
import LocalStoragePrimitive from "./LocalStoragePrimitive.test.svelte";
describe("LocalStorage - Primitive Values", () => {
let localStorageMock: { [key: string]: string };
let originalLocalStorage: Storage;
let consoleSpy: any;
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 = {};
});
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";
render(LocalStoragePrimitive);
expect(localStorage.getItem).toHaveBeenCalledWith("test-key");
});
it("dispatches save event when setting initial value", () => {
render(LocalStoragePrimitive);
expect(consoleSpy).toHaveBeenCalledWith("save event");
});
it("handles invalid values gracefully", () => {
localStorageMock["test-key"] = "{invalid-value}";
render(LocalStoragePrimitive);
expect(localStorage.getItem).toHaveBeenCalledWith("test-key");
});
});