Download src/plugins/contracts/runtime-import-side-effects.contract.test.ts from SaylorTwift/openclaw: direct link, hf CLI and curl.
- Browser
- Download file 4.97 kB
-
https://huggingface.co/SaylorTwift/openclaw/resolve/main/src/plugins/contracts/runtime-import-side-effects.contract.test.ts
- Command line
-
hf download hf://SaylorTwift/openclaw/src/plugins/contracts/runtime-import-side-effects.contract.test.ts
-
curl -L -o runtime-import-side-effects.contract.test.ts https://huggingface.co/SaylorTwift/openclaw/resolve/main/src/plugins/contracts/runtime-import-side-effects.contract.test.ts
4.97 kB
| // Runtime import side-effect contract tests cover cold import behavior for plugin runtime code. | |
| import fs from "node:fs"; | |
| import { afterEach, beforeEach, describe, expect, it, vi } from "vitest"; | |
| import { assertNoImportTimeSideEffects } from "../../plugin-sdk/test-helpers/import-side-effects.js"; | |
| const listChannelPlugins = vi.hoisted(() => | |
| vi.fn(() => [ | |
| { | |
| id: "telegram", | |
| messaging: { | |
| defaultMarkdownTableMode: "bullets", | |
| }, | |
| }, | |
| ]), | |
| ); | |
| const getActivePluginChannelRegistryVersion = vi.hoisted(() => vi.fn(() => 1)); | |
| const CHANNEL_REGISTRY_SEAM = "listChannelPlugins()"; | |
| const CHANNEL_REGISTRY_WHY = | |
| "it boots active channel metadata on hot runtime/config import paths and turns cheap module evaluation into plugin registry work."; | |
| const CHANNEL_REGISTRY_FIX = | |
| "keep the seam behind a lazy getter/runtime boundary so import stays cold and the first real lookup loads once."; | |
| const HOT_RUNTIME_IMPORT_CASES = [ | |
| ["src/config/markdown-tables.ts", () => import("../../config/markdown-tables.js")], | |
| [ | |
| "src/plugin-sdk/approval-handler-adapter-runtime.ts", | |
| () => import("../../plugin-sdk/approval-handler-adapter-runtime.js"), | |
| ], | |
| [ | |
| "src/plugin-sdk/approval-gateway-runtime.ts", | |
| () => import("../../plugin-sdk/approval-gateway-runtime.js"), | |
| ], | |
| [ | |
| "src/plugin-sdk/approval-reference-runtime.ts", | |
| () => import("../../plugin-sdk/approval-reference-runtime.js"), | |
| ], | |
| ["src/plugins/runtime/runtime-system.ts", () => import("../runtime/runtime-system.js")], | |
| ["src/web-search/runtime.ts", () => import("../../web-search/runtime.js")], | |
| ["src/web-fetch/runtime.ts", () => import("../../web-fetch/runtime.js")], | |
| ] as const; | |
| function mockChannelRegistry() { | |
| vi.doMock("../../channels/plugins/index.js", async () => { | |
| const actual = await vi.importActual<typeof import("../../channels/plugins/index.js")>( | |
| "../../channels/plugins/index.js", | |
| ); | |
| return { | |
| ...actual, | |
| normalizeChannelId: (raw?: string | null) => raw ?? null, | |
| }; | |
| }); | |
| vi.doMock("../../channels/plugins/registry.js", async () => { | |
| const actual = await vi.importActual<typeof import("../../channels/plugins/registry.js")>( | |
| "../../channels/plugins/registry.js", | |
| ); | |
| return { | |
| ...actual, | |
| listChannelPlugins, | |
| }; | |
| }); | |
| vi.doMock("../../plugins/runtime.js", async () => { | |
| const actual = await vi.importActual<typeof import("../../plugins/runtime.js")>( | |
| "../../plugins/runtime.js", | |
| ); | |
| return { | |
| ...actual, | |
| getActivePluginChannelRegistryVersion, | |
| }; | |
| }); | |
| } | |
| function expectNoChannelRegistryDuringImport(moduleId: string) { | |
| assertNoImportTimeSideEffects({ | |
| moduleId, | |
| forbiddenSeam: CHANNEL_REGISTRY_SEAM, | |
| calls: listChannelPlugins.mock.calls, | |
| why: CHANNEL_REGISTRY_WHY, | |
| fixHint: CHANNEL_REGISTRY_FIX, | |
| }); | |
| expect(getActivePluginChannelRegistryVersion).not.toHaveBeenCalled(); | |
| } | |
| afterEach(() => { | |
| vi.resetModules(); | |
| vi.restoreAllMocks(); | |
| vi.doUnmock("../../channels/plugins/index.js"); | |
| vi.doUnmock("../../channels/plugins/registry.js"); | |
| vi.doUnmock("../../plugins/runtime.js"); | |
| }); | |
| describe("runtime import side-effect contracts", () => { | |
| beforeEach(() => { | |
| listChannelPlugins.mockClear(); | |
| getActivePluginChannelRegistryVersion.mockClear().mockReturnValue(1); | |
| }); | |
| it("keeps markdown table defaults lazy and memoized after import", async () => { | |
| mockChannelRegistry(); | |
| const markdownTables = await import("../../config/markdown-tables.js"); | |
| expectNoChannelRegistryDuringImport("src/config/markdown-tables.ts"); | |
| expect( | |
| markdownTables.resolveMarkdownTableMode({ | |
| channel: "telegram", | |
| supportsBlockTables: true, | |
| }), | |
| ).toBe("bullets"); | |
| expect(getActivePluginChannelRegistryVersion).toHaveBeenCalled(); | |
| expect(listChannelPlugins).toHaveBeenCalledTimes(1); | |
| expect( | |
| markdownTables.resolveMarkdownTableMode({ | |
| channel: "telegram", | |
| supportsBlockTables: true, | |
| }), | |
| ).toBe("bullets"); | |
| expect(getActivePluginChannelRegistryVersion).toHaveBeenCalled(); | |
| expect(listChannelPlugins).toHaveBeenCalledTimes(1); | |
| }); | |
| it.each(HOT_RUNTIME_IMPORT_CASES)("keeps %s cold", async (moduleId, importModule) => { | |
| mockChannelRegistry(); | |
| await importModule(); | |
| expectNoChannelRegistryDuringImport(moduleId); | |
| }); | |
| it("keeps runtime-channel off direct channel registry imports", () => { | |
| const source = fs.readFileSync("src/plugins/runtime/runtime-channel.ts", "utf8"); | |
| expect(source).not.toContain("../../channels/plugins/registry"); | |
| expect(source).not.toContain("../channels/plugins/registry"); | |
| }); | |
| it("keeps runtime index off direct channel registry imports", () => { | |
| const source = fs.readFileSync("src/plugins/runtime/index.ts", "utf8"); | |
| expect(source).not.toContain("../../channels/plugins/registry"); | |
| expect(source).not.toContain("../channels/plugins/registry"); | |
| }); | |
| }); | |