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);
});
});