import { render, screen, cleanup } from "@testing-library/react"; import userEvent from "@testing-library/user-event"; import assert from "node:assert"; import { describe, test, mock, afterEach, } from "node:test"; import { BlockTable } from "./index"; describe("BlockTable", () => { afterEach(() => { cleanup(); }); /* COMMON */ test("renders without crashing", () => { render(); const table = document.querySelector("table"); assert.notStrictEqual(table, null); }); test("applies base class", () => { render(); const table = document.querySelector("table"); assert.strictEqual(table?.className.includes("customTable"), true); }); test("passes extra attributes", () => { render( ); const table = document.querySelector("table"); assert.strictEqual(table?.getAttribute("data-testid"), "data-table"); }); /* CHILDREN VS ITEMS */ test("renders children when provided", () => { render( Table caption Data ); assert.notStrictEqual(screen.queryByText("Table caption"), null); assert.notStrictEqual(screen.queryByText("Data"), null); }); test("renders items in tbody", () => { const items = [ { type: "tbody" as const, rows: [ { cols: [ { children: "John" }, { children: "Doe" }, ], }, ], }, ]; render(); assert.notStrictEqual(screen.queryByText("John"), null); assert.notStrictEqual(screen.queryByText("Doe"), null); }); test("renders items in thead", () => { const items = [ { type: "thead" as const, rows: [ { cols: [ { children: "First Name" }, { children: "Last Name" }, ], }, ], }, ]; render(); assert.notStrictEqual(screen.queryByText("First Name"), null); assert.notStrictEqual(screen.queryByText("Last Name"), null); }); /* FORMAT CELL */ test("formatCell is called for each cell", () => { const formatCell = mock.fn((cell) => cell); const items = [ { type: "tbody" as const, rows: [ { cols: [ { children: "Data 1" }, { children: "Data 2" }, ], }, ], }, ]; render(); assert.strictEqual(formatCell.mock.calls.length, 2); }); /* AUTO LABELS */ test("adds data attributes when isAutoLabels=true", () => { const items = [ { type: "thead" as const, rows: [ { cols: [ { html: "Name Label", children: "Name" }, ], }, ], }, { type: "tbody" as const, rows: [ { cols: [ { children: "John" }, ], }, ], }, ]; render(); const headerCell = document.querySelector("thead th"); const bodyCell = document.querySelector("tbody td"); assert.strictEqual(headerCell?.getAttribute("data-css-cell-label"), "Name Label"); assert.strictEqual(bodyCell?.getAttribute("data-css-cell-label"), "Name Label"); }); test("no data attributes when isAutoLabels=false", () => { const items = [ { type: "thead" as const, rows: [ { cols: [ { html: "Name Label", children: "Name" }, ], }, ], }, { type: "tbody" as const, rows: [ { cols: [ { children: "John" }, ], }, ], }, ]; render(); const headerCell = document.querySelector("thead th"); const bodyCell = document.querySelector("tbody td"); // Атрибут может присутствовать, но должен быть пустым assert.strictEqual(headerCell?.getAttribute("data-css-cell-label"), ""); assert.strictEqual(bodyCell?.getAttribute("data-css-cell-label"), ""); }); /* CUSTOM GET TABLE ITEM */ test("uses custom getTableItem", () => { const getTableItem = mock.fn(() => Custom Caption); render(); assert.strictEqual(getTableItem.mock.calls.length, 1); assert.notStrictEqual(screen.queryByText("Custom Caption"), null); }); /* CLICK HANDLERS */ test("calls row onClick", async () => { const onClick = mock.fn(); const user = userEvent.setup(); const items = [ { type: "tbody" as const, rows: [ { onClick, cols: [ { children: "Click me" } ], }, ], }, ]; render(); await user.click(screen.getByText("Click me")); assert.strictEqual(onClick.mock.calls.length, 1); }); test("calls cell onClick", async () => { const onClick = mock.fn(); const user = userEvent.setup(); const items = [ { type: "tbody" as const, rows: [ { cols: [ { children: "Click me", onClick } ], }, ], }, ]; render(); await user.click(screen.getByText("Click me")); assert.strictEqual(onClick.mock.calls.length, 1); }); /* HTML CONTENT */ test("renders HTML content in caption", () => { const items = [ { type: "caption" as const, html: "Strong text", }, ]; render(); assert.notStrictEqual(document.querySelector("strong"), null); }); /* SORT BUTTON */ test("renders sort button in th", () => { const items = [ { type: "thead" as const, rows: [ { cols: [ { children: "Column", sort: { label: "Sort me" }, }, ], }, ], }, ]; render(); const th = document.querySelector("th"); assert.notStrictEqual(th, null); assert.notStrictEqual(screen.queryByText("Sort me"), null); assert.notStrictEqual(screen.queryByRole("button", { name: "Sort me" }), null); }); });