import { describe, expect, it } from "vitest"; import { composeQuery, defaultSourceBranch, defaultTargetBranch, parseSource, sortBranchesByRecency, sourceBranchChoices } from "$lib/api/pullCompose"; import type { BranchEntry } from "$lib/api/repo"; const branch = (name: string, when?: string, isDefault = false): BranchEntry => ({ reference: { name, hash: `hash-${name}` }, commit: when ? { Committer: { Name: "n", Email: "e", When: when } } : undefined, is_default: isDefault }); // main is the default; feat is the newest of the rest const branches = [ branch("main", "2024-01-01T00:00:00Z", true), branch("old", "2024-01-02T00:00:00Z"), branch("feat", "2024-03-01T00:00:00Z") ]; const names = (list: BranchEntry[]) => list.map((entry) => entry.reference.name); describe("sortBranchesByRecency", () => { it("puts the newest commit first", () => { expect(names(sortBranchesByRecency(branches))).toEqual(["feat", "old", "main"]); }); it("sinks branches with no commit without reordering them", () => { const list = [ branch("empty-a"), branch("dated", "2024-01-01T00:00:00Z"), branch("empty-b") ]; expect(names(sortBranchesByRecency(list))).toEqual(["dated", "empty-a", "empty-b"]); }); }); describe("sourceBranchChoices", () => { it("drops the default branch and sorts the rest", () => { expect(names(sourceBranchChoices(branches))).toEqual(["feat", "old"]); }); }); describe("defaultTargetBranch", () => { it("keeps a value that names a real branch", () => { expect(defaultTargetBranch(branches, "old")).toBe("old"); }); it("falls back to the default branch when the value is unknown or absent", () => { expect(defaultTargetBranch(branches, "gone")).toBe("main"); expect(defaultTargetBranch(branches, "")).toBe("main"); }); it("gives up when no branch is marked default", () => { expect(defaultTargetBranch([branch("a", "2024-01-01T00:00:00Z")], "")).toBe(""); }); }); describe("defaultSourceBranch", () => { const choices = sourceBranchChoices(branches); const forkBranches = [ branch("fork-old", "2024-01-01T00:00:00Z"), branch("fork-new", "2024-05-01T00:00:00Z") ]; it("picks the most recent non-default branch", () => { expect(defaultSourceBranch("branch", "", choices, [])).toBe("feat"); }); it("replaces a value that is not a candidate", () => { // main is the default branch, so it never appears in the source list expect(defaultSourceBranch("branch", "main", choices, [])).toBe("feat"); }); it("keeps a value that is a candidate", () => { expect(defaultSourceBranch("branch", "old", choices, [])).toBe("old"); }); it("reads the fork's branches in fork mode", () => { expect(defaultSourceBranch("fork", "", choices, forkBranches)).toBe("fork-old"); expect(defaultSourceBranch("fork", "fork-new", choices, forkBranches)).toBe("fork-new"); // a branch of the target repo is not a candidate against a fork expect(defaultSourceBranch("fork", "feat", choices, forkBranches)).toBe("fork-old"); }); it("leaves the value alone in patch mode", () => { expect(defaultSourceBranch("patch", "whatever", choices, forkBranches)).toBe("whatever"); }); it("returns nothing when there are no candidates", () => { expect(defaultSourceBranch("branch", "feat", [], [])).toBe(""); }); }); describe("parseSource", () => { it("accepts the three modes case-insensitively", () => { expect(parseSource("branch")).toBe("branch"); expect(parseSource("FORK")).toBe("fork"); expect(parseSource("patch")).toBe("patch"); }); it("rejects anything else", () => { expect(parseSource("")).toBeNull(); expect(parseSource(null)).toBeNull(); expect(parseSource("stack")).toBeNull(); }); }); describe("composeQuery", () => { it("omits the default source and a fork picked outside fork mode", () => { expect( composeQuery({ source: "branch", sourceBranch: "feat", targetBranch: "main", fork: "did:x" }) ).toBe("sourceBranch=feat&targetBranch=main"); }); it("carries the fork only in fork mode", () => { expect( composeQuery({ source: "fork", sourceBranch: "feat", targetBranch: "main", fork: "did:x" }) ).toBe("source=fork&sourceBranch=feat&targetBranch=main&fork=did%3Ax"); }); it("is empty when nothing is selected", () => { expect( composeQuery({ source: "branch", sourceBranch: "", targetBranch: "", fork: "" }) ).toBe(""); }); });