diff options
Diffstat (limited to 'test/functional/plugin/lsp')
-rw-r--r-- | test/functional/plugin/lsp/codelens_spec.lua | 43 | ||||
-rw-r--r-- | test/functional/plugin/lsp/completion_spec.lua | 118 | ||||
-rw-r--r-- | test/functional/plugin/lsp/diagnostic_spec.lua | 61 | ||||
-rw-r--r-- | test/functional/plugin/lsp/handler_spec.lua | 19 | ||||
-rw-r--r-- | test/functional/plugin/lsp/helpers.lua | 45 | ||||
-rw-r--r-- | test/functional/plugin/lsp/incremental_sync_spec.lua | 430 | ||||
-rw-r--r-- | test/functional/plugin/lsp/inlay_hint_spec.lua | 16 | ||||
-rw-r--r-- | test/functional/plugin/lsp/semantic_tokens_spec.lua | 426 | ||||
-rw-r--r-- | test/functional/plugin/lsp/utils_spec.lua | 117 | ||||
-rw-r--r-- | test/functional/plugin/lsp/watchfiles_spec.lua | 222 |
10 files changed, 683 insertions, 814 deletions
diff --git a/test/functional/plugin/lsp/codelens_spec.lua b/test/functional/plugin/lsp/codelens_spec.lua index 3d7a15a191..29daf7a066 100644 --- a/test/functional/plugin/lsp/codelens_spec.lua +++ b/test/functional/plugin/lsp/codelens_spec.lua @@ -11,17 +11,21 @@ describe('vim.lsp.codelens', function() after_each(helpers.clear) it('on_codelens_stores_and_displays_lenses', function() - local fake_uri = "file:///fake/uri" - local bufnr = exec_lua([[ + local fake_uri = 'file:///fake/uri' + local bufnr = exec_lua( + [[ fake_uri = ... local bufnr = vim.uri_to_bufnr(fake_uri) local lines = {'So', 'many', 'lines'} vim.fn.bufload(bufnr) vim.api.nvim_buf_set_lines(bufnr, 0, -1, false, lines) return bufnr - ]], fake_uri) + ]], + fake_uri + ) - exec_lua([[ + exec_lua( + [[ local bufnr = ... local lenses = { { @@ -33,14 +37,16 @@ describe('vim.lsp.codelens', function() }, } vim.lsp.codelens.on_codelens(nil, lenses, {method='textDocument/codeLens', client_id=1, bufnr=bufnr}) - ]], bufnr) + ]], + bufnr + ) local stored_lenses = exec_lua('return vim.lsp.codelens.get(...)', bufnr) local expected = { { range = { start = { line = 0, character = 0 }, - ['end'] = { line = 0, character = 0 } + ['end'] = { line = 0, character = 0 }, }, command = { title = 'Lens1', @@ -50,28 +56,35 @@ describe('vim.lsp.codelens', function() } eq(expected, stored_lenses) - local virtual_text_chunks = exec_lua([[ + local virtual_text_chunks = exec_lua( + [[ local bufnr = ... local ns = vim.lsp.codelens.__namespaces[1] local extmarks = vim.api.nvim_buf_get_extmarks(bufnr, ns, 0, -1, {}) return vim.api.nvim_buf_get_extmark_by_id(bufnr, ns, extmarks[1][1], { details = true })[3].virt_text - ]], bufnr) + ]], + bufnr + ) - eq({[1] = {'Lens1', 'LspCodeLens'}}, virtual_text_chunks) + eq({ [1] = { 'Lens1', 'LspCodeLens' } }, virtual_text_chunks) end) it('can clear all lens', function() - local fake_uri = "file:///fake/uri" - local bufnr = exec_lua([[ + local fake_uri = 'file:///fake/uri' + local bufnr = exec_lua( + [[ fake_uri = ... local bufnr = vim.uri_to_bufnr(fake_uri) local lines = {'So', 'many', 'lines'} vim.fn.bufload(bufnr) vim.api.nvim_buf_set_lines(bufnr, 0, -1, false, lines) return bufnr - ]], fake_uri) + ]], + fake_uri + ) - exec_lua([[ + exec_lua( + [[ local bufnr = ... local lenses = { { @@ -83,7 +96,9 @@ describe('vim.lsp.codelens', function() }, } vim.lsp.codelens.on_codelens(nil, lenses, {method='textDocument/codeLens', client_id=1, bufnr=bufnr}) - ]], bufnr) + ]], + bufnr + ) local stored_lenses = exec_lua('return vim.lsp.codelens.get(...)', bufnr) eq(1, #stored_lenses) diff --git a/test/functional/plugin/lsp/completion_spec.lua b/test/functional/plugin/lsp/completion_spec.lua index 9354654afe..655eb76be6 100644 --- a/test/functional/plugin/lsp/completion_spec.lua +++ b/test/functional/plugin/lsp/completion_spec.lua @@ -3,7 +3,6 @@ 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 `|` @@ -13,9 +12,10 @@ local exec_lua = helpers.exec_lua 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 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*$') @@ -32,18 +32,22 @@ local function complete(line, candidates, lnum) items = items, server_start_boundary = server_start_boundary } - ]], line, cursor_col, lnum, candidates) + ]], + line, + cursor_col, + lnum, + candidates + ) end - -describe("vim.lsp._completion", function() +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 }, + ['end'] = { line = 0, character = 0 }, } local completion_list = { -- resolves into label @@ -57,7 +61,12 @@ describe("vim.lsp._completion", function() { 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 = 'e', + insertText = 'foodar', + textEdit = { newText = 'foobar', range = range0 }, + }, { label = 'foocar', sortText = 'f', textEdit = { newText = 'foobar', range = range0 } }, -- real-world snippet text { @@ -65,7 +74,10 @@ describe("vim.lsp._completion", function() sortText = 'g', insertText = 'foodar', insertTextFormat = 2, - textEdit = { newText = 'foobar(${1:place holder}, ${2:more ...holder{\\}})', range = range0 }, + textEdit = { + newText = 'foobar(${1:place holder}, ${2:more ...holder{\\}})', + range = range0, + }, }, { label = 'foocar', @@ -81,7 +93,7 @@ describe("vim.lsp._completion", function() insertTextFormat = 2, }, -- braced tabstop - { label = 'foocar', sortText = 'j', insertText = 'foodar()${0}', insertTextFormat = 2}, + { label = 'foocar', sortText = 'j', insertText = 'foodar()${0}', insertTextFormat = 2 }, -- plain text { label = 'foocar', @@ -140,32 +152,32 @@ describe("vim.lsp._completion", function() result = vim.tbl_map(function(x) return { abbr = x.abbr, - word = x.word + word = x.word, } end, result.items) eq(expected, result) end) - it("uses correct start boundary", function() + it('uses correct start boundary', function() local completion_list = { isIncomplete = false, items = { { - filterText = "this_thread", - insertText = "this_thread", + filterText = 'this_thread', + insertText = 'this_thread', insertTextFormat = 1, kind = 9, - label = " this_thread", + label = ' this_thread', score = 1.3205767869949, - sortText = "4056f757this_thread", + sortText = '4056f757this_thread', textEdit = { - newText = "this_thread", + newText = 'this_thread', range = { start = { line = 0, character = 7 }, - ["end"] = { line = 0, character = 11 }, + ['end'] = { line = 0, character = 11 }, }, - } + }, }, - } + }, } local expected = { abbr = ' this_thread', @@ -176,50 +188,50 @@ describe("vim.lsp._completion", function() menu = '', word = 'this_thread', } - local result = complete(" std::this|", completion_list) + 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() + it('should search from start boundary to cursor position', function() local completion_list = { isIncomplete = false, items = { { - filterText = "this_thread", - insertText = "this_thread", + filterText = 'this_thread', + insertText = 'this_thread', insertTextFormat = 1, kind = 9, - label = " this_thread", + label = ' this_thread', score = 1.3205767869949, - sortText = "4056f757this_thread", + sortText = '4056f757this_thread', textEdit = { - newText = "this_thread", + newText = 'this_thread', range = { start = { line = 0, character = 7 }, - ["end"] = { line = 0, character = 11 }, + ['end'] = { line = 0, character = 11 }, }, - } + }, }, { - filterText = "notthis_thread", - insertText = "notthis_thread", + filterText = 'notthis_thread', + insertText = 'notthis_thread', insertTextFormat = 1, kind = 9, - label = " notthis_thread", + label = ' notthis_thread', score = 1.3205767869949, - sortText = "4056f757this_thread", + sortText = '4056f757this_thread', textEdit = { - newText = "notthis_thread", + newText = 'notthis_thread', range = { start = { line = 0, character = 7 }, - ["end"] = { line = 0, character = 11 }, + ['end'] = { line = 0, character = 11 }, }, - } + }, }, - } + }, } local expected = { abbr = ' this_thread', @@ -230,10 +242,38 @@ describe("vim.lsp._completion", function() menu = '', word = 'this_thread', } - local result = complete(" std::this|is", completion_list) + 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) + + it('uses defaults from itemDefaults', function() + --- @type lsp.CompletionList + local completion_list = { + isIncomplete = false, + itemDefaults = { + editRange = { + start = { line = 1, character = 1 }, + ['end'] = { line = 1, character = 4 }, + }, + insertTextFormat = 2, + data = 'foobar', + }, + items = { + { + label = 'hello', + data = 'item-property-has-priority', + textEditText = 'hello', + }, + }, + } + local result = complete('|', completion_list) + eq(1, #result.items) + local item = result.items[1].user_data.nvim.lsp.completion_item --- @type lsp.CompletionItem + eq(2, item.insertTextFormat) + eq('item-property-has-priority', item.data) + eq({ line = 1, character = 1 }, item.textEdit.range.start) + end) end) diff --git a/test/functional/plugin/lsp/diagnostic_spec.lua b/test/functional/plugin/lsp/diagnostic_spec.lua index 1da0222114..705c182df7 100644 --- a/test/functional/plugin/lsp/diagnostic_spec.lua +++ b/test/functional/plugin/lsp/diagnostic_spec.lua @@ -12,10 +12,10 @@ describe('vim.lsp.diagnostic', function() local fake_uri before_each(function() - clear {env={ - NVIM_LUA_NOTRACK="1"; - VIMRUNTIME=os.getenv"VIMRUNTIME"; - }} + clear { env = { + NVIM_LUA_NOTRACK = '1', + VIMRUNTIME = os.getenv 'VIMRUNTIME', + } } exec_lua [[ require('vim.lsp') @@ -76,9 +76,10 @@ describe('vim.lsp.diagnostic', function() } ]] - fake_uri = "file:///fake/uri" + fake_uri = 'file:///fake/uri' - exec_lua([[ + exec_lua( + [[ fake_uri = ... diagnostic_bufnr = vim.uri_to_bufnr(fake_uri) local lines = {"1st line of text", "2nd line of text", "wow", "cool", "more", "lines"} @@ -86,7 +87,9 @@ describe('vim.lsp.diagnostic', function() 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) + ]], + fake_uri + ) end) after_each(function() @@ -113,17 +116,18 @@ describe('vim.lsp.diagnostic', function() vim.lsp.diagnostic.get_line_diagnostics(diagnostic_bufnr, 1)[1], } ]] - eq({code = 42, 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("Hello world", result[2].data) + eq('Hello world', result[2].data) end) end) - describe("vim.lsp.diagnostic.on_publish_diagnostics", function() + describe('vim.lsp.diagnostic.on_publish_diagnostics', function() it('allows configuring the virtual text via vim.lsp.with', function() local expected_spacing = 10 - local extmarks = exec_lua([[ + local extmarks = exec_lua( + [[ PublishDiagnostics = vim.lsp.with(vim.lsp.diagnostic.on_publish_diagnostics, { virtual_text = { spacing = ..., @@ -139,7 +143,9 @@ describe('vim.lsp.diagnostic', function() ) return get_extmarks(diagnostic_bufnr, client_id) - ]], expected_spacing) + ]], + expected_spacing + ) local virt_text = extmarks[1][4].virt_text local spacing = virt_text[1][1] @@ -149,7 +155,8 @@ describe('vim.lsp.diagnostic', function() it('allows configuring the virtual text via vim.lsp.with using a function', function() local expected_spacing = 10 - local extmarks = exec_lua([[ + local extmarks = exec_lua( + [[ spacing = ... PublishDiagnostics = vim.lsp.with(vim.lsp.diagnostic.on_publish_diagnostics, { @@ -169,7 +176,9 @@ describe('vim.lsp.diagnostic', function() ) return get_extmarks(diagnostic_bufnr, client_id) - ]], expected_spacing) + ]], + expected_spacing + ) local virt_text = extmarks[1][4].virt_text local spacing = virt_text[1][1] @@ -179,11 +188,12 @@ describe('vim.lsp.diagnostic', function() it('allows filtering via severity limit', function() local get_extmark_count_with_severity = function(severity_limit) - return exec_lua([[ + return exec_lua( + [[ PublishDiagnostics = vim.lsp.with(vim.lsp.diagnostic.on_publish_diagnostics, { underline = false, virtual_text = { - severity_limit = ... + severity = { min = ... } }, }) @@ -196,20 +206,23 @@ describe('vim.lsp.diagnostic', function() ) return #get_extmarks(diagnostic_bufnr, client_id) - ]], severity_limit) + ]], + severity_limit + ) end -- No messages with Error or higher - eq(0, get_extmark_count_with_severity("Error")) + eq(0, get_extmark_count_with_severity('ERROR')) -- But now we don't filter it - eq(1, get_extmark_count_with_severity("Warning")) - eq(1, get_extmark_count_with_severity("Hint")) + eq(1, get_extmark_count_with_severity('WARN')) + eq(1, get_extmark_count_with_severity('HINT')) end) it('correctly handles UTF-16 offsets', function() - local line = "All 💼 and no 🎉 makes Jack a dull 👦" - local result = exec_lua([[ + local line = 'All 💼 and no 🎉 makes Jack a dull 👦' + local result = exec_lua( + [[ local line = ... vim.api.nvim_buf_set_lines(diagnostic_bufnr, 0, -1, false, {line}) @@ -225,7 +238,9 @@ describe('vim.lsp.diagnostic', function() vim.lsp.stop_client(client_id) vim.api.nvim_exec_autocmds('VimLeavePre', { modeline = false }) return diags - ]], line) + ]], + line + ) eq(1, #result) eq(exec_lua([[return vim.str_byteindex(..., 7, true)]], line), result[1].col) eq(exec_lua([[return vim.str_byteindex(..., 8, true)]], line), result[1].end_col) diff --git a/test/functional/plugin/lsp/handler_spec.lua b/test/functional/plugin/lsp/handler_spec.lua index 3086c23fe8..56e29e7337 100644 --- a/test/functional/plugin/lsp/handler_spec.lua +++ b/test/functional/plugin/lsp/handler_spec.lua @@ -8,21 +8,30 @@ local matches = helpers.matches describe('lsp-handlers', function() describe('vim.lsp._with_extend', function() it('should return a table with the default keys', function() - eq({hello = 'world' }, exec_lua [[ + eq( + { hello = 'world' }, + exec_lua [[ return vim.lsp._with_extend('test', { hello = 'world' }) - ]]) + ]] + ) end) it('should override with config keys', function() - eq({hello = 'universe', other = true}, exec_lua [[ + eq( + { hello = 'universe', other = true }, + exec_lua [[ return vim.lsp._with_extend('test', { other = true, hello = 'world' }, { hello = 'universe' }) - ]]) + ]] + ) end) it('should not allow invalid keys', function() matches( '.*Invalid option for `test`.*', - pcall_err(exec_lua, "return vim.lsp._with_extend('test', { hello = 'world' }, { invalid = true })") + pcall_err( + exec_lua, + "return vim.lsp._with_extend('test', { hello = 'world' }, { invalid = true })" + ) ) end) end) diff --git a/test/functional/plugin/lsp/helpers.lua b/test/functional/plugin/lsp/helpers.lua index 15e6a62781..97fa108500 100644 --- a/test/functional/plugin/lsp/helpers.lua +++ b/test/functional/plugin/lsp/helpers.lua @@ -4,18 +4,20 @@ local clear = helpers.clear local exec_lua = helpers.exec_lua local run = helpers.run local stop = helpers.stop -local NIL = helpers.NIL +local NIL = vim.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"; - NVIM_APPNAME="nvim_lsp_test"; - VIMRUNTIME=os.getenv"VIMRUNTIME"; - }} + clear { + env = { + NVIM_LUA_NOTRACK = '1', + NVIM_APPNAME = 'nvim_lsp_test', + VIMRUNTIME = os.getenv 'VIMRUNTIME', + }, + } end M.create_server_definition = [[ @@ -79,7 +81,8 @@ 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([=[ + exec_lua( + [=[ lsp = require('vim.lsp') local test_name, fake_lsp_code, fake_lsp_logfile, timeout, options, settings = ... TEST_RPC_CLIENT_ID = lsp.start_client { @@ -115,33 +118,49 @@ local function fake_lsp_server_setup(test_name, timeout_ms, options, settings) vim.rpcnotify(1, "exit", ...) end; } - ]=], test_name, M.fake_lsp_code, M.fake_lsp_logfile, timeout_ms or 1e3, options or {}, settings or {}) + ]=], + 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) + 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([=[ + 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, ...) + ]=], + name, + ... + ) end - end; + end, }) local code, signal local function on_request(method, args) - if method == "init" then + if method == 'init' then if config.on_init then config.on_init(client, unpack(args)) end diff --git a/test/functional/plugin/lsp/incremental_sync_spec.lua b/test/functional/plugin/lsp/incremental_sync_spec.lua index 724b3efb97..bd1842ceb5 100644 --- a/test/functional/plugin/lsp/incremental_sync_spec.lua +++ b/test/functional/plugin/lsp/incremental_sync_spec.lua @@ -1,13 +1,13 @@ -- Test suite for testing interactions with the incremental sync algorithms powering the LSP client local helpers = require('test.functional.helpers')(after_each) -local meths = helpers.meths +local api = helpers.api local clear = helpers.clear local eq = helpers.eq local exec_lua = helpers.exec_lua local feed = helpers.feed -before_each(function () +before_each(function() clear() exec_lua [[ local evname = ... @@ -52,19 +52,24 @@ before_each(function () ]] end) -local function test_edit(prev_buffer, edit_operations, expected_text_changes, offset_encoding, line_ending) +local function test_edit( + prev_buffer, + edit_operations, + expected_text_changes, + offset_encoding, + line_ending +) offset_encoding = offset_encoding or 'utf-16' line_ending = line_ending or '\n' - meths.buf_set_lines(0, 0, -1, true, prev_buffer) - exec_lua("return test_register(...)", 0, "test1", offset_encoding, line_ending) + api.nvim_buf_set_lines(0, 0, -1, true, prev_buffer) + exec_lua('return test_register(...)', 0, 'test1', offset_encoding, line_ending) for _, edit in ipairs(edit_operations) do feed(edit) end - eq(expected_text_changes, exec_lua("return get_events(...)" )) + eq(expected_text_changes, exec_lua('return get_events(...)')) exec_lua("test_unreg = 'test1'") - end describe('incremental synchronization', function() @@ -75,18 +80,18 @@ describe('incremental synchronization', function() range = { ['start'] = { character = 0, - line = 0 + line = 0, }, ['end'] = { character = 0, - line = 0 - } + line = 0, + }, }, rangeLength = 0, - text = 'a' - } + text = 'a', + }, } - test_edit({""}, {"ia"}, expected_text_changes, 'utf-16', '\n') + test_edit({ '' }, { 'ia' }, expected_text_changes, 'utf-16', '\n') end) it('inserting a character in the middle of a the first line', function() local expected_text_changes = { @@ -94,18 +99,18 @@ describe('incremental synchronization', function() range = { ['start'] = { character = 1, - line = 0 + line = 0, }, ['end'] = { character = 1, - line = 0 - } + line = 0, + }, }, rangeLength = 0, - text = 'a' - } + text = 'a', + }, } - test_edit({"ab"}, {"lia"}, expected_text_changes, 'utf-16', '\n') + test_edit({ 'ab' }, { 'lia' }, expected_text_changes, 'utf-16', '\n') end) it('deleting the only character in a buffer', function() local expected_text_changes = { @@ -113,18 +118,18 @@ describe('incremental synchronization', function() range = { ['start'] = { character = 0, - line = 0 + line = 0, }, ['end'] = { character = 1, - line = 0 - } + line = 0, + }, }, rangeLength = 1, - text = '' - } + text = '', + }, } - test_edit({"a"}, {"x"}, expected_text_changes, 'utf-16', '\n') + test_edit({ 'a' }, { 'x' }, expected_text_changes, 'utf-16', '\n') end) it('deleting a character in the middle of the line', function() local expected_text_changes = { @@ -132,18 +137,18 @@ describe('incremental synchronization', function() range = { ['start'] = { character = 1, - line = 0 + line = 0, }, ['end'] = { character = 2, - line = 0 - } + line = 0, + }, }, rangeLength = 1, - text = '' - } + text = '', + }, } - test_edit({"abc"}, {"lx"}, expected_text_changes, 'utf-16', '\n') + test_edit({ 'abc' }, { 'lx' }, expected_text_changes, 'utf-16', '\n') end) it('replacing a character', function() local expected_text_changes = { @@ -151,18 +156,18 @@ describe('incremental synchronization', function() range = { ['start'] = { character = 0, - line = 0 + line = 0, }, ['end'] = { character = 1, - line = 0 - } + line = 0, + }, }, rangeLength = 1, - text = 'b' - } + text = 'b', + }, } - test_edit({"a"}, {"rb"}, expected_text_changes, 'utf-16', '\n') + test_edit({ 'a' }, { 'rb' }, expected_text_changes, 'utf-16', '\n') end) it('deleting a line', function() local expected_text_changes = { @@ -170,18 +175,18 @@ describe('incremental synchronization', function() range = { ['start'] = { character = 0, - line = 0 + line = 0, }, ['end'] = { character = 0, - line = 1 - } + line = 1, + }, }, rangeLength = 12, - text = '' - } + text = '', + }, } - test_edit({"hello world"}, {"dd"}, expected_text_changes, 'utf-16', '\n') + test_edit({ 'hello world' }, { 'dd' }, expected_text_changes, 'utf-16', '\n') end) it('deleting an empty line', function() local expected_text_changes = { @@ -189,18 +194,18 @@ describe('incremental synchronization', function() range = { ['start'] = { character = 0, - line = 1 + line = 1, }, ['end'] = { character = 0, - line = 2 - } + line = 2, + }, }, rangeLength = 1, - text = '' - } + text = '', + }, } - test_edit({"hello world", ""}, {"jdd"}, expected_text_changes, 'utf-16', '\n') + test_edit({ 'hello world', '' }, { 'jdd' }, expected_text_changes, 'utf-16', '\n') end) it('adding a line', function() local expected_text_changes = { @@ -212,14 +217,14 @@ describe('incremental synchronization', function() }, ['end'] = { character = 0, - line = 1 - } + line = 1, + }, }, rangeLength = 1, - text = '\nhello world\n' - } + text = '\nhello world\n', + }, } - test_edit({"hello world"}, {"yyp"}, expected_text_changes, 'utf-16', '\n') + test_edit({ 'hello world' }, { 'yyp' }, expected_text_changes, 'utf-16', '\n') end) it('adding an empty line', function() local expected_text_changes = { @@ -227,18 +232,18 @@ describe('incremental synchronization', function() range = { ['start'] = { character = 11, - line = 0 + line = 0, }, ['end'] = { character = 0, - line = 1 - } + line = 1, + }, }, rangeLength = 1, - text = '\n\n' - } + text = '\n\n', + }, } - test_edit({"hello world"}, {"o"}, expected_text_changes, 'utf-16', '\n') + test_edit({ 'hello world' }, { 'o' }, expected_text_changes, 'utf-16', '\n') end) it('adding a line to an empty buffer', function() local expected_text_changes = { @@ -246,18 +251,18 @@ describe('incremental synchronization', function() range = { ['start'] = { character = 0, - line = 0 + line = 0, }, ['end'] = { character = 0, - line = 1 - } + line = 1, + }, }, rangeLength = 1, - text = '\n\n' - } + text = '\n\n', + }, } - test_edit({""}, {"o"}, expected_text_changes, 'utf-16', '\n') + test_edit({ '' }, { 'o' }, expected_text_changes, 'utf-16', '\n') end) it('insert a line above the current line', function() local expected_text_changes = { @@ -265,18 +270,18 @@ describe('incremental synchronization', function() range = { ['start'] = { character = 0, - line = 0 + line = 0, }, ['end'] = { character = 0, - line = 0 - } + line = 0, + }, }, rangeLength = 0, - text = '\n' - } + text = '\n', + }, } - test_edit({""}, {"O"}, expected_text_changes, 'utf-16', '\n') + test_edit({ '' }, { 'O' }, expected_text_changes, 'utf-16', '\n') end) end) describe('multi line edit', function() @@ -287,115 +292,115 @@ describe('incremental synchronization', function() range = { ['start'] = { character = 4, - line = 1 + line = 1, }, ['end'] = { character = 9, - line = 1 - } + line = 1, + }, }, rangeLength = 5, - text = '' + text = '', }, -- delete "hello world\n" from line 2 { range = { ['start'] = { character = 0, - line = 2 + line = 2, }, ['end'] = { character = 0, - line = 3 - } + line = 3, + }, }, rangeLength = 12, - text = '' + text = '', }, -- delete "1234" from beginning of line 2 { range = { ['start'] = { character = 0, - line = 2 + line = 2, }, ['end'] = { character = 4, - line = 2 - } + line = 2, + }, }, rangeLength = 4, - text = '' + text = '', }, -- add " asdf" to end of line 1 { range = { ['start'] = { character = 4, - line = 1 + line = 1, }, ['end'] = { character = 4, - line = 1 - } + line = 1, + }, }, rangeLength = 0, - text = ' asdf' + text = ' asdf', }, -- delete " asdf\n" from line 2 { range = { ['start'] = { character = 0, - line = 2 + line = 2, }, ['end'] = { character = 0, - line = 3 - } + line = 3, + }, }, rangeLength = 6, - text = '' + text = '', }, -- undo entire deletion { range = { ['start'] = { character = 4, - line = 1 + line = 1, }, ['end'] = { character = 9, - line = 1 - } + line = 1, + }, }, rangeLength = 5, - text = "_fdsa\nhello world\n1234 asdf" + text = '_fdsa\nhello world\n1234 asdf', }, -- redo entire deletion { range = { ['start'] = { character = 4, - line = 1 + line = 1, }, ['end'] = { character = 9, - line = 3 - } + line = 3, + }, }, rangeLength = 27, - text = ' asdf' + text = ' asdf', }, } local original_lines = { - "\\begin{document}", - "test_fdsa", - "hello world", - "1234 asdf", - "\\end{document}" + '\\begin{document}', + 'test_fdsa', + 'hello world', + '1234 asdf', + '\\end{document}', } - test_edit(original_lines, {"jf_vejjbhhdu<C-R>"}, expected_text_changes, 'utf-16', '\n') + test_edit(original_lines, { 'jf_vejjbhhdu<C-R>' }, expected_text_changes, 'utf-16', '\n') end) end) @@ -404,64 +409,83 @@ describe('incremental synchronization', function() local expected_text_changes = { { range = { - ["end"] = { - character = 11, - line = 2 }, - ["start"] = { - character = 10, - line = 2 } }, + ['end'] = { + character = 11, + line = 2, + }, + ['start'] = { + character = 10, + line = 2, + }, + }, rangeLength = 1, text = '', - },{ + }, + { range = { - ["end"] = { + ['end'] = { character = 10, - line = 2 }, + line = 2, + }, start = { character = 10, - line = 2 } }, + line = 2, + }, + }, rangeLength = 0, text = '2', - },{ + }, + { range = { - ["end"] = { + ['end'] = { character = 11, - line = 3 }, - ["start"] = { + line = 3, + }, + ['start'] = { character = 10, - line = 3 } }, + line = 3, + }, + }, rangeLength = 1, - text = '' - },{ + text = '', + }, + { range = { ['end'] = { character = 10, - line = 3 }, + line = 3, + }, ['start'] = { character = 10, - line = 3 } }, + line = 3, + }, + }, rangeLength = 0, - text = '3' }, + text = '3', + }, { range = { ['end'] = { character = 0, - line = 3 }, + line = 3, + }, ['start'] = { character = 12, - line = 2 } }, + line = 2, + }, + }, rangeLength = 1, - text = '\n' - } + text = '\n', + }, } local original_lines = { - "\\begin{document}", - "\\section*{1}", - "\\section*{1}", - "\\section*{1}", - "\\end{document}" + '\\begin{document}', + '\\section*{1}', + '\\section*{1}', + '\\section*{1}', + '\\end{document}', } - test_edit(original_lines, {"3gg$h<C-V>jg<C-A>"}, expected_text_changes, 'utf-16', '\n') + test_edit(original_lines, { '3gg$h<C-V>jg<C-A>' }, expected_text_changes, 'utf-16', '\n') end) it('join and undo', function() local expected_text_changes = { @@ -469,44 +493,46 @@ describe('incremental synchronization', function() range = { ['start'] = { character = 11, - line = 0 + line = 0, }, ['end'] = { character = 11, - line = 0 - } + line = 0, + }, }, rangeLength = 0, - text = ' test3' - },{ + text = ' test3', + }, + { range = { ['start'] = { character = 0, - line = 1 + line = 1, }, ['end'] = { character = 0, - line = 2 - } + line = 2, + }, }, rangeLength = 6, - text = '' - },{ + text = '', + }, + { range = { ['start'] = { character = 11, - line = 0 + line = 0, }, ['end'] = { character = 17, - line = 0 - } + line = 0, + }, }, rangeLength = 6, - text = '\ntest3' + text = '\ntest3', }, } - test_edit({"test1 test2", "test3"}, {"J", "u"}, expected_text_changes, 'utf-16', '\n') + test_edit({ 'test1 test2', 'test3' }, { 'J', 'u' }, expected_text_changes, 'utf-16', '\n') end) end) @@ -517,18 +543,18 @@ describe('incremental synchronization', function() range = { ['start'] = { character = 0, - line = 0 + line = 0, }, ['end'] = { character = 2, - line = 0 - } + line = 0, + }, }, rangeLength = 2, - text = '' - } + text = '', + }, } - test_edit({"🔥"}, {"x"}, expected_text_changes, 'utf-16', '\n') + test_edit({ '🔥' }, { 'x' }, expected_text_changes, 'utf-16', '\n') end) it('replacing a multibyte character with matching prefix', function() local expected_text_changes = { @@ -536,24 +562,24 @@ describe('incremental synchronization', function() range = { ['start'] = { character = 0, - line = 1 + line = 1, }, ['end'] = { character = 1, - line = 1 - } + line = 1, + }, }, rangeLength = 1, - text = '⟩' - } + text = '⟩', + }, } -- ⟨ is e29fa8, ⟩ is e29fa9 local original_lines = { - "\\begin{document}", - "⟨", - "\\end{document}", + '\\begin{document}', + '⟨', + '\\end{document}', } - test_edit(original_lines, {"jr⟩"}, expected_text_changes, 'utf-16', '\n') + test_edit(original_lines, { 'jr⟩' }, expected_text_changes, 'utf-16', '\n') end) it('replacing a multibyte character with matching suffix', function() local expected_text_changes = { @@ -561,24 +587,24 @@ describe('incremental synchronization', function() range = { ['start'] = { character = 0, - line = 1 + line = 1, }, ['end'] = { character = 1, - line = 1 - } + line = 1, + }, }, rangeLength = 1, - text = 'ḟ' - } + text = 'ḟ', + }, } -- ฟ is e0b89f, ḟ is e1b89f local original_lines = { - "\\begin{document}", - "ฟ", - "\\end{document}", + '\\begin{document}', + 'ฟ', + '\\end{document}', } - test_edit(original_lines, {"jrḟ"}, expected_text_changes, 'utf-16', '\n') + test_edit(original_lines, { 'jrḟ' }, expected_text_changes, 'utf-16', '\n') end) it('inserting before a multibyte character', function() local expected_text_changes = { @@ -586,23 +612,23 @@ describe('incremental synchronization', function() range = { ['start'] = { character = 0, - line = 1 + line = 1, }, ['end'] = { character = 0, - line = 1 - } + line = 1, + }, }, rangeLength = 0, - text = ' ' - } + text = ' ', + }, } local original_lines = { - "\\begin{document}", - "→", - "\\end{document}", + '\\begin{document}', + '→', + '\\end{document}', } - test_edit(original_lines, {"ji "}, expected_text_changes, 'utf-16', '\n') + test_edit(original_lines, { 'ji ' }, expected_text_changes, 'utf-16', '\n') end) it('deleting a multibyte character from a long line', function() local expected_text_changes = { @@ -610,23 +636,23 @@ describe('incremental synchronization', function() range = { ['start'] = { character = 85, - line = 1 + line = 1, }, ['end'] = { character = 86, - line = 1 - } + line = 1, + }, }, rangeLength = 1, - text = '' - } + text = '', + }, } local original_lines = { - "\\begin{document}", - "→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→", - "\\end{document}", + '\\begin{document}', + '→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→', + '\\end{document}', } - test_edit(original_lines, {"jx"}, expected_text_changes, 'utf-16', '\n') + test_edit(original_lines, { 'jx' }, expected_text_changes, 'utf-16', '\n') end) it('deleting multiple lines containing multibyte characters', function() local expected_text_changes = { @@ -634,19 +660,25 @@ describe('incremental synchronization', function() range = { ['start'] = { character = 0, - line = 1 + line = 1, }, ['end'] = { character = 0, - line = 3 - } + line = 3, + }, }, --utf 16 len of 🔥 is 2 rangeLength = 8, - text = '' - } + text = '', + }, } - test_edit({"a🔥", "b🔥", "c🔥", "d🔥"}, {"j2dd"}, expected_text_changes, 'utf-16', '\n') + test_edit( + { 'a🔥', 'b🔥', 'c🔥', 'd🔥' }, + { 'j2dd' }, + expected_text_changes, + 'utf-16', + '\n' + ) end) end) end) diff --git a/test/functional/plugin/lsp/inlay_hint_spec.lua b/test/functional/plugin/lsp/inlay_hint_spec.lua index d0d55df72b..192797b312 100644 --- a/test/functional/plugin/lsp/inlay_hint_spec.lua +++ b/test/functional/plugin/lsp/inlay_hint_spec.lua @@ -40,7 +40,7 @@ local grid_without_inlay_hints = [[ | ]] -local grid_with_inlay_hints = [[ +local grid_with_inlay_hints = [[ auto add(int a, int b)-> int { return a + b; } | | int main() { | @@ -60,7 +60,8 @@ before_each(function() screen:attach() exec_lua(create_server_definition) - exec_lua([[ + exec_lua( + [[ local response = ... server = _create_server({ capabilities = { @@ -77,7 +78,9 @@ before_each(function() vim.api.nvim_win_set_buf(0, bufnr) client_id = vim.lsp.start({ name = 'dummy', cmd = server.cmd }) - ]], response) + ]], + response + ) insert(text) exec_lua([[vim.lsp.inlay_hint.enable(bufnr)]]) @@ -145,7 +148,8 @@ describe('vim.lsp.inlay_hint', function() paddingRight = false, } - exec_lua([[ + exec_lua( + [[ local expected2 = ... server2 = _create_server({ capabilities = { @@ -159,7 +163,9 @@ describe('vim.lsp.inlay_hint', function() }) client2 = vim.lsp.start({ name = 'dummy2', cmd = server2.cmd }) vim.lsp.inlay_hint.enable(bufnr) - ]], expected2) + ]], + expected2 + ) --- @type vim.lsp.inlay_hint.get.ret local res = exec_lua([[return vim.lsp.inlay_hint.get()]]) diff --git a/test/functional/plugin/lsp/semantic_tokens_spec.lua b/test/functional/plugin/lsp/semantic_tokens_spec.lua index b7ac53f270..77e39c81c8 100644 --- a/test/functional/plugin/lsp/semantic_tokens_spec.lua +++ b/test/functional/plugin/lsp/semantic_tokens_spec.lua @@ -23,21 +23,20 @@ after_each(function() end) describe('semantic token highlighting', function() - local screen before_each(function() screen = Screen.new(40, 16) screen:attach() screen:set_default_attr_ids { - [1] = { bold = true, foreground = Screen.colors.Blue1 }; - [2] = { foreground = Screen.colors.DarkCyan }; - [3] = { foreground = Screen.colors.SlateBlue }; - [4] = { bold = true, foreground = Screen.colors.SeaGreen }; - [5] = { foreground = tonumber('0x6a0dad') }; - [6] = { foreground = Screen.colors.Blue1 }; - [7] = { bold = true, foreground = Screen.colors.DarkCyan }; - [8] = { bold = true, foreground = Screen.colors.SlateBlue }; - [9] = { bold = true, foreground = tonumber('0x6a0dad') }; + [1] = { bold = true, foreground = Screen.colors.Blue1 }, + [2] = { foreground = Screen.colors.DarkCyan }, + [3] = { foreground = Screen.colors.SlateBlue }, + [4] = { bold = true, foreground = Screen.colors.SeaGreen }, + [5] = { foreground = tonumber('0x6a0dad') }, + [6] = { foreground = Screen.colors.Blue1 }, + [7] = { bold = true, foreground = Screen.colors.DarkCyan }, + [8] = { bold = true, foreground = Screen.colors.SlateBlue }, + [9] = { bold = true, foreground = tonumber('0x6a0dad') }, } command([[ hi link @lsp.type.namespace Type ]]) command([[ hi link @lsp.type.function Special ]]) @@ -81,7 +80,8 @@ describe('semantic token highlighting', function() before_each(function() exec_lua(create_server_definition) - exec_lua([[ + exec_lua( + [[ local legend, response, edit_response = ... server = _create_server({ capabilities = { @@ -99,7 +99,11 @@ describe('semantic token highlighting', function() end, } }) - ]], legend, response, edit_response) + ]], + legend, + response, + edit_response + ) end) it('buffer is highlighted when attached', function() @@ -112,7 +116,8 @@ describe('semantic token highlighting', function() insert(text) - screen:expect { grid = [[ + screen:expect { + grid = [[ #include <iostream> | | int {8:main}() | @@ -125,11 +130,10 @@ describe('semantic token highlighting', function() {6:#endif} | } | ^} | - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*3 | - ]] } + ]], + } end) it('use LspTokenUpdate and highlight_token', function() @@ -151,7 +155,8 @@ describe('semantic token highlighting', function() insert(text) - screen:expect { grid = [[ + screen:expect { + grid = [[ #include <iostream> | | int {9:main}() | @@ -164,12 +169,10 @@ describe('semantic token highlighting', function() {6:#endif} | } | ^} | - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*3 | - ]] } - + ]], + } end) it('buffer is unhighlighted when client is detached', function() @@ -186,7 +189,8 @@ describe('semantic token highlighting', function() vim.lsp.buf_detach_client(bufnr, client_id) ]]) - screen:expect { grid = [[ + screen:expect { + grid = [[ #include <iostream> | | int main() | @@ -199,29 +203,30 @@ describe('semantic token highlighting', function() #endif | } | ^} | - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*3 | - ]] } + ]], + } end) - it('buffer is highlighted and unhighlighted when semantic token highlighting is started and stopped' - , function() - exec_lua([[ + it( + 'buffer is highlighted and unhighlighted when semantic token highlighting is started and stopped', + function() + exec_lua([[ 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 }) ]]) - insert(text) + insert(text) - exec_lua([[ + exec_lua([[ vim.notify = function() end vim.lsp.semantic_tokens.stop(bufnr, client_id) ]]) - screen:expect { grid = [[ + screen:expect { + grid = [[ #include <iostream> | | int main() | @@ -234,17 +239,17 @@ describe('semantic token highlighting', function() #endif | } | ^} | - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*3 | - ]] } + ]], + } - exec_lua([[ + exec_lua([[ vim.lsp.semantic_tokens.start(bufnr, client_id) ]]) - screen:expect { grid = [[ + screen:expect { + grid = [[ #include <iostream> | | int {8:main}() | @@ -257,12 +262,12 @@ describe('semantic token highlighting', function() {6:#endif} | } | ^} | - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*3 | - ]] } - end) + ]], + } + end + ) it('buffer is re-highlighted when force refreshed', function() exec_lua([[ @@ -273,7 +278,8 @@ describe('semantic token highlighting', function() insert(text) - screen:expect { grid = [[ + screen:expect { + grid = [[ #include <iostream> | | int {8:main}() | @@ -286,17 +292,17 @@ describe('semantic token highlighting', function() {6:#endif} | } | ^} | - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*3 | - ]] } + ]], + } exec_lua([[ vim.lsp.semantic_tokens.force_refresh(bufnr) ]]) - screen:expect { grid = [[ + screen:expect { + grid = [[ #include <iostream> | | int {8:main}() | @@ -309,11 +315,11 @@ describe('semantic token highlighting', function() {6:#endif} | } | ^} | - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*3 | - ]], unchanged = true } + ]], + unchanged = true, + } local messages = exec_lua('return server.messages') local token_request_count = 0 @@ -352,7 +358,8 @@ describe('semantic token highlighting', function() ]]) insert(text) - screen:expect { grid = [[ + screen:expect { + grid = [[ #include <iostream> | | int {8:main}() | @@ -365,14 +372,14 @@ describe('semantic token highlighting', function() {6:#endif} | } | ^} | - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*3 | - ]] } + ]], + } feed_command('%s/int x/int x()/') feed_command('noh') - screen:expect { grid = [[ + screen:expect { + grid = [[ #include <iostream> | | int {8:main}() | @@ -383,13 +390,11 @@ describe('semantic token highlighting', function() {6:#else} | {6: printf("%d\n", x);} | {6:#endif} | - } | - } | - {1:~ }| - {1:~ }| - {1:~ }| + } |*2 + {1:~ }|*3 :noh | - ]] } + ]], + } end) it('prevents starting semantic token highlighting with invalid conditions', function() @@ -400,7 +405,7 @@ describe('semantic token highlighting', function() notifications = {} vim.notify = function(...) table.insert(notifications, 1, {...}) end ]]) - eq(false, exec_lua("return vim.lsp.buf_is_attached(bufnr, client_id)")) + eq(false, exec_lua('return vim.lsp.buf_is_attached(bufnr, client_id)')) insert(text) @@ -417,7 +422,8 @@ describe('semantic token highlighting', function() matches('%[LSP%] No client with id %d', notifications[1][1]) end) - it('opt-out: does not activate semantic token highlighting if disabled in client attach', + it( + 'opt-out: does not activate semantic token highlighting if disabled in client attach', function() exec_lua([[ bufnr = vim.api.nvim_get_current_buf() @@ -430,11 +436,12 @@ describe('semantic token highlighting', function() end), }) ]]) - eq(true, exec_lua("return vim.lsp.buf_is_attached(bufnr, client_id)")) + eq(true, exec_lua('return vim.lsp.buf_is_attached(bufnr, client_id)')) insert(text) - screen:expect { grid = [[ + screen:expect { + grid = [[ #include <iostream> | | int main() | @@ -447,11 +454,10 @@ describe('semantic token highlighting', function() #endif | } | ^} | - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*3 | - ]] } + ]], + } local notifications = exec_lua([[ local notifications = {} @@ -461,7 +467,8 @@ describe('semantic token highlighting', function() ]]) eq('[LSP] Server does not support semantic tokens', notifications[1][1]) - screen:expect { grid = [[ + screen:expect { + grid = [[ #include <iostream> | | int main() | @@ -474,14 +481,15 @@ describe('semantic token highlighting', function() #endif | } | ^} | - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*3 | - ]], unchanged = true } - end) + ]], + unchanged = true, + } + end + ) - it('ignores null responses from the server', function() + it('ignores null responses from the server', function() exec_lua([[ local legend, response, edit_response = ... server2 = _create_server({ @@ -503,11 +511,12 @@ describe('semantic token highlighting', function() vim.api.nvim_win_set_buf(0, bufnr) client_id = vim.lsp.start({ name = 'dummy', cmd = server2.cmd }) ]]) - eq(true, exec_lua("return vim.lsp.buf_is_attached(bufnr, client_id)")) + eq(true, exec_lua('return vim.lsp.buf_is_attached(bufnr, client_id)')) insert(text) - screen:expect { grid = [[ + screen:expect { + grid = [[ #include <iostream> | | int main() | @@ -520,15 +529,15 @@ describe('semantic token highlighting', function() #endif | } | ^} | - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*3 | - ]] } + ]], + } end) it('does not send delta requests if not supported by server', function() - exec_lua([[ + exec_lua( + [[ local legend, response, edit_response = ... server2 = _create_server({ capabilities = { @@ -549,10 +558,15 @@ describe('semantic token highlighting', function() bufnr = vim.api.nvim_get_current_buf() vim.api.nvim_win_set_buf(0, bufnr) client_id = vim.lsp.start({ name = 'dummy', cmd = server2.cmd }) - ]], legend, response, edit_response) + ]], + legend, + response, + edit_response + ) insert(text) - screen:expect { grid = [[ + screen:expect { + grid = [[ #include <iostream> | | int {8:main}() | @@ -565,18 +579,18 @@ describe('semantic token highlighting', function() {6:#endif} | } | ^} | - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*3 | - ]] } + ]], + } feed_command('%s/int x/int x()/') feed_command('noh') -- the highlights don't change because our fake server sent the exact -- same result for the same method (the full request). "x" would have -- changed to highlight index 3 had we sent a delta request - screen:expect { grid = [[ + screen:expect { + grid = [[ #include <iostream> | | int {8:main}() | @@ -587,13 +601,11 @@ describe('semantic token highlighting', function() {6:#else} | {6: printf("%d\n", x);} | {6:#endif} | - } | - } | - {1:~ }| - {1:~ }| - {1:~ }| + } |*2 + {1:~ }|*3 :noh | - ]] } + ]], + } local messages = exec_lua('return server2.messages') local token_request_count = 0 for _, message in ipairs(messages) do @@ -631,24 +643,13 @@ describe('semantic token highlighting', function() }, }, expected_screen = function() - screen:expect{grid=[[ + screen:expect { + grid = [[ char* {7:foo} = "\n"^; | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*14 | - ]]} + ]], + } end, }, { @@ -763,7 +764,8 @@ int main() }, }, expected_screen = function() - screen:expect{grid=[[ + screen:expect { + grid = [[ #include <iostream> | int {8:main}() | { | @@ -774,13 +776,10 @@ int main() {6: comment} | {6: #endif} | ^} | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*5 | - ]]} + ]], + } end, }, { @@ -824,24 +823,15 @@ b = "as"]], }, }, expected_screen = function() - screen:expect{grid=[[ + screen:expect { + grid = [[ {6:-- comment} | local {7:a} = 1 | {2:b} = "as^" | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*12 | - ]]} + ]], + } end, }, { @@ -954,30 +944,24 @@ b = "as"]], }, }, expected_screen = function() - screen:expect{grid=[[ + screen:expect { + grid = [[ pub fn {8:main}() { | break rust; | //{6:/ what?} | } | ^ | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*10 | - ]]} + ]], + } end, }, }) do it(test.it, function() exec_lua(create_server_definition) - exec_lua([[ + exec_lua( + [[ local legend, resp = ... server = _create_server({ capabilities = { @@ -995,7 +979,10 @@ b = "as"]], 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 }) - ]], test.legend, test.response) + ]], + test.legend, + test.response + ) insert(test.text) @@ -1037,7 +1024,7 @@ b = "as"]], end_col = 9, type = 'variable', marked = true, - } + }, }, expected2 = { { @@ -1050,47 +1037,26 @@ b = "as"]], end_col = 9, type = 'variable', marked = true, - } + }, }, expected_screen1 = function() - screen:expect{grid=[[ + screen:expect { + grid = [[ char* {7:foo} = "\n"^; | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*14 | - ]]} + ]], + } end, expected_screen2 = function() - screen:expect{grid=[[ + screen:expect { + grid = [[ ^ | char* {7:foo} = "\n"; | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*13 | - ]]} + ]], + } end, }, { @@ -1207,7 +1173,7 @@ int main() modifiers = {}, type = 'comment', marked = true, - } + }, }, expected2 = { { @@ -1289,10 +1255,11 @@ int main() modifiers = {}, type = 'comment', marked = true, - } + }, }, expected_screen1 = function() - screen:expect{grid=[[ + screen:expect { + grid = [[ #include <iostream> | | int {8:main}() | @@ -1304,15 +1271,14 @@ int main() {6: printf("%d\n", x);} | {6:#endif} | ^} | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*4 | - ]]} + ]], + } end, expected_screen2 = function() - screen:expect{grid=[[ + screen:expect { + grid = [[ #include <iostream> | | int {8:main}() | @@ -1325,11 +1291,10 @@ int main() {6: printf("%d\n", x);} | {6:^#endif} | } | - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*3 | - ]]} + ]], + } end, }, { @@ -1356,55 +1321,33 @@ int main() end_col = 6, type = 'variable', marked = true, - } - }, - expected2 = { + }, }, + expected2 = {}, expected_screen1 = function() - screen:expect{grid=[[ + screen:expect { + grid = [[ {7:string} = "test^" | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*14 | - ]]} + ]], + } end, expected_screen2 = function() - screen:expect{grid=[[ + screen:expect { + grid = [[ ^ | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*14 | - ]]} + ]], + } end, }, }) do it(test.it, function() exec_lua(create_server_definition) - exec_lua([[ + exec_lua( + [[ local legend, resp1, resp2 = ... server = _create_server({ capabilities = { @@ -1432,7 +1375,11 @@ int main() semantic_tokens.stop(bufnr, client_id) semantic_tokens.start(bufnr, client_id, { debounce = 10 }) end) - ]], test.legend, test.response1, test.response2) + ]], + test.legend, + test.response1, + test.response2 + ) insert(test.text1) @@ -1447,11 +1394,14 @@ int main() if test.edit then feed(test.edit) else - exec_lua([[ + exec_lua( + [[ local text = ... vim.api.nvim_buf_set_lines(bufnr, 0, -1, false, vim.fn.split(text, "\n")) vim.wait(15) -- wait for debounce - ]], test.text2) + ]], + test.text2 + ) end test.expected_screen2() diff --git a/test/functional/plugin/lsp/utils_spec.lua b/test/functional/plugin/lsp/utils_spec.lua index 804dc32f0d..bb9cdb8390 100644 --- a/test/functional/plugin/lsp/utils_spec.lua +++ b/test/functional/plugin/lsp/utils_spec.lua @@ -10,7 +10,8 @@ describe('vim.lsp.util', function() describe('stylize_markdown', function() local stylize_markdown = function(content, opts) - return exec_lua([[ + return exec_lua( + [[ local bufnr = vim.uri_to_bufnr("file:///fake/uri") vim.fn.bufload(bufnr) @@ -20,14 +21,17 @@ describe('vim.lsp.util', function() local stripped_content = vim.lsp.util.stylize_markdown(bufnr, content, opts) return stripped_content - ]], content, opts) + ]], + content, + opts + ) end it('code fences', function() local lines = { - "```lua", + '```lua', "local hello = 'world'", - "```", + '```', } local expected = { "local hello = 'world'", @@ -38,9 +42,9 @@ describe('vim.lsp.util', function() it('code fences with whitespace surrounded info string', function() local lines = { - "``` lua ", + '``` lua ', "local hello = 'world'", - "```", + '```', } local expected = { "local hello = 'world'", @@ -51,16 +55,16 @@ describe('vim.lsp.util', function() it('adds separator after code block', function() local lines = { - "```lua", + '```lua', "local hello = 'world'", - "```", - "", - "something", + '```', + '', + 'something', } local expected = { "local hello = 'world'", - "─────────────────────", - "something", + '─────────────────────', + 'something', } local opts = { separator = true } eq(expected, stylize_markdown(lines, opts)) @@ -68,28 +72,28 @@ describe('vim.lsp.util', function() it('replaces supported HTML entities', function() local lines = { - "1 < 2", - "3 > 2", - ""quoted"", - "'apos'", - "   ", - "&", + '1 < 2', + '3 > 2', + '"quoted"', + ''apos'', + '   ', + '&', } local expected = { - "1 < 2", - "3 > 2", + '1 < 2', + '3 > 2', '"quoted"', "'apos'", - " ", - "&", + ' ', + '&', } local opts = {} eq(expected, stylize_markdown(lines, opts)) end) end) - describe('normalize_markdown', function () - it('collapses consecutive blank lines', function () + describe('normalize_markdown', function() + it('collapses consecutive blank lines', function() local result = exec_lua [[ local lines = { 'foo', @@ -102,11 +106,11 @@ describe('vim.lsp.util', function() } return vim.lsp.util._normalize_markdown(lines) ]] - local expected = {'foo', '', 'bar', '', 'baz'} + local expected = { 'foo', '', 'bar', '', 'baz' } eq(expected, result) end) - it('removes preceding and trailing empty lines', function () + it('removes preceding and trailing empty lines', function() local result = exec_lua [[ local lines = { '', @@ -117,103 +121,105 @@ describe('vim.lsp.util', function() } return vim.lsp.util._normalize_markdown(lines) ]] - local expected = {'foo', 'bar'} + local expected = { 'foo', 'bar' } eq(expected, result) end) end) - describe("make_floating_popup_options", function () - + describe('make_floating_popup_options', function() local function assert_anchor(anchor_bias, expected_anchor) - local opts = exec_lua([[ + local opts = exec_lua( + [[ local args = { ... } local anchor_bias = args[1] return vim.lsp.util.make_floating_popup_options(30, 10, { anchor_bias = anchor_bias }) - ]], anchor_bias) + ]], + anchor_bias + ) - eq(expected_anchor, string.sub(opts.anchor, 1, 1)) + eq(expected_anchor, string.sub(opts.anchor, 1, 1)) end local screen - before_each(function () + before_each(function() helpers.clear() screen = Screen.new(80, 80) screen:attach() - feed("79i<CR><Esc>") -- fill screen with empty lines + feed('79i<CR><Esc>') -- fill screen with empty lines end) - describe('when on the first line it places window below', function () - before_each(function () + describe('when on the first line it places window below', function() + before_each(function() feed('gg') end) - it('for anchor_bias = "auto"', function () + it('for anchor_bias = "auto"', function() assert_anchor('auto', 'N') end) - it('for anchor_bias = "above"', function () + it('for anchor_bias = "above"', function() assert_anchor('above', 'N') end) - it('for anchor_bias = "below"', function () + it('for anchor_bias = "below"', function() assert_anchor('below', 'N') end) end) - describe('when on the last line it places window above', function () - before_each(function () + describe('when on the last line it places window above', function() + before_each(function() feed('G') end) - it('for anchor_bias = "auto"', function () + it('for anchor_bias = "auto"', function() assert_anchor('auto', 'S') end) - it('for anchor_bias = "above"', function () + it('for anchor_bias = "above"', function() assert_anchor('above', 'S') end) - it('for anchor_bias = "below"', function () + it('for anchor_bias = "below"', function() assert_anchor('below', 'S') end) end) - describe('with 20 lines above, 59 lines below', function () - before_each(function () + describe('with 20 lines above, 59 lines below', function() + before_each(function() feed('gg20j') end) - it('places window below for anchor_bias = "auto"', function () + it('places window below for anchor_bias = "auto"', function() assert_anchor('auto', 'N') end) - it('places window above for anchor_bias = "above"', function () + it('places window above for anchor_bias = "above"', function() assert_anchor('above', 'S') end) - it('places window below for anchor_bias = "below"', function () + it('places window below for anchor_bias = "below"', function() assert_anchor('below', 'N') end) end) - describe('with 59 lines above, 20 lines below', function () - before_each(function () + describe('with 59 lines above, 20 lines below', function() + before_each(function() feed('G20k') end) - it('places window above for anchor_bias = "auto"', function () + it('places window above for anchor_bias = "auto"', function() assert_anchor('auto', 'S') end) - it('places window above for anchor_bias = "above"', function () + it('places window above for anchor_bias = "above"', function() assert_anchor('above', 'S') end) - it('places window below for anchor_bias = "below"', function () + it('places window below for anchor_bias = "below"', function() assert_anchor('below', 'N') end) - it('bordered window truncates dimensions correctly', function () + it('bordered window truncates dimensions correctly', function() local opts = exec_lua([[ return vim.lsp.util.make_floating_popup_options(100, 100, { border = 'single' }) ]]) @@ -222,5 +228,4 @@ describe('vim.lsp.util', function() end) end) end) - end) diff --git a/test/functional/plugin/lsp/watchfiles_spec.lua b/test/functional/plugin/lsp/watchfiles_spec.lua deleted file mode 100644 index a8260e0c98..0000000000 --- a/test/functional/plugin/lsp/watchfiles_spec.lua +++ /dev/null @@ -1,222 +0,0 @@ -local helpers = require('test.functional.helpers')(after_each) - -local eq = helpers.eq -local exec_lua = helpers.exec_lua - -describe('vim.lsp._watchfiles', function() - before_each(helpers.clear) - after_each(helpers.clear) - - local match = function(...) - return exec_lua('return require("vim.lsp._watchfiles")._match(...)', ...) - end - - describe('glob matching', function() - it('should match literal strings', function() - eq(true, match('', '')) - eq(false, match('', 'a')) - eq(true, match('a', 'a')) - eq(true, match('/', '/')) - eq(true, match('abc', 'abc')) - eq(false, match('abc', 'abcdef')) - eq(false, match('abc', 'a')) - eq(false, match('abc', 'bc')) - eq(false, match('a', 'b')) - eq(false, match('.', 'a')) - eq(true, match('$', '$')) - eq(true, match('/dir', '/dir')) - eq(true, match('dir/', 'dir/')) - eq(true, match('dir/subdir', 'dir/subdir')) - eq(false, match('dir/subdir', 'subdir')) - eq(false, match('dir/subdir', 'dir/subdir/file')) - eq(true, match('🤠', '🤠')) - end) - - it('should match * wildcards', function() - eq(false, match('*', '')) - eq(true, match('*', 'a')) - eq(false, match('*', '/')) - eq(false, match('*', '/a')) - eq(false, match('*', 'a/')) - eq(true, match('*', 'aaa')) - eq(true, match('*a', 'aa')) - eq(true, match('*a', 'abca')) - eq(true, match('*.txt', 'file.txt')) - eq(false, match('*.txt', 'file.txtxt')) - eq(false, match('*.txt', 'dir/file.txt')) - eq(false, match('*.txt', '/dir/file.txt')) - eq(false, match('*.txt', 'C:/dir/file.txt')) - eq(false, match('*.dir', 'test.dir/file')) - eq(true, match('file.*', 'file.txt')) - eq(false, match('file.*', 'not-file.txt')) - eq(true, match('*/file.txt', 'dir/file.txt')) - eq(false, match('*/file.txt', 'dir/subdir/file.txt')) - eq(false, match('*/file.txt', '/dir/file.txt')) - eq(true, match('dir/*', 'dir/file.txt')) - eq(false, match('dir/*', 'dir')) - eq(false, match('dir/*.txt', 'file.txt')) - eq(true, match('dir/*.txt', 'dir/file.txt')) - eq(false, match('dir/*.txt', 'dir/subdir/file.txt')) - eq(false, match('dir/*/file.txt', 'dir/file.txt')) - eq(true, match('dir/*/file.txt', 'dir/subdir/file.txt')) - eq(false, match('dir/*/file.txt', 'dir/subdir/subdir/file.txt')) - - -- TODO: The spec does not describe this, but VSCode only interprets ** when it's by - -- itself in a path segment, and otherwise interprets ** as consecutive * directives. - -- The following tests show how this behavior should work, but is not yet fully implemented. - -- Currently, "a**" parses incorrectly as "a" "**" and "**a" parses correctly as "*" "*" "a". - -- see: https://github.com/microsoft/vscode/blob/eef30e7165e19b33daa1e15e92fa34ff4a5df0d3/src/vs/base/common/glob.ts#L112 - eq(true, match('a**', 'abc')) -- '**' should parse as two '*'s when not by itself in a path segment - eq(true, match('**c', 'abc')) - -- eq(false, match('a**', 'ab')) -- each '*' should still represent at least one character - eq(false, match('**c', 'bc')) - eq(true, match('a**', 'abcd')) - eq(true, match('**d', 'abcd')) - -- eq(false, match('a**', 'abc/d')) - eq(false, match('**d', 'abc/d')) - end) - - it('should match ? wildcards', function() - eq(false, match('?', '')) - eq(true, match('?', 'a')) - eq(false, match('??', 'a')) - eq(false, match('?', 'ab')) - eq(true, match('??', 'ab')) - eq(true, match('a?c', 'abc')) - eq(false, match('a?c', 'a/c')) - end) - - it('should match ** wildcards', function() - eq(true, match('**', '')) - eq(true, match('**', 'a')) - eq(true, match('**', '/')) - eq(true, match('**', 'a/')) - eq(true, match('**', '/a')) - eq(true, match('**', 'C:/a')) - eq(true, match('**', 'a/a')) - eq(true, match('**', 'a/a/a')) - eq(false, match('/**', '')) -- /** matches leading / literally - eq(true, match('/**', '/')) - eq(true, match('/**', '/a/b/c')) - eq(true, match('**/', '')) -- **/ absorbs trailing / - eq(true, match('**/', '/a/b/c')) - eq(true, match('**/**', '')) - eq(true, match('**/**', 'a')) - eq(false, match('a/**', '')) - eq(false, match('a/**', 'a')) - eq(true, match('a/**', 'a/b')) - eq(true, match('a/**', 'a/b/c')) - eq(false, match('a/**', 'b/a')) - eq(false, match('a/**', '/a')) - eq(false, match('**/a', '')) - eq(true, match('**/a', 'a')) - eq(false, match('**/a', 'a/b')) - eq(true, match('**/a', '/a')) - eq(true, match('**/a', '/b/a')) - eq(true, match('**/a', '/c/b/a')) - eq(true, match('**/a', '/a/a')) - eq(true, match('**/a', '/abc/a')) - eq(false, match('a/**/c', 'a')) - eq(false, match('a/**/c', 'c')) - eq(true, match('a/**/c', 'a/c')) - eq(true, match('a/**/c', 'a/b/c')) - eq(true, match('a/**/c', 'a/b/b/c')) - eq(false, match('**/a/**', 'a')) - eq(true, match('**/a/**', 'a/')) - eq(false, match('**/a/**', '/dir/a')) - eq(false, match('**/a/**', 'dir/a')) - eq(true, match('**/a/**', 'dir/a/')) - eq(true, match('**/a/**', 'a/dir')) - eq(true, match('**/a/**', 'dir/a/dir')) - eq(true, match('**/a/**', '/a/dir')) - eq(true, match('**/a/**', 'C:/a/dir')) - eq(false, match('**/a/**', 'a.txt')) - end) - - it('should match {} groups', function() - eq(true, match('{}', '')) - eq(false, match('{}', 'a')) - eq(true, match('a{}', 'a')) - eq(true, match('{}a', 'a')) - eq(true, match('{,}', '')) - eq(true, match('{a,}', '')) - eq(true, match('{a,}', 'a')) - eq(true, match('{a}', 'a')) - eq(false, match('{a}', 'aa')) - eq(false, match('{a}', 'ab')) - eq(true, match('{a?c}', 'abc')) - eq(false, match('{ab}', 'a')) - eq(false, match('{ab}', 'b')) - eq(true, match('{ab}', 'ab')) - eq(true, match('{a,b}', 'a')) - eq(true, match('{a,b}', 'b')) - eq(false, match('{a,b}', 'ab')) - eq(true, match('{ab,cd}', 'ab')) - eq(false, match('{ab,cd}', 'a')) - eq(true, match('{ab,cd}', 'cd')) - eq(true, match('{a,b,c}', 'c')) - eq(true, match('{a,{b,c}}', 'c')) - end) - - it('should match [] groups', function() - eq(true, match('[]', '[]')) -- empty [] is a literal - eq(false, match('[a-z]', '')) - eq(true, match('[a-z]', 'a')) - eq(false, match('[a-z]', 'ab')) - eq(true, match('[a-z]', 'z')) - eq(true, match('[a-z]', 'j')) - eq(false, match('[a-f]', 'j')) - eq(false, match('[a-z]', '`')) -- 'a' - 1 - eq(false, match('[a-z]', '{')) -- 'z' + 1 - eq(false, match('[a-z]', 'A')) - eq(false, match('[a-z]', '5')) - eq(true, match('[A-Z]', 'A')) - eq(true, match('[A-Z]', 'Z')) - eq(true, match('[A-Z]', 'J')) - eq(false, match('[A-Z]', '@')) -- 'A' - 1 - eq(false, match('[A-Z]', '[')) -- 'Z' + 1 - eq(false, match('[A-Z]', 'a')) - eq(false, match('[A-Z]', '5')) - eq(true, match('[a-zA-Z0-9]', 'z')) - eq(true, match('[a-zA-Z0-9]', 'Z')) - eq(true, match('[a-zA-Z0-9]', '9')) - eq(false, match('[a-zA-Z0-9]', '&')) - end) - - it('should match [!...] groups', function() - eq(true, match('[!]', '[!]')) -- [!] is a literal - eq(false, match('[!a-z]', '')) - eq(false, match('[!a-z]', 'a')) - eq(false, match('[!a-z]', 'z')) - eq(false, match('[!a-z]', 'j')) - eq(true, match('[!a-f]', 'j')) - eq(false, match('[!a-f]', 'jj')) - eq(true, match('[!a-z]', '`')) -- 'a' - 1 - eq(true, match('[!a-z]', '{')) -- 'z' + 1 - eq(false, match('[!a-zA-Z0-9]', 'a')) - eq(false, match('[!a-zA-Z0-9]', 'A')) - eq(false, match('[!a-zA-Z0-9]', '0')) - eq(true, match('[!a-zA-Z0-9]', '!')) - end) - - it('should match complex patterns', function() - eq(false, match('**/*.{c,h}', '')) - eq(false, match('**/*.{c,h}', 'c')) - eq(false, match('**/*.{c,h}', 'file.m')) - eq(true, match('**/*.{c,h}', 'file.c')) - eq(true, match('**/*.{c,h}', 'file.h')) - eq(true, match('**/*.{c,h}', '/file.c')) - eq(true, match('**/*.{c,h}', 'dir/subdir/file.c')) - eq(true, match('**/*.{c,h}', 'dir/subdir/file.h')) - eq(true, match('**/*.{c,h}', '/dir/subdir/file.c')) - eq(true, match('**/*.{c,h}', 'C:/dir/subdir/file.c')) - eq(true, match('/dir/**/*.{c,h}', '/dir/file.c')) - eq(false, match('/dir/**/*.{c,h}', 'dir/file.c')) - eq(true, match('/dir/**/*.{c,h}', '/dir/subdir/subdir/file.c')) - - eq(true, match('{[0-9],[a-z]}', '0')) - eq(true, match('{[0-9],[a-z]}', 'a')) - eq(false, match('{[0-9],[a-z]}', 'A')) - end) - end) -end) |