1" Tests for the writefile() function and some :write commands.
2
3source check.vim
4
5func Test_writefile()
6  let f = tempname()
7  call writefile(["over","written"], f, "b")
8  call writefile(["hello","world"], f, "b")
9  call writefile(["!", "good"], f, "a")
10  call writefile(["morning"], f, "ab")
11  call writefile(["", "vimmers"], f, "ab")
12  let l = readfile(f)
13  call assert_equal("hello", l[0])
14  call assert_equal("world!", l[1])
15  call assert_equal("good", l[2])
16  call assert_equal("morning", l[3])
17  call assert_equal("vimmers", l[4])
18  call delete(f)
19endfunc
20
21func Test_writefile_ignore_regexp_error()
22  write Xt[z-a]est.txt
23  call delete('Xt[z-a]est.txt')
24endfunc
25
26func Test_writefile_fails_gently()
27  call assert_fails('call writefile(["test"], "Xfile", [])', 'E730:')
28  call assert_false(filereadable("Xfile"))
29  call delete("Xfile")
30
31  call assert_fails('call writefile(["test", [], [], [], "tset"], "Xfile")', 'E730:')
32  call assert_false(filereadable("Xfile"))
33  call delete("Xfile")
34
35  call assert_fails('call writefile([], "Xfile", [])', 'E730:')
36  call assert_false(filereadable("Xfile"))
37  call delete("Xfile")
38
39  call assert_fails('call writefile([], [])', 'E730:')
40endfunc
41
42func Test_writefile_fails_conversion()
43  if !has('iconv') || has('sun')
44    return
45  endif
46  " Without a backup file the write won't happen if there is a conversion
47  " error.
48  set nobackup nowritebackup backupdir=. backupskip=
49  new
50  let contents = ["line one", "line two"]
51  call writefile(contents, 'Xfile')
52  edit Xfile
53  call setline(1, ["first line", "cannot convert \u010b", "third line"])
54  call assert_fails('write ++enc=cp932', 'E513:')
55  call assert_equal(contents, readfile('Xfile'))
56
57  call delete('Xfile')
58  bwipe!
59  set backup& writebackup& backupdir&vim backupskip&vim
60endfunc
61
62func Test_writefile_fails_conversion2()
63  if !has('iconv') || has('sun')
64    return
65  endif
66  " With a backup file the write happens even if there is a conversion error,
67  " but then the backup file must remain
68  set nobackup writebackup backupdir=. backupskip=
69  let contents = ["line one", "line two"]
70  call writefile(contents, 'Xfile_conversion_err')
71  edit Xfile_conversion_err
72  call setline(1, ["first line", "cannot convert \u010b", "third line"])
73  set fileencoding=latin1
74  let output = execute('write')
75  call assert_match('CONVERSION ERROR', output)
76  call assert_equal(contents, readfile('Xfile_conversion_err~'))
77
78  call delete('Xfile_conversion_err')
79  call delete('Xfile_conversion_err~')
80  bwipe!
81  set backup& writebackup& backupdir&vim backupskip&vim
82endfunc
83
84func SetFlag(timer)
85  let g:flag = 1
86endfunc
87
88func Test_write_quit_split()
89  " Prevent exiting by splitting window on file write.
90  augroup testgroup
91    autocmd BufWritePre * split
92  augroup END
93  e! Xfile
94  call setline(1, 'nothing')
95  wq
96
97  if has('timers')
98    " timer will not run if "exiting" is still set
99    let g:flag = 0
100    call timer_start(1, 'SetFlag')
101    sleep 50m
102    call assert_equal(1, g:flag)
103    unlet g:flag
104  endif
105  au! testgroup
106  bwipe Xfile
107  call delete('Xfile')
108endfunc
109
110func Test_nowrite_quit_split()
111  " Prevent exiting by opening a help window.
112  e! Xfile
113  help
114  wincmd w
115  exe winnr() . 'q'
116
117  if has('timers')
118    " timer will not run if "exiting" is still set
119    let g:flag = 0
120    call timer_start(1, 'SetFlag')
121    sleep 50m
122    call assert_equal(1, g:flag)
123    unlet g:flag
124  endif
125  bwipe Xfile
126endfunc
127
128func Test_writefile_sync_arg()
129  " This doesn't check if fsync() works, only that the argument is accepted.
130  call writefile(['one'], 'Xtest', 's')
131  call writefile(['two'], 'Xtest', 'S')
132  call delete('Xtest')
133endfunc
134
135func Test_writefile_sync_dev_stdout()
136  if !has('unix')
137    return
138  endif
139  if filewritable('/dev/stdout')
140    " Just check that this doesn't cause an error.
141    call writefile(['one'], '/dev/stdout')
142  else
143    throw 'Skipped: /dev/stdout is not writable'
144  endif
145endfunc
146
147func Test_writefile_autowrite()
148  set autowrite
149  new
150  next Xa Xb Xc
151  call setline(1, 'aaa')
152  next
153  call assert_equal(['aaa'], readfile('Xa'))
154  call setline(1, 'bbb')
155  call assert_fails('edit XX')
156  call assert_false(filereadable('Xb'))
157
158  set autowriteall
159  edit XX
160  call assert_equal(['bbb'], readfile('Xb'))
161
162  bwipe!
163  call delete('Xa')
164  call delete('Xb')
165  set noautowrite
166endfunc
167
168func Test_writefile_autowrite_nowrite()
169  set autowrite
170  new
171  next Xa Xb Xc
172  set buftype=nowrite
173  call setline(1, 'aaa')
174  let buf = bufnr('%')
175  " buffer contents silently lost
176  edit XX
177  call assert_false(filereadable('Xa'))
178  rewind
179  call assert_equal('', getline(1))
180
181  bwipe!
182  set noautowrite
183endfunc
184
185" Test for ':w !<cmd>' to pipe lines from the current buffer to an external
186" command.
187func Test_write_pipe_to_cmd()
188  CheckUnix
189  new
190  call setline(1, ['L1', 'L2', 'L3', 'L4'])
191  2,3w !cat > Xfile
192  call assert_equal(['L2', 'L3'], readfile('Xfile'))
193  close!
194  call delete('Xfile')
195endfunc
196
197" Test for :saveas
198func Test_saveas()
199  call assert_fails('saveas', 'E471:')
200  call writefile(['L1'], 'Xfile')
201  new Xfile
202  new
203  call setline(1, ['L1'])
204  call assert_fails('saveas Xfile', 'E139:')
205  close!
206  enew | only
207  call delete('Xfile')
208endfunc
209
210func Test_write_errors()
211  " Test for writing partial buffer
212  call writefile(['L1', 'L2', 'L3'], 'Xfile')
213  new Xfile
214  call assert_fails('1,2write', 'E140:')
215  close!
216
217  call assert_fails('w > Xtest', 'E494:')
218
219  " Try to overwrite a directory
220  if has('unix')
221    call mkdir('Xdir1')
222    call assert_fails('write Xdir1', 'E17:')
223    call delete('Xdir1', 'd')
224  endif
225
226  " Test for :wall for a buffer with no name
227  enew | only
228  call setline(1, ['L1'])
229  call assert_fails('wall', 'E141:')
230  enew!
231
232  " Test for writing a 'readonly' file
233  new Xfile
234  set readonly
235  call assert_fails('write', 'E45:')
236  close
237
238  " Test for writing to a read-only file
239  new Xfile
240  call setfperm('Xfile', 'r--r--r--')
241  call assert_fails('write', 'E505:')
242  call setfperm('Xfile', 'rw-rw-rw-')
243  close
244
245  call delete('Xfile')
246endfunc
247
248" vim: shiftwidth=2 sts=2 expandtab
249