diff options
Diffstat (limited to 'test/functional/plugin/lsp_spec.lua')
-rw-r--r-- | test/functional/plugin/lsp_spec.lua | 213 |
1 files changed, 208 insertions, 5 deletions
diff --git a/test/functional/plugin/lsp_spec.lua b/test/functional/plugin/lsp_spec.lua index 81ef8a9733..37fba02e0e 100644 --- a/test/functional/plugin/lsp_spec.lua +++ b/test/functional/plugin/lsp_spec.lua @@ -3,9 +3,11 @@ local helpers = require('test.functional.helpers')(after_each) local assert_log = helpers.assert_log local clear = helpers.clear local buf_lines = helpers.buf_lines +local command = helpers.command local dedent = helpers.dedent local exec_lua = helpers.exec_lua local eq = helpers.eq +local eval = helpers.eval local matches = helpers.matches local pcall_err = helpers.pcall_err local pesc = helpers.pesc @@ -272,7 +274,7 @@ describe('LSP', function() return end local expected_handlers = { - {NIL, {}, {method="shutdown", client_id=1}}; + {NIL, {}, {method="shutdown", bufnr=1, client_id=1}}; {NIL, {}, {method="test", client_id=1}}; } test_rpc_server { @@ -486,7 +488,7 @@ describe('LSP', function() it('should forward ContentModified to callback', function() local expected_handlers = { {NIL, {}, {method="finish", client_id=1}}; - {{code = -32801}, NIL, {method = "error_code_test", client_id=1}}; + {{code = -32801}, NIL, {method = "error_code_test", bufnr=1, client_id=1}}; } local client test_rpc_server { @@ -509,6 +511,140 @@ describe('LSP', function() } end) + it('should track pending requests to the language server', function() + local expected_handlers = { + {NIL, {}, {method="finish", client_id=1}}; + {NIL, {}, {method="slow_request", bufnr=1, client_id=1}}; + } + local client + test_rpc_server { + test_name = "check_pending_request_tracked"; + on_init = function(_client) + client = _client + client.request("slow_request") + local request = exec_lua([=[ return TEST_RPC_CLIENT.requests[2] ]=]) + eq("slow_request", request.method) + eq("pending", request.type) + client.notify("release") + end; + on_exit = function(code, signal) + eq(0, code, "exit code", fake_lsp_logfile) + eq(0, signal, "exit signal", fake_lsp_logfile) + eq(0, #expected_handlers, "did not call expected handler") + end; + on_handler = function(err, _, ctx) + eq(table.remove(expected_handlers), {err, {}, ctx}, "expected handler") + if ctx.method == 'slow_request' then + local request = exec_lua([=[ return TEST_RPC_CLIENT.requests[2] ]=]) + eq(NIL, request) + client.notify("finish") + end + if ctx.method == 'finish' then client.stop() end + end; + } + end) + + it('should track cancel requests to the language server', function() + local expected_handlers = { + {NIL, {}, {method="finish", client_id=1}}; + } + local client + test_rpc_server { + test_name = "check_cancel_request_tracked"; + on_init = function(_client) + client = _client + client.request("slow_request") + client.cancel_request(2) + local request = exec_lua([=[ return TEST_RPC_CLIENT.requests[2] ]=]) + eq("slow_request", request.method) + eq("cancel", request.type) + client.notify("release") + end; + on_exit = function(code, signal) + eq(0, code, "exit code", fake_lsp_logfile) + eq(0, signal, "exit signal", fake_lsp_logfile) + eq(0, #expected_handlers, "did not call expected handler") + end; + on_handler = function(err, _, ctx) + eq(table.remove(expected_handlers), {err, {}, ctx}, "expected handler") + local request = exec_lua([=[ return TEST_RPC_CLIENT.requests[2] ]=]) + eq(NIL, request) + if ctx.method == 'finish' then client.stop() end + end; + } + end) + + it('should clear pending and cancel requests on reply', function() + local expected_handlers = { + {NIL, {}, {method="finish", client_id=1}}; + {NIL, {}, {method="slow_request", bufnr=1, client_id=1}}; + } + local client + test_rpc_server { + test_name = "check_tracked_requests_cleared"; + on_init = function(_client) + client = _client + client.request("slow_request") + local request = exec_lua([=[ return TEST_RPC_CLIENT.requests[2] ]=]) + eq("slow_request", request.method) + eq("pending", request.type) + client.cancel_request(2) + request = exec_lua([=[ return TEST_RPC_CLIENT.requests[2] ]=]) + eq("slow_request", request.method) + eq("cancel", request.type) + client.notify("release") + end; + on_exit = function(code, signal) + eq(0, code, "exit code", fake_lsp_logfile) + eq(0, signal, "exit signal", fake_lsp_logfile) + eq(0, #expected_handlers, "did not call expected handler") + end; + on_handler = function(err, _, ctx) + eq(table.remove(expected_handlers), {err, {}, ctx}, "expected handler") + if ctx.method == 'slow_request' then + local request = exec_lua([=[ return TEST_RPC_CLIENT.requests[2] ]=]) + eq(NIL, request) + client.notify("finish") + end + if ctx.method == 'finish' then client.stop() end + end; + } + end) + + it('should trigger LspRequest autocmd when requests table changes', function() + local expected_handlers = { + {NIL, {}, {method="finish", client_id=1}}; + {NIL, {}, {method="slow_request", bufnr=1, client_id=1}}; + } + local client + test_rpc_server { + test_name = "check_tracked_requests_cleared"; + on_init = function(_client) + command('let g:requests = 0') + command('autocmd User LspRequest let g:requests+=1') + client = _client + client.request("slow_request") + eq(1, eval('g:requests')) + client.cancel_request(2) + eq(2, eval('g:requests')) + client.notify("release") + end; + on_exit = function(code, signal) + eq(0, code, "exit code", fake_lsp_logfile) + eq(0, signal, "exit signal", fake_lsp_logfile) + eq(0, #expected_handlers, "did not call expected handler") + eq(3, eval('g:requests')) + end; + on_handler = function(err, _, ctx) + eq(table.remove(expected_handlers), {err, {}, ctx}, "expected handler") + if ctx.method == 'slow_request' then + client.notify("finish") + end + if ctx.method == 'finish' then client.stop() end + end; + } + end) + it('should not send didOpen if the buffer closes before init', function() local expected_handlers = { {NIL, {}, {method="shutdown", client_id=1}}; @@ -790,7 +926,7 @@ describe('LSP', function() -- TODO(askhan) we don't support full for now, so we can disable these tests. pending('should check the body and didChange incremental normal mode editing', function() local expected_handlers = { - {NIL, {}, {method="shutdown", client_id=1}}; + {NIL, {}, {method="shutdown", bufnr=1, client_id=1}}; {NIL, {}, {method="finish", client_id=1}}; {NIL, {}, {method="start", client_id=1}}; } @@ -1164,10 +1300,11 @@ describe('LSP', function() eq({ 2, 6 }, funcs.nvim_win_get_cursor(0)) end) - it('fix the cursor to the valid column if the content was removed', function() + it('fix the cursor to the valid col if the content was removed', function() funcs.nvim_win_set_cursor(0, { 2, 6 }) local edits = { - make_edit(1, 0, 1, 19, '') + make_edit(1, 0, 1, 6, ''), + make_edit(1, 6, 1, 19, '') } exec_lua('vim.lsp.util.apply_text_edits(...)', edits, 1) eq({ @@ -1180,6 +1317,19 @@ describe('LSP', function() eq({ 2, 0 }, funcs.nvim_win_get_cursor(0)) end) + it('fix the cursor to the valid row if the content was removed', function() + funcs.nvim_win_set_cursor(0, { 2, 6 }) + local edits = { + make_edit(1, 0, 1, 6, ''), + make_edit(0, 18, 5, 0, '') + } + exec_lua('vim.lsp.util.apply_text_edits(...)', edits, 1) + eq({ + 'First line of text'; + }, buf_lines(1)) + eq({ 1, 6 }, funcs.nvim_win_get_cursor(0)) + end) + it('fix the cursor row', function() funcs.nvim_win_set_cursor(0, { 3, 0 }) local edits = { @@ -2381,4 +2531,57 @@ describe('LSP', function() ) end) end) + describe('vim.lsp.codelens', function() + it('uses client commands', function() + local client + local expected_handlers = { + {NIL, {}, {method="shutdown", client_id=1}}; + {NIL, {}, {method="start", client_id=1}}; + } + test_rpc_server { + test_name = 'clientside_commands', + on_init = function(client_) + client = client_ + end, + on_setup = function() + end, + on_exit = function(code, signal) + eq(0, code, "exit code", fake_lsp_logfile) + eq(0, signal, "exit signal", fake_lsp_logfile) + end, + on_handler = function(err, result, ctx) + eq(table.remove(expected_handlers), {err, result, ctx}) + if ctx.method == 'start' then + local fake_uri = "file:///fake/uri" + local cmd = exec_lua([[ + fake_uri = ... + local bufnr = vim.uri_to_bufnr(fake_uri) + vim.fn.bufload(bufnr) + vim.api.nvim_buf_set_lines(bufnr, 0, -1, false, {'One line'}) + local lenses = { + { + range = { + start = { line = 0, character = 0, }, + ['end'] = { line = 0, character = 8 } + }, + command = { title = 'Lens1', command = 'Dummy' } + }, + } + vim.lsp.codelens.on_codelens(nil, lenses, {method='textDocument/codeLens', client_id=1, bufnr=bufnr}) + local cmd_called = nil + vim.lsp.commands['Dummy'] = function(command) + cmd_called = command + end + vim.api.nvim_set_current_buf(bufnr) + vim.lsp.codelens.run() + return cmd_called + ]], fake_uri) + eq({ command = 'Dummy', title = 'Lens1' }, cmd) + elseif ctx.method == 'shutdown' then + client.stop() + end + end + } + end) + end) end) |