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