To: vim_dev@googlegroups.com Subject: Patch 8.0.1771 Fcc: outbox From: Bram Moolenaar Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ------------ Patch 8.0.1771 Problem: In tests, when WaitFor() fails it doesn't say why. (James McCoy) Solution: Add WaitForAssert(), which produces an assert error when it fails. Files: src/testdir/shared.vim, src/testdir/test_terminal.vim, src/testdir/screendump.vim, src/testdir/test_autocmd.vim, src/testdir/test_channel.vim, src/testdir/test_clientserver.vim, src/testdir/test_job_fails.vim *** ../vim-8.0.1770/src/testdir/shared.vim 2018-04-11 20:53:45.765218228 +0200 --- src/testdir/shared.vim 2018-04-28 19:05:09.304805196 +0200 *************** *** 115,152 **** " Wait for up to five seconds for "expr" to become true. "expr" can be a " stringified expression to evaluate, or a funcref without arguments. " 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. func WaitFor(expr, ...) let timeout = get(a:000, 0, 5000) " using reltime() is more accurate, but not always available 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 return slept endif ! if !has('reltime') ! let slept += 10 endif sleep 10m ! endfor ! throw 'WaitFor() timed out after ' . timeout . ' msec' 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. --- 115,194 ---- " 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. " ! " 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() 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 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 ! 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. *** ../vim-8.0.1770/src/testdir/test_terminal.vim 2018-04-21 23:34:38.522654097 +0200 --- src/testdir/test_terminal.vim 2018-04-28 19:01:35.566204828 +0200 *************** *** 83,90 **** let buf = Run_shell_in_terminal({}) call assert_fails(buf . 'bwipe', 'E517') exe buf . 'bwipe!' ! call WaitFor('job_status(g:job) == "dead"') ! call assert_equal('dead', job_status(g:job)) call assert_equal("", bufname(buf)) unlet g:job --- 83,89 ---- let buf = Run_shell_in_terminal({}) call assert_fails(buf . 'bwipe', 'E517') exe buf . 'bwipe!' ! call WaitForAssert({-> assert_equal('dead', job_status(g:job))}) call assert_equal("", bufname(buf)) unlet g:job *************** *** 100,106 **** call assert_equal('run', job_status(g:job)) quit! ! call WaitFor('job_status(g:job) == "dead"') call assert_equal('dead', job_status(g:job)) exe buf . 'bwipe' --- 99,105 ---- call assert_equal('run', job_status(g:job)) quit! ! call WaitForAssert({-> assert_equal('dead', job_status(g:job))}) call assert_equal('dead', job_status(g:job)) exe buf . 'bwipe' *** ../vim-8.0.1770/src/testdir/screendump.vim 2018-04-15 22:25:50.496763590 +0200 --- src/testdir/screendump.vim 2018-04-28 19:37:34.471963491 +0200 *************** *** 64,72 **** let cols = term_getsize(buf)[1] endif ! " Wait for "All" of the ruler in the status line to be shown. ! " This can be quite slow (e.g. when using valgrind). ! call WaitFor({-> len(term_getline(buf, rows)) >= cols - 1}) return buf endfunc --- 64,78 ---- let cols = term_getsize(buf)[1] endif ! " Wait for "All" or "Top" of the ruler in the status line to be shown. This ! " can be quite slow (e.g. when using valgrind). ! " If it fails then show the terminal contents for debugging. ! try ! call WaitFor({-> len(term_getline(buf, rows)) >= cols - 1}) ! catch /timed out after/ ! let lines = map(range(1, rows), {key, val -> term_getline(buf, val)}) ! call assert_report('RunVimInTerminal() failed, screen contents: ' . join(lines, "")) ! endtry return buf endfunc *************** *** 75,81 **** func StopVimInTerminal(buf) call assert_equal("running", term_getstatus(a:buf)) call term_sendkeys(a:buf, "\\:qa!\") ! call WaitFor('term_getstatus(' . a:buf . ') == "finished"') only! endfunc --- 81,87 ---- func StopVimInTerminal(buf) call assert_equal("running", term_getstatus(a:buf)) call term_sendkeys(a:buf, "\\:qa!\") ! call WaitForAssert({-> assert_equal("finished", term_getstatus(a:buf))}) only! endfunc *** ../vim-8.0.1770/src/testdir/test_autocmd.vim 2018-04-22 13:27:38.812672851 +0200 --- src/testdir/test_autocmd.vim 2018-04-28 20:01:18.338634100 +0200 *************** *** 1322,1332 **** 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) =~# '\ call writefile(['No'], 'Xchanged.txt')\") call term_sendkeys(buf, "\\:qa!\") ! call WaitFor({-> term_getstatus(buf) == 'finished'}) call assert_equal([''], readfile('Xchanged.txt')) " clean up --- 1322,1332 ---- 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 WaitForAssert({-> assert_match('\ call writefile(['No'], 'Xchanged.txt')\") call term_sendkeys(buf, "\\:qa!\") ! call WaitForAssert({-> assert_equal('finished', term_getstatus(buf))}) call assert_equal([''], readfile('Xchanged.txt')) " clean up *** ../vim-8.0.1770/src/testdir/test_channel.vim 2018-04-24 20:54:01.572445034 +0200 --- src/testdir/test_channel.vim 2018-04-28 21:07:37.996856199 +0200 *************** *** 95,112 **** " handled before getting the response, but it's not guaranteed, thus wait a " tiny bit for the commands to get executed. call assert_equal('ok', ch_evalexpr(handle, 'make change')) ! call WaitFor('"added2" == getline("$")') call assert_equal('added1', getline(line('$') - 1)) - call assert_equal('added2', getline('$')) " Request command "foo bar", which fails silently. call assert_equal('ok', ch_evalexpr(handle, 'bad command')) ! call WaitFor('v:errmsg =~ "E492"') ! call assert_match('E492:.*foo bar', v:errmsg) call assert_equal('ok', ch_evalexpr(handle, 'do normal', {'timeout': 100})) ! call WaitFor('"added more" == getline("$")') ! call assert_equal('added more', getline('$')) " Send a request with a specific handler. call ch_sendexpr(handle, 'hello!', {'callback': 'Ch_requestHandler'}) --- 95,109 ---- " handled before getting the response, but it's not guaranteed, thus wait a " tiny bit for the commands to get executed. call assert_equal('ok', ch_evalexpr(handle, 'make change')) ! call WaitForAssert({-> assert_equal("added2", getline("$"))}) call assert_equal('added1', getline(line('$') - 1)) " Request command "foo bar", which fails silently. call assert_equal('ok', ch_evalexpr(handle, 'bad command')) ! call WaitForAssert({-> assert_match("E492:.*foo bar", v:errmsg)}) call assert_equal('ok', ch_evalexpr(handle, 'do normal', {'timeout': 100})) ! call WaitForAssert({-> assert_equal('added more', getline('$'))}) " Send a request with a specific handler. call ch_sendexpr(handle, 'hello!', {'callback': 'Ch_requestHandler'}) *************** *** 188,197 **** " Send an expr request call assert_equal('ok', ch_evalexpr(handle, 'an expr')) ! call WaitFor('"three" == getline("$")') call assert_equal('one', getline(line('$') - 2)) call assert_equal('two', getline(line('$') - 1)) - call assert_equal('three', getline('$')) " Request a redraw, we don't check for the effect. call assert_equal('ok', ch_evalexpr(handle, 'redraw')) --- 185,193 ---- " Send an expr request call assert_equal('ok', ch_evalexpr(handle, 'an expr')) ! call WaitForAssert({-> assert_equal('three', getline('$'))}) call assert_equal('one', getline(line('$') - 2)) call assert_equal('two', getline(line('$') - 1)) " Request a redraw, we don't check for the effect. call assert_equal('ok', ch_evalexpr(handle, 'redraw')) *************** *** 288,298 **** " Test that it works while waiting on a numbered message. call assert_equal('ok', ch_evalexpr(handle, 'call me')) ! call WaitFor('"we called you" == g:Ch_reply') " Test that it works while not waiting on a numbered message. call ch_sendexpr(handle, 'call me again') ! call WaitFor('"we did call you" == g:Ch_reply') endfunc func Test_channel_handler() --- 284,294 ---- " Test that it works while waiting on a numbered message. call assert_equal('ok', ch_evalexpr(handle, 'call me')) ! call WaitForAssert({-> assert_equal('we called you', g:Ch_reply)}) " Test that it works while not waiting on a numbered message. call ch_sendexpr(handle, 'call me again') ! call WaitForAssert({-> assert_equal('we did call you', g:Ch_reply)}) endfunc func Test_channel_handler() *************** *** 334,340 **** let g:Ch_reply = '' call assert_equal('sent zero', ch_evalexpr(handle, 'send zero')) if s:has_handler ! call WaitFor('"zero index" == g:Ch_reply') else sleep 20m call assert_equal('', g:Ch_reply) --- 330,336 ---- let g:Ch_reply = '' call assert_equal('sent zero', ch_evalexpr(handle, 'send zero')) if s:has_handler ! call WaitForAssert({-> assert_equal('zero index', g:Ch_reply)}) else sleep 20m call assert_equal('', g:Ch_reply) *************** *** 344,350 **** let g:Ch_reply = '' let g:Ch_zero_reply = '' call ch_sendexpr(handle, 'send zero', {'callback': 'Ch_oneHandler'}) ! call WaitFor('"sent zero" == g:Ch_zero_reply') if s:has_handler call assert_equal('zero index', g:Ch_reply) else --- 340,346 ---- let g:Ch_reply = '' let g:Ch_zero_reply = '' call ch_sendexpr(handle, 'send zero', {'callback': 'Ch_oneHandler'}) ! call WaitForAssert({-> assert_equal('sent zero', g:Ch_zero_reply)}) if s:has_handler call assert_equal('zero index', g:Ch_reply) else *************** *** 395,409 **** " The messages are sent raw, we do our own JSON strings here. call ch_sendraw(handle, "[1, \"hello!\"]\n", {'callback': 'Ch_handleRaw1'}) ! call WaitFor('g:Ch_reply1 != ""') ! call assert_equal("[1, \"got it\"]", g:Ch_reply1) call ch_sendraw(handle, "[2, \"echo something\"]\n", {'callback': 'Ch_handleRaw2'}) call ch_sendraw(handle, "[3, \"wait a bit\"]\n", {'callback': 'Ch_handleRaw3'}) ! call WaitFor('g:Ch_reply2 != ""') ! call assert_equal("[2, \"something\"]", g:Ch_reply2) " wait for the 200 msec delayed reply ! call WaitFor('g:Ch_reply3 != ""') ! call assert_equal("[3, \"waited\"]", g:Ch_reply3) endfunc func Test_raw_one_time_callback() --- 391,402 ---- " The messages are sent raw, we do our own JSON strings here. call ch_sendraw(handle, "[1, \"hello!\"]\n", {'callback': 'Ch_handleRaw1'}) ! call WaitForAssert({-> assert_equal("[1, \"got it\"]", g:Ch_reply1)}) call ch_sendraw(handle, "[2, \"echo something\"]\n", {'callback': 'Ch_handleRaw2'}) call ch_sendraw(handle, "[3, \"wait a bit\"]\n", {'callback': 'Ch_handleRaw3'}) ! call WaitForAssert({-> assert_equal("[2, \"something\"]", g:Ch_reply2)}) " wait for the 200 msec delayed reply ! call WaitForAssert({-> assert_equal("[3, \"waited\"]", g:Ch_reply3)}) endfunc func Test_raw_one_time_callback() *************** *** 494,501 **** let g:Ch_reply = "" call ch_sendraw(job, "double this\n", {'callback': 'Ch_handler'}) ! call WaitFor('"" != g:Ch_reply') ! call assert_equal("this\nAND this\n", substitute(g:Ch_reply, "\r", "", 'g')) let reply = ch_evalraw(job, "quit\n", {'timeout': 100}) call assert_equal("Goodbye!\n", substitute(reply, "\r", "", 'g')) --- 487,493 ---- let g:Ch_reply = "" call ch_sendraw(job, "double this\n", {'callback': 'Ch_handler'}) ! call WaitForAssert({-> assert_equal("this\nAND this\n", substitute(g:Ch_reply, "\r", "", 'g'))}) let reply = ch_evalraw(job, "quit\n", {'timeout': 100}) call assert_equal("Goodbye!\n", substitute(reply, "\r", "", 'g')) *************** *** 504,510 **** endtry let g:Ch_job = job ! call WaitFor('"dead" == job_status(g:Ch_job)') let info = job_info(job) call assert_equal("dead", info.status) call assert_equal("term", info.stoponexit) --- 496,502 ---- endtry let g:Ch_job = job ! call WaitForAssert({-> assert_equal("dead", job_status(g:Ch_job))}) let info = job_info(job) call assert_equal("dead", info.status) call assert_equal("term", info.stoponexit) *************** *** 602,608 **** if has('win32') " On MS-Windows the server must close the file handle before we are able " to delete the file. ! call WaitFor('job_status(g:job) == "dead"') sleep 10m endif endfunc --- 594,600 ---- if has('win32') " On MS-Windows the server must close the file handle before we are able " to delete the file. ! call WaitForAssert({-> assert_equal('dead', job_status(g:job))}) sleep 10m endif endfunc *************** *** 641,648 **** call ch_sendraw(handle, "echo line one\n") call ch_sendraw(handle, "echo line two\n") call ch_sendraw(handle, "double this\n") ! call WaitFor('len(readfile("Xoutput")) > 2') ! call assert_equal(['line one', 'line two', 'this', 'AND this'], readfile('Xoutput')) finally call Stop_g_job() call assert_equal(-1, match(s:get_resources(), '\(^\|/\)Xoutput$')) --- 633,639 ---- call ch_sendraw(handle, "echo line one\n") call ch_sendraw(handle, "echo line two\n") call ch_sendraw(handle, "double this\n") ! call WaitForAssert({-> assert_equal(['line one', 'line two', 'this', 'AND this'], readfile('Xoutput'))}) finally call Stop_g_job() call assert_equal(-1, match(s:get_resources(), '\(^\|/\)Xoutput$')) *************** *** 663,670 **** call ch_sendraw(handle, "echoerr line one\n") call ch_sendraw(handle, "echoerr line two\n") call ch_sendraw(handle, "doubleerr this\n") ! call WaitFor('len(readfile("Xoutput")) > 2') ! call assert_equal(['line one', 'line two', 'this', 'AND this'], readfile('Xoutput')) finally call Stop_g_job() call delete('Xoutput') --- 654,660 ---- call ch_sendraw(handle, "echoerr line one\n") call ch_sendraw(handle, "echoerr line two\n") call ch_sendraw(handle, "doubleerr this\n") ! call WaitForAssert({-> assert_equal(['line one', 'line two', 'this', 'AND this'], readfile('Xoutput'))}) finally call Stop_g_job() call delete('Xoutput') *************** *** 685,692 **** call ch_sendraw(handle, "echo line two\n") call ch_sendraw(handle, "double this\n") call ch_sendraw(handle, "doubleerr that\n") ! call WaitFor('len(readfile("Xoutput")) > 5') ! call assert_equal(['line one', 'line two', 'this', 'AND this', 'that', 'AND that'], readfile('Xoutput')) finally call Stop_g_job() call assert_equal(-1, match(s:get_resources(), '\(^\|/\)Xoutput$')) --- 675,681 ---- call ch_sendraw(handle, "echo line two\n") call ch_sendraw(handle, "double this\n") call ch_sendraw(handle, "doubleerr that\n") ! call WaitForAssert({-> assert_equal(['line one', 'line two', 'this', 'AND this', 'that', 'AND that'], readfile('Xoutput'))}) finally call Stop_g_job() call assert_equal(-1, match(s:get_resources(), '\(^\|/\)Xoutput$')) *************** *** 777,784 **** let job = job_start(s:python . " test_channel_write.py", options) call assert_equal("run", job_status(job)) try ! call WaitFor('line("$") == 3') ! call assert_equal(3, line('$')) quit! sleep 100m " Make sure the write didn't happen to the wrong buffer. --- 766,772 ---- let job = job_start(s:python . " test_channel_write.py", options) call assert_equal("run", job_status(job)) try ! call WaitForAssert({-> assert_equal(3, line('$'))}) quit! sleep 100m " Make sure the write didn't happen to the wrong buffer. *************** *** 827,834 **** call ch_sendraw(handle, "doubleerr this\n") call ch_sendraw(handle, "quit\n") sp pipe-err ! call WaitFor('line("$") == ' . len(expected)) ! call assert_equal(expected, getline(1, '$')) if a:nomod call assert_equal(0, &modifiable) else --- 815,821 ---- call ch_sendraw(handle, "doubleerr this\n") call ch_sendraw(handle, "quit\n") sp pipe-err ! call WaitForAssert({-> assert_equal(expected, getline(1, '$'))}) if a:nomod call assert_equal(0, &modifiable) else *************** *** 872,879 **** call ch_sendraw(handle, "doubleerr that\n") call ch_sendraw(handle, "quit\n") sp pipe-err ! call WaitFor('line("$") >= 7') ! call assert_equal(['Reading from channel output...', 'line one', 'line two', 'this', 'AND this', 'that', 'AND that', 'Goodbye!'], getline(1, '$')) bwipe! finally call job_stop(job) --- 859,865 ---- call ch_sendraw(handle, "doubleerr that\n") call ch_sendraw(handle, "quit\n") sp pipe-err ! call WaitForAssert({-> assert_equal(['Reading from channel output...', 'line one', 'line two', 'this', 'AND this', 'that', 'AND that', 'Goodbye!'], getline(1, '$'))}) bwipe! finally call job_stop(job) *************** *** 939,946 **** call ch_close_in(g:job) endif ! call WaitFor('job_status(g:job) == "dead"') ! call assert_equal("dead", job_status(g:job)) sp sortout call WaitFor('line("$") > 3') --- 925,931 ---- call ch_close_in(g:job) endif ! call WaitForAssert({-> assert_equal("dead", job_status(g:job))}) sp sortout call WaitFor('line("$") > 3') *************** *** 1222,1237 **** let g:Ch_errmsg = '' call ch_sendraw(job, "echo [0, \"hello\"]\n") call ch_sendraw(job, "echoerr [0, \"there\"]\n") ! call WaitFor('g:Ch_outmsg != ""') ! call assert_equal("dict: hello", g:Ch_outmsg) ! call WaitFor('g:Ch_errmsg != ""') ! call assert_equal("dict: there", g:Ch_errmsg) " Receive a json object split in pieces unlet! g:Ch_outobj call ch_sendraw(job, "echosplit [0, {\"one\": 1,| \"tw|o\": 2, \"three\": 3|}]\n") ! call WaitFor('exists("g:Ch_outobj")') ! call assert_equal({'one': 1, 'two': 2, 'three': 3}, g:Ch_outobj) finally call job_stop(job) endtry --- 1207,1220 ---- let g:Ch_errmsg = '' call ch_sendraw(job, "echo [0, \"hello\"]\n") call ch_sendraw(job, "echoerr [0, \"there\"]\n") ! call WaitForAssert({-> assert_equal("dict: hello", g:Ch_outmsg)}) ! call WaitForAssert({-> assert_equal("dict: there", g:Ch_errmsg)}) " Receive a json object split in pieces unlet! g:Ch_outobj call ch_sendraw(job, "echosplit [0, {\"one\": 1,| \"tw|o\": 2, \"three\": 3|}]\n") ! let g:Ch_outobj = '' ! call WaitForAssert({-> assert_equal({'one': 1, 'two': 2, 'three': 3}, g:Ch_outobj)}) finally call job_stop(job) endtry *************** *** 1261,1269 **** \ 'close_cb': 'CloseHandler'}) call assert_equal("run", job_status(job)) try ! call WaitFor('g:Ch_closemsg != 0 && g:Ch_msg1 != ""') ! call assert_equal('quit', g:Ch_msg1) ! call assert_equal(2, g:Ch_closemsg) finally call job_stop(job) delfunc OutHandler --- 1244,1251 ---- \ 'close_cb': 'CloseHandler'}) call assert_equal("run", job_status(job)) try ! call WaitForAssert({-> assert_equal('quit', g:Ch_msg1)}) ! call WaitForAssert({-> assert_equal(2, g:Ch_closemsg)}) finally call job_stop(job) delfunc OutHandler *************** *** 1285,1292 **** \ {'close_cb': 'CloseHandler'}) call assert_equal("run", job_status(job)) try ! call WaitFor('g:Ch_received != ""') ! call assert_equal('quit', g:Ch_received) finally call job_stop(job) delfunc CloseHandler --- 1267,1273 ---- \ {'close_cb': 'CloseHandler'}) call assert_equal("run", job_status(job)) try ! call WaitForAssert({-> assert_equal('quit', g:Ch_received)}) finally call job_stop(job) delfunc CloseHandler *************** *** 1310,1317 **** \ {'close_cb': 'CloseHandler'}) call assert_equal("run", job_status(job)) try ! call WaitFor('g:Ch_received != ""') ! call assert_equal('incomplete', g:Ch_received) finally call job_stop(job) delfunc CloseHandler --- 1291,1297 ---- \ {'close_cb': 'CloseHandler'}) call assert_equal("run", job_status(job)) try ! call WaitForAssert({-> assert_equal('incomplete', g:Ch_received)}) finally call job_stop(job) delfunc CloseHandler *************** *** 1335,1344 **** let g:Ch_errmsg = '' call ch_sendraw(job, "echo [0, \"hello\"]\n") call ch_sendraw(job, "echoerr [0, \"there\"]\n") ! call WaitFor('g:Ch_outmsg != ""') ! call assert_equal("lambda: hello", g:Ch_outmsg) ! call WaitFor('g:Ch_errmsg != ""') ! call assert_equal("lambda: there", g:Ch_errmsg) finally call job_stop(job) endtry --- 1315,1322 ---- let g:Ch_errmsg = '' call ch_sendraw(job, "echo [0, \"hello\"]\n") call ch_sendraw(job, "echoerr [0, \"there\"]\n") ! call WaitForAssert({-> assert_equal("lambda: hello", g:Ch_outmsg)}) ! call WaitForAssert({-> assert_equal("lambda: there", g:Ch_errmsg)}) finally call job_stop(job) endtry *************** *** 1364,1371 **** \ }) call assert_equal('run', job_status(g:job)) unlet g:job ! call WaitFor('len(g:retdict.ret) >= 2') ! call assert_equal(2, len(g:retdict.ret)) call assert_match('^\%(dead\|run\)', g:retdict.ret['close_cb']) call assert_equal('dead', g:retdict.ret['exit_cb']) unlet g:retdict --- 1342,1348 ---- \ }) call assert_equal('run', job_status(g:job)) unlet g:job ! call WaitForAssert({-> assert_equal(2, len(g:retdict.ret))}) call assert_match('^\%(dead\|run\)', g:retdict.ret['close_cb']) call assert_equal('dead', g:retdict.ret['exit_cb']) unlet g:retdict *************** *** 1383,1390 **** func Ch_unlet_handle(port) let s:channelfd = ch_open('localhost:' . a:port, s:chopt) call ch_sendexpr(s:channelfd, "test", {'callback': function('s:UnletHandler')}) ! call WaitFor('"what?" == g:Ch_unletResponse') ! call assert_equal('what?', g:Ch_unletResponse) endfunc func Test_unlet_handle() --- 1360,1366 ---- func Ch_unlet_handle(port) let s:channelfd = ch_open('localhost:' . a:port, s:chopt) call ch_sendexpr(s:channelfd, "test", {'callback': function('s:UnletHandler')}) ! call WaitForAssert({-> assert_equal('what?', g:Ch_unletResponse)}) endfunc func Test_unlet_handle() *************** *** 1404,1411 **** func Ch_close_handle(port) let s:channelfd = ch_open('localhost:' . a:port, s:chopt) call ch_sendexpr(s:channelfd, "test", {'callback': function('Ch_CloseHandler')}) ! call WaitFor('"what?" == g:Ch_unletResponse') ! call assert_equal('what?', g:Ch_unletResponse) endfunc func Test_close_handle() --- 1380,1386 ---- func Ch_close_handle(port) let s:channelfd = ch_open('localhost:' . a:port, s:chopt) call ch_sendexpr(s:channelfd, "test", {'callback': function('Ch_CloseHandler')}) ! call WaitForAssert({-> assert_equal('what?', g:Ch_unletResponse)}) endfunc func Test_close_handle() *************** *** 1458,1465 **** let g:Ch_call_ret = [] call assert_equal('ok', ch_evalexpr(handle, 'call-func')) ! call WaitFor('len(g:Ch_call_ret) > 0') ! call assert_equal([1, 2, 3], g:Ch_call_ret) endfunc func Test_call() --- 1433,1439 ---- let g:Ch_call_ret = [] call assert_equal('ok', ch_evalexpr(handle, 'call-func')) ! call WaitForAssert({-> assert_equal([1, 2, 3], g:Ch_call_ret)}) endfunc func Test_call() *************** *** 1556,1563 **** call ch_setoptions(handle, {'close_cb': 'MyCloseCb'}) call assert_equal('', ch_evalexpr(handle, 'close me')) ! call WaitFor('"closed" == g:Ch_close_ret') ! call assert_equal('closed', g:Ch_close_ret) endfunc func Test_close_callback() --- 1530,1536 ---- call ch_setoptions(handle, {'close_cb': 'MyCloseCb'}) call assert_equal('', ch_evalexpr(handle, 'close me')) ! call WaitForAssert({-> assert_equal('closed', g:Ch_close_ret)}) endfunc func Test_close_callback() *************** *** 1578,1585 **** call ch_setoptions(handle, {'close_cb': g:Ch_d.closeCb}) call assert_equal('', ch_evalexpr(handle, 'close me')) ! call WaitFor('"closed" == g:Ch_d.close_ret') ! call assert_equal('closed', g:Ch_d.close_ret) unlet g:Ch_d endfunc --- 1551,1557 ---- call ch_setoptions(handle, {'close_cb': g:Ch_d.closeCb}) call assert_equal('', ch_evalexpr(handle, 'close me')) ! call WaitForAssert({-> assert_equal('closed', g:Ch_d.close_ret)}) unlet g:Ch_d endfunc *************** *** 1601,1608 **** let g:job = job_start([s:python, '-c', 'import time;time.sleep(10)']) try call job_stop(g:job) ! call WaitFor('"dead" == job_status(g:job)') ! call assert_equal('dead', job_status(g:job)) finally call job_stop(g:job, 'kill') unlet g:job --- 1573,1579 ---- let g:job = job_start([s:python, '-c', 'import time;time.sleep(10)']) try call job_stop(g:job) ! call WaitForAssert({-> assert_equal('dead', job_status(g:job))}) finally call job_stop(g:job, 'kill') unlet g:job *************** *** 1637,1644 **** split testout 1,$delete call job_start('cat test_channel.vim', {'out_io': 'buffer', 'out_name': 'testout'}) ! call WaitFor('line("$") >= g:linecount') ! call assert_inrange(g:linecount, g:linecount + 1, line('$')) bwipe! endfunc --- 1608,1614 ---- split testout 1,$delete call job_start('cat test_channel.vim', {'out_io': 'buffer', 'out_name': 'testout'}) ! call WaitForAssert({-> assert_inrange(g:linecount, g:linecount + 1, line('$'))}) bwipe! endfunc *************** *** 1648,1660 **** endif call assert_false(filereadable("file with space")) let job = job_start('touch "file with space"') ! call WaitFor('filereadable("file with space")') ! call assert_true(filereadable("file with space")) call delete("file with space") let job = job_start('touch file\ with\ space') ! call WaitFor('filereadable("file with space")') ! call assert_true(filereadable("file with space")) call delete("file with space") endfunc --- 1618,1628 ---- endif call assert_false(filereadable("file with space")) let job = job_start('touch "file with space"') ! call WaitForAssert({-> assert_true(filereadable("file with space"))}) call delete("file with space") let job = job_start('touch file\ with\ space') ! call WaitForAssert({-> assert_true(filereadable("file with space"))}) call delete("file with space") endfunc *************** *** 1683,1689 **** new mybuffer call setline(1, ["asdf\nasdf", "xxx\n", "\nyyy"]) let g:Ch_job = job_start('cat', {'in_io': 'buffer', 'in_name': 'mybuffer', 'out_io': 'file', 'out_name': 'Xtestwrite'}) ! call WaitFor('"dead" == job_status(g:Ch_job)') bwipe! split Xtestwrite call assert_equal("asdf\nasdf", getline(1)) --- 1651,1657 ---- new mybuffer call setline(1, ["asdf\nasdf", "xxx\n", "\nyyy"]) let g:Ch_job = job_start('cat', {'in_io': 'buffer', 'in_name': 'mybuffer', 'out_io': 'file', 'out_name': 'Xtestwrite'}) ! call WaitForAssert({-> assert_equal("dead", job_status(g:Ch_job))}) bwipe! split Xtestwrite call assert_equal("asdf\nasdf", getline(1)) *************** *** 1707,1714 **** let g:linecount = 0 let arg = 'import sys;sys.stdout.write("1\n2\n3")' call job_start([s:python, '-c', arg], {'callback': 'MyLineCountCb'}) ! call WaitFor('3 <= g:linecount') ! call assert_equal(3, g:linecount) endfunc func Test_read_from_terminated_job() --- 1675,1681 ---- let g:linecount = 0 let arg = 'import sys;sys.stdout.write("1\n2\n3")' call job_start([s:python, '-c', arg], {'callback': 'MyLineCountCb'}) ! call WaitForAssert({-> assert_equal(3, g:linecount)}) endfunc func Test_read_from_terminated_job() *************** *** 1719,1726 **** let g:linecount = 0 let arg = 'import os,sys;os.close(1);sys.stderr.write("test\n")' call job_start([s:python, '-c', arg], {'callback': 'MyLineCountCb'}) ! call WaitFor('1 <= g:linecount') ! call assert_equal(1, g:linecount) endfunc func Test_env() --- 1686,1692 ---- let g:linecount = 0 let arg = 'import os,sys;os.close(1);sys.stderr.write("test\n")' call job_start([s:python, '-c', arg], {'callback': 'MyLineCountCb'}) ! call WaitForAssert({-> assert_equal(1, g:linecount)}) endfunc func Test_env() *************** *** 1736,1743 **** endif call assert_fails('call job_start(cmd, {"env": 1})', 'E475:') call job_start(cmd, {'callback': {ch,msg -> execute(":let g:envstr .= msg")}, 'env': {'FOO': 'bar'}}) ! call WaitFor('"" != g:envstr') ! call assert_equal("bar", g:envstr) unlet g:envstr endfunc --- 1702,1708 ---- endif call assert_fails('call job_start(cmd, {"env": 1})', 'E475:') call job_start(cmd, {'callback': {ch,msg -> execute(":let g:envstr .= msg")}, 'env': {'FOO': 'bar'}}) ! call WaitForAssert({-> assert_equal("bar", g:envstr)}) unlet g:envstr endfunc *************** *** 1756,1762 **** endif let job = job_start(cmd, {'callback': {ch,msg -> execute(":let g:envstr .= msg")}, 'cwd': expect}) try ! call WaitFor('"" != g:envstr') let expect = substitute(expect, '[/\\]$', '', '') let g:envstr = substitute(g:envstr, '[/\\]$', '', '') if $CI != '' && stridx(g:envstr, '/private/') == 0 --- 1721,1727 ---- endif let job = job_start(cmd, {'callback': {ch,msg -> execute(":let g:envstr .= msg")}, 'cwd': expect}) try ! call WaitForAssert({-> assert_notequal("", g:envstr)}) let expect = substitute(expect, '[/\\]$', '', '') let g:envstr = substitute(g:envstr, '[/\\]$', '', '') if $CI != '' && stridx(g:envstr, '/private/') == 0 *************** *** 1779,1786 **** call ch_setoptions(handle, {'close_cb': {ch -> execute("let g:Ch_close_ret = 'closed'")}}) call assert_equal('', ch_evalexpr(handle, 'close me')) ! call WaitFor('"closed" == g:Ch_close_ret') ! call assert_equal('closed', g:Ch_close_ret) endfunc func Test_close_lambda() --- 1744,1750 ---- call ch_setoptions(handle, {'close_cb': {ch -> execute("let g:Ch_close_ret = 'closed'")}}) call assert_equal('', ch_evalexpr(handle, 'close me')) ! call WaitForAssert({-> assert_equal('closed', g:Ch_close_ret)}) endfunc func Test_close_lambda() *** ../vim-8.0.1770/src/testdir/test_clientserver.vim 2018-04-11 20:53:45.765218228 +0200 --- src/testdir/test_clientserver.vim 2018-04-28 21:12:37.358995843 +0200 *************** *** 28,39 **** let name = 'XVIMTEST' let cmd .= ' --servername ' . name let job = job_start(cmd, {'stoponexit': 'kill', 'out_io': 'null'}) ! call WaitFor({-> job_status(job) == "run"}) " 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 remote_foreground(name) --- 28,38 ---- let name = 'XVIMTEST' let cmd .= ' --servername ' . name let job = job_start(cmd, {'stoponexit': 'kill', 'out_io': 'null'}) ! 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 WaitForAssert({-> assert_match(name, serverlist())}) call remote_foreground(name) *************** *** 54,65 **** 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 remote_send(name, ":let testvar = 'maybe'\") ! call WaitFor('remote_expr("' . name . '", "testvar", "", 1) == "maybe"') ! call assert_equal('maybe', remote_expr(name, "testvar", "", 2)) endif call assert_fails('call remote_send("XXX", ":let testvar = ''yes''\")', 'E241') --- 53,62 ---- endif " Wait for the server to be up and answering requests. sleep 100m ! call WaitForAssert({-> assert_true(remote_expr(name, "v:version", "", 1) != "")}) call remote_send(name, ":let testvar = 'maybe'\") ! call WaitForAssert({-> assert_equal('maybe', remote_expr(name, "testvar", "", 2))}) endif call assert_fails('call remote_send("XXX", ":let testvar = ''yes''\")', 'E241') *************** *** 94,100 **** call remote_send(name, ":qa!\") try ! call WaitFor({-> job_status(job) == "dead"}) finally if job_status(job) != 'dead' call assert_report('Server did not exit') --- 91,97 ---- call remote_send(name, ":qa!\") try ! call WaitForAssert({-> assert_equal("dead", job_status(job))}) finally if job_status(job) != 'dead' call assert_report('Server did not exit') *** ../vim-8.0.1770/src/testdir/test_job_fails.vim 2017-11-04 19:24:24.754197129 +0100 --- src/testdir/test_job_fails.vim 2018-04-28 21:13:12.494766693 +0200 *************** *** 8,16 **** if has('job') let job = job_start('axdfxsdf') if has('unix') ! call WaitFor({-> job_status(job) == "dead"}) else ! call WaitFor({-> job_status(job) == "fail"}) endif endif endfunc --- 8,16 ---- if has('job') let job = job_start('axdfxsdf') if has('unix') ! call WaitForAssert({-> assert_equal("dead", job_status(job))}) else ! call WaitForAssert({-> assert_equal("fail", job_status(job))}) endif endif endfunc *** ../vim-8.0.1770/src/version.c 2018-04-28 16:56:20.792322716 +0200 --- src/version.c 2018-04-28 19:07:23.095939984 +0200 *************** *** 763,764 **** --- 763,766 ---- { /* Add new patch number below this line */ + /**/ + 1771, /**/ -- When danger reared its ugly head, He bravely turned his tail and fled Yes, Brave Sir Robin turned about And gallantly he chickened out Bravely taking to his feet He beat a very brave retreat Bravest of the brave Sir Robin Petrified of being dead Soiled his pants then brave Sir Robin Turned away and fled. "Monty Python and the Holy Grail" PYTHON (MONTY) PICTURES LTD /// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net \\\ /// sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\ \\\ an exciting new programming language -- http://www.Zimbu.org /// \\\ help me help AIDS victims -- http://ICCF-Holland.org ///