diff options
Diffstat (limited to 'test')
-rw-r--r-- | test/functional/autocmd/autocmd_spec.lua | 11 | ||||
-rw-r--r-- | test/functional/core/startup_spec.lua | 70 | ||||
-rw-r--r-- | test/functional/ex_cmds/source_spec.lua | 71 | ||||
-rw-r--r-- | test/functional/fixtures/fake-lsp-server.lua | 17 | ||||
-rw-r--r-- | test/functional/helpers.lua | 5 | ||||
-rw-r--r-- | test/functional/legacy/011_autocommands_spec.lua | 9 | ||||
-rw-r--r-- | test/functional/legacy/packadd_spec.lua | 10 | ||||
-rw-r--r-- | test/functional/lua/runtime_spec.lua | 141 | ||||
-rw-r--r-- | test/functional/plugin/lsp/codelens_spec.lua | 62 | ||||
-rw-r--r-- | test/functional/plugin/lsp_spec.lua | 162 | ||||
-rw-r--r-- | test/functional/ui/float_spec.lua | 90 | ||||
-rw-r--r-- | test/functional/ui/messages_spec.lua | 4 | ||||
-rw-r--r-- | test/functional/ui/spell_spec.lua | 3 | ||||
-rw-r--r-- | test/functional/ui/tabline_spec.lua | 43 | ||||
-rw-r--r-- | test/unit/eval/typval_spec.lua | 2 | ||||
-rw-r--r-- | test/unit/marktree_spec.lua | 15 |
16 files changed, 644 insertions, 71 deletions
diff --git a/test/functional/autocmd/autocmd_spec.lua b/test/functional/autocmd/autocmd_spec.lua index e62d3bb66b..93d71a9e45 100644 --- a/test/functional/autocmd/autocmd_spec.lua +++ b/test/functional/autocmd/autocmd_spec.lua @@ -101,6 +101,17 @@ describe('autocmd', function() }, eval('g:evs')) end) + it('WinClosed from root directory', function() + command('cd /') + command('let g:evs = []') + command('autocmd WinClosed * :call add(g:evs, ["WinClosed", expand("<afile>")])') + command('new') + command('close') + eq({ + {'WinClosed', '1001'}, + }, eval('g:evs')) + end) + it('v:vim_did_enter is 1 after VimEnter', function() eq(1, eval('v:vim_did_enter')) end) diff --git a/test/functional/core/startup_spec.lua b/test/functional/core/startup_spec.lua index d5f03db03a..658dfbda60 100644 --- a/test/functional/core/startup_spec.lua +++ b/test/functional/core/startup_spec.lua @@ -11,6 +11,7 @@ local exec_lua = helpers.exec_lua local feed = helpers.feed local funcs = helpers.funcs local mkdir = helpers.mkdir +local mkdir_p = helpers.mkdir_p local nvim_prog = helpers.nvim_prog local nvim_set = helpers.nvim_set local read_file = helpers.read_file @@ -494,6 +495,75 @@ describe('user config init', function() end) end) +describe('runtime:', function() + local xhome = 'Xhome' + local pathsep = helpers.get_pathsep() + local xconfig = xhome .. pathsep .. 'Xconfig' + + setup(function() + mkdir_p(xconfig .. pathsep .. 'nvim') + end) + + teardown(function() + rmdir(xhome) + end) + + it('loads plugin/*.lua from XDG config home', function() + local plugin_folder_path = table.concat({xconfig, 'nvim', 'plugin'}, pathsep) + local plugin_file_path = table.concat({plugin_folder_path, 'plugin.lua'}, pathsep) + mkdir_p(plugin_folder_path) + write_file(plugin_file_path, [[ vim.g.lua_plugin = 1 ]]) + + clear{ args_rm={'-u'}, env={ XDG_CONFIG_HOME=xconfig }} + + eq(1, eval('g:lua_plugin')) + rmdir(plugin_folder_path) + end) + + it('loads plugin/*.lua from start plugins', function() + local plugin_path = table.concat({xconfig, 'nvim', 'pack', 'catagory', + 'start', 'test_plugin'}, pathsep) + local plugin_folder_path = table.concat({plugin_path, 'plugin'}, pathsep) + local plugin_file_path = table.concat({plugin_folder_path, 'plugin.lua'}, + pathsep) + local profiler_file = 'test_startuptime.log' + + mkdir_p(plugin_folder_path) + write_file(plugin_file_path, [[vim.g.lua_plugin = 2]]) + + clear{ args_rm={'-u'}, args={'--startuptime', profiler_file}, env={ XDG_CONFIG_HOME=xconfig }} + + eq(2, eval('g:lua_plugin')) + -- Check if plugin_file_path is listed in :scriptname + local scripts = meths.exec(':scriptnames', true) + assert.Truthy(scripts:find(plugin_file_path)) + + -- Check if plugin_file_path is listed in startup profile + local profile_reader = io.open(profiler_file, 'r') + local profile_log = profile_reader:read('*a') + profile_reader:close() + assert.Truthy(profile_log :find(plugin_file_path)) + + os.remove(profiler_file) + rmdir(plugin_path) + end) + + it('loads ftdetect/*.lua', function() + local ftdetect_folder = table.concat({xconfig, 'nvim', 'ftdetect'}, pathsep) + local ftdetect_file = table.concat({ftdetect_folder , 'new-ft.lua'}, pathsep) + mkdir_p(ftdetect_folder) + write_file(ftdetect_file , [[vim.g.lua_ftdetect = 1]]) + + -- TODO(shadmansaleh): Figure out why this test fails without + -- setting VIMRUNTIME + clear{ args_rm={'-u'}, env={XDG_CONFIG_HOME=xconfig, + VIMRUNTIME='runtime/'}} + + eq(1, eval('g:lua_ftdetect')) + rmdir(ftdetect_folder) + end) +end) + describe('user session', function() local xhome = 'Xhome' local pathsep = helpers.get_pathsep() diff --git a/test/functional/ex_cmds/source_spec.lua b/test/functional/ex_cmds/source_spec.lua index 16d0dfb6a1..37c97f519a 100644 --- a/test/functional/ex_cmds/source_spec.lua +++ b/test/functional/ex_cmds/source_spec.lua @@ -6,6 +6,11 @@ local clear = helpers.clear local meths = helpers.meths local feed = helpers.feed local feed_command = helpers.feed_command +local write_file = helpers.write_file +local exec = helpers.exec +local eval = helpers.eval +local exec_capture = helpers.exec_capture +local neq = helpers.neq describe(':source', function() before_each(function() @@ -44,4 +49,70 @@ describe(':source', function() command('source') eq('4', meths.exec('echo luaeval("y")', true)) end) + + it('can source lua files', function() + local test_file = 'test.lua' + write_file (test_file, [[vim.g.sourced_lua = 1]]) + + exec('source ' .. test_file) + + eq(1, eval('g:sourced_lua')) + os.remove(test_file) + end) + + it('can source selected region in lua file', function() + local test_file = 'test.lua' + + write_file (test_file, [[ + vim.g.b = 5 + vim.g.b = 6 + vim.g.b = 7 + ]]) + + command('edit '..test_file) + feed('ggjV') + feed_command(':source') + + eq(6, eval('g:b')) + os.remove(test_file) + end) + + it('can source current lua buffer without argument', function() + local test_file = 'test.lua' + + write_file (test_file, [[ + vim.g.c = 10 + vim.g.c = 11 + vim.g.c = 12 + ]]) + + command('edit '..test_file) + feed_command(':source') + + eq(12, eval('g:c')) + os.remove(test_file) + end) + + it("doesn't throw E484 for lua parsing/runtime errors", function() + local test_file = 'test.lua' + + -- Does throw E484 for unreadable files + local ok, result = pcall(exec_capture, ":source "..test_file ..'noexisting') + eq(false, ok) + neq(nil, result:find("E484")) + + -- Doesn't throw for parsing error + write_file (test_file, "vim.g.c = ") + ok, result = pcall(exec_capture, ":source "..test_file) + eq(false, ok) + eq(nil, result:find("E484")) + os.remove(test_file) + + -- Doesn't throw for runtime error + write_file (test_file, "error('Cause error anyway :D')") + ok, result = pcall(exec_capture, ":source "..test_file) + eq(false, ok) + eq(nil, result:find("E484")) + os.remove(test_file) + end) end) diff --git a/test/functional/fixtures/fake-lsp-server.lua b/test/functional/fixtures/fake-lsp-server.lua index bcd5e22492..b7fddc8f29 100644 --- a/test/functional/fixtures/fake-lsp-server.lua +++ b/test/functional/fixtures/fake-lsp-server.lua @@ -464,6 +464,23 @@ function tests.invalid_header() io.stdout:write("Content-length: \r\n") end +function tests.decode_nil() + skeleton { + on_init = function(_) + return { capabilities = {} } + end; + body = function() + notify('start') + notify("workspace/executeCommand", { + arguments = { "EXTRACT_METHOD", {metadata = {field = vim.NIL}}, 3, 0, 6123, vim.NIL }, + command = "refactor.perform", + title = "EXTRACT_METHOD" + }) + notify('finish') + end; + } +end + -- Tests will be indexed by TEST_NAME local kill_timer = vim.loop.new_timer() diff --git a/test/functional/helpers.lua b/test/functional/helpers.lua index 4acb1a7d8d..08ca14c3df 100644 --- a/test/functional/helpers.lua +++ b/test/functional/helpers.lua @@ -878,6 +878,11 @@ function module.os_kill(pid) or 'kill -9 '..pid..' > /dev/null')) end +-- Create directories with non exsisting intermidiate directories +function module.mkdir_p(path) + return module.meths.call_function('mkdir', {path, 'p'}) +end + module = global_helpers.tbl_extend('error', module, global_helpers) return function(after_each) diff --git a/test/functional/legacy/011_autocommands_spec.lua b/test/functional/legacy/011_autocommands_spec.lua index 7cc31dc787..7b6f2f63e9 100644 --- a/test/functional/legacy/011_autocommands_spec.lua +++ b/test/functional/legacy/011_autocommands_spec.lua @@ -17,6 +17,7 @@ local lfs = require('lfs') local clear, feed_command, expect, eq, neq, dedent, write_file, feed = helpers.clear, helpers.feed_command, helpers.expect, helpers.eq, helpers.neq, helpers.dedent, helpers.write_file, helpers.feed +local command = helpers.command local iswin = helpers.iswin local read_file = helpers.read_file @@ -28,7 +29,7 @@ end local function prepare_gz_file(name, text) write_file(name, text..'\n') -- Compress the file with gzip. - os.execute('gzip --force '..name) + command([[call system(['gzip', '--force', ']]..name..[['])]]) -- This should create the .gz file and delete the original. neq(nil, lfs.attributes(name..'.gz')) eq(nil, lfs.attributes(name)) @@ -54,7 +55,9 @@ describe('file reading, writing and bufnew and filter autocommands', function() */ ]]) end) - before_each(clear) + before_each(function () + clear({env={GZIP=nil}}) + end) teardown(function() os.remove('Xtestfile.gz') os.remove('Xtest.c') @@ -67,7 +70,6 @@ describe('file reading, writing and bufnew and filter autocommands', function() it('FileReadPost (using gzip)', function() prepare_gz_file('Xtestfile', text1) - feed_command('let $GZIP = ""') --execute('au FileChangedShell * echo "caught FileChangedShell"') feed_command('set bin') feed_command("au FileReadPost *.gz '[,']!gzip -d") @@ -79,7 +81,6 @@ describe('file reading, writing and bufnew and filter autocommands', function() it('BufReadPre, BufReadPost (using gzip)', function() prepare_gz_file('Xtestfile', text1) local gzip_data = read_file('Xtestfile.gz') - feed_command('let $GZIP = ""') -- Setup autocommands to decompress before reading and re-compress afterwards. feed_command("au BufReadPre *.gz exe '!gzip -d ' . shellescape(expand('<afile>'))") feed_command("au BufReadPre *.gz call rename(expand('<afile>:r'), expand('<afile>'))") diff --git a/test/functional/legacy/packadd_spec.lua b/test/functional/legacy/packadd_spec.lua index 486a1fe471..48cd3ef9f8 100644 --- a/test/functional/legacy/packadd_spec.lua +++ b/test/functional/legacy/packadd_spec.lua @@ -101,9 +101,14 @@ describe('packadd', function() call setline(1, 'let g:plugin_works = 24') wq + exe 'split ' . plugdir . '/plugin/test.lua' + call setline(1, 'vim.g.plugin_lua_works = 24') + wq + packadd other call assert_equal(24, g:plugin_works) + call assert_equal(24, g:plugin_lua_works) call assert_true(len(&rtp) > len(rtp)) call assert_match(Escape(plugdir) . '\($\|,\)', &rtp) endfunc @@ -117,13 +122,18 @@ describe('packadd', function() exe 'split ' . s:plugdir . '/plugin/test.vim' call setline(1, 'let g:plugin_works = 42') wq + exe 'split ' . s:plugdir . '/plugin/test.lua' + call setline(1, 'let g:plugin_lua_works = 42') + wq let g:plugin_works = 0 + let g:plugin_lua_works = 0 packadd! mytest call assert_true(len(&rtp) > len(rtp)) call assert_match(Escape(s:plugdir) . '\($\|,\)', &rtp) call assert_equal(0, g:plugin_works) + call assert_equal(0, g:plugin_lua_works) " check the path is not added twice let new_rtp = &rtp diff --git a/test/functional/lua/runtime_spec.lua b/test/functional/lua/runtime_spec.lua new file mode 100644 index 0000000000..e9c34c9228 --- /dev/null +++ b/test/functional/lua/runtime_spec.lua @@ -0,0 +1,141 @@ +local helpers = require('test.functional.helpers')(after_each) + +local clear = helpers.clear +local eq = helpers.eq +local eval = helpers.eval +local exec = helpers.exec +local mkdir_p = helpers.mkdir_p +local rmdir = helpers.rmdir +local write_file = helpers.write_file + +describe('runtime:', function() + local plug_dir = 'Test_Plugin' + local sep = helpers.get_pathsep() + local init = 'dummy_init.lua' + + setup(function() + io.open(init, 'w'):close() -- touch init file + clear{args = {'-u', init}} + exec('set rtp+=' .. plug_dir) + end) + + teardown(function() + os.remove(init) + end) + + before_each(function() + mkdir_p(plug_dir) + end) + + after_each(function() + rmdir(plug_dir) + end) + + describe('colors', function() + local colorscheme_folder = plug_dir .. sep .. 'colors' + + it('loads lua colorscheme', function() + local colorscheme_file = colorscheme_folder .. sep .. 'new_colorscheme.lua' + mkdir_p(colorscheme_folder) + write_file(colorscheme_file, [[vim.g.lua_colorscheme = 1]]) + + exec('colorscheme new_colorscheme') + + eq(1, eval('g:lua_colorscheme')) + rmdir(colorscheme_folder) + end) + + it('loads vim colorscheme when both lua and vim version exist', function() + local colorscheme_file = colorscheme_folder .. sep .. 'new_colorscheme' + mkdir_p(colorscheme_folder) + write_file(colorscheme_file..'.vim', [[let g:colorscheme = 'vim']]) + write_file(colorscheme_file..'.lua', [[vim.g.colorscheme = 'lua']]) + + exec('colorscheme new_colorscheme') + + eq('vim', eval('g:colorscheme')) + rmdir(colorscheme_folder) + end) + end) + + describe('compiler', function() + local compiler_folder = plug_dir .. sep .. 'compiler' + + it('loads lua compilers', function() + local compiler_file = compiler_folder .. sep .. 'new_compiler.lua' + mkdir_p(compiler_folder) + write_file(compiler_file, [[vim.g.lua_compiler = 1]]) + + exec('compiler new_compiler') + + eq(1, eval('g:lua_compiler')) + rmdir(compiler_folder) + end) + + it('loads vim compilers when both lua and vim version exist', function() + local compiler_file = compiler_folder .. sep .. 'new_compiler' + mkdir_p(compiler_folder) + write_file(compiler_file..'.vim', [[let g:compiler = 'vim']]) + write_file(compiler_file..'.lua', [[vim.g.compiler = 'lua']]) + + exec('compiler new_compiler') + + eq('vim', eval('g:compiler')) + rmdir(compiler_folder) + end) + end) + + describe('ftplugin', function() + local ftplugin_folder = table.concat({plug_dir, 'ftplugin'}, sep) + + it('loads lua ftplugins', function() + local ftplugin_file = table.concat({ftplugin_folder , 'new-ft.lua'}, sep) + mkdir_p(ftplugin_folder) + write_file(ftplugin_file , [[vim.g.lua_ftplugin = 1]]) + + exec [[set filetype=new-ft]] + eq(1, eval('g:lua_ftplugin')) + rmdir(ftplugin_folder) + end) + end) + + describe('indent', function() + local indent_folder = table.concat({plug_dir, 'indent'}, sep) + + it('loads lua indents', function() + local indent_file = table.concat({indent_folder , 'new-ft.lua'}, sep) + mkdir_p(indent_folder) + write_file(indent_file , [[vim.g.lua_indent = 1]]) + + exec [[set filetype=new-ft]] + eq(1, eval('g:lua_indent')) + rmdir(indent_folder) + end) + end) + + describe('syntax', function() + local syntax_folder = table.concat({plug_dir, 'syntax'}, sep) + + it('loads lua syntaxes on filetype change', function() + local syntax_file = table.concat({syntax_folder , 'my-lang.lua'}, sep) + mkdir_p(syntax_folder) + write_file(syntax_file , [[vim.g.lua_syntax = 1]]) + + exec('set filetype=my-lang') + eq(1, eval('g:lua_syntax')) + rmdir(syntax_folder) + end) + + it('loads lua syntaxes on syntax change', function() + local syntax_file = table.concat({syntax_folder , 'my-lang.lua'}, sep) + mkdir_p(syntax_folder) + write_file(syntax_file , [[vim.g.lua_syntax = 5]]) + + exec('set syntax=my-lang') + eq(5, eval('g:lua_syntax')) + rmdir(syntax_folder) + end) + end) + +end) + diff --git a/test/functional/plugin/lsp/codelens_spec.lua b/test/functional/plugin/lsp/codelens_spec.lua new file mode 100644 index 0000000000..e09d93f7cc --- /dev/null +++ b/test/functional/plugin/lsp/codelens_spec.lua @@ -0,0 +1,62 @@ +local helpers = require('test.functional.helpers')(after_each) + +local exec_lua = helpers.exec_lua +local eq = helpers.eq + +describe('vim.lsp.codelens', function() + before_each(function() + helpers.clear() + exec_lua('require("vim.lsp")') + end) + after_each(helpers.clear) + + it('on_codelens_stores_and_displays_lenses', function() + 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) + + exec_lua([[ + local bufnr = ... + local lenses = { + { + range = { + start = { line = 0, character = 0, }, + ['end'] = { line = 0, character = 0 } + }, + command = { title = 'Lens1', command = 'Dummy' } + }, + } + vim.lsp.codelens.on_codelens(nil, 'textDocument/codeLens', lenses, 1, 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 } + }, + command = { + title = 'Lens1', + command = 'Dummy', + }, + }, + } + eq(expected, stored_lenses) + + 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) + + eq({[1] = {'Lens1', 'LspCodeLens'}}, virtual_text_chunks) + end) +end) diff --git a/test/functional/plugin/lsp_spec.lua b/test/functional/plugin/lsp_spec.lua index 663271deab..35cc2d3075 100644 --- a/test/functional/plugin/lsp_spec.lua +++ b/test/functional/plugin/lsp_spec.lua @@ -105,8 +105,8 @@ local function test_rpc_server(config) return NIL end if method == 'handler' then - if config.on_callback then - config.on_callback(unpack(args)) + if config.on_handler then + config.on_handler(unpack(args)) end end return NIL @@ -215,7 +215,7 @@ describe('LSP', function() end) it('should run correctly', function() - local expected_callbacks = { + local expected_handlers = { {NIL, "test", {}, 1}; } test_rpc_server { @@ -232,15 +232,15 @@ describe('LSP', function() eq(0, signal, "exit signal", fake_lsp_logfile) end; -- Note that NIL must be used here. - -- on_callback(err, method, result, client_id) - on_callback = function(...) - eq(table.remove(expected_callbacks), {...}) + -- on_handler(err, method, result, client_id) + on_handler = function(...) + eq(table.remove(expected_handlers), {...}) end; } end) it('should fail', function() - local expected_callbacks = { + local expected_handlers = { {NIL, "test", {}, 1}; } test_rpc_server { @@ -255,8 +255,8 @@ describe('LSP', function() assert_log(pesc([[assert_eq failed: left == "\"shutdown\"", right == "\"test\""]]), fake_lsp_logfile) end; - on_callback = function(...) - eq(table.remove(expected_callbacks), {...}, "expected callback") + on_handler = function(...) + eq(table.remove(expected_handlers), {...}, "expected handler") end; } end) @@ -266,7 +266,7 @@ describe('LSP', function() pending('hangs the build on openbsd #14028, re-enable with freeze timeout #14204') return end - local expected_callbacks = { + local expected_handlers = { {NIL, "shutdown", {}, 1, NIL}; {NIL, "test", {}, 1}; } @@ -282,14 +282,14 @@ describe('LSP', function() eq(0, code, "exit code", fake_lsp_logfile) eq(0, signal, "exit signal", fake_lsp_logfile) end; - on_callback = function(...) - eq(table.remove(expected_callbacks), {...}, "expected callback") + on_handler = function(...) + eq(table.remove(expected_handlers), {...}, "expected handler") end; } end) it('client should return settings via workspace/configuration handler', function() - local expected_callbacks = { + local expected_handlers = { {NIL, "shutdown", {}, 1}; {NIL, "workspace/configuration", { items = { { section = "testSetting1" }; @@ -307,8 +307,8 @@ describe('LSP', function() eq(0, code, "exit code", fake_lsp_logfile) eq(0, signal, "exit signal", fake_lsp_logfile) end; - on_callback = function(err, method, params, client_id) - eq(table.remove(expected_callbacks), {err, method, params, client_id}, "expected callback") + on_handler = function(err, method, params, client_id) + eq(table.remove(expected_handlers), {err, method, params, client_id}, "expected handler") if method == 'start' then exec_lua([=[ local client = vim.lsp.get_client_by_id(TEST_RPC_CLIENT_ID) @@ -344,7 +344,7 @@ describe('LSP', function() end) it('should verify capabilities sent', function() - local expected_callbacks = { + local expected_handlers = { {NIL, "shutdown", {}, 1}; } test_rpc_server { @@ -361,14 +361,14 @@ describe('LSP', function() eq(0, code, "exit code", fake_lsp_logfile) eq(0, signal, "exit signal", fake_lsp_logfile) end; - on_callback = function(...) - eq(table.remove(expected_callbacks), {...}, "expected callback") + on_handler = function(...) + eq(table.remove(expected_handlers), {...}, "expected handler") end; } end) it('client.supports_methods() should validate capabilities', function() - local expected_callbacks = { + local expected_handlers = { {NIL, "shutdown", {}, 1}; } test_rpc_server { @@ -395,14 +395,14 @@ describe('LSP', function() eq(0, code, "exit code", fake_lsp_logfile) eq(0, signal, "exit signal", fake_lsp_logfile) end; - on_callback = function(...) - eq(table.remove(expected_callbacks), {...}, "expected callback") + on_handler = function(...) + eq(table.remove(expected_handlers), {...}, "expected handler") end; } end) it('should call unsupported_method when trying to call an unsupported method', function() - local expected_callbacks = { + local expected_handlers = { {NIL, "shutdown", {}, 1}; } test_rpc_server { @@ -412,7 +412,7 @@ describe('LSP', function() BUFFER = vim.api.nvim_get_current_buf() lsp.buf_attach_client(BUFFER, TEST_RPC_CLIENT_ID) vim.lsp.handlers['textDocument/typeDefinition'] = function(err, method) - vim.lsp._last_lsp_callback = { err = err; method = method } + vim.lsp._last_lsp_handler = { err = err; method = method } end vim.lsp._unsupported_method = function(method) vim.lsp._last_unsupported_method = method @@ -425,7 +425,7 @@ describe('LSP', function() client.stop() local method = exec_lua("return vim.lsp._last_unsupported_method") eq("textDocument/typeDefinition", method) - local lsp_cb_call = exec_lua("return vim.lsp._last_lsp_callback") + local lsp_cb_call = exec_lua("return vim.lsp._last_lsp_handler") eq("fake-error", lsp_cb_call.err) eq("textDocument/typeDefinition", lsp_cb_call.method) exec_lua [[ @@ -436,14 +436,14 @@ describe('LSP', function() eq(0, code, "exit code", fake_lsp_logfile) eq(0, signal, "exit signal", fake_lsp_logfile) end; - on_callback = function(...) - eq(table.remove(expected_callbacks), {...}, "expected callback") + on_handler = function(...) + eq(table.remove(expected_handlers), {...}, "expected handler") end; } end) it('shouldn\'t call unsupported_method when no client and trying to call an unsupported method', function() - local expected_callbacks = { + local expected_handlers = { {NIL, "shutdown", {}, 1}; } test_rpc_server { @@ -451,7 +451,7 @@ describe('LSP', function() on_setup = function() exec_lua([=[ vim.lsp.handlers['textDocument/typeDefinition'] = function(err, method) - vim.lsp._last_lsp_callback = { err = err; method = method } + vim.lsp._last_lsp_handler = { err = err; method = method } end vim.lsp._unsupported_method = function(method) vim.lsp._last_unsupported_method = method @@ -463,20 +463,20 @@ describe('LSP', function() on_init = function(client) client.stop() eq(NIL, exec_lua("return vim.lsp._last_unsupported_method")) - eq(NIL, exec_lua("return vim.lsp._last_lsp_callback")) + eq(NIL, exec_lua("return vim.lsp._last_lsp_handler")) end; on_exit = function(code, signal) eq(0, code, "exit code", fake_lsp_logfile) eq(0, signal, "exit signal", fake_lsp_logfile) end; - on_callback = function(...) - eq(table.remove(expected_callbacks), {...}, "expected callback") + on_handler = function(...) + eq(table.remove(expected_handlers), {...}, "expected handler") end; } end) it('should not send didOpen if the buffer closes before init', function() - local expected_callbacks = { + local expected_handlers = { {NIL, "shutdown", {}, 1}; {NIL, "finish", {}, 1}; } @@ -509,8 +509,8 @@ describe('LSP', function() eq(0, code, "exit code", fake_lsp_logfile) eq(0, signal, "exit signal", fake_lsp_logfile) end; - on_callback = function(err, method, params, client_id) - eq(table.remove(expected_callbacks), {err, method, params, client_id}, "expected callback") + on_handler = function(err, method, params, client_id) + eq(table.remove(expected_handlers), {err, method, params, client_id}, "expected handler") if method == 'finish' then client.stop() end @@ -519,7 +519,7 @@ describe('LSP', function() end) it('should check the body sent attaching before init', function() - local expected_callbacks = { + local expected_handlers = { {NIL, "shutdown", {}, 1}; {NIL, "finish", {}, 1}; {NIL, "start", {}, 1}; @@ -552,11 +552,11 @@ describe('LSP', function() eq(0, code, "exit code", fake_lsp_logfile) eq(0, signal, "exit signal", fake_lsp_logfile) end; - on_callback = function(err, method, params, client_id) + on_handler = function(err, method, params, client_id) if method == 'start' then client.notify('finish') end - eq(table.remove(expected_callbacks), {err, method, params, client_id}, "expected callback") + eq(table.remove(expected_handlers), {err, method, params, client_id}, "expected handler") if method == 'finish' then client.stop() end @@ -565,7 +565,7 @@ describe('LSP', function() end) it('should check the body sent attaching after init', function() - local expected_callbacks = { + local expected_handlers = { {NIL, "shutdown", {}, 1}; {NIL, "finish", {}, 1}; {NIL, "start", {}, 1}; @@ -595,11 +595,11 @@ describe('LSP', function() eq(0, code, "exit code", fake_lsp_logfile) eq(0, signal, "exit signal", fake_lsp_logfile) end; - on_callback = function(err, method, params, client_id) + on_handler = function(err, method, params, client_id) if method == 'start' then client.notify('finish') end - eq(table.remove(expected_callbacks), {err, method, params, client_id}, "expected callback") + eq(table.remove(expected_handlers), {err, method, params, client_id}, "expected handler") if method == 'finish' then client.stop() end @@ -608,7 +608,7 @@ describe('LSP', function() end) it('should check the body and didChange full', function() - local expected_callbacks = { + local expected_handlers = { {NIL, "shutdown", {}, 1}; {NIL, "finish", {}, 1}; {NIL, "start", {}, 1}; @@ -638,7 +638,7 @@ describe('LSP', function() eq(0, code, "exit code", fake_lsp_logfile) eq(0, signal, "exit signal", fake_lsp_logfile) end; - on_callback = function(err, method, params, client_id) + on_handler = function(err, method, params, client_id) if method == 'start' then exec_lua [[ vim.api.nvim_buf_set_lines(BUFFER, 1, 2, false, { @@ -647,7 +647,7 @@ describe('LSP', function() ]] client.notify('finish') end - eq(table.remove(expected_callbacks), {err, method, params, client_id}, "expected callback") + eq(table.remove(expected_handlers), {err, method, params, client_id}, "expected handler") if method == 'finish' then client.stop() end @@ -656,7 +656,7 @@ describe('LSP', function() end) it('should check the body and didChange full with noeol', function() - local expected_callbacks = { + local expected_handlers = { {NIL, "shutdown", {}, 1}; {NIL, "finish", {}, 1}; {NIL, "start", {}, 1}; @@ -687,7 +687,7 @@ describe('LSP', function() eq(0, code, "exit code", fake_lsp_logfile) eq(0, signal, "exit signal", fake_lsp_logfile) end; - on_callback = function(err, method, params, client_id) + on_handler = function(err, method, params, client_id) if method == 'start' then exec_lua [[ vim.api.nvim_buf_set_lines(BUFFER, 1, 2, false, { @@ -696,7 +696,7 @@ describe('LSP', function() ]] client.notify('finish') end - eq(table.remove(expected_callbacks), {err, method, params, client_id}, "expected callback") + eq(table.remove(expected_handlers), {err, method, params, client_id}, "expected handler") if method == 'finish' then client.stop() end @@ -705,7 +705,7 @@ describe('LSP', function() end) it('should check the body and didChange incremental', function() - local expected_callbacks = { + local expected_handlers = { {NIL, "shutdown", {}, 1}; {NIL, "finish", {}, 1}; {NIL, "start", {}, 1}; @@ -736,7 +736,7 @@ describe('LSP', function() eq(0, code, "exit code", fake_lsp_logfile) eq(0, signal, "exit signal", fake_lsp_logfile) end; - on_callback = function(err, method, params, client_id) + on_handler = function(err, method, params, client_id) if method == 'start' then exec_lua [[ vim.api.nvim_buf_set_lines(BUFFER, 1, 2, false, { @@ -745,7 +745,7 @@ describe('LSP', function() ]] client.notify('finish') end - eq(table.remove(expected_callbacks), {err, method, params, client_id}, "expected callback") + eq(table.remove(expected_handlers), {err, method, params, client_id}, "expected handler") if method == 'finish' then client.stop() end @@ -755,7 +755,7 @@ describe('LSP', function() -- TODO(askhan) we don't support full for now, so we can disable these tests. pending('should check the body and didChange incremental normal mode editing', function() - local expected_callbacks = { + local expected_handlers = { {NIL, "shutdown", {}, 1}; {NIL, "finish", {}, 1}; {NIL, "start", {}, 1}; @@ -785,12 +785,12 @@ describe('LSP', function() eq(0, code, "exit code", fake_lsp_logfile) eq(0, signal, "exit signal", fake_lsp_logfile) end; - on_callback = function(err, method, params, client_id) + on_handler = function(err, method, params, client_id) if method == 'start' then helpers.command("normal! 1Go") client.notify('finish') end - eq(table.remove(expected_callbacks), {err, method, params, client_id}, "expected callback") + eq(table.remove(expected_handlers), {err, method, params, client_id}, "expected handler") if method == 'finish' then client.stop() end @@ -799,7 +799,7 @@ describe('LSP', function() end) it('should check the body and didChange full with 2 changes', function() - local expected_callbacks = { + local expected_handlers = { {NIL, "shutdown", {}, 1}; {NIL, "finish", {}, 1}; {NIL, "start", {}, 1}; @@ -829,7 +829,7 @@ describe('LSP', function() eq(0, code, "exit code", fake_lsp_logfile) eq(0, signal, "exit signal", fake_lsp_logfile) end; - on_callback = function(err, method, params, client_id) + on_handler = function(err, method, params, client_id) if method == 'start' then exec_lua [[ vim.api.nvim_buf_set_lines(BUFFER, 1, 2, false, { @@ -841,7 +841,7 @@ describe('LSP', function() ]] client.notify('finish') end - eq(table.remove(expected_callbacks), {err, method, params, client_id}, "expected callback") + eq(table.remove(expected_handlers), {err, method, params, client_id}, "expected handler") if method == 'finish' then client.stop() end @@ -850,7 +850,7 @@ describe('LSP', function() end) it('should check the body and didChange full lifecycle', function() - local expected_callbacks = { + local expected_handlers = { {NIL, "shutdown", {}, 1}; {NIL, "finish", {}, 1}; {NIL, "start", {}, 1}; @@ -880,7 +880,7 @@ describe('LSP', function() eq(0, code, "exit code", fake_lsp_logfile) eq(0, signal, "exit signal", fake_lsp_logfile) end; - on_callback = function(err, method, params, client_id) + on_handler = function(err, method, params, client_id) if method == 'start' then exec_lua [[ vim.api.nvim_buf_set_lines(BUFFER, 1, 2, false, { @@ -893,7 +893,7 @@ describe('LSP', function() ]] client.notify('finish') end - eq(table.remove(expected_callbacks), {err, method, params, client_id}, "expected callback") + eq(table.remove(expected_handlers), {err, method, params, client_id}, "expected handler") if method == 'finish' then client.stop() end @@ -904,7 +904,7 @@ describe('LSP', function() describe("parsing tests", function() it('should handle invalid content-length correctly', function() - local expected_callbacks = { + local expected_handlers = { {NIL, "shutdown", {}, 1}; {NIL, "finish", {}, 1}; {NIL, "start", {}, 1}; @@ -923,7 +923,49 @@ describe('LSP', function() eq(0, signal, "exit signal", fake_lsp_logfile) end; on_handler = function(err, method, params, client_id) - eq(table.remove(expected_callbacks), {err, method, params, client_id}, "expected handler") + eq(table.remove(expected_handlers), {err, method, params, client_id}, "expected handler") + end; + } + end) + + it('should not trim vim.NIL from the end of a list', function() + local expected_handlers = { + {NIL, "shutdown", {}, 1}; + {NIL, "finish", {}, 1}; + {NIL, "workspace/executeCommand", { + arguments = { "EXTRACT_METHOD", {metadata = {}}, 3, 0, 6123, NIL }, + command = "refactor.perform", + title = "EXTRACT_METHOD" + }, 1}; + {NIL, "start", {}, 1}; + } + local client + test_rpc_server { + test_name = "decode_nil"; + on_setup = function() + exec_lua [[ + BUFFER = vim.api.nvim_create_buf(false, true) + vim.api.nvim_buf_set_lines(BUFFER, 0, -1, false, { + "testing"; + "123"; + }) + ]] + end; + on_init = function(_client) + client = _client + exec_lua [[ + assert(lsp.buf_attach_client(BUFFER, TEST_RPC_CLIENT_ID)) + ]] + end; + on_exit = function(code, signal) + eq(0, code, "exit code", fake_lsp_logfile) + eq(0, signal, "exit signal", fake_lsp_logfile) + end; + on_handler = function(err, method, params, client_id) + eq(table.remove(expected_handlers), {err, method, params, client_id}, "expected handler") + if method == 'finish' then + client.stop() + end end; } end) diff --git a/test/functional/ui/float_spec.lua b/test/functional/ui/float_spec.lua index f3b840da21..9fa0ad08f1 100644 --- a/test/functional/ui/float_spec.lua +++ b/test/functional/ui/float_spec.lua @@ -711,6 +711,49 @@ describe('float window', function() ]]} end + meths.win_set_config(win, {border="rounded"}) + if multigrid then + screen:expect{grid=[[ + ## grid 1 + [2:----------------------------------------]| + [2:----------------------------------------]| + [2:----------------------------------------]| + [2:----------------------------------------]| + [2:----------------------------------------]| + [2:----------------------------------------]| + [3:----------------------------------------]| + ## grid 2 + ^ | + {0:~ }| + {0:~ }| + {0:~ }| + {0:~ }| + {0:~ }| + ## grid 3 + | + ## grid 5 + {5:╭─────────╮}| + {5:│}{1: halloj! }{5:│}| + {5:│}{1: BORDAA }{5:│}| + {5:╰─────────╯}| + ]], float_pos={ + [5] = { { id = 1002 }, "NW", 1, 2, 5, true } + }, win_viewport={ + [2] = {win = {id = 1000}, topline = 0, botline = 2, curline = 0, curcol = 0}; + [5] = {win = {id = 1002}, topline = 0, botline = 2, curline = 0, curcol = 0}; + }} + else + screen:expect{grid=[[ + ^ | + {0:~ }| + {0:~ }{5:╭─────────╮}{0: }| + {0:~ }{5:│}{1: halloj! }{5:│}{0: }| + {0:~ }{5:│}{1: BORDAA }{5:│}{0: }| + {0:~ }{5:╰─────────╯}{0: }| + | + ]]} + end + meths.win_set_config(win, {border="solid"}) if multigrid then screen:expect{grid=[[ @@ -2901,6 +2944,53 @@ describe('float window', function() end end) + it('command menu rendered above cursor (pum_above)', function() + command('set wildmenu wildmode=longest:full wildoptions=pum') + feed(':sign u<tab>') + if multigrid then + screen:expect{grid=[[ + ## grid 1 + [2:----------------------------------------]| + [2:----------------------------------------]| + [2:----------------------------------------]| + [2:----------------------------------------]| + [2:----------------------------------------]| + [2:----------------------------------------]| + [3:----------------------------------------]| + ## grid 2 + | + {0:~ }| + {0:~ }| + {0:~ }| + {0:~ }| + {0:~ }| + ## grid 3 + :sign un^ | + ## grid 4 + {7: }| + {12:~ }| + {12:~ }| + {12:~ }| + ## grid 5 + {1: undefine }| + {1: unplace }| + ]], float_pos={ + [5] = {{id = -1}, "SW", 1, 6, 5, false, 250}; + [4] = {{id = 1001}, "NW", 1, 2, 5, true, 50}; + }} + else + screen:expect{grid=[[ + | + {0:~ }| + {0:~ }{7: }{0: }| + {0:~ }{12:~ }{0: }| + {0:~ }{1: undefine }{0: }| + {0:~ }{1: unplace }{0: }| + :sign un^ | + ]]} + end + end) + it('with ext_popupmenu', function() screen:set_option('ext_popupmenu', true) feed('ix ') diff --git a/test/functional/ui/messages_spec.lua b/test/functional/ui/messages_spec.lua index 72468392ee..c238898244 100644 --- a/test/functional/ui/messages_spec.lua +++ b/test/functional/ui/messages_spec.lua @@ -811,7 +811,7 @@ describe('ui/ext_messages', function() {1:~ }| {1:^~ }| ]], messages={ - {content = { { 'Change "helllo" to:\n 1 "Hello"\n 2 "Hallo"\n 3 "Helli"\nType number and <Enter> or click with the mouse (q or empty cancels): ' } }, kind = ""} + {content = { { 'Change "helllo" to:\n 1 "Hello"\n 2 "Hallo"\n 3 "Hullo"\nType number and <Enter> or click with the mouse (q or empty cancels): ' } }, kind = ""} }} feed('1') @@ -822,7 +822,7 @@ describe('ui/ext_messages', function() {1:~ }| {1:^~ }| ]], messages={ - {content = { { 'Change "helllo" to:\n 1 "Hello"\n 2 "Hallo"\n 3 "Helli"\nType number and <Enter> or click with the mouse (q or empty cancels): ' } }, kind = ""}, + {content = { { 'Change "helllo" to:\n 1 "Hello"\n 2 "Hallo"\n 3 "Hullo"\nType number and <Enter> or click with the mouse (q or empty cancels): ' } }, kind = ""}, { content = { { "1" } }, kind = "" } }} diff --git a/test/functional/ui/spell_spec.lua b/test/functional/ui/spell_spec.lua index 2c6e586665..de77100cc0 100644 --- a/test/functional/ui/spell_spec.lua +++ b/test/functional/ui/spell_spec.lua @@ -36,7 +36,7 @@ describe("'spell'", function() feed('ggJJJJJJ0') screen:expect([[ {1:^Lorem} {1:ipsum} dolor sit {1:amet}, {1:consectetur} {1:adipiscing} {1:elit}, {1:sed} do {1:eiusmod} {1:tempor} {1:i}| - {1:ncididunt} {1:ut} {1:labore} {1:et} {1:dolore} {1:magna} {1:aliqua}. {1:Ut} {1:enim} ad minim {1:veniam}, {1:quis} {1:nostru}| + {1:ncididunt} {1:ut} {1:labore} et {1:dolore} {1:magna} {1:aliqua}. {1:Ut} {1:enim} ad minim {1:veniam}, {1:quis} {1:nostru}| {1:d} {1:exercitation} {1:ullamco} {1:laboris} {1:nisi} {1:ut} {1:aliquip} ex ea {1:commodo} {1:consequat}. {1:Duis} {1:aut}| {1:e} {1:irure} dolor in {1:reprehenderit} in {1:voluptate} {1:velit} {1:esse} {1:cillum} {1:dolore} {1:eu} {1:fugiat} {1:n}| {1:ulla} {1:pariatur}. {1:Excepteur} {1:sint} {1:occaecat} {1:cupidatat} non {1:proident}, {1:sunt} in culpa {1:qui}| @@ -44,6 +44,7 @@ describe("'spell'", function() {0:~ }| | ]]) + end) it('has correct highlight at start of line', function() diff --git a/test/functional/ui/tabline_spec.lua b/test/functional/ui/tabline_spec.lua index 23aae81745..ab8d63cda1 100644 --- a/test/functional/ui/tabline_spec.lua +++ b/test/functional/ui/tabline_spec.lua @@ -4,14 +4,17 @@ local clear, command, eq = helpers.clear, helpers.command, helpers.eq describe('ui/ext_tabline', function() local screen - local event_tabs, event_curtab + local event_tabs, event_curtab, event_curbuf, event_buffers before_each(function() clear() screen = Screen.new(25, 5) screen:attach({rgb=true, ext_tabline=true}) - function screen:_handle_tabline_update(curtab, tabs) - event_curtab, event_tabs = curtab, tabs + function screen:_handle_tabline_update(curtab, tabs, curbuf, buffers) + event_curtab = curtab + event_tabs = tabs + event_curbuf = curbuf + event_buffers = buffers end end) @@ -45,4 +48,38 @@ describe('ui/ext_tabline', function() eq(expected_tabs, event_tabs) end} end) + + it('buffer UI events', function() + local expected_buffers_initial= { + {buffer = { id = 1 }, name = '[No Name]'}, + } + + screen:expect{grid=[[ + ^ | + ~ | + ~ | + ~ | + | + ]], condition=function() + eq({ id = 1}, event_curbuf) + eq(expected_buffers_initial, event_buffers) + end} + + command("badd another-buffer") + command("bnext") + + local expected_buffers = { + {buffer = { id = 2 }, name = 'another-buffer'}, + } + screen:expect{grid=[[ + ^ | + ~ | + ~ | + ~ | + | + ]], condition=function() + eq({ id = 2 }, event_curbuf) + eq(expected_buffers, event_buffers) + end} + end) end) diff --git a/test/unit/eval/typval_spec.lua b/test/unit/eval/typval_spec.lua index 7c03005529..d81e272877 100644 --- a/test/unit/eval/typval_spec.lua +++ b/test/unit/eval/typval_spec.lua @@ -2623,7 +2623,7 @@ describe('typval.c', function() describe('check_lock()', function() local function tv_check_lock(lock, name, name_len, emsg) return check_emsg(function() - return lib.tv_check_lock(lock, name, name_len) + return lib.var_check_lock(lock, name, name_len) end, emsg) end itp('works', function() diff --git a/test/unit/marktree_spec.lua b/test/unit/marktree_spec.lua index 56acc0f93e..cd9c7bef13 100644 --- a/test/unit/marktree_spec.lua +++ b/test/unit/marktree_spec.lua @@ -186,5 +186,20 @@ describe('marktree', function() lib.marktree_check(tree) shadoworder(tree, shadow, iter2) end + + -- Check iterator validity for 2 specific edge cases: + -- https://github.com/neovim/neovim/pull/14719 + lib.marktree_clear(tree) + for i = 1,20 do + lib.marktree_put(tree, i, i, false) + end + + lib.marktree_itr_get(tree, 10, 10, iter) + lib.marktree_del_itr(tree, iter, false) + eq(11, iter[0].node.key[iter[0].i].pos.col) + + lib.marktree_itr_get(tree, 11, 11, iter) + lib.marktree_del_itr(tree, iter, false) + eq(12, iter[0].node.key[iter[0].i].pos.col) end) end) |