diagnostic_spec.lua (25249B)
1 local t = require('test.testutil') 2 local n = require('test.functional.testnvim')() 3 4 local t_lsp = require('test.functional.plugin.lsp.testutil') 5 6 local clear = n.clear 7 local exec_lua = n.exec_lua 8 local eq = t.eq 9 local neq = t.neq 10 11 local create_server_definition = t_lsp.create_server_definition 12 13 describe('vim.lsp.diagnostic', function() 14 local fake_uri --- @type string 15 local client_id --- @type integer 16 local diagnostic_bufnr --- @type integer 17 18 before_each(function() 19 clear { env = { 20 NVIM_LUA_NOTRACK = '1', 21 VIMRUNTIME = os.getenv 'VIMRUNTIME', 22 } } 23 24 exec_lua(function() 25 require('vim.lsp') 26 27 _G.make_range = function(x1, y1, x2, y2) 28 return { start = { line = x1, character = y1 }, ['end'] = { line = x2, character = y2 } } 29 end 30 31 _G.make_error = function(msg, x1, y1, x2, y2) 32 return { 33 range = _G.make_range(x1, y1, x2, y2), 34 message = msg, 35 severity = 1, 36 } 37 end 38 39 _G.make_warning = function(msg, x1, y1, x2, y2) 40 return { 41 range = _G.make_range(x1, y1, x2, y2), 42 message = msg, 43 severity = 2, 44 } 45 end 46 47 _G.make_information = function(msg, x1, y1, x2, y2) 48 return { 49 range = _G.make_range(x1, y1, x2, y2), 50 message = msg, 51 severity = 3, 52 } 53 end 54 55 function _G.get_extmarks(bufnr, client_id0) 56 local namespace = vim.lsp.diagnostic.get_namespace(client_id0) 57 local ns = vim.diagnostic.get_namespace(namespace) 58 local extmarks = {} 59 if ns.user_data.virt_text_ns then 60 for _, e in 61 pairs( 62 vim.api.nvim_buf_get_extmarks( 63 bufnr, 64 ns.user_data.virt_text_ns, 65 0, 66 -1, 67 { details = true } 68 ) 69 ) 70 do 71 table.insert(extmarks, e) 72 end 73 end 74 if ns.user_data.underline_ns then 75 for _, e in 76 pairs( 77 vim.api.nvim_buf_get_extmarks( 78 bufnr, 79 ns.user_data.underline_ns, 80 0, 81 -1, 82 { details = true } 83 ) 84 ) 85 do 86 table.insert(extmarks, e) 87 end 88 end 89 return extmarks 90 end 91 end) 92 93 fake_uri = 'file:///fake/uri' 94 95 exec_lua(function() 96 diagnostic_bufnr = vim.uri_to_bufnr(fake_uri) 97 local lines = { '1st line', '2nd line of text', 'wow', 'cool', 'more', 'lines' } 98 vim.fn.bufload(diagnostic_bufnr) 99 vim.api.nvim_buf_set_lines(diagnostic_bufnr, 0, 1, false, lines) 100 vim.api.nvim_win_set_buf(0, diagnostic_bufnr) 101 end) 102 end) 103 104 describe('vim.lsp.diagnostic.on_publish_diagnostics', function() 105 before_each(function() 106 exec_lua(function() 107 client_id = assert(vim.lsp.start({ 108 cmd_env = { 109 NVIM_LUA_NOTRACK = '1', 110 }, 111 cmd = { 112 vim.v.progpath, 113 '-es', 114 '-u', 115 'NONE', 116 '--headless', 117 }, 118 offset_encoding = 'utf-16', 119 }, { attach = false })) 120 end) 121 end) 122 123 after_each(function() 124 exec_lua(function() 125 vim.lsp.get_client_by_id(client_id):stop() 126 vim.api.nvim_exec_autocmds('VimLeavePre', { modeline = false }) 127 end) 128 end) 129 130 it('correctly handles UTF-16 offsets', function() 131 local line = 'All 💼 and no 🎉 makes Jack a dull 👦' 132 local result = exec_lua(function() 133 vim.api.nvim_buf_set_lines(diagnostic_bufnr, 0, -1, false, { line }) 134 135 vim.lsp.diagnostic.on_publish_diagnostics(nil, { 136 uri = fake_uri, 137 diagnostics = { 138 _G.make_error('UTF-16 Diagnostic', 0, 7, 0, 8), 139 }, 140 }, { client_id = client_id }) 141 142 local diags = vim.diagnostic.get(diagnostic_bufnr) 143 return diags 144 end) 145 eq(1, #result) 146 eq( 147 exec_lua(function() 148 return vim.str_byteindex(line, 'utf-16', 7) 149 end), 150 result[1].col 151 ) 152 eq( 153 exec_lua(function() 154 return vim.str_byteindex(line, 'utf-16', 8) 155 end), 156 result[1].end_col 157 ) 158 end) 159 160 it('does not create buffer on empty diagnostics', function() 161 -- No buffer is created without diagnostics 162 eq( 163 -1, 164 exec_lua(function() 165 vim.lsp.diagnostic.on_publish_diagnostics(nil, { 166 uri = 'file:///fake/uri2', 167 diagnostics = {}, 168 }, { client_id = client_id }) 169 return vim.fn.bufnr(vim.uri_to_fname('file:///fake/uri2')) 170 end) 171 ) 172 173 -- Create buffer on diagnostics 174 neq( 175 -1, 176 exec_lua(function() 177 vim.lsp.diagnostic.on_publish_diagnostics(nil, { 178 uri = 'file:///fake/uri2', 179 diagnostics = { 180 _G.make_error('Diagnostic', 0, 0, 0, 0), 181 }, 182 }, { client_id = client_id }) 183 return vim.fn.bufnr(vim.uri_to_fname('file:///fake/uri2')) 184 end) 185 ) 186 eq( 187 1, 188 exec_lua(function() 189 return #vim.diagnostic.get(_G.bufnr) 190 end) 191 ) 192 193 -- Clear diagnostics after buffer was created 194 neq( 195 -1, 196 exec_lua(function() 197 vim.lsp.diagnostic.on_publish_diagnostics(nil, { 198 uri = 'file:///fake/uri2', 199 diagnostics = {}, 200 }, { client_id = client_id }) 201 return vim.fn.bufnr(vim.uri_to_fname('file:///fake/uri2')) 202 end) 203 ) 204 eq( 205 0, 206 exec_lua(function() 207 return #vim.diagnostic.get(_G.bufnr) 208 end) 209 ) 210 end) 211 212 it('clears diagnostics for the client namespace on empty publish', function() 213 local before_clear, after_clear = exec_lua(function() 214 local ns = vim.lsp.diagnostic.get_namespace(client_id) 215 216 -- Publish diagnostics 217 vim.lsp.diagnostic.on_publish_diagnostics(nil, { 218 uri = fake_uri, 219 diagnostics = { 220 _G.make_error('Diagnostic', 0, 0, 0, 0), 221 }, 222 }, { client_id = client_id }) 223 224 local before_clear = vim.diagnostic.get(diagnostic_bufnr, { namespace = ns }) 225 226 -- Publish empty diagnostics 227 vim.lsp.diagnostic.on_publish_diagnostics(nil, { 228 uri = fake_uri, 229 diagnostics = {}, 230 }, { client_id = client_id }) 231 232 local after_clear = vim.diagnostic.get(diagnostic_bufnr, { namespace = ns }) 233 234 return before_clear, after_clear 235 end) 236 237 eq(1, #before_clear) 238 eq(0, #after_clear) 239 end) 240 241 it('clears diagnostics when buffer is deleted', function() 242 local before_delete, after_delete = exec_lua(function() 243 local ns = vim.lsp.diagnostic.get_namespace(client_id) 244 245 -- Publish diagnostics 246 vim.lsp.diagnostic.on_publish_diagnostics(nil, { 247 uri = fake_uri, 248 diagnostics = { 249 _G.make_error('Diagnostic', 0, 0, 0, 0), 250 }, 251 }, { client_id = client_id }) 252 253 local before_delete = vim.diagnostic.get(diagnostic_bufnr, { namespace = ns }) 254 255 -- Avoid deleting the currently displayed buffer (Windows teardown edge case) 256 local scratch = vim.api.nvim_create_buf(false, true) 257 vim.api.nvim_win_set_buf(0, scratch) 258 259 -- Delete the buffer deterministically 260 vim.api.nvim_buf_delete(diagnostic_bufnr, { force = true }) 261 262 -- Query remaining diagnostics via valid access path 263 -- (deleted buffer cannot be queried directly) 264 local after_delete = vim.diagnostic.get(nil, { namespace = ns }) 265 266 return before_delete, after_delete 267 end) 268 269 eq(1, #before_delete) 270 eq(0, #after_delete) 271 end) 272 end) 273 274 describe('vim.lsp.diagnostic.on_diagnostic', function() 275 before_each(function() 276 exec_lua(create_server_definition) 277 exec_lua(function() 278 _G.requests = 0 279 _G.server = _G._create_server({ 280 capabilities = { 281 diagnosticProvider = {}, 282 }, 283 handlers = { 284 ['textDocument/diagnostic'] = function(_, params) 285 _G.params = params 286 _G.requests = _G.requests + 1 287 end, 288 }, 289 }) 290 291 function _G.get_extmarks(bufnr, client_id0) 292 local namespace = vim.lsp.diagnostic.get_namespace(client_id0, true) 293 local ns = vim.diagnostic.get_namespace(namespace) 294 local extmarks = {} 295 if ns.user_data.virt_text_ns then 296 for _, e in 297 pairs( 298 vim.api.nvim_buf_get_extmarks( 299 bufnr, 300 ns.user_data.virt_text_ns, 301 0, 302 -1, 303 { details = true } 304 ) 305 ) 306 do 307 table.insert(extmarks, e) 308 end 309 end 310 if ns.user_data.underline_ns then 311 for _, e in 312 pairs( 313 vim.api.nvim_buf_get_extmarks( 314 bufnr, 315 ns.user_data.underline_ns, 316 0, 317 -1, 318 { details = true } 319 ) 320 ) 321 do 322 table.insert(extmarks, e) 323 end 324 end 325 return extmarks 326 end 327 328 client_id = assert(vim.lsp.start({ name = 'dummy', cmd = _G.server.cmd })) 329 end) 330 end) 331 332 it('adds diagnostics to vim.diagnostics', function() 333 local diags = exec_lua(function() 334 vim.lsp.diagnostic.on_diagnostic(nil, { 335 kind = 'full', 336 items = { 337 _G.make_error('Pull Diagnostic', 4, 4, 4, 4), 338 }, 339 }, { 340 params = { 341 textDocument = { uri = fake_uri }, 342 }, 343 uri = fake_uri, 344 client_id = client_id, 345 bufnr = diagnostic_bufnr, 346 }, {}) 347 348 return vim.diagnostic.get(diagnostic_bufnr) 349 end) 350 eq(1, #diags) 351 eq('Pull Diagnostic', diags[1].message) 352 end) 353 354 it('preserves push diagnostics when pull diagnostics are empty', function() 355 local push_ns_count, pull_ns_count, all_diags_count, push_ns, pull_ns = exec_lua(function() 356 vim.lsp.diagnostic.on_publish_diagnostics(nil, { 357 uri = fake_uri, 358 diagnostics = { 359 _G.make_error('Push Diagnostic', 0, 0, 0, 0), 360 }, 361 }, { client_id = client_id }) 362 363 vim.lsp.diagnostic.on_diagnostic(nil, { 364 kind = 'full', 365 items = {}, 366 }, { 367 params = { 368 textDocument = { uri = fake_uri }, 369 }, 370 uri = fake_uri, 371 client_id = client_id, 372 bufnr = diagnostic_bufnr, 373 }, {}) 374 375 local push_ns = vim.lsp.diagnostic.get_namespace(client_id, false) 376 local pull_ns = vim.lsp.diagnostic.get_namespace(client_id, true) 377 378 return #vim.diagnostic.get(diagnostic_bufnr, { namespace = push_ns }), 379 #vim.diagnostic.get(diagnostic_bufnr, { namespace = pull_ns }), 380 #vim.diagnostic.get(diagnostic_bufnr), 381 push_ns, 382 pull_ns 383 end) 384 385 eq(1, push_ns_count) 386 eq(0, pull_ns_count) 387 eq(1, all_diags_count) 388 neq(push_ns, pull_ns) 389 end) 390 391 it('uses pull_id to isolate pull diagnostic namespaces', function() 392 local first_count, second_count, total_count, first_ns, second_ns = exec_lua(function() 393 vim.lsp.diagnostic.on_diagnostic(nil, { 394 kind = 'full', 395 items = { 396 _G.make_error('Pull Diagnostic A', 0, 0, 0, 0), 397 }, 398 }, { 399 params = { 400 identifier = 'provider-a', 401 textDocument = { uri = fake_uri }, 402 }, 403 uri = fake_uri, 404 client_id = client_id, 405 bufnr = diagnostic_bufnr, 406 }, {}) 407 408 vim.lsp.diagnostic.on_diagnostic(nil, { 409 kind = 'full', 410 items = {}, 411 }, { 412 params = { 413 identifier = 'provider-b', 414 textDocument = { uri = fake_uri }, 415 }, 416 uri = fake_uri, 417 client_id = client_id, 418 bufnr = diagnostic_bufnr, 419 }, {}) 420 421 local first_ns = vim.lsp.diagnostic.get_namespace(client_id, 'provider-a') 422 local second_ns = vim.lsp.diagnostic.get_namespace(client_id, 'provider-b') 423 424 return #vim.diagnostic.get(diagnostic_bufnr, { namespace = first_ns }), 425 #vim.diagnostic.get(diagnostic_bufnr, { namespace = second_ns }), 426 #vim.diagnostic.get(diagnostic_bufnr), 427 first_ns, 428 second_ns 429 end) 430 431 eq(1, first_count) 432 eq(0, second_count) 433 eq(1, total_count) 434 neq(first_ns, second_ns) 435 end) 436 437 it('handles multiline diagnostic ranges #33782', function() 438 local diags = exec_lua(function() 439 vim.lsp.diagnostic.on_diagnostic(nil, { 440 kind = 'full', 441 items = { 442 _G.make_error('Pull Diagnostic', 0, 6, 1, 10), 443 }, 444 }, { 445 params = { 446 textDocument = { uri = fake_uri }, 447 }, 448 uri = fake_uri, 449 client_id = client_id, 450 bufnr = diagnostic_bufnr, 451 }, {}) 452 453 return vim.diagnostic.get(diagnostic_bufnr) 454 end) 455 local lines = exec_lua(function() 456 return vim.api.nvim_buf_get_lines(diagnostic_bufnr, 0, -1, false) 457 end) 458 -- This test case must be run over a multiline diagnostic in which the start line is shorter 459 -- than the end line, and the end_col exceeds the start line's length. 460 eq(#lines[1], 8) 461 eq(#lines[2], 16) 462 eq(1, #diags) 463 eq(6, diags[1].col) 464 eq(10, diags[1].end_col) 465 end) 466 467 it('severity defaults to error if missing', function() 468 ---@type vim.Diagnostic[] 469 local diagnostics = exec_lua(function() 470 vim.lsp.diagnostic.on_diagnostic(nil, { 471 kind = 'full', 472 items = { 473 { 474 range = _G.make_range(4, 4, 4, 4), 475 message = 'bad!', 476 }, 477 }, 478 }, { 479 params = { 480 textDocument = { uri = fake_uri }, 481 }, 482 uri = fake_uri, 483 client_id = client_id, 484 bufnr = diagnostic_bufnr, 485 }, {}) 486 return vim.diagnostic.get(diagnostic_bufnr) 487 end) 488 eq(1, #diagnostics) 489 eq(1, diagnostics[1].severity) 490 end) 491 492 it('clears diagnostics when client detaches', function() 493 exec_lua(function() 494 vim.lsp.diagnostic.on_diagnostic(nil, { 495 kind = 'full', 496 items = { 497 _G.make_error('Pull Diagnostic', 4, 4, 4, 4), 498 }, 499 }, { 500 params = { 501 textDocument = { uri = fake_uri }, 502 }, 503 uri = fake_uri, 504 client_id = client_id, 505 bufnr = diagnostic_bufnr, 506 }, {}) 507 end) 508 509 eq( 510 1, 511 exec_lua(function() 512 return #vim.diagnostic.get(diagnostic_bufnr) 513 end) 514 ) 515 516 exec_lua(function() 517 vim.lsp.get_client_by_id(client_id):stop() 518 end) 519 520 eq( 521 0, 522 exec_lua(function() 523 return #vim.diagnostic.get(diagnostic_bufnr) 524 end) 525 ) 526 end) 527 528 it('keeps diagnostics when one client detaches and others still are attached', function() 529 exec_lua(function() 530 _G.client_id2 = assert(vim.lsp.start({ name = 'dummy2', cmd = _G.server.cmd })) 531 532 vim.lsp.diagnostic.on_diagnostic(nil, { 533 kind = 'full', 534 items = { 535 _G.make_error('Pull Diagnostic', 4, 4, 4, 4), 536 }, 537 }, { 538 params = { 539 textDocument = { uri = fake_uri }, 540 }, 541 uri = fake_uri, 542 client_id = client_id, 543 bufnr = diagnostic_bufnr, 544 }, {}) 545 end) 546 547 eq( 548 1, 549 exec_lua(function() 550 return #vim.diagnostic.get(diagnostic_bufnr) 551 end) 552 ) 553 554 exec_lua(function() 555 vim.lsp.get_client_by_id(_G.client_id2):stop() 556 end) 557 558 eq( 559 1, 560 exec_lua(function() 561 return #vim.diagnostic.get(diagnostic_bufnr) 562 end) 563 ) 564 end) 565 566 it('handles server cancellation', function() 567 eq( 568 1, 569 exec_lua(function() 570 vim.lsp.diagnostic.on_diagnostic({ 571 code = vim.lsp.protocol.ErrorCodes.ServerCancelled, 572 -- Empty data defaults to retriggering request 573 data = {}, 574 message = '', 575 }, {}, { 576 method = 'textDocument/diagnostic', 577 client_id = client_id, 578 bufnr = diagnostic_bufnr, 579 }) 580 581 return _G.requests 582 end) 583 ) 584 585 eq( 586 2, 587 exec_lua(function() 588 vim.lsp.diagnostic.on_diagnostic({ 589 code = vim.lsp.protocol.ErrorCodes.ServerCancelled, 590 data = { retriggerRequest = true }, 591 message = '', 592 }, {}, { 593 method = 'textDocument/diagnostic', 594 client_id = client_id, 595 bufnr = diagnostic_bufnr, 596 }) 597 598 return _G.requests 599 end) 600 ) 601 602 eq( 603 2, 604 exec_lua(function() 605 vim.lsp.diagnostic.on_diagnostic({ 606 code = vim.lsp.protocol.ErrorCodes.ServerCancelled, 607 data = { retriggerRequest = false }, 608 message = '', 609 }, {}, { 610 method = 'textDocument/diagnostic', 611 client_id = client_id, 612 bufnr = diagnostic_bufnr, 613 }) 614 615 return _G.requests 616 end) 617 ) 618 end) 619 620 it('supports dynamic registration', function() 621 exec_lua(create_server_definition) 622 exec_lua(function() 623 _G.server2 = _G._create_server({ 624 diagnosticProvider = { 625 documentSelector = vim.NIL, 626 }, 627 handlers = { 628 ['textDocument/diagnostic'] = function(_, _, callback) 629 callback(nil, { 630 kind = 'full', 631 items = { 632 _G.make_error('Dynamic Diagnostic', 4, 4, 4, 4), 633 }, 634 }) 635 end, 636 }, 637 }) 638 639 local client_id2 = assert(vim.lsp.start({ name = 'dummy2', cmd = _G.server2.cmd })) 640 641 vim.lsp.handlers['client/registerCapability'](nil, { 642 registrations = { 643 { id = 'diagnostic', method = 'textDocument/diagnostic' }, 644 }, 645 }, { client_id = client_id2, method = 'client/registerCapability' }) 646 end) 647 648 eq( 649 1, 650 exec_lua(function() 651 return #vim.diagnostic.get(diagnostic_bufnr) 652 end) 653 ) 654 end) 655 656 it('requests with the `previousResultId`', function() 657 -- Full reports 658 eq( 659 'dummy_server', 660 exec_lua(function() 661 vim.lsp.diagnostic.on_diagnostic(nil, { 662 kind = 'full', 663 resultId = 'dummy_server', 664 items = { 665 _G.make_error('Pull Diagnostic', 4, 4, 4, 4), 666 }, 667 }, { 668 method = 'textDocument/diagnostic', 669 params = { 670 textDocument = { uri = fake_uri }, 671 }, 672 client_id = client_id, 673 bufnr = diagnostic_bufnr, 674 }) 675 vim.api.nvim_exec_autocmds('LspNotify', { 676 buffer = diagnostic_bufnr, 677 data = { 678 method = 'textDocument/didChange', 679 client_id = client_id, 680 }, 681 }) 682 return _G.params.previousResultId 683 end) 684 ) 685 686 -- Unchanged reports 687 eq( 688 'squidward', 689 exec_lua(function() 690 vim.lsp.diagnostic.on_diagnostic(nil, { 691 kind = 'unchanged', 692 resultId = 'squidward', 693 }, { 694 method = 'textDocument/diagnostic', 695 params = { 696 textDocument = { uri = fake_uri }, 697 }, 698 client_id = client_id, 699 bufnr = diagnostic_bufnr, 700 }) 701 vim.api.nvim_exec_autocmds('LspNotify', { 702 buffer = diagnostic_bufnr, 703 data = { 704 method = 'textDocument/didChange', 705 client_id = client_id, 706 }, 707 }) 708 return _G.params.previousResultId 709 end) 710 ) 711 end) 712 713 it('handles relatedDocuments diagnostics', function() 714 local fake_uri_2 = 'file:///fake/uri2' 715 ---@type vim.Diagnostic[], vim.Diagnostic[], string? 716 local diagnostics, related_diagnostics, relatedPreviousResultId = exec_lua(function() 717 local second_buf = vim.uri_to_bufnr(fake_uri_2) 718 vim.fn.bufload(second_buf) 719 720 -- Attach the client to both buffers. 721 vim.api.nvim_win_set_buf(0, second_buf) 722 vim.lsp.start({ name = 'dummy', cmd = _G.server.cmd }) 723 724 vim.lsp.diagnostic.on_diagnostic(nil, { 725 kind = 'full', 726 relatedDocuments = { 727 [fake_uri_2] = { 728 kind = 'full', 729 resultId = 'spongebob', 730 items = { 731 { 732 range = _G.make_range(4, 4, 4, 4), 733 message = 'related bad!', 734 }, 735 }, 736 }, 737 }, 738 items = {}, 739 }, { 740 params = { 741 textDocument = { uri = fake_uri }, 742 }, 743 uri = fake_uri, 744 client_id = client_id, 745 bufnr = diagnostic_bufnr, 746 }, {}) 747 748 vim.api.nvim_exec_autocmds('LspNotify', { 749 buffer = second_buf, 750 data = { 751 method = 'textDocument/didChange', 752 client_id = client_id, 753 }, 754 }) 755 756 return vim.diagnostic.get(diagnostic_bufnr), 757 vim.diagnostic.get(second_buf), 758 _G.params.previousResultId 759 end) 760 eq(0, #diagnostics) 761 eq(1, #related_diagnostics) 762 eq('related bad!', related_diagnostics[1].message) 763 eq('spongebob', relatedPreviousResultId) 764 end) 765 end) 766 767 describe('vim.lsp.diagnostic.on_refresh', function() 768 it('refreshes diagnostics on server-to-client request', function() 769 exec_lua(create_server_definition) 770 exec_lua(function() 771 _G.requests = 0 772 _G.server = _G._create_server({ 773 capabilities = { 774 diagnosticProvider = {}, 775 }, 776 handlers = { 777 ['textDocument/diagnostic'] = function(_, _, callback) 778 _G.requests = _G.requests + 1 779 callback(nil, { 780 kind = 'full', 781 items = { 782 _G.make_warning('Pull Diagnostic', 4, 4, 4, 4), 783 }, 784 }) 785 end, 786 }, 787 }) 788 client_id = assert(vim.lsp.start({ name = 'dummy', cmd = _G.server.cmd })) 789 end) 790 791 local diags = exec_lua(function() 792 vim.lsp.diagnostic.on_diagnostic(nil, { 793 kind = 'full', 794 items = { 795 _G.make_error('Pull Diagnostic', 4, 4, 4, 4), 796 }, 797 }, { 798 params = { 799 textDocument = { uri = fake_uri }, 800 }, 801 uri = fake_uri, 802 client_id = client_id, 803 bufnr = diagnostic_bufnr, 804 }, {}) 805 806 return vim.diagnostic.get(diagnostic_bufnr) 807 end) 808 eq(1, #diags) 809 eq(1, diags[1].severity) 810 811 local requests, refreshed_diags = exec_lua(function() 812 vim.lsp.diagnostic.on_refresh(nil, nil, { 813 method = 'workspace/diagnostic/refresh', 814 client_id = client_id, 815 }) 816 817 return _G.requests, vim.diagnostic.get(diagnostic_bufnr) 818 end) 819 eq(1, requests) 820 eq(1, #refreshed_diags) 821 eq(2, refreshed_diags[1].severity) 822 end) 823 824 it('refreshes workspace diagnostics', function() 825 local fake_uri_3 = 'file:///fake/uri3' 826 exec_lua(create_server_definition) 827 exec_lua(function() 828 _G.requests = 0 829 _G.server = _G._create_server({ 830 capabilities = { 831 diagnosticProvider = { workspaceDiagnostics = true }, 832 }, 833 handlers = { 834 ['workspace/diagnostic'] = function(_, _, callback) 835 _G.requests = _G.requests + 1 836 callback(nil, { 837 items = { 838 { 839 kind = 'full', 840 uri = fake_uri_3, 841 items = { 842 _G.make_error('Workspace Diagnostic', 4, 4, 4, 4), 843 }, 844 }, 845 }, 846 }) 847 end, 848 }, 849 }) 850 client_id = assert(vim.lsp.start({ name = 'dummy', cmd = _G.server.cmd })) 851 end) 852 853 eq( 854 0, 855 exec_lua(function() 856 return #vim.diagnostic.get() 857 end) 858 ) 859 860 eq( 861 { vim.NIL }, 862 exec_lua(function() 863 local client = vim.lsp.get_client_by_id(client_id) 864 assert(client) 865 return client:_provider_value_get('workspace/diagnostic', 'identifier') 866 end) 867 ) 868 869 local requests, diags = exec_lua(function() 870 vim.lsp.diagnostic.on_refresh(nil, nil, { 871 method = 'workspace/diagnostic/refresh', 872 client_id = client_id, 873 }) 874 875 return _G.requests, vim.diagnostic.get() 876 end) 877 eq(1, requests) 878 eq(1, #diags) 879 eq(1, diags[1].severity) 880 end) 881 end) 882 end)