diff options
| author | Josh Rahm <joshuarahm@gmail.com> | 2023-11-29 22:40:31 +0000 |
|---|---|---|
| committer | Josh Rahm <joshuarahm@gmail.com> | 2023-11-29 22:40:31 +0000 |
| commit | 339e2d15cc26fe86988ea06468d912a46c8d6f29 (patch) | |
| tree | a6167fc8fcfc6ae2dc102f57b2473858eac34063 /test/functional/plugin | |
| parent | 067dc73729267c0262438a6fdd66e586f8496946 (diff) | |
| parent | 4a8bf24ac690004aedf5540fa440e788459e5e34 (diff) | |
| download | rneovim-339e2d15cc26fe86988ea06468d912a46c8d6f29.tar.gz rneovim-339e2d15cc26fe86988ea06468d912a46c8d6f29.tar.bz2 rneovim-339e2d15cc26fe86988ea06468d912a46c8d6f29.zip | |
Merge remote-tracking branch 'upstream/master' into fix_repeatcmdline
Diffstat (limited to 'test/functional/plugin')
| -rw-r--r-- | test/functional/plugin/editorconfig_spec.lua | 19 | ||||
| -rw-r--r-- | test/functional/plugin/health_spec.lua | 131 | ||||
| -rw-r--r-- | test/functional/plugin/lsp/completion_spec.lua | 239 | ||||
| -rw-r--r-- | test/functional/plugin/lsp/diagnostic_spec.lua | 159 | ||||
| -rw-r--r-- | test/functional/plugin/lsp/helpers.lua | 13 | ||||
| -rw-r--r-- | test/functional/plugin/lsp/incremental_sync_spec.lua | 2 | ||||
| -rw-r--r-- | test/functional/plugin/lsp/inlay_hint_spec.lua | 204 | ||||
| -rw-r--r-- | test/functional/plugin/lsp/semantic_tokens_spec.lua | 450 | ||||
| -rw-r--r-- | test/functional/plugin/lsp/snippet_spec.lua | 261 | ||||
| -rw-r--r-- | test/functional/plugin/lsp/utils_spec.lua | 226 | ||||
| -rw-r--r-- | test/functional/plugin/lsp/watchfiles_spec.lua | 222 | ||||
| -rw-r--r-- | test/functional/plugin/lsp_spec.lua | 1206 | ||||
| -rw-r--r-- | test/functional/plugin/man_spec.lua | 60 | ||||
| -rw-r--r-- | test/functional/plugin/shada_spec.lua | 34 | ||||
| -rw-r--r-- | test/functional/plugin/tutor_spec.lua | 95 |
15 files changed, 2813 insertions, 508 deletions
diff --git a/test/functional/plugin/editorconfig_spec.lua b/test/functional/plugin/editorconfig_spec.lua index e6a2550aba..ac78003a8c 100644 --- a/test/functional/plugin/editorconfig_spec.lua +++ b/test/functional/plugin/editorconfig_spec.lua @@ -3,9 +3,9 @@ local clear = helpers.clear local command = helpers.command local eq = helpers.eq local pathsep = helpers.get_pathsep() -local curbufmeths = helpers.curbufmeths local funcs = helpers.funcs local meths = helpers.meths +local exec_lua = helpers.exec_lua local testdir = 'Xtest-editorconfig' @@ -13,7 +13,7 @@ local function test_case(name, expected) local filename = testdir .. pathsep .. name command('edit ' .. filename) for opt, val in pairs(expected) do - eq(val, curbufmeths.get_option(opt), name) + eq(val, meths.get_option_value(opt, {buf=0}), name) end end @@ -160,8 +160,8 @@ describe('editorconfig', function() end) it('sets newline options', function() - test_case('with_newline.txt', { fixendofline = true, endofline = true }) - test_case('without_newline.txt', { fixendofline = false, endofline = false }) + test_case('with_newline.txt', { fixendofline = true }) + test_case('without_newline.txt', { fixendofline = false }) end) it('respects trim_trailing_whitespace', function() @@ -207,4 +207,15 @@ But not this one test_case('3_space.txt', { shiftwidth = 42 }) test_case('4_space.py', { shiftwidth = 4 }) end) + + it('does not operate on invalid buffers', function() + local ok, err = unpack(exec_lua([[ + vim.cmd.edit('test.txt') + local bufnr = vim.api.nvim_get_current_buf() + vim.cmd.bwipeout(bufnr) + return {pcall(require('editorconfig').config, bufnr)} + ]])) + + eq(true, ok, err) + end) end) diff --git a/test/functional/plugin/health_spec.lua b/test/functional/plugin/health_spec.lua index 97d32313e5..50b1d03f36 100644 --- a/test/functional/plugin/health_spec.lua +++ b/test/functional/plugin/health_spec.lua @@ -1,5 +1,4 @@ local helpers = require('test.functional.helpers')(after_each) -local global_helpers = require('test.helpers') local Screen = require('test.functional.ui.screen') local clear = helpers.clear @@ -43,20 +42,17 @@ end) describe('health.vim', function() before_each(function() clear{args={'-u', 'NORC'}} - -- Provides functions: - -- health#broken#check() - -- health#success1#check() - -- health#success2#check() + -- Provides healthcheck functions command("set runtimepath+=test/functional/fixtures") end) describe(":checkhealth", function() - it("functions health#report_*() render correctly", function() + it("functions report_*() render correctly", function() command("checkhealth full_render") helpers.expect([[ ============================================================================== - full_render: health#full_render#check + test_plug.full_render: require("test_plug.full_render.health").check() report 1 ~ - OK life is fine @@ -79,7 +75,7 @@ describe('health.vim', function() helpers.expect([[ ============================================================================== - success1: health#success1#check + test_plug: require("test_plug.health").check() report 1 ~ - OK everything is fine @@ -88,36 +84,19 @@ describe('health.vim', function() - OK nothing to see here ============================================================================== - success2: health#success2#check - - another 1 ~ - - OK ok - - ============================================================================== - test_plug: require("test_plug.health").check() + test_plug.success1: require("test_plug.success1.health").check() report 1 ~ - OK everything is fine report 2 ~ - OK nothing to see here - ]]) - end) - - it("lua plugins, skips vimscript healthchecks with the same name", function() - command("checkhealth test_plug") - -- Existing file in test/functional/fixtures/lua/test_plug/autoload/health/test_plug.vim - -- and the Lua healthcheck is used instead. - helpers.expect([[ ============================================================================== - test_plug: require("test_plug.health").check() - - report 1 ~ - - OK everything is fine + test_plug.success2: require("test_plug.success2.health").check() - report 2 ~ - - OK nothing to see here + another 1 ~ + - OK ok ]]) end) @@ -136,57 +115,6 @@ describe('health.vim', function() ]]) end) - it("lua plugins submodules with expression '*'", function() - command("checkhealth test_plug*") - local buf_lines = helpers.curbuf('get_lines', 0, -1, true) - -- avoid dealing with path separators - local received = table.concat(buf_lines, '\n', 1, #buf_lines - 5) - local expected = helpers.dedent([[ - - ============================================================================== - test_plug: require("test_plug.health").check() - - report 1 ~ - - OK everything is fine - - report 2 ~ - - OK nothing to see here - - ============================================================================== - test_plug.submodule: require("test_plug.submodule.health").check() - - report 1 ~ - - OK everything is fine - - report 2 ~ - - OK nothing to see here - - ============================================================================== - test_plug.submodule_empty: require("test_plug.submodule_empty.health").check() - - - ERROR The healthcheck report for "test_plug.submodule_empty" plugin is empty. - - ============================================================================== - test_plug.submodule_failed: require("test_plug.submodule_failed.health").check() - - - ERROR Failed to run healthcheck for "test_plug.submodule_failed" plugin. Exception: - function health#check, line 25]]) - eq(expected, received) - end) - - it("gracefully handles broken healthcheck", function() - command("checkhealth broken") - helpers.expect([[ - - ============================================================================== - broken: health#broken#check - - - ERROR Failed to run healthcheck for "broken" plugin. Exception: - function health#check[25]..health#broken#check, line 1 - caused an error - ]]) - end) - it("... including empty reports", function() command("checkhealth test_plug.submodule_empty") helpers.expect([[ @@ -198,36 +126,17 @@ describe('health.vim', function() ]]) end) - it("gracefully handles broken lua healthcheck", function() - command("checkhealth test_plug.submodule_failed") - local buf_lines = helpers.curbuf('get_lines', 0, -1, true) - local received = table.concat(buf_lines, '\n', 1, #buf_lines - 5) - -- avoid dealing with path separators - local lua_err = "attempt to perform arithmetic on a nil value" - local last_line = buf_lines[#buf_lines - 4] - assert(string.find(last_line, lua_err) ~= nil, "Lua error not present") - - local expected = global_helpers.dedent([[ - - ============================================================================== - test_plug.submodule_failed: require("test_plug.submodule_failed.health").check() - - - ERROR Failed to run healthcheck for "test_plug.submodule_failed" plugin. Exception: - function health#check, line 25]]) - eq(expected, received) - end) - it("highlights OK, ERROR", function() local screen = Screen.new(50, 12) screen:attach() screen:set_default_attr_ids({ - Ok = { foreground = Screen.colors.Grey3, background = 6291200 }, - Error = { foreground = Screen.colors.Grey100, background = Screen.colors.Red }, + Ok = { foreground = Screen.colors.LightGreen }, + Error = { foreground = Screen.colors.Red }, Heading = { foreground = tonumber('0x6a0dad') }, Bar = { foreground = Screen.colors.LightGrey, background = Screen.colors.DarkGrey }, }) command("checkhealth foo success1") - command("set nowrap laststatus=0") + command("set nofoldenable nowrap laststatus=0") screen:expect{grid=[[ ^ | {Bar:──────────────────────────────────────────────────}| @@ -236,7 +145,7 @@ describe('health.vim', function() - {Error:ERROR} No healthcheck found for "foo" plugin. | | {Bar:──────────────────────────────────────────────────}| - {Heading:success1: health#success1#check} | + {Heading:test_plug.success1: require("test_plug.success1.he}| | {Heading:report 1} | - {Ok:OK} everything is fine | @@ -244,6 +153,22 @@ describe('health.vim', function() ]]} end) + it("fold healthchecks", function() + local screen = Screen.new(50, 7) + screen:attach() + command("checkhealth foo success1") + command("set nowrap laststatus=0") + screen:expect{grid=[[ + ^ | + ──────────────────────────────────────────────────| + +WE 4 lines: foo: ·······························| + ──────────────────────────────────────────────────| + +-- 8 lines: test_plug.success1: require("test_pl| + ~ | + | + ]]} + end) + it("gracefully handles invalid healthcheck", function() command("checkhealth non_existent_healthcheck") -- luacheck: ignore 613 diff --git a/test/functional/plugin/lsp/completion_spec.lua b/test/functional/plugin/lsp/completion_spec.lua new file mode 100644 index 0000000000..9354654afe --- /dev/null +++ b/test/functional/plugin/lsp/completion_spec.lua @@ -0,0 +1,239 @@ +---@diagnostic disable: no-unknown +local helpers = require('test.functional.helpers')(after_each) +local eq = helpers.eq +local exec_lua = helpers.exec_lua + + +--- Convert completion results. +--- +---@param line string line contents. Mark cursor position with `|` +---@param candidates lsp.CompletionList|lsp.CompletionItem[] +---@param lnum? integer 0-based, defaults to 0 +---@return {items: table[], server_start_boundary: integer?} +local function complete(line, candidates, lnum) + lnum = lnum or 0 + -- nvim_win_get_cursor returns 0 based column, line:find returns 1 based + local cursor_col = line:find("|") - 1 + line = line:gsub("|", "") + return exec_lua([[ + local line, cursor_col, lnum, result = ... + local line_to_cursor = line:sub(1, cursor_col) + local client_start_boundary = vim.fn.match(line_to_cursor, '\\k*$') + local items, server_start_boundary = require("vim.lsp._completion")._convert_results( + line, + lnum, + cursor_col, + client_start_boundary, + nil, + result, + "utf-16" + ) + return { + items = items, + server_start_boundary = server_start_boundary + } + ]], line, cursor_col, lnum, candidates) +end + + +describe("vim.lsp._completion", function() + before_each(helpers.clear) + + -- https://microsoft.github.io/language-server-protocol/specifications/specification-current/#textDocument_completion + it('prefers textEdit over label as word', function() + local range0 = { + start = { line = 0, character = 0 }, + ["end"] = { line = 0, character = 0 }, + } + local completion_list = { + -- resolves into label + { label = 'foobar', sortText = 'a', documentation = 'documentation' }, + { + label = 'foobar', + sortText = 'b', + documentation = { value = 'documentation' }, + }, + -- resolves into insertText + { label = 'foocar', sortText = 'c', insertText = 'foobar' }, + { label = 'foocar', sortText = 'd', insertText = 'foobar' }, + -- resolves into textEdit.newText + { label = 'foocar', sortText = 'e', insertText = 'foodar', textEdit = { newText = 'foobar', range = range0 } }, + { label = 'foocar', sortText = 'f', textEdit = { newText = 'foobar', range = range0 } }, + -- real-world snippet text + { + label = 'foocar', + sortText = 'g', + insertText = 'foodar', + insertTextFormat = 2, + textEdit = { newText = 'foobar(${1:place holder}, ${2:more ...holder{\\}})', range = range0 }, + }, + { + label = 'foocar', + sortText = 'h', + insertText = 'foodar(${1:var1} typ1, ${2:var2} *typ2) {$0\\}', + insertTextFormat = 2, + }, + -- nested snippet tokens + { + label = 'foocar', + sortText = 'i', + insertText = 'foodar(${1:${2|typ1,typ2|}}) {$0\\}', + insertTextFormat = 2, + }, + -- braced tabstop + { label = 'foocar', sortText = 'j', insertText = 'foodar()${0}', insertTextFormat = 2}, + -- plain text + { + label = 'foocar', + sortText = 'k', + insertText = 'foodar(${1:var1})', + insertTextFormat = 1, + }, + } + local expected = { + { + abbr = 'foobar', + word = 'foobar', + }, + { + abbr = 'foobar', + word = 'foobar', + }, + { + abbr = 'foocar', + word = 'foobar', + }, + { + abbr = 'foocar', + word = 'foobar', + }, + { + abbr = 'foocar', + word = 'foobar', + }, + { + abbr = 'foocar', + word = 'foobar', + }, + { + abbr = 'foocar', + word = 'foobar(place holder, more ...holder{})', + }, + { + abbr = 'foocar', + word = 'foodar(var1 typ1, var2 *typ2) {}', + }, + { + abbr = 'foocar', + word = 'foodar(typ1) {}', + }, + { + abbr = 'foocar', + word = 'foodar()', + }, + { + abbr = 'foocar', + word = 'foodar(${1:var1})', + }, + } + local result = complete('|', completion_list) + result = vim.tbl_map(function(x) + return { + abbr = x.abbr, + word = x.word + } + end, result.items) + eq(expected, result) + end) + it("uses correct start boundary", function() + local completion_list = { + isIncomplete = false, + items = { + { + filterText = "this_thread", + insertText = "this_thread", + insertTextFormat = 1, + kind = 9, + label = " this_thread", + score = 1.3205767869949, + sortText = "4056f757this_thread", + textEdit = { + newText = "this_thread", + range = { + start = { line = 0, character = 7 }, + ["end"] = { line = 0, character = 11 }, + }, + } + }, + } + } + local expected = { + abbr = ' this_thread', + dup = 1, + empty = 1, + icase = 1, + kind = 'Module', + menu = '', + word = 'this_thread', + } + local result = complete(" std::this|", completion_list) + eq(7, result.server_start_boundary) + local item = result.items[1] + item.user_data = nil + eq(expected, item) + end) + + it("should search from start boundary to cursor position", function() + local completion_list = { + isIncomplete = false, + items = { + { + filterText = "this_thread", + insertText = "this_thread", + insertTextFormat = 1, + kind = 9, + label = " this_thread", + score = 1.3205767869949, + sortText = "4056f757this_thread", + textEdit = { + newText = "this_thread", + range = { + start = { line = 0, character = 7 }, + ["end"] = { line = 0, character = 11 }, + }, + } + }, + { + filterText = "notthis_thread", + insertText = "notthis_thread", + insertTextFormat = 1, + kind = 9, + label = " notthis_thread", + score = 1.3205767869949, + sortText = "4056f757this_thread", + textEdit = { + newText = "notthis_thread", + range = { + start = { line = 0, character = 7 }, + ["end"] = { line = 0, character = 11 }, + }, + } + }, + } + } + local expected = { + abbr = ' this_thread', + dup = 1, + empty = 1, + icase = 1, + kind = 'Module', + menu = '', + word = 'this_thread', + } + local result = complete(" std::this|is", completion_list) + eq(1, #result.items) + local item = result.items[1] + item.user_data = nil + eq(expected, item) + end) +end) diff --git a/test/functional/plugin/lsp/diagnostic_spec.lua b/test/functional/plugin/lsp/diagnostic_spec.lua index f73ffc29b0..1da0222114 100644 --- a/test/functional/plugin/lsp/diagnostic_spec.lua +++ b/test/functional/plugin/lsp/diagnostic_spec.lua @@ -1,10 +1,13 @@ local helpers = require('test.functional.helpers')(after_each) +local lsp_helpers = require('test.functional.plugin.lsp.helpers') local clear = helpers.clear local exec_lua = helpers.exec_lua local eq = helpers.eq local neq = require('test.helpers').neq +local create_server_definition = lsp_helpers.create_server_definition + describe('vim.lsp.diagnostic', function() local fake_uri @@ -81,6 +84,7 @@ describe('vim.lsp.diagnostic', function() local lines = {"1st line of text", "2nd line of text", "wow", "cool", "more", "lines"} vim.fn.bufload(diagnostic_bufnr) vim.api.nvim_buf_set_lines(diagnostic_bufnr, 0, 1, false, lines) + vim.api.nvim_win_set_buf(0, diagnostic_bufnr) return diagnostic_bufnr ]], fake_uri) end) @@ -97,7 +101,6 @@ describe('vim.lsp.diagnostic', function() } diagnostics[1].code = 42 - diagnostics[1].tags = {"foo", "bar"} diagnostics[1].data = "Hello world" vim.lsp.diagnostic.on_publish_diagnostics(nil, { @@ -110,10 +113,9 @@ describe('vim.lsp.diagnostic', function() vim.lsp.diagnostic.get_line_diagnostics(diagnostic_bufnr, 1)[1], } ]] - eq({code = 42, tags = {"foo", "bar"}, data = "Hello world"}, result[1].user_data.lsp) + eq({code = 42, data = "Hello world"}, result[1].user_data.lsp) eq(42, result[1].code) eq(42, result[2].code) - eq({"foo", "bar"}, result[2].tags) eq("Hello world", result[2].data) end) end) @@ -267,4 +269,155 @@ describe('vim.lsp.diagnostic', function() eq(exec_lua([[return #vim.diagnostic.get(...)]], bufnr), 0) end) end) + + describe('vim.lsp.diagnostic.on_diagnostic', function() + before_each(function() + exec_lua(create_server_definition) + exec_lua([[ + server = _create_server({ + capabilities = { + diagnosticProvider = { + } + } + }) + + function get_extmarks(bufnr, client_id) + local namespace = vim.lsp.diagnostic.get_namespace(client_id, true) + local ns = vim.diagnostic.get_namespace(namespace) + local extmarks = {} + if ns.user_data.virt_text_ns then + for _, e in pairs(vim.api.nvim_buf_get_extmarks(bufnr, ns.user_data.virt_text_ns, 0, -1, {details=true})) do + table.insert(extmarks, e) + end + end + if ns.user_data.underline_ns then + for _, e in pairs(vim.api.nvim_buf_get_extmarks(bufnr, ns.user_data.underline_ns, 0, -1, {details=true})) do + table.insert(extmarks, e) + end + end + return extmarks + end + + client_id = vim.lsp.start({ name = 'dummy', cmd = server.cmd }) + ]]) + end) + + it('adds diagnostics to vim.diagnostics', function() + local diags = exec_lua([[ + vim.lsp.diagnostic.on_diagnostic(nil, + { + kind = 'full', + items = { + make_error('Pull Diagnostic', 4, 4, 4, 4), + } + }, + { + params = { + textDocument = { uri = fake_uri }, + }, + uri = fake_uri, + client_id = client_id, + }, + {} + ) + + return vim.diagnostic.get(diagnostic_bufnr) + ]]) + eq(1, #diags) + eq('Pull Diagnostic', diags[1].message) + end) + + it('allows configuring the virtual text via vim.lsp.with', function() + local expected_spacing = 10 + local extmarks = exec_lua( + [[ + Diagnostic = vim.lsp.with(vim.lsp.diagnostic.on_diagnostic, { + virtual_text = { + spacing = ..., + }, + }) + + Diagnostic(nil, + { + kind = 'full', + items = { + make_error('Pull Diagnostic', 4, 4, 4, 4), + } + }, + { + params = { + textDocument = { uri = fake_uri }, + }, + uri = fake_uri, + client_id = client_id, + }, + {} + ) + + return get_extmarks(diagnostic_bufnr, client_id) + ]], + expected_spacing + ) + eq(2, #extmarks) + eq(expected_spacing, #extmarks[1][4].virt_text[1][1]) + end) + + it('clears diagnostics when client detaches', function() + exec_lua([[ + vim.lsp.diagnostic.on_diagnostic(nil, + { + kind = 'full', + items = { + make_error('Pull Diagnostic', 4, 4, 4, 4), + } + }, + { + params = { + textDocument = { uri = fake_uri }, + }, + uri = fake_uri, + client_id = client_id, + }, + {} + ) + ]]) + local diags = exec_lua([[return vim.diagnostic.get(diagnostic_bufnr)]]) + eq(1, #diags) + + exec_lua([[ vim.lsp.stop_client(client_id) ]]) + + diags = exec_lua([[return vim.diagnostic.get(diagnostic_bufnr)]]) + eq(0, #diags) + end) + + it('keeps diagnostics when one client detaches and others still are attached', function() + exec_lua([[ + client_id2 = vim.lsp.start({ name = 'dummy2', cmd = server.cmd }) + + vim.lsp.diagnostic.on_diagnostic(nil, + { + kind = 'full', + items = { + make_error('Pull Diagnostic', 4, 4, 4, 4), + } + }, + { + params = { + textDocument = { uri = fake_uri }, + }, + uri = fake_uri, + client_id = client_id, + }, + {} + ) + ]]) + local diags = exec_lua([[return vim.diagnostic.get(diagnostic_bufnr)]]) + eq(1, #diags) + + exec_lua([[ vim.lsp.stop_client(client_id2) ]]) + + diags = exec_lua([[return vim.diagnostic.get(diagnostic_bufnr)]]) + eq(1, #diags) + end) + end) end) diff --git a/test/functional/plugin/lsp/helpers.lua b/test/functional/plugin/lsp/helpers.lua index 028ccb9e2c..15e6a62781 100644 --- a/test/functional/plugin/lsp/helpers.lua +++ b/test/functional/plugin/lsp/helpers.lua @@ -13,6 +13,7 @@ function M.clear_notrace() -- solution: don't look too closely for dragons clear {env={ NVIM_LUA_NOTRACK="1"; + NVIM_APPNAME="nvim_lsp_test"; VIMRUNTIME=os.getenv"VIMRUNTIME"; }} end @@ -80,17 +81,15 @@ 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 = ... + local test_name, fake_lsp_code, fake_lsp_logfile, timeout, options, settings = ... TEST_RPC_CLIENT_ID = lsp.start_client { cmd_env = { - NVIM_LOG_FILE = logfile; + NVIM_LOG_FILE = fake_lsp_logfile; NVIM_LUA_NOTRACK = "1"; + NVIM_APPNAME = "nvim_lsp_test"; }; 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, + vim.v.progpath, '-l', fake_lsp_code, test_name, tostring(timeout), }; handlers = setmetatable({}, { __index = function(t, method) @@ -100,7 +99,7 @@ local function fake_lsp_server_setup(test_name, timeout_ms, options, settings) end; }); workspace_folders = {{ - uri = 'file://' .. vim.loop.cwd(), + uri = 'file://' .. vim.uv.cwd(), name = 'test_folder', }}; on_init = function(client, result) diff --git a/test/functional/plugin/lsp/incremental_sync_spec.lua b/test/functional/plugin/lsp/incremental_sync_spec.lua index 4985da9cd7..724b3efb97 100644 --- a/test/functional/plugin/lsp/incremental_sync_spec.lua +++ b/test/functional/plugin/lsp/incremental_sync_spec.lua @@ -21,7 +21,7 @@ before_each(function () -- ["mac"] = '\r', -- } - -- local line_ending = format_line_ending[vim.api.nvim_buf_get_option(0, 'fileformat')] + -- local line_ending = format_line_ending[vim.api.nvim_get_option_value('fileformat', {})] function test_register(bufnr, id, offset_encoding, line_ending) diff --git a/test/functional/plugin/lsp/inlay_hint_spec.lua b/test/functional/plugin/lsp/inlay_hint_spec.lua new file mode 100644 index 0000000000..d0d55df72b --- /dev/null +++ b/test/functional/plugin/lsp/inlay_hint_spec.lua @@ -0,0 +1,204 @@ +local helpers = require('test.functional.helpers')(after_each) +local lsp_helpers = require('test.functional.plugin.lsp.helpers') +local Screen = require('test.functional.ui.screen') + +local eq = helpers.eq +local dedent = helpers.dedent +local exec_lua = helpers.exec_lua +local insert = helpers.insert + +local clear_notrace = lsp_helpers.clear_notrace +local create_server_definition = lsp_helpers.create_server_definition + +local text = dedent([[ +auto add(int a, int b) { return a + b; } + +int main() { + int x = 1; + int y = 2; + return add(x,y); +} +}]]) + +local response = [==[ +[ +{"kind":1,"paddingLeft":false,"label":"-> int","position":{"character":22,"line":0},"paddingRight":false}, +{"kind":2,"paddingLeft":false,"label":"a:","position":{"character":15,"line":5},"paddingRight":true}, +{"kind":2,"paddingLeft":false,"label":"b:","position":{"character":17,"line":5},"paddingRight":true} +] +]==] + +local grid_without_inlay_hints = [[ + auto add(int a, int b) { return a + b; } | + | + int main() { | + int x = 1; | + int y = 2; | + return add(x,y); | + } | + ^} | + | +]] + +local grid_with_inlay_hints = [[ + auto add(int a, int b)-> int { return a + b; } | + | + int main() { | + int x = 1; | + int y = 2; | + return add(a: x,b: y); | + } | + ^} | + | +]] + +--- @type test.functional.ui.screen +local screen +before_each(function() + clear_notrace() + screen = Screen.new(50, 9) + screen:attach() + + exec_lua(create_server_definition) + exec_lua([[ + local response = ... + server = _create_server({ + capabilities = { + inlayHintProvider = true, + }, + handlers = { + ['textDocument/inlayHint'] = function() + return vim.json.decode(response) + end, + } + }) + + bufnr = vim.api.nvim_get_current_buf() + vim.api.nvim_win_set_buf(0, bufnr) + + client_id = vim.lsp.start({ name = 'dummy', cmd = server.cmd }) + ]], response) + + insert(text) + exec_lua([[vim.lsp.inlay_hint.enable(bufnr)]]) + screen:expect({ grid = grid_with_inlay_hints }) +end) + +after_each(function() + exec_lua("vim.api.nvim_exec_autocmds('VimLeavePre', { modeline = false })") +end) + +describe('vim.lsp.inlay_hint', function() + it('clears inlay hints when sole client detaches', function() + exec_lua([[vim.lsp.stop_client(client_id)]]) + screen:expect({ grid = grid_without_inlay_hints, unchanged = true }) + end) + + it('does not clear inlay hints when one of several clients detaches', function() + exec_lua([[ + server2 = _create_server({ + capabilities = { + inlayHintProvider = true, + }, + handlers = { + ['textDocument/inlayHint'] = function() + return {} + end, + } + }) + client2 = vim.lsp.start({ name = 'dummy2', cmd = server2.cmd }) + vim.lsp.inlay_hint.enable(bufnr) + ]]) + + exec_lua([[ vim.lsp.stop_client(client2) ]]) + screen:ex |