1b40c2576SBram Moolenaar" Tests for the writefile() function and some :write commands.
219a1669fSBram Moolenaar
3ea3db914SBram Moolenaarsource check.vim
4494e9069SBram Moolenaarsource term_util.vim
5ea3db914SBram Moolenaar
68cf91286SBram Moolenaarfunc Test_writefile()
719a1669fSBram Moolenaar  let f = tempname()
819a1669fSBram Moolenaar  call writefile(["over","written"], f, "b")
919a1669fSBram Moolenaar  call writefile(["hello","world"], f, "b")
1019a1669fSBram Moolenaar  call writefile(["!", "good"], f, "a")
1119a1669fSBram Moolenaar  call writefile(["morning"], f, "ab")
1219a1669fSBram Moolenaar  call writefile(["", "vimmers"], f, "ab")
1319a1669fSBram Moolenaar  let l = readfile(f)
1419a1669fSBram Moolenaar  call assert_equal("hello", l[0])
1519a1669fSBram Moolenaar  call assert_equal("world!", l[1])
1619a1669fSBram Moolenaar  call assert_equal("good", l[2])
1719a1669fSBram Moolenaar  call assert_equal("morning", l[3])
1819a1669fSBram Moolenaar  call assert_equal("vimmers", l[4])
1919a1669fSBram Moolenaar  call delete(f)
2018a2b87cSBram Moolenaar
2118a2b87cSBram Moolenaar  call assert_fails('call writefile("text", "Xfile")', 'E475: Invalid argument: writefile() first argument must be a List or a Blob')
228cf91286SBram Moolenaarendfunc
238cf91286SBram Moolenaar
24b40c2576SBram Moolenaarfunc Test_writefile_ignore_regexp_error()
25b40c2576SBram Moolenaar  write Xt[z-a]est.txt
26b40c2576SBram Moolenaar  call delete('Xt[z-a]est.txt')
27b40c2576SBram Moolenaarendfunc
28b40c2576SBram Moolenaar
298cf91286SBram Moolenaarfunc Test_writefile_fails_gently()
308cf91286SBram Moolenaar  call assert_fails('call writefile(["test"], "Xfile", [])', 'E730:')
318cf91286SBram Moolenaar  call assert_false(filereadable("Xfile"))
328cf91286SBram Moolenaar  call delete("Xfile")
338cf91286SBram Moolenaar
348cf91286SBram Moolenaar  call assert_fails('call writefile(["test", [], [], [], "tset"], "Xfile")', 'E730:')
358cf91286SBram Moolenaar  call assert_false(filereadable("Xfile"))
368cf91286SBram Moolenaar  call delete("Xfile")
378cf91286SBram Moolenaar
388cf91286SBram Moolenaar  call assert_fails('call writefile([], "Xfile", [])', 'E730:')
398cf91286SBram Moolenaar  call assert_false(filereadable("Xfile"))
408cf91286SBram Moolenaar  call delete("Xfile")
418cf91286SBram Moolenaar
428cf91286SBram Moolenaar  call assert_fails('call writefile([], [])', 'E730:')
438cf91286SBram Moolenaarendfunc
44e6bf655bSBram Moolenaar
45e6bf655bSBram Moolenaarfunc Test_writefile_fails_conversion()
466d91bcb4SBram Moolenaar  CheckFeature iconv
476d91bcb4SBram Moolenaar  if has('sun')
486d91bcb4SBram Moolenaar    throw 'Skipped: does not work on SunOS'
49e6bf655bSBram Moolenaar  endif
50cf0bfd9aSBram Moolenaar  " Without a backup file the write won't happen if there is a conversion
51cf0bfd9aSBram Moolenaar  " error.
52c28cb5b1SBram Moolenaar  set nobackup nowritebackup backupdir=. backupskip=
53e6bf655bSBram Moolenaar  new
54e6bf655bSBram Moolenaar  let contents = ["line one", "line two"]
55e6bf655bSBram Moolenaar  call writefile(contents, 'Xfile')
56e6bf655bSBram Moolenaar  edit Xfile
57e6bf655bSBram Moolenaar  call setline(1, ["first line", "cannot convert \u010b", "third line"])
58cf0bfd9aSBram Moolenaar  call assert_fails('write ++enc=cp932', 'E513:')
59e6bf655bSBram Moolenaar  call assert_equal(contents, readfile('Xfile'))
60e6bf655bSBram Moolenaar
6136f96a51SYegappan Lakshmanan  " With 'backupcopy' set, if there is a conversion error, the backup file is
6236f96a51SYegappan Lakshmanan  " still created.
6336f96a51SYegappan Lakshmanan  set backupcopy=yes writebackup& backup&
6436f96a51SYegappan Lakshmanan  call delete('Xfile' .. &backupext)
6536f96a51SYegappan Lakshmanan  call assert_fails('write ++enc=cp932', 'E513:')
6636f96a51SYegappan Lakshmanan  call assert_equal(contents, readfile('Xfile'))
6736f96a51SYegappan Lakshmanan  call assert_equal(contents, readfile('Xfile' .. &backupext))
6836f96a51SYegappan Lakshmanan  set backupcopy&
6936f96a51SYegappan Lakshmanan  %bw!
7036f96a51SYegappan Lakshmanan
7136f96a51SYegappan Lakshmanan  " Conversion error during write
7236f96a51SYegappan Lakshmanan  new
7336f96a51SYegappan Lakshmanan  call setline(1, ["\U10000000"])
7436f96a51SYegappan Lakshmanan  let output = execute('write! ++enc=utf-16 Xfile')
7536f96a51SYegappan Lakshmanan  call assert_match('CONVERSION ERROR', output)
7636f96a51SYegappan Lakshmanan  let output = execute('write! ++enc=ucs-2 Xfile')
7736f96a51SYegappan Lakshmanan  call assert_match('CONVERSION ERROR', output)
7836f96a51SYegappan Lakshmanan  call delete('Xfilz~')
7936f96a51SYegappan Lakshmanan  call delete('Xfily~')
8036f96a51SYegappan Lakshmanan  %bw!
8136f96a51SYegappan Lakshmanan
82e6bf655bSBram Moolenaar  call delete('Xfile')
8336f96a51SYegappan Lakshmanan  call delete('Xfile' .. &backupext)
84e6bf655bSBram Moolenaar  bwipe!
85c28cb5b1SBram Moolenaar  set backup& writebackup& backupdir&vim backupskip&vim
86e6bf655bSBram Moolenaarendfunc
872c33d7bbSBram Moolenaar
88cf0bfd9aSBram Moolenaarfunc Test_writefile_fails_conversion2()
896d91bcb4SBram Moolenaar  CheckFeature iconv
906d91bcb4SBram Moolenaar  if has('sun')
916d91bcb4SBram Moolenaar    throw 'Skipped: does not work on SunOS'
92cf0bfd9aSBram Moolenaar  endif
93cf0bfd9aSBram Moolenaar  " With a backup file the write happens even if there is a conversion error,
94cf0bfd9aSBram Moolenaar  " but then the backup file must remain
95c28cb5b1SBram Moolenaar  set nobackup writebackup backupdir=. backupskip=
96cf0bfd9aSBram Moolenaar  let contents = ["line one", "line two"]
97cf0bfd9aSBram Moolenaar  call writefile(contents, 'Xfile_conversion_err')
98cf0bfd9aSBram Moolenaar  edit Xfile_conversion_err
99cf0bfd9aSBram Moolenaar  call setline(1, ["first line", "cannot convert \u010b", "third line"])
100cf0bfd9aSBram Moolenaar  set fileencoding=latin1
101cf0bfd9aSBram Moolenaar  let output = execute('write')
102cf0bfd9aSBram Moolenaar  call assert_match('CONVERSION ERROR', output)
103cf0bfd9aSBram Moolenaar  call assert_equal(contents, readfile('Xfile_conversion_err~'))
104cf0bfd9aSBram Moolenaar
105cf0bfd9aSBram Moolenaar  call delete('Xfile_conversion_err')
106cf0bfd9aSBram Moolenaar  call delete('Xfile_conversion_err~')
107cf0bfd9aSBram Moolenaar  bwipe!
108c28cb5b1SBram Moolenaar  set backup& writebackup& backupdir&vim backupskip&vim
109cf0bfd9aSBram Moolenaarendfunc
110cf0bfd9aSBram Moolenaar
1112c33d7bbSBram Moolenaarfunc SetFlag(timer)
1122c33d7bbSBram Moolenaar  let g:flag = 1
1132c33d7bbSBram Moolenaarendfunc
1142c33d7bbSBram Moolenaar
1152c33d7bbSBram Moolenaarfunc Test_write_quit_split()
1162c33d7bbSBram Moolenaar  " Prevent exiting by splitting window on file write.
1172c33d7bbSBram Moolenaar  augroup testgroup
1182c33d7bbSBram Moolenaar    autocmd BufWritePre * split
1192c33d7bbSBram Moolenaar  augroup END
1202c33d7bbSBram Moolenaar  e! Xfile
1212c33d7bbSBram Moolenaar  call setline(1, 'nothing')
1222c33d7bbSBram Moolenaar  wq
1232c33d7bbSBram Moolenaar
1242c33d7bbSBram Moolenaar  if has('timers')
1252c33d7bbSBram Moolenaar    " timer will not run if "exiting" is still set
1262c33d7bbSBram Moolenaar    let g:flag = 0
1272c33d7bbSBram Moolenaar    call timer_start(1, 'SetFlag')
1282c33d7bbSBram Moolenaar    sleep 50m
1292c33d7bbSBram Moolenaar    call assert_equal(1, g:flag)
1302c33d7bbSBram Moolenaar    unlet g:flag
1312c33d7bbSBram Moolenaar  endif
1322c33d7bbSBram Moolenaar  au! testgroup
1332c33d7bbSBram Moolenaar  bwipe Xfile
1342c33d7bbSBram Moolenaar  call delete('Xfile')
1352c33d7bbSBram Moolenaarendfunc
1362c33d7bbSBram Moolenaar
1372c33d7bbSBram Moolenaarfunc Test_nowrite_quit_split()
1382c33d7bbSBram Moolenaar  " Prevent exiting by opening a help window.
1392c33d7bbSBram Moolenaar  e! Xfile
1402c33d7bbSBram Moolenaar  help
1412c33d7bbSBram Moolenaar  wincmd w
1422c33d7bbSBram Moolenaar  exe winnr() . 'q'
1432c33d7bbSBram Moolenaar
1442c33d7bbSBram Moolenaar  if has('timers')
1452c33d7bbSBram Moolenaar    " timer will not run if "exiting" is still set
1462c33d7bbSBram Moolenaar    let g:flag = 0
1472c33d7bbSBram Moolenaar    call timer_start(1, 'SetFlag')
1482c33d7bbSBram Moolenaar    sleep 50m
1492c33d7bbSBram Moolenaar    call assert_equal(1, g:flag)
1502c33d7bbSBram Moolenaar    unlet g:flag
1512c33d7bbSBram Moolenaar  endif
1522c33d7bbSBram Moolenaar  bwipe Xfile
1532c33d7bbSBram Moolenaarendfunc
1547567d0b1SBram Moolenaar
1557567d0b1SBram Moolenaarfunc Test_writefile_sync_arg()
1567567d0b1SBram Moolenaar  " This doesn't check if fsync() works, only that the argument is accepted.
1577567d0b1SBram Moolenaar  call writefile(['one'], 'Xtest', 's')
1587567d0b1SBram Moolenaar  call writefile(['two'], 'Xtest', 'S')
1597567d0b1SBram Moolenaar  call delete('Xtest')
1607567d0b1SBram Moolenaarendfunc
16183799a7bSBram Moolenaar
16283799a7bSBram Moolenaarfunc Test_writefile_sync_dev_stdout()
163b86abadfSBram Moolenaar  CheckUnix
1649980b37aSBram Moolenaar  if filewritable('/dev/stdout')
16583799a7bSBram Moolenaar    " Just check that this doesn't cause an error.
16683799a7bSBram Moolenaar    call writefile(['one'], '/dev/stdout')
1679980b37aSBram Moolenaar  else
1689980b37aSBram Moolenaar    throw 'Skipped: /dev/stdout is not writable'
1699980b37aSBram Moolenaar  endif
17083799a7bSBram Moolenaarendfunc
1718c9e7b00SBram Moolenaar
1728c9e7b00SBram Moolenaarfunc Test_writefile_autowrite()
1738c9e7b00SBram Moolenaar  set autowrite
1748c9e7b00SBram Moolenaar  new
1758c9e7b00SBram Moolenaar  next Xa Xb Xc
1768c9e7b00SBram Moolenaar  call setline(1, 'aaa')
1778c9e7b00SBram Moolenaar  next
1788c9e7b00SBram Moolenaar  call assert_equal(['aaa'], readfile('Xa'))
1798c9e7b00SBram Moolenaar  call setline(1, 'bbb')
1808c9e7b00SBram Moolenaar  call assert_fails('edit XX')
1818c9e7b00SBram Moolenaar  call assert_false(filereadable('Xb'))
1828c9e7b00SBram Moolenaar
1838c9e7b00SBram Moolenaar  set autowriteall
1848c9e7b00SBram Moolenaar  edit XX
1858c9e7b00SBram Moolenaar  call assert_equal(['bbb'], readfile('Xb'))
1868c9e7b00SBram Moolenaar
1878c9e7b00SBram Moolenaar  bwipe!
1888c9e7b00SBram Moolenaar  call delete('Xa')
1898c9e7b00SBram Moolenaar  call delete('Xb')
1908c9e7b00SBram Moolenaar  set noautowrite
1918c9e7b00SBram Moolenaarendfunc
1928c9e7b00SBram Moolenaar
1938c9e7b00SBram Moolenaarfunc Test_writefile_autowrite_nowrite()
1948c9e7b00SBram Moolenaar  set autowrite
1958c9e7b00SBram Moolenaar  new
1968c9e7b00SBram Moolenaar  next Xa Xb Xc
1978c9e7b00SBram Moolenaar  set buftype=nowrite
1988c9e7b00SBram Moolenaar  call setline(1, 'aaa')
1998c9e7b00SBram Moolenaar  let buf = bufnr('%')
2008c9e7b00SBram Moolenaar  " buffer contents silently lost
2018c9e7b00SBram Moolenaar  edit XX
2028c9e7b00SBram Moolenaar  call assert_false(filereadable('Xa'))
2038c9e7b00SBram Moolenaar  rewind
2048c9e7b00SBram Moolenaar  call assert_equal('', getline(1))
2058c9e7b00SBram Moolenaar
2068c9e7b00SBram Moolenaar  bwipe!
2078c9e7b00SBram Moolenaar  set noautowrite
2088c9e7b00SBram Moolenaarendfunc
2095d98dc2aSBram Moolenaar
2105d98dc2aSBram Moolenaar" Test for ':w !<cmd>' to pipe lines from the current buffer to an external
2115d98dc2aSBram Moolenaar" command.
2125d98dc2aSBram Moolenaarfunc Test_write_pipe_to_cmd()
213ea3db914SBram Moolenaar  CheckUnix
2145d98dc2aSBram Moolenaar  new
2155d98dc2aSBram Moolenaar  call setline(1, ['L1', 'L2', 'L3', 'L4'])
2165d98dc2aSBram Moolenaar  2,3w !cat > Xfile
2175d98dc2aSBram Moolenaar  call assert_equal(['L2', 'L3'], readfile('Xfile'))
2185d98dc2aSBram Moolenaar  close!
2195d98dc2aSBram Moolenaar  call delete('Xfile')
2205d98dc2aSBram Moolenaarendfunc
2215d98dc2aSBram Moolenaar
2225d98dc2aSBram Moolenaar" Test for :saveas
2235d98dc2aSBram Moolenaarfunc Test_saveas()
2245d98dc2aSBram Moolenaar  call assert_fails('saveas', 'E471:')
2255d98dc2aSBram Moolenaar  call writefile(['L1'], 'Xfile')
2265d98dc2aSBram Moolenaar  new Xfile
2275d98dc2aSBram Moolenaar  new
2285d98dc2aSBram Moolenaar  call setline(1, ['L1'])
2295d98dc2aSBram Moolenaar  call assert_fails('saveas Xfile', 'E139:')
2305d98dc2aSBram Moolenaar  close!
2315d98dc2aSBram Moolenaar  enew | only
2325d98dc2aSBram Moolenaar  call delete('Xfile')
233*bd9e7961SDominique Pelle
234*bd9e7961SDominique Pelle  " :saveas should detect and set the file type.
235*bd9e7961SDominique Pelle  syntax on
236*bd9e7961SDominique Pelle  saveas! Xsaveas.pl
237*bd9e7961SDominique Pelle  call assert_equal('perl', &filetype)
238*bd9e7961SDominique Pelle  syntax off
239*bd9e7961SDominique Pelle  %bw!
240*bd9e7961SDominique Pelle  call delete('Xsaveas.pl')
2415d98dc2aSBram Moolenaarendfunc
2425d98dc2aSBram Moolenaar
2435d98dc2aSBram Moolenaarfunc Test_write_errors()
2445d98dc2aSBram Moolenaar  " Test for writing partial buffer
2455d98dc2aSBram Moolenaar  call writefile(['L1', 'L2', 'L3'], 'Xfile')
2465d98dc2aSBram Moolenaar  new Xfile
2475d98dc2aSBram Moolenaar  call assert_fails('1,2write', 'E140:')
2485d98dc2aSBram Moolenaar  close!
2495d98dc2aSBram Moolenaar
2504f5776c1SBram Moolenaar  call assert_fails('w > Xtest', 'E494:')
2514f5776c1SBram Moolenaar
2525d98dc2aSBram Moolenaar  " Try to overwrite a directory
2535d98dc2aSBram Moolenaar  if has('unix')
2545d98dc2aSBram Moolenaar    call mkdir('Xdir1')
2555d98dc2aSBram Moolenaar    call assert_fails('write Xdir1', 'E17:')
2565d98dc2aSBram Moolenaar    call delete('Xdir1', 'd')
2575d98dc2aSBram Moolenaar  endif
2585d98dc2aSBram Moolenaar
2595d98dc2aSBram Moolenaar  " Test for :wall for a buffer with no name
2605d98dc2aSBram Moolenaar  enew | only
2615d98dc2aSBram Moolenaar  call setline(1, ['L1'])
2625d98dc2aSBram Moolenaar  call assert_fails('wall', 'E141:')
2635d98dc2aSBram Moolenaar  enew!
2645d98dc2aSBram Moolenaar
2655d98dc2aSBram Moolenaar  " Test for writing a 'readonly' file
2665d98dc2aSBram Moolenaar  new Xfile
2675d98dc2aSBram Moolenaar  set readonly
2685d98dc2aSBram Moolenaar  call assert_fails('write', 'E45:')
2695d98dc2aSBram Moolenaar  close
2705d98dc2aSBram Moolenaar
2715d98dc2aSBram Moolenaar  " Test for writing to a read-only file
2725d98dc2aSBram Moolenaar  new Xfile
2735d98dc2aSBram Moolenaar  call setfperm('Xfile', 'r--r--r--')
2745d98dc2aSBram Moolenaar  call assert_fails('write', 'E505:')
2755d98dc2aSBram Moolenaar  call setfperm('Xfile', 'rw-rw-rw-')
2765d98dc2aSBram Moolenaar  close
2775d98dc2aSBram Moolenaar
2785d98dc2aSBram Moolenaar  call delete('Xfile')
27999fa7219SBram Moolenaar
28099fa7219SBram Moolenaar  call writefile(test_null_list(), 'Xfile')
28199fa7219SBram Moolenaar  call assert_false(filereadable('Xfile'))
28299fa7219SBram Moolenaar  call writefile(test_null_blob(), 'Xfile')
28399fa7219SBram Moolenaar  call assert_false(filereadable('Xfile'))
28499fa7219SBram Moolenaar  call assert_fails('call writefile([], "")', 'E482:')
285494e9069SBram Moolenaar
286494e9069SBram Moolenaar  " very long file name
287494e9069SBram Moolenaar  let long_fname = repeat('n', 5000)
288494e9069SBram Moolenaar  call assert_fails('exe "w " .. long_fname', 'E75:')
289494e9069SBram Moolenaar  call assert_fails('call writefile([], long_fname)', 'E482:')
29036f96a51SYegappan Lakshmanan
29136f96a51SYegappan Lakshmanan  " Test for writing to a block device on Unix-like systems
29236f96a51SYegappan Lakshmanan  if has('unix') && getfperm('/dev/loop0') != ''
29336f96a51SYegappan Lakshmanan        \ && getftype('/dev/loop0') == 'bdev' && !IsRoot()
29436f96a51SYegappan Lakshmanan    new
29536f96a51SYegappan Lakshmanan    edit /dev/loop0
29650157ef1SBram Moolenaar    call assert_fails('write', 'E503: ')
29736f96a51SYegappan Lakshmanan    call assert_fails('write!', 'E503: ')
29836f96a51SYegappan Lakshmanan    close!
29936f96a51SYegappan Lakshmanan  endif
300494e9069SBram Moolenaarendfunc
301494e9069SBram Moolenaar
302494e9069SBram Moolenaar" Test for writing to a file which is modified after Vim read it
303494e9069SBram Moolenaarfunc Test_write_file_mtime()
304494e9069SBram Moolenaar  CheckEnglish
305494e9069SBram Moolenaar  CheckRunVimInTerminal
306494e9069SBram Moolenaar
307494e9069SBram Moolenaar  " First read the file into a buffer
308494e9069SBram Moolenaar  call writefile(["Line1", "Line2"], 'Xfile')
309494e9069SBram Moolenaar  let old_ftime = getftime('Xfile')
310494e9069SBram Moolenaar  let buf = RunVimInTerminal('Xfile', #{rows : 10})
311733d259aSBram Moolenaar  call TermWait(buf)
312494e9069SBram Moolenaar  call term_sendkeys(buf, ":set noswapfile\<CR>")
313733d259aSBram Moolenaar  call TermWait(buf)
314494e9069SBram Moolenaar
315494e9069SBram Moolenaar  " Modify the file directly.  Make sure the file modification time is
316494e9069SBram Moolenaar  " different. Note that on Linux/Unix, the file is considered modified
317494e9069SBram Moolenaar  " outside, only if the difference is 2 seconds or more
318494e9069SBram Moolenaar  sleep 1
319494e9069SBram Moolenaar  call writefile(["Line3", "Line4"], 'Xfile')
320494e9069SBram Moolenaar  let new_ftime = getftime('Xfile')
321494e9069SBram Moolenaar  while new_ftime - old_ftime < 2
322494e9069SBram Moolenaar    sleep 100m
323494e9069SBram Moolenaar    call writefile(["Line3", "Line4"], 'Xfile')
324494e9069SBram Moolenaar    let new_ftime = getftime('Xfile')
325494e9069SBram Moolenaar  endwhile
326494e9069SBram Moolenaar
327494e9069SBram Moolenaar  " Try to overwrite the file and check for the prompt
328494e9069SBram Moolenaar  call term_sendkeys(buf, ":w\<CR>")
329733d259aSBram Moolenaar  call TermWait(buf)
330494e9069SBram Moolenaar  call WaitForAssert({-> assert_equal("WARNING: The file has been changed since reading it!!!", term_getline(buf, 9))})
331494e9069SBram Moolenaar  call assert_equal("Do you really want to write to it (y/n)?",
332494e9069SBram Moolenaar        \ term_getline(buf, 10))
333494e9069SBram Moolenaar  call term_sendkeys(buf, "n\<CR>")
334733d259aSBram Moolenaar  call TermWait(buf)
335494e9069SBram Moolenaar  call assert_equal(new_ftime, getftime('Xfile'))
336494e9069SBram Moolenaar  call term_sendkeys(buf, ":w\<CR>")
337733d259aSBram Moolenaar  call TermWait(buf)
338494e9069SBram Moolenaar  call term_sendkeys(buf, "y\<CR>")
339733d259aSBram Moolenaar  call TermWait(buf)
340494e9069SBram Moolenaar  call WaitForAssert({-> assert_equal('Line2', readfile('Xfile')[1])})
341494e9069SBram Moolenaar
342494e9069SBram Moolenaar  " clean up
343494e9069SBram Moolenaar  call StopVimInTerminal(buf)
344494e9069SBram Moolenaar  call delete('Xfile')
345494e9069SBram Moolenaarendfunc
346494e9069SBram Moolenaar
347494e9069SBram Moolenaar" Test for an autocmd unloading a buffer during a write command
348494e9069SBram Moolenaarfunc Test_write_autocmd_unloadbuf_lockmark()
349494e9069SBram Moolenaar  augroup WriteTest
350494e9069SBram Moolenaar    autocmd BufWritePre Xfile enew | write
351494e9069SBram Moolenaar  augroup END
352494e9069SBram Moolenaar  e Xfile
353e2e4075fSBram Moolenaar  call assert_fails('lockmarks write', ['E32:', 'E203:'])
354494e9069SBram Moolenaar  augroup WriteTest
355494e9069SBram Moolenaar    au!
356494e9069SBram Moolenaar  augroup END
357494e9069SBram Moolenaar  augroup! WriteTest
358494e9069SBram Moolenaarendfunc
359494e9069SBram Moolenaar
360494e9069SBram Moolenaar" Test for writing a buffer with 'acwrite' but without autocmds
361494e9069SBram Moolenaarfunc Test_write_acwrite_error()
362494e9069SBram Moolenaar  new Xfile
363494e9069SBram Moolenaar  call setline(1, ['line1', 'line2', 'line3'])
364494e9069SBram Moolenaar  set buftype=acwrite
365494e9069SBram Moolenaar  call assert_fails('write', 'E676:')
366494e9069SBram Moolenaar  call assert_fails('1,2write!', 'E676:')
367494e9069SBram Moolenaar  call assert_fails('w >>', 'E676:')
368494e9069SBram Moolenaar  close!
369494e9069SBram Moolenaarendfunc
370494e9069SBram Moolenaar
371494e9069SBram Moolenaar" Test for adding and removing lines from an autocmd when writing a buffer
372494e9069SBram Moolenaarfunc Test_write_autocmd_add_remove_lines()
373494e9069SBram Moolenaar  new Xfile
374494e9069SBram Moolenaar  call setline(1, ['aaa', 'bbb', 'ccc', 'ddd'])
375494e9069SBram Moolenaar
376494e9069SBram Moolenaar  " Autocmd deleting lines from the file when writing a partial file
377494e9069SBram Moolenaar  augroup WriteTest2
378494e9069SBram Moolenaar    au!
379494e9069SBram Moolenaar    autocmd FileWritePre Xfile 1,2d
380494e9069SBram Moolenaar  augroup END
381494e9069SBram Moolenaar  call assert_fails('2,3w!', 'E204:')
382494e9069SBram Moolenaar
383494e9069SBram Moolenaar  " Autocmd adding lines to a file when writing a partial file
384494e9069SBram Moolenaar  augroup WriteTest2
385494e9069SBram Moolenaar    au!
386494e9069SBram Moolenaar    autocmd FileWritePre Xfile call append(0, ['xxx', 'yyy'])
387494e9069SBram Moolenaar  augroup END
388494e9069SBram Moolenaar  %d
389494e9069SBram Moolenaar  call setline(1, ['aaa', 'bbb', 'ccc', 'ddd'])
390494e9069SBram Moolenaar  1,2w!
391494e9069SBram Moolenaar  call assert_equal(['xxx', 'yyy', 'aaa', 'bbb'], readfile('Xfile'))
392494e9069SBram Moolenaar
393494e9069SBram Moolenaar  " Autocmd deleting lines from the file when writing the whole file
394494e9069SBram Moolenaar  augroup WriteTest2
395494e9069SBram Moolenaar    au!
396494e9069SBram Moolenaar    autocmd BufWritePre Xfile 1,2d
397494e9069SBram Moolenaar  augroup END
398494e9069SBram Moolenaar  %d
399494e9069SBram Moolenaar  call setline(1, ['aaa', 'bbb', 'ccc', 'ddd'])
400494e9069SBram Moolenaar  w
401494e9069SBram Moolenaar  call assert_equal(['ccc', 'ddd'], readfile('Xfile'))
402494e9069SBram Moolenaar
403494e9069SBram Moolenaar  augroup WriteTest2
404494e9069SBram Moolenaar    au!
405494e9069SBram Moolenaar  augroup END
406494e9069SBram Moolenaar  augroup! WriteTest2
407494e9069SBram Moolenaar
408494e9069SBram Moolenaar  close!
409494e9069SBram Moolenaar  call delete('Xfile')
410494e9069SBram Moolenaarendfunc
411494e9069SBram Moolenaar
412494e9069SBram Moolenaar" Test for writing to a readonly file
413494e9069SBram Moolenaarfunc Test_write_readonly()
414494e9069SBram Moolenaar  call writefile([], 'Xfile')
415494e9069SBram Moolenaar  call setfperm('Xfile', "r--------")
416494e9069SBram Moolenaar  edit Xfile
417b86abadfSBram Moolenaar  set noreadonly backupskip=
418494e9069SBram Moolenaar  call assert_fails('write', 'E505:')
419494e9069SBram Moolenaar  let save_cpo = &cpo
420494e9069SBram Moolenaar  set cpo+=W
421494e9069SBram Moolenaar  call assert_fails('write!', 'E504:')
422494e9069SBram Moolenaar  let &cpo = save_cpo
4231de5f7c8SBram Moolenaar  call setline(1, ['line1'])
4241de5f7c8SBram Moolenaar  write!
4251de5f7c8SBram Moolenaar  call assert_equal(['line1'], readfile('Xfile'))
42636f96a51SYegappan Lakshmanan
42736f96a51SYegappan Lakshmanan  " Auto-saving a readonly file should fail with 'autowriteall'
42836f96a51SYegappan Lakshmanan  %bw!
42936f96a51SYegappan Lakshmanan  e Xfile
43036f96a51SYegappan Lakshmanan  set noreadonly autowriteall
43136f96a51SYegappan Lakshmanan  call setline(1, ['aaaa'])
43236f96a51SYegappan Lakshmanan  call assert_fails('n', 'E505:')
43336f96a51SYegappan Lakshmanan  set cpo+=W
43436f96a51SYegappan Lakshmanan  call assert_fails('n', 'E504:')
43536f96a51SYegappan Lakshmanan  set cpo-=W
43636f96a51SYegappan Lakshmanan  set autowriteall&
43736f96a51SYegappan Lakshmanan
438b86abadfSBram Moolenaar  set backupskip&
439494e9069SBram Moolenaar  call delete('Xfile')
44036f96a51SYegappan Lakshmanan  %bw!
4415d98dc2aSBram Moolenaarendfunc
4425d98dc2aSBram Moolenaar
4431de5f7c8SBram Moolenaar" Test for 'patchmode'
4441de5f7c8SBram Moolenaarfunc Test_patchmode()
4451de5f7c8SBram Moolenaar  call writefile(['one'], 'Xfile')
446b86abadfSBram Moolenaar  set patchmode=.orig nobackup backupskip= writebackup
4471de5f7c8SBram Moolenaar  new Xfile
4481de5f7c8SBram Moolenaar  call setline(1, 'two')
4491de5f7c8SBram Moolenaar  " first write should create the .orig file
4501de5f7c8SBram Moolenaar  write
4511de5f7c8SBram Moolenaar  call assert_equal(['one'], readfile('Xfile.orig'))
4521de5f7c8SBram Moolenaar  call setline(1, 'three')
4531de5f7c8SBram Moolenaar  " subsequent writes should not create/modify the .orig file
4541de5f7c8SBram Moolenaar  write
4551de5f7c8SBram Moolenaar  call assert_equal(['one'], readfile('Xfile.orig'))
45636f96a51SYegappan Lakshmanan
45736f96a51SYegappan Lakshmanan  " use 'patchmode' with 'nobackup' and 'nowritebackup' to create an empty
45836f96a51SYegappan Lakshmanan  " original file
45936f96a51SYegappan Lakshmanan  call delete('Xfile')
46036f96a51SYegappan Lakshmanan  call delete('Xfile.orig')
46136f96a51SYegappan Lakshmanan  %bw!
46236f96a51SYegappan Lakshmanan  set patchmode=.orig nobackup nowritebackup
46336f96a51SYegappan Lakshmanan  edit Xfile
46436f96a51SYegappan Lakshmanan  call setline(1, ['xxx'])
46536f96a51SYegappan Lakshmanan  write
46636f96a51SYegappan Lakshmanan  call assert_equal(['xxx'], readfile('Xfile'))
46736f96a51SYegappan Lakshmanan  call assert_equal([], readfile('Xfile.orig'))
46836f96a51SYegappan Lakshmanan
469b86abadfSBram Moolenaar  set patchmode& backup& backupskip& writebackup&
4701de5f7c8SBram Moolenaar  call delete('Xfile')
4711de5f7c8SBram Moolenaar  call delete('Xfile.orig')
4721de5f7c8SBram Moolenaarendfunc
4731de5f7c8SBram Moolenaar
4741de5f7c8SBram Moolenaar" Test for writing to a file in a readonly directory
475f9a65505SBram Moolenaar" NOTE: if you run tests as root this will fail.  Don't run tests as root!
4761de5f7c8SBram Moolenaarfunc Test_write_readonly_dir()
4771de5f7c8SBram Moolenaar  " On MS-Windows, modifying files in a read-only directory is allowed.
478b86abadfSBram Moolenaar  CheckUnix
47917709e28SBram Moolenaar  " Root can do it too.
48017709e28SBram Moolenaar  CheckNotRoot
48117709e28SBram Moolenaar
48246aa6f93SYegappan Lakshmanan  call mkdir('Xdir/')
4831de5f7c8SBram Moolenaar  call writefile(['one'], 'Xdir/Xfile1')
4841de5f7c8SBram Moolenaar  call setfperm('Xdir', 'r-xr--r--')
4851de5f7c8SBram Moolenaar  " try to create a new file in the directory
4861de5f7c8SBram Moolenaar  new Xdir/Xfile2
4871de5f7c8SBram Moolenaar  call setline(1, 'two')
4881de5f7c8SBram Moolenaar  call assert_fails('write', 'E212:')
4891de5f7c8SBram Moolenaar  " try to create a backup file in the directory
4901de5f7c8SBram Moolenaar  edit! Xdir/Xfile1
491b86abadfSBram Moolenaar  set backupdir=./Xdir backupskip=
4921de5f7c8SBram Moolenaar  set patchmode=.orig
4931de5f7c8SBram Moolenaar  call assert_fails('write', 'E509:')
4941de5f7c8SBram Moolenaar  call setfperm('Xdir', 'rwxr--r--')
4951de5f7c8SBram Moolenaar  call delete('Xdir', 'rf')
496b86abadfSBram Moolenaar  set backupdir& backupskip& patchmode&
4971de5f7c8SBram Moolenaarendfunc
4981de5f7c8SBram Moolenaar
499b340baedSBram Moolenaar" Test for writing a file using invalid file encoding
500b340baedSBram Moolenaarfunc Test_write_invalid_encoding()
501b340baedSBram Moolenaar  new
502b340baedSBram Moolenaar  call setline(1, 'abc')
503b340baedSBram Moolenaar  call assert_fails('write ++enc=axbyc Xfile', 'E213:')
504b340baedSBram Moolenaar  close!
505b340baedSBram Moolenaarendfunc
506b340baedSBram Moolenaar
507622b3568SBram Moolenaar" Tests for reading and writing files with conversion for Win32.
508622b3568SBram Moolenaarfunc Test_write_file_encoding()
509622b3568SBram Moolenaar  CheckMSWindows
510622b3568SBram Moolenaar  let save_encoding = &encoding
511622b3568SBram Moolenaar  let save_fileencodings = &fileencodings
512f883d902SK.Takata  set encoding=latin1 fileencodings&
513622b3568SBram Moolenaar  let text =<< trim END
514622b3568SBram Moolenaar    1 utf-8 text: Для Vim version 6.2.  Последнее изменение: 1970 Jan 01
515622b3568SBram Moolenaar    2 cp1251 text: ��� Vim version 6.2.  ��������� ���������: 1970 Jan 01
516622b3568SBram Moolenaar    3 cp866 text: ��� Vim version 6.2.  ��᫥���� ���������: 1970 Jan 01
517622b3568SBram Moolenaar  END
518622b3568SBram Moolenaar  call writefile(text, 'Xfile')
519622b3568SBram Moolenaar  edit Xfile
520622b3568SBram Moolenaar
521622b3568SBram Moolenaar  " write tests:
522622b3568SBram Moolenaar  " combine three values for 'encoding' with three values for 'fileencoding'
523622b3568SBram Moolenaar  " also write files for read tests
524622b3568SBram Moolenaar  call cursor(1, 1)
525622b3568SBram Moolenaar  set encoding=utf-8
526622b3568SBram Moolenaar  .w! ++enc=utf-8 Xtest
527622b3568SBram Moolenaar  .w ++enc=cp1251 >> Xtest
528622b3568SBram Moolenaar  .w ++enc=cp866 >> Xtest
529622b3568SBram Moolenaar  .w! ++enc=utf-8 Xutf8
530622b3568SBram Moolenaar  let expected =<< trim END
531622b3568SBram Moolenaar    1 utf-8 text: Для Vim version 6.2.  Последнее изменение: 1970 Jan 01
532622b3568SBram Moolenaar    1 utf-8 text: ��� Vim version 6.2.  ��������� ���������: 1970 Jan 01
533622b3568SBram Moolenaar    1 utf-8 text: ��� Vim version 6.2.  ��᫥���� ���������: 1970 Jan 01
534622b3568SBram Moolenaar  END
535622b3568SBram Moolenaar  call assert_equal(expected, readfile('Xtest'))
536622b3568SBram Moolenaar
537622b3568SBram Moolenaar  call cursor(2, 1)
538622b3568SBram Moolenaar  set encoding=cp1251
539622b3568SBram Moolenaar  .w! ++enc=utf-8 Xtest
540622b3568SBram Moolenaar  .w ++enc=cp1251 >> Xtest
541622b3568SBram Moolenaar  .w ++enc=cp866 >> Xtest
542622b3568SBram Moolenaar  .w! ++enc=cp1251 Xcp1251
543622b3568SBram Moolenaar  let expected =<< trim END
544622b3568SBram Moolenaar    2 cp1251 text: Для Vim version 6.2.  Последнее изменение: 1970 Jan 01
545622b3568SBram Moolenaar    2 cp1251 text: ��� Vim version 6.2.  ��������� ���������: 1970 Jan 01
546622b3568SBram Moolenaar    2 cp1251 text: ��� Vim version 6.2.  ��᫥���� ���������: 1970 Jan 01
547622b3568SBram Moolenaar  END
548622b3568SBram Moolenaar  call assert_equal(expected, readfile('Xtest'))
549622b3568SBram Moolenaar
550622b3568SBram Moolenaar  call cursor(3, 1)
551622b3568SBram Moolenaar  set encoding=cp866
552622b3568SBram Moolenaar  .w! ++enc=utf-8 Xtest
553622b3568SBram Moolenaar  .w ++enc=cp1251 >> Xtest
554622b3568SBram Moolenaar  .w ++enc=cp866 >> Xtest
555622b3568SBram Moolenaar  .w! ++enc=cp866 Xcp866
556622b3568SBram Moolenaar  let expected =<< trim END
557622b3568SBram Moolenaar    3 cp866 text: Для Vim version 6.2.  Последнее изменение: 1970 Jan 01
558622b3568SBram Moolenaar    3 cp866 text: ��� Vim version 6.2.  ��������� ���������: 1970 Jan 01
559622b3568SBram Moolenaar    3 cp866 text: ��� Vim version 6.2.  ��᫥���� ���������: 1970 Jan 01
560622b3568SBram Moolenaar  END
561622b3568SBram Moolenaar  call assert_equal(expected, readfile('Xtest'))
562622b3568SBram Moolenaar
563622b3568SBram Moolenaar  " read three 'fileencoding's with utf-8 'encoding'
564622b3568SBram Moolenaar  set encoding=utf-8 fencs=utf-8,cp1251
565622b3568SBram Moolenaar  e Xutf8
566622b3568SBram Moolenaar  .w! ++enc=utf-8 Xtest
567622b3568SBram Moolenaar  e Xcp1251
568622b3568SBram Moolenaar  .w ++enc=utf-8 >> Xtest
569622b3568SBram Moolenaar  set fencs=utf-8,cp866
570622b3568SBram Moolenaar  e Xcp866
571622b3568SBram Moolenaar  .w ++enc=utf-8 >> Xtest
572622b3568SBram Moolenaar  let expected =<< trim END
573622b3568SBram Moolenaar    1 utf-8 text: Для Vim version 6.2.  Последнее изменение: 1970 Jan 01
574622b3568SBram Moolenaar    2 cp1251 text: Для Vim version 6.2.  Последнее изменение: 1970 Jan 01
575622b3568SBram Moolenaar    3 cp866 text: Для Vim version 6.2.  Последнее изменение: 1970 Jan 01
576622b3568SBram Moolenaar  END
577622b3568SBram Moolenaar  call assert_equal(expected, readfile('Xtest'))
578622b3568SBram Moolenaar
579622b3568SBram Moolenaar  " read three 'fileencoding's with cp1251 'encoding'
580622b3568SBram Moolenaar  set encoding=utf-8 fencs=utf-8,cp1251
581622b3568SBram Moolenaar  e Xutf8
582622b3568SBram Moolenaar  .w! ++enc=cp1251 Xtest
583622b3568SBram Moolenaar  e Xcp1251
584622b3568SBram Moolenaar  .w ++enc=cp1251 >> Xtest
585622b3568SBram Moolenaar  set fencs=utf-8,cp866
586622b3568SBram Moolenaar  e Xcp866
587622b3568SBram Moolenaar  .w ++enc=cp1251 >> Xtest
588622b3568SBram Moolenaar  let expected =<< trim END
589622b3568SBram Moolenaar    1 utf-8 text: ��� Vim version 6.2.  ��������� ���������: 1970 Jan 01
590622b3568SBram Moolenaar    2 cp1251 text: ��� Vim version 6.2.  ��������� ���������: 1970 Jan 01
591622b3568SBram Moolenaar    3 cp866 text: ��� Vim version 6.2.  ��������� ���������: 1970 Jan 01
592622b3568SBram Moolenaar  END
593622b3568SBram Moolenaar  call assert_equal(expected, readfile('Xtest'))
594622b3568SBram Moolenaar
595622b3568SBram Moolenaar  " read three 'fileencoding's with cp866 'encoding'
596622b3568SBram Moolenaar  set encoding=cp866 fencs=utf-8,cp1251
597622b3568SBram Moolenaar  e Xutf8
598622b3568SBram Moolenaar  .w! ++enc=cp866 Xtest
599622b3568SBram Moolenaar  e Xcp1251
600622b3568SBram Moolenaar  .w ++enc=cp866 >> Xtest
601622b3568SBram Moolenaar  set fencs=utf-8,cp866
602622b3568SBram Moolenaar  e Xcp866
603622b3568SBram Moolenaar  .w ++enc=cp866 >> Xtest
604622b3568SBram Moolenaar  let expected =<< trim END
605622b3568SBram Moolenaar    1 utf-8 text: ��� Vim version 6.2.  ��᫥���� ���������: 1970 Jan 01
606622b3568SBram Moolenaar    2 cp1251 text: ��� Vim version 6.2.  ��᫥���� ���������: 1970 Jan 01
607622b3568SBram Moolenaar    3 cp866 text: ��� Vim version 6.2.  ��᫥���� ���������: 1970 Jan 01
608622b3568SBram Moolenaar  END
609622b3568SBram Moolenaar  call assert_equal(expected, readfile('Xtest'))
610622b3568SBram Moolenaar
611622b3568SBram Moolenaar  call delete('Xfile')
612622b3568SBram Moolenaar  call delete('Xtest')
613622b3568SBram Moolenaar  call delete('Xutf8')
614622b3568SBram Moolenaar  call delete('Xcp1251')
615622b3568SBram Moolenaar  call delete('Xcp866')
616622b3568SBram Moolenaar  let &encoding = save_encoding
617622b3568SBram Moolenaar  let &fileencodings = save_fileencodings
618622b3568SBram Moolenaar  %bw!
619622b3568SBram Moolenaarendfunc
620622b3568SBram Moolenaar
621b61ef01cSBram Moolenaar" Test for writing and reading a file starting with a BOM.
622b61ef01cSBram Moolenaar" Byte Order Mark (BOM) character for various encodings is below:
623b61ef01cSBram Moolenaar"     UTF-8      : EF BB BF
624b61ef01cSBram Moolenaar"     UTF-16 (BE): FE FF
625b61ef01cSBram Moolenaar"     UTF-16 (LE): FF FE
626b61ef01cSBram Moolenaar"     UTF-32 (BE): 00 00 FE FF
627b61ef01cSBram Moolenaar"     UTF-32 (LE): FF FE 00 00
628b61ef01cSBram Moolenaarfunc Test_readwrite_file_with_bom()
629b61ef01cSBram Moolenaar  let utf8_bom = "\xEF\xBB\xBF"
630b61ef01cSBram Moolenaar  let utf16be_bom = "\xFE\xFF"
631b61ef01cSBram Moolenaar  let utf16le_bom = "\xFF\xFE"
632b61ef01cSBram Moolenaar  let utf32be_bom = "\n\n\xFE\xFF"
633b61ef01cSBram Moolenaar  let utf32le_bom = "\xFF\xFE\n\n"
634b61ef01cSBram Moolenaar  let save_fileencoding = &fileencoding
635b61ef01cSBram Moolenaar  set cpoptions+=S
636b61ef01cSBram Moolenaar
637b61ef01cSBram Moolenaar  " Check that editing a latin1 file doesn't see a BOM
638b61ef01cSBram Moolenaar  call writefile(["\xFE\xFElatin-1"], 'Xtest1')
639b61ef01cSBram Moolenaar  edit Xtest1
640b61ef01cSBram Moolenaar  call assert_equal('latin1', &fileencoding)
641b61ef01cSBram Moolenaar  call assert_equal(0, &bomb)
642b61ef01cSBram Moolenaar  set fenc=latin1
643b61ef01cSBram Moolenaar  write Xfile2
644b61ef01cSBram Moolenaar  call assert_equal(["\xFE\xFElatin-1", ''], readfile('Xfile2', 'b'))
645b61ef01cSBram Moolenaar  set bomb fenc=latin1
646b61ef01cSBram Moolenaar  write Xtest3
647b61ef01cSBram Moolenaar  call assert_equal(["\xFE\xFElatin-1", ''], readfile('Xtest3', 'b'))
648b61ef01cSBram Moolenaar  set bomb&
649b61ef01cSBram Moolenaar
650b61ef01cSBram Moolenaar  " Check utf-8 BOM
651b61ef01cSBram Moolenaar  %bw!
652b61ef01cSBram Moolenaar  call writefile([utf8_bom .. "utf-8"], 'Xtest1')
653b61ef01cSBram Moolenaar  edit! Xtest1
654b61ef01cSBram Moolenaar  call assert_equal('utf-8', &fileencoding)
655b61ef01cSBram Moolenaar  call assert_equal(1, &bomb)
656b61ef01cSBram Moolenaar  call assert_equal('utf-8', getline(1))
657b61ef01cSBram Moolenaar  set fenc=latin1
658b61ef01cSBram Moolenaar  write! Xfile2
659b61ef01cSBram Moolenaar  call assert_equal(['utf-8', ''], readfile('Xfile2', 'b'))
660b61ef01cSBram Moolenaar  set fenc=utf-8
661b61ef01cSBram Moolenaar  w! Xtest3
662b61ef01cSBram Moolenaar  call assert_equal([utf8_bom .. "utf-8", ''], readfile('Xtest3', 'b'))
663b61ef01cSBram Moolenaar
664b61ef01cSBram Moolenaar  " Check utf-8 with an error (will fall back to latin-1)
665b61ef01cSBram Moolenaar  %bw!
666b61ef01cSBram Moolenaar  call writefile([utf8_bom .. "utf-8\x80err"], 'Xtest1')
667b61ef01cSBram Moolenaar  edit! Xtest1
668b61ef01cSBram Moolenaar  call assert_equal('latin1', &fileencoding)
669b61ef01cSBram Moolenaar  call assert_equal(0, &bomb)
670b61ef01cSBram Moolenaar  call assert_equal("\xC3\xAF\xC2\xBB\xC2\xBFutf-8\xC2\x80err", getline(1))
671b61ef01cSBram Moolenaar  set fenc=latin1
672b61ef01cSBram Moolenaar  write! Xfile2
673b61ef01cSBram Moolenaar  call assert_equal([utf8_bom .. "utf-8\x80err", ''], readfile('Xfile2', 'b'))
674b61ef01cSBram Moolenaar  set fenc=utf-8
675b61ef01cSBram Moolenaar  w! Xtest3
676b61ef01cSBram Moolenaar  call assert_equal(["\xC3\xAF\xC2\xBB\xC2\xBFutf-8\xC2\x80err", ''],
677b61ef01cSBram Moolenaar        \ readfile('Xtest3', 'b'))
678b61ef01cSBram Moolenaar
679b61ef01cSBram Moolenaar  " Check ucs-2 BOM
680b61ef01cSBram Moolenaar  %bw!
681b61ef01cSBram Moolenaar  call writefile([utf16be_bom .. "\nu\nc\ns\n-\n2\n"], 'Xtest1')
682b61ef01cSBram Moolenaar  edit! Xtest1
683b61ef01cSBram Moolenaar  call assert_equal('utf-16', &fileencoding)
684b61ef01cSBram Moolenaar  call assert_equal(1, &bomb)
685b61ef01cSBram Moolenaar  call assert_equal('ucs-2', getline(1))
686b61ef01cSBram Moolenaar  set fenc=latin1
687b61ef01cSBram Moolenaar  write! Xfile2
688b61ef01cSBram Moolenaar  call assert_equal(["ucs-2", ''], readfile('Xfile2', 'b'))
689b61ef01cSBram Moolenaar  set fenc=ucs-2
690b61ef01cSBram Moolenaar  w! Xtest3
691b61ef01cSBram Moolenaar  call assert_equal([utf16be_bom .. "\nu\nc\ns\n-\n2\n", ''],
692b61ef01cSBram Moolenaar        \ readfile('Xtest3', 'b'))
693b61ef01cSBram Moolenaar
694b61ef01cSBram Moolenaar  " Check ucs-2le BOM
695b61ef01cSBram Moolenaar  %bw!
696b61ef01cSBram Moolenaar  call writefile([utf16le_bom .. "u\nc\ns\n-\n2\nl\ne\n"], 'Xtest1')
697b61ef01cSBram Moolenaar  " Need to add a NUL byte after the NL byte
698b61ef01cSBram Moolenaar  call writefile(0z00, 'Xtest1', 'a')
699b61ef01cSBram Moolenaar  edit! Xtest1
700b61ef01cSBram Moolenaar  call assert_equal('utf-16le', &fileencoding)
701b61ef01cSBram Moolenaar  call assert_equal(1, &bomb)
702b61ef01cSBram Moolenaar  call assert_equal('ucs-2le', getline(1))
703b61ef01cSBram Moolenaar  set fenc=latin1
704b61ef01cSBram Moolenaar  write! Xfile2
705b61ef01cSBram Moolenaar  call assert_equal(["ucs-2le", ''], readfile('Xfile2', 'b'))
706b61ef01cSBram Moolenaar  set fenc=ucs-2le
707b61ef01cSBram Moolenaar  w! Xtest3
708b61ef01cSBram Moolenaar  call assert_equal([utf16le_bom .. "u\nc\ns\n-\n2\nl\ne\n", "\n"],
709b61ef01cSBram Moolenaar        \ readfile('Xtest3', 'b'))
710b61ef01cSBram Moolenaar
711b61ef01cSBram Moolenaar  " Check ucs-4 BOM
712b61ef01cSBram Moolenaar  %bw!
713b61ef01cSBram Moolenaar  call writefile([utf32be_bom .. "\n\n\nu\n\n\nc\n\n\ns\n\n\n-\n\n\n4\n\n\n"], 'Xtest1')
714b61ef01cSBram Moolenaar  edit! Xtest1
715b61ef01cSBram Moolenaar  call assert_equal('ucs-4', &fileencoding)
716b61ef01cSBram Moolenaar  call assert_equal(1, &bomb)
717b61ef01cSBram Moolenaar  call assert_equal('ucs-4', getline(1))
718b61ef01cSBram Moolenaar  set fenc=latin1
719b61ef01cSBram Moolenaar  write! Xfile2
720b61ef01cSBram Moolenaar  call assert_equal(["ucs-4", ''], readfile('Xfile2', 'b'))
721b61ef01cSBram Moolenaar  set fenc=ucs-4
722b61ef01cSBram Moolenaar  w! Xtest3
723b61ef01cSBram Moolenaar  call assert_equal([utf32be_bom .. "\n\n\nu\n\n\nc\n\n\ns\n\n\n-\n\n\n4\n\n\n", ''], readfile('Xtest3', 'b'))
724b61ef01cSBram Moolenaar
725b61ef01cSBram Moolenaar  " Check ucs-4le BOM
726b61ef01cSBram Moolenaar  %bw!
727b61ef01cSBram Moolenaar  call writefile([utf32le_bom .. "u\n\n\nc\n\n\ns\n\n\n-\n\n\n4\n\n\nl\n\n\ne\n\n\n"], 'Xtest1')
728b61ef01cSBram Moolenaar  " Need to add three NUL bytes after the NL byte
729b61ef01cSBram Moolenaar  call writefile(0z000000, 'Xtest1', 'a')
730b61ef01cSBram Moolenaar  edit! Xtest1
731b61ef01cSBram Moolenaar  call assert_equal('ucs-4le', &fileencoding)
732b61ef01cSBram Moolenaar  call assert_equal(1, &bomb)
733b61ef01cSBram Moolenaar  call assert_equal('ucs-4le', getline(1))
734b61ef01cSBram Moolenaar  set fenc=latin1
735b61ef01cSBram Moolenaar  write! Xfile2
736b61ef01cSBram Moolenaar  call assert_equal(["ucs-4le", ''], readfile('Xfile2', 'b'))
737b61ef01cSBram Moolenaar  set fenc=ucs-4le
738b61ef01cSBram Moolenaar  w! Xtest3
739b61ef01cSBram Moolenaar  call assert_equal([utf32le_bom .. "u\n\n\nc\n\n\ns\n\n\n-\n\n\n4\n\n\nl\n\n\ne\n\n\n", "\n\n\n"], readfile('Xtest3', 'b'))
740b61ef01cSBram Moolenaar
741b61ef01cSBram Moolenaar  set cpoptions-=S
742b61ef01cSBram Moolenaar  let &fileencoding = save_fileencoding
743b61ef01cSBram Moolenaar  call delete('Xtest1')
744733d259aSBram Moolenaar  call delete('Xfile2')
745b61ef01cSBram Moolenaar  call delete('Xtest3')
746b61ef01cSBram Moolenaar  %bw!
747b61ef01cSBram Moolenaarendfunc
748b61ef01cSBram Moolenaar
749b3c8b1d2SBram Moolenaarfunc Test_read_write_bin()
750b3c8b1d2SBram Moolenaar  " write file missing EOL
751b3c8b1d2SBram Moolenaar  call writefile(['noeol'], "XNoEolSetEol", 'bS')
752b3c8b1d2SBram Moolenaar  call assert_equal(0z6E6F656F6C, readfile('XNoEolSetEol', 'B'))
753b3c8b1d2SBram Moolenaar
754b3c8b1d2SBram Moolenaar  " when file is read 'eol' is off
75516204962SBram Moolenaar  set nofixeol
75616204962SBram Moolenaar  e! ++ff=unix XNoEolSetEol
757b3c8b1d2SBram Moolenaar  call assert_equal(0, &eol)
758b3c8b1d2SBram Moolenaar
759b3c8b1d2SBram Moolenaar  " writing with 'eol' set adds the newline
760b3c8b1d2SBram Moolenaar  setlocal eol
761b3c8b1d2SBram Moolenaar  w
762b3c8b1d2SBram Moolenaar  call assert_equal(0z6E6F656F6C0A, readfile('XNoEolSetEol', 'B'))
763b3c8b1d2SBram Moolenaar
764b3c8b1d2SBram Moolenaar  call delete('XNoEolSetEol')
76546aa6f93SYegappan Lakshmanan  set ff& fixeol&
766bd318559SBram Moolenaar  bwipe! XNoEolSetEol
767b3c8b1d2SBram Moolenaarendfunc
768b3c8b1d2SBram Moolenaar
76936f96a51SYegappan Lakshmanan" Test for the 'backupcopy' option when writing files
77036f96a51SYegappan Lakshmananfunc Test_backupcopy()
77136f96a51SYegappan Lakshmanan  CheckUnix
77236f96a51SYegappan Lakshmanan  set backupskip=
77336f96a51SYegappan Lakshmanan  " With the default 'backupcopy' setting, saving a symbolic link file
77436f96a51SYegappan Lakshmanan  " should not break the link.
77536f96a51SYegappan Lakshmanan  set backupcopy&
77636f96a51SYegappan Lakshmanan  call writefile(['1111'], 'Xfile1')
77736f96a51SYegappan Lakshmanan  silent !ln -s Xfile1 Xfile2
77836f96a51SYegappan Lakshmanan  new Xfile2
77936f96a51SYegappan Lakshmanan  call setline(1, ['2222'])
78036f96a51SYegappan Lakshmanan  write
78136f96a51SYegappan Lakshmanan  close
78236f96a51SYegappan Lakshmanan  call assert_equal(['2222'], readfile('Xfile1'))
78336f96a51SYegappan Lakshmanan  call assert_equal('Xfile1', resolve('Xfile2'))
78436f96a51SYegappan Lakshmanan  call assert_equal('link', getftype('Xfile2'))
78536f96a51SYegappan Lakshmanan  call delete('Xfile1')
78636f96a51SYegappan Lakshmanan  call delete('Xfile2')
78736f96a51SYegappan Lakshmanan
78836f96a51SYegappan Lakshmanan  " With the 'backupcopy' set to 'breaksymlink', saving a symbolic link file
78936f96a51SYegappan Lakshmanan  " should break the link.
79036f96a51SYegappan Lakshmanan  set backupcopy=yes,breaksymlink
79136f96a51SYegappan Lakshmanan  call writefile(['1111'], 'Xfile1')
79236f96a51SYegappan Lakshmanan  silent !ln -s Xfile1 Xfile2
79336f96a51SYegappan Lakshmanan  new Xfile2
79436f96a51SYegappan Lakshmanan  call setline(1, ['2222'])
79536f96a51SYegappan Lakshmanan  write
79636f96a51SYegappan Lakshmanan  close
79736f96a51SYegappan Lakshmanan  call assert_equal(['1111'], readfile('Xfile1'))
79836f96a51SYegappan Lakshmanan  call assert_equal(['2222'], readfile('Xfile2'))
79936f96a51SYegappan Lakshmanan  call assert_equal('Xfile2', resolve('Xfile2'))
80036f96a51SYegappan Lakshmanan  call assert_equal('file', getftype('Xfile2'))
80136f96a51SYegappan Lakshmanan  call delete('Xfile1')
80236f96a51SYegappan Lakshmanan  call delete('Xfile2')
80336f96a51SYegappan Lakshmanan  set backupcopy&
80436f96a51SYegappan Lakshmanan
80536f96a51SYegappan Lakshmanan  " With the default 'backupcopy' setting, saving a hard link file
80636f96a51SYegappan Lakshmanan  " should not break the link.
80736f96a51SYegappan Lakshmanan  set backupcopy&
80836f96a51SYegappan Lakshmanan  call writefile(['1111'], 'Xfile1')
80936f96a51SYegappan Lakshmanan  silent !ln Xfile1 Xfile2
81036f96a51SYegappan Lakshmanan  new Xfile2
81136f96a51SYegappan Lakshmanan  call setline(1, ['2222'])
81236f96a51SYegappan Lakshmanan  write
81336f96a51SYegappan Lakshmanan  close
81436f96a51SYegappan Lakshmanan  call assert_equal(['2222'], readfile('Xfile1'))
81536f96a51SYegappan Lakshmanan  call delete('Xfile1')
81636f96a51SYegappan Lakshmanan  call delete('Xfile2')
81736f96a51SYegappan Lakshmanan
81836f96a51SYegappan Lakshmanan  " With the 'backupcopy' set to 'breaksymlink', saving a hard link file
81936f96a51SYegappan Lakshmanan  " should break the link.
82036f96a51SYegappan Lakshmanan  set backupcopy=yes,breakhardlink
82136f96a51SYegappan Lakshmanan  call writefile(['1111'], 'Xfile1')
82236f96a51SYegappan Lakshmanan  silent !ln Xfile1 Xfile2
82336f96a51SYegappan Lakshmanan  new Xfile2
82436f96a51SYegappan Lakshmanan  call setline(1, ['2222'])
82536f96a51SYegappan Lakshmanan  write
82636f96a51SYegappan Lakshmanan  call assert_equal(['1111'], readfile('Xfile1'))
82736f96a51SYegappan Lakshmanan  call assert_equal(['2222'], readfile('Xfile2'))
82836f96a51SYegappan Lakshmanan  call delete('Xfile1')
82936f96a51SYegappan Lakshmanan  call delete('Xfile2')
83036f96a51SYegappan Lakshmanan
83136f96a51SYegappan Lakshmanan  " If a backup file is already present, then a slightly modified filename
83236f96a51SYegappan Lakshmanan  " should be used as the backup file. Try with 'backupcopy' set to 'yes' and
83336f96a51SYegappan Lakshmanan  " 'no'.
83436f96a51SYegappan Lakshmanan  %bw
83536f96a51SYegappan Lakshmanan  call writefile(['aaaa'], 'Xfile')
83636f96a51SYegappan Lakshmanan  call writefile(['bbbb'], 'Xfile.bak')
83736f96a51SYegappan Lakshmanan  set backupcopy=yes backupext=.bak
83836f96a51SYegappan Lakshmanan  new Xfile
83936f96a51SYegappan Lakshmanan  call setline(1, ['cccc'])
84036f96a51SYegappan Lakshmanan  write
84136f96a51SYegappan Lakshmanan  close
84236f96a51SYegappan Lakshmanan  call assert_equal(['cccc'], readfile('Xfile'))
84336f96a51SYegappan Lakshmanan  call assert_equal(['bbbb'], readfile('Xfile.bak'))
84436f96a51SYegappan Lakshmanan  set backupcopy=no backupext=.bak
84536f96a51SYegappan Lakshmanan  new Xfile
84636f96a51SYegappan Lakshmanan  call setline(1, ['dddd'])
84736f96a51SYegappan Lakshmanan  write
84836f96a51SYegappan Lakshmanan  close
84936f96a51SYegappan Lakshmanan  call assert_equal(['dddd'], readfile('Xfile'))
85036f96a51SYegappan Lakshmanan  call assert_equal(['bbbb'], readfile('Xfile.bak'))
85136f96a51SYegappan Lakshmanan  call delete('Xfile')
85236f96a51SYegappan Lakshmanan  call delete('Xfile.bak')
85336f96a51SYegappan Lakshmanan
85436f96a51SYegappan Lakshmanan  " Write to a device file (in Unix-like systems) which cannot be backed up.
85536f96a51SYegappan Lakshmanan  if has('unix')
85636f96a51SYegappan Lakshmanan    set writebackup backupcopy=yes nobackup
85736f96a51SYegappan Lakshmanan    new
85836f96a51SYegappan Lakshmanan    call setline(1, ['aaaa'])
85936f96a51SYegappan Lakshmanan    let output = execute('write! /dev/null')
86036f96a51SYegappan Lakshmanan    call assert_match('"/dev/null" \[Device]', output)
86136f96a51SYegappan Lakshmanan    close
86236f96a51SYegappan Lakshmanan    set writebackup backupcopy=no nobackup
86336f96a51SYegappan Lakshmanan    new
86436f96a51SYegappan Lakshmanan    call setline(1, ['aaaa'])
86536f96a51SYegappan Lakshmanan    let output = execute('write! /dev/null')
86636f96a51SYegappan Lakshmanan    call assert_match('"/dev/null" \[Device]', output)
86736f96a51SYegappan Lakshmanan    close
86836f96a51SYegappan Lakshmanan    set backup writebackup& backupcopy&
86936f96a51SYegappan Lakshmanan    new
87036f96a51SYegappan Lakshmanan    call setline(1, ['aaaa'])
87136f96a51SYegappan Lakshmanan    let output = execute('write! /dev/null')
87236f96a51SYegappan Lakshmanan    call assert_match('"/dev/null" \[Device]', output)
87336f96a51SYegappan Lakshmanan    close
87436f96a51SYegappan Lakshmanan  endif
87536f96a51SYegappan Lakshmanan
87636f96a51SYegappan Lakshmanan  set backupcopy& backupskip& backupext& backup&
87736f96a51SYegappan Lakshmananendfunc
87836f96a51SYegappan Lakshmanan
87936f96a51SYegappan Lakshmanan" Test for writing a file with 'encoding' set to 'utf-16'
88036f96a51SYegappan Lakshmananfunc Test_write_utf16()
88136f96a51SYegappan Lakshmanan  new
88236f96a51SYegappan Lakshmanan  call setline(1, ["\U00010001"])
88336f96a51SYegappan Lakshmanan  write ++enc=utf-16 Xfile
88436f96a51SYegappan Lakshmanan  bw!
88536f96a51SYegappan Lakshmanan  call assert_equal(0zD800DC01, readfile('Xfile', 'B')[0:3])
88636f96a51SYegappan Lakshmanan  call delete('Xfile')
88736f96a51SYegappan Lakshmananendfunc
88836f96a51SYegappan Lakshmanan
88936f96a51SYegappan Lakshmanan" Test for trying to save a backup file when the backup file is a symbolic
89036f96a51SYegappan Lakshmanan" link to the original file. The backup file should not be modified.
89136f96a51SYegappan Lakshmananfunc Test_write_backup_symlink()
89236f96a51SYegappan Lakshmanan  CheckUnix
89336f96a51SYegappan Lakshmanan  call writefile(['1111'], 'Xfile')
89436f96a51SYegappan Lakshmanan  silent !ln -s Xfile Xfile.bak
89536f96a51SYegappan Lakshmanan
89636f96a51SYegappan Lakshmanan  new Xfile
89736f96a51SYegappan Lakshmanan  set backup backupcopy=yes backupext=.bak
89836f96a51SYegappan Lakshmanan  write
89936f96a51SYegappan Lakshmanan  call assert_equal('link', getftype('Xfile.bak'))
90036f96a51SYegappan Lakshmanan  call assert_equal('Xfile', resolve('Xfile.bak'))
90136f96a51SYegappan Lakshmanan  set backup& backupcopy& backupext&
90236f96a51SYegappan Lakshmanan  close
90336f96a51SYegappan Lakshmanan
90436f96a51SYegappan Lakshmanan  call delete('Xfile')
90536f96a51SYegappan Lakshmanan  call delete('Xfile.bak')
90636f96a51SYegappan Lakshmananendfunc
90736f96a51SYegappan Lakshmanan
90846aa6f93SYegappan Lakshmanan" Test for ':write ++bin' and ':write ++nobin'
90946aa6f93SYegappan Lakshmananfunc Test_write_binary_file()
91046aa6f93SYegappan Lakshmanan  " create a file without an eol/eof character
91146aa6f93SYegappan Lakshmanan  call writefile(0z616161, 'Xfile1', 'b')
91246aa6f93SYegappan Lakshmanan  new Xfile1
91346aa6f93SYegappan Lakshmanan  write ++bin Xfile2
91446aa6f93SYegappan Lakshmanan  write ++nobin Xfile3
91546aa6f93SYegappan Lakshmanan  call assert_equal(0z616161, readblob('Xfile2'))
91646aa6f93SYegappan Lakshmanan  if has('win32')
91746aa6f93SYegappan Lakshmanan    call assert_equal(0z6161610D.0A, readblob('Xfile3'))
91846aa6f93SYegappan Lakshmanan  else
91946aa6f93SYegappan Lakshmanan    call assert_equal(0z6161610A, readblob('Xfile3'))
92046aa6f93SYegappan Lakshmanan  endif
92146aa6f93SYegappan Lakshmanan  call delete('Xfile1')
92246aa6f93SYegappan Lakshmanan  call delete('Xfile2')
92346aa6f93SYegappan Lakshmanan  call delete('Xfile3')
92446aa6f93SYegappan Lakshmananendfunc
92546aa6f93SYegappan Lakshmanan
9261174b018SBram Moolenaar" Check that buffer is written before triggering QuitPre
9271174b018SBram Moolenaarfunc Test_wq_quitpre_autocommand()
9281174b018SBram Moolenaar  edit Xsomefile
9291174b018SBram Moolenaar  call setline(1, 'hello')
9301174b018SBram Moolenaar  split
9311174b018SBram Moolenaar  let g:seq = []
9321174b018SBram Moolenaar  augroup Testing
9331174b018SBram Moolenaar    au QuitPre * call add(g:seq, 'QuitPre - ' .. (&modified ? 'modified' : 'not modified'))
9341174b018SBram Moolenaar    au BufWritePost * call add(g:seq, 'written')
9351174b018SBram Moolenaar  augroup END
9361174b018SBram Moolenaar  wq
9371174b018SBram Moolenaar  call assert_equal(['written', 'QuitPre - not modified'], g:seq)
9381174b018SBram Moolenaar
9391174b018SBram Moolenaar  augroup Testing
9401174b018SBram Moolenaar    au!
9411174b018SBram Moolenaar  augroup END
9421174b018SBram Moolenaar  bwipe!
9431174b018SBram Moolenaar  unlet g:seq
9441174b018SBram Moolenaar  call delete('Xsomefile')
9451174b018SBram Moolenaarendfunc
9461174b018SBram Moolenaar
9475d98dc2aSBram Moolenaar" vim: shiftwidth=2 sts=2 expandtab
948