162 lines
3.3 KiB
VimL
162 lines
3.3 KiB
VimL
"
|
|
" Adapted from https://github.com/vim/vim/blob/master/src/testdir/runtest.vim
|
|
"
|
|
" When debugging tests it can help to write debug output:
|
|
" call Log('oh noes')
|
|
"
|
|
|
|
function RunTest(test)
|
|
if exists("*SetUp")
|
|
call SetUp()
|
|
endif
|
|
|
|
try
|
|
execute 'call '.a:test
|
|
catch
|
|
call Exception()
|
|
let s:errored = 1
|
|
endtry
|
|
|
|
if exists("*TearDown")
|
|
call TearDown()
|
|
endif
|
|
endfunction
|
|
|
|
function Log(msg)
|
|
if type(a:msg) == type('')
|
|
call add(s:messages, a:msg)
|
|
elseif type(a:msg) == type([])
|
|
call extend(s:messages, a:msg)
|
|
else
|
|
call add(v:errors, 'Exception: unsupported type: '.type(a:msg))
|
|
endif
|
|
endfunction
|
|
|
|
function Exception()
|
|
call add(v:errors, v:throwpoint.'..'.'Exception: '.v:exception)
|
|
endfunction
|
|
|
|
" Shuffles list in place.
|
|
function Shuffle(list)
|
|
" Fisher-Yates-Durstenfeld-Knuth
|
|
let n = len(a:list)
|
|
if n < 2
|
|
return a:list
|
|
endif
|
|
for i in range(0, n-2)
|
|
let j = Random(0, n-i-1)
|
|
let e = a:list[i]
|
|
let a:list[i] = a:list[i+j]
|
|
let a:list[i+j] = e
|
|
endfor
|
|
return a:list
|
|
endfunction
|
|
|
|
" Returns a pseudorandom integer i such that 0 <= i <= max
|
|
function Random(min, max)
|
|
if has('unix')
|
|
let i = system('echo $RANDOM') " 0 <= i <= 32767
|
|
else
|
|
let i = system('echo %RANDOM%') " 0 <= i <= 32767
|
|
endif
|
|
return i * (a:max - a:min + 1) / 32768 + a:min
|
|
endfunction
|
|
|
|
function FriendlyName(test_name)
|
|
return substitute(a:test_name[5:-3], '_', ' ', 'g')
|
|
endfunction
|
|
|
|
function Align(left, right)
|
|
if type(a:right) == type([])
|
|
let result = []
|
|
for s in a:right
|
|
if empty(result)
|
|
call add(result, printf('%-'.s:indent.'S', a:left).s)
|
|
else
|
|
call add(result, printf('%-'.s:indent.'S', '').s)
|
|
endif
|
|
endfor
|
|
return result
|
|
endif
|
|
|
|
return printf('%-'.s:indent.'S', a:left).a:right
|
|
endfunction
|
|
|
|
let g:testname = expand('%')
|
|
let s:errored = 0
|
|
let s:done = 0
|
|
let s:fail = 0
|
|
let s:errors = 0
|
|
let s:messages = []
|
|
let s:indent = ''
|
|
|
|
call Log(g:testname.':')
|
|
|
|
" Source the test script.
|
|
try
|
|
source %
|
|
catch
|
|
let s:errors += 1
|
|
call Exception()
|
|
endtry
|
|
|
|
" Locate the test functions.
|
|
set nomore
|
|
redir @q
|
|
silent function /^Test_
|
|
redir END
|
|
let s:tests = split(substitute(@q, 'function \(\k*()\)', '\1', 'g'))
|
|
|
|
" If there is another argument, filter test-functions' names against it.
|
|
if argc() > 1
|
|
let s:tests = filter(s:tests, 'v:val =~ argv(1)')
|
|
endif
|
|
|
|
let s:indent = max(map(copy(s:tests), {_, val -> len(FriendlyName(val))}))
|
|
|
|
" Run the tests in random order.
|
|
for test in Shuffle(s:tests)
|
|
call RunTest(test)
|
|
let s:done += 1
|
|
|
|
let friendly_name = FriendlyName(test)
|
|
if len(v:errors) == 0
|
|
call Log(Align(friendly_name, ' - ok'))
|
|
else
|
|
if s:errored
|
|
let s:errors += 1
|
|
let s:errored = 0
|
|
else
|
|
let s:fail += 1
|
|
endif
|
|
call Log(Align(friendly_name, ' - not ok'))
|
|
|
|
let i = 0
|
|
for error in v:errors
|
|
if i != 0
|
|
call Log(Align('',' ! ----'))
|
|
endif
|
|
for trace in reverse(split(error, '\.\.'))
|
|
call Log(Align('', ' ! '.trace))
|
|
endfor
|
|
let i += 1
|
|
endfor
|
|
|
|
let v:errors = []
|
|
endif
|
|
endfor
|
|
|
|
let summary = [
|
|
\ s:done.( s:done == 1 ? ' test' : ' tests'),
|
|
\ s:errors.(s:errors == 1 ? ' error' : ' errors'),
|
|
\ s:fail.( s:fail == 1 ? ' failure' : ' failures'),
|
|
\ ]
|
|
call Log('')
|
|
call Log(join(summary, ', '))
|
|
|
|
split messages.log
|
|
call append(line('$'), s:messages)
|
|
write
|
|
|
|
qall!
|
|
|