mirror of
https://github.com/openclaw/openclaw.git
synced 2026-09-28 14:12:28 +08:00
118 lines
4.0 KiB
TypeScript
118 lines
4.0 KiB
TypeScript
import { spawnSync } from "node:child_process";
|
|
import fs from "node:fs";
|
|
import path from "node:path";
|
|
import { describe, expect, it, vi } from "vitest";
|
|
import { resolvePreviewPython } from "../../scripts/lib/docs-preview-python.mjs";
|
|
import { createScriptTestHarness } from "./test-helpers.js";
|
|
|
|
const { createTempDir } = createScriptTestHarness();
|
|
const wrapper = path.resolve("scripts/docs-dev.mjs");
|
|
|
|
describe("docs source preview", () => {
|
|
it.each([{ prefix: [] }, { prefix: ["--"] }])(
|
|
"hands source edits and page selection to the publisher with prefix %j",
|
|
({ prefix }) => {
|
|
const site = createTempDir("openclaw-docs-site-");
|
|
fs.mkdirSync(path.join(site, "node_modules"));
|
|
fs.writeFileSync(
|
|
path.join(site, "package.json"),
|
|
JSON.stringify({ scripts: { "docs:build:preview": "node preview.cjs" } }),
|
|
);
|
|
fs.writeFileSync(
|
|
path.join(site, "preview.cjs"),
|
|
`require("node:fs").writeFileSync("args.json", JSON.stringify(process.argv.slice(2)));`,
|
|
);
|
|
const before = fs.readFileSync("docs/docs.json");
|
|
const result = spawnSync(
|
|
process.execPath,
|
|
[
|
|
wrapper,
|
|
...prefix,
|
|
"--site-repo",
|
|
site,
|
|
"--build-only",
|
|
"--page",
|
|
"gateway/configuration",
|
|
"--page",
|
|
"index",
|
|
],
|
|
{ encoding: "utf8" },
|
|
);
|
|
expect(result.status, result.stderr).toBe(0);
|
|
expect(JSON.parse(fs.readFileSync(path.join(site, "args.json"), "utf8"))).toEqual([
|
|
"--source-root",
|
|
process.cwd(),
|
|
"--output-dir",
|
|
path.join(process.cwd(), ".cache", "docs-preview"),
|
|
"--page",
|
|
"gateway/configuration",
|
|
"--page",
|
|
"index",
|
|
]);
|
|
expect(fs.readFileSync("docs/docs.json")).toEqual(before);
|
|
},
|
|
);
|
|
|
|
it("explains missing site dependencies and rejects invalid ports before building", () => {
|
|
const site = createTempDir("openclaw-docs-site-missing-");
|
|
fs.writeFileSync(
|
|
path.join(site, "package.json"),
|
|
JSON.stringify({ scripts: { "docs:build:preview": "node preview.cjs" } }),
|
|
);
|
|
const missing = spawnSync(process.execPath, [wrapper, "--site-repo", site, "--build-only"], {
|
|
encoding: "utf8",
|
|
});
|
|
expect(missing.status).not.toBe(0);
|
|
expect(missing.stderr).toContain("Run npm ci");
|
|
const invalid = spawnSync(process.execPath, [wrapper, "--port", "0"], { encoding: "utf8" });
|
|
expect(invalid.status).not.toBe(0);
|
|
expect(invalid.stderr).toContain("--port must be an integer");
|
|
});
|
|
});
|
|
|
|
describe("docs preview Python launcher", () => {
|
|
it.each([
|
|
{ versions: ["3"], command: "py", prefix: ["-3"] },
|
|
{ versions: ["missing", "3"], command: "python", prefix: [] },
|
|
{ versions: ["missing", "2", "3"], command: "python3", prefix: [] },
|
|
])("selects Python 3 using $command", ({ versions, command, prefix }) => {
|
|
const probe = vi.fn((_command: string, _args: string[]) => {
|
|
const version = versions.shift();
|
|
return {
|
|
status: version === "missing" ? 1 : 0,
|
|
stdout: version ?? "",
|
|
stderr: "",
|
|
pid: 1,
|
|
signal: null,
|
|
output: [],
|
|
};
|
|
});
|
|
expect(resolvePreviewPython("win32", probe)).toEqual({ command, args: prefix });
|
|
expect(probe.mock.calls.map((call) => call[0])).toEqual(
|
|
["py", "python", "python3"].slice(0, probe.mock.calls.length),
|
|
);
|
|
});
|
|
|
|
it("uses python3 on Unix and rejects unavailable or non-Python-3 launchers", () => {
|
|
const good = vi.fn(() => ({
|
|
status: 0,
|
|
stdout: "3\n",
|
|
stderr: "",
|
|
pid: 1,
|
|
signal: null,
|
|
output: [],
|
|
}));
|
|
expect(resolvePreviewPython("darwin", good)).toEqual({ command: "python3", args: [] });
|
|
const bad = vi.fn(() => ({
|
|
status: 0,
|
|
stdout: "2\n",
|
|
stderr: "",
|
|
pid: 1,
|
|
signal: null,
|
|
output: [],
|
|
}));
|
|
expect(() => resolvePreviewPython("win32", bad)).toThrow("Python 3 is required");
|
|
expect(bad).toHaveBeenCalledTimes(3);
|
|
});
|
|
});
|