123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687 | package diff
import (
"strings"
"testing"
)
// A hunk that only adds lines, once placed by its header after an earlier
// hunk removed lines, sliced at a negative index and crashed blinker.
func TestApplyAdditionBeforeEarlierHunk(t *testing.T) {
text := "1\n2\n3\n4\n5\n6\n7\n8\n"
for _, patch := range []string{
"@@ -1,6 +1,1 @@\n 1\n-2\n-3\n-4\n-5\n-6\n@@ -3,0 +4,1 @@\n+X\n",
"@@ -9223372036854775807,0 +1 @@\n+X\n",
} {
if _, err := Apply(text, patch); err == nil {
t.Errorf("Apply(%q) succeeded", patch)
}
}
}
// The final newline is part of the text: changing it shows in the diff,
// and applying that diff changes it.
func TestFinalNewline(t *testing.T) {
for _, c := range [][2]string{
{"a\n", "a"},
{"a", "a\n"},
{"a\nb", "a\nc"},
{"x\na", "y\na"},
{"", "a"},
{"a", ""},
} {
u := Unified("f", c[0], c[1], 3)
if u == "" {
t.Errorf("%q → %q: no diff", c[0], c[1])
continue
}
if got, err := Apply(c[0], u); err != nil || got != c[1] {
t.Errorf("%q → %q: Apply = %q, %v\n%s", c[0], c[1], got, err, u)
}
}
if u := Unified("f", "a\n", "a", 3); !strings.Contains(u, "-a\n+a\n"+noNewline+"\n") {
t.Errorf("diff:\n%s", u)
}
}
// Applying the diff between two texts gives the second, unless a hunk's
// context occurs more than once, which Apply refuses rather than guess.
func FuzzApplyUnified(f *testing.F) {
f.Add("a\nb\nc\n", "a\nB\nc\n", 3)
f.Add("a\nb", "a\nb\n", 1)
f.Add("x\nx\nx\n", "x\ny\nx\n", 1)
f.Add("", "new\n", 0)
f.Fuzz(func(t *testing.T, a, b string, context int) {
context = 1 + (context%5+5)%5
u := Unified("f", a, b, context)
if a == b {
if u != "" {
t.Fatalf("diff of equal texts:\n%s", u)
}
return
}
if u == "" {
t.Fatal("no diff of different texts")
}
got, err := Apply(a, u)
if err != nil {
if strings.Contains(err.Error(), "matches the file in") {
return
}
t.Fatalf("Apply: %v\n%s", err, u)
}
if got != b {
t.Fatalf("Apply = %q, want %q\n%s", got, b, u)
}
})
}
// No patch, however malformed, panics.
func FuzzApply(f *testing.F) {
f.Add("1\n2\n3\n", "@@ -1,2 +1,1 @@\n 1\n-2\n@@ -1,0 +1 @@\n+x\n")
f.Add("a", "\\ No newline at end of file\n-a\n+b\n")
f.Add("", "@@ -0,0 +1 @@\n+x")
f.Fuzz(func(t *testing.T, text, patch string) {
Apply(text, patch)
})
}
|