blob: 7889d4b480b01cf940bce9a892963f6cfae7b681 [file] [log] [blame]
Bram Moolenaar430dc5d2017-11-02 21:04:47 +01001" Tests for the swap feature
2
Bram Moolenaard36ef572020-03-24 21:44:51 +01003source check.vim
Bram Moolenaar07282f02019-10-10 16:46:17 +02004source shared.vim
Bram Moolenaarb6541032020-02-22 21:21:27 +01005source term_util.vim
Bram Moolenaar07282f02019-10-10 16:46:17 +02006
Bram Moolenaar110bd602018-09-16 18:46:59 +02007func s:swapname()
8 return trim(execute('swapname'))
9endfunc
10
Bram Moolenaarffe010f2017-11-04 22:30:40 +010011" 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
Bram Moolenaar110bd602018-09-16 18:46:59 +020028 let swfname = s:swapname()
Bram Moolenaarffe010f2017-11-04 22:30:40 +010029 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"
Bram Moolenaar110bd602018-09-16 18:46:59 +020038 call assert_equal(swfname, s:swapname())
Bram Moolenaarffe010f2017-11-04 22:30:40 +010039 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"
Bram Moolenaar110bd602018-09-16 18:46:59 +020049 call assert_equal(swfname, s:swapname())
Bram Moolenaarffe010f2017-11-04 22:30:40 +010050 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
Bram Moolenaar5a73e0c2017-11-04 21:35:01 +010057
58func Test_swap_group()
Bram Moolenaar430dc5d2017-11-02 21:04:47 +010059 if !has("unix")
60 return
61 endif
Bram Moolenaar5a73e0c2017-11-04 21:35:01 +010062 let groups = split(system('groups'))
63 if len(groups) <= 1
Bram Moolenaarad7dac82017-11-04 22:21:21 +010064 throw 'Skipped: need at least two groups, got ' . string(groups)
Bram Moolenaar5a73e0c2017-11-04 21:35:01 +010065 endif
Bram Moolenaar430dc5d2017-11-02 21:04:47 +010066
Bram Moolenaar5842a742017-11-04 22:36:53 +010067 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'
Bram Moolenaar5a73e0c2017-11-04 21:35:01 +010074 else
Bram Moolenaar5842a742017-11-04 22:36:53 +010075 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
Bram Moolenaar110bd602018-09-16 18:46:59 +020081 let swapname = s:swapname()
Bram Moolenaar5842a742017-11-04 22:36:53 +010082 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))
Bram Moolenaar430dc5d2017-11-02 21:04:47 +010085
Bram Moolenaar5842a742017-11-04 22:36:53 +010086 bwipe!
87 endif
Bram Moolenaar5a73e0c2017-11-04 21:35:01 +010088 endif
Bram Moolenaar5842a742017-11-04 22:36:53 +010089 finally
90 call delete('Xtest')
91 endtry
Bram Moolenaar430dc5d2017-11-02 21:04:47 +010092endfunc
Bram Moolenaar8c3169c2018-05-12 17:04:12 +020093
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
Bram Moolenaare3d06542019-01-27 14:29:24 +0100105 " Delete the buffer so that swap file is removed before we try to delete the
106 " directory. That fails on MS-Windows.
107 %bdelete!
Bram Moolenaar8c3169c2018-05-12 17:04:12 +0200108 set directory&
109 call delete('Xswapdir', 'rf')
110endfunc
Bram Moolenaar00f123a2018-08-21 20:28:54 +0200111
112func Test_swapinfo()
113 new Xswapinfo
114 call setline(1, ['one', 'two', 'three'])
115 w
Bram Moolenaar110bd602018-09-16 18:46:59 +0200116 let fname = s:swapname()
Bram Moolenaar00f123a2018-08-21 20:28:54 +0200117 call assert_match('Xswapinfo', fname)
Bram Moolenaarf6ed61e2019-09-07 19:05:09 +0200118 let info = fname->swapinfo()
Bram Moolenaar4c5765b2018-08-22 11:28:01 +0200119
120 let ver = printf('VIM %d.%d', v:version / 100, v:version % 100)
121 call assert_equal(ver, info.version)
122
Bram Moolenaar00f123a2018-08-21 20:28:54 +0200123 call assert_match('\w', info.user)
Bram Moolenaar4c5765b2018-08-22 11:28:01 +0200124 " host name is truncated to 39 bytes in the swap file
125 call assert_equal(hostname()[:38], info.host)
Bram Moolenaar00f123a2018-08-21 20:28:54 +0200126 call assert_match('Xswapinfo', info.fname)
Bram Moolenaar47ad5652018-08-21 21:09:07 +0200127 call assert_match(0, info.dirty)
Bram Moolenaar00f123a2018-08-21 20:28:54 +0200128 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')
Bram Moolenaar47ad5652018-08-21 21:09:07 +0200147 call assert_equal('Not a swap file', info.error)
Bram Moolenaar00f123a2018-08-21 20:28:54 +0200148 call delete('Xnotaswapfile')
149endfunc
Bram Moolenaar110bd602018-09-16 18:46:59 +0200150
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
Bram Moolenaarf6ed61e2019-09-07 19:05:09 +0200160 call assert_equal(expected, buf->swapname())
Bram Moolenaar110bd602018-09-16 18:46:59 +0200161
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
Bram Moolenaar67cf86b2019-04-28 22:25:38 +0200171
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
Bram Moolenaar701df4e2019-04-28 23:07:18 +0200201 call assert_equal(fnamemodify(swapfile_name, ':t'), fnamemodify(s:swapname, ':t'))
Bram Moolenaar67cf86b2019-04-28 22:25:38 +0200202
Bram Moolenaar07282f02019-10-10 16:46:17 +0200203 " 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
Bram Moolenaar67cf86b2019-04-28 22:25:38 +0200214
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
Bram Moolenaar701df4e2019-04-28 23:07:18 +0200221 call assert_equal(fnamemodify(swapfile_name, ':t'), fnamemodify(s:swapname, ':t'))
Bram Moolenaar67cf86b2019-04-28 22:25:38 +0200222
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
Bram Moolenaar99499b12019-05-23 21:35:48 +0200230
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
Bram Moolenaar99499b12019-05-23 21:35:48 +0200282 " 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
Bram Moolenaar406cd902020-02-18 21:54:41 +0100313
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
Bram Moolenaarb6541032020-02-22 21:21:27 +0100354" Test for selecting 'q' in the attention prompt
355func Test_swap_prompt_splitwin()
Bram Moolenaard36ef572020-03-24 21:44:51 +0100356 CheckRunVimInTerminal
357
Bram Moolenaarb6541032020-02-22 21:21:27 +0100358 call writefile(['foo bar'], 'Xfile1')
359 edit Xfile1
Bram Moolenaard36ef572020-03-24 21:44:51 +0100360 preserve " should help to make sure the swap file exists
361
Bram Moolenaarb6541032020-02-22 21:21:27 +0100362 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")
Bram Moolenaar6a2c5a72020-04-08 21:50:25 +0200366 call TermWait(buf)
Bram Moolenaarb6541032020-02-22 21:21:27 +0100367 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")
Bram Moolenaar6a2c5a72020-04-08 21:50:25 +0200369 call TermWait(buf)
Bram Moolenaard36ef572020-03-24 21:44:51 +0100370 call term_sendkeys(buf, ":\<CR>")
Bram Moolenaarb6541032020-02-22 21:21:27 +0100371 call WaitForAssert({-> assert_match('^:$', term_getline(buf, 20))})
Bram Moolenaard36ef572020-03-24 21:44:51 +0100372 call term_sendkeys(buf, ":echomsg winnr('$')\<CR>")
Bram Moolenaar6a2c5a72020-04-08 21:50:25 +0200373 call TermWait(buf)
Bram Moolenaarb6541032020-02-22 21:21:27 +0100374 call WaitForAssert({-> assert_match('^1$', term_getline(buf, 20))})
375 call StopVimInTerminal(buf)
376 %bwipe!
377 call delete('Xfile1')
378endfunc
379
Bram Moolenaar406cd902020-02-18 21:54:41 +0100380" vim: shiftwidth=2 sts=2 expandtab