mirror of https://github.com/golang/go.git
206 lines
5.7 KiB
Go
206 lines
5.7 KiB
Go
// Copyright 2019 The Go Authors. All rights reserved.
|
|
// Use of this source code is governed by a BSD-style
|
|
// license that can be found in the LICENSE file.
|
|
|
|
package diff_test
|
|
|
|
import (
|
|
"fmt"
|
|
"math/rand"
|
|
"strings"
|
|
"testing"
|
|
|
|
"golang.org/x/tools/internal/lsp/diff"
|
|
"golang.org/x/tools/internal/lsp/diff/difftest"
|
|
"golang.org/x/tools/internal/span"
|
|
)
|
|
|
|
func TestApplyEdits(t *testing.T) {
|
|
for _, tc := range difftest.TestCases {
|
|
t.Run(tc.Name, func(t *testing.T) {
|
|
t.Helper()
|
|
if got := diff.ApplyEdits(tc.In, tc.Edits); got != tc.Out {
|
|
t.Errorf("ApplyEdits edits got %q, want %q", got, tc.Out)
|
|
}
|
|
if tc.LineEdits != nil {
|
|
if got := diff.ApplyEdits(tc.In, tc.LineEdits); got != tc.Out {
|
|
t.Errorf("ApplyEdits lineEdits got %q, want %q", got, tc.Out)
|
|
}
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestNEdits(t *testing.T) {
|
|
for i, tc := range difftest.TestCases {
|
|
sp := fmt.Sprintf("file://%s.%d", tc.Name, i)
|
|
edits, err := diff.NComputeEdits(span.URI(sp), tc.In, tc.Out)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
got := diff.ApplyEdits(tc.In, edits)
|
|
if got != tc.Out {
|
|
t.Fatalf("%s: got %q wanted %q", tc.Name, got, tc.Out)
|
|
}
|
|
if len(edits) < len(tc.Edits) { // should find subline edits
|
|
t.Errorf("got %v, expected %v for %#v", edits, tc.Edits, tc)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestNRandom(t *testing.T) {
|
|
rand.Seed(1)
|
|
for i := 0; i < 1000; i++ {
|
|
fname := fmt.Sprintf("file://%x", i)
|
|
a := randstr("abω", 16)
|
|
b := randstr("abωc", 16)
|
|
edits, err := diff.NComputeEdits(span.URI(fname), a, b)
|
|
if err != nil {
|
|
t.Fatalf("%q,%q %v", a, b, err)
|
|
}
|
|
got := diff.ApplyEdits(a, edits)
|
|
if got != b {
|
|
t.Fatalf("%d: got %q, wanted %q, starting with %q", i, got, b, a)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestNLinesRandom(t *testing.T) {
|
|
rand.Seed(2)
|
|
for i := 0; i < 1000; i++ {
|
|
fname := fmt.Sprintf("file://%x", i)
|
|
x := randlines("abω", 4) // avg line length is 6, want a change every 3rd line or so
|
|
v := []rune(x)
|
|
for i := 0; i < len(v); i++ {
|
|
if rand.Float64() < .05 {
|
|
v[i] = 'N'
|
|
}
|
|
}
|
|
y := string(v)
|
|
// occasionally remove the trailing \n
|
|
if rand.Float64() < .1 {
|
|
x = x[:len(x)-1]
|
|
}
|
|
if rand.Float64() < .1 {
|
|
y = y[:len(y)-1]
|
|
}
|
|
a, b := strings.SplitAfter(x, "\n"), strings.SplitAfter(y, "\n")
|
|
edits, err := diff.NComputeLineEdits(span.URI(fname), a, b)
|
|
if err != nil {
|
|
t.Fatalf("%q,%q %v", a, b, err)
|
|
}
|
|
got := diff.ApplyEdits(x, edits)
|
|
if got != y {
|
|
t.Fatalf("%d: got\n%q, wanted\n%q, starting with %q", i, got, y, a)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestLineEdits(t *testing.T) {
|
|
for _, tc := range difftest.TestCases {
|
|
t.Run(tc.Name, func(t *testing.T) {
|
|
t.Helper()
|
|
// if line edits not specified, it is the same as edits
|
|
edits := tc.LineEdits
|
|
if edits == nil {
|
|
edits = tc.Edits
|
|
}
|
|
if got := diff.LineEdits(tc.In, tc.Edits); diffEdits(got, edits) {
|
|
t.Errorf("LineEdits got %q, want %q", got, edits)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestUnified(t *testing.T) {
|
|
for _, tc := range difftest.TestCases {
|
|
t.Run(tc.Name, func(t *testing.T) {
|
|
t.Helper()
|
|
unified := fmt.Sprint(diff.ToUnified(difftest.FileA, difftest.FileB, tc.In, tc.Edits))
|
|
if unified != tc.Unified {
|
|
t.Errorf("edits got diff:\n%v\nexpected:\n%v", unified, tc.Unified)
|
|
}
|
|
if tc.LineEdits != nil {
|
|
unified := fmt.Sprint(diff.ToUnified(difftest.FileA, difftest.FileB, tc.In, tc.LineEdits))
|
|
if unified != tc.Unified {
|
|
t.Errorf("lineEdits got diff:\n%v\nexpected:\n%v", unified, tc.Unified)
|
|
}
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestRegressionOld001(t *testing.T) {
|
|
a := "// Copyright 2019 The Go Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license that can be found in the LICENSE file.\n\npackage diff_test\n\nimport (\n\t\"fmt\"\n\t\"math/rand\"\n\t\"strings\"\n\t\"testing\"\n\n\t\"golang.org/x/tools/internal/lsp/diff\"\n\t\"golang.org/x/tools/internal/lsp/diff/difftest\"\n\t\"golang.org/x/tools/internal/span\"\n)\n"
|
|
|
|
b := "// Copyright 2019 The Go Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license that can be found in the LICENSE file.\n\npackage diff_test\n\nimport (\n\t\"fmt\"\n\t\"math/rand\"\n\t\"strings\"\n\t\"testing\"\n\n\t\"github.com/google/safehtml/template\"\n\t\"golang.org/x/tools/internal/lsp/diff\"\n\t\"golang.org/x/tools/internal/lsp/diff/difftest\"\n\t\"golang.org/x/tools/internal/span\"\n)\n"
|
|
diffs, err := diff.NComputeEdits(span.URI("file://one"), a, b)
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
got := diff.ApplyEdits(a, diffs)
|
|
if got != b {
|
|
i := 0
|
|
for ; i < len(a) && i < len(b) && got[i] == b[i]; i++ {
|
|
}
|
|
t.Errorf("oops %vd\n%q\n%q", diffs, got, b)
|
|
t.Errorf("\n%q\n%q", got[i:], b[i:])
|
|
}
|
|
}
|
|
|
|
func TestRegressionOld002(t *testing.T) {
|
|
a := "n\"\n)\n"
|
|
b := "n\"\n\t\"golang.org/x//nnal/stack\"\n)\n"
|
|
diffs, err := diff.NComputeEdits(span.URI("file://two"), a, b)
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
got := diff.ApplyEdits(a, diffs)
|
|
if got != b {
|
|
i := 0
|
|
for ; i < len(a) && i < len(b) && got[i] == b[i]; i++ {
|
|
}
|
|
t.Errorf("oops %vd\n%q\n%q", diffs, got, b)
|
|
t.Errorf("\n%q\n%q", got[i:], b[i:])
|
|
}
|
|
}
|
|
|
|
func diffEdits(got, want []diff.TextEdit) bool {
|
|
if len(got) != len(want) {
|
|
return true
|
|
}
|
|
for i, w := range want {
|
|
g := got[i]
|
|
if span.Compare(w.Span, g.Span) != 0 {
|
|
return true
|
|
}
|
|
if w.NewText != g.NewText {
|
|
return true
|
|
}
|
|
}
|
|
return false
|
|
}
|
|
|
|
// return a random string of length n made of characters from s
|
|
func randstr(s string, n int) string {
|
|
src := []rune(s)
|
|
x := make([]rune, n)
|
|
for i := 0; i < n; i++ {
|
|
x[i] = src[rand.Intn(len(src))]
|
|
}
|
|
return string(x)
|
|
}
|
|
|
|
// return some random lines, all ending with \n
|
|
func randlines(s string, n int) string {
|
|
src := []rune(s)
|
|
var b strings.Builder
|
|
for i := 0; i < n; i++ {
|
|
for j := 0; j < 4+rand.Intn(4); j++ {
|
|
b.WriteRune(src[rand.Intn(len(src))])
|
|
}
|
|
b.WriteByte('\n')
|
|
}
|
|
return b.String()
|
|
}
|