.gitignore added
[dotfiles/.git] / .config / coc / extensions / coc-go-data / tools / pkg / mod / golang.org / x / tools / gopls@v0.6.9 / internal / regtest / misc / definition_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 misc
6
7 import (
8         "path"
9         "strings"
10         "testing"
11
12         . "golang.org/x/tools/gopls/internal/regtest"
13
14         "golang.org/x/tools/internal/lsp/fake"
15         "golang.org/x/tools/internal/lsp/tests"
16 )
17
18 const internalDefinition = `
19 -- go.mod --
20 module mod.com
21
22 go 1.12
23 -- main.go --
24 package main
25
26 import "fmt"
27
28 func main() {
29         fmt.Println(message)
30 }
31 -- const.go --
32 package main
33
34 const message = "Hello World."
35 `
36
37 func TestGoToInternalDefinition(t *testing.T) {
38         Run(t, internalDefinition, func(t *testing.T, env *Env) {
39                 env.OpenFile("main.go")
40                 name, pos := env.GoToDefinition("main.go", env.RegexpSearch("main.go", "message"))
41                 if want := "const.go"; name != want {
42                         t.Errorf("GoToDefinition: got file %q, want %q", name, want)
43                 }
44                 if want := env.RegexpSearch("const.go", "message"); pos != want {
45                         t.Errorf("GoToDefinition: got position %v, want %v", pos, want)
46                 }
47         })
48 }
49
50 const stdlibDefinition = `
51 -- go.mod --
52 module mod.com
53
54 go 1.12
55 -- main.go --
56 package main
57
58 import "fmt"
59
60 func main() {
61         fmt.Printf()
62 }`
63
64 func TestGoToStdlibDefinition_Issue37045(t *testing.T) {
65         Run(t, stdlibDefinition, func(t *testing.T, env *Env) {
66                 env.OpenFile("main.go")
67                 name, pos := env.GoToDefinition("main.go", env.RegexpSearch("main.go", `fmt.(Printf)`))
68                 if got, want := path.Base(name), "print.go"; got != want {
69                         t.Errorf("GoToDefinition: got file %q, want %q", name, want)
70                 }
71
72                 // Test that we can jump to definition from outside our workspace.
73                 // See golang.org/issues/37045.
74                 newName, newPos := env.GoToDefinition(name, pos)
75                 if newName != name {
76                         t.Errorf("GoToDefinition is not idempotent: got %q, want %q", newName, name)
77                 }
78                 if newPos != pos {
79                         t.Errorf("GoToDefinition is not idempotent: got %v, want %v", newPos, pos)
80                 }
81         })
82 }
83
84 func TestUnexportedStdlib_Issue40809(t *testing.T) {
85         Run(t, stdlibDefinition, func(t *testing.T, env *Env) {
86                 env.OpenFile("main.go")
87                 name, _ := env.GoToDefinition("main.go", env.RegexpSearch("main.go", `fmt.(Printf)`))
88                 env.OpenFile(name)
89
90                 pos := env.RegexpSearch(name, `:=\s*(newPrinter)\(\)`)
91
92                 // Check that we can find references on a reference
93                 refs := env.References(name, pos)
94                 if len(refs) < 5 {
95                         t.Errorf("expected 5+ references to newPrinter, found: %#v", refs)
96                 }
97
98                 name, pos = env.GoToDefinition(name, pos)
99                 content, _ := env.Hover(name, pos)
100                 if !strings.Contains(content.Value, "newPrinter") {
101                         t.Fatal("definition of newPrinter went to the incorrect place")
102                 }
103                 // And on the definition too.
104                 refs = env.References(name, pos)
105                 if len(refs) < 5 {
106                         t.Errorf("expected 5+ references to newPrinter, found: %#v", refs)
107                 }
108         })
109 }
110
111 // Test the hover on an error's Error function.
112 // This can't be done via the marker tests because Error is a builtin.
113 func TestHoverOnError(t *testing.T) {
114         const mod = `
115 -- go.mod --
116 module mod.com
117
118 go 1.12
119 -- main.go --
120 package main
121
122 func main() {
123         var err error
124         err.Error()
125 }`
126         Run(t, mod, func(t *testing.T, env *Env) {
127                 env.OpenFile("main.go")
128                 content, _ := env.Hover("main.go", env.RegexpSearch("main.go", "Error"))
129                 if content == nil {
130                         t.Fatalf("nil hover content for Error")
131                 }
132                 want := "```go\nfunc (error).Error() string\n```"
133                 if content.Value != want {
134                         t.Fatalf("hover failed:\n%s", tests.Diff(t, want, content.Value))
135                 }
136         })
137 }
138
139 func TestImportShortcut(t *testing.T) {
140         const mod = `
141 -- go.mod --
142 module mod.com
143
144 go 1.12
145 -- main.go --
146 package main
147
148 import "fmt"
149
150 func main() {}
151 `
152         for _, tt := range []struct {
153                 wantLinks      int
154                 wantDef        bool
155                 importShortcut string
156         }{
157                 {1, false, "Link"},
158                 {0, true, "Definition"},
159                 {1, true, "Both"},
160         } {
161                 t.Run(tt.importShortcut, func(t *testing.T) {
162                         WithOptions(
163                                 EditorConfig{
164                                         ImportShortcut: tt.importShortcut,
165                                 },
166                         ).Run(t, mod, func(t *testing.T, env *Env) {
167                                 env.OpenFile("main.go")
168                                 file, pos := env.GoToDefinition("main.go", env.RegexpSearch("main.go", `"fmt"`))
169                                 if !tt.wantDef && (file != "" || pos != (fake.Pos{})) {
170                                         t.Fatalf("expected no definition, got one: %s:%v", file, pos)
171                                 } else if tt.wantDef && file == "" && pos == (fake.Pos{}) {
172                                         t.Fatalf("expected definition, got none")
173                                 }
174                                 links := env.DocumentLink("main.go")
175                                 if len(links) != tt.wantLinks {
176                                         t.Fatalf("expected %v links, got %v", tt.wantLinks, len(links))
177                                 }
178                         })
179                 })
180         }
181 }