Files
pikasTech-unidesk/scripts/gh-route-contract-test.ts
T
2026-05-27 09:24:42 +00:00

67 lines
3.1 KiB
TypeScript

import { GhVirtualFileExecutor, applyPatchToGhBody, parseGhContentRoute } from "./src/gh-route";
function assertCondition(condition: unknown, message: string, detail: unknown = {}): void {
if (!condition) throw new Error(`${message}: ${JSON.stringify(detail)}`);
}
const route = parseGhContentRoute("gh:/pikasTech/HWLAB/503/1");
assertCondition(route.repo === "pikasTech/HWLAB", "route should preserve owner/repo");
assertCondition(route.number === 503, "route should parse issue or PR number");
assertCondition(route.floor === 1, "route should parse first-floor body");
const prListRoute = parseGhContentRoute("gh:/pikasTech/HWLAB/pr");
assertCondition(prListRoute.area === "pr-list" && prListRoute.number === null, "PR directory route should list pull requests", prListRoute);
const prBodyRoute = parseGhContentRoute("gh:/pikasTech/HWLAB/pr/503/1");
assertCondition(prBodyRoute.area === "pr-item" && prBodyRoute.number === 503 && prBodyRoute.floor === 1, "PR body route should parse explicit first floor", prBodyRoute);
const issueListRoute = parseGhContentRoute("gh:/pikasTech/HWLAB/issue");
assertCondition(issueListRoute.area === "issue-list" && issueListRoute.number === null, "issue directory route should list issues", issueListRoute);
const original = [
"# Title",
"",
"- 上线 changelog:",
" - fix: old title only",
" - changed files: 2; +10 / -1; commits: 1",
"",
].join("\n");
const patchResult = await applyPatchToGhBody(original, [
"*** Begin Patch",
"*** Update File: body.md",
"@@",
" - 上线 changelog:",
"- - fix: old title only",
"- - changed files: 2; +10 / -1; commits: 1",
"+ - 修复目标:说明真实用户可见问题。",
"+- 自动 diff 摘要:",
"+ - changed files: 2; +10 / -1; commits: 1",
" ",
"*** End Patch",
].join("\n"));
const patched = patchResult.body;
assertCondition(
patched.includes("- 上线 changelog:\n - 修复目标:说明真实用户可见问题。\n- 自动 diff 摘要:"),
"patch-apply should update the virtual body with apply_patch v2 semantics",
patched,
);
assertCondition(!patched.includes("fix: old title only"), "patch-apply should remove old title-only changelog", patched);
assertCondition(patchResult.applyPatchOutput.includes("Success. Updated the following files:"), "gh route should run through the shared apply-patch v2 engine", patchResult.applyPatchOutput);
const executor = new GhVirtualFileExecutor("hello\n");
const stat = await executor.run(["sh", "-c", "ignored", "unidesk-apply-patch-v2", "stat", "body.md"]);
assertCondition(stat.exitCode === 0 && /^6 [0-9a-f]{64}\n$/u.test(stat.stdout), "virtual file executor should expose apply-patch v2 stat protocol", stat);
console.log(JSON.stringify({
ok: true,
checks: [
"gh:/owner/repo/number/1 route parses to a first-floor GitHub body",
"gh:/owner/repo/pr and gh:/owner/repo/issue directory routes parse",
"gh:/owner/repo/pr/number/1 explicit PR body route parses",
"gh route patch-apply uses the shared apply-patch v2 engine",
"gh virtual file executor exposes the apply-patch v2 low-level file protocol",
],
}, null, 2));