diff options
| author | ZyX <kp-pav@yandex.ru> | 2017-12-03 16:49:30 +0300 |
|---|---|---|
| committer | ZyX <kp-pav@yandex.ru> | 2017-12-03 16:49:30 +0300 |
| commit | c49e22d3964d6c7ae1c24e8ad01b5fec4ca40b57 (patch) | |
| tree | b7e59c416d1435725c65f8952b6e55c70544d97e /src/nvim/testdir | |
| parent | 62108c3b0be46936c83f6d4c98b44ceb5e6f77fd (diff) | |
| parent | 27a577586eace687c47e7398845178208cae524a (diff) | |
| download | rneovim-c49e22d3964d6c7ae1c24e8ad01b5fec4ca40b57.tar.gz rneovim-c49e22d3964d6c7ae1c24e8ad01b5fec4ca40b57.tar.bz2 rneovim-c49e22d3964d6c7ae1c24e8ad01b5fec4ca40b57.zip | |
Merge branch 'master' into s-dash-stdin
Diffstat (limited to 'src/nvim/testdir')
72 files changed, 9172 insertions, 431 deletions
diff --git a/src/nvim/testdir/Makefile b/src/nvim/testdir/Makefile index 9f9ecbc6c9..111bd172ef 100644 --- a/src/nvim/testdir/Makefile +++ b/src/nvim/testdir/Makefile @@ -1,12 +1,14 @@ -# +# vim: noet ts=8 # Makefile to run all tests for Vim # NVIM_PRG ?= ../../../build/bin/nvim +TMPDIR ?= Xtest-tmpdir SCRIPTSOURCE := ../../../runtime export SHELL := sh export NVIM_PRG := $(NVIM_PRG) +export TMPDIR SCRIPTS ?= \ test13.out \ @@ -28,17 +30,27 @@ SCRIPTS ?= \ # Tests using runtest.vim. # Keep test_alot*.res as the last one, sort the others. NEW_TESTS ?= \ + test_autocmd.res \ test_bufwintabinfo.res \ + test_charsearch.res \ test_cmdline.res \ + test_command_count.res \ test_cscope.res \ test_digraph.res \ test_diffmode.res \ test_farsi.res \ test_filter_map.res \ + test_fnameescape.res \ + test_fold.res \ + test_ga.res \ + test_glob2regpat.res \ + test_gf.res \ test_gn.res \ test_hardcopy.res \ test_help_tagjump.res \ + test_hide.res \ test_history.res \ + test_hlsearch.res \ test_increment.res \ test_increment_dbcs.res \ test_lambda.res \ @@ -46,14 +58,28 @@ NEW_TESTS ?= \ test_marks.res \ test_match.res \ test_matchadd_conceal.res \ + test_matchadd_conceal_utf8.res \ + test_mksession.res \ + test_mksession_utf8.res \ test_nested_function.res \ + test_normal.res \ + test_profile.res \ test_quickfix.res \ + test_retab.res \ + test_search.res \ test_signs.res \ + test_smartindent.res \ + test_stat.res \ + test_startup.res \ + test_startup_utf8.res \ + test_substitute.res \ test_syntax.res \ + test_tabpage.res \ test_textobjects.res \ test_timers.res \ + test_undo.res \ test_usercommands.res \ - test_viml.res \ + test_vimscript.res \ test_visual.res \ test_window_id.res \ test_writefile.res \ @@ -114,7 +140,7 @@ $(SCRIPTS) $(SCRIPTS_GUI): $(NVIM_PRG) test1.out RM_ON_RUN := test.out X* viminfo RM_ON_START := test.ok -RUN_VIM := VIMRUNTIME=$(SCRIPTSOURCE); export VIMRUNTIME; $(TOOL) $(NVIM_PRG) -u unix.vim -U NONE -i viminfo --noplugin -s dotest.in +RUN_VIM := VIMRUNTIME=$(SCRIPTSOURCE); export VIMRUNTIME; $(TOOL) $(NVIM_PRG) -u unix.vim -U NONE -i viminfo --headless --noplugin -s dotest.in clean: -rm -rf *.out \ @@ -130,10 +156,12 @@ clean: .*.swp \ .*.swo \ .gdbinit \ + $(TMPDIR) \ del test1.out: .gdbinit test1.in -rm -rf $*.failed $(RM_ON_RUN) $(RM_ON_START) wrongtermsize + mkdir -p $(TMPDIR) $(RUN_VIM) $*.in @/bin/sh -c "if test -e wrongtermsize; then \ echo; \ @@ -151,6 +179,7 @@ test1.out: .gdbinit test1.in %.out: %.in .gdbinit -rm -rf $*.failed test.ok $(RM_ON_RUN) + mkdir -p $(TMPDIR) cp $*.ok test.ok # Sleep a moment to avoid that the xterm title is messed up. # 200 msec is sufficient, but only modern sleep supports a fraction of @@ -183,7 +212,7 @@ nolog: # New style of tests uses Vim script with assert calls. These are easier # to write and a lot easier to read and debug. # Limitation: Only works with the +eval feature. -RUN_VIMTEST = VIMRUNTIME=$(SCRIPTSOURCE); export VIMRUNTIME; $(VALGRIND) $(NVIM_PRG) -u unix.vim -U NONE --noplugin +RUN_VIMTEST = VIMRUNTIME=$(SCRIPTSOURCE); export VIMRUNTIME; $(TOOL) $(NVIM_PRG) -u unix.vim -U NONE --headless --noplugin newtests: newtestssilent @/bin/sh -c "if test -f messages && grep -q 'FAILED' messages; then \ @@ -193,4 +222,5 @@ newtests: newtestssilent newtestssilent: $(NEW_TESTS) %.res: %.vim .gdbinit + mkdir -p $(TMPDIR) $(RUN_VIMTEST) -u NONE -S runtest.vim $*.vim diff --git a/src/nvim/testdir/runtest.vim b/src/nvim/testdir/runtest.vim index 0403a53f9c..4de1345679 100644 --- a/src/nvim/testdir/runtest.vim +++ b/src/nvim/testdir/runtest.vim @@ -68,15 +68,22 @@ let $HOME = '/does/not/exist' " Prepare for calling garbagecollect_for_testing(). let v:testing = 1 -" Align with vim defaults. +" Align Nvim defaults to Vim. set directory^=. -set nohidden set backspace= +set nohidden smarttab noautoindent noautoread complete-=i noruler noshowcmd +set listchars=eol:$ +" Prevent Nvim log from writing to stderr. +let $NVIM_LOG_FILE = exists($NVIM_LOG_FILE) ? $NVIM_LOG_FILE : 'Xnvim.log' -function RunTheTest(test) +func RunTheTest(test) echo 'Executing ' . a:test if exists("*SetUp") - call SetUp() + try + call SetUp() + catch + call add(v:errors, 'Caught exception in SetUp() before ' . a:test . ': ' . v:exception . ' @ ' . v:throwpoint) + endtry endif call add(s:messages, 'Executing ' . a:test) @@ -91,7 +98,11 @@ function RunTheTest(test) endtry if exists("*TearDown") - call TearDown() + try + call TearDown() + catch + call add(v:errors, 'Caught exception in TearDown() after ' . a:test . ': ' . v:exception . ' @ ' . v:throwpoint) + endtry endif " Close any extra windows and make the current one not modified. @@ -110,6 +121,60 @@ function RunTheTest(test) set nomodified endfunc +func AfterTheTest() + if len(v:errors) > 0 + let s:fail += 1 + call add(s:errors, 'Found errors in ' . s:test . ':') + call extend(s:errors, v:errors) + let v:errors = [] + endif +endfunc + +" This function can be called by a test if it wants to abort testing. +func FinishTesting() + call AfterTheTest() + + " Don't write viminfo on exit. + set viminfo= + + if s:fail == 0 + " Success, create the .res file so that make knows it's done. + exe 'split ' . fnamemodify(g:testname, ':r') . '.res' + write + endif + + if len(s:errors) > 0 + " Append errors to test.log + split test.log + call append(line('$'), '') + call append(line('$'), 'From ' . g:testname . ':') + call append(line('$'), s:errors) + write + endif + + let message = 'Executed ' . s:done . (s:done > 1 ? ' tests' : ' test') + echo message + call add(s:messages, message) + if s:fail > 0 + let message = s:fail . ' FAILED:' + echo message + call add(s:messages, message) + call extend(s:messages, s:errors) + endif + + " Add SKIPPED messages + call extend(s:messages, s:skipped) + + " Append messages to the file "messages" + split messages + call append(line('$'), '') + call append(line('$'), 'From ' . g:testname . ':') + call append(line('$'), s:messages) + write + + qall! +endfunc + " Source the test script. First grab the file name, in case the script " navigates away. g:testname can be used by the tests. let g:testname = expand('%') @@ -118,7 +183,7 @@ let s:fail = 0 let s:errors = [] let s:messages = [] let s:skipped = [] -if expand('%') =~ 'test_viml.vim' +if expand('%') =~ 'test_vimscript.vim' " this test has intentional s:errors, don't use try/catch. source % else @@ -131,10 +196,13 @@ else endif " Names of flaky tests. -let s:flaky = [] +let s:flaky = [ + \ 'Test_with_partial_callback()', + \ 'Test_oneshot()', + \ 'Test_lambda_with_timer()', + \ ] " Locate Test_ functions and execute them. -set nomore redir @q silent function /^Test_ redir END @@ -150,56 +218,14 @@ for s:test in sort(s:tests) call RunTheTest(s:test) if len(v:errors) > 0 && index(s:flaky, s:test) >= 0 - call add(s:messages, 'Flaky test failed, running it again') - let v:errors = [] - call RunTheTest(s:test) - endif - - if len(v:errors) > 0 - let s:fail += 1 - call add(s:errors, 'Found errors in ' . s:test . ':') - call extend(s:errors, v:errors) + call add(s:messages, 'Flaky test failed, running it again') let v:errors = [] + call RunTheTest(s:test) endif + call AfterTheTest() endfor -" Don't write viminfo on exit. -set viminfo= - -if s:fail == 0 - " Success, create the .res file so that make knows it's done. - exe 'split ' . fnamemodify(g:testname, ':r') . '.res' - write -endif - -if len(s:errors) > 0 - " Append errors to test.log - split test.log - call append(line('$'), '') - call append(line('$'), 'From ' . g:testname . ':') - call append(line('$'), s:errors) - write -endif - -let message = 'Executed ' . s:done . (s:done > 1 ? ' tests': ' test') -echo message -call add(s:messages, message) -if s:fail > 0 - let message = s:fail . ' FAILED' - echo message - call add(s:messages, message) - call extend(s:messages, s:errors) -endif - -" Add SKIPPED messages -call extend(s:messages, s:skipped) - -" Append messages to the file "messages" -split messages -call append(line('$'), '') -call append(line('$'), 'From ' . g:testname . ':') -call append(line('$'), s:messages) -write +call FinishTesting() -qall! +" vim: shiftwidth=2 sts=2 expandtab diff --git a/src/nvim/testdir/samples/memfile_test.c b/src/nvim/testdir/samples/memfile_test.c index 0fa1e14c40..3c8f108255 100644 --- a/src/nvim/testdir/samples/memfile_test.c +++ b/src/nvim/testdir/samples/memfile_test.c @@ -1,3 +1,6 @@ +// This is an open source non-commercial project. Dear PVS-Studio, please check +// it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com + /* vi:set ts=8 sts=4 sw=4 noet: * * VIM - Vi IMproved by Bram Moolenaar diff --git a/src/nvim/testdir/setup.vim b/src/nvim/testdir/setup.vim index 05257d566d..06f2199214 100644 --- a/src/nvim/testdir/setup.vim +++ b/src/nvim/testdir/setup.vim @@ -4,8 +4,9 @@ set noruler set noshowcmd set belloff= -" Make sure 'runtimepath' does not include $HOME. +" Make sure 'runtimepath' and 'packpath' does not include $HOME. set rtp=$VIM/vimfiles,$VIMRUNTIME,$VIM/vimfiles/after +let &packpath = &rtp " Make sure $HOME does not get read or written. let $HOME = '/does/not/exist' diff --git a/src/nvim/testdir/shared.vim b/src/nvim/testdir/shared.vim new file mode 100644 index 0000000000..72cfea96c6 --- /dev/null +++ b/src/nvim/testdir/shared.vim @@ -0,0 +1,214 @@ +" Functions shared by several tests. + +" Get the name of the Python executable. +" Also keeps it in s:python. +func PythonProg() + " This test requires the Python command to run the test server. + " This most likely only works on Unix and Windows. + if has('unix') + " We also need the job feature or the pkill command to make sure the server + " can be stopped. + if !(executable('python') && (has('job') || executable('pkill'))) + return '' + endif + let s:python = 'python' + elseif has('win32') + " Use Python Launcher for Windows (py.exe) if available. + if executable('py.exe') + let s:python = 'py.exe' + elseif executable('python.exe') + let s:python = 'python.exe' + else + return '' + endif + else + return '' + endif + return s:python +endfunc + +" Run "cmd". Returns the job if using a job. +func RunCommand(cmd) + let job = 0 + if has('job') + let job = job_start(a:cmd, {"stoponexit": "hup"}) + call job_setoptions(job, {"stoponexit": "kill"}) + elseif has('win32') + exe 'silent !start cmd /c start "test_channel" ' . a:cmd + else + exe 'silent !' . a:cmd . '&' + endif + return job +endfunc + +" Read the port number from the Xportnr file. +func GetPort() + let l = [] + for i in range(200) + try + let l = readfile("Xportnr") + catch + endtry + if len(l) >= 1 + break + endif + sleep 10m + endfor + call delete("Xportnr") + + if len(l) == 0 + " Can't make the connection, give up. + return 0 + endif + return l[0] +endfunc + +" Run a Python server for "cmd" and call "testfunc". +" Always kills the server before returning. +func RunServer(cmd, testfunc, args) + " The Python program writes the port number in Xportnr. + call delete("Xportnr") + + if len(a:args) == 1 + let arg = ' ' . a:args[0] + else + let arg = '' + endif + let pycmd = s:python . " " . a:cmd . arg + + try + let g:currentJob = RunCommand(pycmd) + + " Wait for up to 2 seconds for the port number to be there. + let port = GetPort() + if port == 0 + call assert_false(1, "Can't start " . a:cmd) + return + endif + + call call(function(a:testfunc), [port]) + catch + call assert_false(1, 'Caught exception: "' . v:exception . '" in ' . v:throwpoint) + finally + call s:kill_server(a:cmd) + endtry +endfunc + +func s:kill_server(cmd) + if has('job') + if exists('g:currentJob') + call job_stop(g:currentJob) + unlet g:currentJob + endif + elseif has('win32') + let cmd = substitute(a:cmd, ".py", '', '') + call system('taskkill /IM ' . s:python . ' /T /F /FI "WINDOWTITLE eq ' . cmd . '"') + else + call system("pkill -f " . a:cmd) + endif +endfunc + +" Wait for up to a second for "expr" to become true. +" 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. +func WaitFor(expr) + " using reltime() is more accurate, but not always available + if has('reltime') + let start = reltime() + else + let slept = 0 + endif + for i in range(100) + try + if eval(a:expr) + if has('reltime') + return float2nr(reltimefloat(reltime(start)) * 1000) + endif + return slept + endif + catch + endtry + if !has('reltime') + let slept += 10 + endif + sleep 10m + endfor + return 1000 +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. +" Without +timers it uses simply :sleep. +func Standby(msec) + if has('timers') + let start = reltime() + let g:_standby_timer = timer_start(a:msec, function('s:feedkeys')) + call getchar() + return float2nr(reltimefloat(reltime(start)) * 1000) + else + execute 'sleep ' a:msec . 'm' + return a:msec + endif +endfunc + +func Resume() + if exists('g:_standby_timer') + call timer_stop(g:_standby_timer) + call s:feedkeys(0) + unlet g:_standby_timer + endif +endfunc + +func s:feedkeys(timer) + call feedkeys('x', 'nt') +endfunc + +" Get the command to run Vim, with -u NONE and --headless arguments. +" Returns an empty string on error. +func GetVimCommand() + let cmd = v:progpath + let cmd = substitute(cmd, '-u \f\+', '-u NONE', '') + if cmd !~ '-u NONE' + let cmd = cmd . ' -u NONE' + endif + let cmd .= ' --headless -i NONE' + let cmd = substitute(cmd, 'VIMRUNTIME=.*VIMRUNTIME;', '', '') + return cmd +endfunc + +" Run Vim, using the "vimcmd" file and "-u NORC". +" "before" is a list of Vim commands to be executed before loading plugins. +" "after" is a list of Vim commands to be executed after loading plugins. +" Plugins are not loaded, unless 'loadplugins' is set in "before". +" Return 1 if Vim could be executed. +func RunVim(before, after, arguments) + return RunVimPiped(a:before, a:after, a:arguments, '') +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') + let args .= ' --cmd "so Xbefore.vim"' + endif + if len(a:after) > 0 + call writefile(a:after, 'Xafter.vim') + let args .= ' -S Xafter.vim' + endif + + exe "silent !" . a:pipecmd . cmd . args . ' ' . a:arguments + + if len(a:before) > 0 + call delete('Xbefore.vim') + endif + if len(a:after) > 0 + call delete('Xafter.vim') + endif + return 1 +endfunc diff --git a/src/nvim/testdir/test13.in b/src/nvim/testdir/test13.in deleted file mode 100644 index fa9ba312b7..0000000000 --- a/src/nvim/testdir/test13.in +++ /dev/null @@ -1,63 +0,0 @@ -Tests for autocommands on :close command - -Write three files and open them, each in a window. -Then go to next window, with autocommand that deletes the previous one. -Do this twice, writing the file. - -Also test deleting the buffer on a Unload event. If this goes wrong there -will be the ATTENTION prompt. - -Also test changing buffers in a BufDel autocommand. If this goes wrong there -are ml_line errors and/or a Crash. - -STARTTEST -:/^start of testfile/,/^end of testfile/w! Xtestje1 -:/^start of testfile/,/^end of testfile/w! Xtestje2 -:/^start of testfile/,/^end of testfile/w! Xtestje3 -:e Xtestje1 -otestje1 -:w -:sp Xtestje2 -otestje2 -:w -:sp Xtestje3 -otestje3 -:w - -:au WinLeave Xtestje2 bwipe - -:w! test.out -:au WinLeave Xtestje1 bwipe Xtestje3 -:close -:w >>test.out -:e Xtestje1 -:bwipe Xtestje2 Xtestje3 test.out -:au! -:au! BufUnload Xtestje1 bwipe -:e Xtestje3 -:w >>test.out -:e Xtestje2 -:sp Xtestje1 -:e -:w >>test.out -:au! -:only -:e Xtestje1 -:bwipe Xtestje2 Xtestje3 test.out test13.in -:au BufWipeout Xtestje1 buf Xtestje1 -:bwipe -:w >>test.out -:only -:new|set buftype=help -:wincmd w -:1quit -:$put ='Final line' -:$w >>test.out -:qa! -ENDTEST - -start of testfile - contents - contents - contents -end of testfile diff --git a/src/nvim/testdir/test13.ok b/src/nvim/testdir/test13.ok deleted file mode 100644 index 66ebce63f7..0000000000 --- a/src/nvim/testdir/test13.ok +++ /dev/null @@ -1,31 +0,0 @@ -start of testfile -testje1 - contents - contents - contents -end of testfile -start of testfile -testje1 - contents - contents - contents -end of testfile -start of testfile -testje3 - contents - contents - contents -end of testfile -start of testfile -testje2 - contents - contents - contents -end of testfile -start of testfile -testje1 - contents - contents - contents -end of testfile -Final line diff --git a/src/nvim/testdir/test49.vim b/src/nvim/testdir/test49.vim index adbabd61b9..467abcd9b9 100644 --- a/src/nvim/testdir/test49.vim +++ b/src/nvim/testdir/test49.vim @@ -608,7 +608,7 @@ com! -nargs=1 -bar ExecAsScript call ExecAsScript(<f-args>) " END_OF_TEST_ENVIRONMENT - do not change or remove this line. -" Tests 1 to 15 were moved to test_viml.vim +" Tests 1 to 15 were moved to test_vimscript.vim let Xtest = 16 "------------------------------------------------------------------------------- diff --git a/src/nvim/testdir/test_alot.vim b/src/nvim/testdir/test_alot.vim index 8aa0f417d1..c1f6405579 100644 --- a/src/nvim/testdir/test_alot.vim +++ b/src/nvim/testdir/test_alot.vim @@ -2,19 +2,21 @@ " This makes testing go faster, since Vim doesn't need to restart. source test_assign.vim -source test_autocmd.vim source test_cursor_func.vim source test_execute_func.vim source test_ex_undo.vim source test_expr.vim source test_expr_utf8.vim source test_feedkeys.vim +source test_filter_cmd.vim source test_filter_map.vim +source test_float_func.vim +source test_functions.vim +source test_ga.vim source test_goto.vim source test_jumps.vim +source test_fileformat.vim source test_lambda.vim -source test_match.vim -source test_matchadd_conceal_utf8.vim source test_menu.vim source test_mapping.vim source test_messages.vim @@ -26,9 +28,12 @@ source test_source_utf8.vim source test_statusline.vim source test_syn_attr.vim source test_tabline.vim -source test_tabpage.vim +" source test_tabpage.vim source test_tagcase.vim source test_tagjump.vim +source test_taglist.vim source test_true_false.vim source test_unlet.vim +source test_utf8.vim +source test_virtualedit.vim source test_window_cmd.vim diff --git a/src/nvim/testdir/test_autocmd.vim b/src/nvim/testdir/test_autocmd.vim index f05a55f1aa..82c04abf5b 100644 --- a/src/nvim/testdir/test_autocmd.vim +++ b/src/nvim/testdir/test_autocmd.vim @@ -1,5 +1,15 @@ " Tests for autocommands +set belloff=all + +function! s:cleanup_buffers() abort + for bnr in range(1, bufnr('$')) + if bufloaded(bnr) && bufnr('%') != bnr + execute 'bd! ' . bnr + endif + endfor +endfunction + func Test_vim_did_enter() call assert_false(v:vim_did_enter) @@ -13,6 +23,9 @@ if has('timers') endfunc func Test_cursorhold_insert() + " Need to move the cursor. + call feedkeys("ggG", "xt") + let g:triggered = 0 au CursorHoldI * let g:triggered += 1 set updatetime=20 @@ -20,6 +33,7 @@ if has('timers') call feedkeys('a', 'x!') call assert_equal(1, g:triggered) au! CursorHoldI + set updatetime& endfunc func Test_cursorhold_insert_ctrl_x() @@ -31,6 +45,7 @@ if has('timers') call feedkeys("a\<C-X>", 'x!') call assert_equal(0, g:triggered) au! CursorHoldI + set updatetime& endfunc endif @@ -77,11 +92,60 @@ function Test_autocmd_bufunload_with_tabnext() quit call assert_equal(2, tabpagenr('$')) + autocmd! test_autocmd_bufunload_with_tabnext_group augroup! test_autocmd_bufunload_with_tabnext_group tablast quit endfunc +function Test_autocmd_bufwinleave_with_tabfirst() + tabedit + augroup sample + autocmd! + autocmd BufWinLeave <buffer> tabfirst + augroup END + call setline(1, ['a', 'b', 'c']) + edit! a.txt + tabclose +endfunc + +" SEGV occurs in older versions. (At least 7.4.2321 or older) +function Test_autocmd_bufunload_avoiding_SEGV_01() + split aa.txt + let lastbuf = bufnr('$') + + augroup test_autocmd_bufunload + autocmd! + exe 'autocmd BufUnload <buffer> ' . (lastbuf + 1) . 'bwipeout!' + augroup END + + call assert_fails('edit bb.txt', 'E937:') + + autocmd! test_autocmd_bufunload + augroup! test_autocmd_bufunload + bwipe! aa.txt + bwipe! bb.txt +endfunc + +" SEGV occurs in older versions. (At least 7.4.2321 or older) +function Test_autocmd_bufunload_avoiding_SEGV_02() + setlocal buftype=nowrite + let lastbuf = bufnr('$') + + augroup test_autocmd_bufunload + autocmd! + exe 'autocmd BufUnload <buffer> ' . (lastbuf + 1) . 'bwipeout!' + augroup END + + normal! i1 + call assert_fails('edit a.txt', 'E517:') + call feedkeys("\<CR>") + + autocmd! test_autocmd_bufunload + augroup! test_autocmd_bufunload + bwipe! a.txt +endfunc + func Test_win_tab_autocmd() let g:record = [] @@ -172,6 +236,7 @@ func Test_augroup_warning() augroup Another augroup END call assert_true(match(execute('au VimEnter'), "-Deleted-.*VimEnter") >= 0) + augroup! Another " no warning for postpone aucmd delete augroup StartOK @@ -196,3 +261,184 @@ func Test_augroup_deleted() au! VimEnter endfunc +" Tests for autocommands on :close command. +" This used to be in test13. +func Test_three_windows() + " Clean up buffers, because in some cases this function fails. + call s:cleanup_buffers() + + " Write three files and open them, each in a window. + " Then go to next window, with autocommand that deletes the previous one. + " Do this twice, writing the file. + e! Xtestje1 + call setline(1, 'testje1') + w + sp Xtestje2 + call setline(1, 'testje2') + w + sp Xtestje3 + call setline(1, 'testje3') + w + wincmd w + au WinLeave Xtestje2 bwipe + wincmd w + call assert_equal('Xtestje1', expand('%')) + + au WinLeave Xtestje1 bwipe Xtestje3 + close + call assert_equal('Xtestje1', expand('%')) + + " Test deleting the buffer on a Unload event. If this goes wrong there + " will be the ATTENTION prompt. + e Xtestje1 + au! + au! BufUnload Xtestje1 bwipe + call assert_fails('e Xtestje3', 'E937:') + call assert_equal('Xtestje3', expand('%')) + + e Xtestje2 + sp Xtestje1 + call assert_fails('e', 'E937:') + call assert_equal('Xtestje2', expand('%')) + + " Test changing buffers in a BufWipeout autocommand. If this goes wrong + " there are ml_line errors and/or a Crash. + au! + only + e Xanother + e Xtestje1 + bwipe Xtestje2 + bwipe Xtestje3 + au BufWipeout Xtestje1 buf Xtestje1 + bwipe + call assert_equal('Xanother', expand('%')) + + only + + helptags ALL + help + wincmd w + 1quit + call assert_equal('Xanother', expand('%')) + + au! + enew + bwipe! Xtestje1 + call delete('Xtestje1') + call delete('Xtestje2') + call delete('Xtestje3') +endfunc + +func Test_BufEnter() + au! BufEnter + au Bufenter * let val = val . '+' + let g:val = '' + split NewFile + call assert_equal('+', g:val) + bwipe! + call assert_equal('++', g:val) + + " Also get BufEnter when editing a directory + call mkdir('Xdir') + split Xdir + call assert_equal('+++', g:val) + + " On MS-Windows we can't edit the directory, make sure we wipe the right + " buffer. + bwipe! Xdir + + call delete('Xdir', 'd') + au! BufEnter +endfunc + +" Closing a window might cause an endless loop +" E814 for older Vims +function Test_autocmd_bufwipe_in_SessLoadPost() + tabnew + set noswapfile + mksession! + + let content = ['set nocp noswapfile', + \ 'let v:swapchoice="e"', + \ 'augroup test_autocmd_sessionload', + \ 'autocmd!', + \ 'autocmd SessionLoadPost * 4bw!', + \ 'augroup END', + \ '', + \ 'func WriteErrors()', + \ ' call writefile([execute("messages")], "Xerrors")', + \ 'endfunc', + \ 'au VimLeave * call WriteErrors()', + \ ] + call writefile(content, 'Xvimrc') + call system(v:progpath. ' --headless -i NONE -u Xvimrc --noplugins -S Session.vim -c cq') + let errors = join(readfile('Xerrors')) + call assert_match('E814', errors) + + set swapfile + for file in ['Session.vim', 'Xvimrc', 'Xerrors'] + call delete(file) + endfor +endfunc + +" SEGV occurs in older versions. +function Test_autocmd_bufwipe_in_SessLoadPost2() + tabnew + 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()', + \ ] + call writefile(content, 'Xvimrc') + call system(v:progpath. ' --headless -i NONE -u Xvimrc --noplugins -S Session.vim -c cq') + let errors = join(readfile('Xerrors')) + " This probably only ever matches on unix. + call assert_notmatch('Caught deadly signal SEGV', errors) + call assert_match('SessionLoadPost DONE', errors) + + set swapfile + for file in ['Session.vim', 'Xvimrc', 'Xerrors'] + call delete(file) + endfor +endfunc + +func Test_Cmdline() + au! CmdlineEnter : let g:entered = expand('<afile>') + au! CmdlineLeave : let g:left = expand('<afile>') + let g:entered = 0 + let g:left = 0 + call feedkeys(":echo 'hello'\<CR>", 'xt') + call assert_equal(':', g:entered) + call assert_equal(':', g:left) + au! CmdlineEnter + au! CmdlineLeave + + au! CmdlineEnter / let g:entered = expand('<afile>') + au! CmdlineLeave / let g:left = expand('<afile>') + let g:entered = 0 + let g:left = 0 + call feedkeys("/hello<CR>", 'xt') + call assert_equal('/', g:entered) + call assert_equal('/', g:left) + au! CmdlineEnter + au! CmdlineLeave +endfunc diff --git a/src/nvim/testdir/test_breakindent.vim b/src/nvim/testdir/test_breakindent.vim new file mode 100644 index 0000000000..7deffbe452 --- /dev/null +++ b/src/nvim/testdir/test_breakindent.vim @@ -0,0 +1,298 @@ +" Test for breakindent +" +" Note: if you get strange failures when adding new tests, it might be that +" while the test is run, the breakindent cacheing gets in its way. +" It helps to change the tabstop setting and force a redraw (e.g. see +" Test_breakindent08()) +if !exists('+breakindent') + finish +endif + +source view_util.vim + +let s:input ="\tabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOP" + +function s:screen_lines(lnum, width) abort + return ScreenLines([a:lnum, a:lnum + 2], a:width) +endfunction + +function! s:compare_lines(expect, actual) + call assert_equal(join(a:expect, "\n"), join(a:actual, "\n")) +endfunction + +function s:test_windows(...) + call NewWindow(10, 20) + setl ts=4 sw=4 sts=4 breakindent + put =s:input + exe get(a:000, 0, '') +endfunction + +function s:close_windows(...) + call CloseWindow() + exe get(a:000, 0, '') +endfunction + +function Test_breakindent01() + " simple breakindent test + call s:test_windows('setl briopt=min:0') + let lines=s:screen_lines(line('.'),8) + let expect=[ +\ " abcd", +\ " qrst", +\ " GHIJ", +\ ] + call s:compare_lines(expect, lines) + call s:close_windows() +endfunction + +function Test_breakindent02() + " simple breakindent test with showbreak set + call s:test_windows('setl briopt=min:0 sbr=>>') + let lines=s:screen_lines(line('.'),8) + let expect=[ +\ " abcd", +\ " >>qr", +\ " >>EF", +\ ] + call s:compare_lines(expect, lines) + call s:close_windows('set sbr=') +endfunction + +function Test_breakindent03() + " simple breakindent test with showbreak set and briopt including sbr + call s:test_windows('setl briopt=sbr,min:0 sbr=++') + let lines=s:screen_lines(line('.'),8) + let expect=[ +\ " abcd", +\ "++ qrst", +\ "++ GHIJ", +\ ] + call s:compare_lines(expect, lines) + " clean up + call s:close_windows('set sbr=') +endfunction + +function Test_breakindent04() + " breakindent set with min width 18 + call s:test_windows('setl sbr= briopt=min:18') + let lines=s:screen_lines(line('.'),8) + let expect=[ +\ " abcd", +\ " qrstuv", +\ " IJKLMN", +\ ] + call s:compare_lines(expect, lines) + " clean up + call s:close_windows('set sbr=') +endfunction + +function Test_breakindent05() + " breakindent set and shift by 2 + call s:test_windows('setl briopt=shift:2,min:0') + let lines=s:screen_lines(line('.'),8) + let expect=[ +\ " abcd", +\ " qr", +\ " EF", +\ ] + call s:compare_lines(expect, lines) + call s:close_windows() +endfunction + +function Test_breakindent06() + " breakindent set and shift by -1 + call s:test_windows('setl briopt=shift:-1,min:0') + let lines=s:screen_lines(line('.'),8) + let expect=[ +\ " abcd", +\ " qrstu", +\ " HIJKL", +\ ] + call s:compare_lines(expect, lines) + call s:close_windows() +endfunction + +function Test_breakindent07() + " breakindent set and shift by 1, Number set sbr=? and briopt:sbr + call s:test_windows('setl briopt=shift:1,sbr,min:0 nu sbr=? nuw=4 cpo+=n') + let lines=s:screen_lines(line('.'),10) + let expect=[ +\ " 2 ab", +\ "? m", +\ "? x", +\ ] + call s:compare_lines(expect, lines) + " clean up + call s:close_windows('set sbr= cpo-=n') +endfunction + +function Test_breakindent07a() + " breakindent set and shift by 1, Number set sbr=? and briopt:sbr + call s:test_windows('setl briopt=shift:1,sbr,min:0 nu sbr=? nuw=4') + let lines=s:screen_lines(line('.'),10) + let expect=[ +\ " 2 ab", +\ " ? m", +\ " ? x", +\ ] + call s:compare_lines(expect, lines) + " clean up + call s:close_windows('set sbr=') +endfunction + +function Test_breakindent08() + " breakindent set and shift by 1, Number and list set sbr=# and briopt:sbr + call s:test_windows('setl briopt=shift:1,sbr,min:0 nu nuw=4 sbr=# list cpo+=n ts=4') + " make sure, cache is invalidated! + set ts=8 + redraw! + set ts=4 + redraw! + let lines=s:screen_lines(line('.'),10) + let expect=[ +\ " 2 ^Iabcd", +\ "# opq", +\ "# BCD", +\ ] + call s:compare_lines(expect, lines) + call s:close_windows('set sbr= cpo-=n') +endfunction + +function Test_breakindent08a() + " breakindent set and shift by 1, Number and list set sbr=# and briopt:sbr + call s:test_windows('setl briopt=shift:1,sbr,min:0 nu nuw=4 sbr=# list') + let lines=s:screen_lines(line('.'),10) + let expect=[ +\ " 2 ^Iabcd", +\ " # opq", +\ " # BCD", +\ ] + call s:compare_lines(expect, lines) + call s:close_windows('set sbr=') +endfunction + +function Test_breakindent09() + " breakindent set and shift by 1, Number and list set sbr=# + call s:test_windows('setl briopt=shift:1,min:0 nu nuw=4 sbr=# list') + let lines=s:screen_lines(line('.'),10) + let expect=[ +\ " 2 ^Iabcd", +\ " #op", +\ " #AB", +\ ] + call s:compare_lines(expect, lines) + call s:close_windows('set sbr=') +endfunction + +function Test_breakindent10() + " breakindent set, Number set sbr=~ + call s:test_windows('setl cpo+=n sbr=~ nu nuw=4 nolist briopt=sbr,min:0') + " make sure, cache is invalidated! + set ts=8 + redraw! + set ts=4 + redraw! + let lines=s:screen_lines(line('.'),10) + let expect=[ +\ " 2 ab", +\ "~ mn", +\ "~ yz", +\ ] + call s:compare_lines(expect, lines) + call s:close_windows('set sbr= cpo-=n') +endfunction + +function Test_breakindent11() + " test strdisplaywidth() + call s:test_windows('setl cpo-=n sbr=>> nu nuw=4 nolist briopt= ts=4') + let text=getline(2) + let width = strlen(text[1:])+indent(2)+strlen(&sbr)*3 " text wraps 3 times + call assert_equal(width, strdisplaywidth(text)) + call s:close_windows('set sbr=') +endfunction + +function Test_breakindent12() + " test breakindent with long indent + let s:input="\t\t\t\t\t{" + call s:test_windows('setl breakindent linebreak briopt=min:10 nu numberwidth=3 ts=4 list listchars=tab:>-') + let lines=s:screen_lines(2,16) + let expect=[ +\ " 2 >--->--->--->", +\ " ---{ ", +\ "~ ", +\ ] + call s:compare_lines(expect, lines) + call s:close_windows('set nuw=4 listchars=') +endfunction + +function Test_breakindent13() + let s:input="" + call s:test_windows('setl breakindent briopt=min:10 ts=8') + vert resize 20 + call setline(1, [" a\tb\tc\td\te", " z y x w v"]) + 1 + norm! fbgj"ayl + 2 + norm! fygj"byl + call assert_equal('d', @a) + call assert_equal('w', @b) + call s:close_windows() +endfunction + +function Test_breakindent14() + let s:input="" + call s:test_windows('setl breakindent briopt= ts=8') + vert resize 30 + norm! 3a1234567890 + norm! a abcde + exec "norm! 0\<C-V>tex" + let lines=s:screen_lines(line('.'),8) + let expect=[ +\ "e ", +\ "~ ", +\ "~ ", +\ ] + call s:compare_lines(expect, lines) + call s:close_windows() +endfunction + +function Test_breakindent15() + let s:input="" + call s:test_windows('setl breakindent briopt= ts=8 sw=8') + vert resize 30 + norm! 4a1234567890 + exe "normal! >>\<C-V>3f0x" + let lines=s:screen_lines(line('.'),20) + let expect=[ +\ " 1234567890 ", +\ "~ ", +\ "~ ", +\ ] + call s:compare_lines(expect, lines) + call s:close_windows() +endfunction + +function Test_breakindent16() + " Check that overlong lines are indented correctly. + let s:input="" + call s:test_windows('setl breakindent briopt=min:0 ts=4') + call setline(1, "\t".repeat("1234567890", 10)) + resize 6 + norm! 1gg$ + redraw! + let lines=s:screen_lines(1,10) + let expect=[ +\ " 789012", +\ " 345678", +\ " 901234", +\ ] + call s:compare_lines(expect, lines) + let lines=s:screen_lines(4,10) + let expect=[ +\ " 567890", +\ " 123456", +\ " 7890 ", +\ ] + call s:compare_lines(expect, lines) + call s:close_windows() +endfunction diff --git a/src/nvim/testdir/test_bufwintabinfo.vim b/src/nvim/testdir/test_bufwintabinfo.vim index 5c916e2dd7..1c9350c416 100644 --- a/src/nvim/testdir/test_bufwintabinfo.vim +++ b/src/nvim/testdir/test_bufwintabinfo.vim @@ -87,9 +87,17 @@ function Test_get_buf_options() endfunc function Test_get_win_options() + if has('folding') + set foldlevel=999 + endif + set list let opts = getwinvar(1, '&') call assert_equal(v:t_dict, type(opts)) call assert_equal(0, opts.linebreak) + call assert_equal(1, opts.list) + if has('folding') + call assert_equal(999, opts.foldlevel) + endif if has('signs') call assert_equal('auto', opts.signcolumn) endif @@ -97,7 +105,12 @@ function Test_get_win_options() let opts = gettabwinvar(1, 1, '&') call assert_equal(v:t_dict, type(opts)) call assert_equal(0, opts.linebreak) + call assert_equal(1, opts.list) if has('signs') call assert_equal('auto', opts.signcolumn) endif + set list& + if has('folding') + set foldlevel=0 + endif endfunc diff --git a/src/nvim/testdir/test_charsearch.vim b/src/nvim/testdir/test_charsearch.vim new file mode 100644 index 0000000000..8b313b5a35 --- /dev/null +++ b/src/nvim/testdir/test_charsearch.vim @@ -0,0 +1,62 @@ + +function! Test_charsearch() + enew! + call append(0, ['Xabcdefghijkemnopqretuvwxyz', + \ 'Yabcdefghijkemnopqretuvwxyz', + \ 'Zabcdefghijkemnokqretkvwxyz']) + " check that "fe" and ";" work + 1 + normal! ylfep;;p,,p + call assert_equal('XabcdeXfghijkeXmnopqreXtuvwxyz', getline(1)) + " check that save/restore works + 2 + normal! ylfep + let csave = getcharsearch() + normal! fip + call setcharsearch(csave) + normal! ;p;p + call assert_equal('YabcdeYfghiYjkeYmnopqreYtuvwxyz', getline(2)) + + " check that setcharsearch() changes the settings. + 3 + normal! ylfep + call setcharsearch({'char': 'k'}) + normal! ;p + call setcharsearch({'forward': 0}) + normal! $;p + call setcharsearch({'until': 1}) + set cpo-=; + normal! ;;p + call assert_equal('ZabcdeZfghijkZZemnokqretkZvwxyz', getline(3)) + enew! +endfunction + +" Test for t,f,F,T movement commands and 'cpo-;' setting +function! Test_search_cmds() + enew! + call append(0, ["aaa two three four", " zzz", "yyy ", + \ "bbb yee yoo four", "ccc two three four", + \ "ddd yee yoo four"]) + set cpo-=; + 1 + normal! 0tt;D + 2 + normal! 0fz;D + 3 + normal! $Fy;D + 4 + normal! $Ty;D + set cpo+=; + 5 + normal! 0tt;;D + 6 + normal! $Ty;;D + + call assert_equal('aaa two', getline(1)) + call assert_equal(' z', getline(2)) + call assert_equal('y', getline(3)) + call assert_equal('bbb y', getline(4)) + call assert_equal('ccc', getline(5)) + call assert_equal('ddd yee y', getline(6)) + enew! +endfunction diff --git a/src/nvim/testdir/test_cmdline.vim b/src/nvim/testdir/test_cmdline.vim index 40db227d97..ac44e09a5a 100644 --- a/src/nvim/testdir/test_cmdline.vim +++ b/src/nvim/testdir/test_cmdline.vim @@ -2,7 +2,7 @@ func Test_complete_tab() call writefile(['testfile'], 'Xtestfile') - call feedkeys(":e Xtest\t\r", "tx") + call feedkeys(":e Xtestf\t\r", "tx") call assert_equal('testfile', getline(1)) call delete('Xtestfile') endfunc @@ -17,7 +17,7 @@ func Test_complete_wildmenu() call writefile(['testfile1'], 'Xtestfile1') call writefile(['testfile2'], 'Xtestfile2') set wildmenu - call feedkeys(":e Xtest\t\t\r", "tx") + call feedkeys(":e Xtestf\t\t\r", "tx") call assert_equal('testfile2', getline(1)) call delete('Xtestfile1') @@ -25,6 +25,34 @@ func Test_complete_wildmenu() set nowildmenu endfunc +func Test_expr_completion() + if !(has('cmdline_compl') && has('eval')) + return + endif + for cmd in [ + \ 'let a = ', + \ 'if', + \ 'elseif', + \ 'while', + \ 'for', + \ 'echo', + \ 'echon', + \ 'execute', + \ 'echomsg', + \ 'echoerr', + \ 'call', + \ 'return', + \ 'cexpr', + \ 'caddexpr', + \ 'cgetexpr', + \ 'lexpr', + \ 'laddexpr', + \ 'lgetexpr'] + call feedkeys(":" . cmd . " getl\<Tab>\<Home>\"\<CR>", 'xt') + call assert_equal('"' . cmd . ' getline(', getreg(':')) + endfor +endfunc + func Test_getcompletion() if !has('cmdline_compl') return @@ -130,6 +158,11 @@ func Test_getcompletion() let l = getcompletion('dark', 'highlight') call assert_equal([], l) + let l = getcompletion('', 'messages') + call assert_true(index(l, 'clear') >= 0) + let l = getcompletion('not', 'messages') + call assert_equal([], l) + if has('cscope') let l = getcompletion('', 'cscope') let cmds = ['add', 'find', 'help', 'kill', 'reset', 'show'] @@ -156,6 +189,20 @@ func Test_getcompletion() call assert_equal(['Testing'], l) endif + " Command line completion tests + let l = getcompletion('cd ', 'cmdline') + call assert_true(index(l, 'sautest/') >= 0) + let l = getcompletion('cd NoMatch', 'cmdline') + call assert_equal([], l) + let l = getcompletion('let v:n', 'cmdline') + call assert_true(index(l, 'v:null') >= 0) + let l = getcompletion('let v:notexists', 'cmdline') + call assert_equal([], l) + let l = getcompletion('call tag', 'cmdline') + call assert_true(index(l, 'taglist(') >= 0) + let l = getcompletion('call paint', 'cmdline') + call assert_equal([], l) + " For others test if the name is recognized. let names = ['buffer', 'environment', 'file_in_path', \ 'mapping', 'shellcmd', 'tag', 'tag_listfiles', 'user'] @@ -187,5 +234,100 @@ func Test_expand_star_star() call writefile(['asdfasdf'], 'a/b/fileXname') call feedkeys(":find **/fileXname\<Tab>\<CR>", 'xt') call assert_equal('find a/b/fileXname', getreg(':')) + bwipe! call delete('a', 'rf') endfunc + +func Test_paste_in_cmdline() + let @a = "def" + call feedkeys(":abc \<C-R>a ghi\<C-B>\"\<CR>", 'tx') + call assert_equal('"abc def ghi', @:) + + new + call setline(1, 'asdf.x /tmp/some verylongword a;b-c*d ') + + call feedkeys(":aaa \<C-R>\<C-W> bbb\<C-B>\"\<CR>", 'tx') + call assert_equal('"aaa asdf bbb', @:) + + call feedkeys("ft:aaa \<C-R>\<C-F> bbb\<C-B>\"\<CR>", 'tx') + call assert_equal('"aaa /tmp/some bbb', @:) + + set incsearch + call feedkeys("fy:aaa veryl\<C-R>\<C-W> bbb\<C-B>\"\<CR>", 'tx') + call assert_equal('"aaa verylongword bbb', @:) + + call feedkeys("f;:aaa \<C-R>\<C-A> bbb\<C-B>\"\<CR>", 'tx') + call assert_equal('"aaa a;b-c*d bbb', @:) + + call feedkeys(":\<C-\>etoupper(getline(1))\<CR>\<C-B>\"\<CR>", 'tx') + call assert_equal('"ASDF.X /TMP/SOME VERYLONGWORD A;B-C*D ', @:) + bwipe! +endfunc + +func Test_remove_char_in_cmdline() + call feedkeys(":abc def\<S-Left>\<Del>\<C-B>\"\<CR>", 'tx') + call assert_equal('"abc ef', @:) + + call feedkeys(":abc def\<S-Left>\<BS>\<C-B>\"\<CR>", 'tx') + call assert_equal('"abcdef', @:) + + call feedkeys(":abc def ghi\<S-Left>\<C-W>\<C-B>\"\<CR>", 'tx') + call assert_equal('"abc ghi', @:) + + call feedkeys(":abc def\<S-Left>\<C-U>\<C-B>\"\<CR>", 'tx') + call assert_equal('"def', @:) +endfunc + +func Test_illegal_address1() + new + 2;'( + 2;') + quit +endfunc + +func Test_illegal_address2() + call writefile(['c', 'x', ' x', '.', '1;y'], 'Xtest.vim') + new + source Xtest.vim + " Trigger calling validate_cursor() + diffsp Xtest.vim + quit! + bwipe! + call delete('Xtest.vim') +endfunc + +func Test_cmdline_complete_wildoptions() + help + call feedkeys(":tag /\<c-a>\<c-b>\"\<cr>", 'tx') + let a = join(sort(split(@:)),' ') + set wildoptions=tagfile + call feedkeys(":tag /\<c-a>\<c-b>\"\<cr>", 'tx') + let b = join(sort(split(@:)),' ') + call assert_equal(a, b) + bw! +endfunc + +" using a leading backslash here +set cpo+=C + +func Test_cmdline_search_range() + new + call setline(1, ['a', 'b', 'c', 'd']) + /d + 1,\/s/b/B/ + call assert_equal('B', getline(2)) + + /a + $ + \?,4s/c/C/ + call assert_equal('C', getline(3)) + + call setline(1, ['a', 'b', 'c', 'd']) + %s/c/c/ + 1,\&s/b/B/ + call assert_equal('B', getline(2)) + + bwipe! +endfunc + +set cpo& diff --git a/src/nvim/testdir/test_command_count.vim b/src/nvim/testdir/test_command_count.vim new file mode 100644 index 0000000000..e438a8b077 --- /dev/null +++ b/src/nvim/testdir/test_command_count.vim @@ -0,0 +1,191 @@ +" Test for user command counts. + +func Test_command_count_0() + set hidden + set noswapfile + + split DoesNotExistEver + let lastbuf = bufnr('$') + call setline(1, 'asdf') + quit! + + command! -range -addr=loaded_buffers RangeLoadedBuffers :let lines = [<line1>, <line2>] + command! -range=% -addr=loaded_buffers RangeLoadedBuffersAll :let lines = [<line1>, <line2>] + command! -range -addr=buffers RangeBuffers :let lines = [<line1>, <line2>] + command! -range=% -addr=buffers RangeBuffersAll :let lines = [<line1>, <line2>] + + .,$RangeLoadedBuffers + call assert_equal([1, 1], lines) + %RangeLoadedBuffers + call assert_equal([1, 1], lines) + RangeLoadedBuffersAll + call assert_equal([1, 1], lines) + .,$RangeBuffers + call assert_equal([1, lastbuf], lines) + %RangeBuffers + call assert_equal([1, lastbuf], lines) + RangeBuffersAll + call assert_equal([1, lastbuf], lines) + + delcommand RangeLoadedBuffers + delcommand RangeLoadedBuffersAll + delcommand RangeBuffers + delcommand RangeBuffersAll + + set hidden& + set swapfile& +endfunc + +func Test_command_count_1() + silent! %argd + arga a b c d e + argdo echo "loading buffers" + argu 3 + command! -range -addr=arguments RangeArguments :let lines = [<line1>, <line2>] + command! -range=% -addr=arguments RangeArgumentsAll :let lines = [<line1>, <line2>] + .-,$-RangeArguments + call assert_equal([2, 4], lines) + %RangeArguments + call assert_equal([1, 5], lines) + RangeArgumentsAll + call assert_equal([1, 5], lines) + N + .RangeArguments + call assert_equal([2, 2], lines) + delcommand RangeArguments + delcommand RangeArgumentsAll + + split|split|split|split + 3wincmd w + command! -range -addr=windows RangeWindows :let lines = [<line1>, <line2>] + .,$RangeWindows + call assert_equal([3, 5], lines) + %RangeWindows + call assert_equal([1, 5], lines) + delcommand RangeWindows + + command! -range=% -addr=windows RangeWindowsAll :let lines = [<line1>, <line2>] + RangeWindowsAll + call assert_equal([1, 5], lines) + delcommand RangeWindowsAll + only + blast|bd + + tabe|tabe|tabe|tabe + normal 2gt + command! -range -addr=tabs RangeTabs :let lines = [<line1>, <line2>] + .,$RangeTabs + call assert_equal([2, 5], lines) + %RangeTabs + call assert_equal([1, 5], lines) + delcommand RangeTabs + + command! -range=% -addr=tabs RangeTabsAll :let lines = [<line1>, <line2>] + RangeTabsAll + call assert_equal([1, 5], lines) + delcommand RangeTabsAll + 1tabonly + + s/\n/\r\r\r\r\r/ + 2ma< + $-ma> + command! -range=% RangeLines :let lines = [<line1>, <line2>] + '<,'>RangeLines + call assert_equal([2, 5], lines) + delcommand RangeLines + + command! -range=% -buffer LocalRangeLines :let lines = [<line1>, <line2>] + '<,'>LocalRangeLines + call assert_equal([2, 5], lines) + delcommand LocalRangeLines +endfunc + +func Test_command_count_2() + silent! %argd + arga a b c d + call assert_fails('5argu', 'E16:') + + $argu + call assert_equal('d', expand('%:t')) + + 1argu + call assert_equal('a', expand('%:t')) + + call assert_fails('300b', 'E16:') + + split|split|split|split + 0close + + $wincmd w + $close + call assert_equal(3, winnr()) + + call assert_fails('$+close', 'E16:') + + $tabe + call assert_equal(2, tabpagenr()) + + call assert_fails('$+tabe', 'E16:') + + only! + e x + 0tabm + normal 1gt + call assert_equal('x', expand('%:t')) + + tabonly! + only! +endfunc + +func Test_command_count_3() + se nohidden + e aaa + let buf_aaa = bufnr('%') + e bbb + let buf_bbb = bufnr('%') + e ccc + let buf_ccc = bufnr('%') + buf 1 + call assert_equal([1, 1, 1], [buflisted(buf_aaa), buflisted(buf_bbb), buflisted(buf_ccc)]) + exe buf_bbb . "," . buf_ccc . "bdelete" + call assert_equal([1, 0, 0], [buflisted(buf_aaa), buflisted(buf_bbb), buflisted(buf_ccc)]) + exe buf_aaa . "bdelete" + call assert_equal([0, 0, 0], [buflisted(buf_aaa), buflisted(buf_bbb), buflisted(buf_ccc)]) +endfunc + +func Test_command_count_4() + %argd + let bufnr = bufnr('$') + 1 + arga aa bb cc dd ee ff + 3argu + let args = [] + .,$-argdo call add(args, expand('%')) + call assert_equal(['cc', 'dd', 'ee'], args) + + " create windows to get 5 + split|split|split|split + 2wincmd w + let windows = [] + .,$-windo call add(windows, winnr()) + call assert_equal([2, 3, 4], windows) + only! + + exe bufnr . 'buf' + let buffers = [] + .,$-bufdo call add(buffers, bufnr('%')) + call assert_equal([bufnr, bufnr + 1, bufnr + 2, bufnr + 3, bufnr + 4], buffers) + + exe (bufnr + 3) . 'bdel' + let buffers = [] + exe (bufnr + 2) . ',' . (bufnr + 5) . "bufdo call add(buffers, bufnr('%'))" + call assert_equal([bufnr + 2, bufnr + 4, bufnr + 5], buffers) + + " create tabpages to get 5 + tabe|tabe|tabe|tabe + normal! 2gt + let tabpages = [] + .,$-tabdo call add(tabpages, tabpagenr()) + call assert_equal([2, 3, 4], tabpages) + tabonly! + bwipe! +endfunc diff --git a/src/nvim/testdir/test_cscope.vim b/src/nvim/testdir/test_cscope.vim index c8d2ebd7da..01a9a3f9ad 100644 --- a/src/nvim/testdir/test_cscope.vim +++ b/src/nvim/testdir/test_cscope.vim @@ -28,7 +28,7 @@ func Test_cscopeWithCscopeConnections() cscope add Xcscope.out set cscopeverbose catch - call assert_true(0) + call assert_report('exception thrown') endtry call assert_fails('cscope add', 'E560') call assert_fails('cscope add Xcscope.out', 'E568') diff --git a/src/nvim/testdir/test_cursor_func.vim b/src/nvim/testdir/test_cursor_func.vim index d819b7b092..e1b9651c84 100644 --- a/src/nvim/testdir/test_cursor_func.vim +++ b/src/nvim/testdir/test_cursor_func.vim @@ -1,13 +1,7 @@ " Tests for cursor(). func Test_wrong_arguments() - try - call cursor(1. 3) - " not reached - call assert_false(1) - catch - call assert_exception('E474:') - endtry + call assert_fails('call cursor(1. 3)', 'E474:') endfunc func Test_move_cursor() diff --git a/src/nvim/testdir/test_diffmode.vim b/src/nvim/testdir/test_diffmode.vim index 5de394de8e..8ee82bd538 100644 --- a/src/nvim/testdir/test_diffmode.vim +++ b/src/nvim/testdir/test_diffmode.vim @@ -212,9 +212,63 @@ func Test_diffoff() call setline(1, ['One', '', 'Two', 'Three']) diffthis redraw + call assert_notequal(normattr, screenattr(1, 1)) diffoff! redraw call assert_equal(normattr, screenattr(1, 1)) bwipe! bwipe! endfunc + +func Test_diffoff_hidden() + set diffopt=filler,foldcolumn:0 + e! one + call setline(1, ['Two', 'Three']) + let normattr = screenattr(1, 1) + diffthis + botright vert new two + call setline(1, ['One', 'Four']) + diffthis + redraw + call assert_notequal(normattr, screenattr(1, 1)) + set hidden + close + redraw + " diffing with hidden buffer two + call assert_notequal(normattr, screenattr(1, 1)) + diffoff + redraw + call assert_equal(normattr, screenattr(1, 1)) + diffthis + redraw + " still diffing with hidden buffer two + call assert_notequal(normattr, screenattr(1, 1)) + diffoff! + redraw + call assert_equal(normattr, screenattr(1, 1)) + diffthis + redraw + " no longer diffing with hidden buffer two + call assert_equal(normattr, screenattr(1, 1)) + + bwipe! + bwipe! + set hidden& diffopt& +endfunc + +func Test_setting_cursor() + new Xtest1 + put =range(1,90) + wq + new Xtest2 + put =range(1,100) + wq + + tabe Xtest2 + $ + diffsp Xtest1 + tabclose + + call delete('Xtest1') + call delete('Xtest2') +endfunc diff --git a/src/nvim/testdir/test_display.vim b/src/nvim/testdir/test_display.vim new file mode 100644 index 0000000000..0ed672d577 --- /dev/null +++ b/src/nvim/testdir/test_display.vim @@ -0,0 +1,71 @@ +" Test for displaying stuff + +" Nvim: `:set term` is not supported. +" if !has('gui_running') && has('unix') +" set term=ansi +" endif + +source view_util.vim + +func! Test_display_foldcolumn() + if !has("folding") + return + endif + new + vnew + vert resize 25 + call assert_equal(25, winwidth(winnr())) + set isprint=@ + + 1put='e more noise blah blah more stuff here' + + let expect = [ + \ "e more noise blah blah<82", + \ "> more stuff here " + \ ] + + call cursor(2, 1) + norm! zt + let lines=ScreenLines([1,2], winwidth(0)) + call assert_equal(expect, lines) + set fdc=2 + let lines=ScreenLines([1,2], winwidth(0)) + let expect = [ + \ " e more noise blah blah<", + \ " 82> more stuff here " + \ ] + call assert_equal(expect, lines) + + quit! + quit! +endfunc + +func! Test_display_foldtext_mbyte() + if !has("folding") || !has("multi_byte") + return + endif + call NewWindow(10, 40) + call append(0, range(1,20)) + exe "set foldmethod=manual foldtext=foldtext() fillchars=fold:\u2500,vert:\u2502 fdc=2" + call cursor(2, 1) + norm! zf13G + let lines=ScreenLines([1,3], winwidth(0)+1) + let expect=[ + \ " 1 \u2502", + \ "+ +-- 12 lines: 2". repeat("\u2500", 23). "\u2502", + \ " 14 \u2502", + \ ] + call assert_equal(expect, lines) + + set fillchars=fold:-,vert:\| + let lines=ScreenLines([1,3], winwidth(0)+1) + let expect=[ + \ " 1 |", + \ "+ +-- 12 lines: 2". repeat("-", 23). "|", + \ " 14 |", + \ ] + call assert_equal(expect, lines) + + set foldtext& fillchars& foldmethod& fdc& + bw! +endfunc diff --git a/src/nvim/testdir/test_expr.vim b/src/nvim/testdir/test_expr.vim index 7f7811dc7a..d32facaa98 100644 --- a/src/nvim/testdir/test_expr.vim +++ b/src/nvim/testdir/test_expr.vim @@ -78,7 +78,7 @@ endfunc func Test_loop_over_null_list() let null_list = submatch(1, 1) for i in null_list - call assert_true(0, 'should not get here') + call assert_report('should not get here') endfor endfunc @@ -98,11 +98,44 @@ func Test_special_char() call assert_fails('echo "\<C-">') endfunc +func Test_option_value() + " boolean + set bri + call assert_equal(1, &bri) + set nobri + call assert_equal(0, &bri) + + " number + set ts=1 + call assert_equal(1, &ts) + set ts=8 + call assert_equal(8, &ts) + + " string + exe "set cedit=\<Esc>" + call assert_equal("\<Esc>", &cedit) + set cpo= + call assert_equal("", &cpo) + set cpo=abcdefi + call assert_equal("abcdefi", &cpo) + set cpo&vim +endfunc + +function Test_printf_64bit() + if has('num64') + call assert_equal("123456789012345", printf('%d', 123456789012345)) + endif +endfunc + func Test_setmatches() hi def link 1 Comment hi def link 2 PreProc - let set = [{"group": 1, "pattern": 2, "id": 3, "priority": 4, "conceal": 5}] - let exp = [{"group": '1', "pattern": '2', "id": 3, "priority": 4, "conceal": '5'}] + let set = [{"group": 1, "pattern": 2, "id": 3, "priority": 4}] + let exp = [{"group": '1', "pattern": '2', "id": 3, "priority": 4}] + if has('conceal') + let set[0]['conceal'] = 5 + let exp[0]['conceal'] = '5' + endif call setmatches(set) call assert_equal(exp, getmatches()) endfunc @@ -152,20 +185,52 @@ function Test_printf_misc() call assert_equal(' 123', printf('% d', 123)) call assert_equal('-123', printf('% d', -123)) + call assert_equal('123', printf('%2d', 123)) + call assert_equal(' 123', printf('%6d', 123)) + call assert_equal('000123', printf('%06d', 123)) + call assert_equal('+00123', printf('%+06d', 123)) + call assert_equal(' 00123', printf('% 06d', 123)) + call assert_equal(' +123', printf('%+6d', 123)) + call assert_equal(' 123', printf('% 6d', 123)) + call assert_equal(' -123', printf('% 6d', -123)) + + " Test left adjusted. + call assert_equal('123 ', printf('%-6d', 123)) + call assert_equal('+123 ', printf('%-+6d', 123)) + call assert_equal(' 123 ', printf('%- 6d', 123)) + call assert_equal('-123 ', printf('%- 6d', -123)) + + call assert_equal(' 00123', printf('%7.5d', 123)) + call assert_equal(' -00123', printf('%7.5d', -123)) + call assert_equal(' +00123', printf('%+7.5d', 123)) + " Precision field should not be used when combined with %0 + call assert_equal(' 00123', printf('%07.5d', 123)) + call assert_equal(' -00123', printf('%07.5d', -123)) + + call assert_equal(' 123', printf('%*d', 5, 123)) + call assert_equal('123 ', printf('%*d', -5, 123)) call assert_equal('00123', printf('%.*d', 5, 123)) call assert_equal(' 123', printf('% *d', 5, 123)) call assert_equal(' +123', printf('%+ *d', 5, 123)) - call assert_equal('123', printf('%2d', 123)) - call assert_equal(' 123', printf('%5d', 123)) - call assert_equal('00123', printf('%05d', 123)) - call assert_equal('123 ', printf('%-5d', 123)) + " Simple quote (thousand grouping char) is ignored. + call assert_equal('+00123456', printf("%+'09d", 123456)) + + " Unrecognized format specifier kept as-is. + call assert_equal('_123', printf("%_%d", 123)) + + " Test alternate forms. call assert_equal('0x7b', printf('%#x', 123)) call assert_equal('0X7B', printf('%#X', 123)) call assert_equal('0173', printf('%#o', 123)) call assert_equal('0173', printf('%#O', 123)) call assert_equal('abc', printf('%#s', 'abc')) call assert_equal('abc', printf('%#S', 'abc')) + call assert_equal(' 0173', printf('%#6o', 123)) + call assert_equal(' 00173', printf('%#6.5o', 123)) + call assert_equal(' 0173', printf('%#6.2o', 123)) + call assert_equal(' 0173', printf('%#6.2o', 123)) + call assert_equal('0173', printf('%#2.2o', 123)) call assert_equal(' 00123', printf('%6.5d', 123)) call assert_equal(' 0007b', printf('%6.5x', 123)) @@ -189,24 +254,104 @@ function Test_printf_misc() endfunc function Test_printf_float() + call assert_equal('1.000000', printf('%f', 1)) call assert_equal('1.230000', printf('%f', 1.23)) call assert_equal('1.230000', printf('%F', 1.23)) - call assert_equal('1.23', printf('%g', 1.23)) - call assert_equal('1.23', printf('%G', 1.23)) + call assert_equal('9999999.9', printf('%g', 9999999.9)) + call assert_equal('9999999.9', printf('%G', 9999999.9)) + call assert_equal('1.00000001e7', printf('%.8g', 10000000.1)) + call assert_equal('1.00000001E7', printf('%.8G', 10000000.1)) call assert_equal('1.230000e+00', printf('%e', 1.23)) call assert_equal('1.230000E+00', printf('%E', 1.23)) call assert_equal('1.200000e-02', printf('%e', 0.012)) call assert_equal('-1.200000e-02', printf('%e', -0.012)) - call assert_equal('1.2', printf('%.1f', 1.23)) - + call assert_equal('0.33', printf('%.2f', 1.0/3.0)) + call assert_equal(' 0.33', printf('%6.2f', 1.0/3.0)) + call assert_equal(' -0.33', printf('%6.2f', -1.0/3.0)) + call assert_equal('000.33', printf('%06.2f', 1.0/3.0)) + call assert_equal('-00.33', printf('%06.2f', -1.0/3.0)) + call assert_equal('-00.33', printf('%+06.2f', -1.0/3.0)) + call assert_equal('+00.33', printf('%+06.2f', 1.0/3.0)) + call assert_equal(' 00.33', printf('% 06.2f', 1.0/3.0)) + call assert_equal('000.33', printf('%06.2g', 1.0/3.0)) + call assert_equal('-00.33', printf('%06.2g', -1.0/3.0)) + call assert_equal('0.33', printf('%3.2f', 1.0/3.0)) + call assert_equal('003.33e-01', printf('%010.2e', 1.0/3.0)) + call assert_equal(' 03.33e-01', printf('% 010.2e', 1.0/3.0)) + call assert_equal('+03.33e-01', printf('%+010.2e', 1.0/3.0)) + call assert_equal('-03.33e-01', printf('%010.2e', -1.0/3.0)) + + " When precision is 0, the dot should be omitted. + call assert_equal(' 2', printf('%3.f', 7.0/3.0)) + call assert_equal(' 2', printf('%3.g', 7.0/3.0)) + call assert_equal(' 2e+00', printf('%7.e', 7.0/3.0)) + + " Float zero can be signed. + call assert_equal('+0.000000', printf('%+f', 0.0)) + call assert_equal('0.000000', printf('%f', 1.0/(1.0/0.0))) + call assert_equal('-0.000000', printf('%f', 1.0/(-1.0/0.0))) + call assert_equal('0.0', printf('%s', 1.0/(1.0/0.0))) + call assert_equal('-0.0', printf('%s', 1.0/(-1.0/0.0))) + call assert_equal('0.0', printf('%S', 1.0/(1.0/0.0))) + call assert_equal('-0.0', printf('%S', 1.0/(-1.0/0.0))) + + " Float infinity can be signed. call assert_equal('inf', printf('%f', 1.0/0.0)) - - " This prints inf but shouldn't it print -inf instead? - call assert_match('^-\?inf$', printf('%f', -1.0/0.0)) - - " This prints -nan but shouldn't it print nan instead? - call assert_match('^-\?nan$', printf('%f', sqrt(-1.0))) - call assert_match('^-\?nan$', printf('%f', 0.0/0.0)) + call assert_equal('-inf', printf('%f', -1.0/0.0)) + call assert_equal('inf', printf('%g', 1.0/0.0)) + call assert_equal('-inf', printf('%g', -1.0/0.0)) + call assert_equal('inf', printf('%e', 1.0/0.0)) + call assert_equal('-inf', printf('%e', -1.0/0.0)) + call assert_equal('INF', printf('%F', 1.0/0.0)) + call assert_equal('-INF', printf('%F', -1.0/0.0)) + call assert_equal('INF', printf('%E', 1.0/0.0)) + call assert_equal('-INF', printf('%E', -1.0/0.0)) + call assert_equal('INF', printf('%E', 1.0/0.0)) + call assert_equal('-INF', printf('%G', -1.0/0.0)) + call assert_equal('+inf', printf('%+f', 1.0/0.0)) + call assert_equal('-inf', printf('%+f', -1.0/0.0)) + call assert_equal(' inf', printf('% f', 1.0/0.0)) + call assert_equal(' inf', printf('%6f', 1.0/0.0)) + call assert_equal(' -inf', printf('%6f', -1.0/0.0)) + call assert_equal(' inf', printf('%6g', 1.0/0.0)) + call assert_equal(' -inf', printf('%6g', -1.0/0.0)) + call assert_equal(' +inf', printf('%+6f', 1.0/0.0)) + call assert_equal(' inf', printf('% 6f', 1.0/0.0)) + call assert_equal(' +inf', printf('%+06f', 1.0/0.0)) + call assert_equal('inf ', printf('%-6f', 1.0/0.0)) + call assert_equal('-inf ', printf('%-6f', -1.0/0.0)) + call assert_equal('+inf ', printf('%-+6f', 1.0/0.0)) + call assert_equal(' inf ', printf('%- 6f', 1.0/0.0)) + call assert_equal('-INF ', printf('%-6F', -1.0/0.0)) + call assert_equal('+INF ', printf('%-+6F', 1.0/0.0)) + call assert_equal(' INF ', printf('%- 6F', 1.0/0.0)) + call assert_equal('INF ', printf('%-6G', 1.0/0.0)) + call assert_equal('-INF ', printf('%-6G', -1.0/0.0)) + call assert_equal('INF ', printf('%-6E', 1.0/0.0)) + call assert_equal('-INF ', printf('%-6E', -1.0/0.0)) + call assert_equal("str2float('inf')", printf('%s', 1.0/0.0)) + call assert_equal("-str2float('inf')", printf('%s', -1.0/0.0)) + + " Float nan (not a number) has no sign. + call assert_equal('nan', printf('%f', sqrt(-1.0))) + call assert_equal('nan', printf('%f', 0.0/0.0)) + call assert_equal('nan', printf('%f', -0.0/0.0)) + call assert_equal('nan', printf('%g', 0.0/0.0)) + call assert_equal('nan', printf('%e', 0.0/0.0)) + call assert_equal('NAN', printf('%F', 0.0/0.0)) + call assert_equal('NAN', printf('%G', 0.0/0.0)) + call assert_equal('NAN', printf('%E', 0.0/0.0)) + call assert_equal('NAN', printf('%F', -0.0/0.0)) + call assert_equal('NAN', printf('%G', -0.0/0.0)) + call assert_equal('NAN', printf('%E', -0.0/0.0)) + call assert_equal(' nan', printf('%6f', 0.0/0.0)) + call assert_equal(' nan', printf('%06f', 0.0/0.0)) + call assert_equal('nan ', printf('%-6f', 0.0/0.0)) + call assert_equal('nan ', printf('%- 6f', 0.0/0.0)) + call assert_equal("str2float('nan')", printf('%s', 0.0/0.0)) + call assert_equal("str2float('nan')", printf('%s', -0.0/0.0)) + call assert_equal("str2float('nan')", printf('%S', 0.0/0.0)) + call assert_equal("str2float('nan')", printf('%S', -0.0/0.0)) call assert_fails('echo printf("%f", "a")', 'E807:') endfunc @@ -219,6 +364,13 @@ function Test_printf_errors() call assert_fails('echo printf("%d", 1.2)', 'E805:') endfunc +function Test_max_min_errors() + call assert_fails('call max(v:true)', 'E712:') + call assert_fails('call max(v:true)', 'max()') + call assert_fails('call min(v:true)', 'E712:') + call assert_fails('call min(v:true)', 'min()') +endfunc + func Test_substitute_expr() let g:val = 'XXX' call assert_equal('XXX', substitute('yyy', 'y*', '\=g:val', '')) @@ -232,9 +384,10 @@ func Test_substitute_expr() \ {-> submatch(2) . submatch(3) . submatch(1)}, '')) func Recurse() - return substitute('yyy', 'y*', {-> g:val}, '') + return substitute('yyy', 'y\(.\)y', {-> submatch(1)}, '') endfunc - call assert_equal('--', substitute('xxx', 'x*', {-> '-' . Recurse() . '-'}, '')) + " recursive call works + call assert_equal('-y-x-', substitute('xxx', 'x\(.\)x', {-> '-' . Recurse() . '-' . submatch(1) . '-'}, '')) endfunc func Test_invalid_submatch() @@ -266,6 +419,9 @@ func Test_function_with_funcref() let s:fref = function(s:f) call assert_equal(v:t_string, s:fref('x')) call assert_fails("call function('s:f')", 'E700:') + + call assert_fails("call function('foo()')", 'E475:') + call assert_fails("call function('foo()')", 'foo()') endfunc func Test_funcref() diff --git a/src/nvim/testdir/test_fileformat.vim b/src/nvim/testdir/test_fileformat.vim new file mode 100644 index 0000000000..8dc25f62b1 --- /dev/null +++ b/src/nvim/testdir/test_fileformat.vim @@ -0,0 +1,33 @@ +" Test behavior of fileformat after bwipeout of last buffer + +func Test_fileformat_after_bw() + bwipeout + set fileformat& + if &fileformat == 'dos' + let test_fileformats = 'unix' + elseif &fileformat == 'unix' + let test_fileformats = 'mac' + else " must be mac + let test_fileformats = 'dos' + endif + exec 'set fileformats='.test_fileformats + bwipeout! + call assert_equal(test_fileformats, &fileformat) + set fileformats& +endfunc + +func Test_fileformat_autocommand() + let filecnt = ["", "foobar\<CR>", "eins\<CR>", "\<CR>", "zwei\<CR>", "drei", "vier", "fünf", ""] + let ffs = &ffs + call writefile(filecnt, 'Xfile', 'b') + au BufReadPre Xfile set ffs=dos ff=dos + new Xfile + call assert_equal('dos', &l:ff) + call assert_equal('dos', &ffs) + + " cleanup + call delete('Xfile') + let &ffs = ffs + au! BufReadPre Xfile + bw! +endfunc diff --git a/src/nvim/testdir/test_filter_cmd.vim b/src/nvim/testdir/test_filter_cmd.vim new file mode 100644 index 0000000000..5aa5fa64df --- /dev/null +++ b/src/nvim/testdir/test_filter_cmd.vim @@ -0,0 +1,76 @@ +" Test the :filter command modifier + +func Test_filter() + edit Xdoesnotmatch + edit Xwillmatch + call assert_equal('"Xwillmatch"', substitute(execute('filter willma ls'), '[^"]*\(".*"\)[^"]*', '\1', '')) + bwipe Xdoesnotmatch + bwipe Xwillmatch + + new + call setline(1, ['foo1', 'foo2', 'foo3', 'foo4', 'foo5']) + call assert_equal("\nfoo2\nfoo4", execute('filter /foo[24]/ 1,$print')) + call assert_equal("\n 2 foo2\n 4 foo4", execute('filter /foo[24]/ 1,$number')) + call assert_equal("\nfoo2$\nfoo4$", execute('filter /foo[24]/ 1,$list')) + + call assert_equal("\nfoo1$\nfoo3$\nfoo5$", execute('filter! /foo[24]/ 1,$list')) + bwipe! + + command XTryThis echo 'this' + command XTryThat echo 'that' + command XDoThat echo 'that' + let lines = split(execute('filter XTry command'), "\n") + call assert_equal(3, len(lines)) + call assert_match("XTryThat", lines[1]) + call assert_match("XTryThis", lines[2]) + delcommand XTryThis + delcommand XTryThat + delcommand XDoThat + + map f1 the first key + map f2 the second key + map f3 not a key + let lines = split(execute('filter the map f'), "\n") + call assert_equal(2, len(lines)) + call assert_match("f2", lines[0]) + call assert_match("f1", lines[1]) + unmap f1 + unmap f2 + unmap f3 +endfunc + +func Test_filter_fails() + call assert_fails('filter', 'E471:') + call assert_fails('filter pat', 'E476:') + call assert_fails('filter /pat', 'E476:') + call assert_fails('filter /pat/', 'E476:') + call assert_fails('filter /pat/ asdf', 'E492:') + + call assert_fails('filter!', 'E471:') + call assert_fails('filter! pat', 'E476:') + call assert_fails('filter! /pat', 'E476:') + call assert_fails('filter! /pat/', 'E476:') + call assert_fails('filter! /pat/ asdf', 'E492:') +endfunc + +function s:complete_filter_cmd(filtcmd) + let keystroke = "\<TAB>\<C-R>=execute('let cmdline = getcmdline()')\<CR>\<C-C>" + let cmdline = '' + call feedkeys(':' . a:filtcmd . keystroke, 'ntx') + return cmdline +endfunction + +func Test_filter_cmd_completion() + " Do not complete pattern + call assert_equal("filter \t", s:complete_filter_cmd('filter ')) + call assert_equal("filter pat\t", s:complete_filter_cmd('filter pat')) + call assert_equal("filter /pat\t", s:complete_filter_cmd('filter /pat')) + call assert_equal("filter /pat/\t", s:complete_filter_cmd('filter /pat/')) + + " Complete after string pattern + call assert_equal('filter pat print', s:complete_filter_cmd('filter pat pri')) + + " Complete after regexp pattern + call assert_equal('filter /pat/ print', s:complete_filter_cmd('filter /pat/ pri')) + call assert_equal('filter #pat# print', s:complete_filter_cmd('filter #pat# pri')) +endfunc diff --git a/src/nvim/testdir/test_float_func.vim b/src/nvim/testdir/test_float_func.vim new file mode 100644 index 0000000000..5ea5192994 --- /dev/null +++ b/src/nvim/testdir/test_float_func.vim @@ -0,0 +1,332 @@ +" test float functions + +if !has('float') + finish +end + +func Test_abs() + call assert_equal('1.23', string(abs(1.23))) + call assert_equal('1.23', string(abs(-1.23))) + call assert_equal('0.0', string(abs(0.0))) + call assert_equal('0.0', string(abs(1.0/(1.0/0.0)))) + call assert_equal('0.0', string(abs(-1.0/(1.0/0.0)))) + call assert_equal("str2float('inf')", string(abs(1.0/0.0))) + call assert_equal("str2float('inf')", string(abs(-1.0/0.0))) + call assert_equal("str2float('nan')", string(abs(0.0/0.0))) + call assert_equal('12', string(abs('-12abc'))) + call assert_fails("call abs([])", 'E745:') + call assert_fails("call abs({})", 'E728:') + call assert_fails("call abs(function('string'))", 'E703:') +endfunc + +func Test_sqrt() + call assert_equal('0.0', string(sqrt(0.0))) + call assert_equal('1.414214', string(sqrt(2.0))) + call assert_equal("str2float('inf')", string(sqrt(1.0/0.0))) + call assert_equal("str2float('nan')", string(sqrt(-1.0))) + call assert_equal("str2float('nan')", string(sqrt(0.0/0.0))) + call assert_fails('call sqrt("")', 'E808:') +endfunc + +func Test_log() + call assert_equal('0.0', string(log(1.0))) + call assert_equal('-0.693147', string(log(0.5))) + call assert_equal("-str2float('inf')", string(log(0.0))) + call assert_equal("str2float('nan')", string(log(-1.0))) + call assert_equal("str2float('inf')", string(log(1.0/0.0))) + call assert_equal("str2float('nan')", string(log(0.0/0.0))) + call assert_fails('call log("")', 'E808:') +endfunc + +func Test_log10() + call assert_equal('0.0', string(log10(1.0))) + call assert_equal('2.0', string(log10(100.0))) + call assert_equal('2.079181', string(log10(120.0))) + call assert_equal("-str2float('inf')", string(log10(0.0))) + call assert_equal("str2float('nan')", string(log10(-1.0))) + call assert_equal("str2float('inf')", string(log10(1.0/0.0))) + call assert_equal("str2float('nan')", string(log10(0.0/0.0))) + call assert_fails('call log10("")', 'E808:') +endfunc + +func Test_exp() + call assert_equal('1.0', string(exp(0.0))) + call assert_equal('7.389056', string(exp(2.0))) + call assert_equal('0.367879', string(exp(-1.0))) + call assert_equal("str2float('inf')", string(exp(1.0/0.0))) + call assert_equal('0.0', string(exp(-1.0/0.0))) + call assert_equal("str2float('nan')", string(exp(0.0/0.0))) + call assert_fails('call exp("")', 'E808:') +endfunc + +func Test_sin() + call assert_equal('0.0', string(sin(0.0))) + call assert_equal('0.841471', string(sin(1.0))) + call assert_equal('-0.479426', string(sin(-0.5))) + call assert_equal("str2float('nan')", string(sin(0.0/0.0))) + call assert_equal("str2float('nan')", string(sin(1.0/0.0))) + call assert_equal('0.0', string(sin(1.0/(1.0/0.0)))) + call assert_equal('-0.0', string(sin(-1.0/(1.0/0.0)))) + call assert_fails('call sin("")', 'E808:') +endfunc + +func Test_asin() + call assert_equal('0.0', string(asin(0.0))) + call assert_equal('1.570796', string(asin(1.0))) + call assert_equal('-0.523599', string(asin(-0.5))) + call assert_equal("str2float('nan')", string(asin(1.1))) + call assert_equal("str2float('nan')", string(asin(1.0/0.0))) + call assert_equal("str2float('nan')", string(asin(0.0/0.0))) + call assert_fails('call asin("")', 'E808:') +endfunc + +func Test_sinh() + call assert_equal('0.0', string(sinh(0.0))) + call assert_equal('0.521095', string(sinh(0.5))) + call assert_equal('-1.026517', string(sinh(-0.9))) + call assert_equal("str2float('inf')", string(sinh(1.0/0.0))) + call assert_equal("-str2float('inf')", string(sinh(-1.0/0.0))) + call assert_equal("str2float('nan')", string(sinh(0.0/0.0))) + call assert_fails('call sinh("")', 'E808:') +endfunc + +func Test_cos() + call assert_equal('1.0', string(cos(0.0))) + call assert_equal('0.540302', string(cos(1.0))) + call assert_equal('0.877583', string(cos(-0.5))) + call assert_equal("str2float('nan')", string(cos(0.0/0.0))) + call assert_equal("str2float('nan')", string(cos(1.0/0.0))) + call assert_fails('call cos("")', 'E808:') +endfunc + +func Test_acos() + call assert_equal('1.570796', string(acos(0.0))) + call assert_equal('0.0', string(acos(1.0))) + call assert_equal('3.141593', string(acos(-1.0))) + call assert_equal('2.094395', string(acos(-0.5))) + call assert_equal("str2float('nan')", string(acos(1.1))) + call assert_equal("str2float('nan')", string(acos(1.0/0.0))) + call assert_equal("str2float('nan')", string(acos(0.0/0.0))) + call assert_fails('call acos("")', 'E808:') +endfunc + +func Test_cosh() + call assert_equal('1.0', string(cosh(0.0))) + call assert_equal('1.127626', string(cosh(0.5))) + call assert_equal("str2float('inf')", string(cosh(1.0/0.0))) + call assert_equal("str2float('inf')", string(cosh(-1.0/0.0))) + call assert_equal("str2float('nan')", string(cosh(0.0/0.0))) + call assert_fails('call cosh("")', 'E808:') +endfunc + +func Test_tan() + call assert_equal('0.0', string(tan(0.0))) + call assert_equal('0.546302', string(tan(0.5))) + call assert_equal('-0.546302', string(tan(-0.5))) + call assert_equal("str2float('nan')", string(tan(1.0/0.0))) + call assert_equal("str2float('nan')", string(cos(0.0/0.0))) + call assert_equal('0.0', string(tan(1.0/(1.0/0.0)))) + call assert_equal('-0.0', string(tan(-1.0/(1.0/0.0)))) + call assert_fails('call tan("")', 'E808:') +endfunc + +func Test_atan() + call assert_equal('0.0', string(atan(0.0))) + call assert_equal('0.463648', string(atan(0.5))) + call assert_equal('-0.785398', string(atan(-1.0))) + call assert_equal('1.570796', string(atan(1.0/0.0))) + call assert_equal('-1.570796', string(atan(-1.0/0.0))) + call assert_equal("str2float('nan')", string(atan(0.0/0.0))) + call assert_fails('call atan("")', 'E808:') +endfunc + +func Test_atan2() + call assert_equal('-2.356194', string(atan2(-1, -1))) + call assert_equal('2.356194', string(atan2(1, -1))) + call assert_equal('0.0', string(atan2(1.0, 1.0/0.0))) + call assert_equal('1.570796', string(atan2(1.0/0.0, 1.0))) + call assert_equal("str2float('nan')", string(atan2(0.0/0.0, 1.0))) + call assert_fails('call atan2("", -1)', 'E808:') + call assert_fails('call atan2(-1, "")', 'E808:') +endfunc + +func Test_tanh() + call assert_equal('0.0', string(tanh(0.0))) + call assert_equal('0.462117', string(tanh(0.5))) + call assert_equal('-0.761594', string(tanh(-1.0))) + call assert_equal('1.0', string(tanh(1.0/0.0))) + call assert_equal('-1.0', string(tanh(-1.0/0.0))) + call assert_equal("str2float('nan')", string(tanh(0.0/0.0))) + call assert_fails('call tanh("")', 'E808:') +endfunc + +func Test_fmod() + call assert_equal('0.13', string(fmod(12.33, 1.22))) + call assert_equal('-0.13', string(fmod(-12.33, 1.22))) + call assert_equal("str2float('nan')", string(fmod(1.0/0.0, 1.0))) + " On Windows we get "nan" instead of 1.0, accept both. + let res = string(fmod(1.0, 1.0/0.0)) + if res != "str2float('nan')" + call assert_equal('1.0', res) + endif + call assert_equal("str2float('nan')", string(fmod(1.0, 0.0))) + call assert_fails("call fmod('', 1.22)", 'E808:') + call assert_fails("call fmod(12.33, '')", 'E808:') +endfunc + +func Test_pow() + call assert_equal('1.0', string(pow(0.0, 0.0))) + call assert_equal('8.0', string(pow(2.0, 3.0))) + call assert_equal("str2float('nan')", string(pow(2.0, 0.0/0.0))) + call assert_equal("str2float('nan')", string(pow(0.0/0.0, 3.0))) + call assert_equal("str2float('nan')", string(pow(0.0/0.0, 3.0))) + call assert_equal("str2float('inf')", string(pow(2.0, 1.0/0.0))) + call assert_equal("str2float('inf')", string(pow(1.0/0.0, 3.0))) + call assert_fails("call pow('', 2.0)", 'E808:') + call assert_fails("call pow(2.0, '')", 'E808:') +endfunc + +func Test_str2float() + call assert_equal('1.0', string(str2float('1'))) + call assert_equal('1.0', string(str2float(' 1 '))) + call assert_equal('1.0', string(str2float(' 1.0 '))) + call assert_equal('1.23', string(str2float('1.23'))) + call assert_equal('1.23', string(str2float('1.23abc'))) + call assert_equal('1.0e40', string(str2float('1e40'))) + call assert_equal('-1.23', string(str2float('-1.23'))) + call assert_equal('1.23', string(str2float(' + 1.23 '))) + + call assert_equal('1.0', string(str2float('+1'))) + call assert_equal('1.0', string(str2float('+1'))) + call assert_equal('1.0', string(str2float(' +1 '))) + call assert_equal('1.0', string(str2float(' + 1 '))) + + call assert_equal('-1.0', string(str2float('-1'))) + call assert_equal('-1.0', string(str2float('-1'))) + call assert_equal('-1.0', string(str2float(' -1 '))) + call assert_equal('-1.0', string(str2float(' - 1 '))) + + call assert_equal('0.0', string(str2float('+0.0'))) + call assert_equal('-0.0', string(str2float('-0.0'))) + call assert_equal("str2float('inf')", string(str2float('1e1000'))) + call assert_equal("str2float('inf')", string(str2float('inf'))) + call assert_equal("-str2float('inf')", string(str2float('-inf'))) + call assert_equal("str2float('inf')", string(str2float('+inf'))) + call assert_equal("str2float('inf')", string(str2float('Inf'))) + call assert_equal("str2float('inf')", string(str2float(' +inf '))) + call assert_equal("str2float('nan')", string(str2float('nan'))) + call assert_equal("str2float('nan')", string(str2float('NaN'))) + call assert_equal("str2float('nan')", string(str2float(' nan '))) + + call assert_fails("call str2float(1.2)", 'E806:') + call assert_fails("call str2float([])", 'E730:') + call assert_fails("call str2float({})", 'E731:') + call assert_fails("call str2float(function('string'))", 'E729:') +endfunc + +func Test_float2nr() + call assert_equal(1, float2nr(1.234)) + call assert_equal(123, float2nr(1.234e2)) + call assert_equal(12, float2nr(123.4e-1)) + let max_number = 1/0 + let min_number = -max_number + call assert_equal(max_number/2+1, float2nr(pow(2, 62))) + call assert_equal(max_number, float2nr(pow(2, 63))) + call assert_equal(max_number, float2nr(pow(2, 64))) + call assert_equal(min_number/2-1, float2nr(-pow(2, 62))) + call assert_equal(min_number, float2nr(-pow(2, 63))) + call assert_equal(min_number, float2nr(-pow(2, 64))) +endfunc + +func Test_floor() + call assert_equal('2.0', string(floor(2.0))) + call assert_equal('2.0', string(floor(2.11))) + call assert_equal('2.0', string(floor(2.99))) + call assert_equal('-3.0', string(floor(-2.11))) + call assert_equal('-3.0', string(floor(-2.99))) + call assert_equal("str2float('nan')", string(floor(0.0/0.0))) + call assert_equal("str2float('inf')", string(floor(1.0/0.0))) + call assert_equal("-str2float('inf')", string(floor(-1.0/0.0))) + call assert_fails("call floor('')", 'E808:') +endfunc + +func Test_ceil() + call assert_equal('2.0', string(ceil(2.0))) + call assert_equal('3.0', string(ceil(2.11))) + call assert_equal('3.0', string(ceil(2.99))) + call assert_equal('-2.0', string(ceil(-2.11))) + call assert_equal('-2.0', string(ceil(-2.99))) + call assert_equal("str2float('nan')", string(ceil(0.0/0.0))) + call assert_equal("str2float('inf')", string(ceil(1.0/0.0))) + call assert_equal("-str2float('inf')", string(ceil(-1.0/0.0))) + call assert_fails("call ceil('')", 'E808:') +endfunc + +func Test_round() + call assert_equal('2.0', string(round(2.1))) + call assert_equal('3.0', string(round(2.5))) + call assert_equal('3.0', string(round(2.9))) + call assert_equal('-2.0', string(round(-2.1))) + call assert_equal('-3.0', string(round(-2.5))) + call assert_equal('-3.0', string(round(-2.9))) + call assert_equal("str2float('nan')", string(round(0.0/0.0))) + call assert_equal("str2float('inf')", string(round(1.0/0.0))) + call assert_equal("-str2float('inf')", string(round(-1.0/0.0))) + call assert_fails("call round('')", 'E808:') +endfunc + +func Test_trunc() + call assert_equal('2.0', string(trunc(2.1))) + call assert_equal('2.0', string(trunc(2.5))) + call assert_equal('2.0', string(trunc(2.9))) + call assert_equal('-2.0', string(trunc(-2.1))) + call assert_equal('-2.0', string(trunc(-2.5))) + call assert_equal('-2.0', string(trunc(-2.9))) + call assert_equal("str2float('nan')", string(trunc(0.0/0.0))) + call assert_equal("str2float('inf')", string(trunc(1.0/0.0))) + call assert_equal("-str2float('inf')", string(trunc(-1.0/0.0))) + call assert_fails("call trunc('')", 'E808:') +endfunc + +func Test_isnan() + throw 'skipped: Nvim does not support isnan()' + call assert_equal(0, isnan(1.0)) + call assert_equal(1, isnan(0.0/0.0)) + call assert_equal(0, isnan(1.0/0.0)) + call assert_equal(0, isnan('a')) + call assert_equal(0, isnan([])) + call assert_equal(0, isnan({})) +endfunc + +" This was converted from test65 +func Test_float_misc() + call assert_equal('123.456000', printf('%f', 123.456)) + call assert_equal('1.234560e+02', printf('%e', 123.456)) + call assert_equal('123.456', printf('%g', 123.456)) + " += + let v = 1.234 + let v += 6.543 + call assert_equal('7.777', printf('%g', v)) + let v = 1.234 + let v += 5 + call assert_equal('6.234', printf('%g', v)) + let v = 5 + let v += 3.333 + call assert_equal('8.333', string(v)) + " == + let v = 1.234 + call assert_true(v == 1.234) + call assert_false(v == 1.2341) + " add-subtract + call assert_equal('5.234', printf('%g', 4 + 1.234)) + call assert_equal('-6.766', printf('%g', 1.234 - 8)) + " mult-div + call assert_equal('4.936', printf('%g', 4 * 1.234)) + call assert_equal('0.003241', printf('%g', 4.0 / 1234)) + " dict + call assert_equal("{'x': 1.234, 'y': -2.0e20}", string({'x': 1.234, 'y': -2.0e20})) + " list + call assert_equal('[-123.4, 2.0e-20]', string([-123.4, 2.0e-20])) +endfunc + +" vim: shiftwidth=2 sts=2 expandtab diff --git a/src/nvim/testdir/test_fnameescape.vim b/src/nvim/testdir/test_fnameescape.vim new file mode 100644 index 0000000000..cdff0dfbd9 --- /dev/null +++ b/src/nvim/testdir/test_fnameescape.vim @@ -0,0 +1,21 @@ + +" Test if fnameescape is correct for special chars like ! +function! Test_fnameescape() + let fname = 'Xspa ce' + let status = v:false + try + exe "w! " . fnameescape(fname) + let status = v:true + endtry + call assert_true(status, "Space") + call delete(fname) + + let fname = 'Xemark!' + let status = v:false + try + exe "w! " . fnameescape(fname) + let status = v:true + endtry + call assert_true(status, "ExclamationMark") + call delete(fname) +endfunction diff --git a/src/nvim/testdir/test_fold.vim b/src/nvim/testdir/test_fold.vim index 7cb9faa75f..46c54e8614 100644 --- a/src/nvim/testdir/test_fold.vim +++ b/src/nvim/testdir/test_fold.vim @@ -1,5 +1,9 @@ " Test for folding +func! PrepIndent(arg) + return [a:arg] + repeat(["\t".a:arg], 5) +endfu + func! Test_address_fold() new call setline(1, ['int FuncName() {/*{{{*/', 1, 2, 3, 4, 5, '}/*}}}*/', @@ -96,6 +100,78 @@ func! Test_indent_fold2() bw! endfunc +func Test_manual_fold_with_filter() + if !executable('cat') + return + endif + for type in ['manual', 'marker'] + exe 'set foldmethod=' . type + new + call setline(1, range(1, 20)) + 4,$fold + %foldopen + 10,$fold + %foldopen + " This filter command should not have an effect + 1,8! cat + call feedkeys('5ggzdzMGdd', 'xt') + call assert_equal(['1', '2', '3', '4', '5', '6', '7', '8', '9'], getline(1, '$')) + + bwipe! + set foldmethod& + endfor +endfunc + +func! Test_indent_fold_with_read() + new + set foldmethod=indent + call setline(1, repeat(["\<Tab>a"], 4)) + for n in range(1, 4) + call assert_equal(1, foldlevel(n)) + endfor + + call writefile(["a", "", "\<Tab>a"], 'Xfile') + foldopen + 2read Xfile + %foldclose + call assert_equal(1, foldlevel(1)) + call assert_equal(2, foldclosedend(1)) + call assert_equal(0, foldlevel(3)) + call assert_equal(0, foldlevel(4)) + call assert_equal(1, foldlevel(5)) + call assert_equal(7, foldclosedend(5)) + + bwipe! + set foldmethod& + call delete('Xfile') +endfunc + +func Test_combining_folds_indent() + new + let one = "\<Tab>a" + let zero = 'a' + call setline(1, [one, one, zero, zero, zero, one, one, one]) + set foldmethod=indent + 3,5d + %foldclose + call assert_equal(5, foldclosedend(1)) + + set foldmethod& + bwipe! +endfunc + +func Test_combining_folds_marker() + new + call setline(1, ['{{{', '}}}', '', '', '', '{{{', '', '}}}']) + set foldmethod=marker + 3,5d + %foldclose + call assert_equal(2, foldclosedend(1)) + + set foldmethod& + bwipe! +endfunc + func Test_folds_marker_in_comment() new call setline(1, ['" foo', 'bar', 'baz']) @@ -112,19 +188,175 @@ func Test_folds_marker_in_comment() bwipe! endfunc -func Test_manual_fold_with_filter() - if !executable('cat') - return +func s:TestFoldExpr(lnum) + let thisline = getline(a:lnum) + if thisline == 'a' + return 1 + elseif thisline == 'b' + return 0 + elseif thisline == 'c' + return '<1' + elseif thisline == 'd' + return '>1' endif + return 0 +endfunction + +func Test_update_folds_expr_read() new - call setline(1, range(1, 20)) - 4,$fold + call setline(1, ['a', 'a', 'a', 'a', 'a', 'a']) + set foldmethod=expr + set foldexpr=s:TestFoldExpr(v:lnum) + 2 + foldopen + call writefile(['b', 'b', 'a', 'a', 'd', 'a', 'a', 'c'], 'Xfile') + read Xfile + %foldclose + call assert_equal(2, foldclosedend(1)) + call assert_equal(0, foldlevel(3)) + call assert_equal(0, foldlevel(4)) + call assert_equal(6, foldclosedend(5)) + call assert_equal(10, foldclosedend(7)) + call assert_equal(14, foldclosedend(11)) + + call delete('Xfile') + bwipe! + set foldmethod& foldexpr& +endfunc + +func! Test_move_folds_around_manual() + new + let input = PrepIndent("a") + PrepIndent("b") + PrepIndent("c") + call setline(1, PrepIndent("a") + PrepIndent("b") + PrepIndent("c")) + let folds=[-1, 2, 2, 2, 2, 2, -1, 8, 8, 8, 8, 8, -1, 14, 14, 14, 14, 14] + " all folds closed + set foldenable foldlevel=0 fdm=indent + " needs a forced redraw + redraw! + set fdm=manual + call assert_equal(folds, map(range(1, line('$')), 'foldclosed(v:val)')) + call assert_equal(input, getline(1, '$')) + 7,12m0 + call assert_equal(PrepIndent("b") + PrepIndent("a") + PrepIndent("c"), getline(1, '$')) + call assert_equal(folds, map(range(1, line('$')), 'foldclosed(v:val)')) + 10,12m0 + call assert_equal(PrepIndent("a")[1:] + PrepIndent("b") + ["a"] + PrepIndent("c"), getline(1, '$')) + call assert_equal([1, 1, 1, 1, 1, -1, 7, 7, 7, 7, 7, -1, -1, 14, 14, 14, 14, 14], map(range(1, line('$')), 'foldclosed(v:val)')) + " moving should not close the folds + %d + call setline(1, PrepIndent("a") + PrepIndent("b") + PrepIndent("c")) + set fdm=indent + redraw! + set fdm=manual + call cursor(2, 1) %foldopen - 10,$fold + 7,12m0 + let folds=repeat([-1], 18) + call assert_equal(PrepIndent("b") + PrepIndent("a") + PrepIndent("c"), getline(1, '$')) + call assert_equal(folds, map(range(1, line('$')), 'foldclosed(v:val)')) + norm! zM + " folds are not corrupted and all have been closed + call assert_equal([-1, 2, 2, 2, 2, 2, -1, 8, 8, 8, 8, 8, -1, 14, 14, 14, 14, 14], map(range(1, line('$')), 'foldclosed(v:val)')) + %d + call setline(1, ["a", "\tb", "\tc", "\td", "\te"]) + set fdm=indent + redraw! + set fdm=manual %foldopen - " This filter command should not have an effect - 1,8! cat - call feedkeys('5ggzdzMGdd', 'xt') - call assert_equal(['1', '2', '3', '4', '5', '6', '7', '8', '9'], getline(1, '$')) - bwipe! + 3m4 + %foldclose + call assert_equal(["a", "\tb", "\td", "\tc", "\te"], getline(1, '$')) + call assert_equal([-1, 5, 5, 5, 5], map(range(1, line('$')), 'foldclosedend(v:val)')) + %d + call setline(1, ["a", "\tb", "\tc", "\td", "\te", "z", "\ty", "\tx", "\tw", "\tv"]) + set fdm=indent foldlevel=0 + set fdm=manual + %foldopen + 3m1 + %foldclose + call assert_equal(["a", "\tc", "\tb", "\td", "\te", "z", "\ty", "\tx", "\tw", "\tv"], getline(1, '$')) + call assert_equal(0, foldlevel(2)) + call assert_equal(5, foldclosedend(3)) + call assert_equal([-1, -1, 3, 3, 3, -1, 7, 7, 7, 7], map(range(1, line('$')), 'foldclosed(v:val)')) + 2,6m$ + %foldclose + call assert_equal(5, foldclosedend(2)) + call assert_equal(0, foldlevel(6)) + call assert_equal(9, foldclosedend(7)) + call assert_equal([-1, 2, 2, 2, 2, -1, 7, 7, 7, -1], map(range(1, line('$')), 'foldclosed(v:val)')) + %d + " Ensure moving around the edges still works. + call setline(1, PrepIndent("a") + repeat(["a"], 3) + ["\ta"]) + set fdm=indent foldlevel=0 + set fdm=manual + %foldopen + 6m$ + " The first fold has been truncated to the 5'th line. + " Second fold has been moved up because the moved line is now below it. + call assert_equal([0, 1, 1, 1, 1, 0, 0, 0, 1, 0], map(range(1, line('$')), 'foldlevel(v:val)')) + bw! +endfunc + +func! Test_move_folds_around_indent() + new + let input = PrepIndent("a") + PrepIndent("b") + PrepIndent("c") + call setline(1, PrepIndent("a") + PrepIndent("b") + PrepIndent("c")) + let folds=[-1, 2, 2, 2, 2, 2, -1, 8, 8, 8, 8, 8, -1, 14, 14, 14, 14, 14] + " all folds closed + set fdm=indent + call assert_equal(folds, map(range(1, line('$')), 'foldclosed(v:val)')) + call assert_equal(input, getline(1, '$')) + 7,12m0 + call assert_equal(PrepIndent("b") + PrepIndent("a") + PrepIndent("c"), getline(1, '$')) + call assert_equal(folds, map(range(1, line('$')), 'foldclosed(v:val)')) + 10,12m0 + call assert_equal(PrepIndent("a")[1:] + PrepIndent("b") + ["a"] + PrepIndent("c"), getline(1, '$')) + call assert_equal([1, 1, 1, 1, 1, -1, 7, 7, 7, 7, 7, -1, -1, 14, 14, 14, 14, 14], map(range(1, line('$')), 'foldclosed(v:val)')) + " moving should not close the folds + %d + call setline(1, PrepIndent("a") + PrepIndent("b") + PrepIndent("c")) + set fdm=indent + call cursor(2, 1) + %foldopen + 7,12m0 + let folds=repeat([-1], 18) + call assert_equal(PrepIndent("b") + PrepIndent("a") + PrepIndent("c"), getline(1, '$')) + call assert_equal(folds, map(range(1, line('$')), 'foldclosed(v:val)')) + norm! zM + " folds are not corrupted and all have been closed + call assert_equal([-1, 2, 2, 2, 2, 2, -1, 8, 8, 8, 8, 8, -1, 14, 14, 14, 14, 14], map(range(1, line('$')), 'foldclosed(v:val)')) + %d + call setline(1, ["a", "\tb", "\tc", "\td", "\te"]) + set fdm=indent + %foldopen + 3m4 + %foldclose + call assert_equal(["a", "\tb", "\td", "\tc", "\te"], getline(1, '$')) + call assert_equal([-1, 5, 5, 5, 5], map(range(1, line('$')), 'foldclosedend(v:val)')) + %d + call setline(1, ["a", "\tb", "\tc", "\td", "\te", "z", "\ty", "\tx", "\tw", "\tv"]) + set fdm=indent foldlevel=0 + %foldopen + 3m1 + %foldclose + call assert_equal(["a", "\tc", "\tb", "\td", "\te", "z", "\ty", "\tx", "\tw", "\tv"], getline(1, '$')) + call assert_equal(1, foldlevel(2)) + call assert_equal(5, foldclosedend(3)) + call assert_equal([-1, 2, 2, 2, 2, -1, 7, 7, 7, 7], map(range(1, line('$')), 'foldclosed(v:val)')) + 2,6m$ + %foldclose + call assert_equal(9, foldclosedend(2)) + call assert_equal(1, foldlevel(6)) + call assert_equal(9, foldclosedend(7)) + call assert_equal([-1, 2, 2, 2, 2, 2, 2, 2, 2, -1], map(range(1, line('$')), 'foldclosed(v:val)')) + " Ensure moving around the edges still works. + %d + call setline(1, PrepIndent("a") + repeat(["a"], 3) + ["\ta"]) + set fdm=indent foldlevel=0 + %foldopen + 6m$ + " The first fold has been truncated to the 5'th line. + " Second fold has been moved up because the moved line is now below it. + call assert_equal([0, 1, 1, 1, 1, 0, 0, 0, 1, 1], map(range(1, line('$')), 'foldlevel(v:val)')) + bw! endfunc diff --git a/src/nvim/testdir/test_functions.vim b/src/nvim/testdir/test_functions.vim new file mode 100644 index 0000000000..0ce034b63e --- /dev/null +++ b/src/nvim/testdir/test_functions.vim @@ -0,0 +1,313 @@ +" Tests for various functions. + +func Test_str2nr() + call assert_equal(0, str2nr('')) + call assert_equal(1, str2nr('1')) + call assert_equal(1, str2nr(' 1 ')) + + call assert_equal(1, str2nr('+1')) + call assert_equal(1, str2nr('+ 1')) + call assert_equal(1, str2nr(' + 1 ')) + + call assert_equal(-1, str2nr('-1')) + call assert_equal(-1, str2nr('- 1')) + call assert_equal(-1, str2nr(' - 1 ')) + + call assert_equal(123456789, str2nr('123456789')) + call assert_equal(-123456789, str2nr('-123456789')) +endfunc + +func Test_setbufvar_options() + " This tests that aucmd_prepbuf() and aucmd_restbuf() properly restore the + " window layout. + call assert_equal(1, winnr('$')) + split dummy_preview + resize 2 + set winfixheight winfixwidth + let prev_id = win_getid() + + wincmd j + let wh = winheight('.') + let dummy_buf = bufnr('dummy_buf1', v:true) + call setbufvar(dummy_buf, '&buftype', 'nofile') + execute 'belowright vertical split #' . dummy_buf + call assert_equal(wh, winheight('.')) + let dum1_id = win_getid() + + wincmd h + let wh = winheight('.') + let dummy_buf = bufnr('dummy_buf2', v:true) + call setbufvar(dummy_buf, '&buftype', 'nofile') + execute 'belowright vertical split #' . dummy_buf + call assert_equal(wh, winheight('.')) + + bwipe! + call win_gotoid(prev_id) + bwipe! + call win_gotoid(dum1_id) + bwipe! +endfunc + +func Test_tolower() + call assert_equal("", tolower("")) + + " Test with all printable ASCII characters. + call assert_equal(' !"#$%&''()*+,-./0123456789:;<=>?@abcdefghijklmnopqrstuvwxyz[\]^_`abcdefghijklmnopqrstuvwxyz{|}~', + \ tolower(' !"#$%&''()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~')) + + if !has('multi_byte') + return + endif + + " Test with a few uppercase diacritics. + call assert_equal("aàáâãäåāăąǎǟǡả", tolower("AÀÁÂÃÄÅĀĂĄǍǞǠẢ")) + call assert_equal("bḃḇ", tolower("BḂḆ")) + call assert_equal("cçćĉċč", tolower("CÇĆĈĊČ")) + call assert_equal("dďđḋḏḑ", tolower("DĎĐḊḎḐ")) + call assert_equal("eèéêëēĕėęěẻẽ", tolower("EÈÉÊËĒĔĖĘĚẺẼ")) + call assert_equal("fḟ ", tolower("FḞ ")) + call assert_equal("gĝğġģǥǧǵḡ", tolower("GĜĞĠĢǤǦǴḠ")) + call assert_equal("hĥħḣḧḩ", tolower("HĤĦḢḦḨ")) + call assert_equal("iìíîïĩīĭįiǐỉ", tolower("IÌÍÎÏĨĪĬĮİǏỈ")) + call assert_equal("jĵ", tolower("JĴ")) + call assert_equal("kķǩḱḵ", tolower("KĶǨḰḴ")) + call assert_equal("lĺļľŀłḻ", tolower("LĹĻĽĿŁḺ")) + call assert_equal("mḿṁ", tolower("MḾṀ")) + call assert_equal("nñńņňṅṉ", tolower("NÑŃŅŇṄṈ")) + call assert_equal("oòóôõöøōŏőơǒǫǭỏ", tolower("OÒÓÔÕÖØŌŎŐƠǑǪǬỎ")) + call assert_equal("pṕṗ", tolower("PṔṖ")) + call assert_equal("q", tolower("Q")) + call assert_equal("rŕŗřṙṟ", tolower("RŔŖŘṘṞ")) + call assert_equal("sśŝşšṡ", tolower("SŚŜŞŠṠ")) + call assert_equal("tţťŧṫṯ", tolower("TŢŤŦṪṮ")) + call assert_equal("uùúûüũūŭůűųưǔủ", tolower("UÙÚÛÜŨŪŬŮŰŲƯǓỦ")) + call assert_equal("vṽ", tolower("VṼ")) + call assert_equal("wŵẁẃẅẇ", tolower("WŴẀẂẄẆ")) + call assert_equal("xẋẍ", tolower("XẊẌ")) + call assert_equal("yýŷÿẏỳỷỹ", tolower("YÝŶŸẎỲỶỸ")) + call assert_equal("zźżžƶẑẕ", tolower("ZŹŻŽƵẐẔ")) + + " Test with a few lowercase diacritics, which should remain unchanged. + call assert_equal("aàáâãäåāăąǎǟǡả", tolower("aàáâãäåāăąǎǟǡả")) + call assert_equal("bḃḇ", tolower("bḃḇ")) + call assert_equal("cçćĉċč", tolower("cçćĉċč")) + call assert_equal("dďđḋḏḑ", tolower("dďđḋḏḑ")) + call assert_equal("eèéêëēĕėęěẻẽ", tolower("eèéêëēĕėęěẻẽ")) + call assert_equal("fḟ", tolower("fḟ")) + call assert_equal("gĝğġģǥǧǵḡ", tolower("gĝğġģǥǧǵḡ")) + call assert_equal("hĥħḣḧḩẖ", tolower("hĥħḣḧḩẖ")) + call assert_equal("iìíîïĩīĭįǐỉ", tolower("iìíîïĩīĭįǐỉ")) + call assert_equal("jĵǰ", tolower("jĵǰ")) + call assert_equal("kķǩḱḵ", tolower("kķǩḱḵ")) + call assert_equal("lĺļľŀłḻ", tolower("lĺļľŀłḻ")) + call assert_equal("mḿṁ ", tolower("mḿṁ ")) + call assert_equal("nñńņňʼnṅṉ", tolower("nñńņňʼnṅṉ")) + call assert_equal("oòóôõöøōŏőơǒǫǭỏ", tolower("oòóôõöøōŏőơǒǫǭỏ")) + call assert_equal("pṕṗ", tolower("pṕṗ")) + call assert_equal("q", tolower("q")) + call assert_equal("rŕŗřṙṟ", tolower("rŕŗřṙṟ")) + call assert_equal("sśŝşšṡ", tolower("sśŝşšṡ")) + call assert_equal("tţťŧṫṯẗ", tolower("tţťŧṫṯẗ")) + call assert_equal("uùúûüũūŭůűųưǔủ", tolower("uùúûüũūŭůűųưǔủ")) + call assert_equal("vṽ", tolower("vṽ")) + call assert_equal("wŵẁẃẅẇẘ", tolower("wŵẁẃẅẇẘ")) + call assert_equal("ẋẍ", tolower("ẋẍ")) + call assert_equal("yýÿŷẏẙỳỷỹ", tolower("yýÿŷẏẙỳỷỹ")) + call assert_equal("zźżžƶẑẕ", tolower("zźżžƶẑẕ")) + + " According to https://twitter.com/jifa/status/625776454479970304 + " Ⱥ (U+023A) and Ⱦ (U+023E) are the *only* code points to increase + " in length (2 to 3 bytes) when lowercased. So let's test them. + call assert_equal("ⱥ ⱦ", tolower("Ⱥ Ⱦ")) +endfunc + +func Test_toupper() + call assert_equal("", toupper("")) + + " Test with all printable ASCII characters. + call assert_equal(' !"#$%&''()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`ABCDEFGHIJKLMNOPQRSTUVWXYZ{|}~', + \ toupper(' !"#$%&''()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~')) + + if !has('multi_byte') + return + endif + + " Test with a few lowercase diacritics. + call assert_equal("AÀÁÂÃÄÅĀĂĄǍǞǠẢ", toupper("aàáâãäåāăąǎǟǡả")) + call assert_equal("BḂḆ", toupper("bḃḇ")) + call assert_equal("CÇĆĈĊČ", toupper("cçćĉċč")) + call assert_equal("DĎĐḊḎḐ", toupper("dďđḋḏḑ")) + call assert_equal("EÈÉÊËĒĔĖĘĚẺẼ", toupper("eèéêëēĕėęěẻẽ")) + call assert_equal("FḞ", toupper("fḟ")) + call assert_equal("GĜĞĠĢǤǦǴḠ", toupper("gĝğġģǥǧǵḡ")) + call assert_equal("HĤĦḢḦḨẖ", toupper("hĥħḣḧḩẖ")) + call assert_equal("IÌÍÎÏĨĪĬĮǏỈ", toupper("iìíîïĩīĭįǐỉ")) + call assert_equal("JĴǰ", toupper("jĵǰ")) + call assert_equal("KĶǨḰḴ", toupper("kķǩḱḵ")) + call assert_equal("LĹĻĽĿŁḺ", toupper("lĺļľŀłḻ")) + call assert_equal("MḾṀ ", toupper("mḿṁ ")) + call assert_equal("NÑŃŅŇʼnṄṈ", toupper("nñńņňʼnṅṉ")) + call assert_equal("OÒÓÔÕÖØŌŎŐƠǑǪǬỎ", toupper("oòóôõöøōŏőơǒǫǭỏ")) + call assert_equal("PṔṖ", toupper("pṕṗ")) + call assert_equal("Q", toupper("q")) + call assert_equal("RŔŖŘṘṞ", toupper("rŕŗřṙṟ")) + call assert_equal("SŚŜŞŠṠ", toupper("sśŝşšṡ")) + call assert_equal("TŢŤŦṪṮẗ", toupper("tţťŧṫṯẗ")) + call assert_equal("UÙÚÛÜŨŪŬŮŰŲƯǓỦ", toupper("uùúûüũūŭůűųưǔủ")) + call assert_equal("VṼ", toupper("vṽ")) + call assert_equal("WŴẀẂẄẆẘ", toupper("wŵẁẃẅẇẘ")) + call assert_equal("ẊẌ", toupper("ẋẍ")) + call assert_equal("YÝŸŶẎẙỲỶỸ", toupper("yýÿŷẏẙỳỷỹ")) + call assert_equal("ZŹŻŽƵẐẔ", toupper("zźżžƶẑẕ")) + + " Test that uppercase diacritics, which should remain unchanged. + call assert_equal("AÀÁÂÃÄÅĀĂĄǍǞǠẢ", toupper("AÀÁÂÃÄÅĀĂĄǍǞǠẢ")) + call assert_equal("BḂḆ", toupper("BḂḆ")) + call assert_equal("CÇĆĈĊČ", toupper("CÇĆĈĊČ")) + call assert_equal("DĎĐḊḎḐ", toupper("DĎĐḊḎḐ")) + call assert_equal("EÈÉÊËĒĔĖĘĚẺẼ", toupper("EÈÉÊËĒĔĖĘĚẺẼ")) + call assert_equal("FḞ ", toupper("FḞ ")) + call assert_equal("GĜĞĠĢǤǦǴḠ", toupper("GĜĞĠĢǤǦǴḠ")) + call assert_equal("HĤĦḢḦḨ", toupper("HĤĦḢḦḨ")) + call assert_equal("IÌÍÎÏĨĪĬĮİǏỈ", toupper("IÌÍÎÏĨĪĬĮİǏỈ")) + call assert_equal("JĴ", toupper("JĴ")) + call assert_equal("KĶǨḰḴ", toupper("KĶǨḰḴ")) + call assert_equal("LĹĻĽĿŁḺ", toupper("LĹĻĽĿŁḺ")) + call assert_equal("MḾṀ", toupper("MḾṀ")) + call assert_equal("NÑŃŅŇṄṈ", toupper("NÑŃŅŇṄṈ")) + call assert_equal("OÒÓÔÕÖØŌŎŐƠǑǪǬỎ", toupper("OÒÓÔÕÖØŌŎŐƠǑǪǬỎ")) + call assert_equal("PṔṖ", toupper("PṔṖ")) + call assert_equal("Q", toupper("Q")) + call assert_equal("RŔŖŘṘṞ", toupper("RŔŖŘṘṞ")) + call assert_equal("SŚŜŞŠṠ", toupper("SŚŜŞŠṠ")) + call assert_equal("TŢŤŦṪṮ", toupper("TŢŤŦṪṮ")) + call assert_equal("UÙÚÛÜŨŪŬŮŰŲƯǓỦ", toupper("UÙÚÛÜŨŪŬŮŰŲƯǓỦ")) + call assert_equal("VṼ", toupper("VṼ")) + call assert_equal("WŴẀẂẄẆ", toupper("WŴẀẂẄẆ")) + call assert_equal("XẊẌ", toupper("XẊẌ")) + call assert_equal("YÝŶŸẎỲỶỸ", toupper("YÝŶŸẎỲỶỸ")) + call assert_equal("ZŹŻŽƵẐẔ", toupper("ZŹŻŽƵẐẔ")) + + call assert_equal("ⱥ ⱦ", tolower("Ⱥ Ⱦ")) +endfunc + +" Tests for the mode() function +let current_modes = '' +func! Save_mode() + let g:current_modes = mode(0) . '-' . mode(1) + return '' +endfunc + +func! Test_mode() + new + call append(0, ["Blue Ball Black", "Brown Band Bowl", ""]) + + inoremap <F2> <C-R>=Save_mode()<CR> + + normal! 3G + exe "normal i\<F2>\<Esc>" + call assert_equal('i-i', g:current_modes) + " i_CTRL-P: Multiple matches + exe "normal i\<C-G>uBa\<C-P>\<F2>\<Esc>u" + call assert_equal('i-ic', g:current_modes) + " i_CTRL-P: Single match + exe "normal iBro\<C-P>\<F2>\<Esc>u" + call assert_equal('i-ic', g:current_modes) + " i_CTRL-X + exe "normal iBa\<C-X>\<F2>\<Esc>u" + call assert_equal('i-ix', g:current_modes) + " i_CTRL-X CTRL-P: Multiple matches + exe "normal iBa\<C-X>\<C-P>\<F2>\<Esc>u" + call assert_equal('i-ic', g:current_modes) + " i_CTRL-X CTRL-P: Single match + exe "normal iBro\<C-X>\<C-P>\<F2>\<Esc>u" + call assert_equal('i-ic', g:current_modes) + " i_CTRL-X CTRL-P + CTRL-P: Single match + exe "normal iBro\<C-X>\<C-P>\<C-P>\<F2>\<Esc>u" + call assert_equal('i-ic', g:current_modes) + " i_CTRL-X CTRL-L: Multiple matches + exe "normal i\<C-X>\<C-L>\<F2>\<Esc>u" + call assert_equal('i-ic', g:current_modes) + " i_CTRL-X CTRL-L: Single match + exe "normal iBlu\<C-X>\<C-L>\<F2>\<Esc>u" + call assert_equal('i-ic', g:current_modes) + " i_CTRL-P: No match + exe "normal iCom\<C-P>\<F2>\<Esc>u" + call assert_equal('i-ic', g:current_modes) + " i_CTRL-X CTRL-P: No match + exe "normal iCom\<C-X>\<C-P>\<F2>\<Esc>u" + call assert_equal('i-ic', g:current_modes) + " i_CTRL-X CTRL-L: No match + exe "normal iabc\<C-X>\<C-L>\<F2>\<Esc>u" + call assert_equal('i-ic', g:current_modes) + + " R_CTRL-P: Multiple matches + exe "normal RBa\<C-P>\<F2>\<Esc>u" + call assert_equal('R-Rc', g:current_modes) + " R_CTRL-P: Single match + exe "normal RBro\<C-P>\<F2>\<Esc>u" + call assert_equal('R-Rc', g:current_modes) + " R_CTRL-X + exe "normal RBa\<C-X>\<F2>\<Esc>u" + call assert_equal('R-Rx', g:current_modes) + " R_CTRL-X CTRL-P: Multiple matches + exe "normal RBa\<C-X>\<C-P>\<F2>\<Esc>u" + call assert_equal('R-Rc', g:current_modes) + " R_CTRL-X CTRL-P: Single match + exe "normal RBro\<C-X>\<C-P>\<F2>\<Esc>u" + call assert_equal('R-Rc', g:current_modes) + " R_CTRL-X CTRL-P + CTRL-P: Single match + exe "normal RBro\<C-X>\<C-P>\<C-P>\<F2>\<Esc>u" + call assert_equal('R-Rc', g:current_modes) + " R_CTRL-X CTRL-L: Multiple matches + exe "normal R\<C-X>\<C-L>\<F2>\<Esc>u" + call assert_equal('R-Rc', g:current_modes) + " R_CTRL-X CTRL-L: Single match + exe "normal RBlu\<C-X>\<C-L>\<F2>\<Esc>u" + call assert_equal('R-Rc', g:current_modes) + " R_CTRL-P: No match + exe "normal RCom\<C-P>\<F2>\<Esc>u" + call assert_equal('R-Rc', g:current_modes) + " R_CTRL-X CTRL-P: No match + exe "normal RCom\<C-X>\<C-P>\<F2>\<Esc>u" + call assert_equal('R-Rc', g:current_modes) + " R_CTRL-X CTRL-L: No match + exe "normal Rabc\<C-X>\<C-L>\<F2>\<Esc>u" + call assert_equal('R-Rc', g:current_modes) + + call assert_equal('n', mode(0)) + call assert_equal('n', mode(1)) + + " How to test operator-pending mode? + + call feedkeys("v", 'xt') + call assert_equal('v', mode()) + call assert_equal('v', mode(1)) + call feedkeys("\<Esc>V", 'xt') + call assert_equal('V', mode()) + call assert_equal('V', mode(1)) + call feedkeys("\<Esc>\<C-V>", 'xt') + call assert_equal("\<C-V>", mode()) + call assert_equal("\<C-V>", mode(1)) + call feedkeys("\<Esc>", 'xt') + + call feedkeys("gh", 'xt') + call assert_equal('s', mode()) + call assert_equal('s', mode(1)) + call feedkeys("\<Esc>gH", 'xt') + call assert_equal('S', mode()) + call assert_equal('S', mode(1)) + call feedkeys("\<Esc>g\<C-H>", 'xt') + call assert_equal("\<C-S>", mode()) + call assert_equal("\<C-S>", mode(1)) + call feedkeys("\<Esc>", 'xt') + + call feedkeys(":echo \<C-R>=Save_mode()\<C-U>\<CR>", 'xt') + call assert_equal('c-c', g:current_modes) + call feedkeys("gQecho \<C-R>=Save_mode()\<CR>\<CR>vi\<CR>", 'xt') + call assert_equal('c-cv', g:current_modes) + " How to test Ex mode? + + bwipe! + iunmap <F2> +endfunc diff --git a/src/nvim/testdir/test_ga.vim b/src/nvim/testdir/test_ga.vim new file mode 100644 index 0000000000..f9357ddc87 --- /dev/null +++ b/src/nvim/testdir/test_ga.vim @@ -0,0 +1,37 @@ +" Test ga normal command, and :ascii Ex command. +func Do_ga(c) + call setline(1, a:c) + let l:a = execute("norm 1goga") + let l:b = execute("ascii") + call assert_equal(l:a, l:b) + return l:a +endfunc + +func Test_ga_command() + new + set display=uhex + call assert_equal("\nNUL", Do_ga('')) + call assert_equal("\n<<01>> 1, Hex 01, Octal 001", Do_ga("\x01")) + call assert_equal("\n<<09>> 9, Hex 09, Octal 011", Do_ga("\t")) + + set display= + call assert_equal("\nNUL", Do_ga('')) + call assert_equal("\n<^A> 1, Hex 01, Octal 001", Do_ga("\x01")) + call assert_equal("\n<^I> 9, Hex 09, Octal 011", Do_ga("\t")) + + call assert_equal("\n<e> 101, Hex 65, Octal 145", Do_ga('e')) + + if !has('multi_byte') + return + endif + + " Test a few multi-bytes characters. + call assert_equal("\n<é> 233, Hex 00e9, Octal 351", Do_ga('é')) + call assert_equal("\n<ẻ> 7867, Hex 1ebb, Octal 17273", Do_ga('ẻ')) + + " Test with combining characters. + call assert_equal("\n<e> 101, Hex 65, Octal 145 < ́> 769, Hex 0301, Octal 1401", Do_ga("e\u0301")) + call assert_equal("\n<e> 101, Hex 65, Octal 145 < ́> 769, Hex 0301, Octal 1401 < ̱> 817, Hex 0331, Octal 1461", Do_ga("e\u0301\u0331")) + call assert_equal("\n<e> 101, Hex 65, Octal 145 < ́> 769, Hex 0301, Octal 1401 < ̱> 817, Hex 0331, Octal 1461 < ̸> 824, Hex 0338, Octal 1470", Do_ga("e\u0301\u0331\u0338")) + bwipe! +endfunc diff --git a/src/nvim/testdir/test_gf.vim b/src/nvim/testdir/test_gf.vim new file mode 100644 index 0000000000..c4aa6f9218 --- /dev/null +++ b/src/nvim/testdir/test_gf.vim @@ -0,0 +1,33 @@ + +" This is a test if a URL is recognized by "gf", with the cursor before and +" after the "://". Also test ":\\". +function! Test_gf_url() + enew! + call append(0, [ + \ "first test for URL://machine.name/tmp/vimtest2a and other text", + \ "second test for URL://machine.name/tmp/vimtest2b. And other text", + \ "third test for URL:\\\\machine.name\\vimtest2c and other text", + \ "fourth test for URL:\\\\machine.name\\tmp\\vimtest2d, and other text" + \ ]) + call cursor(1,1) + call search("^first") + call search("tmp") + call assert_equal("URL://machine.name/tmp/vimtest2a", expand("<cfile>")) + call search("^second") + call search("URL") + call assert_equal("URL://machine.name/tmp/vimtest2b", expand("<cfile>")) + if has("ebcdic") + set isf=@,240-249,/,.,-,_,+,,,$,:,~,\ + else + set isf=@,48-57,/,.,-,_,+,,,$,:,~,\ + endif + call search("^third") + call search("name") + call assert_equal("URL:\\\\machine.name\\vimtest2c", expand("<cfile>")) + call search("^fourth") + call search("URL") + call assert_equal("URL:\\\\machine.name\\tmp\\vimtest2d", expand("<cfile>")) + + set isf&vim + enew! +endfunction diff --git a/src/nvim/testdir/test_goto.vim b/src/nvim/testdir/test_goto.vim index b6ac5720c3..2573401707 100644 --- a/src/nvim/testdir/test_goto.vim +++ b/src/nvim/testdir/test_goto.vim @@ -1,22 +1,277 @@ " Test commands that jump somewhere. -func Test_geeDEE() +" Create a new buffer using "lines" and place the cursor on the word after the +" first occurrence of return and invoke "cmd". The cursor should now be +" positioned at the given line and col. +func XTest_goto_decl(cmd, lines, line, col) new - call setline(1, ["Filename x;", "", "int Filename", "int func() {", "Filename y;"]) - /y;/ - normal gD - call assert_equal(1, line('.')) + call setline(1, a:lines) + /return/ + normal! W + execute 'norm! ' . a:cmd + call assert_equal(a:line, line('.')) + call assert_equal(a:col, col('.')) quit! endfunc -func Test_gee_dee() - new - call setline(1, ["int x;", "", "int func(int x)", "{", " return x;", "}"]) - /return/ - normal $hgd - call assert_equal(3, line('.')) - call assert_equal(14, col('.')) - quit! +func Test_gD() + let lines = [ + \ 'int x;', + \ '', + \ 'int func(void)', + \ '{', + \ ' return x;', + \ '}', + \ ] + 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;', + \ ] + call XTest_goto_decl('gD', lines, 1, 10) +endfunc + +func Test_gD_comment() + let lines = [ + \ '/* int x; */', + \ 'int x;', + \ '', + \ 'int func(void)', + \ '{', + \ ' return x;', + \ '}', + \ ] + 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;', + \ '}', + \ ] + 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;', + \ '}', + \ ] + 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;', + \ '}', + \ ] + 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;', + \ '}', + \ ] + call XTest_goto_decl('gD', lines, 2, 5) +endfunc + +func Test_gd() + let lines = [ + \ 'int x;', + \ '', + \ 'int func(int x)', + \ '{', + \ ' return x;', + \ '}', + \ ] + 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;', + \ '}', + \ ] + call XTest_goto_decl('gd', lines, 3, 10) +endfunc + +func Test_gd_kr_style() + let lines = [ + \ 'int func(x)', + \ ' int x;', + \ '{', + \ ' return x;', + \ '}', + \ ] + 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', + \ ] + call XTest_goto_decl('gd', lines, 1, 11) +endfunc + +func Test_gd_comment() + let lines = [ + \ 'int func(void)', + \ '{', + \ ' /* int x; */', + \ ' int x;', + \ ' return x;', + \ '}', + \] + 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;', + \ '}', + \] + 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;', + \ '}', + \] + 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;', + \ '}', + \ ] + 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;', + \ '}', + \ ] + 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;', + \ '}', + \ ] + 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;', + \ '}', + \ ] + 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;', + \ '}', + \ ] + 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;', + \ '}', + \ ] + call XTest_goto_decl('gd', lines, 4, 7) +endfunc + +func Test_gd_string_only() + let lines = [ + \ 'int func(void)', + \ '{', + \ ' char *s = "x";', + \ '', + \ ' return x;', + \ '}', + \ ] + call XTest_goto_decl('gd', lines, 5, 10) endfunc " Check that setting 'cursorline' does not change curswant diff --git a/src/nvim/testdir/test_help.vim b/src/nvim/testdir/test_help.vim new file mode 100644 index 0000000000..26edc16107 --- /dev/null +++ b/src/nvim/testdir/test_help.vim @@ -0,0 +1,16 @@ + +" Tests for :help + +func Test_help_restore_snapshot() + help + set buftype= + help + edit x + help + helpclose +endfunc + +func Test_help_errors() + call assert_fails('help doesnotexist', 'E149:') + call assert_fails('help!', 'E478:') +endfunc diff --git a/src/nvim/testdir/test_help_tagjump.vim b/src/nvim/testdir/test_help_tagjump.vim index aabfe40537..65d99c644c 100644 --- a/src/nvim/testdir/test_help_tagjump.vim +++ b/src/nvim/testdir/test_help_tagjump.vim @@ -89,17 +89,8 @@ func s:doc_config_teardown() endif endfunc -func s:get_cmd_compl_list(cmd) - let list = [] - let str = '' - for cnt in range(1, 999) - call feedkeys(a:cmd . repeat("\<Tab>", cnt) . "'\<C-B>let str='\<CR>", 'tx') - if str ==# a:cmd[1:] - break - endif - call add(list, str) - endfor - return list +func s:get_help_compl_list(cmd) + return getcompletion(a:cmd, 'help') endfunc func Test_help_complete() @@ -111,49 +102,81 @@ func Test_help_complete() if has('multi_lang') set helplang= endif - let list = s:get_cmd_compl_list(":h test") - call assert_equal(['h test-col', 'h test-char'], list) + let list = s:get_help_compl_list("test") + call assert_equal(['test-col', 'test-char'], list) if has('multi_lang') " 'helplang=ab' and help file lang is 'en' set helplang=ab - let list = s:get_cmd_compl_list(":h test") - call assert_equal(['h test-col', 'h test-char'], list) + let list = s:get_help_compl_list("test") + call assert_equal(['test-col', 'test-char'], list) " 'helplang=' and help file lang is 'en' and 'ab' set rtp+=Xdir1/doc-ab set helplang= - let list = s:get_cmd_compl_list(":h test") - call assert_equal(sort(['h test-col@en', 'h test-col@ab', - \ 'h test-char@en', 'h test-char@ab']), sort(list)) + let list = s:get_help_compl_list("test") + call assert_equal(sort(['test-col@en', 'test-col@ab', + \ 'test-char@en', 'test-char@ab']), sort(list)) " 'helplang=ab' and help file lang is 'en' and 'ab' set helplang=ab - let list = s:get_cmd_compl_list(":h test") - call assert_equal(sort(['h test-col', 'h test-col@en', - \ 'h test-char', 'h test-char@en']), sort(list)) + let list = s:get_help_compl_list("test") + call assert_equal(sort(['test-col', 'test-col@en', + \ 'test-char', 'test-char@en']), sort(list)) " 'helplang=' and help file lang is 'en', 'ab' and 'ja' set rtp+=Xdir1/doc-ja set helplang= - let list = s:get_cmd_compl_list(":h test") - call assert_equal(sort(['h test-col@en', 'h test-col@ab', - \ 'h test-col@ja', 'h test-char@en', - \ 'h test-char@ab', 'h test-char@ja']), sort(list)) + let list = s:get_help_compl_list("test") + call assert_equal(sort(['test-col@en', 'test-col@ab', + \ 'test-col@ja', 'test-char@en', + \ 'test-char@ab', 'test-char@ja']), sort(list)) " 'helplang=ab' and help file lang is 'en', 'ab' and 'ja' set helplang=ab - let list = s:get_cmd_compl_list(":h test") - call assert_equal(sort(['h test-col', 'h test-col@en', - \ 'h test-col@ja', 'h test-char', - \ 'h test-char@en', 'h test-char@ja']), sort(list)) + let list = s:get_help_compl_list("test") + call assert_equal(sort(['test-col', 'test-col@en', + \ 'test-col@ja', 'test-char', + \ 'test-char@en', 'test-char@ja']), sort(list)) " 'helplang=ab,ja' and help file lang is 'en', 'ab' and 'ja' set helplang=ab,ja - let list = s:get_cmd_compl_list(":h test") - call assert_equal(sort(['h test-col', 'h test-col@ja', - \ 'h test-col@en', 'h test-char', - \ 'h test-char@ja', 'h test-char@en']), sort(list)) + let list = s:get_help_compl_list("test") + call assert_equal(sort(['test-col', 'test-col@ja', + \ 'test-col@en', 'test-char', + \ 'test-char@ja', 'test-char@en']), sort(list)) + endif + catch + call assert_exception('X') + finally + call s:doc_config_teardown() + endtry +endfunc + +func Test_help_respect_current_file_lang() + try + let list = [] + call s:doc_config_setup() + + if has('multi_lang') + function s:check_help_file_ext(help_keyword, ext) + exec 'help ' . a:help_keyword + call assert_equal(a:ext, expand('%:e')) + call feedkeys("\<C-]>", 'tx') + call assert_equal(a:ext, expand('%:e')) + pop + helpclose + endfunc + + set rtp+=Xdir1/doc-ab + set rtp+=Xdir1/doc-ja + + set helplang=ab + call s:check_help_file_ext('test-char', 'abx') + call s:check_help_file_ext('test-char@ja', 'jax') + set helplang=ab,ja + call s:check_help_file_ext('test-char@ja', 'jax') + call s:check_help_file_ext('test-char@en', 'txt') endif catch call assert_exception('X') diff --git a/src/nvim/testdir/test_hide.vim b/src/nvim/testdir/test_hide.vim new file mode 100644 index 0000000000..128b8ff945 --- /dev/null +++ b/src/nvim/testdir/test_hide.vim @@ -0,0 +1,97 @@ +" Tests for :hide command/modifier and 'hidden' option + +function SetUp() + let s:save_hidden = &hidden + let s:save_bufhidden = &bufhidden + let s:save_autowrite = &autowrite + set nohidden + set bufhidden= + set noautowrite +endfunc + +function TearDown() + let &hidden = s:save_hidden + let &bufhidden = s:save_bufhidden + let &autowrite = s:save_autowrite +endfunc + +function Test_hide() + let orig_bname = bufname('') + let orig_winnr = winnr('$') + + new Xf1 + set modified + call assert_fails('edit Xf2') + bwipeout! Xf1 + + new Xf1 + set modified + edit! Xf2 + call assert_equal(['Xf2', 2], [bufname(''), winnr('$')]) + call assert_equal([1, 0], [buflisted('Xf1'), bufloaded('Xf1')]) + bwipeout! Xf1 + bwipeout! Xf2 + + new Xf1 + set modified + " :hide as a command + hide + call assert_equal([orig_bname, orig_winnr], [bufname(''), winnr('$')]) + call assert_equal([1, 1], [buflisted('Xf1'), bufloaded('Xf1')]) + bwipeout! Xf1 + + new Xf1 + set modified + " :hide as a command with trailing comment + hide " comment + call assert_equal([orig_bname, orig_winnr], [bufname(''), winnr('$')]) + call assert_equal([1, 1], [buflisted('Xf1'), bufloaded('Xf1')]) + bwipeout! Xf1 + + new Xf1 + set modified + " :hide as a command with bar + hide | new Xf2 " comment + call assert_equal(['Xf2', 2], [bufname(''), winnr('$')]) + call assert_equal([1, 1], [buflisted('Xf1'), bufloaded('Xf1')]) + bwipeout! Xf1 + bwipeout! Xf2 + + new Xf1 + set modified + " :hide as a modifier with trailing comment + hide edit Xf2 " comment + call assert_equal(['Xf2', 2], [bufname(''), winnr('$')]) + call assert_equal([1, 1], [buflisted('Xf1'), bufloaded('Xf1')]) + bwipeout! Xf1 + bwipeout! Xf2 + + new Xf1 + set modified + " To check that the bar is not recognized to separate commands + hide echo "one|two" + call assert_equal(['Xf1', 2], [bufname(''), winnr('$')]) + call assert_equal([1, 1], [buflisted('Xf1'), bufloaded('Xf1')]) + bwipeout! Xf1 + + " set hidden + new Xf1 + set hidden + set modified + edit Xf2 " comment + call assert_equal(['Xf2', 2], [bufname(''), winnr('$')]) + call assert_equal([1, 1], [buflisted('Xf1'), bufloaded('Xf1')]) + bwipeout! Xf1 + bwipeout! Xf2 + + " set hidden bufhidden=wipe + new Xf1 + set bufhidden=wipe + set modified + hide edit! Xf2 " comment + call assert_equal(['Xf2', 2], [bufname(''), winnr('$')]) + call assert_equal([0, 0], [buflisted('Xf1'), bufloaded('Xf1')]) + bwipeout! Xf2 +endfunc + +" vim: shiftwidth=2 sts=2 expandtab diff --git a/src/nvim/testdir/test_history.vim b/src/nvim/testdir/test_history.vim index ee6acfffc3..ca31e3f06c 100644 --- a/src/nvim/testdir/test_history.vim +++ b/src/nvim/testdir/test_history.vim @@ -31,6 +31,30 @@ function History_Tests(hist) call assert_equal('ls', histget(a:hist, -1)) call assert_equal(4, histnr(a:hist)) + let a=execute('history ' . a:hist) + call assert_match("^\n # \\S* history\n 3 buffers\n> 4 ls$", a) + let a=execute('history all') + call assert_match("^\n # .* history\n 3 buffers\n> 4 ls", a) + + if len(a:hist) > 0 + let a=execute('history ' . a:hist . ' 2') + call assert_match("^\n # \\S* history$", a) + let a=execute('history ' . a:hist . ' 3') + call assert_match("^\n # \\S* history\n 3 buffers$", a) + let a=execute('history ' . a:hist . ' 4') + call assert_match("^\n # \\S* history\n> 4 ls$", a) + let a=execute('history ' . a:hist . ' 3,4') + call assert_match("^\n # \\S* history\n 3 buffers\n> 4 ls$", a) + let a=execute('history ' . a:hist . ' -1') + call assert_match("^\n # \\S* history\n> 4 ls$", a) + let a=execute('history ' . a:hist . ' -2') + call assert_match("^\n # \\S* history\n 3 buffers$", a) + let a=execute('history ' . a:hist . ' -2,') + call assert_match("^\n # \\S* history\n 3 buffers\n> 4 ls$", a) + let a=execute('history ' . a:hist . ' -3') + call assert_match("^\n # \\S* history$", a) + endif + " Test for removing entries matching a pattern for i in range(1, 3) call histadd(a:hist, 'text_' . i) @@ -63,3 +87,20 @@ function Test_History() call assert_equal(-1, histnr('abc')) call assert_fails('call histnr([])', 'E730:') endfunction + +function Test_Search_history_window() + new + call setline(1, ['a', 'b', 'a', 'b']) + 1 + call feedkeys("/a\<CR>", 'xt') + call assert_equal('a', getline('.')) + 1 + call feedkeys("/b\<CR>", 'xt') + call assert_equal('b', getline('.')) + 1 + " select the previous /a command + call feedkeys("q/kk\<CR>", 'x!') + call assert_equal('a', getline('.')) + call assert_equal('a', @/) + bwipe! +endfunc diff --git a/src/nvim/testdir/test_hlsearch.vim b/src/nvim/testdir/test_hlsearch.vim new file mode 100644 index 0000000000..066fdd0250 --- /dev/null +++ b/src/nvim/testdir/test_hlsearch.vim @@ -0,0 +1,34 @@ +" Test for v:hlsearch + +function! Test_hlsearch() + new + call setline(1, repeat(['aaa'], 10)) + set hlsearch nolazyredraw + let r=[] + " redraw is needed to make hlsearch highlight the matches + exe "normal! /aaa\<CR>" | redraw + let r1 = screenattr(1, 1) + nohlsearch | redraw + call assert_notequal(r1, screenattr(1,1)) + let v:hlsearch=1 | redraw + call assert_equal(r1, screenattr(1,1)) + let v:hlsearch=0 | redraw + call assert_notequal(r1, screenattr(1,1)) + set hlsearch | redraw + call assert_equal(r1, screenattr(1,1)) + let v:hlsearch=0 | redraw + call assert_notequal(r1, screenattr(1,1)) + exe "normal! n" | redraw + call assert_equal(r1, screenattr(1,1)) + let v:hlsearch=0 | redraw + call assert_notequal(r1, screenattr(1,1)) + exe "normal! /\<CR>" | redraw + call assert_equal(r1, screenattr(1,1)) + set nohls + exe "normal! /\<CR>" | redraw + call assert_notequal(r1, screenattr(1,1)) + call assert_fails('let v:hlsearch=[]', 'E745') + call garbagecollect(1) + call getchar(1) + enew! +endfunction diff --git a/src/nvim/testdir/test_largefile.vim b/src/nvim/testdir/test_largefile.vim new file mode 100644 index 0000000000..1b3e02a0c8 --- /dev/null +++ b/src/nvim/testdir/test_largefile.vim @@ -0,0 +1,34 @@ +" Tests for large files +" This is only executed manually: "make test_largefile". +" This is not run as part of "make test". + +func Test_largefile() + let fname = 'Xlarge.txt' + + call delete(fname) + exe "e" fname + " Make sure that a line break is 1 byte (LF). + set ff=unix + set undolevels=-1 + " Input 99 'A's. The line becomes 100 bytes including a line break. + exe "normal 99iA\<Esc>" + yank + " Put 39,999,999 times. The file becomes 4,000,000,000 bytes. + normal 39999999p + " Moving around in the file randomly. + normal G + normal 10% + normal 90% + normal 50% + normal gg + w + " Check if the file size is 4,000,000,000 bytes. + let fsize=getfsize(fname) + if has('num64') + call assert_true(fsize == 4000000000) + else + " getfsize() returns -2 if a Number is 32 bits. + call assert_true(fsize == -2) + endif + call delete(fname) +endfunc diff --git a/src/nvim/testdir/test_listlbr.vim b/src/nvim/testdir/test_listlbr.vim new file mode 100644 index 0000000000..7856ee82ab --- /dev/null +++ b/src/nvim/testdir/test_listlbr.vim @@ -0,0 +1,235 @@ +" Test for linebreak and list option (non-utf8) + +set encoding=latin1 +scriptencoding latin1 + +if !exists("+linebreak") || !has("conceal") + finish +endif + +source view_util.vim + +function s:screen_lines(lnum, width) abort + return ScreenLines(a:lnum, a:width) +endfunction + +function! s:compare_lines(expect, actual) + call assert_equal(join(a:expect, "\n"), join(a:actual, "\n")) +endfunction + +function s:test_windows(...) + call NewWindow(10, 20) + setl ts=8 sw=4 sts=4 linebreak sbr= wrap + exe get(a:000, 0, '') +endfunction + +function s:close_windows(...) + call CloseWindow() + exe get(a:000, 0, '') +endfunction + +func Test_set_linebreak() + call s:test_windows('setl ts=4 sbr=+') + call setline(1, "\tabcdef hijklmn\tpqrstuvwxyz_1060ABCDEFGHIJKLMNOP ") + let lines = s:screen_lines([1, 4], winwidth(0)) + let expect = [ +\ " abcdef ", +\ "+hijklmn ", +\ "+pqrstuvwxyz_1060ABC", +\ "+DEFGHIJKLMNOP ", +\ ] + call s:compare_lines(expect, lines) + call s:close_windows() +endfunc + +func Test_linebreak_with_list() + call s:test_windows('setl ts=4 sbr=+ list listchars=') + call setline(1, "\tabcdef hijklmn\tpqrstuvwxyz_1060ABCDEFGHIJKLMNOP ") + let lines = s:screen_lines([1, 4], winwidth(0)) + let expect = [ +\ "^Iabcdef hijklmn^I ", +\ "+pqrstuvwxyz_1060ABC", +\ "+DEFGHIJKLMNOP ", +\ "~ ", +\ ] + call s:compare_lines(expect, lines) + call s:close_windows() +endfunc + +func Test_linebreak_with_nolist() + call s:test_windows('setl ts=4 sbr=+ nolist') + call setline(1, "\tabcdef hijklmn\tpqrstuvwxyz_1060ABCDEFGHIJKLMNOP ") + let lines = s:screen_lines([1, 4], winwidth(0)) + let expect = [ +\ " abcdef ", +\ "+hijklmn ", +\ "+pqrstuvwxyz_1060ABC", +\ "+DEFGHIJKLMNOP ", +\ ] + call s:compare_lines(expect, lines) + call s:close_windows() +endfunc + +func Test_should_break() + call s:test_windows('setl sbr=+ nolist') + call setline(1, "1\t" . repeat('a', winwidth(0)-2)) + let lines = s:screen_lines([1, 4], winwidth(0)) + let expect = [ +\ "1 ", +\ "+aaaaaaaaaaaaaaaaaa ", +\ "~ ", +\ "~ ", +\ ] + call s:compare_lines(expect, lines) + call s:close_windows() +endfunc + +func Test_linebreak_with_conceal() + call s:test_windows('setl cpo&vim sbr=+ list conceallevel=2 concealcursor=nv listchars=tab:ab') + call setline(1, "_S_\t bla") + syn match ConcealVar contained /_/ conceal + syn match All /.*/ contains=ConcealVar + let lines = s:screen_lines([1, 4], winwidth(0)) + let expect = [ +\ "Sabbbbbb bla ", +\ "~ ", +\ "~ ", +\ "~ ", +\ ] + call s:compare_lines(expect, lines) + call s:close_windows() +endfunc + +func Test_virtual_block() + call s:test_windows('setl sbr=+') + call setline(1, [ +\ "REMOVE: this not", +\ "REMOVE: aaaaaaaaaaaaa", +\ ]) + exe "norm! 1/^REMOVE:" + exe "norm! 0\<C-V>jf x" + $put + let lines = s:screen_lines([1, 4], winwidth(0)) + let expect = [ +\ "this not ", +\ "aaaaaaaaaaaaa ", +\ "REMOVE: ", +\ "REMOVE: ", +\ ] + call s:compare_lines(expect, lines) + call s:close_windows() +endfunc + +func Test_virtual_block_and_vbA() + call s:test_windows() + call setline(1, "long line: " . repeat("foobar ", 40) . "TARGET at end") + exe "norm! $3B\<C-v>eAx\<Esc>" + let lines = s:screen_lines([1, 10], winwidth(0)) + let expect = [ +\ "foobar foobar ", +\ "foobar foobar ", +\ "foobar foobar ", +\ "foobar foobar ", +\ "foobar foobar ", +\ "foobar foobar ", +\ "foobar foobar ", +\ "foobar foobar ", +\ "foobar foobar ", +\ "foobar TARGETx at ", +\ ] + call s:compare_lines(expect, lines) + call s:close_windows() +endfunc + +func Test_virtual_char_and_block() + call s:test_windows() + call setline(1, "1111-1111-1111-11-1111-1111-1111") + exe "norm! 0f-lv3lc2222\<Esc>bgj." + let lines = s:screen_lines([1, 2], winwidth(0)) + let expect = [ +\ "1111-2222-1111-11- ", +\ "1111-2222-1111 ", +\ ] + call s:compare_lines(expect, lines) + call s:close_windows() +endfunc + +func Test_undo_after_block_visual() + call s:test_windows() + call setline(1, ["aaa", "aaa", "a"]) + exe "norm! gg\<C-V>2j~e." + let lines = s:screen_lines([1, 3], winwidth(0)) + let expect = [ +\ "AaA ", +\ "AaA ", +\ "A ", +\ ] + call s:compare_lines(expect, lines) + call s:close_windows() +endfunc + +func Test_norm_after_block_visual() + call s:test_windows() + call setline(1, ["abcd{ef", "ghijklm", "no}pgrs"]) + exe "norm! ggf{\<C-V>\<C-V>c%" + let lines = s:screen_lines([1, 3], winwidth(0)) + let expect = [ +\ "abcdpgrs ", +\ "~ ", +\ "~ ", +\ ] + call s:compare_lines(expect, lines) + call s:close_windows() +endfunc + +func Test_block_replace_after_wrapping() + call s:test_windows() + call setline(1, repeat("a", 150)) + exe "norm! 0yypk147|\<C-V>jr0" + call assert_equal(repeat("a", 146) . "0aaa", getline(1)) + call assert_equal(repeat("a", 146) . "0aaa", getline(2)) + let lines = s:screen_lines([1, 10], winwidth(0)) + let expect = [ +\ "aaaaaaaaaaaaaaaaaaaa", +\ "aaaaaaaaaaaaaaaaaaaa", +\ "aaaaaaaaaaaaaaaaaaaa", +\ "aaaaaaaaaaaaaaaaaaaa", +\ "aaaaaaaaaaaaaaaaaaaa", +\ "aaaaaaaaaaaaaaaaaaaa", +\ "aaaaaaaaaaaaaaaaaaaa", +\ "aaaaaa0aaa ", +\ "@ ", +\ "@ ", +\ ] + call s:compare_lines(expect, lines) + call s:close_windows() +endfunc + +func Test_list_with_listchars() + call s:test_windows('setl list listchars=space:_,trail:-,tab:>-,eol:$') + call setline(1, "a aaaaaaaaaaaaaaaaaaaaaa\ta ") + let lines = s:screen_lines([1, 3], winwidth(0)) + let expect = [ +\ "a_ ", +\ "aaaaaaaaaaaaaaaaaaaa", +\ "aa>-----a-$ ", +\ ] + call s:compare_lines(expect, lines) + call s:close_windows() +endfunc + +func Test_list_with_tab_and_skipping_first_chars() + call s:test_windows('setl list listchars=tab:>- ts=70 nowrap') + call setline(1, ["iiiiiiiiiiiiiiii\taaaaaaaaaaaaaaaaaa", "iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii\taaaaaaaaaaaaaaaaaa", "iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii\taaaaaaaaaaaaaaaaaa", "iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii\taaaaaaaaaaaaaaaaaa"]) + call cursor(4,64) + norm! 2zl + let lines = s:screen_lines([1, 4], winwidth(0)) + let expect = [ +\ "---------------aaaaa", +\ "---------------aaaaa", +\ "---------------aaaaa", +\ "iiiiiiiii>-----aaaaa", +\ ] + call s:compare_lines(expect, lines) + call s:close_windows() +endfu diff --git a/src/nvim/testdir/test_listlbr_utf8.vim b/src/nvim/testdir/test_listlbr_utf8.vim new file mode 100644 index 0000000000..980d67d49d --- /dev/null +++ b/src/nvim/testdir/test_listlbr_utf8.vim @@ -0,0 +1,229 @@ +" Test for linebreak and list option in utf-8 mode + +set encoding=utf-8 +scriptencoding utf-8 + +if !exists("+linebreak") || !has("conceal") || !has("signs") + finish +endif + +source view_util.vim + +function s:screen_lines(lnum, width) abort + return ScreenLines(a:lnum, a:width) +endfunction + +function! s:compare_lines(expect, actual) + call assert_equal(a:expect, a:actual) +endfunction + +function s:screen_attr(lnum, chars, ...) abort + let line = getline(a:lnum) + let attr = [] + let prefix = get(a:000, 0, 0) + for i in range(a:chars[0], a:chars[1]) + let scol = strdisplaywidth(strcharpart(line, 0, i-1)) + 1 + let attr += [screenattr(a:lnum, scol + prefix)] + endfor + return attr +endfunction + +function s:test_windows(...) + call NewWindow(10, 20) + setl ts=4 sw=4 sts=4 linebreak sbr=+ wrap + exe get(a:000, 0, '') +endfunction + +function s:close_windows(...) + call CloseWindow() + exe get(a:000, 0, '') +endfunction + +func Test_linebreak_with_fancy_listchars() + call s:test_windows("setl list listchars=nbsp:\u2423,tab:\u2595\u2014,trail:\u02d1,eol:\ub6") + call setline(1, "\tabcdef hijklmn\tpqrstuvwxyz\u00a01060ABCDEFGHIJKLMNOP ") + redraw! + let lines = s:screen_lines([1, 4], winwidth(0)) + let expect = [ +\ "▕———abcdef ", +\ "+hijklmn▕——— ", +\ "+pqrstuvwxyz␣1060ABC", +\ "+DEFGHIJKLMNOPˑ¶ ", +\ ] + call s:compare_lines(expect, lines) + call s:close_windows() +endfunc + +func Test_nolinebreak_with_list() + call s:test_windows("setl nolinebreak list listchars=nbsp:\u2423,tab:\u2595\u2014,trail:\u02d1,eol:\ub6") + call setline(1, "\tabcdef hijklmn\tpqrstuvwxyz\u00a01060ABCDEFGHIJKLMNOP ") + redraw! + let lines = s:screen_lines([1, 4], winwidth(0)) + let expect = [ +\ "▕———abcdef hijklmn▕—", +\ "+pqrstuvwxyz␣1060ABC", +\ "+DEFGHIJKLMNOPˑ¶ ", +\ "~ ", +\ ] + call s:compare_lines(expect, lines) + call s:close_windows() +endfunc + +func Test_linebreak_with_nolist() + call s:test_windows('setl nolist') + call setline(1, "\t*mask = nil;") + redraw! + let lines = s:screen_lines([1, 4], winwidth(0)) + let expect = [ +\ " *mask = nil; ", +\ "~ ", +\ "~ ", +\ "~ ", +\ ] + call s:compare_lines(expect, lines) + call s:close_windows() +endfunc + +func Test_list_and_concealing1() + call s:test_windows('setl list listchars=tab:>- cole=1') + call setline(1, [ +\ "#define ABCDE\t\t1", +\ "#define ABCDEF\t\t1", +\ "#define ABCDEFG\t\t1", +\ "#define ABCDEFGH\t1", +\ "#define MSG_MODE_FILE\t\t\t1", +\ "#define MSG_MODE_CONSOLE\t\t2", +\ "#define MSG_MODE_FILE_AND_CONSOLE\t3", +\ "#define MSG_MODE_FILE_THEN_CONSOLE\t4", +\ ]) + vert resize 40 + syn match Conceal conceal cchar=>'AB\|MSG_MODE' + redraw! + let lines = s:screen_lines([1, 7], winwidth(0)) + let expect = [ +\ "#define ABCDE>-->---1 ", +\ "#define >CDEF>-->---1 ", +\ "#define >CDEFG>->---1 ", +\ "#define >CDEFGH>----1 ", +\ "#define >_FILE>--------->--->---1 ", +\ "#define >_CONSOLE>---------->---2 ", +\ "#define >_FILE_AND_CONSOLE>---------3 ", +\ ] + call s:compare_lines(expect, lines) + call s:close_windows() +endfunc + +func Test_list_and_concealing2() + call s:test_windows('setl nowrap ts=2 list listchars=tab:>- cole=2 concealcursor=n') + call setline(1, "bbeeeeee\t\t;\tsome text") + vert resize 40 + syn clear + syn match meaning /;\s*\zs.*/ + syn match hasword /^\x\{8}/ contains=word + syn match word /\<\x\{8}\>/ contains=beginword,endword contained + syn match beginword /\<\x\x/ contained conceal + syn match endword /\x\{6}\>/ contained + hi meaning guibg=blue + hi beginword guibg=green + hi endword guibg=red + redraw! + let lines = s:screen_lines([1, 1], winwidth(0)) + let expect = [ +\ "eeeeee>--->-;>some text ", +\ ] + call s:compare_lines(expect, lines) + call s:close_windows() +endfunc + +func Test_screenattr_for_comment() + call s:test_windows("setl ft=c ts=7 list listchars=nbsp:\u2423,tab:\u2595\u2014,trail:\u02d1,eol:\ub6") + call setline(1, " /*\t\t and some more */") + norm! gg0 + syntax on + hi SpecialKey term=underline ctermfg=red guifg=red + redraw! + let line = getline(1) + let attr = s:screen_attr(1, [1, 6]) + call assert_notequal(attr[0], attr[1]) + call assert_notequal(attr[1], attr[3]) + call assert_notequal(attr[3], attr[5]) + call s:close_windows() +endfunc + +func Test_visual_block_and_selection_exclusive() + call s:test_windows('setl selection=exclusive') + call setline(1, "long line: " . repeat("foobar ", 40) . "TARGETÃ' at end") + exe "norm! $3B\<C-v>eAx\<Esc>" + let lines = s:screen_lines([1, 10], winwidth(0)) + let expect = [ +\ "+foobar foobar ", +\ "+foobar foobar ", +\ "+foobar foobar ", +\ "+foobar foobar ", +\ "+foobar foobar ", +\ "+foobar foobar ", +\ "+foobar foobar ", +\ "+foobar foobar ", +\ "+foobar foobar ", +\ "+foobar TARGETÃx' ", +\ ] + call s:compare_lines(expect, lines) + call s:close_windows() +endfunc + +func Test_multibyte_sign_and_colorcolumn() + call s:test_windows("setl nolinebreak cc=3 list listchars=nbsp:\u2423,tab:\u2595\u2014,trail:\u02d1,eol:\ub6") + call setline(1, ["", "a b c", "a b c"]) + exe "sign define foo text=\uff0b" + exe "sign place 1 name=foo line=2 buffer=" . bufnr('%') + redraw! + norm! ggj0 + let signwidth = strdisplaywidth("\uff0b") + let attr1 = s:screen_attr(2, [1, 3], signwidth) + let attr2 = s:screen_attr(3, [1, 3], signwidth) + call assert_equal(attr1[0], attr2[0]) + call assert_equal(attr1[1], attr2[1]) + call assert_equal(attr1[2], attr2[2]) + let lines = s:screen_lines([1, 3], winwidth(0)) + let expect = [ +\ " ¶ ", +\ "+a b c¶ ", +\ " a b c¶ ", +\ ] + call s:compare_lines(expect, lines) + call s:close_windows() +endfunc + +func Test_chinese_char_on_wrap_column() + call s:test_windows("setl nolbr wrap sbr=") + syntax off + call setline(1, [ +\ 'aaaaaaaaaaaaaaaaaaa中'. +\ 'aaaaaaaaaaaaaaaaa中'. +\ 'aaaaaaaaaaaaaaaaa中'. +\ 'aaaaaaaaaaaaaaaaa中'. +\ 'aaaaaaaaaaaaaaaaa中'. +\ 'aaaaaaaaaaaaaaaaa中'. +\ 'aaaaaaaaaaaaaaaaa中'. +\ 'aaaaaaaaaaaaaaaaa中'. +\ 'aaaaaaaaaaaaaaaaa中'. +\ 'aaaaaaaaaaaaaaaaa中'. +\ 'hello']) + call cursor(1,1) + norm! $ + redraw! + let expect=[ +\ '中aaaaaaaaaaaaaaaaa>', +\ '中aaaaaaaaaaaaaaaaa>', +\ '中aaaaaaaaaaaaaaaaa>', +\ '中aaaaaaaaaaaaaaaaa>', +\ '中aaaaaaaaaaaaaaaaa>', +\ '中aaaaaaaaaaaaaaaaa>', +\ '中aaaaaaaaaaaaaaaaa>', +\ '中aaaaaaaaaaaaaaaaa>', +\ '中aaaaaaaaaaaaaaaaa>', +\ '中hello '] + let lines = s:screen_lines([1, 10], winwidth(0)) + call s:compare_lines(expect, lines) + call s:close_windows() +endfu diff --git a/src/nvim/testdir/test_mapping.vim b/src/nvim/testdir/test_mapping.vim index d937565ce5..f5e4c4b90c 100644 --- a/src/nvim/testdir/test_mapping.vim +++ b/src/nvim/testdir/test_mapping.vim @@ -35,29 +35,83 @@ func Test_map_ctrl_c_visual() endfunc func Test_map_langmap() - " langmap should not get remapped in insert mode - inoremap { FAIL_ilangmap - set langmap=+{ langnoremap + if !has('langmap') + return + endif + + " check langmap applies in normal mode + set langmap=+- nolangremap + new + call setline(1, ['a', 'b', 'c']) + 2 + call assert_equal('b', getline('.')) + call feedkeys("+", "xt") + call assert_equal('a', getline('.')) + + " check no remapping + map x + + 2 + call feedkeys("x", "xt") + call assert_equal('c', getline('.')) + + " check with remapping + set langremap + 2 + call feedkeys("x", "xt") + call assert_equal('a', getline('.')) + + unmap x + bwipe! + + " 'langnoremap' follows 'langremap' and vise versa + set langremap + set langnoremap + call assert_equal(0, &langremap) + set langremap + call assert_equal(0, &langnoremap) + set nolangremap + call assert_equal(1, &langnoremap) + + " check default values + set langnoremap& + call assert_equal(1, &langnoremap) + call assert_equal(0, &langremap) + set langremap& + call assert_equal(1, &langnoremap) + call assert_equal(0, &langremap) + + " langmap should not apply in insert mode, 'langremap' doesn't matter + set langmap=+{ nolangremap call feedkeys("Go+\<Esc>", "xt") call assert_equal('+', getline('$')) - - " Insert-mode expr mapping with langmap - inoremap <expr> { "FAIL_iexplangmap" + set langmap=+{ langremap call feedkeys("Go+\<Esc>", "xt") call assert_equal('+', getline('$')) - iunmap <expr> { - " langmap should not get remapped in Command-line mode - cnoremap { FAIL_clangmap + " langmap used for register name in insert mode. + call setreg('a', 'aaaa') + call setreg('b', 'bbbb') + call setreg('c', 'cccc') + set langmap=ab langremap + call feedkeys("Go\<C-R>a\<Esc>", "xt") + call assert_equal('bbbb', getline('$')) + call feedkeys("Go\<C-R>\<C-R>a\<Esc>", "xt") + call assert_equal('bbbb', getline('$')) + " mapping does not apply + imap c a + call feedkeys("Go\<C-R>c\<Esc>", "xt") + call assert_equal('cccc', getline('$')) + imap a c + call feedkeys("Go\<C-R>a\<Esc>", "xt") + call assert_equal('bbbb', getline('$')) + + " langmap should not apply in Command-line mode + set langmap=+{ nolangremap call feedkeys(":call append(line('$'), '+')\<CR>", "xt") call assert_equal('+', getline('$')) - cunmap { - " Command-line mode expr mapping with langmap - cnoremap <expr> { "FAIL_cexplangmap" - call feedkeys(":call append(line('$'), '+')\<CR>", "xt") - call assert_equal('+', getline('$')) - cunmap { + iunmap a + iunmap c set nomodified endfunc @@ -68,7 +122,7 @@ func Test_map_feedkeys() $-1 call feedkeys("0qqdw.ifoo\<Esc>qj0@q\<Esc>", "xt") call assert_equal(['fooc d', 'fooc d'], getline(line('$') - 1, line('$'))) - unmap . + nunmap . set nomodified endfunc @@ -98,3 +152,11 @@ func Test_break_undo() call assert_equal('new line here', getline(line('$') - 1)) set nomodified endfunc + +func Test_map_meta_quotes() + imap <M-"> foo + call feedkeys("Go-\<M-\">-\<Esc>", "xt") + call assert_equal("-foo-", getline('$')) + set nomodified + iunmap <M-"> +endfunc diff --git a/src/nvim/testdir/test_match.vim b/src/nvim/testdir/test_match.vim index 9398ef2f27..066bb2f6a1 100644 --- a/src/nvim/testdir/test_match.vim +++ b/src/nvim/testdir/test_match.vim @@ -198,6 +198,16 @@ func Test_matchaddpos() call assert_equal(screenattr(2,2), screenattr(1,10)) call assert_notequal(screenattr(2,2), screenattr(1,11)) + " Check overlapping pos + call clearmatches() + call setline(1, ['1234567890', 'NH']) + call matchaddpos('Error', [[1,1,5], [1,3,5], [2,2]]) + redraw! + call assert_notequal(screenattr(2,2), 0) + call assert_equal(screenattr(2,2), screenattr(1,5)) + call assert_equal(screenattr(2,2), screenattr(1,7)) + call assert_notequal(screenattr(2,2), screenattr(1,8)) + nohl call clearmatches() syntax off diff --git a/src/nvim/testdir/test_matchadd_conceal.vim b/src/nvim/testdir/test_matchadd_conceal.vim index bc1c28d6e9..c11f1a84a9 100644 --- a/src/nvim/testdir/test_matchadd_conceal.vim +++ b/src/nvim/testdir/test_matchadd_conceal.vim @@ -260,3 +260,26 @@ function! Test_matchadd_repeat_conceal_with_syntax_off() quit! endfunction + +function! Test_matchadd_and_syn_conceal() + new + let cnt='Inductive bool : Type := | true : bool | false : bool.' + let expect = 'Inductive - : Type := | true : - | false : -.' + 0put =cnt + " set filetype and :syntax on to change screenattr() + set cole=1 cocu=nv + hi link CheckedByCoq WarningMsg + syntax on + syntax keyword coqKwd bool conceal cchar=- + redraw! + call assert_equal(expect, s:screenline(1)) + call assert_notequal(screenattr(1, 10) , screenattr(1, 11)) + call assert_notequal(screenattr(1, 11) , screenattr(1, 12)) + call assert_equal(screenattr(1, 11) , screenattr(1, 32)) + call matchadd('CheckedByCoq', '\%<2l\%>9c\%<16c') + redraw! + call assert_equal(expect, s:screenline(1)) + call assert_notequal(screenattr(1, 10) , screenattr(1, 11)) + call assert_notequal(screenattr(1, 11) , screenattr(1, 12)) + call assert_equal(screenattr(1, 11) , screenattr(1, 32)) +endfunction diff --git a/src/nvim/testdir/test_menu.vim b/src/nvim/testdir/test_menu.vim index be559467c8..af18760065 100644 --- a/src/nvim/testdir/test_menu.vim +++ b/src/nvim/testdir/test_menu.vim @@ -4,6 +4,6 @@ func Test_load_menu() try source $VIMRUNTIME/menu.vim catch - call assert_false(1, 'error while loading menus: ' . v:exception) + call assert_report('error while loading menus: ' . v:exception) endtry endfunc diff --git a/src/nvim/testdir/test_mksession.vim b/src/nvim/testdir/test_mksession.vim new file mode 100644 index 0000000000..4774cf4af5 --- /dev/null +++ b/src/nvim/testdir/test_mksession.vim @@ -0,0 +1,155 @@ +" Test for :mksession, :mkview and :loadview in latin1 encoding + +scriptencoding latin1 + +if !has('multi_byte') || !has('mksession') + finish +endif + +func Test_mksession() + tabnew + let wrap_save = &wrap + set sessionoptions=buffers splitbelow fileencoding=latin1 + call setline(1, [ + \ 'start:', + \ 'no multibyte chAracter', + \ ' one leaDing tab', + \ ' four leadinG spaces', + \ 'two consecutive tabs', + \ 'two tabs in one line', + \ 'one multibyteCharacter', + \ 'a two multiByte characters', + \ 'A three mulTibyte characters' + \ ]) + let tmpfile = 'Xtemp' + exec 'w! ' . tmpfile + /^start: + set wrap + vsplit + norm! j16| + split + norm! j16| + split + norm! j16| + split + norm! j8| + split + norm! j8| + split + norm! j16| + split + norm! j16| + split + norm! j16| + wincmd l + + set nowrap + /^start: + norm! j16|3zl + split + norm! j016|3zl + split + norm! j016|3zl + split + norm! j08|3zl + split + norm! j08|3zl + split + norm! j016|3zl + split + norm! j016|3zl + split + norm! j016|3zl + split + call wincol() + mksession! Xtest_mks.out + let li = filter(readfile('Xtest_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|" + \ ] + call assert_equal(expected, li) + tabclose! + + call delete('Xtest_mks.out') + call delete(tmpfile) + let &wrap = wrap_save +endfunc + +func Test_mksession_winheight() + new + set winheight=10 winminheight=2 + mksession! Xtest_mks.out + source Xtest_mks.out + + call delete('Xtest_mks.out') +endfunc + +" Verify that arglist is stored correctly to the session file. +func Test_mksession_arglist() + argdel * + next file1 file2 file3 file4 + mksession! Xtest_mks.out + source Xtest_mks.out + call assert_equal(['file1', 'file2', 'file3', 'file4'], argv()) + + call delete('Xtest_mks.out') + argdel * +endfunc + + +func Test_mksession_one_buffer_two_windows() + edit Xtest1 + new Xtest2 + split + mksession! Xtest_mks.out + let lines = readfile('Xtest_mks.out') + let count1 = 0 + let count2 = 0 + let count2buf = 0 + for line in lines + if line =~ 'edit \f*Xtest1$' + let count1 += 1 + endif + if line =~ 'edit \f\{-}Xtest2' + let count2 += 1 + endif + if line =~ 'buffer \f\{-}Xtest2' + let count2buf += 1 + endif + endfor + call assert_equal(1, count1, 'Xtest1 count') + call assert_equal(2, count2, 'Xtest2 count') + call assert_equal(2, count2buf, 'Xtest2 buffer count') + + close + bwipe! + call delete('Xtest_mks.out') +endfunc + + +" vim: shiftwidth=2 sts=2 expandtab diff --git a/src/nvim/testdir/test_mksession_utf8.vim b/src/nvim/testdir/test_mksession_utf8.vim new file mode 100644 index 0000000000..c05a1d3b6d --- /dev/null +++ b/src/nvim/testdir/test_mksession_utf8.vim @@ -0,0 +1,104 @@ +" Test for :mksession, :mkview and :loadview in utf-8 encoding + +set encoding=utf-8 +scriptencoding utf-8 + +if !has('multi_byte') || !has('mksession') + finish +endif + +func Test_mksession_utf8() + tabnew + let wrap_save = &wrap + set sessionoptions=buffers splitbelow fileencoding=utf-8 + call setline(1, [ + \ 'start:', + \ 'no multibyte chAracter', + \ ' one leaDing tab', + \ ' four leadinG spaces', + \ 'two consecutive tabs', + \ 'two tabs in one line', + \ 'one … multibyteCharacter', + \ 'a “b” two multiByte characters', + \ '“c”1€ three mulTibyte characters' + \ ]) + let tmpfile = tempname() + exec 'w! ' . tmpfile + /^start: + set wrap + vsplit + norm! j16| + split + norm! j16| + split + norm! j16| + split + norm! j8| + split + norm! j8| + split + norm! j16| + split + norm! j16| + split + norm! j16| + wincmd l + + set nowrap + /^start: + norm! j16|3zl + split + norm! j016|3zl + split + norm! j016|3zl + split + norm! j08|3zl + split + norm! j08|3zl + split + norm! j016|3zl + split + norm! j016|3zl + split + norm! j016|3zl + split + 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|" + \ ] + call assert_equal(expected, li) + tabclose! + + call delete('test_mks.out') + call delete(tmpfile) + let &wrap = wrap_save +endfunc + +" vim: shiftwidth=2 sts=2 expandtab diff --git a/src/nvim/testdir/test_nested_function.vim b/src/nvim/testdir/test_nested_function.vim index f881730529..afaaea6ceb 100644 --- a/src/nvim/testdir/test_nested_function.vim +++ b/src/nvim/testdir/test_nested_function.vim @@ -1,32 +1,63 @@ "Tests for nested functions " -function! NestedFunc() - fu! Func1() +func NestedFunc() + func! Func1() let g:text .= 'Func1 ' - endfunction + endfunc call Func1() - fu! s:func2() + func! s:func2() let g:text .= 's:func2 ' - endfunction + endfunc call s:func2() - fu! s:_func3() + func! s:_func3() let g:text .= 's:_func3 ' - endfunction + endfunc call s:_func3() let fn = 'Func4' - fu! {fn}() + func! {fn}() let g:text .= 'Func4 ' - endfunction + endfunc call {fn}() let fn = 'func5' - fu! s:{fn}() + func! s:{fn}() let g:text .= 's:func5' - endfunction + endfunc call s:{fn}() -endfunction +endfunc -function! Test_nested_functions() +func Test_nested_functions() let g:text = '' call NestedFunc() call assert_equal('Func1 s:func2 s:_func3 Func4 s:func5', g:text) endfunction + +func Test_nested_argument() + func g:X() + let g:Y = function('sort') + endfunc + let g:Y = function('sort') + echo g:Y([], g:X()) + delfunc g:X + unlet g:Y +endfunc + +func Recurse(count) + if a:count > 0 + call Recurse(a:count - 1) + endif +endfunc + +func Test_max_nesting() + let call_depth_here = 2 + let ex_depth_here = 5 + set mfd& + + call Recurse(99 - call_depth_here) + call assert_fails('call Recurse(' . (100 - call_depth_here) . ')', 'E132:') + + set mfd=210 + call Recurse(209 - ex_depth_here) + call assert_fails('call Recurse(' . (210 - ex_depth_here) . ')', 'E169:') + + set mfd& +endfunc diff --git a/src/nvim/testdir/test_normal.vim b/src/nvim/testdir/test_normal.vim new file mode 100644 index 0000000000..4747d5704d --- /dev/null +++ b/src/nvim/testdir/test_normal.vim @@ -0,0 +1,2337 @@ +" Test for various Normal mode commands + +func! Setup_NewWindow() + 10new + call setline(1, range(1,100)) +endfunc + +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) + if getline(ln) =~# '\d\s\+$' + call setline(ln, substitute(line, '\s\+$', '', '') . '->$') + endif + endfor +endfunc + +func! CountSpaces(type, ...) + " for testing operatorfunc + " will count the number of spaces + " and return the result in g:a + let sel_save = &selection + let &selection = "inclusive" + let reg_save = @@ + + if a:0 " Invoked from Visual mode, use gv command. + silent exe "normal! gvy" + elseif a:type == 'line' + silent exe "normal! '[V']y" + else + silent exe "normal! `[v`]y" + endif + let g:a=strlen(substitute(@@, '[^ ]', '', 'g')) + let &selection = sel_save + let @@ = reg_save +endfunc + +func! OpfuncDummy(type, ...) + " for testing operatorfunc + let g:opt=&linebreak + + if a:0 " Invoked from Visual mode, use gv command. + silent exe "normal! gvy" + elseif a:type == 'line' + silent exe "normal! '[V']y" + else + silent exe "normal! `[v`]y" + endif + " Create a new dummy window + new + let g:bufnr=bufnr('%') +endfunc + +fun! Test_normal00_optrans() + new + call append(0, ['1 This is a simple test: abcd', '2 This is the second line', '3 this is the third line']) + 1 + exe "norm! Sfoobar\<esc>" + call assert_equal(['foobar', '2 This is the second line', '3 this is the third line', ''], getline(1,'$')) + 2 + exe "norm! $vbsone" + call assert_equal(['foobar', '2 This is the second one', '3 this is the third line', ''], getline(1,'$')) + norm! VS Second line here + call assert_equal(['foobar', ' Second line here', '3 this is the third line', ''], getline(1, '$')) + %d + call append(0, ['4 This is a simple test: abcd', '5 This is the second line', '6 this is the third line']) + call append(0, ['1 This is a simple test: abcd', '2 This is the second line', '3 this is the third line']) + + 1 + norm! 2D + call assert_equal(['3 this is the third line', '4 This is a simple test: abcd', '5 This is the second line', '6 this is the third line', ''], getline(1,'$')) + " Nvim: no "#" flag in 'cpoptions'. + " set cpo+=# + " norm! 4D + " call assert_equal(['', '4 This is a simple test: abcd', '5 This is the second line', '6 this is the third line', ''], getline(1,'$')) + + " clean up + set cpo-=# + bw! +endfunc + +func! Test_normal01_keymodel() + throw "skipped: Nvim regression: 'keymodel'" + call Setup_NewWindow() + " Test 1: depending on 'keymodel' <s-down> does something different + 50 + call feedkeys("V\<S-Up>y", 'tx') + call assert_equal(['47', '48', '49', '50'], getline("'<", "'>")) + set keymodel=startsel + 50 + call feedkeys("V\<S-Up>y", 'tx') + call assert_equal(['49', '50'], getline("'<", "'>")) + " Start visual mode when keymodel = startsel + 50 + call feedkeys("\<S-Up>y", 'tx') + call assert_equal(['49', '5'], getreg(0, 0, 1)) + " Do not start visual mode when keymodel= + set keymodel= + 50 + call feedkeys("\<S-Up>y$", 'tx') + call assert_equal(['42'], getreg(0, 0, 1)) + " Stop visual mode when keymodel=stopsel + set keymodel=stopsel + 50 + call feedkeys("Vkk\<Up>yy", 'tx') + call assert_equal(['47'], getreg(0, 0, 1)) + + set keymodel= + 50 + call feedkeys("Vkk\<Up>yy", 'tx') + call assert_equal(['47', '48', '49', '50'], getreg(0, 0, 1)) + + " clean up + bw! +endfunc + +func! Test_normal02_selectmode() + " some basic select mode tests + call Setup_NewWindow() + 50 + norm! gHy + call assert_equal('y51', getline('.')) + call setline(1, range(1,100)) + 50 + exe ":norm! V9jo\<c-g>y" + call assert_equal('y60', getline('.')) + " clean up + bw! +endfunc + +func! Test_normal02_selectmode2() + " some basic select mode tests + call Setup_NewWindow() + 50 + call feedkeys(":set im\n\<c-o>gHc\<c-o>:set noim\n", 'tx') + call assert_equal('c51', getline('.')) + " clean up + bw! +endfunc + +func! Test_normal03_join() + " basic join test + call Setup_NewWindow() + 50 + norm! VJ + call assert_equal('50 51', getline('.')) + $ + norm! J + call assert_equal('100', getline('.')) + $ + norm! V9-gJ + call assert_equal('919293949596979899100', getline('.')) + call setline(1, range(1,100)) + $ + :j 10 + call assert_equal('100', getline('.')) + " clean up + bw! +endfunc + +func! Test_normal04_filter() + " basic filter test + " only test on non windows platform + if has('win32') + return + endif + call Setup_NewWindow() + 1 + call feedkeys("!!sed -e 's/^/| /'\n", 'tx') + call assert_equal('| 1', getline('.')) + 90 + :sil :!echo one + call feedkeys('.', 'tx') + call assert_equal('| 90', getline('.')) + 95 + set cpo+=! + " 2 <CR>, 1: for executing the command, + " 2: clear hit-enter-prompt + call feedkeys("!!\n", 'tx') + call feedkeys(":!echo one\n\n", 'tx') + call feedkeys(".", 'tx') + call assert_equal('one', getline('.')) + set cpo-=! + bw! +endfunc + +func! Test_normal05_formatexpr() + " basic formatexpr test + call Setup_NewWindow() + %d_ + call setline(1, ['here: 1 ', '2', 'here: 3 ', '4', 'not here: ']) + 1 + set formatexpr=MyFormatExpr() + norm! gqG + call assert_equal(['here: 1->$', '2', 'here: 3->$', '4', 'not here: '], getline(1,'$')) + set formatexpr= + bw! +endfunc + +func Test_normal05_formatexpr_newbuf() + " Edit another buffer in the 'formatexpr' function + new + func! Format() + edit another + endfunc + set formatexpr=Format() + norm gqG + bw! + set formatexpr= +endfunc + +func Test_normal05_formatexpr_setopt() + " Change the 'formatexpr' value in the function + new + func! Format() + set formatexpr= + endfunc + set formatexpr=Format() + norm gqG + bw! + set formatexpr= +endfunc + +func! Test_normal06_formatprg() + " basic test for formatprg + " only test on non windows platform + if has('win32') + return + endif + + " uses sed to number non-empty lines + call writefile(['#!/bin/sh', 'sed ''/./=''|sed ''/./{', 'N', 's/\n/ /', '}'''], 'Xsed_format.sh') + call system('chmod +x ./Xsed_format.sh') + let text = ['a', '', 'c', '', ' ', 'd', 'e'] + let expected = ['1 a', '', '3 c', '', '5 ', '6 d', '7 e'] + + 10new + call setline(1, text) + set formatprg=./Xsed_format.sh + norm! gggqG + call assert_equal(expected, getline(1, '$')) + bw! + + 10new + call setline(1, text) + set formatprg=donothing + setlocal formatprg=./Xsed_format.sh + norm! gggqG + call assert_equal(expected, getline(1, '$')) + bw! + + " clean up + set formatprg= + setlocal formatprg= + call delete('Xsed_format.sh') +endfunc + +func! Test_normal07_internalfmt() + " basic test for internal formmatter to textwidth of 12 + let list=range(1,11) + call map(list, 'v:val." "') + 10new + call setline(1, list) + set tw=12 + norm! gggqG + call assert_equal(['1 2 3', '4 5 6', '7 8 9', '10 11 '], getline(1, '$')) + " clean up + set tw=0 + bw! +endfunc + +func! Test_normal08_fold() + " basic tests for foldopen/folddelete + if !has("folding") + return + endif + call Setup_NewWindow() + 50 + setl foldenable fdm=marker + " First fold + norm! V4jzf + " check that folds have been created + call assert_equal(['50/*{{{*/', '51', '52', '53', '54/*}}}*/'], getline(50,54)) + " Second fold + 46 + norm! V10jzf + " check that folds have been created + call assert_equal('46/*{{{*/', getline(46)) + call assert_equal('60/*}}}*/', getline(60)) + norm! k + call assert_equal('45', getline('.')) + norm! j + call assert_equal('46/*{{{*/', getline('.')) + norm! j + call assert_equal('61', getline('.')) + norm! k + " open a fold + norm! Vzo + norm! k + call assert_equal('45', getline('.')) + norm! j + call assert_equal('46/*{{{*/', getline('.')) + norm! j + call assert_equal('47', getline('.')) + norm! k + norm! zcVzO + call assert_equal('46/*{{{*/', getline('.')) + norm! j + call assert_equal('47', getline('.')) + norm! j + call assert_equal('48', getline('.')) + norm! j + call assert_equal('49', getline('.')) + norm! j + call assert_equal('50/*{{{*/', getline('.')) + norm! j + call assert_equal('51', getline('.')) + " delete folds + :46 + " collapse fold + norm! V14jzC + " delete all folds recursively + norm! VzD + call assert_equal(['46', '47', '48', '49', '50', '51', '52', '53', '54', '55', '56', '57', '58', '59', '60'], getline(46,60)) + + " clean up + setl nofoldenable fdm=marker + bw! +endfunc + +func! Test_normal09_operatorfunc() + " Test operatorfunc + call Setup_NewWindow() + " Add some spaces for counting + 50,60s/$/ / + unlet! g:a + let g:a=0 + nmap <buffer><silent> ,, :set opfunc=CountSpaces<CR>g@ + vmap <buffer><silent> ,, :<C-U>call CountSpaces(visualmode(), 1)<CR> + 50 + norm V2j,, + call assert_equal(6, g:a) + norm V,, + call assert_equal(2, g:a) + norm ,,l + call assert_equal(0, g:a) + 50 + exe "norm 0\<c-v>10j2l,," + call assert_equal(11, g:a) + 50 + norm V10j,, + call assert_equal(22, g:a) + + " clean up + unmap <buffer> ,, + set opfunc= + unlet! g:a + bw! +endfunc + +func! Test_normal09a_operatorfunc() + " Test operatorfunc + call Setup_NewWindow() + " Add some spaces for counting + 50,60s/$/ / + unlet! g:opt + set linebreak + nmap <buffer><silent> ,, :set opfunc=OpfuncDummy<CR>g@ + 50 + norm ,,j + exe "bd!" g:bufnr + call assert_true(&linebreak) + call assert_equal(g:opt, &linebreak) + set nolinebreak + norm ,,j + exe "bd!" g:bufnr + call assert_false(&linebreak) + call assert_equal(g:opt, &linebreak) + + " clean up + unmap <buffer> ,, + set opfunc= + bw! + unlet! g:opt +endfunc + +func! Test_normal10_expand() + " Test for expand() + 10new + call setline(1, ['1', 'ifooar,,cbar']) + 2 + norm! $ + let a=expand('<cword>') + let b=expand('<cWORD>') + call assert_equal('cbar', a) + call assert_equal('ifooar,,cbar', b) + " clean up + bw! +endfunc + +func! Test_normal11_showcmd() + " test for 'showcmd' + 10new + exe "norm! ofoobar\<esc>" + call assert_equal(2, line('$')) + set showcmd + exe "norm! ofoobar2\<esc>" + call assert_equal(3, line('$')) + exe "norm! VAfoobar3\<esc>" + call assert_equal(3, line('$')) + exe "norm! 0d3\<del>2l" + call assert_equal('obar2foobar3', getline('.')) + bw! +endfunc + +func! Test_normal12_nv_error() + " Test for nv_error + 10new + call setline(1, range(1,5)) + " should not do anything, just beep + exe "norm! <c-k>" + call assert_equal(map(range(1,5), 'string(v:val)'), getline(1,'$')) + bw! +endfunc + +func! Test_normal13_help() + " Test for F1 + call assert_equal(1, winnr()) + call feedkeys("\<f1>", 'txi') + call assert_match('help\.txt', bufname('%')) + call assert_equal(2, winnr('$')) + bw! +endfunc + +func! Test_normal14_page() + " basic test for Ctrl-F and Ctrl-B + call Setup_NewWindow() + exe "norm! \<c-f>" + call assert_equal('9', getline('.')) + exe "norm! 2\<c-f>" + call assert_equal('25', getline('.')) + exe "norm! 2\<c-b>" + call assert_equal('18', getline('.')) + 1 + set scrolloff=5 + exe "norm! 2\<c-f>" + call assert_equal('21', getline('.')) + exe "norm! \<c-b>" + call assert_equal('13', getline('.')) + 1 + set scrolloff=99 + exe "norm! \<c-f>" + call assert_equal('13', getline('.')) + set scrolloff=0 + 100 + exe "norm! $\<c-b>" + call assert_equal('92', getline('.')) + call assert_equal([0, 92, 1, 0, 1], getcurpos()) + 100 + set nostartofline + exe "norm! $\<c-b>" + call assert_equal('92', getline('.')) + call assert_equal([0, 92, 2, 0, 2147483647], getcurpos()) + " cleanup + set startofline + bw! +endfunc + +func! Test_normal14_page_eol() + 10new + norm oxxxxxxx + exe "norm 2\<c-f>" + " check with valgrind that cursor is put back in column 1 + exe "norm 2\<c-b>" + bw! +endfunc + +func! Test_normal15_z_scroll_vert() + " basic test for z commands that scroll the window + call Setup_NewWindow() + 100 + norm! >> + " Test for z<cr> + exe "norm! z\<cr>" + call assert_equal(' 100', getline('.')) + call assert_equal(100, winsaveview()['topline']) + call assert_equal([0, 100, 2, 0, 9], getcurpos()) + + " Test for zt + 21 + norm! >>0zt + call assert_equal(' 21', getline('.')) + call assert_equal(21, winsaveview()['topline']) + call assert_equal([0, 21, 1, 0, 8], getcurpos()) + + " Test for zb + 30 + norm! >>$ztzb + call assert_equal(' 30', getline('.')) + call assert_equal(30, winsaveview()['topline']+winheight(0)-1) + call assert_equal([0, 30, 3, 0, 2147483647], getcurpos()) + + " Test for z- + 1 + 30 + norm! 0z- + call assert_equal(' 30', getline('.')) + call assert_equal(30, winsaveview()['topline']+winheight(0)-1) + call assert_equal([0, 30, 2, 0, 9], getcurpos()) + + " Test for z{height}<cr> + call assert_equal(10, winheight(0)) + exe "norm! z12\<cr>" + call assert_equal(12, winheight(0)) + exe "norm! z10\<cr>" + call assert_equal(10, winheight(0)) + + " Test for z. + 1 + 21 + norm! 0z. + call assert_equal(' 21', getline('.')) + call assert_equal(17, winsaveview()['topline']) + call assert_equal([0, 21, 2, 0, 9], getcurpos()) + + " Test for zz + 1 + 21 + norm! 0zz + call assert_equal(' 21', getline('.')) + call assert_equal(17, winsaveview()['topline']) + call assert_equal([0, 21, 1, 0, 8], getcurpos()) + + " Test for z+ + 11 + norm! zt + norm! z+ + call assert_equal(' 21', getline('.')) + call assert_equal(21, winsaveview()['topline']) + call assert_equal([0, 21, 2, 0, 9], getcurpos()) + + " Test for [count]z+ + 1 + norm! 21z+ + call assert_equal(' 21', getline('.')) + call assert_equal(21, winsaveview()['topline']) + call assert_equal([0, 21, 2, 0, 9], getcurpos()) + + " Test for z^ + norm! 22z+0 + norm! z^ + call assert_equal(' 21', getline('.')) + call assert_equal(12, winsaveview()['topline']) + call assert_equal([0, 21, 2, 0, 9], getcurpos()) + + " Test for [count]z^ + 1 + norm! 30z^ + call assert_equal(' 21', getline('.')) + call assert_equal(12, winsaveview()['topline']) + call assert_equal([0, 21, 2, 0, 9], getcurpos()) + + " cleanup + bw! +endfunc + +func! Test_normal16_z_scroll_hor() + " basic test for z commands that scroll the window + 10new + 15vsp + set nowrap listchars= + let lineA='abcdefghijklmnopqrstuvwxyz' + let lineB='0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ' + $put =lineA + $put =lineB + 1d + + " Test for zl + 1 + norm! 5zl + call assert_equal(lineA, getline('.')) + call assert_equal(6, col('.')) + call assert_equal(5, winsaveview()['leftcol']) + norm! yl + call assert_equal('f', @0) + + " Test for zh + norm! 2zh + call assert_equal(lineA, getline('.')) + call assert_equal(6, col('.')) + norm! yl + call assert_equal('f', @0) + call assert_equal(3, winsaveview()['leftcol']) + + " Test for zL + norm! zL + call assert_equal(11, col('.')) + norm! yl + call assert_equal('k', @0) + call assert_equal(10, winsaveview()['leftcol']) + norm! 2zL + call assert_equal(25, col('.')) + norm! yl + call assert_equal('y', @0) + call assert_equal(24, winsaveview()['leftcol']) + + " Test for zH + norm! 2zH + call assert_equal(25, col('.')) + call assert_equal(10, winsaveview()['leftcol']) + norm! yl + call assert_equal('y', @0) + + " Test for zs + norm! $zs + call assert_equal(26, col('.')) + call assert_equal(25, winsaveview()['leftcol']) + norm! yl + call assert_equal('z', @0) + + " Test for ze + norm! ze + call assert_equal(26, col('.')) + call assert_equal(11, winsaveview()['leftcol']) + norm! yl + call assert_equal('z', @0) + + " cleanup + set wrap listchars=eol:$ + bw! +endfunc + +func! Test_normal17_z_scroll_hor2() + " basic test for z commands that scroll the window + " using 'sidescrolloff' setting + 10new + 20vsp + set nowrap listchars= sidescrolloff=5 + let lineA='abcdefghijklmnopqrstuvwxyz' + let lineB='0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ' + $put =lineA + $put =lineB + 1d + + " Test for zl + 1 + norm! 5zl + call assert_equal(lineA, getline('.')) + call assert_equal(11, col('.')) + call assert_equal(5, winsaveview()['leftcol']) + norm! yl + call assert_equal('k', @0) + + " Test for zh + norm! 2zh + call assert_equal(lineA, getline('.')) + call assert_equal(11, col('.')) + norm! yl + call assert_equal('k', @0) + call assert_equal(3, winsaveview()['leftcol']) + + " Test for zL + norm! 0zL + call assert_equal(16, col('.')) + norm! yl + call assert_equal('p', @0) + call assert_equal(10, winsaveview()['leftcol']) + norm! 2zL + call assert_equal(26, col('.')) + norm! yl + call assert_equal('z', @0) + call assert_equal(15, winsaveview()['leftcol']) + + " Test for zH + norm! 2zH + call assert_equal(15, col('.')) + call assert_equal(0, winsaveview()['leftcol']) + norm! yl + call assert_equal('o', @0) + + " Test for zs + norm! $zs + call assert_equal(26, col('.')) + call assert_equal(20, winsaveview()['leftcol']) + norm! yl + call assert_equal('z', @0) + + " Test for ze + norm! ze + call assert_equal(26, col('.')) + call assert_equal(11, winsaveview()['leftcol']) + norm! yl + call assert_equal('z', @0) + + " cleanup + set wrap listchars=eol:$ sidescrolloff=0 + bw! +endfunc + +func! Test_normal18_z_fold() + " basic tests for foldopen/folddelete + if !has("folding") + return + endif + call Setup_NewWindow() + 50 + setl foldenable fdm=marker foldlevel=5 + + " Test for zF + " First fold + norm! 4zF + " check that folds have been created + call assert_equal(['50/*{{{*/', '51', '52', '53/*}}}*/'], getline(50,53)) + + " Test for zd + 51 + norm! 2zF + call assert_equal(2, foldlevel('.')) + norm! kzd + call assert_equal(['50', '51/*{{{*/', '52/*}}}*/', '53'], getline(50,53)) + norm! j + call assert_equal(1, foldlevel('.')) + + " Test for zD + " also deletes partially selected folds recursively + 51 + norm! zF + call assert_equal(2, foldlevel('.')) + norm! kV2jzD + call assert_equal(['50', '51', '52', '53'], getline(50,53)) + + " Test for zE + 85 + norm! 4zF + 86 + norm! 2zF + 90 + norm! 4zF + call assert_equal(['85/*{{{*/', '86/*{{{*/', '87/*}}}*/', '88/*}}}*/', '89', '90/*{{{*/', '91', '92', '93/*}}}*/'], getline(85,93)) + norm! zE + call assert_equal(['85', '86', '87', '88', '89', '90', '91', '92', '93'], getline(85,93)) + + " Test for zn + 50 + set foldlevel=0 + norm! 2zF + norm! zn + norm! k + call assert_equal('49', getline('.')) + norm! j + call assert_equal('50/*{{{*/', getline('.')) + norm! j + call assert_equal('51/*}}}*/', getline('.')) + norm! j + call assert_equal('52', getline('.')) + call assert_equal(0, &foldenable) + + " Test for zN + 49 + norm! zN + call assert_equal('49', getline('.')) + norm! j + call assert_equal('50/*{{{*/', getline('.')) + norm! j + call assert_equal('52', getline('.')) + call assert_equal(1, &foldenable) + + " Test for zi + norm! zi + call assert_equal(0, &foldenable) + norm! zi + call assert_equal(1, &foldenable) + norm! zi + call assert_equal(0, &foldenable) + norm! zi + call assert_equal(1, &foldenable) + + " Test for za + 50 + norm! za + norm! k + call assert_equal('49', getline('.')) + norm! j + call assert_equal('50/*{{{*/', getline('.')) + norm! j + call assert_equal('51/*}}}*/', getline('.')) + norm! j + call assert_equal('52', getline('.')) + 50 + norm! za + norm! k + call assert_equal('49', getline('.')) + norm! j + call assert_equal('50/*{{{*/', getline('.')) + norm! j + call assert_equal('52', getline('.')) + + 49 + norm! 5zF + norm! k + call assert_equal('48', getline('.')) + norm! j + call assert_equal('49/*{{{*/', getline('.')) + norm! j + call assert_equal('55', getline('.')) + 49 + norm! za + call assert_equal('49/*{{{*/', getline('.')) + norm! j + call assert_equal('50/*{{{*/', getline('.')) + norm! j + call assert_equal('52', getline('.')) + set nofoldenable + " close fold and set foldenable + norm! za + call assert_equal(1, &foldenable) + + 50 + " have to use {count}za to open all folds and make the cursor visible + norm! 2za + norm! 2k + call assert_equal('48', getline('.')) + norm! j + call assert_equal('49/*{{{*/', getline('.')) + norm! j + call assert_equal('50/*{{{*/', getline('.')) + norm! j + call assert_equal('51/*}}}*/', getline('.')) + norm! j + call assert_equal('52', getline('.')) + + " Test for zA + 49 + set foldlevel=0 + 50 + norm! zA + norm! 2k + call assert_equal('48', getline('.')) + norm! j + call assert_equal('49/*{{{*/', getline('.')) + norm! j + call assert_equal('50/*{{{*/', getline('.')) + norm! j + call assert_equal('51/*}}}*/', getline('.')) + norm! j + call assert_equal('52', getline('.')) + + " zA on a opened fold when foldenale is not set + 50 + set nofoldenable + norm! zA + call assert_equal(1, &foldenable) + norm! k + call assert_equal('48', getline('.')) + norm! j + call assert_equal('49/*{{{*/', getline('.')) + norm! j + call assert_equal('55', getline('.')) + + " Test for zc + norm! zE + 50 + norm! 2zF + 49 + norm! 5zF + set nofoldenable + 50 + " There most likely is a bug somewhere: + " https://groups.google.com/d/msg/vim_dev/v2EkfJ_KQjI/u-Cvv94uCAAJ + " TODO: Should this only close the inner most fold or both folds? + norm! zc + call assert_equal(1, &foldenable) + norm! k + call assert_equal('48', getline('.')) + norm! j + call assert_equal('49/*{{{*/', getline('.')) + norm! j + call assert_equal('55', getline('.')) + set nofoldenable + 50 + norm! Vjzc + norm! k + call assert_equal('48', getline('.')) + norm! j + call assert_equal('49/*{{{*/', getline('.')) + norm! j + call assert_equal('55', getline('.')) + + " Test for zC + set nofoldenable + 50 + norm! zCk + call assert_equal('48', getline('.')) + norm! j + call assert_equal('49/*{{{*/', getline('.')) + norm! j + call assert_equal('55', getline('.')) + + " Test for zx + " 1) close folds at line 49-54 + set nofoldenable + 48 + norm! zx + call assert_equal(1, &foldenable) + norm! j + call assert_equal('49/*{{{*/', getline('.')) + norm! j + call assert_equal('55', getline('.')) + + " 2) do not close fold under curser + 51 + set nofoldenable + norm! zx + call assert_equal(1, &foldenable) + norm! 3k + call assert_equal('48', getline('.')) + norm! j + call assert_equal('49/*{{{*/', getline('.')) + norm! j + call assert_equal('50/*{{{*/', getline('.')) + norm! j + call assert_equal('51/*}}}*/', getline('.')) + norm! j + call assert_equal('52', getline('.')) + norm! j + call assert_equal('53', getline('.')) + norm! j + call assert_equal('54/*}}}*/', getline('.')) + norm! j + call assert_equal('55', getline('.')) + + " 3) close one level of folds + 48 + set nofoldenable + set foldlevel=1 + norm! zx + call assert_equal(1, &foldenable) + call assert_equal('48', getline('.')) + norm! j + call assert_equal('49/*{{{*/', getline('.')) + norm! j + call assert_equal('50/*{{{*/', getline('.')) + norm! j + call assert_equal('52', getline('.')) + norm! j + call assert_equal('53', getline('.')) + norm! j + call assert_equal('54/*}}}*/', getline('.')) + norm! j + call assert_equal('55', getline('.')) + + " Test for zX + " Close all folds + set foldlevel=0 nofoldenable + 50 + norm! zX + call assert_equal(1, &foldenable) + norm! k + call assert_equal('48', getline('.')) + norm! j + call assert_equal('49/*{{{*/', getline('.')) + norm! j + call assert_equal('55', getline('.')) + + " Test for zm + 50 + set nofoldenable foldlevel=2 + norm! zm + call assert_equal(1, &foldenable) + call assert_equal(1, &foldlevel) + norm! zm + call assert_equal(0, &foldlevel) + norm! zm + call assert_equal(0, &foldlevel) + norm! k + call assert_equal('48', getline('.')) + norm! j + call assert_equal('49/*{{{*/', getline('.')) + norm! j + call assert_equal('55', getline('.')) + + " Test for zM + 48 + set nofoldenable foldlevel=99 + norm! zM + call assert_equal(1, &foldenable) + call assert_equal(0, &foldlevel) + call assert_equal('48', getline('.')) + norm! j + call assert_equal('49/*{{{*/', getline('.')) + norm! j + call assert_equal('55', getline('.')) + + " Test for zr + 48 + set nofoldenable foldlevel=0 + norm! zr + call assert_equal(0, &foldenable) + call assert_equal(1, &foldlevel) + set foldlevel=0 foldenable + norm! zr + call assert_equal(1, &foldenable) + call assert_equal(1, &foldlevel) + norm! zr + call assert_equal(2, &foldlevel) + call assert_equal('48', getline('.')) + norm! j + call assert_equal('49/*{{{*/', getline('.')) + norm! j + call assert_equal('50/*{{{*/', getline('.')) + norm! j + call assert_equal('51/*}}}*/', getline('.')) + norm! j + call assert_equal('52', getline('.')) + + " Test for zR + 48 + set nofoldenable foldlevel=0 + norm! zR + call assert_equal(0, &foldenable) + call assert_equal(2, &foldlevel) + set foldenable foldlevel=0 + norm! zR + call assert_equal(1, &foldenable) + call assert_equal(2, &foldlevel) + call assert_equal('48', getline('.')) + norm! j + call assert_equal('49/*{{{*/', getline('.')) + norm! j + call assert_equal('50/*{{{*/', getline('.')) + norm! j + call assert_equal('51/*}}}*/', getline('.')) + norm! j + call assert_equal('52', getline('.')) + call append(50, ['a /*{{{*/', 'b /*}}}*/']) + 48 + call assert_equal('48', getline('.')) + norm! j + call assert_equal('49/*{{{*/', getline('.')) + norm! j + call assert_equal('50/*{{{*/', getline('.')) + norm! j + call assert_equal('a /*{{{*/', getline('.')) + norm! j + call assert_equal('51/*}}}*/', getline('.')) + norm! j + call assert_equal('52', getline('.')) + 48 + norm! zR + call assert_equal(1, &foldenable) + call assert_equal(3, &foldlevel) + call assert_equal('48', getline('.')) + norm! j + call assert_equal('49/*{{{*/', getline('.')) + norm! j + call assert_equal('50/*{{{*/', getline('.')) + norm! j + call assert_equal('a /*{{{*/', getline('.')) + norm! j + call assert_equal('b /*}}}*/', getline('.')) + norm! j + call assert_equal('51/*}}}*/', getline('.')) + norm! j + call assert_equal('52', getline('.')) + + " clean up + setl nofoldenable fdm=marker foldlevel=0 + bw! +endfunc + +func! Test_normal19_z_spell() + throw "skipped: Nvim 'spell' requires download" + if !has("spell") || !has('syntax') + return + endif + new + call append(0, ['1 good', '2 goood', '3 goood']) + set spell spellfile=./Xspellfile.add spelllang=en + let oldlang=v:lang + lang C + + " Test for zg + 1 + norm! ]s + call assert_equal('2 goood', getline('.')) + norm! zg + 1 + let a=execute('unsilent :norm! ]s') + call assert_equal('1 good', getline('.')) + call assert_equal('search hit BOTTOM, continuing at TOP', a[1:]) + let cnt=readfile('./Xspellfile.add') + call assert_equal('goood', cnt[0]) + + " Test for zw + 2 + norm! $zw + 1 + norm! ]s + call assert_equal('2 goood', getline('.')) + let cnt=readfile('./Xspellfile.add') + call assert_equal('#oood', cnt[0]) + call assert_equal('goood/!', cnt[1]) + + " Test for zg in visual mode + let a=execute('unsilent :norm! V$zg') + call assert_equal("Word '2 goood' added to ./Xspellfile.add", a[1:]) + 1 + norm! ]s + call assert_equal('3 goood', getline('.')) + let cnt=readfile('./Xspellfile.add') + call assert_equal('2 goood', cnt[2]) + " Remove "2 good" from spellfile + 2 + let a=execute('unsilent norm! V$zw') + call assert_equal("Word '2 goood' added to ./Xspellfile.add", a[1:]) + let cnt=readfile('./Xspellfile.add') + call assert_equal('2 goood/!', cnt[3]) + + " Test for zG + let a=execute('unsilent norm! V$zG') + call assert_match("Word '2 goood' added to .*", a) + let fname=matchstr(a, 'to\s\+\zs\f\+$') + let cnt=readfile(fname) + call assert_equal('2 goood', cnt[0]) + + " Test for zW + let a=execute('unsilent norm! V$zW') + call assert_match("Word '2 goood' added to .*", a) + let cnt=readfile(fname) + call assert_equal('# goood', cnt[0]) + call assert_equal('2 goood/!', cnt[1]) + + " Test for zuW + let a=execute('unsilent norm! V$zuW') + call assert_match("Word '2 goood' removed from .*", a) + let cnt=readfile(fname) + call assert_equal('# goood', cnt[0]) + call assert_equal('# goood/!', cnt[1]) + + " Test for zuG + let a=execute('unsilent norm! $zG') + call assert_match("Word 'goood' added to .*", a) + let cnt=readfile(fname) + call assert_equal('# goood', cnt[0]) + call assert_equal('# goood/!', cnt[1]) + call assert_equal('goood', cnt[2]) + let a=execute('unsilent norm! $zuG') + let cnt=readfile(fname) + call assert_match("Word 'goood' removed from .*", a) + call assert_equal('# goood', cnt[0]) + call assert_equal('# goood/!', cnt[1]) + call assert_equal('#oood', cnt[2]) + " word not found in wordlist + let a=execute('unsilent norm! V$zuG') + let cnt=readfile(fname) + call assert_match("", a) + call assert_equal('# goood', cnt[0]) + call assert_equal('# goood/!', cnt[1]) + call assert_equal('#oood', cnt[2]) + + " Test for zug + call delete('./Xspellfile.add') + 2 + let a=execute('unsilent norm! $zg') + let cnt=readfile('./Xspellfile.add') + call assert_equal('goood', cnt[0]) + let a=execute('unsilent norm! $zug') + call assert_match("Word 'goood' removed from \./Xspellfile.add", a) + let cnt=readfile('./Xspellfile.add') + call assert_equal('#oood', cnt[0]) + " word not in wordlist + let a=execute('unsilent norm! V$zug') + call assert_match('', a) + let cnt=readfile('./Xspellfile.add') + call assert_equal('#oood', cnt[0]) + + " Test for zuw + call delete('./Xspellfile.add') + 2 + let a=execute('unsilent norm! Vzw') + let cnt=readfile('./Xspellfile.add') + call assert_equal('2 goood/!', cnt[0]) + let a=execute('unsilent norm! Vzuw') + call assert_match("Word '2 goood' removed from \./Xspellfile.add", a) + let cnt=readfile('./Xspellfile.add') + call assert_equal('# goood/!', cnt[0]) + " word not in wordlist + let a=execute('unsilent norm! $zug') + call assert_match('', a) + let cnt=readfile('./Xspellfile.add') + call assert_equal('# goood/!', cnt[0]) + + " add second entry to spellfile setting + set spellfile=./Xspellfile.add,./Xspellfile2.add + call delete('./Xspellfile.add') + 2 + let a=execute('unsilent norm! $2zg') + let cnt=readfile('./Xspellfile2.add') + call assert_match("Word 'goood' added to ./Xspellfile2.add", a) + call assert_equal('goood', cnt[0]) + + " clean up + exe "lang" oldlang + call delete("./Xspellfile.add") + call delete("./Xspellfile2.add") + call delete("./Xspellfile.add.spl") + call delete("./Xspellfile2.add.spl") + + " zux -> no-op + 2 + norm! $zux + call assert_equal([], glob('Xspellfile.add',0,1)) + call assert_equal([], glob('Xspellfile2.add',0,1)) + + set spellfile= + bw! +endfunc + +func! Test_normal20_exmode() + if !has("unix") + " Reading from redirected file doesn't work on MS-Windows + return + endif + call writefile(['1a', 'foo', 'bar', '.', 'w! Xfile2', 'q!'], 'Xscript') + call writefile(['1', '2'], 'Xfile') + call system(v:progpath .' -e -s < Xscript Xfile') + let a=readfile('Xfile2') + call assert_equal(['1', 'foo', 'bar', '2'], a) + + " clean up + for file in ['Xfile', 'Xfile2', 'Xscript'] + call delete(file) + endfor + 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! +endfunc + +func! Test_normal22_zet() + " Test for ZZ + " let shell = &shell + " let &shell = 'sh' + + " Remove any stale test files from previous run. + for file in ['Xfile_Test_normal22_zet'] + call delete(file) + endfor + + call writefile(['1', '2'], 'Xfile_Test_normal22_zet') + let args = ' --headless -u NONE -N -U NONE -i NONE --noplugins' + call system(v:progpath . args . ' -c "%d" -c ":norm! ZZ" Xfile_Test_normal22_zet') + let a = readfile('Xfile_Test_normal22_zet') + call assert_equal([], a) + " Test for ZQ + call writefile(['1', '2'], 'Xfile_Test_normal22_zet') + call system(v:progpath . args . ' -c "%d" -c ":norm! ZQ" Xfile_Test_normal22_zet') + let a = readfile('Xfile_Test_normal22_zet') + call assert_equal(['1', '2'], a) + + " Nvim: This sometimes hangs the TSAN build. + " for file in ['Xfile_Test_normal22_zet'] + " call delete(file) + " endfor + " let &shell = shell +endfunc + +func! Test_normal23_K() + " Test for K command + new + call append(0, ['helphelp.txt', 'man', 'aa%bb', 'cc|dd']) + let k = &keywordprg + set keywordprg=:help + 1 + norm! VK + call assert_equal('helphelp.txt', fnamemodify(bufname('%'), ':t')) + call assert_equal('help', &ft) + call assert_match('\*helphelp.txt\*', getline('.')) + helpclose + norm! 0K + call assert_equal('helphelp.txt', fnamemodify(bufname('%'), ':t')) + call assert_equal('help', &ft) + call assert_match('Help on help files', getline('.')) + helpclose + + set keywordprg=:new + set iskeyword+=% + set iskeyword+=\| + 2 + norm! K + call assert_equal('man', fnamemodify(bufname('%'), ':t')) + bwipe! + 3 + norm! K + call assert_equal('aa%bb', fnamemodify(bufname('%'), ':t')) + bwipe! + if !has('win32') + 4 + norm! K + call assert_equal('cc|dd', fnamemodify(bufname('%'), ':t')) + bwipe! + endif + set iskeyword-=% + set iskeyword-=\| + + " Only expect "man" to work on Unix + if !has("unix") + let &keywordprg = k + bw! + return + endif + set keywordprg=man\ --pager=cat + " Test for using man + 2 + let a = execute('unsilent norm! K') + call assert_match("man --pager=cat 'man'", a) + + " clean up + let &keywordprg = k + bw! +endfunc + +func! Test_normal24_rot13() + " This test uses multi byte characters + if !has("multi_byte") + return + endif + " Testing for g?? g?g? + new + call append(0, 'abcdefghijklmnopqrstuvwxyzäüö') + 1 + norm! g?? + call assert_equal('nopqrstuvwxyzabcdefghijklmäüö', getline('.')) + norm! g?g? + call assert_equal('abcdefghijklmnopqrstuvwxyzäüö', getline('.')) + + " clean up + bw! +endfunc + +func! Test_normal25_tag() + " Testing for CTRL-] g CTRL-] g] + " CTRL-W g] CTRL-W CTRL-] CTRL-W g CTRL-] + h + " Test for CTRL-] + call search('\<x\>$') + exe "norm! \<c-]>" + call assert_equal("change.txt", fnamemodify(bufname('%'), ':t')) + norm! yiW + call assert_equal("*x*", @0) + exe ":norm \<c-o>" + + " Test for g_CTRL-] + call search('\<v_u\>$') + exe "norm! g\<c-]>" + call assert_equal("change.txt", fnamemodify(bufname('%'), ':t')) + norm! yiW + call assert_equal("*v_u*", @0) + exe ":norm \<c-o>" + + " Test for g] + call search('\<i_<Esc>$') + let a = execute(":norm! g]") + call assert_match('i_<Esc>.*insert.txt', a) + + if !empty(exepath('cscope')) && has('cscope') + " setting cscopetag changes how g] works + set cst + exe "norm! g]" + call assert_equal("insert.txt", fnamemodify(bufname('%'), ':t')) + norm! yiW + call assert_equal("*i_<Esc>*", @0) + exe ":norm \<c-o>" + " Test for CTRL-W g] + exe "norm! \<C-W>g]" + call assert_equal("insert.txt", fnamemodify(bufname('%'), ':t')) + norm! yiW + call assert_equal("*i_<Esc>*", @0) + call assert_equal(3, winnr('$')) + helpclose + set nocst + endif + + " Test for CTRL-W g] + let a = execute("norm! \<C-W>g]") + call assert_match('i_<Esc>.*insert.txt', a) + + " Test for CTRL-W CTRL-] + exe "norm! \<C-W>\<C-]>" + call assert_equal("insert.txt", fnamemodify(bufname('%'), ':t')) + norm! yiW + call assert_equal("*i_<Esc>*", @0) + call assert_equal(3, winnr('$')) + helpclose + + " Test for CTRL-W g CTRL-] + exe "norm! \<C-W>g\<C-]>" + call assert_equal("insert.txt", fnamemodify(bufname('%'), ':t')) + norm! yiW + call assert_equal("*i_<Esc>*", @0) + call assert_equal(3, winnr('$')) + helpclose + + " clean up + helpclose +endfunc + +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']) + 1 + /Error/y a + 2 + norm! "a]pj"a[p + call assert_equal(['do', "echo 'Error writing file'", " echo 'Error writing file'", ' ((count++))'], getline(2,5)) + 1 + /^\s\{4}/ + exe "norm! \"a]P3Eldt'" + exe "norm! j\"a[P2Eldt'" + call assert_equal([' if [ $? -ne 0 ]; then', " echo 'Error writing'", " echo 'Error'", " echo 'Error writing file'", ' fi'], getline(6,10)) + + " clean up + bw! +endfunc + +func! Test_normal27_bracket() + " Test for [' [` ]' ]` + call Setup_NewWindow() + 1,21s/.\+/ & b/ + 1 + norm! $ma + 5 + norm! $mb + 10 + norm! $mc + 15 + norm! $md + 20 + norm! $me + + " Test for [' + 9 + norm! 2[' + call assert_equal(' 1 b', getline('.')) + call assert_equal(1, line('.')) + call assert_equal(3, col('.')) + + " Test for ]' + norm! ]' + call assert_equal(' 5 b', getline('.')) + call assert_equal(5, line('.')) + call assert_equal(3, col('.')) + + " No mark after line 21, cursor moves to first non blank on current line + 21 + norm! $]' + call assert_equal(' 21 b', getline('.')) + call assert_equal(21, line('.')) + call assert_equal(3, col('.')) + + " Test for [` + norm! 2[` + call assert_equal(' 15 b', getline('.')) + call assert_equal(15, line('.')) + call assert_equal(8, col('.')) + + " Test for ]` + norm! ]` + call assert_equal(' 20 b', getline('.')) + call assert_equal(20, line('.')) + call assert_equal(8, col('.')) + + " clean up + bw! +endfunc + +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']) + + $ + norm! d( + call assert_equal(['This is a test. With some sentences!', '', 'Even with a question? And one more. ', ''], getline(1, '$')) + norm! 2d( + call assert_equal(['This is a test. With some sentences!', '', ' ', ''], getline(1, '$')) + 1 + norm! 0d) + call assert_equal(['With some sentences!', '', ' ', ''], getline(1, '$')) + + call append('$', ['This is a long sentence', '', 'spanning', 'over several lines. ']) + $ + norm! $d( + call assert_equal(['With some sentences!', '', ' ', '', 'This is a long sentence', ''], getline(1, '$')) + + " clean up + bw! +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 paragaraph', + \ 'unless the ''{'' is set', + \ 'in ''cpoptions''', + \ '}', + \ '.IP', + \ 'The nroff macros IP seperates 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'] + new + call append(0, text) + 1 + norm! 0d2} + call assert_equal(['.IP', + \ 'The nroff macros IP seperates 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,'$')) + 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, '$')) + $ + 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, '$')) + norm! d{ + call assert_equal(['.LPIt does not matter, if afterwards some', 'more characters follow.', ''], getline(1,'$')) + " Test with { in cpooptions + %d + call append(0, text) + " Nvim: no "{" flag in 'cpoptions'. + " set cpo+={ + " 1 + " norm! 0d2} + " call assert_equal(['{', 'This is no paragaraph', 'unless the ''{'' is set', 'in ''cpoptions''', '}', + " \ '.IP', 'The nroff macros IP seperates 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,'$')) + " $ + " norm! d} + " call assert_equal(['{', 'This is no paragaraph', 'unless the ''{'' is set', 'in ''cpoptions''', '}', + " \ '.IP', 'The nroff macros IP seperates 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,'$')) + " norm! gg} + " norm! d5} + " call assert_equal(['{', 'This is no paragaraph', 'unless the ''{'' is set', 'in ''cpoptions''', '}', ''], getline(1,'$')) + + " clean up + set cpo-={ + bw! +endfunc + +fun! Test_normal30_changecase() + " This test uses multi byte characters + if !has("multi_byte") + return + endif + new + call append(0, 'This is a simple test: äüöß') + norm! 1ggVu + call assert_equal('this is a simple test: äüöß', getline('.')) + norm! VU + call assert_equal('THIS IS A SIMPLE TEST: ÄÜÖSS', getline('.')) + norm! guu + call assert_equal('this is a simple test: äüöss', getline('.')) + norm! gUgU + call assert_equal('THIS IS A SIMPLE TEST: ÄÜÖSS', getline('.')) + norm! gugu + call assert_equal('this is a simple test: äüöss', getline('.')) + norm! gUU + call assert_equal('THIS IS A SIMPLE TEST: ÄÜÖSS', getline('.')) + norm! 010~ + call assert_equal('this is a SIMPLE TEST: ÄÜÖSS', getline('.')) + norm! V~ + call assert_equal('THIS IS A simple test: äüöss', getline('.')) + + " Turkish ASCII turns to multi-byte. On some systems Turkish locale + " is available but toupper()/tolower() don't do the right thing. + try + lang tr_TR.UTF-8 + set casemap= + let iupper = toupper('i') + if iupper == "\u0130" + call setline(1, 'iI') + 1normal gUU + call assert_equal("\u0130I", getline(1)) + call assert_equal("\u0130I", toupper("iI")) + + call setline(1, 'iI') + 1normal guu + call assert_equal("i\u0131", getline(1)) + call assert_equal("i\u0131", tolower("iI")) + elseif iupper == "I" + call setline(1, 'iI') + 1normal gUU + call assert_equal("II", getline(1)) + call assert_equal("II", toupper("iI")) + + call setline(1, 'iI') + 1normal guu + call assert_equal("ii", getline(1)) + call assert_equal("ii", tolower("iI")) + else + call assert_true(false, "expected toupper('i') to be either 'I' or '\u0131'") + endif + set casemap& + call setline(1, 'iI') + 1normal gUU + call assert_equal("II", getline(1)) + call assert_equal("II", toupper("iI")) + + call setline(1, 'iI') + 1normal guu + call assert_equal("ii", getline(1)) + call assert_equal("ii", tolower("iI")) + + lang en_US.UTF-8 + catch /E197:/ + " can't use Turkish locale + throw 'Skipped: Turkish locale not available' + endtry + + " clean up + bw! +endfunc + +fun! Test_normal31_r_cmd() + " Test for r command + new + call append(0, 'This is a simple test: abcd') + exe "norm! 1gg$r\<cr>" + call assert_equal(['This is a simple test: abc', '', ''], getline(1,'$')) + exe "norm! 1gg2wlr\<cr>" + call assert_equal(['This is a', 'simple test: abc', '', ''], getline(1,'$')) + exe "norm! 2gg0W5r\<cr>" + call assert_equal(['This is a', 'simple ', ' abc', '', ''], getline('1', '$')) + set autoindent + call setline(2, ['simple test: abc', '']) + exe "norm! 2gg0W5r\<cr>" + call assert_equal(['This is a', 'simple ', 'abc', '', '', ''], getline('1', '$')) + exe "norm! 1ggVr\<cr>" + call assert_equal('^M^M^M^M^M^M^M^M^M', strtrans(getline(1))) + call setline(1, 'This is a') + exe "norm! 1gg05rf" + call assert_equal('fffffis a', getline(1)) + + " clean up + set noautoindent + bw! +endfunc + +func! Test_normal32_g_cmd1() + " Test for g*, g# + new + call append(0, ['abc.x_foo', 'x_foobar.abc']) + 1 + norm! $g* + call assert_equal('x_foo', @/) + call assert_equal('x_foobar.abc', getline('.')) + norm! $g# + call assert_equal('abc', @/) + call assert_equal('abc.x_foo', getline('.')) + + " clean up + bw! +endfunc + +fun! Test_normal33_g_cmd2() + if !has("jumplist") + return + endif + " Tests for g cmds + call Setup_NewWindow() + " Test for g` + clearjumps + norm! ma10j + let a=execute(':jumps') + " empty jumplist + call assert_equal('>', a[-1:]) + norm! g`a + call assert_equal('>', a[-1:]) + call assert_equal(1, line('.')) + call assert_equal('1', getline('.')) + + " Test for g; and g, + norm! g; + " there is only one change in the changelist + " currently, when we setup the window + call assert_equal(2, line('.')) + call assert_fails(':norm! g;', 'E662') + call assert_fails(':norm! g,', 'E663') + let &ul=&ul + call append('$', ['a', 'b', 'c', 'd']) + let &ul=&ul + call append('$', ['Z', 'Y', 'X', 'W']) + let a = execute(':changes') + call assert_match('2\s\+0\s\+2', a) + call assert_match('101\s\+0\s\+a', a) + call assert_match('105\s\+0\s\+Z', a) + norm! 3g; + call assert_equal(2, line('.')) + norm! 2g, + call assert_equal(105, line('.')) + + " Test for g& - global substitute + %d + call setline(1, range(1,10)) + call append('$', ['a', 'b', 'c', 'd']) + $s/\w/&&/g + exe "norm! /[1-8]\<cr>" + norm! g& + call assert_equal(['11', '22', '33', '44', '55', '66', '77', '88', '9', '110', 'a', 'b', 'c', 'dd'], getline(1, '$')) + + " Test for gv + %d + call append('$', repeat(['abcdefgh'], 8)) + exe "norm! 2gg02l\<c-v>2j2ly" + call assert_equal(['cde', 'cde', 'cde'], getreg(0, 1, 1)) + " in visual mode, gv swaps current and last selected region + exe "norm! G0\<c-v>4k4lgvd" + call assert_equal(['', 'abfgh', 'abfgh', 'abfgh', 'abcdefgh', 'abcdefgh', 'abcdefgh', 'abcdefgh', 'abcdefgh'], getline(1,'$')) + exe "norm! G0\<c-v>4k4ly" + exe "norm! gvood" + call assert_equal(['', 'abfgh', 'abfgh', 'abfgh', 'fgh', 'fgh', 'fgh', 'fgh', 'fgh'], getline(1,'$')) + + " Test for gk/gj + %d + 15vsp + set wrap listchars= sbr= + let lineA='abcdefghijklmnopqrstuvwxyz' + let lineB='0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ' + $put =lineA + $put =lineB + + norm! 3gg0dgk + call assert_equal(['', 'abcdefghijklmno', '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ'], getline(1, '$')) + set nu + norm! 3gg0gjdgj + call assert_equal(['', 'abcdefghijklmno', '0123456789AMNOPQRSTUVWXYZ'], getline(1,'$')) + + " Test for gJ + norm! 2gggJ + call assert_equal(['', 'abcdefghijklmno0123456789AMNOPQRSTUVWXYZ'], getline(1,'$')) + call assert_equal(16, col('.')) + " shouldn't do anything + norm! 10gJ + call assert_equal(1, col('.')) + + " Test for g0 g^ gm g$ + exe "norm! 2gg0gji " + call assert_equal(['', 'abcdefghijk lmno0123456789AMNOPQRSTUVWXYZ'], getline(1,'$')) + norm! g0yl + call assert_equal(12, col('.')) + call assert_equal(' ', getreg(0)) + norm! g$yl + call assert_equal(22, col('.')) + call assert_equal('3', getreg(0)) + norm! gmyl + call assert_equal(17, col('.')) + call assert_equal('n', getreg(0)) + norm! g^yl + call assert_equal(15, col('.')) + call assert_equal('l', getreg(0)) + + " Test for g Ctrl-G + set ff=unix + let a=execute(":norm! g\<c-g>") + call assert_match('Col 15 of 43; Line 2 of 2; Word 2 of 2; Byte 16 of 45', a) + + " Test for gI + norm! gIfoo + call assert_equal(['', 'fooabcdefghijk lmno0123456789AMNOPQRSTUVWXYZ'], getline(1,'$')) + + " Test for gi + wincmd c + %d + set tw=0 + call setline(1, ['foobar', 'new line']) + norm! A next word + $put ='third line' + norm! gi another word + call assert_equal(['foobar next word another word', 'new line', 'third line'], getline(1,'$')) + + " clean up + bw! +endfunc + +fun! Test_normal34_g_cmd3() + if !has("multi_byte") + return + endif + " Test for g8 + new + call append(0, 'abcdefghijklmnopqrstuvwxyzäüö') + let a=execute(':norm! 1gg$g8') + call assert_equal('c3 b6 ', a[1:]) + + " Test for gp gP + call append(1, range(1,10)) + " clean up + bw! +endfunc + +fun! Test_normal35_g_cmd4() + " Test for g< + " Cannot capture its output, + " probably a bug, therefore, test disabled: + throw "Skipped: output of g< can't be tested currently" + echo "a\nb\nc\nd" + let b=execute(':norm! g<') + call assert_true(!empty(b), 'failed `execute(g<)`') +endfunc + +fun! Test_normal36_g_cmd5() + new + call append(0, 'abcdefghijklmnopqrstuvwxyz') + set ff=unix + " Test for gp gP + call append(1, range(1,10)) + 1 + norm! 1yy + 3 + norm! gp + call assert_equal([0, 5, 1, 0, 1], getcurpos()) + $ + norm! gP + call assert_equal([0, 14, 1, 0, 1], getcurpos()) + + " Test for go + norm! 26go + call assert_equal([0, 1, 26, 0, 26], getcurpos()) + norm! 27go + call assert_equal([0, 1, 26, 0, 26], getcurpos()) + norm! 28go + call assert_equal([0, 2, 1, 0, 1], getcurpos()) + set ff=dos + norm! 29go + call assert_equal([0, 2, 1, 0, 1], getcurpos()) + set ff=unix + norm! gg0 + norm! 101go + call assert_equal([0, 13, 26, 0, 26], getcurpos()) + norm! 103go + call assert_equal([0, 14, 1, 0, 1], getcurpos()) + " count > buffer content + norm! 120go + call assert_equal([0, 14, 1, 0, 2147483647], getcurpos()) + " clean up + bw! +endfunc + +fun! Test_normal37_g_cmd6() + " basic test for gt and gT + tabnew 1.txt + tabnew 2.txt + tabnew 3.txt + norm! 1gt + call assert_equal(1, tabpagenr()) + norm! 3gt + call assert_equal(3, tabpagenr()) + norm! 1gT + " count gT goes not to the absolute tabpagenumber + " but, but goes to the count previous tabpagenumber + call assert_equal(2, tabpagenr()) + " wrap around + norm! 3gT + call assert_equal(3, tabpagenr()) + " gt does not wrap around + norm! 5gt + call assert_equal(3, tabpagenr()) + + for i in range(3) + tabclose + endfor + " clean up + call assert_fails(':tabclose', 'E784') +endfunc + +fun! Test_normal38_nvhome() + " Test for <Home> and <C-Home> key + new + call setline(1, range(10)) + $ + setl et sw=2 + norm! V10>$ + " count is ignored + exe "norm! 10\<home>" + call assert_equal(1, col('.')) + exe "norm! \<home>" + call assert_equal([0, 10, 1, 0, 1], getcurpos()) + exe "norm! 5\<c-home>" + call assert_equal([0, 5, 1, 0, 1], getcurpos()) + exe "norm! \<c-home>" + call assert_equal([0, 1, 1, 0, 1], getcurpos()) + + " clean up + bw! +endfunc + +fun! Test_normal39_cw() + " Test for cw and cW on whitespace + " and cpo+=w setting + new + set tw=0 + call append(0, 'here are some words') + norm! 1gg0elcwZZZ + call assert_equal('hereZZZare some words', getline('.')) + norm! 1gg0elcWYYY + call assert_equal('hereZZZareYYYsome words', getline('.')) + " Nvim: no "w" flag in 'cpoptions'. + " set cpo+=w + " call setline(1, 'here are some words') + " norm! 1gg0elcwZZZ + " call assert_equal('hereZZZ are some words', getline('.')) + " norm! 1gg2elcWYYY + " call assert_equal('hereZZZ areYYY some words', getline('.')) + set cpo-=w + norm! 2gg0cwfoo + call assert_equal('foo', getline('.')) + + " clean up + bw! +endfunc + +fun! Test_normal40_ctrl_bsl() + " Basic test for CTRL-\ commands + new + call append(0, 'here are some words') + exe "norm! 1gg0a\<C-\>\<C-N>" + call assert_equal('n', mode()) + call assert_equal(1, col('.')) + call assert_equal('', visualmode()) + exe "norm! 1gg0viw\<C-\>\<C-N>" + call assert_equal('n', mode()) + call assert_equal(4, col('.')) + exe "norm! 1gg0a\<C-\>\<C-G>" + call assert_equal('n', mode()) + call assert_equal(1, col('.')) + "imap <buffer> , <c-\><c-n> + set im + exe ":norm! \<c-\>\<c-n>dw" + set noim + call assert_equal('are some words', getline(1)) + call assert_false(&insertmode) + + " clean up + bw! +endfunc + +fun! Test_normal41_insert_reg() + " Test for <c-r>=, <c-r><c-r>= and <c-r><c-o>= + " in insert mode + new + set sts=2 sw=2 ts=8 tw=0 + call append(0, ["aaa\tbbb\tccc", '', '', '']) + let a=getline(1) + norm! 2gg0 + exe "norm! a\<c-r>=a\<cr>" + norm! 3gg0 + exe "norm! a\<c-r>\<c-r>=a\<cr>" + norm! 4gg0 + exe "norm! a\<c-r>\<c-o>=a\<cr>" + call assert_equal(['aaa bbb ccc', 'aaa bbb ccc', 'aaa bbb ccc', 'aaa bbb ccc', ''], getline(1, '$')) + + " clean up + set sts=0 sw=8 ts=8 + bw! +endfunc + +func! Test_normal42_halfpage() + " basic test for Ctrl-D and Ctrl-U + call Setup_NewWindow() + call assert_equal(5, &scroll) + exe "norm! \<c-d>" + call assert_equal('6', getline('.')) + exe "norm! 2\<c-d>" + call assert_equal('8', getline('.')) + call assert_equal(2, &scroll) + set scroll=5 + exe "norm! \<c-u>" + call assert_equal('3', getline('.')) + 1 + set scrolloff=5 + exe "norm! \<c-d>" + call assert_equal('10', getline('.')) + exe "norm! \<c-u>" + call assert_equal('5', getline('.')) + 1 + set scrolloff=99 + exe "norm! \<c-d>" + call assert_equal('10', getline('.')) + set scrolloff=0 + 100 + exe "norm! $\<c-u>" + call assert_equal('95', getline('.')) + call assert_equal([0, 95, 1, 0, 1], getcurpos()) + 100 + set nostartofline + exe "norm! $\<c-u>" + call assert_equal('95', getline('.')) + call assert_equal([0, 95, 2, 0, 2147483647], getcurpos()) + " cleanup + set startofline + bw! +endfunc + +fun! Test_normal43_textobject1() + " basic tests for text object aw + new + call append(0, ['foobar,eins,foobar', 'foo,zwei,foo ']) + " diw + norm! 1gg0diw + call assert_equal([',eins,foobar', 'foo,zwei,foo ', ''], getline(1,'$')) + " daw + norm! 2ggEdaw + call assert_equal([',eins,foobar', 'foo,zwei,', ''], getline(1, '$')) + %d + call append(0, ["foo\teins\tfoobar", "foo\tzwei\tfoo "]) + " diW + norm! 2ggwd2iW + call assert_equal(['foo eins foobar', 'foo foo ', ''], getline(1,'$')) + " daW + norm! 1ggd2aW + call assert_equal(['foobar', 'foo foo ', ''], getline(1,'$')) + + %d + call append(0, ["foo\teins\tfoobar", "foo\tzwei\tfoo "]) + " aw in visual line mode switches to characterwise mode + norm! 2gg$Vawd + call assert_equal(['foo eins foobar', 'foo zwei foo'], getline(1,'$')) + norm! 1gg$Viwd + call assert_equal(['foo eins ', 'foo zwei foo'], getline(1,'$')) + + " clean up + bw! +endfunc + +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']) + " Test for dis - does not remove trailing whitespace + norm! 1gg0dis + call assert_equal([' With some sentences!', '', 'Even with a question? And one more. And no sentence here', ''], getline(1,'$')) + " Test for das - removes leading whitespace + norm! 3ggf?ldas + call assert_equal([' With some sentences!', '', 'Even with a question? And no sentence here', ''], getline(1,'$')) + " when used in visual mode, is made characterwise + norm! 3gg$Visy + call assert_equal('v', visualmode()) + " reset visualmode() + norm! 3ggVy + norm! 3gg$Vasy + call assert_equal('v', visualmode()) + " basic testing for textobjects a< and at + %d + call setline(1, ['<div> ','<a href="foobar" class="foo">xyz</a>',' </div>', ' ']) + " a< + norm! 1gg0da< + call assert_equal([' ', '<a href="foobar" class="foo">xyz</a>', ' </div>', ' '], getline(1,'$')) + norm! 1pj + call assert_equal([' <div>', '<a href="foobar" class="foo">xyz</a>', ' </div>', ' '], getline(1,'$')) + " at + norm! d2at + call assert_equal([' '], getline(1,'$')) + %d + call setline(1, ['<div> ','<a href="foobar" class="foo">xyz</a>',' </div>', ' ']) + " i< + norm! 1gg0di< + call assert_equal(['<> ', '<a href="foobar" class="foo">xyz</a>', ' </div>', ' '], getline(1,'$')) + norm! 1Pj + call assert_equal(['<div> ', '<a href="foobar" class="foo">xyz</a>', ' </div>', ' '], getline(1,'$')) + norm! d2it + call assert_equal(['<div></div>',' '], getline(1,'$')) + " basic testing for a[ and i[ text object + %d + call setline(1, [' ', '[', 'one [two]', 'thre', ']']) + norm! 3gg0di[ + call assert_equal([' ', '[', ']'], getline(1,'$')) + call setline(1, [' ', '[', 'one [two]', 'thre', ']']) + norm! 3gg0ftd2a[ + call assert_equal([' '], getline(1,'$')) + %d + " Test for i" when cursor is in front of a quoted object + call append(0, 'foo "bar"') + norm! 1gg0di" + call assert_equal(['foo ""', ''], getline(1,'$')) + + " clean up + bw! +endfunc + +func! Test_normal45_drop() + if !has("dnd") + return + endif + " basic test for :drop command + " unfortunately, without a gui, we can't really test much here, + " so simply test that ~p fails (which uses the drop register) + new + call assert_fails(':norm! "~p', 'E353') + call assert_equal([], getreg('~', 1, 1)) + " the ~ register is read only + call assert_fails(':let @~="1"', 'E354') + bw! +endfunc + +func! Test_normal46_ignore() + " This test uses multi byte characters + if !has("multi_byte") + return + endif + + new + " How to test this? + " let's just for now test, that the buffer + " does not change + call feedkeys("\<c-s>", 't') + call assert_equal([''], getline(1,'$')) + + " no valid commands + exe "norm! \<char-0x100>" + call assert_equal([''], getline(1,'$')) + + exe "norm! ä" + call assert_equal([''], getline(1,'$')) + + " clean up + bw! +endfunc + +func! Test_normal47_visual_buf_wipe() + " This was causing a crash or ml_get error. + enew! + call setline(1,'xxx') + normal $ + new + call setline(1, range(1,2)) + 2 + exe "norm \<C-V>$" + bw! + norm yp + set nomodified +endfunc + +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 + call append(0, repeat('-',20)) + au CursorHold * call feedkeys('2l', '') + 1 + set updatetime=20 + " should delete 12 chars (d12l) + call feedkeys('d1', '!') + call assert_equal('--------', getline(1)) + + " clean up + au! CursorHold + set updatetime=4000 + bw! +endfunc + +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() + new + call setline(1, 'one two three four five six seven eight nine ten') + 1 + norm! 3d2w + call assert_equal('seven eight nine ten', getline(1)) + bw! +endfunc + +func! Test_normal50_commandline() + if !has("timers") || !has("cmdline_hist") || !has("vertsplit") + return + endif + func! DoTimerWork(id) + call assert_equal('[Command Line]', bufname('')) + " should fail, with E11, but does fail with E23? + "call feedkeys("\<c-^>", 'tm') + + " should also fail with E11 + call assert_fails(":wincmd p", 'E11') + " return from commandline window + call feedkeys("\<cr>") + endfunc + + let oldlang=v:lang + lang C + set updatetime=20 + call timer_start(100, 'DoTimerWork') + try + " throws E23, for whatever reason... + call feedkeys('q:', 'x!') + catch /E23/ + " no-op + endtry + " clean up + set updatetime=4000 + exe "lang" oldlang + bw! +endfunc + +func! Test_normal51_FileChangedRO() + if !has("autocmd") + return + endif + call writefile(['foo'], 'Xreadonly.log') + new Xreadonly.log + setl ro + au FileChangedRO <buffer> :call feedkeys("\<c-^>", 'tix') + call assert_fails(":norm! Af", 'E788') + call assert_equal(['foo'], getline(1,'$')) + call assert_equal('Xreadonly.log', bufname('')) + + " cleanup + bw! + call delete("Xreadonly.log") +endfunc + +func! Test_normal52_rl() + if !has("rightleft") + return + endif + new + call setline(1, 'abcde fghij klmnopq') + norm! 1gg$ + set rl + call assert_equal(19, col('.')) + call feedkeys('l', 'tx') + call assert_equal(18, col('.')) + call feedkeys('h', 'tx') + call assert_equal(19, col('.')) + call feedkeys("\<right>", 'tx') + call assert_equal(18, col('.')) + call feedkeys("\<s-right>", 'tx') + call assert_equal(13, col('.')) + call feedkeys("\<c-right>", 'tx') + call assert_equal(7, col('.')) + call feedkeys("\<c-left>", 'tx') + call assert_equal(13, col('.')) + call feedkeys("\<s-left>", 'tx') + call assert_equal(19, col('.')) + call feedkeys("<<", 'tx') + call assert_equal(' abcde fghij klmnopq',getline(1)) + call feedkeys(">>", 'tx') + call assert_equal('abcde fghij klmnopq',getline(1)) + + " cleanup + set norl + bw! +endfunc + +func! Test_normal53_digraph() + if !has('digraphs') + return + endif + new + call setline(1, 'abcdefgh|') + exe "norm! 1gg0f\<c-k>!!" + call assert_equal(9, col('.')) + set cpo+=D + exe "norm! 1gg0f\<c-k>!!" + call assert_equal(1, col('.')) + + set cpo-=D + bw! +endfunc + +func! Test_normal54_Ctrl_bsl() + new + call setline(1, 'abcdefghijklmn') + exe "norm! df\<c-\>\<c-n>" + call assert_equal(['abcdefghijklmn'], getline(1,'$')) + exe "norm! df\<c-\>\<c-g>" + call assert_equal(['abcdefghijklmn'], getline(1,'$')) + exe "norm! df\<c-\>m" + call assert_equal(['abcdefghijklmn'], getline(1,'$')) + if !has("multi_byte") + return + endif + call setline(2, 'abcdefghijklmnāf') + norm! 2gg0 + exe "norm! df\<Char-0x101>" + call assert_equal(['abcdefghijklmn', 'f'], getline(1,'$')) + norm! 1gg0 + exe "norm! df\<esc>" + call assert_equal(['abcdefghijklmn', 'f'], getline(1,'$')) + + " clean up + bw! +endfunc diff --git a/src/nvim/testdir/test_options.vim b/src/nvim/testdir/test_options.vim index 5ee0919e18..08ee00e352 100644 --- a/src/nvim/testdir/test_options.vim +++ b/src/nvim/testdir/test_options.vim @@ -13,6 +13,12 @@ function! Test_whichwrap() set whichwrap+=h,l call assert_equal('b,s,h,l', &whichwrap) + set whichwrap=h,h + call assert_equal('h', &whichwrap) + + set whichwrap=h,h,h + call assert_equal('h', &whichwrap) + set whichwrap& endfunction @@ -97,3 +103,36 @@ func Test_keymap_valid() call assert_fails(":set kmp=trunc\x00name", "E544:") call assert_fails(":set kmp=trunc\x00name", "trunc") endfunc + +func Check_dir_option(name) + " Check that it's possible to set the option. + exe 'set ' . a:name . '=/usr/share/dict/words' + call assert_equal('/usr/share/dict/words', eval('&' . a:name)) + exe 'set ' . a:name . '=/usr/share/dict/words,/and/there' + call assert_equal('/usr/share/dict/words,/and/there', eval('&' . a:name)) + exe 'set ' . a:name . '=/usr/share/dict\ words' + call assert_equal('/usr/share/dict words', eval('&' . a:name)) + + " Check rejecting weird characters. + call assert_fails("set " . a:name . "=/not&there", "E474:") + call assert_fails("set " . a:name . "=/not>there", "E474:") + call assert_fails("set " . a:name . "=/not.*there", "E474:") +endfunc + +func Test_dictionary() + call Check_dir_option('dictionary') +endfunc + +func Test_thesaurus() + call Check_dir_option('thesaurus') +endfunc + +func Test_complete() + " Trailing single backslash used to cause invalid memory access. + set complete=s\ + new + call feedkeys("i\<C-N>\<Esc>", 'xt') + bwipe! + set complete& +endfun + diff --git a/src/nvim/testdir/test_popup.vim b/src/nvim/testdir/test_popup.vim index fd0f3c0d2d..e1ba142d1c 100644 --- a/src/nvim/testdir/test_popup.vim +++ b/src/nvim/testdir/test_popup.vim @@ -7,10 +7,10 @@ func! ListMonths() if g:setting != '' exe ":set" g:setting endif - let mth=copy(g:months) + let mth = copy(g:months) let entered = strcharpart(getline('.'),0,col('.')) if !empty(entered) - let mth=filter(mth, 'v:val=~"^".entered') + let mth = filter(mth, 'v:val=~"^".entered') endif call complete(1, mth) return '' @@ -468,7 +468,7 @@ endfunc " auto-wrap text. func Test_completion_ctrl_e_without_autowrap() new - let tw_save=&tw + let tw_save = &tw set tw=78 let li = [ \ '" zzz', @@ -478,7 +478,7 @@ func Test_completion_ctrl_e_without_autowrap() call feedkeys("A\<C-X>\<C-N>\<C-E>\<Esc>", "tx") call assert_equal(li, getline(1, '$')) - let &tw=tw_save + let &tw = tw_save q! endfunc @@ -533,7 +533,7 @@ func Test_completion_comment_formatting() %d try call feedkeys("o/*\<cr>\<cr>\<c-x>\<c-u>/\<esc>", 'tx') - call assert_false(1, 'completefunc not set, should have failed') + call assert_report('completefunc not set, should have failed') catch call assert_exception('E764:') endtry @@ -541,4 +541,33 @@ func Test_completion_comment_formatting() bwipe! endfunc +function! DummyCompleteSix() + call complete(1, ['Hello', 'World']) + return '' +endfunction + +" complete() correctly clears the list of autocomplete candidates +func Test_completion_clear_candidate_list() + new + %d + " select first entry from the completion popup + call feedkeys("a xxx\<C-N>\<C-R>=DummyCompleteSix()\<CR>", "tx") + call assert_equal('Hello', getline(1)) + %d + " select second entry from the completion popup + call feedkeys("a xxx\<C-N>\<C-R>=DummyCompleteSix()\<CR>\<C-N>", "tx") + call assert_equal('World', getline(1)) + %d + " select original text + call feedkeys("a xxx\<C-N>\<C-R>=DummyCompleteSix()\<CR>\<C-N>\<C-N>", "tx") + call assert_equal(' xxx', getline(1)) + %d + " back at first entry from completion list + call feedkeys("a xxx\<C-N>\<C-R>=DummyCompleteSix()\<CR>\<C-N>\<C-N>\<C-N>", "tx") + call assert_equal('Hello', getline(1)) + + bw! +endfunc + + " vim: shiftwidth=2 sts=2 expandtab diff --git a/src/nvim/testdir/test_profile.vim b/src/nvim/testdir/test_profile.vim new file mode 100644 index 0000000000..4cbd800da5 --- /dev/null +++ b/src/nvim/testdir/test_profile.vim @@ -0,0 +1,183 @@ +" Test Vim profiler +if !has('profile') + finish +endif + +func Test_profile_func() + let lines = [ + \ "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", + \ ] + + call writefile(lines, 'Xprofile_func.vim') + call system(v:progpath + \ . ' -es -u NONE -U NONE -i NONE --noplugin' + \ . ' -c "profile start Xprofile_func.log"' + \ . ' -c "profile func Foo*"' + \ . ' -c "so Xprofile_func.vim"' + \ . ' -c "qall!"') + call assert_equal(0, v:shell_error) + + let lines = readfile('Xprofile_func.log') + + " - Foo1() is called 3 times but should be reported as called twice + " since one call is in between "profile pause" .. "profile continue". + " - Foo2() should come before Foo1() since Foo1() does much more work. + " - Foo3() is not reported because function is deleted. + " - Unlike Foo3(), Foo2() should not be deleted since there is a check + " for v:profiling. + " - Bar() is not reported since it does not match "profile func Foo*". + call assert_equal(28, len(lines)) + + call assert_equal('FUNCTION Foo1()', lines[0]) + call assert_equal('Called 2 times', lines[1]) + call assert_match('^Total time:\s\+\d\+\.\d\+$', lines[2]) + call assert_match('^ Self time:\s\+\d\+\.\d\+$', lines[3]) + call assert_equal('', lines[4]) + call assert_equal('count total (s) self (s)', lines[5]) + call assert_equal('', lines[6]) + call assert_equal('FUNCTION Foo2()', lines[7]) + call assert_equal('Called 1 time', lines[8]) + call assert_match('^Total time:\s\+\d\+\.\d\+$', lines[9]) + call assert_match('^ Self time:\s\+\d\+\.\d\+$', lines[10]) + call assert_equal('', lines[11]) + call assert_equal('count total (s) self (s)', lines[12]) + call assert_match('^\s*1\s\+.*\slet l:count = 100$', lines[13]) + call assert_match('^\s*101\s\+.*\swhile l:count > 0$', lines[14]) + call assert_match('^\s*100\s\+.*\s let l:count = l:count - 1$', lines[15]) + call assert_match('^\s*100\s\+.*\sendwhile$', lines[16]) + call assert_equal('', lines[17]) + call assert_equal('FUNCTIONS SORTED ON TOTAL TIME', lines[18]) + call assert_equal('count total (s) self (s) function', lines[19]) + call assert_match('^\s*1\s\+\d\+\.\d\+\s\+Foo2()$', lines[20]) + call assert_match('^\s*2\s\+\d\+\.\d\+\s\+Foo1()$', lines[21]) + call assert_equal('', lines[22]) + call assert_equal('FUNCTIONS SORTED ON SELF TIME', lines[23]) + call assert_equal('count total (s) self (s) function', lines[24]) + call assert_match('^\s*1\s\+\d\+\.\d\+\s\+Foo2()$', lines[25]) + call assert_match('^\s*2\s\+\d\+\.\d\+\s\+Foo1()$', lines[26]) + call assert_equal('', lines[27]) + + call delete('Xprofile_func.vim') + call delete('Xprofile_func.log') +endfunc + +func Test_profile_file() + let lines = [ + \ 'func! Foo()', + \ 'endfunc', + \ 'for i in range(10)', + \ ' " a comment', + \ ' call Foo()', + \ 'endfor', + \ 'call Foo()', + \ ] + + call writefile(lines, 'Xprofile_file.vim') + call system(v:progpath + \ . ' -es -u NONE -U NONE -i NONE --noplugin' + \ . ' -c "profile start Xprofile_file.log"' + \ . ' -c "profile file Xprofile_file.vim"' + \ . ' -c "so Xprofile_file.vim"' + \ . ' -c "so Xprofile_file.vim"' + \ . ' -c "qall!"') + call assert_equal(0, v:shell_error) + + let lines = readfile('Xprofile_file.log') + + call assert_equal(14, len(lines)) + + call assert_match('^SCRIPT .*Xprofile_file.vim$', lines[0]) + call assert_equal('Sourced 2 times', lines[1]) + call assert_match('^Total time:\s\+\d\+\.\d\+$', lines[2]) + call assert_match('^ Self time:\s\+\d\+\.\d\+$', lines[3]) + call assert_equal('', lines[4]) + call assert_equal('count total (s) self (s)', lines[5]) + call assert_match(' 2 0.\d\+ func! Foo()', lines[6]) + call assert_equal(' endfunc', lines[7]) + " Loop iterates 10 times. Since script runs twice, body executes 20 times. + " First line of loop executes one more time than body to detect end of loop. + call assert_match('^\s*22\s\+\d\+\.\d\+\s\+for i in range(10)$', lines[8]) + call assert_equal(' " a comment', lines[9]) + " if self and total are equal we only get one number + call assert_match('^\s*20\s\+\(\d\+\.\d\+\s\+\)\=\d\+\.\d\+\s\+call Foo()$', lines[10]) + call assert_match('^\s*20\s\+\d\+\.\d\+\s\+endfor$', lines[11]) + " if self and total are equal we only get one number + call assert_match('^\s*2\s\+\(\d\+\.\d\+\s\+\)\=\d\+\.\d\+\s\+call Foo()$', lines[12]) + call assert_equal('', lines[13]) + + call delete('Xprofile_file.vim') + call delete('Xprofile_file.log') +endfunc + +func Test_profile_file_with_cont() + let lines = [ + \ 'echo "hello', + \ ' \ world"', + \ 'echo "foo ', + \ ' \bar"', + \ ] + + call writefile(lines, 'Xprofile_file.vim') + call system(v:progpath + \ . ' -es -u NONE -U NONE -i NONE --noplugin' + \ . ' -c "profile start Xprofile_file.log"' + \ . ' -c "profile file Xprofile_file.vim"' + \ . ' -c "so Xprofile_file.vim"' + \ . ' -c "qall!"') + call assert_equal(0, v:shell_error) + + let lines = readfile('Xprofile_file.log') + call assert_equal(11, len(lines)) + + call assert_match('^SCRIPT .*Xprofile_file.vim$', lines[0]) + call assert_equal('Sourced 1 time', lines[1]) + call assert_match('^Total time:\s\+\d\+\.\d\+$', lines[2]) + call assert_match('^ Self time:\s\+\d\+\.\d\+$', lines[3]) + call assert_equal('', lines[4]) + call assert_equal('count total (s) self (s)', lines[5]) + call assert_match(' 1 0.\d\+ echo "hello', lines[6]) + call assert_equal(' \ world"', lines[7]) + call assert_match(' 1 0.\d\+ echo "foo ', lines[8]) + call assert_equal(' \bar"', lines[9]) + call assert_equal('', lines[10]) + + call delete('Xprofile_file.vim') + call delete('Xprofile_file.log') +endfunc + +func Test_profile_completion() + call feedkeys(":profile \<C-A>\<C-B>\"\<CR>", 'tx') + call assert_equal('"profile continue dump file func pause start stop', @:) + + call feedkeys(":profile start test_prof\<C-A>\<C-B>\"\<CR>", 'tx') + call assert_match('^"profile start.* test_profile\.vim', @:) +endfunc + +func Test_profile_errors() + call assert_fails("profile func Foo", 'E750:') + call assert_fails("profile pause", 'E750:') + call assert_fails("profile continue", 'E750:') +endfunc diff --git a/src/nvim/testdir/test_quickfix.vim b/src/nvim/testdir/test_quickfix.vim index 640918b343..aff5fc2eed 100644 --- a/src/nvim/testdir/test_quickfix.vim +++ b/src/nvim/testdir/test_quickfix.vim @@ -6,7 +6,7 @@ endif set encoding=utf-8 -function! s:setup_commands(cchar) +func s:setup_commands(cchar) if a:cchar == 'c' command! -nargs=* -bang Xlist <mods>clist<bang> <args> command! -nargs=* Xgetexpr <mods>cgetexpr <args> @@ -68,10 +68,10 @@ function! s:setup_commands(cchar) let g:Xgetlist = function('getloclist', [0]) let g:Xsetlist = function('setloclist', [0]) endif -endfunction +endfunc " Tests for the :clist and :llist commands -function XlistTests(cchar) +func XlistTests(cchar) call s:setup_commands(a:cchar) " With an empty list, command should return error @@ -128,17 +128,17 @@ function XlistTests(cchar) let l = split(result, "\n") call assert_equal([' 2 Xtestfile1:1 col 3: Line1', \ ' 3: non-error 2', ' 4 Xtestfile2:2 col 2: Line2'], l) -endfunction +endfunc -function Test_clist() +func Test_clist() call XlistTests('c') call XlistTests('l') -endfunction +endfunc " Tests for the :colder, :cnewer, :lolder and :lnewer commands " Note that this test assumes that a quickfix/location list is " already set by the caller. -function XageTests(cchar) +func XageTests(cchar) call s:setup_commands(a:cchar) " Jumping to a non existent list should return error @@ -171,20 +171,20 @@ function XageTests(cchar) Xnewer 2 let l = g:Xgetlist() call assert_equal('Line3', l[0].text) -endfunction +endfunc -function Test_cage() +func Test_cage() let list = [{'bufnr': 1, 'lnum': 1}] call setqflist(list) call XageTests('c') call setloclist(0, list) call XageTests('l') -endfunction +endfunc " Tests for the :cwindow, :lwindow :cclose, :lclose, :copen and :lopen " commands -function XwindowTests(cchar) +func XwindowTests(cchar) call s:setup_commands(a:cchar) " Create a list with no valid entries @@ -227,16 +227,16 @@ function XwindowTests(cchar) " Calling cwindow should close the quickfix window with no valid errors Xwindow call assert_true(winnr('$') == 1) -endfunction +endfunc -function Test_cwindow() +func Test_cwindow() call XwindowTests('c') call XwindowTests('l') -endfunction +endfunc " Tests for the :cfile, :lfile, :caddfile, :laddfile, :cgetfile and :lgetfile " commands. -function XfileTests(cchar) +func XfileTests(cchar) call s:setup_commands(a:cchar) call writefile(['Xtestfile1:700:10:Line 700', @@ -275,16 +275,16 @@ function XfileTests(cchar) \ l[1].lnum == 333 && l[1].col == 88 && l[1].text ==# 'Line 333') call delete('Xqftestfile1') -endfunction +endfunc -function Test_cfile() +func Test_cfile() call XfileTests('c') call XfileTests('l') -endfunction +endfunc " Tests for the :cbuffer, :lbuffer, :caddbuffer, :laddbuffer, :cgetbuffer and " :lgetbuffer commands. -function XbufferTests(cchar) +func XbufferTests(cchar) call s:setup_commands(a:cchar) enew! @@ -316,26 +316,26 @@ function XbufferTests(cchar) \ l[3].lnum == 750 && l[3].col == 25 && l[3].text ==# 'Line 750') enew! -endfunction +endfunc -function Test_cbuffer() +func Test_cbuffer() call XbufferTests('c') call XbufferTests('l') -endfunction +endfunc -function XexprTests(cchar) +func XexprTests(cchar) call s:setup_commands(a:cchar) call assert_fails('Xexpr 10', 'E777:') -endfunction +endfunc -function Test_cexpr() +func Test_cexpr() call XexprTests('c') call XexprTests('l') -endfunction +endfunc " Tests for :cnext, :cprev, :cfirst, :clast commands -function Xtest_browse(cchar) +func Xtest_browse(cchar) call s:setup_commands(a:cchar) call s:create_test_file('Xqftestfile1') @@ -366,14 +366,14 @@ function Xtest_browse(cchar) call delete('Xqftestfile1') call delete('Xqftestfile2') -endfunction +endfunc -function Test_browse() +func Test_browse() call Xtest_browse('c') call Xtest_browse('l') -endfunction +endfunc -function! s:test_xhelpgrep(cchar) +func s:test_xhelpgrep(cchar) call s:setup_commands(a:cchar) Xhelpgrep quickfix Xopen @@ -385,9 +385,9 @@ function! s:test_xhelpgrep(cchar) call assert_true(w:quickfix_title =~ title_text, w:quickfix_title) " This wipes out the buffer, make sure that doesn't cause trouble. Xclose -endfunction +endfunc -function Test_helpgrep() +func Test_helpgrep() call s:test_xhelpgrep('c') helpclose call s:test_xhelpgrep('l') @@ -425,7 +425,7 @@ func Test_vimgreptitle() augroup! QfBufWinEnter endfunc -function XqfTitleTests(cchar) +func XqfTitleTests(cchar) call s:setup_commands(a:cchar) Xgetexpr ['file:1:1:message'] @@ -444,16 +444,16 @@ function XqfTitleTests(cchar) endif call assert_equal(title, w:quickfix_title) Xclose -endfunction +endfunc " Tests for quickfix window's title -function Test_qf_title() +func Test_qf_title() call XqfTitleTests('c') call XqfTitleTests('l') -endfunction +endfunc " Tests for 'errorformat' -function Test_efm() +func Test_efm() let save_efm = &efm set efm=%EEEE%m,%WWWW%m,%+CCCC%.%#,%-GGGG%.%# cgetexpr ['WWWW', 'EEEE', 'CCCC'] @@ -466,7 +466,7 @@ function Test_efm() let l = strtrans(string(map(getqflist(), '[v:val.text, v:val.valid]'))) call assert_equal("[['W', 1], ['ZZZZ', 0], ['E^@CCCC', 1], ['YYYY', 0]]", l) let &efm = save_efm -endfunction +endfunc " This will test for problems in quickfix: " A. incorrectly copying location lists which caused the location list to show @@ -477,7 +477,7 @@ endfunction " window it belongs to. " " Set up the test environment: -function! ReadTestProtocol(name) +func ReadTestProtocol(name) let base = substitute(a:name, '\v^test://(.*)%(\.[^.]+)?', '\1', '') let word = substitute(base, '\v(.*)\..*', '\1', '') @@ -496,9 +496,9 @@ function! ReadTestProtocol(name) setl nomodifiable setl readonly exe 'doautocmd BufRead ' . substitute(a:name, '\v^test://(.*)', '\1', '') -endfunction +endfunc -function Test_locationlist() +func Test_locationlist() enew augroup testgroup @@ -578,15 +578,15 @@ function Test_locationlist() wincmd n | only augroup! testgroup -endfunction + endfunc -function Test_locationlist_curwin_was_closed() +func Test_locationlist_curwin_was_closed() augroup testgroup au! autocmd BufReadCmd test_curwin.txt call R(expand("<amatch>")) augroup END - function! R(n) + func! R(n) quit endfunc @@ -597,10 +597,26 @@ function Test_locationlist_curwin_was_closed() call assert_fails('lrewind', 'E924:') augroup! testgroup -endfunction + endfunc + +func Test_locationlist_cross_tab_jump() + call writefile(['loclistfoo'], 'loclistfoo') + call writefile(['loclistbar'], 'loclistbar') + set switchbuf=usetab + + edit loclistfoo + tabedit loclistbar + silent lgrep loclistfoo loclist* + call assert_equal(1, tabpagenr()) + + enew | only | tabonly + set switchbuf&vim + call delete('loclistfoo') + call delete('loclistbar') +endfunc " More tests for 'errorformat' -function! Test_efm1() +func Test_efm1() if !has('unix') " The 'errorformat' setting is different on non-Unix systems. " This test works only on Unix-like systems. @@ -718,10 +734,10 @@ function! Test_efm1() call delete('Xerrorfile1') call delete('Xerrorfile2') call delete('Xtestfile') -endfunction + endfunc " Test for quickfix directory stack support -function! s:dir_stack_tests(cchar) +func s:dir_stack_tests(cchar) call s:setup_commands(a:cchar) let save_efm=&efm @@ -763,10 +779,10 @@ function! s:dir_stack_tests(cchar) call assert_equal(5, qf[11].lnum) let &efm=save_efm -endfunction +endfunc " Tests for %D and %X errorformat options -function! Test_efm_dirstack() +func Test_efm_dirstack() " Create the directory stack and files call mkdir('dir1') call mkdir('dir1/a') @@ -798,10 +814,33 @@ function! Test_efm_dirstack() call delete('dir1', 'rf') call delete('dir2', 'rf') call delete('habits1.txt') -endfunction +endfunc + +" Test for resync after continuing an ignored message +func Xefm_ignore_continuations(cchar) + call s:setup_commands(a:cchar) + + let save_efm = &efm + + let &efm = + \ '%Eerror %m %l,' . + \ '%-Wignored %m %l,' . + \ '%+Cmore ignored %m %l,' . + \ '%Zignored end' + Xgetexpr ['ignored warning 1', 'more ignored continuation 2', 'ignored end', 'error resync 4'] + let l = map(g:Xgetlist(), '[v:val.text, v:val.valid, v:val.lnum, v:val.type]') + call assert_equal([['resync', 1, 4, 'E']], l) + + let &efm = save_efm +endfunc + +func Test_efm_ignore_continuations() + call Xefm_ignore_continuations('c') + call Xefm_ignore_continuations('l') +endfunc " Tests for invalid error format specifies -function Xinvalid_efm_Tests(cchar) +func Xinvalid_efm_Tests(cchar) call s:setup_commands(a:cchar) let save_efm = &efm @@ -834,17 +873,17 @@ function Xinvalid_efm_Tests(cchar) call assert_fails('Xexpr ["Entering dir abc", "abc.txt:1:Hello world"]', 'E379:') let &efm = save_efm -endfunction +endfunc -function Test_invalid_efm() +func Test_invalid_efm() call Xinvalid_efm_Tests('c') call Xinvalid_efm_Tests('l') -endfunction +endfunc " TODO: " Add tests for the following formats in 'errorformat' " %r %O -function! Test_efm2() +func Test_efm2() let save_efm = &efm " Test for %s format in efm @@ -930,19 +969,19 @@ function! Test_efm2() call assert_equal('unittests/dbfacadeTest.py', bufname(l[4].bufnr)) let &efm = save_efm -endfunction +endfunc -function XquickfixChangedByAutocmd(cchar) +func XquickfixChangedByAutocmd(cchar) call s:setup_commands(a:cchar) if a:cchar == 'c' let ErrorNr = 'E925' - function! ReadFunc() + func! ReadFunc() colder cgetexpr [] endfunc else let ErrorNr = 'E926' - function! ReadFunc() + func! ReadFunc() lolder lgetexpr [] endfunc @@ -965,10 +1004,10 @@ function XquickfixChangedByAutocmd(cchar) augroup! testgroup endfunc -function Test_quickfix_was_changed_by_autocmd() +func Test_quickfix_was_changed_by_autocmd() call XquickfixChangedByAutocmd('c') call XquickfixChangedByAutocmd('l') -endfunction +endfunc func Test_caddbuffer_to_empty() helpgr quickfix @@ -990,7 +1029,7 @@ func Test_cgetexpr_works() endfunc " Tests for the setqflist() and setloclist() functions -function SetXlistTests(cchar, bnum) +func SetXlistTests(cchar, bnum) call s:setup_commands(a:cchar) call g:Xsetlist([{'bufnr': a:bnum, 'lnum': 1}, @@ -1025,9 +1064,9 @@ function SetXlistTests(cchar, bnum) call g:Xsetlist([]) let l = g:Xgetlist() call assert_equal(0, len(l)) -endfunction +endfunc -function Test_setqflist() +func Test_setqflist() new Xtestfile | only let bnum = bufnr('%') call setline(1, range(1,5)) @@ -1037,9 +1076,9 @@ function Test_setqflist() enew! call delete('Xtestfile') -endfunction +endfunc -function Xlist_empty_middle(cchar) +func Xlist_empty_middle(cchar) call s:setup_commands(a:cchar) " create three quickfix lists @@ -1062,12 +1101,12 @@ function Xlist_empty_middle(cchar) call assert_equal(matchlen, len(g:Xgetlist())) endfunc -function Test_setqflist_empty_middle() +func Test_setqflist_empty_middle() call Xlist_empty_middle('c') call Xlist_empty_middle('l') -endfunction +endfunc -function Xlist_empty_older(cchar) +func Xlist_empty_older(cchar) call s:setup_commands(a:cchar) " create three quickfix lists @@ -1088,14 +1127,14 @@ function Xlist_empty_older(cchar) call assert_equal(twolen, len(g:Xgetlist())) Xnewer call assert_equal(threelen, len(g:Xgetlist())) -endfunction +endfunc -function Test_setqflist_empty_older() +func Test_setqflist_empty_older() call Xlist_empty_older('c') call Xlist_empty_older('l') -endfunction +endfunc -function! XquickfixSetListWithAct(cchar) +func XquickfixSetListWithAct(cchar) call s:setup_commands(a:cchar) let list1 = [{'filename': 'fnameA', 'text': 'A'}, @@ -1169,12 +1208,12 @@ function! XquickfixSetListWithAct(cchar) call assert_fails("call g:Xsetlist(list1, 0)", 'E928:') endfunc -function Test_quickfix_set_list_with_act() +func Test_quickfix_set_list_with_act() call XquickfixSetListWithAct('c') call XquickfixSetListWithAct('l') -endfunction +endfunc -function XLongLinesTests(cchar) +func XLongLinesTests(cchar) let l = g:Xgetlist() call assert_equal(4, len(l)) @@ -1192,9 +1231,9 @@ function XLongLinesTests(cchar) call assert_equal(10, len(l[3].text)) call g:Xsetlist([], 'r') -endfunction +endfunc -function s:long_lines_tests(cchar) +func s:long_lines_tests(cchar) call s:setup_commands(a:cchar) let testfile = 'samples/quickfix.txt' @@ -1215,22 +1254,22 @@ function s:long_lines_tests(cchar) exe 'edit' testfile exe 'Xbuffer' bufnr('%') call XLongLinesTests(a:cchar) -endfunction +endfunc -function Test_long_lines() +func Test_long_lines() call s:long_lines_tests('c') call s:long_lines_tests('l') -endfunction +endfunc -function! s:create_test_file(filename) +func s:create_test_file(filename) let l = [] for i in range(1, 20) call add(l, 'Line' . i) endfor call writefile(l, a:filename) -endfunction +endfunc -function! Test_switchbuf() +func Test_switchbuf() call s:create_test_file('Xqftestfile1') call s:create_test_file('Xqftestfile2') call s:create_test_file('Xqftestfile3') @@ -1317,9 +1356,9 @@ function! Test_switchbuf() call delete('Xqftestfile1') call delete('Xqftestfile2') call delete('Xqftestfile3') -endfunction +endfunc -function! Xadjust_qflnum(cchar) +func Xadjust_qflnum(cchar) call s:setup_commands(a:cchar) enew | only @@ -1344,17 +1383,17 @@ function! Xadjust_qflnum(cchar) enew! call delete(fname) -endfunction +endfunc -function! Test_adjust_lnum() +func Test_adjust_lnum() call setloclist(0, []) call Xadjust_qflnum('c') call setqflist([]) call Xadjust_qflnum('l') -endfunction +endfunc " Tests for the :grep/:lgrep and :grepadd/:lgrepadd commands -function! s:test_xgrep(cchar) +func s:test_xgrep(cchar) call s:setup_commands(a:cchar) " The following lines are used for the grep test. Don't remove. @@ -1373,9 +1412,9 @@ function! s:test_xgrep(cchar) set makeef=Temp_File_## silent Xgrepadd GrepAdd_Test_Text: test_quickfix.vim call assert_true(len(g:Xgetlist()) == 6) -endfunction +endfunc -function! Test_grep() +func Test_grep() if !has('unix') " The grepprg may not be set on non-Unix systems return @@ -1383,9 +1422,9 @@ function! Test_grep() call s:test_xgrep('c') call s:test_xgrep('l') -endfunction +endfunc -function! Test_two_windows() +func Test_two_windows() " Use one 'errorformat' for two windows. Add an expression to each of them, " make sure they each keep their own state. set efm=%DEntering\ dir\ '%f',%f:%l:%m,%XLeaving\ dir\ '%f' @@ -1411,12 +1450,10 @@ function! Test_two_windows() laddexpr 'one.txt:3:one one one' let loc_one = getloclist(one_id) -echo string(loc_one) call assert_equal('Xone/a/one.txt', bufname(loc_one[1].bufnr)) call assert_equal(3, loc_one[1].lnum) let loc_two = getloclist(two_id) -echo string(loc_two) call assert_equal('Xtwo/a/two.txt', bufname(loc_two[1].bufnr)) call assert_equal(5, loc_two[1].lnum) @@ -1428,7 +1465,7 @@ echo string(loc_two) call delete('Xtwo', 'rf') endfunc -function XbottomTests(cchar) +func XbottomTests(cchar) call s:setup_commands(a:cchar) call g:Xsetlist([{'filename': 'foo', 'lnum': 42}]) @@ -1444,12 +1481,12 @@ function XbottomTests(cchar) endfunc " Tests for the :cbottom and :lbottom commands -function Test_cbottom() +func Test_cbottom() call XbottomTests('c') call XbottomTests('l') -endfunction +endfunc -function HistoryTest(cchar) +func HistoryTest(cchar) call s:setup_commands(a:cchar) call assert_fails(a:cchar . 'older 99', 'E380:') @@ -1489,7 +1526,7 @@ func Test_duplicate_buf() endfunc " Quickfix/Location list set/get properties tests -function Xproperty_tests(cchar) +func Xproperty_tests(cchar) call s:setup_commands(a:cchar) " Error cases @@ -1516,6 +1553,11 @@ function Xproperty_tests(cchar) call assert_equal('N1', g:Xgetlist({'all':1}).title) call g:Xsetlist([], ' ', {'title' : 'N2'}) call assert_equal(qfnr + 1, g:Xgetlist({'all':1}).nr) + + let res = g:Xgetlist({'nr': 0}) + call assert_equal(qfnr + 1, res.nr) + call assert_equal(['nr'], keys(res)) + call g:Xsetlist([], ' ', {'title' : 'N3'}) call assert_equal('N2', g:Xgetlist({'nr':2, 'title':1}).title) @@ -1528,21 +1570,21 @@ function Xproperty_tests(cchar) call assert_equal({}, g:Xgetlist({'abc':1})) if a:cchar == 'l' - call assert_equal({}, getloclist(99, ['title'])) + call assert_equal({}, getloclist(99, {'title': 1})) endif -endfunction + endfunc -function Test_qf_property() +func Test_qf_property() call Xproperty_tests('c') call Xproperty_tests('l') -endfunction + endfunc " Tests for the QuickFixCmdPre/QuickFixCmdPost autocommands -function QfAutoCmdHandler(loc, cmd) +func QfAutoCmdHandler(loc, cmd) call add(g:acmds, a:loc . a:cmd) -endfunction +endfunc -function Test_Autocmd() +func Test_Autocmd() autocmd QuickFixCmdPre * call QfAutoCmdHandler('pre', expand('<amatch>')) autocmd QuickFixCmdPost * call QfAutoCmdHandler('post', expand('<amatch>')) @@ -1570,9 +1612,9 @@ function Test_Autocmd() \ 'precaddbuffer', \ 'postcaddbuffer'] call assert_equal(l, g:acmds) -endfunction +endfunc -function! Test_Autocmd_Exception() +func Test_Autocmd_Exception() set efm=%m lgetexpr '?' @@ -1587,4 +1629,47 @@ function! Test_Autocmd_Exception() call assert_equal('1', getloclist(0)[0].text) set efm&vim -endfunction +endfunc + +func Test_caddbuffer_wrong() + " This used to cause a memory access in freed memory. + let save_efm = &efm + set efm=%EEEE%m,%WWWW,%+CCCC%>%#,%GGGG%.# + cgetexpr ['WWWW', 'EEEE', 'CCCC'] + let &efm = save_efm + caddbuffer + bwipe! +endfunc + +func Test_caddexpr_wrong() + " This used to cause a memory access in freed memory. + cbuffer + cbuffer + copen + let save_efm = &efm + set efm=% + call assert_fails('caddexpr ""', 'E376:') + let &efm = save_efm +endfunc + +func Test_dirstack_cleanup() + " This used to cause a memory access in freed memory. + let save_efm = &efm + lexpr '0' + lopen + fun X(c) + let save_efm=&efm + set efm=%D%f + if a:c == 'c' + caddexpr '::' + else + laddexpr ':0:0' + endif + let &efm=save_efm + endfun + call X('c') + call X('l') + call setqflist([], 'r') + caddbuffer + let &efm = save_efm +endfunc diff --git a/src/nvim/testdir/test_regexp_utf8.vim b/src/nvim/testdir/test_regexp_utf8.vim index 9e9a3de500..a2f4286d4f 100644 --- a/src/nvim/testdir/test_regexp_utf8.vim +++ b/src/nvim/testdir/test_regexp_utf8.vim @@ -97,3 +97,27 @@ func Test_recursive_substitute() call setwinvar(1, 'myvar', 1) bwipe! endfunc + +func Test_nested_backrefs() + " Check example in change.txt. + new + for re in range(0, 2) + exe 'set re=' . re + call setline(1, 'aa ab x') + 1s/\(\(a[a-d] \)*\)\(x\)/-\1- -\2- -\3-/ + call assert_equal('-aa ab - -ab - -x-', getline(1)) + + call assert_equal('-aa ab - -ab - -x-', substitute('aa ab x', '\(\(a[a-d] \)*\)\(x\)', '-\1- -\2- -\3-', '')) + endfor + bwipe! + set re=0 +endfunc + +func Test_eow_with_optional() + let expected = ['abc def', 'abc', 'def', '', '', '', '', '', '', ''] + for re in range(0, 2) + exe 'set re=' . re + let actual = matchlist('abc def', '\(abc\>\)\?\s*\(def\)') + call assert_equal(expected, actual) + endfor +endfunc diff --git a/src/nvim/testdir/test_retab.vim b/src/nvim/testdir/test_retab.vim new file mode 100644 index 0000000000..f11a32bade --- /dev/null +++ b/src/nvim/testdir/test_retab.vim @@ -0,0 +1,77 @@ +" Test :retab +func SetUp() + new + call setline(1, "\ta \t b c ") +endfunc + +func TearDown() + bwipe! +endfunc + +func Retab(bang, n) + let l:old_tabstop = &tabstop + let l:old_line = getline(1) + exe "retab" . a:bang . a:n + let l:line = getline(1) + call setline(1, l:old_line) + if a:n > 0 + " :retab changes 'tabstop' to n with argument n > 0. + call assert_equal(a:n, &tabstop) + exe 'set tabstop=' . l:old_tabstop + else + " :retab does not change 'tabstop' with empty or n <= 0. + call assert_equal(l:old_tabstop, &tabstop) + endif + return l:line +endfunc + +func Test_retab() + set tabstop=8 noexpandtab + call assert_equal("\ta\t b c ", Retab('', '')) + call assert_equal("\ta\t b c ", Retab('', 0)) + call assert_equal("\ta\t b c ", Retab('', 8)) + call assert_equal("\ta\t b\t c\t ", Retab('!', '')) + call assert_equal("\ta\t b\t c\t ", Retab('!', 0)) + call assert_equal("\ta\t b\t c\t ", Retab('!', 8)) + + call assert_equal("\t\ta\t\t\tb c ", Retab('', 4)) + call assert_equal("\t\ta\t\t\tb\t\t c\t ", Retab('!', 4)) + + call assert_equal(" a\t\tb c ", Retab('', 10)) + call assert_equal(" a\t\tb c ", Retab('!', 10)) + + set tabstop=8 expandtab + call assert_equal(" a b c ", Retab('', '')) + call assert_equal(" a b c ", Retab('', 0)) + call assert_equal(" a b c ", Retab('', 8)) + call assert_equal(" a b c ", Retab('!', '')) + call assert_equal(" a b c ", Retab('!', 0)) + call assert_equal(" a b c ", Retab('!', 8)) + + call assert_equal(" a b c ", Retab(' ', 4)) + call assert_equal(" a b c ", Retab('!', 4)) + + call assert_equal(" a b c ", Retab(' ', 10)) + call assert_equal(" a b c ", Retab('!', 10)) + + set tabstop=4 noexpandtab + call assert_equal("\ta\t\tb c ", Retab('', '')) + call assert_equal("\ta\t\tb\t\t c\t ", Retab('!', '')) + call assert_equal("\t a\t\t\tb c ", Retab('', 3)) + call assert_equal("\t a\t\t\tb\t\t\tc\t ", Retab('!', 3)) + call assert_equal(" a\t b c ", Retab('', 5)) + call assert_equal(" a\t b\t\t c\t ", Retab('!', 5)) + + set tabstop=4 expandtab + call assert_equal(" a b c ", Retab('', '')) + call assert_equal(" a b c ", Retab('!', '')) + call assert_equal(" a b c ", Retab('', 3)) + call assert_equal(" a b c ", Retab('!', 3)) + call assert_equal(" a b c ", Retab('', 5)) + call assert_equal(" a b c ", Retab('!', 5)) +endfunc + +func Test_retab_error() + call assert_fails('retab -1', 'E487:') + call assert_fails('retab! -1', 'E487:') +endfunc diff --git a/src/nvim/testdir/test_search.vim b/src/nvim/testdir/test_search.vim new file mode 100644 index 0000000000..a333e7f206 --- /dev/null +++ b/src/nvim/testdir/test_search.vim @@ -0,0 +1,300 @@ +" Test for the search command + +func Test_search_cmdline() + " See test/functional/legacy/search_spec.lua + throw 'skipped: Nvim does not support test_disable_char_avail()' + if !exists('+incsearch') + return + endif + " need to disable char_avail, + " so that expansion of commandline works + call test_disable_char_avail(1) + new + call setline(1, [' 1', ' 2 these', ' 3 the', ' 4 their', ' 5 there', ' 6 their', ' 7 the', ' 8 them', ' 9 these', ' 10 foobar']) + " Test 1 + " CTRL-N / CTRL-P skips through the previous search history + set noincsearch + :1 + call feedkeys("/foobar\<cr>", 'tx') + call feedkeys("/the\<cr>",'tx') + call assert_equal('the', @/) + call feedkeys("/thes\<C-P>\<C-P>\<cr>",'tx') + call assert_equal('foobar', @/) + + " Test 2 + " Ctrl-G goes from one match to the next + " until the end of the buffer + set incsearch nowrapscan + :1 + " first match + call feedkeys("/the\<cr>", 'tx') + call assert_equal(' 2 these', getline('.')) + :1 + " second match + call feedkeys("/the\<C-G>\<cr>", 'tx') + call assert_equal(' 3 the', getline('.')) + call assert_equal([0, 0, 0, 0], getpos('"')) + :1 + " third match + call feedkeys("/the".repeat("\<C-G>", 2)."\<cr>", 'tx') + call assert_equal(' 4 their', getline('.')) + :1 + " fourth match + call feedkeys("/the".repeat("\<C-G>", 3)."\<cr>", 'tx') + call assert_equal(' 5 there', getline('.')) + :1 + " fifth match + call feedkeys("/the".repeat("\<C-G>", 4)."\<cr>", 'tx') + call assert_equal(' 6 their', getline('.')) + :1 + " sixth match + call feedkeys("/the".repeat("\<C-G>", 5)."\<cr>", 'tx') + call assert_equal(' 7 the', getline('.')) + :1 + " seventh match + call feedkeys("/the".repeat("\<C-G>", 6)."\<cr>", 'tx') + call assert_equal(' 8 them', getline('.')) + :1 + " eigth match + call feedkeys("/the".repeat("\<C-G>", 7)."\<cr>", 'tx') + call assert_equal(' 9 these', getline('.')) + :1 + " no further match + call feedkeys("/the".repeat("\<C-G>", 8)."\<cr>", 'tx') + call assert_equal(' 9 these', getline('.')) + call assert_equal([0, 0, 0, 0], getpos('"')) + + " Test 3 + " Ctrl-G goes from one match to the next + " and continues back at the top + set incsearch wrapscan + :1 + " first match + call feedkeys("/the\<cr>", 'tx') + call assert_equal(' 2 these', getline('.')) + :1 + " second match + call feedkeys("/the\<C-G>\<cr>", 'tx') + call assert_equal(' 3 the', getline('.')) + :1 + " third match + call feedkeys("/the".repeat("\<C-G>", 2)."\<cr>", 'tx') + call assert_equal(' 4 their', getline('.')) + :1 + " fourth match + call feedkeys("/the".repeat("\<C-G>", 3)."\<cr>", 'tx') + call assert_equal(' 5 there', getline('.')) + :1 + " fifth match + call feedkeys("/the".repeat("\<C-G>", 4)."\<cr>", 'tx') + call assert_equal(' 6 their', getline('.')) + :1 + " sixth match + call feedkeys("/the".repeat("\<C-G>", 5)."\<cr>", 'tx') + call assert_equal(' 7 the', getline('.')) + :1 + " seventh match + call feedkeys("/the".repeat("\<C-G>", 6)."\<cr>", 'tx') + call assert_equal(' 8 them', getline('.')) + :1 + " eigth match + call feedkeys("/the".repeat("\<C-G>", 7)."\<cr>", 'tx') + call assert_equal(' 9 these', getline('.')) + :1 + " back at first match + call feedkeys("/the".repeat("\<C-G>", 8)."\<cr>", 'tx') + call assert_equal(' 2 these', getline('.')) + + " Test 4 + " CTRL-T goes to the previous match + set incsearch nowrapscan + $ + " first match + call feedkeys("?the\<cr>", 'tx') + call assert_equal(' 9 these', getline('.')) + $ + " first match + call feedkeys("?the\<C-G>\<cr>", 'tx') + call assert_equal(' 9 these', getline('.')) + $ + " second match + call feedkeys("?the".repeat("\<C-T>", 1)."\<cr>", 'tx') + call assert_equal(' 8 them', getline('.')) + $ + " last match + call feedkeys("?the".repeat("\<C-T>", 7)."\<cr>", 'tx') + call assert_equal(' 2 these', getline('.')) + $ + " last match + call feedkeys("?the".repeat("\<C-T>", 8)."\<cr>", 'tx') + call assert_equal(' 2 these', getline('.')) + + " Test 5 + " CTRL-T goes to the previous match + set incsearch wrapscan + $ + " first match + call feedkeys("?the\<cr>", 'tx') + call assert_equal(' 9 these', getline('.')) + $ + " first match at the top + call feedkeys("?the\<C-G>\<cr>", 'tx') + call assert_equal(' 2 these', getline('.')) + $ + " second match + call feedkeys("?the".repeat("\<C-T>", 1)."\<cr>", 'tx') + call assert_equal(' 8 them', getline('.')) + $ + " last match + call feedkeys("?the".repeat("\<C-T>", 7)."\<cr>", 'tx') + call assert_equal(' 2 these', getline('.')) + $ + " back at the bottom of the buffer + call feedkeys("?the".repeat("\<C-T>", 8)."\<cr>", 'tx') + call assert_equal(' 9 these', getline('.')) + + " Test 6 + " CTRL-L adds to the search pattern + set incsearch wrapscan + 1 + " first match + call feedkeys("/the\<c-l>\<cr>", 'tx') + call assert_equal(' 2 these', getline('.')) + 1 + " go to next match of 'thes' + call feedkeys("/the\<c-l>\<C-G>\<cr>", 'tx') + call assert_equal(' 9 these', getline('.')) + 1 + " wrap around + call feedkeys("/the\<c-l>\<C-G>\<C-G>\<cr>", 'tx') + call assert_equal(' 2 these', getline('.')) + 1 + " wrap around + set nowrapscan + call feedkeys("/the\<c-l>\<C-G>\<C-G>\<cr>", 'tx') + call assert_equal(' 9 these', getline('.')) + + " Test 7 + " <bs> remove from match, but stay at current match + set incsearch wrapscan + 1 + " first match + call feedkeys("/thei\<cr>", 'tx') + call assert_equal(' 4 their', getline('.')) + 1 + " delete one char, add another + call feedkeys("/thei\<bs>s\<cr>", 'tx') + call assert_equal(' 2 these', getline('.')) + 1 + " delete one char, add another, go to previous match, add one char + call feedkeys("/thei\<bs>s\<bs>\<C-T>\<c-l>\<cr>", 'tx') + call assert_equal(' 9 these', getline('.')) + 1 + " delete all chars, start from the beginning again + call feedkeys("/them". repeat("\<bs>",4).'the\>'."\<cr>", 'tx') + call assert_equal(' 3 the', getline('.')) + + " clean up + call test_disable_char_avail(0) + bw! +endfunc + +func Test_search_cmdline2() + " See test/functional/legacy/search_spec.lua + throw 'skipped: Nvim does not support test_disable_char_avail()' + if !exists('+incsearch') + return + endif + " need to disable char_avail, + " so that expansion of commandline works + call test_disable_char_avail(1) + new + call setline(1, [' 1', ' 2 these', ' 3 the theother']) + " Test 1 + " Ctrl-T goes correctly back and forth + set incsearch + 1 + " first match + call feedkeys("/the\<cr>", 'tx') + call assert_equal(' 2 these', getline('.')) + 1 + " go to next match (on next line) + call feedkeys("/the\<C-G>\<cr>", 'tx') + call assert_equal(' 3 the theother', getline('.')) + 1 + " go to next match (still on line 3) + call feedkeys("/the\<C-G>\<C-G>\<cr>", 'tx') + call assert_equal(' 3 the theother', getline('.')) + 1 + " go to next match (still on line 3) + call feedkeys("/the\<C-G>\<C-G>\<C-G>\<cr>", 'tx') + call assert_equal(' 3 the theother', getline('.')) + 1 + " go to previous match (on line 3) + call feedkeys("/the\<C-G>\<C-G>\<C-G>\<C-T>\<cr>", 'tx') + call assert_equal(' 3 the theother', getline('.')) + 1 + " go to previous match (on line 3) + call feedkeys("/the\<C-G>\<C-G>\<C-G>\<C-T>\<C-T>\<cr>", 'tx') + call assert_equal(' 3 the theother', getline('.')) + 1 + " go to previous match (on line 2) + call feedkeys("/the\<C-G>\<C-G>\<C-G>\<C-T>\<C-T>\<C-T>\<cr>", 'tx') + call assert_equal(' 2 these', getline('.')) + + " Test 2: keep the view, + " after deleting a character from the search cmd + call setline(1, [' 1', ' 2 these', ' 3 the', ' 4 their', ' 5 there', ' 6 their', ' 7 the', ' 8 them', ' 9 these', ' 10 foobar']) + resize 5 + 1 + call feedkeys("/foo\<bs>\<cr>", 'tx') + redraw + call assert_equal({'lnum': 10, 'leftcol': 0, 'col': 4, 'topfill': 0, 'topline': 6, 'coladd': 0, 'skipcol': 0, 'curswant': 4}, winsaveview()) + + " remove all history entries + for i in range(10) + call histdel('/') + endfor + + " Test 3: reset the view, + " after deleting all characters from the search cmd + norm! 1gg0 + " unfortunately, neither "/foo\<c-w>\<cr>", nor "/foo\<bs>\<bs>\<bs>\<cr>", + " nor "/foo\<c-u>\<cr>" works to delete the commandline. + " In that case Vim should return "E35 no previous regular expression", + " but it looks like Vim still sees /foo and therefore the test fails. + " Therefore, disableing this test + "call assert_fails(feedkeys("/foo\<c-w>\<cr>", 'tx'), 'E35') + "call assert_equal({'lnum': 1, 'leftcol': 0, 'col': 0, 'topfill': 0, 'topline': 1, 'coladd': 0, 'skipcol': 0, 'curswant': 0}, winsaveview()) + + " clean up + set noincsearch + call test_disable_char_avail(0) + bw! +endfunc + +func Test_use_sub_pat() + split + let @/ = '' + func X() + s/^/a/ + / + endfunc + call X() + bwipe! +endfunc + +func Test_searchpair() + new + call setline(1, ['other code here', '', '[', '" cursor here', ']']) + 4 + let a=searchpair('\[','',']','bW') + call assert_equal(3, a) + set nomagic + 4 + let a=searchpair('\[','',']','bW') + call assert_equal(3, a) + set magic + q! +endfunc + diff --git a/src/nvim/testdir/test_smartindent.vim b/src/nvim/testdir/test_smartindent.vim new file mode 100644 index 0000000000..d00eac9798 --- /dev/null +++ b/src/nvim/testdir/test_smartindent.vim @@ -0,0 +1,14 @@ + +" Tests for not doing smart indenting when it isn't set. +function! Test_nosmartindent() + new + call append(0, [" some test text", + \ " test text", + \ "test text", + \ " test text"]) + set nocindent nosmartindent autoindent + exe "normal! gg/some\<CR>" + exe "normal! 2cc#test\<Esc>" + call assert_equal(" #test", getline(1)) + enew! | close +endfunction diff --git a/src/nvim/testdir/test_startup.vim b/src/nvim/testdir/test_startup.vim new file mode 100644 index 0000000000..11e26d03aa --- /dev/null +++ b/src/nvim/testdir/test_startup.vim @@ -0,0 +1,242 @@ +" Tests for startup. + +source shared.vim + +" Check that loading startup.vim works. +func Test_startup_script() + throw 'skipped: Nvim does not need defaults.vim' + set compatible + source $VIMRUNTIME/defaults.vim + + call assert_equal(0, &compatible) +endfunc + +" Verify the order in which plugins are loaded: +" 1. plugins in non-after directories +" 2. packages +" 3. plugins in after directories +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', + \ ] + call mkdir('Xhere/plugin', 'p') + call writefile(['let g:sequence .= "here "'], 'Xhere/plugin/here.vim') + call mkdir('Xanother/plugin', 'p') + call writefile(['let g:sequence .= "another "'], 'Xanother/plugin/another.vim') + call mkdir('Xhere/pack/foo/start/foobar/plugin', 'p') + call writefile(['let g:sequence .= "pack "'], 'Xhere/pack/foo/start/foobar/plugin/foo.vim') + + call mkdir('Xafter/plugin', 'p') + call writefile(['let g:sequence .= "after "'], 'Xafter/plugin/later.vim') + + if RunVim(before, after, '') + + let lines = readfile('Xtestout') + let expected = ['Xbefore.vim', 'here.vim', 'another.vim', 'foo.vim', 'later.vim', 'Xafter.vim'] + let found = [] + for line in lines + for one in expected + if line =~ one + call add(found, one) + endif + endfor + endfor + call assert_equal(expected, found) + endif + + call assert_equal('here another pack after', substitute(join(readfile('Xsequence', 1), ''), '\s\+$', '', '')) + + call delete('Xtestout') + call delete('Xsequence') + call delete('Xhere', 'rf') + call delete('Xanother', 'rf') + call delete('Xafter', 'rf') +endfunc + +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 after = [ + \ 'quit', + \ ] + call mkdir('Xhere/plugin', 'p') + call writefile(['redir! > Xtestout', 'silent set runtimepath?', 'silent! call foo#Trigger()', 'redir END'], 'Xhere/plugin/here.vim') + call mkdir('Xhere/pack/foo/start/foobar/autoload', 'p') + call writefile(['function! foo#Trigger()', 'echo "autoloaded foo"', 'endfunction'], 'Xhere/pack/foo/start/foobar/autoload/foo.vim') + + if RunVim(before, after, '') + + let lines = filter(readfile('Xtestout'), '!empty(v:val)') + call assert_match('Xhere[/\\]pack[/\\]foo[/\\]start[/\\]foobar', get(lines, 0)) + call assert_match('autoloaded foo', get(lines, 1)) + endif + + call delete('Xtestout') + call delete('Xhere', 'rf') +endfunc + +func Test_help_arg() + if !has('unix') && has('gui') + " this doesn't work with gvim on MS-Windows + return + endif + if RunVim([], [], '--help >Xtestout') + let lines = readfile('Xtestout') + call assert_true(len(lines) > 20) + call assert_match('Usage:', lines[0]) + + " check if couple of lines are there + let found = [] + for line in lines + if line =~ '-R.*Read-only mode' + call add(found, 'Readonly mode') + endif + " Watch out for a second --version line in the Gnome version. + if line =~ '--version.*Print version information' + call add(found, "--version") + endif + endfor + call assert_equal(['Readonly mode', '--version'], found) + endif + call delete('Xtestout') +endfunc + +func Test_compatible_args() + throw "skipped: Nvim is always 'nocompatible'" + let after = [ + \ 'call writefile([string(&compatible)], "Xtestout")', + \ 'set viminfo+=nviminfo', + \ 'quit', + \ ] + if RunVim([], after, '-C') + let lines = readfile('Xtestout') + call assert_equal('1', lines[0]) + endif + + if RunVim([], after, '-N') + let lines = readfile('Xtestout') + call assert_equal('0', lines[0]) + endif + + call delete('Xtestout') +endfunc + +func Test_file_args() + let after = [ + \ 'call writefile(argv(), "Xtestout")', + \ 'qall', + \ ] + if RunVim([], after, '') + let lines = readfile('Xtestout') + call assert_equal(0, len(lines)) + endif + + if RunVim([], after, 'one') + let lines = readfile('Xtestout') + call assert_equal(1, len(lines)) + call assert_equal('one', lines[0]) + endif + + if RunVim([], after, 'one two three') + let lines = readfile('Xtestout') + call assert_equal(3, len(lines)) + call assert_equal('one', lines[0]) + call assert_equal('two', lines[1]) + call assert_equal('three', lines[2]) + endif + + if RunVim([], after, 'one -c echo two') + let lines = readfile('Xtestout') + call assert_equal(2, len(lines)) + call assert_equal('one', lines[0]) + call assert_equal('two', lines[1]) + endif + + if RunVim([], after, 'one -- -c echo two') + let lines = readfile('Xtestout') + call assert_equal(4, len(lines)) + call assert_equal('one', lines[0]) + call assert_equal('-c', lines[1]) + call assert_equal('echo', lines[2]) + call assert_equal('two', lines[3]) + endif + + call delete('Xtestout') +endfunc + +func Test_startuptime() + if !has('startuptime') + return + endif + let after = ['qall'] + if RunVim([], after, '--startuptime Xtestout one') + let lines = readfile('Xtestout') + let expected = ['parsing arguments', 'inits 3', 'opening buffers'] + let found = [] + for line in lines + for exp in expected + if line =~ exp + call add(found, exp) + endif + endfor + endfor + call assert_equal(expected, found) + endif + call delete('Xtestout') +endfunc + +func Test_read_stdin() + let after = [ + \ 'write Xtestout', + \ 'quit!', + \ ] + if RunVimPiped([], after, '-', 'echo something | ') + let lines = readfile('Xtestout') + " MS-Windows adds a space after the word + call assert_equal(['something'], split(lines[0])) + endif + call delete('Xtestout') +endfunc + +func Test_progpath() + " Tests normally run with "./vim" or "../vim", these must have been expanded + " to a full path. + if has('unix') + call assert_equal('/', v:progpath[0]) + elseif has('win32') + call assert_equal(':', v:progpath[1]) + call assert_match('[/\\]', v:progpath[2]) + endif + + " Only expect "vim" to appear in v:progname. + call assert_match('vim\c', v:progname) +endfunc diff --git a/src/nvim/testdir/test_startup_utf8.vim b/src/nvim/testdir/test_startup_utf8.vim new file mode 100644 index 0000000000..d179a4cc79 --- /dev/null +++ b/src/nvim/testdir/test_startup_utf8.vim @@ -0,0 +1,64 @@ +" Tests for startup using utf-8. +if !has('multi_byte') + finish +endif + +source shared.vim + +func Test_read_stdin_utf8() + let linesin = ['テスト', '€ÀÈÌÒÙ'] + call writefile(linesin, 'Xtestin') + let before = [ + \ 'set enc=utf-8', + \ 'set fencs=cp932,utf-8', + \ ] + let after = [ + \ 'write ++enc=utf-8 Xtestout', + \ 'quit!', + \ ] + if has('win32') + let pipecmd = 'type Xtestin | ' + else + let pipecmd = 'cat Xtestin | ' + endif + if RunVimPiped(before, after, '-', pipecmd) + let lines = readfile('Xtestout') + call assert_equal(linesin, lines) + else + call assert_equal('', 'RunVimPiped failed.') + endif + call delete('Xtestout') + call delete('Xtestin') +endfunc + +func Test_read_fifo_utf8() + if !has('unix') + return + endif + " Using bash/zsh's process substitution. + if executable('bash') + set shell=bash + elseif executable('zsh') + set shell=zsh + else + return + endif + let linesin = ['テスト', '€ÀÈÌÒÙ'] + call writefile(linesin, 'Xtestin') + let before = [ + \ 'set enc=utf-8', + \ 'set fencs=cp932,utf-8', + \ ] + let after = [ + \ 'write ++enc=utf-8 Xtestout', + \ 'quit!', + \ ] + if RunVim(before, after, '<(cat Xtestin)') + let lines = readfile('Xtestout') + call assert_equal(linesin, lines) + else + call assert_equal('', 'RunVim failed.') + endif + call delete('Xtestout') + call delete('Xtestin') +endfunc diff --git a/src/nvim/testdir/test_stat.vim b/src/nvim/testdir/test_stat.vim new file mode 100644 index 0000000000..dee0d13e84 --- /dev/null +++ b/src/nvim/testdir/test_stat.vim @@ -0,0 +1,71 @@ +" Tests for stat functions and checktime + +func Test_existent_file() + let fname = 'Xtest.tmp' + + let ts = localtime() + let fl = ['Hello World!'] + call writefile(fl, fname) + let tf = getftime(fname) + let te = localtime() + + call assert_true(ts <= tf && tf <= te) + call assert_equal(strlen(fl[0] . "\n"), getfsize(fname)) + call assert_equal('file', getftype(fname)) + call assert_equal('rw-', getfperm(fname)[0:2]) + + call delete(fname) +endfunc + +func Test_existent_directory() + let dname = '.' + + call assert_equal(0, getfsize(dname)) + call assert_equal('dir', getftype(dname)) + call assert_equal('rwx', getfperm(dname)[0:2]) +endfunc + +func Test_checktime() + let fname = 'Xtest.tmp' + + let fl = ['Hello World!'] + call writefile(fl, fname) + set autoread + exec 'e' fname + " FAT has a granularity of 2 seconds, otherwise it's usually 1 second + if has('win32') + sleep 2 + else + sleep 2 + endif + let fl = readfile(fname) + let fl[0] .= ' - checktime' + call writefile(fl, fname) + checktime + call assert_equal(fl[0], getline(1)) + + call delete(fname) +endfunc + +func Test_nonexistent_file() + let fname = 'Xtest.tmp' + + call delete(fname) + call assert_equal(-1, getftime(fname)) + call assert_equal(-1, getfsize(fname)) + call assert_equal('', getftype(fname)) + call assert_equal('', getfperm(fname)) +endfunc + +func Test_win32_symlink_dir() + " On Windows, non-admin users cannot create symlinks. + " So we use an existing symlink for this test. + if has('win32') + " Check if 'C:\Users\All Users' is a symlink to a directory. + let res = system('dir C:\Users /a') + if match(res, '\C<SYMLINKD> *All Users') >= 0 + " Get the filetype of the symlink. + call assert_equal('dir', getftype('C:\Users\All Users')) + endif + endif +endfunc diff --git a/src/nvim/testdir/test_substitute.vim b/src/nvim/testdir/test_substitute.vim new file mode 100644 index 0000000000..e2b6de03c3 --- /dev/null +++ b/src/nvim/testdir/test_substitute.vim @@ -0,0 +1,41 @@ +" Tests for multi-line regexps with ":s". + +function! Test_multiline_subst() + enew! + call append(0, ["1 aa", + \ "bb", + \ "cc", + \ "2 dd", + \ "ee", + \ "3 ef", + \ "gh", + \ "4 ij", + \ "5 a8", + \ "8b c9", + \ "9d", + \ "6 e7", + \ "77f", + \ "xxxxx"]) + + 1 + " test if replacing a line break works with a back reference + /^1/,/^2/s/\n\(.\)/ \1/ + " test if inserting a line break works with a back reference + /^3/,/^4/s/\(.\)$/\r\1/ + " test if replacing a line break with another line break works + /^5/,/^6/s/\(\_d\{3}\)/x\1x/ + call assert_equal('1 aa bb cc 2 dd ee', getline(1)) + call assert_equal('3 e', getline(2)) + call assert_equal('f', getline(3)) + call assert_equal('g', getline(4)) + call assert_equal('h', getline(5)) + call assert_equal('4 i', getline(6)) + call assert_equal('j', getline(7)) + call assert_equal('5 ax8', getline(8)) + call assert_equal('8xb cx9', getline(9)) + call assert_equal('9xd', getline(10)) + call assert_equal('6 ex7', getline(11)) + call assert_equal('7x7f', getline(12)) + call assert_equal('xxxxx', getline(13)) + enew! +endfunction diff --git a/src/nvim/testdir/test_syntax.vim b/src/nvim/testdir/test_syntax.vim index af2cbbfe8e..6c084dd2a7 100644 --- a/src/nvim/testdir/test_syntax.vim +++ b/src/nvim/testdir/test_syntax.vim @@ -50,7 +50,7 @@ func Test_syn_iskeyword() setlocal isk-=_ call assert_equal('DLTD_BY', GetSyntaxItem('DLTD')) /\<D\k\+\>/:norm! ygn - let b2=@0 + let b2 = @0 call assert_equal('DLTD', @0) syn iskeyword clear @@ -76,3 +76,85 @@ func Test_syntax_after_reload() call assert_true(exists('g:gotit')) call delete('Xsomefile') endfunc + +func Test_syntime() + if !has('profile') + return + endif + + syntax on + syntime on + let a = execute('syntime report') + call assert_equal("\nNo Syntax items defined for this buffer", a) + + view ../memfile_test.c + setfiletype cpp + redraw + let a = execute('syntime report') + call assert_match('^ TOTAL *COUNT *MATCH *SLOWEST *AVERAGE *NAME *PATTERN', a) + call assert_match(' \d*\.\d* \+[^0]\d* .* cppRawString ', a) + call assert_match(' \d*\.\d* \+[^0]\d* .* cppNumber ', a) + + syntime off + syntime clear + let a = execute('syntime report') + call assert_match('^ TOTAL *COUNT *MATCH *SLOWEST *AVERAGE *NAME *PATTERN', a) + call assert_notmatch('.* cppRawString *', a) + call assert_notmatch('.* cppNumber*', a) + call assert_notmatch('[1-9]', a) + + call assert_fails('syntime abc', 'E475') + + syntax clear + let a = execute('syntime report') + call assert_equal("\nNo Syntax items defined for this buffer", a) + + bd +endfunc + +func Test_syntax_list() + syntax on + let a = execute('syntax list') + call assert_equal("\nNo Syntax items defined for this buffer", a) + + view ../memfile_test.c + setfiletype c + + let a = execute('syntax list') + call assert_match('cInclude*', a) + call assert_match('cDefine', a) + + let a = execute('syntax list cDefine') + call assert_notmatch('cInclude*', a) + call assert_match('cDefine', a) + call assert_match(' links to Macro$', a) + + call assert_fails('syntax list ABCD', 'E28:') + call assert_fails('syntax list @ABCD', 'E392:') + + syntax clear + let a = execute('syntax list') + call assert_equal("\nNo Syntax items defined for this buffer", a) + + bd +endfunc + +func Test_syntax_completion() + call feedkeys(":syn \<C-A>\<C-B>\"\<CR>", 'tx') + call assert_equal('"syn case clear cluster conceal enable include iskeyword keyword list manual match off on region reset spell sync', @:) + + call feedkeys(":syn case \<C-A>\<C-B>\"\<CR>", 'tx') + call assert_equal('"syn case ignore match', @:) + + call feedkeys(":syn spell \<C-A>\<C-B>\"\<CR>", 'tx') + call assert_equal('"syn spell default notoplevel toplevel', @:) + + call feedkeys(":syn sync \<C-A>\<C-B>\"\<CR>", 'tx') + call assert_equal('"syn sync ccomment clear fromstart linebreaks= linecont lines= match maxlines= minlines= region', @:) + + call feedkeys(":syn list \<C-A>\<C-B>\"\<CR>", 'tx') + call assert_match('^"syn list Boolean Character ', @:) + + call feedkeys(":syn match \<C-A>\<C-B>\"\<CR>", 'tx') + call assert_match('^"syn match Boolean Character ', @:) +endfunc
\ No newline at end of file diff --git a/src/nvim/testdir/test_tabpage.vim b/src/nvim/testdir/test_tabpage.vim index 7c3039ba24..33139fcda0 100644 --- a/src/nvim/testdir/test_tabpage.vim +++ b/src/nvim/testdir/test_tabpage.vim @@ -11,6 +11,7 @@ function Test_tabpage() 0tabnew 1tabnew $tabnew + %del tabdo call append(line('$'), tabpagenr()) tabclose! 2 tabrewind @@ -93,10 +94,6 @@ function Test_tabpage() call assert_equal(7, tabpagenr()) tabmove call assert_equal(10, tabpagenr()) - tabmove -20 - call assert_equal(1, tabpagenr()) - tabmove +20 - call assert_equal(10, tabpagenr()) 0tabmove call assert_equal(1, tabpagenr()) $tabmove @@ -109,7 +106,16 @@ function Test_tabpage() call assert_equal(4, tabpagenr()) 7tabmove 5 call assert_equal(5, tabpagenr()) + call assert_fails("99tabmove", 'E16:') + call assert_fails("+99tabmove", 'E16:') + call assert_fails("-99tabmove", 'E16:') call assert_fails("tabmove foo", 'E474:') + call assert_fails("tabmove 99", 'E474:') + call assert_fails("tabmove +99", 'E474:') + call assert_fails("tabmove -99", 'E474:') + call assert_fails("tabmove -3+", 'E474:') + call assert_fails("tabmove $3", 'E474:') + 1tabonly! endfunc " Test autocommands @@ -117,7 +123,6 @@ function Test_tabpage_with_autocmd() if !has('autocmd') return endif - tabonly! command -nargs=1 -bar C :call add(s:li, '=== ' . <q-args> . ' ===')|<args> augroup TestTabpageGroup au! @@ -182,8 +187,10 @@ function Test_tabpage_with_autocmd() autocmd TabDestructive TabEnter * nested :C tabnext 2 | C tabclose 3 let s:li = [] - C tabnext 3 - call assert_equal(['=== tabnext 3 ===', 'BufLeave', 'WinLeave', 'TabLeave', 'WinEnter', 'TabEnter', '=== tabnext 2 ===', 'BufLeave', 'WinLeave', 'TabLeave', 'WinEnter', 'TabEnter', '=== tabnext 2 ===', '=== tabclose 3 ===', 'BufEnter', '=== tabclose 3 ==='], s:li) + call assert_equal(3, tabpagenr('$')) + C tabnext 2 + call assert_equal(2, tabpagenr('$')) + call assert_equal(['=== tabnext 2 ===', 'WinLeave', 'TabLeave', 'WinEnter', 'TabEnter', '=== tabnext 2 ===', '=== tabclose 3 ==='], s:li) call assert_equal(['2/2'], [tabpagenr().'/'.tabpagenr('$')]) delcommand C @@ -191,8 +198,7 @@ function Test_tabpage_with_autocmd() augroup! TabDestructive autocmd! TestTabpageGroup augroup! TestTabpageGroup - tabonly! - bw! + 1tabonly! endfunction function Test_tabpage_with_tab_modifier() @@ -204,7 +210,7 @@ function Test_tabpage_with_tab_modifier() exec 'tabnext ' . a:pre_nr exec a:cmd call assert_equal(a:post_nr, tabpagenr()) - call assert_equal('help', &filetype) + call assert_equal('help', &buftype) helpclose endfunc @@ -223,8 +229,223 @@ function Test_tabpage_with_tab_modifier() call assert_fails('-99tab help', 'E16:') delfunction s:check_tab - tabonly! - bw! + 1tabonly! +endfunction + +function Check_tab_count(pre_nr, cmd, post_nr) + exec 'tabnext' a:pre_nr + normal! G + exec a:cmd + call assert_equal(a:post_nr, tabpagenr(), a:cmd) +endfunc + +" Test for [count] of tabnext +function Test_tabpage_with_tabnext() + for n in range(4) + tabedit + call setline(1, ['', '', '3']) + endfor + + call Check_tab_count(1, 'tabnext', 2) + call Check_tab_count(1, '3tabnext', 3) + call Check_tab_count(1, '.tabnext', 1) + call Check_tab_count(1, '.+1tabnext', 2) + call Check_tab_count(2, '+tabnext', 3) + call Check_tab_count(2, '+2tabnext', 4) + call Check_tab_count(4, '-tabnext', 3) + call Check_tab_count(4, '-2tabnext', 2) + call Check_tab_count(3, '$tabnext', 5) + call assert_fails('0tabnext', 'E16:') + call assert_fails('99tabnext', 'E16:') + call assert_fails('+99tabnext', 'E16:') + call assert_fails('-99tabnext', 'E16:') + call Check_tab_count(1, 'tabnext 3', 3) + call Check_tab_count(2, 'tabnext +', 3) + call Check_tab_count(2, 'tabnext +2', 4) + call Check_tab_count(4, 'tabnext -', 3) + call Check_tab_count(4, 'tabnext -2', 2) + call Check_tab_count(3, 'tabnext $', 5) + call assert_fails('tabnext 0', 'E474:') + call assert_fails('tabnext .', 'E474:') + call assert_fails('tabnext -+', 'E474:') + call assert_fails('tabnext +2-', 'E474:') + call assert_fails('tabnext $3', 'E474:') + call assert_fails('tabnext 99', 'E474:') + call assert_fails('tabnext +99', 'E474:') + call assert_fails('tabnext -99', 'E474:') + + 1tabonly! +endfunction + +" Test for [count] of tabprevious +function Test_tabpage_with_tabprevious() + for n in range(5) + tabedit + call setline(1, ['', '', '3']) + endfor + + for cmd in ['tabNext', 'tabprevious'] + call Check_tab_count(6, cmd, 5) + call Check_tab_count(6, '3' . cmd, 3) + call Check_tab_count(6, '8' . cmd, 4) + call Check_tab_count(6, cmd . ' 3', 3) + call Check_tab_count(6, cmd . ' 8', 4) + for n in range(2) + for c in ['0', '.+3', '+', '+2' , '-', '-2' , '$', '+99', '-99'] + if n == 0 " pre count + let entire_cmd = c . cmd + let err_code = 'E16:' + else + let entire_cmd = cmd . ' ' . c + let err_code = 'E474:' + endif + call assert_fails(entire_cmd, err_code) + endfor + endfor + endfor + + 1tabonly! +endfunction + +function s:reconstruct_tabpage_for_test(nr) + let n = (a:nr > 2) ? a:nr - 2 : 1 + 1tabonly! + 0tabedit n0 + for n in range(1, n) + exec '$tabedit n' . n + if n == 1 + call setline(1, ['', '', '3']) + endif + endfor +endfunc + +" Test for [count] of tabclose +function Test_tabpage_with_tabclose() + + " pre count + call s:reconstruct_tabpage_for_test(6) + call Check_tab_count(3, 'tabclose!', 3) + call Check_tab_count(1, '3tabclose', 1) + call Check_tab_count(4, '4tabclose', 3) + call Check_tab_count(3, '1tabclose', 2) + call Check_tab_count(2, 'tabclose', 1) + call assert_equal(1, tabpagenr('$')) + call assert_equal('', bufname('')) + + call s:reconstruct_tabpage_for_test(6) + call Check_tab_count(2, '$tabclose', 2) + call Check_tab_count(4, '.tabclose', 4) + call Check_tab_count(3, '.+tabclose', 3) + call Check_tab_count(3, '.-2tabclose', 2) + call Check_tab_count(1, '.+1tabclose!', 1) + call assert_equal(1, tabpagenr('$')) + call assert_equal('', bufname('')) + + " post count + call s:reconstruct_tabpage_for_test(6) + call Check_tab_count(3, 'tabclose!', 3) + call Check_tab_count(1, 'tabclose 3', 1) + call Check_tab_count(4, 'tabclose 4', 3) + call Check_tab_count(3, 'tabclose 1', 2) + call Check_tab_count(2, 'tabclose', 1) + call assert_equal(1, tabpagenr('$')) + call assert_equal('', bufname('')) + + call s:reconstruct_tabpage_for_test(6) + call Check_tab_count(2, 'tabclose $', 2) + call Check_tab_count(4, 'tabclose', 4) + call Check_tab_count(3, 'tabclose +', 3) + call Check_tab_count(3, 'tabclose -2', 2) + call Check_tab_count(1, 'tabclose! +1', 1) + call assert_equal(1, tabpagenr('$')) + call assert_equal('', bufname('')) + + call s:reconstruct_tabpage_for_test(6) + for n in range(2) + for c in ['0', '$3', '99', '+99', '-99'] + if n == 0 " pre count + let entire_cmd = c . 'tabclose' + let err_code = 'E16:' + else + let entire_cmd = 'tabclose ' . c + let err_code = 'E474:' + endif + call assert_fails(entire_cmd, err_code) + call assert_equal(6, tabpagenr('$')) + endfor + endfor + + call assert_fails('3tabclose', 'E37:') + call assert_fails('tabclose 3', 'E37:') + call assert_fails('tabclose -+', 'E474:') + call assert_fails('tabclose +2-', 'E474:') + call assert_equal(6, tabpagenr('$')) + + 1tabonly! +endfunction + +" Test for [count] of tabonly +function Test_tabpage_with_tabonly() + + " Test for the normal behavior (pre count only) + let tc = [ [4, '.', '!'], [2, '.+', ''], [3, '.-2', '!'], [1, '.+1', '!'] ] + for c in tc + call s:reconstruct_tabpage_for_test(6) + let entire_cmd = c[1] . 'tabonly' . c[2] + call Check_tab_count(c[0], entire_cmd, 1) + call assert_equal(1, tabpagenr('$')) + endfor + + " Test for the normal behavior + let tc2 = [ [3, '', ''], [1, '3', ''], [4, '4', '!'], [3, '1', '!'], + \ [2, '', '!'], + \ [2, '$', '!'], [3, '+', '!'], [3, '-2', '!'], [3, '+1', '!'] + \ ] + for n in range(2) + for c in tc2 + call s:reconstruct_tabpage_for_test(6) + if n == 0 " pre count + let entire_cmd = c[1] . 'tabonly' . c[2] + else + let entire_cmd = 'tabonly' . c[2] . ' ' . c[1] + endif + call Check_tab_count(c[0], entire_cmd, 1) + call assert_equal(1, tabpagenr('$')) + endfor + endfor + + " Test for the error behavior + for n in range(2) + for c in ['0', '$3', '99', '+99', '-99'] + call s:reconstruct_tabpage_for_test(6) + if n == 0 " pre count + let entire_cmd = c . 'tabonly' + let err_code = 'E16:' + else + let entire_cmd = 'tabonly ' . c + let err_code = 'E474:' + endif + call assert_fails(entire_cmd, err_code) + call assert_equal(6, tabpagenr('$')) + endfor + endfor + + " Test for the error behavior (post count only) + for c in tc + call s:reconstruct_tabpage_for_test(6) + let entire_cmd = 'tabonly' . c[2] . ' ' . c[1] + let err_code = 'E474:' + call assert_fails(entire_cmd, err_code) + call assert_equal(6, tabpagenr('$')) + endfor + + call assert_fails('tabonly -+', 'E474:') + call assert_fails('tabonly +2-', 'E474:') + call assert_equal(6, tabpagenr('$')) + + 1tabonly! + new + only! endfunction func Test_tabnext_on_buf_unload1() diff --git a/src/nvim/testdir/test_tagjump.vim b/src/nvim/testdir/test_tagjump.vim index 678ad0ada8..0d697b3f3e 100644 --- a/src/nvim/testdir/test_tagjump.vim +++ b/src/nvim/testdir/test_tagjump.vim @@ -23,4 +23,76 @@ func Test_cancel_ptjump() quit endfunc +func Test_static_tagjump() + set tags=Xtags + call writefile(["!_TAG_FILE_ENCODING\tutf-8\t//", + \ "one\tXfile1\t/^one/;\"\tf\tfile:\tsignature:(void)", + \ "word\tXfile2\tcmd2"], + \ 'Xtags') + new Xfile1 + call setline(1, ['empty', 'one()', 'empty']) + write + tag one + call assert_equal(2, line('.')) + + bwipe! + set tags& + call delete('Xtags') + call delete('Xfile1') +endfunc + +func Test_duplicate_tagjump() + set tags=Xtags + call writefile(["!_TAG_FILE_ENCODING\tutf-8\t//", + \ "thesame\tXfile1\t1;\"\td\tfile:", + \ "thesame\tXfile1\t2;\"\td\tfile:", + \ "thesame\tXfile1\t3;\"\td\tfile:", + \ ], + \ 'Xtags') + new Xfile1 + call setline(1, ['thesame one', 'thesame two', 'thesame three']) + write + tag thesame + call assert_equal(1, line('.')) + tnext + call assert_equal(2, line('.')) + tnext + call assert_equal(3, line('.')) + + bwipe! + set tags& + call delete('Xtags') + call delete('Xfile1') +endfunc + +" Tests for [ CTRL-I and CTRL-W CTRL-I commands +function Test_keyword_jump() + call writefile(["#include Xinclude", "", + \ "", + \ "/* test text test tex start here", + \ " some text", + \ " test text", + \ " start OK if found this line", + \ " start found wrong line", + \ "test text"], 'Xtestfile') + call writefile(["/* test text test tex start here", + \ " some text", + \ " test text", + \ " start OK if found this line", + \ " start found wrong line", + \ "test text"], 'Xinclude') + new Xtestfile + call cursor(1,1) + call search("start") + exe "normal! 5[\<C-I>" + call assert_equal(" start OK if found this line", getline('.')) + call cursor(1,1) + call search("start") + exe "normal! 5\<C-W>\<C-I>" + call assert_equal(" start OK if found this line", getline('.')) + enew! | only + call delete('Xtestfile') + call delete('Xinclude') +endfunction + " vim: shiftwidth=2 sts=2 expandtab diff --git a/src/nvim/testdir/test_taglist.vim b/src/nvim/testdir/test_taglist.vim new file mode 100644 index 0000000000..2d1557ebd9 --- /dev/null +++ b/src/nvim/testdir/test_taglist.vim @@ -0,0 +1,58 @@ +" test 'taglist' function + +func Test_taglist() + call writefile([ + \ "FFoo\tXfoo\t1", + \ "FBar\tXfoo\t2", + \ "BFoo\tXbar\t1", + \ "BBar\tXbar\t2" + \ ], 'Xtags') + set tags=Xtags + split Xtext + + call assert_equal(['FFoo', 'BFoo'], map(taglist("Foo"), {i, v -> v.name})) + call assert_equal(['FFoo', 'BFoo'], map(taglist("Foo", "Xtext"), {i, v -> v.name})) + call assert_equal(['FFoo', 'BFoo'], map(taglist("Foo", "Xfoo"), {i, v -> v.name})) + call assert_equal(['BFoo', 'FFoo'], map(taglist("Foo", "Xbar"), {i, v -> v.name})) + + call delete('Xtags') + bwipe +endfunc + +func Test_taglist_native_etags() + if !has('emacs_tags') + return + endif + call writefile([ + \ "\x0c", + \ "src/os_unix.c,13491", + \ "set_signals(\x7f1335,32699", + \ "reset_signals(\x7f1407,34136", + \ ], 'Xtags') + + set tags=Xtags + + call assert_equal([['set_signals', '1335,32699'], ['reset_signals', '1407,34136']], + \ map(taglist('set_signals'), {i, v -> [v.name, v.cmd]})) + + call delete('Xtags') +endfunc + +func Test_taglist_ctags_etags() + if !has('emacs_tags') + return + endif + call writefile([ + \ "\x0c", + \ "src/os_unix.c,13491", + \ "set_signals(void)\x7fset_signals\x011335,32699", + \ "reset_signals(void)\x7freset_signals\x011407,34136", + \ ], 'Xtags') + + set tags=Xtags + + call assert_equal([['set_signals', '1335,32699'], ['reset_signals', '1407,34136']], + \ map(taglist('set_signals'), {i, v -> [v.name, v.cmd]})) + + call delete('Xtags') +endfunc diff --git a/src/nvim/testdir/test_timers.vim b/src/nvim/testdir/test_timers.vim index 56f9feef66..d377062780 100644 --- a/src/nvim/testdir/test_timers.vim +++ b/src/nvim/testdir/test_timers.vim @@ -4,8 +4,10 @@ if !has('timers') finish endif +source shared.vim + func MyHandler(timer) - let s:val += 1 + let g:val += 1 endfunc func MyHandlerWithLists(lists, timer) @@ -13,44 +15,159 @@ func MyHandlerWithLists(lists, timer) endfunc func Test_oneshot() - let s:val = 0 + let g:val = 0 let timer = timer_start(50, 'MyHandler') - sleep 200m - call assert_equal(1, s:val) + let slept = WaitFor('g:val == 1') + call assert_equal(1, g:val) + if has('reltime') + call assert_inrange(40, 100, slept) + else + call assert_inrange(20, 100, slept) + endif endfunc func Test_repeat_three() - let s:val = 0 + let g:val = 0 let timer = timer_start(50, 'MyHandler', {'repeat': 3}) - sleep 500m - call assert_equal(3, s:val) + let slept = WaitFor('g:val == 3') + call assert_equal(3, g:val) + if has('reltime') + call assert_inrange(120, 250, slept) + else + call assert_inrange(80, 200, slept) + endif endfunc func Test_repeat_many() - let s:val = 0 + let g:val = 0 let timer = timer_start(50, 'MyHandler', {'repeat': -1}) sleep 200m call timer_stop(timer) - call assert_true(s:val > 1) - call assert_true(s:val < 5) + call assert_inrange(2, 4, g:val) endfunc func Test_with_partial_callback() - let s:val = 0 - let s:meow = {} - function s:meow.bite(...) - let s:val += 1 + let g:val = 0 + let meow = {'one': 1} + function meow.bite(...) + let g:val += self.one endfunction - call timer_start(50, s:meow.bite) - sleep 200m - call assert_equal(1, s:val) + call timer_start(50, meow.bite) + let slept = WaitFor('g:val == 1') + call assert_equal(1, g:val) + if has('reltime') + call assert_inrange(40, 130, slept) + else + call assert_inrange(20, 100, slept) + endif endfunc func Test_retain_partial() - call timer_start(100, function('MyHandlerWithLists', [['a']])) + call timer_start(50, function('MyHandlerWithLists', [['a']])) call garbagecollect() + sleep 100m +endfunc + +func Test_info() + let id = timer_start(1000, 'MyHandler') + let info = timer_info(id) + call assert_equal(id, info[0]['id']) + call assert_equal(1000, info[0]['time']) + call assert_equal("function('MyHandler')", string(info[0]['callback'])) + + let found = 0 + for info in timer_info() + if info['id'] == id + let found += 1 + endif + endfor + call assert_equal(1, found) + + call timer_stop(id) + call assert_equal([], timer_info(id)) +endfunc + +func Test_stopall() + let id1 = timer_start(1000, 'MyHandler') + let id2 = timer_start(2000, 'MyHandler') + let info = timer_info() + call assert_equal(2, len(info)) + + call timer_stopall() + let info = timer_info() + call assert_equal(0, len(info)) +endfunc + +func Test_paused() + let g:val = 0 + + let id = timer_start(50, 'MyHandler') + let info = timer_info(id) + call assert_equal(0, info[0]['paused']) + + call timer_pause(id, 1) + let info = timer_info(id) + call assert_equal(1, info[0]['paused']) sleep 200m + call assert_equal(0, g:val) + + call timer_pause(id, 0) + let info = timer_info(id) + call assert_equal(0, info[0]['paused']) + + let slept = WaitFor('g:val == 1') + call assert_equal(1, g:val) + if has('reltime') + call assert_inrange(0, 60, slept) + else + call assert_inrange(0, 10, slept) + endif endfunc +func StopMyself(timer) + let g:called += 1 + if g:called == 2 + call timer_stop(a:timer) + endif +endfunc + +func Test_delete_myself() + let g:called = 0 + let t = timer_start(10, 'StopMyself', {'repeat': -1}) + call WaitFor('g:called == 2') + call assert_equal(2, g:called) + call assert_equal([], timer_info(t)) +endfunc + +func StopTimer1(timer) + let g:timer2 = timer_start(10, 'StopTimer2') + " avoid maxfuncdepth error + call timer_pause(g:timer1, 1) + sleep 40m +endfunc + +func StopTimer2(timer) + call timer_stop(g:timer1) +endfunc + +func Test_stop_in_callback() + let g:timer1 = timer_start(10, 'StopTimer1') + sleep 40m +endfunc + +func StopTimerAll(timer) + call timer_stopall() +endfunc + +func Test_stop_all_in_callback() + let g:timer1 = timer_start(10, 'StopTimerAll') + let info = timer_info() + call assert_equal(1, len(info)) + sleep 40m + let info = timer_info() + call assert_equal(0, len(info)) +endfunc + + " vim: shiftwidth=2 sts=2 expandtab diff --git a/src/nvim/testdir/test_undo.vim b/src/nvim/testdir/test_undo.vim index fc61d1f223..171618f6f7 100644 --- a/src/nvim/testdir/test_undo.vim +++ b/src/nvim/testdir/test_undo.vim @@ -131,6 +131,39 @@ func Test_undo_del_chars() close! endfunc +func Test_undolist() + new + set ul=100 + + let a=execute('undolist') + call assert_equal("\nNothing to undo", a) + + " 1 leaf (2 changes). + call feedkeys('achange1', 'xt') + call feedkeys('achange2', 'xt') + let a=execute('undolist') + call assert_match("^\nnumber changes when *saved\n *2 *2 .*$", a) + + " 2 leaves. + call feedkeys('u', 'xt') + call feedkeys('achange3\<Esc>', 'xt') + let a=execute('undolist') + call assert_match("^\nnumber changes when *saved\n *2 *2 *.*\n *3 *2 .*$", a) + close! +endfunc + +func Test_U_command() + new + set ul=100 + call feedkeys("achange1\<Esc>", 'xt') + call feedkeys("achange2\<Esc>", 'xt') + norm! U + call assert_equal('', getline(1)) + norm! U + call assert_equal('change1change2', getline(1)) + close! +endfunc + func Test_undojoin() new call feedkeys("Goaaaa\<Esc>", 'xt') @@ -204,3 +237,31 @@ func Test_insert_expr() close! endfunc + +func Test_undofile_earlier() + throw 'skipped: Nvim does not support test_settime()' + + let t0 = localtime() - 43200 + call test_settime(t0) + new Xfile + call feedkeys("ione\<Esc>", 'xt') + set ul=100 + call test_settime(t0 + 1) + call feedkeys("otwo\<Esc>", 'xt') + set ul=100 + call test_settime(t0 + 2) + call feedkeys("othree\<Esc>", 'xt') + set ul=100 + w + wundo Xundofile + bwipe! + " restore normal timestamps. + call test_settime(0) + new Xfile + rundo Xundofile + earlier 1d + call assert_equal('', getline(1)) + bwipe! + call delete('Xfile') + call delete('Xundofile') +endfunc diff --git a/src/nvim/testdir/test_unlet.vim b/src/nvim/testdir/test_unlet.vim index f6705997a9..96ba752d9f 100644 --- a/src/nvim/testdir/test_unlet.vim +++ b/src/nvim/testdir/test_unlet.vim @@ -3,7 +3,7 @@ func Test_read_only() try " this caused a crash - unlet count + unlet v:count catch call assert_true(v:exception =~ ':E795:') endtry diff --git a/src/nvim/testdir/test_usercommands.vim b/src/nvim/testdir/test_usercommands.vim index d0864ec64c..db603610da 100644 --- a/src/nvim/testdir/test_usercommands.vim +++ b/src/nvim/testdir/test_usercommands.vim @@ -102,3 +102,107 @@ func Test_CmdUndefined() call assert_fails('Dothat', 'E492:') call assert_equal('yes', g:didnot) endfunc + +func Test_CmdErrors() + call assert_fails('com! docmd :', 'E183:') + call assert_fails('com! \<Tab> :', 'E182:') + call assert_fails('com! _ :', 'E182:') + call assert_fails('com! X :', 'E841:') + call assert_fails('com! - DoCmd :', 'E175:') + call assert_fails('com! -xxx DoCmd :', 'E181:') + call assert_fails('com! -addr DoCmd :', 'E179:') + call assert_fails('com! -complete DoCmd :', 'E179:') + call assert_fails('com! -complete=xxx DoCmd :', 'E180:') + call assert_fails('com! -complete=custom DoCmd :', 'E467:') + call assert_fails('com! -complete=customlist DoCmd :', 'E467:') + call assert_fails('com! -complete=behave,CustomComplete DoCmd :', 'E468:') + call assert_fails('com! -nargs=x DoCmd :', 'E176:') + call assert_fails('com! -count=1 -count=2 DoCmd :', 'E177:') + call assert_fails('com! -count=x DoCmd :', 'E178:') + call assert_fails('com! -range=x DoCmd :', 'E178:') + + com! -nargs=0 DoCmd : + call assert_fails('DoCmd x', 'E488:') + + com! -nargs=1 DoCmd : + call assert_fails('DoCmd', 'E471:') + + com! -nargs=+ DoCmd : + call assert_fails('DoCmd', 'E471:') + + call assert_fails('com DoCmd :', 'E174:') + comclear + call assert_fails('delcom DoCmd', 'E184:') +endfunc + +func CustomComplete(A, L, P) + return "January\nFebruary\nMars\n" +endfunc + +func CustomCompleteList(A, L, P) + return [ "Monday", "Tuesday", "Wednesday" ] +endfunc + +func Test_CmdCompletion() + call feedkeys(":com -\<C-A>\<C-B>\"\<CR>", 'tx') + call assert_equal('"com -addr bang bar buffer complete count nargs range register', @:) + + call feedkeys(":com -nargs=0 -\<C-A>\<C-B>\"\<CR>", 'tx') + call assert_equal('"com -nargs=0 -addr bang bar buffer complete count nargs range register', @:) + + call feedkeys(":com -nargs=\<C-A>\<C-B>\"\<CR>", 'tx') + call assert_equal('"com -nargs=* + 0 1 ?', @:) + + call feedkeys(":com -addr=\<C-A>\<C-B>\"\<CR>", 'tx') + call assert_equal('"com -addr=arguments buffers lines loaded_buffers quickfix tabs windows', @:) + + call feedkeys(":com -complete=co\<C-A>\<C-B>\"\<CR>", 'tx') + call assert_equal('"com -complete=color command compiler', @:) + + command! DoCmd1 : + command! DoCmd2 : + call feedkeys(":com \<C-A>\<C-B>\"\<CR>", 'tx') + call assert_equal('"com DoCmd1 DoCmd2', @:) + + call feedkeys(":DoC\<C-A>\<C-B>\"\<CR>", 'tx') + call assert_equal('"DoCmd1 DoCmd2', @:) + + call feedkeys(":delcom DoC\<C-A>\<C-B>\"\<CR>", 'tx') + call assert_equal('"delcom DoCmd1 DoCmd2', @:) + + delcom DoCmd1 + call feedkeys(":delcom DoC\<C-A>\<C-B>\"\<CR>", 'tx') + call assert_equal('"delcom DoCmd2', @:) + + call feedkeys(":com DoC\<C-A>\<C-B>\"\<CR>", 'tx') + call assert_equal('"com DoCmd2', @:) + + delcom DoCmd2 + call feedkeys(":delcom DoC\<C-A>\<C-B>\"\<CR>", 'tx') + call assert_equal('"delcom DoC', @:) + + call feedkeys(":com DoC\<C-A>\<C-B>\"\<CR>", 'tx') + call assert_equal('"com DoC', @:) + + com! -complete=behave DoCmd : + call feedkeys(":DoCmd \<C-A>\<C-B>\"\<CR>", 'tx') + call assert_equal('"DoCmd mswin xterm', @:) + + " This does not work. Why? + "call feedkeys(":DoCmd x\<C-A>\<C-B>\"\<CR>", 'tx') + "call assert_equal('"DoCmd xterm', @:) + + com! -complete=custom,CustomComplete DoCmd : + call feedkeys(":DoCmd \<C-A>\<C-B>\"\<CR>", 'tx') + call assert_equal('"DoCmd January February Mars', @:) + + com! -complete=customlist,CustomCompleteList DoCmd : + call feedkeys(":DoCmd \<C-A>\<C-B>\"\<CR>", 'tx') + call assert_equal('"DoCmd Monday Tuesday Wednesday', @:) + + com! -complete=custom,CustomCompleteList DoCmd : + call assert_fails("call feedkeys(':DoCmd \<C-D>', 'tx')", 'E730:') + + com! -complete=customlist,CustomComp DoCmd : + call assert_fails("call feedkeys(':DoCmd \<C-D>', 'tx')", 'E117:') +endfunc diff --git a/src/nvim/testdir/test_utf8.vim b/src/nvim/testdir/test_utf8.vim new file mode 100644 index 0000000000..24e3db86fb --- /dev/null +++ b/src/nvim/testdir/test_utf8.vim @@ -0,0 +1,65 @@ +" Tests for Unicode manipulations +if !has('multi_byte') + finish +endif + + +" Visual block Insert adjusts for multi-byte char +func Test_visual_block_insert() + new + call setline(1, ["aaa", "あああ", "bbb"]) + exe ":norm! gg0l\<C-V>jjIx\<Esc>" + call assert_equal(['axaa', 'xあああ', 'bxbb'], getline(1, '$')) + bwipeout! +endfunc + +" Test for built-in function strchars() +func Test_strchars() + let inp = ["a", "あいa", "A\u20dd", "A\u20dd\u20dd", "\u20dd"] + let exp = [[1, 1, 1], [3, 3, 3], [2, 2, 1], [3, 3, 1], [1, 1, 1]] + for i in range(len(inp)) + call assert_equal(exp[i][0], strchars(inp[i])) + call assert_equal(exp[i][1], strchars(inp[i], 0)) + call assert_equal(exp[i][2], strchars(inp[i], 1)) + endfor +endfunc + +" Test for customlist completion +function! CustomComplete1(lead, line, pos) + return ['あ', 'い'] +endfunction + +function! CustomComplete2(lead, line, pos) + return ['あたし', 'あたま', 'あたりめ'] +endfunction + +function! CustomComplete3(lead, line, pos) + return ['Nこ', 'Nん', 'Nぶ'] +endfunction + +func Test_customlist_completion() + command -nargs=1 -complete=customlist,CustomComplete1 Test1 echo + call feedkeys(":Test1 \<C-L>\<C-B>\"\<CR>", 'itx') + call assert_equal('"Test1 ', getreg(':')) + + command -nargs=1 -complete=customlist,CustomComplete2 Test2 echo + call feedkeys(":Test2 \<C-L>\<C-B>\"\<CR>", 'itx') + call assert_equal('"Test2 あた', getreg(':')) + + command -nargs=1 -complete=customlist,CustomComplete3 Test3 echo + call feedkeys(":Test3 \<C-L>\<C-B>\"\<CR>", 'itx') + call assert_equal('"Test3 N', getreg(':')) + + call garbagecollect(1) +endfunc + +" Yank one 3 byte character and check the mark columns. +func Test_getvcol() + new + call setline(1, "x\u2500x") + normal 0lvy + call assert_equal(2, col("'[")) + call assert_equal(4, col("']")) + call assert_equal(2, virtcol("'[")) + call assert_equal(2, virtcol("']")) +endfunc diff --git a/src/nvim/testdir/test_viml.vim b/src/nvim/testdir/test_vimscript.vim index a2997b6d4d..4e0f1bbd2f 100644 --- a/src/nvim/testdir/test_viml.vim +++ b/src/nvim/testdir/test_vimscript.vim @@ -1062,6 +1062,157 @@ func Test_echo_and_string() call assert_equal(["{'a': [], 'b': []}", \ "{'a': [], 'b': []}"], l) +"------------------------------------------------------------------------------- +" Test 94: 64-bit Numbers {{{1 +"------------------------------------------------------------------------------- + +func Test_num64() + if !has('num64') + return + endif + + call assert_notequal( 4294967296, 0) + call assert_notequal(-4294967296, 0) + call assert_equal( 4294967296, 0xFFFFffff + 1) + call assert_equal(-4294967296, -0xFFFFffff - 1) + + call assert_equal( 9223372036854775807, 1 / 0) + call assert_equal(-9223372036854775807, -1 / 0) + call assert_equal(-9223372036854775807 - 1, 0 / 0) + + call assert_equal( 0x7FFFffffFFFFffff, float2nr( 1.0e150)) + call assert_equal(-0x7FFFffffFFFFffff, float2nr(-1.0e150)) + + let rng = range(0xFFFFffff, 0x100000001) + call assert_equal([0xFFFFffff, 0x100000000, 0x100000001], rng) + call assert_equal(0x100000001, max(rng)) + call assert_equal(0xFFFFffff, min(rng)) + call assert_equal(rng, sort(range(0x100000001, 0xFFFFffff, -1), 'N')) +endfunc + +"------------------------------------------------------------------------------- +" Test 95: lines of :append, :change, :insert {{{1 +"------------------------------------------------------------------------------- + +function! DefineFunction(name, body) + let func = join(['function! ' . a:name . '()'] + a:body + ['endfunction'], "\n") + exec func +endfunction + +func Test_script_lines() + " :append + try + call DefineFunction('T_Append', [ + \ 'append', + \ 'py <<EOS', + \ '.', + \ ]) + catch + call assert_report("Can't define function") + endtry + try + call DefineFunction('T_Append', [ + \ 'append', + \ 'abc', + \ ]) + call assert_report("Shouldn't be able to define function") + catch + call assert_exception('Vim(function):E126: Missing :endfunction') + endtry + + " :change + try + call DefineFunction('T_Change', [ + \ 'change', + \ 'py <<EOS', + \ '.', + \ ]) + catch + call assert_report("Can't define function") + endtry + try + call DefineFunction('T_Change', [ + \ 'change', + \ 'abc', + \ ]) + call assert_report("Shouldn't be able to define function") + catch + call assert_exception('Vim(function):E126: Missing :endfunction') + endtry + + " :insert + try + call DefineFunction('T_Insert', [ + \ 'insert', + \ 'py <<EOS', + \ '.', + \ ]) + catch + call assert_report("Can't define function") + endtry + try + call DefineFunction('T_Insert', [ + \ 'insert', + \ 'abc', + \ ]) + call assert_report("Shouldn't be able to define function") + catch + call assert_exception('Vim(function):E126: Missing :endfunction') + endtry +endfunc + +"------------------------------------------------------------------------------- +" Test 96: line continuation {{{1 +" +" Undefined behavior was detected by ubsan with line continuation +" after an empty line. +"------------------------------------------------------------------------------- +func Test_script_emty_line_continuation() + + \ +endfunc + +"------------------------------------------------------------------------------- +" Test 97: bitwise functions {{{1 +"------------------------------------------------------------------------------- +func Test_bitwise_functions() + " and + call assert_equal(127, and(127, 127)) + call assert_equal(16, and(127, 16)) + call assert_equal(0, and(127, 128)) + call assert_fails("call and(1.0, 1)", 'E805:') + call assert_fails("call and([], 1)", 'E745:') + call assert_fails("call and({}, 1)", 'E728:') + call assert_fails("call and(1, 1.0)", 'E805:') + call assert_fails("call and(1, [])", 'E745:') + call assert_fails("call and(1, {})", 'E728:') + " or + call assert_equal(23, or(16, 7)) + call assert_equal(15, or(8, 7)) + call assert_equal(123, or(0, 123)) + call assert_fails("call or(1.0, 1)", 'E805:') + call assert_fails("call or([], 1)", 'E745:') + call assert_fails("call or({}, 1)", 'E728:') + call assert_fails("call or(1, 1.0)", 'E805:') + call assert_fails("call or(1, [])", 'E745:') + call assert_fails("call or(1, {})", 'E728:') + " xor + call assert_equal(0, xor(127, 127)) + call assert_equal(111, xor(127, 16)) + call assert_equal(255, xor(127, 128)) + call assert_fails("call xor(1.0, 1)", 'E805:') + call assert_fails("call xor([], 1)", 'E745:') + call assert_fails("call xor({}, 1)", 'E728:') + call assert_fails("call xor(1, 1.0)", 'E805:') + call assert_fails("call xor(1, [])", 'E745:') + call assert_fails("call xor(1, {})", 'E728:') + " invert + call assert_equal(65408, and(invert(127), 65535)) + call assert_equal(65519, and(invert(16), 65535)) + call assert_equal(65407, and(invert(128), 65535)) + call assert_fails("call invert(1.0)", 'E805:') + call assert_fails("call invert([])", 'E745:') + call assert_fails("call invert({})", 'E728:') endfunc "------------------------------------------------------------------------------- diff --git a/src/nvim/testdir/test_virtualedit.vim b/src/nvim/testdir/test_virtualedit.vim new file mode 100644 index 0000000000..2b8849f488 --- /dev/null +++ b/src/nvim/testdir/test_virtualedit.vim @@ -0,0 +1,43 @@ +" Tests for 'virtualedit'. + +func Test_yank_move_change() + new + call setline(1, [ + \ "func foo() error {", + \ "\tif n, err := bar();", + \ "\terr != nil {", + \ "\t\treturn err", + \ "\t}", + \ "\tn = n * n", + \ ]) + set virtualedit=all + set ts=4 + function! MoveSelectionDown(count) abort + normal! m` + silent! exe "'<,'>move'>+".a:count + norm! `` + endfunction + + xmap ]e :<C-U>call MoveSelectionDown(v:count1)<CR> + 2 + normal 2gg + normal J + normal jVj + normal ]e + normal ce + bwipe! + set virtualedit= + set ts=8 +endfunc + +func Test_paste_end_of_line() + new + set virtualedit=all + call setline(1, ['456', '123']) + normal! gg0"ay$ + exe "normal! 2G$lllA\<C-O>:normal! \"agP\r" + call assert_equal('123456', getline(2)) + + bwipe! + set virtualedit= +endfunc diff --git a/src/nvim/testdir/test_visual.vim b/src/nvim/testdir/test_visual.vim index cf0e535937..1694adbd32 100644 --- a/src/nvim/testdir/test_visual.vim +++ b/src/nvim/testdir/test_visual.vim @@ -1,13 +1,13 @@ -" Tests for Visual mode -if !has('multi_byte') - finish -endif - +" Tests for various Visual mode. if !has('visual') finish endif func Test_block_shift_multibyte() + " Uses double-wide character. + if !has('multi_byte') + return + endif split call setline(1, ['xヹxxx', 'ヹxxx']) exe "normal 1G0l\<C-V>jl>" @@ -15,3 +15,31 @@ func Test_block_shift_multibyte() call assert_equal(' ヹxxx', getline(2)) q! endfunc + +func Test_Visual_ctrl_o() + new + call setline(1, ['one', 'two', 'three']) + call cursor(1,2) + set noshowmode + set tw=0 + call feedkeys("\<c-v>jjlIa\<c-\>\<c-o>:set tw=88\<cr>\<esc>", 'tx') + call assert_equal(['oane', 'tawo', 'tahree'], getline(1, 3)) + call assert_equal(88, &tw) + set tw& + bw! +endfu + +func Test_Visual_vapo() + new + normal oxx + normal vapo + bwipe! +endfunc + +func Test_dotregister_paste() + new + exe "norm! ihello world\<esc>" + norm! 0ve".p + call assert_equal('hello world world', getline(1)) + q! +endfunc diff --git a/src/nvim/testdir/test_window_cmd.vim b/src/nvim/testdir/test_window_cmd.vim index 569a78a0ed..9d61921988 100644 --- a/src/nvim/testdir/test_window_cmd.vim +++ b/src/nvim/testdir/test_window_cmd.vim @@ -67,4 +67,360 @@ 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 + call assert_equal(2, winnr('$')) + call assert_equal('Xb', bufname(winbufnr(1))) + call assert_equal('Xa', bufname(winbufnr(2))) + + wincmd q + call assert_equal(1, winnr('$')) + call assert_equal('Xa', bufname(winbufnr(1))) + + bw Xa Xb +endfunc + +func Test_window_horizontal_split() + call assert_equal(1, winnr('$')) + 3wincmd s + call assert_equal(2, winnr('$')) + call assert_equal(3, winheight(0)) + call assert_equal(winwidth(1), winwidth(2)) + + call assert_fails('botright topleft wincmd s', 'E442:') + bw +endfunc + +func Test_window_vertical_split() + call assert_equal(1, winnr('$')) + 3wincmd v + call assert_equal(2, winnr('$')) + call assert_equal(3, winwidth(0)) + call assert_equal(winheight(1), winheight(2)) + + call assert_fails('botright topleft wincmd v', 'E442:') + bw +endfunc + +func Test_window_split_edit_alternate() + e Xa + e Xb + + wincmd ^ + call assert_equal('Xa', bufname(winbufnr(1))) + call assert_equal('Xb', bufname(winbufnr(2))) + + bw Xa Xb +endfunc + +func Test_window_preview() + " Open a preview window + pedit Xa + call assert_equal(2, winnr('$')) + call assert_equal(0, &previewwindow) + + " Go to the preview window + wincmd P + call assert_equal(1, &previewwindow) + + " Close preview window + wincmd z + call assert_equal(1, winnr('$')) + call assert_equal(0, &previewwindow) + + call assert_fails('wincmd P', 'E441:') +endfunc + +func Test_window_exchange() + e Xa + + " Nothing happens with window exchange when there is 1 window + wincmd x + call assert_equal(1, winnr('$')) + + split Xb + split Xc + + call assert_equal('Xc', bufname(winbufnr(1))) + call assert_equal('Xb', bufname(winbufnr(2))) + call assert_equal('Xa', bufname(winbufnr(3))) + + " Exchange current window 1 with window 3 + 3wincmd x + call assert_equal('Xa', bufname(winbufnr(1))) + call assert_equal('Xb', bufname(winbufnr(2))) + call assert_equal('Xc', bufname(winbufnr(3))) + + " Exchange window with next when at the top window + wincmd x + call assert_equal('Xb', bufname(winbufnr(1))) + call assert_equal('Xa', bufname(winbufnr(2))) + call assert_equal('Xc', bufname(winbufnr(3))) + + " Exchange window with next when at the middle window + wincmd j + wincmd x + call assert_equal('Xb', bufname(winbufnr(1))) + call assert_equal('Xc', bufname(winbufnr(2))) + call assert_equal('Xa', bufname(winbufnr(3))) + + " Exchange window with next when at the bottom window. + " When there is no next window, it exchanges with the previous window. + wincmd j + wincmd x + call assert_equal('Xb', bufname(winbufnr(1))) + call assert_equal('Xa', bufname(winbufnr(2))) + call assert_equal('Xc', bufname(winbufnr(3))) + + bw Xa Xb Xc +endfunc + +func Test_window_rotate() + e Xa + split Xb + split Xc + call assert_equal('Xc', bufname(winbufnr(1))) + call assert_equal('Xb', bufname(winbufnr(2))) + call assert_equal('Xa', bufname(winbufnr(3))) + + " Rotate downwards + wincmd r + call assert_equal('Xa', bufname(winbufnr(1))) + call assert_equal('Xc', bufname(winbufnr(2))) + call assert_equal('Xb', bufname(winbufnr(3))) + + 2wincmd r + call assert_equal('Xc', bufname(winbufnr(1))) + call assert_equal('Xb', bufname(winbufnr(2))) + call assert_equal('Xa', bufname(winbufnr(3))) + + " Rotate upwards + wincmd R + call assert_equal('Xb', bufname(winbufnr(1))) + call assert_equal('Xa', bufname(winbufnr(2))) + call assert_equal('Xc', bufname(winbufnr(3))) + + 2wincmd R + call assert_equal('Xc', bufname(winbufnr(1))) + call assert_equal('Xb', bufname(winbufnr(2))) + call assert_equal('Xa', bufname(winbufnr(3))) + + bot vsplit + call assert_fails('wincmd R', 'E443:') + + bw Xa Xb Xc +endfunc + +func Test_window_height() + e Xa + split Xb + + let [wh1, wh2] = [winheight(1), winheight(2)] + " Active window (1) should have the same height or 1 more + " than the other window. + call assert_inrange(wh2, wh2 + 1, wh1) + + wincmd - + call assert_equal(wh1 - 1, winheight(1)) + call assert_equal(wh2 + 1, winheight(2)) + + wincmd + + call assert_equal(wh1, winheight(1)) + call assert_equal(wh2, winheight(2)) + + 2wincmd _ + call assert_equal(2, winheight(1)) + call assert_equal(wh1 + wh2 - 2, winheight(2)) + + wincmd = + call assert_equal(wh1, winheight(1)) + call assert_equal(wh2, winheight(2)) + + 2wincmd _ + set winfixheight + split Xc + let [wh1, wh2, wh3] = [winheight(1), winheight(2), winheight(3)] + call assert_equal(2, winheight(2)) + call assert_inrange(wh3, wh3 + 1, wh1) + 3wincmd + + call assert_equal(2, winheight(2)) + call assert_equal(wh1 + 3, winheight(1)) + call assert_equal(wh3 - 3, winheight(3)) + wincmd = + call assert_equal(2, winheight(2)) + call assert_equal(wh1, winheight(1)) + call assert_equal(wh3, winheight(3)) + + wincmd j + set winfixheight& + + wincmd = + let [wh1, wh2, wh3] = [winheight(1), winheight(2), winheight(3)] + " Current window (2) should have the same height or 1 more + " than the other windows. + call assert_inrange(wh1, wh1 + 1, wh2) + call assert_inrange(wh3, wh3 + 1, wh2) + + bw Xa Xb Xc +endfunc + +func Test_window_width() + e Xa + vsplit Xb + + let [ww1, ww2] = [winwidth(1), winwidth(2)] + " Active window (1) should have the same width or 1 more + " than the other window. + call assert_inrange(ww2, ww2 + 1, ww1) + + wincmd < + call assert_equal(ww1 - 1, winwidth(1)) + call assert_equal(ww2 + 1, winwidth(2)) + + wincmd > + call assert_equal(ww1, winwidth(1)) + call assert_equal(ww2, winwidth(2)) + + 2wincmd | + call assert_equal(2, winwidth(1)) + call assert_equal(ww1 + ww2 - 2, winwidth(2)) + + wincmd = + call assert_equal(ww1, winwidth(1)) + call assert_equal(ww2, winwidth(2)) + + 2wincmd | + set winfixwidth + vsplit Xc + let [ww1, ww2, ww3] = [winwidth(1), winwidth(2), winwidth(3)] + " FIXME: commented out: I would expect the width of 2nd window to + " remain 2 but it's actually 1?! + "call assert_equal(2, winwidth(2)) + call assert_inrange(ww3, ww3 + 1, ww1) + 3wincmd > + " FIXME: commented out: I would expect the width of 2nd window to + " remain 2 but it's actually 1?! + "call assert_equal(2, winwidth(2)) + call assert_equal(ww1 + 3, winwidth(1)) + call assert_equal(ww3 - 3, winwidth(3)) + wincmd = + " FIXME: commented out: I would expect the width of 2nd window to + " remain 2 but it's actually 1?! + "call assert_equal(2, winwidth(2)) + call assert_equal(ww1, winwidth(1)) + call assert_equal(ww3, winwidth(3)) + + wincmd l + set winfixwidth& + + wincmd = + let [ww1, ww2, ww3] = [winwidth(1), winwidth(2), winwidth(3)] + " Current window (2) should have the same width or 1 more + " than the other windows. + call assert_inrange(ww1, ww1 + 1, ww2) + call assert_inrange(ww3, ww3 + 1, ww2) + + bw Xa Xb Xc +endfunc + +func Test_equalalways_on_close() + set equalalways + vsplit + windo split + split + wincmd J + " now we have a frame top-left with two windows, a frame top-right with two + " windows and a frame at the bottom, full-width. + let height_1 = winheight(1) + let height_2 = winheight(2) + let height_3 = winheight(3) + let height_4 = winheight(4) + " closing the bottom window causes all windows to be resized. + close + call assert_notequal(height_1, winheight(1)) + call assert_notequal(height_2, winheight(2)) + call assert_notequal(height_3, winheight(3)) + call assert_notequal(height_4, winheight(4)) + call assert_equal(winheight(1), winheight(3)) + call assert_equal(winheight(2), winheight(4)) + + 1wincmd w + split + 4wincmd w + resize + 5 + " left column has three windows, equalized heights. + " right column has two windows, top one a bit higher + let height_1 = winheight(1) + let height_2 = winheight(2) + let height_4 = winheight(4) + let height_5 = winheight(5) + 3wincmd w + " closing window in left column equalizes heights in left column but not in + " the right column + close + call assert_notequal(height_1, winheight(1)) + call assert_notequal(height_2, winheight(2)) + call assert_equal(height_4, winheight(3)) + call assert_equal(height_5, winheight(4)) + + only + set equalalways& +endfunc + +func Test_window_jump_tag() + help + /iccf + call assert_match('^|iccf|', getline('.')) + call assert_equal(2, winnr('$')) + 2wincmd } + call assert_equal(3, winnr('$')) + call assert_match('^|iccf|', getline('.')) + wincmd k + call assert_match('\*iccf\*', getline('.')) + call assert_equal(2, winheight(0)) + + wincmd z + set previewheight=4 + help + /bugs + wincmd } + wincmd k + call assert_match('\*bugs\*', getline('.')) + call assert_equal(4, winheight(0)) + set previewheight& + + %bw! +endfunc + +func Test_window_newtab() + e Xa + + call assert_equal(1, tabpagenr('$')) + call assert_equal("\nAlready only one window", execute('wincmd T')) + + split Xb + split Xc + + wincmd T + call assert_equal(2, tabpagenr('$')) + call assert_equal(['Xb', 'Xa'], map(tabpagebuflist(1), 'bufname(v:val)')) + call assert_equal(['Xc' ], map(tabpagebuflist(2), 'bufname(v:val)')) + + %bw! +endfunc + + " vim: shiftwidth=2 sts=2 expandtab diff --git a/src/nvim/testdir/test_window_id.vim b/src/nvim/testdir/test_window_id.vim index 66656e1d0a..b3b506d04d 100644 --- a/src/nvim/testdir/test_window_id.vim +++ b/src/nvim/testdir/test_window_id.vim @@ -92,3 +92,12 @@ func Test_win_getid() only! endfunc + +func Test_win_getid_curtab() + tabedit X + tabfirst + copen + only + call assert_equal(win_getid(1), win_getid(1, 1)) + tabclose! +endfunc diff --git a/src/nvim/testdir/view_util.vim b/src/nvim/testdir/view_util.vim new file mode 100644 index 0000000000..eb92630761 --- /dev/null +++ b/src/nvim/testdir/view_util.vim @@ -0,0 +1,30 @@ +" Functions about view shared by several tests + +" ScreenLines(lnum, width) or +" ScreenLines([start, end], width) +function! ScreenLines(lnum, width) abort + redraw! + if type(a:lnum) == v:t_list + let start = a:lnum[0] + let end = a:lnum[1] + else + let start = a:lnum + let end = a:lnum + endif + let lines = [] + for l in range(start, end) + let lines += [join(map(range(1, a:width), 'nr2char(screenchar(l, v:val))'), '')] + endfor + return lines +endfunction + +function! NewWindow(height, width) abort + exe a:height . 'new' + exe a:width . 'vsp' + redraw! +endfunction + +function! CloseWindow() abort + bw! + redraw! +endfunction |