aboutsummaryrefslogtreecommitdiff
path: root/test/functional/lua/vim_spec.lua
diff options
context:
space:
mode:
Diffstat (limited to 'test/functional/lua/vim_spec.lua')
-rw-r--r--test/functional/lua/vim_spec.lua306
1 files changed, 263 insertions, 43 deletions
diff --git a/test/functional/lua/vim_spec.lua b/test/functional/lua/vim_spec.lua
index 9b2697b3c2..e9e1f7ec12 100644
--- a/test/functional/lua/vim_spec.lua
+++ b/test/functional/lua/vim_spec.lua
@@ -4,6 +4,7 @@ local Screen = require('test.functional.ui.screen')
local funcs = helpers.funcs
local meths = helpers.meths
+local dedent = helpers.dedent
local command = helpers.command
local clear = helpers.clear
local eq = helpers.eq
@@ -118,6 +119,11 @@ describe('lua stdlib', function()
eq(1, funcs.luaeval('vim.stricmp("\\0C\\0", "\\0B\\0")'))
end)
+ -- for brevity, match only the error header (not the traceback)
+ local function pcall_header(...)
+ return string.gsub(string.gsub(pcall_err(exec_lua, ...), '[\r\n].*', ''), '^Error executing lua: ', '')
+ end
+
it('vim.startswith', function()
eq(true, funcs.luaeval('vim.startswith("123", "1")'))
eq(true, funcs.luaeval('vim.startswith("123", "")'))
@@ -128,8 +134,8 @@ describe('lua stdlib', function()
eq(false, funcs.luaeval('vim.startswith("123", "2")'))
eq(false, funcs.luaeval('vim.startswith("123", "1234")'))
- eq("string", type(pcall_err(funcs.luaeval, 'vim.startswith("123", nil)')))
- eq("string", type(pcall_err(funcs.luaeval, 'vim.startswith(nil, "123")')))
+ eq("vim/shared.lua:0: prefix: expected string, got nil", pcall_header 'return vim.startswith("123", nil)')
+ eq("vim/shared.lua:0: s: expected string, got nil", pcall_header 'return vim.startswith(nil, "123")')
end)
it('vim.endswith', function()
@@ -142,8 +148,8 @@ describe('lua stdlib', function()
eq(false, funcs.luaeval('vim.endswith("123", "2")'))
eq(false, funcs.luaeval('vim.endswith("123", "1234")'))
- eq("string", type(pcall_err(funcs.luaeval, 'vim.endswith("123", nil)')))
- eq("string", type(pcall_err(funcs.luaeval, 'vim.endswith(nil, "123")')))
+ eq("vim/shared.lua:0: suffix: expected string, got nil", pcall_header 'return vim.endswith("123", nil)')
+ eq("vim/shared.lua:0: s: expected string, got nil", pcall_header 'return vim.endswith(nil, "123")')
end)
it("vim.str_utfindex/str_byteindex", function()
@@ -257,16 +263,28 @@ describe('lua stdlib', function()
}
for _, t in ipairs(loops) do
- matches(".*Infinite loop detected", pcall_err(split, t[1], t[2]))
+ eq("Error executing lua: vim/shared.lua:0: Infinite loop detected", pcall_err(split, t[1], t[2]))
end
-- Validates args.
eq(true, pcall(split, 'string', 'string'))
- eq('Error executing lua: .../shared.lua: s: expected string, got number',
+ eq(dedent([[
+ Error executing lua: vim/shared.lua:0: s: expected string, got number
+ stack traceback:
+ vim/shared.lua:0: in function 'gsplit'
+ vim/shared.lua:0: in function <vim/shared.lua:0>]]),
pcall_err(split, 1, 'string'))
- eq('Error executing lua: .../shared.lua: sep: expected string, got number',
+ eq(dedent([[
+ Error executing lua: vim/shared.lua:0: sep: expected string, got number
+ stack traceback:
+ vim/shared.lua:0: in function 'gsplit'
+ vim/shared.lua:0: in function <vim/shared.lua:0>]]),
pcall_err(split, 'string', 1))
- eq('Error executing lua: .../shared.lua: plain: expected boolean, got number',
+ eq(dedent([[
+ Error executing lua: vim/shared.lua:0: plain: expected boolean, got number
+ stack traceback:
+ vim/shared.lua:0: in function 'gsplit'
+ vim/shared.lua:0: in function <vim/shared.lua:0>]]),
pcall_err(split, 'string', 'string', 1))
end)
@@ -287,7 +305,10 @@ describe('lua stdlib', function()
end
-- Validates args.
- eq('Error executing lua: .../shared.lua: s: expected string, got number',
+ eq(dedent([[
+ Error executing lua: vim/shared.lua:0: s: expected string, got number
+ stack traceback:
+ vim/shared.lua:0: in function <vim/shared.lua:0>]]),
pcall_err(trim, 2))
end)
@@ -353,7 +374,7 @@ describe('lua stdlib', function()
return t1.f() ~= t2.f()
]]))
- eq('Error executing lua: .../shared.lua: Cannot deepcopy object of type thread',
+ eq('Error executing lua: vim/shared.lua:0: Cannot deepcopy object of type thread',
pcall_err(exec_lua, [[
local thread = coroutine.create(function () return 0 end)
local t = {thr = thread}
@@ -366,7 +387,10 @@ describe('lua stdlib', function()
eq('foo%%%-bar', exec_lua([[return vim.pesc(vim.pesc('foo-bar'))]]))
-- Validates args.
- eq('Error executing lua: .../shared.lua: s: expected string, got number',
+ eq(dedent([[
+ Error executing lua: vim/shared.lua:0: s: expected string, got number
+ stack traceback:
+ vim/shared.lua:0: in function <vim/shared.lua:0>]]),
pcall_err(exec_lua, [[return vim.pesc(2)]]))
end)
@@ -491,19 +515,19 @@ describe('lua stdlib', function()
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('Error executing lua: vim/shared.lua:0: invalid "behavior": nil',
pcall_err(exec_lua, [[
return vim.tbl_extend()
]])
)
- eq('Error executing lua: .../shared.lua: wrong number of arguments (given 1, expected at least 3)',
+ eq('Error executing lua: vim/shared.lua:0: wrong number of arguments (given 1, expected at least 3)',
pcall_err(exec_lua, [[
return vim.tbl_extend("keep")
]])
)
- eq('Error executing lua: .../shared.lua: wrong number of arguments (given 2, expected at least 3)',
+ eq('Error executing lua: vim/shared.lua:0: wrong number of arguments (given 2, expected at least 3)',
pcall_err(exec_lua, [[
return vim.tbl_extend("keep", {})
]])
@@ -579,19 +603,19 @@ describe('lua stdlib', function()
return vim.tbl_islist(c) and count == 0
]]))
- eq('Error executing lua: .../shared.lua: invalid "behavior": nil',
+ eq('Error executing lua: vim/shared.lua:0: invalid "behavior": nil',
pcall_err(exec_lua, [[
return vim.tbl_deep_extend()
]])
)
- eq('Error executing lua: .../shared.lua: wrong number of arguments (given 1, expected at least 3)',
+ eq('Error executing lua: vim/shared.lua:0: wrong number of arguments (given 1, expected at least 3)',
pcall_err(exec_lua, [[
return vim.tbl_deep_extend("keep")
]])
)
- eq('Error executing lua: .../shared.lua: wrong number of arguments (given 2, expected at least 3)',
+ eq('Error executing lua: vim/shared.lua:0: wrong number of arguments (given 2, expected at least 3)',
pcall_err(exec_lua, [[
return vim.tbl_deep_extend("keep", {})
]])
@@ -624,7 +648,10 @@ describe('lua stdlib', function()
it('vim.list_extend', function()
eq({1,2,3}, exec_lua [[ return vim.list_extend({1}, {2,3}) ]])
- eq('Error executing lua: .../shared.lua: src: expected table, got nil',
+ eq(dedent([[
+ Error executing lua: vim/shared.lua:0: src: expected table, got nil
+ stack traceback:
+ vim/shared.lua:0: in function <vim/shared.lua:0>]]),
pcall_err(exec_lua, [[ return vim.list_extend({1}, nil) ]]))
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 ]])
@@ -648,7 +675,7 @@ describe('lua stdlib', function()
assert(vim.deep_equal(a, { A = 1; [1] = '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('^Error executing lua: vim/shared%.lua:0: The reverse lookup found an existing value for "[1A]" while processing key "[1A]"$',
pcall_err(exec_lua, code))
end)
@@ -820,34 +847,77 @@ describe('lua stdlib', function()
exec_lua("vim.validate{arg1={{}, 't' }, arg2={ 'foo', 's' }}")
exec_lua("vim.validate{arg1={2, function(a) return (a % 2) == 0 end, 'even number' }}")
- eq("Error executing lua: .../shared.lua: 1: expected table, got number",
+ eq(dedent([[
+ Error executing lua: [string "<nvim>"]:0: opt[1]: expected table, got number
+ stack traceback:
+ [string "<nvim>"]:0: in main chunk]]),
pcall_err(exec_lua, "vim.validate{ 1, 'x' }"))
- eq("Error executing lua: .../shared.lua: invalid type name: x",
+ eq(dedent([[
+ Error executing lua: [string "<nvim>"]:0: invalid type name: x
+ stack traceback:
+ [string "<nvim>"]:0: in main chunk]]),
pcall_err(exec_lua, "vim.validate{ arg1={ 1, 'x' }}"))
- eq("Error executing lua: .../shared.lua: invalid type name: 1",
+ eq(dedent([[
+ Error executing lua: [string "<nvim>"]:0: invalid type name: 1
+ stack traceback:
+ [string "<nvim>"]:0: in main chunk]]),
pcall_err(exec_lua, "vim.validate{ arg1={ 1, 1 }}"))
- eq("Error executing lua: .../shared.lua: invalid type name: nil",
+ eq(dedent([[
+ Error executing lua: [string "<nvim>"]:0: invalid type name: nil
+ stack traceback:
+ [string "<nvim>"]:0: in main chunk]]),
pcall_err(exec_lua, "vim.validate{ arg1={ 1 }}"))
-- Validated parameters are required by default.
- eq("Error executing lua: .../shared.lua: arg1: expected string, got nil",
+ eq(dedent([[
+ Error executing lua: [string "<nvim>"]:0: arg1: expected string, got nil
+ stack traceback:
+ [string "<nvim>"]:0: in main chunk]]),
pcall_err(exec_lua, "vim.validate{ arg1={ nil, 's' }}"))
-- Explicitly required.
- eq("Error executing lua: .../shared.lua: arg1: expected string, got nil",
+ eq(dedent([[
+ Error executing lua: [string "<nvim>"]:0: arg1: expected string, got nil
+ stack traceback:
+ [string "<nvim>"]:0: in main chunk]]),
pcall_err(exec_lua, "vim.validate{ arg1={ nil, 's', false }}"))
- eq("Error executing lua: .../shared.lua: arg1: expected table, got number",
+ eq(dedent([[
+ Error executing lua: [string "<nvim>"]:0: arg1: expected table, got number
+ stack traceback:
+ [string "<nvim>"]:0: in main chunk]]),
pcall_err(exec_lua, "vim.validate{arg1={1, 't'}}"))
- eq("Error executing lua: .../shared.lua: arg2: expected string, got number",
+ eq(dedent([[
+ Error executing lua: [string "<nvim>"]:0: arg2: expected string, got number
+ stack traceback:
+ [string "<nvim>"]:0: in main chunk]]),
pcall_err(exec_lua, "vim.validate{arg1={{}, 't'}, arg2={1, 's'}}"))
- eq("Error executing lua: .../shared.lua: arg2: expected string, got nil",
+ eq(dedent([[
+ Error executing lua: [string "<nvim>"]:0: arg2: expected string, got nil
+ stack traceback:
+ [string "<nvim>"]:0: in main chunk]]),
pcall_err(exec_lua, "vim.validate{arg1={{}, 't'}, arg2={nil, 's'}}"))
- eq("Error executing lua: .../shared.lua: arg2: expected string, got nil",
+ eq(dedent([[
+ Error executing lua: [string "<nvim>"]:0: arg2: expected string, got nil
+ stack traceback:
+ [string "<nvim>"]:0: in main chunk]]),
pcall_err(exec_lua, "vim.validate{arg1={{}, 't'}, arg2={nil, 's'}}"))
- eq("Error executing lua: .../shared.lua: arg1: expected even number, got 3",
+ eq(dedent([[
+ Error executing lua: [string "<nvim>"]:0: arg1: expected even number, got 3
+ stack traceback:
+ [string "<nvim>"]:0: in main chunk]]),
pcall_err(exec_lua, "vim.validate{arg1={3, function(a) return a == 1 end, 'even number'}}"))
- eq("Error executing lua: .../shared.lua: arg1: expected ?, got 3",
+ eq(dedent([[
+ Error executing lua: [string "<nvim>"]:0: arg1: expected ?, got 3
+ stack traceback:
+ [string "<nvim>"]:0: in main chunk]]),
pcall_err(exec_lua, "vim.validate{arg1={3, function(a) return a == 1 end}}"))
+
+ -- Pass an additional message back.
+ eq(dedent([[
+ Error executing lua: [string "<nvim>"]:0: arg1: expected ?, got 3. Info: TEST_MSG
+ stack traceback:
+ [string "<nvim>"]:0: in main chunk]]),
+ pcall_err(exec_lua, "vim.validate{arg1={3, function(a) return a == 1, 'TEST_MSG' end}}"))
end)
it('vim.is_callable', function()
@@ -1068,6 +1138,104 @@ describe('lua stdlib', function()
eq({5,15}, exec_lua[[ return vim.region(0,{1,5},{1,14},'v',true)[1] ]])
end)
+ describe('vim.execute_on_keystroke', function()
+ it('should keep track of keystrokes', function()
+ helpers.insert([[hello world ]])
+
+ exec_lua [[
+ KeysPressed = {}
+
+ vim.register_keystroke_callback(function(buf)
+ if buf:byte() == 27 then
+ buf = "<ESC>"
+ end
+
+ table.insert(KeysPressed, buf)
+ end)
+ ]]
+
+ helpers.insert([[next 🤦 lines å ]])
+
+ -- It has escape in the keys pressed
+ eq('inext 🤦 lines å <ESC>', exec_lua [[return table.concat(KeysPressed, '')]])
+ end)
+
+ it('should allow removing trackers.', function()
+ helpers.insert([[hello world]])
+
+ exec_lua [[
+ KeysPressed = {}
+
+ return vim.register_keystroke_callback(function(buf)
+ if buf:byte() == 27 then
+ buf = "<ESC>"
+ end
+
+ table.insert(KeysPressed, buf)
+ end, vim.api.nvim_create_namespace("logger"))
+ ]]
+
+ helpers.insert([[next lines]])
+
+ exec_lua("vim.register_keystroke_callback(nil, vim.api.nvim_create_namespace('logger'))")
+
+ helpers.insert([[more lines]])
+
+ -- It has escape in the keys pressed
+ eq('inext lines<ESC>', exec_lua [[return table.concat(KeysPressed, '')]])
+ end)
+
+ it('should not call functions that error again.', function()
+ helpers.insert([[hello world]])
+
+ exec_lua [[
+ KeysPressed = {}
+
+ return vim.register_keystroke_callback(function(buf)
+ if buf:byte() == 27 then
+ buf = "<ESC>"
+ end
+
+ table.insert(KeysPressed, buf)
+
+ if buf == 'l' then
+ error("Dumb Error")
+ end
+ end)
+ ]]
+
+ helpers.insert([[next lines]])
+ helpers.insert([[more lines]])
+
+ -- Only the first letter gets added. After that we remove the callback
+ eq('inext l', exec_lua [[ return table.concat(KeysPressed, '') ]])
+ end)
+
+ it('should process mapped keys, not unmapped keys', function()
+ exec_lua [[
+ KeysPressed = {}
+
+ vim.cmd("inoremap hello world")
+
+ vim.register_keystroke_callback(function(buf)
+ if buf:byte() == 27 then
+ buf = "<ESC>"
+ end
+
+ table.insert(KeysPressed, buf)
+ end)
+ ]]
+
+ helpers.insert("hello")
+
+ local next_status = exec_lua [[
+ return table.concat(KeysPressed, '')
+ ]]
+
+ eq("iworld<ESC>", next_status)
+ end)
+ end)
+
describe('vim.wait', function()
before_each(function()
exec_lua[[
@@ -1116,6 +1284,23 @@ describe('lua stdlib', function()
]])
end)
+ it('should not process non-fast events when commanded', function()
+ eq({wait_result = false}, exec_lua[[
+ start_time = get_time()
+
+ vim.g.timer_result = false
+ timer = vim.loop.new_timer()
+ timer:start(100, 0, vim.schedule_wrap(function()
+ vim.g.timer_result = true
+ end))
+
+ wait_result = vim.wait(300, function() return vim.g.timer_result end, nil, true)
+
+ return {
+ wait_result = wait_result,
+ }
+ ]])
+ end)
it('should work with vim.defer_fn', function()
eq({time = true, wait_result = true}, exec_lua[[
start_time = get_time()
@@ -1130,22 +1315,32 @@ describe('lua stdlib', function()
]])
end)
- it('should require functions to be passed', function()
- local pcall_result = exec_lua [[
- return {pcall(function() vim.wait(1000, 13) end)}
- ]]
+ it('should not crash when callback errors', function()
+ eq({false, '[string "<nvim>"]:1: As Expected'}, exec_lua [[
+ return {pcall(function() vim.wait(1000, function() error("As Expected") end) end)}
+ ]])
+ end)
- eq(pcall_result[1], false)
- matches('condition must be a function', pcall_result[2])
+ it('if callback is passed, it must be a function', function()
+ eq({false, 'vim.wait: if passed, condition must be a function'}, exec_lua [[
+ return {pcall(function() vim.wait(1000, 13) end)}
+ ]])
end)
- it('should not crash when callback errors', function()
- local pcall_result = exec_lua [[
- return {pcall(function() vim.wait(1000, function() error("As Expected") end) end)}
- ]]
+ it('should allow waiting with no callback, explicit', function()
+ eq(true, exec_lua [[
+ local start_time = vim.loop.hrtime()
+ vim.wait(50, nil)
+ return vim.loop.hrtime() - start_time > 25000
+ ]])
+ end)
- eq(pcall_result[1], false)
- matches('As Expected', pcall_result[2])
+ it('should allow waiting with no callback, implicit', function()
+ eq(true, exec_lua [[
+ local start_time = vim.loop.hrtime()
+ vim.wait(50)
+ return vim.loop.hrtime() - start_time > 25000
+ ]])
end)
it('should call callbacks exactly once if they return true immediately', function()
@@ -1232,4 +1427,29 @@ describe('lua stdlib', function()
eq(false, pcall_result)
end)
end)
+
+ describe('vim.api.nvim_buf_call', function()
+ it('can access buf options', function()
+ local buf1 = meths.get_current_buf()
+ local buf2 = exec_lua [[
+ buf2 = vim.api.nvim_create_buf(false, true)
+ return buf2
+ ]]
+
+ eq(false, meths.buf_get_option(buf1, 'autoindent'))
+ eq(false, meths.buf_get_option(buf2, 'autoindent'))
+
+ local val = exec_lua [[
+ return vim.api.nvim_buf_call(buf2, function()
+ vim.cmd "set autoindent"
+ return vim.api.nvim_get_current_buf()
+ end)
+ ]]
+
+ eq(false, meths.buf_get_option(buf1, 'autoindent'))
+ eq(true, meths.buf_get_option(buf2, 'autoindent'))
+ eq(buf1, meths.get_current_buf())
+ eq(buf2, val)
+ end)
+ end)
end)