1import { describe, expect, it } from "@effect/vitest";
2
3import { commitMessageToEditor, editorToCommitMessage } from "./jj.ts";
4
5describe("commit message editor form", () => {
6 it.each([
7 ["title only", "feat: title", "feat: title"],
8 ["title and body", "feat: title\n\nbody", "feat: title\nbody"],
9 ["body with blank lines", "fix: x\n\none\n\ntwo\n\n\nthree", "fix: x\none\n\ntwo\n\n\nthree"],
10 [
11 "trailers",
12 "feat: x\n\nbody\n\nAssisted-by: claude-opus-5.5\nAssisted-by: gpt-6.1-sol",
13 "feat: x\nbody\n\nAssisted-by: claude-opus-5.5\nAssisted-by: gpt-6.1-sol",
14 ],
15 ["empty", "", ""],
16 ])("round-trips %s", (_, description, editor) => {
17 expect(commitMessageToEditor(description)).toBe(editor);
18 expect(editorToCommitMessage(editor)).toBe(description);
19 });
20
21 it("drops trailing newlines and whitespace", () => {
22 expect(commitMessageToEditor("feat: title\n\nbody\n")).toBe("feat: title\nbody");
23 expect(editorToCommitMessage("feat: title\nbody \n\n")).toBe("feat: title\n\nbody");
24 expect(editorToCommitMessage("feat: title\n")).toBe("feat: title");
25 });
26
27 it("collapses blank lines typed between title and body into one separator", () => {
28 expect(editorToCommitMessage("feat: title\n\n\nbody")).toBe("feat: title\n\nbody");
29 });
30
31 it("keeps a body whose title is empty", () => {
32 expect(editorToCommitMessage("\nbody")).toBe("\n\nbody");
33 expect(commitMessageToEditor("\n\nbody")).toBe("\nbody");
34 });
35});