87 lines
3.0 KiB
TypeScript
87 lines
3.0 KiB
TypeScript
import { describe, it, expect } from "vitest";
|
|
import type { Branch } from "@/lib/types/http";
|
|
import { sortBranches, branchToOption, computeBranchPlaceholder } from "./task-create-dialog-pill";
|
|
|
|
function localBranch(name: string): Branch {
|
|
return { name, type: "local" } as Branch;
|
|
}
|
|
|
|
function remoteBranch(name: string, remote = "origin"): Branch {
|
|
return { name, type: "remote", remote } as Branch;
|
|
}
|
|
|
|
describe("sortBranches", () => {
|
|
it("lifts main before master before develop before other branches", () => {
|
|
const sorted = sortBranches([
|
|
localBranch("feature/a"),
|
|
localBranch("develop"),
|
|
localBranch("master"),
|
|
localBranch("main"),
|
|
]);
|
|
expect(sorted.map((b) => b.name)).toEqual(["main", "master", "develop", "feature/a"]);
|
|
});
|
|
|
|
it("puts local before remote when both have the same preferred name", () => {
|
|
const sorted = sortBranches([remoteBranch("main"), localBranch("main")]);
|
|
expect(sorted.map((b) => b.type)).toEqual(["local", "remote"]);
|
|
});
|
|
|
|
it("leaves non-preferred branches in their original relative order", () => {
|
|
const sorted = sortBranches([
|
|
localBranch("feature/zeta"),
|
|
localBranch("feature/alpha"),
|
|
localBranch("feature/middle"),
|
|
]);
|
|
expect(sorted.map((b) => b.name)).toEqual(["feature/zeta", "feature/alpha", "feature/middle"]);
|
|
});
|
|
|
|
it("does not mutate the input array", () => {
|
|
const input = [localBranch("feature/a"), localBranch("main")];
|
|
const snapshot = input.map((b) => b.name);
|
|
sortBranches(input);
|
|
expect(input.map((b) => b.name)).toEqual(snapshot);
|
|
});
|
|
});
|
|
|
|
describe("branchToOption keywords", () => {
|
|
function keywords(b: Branch): string[] {
|
|
return branchToOption(b).keywords ?? [];
|
|
}
|
|
|
|
it("includes the leaf segment for slash-prefixed branches", () => {
|
|
expect(keywords(localBranch("feat/scope/thing"))).toContain("thing");
|
|
});
|
|
|
|
it("splits on slashes, dots, underscores, and hyphens", () => {
|
|
const kw = keywords(localBranch("feat/scope.thing_with-dash"));
|
|
expect(kw).toEqual(expect.arrayContaining(["feat", "scope", "thing", "with", "dash"]));
|
|
});
|
|
|
|
it("includes the remote name when present", () => {
|
|
expect(keywords(remoteBranch("main", "upstream"))).toContain("upstream");
|
|
});
|
|
|
|
it("dedupes repeated segments", () => {
|
|
const kw = keywords(localBranch("foo/foo"));
|
|
expect(kw.filter((k) => k === "foo")).toHaveLength(1);
|
|
});
|
|
});
|
|
|
|
describe("computeBranchPlaceholder", () => {
|
|
it("returns 'branch' when no repo is selected", () => {
|
|
expect(computeBranchPlaceholder(false, false, 0)).toBe("branch");
|
|
});
|
|
|
|
it("returns 'loading…' while branches are loading", () => {
|
|
expect(computeBranchPlaceholder(true, true, 0)).toBe("loading…");
|
|
});
|
|
|
|
it("returns 'no branches' when loaded but the list is empty", () => {
|
|
expect(computeBranchPlaceholder(true, false, 0)).toBe("no branches");
|
|
});
|
|
|
|
it("returns 'branch' as the default with options available", () => {
|
|
expect(computeBranchPlaceholder(true, false, 3)).toBe("branch");
|
|
});
|
|
});
|