refactor: expose plugin test helpers via sdk

This commit is contained in:
Peter Steinberger
2026-04-27 23:45:08 +01:00
parent 6f09039b0c
commit 0df6e5a473
126 changed files with 659 additions and 349 deletions

View File

@@ -1 +0,0 @@
export { withEnv, withEnvAsync } from "openclaw/plugin-sdk/testing";

View File

@@ -1 +0,0 @@
export { withFetchPreconnect, type FetchMock } from "openclaw/plugin-sdk/testing";

View File

@@ -1 +0,0 @@
export { useFrozenTime, useRealTime } from "../../../src/test-utils/frozen-time.js";

View File

@@ -1 +0,0 @@
export { createRequestCaptureJsonFetch } from "openclaw/plugin-sdk/testing";

View File

@@ -1 +0,0 @@
export { createMockServerResponse } from "openclaw/plugin-sdk/testing";

View File

@@ -1 +0,0 @@
export { registerSingleProviderPlugin } from "openclaw/plugin-sdk/testing";

View File

@@ -1,5 +0,0 @@
export {
createEmptyPluginRegistry,
createTestRegistry,
setActivePluginRegistry,
} from "openclaw/plugin-sdk/testing";

View File

@@ -16,7 +16,7 @@ export type ProviderDiscoveryContractPluginLoader = () => Promise<{
default: Parameters<typeof registerProviders>[0];
}>;
type ProviderHandle = Awaited<ReturnType<typeof requireProvider>>;
type ProviderHandle = Awaited<ReturnType<typeof registerProviders>>[number];
type DiscoveryState = {
runProviderCatalog: typeof import("../../../src/plugins/provider-discovery.js").runProviderCatalog;

View File

@@ -1,91 +0,0 @@
import type {
ImageGenerationProviderPlugin,
MediaUnderstandingProviderPlugin,
MusicGenerationProviderPlugin,
ProviderPlugin,
RealtimeTranscriptionProviderPlugin,
SpeechProviderPlugin,
VideoGenerationProviderPlugin,
} from "../../../src/plugins/types.js";
import { createTestPluginApi } from "./plugin-api.js";
type RegisteredProviderCollections = {
providers: ProviderPlugin[];
realtimeTranscriptionProviders: RealtimeTranscriptionProviderPlugin[];
speechProviders: SpeechProviderPlugin[];
mediaProviders: MediaUnderstandingProviderPlugin[];
imageProviders: ImageGenerationProviderPlugin[];
musicProviders: MusicGenerationProviderPlugin[];
videoProviders: VideoGenerationProviderPlugin[];
};
type ProviderPluginModule = {
register(api: ReturnType<typeof createTestPluginApi>): void;
};
export async function registerProviderPlugin(params: {
plugin: ProviderPluginModule;
id: string;
name: string;
}): Promise<RegisteredProviderCollections> {
const providers: ProviderPlugin[] = [];
const realtimeTranscriptionProviders: RealtimeTranscriptionProviderPlugin[] = [];
const speechProviders: SpeechProviderPlugin[] = [];
const mediaProviders: MediaUnderstandingProviderPlugin[] = [];
const imageProviders: ImageGenerationProviderPlugin[] = [];
const musicProviders: MusicGenerationProviderPlugin[] = [];
const videoProviders: VideoGenerationProviderPlugin[] = [];
params.plugin.register(
createTestPluginApi({
id: params.id,
name: params.name,
source: "test",
config: {},
runtime: {} as never,
registerProvider: (provider) => {
providers.push(provider);
},
registerRealtimeTranscriptionProvider: (provider) => {
realtimeTranscriptionProviders.push(provider);
},
registerSpeechProvider: (provider) => {
speechProviders.push(provider);
},
registerMediaUnderstandingProvider: (provider) => {
mediaProviders.push(provider);
},
registerImageGenerationProvider: (provider) => {
imageProviders.push(provider);
},
registerMusicGenerationProvider: (provider) => {
musicProviders.push(provider);
},
registerVideoGenerationProvider: (provider) => {
videoProviders.push(provider);
},
}),
);
return {
providers,
realtimeTranscriptionProviders,
speechProviders,
mediaProviders,
imageProviders,
musicProviders,
videoProviders,
};
}
export function requireRegisteredProvider<T extends { id: string }>(
entries: T[],
id: string,
label = "provider",
): T {
const entry = entries.find((candidate) => candidate.id === id);
if (!entry) {
throw new Error(`${label} ${id} was not registered`);
}
return entry;
}

View File

@@ -1,13 +1,14 @@
import fs from "node:fs/promises";
import os from "node:os";
import path from "node:path";
import { beforeAll, beforeEach, describe, expect, it, vi } from "vitest";
import type { ProviderPlugin, ProviderRuntimeModel } from "../../../src/plugins/types.js";
import {
createProviderUsageFetch,
makeResponse,
} from "../../../src/test-utils/provider-usage-fetch.js";
import { registerProviderPlugin, requireRegisteredProvider } from "./provider-registration.js";
registerProviderPlugin,
requireRegisteredProvider,
} from "openclaw/plugin-sdk/testing";
import { beforeAll, beforeEach, describe, expect, it, vi } from "vitest";
import type { ProviderPlugin, ProviderRuntimeModel } from "../../../src/plugins/types.js";
const CONTRACT_SETUP_TIMEOUT_MS = 300_000;

View File

@@ -1,4 +0,0 @@
export {
createProviderUsageFetch,
makeResponse,
} from "../../../src/test-utils/provider-usage-fetch.js";

View File

@@ -1 +0,0 @@
export { createRuntimeTaskFlow } from "openclaw/plugin-sdk/testing";

View File

@@ -1,3 +1,4 @@
import { createRuntimeEnv } from "openclaw/plugin-sdk/testing";
import { vi } from "vitest";
import type {
ChannelAccountSnapshot,
@@ -5,7 +6,6 @@ import type {
} from "../../../src/channels/plugins/types.js";
import type { OpenClawConfig } from "../../../src/config/config.js";
import type { RuntimeEnv } from "../../../src/runtime.js";
import { createRuntimeEnv } from "./runtime-env.js";
export function createStartAccountContext<TAccount extends { accountId: string }>(params: {
account: TAccount;

View File

@@ -1 +0,0 @@
export { withTempDir } from "openclaw/plugin-sdk/testing";

View File

@@ -1 +0,0 @@
export { createTempHomeEnv, type TempHomeEnv } from "openclaw/plugin-sdk/testing";

View File

@@ -1 +0,0 @@
export { typedCases } from "openclaw/plugin-sdk/testing";