From 85ef3482d8d81b4401cfc1ad2f0a36217f906cd5 Mon Sep 17 00:00:00 2001 From: Alexander Davydov Date: Fri, 20 Mar 2026 13:25:47 +0300 Subject: [PATCH] Tests: fold loader git-path regression into loader suite --- .../loader.git-path-regression.test.ts | 108 ------------------ src/plugins/loader.test.ts | 11 +- test/fixtures/test-parallel.behavior.json | 4 - 3 files changed, 10 insertions(+), 113 deletions(-) delete mode 100644 src/plugins/loader.git-path-regression.test.ts diff --git a/src/plugins/loader.git-path-regression.test.ts b/src/plugins/loader.git-path-regression.test.ts deleted file mode 100644 index e66771ab714..00000000000 --- a/src/plugins/loader.git-path-regression.test.ts +++ /dev/null @@ -1,108 +0,0 @@ -import fs from "node:fs"; -import os from "node:os"; -import path from "node:path"; -import { afterEach, describe, expect, it, vi } from "vitest"; - -type CreateJiti = typeof import("jiti").createJiti; -type LoaderTesting = (typeof import("./loader.js"))["__testing"]; - -let createJitiPromise: Promise | undefined; -let loaderTestingPromise: Promise | undefined; - -async function getCreateJiti() { - createJitiPromise ??= import("jiti").then(({ createJiti }) => createJiti); - return createJitiPromise; -} - -async function getLoaderTesting() { - loaderTestingPromise ??= (async () => { - vi.resetModules(); - vi.doUnmock("jiti"); - vi.doUnmock("./loader.js"); - const { __testing } = await import("./loader.js"); - return __testing; - })(); - return loaderTestingPromise; -} - -const tempRoots: string[] = []; - -function makeTempDir() { - const dir = fs.mkdtempSync(path.join(os.tmpdir(), "openclaw-plugin-loader-")); - tempRoots.push(dir); - return dir; -} - -function mkdirSafe(dir: string) { - fs.mkdirSync(dir, { recursive: true }); -} - -afterEach(() => { - for (const dir of tempRoots.splice(0)) { - fs.rmSync(dir, { recursive: true, force: true }); - } - createJitiPromise = undefined; - loaderTestingPromise = undefined; -}); - -describe("plugin loader git path regression", () => { - it("loads git-style package extension entries when they import plugin-sdk channel-runtime (#49806)", async () => { - const __testing = await getLoaderTesting(); - const copiedExtensionRoot = path.join(makeTempDir(), "extensions", "imessage"); - const copiedSourceDir = path.join(copiedExtensionRoot, "src"); - const copiedPluginSdkDir = path.join(copiedExtensionRoot, "plugin-sdk"); - mkdirSafe(copiedSourceDir); - mkdirSafe(copiedPluginSdkDir); - - fs.writeFileSync( - path.join(copiedSourceDir, "channel.runtime.ts"), - `import { resolveOutboundSendDep } from "openclaw/plugin-sdk/channel-runtime"; -import { PAIRING_APPROVED_MESSAGE } from "../runtime-api.js"; - -export const copiedRuntimeMarker = { - resolveOutboundSendDep, - PAIRING_APPROVED_MESSAGE, -}; -`, - "utf-8", - ); - fs.writeFileSync( - path.join(copiedExtensionRoot, "runtime-api.ts"), - `export const PAIRING_APPROVED_MESSAGE = "paired"; -`, - "utf-8", - ); - const copiedChannelRuntimeShim = path.join(copiedPluginSdkDir, "channel-runtime.ts"); - fs.writeFileSync( - copiedChannelRuntimeShim, - `export function resolveOutboundSendDep() { - return "shimmed"; -} -`, - "utf-8", - ); - - const copiedChannelRuntime = path.join(copiedExtensionRoot, "src", "channel.runtime.ts"); - const createJiti = await getCreateJiti(); - const withoutAlias = createJiti(import.meta.url, { - ...__testing.buildPluginLoaderJitiOptions({}), - tryNative: false, - }); - // The production loader uses sync Jiti evaluation, so this regression test - // should exercise the same seam instead of Jiti's async import helper. - expect(() => withoutAlias(copiedChannelRuntime)).toThrow(); - - const withAlias = createJiti(import.meta.url, { - ...__testing.buildPluginLoaderJitiOptions({ - "openclaw/plugin-sdk/channel-runtime": copiedChannelRuntimeShim, - }), - tryNative: false, - }); - expect(withAlias(copiedChannelRuntime)).toMatchObject({ - copiedRuntimeMarker: { - PAIRING_APPROVED_MESSAGE: "paired", - resolveOutboundSendDep: expect.any(Function), - }, - }); - }); -}); diff --git a/src/plugins/loader.test.ts b/src/plugins/loader.test.ts index a4bf12fad15..5713ddceb75 100644 --- a/src/plugins/loader.test.ts +++ b/src/plugins/loader.test.ts @@ -3561,7 +3561,7 @@ module.exports = { }); it("loads source runtime shims through the non-native Jiti boundary", async () => { - const copiedExtensionRoot = path.join(makeTempDir(), "extensions", "discord"); + const copiedExtensionRoot = path.join(makeTempDir(), "extensions", "imessage"); const copiedSourceDir = path.join(copiedExtensionRoot, "src"); const copiedPluginSdkDir = path.join(copiedExtensionRoot, "plugin-sdk"); mkdirSafe(copiedSourceDir); @@ -3571,10 +3571,18 @@ module.exports = { fs.writeFileSync( path.join(copiedSourceDir, "channel.runtime.ts"), `import { resolveOutboundSendDep } from "openclaw/plugin-sdk/channel-runtime"; +import { PAIRING_APPROVED_MESSAGE } from "../runtime-api.js"; export const syntheticRuntimeMarker = { resolveOutboundSendDep, + PAIRING_APPROVED_MESSAGE, }; +`, + "utf-8", + ); + fs.writeFileSync( + path.join(copiedExtensionRoot, "runtime-api.ts"), + `export const PAIRING_APPROVED_MESSAGE = "paired"; `, "utf-8", ); @@ -3607,6 +3615,7 @@ export const syntheticRuntimeMarker = { }); expect(withAlias(copiedChannelRuntime)).toMatchObject({ syntheticRuntimeMarker: { + PAIRING_APPROVED_MESSAGE: "paired", resolveOutboundSendDep: expect.any(Function), }, }); diff --git a/test/fixtures/test-parallel.behavior.json b/test/fixtures/test-parallel.behavior.json index 954b5f87557..c0b81451bfc 100644 --- a/test/fixtures/test-parallel.behavior.json +++ b/test/fixtures/test-parallel.behavior.json @@ -199,10 +199,6 @@ "file": "src/infra/heartbeat-runner.model-override.test.ts", "reason": "Mocks jiti at file scope, so it is safer outside shared Vitest workers." }, - { - "file": "src/plugins/loader.git-path-regression.test.ts", - "reason": "Constructs a real Jiti boundary and is safer outside shared workers that may have mocked jiti earlier." - }, { "file": "src/infra/outbound/outbound-session.test.ts", "reason": "Outbound session coverage retained a large shared unit-fast heap spike on Linux Node 22 CI."