Files
neovim/test/functional/lua/overrides_spec.lua

292 lines
13 KiB
Lua
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

-- Test for Vim overrides of lua built-ins
local helpers = require('test.functional.helpers')(after_each)
local Screen = require('test.functional.ui.screen')
local eq = helpers.eq
local neq = helpers.neq
local NIL = helpers.NIL
local feed = helpers.feed
local clear = helpers.clear
local funcs = helpers.funcs
local meths = helpers.meths
local iswin = helpers.iswin
local command = helpers.command
local write_file = helpers.write_file
local redir_exec = helpers.redir_exec
local alter_slashes = helpers.alter_slashes
local screen
local fname = 'Xtest-functional-lua-overrides-luafile'
before_each(clear)
after_each(function()
os.remove(fname)
end)
describe('print', function()
it('returns nothing', function()
eq(NIL, funcs.luaeval('print("abc")'))
eq(0, funcs.luaeval('select("#", print("abc"))'))
end)
it('allows catching printed text with :execute', function()
eq('\nabc', funcs.execute('lua print("abc")'))
eq('\nabc', funcs.execute('luado print("abc")'))
eq('\nabc', funcs.execute('call luaeval("print(\'abc\')")'))
write_file(fname, 'print("abc")')
eq('\nabc', funcs.execute('luafile ' .. fname))
eq('\nabc', redir_exec('lua print("abc")'))
eq('\nabc', redir_exec('luado print("abc")'))
eq('\nabc', redir_exec('call luaeval("print(\'abc\')")'))
write_file(fname, 'print("abc")')
eq('\nabc', redir_exec('luafile ' .. fname))
end)
it('handles errors in __tostring', function()
write_file(fname, [[
local meta_nilerr = { __tostring = function() error(nil) end }
local meta_abcerr = { __tostring = function() error("abc") end }
local meta_tblout = { __tostring = function() return {"TEST"} end }
v_nilerr = setmetatable({}, meta_nilerr)
v_abcerr = setmetatable({}, meta_abcerr)
v_tblout = setmetatable({}, meta_tblout)
]])
eq('', redir_exec('luafile ' .. fname))
eq('\nE5114: Error while converting print argument #2: [NULL]',
redir_exec('lua print("foo", v_nilerr, "bar")'))
eq('\nE5114: Error while converting print argument #2: Xtest-functional-lua-overrides-luafile:2: abc',
redir_exec('lua print("foo", v_abcerr, "bar")'))
eq('\nE5114: Error while converting print argument #2: <Unknown error: lua_tolstring returned NULL for tostring result>',
redir_exec('lua print("foo", v_tblout, "bar")'))
end)
it('prints strings with NULs and NLs correctly', function()
meths.set_option('more', true)
eq('\nabc ^@ def\nghi^@^@^@jkl\nTEST\n\n\nT\n',
redir_exec([[lua print("abc \0 def\nghi\0\0\0jkl\nTEST\n\n\nT\n")]]))
eq('\nabc ^@ def\nghi^@^@^@jkl\nTEST\n\n\nT^@',
redir_exec([[lua print("abc \0 def\nghi\0\0\0jkl\nTEST\n\n\nT\0")]]))
eq('\nT^@', redir_exec([[lua print("T\0")]]))
eq('\nT\n', redir_exec([[lua print("T\n")]]))
end)
end)
describe('debug.debug', function()
before_each(function()
screen = Screen.new()
screen:attach()
screen:set_default_attr_ids({
[0] = {bold=true, foreground=255},
E = {foreground = Screen.colors.Grey100, background = Screen.colors.Red},
cr = {bold = true, foreground = Screen.colors.SeaGreen4},
})
end)
it('works', function()
command([[lua
function Test(a)
print(a)
debug.debug()
print(a * 100)
end
]])
feed(':lua Test()\n')
screen:expect([[
{0:~ }|
{0:~ }|
{0:~ }|
{0:~ }|
{0:~ }|
{0:~ }|
{0:~ }|
{0:~ }|
{0:~ }|
{0:~ }|
{0:~ }|
{0:~ }|
nil |
lua_debug> ^ |
]])
feed('print("TEST")\n')
screen:expect([[
{0:~ }|
{0:~ }|
{0:~ }|
{0:~ }|
{0:~ }|
{0:~ }|
{0:~ }|
{0:~ }|
{0:~ }|
{0:~ }|
nil |
lua_debug> print("TEST") |
TEST |
lua_debug> ^ |
]])
feed('<C-c>')
screen:expect([[
{0:~ }|
{0:~ }|
{0:~ }|
{0:~ }|
{0:~ }|
{0:~ }|
nil |
lua_debug> print("TEST") |
TEST |
|
{E:E5105: Error while calling lua chunk: [string "<VimL }|
{E:compiled string>"]:5: attempt to perform arithmetic o}|
{E:n local 'a' (a nil value)} |
Interrupt: {cr:Press ENTER or type command to continue}^ |
]])
feed('<C-l>:lua Test()\n')
screen:expect([[
{0:~ }|
{0:~ }|
{0:~ }|
{0:~ }|
{0:~ }|
{0:~ }|
{0:~ }|
{0:~ }|
{0:~ }|
{0:~ }|
{0:~ }|
{0:~ }|
nil |
lua_debug> ^ |
]])
feed('\n')
screen:expect([[
{0:~ }|
{0:~ }|
{0:~ }|
{0:~ }|
{0:~ }|
{0:~ }|
{0:~ }|
{0:~ }|
nil |
lua_debug> |
{E:E5105: Error while calling lua chunk: [string "<VimL }|
{E:compiled string>"]:5: attempt to perform arithmetic o}|
{E:n local 'a' (a nil value)} |
{cr:Press ENTER or type command to continue}^ |
]])
end)
end)
describe('package.path/package.cpath', function()
local sl = alter_slashes
local function get_new_paths(sufs, runtimepaths)
runtimepaths = runtimepaths or meths.list_runtime_paths()
local new_paths = {}
for _, v in ipairs(runtimepaths) do
for _, suf in ipairs(sufs) do
new_paths[#new_paths + 1] = v .. suf:sub(1, 1) .. 'lua' .. suf
end
end
return new_paths
end
local function execute_lua(cmd, ...)
return meths.execute_lua(cmd, {...})
end
local function eval_lua(expr, ...)
return meths.execute_lua('return ' .. expr, {...})
end
local function set_path(which, value)
return execute_lua('package[select(1, ...)] = select(2, ...)', which, value)
end
it('contains directories from &runtimepath on first invocation', function()
local new_paths = get_new_paths(sl{'/?.lua', '/?/init.lua'})
local new_paths_str = table.concat(new_paths, ';')
eq(new_paths_str, eval_lua('package.path'):sub(1, #new_paths_str))
local new_cpaths = get_new_paths(iswin() and {'\\?.dll'} or {'/?.so'})
local new_cpaths_str = table.concat(new_cpaths, ';')
eq(new_cpaths_str, eval_lua('package.cpath'):sub(1, #new_cpaths_str))
end)
it('puts directories from &runtimepath always at the start', function()
meths.set_option('runtimepath', 'a,b')
local new_paths = get_new_paths(sl{'/?.lua', '/?/init.lua'}, {'a', 'b'})
local new_paths_str = table.concat(new_paths, ';')
eq(new_paths_str, eval_lua('package.path'):sub(1, #new_paths_str))
set_path('path', sl'foo/?.lua;foo/?/init.lua;' .. new_paths_str)
neq(new_paths_str, eval_lua('package.path'):sub(1, #new_paths_str))
command('set runtimepath+=c')
new_paths = get_new_paths(sl{'/?.lua', '/?/init.lua'}, {'a', 'b', 'c'})
new_paths_str = table.concat(new_paths, ';')
eq(new_paths_str, eval_lua('package.path'):sub(1, #new_paths_str))
end)
it('understands uncommon suffixes', function()
set_path('path', './?/foo/bar/baz/x.nlua')
meths.set_option('runtimepath', 'a')
local new_paths = get_new_paths({'/?/foo/bar/baz/x.nlua'}, {'a'})
local new_paths_str = table.concat(new_paths, ';')
eq(new_paths_str, eval_lua('package.path'):sub(1, #new_paths_str))
set_path('path', './yyy?zzz/x')
meths.set_option('runtimepath', 'b')
new_paths = get_new_paths({'/yyy?zzz/x'}, {'b'})
new_paths_str = table.concat(new_paths, ';')
eq(new_paths_str, eval_lua('package.path'):sub(1, #new_paths_str))
set_path('path', './yyy?zzz/123?ghi/x')
meths.set_option('runtimepath', 'b')
new_paths = get_new_paths({'/yyy?zzz/123?ghi/x'}, {'b'})
new_paths_str = table.concat(new_paths, ';')
eq(new_paths_str, eval_lua('package.path'):sub(1, #new_paths_str))
end)
it('preserves empty items', function()
local many_empty_path = ';;;;;;'
local many_empty_cpath = ';;;;;;./?.luaso'
set_path('path', many_empty_path)
set_path('cpath', many_empty_cpath)
meths.set_option('runtimepath', 'a')
-- No suffixes known, so cant add anything
eq(many_empty_path, eval_lua('package.path'))
local new_paths = get_new_paths({'/?.luaso'}, {'a'})
local new_paths_str = table.concat(new_paths, ';')
eq(new_paths_str .. ';' .. many_empty_cpath, eval_lua('package.cpath'))
end)
it('preserves empty value', function()
set_path('path', '')
meths.set_option('runtimepath', 'a')
-- No suffixes known, so cant add anything
eq('', eval_lua('package.path'))
end)
it('purges out all additions if runtimepath is set to empty', function()
local new_paths = get_new_paths(sl{'/?.lua', '/?/init.lua'})
local new_paths_str = table.concat(new_paths, ';')
local path = eval_lua('package.path')
eq(new_paths_str, path:sub(1, #new_paths_str))
local new_cpaths = get_new_paths(iswin() and {'\\?.dll'} or {'/?.so'})
local new_cpaths_str = table.concat(new_cpaths, ';')
local cpath = eval_lua('package.cpath')
eq(new_cpaths_str, cpath:sub(1, #new_cpaths_str))
meths.set_option('runtimepath', '')
eq(path:sub(#new_paths_str + 2, -1), eval_lua('package.path'))
eq(cpath:sub(#new_cpaths_str + 2, -1), eval_lua('package.cpath'))
end)
it('works with paths with escaped commas', function()
meths.set_option('runtimepath', '\\,')
local new_paths = get_new_paths(sl{'/?.lua', '/?/init.lua'}, {','})
local new_paths_str = table.concat(new_paths, ';')
eq(new_paths_str, eval_lua('package.path'):sub(1, #new_paths_str))
end)
it('ignores paths with semicolons', function()
meths.set_option('runtimepath', 'foo;bar,\\,')
local new_paths = get_new_paths(sl{'/?.lua', '/?/init.lua'}, {','})
local new_paths_str = table.concat(new_paths, ';')
eq(new_paths_str, eval_lua('package.path'):sub(1, #new_paths_str))
end)
end)