| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202 |
- import { act, assertEquals, cleanup, fireEvent, render } from "./setup.ts";
- import ThemeToggle from "../../islands/ThemeToggle.tsx";
- function resetState() {
- document.documentElement.classList.remove("dark");
- localStorage.removeItem("theme");
- }
- Deno.test({
- name: "ThemeToggle - renders moon icon in light mode by default",
- fn() {
- resetState();
- const { container } = render(<ThemeToggle />);
- const icon = container.querySelector("i")!;
- assertEquals(icon.classList.contains("bi-moon-stars"), true);
- assertEquals(icon.classList.contains("bi-sun"), false);
- cleanup();
- },
- sanitizeResources: false,
- sanitizeOps: false,
- });
- Deno.test({
- name: "ThemeToggle - renders sun icon when dark class is present",
- fn() {
- resetState();
- document.documentElement.classList.add("dark");
- let container: HTMLElement;
- act(() => {
- ({ container } = render(<ThemeToggle />));
- });
- const icon = container!.querySelector("i")!;
- assertEquals(icon.classList.contains("bi-sun"), true);
- assertEquals(icon.classList.contains("bi-moon-stars"), false);
- cleanup();
- resetState();
- },
- sanitizeResources: false,
- sanitizeOps: false,
- });
- Deno.test({
- name: "ThemeToggle - click adds dark class to documentElement",
- fn() {
- resetState();
- const { container } = render(<ThemeToggle />);
- const icon = container.querySelector("i")!;
- act(() => {
- fireEvent.click(icon);
- });
- assertEquals(document.documentElement.classList.contains("dark"), true);
- cleanup();
- resetState();
- },
- sanitizeResources: false,
- sanitizeOps: false,
- });
- Deno.test({
- name: "ThemeToggle - click toggles icon from moon to sun",
- fn() {
- resetState();
- const { container } = render(<ThemeToggle />);
- const icon = container.querySelector("i")!;
- assertEquals(icon.classList.contains("bi-moon-stars"), true);
- act(() => {
- fireEvent.click(icon);
- });
- const updatedIcon = container.querySelector("i")!;
- assertEquals(updatedIcon.classList.contains("bi-sun"), true);
- assertEquals(updatedIcon.classList.contains("bi-moon-stars"), false);
- cleanup();
- resetState();
- },
- sanitizeResources: false,
- sanitizeOps: false,
- });
- Deno.test({
- name: "ThemeToggle - second click removes dark class",
- fn() {
- resetState();
- const { container } = render(<ThemeToggle />);
- const icon = container.querySelector("i")!;
- act(() => {
- fireEvent.click(icon);
- });
- assertEquals(document.documentElement.classList.contains("dark"), true);
- act(() => {
- fireEvent.click(container.querySelector("i")!);
- });
- assertEquals(document.documentElement.classList.contains("dark"), false);
- cleanup();
- resetState();
- },
- sanitizeResources: false,
- sanitizeOps: false,
- });
- Deno.test({
- name: "ThemeToggle - click persists 'dark' to localStorage",
- fn() {
- resetState();
- const { container } = render(<ThemeToggle />);
- act(() => {
- fireEvent.click(container.querySelector("i")!);
- });
- assertEquals(localStorage.getItem("theme"), "dark");
- cleanup();
- resetState();
- },
- sanitizeResources: false,
- sanitizeOps: false,
- });
- Deno.test({
- name: "ThemeToggle - second click persists 'light' to localStorage",
- fn() {
- resetState();
- const { container } = render(<ThemeToggle />);
- act(() => {
- fireEvent.click(container.querySelector("i")!);
- });
- act(() => {
- fireEvent.click(container.querySelector("i")!);
- });
- assertEquals(localStorage.getItem("theme"), "light");
- cleanup();
- resetState();
- },
- sanitizeResources: false,
- sanitizeOps: false,
- });
- Deno.test({
- name: "ThemeToggle - click dispatches ThemeChange event",
- fn() {
- resetState();
- let eventDetail: boolean | null = null;
- const listener = (e: Event) => {
- eventDetail = (e as CustomEvent).detail;
- };
- document.addEventListener("ThemeChange", listener);
- const { container } = render(<ThemeToggle />);
- act(() => {
- fireEvent.click(container.querySelector("i")!);
- });
- assertEquals(eventDetail, true);
- document.removeEventListener("ThemeChange", listener);
- cleanup();
- resetState();
- },
- sanitizeResources: false,
- sanitizeOps: false,
- });
- Deno.test({
- name: "ThemeToggle - has hover classes for both themes",
- fn() {
- resetState();
- const { container } = render(<ThemeToggle />);
- const icon = container.querySelector("i")!;
- assertEquals(icon.className.includes("hover:text-blue-600"), true);
- assertEquals(icon.className.includes("dark:hover:text-blue-400"), true);
- cleanup();
- },
- sanitizeResources: false,
- sanitizeOps: false,
- });
- Deno.test({
- name: "ThemeToggle - has correct title attribute in light mode",
- fn() {
- resetState();
- const { container } = render(<ThemeToggle />);
- const icon = container.querySelector("i")!;
- assertEquals(icon.getAttribute("title"), "Switch to dark mode");
- cleanup();
- },
- sanitizeResources: false,
- sanitizeOps: false,
- });
- Deno.test({
- name: "ThemeToggle - has correct title attribute in dark mode",
- fn() {
- resetState();
- document.documentElement.classList.add("dark");
- let container: HTMLElement;
- act(() => {
- ({ container } = render(<ThemeToggle />));
- });
- const icon = container!.querySelector("i")!;
- assertEquals(icon.getAttribute("title"), "Switch to light mode");
- cleanup();
- resetState();
- },
- sanitizeResources: false,
- sanitizeOps: false,
- });
|