Something went wrong. Try again.
fork of prime agent with changes i want but are not upstreamable probqbly (and some fixes)
Something went wrong. Try again.
5.5 kB · 149 lines
TypeScript
at main
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150import { afterEach, describe, expect, test, vi } from "vitest";import { InteractiveMode } from "../src/modes/interactive/interactive-mode.js";
type FakeUi = { start: () => void; stop: () => void; requestRender: (force?: boolean) => void;};
type HandleCtrlZThis = { ui: FakeUi;};
type ProcessSignalHandler = () => void;
type InteractiveModePrototypeWithHandleCtrlZ = { handleCtrlZ(this: HandleCtrlZThis): void;};
function callHandleCtrlZ(context: HandleCtrlZThis): void { (interactiveModePrototype as InteractiveModePrototypeWithHandleCtrlZ).handleCtrlZ.call(context);}
const interactiveModePrototype = InteractiveMode.prototype as unknown;
describe("InteractiveMode.handleCtrlZ", () => { afterEach(() => { vi.restoreAllMocks(); });
test("shows a status message and skips suspend on Windows", () => { const ui: FakeUi = { start: vi.fn(), stop: vi.fn(), requestRender: vi.fn(), }; const showStatus = vi.fn(); const context: HandleCtrlZThis & { showStatus: (message: string) => void } = { ui, showStatus }; const platformDescriptor = Object.getOwnPropertyDescriptor(process, "platform"); Object.defineProperty(process, "platform", { configurable: true, value: "win32", }); const setIntervalSpy = vi.spyOn(globalThis, "setInterval"); const processOnSpy = vi.spyOn(process, "on"); const processOnceSpy = vi.spyOn(process, "once"); const processKillSpy = vi.spyOn(process, "kill");
try { callHandleCtrlZ(context); } finally { if (platformDescriptor) { Object.defineProperty(process, "platform", platformDescriptor); } }
expect(showStatus).toHaveBeenCalledWith("Suspend to background is not supported on Windows"); expect(ui.stop).not.toHaveBeenCalled(); expect(setIntervalSpy).not.toHaveBeenCalled(); expect(processOnSpy).not.toHaveBeenCalledWith("SIGINT", expect.any(Function)); expect(processOnceSpy).not.toHaveBeenCalledWith("SIGCONT", expect.any(Function)); expect(processKillSpy).not.toHaveBeenCalled(); });
test("keeps the process alive while suspended and restores the TUI on SIGCONT", () => { const ui: FakeUi = { start: vi.fn(), stop: vi.fn(), requestRender: vi.fn(), }; const context: HandleCtrlZThis = { ui }; const keepAliveHandle = setTimeout(() => undefined, 0); clearTimeout(keepAliveHandle);
let sigintHandler: ProcessSignalHandler | undefined; let sigcontHandler: ProcessSignalHandler | undefined;
const setIntervalSpy = vi.spyOn(globalThis, "setInterval").mockReturnValue(keepAliveHandle); const clearIntervalSpy = vi.spyOn(globalThis, "clearInterval").mockImplementation(() => undefined); const processOnSpy = vi.spyOn(process, "on").mockImplementation(((event: string, listener: () => void) => { if (event === "SIGINT") { sigintHandler = listener; } return process; }) as typeof process.on); const processOnceSpy = vi.spyOn(process, "once").mockImplementation(((event: string, listener: () => void) => { if (event === "SIGCONT") { sigcontHandler = listener; } return process; }) as typeof process.once); const removeListenerSpy = vi .spyOn(process, "removeListener") .mockImplementation(((_event: string, _listener: () => void) => process) as typeof process.removeListener); const processKillSpy = vi.spyOn(process, "kill").mockImplementation(() => true);
callHandleCtrlZ(context);
expect(setIntervalSpy).toHaveBeenCalledWith(expect.any(Function), 2 ** 30); expect(processOnSpy).toHaveBeenCalledWith("SIGINT", expect.any(Function)); expect(processOnceSpy).toHaveBeenCalledWith("SIGCONT", expect.any(Function)); expect(ui.stop).toHaveBeenCalledTimes(1); expect(processKillSpy).toHaveBeenCalledWith(0, "SIGTSTP"); expect(sigintHandler).toBeDefined(); expect(sigcontHandler).toBeDefined();
sigcontHandler?.();
expect(clearIntervalSpy).toHaveBeenCalledWith(keepAliveHandle); expect(removeListenerSpy).toHaveBeenCalledWith("SIGINT", sigintHandler); expect(ui.start).toHaveBeenCalledTimes(1); expect(ui.requestRender).toHaveBeenCalledWith(true); });
test("cleans up the temporary handlers if suspension fails", () => { const ui: FakeUi = { start: vi.fn(), stop: vi.fn(), requestRender: vi.fn(), }; const context: HandleCtrlZThis = { ui }; const keepAliveHandle = setTimeout(() => undefined, 0); clearTimeout(keepAliveHandle); const suspendError = new Error("suspend failed");
const setIntervalSpy = vi.spyOn(globalThis, "setInterval").mockReturnValue(keepAliveHandle); const clearIntervalSpy = vi.spyOn(globalThis, "clearInterval").mockImplementation(() => undefined); vi.spyOn(process, "on").mockImplementation( ((_event: string, _listener: () => void) => process) as typeof process.on, ); const removeListenerSpy = vi .spyOn(process, "removeListener") .mockImplementation(((_event: string, _listener: () => void) => process) as typeof process.removeListener); vi.spyOn(process, "once").mockImplementation( ((_event: string, _listener: () => void) => process) as typeof process.once, ); vi.spyOn(process, "kill").mockImplementation(() => { throw suspendError; });
expect(() => callHandleCtrlZ(context)).toThrow(suspendError); expect(ui.stop).toHaveBeenCalledTimes(1); expect(setIntervalSpy).toHaveBeenCalledTimes(1); expect(clearIntervalSpy).toHaveBeenCalledWith(keepAliveHandle); expect(removeListenerSpy).toHaveBeenCalledWith("SIGINT", expect.any(Function)); expect(ui.start).not.toHaveBeenCalled(); expect(ui.requestRender).not.toHaveBeenCalled(); });});