import { expect, it } from "vitest"; import { render, screen, within } from "@testing-library/react"; import TokenHeatmap from "./TokenHeatmap"; it("colors positive attributions green and negative red, and keeps tooltips", () => { render( , ); const love = screen.getByText("love"); const not = screen.getByText("not"); expect(love.style.backgroundColor).toContain("16, 185, 129"); // emerald expect(not.style.backgroundColor).toContain("239, 68, 68"); // red expect(love.title).toBe("attribution: 0.900"); expect(not.title).toBe("attribution: -0.500"); }); it("wraps at word boundaries but keeps subword tokens joined in one atomic group", () => { const { container } = render( , ); // Outer container must be a wrapping flex row so long inputs break onto // new lines instead of overflowing as one unbreakable line. const outer = container.querySelector("p"); expect(outer?.className).toContain("flex"); expect(outer?.className).toContain("flex-wrap"); expect(outer?.className).toContain("gap-x"); // horizontal spacing between words // "I", "love", "Fable" — three words, "Fable" made of two BPE subtokens. const groups = container.querySelectorAll('[data-testid="word-group"]'); expect(groups).toHaveLength(3); const fableGroup = groups[2]; expect(within(fableGroup).getByText("Fa")).toBeInTheDocument(); expect(within(fableGroup).getByText("ble")).toBeInTheDocument(); }); it("renders newline tokens as a break instead of literal Ċ text", () => { const { container } = render( , ); expect(screen.queryByText("Ċ")).not.toBeInTheDocument(); expect(screen.queryByText(/Ċ/)).not.toBeInTheDocument(); expect(container.querySelectorAll('[data-testid="newline-break"]')).toHaveLength(2); expect(screen.getByText("it")).toBeInTheDocument(); expect(screen.getByText("3")).toBeInTheDocument(); });