import React from "react";
import { render, screen } from "@testing-library/react";
import { Badge } from "./badge";
describe("Badge", () => {
it("renders a badge element with the correct content", () => {
render(5);
const badge = screen.getByText("5");
expect(badge).toBeInTheDocument();
});
it("renders as a sup element by default", () => {
render(3);
const badge = screen.getByRole("status");
expect(badge.tagName).toBe("SUP");
});
it("has role='status' by default for accessibility", () => {
render(12);
const badge = screen.getByRole("status");
expect(badge).toHaveAttribute("role", "status");
});
it("applies aria-label for screen reader accessibility", () => {
render(3);
const badge = screen.getByRole("status");
expect(badge).toHaveAttribute("aria-label", "3 unread messages");
});
it("renders with nested span element for styling", () => {
render(5);
const badge = screen.getByRole("status");
const span = badge.querySelector("span");
expect(span).toBeInTheDocument();
expect(span?.textContent).toBe("5");
});
it("applies custom id when provided", () => {
render(
10
);
const badge = screen.getByRole("status");
expect(badge).toHaveAttribute("id", "notification-badge");
});
it("applies custom className when provided via classes prop", () => {
render(
7
);
const badge = screen.getByRole("status");
expect(badge).toHaveClass("custom-badge-class");
});
it("applies custom inline styles when provided", () => {
render(
99+
);
const badge = screen.getByRole("status");
expect(badge).toHaveAttribute("style");
expect(badge).toHaveStyle({
fontSize: "1rem",
});
});
describe("variant prop", () => {
it("applies data-badge='rounded' when variant is 'rounded'", () => {
render(
5
);
const badge = screen.getByRole("status");
expect(badge).toHaveAttribute("data-badge", "rounded");
});
it("does not apply data-badge attribute when variant is undefined", () => {
render(3);
const badge = screen.getByRole("status");
expect(badge).not.toHaveAttribute("data-badge");
});
});
describe("children rendering", () => {
it("renders numeric children correctly", () => {
render(123);
expect(screen.getByText("123")).toBeInTheDocument();
});
it("renders string children correctly", () => {
render(NEW);
expect(screen.getByText("NEW")).toBeInTheDocument();
});
it("renders React element children correctly", () => {
render(
★
);
expect(screen.getByTestId("custom-icon")).toBeInTheDocument();
});
});
describe("accessibility", () => {
it("is accessible with proper aria-label", () => {
render(12);
const badge = screen.getByRole("status", { name: "12 items in cart" });
expect(badge).toBeInTheDocument();
});
it("can override role attribute if needed", () => {
render(
i
);
// role="note" should be applied via props spread
const badge = screen.getByText("i").closest("sup");
expect(badge).toHaveAttribute("role", "note");
});
it("supports additional ARIA attributes", () => {
render(
5
);
const badge = screen.getByRole("status");
expect(badge).toHaveAttribute("aria-live", "polite");
expect(badge).toHaveAttribute("aria-atomic", "true");
});
});
describe("integration", () => {
it("renders correctly within text content", () => {
render(
Messages
3
);
expect(screen.getByText("Messages")).toBeInTheDocument();
expect(screen.getByText("3")).toBeInTheDocument();
});
it("renders multiple badges independently", () => {
render(
1
2
3
);
const badges = screen.getAllByRole("status");
expect(badges).toHaveLength(3);
expect(badges[2]).toHaveAttribute("data-badge", "rounded");
});
});
describe("props spreading", () => {
it("forwards additional props to the UI component", () => {
render(
5
);
const badge = screen.getByTestId("custom-badge");
expect(badge).toHaveAttribute("data-custom", "value");
});
});
});