github.com/tiagovtristao/plz@v13.4.0+incompatible/tools/build_langserver/langserver/completion_test.go (about) 1 package langserver 2 3 import ( 4 "context" 5 "strings" 6 "testing" 7 8 "github.com/thought-machine/please/tools/build_langserver/lsp" 9 10 "github.com/stretchr/testify/assert" 11 ) 12 13 /*************************************** 14 *Tests for Attributes 15 ***************************************/ 16 func TestCompletionWithCONFIG(t *testing.T) { 17 ctx := context.Background() 18 19 // Test completion on CONFIG with no starting character 20 items, err := handler.getCompletionItemsList(ctx, completionPropURI, lsp.Position{Line: 4, Character: 7}) 21 assert.Equal(t, nil, err) 22 assert.Equal(t, len(analyzer.State.Config.TagsToFields()), len(items)) 23 for _, i := range items { 24 assert.Equal(t, i.Kind, lsp.Property) 25 } 26 27 // Test completion on CONFIG with 1 starting character 28 items, err = handler.getCompletionItemsList(ctx, completionPropURI, lsp.Position{Line: 5, Character: 8}) 29 assert.Equal(t, nil, err) 30 assert.True(t, len(analyzer.State.Config.TagsToFields()) > len(items)) 31 assert.True(t, itemInList(items, "JARCAT_TOOL")) 32 assert.False(t, itemInList(items, "PLZ_VERSION")) 33 34 // Test completion on CONFIG with a word 35 items, err = handler.getCompletionItemsList(ctx, completionPropURI, lsp.Position{Line: 6, Character: 11}) 36 assert.Equal(t, nil, err) 37 assert.True(t, len(analyzer.State.Config.TagsToFields()) > len(items)) 38 assert.True(t, itemInList(items, "JAVAC_TOOL")) 39 for _, i := range items { 40 assert.True(t, strings.Contains(i.Label, "JAVA")) 41 } 42 43 // Test completion with assignment 44 items, err = handler.getCompletionItemsList(ctx, completionPropURI, lsp.Position{Line: 7, Character: 18}) 45 assert.Equal(t, nil, err) 46 assert.True(t, len(analyzer.State.Config.TagsToFields()) > len(items)) 47 assert.True(t, itemInList(items, "JAVAC_TOOL")) 48 for _, i := range items { 49 assert.True(t, strings.Contains(i.Label, "JAVA")) 50 } 51 52 // Test completion on empty line 53 items, err = handler.getCompletionItemsList(ctx, completionPropURI, lsp.Position{Line: 9, Character: 13}) 54 assert.Equal(t, nil, err) 55 assert.Equal(t, 0, len(items)) 56 57 // Test config should be empty 58 items, err = handler.getCompletionItemsList(ctx, completionPropURI, lsp.Position{Line: 8, Character: 14}) 59 assert.Equal(t, nil, err) 60 assert.Equal(t, 0, len(items)) 61 } 62 63 func TestCompletionWithStringMethods(t *testing.T) { 64 ctx := context.Background() 65 context.Background() 66 67 // Tests completion on no letters follows after dot(.) 68 items, err := handler.getCompletionItemsList(ctx, completionPropURI, lsp.Position{Line: 10, Character: 19}) 69 assert.Equal(t, nil, err) 70 assert.Equal(t, len(analyzer.Attributes["str"]), len(items)) 71 assert.True(t, itemInList(items, "replace")) 72 assert.True(t, itemInList(items, "format")) 73 74 // Test completion with 1 starting character: f 75 items, err = handler.getCompletionItemsList(ctx, completionPropURI, lsp.Position{Line: 11, Character: 20}) 76 assert.Equal(t, nil, err) 77 assert.True(t, itemInList(items, "format")) 78 assert.True(t, itemInList(items, "find")) 79 assert.True(t, itemInList(items, "rfind")) 80 81 // Test completion with a three letters: for 82 items, err = handler.getCompletionItemsList(ctx, completionPropURI, lsp.Position{Line: 12, Character: 22}) 83 assert.Equal(t, nil, err) 84 assert.Equal(t, 1, len(items)) 85 assert.Equal(t, "format", items[0].Label) 86 87 // Test completion with assignment 88 items, err = handler.getCompletionItemsList(ctx, completionPropURI, lsp.Position{Line: 13, Character: 19}) 89 assert.Equal(t, nil, err) 90 assert.Equal(t, 1, len(items)) 91 assert.Equal(t, "format", items[0].Label) 92 93 // Test str method completion with variables 94 items, err = handler.getCompletionItemsList(ctx, completionPropURI, lsp.Position{Line: 14, Character: 16}) 95 assert.Equal(t, nil, err) 96 assert.Equal(t, len(analyzer.Attributes["str"]), len(items)) 97 assert.True(t, itemInList(items, "replace")) 98 assert.True(t, itemInList(items, "format")) 99 } 100 101 func TestCompletionWithDictMethods(t *testing.T) { 102 ctx := context.Background() 103 104 // Tests completion on no letters follows after dot(.) 105 items, err := handler.getCompletionItemsList(ctx, completionPropURI, lsp.Position{Line: 17, Character: 25}) 106 assert.Equal(t, nil, err) 107 assert.Equal(t, len(analyzer.Attributes["dict"]), len(items)) 108 assert.True(t, itemInList(items, "get")) 109 assert.True(t, itemInList(items, "keys")) 110 assert.True(t, itemInList(items, "items")) 111 112 // Test completion with 1 starting character: k 113 items, err = handler.getCompletionItemsList(ctx, completionPropURI, lsp.Position{Line: 18, Character: 16}) 114 assert.Equal(t, nil, err) 115 assert.Equal(t, 1, len(items)) 116 assert.Equal(t, "keys", items[0].Label) 117 118 // Test completion with a three letters: get 119 items, err = handler.getCompletionItemsList(ctx, completionPropURI, lsp.Position{Line: 19, Character: 18}) 120 assert.Equal(t, nil, err) 121 assert.Equal(t, 1, len(items)) 122 assert.Equal(t, "get", items[0].Label) 123 124 // Test dict method completion with variables 125 items, err = handler.getCompletionItemsList(ctx, completionPropURI, lsp.Position{Line: 20, Character: 17}) 126 assert.Equal(t, nil, err) 127 assert.Equal(t, len(analyzer.Attributes["dict"]), len(items)) 128 assert.True(t, itemInList(items, "get")) 129 assert.True(t, itemInList(items, "keys")) 130 assert.True(t, itemInList(items, "items")) 131 } 132 133 /*************************************** 134 *Tests for Build label completions 135 ***************************************/ 136 func TestCompletionWithBuildLabels(t *testing.T) { 137 ctx := context.Background() 138 139 items, err := handler.getCompletionItemsList(ctx, completionLabelURI, lsp.Position{Line: 0, Character: 6}) 140 assert.Equal(t, nil, err) 141 assert.True(t, itemInList(items, "src/cache")) 142 for _, i := range items { 143 assert.True(t, strings.HasPrefix(i.Label, "src")) 144 } 145 146 items, err = handler.getCompletionItemsList(ctx, completionLabelURI, lsp.Position{Line: 1, Character: 13}) 147 assert.Equal(t, nil, err) 148 assert.Equal(t, 1, len(items)) 149 assert.Equal(t, "query", items[0].Label) 150 151 items, err = handler.getCompletionItemsList(ctx, completionLabelURI, lsp.Position{Line: 2, Character: 14}) 152 assert.Equal(t, nil, err) 153 assert.Equal(t, 1, len(items)) 154 assert.Equal(t, "query", items[0].Label) 155 t.Log(items[0].Label) 156 157 // Ensure handling of partially completed labels 158 items, err = handler.getCompletionItemsList(ctx, completionLabelURI, lsp.Position{Line: 4, Character: 8}) 159 assert.Equal(t, nil, err) 160 assert.Equal(t, 2, len(items)) 161 assert.True(t, itemInList(items, "query")) 162 assert.True(t, itemInList(items, "query:query")) 163 assert.Equal(t, items[1].Detail, " BUILD Label: //src/query") 164 } 165 166 func TestCompletionWithBuildLabels2(t *testing.T) { 167 ctx := context.Background() 168 169 analyzer.State.Config.Parse.BuildFileName = []string{"completion2.build", "BUILD"} 170 // Ensure relative label working correctly 171 items, err := handler.getCompletionItemsList(ctx, completion2URI, lsp.Position{Line: 15, Character: 11}) 172 assert.Equal(t, nil, err) 173 assert.Equal(t, 4, len(items)) 174 175 assert.True(t, itemInList(items, "my_binary")) 176 assert.True(t, itemInList(items, "langserver_test")) 177 } 178 179 /*************************************** 180 *Tests for Builtin rules 181 ***************************************/ 182 func TestCompletionWithBuiltins(t *testing.T) { 183 ctx := context.Background() 184 185 items, err := handler.getCompletionItemsList(ctx, completionLiteralURI, lsp.Position{Line: 2, Character: 3}) 186 assert.Equal(t, nil, err) 187 assert.True(t, itemInList(items, "go_library")) 188 assert.True(t, itemInList(items, "go_binary")) 189 assert.True(t, itemInList(items, "go_test")) 190 assert.True(t, itemInList(items, "go_get")) 191 for _, item := range items { 192 if item.Label == "go_library" { 193 expectedDetail := "(name:str, srcs:list, asm_srcs:list=None, hdrs:list=None, out:str=None, deps:list=[],\n" + 194 " visibility:list=None, test_only:bool&testonly=False, complete:bool=True, cover:bool=True,\n" + 195 " filter_srcs:bool=True)" 196 assert.Equal(t, expectedDetail, item.Detail) 197 } 198 } 199 200 items, err = handler.getCompletionItemsList(ctx, completionLiteralURI, lsp.Position{Line: 4, Character: 8}) 201 assert.Equal(t, nil, err) 202 assert.Equal(t, 1, len(items)) 203 assert.True(t, itemInList(items, "python_library")) 204 } 205 206 /*************************************** 207 *Tests for Variables 208 ***************************************/ 209 func TestCompletionWithVars(t *testing.T) { 210 ctx := context.Background() 211 212 items, err := handler.getCompletionItemsList(ctx, completionLiteralURI, lsp.Position{Line: 7, Character: 3}) 213 assert.Equal(t, nil, err) 214 assert.Equal(t, 1, len(items)) 215 assert.Equal(t, "my_str", items[0].Label) 216 217 // Test none existing variable 218 items, err = handler.getCompletionItemsList(ctx, completionLiteralURI, lsp.Position{Line: 6, Character: 10}) 219 assert.Equal(t, nil, err) 220 assert.Equal(t, 0, len(items)) 221 } 222 223 /*************************************** 224 *Tests for Statements 225 ***************************************/ 226 func TestCompletionWithIf(t *testing.T) { 227 ctx := context.Background() 228 229 // test within if statement 230 items, err := handler.getCompletionItemsList(ctx, completionStmtURI, lsp.Position{Line: 7, Character: 7}) 231 assert.Equal(t, nil, err) 232 assert.True(t, itemInList(items, "go_library")) 233 234 items, err = handler.getCompletionItemsList(ctx, completionStmtURI, lsp.Position{Line: 1, Character: 21}) 235 assert.Equal(t, nil, err) 236 assert.Equal(t, len(items), 2) 237 assert.True(t, itemInList(items, "query")) 238 assert.True(t, itemInList(items, "query:query")) 239 240 // test at the beginning of if statement 241 items, err = handler.getCompletionItemsList(ctx, completionStmtURI, lsp.Position{Line: 9, Character: 6}) 242 assert.Equal(t, nil, err) 243 assert.True(t, itemInList(items, "python_library")) 244 245 // test else statement 246 items, err = handler.getCompletionItemsList(ctx, completionStmtURI, lsp.Position{Line: 4, Character: 17}) 247 assert.Equal(t, nil, err) 248 assert.True(t, itemInList(items, "format")) 249 assert.True(t, itemInList(items, "find")) 250 } 251 252 /*************************************** 253 *Tests for Subincludes 254 ***************************************/ 255 func TestCompletionSubinclude(t *testing.T) { 256 ctx := context.Background() 257 258 // test within if statement 259 items, err := handler.getCompletionItemsList(ctx, subincludeURI, lsp.Position{Line: 6, Character: 4}) 260 assert.Equal(t, nil, err) 261 assert.Equal(t, len(items), 1) 262 assert.True(t, itemInList(items, "plz_e2e_test")) 263 } 264 265 /*************************************** 266 *Tests for argument name completion 267 ***************************************/ 268 func TestCompletionArgNameBuild(t *testing.T) { 269 ctx := context.Background() 270 analyzer.State.Config.Parse.BuildFileName = []string{"completion2.build", "BUILD"} 271 272 // test completion for a "visibility" arg 273 items, err := handler.getCompletionItemsList(ctx, completion2URI, lsp.Position{Line: 28, Character: 6}) 274 assert.Equal(t, nil, err) 275 assert.Equal(t, 1, len(items)) 276 277 items, err = handler.getCompletionItemsList(ctx, completion2URI, lsp.Position{Line: 29, Character: 6}) 278 assert.Equal(t, nil, err) 279 assert.Equal(t, 0, len(items)) 280 281 items, err = handler.getCompletionItemsList(ctx, completion2URI, lsp.Position{Line: 30, Character: 6}) 282 assert.Equal(t, nil, err) 283 assert.Equal(t, 2, len(items)) 284 assert.True(t, itemInList(items, "filter_srcs=")) 285 assert.True(t, itemInList(items, "asm_srcs=")) 286 287 } 288 289 func TestCompletionArgSrcLocalFiles(t *testing.T) { 290 ctx := context.Background() 291 analyzer.State.Config.Parse.BuildFileName = []string{"completion2.build", "BUILD"} 292 293 items, err := handler.getCompletionItemsList(ctx, completion2URI, lsp.Position{Line: 26, Character: 11}) 294 assert.Equal(t, nil, err) 295 assert.Equal(t, 3, len(items)) 296 assert.True(t, itemInList(items, "foo.go")) 297 298 // test completion with non-existent srcs 299 items, err = handler.getCompletionItemsList(ctx, completion2URI, lsp.Position{Line: 25, Character: 12}) 300 assert.Equal(t, nil, err) 301 assert.Nil(t, items) 302 303 // test completion with string without ',' 304 items, err = handler.getCompletionItemsList(ctx, completion2URI, lsp.Position{Line: 36, Character: 6}) 305 assert.Equal(t, nil, err) 306 assert.Equal(t, 7, len(items)) 307 assert.True(t, itemInList(items, "foo.go")) 308 309 items, err = handler.getCompletionItemsList(ctx, completion2URI, lsp.Position{Line: 42, Character: 15}) 310 assert.Equal(t, nil, err) 311 assert.Equal(t, 2, len(items)) 312 assert.True(t, itemInList(items, "reformat.build")) 313 assert.True(t, itemInList(items, "reformat2.build")) 314 } 315 316 /*************************************** 317 * Helpers 318 ***************************************/ 319 func itemInList(itemList []*lsp.CompletionItem, targetLabel string) bool { 320 for _, item := range itemList { 321 if item.Label == targetLabel { 322 return true 323 } 324 } 325 return false 326 }