blob: 5982aeef1b80ec9bacaaf68c238ee0c56097aa58 [file] [log] [blame]
Bram Moolenaarda59dd52016-01-05 21:59:58 +01001" Test for the quickfix commands.
2
3if !has('quickfix')
4 finish
5endif
6
7" Tests for the :clist and :llist commands
8function XlistTests(cchar)
9 let Xlist = a:cchar . 'list'
10 let Xgetexpr = a:cchar . 'getexpr'
11
12 " With an empty list, command should return error
13 exe Xgetexpr . ' []'
14 exe 'silent! ' . Xlist
15 call assert_true(v:errmsg ==# 'E42: No Errors')
16
17 " Populate the list and then try
18 exe Xgetexpr . " ['non-error 1', 'Xtestfile1:1:3:Line1',
19 \ 'non-error 2', 'Xtestfile2:2:2:Line2',
20 \ 'non-error 3', 'Xtestfile3:3:1:Line3']"
21
22 " List only valid entries
23 redir => result
24 exe Xlist
25 redir END
26 let l = split(result, "\n")
27 call assert_equal([' 2 Xtestfile1:1 col 3: Line1',
28 \ ' 4 Xtestfile2:2 col 2: Line2',
29 \ ' 6 Xtestfile3:3 col 1: Line3'], l)
30
31 " List all the entries
32 redir => result
33 exe Xlist . "!"
34 redir END
35 let l = split(result, "\n")
36 call assert_equal([' 1: non-error 1', ' 2 Xtestfile1:1 col 3: Line1',
37 \ ' 3: non-error 2', ' 4 Xtestfile2:2 col 2: Line2',
38 \ ' 5: non-error 3', ' 6 Xtestfile3:3 col 1: Line3'], l)
39
40 " List a range of errors
41 redir => result
42 exe Xlist . " 3,6"
43 redir END
44 let l = split(result, "\n")
45 call assert_equal([' 4 Xtestfile2:2 col 2: Line2',
46 \ ' 6 Xtestfile3:3 col 1: Line3'], l)
47
48 redir => result
49 exe Xlist . "! 3,4"
50 redir END
51 let l = split(result, "\n")
52 call assert_equal([' 3: non-error 2', ' 4 Xtestfile2:2 col 2: Line2'], l)
53
54 redir => result
55 exe Xlist . " -6,-4"
56 redir END
57 let l = split(result, "\n")
58 call assert_equal([' 2 Xtestfile1:1 col 3: Line1'], l)
59
60 redir => result
61 exe Xlist . "! -5,-3"
62 redir END
63 let l = split(result, "\n")
64 call assert_equal([' 2 Xtestfile1:1 col 3: Line1',
65 \ ' 3: non-error 2', ' 4 Xtestfile2:2 col 2: Line2'], l)
66endfunction
67
68function Test_clist()
69 call XlistTests('c')
70 call XlistTests('l')
71endfunction
72
73" Tests for the :colder, :cnewer, :lolder and :lnewer commands
74" Note that this test assumes that a quickfix/location list is
Bram Moolenaarcfc0a352016-01-09 20:23:00 +010075" already set by the caller.
Bram Moolenaarda59dd52016-01-05 21:59:58 +010076function XageTests(cchar)
77 let Xolder = a:cchar . 'older'
78 let Xnewer = a:cchar . 'newer'
79 let Xgetexpr = a:cchar . 'getexpr'
80 if a:cchar == 'c'
81 let Xgetlist = 'getqflist()'
82 else
83 let Xgetlist = 'getloclist(0)'
84 endif
85
86 " Jumping to a non existent list should return error
87 exe 'silent! ' . Xolder . ' 99'
88 call assert_true(v:errmsg ==# 'E380: At bottom of quickfix stack')
89
90 exe 'silent! ' . Xnewer . ' 99'
91 call assert_true(v:errmsg ==# 'E381: At top of quickfix stack')
92
93 " Add three quickfix/location lists
94 exe Xgetexpr . " ['Xtestfile1:1:3:Line1']"
95 exe Xgetexpr . " ['Xtestfile2:2:2:Line2']"
96 exe Xgetexpr . " ['Xtestfile3:3:1:Line3']"
97
98 " Go back two lists
99 exe Xolder
100 exe 'let l = ' . Xgetlist
101 call assert_equal('Line2', l[0].text)
102
103 " Go forward two lists
104 exe Xnewer
105 exe 'let l = ' . Xgetlist
106 call assert_equal('Line3', l[0].text)
107
108 " Test for the optional count argument
109 exe Xolder . ' 2'
110 exe 'let l = ' . Xgetlist
111 call assert_equal('Line1', l[0].text)
112
113 exe Xnewer . ' 2'
114 exe 'let l = ' . Xgetlist
115 call assert_equal('Line3', l[0].text)
116endfunction
117
118function Test_cage()
Bram Moolenaarcfc0a352016-01-09 20:23:00 +0100119 let list = [{'bufnr': 1, 'lnum': 1}]
120 call setqflist(list)
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100121 call XageTests('c')
Bram Moolenaarcfc0a352016-01-09 20:23:00 +0100122
123 call setloclist(0, list)
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100124 call XageTests('l')
125endfunction
126
127" Tests for the :cwindow, :lwindow :cclose, :lclose, :copen and :lopen
128" commands
129function XwindowTests(cchar)
130 let Xwindow = a:cchar . 'window'
131 let Xclose = a:cchar . 'close'
132 let Xopen = a:cchar . 'open'
133 let Xgetexpr = a:cchar . 'getexpr'
134
135 " Create a list with no valid entries
136 exe Xgetexpr . " ['non-error 1', 'non-error 2', 'non-error 3']"
137
138 " Quickfix/Location window should not open with no valid errors
139 exe Xwindow
140 call assert_true(winnr('$') == 1)
141
142 " Create a list with valid entries
143 exe Xgetexpr . " ['Xtestfile1:1:3:Line1', 'Xtestfile2:2:2:Line2',
144 \ 'Xtestfile3:3:1:Line3']"
145
146 " Open the window
147 exe Xwindow
148 call assert_true(winnr('$') == 2 && winnr() == 2 &&
149 \ getline('.') ==# 'Xtestfile1|1 col 3| Line1')
150
151 " Close the window
152 exe Xclose
153 call assert_true(winnr('$') == 1)
154
155 " Create a list with no valid entries
156 exe Xgetexpr . " ['non-error 1', 'non-error 2', 'non-error 3']"
157
158 " Open the window
159 exe Xopen . ' 5'
160 call assert_true(winnr('$') == 2 && getline('.') ==# '|| non-error 1'
161 \ && winheight('.') == 5)
162
163 " Opening the window again, should move the cursor to that window
164 wincmd t
165 exe Xopen . ' 7'
166 call assert_true(winnr('$') == 2 && winnr() == 2 &&
167 \ winheight('.') == 7 &&
168 \ getline('.') ==# '|| non-error 1')
169
170
171 " Calling cwindow should close the quickfix window with no valid errors
172 exe Xwindow
173 call assert_true(winnr('$') == 1)
174endfunction
175
176function Test_cwindow()
177 call XwindowTests('c')
178 call XwindowTests('l')
179endfunction
180
181" Tests for the :cfile, :lfile, :caddfile, :laddfile, :cgetfile and :lgetfile
182" commands.
183function XfileTests(cchar)
184 let Xfile = a:cchar . 'file'
185 let Xgetfile = a:cchar . 'getfile'
186 let Xaddfile = a:cchar . 'addfile'
187 if a:cchar == 'c'
188 let Xgetlist = 'getqflist()'
189 else
190 let Xgetlist = 'getloclist(0)'
191 endif
192
193 call writefile(['Xtestfile1:700:10:Line 700',
194 \ 'Xtestfile2:800:15:Line 800'], 'Xqftestfile1')
195
196 enew!
197 exe Xfile . ' Xqftestfile1'
198 exe 'let l = ' . Xgetlist
199 call assert_true(len(l) == 2 &&
200 \ l[0].lnum == 700 && l[0].col == 10 && l[0].text ==# 'Line 700' &&
201 \ l[1].lnum == 800 && l[1].col == 15 && l[1].text ==# 'Line 800')
202
203 " Run cfile/lfile from a modified buffer
204 enew!
205 silent! put ='Quickfix'
206 exe 'silent! ' . Xfile . ' Xqftestfile1'
207 call assert_true(v:errmsg ==# 'E37: No write since last change (add ! to override)')
208
209 call writefile(['Xtestfile3:900:30:Line 900'], 'Xqftestfile1')
210 exe Xaddfile . ' Xqftestfile1'
211 exe 'let l = ' . Xgetlist
212 call assert_true(len(l) == 3 &&
213 \ l[2].lnum == 900 && l[2].col == 30 && l[2].text ==# 'Line 900')
214
215 call writefile(['Xtestfile1:222:77:Line 222',
216 \ 'Xtestfile2:333:88:Line 333'], 'Xqftestfile1')
217
218 enew!
219 exe Xgetfile . ' Xqftestfile1'
220 exe 'let l = ' . Xgetlist
221 call assert_true(len(l) == 2 &&
222 \ l[0].lnum == 222 && l[0].col == 77 && l[0].text ==# 'Line 222' &&
223 \ l[1].lnum == 333 && l[1].col == 88 && l[1].text ==# 'Line 333')
224
225 call delete('Xqftestfile1')
226endfunction
227
228function Test_cfile()
229 call XfileTests('c')
230 call XfileTests('l')
231endfunction
232
233" Tests for the :cbuffer, :lbuffer, :caddbuffer, :laddbuffer, :cgetbuffer and
234" :lgetbuffer commands.
235function XbufferTests(cchar)
236 let Xbuffer = a:cchar . 'buffer'
237 let Xgetbuffer = a:cchar . 'getbuffer'
238 let Xaddbuffer = a:cchar . 'addbuffer'
239 if a:cchar == 'c'
240 let Xgetlist = 'getqflist()'
241 else
242 let Xgetlist = 'getloclist(0)'
243 endif
244
245 enew!
246 silent! call setline(1, ['Xtestfile7:700:10:Line 700',
247 \ 'Xtestfile8:800:15:Line 800'])
248 exe Xbuffer . "!"
249 exe 'let l = ' . Xgetlist
250 call assert_true(len(l) == 2 &&
251 \ l[0].lnum == 700 && l[0].col == 10 && l[0].text ==# 'Line 700' &&
252 \ l[1].lnum == 800 && l[1].col == 15 && l[1].text ==# 'Line 800')
253
254 enew!
255 silent! call setline(1, ['Xtestfile9:900:55:Line 900',
256 \ 'Xtestfile10:950:66:Line 950'])
257 exe Xgetbuffer
258 exe 'let l = ' . Xgetlist
259 call assert_true(len(l) == 2 &&
260 \ l[0].lnum == 900 && l[0].col == 55 && l[0].text ==# 'Line 900' &&
261 \ l[1].lnum == 950 && l[1].col == 66 && l[1].text ==# 'Line 950')
262
263 enew!
264 silent! call setline(1, ['Xtestfile11:700:20:Line 700',
265 \ 'Xtestfile12:750:25:Line 750'])
266 exe Xaddbuffer
267 exe 'let l = ' . Xgetlist
268 call assert_true(len(l) == 4 &&
269 \ l[1].lnum == 950 && l[1].col == 66 && l[1].text ==# 'Line 950' &&
270 \ l[2].lnum == 700 && l[2].col == 20 && l[2].text ==# 'Line 700' &&
271 \ l[3].lnum == 750 && l[3].col == 25 && l[3].text ==# 'Line 750')
272
273endfunction
274
275function Test_cbuffer()
276 call XbufferTests('c')
277 call XbufferTests('l')
278endfunction
279
Bram Moolenaar75bdf6a2016-01-07 21:25:08 +0100280function Test_nomem()
Bram Moolenaar28fb79d2016-01-09 22:28:33 +0100281 call alloc_fail(GetAllocId('qf_dirname_start'), 0, 0)
Bram Moolenaara260b872016-01-15 20:48:22 +0100282 call assert_fails('vimgrep vim runtest.vim', 'E342:')
Bram Moolenaar75bdf6a2016-01-07 21:25:08 +0100283
Bram Moolenaar28fb79d2016-01-09 22:28:33 +0100284 call alloc_fail(GetAllocId('qf_dirname_now'), 0, 0)
Bram Moolenaara260b872016-01-15 20:48:22 +0100285 call assert_fails('vimgrep vim runtest.vim', 'E342:')
Bram Moolenaar75bdf6a2016-01-07 21:25:08 +0100286
Bram Moolenaar28fb79d2016-01-09 22:28:33 +0100287 call alloc_fail(GetAllocId('qf_namebuf'), 0, 0)
Bram Moolenaara260b872016-01-15 20:48:22 +0100288 call assert_fails('cfile runtest.vim', 'E342:')
Bram Moolenaar75bdf6a2016-01-07 21:25:08 +0100289
Bram Moolenaar28fb79d2016-01-09 22:28:33 +0100290 call alloc_fail(GetAllocId('qf_errmsg'), 0, 0)
Bram Moolenaara260b872016-01-15 20:48:22 +0100291 call assert_fails('cfile runtest.vim', 'E342:')
Bram Moolenaar75bdf6a2016-01-07 21:25:08 +0100292
Bram Moolenaar28fb79d2016-01-09 22:28:33 +0100293 call alloc_fail(GetAllocId('qf_pattern'), 0, 0)
Bram Moolenaara260b872016-01-15 20:48:22 +0100294 call assert_fails('cfile runtest.vim', 'E342:')
Bram Moolenaar75bdf6a2016-01-07 21:25:08 +0100295
296endfunc
297
Bram Moolenaar62ef7972016-01-19 14:51:54 +0100298function Test_helpgrep()
299 helpgrep quickfix
300 copen
301 " This wipes out the buffer, make sure that doesn't cause trouble.
302 cclose
303endfunc
Bram Moolenaar75bdf6a2016-01-07 21:25:08 +0100304
Bram Moolenaar6920c722016-01-22 22:44:10 +0100305func Test_errortitle()
306 augroup QfBufWinEnter
307 au!
308 au BufWinEnter * :let g:a=get(w:, 'quickfix_title', 'NONE')
309 augroup END
310 copen
311 let a=[{'lnum': 308, 'bufnr': bufnr(''), 'col': 58, 'valid': 1, 'vcol': 0, 'nr': 0, 'type': '', 'pattern': '', 'text': ' au BufWinEnter * :let g:a=get(w:, ''quickfix_title'', ''NONE'')'}]
312 call setqflist(a)
313 call assert_equal(':setqflist()', g:a)
314 augroup QfBufWinEnter
315 au!
316 augroup END
317 augroup! QfBufWinEnter
318endfunc
Bram Moolenaare27dba42016-03-15 14:11:10 +0100319
Bram Moolenaar5584df62016-03-18 21:00:51 +0100320func Test_vimgreptitle()
321 augroup QfBufWinEnter
322 au!
323 au BufWinEnter * :let g:a=get(w:, 'quickfix_title', 'NONE')
324 augroup END
325 try
326 vimgrep /pattern/j file
327 catch /E480/
328 endtry
329 copen
330 call assert_equal(': vimgrep /pattern/j file', g:a)
331 augroup QfBufWinEnter
332 au!
333 augroup END
334 augroup! QfBufWinEnter
335endfunc
336
Bram Moolenaare27dba42016-03-15 14:11:10 +0100337function XqfTitleTests(cchar)
338 let Xgetexpr = a:cchar . 'getexpr'
339 if a:cchar == 'c'
340 let Xgetlist = 'getqflist()'
341 else
342 let Xgetlist = 'getloclist(0)'
343 endif
344 let Xopen = a:cchar . 'open'
345 let Xclose = a:cchar . 'close'
346
347 exe Xgetexpr . " ['file:1:1:message']"
348 exe 'let l = ' . Xgetlist
349 if a:cchar == 'c'
350 call setqflist(l, 'r')
351 else
352 call setloclist(0, l, 'r')
353 endif
354
355 exe Xopen
356 if a:cchar == 'c'
357 let title = ':setqflist()'
358 else
359 let title = ':setloclist()'
360 endif
361 call assert_equal(title, w:quickfix_title)
362 exe Xclose
363endfunction
364
365" Tests for quickfix window's title
366function Test_qf_title()
367 call XqfTitleTests('c')
368 call XqfTitleTests('l')
369endfunction
370
371" Tests for 'errorformat'
372function Test_efm()
373 let save_efm = &efm
374 set efm=%EEEE%m,%WWWW%m,%+CCCC%.%#,%-GGGG%.%#
375 cgetexpr ['WWWW', 'EEEE', 'CCCC']
376 let l = strtrans(string(map(getqflist(), '[v:val.text, v:val.valid]')))
377 call assert_equal("[['W', 1], ['E^@CCCC', 1]]", l)
378 cgetexpr ['WWWW', 'GGGG', 'EEEE', 'CCCC']
379 let l = strtrans(string(map(getqflist(), '[v:val.text, v:val.valid]')))
380 call assert_equal("[['W', 1], ['E^@CCCC', 1]]", l)
381 cgetexpr ['WWWW', 'GGGG', 'ZZZZ', 'EEEE', 'CCCC', 'YYYY']
382 let l = strtrans(string(map(getqflist(), '[v:val.text, v:val.valid]')))
383 call assert_equal("[['W', 1], ['ZZZZ', 0], ['E^@CCCC', 1], ['YYYY', 0]]", l)
384 let &efm = save_efm
385endfunction
Bram Moolenaar1ff2b642016-03-17 22:07:02 +0100386
387" This will test for problems in quickfix:
388" A. incorrectly copying location lists which caused the location list to show
389" a different name than the file that was actually being displayed.
390" B. not reusing the window for which the location list window is opened but
391" instead creating new windows.
392" C. make sure that the location list window is not reused instead of the
393" window it belongs to.
394"
395" Set up the test environment:
396function! ReadTestProtocol(name)
397 let base = substitute(a:name, '\v^test://(.*)%(\.[^.]+)?', '\1', '')
398 let word = substitute(base, '\v(.*)\..*', '\1', '')
399
400 setl modifiable
401 setl noreadonly
402 setl noswapfile
403 setl bufhidden=delete
404 %del _
405 " For problem 2:
406 " 'buftype' has to be set to reproduce the constant opening of new windows
407 setl buftype=nofile
408
409 call setline(1, word)
410
411 setl nomodified
412 setl nomodifiable
413 setl readonly
414 exe 'doautocmd BufRead ' . substitute(a:name, '\v^test://(.*)', '\1', '')
415endfunction
416
417function Test_locationlist()
418 enew
419
420 augroup testgroup
421 au!
422 autocmd BufReadCmd test://* call ReadTestProtocol(expand("<amatch>"))
423 augroup END
424
425 let words = [ "foo", "bar", "baz", "quux", "shmoo", "spam", "eggs" ]
426
427 let qflist = []
428 for word in words
429 call add(qflist, {'filename': 'test://' . word . '.txt', 'text': 'file ' . word . '.txt', })
430 " NOTE: problem 1:
431 " intentionally not setting 'lnum' so that the quickfix entries are not
432 " valid
433 call setloclist(0, qflist, ' ')
434 endfor
435
436 " Test A
437 lrewind
438 enew
439 lopen
440 lnext
441 lnext
442 lnext
443 lnext
444 vert split
445 wincmd L
446 lopen
447 wincmd p
448 lnext
449 let fileName = expand("%")
450 wincmd p
451 let locationListFileName = substitute(getline(line('.')), '\([^|]*\)|.*', '\1', '')
452 let fileName = substitute(fileName, '\\', '/', 'g')
453 let locationListFileName = substitute(locationListFileName, '\\', '/', 'g')
454 call assert_equal("test://bar.txt", fileName)
455 call assert_equal("test://bar.txt", locationListFileName)
456
457 wincmd n | only
458
459 " Test B:
460 lrewind
461 lopen
462 2
463 exe "normal \<CR>"
464 wincmd p
465 3
466 exe "normal \<CR>"
467 wincmd p
468 4
469 exe "normal \<CR>"
470 call assert_equal(2, winnr('$'))
471 wincmd n | only
472
473 " Test C:
474 lrewind
475 lopen
476 " Let's move the location list window to the top to check whether it (the
477 " first window found) will be reused when we try to open new windows:
478 wincmd K
479 2
480 exe "normal \<CR>"
481 wincmd p
482 3
483 exe "normal \<CR>"
484 wincmd p
485 4
486 exe "normal \<CR>"
487 1wincmd w
488 call assert_equal('quickfix', &buftype)
489 2wincmd w
490 let bufferName = expand("%")
491 let bufferName = substitute(bufferName, '\\', '/', 'g')
492 call assert_equal('test://quux.txt', bufferName)
493
494 wincmd n | only
495
496 augroup! testgroup
497endfunction