0
0
mirror of https://github.com/vim/vim.git synced 2025-07-24 10:45:12 -04:00
vim/runtime/syntax/testdir/runtest.vim
Christian Brabandt 56824430c0
runtime(syntax-tests): simplify code and allow filetype options
The whole testdir/runtest.vim is a bit of a mess. So this is an attempt
to improving the current state. First of all, let's move most of the
code into a single RunTest() function so that it's easier to run this
manually.

Then, let's add the possibility to customize filetype specific tests by
applying filetype specific options. We will make use of it in the next
commit, where the provided java file uses tabs, which cause line
wrapping which will then cause the scrolling to miss some lines when
redrawing (see #14105)

related: #14105

Signed-off-by: Christian Brabandt <cb@256bit.org>
2024-02-28 21:24:25 +01:00

265 lines
6.8 KiB
VimL

" Runs all the syntax tests for which there is no "done/name" file.
"
" Current directory must be runtime/syntax.
" Only do this with the +eval feature
if 1
" Remember the directory where we started. Will change to "testdir" below.
let syntaxDir = getcwd()
let s:messagesFname = fnameescape(syntaxDir .. '/testdir/messages')
let s:messages = []
" Add one message to the list of messages
func Message(msg)
echomsg a:msg
call add(s:messages, a:msg)
endfunc
" Report a fatal message and exit
func Fatal(msg)
echoerr a:msg
call AppendMessages(a:msg)
qall!
endfunc
" Append s:messages to the messages file and make it empty.
func AppendMessages(header)
exe 'split ' .. s:messagesFname
call append(line('$'), '')
call append(line('$'), a:header)
call append(line('$'), s:messages)
let s:messages = []
wq
endfunc
" Relevant messages are written to the "messages" file.
" If the file already exists it is appended to.
exe 'split ' .. s:messagesFname
call append(line('$'), repeat('=-', 70))
call append(line('$'), '')
let s:test_run_message = 'Test run on ' .. strftime("%Y %b %d %H:%M:%S")
call append(line('$'), s:test_run_message)
wq
if syntaxDir !~ '[/\\]runtime[/\\]syntax\>'
call Fatal('Current directory must be "runtime/syntax"')
endif
if !isdirectory('testdir')
call Fatal('"testdir" directory not found')
endif
" Use the script for source code screendump testing. It sources other scripts,
" therefore we must "cd" there.
cd ../../src/testdir
source screendump.vim
exe 'cd ' .. fnameescape(syntaxDir)
" For these tests we need to be able to run terminal Vim with 256 colors. On
" MS-Windows the console only has 16 colors and the GUI can't run in a
" terminal.
if !CanRunVimInTerminal()
call Fatal('Cannot make screendumps, aborting')
endif
cd testdir
if !isdirectory('done')
call mkdir('done')
endif
set nocp
set nowrapscan
set report=9999
set modeline
set debug=throw
set nomore
au! SwapExists * call HandleSwapExists()
func HandleSwapExists()
" Ignore finding a swap file for the test input, the user might be editing
" it and that's OK.
if expand('<afile>') =~ 'input[/\\].*\..*'
let v:swapchoice = 'e'
endif
endfunc
func RunTest()
let ok_count = 0
let failed_tests = []
let skipped_count = 0
let MAX_FAILED_COUNT = 5
for fname in glob('input/*.*', 1, 1)
if fname =~ '\~$'
" backup file, skip
continue
endif
let linecount = readfile(fname)->len()
let root = fnamemodify(fname, ':t:r')
let filetype = substitute(root, '\([^_.]*\)[_.].*', '\1', '')
let failed_root = 'failed/' .. root
" Execute the test if the "done" file does not exist or when the input file
" is newer.
let in_time = getftime(fname)
let out_time = getftime('done/' .. root)
if out_time < 0 || in_time > out_time
call ch_log('running tests for: ' .. fname)
for dumpname in glob(failed_root .. '_\d*\.dump', 1, 1)
call delete(dumpname)
endfor
call delete('done/' .. root)
let lines =<< trim END
syntax on
" extra info for shell variables
func ShellInfo()
let msg = ''
for [key, val] in items(b:)
if key =~ '^is_'
let msg ..= key .. ': ' .. val .. ', '
endif
endfor
if msg != ''
echomsg msg
endif
endfunc
au! SwapExists * call HandleSwapExists()
func HandleSwapExists()
" Ignore finding a swap file for the test input, the user might be
" editing it and that's OK.
if expand('<afile>') =~ 'input[/\\].*\..*'
let v:swapchoice = 'e'
endif
endfunc
func LoadFiletype(type)
for file in glob("ftplugin/" .. a:type .. "*.vim", 1, 1)
exe "source " .. file
endfor
redraw!
endfunc
END
call writefile(lines, 'Xtestscript')
" close all but the last window
while winnr('$') > 1
close
endwhile
" Redraw to make sure that messages are cleared and there is enough space
" for the terminal window.
redraw
let buf = RunVimInTerminal('-S Xtestscript', {})
" edit the file only after catching the SwapExists event
call term_sendkeys(buf, ":edit " .. fname .. "\<CR>")
" load filetype specific settings
call term_sendkeys(buf, ":call LoadFiletype('" .. filetype .. "')\<CR>")
if filetype == 'sh'
call term_sendkeys(buf, ":call ShellInfo()\<CR>")
endif
" Screendump at the start of the file: failed/root_00.dump
let root_00 = root .. '_00'
call ch_log('First screendump for ' .. fname .. ': failed/' .. root_00 .. '.dump')
let fail = VerifyScreenDump(buf, root_00, {})
" clear the shell info if there are not enough lines to cause a scroll
if filetype == 'sh' && linecount <= 19
call term_sendkeys(buf, ":redraw\<CR>")
endif
" Make a Screendump every 18 lines of the file: failed/root_NN.dump
let topline = 1
let nr = 1
while linecount - topline > 20
let topline += 18
call term_sendkeys(buf, printf("%dGzt", topline))
let root_next = root .. printf('_%02d', nr)
call ch_log('Next screendump for ' .. fname .. ': failed/' .. root_next .. '.dump')
let fail += VerifyScreenDump(buf, root_next, {})
let nr += 1
endwhile
" Screendump at the end of the file: failed/root_99.dump
call term_sendkeys(buf, 'Gzb')
let root_last = root .. '_99'
call ch_log('Last screendump for ' .. fname .. ': failed/' .. root_last .. '.dump')
let fail += VerifyScreenDump(buf, root_last, {})
call StopVimInTerminal(buf)
call delete('Xtestscript')
" redraw here to avoid the following messages to get mixed up with screen
" output.
redraw
" Add any assert errors to s:messages.
if len(v:errors) > 0
call extend(s:messages, v:errors)
" Echo the errors here, in case the script aborts or the "messages" file
" is not displayed later.
echomsg v:errors
let v:errors = []
let fail += 1
endif
if fail == 0
call Message("Test " .. root .. " OK")
call writefile(['OK'], 'done/' .. root)
let ok_count += 1
else
call Message("Test " .. root .. " FAILED")
call delete('done/' .. root)
eval failed_tests->add(root)
if len(failed_tests) > MAX_FAILED_COUNT
call Message('')
call Message('Too many errors, aborting')
endif
endif
else
call Message("Test " .. root .. " skipped")
let skipped_count += 1
endif
" Append messages to the file "testdir/messages"
call AppendMessages('Input file ' .. fname .. ':')
if len(failed_tests) > MAX_FAILED_COUNT
break
endif
endfor
call Message(s:test_run_message)
call Message('OK: ' .. ok_count)
call Message('FAILED: ' .. len(failed_tests) .. ': ' .. string(failed_tests))
call Message('skipped: ' .. skipped_count)
call AppendMessages('== SUMMARY ==')
if len(failed_tests) > 0
" have make report an error
cquit
endif
endfunc
call RunTest()
" Matching "if 1" at the start.
endif
qall!
" vim:ts=8