1" Tests for the swap feature 2 3source check.vim 4source shared.vim 5source term_util.vim 6 7func s:swapname() 8 return trim(execute('swapname')) 9endfunc 10 11" Tests for 'directory' option. 12func Test_swap_directory() 13 if !has("unix") 14 return 15 endif 16 let content = ['start of testfile', 17 \ 'line 2 Abcdefghij', 18 \ 'line 3 Abcdefghij', 19 \ 'end of testfile'] 20 call writefile(content, 'Xtest1') 21 22 " '.', swap file in the same directory as file 23 set dir=.,~ 24 25 " Verify that the swap file doesn't exist in the current directory 26 call assert_equal([], glob(".Xtest1*.swp", 1, 1, 1)) 27 edit Xtest1 28 let swfname = s:swapname() 29 call assert_equal([swfname], glob(swfname, 1, 1, 1)) 30 31 " './dir', swap file in a directory relative to the file 32 set dir=./Xtest2,.,~ 33 34 call mkdir("Xtest2") 35 edit Xtest1 36 call assert_equal([], glob(swfname, 1, 1, 1)) 37 let swfname = "Xtest2/Xtest1.swp" 38 call assert_equal(swfname, s:swapname()) 39 call assert_equal([swfname], glob("Xtest2/*", 1, 1, 1)) 40 41 " 'dir', swap file in directory relative to the current dir 42 set dir=Xtest.je,~ 43 44 call mkdir("Xtest.je") 45 call writefile(content, 'Xtest2/Xtest3') 46 edit Xtest2/Xtest3 47 call assert_equal(["Xtest2/Xtest3"], glob("Xtest2/*", 1, 1, 1)) 48 let swfname = "Xtest.je/Xtest3.swp" 49 call assert_equal(swfname, s:swapname()) 50 call assert_equal([swfname], glob("Xtest.je/*", 1, 1, 1)) 51 52 set dir& 53 call delete("Xtest1") 54 call delete("Xtest2", "rf") 55 call delete("Xtest.je", "rf") 56endfunc 57 58func Test_swap_group() 59 if !has("unix") 60 return 61 endif 62 let groups = split(system('groups')) 63 if len(groups) <= 1 64 throw 'Skipped: need at least two groups, got ' . string(groups) 65 endif 66 67 try 68 call delete('Xtest') 69 split Xtest 70 call setline(1, 'just some text') 71 wq 72 if system('ls -l Xtest') !~ ' ' . groups[0] . ' \d' 73 throw 'Skipped: test file does not have the first group' 74 else 75 silent !chmod 640 Xtest 76 call system('chgrp ' . groups[1] . ' Xtest') 77 if system('ls -l Xtest') !~ ' ' . groups[1] . ' \d' 78 throw 'Skipped: cannot set second group on test file' 79 else 80 split Xtest 81 let swapname = s:swapname() 82 call assert_match('Xtest', swapname) 83 " Group of swapfile must now match original file. 84 call assert_match(' ' . groups[1] . ' \d', system('ls -l ' . swapname)) 85 86 bwipe! 87 endif 88 endif 89 finally 90 call delete('Xtest') 91 endtry 92endfunc 93 94func Test_missing_dir() 95 call mkdir('Xswapdir') 96 exe 'set directory=' . getcwd() . '/Xswapdir' 97 98 call assert_equal('', glob('foo')) 99 call assert_equal('', glob('bar')) 100 edit foo/x.txt 101 " This should not give a warning for an existing swap file. 102 split bar/x.txt 103 only 104 105 " Delete the buffer so that swap file is removed before we try to delete the 106 " directory. That fails on MS-Windows. 107 %bdelete! 108 set directory& 109 call delete('Xswapdir', 'rf') 110endfunc 111 112func Test_swapinfo() 113 new Xswapinfo 114 call setline(1, ['one', 'two', 'three']) 115 w 116 let fname = s:swapname() 117 call assert_match('Xswapinfo', fname) 118 let info = fname->swapinfo() 119 120 let ver = printf('VIM %d.%d', v:version / 100, v:version % 100) 121 call assert_equal(ver, info.version) 122 123 call assert_match('\w', info.user) 124 " host name is truncated to 39 bytes in the swap file 125 call assert_equal(hostname()[:38], info.host) 126 call assert_match('Xswapinfo', info.fname) 127 call assert_match(0, info.dirty) 128 call assert_equal(getpid(), info.pid) 129 call assert_match('^\d*$', info.mtime) 130 if has_key(info, 'inode') 131 call assert_match('\d', info.inode) 132 endif 133 bwipe! 134 call delete(fname) 135 call delete('Xswapinfo') 136 137 let info = swapinfo('doesnotexist') 138 call assert_equal('Cannot open file', info.error) 139 140 call writefile(['burp'], 'Xnotaswapfile') 141 let info = swapinfo('Xnotaswapfile') 142 call assert_equal('Cannot read file', info.error) 143 call delete('Xnotaswapfile') 144 145 call writefile([repeat('x', 10000)], 'Xnotaswapfile') 146 let info = swapinfo('Xnotaswapfile') 147 call assert_equal('Not a swap file', info.error) 148 call delete('Xnotaswapfile') 149endfunc 150 151func Test_swapname() 152 edit Xtest1 153 let expected = s:swapname() 154 call assert_equal(expected, swapname('%')) 155 156 new Xtest2 157 let buf = bufnr('%') 158 let expected = s:swapname() 159 wincmd p 160 call assert_equal(expected, buf->swapname()) 161 162 new Xtest3 163 setlocal noswapfile 164 call assert_equal('', swapname('%')) 165 166 bwipe! 167 call delete('Xtest1') 168 call delete('Xtest2') 169 call delete('Xtest3') 170endfunc 171 172func Test_swapfile_delete() 173 autocmd! SwapExists 174 function s:swap_exists() 175 let v:swapchoice = s:swap_choice 176 let s:swapname = v:swapname 177 let s:filename = expand('<afile>') 178 endfunc 179 augroup test_swapfile_delete 180 autocmd! 181 autocmd SwapExists * call s:swap_exists() 182 augroup END 183 184 185 " Create a valid swapfile by editing a file. 186 split XswapfileText 187 call setline(1, ['one', 'two', 'three']) 188 write " file is written, not modified 189 " read the swapfile as a Blob 190 let swapfile_name = swapname('%') 191 let swapfile_bytes = readfile(swapfile_name, 'B') 192 193 " Close the file and recreate the swap file. 194 " Now editing the file will run into the process still existing 195 quit 196 call writefile(swapfile_bytes, swapfile_name) 197 let s:swap_choice = 'e' 198 let s:swapname = '' 199 split XswapfileText 200 quit 201 call assert_equal(fnamemodify(swapfile_name, ':t'), fnamemodify(s:swapname, ':t')) 202 203 " This test won't work as root because root can successfully run kill(1, 0) 204 if !IsRoot() 205 " Write the swapfile with a modified PID, now it will be automatically 206 " deleted. Process one should never be Vim. 207 let swapfile_bytes[24:27] = 0z01000000 208 call writefile(swapfile_bytes, swapfile_name) 209 let s:swapname = '' 210 split XswapfileText 211 quit 212 call assert_equal('', s:swapname) 213 endif 214 215 " Now set the modified flag, the swap file will not be deleted 216 let swapfile_bytes[28 + 80 + 899] = 0x55 217 call writefile(swapfile_bytes, swapfile_name) 218 let s:swapname = '' 219 split XswapfileText 220 quit 221 call assert_equal(fnamemodify(swapfile_name, ':t'), fnamemodify(s:swapname, ':t')) 222 223 call delete('XswapfileText') 224 call delete(swapfile_name) 225 augroup test_swapfile_delete 226 autocmd! 227 augroup END 228 augroup! test_swapfile_delete 229endfunc 230 231func Test_swap_recover() 232 autocmd! SwapExists 233 augroup test_swap_recover 234 autocmd! 235 autocmd SwapExists * let v:swapchoice = 'r' 236 augroup END 237 238 239 call mkdir('Xswap') 240 let $Xswap = 'foo' " Check for issue #4369. 241 set dir=Xswap// 242 " Create a valid swapfile by editing a file. 243 split Xswap/text 244 call setline(1, ['one', 'two', 'three']) 245 write " file is written, not modified 246 " read the swapfile as a Blob 247 let swapfile_name = swapname('%') 248 let swapfile_bytes = readfile(swapfile_name, 'B') 249 250 " Close the file and recreate the swap file. 251 quit 252 call writefile(swapfile_bytes, swapfile_name) 253 " Edit the file again. This triggers recovery. 254 try 255 split Xswap/text 256 catch 257 " E308 should be caught, not E305. 258 call assert_exception('E308:') " Original file may have been changed 259 endtry 260 " The file should be recovered. 261 call assert_equal(['one', 'two', 'three'], getline(1, 3)) 262 quit! 263 264 call delete('Xswap/text') 265 call delete(swapfile_name) 266 call delete('Xswap', 'd') 267 unlet $Xswap 268 set dir& 269 augroup test_swap_recover 270 autocmd! 271 augroup END 272 augroup! test_swap_recover 273endfunc 274 275func Test_swap_recover_ext() 276 autocmd! SwapExists 277 augroup test_swap_recover_ext 278 autocmd! 279 autocmd SwapExists * let v:swapchoice = 'r' 280 augroup END 281 282 " Create a valid swapfile by editing a file with a special extension. 283 split Xtest.scr 284 call setline(1, ['one', 'two', 'three']) 285 write " file is written, not modified 286 write " write again to make sure the swapfile is created 287 " read the swapfile as a Blob 288 let swapfile_name = swapname('%') 289 let swapfile_bytes = readfile(swapfile_name, 'B') 290 291 " Close and delete the file and recreate the swap file. 292 quit 293 call delete('Xtest.scr') 294 call writefile(swapfile_bytes, swapfile_name) 295 " Edit the file again. This triggers recovery. 296 try 297 split Xtest.scr 298 catch 299 " E308 should be caught, not E306. 300 call assert_exception('E308:') " Original file may have been changed 301 endtry 302 " The file should be recovered. 303 call assert_equal(['one', 'two', 'three'], getline(1, 3)) 304 quit! 305 306 call delete('Xtest.scr') 307 call delete(swapfile_name) 308 augroup test_swap_recover_ext 309 autocmd! 310 augroup END 311 augroup! test_swap_recover_ext 312endfunc 313 314" Test for closing a split window automatically when a swap file is detected 315" and 'Q' is selected in the confirmation prompt. 316func Test_swap_split_win() 317 autocmd! SwapExists 318 augroup test_swap_splitwin 319 autocmd! 320 autocmd SwapExists * let v:swapchoice = 'q' 321 augroup END 322 323 " Create a valid swapfile by editing a file with a special extension. 324 split Xtest.scr 325 call setline(1, ['one', 'two', 'three']) 326 write " file is written, not modified 327 write " write again to make sure the swapfile is created 328 " read the swapfile as a Blob 329 let swapfile_name = swapname('%') 330 let swapfile_bytes = readfile(swapfile_name, 'B') 331 332 " Close and delete the file and recreate the swap file. 333 quit 334 call delete('Xtest.scr') 335 call writefile(swapfile_bytes, swapfile_name) 336 " Split edit the file again. This should fail to open the window 337 try 338 split Xtest.scr 339 catch 340 " E308 should be caught, not E306. 341 call assert_exception('E308:') " Original file may have been changed 342 endtry 343 call assert_equal(1, winnr('$')) 344 345 call delete('Xtest.scr') 346 call delete(swapfile_name) 347 348 augroup test_swap_splitwin 349 autocmd! 350 augroup END 351 augroup! test_swap_splitwin 352endfunc 353 354" Test for selecting 'q' in the attention prompt 355func Test_swap_prompt_splitwin() 356 CheckRunVimInTerminal 357 358 call writefile(['foo bar'], 'Xfile1') 359 edit Xfile1 360 preserve " should help to make sure the swap file exists 361 362 let buf = RunVimInTerminal('', {'rows': 20}) 363 call term_sendkeys(buf, ":set nomore\n") 364 call term_sendkeys(buf, ":set noruler\n") 365 call term_sendkeys(buf, ":split Xfile1\n") 366 call TermWait(buf) 367 call WaitForAssert({-> assert_match('^\[O\]pen Read-Only, (E)dit anyway, (R)ecover, (Q)uit, (A)bort: $', term_getline(buf, 20))}) 368 call term_sendkeys(buf, "q") 369 call TermWait(buf) 370 call term_sendkeys(buf, ":\<CR>") 371 call WaitForAssert({-> assert_match('^:$', term_getline(buf, 20))}) 372 call term_sendkeys(buf, ":echomsg winnr('$')\<CR>") 373 call TermWait(buf) 374 call WaitForAssert({-> assert_match('^1$', term_getline(buf, 20))}) 375 call StopVimInTerminal(buf) 376 %bwipe! 377 call delete('Xfile1') 378endfunc 379 380func Test_swap_symlink() 381 if !has("unix") 382 return 383 endif 384 385 call writefile(['text'], 'Xtestfile') 386 silent !ln -s -f Xtestfile Xtestlink 387 388 set dir=. 389 390 " Test that swap file uses the name of the file when editing through a 391 " symbolic link (so that editing the file twice is detected) 392 edit Xtestlink 393 call assert_match('Xtestfile\.swp$', s:swapname()) 394 bwipe! 395 396 call mkdir('Xswapdir') 397 exe 'set dir=' . getcwd() . '/Xswapdir//' 398 399 " Check that this also works when 'directory' ends with '//' 400 edit Xtestlink 401 call assert_match('Xtestfile\.swp$', s:swapname()) 402 bwipe! 403 404 set dir& 405 call delete('Xtestfile') 406 call delete('Xtestlink') 407 call delete('Xswapdir', 'rf') 408endfunc 409 410" vim: shiftwidth=2 sts=2 expandtab 411