Merge pull request #42 from sergi/28-handle-zero-deadlines-differently

Handle zero deadlines differently
diff --git a/diffmatchpatch/dmp.go b/diffmatchpatch/dmp.go
index 9c41a49..af1a34c 100644
--- a/diffmatchpatch/dmp.go
+++ b/diffmatchpatch/dmp.go
@@ -250,25 +250,13 @@
 
 // DiffMain finds the differences between two texts.
 func (dmp *DiffMatchPatch) DiffMain(text1, text2 string, checklines bool) []Diff {
-	var deadline time.Time
-	if dmp.DiffTimeout <= 0 {
-		deadline = time.Now().Add(24 * 365 * time.Hour)
-	} else {
-		deadline = time.Now().Add(dmp.DiffTimeout)
-	}
-	return dmp.diffMain(text1, text2, checklines, deadline)
-}
-
-func (dmp *DiffMatchPatch) diffMain(text1, text2 string, checklines bool, deadline time.Time) []Diff {
-	return dmp.diffMainRunes([]rune(text1), []rune(text2), checklines, deadline)
+	return dmp.DiffMainRunes([]rune(text1), []rune(text2), checklines)
 }
 
 // DiffMainRunes finds the differences between two rune sequences.
 func (dmp *DiffMatchPatch) DiffMainRunes(text1, text2 []rune, checklines bool) []Diff {
 	var deadline time.Time
-	if dmp.DiffTimeout <= 0 {
-		deadline = time.Now().Add(24 * 365 * time.Hour)
-	} else {
+	if dmp.DiffTimeout > 0 {
 		deadline = time.Now().Add(dmp.DiffTimeout)
 	}
 	return dmp.diffMainRunes(text1, text2, checklines, deadline)
@@ -387,6 +375,8 @@
 	pointer := 0
 	countDelete := 0
 	countInsert := 0
+
+	// NOTE: Rune slices are slower than using strings in this case.
 	textDelete := ""
 	textInsert := ""
 
@@ -406,7 +396,7 @@
 					countDelete+countInsert)
 
 				pointer = pointer - countDelete - countInsert
-				a := dmp.diffMain(textDelete, textInsert, false, deadline)
+				a := dmp.diffMainRunes([]rune(textDelete), []rune(textInsert), false, deadline)
 				for j := len(a) - 1; j >= 0; j-- {
 					diffs = splice(diffs, pointer, 0, a[j])
 				}
@@ -464,7 +454,7 @@
 	k2end := 0
 	for d := 0; d < maxD; d++ {
 		// Bail out if deadline is reached.
-		if time.Now().After(deadline) {
+		if !deadline.IsZero() && time.Now().After(deadline) {
 			break
 		}
 
diff --git a/diffmatchpatch/dmp_test.go b/diffmatchpatch/dmp_test.go
index 7d64b6e..bbfeae9 100644
--- a/diffmatchpatch/dmp_test.go
+++ b/diffmatchpatch/dmp_test.go
@@ -907,18 +907,21 @@
 	// Since the resulting diff hasn't been normalized, it would be ok if
 	// the insertion and deletion pairs are swapped.
 	// If the order changes, tweak this test as required.
-	diffs := []Diff{
+	correctDiffs := []Diff{
 		Diff{DiffDelete, "c"},
 		Diff{DiffInsert, "m"},
 		Diff{DiffEqual, "a"},
 		Diff{DiffDelete, "t"},
 		Diff{DiffInsert, "p"}}
 
-	assertDiffEqual(t, diffs, dmp.DiffBisect(a, b, time.Date(9999, time.December, 31, 23, 59, 59, 59, time.UTC)))
+	assertDiffEqual(t, correctDiffs, dmp.DiffBisect(a, b, time.Date(9999, time.December, 31, 23, 59, 59, 59, time.UTC)))
 
 	// Timeout.
-	diffs = []Diff{Diff{DiffDelete, "cat"}, Diff{DiffInsert, "map"}}
-	assertDiffEqual(t, diffs, dmp.DiffBisect(a, b, time.Date(0001, time.January, 01, 00, 00, 00, 00, time.UTC)))
+	diffs := []Diff{Diff{DiffDelete, "cat"}, Diff{DiffInsert, "map"}}
+	assertDiffEqual(t, diffs, dmp.DiffBisect(a, b, time.Now().Add(time.Nanosecond)))
+
+	// Negative deadlines count as having infinite time.
+	assertDiffEqual(t, correctDiffs, dmp.DiffBisect(a, b, time.Date(0001, time.January, 01, 00, 00, 00, 00, time.UTC)))
 }
 
 func Test_diffMain(t *testing.T) {
@@ -1259,6 +1262,14 @@
 
 	patches = dmp.PatchMake("2016-09-01T03:07:14.807830741Z", "2016-09-01T03:07:15.154800781Z")
 	assert.Equal(t, "@@ -15,16 +15,16 @@\n 07:1\n+5.15\n 4\n-.\n 80\n+0\n 78\n-3074\n 1Z\n", dmp.PatchToText(patches), "patch_make: Corner case of #31 fixed by #32")
+
+	text1 = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus ut risus et enim consectetur convallis a non ipsum. Sed nec nibh cursus, interdum libero vel."
+	text2 = "Lorem a ipsum dolor sit amet, consectetur adipiscing elit. Vivamus ut risus et enim consectetur convallis a non ipsum. Sed nec nibh cursus, interdum liberovel."
+	dmp2 := New()
+	dmp2.DiffTimeout = 0
+	diffs = dmp2.DiffMain(text1, text2, true)
+	patches = dmp2.PatchMake(text1, diffs)
+	assert.Equal(t, "@@ -1,14 +1,16 @@\n Lorem \n+a \n ipsum do\n@@ -148,13 +148,12 @@\n m libero\n- \n vel.\n", dmp2.PatchToText(patches), "patch_make: Corner case of #28 wrong patch with timeout of 0")
 }
 
 func Test_PatchSplitMax(t *testing.T) {