github.com/jhump/golang-x-tools@v0.0.0-20220218190644-4958d6d39439/internal/lsp/completion_test.go (about) 1 // Copyright 2019 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 lsp 6 7 import ( 8 "strings" 9 "testing" 10 11 "github.com/jhump/golang-x-tools/internal/lsp/protocol" 12 "github.com/jhump/golang-x-tools/internal/lsp/source" 13 "github.com/jhump/golang-x-tools/internal/lsp/tests" 14 "github.com/jhump/golang-x-tools/internal/span" 15 ) 16 17 func (r *runner) Completion(t *testing.T, src span.Span, test tests.Completion, items tests.CompletionItems) { 18 got := r.callCompletion(t, src, func(opts *source.Options) { 19 opts.DeepCompletion = false 20 opts.Matcher = source.CaseInsensitive 21 opts.CompleteUnimported = false 22 opts.InsertTextFormat = protocol.SnippetTextFormat 23 opts.LiteralCompletions = strings.Contains(string(src.URI()), "literal") 24 opts.ExperimentalPostfixCompletions = strings.Contains(string(src.URI()), "postfix") 25 }) 26 got = tests.FilterBuiltins(src, got) 27 want := expected(t, test, items) 28 if diff := tests.DiffCompletionItems(want, got); diff != "" { 29 t.Errorf("%s", diff) 30 } 31 } 32 33 func (r *runner) CompletionSnippet(t *testing.T, src span.Span, expected tests.CompletionSnippet, placeholders bool, items tests.CompletionItems) { 34 list := r.callCompletion(t, src, func(opts *source.Options) { 35 opts.UsePlaceholders = placeholders 36 opts.DeepCompletion = true 37 opts.Matcher = source.Fuzzy 38 opts.CompleteUnimported = false 39 }) 40 got := tests.FindItem(list, *items[expected.CompletionItem]) 41 want := expected.PlainSnippet 42 if placeholders { 43 want = expected.PlaceholderSnippet 44 } 45 if diff := tests.DiffSnippets(want, got); diff != "" { 46 t.Errorf("%s", diff) 47 } 48 } 49 50 func (r *runner) UnimportedCompletion(t *testing.T, src span.Span, test tests.Completion, items tests.CompletionItems) { 51 got := r.callCompletion(t, src, func(opts *source.Options) {}) 52 got = tests.FilterBuiltins(src, got) 53 want := expected(t, test, items) 54 if diff := tests.CheckCompletionOrder(want, got, false); diff != "" { 55 t.Errorf("%s", diff) 56 } 57 } 58 59 func (r *runner) DeepCompletion(t *testing.T, src span.Span, test tests.Completion, items tests.CompletionItems) { 60 got := r.callCompletion(t, src, func(opts *source.Options) { 61 opts.DeepCompletion = true 62 opts.Matcher = source.CaseInsensitive 63 opts.CompleteUnimported = false 64 }) 65 got = tests.FilterBuiltins(src, got) 66 want := expected(t, test, items) 67 if msg := tests.DiffCompletionItems(want, got); msg != "" { 68 t.Errorf("%s", msg) 69 } 70 } 71 72 func (r *runner) FuzzyCompletion(t *testing.T, src span.Span, test tests.Completion, items tests.CompletionItems) { 73 got := r.callCompletion(t, src, func(opts *source.Options) { 74 opts.DeepCompletion = true 75 opts.Matcher = source.Fuzzy 76 opts.CompleteUnimported = false 77 }) 78 got = tests.FilterBuiltins(src, got) 79 want := expected(t, test, items) 80 if msg := tests.DiffCompletionItems(want, got); msg != "" { 81 t.Errorf("%s", msg) 82 } 83 } 84 85 func (r *runner) CaseSensitiveCompletion(t *testing.T, src span.Span, test tests.Completion, items tests.CompletionItems) { 86 got := r.callCompletion(t, src, func(opts *source.Options) { 87 opts.Matcher = source.CaseSensitive 88 opts.CompleteUnimported = false 89 }) 90 got = tests.FilterBuiltins(src, got) 91 want := expected(t, test, items) 92 if msg := tests.DiffCompletionItems(want, got); msg != "" { 93 t.Errorf("%s", msg) 94 } 95 } 96 97 func (r *runner) RankCompletion(t *testing.T, src span.Span, test tests.Completion, items tests.CompletionItems) { 98 got := r.callCompletion(t, src, func(opts *source.Options) { 99 opts.DeepCompletion = true 100 opts.Matcher = source.Fuzzy 101 opts.CompleteUnimported = false 102 opts.LiteralCompletions = true 103 opts.ExperimentalPostfixCompletions = true 104 }) 105 want := expected(t, test, items) 106 if msg := tests.CheckCompletionOrder(want, got, true); msg != "" { 107 t.Errorf("%s", msg) 108 } 109 } 110 111 func expected(t *testing.T, test tests.Completion, items tests.CompletionItems) []protocol.CompletionItem { 112 t.Helper() 113 114 var want []protocol.CompletionItem 115 for _, pos := range test.CompletionItems { 116 item := items[pos] 117 want = append(want, tests.ToProtocolCompletionItem(*item)) 118 } 119 return want 120 } 121 122 func (r *runner) callCompletion(t *testing.T, src span.Span, options func(*source.Options)) []protocol.CompletionItem { 123 t.Helper() 124 125 view, err := r.server.session.ViewOf(src.URI()) 126 if err != nil { 127 t.Fatal(err) 128 } 129 original := view.Options() 130 modified := view.Options().Clone() 131 options(modified) 132 view, err = view.SetOptions(r.ctx, modified) 133 if err != nil { 134 t.Error(err) 135 return nil 136 } 137 defer view.SetOptions(r.ctx, original) 138 139 list, err := r.server.Completion(r.ctx, &protocol.CompletionParams{ 140 TextDocumentPositionParams: protocol.TextDocumentPositionParams{ 141 TextDocument: protocol.TextDocumentIdentifier{ 142 URI: protocol.URIFromSpanURI(src.URI()), 143 }, 144 Position: protocol.Position{ 145 Line: uint32(src.Start().Line() - 1), 146 Character: uint32(src.Start().Column() - 1), 147 }, 148 }, 149 }) 150 if err != nil { 151 t.Fatal(err) 152 } 153 return list.Items 154 }