github.com/tiagovtristao/plz@v13.4.0+incompatible/tools/build_langserver/langserver/workspace_store_test.go (about) 1 package langserver 2 3 import ( 4 "context" 5 "github.com/thought-machine/please/src/core" 6 "strings" 7 "testing" 8 9 "github.com/thought-machine/please/tools/build_langserver/lsp" 10 11 "github.com/stretchr/testify/assert" 12 ) 13 14 var ws = newWorkspaceStore(lsp.DocumentURI(core.RepoRoot)) 15 16 func TestWorkspaceStore_Store(t *testing.T) { 17 ctx := context.Background() 18 content, err := ReadFile(ctx, completionURI) 19 assert.Equal(t, nil, err) 20 assert.Equal(t, 0, len(ws.documents)) 21 22 text := strings.Join(content, "\n") 23 ws.Store(completionURI, text, 1) 24 assert.Equal(t, 1, len(ws.documents)) 25 assert.Equal(t, "name = \"langserver_test\"\n", ws.documents[completionURI].text[0]) 26 } 27 28 func TestWorkspaceStore_TrackEdit(t *testing.T) { 29 // Test Add Character 30 change := lsp.TextDocumentContentChangeEvent{ 31 Range: &lsp.Range{ 32 Start: lsp.Position{Line: 4, Character: 7}, 33 End: lsp.Position{Line: 4, Character: 7}, 34 }, 35 RangeLength: 1, 36 Text: "s", 37 } 38 39 err := ws.TrackEdit(completionURI, []lsp.TextDocumentContentChangeEvent{change}, 33) 40 assert.Equal(t, nil, err) 41 assert.Equal(t, " srcs\n", ws.documents[completionURI].textInEdit[4]) 42 43 // Test Remove line 44 change = lsp.TextDocumentContentChangeEvent{ 45 Range: &lsp.Range{ 46 Start: lsp.Position{Line: 9, Character: 0}, 47 End: lsp.Position{Line: 10, Character: 12}, 48 }, 49 RangeLength: 0, 50 Text: "", 51 } 52 53 err = ws.TrackEdit(completionURI, []lsp.TextDocumentContentChangeEvent{change}, 34) 54 assert.Equal(t, nil, err) 55 expected := []string{ 56 "go_test(\n", 57 " name = \"\",\n", 58 " srcs =[],\n", 59 " \"//src\"\n", 60 ")\n", 61 "", 62 } 63 assert.Equal(t, expected, ws.documents[completionURI].textInEdit[6:]) 64 assert.Equal(t, 34, ws.documents[completionURI].version) 65 } 66 67 func TestWorkspaceStore_applyChangeAddChar(t *testing.T) { 68 text := []string{ 69 " \"//src/cli\",\n", 70 " name = \"please\",\n", 71 "\"//src/quer\"\n", 72 "\"//src\"\n", 73 "", 74 } 75 76 // add one character 77 change := lsp.TextDocumentContentChangeEvent{ 78 Range: &lsp.Range{ 79 Start: lsp.Position{Line: 2, Character: 11}, 80 End: lsp.Position{Line: 2, Character: 11}, 81 }, 82 RangeLength: 0, 83 Text: "y", 84 } 85 // Copy the text slice so it doesn't modify original 86 inText := append([]string{}, text...) 87 88 outText, err := ws.applyChange(inText, change) 89 assert.Equal(t, nil, err) 90 expected := []string{ 91 " \"//src/cli\",\n", 92 " name = \"please\",\n", 93 "\"//src/query\"\n", 94 "\"//src\"\n", 95 "", 96 } 97 assert.Equal(t, expected, outText) 98 99 // add a whole line 100 change = lsp.TextDocumentContentChangeEvent{ 101 Range: &lsp.Range{ 102 Start: lsp.Position{Line: 1, Character: 0}, 103 End: lsp.Position{Line: 1, Character: 0}, 104 }, 105 RangeLength: 0, 106 Text: " \"//third_party/go:jsonrpc2\",\n", 107 } 108 // Copy the text slice so it doesn't modify original 109 inText = append([]string{}, text...) 110 111 outText, err = ws.applyChange(inText, change) 112 assert.Equal(t, nil, err) 113 expected = []string{ 114 " \"//src/cli\",\n", 115 " \"//third_party/go:jsonrpc2\",\n", 116 " name = \"please\",\n", 117 "\"//src/quer\"\n", 118 "\"//src\"\n", 119 "", 120 } 121 assert.Equal(t, expected, outText) 122 123 // apply changes with empty content 124 change = lsp.TextDocumentContentChangeEvent{ 125 Range: &lsp.Range{ 126 Start: lsp.Position{Line: 0, Character: 0}, 127 End: lsp.Position{Line: 0, Character: 0}, 128 }, 129 RangeLength: 0, 130 Text: "yh", 131 } 132 outText, err = ws.applyChange([]string{""}, change) 133 assert.Equal(t, nil, err) 134 assert.Equal(t, "yh", outText[0]) 135 assert.Equal(t, 1, len(outText)) 136 } 137 138 func TestWorkspaceStore_applyChangeDelete(t *testing.T) { 139 text := []string{ 140 " \"//src/cli\",\n", 141 " name = \"please\",\n", 142 "\"//src/quer\"\n", 143 "\"//src\"\n", 144 "", 145 } 146 147 // delete one character 148 change := lsp.TextDocumentContentChangeEvent{ 149 Range: &lsp.Range{ 150 Start: lsp.Position{Line: 2, Character: 10}, 151 End: lsp.Position{Line: 2, Character: 11}, 152 }, 153 RangeLength: 0, 154 Text: "", 155 } 156 // Copy the text slice so it doesn't modify original 157 inText := append([]string{}, text...) 158 159 outText, err := ws.applyChange(inText, change) 160 assert.Equal(t, nil, err) 161 expected := []string{ 162 " \"//src/cli\",\n", 163 " name = \"please\",\n", 164 "\"//src/que\"\n", 165 "\"//src\"\n", 166 "", 167 } 168 assert.Equal(t, expected, outText) 169 170 // delete more than one char 171 change = lsp.TextDocumentContentChangeEvent{ 172 Range: &lsp.Range{ 173 Start: lsp.Position{Line: 2, Character: 6}, 174 End: lsp.Position{Line: 2, Character: 11}, 175 }, 176 RangeLength: 0, 177 Text: "", 178 } 179 180 inText = append([]string{}, text...) 181 outText, err = ws.applyChange(inText, change) 182 expected = []string{ 183 " \"//src/cli\",\n", 184 " name = \"please\",\n", 185 "\"//src\"\n", 186 "\"//src\"\n", 187 "", 188 } 189 assert.Equal(t, expected, outText) 190 191 // delete the whole line content 192 change = lsp.TextDocumentContentChangeEvent{ 193 Range: &lsp.Range{ 194 Start: lsp.Position{Line: 2, Character: 0}, 195 End: lsp.Position{Line: 2, Character: 12}, 196 }, 197 RangeLength: 0, 198 Text: "", 199 } 200 201 inText = append([]string{}, text...) 202 outText, err = ws.applyChange(inText, change) 203 expected = []string{ 204 " \"//src/cli\",\n", 205 " name = \"please\",\n", 206 "\n", 207 "\"//src\"\n", 208 "", 209 } 210 assert.Equal(t, expected, outText) 211 212 // delete single line content 213 change = lsp.TextDocumentContentChangeEvent{ 214 Range: &lsp.Range{ 215 Start: lsp.Position{Line: 0, Character: 0}, 216 End: lsp.Position{Line: 0, Character: 5}, 217 }, 218 RangeLength: 0, 219 Text: "", 220 } 221 222 outText, err = ws.applyChange([]string{"hello"}, change) 223 assert.Equal(t, nil, err) 224 assert.Equal(t, 1, len(outText)) 225 assert.Equal(t, "", outText[0]) 226 } 227 228 func TestWorkspaceStore_applyChangeDeleteCrossLine(t *testing.T) { 229 text := []string{ 230 " \"//src/cli\",\n", 231 " name = \"please\",\n", 232 "\"//src/quer\"\n", 233 "\"//blah\"\n", 234 "", 235 } 236 237 // delete the whole line including newline char 238 change := lsp.TextDocumentContentChangeEvent{ 239 Range: &lsp.Range{ 240 Start: lsp.Position{Line: 3, Character: 0}, 241 End: lsp.Position{Line: 4, Character: 0}, 242 }, 243 RangeLength: 0, 244 Text: "", 245 } 246 247 inText := append([]string{}, text...) 248 outText, err := ws.applyChange(inText, change) 249 assert.Equal(t, nil, err) 250 expected := []string{ 251 " \"//src/cli\",\n", 252 " name = \"please\",\n", 253 "\"//src/quer\"\n", 254 "", 255 } 256 assert.Equal(t, expected, outText) 257 258 // Intellij's weird range for deleting the whole line... 259 change = lsp.TextDocumentContentChangeEvent{ 260 Range: &lsp.Range{ 261 Start: lsp.Position{Line: 3, Character: 0}, 262 End: lsp.Position{Line: 4, Character: 8}, 263 }, 264 RangeLength: 0, 265 Text: "", 266 } 267 268 inText = append([]string{}, text...) 269 outText, err = ws.applyChange(inText, change) 270 assert.Equal(t, nil, err) 271 expected = []string{ 272 " \"//src/cli\",\n", 273 " name = \"please\",\n", 274 "\"//src/quer\"\n", 275 "", 276 } 277 assert.Equal(t, expected, outText) 278 279 // and we hope this does not interfere with the same thing 280 // if we delete two lines but leave one of the line breaks 281 change = lsp.TextDocumentContentChangeEvent{ 282 Range: &lsp.Range{ 283 Start: lsp.Position{Line: 2, Character: 0}, 284 End: lsp.Position{Line: 3, Character: 12}, 285 }, 286 RangeLength: 0, 287 Text: "", 288 } 289 290 inText = []string{ 291 " \"//src/cli\",\n", 292 " name = \"please\",\n", 293 "\"//src/quer\"\n", 294 "\"//src/quer\"\n", 295 "\"//blah\"\n", 296 "", 297 } 298 outText, err = ws.applyChange(inText, change) 299 assert.Equal(t, nil, err) 300 expected = []string{ 301 " \"//src/cli\",\n", 302 " name = \"please\",\n", 303 "\n", 304 "\"//blah\"\n", 305 "", 306 } 307 assert.Equal(t, expected, outText) 308 309 // delete some the previous line, but leaving parts of the next line 310 change = lsp.TextDocumentContentChangeEvent{ 311 Range: &lsp.Range{ 312 Start: lsp.Position{Line: 2, Character: 0}, 313 End: lsp.Position{Line: 3, Character: 5}, 314 }, 315 RangeLength: 0, 316 Text: "", 317 } 318 319 inText = append([]string{}, text...) 320 outText, err = ws.applyChange(inText, change) 321 assert.Equal(t, nil, err) 322 expected = []string{ 323 " \"//src/cli\",\n", 324 " name = \"please\",\n", 325 "ah\"\n", 326 "", 327 } 328 assert.Equal(t, expected, outText) 329 330 change = lsp.TextDocumentContentChangeEvent{ 331 Range: &lsp.Range{ 332 Start: lsp.Position{Line: 1, Character: 17}, 333 End: lsp.Position{Line: 3, Character: 8}, 334 }, 335 RangeLength: 0, 336 Text: "", 337 } 338 339 inText = append([]string{}, text...) 340 outText, err = ws.applyChange(inText, change) 341 assert.Equal(t, nil, err) 342 expected = []string{ 343 " \"//src/cli\",\n", 344 " name = \"please\",\n", 345 "", 346 } 347 assert.Equal(t, expected, outText) 348 } 349 350 func TestSplitLines(t *testing.T) { 351 content := " \"//src/cli\",\n" + 352 " name = \"please\",\n" + 353 "\"//src/quer\"\n" 354 355 text := SplitLines(content, true) 356 expected := []string{ 357 " \"//src/cli\",\n", 358 " name = \"please\",\n", 359 "\"//src/quer\"\n", 360 "", 361 } 362 363 assert.Equal(t, expected, text) 364 365 // Test with empty content 366 content = "" 367 assert.Equal(t, []string{""}, SplitLines(content, true)) 368 } 369 370 func TestJoinLines(t *testing.T) { 371 text := []string{ 372 " \"//src/cli\",\n", 373 " name = \"please\",\n", 374 "\"//src/quer\"\n", 375 "", 376 } 377 expected := " \"//src/cli\",\n" + 378 " name = \"please\",\n" + 379 "\"//src/quer\"\n" 380 content := JoinLines(text, true) 381 382 assert.Equal(t, expected, content) 383 384 stmts, _ := analyzer.AspStatementFromFile(exampleBuildURI) 385 for _, stmt := range stmts { 386 t.Log(stmt) 387 } 388 389 }