claude-code/src/utils/__tests__/horizontalScroll.test.ts
2026-04-02 20:28:08 +08:00

164 lines
5.6 KiB
TypeScript

import { describe, expect, test } from "bun:test";
import { calculateHorizontalScrollWindow } from "../horizontalScroll";
describe("calculateHorizontalScrollWindow", () => {
// Basic scenarios
test("all items fit within available width", () => {
const result = calculateHorizontalScrollWindow([10, 10, 10], 50, 3, 1);
expect(result).toEqual({
startIndex: 0,
endIndex: 3,
showLeftArrow: false,
showRightArrow: false,
});
});
test("single item selected within view", () => {
const result = calculateHorizontalScrollWindow([20], 50, 3, 0);
expect(result).toEqual({
startIndex: 0,
endIndex: 1,
showLeftArrow: false,
showRightArrow: false,
});
});
test("selected item at beginning", () => {
const widths = [10, 10, 10, 10, 10];
const result = calculateHorizontalScrollWindow(widths, 25, 3, 0);
expect(result.startIndex).toBe(0);
expect(result.showLeftArrow).toBe(false);
expect(result.showRightArrow).toBe(true);
expect(result.endIndex).toBeGreaterThan(0);
});
test("selected item at end", () => {
const widths = [10, 10, 10, 10, 10];
const result = calculateHorizontalScrollWindow(widths, 25, 3, 4);
expect(result.endIndex).toBe(5);
expect(result.showRightArrow).toBe(false);
expect(result.showLeftArrow).toBe(true);
});
test("selected item beyond visible range scrolls right", () => {
const widths = [10, 10, 10, 10, 10];
const result = calculateHorizontalScrollWindow(widths, 20, 3, 4);
expect(result.startIndex).toBeLessThanOrEqual(4);
expect(result.endIndex).toBeGreaterThan(4);
});
test("selected item before visible range scrolls left", () => {
const widths = [10, 10, 10, 10, 10];
// Select last item first (simulates initial scroll to end)
const result = calculateHorizontalScrollWindow(widths, 20, 3, 0);
expect(result.startIndex).toBe(0);
});
// Arrow indicators
test("showLeftArrow when items hidden on left", () => {
const widths = [10, 10, 10, 10, 10];
const result = calculateHorizontalScrollWindow(widths, 15, 3, 4);
expect(result.showLeftArrow).toBe(true);
});
test("showRightArrow when items hidden on right", () => {
const widths = [10, 10, 10, 10, 10];
const result = calculateHorizontalScrollWindow(widths, 15, 3, 0);
expect(result.showRightArrow).toBe(true);
});
test("no arrows when all items visible", () => {
const result = calculateHorizontalScrollWindow([10, 10], 50, 3, 0);
expect(result.showLeftArrow).toBe(false);
expect(result.showRightArrow).toBe(false);
});
test("both arrows when items hidden on both sides", () => {
const widths = [10, 10, 10, 10, 10, 10, 10];
// Select middle item with limited width
const result = calculateHorizontalScrollWindow(widths, 20, 3, 3);
// Both arrows may or may not show depending on exact fit
expect(result.startIndex).toBeLessThanOrEqual(3);
expect(result.endIndex).toBeGreaterThan(3);
});
// Boundary conditions
test("empty itemWidths array", () => {
const result = calculateHorizontalScrollWindow([], 50, 3, 0);
expect(result).toEqual({
startIndex: 0,
endIndex: 0,
showLeftArrow: false,
showRightArrow: false,
});
});
test("single item", () => {
const result = calculateHorizontalScrollWindow([30], 50, 3, 0);
expect(result).toEqual({
startIndex: 0,
endIndex: 1,
showLeftArrow: false,
showRightArrow: false,
});
});
test("available width is 0", () => {
const result = calculateHorizontalScrollWindow([10, 10], 0, 3, 0);
// With 0 width, nothing fits except maybe the selected
expect(result.startIndex).toBe(0);
});
test("item wider than available width", () => {
const result = calculateHorizontalScrollWindow([100], 50, 3, 0);
// Total width > available, but only one item
expect(result.startIndex).toBe(0);
expect(result.endIndex).toBe(1);
});
test("all items same width", () => {
const widths = [10, 10, 10, 10];
const result = calculateHorizontalScrollWindow(widths, 25, 3, 2);
expect(result.startIndex).toBeLessThanOrEqual(2);
expect(result.endIndex).toBeGreaterThan(2);
});
test("varying item widths", () => {
const widths = [5, 20, 5, 20, 5];
const result = calculateHorizontalScrollWindow(widths, 20, 3, 2);
expect(result.startIndex).toBeLessThanOrEqual(2);
expect(result.endIndex).toBeGreaterThan(2);
});
test("firstItemHasSeparator adds separator width to first item", () => {
const widths = [10, 10, 10, 10, 10];
const withSep = calculateHorizontalScrollWindow(widths, 20, 3, 4, true);
const withoutSep = calculateHorizontalScrollWindow(widths, 20, 3, 4, false);
// Both should include selected index 4
expect(withSep.endIndex).toBe(5);
expect(withoutSep.endIndex).toBe(5);
});
test("selectedIdx in middle of overflow", () => {
const widths = [10, 10, 10, 10, 10, 10, 10];
const result = calculateHorizontalScrollWindow(widths, 25, 3, 3);
expect(result.startIndex).toBeLessThanOrEqual(3);
expect(result.endIndex).toBeGreaterThan(3);
});
test("scroll snaps to show selected at left edge", () => {
const widths = [10, 10, 10, 10, 10];
// Jump to last item which forces scroll
const result = calculateHorizontalScrollWindow(widths, 20, 3, 4);
expect(result.startIndex).toBeLessThanOrEqual(4);
expect(result.endIndex).toBe(5);
});
test("scroll snaps to show selected at right edge", () => {
const widths = [10, 10, 10, 10, 10];
const result = calculateHorizontalScrollWindow(widths, 20, 3, 4);
expect(result.endIndex).toBe(5);
expect(result.startIndex).toBeGreaterThan(0);
});
});