* Mock gh runtime. Routes by subcommand; records every invocation so tests can * assert on exactly which commands ran (and which didn't).
(opts: {
prDiff: { stdout?: string; stderr?: string; exitCode: number };
files?: { stdout?: string; stderr?: string; exitCode: number };
view?: { stdout?: string; stderr?: string; exitCode: number };
})
| 21 | * assert on exactly which commands ran (and which didn't). |
| 22 | */ |
| 23 | function githubRuntime(opts: { |
| 24 | prDiff: { stdout?: string; stderr?: string; exitCode: number }; |
| 25 | files?: { stdout?: string; stderr?: string; exitCode: number }; |
| 26 | view?: { stdout?: string; stderr?: string; exitCode: number }; |
| 27 | }): { runtime: PRRuntime; calls: string[] } { |
| 28 | const calls: string[] = []; |
| 29 | const runtime: PRRuntime = { |
| 30 | async runCommand(command, args) { |
| 31 | calls.push([command, ...args].join(" ")); |
| 32 | if (args[0] === "pr" && args[1] === "diff") { |
| 33 | return { stdout: opts.prDiff.stdout ?? "", stderr: opts.prDiff.stderr ?? "", exitCode: opts.prDiff.exitCode }; |
| 34 | } |
| 35 | if (args[0] === "pr" && args[1] === "view") { |
| 36 | return { stdout: opts.view?.stdout ?? VIEW_JSON, stderr: opts.view?.stderr ?? "", exitCode: opts.view?.exitCode ?? 0 }; |
| 37 | } |
| 38 | if (args[0] === "repo" && args[1] === "view") { |
| 39 | return { stdout: "main\n", stderr: "", exitCode: 0 }; |
| 40 | } |
| 41 | if (args[0] === "api" && args[1]?.includes("/compare/")) { |
| 42 | return { stdout: `${"c".repeat(40)}\n`, stderr: "", exitCode: 0 }; |
| 43 | } |
| 44 | if (args[0] === "api" && args[1]?.includes("/pulls/123/files")) { |
| 45 | return { stdout: opts.files?.stdout ?? "", stderr: opts.files?.stderr ?? "", exitCode: opts.files?.exitCode ?? 1 }; |
| 46 | } |
| 47 | return { stdout: "", stderr: `unexpected command: ${args.join(" ")}`, exitCode: 1 }; |
| 48 | }, |
| 49 | }; |
| 50 | return { runtime, calls }; |
| 51 | } |
| 52 | |
| 53 | describe("fetchGhPR", () => { |
| 54 | test("uses gh pr diff verbatim when it succeeds and never touches the files API", async () => { |