aboutsummaryrefslogtreecommitdiff
path: root/test/functional/lua/loop_spec.lua
diff options
context:
space:
mode:
authorBjörn Linse <bjorn.linse@gmail.com>2019-06-23 20:10:28 +0200
committerBjörn Linse <bjorn.linse@gmail.com>2019-06-30 13:13:08 +0200
commitd33aaa0f5f96afb1608a4a3eb2057da956a24b2b (patch)
tree914d11e9d5d4d769069a11841371d1cc8cd1a802 /test/functional/lua/loop_spec.lua
parent7030d7daf1f40e5a3963340d1107d7b7a713df5f (diff)
downloadrneovim-d33aaa0f5f96afb1608a4a3eb2057da956a24b2b.tar.gz
rneovim-d33aaa0f5f96afb1608a4a3eb2057da956a24b2b.tar.bz2
rneovim-d33aaa0f5f96afb1608a4a3eb2057da956a24b2b.zip
libluv: use luv_set_callback to control callback execution
Disable the use of deferred API functions in a fast lua callback Correctly display error messages from a fast lua callback
Diffstat (limited to 'test/functional/lua/loop_spec.lua')
-rw-r--r--test/functional/lua/loop_spec.lua100
1 files changed, 95 insertions, 5 deletions
diff --git a/test/functional/lua/loop_spec.lua b/test/functional/lua/loop_spec.lua
index 8cc54e8c13..3b3b81f886 100644
--- a/test/functional/lua/loop_spec.lua
+++ b/test/functional/lua/loop_spec.lua
@@ -1,11 +1,15 @@
-- Test suite for testing interactions with API bindings
local helpers = require('test.functional.helpers')(after_each)
+local Screen = require('test.functional.ui.screen')
local funcs = helpers.funcs
local meths = helpers.meths
local clear = helpers.clear
local sleep = helpers.sleep
+local feed = helpers.feed
local eq = helpers.eq
+local eval = helpers.eval
local matches = helpers.matches
+local exec_lua = helpers.exec_lua
before_each(clear)
@@ -17,7 +21,7 @@ describe('vim.loop', function()
end)
it('timer', function()
- meths.execute_lua('vim.api.nvim_set_var("coroutine_cnt", 0)', {})
+ exec_lua('vim.api.nvim_set_var("coroutine_cnt", 0)', {})
local code=[[
local loop = vim.loop
@@ -27,14 +31,14 @@ describe('vim.loop', function()
local this = coroutine.running()
assert(this)
local timer = loop.new_timer()
- timer:start(ms, 0, function ()
+ timer:start(ms, 0, vim.schedule_wrap(function ()
timer:close()
touch = touch + 1
coroutine.resume(this)
touch = touch + 1
assert(touch==3)
vim.api.nvim_set_var("coroutine_cnt_1", touch)
- end)
+ end))
coroutine.yield()
touch = touch + 1
return touch
@@ -47,9 +51,95 @@ describe('vim.loop', function()
]]
eq(0, meths.get_var('coroutine_cnt'))
- meths.execute_lua(code, {})
- sleep(20)
+ exec_lua(code)
+ sleep(50)
eq(2, meths.get_var('coroutine_cnt'))
eq(3, meths.get_var('coroutine_cnt_1'))
end)
+
+ it('is API safe', function()
+ local screen = Screen.new(50,10)
+ screen:attach()
+ screen:set_default_attr_ids({
+ [1] = {bold = true, foreground = Screen.colors.Blue1},
+ [2] = {bold = true, reverse = true},
+ [3] = {foreground = Screen.colors.Grey100, background = Screen.colors.Red},
+ [4] = {bold = true, foreground = Screen.colors.SeaGreen4},
+ [5] = {bold = true},
+ })
+
+ -- deferred API functions are disabled, as their safety can't be guaranteed
+ exec_lua([[
+ local timer = vim.loop.new_timer()
+ timer:start(20, 0, function ()
+ timer:close()
+ vim.api.nvim_set_var("valid", true)
+ vim.api.nvim_command("echomsg 'howdy'")
+ end)
+ ]])
+
+ screen:expect([[
+ |
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {2: }|
+ {3:Error executing luv callback:} |
+ {3:[string "<nvim>"]:4: E5560: nvim_set_var must not }|
+ {3:be called in a lua loop callback} |
+ {4:Press ENTER or type command to continue}^ |
+ ]])
+ feed('<cr>')
+ eq(false, eval("get(g:, 'valid', v:false)"))
+
+ -- callbacks can be scheduled to be executed in the main event loop
+ -- where the entire API is available
+ exec_lua([[
+ local timer = vim.loop.new_timer()
+ timer:start(20, 0, vim.schedule_wrap(function ()
+ timer:close()
+ vim.api.nvim_set_var("valid", true)
+ vim.api.nvim_command("echomsg 'howdy'")
+ end))
+ ]])
+
+ screen:expect([[
+ ^ |
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ howdy |
+ ]])
+ eq(true, eval("get(g:, 'valid', v:false)"))
+
+ -- fast (not deferred) API functions are allowed to be called directly
+ exec_lua([[
+ local timer = vim.loop.new_timer()
+ timer:start(20, 0, function ()
+ timer:close()
+ -- input is queued for processing after the callback returns
+ vim.api.nvim_input("isneaky")
+ _G.mode = vim.api.nvim_get_mode()
+ end)
+ ]])
+ screen:expect([[
+ sneaky^ |
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {5:-- INSERT --} |
+ ]])
+ eq({blocking=false, mode='n'}, exec_lua("return _G.mode"))
+ end)
end)