blob: c3414914f835ca3f615f87157251c83410047ab8 [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:
29" call add(v:errors, "this happened")
30
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
37 let error = 'Screen size too small! Tests require at least 24 lines with 80 characters'
38 echoerr error
39 split test.log
40 $put =error
41 w
42 cquit
43endif
44
Bram Moolenaar89b10422016-07-12 22:51:22 +020045" Common with all tests on all systems.
46source setup.vim
47
Bram Moolenaarc0662462015-12-30 15:49:05 +010048" For consistency run all tests with 'nocompatible' set.
49" This also enables use of line continuation.
50set nocp viminfo+=nviminfo
51
Bram Moolenaareb992cb2017-03-09 18:20:16 +010052" Use utf-8 or latin1 by default, instead of whatever the system default
Bram Moolenaarac105ed2016-07-21 20:33:32 +020053" happens to be. Individual tests can overrule this at the top of the file.
54if has('multi_byte')
55 set encoding=utf-8
56else
57 set encoding=latin1
58endif
59
Bram Moolenaar7a073542017-02-01 23:17:36 +010060" Avoid stopping at the "hit enter" prompt
61set nomore
62
Bram Moolenaarc0662462015-12-30 15:49:05 +010063" Output all messages in English.
64lang mess C
65
Bram Moolenaarf60b7962016-01-16 22:47:23 +010066" Always use forward slashes.
67set shellslash
68
Bram Moolenaar28fb79d2016-01-09 22:28:33 +010069let s:srcdir = expand('%:p:h:h')
70
Bram Moolenaar8e8df252016-05-25 21:23:21 +020071" Prepare for calling test_garbagecollect_now().
Bram Moolenaarebf7dfa2016-04-14 12:46:51 +020072let v:testing = 1
73
Bram Moolenaar28fb79d2016-01-09 22:28:33 +010074" Support function: get the alloc ID by name.
75function GetAllocId(name)
76 exe 'split ' . s:srcdir . '/alloc.h'
Bram Moolenaar065ee9a2016-01-15 20:53:38 +010077 let top = search('typedef enum')
78 if top == 0
79 call add(v:errors, 'typedef not found in alloc.h')
80 endif
Bram Moolenaar28fb79d2016-01-09 22:28:33 +010081 let lnum = search('aid_' . a:name . ',')
82 if lnum == 0
83 call add(v:errors, 'Alloc ID ' . a:name . ' not defined')
84 endif
85 close
Bram Moolenaar065ee9a2016-01-15 20:53:38 +010086 return lnum - top - 1
Bram Moolenaar28fb79d2016-01-09 22:28:33 +010087endfunc
88
Bram Moolenaar42205552017-03-18 19:42:22 +010089func RunTheTest(test)
Bram Moolenaarb5760a12016-03-03 13:10:44 +010090 echo 'Executing ' . a:test
Bram Moolenaare5f2a072017-02-01 22:31:49 +010091
92 " Avoid stopping at the "hit enter" prompt
93 set nomore
94
95 " Avoid a three second wait when a message is about to be overwritten by the
96 " mode message.
97 set noshowmode
98
Bram Moolenaareb992cb2017-03-09 18:20:16 +010099 " Clear any overrides.
100 call test_override('ALL', 0)
101
Bram Moolenaarcf1ba352017-10-27 00:55:04 +0200102 " Some tests wipe out buffers. To be consistent, always wipe out all
103 " buffers.
104 %bwipe!
105
Bram Moolenaar209d3872017-11-16 21:52:51 +0100106 " The test may change the current directory. Save and restore the
107 " directory after executing the test.
108 let save_cwd = getcwd()
109
Bram Moolenaarb5760a12016-03-03 13:10:44 +0100110 if exists("*SetUp")
Bram Moolenaarcc28e2d2016-11-17 17:56:13 +0100111 try
112 call SetUp()
113 catch
114 call add(v:errors, 'Caught exception in SetUp() before ' . a:test . ': ' . v:exception . ' @ ' . v:throwpoint)
115 endtry
Bram Moolenaarb5760a12016-03-03 13:10:44 +0100116 endif
117
118 call add(s:messages, 'Executing ' . a:test)
119 let s:done += 1
Bram Moolenaarf204e052017-10-26 17:14:01 +0200120
121 if a:test =~ 'Test_nocatch_'
122 " Function handles errors itself. This avoids skipping commands after the
123 " error.
Bram Moolenaarb5760a12016-03-03 13:10:44 +0100124 exe 'call ' . a:test
Bram Moolenaarf204e052017-10-26 17:14:01 +0200125 else
126 try
Bram Moolenaar89036762018-06-12 14:58:39 +0200127 let s:test = a:test
128 au VimLeavePre * call EarlyExit(s:test)
Bram Moolenaarf204e052017-10-26 17:14:01 +0200129 exe 'call ' . a:test
Bram Moolenaar89036762018-06-12 14:58:39 +0200130 au! VimLeavePre
Bram Moolenaarf204e052017-10-26 17:14:01 +0200131 catch /^\cskipped/
132 call add(s:messages, ' Skipped')
133 call add(s:skipped, 'SKIPPED ' . a:test . ': ' . substitute(v:exception, '^\S*\s\+', '', ''))
134 catch
135 call add(v:errors, 'Caught exception in ' . a:test . ': ' . v:exception . ' @ ' . v:throwpoint)
136 endtry
137 endif
Bram Moolenaarb5760a12016-03-03 13:10:44 +0100138
139 if exists("*TearDown")
Bram Moolenaarcc28e2d2016-11-17 17:56:13 +0100140 try
141 call TearDown()
142 catch
143 call add(v:errors, 'Caught exception in TearDown() after ' . a:test . ': ' . v:exception . ' @ ' . v:throwpoint)
144 endtry
Bram Moolenaarb5760a12016-03-03 13:10:44 +0100145 endif
Bram Moolenaar7cba71d2016-08-02 23:04:49 +0200146
Bram Moolenaarcf1ba352017-10-27 00:55:04 +0200147 " Clear any autocommands
148 au!
149
Bram Moolenaarce11de82017-10-26 22:00:00 +0200150 " Close any extra tab pages and windows and make the current one not modified.
151 while tabpagenr('$') > 1
Bram Moolenaarcf1ba352017-10-27 00:55:04 +0200152 quit!
Bram Moolenaarce11de82017-10-26 22:00:00 +0200153 endwhile
154
Bram Moolenaar358308d2016-08-24 21:21:26 +0200155 while 1
156 let wincount = winnr('$')
157 if wincount == 1
158 break
159 endif
Bram Moolenaar7cba71d2016-08-02 23:04:49 +0200160 bwipe!
Bram Moolenaar358308d2016-08-24 21:21:26 +0200161 if wincount == winnr('$')
162 " Did not manage to close a window.
163 only!
164 break
165 endif
Bram Moolenaar7cba71d2016-08-02 23:04:49 +0200166 endwhile
Bram Moolenaar209d3872017-11-16 21:52:51 +0100167
168 exe 'cd ' . save_cwd
Bram Moolenaarb5760a12016-03-03 13:10:44 +0100169endfunc
Bram Moolenaar28fb79d2016-01-09 22:28:33 +0100170
Bram Moolenaar42205552017-03-18 19:42:22 +0100171func AfterTheTest()
172 if len(v:errors) > 0
173 let s:fail += 1
174 call add(s:errors, 'Found errors in ' . s:test . ':')
175 call extend(s:errors, v:errors)
176 let v:errors = []
177 endif
178endfunc
179
Bram Moolenaar89036762018-06-12 14:58:39 +0200180func EarlyExit(test)
181 " It's OK for the test we use to test the quit detection.
182 if a:test != 'Test_zz_quit_detected()'
183 call add(v:errors, 'Test caused Vim to exit: ' . a:test)
184 endif
185
186 call FinishTesting()
187endfunc
188
Bram Moolenaar42205552017-03-18 19:42:22 +0100189" This function can be called by a test if it wants to abort testing.
190func FinishTesting()
191 call AfterTheTest()
192
193 " Don't write viminfo on exit.
194 set viminfo=
195
Bram Moolenaard1ee0042017-07-29 20:39:53 +0200196 " Clean up files created by setup.vim
197 call delete('XfakeHOME', 'rf')
198
Bram Moolenaar42205552017-03-18 19:42:22 +0100199 if s:fail == 0
200 " Success, create the .res file so that make knows it's done.
201 exe 'split ' . fnamemodify(g:testname, ':r') . '.res'
202 write
203 endif
204
205 if len(s:errors) > 0
206 " Append errors to test.log
207 split test.log
208 call append(line('$'), '')
209 call append(line('$'), 'From ' . g:testname . ':')
210 call append(line('$'), s:errors)
211 write
212 endif
213
Bram Moolenaar29f9ed22018-04-10 19:20:31 +0200214 if s:done == 0
215 let message = 'NO tests executed'
216 else
217 let message = 'Executed ' . s:done . (s:done > 1 ? ' tests' : ' test')
218 endif
Bram Moolenaar42205552017-03-18 19:42:22 +0100219 echo message
220 call add(s:messages, message)
221 if s:fail > 0
222 let message = s:fail . ' FAILED:'
223 echo message
224 call add(s:messages, message)
225 call extend(s:messages, s:errors)
226 endif
227
228 " Add SKIPPED messages
229 call extend(s:messages, s:skipped)
230
231 " Append messages to the file "messages"
232 split messages
233 call append(line('$'), '')
234 call append(line('$'), 'From ' . g:testname . ':')
235 call append(line('$'), s:messages)
236 write
237
238 qall!
239endfunc
240
Bram Moolenaar43345542015-11-29 17:35:35 +0100241" Source the test script. First grab the file name, in case the script
Bram Moolenaar00af60b2016-02-13 14:06:14 +0100242" navigates away. g:testname can be used by the tests.
243let g:testname = expand('%')
244let s:done = 0
245let s:fail = 0
246let s:errors = []
247let s:messages = []
Bram Moolenaardac19472016-09-03 22:35:40 +0200248let s:skipped = []
Bram Moolenaarb544f3c2017-02-23 19:03:28 +0100249if expand('%') =~ 'test_vimscript.vim'
Bram Moolenaar00af60b2016-02-13 14:06:14 +0100250 " this test has intentional s:errors, don't use try/catch.
Bram Moolenaar4686b322015-12-28 14:44:10 +0100251 source %
Bram Moolenaara2cce862016-01-02 19:50:04 +0100252else
253 try
254 source %
255 catch
Bram Moolenaar00af60b2016-02-13 14:06:14 +0100256 let s:fail += 1
257 call add(s:errors, 'Caught exception: ' . v:exception . ' @ ' . v:throwpoint)
Bram Moolenaara2cce862016-01-02 19:50:04 +0100258 endtry
259endif
Bram Moolenaar43345542015-11-29 17:35:35 +0100260
Bram Moolenaarb5760a12016-03-03 13:10:44 +0100261" Names of flaky tests.
Bram Moolenaare1c8c7a2016-09-11 16:48:50 +0200262let s:flaky = [
Bram Moolenaar42205552017-03-18 19:42:22 +0100263 \ 'Test_client_server()',
Bram Moolenaar6fe2eb42017-01-29 21:49:51 +0100264 \ 'Test_close_and_exit_cb()',
Bram Moolenaarb2455592017-02-01 18:00:13 +0100265 \ 'Test_collapse_buffers()',
266 \ 'Test_communicate()',
Bram Moolenaar65873842018-03-25 17:12:58 +0200267 \ 'Test_cwd()',
Bram Moolenaar0529b3e2017-03-16 22:30:37 +0100268 \ 'Test_exit_callback_interval()',
Bram Moolenaarb2455592017-02-01 18:00:13 +0100269 \ 'Test_nb_basic()',
Bram Moolenaard512e172017-02-27 21:35:53 +0100270 \ 'Test_oneshot()',
Bram Moolenaar1eca6f12017-12-05 14:04:27 +0100271 \ 'Test_out_cb()',
Bram Moolenaar24820692017-12-02 16:38:12 +0100272 \ 'Test_paused()',
Bram Moolenaarc79d6aa2016-09-25 22:27:37 +0200273 \ 'Test_pipe_through_sort_all()',
Bram Moolenaar4e032e12017-02-01 20:48:13 +0100274 \ 'Test_pipe_through_sort_some()',
Bram Moolenaar142ae732018-08-19 17:04:01 +0200275 \ 'Test_popup_and_window_resize()',
Bram Moolenaar0fbff642017-03-05 14:30:52 +0100276 \ 'Test_quoteplus()',
Bram Moolenaar7dd48502017-03-19 20:04:22 +0100277 \ 'Test_quotestar()',
Bram Moolenaarb2455592017-02-01 18:00:13 +0100278 \ 'Test_reltime()',
Bram Moolenaarbfbea562018-02-12 21:31:35 +0100279 \ 'Test_repeat_three()',
Bram Moolenaarf204e052017-10-26 17:14:01 +0200280 \ 'Test_terminal_composing_unicode()',
Bram Moolenaar75a60f72017-09-07 22:24:41 +0200281 \ 'Test_terminal_noblock()',
Bram Moolenaar7dd88c52017-11-04 20:46:40 +0100282 \ 'Test_terminal_redir_file()',
Bram Moolenaar24820692017-12-02 16:38:12 +0100283 \ 'Test_terminal_tmap()',
Bram Moolenaard09be322017-07-30 21:37:58 +0200284 \ 'Test_with_partial_callback()',
Bram Moolenaare1c8c7a2016-09-11 16:48:50 +0200285 \ ]
Bram Moolenaarb5760a12016-03-03 13:10:44 +0100286
Bram Moolenaar43345542015-11-29 17:35:35 +0100287" Locate Test_ functions and execute them.
288redir @q
Bram Moolenaar93bf5582016-02-18 22:25:47 +0100289silent function /^Test_
Bram Moolenaar43345542015-11-29 17:35:35 +0100290redir END
Bram Moolenaar00af60b2016-02-13 14:06:14 +0100291let s:tests = split(substitute(@q, 'function \(\k*()\)', '\1', 'g'))
Bram Moolenaar43345542015-11-29 17:35:35 +0100292
Bram Moolenaarbefb3662016-02-20 14:41:40 +0100293" If there is an extra argument filter the function names against it.
294if argc() > 1
295 let s:tests = filter(s:tests, 'v:val =~ argv(1)')
296endif
297
Bram Moolenaarcfc0a352016-01-09 20:23:00 +0100298" Execute the tests in alphabetical order.
Bram Moolenaar93bf5582016-02-18 22:25:47 +0100299for s:test in sort(s:tests)
Bram Moolenaar4a6fcf82017-10-12 21:29:22 +0200300 " Silence, please!
301 set belloff=all
302
Bram Moolenaarb5760a12016-03-03 13:10:44 +0100303 call RunTheTest(s:test)
Bram Moolenaar43345542015-11-29 17:35:35 +0100304
Bram Moolenaarb5760a12016-03-03 13:10:44 +0100305 if len(v:errors) > 0 && index(s:flaky, s:test) >= 0
Bram Moolenaar6caf6062017-03-18 20:45:05 +0100306 call add(s:messages, 'Found errors in ' . s:test . ':')
307 call extend(s:messages, v:errors)
Bram Moolenaarb5760a12016-03-03 13:10:44 +0100308 call add(s:messages, 'Flaky test failed, running it again')
Bram Moolenaar15e737f2017-03-18 21:22:47 +0100309 let first_run = v:errors
310
Bram Moolenaar55058602017-11-21 15:14:51 +0100311 " Flakiness is often caused by the system being very busy. Sleep a couple
312 " of seconds to have a higher chance of succeeding the second time.
313 sleep 2
314
Bram Moolenaarb5760a12016-03-03 13:10:44 +0100315 let v:errors = []
316 call RunTheTest(s:test)
Bram Moolenaar15e737f2017-03-18 21:22:47 +0100317 if len(v:errors) > 0
318 let second_run = v:errors
319 let v:errors = ['First run:']
320 call extend(v:errors, first_run)
321 call add(v:errors, 'Second run:')
322 call extend(v:errors, second_run)
323 endif
Bram Moolenaarb5760a12016-03-03 13:10:44 +0100324 endif
Bram Moolenaar43345542015-11-29 17:35:35 +0100325
Bram Moolenaar42205552017-03-18 19:42:22 +0100326 call AfterTheTest()
Bram Moolenaar43345542015-11-29 17:35:35 +0100327endfor
328
Bram Moolenaar42205552017-03-18 19:42:22 +0100329call FinishTesting()
Bram Moolenaarcc28e2d2016-11-17 17:56:13 +0100330
331" vim: shiftwidth=2 sts=2 expandtab