mirror of
https://github.com/openclaw/openclaw.git
synced 2026-04-01 12:21:25 +00:00
docs: fix English link audits (#57039)
Merged via squash.
Prepared head SHA: d20a3b620f
Co-authored-by: velvet-shark <126378+velvet-shark@users.noreply.github.com>
Reviewed-by: @velvet-shark
This commit is contained in:
committed by
GitHub
parent
6c91b27756
commit
4680335b2a
@@ -1,22 +1,33 @@
|
||||
import fs from "node:fs";
|
||||
import os from "node:os";
|
||||
import path from "node:path";
|
||||
import { describe, expect, it } from "vitest";
|
||||
|
||||
const { normalizeRoute, resolveRoute, runDocsLinkAuditCli } =
|
||||
(await import("../../scripts/docs-link-audit.mjs")) as unknown as {
|
||||
normalizeRoute: (route: string) => string;
|
||||
resolveRoute: (
|
||||
route: string,
|
||||
options?: { redirects?: Map<string, string>; routes?: Set<string> },
|
||||
) => { ok: boolean; terminal: string; loop?: boolean };
|
||||
runDocsLinkAuditCli: (options?: {
|
||||
args?: string[];
|
||||
spawnSyncImpl?: (
|
||||
command: string,
|
||||
args: string[],
|
||||
options: { cwd: string; stdio: string },
|
||||
) => { status: number | null; error?: { code?: string } };
|
||||
}) => number;
|
||||
};
|
||||
const {
|
||||
normalizeRoute,
|
||||
prepareAnchorAuditDocsDir,
|
||||
resolveRoute,
|
||||
runDocsLinkAuditCli,
|
||||
sanitizeDocsConfigForEnglishOnly,
|
||||
} = (await import("../../scripts/docs-link-audit.mjs")) as unknown as {
|
||||
normalizeRoute: (route: string) => string;
|
||||
prepareAnchorAuditDocsDir: (sourceDir?: string) => string;
|
||||
resolveRoute: (
|
||||
route: string,
|
||||
options?: { redirects?: Map<string, string>; routes?: Set<string> },
|
||||
) => { ok: boolean; terminal: string; loop?: boolean };
|
||||
runDocsLinkAuditCli: (options?: {
|
||||
args?: string[];
|
||||
spawnSyncImpl?: (
|
||||
command: string,
|
||||
args: string[],
|
||||
options: { cwd: string; stdio: string },
|
||||
) => { status: number | null; error?: { code?: string } };
|
||||
prepareAnchorAuditDocsDirImpl?: (sourceDir?: string) => string;
|
||||
cleanupAnchorAuditDocsDirImpl?: (dir: string) => void;
|
||||
}) => number;
|
||||
sanitizeDocsConfigForEnglishOnly: (value: unknown) => unknown;
|
||||
};
|
||||
|
||||
describe("docs-link-audit", () => {
|
||||
it("normalizes route fragments away", () => {
|
||||
@@ -38,6 +49,101 @@ describe("docs-link-audit", () => {
|
||||
});
|
||||
});
|
||||
|
||||
it("sanitizes docs.json to English-only route targets", () => {
|
||||
expect(
|
||||
sanitizeDocsConfigForEnglishOnly({
|
||||
navigation: [
|
||||
{
|
||||
language: "en",
|
||||
tabs: [
|
||||
{
|
||||
tab: "Docs",
|
||||
groups: [
|
||||
{
|
||||
group: "Keep",
|
||||
pages: ["help/testing", "zh-CN/help/testing", "ja-JP/help/testing"],
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
language: "zh-Hans",
|
||||
tabs: [{ tab: "中文", groups: [{ group: "帮助", pages: ["zh-CN/help/testing"] }] }],
|
||||
},
|
||||
],
|
||||
redirects: [
|
||||
{ source: "/help/testing", destination: "/help/testing" },
|
||||
{ source: "/zh-CN/help/testing", destination: "/help/testing" },
|
||||
{ source: "/help/testing", destination: "/ja-JP/help/testing" },
|
||||
],
|
||||
}),
|
||||
).toEqual({
|
||||
navigation: [
|
||||
{
|
||||
language: "en",
|
||||
tabs: [
|
||||
{
|
||||
tab: "Docs",
|
||||
groups: [{ group: "Keep", pages: ["help/testing"] }],
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
redirects: [{ source: "/help/testing", destination: "/help/testing" }],
|
||||
});
|
||||
});
|
||||
|
||||
it("builds an English-only docs tree for anchor audits", () => {
|
||||
const fixtureRoot = fs.mkdtempSync(path.join(os.tmpdir(), "docs-link-audit-fixture-"));
|
||||
const docsRoot = path.join(fixtureRoot, "docs");
|
||||
fs.mkdirSync(path.join(docsRoot, "help"), { recursive: true });
|
||||
fs.mkdirSync(path.join(docsRoot, "zh-CN", "help"), { recursive: true });
|
||||
fs.writeFileSync(
|
||||
path.join(docsRoot, "docs.json"),
|
||||
`${JSON.stringify(
|
||||
{
|
||||
navigation: [
|
||||
{
|
||||
language: "en",
|
||||
tabs: [{ tab: "Docs", groups: [{ group: "Help", pages: ["help/testing"] }] }],
|
||||
},
|
||||
{
|
||||
language: "zh-Hans",
|
||||
tabs: [{ tab: "中文", groups: [{ group: "帮助", pages: ["zh-CN/help/testing"] }] }],
|
||||
},
|
||||
],
|
||||
},
|
||||
null,
|
||||
2,
|
||||
)}\n`,
|
||||
"utf8",
|
||||
);
|
||||
fs.writeFileSync(path.join(docsRoot, "help", "testing.md"), "# testing\n", "utf8");
|
||||
fs.writeFileSync(path.join(docsRoot, "zh-CN", "help", "testing.md"), "# 测试\n", "utf8");
|
||||
|
||||
const anchorDocsDir = prepareAnchorAuditDocsDir(docsRoot);
|
||||
try {
|
||||
expect(fs.existsSync(path.join(anchorDocsDir, "help", "testing.md"))).toBe(true);
|
||||
expect(fs.existsSync(path.join(anchorDocsDir, "zh-CN"))).toBe(false);
|
||||
|
||||
const sanitizedDocsJson = JSON.parse(
|
||||
fs.readFileSync(path.join(anchorDocsDir, "docs.json"), "utf8"),
|
||||
);
|
||||
expect(sanitizedDocsJson).toEqual({
|
||||
navigation: [
|
||||
{
|
||||
language: "en",
|
||||
tabs: [{ tab: "Docs", groups: [{ group: "Help", pages: ["help/testing"] }] }],
|
||||
},
|
||||
],
|
||||
});
|
||||
} finally {
|
||||
fs.rmSync(anchorDocsDir, { recursive: true, force: true });
|
||||
fs.rmSync(fixtureRoot, { recursive: true, force: true });
|
||||
}
|
||||
});
|
||||
|
||||
it("prefers a local mint binary for anchor validation", () => {
|
||||
let invocation:
|
||||
| {
|
||||
@@ -46,9 +152,17 @@ describe("docs-link-audit", () => {
|
||||
options: { cwd: string; stdio: string };
|
||||
}
|
||||
| undefined;
|
||||
let cleanedDir: string | undefined;
|
||||
const anchorDocsDir = path.join(os.tmpdir(), "docs-link-audit-anchor");
|
||||
|
||||
const exitCode = runDocsLinkAuditCli({
|
||||
args: ["--anchors"],
|
||||
prepareAnchorAuditDocsDirImpl() {
|
||||
return anchorDocsDir;
|
||||
},
|
||||
cleanupAnchorAuditDocsDirImpl(dir) {
|
||||
cleanedDir = dir;
|
||||
},
|
||||
spawnSyncImpl(command, args, options) {
|
||||
invocation = { command, args, options };
|
||||
return { status: 0 };
|
||||
@@ -60,7 +174,8 @@ describe("docs-link-audit", () => {
|
||||
expect(invocation?.command).toBe("mint");
|
||||
expect(invocation?.args).toEqual(["broken-links", "--check-anchors"]);
|
||||
expect(invocation?.options.stdio).toBe("inherit");
|
||||
expect(path.basename(invocation?.options.cwd ?? "")).toBe("docs");
|
||||
expect(invocation?.options.cwd).toBe(anchorDocsDir);
|
||||
expect(cleanedDir).toBe(anchorDocsDir);
|
||||
});
|
||||
|
||||
it("falls back to pnpm dlx when mint is not on PATH", () => {
|
||||
@@ -69,9 +184,17 @@ describe("docs-link-audit", () => {
|
||||
args: string[];
|
||||
options: { cwd: string; stdio: string };
|
||||
}> = [];
|
||||
let cleanedDir: string | undefined;
|
||||
const anchorDocsDir = path.join(os.tmpdir(), "docs-link-audit-anchor");
|
||||
|
||||
const exitCode = runDocsLinkAuditCli({
|
||||
args: ["--anchors"],
|
||||
prepareAnchorAuditDocsDirImpl() {
|
||||
return anchorDocsDir;
|
||||
},
|
||||
cleanupAnchorAuditDocsDirImpl(dir) {
|
||||
cleanedDir = dir;
|
||||
},
|
||||
spawnSyncImpl(command, args, options) {
|
||||
invocations.push({ command, args, options });
|
||||
if (command === "mint") {
|
||||
@@ -93,7 +216,8 @@ describe("docs-link-audit", () => {
|
||||
args: ["dlx", "mint", "broken-links", "--check-anchors"],
|
||||
options: { stdio: "inherit" },
|
||||
});
|
||||
expect(path.basename(invocations[0]?.options.cwd ?? "")).toBe("docs");
|
||||
expect(path.basename(invocations[1]?.options.cwd ?? "")).toBe("docs");
|
||||
expect(invocations[0]?.options.cwd).toBe(anchorDocsDir);
|
||||
expect(invocations[1]?.options.cwd).toBe(anchorDocsDir);
|
||||
expect(cleanedDir).toBe(anchorDocsDir);
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user