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