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