mirror of
https://github.com/moltbot/moltbot.git
synced 2026-04-23 14:45:46 +00:00
perf: route targeted tests to scoped vitest configs
This commit is contained in:
@@ -2,10 +2,17 @@ import fs from "node:fs";
|
||||
import os from "node:os";
|
||||
import path from "node:path";
|
||||
import { isChannelSurfaceTestFile } from "../vitest.channel-paths.mjs";
|
||||
import { isBoundaryTestFile } from "../vitest.unit-paths.mjs";
|
||||
|
||||
const DEFAULT_VITEST_CONFIG = "vitest.config.ts";
|
||||
const DEFAULT_VITEST_CONFIG = "vitest.unit.config.ts";
|
||||
const AGENTS_VITEST_CONFIG = "vitest.agents.config.ts";
|
||||
const AUTO_REPLY_VITEST_CONFIG = "vitest.auto-reply.config.ts";
|
||||
const BOUNDARY_VITEST_CONFIG = "vitest.boundary.config.ts";
|
||||
const CHANNEL_VITEST_CONFIG = "vitest.channels.config.ts";
|
||||
const COMMANDS_VITEST_CONFIG = "vitest.commands.config.ts";
|
||||
const E2E_VITEST_CONFIG = "vitest.e2e.config.ts";
|
||||
const EXTENSIONS_VITEST_CONFIG = "vitest.extensions.config.ts";
|
||||
const GATEWAY_VITEST_CONFIG = "vitest.gateway.config.ts";
|
||||
const INCLUDE_FILE_ENV_KEY = "OPENCLAW_VITEST_INCLUDE_FILE";
|
||||
|
||||
function normalizePathPattern(value) {
|
||||
@@ -16,6 +23,14 @@ function isExistingPathTarget(arg, cwd) {
|
||||
return fs.existsSync(path.resolve(cwd, arg));
|
||||
}
|
||||
|
||||
function isExistingFileTarget(arg, cwd) {
|
||||
try {
|
||||
return fs.statSync(path.resolve(cwd, arg)).isFile();
|
||||
} catch {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
function isGlobTarget(arg) {
|
||||
return /[*?[\]{}]/u.test(arg);
|
||||
}
|
||||
@@ -44,17 +59,39 @@ function toScopedIncludePattern(arg, cwd) {
|
||||
if (isGlobTarget(relative) || isFileLikeTarget(relative)) {
|
||||
return relative;
|
||||
}
|
||||
if (isExistingFileTarget(arg, cwd)) {
|
||||
const directory = normalizePathPattern(path.posix.dirname(relative));
|
||||
return directory === "." ? "**/*.test.ts" : `${directory}/**/*.test.ts`;
|
||||
}
|
||||
return `${relative.replace(/\/+$/u, "")}/**/*.test.ts`;
|
||||
}
|
||||
|
||||
function classifyTarget(arg, cwd) {
|
||||
const relative = toRepoRelativeTarget(arg, cwd);
|
||||
if (relative.endsWith(".e2e.test.ts")) {
|
||||
return "e2e";
|
||||
}
|
||||
if (relative.startsWith("extensions/")) {
|
||||
return isChannelSurfaceTestFile(relative) ? "channel" : "extension";
|
||||
}
|
||||
if (isChannelSurfaceTestFile(relative)) {
|
||||
return "channel";
|
||||
}
|
||||
if (isBoundaryTestFile(relative)) {
|
||||
return "boundary";
|
||||
}
|
||||
if (relative.startsWith("src/gateway/")) {
|
||||
return "gateway";
|
||||
}
|
||||
if (relative.startsWith("src/commands/")) {
|
||||
return "command";
|
||||
}
|
||||
if (relative.startsWith("src/auto-reply/")) {
|
||||
return "autoReply";
|
||||
}
|
||||
if (relative.startsWith("src/agents/")) {
|
||||
return "agent";
|
||||
}
|
||||
return "default";
|
||||
}
|
||||
|
||||
@@ -119,7 +156,17 @@ export function buildVitestRunPlans(args, cwd = process.cwd()) {
|
||||
}
|
||||
|
||||
const nonTargetArgs = forwardedArgs.filter((arg) => !targetArgs.includes(arg));
|
||||
const orderedKinds = ["default", "channel", "extension"];
|
||||
const orderedKinds = [
|
||||
"default",
|
||||
"boundary",
|
||||
"gateway",
|
||||
"command",
|
||||
"autoReply",
|
||||
"agent",
|
||||
"e2e",
|
||||
"channel",
|
||||
"extension",
|
||||
];
|
||||
const plans = [];
|
||||
for (const kind of orderedKinds) {
|
||||
const grouped = groupedTargets.get(kind);
|
||||
@@ -127,16 +174,28 @@ export function buildVitestRunPlans(args, cwd = process.cwd()) {
|
||||
continue;
|
||||
}
|
||||
const config =
|
||||
kind === "channel"
|
||||
? CHANNEL_VITEST_CONFIG
|
||||
: kind === "extension"
|
||||
? EXTENSIONS_VITEST_CONFIG
|
||||
: DEFAULT_VITEST_CONFIG;
|
||||
kind === "boundary"
|
||||
? BOUNDARY_VITEST_CONFIG
|
||||
: kind === "gateway"
|
||||
? GATEWAY_VITEST_CONFIG
|
||||
: kind === "command"
|
||||
? COMMANDS_VITEST_CONFIG
|
||||
: kind === "autoReply"
|
||||
? AUTO_REPLY_VITEST_CONFIG
|
||||
: kind === "agent"
|
||||
? AGENTS_VITEST_CONFIG
|
||||
: kind === "e2e"
|
||||
? E2E_VITEST_CONFIG
|
||||
: kind === "channel"
|
||||
? CHANNEL_VITEST_CONFIG
|
||||
: kind === "extension"
|
||||
? EXTENSIONS_VITEST_CONFIG
|
||||
: DEFAULT_VITEST_CONFIG;
|
||||
const includePatterns =
|
||||
kind === "default"
|
||||
kind === "default" || kind === "e2e"
|
||||
? null
|
||||
: grouped.map((targetArg) => toScopedIncludePattern(targetArg, cwd));
|
||||
const scopedTargetArgs = kind === "default" ? grouped : [];
|
||||
const scopedTargetArgs = kind === "default" || kind === "e2e" ? grouped : [];
|
||||
plans.push({
|
||||
config,
|
||||
forwardedArgs: [...nonTargetArgs, ...scopedTargetArgs],
|
||||
|
||||
@@ -51,7 +51,7 @@ describe("test-projects args", () => {
|
||||
"exec",
|
||||
"vitest",
|
||||
"--config",
|
||||
"vitest.config.ts",
|
||||
"vitest.unit.config.ts",
|
||||
"src/foo.test.ts",
|
||||
]);
|
||||
});
|
||||
@@ -62,11 +62,88 @@ describe("test-projects args", () => {
|
||||
"vitest",
|
||||
"run",
|
||||
"--config",
|
||||
"vitest.config.ts",
|
||||
"vitest.unit.config.ts",
|
||||
"src/foo.test.ts",
|
||||
]);
|
||||
});
|
||||
|
||||
it("routes boundary targets to the boundary config", () => {
|
||||
expect(buildVitestRunPlans(["src/infra/openclaw-root.test.ts"])).toEqual([
|
||||
{
|
||||
config: "vitest.boundary.config.ts",
|
||||
forwardedArgs: [],
|
||||
includePatterns: ["src/infra/openclaw-root.test.ts"],
|
||||
watchMode: false,
|
||||
},
|
||||
]);
|
||||
});
|
||||
|
||||
it("routes command targets to the commands config", () => {
|
||||
expect(buildVitestRunPlans(["src/commands/status.summary.test.ts"])).toEqual([
|
||||
{
|
||||
config: "vitest.commands.config.ts",
|
||||
forwardedArgs: [],
|
||||
includePatterns: ["src/commands/status.summary.test.ts"],
|
||||
watchMode: false,
|
||||
},
|
||||
]);
|
||||
});
|
||||
|
||||
it("routes auto-reply targets to the auto-reply config", () => {
|
||||
expect(buildVitestRunPlans(["src/auto-reply/reply/get-reply.message-hooks.test.ts"])).toEqual([
|
||||
{
|
||||
config: "vitest.auto-reply.config.ts",
|
||||
forwardedArgs: [],
|
||||
includePatterns: ["src/auto-reply/reply/get-reply.message-hooks.test.ts"],
|
||||
watchMode: false,
|
||||
},
|
||||
]);
|
||||
});
|
||||
|
||||
it("routes agents targets to the agents config", () => {
|
||||
expect(buildVitestRunPlans(["src/agents/tools/image-tool.test.ts"])).toEqual([
|
||||
{
|
||||
config: "vitest.agents.config.ts",
|
||||
forwardedArgs: [],
|
||||
includePatterns: ["src/agents/tools/image-tool.test.ts"],
|
||||
watchMode: false,
|
||||
},
|
||||
]);
|
||||
});
|
||||
|
||||
it("routes gateway targets to the gateway config", () => {
|
||||
expect(buildVitestRunPlans(["src/gateway/call.test.ts"])).toEqual([
|
||||
{
|
||||
config: "vitest.gateway.config.ts",
|
||||
forwardedArgs: [],
|
||||
includePatterns: ["src/gateway/call.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([
|
||||
{
|
||||
config: "vitest.gateway.config.ts",
|
||||
forwardedArgs: [],
|
||||
includePatterns: ["src/gateway/**/*.test.ts"],
|
||||
watchMode: false,
|
||||
},
|
||||
]);
|
||||
});
|
||||
|
||||
it("routes e2e targets straight to the e2e config", () => {
|
||||
expect(buildVitestRunPlans(["src/commands/models.set.e2e.test.ts"])).toEqual([
|
||||
{
|
||||
config: "vitest.e2e.config.ts",
|
||||
forwardedArgs: ["src/commands/models.set.e2e.test.ts"],
|
||||
includePatterns: null,
|
||||
watchMode: false,
|
||||
},
|
||||
]);
|
||||
});
|
||||
|
||||
it("routes direct channel extension file targets to the channels config", () => {
|
||||
expect(
|
||||
buildVitestRunPlans(["extensions/discord/src/monitor/message-handler.preflight.test.ts"]),
|
||||
@@ -101,7 +178,7 @@ describe("test-projects args", () => {
|
||||
]),
|
||||
).toEqual([
|
||||
{
|
||||
config: "vitest.config.ts",
|
||||
config: "vitest.unit.config.ts",
|
||||
forwardedArgs: ["-t", "mention", "src/config/config-misc.test.ts"],
|
||||
includePatterns: null,
|
||||
watchMode: false,
|
||||
|
||||
@@ -2,7 +2,10 @@ import fs from "node:fs";
|
||||
import os from "node:os";
|
||||
import path from "node:path";
|
||||
import { describe, expect, it } from "vitest";
|
||||
import { createAgentsVitestConfig } from "../vitest.agents.config.ts";
|
||||
import { createAutoReplyVitestConfig } from "../vitest.auto-reply.config.ts";
|
||||
import { createChannelsVitestConfig } from "../vitest.channels.config.ts";
|
||||
import { createCommandsVitestConfig } from "../vitest.commands.config.ts";
|
||||
import { createExtensionsVitestConfig } from "../vitest.extensions.config.ts";
|
||||
import { createGatewayVitestConfig } from "../vitest.gateway.config.ts";
|
||||
import { createScopedVitestConfig, resolveVitestIsolation } from "../vitest.scoped-config.ts";
|
||||
@@ -64,6 +67,9 @@ describe("scoped vitest configs", () => {
|
||||
const defaultChannelsConfig = createChannelsVitestConfig({});
|
||||
const defaultExtensionsConfig = createExtensionsVitestConfig({});
|
||||
const defaultGatewayConfig = createGatewayVitestConfig({});
|
||||
const defaultCommandsConfig = createCommandsVitestConfig({});
|
||||
const defaultAutoReplyConfig = createAutoReplyVitestConfig({});
|
||||
const defaultAgentsConfig = createAgentsVitestConfig({});
|
||||
|
||||
it("defaults channel tests to non-isolated mode", () => {
|
||||
expect(defaultChannelsConfig.test?.isolate).toBe(false);
|
||||
@@ -128,4 +134,19 @@ describe("scoped vitest configs", () => {
|
||||
expect(defaultGatewayConfig.test?.dir).toBe("src/gateway");
|
||||
expect(defaultGatewayConfig.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"]);
|
||||
});
|
||||
|
||||
it("normalizes auto-reply include patterns relative to the scoped dir", () => {
|
||||
expect(defaultAutoReplyConfig.test?.dir).toBe("src/auto-reply");
|
||||
expect(defaultAutoReplyConfig.test?.include).toEqual(["**/*.test.ts"]);
|
||||
});
|
||||
|
||||
it("normalizes agents include patterns relative to the scoped dir", () => {
|
||||
expect(defaultAgentsConfig.test?.dir).toBe("src/agents");
|
||||
expect(defaultAgentsConfig.test?.include).toEqual(["**/*.test.ts"]);
|
||||
});
|
||||
});
|
||||
|
||||
10
vitest.agents.config.ts
Normal file
10
vitest.agents.config.ts
Normal file
@@ -0,0 +1,10 @@
|
||||
import { createScopedVitestConfig } from "./vitest.scoped-config.ts";
|
||||
|
||||
export function createAgentsVitestConfig(env?: Record<string, string | undefined>) {
|
||||
return createScopedVitestConfig(["src/agents/**/*.test.ts"], {
|
||||
dir: "src/agents",
|
||||
env,
|
||||
});
|
||||
}
|
||||
|
||||
export default createAgentsVitestConfig();
|
||||
10
vitest.auto-reply.config.ts
Normal file
10
vitest.auto-reply.config.ts
Normal file
@@ -0,0 +1,10 @@
|
||||
import { createScopedVitestConfig } from "./vitest.scoped-config.ts";
|
||||
|
||||
export function createAutoReplyVitestConfig(env?: Record<string, string | undefined>) {
|
||||
return createScopedVitestConfig(["src/auto-reply/**/*.test.ts"], {
|
||||
dir: "src/auto-reply",
|
||||
env,
|
||||
});
|
||||
}
|
||||
|
||||
export default createAutoReplyVitestConfig();
|
||||
10
vitest.commands.config.ts
Normal file
10
vitest.commands.config.ts
Normal file
@@ -0,0 +1,10 @@
|
||||
import { createScopedVitestConfig } from "./vitest.scoped-config.ts";
|
||||
|
||||
export function createCommandsVitestConfig(env?: Record<string, string | undefined>) {
|
||||
return createScopedVitestConfig(["src/commands/**/*.test.ts"], {
|
||||
dir: "src/commands",
|
||||
env,
|
||||
});
|
||||
}
|
||||
|
||||
export default createCommandsVitestConfig();
|
||||
Reference in New Issue
Block a user