mirror of
https://seed.radicle.dev/rad:z4D5UCArafTzTQpDZNQRuqswh3ury.git
synced 2026-11-03 18:40:29 +08:00
145 lines
4.2 KiB
TypeScript
145 lines
4.2 KiB
TypeScript
import type { Commit } from "@bindings/repo/Commit";
|
|
|
|
import { describe, expect, test } from "vitest";
|
|
|
|
import {
|
|
groupCommitsByAuthor,
|
|
isCommitListDescription,
|
|
replaceDescriptionBody,
|
|
revisionTitle,
|
|
splitDescription,
|
|
visibleCommitsOf,
|
|
} from "@app/lib/revisionDescription";
|
|
|
|
import { revision } from "./support/cobs";
|
|
|
|
function commit(id: string, summary = id, name = "Alice"): Commit {
|
|
const person = { name, email: `${name}@x`, time: 0 };
|
|
return {
|
|
id,
|
|
author: person,
|
|
committer: person,
|
|
summary,
|
|
message: summary,
|
|
parents: [],
|
|
};
|
|
}
|
|
|
|
describe("splitDescription", () => {
|
|
test.each([
|
|
["", {}],
|
|
[" ", {}],
|
|
["Subject", { subject: "Subject" }],
|
|
[" Subject \n\n Body text ", { subject: "Subject", body: "Body text" }],
|
|
["Subject\n", { subject: "Subject" }],
|
|
])("splits %j into %j", (text, expected) => {
|
|
expect(splitDescription(text)).toEqual(expected);
|
|
});
|
|
});
|
|
|
|
describe("replaceDescriptionBody", () => {
|
|
test.each([
|
|
["Subject\n\nold", "Subject\n\nnew"],
|
|
["Subject\nold", "Subject\nnew"],
|
|
["Subject\r\n\r\nold\r\n", "Subject\r\n\r\nnew\r\n"],
|
|
[" Subject \n\n old \n", " Subject \n\n new \n"],
|
|
])("keeps the subject and spacing of %j", (description, expected) => {
|
|
expect(replaceDescriptionBody(description, "new")).toBe(expected);
|
|
});
|
|
|
|
test("replaces the body even when the subject contains its text", () => {
|
|
expect(replaceDescriptionBody("Fix old\n\nold", "new")).toBe(
|
|
"Fix old\n\nnew",
|
|
);
|
|
});
|
|
|
|
test("adds a body to a description that has none", () => {
|
|
expect(replaceDescriptionBody("Subject", "new")).toBe("Subject\n\nnew");
|
|
});
|
|
|
|
test("leaves an empty description as just the body", () => {
|
|
expect(replaceDescriptionBody("", "new")).toBe("new");
|
|
});
|
|
});
|
|
|
|
test("revisionTitle is the first line of the current description", () => {
|
|
const edit = (body: string) => ({
|
|
author: revision().author,
|
|
timestamp: 0,
|
|
body,
|
|
});
|
|
|
|
expect(
|
|
revisionTitle(revision({ description: [edit("Old"), edit("New\nbody")] })),
|
|
).toBe("New");
|
|
expect(revisionTitle(revision({ description: [] }))).toBeUndefined();
|
|
expect(
|
|
revisionTitle(revision({ description: [edit(" \n ")] })),
|
|
).toBeUndefined();
|
|
});
|
|
|
|
describe("isCommitListDescription", () => {
|
|
const commits = [commit("a", "Add a"), commit("b", "Fix b")];
|
|
|
|
test("matches a description that lists the commit summaries", () => {
|
|
expect(isCommitListDescription("Add a\nFix b", commits)).toBe(true);
|
|
expect(isCommitListDescription(" Fix b\n\nAdd a ", commits)).toBe(true);
|
|
});
|
|
|
|
test.each([
|
|
["Add a", "a line is missing"],
|
|
["Add a\nFix b\nMore", "there is an extra line"],
|
|
["Add a\nSomething else", "a line isn't a summary"],
|
|
])("doesn't match %j because %s", description => {
|
|
expect(isCommitListDescription(description, commits)).toBe(false);
|
|
});
|
|
|
|
test("doesn't match without commits", () => {
|
|
expect(isCommitListDescription("", [])).toBe(false);
|
|
expect(isCommitListDescription("Add a", undefined)).toBe(false);
|
|
});
|
|
});
|
|
|
|
test("groupCommitsByAuthor groups consecutive commits by author name", () => {
|
|
const groups = groupCommitsByAuthor([
|
|
commit("1", "1", "Alice"),
|
|
commit("2", "2", "Alice"),
|
|
commit("3", "3", "Bob"),
|
|
commit("4", "4", "Alice"),
|
|
]);
|
|
|
|
expect(groups.map(g => g.map(c => c.id))).toEqual([["1", "2"], ["3"], ["4"]]);
|
|
});
|
|
|
|
describe("visibleCommitsOf", () => {
|
|
const group = (n: number) =>
|
|
Array.from({ length: n }, (_, i) => commit(`${i}`));
|
|
|
|
test("shows a short group in full", () => {
|
|
expect(visibleCommitsOf(group(5), false)).toMatchObject({
|
|
collapsed: false,
|
|
hiddenCount: 0,
|
|
});
|
|
expect(visibleCommitsOf(group(5), false).visible).toHaveLength(5);
|
|
});
|
|
|
|
test("collapses a long group to its first three", () => {
|
|
const { collapsed, visible, hiddenCount } = visibleCommitsOf(
|
|
group(6),
|
|
false,
|
|
);
|
|
|
|
expect(collapsed).toBe(true);
|
|
expect(visible.map(c => c.id)).toEqual(["0", "1", "2"]);
|
|
expect(hiddenCount).toBe(3);
|
|
});
|
|
|
|
test("shows a long group in full once expanded", () => {
|
|
expect(visibleCommitsOf(group(6), true)).toMatchObject({
|
|
collapsed: false,
|
|
hiddenCount: 0,
|
|
});
|
|
expect(visibleCommitsOf(group(6), true).visible).toHaveLength(6);
|
|
});
|
|
});
|