import { describe, expect, it } from "vite-plus/test"; import { renderToStaticMarkup } from "react-dom/server"; import { resolveThreadLineageWindow, ThreadLineageRowList } from "./ThreadRelationshipsControl"; const rows = Array.from({ length: 20 }, (_, index) => `row-${index}`); function renderRowList(visibleCount: number) { const { visibleRows, hiddenCount } = resolveThreadLineageWindow(rows, visibleCount); return renderToStaticMarkup( {}}> {visibleRows.map((row) => (
  • {row}
  • ))}
    , ); } describe("thread lineage row list", () => { it("shows six rows before the first expansion", () => { const { visibleRows, hiddenCount } = resolveThreadLineageWindow(rows, 6); expect(visibleRows).toEqual(rows.slice(0, 6)); expect(hiddenCount).toBe(14); }); it("offers one page at a time", () => { expect(renderRowList(6)).toContain("Show 12 more"); expect(renderRowList(6 + 12)).toContain("Show 2 more"); }); it("omits the expansion affordance when everything fits", () => { const markup = renderRowList(rows.length); expect(markup).not.toContain("more"); expect(resolveThreadLineageWindow(rows.slice(0, 6), 6).hiddenCount).toBe(0); }); it("keeps the rows in a bounded, labelled scroll region and the button outside it", () => { const markup = renderRowList(6); const list = /]*)>/.exec(markup)?.[1] ?? ""; expect(list).toContain('aria-label="Related threads"'); expect(list).toContain("max-h-[13.5rem]"); expect(list).toContain("overflow-y-auto"); expect(list).toContain("overscroll-contain"); expect(markup.indexOf("")).toBeLessThan(markup.indexOf("