1 | // Copyright 2019 The Go Authors. All rights reserved. |
---|---|
2 | // Use of this source code is governed by a BSD-style |
3 | // license that can be found in the LICENSE file. |
4 | |
5 | package diff_test |
6 | |
7 | import ( |
8 | "math/rand" |
9 | "reflect" |
10 | "testing" |
11 | "unicode/utf8" |
12 | |
13 | "golang.org/x/tools/internal/diff" |
14 | "golang.org/x/tools/internal/diff/difftest" |
15 | ) |
16 | |
17 | func TestApply(t *testing.T) { |
18 | for _, tc := range difftest.TestCases { |
19 | t.Run(tc.Name, func(t *testing.T) { |
20 | got, err := diff.Apply(tc.In, tc.Edits) |
21 | if err != nil { |
22 | t.Fatalf("Apply(Edits) failed: %v", err) |
23 | } |
24 | if got != tc.Out { |
25 | t.Errorf("Apply(Edits): got %q, want %q", got, tc.Out) |
26 | } |
27 | if tc.LineEdits != nil { |
28 | got, err := diff.Apply(tc.In, tc.LineEdits) |
29 | if err != nil { |
30 | t.Fatalf("Apply(LineEdits) failed: %v", err) |
31 | } |
32 | if got != tc.Out { |
33 | t.Errorf("Apply(LineEdits): got %q, want %q", got, tc.Out) |
34 | } |
35 | } |
36 | }) |
37 | } |
38 | } |
39 | |
40 | func TestNEdits(t *testing.T) { |
41 | for _, tc := range difftest.TestCases { |
42 | edits := diff.Strings(tc.In, tc.Out) |
43 | got, err := diff.Apply(tc.In, edits) |
44 | if err != nil { |
45 | t.Fatalf("Apply failed: %v", err) |
46 | } |
47 | if got != tc.Out { |
48 | t.Fatalf("%s: got %q wanted %q", tc.Name, got, tc.Out) |
49 | } |
50 | if len(edits) < len(tc.Edits) { // should find subline edits |
51 | t.Errorf("got %v, expected %v for %#v", edits, tc.Edits, tc) |
52 | } |
53 | } |
54 | } |
55 | |
56 | func TestNRandom(t *testing.T) { |
57 | rand.Seed(1) |
58 | for i := 0; i < 1000; i++ { |
59 | a := randstr("abω", 16) |
60 | b := randstr("abωc", 16) |
61 | edits := diff.Strings(a, b) |
62 | got, err := diff.Apply(a, edits) |
63 | if err != nil { |
64 | t.Fatalf("Apply failed: %v", err) |
65 | } |
66 | if got != b { |
67 | t.Fatalf("%d: got %q, wanted %q, starting with %q", i, got, b, a) |
68 | } |
69 | } |
70 | } |
71 | |
72 | // $ go test -fuzz=FuzzRoundTrip ./internal/diff |
73 | func FuzzRoundTrip(f *testing.F) { |
74 | f.Fuzz(func(t *testing.T, a, b string) { |
75 | if !utf8.ValidString(a) || !utf8.ValidString(b) { |
76 | return // inputs must be text |
77 | } |
78 | edits := diff.Strings(a, b) |
79 | got, err := diff.Apply(a, edits) |
80 | if err != nil { |
81 | t.Fatalf("Apply failed: %v", err) |
82 | } |
83 | if got != b { |
84 | t.Fatalf("applying diff(%q, %q) gives %q; edits=%v", a, b, got, edits) |
85 | } |
86 | }) |
87 | } |
88 | |
89 | func TestLineEdits(t *testing.T) { |
90 | for _, tc := range difftest.TestCases { |
91 | t.Run(tc.Name, func(t *testing.T) { |
92 | // if line edits not specified, it is the same as edits |
93 | edits := tc.LineEdits |
94 | if edits == nil { |
95 | edits = tc.Edits |
96 | } |
97 | got, err := diff.LineEdits(tc.In, tc.Edits) |
98 | if err != nil { |
99 | t.Fatalf("LineEdits: %v", err) |
100 | } |
101 | if !reflect.DeepEqual(got, edits) { |
102 | t.Errorf("LineEdits got %q, want %q", got, edits) |
103 | } |
104 | }) |
105 | } |
106 | } |
107 | |
108 | func TestToUnified(t *testing.T) { |
109 | for _, tc := range difftest.TestCases { |
110 | t.Run(tc.Name, func(t *testing.T) { |
111 | unified, err := diff.ToUnified(difftest.FileA, difftest.FileB, tc.In, tc.Edits) |
112 | if err != nil { |
113 | t.Fatal(err) |
114 | } |
115 | if unified != tc.Unified { |
116 | t.Errorf("Unified(Edits): got diff:\n%v\nexpected:\n%v", unified, tc.Unified) |
117 | } |
118 | if tc.LineEdits != nil { |
119 | unified, err := diff.ToUnified(difftest.FileA, difftest.FileB, tc.In, tc.LineEdits) |
120 | if err != nil { |
121 | t.Fatal(err) |
122 | } |
123 | if unified != tc.Unified { |
124 | t.Errorf("Unified(LineEdits): got diff:\n%v\nexpected:\n%v", unified, tc.Unified) |
125 | } |
126 | } |
127 | }) |
128 | } |
129 | } |
130 | |
131 | func TestRegressionOld001(t *testing.T) { |
132 | 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/gopls/internal/lsp/diff\"\n\t\"golang.org/x/tools/internal/diff/difftest\"\n\t\"golang.org/x/tools/gopls/internal/span\"\n)\n" |
133 | |
134 | 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/gopls/internal/lsp/diff\"\n\t\"golang.org/x/tools/internal/diff/difftest\"\n\t\"golang.org/x/tools/gopls/internal/span\"\n)\n" |
135 | diffs := diff.Strings(a, b) |
136 | got, err := diff.Apply(a, diffs) |
137 | if err != nil { |
138 | t.Fatalf("Apply failed: %v", err) |
139 | } |
140 | if got != b { |
141 | i := 0 |
142 | for ; i < len(a) && i < len(b) && got[i] == b[i]; i++ { |
143 | } |
144 | t.Errorf("oops %vd\n%q\n%q", diffs, got, b) |
145 | t.Errorf("\n%q\n%q", got[i:], b[i:]) |
146 | } |
147 | } |
148 | |
149 | func TestRegressionOld002(t *testing.T) { |
150 | a := "n\"\n)\n" |
151 | b := "n\"\n\t\"golang.org/x//nnal/stack\"\n)\n" |
152 | diffs := diff.Strings(a, b) |
153 | got, err := diff.Apply(a, diffs) |
154 | if err != nil { |
155 | t.Fatalf("Apply failed: %v", err) |
156 | } |
157 | if got != b { |
158 | i := 0 |
159 | for ; i < len(a) && i < len(b) && got[i] == b[i]; i++ { |
160 | } |
161 | t.Errorf("oops %vd\n%q\n%q", diffs, got, b) |
162 | t.Errorf("\n%q\n%q", got[i:], b[i:]) |
163 | } |
164 | } |
165 | |
166 | // return a random string of length n made of characters from s |
167 | func randstr(s string, n int) string { |
168 | src := []rune(s) |
169 | x := make([]rune, n) |
170 | for i := 0; i < n; i++ { |
171 | x[i] = src[rand.Intn(len(src))] |
172 | } |
173 | return string(x) |
174 | } |
175 |
Members