1package diff
2
3import (
4 "strings"
5 "testing"
6
7 "github.com/sergi/go-diff/diffmatchpatch"
8)
9
10func TestSplitLines_Empty(t *testing.T) {
11 lines := splitLines("")
12 if len(lines) != 0 {
13 t.Errorf("expected 0 lines, got %d", len(lines))
14 }
15}
16
17func TestSplitLines_Single(t *testing.T) {
18 lines := splitLines("hello")
19 if len(lines) != 1 || lines[0] != "hello" {
20 t.Errorf("unexpected: %v", lines)
21 }
22}
23
24func TestSplitLines_Multiple(t *testing.T) {
25 lines := splitLines("a\nb\nc\n")
26 if len(lines) != 3 {
27 t.Fatalf("expected 3, got %d: %v", len(lines), lines)
28 }
29 if lines[0] != "a" || lines[1] != "b" || lines[2] != "c" {
30 t.Errorf("unexpected lines: %v", lines)
31 }
32}
33
34func TestSplitLines_NoTrailingNewline(t *testing.T) {
35 lines := splitLines("a\nb")
36 if len(lines) != 2 {
37 t.Fatalf("expected 2, got %d: %v", len(lines), lines)
38 }
39}
40
41func TestIsPrintable_Text(t *testing.T) {
42 if !isPrintable("hello world\n") {
43 t.Error("plain text should be printable")
44 }
45}
46
47func TestIsPrintable_NullByte(t *testing.T) {
48 if isPrintable("binary\x00data") {
49 t.Error("string with null byte should not be printable")
50 }
51}
52
53func TestIsPrintable_Empty(t *testing.T) {
54 if !isPrintable("") {
55 t.Error("empty string should be printable")
56 }
57}
58
59func TestUnifiedDiff_Equal(t *testing.T) {
60 dmp := diffmatchpatch.New()
61 result := unifiedDiff(dmp, "file.txt", "same content\n", "same content\n")
62 if result != "" {
63 t.Errorf("identical files should produce empty diff, got %q", result)
64 }
65}
66
67func TestUnifiedDiff_AddedFile(t *testing.T) {
68 dmp := diffmatchpatch.New()
69 result := unifiedDiff(dmp, "new.txt", "", "hello\n")
70 if !strings.HasPrefix(result, "--- /dev/null") {
71 t.Errorf("added file should start with --- /dev/null, got: %q", result)
72 }
73 if !strings.Contains(result, "+hello") {
74 t.Errorf("missing +hello in: %q", result)
75 }
76}
77
78func TestUnifiedDiff_DeletedFile(t *testing.T) {
79 dmp := diffmatchpatch.New()
80 result := unifiedDiff(dmp, "old.txt", "goodbye\n", "")
81 if !strings.Contains(result, "+++ /dev/null") {
82 t.Errorf("deleted file should have +++ /dev/null, got: %q", result)
83 }
84 if !strings.Contains(result, "-goodbye") {
85 t.Errorf("missing -goodbye in: %q", result)
86 }
87}
88
89func TestUnifiedDiff_Modified(t *testing.T) {
90 dmp := diffmatchpatch.New()
91 result := unifiedDiff(dmp, "mod.txt", "before\n", "after\n")
92 if !strings.HasPrefix(result, "--- a/mod.txt") {
93 t.Errorf("modified file diff header: %q", result)
94 }
95 if !strings.Contains(result, "+++ b/mod.txt") {
96 t.Errorf("missing +++ header: %q", result)
97 }
98}
99
100func TestUnifiedDiff_Binary(t *testing.T) {
101 dmp := diffmatchpatch.New()
102 result := unifiedDiff(dmp, "data.bin", "text", "\x00binary")
103 if !strings.Contains(result, "binary") {
104 t.Errorf("binary diff should mention binary: %q", result)
105 }
106}
107
108func TestSortFileDiffs(t *testing.T) {
109 diffs := []FileDiff{
110 {Path: "z/file.go", Status: 'M'},
111 {Path: "a/main.go", Status: 'A'},
112 {Path: "m/lib.go", Status: 'D'},
113 }
114 sortFileDiffs(diffs)
115 if diffs[0].Path != "a/main.go" || diffs[1].Path != "m/lib.go" || diffs[2].Path != "z/file.go" {
116 t.Errorf("sort order wrong: %v", diffs)
117 }
118}