import React from "react"; import { render, screen } from "@testing-library/react"; import { describe, it, expect } from "vitest"; import { Col } from "./col"; describe("Col Component", () => { describe("Rendering", () => { it("renders with default props", () => { render(Test content); expect(screen.getByText("Test content")).toBeInTheDocument(); }); it("renders as div by default", () => { const { container } = render(Content); const col = container.firstChild as HTMLElement; expect(col.tagName).toBe("DIV"); }); it("renders as specified element type", () => { const { container } = render(Content); const col = container.firstChild as HTMLElement; expect(col.tagName).toBe("SECTION"); }); it("renders as li element", () => { const { container } = render(Content); const col = container.firstChild as HTMLElement; expect(col.tagName).toBe("LI"); }); it("renders children correctly", () => { render( Child 1 Child 2 ); expect(screen.getByText("Child 1")).toBeInTheDocument(); expect(screen.getByText("Child 2")).toBeInTheDocument(); }); }); describe("No Base Class", () => { it("has no classes when no props provided", () => { const { container } = render(Content); const col = container.firstChild as HTMLElement; expect(col.className).toBe(""); }); it("does not have a base .col class", () => { const { container } = render(Content); const col = container.firstChild as HTMLElement; expect(col.classList.contains("col")).toBe(false); }); }); describe("Span Utilities", () => { it("applies col-1 utility class", () => { const { container } = render(Content); const col = container.firstChild as HTMLElement; expect(col).toHaveClass("col-1"); }); it("applies col-6 utility class", () => { const { container } = render(Content); const col = container.firstChild as HTMLElement; expect(col).toHaveClass("col-6"); }); it("applies col-12 utility class", () => { const { container } = render(Content); const col = container.firstChild as HTMLElement; expect(col).toHaveClass("col-12"); }); it("does not apply span class when span is undefined", () => { const { container } = render(Content); const col = container.firstChild as HTMLElement; expect(col.className).not.toMatch(/col-\d+/); }); // Test all span values [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12].forEach((spanValue) => { it(`applies col-${spanValue} for span={${spanValue}}`, () => { const { container } = render(Content); const col = container.firstChild as HTMLElement; expect(col).toHaveClass(`col-${spanValue}`); }); }); }); describe("Auto Width", () => { it("applies col-auto utility class", () => { const { container } = render(Content); const col = container.firstChild as HTMLElement; expect(col).toHaveClass("col-auto"); }); it("auto overrides span when both provided", () => { const { container } = render(Content); const col = container.firstChild as HTMLElement; expect(col).toHaveClass("col-auto"); expect(col).not.toHaveClass("col-6"); }); it("does not apply auto class when auto is false", () => { const { container } = render(Content); const col = container.firstChild as HTMLElement; expect(col).not.toHaveClass("col-auto"); expect(col).toHaveClass("col-6"); }); }); describe("Flex Column", () => { it("applies col-flex utility class when span is 'flex'", () => { const { container } = render(Content); const col = container.firstChild as HTMLElement; expect(col).toHaveClass("col-flex"); }); it("does not apply numeric col class when span is 'flex'", () => { const { container } = render(Content); const col = container.firstChild as HTMLElement; expect(col.className).not.toMatch(/col-\d+/); }); it("auto overrides flex when both provided", () => { const { container } = render(Content); const col = container.firstChild as HTMLElement; expect(col).toHaveClass("col-auto"); expect(col).not.toHaveClass("col-flex"); }); it("flex column works with offset", () => { const { container } = render(Content); const col = container.firstChild as HTMLElement; expect(col).toHaveClass("col-flex"); expect(col).toHaveClass("col-offset-2"); }); it("flex column works with order", () => { const { container } = render(Content); const col = container.firstChild as HTMLElement; expect(col).toHaveClass("col-flex"); expect(col).toHaveClass("col-order-first"); }); it("flex column works with combined props", () => { const { container } = render( Content ); const col = container.firstChild as HTMLElement; expect(col).toHaveClass("col-flex"); expect(col).toHaveClass("col-offset-1"); expect(col).toHaveClass("col-order-2"); }); }); describe("Offset Utilities", () => { it("applies col-offset-0 utility class", () => { const { container } = render(Content); const col = container.firstChild as HTMLElement; expect(col).toHaveClass("col-offset-0"); }); it("applies col-offset-3 utility class", () => { const { container } = render(Content); const col = container.firstChild as HTMLElement; expect(col).toHaveClass("col-offset-3"); }); it("applies col-offset-11 utility class", () => { const { container } = render(Content); const col = container.firstChild as HTMLElement; expect(col).toHaveClass("col-offset-11"); }); it("does not apply offset class when offset is undefined", () => { const { container } = render(Content); const col = container.firstChild as HTMLElement; expect(col.className).not.toMatch(/col-offset-/); }); // Test all offset values [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11].forEach((offsetValue) => { it(`applies col-offset-${offsetValue} for offset={${offsetValue}}`, () => { const { container } = render( Content ); const col = container.firstChild as HTMLElement; expect(col).toHaveClass(`col-offset-${offsetValue}`); }); }); }); describe("Order Utilities", () => { it("applies col-order-first utility class", () => { const { container } = render(Content); const col = container.firstChild as HTMLElement; expect(col).toHaveClass("col-order-first"); }); it("applies col-order-last utility class", () => { const { container } = render(Content); const col = container.firstChild as HTMLElement; expect(col).toHaveClass("col-order-last"); }); it("applies col-order-0 utility class", () => { const { container } = render(Content); const col = container.firstChild as HTMLElement; expect(col).toHaveClass("col-order-0"); }); it("applies col-order-5 utility class", () => { const { container } = render(Content); const col = container.firstChild as HTMLElement; expect(col).toHaveClass("col-order-5"); }); it("applies col-order-12 utility class", () => { const { container } = render(Content); const col = container.firstChild as HTMLElement; expect(col).toHaveClass("col-order-12"); }); it("does not apply order class when order is undefined", () => { const { container } = render(Content); const col = container.firstChild as HTMLElement; expect(col.className).not.toMatch(/col-order-/); }); // Test numeric order values [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12].forEach((orderValue) => { it(`applies col-order-${orderValue} for order={${orderValue}}`, () => { const { container } = render( Content ); const col = container.firstChild as HTMLElement; expect(col).toHaveClass(`col-order-${orderValue}`); }); }); }); describe("Combined Props", () => { it("applies span and offset together", () => { const { container } = render(Content); const col = container.firstChild as HTMLElement; expect(col).toHaveClass("col-6"); expect(col).toHaveClass("col-offset-3"); }); it("applies span and order together", () => { const { container } = render(Content); const col = container.firstChild as HTMLElement; expect(col).toHaveClass("col-4"); expect(col).toHaveClass("col-order-2"); }); it("applies span, offset, and order together", () => { const { container } = render( Content ); const col = container.firstChild as HTMLElement; expect(col).toHaveClass("col-4"); expect(col).toHaveClass("col-offset-2"); expect(col).toHaveClass("col-order-first"); }); it("applies auto, offset, and order together", () => { const { container } = render( Content ); const col = container.firstChild as HTMLElement; expect(col).toHaveClass("col-auto"); expect(col).toHaveClass("col-offset-1"); expect(col).toHaveClass("col-order-last"); }); }); describe("Custom Classes", () => { it("merges className prop with utility classes", () => { const { container } = render( Content ); const col = container.firstChild as HTMLElement; expect(col).toHaveClass("col-6"); expect(col).toHaveClass("custom-class"); }); it("merges classes prop with utility classes", () => { const { container } = render( Content ); const col = container.firstChild as HTMLElement; expect(col).toHaveClass("col-4"); expect(col).toHaveClass("another-class"); }); it("merges both className and classes props", () => { const { container } = render( Content ); const col = container.firstChild as HTMLElement; expect(col).toHaveClass("col-6"); expect(col).toHaveClass("class-one"); expect(col).toHaveClass("class-two"); }); it("allows custom classes without utility props", () => { const { container } = render( Content ); const col = container.firstChild as HTMLElement; expect(col).toHaveClass("custom-only"); }); }); describe("Ref Forwarding", () => { it("forwards ref to the underlying element", () => { const ref = { current: null }; render(Content); expect(ref.current).toBeInstanceOf(HTMLDivElement); }); it("forwards ref with custom element type", () => { const ref = { current: null }; render( Content ); expect(ref.current).toBeInstanceOf(HTMLElement); expect((ref.current as unknown as HTMLElement).tagName).toBe("SECTION"); }); }); describe("Additional Props", () => { it("passes through additional HTML attributes", () => { const { container } = render( Content ); const col = container.firstChild as HTMLElement; expect(col).toHaveAttribute("data-testid", "test-col"); expect(col).toHaveAttribute("aria-label", "Test Column"); }); it("handles id prop", () => { const { container } = render(Content); const col = container.firstChild as HTMLElement; expect(col).toHaveAttribute("id", "my-col"); }); }); });