fork of go-gitdiff with jj support
at v0.5.0 12 kB view raw
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 expectedBodyAppendix := "CC: Joe Smith <joe.smith@company.com>" 143 144 tests := map[string]struct { 145 Input string 146 Header PatchHeader 147 Err interface{} 148 }{ 149 "prettyShort": { 150 Input: `commit 61f5cd90bed4d204ee3feb3aa41ee91d4734855b 151Author: Morton Haypenny <mhaypenny@example.com> 152 153 A sample commit to test header parsing 154`, 155 Header: PatchHeader{ 156 SHA: expectedSHA, 157 Author: expectedIdentity, 158 Title: expectedTitle, 159 }, 160 }, 161 "prettyMedium": { 162 Input: `commit 61f5cd90bed4d204ee3feb3aa41ee91d4734855b 163Author: Morton Haypenny <mhaypenny@example.com> 164Date: Sat Apr 11 15:21:23 2020 -0700 165 166 A sample commit to test header parsing 167 168 The medium format shows the body, which 169 may wrap on to multiple lines. 170 171 Another body line. 172`, 173 Header: PatchHeader{ 174 SHA: expectedSHA, 175 Author: expectedIdentity, 176 AuthorDate: expectedDate, 177 Title: expectedTitle, 178 Body: expectedBody, 179 }, 180 }, 181 "prettyFull": { 182 Input: `commit 61f5cd90bed4d204ee3feb3aa41ee91d4734855b 183Author: Morton Haypenny <mhaypenny@example.com> 184Commit: Morton Haypenny <mhaypenny@example.com> 185 186 A sample commit to test header parsing 187 188 The medium format shows the body, which 189 may wrap on to multiple lines. 190 191 Another body line. 192`, 193 Header: PatchHeader{ 194 SHA: expectedSHA, 195 Author: expectedIdentity, 196 Committer: expectedIdentity, 197 Title: expectedTitle, 198 Body: expectedBody, 199 }, 200 }, 201 "prettyFuller": { 202 Input: `commit 61f5cd90bed4d204ee3feb3aa41ee91d4734855b 203Author: Morton Haypenny <mhaypenny@example.com> 204AuthorDate: Sat Apr 11 15:21:23 2020 -0700 205Commit: Morton Haypenny <mhaypenny@example.com> 206CommitDate: Sat Apr 11 15:21:23 2020 -0700 207 208 A sample commit to test header parsing 209 210 The medium format shows the body, which 211 may wrap on to multiple lines. 212 213 Another body line. 214`, 215 Header: PatchHeader{ 216 SHA: expectedSHA, 217 Author: expectedIdentity, 218 AuthorDate: expectedDate, 219 Committer: expectedIdentity, 220 CommitterDate: expectedDate, 221 Title: expectedTitle, 222 Body: expectedBody, 223 }, 224 }, 225 "prettyAppendix": { 226 Input: `commit 61f5cd90bed4d204ee3feb3aa41ee91d4734855b 227Author: Morton Haypenny <mhaypenny@example.com> 228AuthorDate: Sat Apr 11 15:21:23 2020 -0700 229Commit: Morton Haypenny <mhaypenny@example.com> 230CommitDate: Sat Apr 11 15:21:23 2020 -0700 231 232 A sample commit to test header parsing 233 234 The medium format shows the body, which 235 may wrap on to multiple lines. 236 237 Another body line. 238 --- 239 CC: Joe Smith <joe.smith@company.com> 240`, 241 Header: PatchHeader{ 242 SHA: expectedSHA, 243 Author: expectedIdentity, 244 AuthorDate: expectedDate, 245 Committer: expectedIdentity, 246 CommitterDate: expectedDate, 247 Title: expectedTitle, 248 Body: expectedBody + "\n---\n" + expectedBodyAppendix, 249 }, 250 }, 251 "mailbox": { 252 Input: `From 61f5cd90bed4d204ee3feb3aa41ee91d4734855b Mon Sep 17 00:00:00 2001 253From: Morton Haypenny <mhaypenny@example.com> 254Date: Sat, 11 Apr 2020 15:21:23 -0700 255Subject: [PATCH] A sample commit to test header parsing 256 257The medium format shows the body, which 258may wrap on to multiple lines. 259 260Another body line. 261`, 262 Header: PatchHeader{ 263 SHA: expectedSHA, 264 Author: expectedIdentity, 265 AuthorDate: expectedDate, 266 Title: expectedTitle, 267 Body: expectedBody, 268 }, 269 }, 270 "mailboxAppendix": { 271 Input: `From 61f5cd90bed4d204ee3feb3aa41ee91d4734855b Mon Sep 17 00:00:00 2001 272From: Morton Haypenny <mhaypenny@example.com> 273Date: Sat, 11 Apr 2020 15:21:23 -0700 274Subject: [PATCH] A sample commit to test header parsing 275 276The medium format shows the body, which 277may wrap on to multiple lines. 278 279Another body line. 280--- 281CC: Joe Smith <joe.smith@company.com> 282`, 283 Header: PatchHeader{ 284 SHA: expectedSHA, 285 Author: expectedIdentity, 286 AuthorDate: expectedDate, 287 Title: expectedTitle, 288 Body: expectedBody, 289 BodyAppendix: expectedBodyAppendix, 290 }, 291 }, 292 "unwrapTitle": { 293 Input: `commit 61f5cd90bed4d204ee3feb3aa41ee91d4734855b 294Author: Morton Haypenny <mhaypenny@example.com> 295Date: Sat Apr 11 15:21:23 2020 -0700 296 297 A sample commit to test header parsing with a long 298 title that is wrapped. 299`, 300 Header: PatchHeader{ 301 SHA: expectedSHA, 302 Author: expectedIdentity, 303 AuthorDate: expectedDate, 304 Title: expectedTitle + " with a long title that is wrapped.", 305 }, 306 }, 307 "normalizeBodySpace": { 308 Input: `commit 61f5cd90bed4d204ee3feb3aa41ee91d4734855b 309Author: Morton Haypenny <mhaypenny@example.com> 310Date: Sat Apr 11 15:21:23 2020 -0700 311 312 A sample commit to test header parsing 313 314 315 The medium format shows the body, which 316 may wrap on to multiple lines. 317 318 319 Another body line. 320 321 322`, 323 Header: PatchHeader{ 324 SHA: expectedSHA, 325 Author: expectedIdentity, 326 AuthorDate: expectedDate, 327 Title: expectedTitle, 328 Body: expectedBody, 329 }, 330 }, 331 "ignoreLeadingBlankLines": { 332 Input: ` 333 334` + " " + ` 335commit 61f5cd90bed4d204ee3feb3aa41ee91d4734855b 336Author: Morton Haypenny <mhaypenny@example.com> 337 338 A sample commit to test header parsing 339`, 340 Header: PatchHeader{ 341 SHA: expectedSHA, 342 Author: expectedIdentity, 343 Title: expectedTitle, 344 }, 345 }, 346 } 347 348 for name, test := range tests { 349 t.Run(name, func(t *testing.T) { 350 h, err := ParsePatchHeader(test.Input) 351 if test.Err != nil { 352 assertError(t, test.Err, err, "parsing patch header") 353 return 354 } 355 if err != nil { 356 t.Fatalf("unexpected error parsing patch header: %v", err) 357 } 358 if h == nil { 359 t.Fatalf("expected non-nil header, but got nil") 360 } 361 362 exp := test.Header 363 act := *h 364 365 if exp.SHA != act.SHA { 366 t.Errorf("incorrect parsed SHA: expected %q, actual %q", exp.SHA, act.SHA) 367 } 368 369 assertPatchIdentity(t, "author", exp.Author, act.Author) 370 if !exp.AuthorDate.Equal(act.AuthorDate) { 371 t.Errorf("incorrect parsed author date: expected %v, but got %v", exp.AuthorDate, act.AuthorDate) 372 } 373 374 assertPatchIdentity(t, "committer", exp.Committer, act.Committer) 375 if !exp.CommitterDate.Equal(act.CommitterDate) { 376 t.Errorf("incorrect parsed committer date: expected %v, but got %v", exp.CommitterDate, act.CommitterDate) 377 } 378 379 if exp.Title != act.Title { 380 t.Errorf("incorrect parsed title:\n expected: %q\n actual: %q", exp.Title, act.Title) 381 } 382 if exp.Body != act.Body { 383 t.Errorf("incorrect parsed body:\n expected: %q\n actual: %q", exp.Body, act.Body) 384 } 385 if exp.BodyAppendix != act.BodyAppendix { 386 t.Errorf("incorrect parsed body appendix:\n expected: %q\n actual: %q", 387 exp.BodyAppendix, act.BodyAppendix) 388 } 389 }) 390 } 391} 392 393func assertPatchIdentity(t *testing.T, kind string, exp, act *PatchIdentity) { 394 switch { 395 case exp == nil && act == nil: 396 case exp == nil && act != nil: 397 t.Errorf("incorrect parsed %s: expected nil, but got %+v", kind, act) 398 case exp != nil && act == nil: 399 t.Errorf("incorrect parsed %s: expected %+v, but got nil", kind, exp) 400 case exp.Name != act.Name || exp.Email != act.Email: 401 t.Errorf("incorrect parsed %s, expected %+v, bot got %+v", kind, exp, act) 402 } 403} 404 405func TestCleanupSubject(t *testing.T) { 406 exp := "A sample commit to test header parsing" 407 tests := map[string]string{ 408 "plain": "", 409 "patch": "[PATCH] ", 410 "patchv5": "[PATCH v5] ", 411 "patchrfc": "[PATCH RFC] ", 412 "patchnospace": "[PATCH]", 413 "space": " ", 414 "re": "re: ", 415 "Re": "Re: ", 416 "RE": "rE: ", 417 "rere": "re: re: ", 418 } 419 420 for name, prefix := range tests { 421 gotprefix, gottitle := parseSubject(prefix + exp) 422 if gottitle != exp { 423 t.Errorf("%s: Incorrect parsing of prefix %s: got title %s, wanted %s", 424 name, prefix, gottitle, exp) 425 } 426 if gotprefix != prefix { 427 t.Errorf("%s: Incorrect parsing of prefix %s: got prefix %s", 428 name, prefix, gotprefix) 429 } 430 } 431 432 moretests := map[string]struct { 433 in, eprefix, etitle string 434 }{ 435 "Reimplement": {"Reimplement something", "", "Reimplement something"}, 436 "patch-reimplement": {"[PATCH v5] Reimplement something", "[PATCH v5] ", "Reimplement something"}, 437 "Openbracket": {"[Just to annoy people", "", "[Just to annoy people"}, 438 } 439 440 for name, test := range moretests { 441 prefix, title := parseSubject(test.in) 442 if title != test.etitle { 443 t.Errorf("%s: Incorrect parsing of %s: got title %s, wanted %s", 444 name, test.in, title, test.etitle) 445 } 446 if prefix != test.eprefix { 447 t.Errorf("%s: Incorrect parsing of %s: got prefix %s, wanted %s", 448 name, test.in, title, test.etitle) 449 } 450 } 451}