cloudflare/pint

Public

mirrored from https://github.com/cloudflare/pintAvailable

CodeCommitsIssuesPull requestsActionsInsightsSecurity
v0.80.0

Branches

Tags

  • No tags available.
0Branches0Tags
Go to file
Add file
Code

Clone

HTTPS

Download ZIP

internal/git/git_test.go

361lines · modecode

1package git_test
2
3import (
4 "errors"
5 "fmt"
6 "regexp"
7 "strconv"
8 "strings"
9 "testing"
10
11 "github.com/stretchr/testify/require"
12
13 "github.com/cloudflare/pint/internal/git"
14)
15
16func blameLine(sha string, line, prevLine int, filename, content string) string {
17 return fmt.Sprintf(`%s %d %d 1
18author Alice Mock
19author-mail <alice@example.com>
20author-time 1559927997
21author-tz 0000
22committer Alice Mock
23committer-mail <alice@example.com>
24committer-time 1559927997
25committer-tz 0000
26summary Mock commit title
27boundary
28filename %s
29 %s
30`, sha, prevLine, line, filename, content)
31}
32
33func TestGitBlame(t *testing.T) {
34 type testCaseT struct {
35 mock git.CommandRunner
36 path string
37 output git.LineBlames
38 shouldError bool
39 }
40
41 testCases := []testCaseT{
42 {
43 mock: func(_ ...string) ([]byte, error) {
44 return nil, nil
45 },
46 path: "foo.txt",
47 output: nil,
48 },
49 {
50 mock: func(_ ...string) ([]byte, error) {
51 return nil, errors.New("mock error")
52 },
53 shouldError: true,
54 },
55 {
56 mock: func(_ ...string) ([]byte, error) {
57 // Line exceeds scanner buffer size, triggers scanner.Err()
58 longLine := strings.Repeat("a", 65537)
59 return []byte(longLine), nil
60 },
61 shouldError: true,
62 },
63 {
64 mock: func(_ ...string) ([]byte, error) {
65 // Line with less than 3 parts
66 return []byte("abc123 1\n"), nil
67 },
68 shouldError: true,
69 },
70 {
71 mock: func(_ ...string) ([]byte, error) {
72 // Invalid prev line number
73 return []byte("abc123 notanumber 1 1\n"), nil
74 },
75 shouldError: true,
76 },
77 {
78 mock: func(_ ...string) ([]byte, error) {
79 // Invalid line number
80 return []byte("abc123 1 notanumber 1\n"), nil
81 },
82 shouldError: true,
83 },
84 {
85 mock: func(_ ...string) ([]byte, error) {
86 // Test "previous" line prefix (should be skipped)
87 content := "b33a88cea35abc47f9973983626e1c6f3f3abc44 1 1 1\n" +
88 "author Alice Mock\n" +
89 "previous abc123 foo.txt\n" +
90 "filename foo.txt\n" +
91 "\tcontent\n"
92 return []byte(content), nil
93 },
94 path: "foo.txt",
95 output: git.LineBlames{
96 {
97 Filename: "foo.txt",
98 Line: 1,
99 PrevLine: 1,
100 Commit: "b33a88cea35abc47f9973983626e1c6f3f3abc44",
101 },
102 },
103 },
104 {
105 mock: func(_ ...string) ([]byte, error) {
106 content := blameLine("b33a88cea35abc47f9973983626e1c6f3f3abc44", 1, 1, "foo.txt", "")
107 return []byte(content), nil
108 },
109 path: "foo.txt",
110 output: git.LineBlames{
111 {
112 Filename: "foo.txt",
113 Line: 1,
114 PrevLine: 1,
115 Commit: "b33a88cea35abc47f9973983626e1c6f3f3abc44",
116 },
117 },
118 },
119 {
120 mock: func(_ ...string) ([]byte, error) {
121 content := blameLine("b33a88cea35abc47f9973983626e1c6f3f3abc44", 1, 5, "foo.txt", "")
122 return []byte(content), nil
123 },
124 path: "foo.txt",
125 output: git.LineBlames{
126 {
127 Filename: "foo.txt",
128 Line: 1,
129 PrevLine: 5,
130 Commit: "b33a88cea35abc47f9973983626e1c6f3f3abc44",
131 },
132 },
133 },
134 {
135 mock: func(_ ...string) ([]byte, error) {
136 content := blameLine("b33a88cea35abc47f9973983626e1c6f3f3abc44", 1, 1, "foo.txt", "") +
137 blameLine("b33a88cea35abc47f9973983626e1c6f3f3abc44", 2, 2, "foo.txt", "") +
138 blameLine("82987dec74ba8e434ba393d83491ace784473291", 3, 3, "foo.txt", "") +
139 blameLine("b33a88cea35abc47f9973983626e1c6f3f3abc44", 4, 4, "bar.txt", "")
140 return []byte(content), nil
141 },
142 path: "foo.txt",
143 output: git.LineBlames{
144 {
145 Filename: "foo.txt",
146 Line: 1,
147 PrevLine: 1,
148 Commit: "b33a88cea35abc47f9973983626e1c6f3f3abc44",
149 },
150 {
151 Filename: "foo.txt",
152 Line: 2,
153 PrevLine: 2,
154 Commit: "b33a88cea35abc47f9973983626e1c6f3f3abc44",
155 },
156 {
157 Filename: "foo.txt",
158 Line: 3,
159 PrevLine: 3,
160 Commit: "82987dec74ba8e434ba393d83491ace784473291",
161 },
162 {
163 Filename: "bar.txt",
164 Line: 4,
165 PrevLine: 4,
166 Commit: "b33a88cea35abc47f9973983626e1c6f3f3abc44",
167 },
168 },
169 },
170 }
171
172 for i, tc := range testCases {
173 t.Run(strconv.Itoa(i), func(t *testing.T) {
174 output, err := git.Blame(tc.mock, tc.path, "")
175
176 hadError := (err != nil)
177 if hadError != tc.shouldError {
178 t.Errorf("git.Blame() returned err=%v, expected=%v", err, tc.shouldError)
179 return
180 }
181
182 require.Equal(t, tc.output, output, "git.Blame() returned wrong output ")
183 })
184 }
185}
186
187func TestCurrentBranch(t *testing.T) {
188 type testCaseT struct {
189 mock git.CommandRunner
190 output string
191 shouldError bool
192 }
193
194 testCases := []testCaseT{
195 {
196 mock: func(_ ...string) ([]byte, error) {
197 return nil, errors.New("mock error")
198 },
199 output: "",
200 shouldError: true,
201 },
202 {
203 mock: func(_ ...string) ([]byte, error) {
204 return []byte(""), nil
205 },
206 output: "",
207 shouldError: false,
208 },
209 {
210 mock: func(_ ...string) ([]byte, error) {
211 return []byte("foo"), nil
212 },
213 output: "foo",
214 },
215 {
216 mock: func(_ ...string) ([]byte, error) {
217 return []byte("foo bar\n"), nil
218 },
219 output: "foo bar",
220 },
221 }
222
223 for i, tc := range testCases {
224 t.Run(strconv.Itoa(i), func(t *testing.T) {
225 output, err := git.CurrentBranch(tc.mock)
226
227 hadError := (err != nil)
228 if hadError != tc.shouldError {
229 t.Errorf("git.CurrentBranch() returned err=%v, expected=%v", err, tc.shouldError)
230 return
231 }
232
233 require.Equal(t, tc.output, output, "git.CurrentBranch() returned wrong output")
234 })
235 }
236}
237
238func TestRunGit(t *testing.T) {
239 type testCaseT struct {
240 output *regexp.Regexp
241 err string
242 args []string
243 }
244
245 testCases := []testCaseT{
246 {
247 args: []string{"version"},
248 output: regexp.MustCompile("^git version"),
249 },
250 {
251 args: []string{"xxx"},
252 err: "git: 'xxx' is not a git command. See 'git --help'.\n",
253 },
254 {
255 // config --get with non-existent key exits with 1 but no stderr
256 args: []string{"config", "--get", "nonexistent.key.that.does.not.exist"},
257 err: "exit status 1",
258 },
259 }
260
261 for _, tc := range testCases {
262 t.Run(strings.Join(tc.args, " "), func(t *testing.T) {
263 output, err := git.RunGit(tc.args...)
264 if tc.err != "" {
265 require.EqualError(t, err, tc.err)
266 } else {
267 require.NoError(t, err)
268 require.Regexp(t, tc.output, string(output))
269 }
270 })
271 }
272}
273
274func TestHeadCommit(t *testing.T) {
275 type testCaseT struct {
276 mock git.CommandRunner
277 output string
278 shouldError bool
279 }
280
281 testCases := []testCaseT{
282 {
283 mock: func(_ ...string) ([]byte, error) {
284 return nil, errors.New("mock error")
285 },
286 output: "",
287 shouldError: true,
288 },
289 {
290 mock: func(_ ...string) ([]byte, error) {
291 return []byte("abc123\n"), nil
292 },
293 output: "abc123",
294 },
295 }
296
297 for i, tc := range testCases {
298 t.Run(strconv.Itoa(i), func(t *testing.T) {
299 output, err := git.HeadCommit(tc.mock)
300
301 hadError := (err != nil)
302 if hadError != tc.shouldError {
303 t.Errorf("git.HeadCommit() returned err=%v, expected=%v", err, tc.shouldError)
304 return
305 }
306
307 require.Equal(t, tc.output, output, "git.HeadCommit() returned wrong output")
308 })
309 }
310}
311
312func TestCommitMessage(t *testing.T) {
313 type testCaseT struct {
314 mock git.CommandRunner
315 output string
316 shouldError bool
317 }
318
319 testCases := []testCaseT{
320 {
321 mock: func(_ ...string) ([]byte, error) {
322 return nil, errors.New("mock error")
323 },
324 output: "",
325 shouldError: true,
326 },
327 {
328 mock: func(_ ...string) ([]byte, error) {
329 return []byte(""), nil
330 },
331 output: "",
332 shouldError: false,
333 },
334 {
335 mock: func(_ ...string) ([]byte, error) {
336 return []byte("foo"), nil
337 },
338 output: "foo",
339 },
340 {
341 mock: func(_ ...string) ([]byte, error) {
342 return []byte("foo bar\n"), nil
343 },
344 output: "foo bar\n",
345 },
346 }
347
348 for i, tc := range testCases {
349 t.Run(strconv.Itoa(i), func(t *testing.T) {
350 output, err := git.CommitMessage(tc.mock, "abc1234567890")
351
352 hadError := (err != nil)
353 if hadError != tc.shouldError {
354 t.Errorf("git.CommitMessage() returned err=%v, expected=%v", err, tc.shouldError)
355 return
356 }
357
358 require.Equal(t, tc.output, output, "git.CommitMessage() returned wrong output")
359 })
360 }
361}
362