blob: e22557d5a20f34fb94ab757849aecbc30d692f62 [file] [log] [blame]
Bram Moolenaar43345542015-11-29 17:35:35 +01001" This script is sourced while editing the .vim file with the tests.
2" When the script is successful the .res file will be created.
3" Errors are appended to the test.log file.
4"
Bram Moolenaarbefb3662016-02-20 14:41:40 +01005" To execute only specific test functions, add a second argument. It will be
6" matched against the names of the Test_ funtion. E.g.:
7" ../vim -u NONE -S runtest.vim test_channel.vim open_delay
8" The output can be found in the "messages" file.
9"
Bram Moolenaar43345542015-11-29 17:35:35 +010010" The test script may contain anything, only functions that start with
11" "Test_" are special. These will be invoked and should contain assert
12" functions. See test_assert.vim for an example.
13"
14" It is possible to source other files that contain "Test_" functions. This
15" can speed up testing, since Vim does not need to restart. But be careful
16" that the tests do not interfere with each other.
17"
18" If an error cannot be detected properly with an assert function add the
19" error to the v:errors list:
20" call add(v:errors, 'test foo failed: Cannot find xyz')
21"
22" If preparation for each Test_ function is needed, define a SetUp function.
23" It will be called before each Test_ function.
24"
25" If cleanup after each Test_ function is needed, define a TearDown function.
26" It will be called after each Test_ function.
Bram Moolenaar00af60b2016-02-13 14:06:14 +010027"
28" When debugging a test it can be useful to add messages to v:errors:
Bram Moolenaar8ad16da2019-01-06 15:29:57 +010029" call add(v:errors, "this happened")
Bram Moolenaar00af60b2016-02-13 14:06:14 +010030
Bram Moolenaar43345542015-11-29 17:35:35 +010031
32" Without the +eval feature we can't run these tests, bail out.
Bram Moolenaar4686b322015-12-28 14:44:10 +010033so small.vim
Bram Moolenaar43345542015-11-29 17:35:35 +010034
35" Check that the screen size is at least 24 x 80 characters.
36if &lines < 24 || &columns < 80
Bram Moolenaar0b5dc642019-08-11 22:56:15 +020037 let error = 'Screen size too small! Tests require at least 24 lines with 80 characters, got ' .. &lines .. ' lines with ' .. &columns .. ' characters'
Bram Moolenaar43345542015-11-29 17:35:35 +010038 echoerr error
39 split test.log
40 $put =error
Bram Moolenaar45aa07d2019-06-15 18:20:38 +020041 write
42 split messages
Bram Moolenaar0b5dc642019-08-11 22:56:15 +020043 call append(line('$'), '')
44 call append(line('$'), 'From ' . expand('%') . ':')
Bram Moolenaar45aa07d2019-06-15 18:20:38 +020045 call append(line('$'), error)
46 write
47 qa!
Bram Moolenaar43345542015-11-29 17:35:35 +010048endif
49
Bram Moolenaar75ee5442019-06-06 18:05:25 +020050if has('reltime')
51 let s:start_time = reltime()
52endif
53
Bram Moolenaar89b10422016-07-12 22:51:22 +020054" Common with all tests on all systems.
55source setup.vim
56
Bram Moolenaarc0662462015-12-30 15:49:05 +010057" For consistency run all tests with 'nocompatible' set.
58" This also enables use of line continuation.
59set nocp viminfo+=nviminfo
60
Bram Moolenaar30276f22019-01-24 17:59:39 +010061" Use utf-8 by default, instead of whatever the system default happens to be.
Bram Moolenaared79d1e2019-02-22 14:38:58 +010062" Individual tests can overrule this at the top of the file and use
63" g:orig_encoding if needed.
64let g:orig_encoding = &encoding
Bram Moolenaar30276f22019-01-24 17:59:39 +010065set encoding=utf-8
Bram Moolenaarac105ed2016-07-21 20:33:32 +020066
Bram Moolenaard8f27b32018-10-07 15:42:07 +020067" REDIR_TEST_TO_NULL has a very permissive SwapExists autocommand which is for
68" the test_name.vim file itself. Replace it here with a more restrictive one,
69" so we still catch mistakes.
70let s:test_script_fname = expand('%')
71au! SwapExists * call HandleSwapExists()
72func HandleSwapExists()
Bram Moolenaarb073da82019-07-13 14:47:26 +020073 " Ignore finding a swap file for the test script (the user might be
Bram Moolenaard8f27b32018-10-07 15:42:07 +020074 " editing it and do ":make test_name") and the output file.
Bram Moolenaarb073da82019-07-13 14:47:26 +020075 " Report finding another swap file and chose 'q' to avoid getting stuck.
Bram Moolenaard8f27b32018-10-07 15:42:07 +020076 if expand('<afile>') == 'messages' || expand('<afile>') =~ s:test_script_fname
77 let v:swapchoice = 'e'
Bram Moolenaarb073da82019-07-13 14:47:26 +020078 else
79 call assert_report('Unexpected swap file: ' .. v:swapname)
80 let v:swapchoice = 'q'
Bram Moolenaard8f27b32018-10-07 15:42:07 +020081 endif
82endfunc
83
Bram Moolenaar7a073542017-02-01 23:17:36 +010084" Avoid stopping at the "hit enter" prompt
85set nomore
86
Bram Moolenaarc0662462015-12-30 15:49:05 +010087" Output all messages in English.
88lang mess C
89
Bram Moolenaarf60b7962016-01-16 22:47:23 +010090" Always use forward slashes.
91set shellslash
92
Bram Moolenaar28fb79d2016-01-09 22:28:33 +010093let s:srcdir = expand('%:p:h:h')
94
Bram Moolenaar8e8df252016-05-25 21:23:21 +020095" Prepare for calling test_garbagecollect_now().
Bram Moolenaarebf7dfa2016-04-14 12:46:51 +020096let v:testing = 1
97
Bram Moolenaar28fb79d2016-01-09 22:28:33 +010098" Support function: get the alloc ID by name.
99function GetAllocId(name)
100 exe 'split ' . s:srcdir . '/alloc.h'
Bram Moolenaar065ee9a2016-01-15 20:53:38 +0100101 let top = search('typedef enum')
102 if top == 0
103 call add(v:errors, 'typedef not found in alloc.h')
104 endif
Bram Moolenaar28fb79d2016-01-09 22:28:33 +0100105 let lnum = search('aid_' . a:name . ',')
106 if lnum == 0
107 call add(v:errors, 'Alloc ID ' . a:name . ' not defined')
108 endif
109 close
Bram Moolenaar065ee9a2016-01-15 20:53:38 +0100110 return lnum - top - 1
Bram Moolenaar28fb79d2016-01-09 22:28:33 +0100111endfunc
112
Bram Moolenaar42205552017-03-18 19:42:22 +0100113func RunTheTest(test)
Bram Moolenaarb5760a12016-03-03 13:10:44 +0100114 echo 'Executing ' . a:test
Bram Moolenaar75ee5442019-06-06 18:05:25 +0200115 if has('reltime')
116 let func_start = reltime()
117 endif
Bram Moolenaare5f2a072017-02-01 22:31:49 +0100118
119 " Avoid stopping at the "hit enter" prompt
120 set nomore
121
122 " Avoid a three second wait when a message is about to be overwritten by the
123 " mode message.
124 set noshowmode
125
Bram Moolenaareb992cb2017-03-09 18:20:16 +0100126 " Clear any overrides.
127 call test_override('ALL', 0)
128
Bram Moolenaarcf1ba352017-10-27 00:55:04 +0200129 " Some tests wipe out buffers. To be consistent, always wipe out all
130 " buffers.
131 %bwipe!
132
Bram Moolenaar209d3872017-11-16 21:52:51 +0100133 " The test may change the current directory. Save and restore the
134 " directory after executing the test.
135 let save_cwd = getcwd()
136
Bram Moolenaarb5760a12016-03-03 13:10:44 +0100137 if exists("*SetUp")
Bram Moolenaarcc28e2d2016-11-17 17:56:13 +0100138 try
139 call SetUp()
140 catch
141 call add(v:errors, 'Caught exception in SetUp() before ' . a:test . ': ' . v:exception . ' @ ' . v:throwpoint)
142 endtry
Bram Moolenaarb5760a12016-03-03 13:10:44 +0100143 endif
144
Bram Moolenaarf204e052017-10-26 17:14:01 +0200145 if a:test =~ 'Test_nocatch_'
146 " Function handles errors itself. This avoids skipping commands after the
147 " error.
Bram Moolenaarb5760a12016-03-03 13:10:44 +0100148 exe 'call ' . a:test
Bram Moolenaarf204e052017-10-26 17:14:01 +0200149 else
150 try
Bram Moolenaar89036762018-06-12 14:58:39 +0200151 let s:test = a:test
152 au VimLeavePre * call EarlyExit(s:test)
Bram Moolenaarf204e052017-10-26 17:14:01 +0200153 exe 'call ' . a:test
Bram Moolenaar89036762018-06-12 14:58:39 +0200154 au! VimLeavePre
Bram Moolenaarf204e052017-10-26 17:14:01 +0200155 catch /^\cskipped/
156 call add(s:messages, ' Skipped')
157 call add(s:skipped, 'SKIPPED ' . a:test . ': ' . substitute(v:exception, '^\S*\s\+', '', ''))
158 catch
159 call add(v:errors, 'Caught exception in ' . a:test . ': ' . v:exception . ' @ ' . v:throwpoint)
160 endtry
161 endif
Bram Moolenaarb5760a12016-03-03 13:10:44 +0100162
Bram Moolenaar8ad16da2019-01-06 15:29:57 +0100163 " In case 'insertmode' was set and something went wrong, make sure it is
164 " reset to avoid trouble with anything else.
165 set noinsertmode
166
Bram Moolenaarb5760a12016-03-03 13:10:44 +0100167 if exists("*TearDown")
Bram Moolenaarcc28e2d2016-11-17 17:56:13 +0100168 try
169 call TearDown()
170 catch
171 call add(v:errors, 'Caught exception in TearDown() after ' . a:test . ': ' . v:exception . ' @ ' . v:throwpoint)
172 endtry
Bram Moolenaarb5760a12016-03-03 13:10:44 +0100173 endif
Bram Moolenaar7cba71d2016-08-02 23:04:49 +0200174
Bram Moolenaar0b5dc642019-08-11 22:56:15 +0200175 " Clear any autocommands and put back the catch-all for SwapExists.
Bram Moolenaarcf1ba352017-10-27 00:55:04 +0200176 au!
Bram Moolenaard8f27b32018-10-07 15:42:07 +0200177 au SwapExists * call HandleSwapExists()
Bram Moolenaarcf1ba352017-10-27 00:55:04 +0200178
Bram Moolenaarae943152019-06-16 22:54:14 +0200179 " Close any stray popup windows
180 if has('textprop')
181 call popup_clear()
182 endif
183
Bram Moolenaarce11de82017-10-26 22:00:00 +0200184 " Close any extra tab pages and windows and make the current one not modified.
185 while tabpagenr('$') > 1
Bram Moolenaarcf1ba352017-10-27 00:55:04 +0200186 quit!
Bram Moolenaarce11de82017-10-26 22:00:00 +0200187 endwhile
188
Bram Moolenaar358308d2016-08-24 21:21:26 +0200189 while 1
190 let wincount = winnr('$')
191 if wincount == 1
192 break
193 endif
Bram Moolenaar7cba71d2016-08-02 23:04:49 +0200194 bwipe!
Bram Moolenaar358308d2016-08-24 21:21:26 +0200195 if wincount == winnr('$')
196 " Did not manage to close a window.
197 only!
198 break
199 endif
Bram Moolenaar7cba71d2016-08-02 23:04:49 +0200200 endwhile
Bram Moolenaar209d3872017-11-16 21:52:51 +0100201
202 exe 'cd ' . save_cwd
Bram Moolenaar640d4f02019-06-10 17:43:46 +0200203
204 let message = 'Executed ' . a:test
205 if has('reltime')
206 let message ..= ' in ' .. reltimestr(reltime(func_start)) .. ' seconds'
207 endif
208 call add(s:messages, message)
209 let s:done += 1
Bram Moolenaarb5760a12016-03-03 13:10:44 +0100210endfunc
Bram Moolenaar28fb79d2016-01-09 22:28:33 +0100211
Bram Moolenaar42205552017-03-18 19:42:22 +0100212func AfterTheTest()
213 if len(v:errors) > 0
214 let s:fail += 1
215 call add(s:errors, 'Found errors in ' . s:test . ':')
216 call extend(s:errors, v:errors)
217 let v:errors = []
218 endif
219endfunc
220
Bram Moolenaar89036762018-06-12 14:58:39 +0200221func EarlyExit(test)
222 " It's OK for the test we use to test the quit detection.
223 if a:test != 'Test_zz_quit_detected()'
224 call add(v:errors, 'Test caused Vim to exit: ' . a:test)
225 endif
226
227 call FinishTesting()
228endfunc
229
Bram Moolenaar42205552017-03-18 19:42:22 +0100230" This function can be called by a test if it wants to abort testing.
231func FinishTesting()
232 call AfterTheTest()
233
234 " Don't write viminfo on exit.
235 set viminfo=
236
Bram Moolenaard1ee0042017-07-29 20:39:53 +0200237 " Clean up files created by setup.vim
238 call delete('XfakeHOME', 'rf')
239
Bram Moolenaar42205552017-03-18 19:42:22 +0100240 if s:fail == 0
241 " Success, create the .res file so that make knows it's done.
242 exe 'split ' . fnamemodify(g:testname, ':r') . '.res'
243 write
244 endif
245
246 if len(s:errors) > 0
247 " Append errors to test.log
248 split test.log
249 call append(line('$'), '')
250 call append(line('$'), 'From ' . g:testname . ':')
251 call append(line('$'), s:errors)
252 write
253 endif
254
Bram Moolenaar29f9ed22018-04-10 19:20:31 +0200255 if s:done == 0
Bram Moolenaar7b666c72019-09-27 21:25:00 +0200256 if s:filtered > 0
257 let message = "NO tests match $TEST_FILTER: '" .. $TEST_FILTER .. "'"
258 else
259 let message = 'NO tests executed'
260 endif
Bram Moolenaar29f9ed22018-04-10 19:20:31 +0200261 else
Bram Moolenaar7b666c72019-09-27 21:25:00 +0200262 if s:filtered > 0
263 call add(s:messages, "Filtered " .. s:filtered .. " tests with $TEST_FILTER")
264 endif
Bram Moolenaar29f9ed22018-04-10 19:20:31 +0200265 let message = 'Executed ' . s:done . (s:done > 1 ? ' tests' : ' test')
266 endif
Bram Moolenaar7b666c72019-09-27 21:25:00 +0200267 if s:done > 0 && has('reltime')
Bram Moolenaar75ee5442019-06-06 18:05:25 +0200268 let message ..= ' in ' .. reltimestr(reltime(s:start_time)) .. ' seconds'
269 endif
Bram Moolenaar42205552017-03-18 19:42:22 +0100270 echo message
271 call add(s:messages, message)
272 if s:fail > 0
273 let message = s:fail . ' FAILED:'
274 echo message
275 call add(s:messages, message)
276 call extend(s:messages, s:errors)
277 endif
278
279 " Add SKIPPED messages
280 call extend(s:messages, s:skipped)
281
282 " Append messages to the file "messages"
283 split messages
284 call append(line('$'), '')
285 call append(line('$'), 'From ' . g:testname . ':')
286 call append(line('$'), s:messages)
287 write
288
289 qall!
290endfunc
291
Bram Moolenaar43345542015-11-29 17:35:35 +0100292" Source the test script. First grab the file name, in case the script
Bram Moolenaar00af60b2016-02-13 14:06:14 +0100293" navigates away. g:testname can be used by the tests.
294let g:testname = expand('%')
295let s:done = 0
296let s:fail = 0
297let s:errors = []
298let s:messages = []
Bram Moolenaardac19472016-09-03 22:35:40 +0200299let s:skipped = []
Bram Moolenaarb544f3c2017-02-23 19:03:28 +0100300if expand('%') =~ 'test_vimscript.vim'
Bram Moolenaar00af60b2016-02-13 14:06:14 +0100301 " this test has intentional s:errors, don't use try/catch.
Bram Moolenaar4686b322015-12-28 14:44:10 +0100302 source %
Bram Moolenaara2cce862016-01-02 19:50:04 +0100303else
304 try
305 source %
Bram Moolenaar9c0cec62019-06-06 13:38:15 +0200306 catch /^\cskipped/
307 call add(s:messages, ' Skipped')
308 call add(s:skipped, 'SKIPPED ' . expand('%') . ': ' . substitute(v:exception, '^\S*\s\+', '', ''))
Bram Moolenaara2cce862016-01-02 19:50:04 +0100309 catch
Bram Moolenaar00af60b2016-02-13 14:06:14 +0100310 let s:fail += 1
311 call add(s:errors, 'Caught exception: ' . v:exception . ' @ ' . v:throwpoint)
Bram Moolenaara2cce862016-01-02 19:50:04 +0100312 endtry
313endif
Bram Moolenaar43345542015-11-29 17:35:35 +0100314
Bram Moolenaarb5760a12016-03-03 13:10:44 +0100315" Names of flaky tests.
Bram Moolenaardbc0d212018-11-16 18:22:45 +0100316let s:flaky_tests = [
Bram Moolenaar0d0c3ca2019-09-25 21:16:15 +0200317 \ 'Test_autocmd_SafeState()',
Bram Moolenaarc0f05d02018-11-16 17:44:48 +0100318 \ 'Test_call()',
319 \ 'Test_channel_handler()',
Bram Moolenaar42205552017-03-18 19:42:22 +0100320 \ 'Test_client_server()',
Bram Moolenaar6fe2eb42017-01-29 21:49:51 +0100321 \ 'Test_close_and_exit_cb()',
Bram Moolenaarc0f05d02018-11-16 17:44:48 +0100322 \ 'Test_close_callback()',
323 \ 'Test_close_handle()',
324 \ 'Test_close_lambda()',
Bram Moolenaard80232b2018-12-15 17:46:23 +0100325 \ 'Test_close_output_buffer()',
Bram Moolenaarc0f05d02018-11-16 17:44:48 +0100326 \ 'Test_close_partial()',
Bram Moolenaarb2455592017-02-01 18:00:13 +0100327 \ 'Test_collapse_buffers()',
328 \ 'Test_communicate()',
Bram Moolenaar65873842018-03-25 17:12:58 +0200329 \ 'Test_cwd()',
Bram Moolenaar218959b2018-11-11 18:51:42 +0100330 \ 'Test_diff_screen()',
Bram Moolenaarc0f05d02018-11-16 17:44:48 +0100331 \ 'Test_exit_callback()',
Bram Moolenaar0529b3e2017-03-16 22:30:37 +0100332 \ 'Test_exit_callback_interval()',
Bram Moolenaarea94c852019-08-16 21:47:27 +0200333 \ 'Test_map_timeout_with_timer_interrupt()',
Bram Moolenaarb2455592017-02-01 18:00:13 +0100334 \ 'Test_nb_basic()',
Bram Moolenaarc0f05d02018-11-16 17:44:48 +0100335 \ 'Test_open_delay()',
Bram Moolenaar1eca6f12017-12-05 14:04:27 +0100336 \ 'Test_out_cb()',
Bram Moolenaarc79d6aa2016-09-25 22:27:37 +0200337 \ 'Test_pipe_through_sort_all()',
Bram Moolenaar4e032e12017-02-01 20:48:13 +0100338 \ 'Test_pipe_through_sort_some()',
Bram Moolenaar0fbff642017-03-05 14:30:52 +0100339 \ 'Test_quoteplus()',
Bram Moolenaar7dd48502017-03-19 20:04:22 +0100340 \ 'Test_quotestar()',
Bram Moolenaarc0f05d02018-11-16 17:44:48 +0100341 \ 'Test_raw_one_time_callback()',
Bram Moolenaarb2455592017-02-01 18:00:13 +0100342 \ 'Test_reltime()',
Bram Moolenaar4e039332019-10-16 21:13:35 +0200343 \ 'Test_popup_and_window_resize()',
Bram Moolenaarc0f05d02018-11-16 17:44:48 +0100344 \ 'Test_server_crash()',
Bram Moolenaar3c8cd4a2019-10-14 22:26:20 +0200345 \ 'Test_state()',
Bram Moolenaar705918f2019-09-17 21:27:49 +0200346 \ 'Test_term_mouse_double_click_to_create_tab()',
Bram Moolenaarc0f05d02018-11-16 17:44:48 +0100347 \ 'Test_terminal_ansicolors_default()',
348 \ 'Test_terminal_ansicolors_func()',
349 \ 'Test_terminal_ansicolors_global()',
Bram Moolenaarf204e052017-10-26 17:14:01 +0200350 \ 'Test_terminal_composing_unicode()',
Bram Moolenaar38767892019-02-21 18:17:14 +0100351 \ 'Test_terminal_does_not_truncate_last_newlines()',
Bram Moolenaarc0f05d02018-11-16 17:44:48 +0100352 \ 'Test_terminal_env()',
353 \ 'Test_terminal_hide_buffer()',
354 \ 'Test_terminal_make_change()',
Bram Moolenaar3615abb2019-02-10 23:04:12 +0100355 \ 'Test_terminal_no_cmd()',
Bram Moolenaar75a60f72017-09-07 22:24:41 +0200356 \ 'Test_terminal_noblock()',
Bram Moolenaar7dd88c52017-11-04 20:46:40 +0100357 \ 'Test_terminal_redir_file()',
Bram Moolenaarc0f05d02018-11-16 17:44:48 +0100358 \ 'Test_terminal_response_to_control_sequence()',
359 \ 'Test_terminal_scrollback()',
360 \ 'Test_terminal_split_quit()',
361 \ 'Test_terminal_termwinkey()',
Bram Moolenaar1bc353b2019-09-01 14:45:28 +0200362 \ 'Test_terminal_termwinsize_minimum()',
Bram Moolenaarc0f05d02018-11-16 17:44:48 +0100363 \ 'Test_terminal_termwinsize_option_fixed()',
364 \ 'Test_terminal_termwinsize_option_zero()',
Bram Moolenaar24820692017-12-02 16:38:12 +0100365 \ 'Test_terminal_tmap()',
Bram Moolenaarc0f05d02018-11-16 17:44:48 +0100366 \ 'Test_terminal_wall()',
367 \ 'Test_terminal_wipe_buffer()',
368 \ 'Test_terminal_wqall()',
Bram Moolenaar9a2fddc2019-08-16 11:26:06 +0200369 \ 'Test_timer_oneshot()',
370 \ 'Test_timer_paused()',
371 \ 'Test_timer_repeat_many()',
372 \ 'Test_timer_repeat_three()',
373 \ 'Test_timer_stop_all_in_callback()',
374 \ 'Test_timer_stop_in_callback()',
Bram Moolenaarc0f05d02018-11-16 17:44:48 +0100375 \ 'Test_two_channels()',
376 \ 'Test_unlet_handle()',
Bram Moolenaar9a2fddc2019-08-16 11:26:06 +0200377 \ 'Test_timer_with_partial_callback()',
Bram Moolenaarc0f05d02018-11-16 17:44:48 +0100378 \ 'Test_zero_reply()',
379 \ 'Test_zz1_terminal_in_gui()',
Bram Moolenaare1c8c7a2016-09-11 16:48:50 +0200380 \ ]
Bram Moolenaarb5760a12016-03-03 13:10:44 +0100381
Bram Moolenaardbc0d212018-11-16 18:22:45 +0100382" Pattern indicating a common flaky test failure.
Bram Moolenaar447f6ce2018-11-16 18:50:19 +0100383let s:flaky_errors_re = 'StopVimInTerminal\|VerifyScreenDump'
Bram Moolenaardbc0d212018-11-16 18:22:45 +0100384
Bram Moolenaar43345542015-11-29 17:35:35 +0100385" Locate Test_ functions and execute them.
386redir @q
Bram Moolenaar93bf5582016-02-18 22:25:47 +0100387silent function /^Test_
Bram Moolenaar43345542015-11-29 17:35:35 +0100388redir END
Bram Moolenaar00af60b2016-02-13 14:06:14 +0100389let s:tests = split(substitute(@q, 'function \(\k*()\)', '\1', 'g'))
Bram Moolenaar43345542015-11-29 17:35:35 +0100390
Bram Moolenaarbefb3662016-02-20 14:41:40 +0100391" If there is an extra argument filter the function names against it.
392if argc() > 1
393 let s:tests = filter(s:tests, 'v:val =~ argv(1)')
394endif
395
Bram Moolenaara7f6c3c2019-09-27 15:34:16 +0200396" If the environment variable $TEST_FILTER is set then filter the function
397" names against it.
Bram Moolenaar7b666c72019-09-27 21:25:00 +0200398let s:filtered = 0
Bram Moolenaara7f6c3c2019-09-27 15:34:16 +0200399if $TEST_FILTER != ''
Bram Moolenaar7b666c72019-09-27 21:25:00 +0200400 let s:filtered = len(s:tests)
Bram Moolenaara7f6c3c2019-09-27 15:34:16 +0200401 let s:tests = filter(s:tests, 'v:val =~ $TEST_FILTER')
Bram Moolenaar7b666c72019-09-27 21:25:00 +0200402 let s:filtered -= len(s:tests)
Bram Moolenaara7f6c3c2019-09-27 15:34:16 +0200403endif
404
Bram Moolenaarcfc0a352016-01-09 20:23:00 +0100405" Execute the tests in alphabetical order.
Bram Moolenaar93bf5582016-02-18 22:25:47 +0100406for s:test in sort(s:tests)
Bram Moolenaar4a6fcf82017-10-12 21:29:22 +0200407 " Silence, please!
408 set belloff=all
Bram Moolenaarf77af0e2018-11-16 16:52:16 +0100409 let prev_error = ''
410 let total_errors = []
411 let run_nr = 1
Bram Moolenaar4a6fcf82017-10-12 21:29:22 +0200412
Bram Moolenaarb5760a12016-03-03 13:10:44 +0100413 call RunTheTest(s:test)
Bram Moolenaar43345542015-11-29 17:35:35 +0100414
Bram Moolenaarf77af0e2018-11-16 16:52:16 +0100415 " Repeat a flaky test. Give up when:
416 " - it fails again with the same message
Bram Moolenaar1bc353b2019-09-01 14:45:28 +0200417 " - it fails five times (with a different message)
Bram Moolenaardbc0d212018-11-16 18:22:45 +0100418 if len(v:errors) > 0
419 \ && (index(s:flaky_tests, s:test) >= 0
420 \ || v:errors[0] =~ s:flaky_errors_re)
Bram Moolenaarf77af0e2018-11-16 16:52:16 +0100421 while 1
422 call add(s:messages, 'Found errors in ' . s:test . ':')
423 call extend(s:messages, v:errors)
Bram Moolenaar15e737f2017-03-18 21:22:47 +0100424
Bram Moolenaarf77af0e2018-11-16 16:52:16 +0100425 call add(total_errors, 'Run ' . run_nr . ':')
426 call extend(total_errors, v:errors)
Bram Moolenaar55058602017-11-21 15:14:51 +0100427
Bram Moolenaarf77af0e2018-11-16 16:52:16 +0100428 if run_nr == 5 || prev_error == v:errors[0]
429 call add(total_errors, 'Flaky test failed too often, giving up')
430 let v:errors = total_errors
431 break
432 endif
433
434 call add(s:messages, 'Flaky test failed, running it again')
435
436 " Flakiness is often caused by the system being very busy. Sleep a
437 " couple of seconds to have a higher chance of succeeding the second
438 " time.
439 sleep 2
440
441 let prev_error = v:errors[0]
442 let v:errors = []
443 let run_nr += 1
444
445 call RunTheTest(s:test)
446
447 if len(v:errors) == 0
448 " Test passed on rerun.
449 break
450 endif
451 endwhile
Bram Moolenaarb5760a12016-03-03 13:10:44 +0100452 endif
Bram Moolenaar43345542015-11-29 17:35:35 +0100453
Bram Moolenaar42205552017-03-18 19:42:22 +0100454 call AfterTheTest()
Bram Moolenaar43345542015-11-29 17:35:35 +0100455endfor
456
Bram Moolenaar42205552017-03-18 19:42:22 +0100457call FinishTesting()
Bram Moolenaarcc28e2d2016-11-17 17:56:13 +0100458
459" vim: shiftwidth=2 sts=2 expandtab