blob: 43192c450c8826d4ba39a2059d799c71408a19da [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 Moolenaarac105ed2016-07-21 20:33:32 +020052" Use utf-8 or latin1 be default, instead of whatever the system default
53" 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 Moolenaarc0662462015-12-30 15:49:05 +010060" Output all messages in English.
61lang mess C
62
Bram Moolenaarf60b7962016-01-16 22:47:23 +010063" Always use forward slashes.
64set shellslash
65
Bram Moolenaar28fb79d2016-01-09 22:28:33 +010066let s:srcdir = expand('%:p:h:h')
67
Bram Moolenaar8e8df252016-05-25 21:23:21 +020068" Prepare for calling test_garbagecollect_now().
Bram Moolenaarebf7dfa2016-04-14 12:46:51 +020069let v:testing = 1
70
Bram Moolenaar28fb79d2016-01-09 22:28:33 +010071" Support function: get the alloc ID by name.
72function GetAllocId(name)
73 exe 'split ' . s:srcdir . '/alloc.h'
Bram Moolenaar065ee9a2016-01-15 20:53:38 +010074 let top = search('typedef enum')
75 if top == 0
76 call add(v:errors, 'typedef not found in alloc.h')
77 endif
Bram Moolenaar28fb79d2016-01-09 22:28:33 +010078 let lnum = search('aid_' . a:name . ',')
79 if lnum == 0
80 call add(v:errors, 'Alloc ID ' . a:name . ' not defined')
81 endif
82 close
Bram Moolenaar065ee9a2016-01-15 20:53:38 +010083 return lnum - top - 1
Bram Moolenaar28fb79d2016-01-09 22:28:33 +010084endfunc
85
Bram Moolenaarb5760a12016-03-03 13:10:44 +010086function RunTheTest(test)
87 echo 'Executing ' . a:test
Bram Moolenaare5f2a072017-02-01 22:31:49 +010088
89 " Avoid stopping at the "hit enter" prompt
90 set nomore
91
92 " Avoid a three second wait when a message is about to be overwritten by the
93 " mode message.
94 set noshowmode
95
Bram Moolenaarb5760a12016-03-03 13:10:44 +010096 if exists("*SetUp")
Bram Moolenaarcc28e2d2016-11-17 17:56:13 +010097 try
98 call SetUp()
99 catch
100 call add(v:errors, 'Caught exception in SetUp() before ' . a:test . ': ' . v:exception . ' @ ' . v:throwpoint)
101 endtry
Bram Moolenaarb5760a12016-03-03 13:10:44 +0100102 endif
103
104 call add(s:messages, 'Executing ' . a:test)
105 let s:done += 1
106 try
107 exe 'call ' . a:test
Bram Moolenaardac19472016-09-03 22:35:40 +0200108 catch /^\cskipped/
109 call add(s:messages, ' Skipped')
110 call add(s:skipped, 'SKIPPED ' . a:test . ': ' . substitute(v:exception, '^\S*\s\+', '', ''))
Bram Moolenaarb5760a12016-03-03 13:10:44 +0100111 catch
112 call add(v:errors, 'Caught exception in ' . a:test . ': ' . v:exception . ' @ ' . v:throwpoint)
113 endtry
114
115 if exists("*TearDown")
Bram Moolenaarcc28e2d2016-11-17 17:56:13 +0100116 try
117 call TearDown()
118 catch
119 call add(v:errors, 'Caught exception in TearDown() after ' . a:test . ': ' . v:exception . ' @ ' . v:throwpoint)
120 endtry
Bram Moolenaarb5760a12016-03-03 13:10:44 +0100121 endif
Bram Moolenaar7cba71d2016-08-02 23:04:49 +0200122
123 " Close any extra windows and make the current one not modified.
Bram Moolenaar358308d2016-08-24 21:21:26 +0200124 while 1
125 let wincount = winnr('$')
126 if wincount == 1
127 break
128 endif
Bram Moolenaar7cba71d2016-08-02 23:04:49 +0200129 bwipe!
Bram Moolenaar358308d2016-08-24 21:21:26 +0200130 if wincount == winnr('$')
131 " Did not manage to close a window.
132 only!
133 break
134 endif
Bram Moolenaar7cba71d2016-08-02 23:04:49 +0200135 endwhile
136 set nomodified
Bram Moolenaarb5760a12016-03-03 13:10:44 +0100137endfunc
Bram Moolenaar28fb79d2016-01-09 22:28:33 +0100138
Bram Moolenaar43345542015-11-29 17:35:35 +0100139" Source the test script. First grab the file name, in case the script
Bram Moolenaar00af60b2016-02-13 14:06:14 +0100140" navigates away. g:testname can be used by the tests.
141let g:testname = expand('%')
142let s:done = 0
143let s:fail = 0
144let s:errors = []
145let s:messages = []
Bram Moolenaardac19472016-09-03 22:35:40 +0200146let s:skipped = []
Bram Moolenaara2cce862016-01-02 19:50:04 +0100147if expand('%') =~ 'test_viml.vim'
Bram Moolenaar00af60b2016-02-13 14:06:14 +0100148 " this test has intentional s:errors, don't use try/catch.
Bram Moolenaar4686b322015-12-28 14:44:10 +0100149 source %
Bram Moolenaara2cce862016-01-02 19:50:04 +0100150else
151 try
152 source %
153 catch
Bram Moolenaar00af60b2016-02-13 14:06:14 +0100154 let s:fail += 1
155 call add(s:errors, 'Caught exception: ' . v:exception . ' @ ' . v:throwpoint)
Bram Moolenaara2cce862016-01-02 19:50:04 +0100156 endtry
157endif
Bram Moolenaar43345542015-11-29 17:35:35 +0100158
Bram Moolenaarb5760a12016-03-03 13:10:44 +0100159" Names of flaky tests.
Bram Moolenaare1c8c7a2016-09-11 16:48:50 +0200160let s:flaky = [
Bram Moolenaar6fe2eb42017-01-29 21:49:51 +0100161 \ 'Test_close_and_exit_cb()',
Bram Moolenaarb2455592017-02-01 18:00:13 +0100162 \ 'Test_collapse_buffers()',
163 \ 'Test_communicate()',
164 \ 'Test_nb_basic()',
Bram Moolenaarc79d6aa2016-09-25 22:27:37 +0200165 \ 'Test_pipe_through_sort_all()',
Bram Moolenaar4e032e12017-02-01 20:48:13 +0100166 \ 'Test_pipe_through_sort_some()',
Bram Moolenaarb2455592017-02-01 18:00:13 +0100167 \ 'Test_reltime()',
Bram Moolenaare1c8c7a2016-09-11 16:48:50 +0200168 \ ]
Bram Moolenaarb5760a12016-03-03 13:10:44 +0100169
Bram Moolenaar43345542015-11-29 17:35:35 +0100170" Locate Test_ functions and execute them.
Bram Moolenaara99b9042016-01-17 17:10:59 +0100171set nomore
Bram Moolenaar43345542015-11-29 17:35:35 +0100172redir @q
Bram Moolenaar93bf5582016-02-18 22:25:47 +0100173silent function /^Test_
Bram Moolenaar43345542015-11-29 17:35:35 +0100174redir END
Bram Moolenaar00af60b2016-02-13 14:06:14 +0100175let s:tests = split(substitute(@q, 'function \(\k*()\)', '\1', 'g'))
Bram Moolenaar43345542015-11-29 17:35:35 +0100176
Bram Moolenaarbefb3662016-02-20 14:41:40 +0100177" If there is an extra argument filter the function names against it.
178if argc() > 1
179 let s:tests = filter(s:tests, 'v:val =~ argv(1)')
180endif
181
Bram Moolenaarcfc0a352016-01-09 20:23:00 +0100182" Execute the tests in alphabetical order.
Bram Moolenaar93bf5582016-02-18 22:25:47 +0100183for s:test in sort(s:tests)
Bram Moolenaarb5760a12016-03-03 13:10:44 +0100184 call RunTheTest(s:test)
Bram Moolenaar43345542015-11-29 17:35:35 +0100185
Bram Moolenaarb5760a12016-03-03 13:10:44 +0100186 if len(v:errors) > 0 && index(s:flaky, s:test) >= 0
187 call add(s:messages, 'Flaky test failed, running it again')
188 let v:errors = []
189 call RunTheTest(s:test)
190 endif
Bram Moolenaar43345542015-11-29 17:35:35 +0100191
192 if len(v:errors) > 0
Bram Moolenaar00af60b2016-02-13 14:06:14 +0100193 let s:fail += 1
194 call add(s:errors, 'Found errors in ' . s:test . ':')
195 call extend(s:errors, v:errors)
Bram Moolenaar43345542015-11-29 17:35:35 +0100196 let v:errors = []
197 endif
Bram Moolenaar43345542015-11-29 17:35:35 +0100198endfor
199
Bram Moolenaarfc4ad612016-07-09 15:38:32 +0200200" Don't write viminfo on exit.
201set viminfo=
202
Bram Moolenaar00af60b2016-02-13 14:06:14 +0100203if s:fail == 0
Bram Moolenaar43345542015-11-29 17:35:35 +0100204 " Success, create the .res file so that make knows it's done.
Bram Moolenaar00af60b2016-02-13 14:06:14 +0100205 exe 'split ' . fnamemodify(g:testname, ':r') . '.res'
Bram Moolenaar43345542015-11-29 17:35:35 +0100206 write
207endif
208
Bram Moolenaar00af60b2016-02-13 14:06:14 +0100209if len(s:errors) > 0
Bram Moolenaar43345542015-11-29 17:35:35 +0100210 " Append errors to test.log
211 split test.log
212 call append(line('$'), '')
Bram Moolenaar00af60b2016-02-13 14:06:14 +0100213 call append(line('$'), 'From ' . g:testname . ':')
214 call append(line('$'), s:errors)
Bram Moolenaar43345542015-11-29 17:35:35 +0100215 write
216endif
217
Bram Moolenaar00af60b2016-02-13 14:06:14 +0100218let message = 'Executed ' . s:done . (s:done > 1 ? ' tests' : ' test')
Bram Moolenaar096c8bb2015-12-29 14:26:57 +0100219echo message
Bram Moolenaar00af60b2016-02-13 14:06:14 +0100220call add(s:messages, message)
221if s:fail > 0
222 let message = s:fail . ' FAILED:'
Bram Moolenaar096c8bb2015-12-29 14:26:57 +0100223 echo message
Bram Moolenaar00af60b2016-02-13 14:06:14 +0100224 call add(s:messages, message)
225 call extend(s:messages, s:errors)
Bram Moolenaar43345542015-11-29 17:35:35 +0100226endif
227
Bram Moolenaardac19472016-09-03 22:35:40 +0200228" Add SKIPPED messages
229call extend(s:messages, s:skipped)
230
231" Append messages to the file "messages"
Bram Moolenaar096c8bb2015-12-29 14:26:57 +0100232split messages
233call append(line('$'), '')
Bram Moolenaar00af60b2016-02-13 14:06:14 +0100234call append(line('$'), 'From ' . g:testname . ':')
235call append(line('$'), s:messages)
Bram Moolenaar096c8bb2015-12-29 14:26:57 +0100236write
237
Bram Moolenaar43345542015-11-29 17:35:35 +0100238qall!
Bram Moolenaarcc28e2d2016-11-17 17:56:13 +0100239
240" vim: shiftwidth=2 sts=2 expandtab