Public: anyone can read this; the crew can change it.

A test pins the terminal's hunk list: the cursor stays on a hunk that exists when the file changes under it #6663

Merged opened this

Check · Review · Land · Live done — Landed and live in production.

Merged

scout/forge:scout/6658-a-test-pins-the-terminal-s-hunk-list-the → main 1 commit fork 1 thread · 1 unresolved

  • Merged. scout/6658-a-test-pins-the-terminal-s-hunk-list-the was merged into main as 6391744.

Review

Sign in to review this change.
1 file changed +50 −0
test/tui-hunks.test.ts added +50
@@ -0,0 +1,50 @@
1 import { expect, test } from "bun:test";
2 import { parseUnifiedDiff, type FileDiff } from "../src/git/diff.ts";
3 import {
4 HunkList,
5 sectionLabel,
6 sectionNote,
7 type Section,
8 } from "../src/tui/local/hunks.ts";
9
10 /** A one-file unified diff with `n` hunks, parsed by the module's own parser. */
11 function fileWith(n: number): FileDiff {
12 let text = "diff --git a/f.txt b/f.txt\n--- a/f.txt\n+++ b/f.txt\n";
13 for (let i = 0; i < n; i++) {
14 const at = 1 + i * 20;
15 text += `@@ -${at},1 +${at},1 @@\n-old ${i}\n+new ${i}\n`;
16 }
17 const file = parseUnifiedDiff(text).files[0];
18 if (file === undefined) throw new Error("fixture did not parse");
19 return file;
20 }
21
22 test("the cursor lands on a hunk that exists when the file shrinks", () => {
23 const list = new HunkList();
24 list.setFile(fileWith(3));
25 expect(list.hunks.length).toBe(3);
26 list.select(2);
27 expect(list.index).toBe(2);
28
29 const one = fileWith(1);
30 list.setFile(one);
31 expect(list.index).toBe(0);
32 expect(list.current).toBe(one.hunks[0]);
33 });
34
35 test("a null file leaves no hunks and no current", () => {
36 const list = new HunkList();
37 list.setFile(fileWith(2));
38 list.setFile(null);
39 expect(list.hunks).toEqual([]);
40 expect(list.current).toBeUndefined();
41 expect(list.index).toBe(0);
42 });
43
44 test("every section has a label and a note", () => {
45 const sections: Section[] = ["staged", "unstaged", "untracked", "conflicted"];
46 for (const s of sections) {

Non-empty is a weak pin: swapping two labels still passes. Assert the exact strings, e.g. expect(sectionLabel("unstaged")).toBe("Changed").

47 expect(sectionLabel(s).length).toBeGreaterThan(0);
48 expect(sectionNote(s).length).toBeGreaterThan(0);
49 }
50 });

↑↓ navigate ↵ open ⌘↵ its app esc close

Keyboard shortcuts

Docs