xref: /vim-8.2.3635/src/testdir/runtest.vim (revision 640d4f0c)
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