uv_spec.lua (7578B)
1 -- Test suite for testing interactions with API bindings 2 local t = require('test.testutil') 3 local n = require('test.functional.testnvim')() 4 local Screen = require('test.functional.ui.screen') 5 6 local fn = n.fn 7 local api = n.api 8 local clear = n.clear 9 local sleep = vim.uv.sleep 10 local feed = n.feed 11 local eq = t.eq 12 local eval = n.eval 13 local matches = t.matches 14 local exec_lua = n.exec_lua 15 local retry = t.retry 16 17 before_each(clear) 18 19 describe('vim.uv', function() 20 it('version', function() 21 assert(fn.luaeval('vim.uv.version()') >= 72961, 'libuv version too old') 22 matches('(%d+)%.(%d+)%.(%d+)', fn.luaeval('vim.uv.version_string()')) 23 end) 24 25 it('timer', function() 26 exec_lua('vim.api.nvim_set_var("coroutine_cnt", 0)', {}) 27 28 local code = function() 29 local touch = 0 30 local function wait(ms) 31 local this = coroutine.running() 32 assert(this) 33 local timer = assert(vim.uv.new_timer()) 34 timer:start( 35 ms, 36 0, 37 vim.schedule_wrap(function() 38 timer:close() 39 touch = touch + 1 40 coroutine.resume(this) 41 touch = touch + 1 42 assert(touch == 3) 43 vim.api.nvim_set_var('coroutine_cnt_1', touch) 44 end) 45 ) 46 coroutine.yield() 47 touch = touch + 1 48 return touch 49 end 50 coroutine.wrap(function() 51 local touched = wait(10) 52 assert(touched == touch) 53 vim.api.nvim_set_var('coroutine_cnt', touched) 54 end)() 55 end 56 57 eq(0, api.nvim_get_var('coroutine_cnt')) 58 exec_lua(code) 59 retry(2, nil, function() 60 sleep(50) 61 eq(2, api.nvim_get_var('coroutine_cnt')) 62 end) 63 eq(3, api.nvim_get_var('coroutine_cnt_1')) 64 end) 65 66 it('is API safe', function() 67 local screen = Screen.new(50, 10) 68 screen:set_default_attr_ids({ 69 [1] = { bold = true, foreground = Screen.colors.Blue1 }, 70 [2] = { bold = true, reverse = true }, 71 [3] = { foreground = Screen.colors.Grey100, background = Screen.colors.Red }, 72 [4] = { bold = true, foreground = Screen.colors.SeaGreen4 }, 73 [5] = { bold = true }, 74 }) 75 76 -- deferred API functions are disabled, as their safety can't be guaranteed 77 exec_lua([[ 78 local timer = vim.uv.new_timer() 79 timer:start(20, 0, function () 80 _G.is_fast = vim.in_fast_event() 81 timer:close() 82 vim.api.nvim_set_var("valid", true) 83 vim.api.nvim_command("echomsg 'howdy'") 84 end) 85 ]]) 86 87 screen:expect([[ 88 | 89 {2: }| 90 {3:Lua callback:} | 91 {3:[string "<nvim>"]:5: E5560: nvim_set_var must not }| 92 {3:be called in a fast event context} | 93 {3:stack traceback:} | 94 {3: [C]: in function 'nvim_set_var'} | 95 {3: [string "<nvim>"]:5: in function <[string }| 96 {3:"<nvim>"]:2>} | 97 {4:Press ENTER or type command to continue}^ | 98 ]]) 99 feed('<cr>') 100 eq(false, eval("get(g:, 'valid', v:false)")) 101 eq(true, exec_lua('return _G.is_fast')) 102 103 -- callbacks can be scheduled to be executed in the main event loop 104 -- where the entire API is available 105 exec_lua(function() 106 local timer = assert(vim.uv.new_timer()) 107 timer:start( 108 20, 109 0, 110 vim.schedule_wrap(function() 111 _G.is_fast = vim.in_fast_event() 112 timer:close() 113 vim.api.nvim_set_var('valid', true) 114 vim.api.nvim_command("echomsg 'howdy'") 115 end) 116 ) 117 end) 118 119 screen:expect([[ 120 ^ | 121 {1:~ }|*8 122 howdy | 123 ]]) 124 eq(true, eval("get(g:, 'valid', v:false)")) 125 eq(false, exec_lua('return _G.is_fast')) 126 127 -- fast (not deferred) API functions are allowed to be called directly 128 exec_lua(function() 129 local timer = assert(vim.uv.new_timer()) 130 timer:start(20, 0, function() 131 timer:close() 132 -- input is queued for processing after the callback returns 133 vim.api.nvim_input('isneaky') 134 _G.mode = vim.api.nvim_get_mode() 135 end) 136 end) 137 screen:expect([[ 138 sneaky^ | 139 {1:~ }|*8 140 {5:-- INSERT --} | 141 ]]) 142 eq({ blocking = false, mode = 'n' }, exec_lua('return _G.mode')) 143 144 exec_lua(function() 145 local timer = assert(vim.uv.new_timer()) 146 timer:start(20, 0, function() 147 _G.is_fast = vim.in_fast_event() 148 timer:close() 149 _G.value = vim.fn.has('nvim-0.5') 150 _G.unvalue = vim.fn.has('python3') 151 end) 152 end) 153 154 screen:expect({ any = [[{3:Vim:E5560: Vimscript function must not be called i}]] }) 155 feed('<cr>') 156 eq({ 1, nil }, exec_lua('return {_G.value, _G.unvalue}')) 157 end) 158 159 it("is equal to require('luv')", function() 160 eq(true, exec_lua("return vim.uv == require('luv')")) 161 end) 162 163 it('non-string error() #32595', function() 164 local screen = Screen.new(50, 10) 165 exec_lua(function() 166 local timer = assert(vim.uv.new_timer()) 167 timer:start(0, 0, function() 168 timer:close() 169 error(nil) 170 end) 171 end) 172 local s = [[ 173 | 174 {1:~ }|*5 175 {3: }| 176 {9:Lua callback:} | 177 {9:[NULL]} | 178 {6:Press ENTER or type command to continue}^ | 179 ]] 180 screen:expect(s) 181 feed('<cr>') 182 n.assert_alive() 183 screen:expect([[ 184 ^ | 185 {1:~ }|*8 186 | 187 ]]) 188 exec_lua(function() 189 vim.uv.fs_stat('non-existent-file', function() 190 error(nil) 191 end) 192 end) 193 screen:expect(s) 194 feed('<cr>') 195 n.assert_alive() 196 end) 197 198 it("doesn't crash on async callbacks throwing nil error", function() 199 local screen = Screen.new(50, 4) 200 201 exec_lua(function() 202 _G.idle = vim.uv.new_idle() 203 _G.idle:start(function() 204 _G.idle:stop() 205 error() 206 end) 207 end) 208 209 screen:expect([[ 210 {3: }| 211 {9:Lua callback:} | 212 {9:[NULL]} | 213 {6:Press ENTER or type command to continue}^ | 214 ]]) 215 feed('<cr>') 216 217 exec_lua(function() 218 _G.idle:close() 219 end) 220 end) 221 222 it("doesn't crash on async callbacks throwing object as an error", function() 223 local screen = Screen.new(50, 4) 224 225 exec_lua(function() 226 _G.idle = vim.uv.new_idle() 227 _G.idle:start(function() 228 _G.idle:stop() 229 error(_G.idle) -- userdata with __tostring method 230 end) 231 end) 232 233 screen:expect([[ 234 {3: }| 235 {9:Lua callback:} | 236 {9:uv_idle_t: 0x{MATCH:%w+}}{MATCH: +}| 237 {6:Press ENTER or type command to continue}^ | 238 ]]) 239 feed('<cr>') 240 241 exec_lua(function() 242 _G.idle:close() 243 end) 244 end) 245 end)