changeset 19370:02111977dd05 v8.2.0243

patch 8.2.0243: insufficient code coverage for ex_docmd.c functions Commit: https://github.com/vim/vim/commit/9f6277bdde97b7767ded43a0b5a2023eb601b3b7 Author: Bram Moolenaar <Bram@vim.org> Date: Tue Feb 11 22:04:02 2020 +0100 patch 8.2.0243: insufficient code coverage for ex_docmd.c functions Problem: Insufficient code coverage for ex_docmd.c functions. Solution: Add more tests. (Yegappan Lakshmanan, closes https://github.com/vim/vim/issues/5618)
author Bram Moolenaar <Bram@vim.org>
date Tue, 11 Feb 2020 22:15:04 +0100
parents 05c259d4233d
children 53ee2ee9e831
files src/testdir/Make_all.mak src/testdir/test_arglist.vim src/testdir/test_buffer.vim src/testdir/test_cd.vim src/testdir/test_cmdline.vim src/testdir/test_ex_mode.vim src/testdir/test_excmd.vim src/testdir/test_mapping.vim src/testdir/test_quickfix.vim src/testdir/test_search.vim src/testdir/test_sort.vim src/testdir/test_source.vim src/testdir/test_substitute.vim src/testdir/test_undo.vim src/testdir/test_vimscript.vim src/testdir/test_window_cmd.vim src/version.c
diffstat 17 files changed, 399 insertions(+), 46 deletions(-) [+]
line wrap: on
line diff
--- a/src/testdir/Make_all.mak
+++ b/src/testdir/Make_all.mak
@@ -60,6 +60,7 @@ NEW_TESTS = \
 	test_blob \
 	test_blockedit \
 	test_breakindent \
+	test_buffer \
 	test_bufline \
 	test_bufwintabinfo \
 	test_cd \
@@ -305,6 +306,7 @@ NEW_TESTS_RES = \
 	test_blob.res \
 	test_blockedit.res \
 	test_breakindent.res \
+	test_buffer.res \
 	test_bufline.res \
 	test_bufwintabinfo.res \
 	test_cd.res \
--- a/src/testdir/test_arglist.vim
+++ b/src/testdir/test_arglist.vim
@@ -1,5 +1,8 @@
 " Test argument list commands
 
+source shared.vim
+source term_util.vim
+
 func Test_argidx()
   args a b c
   last
@@ -505,3 +508,17 @@ func Test_argdo()
   call assert_equal(['Xa.c', 'Xb.c', 'Xc.c'], l)
   bwipe Xa.c Xb.c Xc.c
 endfunc
+
+" Test for quiting Vim with unedited files in the argument list
+func Test_quit_with_arglist()
+  if !CanRunVimInTerminal()
+    throw 'Skipped: cannot run vim in terminal'
+  endif
+  let buf = RunVimInTerminal('', {'rows': 6})
+  call term_sendkeys(buf, ":args a b c\n")
+  call term_sendkeys(buf, ":quit\n")
+  call WaitForAssert({-> assert_match('^E173:', term_getline(buf, 6))})
+  call StopVimInTerminal(buf)
+endfunc
+
+" vim: shiftwidth=2 sts=2 expandtab
new file mode 100644
--- /dev/null
+++ b/src/testdir/test_buffer.vim
@@ -0,0 +1,66 @@
+" Tests for Vim buffer
+
+" Test for the :bunload command with an offset
+func Test_bunload_with_offset()
+  %bwipe!
+  call writefile(['B1'], 'b1')
+  call writefile(['B2'], 'b2')
+  call writefile(['B3'], 'b3')
+  call writefile(['B4'], 'b4')
+
+  " Load four buffers. Unload the second and third buffers and then
+  " execute .+3bunload to unload the last buffer.
+  edit b1
+  new b2
+  new b3
+  new b4
+
+  bunload b2
+  bunload b3
+  exe bufwinnr('b1') . 'wincmd w'
+  .+3bunload
+  call assert_equal(0, getbufinfo('b4')[0].loaded)
+  call assert_equal('b1',
+        \ fnamemodify(getbufinfo({'bufloaded' : 1})[0].name, ':t'))
+
+  " Load four buffers. Unload the third and fourth buffers. Execute .+3bunload
+  " and check whether the second buffer is unloaded.
+  ball
+  bunload b3
+  bunload b4
+  exe bufwinnr('b1') . 'wincmd w'
+  .+3bunload
+  call assert_equal(0, getbufinfo('b2')[0].loaded)
+  call assert_equal('b1',
+        \ fnamemodify(getbufinfo({'bufloaded' : 1})[0].name, ':t'))
+
+  " Load four buffers. Unload the second and third buffers and from the last
+  " buffer execute .-3bunload to unload the first buffer.
+  ball
+  bunload b2
+  bunload b3
+  exe bufwinnr('b4') . 'wincmd w'
+  .-3bunload
+  call assert_equal(0, getbufinfo('b1')[0].loaded)
+  call assert_equal('b4',
+        \ fnamemodify(getbufinfo({'bufloaded' : 1})[0].name, ':t'))
+
+  " Load four buffers. Unload the first and second buffers. Execute .-3bunload
+  " from the last buffer and check whether the third buffer is unloaded.
+  ball
+  bunload b1
+  bunload b2
+  exe bufwinnr('b4') . 'wincmd w'
+  .-3bunload
+  call assert_equal(0, getbufinfo('b3')[0].loaded)
+  call assert_equal('b4',
+        \ fnamemodify(getbufinfo({'bufloaded' : 1})[0].name, ':t'))
+
+  %bwipe!
+  call delete('b1')
+  call delete('b2')
+  call delete('b3')
+  call delete('b4')
+endfunc
+
+" vim: shiftwidth=2 sts=2 expandtab
--- a/src/testdir/test_cd.vim
+++ b/src/testdir/test_cd.vim
@@ -1,5 +1,7 @@
 " Test for :cd and chdir()
 
+source shared.vim
+
 func Test_cd_large_path()
   " This used to crash with a heap write overflow.
   call assert_fails('cd ' . repeat('x', 5000), 'E472:')
@@ -40,6 +42,20 @@ func Test_cd_minus()
   call assert_equal(path_dotdot, getcwd())
   cd -
   call assert_equal(path, getcwd())
+
+  " Test for :cd - without a previous directory
+  let lines =<< trim [SCRIPT]
+    call assert_fails('cd -', 'E186:')
+    call assert_fails('call chdir("-")', 'E186:')
+    call writefile(v:errors, 'Xresult')
+    qall!
+  [SCRIPT]
+  call writefile(lines, 'Xscript')
+  if RunVim([], [], '--clean -S Xscript')
+    call assert_equal([], readfile('Xresult'))
+  endif
+  call delete('Xscript')
+  call delete('Xresult')
 endfunc
 
 func Test_cd_with_cpo_chdir()
--- a/src/testdir/test_cmdline.vim
+++ b/src/testdir/test_cmdline.vim
@@ -923,4 +923,13 @@ func Test_cmdlineclear_tabenter()
   call delete('XtestCmdlineClearTabenter')
 endfunc
 
+" Test for failure in expanding special keywords in cmdline
+func Test_cmdline_expand_special()
+  %bwipe!
+  call assert_fails('e #', 'E499:')
+  call assert_fails('e <afile>', 'E495:')
+  call assert_fails('e <abuf>', 'E496:')
+  call assert_fails('e <amatch>', 'E497:')
+endfunc
+
 " vim: shiftwidth=2 sts=2 expandtab
--- a/src/testdir/test_ex_mode.vim
+++ b/src/testdir/test_ex_mode.vim
@@ -84,4 +84,26 @@ func Test_Ex_substitute()
   call StopVimInTerminal(buf)
 endfunc
 
+" Test for displaying lines from an empty buffer in Ex mode
+func Test_Ex_emptybuf()
+  new
+  call assert_fails('call feedkeys("Q\<CR>", "xt")', 'E749:')
+  call setline(1, "abc")
+  call assert_fails('call feedkeys("Q\<CR>", "xt")', 'E501:')
+  call assert_fails('call feedkeys("Q%d\<CR>", "xt")', 'E749:')
+  close!
+endfunc
+
+" Test for the :open command
+func Test_open_command()
+  new
+  call setline(1, ['foo foo', 'foo bar', 'foo baz'])
+  call feedkeys("Qopen\<CR>j", 'xt')
+  call assert_equal('foo bar', getline('.'))
+  call feedkeys("Qopen /bar/\<CR>", 'xt')
+  call assert_equal(5, col('.'))
+  call assert_fails('call feedkeys("Qopen /baz/\<CR>", "xt")', 'E479:')
+  close!
+endfunc
+
 " vim: shiftwidth=2 sts=2 expandtab
--- a/src/testdir/test_excmd.vim
+++ b/src/testdir/test_excmd.vim
@@ -20,6 +20,7 @@ func Test_range_error()
   call assert_fails(':\/echo 1', 'E481:')
   normal vv
   call assert_fails(":'<,'>echo 1", 'E481:')
+  call assert_fails(":\\xcenter", 'E10:')
 endfunc
 
 func Test_buffers_lastused()
@@ -241,4 +242,41 @@ func Test_confirm_cmd()
   call delete('bar')
 endfunc
 
+" Test for the :print command
+func Test_print_cmd()
+  call assert_fails('print', 'E749:')
+endfunc
+
+" Test for the :winsize command
+func Test_winsize_cmd()
+  call assert_fails('winsize 1', 'E465:')
+endfunc
+
+" Test for the :redir command
+func Test_redir_cmd()
+  call assert_fails('redir @@', 'E475:')
+  call assert_fails('redir abc', 'E475:')
+  if has('unix')
+    call mkdir('Xdir')
+    call assert_fails('redir > Xdir', 'E17:')
+    call delete('Xdir', 'd')
+  endif
+  if !has('bsd')
+    call writefile([], 'Xfile')
+    call setfperm('Xfile', 'r--r--r--')
+    call assert_fails('redir! > Xfile', 'E190:')
+    call delete('Xfile')
+  endif
+endfunc
+
+" Test for the :filetype command
+func Test_filetype_cmd()
+  call assert_fails('filetype abc', 'E475:')
+endfunc
+
+" Test for the :mode command
+func Test_mode_cmd()
+  call assert_fails('mode abc', 'E359:')
+endfunc
+
 " vim: shiftwidth=2 sts=2 expandtab
--- a/src/testdir/test_mapping.vim
+++ b/src/testdir/test_mapping.vim
@@ -552,6 +552,13 @@ func Test_map_error()
   map <expr> ,f abc
   call assert_fails('normal ,f', 'E121:')
   unmap <expr> ,f
+
+  " Recursive use of :normal in a map
+  set maxmapdepth=100
+  map gq :normal gq<CR>
+  call assert_fails('normal gq', 'E192:')
+  unmap gq
+  set maxmapdepth&
 endfunc
 
 " Test for <special> key mapping
--- a/src/testdir/test_quickfix.vim
+++ b/src/testdir/test_quickfix.vim
@@ -2725,10 +2725,6 @@ func XvimgrepTests(cchar)
   call assert_equal(0, getbufinfo('Xtestfile1')[0].loaded)
   call assert_equal([], getbufinfo('Xtestfile2'))
 
-  " Test with the last search pattern not set
-  call test_clear_search_pat()
-  call assert_fails('Xvimgrep // *', 'E35:')
-
   call delete('Xtestfile1')
   call delete('Xtestfile2')
 endfunc
@@ -2754,6 +2750,21 @@ func Test_vimgrep_incsearch()
   set noincsearch
 endfunc
 
+" Test vimgrep with the last search pattern not set
+func Test_vimgrep_with_no_last_search_pat()
+  let lines =<< trim [SCRIPT]
+    call assert_fails('vimgrep // *', 'E35:')
+    call writefile(v:errors, 'Xresult')
+    qall!
+  [SCRIPT]
+  call writefile(lines, 'Xscript')
+  if RunVim([], [], '--clean -S Xscript')
+    call assert_equal([], readfile('Xresult'))
+  endif
+  call delete('Xscript')
+  call delete('Xresult')
+endfunc
+
 func XfreeTests(cchar)
   call s:setup_commands(a:cchar)
 
--- a/src/testdir/test_search.vim
+++ b/src/testdir/test_search.vim
@@ -1457,42 +1457,62 @@ func Test_search_special()
 endfunc
 
 " Test for command failures when the last search pattern is not set.
+" Need to run this in a new vim instance where last search pattern is not set.
 func Test_search_with_no_last_pat()
-  call test_clear_search_pat()
-  call assert_fails("normal i\<C-R>/\e", 'E35:')
-  call assert_fails("exe '/'", 'E35:')
-  call assert_fails("exe '?'", 'E35:')
-  call assert_fails("/", 'E35:')
-  call assert_fails("?", 'E35:')
-  call assert_fails("normal n", 'E35:')
-  call assert_fails("normal N", 'E35:')
-  call assert_fails("normal gn", 'E35:')
-  call assert_fails("normal gN", 'E35:')
-  call assert_fails("normal cgn", 'E35:')
-  call assert_fails("normal cgN", 'E35:')
-  let p = []
-  let p = @/
-  call assert_equal('', p)
-  call assert_fails("normal :\<C-R>/", 'E35:')
-  call assert_fails("//p", 'E35:')
-  call assert_fails(";//p", 'E35:')
-  call assert_fails("??p", 'E35:')
-  call assert_fails(";??p", 'E35:')
-  call assert_fails('g//p', 'E476:')
-  call assert_fails('v//p', 'E476:')
+  let lines =<< trim [SCRIPT]
+    call assert_fails("normal i\<C-R>/\e", 'E35:')
+    call assert_fails("exe '/'", 'E35:')
+    call assert_fails("exe '?'", 'E35:')
+    call assert_fails("/", 'E35:')
+    call assert_fails("?", 'E35:')
+    call assert_fails("normal n", 'E35:')
+    call assert_fails("normal N", 'E35:')
+    call assert_fails("normal gn", 'E35:')
+    call assert_fails("normal gN", 'E35:')
+    call assert_fails("normal cgn", 'E35:')
+    call assert_fails("normal cgN", 'E35:')
+    let p = []
+    let p = @/
+    call assert_equal('', p)
+    call assert_fails("normal :\<C-R>/", 'E35:')
+    call assert_fails("//p", 'E35:')
+    call assert_fails(";//p", 'E35:')
+    call assert_fails("??p", 'E35:')
+    call assert_fails(";??p", 'E35:')
+    call assert_fails('g//p', 'E476:')
+    call assert_fails('v//p', 'E476:')
+    call writefile(v:errors, 'Xresult')
+    qall!
+  [SCRIPT]
+  call writefile(lines, 'Xscript')
+
+  if RunVim([], [], '--clean -S Xscript')
+    call assert_equal([], readfile('Xresult'))
+  endif
+  call delete('Xscript')
+  call delete('Xresult')
 endfunc
 
 " Test for using tilde (~) atom in search. This should use the last used
 " substitute pattern
 func Test_search_tilde_pat()
-  call test_clear_search_pat()
-  set regexpengine=1
-  call assert_fails('exe "normal /~\<CR>"', 'E33:')
-  call assert_fails('exe "normal ?~\<CR>"', 'E33:')
-  set regexpengine=2
-  call assert_fails('exe "normal /~\<CR>"', 'E383:')
-  call assert_fails('exe "normal ?~\<CR>"', 'E383:')
-  set regexpengine&
+  let lines =<< trim [SCRIPT]
+    set regexpengine=1
+    call assert_fails('exe "normal /~\<CR>"', 'E33:')
+    call assert_fails('exe "normal ?~\<CR>"', 'E33:')
+    set regexpengine=2
+    call assert_fails('exe "normal /~\<CR>"', 'E383:')
+    call assert_fails('exe "normal ?~\<CR>"', 'E383:')
+    set regexpengine&
+    call writefile(v:errors, 'Xresult')
+    qall!
+  [SCRIPT]
+  call writefile(lines, 'Xscript')
+  if RunVim([], [], '--clean -S Xscript')
+    call assert_equal([], readfile('Xresult'))
+  endif
+  call delete('Xscript')
+  call delete('Xresult')
 endfunc
 
 " vim: shiftwidth=2 sts=2 expandtab
--- a/src/testdir/test_sort.vim
+++ b/src/testdir/test_sort.vim
@@ -1383,11 +1383,25 @@ func Test_sort_last_search_pat()
   call setline(1, ['3b', '1c', '2a'])
   sort //
   call assert_equal(['2a', '3b', '1c'], getline(1, '$'))
-  call test_clear_search_pat()
-  call assert_fails('sort //', 'E35:')
   close!
 endfunc
 
+" Test for :sort with no last search pattern
+func Test_sort_with_no_last_search_pat()
+  let lines =<< trim [SCRIPT]
+    call setline(1, ['3b', '1c', '2a'])
+    call assert_fails('sort //', 'E35:')
+    call writefile(v:errors, 'Xresult')
+    qall!
+  [SCRIPT]
+  call writefile(lines, 'Xscript')
+  if RunVim([], [], '--clean -S Xscript')
+    call assert_equal([], readfile('Xresult'))
+  endif
+  call delete('Xscript')
+  call delete('Xresult')
+endfunc
+
 " Test for retaining marks across a :sort
 func Test_sort_with_marks()
   new
--- a/src/testdir/test_source.vim
+++ b/src/testdir/test_source.vim
@@ -57,3 +57,13 @@ func Test_different_script()
   call assert_fails('source XtwoScript', 'E121:')
   call delete('XtwoScript')
 endfunc
+
+" When sourcing a vim script, shebang should be ignored.
+func Test_source_ignore_shebang()
+  call writefile(['#!./xyzabc', 'let g:val=369'], 'Xfile.vim')
+  source Xfile.vim
+  call assert_equal(g:val, 369)
+  call delete('Xfile.vim')
+endfunc
+
+" vim: shiftwidth=2 sts=2 expandtab
--- a/src/testdir/test_substitute.vim
+++ b/src/testdir/test_substitute.vim
@@ -1,5 +1,7 @@
 " Tests for multi-line regexps with ":s".
 
+source shared.vim
+
 func Test_multiline_subst()
   enew!
   call append(0, ["1 aa",
@@ -805,17 +807,32 @@ endfunc
 
 " Test for command failures when the last substitute pattern is not set.
 func Test_sub_with_no_last_pat()
-  call test_clear_search_pat()
-  call assert_fails('~', 'E33:')
-  call assert_fails('s//abc/g', 'E476:')
-  call assert_fails('s\/bar', 'E476:')
-  call assert_fails('s\&bar&', 'E476:')
+  let lines =<< trim [SCRIPT]
+    call assert_fails('~', 'E33:')
+    call assert_fails('s//abc/g', 'E476:')
+    call assert_fails('s\/bar', 'E476:')
+    call assert_fails('s\&bar&', 'E476:')
+    call writefile(v:errors, 'Xresult')
+    qall!
+  [SCRIPT]
+  call writefile(lines, 'Xscript')
+  if RunVim([], [], '--clean -S Xscript')
+    call assert_equal([], readfile('Xresult'))
+  endif
 
-  call test_clear_search_pat()
-  let save_cpo = &cpo
-  set cpo+=/
-  call assert_fails('s/abc/%/', 'E33:')
-  let &cpo = save_cpo
+  let lines =<< trim [SCRIPT]
+    set cpo+=/
+    call assert_fails('s/abc/%/', 'E33:')
+    call writefile(v:errors, 'Xresult')
+    qall!
+  [SCRIPT]
+  call writefile(lines, 'Xscript')
+  if RunVim([], [], '--clean -S Xscript')
+    call assert_equal([], readfile('Xresult'))
+  endif
+
+  call delete('Xscript')
+  call delete('Xresult')
 endfunc
 
 " vim: shiftwidth=2 sts=2 expandtab
--- a/src/testdir/test_undo.vim
+++ b/src/testdir/test_undo.vim
@@ -295,6 +295,8 @@ func Test_undo_write()
   close!
   call delete('Xtest')
   bwipe! Xtest
+
+  call assert_fails('earlier xyz', 'E475:')
 endfunc
 
 func Test_insert_expr()
--- a/src/testdir/test_vimscript.vim
+++ b/src/testdir/test_vimscript.vim
@@ -1975,6 +1975,92 @@ func Test_function_defined_line()
     call delete('Xtest.vim')
 endfunc
 
+" Test for missing :endif, :endfor, :endwhile and :endtry           {{{1
+func Test_missing_end()
+  call writefile(['if 2 > 1', 'echo ">"'], 'Xscript')
+  call assert_fails('source Xscript', 'E171:')
+  call writefile(['for i in range(5)', 'echo i'], 'Xscript')
+  call assert_fails('source Xscript', 'E170:')
+  call writefile(['while v:true', 'echo "."'], 'Xscript')
+  call assert_fails('source Xscript', 'E170:')
+  call writefile(['try', 'echo "."'], 'Xscript')
+  call assert_fails('source Xscript', 'E600:')
+  call delete('Xscript')
+endfunc
+
+" Test for deep nesting of if/for/while/try statements              {{{1
+func Test_deep_nest()
+  if !CanRunVimInTerminal()
+    throw 'Skipped: cannot run vim in terminal'
+  endif
+
+  let lines =<< trim [SCRIPT]
+    " Deep nesting of if ... endif
+    func Test1()
+      let @a = join(repeat(['if v:true'], 51), "\n")
+      let @a ..= "\n"
+      let @a ..= join(repeat(['endif'], 51), "\n")
+      @a
+      let @a = ''
+    endfunc
+
+    " Deep nesting of for ... endfor
+    func Test2()
+      let @a = join(repeat(['for i in [1]'], 51), "\n")
+      let @a ..= "\n"
+      let @a ..= join(repeat(['endfor'], 51), "\n")
+      @a
+      let @a = ''
+    endfunc
+
+    " Deep nesting of while ... endwhile
+    func Test3()
+      let @a = join(repeat(['while v:true'], 51), "\n")
+      let @a ..= "\n"
+      let @a ..= join(repeat(['endwhile'], 51), "\n")
+      @a
+      let @a = ''
+    endfunc
+
+    " Deep nesting of try ... endtry
+    func Test4()
+      let @a = join(repeat(['try'], 51), "\n")
+      let @a ..= "\necho v:true\n"
+      let @a ..= join(repeat(['endtry'], 51), "\n")
+      @a
+      let @a = ''
+    endfunc
+  [SCRIPT]
+  call writefile(lines, 'Xscript')
+
+  let buf = RunVimInTerminal('-S Xscript', {'rows': 6})
+
+  " Deep nesting of if ... endif
+  call term_sendkeys(buf, ":call Test1()\n")
+  call WaitForAssert({-> assert_match('^E579:', term_getline(buf, 5))})
+
+  " Deep nesting of for ... endfor
+  call term_sendkeys(buf, ":call Test2()\n")
+  call WaitForAssert({-> assert_match('^E585:', term_getline(buf, 5))})
+
+  " Deep nesting of while ... endwhile
+  call term_sendkeys(buf, ":call Test3()\n")
+  call WaitForAssert({-> assert_match('^E585:', term_getline(buf, 5))})
+
+  " Deep nesting of try ... endtry
+  call term_sendkeys(buf, ":call Test4()\n")
+  call WaitForAssert({-> assert_match('^E601:', term_getline(buf, 5))})
+
+  "let l = ''
+  "for i in range(1, 6)
+  "  let l ..= term_getline(buf, i) . "\n"
+  "endfor
+  "call assert_report(l)
+
+  call StopVimInTerminal(buf)
+  call delete('Xscript')
+endfunc
+
 "-------------------------------------------------------------------------------
 " Modelines								    {{{1
 " vim: ts=8 sw=2 sts=2 expandtab tw=80 fdm=marker
--- a/src/testdir/test_window_cmd.vim
+++ b/src/testdir/test_window_cmd.vim
@@ -942,4 +942,18 @@ func Test_window_only()
   only!
 endfunc
 
+" Test for errors with :wincmd
+func Test_wincmd_errors()
+  call assert_fails('wincmd g', 'E474:')
+  call assert_fails('wincmd ab', 'E474:')
+endfunc
+
+" Test for errors with :winpos
+func Test_winpos_errors()
+  if !has("gui_running") && !has('win32')
+    call assert_fails('winpos', 'E188:')
+  endif
+  call assert_fails('winpos 10', 'E466:')
+endfunc
+
 " vim: shiftwidth=2 sts=2 expandtab
--- a/src/version.c
+++ b/src/version.c
@@ -743,6 +743,8 @@ static char *(features[]) =
 static int included_patches[] =
 {   /* Add new patch number below this line */
 /**/
+    243,
+/**/
     242,
 /**/
     241,