From 1037ce2e461034a20e35ad59969fd05d5ad68b91 Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Sat, 9 Dec 2023 20:42:00 +0800 Subject: test: avoid repeated screen lines in expected states This is the command invoked repeatedly to make the changes: :%s/^\(.*\)|\%(\*\(\d\+\)\)\?$\n\1|\%(\*\(\d\+\)\)\?$/\=submatch(1)..'|*'..(max([str2nr(submatch(2)),1])+max([str2nr(submatch(3)),1]))/g --- test/functional/lua/vim_spec.lua | 16 ++++------------ 1 file changed, 4 insertions(+), 12 deletions(-) (limited to 'test/functional/lua/vim_spec.lua') diff --git a/test/functional/lua/vim_spec.lua b/test/functional/lua/vim_spec.lua index ebe5fc254e..1ef214d611 100644 --- a/test/functional/lua/vim_spec.lua +++ b/test/functional/lua/vim_spec.lua @@ -271,9 +271,7 @@ describe('lua stdlib', function() screen:attach() screen:expect{grid=[[ ^ | - {1:~ }| - {1:~ }| - {1:~ }| + {1:~ }|*3 | ]]} @@ -2798,25 +2796,19 @@ describe('lua stdlib', function() screen:attach() screen:expect{grid=[[ ^ | - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*3 | ]]} exec_lua [[vim.notify_once("I'll only tell you this once...", vim.log.levels.WARN)]] screen:expect{grid=[[ ^ | - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*3 {1:I'll only tell you this once...} | ]]} feed('') screen:expect{grid=[[ ^ | - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*3 | ]]} exec_lua [[vim.notify_once("I'll only tell you this once...")]] -- cgit From 1d4a5cd18537d054a564ff19b9361120597d9dd7 Mon Sep 17 00:00:00 2001 From: Raphael Date: Tue, 12 Dec 2023 19:06:22 +0800 Subject: feat(eval): exists() function supports checking v:lua functions (#26485) Problem: Vimscript function exists() can't check v:lua functions. Solution: Add support for v:lua functions to exists(). --- test/functional/lua/vim_spec.lua | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) (limited to 'test/functional/lua/vim_spec.lua') diff --git a/test/functional/lua/vim_spec.lua b/test/functional/lua/vim_spec.lua index 1ef214d611..403e9f6a12 100644 --- a/test/functional/lua/vim_spec.lua +++ b/test/functional/lua/vim_spec.lua @@ -3352,4 +3352,31 @@ describe('vim.keymap', function() eq(1, exec_lua[[return GlobalCount]]) end) + it('exists() can check a lua function', function() + eq(true, exec_lua[[ + _G.test = function() print("hello") end + return vim.fn.exists('v:lua.test') == 1 + ]]) + + eq(true, exec_lua[[ + return vim.fn.exists('v:lua.require("mpack").decode') == 1 + ]]) + + eq(true, exec_lua[[ + return vim.fn.exists("v:lua.require('vim.lsp').start") == 1 + ]]) + + eq(true, exec_lua[[ + return vim.fn.exists('v:lua.require"vim.lsp".start') == 1 + ]]) + + eq(true, exec_lua[[ + return vim.fn.exists("v:lua.require'vim.lsp'.start") == 1 + ]]) + + eq(false, exec_lua[[ + return vim.fn.exists("v:lua.require'vim.lsp'.unknown") == 1 + ]]) + end) + end) -- cgit From b40170f7a3ca4bd157eeb52c9d57cb2ebfe3c562 Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Tue, 12 Dec 2023 20:34:02 +0800 Subject: fix(lua): memory leak when using invalid syntax with exists() (#26530) --- test/functional/lua/vim_spec.lua | 37 ++++++++++++++----------------------- 1 file changed, 14 insertions(+), 23 deletions(-) (limited to 'test/functional/lua/vim_spec.lua') diff --git a/test/functional/lua/vim_spec.lua b/test/functional/lua/vim_spec.lua index 403e9f6a12..509958bbde 100644 --- a/test/functional/lua/vim_spec.lua +++ b/test/functional/lua/vim_spec.lua @@ -3351,32 +3351,23 @@ describe('vim.keymap', function() eq(1, exec_lua[[return GlobalCount]]) end) +end) - it('exists() can check a lua function', function() - eq(true, exec_lua[[ +describe('Vimscript function exists()', function() + it('can check a lua function', function() + eq(1, exec_lua[[ _G.test = function() print("hello") end - return vim.fn.exists('v:lua.test') == 1 - ]]) - - eq(true, exec_lua[[ - return vim.fn.exists('v:lua.require("mpack").decode') == 1 + return vim.fn.exists('v:lua.test') ]]) - eq(true, exec_lua[[ - return vim.fn.exists("v:lua.require('vim.lsp').start") == 1 - ]]) - - eq(true, exec_lua[[ - return vim.fn.exists('v:lua.require"vim.lsp".start') == 1 - ]]) - - eq(true, exec_lua[[ - return vim.fn.exists("v:lua.require'vim.lsp'.start") == 1 - ]]) - - eq(false, exec_lua[[ - return vim.fn.exists("v:lua.require'vim.lsp'.unknown") == 1 - ]]) + eq(1, funcs.exists('v:lua.require("mpack").decode')) + eq(1, funcs.exists("v:lua.require('mpack').decode")) + eq(1, funcs.exists('v:lua.require"mpack".decode')) + eq(1, funcs.exists("v:lua.require'mpack'.decode")) + eq(1, funcs.exists("v:lua.require('vim.lsp').start")) + eq(1, funcs.exists('v:lua.require"vim.lsp".start')) + eq(1, funcs.exists("v:lua.require'vim.lsp'.start")) + eq(0, funcs.exists("v:lua.require'vim.lsp'.unknown")) + eq(0, funcs.exists('v:lua.?')) end) - end) -- cgit From 0a598c13b1863ba1aff378027c4376e3ab7048ee Mon Sep 17 00:00:00 2001 From: dundargoc Date: Mon, 25 Dec 2023 16:31:38 +0100 Subject: feat(vim.deprecate): only issue warning if neovim version is high enough As specified by MAINTAIN.md, features should be soft deprecated at first (meaning no warnings) to give people a chance to adjust. The problem with this approach is that deprecating a feature becomes harder than usual as during the soft deprecation period you need to remember not to issue a warning, and during the hard deprecation period you need to remember to start issuing a warning. This behavior is only enforced if the `plugin` parameter is `nil` as plugins may not want this specific behavior. --- test/functional/lua/vim_spec.lua | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'test/functional/lua/vim_spec.lua') diff --git a/test/functional/lua/vim_spec.lua b/test/functional/lua/vim_spec.lua index 509958bbde..e017ea7670 100644 --- a/test/functional/lua/vim_spec.lua +++ b/test/functional/lua/vim_spec.lua @@ -132,11 +132,13 @@ describe('lua stdlib', function() -- vim.deprecate(name, alternative, version, plugin, backtrace) eq(dedent[[ foo.bar() is deprecated, use zub.wooo{ok=yay} instead. :help deprecated - This feature will be removed in Nvim version 2.17]], - exec_lua('return vim.deprecate(...)', 'foo.bar()', 'zub.wooo{ok=yay}', '2.17')) + This feature will be removed in Nvim version 0.10]], + exec_lua('return vim.deprecate(...)', 'foo.bar()', 'zub.wooo{ok=yay}', '0.10')) -- Same message, skipped. eq(vim.NIL, - exec_lua('return vim.deprecate(...)', 'foo.bar()', 'zub.wooo{ok=yay}', '2.17')) + exec_lua('return vim.deprecate(...)', 'foo.bar()', 'zub.wooo{ok=yay}', '0.10')) + -- Don't show error if not hard deprecated + eq(vim.NIL, exec_lua('return vim.deprecate(...)', 'foo.bar()', 'nil', '5000.0.0')) -- When `plugin` is specified, don't show ":help deprecated". #22235 eq(dedent[[ foo.bar() is deprecated, use zub.wooo{ok=yay} instead. -- cgit From 04f2f864e270e772c6326cefdf24947f0130e492 Mon Sep 17 00:00:00 2001 From: "Justin M. Keyes" Date: Wed, 3 Jan 2024 02:09:18 +0100 Subject: refactor: format test/* --- test/functional/lua/vim_spec.lua | 1909 +++++++++++++++++++++++++------------- 1 file changed, 1274 insertions(+), 635 deletions(-) (limited to 'test/functional/lua/vim_spec.lua') diff --git a/test/functional/lua/vim_spec.lua b/test/functional/lua/vim_spec.lua index e017ea7670..4ebba827ef 100644 --- a/test/functional/lua/vim_spec.lua +++ b/test/functional/lua/vim_spec.lua @@ -130,20 +130,30 @@ describe('lua stdlib', function() it('vim.deprecate', function() -- vim.deprecate(name, alternative, version, plugin, backtrace) - eq(dedent[[ + eq( + dedent [[ foo.bar() is deprecated, use zub.wooo{ok=yay} instead. :help deprecated This feature will be removed in Nvim version 0.10]], - exec_lua('return vim.deprecate(...)', 'foo.bar()', 'zub.wooo{ok=yay}', '0.10')) + exec_lua('return vim.deprecate(...)', 'foo.bar()', 'zub.wooo{ok=yay}', '0.10') + ) -- Same message, skipped. - eq(vim.NIL, - exec_lua('return vim.deprecate(...)', 'foo.bar()', 'zub.wooo{ok=yay}', '0.10')) + eq(vim.NIL, exec_lua('return vim.deprecate(...)', 'foo.bar()', 'zub.wooo{ok=yay}', '0.10')) -- Don't show error if not hard deprecated eq(vim.NIL, exec_lua('return vim.deprecate(...)', 'foo.bar()', 'nil', '5000.0.0')) -- When `plugin` is specified, don't show ":help deprecated". #22235 - eq(dedent[[ + eq( + dedent [[ foo.bar() is deprecated, use zub.wooo{ok=yay} instead. This feature will be removed in my-plugin.nvim version 0.3.0]], - exec_lua('return vim.deprecate(...)', 'foo.bar()', 'zub.wooo{ok=yay}', '0.3.0', 'my-plugin.nvim', false)) + exec_lua( + 'return vim.deprecate(...)', + 'foo.bar()', + 'zub.wooo{ok=yay}', + '0.3.0', + 'my-plugin.nvim', + false + ) + ) end) it('vim.startswith', function() @@ -156,10 +166,11 @@ describe('lua stdlib', function() eq(false, funcs.luaeval('vim.startswith("123", "2")')) eq(false, funcs.luaeval('vim.startswith("123", "1234")')) - matches("prefix: expected string, got nil", - pcall_err(exec_lua, 'return vim.startswith("123", nil)')) - matches("s: expected string, got nil", - pcall_err(exec_lua, 'return vim.startswith(nil, "123")')) + matches( + 'prefix: expected string, got nil', + pcall_err(exec_lua, 'return vim.startswith("123", nil)') + ) + matches('s: expected string, got nil', pcall_err(exec_lua, 'return vim.startswith(nil, "123")')) end) it('vim.endswith', function() @@ -172,73 +183,275 @@ describe('lua stdlib', function() eq(false, funcs.luaeval('vim.endswith("123", "2")')) eq(false, funcs.luaeval('vim.endswith("123", "1234")')) - matches("suffix: expected string, got nil", - pcall_err(exec_lua, 'return vim.endswith("123", nil)')) - matches("s: expected string, got nil", - pcall_err(exec_lua, 'return vim.endswith(nil, "123")')) + matches( + 'suffix: expected string, got nil', + pcall_err(exec_lua, 'return vim.endswith("123", nil)') + ) + matches('s: expected string, got nil', pcall_err(exec_lua, 'return vim.endswith(nil, "123")')) end) - it("vim.str_utfindex/str_byteindex", function() + it('vim.str_utfindex/str_byteindex', function() exec_lua([[_G.test_text = "xy åäö ɧ 汉语 ↥ 🤦x🦄 å بِيَّ\000ъ"]]) - local indices32 = {[0]=0,1,2,3,5,7,9,10,12,13,16,19,20,23,24,28,29,33,34,35,37,38,40,42,44,46,48,49,51} - local indices16 = {[0]=0,1,2,3,5,7,9,10,12,13,16,19,20,23,24,28,28,29,33,33,34,35,37,38,40,42,44,46,48,49,51} - for i,k in pairs(indices32) do - eq(k, exec_lua("return vim.str_byteindex(_G.test_text, ...)", i), i) + local indices32 = { + [0] = 0, + 1, + 2, + 3, + 5, + 7, + 9, + 10, + 12, + 13, + 16, + 19, + 20, + 23, + 24, + 28, + 29, + 33, + 34, + 35, + 37, + 38, + 40, + 42, + 44, + 46, + 48, + 49, + 51, + } + local indices16 = { + [0] = 0, + 1, + 2, + 3, + 5, + 7, + 9, + 10, + 12, + 13, + 16, + 19, + 20, + 23, + 24, + 28, + 28, + 29, + 33, + 33, + 34, + 35, + 37, + 38, + 40, + 42, + 44, + 46, + 48, + 49, + 51, + } + for i, k in pairs(indices32) do + eq(k, exec_lua('return vim.str_byteindex(_G.test_text, ...)', i), i) end - for i,k in pairs(indices16) do - eq(k, exec_lua("return vim.str_byteindex(_G.test_text, ..., true)", i), i) + for i, k in pairs(indices16) do + eq(k, exec_lua('return vim.str_byteindex(_G.test_text, ..., true)', i), i) end - eq("index out of range", pcall_err(exec_lua, "return vim.str_byteindex(_G.test_text, ...)", #indices32 + 1)) - eq("index out of range", pcall_err(exec_lua, "return vim.str_byteindex(_G.test_text, ..., true)", #indices16 + 1)) + eq( + 'index out of range', + pcall_err(exec_lua, 'return vim.str_byteindex(_G.test_text, ...)', #indices32 + 1) + ) + eq( + 'index out of range', + pcall_err(exec_lua, 'return vim.str_byteindex(_G.test_text, ..., true)', #indices16 + 1) + ) local i32, i16 = 0, 0 local len = 51 - for k = 0,len do + for k = 0, len do if indices32[i32] < k then i32 = i32 + 1 end if indices16[i16] < k then i16 = i16 + 1 - if indices16[i16+1] == indices16[i16] then + if indices16[i16 + 1] == indices16[i16] then i16 = i16 + 1 end end - eq({i32, i16}, exec_lua("return {vim.str_utfindex(_G.test_text, ...)}", k), k) + eq({ i32, i16 }, exec_lua('return {vim.str_utfindex(_G.test_text, ...)}', k), k) end - eq("index out of range", pcall_err(exec_lua, "return vim.str_utfindex(_G.test_text, ...)", len + 1)) + eq( + 'index out of range', + pcall_err(exec_lua, 'return vim.str_utfindex(_G.test_text, ...)', len + 1) + ) end) - it("vim.str_utf_start", function() + it('vim.str_utf_start', function() exec_lua([[_G.test_text = "xy åäö ɧ 汉语 ↥ 🤦x🦄 å بِيَّ"]]) - local expected_positions = {0,0,0,0,-1,0,-1,0,-1,0,0,-1,0,0,-1,-2,0,-1,-2,0,0,-1,-2,0,0,-1,-2,-3,0,0,-1,-2,-3,0,0,0,-1,0,0,-1,0,-1,0,-1,0,-1,0,-1} - eq(expected_positions, exec_lua([[ + local expected_positions = { + 0, + 0, + 0, + 0, + -1, + 0, + -1, + 0, + -1, + 0, + 0, + -1, + 0, + 0, + -1, + -2, + 0, + -1, + -2, + 0, + 0, + -1, + -2, + 0, + 0, + -1, + -2, + -3, + 0, + 0, + -1, + -2, + -3, + 0, + 0, + 0, + -1, + 0, + 0, + -1, + 0, + -1, + 0, + -1, + 0, + -1, + 0, + -1, + } + eq( + expected_positions, + exec_lua([[ local start_codepoint_positions = {} for idx = 1, #_G.test_text do table.insert(start_codepoint_positions, vim.str_utf_start(_G.test_text, idx)) end return start_codepoint_positions - ]])) + ]]) + ) end) - it("vim.str_utf_end", function() + it('vim.str_utf_end', function() exec_lua([[_G.test_text = "xy åäö ɧ 汉语 ↥ 🤦x🦄 å بِيَّ"]]) - local expected_positions = {0,0,0,1,0,1,0,1,0,0,1,0,0,2,1,0,2,1,0,0,2,1,0,0,3,2,1,0,0,3,2,1,0,0,0,1,0,0,1,0,1,0,1,0,1,0,1,0 } - eq(expected_positions, exec_lua([[ + local expected_positions = { + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 2, + 1, + 0, + 2, + 1, + 0, + 0, + 2, + 1, + 0, + 0, + 3, + 2, + 1, + 0, + 0, + 3, + 2, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + 1, + 0, + } + eq( + expected_positions, + exec_lua([[ local end_codepoint_positions = {} for idx = 1, #_G.test_text do table.insert(end_codepoint_positions, vim.str_utf_end(_G.test_text, idx)) end return end_codepoint_positions - ]])) + ]]) + ) end) - - it("vim.str_utf_pos", function() + it('vim.str_utf_pos', function() exec_lua([[_G.test_text = "xy åäö ɧ 汉语 ↥ 🤦x🦄 å بِيَّ"]]) - local expected_positions = { 1,2,3,4,6,8,10,11,13,14,17,20,21,24,25,29,30,34,35,36,38,39,41,43,45,47 } - eq(expected_positions, exec_lua("return vim.str_utf_pos(_G.test_text)")) + local expected_positions = { + 1, + 2, + 3, + 4, + 6, + 8, + 10, + 11, + 13, + 14, + 17, + 20, + 21, + 24, + 25, + 29, + 30, + 34, + 35, + 36, + 38, + 39, + 41, + 43, + 45, + 47, + } + eq(expected_positions, exec_lua('return vim.str_utf_pos(_G.test_text)')) end) - it("vim.schedule", function() + it('vim.schedule', function() exec_lua([[ test_table = {} vim.schedule(function() @@ -246,13 +459,11 @@ describe('lua stdlib', function() end) table.insert(test_table, "yy") ]]) - eq({"yy","xx"}, exec_lua("return test_table")) + eq({ 'yy', 'xx' }, exec_lua('return test_table')) -- Validates args. - matches('vim.schedule: expected function', - pcall_err(exec_lua, "vim.schedule('stringly')")) - matches('vim.schedule: expected function', - pcall_err(exec_lua, "vim.schedule()")) + matches('vim.schedule: expected function', pcall_err(exec_lua, "vim.schedule('stringly')")) + matches('vim.schedule: expected function', pcall_err(exec_lua, 'vim.schedule()')) exec_lua([[ vim.schedule(function() @@ -260,22 +471,24 @@ describe('lua stdlib', function() end) ]]) - feed("") - matches('big failure\nvery async', remove_trace(eval("v:errmsg"))) + feed('') + matches('big failure\nvery async', remove_trace(eval('v:errmsg'))) - local screen = Screen.new(60,5) + local screen = Screen.new(60, 5) screen:set_default_attr_ids({ - [1] = {bold = true, foreground = Screen.colors.Blue1}, - [2] = {bold = true, reverse = true}, - [3] = {foreground = Screen.colors.Grey100, background = Screen.colors.Red}, - [4] = {bold = true, foreground = Screen.colors.SeaGreen4}, + [1] = { bold = true, foreground = Screen.colors.Blue1 }, + [2] = { bold = true, reverse = true }, + [3] = { foreground = Screen.colors.Grey100, background = Screen.colors.Red }, + [4] = { bold = true, foreground = Screen.colors.SeaGreen4 }, }) screen:attach() - screen:expect{grid=[[ + screen:expect { + grid = [[ ^ | {1:~ }|*3 | - ]]} + ]], + } -- nvim_command causes a Vimscript exception, check that it is properly caught -- and propagated as an error message in async contexts.. #10809 @@ -284,62 +497,61 @@ describe('lua stdlib', function() vim.api.nvim_command(":echo 'err") end) ]]) - screen:expect{grid=[[ + screen:expect { + grid = [[ {3:stack traceback:} | {3: [C]: in function 'nvim_command'} | {3: [string ""]:2: in function <[string ""]:}| {3:1>} | {4:Press ENTER or type command to continue}^ | - ]]} + ]], + } end) it('vim.gsplit, vim.split', function() local tests = { -- plain trimempty - { 'a,b', ',', false, false, { 'a', 'b' } }, - { ':aa::::bb:', ':', false, false, { '', 'aa', '', '', '', 'bb', '' } }, - { ':aa::::bb:', ':', false, true, { 'aa', '', '', '', 'bb' } }, - { 'aa::::bb:', ':', false, true, { 'aa', '', '', '', 'bb' } }, - { ':aa::bb:', ':', false, true, { 'aa', '', 'bb' } }, - { '/a/b:/b/\n', '[:\n]', false, true, { '/a/b', '/b/' } }, - { '::ee::ff:', ':', false, false, { '', '', 'ee', '', 'ff', '' } }, - { '::ee::ff::', ':', false, true, { 'ee', '', 'ff' } }, - { 'ab', '.', false, false, { '', '', '' } }, - { 'a1b2c', '[0-9]', false, false, { 'a', 'b', 'c' } }, - { 'xy', '', false, false, { 'x', 'y' } }, - { 'here be dragons', ' ', false, false, { 'here', 'be', 'dragons'} }, - { 'axaby', 'ab?', false, false, { '', 'x', 'y' } }, - { 'f v2v v3v w2w ', '([vw])2%1', false, false, { 'f ', ' v3v ', ' ' } }, - { '', '', false, false, {} }, - { '', '', false, true, {} }, - { '\n', '[:\n]', false, true, {} }, - { '', 'a', false, false, { '' } }, - { 'x*yz*oo*l', '*', true, false, { 'x', 'yz', 'oo', 'l' } }, + { 'a,b', ',', false, false, { 'a', 'b' } }, + { ':aa::::bb:', ':', false, false, { '', 'aa', '', '', '', 'bb', '' } }, + { ':aa::::bb:', ':', false, true, { 'aa', '', '', '', 'bb' } }, + { 'aa::::bb:', ':', false, true, { 'aa', '', '', '', 'bb' } }, + { ':aa::bb:', ':', false, true, { 'aa', '', 'bb' } }, + { '/a/b:/b/\n', '[:\n]', false, true, { '/a/b', '/b/' } }, + { '::ee::ff:', ':', false, false, { '', '', 'ee', '', 'ff', '' } }, + { '::ee::ff::', ':', false, true, { 'ee', '', 'ff' } }, + { 'ab', '.', false, false, { '', '', '' } }, + { 'a1b2c', '[0-9]', false, false, { 'a', 'b', 'c' } }, + { 'xy', '', false, false, { 'x', 'y' } }, + { 'here be dragons', ' ', false, false, { 'here', 'be', 'dragons' } }, + { 'axaby', 'ab?', false, false, { '', 'x', 'y' } }, + { 'f v2v v3v w2w ', '([vw])2%1', false, false, { 'f ', ' v3v ', ' ' } }, + { '', '', false, false, {} }, + { '', '', false, true, {} }, + { '\n', '[:\n]', false, true, {} }, + { '', 'a', false, false, { '' } }, + { 'x*yz*oo*l', '*', true, false, { 'x', 'yz', 'oo', 'l' } }, } for _, t in ipairs(tests) do - eq(t[5], vim.split(t[1], t[2], {plain=t[3], trimempty=t[4]}), t[1]) + eq(t[5], vim.split(t[1], t[2], { plain = t[3], trimempty = t[4] }), t[1]) end -- Test old signature - eq({'x', 'yz', 'oo', 'l'}, vim.split("x*yz*oo*l", "*", true)) + eq({ 'x', 'yz', 'oo', 'l' }, vim.split('x*yz*oo*l', '*', true)) local loops = { - { "abc", ".-" }, + { 'abc', '.-' }, } for _, t in ipairs(loops) do - matches("Infinite loop detected", pcall_err(vim.split, t[1], t[2])) + matches('Infinite loop detected', pcall_err(vim.split, t[1], t[2])) end -- Validates args. eq(true, pcall(vim.split, 'string', 'string')) - matches('s: expected string, got number', - pcall_err(vim.split, 1, 'string')) - matches('sep: expected string, got number', - pcall_err(vim.split, 'string', 1)) - matches('opts: expected table, got number', - pcall_err(vim.split, 'string', 'string', 1)) + matches('s: expected string, got number', pcall_err(vim.split, 1, 'string')) + matches('sep: expected string, got number', pcall_err(vim.split, 'string', 1)) + matches('opts: expected table, got number', pcall_err(vim.split, 'string', 'string', 1)) end) it('vim.trim', function() @@ -348,10 +560,10 @@ describe('lua stdlib', function() end local trims = { - { " a", "a" }, - { " b ", "b" }, - { "\tc" , "c" }, - { "r\n", "r" }, + { ' a', 'a' }, + { ' b ', 'b' }, + { '\tc', 'c' }, + { 'r\n', 'r' }, } for _, t in ipairs(trims) do @@ -359,8 +571,7 @@ describe('lua stdlib', function() end -- Validates args. - matches('s: expected string, got number', - pcall_err(trim, 2)) + matches('s: expected string, got number', pcall_err(trim, 2)) end) it('vim.inspect', function() @@ -370,21 +581,23 @@ describe('lua stdlib', function() end eq('2', inspect(2)) - eq('{+a = {+b = 1+}+}', - inspect({ a = { b = 1 } }, { newline = '+', indent = '' })) + eq('{+a = {+b = 1+}+}', inspect({ a = { b = 1 } }, { newline = '+', indent = '' })) -- special value vim.inspect.KEY works - eq('{ KEY_a = "x", KEY_b = "y"}', exec_lua([[ + eq( + '{ KEY_a = "x", KEY_b = "y"}', + exec_lua([[ return vim.inspect({a="x", b="y"}, {newline = '', process = function(item, path) if path[#path] == vim.inspect.KEY then return 'KEY_'..item end return item end}) - ]])) + ]]) + ) end) - it("vim.deepcopy", function() + it('vim.deepcopy', function() ok(exec_lua([[ local a = { x = { 1, 2 }, y = 5} local b = vim.deepcopy(a) @@ -445,23 +658,27 @@ describe('lua stdlib', function() return t2.a == vim.NIL ]])) - matches('Cannot deepcopy object of type thread', - pcall_err(exec_lua, [[ + matches( + 'Cannot deepcopy object of type thread', + pcall_err( + exec_lua, + [[ local thread = coroutine.create(function () return 0 end) local t = {thr = thread} vim.deepcopy(t) - ]])) + ]] + ) + ) end) it('vim.pesc', function() eq('foo%-bar', exec_lua([[return vim.pesc('foo-bar')]])) eq('foo%%%-bar', exec_lua([[return vim.pesc(vim.pesc('foo-bar'))]])) -- pesc() returns one result. #20751 - eq({'x'}, exec_lua([[return {vim.pesc('x')}]])) + eq({ 'x' }, exec_lua([[return {vim.pesc('x')}]])) -- Validates args. - matches('s: expected string, got number', - pcall_err(exec_lua, [[return vim.pesc(2)]])) + matches('s: expected string, got number', pcall_err(exec_lua, [[return vim.pesc(2)]])) end) it('vim.list_contains', function() @@ -473,97 +690,131 @@ describe('lua stdlib', function() eq(true, exec_lua("return vim.tbl_contains({'a','b','c'}, 'c')")) eq(false, exec_lua("return vim.tbl_contains({'a','b','c'}, 'd')")) eq(true, exec_lua("return vim.tbl_contains({[2]='a',foo='b',[5] = 'c'}, 'c')")) - eq(true, exec_lua([[ + eq( + true, + exec_lua([[ return vim.tbl_contains({ 'a', { 'b', 'c' } }, function(v) return vim.deep_equal(v, { 'b', 'c' }) end, { predicate = true }) - ]])) + ]]) + ) end) it('vim.tbl_keys', function() - eq({}, exec_lua("return vim.tbl_keys({})")) + eq({}, exec_lua('return vim.tbl_keys({})')) for _, v in pairs(exec_lua("return vim.tbl_keys({'a', 'b', 'c'})")) do - eq(true, exec_lua("return vim.tbl_contains({ 1, 2, 3 }, ...)", v)) + eq(true, exec_lua('return vim.tbl_contains({ 1, 2, 3 }, ...)', v)) end - for _, v in pairs(exec_lua("return vim.tbl_keys({a=1, b=2, c=3})")) do + for _, v in pairs(exec_lua('return vim.tbl_keys({a=1, b=2, c=3})')) do eq(true, exec_lua("return vim.tbl_contains({ 'a', 'b', 'c' }, ...)", v)) end end) it('vim.tbl_values', function() - eq({}, exec_lua("return vim.tbl_values({})")) + eq({}, exec_lua('return vim.tbl_values({})')) for _, v in pairs(exec_lua("return vim.tbl_values({'a', 'b', 'c'})")) do eq(true, exec_lua("return vim.tbl_contains({ 'a', 'b', 'c' }, ...)", v)) end - for _, v in pairs(exec_lua("return vim.tbl_values({a=1, b=2, c=3})")) do - eq(true, exec_lua("return vim.tbl_contains({ 1, 2, 3 }, ...)", v)) + for _, v in pairs(exec_lua('return vim.tbl_values({a=1, b=2, c=3})')) do + eq(true, exec_lua('return vim.tbl_contains({ 1, 2, 3 }, ...)', v)) end end) it('vim.tbl_map', function() - eq({}, exec_lua([[ + eq( + {}, + exec_lua([[ return vim.tbl_map(function(v) return v * 2 end, {}) - ]])) - eq({2, 4, 6}, exec_lua([[ + ]]) + ) + eq( + { 2, 4, 6 }, + exec_lua([[ return vim.tbl_map(function(v) return v * 2 end, {1, 2, 3}) - ]])) - eq({{i=2}, {i=4}, {i=6}}, exec_lua([[ + ]]) + ) + eq( + { { i = 2 }, { i = 4 }, { i = 6 } }, + exec_lua([[ return vim.tbl_map(function(v) return { i = v.i * 2 } end, {{i=1}, {i=2}, {i=3}}) - ]])) + ]]) + ) end) it('vim.tbl_filter', function() - eq({}, exec_lua([[ + eq( + {}, + exec_lua([[ return vim.tbl_filter(function(v) return (v % 2) == 0 end, {}) - ]])) - eq({2}, exec_lua([[ + ]]) + ) + eq( + { 2 }, + exec_lua([[ return vim.tbl_filter(function(v) return (v % 2) == 0 end, {1, 2, 3}) - ]])) - eq({{i=2}}, exec_lua([[ + ]]) + ) + eq( + { { i = 2 } }, + exec_lua([[ return vim.tbl_filter(function(v) return (v.i % 2) == 0 end, {{i=1}, {i=2}, {i=3}}) - ]])) + ]]) + ) end) it('vim.tbl_isarray', function() - eq(true, exec_lua("return vim.tbl_isarray({})")) - eq(false, exec_lua("return vim.tbl_isarray(vim.empty_dict())")) + eq(true, exec_lua('return vim.tbl_isarray({})')) + eq(false, exec_lua('return vim.tbl_isarray(vim.empty_dict())')) eq(true, exec_lua("return vim.tbl_isarray({'a', 'b', 'c'})")) eq(false, exec_lua("return vim.tbl_isarray({'a', '32', a='hello', b='baz'})")) eq(false, exec_lua("return vim.tbl_isarray({1, a='hello', b='baz'})")) eq(false, exec_lua("return vim.tbl_isarray({a='hello', b='baz', 1})")) eq(false, exec_lua("return vim.tbl_isarray({1, 2, nil, a='hello'})")) - eq(true, exec_lua("return vim.tbl_isarray({1, 2, nil, 4})")) - eq(true, exec_lua("return vim.tbl_isarray({nil, 2, 3, 4})")) - eq(false, exec_lua("return vim.tbl_isarray({1, [1.5]=2, [3]=3})")) + eq(true, exec_lua('return vim.tbl_isarray({1, 2, nil, 4})')) + eq(true, exec_lua('return vim.tbl_isarray({nil, 2, 3, 4})')) + eq(false, exec_lua('return vim.tbl_isarray({1, [1.5]=2, [3]=3})')) end) it('vim.tbl_islist', function() - eq(true, exec_lua("return vim.tbl_islist({})")) - eq(false, exec_lua("return vim.tbl_islist(vim.empty_dict())")) + eq(true, exec_lua('return vim.tbl_islist({})')) + eq(false, exec_lua('return vim.tbl_islist(vim.empty_dict())')) eq(true, exec_lua("return vim.tbl_islist({'a', 'b', 'c'})")) eq(false, exec_lua("return vim.tbl_islist({'a', '32', a='hello', b='baz'})")) eq(false, exec_lua("return vim.tbl_islist({1, a='hello', b='baz'})")) eq(false, exec_lua("return vim.tbl_islist({a='hello', b='baz', 1})")) eq(false, exec_lua("return vim.tbl_islist({1, 2, nil, a='hello'})")) - eq(false, exec_lua("return vim.tbl_islist({1, 2, nil, 4})")) - eq(false, exec_lua("return vim.tbl_islist({nil, 2, 3, 4})")) - eq(false, exec_lua("return vim.tbl_islist({1, [1.5]=2, [3]=3})")) + eq(false, exec_lua('return vim.tbl_islist({1, 2, nil, 4})')) + eq(false, exec_lua('return vim.tbl_islist({nil, 2, 3, 4})')) + eq(false, exec_lua('return vim.tbl_islist({1, [1.5]=2, [3]=3})')) end) it('vim.tbl_isempty', function() - eq(true, exec_lua("return vim.tbl_isempty({})")) - eq(false, exec_lua("return vim.tbl_isempty({ 1, 2, 3 })")) - eq(false, exec_lua("return vim.tbl_isempty({a=1, b=2, c=3})")) + eq(true, exec_lua('return vim.tbl_isempty({})')) + eq(false, exec_lua('return vim.tbl_isempty({ 1, 2, 3 })')) + eq(false, exec_lua('return vim.tbl_isempty({a=1, b=2, c=3})')) end) it('vim.tbl_get', function() - eq(true, exec_lua("return vim.tbl_get({ test = { nested_test = true }}, 'test', 'nested_test')")) + eq( + true, + exec_lua("return vim.tbl_get({ test = { nested_test = true }}, 'test', 'nested_test')") + ) eq(NIL, exec_lua("return vim.tbl_get({ unindexable = true }, 'unindexable', 'missing_key')")) eq(NIL, exec_lua("return vim.tbl_get({ unindexable = 1 }, 'unindexable', 'missing_key')")) - eq(NIL, exec_lua("return vim.tbl_get({ unindexable = coroutine.create(function () end) }, 'unindexable', 'missing_key')")) - eq(NIL, exec_lua("return vim.tbl_get({ unindexable = function () end }, 'unindexable', 'missing_key')")) + eq( + NIL, + exec_lua( + "return vim.tbl_get({ unindexable = coroutine.create(function () end) }, 'unindexable', 'missing_key')" + ) + ) + eq( + NIL, + exec_lua( + "return vim.tbl_get({ unindexable = function () end }, 'unindexable', 'missing_key')" + ) + ) eq(NIL, exec_lua("return vim.tbl_get({}, 'missing_key')")) - eq(NIL, exec_lua("return vim.tbl_get({})")) + eq(NIL, exec_lua('return vim.tbl_get({})')) eq(1, exec_lua("return select('#', vim.tbl_get({}))")) eq(1, exec_lua("return select('#', vim.tbl_get({ nested = {} }, 'nested', 'missing_key'))")) end) @@ -629,22 +880,34 @@ describe('lua stdlib', function() return c.x.a == 1 and c.x.b == 2 and c.x.c == nil and count == 1 ]])) - matches('invalid "behavior": nil', - pcall_err(exec_lua, [[ + matches( + 'invalid "behavior": nil', + pcall_err( + exec_lua, + [[ return vim.tbl_extend() - ]]) + ]] + ) ) - matches('wrong number of arguments %(given 1, expected at least 3%)', - pcall_err(exec_lua, [[ + matches( + 'wrong number of arguments %(given 1, expected at least 3%)', + pcall_err( + exec_lua, + [[ return vim.tbl_extend("keep") - ]]) + ]] + ) ) - matches('wrong number of arguments %(given 2, expected at least 3%)', - pcall_err(exec_lua, [[ + matches( + 'wrong number of arguments %(given 2, expected at least 3%)', + pcall_err( + exec_lua, + [[ return vim.tbl_extend("keep", {}) - ]]) + ]] + ) ) end) @@ -717,17 +980,23 @@ describe('lua stdlib', function() return vim.tbl_islist(c) and count == 0 ]])) - eq({a = {b = 1}}, exec_lua([[ + eq( + { a = { b = 1 } }, + exec_lua([[ local a = { a = { b = 1 } } local b = { a = {} } return vim.tbl_deep_extend("force", a, b) - ]])) + ]]) + ) - eq({a = {b = 1}}, exec_lua([[ + eq( + { a = { b = 1 } }, + exec_lua([[ local a = { a = 123 } local b = { a = { b = 1} } return vim.tbl_deep_extend("force", a, b) - ]])) + ]]) + ) ok(exec_lua([[ local a = { a = {[2] = 3} } @@ -736,28 +1005,43 @@ describe('lua stdlib', function() return vim.deep_equal(c, {a = {[3] = 3}}) ]])) - eq({a = 123}, exec_lua([[ + eq( + { a = 123 }, + exec_lua([[ local a = { a = { b = 1} } local b = { a = 123 } return vim.tbl_deep_extend("force", a, b) - ]])) + ]]) + ) - matches('invalid "behavior": nil', - pcall_err(exec_lua, [[ + matches( + 'invalid "behavior": nil', + pcall_err( + exec_lua, + [[ return vim.tbl_deep_extend() - ]]) + ]] + ) ) - matches('wrong number of arguments %(given 1, expected at least 3%)', - pcall_err(exec_lua, [[ + matches( + 'wrong number of arguments %(given 1, expected at least 3%)', + pcall_err( + exec_lua, + [[ return vim.tbl_deep_extend("keep") - ]]) + ]] + ) ) - matches('wrong number of arguments %(given 2, expected at least 3%)', - pcall_err(exec_lua, [[ + matches( + 'wrong number of arguments %(given 2, expected at least 3%)', + pcall_err( + exec_lua, + [[ return vim.tbl_deep_extend("keep", {}) - ]]) + ]] + ) ) end) @@ -786,23 +1070,28 @@ describe('lua stdlib', function() end) it('vim.list_extend', function() - eq({1,2,3}, exec_lua [[ return vim.list_extend({1}, {2,3}) ]]) - matches('src: expected table, got nil', - pcall_err(exec_lua, [[ return vim.list_extend({1}, nil) ]])) - eq({1,2}, exec_lua [[ return vim.list_extend({1}, {2;a=1}) ]]) + eq({ 1, 2, 3 }, exec_lua [[ return vim.list_extend({1}, {2,3}) ]]) + matches( + 'src: expected table, got nil', + pcall_err(exec_lua, [[ return vim.list_extend({1}, nil) ]]) + ) + eq({ 1, 2 }, exec_lua [[ return vim.list_extend({1}, {2;a=1}) ]]) eq(true, exec_lua [[ local a = {1} return vim.list_extend(a, {2;a=1}) == a ]]) - eq({2}, exec_lua [[ return vim.list_extend({}, {2;a=1}, 1) ]]) + eq({ 2 }, exec_lua [[ return vim.list_extend({}, {2;a=1}, 1) ]]) eq({}, exec_lua [[ return vim.list_extend({}, {2;a=1}, 2) ]]) eq({}, exec_lua [[ return vim.list_extend({}, {2;a=1}, 1, -1) ]]) - eq({2}, exec_lua [[ return vim.list_extend({}, {2;a=1}, -1, 2) ]]) + eq({ 2 }, exec_lua [[ return vim.list_extend({}, {2;a=1}, -1, 2) ]]) end) it('vim.tbl_add_reverse_lookup', function() - eq(true, exec_lua [[ + eq( + true, + exec_lua [[ local a = { A = 1 } vim.tbl_add_reverse_lookup(a) return vim.deep_equal(a, { A = 1; [1] = 'A'; }) - ]]) + ]] + ) -- Throw an error for trying to do it twice (run into an existing key) local code = [[ local res = {} @@ -811,17 +1100,19 @@ describe('lua stdlib', function() assert(vim.deep_equal(a, { A = 1; [1] = 'A'; })) vim.tbl_add_reverse_lookup(a) ]] - matches('The reverse lookup found an existing value for "[1A]" while processing key "[1A]"$', - pcall_err(exec_lua, code)) + matches( + 'The reverse lookup found an existing value for "[1A]" while processing key "[1A]"$', + pcall_err(exec_lua, code) + ) end) it('vim.spairs', function() local res = '' local table = { - ccc=1, - bbb=2, - ddd=3, - aaa=4 + ccc = 1, + bbb = 2, + ddd = 3, + aaa = 4, } for key, _ in vim.spairs(table) do res = res .. key @@ -848,37 +1139,51 @@ describe('lua stdlib', function() endfunc ]]) eq(true, exec_lua([[return next(vim.fn.FooFunc(3)) == nil ]])) - eq(3, eval("g:test")) + eq(3, eval('g:test')) -- compat: nvim_call_function uses "special" value for empty dict eq(true, exec_lua([[return next(vim.api.nvim_call_function("FooFunc", {5})) == true ]])) - eq(5, eval("g:test")) + eq(5, eval('g:test')) - eq({2, "foo", true}, exec_lua([[return vim.fn.VarArg(2, "foo", true)]])) + eq({ 2, 'foo', true }, exec_lua([[return vim.fn.VarArg(2, "foo", true)]])) - eq(true, exec_lua([[ + eq( + true, + exec_lua([[ local x = vim.fn.Nilly() return #x == 2 and x[1] == vim.NIL and x[2] == vim.NIL - ]])) - eq({NIL, NIL}, exec_lua([[return vim.fn.Nilly()]])) + ]]) + ) + eq({ NIL, NIL }, exec_lua([[return vim.fn.Nilly()]])) -- error handling - eq({false, 'Vim:E897: List or Blob required'}, exec_lua([[return {pcall(vim.fn.add, "aa", "bb")}]])) + eq( + { false, 'Vim:E897: List or Blob required' }, + exec_lua([[return {pcall(vim.fn.add, "aa", "bb")}]]) + ) -- conversion between LuaRef and Vim Funcref - eq(true, exec_lua([[ + eq( + true, + exec_lua([[ local x = vim.fn.VarArg(function() return 'foo' end, function() return 'bar' end) return #x == 2 and x[1]() == 'foo' and x[2]() == 'bar' - ]])) + ]]) + ) -- Test for #20211 - eq('a (b) c', exec_lua([[ + eq( + 'a (b) c', + exec_lua([[ return vim.fn.substitute('a b c', 'b', function(m) return '(' .. m[1] .. ')' end, 'g') - ]])) + ]]) + ) end) it('vim.fn should error when calling API function', function() - matches('Tried to call API function with vim.fn: use vim.api.nvim_get_current_line instead', - pcall_err(exec_lua, "vim.fn.nvim_get_current_line()")) + matches( + 'Tried to call API function with vim.fn: use vim.api.nvim_get_current_line instead', + pcall_err(exec_lua, 'vim.fn.nvim_get_current_line()') + ) end) it('vim.fn is allowed in "fast" context by some functions #18306', function() @@ -892,7 +1197,7 @@ describe('lua stdlib', function() ]]) helpers.poke_eventloop() - eq('hello', exec_lua[[return vim.g.fnres]]) + eq('hello', exec_lua [[return vim.g.fnres]]) end) it('vim.rpcrequest and vim.rpcnotify', function() @@ -902,50 +1207,58 @@ describe('lua stdlib', function() ]]) eq('meow', meths.get_current_line()) command("let x = [3, 'aa', v:true, v:null]") - eq(true, exec_lua([[ + eq( + true, + exec_lua([[ ret = vim.rpcrequest(chan, 'nvim_get_var', 'x') return #ret == 4 and ret[1] == 3 and ret[2] == 'aa' and ret[3] == true and ret[4] == vim.NIL - ]])) - eq({3, 'aa', true, NIL}, exec_lua([[return ret]])) + ]]) + ) + eq({ 3, 'aa', true, NIL }, exec_lua([[return ret]])) - eq({{}, {}, false, true}, exec_lua([[ + eq( + { {}, {}, false, true }, + exec_lua([[ vim.rpcrequest(chan, 'nvim_exec', 'let xx = {}\nlet yy = []', false) local dict = vim.rpcrequest(chan, 'nvim_eval', 'xx') local list = vim.rpcrequest(chan, 'nvim_eval', 'yy') return {dict, list, vim.tbl_islist(dict), vim.tbl_islist(list)} - ]])) + ]]) + ) - exec_lua([[ + exec_lua([[ vim.rpcrequest(chan, 'nvim_set_var', 'aa', {}) vim.rpcrequest(chan, 'nvim_set_var', 'bb', vim.empty_dict()) ]]) - eq({1, 1}, eval('[type(g:aa) == type([]), type(g:bb) == type({})]')) + eq({ 1, 1 }, eval('[type(g:aa) == type([]), type(g:bb) == type({})]')) -- error handling - eq({false, 'Invalid channel: 23'}, - exec_lua([[return {pcall(vim.rpcrequest, 23, 'foo')}]])) - eq({false, 'Invalid channel: 23'}, - exec_lua([[return {pcall(vim.rpcnotify, 23, 'foo')}]])) - - eq({false, 'Vim:E121: Undefined variable: foobar'}, - exec_lua([[return {pcall(vim.rpcrequest, chan, 'nvim_eval', "foobar")}]])) + eq({ false, 'Invalid channel: 23' }, exec_lua([[return {pcall(vim.rpcrequest, 23, 'foo')}]])) + eq({ false, 'Invalid channel: 23' }, exec_lua([[return {pcall(vim.rpcnotify, 23, 'foo')}]])) + eq( + { false, 'Vim:E121: Undefined variable: foobar' }, + exec_lua([[return {pcall(vim.rpcrequest, chan, 'nvim_eval', "foobar")}]]) + ) -- rpcnotify doesn't wait on request - eq('meow', exec_lua([[ + eq( + 'meow', + exec_lua([[ vim.rpcnotify(chan, 'nvim_set_current_line', 'foo') return vim.api.nvim_get_current_line() - ]])) + ]]) + ) retry(10, nil, function() eq('foo', meths.get_current_line()) end) - local screen = Screen.new(50,7) + local screen = Screen.new(50, 7) screen:set_default_attr_ids({ - [1] = {bold = true, foreground = Screen.colors.Blue1}, - [2] = {bold = true, reverse = true}, - [3] = {foreground = Screen.colors.Grey100, background = Screen.colors.Red}, - [4] = {bold = true, foreground = Screen.colors.SeaGreen4}, + [1] = { bold = true, foreground = Screen.colors.Blue1 }, + [2] = { bold = true, reverse = true }, + [3] = { foreground = Screen.colors.Grey100, background = Screen.colors.Red }, + [4] = { bold = true, foreground = Screen.colors.SeaGreen4 }, }) screen:attach() exec_lua([[ @@ -957,7 +1270,8 @@ describe('lua stdlib', function() vim.rpcrequest(chan, 'nvim_set_current_line', 'bork') end) ]]) - screen:expect{grid=[[ + screen:expect { + grid = [[ {3:[string ""]:6: E5560: rpcrequest must not be}| {3: called in a lua loop callback} | {3:stack traceback:} | @@ -965,35 +1279,42 @@ describe('lua stdlib', function() {3: [string ""]:6: in function <[string }| {3:""]:2>} | {4:Press ENTER or type command to continue}^ | - ]]} + ]], + } feed('') - eq({3, NIL}, meths.get_var('yy')) + eq({ 3, NIL }, meths.get_var('yy')) exec_lua([[timer:close()]]) end) it('vim.empty_dict()', function() - eq({true, false, true, true}, exec_lua([[ + eq( + { true, false, true, true }, + exec_lua([[ vim.api.nvim_set_var('listy', {}) vim.api.nvim_set_var('dicty', vim.empty_dict()) local listy = vim.fn.eval("listy") local dicty = vim.fn.eval("dicty") return {vim.tbl_islist(listy), vim.tbl_islist(dicty), next(listy) == nil, next(dicty) == nil} - ]])) + ]]) + ) -- vim.empty_dict() gives new value each time -- equality is not overridden (still by ref) -- non-empty table uses the usual heuristics (ignores the tag) - eq({false, {"foo"}, {namey="bar"}}, exec_lua([[ + eq( + { false, { 'foo' }, { namey = 'bar' } }, + exec_lua([[ local aa = vim.empty_dict() local bb = vim.empty_dict() local equally = (aa == bb) aa[1] = "foo" bb["namey"] = "bar" return {equally, aa, bb} - ]])) + ]]) + ) - eq("{ {}, vim.empty_dict() }", exec_lua("return vim.inspect({{}, vim.empty_dict()})")) + eq('{ {}, vim.empty_dict() }', exec_lua('return vim.inspect({{}, vim.empty_dict()})')) eq('{}', exec_lua([[ return vim.fn.json_encode(vim.empty_dict()) ]])) eq('{"a": {}, "b": []}', exec_lua([[ return vim.fn.json_encode({a=vim.empty_dict(), b={}}) ]])) end) @@ -1028,56 +1349,72 @@ describe('lua stdlib', function() exec_lua("vim.validate{arg1={2, function(a) return (a % 2) == 0 end, 'even number' }}") exec_lua("vim.validate{arg1={5, {'n', 's'} }, arg2={ 'foo', {'n', 's'} }}") - matches('expected table, got number', - pcall_err(exec_lua, "vim.validate{ 1, 'x' }")) - matches('invalid type name: x', - pcall_err(exec_lua, "vim.validate{ arg1={ 1, 'x' }}")) - matches('invalid type name: 1', - pcall_err(exec_lua, "vim.validate{ arg1={ 1, 1 }}")) - matches('invalid type name: nil', - pcall_err(exec_lua, "vim.validate{ arg1={ 1 }}")) + matches('expected table, got number', pcall_err(exec_lua, "vim.validate{ 1, 'x' }")) + matches('invalid type name: x', pcall_err(exec_lua, "vim.validate{ arg1={ 1, 'x' }}")) + matches('invalid type name: 1', pcall_err(exec_lua, 'vim.validate{ arg1={ 1, 1 }}')) + matches('invalid type name: nil', pcall_err(exec_lua, 'vim.validate{ arg1={ 1 }}')) -- Validated parameters are required by default. - matches('arg1: expected string, got nil', - pcall_err(exec_lua, "vim.validate{ arg1={ nil, 's' }}")) + matches( + 'arg1: expected string, got nil', + pcall_err(exec_lua, "vim.validate{ arg1={ nil, 's' }}") + ) -- Explicitly required. - matches('arg1: expected string, got nil', - pcall_err(exec_lua, "vim.validate{ arg1={ nil, 's', false }}")) - - matches('arg1: expected table, got number', - pcall_err(exec_lua, "vim.validate{arg1={1, 't'}}")) - matches('arg2: expected string, got number', - pcall_err(exec_lua, "vim.validate{arg1={{}, 't'}, arg2={1, 's'}}")) - matches('arg2: expected string, got nil', - pcall_err(exec_lua, "vim.validate{arg1={{}, 't'}, arg2={nil, 's'}}")) - matches('arg2: expected string, got nil', - pcall_err(exec_lua, "vim.validate{arg1={{}, 't'}, arg2={nil, 's'}}")) - matches('arg1: expected even number, got 3', - pcall_err(exec_lua, "vim.validate{arg1={3, function(a) return a == 1 end, 'even number'}}")) - matches('arg1: expected %?, got 3', - pcall_err(exec_lua, "vim.validate{arg1={3, function(a) return a == 1 end}}")) - matches('arg1: expected number|string, got nil', - pcall_err(exec_lua, "vim.validate{ arg1={ nil, {'n', 's'} }}")) + matches( + 'arg1: expected string, got nil', + pcall_err(exec_lua, "vim.validate{ arg1={ nil, 's', false }}") + ) + + matches('arg1: expected table, got number', pcall_err(exec_lua, "vim.validate{arg1={1, 't'}}")) + matches( + 'arg2: expected string, got number', + pcall_err(exec_lua, "vim.validate{arg1={{}, 't'}, arg2={1, 's'}}") + ) + matches( + 'arg2: expected string, got nil', + pcall_err(exec_lua, "vim.validate{arg1={{}, 't'}, arg2={nil, 's'}}") + ) + matches( + 'arg2: expected string, got nil', + pcall_err(exec_lua, "vim.validate{arg1={{}, 't'}, arg2={nil, 's'}}") + ) + matches( + 'arg1: expected even number, got 3', + pcall_err(exec_lua, "vim.validate{arg1={3, function(a) return a == 1 end, 'even number'}}") + ) + matches( + 'arg1: expected %?, got 3', + pcall_err(exec_lua, 'vim.validate{arg1={3, function(a) return a == 1 end}}') + ) + matches( + 'arg1: expected number|string, got nil', + pcall_err(exec_lua, "vim.validate{ arg1={ nil, {'n', 's'} }}") + ) -- Pass an additional message back. - matches('arg1: expected %?, got 3. Info: TEST_MSG', - pcall_err(exec_lua, "vim.validate{arg1={3, function(a) return a == 1, 'TEST_MSG' end}}")) + matches( + 'arg1: expected %?, got 3. Info: TEST_MSG', + pcall_err(exec_lua, "vim.validate{arg1={3, function(a) return a == 1, 'TEST_MSG' end}}") + ) end) it('vim.is_callable', function() - eq(true, exec_lua("return vim.is_callable(function()end)")) - eq(true, exec_lua([[ + eq(true, exec_lua('return vim.is_callable(function()end)')) + eq( + true, + exec_lua([[ local meta = { __call = function()end } local function new_callable() return setmetatable({}, meta) end local callable = new_callable() return vim.is_callable(callable) - ]])) + ]]) + ) - eq(false, exec_lua("return vim.is_callable(1)")) + eq(false, exec_lua('return vim.is_callable(1)')) eq(false, exec_lua("return vim.is_callable('foo')")) - eq(false, exec_lua("return vim.is_callable({})")) + eq(false, exec_lua('return vim.is_callable({})')) end) it('vim.g', function() @@ -1089,24 +1426,26 @@ describe('lua stdlib', function() vim.api.nvim_set_var("to_delete", {hello="world"}) ]] - eq('hi', funcs.luaeval "vim.g.testing") - eq(123, funcs.luaeval "vim.g.other") - eq(5120.1, funcs.luaeval "vim.g.floaty") - eq(NIL, funcs.luaeval "vim.g.nonexistent") - eq(NIL, funcs.luaeval "vim.g.nullvar") + eq('hi', funcs.luaeval 'vim.g.testing') + eq(123, funcs.luaeval 'vim.g.other') + eq(5120.1, funcs.luaeval 'vim.g.floaty') + eq(NIL, funcs.luaeval 'vim.g.nonexistent') + eq(NIL, funcs.luaeval 'vim.g.nullvar') -- lost over RPC, so test locally: - eq({false, true}, exec_lua [[ + eq( + { false, true }, + exec_lua [[ return {vim.g.nonexistent == vim.NIL, vim.g.nullvar == vim.NIL} - ]]) + ]] + ) - eq({hello="world"}, funcs.luaeval "vim.g.to_delete") + eq({ hello = 'world' }, funcs.luaeval 'vim.g.to_delete') exec_lua [[ vim.g.to_delete = nil ]] - eq(NIL, funcs.luaeval "vim.g.to_delete") + eq(NIL, funcs.luaeval 'vim.g.to_delete') - matches([[attempt to index .* nil value]], - pcall_err(exec_lua, 'return vim.g[0].testing')) + matches([[attempt to index .* nil value]], pcall_err(exec_lua, 'return vim.g[0].testing')) exec_lua [[ local counter = 0 @@ -1173,12 +1512,12 @@ describe('lua stdlib', function() local pathsep = helpers.get_pathsep() local xconfig = 'Xhome' .. pathsep .. 'Xconfig' local xdata = 'Xhome' .. pathsep .. 'Xdata' - local autoload_folder = table.concat({xconfig, 'nvim', 'autoload'}, pathsep) - local autoload_file = table.concat({autoload_folder , 'testload.vim'}, pathsep) + local autoload_folder = table.concat({ xconfig, 'nvim', 'autoload' }, pathsep) + local autoload_file = table.concat({ autoload_folder, 'testload.vim' }, pathsep) mkdir_p(autoload_folder) - write_file(autoload_file , [[let testload#value = 2]]) + write_file(autoload_file, [[let testload#value = 2]]) - clear{ args_rm={'-u'}, env={ XDG_CONFIG_HOME=xconfig, XDG_DATA_HOME=xdata } } + clear { args_rm = { '-u' }, env = { XDG_CONFIG_HOME = xconfig, XDG_DATA_HOME = xdata } } eq(2, exec_lua("return vim.g['testload#value']")) rmdir('Xhome') @@ -1195,26 +1534,28 @@ describe('lua stdlib', function() vim.api.nvim_buf_set_var(BUF, "testing", "bye") ]] - eq('hi', funcs.luaeval "vim.b.testing") - eq('bye', funcs.luaeval "vim.b[BUF].testing") - eq(123, funcs.luaeval "vim.b.other") - eq(5120.1, funcs.luaeval "vim.b.floaty") - eq(NIL, funcs.luaeval "vim.b.nonexistent") - eq(NIL, funcs.luaeval "vim.b[BUF].nonexistent") - eq(NIL, funcs.luaeval "vim.b.nullvar") + eq('hi', funcs.luaeval 'vim.b.testing') + eq('bye', funcs.luaeval 'vim.b[BUF].testing') + eq(123, funcs.luaeval 'vim.b.other') + eq(5120.1, funcs.luaeval 'vim.b.floaty') + eq(NIL, funcs.luaeval 'vim.b.nonexistent') + eq(NIL, funcs.luaeval 'vim.b[BUF].nonexistent') + eq(NIL, funcs.luaeval 'vim.b.nullvar') -- lost over RPC, so test locally: - eq({false, true}, exec_lua [[ + eq( + { false, true }, + exec_lua [[ return {vim.b.nonexistent == vim.NIL, vim.b.nullvar == vim.NIL} - ]]) + ]] + ) - matches([[attempt to index .* nil value]], - pcall_err(exec_lua, 'return vim.b[BUF][0].testing')) + matches([[attempt to index .* nil value]], pcall_err(exec_lua, 'return vim.b[BUF][0].testing')) - eq({hello="world"}, funcs.luaeval "vim.b.to_delete") + eq({ hello = 'world' }, funcs.luaeval 'vim.b.to_delete') exec_lua [[ vim.b.to_delete = nil ]] - eq(NIL, funcs.luaeval "vim.b.to_delete") + eq(NIL, funcs.luaeval 'vim.b.to_delete') exec_lua [[ local counter = 0 @@ -1281,9 +1622,9 @@ describe('lua stdlib', function() vim.cmd "vnew" ]] - eq(NIL, funcs.luaeval "vim.b.testing") - eq(NIL, funcs.luaeval "vim.b.other") - eq(NIL, funcs.luaeval "vim.b.nonexistent") + eq(NIL, funcs.luaeval 'vim.b.testing') + eq(NIL, funcs.luaeval 'vim.b.other') + eq(NIL, funcs.luaeval 'vim.b.nonexistent') end) it('vim.w', function() @@ -1299,20 +1640,19 @@ describe('lua stdlib', function() vim.api.nvim_win_set_var(WIN, "testing", "bye") ]] - eq('hi', funcs.luaeval "vim.w.testing") - eq('bye', funcs.luaeval "vim.w[WIN].testing") - eq(123, funcs.luaeval "vim.w.other") - eq(NIL, funcs.luaeval "vim.w.nonexistent") - eq(NIL, funcs.luaeval "vim.w[WIN].nonexistent") + eq('hi', funcs.luaeval 'vim.w.testing') + eq('bye', funcs.luaeval 'vim.w[WIN].testing') + eq(123, funcs.luaeval 'vim.w.other') + eq(NIL, funcs.luaeval 'vim.w.nonexistent') + eq(NIL, funcs.luaeval 'vim.w[WIN].nonexistent') - matches([[attempt to index .* nil value]], - pcall_err(exec_lua, 'return vim.w[WIN][0].testing')) + matches([[attempt to index .* nil value]], pcall_err(exec_lua, 'return vim.w[WIN][0].testing')) - eq({hello="world"}, funcs.luaeval "vim.w.to_delete") + eq({ hello = 'world' }, funcs.luaeval 'vim.w.to_delete') exec_lua [[ vim.w.to_delete = nil ]] - eq(NIL, funcs.luaeval "vim.w.to_delete") + eq(NIL, funcs.luaeval 'vim.w.to_delete') exec_lua [[ local counter = 0 @@ -1379,9 +1719,9 @@ describe('lua stdlib', function() vim.cmd "vnew" ]] - eq(NIL, funcs.luaeval "vim.w.testing") - eq(NIL, funcs.luaeval "vim.w.other") - eq(NIL, funcs.luaeval "vim.w.nonexistent") + eq(NIL, funcs.luaeval 'vim.w.testing') + eq(NIL, funcs.luaeval 'vim.w.other') + eq(NIL, funcs.luaeval 'vim.w.nonexistent') end) it('vim.t', function() @@ -1391,21 +1731,20 @@ describe('lua stdlib', function() vim.api.nvim_tabpage_set_var(0, "to_delete", {hello="world"}) ]] - eq('hi', funcs.luaeval "vim.t.testing") - eq(123, funcs.luaeval "vim.t.other") - eq(NIL, funcs.luaeval "vim.t.nonexistent") - eq('hi', funcs.luaeval "vim.t[0].testing") - eq(123, funcs.luaeval "vim.t[0].other") - eq(NIL, funcs.luaeval "vim.t[0].nonexistent") + eq('hi', funcs.luaeval 'vim.t.testing') + eq(123, funcs.luaeval 'vim.t.other') + eq(NIL, funcs.luaeval 'vim.t.nonexistent') + eq('hi', funcs.luaeval 'vim.t[0].testing') + eq(123, funcs.luaeval 'vim.t[0].other') + eq(NIL, funcs.luaeval 'vim.t[0].nonexistent') - matches([[attempt to index .* nil value]], - pcall_err(exec_lua, 'return vim.t[0][0].testing')) + matches([[attempt to index .* nil value]], pcall_err(exec_lua, 'return vim.t[0][0].testing')) - eq({hello="world"}, funcs.luaeval "vim.t.to_delete") + eq({ hello = 'world' }, funcs.luaeval 'vim.t.to_delete') exec_lua [[ vim.t.to_delete = nil ]] - eq(NIL, funcs.luaeval "vim.t.to_delete") + eq(NIL, funcs.luaeval 'vim.t.to_delete') exec_lua [[ local counter = 0 @@ -1461,9 +1800,9 @@ describe('lua stdlib', function() vim.cmd "tabnew" ]] - eq(NIL, funcs.luaeval "vim.t.testing") - eq(NIL, funcs.luaeval "vim.t.other") - eq(NIL, funcs.luaeval "vim.t.nonexistent") + eq(NIL, funcs.luaeval 'vim.t.testing') + eq(NIL, funcs.luaeval 'vim.t.other') + eq(NIL, funcs.luaeval 'vim.t.nonexistent') end) it('vim.env', function() @@ -1487,11 +1826,10 @@ describe('lua stdlib', function() end) it('vim.v', function() - eq(funcs.luaeval "vim.api.nvim_get_vvar('progpath')", funcs.luaeval "vim.v.progpath") + eq(funcs.luaeval "vim.api.nvim_get_vvar('progpath')", funcs.luaeval 'vim.v.progpath') eq(false, funcs.luaeval "vim.v['false']") - eq(NIL, funcs.luaeval "vim.v.null") - matches([[attempt to index .* nil value]], - pcall_err(exec_lua, 'return vim.v[0].progpath')) + eq(NIL, funcs.luaeval 'vim.v.null') + matches([[attempt to index .* nil value]], pcall_err(exec_lua, 'return vim.v[0].progpath')) eq('Key is read-only: count', pcall_err(exec_lua, [[vim.v.count = 42]])) eq('Dictionary is locked', pcall_err(exec_lua, [[vim.v.nosuchvar = 42]])) eq('Key is fixed: errmsg', pcall_err(exec_lua, [[vim.v.errmsg = nil]])) @@ -1507,69 +1845,72 @@ describe('lua stdlib', function() eq({}, eval('v:oldfiles')) feed('i foo foo foo0/foo') - eq({1, 1}, meths.win_get_cursor(0)) + eq({ 1, 1 }, meths.win_get_cursor(0)) eq(1, eval('v:searchforward')) feed('n') - eq({1, 5}, meths.win_get_cursor(0)) + eq({ 1, 5 }, meths.win_get_cursor(0)) exec_lua([[vim.v.searchforward = 0]]) eq(0, eval('v:searchforward')) feed('n') - eq({1, 1}, meths.win_get_cursor(0)) + eq({ 1, 1 }, meths.win_get_cursor(0)) exec_lua([[vim.v.searchforward = 1]]) eq(1, eval('v:searchforward')) feed('n') - eq({1, 5}, meths.win_get_cursor(0)) + eq({ 1, 5 }, meths.win_get_cursor(0)) local screen = Screen.new(60, 3) screen:set_default_attr_ids({ - [0] = {bold = true, foreground = Screen.colors.Blue}, - [1] = {background = Screen.colors.Yellow}, + [0] = { bold = true, foreground = Screen.colors.Blue }, + [1] = { background = Screen.colors.Yellow }, }) screen:attach() eq(1, eval('v:hlsearch')) - screen:expect{grid=[[ + screen:expect { + grid = [[ {1:foo} {1:^foo} {1:foo} | {0:~ }| | - ]]} + ]], + } exec_lua([[vim.v.hlsearch = 0]]) eq(0, eval('v:hlsearch')) - screen:expect{grid=[[ + screen:expect { + grid = [[ foo ^foo foo | {0:~ }| | - ]]} + ]], + } exec_lua([[vim.v.hlsearch = 1]]) eq(1, eval('v:hlsearch')) - screen:expect{grid=[[ + screen:expect { + grid = [[ {1:foo} {1:^foo} {1:foo} | {0:~ }| | - ]]} + ]], + } end) it('vim.bo', function() - eq('', funcs.luaeval "vim.bo.filetype") + eq('', funcs.luaeval 'vim.bo.filetype') exec_lua [[ vim.api.nvim_set_option_value("filetype", "markdown", {}) BUF = vim.api.nvim_create_buf(false, true) vim.api.nvim_set_option_value("modifiable", false, {buf = BUF}) ]] - eq(false, funcs.luaeval "vim.bo.modified") - eq('markdown', funcs.luaeval "vim.bo.filetype") - eq(false, funcs.luaeval "vim.bo[BUF].modifiable") + eq(false, funcs.luaeval 'vim.bo.modified') + eq('markdown', funcs.luaeval 'vim.bo.filetype') + eq(false, funcs.luaeval 'vim.bo[BUF].modifiable') exec_lua [[ vim.bo.filetype = '' vim.bo[BUF].modifiable = true ]] - eq('', funcs.luaeval "vim.bo.filetype") - eq(true, funcs.luaeval "vim.bo[BUF].modifiable") - matches("Unknown option 'nosuchopt'$", - pcall_err(exec_lua, 'return vim.bo.nosuchopt')) - matches("Expected Lua string$", - pcall_err(exec_lua, 'return vim.bo[0][0].autoread')) - matches("Invalid buffer id: %-1$", - pcall_err(exec_lua, 'return vim.bo[-1].filetype')) + eq('', funcs.luaeval 'vim.bo.filetype') + eq(true, funcs.luaeval 'vim.bo[BUF].modifiable') + matches("Unknown option 'nosuchopt'$", pcall_err(exec_lua, 'return vim.bo.nosuchopt')) + matches('Expected Lua string$', pcall_err(exec_lua, 'return vim.bo[0][0].autoread')) + matches('Invalid buffer id: %-1$', pcall_err(exec_lua, 'return vim.bo[-1].filetype')) end) it('vim.wo', function() @@ -1578,34 +1919,32 @@ describe('lua stdlib', function() vim.cmd "split" vim.api.nvim_set_option_value("cole", 2, {}) ]] - eq(2, funcs.luaeval "vim.wo.cole") + eq(2, funcs.luaeval 'vim.wo.cole') exec_lua [[ vim.wo.conceallevel = 0 ]] - eq(0, funcs.luaeval "vim.wo.cole") - eq(0, funcs.luaeval "vim.wo[0].cole") - eq(0, funcs.luaeval "vim.wo[1001].cole") - matches("Unknown option 'notanopt'$", - pcall_err(exec_lua, 'return vim.wo.notanopt')) - matches("Invalid window id: %-1$", - pcall_err(exec_lua, 'return vim.wo[-1].list')) - eq(2, funcs.luaeval "vim.wo[1000].cole") + eq(0, funcs.luaeval 'vim.wo.cole') + eq(0, funcs.luaeval 'vim.wo[0].cole') + eq(0, funcs.luaeval 'vim.wo[1001].cole') + matches("Unknown option 'notanopt'$", pcall_err(exec_lua, 'return vim.wo.notanopt')) + matches('Invalid window id: %-1$', pcall_err(exec_lua, 'return vim.wo[-1].list')) + eq(2, funcs.luaeval 'vim.wo[1000].cole') exec_lua [[ vim.wo[1000].cole = 0 ]] - eq(0, funcs.luaeval "vim.wo[1000].cole") + eq(0, funcs.luaeval 'vim.wo[1000].cole') -- Can handle global-local values exec_lua [[vim.o.scrolloff = 100]] exec_lua [[vim.wo.scrolloff = 200]] - eq(200, funcs.luaeval "vim.wo.scrolloff") + eq(200, funcs.luaeval 'vim.wo.scrolloff') exec_lua [[vim.wo.scrolloff = -1]] - eq(100, funcs.luaeval "vim.wo.scrolloff") + eq(100, funcs.luaeval 'vim.wo.scrolloff') exec_lua [[ vim.wo[0][0].scrolloff = 200 vim.cmd "enew" ]] - eq(100, funcs.luaeval "vim.wo.scrolloff") + eq(100, funcs.luaeval 'vim.wo.scrolloff') end) describe('vim.opt', function() @@ -1638,7 +1977,7 @@ describe('lua stdlib', function() vim.opt.wildignore = { 'hello', 'world' } return vim.o.wildignore ]] - eq(wildignore, "hello,world") + eq(wildignore, 'hello,world') end) it('should allow setting tables with sho