blob: aa67b430e6fb02e0f32aaaabc29d4602388fe608 [file] [log] [blame]
Bram Moolenaar430dc5d2017-11-02 21:04:47 +01001" Tests for the swap feature
2
Bram Moolenaar07282f02019-10-10 16:46:17 +02003source shared.vim
4
Bram Moolenaar110bd602018-09-16 18:46:59 +02005func s:swapname()
6 return trim(execute('swapname'))
7endfunc
8
Bram Moolenaarffe010f2017-11-04 22:30:40 +01009" Tests for 'directory' option.
10func Test_swap_directory()
11 if !has("unix")
12 return
13 endif
14 let content = ['start of testfile',
15 \ 'line 2 Abcdefghij',
16 \ 'line 3 Abcdefghij',
17 \ 'end of testfile']
18 call writefile(content, 'Xtest1')
19
20 " '.', swap file in the same directory as file
21 set dir=.,~
22
23 " Verify that the swap file doesn't exist in the current directory
24 call assert_equal([], glob(".Xtest1*.swp", 1, 1, 1))
25 edit Xtest1
Bram Moolenaar110bd602018-09-16 18:46:59 +020026 let swfname = s:swapname()
Bram Moolenaarffe010f2017-11-04 22:30:40 +010027 call assert_equal([swfname], glob(swfname, 1, 1, 1))
28
29 " './dir', swap file in a directory relative to the file
30 set dir=./Xtest2,.,~
31
32 call mkdir("Xtest2")
33 edit Xtest1
34 call assert_equal([], glob(swfname, 1, 1, 1))
35 let swfname = "Xtest2/Xtest1.swp"
Bram Moolenaar110bd602018-09-16 18:46:59 +020036 call assert_equal(swfname, s:swapname())
Bram Moolenaarffe010f2017-11-04 22:30:40 +010037 call assert_equal([swfname], glob("Xtest2/*", 1, 1, 1))
38
39 " 'dir', swap file in directory relative to the current dir
40 set dir=Xtest.je,~
41
42 call mkdir("Xtest.je")
43 call writefile(content, 'Xtest2/Xtest3')
44 edit Xtest2/Xtest3
45 call assert_equal(["Xtest2/Xtest3"], glob("Xtest2/*", 1, 1, 1))
46 let swfname = "Xtest.je/Xtest3.swp"
Bram Moolenaar110bd602018-09-16 18:46:59 +020047 call assert_equal(swfname, s:swapname())
Bram Moolenaarffe010f2017-11-04 22:30:40 +010048 call assert_equal([swfname], glob("Xtest.je/*", 1, 1, 1))
49
50 set dir&
51 call delete("Xtest1")
52 call delete("Xtest2", "rf")
53 call delete("Xtest.je", "rf")
54endfunc
Bram Moolenaar5a73e0c2017-11-04 21:35:01 +010055
56func Test_swap_group()
Bram Moolenaar430dc5d2017-11-02 21:04:47 +010057 if !has("unix")
58 return
59 endif
Bram Moolenaar5a73e0c2017-11-04 21:35:01 +010060 let groups = split(system('groups'))
61 if len(groups) <= 1
Bram Moolenaarad7dac82017-11-04 22:21:21 +010062 throw 'Skipped: need at least two groups, got ' . string(groups)
Bram Moolenaar5a73e0c2017-11-04 21:35:01 +010063 endif
Bram Moolenaar430dc5d2017-11-02 21:04:47 +010064
Bram Moolenaar5842a742017-11-04 22:36:53 +010065 try
66 call delete('Xtest')
67 split Xtest
68 call setline(1, 'just some text')
69 wq
70 if system('ls -l Xtest') !~ ' ' . groups[0] . ' \d'
71 throw 'Skipped: test file does not have the first group'
Bram Moolenaar5a73e0c2017-11-04 21:35:01 +010072 else
Bram Moolenaar5842a742017-11-04 22:36:53 +010073 silent !chmod 640 Xtest
74 call system('chgrp ' . groups[1] . ' Xtest')
75 if system('ls -l Xtest') !~ ' ' . groups[1] . ' \d'
76 throw 'Skipped: cannot set second group on test file'
77 else
78 split Xtest
Bram Moolenaar110bd602018-09-16 18:46:59 +020079 let swapname = s:swapname()
Bram Moolenaar5842a742017-11-04 22:36:53 +010080 call assert_match('Xtest', swapname)
81 " Group of swapfile must now match original file.
82 call assert_match(' ' . groups[1] . ' \d', system('ls -l ' . swapname))
Bram Moolenaar430dc5d2017-11-02 21:04:47 +010083
Bram Moolenaar5842a742017-11-04 22:36:53 +010084 bwipe!
85 endif
Bram Moolenaar5a73e0c2017-11-04 21:35:01 +010086 endif
Bram Moolenaar5842a742017-11-04 22:36:53 +010087 finally
88 call delete('Xtest')
89 endtry
Bram Moolenaar430dc5d2017-11-02 21:04:47 +010090endfunc
Bram Moolenaar8c3169c2018-05-12 17:04:12 +020091
92func Test_missing_dir()
93 call mkdir('Xswapdir')
94 exe 'set directory=' . getcwd() . '/Xswapdir'
95
96 call assert_equal('', glob('foo'))
97 call assert_equal('', glob('bar'))
98 edit foo/x.txt
99 " This should not give a warning for an existing swap file.
100 split bar/x.txt
101 only
102
Bram Moolenaare3d06542019-01-27 14:29:24 +0100103 " Delete the buffer so that swap file is removed before we try to delete the
104 " directory. That fails on MS-Windows.
105 %bdelete!
Bram Moolenaar8c3169c2018-05-12 17:04:12 +0200106 set directory&
107 call delete('Xswapdir', 'rf')
108endfunc
Bram Moolenaar00f123a2018-08-21 20:28:54 +0200109
110func Test_swapinfo()
111 new Xswapinfo
112 call setline(1, ['one', 'two', 'three'])
113 w
Bram Moolenaar110bd602018-09-16 18:46:59 +0200114 let fname = s:swapname()
Bram Moolenaar00f123a2018-08-21 20:28:54 +0200115 call assert_match('Xswapinfo', fname)
Bram Moolenaarf6ed61e2019-09-07 19:05:09 +0200116 let info = fname->swapinfo()
Bram Moolenaar4c5765b2018-08-22 11:28:01 +0200117
118 let ver = printf('VIM %d.%d', v:version / 100, v:version % 100)
119 call assert_equal(ver, info.version)
120
Bram Moolenaar00f123a2018-08-21 20:28:54 +0200121 call assert_match('\w', info.user)
Bram Moolenaar4c5765b2018-08-22 11:28:01 +0200122 " host name is truncated to 39 bytes in the swap file
123 call assert_equal(hostname()[:38], info.host)
Bram Moolenaar00f123a2018-08-21 20:28:54 +0200124 call assert_match('Xswapinfo', info.fname)
Bram Moolenaar47ad5652018-08-21 21:09:07 +0200125 call assert_match(0, info.dirty)
Bram Moolenaar00f123a2018-08-21 20:28:54 +0200126 call assert_equal(getpid(), info.pid)
127 call assert_match('^\d*$', info.mtime)
128 if has_key(info, 'inode')
129 call assert_match('\d', info.inode)
130 endif
131 bwipe!
132 call delete(fname)
133 call delete('Xswapinfo')
134
135 let info = swapinfo('doesnotexist')
136 call assert_equal('Cannot open file', info.error)
137
138 call writefile(['burp'], 'Xnotaswapfile')
139 let info = swapinfo('Xnotaswapfile')
140 call assert_equal('Cannot read file', info.error)
141 call delete('Xnotaswapfile')
142
143 call writefile([repeat('x', 10000)], 'Xnotaswapfile')
144 let info = swapinfo('Xnotaswapfile')
Bram Moolenaar47ad5652018-08-21 21:09:07 +0200145 call assert_equal('Not a swap file', info.error)
Bram Moolenaar00f123a2018-08-21 20:28:54 +0200146 call delete('Xnotaswapfile')
147endfunc
Bram Moolenaar110bd602018-09-16 18:46:59 +0200148
149func Test_swapname()
150 edit Xtest1
151 let expected = s:swapname()
152 call assert_equal(expected, swapname('%'))
153
154 new Xtest2
155 let buf = bufnr('%')
156 let expected = s:swapname()
157 wincmd p
Bram Moolenaarf6ed61e2019-09-07 19:05:09 +0200158 call assert_equal(expected, buf->swapname())
Bram Moolenaar110bd602018-09-16 18:46:59 +0200159
160 new Xtest3
161 setlocal noswapfile
162 call assert_equal('', swapname('%'))
163
164 bwipe!
165 call delete('Xtest1')
166 call delete('Xtest2')
167 call delete('Xtest3')
168endfunc
Bram Moolenaar67cf86b2019-04-28 22:25:38 +0200169
170func Test_swapfile_delete()
171 autocmd! SwapExists
172 function s:swap_exists()
173 let v:swapchoice = s:swap_choice
174 let s:swapname = v:swapname
175 let s:filename = expand('<afile>')
176 endfunc
177 augroup test_swapfile_delete
178 autocmd!
179 autocmd SwapExists * call s:swap_exists()
180 augroup END
181
182
183 " Create a valid swapfile by editing a file.
184 split XswapfileText
185 call setline(1, ['one', 'two', 'three'])
186 write " file is written, not modified
187 " read the swapfile as a Blob
188 let swapfile_name = swapname('%')
189 let swapfile_bytes = readfile(swapfile_name, 'B')
190
191 " Close the file and recreate the swap file.
192 " Now editing the file will run into the process still existing
193 quit
194 call writefile(swapfile_bytes, swapfile_name)
195 let s:swap_choice = 'e'
196 let s:swapname = ''
197 split XswapfileText
198 quit
Bram Moolenaar701df4e2019-04-28 23:07:18 +0200199 call assert_equal(fnamemodify(swapfile_name, ':t'), fnamemodify(s:swapname, ':t'))
Bram Moolenaar67cf86b2019-04-28 22:25:38 +0200200
Bram Moolenaar07282f02019-10-10 16:46:17 +0200201 " This test won't work as root because root can successfully run kill(1, 0)
202 if !IsRoot()
203 " Write the swapfile with a modified PID, now it will be automatically
204 " deleted. Process one should never be Vim.
205 let swapfile_bytes[24:27] = 0z01000000
206 call writefile(swapfile_bytes, swapfile_name)
207 let s:swapname = ''
208 split XswapfileText
209 quit
210 call assert_equal('', s:swapname)
211 endif
Bram Moolenaar67cf86b2019-04-28 22:25:38 +0200212
213 " Now set the modified flag, the swap file will not be deleted
214 let swapfile_bytes[28 + 80 + 899] = 0x55
215 call writefile(swapfile_bytes, swapfile_name)
216 let s:swapname = ''
217 split XswapfileText
218 quit
Bram Moolenaar701df4e2019-04-28 23:07:18 +0200219 call assert_equal(fnamemodify(swapfile_name, ':t'), fnamemodify(s:swapname, ':t'))
Bram Moolenaar67cf86b2019-04-28 22:25:38 +0200220
221 call delete('XswapfileText')
222 call delete(swapfile_name)
223 augroup test_swapfile_delete
224 autocmd!
225 augroup END
226 augroup! test_swapfile_delete
227endfunc
Bram Moolenaar99499b12019-05-23 21:35:48 +0200228
229func Test_swap_recover()
230 autocmd! SwapExists
231 augroup test_swap_recover
232 autocmd!
233 autocmd SwapExists * let v:swapchoice = 'r'
234 augroup END
235
236
237 call mkdir('Xswap')
238 let $Xswap = 'foo' " Check for issue #4369.
239 set dir=Xswap//
240 " Create a valid swapfile by editing a file.
241 split Xswap/text
242 call setline(1, ['one', 'two', 'three'])
243 write " file is written, not modified
244 " read the swapfile as a Blob
245 let swapfile_name = swapname('%')
246 let swapfile_bytes = readfile(swapfile_name, 'B')
247
248 " Close the file and recreate the swap file.
249 quit
250 call writefile(swapfile_bytes, swapfile_name)
251 " Edit the file again. This triggers recovery.
252 try
253 split Xswap/text
254 catch
255 " E308 should be caught, not E305.
256 call assert_exception('E308:') " Original file may have been changed
257 endtry
258 " The file should be recovered.
259 call assert_equal(['one', 'two', 'three'], getline(1, 3))
260 quit!
261
262 call delete('Xswap/text')
263 call delete(swapfile_name)
264 call delete('Xswap', 'd')
265 unlet $Xswap
266 set dir&
267 augroup test_swap_recover
268 autocmd!
269 augroup END
270 augroup! test_swap_recover
271endfunc
272
273func Test_swap_recover_ext()
274 autocmd! SwapExists
275 augroup test_swap_recover_ext
276 autocmd!
277 autocmd SwapExists * let v:swapchoice = 'r'
278 augroup END
279
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