package main import ( "os" "os/exec" "path/filepath" "testing" ) func TestParseHunkNewRange(t *testing.T) { cases := []struct { header string wantStart int wantCount int }{ {"@@ -1,2 +3,4 @@", 3, 4}, {"@@ -0,0 +1 @@", 1, 1}, // no ,count on the + side → count 1 {"@@ -5,0 +6,3 @@ func Foo() {", 6, 3}, // trailing context after @@ {"@@ -1 +1 @@", 1, 1}, {"not a hunk", 0, 0}, } for _, c := range cases { start, count := parseHunkNewRange(c.header) if start != c.wantStart || count != c.wantCount { t.Errorf("parseHunkNewRange(%q) = (%d,%d), want (%d,%d)", c.header, start, count, c.wantStart, c.wantCount) } } } func TestParseUnifiedDiffRecordsAddedLines(t *testing.T) { diff := "diff --git a/foo.go b/foo.go\n" + "--- a/foo.go\n" + "+++ b/foo.go\n" + "@@ -10,0 +11,2 @@\n" + "+added one\n" + "+added two\n" rd := &repoDiff{changed: map[string]map[int]bool{}, untracked: map[string]bool{}} parseUnifiedDiff(diff, rd) lines := rd.changed["foo.go"] if !lines[11] || !lines[12] { t.Fatalf("expected lines 11,12 changed, got %#v", lines) } if lines[10] || lines[13] { t.Fatalf("unexpected extra changed lines: %#v", lines) } } func TestDiffIndexIsChangedTracksWorkingTreeEdits(t *testing.T) { repo := t.TempDir() runGit := func(args ...string) { t.Helper() cmd := exec.Command("git", append([]string{"-C", repo}, args...)...) if out, err := cmd.CombinedOutput(); err != nil { t.Fatalf("git %v: %v\n%s", args, err, out) } } runGit("init") runGit("config", "user.email", "test@example.com") runGit("config", "user.name", "test") committed := filepath.Join(repo, "committed.go") if err := os.WriteFile(committed, []byte("package p\n\nvar a int\nvar b int\n"), 0o644); err != nil { t.Fatal(err) } runGit("add", "committed.go") runGit("commit", "-m", "init") // Unstaged edit: append a line to the committed file. if err := os.WriteFile(committed, []byte("package p\n\nvar a int\nvar b int\nvar c int\n"), 0o644); err != nil { t.Fatal(err) } // Untracked new file. untracked := filepath.Join(repo, "new.go") if err := os.WriteFile(untracked, []byte("package p\n\nvar d int\n"), 0o644); err != nil { t.Fatal(err) } idx := newDiffIndex() if idx.isChanged(committed, 3) { t.Errorf("line 3 (unchanged, committed) should not be reported as changed") } if !idx.isChanged(committed, 5) { t.Errorf("line 5 (the unstaged append) should be reported as changed") } if !idx.isChanged(untracked, 1) || !idx.isChanged(untracked, 3) { t.Errorf("all lines of an untracked file should be reported as changed") } } func TestDiffIndexIsChangedOutsideRepoIsFalse(t *testing.T) { dir := t.TempDir() // not a git repo f := filepath.Join(dir, "x.go") if err := os.WriteFile(f, []byte("package p\n"), 0o644); err != nil { t.Fatal(err) } idx := newDiffIndex() if idx.isChanged(f, 1) { t.Errorf("files outside any git repo must not be reported as changed") } }