nextui/packages/hooks/use-theme/__tests__/use-theme.test.tsx
WK 0d217e466f
refactor: optimization (#5362)
* chore(deps): bump RA versions

* chore(deps): bump RA versions

* chore(deps): bump RA versions

* chore: changeset

* chore(deps): remove unnecessary dependencies

* fix(calendar): typing issue

* refactor(system): remove unused SupportedCalendars

* refactor(system): move I18nProviderProps to type

* refactor: use `spectrumCalendarProps<DateValue>["createCalendar"]`

* feat: add consistent-type-imports

* fix: eslint

* chore: add changeset

* refactor: remove unused deps
2025-06-09 14:17:44 +08:00

150 lines
4.8 KiB
TypeScript

import type {Theme} from "../src";
import * as React from "react";
import {render, act} from "@testing-library/react";
import {useTheme, ThemeProps} from "../src";
const TestComponent = ({defaultTheme}: {defaultTheme?: Theme}) => {
const {theme, setTheme} = useTheme(defaultTheme);
return (
<div>
<span data-testid="theme-display">{theme}</span>
<button type="button" onClick={() => setTheme(ThemeProps.DARK)}>
Set Dark
</button>
<button type="button" onClick={() => setTheme(ThemeProps.LIGHT)}>
Set Light
</button>
<button type="button" onClick={() => setTheme(ThemeProps.SYSTEM)}>
Set System
</button>
</div>
);
};
TestComponent.displayName = "TestComponent";
const localStorageMock = (() => {
let store: {[key: string]: string} = {};
return {
getItem: (key: string) => store[key] || null,
setItem: (key: string, value: string) => {
store[key] = value;
},
clear: () => {
store = {};
},
};
})();
Object.defineProperty(window, "localStorage", {
value: localStorageMock,
});
describe("useTheme hook", () => {
beforeEach(() => {
jest.clearAllMocks();
localStorage.clear();
document.documentElement.className = "";
});
it("should initialize with default theme if no theme is stored in localStorage", () => {
const {getByTestId} = render(<TestComponent />);
expect(getByTestId("theme-display").textContent).toBe(ThemeProps.LIGHT);
expect(document.documentElement.classList.contains(ThemeProps.LIGHT)).toBe(true);
});
it("should initialize with the given theme if no theme is stored in localStorage", () => {
const customTheme = "purple-dark";
const {getByTestId} = render(<TestComponent defaultTheme={customTheme} />);
expect(getByTestId("theme-display").textContent).toBe(customTheme);
expect(document.documentElement.classList.contains(customTheme)).toBe(true);
});
it("should initialize with stored theme from localStorage", () => {
localStorage.setItem(ThemeProps.KEY, ThemeProps.DARK);
const {getByTestId} = render(<TestComponent />);
expect(localStorage.getItem(ThemeProps.KEY)).toBe(ThemeProps.DARK);
expect(getByTestId("theme-display").textContent).toBe(ThemeProps.DARK);
expect(document.documentElement.classList.contains(ThemeProps.DARK)).toBe(true);
});
it("should set new theme correctly and update localStorage and DOM (dark)", () => {
const {getByText, getByTestId} = render(<TestComponent />);
act(() => {
getByText("Set Dark").click();
});
expect(getByTestId("theme-display").textContent).toBe(ThemeProps.DARK);
expect(localStorage.getItem(ThemeProps.KEY)).toBe(ThemeProps.DARK);
expect(document.documentElement.classList.contains(ThemeProps.DARK)).toBe(true);
});
it("should set new theme correctly and update localStorage and DOM (light)", () => {
const {getByText, getByTestId} = render(<TestComponent />);
act(() => {
getByText("Set Light").click();
});
expect(getByTestId("theme-display").textContent).toBe(ThemeProps.LIGHT);
expect(localStorage.getItem(ThemeProps.KEY)).toBe(ThemeProps.LIGHT);
expect(document.documentElement.classList.contains(ThemeProps.LIGHT)).toBe(true);
});
it("should set new theme correctly and update localStorage and DOM (system - prefers-color-scheme: light)", () => {
const {getByText, getByTestId} = render(<TestComponent />);
Object.defineProperty(window, "matchMedia", {
writable: true,
value: jest.fn().mockImplementation((query) => ({
matches: false,
media: query,
onchange: null,
addEventListener: jest.fn(),
removeEventListener: jest.fn(),
dispatchEvent: jest.fn(),
})),
});
act(() => {
getByText("Set System").click();
});
expect(getByTestId("theme-display").textContent).toBe(ThemeProps.SYSTEM);
expect(localStorage.getItem(ThemeProps.KEY)).toBe(ThemeProps.SYSTEM);
expect(document.documentElement.classList.contains(ThemeProps.LIGHT)).toBe(true);
});
it("should set new theme correctly and update localStorage and DOM (system - prefers-color-scheme: dark)", () => {
const {getByText, getByTestId} = render(<TestComponent />);
Object.defineProperty(window, "matchMedia", {
writable: true,
value: jest.fn().mockImplementation((query) => ({
matches: true,
media: query,
onchange: null,
addEventListener: jest.fn(),
removeEventListener: jest.fn(),
dispatchEvent: jest.fn(),
})),
});
act(() => {
getByText("Set System").click();
});
expect(getByTestId("theme-display").textContent).toBe(ThemeProps.SYSTEM);
expect(localStorage.getItem(ThemeProps.KEY)).toBe(ThemeProps.SYSTEM);
expect(document.documentElement.classList.contains(ThemeProps.DARK)).toBe(true);
});
});