123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303 |
- -- 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)
- it('prints empty strings correctly', function()
- -- Regression: first test used to crash
- eq('', redir_exec('lua print("")'))
- eq('\n def', redir_exec('lua print("", "def")'))
- eq('\nabc ', redir_exec('lua print("abc", "")'))
- eq('\nabc def', redir_exec('lua print("abc", "", "def")'))
- 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},
- })
- command("set display-=msgsep")
- 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 = {}
- local sep = package.config:sub(1, 1)
- for _, v in ipairs(runtimepaths) do
- for _, suf in ipairs(sufs) do
- new_paths[#new_paths + 1] = v .. sep .. '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('cpath', './?/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.cpath'):sub(1, #new_paths_str))
- set_path('cpath', './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.cpath'):sub(1, #new_paths_str))
- set_path('cpath', './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.cpath'):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')
- local new_paths = get_new_paths(sl{'/?.lua', '/?/init.lua'}, {'a'})
- local new_paths_str = table.concat(new_paths, ';')
- eq(new_paths_str .. ';' .. many_empty_path, eval_lua('package.path'))
- local new_cpaths = get_new_paths({'/?.luaso'}, {'a'})
- local new_cpaths_str = table.concat(new_cpaths, ';')
- eq(new_cpaths_str .. ';' .. many_empty_cpath, eval_lua('package.cpath'))
- end)
- it('preserves empty value', function()
- set_path('path', '')
- meths.set_option('runtimepath', 'a')
- local new_paths = get_new_paths(sl{'/?.lua', '/?/init.lua'}, {'a'})
- local new_paths_str = table.concat(new_paths, ';')
- eq(new_paths_str .. ';', 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)
|