2019-09-17 09:10:48 -06:00
|
|
|
package lsp
|
|
|
|
|
|
|
|
import (
|
|
|
|
"strings"
|
|
|
|
"testing"
|
|
|
|
|
|
|
|
"golang.org/x/tools/internal/lsp/protocol"
|
|
|
|
"golang.org/x/tools/internal/lsp/source"
|
|
|
|
"golang.org/x/tools/internal/lsp/tests"
|
|
|
|
"golang.org/x/tools/internal/span"
|
|
|
|
)
|
|
|
|
|
2019-09-26 11:56:23 -06:00
|
|
|
func (r *runner) Completion(t *testing.T, src span.Span, test tests.Completion, items tests.CompletionItems) {
|
2019-12-29 00:22:12 -07:00
|
|
|
got := r.callCompletion(t, src, func(opts *source.Options) {
|
|
|
|
opts.DeepCompletion = false
|
|
|
|
opts.Matcher = source.CaseInsensitive
|
2020-01-15 15:39:57 -07:00
|
|
|
opts.UnimportedCompletion = false
|
2020-03-01 15:33:21 -07:00
|
|
|
opts.InsertTextFormat = protocol.SnippetTextFormat
|
|
|
|
if !strings.Contains(string(src.URI()), "literal") {
|
|
|
|
opts.LiteralCompletions = false
|
2020-01-24 11:34:08 -07:00
|
|
|
}
|
2019-09-26 11:56:23 -06:00
|
|
|
})
|
2020-02-02 22:17:44 -07:00
|
|
|
got = tests.FilterBuiltins(src, got)
|
2019-09-26 11:56:23 -06:00
|
|
|
want := expected(t, test, items)
|
|
|
|
if diff := tests.DiffCompletionItems(want, got); diff != "" {
|
2020-04-21 20:41:25 -06:00
|
|
|
t.Errorf("%s", diff)
|
2019-09-17 09:10:48 -06:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-09-26 11:56:23 -06:00
|
|
|
func (r *runner) CompletionSnippet(t *testing.T, src span.Span, expected tests.CompletionSnippet, placeholders bool, items tests.CompletionItems) {
|
2019-12-29 00:22:12 -07:00
|
|
|
list := r.callCompletion(t, src, func(opts *source.Options) {
|
|
|
|
opts.Placeholders = placeholders
|
|
|
|
opts.DeepCompletion = true
|
|
|
|
opts.Matcher = source.Fuzzy
|
2020-01-15 15:39:57 -07:00
|
|
|
opts.UnimportedCompletion = false
|
2019-09-26 11:56:23 -06:00
|
|
|
})
|
|
|
|
got := tests.FindItem(list, *items[expected.CompletionItem])
|
|
|
|
want := expected.PlainSnippet
|
|
|
|
if placeholders {
|
|
|
|
want = expected.PlaceholderSnippet
|
|
|
|
}
|
|
|
|
if diff := tests.DiffSnippets(want, got); diff != "" {
|
2020-04-21 20:41:25 -06:00
|
|
|
t.Errorf("%s", diff)
|
2019-09-17 09:10:48 -06:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-09-26 11:56:23 -06:00
|
|
|
func (r *runner) UnimportedCompletion(t *testing.T, src span.Span, test tests.Completion, items tests.CompletionItems) {
|
2020-01-15 15:39:57 -07:00
|
|
|
got := r.callCompletion(t, src, func(opts *source.Options) {})
|
2020-02-02 22:17:44 -07:00
|
|
|
got = tests.FilterBuiltins(src, got)
|
2019-09-26 11:56:23 -06:00
|
|
|
want := expected(t, test, items)
|
2019-11-15 17:14:15 -07:00
|
|
|
if diff := tests.CheckCompletionOrder(want, got, false); diff != "" {
|
2020-04-21 20:41:25 -06:00
|
|
|
t.Errorf("%s", diff)
|
2019-09-17 09:10:48 -06:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-09-26 11:56:23 -06:00
|
|
|
func (r *runner) DeepCompletion(t *testing.T, src span.Span, test tests.Completion, items tests.CompletionItems) {
|
2019-12-29 00:22:12 -07:00
|
|
|
got := r.callCompletion(t, src, func(opts *source.Options) {
|
|
|
|
opts.DeepCompletion = true
|
|
|
|
opts.Matcher = source.CaseInsensitive
|
2020-01-15 15:39:57 -07:00
|
|
|
opts.UnimportedCompletion = false
|
2019-09-26 11:56:23 -06:00
|
|
|
})
|
2020-02-02 22:17:44 -07:00
|
|
|
got = tests.FilterBuiltins(src, got)
|
2019-09-26 11:56:23 -06:00
|
|
|
want := expected(t, test, items)
|
|
|
|
if msg := tests.DiffCompletionItems(want, got); msg != "" {
|
2020-04-21 20:41:25 -06:00
|
|
|
t.Errorf("%s", msg)
|
2019-09-17 09:10:48 -06:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-09-26 11:56:23 -06:00
|
|
|
func (r *runner) FuzzyCompletion(t *testing.T, src span.Span, test tests.Completion, items tests.CompletionItems) {
|
2019-12-29 00:22:12 -07:00
|
|
|
got := r.callCompletion(t, src, func(opts *source.Options) {
|
|
|
|
opts.DeepCompletion = true
|
|
|
|
opts.Matcher = source.Fuzzy
|
2020-01-15 15:39:57 -07:00
|
|
|
opts.UnimportedCompletion = false
|
2019-09-26 11:56:23 -06:00
|
|
|
})
|
2020-02-02 22:17:44 -07:00
|
|
|
got = tests.FilterBuiltins(src, got)
|
2019-09-26 11:56:23 -06:00
|
|
|
want := expected(t, test, items)
|
|
|
|
if msg := tests.DiffCompletionItems(want, got); msg != "" {
|
2020-04-21 20:41:25 -06:00
|
|
|
t.Errorf("%s", msg)
|
2019-09-17 09:10:48 -06:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-09-26 11:56:23 -06:00
|
|
|
func (r *runner) CaseSensitiveCompletion(t *testing.T, src span.Span, test tests.Completion, items tests.CompletionItems) {
|
2019-12-29 00:22:12 -07:00
|
|
|
got := r.callCompletion(t, src, func(opts *source.Options) {
|
|
|
|
opts.Matcher = source.CaseSensitive
|
2020-01-15 15:39:57 -07:00
|
|
|
opts.UnimportedCompletion = false
|
2019-09-26 11:56:23 -06:00
|
|
|
})
|
2020-02-02 22:17:44 -07:00
|
|
|
got = tests.FilterBuiltins(src, got)
|
2019-09-26 11:56:23 -06:00
|
|
|
want := expected(t, test, items)
|
|
|
|
if msg := tests.DiffCompletionItems(want, got); msg != "" {
|
2020-04-21 20:41:25 -06:00
|
|
|
t.Errorf("%s", msg)
|
2019-09-26 05:59:06 -06:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-09-26 11:56:23 -06:00
|
|
|
func (r *runner) RankCompletion(t *testing.T, src span.Span, test tests.Completion, items tests.CompletionItems) {
|
2019-12-29 00:22:12 -07:00
|
|
|
got := r.callCompletion(t, src, func(opts *source.Options) {
|
|
|
|
opts.DeepCompletion = true
|
|
|
|
opts.Matcher = source.Fuzzy
|
2020-01-15 15:39:57 -07:00
|
|
|
opts.UnimportedCompletion = false
|
2019-09-26 11:56:23 -06:00
|
|
|
})
|
|
|
|
want := expected(t, test, items)
|
2019-11-15 17:14:15 -07:00
|
|
|
if msg := tests.CheckCompletionOrder(want, got, true); msg != "" {
|
2020-04-21 20:41:25 -06:00
|
|
|
t.Errorf("%s", msg)
|
2019-09-17 09:10:48 -06:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func expected(t *testing.T, test tests.Completion, items tests.CompletionItems) []protocol.CompletionItem {
|
|
|
|
t.Helper()
|
|
|
|
|
|
|
|
var want []protocol.CompletionItem
|
|
|
|
for _, pos := range test.CompletionItems {
|
|
|
|
item := items[pos]
|
|
|
|
want = append(want, tests.ToProtocolCompletionItem(*item))
|
|
|
|
}
|
|
|
|
return want
|
|
|
|
}
|
2019-10-24 22:57:53 -06:00
|
|
|
|
2019-12-29 00:22:12 -07:00
|
|
|
func (r *runner) callCompletion(t *testing.T, src span.Span, options func(*source.Options)) []protocol.CompletionItem {
|
2019-09-17 09:10:48 -06:00
|
|
|
t.Helper()
|
|
|
|
|
2019-11-15 10:43:45 -07:00
|
|
|
view, err := r.server.session.ViewOf(src.URI())
|
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
2019-09-17 09:10:48 -06:00
|
|
|
original := view.Options()
|
|
|
|
modified := original
|
2019-12-29 00:22:12 -07:00
|
|
|
options(&modified)
|
2019-11-15 10:43:45 -07:00
|
|
|
view, err = view.SetOptions(r.ctx, modified)
|
2019-11-08 11:25:29 -07:00
|
|
|
if err != nil {
|
|
|
|
t.Error(err)
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
defer view.SetOptions(r.ctx, original)
|
2019-09-17 09:10:48 -06:00
|
|
|
|
|
|
|
list, err := r.server.Completion(r.ctx, &protocol.CompletionParams{
|
|
|
|
TextDocumentPositionParams: protocol.TextDocumentPositionParams{
|
|
|
|
TextDocument: protocol.TextDocumentIdentifier{
|
2020-02-12 14:36:46 -07:00
|
|
|
URI: protocol.URIFromSpanURI(src.URI()),
|
2019-09-17 09:10:48 -06:00
|
|
|
},
|
|
|
|
Position: protocol.Position{
|
|
|
|
Line: float64(src.Start().Line() - 1),
|
|
|
|
Character: float64(src.Start().Column() - 1),
|
|
|
|
},
|
|
|
|
},
|
|
|
|
})
|
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
return list.Items
|
|
|
|
}
|