import fs from "node:fs"; import os from "node:os"; import path from "node:path"; import { pathToFileURL } from "node:url"; import { afterEach, beforeEach, describe, expect, it } from "vitest"; import { QQBOT_PLUGIN_VERSION_UNKNOWN, resolveQQBotPluginVersion } from "./plugin-version.js";
/** Create a temp directory tree for an individual test and return its root. */ function createTempTree(): string { return fs.mkdtempSync(path.join(os.tmpdir(), "qqbot-pkg-version-"));
}
function fakeEntryFileUrl(dir: string): string { const entryPath = path.join(dir, "gateway.ts"); // File need not exist for `fileURLToPath` to work; the resolver // only uses its *parent directory* as the walk start point. return pathToFileURL(entryPath).href;
}
describe("resolveQQBotPluginVersion", () => {
let tempRoots: string[] = [];
beforeEach(() => {
tempRoots = [];
});
afterEach(() => { for (const root of tempRoots) {
fs.rmSync(root, { recursive: true, force: true });
}
});
it("returns the version from the nearest matching package.json", () => { const root = newTree(); const pluginDir = path.join(root, "extensions", "qqbot"); const bridgeDir = path.join(pluginDir, "src", "bridge");
writeJson(path.join(pluginDir, "package.json"), {
name: "@openclaw/qqbot",
version: "2026.4.16",
});
fs.mkdirSync(bridgeDir, { recursive: true });
const version = resolveQQBotPluginVersion(fakeEntryFileUrl(bridgeDir));
expect(version).toBe("2026.4.16");
});
it("skips package.json files whose name field does not match", () => { const root = newTree(); // Parent package.json belongs to the framework, not the plugin.
writeJson(path.join(root, "package.json"), {
name: "openclaw",
version: "9.9.9",
}); const pluginDir = path.join(root, "extensions", "qqbot"); const bridgeDir = path.join(pluginDir, "src", "bridge");
writeJson(path.join(pluginDir, "package.json"), {
name: "@openclaw/qqbot",
version: "2026.4.16",
});
fs.mkdirSync(bridgeDir, { recursive: true });
const version = resolveQQBotPluginVersion(fakeEntryFileUrl(bridgeDir));
// Must stop at the plugin manifest, never bubble up to the framework one.
expect(version).toBe("2026.4.16");
});
it("ignores manifests with unrelated name and returns unknown when no match is found", () => { const root = newTree(); // Only an unrelated manifest exists up the tree.
writeJson(path.join(root, "package.json"), {
name: "some-other-package",
version: "1.0.0",
}); const startDir = path.join(root, "extensions", "qqbot", "src", "bridge");
fs.mkdirSync(startDir, { recursive: true });
const version = resolveQQBotPluginVersion(fakeEntryFileUrl(startDir));
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.