import { describe, it, expect } from "vitest"; import { render, screen } from "@testing-library/react"; import React from "react"; import Title from "./title"; describe("Title Component", () => { describe("Rendering", () => { it("should render with default h2 level", () => { render(Default Title); const heading = screen.getByRole("heading", { level: 2 }); expect(heading).toBeInTheDocument(); expect(heading).toHaveTextContent("Default Title"); }); it("should render children content", () => { render(Test Content); expect(screen.getByText("Test Content")).toBeInTheDocument(); }); it("should render complex children with elements", () => { render( <span data-testid="icon">📄</span> <span>Document Title</span> ); expect(screen.getByTestId("icon")).toBeInTheDocument(); expect(screen.getByText("Document Title")).toBeInTheDocument(); }); }); describe("Heading Levels", () => { it.each([ ["h1", 1], ["h2", 2], ["h3", 3], ["h4", 4], ["h5", 5], ["h6", 6], ] as const)("should render %s with level %i", (level, numericLevel) => { render(Heading {level}); const heading = screen.getByRole("heading", { level: numericLevel }); expect(heading).toBeInTheDocument(); expect(heading.tagName.toLowerCase()).toBe(level); }); }); describe("Props and Attributes", () => { it("should apply id attribute", () => { render(Title with ID); const heading = screen.getByRole("heading", { level: 2 }); expect(heading).toHaveAttribute("id", "test-heading"); }); it("should apply data-ui attribute", () => { render(Styled Title); const heading = screen.getByRole("heading", { level: 2 }); expect(heading).toHaveAttribute("data-ui", "section-title"); }); it("should apply className", () => { render(Classed Title); const heading = screen.getByRole("heading", { level: 2 }); expect(heading).toHaveClass("custom-class"); }); it("should apply multiple class names", () => { render(Title); const heading = screen.getByRole("heading", { level: 2 }); expect(heading).toHaveClass("class-one"); expect(heading).toHaveClass("class-two"); }); it("should apply inline styles", () => { const styles = { color: "red", fontSize: "24px" }; render(Styled Title); const heading = screen.getByRole("heading", { level: 2 }); // Browsers convert color values, so check for rgb format expect(heading).toHaveStyle({ color: "rgb(255, 0, 0)", fontSize: "24px" }); }); }); describe("Accessibility", () => { it("should have proper heading role", () => { render(Accessible Title); const heading = screen.getByRole("heading", { level: 1 }); expect(heading).toBeInTheDocument(); }); it("should support aria-label", () => { render( Dashboard ); const heading = screen.getByRole("heading", { level: 2 }); expect(heading).toHaveAttribute("aria-label", "Dashboard overview"); }); it("should support aria-labelledby", () => { render( <>
Section Label
Title ); const heading = screen.getByRole("heading", { level: 2 }); expect(heading).toHaveAttribute("aria-labelledby", "label-element"); }); it("should support aria-describedby", () => { render( <>

This is a description

Title ); const heading = screen.getByRole("heading", { level: 2 }); expect(heading).toHaveAttribute("aria-describedby", "description"); }); it("should be findable by accessible name", () => { render(Findable Heading); expect( screen.getByRole("heading", { name: "Findable Heading" }) ).toBeInTheDocument(); }); }); describe("Ref Forwarding", () => { it("should forward ref to the heading element", () => { const ref = React.createRef(); render(Title with Ref); expect(ref.current).toBeInstanceOf(HTMLHeadingElement); expect(ref.current?.tagName.toLowerCase()).toBe("h2"); expect(ref.current?.textContent).toBe("Title with Ref"); }); it("should allow focus via ref", () => { const ref = React.createRef(); render(Focusable Title); ref.current?.focus(); expect(ref.current).toHaveFocus(); }); }); describe("Component API", () => { it("should have displayName set", () => { expect(Title.displayName).toBe("Title"); }); it("should accept all native heading attributes", () => { render( Title ); const heading = screen.getByTestId("custom-heading"); expect(heading).toHaveAttribute("tabIndex", "0"); expect(heading).toHaveAttribute("title", "Tooltip text"); }); }); describe("Edge Cases", () => { it("should handle empty string children", () => { render({""}); const heading = screen.getByRole("heading", { level: 2 }); expect(heading).toBeInTheDocument(); expect(heading).toHaveTextContent(""); }); it("should handle null children gracefully", () => { render({null}); const heading = screen.getByRole("heading", { level: 2 }); expect(heading).toBeInTheDocument(); }); it("should handle multiple text nodes", () => { render( Text one {" "} Text two ); const heading = screen.getByRole("heading", { level: 2 }); expect(heading).toHaveTextContent("Text one Text two"); }); it("should handle conditional rendering", () => { const showIcon = true; render( {showIcon && <span data-testid="icon">📄</span>} Document ); expect(screen.getByTestId("icon")).toBeInTheDocument(); }); }); describe("Integration with UI Component", () => { it("should pass through all UI component props", () => { render( Integration Test ); const heading = screen.getByRole("heading", { level: 3 }); expect(heading).toHaveAttribute("id", "integration-test"); expect(heading).toHaveClass("test-class"); expect(heading).toHaveStyle({ margin: "10px" }); expect(heading).toHaveAttribute("data-custom", "value"); }); }); describe("Memoization", () => { it("should be a memoized component", () => { // Title is wrapped with React.memo, so it should have the memo properties expect(Title.$$typeof).toBeDefined(); }); }); }); describe("Title Component - Backwards Compatibility", () => { describe("Migration from Heading", () => { it("should work with level prop (new API)", () => { render(New API); expect(screen.getByRole("heading", { level: 2 })).toHaveTextContent("New API"); }); it("should use h2 as default (changed from h3)", () => { // This tests the new default behavior render(Default is now h2); expect(screen.getByRole("heading", { level: 2 })).toBeInTheDocument(); }); }); }); describe("Title Size Variants", () => { it("should render with size prop and correct data-title", () => { render(Large); const heading = screen.getByRole("heading", { level: 2 }); expect(heading).toHaveAttribute("data-title", "lg"); }); it.each([ ["xs"], ["sm"], ["md"], ["lg"], ["xl"], ["2xl"], ] as const)("should render size variant %s", (size) => { render({size} Title); const heading = screen.getByRole("heading", { level: 2 }); expect(heading).toHaveAttribute("data-title", size); }); }); describe("Title Color Variants", () => { it("should render with color prop and correct data-title", () => { render(Primary); const heading = screen.getByRole("heading", { level: 2 }); expect(heading).toHaveAttribute("data-title", "primary"); }); it.each([ ["primary"], ["secondary"], ["accent"], ["muted"], ["inherit"], ] as const)("should render color variant %s", (color) => { render({color} Title); const heading = screen.getByRole("heading", { level: 2 }); expect(heading).toHaveAttribute("data-title", color); }); }); describe("Combined Size and Color Variants", () => { it("should combine size and color in data-title attribute", () => { render(Combined); const heading = screen.getByRole("heading", { level: 2 }); expect(heading).toHaveAttribute("data-title", "lg primary"); }); it("should render only size when no color provided", () => { render(Size Only); const heading = screen.getByRole("heading", { level: 2 }); expect(heading).toHaveAttribute("data-title", "xl"); }); it("should render only color when no size provided", () => { render(Color Only); const heading = screen.getByRole("heading", { level: 2 }); expect(heading).toHaveAttribute("data-title", "accent"); }); it("should render no data-title when no variants provided", () => { render(No Variants); const heading = screen.getByRole("heading", { level: 2 }); expect(heading).not.toHaveAttribute("data-title"); }); }); describe("Backward Compatibility with New Props", () => { it("should maintain className functionality with variants", () => { render(Custom); const heading = screen.getByRole("heading", { level: 2 }); expect(heading).toHaveClass("custom-class"); expect(heading).toHaveAttribute("data-title", "lg"); }); it("should maintain styles prop functionality with variants", () => { render(Styled); const heading = screen.getByRole("heading", { level: 2 }); expect(heading).toHaveStyle({ marginTop: "2rem" }); expect(heading).toHaveAttribute("data-title", "primary"); }); it("should preserve semantic heading level with visual size", () => { render(Large h3); const heading = screen.getByRole("heading", { level: 3 }); expect(heading).toBeInTheDocument(); expect(heading).toHaveAttribute("data-title", "xl"); expect(heading.tagName.toLowerCase()).toBe("h3"); }); it("should work with all existing props plus new variants", () => { render( Full Props Test ); const heading = screen.getByRole("heading", { level: 2 }); expect(heading).toHaveAttribute("id", "test-id"); expect(heading).toHaveClass("test-class"); expect(heading).toHaveAttribute("data-ui", "section-title"); expect(heading).toHaveAttribute("data-title", "lg primary"); expect(heading).toHaveStyle({ padding: "1rem" }); }); });