1" Test for the quickfix commands.
2
3if !has('quickfix')
4  finish
5endif
6
7set encoding=utf-8
8
9func s:setup_commands(cchar)
10  if a:cchar == 'c'
11    command! -nargs=* -bang Xlist <mods>clist<bang> <args>
12    command! -nargs=* Xgetexpr <mods>cgetexpr <args>
13    command! -nargs=* Xaddexpr <mods>caddexpr <args>
14    command! -nargs=* -count Xolder <mods><count>colder <args>
15    command! -nargs=* Xnewer <mods>cnewer <args>
16    command! -nargs=* Xopen <mods>copen <args>
17    command! -nargs=* Xwindow <mods>cwindow <args>
18    command! -nargs=* Xbottom <mods>cbottom <args>
19    command! -nargs=* Xclose <mods>cclose <args>
20    command! -nargs=* -bang Xfile <mods>cfile<bang> <args>
21    command! -nargs=* Xgetfile <mods>cgetfile <args>
22    command! -nargs=* Xaddfile <mods>caddfile <args>
23    command! -nargs=* -bang Xbuffer <mods>cbuffer<bang> <args>
24    command! -nargs=* Xgetbuffer <mods>cgetbuffer <args>
25    command! -nargs=* Xaddbuffer <mods>caddbuffer <args>
26    command! -nargs=* Xrewind <mods>crewind <args>
27    command! -count -nargs=* -bang Xnext <mods><count>cnext<bang> <args>
28    command! -count -nargs=* -bang Xprev <mods><count>cprev<bang> <args>
29    command! -nargs=* -bang Xfirst <mods>cfirst<bang> <args>
30    command! -nargs=* -bang Xlast <mods>clast<bang> <args>
31    command! -nargs=* -bang -range Xnfile <mods><count>cnfile<bang> <args>
32    command! -nargs=* -bang Xpfile <mods>cpfile<bang> <args>
33    command! -nargs=* Xexpr <mods>cexpr <args>
34    command! -range -nargs=* Xvimgrep <mods><count>vimgrep <args>
35    command! -nargs=* Xvimgrepadd <mods>vimgrepadd <args>
36    command! -nargs=* Xgrep <mods> grep <args>
37    command! -nargs=* Xgrepadd <mods> grepadd <args>
38    command! -nargs=* Xhelpgrep helpgrep <args>
39    command! -nargs=0 -count Xcc <count>cc
40    let g:Xgetlist = function('getqflist')
41    let g:Xsetlist = function('setqflist')
42    call setqflist([], 'f')
43  else
44    command! -nargs=* -bang Xlist <mods>llist<bang> <args>
45    command! -nargs=* Xgetexpr <mods>lgetexpr <args>
46    command! -nargs=* Xaddexpr <mods>laddexpr <args>
47    command! -nargs=* -count Xolder <mods><count>lolder <args>
48    command! -nargs=* Xnewer <mods>lnewer <args>
49    command! -nargs=* Xopen <mods>lopen <args>
50    command! -nargs=* Xwindow <mods>lwindow <args>
51    command! -nargs=* Xbottom <mods>lbottom <args>
52    command! -nargs=* Xclose <mods>lclose <args>
53    command! -nargs=* -bang Xfile <mods>lfile<bang> <args>
54    command! -nargs=* Xgetfile <mods>lgetfile <args>
55    command! -nargs=* Xaddfile <mods>laddfile <args>
56    command! -nargs=* -bang Xbuffer <mods>lbuffer<bang> <args>
57    command! -nargs=* Xgetbuffer <mods>lgetbuffer <args>
58    command! -nargs=* Xaddbuffer <mods>laddbuffer <args>
59    command! -nargs=* Xrewind <mods>lrewind <args>
60    command! -count -nargs=* -bang Xnext <mods><count>lnext<bang> <args>
61    command! -count -nargs=* -bang Xprev <mods><count>lprev<bang> <args>
62    command! -nargs=* -bang Xfirst <mods>lfirst<bang> <args>
63    command! -nargs=* -bang Xlast <mods>llast<bang> <args>
64    command! -nargs=* -bang -range Xnfile <mods><count>lnfile<bang> <args>
65    command! -nargs=* -bang Xpfile <mods>lpfile<bang> <args>
66    command! -nargs=* Xexpr <mods>lexpr <args>
67    command! -range -nargs=* Xvimgrep <mods><count>lvimgrep <args>
68    command! -nargs=* Xvimgrepadd <mods>lvimgrepadd <args>
69    command! -nargs=* Xgrep <mods> lgrep <args>
70    command! -nargs=* Xgrepadd <mods> lgrepadd <args>
71    command! -nargs=* Xhelpgrep lhelpgrep <args>
72    command! -nargs=0 -count Xcc <count>ll
73    let g:Xgetlist = function('getloclist', [0])
74    let g:Xsetlist = function('setloclist', [0])
75    call setloclist(0, [], 'f')
76  endif
77endfunc
78
79" Tests for the :clist and :llist commands
80func XlistTests(cchar)
81  call s:setup_commands(a:cchar)
82
83  if a:cchar == 'l'
84      call assert_fails('llist', 'E776:')
85  endif
86  " With an empty list, command should return error
87  Xgetexpr []
88  silent! Xlist
89  call assert_true(v:errmsg ==# 'E42: No Errors')
90
91  " Populate the list and then try
92  Xgetexpr ['non-error 1', 'Xtestfile1:1:3:Line1',
93		  \ 'non-error 2', 'Xtestfile2:2:2:Line2',
94		  \ 'non-error 3', 'Xtestfile3:3:1:Line3']
95
96  " List only valid entries
97  let l = split(execute('Xlist', ''), "\n")
98  call assert_equal([' 2 Xtestfile1:1 col 3: Line1',
99		   \ ' 4 Xtestfile2:2 col 2: Line2',
100		   \ ' 6 Xtestfile3:3 col 1: Line3'], l)
101
102  " List all the entries
103  let l = split(execute('Xlist!', ''), "\n")
104  call assert_equal([' 1: non-error 1', ' 2 Xtestfile1:1 col 3: Line1',
105		   \ ' 3: non-error 2', ' 4 Xtestfile2:2 col 2: Line2',
106		   \ ' 5: non-error 3', ' 6 Xtestfile3:3 col 1: Line3'], l)
107
108  " List a range of errors
109  let l = split(execute('Xlist 3,6', ''), "\n")
110  call assert_equal([' 4 Xtestfile2:2 col 2: Line2',
111		   \ ' 6 Xtestfile3:3 col 1: Line3'], l)
112
113  let l = split(execute('Xlist! 3,4', ''), "\n")
114  call assert_equal([' 3: non-error 2', ' 4 Xtestfile2:2 col 2: Line2'], l)
115
116  let l = split(execute('Xlist -6,-4', ''), "\n")
117  call assert_equal([' 2 Xtestfile1:1 col 3: Line1'], l)
118
119  let l = split(execute('Xlist! -5,-3', ''), "\n")
120  call assert_equal([' 2 Xtestfile1:1 col 3: Line1',
121		   \ ' 3: non-error 2', ' 4 Xtestfile2:2 col 2: Line2'], l)
122
123  " Test for '+'
124  let l = split(execute('Xlist! +2', ''), "\n")
125  call assert_equal([' 2 Xtestfile1:1 col 3: Line1',
126		   \ ' 3: non-error 2', ' 4 Xtestfile2:2 col 2: Line2'], l)
127
128  " Different types of errors
129  call g:Xsetlist([{'lnum':10,'col':5,'type':'W', 'text':'Warning','nr':11},
130	      \ {'lnum':20,'col':10,'type':'e','text':'Error','nr':22},
131	      \ {'lnum':30,'col':15,'type':'i','text':'Info','nr':33},
132	      \ {'lnum':40,'col':20,'type':'x', 'text':'Other','nr':44},
133	      \ {'lnum':50,'col':25,'type':"\<C-A>",'text':'one','nr':55}])
134  let l = split(execute('Xlist', ""), "\n")
135  call assert_equal([' 1:10 col 5 warning  11: Warning',
136	      \ ' 2:20 col 10 error  22: Error',
137	      \ ' 3:30 col 15 info  33: Info',
138	      \ ' 4:40 col 20 x  44: Other',
139	      \ ' 5:50 col 25  55: one'], l)
140
141  " Test for module names, one needs to explicitly set `'valid':v:true` so
142  call g:Xsetlist([
143	\ {'lnum':10,'col':5,'type':'W','module':'Data.Text','text':'ModuleWarning','nr':11,'valid':v:true},
144	\ {'lnum':20,'col':10,'type':'W','module':'Data.Text','filename':'Data/Text.hs','text':'ModuleWarning','nr':22,'valid':v:true},
145	\ {'lnum':30,'col':15,'type':'W','filename':'Data/Text.hs','text':'FileWarning','nr':33,'valid':v:true}])
146  let l = split(execute('Xlist', ""), "\n")
147  call assert_equal([' 1 Data.Text:10 col 5 warning  11: ModuleWarning',
148	\ ' 2 Data.Text:20 col 10 warning  22: ModuleWarning',
149	\ ' 3 Data/Text.hs:30 col 15 warning  33: FileWarning'], l)
150
151  " Error cases
152  call assert_fails('Xlist abc', 'E488:')
153endfunc
154
155func Test_clist()
156  call XlistTests('c')
157  call XlistTests('l')
158endfunc
159
160" Tests for the :colder, :cnewer, :lolder and :lnewer commands
161" Note that this test assumes that a quickfix/location list is
162" already set by the caller.
163func XageTests(cchar)
164  call s:setup_commands(a:cchar)
165
166  let list = [{'bufnr': bufnr('%'), 'lnum': 1}]
167  call g:Xsetlist(list)
168
169  " Jumping to a non existent list should return error
170  silent! Xolder 99
171  call assert_true(v:errmsg ==# 'E380: At bottom of quickfix stack')
172
173  silent! Xnewer 99
174  call assert_true(v:errmsg ==# 'E381: At top of quickfix stack')
175
176  " Add three quickfix/location lists
177  Xgetexpr ['Xtestfile1:1:3:Line1']
178  Xgetexpr ['Xtestfile2:2:2:Line2']
179  Xgetexpr ['Xtestfile3:3:1:Line3']
180
181  " Go back two lists
182  Xolder
183  let l = g:Xgetlist()
184  call assert_equal('Line2', l[0].text)
185
186  " Go forward two lists
187  Xnewer
188  let l = g:Xgetlist()
189  call assert_equal('Line3', l[0].text)
190
191  " Test for the optional count argument
192  Xolder 2
193  let l = g:Xgetlist()
194  call assert_equal('Line1', l[0].text)
195
196  Xnewer 2
197  let l = g:Xgetlist()
198  call assert_equal('Line3', l[0].text)
199endfunc
200
201func Test_cage()
202  call XageTests('c')
203  call XageTests('l')
204endfunc
205
206" Tests for the :cwindow, :lwindow :cclose, :lclose, :copen and :lopen
207" commands
208func XwindowTests(cchar)
209  call s:setup_commands(a:cchar)
210
211  " Opening the location list window without any errors should fail
212  if a:cchar == 'l'
213      call assert_fails('lopen', 'E776:')
214  endif
215
216  " Create a list with no valid entries
217  Xgetexpr ['non-error 1', 'non-error 2', 'non-error 3']
218
219  " Quickfix/Location window should not open with no valid errors
220  Xwindow
221  call assert_true(winnr('$') == 1)
222
223  " Create a list with valid entries
224  Xgetexpr ['Xtestfile1:1:3:Line1', 'Xtestfile2:2:2:Line2',
225		  \ 'Xtestfile3:3:1:Line3']
226
227  " Open the window
228  Xwindow
229  call assert_true(winnr('$') == 2 && winnr() == 2 &&
230	\ getline('.') ==# 'Xtestfile1|1 col 3| Line1')
231  redraw!
232
233  " Close the window
234  Xclose
235  call assert_true(winnr('$') == 1)
236
237  " Create a list with no valid entries
238  Xgetexpr ['non-error 1', 'non-error 2', 'non-error 3']
239
240  " Open the window
241  Xopen 5
242  call assert_true(winnr('$') == 2 && getline('.') ==# '|| non-error 1'
243		      \  && winheight('.') == 5)
244
245  " Opening the window again, should move the cursor to that window
246  wincmd t
247  Xopen 7
248  call assert_true(winnr('$') == 2 && winnr() == 2 &&
249	\ winheight('.') == 7 &&
250	\ getline('.') ==# '|| non-error 1')
251
252
253  " Calling cwindow should close the quickfix window with no valid errors
254  Xwindow
255  call assert_true(winnr('$') == 1)
256
257  if a:cchar == 'c'
258      " Opening the quickfix window in multiple tab pages should reuse the
259      " quickfix buffer
260      Xgetexpr ['Xtestfile1:1:3:Line1', 'Xtestfile2:2:2:Line2',
261		  \ 'Xtestfile3:3:1:Line3']
262      Xopen
263      let qfbufnum = bufnr('%')
264      tabnew
265      Xopen
266      call assert_equal(qfbufnum, bufnr('%'))
267      new | only | tabonly
268  endif
269endfunc
270
271func Test_cwindow()
272  call XwindowTests('c')
273  call XwindowTests('l')
274endfunc
275
276" Tests for the :cfile, :lfile, :caddfile, :laddfile, :cgetfile and :lgetfile
277" commands.
278func XfileTests(cchar)
279  call s:setup_commands(a:cchar)
280
281  call writefile(['Xtestfile1:700:10:Line 700',
282	\ 'Xtestfile2:800:15:Line 800'], 'Xqftestfile1')
283
284  enew!
285  Xfile Xqftestfile1
286  let l = g:Xgetlist()
287  call assert_true(len(l) == 2 &&
288	\ l[0].lnum == 700 && l[0].col == 10 && l[0].text ==# 'Line 700' &&
289	\ l[1].lnum == 800 && l[1].col == 15 && l[1].text ==# 'Line 800')
290
291  " Test with a non existent file
292  call assert_fails('Xfile non_existent_file', 'E40')
293
294  " Run cfile/lfile from a modified buffer
295  enew!
296  silent! put ='Quickfix'
297  silent! Xfile Xqftestfile1
298  call assert_true(v:errmsg ==# 'E37: No write since last change (add ! to override)')
299
300  call writefile(['Xtestfile3:900:30:Line 900'], 'Xqftestfile1')
301  Xaddfile Xqftestfile1
302  let l = g:Xgetlist()
303  call assert_true(len(l) == 3 &&
304	\ l[2].lnum == 900 && l[2].col == 30 && l[2].text ==# 'Line 900')
305
306  call writefile(['Xtestfile1:222:77:Line 222',
307	\ 'Xtestfile2:333:88:Line 333'], 'Xqftestfile1')
308
309  enew!
310  Xgetfile Xqftestfile1
311  let l = g:Xgetlist()
312  call assert_true(len(l) == 2 &&
313	\ l[0].lnum == 222 && l[0].col == 77 && l[0].text ==# 'Line 222' &&
314	\ l[1].lnum == 333 && l[1].col == 88 && l[1].text ==# 'Line 333')
315
316  call delete('Xqftestfile1')
317endfunc
318
319func Test_cfile()
320  call XfileTests('c')
321  call XfileTests('l')
322endfunc
323
324" Tests for the :cbuffer, :lbuffer, :caddbuffer, :laddbuffer, :cgetbuffer and
325" :lgetbuffer commands.
326func XbufferTests(cchar)
327  call s:setup_commands(a:cchar)
328
329  enew!
330  silent! call setline(1, ['Xtestfile7:700:10:Line 700',
331	\ 'Xtestfile8:800:15:Line 800'])
332  Xbuffer!
333  let l = g:Xgetlist()
334  call assert_true(len(l) == 2 &&
335	\ l[0].lnum == 700 && l[0].col == 10 && l[0].text ==# 'Line 700' &&
336	\ l[1].lnum == 800 && l[1].col == 15 && l[1].text ==# 'Line 800')
337
338  enew!
339  silent! call setline(1, ['Xtestfile9:900:55:Line 900',
340	\ 'Xtestfile10:950:66:Line 950'])
341  Xgetbuffer
342  let l = g:Xgetlist()
343  call assert_true(len(l) == 2 &&
344	\ l[0].lnum == 900 && l[0].col == 55 && l[0].text ==# 'Line 900' &&
345	\ l[1].lnum == 950 && l[1].col == 66 && l[1].text ==# 'Line 950')
346
347  enew!
348  silent! call setline(1, ['Xtestfile11:700:20:Line 700',
349	\ 'Xtestfile12:750:25:Line 750'])
350  Xaddbuffer
351  let l = g:Xgetlist()
352  call assert_true(len(l) == 4 &&
353	\ l[1].lnum == 950 && l[1].col == 66 && l[1].text ==# 'Line 950' &&
354	\ l[2].lnum == 700 && l[2].col == 20 && l[2].text ==# 'Line 700' &&
355	\ l[3].lnum == 750 && l[3].col == 25 && l[3].text ==# 'Line 750')
356  enew!
357
358  " Check for invalid buffer
359  call assert_fails('Xbuffer 199', 'E474:')
360
361  " Check for unloaded buffer
362  edit Xtestfile1
363  let bnr = bufnr('%')
364  enew!
365  call assert_fails('Xbuffer ' . bnr, 'E681:')
366
367  " Check for invalid range
368  " Using Xbuffer will not run the range check in the cbuffer/lbuffer
369  " commands. So directly call the commands.
370  if (a:cchar == 'c')
371      call assert_fails('900,999cbuffer', 'E16:')
372  else
373      call assert_fails('900,999lbuffer', 'E16:')
374  endif
375endfunc
376
377func Test_cbuffer()
378  call XbufferTests('c')
379  call XbufferTests('l')
380endfunc
381
382func XexprTests(cchar)
383  call s:setup_commands(a:cchar)
384
385  call assert_fails('Xexpr 10', 'E777:')
386endfunc
387
388func Test_cexpr()
389  call XexprTests('c')
390  call XexprTests('l')
391endfunc
392
393" Tests for :cnext, :cprev, :cfirst, :clast commands
394func Xtest_browse(cchar)
395  call s:setup_commands(a:cchar)
396
397  call g:Xsetlist([], 'f')
398  " Jumping to first or next location list entry without any error should
399  " result in failure
400  if a:cchar == 'c'
401    let err = 'E42:'
402  else
403    let err = 'E776:'
404  endif
405  call assert_fails('Xnext', err)
406  call assert_fails('Xprev', err)
407  call assert_fails('Xnfile', err)
408  call assert_fails('Xpfile', err)
409
410  call s:create_test_file('Xqftestfile1')
411  call s:create_test_file('Xqftestfile2')
412
413  Xgetexpr ['Xqftestfile1:5:Line5',
414		\ 'Xqftestfile1:6:Line6',
415		\ 'Xqftestfile2:10:Line10',
416		\ 'Xqftestfile2:11:Line11',
417		\ 'RegularLine1',
418		\ 'RegularLine2']
419
420  Xfirst
421  call assert_fails('Xprev', 'E553')
422  call assert_fails('Xpfile', 'E553')
423  Xnfile
424  call assert_equal('Xqftestfile2', bufname('%'))
425  call assert_equal(10, line('.'))
426  Xpfile
427  call assert_equal('Xqftestfile1', bufname('%'))
428  call assert_equal(6, line('.'))
429  5Xcc
430  call assert_equal(5, g:Xgetlist({'idx':0}).idx)
431  2Xcc
432  call assert_equal(2, g:Xgetlist({'idx':0}).idx)
433  10Xcc
434  call assert_equal(6, g:Xgetlist({'idx':0}).idx)
435  Xlast
436  Xprev
437  call assert_equal('Xqftestfile2', bufname('%'))
438  call assert_equal(11, line('.'))
439  call assert_fails('Xnext', 'E553')
440  call assert_fails('Xnfile', 'E553')
441  Xrewind
442  call assert_equal('Xqftestfile1', bufname('%'))
443  call assert_equal(5, line('.'))
444
445  10Xnext
446  call assert_equal('Xqftestfile2', bufname('%'))
447  call assert_equal(11, line('.'))
448  10Xprev
449  call assert_equal('Xqftestfile1', bufname('%'))
450  call assert_equal(5, line('.'))
451
452  " Jumping to an error from the error window using cc command
453  Xgetexpr ['Xqftestfile1:5:Line5',
454		\ 'Xqftestfile1:6:Line6',
455		\ 'Xqftestfile2:10:Line10',
456		\ 'Xqftestfile2:11:Line11']
457  Xopen
458  10Xcc
459  call assert_equal(11, line('.'))
460  call assert_equal('Xqftestfile2', bufname('%'))
461
462  " Jumping to an error from the error window (when only the error window is
463  " present)
464  Xopen | only
465  Xlast 1
466  call assert_equal(5, line('.'))
467  call assert_equal('Xqftestfile1', bufname('%'))
468
469  Xexpr ""
470  call assert_fails('Xnext', 'E42:')
471
472  call delete('Xqftestfile1')
473  call delete('Xqftestfile2')
474
475  " Should be able to use next/prev with invalid entries
476  Xexpr ""
477  call assert_equal(0, g:Xgetlist({'idx' : 0}).idx)
478  call assert_equal(0, g:Xgetlist({'size' : 0}).size)
479  Xaddexpr ['foo', 'bar', 'baz', 'quux', 'shmoo']
480  call assert_equal(5, g:Xgetlist({'size' : 0}).size)
481  Xlast
482  call assert_equal(5, g:Xgetlist({'idx' : 0}).idx)
483  Xfirst
484  call assert_equal(1, g:Xgetlist({'idx' : 0}).idx)
485  2Xnext
486  call assert_equal(3, g:Xgetlist({'idx' : 0}).idx)
487endfunc
488
489func Test_browse()
490  call Xtest_browse('c')
491  call Xtest_browse('l')
492endfunc
493
494func Test_nomem()
495  call test_alloc_fail(GetAllocId('qf_dirname_start'), 0, 0)
496  call assert_fails('vimgrep vim runtest.vim', 'E342:')
497
498  call test_alloc_fail(GetAllocId('qf_dirname_now'), 0, 0)
499  call assert_fails('vimgrep vim runtest.vim', 'E342:')
500
501  call test_alloc_fail(GetAllocId('qf_namebuf'), 0, 0)
502  call assert_fails('cfile runtest.vim', 'E342:')
503
504  call test_alloc_fail(GetAllocId('qf_errmsg'), 0, 0)
505  call assert_fails('cfile runtest.vim', 'E342:')
506
507  call test_alloc_fail(GetAllocId('qf_pattern'), 0, 0)
508  call assert_fails('cfile runtest.vim', 'E342:')
509
510endfunc
511
512func s:test_xhelpgrep(cchar)
513  call s:setup_commands(a:cchar)
514  Xhelpgrep quickfix
515  Xopen
516  if a:cchar == 'c'
517    let title_text = ':helpgrep quickfix'
518  else
519    let title_text = ':lhelpgrep quickfix'
520  endif
521  call assert_true(w:quickfix_title =~ title_text, w:quickfix_title)
522
523  " Jumping to a help topic should open the help window
524  only
525  Xnext
526  call assert_true(&buftype == 'help')
527  call assert_true(winnr('$') == 2)
528  " Jumping to the next match should reuse the help window
529  Xnext
530  call assert_true(&buftype == 'help')
531  call assert_true(winnr() == 1)
532  call assert_true(winnr('$') == 2)
533  " Jumping to the next match from the quickfix window should reuse the help
534  " window
535  Xopen
536  Xnext
537  call assert_true(&buftype == 'help')
538  call assert_true(winnr() == 1)
539  call assert_true(winnr('$') == 2)
540
541  " This wipes out the buffer, make sure that doesn't cause trouble.
542  Xclose
543
544  if a:cchar == 'l'
545      " When a help window is present, running :lhelpgrep should reuse the
546      " help window and not the current window
547      new | only
548      call g:Xsetlist([], 'f')
549      help index.txt
550      wincmd w
551      lhelpgrep quickfix
552      call assert_equal(1, winnr())
553      call assert_notequal([], getloclist(1))
554      call assert_equal([], getloclist(2))
555  endif
556
557  new | only
558
559  " Search for non existing help string
560  call assert_fails('Xhelpgrep a1b2c3', 'E480:')
561endfunc
562
563func Test_helpgrep()
564  call s:test_xhelpgrep('c')
565  helpclose
566  call s:test_xhelpgrep('l')
567endfunc
568
569func Test_errortitle()
570  augroup QfBufWinEnter
571    au!
572    au BufWinEnter * :let g:a=get(w:, 'quickfix_title', 'NONE')
573  augroup END
574  copen
575  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'')'}]
576  call setqflist(a)
577  call assert_equal(':setqflist()', g:a)
578  augroup QfBufWinEnter
579    au!
580  augroup END
581  augroup! QfBufWinEnter
582endfunc
583
584func Test_vimgreptitle()
585  augroup QfBufWinEnter
586    au!
587    au BufWinEnter * :let g:a=get(w:, 'quickfix_title', 'NONE')
588  augroup END
589  try
590    vimgrep /pattern/j file
591  catch /E480/
592  endtry
593  copen
594  call assert_equal(':    vimgrep /pattern/j file', g:a)
595  augroup QfBufWinEnter
596    au!
597  augroup END
598  augroup! QfBufWinEnter
599endfunc
600
601func XqfTitleTests(cchar)
602  call s:setup_commands(a:cchar)
603
604  Xgetexpr ['file:1:1:message']
605  let l = g:Xgetlist()
606  if a:cchar == 'c'
607    call setqflist(l, 'r')
608  else
609    call setloclist(0, l, 'r')
610  endif
611
612  Xopen
613  if a:cchar == 'c'
614    let title = ':setqflist()'
615  else
616    let title = ':setloclist()'
617  endif
618  call assert_equal(title, w:quickfix_title)
619  Xclose
620endfunc
621
622" Tests for quickfix window's title
623func Test_qf_title()
624  call XqfTitleTests('c')
625  call XqfTitleTests('l')
626endfunc
627
628" Tests for 'errorformat'
629func Test_efm()
630  let save_efm = &efm
631  set efm=%EEEE%m,%WWWW%m,%+CCCC%.%#,%-GGGG%.%#
632  cgetexpr ['WWWW', 'EEEE', 'CCCC']
633  let l = strtrans(string(map(getqflist(), '[v:val.text, v:val.valid]')))
634  call assert_equal("[['W', 1], ['E^@CCCC', 1]]", l)
635  cgetexpr ['WWWW', 'GGGG', 'EEEE', 'CCCC']
636  let l = strtrans(string(map(getqflist(), '[v:val.text, v:val.valid]')))
637  call assert_equal("[['W', 1], ['E^@CCCC', 1]]", l)
638  cgetexpr ['WWWW', 'GGGG', 'ZZZZ', 'EEEE', 'CCCC', 'YYYY']
639  let l = strtrans(string(map(getqflist(), '[v:val.text, v:val.valid]')))
640  call assert_equal("[['W', 1], ['ZZZZ', 0], ['E^@CCCC', 1], ['YYYY', 0]]", l)
641  let &efm = save_efm
642endfunc
643
644" This will test for problems in quickfix:
645" A. incorrectly copying location lists which caused the location list to show
646"    a different name than the file that was actually being displayed.
647" B. not reusing the window for which the location list window is opened but
648"    instead creating new windows.
649" C. make sure that the location list window is not reused instead of the
650"    window it belongs to.
651"
652" Set up the test environment:
653func ReadTestProtocol(name)
654  let base = substitute(a:name, '\v^test://(.*)%(\.[^.]+)?', '\1', '')
655  let word = substitute(base, '\v(.*)\..*', '\1', '')
656
657  setl modifiable
658  setl noreadonly
659  setl noswapfile
660  setl bufhidden=delete
661  %del _
662  " For problem 2:
663  " 'buftype' has to be set to reproduce the constant opening of new windows
664  setl buftype=nofile
665
666  call setline(1, word)
667
668  setl nomodified
669  setl nomodifiable
670  setl readonly
671  exe 'doautocmd BufRead ' . substitute(a:name, '\v^test://(.*)', '\1', '')
672endfunc
673
674func Test_locationlist()
675    enew
676
677    augroup testgroup
678      au!
679      autocmd BufReadCmd test://* call ReadTestProtocol(expand("<amatch>"))
680    augroup END
681
682    let words = [ "foo", "bar", "baz", "quux", "shmoo", "spam", "eggs" ]
683
684    let qflist = []
685    for word in words
686      call add(qflist, {'filename': 'test://' . word . '.txt', 'text': 'file ' . word . '.txt', })
687      " NOTE: problem 1:
688      " intentionally not setting 'lnum' so that the quickfix entries are not
689      " valid
690      call setloclist(0, qflist, ' ')
691    endfor
692
693    " Test A
694    lrewind
695    enew
696    lopen
697    4lnext
698    vert split
699    wincmd L
700    lopen
701    wincmd p
702    lnext
703    let fileName = expand("%")
704    wincmd p
705    let locationListFileName = substitute(getline(line('.')), '\([^|]*\)|.*', '\1', '')
706    let fileName = substitute(fileName, '\\', '/', 'g')
707    let locationListFileName = substitute(locationListFileName, '\\', '/', 'g')
708    call assert_equal("test://bar.txt", fileName)
709    call assert_equal("test://bar.txt", locationListFileName)
710
711    wincmd n | only
712
713    " Test B:
714    lrewind
715    lopen
716    2
717    exe "normal \<CR>"
718    wincmd p
719    3
720    exe "normal \<CR>"
721    wincmd p
722    4
723    exe "normal \<CR>"
724    call assert_equal(2, winnr('$'))
725    wincmd n | only
726
727    " Test C:
728    lrewind
729    lopen
730    " Let's move the location list window to the top to check whether it (the
731    " first window found) will be reused when we try to open new windows:
732    wincmd K
733    2
734    exe "normal \<CR>"
735    wincmd p
736    3
737    exe "normal \<CR>"
738    wincmd p
739    4
740    exe "normal \<CR>"
741    1wincmd w
742    call assert_equal('quickfix', &buftype)
743    2wincmd w
744    let bufferName = expand("%")
745    let bufferName = substitute(bufferName, '\\', '/', 'g')
746    call assert_equal('test://quux.txt', bufferName)
747
748    wincmd n | only
749
750    augroup! testgroup
751endfunc
752
753func Test_locationlist_curwin_was_closed()
754    augroup testgroup
755      au!
756      autocmd BufReadCmd test_curwin.txt call R(expand("<amatch>"))
757    augroup END
758
759    func! R(n)
760      quit
761    endfunc
762
763    new
764    let q = []
765    call add(q, {'filename': 'test_curwin.txt' })
766    call setloclist(0, q)
767    call assert_fails('lrewind', 'E924:')
768
769    augroup! testgroup
770endfunc
771
772func Test_locationlist_cross_tab_jump()
773  call writefile(['loclistfoo'], 'loclistfoo')
774  call writefile(['loclistbar'], 'loclistbar')
775  set switchbuf=usetab
776
777  edit loclistfoo
778  tabedit loclistbar
779  silent lgrep loclistfoo loclist*
780  call assert_equal(1, tabpagenr())
781
782  enew | only | tabonly
783  set switchbuf&vim
784  call delete('loclistfoo')
785  call delete('loclistbar')
786endfunc
787
788" More tests for 'errorformat'
789func Test_efm1()
790    if !has('unix')
791	" The 'errorformat' setting is different on non-Unix systems.
792	" This test works only on Unix-like systems.
793	return
794    endif
795
796    let l = [
797      \ '"Xtestfile", line 4.12: 1506-045 (S) Undeclared identifier fd_set.',
798      \ '"Xtestfile", line 6 col 19; this is an error',
799      \ 'gcc -c -DHAVE_CONFIsing-prototypes -I/usr/X11R6/include  version.c',
800      \ 'Xtestfile:9: parse error before `asd''',
801      \ 'make: *** [vim] Error 1',
802      \ 'in file "Xtestfile" linenr 10: there is an error',
803      \ '',
804      \ '2 returned',
805      \ '"Xtestfile", line 11 col 1; this is an error',
806      \ '"Xtestfile", line 12 col 2; this is another error',
807      \ '"Xtestfile", line 14:10; this is an error in column 10',
808      \ '=Xtestfile=, line 15:10; this is another error, but in vcol 10 this time',
809      \ '"Xtestfile", linenr 16: yet another problem',
810      \ 'Error in "Xtestfile" at line 17:',
811      \ 'x should be a dot',
812      \ '	xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx    line 17',
813      \ '            ^',
814      \ 'Error in "Xtestfile" at line 18:',
815      \ 'x should be a dot',
816      \ '	xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx    line 18',
817      \ '.............^',
818      \ 'Error in "Xtestfile" at line 19:',
819      \ 'x should be a dot',
820      \ '	xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx    line 19',
821      \ '--------------^',
822      \ 'Error in "Xtestfile" at line 20:',
823      \ 'x should be a dot',
824      \ '	xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx    line 20',
825      \ '	       ^',
826      \ '',
827      \ 'Does anyone know what is the problem and how to correction it?',
828      \ '"Xtestfile", line 21 col 9: What is the title of the quickfix window?',
829      \ '"Xtestfile", line 22 col 9: What is the title of the quickfix window?'
830      \ ]
831
832    call writefile(l, 'Xerrorfile1')
833    call writefile(l[:-2], 'Xerrorfile2')
834
835    let m = [
836	\ '	xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx    line  2',
837	\ '	xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx    line  3',
838	\ '	xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx    line  4',
839	\ '	xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx    line  5',
840	\ '	xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx    line  6',
841	\ '	xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx    line  7',
842	\ '	xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx    line  8',
843	\ '	xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx    line  9',
844	\ '	xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx    line 10',
845	\ '	xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx    line 11',
846	\ '	xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx    line 12',
847	\ '	xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx    line 13',
848	\ '	xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx    line 14',
849	\ '	xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx    line 15',
850	\ '	xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx    line 16',
851	\ '	xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx    line 17',
852	\ '	xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx    line 18',
853	\ '	xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx    line 19',
854	\ '	xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx    line 20',
855	\ '	xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx    line 21',
856	\ '	xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx    line 22'
857	\ ]
858    call writefile(m, 'Xtestfile')
859
860    let save_efm = &efm
861    set efm+==%f=\\,\ line\ %l%*\\D%v%*[^\ ]\ %m
862    set efm^=%AError\ in\ \"%f\"\ at\ line\ %l:,%Z%p^,%C%m
863
864    exe 'cf Xerrorfile2'
865    clast
866    copen
867    call assert_equal(':cf Xerrorfile2', w:quickfix_title)
868    wincmd p
869
870    exe 'cf Xerrorfile1'
871    call assert_equal([4, 12], [line('.'), col('.')])
872    cn
873    call assert_equal([6, 19], [line('.'), col('.')])
874    cn
875    call assert_equal([9, 2], [line('.'), col('.')])
876    cn
877    call assert_equal([10, 2], [line('.'), col('.')])
878    cn
879    call assert_equal([11, 1], [line('.'), col('.')])
880    cn
881    call assert_equal([12, 2], [line('.'), col('.')])
882    cn
883    call assert_equal([14, 10], [line('.'), col('.')])
884    cn
885    call assert_equal([15, 3, 10], [line('.'), col('.'), virtcol('.')])
886    cn
887    call assert_equal([16, 2], [line('.'), col('.')])
888    cn
889    call assert_equal([17, 6], [line('.'), col('.')])
890    cn
891    call assert_equal([18, 7], [line('.'), col('.')])
892    cn
893    call assert_equal([19, 8], [line('.'), col('.')])
894    cn
895    call assert_equal([20, 9], [line('.'), col('.')])
896    clast
897    cprev
898    cprev
899    wincmd w
900    call assert_equal(':cf Xerrorfile1', w:quickfix_title)
901    wincmd p
902
903    let &efm = save_efm
904    call delete('Xerrorfile1')
905    call delete('Xerrorfile2')
906    call delete('Xtestfile')
907endfunc
908
909" Test for quickfix directory stack support
910func s:dir_stack_tests(cchar)
911  call s:setup_commands(a:cchar)
912
913  let save_efm=&efm
914  set efm=%DEntering\ dir\ '%f',%f:%l:%m,%XLeaving\ dir\ '%f'
915
916  let lines = ["Entering dir 'dir1/a'",
917		\ 'habits2.txt:1:Nine Healthy Habits',
918		\ "Entering dir 'b'",
919		\ 'habits3.txt:2:0 Hours of television',
920		\ 'habits2.txt:7:5 Small meals',
921		\ "Entering dir 'dir1/c'",
922		\ 'habits4.txt:3:1 Hour of exercise',
923		\ "Leaving dir 'dir1/c'",
924		\ "Leaving dir 'dir1/a'",
925		\ 'habits1.txt:4:2 Liters of water',
926		\ "Entering dir 'dir2'",
927		\ 'habits5.txt:5:3 Cups of hot green tea',
928		\ "Leaving dir 'dir2'"
929		\]
930
931  Xexpr ""
932  for l in lines
933      Xaddexpr l
934  endfor
935
936  let qf = g:Xgetlist()
937
938  call assert_equal('dir1/a/habits2.txt', bufname(qf[1].bufnr))
939  call assert_equal(1, qf[1].lnum)
940  call assert_equal('dir1/a/b/habits3.txt', bufname(qf[3].bufnr))
941  call assert_equal(2, qf[3].lnum)
942  call assert_equal('dir1/a/habits2.txt', bufname(qf[4].bufnr))
943  call assert_equal(7, qf[4].lnum)
944  call assert_equal('dir1/c/habits4.txt', bufname(qf[6].bufnr))
945  call assert_equal(3, qf[6].lnum)
946  call assert_equal('habits1.txt', bufname(qf[9].bufnr))
947  call assert_equal(4, qf[9].lnum)
948  call assert_equal('dir2/habits5.txt', bufname(qf[11].bufnr))
949  call assert_equal(5, qf[11].lnum)
950
951  let &efm=save_efm
952endfunc
953
954" Tests for %D and %X errorformat options
955func Test_efm_dirstack()
956  " Create the directory stack and files
957  call mkdir('dir1')
958  call mkdir('dir1/a')
959  call mkdir('dir1/a/b')
960  call mkdir('dir1/c')
961  call mkdir('dir2')
962
963  let lines = ["Nine Healthy Habits",
964		\ "0 Hours of television",
965		\ "1 Hour of exercise",
966		\ "2 Liters of water",
967		\ "3 Cups of hot green tea",
968		\ "4 Short mental breaks",
969		\ "5 Small meals",
970		\ "6 AM wake up time",
971		\ "7 Minutes of laughter",
972		\ "8 Hours of sleep (at least)",
973		\ "9 PM end of the day and off to bed"
974		\ ]
975  call writefile(lines, 'habits1.txt')
976  call writefile(lines, 'dir1/a/habits2.txt')
977  call writefile(lines, 'dir1/a/b/habits3.txt')
978  call writefile(lines, 'dir1/c/habits4.txt')
979  call writefile(lines, 'dir2/habits5.txt')
980
981  call s:dir_stack_tests('c')
982  call s:dir_stack_tests('l')
983
984  call delete('dir1', 'rf')
985  call delete('dir2', 'rf')
986  call delete('habits1.txt')
987endfunc
988
989" Test for resync after continuing an ignored message
990func Xefm_ignore_continuations(cchar)
991  call s:setup_commands(a:cchar)
992
993  let save_efm = &efm
994
995  let &efm =
996	\ '%Eerror %m %l,' .
997	\ '%-Wignored %m %l,' .
998	\ '%+Cmore ignored %m %l,' .
999	\ '%Zignored end'
1000  Xgetexpr ['ignored warning 1', 'more ignored continuation 2', 'ignored end', 'error resync 4']
1001  let l = map(g:Xgetlist(), '[v:val.text, v:val.valid, v:val.lnum, v:val.type]')
1002  call assert_equal([['resync', 1, 4, 'E']], l)
1003
1004  let &efm = save_efm
1005endfunc
1006
1007func Test_efm_ignore_continuations()
1008  call Xefm_ignore_continuations('c')
1009  call Xefm_ignore_continuations('l')
1010endfunc
1011
1012" Tests for invalid error format specifies
1013func Xinvalid_efm_Tests(cchar)
1014  call s:setup_commands(a:cchar)
1015
1016  let save_efm = &efm
1017
1018  set efm=%f:%l:%m,%f:%f:%l:%m
1019  call assert_fails('Xexpr "abc.txt:1:Hello world"', 'E372:')
1020
1021  set efm=%f:%l:%m,%f:%l:%r:%m
1022  call assert_fails('Xexpr "abc.txt:1:Hello world"', 'E373:')
1023
1024  set efm=%f:%l:%m,%O:%f:%l:%m
1025  call assert_fails('Xexpr "abc.txt:1:Hello world"', 'E373:')
1026
1027  set efm=%f:%l:%m,%f:%l:%*[^a-z
1028  call assert_fails('Xexpr "abc.txt:1:Hello world"', 'E374:')
1029
1030  set efm=%f:%l:%m,%f:%l:%*c
1031  call assert_fails('Xexpr "abc.txt:1:Hello world"', 'E375:')
1032
1033  set efm=%f:%l:%m,%L%M%N
1034  call assert_fails('Xexpr "abc.txt:1:Hello world"', 'E376:')
1035
1036  set efm=%f:%l:%m,%f:%l:%m:%R
1037  call assert_fails('Xexpr "abc.txt:1:Hello world"', 'E377:')
1038
1039  set efm=
1040  call assert_fails('Xexpr "abc.txt:1:Hello world"', 'E378:')
1041
1042  set efm=%DEntering\ dir\ abc,%f:%l:%m
1043  call assert_fails('Xexpr ["Entering dir abc", "abc.txt:1:Hello world"]', 'E379:')
1044
1045  let &efm = save_efm
1046endfunc
1047
1048func Test_invalid_efm()
1049  call Xinvalid_efm_Tests('c')
1050  call Xinvalid_efm_Tests('l')
1051endfunc
1052
1053" TODO:
1054" Add tests for the following formats in 'errorformat'
1055"	%r  %O
1056func Test_efm2()
1057  let save_efm = &efm
1058
1059  " Test for %s format in efm
1060  set efm=%f:%s
1061  cexpr 'Xtestfile:Line search text'
1062  let l = getqflist()
1063  call assert_equal(l[0].pattern, '^\VLine search text\$')
1064  call assert_equal(l[0].lnum, 0)
1065
1066  let l = split(execute('clist', ''), "\n")
1067  call assert_equal([' 1 Xtestfile:^\VLine search text\$:  '], l)
1068
1069  " Test for %P, %Q and %t format specifiers
1070  let lines=["[Xtestfile1]",
1071	      \ "(1,17)  error: ';' missing",
1072	      \ "(21,2)  warning: variable 'z' not defined",
1073	      \ "(67,3)  error: end of file found before string ended",
1074	      \ "--",
1075	      \ "",
1076	      \ "[Xtestfile2]",
1077	      \ "--",
1078	      \ "",
1079	      \ "[Xtestfile3]",
1080	      \ "NEW compiler v1.1",
1081	      \ "(2,2)   warning: variable 'x' not defined",
1082	      \ "(67,3)  warning: 's' already defined",
1083	      \ "--"
1084	      \]
1085  set efm=%+P[%f]%r,(%l\\,%c)%*[\ ]%t%*[^:]:\ %m,%+Q--%r
1086  " To exercise the push/pop file functionality in quickfix, the test files
1087  " need to be created.
1088  call writefile(['Line1'], 'Xtestfile1')
1089  call writefile(['Line2'], 'Xtestfile2')
1090  call writefile(['Line3'], 'Xtestfile3')
1091  cexpr ""
1092  for l in lines
1093      caddexpr l
1094  endfor
1095  let l = getqflist()
1096  call assert_equal(12, len(l))
1097  call assert_equal(21, l[2].lnum)
1098  call assert_equal(2, l[2].col)
1099  call assert_equal('w', l[2].type)
1100  call assert_equal('e', l[3].type)
1101  call delete('Xtestfile1')
1102  call delete('Xtestfile2')
1103  call delete('Xtestfile3')
1104
1105  " Tests for %E, %C and %Z format specifiers
1106  let lines = ["Error 275",
1107	      \ "line 42",
1108	      \ "column 3",
1109	      \ "' ' expected after '--'"
1110	      \]
1111  set efm=%EError\ %n,%Cline\ %l,%Ccolumn\ %c,%Z%m
1112  cgetexpr lines
1113  let l = getqflist()
1114  call assert_equal(275, l[0].nr)
1115  call assert_equal(42, l[0].lnum)
1116  call assert_equal(3, l[0].col)
1117  call assert_equal('E', l[0].type)
1118  call assert_equal("\n' ' expected after '--'", l[0].text)
1119
1120  " Test for %>
1121  let lines = ["Error in line 147 of foo.c:",
1122	      \"unknown variable 'i'"
1123	      \]
1124  set efm=unknown\ variable\ %m,%E%>Error\ in\ line\ %l\ of\ %f:,%Z%m
1125  cgetexpr lines
1126  let l = getqflist()
1127  call assert_equal(147, l[0].lnum)
1128  call assert_equal('E', l[0].type)
1129  call assert_equal("\nunknown variable 'i'", l[0].text)
1130
1131  " Test for %A, %C and other formats
1132  let lines = [
1133	  \"==============================================================",
1134	  \"FAIL: testGetTypeIdCachesResult (dbfacadeTest.DjsDBFacadeTest)",
1135	  \"--------------------------------------------------------------",
1136	  \"Traceback (most recent call last):",
1137	  \'  File "unittests/dbfacadeTest.py", line 89, in testFoo',
1138	  \"    self.assertEquals(34, dtid)",
1139	  \'  File "/usr/lib/python2.2/unittest.py", line 286, in',
1140	  \" failUnlessEqual",
1141	  \"    raise self.failureException, \\",
1142	  \"AssertionError: 34 != 33",
1143	  \"",
1144	  \"--------------------------------------------------------------",
1145	  \"Ran 27 tests in 0.063s"
1146	  \]
1147  set efm=%C\ %.%#,%A\ \ File\ \"%f\"\\,\ line\ %l%.%#,%Z%[%^\ ]%\\@=%m
1148  cgetexpr lines
1149  let l = getqflist()
1150  call assert_equal(8, len(l))
1151  call assert_equal(89, l[4].lnum)
1152  call assert_equal(1, l[4].valid)
1153  call assert_equal('unittests/dbfacadeTest.py', bufname(l[4].bufnr))
1154
1155  " Test for %o
1156  set efm=%f(%o):%l\ %m
1157  cgetexpr ['Xotestfile(Language.PureScript.Types):20 Error']
1158  call writefile(['Line1'], 'Xotestfile')
1159  let l = getqflist()
1160  call assert_equal(1, len(l), string(l))
1161  call assert_equal('Language.PureScript.Types', l[0].module)
1162  copen
1163  call assert_equal('Language.PureScript.Types|20| Error', getline(1))
1164  call feedkeys("\<CR>", 'xn')
1165  call assert_equal('Xotestfile', expand('%:t'))
1166  cclose
1167  bd
1168  call delete("Xotestfile")
1169
1170  " The following sequence of commands used to crash Vim
1171  set efm=%W%m
1172  cgetexpr ['msg1']
1173  let l = getqflist()
1174  call assert_equal(1, len(l), string(l))
1175  call assert_equal('msg1', l[0].text)
1176  set efm=%C%m
1177  lexpr 'msg2'
1178  let l = getloclist(0)
1179  call assert_equal(1, len(l), string(l))
1180  call assert_equal('msg2', l[0].text)
1181  lopen
1182  call setqflist([], 'r')
1183  caddbuf
1184  let l = getqflist()
1185  call assert_equal(1, len(l), string(l))
1186  call assert_equal('|| msg2', l[0].text)
1187
1188  " When matching error lines, case should be ignored. Test for this.
1189  set noignorecase
1190  let l=getqflist({'lines' : ['Xtest:FOO10:Line 20'], 'efm':'%f:foo%l:%m'})
1191  call assert_equal(10, l.items[0].lnum)
1192  call assert_equal('Line 20', l.items[0].text)
1193  set ignorecase&
1194
1195  new | only
1196  let &efm = save_efm
1197endfunc
1198
1199func XquickfixChangedByAutocmd(cchar)
1200  call s:setup_commands(a:cchar)
1201  if a:cchar == 'c'
1202    let ErrorNr = 'E925'
1203    func! ReadFunc()
1204      colder
1205      cgetexpr []
1206    endfunc
1207  else
1208    let ErrorNr = 'E926'
1209    func! ReadFunc()
1210      lolder
1211      lgetexpr []
1212    endfunc
1213  endif
1214
1215  augroup testgroup
1216    au!
1217    autocmd BufReadCmd test_changed.txt call ReadFunc()
1218  augroup END
1219
1220  new | only
1221  let words = [ "a", "b" ]
1222  let qflist = []
1223  for word in words
1224    call add(qflist, {'filename': 'test_changed.txt'})
1225    call g:Xsetlist(qflist, ' ')
1226  endfor
1227  call assert_fails('Xrewind', ErrorNr . ':')
1228
1229  augroup! testgroup
1230endfunc
1231
1232func Test_quickfix_was_changed_by_autocmd()
1233  call XquickfixChangedByAutocmd('c')
1234  call XquickfixChangedByAutocmd('l')
1235endfunc
1236
1237func Test_caddbuffer_to_empty()
1238  helpgr quickfix
1239  call setqflist([], 'r')
1240  cad
1241  try
1242    cn
1243  catch
1244    " number of matches is unknown
1245    call assert_true(v:exception =~ 'E553:')
1246  endtry
1247  quit!
1248endfunc
1249
1250func Test_cgetexpr_works()
1251  " this must not crash Vim
1252  cgetexpr [$x]
1253  lgetexpr [$x]
1254endfunc
1255
1256" Tests for the setqflist() and setloclist() functions
1257func SetXlistTests(cchar, bnum)
1258  call s:setup_commands(a:cchar)
1259
1260  call g:Xsetlist([{'bufnr': a:bnum, 'lnum': 1},
1261	      \  {'bufnr': a:bnum, 'lnum': 2}])
1262  let l = g:Xgetlist()
1263  call assert_equal(2, len(l))
1264  call assert_equal(2, l[1].lnum)
1265
1266  Xnext
1267  call g:Xsetlist([{'bufnr': a:bnum, 'lnum': 3}], 'a')
1268  let l = g:Xgetlist()
1269  call assert_equal(3, len(l))
1270  Xnext
1271  call assert_equal(3, line('.'))
1272
1273  " Appending entries to the list should not change the cursor position
1274  " in the quickfix window
1275  Xwindow
1276  1
1277  call g:Xsetlist([{'bufnr': a:bnum, 'lnum': 4},
1278	      \  {'bufnr': a:bnum, 'lnum': 5}], 'a')
1279  call assert_equal(1, line('.'))
1280  close
1281
1282  call g:Xsetlist([{'bufnr': a:bnum, 'lnum': 3},
1283	      \  {'bufnr': a:bnum, 'lnum': 4},
1284	      \  {'bufnr': a:bnum, 'lnum': 5}], 'r')
1285  let l = g:Xgetlist()
1286  call assert_equal(3, len(l))
1287  call assert_equal(5, l[2].lnum)
1288
1289  call g:Xsetlist([])
1290  let l = g:Xgetlist()
1291  call assert_equal(0, len(l))
1292
1293  " Tests for setting the 'valid' flag
1294  call g:Xsetlist([{'bufnr':a:bnum, 'lnum':4, 'valid':0}])
1295  Xwindow
1296  call assert_equal(1, winnr('$'))
1297  let l = g:Xgetlist()
1298  call g:Xsetlist(l)
1299  call assert_equal(0, g:Xgetlist()[0].valid)
1300  call g:Xsetlist([{'text':'Text1', 'valid':1}])
1301  Xwindow
1302  call assert_equal(2, winnr('$'))
1303  Xclose
1304  let save_efm = &efm
1305  set efm=%m
1306  Xgetexpr 'TestMessage'
1307  let l = g:Xgetlist()
1308  call g:Xsetlist(l)
1309  call assert_equal(1, g:Xgetlist()[0].valid)
1310  let &efm = save_efm
1311
1312  " Error cases:
1313  " Refer to a non-existing buffer and pass a non-dictionary type
1314  call assert_fails("call g:Xsetlist([{'bufnr':998, 'lnum':4}," .
1315	      \ " {'bufnr':999, 'lnum':5}])", 'E92:')
1316  call g:Xsetlist([[1, 2,3]])
1317  call assert_equal(0, len(g:Xgetlist()))
1318endfunc
1319
1320func Test_setqflist()
1321  new Xtestfile | only
1322  let bnum = bufnr('%')
1323  call setline(1, range(1,5))
1324
1325  call SetXlistTests('c', bnum)
1326  call SetXlistTests('l', bnum)
1327
1328  enew!
1329  call delete('Xtestfile')
1330endfunc
1331
1332func Xlist_empty_middle(cchar)
1333  call s:setup_commands(a:cchar)
1334
1335  " create three quickfix lists
1336  let @/ = 'Test_'
1337  Xvimgrep // test_quickfix.vim
1338  let testlen = len(g:Xgetlist())
1339  call assert_true(testlen > 0)
1340  Xvimgrep empty test_quickfix.vim
1341  call assert_true(len(g:Xgetlist()) > 0)
1342  Xvimgrep matches test_quickfix.vim
1343  let matchlen = len(g:Xgetlist())
1344  call assert_true(matchlen > 0)
1345  Xolder
1346  " make the middle list empty
1347  call g:Xsetlist([], 'r')
1348  call assert_true(len(g:Xgetlist()) == 0)
1349  Xolder
1350  call assert_equal(testlen, len(g:Xgetlist()))
1351  Xnewer
1352  Xnewer
1353  call assert_equal(matchlen, len(g:Xgetlist()))
1354endfunc
1355
1356func Test_setqflist_empty_middle()
1357  call Xlist_empty_middle('c')
1358  call Xlist_empty_middle('l')
1359endfunc
1360
1361func Xlist_empty_older(cchar)
1362  call s:setup_commands(a:cchar)
1363
1364  " create three quickfix lists
1365  Xvimgrep one test_quickfix.vim
1366  let onelen = len(g:Xgetlist())
1367  call assert_true(onelen > 0)
1368  Xvimgrep two test_quickfix.vim
1369  let twolen = len(g:Xgetlist())
1370  call assert_true(twolen > 0)
1371  Xvimgrep three test_quickfix.vim
1372  let threelen = len(g:Xgetlist())
1373  call assert_true(threelen > 0)
1374  Xolder 2
1375  " make the first list empty, check the others didn't change
1376  call g:Xsetlist([], 'r')
1377  call assert_true(len(g:Xgetlist()) == 0)
1378  Xnewer
1379  call assert_equal(twolen, len(g:Xgetlist()))
1380  Xnewer
1381  call assert_equal(threelen, len(g:Xgetlist()))
1382endfunc
1383
1384func Test_setqflist_empty_older()
1385  call Xlist_empty_older('c')
1386  call Xlist_empty_older('l')
1387endfunc
1388
1389func XquickfixSetListWithAct(cchar)
1390  call s:setup_commands(a:cchar)
1391
1392  let list1 = [{'filename': 'fnameA', 'text': 'A'},
1393          \    {'filename': 'fnameB', 'text': 'B'}]
1394  let list2 = [{'filename': 'fnameC', 'text': 'C'},
1395          \    {'filename': 'fnameD', 'text': 'D'},
1396          \    {'filename': 'fnameE', 'text': 'E'}]
1397
1398  " {action} is unspecified.  Same as specifing ' '.
1399  new | only
1400  silent! Xnewer 99
1401  call g:Xsetlist(list1)
1402  call g:Xsetlist(list2)
1403  let li = g:Xgetlist()
1404  call assert_equal(3, len(li))
1405  call assert_equal('C', li[0]['text'])
1406  call assert_equal('D', li[1]['text'])
1407  call assert_equal('E', li[2]['text'])
1408  silent! Xolder
1409  let li = g:Xgetlist()
1410  call assert_equal(2, len(li))
1411  call assert_equal('A', li[0]['text'])
1412  call assert_equal('B', li[1]['text'])
1413
1414  " {action} is specified ' '.
1415  new | only
1416  silent! Xnewer 99
1417  call g:Xsetlist(list1)
1418  call g:Xsetlist(list2, ' ')
1419  let li = g:Xgetlist()
1420  call assert_equal(3, len(li))
1421  call assert_equal('C', li[0]['text'])
1422  call assert_equal('D', li[1]['text'])
1423  call assert_equal('E', li[2]['text'])
1424  silent! Xolder
1425  let li = g:Xgetlist()
1426  call assert_equal(2, len(li))
1427  call assert_equal('A', li[0]['text'])
1428  call assert_equal('B', li[1]['text'])
1429
1430  " {action} is specified 'a'.
1431  new | only
1432  silent! Xnewer 99
1433  call g:Xsetlist(list1)
1434  call g:Xsetlist(list2, 'a')
1435  let li = g:Xgetlist()
1436  call assert_equal(5, len(li))
1437  call assert_equal('A', li[0]['text'])
1438  call assert_equal('B', li[1]['text'])
1439  call assert_equal('C', li[2]['text'])
1440  call assert_equal('D', li[3]['text'])
1441  call assert_equal('E', li[4]['text'])
1442
1443  " {action} is specified 'r'.
1444  new | only
1445  silent! Xnewer 99
1446  call g:Xsetlist(list1)
1447  call g:Xsetlist(list2, 'r')
1448  let li = g:Xgetlist()
1449  call assert_equal(3, len(li))
1450  call assert_equal('C', li[0]['text'])
1451  call assert_equal('D', li[1]['text'])
1452  call assert_equal('E', li[2]['text'])
1453
1454  " Test for wrong value.
1455  new | only
1456  call assert_fails("call g:Xsetlist(0)", 'E714:')
1457  call assert_fails("call g:Xsetlist(list1, '')", 'E927:')
1458  call assert_fails("call g:Xsetlist(list1, 'aa')", 'E927:')
1459  call assert_fails("call g:Xsetlist(list1, ' a')", 'E927:')
1460  call assert_fails("call g:Xsetlist(list1, 0)", 'E928:')
1461endfunc
1462
1463func Test_setqflist_invalid_nr()
1464  " The following command used to crash Vim
1465  call setqflist([], ' ', {'nr' : $XXX_DOES_NOT_EXIST})
1466endfunc
1467
1468func Test_quickfix_set_list_with_act()
1469  call XquickfixSetListWithAct('c')
1470  call XquickfixSetListWithAct('l')
1471endfunc
1472
1473func XLongLinesTests(cchar)
1474  let l = g:Xgetlist()
1475
1476  call assert_equal(4, len(l))
1477  call assert_equal(1, l[0].lnum)
1478  call assert_equal(1, l[0].col)
1479  call assert_equal(1975, len(l[0].text))
1480  call assert_equal(2, l[1].lnum)
1481  call assert_equal(1, l[1].col)
1482  call assert_equal(4070, len(l[1].text))
1483  call assert_equal(3, l[2].lnum)
1484  call assert_equal(1, l[2].col)
1485  call assert_equal(4070, len(l[2].text))
1486  call assert_equal(4, l[3].lnum)
1487  call assert_equal(1, l[3].col)
1488  call assert_equal(10, len(l[3].text))
1489
1490  call g:Xsetlist([], 'r')
1491endfunc
1492
1493func s:long_lines_tests(cchar)
1494  call s:setup_commands(a:cchar)
1495
1496  let testfile = 'samples/quickfix.txt'
1497
1498  " file
1499  exe 'Xgetfile' testfile
1500  call XLongLinesTests(a:cchar)
1501
1502  " list
1503  Xexpr readfile(testfile)
1504  call XLongLinesTests(a:cchar)
1505
1506  " string
1507  Xexpr join(readfile(testfile), "\n")
1508  call XLongLinesTests(a:cchar)
1509
1510  " buffer
1511  exe 'edit' testfile
1512  exe 'Xbuffer' bufnr('%')
1513  call XLongLinesTests(a:cchar)
1514endfunc
1515
1516func Test_long_lines()
1517  call s:long_lines_tests('c')
1518  call s:long_lines_tests('l')
1519endfunc
1520
1521func s:create_test_file(filename)
1522  let l = []
1523  for i in range(1, 20)
1524      call add(l, 'Line' . i)
1525  endfor
1526  call writefile(l, a:filename)
1527endfunc
1528
1529func Test_switchbuf()
1530  call s:create_test_file('Xqftestfile1')
1531  call s:create_test_file('Xqftestfile2')
1532  call s:create_test_file('Xqftestfile3')
1533
1534  new | only
1535  edit Xqftestfile1
1536  let file1_winid = win_getid()
1537  new Xqftestfile2
1538  let file2_winid = win_getid()
1539  cgetexpr ['Xqftestfile1:5:Line5',
1540		\ 'Xqftestfile1:6:Line6',
1541		\ 'Xqftestfile2:10:Line10',
1542		\ 'Xqftestfile2:11:Line11',
1543		\ 'Xqftestfile3:15:Line15',
1544		\ 'Xqftestfile3:16:Line16']
1545
1546  new
1547  let winid = win_getid()
1548  cfirst | cnext
1549  call assert_equal(winid, win_getid())
1550  2cnext
1551  call assert_equal(winid, win_getid())
1552  2cnext
1553  call assert_equal(winid, win_getid())
1554  enew
1555
1556  set switchbuf=useopen
1557  cfirst | cnext
1558  call assert_equal(file1_winid, win_getid())
1559  2cnext
1560  call assert_equal(file2_winid, win_getid())
1561  2cnext
1562  call assert_equal(file2_winid, win_getid())
1563
1564  enew | only
1565  set switchbuf=usetab
1566  tabedit Xqftestfile1
1567  tabedit Xqftestfile2
1568  tabedit Xqftestfile3
1569  tabfirst
1570  cfirst | cnext
1571  call assert_equal(2, tabpagenr())
1572  2cnext
1573  call assert_equal(3, tabpagenr())
1574  6cnext
1575  call assert_equal(4, tabpagenr())
1576  2cpfile
1577  call assert_equal(2, tabpagenr())
1578  2cnfile
1579  call assert_equal(4, tabpagenr())
1580  tabfirst | tabonly | enew
1581
1582  set switchbuf=split
1583  cfirst | cnext
1584  call assert_equal(1, winnr('$'))
1585  cnext | cnext
1586  call assert_equal(2, winnr('$'))
1587  cnext | cnext
1588  call assert_equal(3, winnr('$'))
1589  enew | only
1590
1591  set switchbuf=newtab
1592  cfirst | cnext
1593  call assert_equal(1, tabpagenr('$'))
1594  cnext | cnext
1595  call assert_equal(2, tabpagenr('$'))
1596  cnext | cnext
1597  call assert_equal(3, tabpagenr('$'))
1598  tabfirst | enew | tabonly | only
1599
1600  set switchbuf=
1601  edit Xqftestfile1
1602  let file1_winid = win_getid()
1603  new Xqftestfile2
1604  let file2_winid = win_getid()
1605  copen
1606  exe "normal 1G\<CR>"
1607  call assert_equal(file1_winid, win_getid())
1608  copen
1609  exe "normal 3G\<CR>"
1610  call assert_equal(file2_winid, win_getid())
1611  copen | only
1612  exe "normal 5G\<CR>"
1613  call assert_equal(2, winnr('$'))
1614  call assert_equal(1, bufwinnr('Xqftestfile3'))
1615
1616  " If only quickfix window is open in the current tabpage, jumping to an
1617  " entry with 'switchubf' set to 'usetab' should search in other tabpages.
1618  enew | only
1619  set switchbuf=usetab
1620  tabedit Xqftestfile1
1621  tabedit Xqftestfile2
1622  tabedit Xqftestfile3
1623  tabfirst
1624  copen | only
1625  clast
1626  call assert_equal(4, tabpagenr())
1627  tabfirst | tabonly | enew | only
1628
1629  call delete('Xqftestfile1')
1630  call delete('Xqftestfile2')
1631  call delete('Xqftestfile3')
1632  set switchbuf&vim
1633
1634  enew | only
1635endfunc
1636
1637func Xadjust_qflnum(cchar)
1638  call s:setup_commands(a:cchar)
1639
1640  enew | only
1641
1642  let fname = 'Xqftestfile' . a:cchar
1643  call s:create_test_file(fname)
1644  exe 'edit ' . fname
1645
1646  Xgetexpr [fname . ':5:Line5',
1647	      \ fname . ':10:Line10',
1648	      \ fname . ':15:Line15',
1649	      \ fname . ':20:Line20']
1650
1651  6,14delete
1652  call append(6, ['Buffer', 'Window'])
1653
1654  let l = g:Xgetlist()
1655
1656  call assert_equal(5, l[0].lnum)
1657  call assert_equal(6, l[2].lnum)
1658  call assert_equal(13, l[3].lnum)
1659
1660  enew!
1661  call delete(fname)
1662endfunc
1663
1664func Test_adjust_lnum()
1665  call setloclist(0, [])
1666  call Xadjust_qflnum('c')
1667  call setqflist([])
1668  call Xadjust_qflnum('l')
1669endfunc
1670
1671" Tests for the :grep/:lgrep and :grepadd/:lgrepadd commands
1672func s:test_xgrep(cchar)
1673  call s:setup_commands(a:cchar)
1674
1675  " The following lines are used for the grep test. Don't remove.
1676  " Grep_Test_Text: Match 1
1677  " Grep_Test_Text: Match 2
1678  " GrepAdd_Test_Text: Match 1
1679  " GrepAdd_Test_Text: Match 2
1680  enew! | only
1681  set makeef&vim
1682  silent Xgrep Grep_Test_Text: test_quickfix.vim
1683  call assert_true(len(g:Xgetlist()) == 3)
1684  Xopen
1685  call assert_true(w:quickfix_title =~ '^:grep')
1686  Xclose
1687  enew
1688  set makeef=Temp_File_##
1689  silent Xgrepadd GrepAdd_Test_Text: test_quickfix.vim
1690  call assert_true(len(g:Xgetlist()) == 6)
1691endfunc
1692
1693func Test_grep()
1694  if !has('unix')
1695    " The grepprg may not be set on non-Unix systems
1696    return
1697  endif
1698
1699  call s:test_xgrep('c')
1700  call s:test_xgrep('l')
1701endfunc
1702
1703func Test_two_windows()
1704  " Use one 'errorformat' for two windows.  Add an expression to each of them,
1705  " make sure they each keep their own state.
1706  set efm=%DEntering\ dir\ '%f',%f:%l:%m,%XLeaving\ dir\ '%f'
1707  call mkdir('Xone/a', 'p')
1708  call mkdir('Xtwo/a', 'p')
1709  let lines = ['1', '2', 'one one one', '4', 'two two two', '6', '7']
1710  call writefile(lines, 'Xone/a/one.txt')
1711  call writefile(lines, 'Xtwo/a/two.txt')
1712
1713  new one
1714  let one_id = win_getid()
1715  lexpr ""
1716  new two
1717  let two_id = win_getid()
1718  lexpr ""
1719
1720  laddexpr "Entering dir 'Xtwo/a'"
1721  call win_gotoid(one_id)
1722  laddexpr "Entering dir 'Xone/a'"
1723  call win_gotoid(two_id)
1724  laddexpr 'two.txt:5:two two two'
1725  call win_gotoid(one_id)
1726  laddexpr 'one.txt:3:one one one'
1727
1728  let loc_one = getloclist(one_id)
1729  call assert_equal('Xone/a/one.txt', bufname(loc_one[1].bufnr))
1730  call assert_equal(3, loc_one[1].lnum)
1731
1732  let loc_two = getloclist(two_id)
1733  call assert_equal('Xtwo/a/two.txt', bufname(loc_two[1].bufnr))
1734  call assert_equal(5, loc_two[1].lnum)
1735
1736  call win_gotoid(one_id)
1737  bwipe!
1738  call win_gotoid(two_id)
1739  bwipe!
1740  call delete('Xone', 'rf')
1741  call delete('Xtwo', 'rf')
1742endfunc
1743
1744func XbottomTests(cchar)
1745  call s:setup_commands(a:cchar)
1746
1747  " Calling lbottom without any errors should fail
1748  if a:cchar == 'l'
1749      call assert_fails('lbottom', 'E776:')
1750  endif
1751
1752  call g:Xsetlist([{'filename': 'foo', 'lnum': 42}])
1753  Xopen
1754  let wid = win_getid()
1755  call assert_equal(1, line('.'))
1756  wincmd w
1757  call g:Xsetlist([{'filename': 'var', 'lnum': 24}], 'a')
1758  Xbottom
1759  call win_gotoid(wid)
1760  call assert_equal(2, line('.'))
1761  Xclose
1762endfunc
1763
1764" Tests for the :cbottom and :lbottom commands
1765func Test_cbottom()
1766  call XbottomTests('c')
1767  call XbottomTests('l')
1768endfunc
1769
1770func HistoryTest(cchar)
1771  call s:setup_commands(a:cchar)
1772
1773  " clear all lists after the first one, then replace the first one.
1774  call g:Xsetlist([])
1775  call assert_fails('Xolder 99', 'E380:')
1776  let entry = {'filename': 'foo', 'lnum': 42}
1777  call g:Xsetlist([entry], 'r')
1778  call g:Xsetlist([entry, entry])
1779  call g:Xsetlist([entry, entry, entry])
1780  let res = split(execute(a:cchar . 'hist'), "\n")
1781  call assert_equal(3, len(res))
1782  let common = 'errors     :set' . (a:cchar == 'c' ? 'qf' : 'loc') . 'list()'
1783  call assert_equal('  error list 1 of 3; 1 ' . common, res[0])
1784  call assert_equal('  error list 2 of 3; 2 ' . common, res[1])
1785  call assert_equal('> error list 3 of 3; 3 ' . common, res[2])
1786
1787  call g:Xsetlist([], 'f')
1788  let l = split(execute(a:cchar . 'hist'), "\n")
1789  call assert_equal('No entries', l[0])
1790endfunc
1791
1792func Test_history()
1793  call HistoryTest('c')
1794  call HistoryTest('l')
1795endfunc
1796
1797func Test_duplicate_buf()
1798  " make sure we can get the highest buffer number
1799  edit DoesNotExist
1800  edit DoesNotExist2
1801  let last_buffer = bufnr("$")
1802
1803  " make sure only one buffer is created
1804  call writefile(['this one', 'that one'], 'Xgrepthis')
1805  vimgrep one Xgrepthis
1806  vimgrep one Xgrepthis
1807  call assert_equal(last_buffer + 1, bufnr("$"))
1808
1809  call delete('Xgrepthis')
1810endfunc
1811
1812" Quickfix/Location list set/get properties tests
1813func Xproperty_tests(cchar)
1814    call s:setup_commands(a:cchar)
1815
1816    " Error cases
1817    call assert_fails('call g:Xgetlist(99)', 'E715:')
1818    call assert_fails('call g:Xsetlist(99)', 'E714:')
1819    call assert_fails('call g:Xsetlist([], "a", [])', 'E715:')
1820
1821    " Set and get the title
1822    call g:Xsetlist([])
1823    Xopen
1824    wincmd p
1825    call g:Xsetlist([{'filename':'foo', 'lnum':27}])
1826    let s = g:Xsetlist([], 'a', {'title' : 'Sample'})
1827    call assert_equal(0, s)
1828    let d = g:Xgetlist({"title":1})
1829    call assert_equal('Sample', d.title)
1830    " Try setting title to a non-string value
1831    call assert_equal(-1, g:Xsetlist([], 'a', {'title' : ['Test']}))
1832    call assert_equal('Sample', g:Xgetlist({"title":1}).title)
1833
1834    Xopen
1835    call assert_equal('Sample', w:quickfix_title)
1836    Xclose
1837
1838    " Tests for action argument
1839    silent! Xolder 999
1840    let qfnr = g:Xgetlist({'all':1}).nr
1841    call g:Xsetlist([], 'r', {'title' : 'N1'})
1842    call assert_equal('N1', g:Xgetlist({'all':1}).title)
1843    call g:Xsetlist([], ' ', {'title' : 'N2'})
1844    call assert_equal(qfnr + 1, g:Xgetlist({'all':1}).nr)
1845
1846    let res = g:Xgetlist({'nr': 0})
1847    call assert_equal(qfnr + 1, res.nr)
1848    call assert_equal(['nr'], keys(res))
1849
1850    call g:Xsetlist([], ' ', {'title' : 'N3'})
1851    call assert_equal('N2', g:Xgetlist({'nr':2, 'title':1}).title)
1852
1853    " Changing the title of an earlier quickfix list
1854    call g:Xsetlist([], 'r', {'title' : 'NewTitle', 'nr' : 2})
1855    call assert_equal('NewTitle', g:Xgetlist({'nr':2, 'title':1}).title)
1856
1857    " Changing the title of an invalid quickfix list
1858    call assert_equal(-1, g:Xsetlist([], ' ',
1859		\ {'title' : 'SomeTitle', 'nr' : 99}))
1860    call assert_equal(-1, g:Xsetlist([], ' ',
1861		\ {'title' : 'SomeTitle', 'nr' : 'abc'}))
1862
1863    if a:cchar == 'c'
1864	copen
1865	call assert_equal({'winid':win_getid()}, getqflist({'winid':1}))
1866	cclose
1867    endif
1868
1869    " Invalid arguments
1870    call assert_fails('call g:Xgetlist([])', 'E715')
1871    call assert_fails('call g:Xsetlist([], "a", [])', 'E715')
1872    let s = g:Xsetlist([], 'a', {'abc':1})
1873    call assert_equal(-1, s)
1874
1875    call assert_equal({}, g:Xgetlist({'abc':1}))
1876    call assert_equal('', g:Xgetlist({'nr':99, 'title':1}).title)
1877    call assert_equal('', g:Xgetlist({'nr':[], 'title':1}).title)
1878
1879    if a:cchar == 'l'
1880	call assert_equal({}, getloclist(99, {'title': 1}))
1881    endif
1882
1883    " Context related tests
1884    let s = g:Xsetlist([], 'a', {'context':[1,2,3]})
1885    call assert_equal(0, s)
1886    call test_garbagecollect_now()
1887    let d = g:Xgetlist({'context':1})
1888    call assert_equal([1,2,3], d.context)
1889    call g:Xsetlist([], 'a', {'context':{'color':'green'}})
1890    let d = g:Xgetlist({'context':1})
1891    call assert_equal({'color':'green'}, d.context)
1892    call g:Xsetlist([], 'a', {'context':"Context info"})
1893    let d = g:Xgetlist({'context':1})
1894    call assert_equal("Context info", d.context)
1895    call g:Xsetlist([], 'a', {'context':246})
1896    let d = g:Xgetlist({'context':1})
1897    call assert_equal(246, d.context)
1898    if a:cchar == 'l'
1899	" Test for copying context across two different location lists
1900	new | only
1901	let w1_id = win_getid()
1902	let l = [1]
1903	call setloclist(0, [], 'a', {'context':l})
1904	new
1905	let w2_id = win_getid()
1906	call add(l, 2)
1907	call assert_equal([1, 2], getloclist(w1_id, {'context':1}).context)
1908	call assert_equal([1, 2], getloclist(w2_id, {'context':1}).context)
1909	unlet! l
1910	call assert_equal([1, 2], getloclist(w2_id, {'context':1}).context)
1911	only
1912	call setloclist(0, [], 'f')
1913	call assert_equal('', getloclist(0, {'context':1}).context)
1914    endif
1915
1916    " Test for changing the context of previous quickfix lists
1917    call g:Xsetlist([], 'f')
1918    Xexpr "One"
1919    Xexpr "Two"
1920    Xexpr "Three"
1921    call g:Xsetlist([], 'r', {'context' : [1], 'nr' : 1})
1922    call g:Xsetlist([], 'a', {'context' : [2], 'nr' : 2})
1923    " Also, check for setting the context using quickfix list number zero.
1924    call g:Xsetlist([], 'r', {'context' : [3], 'nr' : 0})
1925    call test_garbagecollect_now()
1926    let l = g:Xgetlist({'nr' : 1, 'context' : 1})
1927    call assert_equal([1], l.context)
1928    let l = g:Xgetlist({'nr' : 2, 'context' : 1})
1929    call assert_equal([2], l.context)
1930    let l = g:Xgetlist({'nr' : 3, 'context' : 1})
1931    call assert_equal([3], l.context)
1932
1933    " Test for changing the context through reference and for garbage
1934    " collection of quickfix context
1935    let l = ["red"]
1936    call g:Xsetlist([], ' ', {'context' : l})
1937    call add(l, "blue")
1938    let x = g:Xgetlist({'context' : 1})
1939    call add(x.context, "green")
1940    call assert_equal(["red", "blue", "green"], l)
1941    call assert_equal(["red", "blue", "green"], x.context)
1942    unlet l
1943    call test_garbagecollect_now()
1944    let m = g:Xgetlist({'context' : 1})
1945    call assert_equal(["red", "blue", "green"], m.context)
1946
1947    " Test for setting/getting items
1948    Xexpr ""
1949    let qfprev = g:Xgetlist({'nr':0})
1950    let s = g:Xsetlist([], ' ', {'title':'Green',
1951		\ 'items' : [{'filename':'F1', 'lnum':10}]})
1952    call assert_equal(0, s)
1953    let qfcur = g:Xgetlist({'nr':0})
1954    call assert_true(qfcur.nr == qfprev.nr + 1)
1955    let l = g:Xgetlist({'items':1})
1956    call assert_equal('F1', bufname(l.items[0].bufnr))
1957    call assert_equal(10, l.items[0].lnum)
1958    call g:Xsetlist([], 'a', {'items' : [{'filename':'F2', 'lnum':20},
1959		\  {'filename':'F2', 'lnum':30}]})
1960    let l = g:Xgetlist({'items':1})
1961    call assert_equal('F2', bufname(l.items[2].bufnr))
1962    call assert_equal(30, l.items[2].lnum)
1963    call g:Xsetlist([], 'r', {'items' : [{'filename':'F3', 'lnum':40}]})
1964    let l = g:Xgetlist({'items':1})
1965    call assert_equal('F3', bufname(l.items[0].bufnr))
1966    call assert_equal(40, l.items[0].lnum)
1967    call g:Xsetlist([], 'r', {'items' : []})
1968    let l = g:Xgetlist({'items':1})
1969    call assert_equal(0, len(l.items))
1970
1971    call g:Xsetlist([], 'r', {'title' : 'TestTitle'})
1972    call g:Xsetlist([], 'r', {'items' : [{'filename' : 'F1', 'lnum' : 10, 'text' : 'L10'}]})
1973    call g:Xsetlist([], 'r', {'items' : [{'filename' : 'F1', 'lnum' : 10, 'text' : 'L10'}]})
1974    call assert_equal('TestTitle', g:Xgetlist({'title' : 1}).title)
1975
1976    " Test for getting id of window associated with a location list window
1977    if a:cchar == 'l'
1978      only
1979      call assert_equal(0, g:Xgetlist({'all' : 1}).filewinid)
1980      let wid = win_getid()
1981      Xopen
1982      call assert_equal(wid, g:Xgetlist({'filewinid' : 1}).filewinid)
1983      wincmd w
1984      call assert_equal(0, g:Xgetlist({'filewinid' : 1}).filewinid)
1985      only
1986    endif
1987
1988    " The following used to crash Vim with address sanitizer
1989    call g:Xsetlist([], 'f')
1990    call g:Xsetlist([], 'a', {'items' : [{'filename':'F1', 'lnum':10}]})
1991    call assert_equal(10, g:Xgetlist({'items':1}).items[0].lnum)
1992
1993    " Try setting the items using a string
1994    call assert_equal(-1, g:Xsetlist([], ' ', {'items' : 'Test'}))
1995
1996    " Save and restore the quickfix stack
1997    call g:Xsetlist([], 'f')
1998    call assert_equal(0, g:Xgetlist({'nr':'$'}).nr)
1999    Xexpr "File1:10:Line1"
2000    Xexpr "File2:20:Line2"
2001    Xexpr "File3:30:Line3"
2002    let last_qf = g:Xgetlist({'nr':'$'}).nr
2003    call assert_equal(3, last_qf)
2004    let qstack = []
2005    for i in range(1, last_qf)
2006	let qstack = add(qstack, g:Xgetlist({'nr':i, 'all':1}))
2007    endfor
2008    call g:Xsetlist([], 'f')
2009    for i in range(len(qstack))
2010	call g:Xsetlist([], ' ', qstack[i])
2011    endfor
2012    call assert_equal(3, g:Xgetlist({'nr':'$'}).nr)
2013    call assert_equal(10, g:Xgetlist({'nr':1, 'items':1}).items[0].lnum)
2014    call assert_equal(20, g:Xgetlist({'nr':2, 'items':1}).items[0].lnum)
2015    call assert_equal(30, g:Xgetlist({'nr':3, 'items':1}).items[0].lnum)
2016    call g:Xsetlist([], 'f')
2017
2018    " Swap two quickfix lists
2019    Xexpr "File1:10:Line10"
2020    Xexpr "File2:20:Line20"
2021    Xexpr "File3:30:Line30"
2022    call g:Xsetlist([], 'r', {'nr':1,'title':'Colors','context':['Colors']})
2023    call g:Xsetlist([], 'r', {'nr':2,'title':'Fruits','context':['Fruits']})
2024    let l1=g:Xgetlist({'nr':1,'all':1})
2025    let l2=g:Xgetlist({'nr':2,'all':1})
2026    let save_id = l1.id
2027    let l1.id=l2.id
2028    let l2.id=save_id
2029    call g:Xsetlist([], 'r', l1)
2030    call g:Xsetlist([], 'r', l2)
2031    let newl1=g:Xgetlist({'nr':1,'all':1})
2032    let newl2=g:Xgetlist({'nr':2,'all':1})
2033    call assert_equal('Fruits', newl1.title)
2034    call assert_equal(['Fruits'], newl1.context)
2035    call assert_equal('Line20', newl1.items[0].text)
2036    call assert_equal('Colors', newl2.title)
2037    call assert_equal(['Colors'], newl2.context)
2038    call assert_equal('Line10', newl2.items[0].text)
2039    call g:Xsetlist([], 'f')
2040endfunc
2041
2042func Test_qf_property()
2043    call Xproperty_tests('c')
2044    call Xproperty_tests('l')
2045endfunc
2046
2047" Tests for the QuickFixCmdPre/QuickFixCmdPost autocommands
2048func QfAutoCmdHandler(loc, cmd)
2049  call add(g:acmds, a:loc . a:cmd)
2050endfunc
2051
2052func Test_Autocmd()
2053  autocmd QuickFixCmdPre * call QfAutoCmdHandler('pre', expand('<amatch>'))
2054  autocmd QuickFixCmdPost * call QfAutoCmdHandler('post', expand('<amatch>'))
2055
2056  let g:acmds = []
2057  cexpr "F1:10:Line 10"
2058  caddexpr "F1:20:Line 20"
2059  cgetexpr "F1:30:Line 30"
2060  cexpr ""
2061  caddexpr ""
2062  cgetexpr ""
2063  silent! cexpr non_existing_func()
2064  silent! caddexpr non_existing_func()
2065  silent! cgetexpr non_existing_func()
2066  let l = ['precexpr',
2067	      \ 'postcexpr',
2068	      \ 'precaddexpr',
2069	      \ 'postcaddexpr',
2070	      \ 'precgetexpr',
2071	      \ 'postcgetexpr',
2072	      \ 'precexpr',
2073	      \ 'postcexpr',
2074	      \ 'precaddexpr',
2075	      \ 'postcaddexpr',
2076	      \ 'precgetexpr',
2077	      \ 'postcgetexpr',
2078	      \ 'precexpr',
2079	      \ 'precaddexpr',
2080	      \ 'precgetexpr']
2081  call assert_equal(l, g:acmds)
2082
2083  let g:acmds = []
2084  enew! | call append(0, "F2:10:Line 10")
2085  cbuffer!
2086  enew! | call append(0, "F2:20:Line 20")
2087  cgetbuffer
2088  enew! | call append(0, "F2:30:Line 30")
2089  caddbuffer
2090  new
2091  let bnum = bufnr('%')
2092  bunload
2093  exe 'silent! cbuffer! ' . bnum
2094  exe 'silent! cgetbuffer ' . bnum
2095  exe 'silent! caddbuffer ' . bnum
2096  enew!
2097  let l = ['precbuffer',
2098	      \ 'postcbuffer',
2099	      \ 'precgetbuffer',
2100	      \ 'postcgetbuffer',
2101	      \ 'precaddbuffer',
2102	      \ 'postcaddbuffer',
2103	      \ 'precbuffer',
2104	      \ 'precgetbuffer',
2105	      \ 'precaddbuffer']
2106  call assert_equal(l, g:acmds)
2107
2108  call writefile(['Xtest:1:Line1'], 'Xtest')
2109  call writefile([], 'Xempty')
2110  let g:acmds = []
2111  cfile Xtest
2112  caddfile Xtest
2113  cgetfile Xtest
2114  cfile Xempty
2115  caddfile Xempty
2116  cgetfile Xempty
2117  silent! cfile do_not_exist
2118  silent! caddfile do_not_exist
2119  silent! cgetfile do_not_exist
2120  let l = ['precfile',
2121	      \ 'postcfile',
2122	      \ 'precaddfile',
2123	      \ 'postcaddfile',
2124	      \ 'precgetfile',
2125	      \ 'postcgetfile',
2126	      \ 'precfile',
2127	      \ 'postcfile',
2128	      \ 'precaddfile',
2129	      \ 'postcaddfile',
2130	      \ 'precgetfile',
2131	      \ 'postcgetfile',
2132	      \ 'precfile',
2133	      \ 'postcfile',
2134	      \ 'precaddfile',
2135	      \ 'postcaddfile',
2136	      \ 'precgetfile',
2137	      \ 'postcgetfile']
2138  call assert_equal(l, g:acmds)
2139
2140  let g:acmds = []
2141  helpgrep quickfix
2142  silent! helpgrep non_existing_help_topic
2143  vimgrep test Xtest
2144  vimgrepadd test Xtest
2145  silent! vimgrep non_existing_test Xtest
2146  silent! vimgrepadd non_existing_test Xtest
2147  set makeprg=
2148  silent! make
2149  set makeprg&
2150  let l = ['prehelpgrep',
2151	      \ 'posthelpgrep',
2152	      \ 'prehelpgrep',
2153	      \ 'posthelpgrep',
2154	      \ 'previmgrep',
2155	      \ 'postvimgrep',
2156	      \ 'previmgrepadd',
2157	      \ 'postvimgrepadd',
2158	      \ 'previmgrep',
2159	      \ 'postvimgrep',
2160	      \ 'previmgrepadd',
2161	      \ 'postvimgrepadd',
2162	      \ 'premake',
2163	      \ 'postmake']
2164  call assert_equal(l, g:acmds)
2165
2166  if has('unix')
2167    " Run this test only on Unix-like systems. The grepprg may not be set on
2168    " non-Unix systems.
2169    " The following lines are used for the grep test. Don't remove.
2170    " Grep_Autocmd_Text: Match 1
2171    " GrepAdd_Autocmd_Text: Match 2
2172    let g:acmds = []
2173    silent grep Grep_Autocmd_Text test_quickfix.vim
2174    silent grepadd GrepAdd_Autocmd_Text test_quickfix.vim
2175    silent grep abc123def Xtest
2176    silent grepadd abc123def Xtest
2177    let l = ['pregrep',
2178		\ 'postgrep',
2179		\ 'pregrepadd',
2180		\ 'postgrepadd',
2181		\ 'pregrep',
2182		\ 'postgrep',
2183		\ 'pregrepadd',
2184		\ 'postgrepadd']
2185    call assert_equal(l, g:acmds)
2186  endif
2187
2188  call delete('Xtest')
2189  call delete('Xempty')
2190  au! QuickFixCmdPre
2191  au! QuickFixCmdPost
2192endfunc
2193
2194func Test_Autocmd_Exception()
2195  set efm=%m
2196  lgetexpr '?'
2197
2198  try
2199    call DoesNotExit()
2200  catch
2201    lgetexpr '1'
2202  finally
2203    lgetexpr '1'
2204  endtry
2205
2206  call assert_equal('1', getloclist(0)[0].text)
2207
2208  set efm&vim
2209endfunc
2210
2211func Test_caddbuffer_wrong()
2212  " This used to cause a memory access in freed memory.
2213  let save_efm = &efm
2214  set efm=%EEEE%m,%WWWW,%+CCCC%>%#,%GGGG%.#
2215  cgetexpr ['WWWW', 'EEEE', 'CCCC']
2216  let &efm = save_efm
2217  caddbuffer
2218  bwipe!
2219endfunc
2220
2221func Test_caddexpr_wrong()
2222  " This used to cause a memory access in freed memory.
2223  cbuffer
2224  cbuffer
2225  copen
2226  let save_efm = &efm
2227  set efm=%
2228  call assert_fails('caddexpr ""', 'E376:')
2229  let &efm = save_efm
2230endfunc
2231
2232func Test_dirstack_cleanup()
2233  " This used to cause a memory access in freed memory.
2234  let save_efm = &efm
2235  lexpr '0'
2236  lopen
2237  fun X(c)
2238    let save_efm=&efm
2239    set efm=%D%f
2240    if a:c == 'c'
2241      caddexpr '::'
2242    else
2243      laddexpr ':0:0'
2244    endif
2245    let &efm=save_efm
2246  endfun
2247  call X('c')
2248  call X('l')
2249  call setqflist([], 'r')
2250  caddbuffer
2251  let &efm = save_efm
2252endfunc
2253
2254" Tests for jumping to entries from the location list window and quickfix
2255" window
2256func Test_cwindow_jump()
2257  set efm=%f%%%l%%%m
2258  lgetexpr ["F1%10%Line 10", "F2%20%Line 20", "F3%30%Line 30"]
2259  lopen | only
2260  lfirst
2261  call assert_true(winnr('$') == 2)
2262  call assert_true(winnr() == 1)
2263  " Location list for the new window should be set
2264  call assert_true(getloclist(0)[2].text == 'Line 30')
2265
2266  " Open a scratch buffer
2267  " Open a new window and create a location list
2268  " Open the location list window and close the other window
2269  " Jump to an entry.
2270  " Should create a new window and jump to the entry. The scrtach buffer
2271  " should not be used.
2272  enew | only
2273  set buftype=nofile
2274  below new
2275  lgetexpr ["F1%10%Line 10", "F2%20%Line 20", "F3%30%Line 30"]
2276  lopen
2277  2wincmd c
2278  lnext
2279  call assert_true(winnr('$') == 3)
2280  call assert_true(winnr() == 2)
2281
2282  " Open two windows with two different location lists
2283  " Open the location list window and close the previous window
2284  " Jump to an entry in the location list window
2285  " Should open the file in the first window and not set the location list.
2286  enew | only
2287  lgetexpr ["F1%5%Line 5"]
2288  below new
2289  lgetexpr ["F1%10%Line 10", "F2%20%Line 20", "F3%30%Line 30"]
2290  lopen
2291  2wincmd c
2292  lnext
2293  call assert_true(winnr() == 1)
2294  call assert_true(getloclist(0)[0].text == 'Line 5')
2295
2296  enew | only
2297  cgetexpr ["F1%10%Line 10", "F2%20%Line 20", "F3%30%Line 30"]
2298  copen
2299  cnext
2300  call assert_true(winnr('$') == 2)
2301  call assert_true(winnr() == 1)
2302
2303  enew | only
2304  set efm&vim
2305endfunc
2306
2307func XvimgrepTests(cchar)
2308  call s:setup_commands(a:cchar)
2309
2310  call writefile(['Editor:VIM vim',
2311	      \ 'Editor:Emacs EmAcS',
2312	      \ 'Editor:Notepad NOTEPAD'], 'Xtestfile1')
2313  call writefile(['Linux', 'MacOS', 'MS-Windows'], 'Xtestfile2')
2314
2315  " Error cases
2316  call assert_fails('Xvimgrep /abc *', 'E682:')
2317
2318  let @/=''
2319  call assert_fails('Xvimgrep // *', 'E35:')
2320
2321  call assert_fails('Xvimgrep abc', 'E683:')
2322  call assert_fails('Xvimgrep a1b2c3 Xtestfile1', 'E480:')
2323  call assert_fails('Xvimgrep pat Xa1b2c3', 'E480:')
2324
2325  Xexpr ""
2326  Xvimgrepadd Notepad Xtestfile1
2327  Xvimgrepadd MacOS Xtestfile2
2328  let l = g:Xgetlist()
2329  call assert_equal(2, len(l))
2330  call assert_equal('Editor:Notepad NOTEPAD', l[0].text)
2331
2332  Xvimgrep #\cvim#g Xtestfile?
2333  let l = g:Xgetlist()
2334  call assert_equal(2, len(l))
2335  call assert_equal(8, l[0].col)
2336  call assert_equal(12, l[1].col)
2337
2338  1Xvimgrep ?Editor? Xtestfile*
2339  let l = g:Xgetlist()
2340  call assert_equal(1, len(l))
2341  call assert_equal('Editor:VIM vim', l[0].text)
2342
2343  edit +3 Xtestfile2
2344  Xvimgrep +\cemacs+j Xtestfile1
2345  let l = g:Xgetlist()
2346  call assert_equal('Xtestfile2', bufname(''))
2347  call assert_equal('Editor:Emacs EmAcS', l[0].text)
2348
2349  " Test for unloading a buffer after vimgrep searched the buffer
2350  %bwipe
2351  Xvimgrep /Editor/j Xtestfile*
2352  call assert_equal(0, getbufinfo('Xtestfile1')[0].loaded)
2353  call assert_equal([], getbufinfo('Xtestfile2'))
2354
2355  call delete('Xtestfile1')
2356  call delete('Xtestfile2')
2357endfunc
2358
2359" Tests for the :vimgrep command
2360func Test_vimgrep()
2361  call XvimgrepTests('c')
2362  call XvimgrepTests('l')
2363endfunc
2364
2365func XfreeTests(cchar)
2366  call s:setup_commands(a:cchar)
2367
2368  enew | only
2369
2370  " Deleting the quickfix stack should work even When the current list is
2371  " somewhere in the middle of the stack
2372  Xexpr ['Xfile1:10:10:Line 10', 'Xfile1:15:15:Line 15']
2373  Xexpr ['Xfile2:20:20:Line 20', 'Xfile2:25:25:Line 25']
2374  Xexpr ['Xfile3:30:30:Line 30', 'Xfile3:35:35:Line 35']
2375  Xolder
2376  call g:Xsetlist([], 'f')
2377  call assert_equal(0, len(g:Xgetlist()))
2378
2379  " After deleting the stack, adding a new list should create a stack with a
2380  " single list.
2381  Xexpr ['Xfile1:10:10:Line 10', 'Xfile1:15:15:Line 15']
2382  call assert_equal(1, g:Xgetlist({'all':1}).nr)
2383
2384  " Deleting the stack from a quickfix window should update/clear the
2385  " quickfix/location list window.
2386  Xexpr ['Xfile1:10:10:Line 10', 'Xfile1:15:15:Line 15']
2387  Xexpr ['Xfile2:20:20:Line 20', 'Xfile2:25:25:Line 25']
2388  Xexpr ['Xfile3:30:30:Line 30', 'Xfile3:35:35:Line 35']
2389  Xolder
2390  Xwindow
2391  call g:Xsetlist([], 'f')
2392  call assert_equal(2, winnr('$'))
2393  call assert_equal(1, line('$'))
2394  Xclose
2395
2396  " Deleting the stack from a non-quickfix window should update/clear the
2397  " quickfix/location list window.
2398  Xexpr ['Xfile1:10:10:Line 10', 'Xfile1:15:15:Line 15']
2399  Xexpr ['Xfile2:20:20:Line 20', 'Xfile2:25:25:Line 25']
2400  Xexpr ['Xfile3:30:30:Line 30', 'Xfile3:35:35:Line 35']
2401  Xolder
2402  Xwindow
2403  wincmd p
2404  call g:Xsetlist([], 'f')
2405  call assert_equal(0, len(g:Xgetlist()))
2406  wincmd p
2407  call assert_equal(2, winnr('$'))
2408  call assert_equal(1, line('$'))
2409
2410  " After deleting the location list stack, if the location list window is
2411  " opened, then a new location list should be created. So opening the
2412  " location list window again should not create a new window.
2413  if a:cchar == 'l'
2414      lexpr ['Xfile1:10:10:Line 10', 'Xfile1:15:15:Line 15']
2415      wincmd p
2416      lopen
2417      call assert_equal(2, winnr('$'))
2418  endif
2419  Xclose
2420endfunc
2421
2422" Tests for the quickfix free functionality
2423func Test_qf_free()
2424  call XfreeTests('c')
2425  call XfreeTests('l')
2426endfunc
2427
2428" Test for buffer overflow when parsing lines and adding new entries to
2429" the quickfix list.
2430func Test_bufoverflow()
2431  set efm=%f:%l:%m
2432  cgetexpr ['File1:100:' . repeat('x', 1025)]
2433
2434  set efm=%+GCompiler:\ %.%#,%f:%l:%m
2435  cgetexpr ['Compiler: ' . repeat('a', 1015), 'File1:10:Hello World']
2436
2437  set efm=%DEntering\ directory\ %f,%f:%l:%m
2438  cgetexpr ['Entering directory ' . repeat('a', 1006),
2439	      \ 'File1:10:Hello World']
2440  set efm&vim
2441endfunc
2442
2443" Tests for getting the quickfix stack size
2444func XsizeTests(cchar)
2445  call s:setup_commands(a:cchar)
2446
2447  call g:Xsetlist([], 'f')
2448  call assert_equal(0, g:Xgetlist({'nr':'$'}).nr)
2449  call assert_equal('', g:Xgetlist({'nr':'$', 'all':1}).title)
2450  call assert_equal(0, g:Xgetlist({'nr':0}).nr)
2451
2452  Xexpr "File1:10:Line1"
2453  Xexpr "File2:20:Line2"
2454  Xexpr "File3:30:Line3"
2455  Xolder | Xolder
2456  call assert_equal(3, g:Xgetlist({'nr':'$'}).nr)
2457  call g:Xsetlist([], 'f')
2458
2459  Xexpr "File1:10:Line1"
2460  Xexpr "File2:20:Line2"
2461  Xexpr "File3:30:Line3"
2462  Xolder | Xolder
2463  call g:Xsetlist([], 'a', {'nr':'$', 'title':'Compiler'})
2464  call assert_equal('Compiler', g:Xgetlist({'nr':3, 'all':1}).title)
2465endfunc
2466
2467func Test_Qf_Size()
2468  call XsizeTests('c')
2469  call XsizeTests('l')
2470endfunc
2471
2472func Test_cclose_from_copen()
2473    augroup QF_Test
2474	au!
2475        au FileType qf :call assert_fails(':cclose', 'E788')
2476    augroup END
2477    copen
2478    augroup QF_Test
2479	au!
2480    augroup END
2481    augroup! QF_Test
2482endfunc
2483
2484func Test_cclose_in_autocmd()
2485  " Problem is only triggered if "starting" is zero, so that the OptionsSet
2486  " event will be triggered.
2487  call test_override('starting', 1)
2488  augroup QF_Test
2489    au!
2490    au FileType qf :call assert_fails(':cclose', 'E788')
2491  augroup END
2492  copen
2493  augroup QF_Test
2494    au!
2495  augroup END
2496  augroup! QF_Test
2497  call test_override('starting', 0)
2498endfunc
2499
2500" Check that ":file" without an argument is possible even when "curbuf_lock"
2501" is set.
2502func Test_file_from_copen()
2503  " Works without argument.
2504  augroup QF_Test
2505    au!
2506    au FileType qf file
2507  augroup END
2508  copen
2509
2510  augroup QF_Test
2511    au!
2512  augroup END
2513  cclose
2514
2515  " Fails with argument.
2516  augroup QF_Test
2517    au!
2518    au FileType qf call assert_fails(':file foo', 'E788')
2519  augroup END
2520  copen
2521  augroup QF_Test
2522    au!
2523  augroup END
2524  cclose
2525
2526  augroup! QF_Test
2527endfunction
2528
2529func Test_resize_from_copen()
2530    augroup QF_Test
2531	au!
2532        au FileType qf resize 5
2533    augroup END
2534    try
2535	" This should succeed without any exception.  No other buffers are
2536	" involved in the autocmd.
2537	copen
2538    finally
2539	augroup QF_Test
2540	    au!
2541	augroup END
2542	augroup! QF_Test
2543    endtry
2544endfunc
2545
2546" Tests for the quickfix buffer b:changedtick variable
2547func Xchangedtick_tests(cchar)
2548  call s:setup_commands(a:cchar)
2549
2550  new | only
2551
2552  Xexpr "" | Xexpr "" | Xexpr ""
2553
2554  Xopen
2555  Xolder
2556  Xolder
2557  Xaddexpr "F1:10:Line10"
2558  Xaddexpr "F2:20:Line20"
2559  call g:Xsetlist([{"filename":"F3", "lnum":30, "text":"Line30"}], 'a')
2560  call g:Xsetlist([], 'f')
2561  call assert_equal(8, getbufvar('%', 'changedtick'))
2562  Xclose
2563endfunc
2564
2565func Test_changedtick()
2566  call Xchangedtick_tests('c')
2567  call Xchangedtick_tests('l')
2568endfunc
2569
2570" Tests for parsing an expression using setqflist()
2571func Xsetexpr_tests(cchar)
2572  call s:setup_commands(a:cchar)
2573
2574  let t = ["File1:10:Line10", "File1:20:Line20"]
2575  call g:Xsetlist([], ' ', {'lines' : t})
2576  call g:Xsetlist([], 'a', {'lines' : ["File1:30:Line30"]})
2577
2578  let l = g:Xgetlist()
2579  call assert_equal(3, len(l))
2580  call assert_equal(20, l[1].lnum)
2581  call assert_equal('Line30', l[2].text)
2582  call g:Xsetlist([], 'r', {'lines' : ["File2:5:Line5"]})
2583  let l = g:Xgetlist()
2584  call assert_equal(1, len(l))
2585  call assert_equal('Line5', l[0].text)
2586  call assert_equal(-1, g:Xsetlist([], 'a', {'lines' : 10}))
2587  call assert_equal(-1, g:Xsetlist([], 'a', {'lines' : "F1:10:L10"}))
2588
2589  call g:Xsetlist([], 'f')
2590  " Add entries to multiple lists
2591  call g:Xsetlist([], 'a', {'nr' : 1, 'lines' : ["File1:10:Line10"]})
2592  call g:Xsetlist([], 'a', {'nr' : 2, 'lines' : ["File2:20:Line20"]})
2593  call g:Xsetlist([], 'a', {'nr' : 1, 'lines' : ["File1:15:Line15"]})
2594  call g:Xsetlist([], 'a', {'nr' : 2, 'lines' : ["File2:25:Line25"]})
2595  call assert_equal('Line15', g:Xgetlist({'nr':1, 'items':1}).items[1].text)
2596  call assert_equal('Line25', g:Xgetlist({'nr':2, 'items':1}).items[1].text)
2597
2598  " Adding entries using a custom efm
2599  set efm&
2600  call g:Xsetlist([], ' ', {'efm' : '%f#%l#%m',
2601				\ 'lines' : ["F1#10#L10", "F2#20#L20"]})
2602  call assert_equal(20, g:Xgetlist({'items':1}).items[1].lnum)
2603  call g:Xsetlist([], 'a', {'efm' : '%f#%l#%m', 'lines' : ["F3:30:L30"]})
2604  call assert_equal('F3:30:L30', g:Xgetlist({'items':1}).items[2].text)
2605  call assert_equal(20, g:Xgetlist({'items':1}).items[1].lnum)
2606  call assert_equal(-1, g:Xsetlist([], 'a', {'efm' : [],
2607				\ 'lines' : ['F1:10:L10']}))
2608endfunc
2609
2610func Test_setexpr()
2611  call Xsetexpr_tests('c')
2612  call Xsetexpr_tests('l')
2613endfunc
2614
2615" Tests for per quickfix/location list directory stack
2616func Xmultidirstack_tests(cchar)
2617  call s:setup_commands(a:cchar)
2618
2619  call g:Xsetlist([], 'f')
2620  Xexpr "" | Xexpr ""
2621
2622  call g:Xsetlist([], 'a', {'nr' : 1, 'lines' : ["Entering dir 'Xone/a'"]})
2623  call g:Xsetlist([], 'a', {'nr' : 2, 'lines' : ["Entering dir 'Xtwo/a'"]})
2624  call g:Xsetlist([], 'a', {'nr' : 1, 'lines' : ["one.txt:3:one one one"]})
2625  call g:Xsetlist([], 'a', {'nr' : 2, 'lines' : ["two.txt:5:two two two"]})
2626
2627  let l1 = g:Xgetlist({'nr':1, 'items':1})
2628  let l2 = g:Xgetlist({'nr':2, 'items':1})
2629  call assert_equal('Xone/a/one.txt', bufname(l1.items[1].bufnr))
2630  call assert_equal(3, l1.items[1].lnum)
2631  call assert_equal('Xtwo/a/two.txt', bufname(l2.items[1].bufnr))
2632  call assert_equal(5, l2.items[1].lnum)
2633endfunc
2634
2635func Test_multidirstack()
2636  call mkdir('Xone/a', 'p')
2637  call mkdir('Xtwo/a', 'p')
2638  let lines = ['1', '2', 'one one one', '4', 'two two two', '6', '7']
2639  call writefile(lines, 'Xone/a/one.txt')
2640  call writefile(lines, 'Xtwo/a/two.txt')
2641  let save_efm = &efm
2642  set efm=%DEntering\ dir\ '%f',%f:%l:%m,%XLeaving\ dir\ '%f'
2643
2644  call Xmultidirstack_tests('c')
2645  call Xmultidirstack_tests('l')
2646
2647  let &efm = save_efm
2648  call delete('Xone', 'rf')
2649  call delete('Xtwo', 'rf')
2650endfunc
2651
2652" Tests for per quickfix/location list file stack
2653func Xmultifilestack_tests(cchar)
2654  call s:setup_commands(a:cchar)
2655
2656  call g:Xsetlist([], 'f')
2657  Xexpr "" | Xexpr ""
2658
2659  call g:Xsetlist([], 'a', {'nr' : 1, 'lines' : ["[one.txt]"]})
2660  call g:Xsetlist([], 'a', {'nr' : 2, 'lines' : ["[two.txt]"]})
2661  call g:Xsetlist([], 'a', {'nr' : 1, 'lines' : ["(3,5) one one one"]})
2662  call g:Xsetlist([], 'a', {'nr' : 2, 'lines' : ["(5,9) two two two"]})
2663
2664  let l1 = g:Xgetlist({'nr':1, 'items':1})
2665  let l2 = g:Xgetlist({'nr':2, 'items':1})
2666  call assert_equal('one.txt', bufname(l1.items[1].bufnr))
2667  call assert_equal(3, l1.items[1].lnum)
2668  call assert_equal('two.txt', bufname(l2.items[1].bufnr))
2669  call assert_equal(5, l2.items[1].lnum)
2670
2671  " Test for start of a new error line in the same line where a previous
2672  " error line ends with a file stack.
2673  let efm_val = 'Error\ l%l\ in\ %f,'
2674  let efm_val .= '%-P%>(%f%r,Error\ l%l\ in\ %m,%-Q)%r'
2675  let l = g:Xgetlist({'lines' : [
2676	      \ '(one.txt',
2677	      \ 'Error l4 in one.txt',
2678	      \ ') (two.txt',
2679	      \ 'Error l6 in two.txt',
2680	      \ ')',
2681	      \ 'Error l8 in one.txt'
2682	      \ ], 'efm' : efm_val})
2683  call assert_equal(3, len(l.items))
2684  call assert_equal('one.txt', bufname(l.items[0].bufnr))
2685  call assert_equal(4, l.items[0].lnum)
2686  call assert_equal('one.txt', l.items[0].text)
2687  call assert_equal('two.txt', bufname(l.items[1].bufnr))
2688  call assert_equal(6, l.items[1].lnum)
2689  call assert_equal('two.txt', l.items[1].text)
2690  call assert_equal('one.txt', bufname(l.items[2].bufnr))
2691  call assert_equal(8, l.items[2].lnum)
2692  call assert_equal('', l.items[2].text)
2693endfunc
2694
2695func Test_multifilestack()
2696  let lines = ['1', '2', 'one one one', '4', 'two two two', '6', '7']
2697  call writefile(lines, 'one.txt')
2698  call writefile(lines, 'two.txt')
2699  let save_efm = &efm
2700  set efm=%+P[%f],(%l\\,%c)\ %m,%-Q
2701
2702  call Xmultifilestack_tests('c')
2703  call Xmultifilestack_tests('l')
2704
2705  let &efm = save_efm
2706  call delete('one.txt')
2707  call delete('two.txt')
2708endfunc
2709
2710" Tests for per buffer 'efm' setting
2711func Test_perbuf_efm()
2712  call writefile(["File1-10-Line10"], 'one.txt')
2713  call writefile(["File2#20#Line20"], 'two.txt')
2714  set efm=%f#%l#%m
2715  new | only
2716  new
2717  setlocal efm=%f-%l-%m
2718  cfile one.txt
2719  wincmd w
2720  caddfile two.txt
2721
2722  let l = getqflist()
2723  call assert_equal(10, l[0].lnum)
2724  call assert_equal('Line20', l[1].text)
2725
2726  set efm&
2727  new | only
2728  call delete('one.txt')
2729  call delete('two.txt')
2730endfunc
2731
2732" Open multiple help windows using ":lhelpgrep
2733" This test used to crash Vim
2734func Test_Multi_LL_Help()
2735    new | only
2736    lhelpgrep window
2737    lopen
2738    e#
2739    lhelpgrep buffer
2740    call assert_equal(3, winnr('$'))
2741    call assert_true(len(getloclist(1)) != 0)
2742    call assert_true(len(getloclist(2)) != 0)
2743    new | only
2744endfunc
2745
2746" Tests for adding new quickfix lists using setqflist()
2747func XaddQf_tests(cchar)
2748  call s:setup_commands(a:cchar)
2749
2750  " Create a new list using ' ' for action
2751  call g:Xsetlist([], 'f')
2752  call g:Xsetlist([], ' ', {'title' : 'Test1'})
2753  let l = g:Xgetlist({'nr' : '$', 'all' : 1})
2754  call assert_equal(1, l.nr)
2755  call assert_equal('Test1', l.title)
2756
2757  " Create a new list using ' ' for action and '$' for 'nr'
2758  call g:Xsetlist([], 'f')
2759  call g:Xsetlist([], ' ', {'title' : 'Test2', 'nr' : '$'})
2760  let l = g:Xgetlist({'nr' : '$', 'all' : 1})
2761  call assert_equal(1, l.nr)
2762  call assert_equal('Test2', l.title)
2763
2764  " Create a new list using 'a' for action
2765  call g:Xsetlist([], 'f')
2766  call g:Xsetlist([], 'a', {'title' : 'Test3'})
2767  let l = g:Xgetlist({'nr' : '$', 'all' : 1})
2768  call assert_equal(1, l.nr)
2769  call assert_equal('Test3', l.title)
2770
2771  " Create a new list using 'a' for action and '$' for 'nr'
2772  call g:Xsetlist([], 'f')
2773  call g:Xsetlist([], 'a', {'title' : 'Test3', 'nr' : '$'})
2774  call g:Xsetlist([], 'a', {'title' : 'Test4'})
2775  let l = g:Xgetlist({'nr' : '$', 'all' : 1})
2776  call assert_equal(1, l.nr)
2777  call assert_equal('Test4', l.title)
2778
2779  " Adding a quickfix list should remove all the lists following the current
2780  " list.
2781  Xexpr "" | Xexpr "" | Xexpr ""
2782  silent! 10Xolder
2783  call g:Xsetlist([], ' ', {'title' : 'Test5'})
2784  let l = g:Xgetlist({'nr' : '$', 'all' : 1})
2785  call assert_equal(2, l.nr)
2786  call assert_equal('Test5', l.title)
2787
2788  " Add a quickfix list using '$' as the list number.
2789  let lastqf = g:Xgetlist({'nr':'$'}).nr
2790  silent! 99Xolder
2791  call g:Xsetlist([], ' ', {'nr' : '$', 'title' : 'Test6'})
2792  let l = g:Xgetlist({'nr' : '$', 'all' : 1})
2793  call assert_equal(lastqf + 1, l.nr)
2794  call assert_equal('Test6', l.title)
2795
2796  " Add a quickfix list using 'nr' set to one more than the quickfix
2797  " list size.
2798  let lastqf = g:Xgetlist({'nr':'$'}).nr
2799  silent! 99Xolder
2800  call g:Xsetlist([], ' ', {'nr' : lastqf + 1, 'title' : 'Test7'})
2801  let l = g:Xgetlist({'nr' : '$', 'all' : 1})
2802  call assert_equal(lastqf + 1, l.nr)
2803  call assert_equal('Test7', l.title)
2804
2805  " Add a quickfix list to a stack with 10 lists using 'nr' set to '$'
2806  exe repeat('Xexpr "" |', 9) . 'Xexpr ""'
2807  silent! 99Xolder
2808  call g:Xsetlist([], ' ', {'nr' : '$', 'title' : 'Test8'})
2809  let l = g:Xgetlist({'nr' : '$', 'all' : 1})
2810  call assert_equal(10, l.nr)
2811  call assert_equal('Test8', l.title)
2812
2813  " Add a quickfix list using 'nr' set to a value greater than 10
2814  call assert_equal(-1, g:Xsetlist([], ' ', {'nr' : 12, 'title' : 'Test9'}))
2815
2816  " Try adding a quickfix list with 'nr' set to a value greater than the
2817  " quickfix list size but less than 10.
2818  call g:Xsetlist([], 'f')
2819  Xexpr "" | Xexpr "" | Xexpr ""
2820  silent! 99Xolder
2821  call assert_equal(-1, g:Xsetlist([], ' ', {'nr' : 8, 'title' : 'Test10'}))
2822
2823  " Add a quickfix list using 'nr' set to a some string or list
2824  call assert_equal(-1, g:Xsetlist([], ' ', {'nr' : [1,2], 'title' : 'Test11'}))
2825endfunc
2826
2827func Test_add_qf()
2828  call XaddQf_tests('c')
2829  call XaddQf_tests('l')
2830endfunc
2831
2832" Test for getting the quickfix list items from some text without modifying
2833" the quickfix stack
2834func XgetListFromLines(cchar)
2835  call s:setup_commands(a:cchar)
2836  call g:Xsetlist([], 'f')
2837
2838  let l = g:Xgetlist({'lines' : ["File2:20:Line20", "File2:30:Line30"]}).items
2839  call assert_equal(2, len(l))
2840  call assert_equal(30, l[1].lnum)
2841
2842  call assert_equal({}, g:Xgetlist({'lines' : 10}))
2843  call assert_equal({}, g:Xgetlist({'lines' : 'File1:10:Line10'}))
2844  call assert_equal([], g:Xgetlist({'lines' : []}).items)
2845  call assert_equal([], g:Xgetlist({'lines' : [10, 20]}).items)
2846
2847  " Parse text using a custom efm
2848  set efm&
2849  let l = g:Xgetlist({'lines':['File3#30#Line30'], 'efm' : '%f#%l#%m'}).items
2850  call assert_equal('Line30', l[0].text)
2851  let l = g:Xgetlist({'lines':['File3:30:Line30'], 'efm' : '%f-%l-%m'}).items
2852  call assert_equal('File3:30:Line30', l[0].text)
2853  let l = g:Xgetlist({'lines':['File3:30:Line30'], 'efm' : [1,2]})
2854  call assert_equal({}, l)
2855  call assert_fails("call g:Xgetlist({'lines':['abc'], 'efm':'%2'})", 'E376:')
2856  call assert_fails("call g:Xgetlist({'lines':['abc'], 'efm':''})", 'E378:')
2857
2858  " Make sure that the quickfix stack is not modified
2859  call assert_equal(0, g:Xgetlist({'nr' : '$'}).nr)
2860endfunc
2861
2862func Test_get_list_from_lines()
2863  call XgetListFromLines('c')
2864  call XgetListFromLines('l')
2865endfunc
2866
2867" Tests for the quickfix list id
2868func Xqfid_tests(cchar)
2869  call s:setup_commands(a:cchar)
2870
2871  call g:Xsetlist([], 'f')
2872  call assert_equal(0, g:Xgetlist({'id':0}).id)
2873  Xexpr ''
2874  let start_id = g:Xgetlist({'id' : 0}).id
2875  Xexpr '' | Xexpr ''
2876  Xolder
2877  call assert_equal(start_id, g:Xgetlist({'id':0, 'nr':1}).id)
2878  call assert_equal(start_id + 1, g:Xgetlist({'id':0, 'nr':0}).id)
2879  call assert_equal(start_id + 2, g:Xgetlist({'id':0, 'nr':'$'}).id)
2880  call assert_equal(0, g:Xgetlist({'id':0, 'nr':99}).id)
2881  call assert_equal(2, g:Xgetlist({'id':start_id + 1, 'nr':0}).nr)
2882  call assert_equal(0, g:Xgetlist({'id':99, 'nr':0}).id)
2883  call assert_equal(0, g:Xgetlist({'id':"abc", 'nr':0}).id)
2884
2885  call g:Xsetlist([], 'a', {'id':start_id, 'context':[1,2]})
2886  call assert_equal([1,2], g:Xgetlist({'nr':1, 'context':1}).context)
2887  call g:Xsetlist([], 'a', {'id':start_id+1, 'lines':['F1:10:L10']})
2888  call assert_equal('L10', g:Xgetlist({'nr':2, 'items':1}).items[0].text)
2889  call assert_equal(-1, g:Xsetlist([], 'a', {'id':999, 'title':'Vim'}))
2890  call assert_equal(-1, g:Xsetlist([], 'a', {'id':'abc', 'title':'Vim'}))
2891
2892  let qfid = g:Xgetlist({'id':0, 'nr':0})
2893  call g:Xsetlist([], 'f')
2894  call assert_equal(0, g:Xgetlist({'id':qfid, 'nr':0}).id)
2895endfunc
2896
2897func Test_qf_id()
2898  call Xqfid_tests('c')
2899  call Xqfid_tests('l')
2900endfunc
2901
2902func Xqfjump_tests(cchar)
2903  call s:setup_commands(a:cchar)
2904
2905  call writefile(["Line1\tFoo", "Line2"], 'F1')
2906  call writefile(["Line1\tBar", "Line2"], 'F2')
2907  call writefile(["Line1\tBaz", "Line2"], 'F3')
2908
2909  call g:Xsetlist([], 'f')
2910
2911  " Tests for
2912  "   Jumping to a line using a pattern
2913  "   Jumping to a column greater than the last column in a line
2914  "   Jumping to a line greater than the last line in the file
2915  let l = []
2916  for i in range(1, 7)
2917    call add(l, {})
2918  endfor
2919  let l[0].filename='F1'
2920  let l[0].pattern='Line1'
2921  let l[1].filename='F2'
2922  let l[1].pattern='Line1'
2923  let l[2].filename='F3'
2924  let l[2].pattern='Line1'
2925  let l[3].filename='F3'
2926  let l[3].lnum=1
2927  let l[3].col=9
2928  let l[3].vcol=1
2929  let l[4].filename='F3'
2930  let l[4].lnum=99
2931  let l[5].filename='F3'
2932  let l[5].lnum=1
2933  let l[5].col=99
2934  let l[5].vcol=1
2935  let l[6].filename='F3'
2936  let l[6].pattern='abcxyz'
2937
2938  call g:Xsetlist([], ' ', {'items' : l})
2939  Xopen | only
2940  2Xnext
2941  call assert_equal(3, g:Xgetlist({'idx' : 0}).idx)
2942  call assert_equal('F3', bufname('%'))
2943  Xnext
2944  call assert_equal(7, col('.'))
2945  Xnext
2946  call assert_equal(2, line('.'))
2947  Xnext
2948  call assert_equal(9, col('.'))
2949  2
2950  Xnext
2951  call assert_equal(2, line('.'))
2952
2953  if a:cchar == 'l'
2954    " When jumping to a location list entry in the location list window and
2955    " no usable windows are available, then a new window should be opened.
2956    enew! | new | only
2957    call g:Xsetlist([], 'f')
2958    setlocal buftype=nofile
2959    new
2960    call g:Xsetlist([], ' ', {'lines' : ['F1:1:1:Line1', 'F1:2:2:Line2', 'F2:1:1:Line1', 'F2:2:2:Line2', 'F3:1:1:Line1', 'F3:2:2:Line2']})
2961    Xopen
2962    let winid = win_getid()
2963    wincmd p
2964    close
2965    call win_gotoid(winid)
2966    Xnext
2967    call assert_equal(3, winnr('$'))
2968    call assert_equal(1, winnr())
2969    call assert_equal(2, line('.'))
2970
2971    " When jumping to an entry in the location list window and the window
2972    " associated with the location list is not present and a window containing
2973    " the file is already present, then that window should be used.
2974    close
2975    belowright new
2976    call g:Xsetlist([], 'f')
2977    edit F3
2978    call win_gotoid(winid)
2979    Xlast
2980    call assert_equal(3, winnr())
2981    call assert_equal(6, g:Xgetlist({'size' : 1}).size)
2982    call assert_equal(winid, g:Xgetlist({'winid' : 1}).winid)
2983  endif
2984
2985  " Cleanup
2986  enew!
2987  new | only
2988
2989  call delete('F1')
2990  call delete('F2')
2991  call delete('F3')
2992endfunc
2993
2994func Test_qfjump()
2995  call Xqfjump_tests('c')
2996  call Xqfjump_tests('l')
2997endfunc
2998
2999" Tests for the getqflist() and getloclist() functions when the list is not
3000" present or is empty
3001func Xgetlist_empty_tests(cchar)
3002  call s:setup_commands(a:cchar)
3003
3004  " Empty quickfix stack
3005  call g:Xsetlist([], 'f')
3006  call assert_equal('', g:Xgetlist({'context' : 0}).context)
3007  call assert_equal(0, g:Xgetlist({'id' : 0}).id)
3008  call assert_equal(0, g:Xgetlist({'idx' : 0}).idx)
3009  call assert_equal([], g:Xgetlist({'items' : 0}).items)
3010  call assert_equal(0, g:Xgetlist({'nr' : 0}).nr)
3011  call assert_equal(0, g:Xgetlist({'size' : 0}).size)
3012  call assert_equal('', g:Xgetlist({'title' : 0}).title)
3013  call assert_equal(0, g:Xgetlist({'winid' : 0}).winid)
3014  call assert_equal(0, g:Xgetlist({'changedtick' : 0}).changedtick)
3015  if a:cchar == 'c'
3016    call assert_equal({'context' : '', 'id' : 0, 'idx' : 0,
3017		  \ 'items' : [], 'nr' : 0, 'size' : 0,
3018		  \ 'title' : '', 'winid' : 0, 'changedtick': 0},
3019		  \ g:Xgetlist({'all' : 0}))
3020  else
3021    call assert_equal({'context' : '', 'id' : 0, 'idx' : 0,
3022		\ 'items' : [], 'nr' : 0, 'size' : 0, 'title' : '',
3023		\ 'winid' : 0, 'changedtick': 0, 'filewinid' : 0},
3024		\ g:Xgetlist({'all' : 0}))
3025  endif
3026
3027  " Quickfix window with empty stack
3028  silent! Xopen
3029  let qfwinid = (a:cchar == 'c') ? win_getid() : 0
3030  call assert_equal(qfwinid, g:Xgetlist({'winid' : 0}).winid)
3031  Xclose
3032
3033  " Empty quickfix list
3034  Xexpr ""
3035  call assert_equal('', g:Xgetlist({'context' : 0}).context)
3036  call assert_notequal(0, g:Xgetlist({'id' : 0}).id)
3037  call assert_equal(0, g:Xgetlist({'idx' : 0}).idx)
3038  call assert_equal([], g:Xgetlist({'items' : 0}).items)
3039  call assert_notequal(0, g:Xgetlist({'nr' : 0}).nr)
3040  call assert_equal(0, g:Xgetlist({'size' : 0}).size)
3041  call assert_notequal('', g:Xgetlist({'title' : 0}).title)
3042  call assert_equal(0, g:Xgetlist({'winid' : 0}).winid)
3043  call assert_equal(1, g:Xgetlist({'changedtick' : 0}).changedtick)
3044
3045  let qfid = g:Xgetlist({'id' : 0}).id
3046  call g:Xsetlist([], 'f')
3047
3048  " Non-existing quickfix identifier
3049  call assert_equal('', g:Xgetlist({'id' : qfid, 'context' : 0}).context)
3050  call assert_equal(0, g:Xgetlist({'id' : qfid}).id)
3051  call assert_equal(0, g:Xgetlist({'id' : qfid, 'idx' : 0}).idx)
3052  call assert_equal([], g:Xgetlist({'id' : qfid, 'items' : 0}).items)
3053  call assert_equal(0, g:Xgetlist({'id' : qfid, 'nr' : 0}).nr)
3054  call assert_equal(0, g:Xgetlist({'id' : qfid, 'size' : 0}).size)
3055  call assert_equal('', g:Xgetlist({'id' : qfid, 'title' : 0}).title)
3056  call assert_equal(0, g:Xgetlist({'id' : qfid, 'winid' : 0}).winid)
3057  call assert_equal(0, g:Xgetlist({'id' : qfid, 'changedtick' : 0}).changedtick)
3058  if a:cchar == 'c'
3059    call assert_equal({'context' : '', 'id' : 0, 'idx' : 0, 'items' : [],
3060		\ 'nr' : 0, 'size' : 0, 'title' : '', 'winid' : 0,
3061		\ 'changedtick' : 0}, g:Xgetlist({'id' : qfid, 'all' : 0}))
3062  else
3063    call assert_equal({'context' : '', 'id' : 0, 'idx' : 0, 'items' : [],
3064		\ 'nr' : 0, 'size' : 0, 'title' : '', 'winid' : 0,
3065		\ 'changedtick' : 0, 'filewinid' : 0},
3066		\ g:Xgetlist({'id' : qfid, 'all' : 0}))
3067  endif
3068
3069  " Non-existing quickfix list number
3070  call assert_equal('', g:Xgetlist({'nr' : 5, 'context' : 0}).context)
3071  call assert_equal(0, g:Xgetlist({'nr' : 5}).nr)
3072  call assert_equal(0, g:Xgetlist({'nr' : 5, 'idx' : 0}).idx)
3073  call assert_equal([], g:Xgetlist({'nr' : 5, 'items' : 0}).items)
3074  call assert_equal(0, g:Xgetlist({'nr' : 5, 'id' : 0}).id)
3075  call assert_equal(0, g:Xgetlist({'nr' : 5, 'size' : 0}).size)
3076  call assert_equal('', g:Xgetlist({'nr' : 5, 'title' : 0}).title)
3077  call assert_equal(0, g:Xgetlist({'nr' : 5, 'winid' : 0}).winid)
3078  call assert_equal(0, g:Xgetlist({'nr' : 5, 'changedtick' : 0}).changedtick)
3079  if a:cchar == 'c'
3080    call assert_equal({'context' : '', 'id' : 0, 'idx' : 0, 'items' : [],
3081		\ 'nr' : 0, 'size' : 0, 'title' : '', 'winid' : 0,
3082		\ 'changedtick' : 0}, g:Xgetlist({'nr' : 5, 'all' : 0}))
3083  else
3084    call assert_equal({'context' : '', 'id' : 0, 'idx' : 0, 'items' : [],
3085		\ 'nr' : 0, 'size' : 0, 'title' : '', 'winid' : 0,
3086		\ 'changedtick' : 0, 'filewinid' : 0},
3087		\ g:Xgetlist({'nr' : 5, 'all' : 0}))
3088  endif
3089endfunc
3090
3091func Test_getqflist()
3092  call Xgetlist_empty_tests('c')
3093  call Xgetlist_empty_tests('l')
3094endfunc
3095
3096func Test_getqflist_invalid_nr()
3097  " The following commands used to crash Vim
3098  cexpr ""
3099  call getqflist({'nr' : $XXX_DOES_NOT_EXIST_XXX})
3100
3101  " Cleanup
3102  call setqflist([], 'r')
3103endfunc
3104
3105" Tests for the quickfix/location list changedtick
3106func Xqftick_tests(cchar)
3107  call s:setup_commands(a:cchar)
3108
3109  call g:Xsetlist([], 'f')
3110
3111  Xexpr "F1:10:Line10"
3112  let qfid = g:Xgetlist({'id' : 0}).id
3113  call assert_equal(1, g:Xgetlist({'changedtick' : 0}).changedtick)
3114  Xaddexpr "F2:20:Line20\nF2:21:Line21"
3115  call assert_equal(2, g:Xgetlist({'changedtick' : 0}).changedtick)
3116  call g:Xsetlist([], 'a', {'lines' : ["F3:30:Line30", "F3:31:Line31"]})
3117  call assert_equal(3, g:Xgetlist({'changedtick' : 0}).changedtick)
3118  call g:Xsetlist([], 'r', {'lines' : ["F4:40:Line40"]})
3119  call assert_equal(4, g:Xgetlist({'changedtick' : 0}).changedtick)
3120  call g:Xsetlist([], 'a', {'title' : 'New Title'})
3121  call assert_equal(5, g:Xgetlist({'changedtick' : 0}).changedtick)
3122
3123  enew!
3124  call append(0, ["F5:50:L50", "F6:60:L60"])
3125  Xaddbuffer
3126  call assert_equal(6, g:Xgetlist({'changedtick' : 0}).changedtick)
3127  enew!
3128
3129  call g:Xsetlist([], 'a', {'context' : {'bus' : 'pci'}})
3130  call assert_equal(7, g:Xgetlist({'changedtick' : 0}).changedtick)
3131  call g:Xsetlist([{'filename' : 'F7', 'lnum' : 10, 'text' : 'L7'},
3132	      \ {'filename' : 'F7', 'lnum' : 11, 'text' : 'L11'}], 'a')
3133  call assert_equal(8, g:Xgetlist({'changedtick' : 0}).changedtick)
3134  call g:Xsetlist([{'filename' : 'F7', 'lnum' : 10, 'text' : 'L7'},
3135	      \ {'filename' : 'F7', 'lnum' : 11, 'text' : 'L11'}], ' ')
3136  call assert_equal(1, g:Xgetlist({'changedtick' : 0}).changedtick)
3137  call g:Xsetlist([{'filename' : 'F7', 'lnum' : 10, 'text' : 'L7'},
3138	      \ {'filename' : 'F7', 'lnum' : 11, 'text' : 'L11'}], 'r')
3139  call assert_equal(2, g:Xgetlist({'changedtick' : 0}).changedtick)
3140
3141  call writefile(["F8:80:L80", "F8:81:L81"], "Xone")
3142  Xfile Xone
3143  call assert_equal(1, g:Xgetlist({'changedtick' : 0}).changedtick)
3144  Xaddfile Xone
3145  call assert_equal(2, g:Xgetlist({'changedtick' : 0}).changedtick)
3146
3147  " Test case for updating a non-current quickfix list
3148  call g:Xsetlist([], 'f')
3149  Xexpr "F1:1:L1"
3150  Xexpr "F2:2:L2"
3151  call g:Xsetlist([], 'a', {'nr' : 1, "lines" : ["F10:10:L10"]})
3152  call assert_equal(1, g:Xgetlist({'changedtick' : 0}).changedtick)
3153  call assert_equal(2, g:Xgetlist({'nr' : 1, 'changedtick' : 0}).changedtick)
3154
3155  call delete("Xone")
3156endfunc
3157
3158func Test_qf_tick()
3159  call Xqftick_tests('c')
3160  call Xqftick_tests('l')
3161endfunc
3162
3163" Test helpgrep with lang specifier
3164func Xtest_helpgrep_with_lang_specifier(cchar)
3165  call s:setup_commands(a:cchar)
3166  Xhelpgrep Vim@en
3167  call assert_equal('help', &filetype)
3168  call assert_notequal(0, g:Xgetlist({'nr' : '$'}).nr)
3169  new | only
3170endfunc
3171
3172func Test_helpgrep_with_lang_specifier()
3173  call Xtest_helpgrep_with_lang_specifier('c')
3174  call Xtest_helpgrep_with_lang_specifier('l')
3175endfunc
3176
3177" The following test used to crash Vim.
3178" Open the location list window and close the regular window associated with
3179" the location list. When the garbage collection runs now, it incorrectly
3180" marks the location list context as not in use and frees the context.
3181func Test_ll_window_ctx()
3182  call setloclist(0, [], 'f')
3183  call setloclist(0, [], 'a', {'context' : []})
3184  lopen | only
3185  call test_garbagecollect_now()
3186  echo getloclist(0, {'context' : 1}).context
3187  enew | only
3188endfunc
3189
3190" The following test used to crash vim
3191func Test_lfile_crash()
3192  sp Xtest
3193  au QuickFixCmdPre * bw
3194  call assert_fails('lfile', 'E40')
3195  au! QuickFixCmdPre
3196endfunc
3197
3198" The following test used to crash vim
3199func Test_lbuffer_crash()
3200  sv Xtest
3201  augroup QF_Test
3202    au!
3203    au * * bw
3204  augroup END
3205  lbuffer
3206  augroup QF_Test
3207    au!
3208  augroup END
3209endfunc
3210
3211" The following test used to crash vim
3212func Test_lexpr_crash()
3213  augroup QF_Test
3214    au!
3215    au * * call setloclist(0, [], 'f')
3216  augroup END
3217  lexpr ""
3218  augroup QF_Test
3219    au!
3220  augroup END
3221  enew | only
3222endfunc
3223
3224" The following test used to crash Vim
3225func Test_lvimgrep_crash()
3226  sv Xtest
3227  augroup QF_Test
3228    au!
3229    au * * call setloclist(0, [], 'f')
3230  augroup END
3231  lvimgrep quickfix test_quickfix.vim
3232  augroup QF_Test
3233    au!
3234  augroup END
3235  enew | only
3236endfunc
3237
3238" Test for the position of the quickfix and location list window
3239func Test_qfwin_pos()
3240  " Open two windows
3241  new | only
3242  new
3243  cexpr ['F1:10:L10']
3244  copen
3245  " Quickfix window should be the bottom most window
3246  call assert_equal(3, winnr())
3247  close
3248  " Open at the very top
3249  wincmd t
3250  topleft copen
3251  call assert_equal(1, winnr())
3252  close
3253  " open left of the current window
3254  wincmd t
3255  below new
3256  leftabove copen
3257  call assert_equal(2, winnr())
3258  close
3259  " open right of the current window
3260  rightbelow copen
3261  call assert_equal(3, winnr())
3262  close
3263endfunc
3264
3265" Tests for quickfix/location lists changed by autocommands when
3266" :vimgrep/:lvimgrep commands are running.
3267func Test_vimgrep_autocmd()
3268  call setqflist([], 'f')
3269  call writefile(['stars'], 'Xtest1.txt')
3270  call writefile(['stars'], 'Xtest2.txt')
3271
3272  " Test 1:
3273  " When searching for a pattern using :vimgrep, if the quickfix list is
3274  " changed by an autocmd, the results should be added to the correct quickfix
3275  " list.
3276  autocmd BufRead Xtest2.txt cexpr '' | cexpr ''
3277  silent vimgrep stars Xtest*.txt
3278  call assert_equal(1, getqflist({'nr' : 0}).nr)
3279  call assert_equal(3, getqflist({'nr' : '$'}).nr)
3280  call assert_equal('Xtest2.txt', bufname(getqflist()[1].bufnr))
3281  au! BufRead Xtest2.txt
3282
3283  " Test 2:
3284  " When searching for a pattern using :vimgrep, if the quickfix list is
3285  " freed, then a error should be given.
3286  silent! %bwipe!
3287  call setqflist([], 'f')
3288  autocmd BufRead Xtest2.txt for i in range(10) | cexpr '' | endfor
3289  call assert_fails('vimgrep stars Xtest*.txt', 'E925:')
3290  au! BufRead Xtest2.txt
3291
3292  " Test 3:
3293  " When searching for a pattern using :lvimgrep, if the location list is
3294  " freed, then the command should error out.
3295  silent! %bwipe!
3296  let g:save_winid = win_getid()
3297  autocmd BufRead Xtest2.txt call setloclist(g:save_winid, [], 'f')
3298  call assert_fails('lvimgrep stars Xtest*.txt', 'E926:')
3299  au! BufRead Xtest2.txt
3300
3301  call delete('Xtest1.txt')
3302  call delete('Xtest2.txt')
3303  call setqflist([], 'f')
3304endfunc
3305
3306" The following test used to crash Vim
3307func Test_lhelpgrep_autocmd()
3308  lhelpgrep quickfix
3309  autocmd QuickFixCmdPost * call setloclist(0, [], 'f')
3310  lhelpgrep buffer
3311  call assert_equal('help', &filetype)
3312  call assert_equal(0, getloclist(0, {'nr' : '$'}).nr)
3313  lhelpgrep tabpage
3314  call assert_equal('help', &filetype)
3315  call assert_equal(1, getloclist(0, {'nr' : '$'}).nr)
3316  au! QuickFixCmdPost
3317  new | only
3318endfunc
3319
3320" Test for shortening/simplifying the file name when opening the
3321" quickfix window or when displaying the quickfix list
3322func Test_shorten_fname()
3323  if !has('unix')
3324    return
3325  endif
3326  %bwipe
3327  " Create a quickfix list with a absolute path filename
3328  let fname = getcwd() . '/test_quickfix.vim'
3329  call setqflist([], ' ', {'lines':[fname . ":20:Line20"], 'efm':'%f:%l:%m'})
3330  call assert_equal(fname, bufname('test_quickfix.vim'))
3331  " Opening the quickfix window should simplify the file path
3332  cwindow
3333  call assert_equal('test_quickfix.vim', bufname('test_quickfix.vim'))
3334  cclose
3335  %bwipe
3336  " Create a quickfix list with a absolute path filename
3337  call setqflist([], ' ', {'lines':[fname . ":20:Line20"], 'efm':'%f:%l:%m'})
3338  call assert_equal(fname, bufname('test_quickfix.vim'))
3339  " Displaying the quickfix list should simplify the file path
3340  silent! clist
3341  call assert_equal('test_quickfix.vim', bufname('test_quickfix.vim'))
3342endfunc
3343
3344" Quickfix title tests
3345" In the below tests, 'exe "cmd"' is used to invoke the quickfix commands.
3346" Otherwise due to indentation, the title is set with spaces at the beginning
3347" of the command.
3348func Test_qftitle()
3349  call writefile(["F1:1:Line1"], 'Xerr')
3350
3351  " :cexpr
3352  exe "cexpr readfile('Xerr')"
3353  call assert_equal(":cexpr readfile('Xerr')", getqflist({'title' : 1}).title)
3354
3355  " :cgetexpr
3356  exe "cgetexpr readfile('Xerr')"
3357  call assert_equal(":cgetexpr readfile('Xerr')",
3358					\ getqflist({'title' : 1}).title)
3359
3360  " :caddexpr
3361  call setqflist([], 'f')
3362  exe "caddexpr readfile('Xerr')"
3363  call assert_equal(":caddexpr readfile('Xerr')",
3364					\ getqflist({'title' : 1}).title)
3365
3366  " :cbuffer
3367  new Xerr
3368  exe "cbuffer"
3369  call assert_equal(':cbuffer (Xerr)', getqflist({'title' : 1}).title)
3370
3371  " :cgetbuffer
3372  edit Xerr
3373  exe "cgetbuffer"
3374  call assert_equal(':cgetbuffer (Xerr)', getqflist({'title' : 1}).title)
3375
3376  " :caddbuffer
3377  call setqflist([], 'f')
3378  edit Xerr
3379  exe "caddbuffer"
3380  call assert_equal(':caddbuffer (Xerr)', getqflist({'title' : 1}).title)
3381
3382  " :cfile
3383  exe "cfile Xerr"
3384  call assert_equal(':cfile Xerr', getqflist({'title' : 1}).title)
3385
3386  " :cgetfile
3387  exe "cgetfile Xerr"
3388  call assert_equal(':cgetfile Xerr', getqflist({'title' : 1}).title)
3389
3390  " :caddfile
3391  call setqflist([], 'f')
3392  exe "caddfile Xerr"
3393  call assert_equal(':caddfile Xerr', getqflist({'title' : 1}).title)
3394
3395  " :grep
3396  set grepprg=internal
3397  exe "grep F1 Xerr"
3398  call assert_equal(':grep F1 Xerr', getqflist({'title' : 1}).title)
3399
3400  " :grepadd
3401  call setqflist([], 'f')
3402  exe "grepadd F1 Xerr"
3403  call assert_equal(':grepadd F1 Xerr', getqflist({'title' : 1}).title)
3404  set grepprg&vim
3405
3406  " :vimgrep
3407  exe "vimgrep F1 Xerr"
3408  call assert_equal(':vimgrep F1 Xerr', getqflist({'title' : 1}).title)
3409
3410  " :vimgrepadd
3411  call setqflist([], 'f')
3412  exe "vimgrepadd F1 Xerr"
3413  call assert_equal(':vimgrepadd F1 Xerr', getqflist({'title' : 1}).title)
3414
3415  call setqflist(['F1:10:L10'], ' ')
3416  call assert_equal(':setqflist()', getqflist({'title' : 1}).title)
3417
3418  call setqflist([], 'f')
3419  call setqflist(['F1:10:L10'], 'a')
3420  call assert_equal(':setqflist()', getqflist({'title' : 1}).title)
3421
3422  call setqflist([], 'f')
3423  call setqflist(['F1:10:L10'], 'r')
3424  call assert_equal(':setqflist()', getqflist({'title' : 1}).title)
3425
3426  close
3427  call delete('Xerr')
3428
3429  call setqflist([], ' ', {'title' : 'Errors'})
3430  copen
3431  call assert_equal('Errors', w:quickfix_title)
3432  call setqflist([], 'r', {'items' : [{'filename' : 'a.c', 'lnum' : 10}]})
3433  call assert_equal('Errors', w:quickfix_title)
3434  cclose
3435endfunc
3436
3437func Test_lbuffer_with_bwipe()
3438  new
3439  new
3440  augroup nasty
3441    au * * bwipe
3442  augroup END
3443  lbuffer
3444  augroup nasty
3445    au!
3446  augroup END
3447endfunc
3448
3449" Test for an autocmd freeing the quickfix/location list when cexpr/lexpr is
3450" running
3451func Xexpr_acmd_freelist(cchar)
3452  call s:setup_commands(a:cchar)
3453
3454  " This was using freed memory.
3455  augroup nasty
3456    au * * call g:Xsetlist([], 'f')
3457  augroup END
3458  Xexpr "x"
3459  augroup nasty
3460    au!
3461  augroup END
3462endfunc
3463
3464func Test_cexpr_acmd_freelist()
3465  call Xexpr_acmd_freelist('c')
3466  call Xexpr_acmd_freelist('l')
3467endfunc
3468
3469" Test for commands that create a new quickfix/location list and jump to the
3470" first error automatically.
3471func Xjumpto_first_error_test(cchar)
3472  call s:setup_commands(a:cchar)
3473
3474  call s:create_test_file('Xtestfile1')
3475  call s:create_test_file('Xtestfile2')
3476  let l = ['Xtestfile1:2:Line2', 'Xtestfile2:4:Line4']
3477
3478  " Test for cexpr/lexpr
3479  enew
3480  Xexpr l
3481  call assert_equal('Xtestfile1', bufname(''))
3482  call assert_equal(2, line('.'))
3483
3484  " Test for cfile/lfile
3485  enew
3486  call writefile(l, 'Xerr')
3487  Xfile Xerr
3488  call assert_equal('Xtestfile1', bufname(''))
3489  call assert_equal(2, line('.'))
3490
3491  " Test for cbuffer/lbuffer
3492  edit Xerr
3493  Xbuffer
3494  call assert_equal('Xtestfile1', bufname(''))
3495  call assert_equal(2, line('.'))
3496
3497  call delete('Xerr')
3498  call delete('Xtestfile1')
3499  call delete('Xtestfile2')
3500endfunc
3501
3502func Test_jumpto_first_error()
3503  call Xjumpto_first_error_test('c')
3504  call Xjumpto_first_error_test('l')
3505endfunc
3506
3507" Test for a quickfix autocmd changing the quickfix/location list before
3508" jumping to the first error in the new list.
3509func Xautocmd_changelist(cchar)
3510  call s:setup_commands(a:cchar)
3511
3512  " Test for cfile/lfile
3513  call s:create_test_file('Xtestfile1')
3514  call s:create_test_file('Xtestfile2')
3515  Xexpr 'Xtestfile1:2:Line2'
3516  autocmd QuickFixCmdPost * Xolder
3517  call writefile(['Xtestfile2:4:Line4'], 'Xerr')
3518  Xfile Xerr
3519  call assert_equal('Xtestfile2', bufname(''))
3520  call assert_equal(4, line('.'))
3521  autocmd! QuickFixCmdPost
3522
3523  " Test for cbuffer/lbuffer
3524  call g:Xsetlist([], 'f')
3525  Xexpr 'Xtestfile1:2:Line2'
3526  autocmd QuickFixCmdPost * Xolder
3527  call writefile(['Xtestfile2:4:Line4'], 'Xerr')
3528  edit Xerr
3529  Xbuffer
3530  call assert_equal('Xtestfile2', bufname(''))
3531  call assert_equal(4, line('.'))
3532  autocmd! QuickFixCmdPost
3533
3534  " Test for cexpr/lexpr
3535  call g:Xsetlist([], 'f')
3536  Xexpr 'Xtestfile1:2:Line2'
3537  autocmd QuickFixCmdPost * Xolder
3538  Xexpr 'Xtestfile2:4:Line4'
3539  call assert_equal('Xtestfile2', bufname(''))
3540  call assert_equal(4, line('.'))
3541  autocmd! QuickFixCmdPost
3542
3543  " The grepprg may not be set on non-Unix systems
3544  if has('unix')
3545    " Test for grep/lgrep
3546    call g:Xsetlist([], 'f')
3547    Xexpr 'Xtestfile1:2:Line2'
3548    autocmd QuickFixCmdPost * Xolder
3549    silent Xgrep Line5 Xtestfile2
3550    call assert_equal('Xtestfile2', bufname(''))
3551    call assert_equal(5, line('.'))
3552    autocmd! QuickFixCmdPost
3553  endif
3554
3555  " Test for vimgrep/lvimgrep
3556  call g:Xsetlist([], 'f')
3557  Xexpr 'Xtestfile1:2:Line2'
3558  autocmd QuickFixCmdPost * Xolder
3559  silent Xvimgrep Line5 Xtestfile2
3560  call assert_equal('Xtestfile2', bufname(''))
3561  call assert_equal(5, line('.'))
3562  autocmd! QuickFixCmdPost
3563
3564  " Test for autocommands clearing the quickfix list before jumping to the
3565  " first error. This should not result in an error
3566  autocmd QuickFixCmdPost * call g:Xsetlist([], 'r')
3567  let v:errmsg = ''
3568  " Test for cfile/lfile
3569  Xfile Xerr
3570  call assert_true(v:errmsg !~# 'E42:')
3571  " Test for cbuffer/lbuffer
3572  edit Xerr
3573  Xbuffer
3574  call assert_true(v:errmsg !~# 'E42:')
3575  " Test for cexpr/lexpr
3576  Xexpr 'Xtestfile2:4:Line4'
3577  call assert_true(v:errmsg !~# 'E42:')
3578  " Test for grep/lgrep
3579  " The grepprg may not be set on non-Unix systems
3580  if has('unix')
3581    silent Xgrep Line5 Xtestfile2
3582    call assert_true(v:errmsg !~# 'E42:')
3583  endif
3584  " Test for vimgrep/lvimgrep
3585  call assert_fails('silent Xvimgrep Line5 Xtestfile2', 'E480:')
3586  autocmd! QuickFixCmdPost
3587
3588  call delete('Xerr')
3589  call delete('Xtestfile1')
3590  call delete('Xtestfile2')
3591endfunc
3592
3593func Test_autocmd_changelist()
3594  call Xautocmd_changelist('c')
3595  call Xautocmd_changelist('l')
3596endfunc
3597
3598" Tests for the ':filter /pat/ clist' command
3599func Test_filter_clist()
3600  cexpr ['Xfile1:10:10:Line 10', 'Xfile2:15:15:Line 15']
3601  call assert_equal([' 2 Xfile2:15 col 15: Line 15'],
3602			\ split(execute('filter /Line 15/ clist'), "\n"))
3603  call assert_equal([' 1 Xfile1:10 col 10: Line 10'],
3604			\ split(execute('filter /Xfile1/ clist'), "\n"))
3605  call assert_equal([], split(execute('filter /abc/ clist'), "\n"))
3606
3607  call setqflist([{'module' : 'abc', 'pattern' : 'pat1'},
3608			\ {'module' : 'pqr', 'pattern' : 'pat2'}], ' ')
3609  call assert_equal([' 2 pqr:pat2:  '],
3610			\ split(execute('filter /pqr/ clist'), "\n"))
3611  call assert_equal([' 1 abc:pat1:  '],
3612			\ split(execute('filter /pat1/ clist'), "\n"))
3613endfunc
3614
3615" Tests for the "CTRL-W <CR>" command.
3616func Xview_result_split_tests(cchar)
3617  call s:setup_commands(a:cchar)
3618
3619  " Test that "CTRL-W <CR>" in a qf/ll window fails with empty list.
3620  call g:Xsetlist([])
3621  Xopen
3622  let l:win_count = winnr('$')
3623  call assert_fails('execute "normal! \<C-W>\<CR>"', 'E42')
3624  call assert_equal(l:win_count, winnr('$'))
3625  Xclose
3626endfunc
3627
3628func Test_view_result_split()
3629  call Xview_result_split_tests('c')
3630  call Xview_result_split_tests('l')
3631endfunc
3632
3633" Test that :cc sets curswant
3634func Test_curswant()
3635  helpgrep quickfix
3636  normal! llll
3637  1cc
3638  call assert_equal(getcurpos()[4], virtcol('.'))
3639  cclose | helpclose
3640endfunc
3641