/** * Tests for ArsLeaderboard * @vi-environment jsdom */ import { beforeEach, describe, expect, it } from "vitest"; import { ArsLeaderboard } from "./ars-leaderboard.js"; describe("ArsLeaderboard", () => { let element: ArsLeaderboard; beforeEach(() => { document.body.innerHTML = ""; element = new ArsLeaderboard(); }); it("registers the ars-leaderboard custom element", () => { expect(customElements.get("ars-leaderboard")).toBe(ArsLeaderboard); }); it("creates a shadow root on construction", () => { expect(element.shadowRoot).toBeTruthy(); }); it("defaults max-entries to 10", () => { expect(element.maxEntries).toBe(10); }); it("reflects max-entries attribute", () => { element.setAttribute("max-entries", "5"); expect(element.maxEntries).toBe(5); }); it("renders entries sorted by score descending", () => { document.body.appendChild(element); element.setEntries([ { id: "a", name: "Alice", score: 100 }, { id: "b", name: "Bob", score: 300 }, { id: "c", name: "Carol", score: 200 }, ]); const rows = element.shadowRoot?.querySelectorAll("tbody tr"); expect(rows?.length).toBe(3); expect(rows?.[0].querySelector(".leaderboard__name")?.textContent).toBe("Bob"); expect(rows?.[1].querySelector(".leaderboard__name")?.textContent).toBe("Carol"); expect(rows?.[2].querySelector(".leaderboard__name")?.textContent).toBe("Alice"); }); it("limits entries to max-entries", () => { element.maxEntries = 2; document.body.appendChild(element); element.setEntries([ { id: "a", name: "Alice", score: 100 }, { id: "b", name: "Bob", score: 300 }, { id: "c", name: "Carol", score: 200 }, ]); const rows = element.shadowRoot?.querySelectorAll("tbody tr"); expect(rows?.length).toBe(2); }); it("highlights the row matching highlight-id", () => { document.body.appendChild(element); element.highlightId = "b"; element.setEntries([ { id: "a", name: "Alice", score: 100 }, { id: "b", name: "Bob", score: 300 }, ]); const rows = element.shadowRoot?.querySelectorAll("tbody tr"); // Sorted by score descending: Bob (300) first, Alice (100) second. expect(rows?.[0].classList.contains("leaderboard__row--highlight")).toBe(true); expect(rows?.[1].classList.contains("leaderboard__row--highlight")).toBe(false); }); it("escapes HTML in names", () => { document.body.appendChild(element); element.setEntries([ { id: "x", name: "", score: 0 }, ]); const nameCell = element.shadowRoot?.querySelector(".leaderboard__name"); expect(nameCell?.textContent).toBe(""); expect(nameCell?.innerHTML).not.toContain("