65 lines
2.4 KiB
JavaScript
65 lines
2.4 KiB
JavaScript
import { execFile } from "node:child_process";
|
|
import { mkdtemp, mkdir, writeFile } from "node:fs/promises";
|
|
import os from "node:os";
|
|
import path from "node:path";
|
|
import { promisify } from "node:util";
|
|
import { describe, expect, it } from "vitest";
|
|
|
|
const execFileAsync = promisify(execFile);
|
|
const verifierSourcePath = path.resolve("scripts/verify-porting-guide.mjs");
|
|
|
|
async function makeRepo(guideContent) {
|
|
const root = await mkdtemp(path.join(os.tmpdir(), "portingDocs-porting-guide-"));
|
|
await mkdir(path.join(root, "scripts"), { recursive: true });
|
|
await mkdir(path.join(root, "docs"), { recursive: true });
|
|
await writeFile(path.join(root, "scripts/verify-porting-guide.mjs"), await import("node:fs/promises").then((fs) => fs.readFile(verifierSourcePath, "utf8")));
|
|
if (guideContent !== null) await writeFile(path.join(root, "docs/porting-guide.md"), guideContent);
|
|
return root;
|
|
}
|
|
|
|
function validGuide(rowCount = 12) {
|
|
const rows = Array.from({ length: rowCount }, (_, index) => `| legacy-${index} | preferred-${index} | when-${index} | note-${index} |`).join("\n");
|
|
return `# ToolCTRL Documentation Porting Guide
|
|
|
|
## Rename/Replace Map
|
|
|
|
| Legacy | Preferred | Apply in docs when | Notes |
|
|
| --- | --- | --- | --- |
|
|
${rows}
|
|
|
|
## Do-Not-Replace Rules
|
|
|
|
- Keep runtime identifiers stable.
|
|
|
|
## Verification
|
|
|
|
- Run the verifier.
|
|
`;
|
|
}
|
|
|
|
async function runVerifier(root) {
|
|
return execFileAsync(process.execPath, [path.join(root, "scripts/verify-porting-guide.mjs")], { cwd: root });
|
|
}
|
|
|
|
describe("verify-porting-guide", () => {
|
|
it("passes for a complete guide with enough rename-map rows", async () => {
|
|
const root = await makeRepo(validGuide(12));
|
|
|
|
await expect(runVerifier(root)).resolves.toMatchObject({
|
|
stdout: expect.stringContaining("Verified docs/porting-guide.md: 13 Rename/Replace Map table rows."),
|
|
});
|
|
});
|
|
|
|
it("fails when the guide is missing", async () => {
|
|
const root = await makeRepo(null);
|
|
|
|
await expect(runVerifier(root)).rejects.toMatchObject({ stderr: expect.stringContaining("missing docs/porting-guide.md") });
|
|
});
|
|
|
|
it("fails for unresolved markers and underspecified maps", async () => {
|
|
const root = await makeRepo(validGuide(3).replace("- Run the verifier.", "TODO: decide later."));
|
|
|
|
await expect(runVerifier(root)).rejects.toMatchObject({ stderr: expect.stringContaining("unresolved TODO/TBD/FIXME markers") });
|
|
});
|
|
});
|