import React from "react"; import { describe, it, expect } from "vitest"; import { render, screen } from "@testing-library/react"; import { Cluster } from "./cluster"; import type { ClusterProps } from "./cluster.types"; describe("Cluster Component", () => { describe("Rendering", () => { it("should render with default props", () => { render(Content); const cluster = screen.getByTestId("cluster"); expect(cluster).toBeInTheDocument(); expect(cluster.tagName).toBe("DIV"); expect(cluster).toHaveClass("cluster"); }); it("should render children correctly", () => { render( Tag 1 Tag 2 Tag 3 ); expect(screen.getByText("Tag 1")).toBeInTheDocument(); expect(screen.getByText("Tag 2")).toBeInTheDocument(); expect(screen.getByText("Tag 3")).toBeInTheDocument(); }); it("should render with text content", () => { render(Plain text content); expect(screen.getByText("Plain text content")).toBeInTheDocument(); }); it("should render with multiple children types", () => { render( Span Link ); expect(screen.getByText("Span")).toBeInTheDocument(); expect(screen.getByText("Button")).toBeInTheDocument(); expect(screen.getByText("Link")).toBeInTheDocument(); }); }); describe("Polymorphic Rendering (as prop)", () => { it("should render as div by default", () => { render(Content); expect(screen.getByTestId("cluster").tagName).toBe("DIV"); }); it("should render as ul when as='ul'", () => { render(
  • Item 1
  • Item 2
  • ); expect(screen.getByTestId("cluster").tagName).toBe("UL"); }); it("should render as ol when as='ol'", () => { render(
  • Item 1
  • Item 2
  • ); expect(screen.getByTestId("cluster").tagName).toBe("OL"); }); it("should render as nav when as='nav'", () => { render( Link 1 Link 2 ); expect(screen.getByTestId("cluster").tagName).toBe("NAV"); }); it("should render as section when as='section'", () => { render( Content ); expect(screen.getByTestId("cluster").tagName).toBe("SECTION"); }); }); describe("Gap Prop", () => { it("should apply gap='0' class", () => { render( Content ); expect(screen.getByTestId("cluster")).toHaveClass("cluster-gap-0"); }); it("should apply gap='xs' class", () => { render( Content ); expect(screen.getByTestId("cluster")).toHaveClass("cluster-gap-xs"); }); it("should apply gap='sm' class", () => { render( Content ); expect(screen.getByTestId("cluster")).toHaveClass("cluster-gap-sm"); }); it("should apply gap='md' class", () => { render( Content ); expect(screen.getByTestId("cluster")).toHaveClass("cluster-gap-md"); }); it("should apply gap='lg' class", () => { render( Content ); expect(screen.getByTestId("cluster")).toHaveClass("cluster-gap-lg"); }); it("should apply gap='xl' class", () => { render( Content ); expect(screen.getByTestId("cluster")).toHaveClass("cluster-gap-xl"); }); it("should work without gap prop", () => { render(Content); const cluster = screen.getByTestId("cluster"); expect(cluster).toHaveClass("cluster"); expect(cluster).not.toHaveClass("cluster-gap-0"); expect(cluster).not.toHaveClass("cluster-gap-xs"); expect(cluster).not.toHaveClass("cluster-gap-sm"); }); }); describe("Justify Prop (Horizontal Alignment)", () => { it("should apply justify='start' class", () => { render( Content ); expect(screen.getByTestId("cluster")).toHaveClass("cluster-justify-start"); }); it("should apply justify='center' class", () => { render( Content ); expect(screen.getByTestId("cluster")).toHaveClass("cluster-justify-center"); }); it("should apply justify='end' class", () => { render( Content ); expect(screen.getByTestId("cluster")).toHaveClass("cluster-justify-end"); }); it("should apply justify='between' class", () => { render( Content ); expect(screen.getByTestId("cluster")).toHaveClass("cluster-justify-between"); }); it("should work without justify prop", () => { render(Content); const cluster = screen.getByTestId("cluster"); expect(cluster).not.toHaveClass("cluster-justify-start"); expect(cluster).not.toHaveClass("cluster-justify-center"); }); }); describe("Align Prop (Vertical Alignment)", () => { it("should apply align='start' class", () => { render( Content ); expect(screen.getByTestId("cluster")).toHaveClass("cluster-align-start"); }); it("should apply align='center' class", () => { render( Content ); expect(screen.getByTestId("cluster")).toHaveClass("cluster-align-center"); }); it("should apply align='end' class", () => { render( Content ); expect(screen.getByTestId("cluster")).toHaveClass("cluster-align-end"); }); it("should apply align='baseline' class", () => { render( Content ); expect(screen.getByTestId("cluster")).toHaveClass("cluster-align-baseline"); }); it("should work without align prop", () => { render(Content); const cluster = screen.getByTestId("cluster"); expect(cluster).not.toHaveClass("cluster-align-start"); expect(cluster).not.toHaveClass("cluster-align-center"); }); }); describe("Combined Props", () => { it("should apply gap and justify together", () => { render( Content ); const cluster = screen.getByTestId("cluster"); expect(cluster).toHaveClass("cluster"); expect(cluster).toHaveClass("cluster-gap-md"); expect(cluster).toHaveClass("cluster-justify-center"); }); it("should apply gap and align together", () => { render( Content ); const cluster = screen.getByTestId("cluster"); expect(cluster).toHaveClass("cluster"); expect(cluster).toHaveClass("cluster-gap-lg"); expect(cluster).toHaveClass("cluster-align-baseline"); }); it("should apply all props together", () => { render( Content ); const cluster = screen.getByTestId("cluster"); expect(cluster).toHaveClass("cluster"); expect(cluster).toHaveClass("cluster-gap-sm"); expect(cluster).toHaveClass("cluster-justify-between"); expect(cluster).toHaveClass("cluster-align-center"); }); it("should combine all props with polymorphic as prop", () => { render( Link ); const cluster = screen.getByTestId("cluster"); expect(cluster.tagName).toBe("NAV"); expect(cluster).toHaveClass("cluster"); expect(cluster).toHaveClass("cluster-gap-md"); expect(cluster).toHaveClass("cluster-justify-center"); expect(cluster).toHaveClass("cluster-align-baseline"); }); }); describe("ClassName and Classes Props", () => { it("should merge className prop with utility classes", () => { render( Content ); const cluster = screen.getByTestId("cluster"); expect(cluster).toHaveClass("cluster"); expect(cluster).toHaveClass("custom-class"); }); it("should merge classes prop with utility classes", () => { render( Content ); const cluster = screen.getByTestId("cluster"); expect(cluster).toHaveClass("cluster"); expect(cluster).toHaveClass("another-class"); }); it("should merge both className and classes", () => { render( Content ); const cluster = screen.getByTestId("cluster"); expect(cluster).toHaveClass("cluster"); expect(cluster).toHaveClass("custom"); expect(cluster).toHaveClass("another"); }); it("should merge custom classes with all utility classes", () => { render( Content ); const cluster = screen.getByTestId("cluster"); expect(cluster).toHaveClass("cluster"); expect(cluster).toHaveClass("cluster-gap-md"); expect(cluster).toHaveClass("cluster-justify-center"); expect(cluster).toHaveClass("cluster-align-baseline"); expect(cluster).toHaveClass("custom"); expect(cluster).toHaveClass("utility"); }); }); describe("Inline Styles", () => { it("should apply inline styles via styles prop", () => { render( Content ); const cluster = screen.getByTestId("cluster"); expect(cluster).toHaveStyle({ maxWidth: "500px" }); }); it("should apply inline styles via style prop", () => { render( Content ); const cluster = screen.getByTestId("cluster"); expect(cluster).toHaveStyle({ border: "1px solid red" }); }); it("should apply CSS custom properties", () => { render( Content ); const cluster = screen.getByTestId("cluster"); expect(cluster).toHaveStyle({ "--custom-color": "blue" }); }); }); describe("Ref Forwarding", () => { it("should forward ref to the underlying element", () => { const ref = { current: null as HTMLDivElement | null }; render( Content ); expect(ref.current).toBeInstanceOf(HTMLDivElement); expect(ref.current).toBe(screen.getByTestId("cluster")); }); it("should forward ref with polymorphic as prop", () => { const ref = { current: null as HTMLElement | null }; render( Content ); expect(ref.current).toBeInstanceOf(HTMLElement); expect(ref.current?.tagName).toBe("NAV"); }); }); describe("ARIA and Accessibility Attributes", () => { it("should accept aria-label", () => { render( Content ); expect(screen.getByTestId("cluster")).toHaveAttribute("aria-label", "Tag cloud"); }); it("should accept aria-labelledby", () => { render( <>

    Filter Tags

    Tag 1 ); expect(screen.getByTestId("cluster")).toHaveAttribute("aria-labelledby", "cluster-title"); }); it("should accept aria-describedby", () => { render( <>

    Select tags to filter results

    Tag 1 ); expect(screen.getByTestId("cluster")).toHaveAttribute("aria-describedby", "cluster-desc"); }); it("should accept role attribute", () => { render( Content ); expect(screen.getByTestId("cluster")).toHaveAttribute("role", "group"); }); it("should accept data attributes", () => { render( Content ); expect(screen.getByTestId("cluster")).toHaveAttribute("data-component", "tag-cloud"); }); it("should accept id attribute", () => { render( Content ); expect(screen.getByTestId("cluster")).toHaveAttribute("id", "tags-cluster"); }); }); describe("Edge Cases", () => { it("should handle empty children", () => { render(); expect(screen.getByTestId("cluster")).toBeInTheDocument(); expect(screen.getByTestId("cluster")).toBeEmptyDOMElement(); }); it("should handle null children", () => { render({null}); expect(screen.getByTestId("cluster")).toBeInTheDocument(); }); it("should handle undefined children", () => { render({undefined}); expect(screen.getByTestId("cluster")).toBeInTheDocument(); }); it("should handle false children (conditional rendering)", () => { const shouldShow = false; render({shouldShow && Hidden}); expect(screen.getByTestId("cluster")).toBeInTheDocument(); expect(screen.queryByText("Hidden")).not.toBeInTheDocument(); }); it("should handle fragments", () => { render( <> Item 1 Item 2 ); expect(screen.getByText("Item 1")).toBeInTheDocument(); expect(screen.getByText("Item 2")).toBeInTheDocument(); }); it("should handle mixed content types", () => { render( Text node Element {null} {undefined} {false} ); expect(screen.getByText("Text node")).toBeInTheDocument(); expect(screen.getByText("Element")).toBeInTheDocument(); expect(screen.getByText("Button")).toBeInTheDocument(); }); }); describe("Real-World Usage Patterns", () => { it("should render tag cloud correctly", () => { const tags = ["React", "TypeScript", "CSS", "Accessibility"]; render( {tags.map((tag) => ( {tag} ))} ); const cluster = screen.getByTestId("cluster"); expect(cluster).toHaveClass("cluster-gap-sm"); expect(cluster).toHaveClass("cluster-justify-center"); tags.forEach((tag) => { expect(screen.getByText(tag)).toBeInTheDocument(); }); }); it("should render button group correctly", () => { render( ); expect(screen.getByTestId("cluster")).toHaveClass("cluster-gap-md"); expect(screen.getByText("Action 1")).toBeInTheDocument(); expect(screen.getByText("Action 2")).toBeInTheDocument(); expect(screen.getByText("Action 3")).toBeInTheDocument(); }); it("should render navigation links with baseline alignment", () => { render( Home About Contact ); const cluster = screen.getByTestId("cluster"); expect(cluster.tagName).toBe("NAV"); expect(cluster).toHaveClass("cluster-gap-lg"); expect(cluster).toHaveClass("cluster-align-baseline"); expect(cluster).toHaveClass("cluster-justify-center"); }); it("should render filter pills with semantic list", () => { render(
  • ); const cluster = screen.getByTestId("cluster"); expect(cluster.tagName).toBe("UL"); expect(cluster).toHaveClass("cluster-gap-sm"); }); it("should render badge cluster with zero gap", () => { render( Active New Beta ); expect(screen.getByTestId("cluster")).toHaveClass("cluster-gap-xs"); expect(screen.getByText("Active")).toBeInTheDocument(); expect(screen.getByText("New")).toBeInTheDocument(); expect(screen.getByText("Beta")).toBeInTheDocument(); }); }); describe("TypeScript Type Safety", () => { it("should accept valid ClusterProps", () => { const props: ClusterProps = { gap: "md", justify: "center", align: "baseline", as: "nav", className: "custom", children: Content, }; render(); expect(screen.getByTestId("cluster")).toBeInTheDocument(); }); it("should accept all SpacingScale values", () => { const spacingScales: ClusterProps["gap"][] = ["0", "xs", "sm", "md", "lg", "xl"]; spacingScales.forEach((gap, index) => { render( Content ); expect(screen.getByTestId(`cluster-${index}`)).toHaveClass(`cluster-gap-${gap}`); }); }); it("should accept all ClusterElement values", () => { const elements: ClusterProps["as"][] = ["div", "ul", "ol", "nav", "section"]; elements.forEach((element, index) => { if (!element) return; render( Content ); expect(screen.getByTestId(`cluster-${index}`).tagName).toBe(element.toUpperCase()); }); }); }); });