mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-06 07:20:43 +00:00
test: expand fast lane coverage
This commit is contained in:
@@ -1,22 +1,9 @@
|
||||
import { describe, expect, it, vi } from "vitest";
|
||||
|
||||
const readConfigFileSnapshotMock = vi.hoisted(() => vi.fn());
|
||||
const prepareSimpleCompletionModelForAgentMock = vi.hoisted(() => vi.fn());
|
||||
|
||||
vi.mock("../config/config.js", () => ({
|
||||
readConfigFileSnapshot: readConfigFileSnapshotMock,
|
||||
}));
|
||||
|
||||
vi.mock("../agents/simple-completion-runtime.js", () => ({
|
||||
prepareSimpleCompletionModelForAgent: prepareSimpleCompletionModelForAgentMock,
|
||||
completeWithPreparedSimpleCompletionModel: vi.fn(),
|
||||
}));
|
||||
|
||||
const { planCrestodianCommandWithConfiguredModel } = await import("./assistant.js");
|
||||
import { planCrestodianCommandWithConfiguredModel } from "./assistant.js";
|
||||
|
||||
describe("Crestodian configured-model planner", () => {
|
||||
it("skips the configured model path when no config file exists", async () => {
|
||||
readConfigFileSnapshotMock.mockResolvedValue({
|
||||
const readConfigFileSnapshot = vi.fn(async () => ({
|
||||
path: "/tmp/openclaw.json",
|
||||
exists: false,
|
||||
raw: null,
|
||||
@@ -27,8 +14,10 @@ describe("Crestodian configured-model planner", () => {
|
||||
runtimeConfig: {},
|
||||
config: {},
|
||||
issues: [],
|
||||
legacyIssues: [],
|
||||
warnings: [],
|
||||
});
|
||||
}));
|
||||
const prepareSimpleCompletionModelForAgent = vi.fn();
|
||||
|
||||
await expect(
|
||||
planCrestodianCommandWithConfiguredModel({
|
||||
@@ -58,9 +47,13 @@ describe("Crestodian configured-model planner", () => {
|
||||
sourceUrl: "https://github.com/openclaw/openclaw",
|
||||
},
|
||||
},
|
||||
deps: {
|
||||
readConfigFileSnapshot,
|
||||
prepareSimpleCompletionModelForAgent,
|
||||
},
|
||||
}),
|
||||
).resolves.toBeNull();
|
||||
|
||||
expect(prepareSimpleCompletionModelForAgentMock).not.toHaveBeenCalled();
|
||||
expect(prepareSimpleCompletionModelForAgent).not.toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
||||
@@ -33,6 +33,15 @@ export type CrestodianAssistantPlanner = (params: {
|
||||
|
||||
type RunCliAgentFn = typeof import("../agents/cli-runner.js").runCliAgent;
|
||||
type RunEmbeddedPiAgentFn = typeof import("../agents/pi-embedded.js").runEmbeddedPiAgent;
|
||||
type ReadConfigFileSnapshotFn = typeof readConfigFileSnapshot;
|
||||
type PrepareSimpleCompletionModelForAgentFn = typeof prepareSimpleCompletionModelForAgent;
|
||||
type CompleteWithPreparedSimpleCompletionModelFn = typeof completeWithPreparedSimpleCompletionModel;
|
||||
|
||||
export type CrestodianConfiguredModelPlannerDeps = {
|
||||
readConfigFileSnapshot?: ReadConfigFileSnapshotFn;
|
||||
prepareSimpleCompletionModelForAgent?: PrepareSimpleCompletionModelForAgentFn;
|
||||
completeWithPreparedSimpleCompletionModel?: CompleteWithPreparedSimpleCompletionModelFn;
|
||||
};
|
||||
|
||||
export type CrestodianLocalRuntimePlannerDeps = {
|
||||
runCliAgent?: RunCliAgentFn;
|
||||
@@ -41,10 +50,13 @@ export type CrestodianLocalRuntimePlannerDeps = {
|
||||
removeTempDir?: (dir: string) => Promise<void>;
|
||||
};
|
||||
|
||||
export type CrestodianPlannerDeps = CrestodianConfiguredModelPlannerDeps &
|
||||
CrestodianLocalRuntimePlannerDeps;
|
||||
|
||||
export async function planCrestodianCommand(params: {
|
||||
input: string;
|
||||
overview: CrestodianOverview;
|
||||
deps?: CrestodianLocalRuntimePlannerDeps;
|
||||
deps?: CrestodianPlannerDeps;
|
||||
}): Promise<CrestodianAssistantPlan | null> {
|
||||
const configured = await planCrestodianCommandWithConfiguredModel(params);
|
||||
if (configured) {
|
||||
@@ -56,18 +68,21 @@ export async function planCrestodianCommand(params: {
|
||||
export async function planCrestodianCommandWithConfiguredModel(params: {
|
||||
input: string;
|
||||
overview: CrestodianOverview;
|
||||
deps?: CrestodianConfiguredModelPlannerDeps;
|
||||
}): Promise<CrestodianAssistantPlan | null> {
|
||||
const input = params.input.trim();
|
||||
if (!input) {
|
||||
return null;
|
||||
}
|
||||
const snapshot = await readConfigFileSnapshot();
|
||||
const snapshot = await (params.deps?.readConfigFileSnapshot ?? readConfigFileSnapshot)();
|
||||
if (!snapshot.exists || !snapshot.valid) {
|
||||
return null;
|
||||
}
|
||||
const cfg = snapshot.runtimeConfig ?? snapshot.config;
|
||||
const agentId = resolveDefaultAgentId(cfg);
|
||||
const prepared = await prepareSimpleCompletionModelForAgent({
|
||||
const prepared = await (
|
||||
params.deps?.prepareSimpleCompletionModelForAgent ?? prepareSimpleCompletionModelForAgent
|
||||
)({
|
||||
cfg,
|
||||
agentId,
|
||||
allowMissingApiKeyModes: ["aws-sdk"],
|
||||
@@ -79,7 +94,10 @@ export async function planCrestodianCommandWithConfiguredModel(params: {
|
||||
const controller = new AbortController();
|
||||
const timer = setTimeout(() => controller.abort(), CRESTODIAN_ASSISTANT_TIMEOUT_MS);
|
||||
try {
|
||||
const response = await completeWithPreparedSimpleCompletionModel({
|
||||
const response = await (
|
||||
params.deps?.completeWithPreparedSimpleCompletionModel ??
|
||||
completeWithPreparedSimpleCompletionModel
|
||||
)({
|
||||
model: prepared.model,
|
||||
auth: prepared.auth,
|
||||
context: {
|
||||
|
||||
@@ -26,8 +26,30 @@ describe("unit-fast vitest lane", () => {
|
||||
expect(config.test?.include).toContain("src/acp/control-plane/runtime-cache.test.ts");
|
||||
expect(config.test?.include).toContain("src/acp/runtime/registry.test.ts");
|
||||
expect(config.test?.include).toContain("src/commands/status-overview-values.test.ts");
|
||||
expect(config.test?.include).toContain("src/entry.respawn.test.ts");
|
||||
expect(config.test?.include).toContain("src/entry.version-fast-path.test.ts");
|
||||
expect(config.test?.include).toContain("src/flows/doctor-startup-channel-maintenance.test.ts");
|
||||
expect(config.test?.include).toContain("src/crestodian/rescue-policy.test.ts");
|
||||
expect(config.test?.include).toContain("src/crestodian/assistant.configured.test.ts");
|
||||
expect(config.test?.include).toContain("src/flows/search-setup.test.ts");
|
||||
expect(config.test?.include).toContain("src/memory-host-sdk/host/mirror.test.ts");
|
||||
expect(config.test?.include).toContain("src/plugins/config-policy.test.ts");
|
||||
expect(config.test?.include).toContain("src/proxy-capture/proxy-server.test.ts");
|
||||
expect(config.test?.include).toContain("src/realtime-voice/agent-consult-tool.test.ts");
|
||||
expect(config.test?.include).toContain("src/sessions/transcript-events.test.ts");
|
||||
expect(config.test?.include).toContain(
|
||||
"src/security/audit-channel-source-config-slack.test.ts",
|
||||
);
|
||||
expect(config.test?.include).toContain("src/security/audit-config-symlink.test.ts");
|
||||
expect(config.test?.include).toContain("src/security/audit-exec-sandbox-host.test.ts");
|
||||
expect(config.test?.include).toContain("src/security/audit-gateway-auth-selection.test.ts");
|
||||
expect(config.test?.include).toContain("src/security/audit-gateway-http-auth.test.ts");
|
||||
expect(config.test?.include).toContain("src/security/audit-gateway-tools-http.test.ts");
|
||||
expect(config.test?.include).toContain("src/security/audit-plugin-readonly-scope.test.ts");
|
||||
expect(config.test?.include).toContain("src/security/audit-loopback-logging.test.ts");
|
||||
expect(config.test?.include).toContain("src/security/audit-sandbox-browser.test.ts");
|
||||
expect(config.test?.include).toContain("src/ui-app-settings.agents-files-refresh.test.ts");
|
||||
expect(config.test?.include).toContain("src/video-generation/provider-registry.test.ts");
|
||||
expect(config.test?.include).toContain("src/plugin-sdk/provider-entry.test.ts");
|
||||
expect(config.test?.include).toContain("src/security/dangerous-config-flags.test.ts");
|
||||
expect(config.test?.include).toContain("src/security/safe-regex.test.ts");
|
||||
|
||||
@@ -75,9 +75,11 @@ export const forcedUnitFastTestFiles = [
|
||||
"src/browser-lifecycle-cleanup.test.ts",
|
||||
"src/canvas-host/server.test.ts",
|
||||
"src/crestodian/audit.test.ts",
|
||||
"src/crestodian/assistant.configured.test.ts",
|
||||
"src/crestodian/crestodian.test.ts",
|
||||
"src/crestodian/operations.test.ts",
|
||||
"src/crestodian/overview.test.ts",
|
||||
"src/crestodian/rescue-policy.test.ts",
|
||||
"src/crestodian/rescue-message.test.ts",
|
||||
"src/crestodian/tui-backend.test.ts",
|
||||
"src/flows/channel-setup.test.ts",
|
||||
@@ -91,8 +93,11 @@ export const forcedUnitFastTestFiles = [
|
||||
"src/docker-image-digests.test.ts",
|
||||
"src/dockerfile.test.ts",
|
||||
"src/entry.compile-cache.test.ts",
|
||||
"src/entry.respawn.test.ts",
|
||||
"src/entry.version-fast-path.test.ts",
|
||||
"src/entry.test.ts",
|
||||
"src/flows/doctor-startup-channel-maintenance.test.ts",
|
||||
"src/flows/search-setup.test.ts",
|
||||
"src/i18n/registry.test.ts",
|
||||
"src/image-generation/openai-compatible-image-provider.test.ts",
|
||||
"src/install-sh-version.test.ts",
|
||||
@@ -103,6 +108,7 @@ export const forcedUnitFastTestFiles = [
|
||||
"src/memory-host-sdk/host/batch-http.test.ts",
|
||||
"src/memory-host-sdk/host/backend-config.test.ts",
|
||||
"src/memory-host-sdk/host/embeddings-remote-fetch.test.ts",
|
||||
"src/memory-host-sdk/host/mirror.test.ts",
|
||||
"src/memory-host-sdk/host/post-json.test.ts",
|
||||
"src/memory-host-sdk/host/session-files.test.ts",
|
||||
"src/music-generation/runtime.test.ts",
|
||||
@@ -118,18 +124,26 @@ export const forcedUnitFastTestFiles = [
|
||||
"src/plugin-activation-boundary.test.ts",
|
||||
"src/plugin-sdk/memory-host-events.test.ts",
|
||||
"src/proxy-capture/runtime.test.ts",
|
||||
"src/proxy-capture/proxy-server.test.ts",
|
||||
"src/proxy-capture/store.sqlite.test.ts",
|
||||
"src/realtime-voice/agent-consult-runtime.test.ts",
|
||||
"src/realtime-voice/session-runtime.test.ts",
|
||||
"src/security/audit-channel-dm-policy.test.ts",
|
||||
"src/security/audit-channel-source-config-slack.test.ts",
|
||||
"src/security/audit-channel-readonly-resolution.test.ts",
|
||||
"src/security/audit-config-symlink.test.ts",
|
||||
"src/security/audit-exec-surface.test.ts",
|
||||
"src/security/audit-exec-sandbox-host.test.ts",
|
||||
"src/security/audit-exec-safe-bins.test.ts",
|
||||
"src/security/dangerous-config-flags.test.ts",
|
||||
"src/security/audit-extra.sync.test.ts",
|
||||
"src/security/audit-filesystem-windows.test.ts",
|
||||
"src/security/audit-gateway-exposure.test.ts",
|
||||
"src/security/audit-gateway-auth-selection.test.ts",
|
||||
"src/security/audit-gateway-http-auth.test.ts",
|
||||
"src/security/audit-gateway-tools-http.test.ts",
|
||||
"src/security/audit-sandbox-docker-config.test.ts",
|
||||
"src/security/audit-sandbox-browser.test.ts",
|
||||
"src/security/safe-regex.test.ts",
|
||||
"src/security/audit-small-model-risk.test.ts",
|
||||
"src/security/audit-node-command-findings.test.ts",
|
||||
@@ -137,6 +151,8 @@ export const forcedUnitFastTestFiles = [
|
||||
"src/security/audit-trust-model.test.ts",
|
||||
"src/security/dm-policy-shared.test.ts",
|
||||
"src/security/audit-plugins-trust.test.ts",
|
||||
"src/security/audit-plugin-readonly-scope.test.ts",
|
||||
"src/security/audit-loopback-logging.test.ts",
|
||||
"src/security/audit-workspace-skill-escape.test.ts",
|
||||
"src/security/external-content.test.ts",
|
||||
"src/security/fix.test.ts",
|
||||
@@ -144,7 +160,9 @@ export const forcedUnitFastTestFiles = [
|
||||
"src/security/skill-scanner.test.ts",
|
||||
"src/security/audit-config-include-perms.test.ts",
|
||||
"src/realtime-transcription/websocket-session.test.ts",
|
||||
"src/realtime-voice/agent-consult-tool.test.ts",
|
||||
"src/routing/resolve-route.test.ts",
|
||||
"src/sessions/transcript-events.test.ts",
|
||||
"src/security/windows-acl.test.ts",
|
||||
"src/trajectory/cleanup.test.ts",
|
||||
"src/trajectory/export.test.ts",
|
||||
@@ -154,6 +172,7 @@ export const forcedUnitFastTestFiles = [
|
||||
"src/tts/provider-registry.test.ts",
|
||||
"src/tts/status-config.test.ts",
|
||||
"src/tts/tts-config.test.ts",
|
||||
"src/ui-app-settings.agents-files-refresh.test.ts",
|
||||
"src/terminal/restore.test.ts",
|
||||
"src/terminal/table.test.ts",
|
||||
"src/test-helpers/state-dir-env.test.ts",
|
||||
@@ -161,6 +180,7 @@ export const forcedUnitFastTestFiles = [
|
||||
"src/test-utils/temp-home.test.ts",
|
||||
"src/utils.test.ts",
|
||||
"src/version.test.ts",
|
||||
"src/video-generation/provider-registry.test.ts",
|
||||
];
|
||||
const forcedUnitFastTestFileSet = new Set(forcedUnitFastTestFiles);
|
||||
const unitFastCandidateExactFiles = [...pluginSdkLightTestFiles, ...commandsLightTestFiles];
|
||||
@@ -269,6 +289,21 @@ function walkFiles(directory, files = []) {
|
||||
return files;
|
||||
}
|
||||
|
||||
const walkedTestFilesByCwd = new Map();
|
||||
|
||||
function collectRepoTestFiles(cwd) {
|
||||
const normalizedCwd = normalizeRepoPath(cwd);
|
||||
const cached = walkedTestFilesByCwd.get(normalizedCwd);
|
||||
if (cached) {
|
||||
return cached;
|
||||
}
|
||||
const files = ["src", "packages", "test"]
|
||||
.flatMap((directory) => walkFiles(path.join(cwd, directory)))
|
||||
.map((file) => normalizeRepoPath(path.relative(cwd, file)));
|
||||
walkedTestFilesByCwd.set(normalizedCwd, files);
|
||||
return files;
|
||||
}
|
||||
|
||||
export function classifyUnitFastTestFileContent(source) {
|
||||
const reasons = [];
|
||||
for (const { code, pattern } of disqualifyingPatterns) {
|
||||
@@ -280,39 +315,40 @@ export function classifyUnitFastTestFileContent(source) {
|
||||
}
|
||||
|
||||
export function collectUnitFastTestCandidates(cwd = process.cwd()) {
|
||||
const discovered = ["src", "packages", "test"]
|
||||
.flatMap((directory) => walkFiles(path.join(cwd, directory)))
|
||||
.map((file) => normalizeRepoPath(path.relative(cwd, file)))
|
||||
.filter(
|
||||
(file) =>
|
||||
matchesAnyGlob(file, unitFastCandidateGlobs) &&
|
||||
!matchesAnyGlob(file, broadUnitFastCandidateSkipGlobs),
|
||||
);
|
||||
const discovered = collectRepoTestFiles(cwd).filter(
|
||||
(file) =>
|
||||
matchesAnyGlob(file, unitFastCandidateGlobs) &&
|
||||
!matchesAnyGlob(file, broadUnitFastCandidateSkipGlobs),
|
||||
);
|
||||
return [
|
||||
...new Set([...discovered, ...unitFastCandidateExactFiles, ...forcedUnitFastTestFiles]),
|
||||
].toSorted((a, b) => a.localeCompare(b));
|
||||
}
|
||||
|
||||
export function collectBroadUnitFastTestCandidates(cwd = process.cwd()) {
|
||||
const discovered = ["src", "packages", "test"]
|
||||
.flatMap((directory) => walkFiles(path.join(cwd, directory)))
|
||||
.map((file) => normalizeRepoPath(path.relative(cwd, file)))
|
||||
.filter(
|
||||
(file) =>
|
||||
matchesAnyGlob(file, broadUnitFastCandidateGlobs) &&
|
||||
!matchesAnyGlob(file, broadUnitFastCandidateSkipGlobs),
|
||||
);
|
||||
const discovered = collectRepoTestFiles(cwd).filter(
|
||||
(file) =>
|
||||
matchesAnyGlob(file, broadUnitFastCandidateGlobs) &&
|
||||
!matchesAnyGlob(file, broadUnitFastCandidateSkipGlobs),
|
||||
);
|
||||
return [
|
||||
...new Set([...discovered, ...unitFastCandidateExactFiles, ...forcedUnitFastTestFiles]),
|
||||
].toSorted((a, b) => a.localeCompare(b));
|
||||
}
|
||||
|
||||
const unitFastAnalysisByKey = new Map();
|
||||
|
||||
export function collectUnitFastTestFileAnalysis(cwd = process.cwd(), options = {}) {
|
||||
const cacheKey = `${normalizeRepoPath(cwd)}\0${options.scope ?? "default"}`;
|
||||
const cached = unitFastAnalysisByKey.get(cacheKey);
|
||||
if (cached) {
|
||||
return cached;
|
||||
}
|
||||
const candidates =
|
||||
options.scope === "broad"
|
||||
? collectBroadUnitFastTestCandidates(cwd)
|
||||
: collectUnitFastTestCandidates(cwd);
|
||||
return candidates.map((file) => {
|
||||
const analysis = candidates.map((file) => {
|
||||
const absolutePath = path.join(cwd, file);
|
||||
let source = "";
|
||||
try {
|
||||
@@ -333,6 +369,8 @@ export function collectUnitFastTestFileAnalysis(cwd = process.cwd(), options = {
|
||||
reasons,
|
||||
};
|
||||
});
|
||||
unitFastAnalysisByKey.set(cacheKey, analysis);
|
||||
return analysis;
|
||||
}
|
||||
|
||||
let cachedUnitFastTestFiles = null;
|
||||
|
||||
Reference in New Issue
Block a user