blob: 9ba5d0f84d19168d7c6f29304443b32925a11872 [file] [log] [blame]
Bram Moolenaar975b5272016-03-15 23:10:59 +01001" Test for timers
2
Bram Moolenaarb46fecd2019-06-15 17:58:09 +02003CheckFeature timers
Bram Moolenaar975b5272016-03-15 23:10:59 +01004
Christian Brabandteb380b92025-07-07 20:53:55 +02005source util/screendump.vim
Bram Moolenaar11aa62f2017-09-04 22:56:01 +02006
Bram Moolenaar29b4c512023-05-30 15:34:50 +01007func SetUp()
8 " The tests here use timers, thus are sensitive to timing.
9 let g:test_is_flaky = 1
10endfunc
11
Bram Moolenaar975b5272016-03-15 23:10:59 +010012func MyHandler(timer)
Bram Moolenaarb73598e2016-08-07 18:22:53 +020013 let g:val += 1
Bram Moolenaar975b5272016-03-15 23:10:59 +010014endfunc
15
Bram Moolenaare3188e22016-05-31 21:13:04 +020016func MyHandlerWithLists(lists, timer)
17 let x = string(a:lists)
18endfunc
19
Bram Moolenaar9a2fddc2019-08-16 11:26:06 +020020func Test_timer_oneshot()
Bram Moolenaarb73598e2016-08-07 18:22:53 +020021 let g:val = 0
Bram Moolenaar975b5272016-03-15 23:10:59 +010022 let timer = timer_start(50, 'MyHandler')
Bram Moolenaarb73598e2016-08-07 18:22:53 +020023 let slept = WaitFor('g:val == 1')
24 call assert_equal(1, g:val)
Bram Moolenaarbc28e9f2019-12-18 20:10:23 +010025 if has('mac')
Bram Moolenaar818fed72019-12-25 15:47:14 +010026 " Mac on Travis can be very slow.
27 let limit = 180
Bram Moolenaarf267f8b2016-08-22 21:40:29 +020028 else
Bram Moolenaarbc28e9f2019-12-18 20:10:23 +010029 let limit = 100
30 endif
31 if has('reltime')
32 call assert_inrange(49, limit, slept)
33 else
34 call assert_inrange(20, limit, slept)
Bram Moolenaarf267f8b2016-08-22 21:40:29 +020035 endif
Bram Moolenaar975b5272016-03-15 23:10:59 +010036endfunc
37
Bram Moolenaar9a2fddc2019-08-16 11:26:06 +020038func Test_timer_repeat_three()
Bram Moolenaarb73598e2016-08-07 18:22:53 +020039 let g:val = 0
Bram Moolenaar975b5272016-03-15 23:10:59 +010040 let timer = timer_start(50, 'MyHandler', {'repeat': 3})
Bram Moolenaarb73598e2016-08-07 18:22:53 +020041 let slept = WaitFor('g:val == 3')
42 call assert_equal(3, g:val)
Bram Moolenaarf267f8b2016-08-22 21:40:29 +020043 if has('reltime')
Yee Cheng Chine70587d2025-02-13 20:55:45 +010044 " Timer has an internal 1ms allowance in calculating due time, so it's
45 " possible for each timer to undershoot by 1ms resulting in only 49*3=147
46 " ms elapsed. Additionally we started the timer before we called
47 " WaitFor(), so the reported time could be a couple more ms below 147.
Bram Moolenaarbc28e9f2019-12-18 20:10:23 +010048 if has('mac')
Yee Cheng Chine70587d2025-02-13 20:55:45 +010049 " Mac in CI can be slow.
50 call assert_inrange(145, 400, slept)
Bram Moolenaarbc28e9f2019-12-18 20:10:23 +010051 else
Yee Cheng Chine70587d2025-02-13 20:55:45 +010052 call assert_inrange(145, 250, slept)
Bram Moolenaarbc28e9f2019-12-18 20:10:23 +010053 endif
Bram Moolenaarf267f8b2016-08-22 21:40:29 +020054 else
55 call assert_inrange(80, 200, slept)
56 endif
Bram Moolenaar975b5272016-03-15 23:10:59 +010057endfunc
58
Bram Moolenaar9a2fddc2019-08-16 11:26:06 +020059func Test_timer_repeat_many()
Bram Moolenaarb73598e2016-08-07 18:22:53 +020060 let g:val = 0
Bram Moolenaar975b5272016-03-15 23:10:59 +010061 let timer = timer_start(50, 'MyHandler', {'repeat': -1})
62 sleep 200m
63 call timer_stop(timer)
Bram Moolenaarbc28e9f2019-12-18 20:10:23 +010064 " Mac on Travis can be slow.
65 if has('mac')
66 call assert_inrange(1, 5, g:val)
67 else
68 call assert_inrange(2, 5, g:val)
69 endif
Bram Moolenaar975b5272016-03-15 23:10:59 +010070endfunc
Bram Moolenaar92e35ef2016-03-26 18:20:41 +010071
Bram Moolenaar9a2fddc2019-08-16 11:26:06 +020072func Test_timer_with_partial_callback()
Bram Moolenaarb73598e2016-08-07 18:22:53 +020073 let g:val = 0
Bram Moolenaar26fe0d52016-09-10 14:27:30 +020074 let meow = {'one': 1}
75 function meow.bite(...)
76 let g:val += self.one
Bram Moolenaar92e35ef2016-03-26 18:20:41 +010077 endfunction
78
Bram Moolenaar26fe0d52016-09-10 14:27:30 +020079 call timer_start(50, meow.bite)
Bram Moolenaarb73598e2016-08-07 18:22:53 +020080 let slept = WaitFor('g:val == 1')
81 call assert_equal(1, g:val)
Bram Moolenaarf267f8b2016-08-22 21:40:29 +020082 if has('reltime')
Bram Moolenaar5c463a22019-12-27 17:14:33 +010083 " Mac on Travis can be slow.
84 if has('mac')
85 call assert_inrange(49, 180, slept)
86 else
87 call assert_inrange(49, 130, slept)
88 endif
Bram Moolenaarf267f8b2016-08-22 21:40:29 +020089 else
90 call assert_inrange(20, 100, slept)
91 endif
Bram Moolenaar92e35ef2016-03-26 18:20:41 +010092endfunc
Bram Moolenaare3188e22016-05-31 21:13:04 +020093
Bram Moolenaar9a2fddc2019-08-16 11:26:06 +020094func Test_timer_retain_partial()
Bram Moolenaarb73598e2016-08-07 18:22:53 +020095 call timer_start(50, function('MyHandlerWithLists', [['a']]))
Bram Moolenaare3188e22016-05-31 21:13:04 +020096 call test_garbagecollect_now()
Bram Moolenaarb73598e2016-08-07 18:22:53 +020097 sleep 100m
Bram Moolenaare3188e22016-05-31 21:13:04 +020098endfunc
Bram Moolenaarb73598e2016-08-07 18:22:53 +020099
Bram Moolenaar9a2fddc2019-08-16 11:26:06 +0200100func Test_timer_info()
Bram Moolenaarb73598e2016-08-07 18:22:53 +0200101 let id = timer_start(1000, 'MyHandler')
Bram Moolenaarf92e58c2019-09-08 21:51:41 +0200102 let info = id->timer_info()
Bram Moolenaarb73598e2016-08-07 18:22:53 +0200103 call assert_equal(id, info[0]['id'])
104 call assert_equal(1000, info[0]['time'])
105 call assert_true(info[0]['remaining'] > 500)
106 call assert_true(info[0]['remaining'] <= 1000)
107 call assert_equal(1, info[0]['repeat'])
108 call assert_equal("function('MyHandler')", string(info[0]['callback']))
109
110 let found = 0
111 for info in timer_info()
112 if info['id'] == id
113 let found += 1
114 endif
115 endfor
116 call assert_equal(1, found)
117
118 call timer_stop(id)
119 call assert_equal([], timer_info(id))
Bram Moolenaare20b9ec2020-02-03 21:40:04 +0100120
Yegappan Lakshmanan8deb2b32022-09-02 15:15:27 +0100121 call assert_fails('call timer_info("abc")', 'E1210:')
Bram Moolenaar95b2dd02021-12-09 18:42:57 +0000122
123 " check repeat count inside the callback
124 let g:timer_repeat = []
125 let tid = timer_start(10, {tid -> execute("call add(g:timer_repeat, timer_info(tid)[0].repeat)")}, #{repeat: 3})
Bram Moolenaarff39a652021-12-10 10:57:08 +0000126 call WaitForAssert({-> assert_equal([2, 1, 0], g:timer_repeat)})
Bram Moolenaar95b2dd02021-12-09 18:42:57 +0000127 unlet g:timer_repeat
Bram Moolenaarb73598e2016-08-07 18:22:53 +0200128endfunc
129
Bram Moolenaar9a2fddc2019-08-16 11:26:06 +0200130func Test_timer_stopall()
Bram Moolenaarb73598e2016-08-07 18:22:53 +0200131 let id1 = timer_start(1000, 'MyHandler')
132 let id2 = timer_start(2000, 'MyHandler')
133 let info = timer_info()
Bram Moolenaar0056ca72022-09-23 21:26:39 +0100134 " count one for the TestTimeout() timer
135 call assert_equal(3, len(info))
Bram Moolenaarb73598e2016-08-07 18:22:53 +0200136
137 call timer_stopall()
138 let info = timer_info()
139 call assert_equal(0, len(info))
140endfunc
141
Bram Moolenaarcf3d0ea2022-10-07 11:20:29 +0100142def Test_timer_stopall_with_popup()
143 # Create a popup that times out after ten seconds.
144 # Another timer will fire in half a second and close it early after stopping
145 # all timers.
146 var pop = popup_create('Popup', {time: 10000})
Yee Cheng Chine70587d2025-02-13 20:55:45 +0100147 var tmr = timer_start(100, (_) => {
Bram Moolenaarcf3d0ea2022-10-07 11:20:29 +0100148 timer_stopall()
149 popup_clear()
150 })
Yee Cheng Chine70587d2025-02-13 20:55:45 +0100151 sleep 100m
152 g:WaitForAssert(() => assert_equal([], popup_list()), 1000)
Bram Moolenaarcf3d0ea2022-10-07 11:20:29 +0100153 assert_equal([], timer_info(tmr))
Bram Moolenaarcf3d0ea2022-10-07 11:20:29 +0100154enddef
155
Bram Moolenaar9a2fddc2019-08-16 11:26:06 +0200156func Test_timer_paused()
Bram Moolenaarb73598e2016-08-07 18:22:53 +0200157 let g:val = 0
158
159 let id = timer_start(50, 'MyHandler')
160 let info = timer_info(id)
161 call assert_equal(0, info[0]['paused'])
162
Bram Moolenaarf92e58c2019-09-08 21:51:41 +0200163 eval id->timer_pause(1)
Bram Moolenaarb73598e2016-08-07 18:22:53 +0200164 let info = timer_info(id)
165 call assert_equal(1, info[0]['paused'])
166 sleep 100m
167 call assert_equal(0, g:val)
168
169 call timer_pause(id, 0)
170 let info = timer_info(id)
171 call assert_equal(0, info[0]['paused'])
172
173 let slept = WaitFor('g:val == 1')
174 call assert_equal(1, g:val)
Bram Moolenaarf267f8b2016-08-22 21:40:29 +0200175 if has('reltime')
Bram Moolenaara47ebdb2017-12-23 18:41:35 +0100176 if has('mac')
177 " The travis Mac machines appear to be very busy.
Bram Moolenaarbc28e9f2019-12-18 20:10:23 +0100178 call assert_inrange(0, 90, slept)
Bram Moolenaara47ebdb2017-12-23 18:41:35 +0100179 else
180 call assert_inrange(0, 30, slept)
181 endif
Bram Moolenaarf267f8b2016-08-22 21:40:29 +0200182 else
183 call assert_inrange(0, 10, slept)
184 endif
Bram Moolenaare20b9ec2020-02-03 21:40:04 +0100185
186 call assert_fails('call timer_pause("abc", 1)', 'E39:')
Bram Moolenaarb73598e2016-08-07 18:22:53 +0200187endfunc
188
Bram Moolenaar417ccd72016-09-01 21:26:20 +0200189func StopMyself(timer)
190 let g:called += 1
191 if g:called == 2
192 call timer_stop(a:timer)
193 endif
194endfunc
195
Bram Moolenaar9a2fddc2019-08-16 11:26:06 +0200196func Test_timer_delete_myself()
Bram Moolenaar417ccd72016-09-01 21:26:20 +0200197 let g:called = 0
198 let t = timer_start(10, 'StopMyself', {'repeat': -1})
Bram Moolenaar0e9d1ae2018-04-30 14:28:24 +0200199 call WaitForAssert({-> assert_equal(2, g:called)})
Bram Moolenaar417ccd72016-09-01 21:26:20 +0200200 call assert_equal(2, g:called)
201 call assert_equal([], timer_info(t))
202endfunc
203
Bram Moolenaar75537a92016-09-05 22:45:28 +0200204func StopTimer1(timer)
Bram Moolenaarf92e58c2019-09-08 21:51:41 +0200205 let g:timer2 = 10->timer_start('StopTimer2')
Bram Moolenaar75537a92016-09-05 22:45:28 +0200206 " avoid maxfuncdepth error
207 call timer_pause(g:timer1, 1)
Bram Moolenaar413c04e2019-08-16 22:29:18 +0200208 sleep 20m
Bram Moolenaar75537a92016-09-05 22:45:28 +0200209endfunc
210
211func StopTimer2(timer)
212 call timer_stop(g:timer1)
213endfunc
214
Bram Moolenaar9a2fddc2019-08-16 11:26:06 +0200215func Test_timer_stop_in_callback()
Bram Moolenaar0056ca72022-09-23 21:26:39 +0100216 call assert_equal(1, len(timer_info()))
Bram Moolenaar75537a92016-09-05 22:45:28 +0200217 let g:timer1 = timer_start(10, 'StopTimer1')
Bram Moolenaar315244d2019-08-17 13:18:16 +0200218 let slept = 0
219 for i in range(10)
Bram Moolenaar0056ca72022-09-23 21:26:39 +0100220 if len(timer_info()) == 1
Bram Moolenaar315244d2019-08-17 13:18:16 +0200221 break
222 endif
223 sleep 10m
224 let slept += 10
225 endfor
Bram Moolenaar0056ca72022-09-23 21:26:39 +0100226 if slept == 100
227 call assert_equal(1, len(timer_info()))
228 else
229 " This should take only 30 msec, but on Mac it's often longer
230 call assert_inrange(0, 50, slept)
231 endif
Bram Moolenaar75537a92016-09-05 22:45:28 +0200232endfunc
233
234func StopTimerAll(timer)
235 call timer_stopall()
236endfunc
237
Bram Moolenaar9a2fddc2019-08-16 11:26:06 +0200238func Test_timer_stop_all_in_callback()
Bram Moolenaar0056ca72022-09-23 21:26:39 +0100239 " One timer is for TestTimeout()
Bram Moolenaar427dddf2019-08-16 21:22:41 +0200240 call assert_equal(1, len(timer_info()))
Bram Moolenaar0056ca72022-09-23 21:26:39 +0100241 call timer_start(10, 'StopTimerAll')
242 call assert_equal(2, len(timer_info()))
Bram Moolenaar427dddf2019-08-16 21:22:41 +0200243 let slept = 0
244 for i in range(10)
245 if len(timer_info()) == 0
246 break
247 endif
248 sleep 10m
249 let slept += 10
250 endfor
Bram Moolenaar0056ca72022-09-23 21:26:39 +0100251 if slept == 100
252 call assert_equal(0, len(timer_info()))
253 else
254 call assert_inrange(0, 30, slept)
255 endif
Bram Moolenaar75537a92016-09-05 22:45:28 +0200256endfunc
257
Bram Moolenaar1e8e1452017-06-24 16:03:06 +0200258func FeedkeysCb(timer)
259 call feedkeys("hello\<CR>", 'nt')
260endfunc
261
262func InputCb(timer)
263 call timer_start(10, 'FeedkeysCb')
264 let g:val = input('?')
265 call Resume()
266endfunc
267
Bram Moolenaar9a2fddc2019-08-16 11:26:06 +0200268func Test_timer_input_in_timer()
Bram Moolenaar1e8e1452017-06-24 16:03:06 +0200269 let g:val = ''
270 call timer_start(10, 'InputCb')
271 call Standby(1000)
272 call assert_equal('hello', g:val)
273endfunc
Bram Moolenaar75537a92016-09-05 22:45:28 +0200274
Bram Moolenaarc577d812017-07-08 22:37:34 +0200275func FuncWithError(timer)
276 let g:call_count += 1
277 if g:call_count == 4
278 return
279 endif
280 doesnotexist
281endfunc
282
283func Test_timer_errors()
284 let g:call_count = 0
285 let timer = timer_start(10, 'FuncWithError', {'repeat': -1})
286 " Timer will be stopped after failing 3 out of 3 times.
Bram Moolenaar0e9d1ae2018-04-30 14:28:24 +0200287 call WaitForAssert({-> assert_equal(3, g:call_count)})
Bram Moolenaarc577d812017-07-08 22:37:34 +0200288 sleep 50m
289 call assert_equal(3, g:call_count)
Bram Moolenaare20b9ec2020-02-03 21:40:04 +0100290
Yegappan Lakshmanan04c4c572022-08-30 19:48:24 +0100291 call assert_fails('call timer_start(100, "MyHandler", "abc")', 'E1206:')
Bram Moolenaare20b9ec2020-02-03 21:40:04 +0100292 call assert_fails('call timer_start(100, [])', 'E921:')
Yegappan Lakshmanan8deb2b32022-09-02 15:15:27 +0100293 call assert_fails('call timer_stop("abc")', 'E1210:')
Bram Moolenaarc577d812017-07-08 22:37:34 +0200294endfunc
295
Bram Moolenaare723c422017-09-06 23:40:10 +0200296func FuncWithCaughtError(timer)
297 let g:call_count += 1
298 try
299 doesnotexist
300 catch
301 " nop
302 endtry
303endfunc
304
305func Test_timer_catch_error()
306 let g:call_count = 0
307 let timer = timer_start(10, 'FuncWithCaughtError', {'repeat': 4})
308 " Timer will not be stopped.
Bram Moolenaar0e9d1ae2018-04-30 14:28:24 +0200309 call WaitForAssert({-> assert_equal(4, g:call_count)})
Bram Moolenaare723c422017-09-06 23:40:10 +0200310 sleep 50m
311 call assert_equal(4, g:call_count)
312endfunc
313
Bram Moolenaar5e80de32017-09-03 15:48:12 +0200314func FeedAndPeek(timer)
315 call test_feedinput('a')
316 call getchar(1)
317endfunc
318
319func Interrupt(timer)
Bram Moolenaarce90e362019-09-08 18:58:44 +0200320 eval "\<C-C>"->test_feedinput()
Bram Moolenaar5e80de32017-09-03 15:48:12 +0200321endfunc
322
Bram Moolenaar9a2fddc2019-08-16 11:26:06 +0200323func Test_timer_peek_and_get_char()
zeertzjqeb273cd2022-07-01 19:11:23 +0100324 if !has('unix') && !has('gui_running')
325 throw 'Skipped: cannot feed low-level input'
326 endif
Bram Moolenaar8c5a2782019-08-07 23:07:07 +0200327
Bram Moolenaar5e80de32017-09-03 15:48:12 +0200328 call timer_start(0, 'FeedAndPeek')
329 let intr = timer_start(100, 'Interrupt')
330 let c = getchar()
331 call assert_equal(char2nr('a'), c)
Bram Moolenaarf92e58c2019-09-08 21:51:41 +0200332 eval intr->timer_stop()
Bram Moolenaar5e80de32017-09-03 15:48:12 +0200333endfunc
Bram Moolenaarc577d812017-07-08 22:37:34 +0200334
Bram Moolenaar9a2fddc2019-08-16 11:26:06 +0200335func Test_timer_getchar_zero()
Bram Moolenaar8d4ce562019-01-30 22:01:40 +0100336 if has('win32') && !has('gui_running')
zeertzjqeb273cd2022-07-01 19:11:23 +0100337 throw 'Skipped: cannot feed low-level input'
Bram Moolenaarcb908a82019-01-28 23:20:04 +0100338 endif
Bram Moolenaar5feabe02020-01-30 18:24:53 +0100339 CheckFunction reltimefloat
Bram Moolenaarcb908a82019-01-28 23:20:04 +0100340
Bram Moolenaar50948e42019-01-29 20:36:56 +0100341 " Measure the elapsed time to avoid a hang when it fails.
342 let start = reltime()
Bram Moolenaar8d4ce562019-01-30 22:01:40 +0100343 let id = timer_start(20, {-> feedkeys('x', 'L')})
Bram Moolenaar12dfc9e2019-01-28 22:32:58 +0100344 let c = 0
Bram Moolenaar50948e42019-01-29 20:36:56 +0100345 while c == 0 && reltimefloat(reltime(start)) < 0.2
Bram Moolenaar12dfc9e2019-01-28 22:32:58 +0100346 let c = getchar(0)
347 sleep 10m
348 endwhile
349 call assert_equal('x', nr2char(c))
Bram Moolenaarcb908a82019-01-28 23:20:04 +0100350 call timer_stop(id)
Bram Moolenaar12dfc9e2019-01-28 22:32:58 +0100351endfunc
352
Bram Moolenaar9a2fddc2019-08-16 11:26:06 +0200353func Test_timer_ex_mode()
Bram Moolenaarf5291f32017-09-14 22:55:37 +0200354 " Function with an empty line.
355 func Foo(...)
356
357 endfunc
Bram Moolenaarcb908a82019-01-28 23:20:04 +0100358 let timer = timer_start(40, function('g:Foo'), {'repeat':-1})
Bram Moolenaarf5291f32017-09-14 22:55:37 +0200359 " This used to throw error E749.
360 exe "normal Qsleep 100m\rvi\r"
361 call timer_stop(timer)
362endfunc
363
Bram Moolenaar9a2fddc2019-08-16 11:26:06 +0200364func Test_timer_restore_count()
Bram Moolenaar494e9062020-05-31 21:28:02 +0200365 CheckRunVimInTerminal
Bram Moolenaarb0f42ba2018-05-12 15:38:26 +0200366 " Check that v:count is saved and restored, not changed by a timer.
367 call writefile([
368 \ 'nnoremap <expr><silent> L v:count ? v:count . "l" : "l"',
369 \ 'func Doit(id)',
370 \ ' normal 3j',
371 \ 'endfunc',
372 \ 'call timer_start(100, "Doit")',
Bram Moolenaarc4860bd2022-10-15 20:52:26 +0100373 \ ], 'Xtrcscript', 'D')
Bram Moolenaarb0f42ba2018-05-12 15:38:26 +0200374 call writefile([
375 \ '1-1234',
376 \ '2-1234',
377 \ '3-1234',
Bram Moolenaarc4860bd2022-10-15 20:52:26 +0100378 \ ], 'Xtrctext', 'D')
Bram Moolenaarb0f42ba2018-05-12 15:38:26 +0200379 let buf = RunVimInTerminal('-S Xtrcscript Xtrctext', {})
380
381 " Wait for the timer to move the cursor to the third line.
382 call WaitForAssert({-> assert_equal(3, term_getcursor(buf)[0])})
383 call assert_equal(1, term_getcursor(buf)[1])
384 " Now check that v:count has not been set to 3
385 call term_sendkeys(buf, 'L')
386 call WaitForAssert({-> assert_equal(2, term_getcursor(buf)[1])})
387
388 call StopVimInTerminal(buf)
Bram Moolenaarb0f42ba2018-05-12 15:38:26 +0200389endfunc
390
Bram Moolenaaradc67142019-06-22 01:40:42 +0200391" Test that the garbage collector isn't triggered if a timer callback invokes
392" vgetc().
zeertzjqbb404f52022-07-23 06:25:29 +0100393func Test_nocatch_timer_garbage_collect()
Bram Moolenaar0056ca72022-09-23 21:26:39 +0100394 " FIXME: why does this fail only on MacOS M1?
Bram Moolenaar94722c52023-01-28 19:19:03 +0000395 try
Bram Moolenaar140f6d02022-09-24 14:49:07 +0100396 CheckNotMacM1
397 catch /Skipped/
398 let g:skipped_reason = v:exception
399 return
400 endtry
Bram Moolenaar0056ca72022-09-23 21:26:39 +0100401
Bram Moolenaaradc67142019-06-22 01:40:42 +0200402 " 'uptimetime. must be bigger than the timer timeout
403 set ut=200
404 call test_garbagecollect_soon()
405 call test_override('no_wait_return', 0)
406 func CauseAnError(id)
407 " This will show an error and wait for Enter.
408 let a = {'foo', 'bar'}
409 endfunc
410 func FeedChar(id)
Bram Moolenaar4ecf16b2022-09-23 18:22:21 +0100411 call feedkeys(":\<CR>", 't')
Bram Moolenaaradc67142019-06-22 01:40:42 +0200412 endfunc
413 call timer_start(300, 'FeedChar')
414 call timer_start(100, 'CauseAnError')
Bram Moolenaar4ecf16b2022-09-23 18:22:21 +0100415 let x = getchar() " wait for error in timer
416 let x = getchar(0) " read any remaining chars
417 let x = getchar(0)
Bram Moolenaaradc67142019-06-22 01:40:42 +0200418
419 set ut&
420 call test_override('no_wait_return', 1)
421 delfunc CauseAnError
422 delfunc FeedChar
423endfunc
424
Bram Moolenaar9a2fddc2019-08-16 11:26:06 +0200425func Test_timer_error_in_timer_callback()
Bram Moolenaar0d702022019-07-04 14:20:41 +0200426 if !has('terminal') || (has('win32') && has('gui_running'))
Bram Moolenaar7d491c42019-06-25 06:28:02 +0200427 throw 'Skipped: cannot run Vim in a terminal window'
428 endif
429
430 let lines =<< trim [CODE]
431 func Func(timer)
432 " fail to create list
433 let x = [
434 endfunc
435 set updatetime=50
436 call timer_start(1, 'Func')
437 [CODE]
Bram Moolenaarc4860bd2022-10-15 20:52:26 +0100438 call writefile(lines, 'Xtest.vim', 'D')
Bram Moolenaar7d491c42019-06-25 06:28:02 +0200439
Bram Moolenaar0d702022019-07-04 14:20:41 +0200440 let buf = term_start(GetVimCommandCleanTerm() .. ' -S Xtest.vim', {'term_rows': 8})
Bram Moolenaar7d491c42019-06-25 06:28:02 +0200441 let job = term_getjob(buf)
442 call WaitForAssert({-> assert_notequal('', term_getline(buf, 8))})
443
444 " GC must not run during timer callback, which can make Vim crash.
Bram Moolenaar6a2c5a72020-04-08 21:50:25 +0200445 call TermWait(buf, 50)
Bram Moolenaar7d491c42019-06-25 06:28:02 +0200446 call term_sendkeys(buf, "\<CR>")
Bram Moolenaar6a2c5a72020-04-08 21:50:25 +0200447 call TermWait(buf, 50)
Bram Moolenaar7d491c42019-06-25 06:28:02 +0200448 call assert_equal('run', job_status(job))
449
450 call term_sendkeys(buf, ":qall!\<CR>")
451 call WaitFor({-> job_status(job) ==# 'dead'})
452 if has('unix')
453 call assert_equal('', job_info(job).termsig)
454 endif
455
Bram Moolenaar7d491c42019-06-25 06:28:02 +0200456 exe buf .. 'bwipe!'
457endfunc
458
Bram Moolenaare20b9ec2020-02-03 21:40:04 +0100459" Test for garbage collection when a timer is still running
460func Test_timer_garbage_collect()
461 let timer = timer_start(1000, function('MyHandler'), {'repeat' : 10})
462 call test_garbagecollect_now()
463 let l = timer_info(timer)
464 call assert_equal(function('MyHandler'), l[0].callback)
465 call timer_stop(timer)
466endfunc
467
Bram Moolenaar14e579092020-03-07 16:59:25 +0100468func Test_timer_invalid_callback()
Bram Moolenaare2e40752020-09-04 21:18:46 +0200469 call assert_fails('call timer_start(0, "0")', 'E921:')
Bram Moolenaar14e579092020-03-07 16:59:25 +0100470endfunc
471
Bram Moolenaar3fffa972020-06-05 21:06:10 +0200472func Test_timer_changing_function_list()
473 CheckRunVimInTerminal
474
475 " Create a large number of functions. Should get the "more" prompt.
476 " The typing "G" triggers the timer, which changes the function table.
477 let lines =<< trim END
478 for func in map(range(1,99), "'Func' .. v:val")
479 exe "func " .. func .. "()"
480 endfunc
481 endfor
482 au CmdlineLeave : call timer_start(0, {-> 0})
483 END
Bram Moolenaarc4860bd2022-10-15 20:52:26 +0100484 call writefile(lines, 'XTest_timerchange', 'D')
Bram Moolenaar3fffa972020-06-05 21:06:10 +0200485 let buf = RunVimInTerminal('-S XTest_timerchange', #{rows: 10})
486 call term_sendkeys(buf, ":fu\<CR>")
487 call WaitForAssert({-> assert_match('-- More --', term_getline(buf, 10))})
488 call term_sendkeys(buf, "G")
Bram Moolenaare2e40752020-09-04 21:18:46 +0200489 call WaitForAssert({-> assert_match('E454:', term_getline(buf, 9))})
Bram Moolenaar3fffa972020-06-05 21:06:10 +0200490 call term_sendkeys(buf, "\<Esc>")
491
492 call StopVimInTerminal(buf)
Bram Moolenaar3fffa972020-06-05 21:06:10 +0200493endfunc
494
Bram Moolenaar9f284162021-04-22 21:39:30 +0200495func Test_timer_outputting_message()
496 CheckRunVimInTerminal
497
498 let lines =<< trim END
499 vim9script
500 setline(1, 'some text')
501 set showcmd ut=2000 cmdheight=1
502 timer_start(0, (_) => {
503 echon repeat('x', &columns - 11)
504 })
505 END
Bram Moolenaarc4860bd2022-10-15 20:52:26 +0100506 call writefile(lines, 'XTest_timermessage', 'D')
Bram Moolenaar9f284162021-04-22 21:39:30 +0200507 let buf = RunVimInTerminal('-S XTest_timermessage', #{rows: 6})
508 call term_sendkeys(buf, "l")
509 call term_wait(buf)
510 " should not get a hit-enter prompt
511 call WaitForAssert({-> assert_match('xxxxxxxxxxx', term_getline(buf, 6))})
512
513 call StopVimInTerminal(buf)
Bram Moolenaar9f284162021-04-22 21:39:30 +0200514endfunc
515
Bram Moolenaare615db02022-01-20 21:00:54 +0000516func Test_timer_using_win_execute_undo_sync()
Bram Moolenaar865bf2e2022-09-24 17:44:22 +0100517 " FIXME: why does this fail only on MacOS M1?
518 CheckNotMacM1
519
Bram Moolenaare615db02022-01-20 21:00:54 +0000520 let bufnr1 = bufnr()
521 new
522 let g:bufnr2 = bufnr()
523 let g:winid = win_getid()
524 exe "buffer " .. bufnr1
525 wincmd w
526 call setline(1, ['test'])
527 autocmd InsertEnter * call timer_start(100, { -> win_execute(g:winid, 'buffer ' .. g:bufnr2) })
528 call timer_start(200, { -> feedkeys("\<CR>bbbb\<Esc>") })
529 call feedkeys("Oaaaa", 'x!t')
530 " will hang here until the second timer fires
531 call assert_equal(['aaaa', 'bbbb', 'test'], getline(1, '$'))
532 undo
533 call assert_equal(['test'], getline(1, '$'))
534
535 bwipe!
536 bwipe!
537 unlet g:winid
538 unlet g:bufnr2
539 au! InsertEnter
540endfunc
541
Bram Moolenaarf08b0eb2021-10-16 13:00:14 +0100542
Bram Moolenaar9e4d8212016-08-18 23:04:48 +0200543" vim: shiftwidth=2 sts=2 expandtab