diff options
Diffstat (limited to 'test/functional/lua/overrides_spec.lua')
| -rw-r--r-- | test/functional/lua/overrides_spec.lua | 302 | 
1 files changed, 302 insertions, 0 deletions
| diff --git a/test/functional/lua/overrides_spec.lua b/test/functional/lua/overrides_spec.lua new file mode 100644 index 0000000000..007d40874f --- /dev/null +++ b/test/functional/lua/overrides_spec.lua @@ -0,0 +1,302 @@ +-- 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) | 
