fork of go-gitdiff with jj support
1package gitdiff
2
3import (
4 "testing"
5 "time"
6)
7
8func TestParsePatchIdentity(t *testing.T) {
9 tests := map[string]struct {
10 Input string
11 Output PatchIdentity
12 Err interface{}
13 }{
14 "simple": {
15 Input: "Morton Haypenny <mhaypenny@example.com>",
16 Output: PatchIdentity{
17 Name: "Morton Haypenny",
18 Email: "mhaypenny@example.com",
19 },
20 },
21 "extraWhitespace": {
22 Input: " Morton Haypenny <mhaypenny@example.com > ",
23 Output: PatchIdentity{
24 Name: "Morton Haypenny",
25 Email: "mhaypenny@example.com",
26 },
27 },
28 "trailingCharacters": {
29 Input: "Morton Haypenny <mhaypenny@example.com> unrelated garbage",
30 Output: PatchIdentity{
31 Name: "Morton Haypenny",
32 Email: "mhaypenny@example.com",
33 },
34 },
35 "missingName": {
36 Input: "<mhaypenny@example.com>",
37 Err: "invalid identity",
38 },
39 "missingEmail": {
40 Input: "Morton Haypenny",
41 Err: "invalid identity",
42 },
43 "unclosedEmail": {
44 Input: "Morton Haypenny <mhaypenny@example.com",
45 Err: "unclosed email",
46 },
47 }
48
49 for name, test := range tests {
50 t.Run(name, func(t *testing.T) {
51 id, err := ParsePatchIdentity(test.Input)
52 if test.Err != nil {
53 assertError(t, test.Err, err, "parsing identity")
54 return
55 }
56 if err != nil {
57 t.Fatalf("unexpected error parsing identity: %v", err)
58 }
59
60 if test.Output != id {
61 t.Errorf("incorrect identity: expected %#v, actual %#v", test.Output, id)
62 }
63 })
64 }
65}
66
67func TestParsePatchDate(t *testing.T) {
68 expected := time.Date(2020, 4, 9, 8, 7, 6, 0, time.UTC)
69
70 tests := map[string]struct {
71 Input string
72 Output time.Time
73 Err interface{}
74 }{
75 "default": {
76 Input: "Thu Apr 9 01:07:06 2020 -0700",
77 Output: expected,
78 },
79 "defaultLocal": {
80 Input: "Thu Apr 9 01:07:06 2020",
81 Output: time.Date(2020, 4, 9, 1, 7, 6, 0, time.Local),
82 },
83 "iso": {
84 Input: "2020-04-09 01:07:06 -0700",
85 Output: expected,
86 },
87 "isoStrict": {
88 Input: "2020-04-09T01:07:06-07:00",
89 Output: expected,
90 },
91 "rfc": {
92 Input: "Thu, 9 Apr 2020 01:07:06 -0700",
93 Output: expected,
94 },
95 "short": {
96 Input: "2020-04-09",
97 Output: time.Date(2020, 4, 9, 0, 0, 0, 0, time.Local),
98 },
99 "raw": {
100 Input: "1586419626 -0700",
101 Output: expected,
102 },
103 "unix": {
104 Input: "1586419626",
105 Output: expected,
106 },
107 "unknownFormat": {
108 Input: "4/9/2020 01:07:06 PDT",
109 Err: "unknown date format",
110 },
111 "empty": {
112 Input: "",
113 },
114 }
115
116 for name, test := range tests {
117 t.Run(name, func(t *testing.T) {
118 d, err := ParsePatchDate(test.Input)
119 if test.Err != nil {
120 assertError(t, test.Err, err, "parsing date")
121 return
122 }
123 if err != nil {
124 t.Fatalf("unexpected error parsing date: %v", err)
125 }
126 if !test.Output.Equal(d) {
127 t.Errorf("incorrect parsed date: expected %v, actual %v", test.Output, d)
128 }
129 })
130 }
131}
132
133func TestParsePatchHeader(t *testing.T) {
134 expectedSHA := "61f5cd90bed4d204ee3feb3aa41ee91d4734855b"
135 expectedIdentity := &PatchIdentity{
136 Name: "Morton Haypenny",
137 Email: "mhaypenny@example.com",
138 }
139 expectedDate := time.Date(2020, 04, 11, 15, 21, 23, 0, time.FixedZone("PDT", -7*60*60))
140 expectedTitle := "A sample commit to test header parsing"
141 expectedBody := "The medium format shows the body, which\nmay wrap on to multiple lines.\n\nAnother body line."
142
143 tests := map[string]struct {
144 Input string
145 Header PatchHeader
146 Err interface{}
147 }{
148 "prettyShort": {
149 Input: `commit 61f5cd90bed4d204ee3feb3aa41ee91d4734855b
150Author: Morton Haypenny <mhaypenny@example.com>
151
152 A sample commit to test header parsing
153`,
154 Header: PatchHeader{
155 SHA: expectedSHA,
156 Author: expectedIdentity,
157 Title: expectedTitle,
158 },
159 },
160 "prettyMedium": {
161 Input: `commit 61f5cd90bed4d204ee3feb3aa41ee91d4734855b
162Author: Morton Haypenny <mhaypenny@example.com>
163Date: Sat Apr 11 15:21:23 2020 -0700
164
165 A sample commit to test header parsing
166
167 The medium format shows the body, which
168 may wrap on to multiple lines.
169
170 Another body line.
171`,
172 Header: PatchHeader{
173 SHA: expectedSHA,
174 Author: expectedIdentity,
175 AuthorDate: expectedDate,
176 Title: expectedTitle,
177 Body: expectedBody,
178 },
179 },
180 "prettyFull": {
181 Input: `commit 61f5cd90bed4d204ee3feb3aa41ee91d4734855b
182Author: Morton Haypenny <mhaypenny@example.com>
183Commit: Morton Haypenny <mhaypenny@example.com>
184
185 A sample commit to test header parsing
186
187 The medium format shows the body, which
188 may wrap on to multiple lines.
189
190 Another body line.
191`,
192 Header: PatchHeader{
193 SHA: expectedSHA,
194 Author: expectedIdentity,
195 Committer: expectedIdentity,
196 Title: expectedTitle,
197 Body: expectedBody,
198 },
199 },
200 "prettyFuller": {
201 Input: `commit 61f5cd90bed4d204ee3feb3aa41ee91d4734855b
202Author: Morton Haypenny <mhaypenny@example.com>
203AuthorDate: Sat Apr 11 15:21:23 2020 -0700
204Commit: Morton Haypenny <mhaypenny@example.com>
205CommitDate: Sat Apr 11 15:21:23 2020 -0700
206
207 A sample commit to test header parsing
208
209 The medium format shows the body, which
210 may wrap on to multiple lines.
211
212 Another body line.
213`,
214 Header: PatchHeader{
215 SHA: expectedSHA,
216 Author: expectedIdentity,
217 AuthorDate: expectedDate,
218 Committer: expectedIdentity,
219 CommitterDate: expectedDate,
220 Title: expectedTitle,
221 Body: expectedBody,
222 },
223 },
224 "mailbox": {
225 Input: `From 61f5cd90bed4d204ee3feb3aa41ee91d4734855b Mon Sep 17 00:00:00 2001
226From: Morton Haypenny <mhaypenny@example.com>
227Date: Sat, 11 Apr 2020 15:21:23 -0700
228Subject: [PATCH] A sample commit to test header parsing
229
230The medium format shows the body, which
231may wrap on to multiple lines.
232
233Another body line.
234`,
235 Header: PatchHeader{
236 SHA: expectedSHA,
237 Author: expectedIdentity,
238 AuthorDate: expectedDate,
239 Title: "[PATCH] " + expectedTitle,
240 Body: expectedBody,
241 },
242 },
243 "unwrapTitle": {
244 Input: `commit 61f5cd90bed4d204ee3feb3aa41ee91d4734855b
245Author: Morton Haypenny <mhaypenny@example.com>
246Date: Sat Apr 11 15:21:23 2020 -0700
247
248 A sample commit to test header parsing with a long
249 title that is wrapped.
250`,
251 Header: PatchHeader{
252 SHA: expectedSHA,
253 Author: expectedIdentity,
254 AuthorDate: expectedDate,
255 Title: expectedTitle + " with a long title that is wrapped.",
256 },
257 },
258 "normalizeBodySpace": {
259 Input: `commit 61f5cd90bed4d204ee3feb3aa41ee91d4734855b
260Author: Morton Haypenny <mhaypenny@example.com>
261Date: Sat Apr 11 15:21:23 2020 -0700
262
263 A sample commit to test header parsing
264
265
266 The medium format shows the body, which
267 may wrap on to multiple lines.
268
269
270 Another body line.
271
272
273`,
274 Header: PatchHeader{
275 SHA: expectedSHA,
276 Author: expectedIdentity,
277 AuthorDate: expectedDate,
278 Title: expectedTitle,
279 Body: expectedBody,
280 },
281 },
282 "ignoreLeadingBlankLines": {
283 Input: `
284
285` + " " + `
286commit 61f5cd90bed4d204ee3feb3aa41ee91d4734855b
287Author: Morton Haypenny <mhaypenny@example.com>
288
289 A sample commit to test header parsing
290`,
291 Header: PatchHeader{
292 SHA: expectedSHA,
293 Author: expectedIdentity,
294 Title: expectedTitle,
295 },
296 },
297 }
298
299 for name, test := range tests {
300 t.Run(name, func(t *testing.T) {
301 h, err := ParsePatchHeader(test.Input)
302 if test.Err != nil {
303 assertError(t, test.Err, err, "parsing patch header")
304 return
305 }
306 if err != nil {
307 t.Fatalf("unexpected error parsing patch header: %v", err)
308 }
309 if h == nil {
310 t.Fatalf("expected non-nil header, but got nil")
311 }
312
313 exp := test.Header
314 act := *h
315
316 if exp.SHA != act.SHA {
317 t.Errorf("incorrect parsed SHA: expected %q, actual %q", exp.SHA, act.SHA)
318 }
319
320 assertPatchIdentity(t, "author", exp.Author, act.Author)
321 if !exp.AuthorDate.Equal(act.AuthorDate) {
322 t.Errorf("incorrect parsed author date: expected %v, but got %v", exp.AuthorDate, act.AuthorDate)
323 }
324
325 assertPatchIdentity(t, "committer", exp.Committer, act.Committer)
326 if !exp.CommitterDate.Equal(act.CommitterDate) {
327 t.Errorf("incorrect parsed committer date: expected %v, but got %v", exp.CommitterDate, act.CommitterDate)
328 }
329
330 if exp.Title != act.Title {
331 t.Errorf("incorrect parsed title:\n expected: %q\n actual: %q", exp.Title, act.Title)
332 }
333 if exp.Body != act.Body {
334 t.Errorf("incorrect parsed body:\n expected: %q\n actual: %q", exp.Body, act.Body)
335 }
336 })
337 }
338}
339
340func assertPatchIdentity(t *testing.T, kind string, exp, act *PatchIdentity) {
341 switch {
342 case exp == nil && act == nil:
343 case exp == nil && act != nil:
344 t.Errorf("incorrect parsed %s: expected nil, but got %+v", kind, act)
345 case exp != nil && act == nil:
346 t.Errorf("incorrect parsed %s: expected %+v, but got nil", kind, exp)
347 case exp.Name != act.Name || exp.Email != act.Email:
348 t.Errorf("incorrect parsed %s, expected %+v, bot got %+v", kind, exp, act)
349 }
350}