mirror of
https://github.com/carbon-design-system/carbon-components-svelte.git
synced 2025-09-14 18:01:06 +00:00
test(theme): add unit tests
This commit is contained in:
parent
f28bfe307e
commit
150e03e1fd
7 changed files with 243 additions and 24 deletions
|
@ -1,24 +0,0 @@
|
|||
<script lang="ts">
|
||||
import { Theme } from "carbon-components-svelte";
|
||||
import type { CarbonTheme } from "carbon-components-svelte/Theme/Theme.svelte";
|
||||
|
||||
let theme: CarbonTheme = "g10";
|
||||
</script>
|
||||
|
||||
<Theme
|
||||
bind:theme
|
||||
persist
|
||||
persistKey="carbon-theme"
|
||||
on:update={(e) => console.log(e.detail.theme)}
|
||||
tokens={{ "button-primary": "violet" }}
|
||||
render="toggle"
|
||||
toggle={{
|
||||
themes: ["g10", "g90"],
|
||||
labelA: "",
|
||||
labelB: "",
|
||||
}}
|
||||
select={{
|
||||
themes: ["g10", "g90"],
|
||||
labelText: "",
|
||||
}}
|
||||
/>
|
23
tests/Theme/Theme.test.svelte
Normal file
23
tests/Theme/Theme.test.svelte
Normal file
|
@ -0,0 +1,23 @@
|
|||
<svelte:options accessors />
|
||||
|
||||
<script lang="ts">
|
||||
import { Theme } from "carbon-components-svelte";
|
||||
import type { CarbonTheme } from "carbon-components-svelte/Theme/Theme.svelte";
|
||||
|
||||
export let theme: CarbonTheme = "white";
|
||||
export let persist = false;
|
||||
export let tokens = {};
|
||||
</script>
|
||||
|
||||
<div data-testid="theme-wrapper">
|
||||
<Theme
|
||||
{theme}
|
||||
{persist}
|
||||
{tokens}
|
||||
on:update={({ detail }) => {
|
||||
console.log("update", detail);
|
||||
}}
|
||||
>
|
||||
<slot />
|
||||
</Theme>
|
||||
</div>
|
168
tests/Theme/Theme.test.ts
Normal file
168
tests/Theme/Theme.test.ts
Normal file
|
@ -0,0 +1,168 @@
|
|||
import { render, screen } from "@testing-library/svelte";
|
||||
import { tick } from "svelte";
|
||||
import { user } from "../setup-tests";
|
||||
import Theme from "./Theme.test.svelte";
|
||||
import ThemeSelect from "./ThemeSelect.test.svelte";
|
||||
import ThemeSelectCustom from "./ThemeSelectCustom.test.svelte";
|
||||
import ThemeToggle from "./ThemeToggle.test.svelte";
|
||||
import ThemeToggleCustom from "./ThemeToggleCustom.test.svelte";
|
||||
|
||||
describe("Theme", () => {
|
||||
let documentMock: {
|
||||
setAttribute: ReturnType<typeof vi.spyOn>;
|
||||
style: { setProperty: ReturnType<typeof vi.spyOn> };
|
||||
};
|
||||
let consoleLog: ReturnType<typeof vi.spyOn>;
|
||||
let localStorageMock: Record<string, string>;
|
||||
let originalLocalStorage: Storage;
|
||||
|
||||
beforeEach(() => {
|
||||
documentMock = {
|
||||
setAttribute: vi.spyOn(document.documentElement, "setAttribute"),
|
||||
style: {
|
||||
setProperty: vi.spyOn(document.documentElement.style, "setProperty"),
|
||||
},
|
||||
};
|
||||
consoleLog = vi.spyOn(console, "log");
|
||||
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(() => {
|
||||
vi.restoreAllMocks();
|
||||
global.localStorage = originalLocalStorage;
|
||||
localStorage.clear();
|
||||
localStorageMock = {};
|
||||
});
|
||||
|
||||
it("should set default theme to white", () => {
|
||||
render(Theme);
|
||||
expect(documentMock.setAttribute).toHaveBeenCalledWith("theme", "white");
|
||||
});
|
||||
|
||||
it("should update theme attribute when theme changes", async () => {
|
||||
const { component } = render(Theme);
|
||||
|
||||
component.$set({ theme: "g100" });
|
||||
await tick();
|
||||
|
||||
expect(documentMock.setAttribute).toHaveBeenCalledWith("theme", "g100");
|
||||
expect(consoleLog).toHaveBeenCalledWith("update", { theme: "g100" });
|
||||
});
|
||||
|
||||
it("should apply custom tokens", async () => {
|
||||
const tokens = {
|
||||
"interactive-01": "#ff0000",
|
||||
"ui-background": "#ffffff",
|
||||
};
|
||||
|
||||
render(Theme, { props: { tokens } });
|
||||
await tick();
|
||||
|
||||
expect(documentMock.style.setProperty).toHaveBeenCalledWith(
|
||||
"--cds-interactive-01",
|
||||
"#ff0000",
|
||||
);
|
||||
expect(documentMock.style.setProperty).toHaveBeenCalledWith(
|
||||
"--cds-ui-background",
|
||||
"#ffffff",
|
||||
);
|
||||
});
|
||||
|
||||
it("should persist theme in localStorage when persist is true", async () => {
|
||||
render(Theme, { props: { persist: true } });
|
||||
await tick();
|
||||
|
||||
expect(localStorage.setItem).toHaveBeenCalledWith("theme", "white");
|
||||
});
|
||||
|
||||
it("should load persisted theme from localStorage", async () => {
|
||||
localStorageMock["theme"] = "g90";
|
||||
|
||||
render(Theme, { props: { persist: true } });
|
||||
await tick();
|
||||
|
||||
expect(documentMock.setAttribute).toHaveBeenCalledWith("theme", "g90");
|
||||
});
|
||||
|
||||
it("should warn on invalid theme", async () => {
|
||||
const consoleWarn = vi.spyOn(console, "warn");
|
||||
const { component } = render(Theme);
|
||||
|
||||
// @ts-ignore - Testing invalid theme
|
||||
component.$set({ theme: "invalid" });
|
||||
await tick();
|
||||
|
||||
expect(consoleWarn).toHaveBeenCalledWith(
|
||||
expect.stringContaining('invalid theme "invalid"'),
|
||||
);
|
||||
});
|
||||
|
||||
it("should render toggle when render prop is set to toggle", async () => {
|
||||
render(ThemeToggle);
|
||||
|
||||
const toggle = screen.getByLabelText("Dark mode");
|
||||
expect(toggle).toBeInTheDocument();
|
||||
expect(toggle).toHaveAttribute("type", "checkbox");
|
||||
|
||||
await user.click(toggle);
|
||||
expect(consoleLog).toHaveBeenCalledWith("update", { theme: "g100" });
|
||||
|
||||
await user.click(toggle);
|
||||
expect(consoleLog).toHaveBeenCalledWith("update", { theme: "white" });
|
||||
});
|
||||
|
||||
it("should render custom toggle when render prop is set to toggle and custom toggle options are provided", async () => {
|
||||
render(ThemeToggleCustom);
|
||||
|
||||
const toggle = screen.getAllByText("Enable dark mode")[0];
|
||||
expect(toggle).toBeInTheDocument();
|
||||
|
||||
await user.click(toggle);
|
||||
expect(consoleLog).toHaveBeenCalledWith("update", { theme: "g80" });
|
||||
|
||||
await user.click(toggle);
|
||||
expect(consoleLog).toHaveBeenCalledWith("update", { theme: "g10" });
|
||||
});
|
||||
|
||||
it("should render select when render prop is set to select", async () => {
|
||||
render(ThemeSelect);
|
||||
|
||||
const select = screen.getByLabelText("Themes");
|
||||
expect(select).toBeInTheDocument();
|
||||
|
||||
await user.selectOptions(select, "g100");
|
||||
expect(consoleLog).toHaveBeenCalledWith("update", { theme: "g100" });
|
||||
|
||||
await user.selectOptions(select, "white");
|
||||
expect(consoleLog).toHaveBeenCalledWith("update", { theme: "white" });
|
||||
});
|
||||
|
||||
it("should render custom select when render prop is set to select and custom select options are provided", async () => {
|
||||
render(ThemeSelectCustom);
|
||||
|
||||
const select = screen.getByLabelText("Select a theme");
|
||||
expect(select).toBeInTheDocument();
|
||||
|
||||
await user.selectOptions(select, "g100");
|
||||
expect(consoleLog).toHaveBeenCalledWith("update", { theme: "g100" });
|
||||
|
||||
await user.selectOptions(select, "white");
|
||||
expect(consoleLog).toHaveBeenCalledWith("update", { theme: "white" });
|
||||
});
|
||||
});
|
10
tests/Theme/ThemeSelect.test.svelte
Normal file
10
tests/Theme/ThemeSelect.test.svelte
Normal file
|
@ -0,0 +1,10 @@
|
|||
<script lang="ts">
|
||||
import { Theme } from "carbon-components-svelte";
|
||||
</script>
|
||||
|
||||
<Theme
|
||||
render="select"
|
||||
on:update={({ detail }) => {
|
||||
console.log("update", detail);
|
||||
}}
|
||||
/>
|
15
tests/Theme/ThemeSelectCustom.test.svelte
Normal file
15
tests/Theme/ThemeSelectCustom.test.svelte
Normal file
|
@ -0,0 +1,15 @@
|
|||
<script lang="ts">
|
||||
import { Theme } from "carbon-components-svelte";
|
||||
</script>
|
||||
|
||||
<Theme
|
||||
render="select"
|
||||
select={{
|
||||
themes: ["white", "g90", "g100"],
|
||||
labelText: "Select a theme",
|
||||
inline: true,
|
||||
}}
|
||||
on:update={({ detail }) => {
|
||||
console.log("update", detail);
|
||||
}}
|
||||
/>
|
10
tests/Theme/ThemeToggle.test.svelte
Normal file
10
tests/Theme/ThemeToggle.test.svelte
Normal file
|
@ -0,0 +1,10 @@
|
|||
<script lang="ts">
|
||||
import { Theme } from "carbon-components-svelte";
|
||||
</script>
|
||||
|
||||
<Theme
|
||||
render="toggle"
|
||||
on:update={({ detail }) => {
|
||||
console.log("update", detail);
|
||||
}}
|
||||
/>
|
17
tests/Theme/ThemeToggleCustom.test.svelte
Normal file
17
tests/Theme/ThemeToggleCustom.test.svelte
Normal file
|
@ -0,0 +1,17 @@
|
|||
<script lang="ts">
|
||||
import { Theme } from "carbon-components-svelte";
|
||||
</script>
|
||||
|
||||
<Theme
|
||||
render="toggle"
|
||||
toggle={{
|
||||
themes: ["g10", "g80"],
|
||||
labelA: "Enable dark mode",
|
||||
labelB: "Enable dark mode",
|
||||
hideLabel: true,
|
||||
size: "sm",
|
||||
}}
|
||||
on:update={({ detail }) => {
|
||||
console.log("update", detail);
|
||||
}}
|
||||
/>
|
Loading…
Add table
Add a link
Reference in a new issue