test/vim.validate(): assert normalized stacktrace

- The previous commit lost information in the tests. Instead, add some
  more "normalization" substitutions in pcall_err(), so that the general
  shape of the stacktrace is included in the asserted text.
- Eliminate contains(), it is redundant with matches()
This commit is contained in:
Justin M. Keyes
2020-09-12 19:04:22 -07:00
committed by TJ DeVries
parent aad7a74053
commit 8e77d70e29
9 changed files with 190 additions and 103 deletions

View File

@@ -514,20 +514,20 @@ do
local optional = (true == spec[3]) local optional = (true == spec[3])
if type(t) == 'string' then if type(t) == 'string' then
local translated_type_name = type_names[t] local t_name = type_names[t]
if not translated_type_name then if not t_name then
return false, string.format('invalid type name: %s', t) return false, string.format('invalid type name: %s', t)
end end
if (not optional or val ~= nil) and not _is_type(val, translated_type_name) then if (not optional or val ~= nil) and not _is_type(val, t_name) then
return false, string.format("%s: expected %s, got %s", param_name, translated_type_name, type(val)) return false, string.format("%s: expected %s, got %s", param_name, t_name, type(val))
end end
elseif vim.is_callable(t) then elseif vim.is_callable(t) then
-- Check user-provided validation function. -- Check user-provided validation function.
local valid, optional_message = t(val) local valid, optional_message = t(val)
if not valid then if not valid then
local error_message = string.format("%s: expected %s, got %s", param_name, (spec[3] or '?'), val) local error_message = string.format("%s: expected %s, got %s", param_name, (spec[3] or '?'), val)
if not (optional_message == nil) then if optional_message ~= nil then
error_message = error_message .. string.format(". Info: %s", optional_message) error_message = error_message .. string.format(". Info: %s", optional_message)
end end

View File

@@ -449,19 +449,19 @@ describe('API', function()
end) end)
it('reports errors', function() it('reports errors', function()
eq([[Error loading lua: [string "<nvim>"]:1: '=' expected near '+']], eq([[Error loading lua: [string "<nvim>"]:0: '=' expected near '+']],
pcall_err(meths.exec_lua, 'a+*b', {})) pcall_err(meths.exec_lua, 'a+*b', {}))
eq([[Error loading lua: [string "<nvim>"]:1: unexpected symbol near '1']], eq([[Error loading lua: [string "<nvim>"]:0: unexpected symbol near '1']],
pcall_err(meths.exec_lua, '1+2', {})) pcall_err(meths.exec_lua, '1+2', {}))
eq([[Error loading lua: [string "<nvim>"]:1: unexpected symbol]], eq([[Error loading lua: [string "<nvim>"]:0: unexpected symbol]],
pcall_err(meths.exec_lua, 'aa=bb\0', {})) pcall_err(meths.exec_lua, 'aa=bb\0', {}))
eq([[Error executing lua: [string "<nvim>"]:1: attempt to call global 'bork' (a nil value)]], eq([[Error executing lua: [string "<nvim>"]:0: attempt to call global 'bork' (a nil value)]],
pcall_err(meths.exec_lua, 'bork()', {})) pcall_err(meths.exec_lua, 'bork()', {}))
eq('Error executing lua: [string "<nvim>"]:1: did\nthe\nfail', eq('Error executing lua: [string "<nvim>"]:0: did\nthe\nfail',
pcall_err(meths.exec_lua, 'error("did\\nthe\\nfail")', {})) pcall_err(meths.exec_lua, 'error("did\\nthe\\nfail")', {}))
end) end)
@@ -605,7 +605,7 @@ describe('API', function()
end) end)
it('vim.paste() failure', function() it('vim.paste() failure', function()
nvim('exec_lua', 'vim.paste = (function(lines, phase) error("fake fail") end)', {}) nvim('exec_lua', 'vim.paste = (function(lines, phase) error("fake fail") end)', {})
eq([[Error executing lua: [string "<nvim>"]:1: fake fail]], eq([[Error executing lua: [string "<nvim>"]:0: fake fail]],
pcall_err(request, 'nvim_paste', 'line 1\nline 2\nline 3', false, 1)) pcall_err(request, 'nvim_paste', 'line 1\nline 2\nline 3', false, 1))
end) end)
end) end)

View File

@@ -43,7 +43,7 @@ describe(':lua command', function()
eq({'', 'ETTS', 'TTSE', 'STTE'}, curbufmeths.get_lines(0, 100, false)) eq({'', 'ETTS', 'TTSE', 'STTE'}, curbufmeths.get_lines(0, 100, false))
end) end)
it('throws catchable errors', function() it('throws catchable errors', function()
eq([[Vim(lua):E5107: Error loading lua [string ":lua"]:1: unexpected symbol near ')']], eq([[Vim(lua):E5107: Error loading lua [string ":lua"]:0: unexpected symbol near ')']],
pcall_err(command, 'lua ()')) pcall_err(command, 'lua ()'))
eq([[Vim(lua):E5108: Error executing lua [string ":lua"]:1: TEST]], eq([[Vim(lua):E5108: Error executing lua [string ":lua"]:1: TEST]],
exc_exec('lua error("TEST")')) exc_exec('lua error("TEST")'))

View File

@@ -477,14 +477,14 @@ describe('v:lua', function()
eq(NIL, eval('v:lua.mymod.noisy("eval")')) eq(NIL, eval('v:lua.mymod.noisy("eval")'))
eq("hey eval", meths.get_current_line()) eq("hey eval", meths.get_current_line())
eq("Vim:E5108: Error executing lua [string \"<nvim>\"]:10: attempt to call global 'nonexistent' (a nil value)", eq("Vim:E5108: Error executing lua [string \"<nvim>\"]:0: attempt to call global 'nonexistent' (a nil value)",
pcall_err(eval, 'v:lua.mymod.crashy()')) pcall_err(eval, 'v:lua.mymod.crashy()'))
end) end)
it('works in :call', function() it('works in :call', function()
command(":call v:lua.mymod.noisy('command')") command(":call v:lua.mymod.noisy('command')")
eq("hey command", meths.get_current_line()) eq("hey command", meths.get_current_line())
eq("Vim(call):E5108: Error executing lua [string \"<nvim>\"]:10: attempt to call global 'nonexistent' (a nil value)", eq("Vim(call):E5108: Error executing lua [string \"<nvim>\"]:0: attempt to call global 'nonexistent' (a nil value)",
pcall_err(command, 'call v:lua.mymod.crashy()')) pcall_err(command, 'call v:lua.mymod.crashy()'))
end) end)

View File

@@ -15,14 +15,14 @@ before_each(clear)
describe('treesitter API', function() describe('treesitter API', function()
-- error tests not requiring a parser library -- error tests not requiring a parser library
it('handles missing language', function() it('handles missing language', function()
eq("Error executing lua: .../language.lua: no parser for 'borklang' language, see :help treesitter-parsers", eq("Error executing lua: .../language.lua:0: no parser for 'borklang' language, see :help treesitter-parsers",
pcall_err(exec_lua, "parser = vim.treesitter.get_parser(0, 'borklang')")) pcall_err(exec_lua, "parser = vim.treesitter.get_parser(0, 'borklang')"))
-- actual message depends on platform -- actual message depends on platform
matches("Error executing lua: Failed to load parser: uv_dlopen: .+", matches("Error executing lua: Failed to load parser: uv_dlopen: .+",
pcall_err(exec_lua, "parser = vim.treesitter.require_language('borklang', 'borkbork.so')")) pcall_err(exec_lua, "parser = vim.treesitter.require_language('borklang', 'borkbork.so')"))
eq("Error executing lua: .../language.lua: no parser for 'borklang' language, see :help treesitter-parsers", eq("Error executing lua: .../language.lua:0: no parser for 'borklang' language, see :help treesitter-parsers",
pcall_err(exec_lua, "parser = vim.treesitter.inspect_language('borklang')")) pcall_err(exec_lua, "parser = vim.treesitter.inspect_language('borklang')"))
end) end)

View File

@@ -4,16 +4,16 @@ local Screen = require('test.functional.ui.screen')
local funcs = helpers.funcs local funcs = helpers.funcs
local meths = helpers.meths local meths = helpers.meths
local dedent = helpers.dedent
local command = helpers.command local command = helpers.command
local clear = helpers.clear local clear = helpers.clear
local eq = helpers.eq local eq = helpers.eq
local ok = helpers.ok local ok = helpers.ok
local eval = helpers.eval local eval = helpers.eval
local feed = helpers.feed local feed = helpers.feed
local pcall_err = helpers.pcall_err local pcall_err_withfile = helpers.pcall_err_withfile
local exec_lua = helpers.exec_lua local exec_lua = helpers.exec_lua
local matches = helpers.matches local matches = helpers.matches
local contains = helpers.contains
local source = helpers.source local source = helpers.source
local NIL = helpers.NIL local NIL = helpers.NIL
local retry = helpers.retry local retry = helpers.retry
@@ -129,8 +129,8 @@ describe('lua stdlib', function()
eq(false, funcs.luaeval('vim.startswith("123", "2")')) eq(false, funcs.luaeval('vim.startswith("123", "2")'))
eq(false, funcs.luaeval('vim.startswith("123", "1234")')) eq(false, funcs.luaeval('vim.startswith("123", "1234")'))
eq("string", type(pcall_err(funcs.luaeval, 'vim.startswith("123", nil)'))) eq("string", type(pcall_err_withfile(funcs.luaeval, 'vim.startswith("123", nil)')))
eq("string", type(pcall_err(funcs.luaeval, 'vim.startswith(nil, "123")'))) eq("string", type(pcall_err_withfile(funcs.luaeval, 'vim.startswith(nil, "123")')))
end) end)
it('vim.endswith', function() it('vim.endswith', function()
@@ -143,8 +143,8 @@ describe('lua stdlib', function()
eq(false, funcs.luaeval('vim.endswith("123", "2")')) eq(false, funcs.luaeval('vim.endswith("123", "2")'))
eq(false, funcs.luaeval('vim.endswith("123", "1234")')) eq(false, funcs.luaeval('vim.endswith("123", "1234")'))
eq("string", type(pcall_err(funcs.luaeval, 'vim.endswith("123", nil)'))) eq("string", type(pcall_err_withfile(funcs.luaeval, 'vim.endswith("123", nil)')))
eq("string", type(pcall_err(funcs.luaeval, 'vim.endswith(nil, "123")'))) eq("string", type(pcall_err_withfile(funcs.luaeval, 'vim.endswith(nil, "123")')))
end) end)
it("vim.str_utfindex/str_byteindex", function() it("vim.str_utfindex/str_byteindex", function()
@@ -183,10 +183,10 @@ describe('lua stdlib', function()
eq({"yy","xx"}, exec_lua("return test_table")) eq({"yy","xx"}, exec_lua("return test_table"))
-- Validates args. -- Validates args.
eq('Error executing lua: vim.schedule: expected function', eq('.../helpers.lua:0: Error executing lua: vim.schedule: expected function',
pcall_err(exec_lua, "vim.schedule('stringly')")) pcall_err_withfile(exec_lua, "vim.schedule('stringly')"))
eq('Error executing lua: vim.schedule: expected function', eq('.../helpers.lua:0: Error executing lua: vim.schedule: expected function',
pcall_err(exec_lua, "vim.schedule()")) pcall_err_withfile(exec_lua, "vim.schedule()"))
exec_lua([[ exec_lua([[
vim.schedule(function() vim.schedule(function()
@@ -258,14 +258,29 @@ describe('lua stdlib', function()
} }
for _, t in ipairs(loops) do for _, t in ipairs(loops) do
matches(".*Infinite loop detected", pcall_err(split, t[1], t[2])) matches(".*Infinite loop detected", pcall_err_withfile(split, t[1], t[2]))
end end
-- Validates args. -- Validates args.
eq(true, pcall(split, 'string', 'string')) eq(true, pcall(split, 'string', 'string'))
contains('s: expected string, got number', pcall_err(split, 1, 'string')) eq(dedent([[
contains('sep: expected string, got number', pcall_err(split, 'string', 1)) .../helpers.lua:0: Error executing lua: shared.lua:0: s: expected string, got number
contains('plain: expected boolean, got number', pcall_err(split, 'string', 'string', 1)) stack traceback:
shared.lua:0: in function 'gsplit'
shared.lua:0: in function <shared.lua:0>]]),
pcall_err_withfile(split, 1, 'string'))
eq(dedent([[
.../helpers.lua:0: Error executing lua: shared.lua:0: sep: expected string, got number
stack traceback:
shared.lua:0: in function 'gsplit'
shared.lua:0: in function <shared.lua:0>]]),
pcall_err_withfile(split, 'string', 1))
eq(dedent([[
.../helpers.lua:0: Error executing lua: shared.lua:0: plain: expected boolean, got number
stack traceback:
shared.lua:0: in function 'gsplit'
shared.lua:0: in function <shared.lua:0>]]),
pcall_err_withfile(split, 'string', 'string', 1))
end) end)
it('vim.trim', function() it('vim.trim', function()
@@ -285,7 +300,11 @@ describe('lua stdlib', function()
end end
-- Validates args. -- Validates args.
contains('s: expected string, got number', pcall_err(trim, 2)) eq(dedent([[
.../helpers.lua:0: Error executing lua: shared.lua:0: s: expected string, got number
stack traceback:
shared.lua:0: in function <shared.lua:0>]]),
pcall_err_withfile(trim, 2))
end) end)
it('vim.inspect', function() it('vim.inspect', function()
@@ -350,8 +369,8 @@ describe('lua stdlib', function()
return t1.f() ~= t2.f() return t1.f() ~= t2.f()
]])) ]]))
eq('Error executing lua: .../shared.lua: Cannot deepcopy object of type thread', eq('.../helpers.lua:0: Error executing lua: shared.lua:0: Cannot deepcopy object of type thread',
pcall_err(exec_lua, [[ pcall_err_withfile(exec_lua, [[
local thread = coroutine.create(function () return 0 end) local thread = coroutine.create(function () return 0 end)
local t = {thr = thread} local t = {thr = thread}
vim.deepcopy(t) vim.deepcopy(t)
@@ -363,8 +382,11 @@ describe('lua stdlib', function()
eq('foo%%%-bar', exec_lua([[return vim.pesc(vim.pesc('foo-bar'))]])) eq('foo%%%-bar', exec_lua([[return vim.pesc(vim.pesc('foo-bar'))]]))
-- Validates args. -- Validates args.
contains('s: expected string, got number', eq(dedent([[
pcall_err(exec_lua, [[return vim.pesc(2)]])) .../helpers.lua:0: Error executing lua: shared.lua:0: s: expected string, got number
stack traceback:
shared.lua:0: in function <shared.lua:0>]]),
pcall_err_withfile(exec_lua, [[return vim.pesc(2)]]))
end) end)
it('vim.tbl_keys', function() it('vim.tbl_keys', function()
@@ -488,20 +510,20 @@ describe('lua stdlib', function()
return c.x.a == 1 and c.x.b == 2 and c.x.c == nil and count == 1 return c.x.a == 1 and c.x.b == 2 and c.x.c == nil and count == 1
]])) ]]))
eq('Error executing lua: .../shared.lua: invalid "behavior": nil', eq('.../helpers.lua:0: Error executing lua: shared.lua:0: invalid "behavior": nil',
pcall_err(exec_lua, [[ pcall_err_withfile(exec_lua, [[
return vim.tbl_extend() return vim.tbl_extend()
]]) ]])
) )
eq('Error executing lua: .../shared.lua: wrong number of arguments (given 1, expected at least 3)', eq('.../helpers.lua:0: Error executing lua: shared.lua:0: wrong number of arguments (given 1, expected at least 3)',
pcall_err(exec_lua, [[ pcall_err_withfile(exec_lua, [[
return vim.tbl_extend("keep") return vim.tbl_extend("keep")
]]) ]])
) )
eq('Error executing lua: .../shared.lua: wrong number of arguments (given 2, expected at least 3)', eq('.../helpers.lua:0: Error executing lua: shared.lua:0: wrong number of arguments (given 2, expected at least 3)',
pcall_err(exec_lua, [[ pcall_err_withfile(exec_lua, [[
return vim.tbl_extend("keep", {}) return vim.tbl_extend("keep", {})
]]) ]])
) )
@@ -576,20 +598,20 @@ describe('lua stdlib', function()
return vim.tbl_islist(c) and count == 0 return vim.tbl_islist(c) and count == 0
]])) ]]))
eq('Error executing lua: .../shared.lua: invalid "behavior": nil', eq('.../helpers.lua:0: Error executing lua: shared.lua:0: invalid "behavior": nil',
pcall_err(exec_lua, [[ pcall_err_withfile(exec_lua, [[
return vim.tbl_deep_extend() return vim.tbl_deep_extend()
]]) ]])
) )
eq('Error executing lua: .../shared.lua: wrong number of arguments (given 1, expected at least 3)', eq('.../helpers.lua:0: Error executing lua: shared.lua:0: wrong number of arguments (given 1, expected at least 3)',
pcall_err(exec_lua, [[ pcall_err_withfile(exec_lua, [[
return vim.tbl_deep_extend("keep") return vim.tbl_deep_extend("keep")
]]) ]])
) )
eq('Error executing lua: .../shared.lua: wrong number of arguments (given 2, expected at least 3)', eq('.../helpers.lua:0: Error executing lua: shared.lua:0: wrong number of arguments (given 2, expected at least 3)',
pcall_err(exec_lua, [[ pcall_err_withfile(exec_lua, [[
return vim.tbl_deep_extend("keep", {}) return vim.tbl_deep_extend("keep", {})
]]) ]])
) )
@@ -621,14 +643,17 @@ describe('lua stdlib', function()
it('vim.list_extend', function() it('vim.list_extend', function()
eq({1,2,3}, exec_lua [[ return vim.list_extend({1}, {2,3}) ]]) eq({1,2,3}, exec_lua [[ return vim.list_extend({1}, {2,3}) ]])
eq(dedent([[
.../helpers.lua:0: Error executing lua: shared.lua:0: src: expected table, got nil
stack traceback:
shared.lua:0: in function <shared.lua:0>]]),
pcall_err_withfile(exec_lua, [[ return vim.list_extend({1}, nil) ]]))
eq({1,2}, exec_lua [[ return vim.list_extend({1}, {2;a=1}) ]]) 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(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}, 2) ]])
eq({}, exec_lua [[ return vim.list_extend({}, {2;a=1}, 1, -1) ]]) 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) ]])
contains('src: expected table, got nil', pcall_err(exec_lua, [[ return vim.list_extend({1}, nil) ]]))
end) end)
it('vim.tbl_add_reverse_lookup', function() it('vim.tbl_add_reverse_lookup', function()
@@ -645,8 +670,8 @@ describe('lua stdlib', function()
assert(vim.deep_equal(a, { A = 1; [1] = 'A'; })) assert(vim.deep_equal(a, { A = 1; [1] = 'A'; }))
vim.tbl_add_reverse_lookup(a) vim.tbl_add_reverse_lookup(a)
]] ]]
matches('Error executing lua: .../shared.lua: The reverse lookup found an existing value for "[1A]" while processing key "[1A]"', matches('.../helpers.lua:0: Error executing lua: shared.lua:0: The reverse lookup found an existing value for "[1A]" while processing key "[1A]"',
pcall_err(exec_lua, code)) pcall_err_withfile(exec_lua, code))
end) end)
it('vim.call, vim.fn', function() it('vim.call, vim.fn', function()
@@ -817,30 +842,77 @@ describe('lua stdlib', function()
exec_lua("vim.validate{arg1={{}, 't' }, arg2={ 'foo', 's' }}") exec_lua("vim.validate{arg1={{}, 't' }, arg2={ 'foo', 's' }}")
exec_lua("vim.validate{arg1={2, function(a) return (a % 2) == 0 end, 'even number' }}") exec_lua("vim.validate{arg1={2, function(a) return (a % 2) == 0 end, 'even number' }}")
contains("expected table, got number", pcall_err(exec_lua, "vim.validate{ 1, 'x' }")) eq(dedent([[
contains("invalid type name: x", pcall_err(exec_lua, "vim.validate{ arg1={ 1, 'x' }}")) .../helpers.lua:0: Error executing lua: [string "<nvim>"]:0: opt[1]: expected table, got number
contains("invalid type name: 1", pcall_err(exec_lua, "vim.validate{ arg1={ 1, 1 }}")) stack traceback:
contains("invalid type name: nil", pcall_err(exec_lua, "vim.validate{ arg1={ 1 }}")) [string "<nvim>"]:0: in main chunk]]),
pcall_err_withfile(exec_lua, "vim.validate{ 1, 'x' }"))
eq(dedent([[
.../helpers.lua:0: Error executing lua: [string "<nvim>"]:0: invalid type name: x
stack traceback:
[string "<nvim>"]:0: in main chunk]]),
pcall_err_withfile(exec_lua, "vim.validate{ arg1={ 1, 'x' }}"))
eq(dedent([[
.../helpers.lua:0: Error executing lua: [string "<nvim>"]:0: invalid type name: 1
stack traceback:
[string "<nvim>"]:0: in main chunk]]),
pcall_err_withfile(exec_lua, "vim.validate{ arg1={ 1, 1 }}"))
eq(dedent([[
.../helpers.lua:0: Error executing lua: [string "<nvim>"]:0: invalid type name: nil
stack traceback:
[string "<nvim>"]:0: in main chunk]]),
pcall_err_withfile(exec_lua, "vim.validate{ arg1={ 1 }}"))
-- Validated parameters are required by default. -- Validated parameters are required by default.
contains("arg1: expected string, got nil", eq(dedent([[
pcall_err(exec_lua, "vim.validate{ arg1={ nil, 's' }}")) .../helpers.lua:0: Error executing lua: [string "<nvim>"]:0: arg1: expected string, got nil
stack traceback:
[string "<nvim>"]:0: in main chunk]]),
pcall_err_withfile(exec_lua, "vim.validate{ arg1={ nil, 's' }}"))
-- Explicitly required. -- Explicitly required.
contains("arg1: expected string, got nil", eq(dedent([[
pcall_err(exec_lua, "vim.validate{ arg1={ nil, 's', false }}")) .../helpers.lua:0: Error executing lua: [string "<nvim>"]:0: arg1: expected string, got nil
stack traceback:
[string "<nvim>"]:0: in main chunk]]),
pcall_err_withfile(exec_lua, "vim.validate{ arg1={ nil, 's', false }}"))
contains("arg1: expected table, got number", eq(dedent([[
pcall_err(exec_lua, "vim.validate{arg1={1, 't'}}")) .../helpers.lua:0: Error executing lua: [string "<nvim>"]:0: arg1: expected table, got number
contains("arg2: expected string, got number", stack traceback:
pcall_err(exec_lua, "vim.validate{arg1={{}, 't'}, arg2={1, 's'}}")) [string "<nvim>"]:0: in main chunk]]),
contains("arg2: expected string, got nil", pcall_err_withfile(exec_lua, "vim.validate{arg1={1, 't'}}"))
pcall_err(exec_lua, "vim.validate{arg1={{}, 't'}, arg2={nil, 's'}}")) eq(dedent([[
contains("arg2: expected string, got nil", .../helpers.lua:0: Error executing lua: [string "<nvim>"]:0: arg2: expected string, got number
pcall_err(exec_lua, "vim.validate{arg1={{}, 't'}, arg2={nil, 's'}}")) stack traceback:
contains("arg1: expected even number, got 3", [string "<nvim>"]:0: in main chunk]]),
pcall_err(exec_lua, "vim.validate{arg1={3, function(a) return a == 1 end, 'even number'}}")) pcall_err_withfile(exec_lua, "vim.validate{arg1={{}, 't'}, arg2={1, 's'}}"))
contains("arg1: expected %?, got 3", eq(dedent([[
pcall_err(exec_lua, "vim.validate{arg1={3, function(a) return a == 1 end}}")) .../helpers.lua:0: Error executing lua: [string "<nvim>"]:0: arg2: expected string, got nil
stack traceback:
[string "<nvim>"]:0: in main chunk]]),
pcall_err_withfile(exec_lua, "vim.validate{arg1={{}, 't'}, arg2={nil, 's'}}"))
eq(dedent([[
.../helpers.lua:0: Error executing lua: [string "<nvim>"]:0: arg2: expected string, got nil
stack traceback:
[string "<nvim>"]:0: in main chunk]]),
pcall_err_withfile(exec_lua, "vim.validate{arg1={{}, 't'}, arg2={nil, 's'}}"))
eq(dedent([[
.../helpers.lua:0: Error executing lua: [string "<nvim>"]:0: arg1: expected even number, got 3
stack traceback:
[string "<nvim>"]:0: in main chunk]]),
pcall_err_withfile(exec_lua, "vim.validate{arg1={3, function(a) return a == 1 end, 'even number'}}"))
eq(dedent([[
.../helpers.lua:0: Error executing lua: [string "<nvim>"]:0: arg1: expected ?, got 3
stack traceback:
[string "<nvim>"]:0: in main chunk]]),
pcall_err_withfile(exec_lua, "vim.validate{arg1={3, function(a) return a == 1 end}}"))
-- Pass an additional message back.
eq(dedent([[
.../helpers.lua:0: Error executing lua: [string "<nvim>"]:0: arg1: expected ?, got 3. Info: TEST_MSG
stack traceback:
[string "<nvim>"]:0: in main chunk]]),
pcall_err_withfile(exec_lua, "vim.validate{arg1={3, function(a) return a == 1, 'TEST_MSG' end}}"))
end) end)
it('vim.is_callable', function() it('vim.is_callable', function()
@@ -985,10 +1057,10 @@ describe('lua stdlib', function()
]] ]]
eq('', funcs.luaeval "vim.bo.filetype") eq('', funcs.luaeval "vim.bo.filetype")
eq(true, funcs.luaeval "vim.bo[BUF].modifiable") eq(true, funcs.luaeval "vim.bo[BUF].modifiable")
matches("^Error executing lua: .*: Invalid option name: 'nosuchopt'$", matches("^.../helpers.lua:0: Error executing lua: .*: Invalid option name: 'nosuchopt'$",
pcall_err(exec_lua, 'return vim.bo.nosuchopt')) pcall_err_withfile(exec_lua, 'return vim.bo.nosuchopt'))
matches("^Error executing lua: .*: Expected lua string$", matches("^.../helpers.lua:0: Error executing lua: .*: Expected lua string$",
pcall_err(exec_lua, 'return vim.bo[0][0].autoread')) pcall_err_withfile(exec_lua, 'return vim.bo[0][0].autoread'))
end) end)
it('vim.wo', function() it('vim.wo', function()
@@ -1004,10 +1076,10 @@ describe('lua stdlib', function()
eq(0, funcs.luaeval "vim.wo.cole") eq(0, funcs.luaeval "vim.wo.cole")
eq(0, funcs.luaeval "vim.wo[0].cole") eq(0, funcs.luaeval "vim.wo[0].cole")
eq(0, funcs.luaeval "vim.wo[1001].cole") eq(0, funcs.luaeval "vim.wo[1001].cole")
matches("^Error executing lua: .*: Invalid option name: 'notanopt'$", matches("^.../helpers.lua:0: Error executing lua: .*: Invalid option name: 'notanopt'$",
pcall_err(exec_lua, 'return vim.wo.notanopt')) pcall_err_withfile(exec_lua, 'return vim.wo.notanopt'))
matches("^Error executing lua: .*: Expected lua string$", matches("^.../helpers.lua:0: Error executing lua: .*: Expected lua string$",
pcall_err(exec_lua, 'return vim.wo[0][0].list')) pcall_err_withfile(exec_lua, 'return vim.wo[0][0].list'))
eq(2, funcs.luaeval "vim.wo[1000].cole") eq(2, funcs.luaeval "vim.wo[1000].cole")
exec_lua [[ exec_lua [[
vim.wo[1000].cole = 0 vim.wo[1000].cole = 0

View File

@@ -6,7 +6,6 @@ local buf_lines = helpers.buf_lines
local dedent = helpers.dedent local dedent = helpers.dedent
local exec_lua = helpers.exec_lua local exec_lua = helpers.exec_lua
local eq = helpers.eq local eq = helpers.eq
local contains = helpers.contains
local pcall_err = helpers.pcall_err local pcall_err = helpers.pcall_err
local pesc = helpers.pesc local pesc = helpers.pesc
local insert = helpers.insert local insert = helpers.insert
@@ -748,8 +747,16 @@ describe('LSP', function()
end) end)
it('should invalid cmd argument', function() it('should invalid cmd argument', function()
contains('cmd: expected list, got nvim', pcall_err(_cmd_parts, "nvim")) eq(dedent([[
contains('cmd argument: expected string, got number', pcall_err(_cmd_parts, {"nvim", 1})) Error executing lua: .../lsp.lua:0: cmd: expected list, got nvim
stack traceback:
.../lsp.lua:0: in function .../lsp.lua:0>]]),
pcall_err(_cmd_parts, 'nvim'))
eq(dedent([[
Error executing lua: .../lsp.lua:0: cmd argument: expected string, got number
stack traceback:
.../lsp.lua:0: in function .../lsp.lua:0>]]),
pcall_err(_cmd_parts, {'nvim', 1}))
end) end)
end) end)
end) end)

View File

@@ -59,7 +59,7 @@ describe('floatwin', function()
end) end)
it('closed immediately by autocmd #11383', function() it('closed immediately by autocmd #11383', function()
eq('Error executing lua: [string "<nvim>"]:4: Window was closed immediately', eq('Error executing lua: [string "<nvim>"]:0: Window was closed immediately',
pcall_err(exec_lua, [[ pcall_err(exec_lua, [[
local a = vim.api local a = vim.api
local function crashes(contents) local function crashes(contents)

View File

@@ -99,9 +99,6 @@ function module.matches(pat, actual)
end end
error(string.format('Pattern does not match.\nPattern:\n%s\nActual:\n%s', pat, actual)) error(string.format('Pattern does not match.\nPattern:\n%s\nActual:\n%s', pat, actual))
end end
function module.contains(pat, actual)
return module.matches(".*" .. pat .. ".*", actual)
end
--- Asserts that `pat` matches one or more lines in the tail of $NVIM_LOG_FILE. --- Asserts that `pat` matches one or more lines in the tail of $NVIM_LOG_FILE.
--- ---
@@ -119,8 +116,12 @@ function module.assert_log(pat, logfile)
pat, nrlines, logfile, logtail)) pat, nrlines, logfile, logtail))
end end
-- Invokes `fn` and returns the error string (may truncate full paths), or -- Invokes `fn` and returns the error string (with truncated paths), or raises
-- raises an error if `fn` succeeds. -- an error if `fn` succeeds.
--
-- Replaces line/column numbers with zero:
-- shared.lua:0: in function 'gsplit'
-- shared.lua:0: in function <shared.lua:0>'
-- --
-- Usage: -- Usage:
-- -- Match exact string. -- -- Match exact string.
@@ -128,29 +129,36 @@ end
-- -- Match Lua pattern. -- -- Match Lua pattern.
-- matches('e[or]+$', pcall_err(function(a, b) error('some error') end, 'arg1', 'arg2')) -- matches('e[or]+$', pcall_err(function(a, b) error('some error') end, 'arg1', 'arg2'))
-- --
function module.pcall_err(fn, ...) function module.pcall_err_withfile(fn, ...)
assert(type(fn) == 'function') assert(type(fn) == 'function')
local status, rv = pcall(fn, ...) local status, rv = pcall(fn, ...)
if status == true then if status == true then
error('expected failure, but got success') error('expected failure, but got success')
end end
-- From this: -- From:
-- /home/foo/neovim/runtime/lua/vim/shared.lua:186: Expected string, got number -- C:/long/path/foo.lua:186: Expected string, got number
-- to this: -- to:
-- Expected string, got number -- .../foo.lua:0: Expected string, got number
local errmsg = tostring(rv):gsub('^[^:]+:%d+: ', '') local errmsg = tostring(rv):gsub('[^%s]-[/\\]([^%s:/\\]+):%d+', '.../%1:0')
-- From this: -- Scrub numbers in paths/stacktraces:
-- Error executing lua: /very/long/foo.lua:186: Expected string, got number -- shared.lua:0: in function 'gsplit'
-- to this: -- shared.lua:0: in function <shared.lua:0>'
-- Error executing lua: .../foo.lua:186: Expected string, got number errmsg = errmsg:gsub('([^%s]):%d+', '%1:0')
errmsg = errmsg:gsub([[lua: [a-zA-Z]?:?[^:]-[/\]([^:/\]+):%d+: ]], 'lua: .../%1: ') -- Scrub tab chars:
-- Compiled modules will not have a path and will just be a name like errmsg = errmsg:gsub('\t', ' ')
-- shared.lua:186, so strip the number. -- In Lua 5.1, we sometimes get a "(tail call): ?" on the last line.
errmsg = errmsg:gsub([[lua: ([^:/\ ]+):%d+: ]], 'lua: .../%1: ') -- We remove this so that the tests are not lua dependent.
-- ^ Windows drive-letter (C:) errmsg = errmsg:gsub('%s*%(tail call%): %?', '')
return errmsg return errmsg
end end
function module.pcall_err(fn, ...)
local errmsg = module.pcall_err_withfile(fn, ...)
return errmsg:gsub('.../helpers.lua:0: ', '')
end
-- initial_path: directory to recurse into -- initial_path: directory to recurse into
-- re: include pattern (string) -- re: include pattern (string)
-- exc_re: exclude pattern(s) (string or table) -- exc_re: exclude pattern(s) (string or table)