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