import { describe, expect, it } from "vitest"; import { resolveTerminalSelectionActionPosition, selectPendingTerminalEventEntries, selectTerminalEventEntriesAfterSnapshot, shouldHandleTerminalSelectionMouseUp, terminalSelectionActionDelayForClickCount, } from "./ThreadTerminalDrawer"; describe("resolveTerminalSelectionActionPosition", () => { it("prefers the selection rect over the last pointer position", () => { expect( resolveTerminalSelectionActionPosition({ bounds: { left: 100, top: 50, width: 500, height: 220 }, selectionRect: { right: 260, bottom: 140 }, pointer: { x: 520, y: 200 }, viewport: { width: 1024, height: 768 }, }), ).toEqual({ x: 260, y: 144, }); }); it("falls back to the pointer position when no selection rect is available", () => { expect( resolveTerminalSelectionActionPosition({ bounds: { left: 100, top: 50, width: 500, height: 220 }, selectionRect: null, pointer: { x: 180, y: 130 }, viewport: { width: 1024, height: 768 }, }), ).toEqual({ x: 180, y: 130, }); }); it("clamps the pointer fallback into the terminal drawer bounds", () => { expect( resolveTerminalSelectionActionPosition({ bounds: { left: 100, top: 50, width: 500, height: 220 }, selectionRect: null, pointer: { x: 720, y: 340 }, viewport: { width: 1024, height: 768 }, }), ).toEqual({ x: 600, y: 270, }); expect( resolveTerminalSelectionActionPosition({ bounds: { left: 100, top: 50, width: 500, height: 220 }, selectionRect: null, pointer: { x: 40, y: 20 }, viewport: { width: 1024, height: 768 }, }), ).toEqual({ x: 100, y: 50, }); }); it("delays multi-click selection actions so triple-click selection can complete", () => { expect(terminalSelectionActionDelayForClickCount(1)).toBe(0); expect(terminalSelectionActionDelayForClickCount(2)).toBe(260); expect(terminalSelectionActionDelayForClickCount(3)).toBe(260); }); it("only handles mouseup when the selection gesture started in the terminal", () => { expect(shouldHandleTerminalSelectionMouseUp(true, 0)).toBe(true); expect(shouldHandleTerminalSelectionMouseUp(false, 0)).toBe(false); expect(shouldHandleTerminalSelectionMouseUp(true, 1)).toBe(false); }); it("replays only terminal events newer than the open snapshot", () => { expect( selectTerminalEventEntriesAfterSnapshot( [ { id: 1, event: { threadId: "thread-1", terminalId: "default", createdAt: "2026-04-02T20:00:00.000Z", type: "output", data: "before", }, }, { id: 2, event: { threadId: "thread-1", terminalId: "default", createdAt: "2026-04-02T20:00:01.000Z", type: "output", data: "after", }, }, ], "2026-04-02T20:00:00.500Z", ).map((entry) => entry.id), ).toEqual([2]); }); it("applies only terminal events that have not already been consumed", () => { expect( selectPendingTerminalEventEntries( [ { id: 1, event: { threadId: "thread-1", terminalId: "default", createdAt: "2026-04-02T20:00:00.000Z", type: "output", data: "one", }, }, { id: 2, event: { threadId: "thread-1", terminalId: "default", createdAt: "2026-04-02T20:00:01.000Z", type: "output", data: "two", }, }, ], 1, ).map((entry) => entry.id), ).toEqual([2]); }); });