blob: 2b38981bb134d170bf9a5e0c77b8f2bdf37eea2f [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 Moolenaarc0662462015-12-30 15:49:05 +010045" For consistency run all tests with 'nocompatible' set.
46" This also enables use of line continuation.
47set nocp viminfo+=nviminfo
48
49" Avoid stopping at the "hit enter" prompt
50set nomore
51
52" Output all messages in English.
53lang mess C
54
Bram Moolenaarf60b7962016-01-16 22:47:23 +010055" Always use forward slashes.
56set shellslash
57
Bram Moolenaare9c07272016-03-30 20:50:46 +020058" Make sure $HOME does not get read or written.
59let $HOME = '/does/not/exist'
60
Bram Moolenaar28fb79d2016-01-09 22:28:33 +010061let s:srcdir = expand('%:p:h:h')
62
Bram Moolenaarebf7dfa2016-04-14 12:46:51 +020063" Prepare for calling garbagecollect_for_testing().
64let v:testing = 1
65
Bram Moolenaar28fb79d2016-01-09 22:28:33 +010066" Support function: get the alloc ID by name.
67function GetAllocId(name)
68 exe 'split ' . s:srcdir . '/alloc.h'
Bram Moolenaar065ee9a2016-01-15 20:53:38 +010069 let top = search('typedef enum')
70 if top == 0
71 call add(v:errors, 'typedef not found in alloc.h')
72 endif
Bram Moolenaar28fb79d2016-01-09 22:28:33 +010073 let lnum = search('aid_' . a:name . ',')
74 if lnum == 0
75 call add(v:errors, 'Alloc ID ' . a:name . ' not defined')
76 endif
77 close
Bram Moolenaar065ee9a2016-01-15 20:53:38 +010078 return lnum - top - 1
Bram Moolenaar28fb79d2016-01-09 22:28:33 +010079endfunc
80
Bram Moolenaarb5760a12016-03-03 13:10:44 +010081function RunTheTest(test)
82 echo 'Executing ' . a:test
83 if exists("*SetUp")
84 call SetUp()
85 endif
86
87 call add(s:messages, 'Executing ' . a:test)
88 let s:done += 1
89 try
90 exe 'call ' . a:test
91 catch
92 call add(v:errors, 'Caught exception in ' . a:test . ': ' . v:exception . ' @ ' . v:throwpoint)
93 endtry
94
95 if exists("*TearDown")
96 call TearDown()
97 endif
98endfunc
Bram Moolenaar28fb79d2016-01-09 22:28:33 +010099
Bram Moolenaar43345542015-11-29 17:35:35 +0100100" Source the test script. First grab the file name, in case the script
Bram Moolenaar00af60b2016-02-13 14:06:14 +0100101" navigates away. g:testname can be used by the tests.
102let g:testname = expand('%')
103let s:done = 0
104let s:fail = 0
105let s:errors = []
106let s:messages = []
Bram Moolenaara2cce862016-01-02 19:50:04 +0100107if expand('%') =~ 'test_viml.vim'
Bram Moolenaar00af60b2016-02-13 14:06:14 +0100108 " this test has intentional s:errors, don't use try/catch.
Bram Moolenaar4686b322015-12-28 14:44:10 +0100109 source %
Bram Moolenaara2cce862016-01-02 19:50:04 +0100110else
111 try
112 source %
113 catch
Bram Moolenaar00af60b2016-02-13 14:06:14 +0100114 let s:fail += 1
115 call add(s:errors, 'Caught exception: ' . v:exception . ' @ ' . v:throwpoint)
Bram Moolenaara2cce862016-01-02 19:50:04 +0100116 endtry
117endif
Bram Moolenaar43345542015-11-29 17:35:35 +0100118
Bram Moolenaarb5760a12016-03-03 13:10:44 +0100119" Names of flaky tests.
120let s:flaky = ['Test_reltime()']
121
Bram Moolenaar43345542015-11-29 17:35:35 +0100122" Locate Test_ functions and execute them.
Bram Moolenaara99b9042016-01-17 17:10:59 +0100123set nomore
Bram Moolenaar43345542015-11-29 17:35:35 +0100124redir @q
Bram Moolenaar93bf5582016-02-18 22:25:47 +0100125silent function /^Test_
Bram Moolenaar43345542015-11-29 17:35:35 +0100126redir END
Bram Moolenaar00af60b2016-02-13 14:06:14 +0100127let s:tests = split(substitute(@q, 'function \(\k*()\)', '\1', 'g'))
Bram Moolenaar43345542015-11-29 17:35:35 +0100128
Bram Moolenaarbefb3662016-02-20 14:41:40 +0100129" If there is an extra argument filter the function names against it.
130if argc() > 1
131 let s:tests = filter(s:tests, 'v:val =~ argv(1)')
132endif
133
Bram Moolenaarcfc0a352016-01-09 20:23:00 +0100134" Execute the tests in alphabetical order.
Bram Moolenaar93bf5582016-02-18 22:25:47 +0100135for s:test in sort(s:tests)
Bram Moolenaarb5760a12016-03-03 13:10:44 +0100136 call RunTheTest(s:test)
Bram Moolenaar43345542015-11-29 17:35:35 +0100137
Bram Moolenaarb5760a12016-03-03 13:10:44 +0100138 if len(v:errors) > 0 && index(s:flaky, s:test) >= 0
139 call add(s:messages, 'Flaky test failed, running it again')
140 let v:errors = []
141 call RunTheTest(s:test)
142 endif
Bram Moolenaar43345542015-11-29 17:35:35 +0100143
144 if len(v:errors) > 0
Bram Moolenaar00af60b2016-02-13 14:06:14 +0100145 let s:fail += 1
146 call add(s:errors, 'Found errors in ' . s:test . ':')
147 call extend(s:errors, v:errors)
Bram Moolenaar43345542015-11-29 17:35:35 +0100148 let v:errors = []
149 endif
Bram Moolenaar43345542015-11-29 17:35:35 +0100150endfor
151
Bram Moolenaar00af60b2016-02-13 14:06:14 +0100152if s:fail == 0
Bram Moolenaar43345542015-11-29 17:35:35 +0100153 " Success, create the .res file so that make knows it's done.
Bram Moolenaar00af60b2016-02-13 14:06:14 +0100154 exe 'split ' . fnamemodify(g:testname, ':r') . '.res'
Bram Moolenaar43345542015-11-29 17:35:35 +0100155 write
156endif
157
Bram Moolenaar00af60b2016-02-13 14:06:14 +0100158if len(s:errors) > 0
Bram Moolenaar43345542015-11-29 17:35:35 +0100159 " Append errors to test.log
160 split test.log
161 call append(line('$'), '')
Bram Moolenaar00af60b2016-02-13 14:06:14 +0100162 call append(line('$'), 'From ' . g:testname . ':')
163 call append(line('$'), s:errors)
Bram Moolenaar43345542015-11-29 17:35:35 +0100164 write
165endif
166
Bram Moolenaar00af60b2016-02-13 14:06:14 +0100167let message = 'Executed ' . s:done . (s:done > 1 ? ' tests' : ' test')
Bram Moolenaar096c8bb2015-12-29 14:26:57 +0100168echo message
Bram Moolenaar00af60b2016-02-13 14:06:14 +0100169call add(s:messages, message)
170if s:fail > 0
171 let message = s:fail . ' FAILED:'
Bram Moolenaar096c8bb2015-12-29 14:26:57 +0100172 echo message
Bram Moolenaar00af60b2016-02-13 14:06:14 +0100173 call add(s:messages, message)
174 call extend(s:messages, s:errors)
Bram Moolenaar43345542015-11-29 17:35:35 +0100175endif
176
Bram Moolenaar096c8bb2015-12-29 14:26:57 +0100177" Append messages to "messages"
178split messages
179call append(line('$'), '')
Bram Moolenaar00af60b2016-02-13 14:06:14 +0100180call append(line('$'), 'From ' . g:testname . ':')
181call append(line('$'), s:messages)
Bram Moolenaar096c8bb2015-12-29 14:26:57 +0100182write
183
Bram Moolenaar43345542015-11-29 17:35:35 +0100184qall!