test: speed up changed unit checks

This commit is contained in:
Peter Steinberger
2026-04-25 09:27:50 +01:00
parent 9ad14f3639
commit 8503935a21
4 changed files with 63 additions and 92 deletions

View File

@@ -1,5 +1,5 @@
import { describe, expect, test } from "vitest";
import { withTempDir } from "../test-helpers/temp-dir.js";
import { afterAll, beforeAll, describe, expect, test } from "vitest";
import { createSuiteTempRootTracker } from "../test-helpers/temp-dir.js";
import {
approveNodePairing,
getPairedNode,
@@ -30,11 +30,21 @@ async function setupPairedNode(baseDir: string): Promise<string> {
return paired.token;
}
const tempDirs = createSuiteTempRootTracker({ prefix: "openclaw-node-pairing-" });
async function withNodePairingDir<T>(run: (baseDir: string) => Promise<T>): Promise<T> {
return await withTempDir({ prefix: "openclaw-node-pairing-" }, run);
return await run(await tempDirs.make("case"));
}
describe("node pairing tokens", () => {
beforeAll(async () => {
await tempDirs.setup();
});
afterAll(async () => {
await tempDirs.cleanup();
});
test("reuses existing pending requests for the same node", async () => {
await withNodePairingDir(async (baseDir) => {
const first = await requestNodePairing(

View File

@@ -1,10 +1,5 @@
import { describe, expect, it } from "vitest";
import {
loadPluginManifestRegistry,
resolveManifestContractOwnerPluginId,
resolveManifestContractPluginIds,
resolveManifestContractPluginIdsByCompatibilityRuntimePath,
} from "./manifest-registry.js";
import { loadPluginManifestRegistry } from "./manifest-registry.js";
import {
hasBundledWebFetchProviderPublicArtifact,
hasBundledWebSearchProviderPublicArtifact,
@@ -34,12 +29,34 @@ function supportsSecretRefWebSearchApiKey(
return Array.isArray(typeValue) && typeValue.includes("object");
}
const registry = loadPluginManifestRegistry();
function bundledPluginIdsWithContract(
contract: "webSearchProviders" | "webFetchProviders",
): string[] {
return registry.plugins
.filter(
(plugin) => plugin.origin === "bundled" && (plugin.contracts?.[contract]?.length ?? 0) > 0,
)
.map((plugin) => plugin.id)
.toSorted((left, right) => left.localeCompare(right));
}
function ownerPluginIdForContractValue(
contract: "webSearchProviders" | "webFetchProviders",
value: string,
): string | undefined {
const normalized = value.toLowerCase();
return registry.plugins.find(
(plugin) =>
plugin.origin === "bundled" &&
plugin.contracts?.[contract]?.some((candidate) => candidate.toLowerCase() === normalized),
)?.id;
}
describe("web provider public artifacts", () => {
it("has a public artifact for every bundled web search provider declared in manifests", () => {
const pluginIds = resolveManifestContractPluginIds({
contract: "webSearchProviders",
origin: "bundled",
});
const pluginIds = bundledPluginIdsWithContract("webSearchProviders");
expect(pluginIds).not.toHaveLength(0);
for (const pluginId of pluginIds) {
@@ -48,10 +65,7 @@ describe("web provider public artifacts", () => {
});
it("keeps public web search artifacts mapped to their manifest owner plugin", () => {
const pluginIds = resolveManifestContractPluginIds({
contract: "webSearchProviders",
origin: "bundled",
});
const pluginIds = bundledPluginIdsWithContract("webSearchProviders");
const providers = resolveBundledExplicitWebSearchProvidersFromPublicArtifacts({
onlyPluginIds: pluginIds,
@@ -59,18 +73,13 @@ describe("web provider public artifacts", () => {
expect(providers).not.toBeNull();
for (const provider of providers ?? []) {
expect(
resolveManifestContractOwnerPluginId({
contract: "webSearchProviders",
value: provider.id,
origin: "bundled",
}),
).toBe(provider.pluginId);
expect(ownerPluginIdForContractValue("webSearchProviders", provider.id)).toBe(
provider.pluginId,
);
}
});
it("registers compatibility runtime paths for bundled SecretRef-capable web search providers", () => {
const registry = loadPluginManifestRegistry({ cache: false });
const expectedPluginIds = registry.plugins
.filter(
(plugin) =>
@@ -82,20 +91,22 @@ describe("web provider public artifacts", () => {
.toSorted((left, right) => left.localeCompare(right));
expect(expectedPluginIds).not.toHaveLength(0);
expect(
resolveManifestContractPluginIdsByCompatibilityRuntimePath({
contract: "webSearchProviders",
path: "tools.web.search.apiKey",
origin: "bundled",
}),
).toEqual(expectedPluginIds);
const actualPluginIds = registry.plugins
.filter(
(plugin) =>
plugin.origin === "bundled" &&
(plugin.contracts?.webSearchProviders?.length ?? 0) > 0 &&
(plugin.configContracts?.compatibilityRuntimePaths ?? []).includes(
"tools.web.search.apiKey",
),
)
.map((plugin) => plugin.id)
.toSorted((left, right) => left.localeCompare(right));
expect(actualPluginIds).toEqual(expectedPluginIds);
});
it("has a public artifact for every bundled web fetch provider declared in manifests", () => {
const pluginIds = resolveManifestContractPluginIds({
contract: "webFetchProviders",
origin: "bundled",
});
const pluginIds = bundledPluginIdsWithContract("webFetchProviders");
expect(pluginIds).not.toHaveLength(0);
for (const pluginId of pluginIds) {

View File

@@ -1,29 +1,11 @@
import { describe, expect, it } from "vitest";
import {
collectExtensionPluginSdkBoundaryInventory,
main as extensionPluginSdkMain,
} from "../scripts/check-extension-plugin-sdk-boundary.mjs";
import {
collectSdkPackageExtensionImportBoundaryInventory,
main as sdkPackageMain,
} from "../scripts/check-sdk-package-extension-import-boundary.mjs";
import {
collectSrcExtensionImportBoundaryInventory,
main as srcExtensionMain,
} from "../scripts/check-src-extension-import-boundary.mjs";
import { main as extensionPluginSdkMain } from "../scripts/check-extension-plugin-sdk-boundary.mjs";
import { main as sdkPackageMain } from "../scripts/check-sdk-package-extension-import-boundary.mjs";
import { main as srcExtensionMain } from "../scripts/check-src-extension-import-boundary.mjs";
import { createCapturedIo } from "./helpers/captured-io.js";
const srcInventoryPromise = collectSrcExtensionImportBoundaryInventory();
const srcJsonOutputPromise = getJsonOutput(srcExtensionMain, ["--json"]);
const sdkPackageInventoryPromise = collectSdkPackageExtensionImportBoundaryInventory();
const sdkPackageJsonOutputPromise = getJsonOutput(sdkPackageMain, ["--json"]);
const srcOutsideInventoryPromise =
collectExtensionPluginSdkBoundaryInventory("src-outside-plugin-sdk");
const pluginSdkInternalInventoryPromise =
collectExtensionPluginSdkBoundaryInventory("plugin-sdk-internal");
const relativeOutsidePackageInventoryPromise = collectExtensionPluginSdkBoundaryInventory(
"relative-outside-package",
);
const srcOutsideJsonOutputPromise = getJsonOutput(extensionPluginSdkMain, [
"--mode=src-outside-plugin-sdk",
"--json",
@@ -53,10 +35,6 @@ async function getJsonOutput(
}
describe("src extension import boundary inventory", () => {
it("stays empty", async () => {
expect(await srcInventoryPromise).toEqual([]);
});
it("script json output stays empty", async () => {
const jsonOutput = await srcJsonOutputPromise;
@@ -67,10 +45,6 @@ describe("src extension import boundary inventory", () => {
});
describe("sdk/package extension import boundary inventory", () => {
it("stays empty", async () => {
expect(await sdkPackageInventoryPromise).toEqual([]);
});
it("script json output stays empty", async () => {
const jsonOutput = await sdkPackageJsonOutputPromise;
@@ -81,22 +55,9 @@ describe("sdk/package extension import boundary inventory", () => {
});
describe("extension src outside plugin-sdk boundary inventory", () => {
it("stays empty and sorted", async () => {
const inventory = await srcOutsideInventoryPromise;
it("script json output stays empty", async () => {
const jsonResult = await srcOutsideJsonOutputPromise;
expect(inventory).toEqual([]);
expect(
[...inventory].toSorted(
(left, right) =>
left.file.localeCompare(right.file) ||
left.line - right.line ||
left.kind.localeCompare(right.kind) ||
left.specifier.localeCompare(right.specifier) ||
left.resolvedPath.localeCompare(right.resolvedPath) ||
left.reason.localeCompare(right.reason),
),
).toEqual(inventory);
expect(jsonResult.exitCode).toBe(0);
expect(jsonResult.stderr).toBe("");
expect(jsonResult.json).toEqual([]);
@@ -104,11 +65,9 @@ describe("extension src outside plugin-sdk boundary inventory", () => {
});
describe("extension plugin-sdk-internal boundary inventory", () => {
it("stays empty", async () => {
const inventory = await pluginSdkInternalInventoryPromise;
it("script json output stays empty", async () => {
const jsonResult = await pluginSdkInternalJsonOutputPromise;
expect(inventory).toEqual([]);
expect(jsonResult.exitCode).toBe(0);
expect(jsonResult.stderr).toBe("");
expect(jsonResult.json).toEqual([]);
@@ -116,11 +75,9 @@ describe("extension plugin-sdk-internal boundary inventory", () => {
});
describe("extension relative-outside-package boundary inventory", () => {
it("stays empty", async () => {
const inventory = await relativeOutsidePackageInventoryPromise;
it("script json output stays empty", async () => {
const jsonResult = await relativeOutsidePackageJsonOutputPromise;
expect(inventory).toEqual([]);
expect(jsonResult.exitCode).toBe(0);
expect(jsonResult.stderr).toBe("");
expect(jsonResult.json).toEqual([]);

View File

@@ -10,13 +10,6 @@ describe("test-helper extension import boundary inventory", () => {
expect(await collectTestHelperExtensionImportBoundaryInventory()).toEqual([]);
});
it("produces stable sorted output", async () => {
const first = await collectTestHelperExtensionImportBoundaryInventory();
const second = await collectTestHelperExtensionImportBoundaryInventory();
expect(second).toEqual(first);
});
it("script json output stays empty", async () => {
const captured = createCapturedIo();
const exitCode = await main(["--json"], captured.io);