1" Tests for the writefile() function and some :write commands. 2 3source check.vim 4source term_util.vim 5 6func Test_writefile() 7 let f = tempname() 8 call writefile(["over","written"], f, "b") 9 call writefile(["hello","world"], f, "b") 10 call writefile(["!", "good"], f, "a") 11 call writefile(["morning"], f, "ab") 12 call writefile(["", "vimmers"], f, "ab") 13 let l = readfile(f) 14 call assert_equal("hello", l[0]) 15 call assert_equal("world!", l[1]) 16 call assert_equal("good", l[2]) 17 call assert_equal("morning", l[3]) 18 call assert_equal("vimmers", l[4]) 19 call delete(f) 20 21 call assert_fails('call writefile("text", "Xfile")', 'E475: Invalid argument: writefile() first argument must be a List or a Blob') 22endfunc 23 24func Test_writefile_ignore_regexp_error() 25 write Xt[z-a]est.txt 26 call delete('Xt[z-a]est.txt') 27endfunc 28 29func Test_writefile_fails_gently() 30 call assert_fails('call writefile(["test"], "Xfile", [])', 'E730:') 31 call assert_false(filereadable("Xfile")) 32 call delete("Xfile") 33 34 call assert_fails('call writefile(["test", [], [], [], "tset"], "Xfile")', 'E730:') 35 call assert_false(filereadable("Xfile")) 36 call delete("Xfile") 37 38 call assert_fails('call writefile([], "Xfile", [])', 'E730:') 39 call assert_false(filereadable("Xfile")) 40 call delete("Xfile") 41 42 call assert_fails('call writefile([], [])', 'E730:') 43endfunc 44 45func Test_writefile_fails_conversion() 46 if !has('iconv') || has('sun') 47 return 48 endif 49 " Without a backup file the write won't happen if there is a conversion 50 " error. 51 set nobackup nowritebackup backupdir=. backupskip= 52 new 53 let contents = ["line one", "line two"] 54 call writefile(contents, 'Xfile') 55 edit Xfile 56 call setline(1, ["first line", "cannot convert \u010b", "third line"]) 57 call assert_fails('write ++enc=cp932', 'E513:') 58 call assert_equal(contents, readfile('Xfile')) 59 60 call delete('Xfile') 61 bwipe! 62 set backup& writebackup& backupdir&vim backupskip&vim 63endfunc 64 65func Test_writefile_fails_conversion2() 66 if !has('iconv') || has('sun') 67 return 68 endif 69 " With a backup file the write happens even if there is a conversion error, 70 " but then the backup file must remain 71 set nobackup writebackup backupdir=. backupskip= 72 let contents = ["line one", "line two"] 73 call writefile(contents, 'Xfile_conversion_err') 74 edit Xfile_conversion_err 75 call setline(1, ["first line", "cannot convert \u010b", "third line"]) 76 set fileencoding=latin1 77 let output = execute('write') 78 call assert_match('CONVERSION ERROR', output) 79 call assert_equal(contents, readfile('Xfile_conversion_err~')) 80 81 call delete('Xfile_conversion_err') 82 call delete('Xfile_conversion_err~') 83 bwipe! 84 set backup& writebackup& backupdir&vim backupskip&vim 85endfunc 86 87func SetFlag(timer) 88 let g:flag = 1 89endfunc 90 91func Test_write_quit_split() 92 " Prevent exiting by splitting window on file write. 93 augroup testgroup 94 autocmd BufWritePre * split 95 augroup END 96 e! Xfile 97 call setline(1, 'nothing') 98 wq 99 100 if has('timers') 101 " timer will not run if "exiting" is still set 102 let g:flag = 0 103 call timer_start(1, 'SetFlag') 104 sleep 50m 105 call assert_equal(1, g:flag) 106 unlet g:flag 107 endif 108 au! testgroup 109 bwipe Xfile 110 call delete('Xfile') 111endfunc 112 113func Test_nowrite_quit_split() 114 " Prevent exiting by opening a help window. 115 e! Xfile 116 help 117 wincmd w 118 exe winnr() . 'q' 119 120 if has('timers') 121 " timer will not run if "exiting" is still set 122 let g:flag = 0 123 call timer_start(1, 'SetFlag') 124 sleep 50m 125 call assert_equal(1, g:flag) 126 unlet g:flag 127 endif 128 bwipe Xfile 129endfunc 130 131func Test_writefile_sync_arg() 132 " This doesn't check if fsync() works, only that the argument is accepted. 133 call writefile(['one'], 'Xtest', 's') 134 call writefile(['two'], 'Xtest', 'S') 135 call delete('Xtest') 136endfunc 137 138func Test_writefile_sync_dev_stdout() 139 if !has('unix') 140 return 141 endif 142 if filewritable('/dev/stdout') 143 " Just check that this doesn't cause an error. 144 call writefile(['one'], '/dev/stdout') 145 else 146 throw 'Skipped: /dev/stdout is not writable' 147 endif 148endfunc 149 150func Test_writefile_autowrite() 151 set autowrite 152 new 153 next Xa Xb Xc 154 call setline(1, 'aaa') 155 next 156 call assert_equal(['aaa'], readfile('Xa')) 157 call setline(1, 'bbb') 158 call assert_fails('edit XX') 159 call assert_false(filereadable('Xb')) 160 161 set autowriteall 162 edit XX 163 call assert_equal(['bbb'], readfile('Xb')) 164 165 bwipe! 166 call delete('Xa') 167 call delete('Xb') 168 set noautowrite 169endfunc 170 171func Test_writefile_autowrite_nowrite() 172 set autowrite 173 new 174 next Xa Xb Xc 175 set buftype=nowrite 176 call setline(1, 'aaa') 177 let buf = bufnr('%') 178 " buffer contents silently lost 179 edit XX 180 call assert_false(filereadable('Xa')) 181 rewind 182 call assert_equal('', getline(1)) 183 184 bwipe! 185 set noautowrite 186endfunc 187 188" Test for ':w !<cmd>' to pipe lines from the current buffer to an external 189" command. 190func Test_write_pipe_to_cmd() 191 CheckUnix 192 new 193 call setline(1, ['L1', 'L2', 'L3', 'L4']) 194 2,3w !cat > Xfile 195 call assert_equal(['L2', 'L3'], readfile('Xfile')) 196 close! 197 call delete('Xfile') 198endfunc 199 200" Test for :saveas 201func Test_saveas() 202 call assert_fails('saveas', 'E471:') 203 call writefile(['L1'], 'Xfile') 204 new Xfile 205 new 206 call setline(1, ['L1']) 207 call assert_fails('saveas Xfile', 'E139:') 208 close! 209 enew | only 210 call delete('Xfile') 211endfunc 212 213func Test_write_errors() 214 " Test for writing partial buffer 215 call writefile(['L1', 'L2', 'L3'], 'Xfile') 216 new Xfile 217 call assert_fails('1,2write', 'E140:') 218 close! 219 220 call assert_fails('w > Xtest', 'E494:') 221 222 " Try to overwrite a directory 223 if has('unix') 224 call mkdir('Xdir1') 225 call assert_fails('write Xdir1', 'E17:') 226 call delete('Xdir1', 'd') 227 endif 228 229 " Test for :wall for a buffer with no name 230 enew | only 231 call setline(1, ['L1']) 232 call assert_fails('wall', 'E141:') 233 enew! 234 235 " Test for writing a 'readonly' file 236 new Xfile 237 set readonly 238 call assert_fails('write', 'E45:') 239 close 240 241 " Test for writing to a read-only file 242 new Xfile 243 call setfperm('Xfile', 'r--r--r--') 244 call assert_fails('write', 'E505:') 245 call setfperm('Xfile', 'rw-rw-rw-') 246 close 247 248 call delete('Xfile') 249 250 call writefile(test_null_list(), 'Xfile') 251 call assert_false(filereadable('Xfile')) 252 call writefile(test_null_blob(), 'Xfile') 253 call assert_false(filereadable('Xfile')) 254 call assert_fails('call writefile([], "")', 'E482:') 255 256 " very long file name 257 let long_fname = repeat('n', 5000) 258 call assert_fails('exe "w " .. long_fname', 'E75:') 259 call assert_fails('call writefile([], long_fname)', 'E482:') 260endfunc 261 262" Test for writing to a file which is modified after Vim read it 263func Test_write_file_mtime() 264 CheckEnglish 265 CheckRunVimInTerminal 266 267 " First read the file into a buffer 268 call writefile(["Line1", "Line2"], 'Xfile') 269 let old_ftime = getftime('Xfile') 270 let buf = RunVimInTerminal('Xfile', #{rows : 10}) 271 call term_wait(buf) 272 call term_sendkeys(buf, ":set noswapfile\<CR>") 273 call term_wait(buf) 274 275 " Modify the file directly. Make sure the file modification time is 276 " different. Note that on Linux/Unix, the file is considered modified 277 " outside, only if the difference is 2 seconds or more 278 sleep 1 279 call writefile(["Line3", "Line4"], 'Xfile') 280 let new_ftime = getftime('Xfile') 281 while new_ftime - old_ftime < 2 282 sleep 100m 283 call writefile(["Line3", "Line4"], 'Xfile') 284 let new_ftime = getftime('Xfile') 285 endwhile 286 287 " Try to overwrite the file and check for the prompt 288 call term_sendkeys(buf, ":w\<CR>") 289 call term_wait(buf) 290 call WaitForAssert({-> assert_equal("WARNING: The file has been changed since reading it!!!", term_getline(buf, 9))}) 291 call assert_equal("Do you really want to write to it (y/n)?", 292 \ term_getline(buf, 10)) 293 call term_sendkeys(buf, "n\<CR>") 294 call term_wait(buf) 295 call assert_equal(new_ftime, getftime('Xfile')) 296 call term_sendkeys(buf, ":w\<CR>") 297 call term_wait(buf) 298 call term_sendkeys(buf, "y\<CR>") 299 call term_wait(buf) 300 call WaitForAssert({-> assert_equal('Line2', readfile('Xfile')[1])}) 301 302 " clean up 303 call StopVimInTerminal(buf) 304 call delete('Xfile') 305endfunc 306 307" Test for an autocmd unloading a buffer during a write command 308func Test_write_autocmd_unloadbuf_lockmark() 309 augroup WriteTest 310 autocmd BufWritePre Xfile enew | write 311 augroup END 312 e Xfile 313 call assert_fails('lockmarks write', 'E203:') 314 augroup WriteTest 315 au! 316 augroup END 317 augroup! WriteTest 318endfunc 319 320" Test for writing a buffer with 'acwrite' but without autocmds 321func Test_write_acwrite_error() 322 new Xfile 323 call setline(1, ['line1', 'line2', 'line3']) 324 set buftype=acwrite 325 call assert_fails('write', 'E676:') 326 call assert_fails('1,2write!', 'E676:') 327 call assert_fails('w >>', 'E676:') 328 close! 329endfunc 330 331" Test for adding and removing lines from an autocmd when writing a buffer 332func Test_write_autocmd_add_remove_lines() 333 new Xfile 334 call setline(1, ['aaa', 'bbb', 'ccc', 'ddd']) 335 336 " Autocmd deleting lines from the file when writing a partial file 337 augroup WriteTest2 338 au! 339 autocmd FileWritePre Xfile 1,2d 340 augroup END 341 call assert_fails('2,3w!', 'E204:') 342 343 " Autocmd adding lines to a file when writing a partial file 344 augroup WriteTest2 345 au! 346 autocmd FileWritePre Xfile call append(0, ['xxx', 'yyy']) 347 augroup END 348 %d 349 call setline(1, ['aaa', 'bbb', 'ccc', 'ddd']) 350 1,2w! 351 call assert_equal(['xxx', 'yyy', 'aaa', 'bbb'], readfile('Xfile')) 352 353 " Autocmd deleting lines from the file when writing the whole file 354 augroup WriteTest2 355 au! 356 autocmd BufWritePre Xfile 1,2d 357 augroup END 358 %d 359 call setline(1, ['aaa', 'bbb', 'ccc', 'ddd']) 360 w 361 call assert_equal(['ccc', 'ddd'], readfile('Xfile')) 362 363 augroup WriteTest2 364 au! 365 augroup END 366 augroup! WriteTest2 367 368 close! 369 call delete('Xfile') 370endfunc 371 372" Test for writing to a readonly file 373func Test_write_readonly() 374 " In Cirrus-CI, the freebsd tests are run under a root account. So this test 375 " doesn't fail. 376 CheckNotBSD 377 call writefile([], 'Xfile') 378 call setfperm('Xfile', "r--------") 379 edit Xfile 380 set noreadonly 381 call assert_fails('write', 'E505:') 382 let save_cpo = &cpo 383 set cpo+=W 384 call assert_fails('write!', 'E504:') 385 let &cpo = save_cpo 386 call delete('Xfile') 387endfunc 388 389" vim: shiftwidth=2 sts=2 expandtab 390