Files
oh-my-pi/packages/coding-agent/test/issue-interrupt-and-flush-empty-messages.test.ts
T
can1357 93db34b0d5 refactor(coding-agent): consolidated editor state and unify transcript rendering
- Centralized draft state and image management by migrating fields from context to the CustomEditor component.
- Standardized transcript row construction by introducing shared helpers for background jobs, IRC traffic, and file mentions.
- Refactored redundant UI logic and helper functions into reusable utility modules to streamline message submission and component rendering.
- Standardized event handler types by consolidating lifecycle definitions into a shared module while maintaining public API stability.
2026-06-22 06:11:57 +02:00

68 lines
2.1 KiB
TypeScript

import { describe, expect, it, vi } from "bun:test";
import type { ImageContent } from "@oh-my-pi/pi-ai";
import { InputController } from "@oh-my-pi/pi-coding-agent/modes/controllers/input-controller";
import type { InteractiveModeContext } from "@oh-my-pi/pi-coding-agent/modes/types";
import { USER_INTERRUPT_LABEL } from "@oh-my-pi/pi-coding-agent/session/messages";
function createContext() {
let editorText = "";
const abort = vi.fn(async () => {});
const prompt = vi.fn(async () => {});
const updatePendingMessagesDisplay = vi.fn();
const requestRender = vi.fn();
const showError = vi.fn();
const ctx = {
editor: {
setText(text: string) {
editorText = text;
},
getText() {
return editorText;
},
addToHistory: vi.fn(),
pendingImages: [] as ImageContent[],
pendingImageLinks: [] as (string | undefined)[],
},
ui: { requestRender },
session: {
isStreaming: true,
isCompacting: false,
isBashRunning: false,
isEvalRunning: false,
queuedMessageCount: 1,
extensionRunner: undefined,
abort,
prompt,
},
get viewSession() {
return (this as typeof ctx).session;
},
compactionQueuedMessages: [],
locallySubmittedUserSignatures: new Set<string>(),
isBashMode: false,
isPythonMode: false,
loopModeEnabled: false,
updatePendingMessagesDisplay,
showError,
hasActiveBtw: () => false,
hasActiveOmfg: () => false,
} as unknown as InteractiveModeContext;
return { ctx, abort, prompt, updatePendingMessagesDisplay, requestRender, showError };
}
describe("empty submit with queued messages", () => {
it("aborts the active stream instead of eagerly prompting a drained queue", async () => {
const { ctx, abort, prompt, updatePendingMessagesDisplay, requestRender, showError } = createContext();
const controller = new InputController(ctx);
controller.setupEditorSubmitHandler();
await ctx.editor.onSubmit?.("");
expect(abort).toHaveBeenCalledWith({ reason: USER_INTERRUPT_LABEL });
expect(prompt).not.toHaveBeenCalled();
expect(showError).not.toHaveBeenCalled();
expect(updatePendingMessagesDisplay).toHaveBeenCalledTimes(1);
expect(requestRender).toHaveBeenCalledTimes(1);
});
});