import { describe, it, expect, afterEach, vi } from "vitest"; import "@testing-library/jest-dom/vitest"; import { render, cleanup, waitFor } from "@testing-library/react"; import userEvent from "@testing-library/user-event"; import { Spoiler } from "./Spoiler"; afterEach(cleanup); describe("wrapper element customization", () => { it("renders a span wrapper by default", () => { const { container } = render(Hello!); const element = container.firstElementChild!; expect(element).toBeInTheDocument(); expect(element.tagName).toBe("SPAN"); }); it("passes standard props to the element", () => { const { container } = render( Hello! ); const element = container.firstElementChild!; expect(element).toHaveClass("custom"); expect(element).toHaveAttribute("dir", "rtl"); }); it("can customize wrapper's tag via `tagName` prop", () => { const { container } = render( test ); const divElement = container.firstElementChild!; expect(divElement).toBeInTheDocument(); expect(divElement).toContainHTML('test'); }); it("attaches directly to the element given as children when `asChild` prop is used", () => { const { getByLabelText } = render(
); expect(getByLabelText("hello")).toBeInTheDocument(); expect(getByLabelText("hello").tagName).toBe("BLOCKQUOTE"); }); }); describe("controlled/uncontrolled Spoiler Component", () => { it("calls onHiddenChange with false when clicked (default is hidden)", async () => { const changeHandler = vi.fn(); const { getByText } = render( Click me ); await userEvent.click(getByText("Click me")); await waitFor(() => expect(changeHandler).toHaveBeenCalledWith(false)); }); it("calls onChange with true when clicked (defaultHidden is false)", async () => { const changeHandler = vi.fn(); const { getByText } = render( Click me ); await userEvent.click(getByText("Click me")); await waitFor(() => expect(changeHandler).toHaveBeenCalledWith(true)); }); it("controls Spoiler's visibility via `hidden` prop", () => { const { container, rerender } = render(); expect(container.firstElementChild!).toHaveAttribute("aria-expanded", "false"); rerender(); expect(container.firstElementChild!).not.toHaveAttribute("aria-expanded", "false"); }); }); describe("Spoiler options", () => { it("accepts custom spoiler painter options", () => { Hey; // @ts-expect-error - This should error in TypeScript due to unknown prop Hey; }); }); describe("content transitions via `transition` keyword", () => { it('renders one wrapper element when it is falsey or "none"', () => { const { getByText } = render( Spoiler Alert: Dumbledore joins Voldemort ); const element = getByText(/Voldemort/); expect(element).toBeInTheDocument(); expect(element.tagName).toBe("SPAN"); expect(element.parentElement?.tagName).not.toBe("SPAN"); }); it("renders with specified transition", () => { const { getByText } = render( Spoiler Alert: Frodo keeps the Ring ); const element = getByText(/Frodo/); expect(element).toBeInTheDocument(); // should be span within a span expect(element.tagName).toBe("SPAN"); expect(element.parentElement?.tagName).toBe("SPAN"); }); });