test(tui): cover description layout boundaries

This commit is contained in:
Peter Steinberger
2026-02-14 19:06:11 +01:00
parent fc4b913d96
commit e03b0ce058

View File

@@ -1,4 +1,5 @@
import { describe, expect, it } from "vitest";
import { visibleWidth } from "../../terminal/ansi.js";
import { SearchableSelectList, type SearchableSelectListTheme } from "./searchable-select-list.js";
const mockTheme: SearchableSelectListTheme = {
@@ -48,6 +49,60 @@ describe("SearchableSelectList", () => {
expect(output).toContain(tail);
});
it("does not show description layout at width 40 (boundary)", () => {
const items = [
{ value: "one", label: "one", description: "desc" },
{ value: "two", label: "two", description: "desc" },
];
const list = new SearchableSelectList(items, 5, mockTheme);
list.setSelectedIndex(1); // ensure first row is not selected so description styling is applied
const output = list.render(40).join("\n");
expect(output).not.toContain("(desc)");
});
it("shows description layout at width 41 (boundary)", () => {
const items = [
{ value: "one", label: "one", description: "desc" },
{ value: "two", label: "two", description: "desc" },
];
const list = new SearchableSelectList(items, 5, mockTheme);
list.setSelectedIndex(1); // ensure first row is not selected so description styling is applied
const output = list.render(41).join("\n");
expect(output).toContain("(desc)");
});
it("keeps ANSI-highlighted description rows within terminal width", () => {
const ansiTheme: SearchableSelectListTheme = {
selectedPrefix: (t) => t,
selectedText: (t) => t,
description: (t) => t,
scrollInfo: (t) => t,
noMatch: (t) => t,
searchPrompt: (t) => t,
searchInput: (t) => t,
matchHighlight: (t) => `\u001b[31m${t}\u001b[0m`,
};
const label = `provider/${"x".repeat(80)}`;
const items = [
{ value: label, label, description: "Some description text that should not overflow" },
{ value: "other", label: "other", description: "Other description" },
];
const list = new SearchableSelectList(items, 5, ansiTheme);
list.setSelectedIndex(1); // make first row non-selected so description styling is applied
for (const ch of "provider") {
list.handleInput(ch);
}
const width = 80;
const output = list.render(width);
for (const line of output) {
expect(visibleWidth(line)).toBeLessThanOrEqual(width);
}
});
it("filters items when typing", () => {
const list = new SearchableSelectList(testItems, 5, mockTheme);