Refactor the test code

- Use table-driven tests where possible
- Reduce helper code, e.q., copycats of assert.Equal
- Reformat most of the code
- Rename the test functions to be Go conform
diff --git a/diffmatchpatch/diffmatchpatch_test.go b/diffmatchpatch/diffmatchpatch_test.go
index 2398849..a6daaa2 100644
--- a/diffmatchpatch/diffmatchpatch_test.go
+++ b/diffmatchpatch/diffmatchpatch_test.go
@@ -15,16 +15,20 @@
 )
 
 func caller() string {
-	if _, _, line, ok := runtime.Caller(2); ok {
-		return fmt.Sprintf("(actual-line %v) ", line)
+	_, _, line, ok := runtime.Caller(2)
+	if !ok {
+		return ""
 	}
-	return ""
+
+	return fmt.Sprintf("at line %d ", line)
 }
 
 func pretty(diffs []Diff) string {
 	var w bytes.Buffer
+
 	for i, diff := range diffs {
 		_, _ = w.WriteString(fmt.Sprintf("%v. ", i))
+
 		switch diff.Type {
 		case DiffInsert:
 			_, _ = w.WriteString("DiffIns")
@@ -35,130 +39,134 @@
 		default:
 			_, _ = w.WriteString("Unknown")
 		}
+
 		_, _ = w.WriteString(fmt.Sprintf(": %v\n", diff.Text))
 	}
+
 	return w.String()
 }
 
-func assertDiffEqual(t *testing.T, seq1, seq2 []Diff) {
-	if a, b := len(seq1), len(seq2); a != b {
-		t.Errorf("%v\nseq1:\n%v\nseq2:\n%v", caller(), pretty(seq1), pretty(seq2))
-		t.Errorf("%v Sequences of different length: %v != %v", caller(), a, b)
-		return
-	}
+func diffRebuildTexts(diffs []Diff) []string {
+	texts := []string{"", ""}
 
-	for i := range seq1 {
-		if a, b := seq1[i], seq2[i]; a != b {
-			t.Errorf("%v\nseq1:\n%v\nseq2:\n%v", caller(), pretty(seq1), pretty(seq2))
-			t.Errorf("%v %v != %v", caller(), a, b)
-			return
+	for _, d := range diffs {
+		if d.Type != DiffInsert {
+			texts[0] += d.Text
+		}
+		if d.Type != DiffDelete {
+			texts[1] += d.Text
 		}
 	}
+
+	return texts
 }
 
-func assertStrEqual(t *testing.T, seq1, seq2 []string) {
-	if a, b := len(seq1), len(seq2); a != b {
-		t.Fatalf("%v Sequences of different length: %v != %v", caller(), a, b)
-	}
-
-	for i := range seq1 {
-		if a, b := seq1[i], seq2[i]; a != b {
-			t.Fatalf("%v %v != %v", caller(), a, b)
-		}
-	}
-}
-
-func diffRebuildtexts(diffs []Diff) []string {
-	text := []string{"", ""}
-	for _, myDiff := range diffs {
-		if myDiff.Type != DiffInsert {
-			text[0] += myDiff.Text
-		}
-		if myDiff.Type != DiffDelete {
-			text[1] += myDiff.Text
-		}
-	}
-	return text
-}
-
-func readFile(b *testing.B, filename string) string {
-	bytes, err := ioutil.ReadFile(filename)
+func readFile(filepath string) string {
+	data, err := ioutil.ReadFile(filepath)
 	if err != nil {
-		b.Fatal(err)
+		panic(err)
 	}
 
-	return string(bytes)
+	return string(data)
 }
 
-func speedtestTexts(b *testing.B) (s1 string, s2 string) {
-	s1 = readFile(b, "../testdata/speedtest1.txt")
-	s2 = readFile(b, "../testdata/speedtest2.txt")
+func speedtestTexts() (s1 string, s2 string) {
+	s1 = readFile("../testdata/speedtest1.txt")
+	s2 = readFile("../testdata/speedtest2.txt")
 
 	return s1, s2
 }
 
-func Test_diffCommonPrefix(t *testing.T) {
+func TestDiffCommonPrefix(t *testing.T) {
+	type TestCase struct {
+		Name string
+
+		Text1 string
+		Text2 string
+
+		Expected int
+	}
+
 	dmp := New()
-	// Detect any common suffix.
-	// Null case.
-	assert.Equal(t, 0, dmp.DiffCommonPrefix("abc", "xyz"), "'abc' and 'xyz' should not be equal")
 
-	// Non-null case.
-	assert.Equal(t, 4, dmp.DiffCommonPrefix("1234abcdef", "1234xyz"), "")
-
-	// Whole case.
-	assert.Equal(t, 4, dmp.DiffCommonPrefix("1234", "1234xyz"), "")
+	for i, tc := range []TestCase{
+		{"Null", "abc", "xyz", 0},
+		{"Non-null", "1234abcdef", "1234xyz", 4},
+		{"Whole", "1234", "1234xyz", 4},
+	} {
+		actual := dmp.DiffCommonPrefix(tc.Text1, tc.Text2)
+		assert.Equal(t, tc.Expected, actual, fmt.Sprintf("Test case #%d, %s", i, tc.Name))
+	}
 }
 
-func Test_commonPrefixLength(t *testing.T) {
-	for _, test := range []struct {
-		s1, s2 string
-		want   int
-	}{
+func TestCommonPrefixLength(t *testing.T) {
+	type TestCase struct {
+		Text1 string
+		Text2 string
+
+		Expected int
+	}
+
+	for i, tc := range []TestCase{
 		{"abc", "xyz", 0},
 		{"1234abcdef", "1234xyz", 4},
 		{"1234", "1234xyz", 4},
 	} {
-		assert.Equal(t, test.want, commonPrefixLength([]rune(test.s1), []rune(test.s2)),
-			fmt.Sprintf("%q, %q", test.s1, test.s2))
+		actual := commonPrefixLength([]rune(tc.Text1), []rune(tc.Text2))
+		assert.Equal(t, tc.Expected, actual, fmt.Sprintf("Test case #%d, %#v", i, tc))
 	}
 }
 
-func Test_diffCommonSuffixTest(t *testing.T) {
+func TestDiffCommonSuffix(t *testing.T) {
+	type TestCase struct {
+		Name string
+
+		Text1 string
+		Text2 string
+
+		Expected int
+	}
+
 	dmp := New()
-	// Detect any common suffix.
-	// Null case.
-	assert.Equal(t, 0, dmp.DiffCommonSuffix("abc", "xyz"), "")
 
-	// Non-null case.
-	assert.Equal(t, 4, dmp.DiffCommonSuffix("abcdef1234", "xyz1234"), "")
-
-	// Whole case.
-	assert.Equal(t, 4, dmp.DiffCommonSuffix("1234", "xyz1234"), "")
+	for i, tc := range []TestCase{
+		{"Null", "abc", "xyz", 0},
+		{"Non-null", "abcdef1234", "xyz1234", 4},
+		{"Whole", "1234", "xyz1234", 4},
+	} {
+		actual := dmp.DiffCommonSuffix(tc.Text1, tc.Text2)
+		assert.Equal(t, tc.Expected, actual, fmt.Sprintf("Test case #%d, %s", i, tc.Name))
+	}
 }
 
-func Test_commonSuffixLength(t *testing.T) {
-	for _, test := range []struct {
-		s1, s2 string
-		want   int
-	}{
+func TestCommonSuffixLength(t *testing.T) {
+	type TestCase struct {
+		Text1 string
+		Text2 string
+
+		Expected int
+	}
+
+	for i, tc := range []TestCase{
 		{"abc", "xyz", 0},
 		{"abcdef1234", "xyz1234", 4},
 		{"1234", "xyz1234", 4},
 		{"123", "a3", 1},
 	} {
-		assert.Equal(t, test.want, commonSuffixLength([]rune(test.s1), []rune(test.s2)),
-			fmt.Sprintf("%q, %q", test.s1, test.s2))
+		actual := commonSuffixLength([]rune(tc.Text1), []rune(tc.Text2))
+		assert.Equal(t, tc.Expected, actual, fmt.Sprintf("Test case #%d, %#v", i, tc))
 	}
 }
 
-func Test_runesIndexOf(t *testing.T) {
-	target := []rune("abcde")
-	for _, test := range []struct {
-		pattern string
-		start   int
-		want    int
-	}{
+func TestRunesIndexOf(t *testing.T) {
+	type TestCase struct {
+		Pattern string
+		Start   int
+
+		Expected int
+	}
+
+	for i, tc := range []TestCase{
 		{"abc", 0, 0},
 		{"cde", 0, 2},
 		{"e", 0, 4},
@@ -171,636 +179,824 @@
 		{"abcdef", 2, -1},
 		{"e", 6, -1},
 	} {
-		assert.Equal(t, test.want,
-			runesIndexOf(target, []rune(test.pattern), test.start),
-			fmt.Sprintf("%q, %d", test.pattern, test.start))
+		actual := runesIndexOf([]rune("abcde"), []rune(tc.Pattern), tc.Start)
+		assert.Equal(t, tc.Expected, actual, fmt.Sprintf("Test case #%d, %#v", i, tc))
 	}
 }
 
-func Test_diffCommonOverlapTest(t *testing.T) {
+func TestDiffCommonOverlap(t *testing.T) {
+	type TestCase struct {
+		Name string
+
+		Text1 string
+		Text2 string
+
+		Expected int
+	}
+
 	dmp := New()
-	// Detect any suffix/prefix overlap.
-	// Null case.
-	assert.Equal(t, 0, dmp.DiffCommonOverlap("", "abcd"), "")
 
-	// Whole case.
-	assert.Equal(t, 3, dmp.DiffCommonOverlap("abc", "abcd"), "")
-
-	// No overlap.
-	assert.Equal(t, 0, dmp.DiffCommonOverlap("123456", "abcd"), "")
-
-	// Overlap.
-	assert.Equal(t, 3, dmp.DiffCommonOverlap("123456xxx", "xxxabcd"), "")
-
-	// Unicode.
-	// Some overly clever languages (C#) may treat ligatures as equal to their
-	// component letters.  E.g. U+FB01 == 'fi'
-	assert.Equal(t, 0, dmp.DiffCommonOverlap("fi", "\ufb01i"), "")
+	for i, tc := range []TestCase{
+		{"Null", "", "abcd", 0},
+		{"Whole", "abc", "abcd", 3},
+		{"Null", "123456", "abcd", 0},
+		{"Null", "123456xxx", "xxxabcd", 3},
+		// Some overly clever languages (C#) may treat ligatures as equal to their component letters, e.g. U+FB01 == 'fi'
+		{"Unicode", "fi", "\ufb01i", 0},
+	} {
+		actual := dmp.DiffCommonOverlap(tc.Text1, tc.Text2)
+		assert.Equal(t, tc.Expected, actual, fmt.Sprintf("Test case #%d, %s", i, tc.Name))
+	}
 }
 
-func Test_diffHalfmatchTest(t *testing.T) {
+func TestDiffHalfMatch(t *testing.T) {
+	type TestCase struct {
+		Text1 string
+		Text2 string
+
+		Expected []string
+	}
+
 	dmp := New()
 	dmp.DiffTimeout = 1
-	// No match.
-	assert.True(t, dmp.DiffHalfMatch("1234567890", "abcdef") == nil, "")
-	assert.True(t, dmp.DiffHalfMatch("12345", "23") == nil, "")
 
-	// Single Match.
-	assertStrEqual(t,
-		[]string{"12", "90", "a", "z", "345678"},
-		dmp.DiffHalfMatch("1234567890", "a345678z"))
+	for i, tc := range []TestCase{
+		// No match
+		{"1234567890", "abcdef", nil},
+		{"12345", "23", nil},
 
-	assertStrEqual(t, []string{"a", "z", "12", "90", "345678"}, dmp.DiffHalfMatch("a345678z", "1234567890"))
+		// Single Match
+		{"1234567890", "a345678z", []string{"12", "90", "a", "z", "345678"}},
+		{"a345678z", "1234567890", []string{"a", "z", "12", "90", "345678"}},
+		{"abc56789z", "1234567890", []string{"abc", "z", "1234", "0", "56789"}},
+		{"a23456xyz", "1234567890", []string{"a", "xyz", "1", "7890", "23456"}},
 
-	assertStrEqual(t, []string{"abc", "z", "1234", "0", "56789"}, dmp.DiffHalfMatch("abc56789z", "1234567890"))
+		// Multiple Matches
+		{"121231234123451234123121", "a1234123451234z", []string{"12123", "123121", "a", "z", "1234123451234"}},
+		{"x-=-=-=-=-=-=-=-=-=-=-=-=", "xx-=-=-=-=-=-=-=", []string{"", "-=-=-=-=-=", "x", "", "x-=-=-=-=-=-=-="}},
+		{"-=-=-=-=-=-=-=-=-=-=-=-=y", "-=-=-=-=-=-=-=yy", []string{"-=-=-=-=-=", "", "", "y", "-=-=-=-=-=-=-=y"}},
 
-	assertStrEqual(t, []string{"a", "xyz", "1", "7890", "23456"}, dmp.DiffHalfMatch("a23456xyz", "1234567890"))
+		// Non-optimal halfmatch, ptimal diff would be -q+x=H-i+e=lloHe+Hu=llo-Hew+y not -qHillo+x=HelloHe-w+Hulloy
+		{"qHilloHelloHew", "xHelloHeHulloy", []string{"qHillo", "w", "x", "Hulloy", "HelloHe"}},
+	} {
+		actual := dmp.DiffHalfMatch(tc.Text1, tc.Text2)
+		assert.Equal(t, tc.Expected, actual, fmt.Sprintf("Test case #%d, %#v", i, tc))
+	}
 
-	// Multiple Matches.
-	assertStrEqual(t, []string{"12123", "123121", "a", "z", "1234123451234"}, dmp.DiffHalfMatch("121231234123451234123121", "a1234123451234z"))
-
-	assertStrEqual(t, []string{"", "-=-=-=-=-=", "x", "", "x-=-=-=-=-=-=-="}, dmp.DiffHalfMatch("x-=-=-=-=-=-=-=-=-=-=-=-=", "xx-=-=-=-=-=-=-="))
-
-	assertStrEqual(t, []string{"-=-=-=-=-=", "", "", "y", "-=-=-=-=-=-=-=y"}, dmp.DiffHalfMatch("-=-=-=-=-=-=-=-=-=-=-=-=y", "-=-=-=-=-=-=-=yy"))
-
-	// Non-optimal halfmatch.
-	// Optimal diff would be -q+x=H-i+e=lloHe+Hu=llo-Hew+y not -qHillo+x=HelloHe-w+Hulloy
-	assertStrEqual(t, []string{"qHillo", "w", "x", "Hulloy", "HelloHe"}, dmp.DiffHalfMatch("qHilloHelloHew", "xHelloHeHulloy"))
-
-	// Optimal no halfmatch.
 	dmp.DiffTimeout = 0
-	assert.True(t, dmp.DiffHalfMatch("qHilloHelloHew", "xHelloHeHulloy") == nil, "")
-}
 
-func Test_diffBisectSplit(t *testing.T) {
-	// As originally written, this can produce invalid utf8 strings.
-	dmp := New()
-	diffs := dmp.diffBisectSplit([]rune("STUV\x05WX\x05YZ\x05["),
-		[]rune("WĺĻļ\x05YZ\x05ĽľĿŀZ"), 7, 6, time.Now().Add(time.Hour))
-	for _, d := range diffs {
-		assert.True(t, utf8.ValidString(d.Text))
+	for i, tc := range []TestCase{
+		// Optimal no halfmatch
+		{"qHilloHelloHew", "xHelloHeHulloy", nil},
+	} {
+		actual := dmp.DiffHalfMatch(tc.Text1, tc.Text2)
+		assert.Equal(t, tc.Expected, actual, fmt.Sprintf("Test case #%d, %#v", i, tc))
 	}
 }
 
-func Test_diffLinesToChars(t *testing.T) {
+func TestDiffBisectSplit(t *testing.T) {
+	type TestCase struct {
+		Text1 string
+		Text2 string
+	}
+
 	dmp := New()
-	// Convert lines down to characters.
-	tmpVector := []string{"", "alpha\n", "beta\n"}
 
-	result0, result1, result2 := dmp.DiffLinesToChars("alpha\nbeta\nalpha\n", "beta\nalpha\nbeta\n")
-	assert.Equal(t, "\u0001\u0002\u0001", result0, "")
-	assert.Equal(t, "\u0002\u0001\u0002", result1, "")
-	assertStrEqual(t, tmpVector, result2)
+	for _, tc := range []TestCase{
+		{"STUV\x05WX\x05YZ\x05[", "WĺĻļ\x05YZ\x05ĽľĿŀZ"},
+	} {
+		diffs := dmp.diffBisectSplit([]rune(tc.Text1),
+			[]rune(tc.Text2), 7, 6, time.Now().Add(time.Hour))
 
-	tmpVector = []string{"", "alpha\r\n", "beta\r\n", "\r\n"}
-	result0, result1, result2 = dmp.DiffLinesToChars("", "alpha\r\nbeta\r\n\r\n\r\n")
-	assert.Equal(t, "", result0, "")
-	assert.Equal(t, "\u0001\u0002\u0003\u0003", result1, "")
-	assertStrEqual(t, tmpVector, result2)
+		for _, d := range diffs {
+			assert.True(t, utf8.ValidString(d.Text))
+		}
 
-	tmpVector = []string{"", "a", "b"}
-	result0, result1, result2 = dmp.DiffLinesToChars("a", "b")
-	assert.Equal(t, "\u0001", result0, "")
-	assert.Equal(t, "\u0002", result1, "")
-	assertStrEqual(t, tmpVector, result2)
+		// TODO define the expected outcome
+	}
+}
 
-	// Omit final newline.
-	result0, result1, result2 = dmp.DiffLinesToChars("alpha\nbeta\nalpha", "")
-	assert.Equal(t, "\u0001\u0002\u0003", result0)
-	assert.Equal(t, "", result1)
-	assertStrEqual(t, []string{"", "alpha\n", "beta\n", "alpha"}, result2)
+func TestDiffLinesToChars(t *testing.T) {
+	type TestCase struct {
+		Text1 string
+		Text2 string
+
+		ExpectedChars1 string
+		ExpectedChars2 string
+		ExpectedLines  []string
+	}
+
+	dmp := New()
+
+	for i, tc := range []TestCase{
+		{"", "alpha\r\nbeta\r\n\r\n\r\n", "", "\u0001\u0002\u0003\u0003", []string{"", "alpha\r\n", "beta\r\n", "\r\n"}},
+		{"a", "b", "\u0001", "\u0002", []string{"", "a", "b"}},
+		// Omit final newline.
+		{"alpha\nbeta\nalpha", "", "\u0001\u0002\u0003", "", []string{"", "alpha\n", "beta\n", "alpha"}},
+	} {
+		actualChars1, actualChars2, actualLines := dmp.DiffLinesToChars(tc.Text1, tc.Text2)
+		assert.Equal(t, tc.ExpectedChars1, actualChars1, fmt.Sprintf("Test case #%d, %#v", i, tc))
+		assert.Equal(t, tc.ExpectedChars2, actualChars2, fmt.Sprintf("Test case #%d, %#v", i, tc))
+		assert.Equal(t, tc.ExpectedLines, actualLines, fmt.Sprintf("Test case #%d, %#v", i, tc))
+	}
 
 	// More than 256 to reveal any 8-bit limitations.
 	n := 300
-	lineList := []string{}
-	charList := []rune{}
-
+	lineList := []string{
+		"", // Account for the initial empty element of the lines array.
+	}
+	var charList []rune
 	for x := 1; x < n+1; x++ {
 		lineList = append(lineList, strconv.Itoa(x)+"\n")
 		charList = append(charList, rune(x))
 	}
-
 	lines := strings.Join(lineList, "")
 	chars := string(charList)
-	assert.Equal(t, n, utf8.RuneCountInString(chars), "")
+	assert.Equal(t, n, utf8.RuneCountInString(chars))
 
-	result0, result1, result2 = dmp.DiffLinesToChars(lines, "")
-
-	assert.Equal(t, chars, result0)
-	assert.Equal(t, "", result1, "")
-	// Account for the initial empty element of the lines array.
-	assertStrEqual(t, append([]string{""}, lineList...), result2)
+	actualChars1, actualChars2, actualLines := dmp.DiffLinesToChars(lines, "")
+	assert.Equal(t, chars, actualChars1)
+	assert.Equal(t, "", actualChars2)
+	assert.Equal(t, lineList, actualLines)
 }
 
-func Test_diffCharsToLines(t *testing.T) {
-	dmp := New()
-	// Convert chars up to lines.
-	diffs := []Diff{
-		Diff{DiffEqual, "\u0001\u0002\u0001"},
-		Diff{DiffInsert, "\u0002\u0001\u0002"}}
+func TestDiffCharsToLines(t *testing.T) {
+	type TestCase struct {
+		Diffs []Diff
+		Lines []string
 
-	tmpVector := []string{"", "alpha\n", "beta\n"}
-	actual := dmp.DiffCharsToLines(diffs, tmpVector)
-	assertDiffEqual(t, []Diff{
-		Diff{DiffEqual, "alpha\nbeta\nalpha\n"},
-		Diff{DiffInsert, "beta\nalpha\nbeta\n"}}, actual)
+		Expected []Diff
+	}
+
+	dmp := New()
+
+	for i, tc := range []TestCase{
+		{
+			Diffs: []Diff{
+				{DiffEqual, "\u0001\u0002\u0001"},
+				{DiffInsert, "\u0002\u0001\u0002"},
+			},
+			Lines: []string{"", "alpha\n", "beta\n"},
+
+			Expected: []Diff{
+				{DiffEqual, "alpha\nbeta\nalpha\n"},
+				{DiffInsert, "beta\nalpha\nbeta\n"},
+			},
+		},
+	} {
+		actual := dmp.DiffCharsToLines(tc.Diffs, tc.Lines)
+		assert.Equal(t, tc.Expected, actual, fmt.Sprintf("Test case #%d, %#v", i, tc))
+	}
 
 	// More than 256 to reveal any 8-bit limitations.
 	n := 300
-	lineList := []string{}
+	lineList := []string{
+		"", // Account for the initial empty element of the lines array.
+	}
 	charList := []rune{}
-
 	for x := 1; x <= n; x++ {
 		lineList = append(lineList, strconv.Itoa(x)+"\n")
 		charList = append(charList, rune(x))
 	}
-
 	assert.Equal(t, n, len(charList))
 
-	lineList = append([]string{""}, lineList...)
-	diffs = []Diff{Diff{DiffDelete, string(charList)}}
-	actual = dmp.DiffCharsToLines(diffs, lineList)
-	assertDiffEqual(t, []Diff{
-		Diff{DiffDelete, strings.Join(lineList, "")}}, actual)
+	actual := dmp.DiffCharsToLines([]Diff{Diff{DiffDelete, string(charList)}}, lineList)
+	assert.Equal(t, []Diff{Diff{DiffDelete, strings.Join(lineList, "")}}, actual)
 }
 
-func Test_diffCleanupMerge(t *testing.T) {
-	dmp := New()
-	// Cleanup a messy diff.
-	// Null case.
-	diffs := []Diff{}
-	diffs = dmp.DiffCleanupMerge(diffs)
-	assertDiffEqual(t, []Diff{}, diffs)
+func TestDiffCleanupMerge(t *testing.T) {
+	type TestCase struct {
+		Name string
 
-	// No Diff case.
-	diffs = []Diff{Diff{DiffEqual, "a"}, Diff{DiffDelete, "b"}, Diff{DiffInsert, "c"}}
-	diffs = dmp.DiffCleanupMerge(diffs)
-	assertDiffEqual(t, []Diff{Diff{DiffEqual, "a"}, Diff{DiffDelete, "b"}, Diff{DiffInsert, "c"}}, diffs)
+		Diffs []Diff
 
-	// Merge equalities.
-	diffs = []Diff{Diff{DiffEqual, "a"}, Diff{DiffEqual, "b"}, Diff{DiffEqual, "c"}}
-	diffs = dmp.DiffCleanupMerge(diffs)
-	assertDiffEqual(t, []Diff{Diff{DiffEqual, "abc"}}, diffs)
-
-	// Merge deletions.
-	diffs = []Diff{Diff{DiffDelete, "a"}, Diff{DiffDelete, "b"}, Diff{DiffDelete, "c"}}
-	diffs = dmp.DiffCleanupMerge(diffs)
-	assertDiffEqual(t, []Diff{Diff{DiffDelete, "abc"}}, diffs)
-
-	// Merge insertions.
-	diffs = []Diff{Diff{DiffInsert, "a"}, Diff{DiffInsert, "b"}, Diff{DiffInsert, "c"}}
-	diffs = dmp.DiffCleanupMerge(diffs)
-	assertDiffEqual(t, []Diff{Diff{DiffInsert, "abc"}}, diffs)
-
-	// Merge interweave.
-	diffs = []Diff{Diff{DiffDelete, "a"}, Diff{DiffInsert, "b"}, Diff{DiffDelete, "c"}, Diff{DiffInsert, "d"}, Diff{DiffEqual, "e"}, Diff{DiffEqual, "f"}}
-	diffs = dmp.DiffCleanupMerge(diffs)
-	assertDiffEqual(t, []Diff{Diff{DiffDelete, "ac"}, Diff{DiffInsert, "bd"}, Diff{DiffEqual, "ef"}}, diffs)
-
-	// Prefix and suffix detection.
-	diffs = []Diff{Diff{DiffDelete, "a"}, Diff{DiffInsert, "abc"}, Diff{DiffDelete, "dc"}}
-	diffs = dmp.DiffCleanupMerge(diffs)
-	assertDiffEqual(t, []Diff{Diff{DiffEqual, "a"}, Diff{DiffDelete, "d"}, Diff{DiffInsert, "b"}, Diff{DiffEqual, "c"}}, diffs)
-
-	// Prefix and suffix detection with equalities.
-	diffs = []Diff{Diff{DiffEqual, "x"}, Diff{DiffDelete, "a"}, Diff{DiffInsert, "abc"}, Diff{DiffDelete, "dc"}, Diff{DiffEqual, "y"}}
-	diffs = dmp.DiffCleanupMerge(diffs)
-	assertDiffEqual(t, []Diff{Diff{DiffEqual, "xa"}, Diff{DiffDelete, "d"}, Diff{DiffInsert, "b"}, Diff{DiffEqual, "cy"}}, diffs)
-
-	// Same test as above but with unicode (\u0101 will appear in diffs with at least 257 unique lines)
-	diffs = []Diff{Diff{DiffEqual, "x"}, Diff{DiffDelete, "\u0101"}, Diff{DiffInsert, "\u0101bc"}, Diff{DiffDelete, "dc"}, Diff{DiffEqual, "y"}}
-	diffs = dmp.DiffCleanupMerge(diffs)
-	assertDiffEqual(t, []Diff{Diff{DiffEqual, "x\u0101"}, Diff{DiffDelete, "d"}, Diff{DiffInsert, "b"}, Diff{DiffEqual, "cy"}}, diffs)
-
-	// Slide edit left.
-	diffs = []Diff{Diff{DiffEqual, "a"}, Diff{DiffInsert, "ba"}, Diff{DiffEqual, "c"}}
-	diffs = dmp.DiffCleanupMerge(diffs)
-	assertDiffEqual(t, []Diff{Diff{DiffInsert, "ab"}, Diff{DiffEqual, "ac"}}, diffs)
-
-	// Slide edit right.
-	diffs = []Diff{Diff{DiffEqual, "c"}, Diff{DiffInsert, "ab"}, Diff{DiffEqual, "a"}}
-	diffs = dmp.DiffCleanupMerge(diffs)
-
-	assertDiffEqual(t, []Diff{Diff{DiffEqual, "ca"}, Diff{DiffInsert, "ba"}}, diffs)
-
-	// Slide edit left recursive.
-	diffs = []Diff{Diff{DiffEqual, "a"}, Diff{DiffDelete, "b"}, Diff{DiffEqual, "c"}, Diff{DiffDelete, "ac"}, Diff{DiffEqual, "x"}}
-	diffs = dmp.DiffCleanupMerge(diffs)
-	assertDiffEqual(t, []Diff{Diff{DiffDelete, "abc"}, Diff{DiffEqual, "acx"}}, diffs)
-
-	// Slide edit right recursive.
-	diffs = []Diff{Diff{DiffEqual, "x"}, Diff{DiffDelete, "ca"}, Diff{DiffEqual, "c"}, Diff{DiffDelete, "b"}, Diff{DiffEqual, "a"}}
-	diffs = dmp.DiffCleanupMerge(diffs)
-	assertDiffEqual(t, []Diff{Diff{DiffEqual, "xca"}, Diff{DiffDelete, "cba"}}, diffs)
-}
-
-func Test_diffCleanupSemanticLossless(t *testing.T) {
-	dmp := New()
-	// Slide diffs to match logical boundaries.
-	// Null case.
-	diffs := []Diff{}
-	diffs = dmp.DiffCleanupSemanticLossless(diffs)
-	assertDiffEqual(t, []Diff{}, diffs)
-
-	// Blank lines.
-	diffs = []Diff{
-		Diff{DiffEqual, "AAA\r\n\r\nBBB"},
-		Diff{DiffInsert, "\r\nDDD\r\n\r\nBBB"},
-		Diff{DiffEqual, "\r\nEEE"},
+		Expected []Diff
 	}
 
-	diffs = dmp.DiffCleanupSemanticLossless(diffs)
+	dmp := New()
 
-	assertDiffEqual(t, []Diff{
-		Diff{DiffEqual, "AAA\r\n\r\n"},
-		Diff{DiffInsert, "BBB\r\nDDD\r\n\r\n"},
-		Diff{DiffEqual, "BBB\r\nEEE"}}, diffs)
-
-	// Line boundaries.
-	diffs = []Diff{
-		Diff{DiffEqual, "AAA\r\nBBB"},
-		Diff{DiffInsert, " DDD\r\nBBB"},
-		Diff{DiffEqual, " EEE"}}
-
-	diffs = dmp.DiffCleanupSemanticLossless(diffs)
-
-	assertDiffEqual(t, []Diff{
-		Diff{DiffEqual, "AAA\r\n"},
-		Diff{DiffInsert, "BBB DDD\r\n"},
-		Diff{DiffEqual, "BBB EEE"}}, diffs)
-
-	// Word boundaries.
-	diffs = []Diff{
-		Diff{DiffEqual, "The c"},
-		Diff{DiffInsert, "ow and the c"},
-		Diff{DiffEqual, "at."}}
-
-	diffs = dmp.DiffCleanupSemanticLossless(diffs)
-
-	assertDiffEqual(t, []Diff{
-		Diff{DiffEqual, "The "},
-		Diff{DiffInsert, "cow and the "},
-		Diff{DiffEqual, "cat."}}, diffs)
-
-	// Alphanumeric boundaries.
-	diffs = []Diff{
-		Diff{DiffEqual, "The-c"},
-		Diff{DiffInsert, "ow-and-the-c"},
-		Diff{DiffEqual, "at."}}
-
-	diffs = dmp.DiffCleanupSemanticLossless(diffs)
-
-	assertDiffEqual(t, []Diff{
-		Diff{DiffEqual, "The-"},
-		Diff{DiffInsert, "cow-and-the-"},
-		Diff{DiffEqual, "cat."}}, diffs)
-
-	// Hitting the start.
-	diffs = []Diff{
-		Diff{DiffEqual, "a"},
-		Diff{DiffDelete, "a"},
-		Diff{DiffEqual, "ax"}}
-
-	diffs = dmp.DiffCleanupSemanticLossless(diffs)
-
-	assertDiffEqual(t, []Diff{
-		Diff{DiffDelete, "a"},
-		Diff{DiffEqual, "aax"}}, diffs)
-
-	// Hitting the end.
-	diffs = []Diff{
-		Diff{DiffEqual, "xa"},
-		Diff{DiffDelete, "a"},
-		Diff{DiffEqual, "a"}}
-
-	diffs = dmp.DiffCleanupSemanticLossless(diffs)
-	assertDiffEqual(t, []Diff{
-		Diff{DiffEqual, "xaa"},
-		Diff{DiffDelete, "a"}}, diffs)
-
-	// Sentence boundaries.
-	diffs = []Diff{
-		Diff{DiffEqual, "The xxx. The "},
-		Diff{DiffInsert, "zzz. The "},
-		Diff{DiffEqual, "yyy."}}
-
-	diffs = dmp.DiffCleanupSemanticLossless(diffs)
-
-	assertDiffEqual(t, []Diff{
-		Diff{DiffEqual, "The xxx."},
-		Diff{DiffInsert, " The zzz."},
-		Diff{DiffEqual, " The yyy."}}, diffs)
-
-	// UTF-8 strings.
-	diffs = []Diff{
-		Diff{DiffEqual, "The ♕. The "},
-		Diff{DiffInsert, "♔. The "},
-		Diff{DiffEqual, "♖."}}
-
-	diffs = dmp.DiffCleanupSemanticLossless(diffs)
-
-	assertDiffEqual(t, []Diff{
-		Diff{DiffEqual, "The ♕."},
-		Diff{DiffInsert, " The ♔."},
-		Diff{DiffEqual, " The ♖."}}, diffs)
-
-	// Rune boundaries.
-	diffs = []Diff{
-		Diff{DiffEqual, "♕♕"},
-		Diff{DiffInsert, "♔♔"},
-		Diff{DiffEqual, "♖♖"}}
-
-	diffs = dmp.DiffCleanupSemanticLossless(diffs)
-
-	assertDiffEqual(t, []Diff{
-		Diff{DiffEqual, "♕♕"},
-		Diff{DiffInsert, "♔♔"},
-		Diff{DiffEqual, "♖♖"}}, diffs)
+	for i, tc := range []TestCase{
+		{
+			"Null case",
+			[]Diff{},
+			[]Diff{},
+		},
+		{
+			"No Diff case",
+			[]Diff{Diff{DiffEqual, "a"}, Diff{DiffDelete, "b"}, Diff{DiffInsert, "c"}},
+			[]Diff{Diff{DiffEqual, "a"}, Diff{DiffDelete, "b"}, Diff{DiffInsert, "c"}},
+		},
+		{
+			"Merge equalities",
+			[]Diff{Diff{DiffEqual, "a"}, Diff{DiffEqual, "b"}, Diff{DiffEqual, "c"}},
+			[]Diff{Diff{DiffEqual, "abc"}},
+		},
+		{
+			"Merge deletions",
+			[]Diff{Diff{DiffDelete, "a"}, Diff{DiffDelete, "b"}, Diff{DiffDelete, "c"}},
+			[]Diff{Diff{DiffDelete, "abc"}},
+		},
+		{
+			"Merge insertions",
+			[]Diff{Diff{DiffInsert, "a"}, Diff{DiffInsert, "b"}, Diff{DiffInsert, "c"}},
+			[]Diff{Diff{DiffInsert, "abc"}},
+		},
+		{
+			"Merge interweave",
+			[]Diff{Diff{DiffDelete, "a"}, Diff{DiffInsert, "b"}, Diff{DiffDelete, "c"}, Diff{DiffInsert, "d"}, Diff{DiffEqual, "e"}, Diff{DiffEqual, "f"}},
+			[]Diff{Diff{DiffDelete, "ac"}, Diff{DiffInsert, "bd"}, Diff{DiffEqual, "ef"}},
+		},
+		{
+			"Prefix and suffix detection",
+			[]Diff{Diff{DiffDelete, "a"}, Diff{DiffInsert, "abc"}, Diff{DiffDelete, "dc"}},
+			[]Diff{Diff{DiffEqual, "a"}, Diff{DiffDelete, "d"}, Diff{DiffInsert, "b"}, Diff{DiffEqual, "c"}},
+		},
+		{
+			"Prefix and suffix detection with equalities",
+			[]Diff{Diff{DiffEqual, "x"}, Diff{DiffDelete, "a"}, Diff{DiffInsert, "abc"}, Diff{DiffDelete, "dc"}, Diff{DiffEqual, "y"}},
+			[]Diff{Diff{DiffEqual, "xa"}, Diff{DiffDelete, "d"}, Diff{DiffInsert, "b"}, Diff{DiffEqual, "cy"}},
+		},
+		{
+			"Same test as above but with unicode (\u0101 will appear in diffs with at least 257 unique lines)",
+			[]Diff{Diff{DiffEqual, "x"}, Diff{DiffDelete, "\u0101"}, Diff{DiffInsert, "\u0101bc"}, Diff{DiffDelete, "dc"}, Diff{DiffEqual, "y"}},
+			[]Diff{Diff{DiffEqual, "x\u0101"}, Diff{DiffDelete, "d"}, Diff{DiffInsert, "b"}, Diff{DiffEqual, "cy"}},
+		},
+		{
+			"Slide edit left",
+			[]Diff{Diff{DiffEqual, "a"}, Diff{DiffInsert, "ba"}, Diff{DiffEqual, "c"}},
+			[]Diff{Diff{DiffInsert, "ab"}, Diff{DiffEqual, "ac"}},
+		},
+		{
+			"Slide edit right",
+			[]Diff{Diff{DiffEqual, "c"}, Diff{DiffInsert, "ab"}, Diff{DiffEqual, "a"}},
+			[]Diff{Diff{DiffEqual, "ca"}, Diff{DiffInsert, "ba"}},
+		},
+		{
+			"Slide edit left recursive",
+			[]Diff{Diff{DiffEqual, "a"}, Diff{DiffDelete, "b"}, Diff{DiffEqual, "c"}, Diff{DiffDelete, "ac"}, Diff{DiffEqual, "x"}},
+			[]Diff{Diff{DiffDelete, "abc"}, Diff{DiffEqual, "acx"}},
+		},
+		{
+			"Slide edit right recursive",
+			[]Diff{Diff{DiffEqual, "x"}, Diff{DiffDelete, "ca"}, Diff{DiffEqual, "c"}, Diff{DiffDelete, "b"}, Diff{DiffEqual, "a"}},
+			[]Diff{Diff{DiffEqual, "xca"}, Diff{DiffDelete, "cba"}},
+		},
+	} {
+		actual := dmp.DiffCleanupMerge(tc.Diffs)
+		assert.Equal(t, tc.Expected, actual, fmt.Sprintf("Test case #%d, %s", i, tc.Name))
+	}
 }
 
-func Test_diffCleanupSemantic(t *testing.T) {
+func TestDiffCleanupSemanticLossless(t *testing.T) {
+	type TestCase struct {
+		Name string
+
+		Diffs []Diff
+
+		Expected []Diff
+	}
+
 	dmp := New()
-	// Cleanup semantically trivial equalities.
-	// Null case.
-	diffs := []Diff{}
-	diffs = dmp.DiffCleanupSemantic(diffs)
-	assertDiffEqual(t, []Diff{}, diffs)
 
-	// No elimination #1.
-	diffs = []Diff{
-		Diff{DiffDelete, "ab"},
-		Diff{DiffInsert, "cd"},
-		Diff{DiffEqual, "12"},
-		Diff{DiffDelete, "e"}}
-	diffs = dmp.DiffCleanupSemantic(diffs)
-	assertDiffEqual(t, []Diff{
-		Diff{DiffDelete, "ab"},
-		Diff{DiffInsert, "cd"},
-		Diff{DiffEqual, "12"},
-		Diff{DiffDelete, "e"}}, diffs)
-
-	// No elimination #2.
-	diffs = []Diff{
-		Diff{DiffDelete, "abc"},
-		Diff{DiffInsert, "ABC"},
-		Diff{DiffEqual, "1234"},
-		Diff{DiffDelete, "wxyz"}}
-	diffs = dmp.DiffCleanupSemantic(diffs)
-	assertDiffEqual(t, []Diff{
-		Diff{DiffDelete, "abc"},
-		Diff{DiffInsert, "ABC"},
-		Diff{DiffEqual, "1234"},
-		Diff{DiffDelete, "wxyz"}}, diffs)
-
-	// No elimination #3.
-	diffs = []Diff{
-		Diff{DiffEqual, "2016-09-01T03:07:1"},
-		Diff{DiffInsert, "5.15"},
-		Diff{DiffEqual, "4"},
-		Diff{DiffDelete, "."},
-		Diff{DiffEqual, "80"},
-		Diff{DiffInsert, "0"},
-		Diff{DiffEqual, "78"},
-		Diff{DiffDelete, "3074"},
-		Diff{DiffEqual, "1Z"}}
-	diffs = dmp.DiffCleanupSemantic(diffs)
-	assertDiffEqual(t, []Diff{
-		Diff{DiffEqual, "2016-09-01T03:07:1"},
-		Diff{DiffInsert, "5.15"},
-		Diff{DiffEqual, "4"},
-		Diff{DiffDelete, "."},
-		Diff{DiffEqual, "80"},
-		Diff{DiffInsert, "0"},
-		Diff{DiffEqual, "78"},
-		Diff{DiffDelete, "3074"},
-		Diff{DiffEqual, "1Z"}}, diffs)
-
-	// Simple elimination.
-	diffs = []Diff{
-		Diff{DiffDelete, "a"},
-		Diff{DiffEqual, "b"},
-		Diff{DiffDelete, "c"}}
-	diffs = dmp.DiffCleanupSemantic(diffs)
-	assertDiffEqual(t, []Diff{
-		Diff{DiffDelete, "abc"},
-		Diff{DiffInsert, "b"}}, diffs)
-
-	// Backpass elimination.
-	diffs = []Diff{
-		Diff{DiffDelete, "ab"},
-		Diff{DiffEqual, "cd"},
-		Diff{DiffDelete, "e"},
-		Diff{DiffEqual, "f"},
-		Diff{DiffInsert, "g"}}
-	diffs = dmp.DiffCleanupSemantic(diffs)
-	assertDiffEqual(t, []Diff{
-		Diff{DiffDelete, "abcdef"},
-		Diff{DiffInsert, "cdfg"}}, diffs)
-
-	// Multiple eliminations.
-	diffs = []Diff{
-		Diff{DiffInsert, "1"},
-		Diff{DiffEqual, "A"},
-		Diff{DiffDelete, "B"},
-		Diff{DiffInsert, "2"},
-		Diff{DiffEqual, "_"},
-		Diff{DiffInsert, "1"},
-		Diff{DiffEqual, "A"},
-		Diff{DiffDelete, "B"},
-		Diff{DiffInsert, "2"}}
-	diffs = dmp.DiffCleanupSemantic(diffs)
-	assertDiffEqual(t, []Diff{
-		Diff{DiffDelete, "AB_AB"},
-		Diff{DiffInsert, "1A2_1A2"}}, diffs)
-
-	// Word boundaries.
-	diffs = []Diff{
-		Diff{DiffEqual, "The c"},
-		Diff{DiffDelete, "ow and the c"},
-		Diff{DiffEqual, "at."}}
-	diffs = dmp.DiffCleanupSemantic(diffs)
-	assertDiffEqual(t, []Diff{
-		Diff{DiffEqual, "The "},
-		Diff{DiffDelete, "cow and the "},
-		Diff{DiffEqual, "cat."}}, diffs)
-
-	// No overlap elimination.
-	diffs = []Diff{
-		Diff{DiffDelete, "abcxx"},
-		Diff{DiffInsert, "xxdef"}}
-	diffs = dmp.DiffCleanupSemantic(diffs)
-	assertDiffEqual(t, []Diff{
-		Diff{DiffDelete, "abcxx"},
-		Diff{DiffInsert, "xxdef"}}, diffs)
-
-	// Overlap elimination.
-	diffs = []Diff{
-		Diff{DiffDelete, "abcxxx"},
-		Diff{DiffInsert, "xxxdef"}}
-	diffs = dmp.DiffCleanupSemantic(diffs)
-	assertDiffEqual(t, []Diff{
-		Diff{DiffDelete, "abc"},
-		Diff{DiffEqual, "xxx"},
-		Diff{DiffInsert, "def"}}, diffs)
-
-	// Reverse overlap elimination.
-	diffs = []Diff{
-		Diff{DiffDelete, "xxxabc"},
-		Diff{DiffInsert, "defxxx"}}
-	diffs = dmp.DiffCleanupSemantic(diffs)
-	assertDiffEqual(t, []Diff{
-		Diff{DiffInsert, "def"},
-		Diff{DiffEqual, "xxx"},
-		Diff{DiffDelete, "abc"}}, diffs)
-
-	// Two overlap eliminations.
-	diffs = []Diff{
-		Diff{DiffDelete, "abcd1212"},
-		Diff{DiffInsert, "1212efghi"},
-		Diff{DiffEqual, "----"},
-		Diff{DiffDelete, "A3"},
-		Diff{DiffInsert, "3BC"}}
-	diffs = dmp.DiffCleanupSemantic(diffs)
-	assertDiffEqual(t, []Diff{
-		Diff{DiffDelete, "abcd"},
-		Diff{DiffEqual, "1212"},
-		Diff{DiffInsert, "efghi"},
-		Diff{DiffEqual, "----"},
-		Diff{DiffDelete, "A"},
-		Diff{DiffEqual, "3"},
-		Diff{DiffInsert, "BC"}}, diffs)
-
-	// Test case for adapting DiffCleanupSemantic to be equal to the Python version #19
-	diffs = dmp.DiffMain("James McCarthy close to signing new Everton deal", "James McCarthy signs new five-year deal at Everton", false)
-	diffs = dmp.DiffCleanupSemantic(diffs)
-	assertDiffEqual(t, []Diff{
-		Diff{DiffEqual, "James McCarthy "},
-		Diff{DiffDelete, "close to "},
-		Diff{DiffEqual, "sign"},
-		Diff{DiffDelete, "ing"},
-		Diff{DiffInsert, "s"},
-		Diff{DiffEqual, " new "},
-		Diff{DiffInsert, "five-year deal at "},
-		Diff{DiffEqual, "Everton"},
-		Diff{DiffDelete, " deal"},
-	}, diffs)
+	for i, tc := range []TestCase{
+		{
+			"Null case",
+			[]Diff{},
+			[]Diff{},
+		},
+		{
+			"Blank lines",
+			[]Diff{
+				Diff{DiffEqual, "AAA\r\n\r\nBBB"},
+				Diff{DiffInsert, "\r\nDDD\r\n\r\nBBB"},
+				Diff{DiffEqual, "\r\nEEE"},
+			},
+			[]Diff{
+				Diff{DiffEqual, "AAA\r\n\r\n"},
+				Diff{DiffInsert, "BBB\r\nDDD\r\n\r\n"},
+				Diff{DiffEqual, "BBB\r\nEEE"},
+			},
+		},
+		{
+			"Line boundaries",
+			[]Diff{
+				Diff{DiffEqual, "AAA\r\nBBB"},
+				Diff{DiffInsert, " DDD\r\nBBB"},
+				Diff{DiffEqual, " EEE"},
+			},
+			[]Diff{
+				Diff{DiffEqual, "AAA\r\n"},
+				Diff{DiffInsert, "BBB DDD\r\n"},
+				Diff{DiffEqual, "BBB EEE"},
+			},
+		},
+		{
+			"Word boundaries",
+			[]Diff{
+				Diff{DiffEqual, "The c"},
+				Diff{DiffInsert, "ow and the c"},
+				Diff{DiffEqual, "at."},
+			},
+			[]Diff{
+				Diff{DiffEqual, "The "},
+				Diff{DiffInsert, "cow and the "},
+				Diff{DiffEqual, "cat."},
+			},
+		},
+		{
+			"Alphanumeric boundaries",
+			[]Diff{
+				Diff{DiffEqual, "The-c"},
+				Diff{DiffInsert, "ow-and-the-c"},
+				Diff{DiffEqual, "at."},
+			},
+			[]Diff{
+				Diff{DiffEqual, "The-"},
+				Diff{DiffInsert, "cow-and-the-"},
+				Diff{DiffEqual, "cat."},
+			},
+		},
+		{
+			"Hitting the start",
+			[]Diff{
+				Diff{DiffEqual, "a"},
+				Diff{DiffDelete, "a"},
+				Diff{DiffEqual, "ax"},
+			},
+			[]Diff{
+				Diff{DiffDelete, "a"},
+				Diff{DiffEqual, "aax"},
+			},
+		},
+		{
+			"Hitting the end",
+			[]Diff{
+				Diff{DiffEqual, "xa"},
+				Diff{DiffDelete, "a"},
+				Diff{DiffEqual, "a"},
+			},
+			[]Diff{
+				Diff{DiffEqual, "xaa"},
+				Diff{DiffDelete, "a"},
+			},
+		},
+		{
+			"Sentence boundaries",
+			[]Diff{
+				Diff{DiffEqual, "The xxx. The "},
+				Diff{DiffInsert, "zzz. The "},
+				Diff{DiffEqual, "yyy."},
+			},
+			[]Diff{
+				Diff{DiffEqual, "The xxx."},
+				Diff{DiffInsert, " The zzz."},
+				Diff{DiffEqual, " The yyy."},
+			},
+		},
+		{
+			"UTF-8 strings",
+			[]Diff{
+				Diff{DiffEqual, "The ♕. The "},
+				Diff{DiffInsert, "♔. The "},
+				Diff{DiffEqual, "♖."},
+			},
+			[]Diff{
+				Diff{DiffEqual, "The ♕."},
+				Diff{DiffInsert, " The ♔."},
+				Diff{DiffEqual, " The ♖."},
+			},
+		},
+		{
+			"Rune boundaries",
+			[]Diff{
+				Diff{DiffEqual, "♕♕"},
+				Diff{DiffInsert, "♔♔"},
+				Diff{DiffEqual, "♖♖"},
+			},
+			[]Diff{
+				Diff{DiffEqual, "♕♕"},
+				Diff{DiffInsert, "♔♔"},
+				Diff{DiffEqual, "♖♖"},
+			},
+		},
+	} {
+		actual := dmp.DiffCleanupSemanticLossless(tc.Diffs)
+		assert.Equal(t, tc.Expected, actual, fmt.Sprintf("Test case #%d, %s", i, tc.Name))
+	}
 }
 
-func Test_diffCleanupEfficiency(t *testing.T) {
+func TestDiffCleanupSemantic(t *testing.T) {
+	type TestCase struct {
+		Name string
+
+		Diffs []Diff
+
+		Expected []Diff
+	}
+
 	dmp := New()
-	// Cleanup operationally trivial equalities.
+
+	for i, tc := range []TestCase{
+		{
+			"Null case",
+			[]Diff{},
+			[]Diff{},
+		},
+		{
+			"No elimination #1",
+			[]Diff{
+				{DiffDelete, "ab"},
+				{DiffInsert, "cd"},
+				{DiffEqual, "12"},
+				{DiffDelete, "e"},
+			},
+			[]Diff{
+				{DiffDelete, "ab"},
+				{DiffInsert, "cd"},
+				{DiffEqual, "12"},
+				{DiffDelete, "e"},
+			},
+		},
+		{
+			"No elimination #2",
+			[]Diff{
+				{DiffDelete, "abc"},
+				{DiffInsert, "ABC"},
+				{DiffEqual, "1234"},
+				{DiffDelete, "wxyz"},
+			},
+			[]Diff{
+				{DiffDelete, "abc"},
+				{DiffInsert, "ABC"},
+				{DiffEqual, "1234"},
+				{DiffDelete, "wxyz"},
+			},
+		},
+		{
+			"No elimination #3",
+			[]Diff{
+				{DiffEqual, "2016-09-01T03:07:1"},
+				{DiffInsert, "5.15"},
+				{DiffEqual, "4"},
+				{DiffDelete, "."},
+				{DiffEqual, "80"},
+				{DiffInsert, "0"},
+				{DiffEqual, "78"},
+				{DiffDelete, "3074"},
+				{DiffEqual, "1Z"},
+			},
+			[]Diff{
+				{DiffEqual, "2016-09-01T03:07:1"},
+				{DiffInsert, "5.15"},
+				{DiffEqual, "4"},
+				{DiffDelete, "."},
+				{DiffEqual, "80"},
+				{DiffInsert, "0"},
+				{DiffEqual, "78"},
+				{DiffDelete, "3074"},
+				{DiffEqual, "1Z"},
+			},
+		},
+		{
+			"Simple elimination",
+			[]Diff{
+				{DiffDelete, "a"},
+				{DiffEqual, "b"},
+				{DiffDelete, "c"},
+			},
+			[]Diff{
+				{DiffDelete, "abc"},
+				{DiffInsert, "b"},
+			},
+		},
+		{
+			"Backpass elimination",
+			[]Diff{
+				{DiffDelete, "ab"},
+				{DiffEqual, "cd"},
+				{DiffDelete, "e"},
+				{DiffEqual, "f"},
+				{DiffInsert, "g"},
+			},
+			[]Diff{
+				{DiffDelete, "abcdef"},
+				{DiffInsert, "cdfg"},
+			},
+		},
+		{
+			"Multiple eliminations",
+			[]Diff{
+				{DiffInsert, "1"},
+				{DiffEqual, "A"},
+				{DiffDelete, "B"},
+				{DiffInsert, "2"},
+				{DiffEqual, "_"},
+				{DiffInsert, "1"},
+				{DiffEqual, "A"},
+				{DiffDelete, "B"},
+				{DiffInsert, "2"},
+			},
+			[]Diff{
+				{DiffDelete, "AB_AB"},
+				{DiffInsert, "1A2_1A2"},
+			},
+		},
+		{
+			"Word boundaries",
+			[]Diff{
+				{DiffEqual, "The c"},
+				{DiffDelete, "ow and the c"},
+				{DiffEqual, "at."},
+			},
+			[]Diff{
+				{DiffEqual, "The "},
+				{DiffDelete, "cow and the "},
+				{DiffEqual, "cat."},
+			},
+		},
+		{
+			"No overlap elimination",
+			[]Diff{
+				{DiffDelete, "abcxx"},
+				{DiffInsert, "xxdef"},
+			},
+			[]Diff{
+				{DiffDelete, "abcxx"},
+				{DiffInsert, "xxdef"},
+			},
+		},
+		{
+			"Overlap elimination",
+			[]Diff{
+				{DiffDelete, "abcxxx"},
+				{DiffInsert, "xxxdef"},
+			},
+			[]Diff{
+				{DiffDelete, "abc"},
+				{DiffEqual, "xxx"},
+				{DiffInsert, "def"},
+			},
+		},
+		{
+			"Reverse overlap elimination",
+			[]Diff{
+				{DiffDelete, "xxxabc"},
+				{DiffInsert, "defxxx"},
+			},
+			[]Diff{
+				{DiffInsert, "def"},
+				{DiffEqual, "xxx"},
+				{DiffDelete, "abc"},
+			},
+		},
+		{
+			"Two overlap eliminations",
+			[]Diff{
+				{DiffDelete, "abcd1212"},
+				{DiffInsert, "1212efghi"},
+				{DiffEqual, "----"},
+				{DiffDelete, "A3"},
+				{DiffInsert, "3BC"},
+			},
+			[]Diff{
+				{DiffDelete, "abcd"},
+				{DiffEqual, "1212"},
+				{DiffInsert, "efghi"},
+				{DiffEqual, "----"},
+				{DiffDelete, "A"},
+				{DiffEqual, "3"},
+				{DiffInsert, "BC"},
+			},
+		},
+		{
+			"Test case for adapting DiffCleanupSemantic to be equal to the Python version #19",
+			[]Diff{
+				{DiffEqual, "James McCarthy "},
+				{DiffDelete, "close to "},
+				{DiffEqual, "sign"},
+				{DiffDelete, "ing"},
+				{DiffInsert, "s"},
+				{DiffEqual, " new "},
+				{DiffDelete, "E"},
+				{DiffInsert, "fi"},
+				{DiffEqual, "ve"},
+				{DiffInsert, "-yea"},
+				{DiffEqual, "r"},
+				{DiffDelete, "ton"},
+				{DiffEqual, " deal"},
+				{DiffInsert, " at Everton"},
+			},
+			[]Diff{
+				{DiffEqual, "James McCarthy "},
+				{DiffDelete, "close to "},
+				{DiffEqual, "sign"},
+				{DiffDelete, "ing"},
+				{DiffInsert, "s"},
+				{DiffEqual, " new "},
+				{DiffInsert, "five-year deal at "},
+				{DiffEqual, "Everton"},
+				{DiffDelete, " deal"},
+			},
+		},
+	} {
+		actual := dmp.DiffCleanupSemantic(tc.Diffs)
+		assert.Equal(t, tc.Expected, actual, fmt.Sprintf("Test case #%d, %s", i, tc.Name))
+	}
+}
+
+func TestDiffCleanupEfficiency(t *testing.T) {
+	type TestCase struct {
+		Name string
+
+		Diffs []Diff
+
+		Expected []Diff
+	}
+
+	dmp := New()
 	dmp.DiffEditCost = 4
-	// Null case.
-	diffs := []Diff{}
-	diffs = dmp.DiffCleanupEfficiency(diffs)
-	assertDiffEqual(t, []Diff{}, diffs)
 
-	// No elimination.
-	diffs = []Diff{
-		Diff{DiffDelete, "ab"},
-		Diff{DiffInsert, "12"},
-		Diff{DiffEqual, "wxyz"},
-		Diff{DiffDelete, "cd"},
-		Diff{DiffInsert, "34"}}
-	diffs = dmp.DiffCleanupEfficiency(diffs)
-	assertDiffEqual(t, []Diff{
-		Diff{DiffDelete, "ab"},
-		Diff{DiffInsert, "12"},
-		Diff{DiffEqual, "wxyz"},
-		Diff{DiffDelete, "cd"},
-		Diff{DiffInsert, "34"}}, diffs)
+	for i, tc := range []TestCase{
+		{
+			"Null case",
+			[]Diff{},
+			[]Diff{},
+		},
+		{
+			"No elimination",
+			[]Diff{
+				Diff{DiffDelete, "ab"},
+				Diff{DiffInsert, "12"},
+				Diff{DiffEqual, "wxyz"},
+				Diff{DiffDelete, "cd"},
+				Diff{DiffInsert, "34"},
+			},
+			[]Diff{
+				Diff{DiffDelete, "ab"},
+				Diff{DiffInsert, "12"},
+				Diff{DiffEqual, "wxyz"},
+				Diff{DiffDelete, "cd"},
+				Diff{DiffInsert, "34"},
+			},
+		},
+		{
+			"Four-edit elimination",
+			[]Diff{
+				Diff{DiffDelete, "ab"},
+				Diff{DiffInsert, "12"},
+				Diff{DiffEqual, "xyz"},
+				Diff{DiffDelete, "cd"},
+				Diff{DiffInsert, "34"},
+			},
+			[]Diff{
+				Diff{DiffDelete, "abxyzcd"},
+				Diff{DiffInsert, "12xyz34"},
+			},
+		},
+		{
+			"Three-edit elimination",
+			[]Diff{
+				Diff{DiffInsert, "12"},
+				Diff{DiffEqual, "x"},
+				Diff{DiffDelete, "cd"},
+				Diff{DiffInsert, "34"},
+			},
+			[]Diff{
+				Diff{DiffDelete, "xcd"},
+				Diff{DiffInsert, "12x34"},
+			},
+		},
+		{
+			"Backpass elimination",
+			[]Diff{
+				Diff{DiffDelete, "ab"},
+				Diff{DiffInsert, "12"},
+				Diff{DiffEqual, "xy"},
+				Diff{DiffInsert, "34"},
+				Diff{DiffEqual, "z"},
+				Diff{DiffDelete, "cd"},
+				Diff{DiffInsert, "56"},
+			},
+			[]Diff{
+				Diff{DiffDelete, "abxyzcd"},
+				Diff{DiffInsert, "12xy34z56"},
+			},
+		},
+	} {
+		actual := dmp.DiffCleanupEfficiency(tc.Diffs)
+		assert.Equal(t, tc.Expected, actual, fmt.Sprintf("Test case #%d, %s", i, tc.Name))
+	}
 
-	// Four-edit elimination.
-	diffs = []Diff{
-		Diff{DiffDelete, "ab"},
-		Diff{DiffInsert, "12"},
-		Diff{DiffEqual, "xyz"},
-		Diff{DiffDelete, "cd"},
-		Diff{DiffInsert, "34"}}
-	diffs = dmp.DiffCleanupEfficiency(diffs)
-	assertDiffEqual(t, []Diff{
-		Diff{DiffDelete, "abxyzcd"},
-		Diff{DiffInsert, "12xyz34"}}, diffs)
-
-	// Three-edit elimination.
-	diffs = []Diff{
-		Diff{DiffInsert, "12"},
-		Diff{DiffEqual, "x"},
-		Diff{DiffDelete, "cd"},
-		Diff{DiffInsert, "34"}}
-	diffs = dmp.DiffCleanupEfficiency(diffs)
-	assertDiffEqual(t, []Diff{
-		Diff{DiffDelete, "xcd"},
-		Diff{DiffInsert, "12x34"}}, diffs)
-
-	// Backpass elimination.
-	diffs = []Diff{
-		Diff{DiffDelete, "ab"},
-		Diff{DiffInsert, "12"},
-		Diff{DiffEqual, "xy"},
-		Diff{DiffInsert, "34"},
-		Diff{DiffEqual, "z"},
-		Diff{DiffDelete, "cd"},
-		Diff{DiffInsert, "56"}}
-	diffs = dmp.DiffCleanupEfficiency(diffs)
-	assertDiffEqual(t, []Diff{
-		Diff{DiffDelete, "abxyzcd"},
-		Diff{DiffInsert, "12xy34z56"}}, diffs)
-
-	// High cost elimination.
 	dmp.DiffEditCost = 5
-	diffs = []Diff{
-		Diff{DiffDelete, "ab"},
-		Diff{DiffInsert, "12"},
-		Diff{DiffEqual, "wxyz"},
-		Diff{DiffDelete, "cd"},
-		Diff{DiffInsert, "34"}}
-	diffs = dmp.DiffCleanupEfficiency(diffs)
-	assertDiffEqual(t, []Diff{
-		Diff{DiffDelete, "abwxyzcd"},
-		Diff{DiffInsert, "12wxyz34"}}, diffs)
-	dmp.DiffEditCost = 4
+
+	for i, tc := range []TestCase{
+		{
+			"High cost elimination",
+			[]Diff{
+				Diff{DiffDelete, "ab"},
+				Diff{DiffInsert, "12"},
+				Diff{DiffEqual, "wxyz"},
+				Diff{DiffDelete, "cd"},
+				Diff{DiffInsert, "34"},
+			},
+			[]Diff{
+				Diff{DiffDelete, "abwxyzcd"},
+				Diff{DiffInsert, "12wxyz34"},
+			},
+		},
+	} {
+		actual := dmp.DiffCleanupEfficiency(tc.Diffs)
+		assert.Equal(t, tc.Expected, actual, fmt.Sprintf("Test case #%d, %s", i, tc.Name))
+	}
 }
 
-func Test_diffPrettyHtml(t *testing.T) {
+func TestDiffPrettyHtml(t *testing.T) {
+	type TestCase struct {
+		Diffs []Diff
+
+		Expected string
+	}
+
 	dmp := New()
-	// Pretty print.
-	diffs := []Diff{
-		Diff{DiffEqual, "a\n"},
-		Diff{DiffDelete, "<B>b</B>"},
-		Diff{DiffInsert, "c&d"}}
-	assert.Equal(t, "<span>a&para;<br></span><del style=\"background:#ffe6e6;\">&lt;B&gt;b&lt;/B&gt;</del><ins style=\"background:#e6ffe6;\">c&amp;d</ins>",
-		dmp.DiffPrettyHtml(diffs))
+
+	for i, tc := range []TestCase{
+		{
+			Diffs: []Diff{
+				{DiffEqual, "a\n"},
+				{DiffDelete, "<B>b</B>"},
+				{DiffInsert, "c&d"},
+			},
+
+			Expected: "<span>a&para;<br></span><del style=\"background:#ffe6e6;\">&lt;B&gt;b&lt;/B&gt;</del><ins style=\"background:#e6ffe6;\">c&amp;d</ins>",
+		},
+	} {
+		actual := dmp.DiffPrettyHtml(tc.Diffs)
+		assert.Equal(t, tc.Expected, actual, fmt.Sprintf("Test case #%d, %#v", i, tc))
+	}
 }
 
-func Test_diffPrettyText(t *testing.T) {
+func TestDiffPrettyText(t *testing.T) {
+	type TestCase struct {
+		Diffs []Diff
+
+		Expected string
+	}
+
 	dmp := New()
-	// Pretty print.
-	diffs := []Diff{
-		Diff{DiffEqual, "a\n"},
-		Diff{DiffDelete, "<B>b</B>"},
-		Diff{DiffInsert, "c&d"}}
-	assert.Equal(t, "a\n\x1b[31m<B>b</B>\x1b[0m\x1b[32mc&d\x1b[0m",
-		dmp.DiffPrettyText(diffs))
+
+	for i, tc := range []TestCase{
+		{
+			Diffs: []Diff{
+				{DiffEqual, "a\n"},
+				{DiffDelete, "<B>b</B>"},
+				{DiffInsert, "c&d"},
+			},
+
+			Expected: "a\n\x1b[31m<B>b</B>\x1b[0m\x1b[32mc&d\x1b[0m",
+		},
+	} {
+		actual := dmp.DiffPrettyText(tc.Diffs)
+		assert.Equal(t, tc.Expected, actual, fmt.Sprintf("Test case #%d, %#v", i, tc))
+	}
 }
 
-func Test_diffText(t *testing.T) {
+func TestDiffText(t *testing.T) {
+	type TestCase struct {
+		Diffs []Diff
+
+		ExpectedText1 string
+		ExpectedText2 string
+	}
+
 	dmp := New()
-	// Compute the source and destination texts.
-	diffs := []Diff{
-		Diff{DiffEqual, "jump"},
-		Diff{DiffDelete, "s"},
-		Diff{DiffInsert, "ed"},
-		Diff{DiffEqual, " over "},
-		Diff{DiffDelete, "the"},
-		Diff{DiffInsert, "a"},
-		Diff{DiffEqual, " lazy"}}
-	assert.Equal(t, "jumps over the lazy", dmp.DiffText1(diffs))
-	assert.Equal(t, "jumped over a lazy", dmp.DiffText2(diffs))
+
+	for i, tc := range []TestCase{
+		{
+			Diffs: []Diff{
+				{DiffEqual, "jump"},
+				{DiffDelete, "s"},
+				{DiffInsert, "ed"},
+				{DiffEqual, " over "},
+				{DiffDelete, "the"},
+				{DiffInsert, "a"},
+				{DiffEqual, " lazy"},
+			},
+
+			ExpectedText1: "jumps over the lazy",
+			ExpectedText2: "jumped over a lazy",
+		},
+	} {
+		actualText1 := dmp.DiffText1(tc.Diffs)
+		assert.Equal(t, tc.ExpectedText1, actualText1, fmt.Sprintf("Test case #%d, %#v", i, tc))
+
+		actualText2 := dmp.DiffText2(tc.Diffs)
+		assert.Equal(t, tc.ExpectedText2, actualText2, fmt.Sprintf("Test case #%d, %#v", i, tc))
+	}
 }
 
-func Test_diffDelta(t *testing.T) {
+func TestDiffDelta(t *testing.T) {
 	dmp := New()
+
 	// Convert a diff into delta string.
 	diffs := []Diff{
 		Diff{DiffEqual, "jump"},
@@ -810,8 +1006,8 @@
 		Diff{DiffDelete, "the"},
 		Diff{DiffInsert, "a"},
 		Diff{DiffEqual, " lazy"},
-		Diff{DiffInsert, "old dog"}}
-
+		Diff{DiffInsert, "old dog"},
+	}
 	text1 := dmp.DiffText1(diffs)
 	assert.Equal(t, "jumps over the lazy", text1)
 
@@ -819,205 +1015,294 @@
 	assert.Equal(t, "=4\t-1\t+ed\t=6\t-3\t+a\t=5\t+old dog", delta)
 
 	// Convert delta string into a diff.
-	_seq1, err := dmp.DiffFromDelta(text1, delta)
-	assertDiffEqual(t, diffs, _seq1)
+	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("diff_fromDelta: Too long.")
+		t.Fatal("Too long.")
 	}
 
 	// Generates error (19 > 18).
 	_, err = dmp.DiffFromDelta(text1[1:], delta)
 	if err == nil {
-		t.Fatal("diff_fromDelta: Too short.")
+		t.Fatal("Too short.")
 	}
 
 	// Generates error (%xy invalid URL escape).
 	_, err = dmp.DiffFromDelta("", "+%c3%xy")
 	if err == nil {
-		assert.Fail(t, "diff_fromDelta: expected Invalid URL escape.")
+		assert.Fail(t, "expected Invalid URL escape.")
 	}
 
 	// Generates error (invalid utf8).
 	_, err = dmp.DiffFromDelta("", "+%c3xy")
 	if err == nil {
-		assert.Fail(t, "diff_fromDelta: expected Invalid utf8.")
+		assert.Fail(t, "expected Invalid utf8.")
 	}
 
 	// Test deltas with special characters.
 	diffs = []Diff{
 		Diff{DiffEqual, "\u0680 \x00 \t %"},
 		Diff{DiffDelete, "\u0681 \x01 \n ^"},
-		Diff{DiffInsert, "\u0682 \x02 \\ |"}}
+		Diff{DiffInsert, "\u0682 \x02 \\ |"},
+	}
 	text1 = dmp.DiffText1(diffs)
 	assert.Equal(t, "\u0680 \x00 \t %\u0681 \x01 \n ^", text1)
 
-	delta = dmp.DiffToDelta(diffs)
 	// Lowercase, due to UrlEncode uses lower.
+	delta = dmp.DiffToDelta(diffs)
 	assert.Equal(t, "=7\t-7\t+%DA%82 %02 %5C %7C", delta)
 
-	_res1, err := dmp.DiffFromDelta(text1, delta)
-	if err != nil {
-		t.Fatal(err)
-	}
-	assertDiffEqual(t, diffs, _res1)
+	deltaDiffs, err = dmp.DiffFromDelta(text1, delta)
+	assert.Equal(t, diffs, deltaDiffs)
+	assert.Nil(t, err)
 
 	// Verify pool of unchanged characters.
 	diffs = []Diff{
-		Diff{DiffInsert, "A-Z a-z 0-9 - _ . ! ~ * ' ( ) ; / ? : @ & = + $ , # "}}
-	text2 := dmp.DiffText2(diffs)
-	assert.Equal(t, "A-Z a-z 0-9 - _ . ! ~ * ' ( ) ; / ? : @ & = + $ , # ", text2, "diff_text2: Unchanged characters.")
+		Diff{DiffInsert, "A-Z a-z 0-9 - _ . ! ~ * ' ( ) ; / ? : @ & = + $ , # "},
+	}
 
 	delta = dmp.DiffToDelta(diffs)
-	assert.Equal(t, "+A-Z a-z 0-9 - _ . ! ~ * ' ( ) ; / ? : @ & = + $ , # ", delta, "diff_toDelta: Unchanged characters.")
+	assert.Equal(t, "+A-Z a-z 0-9 - _ . ! ~ * ' ( ) ; / ? : @ & = + $ , # ", delta, "Unchanged characters.")
 
 	// Convert delta string into a diff.
-	_res2, _ := dmp.DiffFromDelta("", delta)
-	assertDiffEqual(t, diffs, _res2)
+	deltaDiffs, err = dmp.DiffFromDelta("", delta)
+	assert.Equal(t, diffs, deltaDiffs)
+	assert.Nil(t, err)
 }
 
-func Test_diffXIndex(t *testing.T) {
-	dmp := New()
-	// Translate a location in text1 to text2.
-	diffs := []Diff{
-		Diff{DiffDelete, "a"},
-		Diff{DiffInsert, "1234"},
-		Diff{DiffEqual, "xyz"}}
-	assert.Equal(t, 5, dmp.DiffXIndex(diffs, 2), "diff_xIndex: Translation on equality.")
+func TestDiffXIndex(t *testing.T) {
+	type TestCase struct {
+		Name string
 
-	diffs = []Diff{
-		Diff{DiffEqual, "a"},
-		Diff{DiffDelete, "1234"},
-		Diff{DiffEqual, "xyz"}}
-	assert.Equal(t, 1, dmp.DiffXIndex(diffs, 3), "diff_xIndex: Translation on deletion.")
+		Diffs    []Diff
+		Location int
+
+		Expected int
+	}
+
+	dmp := New()
+
+	for i, tc := range []TestCase{
+		{"Translation on equality", []Diff{{DiffDelete, "a"}, {DiffInsert, "1234"}, {DiffEqual, "xyz"}}, 2, 5},
+		{"Translation on deletion", []Diff{{DiffEqual, "a"}, {DiffDelete, "1234"}, {DiffEqual, "xyz"}}, 3, 1},
+	} {
+		actual := dmp.DiffXIndex(tc.Diffs, tc.Location)
+		assert.Equal(t, tc.Expected, actual, fmt.Sprintf("Test case #%d, %s", i, tc.Name))
+	}
 }
 
-func Test_diffLevenshtein(t *testing.T) {
+func TestDiffLevenshtein(t *testing.T) {
+	type TestCase struct {
+		Name string
+
+		Diffs []Diff
+
+		Expected int
+	}
+
 	dmp := New()
-	diffs := []Diff{
-		Diff{DiffDelete, "abc"},
-		Diff{DiffInsert, "1234"},
-		Diff{DiffEqual, "xyz"}}
-	assert.Equal(t, 4, dmp.DiffLevenshtein(diffs), "diff_levenshtein: Levenshtein with trailing equality.")
 
-	diffs = []Diff{
-		Diff{DiffEqual, "xyz"},
-		Diff{DiffDelete, "abc"},
-		Diff{DiffInsert, "1234"}}
-	assert.Equal(t, 4, dmp.DiffLevenshtein(diffs), "diff_levenshtein: Levenshtein with leading equality.")
-
-	diffs = []Diff{
-		Diff{DiffDelete, "abc"},
-		Diff{DiffEqual, "xyz"},
-		Diff{DiffInsert, "1234"}}
-	assert.Equal(t, 7, dmp.DiffLevenshtein(diffs), "diff_levenshtein: Levenshtein with middle equality.")
+	for i, tc := range []TestCase{
+		{"Levenshtein with trailing equality", []Diff{{DiffDelete, "abc"}, {DiffInsert, "1234"}, {DiffEqual, "xyz"}}, 4},
+		{"Levenshtein with leading equality", []Diff{{DiffEqual, "xyz"}, {DiffDelete, "abc"}, {DiffInsert, "1234"}}, 4},
+		{"Levenshtein with middle equality", []Diff{{DiffDelete, "abc"}, {DiffEqual, "xyz"}, {DiffInsert, "1234"}}, 7},
+	} {
+		actual := dmp.DiffLevenshtein(tc.Diffs)
+		assert.Equal(t, tc.Expected, actual, fmt.Sprintf("Test case #%d, %s", i, tc.Name))
+	}
 }
 
-func Test_diffBisect(t *testing.T) {
+func TestDiffBisect(t *testing.T) {
+	type TestCase struct {
+		Name string
+
+		Time time.Time
+
+		Expected []Diff
+	}
+
 	dmp := New()
-	// Normal.
-	a := "cat"
-	b := "map"
-	// 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.
-	correctDiffs := []Diff{
-		Diff{DiffDelete, "c"},
-		Diff{DiffInsert, "m"},
-		Diff{DiffEqual, "a"},
-		Diff{DiffDelete, "t"},
-		Diff{DiffInsert, "p"}}
 
-	assertDiffEqual(t, correctDiffs, dmp.DiffBisect(a, b, time.Date(9999, time.December, 31, 23, 59, 59, 59, time.UTC)))
+	text1 := "cat"
+	text2 := "map"
 
-	// Timeout.
-	diffs := []Diff{Diff{DiffDelete, "cat"}, Diff{DiffInsert, "map"}}
-	assertDiffEqual(t, diffs, dmp.DiffBisect(a, b, time.Now().Add(time.Nanosecond)))
+	for i, tc := range []TestCase{
+		{
+			Name: "normal",
+			Time: time.Date(9999, time.December, 31, 23, 59, 59, 59, time.UTC),
 
-	// 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)))
+			Expected: []Diff{
+				{DiffDelete, "c"},
+				{DiffInsert, "m"},
+				{DiffEqual, "a"},
+				{DiffDelete, "t"},
+				{DiffInsert, "p"},
+			},
+		},
+		{
+			Name: "Negative deadlines count as having infinite time",
+			Time: time.Date(0001, time.January, 01, 00, 00, 00, 00, time.UTC),
+
+			Expected: []Diff{
+				{DiffDelete, "c"},
+				{DiffInsert, "m"},
+				{DiffEqual, "a"},
+				{DiffDelete, "t"},
+				{DiffInsert, "p"},
+			},
+		},
+		{
+			Name: "Timeout",
+			Time: time.Now().Add(time.Nanosecond),
+
+			Expected: []Diff{
+				{DiffDelete, "cat"},
+				{DiffInsert, "map"},
+			},
+		},
+	} {
+		actual := dmp.DiffBisect(text1, text2, tc.Time)
+		assert.Equal(t, tc.Expected, actual, fmt.Sprintf("Test case #%d, %s", i, tc.Name))
+	}
 }
 
-func Test_diffMain(t *testing.T) {
+func TestDiffMain(t *testing.T) {
+	type TestCase struct {
+		Text1 string
+		Text2 string
+
+		Expected []Diff
+	}
+
 	dmp := New()
+
 	// Perform a trivial diff.
-	diffs := []Diff{}
-	assertDiffEqual(t, diffs, dmp.DiffMain("", "", false))
+	for i, tc := range []TestCase{
+		{
+			"",
+			"",
+			nil,
+		},
+		{
+			"abc",
+			"abc",
+			[]Diff{Diff{DiffEqual, "abc"}},
+		},
+		{
+			"abc",
+			"ab123c",
+			[]Diff{Diff{DiffEqual, "ab"}, Diff{DiffInsert, "123"}, Diff{DiffEqual, "c"}},
+		},
+		{
+			"a123bc",
+			"abc",
+			[]Diff{Diff{DiffEqual, "a"}, Diff{DiffDelete, "123"}, Diff{DiffEqual, "bc"}},
+		},
+		{
+			"abc",
+			"a123b456c",
+			[]Diff{Diff{DiffEqual, "a"}, Diff{DiffInsert, "123"}, Diff{DiffEqual, "b"}, Diff{DiffInsert, "456"}, Diff{DiffEqual, "c"}},
+		},
+		{
+			"a123b456c",
+			"abc",
+			[]Diff{Diff{DiffEqual, "a"}, Diff{DiffDelete, "123"}, Diff{DiffEqual, "b"}, Diff{DiffDelete, "456"}, Diff{DiffEqual, "c"}},
+		},
+	} {
+		actual := dmp.DiffMain(tc.Text1, tc.Text2, false)
+		assert.Equal(t, tc.Expected, actual, fmt.Sprintf("Test case #%d, %#v", i, tc))
+	}
 
-	diffs = []Diff{Diff{DiffEqual, "abc"}}
-	assertDiffEqual(t, diffs, dmp.DiffMain("abc", "abc", false))
-
-	diffs = []Diff{Diff{DiffEqual, "ab"}, Diff{DiffInsert, "123"}, Diff{DiffEqual, "c"}}
-	assertDiffEqual(t, diffs, dmp.DiffMain("abc", "ab123c", false))
-
-	diffs = []Diff{Diff{DiffEqual, "a"}, Diff{DiffDelete, "123"}, Diff{DiffEqual, "bc"}}
-	assertDiffEqual(t, diffs, dmp.DiffMain("a123bc", "abc", false))
-
-	diffs = []Diff{Diff{DiffEqual, "a"}, Diff{DiffInsert, "123"}, Diff{DiffEqual, "b"}, Diff{DiffInsert, "456"}, Diff{DiffEqual, "c"}}
-	assertDiffEqual(t, diffs, dmp.DiffMain("abc", "a123b456c", false))
-
-	diffs = []Diff{Diff{DiffEqual, "a"}, Diff{DiffDelete, "123"}, Diff{DiffEqual, "b"}, Diff{DiffDelete, "456"}, Diff{DiffEqual, "c"}}
-	assertDiffEqual(t, diffs, dmp.DiffMain("a123b456c", "abc", false))
-
-	// Perform a real diff.
-	// Switch off the timeout.
+	// Perform a real diff and switch off the timeout.
 	dmp.DiffTimeout = 0
-	diffs = []Diff{Diff{DiffDelete, "a"}, Diff{DiffInsert, "b"}}
-	assertDiffEqual(t, diffs, dmp.DiffMain("a", "b", false))
 
-	diffs = []Diff{
-		Diff{DiffDelete, "Apple"},
-		Diff{DiffInsert, "Banana"},
-		Diff{DiffEqual, "s are a"},
-		Diff{DiffInsert, "lso"},
-		Diff{DiffEqual, " fruit."}}
-	assertDiffEqual(t, diffs, dmp.DiffMain("Apples are a fruit.", "Bananas are also fruit.", false))
+	for i, tc := range []TestCase{
+		{
+			"a",
+			"b",
+			[]Diff{Diff{DiffDelete, "a"}, Diff{DiffInsert, "b"}},
+		},
+		{
+			"Apples are a fruit.",
+			"Bananas are also fruit.",
+			[]Diff{
+				Diff{DiffDelete, "Apple"},
+				Diff{DiffInsert, "Banana"},
+				Diff{DiffEqual, "s are a"},
+				Diff{DiffInsert, "lso"},
+				Diff{DiffEqual, " fruit."},
+			},
+		},
+		{
+			"ax\t",
+			"\u0680x\u0000",
+			[]Diff{
+				Diff{DiffDelete, "a"},
+				Diff{DiffInsert, "\u0680"},
+				Diff{DiffEqual, "x"},
+				Diff{DiffDelete, "\t"},
+				Diff{DiffInsert, "\u0000"},
+			},
+		},
+		{
+			"1ayb2",
+			"abxab",
+			[]Diff{
+				Diff{DiffDelete, "1"},
+				Diff{DiffEqual, "a"},
+				Diff{DiffDelete, "y"},
+				Diff{DiffEqual, "b"},
+				Diff{DiffDelete, "2"},
+				Diff{DiffInsert, "xab"},
+			},
+		},
+		{
+			"abcy",
+			"xaxcxabc",
+			[]Diff{
+				Diff{DiffInsert, "xaxcx"},
+				Diff{DiffEqual, "abc"}, Diff{DiffDelete, "y"},
+			},
+		},
+		{
+			"ABCDa=bcd=efghijklmnopqrsEFGHIJKLMNOefg",
+			"a-bcd-efghijklmnopqrs",
+			[]Diff{
+				Diff{DiffDelete, "ABCD"},
+				Diff{DiffEqual, "a"},
+				Diff{DiffDelete, "="},
+				Diff{DiffInsert, "-"},
+				Diff{DiffEqual, "bcd"},
+				Diff{DiffDelete, "="},
+				Diff{DiffInsert, "-"},
+				Diff{DiffEqual, "efghijklmnopqrs"},
+				Diff{DiffDelete, "EFGHIJKLMNOefg"},
+			},
+		},
+		{
+			"a [[Pennsylvania]] and [[New",
+			" and [[Pennsylvania]]",
+			[]Diff{
+				Diff{DiffInsert, " "},
+				Diff{DiffEqual, "a"},
+				Diff{DiffInsert, "nd"},
+				Diff{DiffEqual, " [[Pennsylvania]]"},
+				Diff{DiffDelete, " and [[New"},
+			},
+		},
+	} {
+		actual := dmp.DiffMain(tc.Text1, tc.Text2, false)
+		assert.Equal(t, tc.Expected, actual, fmt.Sprintf("Test case #%d, %#v", i, tc))
+	}
+}
 
-	diffs = []Diff{
-		Diff{DiffDelete, "a"},
-		Diff{DiffInsert, "\u0680"},
-		Diff{DiffEqual, "x"},
-		Diff{DiffDelete, "\t"},
-		Diff{DiffInsert, "\u0000"}}
-	assertDiffEqual(t, diffs, dmp.DiffMain("ax\t", "\u0680x\u0000", false))
-
-	diffs = []Diff{
-		Diff{DiffDelete, "1"},
-		Diff{DiffEqual, "a"},
-		Diff{DiffDelete, "y"},
-		Diff{DiffEqual, "b"},
-		Diff{DiffDelete, "2"},
-		Diff{DiffInsert, "xab"}}
-	assertDiffEqual(t, diffs, dmp.DiffMain("1ayb2", "abxab", false))
-
-	diffs = []Diff{
-		Diff{DiffInsert, "xaxcx"},
-		Diff{DiffEqual, "abc"}, Diff{DiffDelete, "y"}}
-	assertDiffEqual(t, diffs, dmp.DiffMain("abcy", "xaxcxabc", false))
-
-	diffs = []Diff{
-		Diff{DiffDelete, "ABCD"},
-		Diff{DiffEqual, "a"},
-		Diff{DiffDelete, "="},
-		Diff{DiffInsert, "-"},
-		Diff{DiffEqual, "bcd"},
-		Diff{DiffDelete, "="},
-		Diff{DiffInsert, "-"},
-		Diff{DiffEqual, "efghijklmnopqrs"},
-		Diff{DiffDelete, "EFGHIJKLMNOefg"}}
-	assertDiffEqual(t, diffs, dmp.DiffMain("ABCDa=bcd=efghijklmnopqrsEFGHIJKLMNOefg", "a-bcd-efghijklmnopqrs", false))
-
-	diffs = []Diff{
-		Diff{DiffInsert, " "},
-		Diff{DiffEqual, "a"},
-		Diff{DiffInsert, "nd"},
-		Diff{DiffEqual, " [[Pennsylvania]]"},
-		Diff{DiffDelete, " and [[New"}}
-	assertDiffEqual(t, diffs, dmp.DiffMain("a [[Pennsylvania]] and [[New", " and [[Pennsylvania]]", false))
-
+func TestDiffMainWithTimeout(t *testing.T) {
+	dmp := New()
 	dmp.DiffTimeout = 200 * time.Millisecond
+
 	a := "`Twas brillig, and the slithy toves\nDid gyre and gimble in the wabe:\nAll mimsy were the borogoves,\nAnd the mome raths outgrabe.\n"
 	b := "I am the very model of a modern major general,\nI've information vegetable, animal, and mineral,\nI know the kings of England, and I quote the fights historical,\nFrom Marathon to Waterloo, in order categorical.\n"
 	// Increase the text lengths by 1024 times to ensure a timeout.
@@ -1029,415 +1314,527 @@
 	startTime := time.Now()
 	dmp.DiffMain(a, b, true)
 	endTime := time.Now()
+
 	delta := endTime.Sub(startTime)
+
 	// Test that we took at least the timeout period.
 	assert.True(t, delta >= dmp.DiffTimeout, fmt.Sprintf("%v !>= %v", delta, dmp.DiffTimeout))
+
 	// Test that we didn't take forever (be very forgiving).
 	// Theoretically this test could fail very occasionally if the
 	// OS task swaps or locks up for a second at the wrong moment.
 	assert.True(t, delta < (dmp.DiffTimeout*100), fmt.Sprintf("%v !< %v", delta, dmp.DiffTimeout*100))
+}
+
+func TestDiffMainWithCheckLines(t *testing.T) {
+	type TestCase struct {
+		Text1 string
+		Text2 string
+	}
+
+	dmp := New()
 	dmp.DiffTimeout = 0
 
-	// Test the linemode speedup.
-	// Must be long to pass the 100 char cutoff.
-	a = "1234567890\n1234567890\n1234567890\n1234567890\n1234567890\n1234567890\n1234567890\n1234567890\n1234567890\n1234567890\n1234567890\n1234567890\n1234567890\n"
-	b = "abcdefghij\nabcdefghij\nabcdefghij\nabcdefghij\nabcdefghij\nabcdefghij\nabcdefghij\nabcdefghij\nabcdefghij\nabcdefghij\nabcdefghij\nabcdefghij\nabcdefghij\n"
-	assertDiffEqual(t, dmp.DiffMain(a, b, true), dmp.DiffMain(a, b, false))
+	// Test cases must be at least 100 chars long to pass the cutoff.
+	for i, tc := range []TestCase{
+		{
+			"1234567890\n1234567890\n1234567890\n1234567890\n1234567890\n1234567890\n1234567890\n1234567890\n1234567890\n1234567890\n1234567890\n1234567890\n1234567890\n",
+			"abcdefghij\nabcdefghij\nabcdefghij\nabcdefghij\nabcdefghij\nabcdefghij\nabcdefghij\nabcdefghij\nabcdefghij\nabcdefghij\nabcdefghij\nabcdefghij\nabcdefghij\n",
+		},
+		{
+			"1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890",
+			"abcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghij",
+		},
+		{
+			"1234567890\n1234567890\n1234567890\n1234567890\n1234567890\n1234567890\n1234567890\n1234567890\n1234567890\n1234567890\n1234567890\n1234567890\n1234567890\n",
+			"abcdefghij\n1234567890\n1234567890\n1234567890\nabcdefghij\n1234567890\n1234567890\n1234567890\nabcdefghij\n1234567890\n1234567890\n1234567890\nabcdefghij\n",
+		},
+	} {
+		resultWithoutCheckLines := dmp.DiffMain(tc.Text1, tc.Text2, false)
+		resultWithCheckLines := dmp.DiffMain(tc.Text1, tc.Text2, true)
 
-	a = "1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890"
-	b = "abcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghij"
-	assertDiffEqual(t, dmp.DiffMain(a, b, true), dmp.DiffMain(a, b, false))
-
-	a = "1234567890\n1234567890\n1234567890\n1234567890\n1234567890\n1234567890\n1234567890\n1234567890\n1234567890\n1234567890\n1234567890\n1234567890\n1234567890\n"
-	b = "abcdefghij\n1234567890\n1234567890\n1234567890\nabcdefghij\n1234567890\n1234567890\n1234567890\nabcdefghij\n1234567890\n1234567890\n1234567890\nabcdefghij\n"
-	textsLinemode := diffRebuildtexts(dmp.DiffMain(a, b, true))
-	textsTextmode := diffRebuildtexts(dmp.DiffMain(a, b, false))
-	assertStrEqual(t, textsTextmode, textsLinemode)
-
-	// Test null inputs -- not needed because nulls can't be passed in Go.
+		// TODO this fails for the third test case, why?
+		if i != 2 {
+			assert.Equal(t, resultWithoutCheckLines, resultWithCheckLines, fmt.Sprintf("Test case #%d, %#v", i, tc))
+		}
+		assert.Equal(t, diffRebuildTexts(resultWithoutCheckLines), diffRebuildTexts(resultWithCheckLines), fmt.Sprintf("Test case #%d, %#v", i, tc))
+	}
 }
 
-func Test_match_alphabet(t *testing.T) {
+func TestMatchAlphabet(t *testing.T) {
+	type TestCase struct {
+		Pattern string
+
+		Expected map[byte]int
+	}
+
 	dmp := New()
 
-	bitmask := map[byte]int{
-		'a': 4,
-		'b': 2,
-		'c': 1,
-	}
-	assert.Equal(t, bitmask, dmp.MatchAlphabet("abc"))
+	for i, tc := range []TestCase{
+		{
+			Pattern: "abc",
 
-	bitmask = map[byte]int{
-		'a': 37,
-		'b': 18,
-		'c': 8,
+			Expected: map[byte]int{
+				'a': 4,
+				'b': 2,
+				'c': 1,
+			},
+		},
+		{
+			Pattern: "abcaba",
+
+			Expected: map[byte]int{
+				'a': 37,
+				'b': 18,
+				'c': 8,
+			},
+		},
+	} {
+		actual := dmp.MatchAlphabet(tc.Pattern)
+		assert.Equal(t, tc.Expected, actual, fmt.Sprintf("Test case #%d, %#v", i, tc))
 	}
-	assert.Equal(t, bitmask, dmp.MatchAlphabet("abcaba"))
 }
 
-func Test_match_bitap(t *testing.T) {
-	dmp := New()
+func TestMatchBitap(t *testing.T) {
+	type TestCase struct {
+		Name string
 
-	// Bitap algorithm.
+		Text     string
+		Pattern  string
+		Location int
+
+		Expected int
+	}
+
+	dmp := New()
 	dmp.MatchDistance = 100
 	dmp.MatchThreshold = 0.5
-	assert.Equal(t, 5, dmp.MatchBitap("abcdefghijk", "fgh", 5), "match_bitap: Exact match #1.")
 
-	assert.Equal(t, 5, dmp.MatchBitap("abcdefghijk", "fgh", 0), "match_bitap: Exact match #2.")
-
-	assert.Equal(t, 4, dmp.MatchBitap("abcdefghijk", "efxhi", 0), "match_bitap: Fuzzy match #1.")
-
-	assert.Equal(t, 2, dmp.MatchBitap("abcdefghijk", "cdefxyhijk", 5), "match_bitap: Fuzzy match #2.")
-
-	assert.Equal(t, -1, dmp.MatchBitap("abcdefghijk", "bxy", 1), "match_bitap: Fuzzy match #3.")
-
-	assert.Equal(t, 2, dmp.MatchBitap("123456789xx0", "3456789x0", 2), "match_bitap: Overflow.")
-
-	assert.Equal(t, 0, dmp.MatchBitap("abcdef", "xxabc", 4), "match_bitap: Before start match.")
-
-	assert.Equal(t, 3, dmp.MatchBitap("abcdef", "defyy", 4), "match_bitap: Beyond end match.")
-
-	assert.Equal(t, 0, dmp.MatchBitap("abcdef", "xabcdefy", 0), "match_bitap: Oversized pattern.")
+	for i, tc := range []TestCase{
+		{"Exact match #1", "abcdefghijk", "fgh", 5, 5},
+		{"Exact match #2", "abcdefghijk", "fgh", 0, 5},
+		{"Fuzzy match #1", "abcdefghijk", "efxhi", 0, 4},
+		{"Fuzzy match #2", "abcdefghijk", "cdefxyhijk", 5, 2},
+		{"Fuzzy match #3", "abcdefghijk", "bxy", 1, -1},
+		{"Overflow", "123456789xx0", "3456789x0", 2, 2},
+		{"Before start match", "abcdef", "xxabc", 4, 0},
+		{"Beyond end match", "abcdef", "defyy", 4, 3},
+		{"Oversized pattern", "abcdef", "xabcdefy", 0, 0},
+	} {
+		actual := dmp.MatchBitap(tc.Text, tc.Pattern, tc.Location)
+		assert.Equal(t, tc.Expected, actual, fmt.Sprintf("Test case #%d, %s", i, tc.Name))
+	}
 
 	dmp.MatchThreshold = 0.4
-	assert.Equal(t, 4, dmp.MatchBitap("abcdefghijk", "efxyhi", 1), "match_bitap: Threshold #1.")
+
+	for i, tc := range []TestCase{
+		{"Threshold #1", "abcdefghijk", "efxyhi", 1, 4},
+	} {
+		actual := dmp.MatchBitap(tc.Text, tc.Pattern, tc.Location)
+		assert.Equal(t, tc.Expected, actual, fmt.Sprintf("Test case #%d, %s", i, tc.Name))
+	}
 
 	dmp.MatchThreshold = 0.3
-	assert.Equal(t, -1, dmp.MatchBitap("abcdefghijk", "efxyhi", 1), "match_bitap: Threshold #2.")
+
+	for i, tc := range []TestCase{
+		{"Threshold #2", "abcdefghijk", "efxyhi", 1, -1},
+	} {
+		actual := dmp.MatchBitap(tc.Text, tc.Pattern, tc.Location)
+		assert.Equal(t, tc.Expected, actual, fmt.Sprintf("Test case #%d, %s", i, tc.Name))
+	}
 
 	dmp.MatchThreshold = 0.0
-	assert.Equal(t, 1, dmp.MatchBitap("abcdefghijk", "bcdef", 1), "match_bitap: Threshold #3.")
+
+	for i, tc := range []TestCase{
+		{"Threshold #3", "abcdefghijk", "bcdef", 1, 1},
+	} {
+		actual := dmp.MatchBitap(tc.Text, tc.Pattern, tc.Location)
+		assert.Equal(t, tc.Expected, actual, fmt.Sprintf("Test case #%d, %s", i, tc.Name))
+	}
 
 	dmp.MatchThreshold = 0.5
-	assert.Equal(t, 0, dmp.MatchBitap("abcdexyzabcde", "abccde", 3), "match_bitap: Multiple select #1.")
 
-	assert.Equal(t, 8, dmp.MatchBitap("abcdexyzabcde", "abccde", 5), "match_bitap: Multiple select #2.")
+	for i, tc := range []TestCase{
+		{"Multiple select #1", "abcdexyzabcde", "abccde", 3, 0},
+		{"Multiple select #2", "abcdexyzabcde", "abccde", 5, 8},
+	} {
+		actual := dmp.MatchBitap(tc.Text, tc.Pattern, tc.Location)
+		assert.Equal(t, tc.Expected, actual, fmt.Sprintf("Test case #%d, %s", i, tc.Name))
+	}
 
-	dmp.MatchDistance = 10 // Strict location.
-	assert.Equal(t, -1, dmp.MatchBitap("abcdefghijklmnopqrstuvwxyz", "abcdefg", 24), "match_bitap: Distance test #1.")
+	// Strict location.
+	dmp.MatchDistance = 10
 
-	assert.Equal(t, 0, dmp.MatchBitap("abcdefghijklmnopqrstuvwxyz", "abcdxxefg", 1), "match_bitap: Distance test #2.")
+	for i, tc := range []TestCase{
+		{"Distance test #1", "abcdefghijklmnopqrstuvwxyz", "abcdefg", 24, -1},
+		{"Distance test #2", "abcdefghijklmnopqrstuvwxyz", "abcdxxefg", 1, 0},
+	} {
+		actual := dmp.MatchBitap(tc.Text, tc.Pattern, tc.Location)
+		assert.Equal(t, tc.Expected, actual, fmt.Sprintf("Test case #%d, %s", i, tc.Name))
+	}
 
-	dmp.MatchDistance = 1000 // Loose location.
-	assert.Equal(t, 0, dmp.MatchBitap("abcdefghijklmnopqrstuvwxyz", "abcdefg", 24), "match_bitap: Distance test #3.")
+	// Loose location.
+	dmp.MatchDistance = 1000
+
+	for i, tc := range []TestCase{
+		{"Distance test #3", "abcdefghijklmnopqrstuvwxyz", "abcdefg", 24, 0},
+	} {
+		actual := dmp.MatchBitap(tc.Text, tc.Pattern, tc.Location)
+		assert.Equal(t, tc.Expected, actual, fmt.Sprintf("Test case #%d, %s", i, tc.Name))
+	}
 }
 
-func Test_MatchMain(t *testing.T) {
+func TestMatchMain(t *testing.T) {
+	type TestCase struct {
+		Name string
+
+		Text1    string
+		Text2    string
+		Location int
+
+		Expected int
+	}
+
 	dmp := New()
-	// Full match.
-	assert.Equal(t, 0, dmp.MatchMain("abcdef", "abcdef", 1000), "MatchMain: Equality.")
 
-	assert.Equal(t, -1, dmp.MatchMain("", "abcdef", 1), "MatchMain: Null text.")
-
-	assert.Equal(t, 3, dmp.MatchMain("abcdef", "", 3), "MatchMain: Null pattern.")
-
-	assert.Equal(t, 3, dmp.MatchMain("abcdef", "de", 3), "MatchMain: Exact match.")
-
-	assert.Equal(t, 3, dmp.MatchMain("abcdef", "defy", 4), "MatchMain: Beyond end match.")
-
-	assert.Equal(t, 0, dmp.MatchMain("abcdef", "abcdefy", 0), "MatchMain: Oversized pattern.")
+	for i, tc := range []TestCase{
+		{"Equality", "abcdef", "abcdef", 1000, 0},
+		{"Null text", "", "abcdef", 1, -1},
+		{"Null pattern", "abcdef", "", 3, 3},
+		{"Exact match", "abcdef", "de", 3, 3},
+		{"Beyond end match", "abcdef", "defy", 4, 3},
+		{"Oversized pattern", "abcdef", "abcdefy", 0, 0},
+	} {
+		actual := dmp.MatchMain(tc.Text1, tc.Text2, tc.Location)
+		assert.Equal(t, tc.Expected, actual, fmt.Sprintf("Test case #%d, %s", i, tc.Name))
+	}
 
 	dmp.MatchThreshold = 0.7
-	assert.Equal(t, 4, dmp.MatchMain("I am the very model of a modern major general.", " that berry ", 5), "MatchMain: Complex match.")
-	dmp.MatchThreshold = 0.5
 
-	// Test null inputs -- not needed because nulls can't be passed in C#.
+	for i, tc := range []TestCase{
+		{"Complex match", "I am the very model of a modern major general.", " that berry ", 5, 4},
+	} {
+		actual := dmp.MatchMain(tc.Text1, tc.Text2, tc.Location)
+		assert.Equal(t, tc.Expected, actual, fmt.Sprintf("Test case #%d, %#v", i, tc))
+	}
 }
 
-func Test_patch_patchObj(t *testing.T) {
-	// Patch Object.
-	p := Patch{}
-	p.start1 = 20
-	p.start2 = 21
-	p.length1 = 18
-	p.length2 = 17
-	p.diffs = []Diff{
-		Diff{DiffEqual, "jump"},
-		Diff{DiffDelete, "s"},
-		Diff{DiffInsert, "ed"},
-		Diff{DiffEqual, " over "},
-		Diff{DiffDelete, "the"},
-		Diff{DiffInsert, "a"},
-		Diff{DiffEqual, "\nlaz"}}
-	strp := "@@ -21,18 +22,17 @@\n jump\n-s\n+ed\n  over \n-the\n+a\n %0Alaz\n"
+func TestPatchString(t *testing.T) {
+	type TestCase struct {
+		Patch Patch
 
-	assert.Equal(t, strp, p.String(), "Patch: toString.")
+		Expected string
+	}
+
+	for i, tc := range []TestCase{
+		{
+			Patch: Patch{
+				start1:  20,
+				start2:  21,
+				length1: 18,
+				length2: 17,
+
+				diffs: []Diff{
+					{DiffEqual, "jump"},
+					{DiffDelete, "s"},
+					{DiffInsert, "ed"},
+					{DiffEqual, " over "},
+					{DiffDelete, "the"},
+					{DiffInsert, "a"},
+					{DiffEqual, "\nlaz"},
+				},
+			},
+
+			Expected: "@@ -21,18 +22,17 @@\n jump\n-s\n+ed\n  over \n-the\n+a\n %0Alaz\n",
+		},
+	} {
+		actual := tc.Patch.String()
+		assert.Equal(t, tc.Expected, actual, fmt.Sprintf("Test case #%d, %#v", i, tc))
+	}
 }
 
-func Test_patch_fromText(t *testing.T) {
+func TestPatchFromText(t *testing.T) {
+	type TestCase struct {
+		Patch string
+
+		ErrorMessagePrefix string
+	}
+
 	dmp := New()
 
-	_v1, _ := dmp.PatchFromText("")
-	assert.True(t, len(_v1) == 0, "patch_fromText: #0.")
-	strp := "@@ -21,18 +22,17 @@\n jump\n-s\n+ed\n  over \n-the\n+a\n %0Alaz\n"
-	_v2, _ := dmp.PatchFromText(strp)
-	assert.Equal(t, strp, _v2[0].String(), "patch_fromText: #1.")
+	for i, tc := range []TestCase{
+		{"", ""},
+		{"@@ -21,18 +22,17 @@\n jump\n-s\n+ed\n  over \n-the\n+a\n %0Alaz\n", ""},
+		{"@@ -1 +1 @@\n-a\n+b\n", ""},
+		{"@@ -1,3 +0,0 @@\n-abc\n", ""},
+		{"@@ -0,0 +1,3 @@\n+abc\n", ""},
+		{"Bad\nPatch\n", "Invalid patch string"},
+	} {
+		patches, err := dmp.PatchFromText(tc.Patch)
+		if tc.ErrorMessagePrefix == "" {
+			assert.Nil(t, err)
 
-	_v3, _ := dmp.PatchFromText("@@ -1 +1 @@\n-a\n+b\n")
-	assert.Equal(t, "@@ -1 +1 @@\n-a\n+b\n", _v3[0].String(), "patch_fromText: #2.")
+			if tc.Patch == "" {
+				assert.Equal(t, []Patch{}, patches, fmt.Sprintf("Test case #%d, %#v", i, tc))
+			} else {
+				assert.Equal(t, tc.Patch, patches[0].String(), fmt.Sprintf("Test case #%d, %#v", i, tc))
+			}
+		} else {
+			e := err.Error()
+			if strings.HasPrefix(e, tc.ErrorMessagePrefix) {
+				e = tc.ErrorMessagePrefix
+			}
+			assert.Equal(t, tc.ErrorMessagePrefix, e)
+		}
+	}
 
-	_v4, _ := dmp.PatchFromText("@@ -1,3 +0,0 @@\n-abc\n")
-	assert.Equal(t, "@@ -1,3 +0,0 @@\n-abc\n", _v4[0].String(), "patch_fromText: #3.")
+	diffs := []Diff{
+		{DiffDelete, "`1234567890-=[]\\;',./"},
+		{DiffInsert, "~!@#$%^&*()_+{}|:\"<>?"},
+	}
 
-	_v5, _ := dmp.PatchFromText("@@ -0,0 +1,3 @@\n+abc\n")
-	assert.Equal(t, "@@ -0,0 +1,3 @@\n+abc\n", _v5[0].String(), "patch_fromText: #4.")
-
-	// Generates error.
-	_, err := dmp.PatchFromText("Bad\nPatch\n")
-	assert.True(t, err != nil, "There should be an error")
+	patches, err := dmp.PatchFromText("@@ -1,21 +1,21 @@\n-%601234567890-=%5B%5D%5C;',./\n+~!@#$%25%5E&*()_+%7B%7D%7C:%22%3C%3E?\n")
+	assert.Len(t, patches, 1)
+	assert.Equal(t, diffs,
+		patches[0].diffs,
+	)
+	assert.Nil(t, err)
 }
 
-func Test_patch_toText(t *testing.T) {
+func TestPatchToText(t *testing.T) {
+	type TestCase struct {
+		Patch string
+	}
+
 	dmp := New()
-	strp := "@@ -21,18 +22,17 @@\n jump\n-s\n+ed\n  over \n-the\n+a\n  laz\n"
-	var patches []Patch
-	patches, _ = dmp.PatchFromText(strp)
-	result := dmp.PatchToText(patches)
-	assert.Equal(t, strp, result)
 
-	strp = "@@ -1,9 +1,9 @@\n-f\n+F\n oo+fooba\n@@ -7,9 +7,9 @@\n obar\n-,\n+.\n  tes\n"
-	patches, _ = dmp.PatchFromText(strp)
-	result = dmp.PatchToText(patches)
-	assert.Equal(t, strp, result)
+	for i, tc := range []TestCase{
+		{"@@ -21,18 +22,17 @@\n jump\n-s\n+ed\n  over \n-the\n+a\n  laz\n"},
+		{"@@ -1,9 +1,9 @@\n-f\n+F\n oo+fooba\n@@ -7,9 +7,9 @@\n obar\n-,\n+.\n  tes\n"},
+	} {
+		patches, err := dmp.PatchFromText(tc.Patch)
+		assert.Nil(t, err)
+
+		actual := dmp.PatchToText(patches)
+		assert.Equal(t, tc.Patch, actual, fmt.Sprintf("Test case #%d, %#v", i, tc))
+	}
 }
 
-func Test_patch_addContext(t *testing.T) {
+func TestPatchAddContext(t *testing.T) {
+	type TestCase struct {
+		Name string
+
+		Patch string
+		Text  string
+
+		Expected string
+	}
+
 	dmp := New()
 	dmp.PatchMargin = 4
-	var p Patch
-	_p, _ := dmp.PatchFromText("@@ -21,4 +21,10 @@\n-jump\n+somersault\n")
-	p = _p[0]
-	p = dmp.PatchAddContext(p, "The quick brown fox jumps over the lazy dog.")
-	assert.Equal(t, "@@ -17,12 +17,18 @@\n fox \n-jump\n+somersault\n s ov\n", p.String(), "patch_addContext: Simple case.")
 
-	_p, _ = dmp.PatchFromText("@@ -21,4 +21,10 @@\n-jump\n+somersault\n")
-	p = _p[0]
-	p = dmp.PatchAddContext(p, "The quick brown fox jumps.")
-	assert.Equal(t, "@@ -17,10 +17,16 @@\n fox \n-jump\n+somersault\n s.\n", p.String(), "patch_addContext: Not enough trailing context.")
+	for i, tc := range []TestCase{
+		{"Simple case", "@@ -21,4 +21,10 @@\n-jump\n+somersault\n", "The quick brown fox jumps over the lazy dog.", "@@ -17,12 +17,18 @@\n fox \n-jump\n+somersault\n s ov\n"},
+		{"Not enough trailing context", "@@ -21,4 +21,10 @@\n-jump\n+somersault\n", "The quick brown fox jumps.", "@@ -17,10 +17,16 @@\n fox \n-jump\n+somersault\n s.\n"},
+		{"Not enough leading context", "@@ -3 +3,2 @@\n-e\n+at\n", "The quick brown fox jumps.", "@@ -1,7 +1,8 @@\n Th\n-e\n+at\n  qui\n"},
+		{"Ambiguity", "@@ -3 +3,2 @@\n-e\n+at\n", "The quick brown fox jumps.  The quick brown fox crashes.", "@@ -1,27 +1,28 @@\n Th\n-e\n+at\n  quick brown fox jumps. \n"},
+	} {
+		patches, err := dmp.PatchFromText(tc.Patch)
+		assert.Nil(t, err)
 
-	_p, _ = dmp.PatchFromText("@@ -3 +3,2 @@\n-e\n+at\n")
-	p = _p[0]
-	p = dmp.PatchAddContext(p, "The quick brown fox jumps.")
-	assert.Equal(t, "@@ -1,7 +1,8 @@\n Th\n-e\n+at\n  qui\n", p.String(), "patch_addContext: Not enough leading context.")
-
-	_p, _ = dmp.PatchFromText("@@ -3 +3,2 @@\n-e\n+at\n")
-	p = _p[0]
-	p = dmp.PatchAddContext(p, "The quick brown fox jumps.  The quick brown fox crashes.")
-	assert.Equal(t, "@@ -1,27 +1,28 @@\n Th\n-e\n+at\n  quick brown fox jumps. \n", p.String(), "patch_addContext: Ambiguity.")
+		actual := dmp.PatchAddContext(patches[0], tc.Text)
+		assert.Equal(t, tc.Expected, actual.String(), fmt.Sprintf("Test case #%d, %s", i, tc.Name))
+	}
 }
 
-func Test_patch_make(t *testing.T) {
+// TODO
+func TestPatchMakeAndPatchToText(t *testing.T) {
+	type TestCase struct {
+		Name string
+
+		Input1 interface{}
+		Input2 interface{}
+		Input3 interface{}
+
+		Expected string
+	}
+
 	dmp := New()
-	var patches []Patch
-	patches = dmp.PatchMake("", "")
-	assert.Equal(t, "", dmp.PatchToText(patches), "patch_make: Null case.")
 
 	text1 := "The quick brown fox jumps over the lazy dog."
 	text2 := "That quick brown fox jumped over a lazy dog."
-	expectedPatch := "@@ -1,8 +1,7 @@\n Th\n-at\n+e\n  qui\n@@ -21,17 +21,18 @@\n jump\n-ed\n+s\n  over \n-a\n+the\n  laz\n"
-	// The second patch must be "-21,17 +21,18", not "-22,17 +21,18" due to rolling context.
-	patches = dmp.PatchMake(text2, text1)
-	assert.Equal(t, expectedPatch, dmp.PatchToText(patches), "patch_make: Text2+Text1 inputs.")
 
-	expectedPatch = "@@ -1,11 +1,12 @@\n Th\n-e\n+at\n  quick b\n@@ -22,18 +22,17 @@\n jump\n-s\n+ed\n  over \n-the\n+a\n  laz\n"
-	patches = dmp.PatchMake(text1, text2)
-	assert.Equal(t, expectedPatch, dmp.PatchToText(patches), "patch_make: Text1+Text2 inputs.")
+	for i, tc := range []TestCase{
+		{"Null case", "", "", nil, ""},
+		{"Text2+Text1 inputs", text2, text1, nil, "@@ -1,8 +1,7 @@\n Th\n-at\n+e\n  qui\n@@ -21,17 +21,18 @@\n jump\n-ed\n+s\n  over \n-a\n+the\n  laz\n"},
+		{"Text1+Text2 inputs", text1, text2, nil, "@@ -1,11 +1,12 @@\n Th\n-e\n+at\n  quick b\n@@ -22,18 +22,17 @@\n jump\n-s\n+ed\n  over \n-the\n+a\n  laz\n"},
+		{"Diff input", dmp.DiffMain(text1, text2, false), nil, nil, "@@ -1,11 +1,12 @@\n Th\n-e\n+at\n  quick b\n@@ -22,18 +22,17 @@\n jump\n-s\n+ed\n  over \n-the\n+a\n  laz\n"},
+		{"Text1+Diff inputs", text1, dmp.DiffMain(text1, text2, false), nil, "@@ -1,11 +1,12 @@\n Th\n-e\n+at\n  quick b\n@@ -22,18 +22,17 @@\n jump\n-s\n+ed\n  over \n-the\n+a\n  laz\n"},
+		{"Text1+Text2+Diff inputs (deprecated)", text1, text2, dmp.DiffMain(text1, text2, false), "@@ -1,11 +1,12 @@\n Th\n-e\n+at\n  quick b\n@@ -22,18 +22,17 @@\n jump\n-s\n+ed\n  over \n-the\n+a\n  laz\n"},
+		{"Character encoding", "`1234567890-=[]\\;',./", "~!@#$%^&*()_+{}|:\"<>?", nil, "@@ -1,21 +1,21 @@\n-%601234567890-=%5B%5D%5C;',./\n+~!@#$%25%5E&*()_+%7B%7D%7C:%22%3C%3E?\n"},
+		{"Long string with repeats", strings.Repeat("abcdef", 100), strings.Repeat("abcdef", 100) + "123", nil, "@@ -573,28 +573,31 @@\n cdefabcdefabcdefabcdefabcdef\n+123\n"},
+		{"Corner case of #31 fixed by #32", "2016-09-01T03:07:14.807830741Z", "2016-09-01T03:07:15.154800781Z", nil, "@@ -15,16 +15,16 @@\n 07:1\n+5.15\n 4\n-.\n 80\n+0\n 78\n-3074\n 1Z\n"},
+	} {
+		var patches []Patch
+		if tc.Input3 != nil {
+			patches = dmp.PatchMake(tc.Input1, tc.Input2, tc.Input3)
+		} else if tc.Input2 != nil {
+			patches = dmp.PatchMake(tc.Input1, tc.Input2)
+		} else if ps, ok := tc.Input1.([]Patch); ok {
+			patches = ps
+		} else {
+			patches = dmp.PatchMake(tc.Input1)
+		}
 
-	diffs := dmp.DiffMain(text1, text2, false)
-	patches = dmp.PatchMake(diffs)
-	assert.Equal(t, expectedPatch, dmp.PatchToText(patches), "patch_make: Diff input.")
-
-	patches = dmp.PatchMake(text1, diffs)
-	assert.Equal(t, expectedPatch, dmp.PatchToText(patches), "patch_make: Text1+Diff inputs.")
-
-	patches = dmp.PatchMake(text1, text2, diffs)
-	assert.Equal(t, expectedPatch, dmp.PatchToText(patches), "patch_make: Text1+Text2+Diff inputs (deprecated).")
-
-	patches = dmp.PatchMake("`1234567890-=[]\\;',./", "~!@#$%^&*()_+{}|:\"<>?")
-	assert.Equal(t, "@@ -1,21 +1,21 @@\n-%601234567890-=%5B%5D%5C;',./\n+~!@#$%25%5E&*()_+%7B%7D%7C:%22%3C%3E?\n",
-		dmp.PatchToText(patches),
-		"patch_toText: Character encoding.")
-
-	diffs = []Diff{
-		Diff{DiffDelete, "`1234567890-=[]\\;',./"},
-		Diff{DiffInsert, "~!@#$%^&*()_+{}|:\"<>?"}}
-
-	_p1, _ := dmp.PatchFromText("@@ -1,21 +1,21 @@\n-%601234567890-=%5B%5D%5C;',./\n+~!@#$%25%5E&*()_+%7B%7D%7C:%22%3C%3E?\n")
-	assertDiffEqual(t, diffs,
-		_p1[0].diffs,
-	)
-
-	text1 = ""
-	for x := 0; x < 100; x++ {
-		text1 += "abcdef"
+		actual := dmp.PatchToText(patches)
+		assert.Equal(t, tc.Expected, actual, fmt.Sprintf("Test case #%d, %s", i, tc.Name))
 	}
-	text2 = text1 + "123"
-	expectedPatch = "@@ -573,28 +573,31 @@\n cdefabcdefabcdefabcdefabcdef\n+123\n"
-	patches = dmp.PatchMake(text1, text2)
-	assert.Equal(t, expectedPatch, dmp.PatchToText(patches), "patch_make: Long string with repeats.")
 
-	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")
+	// Corner case of #28 wrong patch with timeout of 0
+	dmp.DiffTimeout = 0
 
 	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")
 
+	diffs := dmp.DiffMain(text1, text2, true)
 	// Additional check that the diff texts are equal to the originals even if we are using DiffMain with checklines=true #29
-	assert.Equal(t, text1, dmp2.DiffText1(diffs))
-	assert.Equal(t, text2, dmp2.DiffText2(diffs))
+	assert.Equal(t, text1, dmp.DiffText1(diffs))
+	assert.Equal(t, text2, dmp.DiffText2(diffs))
+
+	patches := dmp.PatchMake(text1, diffs)
+
+	actual := dmp.PatchToText(patches)
+	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", actual)
 }
 
-func Test_PatchSplitMax(t *testing.T) {
-	// Assumes that Match_MaxBits is 32.
-	dmp := New()
-	var patches []Patch
+func TestPatchSplitMax(t *testing.T) {
+	type TestCase struct {
+		Text1 string
+		Text2 string
 
-	patches = dmp.PatchMake("abcdefghijklmnopqrstuvwxyz01234567890", "XabXcdXefXghXijXklXmnXopXqrXstXuvXwxXyzX01X23X45X67X89X0")
-	patches = dmp.PatchSplitMax(patches)
-	assert.Equal(t, "@@ -1,32 +1,46 @@\n+X\n ab\n+X\n cd\n+X\n ef\n+X\n gh\n+X\n ij\n+X\n kl\n+X\n mn\n+X\n op\n+X\n qr\n+X\n st\n+X\n uv\n+X\n wx\n+X\n yz\n+X\n 012345\n@@ -25,13 +39,18 @@\n zX01\n+X\n 23\n+X\n 45\n+X\n 67\n+X\n 89\n+X\n 0\n", dmp.PatchToText(patches))
-
-	patches = dmp.PatchMake("abcdef1234567890123456789012345678901234567890123456789012345678901234567890uvwxyz", "abcdefuvwxyz")
-	oldToText := dmp.PatchToText(patches)
-	dmp.PatchSplitMax(patches)
-	assert.Equal(t, oldToText, dmp.PatchToText(patches))
-
-	patches = dmp.PatchMake("1234567890123456789012345678901234567890123456789012345678901234567890", "abc")
-	patches = dmp.PatchSplitMax(patches)
-	assert.Equal(t, "@@ -1,32 +1,4 @@\n-1234567890123456789012345678\n 9012\n@@ -29,32 +1,4 @@\n-9012345678901234567890123456\n 7890\n@@ -57,14 +1,3 @@\n-78901234567890\n+abc\n", dmp.PatchToText(patches))
-
-	patches = dmp.PatchMake("abcdefghij , h : 0 , t : 1 abcdefghij , h : 0 , t : 1 abcdefghij , h : 0 , t : 1", "abcdefghij , h : 1 , t : 1 abcdefghij , h : 1 , t : 1 abcdefghij , h : 0 , t : 1")
-	dmp.PatchSplitMax(patches)
-	assert.Equal(t, "@@ -2,32 +2,32 @@\n bcdefghij , h : \n-0\n+1\n  , t : 1 abcdef\n@@ -29,32 +29,32 @@\n bcdefghij , h : \n-0\n+1\n  , t : 1 abcdef\n", dmp.PatchToText(patches))
-}
-
-func Test_PatchAddPadding(t *testing.T) {
-	dmp := New()
-	var patches []Patch
-	patches = dmp.PatchMake("", "test")
-	pass := assert.Equal(t, "@@ -0,0 +1,4 @@\n+test\n",
-		dmp.PatchToText(patches),
-		"PatchAddPadding: Both edges full.")
-	if !pass {
-		t.FailNow()
+		Expected string
 	}
 
-	dmp.PatchAddPadding(patches)
-	assert.Equal(t, "@@ -1,8 +1,12 @@\n %01%02%03%04\n+test\n %01%02%03%04\n",
-		dmp.PatchToText(patches),
-		"PatchAddPadding: Both edges full.")
+	dmp := New()
 
-	patches = dmp.PatchMake("XY", "XtestY")
-	assert.Equal(t, "@@ -1,2 +1,6 @@\n X\n+test\n Y\n",
-		dmp.PatchToText(patches),
-		"PatchAddPadding: Both edges partial.")
-	dmp.PatchAddPadding(patches)
-	assert.Equal(t, "@@ -2,8 +2,12 @@\n %02%03%04X\n+test\n Y%01%02%03\n",
-		dmp.PatchToText(patches),
-		"PatchAddPadding: Both edges partial.")
+	for i, tc := range []TestCase{
+		{"abcdefghijklmnopqrstuvwxyz01234567890", "XabXcdXefXghXijXklXmnXopXqrXstXuvXwxXyzX01X23X45X67X89X0", "@@ -1,32 +1,46 @@\n+X\n ab\n+X\n cd\n+X\n ef\n+X\n gh\n+X\n ij\n+X\n kl\n+X\n mn\n+X\n op\n+X\n qr\n+X\n st\n+X\n uv\n+X\n wx\n+X\n yz\n+X\n 012345\n@@ -25,13 +39,18 @@\n zX01\n+X\n 23\n+X\n 45\n+X\n 67\n+X\n 89\n+X\n 0\n"},
+		{"abcdef1234567890123456789012345678901234567890123456789012345678901234567890uvwxyz", "abcdefuvwxyz", "@@ -3,78 +3,8 @@\n cdef\n-1234567890123456789012345678901234567890123456789012345678901234567890\n uvwx\n"},
+		{"1234567890123456789012345678901234567890123456789012345678901234567890", "abc", "@@ -1,32 +1,4 @@\n-1234567890123456789012345678\n 9012\n@@ -29,32 +1,4 @@\n-9012345678901234567890123456\n 7890\n@@ -57,14 +1,3 @@\n-78901234567890\n+abc\n"},
+		{"abcdefghij , h : 0 , t : 1 abcdefghij , h : 0 , t : 1 abcdefghij , h : 0 , t : 1", "abcdefghij , h : 1 , t : 1 abcdefghij , h : 1 , t : 1 abcdefghij , h : 0 , t : 1", "@@ -2,32 +2,32 @@\n bcdefghij , h : \n-0\n+1\n  , t : 1 abcdef\n@@ -29,32 +29,32 @@\n bcdefghij , h : \n-0\n+1\n  , t : 1 abcdef\n"},
+	} {
+		patches := dmp.PatchMake(tc.Text1, tc.Text2)
+		patches = dmp.PatchSplitMax(patches)
 
-	patches = dmp.PatchMake("XXXXYYYY", "XXXXtestYYYY")
-	assert.Equal(t, "@@ -1,8 +1,12 @@\n XXXX\n+test\n YYYY\n",
-		dmp.PatchToText(patches),
-		"PatchAddPadding: Both edges none.")
-	dmp.PatchAddPadding(patches)
-	assert.Equal(t, "@@ -5,8 +5,12 @@\n XXXX\n+test\n YYYY\n",
-		dmp.PatchToText(patches),
-		"PatchAddPadding: Both edges none.")
+		actual := dmp.PatchToText(patches)
+		assert.Equal(t, tc.Expected, actual, fmt.Sprintf("Test case #%d, %#v", i, tc))
+	}
 }
 
-func Test_patchApply(t *testing.T) {
+func TestPatchAddPadding(t *testing.T) {
+	type TestCase struct {
+		Name string
+
+		Text1 string
+		Text2 string
+
+		Expected            string
+		ExpectedWithPadding string
+	}
+
+	dmp := New()
+
+	for i, tc := range []TestCase{
+		{"Both edges full", "", "test", "@@ -0,0 +1,4 @@\n+test\n", "@@ -1,8 +1,12 @@\n %01%02%03%04\n+test\n %01%02%03%04\n"},
+		{"Both edges partial", "XY", "XtestY", "@@ -1,2 +1,6 @@\n X\n+test\n Y\n", "@@ -2,8 +2,12 @@\n %02%03%04X\n+test\n Y%01%02%03\n"},
+		{"Both edges none", "XXXXYYYY", "XXXXtestYYYY", "@@ -1,8 +1,12 @@\n XXXX\n+test\n YYYY\n", "@@ -5,8 +5,12 @@\n XXXX\n+test\n YYYY\n"},
+	} {
+		patches := dmp.PatchMake(tc.Text1, tc.Text2)
+
+		actual := dmp.PatchToText(patches)
+		assert.Equal(t, tc.Expected, actual, fmt.Sprintf("Test case #%d, %s", i, tc.Name))
+
+		dmp.PatchAddPadding(patches)
+
+		actualWithPadding := dmp.PatchToText(patches)
+		assert.Equal(t, tc.ExpectedWithPadding, actualWithPadding, fmt.Sprintf("Test case #%d, %s", i, tc.Name))
+	}
+}
+
+func TestPatchApply(t *testing.T) {
+	type TestCase struct {
+		Name string
+
+		Text1    string
+		Text2    string
+		TextBase string
+
+		Expected        string
+		ExpectedApplies []bool
+	}
+
 	dmp := New()
 	dmp.MatchDistance = 1000
 	dmp.MatchThreshold = 0.5
 	dmp.PatchDeleteThreshold = 0.5
-	patches := []Patch{}
-	patches = dmp.PatchMake("", "")
-	results0, results1 := dmp.PatchApply(patches, "Hello world.")
-	boolArray := results1
-	resultStr := fmt.Sprintf("%v\t%v", results0, len(boolArray))
-	pass := assert.Equal(t, "Hello world.\t0", resultStr, "patch_apply: Null case.")
-	if !pass {
-		t.FailNow()
+
+	for i, tc := range []TestCase{
+		{"Null case", "", "", "Hello world.", "Hello world.", []bool{}},
+		{"Exact match", "The quick brown fox jumps over the lazy dog.", "That quick brown fox jumped over a lazy dog.", "The quick brown fox jumps over the lazy dog.", "That quick brown fox jumped over a lazy dog.", []bool{true, true}},
+		{"Partial match", "The quick brown fox jumps over the lazy dog.", "That quick brown fox jumped over a lazy dog.", "The quick red rabbit jumps over the tired tiger.", "That quick red rabbit jumped over a tired tiger.", []bool{true, true}},
+		{"Failed match", "The quick brown fox jumps over the lazy dog.", "That quick brown fox jumped over a lazy dog.", "I am the very model of a modern major general.", "I am the very model of a modern major general.", []bool{false, false}},
+		{"Big delete, small Diff", "x1234567890123456789012345678901234567890123456789012345678901234567890y", "xabcy", "x123456789012345678901234567890-----++++++++++-----123456789012345678901234567890y", "xabcy", []bool{true, true}},
+		{"Big delete, big Diff 1", "x1234567890123456789012345678901234567890123456789012345678901234567890y", "xabcy", "x12345678901234567890---------------++++++++++---------------12345678901234567890y", "xabc12345678901234567890---------------++++++++++---------------12345678901234567890y", []bool{false, true}},
+	} {
+		patches := dmp.PatchMake(tc.Text1, tc.Text2)
+
+		actual, actualApplies := dmp.PatchApply(patches, tc.TextBase)
+		assert.Equal(t, tc.Expected, actual, fmt.Sprintf("Test case #%d, %s", i, tc.Name))
+		assert.Equal(t, tc.ExpectedApplies, actualApplies, fmt.Sprintf("Test case #%d, %s", i, tc.Name))
 	}
 
-	patches = dmp.PatchMake("The quick brown fox jumps over the lazy dog.", "That quick brown fox jumped over a lazy dog.")
-	results0, results1 = dmp.PatchApply(patches, "The quick brown fox jumps over the lazy dog.")
-	boolArray = results1
-	resultStr = results0 + "\t" + strconv.FormatBool(boolArray[0]) + "\t" + strconv.FormatBool(boolArray[1])
-	assert.Equal(t, "That quick brown fox jumped over a lazy dog.\ttrue\ttrue", resultStr, "patch_apply: Exact match.")
-
-	results0, results1 = dmp.PatchApply(patches, "The quick red rabbit jumps over the tired tiger.")
-	boolArray = results1
-	resultStr = results0 + "\t" + strconv.FormatBool(boolArray[0]) + "\t" + strconv.FormatBool(boolArray[1])
-	assert.Equal(t, "That quick red rabbit jumped over a tired tiger.\ttrue\ttrue", resultStr, "patch_apply: Partial match.")
-
-	results0, results1 = dmp.PatchApply(patches, "I am the very model of a modern major general.")
-	boolArray = results1
-	resultStr = results0 + "\t" + strconv.FormatBool(boolArray[0]) + "\t" + strconv.FormatBool(boolArray[1])
-	assert.Equal(t, "I am the very model of a modern major general.\tfalse\tfalse", resultStr, "patch_apply: Failed match.")
-
-	patches = dmp.PatchMake("x1234567890123456789012345678901234567890123456789012345678901234567890y", "xabcy")
-	results0, results1 = dmp.PatchApply(patches, "x123456789012345678901234567890-----++++++++++-----123456789012345678901234567890y")
-	boolArray = results1
-	resultStr = results0 + "\t" + strconv.FormatBool(boolArray[0]) + "\t" + strconv.FormatBool(boolArray[1])
-	assert.Equal(t, "xabcy\ttrue\ttrue", resultStr, "patch_apply: Big delete, small Diff.")
-
-	patches = dmp.PatchMake("x1234567890123456789012345678901234567890123456789012345678901234567890y", "xabcy")
-	results0, results1 = dmp.PatchApply(patches, "x12345678901234567890---------------++++++++++---------------12345678901234567890y")
-	boolArray = results1
-	resultStr = results0 + "\t" + strconv.FormatBool(boolArray[0]) + "\t" + strconv.FormatBool(boolArray[1])
-	assert.Equal(t, "xabc12345678901234567890---------------++++++++++---------------12345678901234567890y\tfalse\ttrue", resultStr, "patch_apply: Big delete, big Diff 1.")
-
 	dmp.PatchDeleteThreshold = 0.6
-	patches = dmp.PatchMake("x1234567890123456789012345678901234567890123456789012345678901234567890y", "xabcy")
-	results0, results1 = dmp.PatchApply(patches, "x12345678901234567890---------------++++++++++---------------12345678901234567890y")
-	boolArray = results1
-	resultStr = results0 + "\t" + strconv.FormatBool(boolArray[0]) + "\t" + strconv.FormatBool(boolArray[1])
-	assert.Equal(t, "xabcy\ttrue\ttrue", resultStr, "patch_apply: Big delete, big Diff 2.")
+
+	for i, tc := range []TestCase{
+		{"Big delete, big Diff 2", "x1234567890123456789012345678901234567890123456789012345678901234567890y", "xabcy", "x12345678901234567890---------------++++++++++---------------12345678901234567890y", "xabcy", []bool{true, true}},
+	} {
+		patches := dmp.PatchMake(tc.Text1, tc.Text2)
+
+		actual, actualApplies := dmp.PatchApply(patches, tc.TextBase)
+		assert.Equal(t, tc.Expected, actual, fmt.Sprintf("Test case #%d, %s", i, tc.Name))
+		assert.Equal(t, tc.ExpectedApplies, actualApplies, fmt.Sprintf("Test case #%d, %s", i, tc.Name))
+	}
+
+	dmp.MatchDistance = 0
+	dmp.MatchThreshold = 0.0
 	dmp.PatchDeleteThreshold = 0.5
 
-	dmp.MatchThreshold = 0.0
-	dmp.MatchDistance = 0
-	patches = dmp.PatchMake("abcdefghijklmnopqrstuvwxyz--------------------1234567890", "abcXXXXXXXXXXdefghijklmnopqrstuvwxyz--------------------1234567YYYYYYYYYY890")
-	results0, results1 = dmp.PatchApply(patches, "ABCDEFGHIJKLMNOPQRSTUVWXYZ--------------------1234567890")
-	boolArray = results1
-	resultStr = results0 + "\t" + strconv.FormatBool(boolArray[0]) + "\t" + strconv.FormatBool(boolArray[1])
-	assert.Equal(t, "ABCDEFGHIJKLMNOPQRSTUVWXYZ--------------------1234567YYYYYYYYYY890\tfalse\ttrue", resultStr, "patch_apply: Compensate for failed patch.")
+	for i, tc := range []TestCase{
+		{"Compensate for failed patch", "abcdefghijklmnopqrstuvwxyz--------------------1234567890", "abcXXXXXXXXXXdefghijklmnopqrstuvwxyz--------------------1234567YYYYYYYYYY890", "ABCDEFGHIJKLMNOPQRSTUVWXYZ--------------------1234567890", "ABCDEFGHIJKLMNOPQRSTUVWXYZ--------------------1234567YYYYYYYYYY890", []bool{false, true}},
+	} {
+		patches := dmp.PatchMake(tc.Text1, tc.Text2)
+
+		actual, actualApplies := dmp.PatchApply(patches, tc.TextBase)
+		assert.Equal(t, tc.Expected, actual, fmt.Sprintf("Test case #%d, %s", i, tc.Name))
+		assert.Equal(t, tc.ExpectedApplies, actualApplies, fmt.Sprintf("Test case #%d, %s", i, tc.Name))
+	}
+
 	dmp.MatchThreshold = 0.5
 	dmp.MatchDistance = 1000
 
-	patches = dmp.PatchMake("", "test")
-	patchStr := dmp.PatchToText(patches)
-	dmp.PatchApply(patches, "")
-	assert.Equal(t, patchStr, dmp.PatchToText(patches), "patch_apply: No side effects.")
+	for i, tc := range []TestCase{
+		{"No side effects", "", "test", "", "test", []bool{true}},
+		{"No side effects with major delete", "The quick brown fox jumps over the lazy dog.", "Woof", "The quick brown fox jumps over the lazy dog.", "Woof", []bool{true, true}},
+		{"Edge exact match", "", "test", "", "test", []bool{true}},
+		{"Near edge exact match", "XY", "XtestY", "XY", "XtestY", []bool{true}},
+		{"Edge partial match", "y", "y123", "x", "x123", []bool{true}},
+	} {
+		patches := dmp.PatchMake(tc.Text1, tc.Text2)
 
-	patches = dmp.PatchMake("The quick brown fox jumps over the lazy dog.", "Woof")
-	patchStr = dmp.PatchToText(patches)
-	dmp.PatchApply(patches, "The quick brown fox jumps over the lazy dog.")
-	assert.Equal(t, patchStr, dmp.PatchToText(patches), "patch_apply: No side effects with major delete.")
-
-	patches = dmp.PatchMake("", "test")
-	results0, results1 = dmp.PatchApply(patches, "")
-	boolArray = results1
-	resultStr = results0 + "\t" + strconv.FormatBool(boolArray[0])
-	assert.Equal(t, "test\ttrue", resultStr, "patch_apply: Edge exact match.")
-
-	patches = dmp.PatchMake("XY", "XtestY")
-	results0, results1 = dmp.PatchApply(patches, "XY")
-	boolArray = results1
-	resultStr = results0 + "\t" + strconv.FormatBool(boolArray[0])
-	assert.Equal(t, "XtestY\ttrue", resultStr, "patch_apply: Near edge exact match.")
-
-	patches = dmp.PatchMake("y", "y123")
-	results0, results1 = dmp.PatchApply(patches, "x")
-	boolArray = results1
-	resultStr = results0 + "\t" + strconv.FormatBool(boolArray[0])
-	assert.Equal(t, "x123\ttrue", resultStr, "patch_apply: Edge partial match.")
+		actual, actualApplies := dmp.PatchApply(patches, tc.TextBase)
+		assert.Equal(t, tc.Expected, actual, fmt.Sprintf("Test case #%d, %s", i, tc.Name))
+		assert.Equal(t, tc.ExpectedApplies, actualApplies, fmt.Sprintf("Test case #%d, %s", i, tc.Name))
+	}
 }
 
 func TestIndexOf(t *testing.T) {
@@ -1445,9 +1842,11 @@
 		String   string
 		Pattern  string
 		Position int
+
 		Expected int
 	}
-	cases := []TestCase{
+
+	for i, tc := range []TestCase{
 		{"hi world", "world", -1, 3},
 		{"hi world", "world", 0, 3},
 		{"hi world", "world", 1, 3},
@@ -1467,10 +1866,9 @@
 		{"a\u03b2\u03b2c", "\u03b2", 3, 3},
 		{"a\u03b2\u03b2c", "\u03b2", 5, -1},
 		{"a\u03b2\u03b2c", "\u03b2", 6, -1},
-	}
-	for i, c := range cases {
-		actual := indexOf(c.String, c.Pattern, c.Position)
-		assert.Equal(t, c.Expected, actual, fmt.Sprintf("TestIndex case %d", i))
+	} {
+		actual := indexOf(tc.String, tc.Pattern, tc.Position)
+		assert.Equal(t, tc.Expected, actual, fmt.Sprintf("Test case #%d, %#v", i, tc))
 	}
 }
 
@@ -1479,9 +1877,11 @@
 		String   string
 		Pattern  string
 		Position int
+
 		Expected int
 	}
-	cases := []TestCase{
+
+	for i, tc := range []TestCase{
 		{"hi world", "world", -1, -1},
 		{"hi world", "world", 0, -1},
 		{"hi world", "world", 1, -1},
@@ -1505,12 +1905,9 @@
 		{"a\u03b2\u03b2c", "\u03b2", 3, 3},
 		{"a\u03b2\u03b2c", "\u03b2", 5, 3},
 		{"a\u03b2\u03b2c", "\u03b2", 6, 3},
-	}
-
-	for i, c := range cases {
-		actual := lastIndexOf(c.String, c.Pattern, c.Position)
-		assert.Equal(t, c.Expected, actual,
-			fmt.Sprintf("TestLastIndex case %d", i))
+	} {
+		actual := lastIndexOf(tc.String, tc.Pattern, tc.Position)
+		assert.Equal(t, tc.Expected, actual, fmt.Sprintf("Test case #%d, %#v", i, tc))
 	}
 }
 
@@ -1557,7 +1954,7 @@
 }
 
 func BenchmarkDiffMainLarge(b *testing.B) {
-	s1, s2 := speedtestTexts(b)
+	s1, s2 := speedtestTexts()
 
 	dmp := New()
 
@@ -1569,7 +1966,7 @@
 }
 
 func BenchmarkDiffMainRunesLargeLines(b *testing.B) {
-	s1, s2 := speedtestTexts(b)
+	s1, s2 := speedtestTexts()
 
 	dmp := New()
 
@@ -1584,7 +1981,7 @@
 }
 
 func BenchmarkDiffHalfMatch(b *testing.B) {
-	s1, s2 := speedtestTexts(b)
+	s1, s2 := speedtestTexts()
 
 	dmp := New()
 
@@ -1596,7 +1993,7 @@
 }
 
 func BenchmarkDiffCleanupSemantic(b *testing.B) {
-	s1, s2 := speedtestTexts(b)
+	s1, s2 := speedtestTexts()
 
 	dmp := New()