Skip to content
104 linesCodeBlameRaw
1import assert from "node:assert/strict";
2import { test } from "node:test";
3
4import type { BranchDrifts, Commit } from "@g1t/contracts";
5
6import { activeBranches, branchesToRead } from "./branches.ts";
7
8const commit = (hash: string, at: string, message = `${hash}\n\nbody`): Commit => ({
9 hash,
10 treeHash: `t${hash}`,
11 message,
12 author: { name: "Ada", email: "ada@example.com" },
13 parents: [],
14 authoredAt: at,
15});
16
17const branches = [
18 { name: "main", hash: "m3" },
19 { name: "old", hash: "o1" },
20 { name: "fix", hash: "f2" },
21 { name: "idea", hash: "i1" },
22];
23const pulls = [{ branch: "fix", number: 7, title: "Fix it", checkStatus: "passed" as const, status: "open" as const }];
24
25test("branches with an open pull request are read first, the default branch never", () => {
26 const read = branchesToRead({ defaultBranch: "main", branches, pulls }, 2);
27 assert.deepEqual(read.reading.map((b) => b.name), ["fix", "old"]);
28 assert.equal(read.total, 3);
29 assert.equal(read.mainHead, "m3");
30});
31
32test("no default branch head, nothing to measure against", () => {
33 assert.equal(branchesToRead({ defaultBranch: "trunk", branches, pulls: [] }, 10).mainHead, null);
34});
35
36test("each branch gets its measured commit and drift, newest first, by head hash", () => {
37 const measured: BranchDrifts = {
38 base: commit("m3", "2026-10-08T00:00:00Z"),
39 branches: [
40 { head: "f2", commit: commit("f2", "2026-10-07T00:00:00Z"), drift: { ahead: 2, behind: 1 } },
41 { head: "o1", commit: commit("o1", "2026-01-01T00:00:00Z"), drift: null },
42 { head: "i1", commit: commit("i1", "2026-10-08T00:00:00Z", "one line"), drift: { ahead: 1, behind: 0 } },
43 ],
44 };
45 const { reading } = branchesToRead({ defaultBranch: "main", branches, pulls }, 10);
46 const shown = activeBranches(reading, measured, { pulls, previews: [{ number: 7, url: "https://fix.g1t.page" }] });
47 assert.deepEqual(shown.map((b) => b.name), ["idea", "fix", "old"]);
48 assert.deepEqual(shown[1], {
49 name: "fix",
50 // No accounts given: the name on the commit, and never its address.
51 commit: { hash: "f2", message: "f2", author: { kind: "author", name: "Ada", username: null, avatar: null }, coAuthors: [], at: "2026-10-07T00:00:00Z" },
52 drift: { ahead: 2, behind: 1 },
53 pull: { number: 7, title: "Fix it", checkStatus: "passed", draft: false },
54 preview: "https://fix.g1t.page",
55 });
56 assert.equal(shown[2]?.drift, null);
57});
58
59test("when repos could not answer, the branches still show, without commits or counts", () => {
60 const { reading } = branchesToRead({ defaultBranch: "main", branches, pulls: [] }, 10);
61 const shown = activeBranches(reading, null, { pulls: [], previews: [] });
62 assert.equal(shown.length, 3);
63 assert.ok(shown.every((b) => b.commit == null && b.drift == null && b.pull == null));
64});
65
66test("repos' answer, as its JSON reads, keeps every count (flagon-io/hello's farewell)", () => {
67 // What services/repos serializes for `branch_drift` (drift.rs
68 // `the_answer_has_the_names_the_site_reads`): a name that differs here
69 // would drop every count without an error.
70 const wire = JSON.stringify({
71 base: {
72 hash: "8407eba",
73 treeHash: "t1",
74 message: "Use farewell() in the --both call",
75 author: { name: "g1t agent", email: "agent@example.com" },
76 parents: ["ac45e10"],
77 authoredAt: "2026-10-03T09:11:34.000Z",
78 },
79 branches: [
80 {
81 head: "bab14ff",
82 commit: {
83 hash: "bab14ff",
84 treeHash: "t2",
85 message: "Add a farewell\n\nbody",
86 author: { name: "syntaqx", email: "s@example.com" },
87 parents: ["c2ef68d"],
88 authoredAt: "2026-10-02T07:52:16.000Z",
89 },
90 drift: { ahead: 1, behind: 41 },
91 },
92 ],
93 });
94 const measured = JSON.parse(wire) as BranchDrifts;
95 const shown = activeBranches([{ name: "farewell", hash: "bab14ff" }], measured, { pulls: [], previews: [] });
96 assert.deepEqual(shown[0]?.drift, { ahead: 1, behind: 41 });
97 assert.deepEqual(shown[0]?.commit, {
98 hash: "bab14ff",
99 message: "Add a farewell",
100 author: { kind: "author", name: "syntaqx", username: null, avatar: null },
101 coAuthors: [],
102 at: "2026-10-02T07:52:16.000Z",
103 });
104});