Files
qiming/qimingclaw/crates/agent-electron-client/src/main/services/engines/engineHooks.test.ts

121 lines
4.2 KiB
TypeScript

/**
* Tests for engineHooks — env provider and prompt enhancer registries
*/
import { describe, it, expect, beforeEach, vi } from "vitest";
vi.mock("electron-log", () => ({
default: {
info: vi.fn(),
warn: vi.fn(),
error: vi.fn(),
},
}));
// engineHooks uses module-level arrays, so we need to re-import for isolation
// Since we can't easily reset module state, we test behavior additively
import {
registerEnvProvider,
collectEnvFromProviders,
registerPromptEnhancer,
enhanceSystemPrompt,
} from "./engineHooks";
describe("engineHooks", () => {
// Note: providers accumulate across tests within this module since they're module-level singletons.
// Tests are designed to be additive and order-independent where possible.
describe("env providers", () => {
it("collectEnvFromProviders returns empty object when no providers return env", () => {
// Register a provider that returns undefined
registerEnvProvider(() => undefined);
// collectEnvFromProviders should still return an object (may have env from prior tests)
const result = collectEnvFromProviders();
expect(typeof result).toBe("object");
});
it("collects env vars from providers", () => {
registerEnvProvider(() => ({ TEST_KEY: "test_value" }));
const result = collectEnvFromProviders();
expect(result.TEST_KEY).toBe("test_value");
});
it("merges env from multiple providers", () => {
registerEnvProvider(() => ({ KEY_A: "a" }));
registerEnvProvider(() => ({ KEY_B: "b" }));
const result = collectEnvFromProviders();
expect(result.KEY_A).toBe("a");
expect(result.KEY_B).toBe("b");
});
it("later providers override earlier ones for same key", () => {
registerEnvProvider(() => ({ OVERRIDE_KEY: "first" }));
registerEnvProvider(() => ({ OVERRIDE_KEY: "second" }));
const result = collectEnvFromProviders();
expect(result.OVERRIDE_KEY).toBe("second");
});
it("handles provider errors gracefully", () => {
registerEnvProvider(() => {
throw new Error("provider error");
});
// Should not throw, just skip the erroring provider
const result = collectEnvFromProviders();
expect(typeof result).toBe("object");
});
it("skips providers that return undefined", () => {
registerEnvProvider(() => undefined);
registerEnvProvider(() => ({ VALID_KEY: "valid" }));
const result = collectEnvFromProviders();
expect(result.VALID_KEY).toBe("valid");
});
});
describe("prompt enhancers", () => {
it("returns base prompt when no enhancers modify it", () => {
registerPromptEnhancer((base) => base);
const result = enhanceSystemPrompt("hello");
expect(result).toBe("hello");
});
it("returns undefined for undefined base with pass-through enhancer", () => {
registerPromptEnhancer((base) => base);
// The enhancer just passes through, so undefined stays undefined
// (but previous enhancers from other tests may have been registered)
// We test the function contract directly
const result = enhanceSystemPrompt(undefined);
// Could be undefined or enhanced — depends on previously registered enhancers
expect(result === undefined || typeof result === "string").toBe(true);
});
it("enhancer can append to base prompt", () => {
registerPromptEnhancer((base) =>
base ? `${base}\n\nAPPENDED` : "APPENDED",
);
const result = enhanceSystemPrompt("original");
expect(result).toContain("original");
expect(result).toContain("APPENDED");
});
it("chains multiple enhancers in order", () => {
registerPromptEnhancer((base) => `${base || ""}-A`);
registerPromptEnhancer((base) => `${base || ""}-B`);
const result = enhanceSystemPrompt("start");
// Both A and B should be present, and B appended after A
expect(result).toContain("-A");
expect(result).toContain("-B");
});
it("handles enhancer errors gracefully", () => {
registerPromptEnhancer(() => {
throw new Error("enhancer error");
});
// Should not throw
const result = enhanceSystemPrompt("test");
expect(typeof result === "string" || result === undefined).toBe(true);
});
});
});