import "@testing-library/jest-dom"; import { render, screen } from "@testing-library/react"; import Table from "./Table"; const columns = [ { key: "name", header: "Name" }, { key: "role", header: "Role" }, { key: "status", header: "Status" }, ]; const rows = [ { id: 1, name: "Alice Chen", role: "Engineer", status: "active" }, { id: 2, name: "Bob Smith", role: "Designer", status: "inactive" }, { id: 3, name: "Carol White", role: "Manager", status: "active" }, ]; describe("Table", () => { test("renders all column headers", () => { render(); expect(screen.getByText("Name")).toBeInTheDocument(); expect(screen.getByText("Role")).toBeInTheDocument(); expect(screen.getByText("Status")).toBeInTheDocument(); }); test("renders all row data", () => { render(
); expect(screen.getByText("Alice Chen")).toBeInTheDocument(); expect(screen.getByText("Bob Smith")).toBeInTheDocument(); expect(screen.getByText("Carol White")).toBeInTheDocument(); }); test("renders the correct number of rows", () => { const { container } = render(
); const bodyRows = container.querySelectorAll("tbody tr"); expect(bodyRows).toHaveLength(3); }); test("renders the correct number of columns per row", () => { const { container } = render(
); const firstRowCells = container.querySelectorAll("tbody tr:first-child td"); expect(firstRowCells).toHaveLength(3); }); test("uses a custom render function for a column", () => { const columnsWithRender = [ ...columns.slice(0, 2), { key: "status", header: "Status", render: (value: unknown) => ( {(value as string).toUpperCase()} ), }, ]; render(
); const cells = screen.getAllByTestId("status-cell"); expect(cells).toHaveLength(3); expect(cells[0]).toHaveTextContent("ACTIVE"); expect(cells[1]).toHaveTextContent("INACTIVE"); }); test("passes the full row to the render function", () => { const renderFn = vi.fn((_value: unknown, row: Record) => ( {row.name as string} )); const columnsWithRender = [ { key: "status", header: "Status", render: renderFn }, ]; render(
); expect(renderFn).toHaveBeenCalledWith("active", rows[0]); }); test("renders the caption when provided", () => { render(
); expect(screen.getByText("Team members")).toBeInTheDocument(); }); test("does not render a caption element when caption is omitted", () => { const { container } = render(
); expect(container.querySelector("caption")).not.toBeInTheDocument(); }); test("applies an additional className to the table", () => { const { container } = render(
, ); expect(container.querySelector("table")).toHaveClass( "table", "custom-class", ); }); test("uses a custom rowKey field for row identity", () => { const rowsWithSlug = [ { slug: "alice", name: "Alice", role: "Engineer", status: "active" }, { slug: "bob", name: "Bob", role: "Designer", status: "inactive" }, ]; const { container } = render(
, ); expect(container.querySelectorAll("tbody tr")).toHaveLength(2); }); test("renders an empty tbody when rows is empty", () => { const { container } = render(
); const bodyRows = container.querySelectorAll("tbody tr"); expect(bodyRows).toHaveLength(0); }); test("column headers use scope=col for accessibility", () => { const { container } = render(
); const headers = container.querySelectorAll("th"); for (const th of headers) { expect(th).toHaveAttribute("scope", "col"); } }); });