mirror of
https://github.com/openclaw/openclaw.git
synced 2026-04-12 01:31:08 +00:00
Tests: add unit-fast Vitest lane
This commit is contained in:
@@ -1248,6 +1248,9 @@
|
||||
"test:startup:bench:update": "node scripts/test-update-cli-startup-bench.mjs",
|
||||
"test:startup:memory": "node scripts/check-cli-startup-memory.mjs",
|
||||
"test:ui": "pnpm ui:i18n:check && pnpm lint:ui:no-raw-window-open && pnpm --dir ui test",
|
||||
"test:unit": "pnpm test:unit:fast && node scripts/run-vitest.mjs run --config vitest.unit.config.ts",
|
||||
"test:unit:fast": "node scripts/run-vitest.mjs run --config vitest.unit-fast.config.ts",
|
||||
"test:unit:fast:audit": "node scripts/test-unit-fast-audit.mjs",
|
||||
"test:voicecall:closedloop": "node scripts/test-voicecall-closedloop.mjs",
|
||||
"test:watch": "node scripts/test-projects.mjs --watch",
|
||||
"tool-display:check": "node --import tsx scripts/tool-display.ts --check",
|
||||
|
||||
@@ -27,6 +27,7 @@ import {
|
||||
resolvePluginSdkLightIncludePattern,
|
||||
} from "../vitest.plugin-sdk-paths.mjs";
|
||||
import { fullSuiteVitestShards } from "../vitest.test-shards.mjs";
|
||||
import { resolveUnitFastTestIncludePattern } from "../vitest.unit-fast-paths.mjs";
|
||||
import { isBoundaryTestFile, isBundledPluginDependentUnitTestFile } from "../vitest.unit-paths.mjs";
|
||||
import { resolveVitestCliEntry, resolveVitestNodeArgs } from "./run-vitest.mjs";
|
||||
|
||||
@@ -70,6 +71,7 @@ const LOGGING_VITEST_CONFIG = "vitest.logging.config.ts";
|
||||
const PLUGIN_SDK_LIGHT_VITEST_CONFIG = "vitest.plugin-sdk-light.config.ts";
|
||||
const PLUGIN_SDK_VITEST_CONFIG = "vitest.plugin-sdk.config.ts";
|
||||
const PLUGINS_VITEST_CONFIG = "vitest.plugins.config.ts";
|
||||
const UNIT_FAST_VITEST_CONFIG = "vitest.unit-fast.config.ts";
|
||||
const PROCESS_VITEST_CONFIG = "vitest.process.config.ts";
|
||||
const RUNTIME_CONFIG_VITEST_CONFIG = "vitest.runtime-config.config.ts";
|
||||
const SECRETS_VITEST_CONFIG = "vitest.secrets.config.ts";
|
||||
@@ -82,6 +84,58 @@ const UTILS_VITEST_CONFIG = "vitest.utils.config.ts";
|
||||
const WIZARD_VITEST_CONFIG = "vitest.wizard.config.ts";
|
||||
const INCLUDE_FILE_ENV_KEY = "OPENCLAW_VITEST_INCLUDE_FILE";
|
||||
const CHANGED_ARGS_PATTERN = /^--changed(?:=(.+))?$/u;
|
||||
const VITEST_CONFIG_BY_KIND = {
|
||||
acp: ACP_VITEST_CONFIG,
|
||||
agent: AGENTS_VITEST_CONFIG,
|
||||
autoReply: AUTO_REPLY_VITEST_CONFIG,
|
||||
boundary: BOUNDARY_VITEST_CONFIG,
|
||||
bundled: BUNDLED_VITEST_CONFIG,
|
||||
channel: CHANNEL_VITEST_CONFIG,
|
||||
cli: CLI_VITEST_CONFIG,
|
||||
command: COMMANDS_VITEST_CONFIG,
|
||||
commandLight: COMMANDS_LIGHT_VITEST_CONFIG,
|
||||
contracts: CONTRACTS_VITEST_CONFIG,
|
||||
cron: CRON_VITEST_CONFIG,
|
||||
daemon: DAEMON_VITEST_CONFIG,
|
||||
e2e: E2E_VITEST_CONFIG,
|
||||
extension: EXTENSIONS_VITEST_CONFIG,
|
||||
extensionAcpx: EXTENSION_ACPX_VITEST_CONFIG,
|
||||
extensionBlueBubbles: EXTENSION_BLUEBUBBLES_VITEST_CONFIG,
|
||||
extensionChannel: EXTENSION_CHANNELS_VITEST_CONFIG,
|
||||
extensionDiffs: EXTENSION_DIFFS_VITEST_CONFIG,
|
||||
extensionFeishu: EXTENSION_FEISHU_VITEST_CONFIG,
|
||||
extensionIrc: EXTENSION_IRC_VITEST_CONFIG,
|
||||
extensionMatrix: EXTENSION_MATRIX_VITEST_CONFIG,
|
||||
extensionMattermost: EXTENSION_MATTERMOST_VITEST_CONFIG,
|
||||
extensionMemory: EXTENSION_MEMORY_VITEST_CONFIG,
|
||||
extensionMessaging: EXTENSION_MESSAGING_VITEST_CONFIG,
|
||||
extensionMsTeams: EXTENSION_MSTEAMS_VITEST_CONFIG,
|
||||
extensionProvider: EXTENSION_PROVIDERS_VITEST_CONFIG,
|
||||
extensionTelegram: EXTENSION_TELEGRAM_VITEST_CONFIG,
|
||||
extensionVoiceCall: EXTENSION_VOICE_CALL_VITEST_CONFIG,
|
||||
extensionWhatsApp: EXTENSION_WHATSAPP_VITEST_CONFIG,
|
||||
extensionZalo: EXTENSION_ZALO_VITEST_CONFIG,
|
||||
gateway: GATEWAY_VITEST_CONFIG,
|
||||
hooks: HOOKS_VITEST_CONFIG,
|
||||
infra: INFRA_VITEST_CONFIG,
|
||||
logging: LOGGING_VITEST_CONFIG,
|
||||
media: MEDIA_VITEST_CONFIG,
|
||||
mediaUnderstanding: MEDIA_UNDERSTANDING_VITEST_CONFIG,
|
||||
plugin: PLUGINS_VITEST_CONFIG,
|
||||
pluginSdk: PLUGIN_SDK_VITEST_CONFIG,
|
||||
pluginSdkLight: PLUGIN_SDK_LIGHT_VITEST_CONFIG,
|
||||
process: PROCESS_VITEST_CONFIG,
|
||||
unitFast: UNIT_FAST_VITEST_CONFIG,
|
||||
runtimeConfig: RUNTIME_CONFIG_VITEST_CONFIG,
|
||||
secrets: SECRETS_VITEST_CONFIG,
|
||||
sharedCore: SHARED_CORE_VITEST_CONFIG,
|
||||
tasks: TASKS_VITEST_CONFIG,
|
||||
tooling: TOOLING_VITEST_CONFIG,
|
||||
tui: TUI_VITEST_CONFIG,
|
||||
ui: UI_VITEST_CONFIG,
|
||||
utils: UTILS_VITEST_CONFIG,
|
||||
wizard: WIZARD_VITEST_CONFIG,
|
||||
};
|
||||
const BROAD_CHANGED_RERUN_PATTERNS = [
|
||||
/^package\.json$/u,
|
||||
/^pnpm-lock\.yaml$/u,
|
||||
@@ -221,6 +275,9 @@ export function resolveChangedTargetArgs(
|
||||
|
||||
function classifyTarget(arg, cwd) {
|
||||
const relative = toRepoRelativeTarget(arg, cwd);
|
||||
if (resolveUnitFastTestIncludePattern(relative)) {
|
||||
return "unitFast";
|
||||
}
|
||||
if (relative.endsWith(".e2e.test.ts")) {
|
||||
return "e2e";
|
||||
}
|
||||
@@ -376,6 +433,10 @@ function classifyTarget(arg, cwd) {
|
||||
|
||||
function resolveLightLaneIncludePatterns(kind, targetArg, cwd) {
|
||||
const relative = toRepoRelativeTarget(targetArg, cwd);
|
||||
if (kind === "unitFast") {
|
||||
const includePattern = resolveUnitFastTestIncludePattern(relative);
|
||||
return includePattern ? [includePattern] : null;
|
||||
}
|
||||
if (kind === "pluginSdkLight") {
|
||||
const includePattern = resolvePluginSdkLightIncludePattern(relative);
|
||||
return includePattern ? [includePattern] : null;
|
||||
@@ -459,6 +520,7 @@ export function buildVitestRunPlans(
|
||||
|
||||
const nonTargetArgs = activeForwardedArgs.filter((arg) => !activeTargetArgs.includes(arg));
|
||||
const orderedKinds = [
|
||||
"unitFast",
|
||||
"default",
|
||||
"boundary",
|
||||
"tooling",
|
||||
@@ -516,122 +578,7 @@ export function buildVitestRunPlans(
|
||||
if (!grouped || grouped.length === 0) {
|
||||
continue;
|
||||
}
|
||||
const config =
|
||||
kind === "boundary"
|
||||
? BOUNDARY_VITEST_CONFIG
|
||||
: kind === "tooling"
|
||||
? TOOLING_VITEST_CONFIG
|
||||
: kind === "contracts"
|
||||
? CONTRACTS_VITEST_CONFIG
|
||||
: kind === "bundled"
|
||||
? BUNDLED_VITEST_CONFIG
|
||||
: kind === "gateway"
|
||||
? GATEWAY_VITEST_CONFIG
|
||||
: kind === "hooks"
|
||||
? HOOKS_VITEST_CONFIG
|
||||
: kind === "infra"
|
||||
? INFRA_VITEST_CONFIG
|
||||
: kind === "runtimeConfig"
|
||||
? RUNTIME_CONFIG_VITEST_CONFIG
|
||||
: kind === "cron"
|
||||
? CRON_VITEST_CONFIG
|
||||
: kind === "daemon"
|
||||
? DAEMON_VITEST_CONFIG
|
||||
: kind === "media"
|
||||
? MEDIA_VITEST_CONFIG
|
||||
: kind === "logging"
|
||||
? LOGGING_VITEST_CONFIG
|
||||
: kind === "pluginSdkLight"
|
||||
? PLUGIN_SDK_LIGHT_VITEST_CONFIG
|
||||
: kind === "pluginSdk"
|
||||
? PLUGIN_SDK_VITEST_CONFIG
|
||||
: kind === "process"
|
||||
? PROCESS_VITEST_CONFIG
|
||||
: kind === "secrets"
|
||||
? SECRETS_VITEST_CONFIG
|
||||
: kind === "sharedCore"
|
||||
? SHARED_CORE_VITEST_CONFIG
|
||||
: kind === "tasks"
|
||||
? TASKS_VITEST_CONFIG
|
||||
: kind === "tui"
|
||||
? TUI_VITEST_CONFIG
|
||||
: kind === "mediaUnderstanding"
|
||||
? MEDIA_UNDERSTANDING_VITEST_CONFIG
|
||||
: kind === "acp"
|
||||
? ACP_VITEST_CONFIG
|
||||
: kind === "cli"
|
||||
? CLI_VITEST_CONFIG
|
||||
: kind === "commandLight"
|
||||
? COMMANDS_LIGHT_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 === "utils"
|
||||
? UTILS_VITEST_CONFIG
|
||||
: kind === "wizard"
|
||||
? WIZARD_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 ===
|
||||
"extensionFeishu"
|
||||
? EXTENSION_FEISHU_VITEST_CONFIG
|
||||
: kind ===
|
||||
"extensionIrc"
|
||||
? EXTENSION_IRC_VITEST_CONFIG
|
||||
: kind ===
|
||||
"extensionMattermost"
|
||||
? EXTENSION_MATTERMOST_VITEST_CONFIG
|
||||
: kind ===
|
||||
"extensionChannel"
|
||||
? EXTENSION_CHANNELS_VITEST_CONFIG
|
||||
: kind ===
|
||||
"extensionTelegram"
|
||||
? EXTENSION_TELEGRAM_VITEST_CONFIG
|
||||
: kind ===
|
||||
"extensionVoiceCall"
|
||||
? EXTENSION_VOICE_CALL_VITEST_CONFIG
|
||||
: kind ===
|
||||
"extensionWhatsApp"
|
||||
? EXTENSION_WHATSAPP_VITEST_CONFIG
|
||||
: kind ===
|
||||
"extensionZalo"
|
||||
? EXTENSION_ZALO_VITEST_CONFIG
|
||||
: kind ===
|
||||
"extensionMatrix"
|
||||
? EXTENSION_MATRIX_VITEST_CONFIG
|
||||
: kind ===
|
||||
"extensionMemory"
|
||||
? EXTENSION_MEMORY_VITEST_CONFIG
|
||||
: kind ===
|
||||
"extensionMsTeams"
|
||||
? EXTENSION_MSTEAMS_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 config = VITEST_CONFIG_BY_KIND[kind] ?? DEFAULT_VITEST_CONFIG;
|
||||
const useCliTargetArgs =
|
||||
kind === "e2e" ||
|
||||
(kind === "default" &&
|
||||
|
||||
60
scripts/test-unit-fast-audit.mjs
Normal file
60
scripts/test-unit-fast-audit.mjs
Normal file
@@ -0,0 +1,60 @@
|
||||
import {
|
||||
collectBroadUnitFastTestCandidates,
|
||||
collectUnitFastTestFileAnalysis,
|
||||
collectUnitFastTestCandidates,
|
||||
unitFastTestFiles,
|
||||
} from "../vitest.unit-fast-paths.mjs";
|
||||
|
||||
const args = new Set(process.argv.slice(2));
|
||||
const json = args.has("--json");
|
||||
const scope = args.has("--broad") ? "broad" : "current";
|
||||
|
||||
const analysis = collectUnitFastTestFileAnalysis(process.cwd(), { scope });
|
||||
const rejected = analysis.filter((entry) => !entry.unitFast);
|
||||
const reasonCounts = new Map();
|
||||
const candidateCount =
|
||||
scope === "broad"
|
||||
? collectBroadUnitFastTestCandidates(process.cwd()).length
|
||||
: collectUnitFastTestCandidates(process.cwd()).length;
|
||||
const unitFastCount = analysis.filter((entry) => entry.unitFast).length;
|
||||
|
||||
for (const entry of rejected) {
|
||||
for (const reason of entry.reasons) {
|
||||
reasonCounts.set(reason, (reasonCounts.get(reason) ?? 0) + 1);
|
||||
}
|
||||
}
|
||||
|
||||
if (json) {
|
||||
console.log(
|
||||
JSON.stringify(
|
||||
{
|
||||
candidates: candidateCount,
|
||||
unitFast: unitFastCount,
|
||||
routed: unitFastTestFiles.length,
|
||||
rejected: rejected.length,
|
||||
reasonCounts: Object.fromEntries(
|
||||
[...reasonCounts.entries()].toSorted(([a], [b]) => a.localeCompare(b)),
|
||||
),
|
||||
scope,
|
||||
files: analysis,
|
||||
},
|
||||
null,
|
||||
2,
|
||||
),
|
||||
);
|
||||
process.exit(0);
|
||||
}
|
||||
|
||||
console.log(
|
||||
[
|
||||
`[test-unit-fast-audit] scope=${scope} candidates=${analysis.length} unitFast=${unitFastCount} routed=${unitFastTestFiles.length} rejected=${rejected.length}`,
|
||||
scope === "broad"
|
||||
? `[test-unit-fast-audit] broad unit-fast candidates are not routed automatically`
|
||||
: "",
|
||||
"",
|
||||
"Rejected reasons:",
|
||||
...[...reasonCounts.entries()]
|
||||
.toSorted((a, b) => b[1] - a[1] || a[0].localeCompare(b[0]))
|
||||
.map(([reason, count]) => ` ${String(count).padStart(4, " ")} ${reason}`),
|
||||
].join("\n"),
|
||||
);
|
||||
@@ -226,6 +226,13 @@ describe("test scripts", () => {
|
||||
expect(pkg.scripts?.["test:fast"]).toBe(
|
||||
"node scripts/run-vitest.mjs run --config vitest.unit.config.ts",
|
||||
);
|
||||
expect(pkg.scripts?.["test:unit"]).toBe(
|
||||
"pnpm test:unit:fast && node scripts/run-vitest.mjs run --config vitest.unit.config.ts",
|
||||
);
|
||||
expect(pkg.scripts?.["test:unit:fast"]).toBe(
|
||||
"node scripts/run-vitest.mjs run --config vitest.unit-fast.config.ts",
|
||||
);
|
||||
expect(pkg.scripts?.["test:unit:fast:audit"]).toBe("node scripts/test-unit-fast-audit.mjs");
|
||||
expect(pkg.scripts?.["test"]).toBe("node scripts/test-projects.mjs");
|
||||
expect(pkg.scripts?.["test:gateway"]).toBe(
|
||||
"node scripts/run-vitest.mjs run --config vitest.gateway.config.ts",
|
||||
|
||||
@@ -163,33 +163,44 @@ describe("test-projects args", () => {
|
||||
});
|
||||
|
||||
it("routes daemon targets to the daemon config", () => {
|
||||
expect(buildVitestRunPlans(["src/daemon/constants.test.ts"])).toEqual([
|
||||
expect(buildVitestRunPlans(["src/daemon/inspect.test.ts"])).toEqual([
|
||||
{
|
||||
config: "vitest.daemon.config.ts",
|
||||
forwardedArgs: [],
|
||||
includePatterns: ["src/daemon/constants.test.ts"],
|
||||
includePatterns: ["src/daemon/inspect.test.ts"],
|
||||
watchMode: false,
|
||||
},
|
||||
]);
|
||||
});
|
||||
|
||||
it("routes media targets to the media config", () => {
|
||||
expect(buildVitestRunPlans(["src/media/mime.test.ts"])).toEqual([
|
||||
expect(buildVitestRunPlans(["src/media/fetch.test.ts"])).toEqual([
|
||||
{
|
||||
config: "vitest.media.config.ts",
|
||||
forwardedArgs: [],
|
||||
includePatterns: ["src/media/mime.test.ts"],
|
||||
includePatterns: ["src/media/fetch.test.ts"],
|
||||
watchMode: false,
|
||||
},
|
||||
]);
|
||||
});
|
||||
|
||||
it("routes plugin-sdk targets to the plugin-sdk config", () => {
|
||||
expect(buildVitestRunPlans(["src/plugin-sdk/provider-stream.test.ts"])).toEqual([
|
||||
expect(buildVitestRunPlans(["src/plugin-sdk/anthropic-vertex-auth-presence.test.ts"])).toEqual([
|
||||
{
|
||||
config: "vitest.plugin-sdk.config.ts",
|
||||
forwardedArgs: [],
|
||||
includePatterns: ["src/plugin-sdk/provider-stream.test.ts"],
|
||||
includePatterns: ["src/plugin-sdk/anthropic-vertex-auth-presence.test.ts"],
|
||||
watchMode: false,
|
||||
},
|
||||
]);
|
||||
});
|
||||
|
||||
it("routes unit-fast light targets to the cache-friendly unit-fast config", () => {
|
||||
expect(buildVitestRunPlans(["src/plugin-sdk/provider-entry.test.ts"])).toEqual([
|
||||
{
|
||||
config: "vitest.unit-fast.config.ts",
|
||||
forwardedArgs: [],
|
||||
includePatterns: ["src/plugin-sdk/provider-entry.test.ts"],
|
||||
watchMode: false,
|
||||
},
|
||||
]);
|
||||
@@ -217,10 +228,10 @@ describe("test-projects args", () => {
|
||||
]);
|
||||
});
|
||||
|
||||
it("routes shared-core targets to the shared-core config", () => {
|
||||
it("routes unit-fast shared-core targets to the unit-fast config", () => {
|
||||
expect(buildVitestRunPlans(["src/shared/text-chunking.test.ts"])).toEqual([
|
||||
{
|
||||
config: "vitest.shared-core.config.ts",
|
||||
config: "vitest.unit-fast.config.ts",
|
||||
forwardedArgs: [],
|
||||
includePatterns: ["src/shared/text-chunking.test.ts"],
|
||||
watchMode: false,
|
||||
@@ -240,11 +251,11 @@ describe("test-projects args", () => {
|
||||
});
|
||||
|
||||
it("routes logging targets to the logging config", () => {
|
||||
expect(buildVitestRunPlans(["src/logging/load-levels.test.ts"])).toEqual([
|
||||
expect(buildVitestRunPlans(["src/logging/console-settings.test.ts"])).toEqual([
|
||||
{
|
||||
config: "vitest.logging.config.ts",
|
||||
forwardedArgs: [],
|
||||
includePatterns: ["src/logging/load-levels.test.ts"],
|
||||
includePatterns: ["src/logging/console-settings.test.ts"],
|
||||
watchMode: false,
|
||||
},
|
||||
]);
|
||||
@@ -339,11 +350,11 @@ describe("test-projects args", () => {
|
||||
});
|
||||
|
||||
it("routes channel targets to the channels config", () => {
|
||||
expect(buildVitestRunPlans(["src/channels/ids.test.ts"])).toEqual([
|
||||
expect(buildVitestRunPlans(["src/channels/session.test.ts"])).toEqual([
|
||||
{
|
||||
config: "vitest.channels.config.ts",
|
||||
forwardedArgs: [],
|
||||
includePatterns: ["src/channels/ids.test.ts"],
|
||||
includePatterns: ["src/channels/session.test.ts"],
|
||||
watchMode: false,
|
||||
},
|
||||
]);
|
||||
|
||||
@@ -55,9 +55,9 @@ describe("scripts/test-projects changed-target routing", () => {
|
||||
|
||||
expect(plans).toEqual([
|
||||
{
|
||||
config: "vitest.shared-core.config.ts",
|
||||
config: "vitest.unit-fast.config.ts",
|
||||
forwardedArgs: [],
|
||||
includePatterns: ["src/shared/**/*.test.ts"],
|
||||
includePatterns: ["src/shared/string-normalization.test.ts"],
|
||||
watchMode: false,
|
||||
},
|
||||
{
|
||||
@@ -83,13 +83,29 @@ describe("scripts/test-projects changed-target routing", () => {
|
||||
});
|
||||
|
||||
it("routes explicit commands light tests to the lighter commands lane", () => {
|
||||
const plans = buildVitestRunPlans(["src/commands/cleanup-utils.test.ts"], process.cwd());
|
||||
const plans = buildVitestRunPlans(["src/commands/status-json-runtime.test.ts"], process.cwd());
|
||||
|
||||
expect(plans).toEqual([
|
||||
{
|
||||
config: "vitest.commands-light.config.ts",
|
||||
forwardedArgs: [],
|
||||
includePatterns: ["src/commands/cleanup-utils.test.ts"],
|
||||
includePatterns: ["src/commands/status-json-runtime.test.ts"],
|
||||
watchMode: false,
|
||||
},
|
||||
]);
|
||||
});
|
||||
|
||||
it("routes unit-fast light tests to the cache-friendly unit-fast lane", () => {
|
||||
const plans = buildVitestRunPlans(
|
||||
["src/commands/status-overview-values.test.ts"],
|
||||
process.cwd(),
|
||||
);
|
||||
|
||||
expect(plans).toEqual([
|
||||
{
|
||||
config: "vitest.unit-fast.config.ts",
|
||||
forwardedArgs: [],
|
||||
includePatterns: ["src/commands/status-overview-values.test.ts"],
|
||||
watchMode: false,
|
||||
},
|
||||
]);
|
||||
@@ -97,14 +113,14 @@ describe("scripts/test-projects changed-target routing", () => {
|
||||
|
||||
it("routes changed plugin-sdk source allowlist files to sibling light tests", () => {
|
||||
const plans = buildVitestRunPlans(["--changed", "origin/main"], process.cwd(), () => [
|
||||
"src/plugin-sdk/lazy-value.ts",
|
||||
"src/plugin-sdk/provider-entry.ts",
|
||||
]);
|
||||
|
||||
expect(plans).toEqual([
|
||||
{
|
||||
config: "vitest.plugin-sdk-light.config.ts",
|
||||
config: "vitest.unit-fast.config.ts",
|
||||
forwardedArgs: [],
|
||||
includePatterns: ["src/plugin-sdk/lazy-value.test.ts"],
|
||||
includePatterns: ["src/plugin-sdk/provider-entry.test.ts"],
|
||||
watchMode: false,
|
||||
},
|
||||
]);
|
||||
@@ -118,7 +134,7 @@ describe("scripts/test-projects changed-target routing", () => {
|
||||
|
||||
expect(plans).toEqual([
|
||||
{
|
||||
config: "vitest.commands-light.config.ts",
|
||||
config: "vitest.unit-fast.config.ts",
|
||||
forwardedArgs: [],
|
||||
includePatterns: [
|
||||
"src/commands/status-overview-values.test.ts",
|
||||
@@ -163,6 +179,12 @@ describe("scripts/test-projects changed-target routing", () => {
|
||||
describe("scripts/test-projects full-suite sharding", () => {
|
||||
it("splits untargeted runs into fixed shard configs", () => {
|
||||
expect(buildFullSuiteVitestRunPlans([], process.cwd())).toEqual([
|
||||
{
|
||||
config: "vitest.full-core-unit-fast.config.ts",
|
||||
forwardedArgs: [],
|
||||
includePatterns: null,
|
||||
watchMode: false,
|
||||
},
|
||||
{
|
||||
config: "vitest.full-core-unit-src.config.ts",
|
||||
forwardedArgs: [],
|
||||
|
||||
@@ -8,6 +8,7 @@ import { createContractsVitestConfig } from "../vitest.contracts.config.ts";
|
||||
import { createGatewayVitestConfig } from "../vitest.gateway.config.ts";
|
||||
import { createPluginSdkLightVitestConfig } from "../vitest.plugin-sdk-light.config.ts";
|
||||
import { createUiVitestConfig } from "../vitest.ui.config.ts";
|
||||
import { createUnitFastVitestConfig } from "../vitest.unit-fast.config.ts";
|
||||
import { createUnitVitestConfig } from "../vitest.unit.config.ts";
|
||||
|
||||
describe("projects vitest config", () => {
|
||||
@@ -21,6 +22,7 @@ describe("projects vitest config", () => {
|
||||
expect(createCommandsLightVitestConfig().test.pool).toBe("threads");
|
||||
expect(createCommandsVitestConfig().test.pool).toBe("threads");
|
||||
expect(createPluginSdkLightVitestConfig().test.pool).toBe("threads");
|
||||
expect(createUnitFastVitestConfig().test.pool).toBe("threads");
|
||||
expect(createContractsVitestConfig().test.pool).toBe("threads");
|
||||
});
|
||||
|
||||
@@ -46,6 +48,12 @@ describe("projects vitest config", () => {
|
||||
expect(config.test.runner).toBe("./test/non-isolated-runner.ts");
|
||||
});
|
||||
|
||||
it("keeps the unit-fast lane on shared workers without the reset-heavy runner", () => {
|
||||
const config = createUnitFastVitestConfig();
|
||||
expect(config.test.isolate).toBe(false);
|
||||
expect(config.test.runner).toBeUndefined();
|
||||
});
|
||||
|
||||
it("keeps the bundled lane on thread workers with the non-isolated runner", () => {
|
||||
expect(bundledConfig.test?.pool).toBe("threads");
|
||||
expect(bundledConfig.test?.isolate).toBe(false);
|
||||
|
||||
65
test/vitest-unit-fast-config.test.ts
Normal file
65
test/vitest-unit-fast-config.test.ts
Normal file
@@ -0,0 +1,65 @@
|
||||
import { describe, expect, it } from "vitest";
|
||||
import { createCommandsLightVitestConfig } from "../vitest.commands-light.config.ts";
|
||||
import { createPluginSdkLightVitestConfig } from "../vitest.plugin-sdk-light.config.ts";
|
||||
import {
|
||||
classifyUnitFastTestFileContent,
|
||||
collectBroadUnitFastTestCandidates,
|
||||
collectUnitFastTestCandidates,
|
||||
collectUnitFastTestFileAnalysis,
|
||||
isUnitFastTestFile,
|
||||
unitFastTestFiles,
|
||||
resolveUnitFastTestIncludePattern,
|
||||
} from "../vitest.unit-fast-paths.mjs";
|
||||
import { createUnitFastVitestConfig } from "../vitest.unit-fast.config.ts";
|
||||
|
||||
describe("unit-fast vitest lane", () => {
|
||||
it("runs cache-friendly tests without the reset-heavy runner or runtime setup", () => {
|
||||
const config = createUnitFastVitestConfig({});
|
||||
|
||||
expect(config.test?.isolate).toBe(false);
|
||||
expect(config.test?.runner).toBeUndefined();
|
||||
expect(config.test?.setupFiles).toEqual([]);
|
||||
expect(config.test?.include).toContain("src/plugin-sdk/provider-entry.test.ts");
|
||||
expect(config.test?.include).toContain("src/commands/status-overview-values.test.ts");
|
||||
});
|
||||
|
||||
it("keeps obvious stateful files out of the unit-fast lane", () => {
|
||||
expect(isUnitFastTestFile("src/plugin-sdk/temp-path.test.ts")).toBe(false);
|
||||
expect(resolveUnitFastTestIncludePattern("src/plugin-sdk/temp-path.ts")).toBeNull();
|
||||
expect(classifyUnitFastTestFileContent("vi.resetModules(); await import('./x.js')")).toEqual([
|
||||
"module-mocking",
|
||||
"vitest-mock-api",
|
||||
"dynamic-import",
|
||||
]);
|
||||
});
|
||||
|
||||
it("routes unit-fast source files to their unit-fast sibling tests", () => {
|
||||
expect(resolveUnitFastTestIncludePattern("src/plugin-sdk/provider-entry.ts")).toBe(
|
||||
"src/plugin-sdk/provider-entry.test.ts",
|
||||
);
|
||||
expect(resolveUnitFastTestIncludePattern("src/commands/status-overview-values.ts")).toBe(
|
||||
"src/commands/status-overview-values.test.ts",
|
||||
);
|
||||
});
|
||||
|
||||
it("keeps broad audit candidates separate from automatically routed unit-fast tests", () => {
|
||||
const currentCandidates = collectUnitFastTestCandidates();
|
||||
const broadCandidates = collectBroadUnitFastTestCandidates();
|
||||
const broadAnalysis = collectUnitFastTestFileAnalysis(process.cwd(), { scope: "broad" });
|
||||
|
||||
expect(currentCandidates.length).toBeGreaterThanOrEqual(unitFastTestFiles.length);
|
||||
expect(broadCandidates.length).toBeGreaterThan(currentCandidates.length);
|
||||
expect(broadAnalysis.filter((entry) => entry.unitFast).length).toBeGreaterThan(
|
||||
unitFastTestFiles.length,
|
||||
);
|
||||
});
|
||||
|
||||
it("excludes unit-fast files from the older light lanes so full runs do not duplicate them", () => {
|
||||
const pluginSdkLight = createPluginSdkLightVitestConfig({});
|
||||
const commandsLight = createCommandsLightVitestConfig({});
|
||||
|
||||
expect(unitFastTestFiles).toContain("src/plugin-sdk/provider-entry.test.ts");
|
||||
expect(pluginSdkLight.test?.exclude).toContain("plugin-sdk/provider-entry.test.ts");
|
||||
expect(commandsLight.test?.exclude).toContain("status-overview-values.test.ts");
|
||||
});
|
||||
});
|
||||
@@ -1,10 +1,12 @@
|
||||
import { commandsLightTestFiles } from "./vitest.commands-light-paths.mjs";
|
||||
import { createScopedVitestConfig } from "./vitest.scoped-config.ts";
|
||||
import { unitFastTestFiles } from "./vitest.unit-fast-paths.mjs";
|
||||
|
||||
export function createCommandsLightVitestConfig(env?: Record<string, string | undefined>) {
|
||||
return createScopedVitestConfig(commandsLightTestFiles, {
|
||||
dir: "src/commands",
|
||||
env,
|
||||
exclude: unitFastTestFiles,
|
||||
includeOpenClawRuntimeSetup: false,
|
||||
name: "commands-light",
|
||||
passWithNoTests: true,
|
||||
|
||||
@@ -26,6 +26,7 @@ export const rootVitestProjects = [
|
||||
"vitest.agents.config.ts",
|
||||
"vitest.daemon.config.ts",
|
||||
"vitest.media.config.ts",
|
||||
"vitest.unit-fast.config.ts",
|
||||
"vitest.plugin-sdk-light.config.ts",
|
||||
"vitest.plugin-sdk.config.ts",
|
||||
"vitest.plugins.config.ts",
|
||||
|
||||
11
vitest.full-core-unit-fast.config.ts
Normal file
11
vitest.full-core-unit-fast.config.ts
Normal file
@@ -0,0 +1,11 @@
|
||||
import { defineConfig } from "vitest/config";
|
||||
import { sharedVitestConfig } from "./vitest.shared.config.ts";
|
||||
|
||||
export default defineConfig({
|
||||
...sharedVitestConfig,
|
||||
test: {
|
||||
...sharedVitestConfig.test,
|
||||
runner: undefined,
|
||||
projects: ["vitest.unit-fast.config.ts"],
|
||||
},
|
||||
});
|
||||
@@ -1,10 +1,12 @@
|
||||
import { pluginSdkLightTestFiles } from "./vitest.plugin-sdk-paths.mjs";
|
||||
import { createScopedVitestConfig } from "./vitest.scoped-config.ts";
|
||||
import { unitFastTestFiles } from "./vitest.unit-fast-paths.mjs";
|
||||
|
||||
export function createPluginSdkLightVitestConfig(env?: Record<string, string | undefined>) {
|
||||
return createScopedVitestConfig(pluginSdkLightTestFiles, {
|
||||
dir: "src",
|
||||
env,
|
||||
exclude: unitFastTestFiles,
|
||||
includeOpenClawRuntimeSetup: false,
|
||||
name: "plugin-sdk-light",
|
||||
passWithNoTests: true,
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { defineConfig } from "vitest/config";
|
||||
import { loadPatternListFromEnv, narrowIncludePatternsForCli } from "./vitest.pattern-file.ts";
|
||||
import { sharedVitestConfig } from "./vitest.shared.config.ts";
|
||||
import { unitFastTestFiles } from "./vitest.unit-fast-paths.mjs";
|
||||
|
||||
function normalizePathPattern(value: string): string {
|
||||
return value.replaceAll("\\", "/");
|
||||
@@ -59,7 +60,7 @@ export function createScopedVitestConfig(
|
||||
const includeFromEnv = loadPatternListFromEnv("OPENCLAW_VITEST_INCLUDE_FILE", env);
|
||||
const cliInclude = narrowIncludePatternsForCli(include, options?.argv);
|
||||
const exclude = relativizeScopedPatterns(
|
||||
[...(baseTest.exclude ?? []), ...(options?.exclude ?? [])],
|
||||
[...(baseTest.exclude ?? []), ...unitFastTestFiles, ...(options?.exclude ?? [])],
|
||||
scopedDir,
|
||||
);
|
||||
const isolate = options?.isolate ?? resolveVitestIsolation(options?.env);
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
import { createScopedVitestConfig } from "./vitest.scoped-config.ts";
|
||||
import { unitFastTestFiles } from "./vitest.unit-fast-paths.mjs";
|
||||
|
||||
export function createSharedCoreVitestConfig(env?: Record<string, string | undefined>) {
|
||||
return createScopedVitestConfig(["src/shared/**/*.test.ts"], {
|
||||
dir: "src",
|
||||
env,
|
||||
exclude: unitFastTestFiles,
|
||||
includeOpenClawRuntimeSetup: false,
|
||||
name: "shared-core",
|
||||
passWithNoTests: true,
|
||||
|
||||
@@ -256,6 +256,8 @@ export const sharedVitestConfig = {
|
||||
"vitest.media.config.ts",
|
||||
"vitest.media-understanding.config.ts",
|
||||
"vitest.performance-config.ts",
|
||||
"vitest.unit-fast.config.ts",
|
||||
"vitest.unit-fast-paths.mjs",
|
||||
"vitest.scoped-config.ts",
|
||||
"vitest.shared-core.config.ts",
|
||||
"vitest.shared.config.ts",
|
||||
|
||||
@@ -7,6 +7,11 @@ export const autoReplyTopLevelReplyTestInclude = ["src/auto-reply/reply*.test.ts
|
||||
export const autoReplyReplySubtreeTestInclude = ["src/auto-reply/reply/**/*.test.ts"];
|
||||
|
||||
export const fullSuiteVitestShards = [
|
||||
{
|
||||
config: "vitest.full-core-unit-fast.config.ts",
|
||||
name: "core-unit-fast",
|
||||
projects: ["vitest.unit-fast.config.ts"],
|
||||
},
|
||||
{
|
||||
config: "vitest.full-core-unit-src.config.ts",
|
||||
name: "core-unit-src",
|
||||
|
||||
231
vitest.unit-fast-paths.mjs
Normal file
231
vitest.unit-fast-paths.mjs
Normal file
@@ -0,0 +1,231 @@
|
||||
import fs from "node:fs";
|
||||
import path from "node:path";
|
||||
import {
|
||||
commandsLightSourceFiles,
|
||||
commandsLightTestFiles,
|
||||
} from "./vitest.commands-light-paths.mjs";
|
||||
import { pluginSdkLightSourceFiles, pluginSdkLightTestFiles } from "./vitest.plugin-sdk-paths.mjs";
|
||||
|
||||
const normalizeRepoPath = (value) => value.replaceAll("\\", "/");
|
||||
|
||||
const unitFastCandidateGlobs = [
|
||||
"packages/memory-host-sdk/**/*.test.ts",
|
||||
"packages/plugin-package-contract/**/*.test.ts",
|
||||
"src/acp/**/*.test.ts",
|
||||
"src/bootstrap/**/*.test.ts",
|
||||
"src/channels/**/*.test.ts",
|
||||
"src/cli/**/*.test.ts",
|
||||
"src/config/**/*.test.ts",
|
||||
"src/daemon/**/*.test.ts",
|
||||
"src/i18n/**/*.test.ts",
|
||||
"src/hooks/**/*.test.ts",
|
||||
"src/image-generation/**/*.test.ts",
|
||||
"src/infra/**/*.test.ts",
|
||||
"src/interactive/**/*.test.ts",
|
||||
"src/link-understanding/**/*.test.ts",
|
||||
"src/logging/**/*.test.ts",
|
||||
"src/markdown/**/*.test.ts",
|
||||
"src/media/**/*.test.ts",
|
||||
"src/media-generation/**/*.test.ts",
|
||||
"src/media-understanding/**/*.test.ts",
|
||||
"src/memory-host-sdk/**/*.test.ts",
|
||||
"src/music-generation/**/*.test.ts",
|
||||
"src/node-host/**/*.test.ts",
|
||||
"src/plugin-sdk/**/*.test.ts",
|
||||
"src/poll-params.test.ts",
|
||||
"src/polls.test.ts",
|
||||
"src/process/**/*.test.ts",
|
||||
"src/routing/**/*.test.ts",
|
||||
"src/sessions/**/*.test.ts",
|
||||
"src/shared/**/*.test.ts",
|
||||
"src/terminal/**/*.test.ts",
|
||||
"src/test-utils/**/*.test.ts",
|
||||
"src/tasks/**/*.test.ts",
|
||||
"src/tts/**/*.test.ts",
|
||||
"src/utils/**/*.test.ts",
|
||||
"src/video-generation/**/*.test.ts",
|
||||
"src/wizard/**/*.test.ts",
|
||||
"test/**/*.test.ts",
|
||||
];
|
||||
const unitFastCandidateExactFiles = [...pluginSdkLightTestFiles, ...commandsLightTestFiles];
|
||||
const broadUnitFastCandidateGlobs = [
|
||||
"src/**/*.test.ts",
|
||||
"packages/**/*.test.ts",
|
||||
"test/**/*.test.ts",
|
||||
];
|
||||
const broadUnitFastCandidateSkipGlobs = [
|
||||
"**/*.e2e.test.ts",
|
||||
"**/*.live.test.ts",
|
||||
"test/fixtures/**/*.test.ts",
|
||||
"test/setup-home-isolation.test.ts",
|
||||
"src/config/schema.base.generated.test.ts",
|
||||
"src/gateway/**/*.test.ts",
|
||||
"src/security/**/*.test.ts",
|
||||
"src/secrets/**/*.test.ts",
|
||||
"src/tasks/**/*.test.ts",
|
||||
];
|
||||
|
||||
const disqualifyingPatterns = [
|
||||
{
|
||||
code: "jsdom-environment",
|
||||
pattern: /@vitest-environment\s+jsdom/u,
|
||||
},
|
||||
{
|
||||
code: "module-mocking",
|
||||
pattern: /\bvi\.(?:mock|doMock|unmock|doUnmock|importActual|resetModules)\s*\(/u,
|
||||
},
|
||||
{
|
||||
code: "vitest-mock-api",
|
||||
pattern: /\bvi\b/u,
|
||||
},
|
||||
{
|
||||
code: "dynamic-import",
|
||||
pattern: /\b(?:await\s+)?import\s*\(/u,
|
||||
},
|
||||
{
|
||||
code: "fake-timers",
|
||||
pattern:
|
||||
/\bvi\.(?:useFakeTimers|setSystemTime|advanceTimers|runAllTimers|runOnlyPendingTimers)\s*\(/u,
|
||||
},
|
||||
{
|
||||
code: "env-or-global-stub",
|
||||
pattern: /\bvi\.(?:stubEnv|stubGlobal|unstubAllEnvs|unstubAllGlobals)\s*\(/u,
|
||||
},
|
||||
{
|
||||
code: "process-env-mutation",
|
||||
pattern: /(?:process\.env(?:\.[A-Za-z_$][\w$]*|\[[^\]]+\])?\s*=|delete\s+process\.env)/u,
|
||||
},
|
||||
{
|
||||
code: "global-mutation",
|
||||
pattern: /(?:globalThis|global)\s*\[[^\]]+\]\s*=/u,
|
||||
},
|
||||
{
|
||||
code: "filesystem-state",
|
||||
pattern:
|
||||
/\b(?:mkdtemp|rmSync|writeFileSync|appendFileSync|mkdirSync|createTemp|makeTempDir|tempDir|tmpdir|node:fs|node:os)\b/u,
|
||||
},
|
||||
{
|
||||
code: "runtime-singleton-state",
|
||||
pattern: /\b(?:setActivePluginRegistry|resetPluginRuntimeStateForTest|reset.*ForTest)\s*\(/u,
|
||||
},
|
||||
];
|
||||
|
||||
function matchesAnyGlob(file, patterns) {
|
||||
return patterns.some((pattern) => path.matchesGlob(file, pattern));
|
||||
}
|
||||
|
||||
function walkFiles(directory, files = []) {
|
||||
let entries;
|
||||
try {
|
||||
entries = fs.readdirSync(directory, { withFileTypes: true });
|
||||
} catch {
|
||||
return files;
|
||||
}
|
||||
|
||||
for (const entry of entries) {
|
||||
const entryPath = path.join(directory, entry.name);
|
||||
if (entry.isDirectory()) {
|
||||
if (entry.name === "node_modules" || entry.name === "dist" || entry.name === "vendor") {
|
||||
continue;
|
||||
}
|
||||
walkFiles(entryPath, files);
|
||||
continue;
|
||||
}
|
||||
if (entry.isFile() && entry.name.endsWith(".test.ts")) {
|
||||
files.push(normalizeRepoPath(entryPath));
|
||||
}
|
||||
}
|
||||
return files;
|
||||
}
|
||||
|
||||
export function classifyUnitFastTestFileContent(source) {
|
||||
const reasons = [];
|
||||
for (const { code, pattern } of disqualifyingPatterns) {
|
||||
if (pattern.test(source)) {
|
||||
reasons.push(code);
|
||||
}
|
||||
}
|
||||
return reasons;
|
||||
}
|
||||
|
||||
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),
|
||||
);
|
||||
return [...new Set([...discovered, ...unitFastCandidateExactFiles])].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),
|
||||
);
|
||||
return [...new Set([...discovered, ...unitFastCandidateExactFiles])].toSorted((a, b) =>
|
||||
a.localeCompare(b),
|
||||
);
|
||||
}
|
||||
|
||||
export function collectUnitFastTestFileAnalysis(cwd = process.cwd(), options = {}) {
|
||||
const candidates =
|
||||
options.scope === "broad"
|
||||
? collectBroadUnitFastTestCandidates(cwd)
|
||||
: collectUnitFastTestCandidates(cwd);
|
||||
return candidates.map((file) => {
|
||||
const absolutePath = path.join(cwd, file);
|
||||
let source = "";
|
||||
try {
|
||||
source = fs.readFileSync(absolutePath, "utf8");
|
||||
} catch {
|
||||
return {
|
||||
file,
|
||||
unitFast: false,
|
||||
reasons: ["missing-file"],
|
||||
};
|
||||
}
|
||||
const reasons = classifyUnitFastTestFileContent(source);
|
||||
return {
|
||||
file,
|
||||
unitFast: reasons.length === 0,
|
||||
reasons,
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
export const unitFastTestFiles = collectUnitFastTestFileAnalysis()
|
||||
.filter((entry) => entry.unitFast)
|
||||
.map((entry) => entry.file);
|
||||
|
||||
const unitFastTestFileSet = new Set(unitFastTestFiles);
|
||||
const sourceToUnitFastTestFile = new Map(
|
||||
[...pluginSdkLightSourceFiles, ...commandsLightSourceFiles].flatMap((sourceFile) => {
|
||||
const testFile = sourceFile.replace(/\.ts$/u, ".test.ts");
|
||||
return unitFastTestFileSet.has(testFile) ? [[sourceFile, testFile]] : [];
|
||||
}),
|
||||
);
|
||||
|
||||
export function isUnitFastTestFile(file) {
|
||||
return unitFastTestFileSet.has(normalizeRepoPath(file));
|
||||
}
|
||||
|
||||
export function resolveUnitFastTestIncludePattern(file) {
|
||||
const normalized = normalizeRepoPath(file);
|
||||
if (unitFastTestFileSet.has(normalized)) {
|
||||
return normalized;
|
||||
}
|
||||
const siblingTestFile = normalized.replace(/\.ts$/u, ".test.ts");
|
||||
if (unitFastTestFileSet.has(siblingTestFile)) {
|
||||
return siblingTestFile;
|
||||
}
|
||||
return sourceToUnitFastTestFile.get(normalized) ?? null;
|
||||
}
|
||||
29
vitest.unit-fast.config.ts
Normal file
29
vitest.unit-fast.config.ts
Normal file
@@ -0,0 +1,29 @@
|
||||
import { defineConfig } from "vitest/config";
|
||||
import { loadPatternListFromEnv, narrowIncludePatternsForCli } from "./vitest.pattern-file.ts";
|
||||
import { sharedVitestConfig } from "./vitest.shared.config.ts";
|
||||
import { unitFastTestFiles } from "./vitest.unit-fast-paths.mjs";
|
||||
|
||||
export function createUnitFastVitestConfig(
|
||||
env: Record<string, string | undefined> = process.env,
|
||||
options: { argv?: string[] } = {},
|
||||
) {
|
||||
const sharedTest = sharedVitestConfig.test ?? {};
|
||||
const includeFromEnv = loadPatternListFromEnv("OPENCLAW_VITEST_INCLUDE_FILE", env);
|
||||
const cliInclude = narrowIncludePatternsForCli(unitFastTestFiles, options.argv);
|
||||
|
||||
return defineConfig({
|
||||
...sharedVitestConfig,
|
||||
test: {
|
||||
...sharedTest,
|
||||
name: "unit-fast",
|
||||
isolate: false,
|
||||
runner: undefined,
|
||||
setupFiles: [],
|
||||
include: includeFromEnv ?? cliInclude ?? unitFastTestFiles,
|
||||
exclude: sharedTest.exclude ?? [],
|
||||
passWithNoTests: true,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
export default createUnitFastVitestConfig();
|
||||
@@ -2,6 +2,7 @@ import { defineProject } from "vitest/config";
|
||||
import { loadPatternListFromEnv, narrowIncludePatternsForCli } from "./vitest.pattern-file.ts";
|
||||
import { resolveVitestIsolation } from "./vitest.scoped-config.ts";
|
||||
import { sharedVitestConfig } from "./vitest.shared.config.ts";
|
||||
import { unitFastTestFiles } from "./vitest.unit-fast-paths.mjs";
|
||||
import {
|
||||
isBundledPluginDependentUnitTestFile,
|
||||
unitTestAdditionalExcludePatterns,
|
||||
@@ -59,6 +60,7 @@ export function createUnitVitestConfigWithOptions(
|
||||
...new Set([
|
||||
...exclude,
|
||||
...baseExcludePatterns,
|
||||
...unitFastTestFiles,
|
||||
...(options.extraExcludePatterns ?? []),
|
||||
...loadExtraExcludePatternsFromEnv(env),
|
||||
]),
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
import { createScopedVitestConfig } from "./vitest.scoped-config.ts";
|
||||
import { unitFastTestFiles } from "./vitest.unit-fast-paths.mjs";
|
||||
|
||||
export function createUtilsVitestConfig(env?: Record<string, string | undefined>) {
|
||||
return createScopedVitestConfig(["src/utils/**/*.test.ts"], {
|
||||
dir: "src",
|
||||
env,
|
||||
exclude: unitFastTestFiles,
|
||||
includeOpenClawRuntimeSetup: false,
|
||||
name: "utils",
|
||||
passWithNoTests: true,
|
||||
|
||||
Reference in New Issue
Block a user