xref: /vim-8.2.3635/src/testdir/runtest.vim (revision 93bf558c)
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"
543345546SBram Moolenaar" The test script may contain anything, only functions that start with
643345546SBram Moolenaar" "Test_" are special.  These will be invoked and should contain assert
743345546SBram Moolenaar" functions.  See test_assert.vim for an example.
843345546SBram Moolenaar"
943345546SBram Moolenaar" It is possible to source other files that contain "Test_" functions.  This
1043345546SBram Moolenaar" can speed up testing, since Vim does not need to restart.  But be careful
1143345546SBram Moolenaar" that the tests do not interfere with each other.
1243345546SBram Moolenaar"
1343345546SBram Moolenaar" If an error cannot be detected properly with an assert function add the
1443345546SBram Moolenaar" error to the v:errors list:
1543345546SBram Moolenaar"   call add(v:errors, 'test foo failed: Cannot find xyz')
1643345546SBram Moolenaar"
1743345546SBram Moolenaar" If preparation for each Test_ function is needed, define a SetUp function.
1843345546SBram Moolenaar" It will be called before each Test_ function.
1943345546SBram Moolenaar"
2043345546SBram Moolenaar" If cleanup after each Test_ function is needed, define a TearDown function.
2143345546SBram Moolenaar" It will be called after each Test_ function.
2200af60bbSBram Moolenaar"
2300af60bbSBram Moolenaar" When debugging a test it can be useful to add messages to v:errors:
2400af60bbSBram Moolenaar" 	call add(v:errors, "this happened")
2500af60bbSBram Moolenaar
2643345546SBram Moolenaar
2743345546SBram Moolenaar" Without the +eval feature we can't run these tests, bail out.
284686b323SBram Moolenaarso small.vim
2943345546SBram Moolenaar
3043345546SBram Moolenaar" Check that the screen size is at least 24 x 80 characters.
3143345546SBram Moolenaarif &lines < 24 || &columns < 80
3243345546SBram Moolenaar  let error = 'Screen size too small! Tests require at least 24 lines with 80 characters'
3343345546SBram Moolenaar  echoerr error
3443345546SBram Moolenaar  split test.log
3543345546SBram Moolenaar  $put =error
3643345546SBram Moolenaar  w
3743345546SBram Moolenaar  cquit
3843345546SBram Moolenaarendif
3943345546SBram Moolenaar
40c0662466SBram Moolenaar" For consistency run all tests with 'nocompatible' set.
41c0662466SBram Moolenaar" This also enables use of line continuation.
42c0662466SBram Moolenaarset nocp viminfo+=nviminfo
43c0662466SBram Moolenaar
44c0662466SBram Moolenaar" Avoid stopping at the "hit enter" prompt
45c0662466SBram Moolenaarset nomore
46c0662466SBram Moolenaar
47c0662466SBram Moolenaar" Output all messages in English.
48c0662466SBram Moolenaarlang mess C
49c0662466SBram Moolenaar
50f60b796fSBram Moolenaar" Always use forward slashes.
51f60b796fSBram Moolenaarset shellslash
52f60b796fSBram Moolenaar
5328fb79dbSBram Moolenaarlet s:srcdir = expand('%:p:h:h')
5428fb79dbSBram Moolenaar
5528fb79dbSBram Moolenaar" Support function: get the alloc ID by name.
5628fb79dbSBram Moolenaarfunction GetAllocId(name)
5728fb79dbSBram Moolenaar  exe 'split ' . s:srcdir . '/alloc.h'
58065ee9aeSBram Moolenaar  let top = search('typedef enum')
59065ee9aeSBram Moolenaar  if top == 0
60065ee9aeSBram Moolenaar    call add(v:errors, 'typedef not found in alloc.h')
61065ee9aeSBram Moolenaar  endif
6228fb79dbSBram Moolenaar  let lnum = search('aid_' . a:name . ',')
6328fb79dbSBram Moolenaar  if lnum == 0
6428fb79dbSBram Moolenaar    call add(v:errors, 'Alloc ID ' . a:name . ' not defined')
6528fb79dbSBram Moolenaar  endif
6628fb79dbSBram Moolenaar  close
67065ee9aeSBram Moolenaar  return lnum - top - 1
6828fb79dbSBram Moolenaarendfunc
6928fb79dbSBram Moolenaar
7028fb79dbSBram Moolenaar
7143345546SBram Moolenaar" Source the test script.  First grab the file name, in case the script
7200af60bbSBram Moolenaar" navigates away.  g:testname can be used by the tests.
7300af60bbSBram Moolenaarlet g:testname = expand('%')
7400af60bbSBram Moolenaarlet s:done = 0
7500af60bbSBram Moolenaarlet s:fail = 0
7600af60bbSBram Moolenaarlet s:errors = []
7700af60bbSBram Moolenaarlet s:messages = []
78a2cce863SBram Moolenaarif expand('%') =~ 'test_viml.vim'
7900af60bbSBram Moolenaar  " this test has intentional s:errors, don't use try/catch.
80a2cce863SBram Moolenaar  source %
81a2cce863SBram Moolenaarelse
824686b323SBram Moolenaar  try
8343345546SBram Moolenaar    source %
844686b323SBram Moolenaar  catch
8500af60bbSBram Moolenaar    let s:fail += 1
8600af60bbSBram Moolenaar    call add(s:errors, 'Caught exception: ' . v:exception . ' @ ' . v:throwpoint)
874686b323SBram Moolenaar  endtry
88a2cce863SBram Moolenaarendif
8943345546SBram Moolenaar
9043345546SBram Moolenaar" Locate Test_ functions and execute them.
91a99b9043SBram Moolenaarset nomore
9243345546SBram Moolenaarredir @q
93*93bf558cSBram Moolenaarsilent function /^Test_
9443345546SBram Moolenaarredir END
9500af60bbSBram Moolenaarlet s:tests = split(substitute(@q, 'function \(\k*()\)', '\1', 'g'))
9643345546SBram Moolenaar
97cfc0a350SBram Moolenaar" Execute the tests in alphabetical order.
9800af60bbSBram Moolenaarfor s:test in sort(s:tests)
99*93bf558cSBram Moolenaar  echo 'Executing ' . s:test
10043345546SBram Moolenaar  if exists("*SetUp")
10143345546SBram Moolenaar    call SetUp()
10243345546SBram Moolenaar  endif
10343345546SBram Moolenaar
10400af60bbSBram Moolenaar  call add(s:messages, 'Executing ' . s:test)
10500af60bbSBram Moolenaar  let s:done += 1
10643345546SBram Moolenaar  try
10700af60bbSBram Moolenaar    exe 'call ' . s:test
10843345546SBram Moolenaar  catch
10900af60bbSBram Moolenaar    call add(v:errors, 'Caught exception in ' . s:test . ': ' . v:exception . ' @ ' . v:throwpoint)
11043345546SBram Moolenaar  endtry
11143345546SBram Moolenaar
11243345546SBram Moolenaar  if len(v:errors) > 0
11300af60bbSBram Moolenaar    let s:fail += 1
11400af60bbSBram Moolenaar    call add(s:errors, 'Found errors in ' . s:test . ':')
11500af60bbSBram Moolenaar    call extend(s:errors, v:errors)
11643345546SBram Moolenaar    let v:errors = []
11743345546SBram Moolenaar  endif
11843345546SBram Moolenaar
11943345546SBram Moolenaar  if exists("*TearDown")
12043345546SBram Moolenaar    call TearDown()
12143345546SBram Moolenaar  endif
12243345546SBram Moolenaarendfor
12343345546SBram Moolenaar
12400af60bbSBram Moolenaarif s:fail == 0
12543345546SBram Moolenaar  " Success, create the .res file so that make knows it's done.
12600af60bbSBram Moolenaar  exe 'split ' . fnamemodify(g:testname, ':r') . '.res'
12743345546SBram Moolenaar  write
12843345546SBram Moolenaarendif
12943345546SBram Moolenaar
13000af60bbSBram Moolenaarif len(s:errors) > 0
13143345546SBram Moolenaar  " Append errors to test.log
13243345546SBram Moolenaar  split test.log
13343345546SBram Moolenaar  call append(line('$'), '')
13400af60bbSBram Moolenaar  call append(line('$'), 'From ' . g:testname . ':')
13500af60bbSBram Moolenaar  call append(line('$'), s:errors)
13643345546SBram Moolenaar  write
13743345546SBram Moolenaarendif
13843345546SBram Moolenaar
13900af60bbSBram Moolenaarlet message = 'Executed ' . s:done . (s:done > 1 ? ' tests' : ' test')
140096c8bb4SBram Moolenaarecho message
14100af60bbSBram Moolenaarcall add(s:messages, message)
14200af60bbSBram Moolenaarif s:fail > 0
14300af60bbSBram Moolenaar  let message = s:fail . ' FAILED:'
144096c8bb4SBram Moolenaar  echo message
14500af60bbSBram Moolenaar  call add(s:messages, message)
14600af60bbSBram Moolenaar  call extend(s:messages, s:errors)
14743345546SBram Moolenaarendif
14843345546SBram Moolenaar
149096c8bb4SBram Moolenaar" Append messages to "messages"
150096c8bb4SBram Moolenaarsplit messages
151096c8bb4SBram Moolenaarcall append(line('$'), '')
15200af60bbSBram Moolenaarcall append(line('$'), 'From ' . g:testname . ':')
15300af60bbSBram Moolenaarcall append(line('$'), s:messages)
154096c8bb4SBram Moolenaarwrite
155096c8bb4SBram Moolenaar
15643345546SBram Moolenaarqall!
157