aboutsummaryrefslogtreecommitdiff
path: root/test/functional/plugin
diff options
context:
space:
mode:
authorJosh Rahm <joshuarahm@gmail.com>2023-11-30 20:35:25 +0000
committerJosh Rahm <joshuarahm@gmail.com>2023-11-30 20:35:25 +0000
commit1b7b916b7631ddf73c38e3a0070d64e4636cb2f3 (patch)
treecd08258054db80bb9a11b1061bb091c70b76926a /test/functional/plugin
parenteaa89c11d0f8aefbb512de769c6c82f61a8baca3 (diff)
parent4a8bf24ac690004aedf5540fa440e788459e5e34 (diff)
downloadrneovim-aucmd_textputpost.tar.gz
rneovim-aucmd_textputpost.tar.bz2
rneovim-aucmd_textputpost.zip
Merge remote-tracking branch 'upstream/master' into aucmd_textputpostaucmd_textputpost
Diffstat (limited to 'test/functional/plugin')
-rw-r--r--test/functional/plugin/editorconfig_spec.lua19
-rw-r--r--test/functional/plugin/health_spec.lua131
-rw-r--r--test/functional/plugin/lsp/completion_spec.lua239
-rw-r--r--test/functional/plugin/lsp/diagnostic_spec.lua159
-rw-r--r--test/functional/plugin/lsp/helpers.lua4
-rw-r--r--test/functional/plugin/lsp/incremental_sync_spec.lua2
-rw-r--r--test/functional/plugin/lsp/inlay_hint_spec.lua204
-rw-r--r--test/functional/plugin/lsp/semantic_tokens_spec.lua450
-rw-r--r--test/functional/plugin/lsp/snippet_spec.lua261
-rw-r--r--test/functional/plugin/lsp/utils_spec.lua226
-rw-r--r--test/functional/plugin/lsp/watchfiles_spec.lua222
-rw-r--r--test/functional/plugin/lsp_spec.lua1198
-rw-r--r--test/functional/plugin/man_spec.lua54
-rw-r--r--test/functional/plugin/shada_spec.lua34
-rw-r--r--test/functional/plugin/tutor_spec.lua95
15 files changed, 2804 insertions, 494 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 caab174b4d..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
@@ -85,6 +86,7 @@ local function fake_lsp_server_setup(test_name, timeout_ms, options, settings)
cmd_env = {
NVIM_LOG_FILE = fake_lsp_logfile;
NVIM_LUA_NOTRACK = "1";
+ NVIM_APPNAME = "nvim_lsp_test";
};
cmd = {
vim.v.progpath, '-l', fake_lsp_code, test_name, tostring(timeout),
@@ -97,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:expect({ grid = grid_with_inlay_hints, unchanged = true })
+ end)
+
+ describe('enable()', function()
+ it('clears/applies inlay hints when passed false/true/nil', function()
+ exec_lua([[vim.lsp.inlay_hint.enable(bufnr, false)]])
+ screen:expect({ grid = grid_without_inlay_hints, unchanged = true })
+
+ exec_lua([[vim.lsp.inlay_hint.enable(bufnr, true)]])
+ screen:expect({ grid = grid_with_inlay_hints, unchanged = true })
+
+ exec_lua([[vim.lsp.inlay_hint.enable(bufnr, not vim.lsp.inlay_hint.is_enabled(bufnr))]])
+ screen:expect({ grid = grid_without_inlay_hints, unchanged = true })
+
+ exec_lua([[vim.lsp.inlay_hint.enable(bufnr)]])
+ screen:expect({ grid = grid_with_inlay_hints, unchanged = true })
+ end)
+ end)
+
+ describe('get()', function()
+ it('returns filtered inlay hints', function()
+ --- @type lsp.InlayHint[]