1import { assert, describe, it } from "@effect/vitest";
2
3import {
4 gitHubApiHostForRemote,
5 selectGitHubBaseRepository,
6} from "./gitHubRepositoryResolution.ts";
7
8describe("selectGitHubBaseRepository", () => {
9 const remotes = (...entries: ReadonlyArray<readonly [string, string]>) =>
10 entries
11 .flatMap(([name, url]) => [`${name}\t${url} (fetch)`, `${name}\t${url} (push)`])
12 .join("\n");
13 const select = (input: { remotes: string; resolved?: string }) =>
14 selectGitHubBaseRepository({ resolved: "", host: "github.com", ...input });
15
16 it("picks the repository gh reads without a prompt", () => {
17 assert.deepStrictEqual(select({ remotes: remotes(["fork", "git@github.com:me/web.git"]) }), {
18 owner: "me",
19 name: "web",
20 });
21 const fork = remotes(
22 ["origin", "git@github.com:me/web.git"],
23 ["upstream", "https://github.com/Acme/Web.git"],
24 );
25 assert.deepStrictEqual(select({ remotes: fork }), { owner: "acme", name: "web" });
26 assert.deepStrictEqual(select({ remotes: fork, resolved: "remote.origin.gh-resolved base" }), {
27 owner: "me",
28 name: "web",
29 });
30 assert.deepStrictEqual(
31 select({ remotes: fork, resolved: "remote.origin.gh-resolved acme/other" }),
32 { owner: "acme", name: "other" },
33 );
34 // gh ranks remote names in any case.
35 assert.deepStrictEqual(
36 select({
37 remotes: remotes(
38 ["origin", "git@github.com:me/web.git"],
39 ["Upstream", "git@github.com:acme/web.git"],
40 ),
41 }),
42 { owner: "acme", name: "web" },
43 );
44 });
45
46 it("leaves gh to choose when it might weigh the remotes differently", () => {
47 for (const input of [
48 { remotes: "" },
49 {
50 remotes: remotes(["a", "git@github.com:me/web.git"], ["b", "git@github.com:acme/web.git"]),
51 },
52 {
53 remotes: remotes(
54 ["origin", "git@github.com:me/web.git"],
55 ["mirror", "git@gitlab.com:me/web.git"],
56 ),
57 },
58 { remotes: remotes(["origin", "git@github-work:me/web.git"]) },
59 {
60 remotes: remotes(
61 ["origin", "git@github.com:me/web.git"],
62 ["Origin", "git@github.com:acme/web.git"],
63 ),
64 },
65 {
66 remotes: remotes(
67 ["origin", "git@github.com:me/web.git"],
68 ["upstream", "git@github.com:acme/web.git"],
69 ),
70 resolved: "remote.origin.gh-resolved base\nremote.upstream.gh-resolved base",
71 },
72 ]) {
73 assert.strictEqual(select(input), null);
74 }
75 });
76});
77
78describe("gitHubApiHostForRemote", () => {
79 it("reads an SSH alias through github.com and a real host as itself", () => {
80 assert.strictEqual(gitHubApiHostForRemote("git@github:acme/web.git"), "github.com");
81 assert.strictEqual(
82 gitHubApiHostForRemote("git@github.example.com:a/b.git"),
83 "github.example.com",
84 );
85 assert.strictEqual(gitHubApiHostForRemote("git@gitlab.com:a/b.git"), null);
86 });
87});