Giant blob of minor changes
[dotfiles/.git] / .config / coc / extensions / coc-go-data / tools / pkg / mod / golang.org / x / tools / gopls@v0.5.2 / internal / regtest / codelens_test.go
1 // Copyright 2020 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 regtest
6
7 import (
8         "runtime"
9         "strings"
10         "testing"
11
12         "golang.org/x/tools/internal/lsp/protocol"
13         "golang.org/x/tools/internal/lsp/source"
14         "golang.org/x/tools/internal/lsp/tests"
15         "golang.org/x/tools/internal/testenv"
16 )
17
18 func TestDisablingCodeLens(t *testing.T) {
19         const workspace = `
20 -- go.mod --
21 module codelens.test
22 -- lib.go --
23 package lib
24
25 type Number int
26
27 const (
28         Zero Number = iota
29         One
30         Two
31 )
32
33 //go:generate stringer -type=Number
34 `
35         tests := []struct {
36                 label        string
37                 enabled      map[string]bool
38                 wantCodeLens bool
39         }{
40                 {
41                         label:        "default",
42                         wantCodeLens: true,
43                 },
44                 {
45                         label:        "generate disabled",
46                         enabled:      map[string]bool{source.CommandGenerate.Name: false},
47                         wantCodeLens: false,
48                 },
49         }
50         for _, test := range tests {
51                 t.Run(test.label, func(t *testing.T) {
52                         withOptions(
53                                 EditorConfig{
54                                         CodeLens: test.enabled,
55                                 },
56                         ).run(t, workspace, func(t *testing.T, env *Env) {
57                                 env.OpenFile("lib.go")
58                                 lens := env.CodeLens("lib.go")
59                                 if gotCodeLens := len(lens) > 0; gotCodeLens != test.wantCodeLens {
60                                         t.Errorf("got codeLens: %t, want %t", gotCodeLens, test.wantCodeLens)
61                                 }
62                         })
63                 })
64         }
65 }
66
67 // This test confirms the full functionality of the code lenses for updating
68 // dependencies in a go.mod file. It checks for the code lens that suggests
69 // an update and then executes the command associated with that code lens. A
70 // regression test for golang/go#39446.
71 func TestUpdateCodelens(t *testing.T) {
72         const proxyWithLatest = `
73 -- golang.org/x/hello@v1.3.3/go.mod --
74 module golang.org/x/hello
75
76 go 1.12
77 -- golang.org/x/hello@v1.3.3/hi/hi.go --
78 package hi
79
80 var Goodbye error
81         -- golang.org/x/hello@v1.2.3/go.mod --
82 module golang.org/x/hello
83
84 go 1.12
85 -- golang.org/x/hello@v1.2.3/hi/hi.go --
86 package hi
87
88 var Goodbye error
89 `
90
91         const shouldUpdateDep = `
92 -- go.mod --
93 module mod.com
94
95 go 1.12
96
97 require golang.org/x/hello v1.2.3
98 -- go.sum --
99 golang.org/x/hello v1.2.3 h1:jOtNXLsiCuLzU6KM3wRHidpc29IxcKpofHZiOW1hYKA=
100 golang.org/x/hello v1.2.3/go.mod h1:X79D30QqR94cGK8aIhQNhCZLq4mIr5Gimj5qekF08rY=
101 -- main.go --
102 package main
103
104 import "golang.org/x/hello/hi"
105
106 func main() {
107         _ = hi.Goodbye
108 }
109 `
110         runner.Run(t, shouldUpdateDep, func(t *testing.T, env *Env) {
111                 env.OpenFile("go.mod")
112                 lenses := env.CodeLens("go.mod")
113                 want := "Upgrade dependency to v1.3.3"
114                 var found protocol.CodeLens
115                 for _, lens := range lenses {
116                         if lens.Command.Title == want {
117                                 found = lens
118                                 break
119                         }
120                 }
121                 if found.Command.Command == "" {
122                         t.Fatalf("did not find lens %q, got %v", want, lenses)
123                 }
124                 if _, err := env.Editor.ExecuteCommand(env.Ctx, &protocol.ExecuteCommandParams{
125                         Command:   found.Command.Command,
126                         Arguments: found.Command.Arguments,
127                 }); err != nil {
128                         t.Fatal(err)
129                 }
130                 env.Await(NoOutstandingWork())
131                 got := env.ReadWorkspaceFile("go.mod")
132                 const wantGoMod = `module mod.com
133
134 go 1.12
135
136 require golang.org/x/hello v1.3.3
137 `
138                 if got != wantGoMod {
139                         t.Fatalf("go.mod upgrade failed:\n%s", tests.Diff(wantGoMod, got))
140                 }
141         }, WithProxyFiles(proxyWithLatest))
142 }
143
144 func TestUnusedDependenciesCodelens(t *testing.T) {
145         testenv.NeedsGo1Point(t, 14)
146         const proxy = `
147 -- golang.org/x/hello@v1.0.0/go.mod --
148 module golang.org/x/hello
149
150 go 1.14
151 -- golang.org/x/hello@v1.0.0/hi/hi.go --
152 package hi
153
154 var Goodbye error
155 -- golang.org/x/unused@v1.0.0/go.mod --
156 module golang.org/x/unused
157
158 go 1.14
159 -- golang.org/x/unused@v1.0.0/nouse/nouse.go --
160 package nouse
161
162 var NotUsed error
163 `
164
165         const shouldRemoveDep = `
166 -- go.mod --
167 module mod.com
168
169 go 1.14
170
171 require golang.org/x/hello v1.0.0
172 require golang.org/x/unused v1.0.0
173 -- main.go --
174 package main
175
176 import "golang.org/x/hello/hi"
177
178 func main() {
179         _ = hi.Goodbye
180 }
181 `
182         runner.Run(t, shouldRemoveDep, func(t *testing.T, env *Env) {
183                 env.OpenFile("go.mod")
184                 env.ExecuteCodeLensCommand("go.mod", source.CommandTidy)
185                 env.Await(NoOutstandingWork())
186                 got := env.ReadWorkspaceFile("go.mod")
187                 const wantGoMod = `module mod.com
188
189 go 1.14
190
191 require golang.org/x/hello v1.0.0
192 `
193                 if got != wantGoMod {
194                         t.Fatalf("go.mod tidy failed:\n%s", tests.Diff(wantGoMod, got))
195                 }
196         }, WithProxyFiles(proxy))
197 }
198
199 func TestRegenerateCgo(t *testing.T) {
200         testenv.NeedsTool(t, "cgo")
201         testenv.NeedsGo1Point(t, 15)
202
203         const workspace = `
204 -- go.mod --
205 module example.com
206 -- cgo.go --
207 package x
208
209 /*
210 int fortythree() { return 42; }
211 */
212 import "C"
213
214 func Foo() {
215         print(C.fortytwo())
216 }
217 `
218         runner.Run(t, workspace, func(t *testing.T, env *Env) {
219                 // Open the file. We should have a nonexistant symbol.
220                 env.OpenFile("cgo.go")
221                 env.Await(env.DiagnosticAtRegexp("cgo.go", `C\.(fortytwo)`)) // could not determine kind of name for C.fortytwo
222
223                 // Fix the C function name. We haven't regenerated cgo, so nothing should be fixed.
224                 env.RegexpReplace("cgo.go", `int fortythree`, "int fortytwo")
225                 env.SaveBuffer("cgo.go")
226                 env.Await(env.DiagnosticAtRegexp("cgo.go", `C\.(fortytwo)`))
227
228                 // Regenerate cgo, fixing the diagnostic.
229                 env.ExecuteCodeLensCommand("cgo.go", source.CommandRegenerateCgo)
230                 env.Await(EmptyDiagnostics("cgo.go"))
231         })
232 }
233
234 func TestGCDetails(t *testing.T) {
235         testenv.NeedsGo1Point(t, 15)
236         if runtime.GOOS == "android" {
237                 t.Skipf("the gc details code lens doesn't work on Android")
238         }
239
240         const mod = `
241 -- go.mod --
242 module mod.com
243
244 go 1.15
245 -- main.go --
246 package main
247
248 import "fmt"
249
250 func main() {
251         var x string
252         fmt.Println(x)
253 }
254 `
255         withOptions(
256                 EditorConfig{
257                         CodeLens: map[string]bool{
258                                 "gc_details": true,
259                         }},
260         ).run(t, mod, func(t *testing.T, env *Env) {
261                 env.OpenFile("main.go")
262                 env.ExecuteCodeLensCommand("main.go", source.CommandToggleDetails)
263                 d := &protocol.PublishDiagnosticsParams{}
264                 env.Await(
265                         OnceMet(
266                                 DiagnosticAt("main.go", 6, 12),
267                                 ReadDiagnostics("main.go", d),
268                         ),
269                 )
270                 // Confirm that the diagnostics come from the gc details code lens.
271                 var found bool
272                 for _, d := range d.Diagnostics {
273                         if d.Severity != protocol.SeverityInformation {
274                                 t.Fatalf("unexpected diagnostic severity %v, wanted Information", d.Severity)
275                         }
276                         if strings.Contains(d.Message, "x escapes") {
277                                 found = true
278                         }
279                 }
280                 if !found {
281                         t.Fatalf(`expected to find diagnostic with message "escape(x escapes to heap)", found none`)
282                 }
283                 // Toggle the GC details code lens again so now it should be off.
284                 env.ExecuteCodeLensCommand("main.go", source.CommandToggleDetails)
285                 env.Await(
286                         EmptyDiagnostics("main.go"),
287                 )
288         })
289 }