diff options
Diffstat (limited to 'pkg/commands/patch/patch_test.go')
-rw-r--r-- | pkg/commands/patch/patch_test.go | 616 |
1 files changed, 616 insertions, 0 deletions
diff --git a/pkg/commands/patch/patch_test.go b/pkg/commands/patch/patch_test.go new file mode 100644 index 000000000..bc029da0d --- /dev/null +++ b/pkg/commands/patch/patch_test.go @@ -0,0 +1,616 @@ +package patch + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +const simpleDiff = `diff --git a/filename b/filename +index dcd3485..1ba5540 100644 +--- a/filename ++++ b/filename +@@ -1,5 +1,5 @@ + apple +-orange ++grape + ... + ... + ... +` + +const addNewlineToEndOfFile = `diff --git a/filename b/filename +index 80a73f1..e48a11c 100644 +--- a/filename ++++ b/filename +@@ -60,4 +60,4 @@ grape + ... + ... + ... +-last line +\ No newline at end of file ++last line +` + +const removeNewlinefromEndOfFile = `diff --git a/filename b/filename +index e48a11c..80a73f1 100644 +--- a/filename ++++ b/filename +@@ -60,4 +60,4 @@ grape + ... + ... + ... +-last line ++last line +\ No newline at end of file +` + +const twoHunks = `diff --git a/filename b/filename +index e48a11c..b2ab81b 100644 +--- a/filename ++++ b/filename +@@ -1,5 +1,5 @@ + apple +-grape ++orange + ... + ... + ... +@@ -8,6 +8,8 @@ grape + ... + ... + ... ++pear ++lemon + ... + ... + ... +` + +const twoChangesInOneHunk = `diff --git a/filename b/filename +index 9320895..6d79956 100644 +--- a/filename ++++ b/filename +@@ -1,5 +1,5 @@ + apple +-grape ++kiwi + orange +-pear ++banana + lemon +` + +const newFile = `diff --git a/newfile b/newfile +new file mode 100644 +index 0000000..4e680cc +--- /dev/null ++++ b/newfile +@@ -0,0 +1,3 @@ ++apple ++orange ++grape +` + +const addNewlineToPreviouslyEmptyFile = `diff --git a/newfile b/newfile +index e69de29..c6568ea 100644 +--- a/newfile ++++ b/newfile +@@ -0,0 +1 @@ ++new line +\ No newline at end of file +` + +const exampleHunk = `@@ -1,5 +1,5 @@ + apple +-grape ++orange +... +... +... +` + +func TestTransform(t *testing.T) { + type scenario struct { + testName string + filename string + diffText string + firstLineIndex int + lastLineIndex int + reverse bool + expected string + } + + scenarios := []scenario{ + { + testName: "nothing selected", + filename: "filename", + firstLineIndex: -1, + lastLineIndex: -1, + diffText: simpleDiff, + expected: "", + }, + { + testName: "only context selected", + filename: "filename", + firstLineIndex: 5, + lastLineIndex: 5, + diffText: simpleDiff, + expected: "", + }, + { + testName: "whole range selected", + filename: "filename", + firstLineIndex: 0, + lastLineIndex: 11, + diffText: simpleDiff, + expected: `--- a/filename ++++ b/filename +@@ -1,5 +1,5 @@ + apple +-orange ++grape + ... + ... + ... +`, + }, + { + testName: "only removal selected", + filename: "filename", + firstLineIndex: 6, + lastLineIndex: 6, + diffText: simpleDiff, + expected: `--- a/filename ++++ b/filename +@@ -1,5 +1,4 @@ + apple +-orange + ... + ... + ... +`, + }, + { + testName: "only addition selected", + filename: "filename", + firstLineIndex: 7, + lastLineIndex: 7, + diffText: simpleDiff, + expected: `--- a/filename ++++ b/filename +@@ -1,5 +1,6 @@ + apple + orange ++grape + ... + ... + ... +`, + }, + { + testName: "range that extends beyond diff bounds", + filename: "filename", + firstLineIndex: -100, + lastLineIndex: 100, + diffText: simpleDiff, + expected: `--- a/filename ++++ b/filename +@@ -1,5 +1,5 @@ + apple +-orange ++grape + ... + ... + ... +`, + }, + { + testName: "add newline to end of file", + filename: "filename", + firstLineIndex: -100, + lastLineIndex: 100, + diffText: addNewlineToEndOfFile, + expected: `--- a/filename ++++ b/filename +@@ -60,4 +60,4 @@ grape + ... + ... + ... +-last line +\ No newline at end of file ++last line +`, + }, + { + testName: "add newline to end of file, reversed", + filename: "filename", + firstLineIndex: -100, + lastLineIndex: 100, + reverse: true, + diffText: addNewlineToEndOfFile, + expected: `--- a/filename ++++ b/filename +@@ -60,4 +60,4 @@ grape + ... + ... + ... +-last line +\ No newline at end of file ++last line +`, + }, + { + testName: "remove newline from end of file", + filename: "filename", + firstLineIndex: -100, + lastLineIndex: 100, + diffText: removeNewlinefromEndOfFile, + expected: `--- a/filename ++++ b/filename +@@ -60,4 +60,4 @@ grape + ... + ... + ... +-last line ++last line +\ No newline at end of file +`, + }, + { + testName: "remove newline from end of file, reversed", + filename: "filename", + firstLineIndex: -100, + lastLineIndex: 100, + reverse: true, + diffText: removeNewlinefromEndOfFile, + expected: `--- a/filename ++++ b/filename +@@ -60,4 +60,4 @@ grape + ... + ... + ... +-last line ++last line +\ No newline at end of file +`, + }, + { + testName: "remove newline from end of file, removal only", + filename: "filename", + firstLineIndex: 8, + lastLineIndex: 8, + diffText: removeNewlinefromEndOfFile, + expected: `--- a/filename ++++ b/filename +@@ -60,4 +60,3 @@ grape + ... + ... + ... +-last line +`, + }, + { + testName: "remove newline from end of file, removal only, reversed", + filename: "filename", + firstLineIndex: 8, + lastLineIndex: 8, + reverse: true, + diffText: removeNewlinefromEndOfFile, + expected: `--- a/filename ++++ b/filename +@@ -60,5 +60,4 @@ grape + ... + ... + ... +-last line + last line +\ No newline at end of file +`, + }, + { + testName: "remove newline from end of file, addition only", + filename: "filename", + firstLineIndex: 9, + lastLineIndex: 9, + diffText: removeNewlinefromEndOfFile, + expected: `--- a/filename ++++ b/filename +@@ -60,4 +60,5 @@ grape + ... + ... + ... + last line ++last line +\ No newline at end of file +`, + }, + { + testName: "remove newline from end of file, addition only, reversed", + filename: "filename", + firstLineIndex: 9, + lastLineIndex: 9, + reverse: true, + diffText: removeNewlinefromEndOfFile, + expected: `--- a/filename ++++ b/filename +@@ -60,3 +60,4 @@ grape + ... + ... + ... ++last line +\ No newline at end of file +`, + }, + { + testName: "staging two whole hunks", + filename: "filename", + firstLineIndex: -100, + lastLineIndex: 100, + diffText: twoHunks, + expected: `--- a/filename ++++ b/filename +@@ -1,5 +1,5 @@ + apple +-grape ++orange + ... + ... + ... +@@ -8,6 +8,8 @@ grape + ... + ... + ... ++pear ++lemon + ... + ... + ... +`, + }, + { + testName: "staging part of both hunks", + filename: "filename", + firstLineIndex: 7, + lastLineIndex: 15, + diffText: twoHunks, + expected: `--- a/filename ++++ b/filename +@@ -1,5 +1,6 @@ + apple + grape ++orange + ... + ... + ... +@@ -8,6 +9,7 @@ grape + ... + ... + ... ++pear + ... + ... + ... +`, + }, + { + testName: "adding a new file", + filename: "newfile", + firstLineIndex: -100, + lastLineIndex: 100, + diffText: newFile, + expected: `--- a/newfile ++++ b/newfile +@@ -0,0 +1,3 @@ ++apple ++orange ++grape +`, + }, + { + testName: "adding part of a new file", + filename: "newfile", + firstLineIndex: 6, + lastLineIndex: 7, + diffText: newFile, + expected: `--- a/newfile ++++ b/newfile +@@ -0,0 +1,2 @@ ++apple ++orange +`, + }, + { + testName: "adding a new line to a previously empty file", + filename: "newfile", + firstLineIndex: -100, + lastLineIndex: 100, + diffText: addNewlineToPreviouslyEmptyFile, + expected: `--- a/newfile ++++ b/newfile +@@ -0,0 +1 @@ ++new line +\ No newline at end of file +`, + }, + { + testName: "adding a new line to a previously empty file, reversed", + filename: "newfile", + firstLineIndex: -100, + lastLineIndex: 100, + diffText: addNewlineToPreviouslyEmptyFile, + reverse: true, + expected: `--- a/newfile ++++ b/newfile +@@ -0,0 +1 @@ ++new line +\ No newline at end of file +`, + }, + { + testName: "adding part of a hunk", + filename: "filename", + firstLineIndex: 6, + lastLineIndex: 7, + reverse: false, + diffText: twoChangesInOneHunk, + expected: `--- a/filename ++++ b/filename +@@ -1,5 +1,5 @@ + apple +-grape ++kiwi + orange + pear + lemon +`, + }, + { + testName: "adding part of a hunk, reverse", + filename: "filename", + firstLineIndex: 6, + lastLineIndex: 7, + reverse: true, + diffText: twoChangesInOneHunk, + expected: `--- a/filename ++++ b/filename +@@ -1,5 +1,5 @@ + apple +-grape ++kiwi + orange + banana + lemon +`, + }, + } + + for _, s := range scenarios { + s := s + t.Run(s.testName, func(t *testing.T) { + lineIndices := ExpandRange(s.firstLineIndex, s.lastLineIndex) + + result := Parse(s.diffText). + Transform(TransformOpts{ + Reverse: s.reverse, + FileNameOverride: s.filename, + IncludedLineIndices: lineIndices, + }). + FormatPlain() + + assert.Equal(t, s.expected, result) + }) + } +} + +func TestParseAndFormatPlain(t *testing.T) { + scenarios := []struct { + testName string + patchStr string + }{ + { + testName: "simpleDiff", + patchStr: simpleDiff, + }, + { + testName: "addNewlineToEndOfFile", + patchStr: addNewlineToEndOfFile, + }, + { + testName: "removeNewlinefromEndOfFile", + patchStr: removeNewlinefromEndOfFile, + }, + { + testName: "twoHunks", + patchStr: twoHunks, + }, + { + testName: "twoChangesInOneHunk", + patchStr: twoChangesInOneHunk, + }, + { + testName: "newFile", + patchStr: newFile, + }, + { + testName: "addNewlineToPreviouslyEmptyFile", + patchStr: addNewlineToPreviouslyEmptyFile, + }, + { + testName: "exampleHunk", + patchStr: exampleHunk, + }, + } + + for _, s := range scenarios { + s := s + t.Run(s.testName, func(t *testing.T) { + // here we parse the patch, then format it, and ensure the result + // matches the original patch. Note that unified diffs allow omitting + // the new length in a hunk header if the value is 1, and currently we always + // omit the new length in such cases. + patch := Parse(s.patchStr) + result := formatPlain(patch) + assert.Equal(t, s.patchStr, result) + }) + } +} + +func TestLineNumberOfLine(t *testing.T) { + type scenario struct { + testName string + patchStr string + indexes []int + expecteds []int + } + + scenarios := []scenario{ + { + testName: "twoHunks", + patchStr: twoHunks, + // this is really more of a characteristic test than anything. + indexes: []int{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 1000}, + expecteds: []int{1, 1, 1, 1, 1, 1, 2, 2, 3, 4, 5, 8, 8, 9, 10, 11, 12, 13, 14, 15, 15, 15, 15, 15, 15}, + }, + } + + for _, s := range scenarios { + s := s + t.Run(s.testName, func(t *testing.T) { + for i, idx := range s.indexes { + patch := Parse(s.patchStr) + result := patch.LineNumberOfLine(idx) + assert.Equal(t, s.expecteds[i], result) + } + }) + } +} + +func TestGetNextStageableLineIndex(t *testing.T) { + type scenario struct { + testName string + patchStr string + indexes []int + expecteds []int + } + + scenarios := []scenario{ + { + testName: "twoHunks", + patchStr: twoHunks, + indexes: []int{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 1000}, + expecteds: []int{6, 6, 6, 6, 6, 6, 6, 7, 15, 15, 15, 15, 15, 15, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16, 16}, + }, + } + + for _, s := range scenarios { + s := s + t.Run(s.testName, func(t *testing.T) { + for i, idx := range s.indexes { + patch := Parse(s.patchStr) + result := patch.GetNextChangeIdx(idx) + assert.Equal(t, s.expecteds[i], result) + } + }) + } +} |