diff options
| author | mo khan <mo@mokhan.ca> | 2026-01-30 17:18:31 -0700 |
|---|---|---|
| committer | mo khan <mo@mokhan.ca> | 2026-01-30 17:18:31 -0700 |
| commit | e4ed0342932b0aa741ee78d9e4fe135eba6e9ca7 (patch) | |
| tree | f1e7f602cb86e78aedf04185b2c2e1428fc5b8f2 /pkg/gitdiff/file_header_test.go | |
| parent | 83be9ddcf82e8a90ea50a9d54c1ebfc3e22ace16 (diff) | |
initial commit
Diffstat (limited to 'pkg/gitdiff/file_header_test.go')
| -rw-r--r-- | pkg/gitdiff/file_header_test.go | 766 |
1 files changed, 0 insertions, 766 deletions
diff --git a/pkg/gitdiff/file_header_test.go b/pkg/gitdiff/file_header_test.go deleted file mode 100644 index ef29833..0000000 --- a/pkg/gitdiff/file_header_test.go +++ /dev/null @@ -1,766 +0,0 @@ -package gitdiff - -import ( - "io" - "os" - "reflect" - "testing" -) - -func TestParseGitFileHeader(t *testing.T) { - tests := map[string]struct { - Input string - Output *File - Err bool - }{ - "fileContentChange": { - Input: `diff --git a/dir/file.txt b/dir/file.txt -index 1c23fcc..40a1b33 100644 ---- a/dir/file.txt -+++ b/dir/file.txt -@@ -2,3 +4,5 @@ -`, - Output: &File{ - OldName: "dir/file.txt", - NewName: "dir/file.txt", - OldMode: os.FileMode(0100644), - OldOIDPrefix: "1c23fcc", - NewOIDPrefix: "40a1b33", - }, - }, - "newFile": { - Input: `diff --git a/dir/file.txt b/dir/file.txt -new file mode 100644 -index 0000000..f5711e4 ---- /dev/null -+++ b/dir/file.txt -`, - Output: &File{ - NewName: "dir/file.txt", - NewMode: os.FileMode(0100644), - OldOIDPrefix: "0000000", - NewOIDPrefix: "f5711e4", - IsNew: true, - }, - }, - "newEmptyFile": { - Input: `diff --git a/empty.txt b/empty.txt -new file mode 100644 -index 0000000..e69de29 -`, - Output: &File{ - NewName: "empty.txt", - NewMode: os.FileMode(0100644), - OldOIDPrefix: "0000000", - NewOIDPrefix: "e69de29", - IsNew: true, - }, - }, - "deleteFile": { - Input: `diff --git a/dir/file.txt b/dir/file.txt -deleted file mode 100644 -index 44cc321..0000000 ---- a/dir/file.txt -+++ /dev/null -`, - Output: &File{ - OldName: "dir/file.txt", - OldMode: os.FileMode(0100644), - OldOIDPrefix: "44cc321", - NewOIDPrefix: "0000000", - IsDelete: true, - }, - }, - "changeMode": { - Input: `diff --git a/file.sh b/file.sh -old mode 100644 -new mode 100755 -`, - Output: &File{ - OldName: "file.sh", - NewName: "file.sh", - OldMode: os.FileMode(0100644), - NewMode: os.FileMode(0100755), - }, - }, - "rename": { - Input: `diff --git a/foo.txt b/bar.txt -similarity index 100% -rename from foo.txt -rename to bar.txt -`, - Output: &File{ - OldName: "foo.txt", - NewName: "bar.txt", - Score: 100, - IsRename: true, - }, - }, - "copy": { - Input: `diff --git a/file.txt b/copy.txt -similarity index 100% -copy from file.txt -copy to copy.txt -`, - Output: &File{ - OldName: "file.txt", - NewName: "copy.txt", - Score: 100, - IsCopy: true, - }, - }, - "missingDefaultFilename": { - Input: `diff --git a/foo.sh b/bar.sh -old mode 100644 -new mode 100755 -`, - Err: true, - }, - "missingNewFilename": { - Input: `diff --git a/file.txt b/file.txt -index 1c23fcc..40a1b33 100644 ---- a/file.txt -`, - Err: true, - }, - "missingOldFilename": { - Input: `diff --git a/file.txt b/file.txt -index 1c23fcc..40a1b33 100644 -+++ b/file.txt -`, - Err: true, - }, - "invalidHeaderLine": { - Input: `diff --git a/file.txt b/file.txt -index deadbeef ---- a/file.txt -+++ b/file.txt -`, - Err: true, - }, - "notGitHeader": { - Input: `--- file.txt -+++ file.txt -@@ -0,0 +1 @@ -`, - Output: nil, - }, - } - - for name, test := range tests { - t.Run(name, func(t *testing.T) { - p := newTestParser(test.Input, true) - - f, err := p.ParseGitFileHeader() - if test.Err { - if err == nil || err == io.EOF { - t.Fatalf("expected error parsing git file header, got %v", err) - } - return - } - if err != nil { - t.Fatalf("unexpected error parsing git file header: %v", err) - } - - if !reflect.DeepEqual(test.Output, f) { - t.Errorf("incorrect file\nexpected: %+v\n actual: %+v", test.Output, f) - } - }) - } -} - -func TestParseTraditionalFileHeader(t *testing.T) { - tests := map[string]struct { - Input string - Output *File - Err bool - }{ - "fileContentChange": { - Input: `--- dir/file_old.txt 2019-03-21 23:00:00.0 -0700 -+++ dir/file_new.txt 2019-03-21 23:30:00.0 -0700 -@@ -0,0 +1 @@ -`, - Output: &File{ - OldName: "dir/file_new.txt", - NewName: "dir/file_new.txt", - }, - }, - "newFile": { - Input: `--- /dev/null 1969-12-31 17:00:00.0 -0700 -+++ dir/file.txt 2019-03-21 23:30:00.0 -0700 -@@ -0,0 +1 @@ -`, - Output: &File{ - NewName: "dir/file.txt", - IsNew: true, - }, - }, - "newFileTimestamp": { - Input: `--- dir/file.txt 1969-12-31 17:00:00.0 -0700 -+++ dir/file.txt 2019-03-21 23:30:00.0 -0700 -@@ -0,0 +1 @@ -`, - Output: &File{ - NewName: "dir/file.txt", - IsNew: true, - }, - }, - "deleteFile": { - Input: `--- dir/file.txt 2019-03-21 23:30:00.0 -0700 -+++ /dev/null 1969-12-31 17:00:00.0 -0700 -@@ -0,0 +1 @@ -`, - Output: &File{ - OldName: "dir/file.txt", - IsDelete: true, - }, - }, - "deleteFileTimestamp": { - Input: `--- dir/file.txt 2019-03-21 23:30:00.0 -0700 -+++ dir/file.txt 1969-12-31 17:00:00.0 -0700 -@@ -0,0 +1 @@ -`, - Output: &File{ - OldName: "dir/file.txt", - IsDelete: true, - }, - }, - "useShortestPrefixName": { - Input: `--- dir/file.txt 2019-03-21 23:00:00.0 -0700 -+++ dir/file.txt~ 2019-03-21 23:30:00.0 -0700 -@@ -0,0 +1 @@ -`, - Output: &File{ - OldName: "dir/file.txt", - NewName: "dir/file.txt", - }, - }, - "notTraditionalHeader": { - Input: `diff --git a/dir/file.txt b/dir/file.txt ---- a/dir/file.txt -+++ b/dir/file.txt -`, - Output: nil, - }, - "noUnifiedFragment": { - Input: `--- dir/file_old.txt 2019-03-21 23:00:00.0 -0700 -+++ dir/file_new.txt 2019-03-21 23:30:00.0 -0700 -context line -+added line -`, - Output: nil, - }, - } - - for name, test := range tests { - t.Run(name, func(t *testing.T) { - p := newTestParser(test.Input, true) - - f, err := p.ParseTraditionalFileHeader() - if test.Err { - if err == nil || err == io.EOF { - t.Fatalf("expected error parsing traditional file header, got %v", err) - } - return - } - if err != nil { - t.Fatalf("unexpected error parsing traditional file header: %v", err) - } - - if !reflect.DeepEqual(test.Output, f) { - t.Errorf("incorrect file\nexpected: %+v\n actual: %+v", test.Output, f) - } - }) - } -} - -func TestCleanName(t *testing.T) { - tests := map[string]struct { - Input string - Drop int - Output string - }{ - "alreadyClean": { - Input: "a/b/c.txt", Output: "a/b/c.txt", - }, - "doubleSlashes": { - Input: "a//b/c.txt", Output: "a/b/c.txt", - }, - "tripleSlashes": { - Input: "a///b/c.txt", Output: "a/b/c.txt", - }, - "dropPrefix": { - Input: "a/b/c.txt", Drop: 2, Output: "c.txt", - }, - "removeDoublesBeforeDrop": { - Input: "a//b/c.txt", Drop: 1, Output: "b/c.txt", - }, - } - - for name, test := range tests { - t.Run(name, func(t *testing.T) { - output := cleanName(test.Input, test.Drop) - if output != test.Output { - t.Fatalf("incorrect output: expected %q, actual %q", test.Output, output) - } - }) - } -} - -func TestParseName(t *testing.T) { - tests := map[string]struct { - Input string - Term byte - Drop int - Output string - N int - Err bool - }{ - "singleUnquoted": { - Input: "dir/file.txt", Output: "dir/file.txt", N: 12, - }, - "singleQuoted": { - Input: `"dir/file.txt"`, Output: "dir/file.txt", N: 14, - }, - "quotedWithEscape": { - Input: `"dir/\"quotes\".txt"`, Output: `dir/"quotes".txt`, N: 20, - }, - "quotedWithSpaces": { - Input: `"dir/space file.txt"`, Output: "dir/space file.txt", N: 20, - }, - "tabTerminator": { - Input: "dir/space file.txt\tfile2.txt", Term: '\t', Output: "dir/space file.txt", N: 18, - }, - "dropPrefix": { - Input: "a/dir/file.txt", Drop: 1, Output: "dir/file.txt", N: 14, - }, - "unquotedWithSpaces": { - Input: "dir/with spaces.txt", Output: "dir/with spaces.txt", N: 19, - }, - "unquotedWithTrailingSpaces": { - Input: "dir/with spaces.space ", Output: "dir/with spaces.space ", N: 23, - }, - "devNull": { - Input: "/dev/null", Term: '\t', Drop: 1, Output: "/dev/null", N: 9, - }, - "newlineSeparates": { - Input: "dir/file.txt\n", Output: "dir/file.txt", N: 12, - }, - "emptyString": { - Input: "", Err: true, - }, - "emptyQuotedString": { - Input: `""`, Err: true, - }, - "unterminatedQuotes": { - Input: `"dir/file.txt`, Err: true, - }, - } - - for name, test := range tests { - t.Run(name, func(t *testing.T) { - output, n, err := parseName(test.Input, test.Term, test.Drop) - if test.Err { - if err == nil || err == io.EOF { - t.Fatalf("expected error parsing name, but got %v", err) - } - return - } - if err != nil { - t.Fatalf("unexpected error parsing name: %v", err) - } - - if output != test.Output { - t.Errorf("incorrect output: expected %q, actual: %q", test.Output, output) - } - if n != test.N { - t.Errorf("incorrect next position: expected %d, actual %d", test.N, n) - } - }) - } -} - -func TestParseGitHeaderData(t *testing.T) { - tests := map[string]struct { - InputFile *File - Line string - DefaultName string - - OutputFile *File - End bool - Err bool - }{ - "fragementEndsParsing": { - Line: "@@ -12,3 +12,2 @@\n", - End: true, - }, - "unknownEndsParsing": { - Line: "GIT binary file\n", - End: true, - }, - "oldFileName": { - Line: "--- a/dir/file.txt\n", - OutputFile: &File{ - OldName: "dir/file.txt", - }, - }, - "oldFileNameDevNull": { - InputFile: &File{ - IsNew: true, - }, - Line: "--- /dev/null\n", - OutputFile: &File{ - IsNew: true, - }, - }, - "oldFileNameInconsistent": { - InputFile: &File{ - OldName: "dir/foo.txt", - }, - Line: "--- a/dir/bar.txt\n", - Err: true, - }, - "oldFileNameExistingCreateMismatch": { - InputFile: &File{ - OldName: "dir/foo.txt", - IsNew: true, - }, - Line: "--- /dev/null\n", - Err: true, - }, - "oldFileNameParsedCreateMismatch": { - InputFile: &File{ - IsNew: true, - }, - Line: "--- a/dir/file.txt\n", - Err: true, - }, - "oldFileNameMissing": { - Line: "--- \n", - Err: true, - }, - "newFileName": { - Line: "+++ b/dir/file.txt\n", - OutputFile: &File{ - NewName: "dir/file.txt", - }, - }, - "newFileNameDevNull": { - InputFile: &File{ - IsDelete: true, - }, - Line: "+++ /dev/null\n", - OutputFile: &File{ - IsDelete: true, - }, - }, - "newFileNameInconsistent": { - InputFile: &File{ - NewName: "dir/foo.txt", - }, - Line: "+++ b/dir/bar.txt\n", - Err: true, - }, - "newFileNameExistingDeleteMismatch": { - InputFile: &File{ - NewName: "dir/foo.txt", - IsDelete: true, - }, - Line: "+++ /dev/null\n", - Err: true, - }, - "newFileNameParsedDeleteMismatch": { - InputFile: &File{ - IsDelete: true, - }, - Line: "+++ b/dir/file.txt\n", - Err: true, - }, - "newFileNameMissing": { - Line: "+++ \n", - Err: true, - }, - "oldMode": { - Line: "old mode 100644\n", - OutputFile: &File{ - OldMode: os.FileMode(0100644), - }, - }, - "oldModeWithTrailingSpace": { - Line: "old mode 100644\r\n", - OutputFile: &File{ - OldMode: os.FileMode(0100644), - }, - }, - "invalidOldMode": { - Line: "old mode rw\n", - Err: true, - }, - "newMode": { - Line: "new mode 100755\n", - OutputFile: &File{ - NewMode: os.FileMode(0100755), - }, - }, - "newModeWithTrailingSpace": { - Line: "new mode 100755\r\n", - OutputFile: &File{ - NewMode: os.FileMode(0100755), - }, - }, - "invalidNewMode": { - Line: "new mode rwx\n", - Err: true, - }, - "deletedFileMode": { - Line: "deleted file mode 100644\n", - DefaultName: "dir/file.txt", - OutputFile: &File{ - OldName: "dir/file.txt", - OldMode: os.FileMode(0100644), - IsDelete: true, - }, - }, - "newFileMode": { - Line: "new file mode 100755\n", - DefaultName: "dir/file.txt", - OutputFile: &File{ - NewName: "dir/file.txt", - NewMode: os.FileMode(0100755), - IsNew: true, - }, - }, - "newFileModeWithTrailingSpace": { - Line: "new file mode 100755\r\n", - DefaultName: "dir/file.txt", - OutputFile: &File{ - NewName: "dir/file.txt", - NewMode: os.FileMode(0100755), - IsNew: true, - }, - }, - "copyFrom": { - Line: "copy from dir/file.txt\n", - OutputFile: &File{ - OldName: "dir/file.txt", - IsCopy: true, - }, - }, - "copyTo": { - Line: "copy to dir/file.txt\n", - OutputFile: &File{ - NewName: "dir/file.txt", - IsCopy: true, - }, - }, - "renameFrom": { - Line: "rename from dir/file.txt\n", - OutputFile: &File{ - OldName: "dir/file.txt", - IsRename: true, - }, - }, - "renameTo": { - Line: "rename to dir/file.txt\n", - OutputFile: &File{ - NewName: "dir/file.txt", - IsRename: true, - }, - }, - "similarityIndex": { - Line: "similarity index 88%\n", - OutputFile: &File{ - Score: 88, - }, - }, - "similarityIndexTooBig": { - Line: "similarity index 9001%\n", - OutputFile: &File{ - Score: 0, - }, - }, - "similarityIndexInvalid": { - Line: "similarity index 12ab%\n", - Err: true, - }, - "indexFullSHA1AndMode": { - Line: "index 79c6d7f7b7e76c75b3d238f12fb1323f2333ba14..04fab916d8f938173cbb8b93469855f0e838f098 100644\n", - OutputFile: &File{ - OldOIDPrefix: "79c6d7f7b7e76c75b3d238f12fb1323f2333ba14", - NewOIDPrefix: "04fab916d8f938173cbb8b93469855f0e838f098", - OldMode: os.FileMode(0100644), - }, - }, - "indexFullSHA1NoMode": { - Line: "index 79c6d7f7b7e76c75b3d238f12fb1323f2333ba14..04fab916d8f938173cbb8b93469855f0e838f098\n", - OutputFile: &File{ - OldOIDPrefix: "79c6d7f7b7e76c75b3d238f12fb1323f2333ba14", - NewOIDPrefix: "04fab916d8f938173cbb8b93469855f0e838f098", - }, - }, - "indexAbbrevSHA1AndMode": { - Line: "index 79c6d7..04fab9 100644\n", - OutputFile: &File{ - OldOIDPrefix: "79c6d7", - NewOIDPrefix: "04fab9", - OldMode: os.FileMode(0100644), - }, - }, - "indexInvalid": { - Line: "index 79c6d7f7b7e76c75b3d238f12fb1323f2333ba14\n", - Err: true, - }, - } - - for name, test := range tests { - t.Run(name, func(t *testing.T) { - var f File - if test.InputFile != nil { - f = *test.InputFile - } - - end, err := parseGitHeaderData(&f, test.Line, test.DefaultName) - if test.Err { - if err == nil || err == io.EOF { - t.Fatalf("expected error parsing header data, but got %v", err) - } - return - } - if err != nil { - t.Fatalf("unexpected error parsing header data: %v", err) - } - - if test.OutputFile != nil && !reflect.DeepEqual(test.OutputFile, &f) { - t.Errorf("incorrect output:\nexpected: %+v\nactual: %+v", test.OutputFile, &f) - } - if end != test.End { - t.Errorf("incorrect end state, expected %t, actual %t", test.End, end) - } - }) - } -} - -func TestParseGitHeaderName(t *testing.T) { - tests := map[string]struct { - Input string - Output string - Err bool - }{ - "twoMatchingNames": { - Input: "a/dir/file.txt b/dir/file.txt", - Output: "dir/file.txt", - }, - "twoDifferentNames": { - Input: "a/dir/foo.txt b/dir/bar.txt", - Output: "", - }, - "matchingNamesWithSpaces": { - Input: "a/dir/file with spaces.txt b/dir/file with spaces.txt", - Output: "dir/file with spaces.txt", - }, - "matchingNamesWithTrailingSpaces": { - Input: "a/dir/spaces b/dir/spaces ", - Output: "dir/spaces ", - }, - "matchingNamesQuoted": { - Input: `"a/dir/\"quotes\".txt" "b/dir/\"quotes\".txt"`, - Output: `dir/"quotes".txt`, - }, - "matchingNamesFirstQuoted": { - Input: `"a/dir/file.txt" b/dir/file.txt`, - Output: "dir/file.txt", - }, - "matchingNamesSecondQuoted": { - Input: `a/dir/file.txt "b/dir/file.txt"`, - Output: "dir/file.txt", - }, - "noSecondName": { - Input: "a/dir/foo.txt", - Output: "", - }, - "noSecondNameQuoted": { - Input: `"a/dir/foo.txt"`, - Output: "", - }, - "invalidName": { - Input: `"a/dir/file.txt b/dir/file.txt`, - Err: true, - }, - } - - for name, test := range tests { - t.Run(name, func(t *testing.T) { - output, err := parseGitHeaderName(test.Input) - if test.Err { - if err == nil { - t.Fatalf("expected error parsing header name, but got nil") - } - return - } - if err != nil { - t.Fatalf("unexpected error parsing header name: %v", err) - } - - if output != test.Output { - t.Errorf("incorrect output: expected %q, actual %q", test.Output, output) - } - }) - } -} - -func TestHasEpochTimestamp(t *testing.T) { - tests := map[string]struct { - Input string - Output bool - }{ - "utcTimestamp": { - Input: "+++ file.txt\t1970-01-01 00:00:00 +0000\n", - Output: true, - }, - "utcZoneWithColon": { - Input: "+++ file.txt\t1970-01-01 00:00:00 +00:00\n", - Output: true, - }, - "utcZoneWithMilliseconds": { - Input: "+++ file.txt\t1970-01-01 00:00:00.000000 +00:00\n", - Output: true, - }, - "westTimestamp": { - Input: "+++ file.txt\t1969-12-31 16:00:00 -0800\n", - Output: true, - }, - "eastTimestamp": { - Input: "+++ file.txt\t1970-01-01 04:00:00 +0400\n", - Output: true, - }, - "noTab": { - Input: "+++ file.txt 1970-01-01 00:00:00 +0000\n", - Output: false, - }, - "invalidFormat": { - Input: "+++ file.txt\t1970-01-01T00:00:00Z\n", - Output: false, - }, - "notEpoch": { - Input: "+++ file.txt\t2019-03-21 12:34:56.789 -0700\n", - Output: false, - }, - "notTimestamp": { - Input: "+++ file.txt\trandom text\n", - Output: false, - }, - "notTimestampShort": { - Input: "+++ file.txt\t0\n", - Output: false, - }, - } - - for name, test := range tests { - t.Run(name, func(t *testing.T) { - output := hasEpochTimestamp(test.Input) - if output != test.Output { - t.Errorf("incorrect output: expected %t, actual %t", test.Output, output) - } - }) - } -} |
