Skip to content

Commit 6d7d0d3

Browse files
committed
POC test runner for VimScript that stubs globals for verification
1 parent c1c5c81 commit 6d7d0d3

7 files changed

+205
-0
lines changed
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
" test-setup
2+
" vi: ft=vim
3+
4+
let s:debug = 0
5+
6+
source ./shared-mocks.vimtest
7+
8+
let s:hasArgs = []
9+
function! MOCK_has(arg)
10+
call add(s:hasArgs, a:arg)
11+
if a:arg ==# "nvim"
12+
return 1
13+
elseif a:arg ==# "nvim-0.3.2"
14+
return 1
15+
elseif a:arg ==# "nvim-0.4.0"
16+
return 1
17+
else
18+
return 0
19+
endif
20+
endfunction
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
" test assertions
2+
" vi: ft=vim
3+
source ./vimunit.testvim
4+
5+
" Arrange
6+
7+
" Act
8+
call s:checkVersion()
9+
10+
" Assert
11+
call ShouldNotMatchListElem(g:echomArgs, 0, "coc.nvim works best on .* and neovim >= 0.4.0")
12+
call ShouldBeEmpty(g:echomArgs)
13+
14+
if s:debug
15+
echo "echom arguments: " . join(g:echomArgs, ',')
16+
echo "has arguments: " . join(s:hasArgs, ',')
17+
endif
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
" test-setup
2+
" vi: ft=vim
3+
4+
let s:debug = 0
5+
6+
source ./shared-mocks.vimtest
7+
8+
let s:hasArgs = []
9+
function! MOCK_has(arg)
10+
call add(s:hasArgs, a:arg)
11+
if a:arg ==# "nvim"
12+
return 1
13+
elseif a:arg ==# "nvim-0.3.2"
14+
return 1
15+
else
16+
return 0
17+
endif
18+
endfunction
19+
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
" test assertions
2+
" vi: ft=vim
3+
source ./vimunit.testvim
4+
5+
" Arrange
6+
" done in coc.setup.vimtest
7+
8+
" Act
9+
call s:checkVersion()
10+
11+
" Assert
12+
call ShouldMatch(g:echomArgs[0], "coc.nvim works best on .* and neovim >= 0.4.0")
13+
14+
if s:debug
15+
echo "echom arguments: " . join(g:echomArgs, ',')
16+
echo "has arguments: " . join(s:hasArgs, ',')
17+
endif

plugin/shared-mocks.vimtest

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
" vi: ft=vim
2+
3+
function! MOCK_coc_rpc_start_server()
4+
endfunction
5+
6+
let g:echomArgs = []
7+
function! MOCK_echom(arg)
8+
call add(g:echomArgs, a:arg)
9+
endfunction
10+

plugin/test-runner

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
#!/bin/bash
2+
# Test runner for coc.vim
3+
# Strips away everything but the function definitions
4+
# and replaces built-ins with overridable functions
5+
6+
# exit on error
7+
set -e
8+
#set -x
9+
10+
assert_file(){
11+
if [ ! -e $1 ]; then
12+
printf "Missing file: %s\n" $1
13+
exit 1
14+
fi
15+
}
16+
17+
# @param testname corresponds to two files: ${testname}.setup.vimtest and ${testname}.vimtest
18+
make_test(){
19+
TMPSCRIPT=$(mktemp)
20+
local SETUP=${1}.setup.vimtest
21+
local TEST=${1}.vimtest
22+
23+
assert_file $SETUP
24+
assert_file $TEST
25+
26+
# setup test code, including stubs to be used
27+
cp $SETUP $TMPSCRIPT
28+
29+
# strip all non-functions from the plugin code and append to the test script
30+
egrep -v '^(command|.noremap|call)' coc.vim | \
31+
sed -e 's/coc#\([a-z]*\)#\([a-z]\)/MOCK_coc_\1_\2/' | \
32+
sed -e 's/echom \(.*\)/call MOCK_echom(\1)/' | \
33+
replace_builtins >> $TMPSCRIPT
34+
35+
36+
if [ -n "$DEBUG" ]; then
37+
echo "let s:debug = 1" >> $TMPSCRIPT
38+
fi
39+
40+
# the tests to run
41+
cat $TEST >> $TMPSCRIPT
42+
43+
# Signal test end to user
44+
cat >> $TMPSCRIPT << EOF
45+
echom "$1 finished"
46+
sleep 1
47+
EOF
48+
49+
# auto-quit unless ...
50+
if [ -z "$STOP_ON_FINISH" ]; then
51+
echo "quit" >> $TMPSCRIPT
52+
fi
53+
}
54+
55+
# @param builtin
56+
# @returns sed compatible regex that replaces $1 with MOCK_$1
57+
# @example `if !(has("nvim-0.4.0"))` => `if !(MOCK_has("nvim-0.4.0"))
58+
create_replace_regex(){
59+
printf "%s" "s/ \([!(]\{0,2\}\)$1(/ \1MOCK_$1(/g"
60+
}
61+
62+
# replaces built-in _functions_
63+
replace_builtins(){
64+
sed \
65+
-e "$(create_replace_regex has)" \
66+
;
67+
}
68+
69+
# override which vim version to test this with by setting
70+
# the VIM environment variable: `VIM_EXE=nvim ./run-test
71+
if [ "x$VIM_EXE" = "x" ]; then
72+
VIM_EXE=/usr/bin/vim # default
73+
fi
74+
75+
case $1 in
76+
--help)
77+
printf "Usage: %s [--show-script | --stop-on-finish] test-name"
78+
exit 1
79+
;;
80+
--show-script)
81+
SHOW_SCRIPT=1
82+
shift
83+
;;
84+
--stop-on-finish)
85+
STOP_ON_FINISH=1
86+
shift
87+
;;
88+
esac
89+
90+
make_test $1
91+
if [ "$SHOW_SCRIPT" ]; then
92+
less $TMPSCRIPT
93+
exit
94+
fi
95+
$VIM_EXE --clean -S $TMPSCRIPT
96+
rm $TMPSCRIPT

plugin/vimunit.testvim

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
" XUnit for VIM :p
2+
" vi: ft=vim
3+
4+
function! ShouldMatch(text,regexp)
5+
if !(a:text =~# a:regexp)
6+
throw "Assertion failed. Expected '" . a:text . "' to match '" . a:regexp . "'"
7+
endif
8+
endfunction
9+
10+
function! ShouldNotMatch(text,regexp)
11+
if a:text =~# a:regexp
12+
throw "Assertion failed. Expected '" . a:text . "' not to match '" . a:regexp . "'"
13+
endif
14+
endfunction
15+
16+
function! ShouldNotMatchListElem(list,index,regexp)
17+
if len(a:list) > 0
18+
call ShouldNotMatch(a:list[a:index], a:regexp)
19+
endif
20+
endfunction
21+
22+
function! ShouldBeEmpty(list)
23+
if len(a:list) > 0
24+
throw "Assertion failed. Expected empty list"
25+
endif
26+
endfunction

0 commit comments

Comments
 (0)