143345546SBram Moolenaar" This script is sourced while editing the .vim file with the tests. 243345546SBram Moolenaar" When the script is successful the .res file will be created. 343345546SBram Moolenaar" Errors are appended to the test.log file. 443345546SBram Moolenaar" 5befb366aSBram Moolenaar" To execute only specific test functions, add a second argument. It will be 6befb366aSBram Moolenaar" matched against the names of the Test_ funtion. E.g.: 7befb366aSBram Moolenaar" ../vim -u NONE -S runtest.vim test_channel.vim open_delay 8befb366aSBram Moolenaar" The output can be found in the "messages" file. 9befb366aSBram Moolenaar" 1043345546SBram Moolenaar" The test script may contain anything, only functions that start with 1143345546SBram Moolenaar" "Test_" are special. These will be invoked and should contain assert 1243345546SBram Moolenaar" functions. See test_assert.vim for an example. 1343345546SBram Moolenaar" 1443345546SBram Moolenaar" It is possible to source other files that contain "Test_" functions. This 1543345546SBram Moolenaar" can speed up testing, since Vim does not need to restart. But be careful 1643345546SBram Moolenaar" that the tests do not interfere with each other. 1743345546SBram Moolenaar" 1843345546SBram Moolenaar" If an error cannot be detected properly with an assert function add the 1943345546SBram Moolenaar" error to the v:errors list: 2043345546SBram Moolenaar" call add(v:errors, 'test foo failed: Cannot find xyz') 2143345546SBram Moolenaar" 2243345546SBram Moolenaar" If preparation for each Test_ function is needed, define a SetUp function. 2343345546SBram Moolenaar" It will be called before each Test_ function. 2443345546SBram Moolenaar" 2543345546SBram Moolenaar" If cleanup after each Test_ function is needed, define a TearDown function. 2643345546SBram Moolenaar" It will be called after each Test_ function. 2700af60bbSBram Moolenaar" 2800af60bbSBram Moolenaar" When debugging a test it can be useful to add messages to v:errors: 2900af60bbSBram Moolenaar" call add(v:errors, "this happened") 3000af60bbSBram Moolenaar 3143345546SBram Moolenaar 3243345546SBram Moolenaar" Without the +eval feature we can't run these tests, bail out. 334686b323SBram Moolenaarso small.vim 3443345546SBram Moolenaar 3543345546SBram Moolenaar" Check that the screen size is at least 24 x 80 characters. 3643345546SBram Moolenaarif &lines < 24 || &columns < 80 3743345546SBram Moolenaar let error = 'Screen size too small! Tests require at least 24 lines with 80 characters' 3843345546SBram Moolenaar echoerr error 3943345546SBram Moolenaar split test.log 4043345546SBram Moolenaar $put =error 4143345546SBram Moolenaar w 4243345546SBram Moolenaar cquit 4343345546SBram Moolenaarendif 4443345546SBram Moolenaar 4575ee544fSBram Moolenaarif has('reltime') 4675ee544fSBram Moolenaar let s:start_time = reltime() 4775ee544fSBram Moolenaarendif 4875ee544fSBram Moolenaar 4989b10421SBram Moolenaar" Common with all tests on all systems. 5089b10421SBram Moolenaarsource setup.vim 5189b10421SBram Moolenaar 52c0662466SBram Moolenaar" For consistency run all tests with 'nocompatible' set. 53c0662466SBram Moolenaar" This also enables use of line continuation. 54c0662466SBram Moolenaarset nocp viminfo+=nviminfo 55c0662466SBram Moolenaar 5630276f2bSBram Moolenaar" Use utf-8 by default, instead of whatever the system default happens to be. 57ed79d1e3SBram Moolenaar" Individual tests can overrule this at the top of the file and use 58ed79d1e3SBram Moolenaar" g:orig_encoding if needed. 59ed79d1e3SBram Moolenaarlet g:orig_encoding = &encoding 60ac105ed3SBram Moolenaarset encoding=utf-8 61ac105ed3SBram Moolenaar 62d8f27b30SBram Moolenaar" REDIR_TEST_TO_NULL has a very permissive SwapExists autocommand which is for 63d8f27b30SBram Moolenaar" the test_name.vim file itself. Replace it here with a more restrictive one, 64d8f27b30SBram Moolenaar" so we still catch mistakes. 65d8f27b30SBram Moolenaarlet s:test_script_fname = expand('%') 66d8f27b30SBram Moolenaarau! SwapExists * call HandleSwapExists() 67d8f27b30SBram Moolenaarfunc HandleSwapExists() 68d8f27b30SBram Moolenaar " Only ignore finding a swap file for the test script (the user might be 69d8f27b30SBram Moolenaar " editing it and do ":make test_name") and the output file. 70d8f27b30SBram Moolenaar if expand('<afile>') == 'messages' || expand('<afile>') =~ s:test_script_fname 71d8f27b30SBram Moolenaar let v:swapchoice = 'e' 72d8f27b30SBram Moolenaar endif 73d8f27b30SBram Moolenaarendfunc 74d8f27b30SBram Moolenaar 757a073549SBram Moolenaar" Avoid stopping at the "hit enter" prompt 767a073549SBram Moolenaarset nomore 777a073549SBram Moolenaar 78c0662466SBram Moolenaar" Output all messages in English. 79c0662466SBram Moolenaarlang mess C 80c0662466SBram Moolenaar 81f60b796fSBram Moolenaar" Always use forward slashes. 82f60b796fSBram Moolenaarset shellslash 83f60b796fSBram Moolenaar 8428fb79dbSBram Moolenaarlet s:srcdir = expand('%:p:h:h') 8528fb79dbSBram Moolenaar 868e8df251SBram Moolenaar" Prepare for calling test_garbagecollect_now(). 87ebf7dfa6SBram Moolenaarlet v:testing = 1 88ebf7dfa6SBram Moolenaar 8928fb79dbSBram Moolenaar" Support function: get the alloc ID by name. 9028fb79dbSBram Moolenaarfunction GetAllocId(name) 9128fb79dbSBram Moolenaar exe 'split ' . s:srcdir . '/alloc.h' 92065ee9aeSBram Moolenaar let top = search('typedef enum') 93065ee9aeSBram Moolenaar if top == 0 94065ee9aeSBram Moolenaar call add(v:errors, 'typedef not found in alloc.h') 95065ee9aeSBram Moolenaar endif 9628fb79dbSBram Moolenaar let lnum = search('aid_' . a:name . ',') 9728fb79dbSBram Moolenaar if lnum == 0 9828fb79dbSBram Moolenaar call add(v:errors, 'Alloc ID ' . a:name . ' not defined') 9928fb79dbSBram Moolenaar endif 10028fb79dbSBram Moolenaar close 101065ee9aeSBram Moolenaar return lnum - top - 1 10228fb79dbSBram Moolenaarendfunc 10328fb79dbSBram Moolenaar 10442205551SBram Moolenaarfunc RunTheTest(test) 105b5760a1cSBram Moolenaar echo 'Executing ' . a:test 10675ee544fSBram Moolenaar if has('reltime') 10775ee544fSBram Moolenaar let func_start = reltime() 10875ee544fSBram Moolenaar endif 109e5f2a075SBram Moolenaar 110e5f2a075SBram Moolenaar " Avoid stopping at the "hit enter" prompt 111e5f2a075SBram Moolenaar set nomore 112e5f2a075SBram Moolenaar 113e5f2a075SBram Moolenaar " Avoid a three second wait when a message is about to be overwritten by the 114e5f2a075SBram Moolenaar " mode message. 115e5f2a075SBram Moolenaar set noshowmode 116e5f2a075SBram Moolenaar 117eb992cb9SBram Moolenaar " Clear any overrides. 118eb992cb9SBram Moolenaar call test_override('ALL', 0) 119eb992cb9SBram Moolenaar 120cf1ba35fSBram Moolenaar " Some tests wipe out buffers. To be consistent, always wipe out all 121cf1ba35fSBram Moolenaar " buffers. 122cf1ba35fSBram Moolenaar %bwipe! 123cf1ba35fSBram Moolenaar 124209d3874SBram Moolenaar " The test may change the current directory. Save and restore the 125209d3874SBram Moolenaar " directory after executing the test. 126209d3874SBram Moolenaar let save_cwd = getcwd() 127209d3874SBram Moolenaar 128b5760a1cSBram Moolenaar if exists("*SetUp") 129cc28e2d0SBram Moolenaar try 130b5760a1cSBram Moolenaar call SetUp() 131cc28e2d0SBram Moolenaar catch 132cc28e2d0SBram Moolenaar call add(v:errors, 'Caught exception in SetUp() before ' . a:test . ': ' . v:exception . ' @ ' . v:throwpoint) 133cc28e2d0SBram Moolenaar endtry 134b5760a1cSBram Moolenaar endif 135b5760a1cSBram Moolenaar 136f204e05aSBram Moolenaar if a:test =~ 'Test_nocatch_' 137f204e05aSBram Moolenaar " Function handles errors itself. This avoids skipping commands after the 138f204e05aSBram Moolenaar " error. 139f204e05aSBram Moolenaar exe 'call ' . a:test 140f204e05aSBram Moolenaar else 141b5760a1cSBram Moolenaar try 1428903676dSBram Moolenaar let s:test = a:test 1438903676dSBram Moolenaar au VimLeavePre * call EarlyExit(s:test) 144b5760a1cSBram Moolenaar exe 'call ' . a:test 1458903676dSBram Moolenaar au! VimLeavePre 146dac1947bSBram Moolenaar catch /^\cskipped/ 147dac1947bSBram Moolenaar call add(s:messages, ' Skipped') 148dac1947bSBram Moolenaar call add(s:skipped, 'SKIPPED ' . a:test . ': ' . substitute(v:exception, '^\S*\s\+', '', '')) 149b5760a1cSBram Moolenaar catch 150b5760a1cSBram Moolenaar call add(v:errors, 'Caught exception in ' . a:test . ': ' . v:exception . ' @ ' . v:throwpoint) 151b5760a1cSBram Moolenaar endtry 152f204e05aSBram Moolenaar endif 1538ad16da7SBram Moolenaar 1548ad16da7SBram Moolenaar " In case 'insertmode' was set and something went wrong, make sure it is 1558ad16da7SBram Moolenaar " reset to avoid trouble with anything else. 1568ad16da7SBram Moolenaar set noinsertmode 157b5760a1cSBram Moolenaar 158b5760a1cSBram Moolenaar if exists("*TearDown") 159cc28e2d0SBram Moolenaar try 160b5760a1cSBram Moolenaar call TearDown() 161cc28e2d0SBram Moolenaar catch 162cc28e2d0SBram Moolenaar call add(v:errors, 'Caught exception in TearDown() after ' . a:test . ': ' . v:exception . ' @ ' . v:throwpoint) 163cc28e2d0SBram Moolenaar endtry 164b5760a1cSBram Moolenaar endif 1657cba71d7SBram Moolenaar 166cf1ba35fSBram Moolenaar " Clear any autocommands 167cf1ba35fSBram Moolenaar au! 168d8f27b30SBram Moolenaar au SwapExists * call HandleSwapExists() 169cf1ba35fSBram Moolenaar 170ce11de87SBram Moolenaar " Close any extra tab pages and windows and make the current one not modified. 171ce11de87SBram Moolenaar while tabpagenr('$') > 1 172cf1ba35fSBram Moolenaar quit! 173ce11de87SBram Moolenaar endwhile 174ce11de87SBram Moolenaar 175358308ddSBram Moolenaar while 1 176358308ddSBram Moolenaar let wincount = winnr('$') 177358308ddSBram Moolenaar if wincount == 1 178358308ddSBram Moolenaar break 179358308ddSBram Moolenaar endif 1807cba71d7SBram Moolenaar bwipe! 181358308ddSBram Moolenaar if wincount == winnr('$') 182358308ddSBram Moolenaar " Did not manage to close a window. 183358308ddSBram Moolenaar only! 184358308ddSBram Moolenaar break 185358308ddSBram Moolenaar endif 1867cba71d7SBram Moolenaar endwhile 187209d3874SBram Moolenaar 188209d3874SBram Moolenaar exe 'cd ' . save_cwd 189*640d4f0cSBram Moolenaar 190*640d4f0cSBram Moolenaar let message = 'Executed ' . a:test 191*640d4f0cSBram Moolenaar if has('reltime') 192*640d4f0cSBram Moolenaar let message ..= ' in ' .. reltimestr(reltime(func_start)) .. ' seconds' 193*640d4f0cSBram Moolenaar endif 194*640d4f0cSBram Moolenaar call add(s:messages, message) 195*640d4f0cSBram Moolenaar let s:done += 1 196b5760a1cSBram Moolenaarendfunc 19728fb79dbSBram Moolenaar 19842205551SBram Moolenaarfunc AfterTheTest() 19943345546SBram Moolenaar if len(v:errors) > 0 20000af60bbSBram Moolenaar let s:fail += 1 20100af60bbSBram Moolenaar call add(s:errors, 'Found errors in ' . s:test . ':') 20200af60bbSBram Moolenaar call extend(s:errors, v:errors) 20343345546SBram Moolenaar let v:errors = [] 20443345546SBram Moolenaar endif 20542205551SBram Moolenaarendfunc 20642205551SBram Moolenaar 2078903676dSBram Moolenaarfunc EarlyExit(test) 2088903676dSBram Moolenaar " It's OK for the test we use to test the quit detection. 2098903676dSBram Moolenaar if a:test != 'Test_zz_quit_detected()' 2108903676dSBram Moolenaar call add(v:errors, 'Test caused Vim to exit: ' . a:test) 2118903676dSBram Moolenaar endif 2128903676dSBram Moolenaar 2138903676dSBram Moolenaar call FinishTesting() 2148903676dSBram Moolenaarendfunc 2158903676dSBram Moolenaar 21642205551SBram Moolenaar" This function can be called by a test if it wants to abort testing. 21742205551SBram Moolenaarfunc FinishTesting() 21842205551SBram Moolenaar call AfterTheTest() 21943345546SBram Moolenaar 220fc4ad616SBram Moolenaar " Don't write viminfo on exit. 221fc4ad616SBram Moolenaar set viminfo= 222fc4ad616SBram Moolenaar 223d1ee0043SBram Moolenaar " Clean up files created by setup.vim 224d1ee0043SBram Moolenaar call delete('XfakeHOME', 'rf') 225d1ee0043SBram Moolenaar 22600af60bbSBram Moolenaar if s:fail == 0 22743345546SBram Moolenaar " Success, create the .res file so that make knows it's done. 22800af60bbSBram Moolenaar exe 'split ' . fnamemodify(g:testname, ':r') . '.res' 22943345546SBram Moolenaar write 23043345546SBram Moolenaar endif 23143345546SBram Moolenaar 23200af60bbSBram Moolenaar if len(s:errors) > 0 23343345546SBram Moolenaar " Append errors to test.log 23443345546SBram Moolenaar split test.log 23543345546SBram Moolenaar call append(line('$'), '') 23600af60bbSBram Moolenaar call append(line('$'), 'From ' . g:testname . ':') 23700af60bbSBram Moolenaar call append(line('$'), s:errors) 23843345546SBram Moolenaar write 23943345546SBram Moolenaar endif 24043345546SBram Moolenaar 24129f9ed20SBram Moolenaar if s:done == 0 24229f9ed20SBram Moolenaar let message = 'NO tests executed' 24329f9ed20SBram Moolenaar else 24400af60bbSBram Moolenaar let message = 'Executed ' . s:done . (s:done > 1 ? ' tests' : ' test') 24529f9ed20SBram Moolenaar endif 24675ee544fSBram Moolenaar if has('reltime') 24775ee544fSBram Moolenaar let message ..= ' in ' .. reltimestr(reltime(s:start_time)) .. ' seconds' 24875ee544fSBram Moolenaar endif 249096c8bb4SBram Moolenaar echo message 25000af60bbSBram Moolenaar call add(s:messages, message) 25100af60bbSBram Moolenaar if s:fail > 0 25200af60bbSBram Moolenaar let message = s:fail . ' FAILED:' 253096c8bb4SBram Moolenaar echo message 25400af60bbSBram Moolenaar call add(s:messages, message) 25500af60bbSBram Moolenaar call extend(s:messages, s:errors) 25643345546SBram Moolenaar endif 25743345546SBram Moolenaar 258dac1947bSBram Moolenaar " Add SKIPPED messages 259dac1947bSBram Moolenaar call extend(s:messages, s:skipped) 260dac1947bSBram Moolenaar 261dac1947bSBram Moolenaar " Append messages to the file "messages" 262096c8bb4SBram Moolenaar split messages 263096c8bb4SBram Moolenaar call append(line('$'), '') 26400af60bbSBram Moolenaar call append(line('$'), 'From ' . g:testname . ':') 26500af60bbSBram Moolenaar call append(line('$'), s:messages) 266096c8bb4SBram Moolenaar write 267096c8bb4SBram Moolenaar 26843345546SBram Moolenaar qall! 26942205551SBram Moolenaarendfunc 27042205551SBram Moolenaar 27142205551SBram Moolenaar" Source the test script. First grab the file name, in case the script 27242205551SBram Moolenaar" navigates away. g:testname can be used by the tests. 27342205551SBram Moolenaarlet g:testname = expand('%') 27442205551SBram Moolenaarlet s:done = 0 27542205551SBram Moolenaarlet s:fail = 0 27642205551SBram Moolenaarlet s:errors = [] 27742205551SBram Moolenaarlet s:messages = [] 27842205551SBram Moolenaarlet s:skipped = [] 27942205551SBram Moolenaarif expand('%') =~ 'test_vimscript.vim' 28042205551SBram Moolenaar " this test has intentional s:errors, don't use try/catch. 28142205551SBram Moolenaar source % 28242205551SBram Moolenaarelse 28342205551SBram Moolenaar try 28442205551SBram Moolenaar source % 2859c0cec65SBram Moolenaar catch /^\cskipped/ 2869c0cec65SBram Moolenaar call add(s:messages, ' Skipped') 2879c0cec65SBram Moolenaar call add(s:skipped, 'SKIPPED ' . expand('%') . ': ' . substitute(v:exception, '^\S*\s\+', '', '')) 28842205551SBram Moolenaar catch 28942205551SBram Moolenaar let s:fail += 1 29042205551SBram Moolenaar call add(s:errors, 'Caught exception: ' . v:exception . ' @ ' . v:throwpoint) 29142205551SBram Moolenaar endtry 29242205551SBram Moolenaarendif 29342205551SBram Moolenaar 29442205551SBram Moolenaar" Names of flaky tests. 295dbc0d216SBram Moolenaarlet s:flaky_tests = [ 296c0f05d0bSBram Moolenaar \ 'Test_call()', 297c0f05d0bSBram Moolenaar \ 'Test_channel_handler()', 29842205551SBram Moolenaar \ 'Test_client_server()', 29942205551SBram Moolenaar \ 'Test_close_and_exit_cb()', 300c0f05d0bSBram Moolenaar \ 'Test_close_callback()', 301c0f05d0bSBram Moolenaar \ 'Test_close_handle()', 302c0f05d0bSBram Moolenaar \ 'Test_close_lambda()', 303d80232beSBram Moolenaar \ 'Test_close_output_buffer()', 304c0f05d0bSBram Moolenaar \ 'Test_close_partial()', 30542205551SBram Moolenaar \ 'Test_collapse_buffers()', 30642205551SBram Moolenaar \ 'Test_communicate()', 30765873846SBram Moolenaar \ 'Test_cwd()', 308218959bcSBram Moolenaar \ 'Test_diff_screen()', 309c0f05d0bSBram Moolenaar \ 'Test_exit_callback()', 31042205551SBram Moolenaar \ 'Test_exit_callback_interval()', 31142205551SBram Moolenaar \ 'Test_nb_basic()', 31242205551SBram Moolenaar \ 'Test_oneshot()', 313c0f05d0bSBram Moolenaar \ 'Test_open_delay()', 3141eca6f13SBram Moolenaar \ 'Test_out_cb()', 31524820691SBram Moolenaar \ 'Test_paused()', 31642205551SBram Moolenaar \ 'Test_pipe_through_sort_all()', 31742205551SBram Moolenaar \ 'Test_pipe_through_sort_some()', 318142ae736SBram Moolenaar \ 'Test_popup_and_window_resize()', 31942205551SBram Moolenaar \ 'Test_quoteplus()', 3207dd48506SBram Moolenaar \ 'Test_quotestar()', 321c0f05d0bSBram Moolenaar \ 'Test_raw_one_time_callback()', 32242205551SBram Moolenaar \ 'Test_reltime()', 323bfbea567SBram Moolenaar \ 'Test_repeat_three()', 324c0f05d0bSBram Moolenaar \ 'Test_server_crash()', 325c0f05d0bSBram Moolenaar \ 'Test_terminal_ansicolors_default()', 326c0f05d0bSBram Moolenaar \ 'Test_terminal_ansicolors_func()', 327c0f05d0bSBram Moolenaar \ 'Test_terminal_ansicolors_global()', 328f204e05aSBram Moolenaar \ 'Test_terminal_composing_unicode()', 3293876789bSBram Moolenaar \ 'Test_terminal_does_not_truncate_last_newlines()', 330c0f05d0bSBram Moolenaar \ 'Test_terminal_env()', 331c0f05d0bSBram Moolenaar \ 'Test_terminal_hide_buffer()', 332c0f05d0bSBram Moolenaar \ 'Test_terminal_make_change()', 3333615abb6SBram Moolenaar \ 'Test_terminal_no_cmd()', 33475a60f74SBram Moolenaar \ 'Test_terminal_noblock()', 3357dd88c51SBram Moolenaar \ 'Test_terminal_redir_file()', 336c0f05d0bSBram Moolenaar \ 'Test_terminal_response_to_control_sequence()', 337c0f05d0bSBram Moolenaar \ 'Test_terminal_scrollback()', 338c0f05d0bSBram Moolenaar \ 'Test_terminal_split_quit()', 339c0f05d0bSBram Moolenaar \ 'Test_terminal_termwinkey()', 340c0f05d0bSBram Moolenaar \ 'Test_terminal_termwinsize_mininmum()', 341c0f05d0bSBram Moolenaar \ 'Test_terminal_termwinsize_option_fixed()', 342c0f05d0bSBram Moolenaar \ 'Test_terminal_termwinsize_option_zero()', 34324820691SBram Moolenaar \ 'Test_terminal_tmap()', 344c0f05d0bSBram Moolenaar \ 'Test_terminal_wall()', 345c0f05d0bSBram Moolenaar \ 'Test_terminal_wipe_buffer()', 346c0f05d0bSBram Moolenaar \ 'Test_terminal_wqall()', 347c0f05d0bSBram Moolenaar \ 'Test_two_channels()', 348c0f05d0bSBram Moolenaar \ 'Test_unlet_handle()', 349d09be321SBram Moolenaar \ 'Test_with_partial_callback()', 350c0f05d0bSBram Moolenaar \ 'Test_zero_reply()', 351c0f05d0bSBram Moolenaar \ 'Test_zz1_terminal_in_gui()', 35242205551SBram Moolenaar \ ] 35342205551SBram Moolenaar 354dbc0d216SBram Moolenaar" Pattern indicating a common flaky test failure. 355447f6ce8SBram Moolenaarlet s:flaky_errors_re = 'StopVimInTerminal\|VerifyScreenDump' 356dbc0d216SBram Moolenaar 35742205551SBram Moolenaar" Locate Test_ functions and execute them. 35842205551SBram Moolenaarredir @q 35942205551SBram Moolenaarsilent function /^Test_ 36042205551SBram Moolenaarredir END 36142205551SBram Moolenaarlet s:tests = split(substitute(@q, 'function \(\k*()\)', '\1', 'g')) 36242205551SBram Moolenaar 36342205551SBram Moolenaar" If there is an extra argument filter the function names against it. 36442205551SBram Moolenaarif argc() > 1 36542205551SBram Moolenaar let s:tests = filter(s:tests, 'v:val =~ argv(1)') 36642205551SBram Moolenaarendif 36742205551SBram Moolenaar 36842205551SBram Moolenaar" Execute the tests in alphabetical order. 36942205551SBram Moolenaarfor s:test in sort(s:tests) 3704a6fcf80SBram Moolenaar " Silence, please! 3714a6fcf80SBram Moolenaar set belloff=all 372f77af0e6SBram Moolenaar let prev_error = '' 373f77af0e6SBram Moolenaar let total_errors = [] 374f77af0e6SBram Moolenaar let run_nr = 1 3754a6fcf80SBram Moolenaar 37642205551SBram Moolenaar call RunTheTest(s:test) 37742205551SBram Moolenaar 378f77af0e6SBram Moolenaar " Repeat a flaky test. Give up when: 379f77af0e6SBram Moolenaar " - it fails again with the same message 380f77af0e6SBram Moolenaar " - it fails five times (with a different mesage) 381dbc0d216SBram Moolenaar if len(v:errors) > 0 382dbc0d216SBram Moolenaar \ && (index(s:flaky_tests, s:test) >= 0 383dbc0d216SBram Moolenaar \ || v:errors[0] =~ s:flaky_errors_re) 384f77af0e6SBram Moolenaar while 1 3856caf606bSBram Moolenaar call add(s:messages, 'Found errors in ' . s:test . ':') 3866caf606bSBram Moolenaar call extend(s:messages, v:errors) 38715e737f7SBram Moolenaar 388f77af0e6SBram Moolenaar call add(total_errors, 'Run ' . run_nr . ':') 389f77af0e6SBram Moolenaar call extend(total_errors, v:errors) 390f77af0e6SBram Moolenaar 391f77af0e6SBram Moolenaar if run_nr == 5 || prev_error == v:errors[0] 392f77af0e6SBram Moolenaar call add(total_errors, 'Flaky test failed too often, giving up') 393f77af0e6SBram Moolenaar let v:errors = total_errors 394f77af0e6SBram Moolenaar break 395f77af0e6SBram Moolenaar endif 396f77af0e6SBram Moolenaar 397f77af0e6SBram Moolenaar call add(s:messages, 'Flaky test failed, running it again') 398f77af0e6SBram Moolenaar 399f77af0e6SBram Moolenaar " Flakiness is often caused by the system being very busy. Sleep a 400f77af0e6SBram Moolenaar " couple of seconds to have a higher chance of succeeding the second 401f77af0e6SBram Moolenaar " time. 40255058601SBram Moolenaar sleep 2 40355058601SBram Moolenaar 404f77af0e6SBram Moolenaar let prev_error = v:errors[0] 40542205551SBram Moolenaar let v:errors = [] 406f77af0e6SBram Moolenaar let run_nr += 1 407f77af0e6SBram Moolenaar 40842205551SBram Moolenaar call RunTheTest(s:test) 409f77af0e6SBram Moolenaar 410f77af0e6SBram Moolenaar if len(v:errors) == 0 411f77af0e6SBram Moolenaar " Test passed on rerun. 412f77af0e6SBram Moolenaar break 41315e737f7SBram Moolenaar endif 414f77af0e6SBram Moolenaar endwhile 41542205551SBram Moolenaar endif 41642205551SBram Moolenaar 41742205551SBram Moolenaar call AfterTheTest() 41842205551SBram Moolenaarendfor 41942205551SBram Moolenaar 42042205551SBram Moolenaarcall FinishTesting() 421cc28e2d0SBram Moolenaar 422cc28e2d0SBram Moolenaar" vim: shiftwidth=2 sts=2 expandtab 423