import { clsx, cx } from "./cx"; describe("cx utility", () => { describe("basic class merging", () => { it("returns empty string for no arguments", () => { expect(cx()).toBe(""); }); it("returns single class unchanged", () => { expect(cx("text-red-500")).toBe("text-red-500"); }); it("combines multiple classes", () => { const result = cx("p-4", "m-2", "bg-white"); expect(result).toContain("p-4"); expect(result).toContain("m-2"); expect(result).toContain("bg-white"); }); }); describe("Tailwind conflict resolution", () => { it("resolves conflicting padding classes (last wins)", () => { expect(cx("p-4", "p-8")).toBe("p-8"); }); it("resolves conflicting text color classes", () => { expect(cx("text-red-500", "text-blue-500")).toBe("text-blue-500"); }); it("resolves conflicting margin classes", () => { expect(cx("m-2", "m-6")).toBe("m-6"); }); }); describe("custom font-variants class group", () => { it("resolves conflicting font variant classes", () => { expect(cx("heading1", "body1")).toBe("body1"); }); it("resolves heading vs label variants", () => { expect(cx("heading3", "label2")).toBe("label2"); }); it("keeps non-conflicting classes alongside font variants", () => { const result = cx("heading1", "text-red-500", "body2"); expect(result).toContain("body2"); expect(result).toContain("text-red-500"); expect(result).not.toContain("heading1"); }); }); describe("custom button-sizes class group", () => { it("resolves conflicting button size classes", () => { expect(cx("btn-small", "btn-large")).toBe("btn-large"); }); it("resolves btn-medium vs btn-x-large", () => { expect(cx("btn-medium", "btn-x-large")).toBe("btn-x-large"); }); }); describe("conditional and falsy values (via clsx)", () => { it("filters out falsy values", () => { expect(cx("p-4", false, null, undefined, 0, "", "m-2")).toBe("p-4 m-2"); }); it("supports conditional object syntax", () => { expect(cx({ "bg-red-500": true, "bg-blue-500": false })).toBe( "bg-red-500" ); }); it("supports arrays", () => { expect(cx(["p-2", "m-4"])).toBe("p-2 m-4"); }); it("supports mixed arguments", () => { const result = cx("base", ["arr1"], { conditional: true }, undefined); expect(result).toContain("base"); expect(result).toContain("arr1"); expect(result).toContain("conditional"); }); }); describe("exports", () => { it("exports clsx function", () => { expect(typeof clsx).toBe("function"); }); }); });