From f5b5f2095eb2bd05e3bd463d838bac9a5639ba69 Mon Sep 17 00:00:00 2001 From: "Justin M. Keyes" Date: Tue, 6 May 2025 18:00:20 -0700 Subject: refactor(tests): lint decorations_spec, float_spec, multigrid_spec #33274 Problem: decorations_spec.lua, float_spec.lua, multigrid_spec.lua are not auto-formatted. Solution: Add a special `formatlua2` cmake target, which invokes `stylua` with an alternative `.stylua2.toml` config. --- test/functional/lua/luaeval_spec.lua | 298 ++++++++++++++++++++++------------- 1 file changed, 189 insertions(+), 109 deletions(-) (limited to 'test/functional/lua/luaeval_spec.lua') diff --git a/test/functional/lua/luaeval_spec.lua b/test/functional/lua/luaeval_spec.lua index 495525b1e9..a203fc27c5 100644 --- a/test/functional/lua/luaeval_spec.lua +++ b/test/functional/lua/luaeval_spec.lua @@ -27,39 +27,45 @@ describe('luaeval()', function() local nested_by_level = {} local nested = {} local nested_s = '{}' - for i=1,100 do + for i = 1, 100 do if i % 2 == 0 then - nested = {nested} + nested = { nested } nested_s = '{' .. nested_s .. '}' else - nested = {nested=nested} + nested = { nested = nested } nested_s = '{nested=' .. nested_s .. '}' end - nested_by_level[i] = {o=nested, s=nested_s} + nested_by_level[i] = { o = nested, s = nested_s } end describe('second argument', function() it('is successfully received', function() - local q = {t=true, f=false, --[[n=NIL,]] d={l={'string', 42, 0.42}}} - eq(q, fn.luaeval("_A", q)) + local q = { + t = true, + f = false, --[[n=NIL,]] + d = { l = { 'string', 42, 0.42 } }, + } + eq(q, fn.luaeval('_A', q)) -- Not tested: nil, funcrefs, returned object identity: behaviour will -- most likely change. end) end) describe('lua values', function() it('are successfully transformed', function() - eq({n=1, f=1.5, s='string', l={4, 2}}, - fn.luaeval('{n=1, f=1.5, s="string", l={4, 2}}')) + eq( + { n = 1, f = 1.5, s = 'string', l = { 4, 2 } }, + fn.luaeval('{n=1, f=1.5, s="string", l={4, 2}}') + ) -- Not tested: nil inside containers: behaviour will most likely change. eq(NIL, fn.luaeval('nil')) - eq({['']=1}, fn.luaeval('{[""]=1}')) + eq({ [''] = 1 }, fn.luaeval('{[""]=1}')) end) end) describe('recursive lua values', function() it('are successfully transformed', function() command('lua rawset(_G, "d", {})') command('lua rawset(d, "d", d)') - eq('\n{\'d\': {...@0}}', fn.execute('echo luaeval("d")')) + eq("\n{'d': {...@0}}", fn.execute('echo luaeval("d")')) command('lua rawset(_G, "l", {})') command('lua table.insert(l, l)') @@ -73,13 +79,13 @@ describe('luaeval()', function() end) it('are successfully converted to special dictionaries in table keys', function() command([[let d = luaeval('{["\0"]=1}')]]) - eq({_TYPE={}, _VAL={{'\000', 1}}}, api.nvim_get_var('d')) + eq({ _TYPE = {}, _VAL = { { '\000', 1 } } }, api.nvim_get_var('d')) eq(1, fn.eval('d._TYPE is v:msgpack_types.map')) eq(eval('v:t_blob'), fn.eval('type(d._VAL[0][0])')) end) it('are successfully converted to blobs from a list', function() command([[let l = luaeval('{"abc", "a\0b", "c\0d", "def"}')]]) - eq({'abc', 'a\000b', 'c\000d', 'def'}, api.nvim_get_var('l')) + eq({ 'abc', 'a\000b', 'c\000d', 'def' }, api.nvim_get_var('l')) end) end) @@ -94,7 +100,7 @@ describe('luaeval()', function() eq(1.5, fn.luaeval('1.5')) eq(5, eval('"1.5"->luaeval()->type()')) - eq("test", fn.luaeval('"test"')) + eq('test', fn.luaeval('"test"')) eq(1, eval('"\'test\'"->luaeval()->type()')) eq('', fn.luaeval('""')) @@ -111,27 +117,31 @@ describe('luaeval()', function() eq({}, fn.luaeval('{}')) eq(3, eval('type(luaeval("{}"))')) - eq({test=1, foo=2}, fn.luaeval('{test=1, foo=2}')) + eq({ test = 1, foo = 2 }, fn.luaeval('{test=1, foo=2}')) eq(4, eval('type(luaeval("{test=1, foo=2}"))')) - eq({4, 2}, fn.luaeval('{4, 2}')) + eq({ 4, 2 }, fn.luaeval('{4, 2}')) eq(3, eval('type(luaeval("{4, 2}"))')) - eq({NIL, 20}, fn.luaeval('{[2] = 20}')) + eq({ NIL, 20 }, fn.luaeval('{[2] = 20}')) eq(3, eval('type(luaeval("{[2] = 20}"))')) - eq({10, NIL, 30}, fn.luaeval('{[1] = 10, [3] = 30}')) + eq({ 10, NIL, 30 }, fn.luaeval('{[1] = 10, [3] = 30}')) eq(3, eval('type(luaeval("{[1] = 10, [3] = 30}"))')) local level = 30 eq(nested_by_level[level].o, fn.luaeval(nested_by_level[level].s)) - eq({_TYPE={}, _VAL={{'\000\n\000', '\000\n\000\000'}}}, - fn.luaeval([[{['\0\n\0']='\0\n\0\0'}]])) + eq( + { _TYPE = {}, _VAL = { { '\000\n\000', '\000\n\000\000' } } }, + fn.luaeval([[{['\0\n\0']='\0\n\0\0'}]]) + ) eq(1, eval([[luaeval('{["\0\n\0"]="\0\n\0\0"}')._TYPE is v:msgpack_types.map]])) - eq(eval("v:t_blob"), eval([[type(luaeval('{["\0\n\0"]="\0\n\0\0"}')._VAL[0][0])]])) - eq({nested={{_TYPE={}, _VAL={{'\000\n\000', '\000\n\000\000'}}}}}, - fn.luaeval([[{nested={{['\0\n\0']='\0\n\0\0'}}}]])) + eq(eval('v:t_blob'), eval([[type(luaeval('{["\0\n\0"]="\0\n\0\0"}')._VAL[0][0])]])) + eq( + { nested = { { _TYPE = {}, _VAL = { { '\000\n\000', '\000\n\000\000' } } } } }, + fn.luaeval([[{nested={{['\0\n\0']='\0\n\0\0'}}}]]) + ) end) it('correctly passes scalars as argument', function() @@ -146,8 +156,8 @@ describe('luaeval()', function() it('correctly passes containers as argument', function() eq({}, fn.luaeval('_A', {})) - eq({test=1}, fn.luaeval('_A', {test=1})) - eq({4, 2}, fn.luaeval('_A', {4, 2})) + eq({ test = 1 }, fn.luaeval('_A', { test = 1 })) + eq({ 4, 2 }, fn.luaeval('_A', { 4, 2 })) local level = 28 eq(nested_by_level[level].o, fn.luaeval('_A', nested_by_level[level].o)) end) @@ -157,9 +167,8 @@ describe('luaeval()', function() end local function mapsp(...) local val = '' - for i=1,(select('#', ...)/2) do - val = ('%s[%s,%s],'):format(val, select(i * 2 - 1, ...), - select(i * 2, ...)) + for i = 1, (select('#', ...) / 2) do + val = ('%s[%s,%s],'):format(val, select(i * 2 - 1, ...), select(i * 2, ...)) end return sp('map', '[' .. val .. ']') end @@ -178,26 +187,27 @@ describe('luaeval()', function() end it('correctly passes special dictionaries', function() - eq({0, '\000\n\000'}, luaevalarg(sp('string', '["\\n", "\\n"]'))) - eq({0, true}, luaevalarg(sp('boolean', 1))) - eq({0, false}, luaevalarg(sp('boolean', 0))) - eq({0, NIL}, luaevalarg(sp('nil', 0))) - eq({0, {[""]=""}}, luaevalarg(mapsp(sp('string', '[""]'), '""'))) + eq({ 0, '\000\n\000' }, luaevalarg(sp('string', '["\\n", "\\n"]'))) + eq({ 0, true }, luaevalarg(sp('boolean', 1))) + eq({ 0, false }, luaevalarg(sp('boolean', 0))) + eq({ 0, NIL }, luaevalarg(sp('nil', 0))) + eq({ 0, { [''] = '' } }, luaevalarg(mapsp(sp('string', '[""]'), '""'))) end) it('issues an error in some cases', function() - eq("Vim(call):E5100: Cannot convert given Lua table: table should contain either only integer keys or only string keys", - exc_exec('call luaeval("{1, foo=2}")')) - - startswith("Vim(call):E5107: Lua: [string \"luaeval()\"]:", - exc_exec('call luaeval("1, 2, 3")')) - startswith("Vim(call):E5108: Lua: [string \"luaeval()\"]:", - exc_exec('call luaeval("(nil)()")')) + eq( + 'Vim(call):E5100: Cannot convert given Lua table: table should contain either only integer keys or only string keys', + exc_exec('call luaeval("{1, foo=2}")') + ) + startswith('Vim(call):E5107: Lua: [string "luaeval()"]:', exc_exec('call luaeval("1, 2, 3")')) + startswith('Vim(call):E5108: Lua: [string "luaeval()"]:', exc_exec('call luaeval("(nil)()")')) end) it('should handle sending lua functions to viml', function() - eq(true, exec_lua [[ + eq( + true, + exec_lua [[ can_pass_lua_callback_to_vim_from_lua_result = nil vim.fn.call(function() @@ -205,11 +215,14 @@ describe('luaeval()', function() end, {}) return can_pass_lua_callback_to_vim_from_lua_result - ]]) + ]] + ) end) it('run functions even in timers', function() - eq(true, exec_lua [[ + eq( + true, + exec_lua [[ can_pass_lua_callback_to_vim_from_lua_result = nil vim.fn.timer_start(50, function() @@ -221,11 +234,14 @@ describe('luaeval()', function() end) return can_pass_lua_callback_to_vim_from_lua_result - ]]) + ]] + ) end) it('can run named functions more than once', function() - eq(5, exec_lua [[ + eq( + 5, + exec_lua [[ count_of_vals = 0 vim.fn.timer_start(5, function() @@ -237,11 +253,14 @@ describe('luaeval()', function() end) return count_of_vals - ]]) + ]] + ) end) it('can handle clashing names', function() - eq(1, exec_lua [[ + eq( + 1, + exec_lua [[ local f_loc = function() return 1 end local result = nil @@ -253,11 +272,14 @@ describe('luaeval()', function() vim.wait(1000, function() return result ~= nil end) return result - ]]) + ]] + ) end) it('can handle functions with errors', function() - eq(true, exec_lua [[ + eq( + true, + exec_lua [[ vim.fn.timer_start(10, function() error("dead function") end) @@ -265,7 +287,8 @@ describe('luaeval()', function() vim.wait(1000, function() return false end) return true - ]]) + ]] + ) end) it('should handle passing functions around', function() @@ -276,7 +299,9 @@ describe('luaeval()', function() endfunction ]] - eq("Hello Vim I'm Lua", exec_lua [[ + eq( + "Hello Vim I'm Lua", + exec_lua [[ can_pass_lua_callback_to_vim_from_lua_result = "" vim.fn.VimCanCallLuaCallbacks( @@ -285,7 +310,8 @@ describe('luaeval()', function() ) return can_pass_lua_callback_to_vim_from_lua_result - ]]) + ]] + ) end) it('should handle funcrefs', function() @@ -296,7 +322,9 @@ describe('luaeval()', function() endfunction ]] - eq("Hello Vim I'm Lua", exec_lua [[ + eq( + "Hello Vim I'm Lua", + exec_lua [[ can_pass_lua_callback_to_vim_from_lua_result = "" vim.funcref('VimCanCallLuaCallbacks')( @@ -305,11 +333,14 @@ describe('luaeval()', function() ) return can_pass_lua_callback_to_vim_from_lua_result - ]]) + ]] + ) end) it('should work with metatables using __call', function() - eq(1, exec_lua [[ + eq( + 1, + exec_lua [[ local this_is_local_variable = false local callable_table = setmetatable({x = 1}, { __call = function(t, ...) @@ -324,11 +355,14 @@ describe('luaeval()', function() end) return this_is_local_variable - ]]) + ]] + ) end) it('should handle being called from a timer once.', function() - eq(3, exec_lua [[ + eq( + 3, + exec_lua [[ local this_is_local_variable = false local callable_table = setmetatable({5, 4, 3, 2, 1}, { __call = function(t, ...) this_is_local_variable = t[3] end @@ -340,11 +374,14 @@ describe('luaeval()', function() end) return this_is_local_variable - ]]) + ]] + ) end) it('should call functions once with __call metamethod', function() - eq(true, exec_lua [[ + eq( + true, + exec_lua [[ local this_is_local_variable = false local callable_table = setmetatable({a = true, b = false}, { __call = function(t, ...) this_is_local_variable = t.a end @@ -354,11 +391,14 @@ describe('luaeval()', function() vim.fn.call(callable_table, {}) return this_is_local_variable - ]]) + ]] + ) end) it('should work with lists using __call', function() - eq(3, exec_lua [[ + eq( + 3, + exec_lua [[ local this_is_local_variable = false local mt = { __call = function(t, ...) @@ -382,16 +422,20 @@ describe('luaeval()', function() end) return this_is_local_variable - ]]) + ]] + ) end) it('should not work with tables not using __call', function() - eq({false, 'Vim:E921: Invalid callback argument'}, exec_lua [[ + eq( + { false, 'Vim:E921: Invalid callback argument' }, + exec_lua [[ local this_is_local_variable = false local callable_table = setmetatable({x = 1}, {}) return {pcall(function() vim.fn.timer_start(5, callable_table) end)} - ]]) + ]] + ) end) it('correctly converts containers with type_idx', function() @@ -402,8 +446,14 @@ describe('luaeval()', function() eq({}, fn.luaeval('{[vim.type_idx]=vim.types.array}')) -- Presence of type_idx makes Vim ignore some keys - eq({42}, fn.luaeval('{[vim.type_idx]=vim.types.array, [vim.val_idx]=10, [5]=1, foo=2, [1]=42}')) - eq({foo=2}, fn.luaeval('{[vim.type_idx]=vim.types.dictionary, [vim.val_idx]=10, [5]=1, foo=2, [1]=42}')) + eq( + { 42 }, + fn.luaeval('{[vim.type_idx]=vim.types.array, [vim.val_idx]=10, [5]=1, foo=2, [1]=42}') + ) + eq( + { foo = 2 }, + fn.luaeval('{[vim.type_idx]=vim.types.dictionary, [vim.val_idx]=10, [5]=1, foo=2, [1]=42}') + ) eq(10, fn.luaeval('{[vim.type_idx]=vim.types.float, [vim.val_idx]=10, [5]=1, foo=2, [1]=42}')) -- The following should not crash @@ -418,7 +468,7 @@ describe('luaeval()', function() eq(true, eval('luaeval("_A.d == _A.d[1]", {"d": l})')) eq(true, eval('luaeval("_A ~= _A[1]", [l])')) - api.nvim_set_var('d', {foo=42}) + api.nvim_set_var('d', { foo = 42 }) eval('extend(d, {"d": d})') eq(true, eval('luaeval("_A == _A.d", d)')) eq(true, eval('luaeval("_A[1] == _A[1].d", [d])')) @@ -428,19 +478,23 @@ describe('luaeval()', function() it('errors out correctly when doing incorrect things in lua', function() -- Conversion errors - eq('Vim(call):E5108: Lua: [string "luaeval()"]:1: attempt to call field \'xxx_nonexistent_key_xxx\' (a nil value)', - remove_trace(exc_exec([[call luaeval("vim.xxx_nonexistent_key_xxx()")]]))) - eq('Vim(call):E5108: Lua: [string "luaeval()"]:1: ERROR', - remove_trace(exc_exec([[call luaeval("error('ERROR')")]]))) - eq('Vim(call):E5108: Lua: [NULL]', - remove_trace(exc_exec([[call luaeval("error(nil)")]]))) - end) - - it('does not leak memory when called with too long line', - function() + eq( + 'Vim(call):E5108: Lua: [string "luaeval()"]:1: attempt to call field \'xxx_nonexistent_key_xxx\' (a nil value)', + remove_trace(exc_exec([[call luaeval("vim.xxx_nonexistent_key_xxx()")]])) + ) + eq( + 'Vim(call):E5108: Lua: [string "luaeval()"]:1: ERROR', + remove_trace(exc_exec([[call luaeval("error('ERROR')")]])) + ) + eq('Vim(call):E5108: Lua: [NULL]', remove_trace(exc_exec([[call luaeval("error(nil)")]]))) + end) + + it('does not leak memory when called with too long line', function() local s = ('x'):rep(65536) - eq('Vim(call):E5107: Lua: [string "luaeval()"]:1: unexpected symbol near \')\'', - exc_exec([[call luaeval("(']] .. s ..[[' + )")]])) + eq( + 'Vim(call):E5107: Lua: [string "luaeval()"]:1: unexpected symbol near \')\'', + exc_exec([[call luaeval("(']] .. s .. [[' + )")]]) + ) eq(s, fn.luaeval('"' .. s .. '"')) end) end) @@ -478,12 +532,14 @@ describe('v:lua', function() eq(7, eval('v:lua.foo(3,4,v:null)')) eq(true, exec_lua([[return _G.val == vim.NIL]])) eq(NIL, eval('v:lua.mymod.noisy("eval")')) - eq("hey eval", api.nvim_get_current_line()) - eq("string: abc", eval('v:lua.mymod.whatis(0z616263)')) - eq("string: ", eval('v:lua.mymod.whatis(v:_null_blob)')) + eq('hey eval', api.nvim_get_current_line()) + eq('string: abc', eval('v:lua.mymod.whatis(0z616263)')) + eq('string: ', eval('v:lua.mymod.whatis(v:_null_blob)')) - eq("Vim:E5108: Lua: [string \"\"]:0: attempt to call global 'nonexistent' (a nil value)", - pcall_err(eval, 'v:lua.mymod.crashy()')) + eq( + 'Vim:E5108: Lua: [string ""]:0: attempt to call global \'nonexistent\' (a nil value)', + pcall_err(eval, 'v:lua.mymod.crashy()') + ) end) it('works when called as a method', function() @@ -491,38 +547,44 @@ describe('v:lua', function() eq(true, exec_lua([[return _G.val == nil]])) eq(321, eval('300->v:lua.foo(21, "boop")')) - eq("boop", exec_lua([[return _G.val]])) + eq('boop', exec_lua([[return _G.val]])) eq(NIL, eval('"there"->v:lua.mymod.noisy()')) - eq("hey there", api.nvim_get_current_line()) - eq({5, 10, 15, 20}, eval('[[1], [2, 3], [4]]->v:lua.vim.tbl_flatten()->map({_, v -> v * 5})')) + eq('hey there', api.nvim_get_current_line()) + eq({ 5, 10, 15, 20 }, eval('[[1], [2, 3], [4]]->v:lua.vim.tbl_flatten()->map({_, v -> v * 5})')) - eq("Vim:E5108: Lua: [string \"\"]:0: attempt to call global 'nonexistent' (a nil value)", - pcall_err(eval, '"huh?"->v:lua.mymod.crashy()')) + eq( + 'Vim:E5108: Lua: [string ""]:0: attempt to call global \'nonexistent\' (a nil value)', + pcall_err(eval, '"huh?"->v:lua.mymod.crashy()') + ) end) it('works in :call', function() command(":call v:lua.mymod.noisy('command')") - eq("hey command", api.nvim_get_current_line()) - eq("Vim(call):E5108: Lua: [string \"\"]:0: attempt to call global 'nonexistent' (a nil value)", - pcall_err(command, 'call v:lua.mymod.crashy()')) + eq('hey command', api.nvim_get_current_line()) + eq( + 'Vim(call):E5108: Lua: [string ""]:0: attempt to call global \'nonexistent\' (a nil value)', + pcall_err(command, 'call v:lua.mymod.crashy()') + ) end) it('works in func options', function() local screen = Screen.new(60, 8) api.nvim_set_option_value('omnifunc', 'v:lua.mymod.omni', {}) feed('isome st') - screen:expect{grid=[[ + screen:expect { + grid = [[ some stuff^ | {1:~ }{12: stuff }{1: }| {1:~ }{4: steam }{1: }| {1:~ }{4: strange things }{1: }| {1:~ }|*3 {5:-- Omni completion (^O^N^P) }{6:match 1 of 3} | - ]]} + ]], + } api.nvim_set_option_value('operatorfunc', 'v:lua.mymod.noisy', {}) feed('g@g@') - eq("hey line", api.nvim_get_current_line()) + eq('hey line', api.nvim_get_current_line()) end) it('supports packages', function() @@ -535,25 +597,43 @@ describe('v:lua', function() end) it('throw errors for invalid use', function() - eq([[Vim(let):E15: Invalid expression: "v:lua.func"]], pcall_err(command, "let g:Func = v:lua.func")) - eq([[Vim(let):E15: Invalid expression: "v:lua"]], pcall_err(command, "let g:Func = v:lua")) - eq([[Vim(let):E15: Invalid expression: "v:['lua']"]], pcall_err(command, "let g:Func = v:['lua']")) + eq( + [[Vim(let):E15: Invalid expression: "v:lua.func"]], + pcall_err(command, 'let g:Func = v:lua.func') + ) + eq([[Vim(let):E15: Invalid expression: "v:lua"]], pcall_err(command, 'let g:Func = v:lua')) + eq( + [[Vim(let):E15: Invalid expression: "v:['lua']"]], + pcall_err(command, "let g:Func = v:['lua']") + ) eq([[Vim:E15: Invalid expression: "v:['lua'].foo()"]], pcall_err(eval, "v:['lua'].foo()")) - eq("Vim(call):E461: Illegal variable name: v:['lua']", pcall_err(command, "call v:['lua'].baar()")) - eq("Vim:E1085: Not a callable type: v:lua", pcall_err(eval, "v:lua()")) - - eq("Vim(let):E46: Cannot change read-only variable \"v:['lua']\"", pcall_err(command, "let v:['lua'] = 'xx'")) - eq("Vim(let):E46: Cannot change read-only variable \"v:lua\"", pcall_err(command, "let v:lua = 'xx'")) - - eq("Vim:E107: Missing parentheses: v:lua.func", pcall_err(eval, "'bad'->v:lua.func")) - eq("Vim:E274: No white space allowed before parenthesis", pcall_err(eval, "'bad'->v:lua.func ()")) - eq("Vim:E107: Missing parentheses: v:lua", pcall_err(eval, "'bad'->v:lua")) - eq("Vim:E1085: Not a callable type: v:lua", pcall_err(eval, "'bad'->v:lua()")) + eq( + "Vim(call):E461: Illegal variable name: v:['lua']", + pcall_err(command, "call v:['lua'].baar()") + ) + eq('Vim:E1085: Not a callable type: v:lua', pcall_err(eval, 'v:lua()')) + + eq( + 'Vim(let):E46: Cannot change read-only variable "v:[\'lua\']"', + pcall_err(command, "let v:['lua'] = 'xx'") + ) + eq( + 'Vim(let):E46: Cannot change read-only variable "v:lua"', + pcall_err(command, "let v:lua = 'xx'") + ) + + eq('Vim:E107: Missing parentheses: v:lua.func', pcall_err(eval, "'bad'->v:lua.func")) + eq( + 'Vim:E274: No white space allowed before parenthesis', + pcall_err(eval, "'bad'->v:lua.func ()") + ) + eq('Vim:E107: Missing parentheses: v:lua', pcall_err(eval, "'bad'->v:lua")) + eq('Vim:E1085: Not a callable type: v:lua', pcall_err(eval, "'bad'->v:lua()")) eq([[Vim:E15: Invalid expression: "v:lua.()"]], pcall_err(eval, "'bad'->v:lua.()")) - eq("Vim:E1085: Not a callable type: v:lua", pcall_err(eval, "v:lua()")) - eq([[Vim:E15: Invalid expression: "v:lua.()"]], pcall_err(eval, "v:lua.()")) + eq('Vim:E1085: Not a callable type: v:lua', pcall_err(eval, 'v:lua()')) + eq([[Vim:E15: Invalid expression: "v:lua.()"]], pcall_err(eval, 'v:lua.()')) end) describe('invalid use in fold text', function() -- cgit