@@ -4,11 +4,14 @@ import (
44 "bytes"
55 "encoding/binary"
66 "encoding/json"
7+ "fmt"
78 "io"
89 "os"
910 "os/exec"
1011 "reflect"
12+ "strings"
1113 "testing"
14+ "time"
1215)
1316
1417func TestLineOperations (t * testing.T ) {
@@ -395,6 +398,16 @@ Date: Tue Apr 2 22:55:40 2019 -0700
395398 InputFile : "testdata/one_file.patch" ,
396399 Output : []* File {
397400 {
401+ PatchHeader : & PatchHeader {
402+ SHA : "5d9790fec7d95aa223f3d20936340bf55ff3dcbe" ,
403+ Author : & PatchIdentity {
404+ Name : "Morton Haypenny" ,
405+ Email : "mhaypenny@example.com" ,
406+ },
407+ AuthorDate : asTime ("2019-04-02T22:55:40-07:00" ),
408+ Title : "A file with multiple fragments." ,
409+ Body : "The content is arbitrary." ,
410+ },
398411 OldName : "dir/file1.txt" ,
399412 NewName : "dir/file1.txt" ,
400413 OldMode : os .FileMode (0100644 ),
@@ -409,6 +422,16 @@ Date: Tue Apr 2 22:55:40 2019 -0700
409422 InputFile : "testdata/two_files.patch" ,
410423 Output : []* File {
411424 {
425+ PatchHeader : & PatchHeader {
426+ SHA : "5d9790fec7d95aa223f3d20936340bf55ff3dcbe" ,
427+ Author : & PatchIdentity {
428+ Name : "Morton Haypenny" ,
429+ Email : "mhaypenny@example.com" ,
430+ },
431+ AuthorDate : asTime ("2019-04-02T22:55:40-07:00" ),
432+ Title : "A file with multiple fragments." ,
433+ Body : "The content is arbitrary." ,
434+ },
412435 OldName : "dir/file1.txt" ,
413436 NewName : "dir/file1.txt" ,
414437 OldMode : os .FileMode (0100644 ),
@@ -417,6 +440,16 @@ Date: Tue Apr 2 22:55:40 2019 -0700
417440 TextFragments : textFragments ,
418441 },
419442 {
443+ PatchHeader : & PatchHeader {
444+ SHA : "5d9790fec7d95aa223f3d20936340bf55ff3dcbe" ,
445+ Author : & PatchIdentity {
446+ Name : "Morton Haypenny" ,
447+ Email : "mhaypenny@example.com" ,
448+ },
449+ AuthorDate : asTime ("2019-04-02T22:55:40-07:00" ),
450+ Title : "A file with multiple fragments." ,
451+ Body : "The content is arbitrary." ,
452+ },
420453 OldName : "dir/file2.txt" ,
421454 NewName : "dir/file2.txt" ,
422455 OldMode : os .FileMode (0100644 ),
@@ -431,6 +464,15 @@ Date: Tue Apr 2 22:55:40 2019 -0700
431464 InputFile : "testdata/new_binary_file.patch" ,
432465 Output : []* File {
433466 {
467+ PatchHeader : & PatchHeader {
468+ SHA : "5d9790fec7d95aa223f3d20936340bf55ff3dcbe" ,
469+ Author : & PatchIdentity {
470+ Name : "Morton Haypenny" ,
471+ Email : "mhaypenny@example.com" ,
472+ },
473+ AuthorDate : asTime ("2019-04-02T22:55:40-07:00" ),
474+ Title : "A binary file with the first 10 fibonacci numbers." ,
475+ },
434476 OldName : "" ,
435477 NewName : "dir/ten.bin" ,
436478 NewMode : os .FileMode (0100644 ),
@@ -463,7 +505,7 @@ Date: Tue Apr 2 22:55:40 2019 -0700
463505
464506 cmd := exec .Command ("echo" , "hello" )
465507
466- files , err := Parse (cmd , f )
508+ fileChan , err := Parse (cmd , f )
467509 if test .Err {
468510 if err == nil || err == io .EOF {
469511 t .Fatalf ("expected error parsing patch, but got %v" , err )
@@ -473,6 +515,10 @@ Date: Tue Apr 2 22:55:40 2019 -0700
473515 if err != nil {
474516 t .Fatalf ("unexpected error parsing patch: %v" , err )
475517 }
518+ var files []* File
519+ for file := range fileChan {
520+ files = append (files , file )
521+ }
476522
477523 if len (test .Output ) != len (files ) {
478524 t .Fatalf ("incorrect number of parsed files: expected %d, actual %d" , len (test .Output ), len (files ))
@@ -488,10 +534,73 @@ Date: Tue Apr 2 22:55:40 2019 -0700
488534 }
489535}
490536
537+ func BenchmarkParse (b * testing.B ) {
538+ var inputDiff string
539+ {
540+ builder := strings.Builder {}
541+ builder .WriteString (`commit 5d9790fec7d95aa223f3d20936340bf55ff3dcbe
542+ Author: Morton Haypenny <mhaypenny@example.com>
543+ Date: Tue Apr 2 22:55:40 2019 -0700
544+
545+ A file with multiple fragments.
546+
547+ The content is arbitrary.
548+
549+ ` )
550+ fileDiff := func (i int ) string {
551+ return fmt .Sprintf (`diff --git a/dir/file%[1]d.txt b/dir/file%[1]d.txt
552+ index ebe9fa54..fe103e1d 100644
553+ --- a/dir/file%[1]d.txt
554+ +++ b/dir/file%[1]d.txt
555+ @@ -3,6 +3,8 @@ fragment 1
556+ context line
557+ -old line 1
558+ -old line 2
559+ context line
560+ +new line 1
561+ +new line 2
562+ +new line 3
563+ context line
564+ -old line 3
565+ +new line 4
566+ +new line 5
567+ @@ -31,2 +33,2 @@ fragment 2
568+ context line
569+ -old line 4
570+ +new line 6
571+ ` , i )
572+ }
573+ for i := 0 ; i < 1000 ; i ++ {
574+ _ , err := builder .WriteString (fileDiff (i ))
575+ if err != nil {
576+ panic (err )
577+ }
578+ }
579+ inputDiff = builder .String ()
580+ }
581+ for i := 0 ; i < b .N ; i ++ {
582+ reader := io .NopCloser (strings .NewReader (inputDiff ))
583+ ch , err := Parse (& exec.Cmd {}, reader )
584+ if err != nil {
585+ panic (err )
586+ }
587+ for range ch {
588+ }
589+ }
590+ }
591+
491592func newTestParser (input string , init bool ) * parser {
492593 p := newParser (bytes .NewBufferString (input ))
493594 if init {
494595 _ = p .Next ()
495596 }
496597 return p
497598}
599+
600+ func asTime (s string ) time.Time {
601+ t , err := time .Parse (time .RFC3339 , s )
602+ if err != nil {
603+ panic (err )
604+ }
605+ return t
606+ }
0 commit comments