Merge pull request #72 from maksimov/master
Refactored error checking tests. Fixes #71
diff --git a/diffmatchpatch/diff.go b/diffmatchpatch/diff.go
index 59b8851..82ad7bc 100644
--- a/diffmatchpatch/diff.go
+++ b/diffmatchpatch/diff.go
@@ -1285,6 +1285,7 @@
// DiffFromDelta given the original text1, and an encoded string which describes the operations required to transform text1 into text2, comAdde the full diff.
func (dmp *DiffMatchPatch) DiffFromDelta(text1 string, delta string) (diffs []Diff, err error) {
i := 0
+ runes := []rune(text1)
for _, token := range strings.Split(delta, "\t") {
if len(token) == 0 {
@@ -1316,9 +1317,13 @@
return nil, errors.New("Negative number in DiffFromDelta: " + param)
}
- // Remember that string slicing is by byte - we want by rune here.
- text := string([]rune(text1)[i : i+int(n)])
i += int(n)
+ // Break out if we are out of bounds, go1.6 can't handle this very well
+ if i > len(runes) {
+ break
+ }
+ // Remember that string slicing is by byte - we want by rune here.
+ text := string(runes[i-int(n) : i])
if op == '=' {
diffs = append(diffs, Diff{DiffEqual, text})
@@ -1331,8 +1336,8 @@
}
}
- if i != len([]rune(text1)) {
- return nil, fmt.Errorf("Delta length (%v) smaller than source text length (%v)", i, len(text1))
+ if i != len(runes) {
+ return nil, fmt.Errorf("Delta length (%v) is different from source text length (%v)", i, len(text1))
}
return diffs, nil
diff --git a/diffmatchpatch/diff_test.go b/diffmatchpatch/diff_test.go
index e642c66..b52bd70 100644
--- a/diffmatchpatch/diff_test.go
+++ b/diffmatchpatch/diff_test.go
@@ -998,8 +998,42 @@
}
func TestDiffDelta(t *testing.T) {
+ type TestCase struct {
+ Name string
+
+ Text string
+ Delta string
+
+ ErrorMessagePrefix string
+ }
+
dmp := New()
+ for i, tc := range []TestCase{
+ {"Delta shorter than text", "jumps over the lazyx", "=4\t-1\t+ed\t=6\t-3\t+a\t=5\t+old dog", "Delta length (19) is different from source text length (20)"},
+ {"Delta longer than text", "umps over the lazy", "=4\t-1\t+ed\t=6\t-3\t+a\t=5\t+old dog", "Delta length (19) is different from source text length (18)"},
+ {"Invalid URL escaping", "", "+%c3%xy", "invalid URL escape \"%xy\""},
+ {"Invalid UTF-8 sequence", "", "+%c3xy", "invalid UTF-8 token: \"\\xc3xy\""},
+ {"Invalid diff operation", "", "a", "Invalid diff operation in DiffFromDelta: a"},
+ {"Invalid diff syntax", "", "-", "strconv.ParseInt: parsing \"\": invalid syntax"},
+ {"Negative number in delta", "", "--1", "Negative number in DiffFromDelta: -1"},
+ {"Empty case", "", "", ""},
+ } {
+ diffs, err := dmp.DiffFromDelta(tc.Text, tc.Delta)
+ msg := fmt.Sprintf("Test case #%d, %s", i, tc.Name)
+ if tc.ErrorMessagePrefix == "" {
+ assert.Nil(t, err, msg)
+ assert.Nil(t, diffs, msg)
+ } else {
+ e := err.Error()
+ if strings.HasPrefix(e, tc.ErrorMessagePrefix) {
+ e = tc.ErrorMessagePrefix
+ }
+ assert.Nil(t, diffs, msg)
+ assert.Equal(t, tc.ErrorMessagePrefix, e, msg)
+ }
+ }
+
// Convert a diff into delta string.
diffs := []Diff{
Diff{DiffEqual, "jump"},
@@ -1021,30 +1055,6 @@
deltaDiffs, err := dmp.DiffFromDelta(text1, delta)
assert.Equal(t, diffs, deltaDiffs)
- // Generates error (19 < 20).
- _, err = dmp.DiffFromDelta(text1+"x", delta)
- if err == nil {
- t.Fatal("Too long.")
- }
-
- // Generates error (19 > 18).
- _, err = dmp.DiffFromDelta(text1[1:], delta)
- if err == nil {
- t.Fatal("Too short.")
- }
-
- // Generates error (%xy invalid URL escape).
- _, err = dmp.DiffFromDelta("", "+%c3%xy")
- if err == nil {
- assert.Fail(t, "expected Invalid URL escape.")
- }
-
- // Generates error (invalid utf8).
- _, err = dmp.DiffFromDelta("", "+%c3xy")
- if err == nil {
- assert.Fail(t, "expected Invalid utf8.")
- }
-
// Test deltas with special characters.
diffs = []Diff{
Diff{DiffEqual, "\u0680 \x00 \t %"},
@@ -1074,29 +1084,6 @@
deltaDiffs, err = dmp.DiffFromDelta("", delta)
assert.Equal(t, diffs, deltaDiffs)
assert.Nil(t, err)
-
- // Test blank tokens.
- _, err = dmp.DiffFromDelta("", "")
- assert.Nil(t, err)
-
- // Test invalid diff operation "a"
- _, err = dmp.DiffFromDelta("", "a")
- if err == nil {
- assert.Fail(t, "expected Invalid diff operation.")
- }
-
- // Test non-numeric parameter
- _, err = dmp.DiffFromDelta("", "-")
- if err == nil {
- assert.Fail(t, "expected Invalid syntax.")
- }
-
- // Test negative parameter
- _, err = dmp.DiffFromDelta("", "--1")
- if err == nil {
- assert.Fail(t, "expected Negative number.")
- }
-
}
func TestDiffXIndex(t *testing.T) {