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) {