Skip to content

Commit 5ec020e

Browse files
committed
gopls/internal/lsp: add testSignatureHelpOverload
1 parent e02ab1e commit 5ec020e

File tree

2 files changed

+113
-0
lines changed

2 files changed

+113
-0
lines changed
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
func _() {
2+
Demo(100) //@signature_overload("100", "Demo__1(n int) int", 1, 0)
3+
Demo(100, 200) //@signature_overload("100", "Demo__2(n1 int, n2 int)", 2, 0)
4+
Demo(100, 200) //@signature_overload("200", "Demo__2(n1 int, n2 int)", 2, 1)
5+
}
6+
7+
func _() {
8+
Demo 100 //@signature_overload("100", "Demo__1(n int) int", 1, 0)
9+
Demo 100, 200 //@signature_overload("100", "Demo__2(n1 int, n2 int)", 2, 0)
10+
Demo 100, 200 //@signature_overload("200", "Demo__2(n1 int, n2 int)", 2, 1)
11+
}

gopls/internal/lsp/goxls_test.go

Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,17 @@
11
package lsp
22

33
import (
4+
"fmt"
45
"path/filepath"
6+
"strings"
57
"testing"
68

79
"golang.org/x/tools/gopls/internal/lsp/cache"
810
"golang.org/x/tools/gopls/internal/lsp/debug"
11+
"golang.org/x/tools/gopls/internal/lsp/protocol"
912
"golang.org/x/tools/gopls/internal/lsp/source"
1013
"golang.org/x/tools/gopls/internal/lsp/tests"
14+
"golang.org/x/tools/gopls/internal/lsp/tests/compare"
1115
"golang.org/x/tools/gopls/internal/span"
1216
"golang.org/x/tools/internal/testenv"
1317
)
@@ -98,4 +102,102 @@ func testXLS(t *testing.T, datum *tests.Data) {
98102
}
99103
r.server = NewServer(session, testClient{runner: r})
100104
tests.Run(t, r, datum)
105+
// test signature_overload
106+
testSignatureHelpOverload(t, r, datum)
107+
}
108+
109+
func testSignatureHelpOverload(t *testing.T, r *runner, datum *tests.Data) {
110+
// Collect names for the entries that require golden files.
111+
signatures := make(map[span.Span]*protocol.SignatureHelp)
112+
collectSignatures := func(spn span.Span, signature string, activeSignature int64, activeParam int64) {
113+
signatures[spn] = &protocol.SignatureHelp{
114+
Signatures: []protocol.SignatureInformation{
115+
{
116+
Label: signature,
117+
},
118+
},
119+
ActiveSignature: uint32(activeSignature),
120+
ActiveParameter: uint32(activeParam),
121+
}
122+
// Hardcode special case to test the lack of a signature.
123+
if signature == "" && activeParam == 0 {
124+
signatures[spn] = nil
125+
}
126+
}
127+
128+
if err := datum.Exported.Expect(map[string]interface{}{
129+
"signature_overload": collectSignatures,
130+
}); err != nil {
131+
t.Fatal(err)
132+
}
133+
134+
t.Run("SignatureHelpOverload", func(t *testing.T) {
135+
t.Helper()
136+
for spn, expectedSignature := range signatures {
137+
t.Run(tests.SpanName(spn), func(t *testing.T) {
138+
t.Helper()
139+
r.SignatureHelpOverload(t, spn, expectedSignature)
140+
})
141+
}
142+
})
143+
}
144+
145+
func (r *runner) SignatureHelpOverload(t *testing.T, spn span.Span, want *protocol.SignatureHelp) {
146+
m, err := r.data.Mapper(spn.URI())
147+
if err != nil {
148+
t.Fatal(err)
149+
}
150+
loc, err := m.SpanLocation(spn)
151+
if err != nil {
152+
t.Fatalf("failed for %v: %v", loc, err)
153+
}
154+
params := &protocol.SignatureHelpParams{
155+
TextDocumentPositionParams: protocol.LocationTextDocumentPositionParams(loc),
156+
}
157+
got, err := r.server.SignatureHelp(r.ctx, params)
158+
if err != nil {
159+
// Only fail if we got an error we did not expect.
160+
if want != nil {
161+
t.Fatal(err)
162+
}
163+
return
164+
}
165+
if want == nil {
166+
if got != nil {
167+
t.Errorf("expected no signature, got %v", got)
168+
}
169+
return
170+
}
171+
if got == nil {
172+
t.Fatalf("expected %v, got nil", want)
173+
}
174+
if diff := DiffSignaturesOverload(spn, want, got); diff != "" {
175+
t.Error(diff)
176+
}
177+
}
178+
179+
func DiffSignaturesOverload(spn span.Span, want, got *protocol.SignatureHelp) string {
180+
decorate := func(f string, args ...interface{}) string {
181+
return fmt.Sprintf("invalid signature at %s: %s", spn, fmt.Sprintf(f, args...))
182+
}
183+
if want.ActiveSignature != got.ActiveSignature {
184+
return decorate("wanted active signature of %d, got %d", want.ActiveSignature, int(got.ActiveSignature))
185+
}
186+
if want.ActiveParameter != got.ActiveParameter {
187+
return decorate("wanted active parameter of %d, got %d", want.ActiveParameter, int(got.ActiveParameter))
188+
}
189+
g := got.Signatures[got.ActiveSignature]
190+
w := want.Signatures[0]
191+
if diff := compare.Text(tests.NormalizeAny(w.Label), tests.NormalizeAny(g.Label)); diff != "" {
192+
return decorate("mismatched labels:\n%s", diff)
193+
}
194+
var paramParts []string
195+
for _, p := range g.Parameters {
196+
paramParts = append(paramParts, p.Label)
197+
}
198+
paramsStr := strings.Join(paramParts, ", ")
199+
if !strings.Contains(g.Label, paramsStr) {
200+
return decorate("expected signature %q to contain params %q", g.Label, paramsStr)
201+
}
202+
return ""
101203
}

0 commit comments

Comments
 (0)