openclaw/test/scripts/test-extension.test.ts
Alexander Davydov 2c4f5203f5 Merge remote-tracking branch 'upstream/main' into feat/gigachat
# Conflicts:
#	extensions/discord/src/accounts.ts
#	extensions/discord/src/audit.test.ts
#	extensions/discord/src/monitor/message-handler.process.test.ts
#	extensions/discord/src/monitor/provider.registry.test.ts
#	extensions/discord/src/monitor/thread-bindings.discord-api.test.ts
#	extensions/discord/src/monitor/thread-bindings.lifecycle.test.ts
#	extensions/telegram/src/bot-handlers.runtime.ts
#	extensions/telegram/src/bot-message-dispatch.test.ts
#	extensions/telegram/src/bot.create-telegram-bot.test-harness.ts
#	extensions/telegram/src/bot.create-telegram-bot.test.ts
#	extensions/whatsapp/src/auto-reply/heartbeat-runner.test.ts
#	extensions/whatsapp/src/inbound/access-control.test-harness.ts
#	extensions/whatsapp/src/monitor-inbox.test-harness.ts
#	extensions/whatsapp/src/test-helpers.ts
#	package.json
#	pnpm-lock.yaml
#	scripts/test-extension.mjs
#	src/commands/onboard-auth.config-shared.test.ts
2026-03-19 19:51:09 +03:00

117 lines
4.2 KiB
TypeScript

import { execFileSync } from "node:child_process";
import path from "node:path";
import { describe, expect, it } from "vitest";
import {
detectChangedExtensionIds,
listAvailableExtensionIds,
resolveExtensionTestPlan,
} from "../../scripts/test-extension.mjs";
const scriptPath = path.join(process.cwd(), "scripts", "test-extension.mjs");
function readPlan(args: string[], cwd = process.cwd()) {
const stdout = execFileSync(process.execPath, [scriptPath, ...args, "--dry-run", "--json"], {
cwd,
encoding: "utf8",
});
return JSON.parse(stdout) as ReturnType<typeof resolveExtensionTestPlan>;
}
function runScript(args: string[], cwd = process.cwd()) {
return execFileSync(process.execPath, [scriptPath, ...args], {
cwd,
encoding: "utf8",
});
}
describe("scripts/test-extension.mjs", () => {
it("resolves channel-root extensions onto the channel vitest config", () => {
const plan = resolveExtensionTestPlan({ targetArg: "slack", cwd: process.cwd() });
expect(plan.extensionId).toBe("slack");
expect(plan.extensionDir).toBe("extensions/slack");
expect(plan.config).toBe("vitest.channels.config.ts");
expect(plan.testFiles.some((file) => file.startsWith("extensions/slack/"))).toBe(true);
});
it("resolves provider extensions onto the extensions vitest config", () => {
const plan = resolveExtensionTestPlan({ targetArg: "firecrawl", cwd: process.cwd() });
expect(plan.extensionId).toBe("firecrawl");
expect(plan.config).toBe("vitest.extensions.config.ts");
expect(plan.testFiles.some((file) => file.startsWith("extensions/firecrawl/"))).toBe(true);
});
it("returns an empty test list for provider extensions without dedicated tests", () => {
const plan = resolveExtensionTestPlan({ targetArg: "openrouter", cwd: process.cwd() });
expect(plan.extensionId).toBe("openrouter");
expect(plan.config).toBe("vitest.extensions.config.ts");
expect(plan.testFiles).toEqual([]);
});
it("includes paired src roots when they contain tests", () => {
const plan = resolveExtensionTestPlan({ targetArg: "line", cwd: process.cwd() });
expect(plan.roots).toContain("extensions/line");
expect(plan.roots).toContain("src/line");
expect(plan.config).toBe("vitest.channels.config.ts");
expect(plan.testFiles.some((file) => file.startsWith("src/line/"))).toBe(true);
});
it("infers the extension from the current working directory", () => {
const cwd = path.join(process.cwd(), "extensions", "slack");
const plan = readPlan([], cwd);
expect(plan.extensionId).toBe("slack");
expect(plan.extensionDir).toBe("extensions/slack");
});
it("treats extensions without dedicated tests as a clean dry-run skip", () => {
const stdout = execFileSync(process.execPath, [scriptPath, "openrouter"], {
cwd: process.cwd(),
encoding: "utf8",
});
expect(stdout).toContain("[test-extension] No tests found for extensions/openrouter.");
expect(stdout).toContain(
'Run "pnpm test:extension openrouter -- --dry-run" to inspect the resolved roots. Skipping.',
);
});
it("maps changed paths back to extension ids", () => {
const extensionIds = detectChangedExtensionIds([
"extensions/slack/src/channel.ts",
"src/line/message.test.ts",
"extensions/firecrawl/package.json",
"src/not-a-plugin/file.ts",
]);
expect(extensionIds).toEqual(["firecrawl", "line", "slack"]);
});
it("lists available extension ids", () => {
const extensionIds = listAvailableExtensionIds();
expect(extensionIds).toContain("slack");
expect(extensionIds).toContain("firecrawl");
expect(extensionIds).toEqual(
[...extensionIds].toSorted((left, right) => left.localeCompare(right)),
);
});
it("dry-run still reports a plan for extensions without tests", () => {
const plan = readPlan(["copilot-proxy"]);
expect(plan.extensionId).toBe("copilot-proxy");
expect(plan.testFiles).toEqual([]);
});
it("treats extensions without tests as a no-op by default", () => {
const stdout = runScript(["copilot-proxy"]);
expect(stdout).toContain("No tests found for extensions/copilot-proxy.");
expect(stdout).toContain("Skipping.");
});
});