changeset 24620:9f48b262539b v8.2.2849

patch 8.2.2849: bufwrite not sufficiently tested Commit: https://github.com/vim/vim/commit/36f96a515109dc1fad279571a645c0f0d65f2de4 Author: Yegappan Lakshmanan <yegappan@yahoo.com> Date: Thu May 13 18:33:16 2021 +0200 patch 8.2.2849: bufwrite not sufficiently tested Problem: Bufwrite not sufficiently tested. Solution: Add a few more tests. (Yegappan Lakshmanan, closes https://github.com/vim/vim/issues/8192)
author Bram Moolenaar <Bram@vim.org>
date Thu, 13 May 2021 18:45:02 +0200
parents 53939914f672
children 509b22dbcb23
files src/testdir/test_startup.vim src/testdir/test_writefile.vim src/version.c
diffstat 3 files changed, 214 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- a/src/testdir/test_startup.vim
+++ b/src/testdir/test_startup.vim
@@ -1270,4 +1270,19 @@ func Test_progname()
   call delete('Xprogname', 'd')
 endfunc
 
+" Test for doing a write from .vimrc
+func Test_write_in_vimrc()
+  call writefile(['silent! write'], 'Xvimrc')
+  let after =<< trim [CODE]
+    call assert_match('E32: ', v:errmsg)
+    call writefile(v:errors, 'Xtestout')
+    qall
+  [CODE]
+  if RunVim([], after, '-u Xvimrc')
+    call assert_equal([], readfile('Xtestout'))
+    call delete('Xtestout')
+  endif
+  call delete('Xvimrc')
+endfunc
+
 " vim: shiftwidth=2 sts=2 expandtab
--- a/src/testdir/test_writefile.vim
+++ b/src/testdir/test_writefile.vim
@@ -58,7 +58,29 @@ func Test_writefile_fails_conversion()
   call assert_fails('write ++enc=cp932', 'E513:')
   call assert_equal(contents, readfile('Xfile'))
 
+  " With 'backupcopy' set, if there is a conversion error, the backup file is
+  " still created.
+  set backupcopy=yes writebackup& backup&
+  call delete('Xfile' .. &backupext)
+  call assert_fails('write ++enc=cp932', 'E513:')
+  call assert_equal(contents, readfile('Xfile'))
+  call assert_equal(contents, readfile('Xfile' .. &backupext))
+  set backupcopy&
+  %bw!
+
+  " Conversion error during write
+  new
+  call setline(1, ["\U10000000"])
+  let output = execute('write! ++enc=utf-16 Xfile')
+  call assert_match('CONVERSION ERROR', output)
+  let output = execute('write! ++enc=ucs-2 Xfile')
+  call assert_match('CONVERSION ERROR', output)
+  call delete('Xfilz~')
+  call delete('Xfily~')
+  %bw!
+
   call delete('Xfile')
+  call delete('Xfile' .. &backupext)
   bwipe!
   set backup& writebackup& backupdir&vim backupskip&vim
 endfunc
@@ -257,6 +279,16 @@ func Test_write_errors()
   let long_fname = repeat('n', 5000)
   call assert_fails('exe "w " .. long_fname', 'E75:')
   call assert_fails('call writefile([], long_fname)', 'E482:')
+
+  " Test for writing to a block device on Unix-like systems
+  if has('unix') && getfperm('/dev/loop0') != ''
+        \ && getftype('/dev/loop0') == 'bdev' && !IsRoot()
+    new
+    edit /dev/loop0
+    call assert_fails('write', 'E505: ')
+    call assert_fails('write!', 'E503: ')
+    close!
+  endif
 endfunc
 
 " Test for writing to a file which is modified after Vim read it
@@ -383,8 +415,21 @@ func Test_write_readonly()
   call setline(1, ['line1'])
   write!
   call assert_equal(['line1'], readfile('Xfile'))
+
+  " Auto-saving a readonly file should fail with 'autowriteall'
+  %bw!
+  e Xfile
+  set noreadonly autowriteall
+  call setline(1, ['aaaa'])
+  call assert_fails('n', 'E505:')
+  set cpo+=W
+  call assert_fails('n', 'E504:')
+  set cpo-=W
+  set autowriteall&
+
   set backupskip&
   call delete('Xfile')
+  %bw!
 endfunc
 
 " Test for 'patchmode'
@@ -400,6 +445,19 @@ func Test_patchmode()
   " subsequent writes should not create/modify the .orig file
   write
   call assert_equal(['one'], readfile('Xfile.orig'))
+
+  " use 'patchmode' with 'nobackup' and 'nowritebackup' to create an empty
+  " original file
+  call delete('Xfile')
+  call delete('Xfile.orig')
+  %bw!
+  set patchmode=.orig nobackup nowritebackup
+  edit Xfile
+  call setline(1, ['xxx'])
+  write
+  call assert_equal(['xxx'], readfile('Xfile'))
+  call assert_equal([], readfile('Xfile.orig'))
+
   set patchmode& backup& backupskip& writebackup&
   call delete('Xfile')
   call delete('Xfile.orig')
@@ -700,4 +758,143 @@ func Test_read_write_bin()
   bwipe! XNoEolSetEol
 endfunc
 
+" Test for the 'backupcopy' option when writing files
+func Test_backupcopy()
+  CheckUnix
+  set backupskip=
+  " With the default 'backupcopy' setting, saving a symbolic link file
+  " should not break the link.
+  set backupcopy&
+  call writefile(['1111'], 'Xfile1')
+  silent !ln -s Xfile1 Xfile2
+  new Xfile2
+  call setline(1, ['2222'])
+  write
+  close
+  call assert_equal(['2222'], readfile('Xfile1'))
+  call assert_equal('Xfile1', resolve('Xfile2'))
+  call assert_equal('link', getftype('Xfile2'))
+  call delete('Xfile1')
+  call delete('Xfile2')
+
+  " With the 'backupcopy' set to 'breaksymlink', saving a symbolic link file
+  " should break the link.
+  set backupcopy=yes,breaksymlink
+  call writefile(['1111'], 'Xfile1')
+  silent !ln -s Xfile1 Xfile2
+  new Xfile2
+  call setline(1, ['2222'])
+  write
+  close
+  call assert_equal(['1111'], readfile('Xfile1'))
+  call assert_equal(['2222'], readfile('Xfile2'))
+  call assert_equal('Xfile2', resolve('Xfile2'))
+  call assert_equal('file', getftype('Xfile2'))
+  call delete('Xfile1')
+  call delete('Xfile2')
+  set backupcopy&
+
+  " With the default 'backupcopy' setting, saving a hard link file
+  " should not break the link.
+  set backupcopy&
+  call writefile(['1111'], 'Xfile1')
+  silent !ln Xfile1 Xfile2
+  new Xfile2
+  call setline(1, ['2222'])
+  write
+  close
+  call assert_equal(['2222'], readfile('Xfile1'))
+  call delete('Xfile1')
+  call delete('Xfile2')
+
+  " With the 'backupcopy' set to 'breaksymlink', saving a hard link file
+  " should break the link.
+  set backupcopy=yes,breakhardlink
+  call writefile(['1111'], 'Xfile1')
+  silent !ln Xfile1 Xfile2
+  new Xfile2
+  call setline(1, ['2222'])
+  write
+  call assert_equal(['1111'], readfile('Xfile1'))
+  call assert_equal(['2222'], readfile('Xfile2'))
+  call delete('Xfile1')
+  call delete('Xfile2')
+
+  " If a backup file is already present, then a slightly modified filename
+  " should be used as the backup file. Try with 'backupcopy' set to 'yes' and
+  " 'no'.
+  %bw
+  call writefile(['aaaa'], 'Xfile')
+  call writefile(['bbbb'], 'Xfile.bak')
+  set backupcopy=yes backupext=.bak
+  new Xfile
+  call setline(1, ['cccc'])
+  write
+  close
+  call assert_equal(['cccc'], readfile('Xfile'))
+  call assert_equal(['bbbb'], readfile('Xfile.bak'))
+  set backupcopy=no backupext=.bak
+  new Xfile
+  call setline(1, ['dddd'])
+  write
+  close
+  call assert_equal(['dddd'], readfile('Xfile'))
+  call assert_equal(['bbbb'], readfile('Xfile.bak'))
+  call delete('Xfile')
+  call delete('Xfile.bak')
+
+  " Write to a device file (in Unix-like systems) which cannot be backed up.
+  if has('unix')
+    set writebackup backupcopy=yes nobackup
+    new
+    call setline(1, ['aaaa'])
+    let output = execute('write! /dev/null')
+    call assert_match('"/dev/null" \[Device]', output)
+    close
+    set writebackup backupcopy=no nobackup
+    new
+    call setline(1, ['aaaa'])
+    let output = execute('write! /dev/null')
+    call assert_match('"/dev/null" \[Device]', output)
+    close
+    set backup writebackup& backupcopy&
+    new
+    call setline(1, ['aaaa'])
+    let output = execute('write! /dev/null')
+    call assert_match('"/dev/null" \[Device]', output)
+    close
+  endif
+
+  set backupcopy& backupskip& backupext& backup&
+endfunc
+
+" Test for writing a file with 'encoding' set to 'utf-16'
+func Test_write_utf16()
+  new
+  call setline(1, ["\U00010001"])
+  write ++enc=utf-16 Xfile
+  bw!
+  call assert_equal(0zD800DC01, readfile('Xfile', 'B')[0:3])
+  call delete('Xfile')
+endfunc
+
+" Test for trying to save a backup file when the backup file is a symbolic
+" link to the original file. The backup file should not be modified.
+func Test_write_backup_symlink()
+  CheckUnix
+  call writefile(['1111'], 'Xfile')
+  silent !ln -s Xfile Xfile.bak
+
+  new Xfile
+  set backup backupcopy=yes backupext=.bak
+  write
+  call assert_equal('link', getftype('Xfile.bak'))
+  call assert_equal('Xfile', resolve('Xfile.bak'))
+  set backup& backupcopy& backupext&
+  close
+
+  call delete('Xfile')
+  call delete('Xfile.bak')
+endfunc
+
 " vim: shiftwidth=2 sts=2 expandtab
--- a/src/version.c
+++ b/src/version.c
@@ -751,6 +751,8 @@ static char *(features[]) =
 static int included_patches[] =
 {   /* Add new patch number below this line */
 /**/
+    2849,
+/**/
     2848,
 /**/
     2847,