main
diff_render_test.go
Eric Bower
·
2026-09-14
1package main
2
3import (
4 "strings"
5 "testing"
6
7 "github.com/alecthomas/chroma/v2/styles"
8 git "github.com/gogs/git-module"
9)
10
11func TestFormatDiffHunkGo(t *testing.T) {
12 section := &git.DiffSection{
13 Lines: []*git.DiffLine{
14 {Type: git.DiffLineSection, Content: "@@ -1,5 +1,6 @@"},
15 {Type: git.DiffLinePlain, Content: " package main", LeftLine: 1, RightLine: 1},
16 {Type: git.DiffLinePlain, Content: " ", LeftLine: 2, RightLine: 2},
17 {Type: git.DiffLineDelete, Content: "-func OldFunction() int {", LeftLine: 3},
18 {Type: git.DiffLineAdd, Content: "+func NewFunction() string {", RightLine: 3},
19 {Type: git.DiffLineAdd, Content: "+\t// added comment", RightLine: 4},
20 {Type: git.DiffLinePlain, Content: " \treturn 42", LeftLine: 4, RightLine: 5},
21 {Type: git.DiffLinePlain, Content: " }", LeftLine: 5, RightLine: 6},
22 },
23 }
24
25 theme := styles.Get("dracula")
26 anchor := "diff-main.go-hunk-0"
27 htmlOut, err := FormatDiffHunk(theme, "main.go", section, anchor)
28 if err != nil {
29 t.Fatalf("FormatDiffHunk: %v", err)
30 }
31
32 // Verify table structure
33 if !strings.Contains(htmlOut, "diff-table") {
34 t.Errorf("expected diff-table class in output")
35 }
36 if !strings.Contains(htmlOut, "diff-line-hunk") {
37 t.Errorf("expected diff-line-hunk class in output")
38 }
39
40 // Verify line number and diff overlays
41 if !strings.Contains(htmlOut, "diff-line-add") {
42 t.Errorf("expected diff-line-add class in output")
43 }
44 if !strings.Contains(htmlOut, "diff-line-delete") {
45 t.Errorf("expected diff-line-delete class in output")
46 }
47 if !strings.Contains(htmlOut, "diff-line-context") {
48 t.Errorf("expected diff-line-context class in output")
49 }
50
51 // Verify gutter markers
52 if !strings.Contains(htmlOut, "<td class=\"diff-gutter\">+</td>") {
53 t.Errorf("expected '+' in gutter")
54 }
55 if !strings.Contains(htmlOut, "<td class=\"diff-gutter\">-</td>") {
56 t.Errorf("expected '-' in gutter")
57 }
58
59 // Verify anchor links in line numbers
60 if !strings.Contains(htmlOut, `id="diff-main.go-hunk-0-L3"`) {
61 t.Errorf("expected deleted line anchor id in output, got:\n%s", htmlOut)
62 }
63 if !strings.Contains(htmlOut, `href="#diff-main.go-hunk-0-L3"`) {
64 t.Errorf("expected deleted line anchor href in output, got:\n%s", htmlOut)
65 }
66 if !strings.Contains(htmlOut, `id="diff-main.go-hunk-0-R3"`) {
67 t.Errorf("expected added line anchor id in output, got:\n%s", htmlOut)
68 }
69 if !strings.Contains(htmlOut, `href="#diff-main.go-hunk-0-R3"`) {
70 t.Errorf("expected added line anchor href in output, got:\n%s", htmlOut)
71 }
72
73 // Verify syntax highlighting (Chroma classes for Go keywords / comments)
74 if !strings.Contains(htmlOut, "class=\"kd\"") && !strings.Contains(htmlOut, "class=\"k\"") {
75 t.Errorf("expected keyword chroma class (kd or k) for 'func' or 'package', got:\n%s", htmlOut)
76 }
77 if !strings.Contains(htmlOut, "class=\"c1\"") && !strings.Contains(htmlOut, "class=\"c\"") {
78 t.Errorf("expected comment chroma class (c1 or c) for '// added comment', got:\n%s", htmlOut)
79 }
80}
81
82func TestFormatDiffHunkZig(t *testing.T) {
83 section := &git.DiffSection{
84 Lines: []*git.DiffLine{
85 {Type: git.DiffLineSection, Content: "@@ -1,4 +1,5 @@"},
86 {Type: git.DiffLinePlain, Content: " const std = @import(\"std\");", LeftLine: 1, RightLine: 1},
87 {Type: git.DiffLinePlain, Content: " ", LeftLine: 2, RightLine: 2},
88 {Type: git.DiffLineDelete, Content: "-pub fn main() void {", LeftLine: 3},
89 {Type: git.DiffLineAdd, Content: "+pub fn main() !void {", RightLine: 3},
90 {Type: git.DiffLineAdd, Content: "+ // zig comment", RightLine: 4},
91 {Type: git.DiffLinePlain, Content: " }", LeftLine: 4, RightLine: 5},
92 },
93 }
94
95 htmlOut, err := FormatDiffHunk(nil, "src/main.zig", section, "diff-main.zig-hunk-0")
96 if err != nil {
97 t.Fatalf("FormatDiffHunk: %v", err)
98 }
99
100 // Verify Zig syntax highlighting tokens
101 if !strings.Contains(htmlOut, "class=\"k\"") && !strings.Contains(htmlOut, "class=\"kd\"") {
102 t.Errorf("expected keyword class for 'pub' or 'fn' or 'const', got:\n%s", htmlOut)
103 }
104 if !strings.Contains(htmlOut, "diff-line-add") {
105 t.Errorf("expected diff-line-add in zig diff")
106 }
107 if !strings.Contains(htmlOut, `href="#diff-main.zig-hunk-0-R3"`) {
108 t.Errorf("expected anchor link in zig diff, got:\n%s", htmlOut)
109 }
110}
111
112func TestFormatDiffHunkFallback(t *testing.T) {
113 section := &git.DiffSection{
114 Lines: []*git.DiffLine{
115 {Type: git.DiffLineSection, Content: "@@ -1,2 +1,2 @@"},
116 {Type: git.DiffLineDelete, Content: "-foo", LeftLine: 1},
117 {Type: git.DiffLineAdd, Content: "+bar", RightLine: 1},
118 },
119 }
120
121 // Unknown extension should not error and still render diff table correctly
122 htmlOut, err := FormatDiffHunk(nil, "unknown.xyz", section, "")
123 if err != nil {
124 t.Fatalf("FormatDiffHunk: %v", err)
125 }
126
127 if !strings.Contains(htmlOut, "diff-table") {
128 t.Errorf("expected diff-table class in output")
129 }
130 if !strings.Contains(htmlOut, "diff-line-add") {
131 t.Errorf("expected diff-line-add in unknown file diff")
132 }
133}
134
135func TestFormatDiffFile(t *testing.T) {
136 file := &git.DiffFile{
137 Name: "test.go",
138 Sections: []*git.DiffSection{
139 {
140 Lines: []*git.DiffLine{
141 {Type: git.DiffLineSection, Content: "@@ -1,2 +1,2 @@"},
142 {Type: git.DiffLineDelete, Content: "-package old", LeftLine: 1},
143 {Type: git.DiffLineAdd, Content: "+package new", RightLine: 1},
144 },
145 },
146 },
147 }
148
149 htmlOut, err := FormatDiffFile(nil, file)
150 if err != nil {
151 t.Fatalf("FormatDiffFile: %v", err)
152 }
153
154 if !strings.Contains(htmlOut, "diff-test.go-hunk-0") {
155 t.Errorf("expected hunk anchor in file diff")
156 }
157 if !strings.Contains(htmlOut, "diff-line-add") {
158 t.Errorf("expected diff-line-add")
159 }
160}