import { afterEach, expect, test } from "bun:test";
import { act } from "react";
import { testRender } from "../../../renderers/opentui/test-utils";
import type { CloudSearchDocument, CloudSearchHit } from "../../../api-client";
import { SearchDocumentView } from "./document-view";
// One unbroken run, so every wrapped line is exactly as wide as the wrap width
// and the rightmost printed column is the wrap width rather than wherever the
// last word happened to end.
const PARAGRAPH = "forward-looking-statement.".repeat(40);
const HIT = {
id: "hit-1",
docType: "news",
sourceId: "doc-1",
chunkIndex: 0,
ticker: "NVDA",
publishedAt: "2026-08-31T12:00:00.000Z",
title: "Press Release",
url: "https://example.com/doc-1",
snippet: "lorem ipsum dolor",
score: 1,
metadata: { source: "Business Wire" },
} as unknown as CloudSearchHit;
const DOCUMENT = {
docType: "news",
sourceId: "doc-1",
ticker: "NVDA",
title: "Press Release",
url: "https://example.com/doc-1",
publishedAt: "2026-08-31T12:00:00.000Z",
chunks: Array.from({ length: 4 }, (_, index) => ({
id: `chunk-${index}`,
chunkIndex: index,
body: PARAGRAPH,
metadata: { source: "Business Wire" },
})),
} as unknown as CloudSearchDocument;
let testSetup: Awaited> | undefined;
afterEach(async () => {
if (testSetup) {
await act(async () => {
testSetup!.renderer.destroy();
});
testSetup = undefined;
}
});
/**
* The wrap width, the scroll box's inset and its scrollbar are three separate
* subtractions from the same pane, and counting one of them twice is invisible
* in review: the text still renders, just short of the edge.
*/
for (const width of [60, 88, 120]) {
test(`paragraphs reach the column before the scrollbar at width ${width}`, async () => {
testSetup = await testRender(
,
{ width, height: 20 },
);
for (let frame = 0; frame < 3; frame += 1) {
await act(async () => {
await testSetup!.renderOnce();
});
}
const rows = testSetup.captureCharFrame().split("\n");
// The scrollbar owns the last column on every row it covers, so measure the
// text against the column before it.
const textRight = Math.max(...rows.map((row) => row.slice(0, width - 1).trimEnd().length));
expect(textRight).toBe(width - 1);
});
}