xref: /vim-8.2.3635/src/testdir/runtest.vim (revision b073da89)
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
4145aa07d3SBram Moolenaar  write
4245aa07d3SBram Moolenaar  split messages
4345aa07d3SBram Moolenaar  call append(line('$'), error)
4445aa07d3SBram Moolenaar  write
4545aa07d3SBram Moolenaar  qa!
4643345546SBram Moolenaarendif
4743345546SBram Moolenaar
4875ee544fSBram Moolenaarif has('reltime')
4975ee544fSBram Moolenaar  let s:start_time = reltime()
5075ee544fSBram Moolenaarendif
5175ee544fSBram Moolenaar
5289b10421SBram Moolenaar" Common with all tests on all systems.
5389b10421SBram Moolenaarsource setup.vim
5489b10421SBram Moolenaar
55c0662466SBram Moolenaar" For consistency run all tests with 'nocompatible' set.
56c0662466SBram Moolenaar" This also enables use of line continuation.
57c0662466SBram Moolenaarset nocp viminfo+=nviminfo
58c0662466SBram Moolenaar
5930276f2bSBram Moolenaar" Use utf-8 by default, instead of whatever the system default happens to be.
60ed79d1e3SBram Moolenaar" Individual tests can overrule this at the top of the file and use
61ed79d1e3SBram Moolenaar" g:orig_encoding if needed.
62ed79d1e3SBram Moolenaarlet g:orig_encoding = &encoding
63ac105ed3SBram Moolenaarset encoding=utf-8
64ac105ed3SBram Moolenaar
65d8f27b30SBram Moolenaar" REDIR_TEST_TO_NULL has a very permissive SwapExists autocommand which is for
66d8f27b30SBram Moolenaar" the test_name.vim file itself. Replace it here with a more restrictive one,
67d8f27b30SBram Moolenaar" so we still catch mistakes.
68d8f27b30SBram Moolenaarlet s:test_script_fname = expand('%')
69d8f27b30SBram Moolenaarau! SwapExists * call HandleSwapExists()
70d8f27b30SBram Moolenaarfunc HandleSwapExists()
71*b073da89SBram Moolenaar  " Ignore finding a swap file for the test script (the user might be
72d8f27b30SBram Moolenaar  " editing it and do ":make test_name") and the output file.
73*b073da89SBram Moolenaar  " Report finding another swap file and chose 'q' to avoid getting stuck.
74d8f27b30SBram Moolenaar  if expand('<afile>') == 'messages' || expand('<afile>') =~ s:test_script_fname
75d8f27b30SBram Moolenaar    let v:swapchoice = 'e'
76*b073da89SBram Moolenaar  else
77*b073da89SBram Moolenaar    call assert_report('Unexpected swap file: ' .. v:swapname)
78*b073da89SBram Moolenaar    let v:swapchoice = 'q'
79d8f27b30SBram Moolenaar  endif
80d8f27b30SBram Moolenaarendfunc
81d8f27b30SBram Moolenaar
827a073549SBram Moolenaar" Avoid stopping at the "hit enter" prompt
837a073549SBram Moolenaarset nomore
847a073549SBram Moolenaar
85c0662466SBram Moolenaar" Output all messages in English.
86c0662466SBram Moolenaarlang mess C
87c0662466SBram Moolenaar
88f60b796fSBram Moolenaar" Always use forward slashes.
89f60b796fSBram Moolenaarset shellslash
90f60b796fSBram Moolenaar
9128fb79dbSBram Moolenaarlet s:srcdir = expand('%:p:h:h')
9228fb79dbSBram Moolenaar
938e8df251SBram Moolenaar" Prepare for calling test_garbagecollect_now().
94ebf7dfa6SBram Moolenaarlet v:testing = 1
95ebf7dfa6SBram Moolenaar
9628fb79dbSBram Moolenaar" Support function: get the alloc ID by name.
9728fb79dbSBram Moolenaarfunction GetAllocId(name)
9828fb79dbSBram Moolenaar  exe 'split ' . s:srcdir . '/alloc.h'
99065ee9aeSBram Moolenaar  let top = search('typedef enum')
100065ee9aeSBram Moolenaar  if top == 0
101065ee9aeSBram Moolenaar    call add(v:errors, 'typedef not found in alloc.h')
102065ee9aeSBram Moolenaar  endif
10328fb79dbSBram Moolenaar  let lnum = search('aid_' . a:name . ',')
10428fb79dbSBram Moolenaar  if lnum == 0
10528fb79dbSBram Moolenaar    call add(v:errors, 'Alloc ID ' . a:name . ' not defined')
10628fb79dbSBram Moolenaar  endif
10728fb79dbSBram Moolenaar  close
108065ee9aeSBram Moolenaar  return lnum - top - 1
10928fb79dbSBram Moolenaarendfunc
11028fb79dbSBram Moolenaar
11142205551SBram Moolenaarfunc RunTheTest(test)
112b5760a1cSBram Moolenaar  echo 'Executing ' . a:test
11375ee544fSBram Moolenaar  if has('reltime')
11475ee544fSBram Moolenaar    let func_start = reltime()
11575ee544fSBram Moolenaar  endif
116e5f2a075SBram Moolenaar
117e5f2a075SBram Moolenaar  " Avoid stopping at the "hit enter" prompt
118e5f2a075SBram Moolenaar  set nomore
119e5f2a075SBram Moolenaar
120e5f2a075SBram Moolenaar  " Avoid a three second wait when a message is about to be overwritten by the
121e5f2a075SBram Moolenaar  " mode message.
122e5f2a075SBram Moolenaar  set noshowmode
123e5f2a075SBram Moolenaar
124eb992cb9SBram Moolenaar  " Clear any overrides.
125eb992cb9SBram Moolenaar  call test_override('ALL', 0)
126eb992cb9SBram Moolenaar
127cf1ba35fSBram Moolenaar  " Some tests wipe out buffers.  To be consistent, always wipe out all
128cf1ba35fSBram Moolenaar  " buffers.
129cf1ba35fSBram Moolenaar  %bwipe!
130cf1ba35fSBram Moolenaar
131209d3874SBram Moolenaar  " The test may change the current directory. Save and restore the
132209d3874SBram Moolenaar  " directory after executing the test.
133209d3874SBram Moolenaar  let save_cwd = getcwd()
134209d3874SBram Moolenaar
135b5760a1cSBram Moolenaar  if exists("*SetUp")
136cc28e2d0SBram Moolenaar    try
137b5760a1cSBram Moolenaar      call SetUp()
138cc28e2d0SBram Moolenaar    catch
139cc28e2d0SBram Moolenaar      call add(v:errors, 'Caught exception in SetUp() before ' . a:test . ': ' . v:exception . ' @ ' . v:throwpoint)
140cc28e2d0SBram Moolenaar    endtry
141b5760a1cSBram Moolenaar  endif
142b5760a1cSBram Moolenaar
143f204e05aSBram Moolenaar  if a:test =~ 'Test_nocatch_'
144f204e05aSBram Moolenaar    " Function handles errors itself.  This avoids skipping commands after the
145f204e05aSBram Moolenaar    " error.
146f204e05aSBram Moolenaar    exe 'call ' . a:test
147f204e05aSBram Moolenaar  else
148b5760a1cSBram Moolenaar    try
1498903676dSBram Moolenaar      let s:test = a:test
1508903676dSBram Moolenaar      au VimLeavePre * call EarlyExit(s:test)
151b5760a1cSBram Moolenaar      exe 'call ' . a:test
1528903676dSBram Moolenaar      au! VimLeavePre
153dac1947bSBram Moolenaar    catch /^\cskipped/
154dac1947bSBram Moolenaar      call add(s:messages, '    Skipped')
155dac1947bSBram Moolenaar      call add(s:skipped, 'SKIPPED ' . a:test . ': ' . substitute(v:exception, '^\S*\s\+', '',  ''))
156b5760a1cSBram Moolenaar    catch
157b5760a1cSBram Moolenaar      call add(v:errors, 'Caught exception in ' . a:test . ': ' . v:exception . ' @ ' . v:throwpoint)
158b5760a1cSBram Moolenaar    endtry
159f204e05aSBram Moolenaar  endif
1608ad16da7SBram Moolenaar
1618ad16da7SBram Moolenaar  " In case 'insertmode' was set and something went wrong, make sure it is
1628ad16da7SBram Moolenaar  " reset to avoid trouble with anything else.
1638ad16da7SBram Moolenaar  set noinsertmode
164b5760a1cSBram Moolenaar
165b5760a1cSBram Moolenaar  if exists("*TearDown")
166cc28e2d0SBram Moolenaar    try
167b5760a1cSBram Moolenaar      call TearDown()
168cc28e2d0SBram Moolenaar    catch
169cc28e2d0SBram Moolenaar      call add(v:errors, 'Caught exception in TearDown() after ' . a:test . ': ' . v:exception . ' @ ' . v:throwpoint)
170cc28e2d0SBram Moolenaar    endtry
171b5760a1cSBram Moolenaar  endif
1727cba71d7SBram Moolenaar
173cf1ba35fSBram Moolenaar  " Clear any autocommands
174cf1ba35fSBram Moolenaar  au!
175d8f27b30SBram Moolenaar  au SwapExists * call HandleSwapExists()
176cf1ba35fSBram Moolenaar
177ae943150SBram Moolenaar  " Close any stray popup windows
178ae943150SBram Moolenaar  if has('textprop')
179ae943150SBram Moolenaar    call popup_clear()
180ae943150SBram Moolenaar  endif
181ae943150SBram Moolenaar
182ce11de87SBram Moolenaar  " Close any extra tab pages and windows and make the current one not modified.
183ce11de87SBram Moolenaar  while tabpagenr('$') > 1
184cf1ba35fSBram Moolenaar    quit!
185ce11de87SBram Moolenaar  endwhile
186ce11de87SBram Moolenaar
187358308ddSBram Moolenaar  while 1
188358308ddSBram Moolenaar    let wincount = winnr('$')
189358308ddSBram Moolenaar    if wincount == 1
190358308ddSBram Moolenaar      break
191358308ddSBram Moolenaar    endif
1927cba71d7SBram Moolenaar    bwipe!
193358308ddSBram Moolenaar    if wincount == winnr('$')
194358308ddSBram Moolenaar      " Did not manage to close a window.
195358308ddSBram Moolenaar      only!
196358308ddSBram Moolenaar      break
197358308ddSBram Moolenaar    endif
1987cba71d7SBram Moolenaar  endwhile
199209d3874SBram Moolenaar
200209d3874SBram Moolenaar  exe 'cd ' . save_cwd
201640d4f0cSBram Moolenaar
202640d4f0cSBram Moolenaar  let message = 'Executed ' . a:test
203640d4f0cSBram Moolenaar  if has('reltime')
204640d4f0cSBram Moolenaar    let message ..= ' in ' .. reltimestr(reltime(func_start)) .. ' seconds'
205640d4f0cSBram Moolenaar  endif
206640d4f0cSBram Moolenaar  call add(s:messages, message)
207640d4f0cSBram Moolenaar  let s:done += 1
208b5760a1cSBram Moolenaarendfunc
20928fb79dbSBram Moolenaar
21042205551SBram Moolenaarfunc AfterTheTest()
21143345546SBram Moolenaar  if len(v:errors) > 0
21200af60bbSBram Moolenaar    let s:fail += 1
21300af60bbSBram Moolenaar    call add(s:errors, 'Found errors in ' . s:test . ':')
21400af60bbSBram Moolenaar    call extend(s:errors, v:errors)
21543345546SBram Moolenaar    let v:errors = []
21643345546SBram Moolenaar  endif
21742205551SBram Moolenaarendfunc
21842205551SBram Moolenaar
2198903676dSBram Moolenaarfunc EarlyExit(test)
2208903676dSBram Moolenaar  " It's OK for the test we use to test the quit detection.
2218903676dSBram Moolenaar  if a:test != 'Test_zz_quit_detected()'
2228903676dSBram Moolenaar    call add(v:errors, 'Test caused Vim to exit: ' . a:test)
2238903676dSBram Moolenaar  endif
2248903676dSBram Moolenaar
2258903676dSBram Moolenaar  call FinishTesting()
2268903676dSBram Moolenaarendfunc
2278903676dSBram Moolenaar
22842205551SBram Moolenaar" This function can be called by a test if it wants to abort testing.
22942205551SBram Moolenaarfunc FinishTesting()
23042205551SBram Moolenaar  call AfterTheTest()
23143345546SBram Moolenaar
232fc4ad616SBram Moolenaar  " Don't write viminfo on exit.
233fc4ad616SBram Moolenaar  set viminfo=
234fc4ad616SBram Moolenaar
235d1ee0043SBram Moolenaar  " Clean up files created by setup.vim
236d1ee0043SBram Moolenaar  call delete('XfakeHOME', 'rf')
237d1ee0043SBram Moolenaar
23800af60bbSBram Moolenaar  if s:fail == 0
23943345546SBram Moolenaar    " Success, create the .res file so that make knows it's done.
24000af60bbSBram Moolenaar    exe 'split ' . fnamemodify(g:testname, ':r') . '.res'
24143345546SBram Moolenaar    write
24243345546SBram Moolenaar  endif
24343345546SBram Moolenaar
24400af60bbSBram Moolenaar  if len(s:errors) > 0
24543345546SBram Moolenaar    " Append errors to test.log
24643345546SBram Moolenaar    split test.log
24743345546SBram Moolenaar    call append(line('$'), '')
24800af60bbSBram Moolenaar    call append(line('$'), 'From ' . g:testname . ':')
24900af60bbSBram Moolenaar    call append(line('$'), s:errors)
25043345546SBram Moolenaar    write
25143345546SBram Moolenaar  endif
25243345546SBram Moolenaar
25329f9ed20SBram Moolenaar  if s:done == 0
25429f9ed20SBram Moolenaar    let message = 'NO tests executed'
25529f9ed20SBram Moolenaar  else
25600af60bbSBram Moolenaar    let message = 'Executed ' . s:done . (s:done > 1 ? ' tests' : ' test')
25729f9ed20SBram Moolenaar  endif
25875ee544fSBram Moolenaar  if has('reltime')
25975ee544fSBram Moolenaar    let message ..= ' in ' .. reltimestr(reltime(s:start_time)) .. ' seconds'
26075ee544fSBram Moolenaar  endif
261096c8bb4SBram Moolenaar  echo message
26200af60bbSBram Moolenaar  call add(s:messages, message)
26300af60bbSBram Moolenaar  if s:fail > 0
26400af60bbSBram Moolenaar    let message = s:fail . ' FAILED:'
265096c8bb4SBram Moolenaar    echo message
26600af60bbSBram Moolenaar    call add(s:messages, message)
26700af60bbSBram Moolenaar    call extend(s:messages, s:errors)
26843345546SBram Moolenaar  endif
26943345546SBram Moolenaar
270dac1947bSBram Moolenaar  " Add SKIPPED messages
271dac1947bSBram Moolenaar  call extend(s:messages, s:skipped)
272dac1947bSBram Moolenaar
273dac1947bSBram Moolenaar  " Append messages to the file "messages"
274096c8bb4SBram Moolenaar  split messages
275096c8bb4SBram Moolenaar  call append(line('$'), '')
27600af60bbSBram Moolenaar  call append(line('$'), 'From ' . g:testname . ':')
27700af60bbSBram Moolenaar  call append(line('$'), s:messages)
278096c8bb4SBram Moolenaar  write
279096c8bb4SBram Moolenaar
28043345546SBram Moolenaar  qall!
28142205551SBram Moolenaarendfunc
28242205551SBram Moolenaar
28342205551SBram Moolenaar" Source the test script.  First grab the file name, in case the script
28442205551SBram Moolenaar" navigates away.  g:testname can be used by the tests.
28542205551SBram Moolenaarlet g:testname = expand('%')
28642205551SBram Moolenaarlet s:done = 0
28742205551SBram Moolenaarlet s:fail = 0
28842205551SBram Moolenaarlet s:errors = []
28942205551SBram Moolenaarlet s:messages = []
29042205551SBram Moolenaarlet s:skipped = []
29142205551SBram Moolenaarif expand('%') =~ 'test_vimscript.vim'
29242205551SBram Moolenaar  " this test has intentional s:errors, don't use try/catch.
29342205551SBram Moolenaar  source %
29442205551SBram Moolenaarelse
29542205551SBram Moolenaar  try
29642205551SBram Moolenaar    source %
2979c0cec65SBram Moolenaar  catch /^\cskipped/
2989c0cec65SBram Moolenaar    call add(s:messages, '    Skipped')
2999c0cec65SBram Moolenaar    call add(s:skipped, 'SKIPPED ' . expand('%') . ': ' . substitute(v:exception, '^\S*\s\+', '',  ''))
30042205551SBram Moolenaar  catch
30142205551SBram Moolenaar    let s:fail += 1
30242205551SBram Moolenaar    call add(s:errors, 'Caught exception: ' . v:exception . ' @ ' . v:throwpoint)
30342205551SBram Moolenaar  endtry
30442205551SBram Moolenaarendif
30542205551SBram Moolenaar
30642205551SBram Moolenaar" Names of flaky tests.
307dbc0d216SBram Moolenaarlet s:flaky_tests = [
308c0f05d0bSBram Moolenaar      \ 'Test_call()',
309c0f05d0bSBram Moolenaar      \ 'Test_channel_handler()',
31042205551SBram Moolenaar      \ 'Test_client_server()',
31142205551SBram Moolenaar      \ 'Test_close_and_exit_cb()',
312c0f05d0bSBram Moolenaar      \ 'Test_close_callback()',
313c0f05d0bSBram Moolenaar      \ 'Test_close_handle()',
314c0f05d0bSBram Moolenaar      \ 'Test_close_lambda()',
315d80232beSBram Moolenaar      \ 'Test_close_output_buffer()',
316c0f05d0bSBram Moolenaar      \ 'Test_close_partial()',
31742205551SBram Moolenaar      \ 'Test_collapse_buffers()',
31842205551SBram Moolenaar      \ 'Test_communicate()',
31965873846SBram Moolenaar      \ 'Test_cwd()',
320218959bcSBram Moolenaar      \ 'Test_diff_screen()',
321c0f05d0bSBram Moolenaar      \ 'Test_exit_callback()',
32242205551SBram Moolenaar      \ 'Test_exit_callback_interval()',
32342205551SBram Moolenaar      \ 'Test_nb_basic()',
32442205551SBram Moolenaar      \ 'Test_oneshot()',
325c0f05d0bSBram Moolenaar      \ 'Test_open_delay()',
3261eca6f13SBram Moolenaar      \ 'Test_out_cb()',
32724820691SBram Moolenaar      \ 'Test_paused()',
32842205551SBram Moolenaar      \ 'Test_pipe_through_sort_all()',
32942205551SBram Moolenaar      \ 'Test_pipe_through_sort_some()',
330142ae736SBram Moolenaar      \ 'Test_popup_and_window_resize()',
33142205551SBram Moolenaar      \ 'Test_quoteplus()',
3327dd48506SBram Moolenaar      \ 'Test_quotestar()',
333c0f05d0bSBram Moolenaar      \ 'Test_raw_one_time_callback()',
33442205551SBram Moolenaar      \ 'Test_reltime()',
335bfbea567SBram Moolenaar      \ 'Test_repeat_three()',
336c0f05d0bSBram Moolenaar      \ 'Test_server_crash()',
337c0f05d0bSBram Moolenaar      \ 'Test_terminal_ansicolors_default()',
338c0f05d0bSBram Moolenaar      \ 'Test_terminal_ansicolors_func()',
339c0f05d0bSBram Moolenaar      \ 'Test_terminal_ansicolors_global()',
340f204e05aSBram Moolenaar      \ 'Test_terminal_composing_unicode()',
3413876789bSBram Moolenaar      \ 'Test_terminal_does_not_truncate_last_newlines()',
342c0f05d0bSBram Moolenaar      \ 'Test_terminal_env()',
343c0f05d0bSBram Moolenaar      \ 'Test_terminal_hide_buffer()',
344c0f05d0bSBram Moolenaar      \ 'Test_terminal_make_change()',
3453615abb6SBram Moolenaar      \ 'Test_terminal_no_cmd()',
34675a60f74SBram Moolenaar      \ 'Test_terminal_noblock()',
3477dd88c51SBram Moolenaar      \ 'Test_terminal_redir_file()',
348c0f05d0bSBram Moolenaar      \ 'Test_terminal_response_to_control_sequence()',
349c0f05d0bSBram Moolenaar      \ 'Test_terminal_scrollback()',
350c0f05d0bSBram Moolenaar      \ 'Test_terminal_split_quit()',
351c0f05d0bSBram Moolenaar      \ 'Test_terminal_termwinkey()',
352c0f05d0bSBram Moolenaar      \ 'Test_terminal_termwinsize_mininmum()',
353c0f05d0bSBram Moolenaar      \ 'Test_terminal_termwinsize_option_fixed()',
354c0f05d0bSBram Moolenaar      \ 'Test_terminal_termwinsize_option_zero()',
35524820691SBram Moolenaar      \ 'Test_terminal_tmap()',
356c0f05d0bSBram Moolenaar      \ 'Test_terminal_wall()',
357c0f05d0bSBram Moolenaar      \ 'Test_terminal_wipe_buffer()',
358c0f05d0bSBram Moolenaar      \ 'Test_terminal_wqall()',
359c0f05d0bSBram Moolenaar      \ 'Test_two_channels()',
360c0f05d0bSBram Moolenaar      \ 'Test_unlet_handle()',
361d09be321SBram Moolenaar      \ 'Test_with_partial_callback()',
362c0f05d0bSBram Moolenaar      \ 'Test_zero_reply()',
363c0f05d0bSBram Moolenaar      \ 'Test_zz1_terminal_in_gui()',
36442205551SBram Moolenaar      \ ]
36542205551SBram Moolenaar
366dbc0d216SBram Moolenaar" Pattern indicating a common flaky test failure.
367447f6ce8SBram Moolenaarlet s:flaky_errors_re = 'StopVimInTerminal\|VerifyScreenDump'
368dbc0d216SBram Moolenaar
36942205551SBram Moolenaar" Locate Test_ functions and execute them.
37042205551SBram Moolenaarredir @q
37142205551SBram Moolenaarsilent function /^Test_
37242205551SBram Moolenaarredir END
37342205551SBram Moolenaarlet s:tests = split(substitute(@q, 'function \(\k*()\)', '\1', 'g'))
37442205551SBram Moolenaar
37542205551SBram Moolenaar" If there is an extra argument filter the function names against it.
37642205551SBram Moolenaarif argc() > 1
37742205551SBram Moolenaar  let s:tests = filter(s:tests, 'v:val =~ argv(1)')
37842205551SBram Moolenaarendif
37942205551SBram Moolenaar
38042205551SBram Moolenaar" Execute the tests in alphabetical order.
38142205551SBram Moolenaarfor s:test in sort(s:tests)
3824a6fcf80SBram Moolenaar  " Silence, please!
3834a6fcf80SBram Moolenaar  set belloff=all
384f77af0e6SBram Moolenaar  let prev_error = ''
385f77af0e6SBram Moolenaar  let total_errors = []
386f77af0e6SBram Moolenaar  let run_nr = 1
3874a6fcf80SBram Moolenaar
38842205551SBram Moolenaar  call RunTheTest(s:test)
38942205551SBram Moolenaar
390f77af0e6SBram Moolenaar  " Repeat a flaky test.  Give up when:
391f77af0e6SBram Moolenaar  " - it fails again with the same message
392f77af0e6SBram Moolenaar  " - it fails five times (with a different mesage)
393dbc0d216SBram Moolenaar  if len(v:errors) > 0
394dbc0d216SBram Moolenaar        \ && (index(s:flaky_tests, s:test) >= 0
395dbc0d216SBram Moolenaar        \      || v:errors[0] =~ s:flaky_errors_re)
396f77af0e6SBram Moolenaar    while 1
3976caf606bSBram Moolenaar      call add(s:messages, 'Found errors in ' . s:test . ':')
3986caf606bSBram Moolenaar      call extend(s:messages, v:errors)
39915e737f7SBram Moolenaar
400f77af0e6SBram Moolenaar      call add(total_errors, 'Run ' . run_nr . ':')
401f77af0e6SBram Moolenaar      call extend(total_errors, v:errors)
402f77af0e6SBram Moolenaar
403f77af0e6SBram Moolenaar      if run_nr == 5 || prev_error == v:errors[0]
404f77af0e6SBram Moolenaar        call add(total_errors, 'Flaky test failed too often, giving up')
405f77af0e6SBram Moolenaar        let v:errors = total_errors
406f77af0e6SBram Moolenaar        break
407f77af0e6SBram Moolenaar      endif
408f77af0e6SBram Moolenaar
409f77af0e6SBram Moolenaar      call add(s:messages, 'Flaky test failed, running it again')
410f77af0e6SBram Moolenaar
411f77af0e6SBram Moolenaar      " Flakiness is often caused by the system being very busy.  Sleep a
412f77af0e6SBram Moolenaar      " couple of seconds to have a higher chance of succeeding the second
413f77af0e6SBram Moolenaar      " time.
41455058601SBram Moolenaar      sleep 2
41555058601SBram Moolenaar
416f77af0e6SBram Moolenaar      let prev_error = v:errors[0]
41742205551SBram Moolenaar      let v:errors = []
418f77af0e6SBram Moolenaar      let run_nr += 1
419f77af0e6SBram Moolenaar
42042205551SBram Moolenaar      call RunTheTest(s:test)
421f77af0e6SBram Moolenaar
422f77af0e6SBram Moolenaar      if len(v:errors) == 0
423f77af0e6SBram Moolenaar        " Test passed on rerun.
424f77af0e6SBram Moolenaar        break
42515e737f7SBram Moolenaar      endif
426f77af0e6SBram Moolenaar    endwhile
42742205551SBram Moolenaar  endif
42842205551SBram Moolenaar
42942205551SBram Moolenaar  call AfterTheTest()
43042205551SBram Moolenaarendfor
43142205551SBram Moolenaar
43242205551SBram Moolenaarcall FinishTesting()
433cc28e2d0SBram Moolenaar
434cc28e2d0SBram Moolenaar" vim: shiftwidth=2 sts=2 expandtab
435