aboutsummaryrefslogtreecommitdiff
path: root/test/functional/plugin/lsp/helpers.lua
diff options
context:
space:
mode:
Diffstat (limited to 'test/functional/plugin/lsp/helpers.lua')
-rw-r--r--test/functional/plugin/lsp/helpers.lua176
1 files changed, 176 insertions, 0 deletions
diff --git a/test/functional/plugin/lsp/helpers.lua b/test/functional/plugin/lsp/helpers.lua
new file mode 100644
index 0000000000..028ccb9e2c
--- /dev/null
+++ b/test/functional/plugin/lsp/helpers.lua
@@ -0,0 +1,176 @@
+local helpers = require('test.functional.helpers')(nil)
+
+local clear = helpers.clear
+local exec_lua = helpers.exec_lua
+local run = helpers.run
+local stop = helpers.stop
+local NIL = helpers.NIL
+
+local M = {}
+
+function M.clear_notrace()
+ -- problem: here be dragons
+ -- solution: don't look too closely for dragons
+ clear {env={
+ NVIM_LUA_NOTRACK="1";
+ VIMRUNTIME=os.getenv"VIMRUNTIME";
+ }}
+end
+
+M.create_server_definition = [[
+ function _create_server(opts)
+ opts = opts or {}
+ local server = {}
+ server.messages = {}
+
+ function server.cmd(dispatchers)
+ local closing = false
+ local handlers = opts.handlers or {}
+ local srv = {}
+
+ function srv.request(method, params, callback)
+ table.insert(server.messages, {
+ method = method,
+ params = params,
+ })
+ local handler = handlers[method]
+ if handler then
+ local response, err = handler(method, params)
+ callback(err, response)
+ elseif method == 'initialize' then
+ callback(nil, {
+ capabilities = opts.capabilities or {}
+ })
+ elseif method == 'shutdown' then
+ callback(nil, nil)
+ end
+ local request_id = #server.messages
+ return true, request_id
+ end
+
+ function srv.notify(method, params)
+ table.insert(server.messages, {
+ method = method,
+ params = params
+ })
+ if method == 'exit' then
+ dispatchers.on_exit(0, 15)
+ end
+ end
+
+ function srv.is_closing()
+ return closing
+ end
+
+ function srv.terminate()
+ closing = true
+ end
+
+ return srv
+ end
+
+ return server
+ end
+]]
+
+-- Fake LSP server.
+M.fake_lsp_code = 'test/functional/fixtures/fake-lsp-server.lua'
+M.fake_lsp_logfile = 'Xtest-fake-lsp.log'
+
+local function fake_lsp_server_setup(test_name, timeout_ms, options, settings)
+ exec_lua([=[
+ lsp = require('vim.lsp')
+ local test_name, fixture_filename, logfile, timeout, options, settings = ...
+ TEST_RPC_CLIENT_ID = lsp.start_client {
+ cmd_env = {
+ NVIM_LOG_FILE = logfile;
+ NVIM_LUA_NOTRACK = "1";
+ };
+ cmd = {
+ vim.v.progpath, '-Es', '-u', 'NONE', '--headless',
+ "-c", string.format("lua TEST_NAME = %q", test_name),
+ "-c", string.format("lua TIMEOUT = %d", timeout),
+ "-c", "luafile "..fixture_filename,
+ };
+ handlers = setmetatable({}, {
+ __index = function(t, method)
+ return function(...)
+ return vim.rpcrequest(1, 'handler', ...)
+ end
+ end;
+ });
+ workspace_folders = {{
+ uri = 'file://' .. vim.loop.cwd(),
+ name = 'test_folder',
+ }};
+ on_init = function(client, result)
+ TEST_RPC_CLIENT = client
+ vim.rpcrequest(1, "init", result)
+ end;
+ flags = {
+ allow_incremental_sync = options.allow_incremental_sync or false;
+ debounce_text_changes = options.debounce_text_changes or 0;
+ };
+ settings = settings;
+ on_exit = function(...)
+ vim.rpcnotify(1, "exit", ...)
+ end;
+ }
+ ]=], test_name, M.fake_lsp_code, M.fake_lsp_logfile, timeout_ms or 1e3, options or {}, settings or {})
+end
+
+function M.test_rpc_server(config)
+ if config.test_name then
+ M.clear_notrace()
+ fake_lsp_server_setup(config.test_name, config.timeout_ms or 1e3, config.options, config.settings)
+ end
+ local client = setmetatable({}, {
+ __index = function(_, name)
+ -- Workaround for not being able to yield() inside __index for Lua 5.1 :(
+ -- Otherwise I would just return the value here.
+ return function(...)
+ return exec_lua([=[
+ local name = ...
+ if type(TEST_RPC_CLIENT[name]) == 'function' then
+ return TEST_RPC_CLIENT[name](select(2, ...))
+ else
+ return TEST_RPC_CLIENT[name]
+ end
+ ]=], name, ...)
+ end
+ end;
+ })
+ local code, signal
+ local function on_request(method, args)
+ if method == "init" then
+ if config.on_init then
+ config.on_init(client, unpack(args))
+ end
+ return NIL
+ end
+ if method == 'handler' then
+ if config.on_handler then
+ config.on_handler(unpack(args))
+ end
+ end
+ return NIL
+ end
+ local function on_notify(method, args)
+ if method == 'exit' then
+ code, signal = unpack(args)
+ return stop()
+ end
+ end
+ -- TODO specify timeout?
+ -- run(on_request, on_notify, config.on_setup, 1000)
+ run(on_request, on_notify, config.on_setup)
+ if config.on_exit then
+ config.on_exit(code, signal)
+ end
+ stop()
+ if config.test_name then
+ exec_lua("vim.api.nvim_exec_autocmds('VimLeavePre', { modeline = false })")
+ end
+end
+
+return M