From c7cb43cac958f00b8846baf209c29449931b8722 Mon Sep 17 00:00:00 2001 From: Peter Steinberger Date: Sat, 4 Apr 2026 05:25:04 +0100 Subject: [PATCH] perf: split more scoped vitest lanes --- package.json | 8 +- scripts/lib/extension-test-plan.mjs | 34 ++++- scripts/test-projects.test-support.mjs | 171 ++++++++++++++++++--- src/scripts/test-projects.test.ts | 204 ++++++++++++++++++++++++- test/scripts/test-extension.test.ts | 120 ++++++++++++++- test/vitest-scoped-config.test.ts | 181 +++++++++++++++++++++- vitest.channel-paths.mjs | 1 + vitest.channels.config.ts | 2 +- vitest.cli.config.ts | 12 ++ vitest.config.ts | 17 +++ vitest.cron.config.ts | 12 ++ vitest.daemon.config.ts | 12 ++ vitest.extension-acpx-paths.mjs | 5 + vitest.extension-acpx.config.ts | 26 ++++ vitest.extension-bluebubbles-paths.mjs | 5 + vitest.extension-bluebubbles.config.ts | 27 ++++ vitest.extension-diffs-paths.mjs | 5 + vitest.extension-diffs.config.ts | 27 ++++ vitest.extension-matrix-paths.mjs | 9 ++ vitest.extension-matrix.config.ts | 17 +++ vitest.extension-memory-paths.mjs | 5 + vitest.extension-memory.config.ts | 27 ++++ vitest.extension-messaging-paths.mjs | 25 +++ vitest.extension-messaging.config.ts | 27 ++++ vitest.extension-telegram-paths.mjs | 5 + vitest.extension-telegram.config.ts | 27 ++++ vitest.extensions.config.ts | 14 ++ vitest.media-understanding.config.ts | 12 ++ vitest.media.config.ts | 12 ++ vitest.plugin-sdk.config.ts | 12 ++ vitest.plugins.config.ts | 12 ++ vitest.runtime-config.config.ts | 12 ++ vitest.scoped-config.ts | 2 +- vitest.secrets.config.ts | 12 ++ vitest.shared-core.config.ts | 12 ++ vitest.shared.config.ts | 33 +++- vitest.unit-paths.mjs | 12 +- 37 files changed, 1107 insertions(+), 49 deletions(-) create mode 100644 vitest.cli.config.ts create mode 100644 vitest.cron.config.ts create mode 100644 vitest.daemon.config.ts create mode 100644 vitest.extension-acpx-paths.mjs create mode 100644 vitest.extension-acpx.config.ts create mode 100644 vitest.extension-bluebubbles-paths.mjs create mode 100644 vitest.extension-bluebubbles.config.ts create mode 100644 vitest.extension-diffs-paths.mjs create mode 100644 vitest.extension-diffs.config.ts create mode 100644 vitest.extension-matrix-paths.mjs create mode 100644 vitest.extension-matrix.config.ts create mode 100644 vitest.extension-memory-paths.mjs create mode 100644 vitest.extension-memory.config.ts create mode 100644 vitest.extension-messaging-paths.mjs create mode 100644 vitest.extension-messaging.config.ts create mode 100644 vitest.extension-telegram-paths.mjs create mode 100644 vitest.extension-telegram.config.ts create mode 100644 vitest.media-understanding.config.ts create mode 100644 vitest.media.config.ts create mode 100644 vitest.plugin-sdk.config.ts create mode 100644 vitest.plugins.config.ts create mode 100644 vitest.runtime-config.config.ts create mode 100644 vitest.secrets.config.ts create mode 100644 vitest.shared-core.config.ts diff --git a/package.json b/package.json index 7ac3c149f23..30a47a0e476 100644 --- a/package.json +++ b/package.json @@ -1091,7 +1091,7 @@ "runtime-sidecars:gen": "node --import tsx scripts/generate-runtime-sidecar-paths-baseline.ts --write", "stage:bundled-plugin-runtime-deps": "node scripts/stage-bundled-plugin-runtime-deps.mjs", "start": "node scripts/run-node.mjs", - "test": "vitest run --config vitest.config.ts", + "test": "node scripts/test-projects.mjs", "test:all": "pnpm lint && pnpm build && pnpm test && pnpm test:e2e && pnpm test:live && pnpm test:docker:all", "test:auth:compat": "vitest run --config vitest.gateway.config.ts src/gateway/server.auth.compat-baseline.test.ts src/gateway/client.test.ts src/gateway/reconnect-gating.test.ts src/gateway/protocol/connect-error-details.test.ts", "test:build:singleton": "node scripts/test-built-plugin-singleton.mjs", @@ -1135,7 +1135,7 @@ "test:live": "node scripts/test-live.mjs", "test:live:gateway-profiles": "node scripts/test-live.mjs -- src/gateway/gateway-models.profiles.live.test.ts", "test:live:models-profiles": "node scripts/test-live.mjs -- src/agents/models.profiles.live.test.ts", - "test:max": "OPENCLAW_VITEST_MAX_WORKERS=8 vitest run --config vitest.config.ts", + "test:max": "OPENCLAW_VITEST_MAX_WORKERS=8 node scripts/test-projects.mjs", "test:parallels:linux": "bash scripts/e2e/parallels-linux-smoke.sh", "test:parallels:macos": "bash scripts/e2e/parallels-macos-smoke.sh", "test:parallels:npm-update": "bash scripts/e2e/parallels-npm-update-smoke.sh", @@ -1147,7 +1147,7 @@ "test:perf:profile:main": "node scripts/run-vitest-profile.mjs main", "test:perf:profile:runner": "node scripts/run-vitest-profile.mjs runner", "test:sectriage": "pnpm exec vitest run --config vitest.gateway.config.ts && vitest run --config vitest.unit.config.ts --exclude src/daemon/launchd.integration.test.ts --exclude src/process/exec.test.ts", - "test:serial": "OPENCLAW_VITEST_MAX_WORKERS=1 vitest run --config vitest.config.ts", + "test:serial": "OPENCLAW_VITEST_MAX_WORKERS=1 node scripts/test-projects.mjs", "test:startup:bench": "node --import tsx scripts/bench-cli-startup.ts", "test:startup:bench:check": "node scripts/test-cli-startup-bench-budget.mjs", "test:startup:bench:save": "node --import tsx scripts/bench-cli-startup.ts --preset all --runs 5 --warmup 1 --output .artifacts/cli-startup-bench-all.json", @@ -1156,7 +1156,7 @@ "test:startup:memory": "node scripts/check-cli-startup-memory.mjs", "test:ui": "pnpm lint:ui:no-raw-window-open && pnpm --dir ui test", "test:voicecall:closedloop": "node scripts/test-voicecall-closedloop.mjs", - "test:watch": "vitest --config vitest.config.ts", + "test:watch": "node scripts/test-projects.mjs --watch", "ts-topology": "node --import tsx scripts/ts-topology.ts", "tsgo": "node scripts/run-tsgo.mjs", "tui": "node scripts/run-node.mjs tui", diff --git a/scripts/lib/extension-test-plan.mjs b/scripts/lib/extension-test-plan.mjs index 02c97e88717..93f7ee67fe4 100644 --- a/scripts/lib/extension-test-plan.mjs +++ b/scripts/lib/extension-test-plan.mjs @@ -1,7 +1,14 @@ import fs from "node:fs"; import path from "node:path"; import { channelTestRoots } from "../../vitest.channel-paths.mjs"; +import { isAcpxExtensionRoot } from "../../vitest.extension-acpx-paths.mjs"; +import { isBlueBubblesExtensionRoot } from "../../vitest.extension-bluebubbles-paths.mjs"; +import { isDiffsExtensionRoot } from "../../vitest.extension-diffs-paths.mjs"; +import { isMatrixExtensionRoot } from "../../vitest.extension-matrix-paths.mjs"; +import { isMemoryExtensionRoot } from "../../vitest.extension-memory-paths.mjs"; +import { isMessagingExtensionRoot } from "../../vitest.extension-messaging-paths.mjs"; import { isProviderExtensionRoot } from "../../vitest.extension-provider-paths.mjs"; +import { isTelegramExtensionRoot } from "../../vitest.extension-telegram-paths.mjs"; import { BUNDLED_PLUGIN_PATH_PREFIX, BUNDLED_PLUGIN_ROOT_DIR } from "./bundled-plugin-paths.mjs"; import { listAvailableExtensionIds } from "./changed-extensions.mjs"; @@ -90,12 +97,33 @@ export function resolveExtensionTestPlan(params = {}) { } const usesChannelConfig = roots.some((root) => channelTestRoots.includes(root)); + const usesAcpxConfig = roots.some((root) => isAcpxExtensionRoot(root)); + const usesDiffsConfig = roots.some((root) => isDiffsExtensionRoot(root)); + const usesBlueBubblesConfig = roots.some((root) => isBlueBubblesExtensionRoot(root)); + const usesTelegramConfig = roots.some((root) => isTelegramExtensionRoot(root)); + const usesMatrixConfig = roots.some((root) => isMatrixExtensionRoot(root)); + const usesMemoryConfig = roots.some((root) => isMemoryExtensionRoot(root)); + const usesMessagingConfig = roots.some((root) => isMessagingExtensionRoot(root)); const usesProviderConfig = roots.some((root) => isProviderExtensionRoot(root)); const config = usesChannelConfig ? "vitest.extension-channels.config.ts" - : usesProviderConfig - ? "vitest.extension-providers.config.ts" - : "vitest.extensions.config.ts"; + : usesAcpxConfig + ? "vitest.extension-acpx.config.ts" + : usesDiffsConfig + ? "vitest.extension-diffs.config.ts" + : usesBlueBubblesConfig + ? "vitest.extension-bluebubbles.config.ts" + : usesMatrixConfig + ? "vitest.extension-matrix.config.ts" + : usesTelegramConfig + ? "vitest.extension-telegram.config.ts" + : usesMemoryConfig + ? "vitest.extension-memory.config.ts" + : usesMessagingConfig + ? "vitest.extension-messaging.config.ts" + : usesProviderConfig + ? "vitest.extension-providers.config.ts" + : "vitest.extensions.config.ts"; const testFileCount = roots.reduce( (sum, root) => sum + countTestFiles(path.join(repoRoot, root)), 0, diff --git a/scripts/test-projects.test-support.mjs b/scripts/test-projects.test-support.mjs index 181621044f3..f2445073a68 100644 --- a/scripts/test-projects.test-support.mjs +++ b/scripts/test-projects.test-support.mjs @@ -2,7 +2,14 @@ import fs from "node:fs"; import os from "node:os"; import path from "node:path"; import { isChannelSurfaceTestFile } from "../vitest.channel-paths.mjs"; +import { isAcpxExtensionRoot } from "../vitest.extension-acpx-paths.mjs"; +import { isBlueBubblesExtensionRoot } from "../vitest.extension-bluebubbles-paths.mjs"; +import { isDiffsExtensionRoot } from "../vitest.extension-diffs-paths.mjs"; +import { isMatrixExtensionRoot } from "../vitest.extension-matrix-paths.mjs"; +import { isMemoryExtensionRoot } from "../vitest.extension-memory-paths.mjs"; +import { isMessagingExtensionRoot } from "../vitest.extension-messaging-paths.mjs"; import { isProviderExtensionRoot } from "../vitest.extension-provider-paths.mjs"; +import { isTelegramExtensionRoot } from "../vitest.extension-telegram-paths.mjs"; import { isBoundaryTestFile, isBundledPluginDependentUnitTestFile } from "../vitest.unit-paths.mjs"; const DEFAULT_VITEST_CONFIG = "vitest.unit.config.ts"; @@ -12,14 +19,31 @@ const AUTO_REPLY_VITEST_CONFIG = "vitest.auto-reply.config.ts"; const BOUNDARY_VITEST_CONFIG = "vitest.boundary.config.ts"; const BUNDLED_VITEST_CONFIG = "vitest.bundled.config.ts"; const CHANNEL_VITEST_CONFIG = "vitest.channels.config.ts"; +const CLI_VITEST_CONFIG = "vitest.cli.config.ts"; const COMMANDS_VITEST_CONFIG = "vitest.commands.config.ts"; const CONTRACTS_VITEST_CONFIG = "vitest.contracts.config.ts"; +const CRON_VITEST_CONFIG = "vitest.cron.config.ts"; +const DAEMON_VITEST_CONFIG = "vitest.daemon.config.ts"; const E2E_VITEST_CONFIG = "vitest.e2e.config.ts"; +const EXTENSION_ACPX_VITEST_CONFIG = "vitest.extension-acpx.config.ts"; +const EXTENSION_BLUEBUBBLES_VITEST_CONFIG = "vitest.extension-bluebubbles.config.ts"; const EXTENSION_CHANNELS_VITEST_CONFIG = "vitest.extension-channels.config.ts"; +const EXTENSION_DIFFS_VITEST_CONFIG = "vitest.extension-diffs.config.ts"; +const EXTENSION_MATRIX_VITEST_CONFIG = "vitest.extension-matrix.config.ts"; +const EXTENSION_MEMORY_VITEST_CONFIG = "vitest.extension-memory.config.ts"; +const EXTENSION_MESSAGING_VITEST_CONFIG = "vitest.extension-messaging.config.ts"; const EXTENSION_PROVIDERS_VITEST_CONFIG = "vitest.extension-providers.config.ts"; +const EXTENSION_TELEGRAM_VITEST_CONFIG = "vitest.extension-telegram.config.ts"; const EXTENSIONS_VITEST_CONFIG = "vitest.extensions.config.ts"; const GATEWAY_VITEST_CONFIG = "vitest.gateway.config.ts"; const INFRA_VITEST_CONFIG = "vitest.infra.config.ts"; +const MEDIA_VITEST_CONFIG = "vitest.media.config.ts"; +const MEDIA_UNDERSTANDING_VITEST_CONFIG = "vitest.media-understanding.config.ts"; +const PLUGIN_SDK_VITEST_CONFIG = "vitest.plugin-sdk.config.ts"; +const PLUGINS_VITEST_CONFIG = "vitest.plugins.config.ts"; +const RUNTIME_CONFIG_VITEST_CONFIG = "vitest.runtime-config.config.ts"; +const SECRETS_VITEST_CONFIG = "vitest.secrets.config.ts"; +const SHARED_CORE_VITEST_CONFIG = "vitest.shared-core.config.ts"; const TOOLING_VITEST_CONFIG = "vitest.tooling.config.ts"; const UI_VITEST_CONFIG = "vitest.ui.config.ts"; const INCLUDE_FILE_ENV_KEY = "OPENCLAW_VITEST_INCLUDE_FILE"; @@ -85,6 +109,27 @@ function classifyTarget(arg, cwd) { if (isChannelSurfaceTestFile(relative)) { return "extensionChannel"; } + if (isAcpxExtensionRoot(extensionRoot)) { + return "extensionAcpx"; + } + if (isDiffsExtensionRoot(extensionRoot)) { + return "extensionDiffs"; + } + if (isBlueBubblesExtensionRoot(extensionRoot)) { + return "extensionBlueBubbles"; + } + if (isTelegramExtensionRoot(extensionRoot)) { + return "extensionTelegram"; + } + if (isMatrixExtensionRoot(extensionRoot)) { + return "extensionMatrix"; + } + if (isMemoryExtensionRoot(extensionRoot)) { + return "extensionMemory"; + } + if (isMessagingExtensionRoot(extensionRoot)) { + return "extensionMessaging"; + } return isProviderExtensionRoot(extensionRoot) ? "extensionProvider" : "extension"; } if (isChannelSurfaceTestFile(relative)) { @@ -110,15 +155,45 @@ function classifyTarget(arg, cwd) { if (isBundledPluginDependentUnitTestFile(relative)) { return "bundled"; } + if (relative.startsWith("src/channels/")) { + return "channel"; + } if (relative.startsWith("src/gateway/")) { return "gateway"; } if (relative.startsWith("src/infra/")) { return "infra"; } + if (relative.startsWith("src/config/")) { + return "runtimeConfig"; + } + if (relative.startsWith("src/cron/")) { + return "cron"; + } + if (relative.startsWith("src/daemon/")) { + return "daemon"; + } + if (relative.startsWith("src/media-understanding/")) { + return "mediaUnderstanding"; + } + if (relative.startsWith("src/media/")) { + return "media"; + } + if (relative.startsWith("src/plugin-sdk/")) { + return "pluginSdk"; + } + if (relative.startsWith("src/secrets/")) { + return "secrets"; + } + if (relative.startsWith("src/shared/")) { + return "sharedCore"; + } if (relative.startsWith("src/acp/")) { return "acp"; } + if (relative.startsWith("src/cli/")) { + return "cli"; + } if (relative.startsWith("src/commands/")) { return "command"; } @@ -128,6 +203,9 @@ function classifyTarget(arg, cwd) { if (relative.startsWith("src/agents/")) { return "agent"; } + if (relative.startsWith("src/plugins/")) { + return "plugin"; + } if (relative.startsWith("ui/src/ui/")) { return "ui"; } @@ -203,13 +281,30 @@ export function buildVitestRunPlans(args, cwd = process.cwd()) { "bundled", "gateway", "infra", + "runtimeConfig", + "cron", + "daemon", + "media", + "pluginSdk", + "secrets", + "sharedCore", + "mediaUnderstanding", "acp", + "cli", "command", "autoReply", "agent", + "plugin", "ui", "e2e", + "extensionAcpx", + "extensionDiffs", + "extensionBlueBubbles", "extensionChannel", + "extensionTelegram", + "extensionMatrix", + "extensionMemory", + "extensionMessaging", "extensionProvider", "channel", "extension", @@ -233,27 +328,61 @@ export function buildVitestRunPlans(args, cwd = process.cwd()) { ? GATEWAY_VITEST_CONFIG : kind === "infra" ? INFRA_VITEST_CONFIG - : kind === "acp" - ? ACP_VITEST_CONFIG - : kind === "command" - ? COMMANDS_VITEST_CONFIG - : kind === "autoReply" - ? AUTO_REPLY_VITEST_CONFIG - : kind === "agent" - ? AGENTS_VITEST_CONFIG - : kind === "ui" - ? UI_VITEST_CONFIG - : kind === "e2e" - ? E2E_VITEST_CONFIG - : kind === "extensionChannel" - ? EXTENSION_CHANNELS_VITEST_CONFIG - : kind === "extensionProvider" - ? EXTENSION_PROVIDERS_VITEST_CONFIG - : kind === "channel" - ? CHANNEL_VITEST_CONFIG - : kind === "extension" - ? EXTENSIONS_VITEST_CONFIG - : DEFAULT_VITEST_CONFIG; + : kind === "runtimeConfig" + ? RUNTIME_CONFIG_VITEST_CONFIG + : kind === "cron" + ? CRON_VITEST_CONFIG + : kind === "daemon" + ? DAEMON_VITEST_CONFIG + : kind === "media" + ? MEDIA_VITEST_CONFIG + : kind === "pluginSdk" + ? PLUGIN_SDK_VITEST_CONFIG + : kind === "secrets" + ? SECRETS_VITEST_CONFIG + : kind === "sharedCore" + ? SHARED_CORE_VITEST_CONFIG + : kind === "mediaUnderstanding" + ? MEDIA_UNDERSTANDING_VITEST_CONFIG + : kind === "acp" + ? ACP_VITEST_CONFIG + : kind === "cli" + ? CLI_VITEST_CONFIG + : kind === "command" + ? COMMANDS_VITEST_CONFIG + : kind === "autoReply" + ? AUTO_REPLY_VITEST_CONFIG + : kind === "agent" + ? AGENTS_VITEST_CONFIG + : kind === "plugin" + ? PLUGINS_VITEST_CONFIG + : kind === "ui" + ? UI_VITEST_CONFIG + : kind === "e2e" + ? E2E_VITEST_CONFIG + : kind === "extensionAcpx" + ? EXTENSION_ACPX_VITEST_CONFIG + : kind === "extensionDiffs" + ? EXTENSION_DIFFS_VITEST_CONFIG + : kind === "extensionBlueBubbles" + ? EXTENSION_BLUEBUBBLES_VITEST_CONFIG + : kind === "extensionChannel" + ? EXTENSION_CHANNELS_VITEST_CONFIG + : kind === "extensionTelegram" + ? EXTENSION_TELEGRAM_VITEST_CONFIG + : kind === "extensionMatrix" + ? EXTENSION_MATRIX_VITEST_CONFIG + : kind === "extensionMemory" + ? EXTENSION_MEMORY_VITEST_CONFIG + : kind === "extensionMessaging" + ? EXTENSION_MESSAGING_VITEST_CONFIG + : kind === "extensionProvider" + ? EXTENSION_PROVIDERS_VITEST_CONFIG + : kind === "channel" + ? CHANNEL_VITEST_CONFIG + : kind === "extension" + ? EXTENSIONS_VITEST_CONFIG + : DEFAULT_VITEST_CONFIG; const includePatterns = kind === "default" || kind === "e2e" ? null diff --git a/src/scripts/test-projects.test.ts b/src/scripts/test-projects.test.ts index 83cc0347868..24864863e91 100644 --- a/src/scripts/test-projects.test.ts +++ b/src/scripts/test-projects.test.ts @@ -135,6 +135,94 @@ describe("test-projects args", () => { ]); }); + it("routes runtime config targets to the runtime-config config", () => { + expect(buildVitestRunPlans(["src/config/sessions.test.ts"])).toEqual([ + { + config: "vitest.runtime-config.config.ts", + forwardedArgs: [], + includePatterns: ["src/config/sessions.test.ts"], + watchMode: false, + }, + ]); + }); + + it("routes cron targets to the cron config", () => { + expect(buildVitestRunPlans(["src/cron/isolated-agent.lane.test.ts"])).toEqual([ + { + config: "vitest.cron.config.ts", + forwardedArgs: [], + includePatterns: ["src/cron/isolated-agent.lane.test.ts"], + watchMode: false, + }, + ]); + }); + + it("routes daemon targets to the daemon config", () => { + expect(buildVitestRunPlans(["src/daemon/constants.test.ts"])).toEqual([ + { + config: "vitest.daemon.config.ts", + forwardedArgs: [], + includePatterns: ["src/daemon/constants.test.ts"], + watchMode: false, + }, + ]); + }); + + it("routes media targets to the media config", () => { + expect(buildVitestRunPlans(["src/media/mime.test.ts"])).toEqual([ + { + config: "vitest.media.config.ts", + forwardedArgs: [], + includePatterns: ["src/media/mime.test.ts"], + watchMode: false, + }, + ]); + }); + + it("routes plugin-sdk targets to the plugin-sdk config", () => { + expect(buildVitestRunPlans(["src/plugin-sdk/provider-stream.test.ts"])).toEqual([ + { + config: "vitest.plugin-sdk.config.ts", + forwardedArgs: [], + includePatterns: ["src/plugin-sdk/provider-stream.test.ts"], + watchMode: false, + }, + ]); + }); + + it("routes secrets targets to the secrets config", () => { + expect(buildVitestRunPlans(["src/secrets/resolve.test.ts"])).toEqual([ + { + config: "vitest.secrets.config.ts", + forwardedArgs: [], + includePatterns: ["src/secrets/resolve.test.ts"], + watchMode: false, + }, + ]); + }); + + it("routes shared-core targets to the shared-core config", () => { + expect(buildVitestRunPlans(["src/shared/text-chunking.test.ts"])).toEqual([ + { + config: "vitest.shared-core.config.ts", + forwardedArgs: [], + includePatterns: ["src/shared/text-chunking.test.ts"], + watchMode: false, + }, + ]); + }); + + it("routes media-understanding targets to the media-understanding config", () => { + expect(buildVitestRunPlans(["src/media-understanding/runtime.test.ts"])).toEqual([ + { + config: "vitest.media-understanding.config.ts", + forwardedArgs: [], + includePatterns: ["src/media-understanding/runtime.test.ts"], + watchMode: false, + }, + ]); + }); + it("routes command targets to the commands config", () => { expect(buildVitestRunPlans(["src/commands/status.summary.test.ts"])).toEqual([ { @@ -179,6 +267,17 @@ describe("test-projects args", () => { ]); }); + it("routes channel targets to the channels config", () => { + expect(buildVitestRunPlans(["src/channels/ids.test.ts"])).toEqual([ + { + config: "vitest.channels.config.ts", + forwardedArgs: [], + includePatterns: ["src/channels/ids.test.ts"], + watchMode: false, + }, + ]); + }); + it("routes infra targets to the infra config", () => { expect(buildVitestRunPlans(["src/infra/openclaw-root.test.ts"])).toEqual([ { @@ -210,6 +309,37 @@ describe("test-projects args", () => { ]); }); + it("routes cli targets to the cli config", () => { + expect(buildVitestRunPlans(["src/cli/test-runtime-capture.test.ts"])).toEqual([ + { + config: "vitest.cli.config.ts", + forwardedArgs: [], + includePatterns: ["src/cli/test-runtime-capture.test.ts"], + watchMode: false, + }, + ]); + }); + + it("routes plugin targets to the plugins config", () => { + expect(buildVitestRunPlans(["src/plugins/loader.test.ts"])).toEqual([ + { + config: "vitest.bundled.config.ts", + forwardedArgs: [], + includePatterns: ["src/plugins/loader.test.ts"], + watchMode: false, + }, + ]); + + expect(buildVitestRunPlans(["src/plugins/discovery.test.ts"])).toEqual([ + { + config: "vitest.plugins.config.ts", + forwardedArgs: [], + includePatterns: ["src/plugins/discovery.test.ts"], + watchMode: false, + }, + ]); + }); + it("widens non-test helper file targets to sibling tests inside the routed suite", () => { expect(buildVitestRunPlans(["src/gateway/gateway-connection.test-mocks.ts"])).toEqual([ { @@ -226,7 +356,7 @@ describe("test-projects args", () => { buildVitestRunPlans(["extensions/memory-core/src/memory/test-runtime-mocks.ts"]), ).toEqual([ { - config: "vitest.extensions.config.ts", + config: "vitest.extension-memory.config.ts", forwardedArgs: [], includePatterns: ["extensions/memory-core/src/memory/**/*.test.ts"], watchMode: false, @@ -234,6 +364,61 @@ describe("test-projects args", () => { ]); }); + it("routes telegram extension tests to the telegram config", () => { + expect(buildVitestRunPlans(["extensions/telegram/src/fetch.test.ts"])).toEqual([ + { + config: "vitest.extension-telegram.config.ts", + forwardedArgs: [], + includePatterns: ["extensions/telegram/src/fetch.test.ts"], + watchMode: false, + }, + ]); + }); + + it("routes matrix extension tests to the matrix config", () => { + expect(buildVitestRunPlans(["extensions/matrix/src/channel.test.ts"])).toEqual([ + { + config: "vitest.extension-matrix.config.ts", + forwardedArgs: [], + includePatterns: ["extensions/matrix/src/channel.test.ts"], + watchMode: false, + }, + ]); + }); + + it("routes bluebubbles extension tests to the bluebubbles config", () => { + expect(buildVitestRunPlans(["extensions/bluebubbles/src/monitor.test.ts"])).toEqual([ + { + config: "vitest.extension-bluebubbles.config.ts", + forwardedArgs: [], + includePatterns: ["extensions/bluebubbles/src/monitor.test.ts"], + watchMode: false, + }, + ]); + }); + + it("routes acpx extension tests to the acpx config", () => { + expect(buildVitestRunPlans(["extensions/acpx/src/runtime.test.ts"])).toEqual([ + { + config: "vitest.extension-acpx.config.ts", + forwardedArgs: [], + includePatterns: ["extensions/acpx/src/runtime.test.ts"], + watchMode: false, + }, + ]); + }); + + it("routes diffs extension tests to the diffs config", () => { + expect(buildVitestRunPlans(["extensions/diffs/src/render.test.ts"])).toEqual([ + { + config: "vitest.extension-diffs.config.ts", + forwardedArgs: [], + includePatterns: ["extensions/diffs/src/render.test.ts"], + watchMode: false, + }, + ]); + }); + it("routes ui targets to the ui config", () => { expect(buildVitestRunPlans(["ui/src/ui/views/channels.test.ts"])).toEqual([ { @@ -302,6 +487,17 @@ describe("test-projects args", () => { ]); }); + it("routes matrix extension file targets to the matrix config", () => { + expect(buildVitestRunPlans(["extensions/matrix/src/channel.test.ts"])).toEqual([ + { + config: "vitest.extension-matrix.config.ts", + forwardedArgs: [], + includePatterns: ["extensions/matrix/src/channel.test.ts"], + watchMode: false, + }, + ]); + }); + it("routes direct provider extension file targets to the extension providers config", () => { expect(buildVitestRunPlans(["extensions/openai/openai-codex-provider.test.ts"])).toEqual([ { @@ -334,9 +530,9 @@ describe("test-projects args", () => { ]), ).toEqual([ { - config: "vitest.unit.config.ts", - forwardedArgs: ["-t", "mention", "src/config/config-misc.test.ts"], - includePatterns: null, + config: "vitest.runtime-config.config.ts", + forwardedArgs: ["-t", "mention"], + includePatterns: ["src/config/config-misc.test.ts"], watchMode: false, }, { diff --git a/test/scripts/test-extension.test.ts b/test/scripts/test-extension.test.ts index e5ca5574497..7300a3094fd 100644 --- a/test/scripts/test-extension.test.ts +++ b/test/scripts/test-extension.test.ts @@ -43,6 +43,33 @@ describe("scripts/test-extension.mjs", () => { expect(plan.hasTests).toBe(true); }); + it("resolves bluebubbles onto the bluebubbles vitest config", () => { + const plan = resolveExtensionTestPlan({ targetArg: "bluebubbles", cwd: process.cwd() }); + + expect(plan.extensionId).toBe("bluebubbles"); + expect(plan.config).toBe("vitest.extension-bluebubbles.config.ts"); + expect(plan.roots).toContain(bundledPluginRoot("bluebubbles")); + expect(plan.hasTests).toBe(true); + }); + + it("resolves acpx onto the acpx vitest config", () => { + const plan = resolveExtensionTestPlan({ targetArg: "acpx", cwd: process.cwd() }); + + expect(plan.extensionId).toBe("acpx"); + expect(plan.config).toBe("vitest.extension-acpx.config.ts"); + expect(plan.roots).toContain(bundledPluginRoot("acpx")); + expect(plan.hasTests).toBe(true); + }); + + it("resolves diffs onto the diffs vitest config", () => { + const plan = resolveExtensionTestPlan({ targetArg: "diffs", cwd: process.cwd() }); + + expect(plan.extensionId).toBe("diffs"); + expect(plan.config).toBe("vitest.extension-diffs.config.ts"); + expect(plan.roots).toContain(bundledPluginRoot("diffs")); + expect(plan.hasTests).toBe(true); + }); + it("resolves provider extensions onto the provider vitest config", () => { const plan = resolveExtensionTestPlan({ targetArg: "openai", cwd: process.cwd() }); @@ -52,6 +79,33 @@ describe("scripts/test-extension.mjs", () => { expect(plan.hasTests).toBe(true); }); + it("resolves matrix onto the matrix vitest config", () => { + const plan = resolveExtensionTestPlan({ targetArg: "matrix", cwd: process.cwd() }); + + expect(plan.extensionId).toBe("matrix"); + expect(plan.config).toBe("vitest.extension-matrix.config.ts"); + expect(plan.roots).toContain(bundledPluginRoot("matrix")); + expect(plan.hasTests).toBe(true); + }); + + it("resolves telegram onto the telegram vitest config", () => { + const plan = resolveExtensionTestPlan({ targetArg: "telegram", cwd: process.cwd() }); + + expect(plan.extensionId).toBe("telegram"); + expect(plan.config).toBe("vitest.extension-telegram.config.ts"); + expect(plan.roots).toContain(bundledPluginRoot("telegram")); + expect(plan.hasTests).toBe(true); + }); + + it("resolves memory extensions onto the memory vitest config", () => { + const plan = resolveExtensionTestPlan({ targetArg: "memory-core", cwd: process.cwd() }); + + expect(plan.extensionId).toBe("memory-core"); + expect(plan.config).toBe("vitest.extension-memory.config.ts"); + expect(plan.roots).toContain(bundledPluginRoot("memory-core")); + expect(plan.hasTests).toBe(true); + }); + it("keeps non-provider extensions on the shared extensions vitest config", () => { const plan = resolveExtensionTestPlan({ targetArg: "firecrawl", cwd: process.cwd() }); @@ -66,7 +120,7 @@ describe("scripts/test-extension.mjs", () => { expect(plan.roots).toContain(bundledPluginRoot("line")); expect(plan.roots).not.toContain("src/line"); - expect(plan.config).toBe("vitest.channels.config.ts"); + expect(plan.config).toBe("vitest.extension-channels.config.ts"); expect(plan.hasTests).toBe(true); }); @@ -120,23 +174,81 @@ describe("scripts/test-extension.mjs", () => { it("batches extensions into config-specific vitest invocations", () => { const batch = resolveExtensionBatchPlan({ cwd: process.cwd(), - extensionIds: ["slack", "firecrawl", "line", "openai"], + extensionIds: [ + "slack", + "firecrawl", + "line", + "openai", + "matrix", + "telegram", + "memory-core", + "bluebubbles", + "acpx", + "diffs", + ], }); - expect(batch.extensionIds).toEqual(["firecrawl", "line", "openai", "slack"]); + expect(batch.extensionIds).toEqual([ + "acpx", + "bluebubbles", + "diffs", + "firecrawl", + "line", + "matrix", + "memory-core", + "openai", + "slack", + "telegram", + ]); expect(batch.planGroups).toEqual([ { - config: "vitest.channels.config.ts", + config: "vitest.extension-acpx.config.ts", + extensionIds: ["acpx"], + roots: [bundledPluginRoot("acpx")], + testFileCount: expect.any(Number), + }, + { + config: "vitest.extension-bluebubbles.config.ts", + extensionIds: ["bluebubbles"], + roots: [bundledPluginRoot("bluebubbles")], + testFileCount: expect.any(Number), + }, + { + config: "vitest.extension-channels.config.ts", extensionIds: ["line", "slack"], roots: [bundledPluginRoot("slack"), bundledPluginRoot("line")], testFileCount: expect.any(Number), }, + { + config: "vitest.extension-diffs.config.ts", + extensionIds: ["diffs"], + roots: [bundledPluginRoot("diffs")], + testFileCount: expect.any(Number), + }, + { + config: "vitest.extension-matrix.config.ts", + extensionIds: ["matrix"], + roots: [bundledPluginRoot("matrix")], + testFileCount: expect.any(Number), + }, + { + config: "vitest.extension-memory.config.ts", + extensionIds: ["memory-core"], + roots: [bundledPluginRoot("memory-core")], + testFileCount: expect.any(Number), + }, { config: "vitest.extension-providers.config.ts", extensionIds: ["openai"], roots: [bundledPluginRoot("openai")], testFileCount: expect.any(Number), }, + { + config: "vitest.extension-telegram.config.ts", + extensionIds: ["telegram"], + roots: [bundledPluginRoot("telegram")], + testFileCount: expect.any(Number), + }, { config: "vitest.extensions.config.ts", extensionIds: ["firecrawl"], diff --git a/test/vitest-scoped-config.test.ts b/test/vitest-scoped-config.test.ts index 94bc8c9444e..20c6b75c5c9 100644 --- a/test/vitest-scoped-config.test.ts +++ b/test/vitest-scoped-config.test.ts @@ -6,13 +6,30 @@ import { createAcpVitestConfig } from "../vitest.acp.config.ts"; import { createAgentsVitestConfig } from "../vitest.agents.config.ts"; import { createAutoReplyVitestConfig } from "../vitest.auto-reply.config.ts"; import { createChannelsVitestConfig } from "../vitest.channels.config.ts"; +import { createCliVitestConfig } from "../vitest.cli.config.ts"; import { createCommandsVitestConfig } from "../vitest.commands.config.ts"; +import { createCronVitestConfig } from "../vitest.cron.config.ts"; +import { createDaemonVitestConfig } from "../vitest.daemon.config.ts"; +import { createExtensionAcpxVitestConfig } from "../vitest.extension-acpx.config.ts"; +import { createExtensionBlueBubblesVitestConfig } from "../vitest.extension-bluebubbles.config.ts"; import { createExtensionChannelsVitestConfig } from "../vitest.extension-channels.config.ts"; +import { createExtensionDiffsVitestConfig } from "../vitest.extension-diffs.config.ts"; +import { createExtensionMatrixVitestConfig } from "../vitest.extension-matrix.config.ts"; +import { createExtensionMemoryVitestConfig } from "../vitest.extension-memory.config.ts"; +import { createExtensionMessagingVitestConfig } from "../vitest.extension-messaging.config.ts"; import { createExtensionProvidersVitestConfig } from "../vitest.extension-providers.config.ts"; +import { createExtensionTelegramVitestConfig } from "../vitest.extension-telegram.config.ts"; import { createExtensionsVitestConfig } from "../vitest.extensions.config.ts"; import { createGatewayVitestConfig } from "../vitest.gateway.config.ts"; import { createInfraVitestConfig } from "../vitest.infra.config.ts"; +import { createMediaUnderstandingVitestConfig } from "../vitest.media-understanding.config.ts"; +import { createMediaVitestConfig } from "../vitest.media.config.ts"; +import { createPluginSdkVitestConfig } from "../vitest.plugin-sdk.config.ts"; +import { createPluginsVitestConfig } from "../vitest.plugins.config.ts"; +import { createRuntimeConfigVitestConfig } from "../vitest.runtime-config.config.ts"; import { createScopedVitestConfig, resolveVitestIsolation } from "../vitest.scoped-config.ts"; +import { createSecretsVitestConfig } from "../vitest.secrets.config.ts"; +import { createSharedCoreVitestConfig } from "../vitest.shared-core.config.ts"; import { createToolingVitestConfig } from "../vitest.tooling.config.ts"; import { createUiVitestConfig } from "../vitest.ui.config.ts"; import { BUNDLED_PLUGIN_TEST_GLOB, bundledPluginFile } from "./helpers/bundled-plugin-paths.js"; @@ -76,24 +93,41 @@ describe("createScopedVitestConfig", () => { describe("scoped vitest configs", () => { const defaultChannelsConfig = createChannelsVitestConfig({}); const defaultAcpConfig = createAcpVitestConfig({}); + const defaultCliConfig = createCliVitestConfig({}); const defaultExtensionsConfig = createExtensionsVitestConfig({}); + const defaultExtensionAcpxConfig = createExtensionAcpxVitestConfig({}); + const defaultExtensionBlueBubblesConfig = createExtensionBlueBubblesVitestConfig({}); const defaultExtensionChannelsConfig = createExtensionChannelsVitestConfig({}); + const defaultExtensionDiffsConfig = createExtensionDiffsVitestConfig({}); + const defaultExtensionMatrixConfig = createExtensionMatrixVitestConfig({}); + const defaultExtensionMemoryConfig = createExtensionMemoryVitestConfig({}); + const defaultExtensionMessagingConfig = createExtensionMessagingVitestConfig({}); const defaultExtensionProvidersConfig = createExtensionProvidersVitestConfig({}); + const defaultExtensionTelegramConfig = createExtensionTelegramVitestConfig({}); const defaultGatewayConfig = createGatewayVitestConfig({}); const defaultInfraConfig = createInfraVitestConfig({}); + const defaultPluginSdkConfig = createPluginSdkVitestConfig({}); + const defaultSecretsConfig = createSecretsVitestConfig({}); + const defaultRuntimeConfig = createRuntimeConfigVitestConfig({}); + const defaultCronConfig = createCronVitestConfig({}); + const defaultDaemonConfig = createDaemonVitestConfig({}); + const defaultMediaConfig = createMediaVitestConfig({}); + const defaultMediaUnderstandingConfig = createMediaUnderstandingVitestConfig({}); + const defaultSharedCoreConfig = createSharedCoreVitestConfig({}); const defaultCommandsConfig = createCommandsVitestConfig({}); const defaultAutoReplyConfig = createAutoReplyVitestConfig({}); const defaultAgentsConfig = createAgentsVitestConfig({}); + const defaultPluginsConfig = createPluginsVitestConfig({}); const defaultToolingConfig = createToolingVitestConfig({}); const defaultUiConfig = createUiVitestConfig({}); it("defaults channel tests to non-isolated mode", () => { expect(defaultChannelsConfig.test?.isolate).toBe(false); - expect(defaultChannelsConfig.test?.pool).toBe("threads"); + expect(defaultChannelsConfig.test?.pool).toBe("forks"); }); it("keeps the core channel lane limited to non-extension roots", () => { - expect(defaultChannelsConfig.test?.include).toEqual([]); + expect(defaultChannelsConfig.test?.include).toEqual(["src/channels/**/*.test.ts"]); }); it("loads channel include overrides from OPENCLAW_VITEST_INCLUDE_FILE", () => { @@ -125,7 +159,7 @@ describe("scoped vitest configs", () => { it("defaults extension tests to non-isolated mode", () => { expect(defaultExtensionsConfig.test?.isolate).toBe(false); - expect(defaultExtensionsConfig.test?.pool).toBe("threads"); + expect(defaultExtensionsConfig.test?.pool).toBe("forks"); }); it("normalizes extension channel include patterns relative to the scoped dir", () => { @@ -143,6 +177,21 @@ describe("scoped vitest configs", () => { ); }); + it("normalizes bluebubbles extension include patterns relative to the scoped dir", () => { + expect(defaultExtensionBlueBubblesConfig.test?.dir).toBe("extensions"); + expect(defaultExtensionBlueBubblesConfig.test?.include).toEqual(["bluebubbles/**/*.test.ts"]); + }); + + it("normalizes acpx extension include patterns relative to the scoped dir", () => { + expect(defaultExtensionAcpxConfig.test?.dir).toBe("extensions"); + expect(defaultExtensionAcpxConfig.test?.include).toEqual(["acpx/**/*.test.ts"]); + }); + + it("normalizes diffs extension include patterns relative to the scoped dir", () => { + expect(defaultExtensionDiffsConfig.test?.dir).toBe("extensions"); + expect(defaultExtensionDiffsConfig.test?.include).toEqual(["diffs/**/*.test.ts"]); + }); + it("normalizes extension include patterns relative to the scoped dir", () => { expect(defaultExtensionsConfig.test?.dir).toBe("extensions"); expect(defaultExtensionsConfig.test?.include).toEqual(["**/*.test.ts"]); @@ -155,16 +204,40 @@ describe("scoped vitest configs", () => { ); }); - it("keeps telegram plugin tests in extensions while excluding channel-surface plugin roots", () => { + it("normalizes extension messaging include patterns relative to the scoped dir", () => { + expect(defaultExtensionMessagingConfig.test?.dir).toBe("extensions"); + expect(defaultExtensionMessagingConfig.test?.include).toEqual( + expect.arrayContaining(["feishu/**/*.test.ts"]), + ); + }); + + it("normalizes matrix extension include patterns relative to the scoped dir", () => { + expect(defaultExtensionMatrixConfig.test?.dir).toBe("extensions"); + expect(defaultExtensionMatrixConfig.test?.include).toEqual(["matrix/**/*.test.ts"]); + }); + + it("normalizes telegram extension include patterns relative to the scoped dir", () => { + expect(defaultExtensionTelegramConfig.test?.dir).toBe("extensions"); + expect(defaultExtensionTelegramConfig.test?.include).toEqual(["telegram/**/*.test.ts"]); + }); + + it("normalizes memory extension include patterns relative to the scoped dir", () => { + expect(defaultExtensionMemoryConfig.test?.dir).toBe("extensions"); + expect(defaultExtensionMemoryConfig.test?.include).toEqual( + expect.arrayContaining(["memory-core/**/*.test.ts", "memory-lancedb/**/*.test.ts"]), + ); + }); + + it("keeps telegram plugin tests out of the shared extensions lane", () => { const extensionExcludes = defaultExtensionsConfig.test?.exclude ?? []; expect( extensionExcludes.some((pattern) => path.matchesGlob("telegram/src/fetch.test.ts", pattern)), - ).toBe(false); + ).toBe(true); expect( extensionExcludes.some((pattern) => path.matchesGlob("telegram/src/bot/delivery.resolve-media-retry.test.ts", pattern), ), - ).toBe(false); + ).toBe(true); expect(defaultChannelsConfig.test?.include).not.toContain("extensions/telegram/**/*.test.ts"); expect(defaultChannelsConfig.test?.exclude).not.toContain( bundledPluginFile("telegram", "src/fetch.test.ts"), @@ -174,6 +247,11 @@ describe("scoped vitest configs", () => { "test/setup.extensions.ts", "test/setup-openclaw-runtime.ts", ]); + expect(defaultExtensionTelegramConfig.test?.setupFiles).toEqual([ + "test/setup.ts", + "test/setup.extensions.ts", + "test/setup-openclaw-runtime.ts", + ]); }); it("keeps provider plugin tests out of the shared extensions lane", () => { @@ -185,6 +263,50 @@ describe("scoped vitest configs", () => { ).toBe(true); }); + it("keeps messaging plugin tests out of the shared extensions lane", () => { + const extensionExcludes = defaultExtensionsConfig.test?.exclude ?? []; + expect( + extensionExcludes.some((pattern) => path.matchesGlob("matrix/src/channel.test.ts", pattern)), + ).toBe(true); + }); + + it("normalizes secrets include patterns relative to the scoped dir", () => { + expect(defaultSecretsConfig.test?.dir).toBe("src/secrets"); + expect(defaultSecretsConfig.test?.include).toEqual(["**/*.test.ts"]); + }); + + it("keeps memory plugin tests out of the shared extensions lane", () => { + const extensionExcludes = defaultExtensionsConfig.test?.exclude ?? []; + expect( + extensionExcludes.some((pattern) => + path.matchesGlob("memory-core/src/memory/test-runtime-mocks.ts", pattern), + ), + ).toBe(true); + }); + + it("keeps bluebubbles tests out of the shared extensions lane", () => { + const extensionExcludes = defaultExtensionsConfig.test?.exclude ?? []; + expect( + extensionExcludes.some((pattern) => + path.matchesGlob("bluebubbles/src/monitor.test.ts", pattern), + ), + ).toBe(true); + }); + + it("keeps acpx tests out of the shared extensions lane", () => { + const extensionExcludes = defaultExtensionsConfig.test?.exclude ?? []; + expect( + extensionExcludes.some((pattern) => path.matchesGlob("acpx/src/runtime.test.ts", pattern)), + ).toBe(true); + }); + + it("keeps diffs tests out of the shared extensions lane", () => { + const extensionExcludes = defaultExtensionsConfig.test?.exclude ?? []; + expect( + extensionExcludes.some((pattern) => path.matchesGlob("diffs/src/render.test.ts", pattern)), + ).toBe(true); + }); + it("normalizes gateway include patterns relative to the scoped dir", () => { expect(defaultGatewayConfig.test?.dir).toBe("src/gateway"); expect(defaultGatewayConfig.test?.include).toEqual(["**/*.test.ts"]); @@ -195,6 +317,43 @@ describe("scoped vitest configs", () => { expect(defaultInfraConfig.test?.include).toEqual(["infra/**/*.test.ts"]); }); + it("normalizes runtime config include patterns relative to the scoped dir", () => { + expect(defaultRuntimeConfig.test?.dir).toBe("src"); + expect(defaultRuntimeConfig.test?.include).toEqual(["config/**/*.test.ts"]); + }); + + it("normalizes cron include patterns relative to the scoped dir", () => { + expect(defaultCronConfig.test?.dir).toBe("src"); + expect(defaultCronConfig.test?.include).toEqual(["cron/**/*.test.ts"]); + }); + + it("normalizes daemon include patterns relative to the scoped dir", () => { + expect(defaultDaemonConfig.test?.dir).toBe("src"); + expect(defaultDaemonConfig.test?.include).toEqual(["daemon/**/*.test.ts"]); + }); + + it("normalizes media include patterns relative to the scoped dir", () => { + expect(defaultMediaConfig.test?.dir).toBe("src"); + expect(defaultMediaConfig.test?.include).toEqual(["media/**/*.test.ts"]); + }); + + it("normalizes plugin-sdk include patterns relative to the scoped dir", () => { + expect(defaultPluginSdkConfig.test?.dir).toBe("src"); + expect(defaultPluginSdkConfig.test?.include).toEqual(["plugin-sdk/**/*.test.ts"]); + }); + + it("normalizes shared-core include patterns relative to the scoped dir", () => { + expect(defaultSharedCoreConfig.test?.dir).toBe("src"); + expect(defaultSharedCoreConfig.test?.include).toEqual(["shared/**/*.test.ts"]); + }); + + it("normalizes media-understanding include patterns relative to the scoped dir", () => { + expect(defaultMediaUnderstandingConfig.test?.dir).toBe("src"); + expect(defaultMediaUnderstandingConfig.test?.include).toEqual([ + "media-understanding/**/*.test.ts", + ]); + }); + it("keeps tooling tests in their own lane", () => { expect(defaultToolingConfig.test?.include).toEqual( expect.arrayContaining([ @@ -210,6 +369,11 @@ describe("scoped vitest configs", () => { expect(defaultAcpConfig.test?.include).toEqual(["**/*.test.ts"]); }); + it("normalizes cli include patterns relative to the scoped dir", () => { + expect(defaultCliConfig.test?.dir).toBe("src/cli"); + expect(defaultCliConfig.test?.include).toEqual(["**/*.test.ts"]); + }); + it("normalizes commands include patterns relative to the scoped dir", () => { expect(defaultCommandsConfig.test?.dir).toBe("src/commands"); expect(defaultCommandsConfig.test?.include).toEqual(["**/*.test.ts"]); @@ -225,6 +389,11 @@ describe("scoped vitest configs", () => { expect(defaultAgentsConfig.test?.include).toEqual(["**/*.test.ts"]); }); + it("normalizes plugins include patterns relative to the scoped dir", () => { + expect(defaultPluginsConfig.test?.dir).toBe("src/plugins"); + expect(defaultPluginsConfig.test?.include).toEqual(["**/*.test.ts"]); + }); + it("normalizes ui include patterns relative to the scoped dir", () => { expect(defaultUiConfig.test?.dir).toBe("ui/src/ui"); expect(defaultUiConfig.test?.include).toEqual(["**/*.test.ts"]); diff --git a/vitest.channel-paths.mjs b/vitest.channel-paths.mjs index f9bd643f0f2..e99ffd9ddd8 100644 --- a/vitest.channel-paths.mjs +++ b/vitest.channel-paths.mjs @@ -11,6 +11,7 @@ export const extensionRoutedChannelTestFiles = []; const extensionRoutedChannelTestFileSet = new Set(extensionRoutedChannelTestFiles); export const channelTestRoots = [ + "src/channels", bundledPluginRoot("discord"), bundledPluginRoot("whatsapp"), bundledPluginRoot("slack"), diff --git a/vitest.channels.config.ts b/vitest.channels.config.ts index 42fcb3e9667..e0448ffb98c 100644 --- a/vitest.channels.config.ts +++ b/vitest.channels.config.ts @@ -11,7 +11,7 @@ export function loadIncludePatternsFromEnv( export function createChannelsVitestConfig(env?: Record) { return createScopedVitestConfig(loadIncludePatternsFromEnv(env) ?? coreChannelTestInclude, { env, - exclude: ["src/gateway/**"], + exclude: ["src/gateway/**", "src/channels/plugins/contracts/**"], name: "channels", passWithNoTests: true, }); diff --git a/vitest.cli.config.ts b/vitest.cli.config.ts new file mode 100644 index 00000000000..953baa1e06a --- /dev/null +++ b/vitest.cli.config.ts @@ -0,0 +1,12 @@ +import { createScopedVitestConfig } from "./vitest.scoped-config.ts"; + +export function createCliVitestConfig(env?: Record) { + return createScopedVitestConfig(["src/cli/**/*.test.ts"], { + dir: "src/cli", + env, + name: "cli", + passWithNoTests: true, + }); +} + +export default createCliVitestConfig(); diff --git a/vitest.config.ts b/vitest.config.ts index c50e0256ebe..5e0d7c96a55 100644 --- a/vitest.config.ts +++ b/vitest.config.ts @@ -15,14 +15,31 @@ export const rootVitestProjects = [ "vitest.bundled.config.ts", "vitest.gateway.config.ts", "vitest.acp.config.ts", + "vitest.runtime-config.config.ts", + "vitest.secrets.config.ts", + "vitest.cli.config.ts", "vitest.commands.config.ts", "vitest.auto-reply.config.ts", "vitest.agents.config.ts", + "vitest.daemon.config.ts", + "vitest.media.config.ts", + "vitest.plugin-sdk.config.ts", + "vitest.plugins.config.ts", + "vitest.cron.config.ts", + "vitest.media-understanding.config.ts", + "vitest.shared-core.config.ts", "vitest.tooling.config.ts", "vitest.ui.config.ts", "vitest.channels.config.ts", + "vitest.extension-acpx.config.ts", + "vitest.extension-bluebubbles.config.ts", "vitest.extension-channels.config.ts", + "vitest.extension-diffs.config.ts", + "vitest.extension-matrix.config.ts", + "vitest.extension-memory.config.ts", + "vitest.extension-messaging.config.ts", "vitest.extension-providers.config.ts", + "vitest.extension-telegram.config.ts", "vitest.extensions.config.ts", ] as const; diff --git a/vitest.cron.config.ts b/vitest.cron.config.ts new file mode 100644 index 00000000000..46b69ad6329 --- /dev/null +++ b/vitest.cron.config.ts @@ -0,0 +1,12 @@ +import { createScopedVitestConfig } from "./vitest.scoped-config.ts"; + +export function createCronVitestConfig(env?: Record) { + return createScopedVitestConfig(["src/cron/**/*.test.ts"], { + dir: "src", + env, + name: "cron", + passWithNoTests: true, + }); +} + +export default createCronVitestConfig(); diff --git a/vitest.daemon.config.ts b/vitest.daemon.config.ts new file mode 100644 index 00000000000..393a1b59db4 --- /dev/null +++ b/vitest.daemon.config.ts @@ -0,0 +1,12 @@ +import { createScopedVitestConfig } from "./vitest.scoped-config.ts"; + +export function createDaemonVitestConfig(env?: Record) { + return createScopedVitestConfig(["src/daemon/**/*.test.ts"], { + dir: "src", + env, + name: "daemon", + passWithNoTests: true, + }); +} + +export default createDaemonVitestConfig(); diff --git a/vitest.extension-acpx-paths.mjs b/vitest.extension-acpx-paths.mjs new file mode 100644 index 00000000000..0e69166dfb2 --- /dev/null +++ b/vitest.extension-acpx-paths.mjs @@ -0,0 +1,5 @@ +export const acpxExtensionTestRoots = ["extensions/acpx"]; + +export function isAcpxExtensionRoot(root) { + return acpxExtensionTestRoots.includes(root); +} diff --git a/vitest.extension-acpx.config.ts b/vitest.extension-acpx.config.ts new file mode 100644 index 00000000000..9530acf844b --- /dev/null +++ b/vitest.extension-acpx.config.ts @@ -0,0 +1,26 @@ +import { acpxExtensionTestRoots } from "./vitest.extension-acpx-paths.mjs"; +import { loadPatternListFromEnv } from "./vitest.pattern-file.ts"; +import { createScopedVitestConfig } from "./vitest.scoped-config.ts"; + +export function loadIncludePatternsFromEnv( + env: Record = process.env, +): string[] | null { + return loadPatternListFromEnv("OPENCLAW_VITEST_INCLUDE_FILE", env); +} + +export function createExtensionAcpxVitestConfig( + env: Record = process.env, +) { + return createScopedVitestConfig( + loadIncludePatternsFromEnv(env) ?? acpxExtensionTestRoots.map((root) => `${root}/**/*.test.ts`), + { + dir: "extensions", + env, + name: "extension-acpx", + passWithNoTests: true, + setupFiles: ["test/setup.extensions.ts"], + }, + ); +} + +export default createExtensionAcpxVitestConfig(); diff --git a/vitest.extension-bluebubbles-paths.mjs b/vitest.extension-bluebubbles-paths.mjs new file mode 100644 index 00000000000..e119979fbe8 --- /dev/null +++ b/vitest.extension-bluebubbles-paths.mjs @@ -0,0 +1,5 @@ +export const blueBubblesExtensionTestRoots = ["extensions/bluebubbles"]; + +export function isBlueBubblesExtensionRoot(root) { + return blueBubblesExtensionTestRoots.includes(root); +} diff --git a/vitest.extension-bluebubbles.config.ts b/vitest.extension-bluebubbles.config.ts new file mode 100644 index 00000000000..f9931ee732f --- /dev/null +++ b/vitest.extension-bluebubbles.config.ts @@ -0,0 +1,27 @@ +import { blueBubblesExtensionTestRoots } from "./vitest.extension-bluebubbles-paths.mjs"; +import { loadPatternListFromEnv } from "./vitest.pattern-file.ts"; +import { createScopedVitestConfig } from "./vitest.scoped-config.ts"; + +export function loadIncludePatternsFromEnv( + env: Record = process.env, +): string[] | null { + return loadPatternListFromEnv("OPENCLAW_VITEST_INCLUDE_FILE", env); +} + +export function createExtensionBlueBubblesVitestConfig( + env: Record = process.env, +) { + return createScopedVitestConfig( + loadIncludePatternsFromEnv(env) ?? + blueBubblesExtensionTestRoots.map((root) => `${root}/**/*.test.ts`), + { + dir: "extensions", + env, + name: "extension-bluebubbles", + passWithNoTests: true, + setupFiles: ["test/setup.extensions.ts"], + }, + ); +} + +export default createExtensionBlueBubblesVitestConfig(); diff --git a/vitest.extension-diffs-paths.mjs b/vitest.extension-diffs-paths.mjs new file mode 100644 index 00000000000..9559113ef01 --- /dev/null +++ b/vitest.extension-diffs-paths.mjs @@ -0,0 +1,5 @@ +export const diffsExtensionTestRoots = ["extensions/diffs"]; + +export function isDiffsExtensionRoot(root) { + return diffsExtensionTestRoots.includes(root); +} diff --git a/vitest.extension-diffs.config.ts b/vitest.extension-diffs.config.ts new file mode 100644 index 00000000000..19fbea7ae1f --- /dev/null +++ b/vitest.extension-diffs.config.ts @@ -0,0 +1,27 @@ +import { diffsExtensionTestRoots } from "./vitest.extension-diffs-paths.mjs"; +import { loadPatternListFromEnv } from "./vitest.pattern-file.ts"; +import { createScopedVitestConfig } from "./vitest.scoped-config.ts"; + +export function loadIncludePatternsFromEnv( + env: Record = process.env, +): string[] | null { + return loadPatternListFromEnv("OPENCLAW_VITEST_INCLUDE_FILE", env); +} + +export function createExtensionDiffsVitestConfig( + env: Record = process.env, +) { + return createScopedVitestConfig( + loadIncludePatternsFromEnv(env) ?? + diffsExtensionTestRoots.map((root) => `${root}/**/*.test.ts`), + { + dir: "extensions", + env, + name: "extension-diffs", + passWithNoTests: true, + setupFiles: ["test/setup.extensions.ts"], + }, + ); +} + +export default createExtensionDiffsVitestConfig(); diff --git a/vitest.extension-matrix-paths.mjs b/vitest.extension-matrix-paths.mjs new file mode 100644 index 00000000000..29d9856200b --- /dev/null +++ b/vitest.extension-matrix-paths.mjs @@ -0,0 +1,9 @@ +import { bundledPluginRoot } from "./scripts/lib/bundled-plugin-paths.mjs"; + +export const matrixExtensionIds = ["matrix"]; + +export const matrixExtensionTestRoots = matrixExtensionIds.map((id) => bundledPluginRoot(id)); + +export function isMatrixExtensionRoot(root) { + return matrixExtensionTestRoots.includes(root); +} diff --git a/vitest.extension-matrix.config.ts b/vitest.extension-matrix.config.ts new file mode 100644 index 00000000000..18bd8c29786 --- /dev/null +++ b/vitest.extension-matrix.config.ts @@ -0,0 +1,17 @@ +import { matrixExtensionTestRoots } from "./vitest.extension-matrix-paths.mjs"; +import { createScopedVitestConfig } from "./vitest.scoped-config.ts"; + +export function createExtensionMatrixVitestConfig(env?: Record) { + return createScopedVitestConfig( + matrixExtensionTestRoots.map((root) => `${root}/**/*.test.ts`), + { + dir: "extensions", + env, + name: "extension-matrix", + passWithNoTests: true, + setupFiles: ["test/setup.extensions.ts"], + }, + ); +} + +export default createExtensionMatrixVitestConfig(); diff --git a/vitest.extension-memory-paths.mjs b/vitest.extension-memory-paths.mjs new file mode 100644 index 00000000000..4b6d83de819 --- /dev/null +++ b/vitest.extension-memory-paths.mjs @@ -0,0 +1,5 @@ +export const memoryExtensionTestRoots = ["extensions/memory-core", "extensions/memory-lancedb"]; + +export function isMemoryExtensionRoot(root) { + return memoryExtensionTestRoots.includes(root); +} diff --git a/vitest.extension-memory.config.ts b/vitest.extension-memory.config.ts new file mode 100644 index 00000000000..594e8a046b9 --- /dev/null +++ b/vitest.extension-memory.config.ts @@ -0,0 +1,27 @@ +import { memoryExtensionTestRoots } from "./vitest.extension-memory-paths.mjs"; +import { loadPatternListFromEnv } from "./vitest.pattern-file.ts"; +import { createScopedVitestConfig } from "./vitest.scoped-config.ts"; + +export function loadIncludePatternsFromEnv( + env: Record = process.env, +): string[] | null { + return loadPatternListFromEnv("OPENCLAW_VITEST_INCLUDE_FILE", env); +} + +export function createExtensionMemoryVitestConfig( + env: Record = process.env, +) { + return createScopedVitestConfig( + loadIncludePatternsFromEnv(env) ?? + memoryExtensionTestRoots.map((root) => `${root}/**/*.test.ts`), + { + dir: "extensions", + env, + name: "extension-memory", + passWithNoTests: true, + setupFiles: ["test/setup.extensions.ts"], + }, + ); +} + +export default createExtensionMemoryVitestConfig(); diff --git a/vitest.extension-messaging-paths.mjs b/vitest.extension-messaging-paths.mjs new file mode 100644 index 00000000000..bc920bfc927 --- /dev/null +++ b/vitest.extension-messaging-paths.mjs @@ -0,0 +1,25 @@ +import { bundledPluginRoot } from "./scripts/lib/bundled-plugin-paths.mjs"; + +export const messagingExtensionIds = [ + "bluebubbles", + "feishu", + "googlechat", + "irc", + "mattermost", + "msteams", + "nextcloud-talk", + "nostr", + "qqbot", + "synology-chat", + "tlon", + "twitch", + "voice-call", + "zalo", + "zalouser", +]; + +export const messagingExtensionTestRoots = messagingExtensionIds.map((id) => bundledPluginRoot(id)); + +export function isMessagingExtensionRoot(root) { + return messagingExtensionTestRoots.includes(root); +} diff --git a/vitest.extension-messaging.config.ts b/vitest.extension-messaging.config.ts new file mode 100644 index 00000000000..bd2f2e00e75 --- /dev/null +++ b/vitest.extension-messaging.config.ts @@ -0,0 +1,27 @@ +import { messagingExtensionTestRoots } from "./vitest.extension-messaging-paths.mjs"; +import { loadPatternListFromEnv } from "./vitest.pattern-file.ts"; +import { createScopedVitestConfig } from "./vitest.scoped-config.ts"; + +export function loadIncludePatternsFromEnv( + env: Record = process.env, +): string[] | null { + return loadPatternListFromEnv("OPENCLAW_VITEST_INCLUDE_FILE", env); +} + +export function createExtensionMessagingVitestConfig( + env: Record = process.env, +) { + return createScopedVitestConfig( + loadIncludePatternsFromEnv(env) ?? + messagingExtensionTestRoots.map((root) => `${root}/**/*.test.ts`), + { + dir: "extensions", + env, + name: "extension-messaging", + passWithNoTests: true, + setupFiles: ["test/setup.extensions.ts"], + }, + ); +} + +export default createExtensionMessagingVitestConfig(); diff --git a/vitest.extension-telegram-paths.mjs b/vitest.extension-telegram-paths.mjs new file mode 100644 index 00000000000..2ee49f94d44 --- /dev/null +++ b/vitest.extension-telegram-paths.mjs @@ -0,0 +1,5 @@ +export const telegramExtensionTestRoots = ["extensions/telegram"]; + +export function isTelegramExtensionRoot(root) { + return telegramExtensionTestRoots.includes(root); +} diff --git a/vitest.extension-telegram.config.ts b/vitest.extension-telegram.config.ts new file mode 100644 index 00000000000..470f8d2d569 --- /dev/null +++ b/vitest.extension-telegram.config.ts @@ -0,0 +1,27 @@ +import { telegramExtensionTestRoots } from "./vitest.extension-telegram-paths.mjs"; +import { loadPatternListFromEnv } from "./vitest.pattern-file.ts"; +import { createScopedVitestConfig } from "./vitest.scoped-config.ts"; + +export function loadIncludePatternsFromEnv( + env: Record = process.env, +): string[] | null { + return loadPatternListFromEnv("OPENCLAW_VITEST_INCLUDE_FILE", env); +} + +export function createExtensionTelegramVitestConfig( + env: Record = process.env, +) { + return createScopedVitestConfig( + loadIncludePatternsFromEnv(env) ?? + telegramExtensionTestRoots.map((root) => `${root}/**/*.test.ts`), + { + dir: "extensions", + env, + name: "extension-telegram", + passWithNoTests: true, + setupFiles: ["test/setup.extensions.ts"], + }, + ); +} + +export default createExtensionTelegramVitestConfig(); diff --git a/vitest.extensions.config.ts b/vitest.extensions.config.ts index d978198a182..d9e5168e68e 100644 --- a/vitest.extensions.config.ts +++ b/vitest.extensions.config.ts @@ -1,6 +1,13 @@ import { BUNDLED_PLUGIN_TEST_GLOB } from "./vitest.bundled-plugin-paths.ts"; import { extensionExcludedChannelTestGlobs } from "./vitest.channel-paths.mjs"; +import { acpxExtensionTestRoots } from "./vitest.extension-acpx-paths.mjs"; +import { blueBubblesExtensionTestRoots } from "./vitest.extension-bluebubbles-paths.mjs"; +import { diffsExtensionTestRoots } from "./vitest.extension-diffs-paths.mjs"; +import { matrixExtensionTestRoots } from "./vitest.extension-matrix-paths.mjs"; +import { memoryExtensionTestRoots } from "./vitest.extension-memory-paths.mjs"; +import { messagingExtensionTestRoots } from "./vitest.extension-messaging-paths.mjs"; import { providerExtensionTestRoots } from "./vitest.extension-provider-paths.mjs"; +import { telegramExtensionTestRoots } from "./vitest.extension-telegram-paths.mjs"; import { loadPatternListFromEnv } from "./vitest.pattern-file.ts"; import { createScopedVitestConfig } from "./vitest.scoped-config.ts"; @@ -23,7 +30,14 @@ export function createExtensionsVitestConfig( // out of the shared extensions lane. exclude: [ ...extensionExcludedChannelTestGlobs, + ...acpxExtensionTestRoots.map((root) => `${root.replace(/^extensions\//u, "")}/**`), + ...blueBubblesExtensionTestRoots.map((root) => `${root.replace(/^extensions\//u, "")}/**`), + ...diffsExtensionTestRoots.map((root) => `${root.replace(/^extensions\//u, "")}/**`), + ...matrixExtensionTestRoots.map((root) => `${root.replace(/^extensions\//u, "")}/**`), + ...memoryExtensionTestRoots.map((root) => `${root.replace(/^extensions\//u, "")}/**`), + ...messagingExtensionTestRoots.map((root) => `${root.replace(/^extensions\//u, "")}/**`), ...providerExtensionTestRoots.map((root) => `${root.replace(/^extensions\//u, "")}/**`), + ...telegramExtensionTestRoots.map((root) => `${root.replace(/^extensions\//u, "")}/**`), ], }); } diff --git a/vitest.media-understanding.config.ts b/vitest.media-understanding.config.ts new file mode 100644 index 00000000000..ed52290989a --- /dev/null +++ b/vitest.media-understanding.config.ts @@ -0,0 +1,12 @@ +import { createScopedVitestConfig } from "./vitest.scoped-config.ts"; + +export function createMediaUnderstandingVitestConfig(env?: Record) { + return createScopedVitestConfig(["src/media-understanding/**/*.test.ts"], { + dir: "src", + env, + name: "media-understanding", + passWithNoTests: true, + }); +} + +export default createMediaUnderstandingVitestConfig(); diff --git a/vitest.media.config.ts b/vitest.media.config.ts new file mode 100644 index 00000000000..a97382525f2 --- /dev/null +++ b/vitest.media.config.ts @@ -0,0 +1,12 @@ +import { createScopedVitestConfig } from "./vitest.scoped-config.ts"; + +export function createMediaVitestConfig(env?: Record) { + return createScopedVitestConfig(["src/media/**/*.test.ts"], { + dir: "src", + env, + name: "media", + passWithNoTests: true, + }); +} + +export default createMediaVitestConfig(); diff --git a/vitest.plugin-sdk.config.ts b/vitest.plugin-sdk.config.ts new file mode 100644 index 00000000000..c49dea19324 --- /dev/null +++ b/vitest.plugin-sdk.config.ts @@ -0,0 +1,12 @@ +import { createScopedVitestConfig } from "./vitest.scoped-config.ts"; + +export function createPluginSdkVitestConfig(env?: Record) { + return createScopedVitestConfig(["src/plugin-sdk/**/*.test.ts"], { + dir: "src", + env, + name: "plugin-sdk", + passWithNoTests: true, + }); +} + +export default createPluginSdkVitestConfig(); diff --git a/vitest.plugins.config.ts b/vitest.plugins.config.ts new file mode 100644 index 00000000000..7fdbc97f4b4 --- /dev/null +++ b/vitest.plugins.config.ts @@ -0,0 +1,12 @@ +import { createScopedVitestConfig } from "./vitest.scoped-config.ts"; + +export function createPluginsVitestConfig(env?: Record) { + return createScopedVitestConfig(["src/plugins/**/*.test.ts"], { + dir: "src/plugins", + env, + name: "plugins", + passWithNoTests: true, + }); +} + +export default createPluginsVitestConfig(); diff --git a/vitest.runtime-config.config.ts b/vitest.runtime-config.config.ts new file mode 100644 index 00000000000..8d448c3574c --- /dev/null +++ b/vitest.runtime-config.config.ts @@ -0,0 +1,12 @@ +import { createScopedVitestConfig } from "./vitest.scoped-config.ts"; + +export function createRuntimeConfigVitestConfig(env?: Record) { + return createScopedVitestConfig(["src/config/**/*.test.ts"], { + dir: "src", + env, + name: "runtime-config", + passWithNoTests: true, + }); +} + +export default createRuntimeConfigVitestConfig(); diff --git a/vitest.scoped-config.ts b/vitest.scoped-config.ts index 6c48c5df004..9e7ce1af5a3 100644 --- a/vitest.scoped-config.ts +++ b/vitest.scoped-config.ts @@ -48,7 +48,7 @@ export function createScopedVitestConfig( includeOpenClawRuntimeSetup?: boolean; isolate?: boolean; name?: string; - pool?: "threads" | "forks"; + pool?: "forks"; passWithNoTests?: boolean; setupFiles?: string[]; useNonIsolatedRunner?: boolean; diff --git a/vitest.secrets.config.ts b/vitest.secrets.config.ts new file mode 100644 index 00000000000..dc583872ec9 --- /dev/null +++ b/vitest.secrets.config.ts @@ -0,0 +1,12 @@ +import { createScopedVitestConfig } from "./vitest.scoped-config.ts"; + +export function createSecretsVitestConfig(env?: Record) { + return createScopedVitestConfig(["src/secrets/**/*.test.ts"], { + dir: "src/secrets", + env, + name: "secrets", + passWithNoTests: true, + }); +} + +export default createSecretsVitestConfig(); diff --git a/vitest.shared-core.config.ts b/vitest.shared-core.config.ts new file mode 100644 index 00000000000..945b171a269 --- /dev/null +++ b/vitest.shared-core.config.ts @@ -0,0 +1,12 @@ +import { createScopedVitestConfig } from "./vitest.scoped-config.ts"; + +export function createSharedCoreVitestConfig(env?: Record) { + return createScopedVitestConfig(["src/shared/**/*.test.ts"], { + dir: "src", + env, + name: "shared-core", + passWithNoTests: true, + }); +} + +export default createSharedCoreVitestConfig(); diff --git a/vitest.shared.config.ts b/vitest.shared.config.ts index 34ec87d641d..17b4ee31ada 100644 --- a/vitest.shared.config.ts +++ b/vitest.shared.config.ts @@ -21,7 +21,7 @@ type VitestHostInfo = { totalMemoryBytes?: number; }; -export type OpenClawVitestPool = "threads" | "forks"; +export type OpenClawVitestPool = "forks"; export const jsdomOptimizedDeps = { optimizer: { @@ -97,10 +97,10 @@ export function resolveDefaultVitestPool( env: Record = process.env, ): OpenClawVitestPool { const configuredPool = (env.OPENCLAW_VITEST_POOL ?? env.OPENCLAW_TEST_POOL)?.trim(); - if (configuredPool === "threads" || configuredPool === "forks") { - return configuredPool; + if (configuredPool && configuredPool !== "forks") { + return "forks"; } - return "threads"; + return "forks"; } const repoRoot = path.dirname(fileURLToPath(import.meta.url)); @@ -146,21 +146,45 @@ export const sharedVitestConfig = { "vitest.acp.config.ts", "vitest.boundary.config.ts", "vitest.bundled.config.ts", + "vitest.cli.config.ts", "vitest.config.ts", "vitest.contracts.config.ts", + "vitest.cron.config.ts", + "vitest.daemon.config.ts", "vitest.e2e.config.ts", + "vitest.extension-acpx-paths.mjs", + "vitest.extension-acpx.config.ts", + "vitest.extension-bluebubbles-paths.mjs", + "vitest.extension-bluebubbles.config.ts", "vitest.extension-channels.config.ts", + "vitest.extension-diffs-paths.mjs", + "vitest.extension-diffs.config.ts", + "vitest.extension-matrix-paths.mjs", + "vitest.extension-matrix.config.ts", + "vitest.extension-memory-paths.mjs", + "vitest.extension-memory.config.ts", + "vitest.extension-messaging-paths.mjs", + "vitest.extension-messaging.config.ts", "vitest.extensions.config.ts", "vitest.gateway.config.ts", "vitest.infra.config.ts", "vitest.live.config.ts", + "vitest.media.config.ts", + "vitest.media-understanding.config.ts", "vitest.performance-config.ts", "vitest.scoped-config.ts", + "vitest.shared-core.config.ts", "vitest.shared.config.ts", "vitest.tooling.config.ts", "vitest.ui.config.ts", "vitest.unit.config.ts", "vitest.unit-paths.mjs", + "vitest.runtime-config.config.ts", + "vitest.secrets.config.ts", + "vitest.plugin-sdk.config.ts", + "vitest.plugins.config.ts", + "vitest.extension-telegram-paths.mjs", + "vitest.extension-telegram.config.ts", "vitest.extension-provider-paths.mjs", "vitest.extension-providers.config.ts", ], @@ -235,6 +259,7 @@ export const sharedVitestConfig = { "src/node-host/**", "src/plugins/**", "src/providers/**", + "src/secrets/**", "src/agents/model-scan.ts", "src/agents/pi-embedded-runner.ts", "src/agents/sandbox-paths.ts", diff --git a/vitest.unit-paths.mjs b/vitest.unit-paths.mjs index 61b9cb194b6..7e63a9d7e87 100644 --- a/vitest.unit-paths.mjs +++ b/vitest.unit-paths.mjs @@ -46,8 +46,18 @@ export const unitTestAdditionalExcludePatterns = [ "src/line/**", "src/agents/**", "src/auto-reply/**", + "src/channels/**", + "src/cli/**", "src/commands/**", - "src/channels/plugins/contracts/**", + "src/config/**", + "src/cron/**", + "src/daemon/**", + "src/media/**", + "src/plugin-sdk/**", + "src/plugins/**", + "src/secrets/**", + "src/shared/**", + "src/media-understanding/**", "src/plugins/contracts/**", "src/scripts/**", "src/infra/boundary-path.test.ts",