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=* Xolder <mods>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 Xnfile <mods>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    let g:Xgetlist = function('getqflist')
40    let g:Xsetlist = function('setqflist')
41    call setqflist([], 'f')
42  else
43    command! -nargs=* -bang Xlist <mods>llist<bang> <args>
44    command! -nargs=* Xgetexpr <mods>lgetexpr <args>
45    command! -nargs=* Xaddexpr <mods>laddexpr <args>
46    command! -nargs=* Xolder <mods>lolder <args>
47    command! -nargs=* Xnewer <mods>lnewer <args>
48    command! -nargs=* Xopen <mods>lopen <args>
49    command! -nargs=* Xwindow <mods>lwindow <args>
50    command! -nargs=* Xbottom <mods>lbottom <args>
51    command! -nargs=* Xclose <mods>lclose <args>
52    command! -nargs=* -bang Xfile <mods>lfile<bang> <args>
53    command! -nargs=* Xgetfile <mods>lgetfile <args>
54    command! -nargs=* Xaddfile <mods>laddfile <args>
55    command! -nargs=* -bang Xbuffer <mods>lbuffer<bang> <args>
56    command! -nargs=* Xgetbuffer <mods>lgetbuffer <args>
57    command! -nargs=* Xaddbuffer <mods>laddbuffer <args>
58    command! -nargs=* Xrewind <mods>lrewind <args>
59    command! -count -nargs=* -bang Xnext <mods><count>lnext<bang> <args>
60    command! -count -nargs=* -bang Xprev <mods><count>lprev<bang> <args>
61    command! -nargs=* -bang Xfirst <mods>lfirst<bang> <args>
62    command! -nargs=* -bang Xlast <mods>llast<bang> <args>
63    command! -nargs=* -bang Xnfile <mods>lnfile<bang> <args>
64    command! -nargs=* -bang Xpfile <mods>lpfile<bang> <args>
65    command! -nargs=* Xexpr <mods>lexpr <args>
66    command! -range -nargs=* Xvimgrep <mods><count>lvimgrep <args>
67    command! -nargs=* Xvimgrepadd <mods>lvimgrepadd <args>
68    command! -nargs=* Xgrep <mods> lgrep <args>
69    command! -nargs=* Xgrepadd <mods> lgrepadd <args>
70    command! -nargs=* Xhelpgrep lhelpgrep <args>
71    let g:Xgetlist = function('getloclist', [0])
72    let g:Xsetlist = function('setloclist', [0])
73    call setloclist(0, [], 'f')
74  endif
75endfunc
76
77" Tests for the :clist and :llist commands
78func XlistTests(cchar)
79  call s:setup_commands(a:cchar)
80
81  if a:cchar == 'l'
82      call assert_fails('llist', 'E776:')
83  endif
84  " With an empty list, command should return error
85  Xgetexpr []
86  silent! Xlist
87  call assert_true(v:errmsg ==# 'E42: No Errors')
88
89  " Populate the list and then try
90  Xgetexpr ['non-error 1', 'Xtestfile1:1:3:Line1',
91		  \ 'non-error 2', 'Xtestfile2:2:2:Line2',
92		  \ 'non-error 3', 'Xtestfile3:3:1:Line3']
93
94  " List only valid entries
95  let l = split(execute('Xlist', ''), "\n")
96  call assert_equal([' 2 Xtestfile1:1 col 3: Line1',
97		   \ ' 4 Xtestfile2:2 col 2: Line2',
98		   \ ' 6 Xtestfile3:3 col 1: Line3'], l)
99
100  " List all the entries
101  let l = split(execute('Xlist!', ''), "\n")
102  call assert_equal([' 1: non-error 1', ' 2 Xtestfile1:1 col 3: Line1',
103		   \ ' 3: non-error 2', ' 4 Xtestfile2:2 col 2: Line2',
104		   \ ' 5: non-error 3', ' 6 Xtestfile3:3 col 1: Line3'], l)
105
106  " List a range of errors
107  let l = split(execute('Xlist 3,6', ''), "\n")
108  call assert_equal([' 4 Xtestfile2:2 col 2: Line2',
109		   \ ' 6 Xtestfile3:3 col 1: Line3'], l)
110
111  let l = split(execute('Xlist! 3,4', ''), "\n")
112  call assert_equal([' 3: non-error 2', ' 4 Xtestfile2:2 col 2: Line2'], l)
113
114  let l = split(execute('Xlist -6,-4', ''), "\n")
115  call assert_equal([' 2 Xtestfile1:1 col 3: Line1'], l)
116
117  let l = split(execute('Xlist! -5,-3', ''), "\n")
118  call assert_equal([' 2 Xtestfile1:1 col 3: Line1',
119		   \ ' 3: non-error 2', ' 4 Xtestfile2:2 col 2: Line2'], l)
120
121  " Test for '+'
122  let l = split(execute('Xlist! +2', ''), "\n")
123  call assert_equal([' 2 Xtestfile1:1 col 3: Line1',
124		   \ ' 3: non-error 2', ' 4 Xtestfile2:2 col 2: Line2'], l)
125
126  " Different types of errors
127  call g:Xsetlist([{'lnum':10,'col':5,'type':'W', 'text':'Warning','nr':11},
128	      \ {'lnum':20,'col':10,'type':'e','text':'Error','nr':22},
129	      \ {'lnum':30,'col':15,'type':'i','text':'Info','nr':33},
130	      \ {'lnum':40,'col':20,'type':'x', 'text':'Other','nr':44},
131	      \ {'lnum':50,'col':25,'type':"\<C-A>",'text':'one','nr':55}])
132  let l = split(execute('Xlist', ""), "\n")
133  call assert_equal([' 1:10 col 5 warning  11: Warning',
134	      \ ' 2:20 col 10 error  22: Error',
135	      \ ' 3:30 col 15 info  33: Info',
136	      \ ' 4:40 col 20 x  44: Other',
137	      \ ' 5:50 col 25  55: one'], l)
138
139  " Error cases
140  call assert_fails('Xlist abc', 'E488:')
141endfunc
142
143func Test_clist()
144  call XlistTests('c')
145  call XlistTests('l')
146endfunc
147
148" Tests for the :colder, :cnewer, :lolder and :lnewer commands
149" Note that this test assumes that a quickfix/location list is
150" already set by the caller.
151func XageTests(cchar)
152  call s:setup_commands(a:cchar)
153
154  let list = [{'bufnr': 1, 'lnum': 1}]
155  call g:Xsetlist(list)
156
157  " Jumping to a non existent list should return error
158  silent! Xolder 99
159  call assert_true(v:errmsg ==# 'E380: At bottom of quickfix stack')
160
161  silent! Xnewer 99
162  call assert_true(v:errmsg ==# 'E381: At top of quickfix stack')
163
164  " Add three quickfix/location lists
165  Xgetexpr ['Xtestfile1:1:3:Line1']
166  Xgetexpr ['Xtestfile2:2:2:Line2']
167  Xgetexpr ['Xtestfile3:3:1:Line3']
168
169  " Go back two lists
170  Xolder
171  let l = g:Xgetlist()
172  call assert_equal('Line2', l[0].text)
173
174  " Go forward two lists
175  Xnewer
176  let l = g:Xgetlist()
177  call assert_equal('Line3', l[0].text)
178
179  " Test for the optional count argument
180  Xolder 2
181  let l = g:Xgetlist()
182  call assert_equal('Line1', l[0].text)
183
184  Xnewer 2
185  let l = g:Xgetlist()
186  call assert_equal('Line3', l[0].text)
187endfunc
188
189func Test_cage()
190  call XageTests('c')
191  call XageTests('l')
192endfunc
193
194" Tests for the :cwindow, :lwindow :cclose, :lclose, :copen and :lopen
195" commands
196func XwindowTests(cchar)
197  call s:setup_commands(a:cchar)
198
199  " Opening the location list window without any errors should fail
200  if a:cchar == 'l'
201      call assert_fails('lopen', 'E776:')
202  endif
203
204  " Create a list with no valid entries
205  Xgetexpr ['non-error 1', 'non-error 2', 'non-error 3']
206
207  " Quickfix/Location window should not open with no valid errors
208  Xwindow
209  call assert_true(winnr('$') == 1)
210
211  " Create a list with valid entries
212  Xgetexpr ['Xtestfile1:1:3:Line1', 'Xtestfile2:2:2:Line2',
213		  \ 'Xtestfile3:3:1:Line3']
214
215  " Open the window
216  Xwindow
217  call assert_true(winnr('$') == 2 && winnr() == 2 &&
218	\ getline('.') ==# 'Xtestfile1|1 col 3| Line1')
219  redraw!
220
221  " Close the window
222  Xclose
223  call assert_true(winnr('$') == 1)
224
225  " Create a list with no valid entries
226  Xgetexpr ['non-error 1', 'non-error 2', 'non-error 3']
227
228  " Open the window
229  Xopen 5
230  call assert_true(winnr('$') == 2 && getline('.') ==# '|| non-error 1'
231		      \  && winheight('.') == 5)
232
233  " Opening the window again, should move the cursor to that window
234  wincmd t
235  Xopen 7
236  call assert_true(winnr('$') == 2 && winnr() == 2 &&
237	\ winheight('.') == 7 &&
238	\ getline('.') ==# '|| non-error 1')
239
240
241  " Calling cwindow should close the quickfix window with no valid errors
242  Xwindow
243  call assert_true(winnr('$') == 1)
244
245  if a:cchar == 'c'
246      " Opening the quickfix window in multiple tab pages should reuse the
247      " quickfix buffer
248      Xgetexpr ['Xtestfile1:1:3:Line1', 'Xtestfile2:2:2:Line2',
249		  \ 'Xtestfile3:3:1:Line3']
250      Xopen
251      let qfbufnum = bufnr('%')
252      tabnew
253      Xopen
254      call assert_equal(qfbufnum, bufnr('%'))
255      new | only | tabonly
256  endif
257endfunc
258
259func Test_cwindow()
260  call XwindowTests('c')
261  call XwindowTests('l')
262endfunc
263
264" Tests for the :cfile, :lfile, :caddfile, :laddfile, :cgetfile and :lgetfile
265" commands.
266func XfileTests(cchar)
267  call s:setup_commands(a:cchar)
268
269  call writefile(['Xtestfile1:700:10:Line 700',
270	\ 'Xtestfile2:800:15:Line 800'], 'Xqftestfile1')
271
272  enew!
273  Xfile Xqftestfile1
274  let l = g:Xgetlist()
275  call assert_true(len(l) == 2 &&
276	\ l[0].lnum == 700 && l[0].col == 10 && l[0].text ==# 'Line 700' &&
277	\ l[1].lnum == 800 && l[1].col == 15 && l[1].text ==# 'Line 800')
278
279  " Test with a non existent file
280  call assert_fails('Xfile non_existent_file', 'E40')
281
282  " Run cfile/lfile from a modified buffer
283  enew!
284  silent! put ='Quickfix'
285  silent! Xfile Xqftestfile1
286  call assert_true(v:errmsg ==# 'E37: No write since last change (add ! to override)')
287
288  call writefile(['Xtestfile3:900:30:Line 900'], 'Xqftestfile1')
289  Xaddfile Xqftestfile1
290  let l = g:Xgetlist()
291  call assert_true(len(l) == 3 &&
292	\ l[2].lnum == 900 && l[2].col == 30 && l[2].text ==# 'Line 900')
293
294  call writefile(['Xtestfile1:222:77:Line 222',
295	\ 'Xtestfile2:333:88:Line 333'], 'Xqftestfile1')
296
297  enew!
298  Xgetfile Xqftestfile1
299  let l = g:Xgetlist()
300  call assert_true(len(l) == 2 &&
301	\ l[0].lnum == 222 && l[0].col == 77 && l[0].text ==# 'Line 222' &&
302	\ l[1].lnum == 333 && l[1].col == 88 && l[1].text ==# 'Line 333')
303
304  call delete('Xqftestfile1')
305endfunc
306
307func Test_cfile()
308  call XfileTests('c')
309  call XfileTests('l')
310endfunc
311
312" Tests for the :cbuffer, :lbuffer, :caddbuffer, :laddbuffer, :cgetbuffer and
313" :lgetbuffer commands.
314func XbufferTests(cchar)
315  call s:setup_commands(a:cchar)
316
317  enew!
318  silent! call setline(1, ['Xtestfile7:700:10:Line 700',
319	\ 'Xtestfile8:800:15:Line 800'])
320  Xbuffer!
321  let l = g:Xgetlist()
322  call assert_true(len(l) == 2 &&
323	\ l[0].lnum == 700 && l[0].col == 10 && l[0].text ==# 'Line 700' &&
324	\ l[1].lnum == 800 && l[1].col == 15 && l[1].text ==# 'Line 800')
325
326  enew!
327  silent! call setline(1, ['Xtestfile9:900:55:Line 900',
328	\ 'Xtestfile10:950:66:Line 950'])
329  Xgetbuffer
330  let l = g:Xgetlist()
331  call assert_true(len(l) == 2 &&
332	\ l[0].lnum == 900 && l[0].col == 55 && l[0].text ==# 'Line 900' &&
333	\ l[1].lnum == 950 && l[1].col == 66 && l[1].text ==# 'Line 950')
334
335  enew!
336  silent! call setline(1, ['Xtestfile11:700:20:Line 700',
337	\ 'Xtestfile12:750:25:Line 750'])
338  Xaddbuffer
339  let l = g:Xgetlist()
340  call assert_true(len(l) == 4 &&
341	\ l[1].lnum == 950 && l[1].col == 66 && l[1].text ==# 'Line 950' &&
342	\ l[2].lnum == 700 && l[2].col == 20 && l[2].text ==# 'Line 700' &&
343	\ l[3].lnum == 750 && l[3].col == 25 && l[3].text ==# 'Line 750')
344  enew!
345
346  " Check for invalid buffer
347  call assert_fails('Xbuffer 199', 'E474:')
348
349  " Check for unloaded buffer
350  edit Xtestfile1
351  let bnr = bufnr('%')
352  enew!
353  call assert_fails('Xbuffer ' . bnr, 'E681:')
354
355  " Check for invalid range
356  " Using Xbuffer will not run the range check in the cbuffer/lbuffer
357  " commands. So directly call the commands.
358  if (a:cchar == 'c')
359      call assert_fails('900,999cbuffer', 'E16:')
360  else
361      call assert_fails('900,999lbuffer', 'E16:')
362  endif
363endfunc
364
365func Test_cbuffer()
366  call XbufferTests('c')
367  call XbufferTests('l')
368endfunc
369
370func XexprTests(cchar)
371  call s:setup_commands(a:cchar)
372
373  call assert_fails('Xexpr 10', 'E777:')
374endfunc
375
376func Test_cexpr()
377  call XexprTests('c')
378  call XexprTests('l')
379endfunc
380
381" Tests for :cnext, :cprev, :cfirst, :clast commands
382func Xtest_browse(cchar)
383  call s:setup_commands(a:cchar)
384
385  " Jumping to first or next location list entry without any error should
386  " result in failure
387  if a:cchar == 'l'
388      call assert_fails('lfirst', 'E776:')
389      call assert_fails('lnext', 'E776:')
390  endif
391
392  call s:create_test_file('Xqftestfile1')
393  call s:create_test_file('Xqftestfile2')
394
395  Xgetexpr ['Xqftestfile1:5:Line5',
396		\ 'Xqftestfile1:6:Line6',
397		\ 'Xqftestfile2:10:Line10',
398		\ 'Xqftestfile2:11:Line11',
399		\ 'RegularLine1',
400		\ 'RegularLine2']
401
402  Xfirst
403  call assert_fails('Xprev', 'E553')
404  call assert_fails('Xpfile', 'E553')
405  Xnfile
406  call assert_equal('Xqftestfile2', bufname('%'))
407  call assert_equal(10, line('.'))
408  Xpfile
409  call assert_equal('Xqftestfile1', bufname('%'))
410  call assert_equal(6, line('.'))
411  Xlast
412  Xprev
413  call assert_equal('Xqftestfile2', bufname('%'))
414  call assert_equal(11, line('.'))
415  call assert_fails('Xnext', 'E553')
416  call assert_fails('Xnfile', 'E553')
417  Xrewind
418  call assert_equal('Xqftestfile1', bufname('%'))
419  call assert_equal(5, line('.'))
420
421  10Xnext
422  call assert_equal('Xqftestfile2', bufname('%'))
423  call assert_equal(11, line('.'))
424  10Xprev
425  call assert_equal('Xqftestfile1', bufname('%'))
426  call assert_equal(5, line('.'))
427
428  Xexpr ""
429  call assert_fails('Xnext', 'E42:')
430
431  call delete('Xqftestfile1')
432  call delete('Xqftestfile2')
433endfunc
434
435func Test_browse()
436  call Xtest_browse('c')
437  call Xtest_browse('l')
438endfunc
439
440func Test_nomem()
441  call test_alloc_fail(GetAllocId('qf_dirname_start'), 0, 0)
442  call assert_fails('vimgrep vim runtest.vim', 'E342:')
443
444  call test_alloc_fail(GetAllocId('qf_dirname_now'), 0, 0)
445  call assert_fails('vimgrep vim runtest.vim', 'E342:')
446
447  call test_alloc_fail(GetAllocId('qf_namebuf'), 0, 0)
448  call assert_fails('cfile runtest.vim', 'E342:')
449
450  call test_alloc_fail(GetAllocId('qf_errmsg'), 0, 0)
451  call assert_fails('cfile runtest.vim', 'E342:')
452
453  call test_alloc_fail(GetAllocId('qf_pattern'), 0, 0)
454  call assert_fails('cfile runtest.vim', 'E342:')
455
456endfunc
457
458func s:test_xhelpgrep(cchar)
459  call s:setup_commands(a:cchar)
460  Xhelpgrep quickfix
461  Xopen
462  if a:cchar == 'c'
463    let title_text = ':helpgrep quickfix'
464  else
465    let title_text = ':lhelpgrep quickfix'
466  endif
467  call assert_true(w:quickfix_title =~ title_text, w:quickfix_title)
468
469  " Jumping to a help topic should open the help window
470  only
471  Xnext
472  call assert_true(&buftype == 'help')
473  call assert_true(winnr('$') == 2)
474  " Jumping to the next match should reuse the help window
475  Xnext
476  call assert_true(&buftype == 'help')
477  call assert_true(winnr() == 1)
478  call assert_true(winnr('$') == 2)
479  " Jumping to the next match from the quickfix window should reuse the help
480  " window
481  Xopen
482  Xnext
483  call assert_true(&buftype == 'help')
484  call assert_true(winnr() == 1)
485  call assert_true(winnr('$') == 2)
486
487  " This wipes out the buffer, make sure that doesn't cause trouble.
488  Xclose
489
490  new | only
491
492  " Search for non existing help string
493  call assert_fails('Xhelpgrep a1b2c3', 'E480:')
494endfunc
495
496func Test_helpgrep()
497  call s:test_xhelpgrep('c')
498  helpclose
499  call s:test_xhelpgrep('l')
500endfunc
501
502func Test_errortitle()
503  augroup QfBufWinEnter
504    au!
505    au BufWinEnter * :let g:a=get(w:, 'quickfix_title', 'NONE')
506  augroup END
507  copen
508  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'')'}]
509  call setqflist(a)
510  call assert_equal(':setqflist()', g:a)
511  augroup QfBufWinEnter
512    au!
513  augroup END
514  augroup! QfBufWinEnter
515endfunc
516
517func Test_vimgreptitle()
518  augroup QfBufWinEnter
519    au!
520    au BufWinEnter * :let g:a=get(w:, 'quickfix_title', 'NONE')
521  augroup END
522  try
523    vimgrep /pattern/j file
524  catch /E480/
525  endtry
526  copen
527  call assert_equal(':    vimgrep /pattern/j file', g:a)
528  augroup QfBufWinEnter
529    au!
530  augroup END
531  augroup! QfBufWinEnter
532endfunc
533
534func XqfTitleTests(cchar)
535  call s:setup_commands(a:cchar)
536
537  Xgetexpr ['file:1:1:message']
538  let l = g:Xgetlist()
539  if a:cchar == 'c'
540    call setqflist(l, 'r')
541  else
542    call setloclist(0, l, 'r')
543  endif
544
545  Xopen
546  if a:cchar == 'c'
547    let title = ':setqflist()'
548  else
549    let title = ':setloclist()'
550  endif
551  call assert_equal(title, w:quickfix_title)
552  Xclose
553endfunc
554
555" Tests for quickfix window's title
556func Test_qf_title()
557  call XqfTitleTests('c')
558  call XqfTitleTests('l')
559endfunc
560
561" Tests for 'errorformat'
562func Test_efm()
563  let save_efm = &efm
564  set efm=%EEEE%m,%WWWW%m,%+CCCC%.%#,%-GGGG%.%#
565  cgetexpr ['WWWW', 'EEEE', 'CCCC']
566  let l = strtrans(string(map(getqflist(), '[v:val.text, v:val.valid]')))
567  call assert_equal("[['W', 1], ['E^@CCCC', 1]]", l)
568  cgetexpr ['WWWW', 'GGGG', 'EEEE', 'CCCC']
569  let l = strtrans(string(map(getqflist(), '[v:val.text, v:val.valid]')))
570  call assert_equal("[['W', 1], ['E^@CCCC', 1]]", l)
571  cgetexpr ['WWWW', 'GGGG', 'ZZZZ', 'EEEE', 'CCCC', 'YYYY']
572  let l = strtrans(string(map(getqflist(), '[v:val.text, v:val.valid]')))
573  call assert_equal("[['W', 1], ['ZZZZ', 0], ['E^@CCCC', 1], ['YYYY', 0]]", l)
574  let &efm = save_efm
575endfunc
576
577" This will test for problems in quickfix:
578" A. incorrectly copying location lists which caused the location list to show
579"    a different name than the file that was actually being displayed.
580" B. not reusing the window for which the location list window is opened but
581"    instead creating new windows.
582" C. make sure that the location list window is not reused instead of the
583"    window it belongs to.
584"
585" Set up the test environment:
586func ReadTestProtocol(name)
587  let base = substitute(a:name, '\v^test://(.*)%(\.[^.]+)?', '\1', '')
588  let word = substitute(base, '\v(.*)\..*', '\1', '')
589
590  setl modifiable
591  setl noreadonly
592  setl noswapfile
593  setl bufhidden=delete
594  %del _
595  " For problem 2:
596  " 'buftype' has to be set to reproduce the constant opening of new windows
597  setl buftype=nofile
598
599  call setline(1, word)
600
601  setl nomodified
602  setl nomodifiable
603  setl readonly
604  exe 'doautocmd BufRead ' . substitute(a:name, '\v^test://(.*)', '\1', '')
605endfunc
606
607func Test_locationlist()
608    enew
609
610    augroup testgroup
611      au!
612      autocmd BufReadCmd test://* call ReadTestProtocol(expand("<amatch>"))
613    augroup END
614
615    let words = [ "foo", "bar", "baz", "quux", "shmoo", "spam", "eggs" ]
616
617    let qflist = []
618    for word in words
619      call add(qflist, {'filename': 'test://' . word . '.txt', 'text': 'file ' . word . '.txt', })
620      " NOTE: problem 1:
621      " intentionally not setting 'lnum' so that the quickfix entries are not
622      " valid
623      call setloclist(0, qflist, ' ')
624    endfor
625
626    " Test A
627    lrewind
628    enew
629    lopen
630    4lnext
631    vert split
632    wincmd L
633    lopen
634    wincmd p
635    lnext
636    let fileName = expand("%")
637    wincmd p
638    let locationListFileName = substitute(getline(line('.')), '\([^|]*\)|.*', '\1', '')
639    let fileName = substitute(fileName, '\\', '/', 'g')
640    let locationListFileName = substitute(locationListFileName, '\\', '/', 'g')
641    call assert_equal("test://bar.txt", fileName)
642    call assert_equal("test://bar.txt", locationListFileName)
643
644    wincmd n | only
645
646    " Test B:
647    lrewind
648    lopen
649    2
650    exe "normal \<CR>"
651    wincmd p
652    3
653    exe "normal \<CR>"
654    wincmd p
655    4
656    exe "normal \<CR>"
657    call assert_equal(2, winnr('$'))
658    wincmd n | only
659
660    " Test C:
661    lrewind
662    lopen
663    " Let's move the location list window to the top to check whether it (the
664    " first window found) will be reused when we try to open new windows:
665    wincmd K
666    2
667    exe "normal \<CR>"
668    wincmd p
669    3
670    exe "normal \<CR>"
671    wincmd p
672    4
673    exe "normal \<CR>"
674    1wincmd w
675    call assert_equal('quickfix', &buftype)
676    2wincmd w
677    let bufferName = expand("%")
678    let bufferName = substitute(bufferName, '\\', '/', 'g')
679    call assert_equal('test://quux.txt', bufferName)
680
681    wincmd n | only
682
683    augroup! testgroup
684endfunc
685
686func Test_locationlist_curwin_was_closed()
687    augroup testgroup
688      au!
689      autocmd BufReadCmd test_curwin.txt call R(expand("<amatch>"))
690    augroup END
691
692    func! R(n)
693      quit
694    endfunc
695
696    new
697    let q = []
698    call add(q, {'filename': 'test_curwin.txt' })
699    call setloclist(0, q)
700    call assert_fails('lrewind', 'E924:')
701
702    augroup! testgroup
703endfunc
704
705func Test_locationlist_cross_tab_jump()
706  call writefile(['loclistfoo'], 'loclistfoo')
707  call writefile(['loclistbar'], 'loclistbar')
708  set switchbuf=usetab
709
710  edit loclistfoo
711  tabedit loclistbar
712  silent lgrep loclistfoo loclist*
713  call assert_equal(1, tabpagenr())
714
715  enew | only | tabonly
716  set switchbuf&vim
717  call delete('loclistfoo')
718  call delete('loclistbar')
719endfunc
720
721" More tests for 'errorformat'
722func Test_efm1()
723    if !has('unix')
724	" The 'errorformat' setting is different on non-Unix systems.
725	" This test works only on Unix-like systems.
726	return
727    endif
728
729    let l = [
730      \ '"Xtestfile", line 4.12: 1506-045 (S) Undeclared identifier fd_set.',
731      \ '"Xtestfile", line 6 col 19; this is an error',
732      \ 'gcc -c -DHAVE_CONFIsing-prototypes -I/usr/X11R6/include  version.c',
733      \ 'Xtestfile:9: parse error before `asd''',
734      \ 'make: *** [vim] Error 1',
735      \ 'in file "Xtestfile" linenr 10: there is an error',
736      \ '',
737      \ '2 returned',
738      \ '"Xtestfile", line 11 col 1; this is an error',
739      \ '"Xtestfile", line 12 col 2; this is another error',
740      \ '"Xtestfile", line 14:10; this is an error in column 10',
741      \ '=Xtestfile=, line 15:10; this is another error, but in vcol 10 this time',
742      \ '"Xtestfile", linenr 16: yet another problem',
743      \ 'Error in "Xtestfile" at line 17:',
744      \ 'x should be a dot',
745      \ '	xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx    line 17',
746      \ '            ^',
747      \ 'Error in "Xtestfile" at line 18:',
748      \ 'x should be a dot',
749      \ '	xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx    line 18',
750      \ '.............^',
751      \ 'Error in "Xtestfile" at line 19:',
752      \ 'x should be a dot',
753      \ '	xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx    line 19',
754      \ '--------------^',
755      \ 'Error in "Xtestfile" at line 20:',
756      \ 'x should be a dot',
757      \ '	xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx    line 20',
758      \ '	       ^',
759      \ '',
760      \ 'Does anyone know what is the problem and how to correction it?',
761      \ '"Xtestfile", line 21 col 9: What is the title of the quickfix window?',
762      \ '"Xtestfile", line 22 col 9: What is the title of the quickfix window?'
763      \ ]
764
765    call writefile(l, 'Xerrorfile1')
766    call writefile(l[:-2], 'Xerrorfile2')
767
768    let m = [
769	\ '	xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx    line  2',
770	\ '	xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx    line  3',
771	\ '	xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx    line  4',
772	\ '	xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx    line  5',
773	\ '	xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx    line  6',
774	\ '	xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx    line  7',
775	\ '	xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx    line  8',
776	\ '	xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx    line  9',
777	\ '	xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx    line 10',
778	\ '	xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx    line 11',
779	\ '	xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx    line 12',
780	\ '	xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx    line 13',
781	\ '	xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx    line 14',
782	\ '	xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx    line 15',
783	\ '	xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx    line 16',
784	\ '	xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx    line 17',
785	\ '	xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx    line 18',
786	\ '	xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx    line 19',
787	\ '	xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx    line 20',
788	\ '	xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx    line 21',
789	\ '	xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx    line 22'
790	\ ]
791    call writefile(m, 'Xtestfile')
792
793    let save_efm = &efm
794    set efm+==%f=\\,\ line\ %l%*\\D%v%*[^\ ]\ %m
795    set efm^=%AError\ in\ \"%f\"\ at\ line\ %l:,%Z%p^,%C%m
796
797    exe 'cf Xerrorfile2'
798    clast
799    copen
800    call assert_equal(':cf Xerrorfile2', w:quickfix_title)
801    wincmd p
802
803    exe 'cf Xerrorfile1'
804    call assert_equal([4, 12], [line('.'), col('.')])
805    cn
806    call assert_equal([6, 19], [line('.'), col('.')])
807    cn
808    call assert_equal([9, 2], [line('.'), col('.')])
809    cn
810    call assert_equal([10, 2], [line('.'), col('.')])
811    cn
812    call assert_equal([11, 1], [line('.'), col('.')])
813    cn
814    call assert_equal([12, 2], [line('.'), col('.')])
815    cn
816    call assert_equal([14, 10], [line('.'), col('.')])
817    cn
818    call assert_equal([15, 3, 10], [line('.'), col('.'), virtcol('.')])
819    cn
820    call assert_equal([16, 2], [line('.'), col('.')])
821    cn
822    call assert_equal([17, 6], [line('.'), col('.')])
823    cn
824    call assert_equal([18, 7], [line('.'), col('.')])
825    cn
826    call assert_equal([19, 8], [line('.'), col('.')])
827    cn
828    call assert_equal([20, 9], [line('.'), col('.')])
829    clast
830    cprev
831    cprev
832    wincmd w
833    call assert_equal(':cf Xerrorfile1', w:quickfix_title)
834    wincmd p
835
836    let &efm = save_efm
837    call delete('Xerrorfile1')
838    call delete('Xerrorfile2')
839    call delete('Xtestfile')
840endfunc
841
842" Test for quickfix directory stack support
843func s:dir_stack_tests(cchar)
844  call s:setup_commands(a:cchar)
845
846  let save_efm=&efm
847  set efm=%DEntering\ dir\ '%f',%f:%l:%m,%XLeaving\ dir\ '%f'
848
849  let lines = ["Entering dir 'dir1/a'",
850		\ 'habits2.txt:1:Nine Healthy Habits',
851		\ "Entering dir 'b'",
852		\ 'habits3.txt:2:0 Hours of television',
853		\ 'habits2.txt:7:5 Small meals',
854		\ "Entering dir 'dir1/c'",
855		\ 'habits4.txt:3:1 Hour of exercise',
856		\ "Leaving dir 'dir1/c'",
857		\ "Leaving dir 'dir1/a'",
858		\ 'habits1.txt:4:2 Liters of water',
859		\ "Entering dir 'dir2'",
860		\ 'habits5.txt:5:3 Cups of hot green tea',
861		\ "Leaving dir 'dir2'"
862		\]
863
864  Xexpr ""
865  for l in lines
866      Xaddexpr l
867  endfor
868
869  let qf = g:Xgetlist()
870
871  call assert_equal('dir1/a/habits2.txt', bufname(qf[1].bufnr))
872  call assert_equal(1, qf[1].lnum)
873  call assert_equal('dir1/a/b/habits3.txt', bufname(qf[3].bufnr))
874  call assert_equal(2, qf[3].lnum)
875  call assert_equal('dir1/a/habits2.txt', bufname(qf[4].bufnr))
876  call assert_equal(7, qf[4].lnum)
877  call assert_equal('dir1/c/habits4.txt', bufname(qf[6].bufnr))
878  call assert_equal(3, qf[6].lnum)
879  call assert_equal('habits1.txt', bufname(qf[9].bufnr))
880  call assert_equal(4, qf[9].lnum)
881  call assert_equal('dir2/habits5.txt', bufname(qf[11].bufnr))
882  call assert_equal(5, qf[11].lnum)
883
884  let &efm=save_efm
885endfunc
886
887" Tests for %D and %X errorformat options
888func Test_efm_dirstack()
889  " Create the directory stack and files
890  call mkdir('dir1')
891  call mkdir('dir1/a')
892  call mkdir('dir1/a/b')
893  call mkdir('dir1/c')
894  call mkdir('dir2')
895
896  let lines = ["Nine Healthy Habits",
897		\ "0 Hours of television",
898		\ "1 Hour of exercise",
899		\ "2 Liters of water",
900		\ "3 Cups of hot green tea",
901		\ "4 Short mental breaks",
902		\ "5 Small meals",
903		\ "6 AM wake up time",
904		\ "7 Minutes of laughter",
905		\ "8 Hours of sleep (at least)",
906		\ "9 PM end of the day and off to bed"
907		\ ]
908  call writefile(lines, 'habits1.txt')
909  call writefile(lines, 'dir1/a/habits2.txt')
910  call writefile(lines, 'dir1/a/b/habits3.txt')
911  call writefile(lines, 'dir1/c/habits4.txt')
912  call writefile(lines, 'dir2/habits5.txt')
913
914  call s:dir_stack_tests('c')
915  call s:dir_stack_tests('l')
916
917  call delete('dir1', 'rf')
918  call delete('dir2', 'rf')
919  call delete('habits1.txt')
920endfunc
921
922" Test for resync after continuing an ignored message
923func Xefm_ignore_continuations(cchar)
924  call s:setup_commands(a:cchar)
925
926  let save_efm = &efm
927
928  let &efm =
929	\ '%Eerror %m %l,' .
930	\ '%-Wignored %m %l,' .
931	\ '%+Cmore ignored %m %l,' .
932	\ '%Zignored end'
933  Xgetexpr ['ignored warning 1', 'more ignored continuation 2', 'ignored end', 'error resync 4']
934  let l = map(g:Xgetlist(), '[v:val.text, v:val.valid, v:val.lnum, v:val.type]')
935  call assert_equal([['resync', 1, 4, 'E']], l)
936
937  let &efm = save_efm
938endfunc
939
940func Test_efm_ignore_continuations()
941  call Xefm_ignore_continuations('c')
942  call Xefm_ignore_continuations('l')
943endfunc
944
945" Tests for invalid error format specifies
946func Xinvalid_efm_Tests(cchar)
947  call s:setup_commands(a:cchar)
948
949  let save_efm = &efm
950
951  set efm=%f:%l:%m,%f:%f:%l:%m
952  call assert_fails('Xexpr "abc.txt:1:Hello world"', 'E372:')
953
954  set efm=%f:%l:%m,%f:%l:%r:%m
955  call assert_fails('Xexpr "abc.txt:1:Hello world"', 'E373:')
956
957  set efm=%f:%l:%m,%O:%f:%l:%m
958  call assert_fails('Xexpr "abc.txt:1:Hello world"', 'E373:')
959
960  set efm=%f:%l:%m,%f:%l:%*[^a-z
961  call assert_fails('Xexpr "abc.txt:1:Hello world"', 'E374:')
962
963  set efm=%f:%l:%m,%f:%l:%*c
964  call assert_fails('Xexpr "abc.txt:1:Hello world"', 'E375:')
965
966  set efm=%f:%l:%m,%L%M%N
967  call assert_fails('Xexpr "abc.txt:1:Hello world"', 'E376:')
968
969  set efm=%f:%l:%m,%f:%l:%m:%R
970  call assert_fails('Xexpr "abc.txt:1:Hello world"', 'E377:')
971
972  set efm=
973  call assert_fails('Xexpr "abc.txt:1:Hello world"', 'E378:')
974
975  set efm=%DEntering\ dir\ abc,%f:%l:%m
976  call assert_fails('Xexpr ["Entering dir abc", "abc.txt:1:Hello world"]', 'E379:')
977
978  let &efm = save_efm
979endfunc
980
981func Test_invalid_efm()
982  call Xinvalid_efm_Tests('c')
983  call Xinvalid_efm_Tests('l')
984endfunc
985
986" TODO:
987" Add tests for the following formats in 'errorformat'
988"	%r  %O
989func Test_efm2()
990  let save_efm = &efm
991
992  " Test for %s format in efm
993  set efm=%f:%s
994  cexpr 'Xtestfile:Line search text'
995  let l = getqflist()
996  call assert_equal(l[0].pattern, '^\VLine search text\$')
997  call assert_equal(l[0].lnum, 0)
998
999  let l = split(execute('clist', ''), "\n")
1000  call assert_equal([' 1 Xtestfile:^\VLine search text\$:  '], l)
1001
1002  " Test for %P, %Q and %t format specifiers
1003  let lines=["[Xtestfile1]",
1004	      \ "(1,17)  error: ';' missing",
1005	      \ "(21,2)  warning: variable 'z' not defined",
1006	      \ "(67,3)  error: end of file found before string ended",
1007	      \ "--",
1008	      \ "",
1009	      \ "[Xtestfile2]",
1010	      \ "--",
1011	      \ "",
1012	      \ "[Xtestfile3]",
1013	      \ "NEW compiler v1.1",
1014	      \ "(2,2)   warning: variable 'x' not defined",
1015	      \ "(67,3)  warning: 's' already defined",
1016	      \ "--"
1017	      \]
1018  set efm=%+P[%f]%r,(%l\\,%c)%*[\ ]%t%*[^:]:\ %m,%+Q--%r
1019  " To exercise the push/pop file functionality in quickfix, the test files
1020  " need to be created.
1021  call writefile(['Line1'], 'Xtestfile1')
1022  call writefile(['Line2'], 'Xtestfile2')
1023  call writefile(['Line3'], 'Xtestfile3')
1024  cexpr ""
1025  for l in lines
1026      caddexpr l
1027  endfor
1028  let l = getqflist()
1029  call assert_equal(12, len(l))
1030  call assert_equal(21, l[2].lnum)
1031  call assert_equal(2, l[2].col)
1032  call assert_equal('w', l[2].type)
1033  call assert_equal('e', l[3].type)
1034  call delete('Xtestfile1')
1035  call delete('Xtestfile2')
1036  call delete('Xtestfile3')
1037
1038  " Tests for %E, %C and %Z format specifiers
1039  let lines = ["Error 275",
1040	      \ "line 42",
1041	      \ "column 3",
1042	      \ "' ' expected after '--'"
1043	      \]
1044  set efm=%EError\ %n,%Cline\ %l,%Ccolumn\ %c,%Z%m
1045  cgetexpr lines
1046  let l = getqflist()
1047  call assert_equal(275, l[0].nr)
1048  call assert_equal(42, l[0].lnum)
1049  call assert_equal(3, l[0].col)
1050  call assert_equal('E', l[0].type)
1051  call assert_equal("\n' ' expected after '--'", l[0].text)
1052
1053  " Test for %>
1054  let lines = ["Error in line 147 of foo.c:",
1055	      \"unknown variable 'i'"
1056	      \]
1057  set efm=unknown\ variable\ %m,%E%>Error\ in\ line\ %l\ of\ %f:,%Z%m
1058  cgetexpr lines
1059  let l = getqflist()
1060  call assert_equal(147, l[0].lnum)
1061  call assert_equal('E', l[0].type)
1062  call assert_equal("\nunknown variable 'i'", l[0].text)
1063
1064  " Test for %A, %C and other formats
1065  let lines = [
1066	  \"==============================================================",
1067	  \"FAIL: testGetTypeIdCachesResult (dbfacadeTest.DjsDBFacadeTest)",
1068	  \"--------------------------------------------------------------",
1069	  \"Traceback (most recent call last):",
1070	  \'  File "unittests/dbfacadeTest.py", line 89, in testFoo',
1071	  \"    self.assertEquals(34, dtid)",
1072	  \'  File "/usr/lib/python2.2/unittest.py", line 286, in',
1073	  \" failUnlessEqual",
1074	  \"    raise self.failureException, \\",
1075	  \"AssertionError: 34 != 33",
1076	  \"",
1077	  \"--------------------------------------------------------------",
1078	  \"Ran 27 tests in 0.063s"
1079	  \]
1080  set efm=%C\ %.%#,%A\ \ File\ \"%f\"\\,\ line\ %l%.%#,%Z%[%^\ ]%\\@=%m
1081  cgetexpr lines
1082  let l = getqflist()
1083  call assert_equal(8, len(l))
1084  call assert_equal(89, l[4].lnum)
1085  call assert_equal(1, l[4].valid)
1086  call assert_equal('unittests/dbfacadeTest.py', bufname(l[4].bufnr))
1087
1088  " The following sequence of commands used to crash Vim
1089  set efm=%W%m
1090  cgetexpr ['msg1']
1091  let l = getqflist()
1092  call assert_equal(1, len(l), string(l))
1093  call assert_equal('msg1', l[0].text)
1094  set efm=%C%m
1095  lexpr 'msg2'
1096  let l = getloclist(0)
1097  call assert_equal(1, len(l), string(l))
1098  call assert_equal('msg2', l[0].text)
1099  lopen
1100  call setqflist([], 'r')
1101  caddbuf
1102  let l = getqflist()
1103  call assert_equal(1, len(l), string(l))
1104  call assert_equal('|| msg2', l[0].text)
1105
1106  new | only
1107  let &efm = save_efm
1108endfunc
1109
1110func XquickfixChangedByAutocmd(cchar)
1111  call s:setup_commands(a:cchar)
1112  if a:cchar == 'c'
1113    let ErrorNr = 'E925'
1114    func! ReadFunc()
1115      colder
1116      cgetexpr []
1117    endfunc
1118  else
1119    let ErrorNr = 'E926'
1120    func! ReadFunc()
1121      lolder
1122      lgetexpr []
1123    endfunc
1124  endif
1125
1126  augroup testgroup
1127    au!
1128    autocmd BufReadCmd test_changed.txt call ReadFunc()
1129  augroup END
1130
1131  new | only
1132  let words = [ "a", "b" ]
1133  let qflist = []
1134  for word in words
1135    call add(qflist, {'filename': 'test_changed.txt'})
1136    call g:Xsetlist(qflist, ' ')
1137  endfor
1138  call assert_fails('Xrewind', ErrorNr . ':')
1139
1140  augroup! testgroup
1141endfunc
1142
1143func Test_quickfix_was_changed_by_autocmd()
1144  call XquickfixChangedByAutocmd('c')
1145  call XquickfixChangedByAutocmd('l')
1146endfunc
1147
1148func Test_caddbuffer_to_empty()
1149  helpgr quickfix
1150  call setqflist([], 'r')
1151  cad
1152  try
1153    cn
1154  catch
1155    " number of matches is unknown
1156    call assert_true(v:exception =~ 'E553:')
1157  endtry
1158  quit!
1159endfunc
1160
1161func Test_cgetexpr_works()
1162  " this must not crash Vim
1163  cgetexpr [$x]
1164  lgetexpr [$x]
1165endfunc
1166
1167" Tests for the setqflist() and setloclist() functions
1168func SetXlistTests(cchar, bnum)
1169  call s:setup_commands(a:cchar)
1170
1171  call g:Xsetlist([{'bufnr': a:bnum, 'lnum': 1},
1172	      \  {'bufnr': a:bnum, 'lnum': 2}])
1173  let l = g:Xgetlist()
1174  call assert_equal(2, len(l))
1175  call assert_equal(2, l[1].lnum)
1176
1177  Xnext
1178  call g:Xsetlist([{'bufnr': a:bnum, 'lnum': 3}], 'a')
1179  let l = g:Xgetlist()
1180  call assert_equal(3, len(l))
1181  Xnext
1182  call assert_equal(3, line('.'))
1183
1184  " Appending entries to the list should not change the cursor position
1185  " in the quickfix window
1186  Xwindow
1187  1
1188  call g:Xsetlist([{'bufnr': a:bnum, 'lnum': 4},
1189	      \  {'bufnr': a:bnum, 'lnum': 5}], 'a')
1190  call assert_equal(1, line('.'))
1191  close
1192
1193  call g:Xsetlist([{'bufnr': a:bnum, 'lnum': 3},
1194	      \  {'bufnr': a:bnum, 'lnum': 4},
1195	      \  {'bufnr': a:bnum, 'lnum': 5}], 'r')
1196  let l = g:Xgetlist()
1197  call assert_equal(3, len(l))
1198  call assert_equal(5, l[2].lnum)
1199
1200  call g:Xsetlist([])
1201  let l = g:Xgetlist()
1202  call assert_equal(0, len(l))
1203
1204  " Tests for setting the 'valid' flag
1205  call g:Xsetlist([{'bufnr':a:bnum, 'lnum':4, 'valid':0}])
1206  Xwindow
1207  call assert_equal(1, winnr('$'))
1208  let l = g:Xgetlist()
1209  call g:Xsetlist(l)
1210  call assert_equal(0, g:Xgetlist()[0].valid)
1211  call g:Xsetlist([{'text':'Text1', 'valid':1}])
1212  Xwindow
1213  call assert_equal(2, winnr('$'))
1214  Xclose
1215  let save_efm = &efm
1216  set efm=%m
1217  Xgetexpr 'TestMessage'
1218  let l = g:Xgetlist()
1219  call g:Xsetlist(l)
1220  call assert_equal(1, g:Xgetlist()[0].valid)
1221  let &efm = save_efm
1222
1223  " Error cases:
1224  " Refer to a non-existing buffer and pass a non-dictionary type
1225  call assert_fails("call g:Xsetlist([{'bufnr':998, 'lnum':4}," .
1226	      \ " {'bufnr':999, 'lnum':5}])", 'E92:')
1227  call g:Xsetlist([[1, 2,3]])
1228  call assert_equal(0, len(g:Xgetlist()))
1229endfunc
1230
1231func Test_setqflist()
1232  new Xtestfile | only
1233  let bnum = bufnr('%')
1234  call setline(1, range(1,5))
1235
1236  call SetXlistTests('c', bnum)
1237  call SetXlistTests('l', bnum)
1238
1239  enew!
1240  call delete('Xtestfile')
1241endfunc
1242
1243func Xlist_empty_middle(cchar)
1244  call s:setup_commands(a:cchar)
1245
1246  " create three quickfix lists
1247  let @/ = 'Test_'
1248  Xvimgrep // test_quickfix.vim
1249  let testlen = len(g:Xgetlist())
1250  call assert_true(testlen > 0)
1251  Xvimgrep empty test_quickfix.vim
1252  call assert_true(len(g:Xgetlist()) > 0)
1253  Xvimgrep matches test_quickfix.vim
1254  let matchlen = len(g:Xgetlist())
1255  call assert_true(matchlen > 0)
1256  Xolder
1257  " make the middle list empty
1258  call g:Xsetlist([], 'r')
1259  call assert_true(len(g:Xgetlist()) == 0)
1260  Xolder
1261  call assert_equal(testlen, len(g:Xgetlist()))
1262  Xnewer
1263  Xnewer
1264  call assert_equal(matchlen, len(g:Xgetlist()))
1265endfunc
1266
1267func Test_setqflist_empty_middle()
1268  call Xlist_empty_middle('c')
1269  call Xlist_empty_middle('l')
1270endfunc
1271
1272func Xlist_empty_older(cchar)
1273  call s:setup_commands(a:cchar)
1274
1275  " create three quickfix lists
1276  Xvimgrep one test_quickfix.vim
1277  let onelen = len(g:Xgetlist())
1278  call assert_true(onelen > 0)
1279  Xvimgrep two test_quickfix.vim
1280  let twolen = len(g:Xgetlist())
1281  call assert_true(twolen > 0)
1282  Xvimgrep three test_quickfix.vim
1283  let threelen = len(g:Xgetlist())
1284  call assert_true(threelen > 0)
1285  Xolder 2
1286  " make the first list empty, check the others didn't change
1287  call g:Xsetlist([], 'r')
1288  call assert_true(len(g:Xgetlist()) == 0)
1289  Xnewer
1290  call assert_equal(twolen, len(g:Xgetlist()))
1291  Xnewer
1292  call assert_equal(threelen, len(g:Xgetlist()))
1293endfunc
1294
1295func Test_setqflist_empty_older()
1296  call Xlist_empty_older('c')
1297  call Xlist_empty_older('l')
1298endfunc
1299
1300func XquickfixSetListWithAct(cchar)
1301  call s:setup_commands(a:cchar)
1302
1303  let list1 = [{'filename': 'fnameA', 'text': 'A'},
1304          \    {'filename': 'fnameB', 'text': 'B'}]
1305  let list2 = [{'filename': 'fnameC', 'text': 'C'},
1306          \    {'filename': 'fnameD', 'text': 'D'},
1307          \    {'filename': 'fnameE', 'text': 'E'}]
1308
1309  " {action} is unspecified.  Same as specifing ' '.
1310  new | only
1311  silent! Xnewer 99
1312  call g:Xsetlist(list1)
1313  call g:Xsetlist(list2)
1314  let li = g:Xgetlist()
1315  call assert_equal(3, len(li))
1316  call assert_equal('C', li[0]['text'])
1317  call assert_equal('D', li[1]['text'])
1318  call assert_equal('E', li[2]['text'])
1319  silent! Xolder
1320  let li = g:Xgetlist()
1321  call assert_equal(2, len(li))
1322  call assert_equal('A', li[0]['text'])
1323  call assert_equal('B', li[1]['text'])
1324
1325  " {action} is specified ' '.
1326  new | only
1327  silent! Xnewer 99
1328  call g:Xsetlist(list1)
1329  call g:Xsetlist(list2, ' ')
1330  let li = g:Xgetlist()
1331  call assert_equal(3, len(li))
1332  call assert_equal('C', li[0]['text'])
1333  call assert_equal('D', li[1]['text'])
1334  call assert_equal('E', li[2]['text'])
1335  silent! Xolder
1336  let li = g:Xgetlist()
1337  call assert_equal(2, len(li))
1338  call assert_equal('A', li[0]['text'])
1339  call assert_equal('B', li[1]['text'])
1340
1341  " {action} is specified 'a'.
1342  new | only
1343  silent! Xnewer 99
1344  call g:Xsetlist(list1)
1345  call g:Xsetlist(list2, 'a')
1346  let li = g:Xgetlist()
1347  call assert_equal(5, len(li))
1348  call assert_equal('A', li[0]['text'])
1349  call assert_equal('B', li[1]['text'])
1350  call assert_equal('C', li[2]['text'])
1351  call assert_equal('D', li[3]['text'])
1352  call assert_equal('E', li[4]['text'])
1353
1354  " {action} is specified 'r'.
1355  new | only
1356  silent! Xnewer 99
1357  call g:Xsetlist(list1)
1358  call g:Xsetlist(list2, 'r')
1359  let li = g:Xgetlist()
1360  call assert_equal(3, len(li))
1361  call assert_equal('C', li[0]['text'])
1362  call assert_equal('D', li[1]['text'])
1363  call assert_equal('E', li[2]['text'])
1364
1365  " Test for wrong value.
1366  new | only
1367  call assert_fails("call g:Xsetlist(0)", 'E714:')
1368  call assert_fails("call g:Xsetlist(list1, '')", 'E927:')
1369  call assert_fails("call g:Xsetlist(list1, 'aa')", 'E927:')
1370  call assert_fails("call g:Xsetlist(list1, ' a')", 'E927:')
1371  call assert_fails("call g:Xsetlist(list1, 0)", 'E928:')
1372endfunc
1373
1374func Test_quickfix_set_list_with_act()
1375  call XquickfixSetListWithAct('c')
1376  call XquickfixSetListWithAct('l')
1377endfunc
1378
1379func XLongLinesTests(cchar)
1380  let l = g:Xgetlist()
1381
1382  call assert_equal(4, len(l))
1383  call assert_equal(1, l[0].lnum)
1384  call assert_equal(1, l[0].col)
1385  call assert_equal(1975, len(l[0].text))
1386  call assert_equal(2, l[1].lnum)
1387  call assert_equal(1, l[1].col)
1388  call assert_equal(4070, len(l[1].text))
1389  call assert_equal(3, l[2].lnum)
1390  call assert_equal(1, l[2].col)
1391  call assert_equal(4070, len(l[2].text))
1392  call assert_equal(4, l[3].lnum)
1393  call assert_equal(1, l[3].col)
1394  call assert_equal(10, len(l[3].text))
1395
1396  call g:Xsetlist([], 'r')
1397endfunc
1398
1399func s:long_lines_tests(cchar)
1400  call s:setup_commands(a:cchar)
1401
1402  let testfile = 'samples/quickfix.txt'
1403
1404  " file
1405  exe 'Xgetfile' testfile
1406  call XLongLinesTests(a:cchar)
1407
1408  " list
1409  Xexpr readfile(testfile)
1410  call XLongLinesTests(a:cchar)
1411
1412  " string
1413  Xexpr join(readfile(testfile), "\n")
1414  call XLongLinesTests(a:cchar)
1415
1416  " buffer
1417  exe 'edit' testfile
1418  exe 'Xbuffer' bufnr('%')
1419  call XLongLinesTests(a:cchar)
1420endfunc
1421
1422func Test_long_lines()
1423  call s:long_lines_tests('c')
1424  call s:long_lines_tests('l')
1425endfunc
1426
1427func s:create_test_file(filename)
1428  let l = []
1429  for i in range(1, 20)
1430      call add(l, 'Line' . i)
1431  endfor
1432  call writefile(l, a:filename)
1433endfunc
1434
1435func Test_switchbuf()
1436  call s:create_test_file('Xqftestfile1')
1437  call s:create_test_file('Xqftestfile2')
1438  call s:create_test_file('Xqftestfile3')
1439
1440  new | only
1441  edit Xqftestfile1
1442  let file1_winid = win_getid()
1443  new Xqftestfile2
1444  let file2_winid = win_getid()
1445  cgetexpr ['Xqftestfile1:5:Line5',
1446		\ 'Xqftestfile1:6:Line6',
1447		\ 'Xqftestfile2:10:Line10',
1448		\ 'Xqftestfile2:11:Line11',
1449		\ 'Xqftestfile3:15:Line15',
1450		\ 'Xqftestfile3:16:Line16']
1451
1452  new
1453  let winid = win_getid()
1454  cfirst | cnext
1455  call assert_equal(winid, win_getid())
1456  2cnext
1457  call assert_equal(winid, win_getid())
1458  2cnext
1459  call assert_equal(winid, win_getid())
1460  enew
1461
1462  set switchbuf=useopen
1463  cfirst | cnext
1464  call assert_equal(file1_winid, win_getid())
1465  2cnext
1466  call assert_equal(file2_winid, win_getid())
1467  2cnext
1468  call assert_equal(file2_winid, win_getid())
1469
1470  enew | only
1471  set switchbuf=usetab
1472  tabedit Xqftestfile1
1473  tabedit Xqftestfile2
1474  tabfirst
1475  cfirst | cnext
1476  call assert_equal(2, tabpagenr())
1477  2cnext
1478  call assert_equal(3, tabpagenr())
1479  2cnext
1480  call assert_equal(3, tabpagenr())
1481  tabfirst | tabonly | enew
1482
1483  set switchbuf=split
1484  cfirst | cnext
1485  call assert_equal(1, winnr('$'))
1486  cnext | cnext
1487  call assert_equal(2, winnr('$'))
1488  cnext | cnext
1489  call assert_equal(3, winnr('$'))
1490  enew | only
1491
1492  set switchbuf=newtab
1493  cfirst | cnext
1494  call assert_equal(1, tabpagenr('$'))
1495  cnext | cnext
1496  call assert_equal(2, tabpagenr('$'))
1497  cnext | cnext
1498  call assert_equal(3, tabpagenr('$'))
1499  tabfirst | enew | tabonly | only
1500
1501  set switchbuf=
1502  edit Xqftestfile1
1503  let file1_winid = win_getid()
1504  new Xqftestfile2
1505  let file2_winid = win_getid()
1506  copen
1507  exe "normal 1G\<CR>"
1508  call assert_equal(file1_winid, win_getid())
1509  copen
1510  exe "normal 3G\<CR>"
1511  call assert_equal(file2_winid, win_getid())
1512  copen | only
1513  exe "normal 5G\<CR>"
1514  call assert_equal(2, winnr('$'))
1515  call assert_equal(1, bufwinnr('Xqftestfile3'))
1516
1517  " If only quickfix window is open in the current tabpage, jumping to an
1518  " entry with 'switchubf' set to 'usetab' should search in other tabpages.
1519  enew | only
1520  set switchbuf=usetab
1521  tabedit Xqftestfile1
1522  tabedit Xqftestfile2
1523  tabedit Xqftestfile3
1524  tabfirst
1525  copen | only
1526  clast
1527  call assert_equal(4, tabpagenr())
1528  tabfirst | tabonly | enew | only
1529
1530  call delete('Xqftestfile1')
1531  call delete('Xqftestfile2')
1532  call delete('Xqftestfile3')
1533  set switchbuf&vim
1534
1535  enew | only
1536endfunc
1537
1538func Xadjust_qflnum(cchar)
1539  call s:setup_commands(a:cchar)
1540
1541  enew | only
1542
1543  let fname = 'Xqftestfile' . a:cchar
1544  call s:create_test_file(fname)
1545  exe 'edit ' . fname
1546
1547  Xgetexpr [fname . ':5:Line5',
1548	      \ fname . ':10:Line10',
1549	      \ fname . ':15:Line15',
1550	      \ fname . ':20:Line20']
1551
1552  6,14delete
1553  call append(6, ['Buffer', 'Window'])
1554
1555  let l = g:Xgetlist()
1556
1557  call assert_equal(5, l[0].lnum)
1558  call assert_equal(6, l[2].lnum)
1559  call assert_equal(13, l[3].lnum)
1560
1561  enew!
1562  call delete(fname)
1563endfunc
1564
1565func Test_adjust_lnum()
1566  call setloclist(0, [])
1567  call Xadjust_qflnum('c')
1568  call setqflist([])
1569  call Xadjust_qflnum('l')
1570endfunc
1571
1572" Tests for the :grep/:lgrep and :grepadd/:lgrepadd commands
1573func s:test_xgrep(cchar)
1574  call s:setup_commands(a:cchar)
1575
1576  " The following lines are used for the grep test. Don't remove.
1577  " Grep_Test_Text: Match 1
1578  " Grep_Test_Text: Match 2
1579  " GrepAdd_Test_Text: Match 1
1580  " GrepAdd_Test_Text: Match 2
1581  enew! | only
1582  set makeef&vim
1583  silent Xgrep Grep_Test_Text: test_quickfix.vim
1584  call assert_true(len(g:Xgetlist()) == 3)
1585  Xopen
1586  call assert_true(w:quickfix_title =~ '^:grep')
1587  Xclose
1588  enew
1589  set makeef=Temp_File_##
1590  silent Xgrepadd GrepAdd_Test_Text: test_quickfix.vim
1591  call assert_true(len(g:Xgetlist()) == 6)
1592endfunc
1593
1594func Test_grep()
1595  if !has('unix')
1596    " The grepprg may not be set on non-Unix systems
1597    return
1598  endif
1599
1600  call s:test_xgrep('c')
1601  call s:test_xgrep('l')
1602endfunc
1603
1604func Test_two_windows()
1605  " Use one 'errorformat' for two windows.  Add an expression to each of them,
1606  " make sure they each keep their own state.
1607  set efm=%DEntering\ dir\ '%f',%f:%l:%m,%XLeaving\ dir\ '%f'
1608  call mkdir('Xone/a', 'p')
1609  call mkdir('Xtwo/a', 'p')
1610  let lines = ['1', '2', 'one one one', '4', 'two two two', '6', '7']
1611  call writefile(lines, 'Xone/a/one.txt')
1612  call writefile(lines, 'Xtwo/a/two.txt')
1613
1614  new one
1615  let one_id = win_getid()
1616  lexpr ""
1617  new two
1618  let two_id = win_getid()
1619  lexpr ""
1620
1621  laddexpr "Entering dir 'Xtwo/a'"
1622  call win_gotoid(one_id)
1623  laddexpr "Entering dir 'Xone/a'"
1624  call win_gotoid(two_id)
1625  laddexpr 'two.txt:5:two two two'
1626  call win_gotoid(one_id)
1627  laddexpr 'one.txt:3:one one one'
1628
1629  let loc_one = getloclist(one_id)
1630  call assert_equal('Xone/a/one.txt', bufname(loc_one[1].bufnr))
1631  call assert_equal(3, loc_one[1].lnum)
1632
1633  let loc_two = getloclist(two_id)
1634  call assert_equal('Xtwo/a/two.txt', bufname(loc_two[1].bufnr))
1635  call assert_equal(5, loc_two[1].lnum)
1636
1637  call win_gotoid(one_id)
1638  bwipe!
1639  call win_gotoid(two_id)
1640  bwipe!
1641  call delete('Xone', 'rf')
1642  call delete('Xtwo', 'rf')
1643endfunc
1644
1645func XbottomTests(cchar)
1646  call s:setup_commands(a:cchar)
1647
1648  " Calling lbottom without any errors should fail
1649  if a:cchar == 'l'
1650      call assert_fails('lbottom', 'E776:')
1651  endif
1652
1653  call g:Xsetlist([{'filename': 'foo', 'lnum': 42}])
1654  Xopen
1655  let wid = win_getid()
1656  call assert_equal(1, line('.'))
1657  wincmd w
1658  call g:Xsetlist([{'filename': 'var', 'lnum': 24}], 'a')
1659  Xbottom
1660  call win_gotoid(wid)
1661  call assert_equal(2, line('.'))
1662  Xclose
1663endfunc
1664
1665" Tests for the :cbottom and :lbottom commands
1666func Test_cbottom()
1667  call XbottomTests('c')
1668  call XbottomTests('l')
1669endfunc
1670
1671func HistoryTest(cchar)
1672  call s:setup_commands(a:cchar)
1673
1674  " clear all lists after the first one, then replace the first one.
1675  call g:Xsetlist([])
1676  call assert_fails('Xolder 99', 'E380:')
1677  let entry = {'filename': 'foo', 'lnum': 42}
1678  call g:Xsetlist([entry], 'r')
1679  call g:Xsetlist([entry, entry])
1680  call g:Xsetlist([entry, entry, entry])
1681  let res = split(execute(a:cchar . 'hist'), "\n")
1682  call assert_equal(3, len(res))
1683  let common = 'errors     :set' . (a:cchar == 'c' ? 'qf' : 'loc') . 'list()'
1684  call assert_equal('  error list 1 of 3; 1 ' . common, res[0])
1685  call assert_equal('  error list 2 of 3; 2 ' . common, res[1])
1686  call assert_equal('> error list 3 of 3; 3 ' . common, res[2])
1687endfunc
1688
1689func Test_history()
1690  call HistoryTest('c')
1691  call HistoryTest('l')
1692endfunc
1693
1694func Test_duplicate_buf()
1695  " make sure we can get the highest buffer number
1696  edit DoesNotExist
1697  edit DoesNotExist2
1698  let last_buffer = bufnr("$")
1699
1700  " make sure only one buffer is created
1701  call writefile(['this one', 'that one'], 'Xgrepthis')
1702  vimgrep one Xgrepthis
1703  vimgrep one Xgrepthis
1704  call assert_equal(last_buffer + 1, bufnr("$"))
1705
1706  call delete('Xgrepthis')
1707endfunc
1708
1709" Quickfix/Location list set/get properties tests
1710func Xproperty_tests(cchar)
1711    call s:setup_commands(a:cchar)
1712
1713    " Error cases
1714    call assert_fails('call g:Xgetlist(99)', 'E715:')
1715    call assert_fails('call g:Xsetlist(99)', 'E714:')
1716    call assert_fails('call g:Xsetlist([], "a", [])', 'E715:')
1717
1718    " Set and get the title
1719    call g:Xsetlist([])
1720    Xopen
1721    wincmd p
1722    call g:Xsetlist([{'filename':'foo', 'lnum':27}])
1723    call g:Xsetlist([], 'a', {'title' : 'Sample'})
1724    let d = g:Xgetlist({"title":1})
1725    call assert_equal('Sample', d.title)
1726
1727    Xopen
1728    call assert_equal('Sample', w:quickfix_title)
1729    Xclose
1730
1731    " Tests for action argument
1732    silent! Xolder 999
1733    let qfnr = g:Xgetlist({'all':1}).nr
1734    call g:Xsetlist([], 'r', {'title' : 'N1'})
1735    call assert_equal('N1', g:Xgetlist({'all':1}).title)
1736    call g:Xsetlist([], ' ', {'title' : 'N2'})
1737    call assert_equal(qfnr + 1, g:Xgetlist({'all':1}).nr)
1738
1739    let res = g:Xgetlist({'nr': 0})
1740    call assert_equal(qfnr + 1, res.nr)
1741    call assert_equal(['nr'], keys(res))
1742
1743    call g:Xsetlist([], ' ', {'title' : 'N3'})
1744    call assert_equal('N2', g:Xgetlist({'nr':2, 'title':1}).title)
1745
1746    " Changing the title of an earlier quickfix list
1747    call g:Xsetlist([], ' ', {'title' : 'NewTitle', 'nr' : 2})
1748    call assert_equal('NewTitle', g:Xgetlist({'nr':2, 'title':1}).title)
1749
1750    " Changing the title of an invalid quickfix list
1751    call assert_equal(-1, g:Xsetlist([], ' ',
1752		\ {'title' : 'SomeTitle', 'nr' : 99}))
1753    call assert_equal(-1, g:Xsetlist([], ' ',
1754		\ {'title' : 'SomeTitle', 'nr' : 'abc'}))
1755
1756    if a:cchar == 'c'
1757	copen
1758	call assert_equal({'winid':win_getid()}, getqflist({'winid':1}))
1759	cclose
1760    endif
1761
1762    " Invalid arguments
1763    call assert_fails('call g:Xgetlist([])', 'E715')
1764    call assert_fails('call g:Xsetlist([], "a", [])', 'E715')
1765    let s = g:Xsetlist([], 'a', {'abc':1})
1766    call assert_equal(-1, s)
1767
1768    call assert_equal({}, g:Xgetlist({'abc':1}))
1769    call assert_equal({}, g:Xgetlist({'nr':99, 'title':1}))
1770    call assert_equal({}, g:Xgetlist({'nr':[], 'title':1}))
1771
1772    if a:cchar == 'l'
1773	call assert_equal({}, getloclist(99, {'title': 1}))
1774    endif
1775
1776    " Context related tests
1777    call g:Xsetlist([], 'a', {'context':[1,2,3]})
1778    call test_garbagecollect_now()
1779    let d = g:Xgetlist({'context':1})
1780    call assert_equal([1,2,3], d.context)
1781    call g:Xsetlist([], 'a', {'context':{'color':'green'}})
1782    let d = g:Xgetlist({'context':1})
1783    call assert_equal({'color':'green'}, d.context)
1784    call g:Xsetlist([], 'a', {'context':"Context info"})
1785    let d = g:Xgetlist({'context':1})
1786    call assert_equal("Context info", d.context)
1787    call g:Xsetlist([], 'a', {'context':246})
1788    let d = g:Xgetlist({'context':1})
1789    call assert_equal(246, d.context)
1790    if a:cchar == 'l'
1791	" Test for copying context across two different location lists
1792	new | only
1793	let w1_id = win_getid()
1794	let l = [1]
1795	call setloclist(0, [], 'a', {'context':l})
1796	new
1797	let w2_id = win_getid()
1798	call add(l, 2)
1799	call assert_equal([1, 2], getloclist(w1_id, {'context':1}).context)
1800	call assert_equal([1, 2], getloclist(w2_id, {'context':1}).context)
1801	unlet! l
1802	call assert_equal([1, 2], getloclist(w2_id, {'context':1}).context)
1803	only
1804	call setloclist(0, [], 'f')
1805	call assert_equal({}, getloclist(0, {'context':1}))
1806    endif
1807
1808    " Test for changing the context of previous quickfix lists
1809    call g:Xsetlist([], 'f')
1810    Xexpr "One"
1811    Xexpr "Two"
1812    Xexpr "Three"
1813    call g:Xsetlist([], ' ', {'context' : [1], 'nr' : 1})
1814    call g:Xsetlist([], ' ', {'context' : [2], 'nr' : 2})
1815    " Also, check for setting the context using quickfix list number zero.
1816    call g:Xsetlist([], ' ', {'context' : [3], 'nr' : 0})
1817    call test_garbagecollect_now()
1818    let l = g:Xgetlist({'nr' : 1, 'context' : 1})
1819    call assert_equal([1], l.context)
1820    let l = g:Xgetlist({'nr' : 2, 'context' : 1})
1821    call assert_equal([2], l.context)
1822    let l = g:Xgetlist({'nr' : 3, 'context' : 1})
1823    call assert_equal([3], l.context)
1824
1825    " Test for changing the context through reference and for garbage
1826    " collection of quickfix context
1827    let l = ["red"]
1828    call g:Xsetlist([], ' ', {'context' : l})
1829    call add(l, "blue")
1830    let x = g:Xgetlist({'context' : 1})
1831    call add(x.context, "green")
1832    call assert_equal(["red", "blue", "green"], l)
1833    call assert_equal(["red", "blue", "green"], x.context)
1834    unlet l
1835    call test_garbagecollect_now()
1836    let m = g:Xgetlist({'context' : 1})
1837    call assert_equal(["red", "blue", "green"], m.context)
1838endfunc
1839
1840func Test_qf_property()
1841    call Xproperty_tests('c')
1842    call Xproperty_tests('l')
1843endfunc
1844
1845" Tests for the QuickFixCmdPre/QuickFixCmdPost autocommands
1846func QfAutoCmdHandler(loc, cmd)
1847  call add(g:acmds, a:loc . a:cmd)
1848endfunc
1849
1850func Test_Autocmd()
1851  autocmd QuickFixCmdPre * call QfAutoCmdHandler('pre', expand('<amatch>'))
1852  autocmd QuickFixCmdPost * call QfAutoCmdHandler('post', expand('<amatch>'))
1853
1854  let g:acmds = []
1855  cexpr "F1:10:Line 10"
1856  caddexpr "F1:20:Line 20"
1857  cgetexpr "F1:30:Line 30"
1858  enew! | call append(0, "F2:10:Line 10")
1859  cbuffer!
1860  enew! | call append(0, "F2:20:Line 20")
1861  cgetbuffer
1862  enew! | call append(0, "F2:30:Line 30")
1863  caddbuffer
1864
1865  let l = ['precexpr',
1866	      \ 'postcexpr',
1867	      \ 'precaddexpr',
1868	      \ 'postcaddexpr',
1869	      \ 'precgetexpr',
1870	      \ 'postcgetexpr',
1871	      \ 'precbuffer',
1872	      \ 'postcbuffer',
1873	      \ 'precgetbuffer',
1874	      \ 'postcgetbuffer',
1875	      \ 'precaddbuffer',
1876	      \ 'postcaddbuffer']
1877  call assert_equal(l, g:acmds)
1878endfunc
1879
1880func Test_Autocmd_Exception()
1881  set efm=%m
1882  lgetexpr '?'
1883
1884  try
1885    call DoesNotExit()
1886  catch
1887    lgetexpr '1'
1888  finally
1889    lgetexpr '1'
1890  endtry
1891
1892  call assert_equal('1', getloclist(0)[0].text)
1893
1894  set efm&vim
1895endfunc
1896
1897func Test_caddbuffer_wrong()
1898  " This used to cause a memory access in freed memory.
1899  let save_efm = &efm
1900  set efm=%EEEE%m,%WWWW,%+CCCC%>%#,%GGGG%.#
1901  cgetexpr ['WWWW', 'EEEE', 'CCCC']
1902  let &efm = save_efm
1903  caddbuffer
1904  bwipe!
1905endfunc
1906
1907func Test_caddexpr_wrong()
1908  " This used to cause a memory access in freed memory.
1909  cbuffer
1910  cbuffer
1911  copen
1912  let save_efm = &efm
1913  set efm=%
1914  call assert_fails('caddexpr ""', 'E376:')
1915  let &efm = save_efm
1916endfunc
1917
1918func Test_dirstack_cleanup()
1919  " This used to cause a memory access in freed memory.
1920  let save_efm = &efm
1921  lexpr '0'
1922  lopen
1923  fun X(c)
1924    let save_efm=&efm
1925    set efm=%D%f
1926    if a:c == 'c'
1927      caddexpr '::'
1928    else
1929      laddexpr ':0:0'
1930    endif
1931    let &efm=save_efm
1932  endfun
1933  call X('c')
1934  call X('l')
1935  call setqflist([], 'r')
1936  caddbuffer
1937  let &efm = save_efm
1938endfunc
1939
1940" Tests for jumping to entries from the location list window and quickfix
1941" window
1942func Test_cwindow_jump()
1943  set efm=%f%%%l%%%m
1944  lgetexpr ["F1%10%Line 10", "F2%20%Line 20", "F3%30%Line 30"]
1945  lopen | only
1946  lfirst
1947  call assert_true(winnr('$') == 2)
1948  call assert_true(winnr() == 1)
1949  " Location list for the new window should be set
1950  call assert_true(getloclist(0)[2].text == 'Line 30')
1951
1952  " Open a scratch buffer
1953  " Open a new window and create a location list
1954  " Open the location list window and close the other window
1955  " Jump to an entry.
1956  " Should create a new window and jump to the entry. The scrtach buffer
1957  " should not be used.
1958  enew | only
1959  set buftype=nofile
1960  below new
1961  lgetexpr ["F1%10%Line 10", "F2%20%Line 20", "F3%30%Line 30"]
1962  lopen
1963  2wincmd c
1964  lnext
1965  call assert_true(winnr('$') == 3)
1966  call assert_true(winnr() == 2)
1967
1968  " Open two windows with two different location lists
1969  " Open the location list window and close the previous window
1970  " Jump to an entry in the location list window
1971  " Should open the file in the first window and not set the location list.
1972  enew | only
1973  lgetexpr ["F1%5%Line 5"]
1974  below new
1975  lgetexpr ["F1%10%Line 10", "F2%20%Line 20", "F3%30%Line 30"]
1976  lopen
1977  2wincmd c
1978  lnext
1979  call assert_true(winnr() == 1)
1980  call assert_true(getloclist(0)[0].text == 'Line 5')
1981
1982  enew | only
1983  cgetexpr ["F1%10%Line 10", "F2%20%Line 20", "F3%30%Line 30"]
1984  copen
1985  cnext
1986  call assert_true(winnr('$') == 2)
1987  call assert_true(winnr() == 1)
1988
1989  enew | only
1990  set efm&vim
1991endfunc
1992
1993func XvimgrepTests(cchar)
1994  call s:setup_commands(a:cchar)
1995
1996  call writefile(['Editor:VIM vim',
1997	      \ 'Editor:Emacs EmAcS',
1998	      \ 'Editor:Notepad NOTEPAD'], 'Xtestfile1')
1999  call writefile(['Linux', 'MacOS', 'MS-Windows'], 'Xtestfile2')
2000
2001  " Error cases
2002  call assert_fails('Xvimgrep /abc *', 'E682:')
2003
2004  let @/=''
2005  call assert_fails('Xvimgrep // *', 'E35:')
2006
2007  call assert_fails('Xvimgrep abc', 'E683:')
2008  call assert_fails('Xvimgrep a1b2c3 Xtestfile1', 'E480:')
2009  call assert_fails('Xvimgrep pat Xa1b2c3', 'E480:')
2010
2011  Xexpr ""
2012  Xvimgrepadd Notepad Xtestfile1
2013  Xvimgrepadd MacOS Xtestfile2
2014  let l = g:Xgetlist()
2015  call assert_equal(2, len(l))
2016  call assert_equal('Editor:Notepad NOTEPAD', l[0].text)
2017
2018  Xvimgrep #\cvim#g Xtestfile?
2019  let l = g:Xgetlist()
2020  call assert_equal(2, len(l))
2021  call assert_equal(8, l[0].col)
2022  call assert_equal(12, l[1].col)
2023
2024  1Xvimgrep ?Editor? Xtestfile*
2025  let l = g:Xgetlist()
2026  call assert_equal(1, len(l))
2027  call assert_equal('Editor:VIM vim', l[0].text)
2028
2029  edit +3 Xtestfile2
2030  Xvimgrep +\cemacs+j Xtestfile1
2031  let l = g:Xgetlist()
2032  call assert_equal('Xtestfile2', bufname(''))
2033  call assert_equal('Editor:Emacs EmAcS', l[0].text)
2034
2035  call delete('Xtestfile1')
2036  call delete('Xtestfile2')
2037endfunc
2038
2039" Tests for the :vimgrep command
2040func Test_vimgrep()
2041  call XvimgrepTests('c')
2042  call XvimgrepTests('l')
2043endfunc
2044
2045func XfreeTests(cchar)
2046  call s:setup_commands(a:cchar)
2047
2048  enew | only
2049
2050  " Deleting the quickfix stack should work even When the current list is
2051  " somewhere in the middle of the stack
2052  Xexpr ['Xfile1:10:10:Line 10', 'Xfile1:15:15:Line 15']
2053  Xexpr ['Xfile2:20:20:Line 20', 'Xfile2:25:25:Line 25']
2054  Xexpr ['Xfile3:30:30:Line 30', 'Xfile3:35:35:Line 35']
2055  Xolder
2056  call g:Xsetlist([], 'f')
2057  call assert_equal(0, len(g:Xgetlist()))
2058
2059  " After deleting the stack, adding a new list should create a stack with a
2060  " single list.
2061  Xexpr ['Xfile1:10:10:Line 10', 'Xfile1:15:15:Line 15']
2062  call assert_equal(1, g:Xgetlist({'all':1}).nr)
2063
2064  " Deleting the stack from a quickfix window should update/clear the
2065  " quickfix/location list window.
2066  Xexpr ['Xfile1:10:10:Line 10', 'Xfile1:15:15:Line 15']
2067  Xexpr ['Xfile2:20:20:Line 20', 'Xfile2:25:25:Line 25']
2068  Xexpr ['Xfile3:30:30:Line 30', 'Xfile3:35:35:Line 35']
2069  Xolder
2070  Xwindow
2071  call g:Xsetlist([], 'f')
2072  call assert_equal(2, winnr('$'))
2073  call assert_equal(1, line('$'))
2074  Xclose
2075
2076  " Deleting the stack from a non-quickfix window should update/clear the
2077  " quickfix/location list window.
2078  Xexpr ['Xfile1:10:10:Line 10', 'Xfile1:15:15:Line 15']
2079  Xexpr ['Xfile2:20:20:Line 20', 'Xfile2:25:25:Line 25']
2080  Xexpr ['Xfile3:30:30:Line 30', 'Xfile3:35:35:Line 35']
2081  Xolder
2082  Xwindow
2083  wincmd p
2084  call g:Xsetlist([], 'f')
2085  call assert_equal(0, len(g:Xgetlist()))
2086  wincmd p
2087  call assert_equal(2, winnr('$'))
2088  call assert_equal(1, line('$'))
2089
2090  " After deleting the location list stack, if the location list window is
2091  " opened, then a new location list should be created. So opening the
2092  " location list window again should not create a new window.
2093  if a:cchar == 'l'
2094      lexpr ['Xfile1:10:10:Line 10', 'Xfile1:15:15:Line 15']
2095      wincmd p
2096      lopen
2097      call assert_equal(2, winnr('$'))
2098  endif
2099  Xclose
2100endfunc
2101
2102" Tests for the quickifx free functionality
2103func Test_qf_free()
2104  call XfreeTests('c')
2105  call XfreeTests('l')
2106endfunc
2107
2108" Test for buffer overflow when parsing lines and adding new entries to
2109" the quickfix list.
2110func Test_bufoverflow()
2111  set efm=%f:%l:%m
2112  cgetexpr ['File1:100:' . repeat('x', 1025)]
2113
2114  set efm=%+GCompiler:\ %.%#,%f:%l:%m
2115  cgetexpr ['Compiler: ' . repeat('a', 1015), 'File1:10:Hello World']
2116
2117  set efm=%DEntering\ directory\ %f,%f:%l:%m
2118  cgetexpr ['Entering directory ' . repeat('a', 1006),
2119	      \ 'File1:10:Hello World']
2120  set efm&vim
2121endfunc
2122
2123func Test_cclose_from_copen()
2124    augroup QF_Test
2125	au!
2126	au FileType qf :cclose
2127    augroup END
2128    copen
2129    augroup QF_Test
2130	au!
2131    augroup END
2132    augroup! QF_Test
2133endfunc
2134
2135" Tests for getting the quickfix stack size
2136func XsizeTests(cchar)
2137  call s:setup_commands(a:cchar)
2138
2139  call g:Xsetlist([], 'f')
2140  call assert_equal(0, g:Xgetlist({'nr':'$'}).nr)
2141  call assert_equal(1, len(g:Xgetlist({'nr':'$', 'all':1})))
2142  call assert_equal(0, len(g:Xgetlist({'nr':0})))
2143
2144  Xexpr "File1:10:Line1"
2145  Xexpr "File2:20:Line2"
2146  Xexpr "File3:30:Line3"
2147  Xolder | Xolder
2148  call assert_equal(3, g:Xgetlist({'nr':'$'}).nr)
2149  call g:Xsetlist([], 'f')
2150
2151  Xexpr "File1:10:Line1"
2152  Xexpr "File2:20:Line2"
2153  Xexpr "File3:30:Line3"
2154  Xolder | Xolder
2155  call g:Xsetlist([], 'a', {'nr':'$', 'title':'Compiler'})
2156  call assert_equal('Compiler', g:Xgetlist({'nr':3, 'all':1}).title)
2157endfunc
2158
2159func Test_Qf_Size()
2160  call XsizeTests('c')
2161  call XsizeTests('l')
2162endfunc
2163