xref: /vim-8.2.3635/src/testdir/test_stat.vim (revision 944eeb44)
1" Tests for stat functions and checktime
2
3source check.vim
4
5func CheckFileTime(doSleep)
6  let fnames = ['Xtest1.tmp', 'Xtest2.tmp', 'Xtest3.tmp']
7  let times = []
8  let result = 0
9
10  " Use three files instead of localtim(), with a network filesystem the file
11  " times may differ at bit
12  let fl = ['Hello World!']
13  for fname in fnames
14    call writefile(fl, fname)
15    call add(times, fname->getftime())
16    if a:doSleep
17      sleep 1
18    endif
19  endfor
20
21  let time_correct = (times[0] <= times[1] && times[1] <= times[2])
22  if a:doSleep || time_correct
23    call assert_true(time_correct, printf('Expected %s <= %s <= %s', times[0], times[1], times[2]))
24    call assert_equal(strlen(fl[0] . "\n"), fnames[0]->getfsize())
25    call assert_equal('file', fnames[0]->getftype())
26    call assert_equal('rw-', getfperm(fnames[0])[0:2])
27    let result = 1
28  endif
29
30  for fname in fnames
31    call delete(fname)
32  endfor
33  return result
34endfunc
35
36func Test_existent_file()
37  " On some systems the file timestamp is rounded to a multiple of 2 seconds.
38  " We need to sleep to handle that, but that makes the test slow.  First try
39  " without the sleep, and if it fails try again with the sleep.
40  if CheckFileTime(0) == 0
41    call CheckFileTime(1)
42  endif
43endfunc
44
45func Test_existent_directory()
46  let dname = '.'
47
48  call assert_equal(0, getfsize(dname))
49  call assert_equal('dir', getftype(dname))
50  call assert_equal('rwx', getfperm(dname)[0:2])
51endfunc
52
53func SleepForTimestamp()
54  " FAT has a granularity of 2 seconds, otherwise it's usually 1 second
55  if has('win32')
56    sleep 2
57  else
58    sleep 1
59  endif
60endfunc
61
62func Test_checktime()
63  let fname = 'Xtest.tmp'
64
65  let fl = ['Hello World!']
66  call writefile(fl, fname)
67  set autoread
68  exec 'e' fname
69  call SleepForTimestamp()
70  let fl = readfile(fname)
71  let fl[0] .= ' - checktime'
72  call writefile(fl, fname)
73  checktime
74  call assert_equal(fl[0], getline(1))
75
76  call delete(fname)
77endfunc
78
79func Test_checktime_fast()
80  CheckFeature nanotime
81
82  let fname = 'Xtest.tmp'
83
84  let fl = ['Hello World!']
85  call writefile(fl, fname)
86  set autoread
87  exec 'e' fname
88  let fl = readfile(fname)
89  let fl[0] .= ' - checktime'
90  call writefile(fl, fname)
91  checktime
92  call assert_equal(fl[0], getline(1))
93
94  call delete(fname)
95endfunc
96
97func Test_autoread_fast()
98  CheckFeature nanotime
99
100  " this is timing sensitive
101  let g:test_is_flaky = 1
102
103  new Xautoread
104  setlocal autoread
105  call setline(1, 'foo')
106  w!
107  sleep 10m
108  call writefile(['bar'], 'Xautoread')
109  sleep 10m
110  checktime
111  call assert_equal('bar', trim(getline(1)))
112
113  call delete('Xautoread')
114endfunc
115
116func Test_autoread_file_deleted()
117  new Xautoread
118  set autoread
119  call setline(1, 'original')
120  w!
121
122  call SleepForTimestamp()
123  if has('win32')
124    silent !echo changed > Xautoread
125  else
126    silent !echo 'changed' > Xautoread
127  endif
128  checktime
129  call assert_equal('changed', trim(getline(1)))
130
131  call SleepForTimestamp()
132  messages clear
133  if has('win32')
134    silent !del Xautoread
135  else
136    silent !rm Xautoread
137  endif
138  checktime
139  call assert_match('E211:', execute('messages'))
140  call assert_equal('changed', trim(getline(1)))
141
142  call SleepForTimestamp()
143  if has('win32')
144    silent !echo recreated > Xautoread
145  else
146    silent !echo 'recreated' > Xautoread
147  endif
148  checktime
149  call assert_equal('recreated', trim(getline(1)))
150
151  call delete('Xautoread')
152  bwipe!
153endfunc
154
155
156func Test_nonexistent_file()
157  let fname = 'Xtest.tmp'
158
159  call delete(fname)
160  call assert_equal(-1, getftime(fname))
161  call assert_equal(-1, getfsize(fname))
162  call assert_equal('', getftype(fname))
163  call assert_equal('', getfperm(fname))
164endfunc
165
166func Test_getftype()
167  call assert_equal('file', getftype(v:progpath))
168  call assert_equal('dir',  getftype('.'))
169
170  if !has('unix')
171    return
172  endif
173
174  silent !ln -s Xfile Xlink
175  call assert_equal('link', getftype('Xlink'))
176  call delete('Xlink')
177
178  if executable('mkfifo')
179    silent !mkfifo Xfifo
180    call assert_equal('fifo', getftype('Xfifo'))
181    call delete('Xfifo')
182  endif
183
184  for cdevfile in systemlist('find /dev -type c -maxdepth 2 2>/dev/null')
185    " On Mac /def/fd/2 is found but the type is "fifo"
186    if cdevfile !~ '/dev/fd/'
187      let type = getftype(cdevfile)
188      " ignore empty result, can happen if the file disappeared
189      if type != ''
190	call assert_equal('cdev', type, 'for ' .. cdevfile)
191      endif
192    endif
193  endfor
194
195  for bdevfile in systemlist('find /dev -type b -maxdepth 2 2>/dev/null')
196    let type = getftype(bdevfile)
197    " ignore empty result, can happen if the file disappeared
198    if type != ''
199      call assert_equal('bdev', type, 'for ' .. bdevfile)
200    endif
201  endfor
202
203  " The /run/ directory typically contains socket files.
204  " If it does not, test won't fail but will not test socket files.
205  for socketfile in systemlist('find /run -type s -maxdepth 2 2>/dev/null')
206    let type = getftype(socketfile)
207    " ignore empty result, can happen if the file disappeared
208    if type != ''
209      call assert_equal('socket', type, 'for ' .. socketfile)
210    endif
211  endfor
212
213  " TODO: file type 'other' is not tested. How can we test it?
214endfunc
215
216func Test_win32_symlink_dir()
217  " On Windows, non-admin users cannot create symlinks.
218  " So we use an existing symlink for this test.
219  CheckMSWindows
220  " Check if 'C:\Users\All Users' is a symlink to a directory.
221  let res = system('dir C:\Users /a')
222  if match(res, '\C<SYMLINKD> *All Users') >= 0
223    " Get the filetype of the symlink.
224    call assert_equal('dir', getftype('C:\Users\All Users'))
225  else
226    throw 'Skipped: cannot find an existing symlink'
227  endif
228endfunc
229
230" vim: shiftwidth=2 sts=2 expandtab
231