fix(coding-agent): wire extension editor component replacement
This commit is contained in:
@@ -0,0 +1,89 @@
|
||||
import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "bun:test";
|
||||
import * as path from "node:path";
|
||||
import { Agent } from "@oh-my-pi/pi-agent-core";
|
||||
import { _resetSettingsForTest, Settings } from "@oh-my-pi/pi-coding-agent/config/settings";
|
||||
import { initTheme } from "@oh-my-pi/pi-coding-agent/modes/theme/theme";
|
||||
import { Editor } from "@oh-my-pi/pi-tui";
|
||||
import { TempDir } from "@oh-my-pi/pi-utils";
|
||||
import { ModelRegistry } from "../src/config/model-registry";
|
||||
import { CustomEditor } from "../src/modes/components/custom-editor";
|
||||
import { InteractiveMode } from "../src/modes/interactive-mode";
|
||||
import { AgentSession } from "../src/session/agent-session";
|
||||
import { AuthStorage } from "../src/session/auth-storage";
|
||||
import { SessionManager } from "../src/session/session-manager";
|
||||
|
||||
class TestModalEditor extends CustomEditor {}
|
||||
|
||||
describe("InteractiveMode.setEditorComponent", () => {
|
||||
let tempDir: TempDir;
|
||||
let authStorage: AuthStorage;
|
||||
let session: AgentSession;
|
||||
let mode: InteractiveMode;
|
||||
|
||||
beforeAll(() => {
|
||||
initTheme();
|
||||
});
|
||||
|
||||
beforeEach(async () => {
|
||||
_resetSettingsForTest();
|
||||
tempDir = TempDir.createSync("@pi-editor-component-");
|
||||
await Settings.init({ inMemory: true, cwd: tempDir.path() });
|
||||
authStorage = await AuthStorage.create(path.join(tempDir.path(), "testauth.db"));
|
||||
const modelRegistry = new ModelRegistry(authStorage);
|
||||
const model = modelRegistry.find("anthropic", "claude-sonnet-4-5");
|
||||
if (!model) {
|
||||
throw new Error("Expected claude-sonnet-4-5 to exist in registry");
|
||||
}
|
||||
|
||||
session = new AgentSession({
|
||||
agent: new Agent({
|
||||
initialState: {
|
||||
model,
|
||||
systemPrompt: "Test",
|
||||
tools: [],
|
||||
messages: [],
|
||||
},
|
||||
}),
|
||||
sessionManager: SessionManager.create(tempDir.path(), tempDir.path()),
|
||||
settings: Settings.isolated(),
|
||||
modelRegistry,
|
||||
});
|
||||
mode = new InteractiveMode(session, "test");
|
||||
});
|
||||
|
||||
afterEach(async () => {
|
||||
vi.restoreAllMocks();
|
||||
mode?.stop();
|
||||
await session?.dispose();
|
||||
authStorage?.close();
|
||||
tempDir?.removeSync();
|
||||
_resetSettingsForTest();
|
||||
});
|
||||
|
||||
it("replaces the editor and rebinds interactive handlers", () => {
|
||||
mode.editor.setText("draft prompt");
|
||||
const previousEditor = mode.editor;
|
||||
const refreshSpy = vi.spyOn(mode, "refreshSlashCommandState").mockResolvedValue();
|
||||
|
||||
mode.setEditorComponent((_tui, editorTheme) => new TestModalEditor(editorTheme));
|
||||
|
||||
expect(mode.editor).toBeInstanceOf(TestModalEditor);
|
||||
expect(mode.editor).not.toBe(previousEditor);
|
||||
expect(mode.editor.getText()).toBe("draft prompt");
|
||||
expect(mode.editor.onSubmit).toBeDefined();
|
||||
expect(mode.editor.onEscape).toBeDefined();
|
||||
expect(refreshSpy).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("keeps the current editor when factory returns a non-CustomEditor", () => {
|
||||
const previousEditor = mode.editor;
|
||||
const warningSpy = vi.spyOn(mode, "showWarning");
|
||||
|
||||
mode.setEditorComponent((_tui, editorTheme) => new Editor(editorTheme));
|
||||
|
||||
expect(mode.editor).toBe(previousEditor);
|
||||
expect(warningSpy).toHaveBeenCalledWith(
|
||||
"Custom editor components must implement CustomEditor-compatible interactive methods.",
|
||||
);
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user