Files
oh-my-pi/packages/coding-agent/test/hook-input-timeout.test.ts
T
2026-03-03 15:09:46 +01:00

76 lines
2.0 KiB
TypeScript

import { afterEach, beforeAll, describe, expect, it, vi } from "bun:test";
import { HookInputComponent } from "@oh-my-pi/pi-coding-agent/modes/components/hook-input";
import { getThemeByName, setThemeInstance } from "@oh-my-pi/pi-coding-agent/modes/theme/theme";
import type { TUI } from "@oh-my-pi/pi-tui";
beforeAll(async () => {
const theme = await getThemeByName("dark");
if (!theme) {
throw new Error("Failed to load dark theme for tests");
}
setThemeInstance(theme);
});
describe("HookInputComponent timeout", () => {
afterEach(() => {
vi.useRealTimers();
});
it("resets timeout on user activity and still expires when idle", () => {
vi.useFakeTimers();
const onSubmit = vi.fn();
const onCancel = vi.fn();
const onTimeout = vi.fn();
const tui = { requestRender: vi.fn() } as unknown as TUI;
const component = new HookInputComponent("Prompt", undefined, onSubmit, onCancel, {
timeout: 1_000,
tui,
onTimeout,
});
vi.advanceTimersByTime(900);
component.handleInput("a");
vi.advanceTimersByTime(900);
component.handleInput("\x7f");
vi.advanceTimersByTime(900);
expect(onTimeout).not.toHaveBeenCalled();
expect(onCancel).not.toHaveBeenCalled();
vi.advanceTimersByTime(200);
expect(onTimeout).toHaveBeenCalledTimes(1);
expect(onCancel).toHaveBeenCalledTimes(1);
component.dispose();
});
it("preserves submit behavior", () => {
vi.useFakeTimers();
const onSubmit = vi.fn();
const onCancel = vi.fn();
const onTimeout = vi.fn();
const tui = { requestRender: vi.fn() } as unknown as TUI;
const component = new HookInputComponent("Prompt", undefined, onSubmit, onCancel, {
timeout: 1_000,
tui,
onTimeout,
});
component.handleInput("h");
component.handleInput("i");
component.handleInput("\n");
expect(onSubmit).toHaveBeenCalledTimes(1);
expect(onSubmit).toHaveBeenCalledWith("hi");
expect(onCancel).not.toHaveBeenCalled();
expect(onTimeout).not.toHaveBeenCalled();
component.dispose();
});
});