vim-patch:8.0.1771: in tests, when WaitFor() fails it doesn't say why

Problem:    In tests, when WaitFor() fails it doesn't say why. (James McCoy)
Solution:   Add WaitForAssert(), which produces an assert error when it fails.
50182fa84e
This commit is contained in:
Jan Edmund Lazo 2019-09-20 19:08:01 -04:00
parent 7cffc87868
commit 3878b0822e
No known key found for this signature in database
GPG Key ID: 64915E6E9F735B15
3 changed files with 66 additions and 28 deletions

View File

@ -135,39 +135,80 @@ endfunc
" Wait for up to five seconds for "expr" to become true. "expr" can be a
" stringified expression to evaluate, or a funcref without arguments.
" Using a lambda works best. Example:
" call WaitFor({-> status == "ok"})
"
" A second argument can be used to specify a different timeout in msec.
"
" Return time slept in milliseconds. With the +reltime feature this can be
" more than the actual waiting time. Without +reltime it can also be less.
" When successful the time slept is returned.
" When running into the timeout an exception is thrown, thus the function does
" not return.
func WaitFor(expr, ...)
let timeout = get(a:000, 0, 5000)
let slept = s:WaitForCommon(a:expr, v:null, timeout)
if slept < 0
throw 'WaitFor() timed out after ' . timeout . ' msec'
endif
return slept
endfunc
" Wait for up to five seconds for "assert" to return zero. "assert" must be a
" (lambda) function containing one assert function. Example:
" call WaitForAssert({-> assert_equal("dead", job_status(job)})
"
" A second argument can be used to specify a different timeout in msec.
"
" Return zero for success, one for failure (like the assert function).
func WaitForAssert(assert, ...)
let timeout = get(a:000, 0, 5000)
if s:WaitForCommon(v:null, a:assert, timeout) < 0
return 1
endif
return 0
endfunc
" Common implementation of WaitFor() and WaitForAssert().
" Either "expr" or "assert" is not v:null
" Return the waiting time for success, -1 for failure.
func s:WaitForCommon(expr, assert, timeout)
" using reltime() is more accurate, but not always available
let slept = 0
if has('reltime')
let start = reltime()
else
let slept = 0
endif
if type(a:expr) == v:t_func
let Test = a:expr
else
let Test = {-> eval(a:expr) }
endif
for i in range(timeout / 10)
if Test()
if has('reltime')
return float2nr(reltimefloat(reltime(start)) * 1000)
endif
while 1
if type(a:expr) == v:t_func
let success = a:expr()
elseif type(a:assert) == v:t_func
let success = a:assert() == 0
else
let success = eval(a:expr)
endif
if success
return slept
endif
if !has('reltime')
if slept >= a:timeout
break
endif
if type(a:assert) == v:t_func
" Remove the error added by the assert function.
call remove(v:errors, -1)
endif
sleep 10m
if has('reltime')
let slept = float2nr(reltimefloat(reltime(start)) * 1000)
else
let slept += 10
endif
sleep 10m
endfor
throw 'WaitFor() timed out after ' . timeout . ' msec'
endwhile
return -1 " timed out
endfunc
" Wait for up to a given milliseconds.
" With the +timers feature this waits for key-input by getchar(), Resume()
" feeds key-input and resumes process. Return time waited in milliseconds.

View File

@ -1344,11 +1344,11 @@ func Test_Changed_FirstTime()
let buf = term_start([GetVimProg(), '--clean', '-c', 'set noswapfile'], {'term_rows': 3})
call assert_equal('running', term_getstatus(buf))
" Wait for the ruler (in the status line) to be shown.
call WaitFor({-> term_getline(buf, 3) =~# '\<All$'})
call WaitForAssert({-> assert_match('\<All$', term_getline(buf, 3))})
" It's only adding autocmd, so that no event occurs.
call term_sendkeys(buf, ":au! TextChanged <buffer> call writefile(['No'], 'Xchanged.txt')\<cr>")
call term_sendkeys(buf, "\<C-\\>\<C-N>:qa!\<cr>")
call WaitFor({-> term_getstatus(buf) == 'finished'})
call WaitForAssert({-> assert_equal('finished', term_getstatus(buf))})
call assert_equal([''], readfile('Xchanged.txt'))
" clean up

View File

@ -28,12 +28,11 @@ func Test_client_server()
let name = 'XVIMTEST'
let cmd .= ' --servername ' . name
let job = job_start(cmd, {'stoponexit': 'kill', 'out_io': 'null'})
call WaitFor({-> job_status(job) == "run"})
call WaitForAssert({-> assert_equal("run", job_status(job))})
" Takes a short while for the server to be active.
" When using valgrind it takes much longer.
call WaitFor('serverlist() =~ "' . name . '"')
call assert_match(name, serverlist())
call WaitForAssert({-> assert_match(name, serverlist())})
call remote_foreground(name)
@ -54,12 +53,10 @@ func Test_client_server()
endif
" Wait for the server to be up and answering requests.
sleep 100m
call WaitFor('remote_expr("' . name . '", "v:version", "", 1) != ""')
call assert_true(remote_expr(name, "v:version", "", 1) != "")
call WaitForAssert({-> assert_true(remote_expr(name, "v:version", "", 1) != "")})
call remote_send(name, ":let testvar = 'maybe'\<CR>")
call WaitFor('remote_expr("' . name . '", "testvar", "", 1) == "maybe"')
call assert_equal('maybe', remote_expr(name, "testvar", "", 2))
call WaitForAssert({-> assert_equal('maybe', remote_expr(name, "testvar", "", 2))})
endif
call assert_fails('call remote_send("XXX", ":let testvar = ''yes''\<CR>")', 'E241')
@ -94,7 +91,7 @@ func Test_client_server()
call remote_send(name, ":qa!\<CR>")
try
call WaitFor({-> job_status(job) == "dead"})
call WaitForAssert({-> assert_equal("dead", job_status(job))})
finally
if job_status(job) != 'dead'
call assert_report('Server did not exit')