From 31bbe6eb0fc86597b8170fa528aea1fc8655a767 Mon Sep 17 00:00:00 2001 From: Vincent Koc Date: Sat, 16 May 2026 14:31:43 +0800 Subject: [PATCH] fix(test): avoid scanning status runtime bundles --- scripts/test-built-status-message-runtime.mjs | 81 +++++++++++++------ .../test-built-status-message-runtime.test.ts | 40 +++++++++ 2 files changed, 98 insertions(+), 23 deletions(-) create mode 100644 test/scripts/test-built-status-message-runtime.test.ts diff --git a/scripts/test-built-status-message-runtime.mjs b/scripts/test-built-status-message-runtime.mjs index e081354f128..64bd66a7824 100644 --- a/scripts/test-built-status-message-runtime.mjs +++ b/scripts/test-built-status-message-runtime.mjs @@ -1,4 +1,5 @@ import assert from "node:assert/strict"; +import { spawnSync } from "node:child_process"; import fs from "node:fs"; import path from "node:path"; import { pathToFileURL } from "node:url"; @@ -6,16 +7,8 @@ import { parsePackageRootArg } from "./lib/package-root-args.mjs"; const STATUS_MESSAGE_RUNTIME_RE = /^status-message\.runtime(?:-[A-Za-z0-9_-]+)?\.js$/u; -const { packageRoot } = parsePackageRootArg( - process.argv.slice(2), - "OPENCLAW_STATUS_MESSAGE_RUNTIME_ROOT", -); - -function findBuiltStatusMessageRuntimePath(distDir) { - const candidates = fs - .readdirSync(distDir, { withFileTypes: true }) - .filter((entry) => entry.isFile() && STATUS_MESSAGE_RUNTIME_RE.test(entry.name)) - .map((entry) => entry.name) +export function findBuiltStatusMessageRuntimePath(distDir) { + const candidates = listBuiltStatusMessageRuntimeFiles(distDir) .toSorted((left, right) => { const leftHasHash = left !== "status-message.runtime.js"; const rightHasHash = right !== "status-message.runtime.js"; @@ -30,18 +23,60 @@ function findBuiltStatusMessageRuntimePath(distDir) { return path.join(distDir, candidates[0]); } -const runtimePath = findBuiltStatusMessageRuntimePath(path.join(packageRoot, "dist")); -const runtimeModule = await import(pathToFileURL(runtimePath).href); +function listBuiltStatusMessageRuntimeFiles(distDir) { + const externalFiles = listFindBuiltStatusMessageRuntimeFiles(distDir); + if (externalFiles) { + return externalFiles; + } + return fs + .readdirSync(distDir, { withFileTypes: true }) + .filter((entry) => entry.isFile() && STATUS_MESSAGE_RUNTIME_RE.test(entry.name)) + .map((entry) => entry.name); +} -assert.equal( - typeof runtimeModule.loadStatusMessageRuntimeModule, - "function", - `built status-message runtime did not export loadStatusMessageRuntimeModule: ${runtimePath}`, -); +function listFindBuiltStatusMessageRuntimeFiles(distDir) { + const result = spawnSync( + "find", + [distDir, "-maxdepth", "1", "-type", "f", "-name", "status-message.runtime*.js"], + { + encoding: "utf8", + maxBuffer: 1024 * 1024, + stdio: ["ignore", "pipe", "ignore"], + }, + ); + if (result.status !== 0) { + return null; + } + return result.stdout + .split("\n") + .map((line) => line.trim()) + .filter((line) => line.length > 0) + .map((file) => path.basename(file)) + .filter((file) => STATUS_MESSAGE_RUNTIME_RE.test(file)); +} -const statusModule = await runtimeModule.loadStatusMessageRuntimeModule(); -assert.equal( - typeof statusModule.buildStatusMessage, - "function", - "status-message runtime did not load buildStatusMessage", -); +async function main() { + const { packageRoot } = parsePackageRootArg( + process.argv.slice(2), + "OPENCLAW_STATUS_MESSAGE_RUNTIME_ROOT", + ); + const runtimePath = findBuiltStatusMessageRuntimePath(path.join(packageRoot, "dist")); + const runtimeModule = await import(pathToFileURL(runtimePath).href); + + assert.equal( + typeof runtimeModule.loadStatusMessageRuntimeModule, + "function", + `built status-message runtime did not export loadStatusMessageRuntimeModule: ${runtimePath}`, + ); + + const statusModule = await runtimeModule.loadStatusMessageRuntimeModule(); + assert.equal( + typeof statusModule.buildStatusMessage, + "function", + "status-message runtime did not load buildStatusMessage", + ); +} + +if (process.argv[1] && import.meta.url === pathToFileURL(path.resolve(process.argv[1])).href) { + await main(); +} diff --git a/test/scripts/test-built-status-message-runtime.test.ts b/test/scripts/test-built-status-message-runtime.test.ts new file mode 100644 index 00000000000..8f7a4a7d272 --- /dev/null +++ b/test/scripts/test-built-status-message-runtime.test.ts @@ -0,0 +1,40 @@ +import fs from "node:fs"; +import os from "node:os"; +import path from "node:path"; +import { afterEach, describe, expect, it, vi } from "vitest"; +import { findBuiltStatusMessageRuntimePath } from "../../scripts/test-built-status-message-runtime.mjs"; + +const tempDirs: string[] = []; + +afterEach(() => { + for (const dir of tempDirs.splice(0)) { + fs.rmSync(dir, { recursive: true, force: true }); + } +}); + +function makeDistDir(): string { + const root = fs.mkdtempSync(path.join(os.tmpdir(), "openclaw-status-runtime-")); + tempDirs.push(root); + const distDir = path.join(root, "dist"); + fs.mkdirSync(distDir, { recursive: true }); + return distDir; +} + +describe("test-built-status-message-runtime", () => { + it("finds the built status runtime without scanning dist in-process", () => { + const distDir = makeDistDir(); + fs.writeFileSync(path.join(distDir, "status-message.runtime.js"), "export {}\n"); + fs.writeFileSync(path.join(distDir, "status-message.runtime-abc123.js"), "export {}\n"); + fs.writeFileSync(path.join(distDir, "other.js"), "export {}\n"); + + const readDir = vi.spyOn(fs, "readdirSync"); + try { + expect(findBuiltStatusMessageRuntimePath(distDir)).toBe( + path.join(distDir, "status-message.runtime-abc123.js"), + ); + expect(readDir).not.toHaveBeenCalled(); + } finally { + readDir.mockRestore(); + } + }); +});