diff options
| author | James McCoy <jamessan@jamessan.com> | 2019-12-15 21:17:16 -0500 |
|---|---|---|
| committer | James McCoy <jamessan@jamessan.com> | 2019-12-15 21:17:16 -0500 |
| commit | 6566251d144d2c9c9e08e05c8c3a3fe9915a19b8 (patch) | |
| tree | 980fd0c7287e295c8ac72858b0794f72224415e0 /src/nvim/testdir | |
| parent | 9c4223215f71e1212462ada4e698be1b31437dd9 (diff) | |
| parent | 9f3d483c79f03c48239fdc82cc02e8685a03d22a (diff) | |
| download | rneovim-6566251d144d2c9c9e08e05c8c3a3fe9915a19b8.tar.gz rneovim-6566251d144d2c9c9e08e05c8c3a3fe9915a19b8.tar.bz2 rneovim-6566251d144d2c9c9e08e05c8c3a3fe9915a19b8.zip | |
Merge remote-tracking branch 'upstream/master' into libcall
Diffstat (limited to 'src/nvim/testdir')
59 files changed, 3467 insertions, 1320 deletions
diff --git a/src/nvim/testdir/Makefile b/src/nvim/testdir/Makefile index d1a449c7cc..b470dbf8f6 100644 --- a/src/nvim/testdir/Makefile +++ b/src/nvim/testdir/Makefile @@ -11,11 +11,10 @@ ROOT := ../../.. export SHELL := sh export NVIM_PRG := $(NVIM_PRG) -export TMPDIR := $(abspath ../../../Xtest-tmpdir) +export TMPDIR := $(abspath Xtest-tmpdir) SCRIPTS_DEFAULT = \ test42.out \ - test48.out \ test64.out \ ifneq ($(OS),Windows_NT) @@ -34,21 +33,23 @@ SCRIPTS ?= $(SCRIPTS_DEFAULT) # Tests using runtest.vim. NEW_TESTS_ALOT := test_alot_utf8 test_alot -NEW_TESTS_IN_ALOT := $(shell sed '/^source/ s/^source //;s/\.vim$$//' test_alot*.vim) +NEW_TESTS_IN_ALOT := $(shell sed -n '/^source/ s/^source //; s/\.vim$$//p' $(addsuffix .vim,$(NEW_TESTS_ALOT))) +NEW_TESTS_IN_ALOT_LATIN := $(shell sed -n '/^source/ s/^source //; s/\.vim$$//p' test_alot_latin.vim) # Ignored tests. # test_alot_latin: Nvim does not allow setting encoding. # test_autochdir: ported to Lua, but kept for easier merging. # test_eval_func: used as include in old-style test (test_eval.in). # test_listlbr: Nvim does not allow setting encoding. # test_largefile: uses too much resources to run on CI. -NEW_TESTS_IGNORE := $(NEW_TESTS_IN_ALOT) $(NEW_TESTS_ALOT) \ - test_alot_latin \ +NEW_TESTS_IGNORE := \ + test_alot_latin $(NEW_TESTS_IN_ALOT_LATIN) \ test_autochdir \ test_eval_func \ test_listlbr \ test_largefile \ -NEW_TESTS ?= $(addsuffix .res,$(sort $(filter-out $(NEW_TESTS_IGNORE),$(basename $(notdir $(wildcard test_*.vim))))) $(NEW_TESTS_ALOT)) +NEW_TESTS := $(sort $(basename $(notdir $(wildcard test_*.vim)))) +NEW_TESTS_RES := $(addsuffix .res,$(filter-out $(NEW_TESTS_ALOT) $(NEW_TESTS_IN_ALOT) $(NEW_TESTS_IGNORE),$(NEW_TESTS)) $(NEW_TESTS_ALOT)) ifdef VALGRIND_GDB @@ -112,6 +113,16 @@ fixff: -$(NVIM_PRG) $(NO_INITS) -u unix.vim "+argdo set ff=dos|upd" +q \ dotest.in +# Execute an individual new style test, e.g.: +# make test_largefile +$(NEW_TESTS): + rm -f $@.res test.log messages + @MAKEFLAGS=--no-print-directory $(MAKE) -f Makefile $@.res + @cat messages + @if test -f test.log; then \ + exit 1; \ + fi + RM_ON_RUN := test.out X* viminfo RM_ON_START := test.ok RUN_VIM := $(TOOL) $(NVIM_PRG) -u unix.vim -U NONE -i viminfo --headless --noplugin -s dotest.in @@ -172,7 +183,7 @@ newtests: newtestssilent cat messages && cat test.log; \ fi" -newtestssilent: $(NEW_TESTS) +newtestssilent: $(NEW_TESTS_RES) %.res: %.vim .gdbinit @echo "[OLDTEST] Running" $* diff --git a/src/nvim/testdir/runnvim.sh b/src/nvim/testdir/runnvim.sh index 2dcd9150be..72f9254635 100755 --- a/src/nvim/testdir/runnvim.sh +++ b/src/nvim/testdir/runnvim.sh @@ -82,6 +82,11 @@ main() {( fi if test "$FAILED" = 1 ; then echo "Test $test_name failed, see output above and summary for more details" >> test.log + # When Neovim crashed/aborted it might not have created messages. + # test.log itself is used as an indicator to exit non-zero in the Makefile. + if ! test -f message; then + cp -a test.log messages + fi fi )} diff --git a/src/nvim/testdir/runtest.vim b/src/nvim/testdir/runtest.vim index 593ce6fcdc..2d4134a644 100644 --- a/src/nvim/testdir/runtest.vim +++ b/src/nvim/testdir/runtest.vim @@ -282,18 +282,23 @@ endif " Names of flaky tests. let s:flaky_tests = [ + \ 'Test_autocmd_SafeState()', \ 'Test_cursorhold_insert()', \ 'Test_exit_callback_interval()', \ 'Test_map_timeout_with_timer_interrupt()', \ 'Test_oneshot()', \ 'Test_out_cb()', \ 'Test_paused()', + \ 'Test_popup_and_window_resize()', \ 'Test_quoteplus()', \ 'Test_quotestar()', \ 'Test_reltime()', \ 'Test_repeat_many()', \ 'Test_repeat_three()', + \ 'Test_state()', \ 'Test_stop_all_in_callback()', + \ 'Test_term_mouse_double_click_to_create_tab', + \ 'Test_term_mouse_multiple_clicks_to_visually_select()', \ 'Test_terminal_composing_unicode()', \ 'Test_terminal_redir_file()', \ 'Test_terminal_tmap()', diff --git a/src/nvim/testdir/setup.vim b/src/nvim/testdir/setup.vim index ea28f328ae..d032c9a739 100644 --- a/src/nvim/testdir/setup.vim +++ b/src/nvim/testdir/setup.vim @@ -19,6 +19,7 @@ set sidescroll=0 set tags=./tags,tags set undodir^=. set wildoptions= +set startofline " Prevent Nvim log from writing to stderr. let $NVIM_LOG_FILE = exists($NVIM_LOG_FILE) ? $NVIM_LOG_FILE : 'Xnvim.log' diff --git a/src/nvim/testdir/shared.vim b/src/nvim/testdir/shared.vim index df512e2e3f..3875ffc056 100644 --- a/src/nvim/testdir/shared.vim +++ b/src/nvim/testdir/shared.vim @@ -69,7 +69,8 @@ endfunc " Read the port number from the Xportnr file. func GetPort() let l = [] - for i in range(200) + " with 200 it sometimes failed + for i in range(400) try let l = readfile("Xportnr") catch @@ -135,39 +136,80 @@ endfunc " Wait for up to five seconds for "expr" to become true. "expr" can be a " stringified expression to evaluate, or a funcref without arguments. +" Using a lambda works best. Example: +" call WaitFor({-> status == "ok"}) " " A second argument can be used to specify a different timeout in msec. " -" Return time slept in milliseconds. With the +reltime feature this can be -" more than the actual waiting time. Without +reltime it can also be less. +" When successful the time slept is returned. +" When running into the timeout an exception is thrown, thus the function does +" not return. func WaitFor(expr, ...) let timeout = get(a:000, 0, 5000) + let slept = s:WaitForCommon(a:expr, v:null, timeout) + if slept < 0 + throw 'WaitFor() timed out after ' . timeout . ' msec' + endif + return slept +endfunc + +" Wait for up to five seconds for "assert" to return zero. "assert" must be a +" (lambda) function containing one assert function. Example: +" call WaitForAssert({-> assert_equal("dead", job_status(job)}) +" +" A second argument can be used to specify a different timeout in msec. +" +" Return zero for success, one for failure (like the assert function). +func WaitForAssert(assert, ...) + let timeout = get(a:000, 0, 5000) + if s:WaitForCommon(v:null, a:assert, timeout) < 0 + return 1 + endif + return 0 +endfunc + +" Common implementation of WaitFor() and WaitForAssert(). +" Either "expr" or "assert" is not v:null +" Return the waiting time for success, -1 for failure. +func s:WaitForCommon(expr, assert, timeout) " using reltime() is more accurate, but not always available + let slept = 0 if has('reltime') let start = reltime() - else - let slept = 0 endif - if type(a:expr) == v:t_func - let Test = a:expr - else - let Test = {-> eval(a:expr) } - endif - for i in range(timeout / 10) - if Test() - if has('reltime') - return float2nr(reltimefloat(reltime(start)) * 1000) - endif + + while 1 + if type(a:expr) == v:t_func + let success = a:expr() + elseif type(a:assert) == v:t_func + let success = a:assert() == 0 + else + let success = eval(a:expr) + endif + if success return slept endif - if !has('reltime') - let slept += 10 + + if slept >= a:timeout + break + endif + if type(a:assert) == v:t_func + " Remove the error added by the assert function. + call remove(v:errors, -1) endif + sleep 10m - endfor - throw 'WaitFor() timed out after ' . timeout . ' msec' + if has('reltime') + let slept = float2nr(reltimefloat(reltime(start)) * 1000) + else + let slept += 10 + endif + endwhile + + return -1 " timed out endfunc + " Wait for up to a given milliseconds. " With the +timers feature this waits for key-input by getchar(), Resume() " feeds key-input and resumes process. Return time waited in milliseconds. @@ -211,6 +253,8 @@ func GetVimProg() endif endfunc +let g:valgrind_cnt = 1 + " Get the command to run Vim, with -u NONE and --headless arguments. " If there is an argument use it instead of "NONE". func GetVimCommand(...) @@ -226,14 +270,25 @@ func GetVimCommand(...) endif let cmd .= ' --headless -i NONE' let cmd = substitute(cmd, 'VIMRUNTIME=.*VIMRUNTIME;', '', '') + + " If using valgrind, make sure every run uses a different log file. + if cmd =~ 'valgrind.*--log-file=' + let cmd = substitute(cmd, '--log-file=\(^\s*\)', '--log-file=\1.' . g:valgrind_cnt, '') + let g:valgrind_cnt += 1 + endif + return cmd endfunc -" Get the command to run Vim, with --clean. +" Get the command to run Vim, with --clean instead of "-u NONE". func GetVimCommandClean() let cmd = GetVimCommand() let cmd = substitute(cmd, '-u NONE', '--clean', '') let cmd = substitute(cmd, '--headless', '', '') + + " Optionally run Vim under valgrind + " let cmd = 'valgrind --tool=memcheck --leak-check=yes --num-callers=25 --log-file=valgrind ' . cmd + return cmd endfunc @@ -249,9 +304,6 @@ endfunc func RunVimPiped(before, after, arguments, pipecmd) let $NVIM_LOG_FILE = exists($NVIM_LOG_FILE) ? $NVIM_LOG_FILE : 'Xnvim.log' let cmd = GetVimCommand() - if cmd == '' - return 0 - endif let args = '' if len(a:before) > 0 call writefile(a:before, 'Xbefore.vim') @@ -262,6 +314,9 @@ func RunVimPiped(before, after, arguments, pipecmd) let args .= ' -S Xafter.vim' endif + " Optionally run Vim under valgrind + " let cmd = 'valgrind --tool=memcheck --leak-check=yes --num-callers=25 --log-file=valgrind ' . cmd + exe "silent !" . a:pipecmd . cmd . args . ' ' . a:arguments if len(a:before) > 0 diff --git a/src/nvim/testdir/test42.in b/src/nvim/testdir/test42.in Binary files differindex baa6e67d26..d9057e72fb 100644 --- a/src/nvim/testdir/test42.in +++ b/src/nvim/testdir/test42.in diff --git a/src/nvim/testdir/test48.in b/src/nvim/testdir/test48.in deleted file mode 100644 index 1df5a3c46a..0000000000 --- a/src/nvim/testdir/test48.in +++ /dev/null @@ -1,82 +0,0 @@ -This is a test of 'virtualedit'. - -STARTTEST -:set noswf -:set ve=all -j-dgg -:" -:" Insert "keyword keyw", ESC, C CTRL-N, shows "keyword ykeyword". -:" Repeating CTRL-N fixes it. (Mary Ellen Foster) -2/w -C -:" -:" Using "C" then then <CR> moves the last remaining character to the next -:" line. (Mary Ellen Foster) -j^/are -C
are belong to vim -:" -:" When past the end of a line that ends in a single character "b" skips -:" that word. -^$15lbC7 -:" -:" Make sure 'i' works -$4li<-- should be 3 ' ' -:" -:" Make sure 'C' works -$4lC<-- should be 3 ' ' -:" -:" Make sure 'a' works -$4la<-- should be 4 ' ' -:" -:" Make sure 'A' works -$4lA<-- should be 0 ' ' -:" -:" Make sure 'D' works -$4lDi<-- 'D' should be intact -:" -:" Test for yank bug reported by Mark Waggoner. -:set ve=block -^2w3jyGp -:" -:" Test "r" beyond the end of the line -:set ve=all -/^"r" -$5lrxa<-- should be 'x' -:" -:" Test "r" on a tab -:" Note that for this test, 'ts' must be 8 (the default). -^5lrxA<-- should be ' x ' -:" -:" Test to make sure 'x' can delete control characters -:set display=uhex -^xxxxxxi[This line should contain only the text between the brackets.] -:set display= -:" -:" Test for ^Y/^E due to bad w_virtcol value, reported by -:" Roy <royl@netropolis.net>. -^O3li4li4li <-- should show the name of a noted text editor -^o4li4li4li <-- and its version number-dd -:" -:" Test for yanking and pasting using the small delete register -gg/^foo -dewve"-p -:wq! test.out -ENDTEST -foo, bar -keyword keyw -all your base are belong to us -1 2 3 4 5 6 -'i' -'C' -'a' -'A' -'D' -this is a test -this is a test -this is a test -"r" -"r" -ab
sd -abcv6efi.him0kl - - diff --git a/src/nvim/testdir/test48.ok b/src/nvim/testdir/test48.ok deleted file mode 100644 index 14cd9b12ec..0000000000 --- a/src/nvim/testdir/test48.ok +++ /dev/null @@ -1,23 +0,0 @@ -, foo -keyword keyword -all your base -are belong to vim -1 2 3 4 5 7 -'i' <-- should be 3 ' ' -'C' <-- should be 3 ' ' -'a' <-- should be 4 ' ' -'A'<-- should be 0 ' ' -'D' <-- 'D' should be intact -this is a test -this is a test -this is a test -"r" x<-- should be 'x' -"r" x <-- should be ' x ' -[This line should contain only the text between the brackets.] - v i m <-- should show the name of a noted text editor - 6 . 0 <-- and its version number - -a -a -a - diff --git a/src/nvim/testdir/test49.vim b/src/nvim/testdir/test49.vim index 837e55ebca..fc79f57d2e 100644 --- a/src/nvim/testdir/test49.vim +++ b/src/nvim/testdir/test49.vim @@ -178,7 +178,7 @@ endif " next Xpath value. No new Xnext value is prepared. The argument " should be 2^(n-1) for the nth Xloop command inside the loop. " If the loop has only one Xloop command, the argument can be -" ommitted (default: 1). +" omitted (default: 1). " " - Use XloopNEXT before ":continue" and ":endwhile". This computes a new " Xnext value for the next execution of the loop by multiplying the old diff --git a/src/nvim/testdir/test_alot.vim b/src/nvim/testdir/test_alot.vim index 6bf2e8329c..5668f45dea 100644 --- a/src/nvim/testdir/test_alot.vim +++ b/src/nvim/testdir/test_alot.vim @@ -2,6 +2,7 @@ " This makes testing go faster, since Vim doesn't need to restart. source test_assign.vim +source test_backup.vim source test_behave.vim source test_cd.vim source test_changedtick.vim @@ -27,7 +28,6 @@ source test_jumps.vim source test_fileformat.vim source test_filetype.vim source test_lambda.vim -source test_mapping.vim source test_menu.vim source test_messages.vim source test_modeline.vim @@ -45,6 +45,7 @@ source test_syn_attr.vim source test_tabline.vim source test_tabpage.vim source test_tagcase.vim +source test_tagfunc.vim source test_tagjump.vim source test_taglist.vim source test_true_false.vim diff --git a/src/nvim/testdir/test_assert.vim b/src/nvim/testdir/test_assert.vim index a4c8ce7e43..4cc90eca7a 100644 --- a/src/nvim/testdir/test_assert.vim +++ b/src/nvim/testdir/test_assert.vim @@ -1,5 +1,40 @@ " Test that the methods used for testing work. +func Test_assert_equalfile() + call assert_equal(1, assert_equalfile('abcabc', 'xyzxyz')) + call assert_match("E485: Can't read file abcabc", v:errors[0]) + call remove(v:errors, 0) + + let goodtext = ["one", "two", "three"] + call writefile(goodtext, 'Xone') + call assert_equal(1, assert_equalfile('Xone', 'xyzxyz')) + call assert_match("E485: Can't read file xyzxyz", v:errors[0]) + call remove(v:errors, 0) + + call writefile(goodtext, 'Xtwo') + call assert_equal(0, assert_equalfile('Xone', 'Xtwo')) + + call writefile([goodtext[0]], 'Xone') + call assert_equal(1, assert_equalfile('Xone', 'Xtwo')) + call assert_match("first file is shorter", v:errors[0]) + call remove(v:errors, 0) + + call writefile(goodtext, 'Xone') + call writefile([goodtext[0]], 'Xtwo') + call assert_equal(1, assert_equalfile('Xone', 'Xtwo')) + call assert_match("second file is shorter", v:errors[0]) + call remove(v:errors, 0) + + call writefile(['1234X89'], 'Xone') + call writefile(['1234Y89'], 'Xtwo') + call assert_equal(1, assert_equalfile('Xone', 'Xtwo')) + call assert_match("difference at byte 4", v:errors[0]) + call remove(v:errors, 0) + + call delete('Xone') + call delete('Xtwo') +endfunc + func Test_assert_fails_in_try_block() try call assert_equal(0, assert_fails('throw "error"')) diff --git a/src/nvim/testdir/test_autocmd.vim b/src/nvim/testdir/test_autocmd.vim index 5848940a2b..275b053bc9 100644 --- a/src/nvim/testdir/test_autocmd.vim +++ b/src/nvim/testdir/test_autocmd.vim @@ -425,18 +425,20 @@ func Test_autocmd_bufwipe_in_SessLoadPost() set noswapfile mksession! - let content = ['set nocp noswapfile', - \ 'let v:swapchoice="e"', - \ 'augroup test_autocmd_sessionload', - \ 'autocmd!', - \ 'autocmd SessionLoadPost * exe bufnr("Xsomething") . "bw!"', - \ 'augroup END', - \ '', - \ 'func WriteErrors()', - \ ' call writefile([execute("messages")], "Xerrors")', - \ 'endfunc', - \ 'au VimLeave * call WriteErrors()', - \ ] + let content =<< trim [CODE] + set nocp noswapfile + let v:swapchoice="e" + augroup test_autocmd_sessionload + autocmd! + autocmd SessionLoadPost * exe bufnr("Xsomething") . "bw!" + augroup END + + func WriteErrors() + call writefile([execute("messages")], "Xerrors") + endfunc + au VimLeave * call WriteErrors() + [CODE] + call writefile(content, 'Xvimrc') call system(v:progpath. ' --headless -i NONE -u Xvimrc --noplugins -S Session.vim -c cq') let errors = join(readfile('Xerrors')) @@ -454,27 +456,29 @@ func Test_autocmd_bufwipe_in_SessLoadPost2() set noswapfile mksession! - let content = ['set nocp noswapfile', - \ 'function! DeleteInactiveBufs()', - \ ' tabfirst', - \ ' let tabblist = []', - \ ' for i in range(1, tabpagenr(''$''))', - \ ' call extend(tabblist, tabpagebuflist(i))', - \ ' endfor', - \ ' for b in range(1, bufnr(''$''))', - \ ' if bufexists(b) && buflisted(b) && (index(tabblist, b) == -1 || bufname(b) =~# ''^$'')', - \ ' exec ''bwipeout '' . b', - \ ' endif', - \ ' endfor', - \ ' echomsg "SessionLoadPost DONE"', - \ 'endfunction', - \ 'au SessionLoadPost * call DeleteInactiveBufs()', - \ '', - \ 'func WriteErrors()', - \ ' call writefile([execute("messages")], "Xerrors")', - \ 'endfunc', - \ 'au VimLeave * call WriteErrors()', - \ ] + let content =<< trim [CODE] + set nocp noswapfile + function! DeleteInactiveBufs() + tabfirst + let tabblist = [] + for i in range(1, tabpagenr(''$'')) + call extend(tabblist, tabpagebuflist(i)) + endfor + for b in range(1, bufnr(''$'')) + if bufexists(b) && buflisted(b) && (index(tabblist, b) == -1 || bufname(b) =~# ''^$'') + exec ''bwipeout '' . b + endif + endfor + echomsg "SessionLoadPost DONE" + endfunction + au SessionLoadPost * call DeleteInactiveBufs() + + func WriteErrors() + call writefile([execute("messages")], "Xerrors") + endfunc + au VimLeave * call WriteErrors() + [CODE] + call writefile(content, 'Xvimrc') call system(v:progpath. ' --headless -i NONE -u Xvimrc --noplugins -S Session.vim -c cq') let errors = join(readfile('Xerrors')) @@ -936,21 +940,23 @@ func Test_bufunload_all() call writefile(['Test file Xxx1'], 'Xxx1')" call writefile(['Test file Xxx2'], 'Xxx2')" - let content = [ - \ "func UnloadAllBufs()", - \ " let i = 1", - \ " while i <= bufnr('$')", - \ " if i != bufnr('%') && bufloaded(i)", - \ " exe i . 'bunload'", - \ " endif", - \ " let i += 1", - \ " endwhile", - \ "endfunc", - \ "au BufUnload * call UnloadAllBufs()", - \ "au VimLeave * call writefile(['Test Finished'], 'Xout')", - \ "edit Xxx1", - \ "split Xxx2", - \ "q"] + let content =<< trim [CODE] + func UnloadAllBufs() + let i = 1 + while i <= bufnr('$') + if i != bufnr('%') && bufloaded(i) + exe i . 'bunload' + endif + let i += 1 + endwhile + endfunc + au BufUnload * call UnloadAllBufs() + au VimLeave * call writefile(['Test Finished'], 'Xout') + edit Xxx1 + split Xxx2 + q + [CODE] + call writefile(content, 'Xtest') call delete('Xout') @@ -1344,11 +1350,11 @@ func Test_Changed_FirstTime() let buf = term_start([GetVimProg(), '--clean', '-c', 'set noswapfile'], {'term_rows': 3}) call assert_equal('running', term_getstatus(buf)) " Wait for the ruler (in the status line) to be shown. - call WaitFor({-> term_getline(buf, 3) =~# '\<All$'}) + call WaitForAssert({-> assert_match('\<All$', term_getline(buf, 3))}) " It's only adding autocmd, so that no event occurs. call term_sendkeys(buf, ":au! TextChanged <buffer> call writefile(['No'], 'Xchanged.txt')\<cr>") call term_sendkeys(buf, "\<C-\\>\<C-N>:qa!\<cr>") - call WaitFor({-> term_getstatus(buf) == 'finished'}) + call WaitForAssert({-> assert_equal('finished', term_getstatus(buf))}) call assert_equal([''], readfile('Xchanged.txt')) " clean up diff --git a/src/nvim/testdir/test_backup.vim b/src/nvim/testdir/test_backup.vim new file mode 100644 index 0000000000..fa10430613 --- /dev/null +++ b/src/nvim/testdir/test_backup.vim @@ -0,0 +1,58 @@ +" Tests for the backup function + +func Test_backup() + set backup backupdir=. + new + call setline(1, ['line1', 'line2']) + :f Xbackup.txt + :w! Xbackup.txt + " backup file is only created after + " writing a second time (before overwriting) + :w! Xbackup.txt + let l = readfile('Xbackup.txt~') + call assert_equal(['line1', 'line2'], l) + bw! + set backup&vim backupdir&vim + call delete('Xbackup.txt') + call delete('Xbackup.txt~') +endfunc + +func Test_backup2() + set backup backupdir=.// + new + call setline(1, ['line1', 'line2', 'line3']) + :f Xbackup.txt + :w! Xbackup.txt + " backup file is only created after + " writing a second time (before overwriting) + :w! Xbackup.txt + sp *Xbackup.txt~ + call assert_equal(['line1', 'line2', 'line3'], getline(1,'$')) + let f=expand('%') + call assert_match('src%nvim%testdir%Xbackup.txt\~', f) + bw! + bw! + call delete('Xbackup.txt') + call delete(f) + set backup&vim backupdir&vim +endfunc + +func Test_backup2_backupcopy() + set backup backupdir=.// backupcopy=yes + new + call setline(1, ['line1', 'line2', 'line3']) + :f Xbackup.txt + :w! Xbackup.txt + " backup file is only created after + " writing a second time (before overwriting) + :w! Xbackup.txt + sp *Xbackup.txt~ + call assert_equal(['line1', 'line2', 'line3'], getline(1,'$')) + let f=expand('%') + call assert_match('src%nvim%testdir%Xbackup.txt\~', f) + bw! + bw! + call delete('Xbackup.txt') + call delete(f) + set backup&vim backupdir&vim backupcopy&vim +endfunc diff --git a/src/nvim/testdir/test_cindent.vim b/src/nvim/testdir/test_cindent.vim index 7c2c5e341c..d9795d9335 100644 --- a/src/nvim/testdir/test_cindent.vim +++ b/src/nvim/testdir/test_cindent.vim @@ -18,25 +18,25 @@ endfunc func Test_cino_extern_c() " Test for cino-E - let without_ind = [ - \ '#ifdef __cplusplus', - \ 'extern "C" {', - \ '#endif', - \ 'int func_a(void);', - \ '#ifdef __cplusplus', - \ '}', - \ '#endif' - \ ] + let without_ind =<< trim [CODE] + #ifdef __cplusplus + extern "C" { + #endif + int func_a(void); + #ifdef __cplusplus + } + #endif + [CODE] - let with_ind = [ - \ '#ifdef __cplusplus', - \ 'extern "C" {', - \ '#endif', - \ "\tint func_a(void);", - \ '#ifdef __cplusplus', - \ '}', - \ '#endif' - \ ] + let with_ind =<< trim [CODE] + #ifdef __cplusplus + extern "C" { + #endif + int func_a(void); + #ifdef __cplusplus + } + #endif + [CODE] new setlocal cindent cinoptions=E0 call setline(1, without_ind) @@ -89,16 +89,32 @@ func Test_cindent_expr() return v:lnum == 1 ? shiftwidth() : 0 endfunc setl expandtab sw=8 indentkeys+=; indentexpr=MyIndentFunction() - call setline(1, ['var_a = something()', 'b = something()']) + let testinput =<< trim [CODE] + var_a = something() + b = something() + [CODE] + call setline(1, testinput) call cursor(1, 1) call feedkeys("^\<c-v>j$A;\<esc>", 'tnix') - call assert_equal([' var_a = something();', 'b = something();'], getline(1, '$')) + let expected =<< [CODE] + var_a = something(); +b = something(); +[CODE] + call assert_equal(expected, getline(1, '$')) %d - call setline(1, [' var_a = something()', ' b = something()']) + let testinput =<< [CODE] + var_a = something() + b = something() +[CODE] + call setline(1, testinput) call cursor(1, 1) call feedkeys("^\<c-v>j$A;\<esc>", 'tnix') - call assert_equal([' var_a = something();', ' b = something()'], getline(1, '$')) + let expected =<< [CODE] + var_a = something(); + b = something() +[CODE] + call assert_equal(expected, getline(1, '$')) bw! endfunc diff --git a/src/nvim/testdir/test_clientserver.vim b/src/nvim/testdir/test_clientserver.vim index 813cb338a5..3377f86126 100644 --- a/src/nvim/testdir/test_clientserver.vim +++ b/src/nvim/testdir/test_clientserver.vim @@ -28,12 +28,11 @@ func Test_client_server() let name = 'XVIMTEST' let cmd .= ' --servername ' . name let job = job_start(cmd, {'stoponexit': 'kill', 'out_io': 'null'}) - call WaitFor({-> job_status(job) == "run"}) + call WaitForAssert({-> assert_equal("run", job_status(job))}) " Takes a short while for the server to be active. " When using valgrind it takes much longer. - call WaitFor('serverlist() =~ "' . name . '"') - call assert_match(name, serverlist()) + call WaitForAssert({-> assert_match(name, serverlist())}) call remote_foreground(name) @@ -54,12 +53,10 @@ func Test_client_server() endif " Wait for the server to be up and answering requests. sleep 100m - call WaitFor('remote_expr("' . name . '", "v:version", "", 1) != ""') - call assert_true(remote_expr(name, "v:version", "", 1) != "") + call WaitForAssert({-> assert_true(remote_expr(name, "v:version", "", 1) != "")}) call remote_send(name, ":let testvar = 'maybe'\<CR>") - call WaitFor('remote_expr("' . name . '", "testvar", "", 1) == "maybe"') - call assert_equal('maybe', remote_expr(name, "testvar", "", 2)) + call WaitForAssert({-> assert_equal('maybe', remote_expr(name, "testvar", "", 2))}) endif call assert_fails('call remote_send("XXX", ":let testvar = ''yes''\<CR>")', 'E241') @@ -94,7 +91,7 @@ func Test_client_server() call remote_send(name, ":qa!\<CR>") try - call WaitFor({-> job_status(job) == "dead"}) + call WaitForAssert({-> assert_equal("dead", job_status(job))}) finally if job_status(job) != 'dead' call assert_report('Server did not exit') diff --git a/src/nvim/testdir/test_cmdline.vim b/src/nvim/testdir/test_cmdline.vim index e6aafd964b..9c3c33a943 100644 --- a/src/nvim/testdir/test_cmdline.vim +++ b/src/nvim/testdir/test_cmdline.vim @@ -1,6 +1,5 @@ " Tests for editing the command line. - func Test_complete_tab() call writefile(['testfile'], 'Xtestfile') call feedkeys(":e Xtestf\t\r", "tx") @@ -79,26 +78,45 @@ func Test_map_completion() call feedkeys(":map <silent> <sp\<Tab>\<Home>\"\<CR>", 'xt') call assert_equal('"map <silent> <special>', getreg(':')) + map <Middle>x middle + map ,f commaf map ,g commaf + map <Left> left + map <A-Left>x shiftleft call feedkeys(":map ,\<Tab>\<Home>\"\<CR>", 'xt') call assert_equal('"map ,f', getreg(':')) call feedkeys(":map ,\<Tab>\<Tab>\<Home>\"\<CR>", 'xt') call assert_equal('"map ,g', getreg(':')) + call feedkeys(":map <L\<Tab>\<Home>\"\<CR>", 'xt') + call assert_equal('"map <Left>', getreg(':')) + call feedkeys(":map <A-Left>\<Tab>\<Home>\"\<CR>", 'xt') + call assert_equal("\"map <A-Left>\<Tab>", getreg(':')) unmap ,f unmap ,g + unmap <Left> + unmap <A-Left>x set cpo-=< cpo-=B cpo-=k map <Left> left call feedkeys(":map <L\<Tab>\<Home>\"\<CR>", 'xt') call assert_equal('"map <Left>', getreg(':')) + call feedkeys(":map <M\<Tab>\<Home>\"\<CR>", 'xt') + " call assert_equal("\"map <M\<Tab>", getreg(':')) unmap <Left> " set cpo+=< map <Left> left + exe "set t_k6=\<Esc>[17~" + call feedkeys(":map \<Esc>[17~x f6x\<CR>", 'xt') call feedkeys(":map <L\<Tab>\<Home>\"\<CR>", 'xt') call assert_equal('"map <Left>', getreg(':')) + if !has('gui_running') + call feedkeys(":map \<Esc>[17~\<Tab>\<Home>\"\<CR>", 'xt') + " call assert_equal("\"map <F6>x", getreg(':')) + endif unmap <Left> + call feedkeys(":unmap \<Esc>[17~x\<CR>", 'xt') set cpo-=< set cpo+=B @@ -114,6 +132,9 @@ func Test_map_completion() call assert_equal('"map <Left>', getreg(':')) unmap <Left> " set cpo-=k + + unmap <Middle>x + set cpo&vim endfunc func Test_match_completion() @@ -160,6 +181,7 @@ func Test_expr_completion() endif for cmd in [ \ 'let a = ', + \ 'const a = ', \ 'if', \ 'elseif', \ 'while', @@ -302,7 +324,7 @@ func Test_getcompletion() call assert_equal([], l) let l = getcompletion('.', 'shellcmd') - call assert_equal(['./', '../'], l[0:1]) + call assert_equal(['./', '../'], filter(l, 'v:val =~ "\\./"')) call assert_equal(-1, match(l[2:], '^\.\.\?/$')) let root = has('win32') ? 'C:\\' : '/' let l = getcompletion(root, 'shellcmd') @@ -376,6 +398,29 @@ func Test_getcompletion() call assert_fails('call getcompletion("", "burp")', 'E475:') endfunc +func Test_shellcmd_completion() + let save_path = $PATH + + call mkdir('Xpathdir/Xpathsubdir', 'p') + call writefile([''], 'Xpathdir/Xfile.exe') + call setfperm('Xpathdir/Xfile.exe', 'rwx------') + + " Set PATH to example directory without trailing slash. + let $PATH = getcwd() . '/Xpathdir' + + " Test for the ":!<TAB>" case. Previously, this would include subdirs of + " dirs in the PATH, even though they won't be executed. We check that only + " subdirs of the PWD and executables from the PATH are included in the + " suggestions. + let actual = getcompletion('X', 'shellcmd') + let expected = map(filter(glob('*', 0, 1), 'isdirectory(v:val) && v:val[0] == "X"'), 'v:val . "/"') + call insert(expected, 'Xfile.exe') + call assert_equal(expected, actual) + + call delete('Xpathdir', 'rf') + let $PATH = save_path +endfunc + func Test_expand_star_star() call mkdir('a/b', 'p') call writefile(['asdfasdf'], 'a/b/fileXname') @@ -477,6 +522,51 @@ func Test_cmdline_complete_user_cmd() delcommand Foo endfunc +func Test_cmdline_complete_user_names() + if has('unix') && executable('whoami') + let whoami = systemlist('whoami')[0] + let first_letter = whoami[0] + if len(first_letter) > 0 + " Trying completion of :e ~x where x is the first letter of + " the user name should complete to at least the user name. + call feedkeys(':e ~' . first_letter . "\<c-a>\<c-B>\"\<cr>", 'tx') + call assert_match('^"e \~.*\<' . whoami . '\>', @:) + endif + endif + if has('win32') + " Just in case: check that the system has an Administrator account. + let names = system('net user') + if names =~ 'Administrator' + " Trying completion of :e ~A should complete to Administrator. + " There could be other names starting with "A" before Administrator. + call feedkeys(':e ~A' . "\<c-a>\<c-B>\"\<cr>", 'tx') + call assert_match('^"e \~.*Administrator', @:) + endif + endif +endfunc + +funct Test_cmdline_complete_languages() + let lang = substitute(execute('language messages'), '.*"\(.*\)"$', '\1', '') + + call feedkeys(":language \<c-a>\<c-b>\"\<cr>", 'tx') + call assert_match('^"language .*\<ctype\>.*\<messages\>.*\<time\>', @:) + + if has('unix') + " TODO: these tests don't work on Windows. lang appears to be 'C' + " but C does not appear in the completion. Why? + call assert_match('^"language .*\<' . lang . '\>', @:) + + call feedkeys(":language messages \<c-a>\<c-b>\"\<cr>", 'tx') + call assert_match('^"language .*\<' . lang . '\>', @:) + + call feedkeys(":language ctype \<c-a>\<c-b>\"\<cr>", 'tx') + call assert_match('^"language .*\<' . lang . '\>', @:) + + call feedkeys(":language time \<c-a>\<c-b>\"\<cr>", 'tx') + call assert_match('^"language .*\<' . lang . '\>', @:) + endif +endfunc + func Test_cmdline_write_alternatefile() new call setline('.', ['one', 'two']) @@ -529,6 +619,8 @@ func Check_cmdline(cmdtype) return '' endfunc +set cpo& + func Test_getcmdtype() call feedkeys(":MyCmd a\<C-R>=Check_cmdline(':')\<CR>\<Esc>", "xt") @@ -569,6 +661,37 @@ func Test_getcmdwintype() call assert_equal('', getcmdwintype()) endfunc +func Test_getcmdwin_autocmd() + let s:seq = [] + augroup CmdWin + au WinEnter * call add(s:seq, 'WinEnter ' .. win_getid()) + au WinLeave * call add(s:seq, 'WinLeave ' .. win_getid()) + au BufEnter * call add(s:seq, 'BufEnter ' .. bufnr()) + au BufLeave * call add(s:seq, 'BufLeave ' .. bufnr()) + au CmdWinEnter * call add(s:seq, 'CmdWinEnter ' .. win_getid()) + au CmdWinLeave * call add(s:seq, 'CmdWinLeave ' .. win_getid()) + + let org_winid = win_getid() + let org_bufnr = bufnr() + call feedkeys("q::let a = getcmdwintype()\<CR>:let s:cmd_winid = win_getid()\<CR>:let s:cmd_bufnr = bufnr()\<CR>:q\<CR>", 'x!') + call assert_equal(':', a) + call assert_equal([ + \ 'WinLeave ' .. org_winid, + \ 'WinEnter ' .. s:cmd_winid, + \ 'BufLeave ' .. org_bufnr, + \ 'BufEnter ' .. s:cmd_bufnr, + \ 'CmdWinEnter ' .. s:cmd_winid, + \ 'CmdWinLeave ' .. s:cmd_winid, + \ 'BufLeave ' .. s:cmd_bufnr, + \ 'WinLeave ' .. s:cmd_winid, + \ 'WinEnter ' .. org_winid, + \ 'BufEnter ' .. org_bufnr, + \ ], s:seq) + + au! + augroup END +endfunc + func Test_verbosefile() set verbosefile=Xlog echomsg 'foo' @@ -628,4 +751,7 @@ func Test_cmdline_overstrike() let &encoding = encoding_save endfunc -set cpo& +func Test_cmdwin_feedkeys() + " This should not generate E488 + call feedkeys("q:\<CR>", 'x') +endfunc diff --git a/src/nvim/testdir/test_compiler.vim b/src/nvim/testdir/test_compiler.vim index 46c14d8bc3..40d3cdbdae 100644 --- a/src/nvim/testdir/test_compiler.vim +++ b/src/nvim/testdir/test_compiler.vim @@ -10,6 +10,10 @@ func Test_compiler() unlet $LANG endif + " %:S does not work properly with 'shellslash' set + let save_shellslash = &shellslash + set noshellslash + e Xfoo.pl compiler perl call assert_equal('perl', b:current_compiler) @@ -24,9 +28,11 @@ func Test_compiler() w! call feedkeys(":make\<CR>\<CR>", 'tx') let a=execute('clist') - call assert_match("\n 1 Xfoo.pl:3: Global symbol \"\$foo\" " - \ . "requires explicit package name", a) + call assert_match('\n \d\+ Xfoo.pl:3: Global symbol "$foo" ' + \ . 'requires explicit package name', a) + + let &shellslash = save_shellslash call delete('Xfoo.pl') bw! endfunc diff --git a/src/nvim/testdir/test_const.vim b/src/nvim/testdir/test_const.vim index 06062c5e58..eaf200e9bb 100644 --- a/src/nvim/testdir/test_const.vim +++ b/src/nvim/testdir/test_const.vim @@ -176,6 +176,26 @@ func Test_cannot_modify_existing_variable() call assert_fails('const [i2, f2, s2] = [1, 1.1, "vim"]', 'E995:') endfunc +func Test_const_with_condition() + const x = 0 + if 0 | const x = 1 | endif + call assert_equal(0, x) +endfunc + +func Test_lockvar() + let x = 'hello' + lockvar x + call assert_fails('let x = "there"', 'E741') + if 0 | unlockvar x | endif + call assert_fails('let x = "there"', 'E741') + unlockvar x + let x = 'there' + + if 0 | lockvar x | endif + let x = 'again' +endfunc + + func Test_const_with_index_access() let l = [1, 2, 3] call assert_fails('const l[0] = 4', 'E996:') diff --git a/src/nvim/testdir/test_debugger.vim b/src/nvim/testdir/test_debugger.vim index 3ef460b4fe..130bcf8910 100644 --- a/src/nvim/testdir/test_debugger.vim +++ b/src/nvim/testdir/test_debugger.vim @@ -26,27 +26,29 @@ func Test_Debugger() endif " Create a Vim script with some functions - call writefile([ - \ 'func Foo()', - \ ' let var1 = 1', - \ ' let var2 = Bar(var1) + 9', - \ ' return var2', - \ 'endfunc', - \ 'func Bar(var)', - \ ' let var1 = 2 + a:var', - \ ' let var2 = Bazz(var1) + 4', - \ ' return var2', - \ 'endfunc', - \ 'func Bazz(var)', - \ ' try', - \ ' let var1 = 3 + a:var', - \ ' let var3 = "another var"', - \ ' let var3 = "value2"', - \ ' catch', - \ ' let var4 = "exception"', - \ ' endtry', - \ ' return var1', - \ 'endfunc'], 'Xtest.vim') + let lines =<< trim END + func Foo() + let var1 = 1 + let var2 = Bar(var1) + 9 + return var2 + endfunc + func Bar(var) + let var1 = 2 + a:var + let var2 = Bazz(var1) + 4 + return var2 + endfunc + func Bazz(var) + try + let var1 = 3 + a:var + let var3 = "another var" + let var3 = "value2" + catch + let var4 = "exception" + endtry + return var1 + endfunc + END + call writefile(lines, 'Xtest.vim') " Start Vim in a terminal let buf = RunVimInTerminal('-S Xtest.vim', {}) @@ -294,11 +296,13 @@ func Test_Debugger() " Tests for :breakadd file and :breakadd here " Breakpoints should be set before sourcing the file - call writefile([ - \ 'let var1 = 10', - \ 'let var2 = 20', - \ 'let var3 = 30', - \ 'let var4 = 40'], 'Xtest.vim') + let lines =<< trim END + let var1 = 10 + let var2 = 20 + let var3 = 30 + let var4 = 40 + END + call writefile(lines, 'Xtest.vim') " Start Vim in a terminal let buf = RunVimInTerminal('Xtest.vim', {}) diff --git a/src/nvim/testdir/test_diffmode.vim b/src/nvim/testdir/test_diffmode.vim index 57b19aa817..21e0271bda 100644 --- a/src/nvim/testdir/test_diffmode.vim +++ b/src/nvim/testdir/test_diffmode.vim @@ -773,3 +773,28 @@ func Test_diff_of_diff() call StopVimInTerminal(buf) call delete('Xtest_diff_diff') endfunc + +func CloseoffSetup() + enew + call setline(1, ['one', 'two', 'three']) + diffthis + new + call setline(1, ['one', 'tow', 'three']) + diffthis + call assert_equal(1, &diff) + only! +endfunc + +func Test_diff_closeoff() + " "closeoff" included by default: last diff win gets 'diff' reset' + call CloseoffSetup() + call assert_equal(0, &diff) + enew! + + " "closeoff" excluded: last diff win keeps 'diff' set' + set diffopt-=closeoff + call CloseoffSetup() + call assert_equal(1, &diff) + diffoff! + enew! +endfunc diff --git a/src/nvim/testdir/test_digraph.vim b/src/nvim/testdir/test_digraph.vim index 62a5da33df..5da05e85b5 100644 --- a/src/nvim/testdir/test_digraph.vim +++ b/src/nvim/testdir/test_digraph.vim @@ -465,4 +465,17 @@ func Test_show_digraph() bwipe! endfunc +func Test_show_digraph_cp1251() + throw 'skipped: Nvim supports ''utf8'' encoding only' + if !has('multi_byte') + return + endif + new + set encoding=cp1251 + call Put_Dig("='") + call assert_equal("\n<\xfa> <|z> <M-z> 250, Hex fa, Oct 372, Digr ='", execute('ascii')) + set encoding=utf-8 + bwipe! +endfunc + " vim: shiftwidth=2 sts=2 expandtab diff --git a/src/nvim/testdir/test_display.vim b/src/nvim/testdir/test_display.vim index 5feb59eef1..1c2f5a05ff 100644 --- a/src/nvim/testdir/test_display.vim +++ b/src/nvim/testdir/test_display.vim @@ -69,3 +69,59 @@ func! Test_display_foldtext_mbyte() set foldtext& fillchars& foldmethod& fdc& bw! endfunc + +func Test_display_listchars_precedes() + set fillchars+=vert:\| + call NewWindow(10, 10) + " Need a physical line that wraps over the complete + " window size + call append(0, repeat('aaa aaa aa ', 10)) + call append(1, repeat(['bbb bbb bbb bbb'], 2)) + " remove blank trailing line + $d + set list nowrap + call cursor(1, 1) + " move to end of line and scroll 2 characters back + norm! $2zh + let lines=ScreenLines([1,4], winwidth(0)+1) + let expect = [ + \ " aaa aa $ |", + \ "$ |", + \ "$ |", + \ "~ |", + \ ] + call assert_equal(expect, lines) + set list listchars+=precedes:< nowrap + call cursor(1, 1) + " move to end of line and scroll 2 characters back + norm! $2zh + let lines = ScreenLines([1,4], winwidth(0)+1) + let expect = [ + \ "<aaa aa $ |", + \ "< |", + \ "< |", + \ "~ |", + \ ] + call assert_equal(expect, lines) + set wrap + call cursor(1, 1) + " the complete line should be displayed in the window + norm! $ + + let lines = ScreenLines([1,10], winwidth(0)+1) + let expect = [ + \ "<aaa aaa a|", + \ "a aaa aaa |", + \ "aa aaa aaa|", + \ " aa aaa aa|", + \ "a aa aaa a|", + \ "aa aa aaa |", + \ "aaa aa aaa|", + \ " aaa aa aa|", + \ "a aaa aa a|", + \ "aa aaa aa |", + \ ] + call assert_equal(expect, lines) + set list& listchars& wrap& + bw! +endfunc diff --git a/src/nvim/testdir/test_exit.vim b/src/nvim/testdir/test_exit.vim index 8f02fd29e3..99a401d4a4 100644 --- a/src/nvim/testdir/test_exit.vim +++ b/src/nvim/testdir/test_exit.vim @@ -3,52 +3,78 @@ source shared.vim func Test_exiting() - let after = [ - \ 'au QuitPre * call writefile(["QuitPre"], "Xtestout")', - \ 'au ExitPre * call writefile(["ExitPre"], "Xtestout", "a")', - \ 'quit', - \ ] + let after =<< trim [CODE] + au QuitPre * call writefile(["QuitPre"], "Xtestout") + au ExitPre * call writefile(["ExitPre"], "Xtestout", "a") + quit + [CODE] + if RunVim([], after, '') call assert_equal(['QuitPre', 'ExitPre'], readfile('Xtestout')) endif call delete('Xtestout') - let after = [ - \ 'au QuitPre * call writefile(["QuitPre"], "Xtestout")', - \ 'au ExitPre * call writefile(["ExitPre"], "Xtestout", "a")', - \ 'help', - \ 'wincmd w', - \ 'quit', - \ ] + let after =<< trim [CODE] + au QuitPre * call writefile(["QuitPre"], "Xtestout") + au ExitPre * call writefile(["ExitPre"], "Xtestout", "a") + help + wincmd w + quit + [CODE] + if RunVim([], after, '') call assert_equal(['QuitPre', 'ExitPre'], readfile('Xtestout')) endif call delete('Xtestout') - let after = [ - \ 'au QuitPre * call writefile(["QuitPre"], "Xtestout")', - \ 'au ExitPre * call writefile(["ExitPre"], "Xtestout", "a")', - \ 'split', - \ 'new', - \ 'qall', - \ ] + let after =<< trim [CODE] + au QuitPre * call writefile(["QuitPre"], "Xtestout") + au ExitPre * call writefile(["ExitPre"], "Xtestout", "a") + split + new + qall + [CODE] + if RunVim([], after, '') call assert_equal(['QuitPre', 'ExitPre'], readfile('Xtestout')) endif call delete('Xtestout') - let after = [ - \ 'au QuitPre * call writefile(["QuitPre"], "Xtestout", "a")', - \ 'au ExitPre * call writefile(["ExitPre"], "Xtestout", "a")', - \ 'augroup nasty', - \ ' au ExitPre * split', - \ 'augroup END', - \ 'quit', - \ 'augroup nasty', - \ ' au! ExitPre', - \ 'augroup END', - \ 'quit', - \ ] + " ExitPre autocommand splits the window, so that it's no longer the last one. + let after =<< trim [CODE] + au QuitPre * call writefile(["QuitPre"], "Xtestout", "a") + au ExitPre * call writefile(["ExitPre"], "Xtestout", "a") + augroup nasty + au ExitPre * split + augroup END + quit + augroup nasty + au! ExitPre + augroup END + quit + [CODE] + + if RunVim([], after, '') + call assert_equal(['QuitPre', 'ExitPre', 'QuitPre', 'ExitPre'], + \ readfile('Xtestout')) + endif + call delete('Xtestout') + + " ExitPre autocommand splits and closes the window, so that there is still + " one window but it's a different one. + let after =<< trim [CODE] + au QuitPre * call writefile(["QuitPre"], "Xtestout", "a") + au ExitPre * call writefile(["ExitPre"], "Xtestout", "a") + augroup nasty + au ExitPre * split | only + augroup END + quit + augroup nasty + au! ExitPre + augroup END + quit + [CODE] + if RunVim([], after, '') call assert_equal(['QuitPre', 'ExitPre', 'QuitPre', 'ExitPre'], \ readfile('Xtestout')) diff --git a/src/nvim/testdir/test_expr.vim b/src/nvim/testdir/test_expr.vim index 4f99625e73..dd546dbf71 100644 --- a/src/nvim/testdir/test_expr.vim +++ b/src/nvim/testdir/test_expr.vim @@ -279,6 +279,9 @@ function Test_printf_misc() call assert_equal('abc ', printf('%-4s', 'abc')) call assert_equal('abc ', printf('%-4S', 'abc')) + call assert_equal('🐍', printf('%.2S', '🐍🐍')) + call assert_equal('', printf('%.1S', '🐍🐍')) + call assert_equal('1%', printf('%d%%', 1)) endfunc diff --git a/src/nvim/testdir/test_filetype.vim b/src/nvim/testdir/test_filetype.vim index 7512d599b8..e085f58e56 100644 --- a/src/nvim/testdir/test_filetype.vim +++ b/src/nvim/testdir/test_filetype.vim @@ -122,6 +122,7 @@ let s:filename_checks = { \ 'cvs': ['cvs123'], \ 'cvsrc': ['.cvsrc'], \ 'cynpp': ['file.cyn'], + \ 'dart': ['file.dart', 'file.drt'], \ 'datascript': ['file.ds'], \ 'dcd': ['file.dcd'], \ 'debcontrol': ['/debian/control'], @@ -201,6 +202,7 @@ let s:filename_checks = { \ 'hex': ['file.hex', 'file.h32'], \ 'hgcommit': ['hg-editor-file.txt'], \ 'hog': ['file.hog', 'snort.conf', 'vision.conf'], + \ 'hollywood': ['file.hws'], \ 'hostconf': ['/etc/host.conf'], \ 'hostsaccess': ['/etc/hosts.allow', '/etc/hosts.deny'], \ 'template': ['file.tmpl'], @@ -221,7 +223,7 @@ let s:filename_checks = { \ 'jam': ['file.jpl', 'file.jpr'], \ 'java': ['file.java', 'file.jav'], \ 'javacc': ['file.jj', 'file.jjt'], - \ 'javascript': ['file.js', 'file.javascript', 'file.es', 'file.mjs'], + \ 'javascript': ['file.js', 'file.javascript', 'file.es', 'file.mjs', 'file.cjs'], \ 'javascriptreact': ['file.jsx'], \ 'jess': ['file.clp'], \ 'jgraph': ['file.jgr'], @@ -273,6 +275,7 @@ let s:filename_checks = { \ 'mason': ['file.mason', 'file.mhtml', 'file.comp'], \ 'master': ['file.mas', 'file.master'], \ 'mel': ['file.mel'], + \ 'meson': ['meson.build', 'meson_options.txt'], \ 'messages': ['/log/auth', '/log/cron', '/log/daemon', '/log/debug', '/log/kern', '/log/lpr', '/log/mail', '/log/messages', '/log/news/news', '/log/syslog', '/log/user', \ '/log/auth.log', '/log/cron.log', '/log/daemon.log', '/log/debug.log', '/log/kern.log', '/log/lpr.log', '/log/mail.log', '/log/messages.log', '/log/news/news.log', '/log/syslog.log', '/log/user.log', \ '/log/auth.err', '/log/cron.err', '/log/daemon.err', '/log/debug.err', '/log/kern.err', '/log/lpr.err', '/log/mail.err', '/log/messages.err', '/log/news/news.err', '/log/syslog.err', '/log/user.err', diff --git a/src/nvim/testdir/test_fnamemodify.vim b/src/nvim/testdir/test_fnamemodify.vim new file mode 100644 index 0000000000..116d23ba88 --- /dev/null +++ b/src/nvim/testdir/test_fnamemodify.vim @@ -0,0 +1,75 @@ +" Test filename modifiers. + +func Test_fnamemodify() + let save_home = $HOME + let save_shell = &shell + let $HOME = fnamemodify('.', ':p:h:h') + set shell=sh + + call assert_equal('/', fnamemodify('.', ':p')[-1:]) + call assert_equal('r', fnamemodify('.', ':p:h')[-1:]) + call assert_equal('t', fnamemodify('test.out', ':p')[-1:]) + call assert_equal('test.out', fnamemodify('test.out', ':.')) + call assert_equal('a', fnamemodify('../testdir/a', ':.')) + call assert_equal('~/testdir/test.out', fnamemodify('test.out', ':~')) + call assert_equal('~/testdir/a', fnamemodify('../testdir/a', ':~')) + call assert_equal('a', fnamemodify('../testdir/a', ':t')) + call assert_equal('', fnamemodify('.', ':p:t')) + call assert_equal('test.out', fnamemodify('test.out', ':p:t')) + call assert_equal('out', fnamemodify('test.out', ':p:e')) + call assert_equal('out', fnamemodify('test.out', ':p:t:e')) + call assert_equal('abc.fb2.tar', fnamemodify('abc.fb2.tar.gz', ':r')) + call assert_equal('abc.fb2', fnamemodify('abc.fb2.tar.gz', ':r:r')) + call assert_equal('abc', fnamemodify('abc.fb2.tar.gz', ':r:r:r')) + call assert_equal('testdir/abc.fb2', substitute(fnamemodify('abc.fb2.tar.gz', ':p:r:r'), '.*\(testdir/.*\)', '\1', '')) + call assert_equal('gz', fnamemodify('abc.fb2.tar.gz', ':e')) + call assert_equal('tar.gz', fnamemodify('abc.fb2.tar.gz', ':e:e')) + call assert_equal('fb2.tar.gz', fnamemodify('abc.fb2.tar.gz', ':e:e:e')) + call assert_equal('fb2.tar.gz', fnamemodify('abc.fb2.tar.gz', ':e:e:e:e')) + call assert_equal('tar', fnamemodify('abc.fb2.tar.gz', ':e:e:r')) + + call assert_equal('''abc def''', fnamemodify('abc def', ':S')) + call assert_equal('''abc" "def''', fnamemodify('abc" "def', ':S')) + call assert_equal('''abc"%"def''', fnamemodify('abc"%"def', ':S')) + call assert_equal('''abc''\'''' ''\''''def''', fnamemodify('abc'' ''def', ':S')) + call assert_equal('''abc''\''''%''\''''def''', fnamemodify('abc''%''def', ':S')) + sp test_alot.vim + call assert_equal(expand('%:r:S'), shellescape(expand('%:r'))) + call assert_equal('test_alot,''test_alot'',test_alot.vim', join([expand('%:r'), expand('%:r:S'), expand('%')], ',')) + quit + + call assert_equal("'abc\ndef'", fnamemodify("abc\ndef", ':S')) + set shell=tcsh + call assert_equal("'abc\\\ndef'", fnamemodify("abc\ndef", ':S')) + + let $HOME = save_home + let &shell = save_shell +endfunc + +func Test_fnamemodify_er() + call assert_equal("with", fnamemodify("path/to/file.with.extensions", ':e:e:r:r')) + + call assert_equal('c', fnamemodify('a.c', ':e')) + call assert_equal('c', fnamemodify('a.c', ':e:e')) + call assert_equal('c', fnamemodify('a.c', ':e:e:r')) + call assert_equal('c', fnamemodify('a.c', ':e:e:r:r')) + + call assert_equal('rb', fnamemodify('a.spec.rb', ':e:r')) + call assert_equal('rb', fnamemodify('a.spec.rb', ':e:r')) + call assert_equal('spec.rb', fnamemodify('a.spec.rb', ':e:e')) + call assert_equal('spec', fnamemodify('a.spec.rb', ':e:e:r')) + call assert_equal('spec', fnamemodify('a.spec.rb', ':e:e:r:r')) + call assert_equal('spec', fnamemodify('a.b.spec.rb', ':e:e:r')) + call assert_equal('b.spec', fnamemodify('a.b.spec.rb', ':e:e:e:r')) + call assert_equal('b', fnamemodify('a.b.spec.rb', ':e:e:e:r:r')) + + call assert_equal('spec', fnamemodify('a.b.spec.rb', ':r:e')) + call assert_equal('b', fnamemodify('a.b.spec.rb', ':r:r:e')) + + call assert_equal('c', fnamemodify('a.b.c.d.e', ':r:r:e')) + call assert_equal('b.c', fnamemodify('a.b.c.d.e', ':r:r:e:e')) + + " :e never includes the whole filename, so "a.b":e:e:e --> "b" + call assert_equal('b.c', fnamemodify('a.b.c.d.e', ':r:r:e:e:e')) + call assert_equal('b.c', fnamemodify('a.b.c.d.e', ':r:r:e:e:e:e')) +endfunc diff --git a/src/nvim/testdir/test_fold.vim b/src/nvim/testdir/test_fold.vim index 3cb42579be..324f3f8cf2 100644 --- a/src/nvim/testdir/test_fold.vim +++ b/src/nvim/testdir/test_fold.vim @@ -520,17 +520,18 @@ func Test_fold_create_marker_in_C() set fdm=marker fdl=9 set filetype=c - let content = [ - \ '/*', - \ ' * comment', - \ ' * ', - \ ' *', - \ ' */', - \ 'int f(int* p) {', - \ ' *p = 3;', - \ ' return 0;', - \ '}' - \] + let content =<< trim [CODE] + /* + * comment + * + * + */ + int f(int* p) { + *p = 3; + return 0; + } + [CODE] + for c in range(len(content) - 1) bw! call append(0, content) @@ -756,3 +757,15 @@ func Test_fold_delete_with_marker() bwipe! bwipe! endfunc + +func Test_fold_delete_with_marker_and_whichwrap() + new + let content1 = [''] + let content2 = ['folded line 1 "{{{1', ' test', ' test2', ' test3', '', 'folded line 2 "{{{1', ' test', ' test2', ' test3'] + call setline(1, content1 + content2) + set fdm=marker ww+=l + normal! x + call assert_equal(content2, getline(1, '$')) + set fdm& ww& + bwipe! +endfunc diff --git a/src/nvim/testdir/test_functions.vim b/src/nvim/testdir/test_functions.vim index a36c51f56f..7822507f86 100644 --- a/src/nvim/testdir/test_functions.vim +++ b/src/nvim/testdir/test_functions.vim @@ -1132,6 +1132,13 @@ func Test_reg_executing_and_recording() " :normal command saves and restores reg_executing let s:reg_stat = '' + let @q = ":call TestFunc()\<CR>:call s:save_reg_stat()\<CR>" + func TestFunc() abort + normal! ia + endfunc + call feedkeys("@q", 'xt') + call assert_equal(':q', s:reg_stat) + delfunc TestFunc " getchar() command saves and restores reg_executing map W :call TestFunc()<CR> diff --git a/src/nvim/testdir/test_gf.vim b/src/nvim/testdir/test_gf.vim index accd21e9a3..d301874891 100644 --- a/src/nvim/testdir/test_gf.vim +++ b/src/nvim/testdir/test_gf.vim @@ -99,3 +99,28 @@ func Test_gf() call delete('Xtest1') call delete('Xtestgf') endfunc + +func Test_gf_visual() + call writefile([], "Xtest_gf_visual") + new + call setline(1, 'XXXtest_gf_visualXXX') + set hidden + + " Visually select Xtest_gf_visual and use gf to go to that file + norm! ttvtXgf + call assert_equal('Xtest_gf_visual', bufname('%')) + + bwipe! + call delete('Xtest_gf_visual') + set hidden& +endfunc + +func Test_gf_error() + new + call assert_fails('normal gf', 'E446:') + call assert_fails('normal gF', 'E446:') + call setline(1, '/doesnotexist') + call assert_fails('normal gf', 'E447:') + call assert_fails('normal gF', 'E447:') + bwipe! +endfunc diff --git a/src/nvim/testdir/test_gn.vim b/src/nvim/testdir/test_gn.vim index 5e74289b00..d41675be0c 100644 --- a/src/nvim/testdir/test_gn.vim +++ b/src/nvim/testdir/test_gn.vim @@ -129,6 +129,33 @@ func Test_gn_command() call assert_equal([' nnoremap', '', 'match'], getline(1,'$')) sil! %d_ + " make sure it works correctly for one-char wide search items + call setline('.', ['abcdefghi']) + let @/ = 'a' + exe "norm! 0fhvhhgNgU" + call assert_equal(['ABCDEFGHi'], getline(1,'$')) + call setline('.', ['abcdefghi']) + let @/ = 'b' + " this gn wraps around the end of the file + exe "norm! 0fhvhhgngU" + call assert_equal(['aBCDEFGHi'], getline(1,'$')) + sil! %d _ + call setline('.', ['abcdefghi']) + let @/ = 'f' + exe "norm! 0vllgngU" + call assert_equal(['ABCDEFghi'], getline(1,'$')) + sil! %d _ + call setline('.', ['12345678']) + let @/ = '5' + norm! gg0f7vhhhhgnd + call assert_equal(['12348'], getline(1,'$')) + sil! %d _ + call setline('.', ['12345678']) + let @/ = '5' + norm! gg0f2vf7gNd + call assert_equal(['1678'], getline(1,'$')) + sil! %d _ + set wrapscan&vim set belloff&vim endfu diff --git a/src/nvim/testdir/test_goto.vim b/src/nvim/testdir/test_goto.vim index c0235b1707..19513b315a 100644 --- a/src/nvim/testdir/test_goto.vim +++ b/src/nvim/testdir/test_goto.vim @@ -15,262 +15,283 @@ func XTest_goto_decl(cmd, lines, line, col) endfunc func Test_gD() - let lines = [ - \ 'int x;', - \ '', - \ 'int func(void)', - \ '{', - \ ' return x;', - \ '}', - \ ] + let lines =<< trim [CODE] + int x; + + int func(void) + { + return x; + } + [CODE] + call XTest_goto_decl('gD', lines, 1, 5) endfunc func Test_gD_too() - let lines = [ - \ 'Filename x;', - \ '', - \ 'int Filename', - \ 'int func() {', - \ ' Filename x;', - \ ' return x;', - \ ] + let lines =<< trim [CODE] + Filename x; + + int Filename + int func() { + Filename x; + return x; + [CODE] + call XTest_goto_decl('gD', lines, 1, 10) endfunc func Test_gD_comment() - let lines = [ - \ '/* int x; */', - \ 'int x;', - \ '', - \ 'int func(void)', - \ '{', - \ ' return x;', - \ '}', - \ ] + let lines =<< trim [CODE] + /* int x; */ + int x; + + int func(void) + { + return x; + } + [CODE] + call XTest_goto_decl('gD', lines, 2, 5) endfunc func Test_gD_inline_comment() - let lines = [ - \ 'int y /* , x */;', - \ 'int x;', - \ '', - \ 'int func(void)', - \ '{', - \ ' return x;', - \ '}', - \ ] + let lines =<< trim [CODE] + int y /* , x */; + int x; + + int func(void) + { + return x; + } + [CODE] + call XTest_goto_decl('gD', lines, 2, 5) endfunc func Test_gD_string() - let lines = [ - \ 'char *s[] = "x";', - \ 'int x = 1;', - \ '', - \ 'int func(void)', - \ '{', - \ ' return x;', - \ '}', - \ ] + let lines =<< trim [CODE] + char *s[] = "x"; + int x = 1; + + int func(void) + { + return x; + } + [CODE] + call XTest_goto_decl('gD', lines, 2, 5) endfunc func Test_gD_string_same_line() - let lines = [ - \ 'char *s[] = "x", int x = 1;', - \ '', - \ 'int func(void)', - \ '{', - \ ' return x;', - \ '}', - \ ] + let lines =<< trim [CODE] + char *s[] = "x", int x = 1; + + int func(void) + { + return x; + } + [CODE] + call XTest_goto_decl('gD', lines, 1, 22) endfunc func Test_gD_char() - let lines = [ - \ "char c = 'x';", - \ 'int x = 1;', - \ '', - \ 'int func(void)', - \ '{', - \ ' return x;', - \ '}', - \ ] + let lines =<< trim [CODE] + char c = 'x'; + int x = 1; + + int func(void) + { + return x; + } + [CODE] + call XTest_goto_decl('gD', lines, 2, 5) endfunc func Test_gd() - let lines = [ - \ 'int x;', - \ '', - \ 'int func(int x)', - \ '{', - \ ' return x;', - \ '}', - \ ] + let lines =<< trim [CODE] + int x; + + int func(int x) + { + return x; + } + [CODE] + call XTest_goto_decl('gd', lines, 3, 14) endfunc func Test_gd_not_local() - let lines = [ - \ 'int func1(void)', - \ '{', - \ ' return x;', - \ '}', - \ '', - \ 'int func2(int x)', - \ '{', - \ ' return x;', - \ '}', - \ ] + let lines =<< trim [CODE] + int func1(void) + { + return x; + } + + int func2(int x) + { + return x; + } + [CODE] + call XTest_goto_decl('gd', lines, 3, 10) endfunc func Test_gd_kr_style() - let lines = [ - \ 'int func(x)', - \ ' int x;', - \ '{', - \ ' return x;', - \ '}', - \ ] + let lines =<< trim [CODE] + int func(x) + int x; + { + return x; + } + [CODE] + call XTest_goto_decl('gd', lines, 2, 7) endfunc func Test_gd_missing_braces() - let lines = [ - \ 'def func1(a)', - \ ' a + 1', - \ 'end', - \ '', - \ 'a = 1', - \ '', - \ 'def func2()', - \ ' return a', - \ 'end', - \ ] + let lines =<< trim [CODE] + def func1(a) + a + 1 + end + + a = 1 + + def func2() + return a + end + [CODE] + call XTest_goto_decl('gd', lines, 1, 11) endfunc func Test_gd_comment() - let lines = [ - \ 'int func(void)', - \ '{', - \ ' /* int x; */', - \ ' int x;', - \ ' return x;', - \ '}', - \] + let lines =<< trim [CODE] + int func(void) + { + /* int x; */ + int x; + return x; + } + [CODE] + call XTest_goto_decl('gd', lines, 4, 7) endfunc func Test_gd_comment_in_string() - let lines = [ - \ 'int func(void)', - \ '{', - \ ' char *s ="//"; int x;', - \ ' int x;', - \ ' return x;', - \ '}', - \] + let lines =<< trim [CODE] + int func(void) + { + char *s ="//"; int x; + int x; + return x; + } + [CODE] + call XTest_goto_decl('gd', lines, 3, 22) endfunc func Test_gd_string_in_comment() set comments= - let lines = [ - \ 'int func(void)', - \ '{', - \ ' /* " */ int x;', - \ ' int x;', - \ ' return x;', - \ '}', - \] + let lines =<< trim [CODE] + int func(void) + { + /* " */ int x; + int x; + return x; + } + [CODE] + call XTest_goto_decl('gd', lines, 3, 15) set comments& endfunc func Test_gd_inline_comment() - let lines = [ - \ 'int func(/* x is an int */ int x)', - \ '{', - \ ' return x;', - \ '}', - \ ] + let lines =<< trim [CODE] + int func(/* x is an int */ int x) + { + return x; + } + [CODE] + call XTest_goto_decl('gd', lines, 1, 32) endfunc func Test_gd_inline_comment_only() - let lines = [ - \ 'int func(void) /* one lonely x */', - \ '{', - \ ' return x;', - \ '}', - \ ] + let lines =<< trim [CODE] + int func(void) /* one lonely x */ + { + return x; + } + [CODE] + call XTest_goto_decl('gd', lines, 3, 10) endfunc func Test_gd_inline_comment_body() - let lines = [ - \ 'int func(void)', - \ '{', - \ ' int y /* , x */;', - \ '', - \ ' for (/* int x = 0 */; y < 2; y++);', - \ '', - \ ' int x = 0;', - \ '', - \ ' return x;', - \ '}', - \ ] + let lines =<< trim [CODE] + int func(void) + { + int y /* , x */; + + for (/* int x = 0 */; y < 2; y++); + + int x = 0; + + return x; + } + [CODE] + call XTest_goto_decl('gd', lines, 7, 7) endfunc func Test_gd_trailing_multiline_comment() - let lines = [ - \ 'int func(int x) /* x is an int */', - \ '{', - \ ' return x;', - \ '}', - \ ] + let lines =<< trim [CODE] + int func(int x) /* x is an int */ + { + return x; + } + [CODE] + call XTest_goto_decl('gd', lines, 1, 14) endfunc func Test_gd_trailing_comment() - let lines = [ - \ 'int func(int x) // x is an int', - \ '{', - \ ' return x;', - \ '}', - \ ] + let lines =<< trim [CODE] + int func(int x) // x is an int + { + return x; + } + [CODE] + call XTest_goto_decl('gd', lines, 1, 14) endfunc func Test_gd_string() - let lines = [ - \ 'int func(void)', - \ '{', - \ ' char *s = "x";', - \ ' int x = 1;', - \ '', - \ ' return x;', - \ '}', - \ ] + let lines =<< trim [CODE] + int func(void) + { + char *s = "x"; + int x = 1; + + return x; + } + [CODE] + call XTest_goto_decl('gd', lines, 4, 7) endfunc func Test_gd_string_only() - let lines = [ - \ 'int func(void)', - \ '{', - \ ' char *s = "x";', - \ '', - \ ' return x;', - \ '}', - \ ] + let lines =<< trim [CODE] + int func(void) + { + char *s = "x"; + + return x; + } + [CODE] + call XTest_goto_decl('gd', lines, 5, 10) endfunc @@ -289,24 +310,25 @@ func Test_cursorline_keep_col() endfunc func Test_gd_local_block() - let lines = [ - \ ' int main()', - \ '{', - \ ' char *a = "NOT NULL";', - \ ' if(a)', - \ ' {', - \ ' char *b = a;', - \ ' printf("%s\n", b);', - \ ' }', - \ ' else', - \ ' {', - \ ' char *b = "NULL";', - \ ' return b;', - \ ' }', - \ '', - \ ' return 0;', - \ '}', - \ ] + let lines =<< trim [CODE] + int main() + { + char *a = "NOT NULL"; + if(a) + { + char *b = a; + printf("%s\n", b); + } + else + { + char *b = "NULL"; + return b; + } + + return 0; + } + [CODE] + call XTest_goto_decl('1gd', lines, 11, 11) endfunc diff --git a/src/nvim/testdir/test_help.vim b/src/nvim/testdir/test_help.vim index ed3181564c..01fb9917e9 100644 --- a/src/nvim/testdir/test_help.vim +++ b/src/nvim/testdir/test_help.vim @@ -21,6 +21,12 @@ func Test_help_errors() bwipe! endfunc +func Test_help_expr() + help expr-!~? + call assert_equal('eval.txt', expand('%:t')) + close +endfunc + func Test_help_keyword() new set keywordprg=:help diff --git a/src/nvim/testdir/test_ins_complete.vim b/src/nvim/testdir/test_ins_complete.vim index 7f52481ba8..52ec281d82 100644 --- a/src/nvim/testdir/test_ins_complete.vim +++ b/src/nvim/testdir/test_ins_complete.vim @@ -285,3 +285,21 @@ func Test_compl_feedkeys() bwipe! set completeopt& endfunc + +func Test_compl_in_cmdwin() + set wildmenu wildchar=<Tab> + com! -nargs=1 -complete=command GetInput let input = <q-args> + com! -buffer TestCommand echo 'TestCommand' + + let input = '' + call feedkeys("q:iGetInput T\<C-x>\<C-v>\<CR>", 'tx!') + call assert_equal('TestCommand', input) + + let input = '' + call feedkeys("q::GetInput T\<Tab>\<CR>:q\<CR>", 'tx!') + call assert_equal('T', input) + + delcom TestCommand + delcom GetInput + set wildmenu& wildchar& +endfunc diff --git a/src/nvim/testdir/test_join.vim b/src/nvim/testdir/test_join.vim index 1c97414164..ecb55c9af6 100644 --- a/src/nvim/testdir/test_join.vim +++ b/src/nvim/testdir/test_join.vim @@ -9,6 +9,27 @@ func Test_join_with_count() call setline(1, ['one', 'two', 'three', 'four']) normal 10J call assert_equal('one two three four', getline(1)) + + call setline(1, ['one', '', 'two']) + normal J + call assert_equal('one', getline(1)) + + call setline(1, ['one', ' ', 'two']) + normal J + call assert_equal('one', getline(1)) + + call setline(1, ['one', '', '', 'two']) + normal JJ + call assert_equal('one', getline(1)) + + call setline(1, ['one', ' ', ' ', 'two']) + normal JJ + call assert_equal('one', getline(1)) + + call setline(1, ['one', '', '', 'two']) + normal 2J + call assert_equal('one', getline(1)) + quit! endfunc diff --git a/src/nvim/testdir/test_let.vim b/src/nvim/testdir/test_let.vim index 8a6f1bc320..0b9331ee38 100644 --- a/src/nvim/testdir/test_let.vim +++ b/src/nvim/testdir/test_let.vim @@ -24,6 +24,10 @@ func Test_let() let out = execute('let a {0 == 1 ? "a" : "b"}') let s = "\na #1\nb #2" call assert_equal(s, out) + + let x = 0 + if 0 | let x = 1 | endif + call assert_equal(0, x) endfunc func s:set_arg1(a) abort @@ -140,3 +144,161 @@ func Test_let_varg_fail() call assert_fails('call s:set_varg7(1)', 'E742:') call s:set_varg8([0]) endfunction + +func Test_let_utf8_environment() + let $a = 'ĀĒĪŌŪあいうえお' + call assert_equal('ĀĒĪŌŪあいうえお', $a) +endfunc + +func Test_let_heredoc_fails() + call assert_fails('let v =<< marker', 'E991:') + + let text =<< trim END + func WrongSyntax() + let v =<< that there + endfunc + END + call writefile(text, 'XheredocFail') + call assert_fails('source XheredocFail', 'E126:') + call delete('XheredocFail') + + let text =<< trim CodeEnd + func MissingEnd() + let v =<< END + endfunc + CodeEnd + call writefile(text, 'XheredocWrong') + call assert_fails('source XheredocWrong', 'E126:') + call delete('XheredocWrong') + + let text =<< trim TEXTend + let v =<< " comment + TEXTend + call writefile(text, 'XheredocNoMarker') + call assert_fails('source XheredocNoMarker', 'E172:') + call delete('XheredocNoMarker') + + let text =<< trim TEXTend + let v =<< text + TEXTend + call writefile(text, 'XheredocBadMarker') + call assert_fails('source XheredocBadMarker', 'E221:') + call delete('XheredocBadMarker') +endfunc + +func Test_let_heredoc_trim_no_indent_marker() + let text =<< trim END + Text + with + indent +END + call assert_equal(['Text', 'with', 'indent'], text) +endfunc + +" Test for the setting a variable using the heredoc syntax +func Test_let_heredoc() + let var1 =<< END +Some sample text + Text with indent + !@#$%^&*()-+_={}|[]\~`:";'<>?,./ +END + + call assert_equal(["Some sample text", "\tText with indent", " !@#$%^&*()-+_={}|[]\\~`:\";'<>?,./"], var1) + + let var2 =<< XXX +Editor +XXX + call assert_equal(['Editor'], var2) + + let var3 =<<END +END + call assert_equal([], var3) + + let var3 =<<END +vim + +end + END +END +END + call assert_equal(['vim', '', 'end', ' END', 'END '], var3) + + let var1 =<< trim END + Line1 + Line2 + Line3 + END + END + call assert_equal(['Line1', ' Line2', "\tLine3", ' END'], var1) + + let var1 =<< trim !!! + Line1 + line2 + Line3 + !!! + !!! + call assert_equal(['Line1', ' line2', "\tLine3", '!!!',], var1) + + let var1 =<< trim XX + Line1 + XX + call assert_equal(['Line1'], var1) + + " ignore "endfunc" + let var1 =<< END +something +endfunc +END + call assert_equal(['something', 'endfunc'], var1) + + " ignore "endfunc" with trim + let var1 =<< trim END + something + endfunc + END + call assert_equal(['something', 'endfunc'], var1) + + " ignore "python << xx" + let var1 =<<END +something +python << xx +END + call assert_equal(['something', 'python << xx'], var1) + + " ignore "python << xx" with trim + let var1 =<< trim END + something + python << xx + END + call assert_equal(['something', 'python << xx'], var1) + + " ignore "append" + let var1 =<< E +something +app +E + call assert_equal(['something', 'app'], var1) + + " ignore "append" with trim + let var1 =<< trim END + something + app + END + call assert_equal(['something', 'app'], var1) + + let check = [] + if 0 + let check =<< trim END + from heredoc + END + endif + call assert_equal([], check) + + " unpack assignment + let [a, b, c] =<< END + x + \y + z +END + call assert_equal([' x', ' \y', ' z'], [a, b, c]) +endfunc diff --git a/src/nvim/testdir/test_mksession_utf8.vim b/src/nvim/testdir/test_mksession_utf8.vim index 67af3a9ca2..722fd28beb 100644 --- a/src/nvim/testdir/test_mksession_utf8.vim +++ b/src/nvim/testdir/test_mksession_utf8.vim @@ -65,34 +65,35 @@ func Test_mksession_utf8() call wincol() mksession! test_mks.out let li = filter(readfile('test_mks.out'), 'v:val =~# "\\(^ *normal! 0\\|^ *exe ''normal!\\)"') - let expected = [ - \ 'normal! 016|', - \ 'normal! 016|', - \ 'normal! 016|', - \ 'normal! 08|', - \ 'normal! 08|', - \ 'normal! 016|', - \ 'normal! 016|', - \ 'normal! 016|', - \ " exe 'normal! ' . s:c . '|zs' . 16 . '|'", - \ " normal! 016|", - \ " exe 'normal! ' . s:c . '|zs' . 16 . '|'", - \ " normal! 016|", - \ " exe 'normal! ' . s:c . '|zs' . 16 . '|'", - \ " normal! 016|", - \ " exe 'normal! ' . s:c . '|zs' . 8 . '|'", - \ " normal! 08|", - \ " exe 'normal! ' . s:c . '|zs' . 8 . '|'", - \ " normal! 08|", - \ " exe 'normal! ' . s:c . '|zs' . 16 . '|'", - \ " normal! 016|", - \ " exe 'normal! ' . s:c . '|zs' . 16 . '|'", - \ " normal! 016|", - \ " exe 'normal! ' . s:c . '|zs' . 16 . '|'", - \ " normal! 016|", - \ " exe 'normal! ' . s:c . '|zs' . 16 . '|'", - \ " normal! 016|" - \ ] + let expected =<< trim [DATA] + normal! 016| + normal! 016| + normal! 016| + normal! 08| + normal! 08| + normal! 016| + normal! 016| + normal! 016| + exe 'normal! ' . s:c . '|zs' . 16 . '|' + normal! 016| + exe 'normal! ' . s:c . '|zs' . 16 . '|' + normal! 016| + exe 'normal! ' . s:c . '|zs' . 16 . '|' + normal! 016| + exe 'normal! ' . s:c . '|zs' . 8 . '|' + normal! 08| + exe 'normal! ' . s:c . '|zs' . 8 . '|' + normal! 08| + exe 'normal! ' . s:c . '|zs' . 16 . '|' + normal! 016| + exe 'normal! ' . s:c . '|zs' . 16 . '|' + normal! 016| + exe 'normal! ' . s:c . '|zs' . 16 . '|' + normal! 016| + exe 'normal! ' . s:c . '|zs' . 16 . '|' + normal! 016| + [DATA] + call assert_equal(expected, li) tabclose! diff --git a/src/nvim/testdir/test_normal.vim b/src/nvim/testdir/test_normal.vim index 532beb9c39..ad6d325510 100644 --- a/src/nvim/testdir/test_normal.vim +++ b/src/nvim/testdir/test_normal.vim @@ -2,12 +2,12 @@ source shared.vim -func! Setup_NewWindow() +func Setup_NewWindow() 10new call setline(1, range(1,100)) endfunc -func! MyFormatExpr() +func MyFormatExpr() " Adds '->$' at lines having numbers followed by trailing whitespace for ln in range(v:lnum, v:lnum+v:count-1) let line = getline(ln) @@ -17,7 +17,7 @@ func! MyFormatExpr() endfor endfunc -func! CountSpaces(type, ...) +func CountSpaces(type, ...) " for testing operatorfunc " will count the number of spaces " and return the result in g:a @@ -37,7 +37,7 @@ func! CountSpaces(type, ...) let @@ = reg_save endfunc -func! OpfuncDummy(type, ...) +func OpfuncDummy(type, ...) " for testing operatorfunc let g:opt=&linebreak @@ -81,7 +81,7 @@ fun! Test_normal00_optrans() bw! endfunc -func! Test_normal01_keymodel() +func Test_normal01_keymodel() call Setup_NewWindow() " Test 1: depending on 'keymodel' <s-down> does something different 50 @@ -115,7 +115,7 @@ func! Test_normal01_keymodel() bw! endfunc -func! Test_normal02_selectmode() +func Test_normal02_selectmode() " some basic select mode tests call Setup_NewWindow() 50 @@ -129,7 +129,7 @@ func! Test_normal02_selectmode() bw! endfunc -func! Test_normal02_selectmode2() +func Test_normal02_selectmode2() " some basic select mode tests call Setup_NewWindow() 50 @@ -139,7 +139,7 @@ func! Test_normal02_selectmode2() bw! endfunc -func! Test_normal03_join() +func Test_normal03_join() " basic join test call Setup_NewWindow() 50 @@ -159,7 +159,7 @@ func! Test_normal03_join() bw! endfunc -func! Test_normal04_filter() +func Test_normal04_filter() " basic filter test " only test on non windows platform if has('win32') @@ -185,7 +185,7 @@ func! Test_normal04_filter() bw! endfunc -func! Test_normal05_formatexpr() +func Test_normal05_formatexpr() " basic formatexpr test call Setup_NewWindow() %d_ @@ -222,7 +222,7 @@ func Test_normal05_formatexpr_setopt() set formatexpr= endfunc -func! Test_normal06_formatprg() +func Test_normal06_formatprg() " basic test for formatprg " only test on non windows platform if has('win32') @@ -256,7 +256,7 @@ func! Test_normal06_formatprg() call delete('Xsed_format.sh') endfunc -func! Test_normal07_internalfmt() +func Test_normal07_internalfmt() " basic test for internal formmatter to textwidth of 12 let list=range(1,11) call map(list, 'v:val." "') @@ -270,7 +270,7 @@ func! Test_normal07_internalfmt() bw! endfunc -func! Test_normal08_fold() +func Test_normal08_fold() " basic tests for foldopen/folddelete if !has("folding") return @@ -329,7 +329,7 @@ func! Test_normal08_fold() bw! endfunc -func! Test_normal09_operatorfunc() +func Test_normal09_operatorfunc() " Test operatorfunc call Setup_NewWindow() " Add some spaces for counting @@ -359,7 +359,7 @@ func! Test_normal09_operatorfunc() bw! endfunc -func! Test_normal09a_operatorfunc() +func Test_normal09a_operatorfunc() " Test operatorfunc call Setup_NewWindow() " Add some spaces for counting @@ -385,7 +385,7 @@ func! Test_normal09a_operatorfunc() unlet! g:opt endfunc -func! Test_normal10_expand() +func Test_normal10_expand() " Test for expand() 10new call setline(1, ['1', 'ifooar,,cbar']) @@ -420,7 +420,7 @@ func! Test_normal10_expand() bw! endfunc -func! Test_normal11_showcmd() +func Test_normal11_showcmd() " test for 'showcmd' 10new exe "norm! ofoobar\<esc>" @@ -435,7 +435,7 @@ func! Test_normal11_showcmd() bw! endfunc -func! Test_normal12_nv_error() +func Test_normal12_nv_error() " Test for nv_error 10new call setline(1, range(1,5)) @@ -445,7 +445,7 @@ func! Test_normal12_nv_error() bw! endfunc -func! Test_normal13_help() +func Test_normal13_help() " Test for F1 call assert_equal(1, winnr()) call feedkeys("\<f1>", 'txi') @@ -454,7 +454,7 @@ func! Test_normal13_help() bw! endfunc -func! Test_normal14_page() +func Test_normal14_page() " basic test for Ctrl-F and Ctrl-B call Setup_NewWindow() exe "norm! \<c-f>" @@ -488,7 +488,7 @@ func! Test_normal14_page() bw! endfunc -func! Test_normal14_page_eol() +func Test_normal14_page_eol() 10new norm oxxxxxxx exe "norm 2\<c-f>" @@ -497,7 +497,7 @@ func! Test_normal14_page_eol() bw! endfunc -func! Test_normal15_z_scroll_vert() +func Test_normal15_z_scroll_vert() " basic test for z commands that scroll the window call Setup_NewWindow() 100 @@ -586,7 +586,7 @@ func! Test_normal15_z_scroll_vert() bw! endfunc -func! Test_normal16_z_scroll_hor() +func Test_normal16_z_scroll_hor() " basic test for z commands that scroll the window 10new 15vsp @@ -652,7 +652,7 @@ func! Test_normal16_z_scroll_hor() bw! endfunc -func! Test_normal17_z_scroll_hor2() +func Test_normal17_z_scroll_hor2() " basic test for z commands that scroll the window " using 'sidescrolloff' setting 10new @@ -719,7 +719,7 @@ func! Test_normal17_z_scroll_hor2() bw! endfunc -func! Test_normal18_z_fold() +func Test_normal18_z_fold() " basic tests for foldopen/folddelete if !has("folding") return @@ -1090,7 +1090,7 @@ func! Test_normal18_z_fold() bw! endfunc -func! Test_normal19_z_spell() +func Test_normal19_z_spell() if !has("spell") || !has('syntax') return endif @@ -1245,7 +1245,7 @@ func! Test_normal19_z_spell() bw! endfunc -func! Test_normal20_exmode() +func Test_normal20_exmode() if !has("unix") " Reading from redirected file doesn't work on MS-Windows return @@ -1263,24 +1263,38 @@ func! Test_normal20_exmode() bw! endfunc -func! Test_normal21_nv_hat() - set hidden - new - " to many buffers opened already, will not work - "call assert_fails(":b#", 'E23') - "call assert_equal('', @#) - e Xfoobar - e Xfile2 - call feedkeys("\<c-^>", 't') - call assert_equal("Xfile2", fnamemodify(bufname('%'), ':t')) - call feedkeys("f\<c-^>", 't') - call assert_equal("Xfile2", fnamemodify(bufname('%'), ':t')) - " clean up - set nohidden - bw! +func Test_normal21_nv_hat() + + " Edit a fresh file and wipe the buffer list so that there is no alternate + " file present. Next, check for the expected command failures. + edit Xfoo | %bw + call assert_fails(':buffer #', 'E86') + call assert_fails(':execute "normal! \<C-^>"', 'E23') + + " Test for the expected behavior when switching between two named buffers. + edit Xfoo | edit Xbar + call feedkeys("\<C-^>", 'tx') + call assert_equal('Xfoo', fnamemodify(bufname('%'), ':t')) + call feedkeys("\<C-^>", 'tx') + call assert_equal('Xbar', fnamemodify(bufname('%'), ':t')) + + " Test for the expected behavior when only one buffer is named. + enew | let l:nr = bufnr('%') + call feedkeys("\<C-^>", 'tx') + call assert_equal('Xbar', fnamemodify(bufname('%'), ':t')) + call feedkeys("\<C-^>", 'tx') + call assert_equal('', bufname('%')) + call assert_equal(l:nr, bufnr('%')) + + " Test that no action is taken by "<C-^>" when an operator is pending. + edit Xfoo + call feedkeys("ci\<C-^>", 'tx') + call assert_equal('Xfoo', fnamemodify(bufname('%'), ':t')) + + %bw! endfunc -func! Test_normal22_zet() +func Test_normal22_zet() " Test for ZZ " let shell = &shell " let &shell = 'sh' @@ -1308,7 +1322,7 @@ func! Test_normal22_zet() " let &shell = shell endfunc -func! Test_normal23_K() +func Test_normal23_K() " Test for K command new call append(0, ['helphelp.txt', 'man', 'aa%bb', 'cc|dd']) @@ -1353,8 +1367,9 @@ func! Test_normal23_K() return endif - if has('mac') - " In MacOS, the option for specifying a pager is different + let not_gnu_man = has('mac') || has('bsd') + if not_gnu_man + " In MacOS and BSD, the option for specifying a pager is different set keywordprg=man\ -P\ cat else set keywordprg=man\ --pager=cat @@ -1362,7 +1377,7 @@ func! Test_normal23_K() " Test for using man 2 let a = execute('unsilent norm! K') - if has('mac') + if not_gnu_man call assert_match("man -P cat 'man'", a) else call assert_match("man --pager=cat 'man'", a) @@ -1373,7 +1388,7 @@ func! Test_normal23_K() bw! endfunc -func! Test_normal24_rot13() +func Test_normal24_rot13() " Testing for g?? g?g? new call append(0, 'abcdefghijklmnopqrstuvwxyzäüö') @@ -1387,7 +1402,7 @@ func! Test_normal24_rot13() bw! endfunc -func! Test_normal25_tag() +func Test_normal25_tag() " Testing for CTRL-] g CTRL-] g] " CTRL-W g] CTRL-W CTRL-] CTRL-W g CTRL-] h @@ -1454,7 +1469,7 @@ func! Test_normal25_tag() helpclose endfunc -func! Test_normal26_put() +func Test_normal26_put() " Test for ]p ]P [p and [P new call append(0, ['while read LINE', 'do', ' ((count++))', ' if [ $? -ne 0 ]; then', " echo 'Error writing file'", ' fi', 'done']) @@ -1473,7 +1488,7 @@ func! Test_normal26_put() bw! endfunc -func! Test_normal27_bracket() +func Test_normal27_bracket() " Test for [' [` ]' ]` call Setup_NewWindow() 1,21s/.\+/ & b/ @@ -1524,7 +1539,7 @@ func! Test_normal27_bracket() bw! endfunc -func! Test_normal28_parenthesis() +func Test_normal28_parenthesis() " basic testing for ( and ) new call append(0, ['This is a test. With some sentences!', '', 'Even with a question? And one more. And no sentence here']) @@ -1549,52 +1564,94 @@ endfunc fun! Test_normal29_brace() " basic test for { and } movements - let text= ['A paragraph begins after each empty line, and also at each of a set of', - \ 'paragraph macros, specified by the pairs of characters in the ''paragraphs''', - \ 'option. The default is "IPLPPPQPP TPHPLIPpLpItpplpipbp", which corresponds to', - \ 'the macros ".IP", ".LP", etc. (These are nroff macros, so the dot must be in', - \ 'the first column). A section boundary is also a paragraph boundary.', - \ 'Note that a blank line (only containing white space) is NOT a paragraph', - \ 'boundary.', - \ '', - \ '', - \ 'Also note that this does not include a ''{'' or ''}'' in the first column. When', - \ 'the ''{'' flag is in ''cpoptions'' then ''{'' in the first column is used as a', - \ 'paragraph boundary |posix|.', - \ '{', - \ 'This is no paragraph', - \ 'unless the ''{'' is set', - \ 'in ''cpoptions''', - \ '}', - \ '.IP', - \ 'The nroff macros IP separates a paragraph', - \ 'That means, it must be a ''.''', - \ 'followed by IP', - \ '.LPIt does not matter, if afterwards some', - \ 'more characters follow.', - \ '.SHAlso section boundaries from the nroff', - \ 'macros terminate a paragraph. That means', - \ 'a character like this:', - \ '.NH', - \ 'End of text here'] + let text =<< trim [DATA] + A paragraph begins after each empty line, and also at each of a set of + paragraph macros, specified by the pairs of characters in the 'paragraphs' + option. The default is "IPLPPPQPP TPHPLIPpLpItpplpipbp", which corresponds to + the macros ".IP", ".LP", etc. (These are nroff macros, so the dot must be in + the first column). A section boundary is also a paragraph boundary. + Note that a blank line (only containing white space) is NOT a paragraph + boundary. + + + Also note that this does not include a '{' or '}' in the first column. When + the '{' flag is in 'cpoptions' then '{' in the first column is used as a + paragraph boundary |posix|. + { + This is no paragraph + unless the '{' is set + in 'cpoptions' + } + .IP + The nroff macros IP separates a paragraph + That means, it must be a '.' + followed by IP + .LPIt does not matter, if afterwards some + more characters follow. + .SHAlso section boundaries from the nroff + macros terminate a paragraph. That means + a character like this: + .NH + End of text here + [DATA] + new call append(0, text) 1 norm! 0d2} - call assert_equal(['.IP', - \ 'The nroff macros IP separates a paragraph', 'That means, it must be a ''.''', 'followed by IP', - \ '.LPIt does not matter, if afterwards some', 'more characters follow.', '.SHAlso section boundaries from the nroff', - \ 'macros terminate a paragraph. That means', 'a character like this:', '.NH', 'End of text here', ''], getline(1,'$')) + + let expected =<< trim [DATA] + .IP + The nroff macros IP separates a paragraph + That means, it must be a '.' + followed by IP + .LPIt does not matter, if afterwards some + more characters follow. + .SHAlso section boundaries from the nroff + macros terminate a paragraph. That means + a character like this: + .NH + End of text here + + [DATA] + call assert_equal(expected, getline(1, '$')) + norm! 0d} - call assert_equal(['.LPIt does not matter, if afterwards some', 'more characters follow.', - \ '.SHAlso section boundaries from the nroff', 'macros terminate a paragraph. That means', - \ 'a character like this:', '.NH', 'End of text here', ''], getline(1, '$')) + + let expected =<< trim [DATA] + .LPIt does not matter, if afterwards some + more characters follow. + .SHAlso section boundaries from the nroff + macros terminate a paragraph. That means + a character like this: + .NH + End of text here + + [DATA] + call assert_equal(expected, getline(1, '$')) + $ norm! d{ - call assert_equal(['.LPIt does not matter, if afterwards some', 'more characters follow.', - \ '.SHAlso section boundaries from the nroff', 'macros terminate a paragraph. That means', 'a character like this:', ''], getline(1, '$')) + + let expected =<< trim [DATA] + .LPIt does not matter, if afterwards some + more characters follow. + .SHAlso section boundaries from the nroff + macros terminate a paragraph. That means + a character like this: + + [DATA] + call assert_equal(expected, getline(1, '$')) + norm! d{ - call assert_equal(['.LPIt does not matter, if afterwards some', 'more characters follow.', ''], getline(1,'$')) + + let expected =<< trim [DATA] + .LPIt does not matter, if afterwards some + more characters follow. + + [DATA] + call assert_equal(expected, getline(1, '$')) + " Test with { in cpooptions %d call append(0, text) @@ -1602,21 +1659,62 @@ fun! Test_normal29_brace() " set cpo+={ " 1 " norm! 0d2} - " call assert_equal(['{', 'This is no paragraph', 'unless the ''{'' is set', 'in ''cpoptions''', '}', - " \ '.IP', 'The nroff macros IP separates a paragraph', 'That means, it must be a ''.''', - " \ 'followed by IP', '.LPIt does not matter, if afterwards some', 'more characters follow.', - " \ '.SHAlso section boundaries from the nroff', 'macros terminate a paragraph. That means', - " \ 'a character like this:', '.NH', 'End of text here', ''], getline(1,'$')) + " let expected =<< trim [DATA] + " { + " This is no paragraph + " unless the '{' is set + " in 'cpoptions' + " } + " .IP + " The nroff macros IP separates a paragraph + " That means, it must be a '.' + " followed by IP + " .LPIt does not matter, if afterwards some + " more characters follow. + " .SHAlso section boundaries from the nroff + " macros terminate a paragraph. That means + " a character like this: + " .NH + " End of text here + " + " [DATA] + " call assert_equal(expected, getline(1, '$')) + " " $ " norm! d} - " call assert_equal(['{', 'This is no paragraph', 'unless the ''{'' is set', 'in ''cpoptions''', '}', - " \ '.IP', 'The nroff macros IP separates a paragraph', 'That means, it must be a ''.''', - " \ 'followed by IP', '.LPIt does not matter, if afterwards some', 'more characters follow.', - " \ '.SHAlso section boundaries from the nroff', 'macros terminate a paragraph. That means', - " \ 'a character like this:', '.NH', 'End of text here', ''], getline(1,'$')) + " let expected =<< trim [DATA] + " { + " This is no paragraph + " unless the '{' is set + " in 'cpoptions' + " } + " .IP + " The nroff macros IP separates a paragraph + " That means, it must be a '.' + " followed by IP + " .LPIt does not matter, if afterwards some + " more characters follow. + " .SHAlso section boundaries from the nroff + " macros terminate a paragraph. That means + " a character like this: + " .NH + " End of text here + " + " [DATA] + " call assert_equal(expected, getline(1, '$')) + " " norm! gg} " norm! d5} - " call assert_equal(['{', 'This is no paragraph', 'unless the ''{'' is set', 'in ''cpoptions''', '}', ''], getline(1,'$')) + " + " let expected =<< trim [DATA] + " { + " This is no paragraph + " unless the '{' is set + " in 'cpoptions' + " } + + " [DATA] + " call assert_equal(expected, getline(1, '$')) " clean up set cpo-={ @@ -1718,7 +1816,7 @@ fun! Test_normal31_r_cmd() bw! endfunc -func! Test_normal32_g_cmd1() +func Test_normal32_g_cmd1() " Test for g*, g# new call append(0, ['abc.x_foo', 'x_foobar.abc']) @@ -1798,6 +1896,7 @@ fun! Test_normal33_g_cmd2() set wrap listchars= sbr= let lineA='abcdefghijklmnopqrstuvwxyz' let lineB='0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ' + let lineC='0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz01234567890123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789' $put =lineA $put =lineB @@ -1831,9 +1930,30 @@ fun! Test_normal33_g_cmd2() call assert_equal(15, col('.')) call assert_equal('l', getreg(0)) + norm! 2ggdd + $put =lineC + + " Test for gM + norm! gMyl + call assert_equal(73, col('.')) + call assert_equal('0', getreg(0)) + " Test for 20gM + norm! 20gMyl + call assert_equal(29, col('.')) + call assert_equal('S', getreg(0)) + " Test for 60gM + norm! 60gMyl + call assert_equal(87, col('.')) + call assert_equal('E', getreg(0)) + + " Test for g Ctrl-G + set ff=unix + let a=execute(":norm! g\<c-g>") + call assert_match('Col 87 of 144; Line 2 of 2; Word 1 of 1; Byte 88 of 146', a) + " Test for gI norm! gIfoo - call assert_equal(['', 'fooabcdefghijk lmno0123456789AMNOPQRSTUVWXYZ'], getline(1,'$')) + call assert_equal(['', 'foo0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz01234567890123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'], getline(1,'$')) " Test for gi wincmd c @@ -1849,7 +1969,7 @@ fun! Test_normal33_g_cmd2() bw! endfunc -func! Test_g_ctrl_g() +func Test_g_ctrl_g() new let a = execute(":norm! g\<c-g>") @@ -2139,7 +2259,7 @@ fun! Test_normal41_insert_reg() bw! endfunc -func! Test_normal42_halfpage() +func Test_normal42_halfpage() " basic test for Ctrl-D and Ctrl-U call Setup_NewWindow() call assert_equal(5, &scroll) @@ -2207,7 +2327,7 @@ fun! Test_normal43_textobject1() bw! endfunc -func! Test_normal44_textobjects2() +func Test_normal44_textobjects2() " basic testing for is and as text objects new call append(0, ['This is a test. With some sentences!', '', 'Even with a question? And one more. And no sentence here']) @@ -2262,7 +2382,7 @@ func! Test_normal44_textobjects2() bw! endfunc -func! Test_normal45_drop() +func Test_normal45_drop() if !has('dnd') " The ~ register does not exist call assert_beeps('norm! "~') @@ -2280,7 +2400,7 @@ func! Test_normal45_drop() bw! endfunc -func! Test_normal46_ignore() +func Test_normal46_ignore() new " How to test this? " let's just for now test, that the buffer @@ -2299,7 +2419,7 @@ func! Test_normal46_ignore() bw! endfunc -func! Test_normal47_visual_buf_wipe() +func Test_normal47_visual_buf_wipe() " This was causing a crash or ml_get error. enew! call setline(1,'xxx') @@ -2313,7 +2433,7 @@ func! Test_normal47_visual_buf_wipe() set nomodified endfunc -func! Test_normal47_autocmd() +func Test_normal47_autocmd() " disabled, does not seem to be possible currently throw "Skipped: not possible to test cursorhold autocmd while waiting for input in normal_cmd" new @@ -2331,14 +2451,14 @@ func! Test_normal47_autocmd() bw! endfunc -func! Test_normal48_wincmd() +func Test_normal48_wincmd() new exe "norm! \<c-w>c" call assert_equal(1, winnr('$')) call assert_fails(":norm! \<c-w>c", "E444") endfunc -func! Test_normal49_counts() +func Test_normal49_counts() new call setline(1, 'one two three four five six seven eight nine ten') 1 @@ -2347,7 +2467,7 @@ func! Test_normal49_counts() bw! endfunc -func! Test_normal50_commandline() +func Test_normal50_commandline() if !has("timers") || !has("cmdline_hist") || !has("vertsplit") return endif @@ -2378,7 +2498,7 @@ func! Test_normal50_commandline() bw! endfunc -func! Test_normal51_FileChangedRO() +func Test_normal51_FileChangedRO() if !has("autocmd") return endif @@ -2395,7 +2515,7 @@ func! Test_normal51_FileChangedRO() call delete("Xreadonly.log") endfunc -func! Test_normal52_rl() +func Test_normal52_rl() if !has("rightleft") return endif @@ -2428,7 +2548,7 @@ func! Test_normal52_rl() bw! endfunc -func! Test_normal53_digraph() +func Test_normal53_digraph() if !has('digraphs') return endif @@ -2474,6 +2594,15 @@ func Test_normal_large_count() bwipe! endfunc +func Test_delete_until_paragraph() + new + normal grádv} + call assert_equal('á', getline(1)) + normal grád} + call assert_equal('', getline(1)) + bwipe! +endfunc + " Test for the gr (virtual replace) command " Test for the bug fixed by 7.4.387 func Test_gr_command() @@ -2516,13 +2645,27 @@ func Test_changelist() let &ul = save_ul endfunc -func Test_delete_until_paragraph() - new - normal grádv} - call assert_equal('á', getline(1)) - normal grád} - call assert_equal('', getline(1)) - bwipe! +func Test_nv_hat_count() + %bwipeout! + let l:nr = bufnr('%') + 1 + call assert_fails(':execute "normal! ' . l:nr . '\<C-^>"', 'E92') + + edit Xfoo + let l:foo_nr = bufnr('Xfoo') + + edit Xbar + let l:bar_nr = bufnr('Xbar') + + " Make sure we are not just using the alternate file. + edit Xbaz + + call feedkeys(l:foo_nr . "\<C-^>", 'tx') + call assert_equal('Xfoo', fnamemodify(bufname('%'), ':t')) + + call feedkeys(l:bar_nr . "\<C-^>", 'tx') + call assert_equal('Xbar', fnamemodify(bufname('%'), ':t')) + + %bwipeout! endfunc func Test_message_when_using_ctrl_c() @@ -2617,3 +2760,105 @@ Piece of Java close! endfunc + +fun! Test_normal_gdollar_cmd() + if !has("jumplist") + return + endif + " Tests for g cmds + call Setup_NewWindow() + " Make long lines that will wrap + %s/$/\=repeat(' foobar', 10)/ + 20vsp + set wrap + " Test for g$ with count + norm! gg + norm! 0vg$y + call assert_equal(20, col("'>")) + call assert_equal('1 foobar foobar foob', getreg(0)) + norm! gg + norm! 0v4g$y + call assert_equal(72, col("'>")) + call assert_equal('1 foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar'.."\n", getreg(0)) + norm! gg + norm! 0v6g$y + call assert_equal(40, col("'>")) + call assert_equal('1 foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar'.. "\n".. + \ '2 foobar foobar foobar foobar foobar foo', getreg(0)) + set nowrap + " clean up + norm! gg + norm! 0vg$y + call assert_equal(20, col("'>")) + call assert_equal('1 foobar foobar foob', getreg(0)) + norm! gg + norm! 0v4g$y + call assert_equal(20, col("'>")) + call assert_equal('1 foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar'.. "\n".. + \ '2 foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar'.. "\n".. + \ '3 foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar'.. "\n".. + \ '4 foobar foobar foob', getreg(0)) + norm! gg + norm! 0v6g$y + call assert_equal(20, col("'>")) + call assert_equal('1 foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar'.. "\n".. + \ '2 foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar'.. "\n".. + \ '3 foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar'.. "\n".. + \ '4 foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar'.. "\n".. + \ '5 foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar'.. "\n".. + \ '6 foobar foobar foob', getreg(0)) + " Move to last line, also down movement is not possible, should still move + " the cursor to the last visible char + norm! G + norm! 0v6g$y + call assert_equal(20, col("'>")) + call assert_equal('100 foobar foobar fo', getreg(0)) + bw! +endfunc + +func Test_normal_gk() + " needs 80 column new window + new + vert 80new + put =[repeat('x',90)..' {{{1', 'x {{{1'] + norm! gk + " In a 80 column wide terminal the window will be only 78 char + " (because Vim will leave space for the other window), + " but if the terminal is larger, it will be 80 chars, so verify the + " cursor column correctly. + call assert_equal(winwidth(0)+1, col('.')) + call assert_equal(winwidth(0)+1, virtcol('.')) + norm! j + call assert_equal(6, col('.')) + call assert_equal(6, virtcol('.')) + norm! gk + call assert_equal(95, col('.')) + call assert_equal(95, virtcol('.')) + bw! + bw! + + " needs 80 column new window + new + vert 80new + set number + set numberwidth=10 + set cpoptions+=n + put =[repeat('0',90), repeat('1',90)] + norm! 075l + call assert_equal(76, col('.')) + norm! gk + call assert_equal(1, col('.')) + norm! gk + call assert_equal(76, col('.')) + norm! gk + call assert_equal(1, col('.')) + norm! gj + call assert_equal(76, col('.')) + norm! gj + call assert_equal(1, col('.')) + norm! gj + call assert_equal(76, col('.')) + bw! + bw! + set cpoptions& number& numberwidth& +endfunc diff --git a/src/nvim/testdir/test_options.vim b/src/nvim/testdir/test_options.vim index f4f5cbca61..6fcc372591 100644 --- a/src/nvim/testdir/test_options.vim +++ b/src/nvim/testdir/test_options.vim @@ -476,13 +476,19 @@ func Test_shortmess_F2() call assert_match('file2', execute('bn', '')) set shortmess+=F call assert_true(empty(execute('bn', ''))) + " call assert_false(test_getvalue('need_fileinfo')) call assert_true(empty(execute('bn', ''))) + " call assert_false(test_getvalue('need_fileinfo')) set hidden call assert_true(empty(execute('bn', ''))) + " call assert_false(test_getvalue('need_fileinfo')) call assert_true(empty(execute('bn', ''))) + " call assert_false(test_getvalue('need_fileinfo')) set nohidden call assert_true(empty(execute('bn', ''))) + " call assert_false(test_getvalue('need_fileinfo')) call assert_true(empty(execute('bn', ''))) + " call assert_false(test_getvalue('need_fileinfo')) " Accommodate Nvim default. set shortmess-=F call assert_match('file1', execute('bn', '')) diff --git a/src/nvim/testdir/test_popup.vim b/src/nvim/testdir/test_popup.vim index 53df30bb19..8083672808 100644 --- a/src/nvim/testdir/test_popup.vim +++ b/src/nvim/testdir/test_popup.vim @@ -1,6 +1,7 @@ " Test for completion menu source shared.vim +source screendump.vim let g:months = ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'] let g:setting = '' @@ -680,18 +681,15 @@ func Test_popup_and_window_resize() call term_sendkeys(buf, "\<c-v>") call term_wait(buf, 100) " popup first entry "!" must be at the top - call WaitFor({-> term_getline(buf, 1) =~ "^!"}) - call assert_match('^!\s*$', term_getline(buf, 1)) + call WaitForAssert({-> assert_match('^!\s*$', term_getline(buf, 1))}) exe 'resize +' . (h - 1) call term_wait(buf, 100) redraw! " popup shifted down, first line is now empty - call WaitFor({-> term_getline(buf, 1) == ""}) - call assert_equal('', term_getline(buf, 1)) + call WaitForAssert({-> assert_equal('', term_getline(buf, 1))}) sleep 100m " popup is below cursor line and shows first match "!" - call WaitFor({-> term_getline(buf, term_getcursor(buf)[0] + 1) =~ "^!"}) - call assert_match('^!\s*$', term_getline(buf, term_getcursor(buf)[0] + 1)) + call WaitForAssert({-> assert_match('^!\s*$', term_getline(buf, term_getcursor(buf)[0] + 1))}) " cursor line also shows ! call assert_match('^!\s*$', term_getline(buf, term_getcursor(buf)[0])) bwipe! @@ -735,6 +733,39 @@ func Test_popup_and_preview_autocommand() bw! endfunc +func Test_popup_position() + if !CanRunVimInTerminal() + return + endif + let lines =<< trim END + 123456789_123456789_123456789_a + 123456789_123456789_123456789_b + 123 + END + call writefile(lines, 'Xtest') + let buf = RunVimInTerminal('Xtest', {}) + call term_sendkeys(buf, ":vsplit\<CR>") + + " default pumwidth in left window: overlap in right window + call term_sendkeys(buf, "GA\<C-N>") + call VerifyScreenDump(buf, 'Test_popup_position_01', {'rows': 8}) + call term_sendkeys(buf, "\<Esc>u") + + " default pumwidth: fill until right of window + call term_sendkeys(buf, "\<C-W>l") + call term_sendkeys(buf, "GA\<C-N>") + call VerifyScreenDump(buf, 'Test_popup_position_02', {'rows': 8}) + + " larger pumwidth: used as minimum width + call term_sendkeys(buf, "\<Esc>u") + call term_sendkeys(buf, ":set pumwidth=30\<CR>") + call term_sendkeys(buf, "GA\<C-N>") + call VerifyScreenDump(buf, 'Test_popup_position_03', {'rows': 8}) + + call term_sendkeys(buf, "\<Esc>u") + call StopVimInTerminal(buf) + call delete('Xtest') +endfunc func Test_popup_complete_backwards() new @@ -746,6 +777,16 @@ func Test_popup_complete_backwards() bwipe! endfunc +func Test_popup_complete_backwards_ctrl_p() + new + call setline(1, ['Post', 'Port', 'Po']) + let expected=['Post', 'Port', 'Port'] + call cursor(3,2) + call feedkeys("A\<C-P>\<C-N>rt\<cr>", 'tx') + call assert_equal(expected, getline(1,'$')) + bwipe! +endfunc + fun! Test_complete_o_tab() throw 'skipped: Nvim does not support test_override()' let s:o_char_pressed = 0 diff --git a/src/nvim/testdir/test_profile.vim b/src/nvim/testdir/test_profile.vim index 7e853eeac3..f3eb88abf0 100644 --- a/src/nvim/testdir/test_profile.vim +++ b/src/nvim/testdir/test_profile.vim @@ -6,34 +6,34 @@ endif source screendump.vim func Test_profile_func() - let lines = [ - \ 'profile start Xprofile_func.log', - \ 'profile func Foo*"', - \ "func! Foo1()", - \ "endfunc", - \ "func! Foo2()", - \ " let l:count = 100", - \ " while l:count > 0", - \ " let l:count = l:count - 1", - \ " endwhile", - \ "endfunc", - \ "func! Foo3()", - \ "endfunc", - \ "func! Bar()", - \ "endfunc", - \ "call Foo1()", - \ "call Foo1()", - \ "profile pause", - \ "call Foo1()", - \ "profile continue", - \ "call Foo2()", - \ "call Foo3()", - \ "call Bar()", - \ "if !v:profiling", - \ " delfunc Foo2", - \ "endif", - \ "delfunc Foo3", - \ ] + let lines =<< trim [CODE] + profile start Xprofile_func.log + profile func Foo* + func! Foo1() + endfunc + func! Foo2() + let l:count = 100 + while l:count > 0 + let l:count = l:count - 1 + endwhile + endfunc + func! Foo3() + endfunc + func! Bar() + endfunc + call Foo1() + call Foo1() + profile pause + call Foo1() + profile continue + call Foo2() + call Foo3() + call Bar() + if !v:profiling + delfunc Foo2 + endif + delfunc Foo3 + [CODE] call writefile(lines, 'Xprofile_func.vim') call system(v:progpath @@ -54,7 +54,7 @@ func Test_profile_func() call assert_equal(30, len(lines)) call assert_equal('FUNCTION Foo1()', lines[0]) - call assert_match('Defined:.*Xprofile_func.vim', lines[1]) + call assert_match('Defined:.*Xprofile_func.vim:3', lines[1]) call assert_equal('Called 2 times', lines[2]) call assert_match('^Total time:\s\+\d\+\.\d\+$', lines[3]) call assert_match('^ Self time:\s\+\d\+\.\d\+$', lines[4]) @@ -88,38 +88,38 @@ func Test_profile_func() endfunc func Test_profile_func_with_ifelse() - let lines = [ - \ "func! Foo1()", - \ " if 1", - \ " let x = 0", - \ " elseif 1", - \ " let x = 1", - \ " else", - \ " let x = 2", - \ " endif", - \ "endfunc", - \ "func! Foo2()", - \ " if 0", - \ " let x = 0", - \ " elseif 1", - \ " let x = 1", - \ " else", - \ " let x = 2", - \ " endif", - \ "endfunc", - \ "func! Foo3()", - \ " if 0", - \ " let x = 0", - \ " elseif 0", - \ " let x = 1", - \ " else", - \ " let x = 2", - \ " endif", - \ "endfunc", - \ "call Foo1()", - \ "call Foo2()", - \ "call Foo3()", - \ ] + let lines =<< trim [CODE] + func! Foo1() + if 1 + let x = 0 + elseif 1 + let x = 1 + else + let x = 2 + endif + endfunc + func! Foo2() + if 0 + let x = 0 + elseif 1 + let x = 1 + else + let x = 2 + endif + endfunc + func! Foo3() + if 0 + let x = 0 + elseif 0 + let x = 1 + else + let x = 2 + endif + endfunc + call Foo1() + call Foo2() + call Foo3() + [CODE] call writefile(lines, 'Xprofile_func.vim') call system(v:progpath @@ -198,41 +198,41 @@ func Test_profile_func_with_ifelse() endfunc func Test_profile_func_with_trycatch() - let lines = [ - \ "func! Foo1()", - \ " try", - \ " let x = 0", - \ " catch", - \ " let x = 1", - \ " finally", - \ " let x = 2", - \ " endtry", - \ "endfunc", - \ "func! Foo2()", - \ " try", - \ " throw 0", - \ " catch", - \ " let x = 1", - \ " finally", - \ " let x = 2", - \ " endtry", - \ "endfunc", - \ "func! Foo3()", - \ " try", - \ " throw 0", - \ " catch", - \ " throw 1", - \ " finally", - \ " let x = 2", - \ " endtry", - \ "endfunc", - \ "call Foo1()", - \ "call Foo2()", - \ "try", - \ " call Foo3()", - \ "catch", - \ "endtry", - \ ] + let lines =<< trim [CODE] + func! Foo1() + try + let x = 0 + catch + let x = 1 + finally + let x = 2 + endtry + endfunc + func! Foo2() + try + throw 0 + catch + let x = 1 + finally + let x = 2 + endtry + endfunc + func! Foo3() + try + throw 0 + catch + throw 1 + finally + let x = 2 + endtry + endfunc + call Foo1() + call Foo2() + try + call Foo3() + catch + endtry + [CODE] call writefile(lines, 'Xprofile_func.vim') call system(v:progpath @@ -311,15 +311,15 @@ func Test_profile_func_with_trycatch() endfunc func Test_profile_file() - let lines = [ - \ 'func! Foo()', - \ 'endfunc', - \ 'for i in range(10)', - \ ' " a comment', - \ ' call Foo()', - \ 'endfor', - \ 'call Foo()', - \ ] + let lines =<< trim [CODE] + func! Foo() + endfunc + for i in range(10) + " a comment + call Foo() + endfor + call Foo() + [CODE] call writefile(lines, 'Xprofile_file.vim') call system(v:progpath @@ -450,26 +450,27 @@ func Test_profile_truncate_mbyte() endfunc func Test_profdel_func() - let lines = [ - \ 'profile start Xprofile_file.log', - \ 'func! Foo1()', - \ 'endfunc', - \ 'func! Foo2()', - \ 'endfunc', - \ 'func! Foo3()', - \ 'endfunc', - \ '', - \ 'profile func Foo1', - \ 'profile func Foo2', - \ 'call Foo1()', - \ 'call Foo2()', - \ '', - \ 'profile func Foo3', - \ 'profdel func Foo2', - \ 'profdel func Foo3', - \ 'call Foo1()', - \ 'call Foo2()', - \ 'call Foo3()' ] + let lines =<< trim [CODE] + profile start Xprofile_file.log + func! Foo1() + endfunc + func! Foo2() + endfunc + func! Foo3() + endfunc + + profile func Foo1 + profile func Foo2 + call Foo1() + call Foo2() + + profile func Foo3 + profdel func Foo2 + profdel func Foo3 + call Foo1() + call Foo2() + call Foo3() + [CODE] call writefile(lines, 'Xprofile_file.vim') call system(v:progpath . ' -es --clean -c "so Xprofile_file.vim" -c q') call assert_equal(0, v:shell_error) @@ -496,14 +497,15 @@ endfunc func Test_profdel_star() " Foo() is invoked once before and once after 'profdel *'. " So profiling should report it only once. - let lines = [ - \ 'profile start Xprofile_file.log', - \ 'func! Foo()', - \ 'endfunc', - \ 'profile func Foo', - \ 'call Foo()', - \ 'profdel *', - \ 'call Foo()' ] + let lines =<< trim [CODE] + profile start Xprofile_file.log + func! Foo() + endfunc + profile func Foo + call Foo() + profdel * + call Foo() + [CODE] call writefile(lines, 'Xprofile_file.vim') call system(v:progpath . ' -es --clean -c "so Xprofile_file.vim" -c q') call assert_equal(0, v:shell_error) diff --git a/src/nvim/testdir/test_quickfix.vim b/src/nvim/testdir/test_quickfix.vim index b7f45aeeb1..d7b387c2c9 100644 --- a/src/nvim/testdir/test_quickfix.vim +++ b/src/nvim/testdir/test_quickfix.vim @@ -37,6 +37,8 @@ func s:setup_commands(cchar) command! -nargs=* Xgrepadd <mods> grepadd <args> command! -nargs=* Xhelpgrep helpgrep <args> command! -nargs=0 -count Xcc <count>cc + command! -count=1 -nargs=0 Xbelow <mods><count>cbelow + command! -count=1 -nargs=0 Xabove <mods><count>cabove let g:Xgetlist = function('getqflist') let g:Xsetlist = function('setqflist') call setqflist([], 'f') @@ -70,6 +72,8 @@ func s:setup_commands(cchar) command! -nargs=* Xgrepadd <mods> lgrepadd <args> command! -nargs=* Xhelpgrep lhelpgrep <args> command! -nargs=0 -count Xcc <count>ll + command! -count=1 -nargs=0 Xbelow <mods><count>lbelow + command! -count=1 -nargs=0 Xabove <mods><count>labove let g:Xgetlist = function('getloclist', [0]) let g:Xsetlist = function('setloclist', [0]) call setloclist(0, [], 'f') @@ -163,6 +167,12 @@ endfunc func XageTests(cchar) call s:setup_commands(a:cchar) + if a:cchar == 'l' + " No location list for the current window + call assert_fails('lolder', 'E776:') + call assert_fails('lnewer', 'E776:') + endif + let list = [{'bufnr': bufnr('%'), 'lnum': 1}] call g:Xsetlist(list) @@ -273,6 +283,27 @@ func Test_cwindow() call XwindowTests('l') endfunc +func Test_copenHeight() + copen + wincmd H + let height = winheight(0) + copen 10 + call assert_equal(height, winheight(0)) + quit +endfunc + +func Test_copenHeight_tabline() + set tabline=foo showtabline=2 + copen + wincmd H + let height = winheight(0) + copen 10 + call assert_equal(height, winheight(0)) + quit + set tabline& showtabline& +endfunc + + " Tests for the :cfile, :lfile, :caddfile, :laddfile, :cgetfile and :lgetfile " commands. func XfileTests(cchar) @@ -540,6 +571,8 @@ func s:test_xhelpgrep(cchar) " Search for non existing help string call assert_fails('Xhelpgrep a1b2c3', 'E480:') + " Invalid regular expression + call assert_fails('Xhelpgrep \@<!', 'E480:') endfunc func Test_helpgrep() @@ -775,68 +808,68 @@ func Test_efm1() return endif - let l = [ - \ '"Xtestfile", line 4.12: 1506-045 (S) Undeclared identifier fd_set.', - \ '"Xtestfile", line 6 col 19; this is an error', - \ 'gcc -c -DHAVE_CONFIsing-prototypes -I/usr/X11R6/include version.c', - \ 'Xtestfile:9: parse error before `asd''', - \ 'make: *** [vim] Error 1', - \ 'in file "Xtestfile" linenr 10: there is an error', - \ '', - \ '2 returned', - \ '"Xtestfile", line 11 col 1; this is an error', - \ '"Xtestfile", line 12 col 2; this is another error', - \ '"Xtestfile", line 14:10; this is an error in column 10', - \ '=Xtestfile=, line 15:10; this is another error, but in vcol 10 this time', - \ '"Xtestfile", linenr 16: yet another problem', - \ 'Error in "Xtestfile" at line 17:', - \ 'x should be a dot', - \ ' xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 17', - \ ' ^', - \ 'Error in "Xtestfile" at line 18:', - \ 'x should be a dot', - \ ' xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 18', - \ '.............^', - \ 'Error in "Xtestfile" at line 19:', - \ 'x should be a dot', - \ ' xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 19', - \ '--------------^', - \ 'Error in "Xtestfile" at line 20:', - \ 'x should be a dot', - \ ' xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 20', - \ ' ^', - \ '', - \ 'Does anyone know what is the problem and how to correction it?', - \ '"Xtestfile", line 21 col 9: What is the title of the quickfix window?', - \ '"Xtestfile", line 22 col 9: What is the title of the quickfix window?' - \ ] + let l =<< trim [DATA] + "Xtestfile", line 4.12: 1506-045 (S) Undeclared identifier fd_set. + "Xtestfile", line 6 col 19; this is an error + gcc -c -DHAVE_CONFIsing-prototypes -I/usr/X11R6/include version.c + Xtestfile:9: parse error before `asd' + make: *** [vim] Error 1 + in file "Xtestfile" linenr 10: there is an error + + 2 returned + "Xtestfile", line 11 col 1; this is an error + "Xtestfile", line 12 col 2; this is another error + "Xtestfile", line 14:10; this is an error in column 10 + =Xtestfile=, line 15:10; this is another error, but in vcol 10 this time + "Xtestfile", linenr 16: yet another problem + Error in "Xtestfile" at line 17: + x should be a dot + xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 17 + ^ + Error in "Xtestfile" at line 18: + x should be a dot + xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 18 + .............^ + Error in "Xtestfile" at line 19: + x should be a dot + xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 19 + --------------^ + Error in "Xtestfile" at line 20: + x should be a dot + xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 20 + ^ + + Does anyone know what is the problem and how to correction it? + "Xtestfile", line 21 col 9: What is the title of the quickfix window? + "Xtestfile", line 22 col 9: What is the title of the quickfix window? + [DATA] call writefile(l, 'Xerrorfile1') call writefile(l[:-2], 'Xerrorfile2') - let m = [ - \ ' xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 2', - \ ' xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 3', - \ ' xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 4', - \ ' xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 5', - \ ' xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 6', - \ ' xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 7', - \ ' xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 8', - \ ' xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 9', - \ ' xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 10', - \ ' xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 11', - \ ' xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 12', - \ ' xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 13', - \ ' xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 14', - \ ' xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 15', - \ ' xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 16', - \ ' xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 17', - \ ' xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 18', - \ ' xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 19', - \ ' xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 20', - \ ' xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 21', - \ ' xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 22' - \ ] + let m =<< [DATA] + xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 2 + xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 3 + xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 4 + xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 5 + xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 6 + xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 7 + xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 8 + xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 9 + xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 10 + xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 11 + xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 12 + xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 13 + xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 14 + xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 15 + xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 16 + xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 17 + xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 18 + xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 19 + xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 20 + xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 21 + xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 22 +[DATA] call writefile(m, 'Xtestfile') let save_efm = &efm @@ -895,20 +928,21 @@ func s:dir_stack_tests(cchar) let save_efm=&efm set efm=%DEntering\ dir\ '%f',%f:%l:%m,%XLeaving\ dir\ '%f' - let lines = ["Entering dir 'dir1/a'", - \ 'habits2.txt:1:Nine Healthy Habits', - \ "Entering dir 'b'", - \ 'habits3.txt:2:0 Hours of television', - \ 'habits2.txt:7:5 Small meals', - \ "Entering dir 'dir1/c'", - \ 'habits4.txt:3:1 Hour of exercise', - \ "Leaving dir 'dir1/c'", - \ "Leaving dir 'dir1/a'", - \ 'habits1.txt:4:2 Liters of water', - \ "Entering dir 'dir2'", - \ 'habits5.txt:5:3 Cups of hot green tea', - \ "Leaving dir 'dir2'" - \] + let lines =<< trim [DATA] + Entering dir 'dir1/a' + habits2.txt:1:Nine Healthy Habits + Entering dir 'b' + habits3.txt:2:0 Hours of television + habits2.txt:7:5 Small meals + Entering dir 'dir1/c' + habits4.txt:3:1 Hour of exercise + Leaving dir 'dir1/c' + Leaving dir 'dir1/a' + habits1.txt:4:2 Liters of water + Entering dir 'dir2' + habits5.txt:5:3 Cups of hot green tea + Leaving dir 'dir2 + [DATA] Xexpr "" for l in lines @@ -942,18 +976,20 @@ func Test_efm_dirstack() call mkdir('dir1/c') call mkdir('dir2') - let lines = ["Nine Healthy Habits", - \ "0 Hours of television", - \ "1 Hour of exercise", - \ "2 Liters of water", - \ "3 Cups of hot green tea", - \ "4 Short mental breaks", - \ "5 Small meals", - \ "6 AM wake up time", - \ "7 Minutes of laughter", - \ "8 Hours of sleep (at least)", - \ "9 PM end of the day and off to bed" - \ ] + let lines =<< trim [DATA] + Nine Healthy Habits, + 0 Hours of television, + 1 Hour of exercise, + 2 Liters of water, + 3 Cups of hot green tea, + 4 Short mental breaks, + 5 Small meals, + 6 AM wake up time, + 7 Minutes of laughter, + 8 Hours of sleep (at least), + 9 PM end of the day and off to bed + [DATA] + call writefile(lines, 'habits1.txt') call writefile(lines, 'dir1/a/habits2.txt') call writefile(lines, 'dir1/a/b/habits3.txt') @@ -1042,28 +1078,29 @@ func Test_efm2() set efm=%f:%s cexpr 'Xtestfile:Line search text' let l = getqflist() - call assert_equal(l[0].pattern, '^\VLine search text\$') - call assert_equal(l[0].lnum, 0) + call assert_equal('^\VLine search text\$', l[0].pattern) + call assert_equal(0, l[0].lnum) let l = split(execute('clist', ''), "\n") call assert_equal([' 1 Xtestfile:^\VLine search text\$: '], l) " Test for %P, %Q and %t format specifiers - let lines=["[Xtestfile1]", - \ "(1,17) error: ';' missing", - \ "(21,2) warning: variable 'z' not defined", - \ "(67,3) error: end of file found before string ended", - \ "--", - \ "", - \ "[Xtestfile2]", - \ "--", - \ "", - \ "[Xtestfile3]", - \ "NEW compiler v1.1", - \ "(2,2) warning: variable 'x' not defined", - \ "(67,3) warning: 's' already defined", - \ "--" - \] + let lines =<< trim [DATA] + [Xtestfile1] + (1,17) error: ';' missing + (21,2) warning: variable 'z' not defined + (67,3) error: end of file found before string ended + -- + + [Xtestfile2] + -- + + [Xtestfile3] + NEW compiler v1.1 + (2,2) warning: variable 'x' not defined + (67,3) warning: 's' already defined + -- + [DATA] set efm=%+P[%f]%r,(%l\\,%c)%*[\ ]%t%*[^:]:\ %m,%+Q--%r " To exercise the push/pop file functionality in quickfix, the test files " need to be created. @@ -1085,11 +1122,13 @@ func Test_efm2() call delete('Xtestfile3') " Tests for %E, %C and %Z format specifiers - let lines = ["Error 275", - \ "line 42", - \ "column 3", - \ "' ' expected after '--'" - \] + let lines =<< trim [DATA] + Error 275 + line 42 + column 3 + ' ' expected after '--' + [DATA] + set efm=%EError\ %n,%Cline\ %l,%Ccolumn\ %c,%Z%m cgetexpr lines let l = getqflist() @@ -1100,9 +1139,11 @@ func Test_efm2() call assert_equal("\n' ' expected after '--'", l[0].text) " Test for %> - let lines = ["Error in line 147 of foo.c:", - \"unknown variable 'i'" - \] + let lines =<< trim [DATA] + Error in line 147 of foo.c: + unknown variable 'i' + [DATA] + set efm=unknown\ variable\ %m,%E%>Error\ in\ line\ %l\ of\ %f:,%Z%m cgetexpr lines let l = getqflist() @@ -1111,21 +1152,21 @@ func Test_efm2() call assert_equal("\nunknown variable 'i'", l[0].text) " Test for %A, %C and other formats - let lines = [ - \"==============================================================", - \"FAIL: testGetTypeIdCachesResult (dbfacadeTest.DjsDBFacadeTest)", - \"--------------------------------------------------------------", - \"Traceback (most recent call last):", - \' File "unittests/dbfacadeTest.py", line 89, in testFoo', - \" self.assertEquals(34, dtid)", - \' File "/usr/lib/python2.2/unittest.py", line 286, in', - \" failUnlessEqual", - \" raise self.failureException, \\", - \"AssertionError: 34 != 33", - \"", - \"--------------------------------------------------------------", - \"Ran 27 tests in 0.063s" - \] + let lines =<< trim [DATA] + ============================================================== + FAIL: testGetTypeIdCachesResult (dbfacadeTest.DjsDBFacadeTest) + -------------------------------------------------------------- + Traceback (most recent call last): + File "unittests/dbfacadeTest.py", line 89, in testFoo + self.assertEquals(34, dtid) + File "/usr/lib/python2.2/unittest.py", line 286, in + failUnlessEqual + raise self.failureException, \\ + AssertionError: 34 != 33 + + -------------------------------------------------------------- + Ran 27 tests in 0.063s + [DATA] set efm=%C\ %.%#,%A\ \ File\ \"%f\"\\,\ line\ %l%.%#,%Z%[%^\ ]%\\@=%m cgetexpr lines let l = getqflist() @@ -1279,6 +1320,28 @@ func SetXlistTests(cchar, bnum) let l = g:Xgetlist() call g:Xsetlist(l) call assert_equal(0, g:Xgetlist()[0].valid) + " Adding a non-valid entry should not mark the list as having valid entries + call g:Xsetlist([{'bufnr':a:bnum, 'lnum':5, 'valid':0}], 'a') + Xwindow + call assert_equal(1, winnr('$')) + + " :cnext/:cprev should still work even with invalid entries in the list + let l = [{'bufnr' : a:bnum, 'lnum' : 1, 'text' : '1', 'valid' : 0}, + \ {'bufnr' : a:bnum, 'lnum' : 2, 'text' : '2', 'valid' : 0}] + call g:Xsetlist(l) + Xnext + call assert_equal(2, g:Xgetlist({'idx' : 0}).idx) + Xprev + call assert_equal(1, g:Xgetlist({'idx' : 0}).idx) + " :cnext/:cprev should still work after appending invalid entries to an + " empty list + call g:Xsetlist([]) + call g:Xsetlist(l, 'a') + Xnext + call assert_equal(2, g:Xgetlist({'idx' : 0}).idx) + Xprev + call assert_equal(1, g:Xgetlist({'idx' : 0}).idx) + call g:Xsetlist([{'text':'Text1', 'valid':1}]) Xwindow call assert_equal(2, winnr('$')) @@ -1579,6 +1642,14 @@ func Test_switchbuf() call assert_equal(3, tabpagenr('$')) tabfirst | enew | tabonly | only + set switchbuf=uselast + split + let last_winid = win_getid() + copen + exe "normal 1G\<CR>" + call assert_equal(last_winid, win_getid()) + enew | only + set switchbuf= edit Xqftestfile1 let file1_winid = win_getid() @@ -1955,6 +2026,18 @@ func Xproperty_tests(cchar) call g:Xsetlist([], 'r', {'items' : [{'filename' : 'F1', 'lnum' : 10, 'text' : 'L10'}]}) call assert_equal('TestTitle', g:Xgetlist({'title' : 1}).title) + " Test for getting id of window associated with a location list window + if a:cchar == 'l' + only + call assert_equal(0, g:Xgetlist({'all' : 1}).filewinid) + let wid = win_getid() + Xopen + call assert_equal(wid, g:Xgetlist({'filewinid' : 1}).filewinid) + wincmd w + call assert_equal(0, g:Xgetlist({'filewinid' : 1}).filewinid) + only + endif + " The following used to crash Vim with address sanitizer call g:Xsetlist([], 'f') call g:Xsetlist([], 'a', {'items' : [{'filename':'F1', 'lnum':10}]}) @@ -2317,6 +2400,12 @@ func XvimgrepTests(cchar) call assert_equal('Xtestfile2', bufname('')) call assert_equal('Editor:Emacs EmAcS', l[0].text) + " Test for unloading a buffer after vimgrep searched the buffer + %bwipe + Xvimgrep /Editor/j Xtestfile* + call assert_equal(0, getbufinfo('Xtestfile1')[0].loaded) + call assert_equal([], getbufinfo('Xtestfile2')) + call delete('Xtestfile1') call delete('Xtestfile2') endfunc @@ -2489,7 +2578,7 @@ func Test_file_from_copen() cclose augroup! QF_Test -endfunction +endfunc func Test_resize_from_copen() augroup QF_Test @@ -2864,185 +2953,101 @@ func Test_qf_id() call Xqfid_tests('l') endfunc -func Test_getqflist_invalid_nr() - " The following commands used to crash Vim - cexpr "" - call getqflist({'nr' : $XXX_DOES_NOT_EXIST_XXX}) - - " Cleanup - call setqflist([], 'r') -endfunc - -" Test for shortening/simplifying the file name when opening the -" quickfix window or when displaying the quickfix list -func Test_shorten_fname() - if !has('unix') - return - endif - %bwipe - " Create a quickfix list with a absolute path filename - let fname = getcwd() . '/test_quickfix.vim' - call setqflist([], ' ', {'lines':[fname . ":20:Line20"], 'efm':'%f:%l:%m'}) - call assert_equal(fname, bufname('test_quickfix.vim')) - " Opening the quickfix window should simplify the file path - cwindow - call assert_equal('test_quickfix.vim', bufname('test_quickfix.vim')) - cclose - %bwipe - " Create a quickfix list with a absolute path filename - call setqflist([], ' ', {'lines':[fname . ":20:Line20"], 'efm':'%f:%l:%m'}) - call assert_equal(fname, bufname('test_quickfix.vim')) - " Displaying the quickfix list should simplify the file path - silent! clist - call assert_equal('test_quickfix.vim', bufname('test_quickfix.vim')) -endfunc - -" Quickfix title tests -" In the below tests, 'exe "cmd"' is used to invoke the quickfix commands. -" Otherwise due to indentation, the title is set with spaces at the beginning -" of the command. -func Test_qftitle() - call writefile(["F1:1:Line1"], 'Xerr') - - " :cexpr - exe "cexpr readfile('Xerr')" - call assert_equal(":cexpr readfile('Xerr')", getqflist({'title' : 1}).title) - - " :cgetexpr - exe "cgetexpr readfile('Xerr')" - call assert_equal(":cgetexpr readfile('Xerr')", - \ getqflist({'title' : 1}).title) - - " :caddexpr - call setqflist([], 'f') - exe "caddexpr readfile('Xerr')" - call assert_equal(":caddexpr readfile('Xerr')", - \ getqflist({'title' : 1}).title) - - " :cbuffer - new Xerr - exe "cbuffer" - call assert_equal(':cbuffer (Xerr)', getqflist({'title' : 1}).title) - - " :cgetbuffer - edit Xerr - exe "cgetbuffer" - call assert_equal(':cgetbuffer (Xerr)', getqflist({'title' : 1}).title) - - " :caddbuffer - call setqflist([], 'f') - edit Xerr - exe "caddbuffer" - call assert_equal(':caddbuffer (Xerr)', getqflist({'title' : 1}).title) - - " :cfile - exe "cfile Xerr" - call assert_equal(':cfile Xerr', getqflist({'title' : 1}).title) - - " :cgetfile - exe "cgetfile Xerr" - call assert_equal(':cgetfile Xerr', getqflist({'title' : 1}).title) - - " :caddfile - call setqflist([], 'f') - exe "caddfile Xerr" - call assert_equal(':caddfile Xerr', getqflist({'title' : 1}).title) - - " :grep - set grepprg=internal - exe "grep F1 Xerr" - call assert_equal(':grep F1 Xerr', getqflist({'title' : 1}).title) - - " :grepadd - call setqflist([], 'f') - exe "grepadd F1 Xerr" - call assert_equal(':grepadd F1 Xerr', getqflist({'title' : 1}).title) - set grepprg&vim - - " :vimgrep - exe "vimgrep F1 Xerr" - call assert_equal(':vimgrep F1 Xerr', getqflist({'title' : 1}).title) +func Xqfjump_tests(cchar) + call s:setup_commands(a:cchar) - " :vimgrepadd - call setqflist([], 'f') - exe "vimgrepadd F1 Xerr" - call assert_equal(':vimgrepadd F1 Xerr', getqflist({'title' : 1}).title) + call writefile(["Line1\tFoo", "Line2"], 'F1') + call writefile(["Line1\tBar", "Line2"], 'F2') + call writefile(["Line1\tBaz", "Line2"], 'F3') - call setqflist(['F1:10:L10'], ' ') - call assert_equal(':setqflist()', getqflist({'title' : 1}).title) + call g:Xsetlist([], 'f') - call setqflist([], 'f') - call setqflist(['F1:10:L10'], 'a') - call assert_equal(':setqflist()', getqflist({'title' : 1}).title) + " Tests for + " Jumping to a line using a pattern + " Jumping to a column greater than the last column in a line + " Jumping to a line greater than the last line in the file + let l = [] + for i in range(1, 7) + call add(l, {}) + endfor + let l[0].filename='F1' + let l[0].pattern='Line1' + let l[1].filename='F2' + let l[1].pattern='Line1' + let l[2].filename='F3' + let l[2].pattern='Line1' + let l[3].filename='F3' + let l[3].lnum=1 + let l[3].col=9 + let l[3].vcol=1 + let l[4].filename='F3' + let l[4].lnum=99 + let l[5].filename='F3' + let l[5].lnum=1 + let l[5].col=99 + let l[5].vcol=1 + let l[6].filename='F3' + let l[6].pattern='abcxyz' - call setqflist([], 'f') - call setqflist(['F1:10:L10'], 'r') - call assert_equal(':setqflist()', getqflist({'title' : 1}).title) + call g:Xsetlist([], ' ', {'items' : l}) + Xopen | only + 2Xnext + call assert_equal(3, g:Xgetlist({'idx' : 0}).idx) + call assert_equal('F3', bufname('%')) + Xnext + call assert_equal(7, col('.')) + Xnext + call assert_equal(2, line('.')) + Xnext + call assert_equal(9, col('.')) + 2 + Xnext + call assert_equal(2, line('.')) - close - call delete('Xerr') + if a:cchar == 'l' + " When jumping to a location list entry in the location list window and + " no usable windows are available, then a new window should be opened. + enew! | new | only + call g:Xsetlist([], 'f') + setlocal buftype=nofile + new + call g:Xsetlist([], ' ', {'lines' : ['F1:1:1:Line1', 'F1:2:2:Line2', 'F2:1:1:Line1', 'F2:2:2:Line2', 'F3:1:1:Line1', 'F3:2:2:Line2']}) + Xopen + let winid = win_getid() + wincmd p + close + call win_gotoid(winid) + Xnext + call assert_equal(3, winnr('$')) + call assert_equal(1, winnr()) + call assert_equal(2, line('.')) - call setqflist([], ' ', {'title' : 'Errors'}) - copen - call assert_equal('Errors', w:quickfix_title) - call setqflist([], 'r', {'items' : [{'filename' : 'a.c', 'lnum' : 10}]}) - call assert_equal('Errors', w:quickfix_title) - cclose -endfunc + " When jumping to an entry in the location list window and the window + " associated with the location list is not present and a window containing + " the file is already present, then that window should be used. + close + belowright new + call g:Xsetlist([], 'f') + edit F3 + call win_gotoid(winid) + Xlast + call assert_equal(3, winnr()) + call assert_equal(6, g:Xgetlist({'size' : 1}).size) + call assert_equal(winid, g:Xgetlist({'winid' : 1}).winid) + endif -" Test for the position of the quickfix and location list window -func Test_qfwin_pos() - " Open two windows + " Cleanup + enew! new | only - new - cexpr ['F1:10:L10'] - copen - " Quickfix window should be the bottom most window - call assert_equal(3, winnr()) - close - " Open at the very top - wincmd t - topleft copen - call assert_equal(1, winnr()) - close - " open left of the current window - wincmd t - below new - leftabove copen - call assert_equal(2, winnr()) - close - " open right of the current window - rightbelow copen - call assert_equal(3, winnr()) - close -endfunc -" The following test used to crash Vim -func Test_lhelpgrep_autocmd() - lhelpgrep quickfix - autocmd QuickFixCmdPost * call setloclist(0, [], 'f') - lhelpgrep buffer - call assert_equal('help', &filetype) - call assert_equal(0, getloclist(0, {'nr' : '$'}).nr) - lhelpgrep tabpage - call assert_equal('help', &filetype) - call assert_equal(1, getloclist(0, {'nr' : '$'}).nr) - au! QuickFixCmdPost - new | only + call delete('F1') + call delete('F2') + call delete('F3') endfunc -" Test to make sure that an empty quickfix buffer is not reused for loading -" a normal buffer. -func Test_empty_qfbuf() - enew | only - call writefile(["Test"], 'Xfile1') - call setqflist([], 'f') - copen | only - let qfbuf = bufnr('') - edit Xfile1 - call assert_notequal(qfbuf, bufnr('')) - enew - call delete('Xfile1') +func Test_qfjump() + call Xqfjump_tests('c') + call Xqfjump_tests('l') endfunc " Tests for the getqflist() and getloclist() functions when the list is not @@ -3061,7 +3066,17 @@ func Xgetlist_empty_tests(cchar) call assert_equal('', g:Xgetlist({'title' : 0}).title) call assert_equal(0, g:Xgetlist({'winid' : 0}).winid) call assert_equal(0, g:Xgetlist({'changedtick' : 0}).changedtick) - call assert_equal({'context' : '', 'id' : 0, 'idx' : 0, 'items' : [], 'nr' : 0, 'size' : 0, 'title' : '', 'winid' : 0, 'changedtick': 0}, g:Xgetlist({'all' : 0})) + if a:cchar == 'c' + call assert_equal({'context' : '', 'id' : 0, 'idx' : 0, + \ 'items' : [], 'nr' : 0, 'size' : 0, + \ 'title' : '', 'winid' : 0, 'changedtick': 0}, + \ g:Xgetlist({'all' : 0})) + else + call assert_equal({'context' : '', 'id' : 0, 'idx' : 0, + \ 'items' : [], 'nr' : 0, 'size' : 0, 'title' : '', + \ 'winid' : 0, 'changedtick': 0, 'filewinid' : 0}, + \ g:Xgetlist({'all' : 0})) + endif " Quickfix window with empty stack silent! Xopen @@ -3094,7 +3109,16 @@ func Xgetlist_empty_tests(cchar) call assert_equal('', g:Xgetlist({'id' : qfid, 'title' : 0}).title) call assert_equal(0, g:Xgetlist({'id' : qfid, 'winid' : 0}).winid) call assert_equal(0, g:Xgetlist({'id' : qfid, 'changedtick' : 0}).changedtick) - call assert_equal({'context' : '', 'id' : 0, 'idx' : 0, 'items' : [], 'nr' : 0, 'size' : 0, 'title' : '', 'winid' : 0, 'changedtick' : 0}, g:Xgetlist({'id' : qfid, 'all' : 0})) + if a:cchar == 'c' + call assert_equal({'context' : '', 'id' : 0, 'idx' : 0, 'items' : [], + \ 'nr' : 0, 'size' : 0, 'title' : '', 'winid' : 0, + \ 'changedtick' : 0}, g:Xgetlist({'id' : qfid, 'all' : 0})) + else + call assert_equal({'context' : '', 'id' : 0, 'idx' : 0, 'items' : [], + \ 'nr' : 0, 'size' : 0, 'title' : '', 'winid' : 0, + \ 'changedtick' : 0, 'filewinid' : 0}, + \ g:Xgetlist({'id' : qfid, 'all' : 0})) + endif " Non-existing quickfix list number call assert_equal('', g:Xgetlist({'nr' : 5, 'context' : 0}).context) @@ -3106,7 +3130,16 @@ func Xgetlist_empty_tests(cchar) call assert_equal('', g:Xgetlist({'nr' : 5, 'title' : 0}).title) call assert_equal(0, g:Xgetlist({'nr' : 5, 'winid' : 0}).winid) call assert_equal(0, g:Xgetlist({'nr' : 5, 'changedtick' : 0}).changedtick) - call assert_equal({'context' : '', 'id' : 0, 'idx' : 0, 'items' : [], 'nr' : 0, 'size' : 0, 'title' : '', 'winid' : 0, 'changedtick' : 0}, g:Xgetlist({'nr' : 5, 'all' : 0})) + if a:cchar == 'c' + call assert_equal({'context' : '', 'id' : 0, 'idx' : 0, 'items' : [], + \ 'nr' : 0, 'size' : 0, 'title' : '', 'winid' : 0, + \ 'changedtick' : 0}, g:Xgetlist({'nr' : 5, 'all' : 0})) + else + call assert_equal({'context' : '', 'id' : 0, 'idx' : 0, 'items' : [], + \ 'nr' : 0, 'size' : 0, 'title' : '', 'winid' : 0, + \ 'changedtick' : 0, 'filewinid' : 0}, + \ g:Xgetlist({'nr' : 5, 'all' : 0})) + endif endfunc func Test_getqflist() @@ -3114,6 +3147,16 @@ func Test_getqflist() call Xgetlist_empty_tests('l') endfunc + +func Test_getqflist_invalid_nr() + " The following commands used to crash Vim + cexpr "" + call getqflist({'nr' : $XXX_DOES_NOT_EXIST_XXX}) + + " Cleanup + call setqflist([], 'r') +endfunc + " Tests for the quickfix/location list changedtick func Xqftick_tests(cchar) call s:setup_commands(a:cchar) @@ -3172,6 +3215,41 @@ func Test_qf_tick() call Xqftick_tests('l') endfunc +" Test helpgrep with lang specifier +func Xtest_helpgrep_with_lang_specifier(cchar) + call s:setup_commands(a:cchar) + Xhelpgrep Vim@en + call assert_equal('help', &filetype) + call assert_notequal(0, g:Xgetlist({'nr' : '$'}).nr) + new | only +endfunc + +func Test_helpgrep_with_lang_specifier() + call Xtest_helpgrep_with_lang_specifier('c') + call Xtest_helpgrep_with_lang_specifier('l') +endfunc + +" The following test used to crash Vim. +" Open the location list window and close the regular window associated with +" the location list. When the garbage collection runs now, it incorrectly +" marks the location list context as not in use and frees the context. +func Test_ll_window_ctx() + call setloclist(0, [], 'f') + call setloclist(0, [], 'a', {'context' : []}) + lopen | only + call test_garbagecollect_now() + echo getloclist(0, {'context' : 1}).context + enew | only +endfunc + +" The following test used to crash vim +func Test_lfile_crash() + sp Xtest + au QuickFixCmdPre * bw + call assert_fails('lfile', 'E40') + au! QuickFixCmdPre +endfunc + " The following test used to crash vim func Test_lbuffer_crash() sv Xtest @@ -3195,7 +3273,28 @@ func Test_lexpr_crash() augroup QF_Test au! augroup END + + enew | only + augroup QF_Test + au! + au BufNew * call setloclist(0, [], 'f') + augroup END + lexpr 'x:1:x' + augroup QF_Test + au! + augroup END + enew | only + lexpr '' + lopen + augroup QF_Test + au! + au FileType * call setloclist(0, [], 'f') + augroup END + lexpr '' + augroup QF_Test + au! + augroup END endfunc " The following test used to crash Vim @@ -3212,122 +3311,31 @@ func Test_lvimgrep_crash() enew | only endfunc -func Xqfjump_tests(cchar) - call s:setup_commands(a:cchar) - - call writefile(["Line1\tFoo", "Line2"], 'F1') - call writefile(["Line1\tBar", "Line2"], 'F2') - call writefile(["Line1\tBaz", "Line2"], 'F3') - - call g:Xsetlist([], 'f') - - " Tests for - " Jumping to a line using a pattern - " Jumping to a column greater than the last column in a line - " Jumping to a line greater than the last line in the file - let l = [] - for i in range(1, 7) - call add(l, {}) - endfor - let l[0].filename='F1' - let l[0].pattern='Line1' - let l[1].filename='F2' - let l[1].pattern='Line1' - let l[2].filename='F3' - let l[2].pattern='Line1' - let l[3].filename='F3' - let l[3].lnum=1 - let l[3].col=9 - let l[3].vcol=1 - let l[4].filename='F3' - let l[4].lnum=99 - let l[5].filename='F3' - let l[5].lnum=1 - let l[5].col=99 - let l[5].vcol=1 - let l[6].filename='F3' - let l[6].pattern='abcxyz' - - call g:Xsetlist([], ' ', {'items' : l}) - Xopen | only - 2Xnext - call assert_equal(3, g:Xgetlist({'idx' : 0}).idx) - call assert_equal('F3', bufname('%')) - Xnext - call assert_equal(7, col('.')) - Xnext - call assert_equal(2, line('.')) - Xnext - call assert_equal(9, col('.')) - 2 - Xnext - call assert_equal(2, line('.')) - - if a:cchar == 'l' - " When jumping to a location list entry in the location list window and - " no usable windows are available, then a new window should be opened. - enew! | new | only - call g:Xsetlist([], 'f') - setlocal buftype=nofile - new - call g:Xsetlist([], ' ', {'lines' : ['F1:1:1:Line1', 'F1:2:2:Line2', 'F2:1:1:Line1', 'F2:2:2:Line2', 'F3:1:1:Line1', 'F3:2:2:Line2']}) - Xopen - let winid = win_getid() - wincmd p - close - call win_gotoid(winid) - Xnext - call assert_equal(3, winnr('$')) - call assert_equal(1, winnr()) - call assert_equal(2, line('.')) - - " When jumping to an entry in the location list window and the window - " associated with the location list is not present and a window containing - " the file is already present, then that window should be used. - close - belowright new - call g:Xsetlist([], 'f') - edit F3 - call win_gotoid(winid) - Xlast - call assert_equal(3, winnr()) - call assert_equal(6, g:Xgetlist({'size' : 1}).size) - call assert_equal(winid, g:Xgetlist({'winid' : 1}).winid) - endif - - " Cleanup - enew! +" Test for the position of the quickfix and location list window +func Test_qfwin_pos() + " Open two windows new | only - - call delete('F1') - call delete('F2') - call delete('F3') -endfunc - -func Test_qfjump() - call Xqfjump_tests('c') - call Xqfjump_tests('l') -endfunc - -" The following test used to crash Vim. -" Open the location list window and close the regular window associated with -" the location list. When the garbage collection runs now, it incorrectly -" marks the location list context as not in use and frees the context. -func Test_ll_window_ctx() - call setloclist(0, [], 'f') - call setloclist(0, [], 'a', {'context' : []}) - lopen | only - call test_garbagecollect_now() - echo getloclist(0, {'context' : 1}).context - enew | only -endfunc - -" The following test used to crash vim -func Test_lfile_crash() - sp Xtest - au QuickFixCmdPre * bw - call assert_fails('lfile', 'E40') - au! QuickFixCmdPre + new + cexpr ['F1:10:L10'] + copen + " Quickfix window should be the bottom most window + call assert_equal(3, winnr()) + close + " Open at the very top + wincmd t + topleft copen + call assert_equal(1, winnr()) + close + " open left of the current window + wincmd t + below new + leftabove copen + call assert_equal(2, winnr()) + close + " open right of the current window + rightbelow copen + call assert_equal(3, winnr()) + close endfunc " Tests for quickfix/location lists changed by autocommands when @@ -3371,6 +3379,137 @@ func Test_vimgrep_autocmd() call setqflist([], 'f') endfunc +" The following test used to crash Vim +func Test_lhelpgrep_autocmd() + lhelpgrep quickfix + autocmd QuickFixCmdPost * call setloclist(0, [], 'f') + lhelpgrep buffer + call assert_equal('help', &filetype) + call assert_equal(0, getloclist(0, {'nr' : '$'}).nr) + lhelpgrep tabpage + call assert_equal('help', &filetype) + call assert_equal(1, getloclist(0, {'nr' : '$'}).nr) + au! QuickFixCmdPost + new | only +endfunc + +" Test for shortening/simplifying the file name when opening the +" quickfix window or when displaying the quickfix list +func Test_shorten_fname() + if !has('unix') + return + endif + %bwipe + " Create a quickfix list with a absolute path filename + let fname = getcwd() . '/test_quickfix.vim' + call setqflist([], ' ', {'lines':[fname . ":20:Line20"], 'efm':'%f:%l:%m'}) + call assert_equal(fname, bufname('test_quickfix.vim')) + " Opening the quickfix window should simplify the file path + cwindow + call assert_equal('test_quickfix.vim', bufname('test_quickfix.vim')) + cclose + %bwipe + " Create a quickfix list with a absolute path filename + call setqflist([], ' ', {'lines':[fname . ":20:Line20"], 'efm':'%f:%l:%m'}) + call assert_equal(fname, bufname('test_quickfix.vim')) + " Displaying the quickfix list should simplify the file path + silent! clist + call assert_equal('test_quickfix.vim', bufname('test_quickfix.vim')) +endfunc + +" Quickfix title tests +" In the below tests, 'exe "cmd"' is used to invoke the quickfix commands. +" Otherwise due to indentation, the title is set with spaces at the beginning +" of the command. +func Test_qftitle() + call writefile(["F1:1:Line1"], 'Xerr') + + " :cexpr + exe "cexpr readfile('Xerr')" + call assert_equal(":cexpr readfile('Xerr')", getqflist({'title' : 1}).title) + + " :cgetexpr + exe "cgetexpr readfile('Xerr')" + call assert_equal(":cgetexpr readfile('Xerr')", + \ getqflist({'title' : 1}).title) + + " :caddexpr + call setqflist([], 'f') + exe "caddexpr readfile('Xerr')" + call assert_equal(":caddexpr readfile('Xerr')", + \ getqflist({'title' : 1}).title) + + " :cbuffer + new Xerr + exe "cbuffer" + call assert_equal(':cbuffer (Xerr)', getqflist({'title' : 1}).title) + + " :cgetbuffer + edit Xerr + exe "cgetbuffer" + call assert_equal(':cgetbuffer (Xerr)', getqflist({'title' : 1}).title) + + " :caddbuffer + call setqflist([], 'f') + edit Xerr + exe "caddbuffer" + call assert_equal(':caddbuffer (Xerr)', getqflist({'title' : 1}).title) + + " :cfile + exe "cfile Xerr" + call assert_equal(':cfile Xerr', getqflist({'title' : 1}).title) + + " :cgetfile + exe "cgetfile Xerr" + call assert_equal(':cgetfile Xerr', getqflist({'title' : 1}).title) + + " :caddfile + call setqflist([], 'f') + exe "caddfile Xerr" + call assert_equal(':caddfile Xerr', getqflist({'title' : 1}).title) + + " :grep + set grepprg=internal + exe "grep F1 Xerr" + call assert_equal(':grep F1 Xerr', getqflist({'title' : 1}).title) + + " :grepadd + call setqflist([], 'f') + exe "grepadd F1 Xerr" + call assert_equal(':grepadd F1 Xerr', getqflist({'title' : 1}).title) + set grepprg&vim + + " :vimgrep + exe "vimgrep F1 Xerr" + call assert_equal(':vimgrep F1 Xerr', getqflist({'title' : 1}).title) + + " :vimgrepadd + call setqflist([], 'f') + exe "vimgrepadd F1 Xerr" + call assert_equal(':vimgrepadd F1 Xerr', getqflist({'title' : 1}).title) + + call setqflist(['F1:10:L10'], ' ') + call assert_equal(':setqflist()', getqflist({'title' : 1}).title) + + call setqflist([], 'f') + call setqflist(['F1:10:L10'], 'a') + call assert_equal(':setqflist()', getqflist({'title' : 1}).title) + + call setqflist([], 'f') + call setqflist(['F1:10:L10'], 'r') + call assert_equal(':setqflist()', getqflist({'title' : 1}).title) + + close + call delete('Xerr') + + call setqflist([], ' ', {'title' : 'Errors'}) + copen + call assert_equal('Errors', w:quickfix_title) + call setqflist([], 'r', {'items' : [{'filename' : 'a.c', 'lnum' : 10}]}) + call assert_equal('Errors', w:quickfix_title) + cclose +endfunc + func Test_lbuffer_with_bwipe() new new @@ -3383,23 +3522,6 @@ func Test_lbuffer_with_bwipe() augroup END endfunc -" Tests for the ':filter /pat/ clist' command -func Test_filter_clist() - cexpr ['Xfile1:10:10:Line 10', 'Xfile2:15:15:Line 15'] - call assert_equal([' 2 Xfile2:15 col 15: Line 15'], - \ split(execute('filter /Line 15/ clist'), "\n")) - call assert_equal([' 1 Xfile1:10 col 10: Line 10'], - \ split(execute('filter /Xfile1/ clist'), "\n")) - call assert_equal([], split(execute('filter /abc/ clist'), "\n")) - - call setqflist([{'module' : 'abc', 'pattern' : 'pat1'}, - \ {'module' : 'pqr', 'pattern' : 'pat2'}], ' ') - call assert_equal([' 2 pqr:pat2: '], - \ split(execute('filter /pqr/ clist'), "\n")) - call assert_equal([' 1 abc:pat1: '], - \ split(execute('filter /pat1/ clist'), "\n")) -endfunc - " Test for an autocmd freeing the quickfix/location list when cexpr/lexpr is " running func Xexpr_acmd_freelist(cchar) @@ -3549,6 +3671,23 @@ func Test_autocmd_changelist() call Xautocmd_changelist('l') endfunc +" Tests for the ':filter /pat/ clist' command +func Test_filter_clist() + cexpr ['Xfile1:10:10:Line 10', 'Xfile2:15:15:Line 15'] + call assert_equal([' 2 Xfile2:15 col 15: Line 15'], + \ split(execute('filter /Line 15/ clist'), "\n")) + call assert_equal([' 1 Xfile1:10 col 10: Line 10'], + \ split(execute('filter /Xfile1/ clist'), "\n")) + call assert_equal([], split(execute('filter /abc/ clist'), "\n")) + + call setqflist([{'module' : 'abc', 'pattern' : 'pat1'}, + \ {'module' : 'pqr', 'pattern' : 'pat2'}], ' ') + call assert_equal([' 2 pqr:pat2: '], + \ split(execute('filter /pqr/ clist'), "\n")) + call assert_equal([' 1 abc:pat1: '], + \ split(execute('filter /pat1/ clist'), "\n")) +endfunc + " Tests for the "CTRL-W <CR>" command. func Xview_result_split_tests(cchar) call s:setup_commands(a:cchar) @@ -3575,3 +3714,269 @@ func Test_curswant() call assert_equal(getcurpos()[4], virtcol('.')) cclose | helpclose endfunc + +" Test for parsing entries using visual screen column +func Test_viscol() + enew + call writefile(["Col1\tCol2\tCol3"], 'Xfile1') + edit Xfile1 + + " Use byte offset for column number + set efm& + cexpr "Xfile1:1:5:XX\nXfile1:1:9:YY\nXfile1:1:20:ZZ" + call assert_equal([5, 8], [col('.'), virtcol('.')]) + cnext + call assert_equal([9, 12], [col('.'), virtcol('.')]) + cnext + call assert_equal([14, 20], [col('.'), virtcol('.')]) + + " Use screen column offset for column number + set efm=%f:%l:%v:%m + cexpr "Xfile1:1:8:XX\nXfile1:1:12:YY\nXfile1:1:20:ZZ" + call assert_equal([5, 8], [col('.'), virtcol('.')]) + cnext + call assert_equal([9, 12], [col('.'), virtcol('.')]) + cnext + call assert_equal([14, 20], [col('.'), virtcol('.')]) + cexpr "Xfile1:1:6:XX\nXfile1:1:15:YY\nXfile1:1:24:ZZ" + call assert_equal([5, 8], [col('.'), virtcol('.')]) + cnext + call assert_equal([10, 16], [col('.'), virtcol('.')]) + cnext + call assert_equal([14, 20], [col('.'), virtcol('.')]) + + enew + call writefile(["Col1\täü\töß\tCol4"], 'Xfile1') + + " Use byte offset for column number + set efm& + cexpr "Xfile1:1:8:XX\nXfile1:1:11:YY\nXfile1:1:16:ZZ" + call assert_equal([8, 10], [col('.'), virtcol('.')]) + cnext + call assert_equal([11, 17], [col('.'), virtcol('.')]) + cnext + call assert_equal([16, 25], [col('.'), virtcol('.')]) + + " Use screen column offset for column number + set efm=%f:%l:%v:%m + cexpr "Xfile1:1:10:XX\nXfile1:1:17:YY\nXfile1:1:25:ZZ" + call assert_equal([8, 10], [col('.'), virtcol('.')]) + cnext + call assert_equal([11, 17], [col('.'), virtcol('.')]) + cnext + call assert_equal([16, 25], [col('.'), virtcol('.')]) + + enew | only + set efm& + call delete('Xfile1') +endfunc + +" Test to make sure that an empty quickfix buffer is not reused for loading +" a normal buffer. +func Test_empty_qfbuf() + enew | only + call writefile(["Test"], 'Xfile1') + call setqflist([], 'f') + copen | only + let qfbuf = bufnr('') + edit Xfile1 + call assert_notequal(qfbuf, bufnr('')) + enew + call delete('Xfile1') +endfunc + +" Test for the :cbelow, :cabove, :lbelow and :labove commands. +func Xtest_below(cchar) + call s:setup_commands(a:cchar) + + " No quickfix/location list + call assert_fails('Xbelow', 'E42:') + call assert_fails('Xabove', 'E42:') + + " Empty quickfix/location list + call g:Xsetlist([]) + call assert_fails('Xbelow', 'E42:') + call assert_fails('Xabove', 'E42:') + + call s:create_test_file('X1') + call s:create_test_file('X2') + call s:create_test_file('X3') + call s:create_test_file('X4') + + " Invalid entries + edit X1 + call g:Xsetlist(["E1", "E2"]) + call assert_fails('Xbelow', 'E42:') + call assert_fails('Xabove', 'E42:') + call assert_fails('3Xbelow', 'E42:') + call assert_fails('4Xabove', 'E42:') + + " Test the commands with various arguments + Xexpr ["X1:5:L5", "X2:5:L5", "X2:10:L10", "X2:15:L15", "X3:3:L3"] + edit +7 X2 + Xabove + call assert_equal(['X2', 5], [bufname(''), line('.')]) + call assert_fails('Xabove', 'E553:') + normal 2j + Xbelow + call assert_equal(['X2', 10], [bufname(''), line('.')]) + " Last error in this file + Xbelow 99 + call assert_equal(['X2', 15], [bufname(''), line('.')]) + call assert_fails('Xbelow', 'E553:') + " First error in this file + Xabove 99 + call assert_equal(['X2', 5], [bufname(''), line('.')]) + call assert_fails('Xabove', 'E553:') + normal gg + Xbelow 2 + call assert_equal(['X2', 10], [bufname(''), line('.')]) + normal G + Xabove 2 + call assert_equal(['X2', 10], [bufname(''), line('.')]) + edit X4 + call assert_fails('Xabove', 'E42:') + call assert_fails('Xbelow', 'E42:') + if a:cchar == 'l' + " If a buffer has location list entries from some other window but not + " from the current window, then the commands should fail. + edit X1 | split | call setloclist(0, [], 'f') + call assert_fails('Xabove', 'E776:') + call assert_fails('Xbelow', 'E776:') + close + endif + + " Test for lines with multiple quickfix entries + Xexpr ["X1:5:L5", "X2:5:1:L5_1", "X2:5:2:L5_2", "X2:5:3:L5_3", + \ "X2:10:1:L10_1", "X2:10:2:L10_2", "X2:10:3:L10_3", + \ "X2:15:1:L15_1", "X2:15:2:L15_2", "X2:15:3:L15_3", "X3:3:L3"] + edit +1 X2 + Xbelow 2 + call assert_equal(['X2', 10, 1], [bufname(''), line('.'), col('.')]) + normal gg + Xbelow 99 + call assert_equal(['X2', 15, 1], [bufname(''), line('.'), col('.')]) + normal G + Xabove 2 + call assert_equal(['X2', 10, 1], [bufname(''), line('.'), col('.')]) + normal G + Xabove 99 + call assert_equal(['X2', 5, 1], [bufname(''), line('.'), col('.')]) + normal 10G + Xabove + call assert_equal(['X2', 5, 1], [bufname(''), line('.'), col('.')]) + normal 10G + Xbelow + call assert_equal(['X2', 15, 1], [bufname(''), line('.'), col('.')]) + + " Invalid range + if a:cchar == 'c' + call assert_fails('-2cbelow', 'E553:') + " TODO: should go to first error in the current line? + 0cabove + else + call assert_fails('-2lbelow', 'E553:') + " TODO: should go to first error in the current line? + 0labove + endif + + call delete('X1') + call delete('X2') + call delete('X3') + call delete('X4') +endfunc + +func Test_cbelow() + call Xtest_below('c') + call Xtest_below('l') +endfunc + +" Test for aborting quickfix commands using QuickFixCmdPre +func Xtest_qfcmd_abort(cchar) + call s:setup_commands(a:cchar) + + call g:Xsetlist([], 'f') + + " cexpr/lexpr + let e = '' + try + Xexpr ["F1:10:Line10", "F2:20:Line20"] + catch /.*/ + let e = v:exception + endtry + call assert_equal('AbortCmd', e) + call assert_equal(0, g:Xgetlist({'nr' : '$'}).nr) + + " cfile/lfile + call writefile(["F1:10:Line10", "F2:20:Line20"], 'Xfile1') + let e = '' + try + Xfile Xfile1 + catch /.*/ + let e = v:exception + endtry + call assert_equal('AbortCmd', e) + call assert_equal(0, g:Xgetlist({'nr' : '$'}).nr) + call delete('Xfile1') + + " cgetbuffer/lgetbuffer + enew! + call append(0, ["F1:10:Line10", "F2:20:Line20"]) + let e = '' + try + Xgetbuffer + catch /.*/ + let e = v:exception + endtry + call assert_equal('AbortCmd', e) + call assert_equal(0, g:Xgetlist({'nr' : '$'}).nr) + enew! + + " vimgrep/lvimgrep + let e = '' + try + Xvimgrep /func/ test_quickfix.vim + catch /.*/ + let e = v:exception + endtry + call assert_equal('AbortCmd', e) + call assert_equal(0, g:Xgetlist({'nr' : '$'}).nr) + + " helpgrep/lhelpgrep + let e = '' + try + Xhelpgrep quickfix + catch /.*/ + let e = v:exception + endtry + call assert_equal('AbortCmd', e) + call assert_equal(0, g:Xgetlist({'nr' : '$'}).nr) + + " grep/lgrep + if has('unix') + let e = '' + try + silent Xgrep func test_quickfix.vim + catch /.*/ + let e = v:exception + endtry + call assert_equal('AbortCmd', e) + call assert_equal(0, g:Xgetlist({'nr' : '$'}).nr) + endif +endfunc + +func Test_qfcmd_abort() + augroup QF_Test + au! + autocmd QuickFixCmdPre * throw "AbortCmd" + augroup END + + call Xtest_qfcmd_abort('c') + call Xtest_qfcmd_abort('l') + + augroup QF_Test + au! + augroup END +endfunc + +" vim: shiftwidth=2 sts=2 expandtab diff --git a/src/nvim/testdir/test_quotestar.vim b/src/nvim/testdir/test_quotestar.vim index b83fbe40e8..ce5a9ee827 100644 --- a/src/nvim/testdir/test_quotestar.vim +++ b/src/nvim/testdir/test_quotestar.vim @@ -54,34 +54,33 @@ func Do_test_quotestar_for_x11() " Make sure a previous server has exited try call remote_send(name, ":qa!\<CR>") - call WaitFor('serverlist() !~ "' . name . '"') catch /E241:/ endtry - call assert_notmatch(name, serverlist()) + call WaitForAssert({-> assert_notmatch(name, serverlist())}) let cmd .= ' --servername ' . name let job = job_start(cmd, {'stoponexit': 'kill', 'out_io': 'null'}) - call WaitFor({-> job_status(job) == "run"}) + call WaitForAssert({-> assert_equal("run", job_status(job))}) " Takes a short while for the server to be active. - call WaitFor('serverlist() =~ "' . name . '"') + call WaitForAssert({-> assert_match(name, serverlist())}) " Wait for the server to be up and answering requests. One second is not " always sufficient. - call WaitFor('remote_expr("' . name . '", "v:version", "", 2) != ""') + call WaitForAssert({-> assert_notequal('', remote_expr(name, "v:version", "", 2))}) " Clear the *-register of this vim instance and wait for it to be picked up " by the server. let @* = 'no' call remote_foreground(name) - call WaitFor('remote_expr("' . name . '", "@*", "", 1) == "no"') + call WaitForAssert({-> assert_equal("no", remote_expr(name, "@*", "", 1))}) " Set the * register on the server. call remote_send(name, ":let @* = 'yes'\<CR>") - call WaitFor('remote_expr("' . name . '", "@*", "", 1) == "yes"') + call WaitForAssert({-> assert_equal("yes", remote_expr(name, "@*", "", 1))}) " Check that the *-register of this vim instance is changed as expected. - call WaitFor('@* == "yes"') + call WaitForAssert({-> assert_equal("yes", @*)}) " Handle the large selection over 262040 byte. let length = 262044 @@ -109,18 +108,17 @@ func Do_test_quotestar_for_x11() call remote_send(name, ":gui -f\<CR>") endif " Wait for the server in the GUI to be up and answering requests. - call WaitFor('remote_expr("' . name . '", "has(\"gui_running\")", "", 1) =~ "1"') + call WaitForAssert({-> assert_match("1", remote_expr(name, "has('gui_running')", "", 1))}) call remote_send(name, ":let @* = 'maybe'\<CR>") - call WaitFor('remote_expr("' . name . '", "@*", "", 1) == "maybe"') - call assert_equal('maybe', remote_expr(name, "@*", "", 2)) + call WaitForAssert({-> assert_equal("maybe", remote_expr(name, "@*", "", 2))}) call assert_equal('maybe', @*) endif call remote_send(name, ":qa!\<CR>") try - call WaitFor({-> job_status(job) == "dead"}) + call WaitForAssert({-> assert_equal("dead", job_status(job))}) finally if job_status(job) != 'dead' call assert_report('Server did not exit') diff --git a/src/nvim/testdir/test_recover.vim b/src/nvim/testdir/test_recover.vim index 09c8d1cda6..fc073cacd2 100644 --- a/src/nvim/testdir/test_recover.vim +++ b/src/nvim/testdir/test_recover.vim @@ -14,6 +14,12 @@ func Test_recover_root_dir() set dir=/notexist/ endif call assert_fails('split Xtest', 'E303:') + + " No error with empty 'directory' setting. + set directory= + split XtestOK + close! + set dir& endfunc diff --git a/src/nvim/testdir/test_registers.vim b/src/nvim/testdir/test_registers.vim index 298268a994..d4f58af10a 100644 --- a/src/nvim/testdir/test_registers.vim +++ b/src/nvim/testdir/test_registers.vim @@ -1,3 +1,16 @@ +" +" Tests for register operations +" + +" This test must be executed first to check for empty and unset registers. +func Test_aaa_empty_reg_test() + call assert_fails('normal @@', 'E748:') + call assert_fails('normal @%', 'E354:') + call assert_fails('normal @#', 'E354:') + call assert_fails('normal @!', 'E354:') + call assert_fails('normal @:', 'E30:') + call assert_fails('normal @.', 'E29:') +endfunc func Test_yank_shows_register() enew @@ -82,3 +95,76 @@ func Test_recording_esc_sequence() let &t_F2 = save_F2 endif endfunc + +" Test for executing the last used register (@) +func Test_last_used_exec_reg() + " Test for the @: command + let a = '' + call feedkeys(":let a ..= 'Vim'\<CR>", 'xt') + normal @: + call assert_equal('VimVim', a) + + " Test for the @= command + let x = '' + let a = ":let x ..= 'Vim'\<CR>" + exe "normal @=a\<CR>" + normal @@ + call assert_equal('VimVim', x) + + " Test for the @. command + let a = '' + call feedkeys("i:let a ..= 'Edit'\<CR>", 'xt') + normal @. + normal @@ + call assert_equal('EditEdit', a) + + enew! +endfunc + +func Test_get_register() + enew + edit Xfile1 + edit Xfile2 + call assert_equal('Xfile2', getreg('%')) + call assert_equal('Xfile1', getreg('#')) + + call feedkeys("iTwo\<Esc>", 'xt') + call assert_equal('Two', getreg('.')) + call assert_equal('', getreg('_')) + call assert_beeps('normal ":yy') + call assert_beeps('normal "%yy') + call assert_beeps('normal ".yy') + + call assert_equal('', getreg("\<C-F>")) + call assert_equal('', getreg("\<C-W>")) + call assert_equal('', getreg("\<C-L>")) + + call assert_equal('', getregtype('!')) + + enew! +endfunc + +func Test_set_register() + call assert_fails("call setreg('#', 200)", 'E86:') + + edit Xfile_alt_1 + let b1 = bufnr('') + edit Xfile_alt_2 + let b2 = bufnr('') + edit Xfile_alt_3 + let b3 = bufnr('') + call setreg('#', 'alt_1') + call assert_equal('Xfile_alt_1', getreg('#')) + call setreg('#', b2) + call assert_equal('Xfile_alt_2', getreg('#')) + + let ab = 'regwrite' + call setreg('=', '') + call setreg('=', 'a', 'a') + call setreg('=', 'b', 'a') + call assert_equal('regwrite', getreg('=')) + + enew! +endfunc + +" vim: shiftwidth=2 sts=2 expandtab diff --git a/src/nvim/testdir/test_search.vim b/src/nvim/testdir/test_search.vim index 5d4c2a015f..68eb311e3c 100644 --- a/src/nvim/testdir/test_search.vim +++ b/src/nvim/testdir/test_search.vim @@ -57,7 +57,7 @@ func Test_search_cmdline() call feedkeys("/the".repeat("\<C-G>", 6)."\<cr>", 'tx') call assert_equal(' 8 them', getline('.')) :1 - " eigth match + " eighth match call feedkeys("/the".repeat("\<C-G>", 7)."\<cr>", 'tx') call assert_equal(' 9 these', getline('.')) :1 @@ -99,7 +99,7 @@ func Test_search_cmdline() call feedkeys("/the".repeat("\<C-G>", 6)."\<cr>", 'tx') call assert_equal(' 8 them', getline('.')) :1 - " eigth match + " eighth match call feedkeys("/the".repeat("\<C-G>", 7)."\<cr>", 'tx') call assert_equal(' 9 these', getline('.')) :1 diff --git a/src/nvim/testdir/test_spell.vim b/src/nvim/testdir/test_spell.vim index e49b5542fa..e2016d7927 100644 --- a/src/nvim/testdir/test_spell.vim +++ b/src/nvim/testdir/test_spell.vim @@ -283,9 +283,9 @@ func Test_zz_affix() \ ]) call LoadAffAndDic(g:test_data_aff7, g:test_data_dic7) - call RunGoodBad("meea1 meea\xE9 bar prebar barmeat prebarmeat leadprebar lead tail leadtail leadmiddletail", + call RunGoodBad("meea1 meezero meea\xE9 bar prebar barmeat prebarmeat leadprebar lead tail leadtail leadmiddletail", \ "bad: mee meea2 prabar probarmaat middle leadmiddle middletail taillead leadprobar", - \ ["bar", "barmeat", "lead", "meea1", "meea\xE9", "prebar", "prebarmeat", "tail"], + \ ["bar", "barmeat", "lead", "meea1", "meea\xE9", "meezero", "prebar", "prebarmeat", "tail"], \ [ \ ["bad", ["bar", "lead", "tail"]], \ ["mee", ["meea1", "meea\xE9", "bar"]], @@ -320,6 +320,19 @@ func Test_zz_Numbers() \ ]) endfunc +" Affix flags +func Test_zz_affix_flags() + call LoadAffAndDic(g:test_data_aff10, g:test_data_dic10) + call RunGoodBad("drink drinkable drinkables drinktable drinkabletable", + \ "bad: drinks drinkstable drinkablestable", + \ ["drink", "drinkable", "drinkables", "table"], + \ [['bad', []], + \ ['drinks', ['drink']], + \ ['drinkstable', ['drinktable', 'drinkable', 'drink table']], + \ ['drinkablestable', ['drinkabletable', 'drinkables table', 'drinkable table']], + \ ]) +endfunc + function FirstSpellWord() call feedkeys("/^start:\n", 'tx') normal ]smm @@ -713,6 +726,9 @@ let g:test_data_aff7 = [ \"SFX 61003 Y 1", \"SFX 61003 0 meat .", \"", + \"SFX 0 Y 1", + \"SFX 0 0 zero .", + \"", \"SFX 391 Y 1", \"SFX 391 0 a1 .", \"", @@ -724,7 +740,7 @@ let g:test_data_aff7 = [ \ ] let g:test_data_dic7 = [ \"1234", - \"mee/391,111,9999", + \"mee/0,391,111,9999", \"bar/17,61003,123", \"lead/2", \"tail/123", @@ -748,6 +764,21 @@ let g:test_data_dic9 = [ \"foo", \"bar", \ ] +let g:test_data_aff10 = [ + \"COMPOUNDRULE se", + \"COMPOUNDPERMITFLAG p", + \"", + \"SFX A Y 1", + \"SFX A 0 able/Mp .", + \"", + \"SFX M Y 1", + \"SFX M 0 s .", + \ ] +let g:test_data_dic10 = [ + \"1234", + \"drink/As", + \"table/e", + \ ] let g:test_data_aff_sal = [ \"SET ISO8859-1", \"TRY esianrtolcdugmphbyfvkwjkqxz-\xEB\xE9\xE8\xEA\xEF\xEE\xE4\xE0\xE2\xF6\xFC\xFB'ESIANRTOLCDUGMPHBYFVKWJKQXZ", diff --git a/src/nvim/testdir/test_startup.vim b/src/nvim/testdir/test_startup.vim index 1e70f28a00..a38625cca8 100644 --- a/src/nvim/testdir/test_startup.vim +++ b/src/nvim/testdir/test_startup.vim @@ -20,25 +20,27 @@ func Test_after_comes_later() if !has('packages') return endif - let before = [ - \ 'set nocp viminfo+=nviminfo', - \ 'set guioptions+=M', - \ 'let $HOME = "/does/not/exist"', - \ 'set loadplugins', - \ 'set rtp=Xhere,Xafter,Xanother', - \ 'set packpath=Xhere,Xafter', - \ 'set nomore', - \ 'let g:sequence = ""', - \ ] - let after = [ - \ 'redir! > Xtestout', - \ 'scriptnames', - \ 'redir END', - \ 'redir! > Xsequence', - \ 'echo g:sequence', - \ 'redir END', - \ 'quit', - \ ] + let before =<< trim [CODE] + set nocp viminfo+=nviminfo + set guioptions+=M + let $HOME = "/does/not/exist" + set loadplugins + set rtp=Xhere,Xafter,Xanother + set packpath=Xhere,Xafter + set nomore + let g:sequence = "" + [CODE] + + let after =<< trim [CODE] + redir! > Xtestout + scriptnames + redir END + redir! > Xsequence + echo g:sequence + redir END + quit + [CODE] + call mkdir('Xhere/plugin', 'p') call writefile(['let g:sequence .= "here "'], 'Xhere/plugin/here.vim') call mkdir('Xanother/plugin', 'p') @@ -77,15 +79,16 @@ func Test_pack_in_rtp_when_plugins_run() if !has('packages') return endif - let before = [ - \ 'set nocp viminfo+=nviminfo', - \ 'set guioptions+=M', - \ 'let $HOME = "/does/not/exist"', - \ 'set loadplugins', - \ 'set rtp=Xhere', - \ 'set packpath=Xhere', - \ 'set nomore', - \ ] + let before =<< trim [CODE] + set nocp viminfo+=nviminfo + set guioptions+=M + let $HOME = "/does/not/exist" + set loadplugins + set rtp=Xhere + set packpath=Xhere + set nomore + [CODE] + let after = [ \ 'quit', \ ] @@ -133,11 +136,12 @@ endfunc func Test_compatible_args() throw "skipped: Nvim is always 'nocompatible'" - let after = [ - \ 'call writefile([string(&compatible)], "Xtestout")', - \ 'set viminfo+=nviminfo', - \ 'quit', - \ ] + let after =<< trim [CODE] + call writefile([string(&compatible)], "Xtestout") + set viminfo+=nviminfo + quit + [CODE] + if RunVim([], after, '-C') let lines = readfile('Xtestout') call assert_equal('1', lines[0]) @@ -154,14 +158,15 @@ endfunc " Test the -o[N] and -O[N] arguments to open N windows split " horizontally or vertically. func Test_o_arg() - let after = [ - \ 'call writefile([winnr("$"), - \ winheight(1), winheight(2), &lines, - \ winwidth(1), winwidth(2), &columns, - \ bufname(winbufnr(1)), bufname(winbufnr(2))], - \ "Xtestout")', - \ 'qall', - \ ] + let after =<< trim [CODE] + call writefile([winnr("$"), + \ winheight(1), winheight(2), &lines, + \ winwidth(1), winwidth(2), &columns, + \ bufname(winbufnr(1)), bufname(winbufnr(2))], + \ "Xtestout") + qall + [CODE] + if RunVim([], after, '-o2') " Open 2 windows split horizontally. Expect: " - 2 windows @@ -230,10 +235,11 @@ endfunc " Test the -p[N] argument to open N tabpages. func Test_p_arg() - let after = [ - \ 'call writefile(split(execute("tabs"), "\n"), "Xtestout")', - \ 'qall', - \ ] + let after =<< trim [CODE] + call writefile(split(execute("tabs"), "\n"), "Xtestout") + qall + [CODE] + if RunVim([], after, '-p2') let lines = readfile('Xtestout') call assert_equal(4, len(lines)) @@ -290,10 +296,11 @@ endfunc " -M resets 'modifiable' and 'write' " -R sets 'readonly' func Test_m_M_R() - let after = [ - \ 'call writefile([&write, &modifiable, &readonly, &updatecount], "Xtestout")', - \ 'qall', - \ ] + let after =<< trim [CODE] + call writefile([&write, &modifiable, &readonly, &updatecount], "Xtestout") + qall + [CODE] + if RunVim([], after, '') let lines = readfile('Xtestout') call assert_equal(['1', '1', '0', '200'], lines) @@ -316,10 +323,11 @@ endfunc " Test the -A, -F and -H arguments (Arabic, Farsi and Hebrew modes). func Test_A_F_H_arg() - let after = [ - \ 'call writefile([&rightleft, &arabic, 0, &hkmap], "Xtestout")', - \ 'qall', - \ ] + let after =<< trim [CODE] + call writefile([&rightleft, &arabic, 0, &hkmap], "Xtestout") + qall + [CODE] + " Use silent Ex mode to avoid the hit-Enter prompt for the warning that " 'encoding' is not utf-8. if has('arabic') && &encoding == 'utf-8' && RunVim([], after, '-e -s -A') @@ -423,10 +431,11 @@ func Test_invalid_args() endfunc func Test_file_args() - let after = [ - \ 'call writefile(argv(), "Xtestout")', - \ 'qall', - \ ] + let after =<< trim [CODE] + call writefile(argv(), "Xtestout") + qall + [CODE] + if RunVim([], after, '') let lines = readfile('Xtestout') call assert_equal(0, len(lines)) @@ -487,10 +496,11 @@ func Test_startuptime() endfunc func Test_read_stdin() - let after = [ - \ 'write Xtestout', - \ 'quit!', - \ ] + let after =<< trim [CODE] + write Xtestout + quit! + [CODE] + if RunVimPiped([], after, '-', 'echo something | ') let lines = readfile('Xtestout') " MS-Windows adds a space after the word @@ -540,20 +550,22 @@ endfunc func Test_zzz_startinsert() " Test :startinsert call writefile(['123456'], 'Xtestout') - let after = [ - \ ':startinsert', - \ 'call feedkeys("foobar\<c-o>:wq\<cr>","t")' - \ ] + let after =<< trim [CODE] + :startinsert + call feedkeys("foobar\<c-o>:wq\<cr>","t") + [CODE] + if RunVim([], after, 'Xtestout') let lines = readfile('Xtestout') call assert_equal(['foobar123456'], lines) endif " Test :startinsert! call writefile(['123456'], 'Xtestout') - let after = [ - \ ':startinsert!', - \ 'call feedkeys("foobar\<c-o>:wq\<cr>","t")' - \ ] + let after =<< trim [CODE] + :startinsert! + call feedkeys("foobar\<c-o>:wq\<cr>","t") + [CODE] + if RunVim([], after, 'Xtestout') let lines = readfile('Xtestout') call assert_equal(['123456foobar'], lines) diff --git a/src/nvim/testdir/test_statusline.vim b/src/nvim/testdir/test_statusline.vim index b86340a23a..48ec777ffd 100644 --- a/src/nvim/testdir/test_statusline.vim +++ b/src/nvim/testdir/test_statusline.vim @@ -347,3 +347,25 @@ func Test_statusline() set laststatus& set splitbelow& endfunc + +func Test_statusline_visual() + func CallWordcount() + call wordcount() + endfunc + new x1 + setl statusline=count=%{CallWordcount()} + " buffer must not be empty + call setline(1, 'hello') + + " window with more lines than x1 + new x2 + call setline(1, range(10)) + $ + " Visual mode in line below liast line in x1 should not give ml_get error + call feedkeys("\<C-V>", "xt") + redraw + + delfunc CallWordcount + bwipe! x1 + bwipe! x2 +endfunc diff --git a/src/nvim/testdir/test_substitute.vim b/src/nvim/testdir/test_substitute.vim index b29b678129..e94bd22cea 100644 --- a/src/nvim/testdir/test_substitute.vim +++ b/src/nvim/testdir/test_substitute.vim @@ -149,6 +149,7 @@ func Run_SubCmd_Tests(tests) for t in a:tests let start = line('.') + 1 let end = start + len(t[2]) - 1 + " TODO: why is there a one second delay the first time we get here? exe "normal o" . t[0] call cursor(start, 1) exe t[1] @@ -240,7 +241,7 @@ func Test_sub_cmd_3() call Run_SubCmd_Tests(tests) endfunc -" Test for submatch() on :substitue. +" Test for submatch() on :substitute. func Test_sub_cmd_4() set magic& set cpo& @@ -717,3 +718,12 @@ one two close! endfunc + +func Test_sub_beyond_end() + new + call setline(1, '#') + let @/ = '^#\n\zs' + s///e + call assert_equal('#', getline(1)) + bwipe! +endfunc diff --git a/src/nvim/testdir/test_swap.vim b/src/nvim/testdir/test_swap.vim index 11eb324488..e072e9ed7f 100644 --- a/src/nvim/testdir/test_swap.vim +++ b/src/nvim/testdir/test_swap.vim @@ -221,3 +221,87 @@ func Test_swapfile_delete() augroup END augroup! test_swapfile_delete endfunc + +func Test_swap_recover() + autocmd! SwapExists + augroup test_swap_recover + autocmd! + autocmd SwapExists * let v:swapchoice = 'r' + augroup END + + + call mkdir('Xswap') + let $Xswap = 'foo' " Check for issue #4369. + set dir=Xswap// + " Create a valid swapfile by editing a file. + split Xswap/text + call setline(1, ['one', 'two', 'three']) + write " file is written, not modified + " read the swapfile as a Blob + let swapfile_name = swapname('%') + let swapfile_bytes = readfile(swapfile_name, 'B') + + " Close the file and recreate the swap file. + quit + call writefile(swapfile_bytes, swapfile_name) + " Edit the file again. This triggers recovery. + try + split Xswap/text + catch + " E308 should be caught, not E305. + call assert_exception('E308:') " Original file may have been changed + endtry + " The file should be recovered. + call assert_equal(['one', 'two', 'three'], getline(1, 3)) + quit! + + call delete('Xswap/text') + call delete(swapfile_name) + call delete('Xswap', 'd') + unlet $Xswap + set dir& + augroup test_swap_recover + autocmd! + augroup END + augroup! test_swap_recover +endfunc + +func Test_swap_recover_ext() + autocmd! SwapExists + augroup test_swap_recover_ext + autocmd! + autocmd SwapExists * let v:swapchoice = 'r' + augroup END + + + " Create a valid swapfile by editing a file with a special extension. + split Xtest.scr + call setline(1, ['one', 'two', 'three']) + write " file is written, not modified + write " write again to make sure the swapfile is created + " read the swapfile as a Blob + let swapfile_name = swapname('%') + let swapfile_bytes = readfile(swapfile_name, 'B') + + " Close and delete the file and recreate the swap file. + quit + call delete('Xtest.scr') + call writefile(swapfile_bytes, swapfile_name) + " Edit the file again. This triggers recovery. + try + split Xtest.scr + catch + " E308 should be caught, not E306. + call assert_exception('E308:') " Original file may have been changed + endtry + " The file should be recovered. + call assert_equal(['one', 'two', 'three'], getline(1, 3)) + quit! + + call delete('Xtest.scr') + call delete(swapfile_name) + augroup test_swap_recover_ext + autocmd! + augroup END + augroup! test_swap_recover_ext +endfunc diff --git a/src/nvim/testdir/test_syntax.vim b/src/nvim/testdir/test_syntax.vim index 598a00476c..6cada1503f 100644 --- a/src/nvim/testdir/test_syntax.vim +++ b/src/nvim/testdir/test_syntax.vim @@ -1,6 +1,7 @@ " Test for syntax and syntax iskeyword option source view_util.vim +source screendump.vim func GetSyntaxItem(pat) let c = '' @@ -501,9 +502,7 @@ func Test_syntax_c() endif call writefile([ \ '/* comment line at the top */', - \ ' int', - \ 'main(int argc, char **argv)// another comment', - \ '{', + \ 'int main(int argc, char **argv) { // another comment', \ '#if 0', \ ' int not_used;', \ '#else', @@ -518,6 +517,7 @@ func Test_syntax_c() \ ' for (int i = 0; i < count; ++i) {', \ ' break;', \ ' }', + \ " Note: asdf", \ '}', \ ], 'Xtest.c') @@ -526,7 +526,8 @@ func Test_syntax_c() let $COLORFGBG = '15;0' let buf = RunVimInTerminal('Xtest.c', {}) - call VerifyScreenDump(buf, 'Test_syntax_c_01') + call term_sendkeys(buf, ":syn keyword Search Note\r") + call VerifyScreenDump(buf, 'Test_syntax_c_01', {}) call StopVimInTerminal(buf) let $COLORFGBG = '' diff --git a/src/nvim/testdir/test_tagfunc.vim b/src/nvim/testdir/test_tagfunc.vim new file mode 100644 index 0000000000..242aa3a235 --- /dev/null +++ b/src/nvim/testdir/test_tagfunc.vim @@ -0,0 +1,84 @@ +" Test 'tagfunc' + +func TagFunc(pat, flag, info) + let g:tagfunc_args = [a:pat, a:flag, a:info] + let tags = [] + for num in range(1,10) + let tags += [{ + \ 'cmd': '2', 'name': 'nothing'.num, 'kind': 'm', + \ 'filename': 'Xfile1', 'user_data': 'somedata'.num, + \}] + endfor + return tags +endfunc + +func Test_tagfunc() + set tagfunc=TagFunc + new Xfile1 + call setline(1, ['empty', 'one()', 'empty']) + write + + call assert_equal({'cmd': '2', 'static': 0, + \ 'name': 'nothing2', 'user_data': 'somedata2', + \ 'kind': 'm', 'filename': 'Xfile1'}, taglist('.')[1]) + + call settagstack(win_getid(), {'items': []}) + + tag arbitrary + call assert_equal('arbitrary', g:tagfunc_args[0]) + call assert_equal('', g:tagfunc_args[1]) + call assert_equal('somedata1', gettagstack().items[0].user_data) + 5tag arbitrary + call assert_equal('arbitrary', g:tagfunc_args[0]) + call assert_equal('', g:tagfunc_args[1]) + call assert_equal('somedata5', gettagstack().items[1].user_data) + pop + tag + call assert_equal('arbitrary', g:tagfunc_args[0]) + call assert_equal('', g:tagfunc_args[1]) + call assert_equal('somedata5', gettagstack().items[1].user_data) + + let g:tagfunc_args=[] + execute "normal! \<c-]>" + call assert_equal('one', g:tagfunc_args[0]) + call assert_equal('c', g:tagfunc_args[1]) + + set cpt=t + let g:tagfunc_args=[] + execute "normal! i\<c-n>\<c-y>" + call assert_equal('ci', g:tagfunc_args[1]) + call assert_equal('nothing1', getline('.')[0:7]) + + func BadTagFunc1(...) + return 0 + endfunc + func BadTagFunc2(...) + return [1] + endfunc + func BadTagFunc3(...) + return [{'name': 'foo'}] + endfunc + + for &tagfunc in ['BadTagFunc1', 'BadTagFunc2', 'BadTagFunc3'] + try + tag nothing + call assert_false(1, 'tag command should have failed') + catch + call assert_exception('E987:') + endtry + exe 'delf' &tagfunc + endfor + + func NullTagFunc(...) + return v:null + endfunc + set tags= tfu=NullTagFunc + call assert_fails('tag nothing', 'E426') + delf NullTagFunc + + bwipe! + set tags& tfu& cpt& + call delete('Xfile1') +endfunc + +" vim: shiftwidth=2 sts=2 expandtab diff --git a/src/nvim/testdir/test_tagjump.vim b/src/nvim/testdir/test_tagjump.vim index ce527a5e1d..fe98ef1ae2 100644 --- a/src/nvim/testdir/test_tagjump.vim +++ b/src/nvim/testdir/test_tagjump.vim @@ -449,7 +449,8 @@ func Test_tag_line_toolong() call assert_report(v:exception) catch /.*/ endtry - call assert_equal('Ignoring long line in tags file', split(execute('messages'), '\n')[-1]) + call assert_equal('Searching tags file Xtags', split(execute('messages'), '\n')[-1]) + call writefile([ \ '123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567 django/contrib/admin/templates/admin/edit_inline/stacked.html 16;" j line:16 language:HTML' \ ], 'Xtags') @@ -460,10 +461,52 @@ func Test_tag_line_toolong() call assert_report(v:exception) catch /.*/ endtry - call assert_equal('Ignoring long line in tags file', split(execute('messages'), '\n')[-1]) + call assert_equal('Searching tags file Xtags', split(execute('messages'), '\n')[-1]) + + " binary search works in file with long line + call writefile([ + \ 'asdfasfd nowhere 16', + \ 'foobar Xsomewhere 3; " 12345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567', + \ 'zasdfasfd nowhere 16', + \ ], 'Xtags') + call writefile([ + \ 'one', + \ 'two', + \ 'trhee', + \ 'four', + \ ], 'Xsomewhere') + tag foobar + call assert_equal('Xsomewhere', expand('%')) + call assert_equal(3, getcurpos()[1]) + call delete('Xtags') + call delete('Xsomewhere') set tags& let &verbose = old_vbs endfunc +func Test_tagline() + call writefile([ + \ 'provision Xtest.py /^ def provision(self, **kwargs):$/;" m line:1 language:Python class:Foo', + \ 'provision Xtest.py /^ def provision(self, **kwargs):$/;" m line:3 language:Python class:Bar', + \], 'Xtags') + call writefile([ + \ ' def provision(self, **kwargs):', + \ ' pass', + \ ' def provision(self, **kwargs):', + \ ' pass', + \], 'Xtest.py') + + set tags=Xtags + + 1tag provision + call assert_equal(line('.'), 1) + 2tag provision + call assert_equal(line('.'), 3) + + call delete('Xtags') + call delete('Xtest.py') + set tags& +endfunc + " vim: shiftwidth=2 sts=2 expandtab diff --git a/src/nvim/testdir/test_textobjects.vim b/src/nvim/testdir/test_textobjects.vim index 9194e0014d..b20c4df311 100644 --- a/src/nvim/testdir/test_textobjects.vim +++ b/src/nvim/testdir/test_textobjects.vim @@ -46,8 +46,18 @@ func Test_quote_selection_selection_exclusive() new call setline(1, "a 'bcde' f") set selection=exclusive + exe "norm! fdvhi'y" call assert_equal('bcde', @") + + let @"='dummy' + exe "norm! $gevi'y" + call assert_equal('bcde', @") + + let @"='dummy' + exe "norm! 0fbhvi'y" + call assert_equal('bcde', @") + set selection&vim bw! endfunc diff --git a/src/nvim/testdir/test_timers.vim b/src/nvim/testdir/test_timers.vim index 24c735865c..bd63d94729 100644 --- a/src/nvim/testdir/test_timers.vim +++ b/src/nvim/testdir/test_timers.vim @@ -141,7 +141,7 @@ endfunc func Test_delete_myself() let g:called = 0 let t = timer_start(10, 'StopMyself', {'repeat': -1}) - call WaitFor('g:called == 2') + call WaitForAssert({-> assert_equal(2, g:called)}) call assert_equal(2, g:called) call assert_equal([], timer_info(t)) endfunc @@ -208,7 +208,7 @@ func Test_timer_errors() let g:call_count = 0 let timer = timer_start(10, 'FuncWithError', {'repeat': -1}) " Timer will be stopped after failing 3 out of 3 times. - call WaitFor('g:call_count == 3') + call WaitForAssert({-> assert_equal(3, g:call_count)}) sleep 50m call assert_equal(3, g:call_count) endfunc @@ -226,7 +226,7 @@ func Test_timer_catch_error() let g:call_count = 0 let timer = timer_start(10, 'FuncWithCaughtError', {'repeat': 4}) " Timer will not be stopped. - call WaitFor('g:call_count == 4') + call WaitForAssert({-> assert_equal(4, g:call_count)}) sleep 50m call assert_equal(4, g:call_count) endfunc @@ -252,4 +252,15 @@ func Test_peek_and_get_char() call timer_stop(intr) endfunc +func Test_ex_mode() + " Function with an empty line. + func Foo(...) + + endfunc + let timer = timer_start(40, function('g:Foo'), {'repeat':-1}) + " This used to throw error E749. + exe "normal Qsleep 100m\rvi\r" + call timer_stop(timer) +endfunc + " vim: shiftwidth=2 sts=2 expandtab diff --git a/src/nvim/testdir/test_vimscript.vim b/src/nvim/testdir/test_vimscript.vim index f39e53d6dd..d2f13ff072 100644 --- a/src/nvim/testdir/test_vimscript.vim +++ b/src/nvim/testdir/test_vimscript.vim @@ -1284,7 +1284,7 @@ func s:DoNothing() endfunc func Test_script_local_func() - set nocp viminfo+=nviminfo + set nocp nomore viminfo+=nviminfo new nnoremap <buffer> _x :call <SID>DoNothing()<bar>call <SID>DoLast()<bar>delfunc <SID>DoNothing<bar>delfunc <SID>DoLast<cr> @@ -1409,6 +1409,76 @@ func Test_compound_assignment_operators() let @/ = '' endfunc +func Test_function_defined_line() + if has('gui_running') + " Can't catch the output of gvim. + return + endif + + let lines =<< trim [CODE] + " F1 + func F1() + " F2 + func F2() + " + " + " + return + endfunc + " F3 + execute "func F3()\n\n\n\nreturn\nendfunc" + " F4 + execute "func F4()\n + \\n + \\n + \\n + \return\n + \endfunc" + endfunc + " F5 + execute "func F5()\n\n\n\nreturn\nendfunc" + " F6 + execute "func F6()\n + \\n + \\n + \\n + \return\n + \endfunc" + call F1() + verbose func F1 + verbose func F2 + verbose func F3 + verbose func F4 + verbose func F5 + verbose func F6 + qall! + [CODE] + + call writefile(lines, 'Xtest.vim') + let res = system(v:progpath .. ' --clean -es -X -S Xtest.vim') + call assert_equal(0, v:shell_error) + + let m = matchstr(res, 'function F1()[^[:print:]]*[[:print:]]*') + call assert_match(' line 2$', m) + + let m = matchstr(res, 'function F2()[^[:print:]]*[[:print:]]*') + call assert_match(' line 4$', m) + + let m = matchstr(res, 'function F3()[^[:print:]]*[[:print:]]*') + call assert_match(' line 11$', m) + + let m = matchstr(res, 'function F4()[^[:print:]]*[[:print:]]*') + call assert_match(' line 13$', m) + + let m = matchstr(res, 'function F5()[^[:print:]]*[[:print:]]*') + call assert_match(' line 21$', m) + + let m = matchstr(res, 'function F6()[^[:print:]]*[[:print:]]*') + call assert_match(' line 23$', m) + + call delete('Xtest.vim') +endfunc + "------------------------------------------------------------------------------- " Modelines {{{1 " vim: ts=8 sw=4 tw=80 fdm=marker diff --git a/src/nvim/testdir/test_virtualedit.vim b/src/nvim/testdir/test_virtualedit.vim index 67adede8d7..8f992f7501 100644 --- a/src/nvim/testdir/test_virtualedit.vim +++ b/src/nvim/testdir/test_virtualedit.vim @@ -73,3 +73,147 @@ func Test_edit_CTRL_G() bwipe! set virtualedit= endfunc + +func Test_edit_change() + new + set virtualedit=all + call setline(1, "\t⒌") + normal Cx + call assert_equal('x', getline(1)) + bwipe! +endfunc + +" Insert "keyword keyw", ESC, C CTRL-N, shows "keyword ykeyword". +" Repeating CTRL-N fixes it. (Mary Ellen Foster) +func Test_ve_completion() + new + set completeopt&vim + set virtualedit=all + exe "normal ikeyword keyw\<Esc>C\<C-N>" + call assert_equal('keyword keyword', getline(1)) + bwipe! + set virtualedit= +endfunc + +" Using "C" then then <CR> moves the last remaining character to the next +" line. (Mary Ellen Foster) +func Test_ve_del_to_eol() + new + set virtualedit=all + call append(0, 'all your base are belong to us') + call search('are', 'w') + exe "normal C\<CR>are belong to vim" + call assert_equal(['all your base ', 'are belong to vim'], getline(1, 2)) + bwipe! + set virtualedit= +endfunc + +" When past the end of a line that ends in a single character "b" skips +" that word. +func Test_ve_b_past_eol() + new + set virtualedit=all + call append(0, '1 2 3 4 5 6') + normal gg^$15lbC7 + call assert_equal('1 2 3 4 5 7', getline(1)) + bwipe! + set virtualedit= +endfunc + +" Make sure 'i', 'C', 'a', 'A' and 'D' works +func Test_ve_ins_del() + new + set virtualedit=all + call append(0, ["'i'", "'C'", "'a'", "'A'", "'D'"]) + call cursor(1, 1) + normal $4lix + call assert_equal("'i' x", getline(1)) + call cursor(2, 1) + normal $4lCx + call assert_equal("'C' x", getline(2)) + call cursor(3, 1) + normal $4lax + call assert_equal("'a' x", getline(3)) + call cursor(4, 1) + normal $4lAx + call assert_equal("'A'x", getline(4)) + call cursor(5, 1) + normal $4lDix + call assert_equal("'D' x", getline(5)) + bwipe! + set virtualedit= +endfunc + +" Test for yank bug reported by Mark Waggoner. +func Test_yank_block() + new + set virtualedit=block + call append(0, repeat(['this is a test'], 3)) + exe "normal gg^2w\<C-V>3jy" + call assert_equal("a\na\na\n ", @") + bwipe! + set virtualedit= +endfunc + +" Test "r" beyond the end of the line +func Test_replace_after_eol() + new + set virtualedit=all + call append(0, '"r"') + normal gg$5lrxa + call assert_equal('"r" x', getline(1)) + bwipe! + set virtualedit= +endfunc + +" Test "r" on a tab +" Note that for this test, 'ts' must be 8 (the default). +func Test_replace_on_tab() + new + set virtualedit=all + call append(0, "'r'\t") + normal gg^5lrxAy + call assert_equal("'r' x y", getline(1)) + bwipe! + set virtualedit= +endfunc + +" Test to make sure 'x' can delete control characters +func Test_ve_del_ctrl_chars() + new + set virtualedit=all + call append(0, "a\<C-V>b\<CR>sd") + set display=uhex + normal gg^xxxxxxi[text] + set display= + call assert_equal('[text]', getline(1)) + bwipe! + set virtualedit= +endfunc + +" Test for ^Y/^E due to bad w_virtcol value, reported by +" Roy <royl@netropolis.net>. +func Test_ins_copy_char() + new + set virtualedit=all + call append(0, 'abcv8efi.him2kl') + exe "normal gg^O\<Esc>3li\<C-E>\<Esc>4li\<C-E>\<Esc>4li\<C-E> <--" + exe "normal j^o\<Esc>4li\<C-Y>\<Esc>4li\<C-Y>\<Esc>4li\<C-Y> <--" + call assert_equal(' v i m <--', getline(1)) + call assert_equal(' 8 . 2 <--', getline(3)) + bwipe! + set virtualedit= +endfunc + +" Test for yanking and pasting using the small delete register +func Test_yank_paste_small_del_reg() + new + set virtualedit=all + call append(0, "foo, bar") + normal ggdewve"-p + call assert_equal(', foo', getline(1)) + bwipe! + set virtualedit= +endfunc + +" vim: shiftwidth=2 sts=2 expandtab diff --git a/src/nvim/testdir/test_window_cmd.vim b/src/nvim/testdir/test_window_cmd.vim index c87c0a0af4..aaa291f87d 100644 --- a/src/nvim/testdir/test_window_cmd.vim +++ b/src/nvim/testdir/test_window_cmd.vim @@ -69,18 +69,6 @@ function Test_window_cmd_wincmd_gf() augroup! test_window_cmd_wincmd_gf endfunc -func Test_next_split_all() - " This was causing an illegal memory access. - n x - norm axxx - split - split - s/x - s/x - all - bwipe! -endfunc - func Test_window_quit() e Xa split Xb @@ -117,15 +105,71 @@ func Test_window_vertical_split() bw endfunc +" Test the ":wincmd ^" and "<C-W>^" commands. func Test_window_split_edit_alternate() - e Xa - e Xb + " Test for failure when the alternate buffer/file no longer exists. + edit Xfoo | %bw + call assert_fails(':wincmd ^', 'E23') + + " Test for the expected behavior when we have two named buffers. + edit Xfoo | edit Xbar wincmd ^ - call assert_equal('Xa', bufname(winbufnr(1))) - call assert_equal('Xb', bufname(winbufnr(2))) + call assert_equal('Xfoo', bufname(winbufnr(1))) + call assert_equal('Xbar', bufname(winbufnr(2))) + only - bw Xa Xb + " Test for the expected behavior when the alternate buffer is not named. + enew | let l:nr1 = bufnr('%') + edit Xfoo | let l:nr2 = bufnr('%') + wincmd ^ + call assert_equal(l:nr1, winbufnr(1)) + call assert_equal(l:nr2, winbufnr(2)) + only + + " FIXME: this currently fails on AppVeyor, but passes locally + if !has('win32') + " Test the Normal mode command. + call feedkeys("\<C-W>\<C-^>", 'tx') + call assert_equal(l:nr2, winbufnr(1)) + call assert_equal(l:nr1, winbufnr(2)) + endif + + %bw! +endfunc + +" Test the ":[count]wincmd ^" and "[count]<C-W>^" commands. +func Test_window_split_edit_bufnr() + + %bwipeout + let l:nr = bufnr('%') + 1 + call assert_fails(':execute "normal! ' . l:nr . '\<C-W>\<C-^>"', 'E92') + call assert_fails(':' . l:nr . 'wincmd ^', 'E16') + call assert_fails(':0wincmd ^', 'E16') + + edit Xfoo | edit Xbar | edit Xbaz + let l:foo_nr = bufnr('Xfoo') + let l:bar_nr = bufnr('Xbar') + let l:baz_nr = bufnr('Xbaz') + + " FIXME: this currently fails on AppVeyor, but passes locally + if !has('win32') + call feedkeys(l:foo_nr . "\<C-W>\<C-^>", 'tx') + call assert_equal('Xfoo', bufname(winbufnr(1))) + call assert_equal('Xbaz', bufname(winbufnr(2))) + only + + call feedkeys(l:bar_nr . "\<C-W>\<C-^>", 'tx') + call assert_equal('Xbar', bufname(winbufnr(1))) + call assert_equal('Xfoo', bufname(winbufnr(2))) + only + + execute l:baz_nr . 'wincmd ^' + call assert_equal('Xbaz', bufname(winbufnr(1))) + call assert_equal('Xbar', bufname(winbufnr(2))) + endif + + %bw! endfunc func Test_window_preview() @@ -446,6 +490,17 @@ func Test_window_newtab() %bw! endfunc +func Test_next_split_all() + " This was causing an illegal memory access. + n x + norm axxx + split + split + s/x + s/x + all + bwipe! +endfunc " Tests for adjusting window and contents func GetScreenStr(row) @@ -485,6 +540,11 @@ func Test_window_contents() call test_garbagecollect_now() endfunc +func Test_window_colon_command() + " This was reading invalid memory. + exe "norm! v\<C-W>:\<C-U>echo v:version" +endfunc + func Test_access_freed_mem() " This was accessing freed memory au * 0 vs xxx @@ -700,6 +760,42 @@ func Test_relative_cursor_second_line_after_resize() let &so = so_save endfunc +func Test_split_noscroll() + let so_save = &so + enew + call setline(1, range(1, 8)) + normal 100% + split + + 1wincmd w + let winid1 = win_getid() + let info1 = getwininfo(winid1)[0] + + 2wincmd w + let winid2 = win_getid() + let info2 = getwininfo(winid2)[0] + + call assert_equal(1, info1.topline) + call assert_equal(1, info2.topline) + + " window that fits all lines by itself, but not when split: closing other + " window should restore fraction. + only! + call setline(1, range(1, &lines - 10)) + exe &lines / 4 + let winid1 = win_getid() + let info1 = getwininfo(winid1)[0] + call assert_equal(1, info1.topline) + new + redraw + close + let info1 = getwininfo(winid1)[0] + call assert_equal(1, info1.topline) + + bwipe! + let &so = so_save +endfunc + " Tests for the winnr() function func Test_winnr() only | tabonly @@ -745,9 +841,4 @@ func Test_winnr() only | tabonly endfunc -func Test_window_colon_command() - " This was reading invalid memory. - exe "norm! v\<C-W>:\<C-U>echo v:version" -endfunc - " vim: shiftwidth=2 sts=2 expandtab diff --git a/src/nvim/testdir/view_util.vim b/src/nvim/testdir/view_util.vim index 29ea073f97..520f65c1e7 100644 --- a/src/nvim/testdir/view_util.vim +++ b/src/nvim/testdir/view_util.vim @@ -42,6 +42,7 @@ endfunction function! NewWindow(height, width) abort exe a:height . 'new' exe a:width . 'vsp' + set winfixwidth winfixheight redraw! endfunction |