// @vitest-environment jsdom // // E28 S3b: the chip family (docs/DESIGN.md "One primitive per button family"). One geometry for a // filter, an applied narrowing, a tag and a suggestion, where five files had five. import { afterEach, describe, expect, it, vi } from "vitest"; import { cleanup, fireEvent, render, screen } from "@testing-library/react"; import { Chip, DismissibleChip } from "./Chip"; import { chipClass } from "./chipStyles"; afterEach(cleanup); describe("Chip", () => { it("is a pill on the 24px floor that never submits a form, and a toggle announces its state", () => { const onSubmit = vi.fn((e: { preventDefault: () => void }) => e.preventDefault()); render(
2024
, ); const chip = screen.getByRole("button", { name: "2024" }); expect(chip.className).toContain("rounded-full"); expect(chip.className).toContain("h-6"); expect(chip.className).toContain("touch-target"); expect(chip.getAttribute("aria-pressed")).toBe("false"); fireEvent.click(chip); expect(onSubmit).not.toHaveBeenCalled(); }); it("a removing chip is named by the removal and shows the ×", () => { const onClick = vi.fn(); render( Music , ); const chip = screen.getByRole("button", { name: "Remove Music" }); expect(chip.getAttribute("title")).toBe("Remove Music"); expect(chip.className).toContain("h-7"); expect(chip.querySelector("svg")).not.toBeNull(); fireEvent.click(chip); expect(onClick).toHaveBeenCalledOnce(); }); it("the measuring mirror lays out exactly like the chip it measures", () => { render( tag , ); const cls = screen.getByRole("button", { name: "tag" }).className; for (const c of chipClass("tag", "xs").split(" ")) expect(cls).toContain(c); }); }); describe("DismissibleChip", () => { it("is two sibling controls at most, never a button in a button", () => { const onAccept = vi.fn(); const onDismiss = vi.fn(); const { container } = render( Music , ); expect(container.querySelector("button button")).toBeNull(); fireEvent.click(screen.getByRole("button", { name: "Add the tag Music" })); fireEvent.click(screen.getByRole("button", { name: "Not now" })); expect(onAccept).toHaveBeenCalledOnce(); expect(onDismiss).toHaveBeenCalledOnce(); }); it("with no body action the label is text, and only the × is a control", () => { render( {}} dismissLabel="Remove Year: 2024"> Year: 2024 , ); expect(screen.getAllByRole("button")).toHaveLength(1); expect(screen.getByText("Year: 2024").closest("button")).toBeNull(); }); });