Files
kandev/apps/web/components/task-create-dialog-pill.test.tsx
T

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");
});
});