Skip to content

Commit 02f7ff4

Browse files
committed
Add positive tests for TextFragment#ApplyStrict
These cover all of the cases (I think) where application should succeed.
1 parent ae70423 commit 02f7ff4

26 files changed

+234
-8
lines changed

gitdiff/apply.go

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -122,32 +122,34 @@ func (f *TextFragment) ApplyStrict(dst io.Writer, src LineReader) error {
122122
return applyError(err, lineNum(n))
123123
}
124124

125+
used := int64(0)
125126
for i, line := range f.Lines {
126-
fromSrc, err := applyTextLine(dst, nextLine, line)
127-
if err != nil {
127+
if err := applyTextLine(dst, nextLine, line); err != nil {
128128
return applyError(err, lineNum(n), fragLineNum(i))
129129
}
130-
131-
if fromSrc && i < len(f.Lines)-1 {
130+
if fromSrc(line) {
131+
used++
132+
}
133+
// advance reader if the next fragment line appears in src and we're behind
134+
if i < len(f.Lines)-1 && fromSrc(f.Lines[i+1]) && int64(n)-limit < used {
132135
nextLine, n, err = src.ReadLine()
133136
if err != nil {
134137
if err == io.EOF {
135138
err = io.ErrUnexpectedEOF
136139
}
137-
return applyError(err, lineNum(n), fragLineNum(i+1))
140+
return applyError(err, lineNum(n), fragLineNum(i+1)) // report for _next_ line in fragment
138141
}
139142
}
140143
}
141144

142145
return nil
143146
}
144147

145-
func applyTextLine(dst io.Writer, src string, line Line) (fromSrc bool, err error) {
148+
func applyTextLine(dst io.Writer, src string, line Line) (err error) {
146149
switch line.Op {
147150
case OpContext, OpDelete:
148-
fromSrc = true
149151
if src != line.Line {
150-
return fromSrc, conflictError("fragment line does not match src line")
152+
return conflictError("fragment line does not match src line")
151153
}
152154
}
153155
switch line.Op {
@@ -157,6 +159,10 @@ func applyTextLine(dst io.Writer, src string, line Line) (fromSrc bool, err erro
157159
return
158160
}
159161

162+
func fromSrc(line Line) bool {
163+
return line.Op != OpAdd
164+
}
165+
160166
// copyLines copies from src to dst until the line at limit, exclusive. Returns
161167
// the line at limit and the line number. The line number may not equal the
162168
// limit if and only if a non-EOF error occurs. A negative limit means the

gitdiff/apply_test.go

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
package gitdiff
2+
3+
import (
4+
"bytes"
5+
"io/ioutil"
6+
"path/filepath"
7+
"testing"
8+
)
9+
10+
func TestTextFragmentApplyStrict(t *testing.T) {
11+
tests := map[string]struct {
12+
File string
13+
Err bool
14+
}{
15+
"createFile": {File: "new"},
16+
"deleteFile": {File: "delete_all"},
17+
"addStart": {File: "add_start"},
18+
"addMiddle": {File: "add_middle"},
19+
"addEnd": {File: "add_end"},
20+
"changeStart": {File: "change_start"},
21+
"changeMiddle": {File: "change_middle"},
22+
"changeEnd": {File: "change_end"},
23+
}
24+
25+
for name, test := range tests {
26+
t.Run(name, func(t *testing.T) {
27+
base := filepath.Join("testdata", "apply", "text_fragment_"+test.File)
28+
29+
src, err := ioutil.ReadFile(base + ".src")
30+
if err != nil {
31+
t.Fatalf("failed to read source file: %v", err)
32+
}
33+
patch, err := ioutil.ReadFile(base + ".patch")
34+
if err != nil {
35+
t.Fatalf("failed to read patch file: %v", err)
36+
}
37+
result, err := ioutil.ReadFile(base + ".dst")
38+
if err != nil {
39+
t.Fatalf("failed to read result file: %v", err)
40+
}
41+
42+
files, _, err := Parse(bytes.NewReader(patch))
43+
if err != nil {
44+
t.Fatalf("failed to parse patch file: %v", err)
45+
}
46+
47+
frag := files[0].TextFragments[0]
48+
49+
var dst bytes.Buffer
50+
err = frag.ApplyStrict(&dst, NewLineReader(bytes.NewReader(src), 0))
51+
if test.Err {
52+
if err == nil {
53+
t.Fatalf("expected error applying fragment, but got nil")
54+
}
55+
return
56+
}
57+
if err != nil {
58+
t.Fatalf("unexpected error applying fragment: %v", err)
59+
}
60+
61+
if !bytes.Equal(result, dst.Bytes()) {
62+
t.Errorf("incorrect result after apply\nexpected:\n%s\nactual:\n%s", result, dst.Bytes())
63+
}
64+
})
65+
}
66+
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
line 1
2+
line 2
3+
line 3
4+
new line a
5+
new line b
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
diff --git a/gitdiff/testdata/apply/fragment_add_end.src b/gitdiff/testdata/apply/fragment_add_end.src
2+
--- a/gitdiff/testdata/apply/fragment_add_end.src
3+
+++ b/gitdiff/testdata/apply/fragment_add_end.src
4+
@@ -1,3 +1,5 @@
5+
line 1
6+
line 2
7+
line 3
8+
+new line a
9+
+new line b
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
line 1
2+
line 2
3+
line 3
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
line 1
2+
line 2
3+
new line a
4+
new line b
5+
line 3
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
diff --git a/gitdiff/testdata/apply/fragment_add_middle.src b/gitdiff/testdata/apply/fragment_add_middle.src
2+
--- a/gitdiff/testdata/apply/fragment_add_middle.src
3+
+++ b/gitdiff/testdata/apply/fragment_add_middle.src
4+
@@ -1,3 +1,5 @@
5+
line 1
6+
line 2
7+
+new line a
8+
+new line b
9+
line 3
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
line 1
2+
line 2
3+
line 3
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
new line a
2+
line 1
3+
line 2
4+
line 3
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
diff --git a/gitdiff/testdata/apply/fragment_add_start.src b/gitdiff/testdata/apply/fragment_add_start.src
2+
--- a/gitdiff/testdata/apply/fragment_add_start.src
3+
+++ b/gitdiff/testdata/apply/fragment_add_start.src
4+
@@ -1,3 +1,4 @@
5+
+new line a
6+
line 1
7+
line 2
8+
line 3

0 commit comments

Comments
 (0)