mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-06 17:40:44 +00:00
test: reduce repeated test setup overhead
This commit is contained in:
@@ -1,30 +1,39 @@
|
||||
import { beforeAll, beforeEach, describe, expect, it, vi } from "vitest";
|
||||
import { beforeEach, describe, expect, it, vi } from "vitest";
|
||||
|
||||
vi.mock("./remote-http.js", () => ({
|
||||
withRemoteHttpResponse: vi.fn(),
|
||||
}));
|
||||
|
||||
let postJson: typeof import("./post-json.js").postJson;
|
||||
let withRemoteHttpResponse: typeof import("./remote-http.js").withRemoteHttpResponse;
|
||||
const { postJson } = await import("./post-json.js");
|
||||
const { withRemoteHttpResponse } = await import("./remote-http.js");
|
||||
const remoteHttpMock = vi.mocked(withRemoteHttpResponse);
|
||||
|
||||
function jsonResponse(payload: unknown, status = 200): Response {
|
||||
return {
|
||||
ok: status >= 200 && status < 300,
|
||||
status,
|
||||
json: async () => payload,
|
||||
text: async () => JSON.stringify(payload),
|
||||
} as Response;
|
||||
}
|
||||
|
||||
function textResponse(body: string, status: number): Response {
|
||||
return {
|
||||
ok: status >= 200 && status < 300,
|
||||
status,
|
||||
json: async () => JSON.parse(body) as unknown,
|
||||
text: async () => body,
|
||||
} as Response;
|
||||
}
|
||||
|
||||
describe("postJson", () => {
|
||||
let remoteHttpMock: ReturnType<typeof vi.mocked<typeof withRemoteHttpResponse>>;
|
||||
|
||||
beforeAll(async () => {
|
||||
({ postJson } = await import("./post-json.js"));
|
||||
({ withRemoteHttpResponse } = await import("./remote-http.js"));
|
||||
remoteHttpMock = vi.mocked(withRemoteHttpResponse);
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
vi.clearAllMocks();
|
||||
});
|
||||
|
||||
it("parses JSON payload on successful response", async () => {
|
||||
remoteHttpMock.mockImplementationOnce(async (params) => {
|
||||
return await params.onResponse(
|
||||
new Response(JSON.stringify({ data: [{ embedding: [1, 2] }] }), { status: 200 }),
|
||||
);
|
||||
return await params.onResponse(jsonResponse({ data: [{ embedding: [1, 2] }] }));
|
||||
});
|
||||
|
||||
const result = await postJson({
|
||||
@@ -40,7 +49,7 @@ describe("postJson", () => {
|
||||
|
||||
it("attaches status to thrown error when requested", async () => {
|
||||
remoteHttpMock.mockImplementationOnce(async (params) => {
|
||||
return await params.onResponse(new Response("bad gateway", { status: 502 }));
|
||||
return await params.onResponse(textResponse("bad gateway", 502));
|
||||
});
|
||||
|
||||
await expect(
|
||||
|
||||
@@ -6,14 +6,14 @@ vi.mock("./plugin-sdk/browser-maintenance.js", () => ({
|
||||
closeTrackedBrowserTabsForSessions,
|
||||
}));
|
||||
|
||||
const { cleanupBrowserSessionsForLifecycleEnd } = await import("./browser-lifecycle-cleanup.js");
|
||||
|
||||
describe("cleanupBrowserSessionsForLifecycleEnd", () => {
|
||||
beforeEach(() => {
|
||||
vi.clearAllMocks();
|
||||
});
|
||||
|
||||
it("normalizes session keys before closing browser sessions", async () => {
|
||||
const { cleanupBrowserSessionsForLifecycleEnd } =
|
||||
await import("./browser-lifecycle-cleanup.js");
|
||||
const onWarn = vi.fn();
|
||||
|
||||
await expect(
|
||||
@@ -30,8 +30,6 @@ describe("cleanupBrowserSessionsForLifecycleEnd", () => {
|
||||
});
|
||||
|
||||
it("swallows browser cleanup failures", async () => {
|
||||
const { cleanupBrowserSessionsForLifecycleEnd } =
|
||||
await import("./browser-lifecycle-cleanup.js");
|
||||
const onError = vi.fn();
|
||||
const error = new Error("cleanup failed");
|
||||
closeTrackedBrowserTabsForSessions.mockRejectedValueOnce(error);
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import fs from "node:fs";
|
||||
import { fileURLToPath } from "node:url";
|
||||
import { beforeAll, describe, expect, it } from "vitest";
|
||||
import { describe, expect, it } from "vitest";
|
||||
|
||||
type TranslationTree = {
|
||||
readonly [key: string]: string | TranslationTree | undefined;
|
||||
@@ -18,7 +18,17 @@ const describeWhenUiI18nPresent = fs.existsSync(fileURLToPath(registryModuleUrl)
|
||||
? describe
|
||||
: describe.skip;
|
||||
|
||||
let registry: LocaleRegistry;
|
||||
const registry =
|
||||
describeWhenUiI18nPresent === describe
|
||||
? ((await import("../../ui/src/i18n/lib/registry.ts")) as LocaleRegistry)
|
||||
: undefined;
|
||||
|
||||
function getRegistry(): LocaleRegistry {
|
||||
if (registry === undefined) {
|
||||
throw new Error("expected UI i18n registry to be present");
|
||||
}
|
||||
return registry;
|
||||
}
|
||||
|
||||
function getNestedTranslation(map: TranslationTree | null, ...path: string[]): string | undefined {
|
||||
let value: string | TranslationTree | undefined = map ?? undefined;
|
||||
@@ -32,12 +42,10 @@ function getNestedTranslation(map: TranslationTree | null, ...path: string[]): s
|
||||
}
|
||||
|
||||
describeWhenUiI18nPresent("ui i18n locale registry", () => {
|
||||
beforeAll(async () => {
|
||||
registry = (await import("../../ui/src/i18n/lib/registry.ts")) as LocaleRegistry;
|
||||
});
|
||||
|
||||
it("lists supported locales", () => {
|
||||
expect(registry.SUPPORTED_LOCALES).toEqual([
|
||||
const localeRegistry = getRegistry();
|
||||
|
||||
expect(localeRegistry.SUPPORTED_LOCALES).toEqual([
|
||||
"en",
|
||||
"zh-CN",
|
||||
"zh-TW",
|
||||
@@ -53,34 +61,37 @@ describeWhenUiI18nPresent("ui i18n locale registry", () => {
|
||||
"pl",
|
||||
"th",
|
||||
]);
|
||||
expect(registry.DEFAULT_LOCALE).toBe("en");
|
||||
expect(localeRegistry.DEFAULT_LOCALE).toBe("en");
|
||||
});
|
||||
|
||||
it("resolves browser locale fallbacks", () => {
|
||||
expect(registry.resolveNavigatorLocale("de-DE")).toBe("de");
|
||||
expect(registry.resolveNavigatorLocale("es-ES")).toBe("es");
|
||||
expect(registry.resolveNavigatorLocale("es-MX")).toBe("es");
|
||||
expect(registry.resolveNavigatorLocale("pt-PT")).toBe("pt-BR");
|
||||
expect(registry.resolveNavigatorLocale("zh-HK")).toBe("zh-TW");
|
||||
expect(registry.resolveNavigatorLocale("en-US")).toBe("en");
|
||||
expect(registry.resolveNavigatorLocale("ja-JP")).toBe("ja-JP");
|
||||
expect(registry.resolveNavigatorLocale("ko-KR")).toBe("ko");
|
||||
expect(registry.resolveNavigatorLocale("fr-CA")).toBe("fr");
|
||||
expect(registry.resolveNavigatorLocale("tr-TR")).toBe("tr");
|
||||
expect(registry.resolveNavigatorLocale("uk-UA")).toBe("uk");
|
||||
expect(registry.resolveNavigatorLocale("id-ID")).toBe("id");
|
||||
expect(registry.resolveNavigatorLocale("pl-PL")).toBe("pl");
|
||||
expect(registry.resolveNavigatorLocale("th-TH")).toBe("th");
|
||||
const localeRegistry = getRegistry();
|
||||
|
||||
expect(localeRegistry.resolveNavigatorLocale("de-DE")).toBe("de");
|
||||
expect(localeRegistry.resolveNavigatorLocale("es-ES")).toBe("es");
|
||||
expect(localeRegistry.resolveNavigatorLocale("es-MX")).toBe("es");
|
||||
expect(localeRegistry.resolveNavigatorLocale("pt-PT")).toBe("pt-BR");
|
||||
expect(localeRegistry.resolveNavigatorLocale("zh-HK")).toBe("zh-TW");
|
||||
expect(localeRegistry.resolveNavigatorLocale("en-US")).toBe("en");
|
||||
expect(localeRegistry.resolveNavigatorLocale("ja-JP")).toBe("ja-JP");
|
||||
expect(localeRegistry.resolveNavigatorLocale("ko-KR")).toBe("ko");
|
||||
expect(localeRegistry.resolveNavigatorLocale("fr-CA")).toBe("fr");
|
||||
expect(localeRegistry.resolveNavigatorLocale("tr-TR")).toBe("tr");
|
||||
expect(localeRegistry.resolveNavigatorLocale("uk-UA")).toBe("uk");
|
||||
expect(localeRegistry.resolveNavigatorLocale("id-ID")).toBe("id");
|
||||
expect(localeRegistry.resolveNavigatorLocale("pl-PL")).toBe("pl");
|
||||
expect(localeRegistry.resolveNavigatorLocale("th-TH")).toBe("th");
|
||||
});
|
||||
|
||||
it("loads lazy locale translations from the registry", async () => {
|
||||
const localeRegistry = getRegistry();
|
||||
const [de, es, ptBR, zhCN, th, en] = await Promise.all([
|
||||
registry.loadLazyLocaleTranslation("de"),
|
||||
registry.loadLazyLocaleTranslation("es"),
|
||||
registry.loadLazyLocaleTranslation("pt-BR"),
|
||||
registry.loadLazyLocaleTranslation("zh-CN"),
|
||||
registry.loadLazyLocaleTranslation("th"),
|
||||
registry.loadLazyLocaleTranslation("en"),
|
||||
localeRegistry.loadLazyLocaleTranslation("de"),
|
||||
localeRegistry.loadLazyLocaleTranslation("es"),
|
||||
localeRegistry.loadLazyLocaleTranslation("pt-BR"),
|
||||
localeRegistry.loadLazyLocaleTranslation("zh-CN"),
|
||||
localeRegistry.loadLazyLocaleTranslation("th"),
|
||||
localeRegistry.loadLazyLocaleTranslation("en"),
|
||||
]);
|
||||
|
||||
expect(getNestedTranslation(de, "common", "health")).toBe("Status");
|
||||
|
||||
@@ -5,16 +5,18 @@ import { afterEach, describe, expect, it } from "vitest";
|
||||
import { cleanupTempDirs, makeTempDir } from "../test/helpers/temp-dir.js";
|
||||
|
||||
const tempRoots: string[] = [];
|
||||
const installerPath = path.join(process.cwd(), "scripts", "install.sh");
|
||||
const installerSource = fs.readFileSync(installerPath, "utf-8");
|
||||
const versionHelperStart = installerSource.indexOf("load_install_version_helpers() {");
|
||||
const versionHelperEnd = installerSource.indexOf("\nis_gateway_daemon_loaded() {");
|
||||
|
||||
if (versionHelperStart < 0 || versionHelperEnd < 0) {
|
||||
throw new Error("install.sh version helper block not found");
|
||||
}
|
||||
|
||||
const versionHelperSource = installerSource.slice(versionHelperStart, versionHelperEnd);
|
||||
|
||||
function resolveInstallerVersionCases(params: { stdinCwd: string }): string[] {
|
||||
const installerPath = path.join(process.cwd(), "scripts", "install.sh");
|
||||
const installerSource = fs.readFileSync(installerPath, "utf-8");
|
||||
const versionHelperStart = installerSource.indexOf("load_install_version_helpers() {");
|
||||
const versionHelperEnd = installerSource.indexOf("\nis_gateway_daemon_loaded() {");
|
||||
if (versionHelperStart < 0 || versionHelperEnd < 0) {
|
||||
throw new Error("install.sh version helper block not found");
|
||||
}
|
||||
const versionHelperSource = installerSource.slice(versionHelperStart, versionHelperEnd);
|
||||
const output = execFileSync(
|
||||
"bash",
|
||||
[
|
||||
|
||||
@@ -2,7 +2,7 @@ import fsSync from "node:fs";
|
||||
import fs from "node:fs/promises";
|
||||
import os from "node:os";
|
||||
import path from "node:path";
|
||||
import { afterAll, beforeAll, beforeEach, describe, expect, it, vi } from "vitest";
|
||||
import { afterAll, beforeEach, describe, expect, it, vi } from "vitest";
|
||||
|
||||
vi.mock("../../media/mime.js", () => ({
|
||||
detectMime: async (opts: { filePath?: string }) => {
|
||||
@@ -30,17 +30,11 @@ import {
|
||||
type MemoryMultimodalSettings,
|
||||
} from "./multimodal.js";
|
||||
|
||||
let sharedTempRoot = "";
|
||||
const sharedTempRoot = fsSync.mkdtempSync(path.join(os.tmpdir(), "memory-host-sdk-tests-"));
|
||||
let sharedTempId = 0;
|
||||
|
||||
beforeAll(() => {
|
||||
sharedTempRoot = fsSync.mkdtempSync(path.join(os.tmpdir(), "memory-host-sdk-tests-"));
|
||||
});
|
||||
|
||||
afterAll(() => {
|
||||
if (sharedTempRoot) {
|
||||
fsSync.rmSync(sharedTempRoot, { recursive: true, force: true });
|
||||
}
|
||||
fsSync.rmSync(sharedTempRoot, { recursive: true, force: true });
|
||||
});
|
||||
|
||||
function setupTempDirLifecycle(prefix: string): () => string {
|
||||
|
||||
@@ -1,30 +1,39 @@
|
||||
import { beforeAll, beforeEach, describe, expect, it, vi } from "vitest";
|
||||
import { beforeEach, describe, expect, it, vi } from "vitest";
|
||||
|
||||
vi.mock("./remote-http.js", () => ({
|
||||
withRemoteHttpResponse: vi.fn(),
|
||||
}));
|
||||
|
||||
let postJson: typeof import("./post-json.js").postJson;
|
||||
let withRemoteHttpResponse: typeof import("./remote-http.js").withRemoteHttpResponse;
|
||||
const { postJson } = await import("./post-json.js");
|
||||
const { withRemoteHttpResponse } = await import("./remote-http.js");
|
||||
const remoteHttpMock = vi.mocked(withRemoteHttpResponse);
|
||||
|
||||
function jsonResponse(payload: unknown, status = 200): Response {
|
||||
return {
|
||||
ok: status >= 200 && status < 300,
|
||||
status,
|
||||
json: async () => payload,
|
||||
text: async () => JSON.stringify(payload),
|
||||
} as Response;
|
||||
}
|
||||
|
||||
function textResponse(body: string, status: number): Response {
|
||||
return {
|
||||
ok: status >= 200 && status < 300,
|
||||
status,
|
||||
json: async () => JSON.parse(body) as unknown,
|
||||
text: async () => body,
|
||||
} as Response;
|
||||
}
|
||||
|
||||
describe("postJson", () => {
|
||||
let remoteHttpMock: ReturnType<typeof vi.mocked<typeof withRemoteHttpResponse>>;
|
||||
|
||||
beforeAll(async () => {
|
||||
({ postJson } = await import("./post-json.js"));
|
||||
({ withRemoteHttpResponse } = await import("./remote-http.js"));
|
||||
remoteHttpMock = vi.mocked(withRemoteHttpResponse);
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
vi.clearAllMocks();
|
||||
});
|
||||
|
||||
it("parses JSON payload on successful response", async () => {
|
||||
remoteHttpMock.mockImplementationOnce(async (params) => {
|
||||
return await params.onResponse(
|
||||
new Response(JSON.stringify({ data: [{ embedding: [1, 2] }] }), { status: 200 }),
|
||||
);
|
||||
return await params.onResponse(jsonResponse({ data: [{ embedding: [1, 2] }] }));
|
||||
});
|
||||
|
||||
const result = await postJson({
|
||||
@@ -40,7 +49,7 @@ describe("postJson", () => {
|
||||
|
||||
it("attaches status to thrown error when requested", async () => {
|
||||
remoteHttpMock.mockImplementationOnce(async (params) => {
|
||||
return await params.onResponse(new Response("bad gateway", { status: 502 }));
|
||||
return await params.onResponse(textResponse("bad gateway", 502));
|
||||
});
|
||||
|
||||
await expect(
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest";
|
||||
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
|
||||
import type { SecretInput } from "../config/types.secrets.js";
|
||||
|
||||
vi.mock("../infra/device-bootstrap.js", () => ({
|
||||
@@ -8,9 +8,9 @@ vi.mock("../infra/device-bootstrap.js", () => ({
|
||||
})),
|
||||
}));
|
||||
|
||||
let encodePairingSetupCode: typeof import("./setup-code.js").encodePairingSetupCode;
|
||||
let resolvePairingSetupFromConfig: typeof import("./setup-code.js").resolvePairingSetupFromConfig;
|
||||
let issueDeviceBootstrapTokenMock: typeof import("../infra/device-bootstrap.js").issueDeviceBootstrapToken;
|
||||
const { encodePairingSetupCode, resolvePairingSetupFromConfig } = await import("./setup-code.js");
|
||||
const { issueDeviceBootstrapToken: issueDeviceBootstrapTokenMock } =
|
||||
await import("../infra/device-bootstrap.js");
|
||||
|
||||
describe("pairing setup code", () => {
|
||||
type ResolvedSetup = Awaited<ReturnType<typeof resolvePairingSetupFromConfig>>;
|
||||
@@ -185,12 +185,6 @@ describe("pairing setup code", () => {
|
||||
vi.stubEnv("OPENCLAW_GATEWAY_PORT", "");
|
||||
});
|
||||
|
||||
beforeAll(async () => {
|
||||
({ encodePairingSetupCode, resolvePairingSetupFromConfig } = await import("./setup-code.js"));
|
||||
({ issueDeviceBootstrapToken: issueDeviceBootstrapTokenMock } =
|
||||
await import("../infra/device-bootstrap.js"));
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
vi.mocked(issueDeviceBootstrapTokenMock).mockClear();
|
||||
});
|
||||
|
||||
@@ -2,7 +2,7 @@ import fsSync from "node:fs";
|
||||
import fs from "node:fs/promises";
|
||||
import os from "node:os";
|
||||
import path from "node:path";
|
||||
import { afterAll, afterEach, beforeAll, describe, expect, it, vi } from "vitest";
|
||||
import { afterAll, afterEach, describe, expect, it, vi } from "vitest";
|
||||
import {
|
||||
clearSkillScanCacheForTest,
|
||||
isScannable,
|
||||
@@ -16,17 +16,11 @@ import type { SkillScanOptions } from "./skill-scanner.js";
|
||||
// Helpers
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
let fixtureRoot = "";
|
||||
const fixtureRoot = fsSync.mkdtempSync(path.join(os.tmpdir(), "skill-scanner-test-"));
|
||||
let fixtureId = 0;
|
||||
|
||||
beforeAll(() => {
|
||||
fixtureRoot = fsSync.mkdtempSync(path.join(os.tmpdir(), "skill-scanner-test-"));
|
||||
});
|
||||
|
||||
afterAll(() => {
|
||||
if (fixtureRoot) {
|
||||
fsSync.rmSync(fixtureRoot, { recursive: true, force: true });
|
||||
}
|
||||
fsSync.rmSync(fixtureRoot, { recursive: true, force: true });
|
||||
});
|
||||
|
||||
function makeTmpDir(): string {
|
||||
|
||||
@@ -2,12 +2,12 @@ import fs from "node:fs";
|
||||
import os from "node:os";
|
||||
import path from "node:path";
|
||||
import type { Message, Usage } from "@mariozechner/pi-ai";
|
||||
import { afterAll, beforeAll, describe, expect, it } from "vitest";
|
||||
import { afterAll, describe, expect, it } from "vitest";
|
||||
import { exportTrajectoryBundle, resolveDefaultTrajectoryExportDir } from "./export.js";
|
||||
import { resolveTrajectoryPointerFilePath } from "./paths.js";
|
||||
import type { TrajectoryEvent } from "./types.js";
|
||||
|
||||
let tempRoot = "";
|
||||
const tempRoot = fs.mkdtempSync(path.join(os.tmpdir(), "openclaw-trajectory-"));
|
||||
let tempDirId = 0;
|
||||
|
||||
function makeTempDir(): string {
|
||||
@@ -180,14 +180,8 @@ function writeToolCallSessionFile(sessionFile: string): void {
|
||||
);
|
||||
}
|
||||
|
||||
beforeAll(() => {
|
||||
tempRoot = fs.mkdtempSync(path.join(os.tmpdir(), "openclaw-trajectory-"));
|
||||
});
|
||||
|
||||
afterAll(() => {
|
||||
if (tempRoot) {
|
||||
fs.rmSync(tempRoot, { recursive: true, force: true });
|
||||
}
|
||||
fs.rmSync(tempRoot, { recursive: true, force: true });
|
||||
});
|
||||
|
||||
describe("exportTrajectoryBundle", () => {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { beforeAll, beforeEach, describe, expect, it, vi } from "vitest";
|
||||
import { beforeEach, describe, expect, it, vi } from "vitest";
|
||||
|
||||
const loadBundledPluginPublicSurfaceModuleSync = vi.hoisted(() => vi.fn());
|
||||
const loadActivatedBundledPluginPublicSurfaceModuleSync = vi.hoisted(() => vi.fn());
|
||||
@@ -31,13 +31,9 @@ vi.mock("../plugin-sdk/facade-runtime.js", () => ({
|
||||
loadBundledPluginPublicSurfaceModuleSync,
|
||||
}));
|
||||
|
||||
const tts = await import("./tts.js");
|
||||
|
||||
describe("tts runtime facade", () => {
|
||||
let tts: typeof import("./tts.js");
|
||||
|
||||
beforeAll(async () => {
|
||||
tts = await import("./tts.js");
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
loadActivatedBundledPluginPublicSurfaceModuleSync.mockReset();
|
||||
loadBundledPluginPublicSurfaceModuleSync.mockReset();
|
||||
|
||||
Reference in New Issue
Block a user