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 / completion_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         "fmt"
9         "strings"
10         "testing"
11
12         "golang.org/x/tools/internal/lsp"
13         "golang.org/x/tools/internal/lsp/fake"
14         "golang.org/x/tools/internal/lsp/protocol"
15         "golang.org/x/tools/internal/testenv"
16 )
17
18 func TestPackageCompletion(t *testing.T) {
19         testenv.NeedsGo1Point(t, 14)
20         const files = `
21 -- go.mod --
22 module mod.com
23
24 -- fruits/apple.go --
25 package apple
26
27 fun apple() int {
28         return 0
29 }
30
31 -- fruits/testfile.go --
32 // this is a comment
33
34 /*
35  this is a multiline comment
36 */
37
38 import "fmt"
39
40 func test() {}
41
42 -- fruits/testfile2.go --
43 package
44
45 -- fruits/testfile3.go --
46 pac
47 `
48         var (
49                 testfile4 = ""
50                 testfile5 = "/*a comment*/ "
51                 testfile6 = "/*a comment*/\n"
52         )
53         for _, tc := range []struct {
54                 name          string
55                 filename      string
56                 content       *string
57                 triggerRegexp string
58                 want          []string
59                 editRegexp    string
60         }{
61                 {
62                         name:          "package completion at valid position",
63                         filename:      "fruits/testfile.go",
64                         triggerRegexp: "\n()",
65                         want:          []string{"package apple", "package apple_test", "package fruits", "package fruits_test", "package main"},
66                         editRegexp:    "\n()",
67                 },
68                 {
69                         name:          "package completion in a comment",
70                         filename:      "fruits/testfile.go",
71                         triggerRegexp: "th(i)s",
72                         want:          nil,
73                 },
74                 {
75                         name:          "package completion in a multiline comment",
76                         filename:      "fruits/testfile.go",
77                         triggerRegexp: `\/\*\n()`,
78                         want:          nil,
79                 },
80                 {
81                         name:          "package completion at invalid position",
82                         filename:      "fruits/testfile.go",
83                         triggerRegexp: "import \"fmt\"\n()",
84                         want:          nil,
85                 },
86                 {
87                         name:          "package completion after keyword 'package'",
88                         filename:      "fruits/testfile2.go",
89                         triggerRegexp: "package()",
90                         want:          []string{"package apple", "package apple_test", "package fruits", "package fruits_test", "package main"},
91                         editRegexp:    "package\n",
92                 },
93                 {
94                         name:          "package completion with 'pac' prefix",
95                         filename:      "fruits/testfile3.go",
96                         triggerRegexp: "pac()",
97                         want:          []string{"package apple", "package apple_test", "package fruits", "package fruits_test", "package main"},
98                         editRegexp:    "pac",
99                 },
100                 {
101                         name:          "package completion for empty file",
102                         filename:      "fruits/testfile4.go",
103                         triggerRegexp: "^$",
104                         content:       &testfile4,
105                         want:          []string{"package apple", "package apple_test", "package fruits", "package fruits_test", "package main"},
106                         editRegexp:    "^$",
107                 },
108                 {
109                         name:          "package completion without terminal newline",
110                         filename:      "fruits/testfile5.go",
111                         triggerRegexp: `\*\/ ()`,
112                         content:       &testfile5,
113                         want:          []string{"package apple", "package apple_test", "package fruits", "package fruits_test", "package main"},
114                         editRegexp:    `\*\/ ()`,
115                 },
116                 {
117                         name:          "package completion on terminal newline",
118                         filename:      "fruits/testfile6.go",
119                         triggerRegexp: `\*\/\n()`,
120                         content:       &testfile6,
121                         want:          []string{"package apple", "package apple_test", "package fruits", "package fruits_test", "package main"},
122                         editRegexp:    `\*\/\n()`,
123                 },
124         } {
125                 t.Run(tc.name, func(t *testing.T) {
126                         run(t, files, func(t *testing.T, env *Env) {
127                                 if tc.content != nil {
128                                         env.WriteWorkspaceFile(tc.filename, *tc.content)
129                                         env.Await(
130                                                 CompletedWork(lsp.DiagnosticWorkTitle(lsp.FromDidChangeWatchedFiles), 1),
131                                         )
132                                 }
133                                 env.OpenFile(tc.filename)
134                                 completions := env.Completion(tc.filename, env.RegexpSearch(tc.filename, tc.triggerRegexp))
135
136                                 // Check that the completion item suggestions are in the range
137                                 // of the file.
138                                 lineCount := len(strings.Split(env.Editor.BufferText(tc.filename), "\n"))
139                                 for _, item := range completions.Items {
140                                         if start := int(item.TextEdit.Range.Start.Line); start >= lineCount {
141                                                 t.Fatalf("unexpected text edit range start line number: got %d, want less than %d", start, lineCount)
142                                         }
143                                         if end := int(item.TextEdit.Range.End.Line); end >= lineCount {
144                                                 t.Fatalf("unexpected text edit range end line number: got %d, want less than %d", end, lineCount)
145                                         }
146                                 }
147
148                                 if tc.want != nil {
149                                         start, end := env.RegexpRange(tc.filename, tc.editRegexp)
150                                         expectedRng := protocol.Range{
151                                                 Start: fake.Pos.ToProtocolPosition(start),
152                                                 End:   fake.Pos.ToProtocolPosition(end),
153                                         }
154                                         for _, item := range completions.Items {
155                                                 gotRng := item.TextEdit.Range
156                                                 if expectedRng != gotRng {
157                                                         t.Errorf("unexpected completion range for completion item %s: got %v, want %v",
158                                                                 item.Label, gotRng, expectedRng)
159                                                 }
160                                         }
161                                 }
162
163                                 diff := compareCompletionResults(tc.want, completions.Items)
164                                 if diff != "" {
165                                         t.Error(diff)
166                                 }
167                         })
168                 })
169         }
170 }
171
172 func TestPackageNameCompletion(t *testing.T) {
173         const files = `
174 -- go.mod --
175 module mod.com
176
177 -- math/add.go --
178 package ma
179 `
180
181         want := []string{"ma", "ma_test", "main", "math", "math_test"}
182         run(t, files, func(t *testing.T, env *Env) {
183                 env.OpenFile("math/add.go")
184                 completions := env.Completion("math/add.go", fake.Pos{
185                         Line:   0,
186                         Column: 10,
187                 })
188
189                 diff := compareCompletionResults(want, completions.Items)
190                 if diff != "" {
191                         t.Fatal(diff)
192                 }
193         })
194 }
195
196 func compareCompletionResults(want []string, gotItems []protocol.CompletionItem) string {
197         if len(gotItems) != len(want) {
198                 return fmt.Sprintf("got %v completion(s), want %v", len(gotItems), len(want))
199         }
200
201         var got []string
202         for _, item := range gotItems {
203                 got = append(got, item.Label)
204         }
205
206         for i, v := range got {
207                 if v != want[i] {
208                         return fmt.Sprintf("completion results are not the same: got %v, want %v", got, want)
209                 }
210         }
211
212         return ""
213 }