changeset 20625:116c7bd5e980 v8.2.0866

patch 8.2.0866: not enough tests for buffer writing Commit: https://github.com/vim/vim/commit/494e9069cb32620f7688a7cb128a3feff827639e Author: Bram Moolenaar <Bram@vim.org> Date: Sun May 31 21:28:02 2020 +0200 patch 8.2.0866: not enough tests for buffer writing Problem: Not enough tests for buffer writing. Solution: Add more tests. Use CheckRunVimInTerminal in more places. (Yegappan Lakshmanan, closes #6167)
author Bram Moolenaar <Bram@vim.org>
date Sun, 31 May 2020 21:30:03 +0200
parents f782c48d548a
children 38f728a93c07
files src/testdir/test_arglist.vim src/testdir/test_match.vim src/testdir/test_messages.vim src/testdir/test_netbeans.py src/testdir/test_netbeans.vim src/testdir/test_search.vim src/testdir/test_signals.vim src/testdir/test_signs.vim src/testdir/test_startup.vim src/testdir/test_startup_utf8.vim src/testdir/test_syntax.vim src/testdir/test_tabpage.vim src/testdir/test_timers.vim src/testdir/test_vimscript.vim src/testdir/test_writefile.vim src/version.c
diffstat 16 files changed, 167 insertions(+), 57 deletions(-) [+]
line wrap: on
line diff
--- a/src/testdir/test_arglist.vim
+++ b/src/testdir/test_arglist.vim
@@ -1,5 +1,6 @@
 " Test argument list commands
 
+source check.vim
 source shared.vim
 source term_util.vim
 
@@ -511,9 +512,7 @@ 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
+  CheckRunVimInTerminal
   let buf = RunVimInTerminal('', {'rows': 6})
   call term_sendkeys(buf, ":set nomore\n")
   call term_sendkeys(buf, ":args a b c\n")
--- a/src/testdir/test_match.vim
+++ b/src/testdir/test_match.vim
@@ -313,9 +313,7 @@ func Test_matchdelete_error()
 endfunc
 
 func Test_matchclear_other_window()
-  if !CanRunVimInTerminal()
-    throw 'Skipped: cannot make screendumps'
-  endif
+  CheckRunVimInTerminal
   let buf = OtherWindowCommon()
   call term_sendkeys(buf, ":call clearmatches(winid)\<CR>")
   call VerifyScreenDump(buf, 'Test_matchclear_1', {})
@@ -325,9 +323,7 @@ func Test_matchclear_other_window()
 endfunc
 
 func Test_matchadd_other_window()
-  if !CanRunVimInTerminal()
-    throw 'Skipped: cannot make screendumps'
-  endif
+  CheckRunVimInTerminal
   let buf = OtherWindowCommon()
   call term_sendkeys(buf, ":call matchadd('Search', 'Hello', 1, -1, #{window: winid})\<CR>")
   call term_sendkeys(buf, ":\<CR>")
--- a/src/testdir/test_messages.vim
+++ b/src/testdir/test_messages.vim
@@ -1,5 +1,6 @@
 " Tests for :messages, :echomsg, :echoerr
 
+source check.vim
 source shared.vim
 source term_util.vim
 source view_util.vim
@@ -172,9 +173,7 @@ endfunc
 
 " Test more-prompt (see :help more-prompt).
 func Test_message_more()
-  if !CanRunVimInTerminal()
-    throw 'Skipped: cannot run vim in terminal'
-  endif
+  CheckRunVimInTerminal
   let buf = RunVimInTerminal('', {'rows': 6})
   call term_sendkeys(buf, ":call setline(1, range(1, 100))\n")
 
@@ -265,9 +264,7 @@ func Test_message_more()
 endfunc
 
 func Test_ask_yesno()
-  if !CanRunVimInTerminal()
-    throw 'Skipped: cannot run vim in terminal'
-  endif
+  CheckRunVimInTerminal
   let buf = RunVimInTerminal('', {'rows': 6})
   call term_sendkeys(buf, ":call setline(1, range(1, 2))\n")
 
--- a/src/testdir/test_netbeans.py
+++ b/src/testdir/test_netbeans.py
@@ -102,7 +102,8 @@ class ThreadedTCPRequestHandler(socketse
                   'setReadOnly_Test' : '3:setReadOnly!87\n',
                   'close_Test' : '3:close!88\n',
                   'specialKeys_Test' : '0:specialKeys!89 "F12 F13"\n',
-                  'detach_Test' : '2:close!90\n1:close!91\nDETACH\n'
+                  'nbbufwrite_Test' : '4:editFile!90 "XnbBuffer"\n4:netbeansBuffer!91 T\n',
+                  'detach_Test' : '2:close!92\n1:close!93\nDETACH\n'
                 }
                 # execute the specified test
                 if cmd not in testmap:
@@ -120,7 +121,7 @@ class ThreadedTCPRequestHandler(socketse
 
             if len(response) > 0:
                 self.request.sendall(response.encode('utf-8'))
-                # Write the respoinse into the file, so that the test can knows
+                # Write the response into the file, so that the test can knows
                 # the command was sent.
                 with open("Xnetbeans", "a") as myfile:
                     myfile.write('send: ' + response)
--- a/src/testdir/test_netbeans.vim
+++ b/src/testdir/test_netbeans.vim
@@ -607,10 +607,20 @@ func Nb_basic(port)
   call assert_equal('0:fileOpened=0 "" T F', l[-1])
   let g:last += 1
 
+  " Test for writing a netbeans buffer
+  call appendbufline(cmdbufnr, '$', 'nbbufwrite_Test')
+  call WaitFor('len(readfile("Xnetbeans")) >= (g:last + 5)')
+  call assert_fails('write', 'E656:')
+  call setline(1, ['one', 'two'])
+  call assert_fails('1write!', 'E657:')
+  write
+  call WaitFor('len(readfile("Xnetbeans")) >= (g:last + 10)')
+  let g:last += 10
+
   " detach
   call appendbufline(cmdbufnr, '$', 'detach_Test')
   call WaitFor('len(readfile("Xnetbeans")) >= (g:last + 8)')
-  call WaitForAssert({-> assert_equal('0:disconnect=91', readfile("Xnetbeans")[-1])})
+  call WaitForAssert({-> assert_equal('0:disconnect=93', readfile("Xnetbeans")[-1])})
 
   " the connection was closed
   call assert_false(has("netbeans_enabled"))
--- a/src/testdir/test_search.vim
+++ b/src/testdir/test_search.vim
@@ -886,9 +886,7 @@ func Test_incsearch_cmdline_modifier()
 endfunc
 
 func Test_incsearch_scrolling()
-  if !CanRunVimInTerminal()
-    throw 'Skipped: cannot make screendumps'
-  endif
+  CheckRunVimInTerminal
   call assert_equal(0, &scrolloff)
   call writefile([
 	\ 'let dots = repeat(".", 120)',
--- a/src/testdir/test_signals.vim
+++ b/src/testdir/test_signals.vim
@@ -80,6 +80,7 @@ endfunc
 
 " Test signal INT. Handler sets got_int. It should be like typing CTRL-C.
 func Test_signal_INT()
+  CheckRunVimInTerminal
   if !HasSignal('INT')
     throw 'Skipped: INT signal not supported'
   endif
@@ -91,9 +92,6 @@ func Test_signal_INT()
     throw 'Skipped: cannot test signal INT with valgrind'
   endif
 
-  if !CanRunVimInTerminal()
-    throw 'Skipped: cannot run vim in terminal'
-  endif
   let buf = RunVimInTerminal('', {'rows': 6})
   let pid_vim = term_getjob(buf)->job_info().process
 
@@ -120,9 +118,7 @@ func Test_deadly_signal_TERM()
   if !HasSignal('TERM')
     throw 'Skipped: TERM signal not supported'
   endif
-  if !CanRunVimInTerminal()
-    throw 'Skipped: cannot run vim in terminal'
-  endif
+  CheckRunVimInTerminal
   let cmd = GetVimCommand()
   if cmd =~ 'valgrind'
     throw 'Skipped: cannot test signal TERM with valgrind'
--- a/src/testdir/test_signs.vim
+++ b/src/testdir/test_signs.vim
@@ -1734,9 +1734,7 @@ endfunc
 
 " Test for correct cursor position after the sign column appears or disappears.
 func Test_sign_cursor_position()
-  if !CanRunVimInTerminal()
-    throw 'Skipped: cannot make screendumps'
-  endif
+  CheckRunVimInTerminal
 
   let lines =<< trim END
 	call setline(1, [repeat('x', 75), 'mmmm', 'yyyy'])
--- a/src/testdir/test_startup.vim
+++ b/src/testdir/test_startup.vim
@@ -673,9 +673,7 @@ func Test_issue_3969()
 endfunc
 
 func Test_start_with_tabs()
-  if !CanRunVimInTerminal()
-    throw 'Skipped: cannot make screendumps'
-  endif
+  CheckRunVimInTerminal
 
   let buf = RunVimInTerminal('-p a b c', {})
   call VerifyScreenDump(buf, 'Test_start_with_tabs', {})
@@ -783,9 +781,7 @@ endfunc
 
 " Test for specifying a non-existing vimrc file using "-u"
 func Test_missing_vimrc()
-  if !CanRunVimInTerminal()
-    throw 'Skipped: cannot run vim in terminal'
-  endif
+  CheckRunVimInTerminal
   let after =<< trim [CODE]
     call assert_match('^E282:', v:errmsg)
     call writefile(v:errors, 'Xtestout')
--- a/src/testdir/test_startup_utf8.vim
+++ b/src/testdir/test_startup_utf8.vim
@@ -62,9 +62,7 @@ func Test_read_fifo_utf8()
 endfunc
 
 func Test_detect_ambiwidth()
-  if !CanRunVimInTerminal()
-    throw 'Skipped: cannot run Vim in a terminal window'
-  endif
+  CheckRunVimInTerminal
 
   " Use the title termcap entries to output the escape sequence.
   call writefile([
--- a/src/testdir/test_syntax.vim
+++ b/src/testdir/test_syntax.vim
@@ -597,9 +597,7 @@ endfunc
 
 " Check highlighting for a small piece of C code with a screen dump.
 func Test_syntax_c()
-  if !CanRunVimInTerminal()
-    throw 'Skipped: cannot make screendumps'
-  endif
+  CheckRunVimInTerminal
   call writefile([
 	\ '/* comment line at the top */',
 	\ 'int main(int argc, char **argv) { // another comment',
--- a/src/testdir/test_tabpage.vim
+++ b/src/testdir/test_tabpage.vim
@@ -593,9 +593,7 @@ func Test_tabs()
 endfunc
 
 func Test_tabpage_cmdheight()
-  if !CanRunVimInTerminal()
-    throw 'Skipped: cannot make screendumps'
-  endif
+  CheckRunVimInTerminal
   call writefile([
         \ 'set laststatus=2',
         \ 'set cmdheight=2',
--- a/src/testdir/test_timers.vim
+++ b/src/testdir/test_timers.vim
@@ -324,9 +324,7 @@ func Test_timer_ex_mode()
 endfunc
 
 func Test_timer_restore_count()
-  if !CanRunVimInTerminal()
-    throw 'Skipped: cannot run Vim in a terminal window'
-  endif
+  CheckRunVimInTerminal
   " Check that v:count is saved and restored, not changed by a timer.
   call writefile([
         \ 'nnoremap <expr><silent> L v:count ? v:count . "l" : "l"',
--- a/src/testdir/test_vimscript.vim
+++ b/src/testdir/test_vimscript.vim
@@ -1904,9 +1904,7 @@ 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
+  CheckRunVimInTerminal
 
   let lines =<< trim [SCRIPT]
     " Deep nesting of if ... endif
--- a/src/testdir/test_writefile.vim
+++ b/src/testdir/test_writefile.vim
@@ -1,6 +1,7 @@
 " Tests for the writefile() function and some :write commands.
 
 source check.vim
+source term_util.vim
 
 func Test_writefile()
   let f = tempname()
@@ -207,12 +208,6 @@ func Test_saveas()
   close!
   enew | only
   call delete('Xfile')
-
-  call writefile(test_null_list(), 'Xfile')
-  call assert_false(filereadable('Xfile'))
-  call writefile(test_null_blob(), 'Xfile')
-  call assert_false(filereadable('Xfile'))
-  call assert_fails('call writefile([], "")', 'E482:')
 endfunc
 
 func Test_write_errors()
@@ -257,6 +252,138 @@ func Test_write_errors()
   call writefile(test_null_blob(), 'Xfile')
   call assert_false(filereadable('Xfile'))
   call assert_fails('call writefile([], "")', 'E482:')
+
+  " very long file name
+  let long_fname = repeat('n', 5000)
+  call assert_fails('exe "w " .. long_fname', 'E75:')
+  call assert_fails('call writefile([], long_fname)', 'E482:')
+endfunc
+
+" Test for writing to a file which is modified after Vim read it
+func Test_write_file_mtime()
+  CheckEnglish
+  CheckRunVimInTerminal
+
+  " First read the file into a buffer
+  call writefile(["Line1", "Line2"], 'Xfile')
+  let old_ftime = getftime('Xfile')
+  let buf = RunVimInTerminal('Xfile', #{rows : 10})
+  call term_wait(buf)
+  call term_sendkeys(buf, ":set noswapfile\<CR>")
+  call term_wait(buf)
+
+  " Modify the file directly.  Make sure the file modification time is
+  " different. Note that on Linux/Unix, the file is considered modified
+  " outside, only if the difference is 2 seconds or more
+  sleep 1
+  call writefile(["Line3", "Line4"], 'Xfile')
+  let new_ftime = getftime('Xfile')
+  while new_ftime - old_ftime < 2
+    sleep 100m
+    call writefile(["Line3", "Line4"], 'Xfile')
+    let new_ftime = getftime('Xfile')
+  endwhile
+
+  " Try to overwrite the file and check for the prompt
+  call term_sendkeys(buf, ":w\<CR>")
+  call term_wait(buf)
+  call WaitForAssert({-> assert_equal("WARNING: The file has been changed since reading it!!!", term_getline(buf, 9))})
+  call assert_equal("Do you really want to write to it (y/n)?",
+        \ term_getline(buf, 10))
+  call term_sendkeys(buf, "n\<CR>")
+  call term_wait(buf)
+  call assert_equal(new_ftime, getftime('Xfile'))
+  call term_sendkeys(buf, ":w\<CR>")
+  call term_wait(buf)
+  call term_sendkeys(buf, "y\<CR>")
+  call term_wait(buf)
+  call WaitForAssert({-> assert_equal('Line2', readfile('Xfile')[1])})
+
+  " clean up
+  call StopVimInTerminal(buf)
+  call delete('Xfile')
+endfunc
+
+" Test for an autocmd unloading a buffer during a write command
+func Test_write_autocmd_unloadbuf_lockmark()
+  augroup WriteTest
+    autocmd BufWritePre Xfile enew | write
+  augroup END
+  e Xfile
+  call assert_fails('lockmarks write', 'E203:')
+  augroup WriteTest
+    au!
+  augroup END
+  augroup! WriteTest
+endfunc
+
+" Test for writing a buffer with 'acwrite' but without autocmds
+func Test_write_acwrite_error()
+  new Xfile
+  call setline(1, ['line1', 'line2', 'line3'])
+  set buftype=acwrite
+  call assert_fails('write', 'E676:')
+  call assert_fails('1,2write!', 'E676:')
+  call assert_fails('w >>', 'E676:')
+  close!
+endfunc
+
+" Test for adding and removing lines from an autocmd when writing a buffer
+func Test_write_autocmd_add_remove_lines()
+  new Xfile
+  call setline(1, ['aaa', 'bbb', 'ccc', 'ddd'])
+
+  " Autocmd deleting lines from the file when writing a partial file
+  augroup WriteTest2
+    au!
+    autocmd FileWritePre Xfile 1,2d
+  augroup END
+  call assert_fails('2,3w!', 'E204:')
+
+  " Autocmd adding lines to a file when writing a partial file
+  augroup WriteTest2
+    au!
+    autocmd FileWritePre Xfile call append(0, ['xxx', 'yyy'])
+  augroup END
+  %d
+  call setline(1, ['aaa', 'bbb', 'ccc', 'ddd'])
+  1,2w!
+  call assert_equal(['xxx', 'yyy', 'aaa', 'bbb'], readfile('Xfile'))
+
+  " Autocmd deleting lines from the file when writing the whole file
+  augroup WriteTest2
+    au!
+    autocmd BufWritePre Xfile 1,2d
+  augroup END
+  %d
+  call setline(1, ['aaa', 'bbb', 'ccc', 'ddd'])
+  w
+  call assert_equal(['ccc', 'ddd'], readfile('Xfile'))
+
+  augroup WriteTest2
+    au!
+  augroup END
+  augroup! WriteTest2
+
+  close!
+  call delete('Xfile')
+endfunc
+
+" Test for writing to a readonly file
+func Test_write_readonly()
+  " In Cirrus-CI, the freebsd tests are run under a root account. So this test
+  " doesn't fail.
+  CheckNotBSD
+  call writefile([], 'Xfile')
+  call setfperm('Xfile', "r--------")
+  edit Xfile
+  set noreadonly
+  call assert_fails('write', 'E505:')
+  let save_cpo = &cpo
+  set cpo+=W
+  call assert_fails('write!', 'E504:')
+  let &cpo = save_cpo
+  call delete('Xfile')
 endfunc
 
 " vim: shiftwidth=2 sts=2 expandtab
--- a/src/version.c
+++ b/src/version.c
@@ -747,6 +747,8 @@ static char *(features[]) =
 static int included_patches[] =
 {   /* Add new patch number below this line */
 /**/
+    866,
+/**/
     865,
 /**/
     864,