test: inject cli backend fixtures

This commit is contained in:
Peter Steinberger
2026-04-10 16:33:15 +01:00
parent 574bab80e5
commit d6ece7fb89
2 changed files with 88 additions and 34 deletions

View File

@@ -1,13 +1,22 @@
import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest";
import { afterEach, beforeEach, describe, expect, it } from "vitest";
import type { OpenClawConfig } from "../config/config.js";
import type { CliBackendConfig } from "../config/types.js";
import type { CliBundleMcpMode } from "../plugins/types.js";
import {
__testing as cliBackendsTesting,
resolveCliBackendConfig,
resolveCliBackendLiveTest,
} from "./cli-backends.js";
let createEmptyPluginRegistry: typeof import("../plugins/registry.js").createEmptyPluginRegistry;
let resetPluginRuntimeStateForTest: typeof import("../plugins/runtime.js").resetPluginRuntimeStateForTest;
let setActivePluginRegistry: typeof import("../plugins/runtime.js").setActivePluginRegistry;
let resolveCliBackendConfig: typeof import("./cli-backends.js").resolveCliBackendConfig;
let resolveCliBackendLiveTest: typeof import("./cli-backends.js").resolveCliBackendLiveTest;
type RuntimeBackendEntry = ReturnType<
(typeof import("../plugins/cli-backends.runtime.js"))["resolveRuntimeCliBackends"]
>[number];
type SetupBackendEntry = NonNullable<
ReturnType<(typeof import("../plugins/setup-registry.js"))["resolvePluginSetupCliBackend"]>
>;
let runtimeBackendEntries: RuntimeBackendEntry[] = [];
let setupBackendEntries: SetupBackendEntry[] = [];
function createBackendEntry(params: {
pluginId: string;
@@ -60,6 +69,14 @@ function createBackendEntry(params: {
};
}
function createRuntimeBackendEntry(params: Parameters<typeof createBackendEntry>[0]) {
const entry = createBackendEntry(params);
return {
...entry.backend,
pluginId: entry.pluginId,
} satisfies RuntimeBackendEntry;
}
function createClaudeCliOverrideConfig(config: CliBackendConfig): OpenClawConfig {
return {
agents: {
@@ -149,24 +166,13 @@ function normalizeTestClaudeBackendConfig(config: CliBackendConfig): CliBackendC
};
}
beforeAll(async () => {
vi.doUnmock("../plugins/setup-registry.js");
vi.doUnmock("../plugins/cli-backends.runtime.js");
vi.resetModules();
({ createEmptyPluginRegistry } = await import("../plugins/registry.js"));
({ resetPluginRuntimeStateForTest, setActivePluginRegistry } =
await import("../plugins/runtime.js"));
({ resolveCliBackendConfig, resolveCliBackendLiveTest } = await import("./cli-backends.js"));
});
afterEach(() => {
resetPluginRuntimeStateForTest();
cliBackendsTesting.resetDepsForTest();
});
beforeEach(() => {
const registry = createEmptyPluginRegistry();
registry.cliBackends = [
createBackendEntry({
runtimeBackendEntries = [
createRuntimeBackendEntry({
pluginId: "anthropic",
id: "claude-cli",
bundleMcp: true,
@@ -222,7 +228,7 @@ beforeEach(() => {
},
normalizeConfig: normalizeTestClaudeBackendConfig,
}),
createBackendEntry({
createRuntimeBackendEntry({
pluginId: "openai",
id: "codex-cli",
bundleMcp: true,
@@ -258,7 +264,7 @@ beforeEach(() => {
},
},
}),
createBackendEntry({
createRuntimeBackendEntry({
pluginId: "google",
id: "google-gemini-cli",
bundleMcp: true,
@@ -276,7 +282,30 @@ beforeEach(() => {
},
}),
];
setActivePluginRegistry(registry);
const claudeBackend = runtimeBackendEntries.find((entry) => entry.id === "claude-cli");
setupBackendEntries = claudeBackend
? [
{
pluginId: claudeBackend.pluginId,
backend: {
...claudeBackend,
config: {
...claudeBackend.config,
sessionArg: "--session-id",
sessionMode: "always",
systemPromptArg: "--append-system-prompt",
systemPromptWhen: "first",
},
},
},
]
: [];
cliBackendsTesting.setDepsForTest({
resolveRuntimeCliBackends: () => runtimeBackendEntries,
resolvePluginSetupCliBackend: ({ backend }) => {
return setupBackendEntries.find((entry) => entry.backend.id === backend);
},
});
});
describe("resolveCliBackendConfig reliability merge", () => {
@@ -648,8 +677,7 @@ describe("resolveCliBackendConfig claude-cli defaults", () => {
});
it("normalizes override-only claude-cli config when the plugin registry is absent", () => {
const registry = createEmptyPluginRegistry();
setActivePluginRegistry(registry);
runtimeBackendEntries = [];
const cfg = {
agents: {
@@ -735,9 +763,8 @@ describe("resolveCliBackendConfig google-gemini-cli defaults", () => {
describe("resolveCliBackendConfig alias precedence", () => {
it("prefers the canonical backend key over legacy aliases when both are configured", () => {
const registry = createEmptyPluginRegistry();
registry.cliBackends = [
createBackendEntry({
runtimeBackendEntries = [
createRuntimeBackendEntry({
pluginId: "moonshot",
id: "kimi",
config: {
@@ -746,7 +773,6 @@ describe("resolveCliBackendConfig alias precedence", () => {
},
}),
];
setActivePluginRegistry(registry);
const cfg = {
agents: {

View File

@@ -6,6 +6,18 @@ import type { CliBundleMcpMode } from "../plugins/types.js";
import { normalizeOptionalLowercaseString } from "../shared/string-coerce.js";
import { normalizeProviderId } from "./model-selection.js";
type CliBackendsDeps = {
resolvePluginSetupCliBackend: typeof resolvePluginSetupCliBackend;
resolveRuntimeCliBackends: typeof resolveRuntimeCliBackends;
};
const defaultCliBackendsDeps: CliBackendsDeps = {
resolvePluginSetupCliBackend,
resolveRuntimeCliBackends,
};
let cliBackendsDeps: CliBackendsDeps = defaultCliBackendsDeps;
export type ResolvedCliBackend = {
id: string;
config: CliBackendConfig;
@@ -47,7 +59,7 @@ function normalizeBundleMcpMode(
}
function resolveSetupCliBackendPolicy(provider: string): FallbackCliBackendPolicy | undefined {
const entry = resolvePluginSetupCliBackend({
const entry = cliBackendsDeps.resolvePluginSetupCliBackend({
backend: provider,
});
if (!entry) {
@@ -94,7 +106,9 @@ function pickBackendConfig(
function resolveRegisteredBackend(provider: string) {
const normalized = normalizeBackendKey(provider);
return resolveRuntimeCliBackends().find((entry) => normalizeBackendKey(entry.id) === normalized);
return cliBackendsDeps
.resolveRuntimeCliBackends()
.find((entry) => normalizeBackendKey(entry.id) === normalized);
}
function mergeBackendConfig(base: CliBackendConfig, override?: CliBackendConfig): CliBackendConfig {
@@ -136,7 +150,7 @@ function mergeBackendConfig(base: CliBackendConfig, override?: CliBackendConfig)
export function resolveCliBackendIds(cfg?: OpenClawConfig): Set<string> {
const ids = new Set<string>();
for (const backend of resolveRuntimeCliBackends()) {
for (const backend of cliBackendsDeps.resolveRuntimeCliBackends()) {
ids.add(normalizeBackendKey(backend.id));
}
const configured = cfg?.agents?.defaults?.cliBackends ?? {};
@@ -149,8 +163,10 @@ export function resolveCliBackendIds(cfg?: OpenClawConfig): Set<string> {
export function resolveCliBackendLiveTest(provider: string): ResolvedCliBackendLiveTest | null {
const normalized = normalizeBackendKey(provider);
const entry =
resolvePluginSetupCliBackend({ backend: normalized }) ??
resolveRuntimeCliBackends().find((backend) => normalizeBackendKey(backend.id) === normalized);
cliBackendsDeps.resolvePluginSetupCliBackend({ backend: normalized }) ??
cliBackendsDeps
.resolveRuntimeCliBackends()
.find((backend) => normalizeBackendKey(backend.id) === normalized);
if (!entry) {
return null;
}
@@ -227,3 +243,15 @@ export function resolveCliBackendConfig(
bundleMcpMode: fallbackPolicy?.bundleMcpMode,
};
}
export const __testing = {
resetDepsForTest(): void {
cliBackendsDeps = defaultCliBackendsDeps;
},
setDepsForTest(deps: Partial<CliBackendsDeps>): void {
cliBackendsDeps = {
...defaultCliBackendsDeps,
...deps,
};
},
} as const;