mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-06 05:50:43 +00:00
test(vitest): cut unit-ui startup overhead
This commit is contained in:
@@ -2,7 +2,7 @@ import {
|
||||
collectBroadUnitFastTestCandidates,
|
||||
collectUnitFastTestFileAnalysis,
|
||||
collectUnitFastTestCandidates,
|
||||
unitFastTestFiles,
|
||||
getUnitFastTestFiles,
|
||||
} from "../test/vitest/vitest.unit-fast-paths.mjs";
|
||||
|
||||
const args = new Set(process.argv.slice(2));
|
||||
@@ -16,6 +16,7 @@ const candidateCount =
|
||||
scope === "broad"
|
||||
? collectBroadUnitFastTestCandidates(process.cwd()).length
|
||||
: collectUnitFastTestCandidates(process.cwd()).length;
|
||||
const unitFastTestFiles = getUnitFastTestFiles();
|
||||
const unitFastCount = analysis.filter((entry) => entry.unitFast).length;
|
||||
|
||||
for (const entry of rejected) {
|
||||
|
||||
@@ -11,6 +11,7 @@ import { createPluginSdkLightVitestConfig } from "./vitest/vitest.plugin-sdk-lig
|
||||
import { sharedVitestConfig } from "./vitest/vitest.shared.config.ts";
|
||||
import { createUiVitestConfig } from "./vitest/vitest.ui.config.ts";
|
||||
import { createUnitFastVitestConfig } from "./vitest/vitest.unit-fast.config.ts";
|
||||
import unitUiConfig from "./vitest/vitest.unit-ui.config.ts";
|
||||
import { createUnitVitestConfig } from "./vitest/vitest.unit.config.ts";
|
||||
|
||||
describe("projects vitest config", () => {
|
||||
@@ -51,6 +52,15 @@ describe("projects vitest config", () => {
|
||||
expect(config.test.deps?.optimizer?.web?.enabled).toBe(true);
|
||||
});
|
||||
|
||||
it("keeps the unit-ui shard aligned with the isolated jsdom setup", () => {
|
||||
expect(unitUiConfig.test?.environment).toBe("jsdom");
|
||||
expect(unitUiConfig.test?.isolate).toBe(true);
|
||||
expect(unitUiConfig.test?.runner).toBeUndefined();
|
||||
const setupFiles = normalizeConfigPaths(unitUiConfig.test?.setupFiles);
|
||||
expect(setupFiles).not.toContain("test/setup-openclaw-runtime.ts");
|
||||
expect(setupFiles).toContain("ui/src/test-helpers/lit-warnings.setup.ts");
|
||||
});
|
||||
|
||||
it("keeps the unit lane on the non-isolated runner by default", () => {
|
||||
const config = createUnitVitestConfig();
|
||||
expect(config.test.isolate).toBe(false);
|
||||
|
||||
@@ -281,6 +281,14 @@ describe("scoped vitest configs", () => {
|
||||
]);
|
||||
});
|
||||
|
||||
it("keeps the ui lane off both the openclaw runtime setup and unit-fast excludes", () => {
|
||||
expect(normalizeConfigPaths(defaultUiConfig.test?.setupFiles)).toEqual([
|
||||
"test/setup.ts",
|
||||
"ui/src/test-helpers/lit-warnings.setup.ts",
|
||||
]);
|
||||
expect(defaultUiConfig.test?.exclude).not.toContain("chat/slash-command-executor.node.test.ts");
|
||||
});
|
||||
|
||||
it("defaults channel tests to threads with the non-isolated runner", () => {
|
||||
expect(defaultChannelsConfig.test?.isolate).toBe(false);
|
||||
expect(defaultChannelsConfig.test?.pool).toBe("threads");
|
||||
|
||||
@@ -6,8 +6,8 @@ import {
|
||||
collectBroadUnitFastTestCandidates,
|
||||
collectUnitFastTestCandidates,
|
||||
collectUnitFastTestFileAnalysis,
|
||||
getUnitFastTestFiles,
|
||||
isUnitFastTestFile,
|
||||
unitFastTestFiles,
|
||||
resolveUnitFastTestIncludePattern,
|
||||
} from "./vitest/vitest.unit-fast-paths.mjs";
|
||||
import { createUnitFastVitestConfig } from "./vitest/vitest.unit-fast.config.ts";
|
||||
@@ -63,6 +63,7 @@ describe("unit-fast vitest lane", () => {
|
||||
const currentCandidates = collectUnitFastTestCandidates();
|
||||
const broadCandidates = collectBroadUnitFastTestCandidates();
|
||||
const broadAnalysis = collectUnitFastTestFileAnalysis(process.cwd(), { scope: "broad" });
|
||||
const unitFastTestFiles = getUnitFastTestFiles();
|
||||
|
||||
expect(currentCandidates.length).toBeGreaterThanOrEqual(unitFastTestFiles.length);
|
||||
expect(broadCandidates.length).toBeGreaterThan(currentCandidates.length);
|
||||
@@ -74,6 +75,7 @@ describe("unit-fast vitest lane", () => {
|
||||
it("excludes unit-fast files from the older light lanes so full runs do not duplicate them", () => {
|
||||
const pluginSdkLight = createPluginSdkLightVitestConfig({});
|
||||
const commandsLight = createCommandsLightVitestConfig({});
|
||||
const unitFastTestFiles = getUnitFastTestFiles();
|
||||
|
||||
expect(unitFastTestFiles).toContain("src/plugin-sdk/provider-entry.test.ts");
|
||||
expect(pluginSdkLight.test?.exclude).toContain("plugin-sdk/provider-entry.test.ts");
|
||||
|
||||
@@ -1,12 +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";
|
||||
import { getUnitFastTestFiles } from "./vitest.unit-fast-paths.mjs";
|
||||
|
||||
export function createCommandsLightVitestConfig(env?: Record<string, string | undefined>) {
|
||||
return createScopedVitestConfig(commandsLightTestFiles, {
|
||||
dir: "src/commands",
|
||||
env,
|
||||
exclude: unitFastTestFiles,
|
||||
exclude: getUnitFastTestFiles(),
|
||||
includeOpenClawRuntimeSetup: false,
|
||||
name: "commands-light",
|
||||
passWithNoTests: true,
|
||||
|
||||
@@ -1,12 +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";
|
||||
import { getUnitFastTestFiles } from "./vitest.unit-fast-paths.mjs";
|
||||
|
||||
export function createPluginSdkLightVitestConfig(env?: Record<string, string | undefined>) {
|
||||
return createScopedVitestConfig(pluginSdkLightTestFiles, {
|
||||
dir: "src",
|
||||
env,
|
||||
exclude: unitFastTestFiles,
|
||||
exclude: getUnitFastTestFiles(),
|
||||
includeOpenClawRuntimeSetup: false,
|
||||
name: "plugin-sdk-light",
|
||||
passWithNoTests: true,
|
||||
|
||||
@@ -7,7 +7,7 @@ import {
|
||||
resolveRepoRootPath,
|
||||
sharedVitestConfig,
|
||||
} from "./vitest.shared.config.ts";
|
||||
import { unitFastTestFiles } from "./vitest.unit-fast-paths.mjs";
|
||||
import { getUnitFastTestFiles } from "./vitest.unit-fast-paths.mjs";
|
||||
|
||||
function normalizePathPattern(value: string): string {
|
||||
return value.replaceAll("\\", "/");
|
||||
@@ -144,6 +144,7 @@ export function createScopedVitestConfig(
|
||||
fileParallelism?: boolean;
|
||||
pool?: "forks" | "threads";
|
||||
passWithNoTests?: boolean;
|
||||
excludeUnitFastTests?: boolean;
|
||||
setupFiles?: string[];
|
||||
useNonIsolatedRunner?: boolean;
|
||||
},
|
||||
@@ -155,8 +156,10 @@ export function createScopedVitestConfig(
|
||||
const env = options?.env;
|
||||
const includeFromEnv = loadPatternListFromEnv("OPENCLAW_VITEST_INCLUDE_FILE", env);
|
||||
const cliInclude = narrowIncludePatternsForCli(include, options?.argv);
|
||||
const unitFastExcludePatterns =
|
||||
options?.excludeUnitFastTests === false ? [] : getUnitFastTestFiles();
|
||||
const exclude = relativizeScopedPatterns(
|
||||
[...(baseTest.exclude ?? []), ...unitFastTestFiles, ...(options?.exclude ?? [])],
|
||||
[...(baseTest.exclude ?? []), ...unitFastExcludePatterns, ...(options?.exclude ?? [])],
|
||||
scopedDir,
|
||||
);
|
||||
const isolate = options?.isolate ?? resolveVitestIsolation(options?.env);
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
import { createScopedVitestConfig } from "./vitest.scoped-config.ts";
|
||||
import { unitFastTestFiles } from "./vitest.unit-fast-paths.mjs";
|
||||
import { getUnitFastTestFiles } 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,
|
||||
exclude: getUnitFastTestFiles(),
|
||||
includeOpenClawRuntimeSetup: false,
|
||||
name: "shared-core",
|
||||
passWithNoTests: true,
|
||||
|
||||
@@ -1,15 +1,31 @@
|
||||
import { createScopedVitestConfig } from "./vitest.scoped-config.ts";
|
||||
import { jsdomOptimizedDeps } from "./vitest.shared.config.ts";
|
||||
|
||||
export function createUiVitestConfig(env?: Record<string, string | undefined>) {
|
||||
return createScopedVitestConfig(["ui/src/ui/**/*.test.ts"], {
|
||||
export const unitUiIncludePatterns = [
|
||||
"ui/src/ui/app-chat.test.ts",
|
||||
"ui/src/ui/chat/**/*.test.ts",
|
||||
"ui/src/ui/views/agents-utils.test.ts",
|
||||
"ui/src/ui/views/channels.test.ts",
|
||||
"ui/src/ui/views/chat.test.ts",
|
||||
"ui/src/ui/views/dreams.test.ts",
|
||||
"ui/src/ui/views/usage-render-details.test.ts",
|
||||
"ui/src/ui/controllers/agents.test.ts",
|
||||
"ui/src/ui/controllers/chat.test.ts",
|
||||
];
|
||||
|
||||
export function createUiVitestConfig(
|
||||
env?: Record<string, string | undefined>,
|
||||
options?: { includePatterns?: string[]; name?: string },
|
||||
) {
|
||||
return createScopedVitestConfig(options?.includePatterns ?? ["ui/src/ui/**/*.test.ts"], {
|
||||
deps: jsdomOptimizedDeps,
|
||||
dir: "ui/src/ui",
|
||||
environment: "jsdom",
|
||||
env,
|
||||
excludeUnitFastTests: false,
|
||||
includeOpenClawRuntimeSetup: false,
|
||||
isolate: true,
|
||||
name: "ui",
|
||||
name: options?.name ?? "ui",
|
||||
setupFiles: ["ui/src/test-helpers/lit-warnings.setup.ts"],
|
||||
});
|
||||
}
|
||||
|
||||
@@ -214,24 +214,49 @@ export function collectUnitFastTestFileAnalysis(cwd = process.cwd(), options = {
|
||||
});
|
||||
}
|
||||
|
||||
export const unitFastTestFiles = collectUnitFastTestFileAnalysis()
|
||||
.filter((entry) => entry.unitFast)
|
||||
.map((entry) => entry.file);
|
||||
let cachedUnitFastTestFiles = null;
|
||||
let cachedUnitFastTestFileSet = null;
|
||||
let cachedSourceToUnitFastTestFile = null;
|
||||
|
||||
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 getUnitFastTestFiles() {
|
||||
if (cachedUnitFastTestFiles !== null) {
|
||||
return cachedUnitFastTestFiles;
|
||||
}
|
||||
cachedUnitFastTestFiles = collectUnitFastTestFileAnalysis()
|
||||
.filter((entry) => entry.unitFast)
|
||||
.map((entry) => entry.file);
|
||||
return cachedUnitFastTestFiles;
|
||||
}
|
||||
|
||||
function getUnitFastTestFileSet() {
|
||||
if (cachedUnitFastTestFileSet !== null) {
|
||||
return cachedUnitFastTestFileSet;
|
||||
}
|
||||
cachedUnitFastTestFileSet = new Set(getUnitFastTestFiles());
|
||||
return cachedUnitFastTestFileSet;
|
||||
}
|
||||
|
||||
function getSourceToUnitFastTestFile() {
|
||||
if (cachedSourceToUnitFastTestFile !== null) {
|
||||
return cachedSourceToUnitFastTestFile;
|
||||
}
|
||||
const unitFastTestFileSet = getUnitFastTestFileSet();
|
||||
cachedSourceToUnitFastTestFile = new Map(
|
||||
[...pluginSdkLightSourceFiles, ...commandsLightSourceFiles].flatMap((sourceFile) => {
|
||||
const testFile = sourceFile.replace(/\.ts$/u, ".test.ts");
|
||||
return unitFastTestFileSet.has(testFile) ? [[sourceFile, testFile]] : [];
|
||||
}),
|
||||
);
|
||||
return cachedSourceToUnitFastTestFile;
|
||||
}
|
||||
|
||||
export function isUnitFastTestFile(file) {
|
||||
return unitFastTestFileSet.has(normalizeRepoPath(file));
|
||||
return getUnitFastTestFileSet().has(normalizeRepoPath(file));
|
||||
}
|
||||
|
||||
export function resolveUnitFastTestIncludePattern(file) {
|
||||
const normalized = normalizeRepoPath(file);
|
||||
const unitFastTestFileSet = getUnitFastTestFileSet();
|
||||
if (unitFastTestFileSet.has(normalized)) {
|
||||
return normalized;
|
||||
}
|
||||
@@ -239,5 +264,5 @@ export function resolveUnitFastTestIncludePattern(file) {
|
||||
if (unitFastTestFileSet.has(siblingTestFile)) {
|
||||
return siblingTestFile;
|
||||
}
|
||||
return sourceToUnitFastTestFile.get(normalized) ?? null;
|
||||
return getSourceToUnitFastTestFile().get(normalized) ?? null;
|
||||
}
|
||||
|
||||
@@ -1,7 +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";
|
||||
import { getUnitFastTestFiles } from "./vitest.unit-fast-paths.mjs";
|
||||
|
||||
export function createUnitFastVitestConfig(
|
||||
env: Record<string, string | undefined> = process.env,
|
||||
@@ -9,6 +9,7 @@ export function createUnitFastVitestConfig(
|
||||
) {
|
||||
const sharedTest = sharedVitestConfig.test ?? {};
|
||||
const includeFromEnv = loadPatternListFromEnv("OPENCLAW_VITEST_INCLUDE_FILE", env);
|
||||
const unitFastTestFiles = getUnitFastTestFiles();
|
||||
const cliInclude = narrowIncludePatternsForCli(unitFastTestFiles, options.argv);
|
||||
|
||||
return defineConfig({
|
||||
|
||||
@@ -1,16 +1,6 @@
|
||||
import { createUnitVitestConfigWithOptions } from "./vitest.unit.config.ts";
|
||||
import { createUiVitestConfig, unitUiIncludePatterns } from "./vitest.ui.config.ts";
|
||||
|
||||
export default createUnitVitestConfigWithOptions(process.env, {
|
||||
export default createUiVitestConfig(process.env, {
|
||||
includePatterns: unitUiIncludePatterns,
|
||||
name: "unit-ui",
|
||||
includePatterns: [
|
||||
"ui/src/ui/app-chat.test.ts",
|
||||
"ui/src/ui/chat/**/*.test.ts",
|
||||
"ui/src/ui/views/agents-utils.test.ts",
|
||||
"ui/src/ui/views/channels.test.ts",
|
||||
"ui/src/ui/views/chat.test.ts",
|
||||
"ui/src/ui/views/dreams.test.ts",
|
||||
"ui/src/ui/views/usage-render-details.test.ts",
|
||||
"ui/src/ui/controllers/agents.test.ts",
|
||||
"ui/src/ui/controllers/chat.test.ts",
|
||||
],
|
||||
});
|
||||
|
||||
@@ -6,7 +6,7 @@ import {
|
||||
resolveRepoRootPath,
|
||||
sharedVitestConfig,
|
||||
} from "./vitest.shared.config.ts";
|
||||
import { unitFastTestFiles } from "./vitest.unit-fast-paths.mjs";
|
||||
import { getUnitFastTestFiles } from "./vitest.unit-fast-paths.mjs";
|
||||
import {
|
||||
isBundledPluginDependentUnitTestFile,
|
||||
unitTestAdditionalExcludePatterns,
|
||||
@@ -38,6 +38,7 @@ export function createUnitVitestConfigWithOptions(
|
||||
} = {},
|
||||
) {
|
||||
const isolate = resolveVitestIsolation(env);
|
||||
const unitFastTestFiles = getUnitFastTestFiles();
|
||||
const defaultIncludePatterns = options.includePatterns ?? unitTestIncludePatterns;
|
||||
const cliIncludePatterns = narrowIncludePatternsForCli(defaultIncludePatterns, options.argv);
|
||||
const protectedIncludeFiles = new Set(
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
import { createScopedVitestConfig } from "./vitest.scoped-config.ts";
|
||||
import { unitFastTestFiles } from "./vitest.unit-fast-paths.mjs";
|
||||
import { getUnitFastTestFiles } 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,
|
||||
exclude: getUnitFastTestFiles(),
|
||||
includeOpenClawRuntimeSetup: false,
|
||||
name: "utils",
|
||||
passWithNoTests: true,
|
||||
|
||||
Reference in New Issue
Block a user