1" Test for the quickfix commands.
2
3if !has('quickfix')
4  finish
5endif
6
7set encoding=utf-8
8
9function! 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! -nargs=* -bang Xnext <mods>cnext<bang> <args>
28    command! -nargs=* -bang Xprev <mods>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! -nargs=* Xvimgrep <mods>vimgrep <args>
35    command! -nargs=* Xgrep <mods> grep <args>
36    command! -nargs=* Xgrepadd <mods> grepadd <args>
37    command! -nargs=* Xhelpgrep helpgrep <args>
38    let g:Xgetlist = function('getqflist')
39    let g:Xsetlist = function('setqflist')
40  else
41    command! -nargs=* -bang Xlist <mods>llist<bang> <args>
42    command! -nargs=* Xgetexpr <mods>lgetexpr <args>
43    command! -nargs=* Xaddexpr <mods>laddexpr <args>
44    command! -nargs=* Xolder <mods>lolder <args>
45    command! -nargs=* Xnewer <mods>lnewer <args>
46    command! -nargs=* Xopen <mods>lopen <args>
47    command! -nargs=* Xwindow <mods>lwindow <args>
48    command! -nargs=* Xbottom <mods>lbottom <args>
49    command! -nargs=* Xclose <mods>lclose <args>
50    command! -nargs=* -bang Xfile <mods>lfile<bang> <args>
51    command! -nargs=* Xgetfile <mods>lgetfile <args>
52    command! -nargs=* Xaddfile <mods>laddfile <args>
53    command! -nargs=* -bang Xbuffer <mods>lbuffer<bang> <args>
54    command! -nargs=* Xgetbuffer <mods>lgetbuffer <args>
55    command! -nargs=* Xaddbuffer <mods>laddbuffer <args>
56    command! -nargs=* Xrewind <mods>lrewind <args>
57    command! -nargs=* -bang Xnext <mods>lnext<bang> <args>
58    command! -nargs=* -bang Xprev <mods>lprev<bang> <args>
59    command! -nargs=* -bang Xfirst <mods>lfirst<bang> <args>
60    command! -nargs=* -bang Xlast <mods>llast<bang> <args>
61    command! -nargs=* -bang Xnfile <mods>lnfile<bang> <args>
62    command! -nargs=* -bang Xpfile <mods>lpfile<bang> <args>
63    command! -nargs=* Xexpr <mods>lexpr <args>
64    command! -nargs=* Xvimgrep <mods>lvimgrep <args>
65    command! -nargs=* Xgrep <mods> lgrep <args>
66    command! -nargs=* Xgrepadd <mods> lgrepadd <args>
67    command! -nargs=* Xhelpgrep lhelpgrep <args>
68    let g:Xgetlist = function('getloclist', [0])
69    let g:Xsetlist = function('setloclist', [0])
70  endif
71endfunction
72
73" Tests for the :clist and :llist commands
74function XlistTests(cchar)
75  call s:setup_commands(a:cchar)
76
77  " With an empty list, command should return error
78  Xgetexpr []
79  silent! Xlist
80  call assert_true(v:errmsg ==# 'E42: No Errors')
81
82  " Populate the list and then try
83  Xgetexpr ['non-error 1', 'Xtestfile1:1:3:Line1',
84		  \ 'non-error 2', 'Xtestfile2:2:2:Line2',
85		  \ 'non-error 3', 'Xtestfile3:3:1:Line3']
86
87  " List only valid entries
88  redir => result
89  Xlist
90  redir END
91  let l = split(result, "\n")
92  call assert_equal([' 2 Xtestfile1:1 col 3: Line1',
93		   \ ' 4 Xtestfile2:2 col 2: Line2',
94		   \ ' 6 Xtestfile3:3 col 1: Line3'], l)
95
96  " List all the entries
97  redir => result
98  Xlist!
99  redir END
100  let l = split(result, "\n")
101  call assert_equal([' 1: non-error 1', ' 2 Xtestfile1:1 col 3: Line1',
102		   \ ' 3: non-error 2', ' 4 Xtestfile2:2 col 2: Line2',
103		   \ ' 5: non-error 3', ' 6 Xtestfile3:3 col 1: Line3'], l)
104
105  " List a range of errors
106  redir => result
107  Xlist 3,6
108  redir END
109  let l = split(result, "\n")
110  call assert_equal([' 4 Xtestfile2:2 col 2: Line2',
111		   \ ' 6 Xtestfile3:3 col 1: Line3'], l)
112
113  redir => result
114  Xlist! 3,4
115  redir END
116  let l = split(result, "\n")
117  call assert_equal([' 3: non-error 2', ' 4 Xtestfile2:2 col 2: Line2'], l)
118
119  redir => result
120  Xlist -6,-4
121  redir END
122  let l = split(result, "\n")
123  call assert_equal([' 2 Xtestfile1:1 col 3: Line1'], l)
124
125  redir => result
126  Xlist! -5,-3
127  redir END
128  let l = split(result, "\n")
129  call assert_equal([' 2 Xtestfile1:1 col 3: Line1',
130		   \ ' 3: non-error 2', ' 4 Xtestfile2:2 col 2: Line2'], l)
131endfunction
132
133function Test_clist()
134  call XlistTests('c')
135  call XlistTests('l')
136endfunction
137
138" Tests for the :colder, :cnewer, :lolder and :lnewer commands
139" Note that this test assumes that a quickfix/location list is
140" already set by the caller.
141function XageTests(cchar)
142  call s:setup_commands(a:cchar)
143
144  " Jumping to a non existent list should return error
145  silent! Xolder 99
146  call assert_true(v:errmsg ==# 'E380: At bottom of quickfix stack')
147
148  silent! Xnewer 99
149  call assert_true(v:errmsg ==# 'E381: At top of quickfix stack')
150
151  " Add three quickfix/location lists
152  Xgetexpr ['Xtestfile1:1:3:Line1']
153  Xgetexpr ['Xtestfile2:2:2:Line2']
154  Xgetexpr ['Xtestfile3:3:1:Line3']
155
156  " Go back two lists
157  Xolder
158  let l = g:Xgetlist()
159  call assert_equal('Line2', l[0].text)
160
161  " Go forward two lists
162  Xnewer
163  let l = g:Xgetlist()
164  call assert_equal('Line3', l[0].text)
165
166  " Test for the optional count argument
167  Xolder 2
168  let l = g:Xgetlist()
169  call assert_equal('Line1', l[0].text)
170
171  Xnewer 2
172  let l = g:Xgetlist()
173  call assert_equal('Line3', l[0].text)
174endfunction
175
176function Test_cage()
177  let list = [{'bufnr': 1, 'lnum': 1}]
178  call setqflist(list)
179  call XageTests('c')
180
181  call setloclist(0, list)
182  call XageTests('l')
183endfunction
184
185" Tests for the :cwindow, :lwindow :cclose, :lclose, :copen and :lopen
186" commands
187function XwindowTests(cchar)
188  call s:setup_commands(a:cchar)
189
190  " Create a list with no valid entries
191  Xgetexpr ['non-error 1', 'non-error 2', 'non-error 3']
192
193  " Quickfix/Location window should not open with no valid errors
194  Xwindow
195  call assert_true(winnr('$') == 1)
196
197  " Create a list with valid entries
198  Xgetexpr ['Xtestfile1:1:3:Line1', 'Xtestfile2:2:2:Line2',
199		  \ 'Xtestfile3:3:1:Line3']
200
201  " Open the window
202  Xwindow
203  call assert_true(winnr('$') == 2 && winnr() == 2 &&
204	\ getline('.') ==# 'Xtestfile1|1 col 3| Line1')
205  redraw!
206
207  " Close the window
208  Xclose
209  call assert_true(winnr('$') == 1)
210
211  " Create a list with no valid entries
212  Xgetexpr ['non-error 1', 'non-error 2', 'non-error 3']
213
214  " Open the window
215  Xopen 5
216  call assert_true(winnr('$') == 2 && getline('.') ==# '|| non-error 1'
217		      \  && winheight('.') == 5)
218
219  " Opening the window again, should move the cursor to that window
220  wincmd t
221  Xopen 7
222  call assert_true(winnr('$') == 2 && winnr() == 2 &&
223	\ winheight('.') == 7 &&
224	\ getline('.') ==# '|| non-error 1')
225
226
227  " Calling cwindow should close the quickfix window with no valid errors
228  Xwindow
229  call assert_true(winnr('$') == 1)
230endfunction
231
232function Test_cwindow()
233  call XwindowTests('c')
234  call XwindowTests('l')
235endfunction
236
237" Tests for the :cfile, :lfile, :caddfile, :laddfile, :cgetfile and :lgetfile
238" commands.
239function XfileTests(cchar)
240  call s:setup_commands(a:cchar)
241
242  call writefile(['Xtestfile1:700:10:Line 700',
243	\ 'Xtestfile2:800:15:Line 800'], 'Xqftestfile1')
244
245  enew!
246  Xfile Xqftestfile1
247  let l = g:Xgetlist()
248  call assert_true(len(l) == 2 &&
249	\ l[0].lnum == 700 && l[0].col == 10 && l[0].text ==# 'Line 700' &&
250	\ l[1].lnum == 800 && l[1].col == 15 && l[1].text ==# 'Line 800')
251
252  " Test with a non existent file
253  call assert_fails('Xfile non_existent_file', 'E40')
254
255  " Run cfile/lfile from a modified buffer
256  enew!
257  silent! put ='Quickfix'
258  silent! Xfile Xqftestfile1
259  call assert_true(v:errmsg ==# 'E37: No write since last change (add ! to override)')
260
261  call writefile(['Xtestfile3:900:30:Line 900'], 'Xqftestfile1')
262  Xaddfile Xqftestfile1
263  let l = g:Xgetlist()
264  call assert_true(len(l) == 3 &&
265	\ l[2].lnum == 900 && l[2].col == 30 && l[2].text ==# 'Line 900')
266
267  call writefile(['Xtestfile1:222:77:Line 222',
268	\ 'Xtestfile2:333:88:Line 333'], 'Xqftestfile1')
269
270  enew!
271  Xgetfile Xqftestfile1
272  let l = g:Xgetlist()
273  call assert_true(len(l) == 2 &&
274	\ l[0].lnum == 222 && l[0].col == 77 && l[0].text ==# 'Line 222' &&
275	\ l[1].lnum == 333 && l[1].col == 88 && l[1].text ==# 'Line 333')
276
277  call delete('Xqftestfile1')
278endfunction
279
280function Test_cfile()
281  call XfileTests('c')
282  call XfileTests('l')
283endfunction
284
285" Tests for the :cbuffer, :lbuffer, :caddbuffer, :laddbuffer, :cgetbuffer and
286" :lgetbuffer commands.
287function XbufferTests(cchar)
288  call s:setup_commands(a:cchar)
289
290  enew!
291  silent! call setline(1, ['Xtestfile7:700:10:Line 700',
292	\ 'Xtestfile8:800:15:Line 800'])
293  Xbuffer!
294  let l = g:Xgetlist()
295  call assert_true(len(l) == 2 &&
296	\ l[0].lnum == 700 && l[0].col == 10 && l[0].text ==# 'Line 700' &&
297	\ l[1].lnum == 800 && l[1].col == 15 && l[1].text ==# 'Line 800')
298
299  enew!
300  silent! call setline(1, ['Xtestfile9:900:55:Line 900',
301	\ 'Xtestfile10:950:66:Line 950'])
302  Xgetbuffer
303  let l = g:Xgetlist()
304  call assert_true(len(l) == 2 &&
305	\ l[0].lnum == 900 && l[0].col == 55 && l[0].text ==# 'Line 900' &&
306	\ l[1].lnum == 950 && l[1].col == 66 && l[1].text ==# 'Line 950')
307
308  enew!
309  silent! call setline(1, ['Xtestfile11:700:20:Line 700',
310	\ 'Xtestfile12:750:25:Line 750'])
311  Xaddbuffer
312  let l = g:Xgetlist()
313  call assert_true(len(l) == 4 &&
314	\ l[1].lnum == 950 && l[1].col == 66 && l[1].text ==# 'Line 950' &&
315	\ l[2].lnum == 700 && l[2].col == 20 && l[2].text ==# 'Line 700' &&
316	\ l[3].lnum == 750 && l[3].col == 25 && l[3].text ==# 'Line 750')
317  enew!
318
319endfunction
320
321function Test_cbuffer()
322  call XbufferTests('c')
323  call XbufferTests('l')
324endfunction
325
326function XexprTests(cchar)
327  call s:setup_commands(a:cchar)
328
329  call assert_fails('Xexpr 10', 'E777:')
330endfunction
331
332function Test_cexpr()
333  call XexprTests('c')
334  call XexprTests('l')
335endfunction
336
337" Tests for :cnext, :cprev, :cfirst, :clast commands
338function Xtest_browse(cchar)
339  call s:setup_commands(a:cchar)
340
341  call s:create_test_file('Xqftestfile1')
342  call s:create_test_file('Xqftestfile2')
343
344  Xgetexpr ['Xqftestfile1:5:Line5',
345		\ 'Xqftestfile1:6:Line6',
346		\ 'Xqftestfile2:10:Line10',
347		\ 'Xqftestfile2:11:Line11']
348
349  Xfirst
350  call assert_fails('Xprev', 'E553')
351  call assert_fails('Xpfile', 'E553')
352  Xnfile
353  call assert_equal('Xqftestfile2', bufname('%'))
354  call assert_equal(10, line('.'))
355  Xpfile
356  call assert_equal('Xqftestfile1', bufname('%'))
357  call assert_equal(6, line('.'))
358  Xlast
359  call assert_equal('Xqftestfile2', bufname('%'))
360  call assert_equal(11, line('.'))
361  call assert_fails('Xnext', 'E553')
362  call assert_fails('Xnfile', 'E553')
363  Xrewind
364  call assert_equal('Xqftestfile1', bufname('%'))
365  call assert_equal(5, line('.'))
366
367  call delete('Xqftestfile1')
368  call delete('Xqftestfile2')
369endfunction
370
371function Test_browse()
372  call Xtest_browse('c')
373  call Xtest_browse('l')
374endfunction
375
376function Test_nomem()
377  call test_alloc_fail(GetAllocId('qf_dirname_start'), 0, 0)
378  call assert_fails('vimgrep vim runtest.vim', 'E342:')
379
380  call test_alloc_fail(GetAllocId('qf_dirname_now'), 0, 0)
381  call assert_fails('vimgrep vim runtest.vim', 'E342:')
382
383  call test_alloc_fail(GetAllocId('qf_namebuf'), 0, 0)
384  call assert_fails('cfile runtest.vim', 'E342:')
385
386  call test_alloc_fail(GetAllocId('qf_errmsg'), 0, 0)
387  call assert_fails('cfile runtest.vim', 'E342:')
388
389  call test_alloc_fail(GetAllocId('qf_pattern'), 0, 0)
390  call assert_fails('cfile runtest.vim', 'E342:')
391
392endfunc
393
394function! s:test_xhelpgrep(cchar)
395  call s:setup_commands(a:cchar)
396  Xhelpgrep quickfix
397  Xopen
398  if a:cchar == 'c'
399    let title_text = ':helpgrep quickfix'
400  else
401    let title_text = ':lhelpgrep quickfix'
402  endif
403  call assert_true(w:quickfix_title =~ title_text, w:quickfix_title)
404  " This wipes out the buffer, make sure that doesn't cause trouble.
405  Xclose
406endfunction
407
408function Test_helpgrep()
409  call s:test_xhelpgrep('c')
410  helpclose
411  call s:test_xhelpgrep('l')
412endfunc
413
414func Test_errortitle()
415  augroup QfBufWinEnter
416    au!
417    au BufWinEnter * :let g:a=get(w:, 'quickfix_title', 'NONE')
418  augroup END
419  copen
420  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'')'}]
421  call setqflist(a)
422  call assert_equal(':setqflist()', g:a)
423  augroup QfBufWinEnter
424    au!
425  augroup END
426  augroup! QfBufWinEnter
427endfunc
428
429func Test_vimgreptitle()
430  augroup QfBufWinEnter
431    au!
432    au BufWinEnter * :let g:a=get(w:, 'quickfix_title', 'NONE')
433  augroup END
434  try
435    vimgrep /pattern/j file
436  catch /E480/
437  endtry
438  copen
439  call assert_equal(':    vimgrep /pattern/j file', g:a)
440  augroup QfBufWinEnter
441    au!
442  augroup END
443  augroup! QfBufWinEnter
444endfunc
445
446function XqfTitleTests(cchar)
447  call s:setup_commands(a:cchar)
448
449  Xgetexpr ['file:1:1:message']
450  let l = g:Xgetlist()
451  if a:cchar == 'c'
452    call setqflist(l, 'r')
453  else
454    call setloclist(0, l, 'r')
455  endif
456
457  Xopen
458  if a:cchar == 'c'
459    let title = ':setqflist()'
460  else
461    let title = ':setloclist()'
462  endif
463  call assert_equal(title, w:quickfix_title)
464  Xclose
465endfunction
466
467" Tests for quickfix window's title
468function Test_qf_title()
469  call XqfTitleTests('c')
470  call XqfTitleTests('l')
471endfunction
472
473" Tests for 'errorformat'
474function Test_efm()
475  let save_efm = &efm
476  set efm=%EEEE%m,%WWWW%m,%+CCCC%.%#,%-GGGG%.%#
477  cgetexpr ['WWWW', 'EEEE', 'CCCC']
478  let l = strtrans(string(map(getqflist(), '[v:val.text, v:val.valid]')))
479  call assert_equal("[['W', 1], ['E^@CCCC', 1]]", l)
480  cgetexpr ['WWWW', 'GGGG', 'EEEE', 'CCCC']
481  let l = strtrans(string(map(getqflist(), '[v:val.text, v:val.valid]')))
482  call assert_equal("[['W', 1], ['E^@CCCC', 1]]", l)
483  cgetexpr ['WWWW', 'GGGG', 'ZZZZ', 'EEEE', 'CCCC', 'YYYY']
484  let l = strtrans(string(map(getqflist(), '[v:val.text, v:val.valid]')))
485  call assert_equal("[['W', 1], ['ZZZZ', 0], ['E^@CCCC', 1], ['YYYY', 0]]", l)
486  let &efm = save_efm
487endfunction
488
489" This will test for problems in quickfix:
490" A. incorrectly copying location lists which caused the location list to show
491"    a different name than the file that was actually being displayed.
492" B. not reusing the window for which the location list window is opened but
493"    instead creating new windows.
494" C. make sure that the location list window is not reused instead of the
495"    window it belongs to.
496"
497" Set up the test environment:
498function! ReadTestProtocol(name)
499  let base = substitute(a:name, '\v^test://(.*)%(\.[^.]+)?', '\1', '')
500  let word = substitute(base, '\v(.*)\..*', '\1', '')
501
502  setl modifiable
503  setl noreadonly
504  setl noswapfile
505  setl bufhidden=delete
506  %del _
507  " For problem 2:
508  " 'buftype' has to be set to reproduce the constant opening of new windows
509  setl buftype=nofile
510
511  call setline(1, word)
512
513  setl nomodified
514  setl nomodifiable
515  setl readonly
516  exe 'doautocmd BufRead ' . substitute(a:name, '\v^test://(.*)', '\1', '')
517endfunction
518
519function Test_locationlist()
520    enew
521
522    augroup testgroup
523      au!
524      autocmd BufReadCmd test://* call ReadTestProtocol(expand("<amatch>"))
525    augroup END
526
527    let words = [ "foo", "bar", "baz", "quux", "shmoo", "spam", "eggs" ]
528
529    let qflist = []
530    for word in words
531      call add(qflist, {'filename': 'test://' . word . '.txt', 'text': 'file ' . word . '.txt', })
532      " NOTE: problem 1:
533      " intentionally not setting 'lnum' so that the quickfix entries are not
534      " valid
535      call setloclist(0, qflist, ' ')
536    endfor
537
538    " Test A
539    lrewind
540    enew
541    lopen
542    lnext
543    lnext
544    lnext
545    lnext
546    vert split
547    wincmd L
548    lopen
549    wincmd p
550    lnext
551    let fileName = expand("%")
552    wincmd p
553    let locationListFileName = substitute(getline(line('.')), '\([^|]*\)|.*', '\1', '')
554    let fileName = substitute(fileName, '\\', '/', 'g')
555    let locationListFileName = substitute(locationListFileName, '\\', '/', 'g')
556    call assert_equal("test://bar.txt", fileName)
557    call assert_equal("test://bar.txt", locationListFileName)
558
559    wincmd n | only
560
561    " Test B:
562    lrewind
563    lopen
564    2
565    exe "normal \<CR>"
566    wincmd p
567    3
568    exe "normal \<CR>"
569    wincmd p
570    4
571    exe "normal \<CR>"
572    call assert_equal(2, winnr('$'))
573    wincmd n | only
574
575    " Test C:
576    lrewind
577    lopen
578    " Let's move the location list window to the top to check whether it (the
579    " first window found) will be reused when we try to open new windows:
580    wincmd K
581    2
582    exe "normal \<CR>"
583    wincmd p
584    3
585    exe "normal \<CR>"
586    wincmd p
587    4
588    exe "normal \<CR>"
589    1wincmd w
590    call assert_equal('quickfix', &buftype)
591    2wincmd w
592    let bufferName = expand("%")
593    let bufferName = substitute(bufferName, '\\', '/', 'g')
594    call assert_equal('test://quux.txt', bufferName)
595
596    wincmd n | only
597
598    augroup! testgroup
599endfunction
600
601function Test_locationlist_curwin_was_closed()
602    augroup testgroup
603      au!
604      autocmd BufReadCmd test_curwin.txt call R(expand("<amatch>"))
605    augroup END
606
607    function! R(n)
608      quit
609    endfunc
610
611    new
612    let q = []
613    call add(q, {'filename': 'test_curwin.txt' })
614    call setloclist(0, q)
615    call assert_fails('lrewind', 'E924:')
616
617    augroup! testgroup
618endfunction
619
620" More tests for 'errorformat'
621function! Test_efm1()
622    if !has('unix')
623	" The 'errorformat' setting is different on non-Unix systems.
624	" This test works only on Unix-like systems.
625	return
626    endif
627
628    let l = [
629      \ '"Xtestfile", line 4.12: 1506-045 (S) Undeclared identifier fd_set.',
630      \ '"Xtestfile", line 6 col 19; this is an error',
631      \ 'gcc -c -DHAVE_CONFIsing-prototypes -I/usr/X11R6/include  version.c',
632      \ 'Xtestfile:9: parse error before `asd''',
633      \ 'make: *** [vim] Error 1',
634      \ 'in file "Xtestfile" linenr 10: there is an error',
635      \ '',
636      \ '2 returned',
637      \ '"Xtestfile", line 11 col 1; this is an error',
638      \ '"Xtestfile", line 12 col 2; this is another error',
639      \ '"Xtestfile", line 14:10; this is an error in column 10',
640      \ '=Xtestfile=, line 15:10; this is another error, but in vcol 10 this time',
641      \ '"Xtestfile", linenr 16: yet another problem',
642      \ 'Error in "Xtestfile" at line 17:',
643      \ 'x should be a dot',
644      \ '	xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx    line 17',
645      \ '            ^',
646      \ 'Error in "Xtestfile" at line 18:',
647      \ 'x should be a dot',
648      \ '	xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx    line 18',
649      \ '.............^',
650      \ 'Error in "Xtestfile" at line 19:',
651      \ 'x should be a dot',
652      \ '	xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx    line 19',
653      \ '--------------^',
654      \ 'Error in "Xtestfile" at line 20:',
655      \ 'x should be a dot',
656      \ '	xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx    line 20',
657      \ '	       ^',
658      \ '',
659      \ 'Does anyone know what is the problem and how to correction it?',
660      \ '"Xtestfile", line 21 col 9: What is the title of the quickfix window?',
661      \ '"Xtestfile", line 22 col 9: What is the title of the quickfix window?'
662      \ ]
663
664    call writefile(l, 'Xerrorfile1')
665    call writefile(l[:-2], 'Xerrorfile2')
666
667    let m = [
668	\ '	xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx    line  2',
669	\ '	xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx    line  3',
670	\ '	xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx    line  4',
671	\ '	xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx    line  5',
672	\ '	xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx    line  6',
673	\ '	xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx    line  7',
674	\ '	xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx    line  8',
675	\ '	xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx    line  9',
676	\ '	xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx    line 10',
677	\ '	xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx    line 11',
678	\ '	xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx    line 12',
679	\ '	xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx    line 13',
680	\ '	xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx    line 14',
681	\ '	xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx    line 15',
682	\ '	xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx    line 16',
683	\ '	xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx    line 17',
684	\ '	xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx    line 18',
685	\ '	xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx    line 19',
686	\ '	xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx    line 20',
687	\ '	xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx    line 21',
688	\ '	xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx    line 22'
689	\ ]
690    call writefile(m, 'Xtestfile')
691
692    let save_efm = &efm
693    set efm+==%f=\\,\ line\ %l%*\\D%v%*[^\ ]\ %m
694    set efm^=%AError\ in\ \"%f\"\ at\ line\ %l:,%Z%p^,%C%m
695
696    exe 'cf Xerrorfile2'
697    clast
698    copen
699    call assert_equal(':cf Xerrorfile2', w:quickfix_title)
700    wincmd p
701
702    exe 'cf Xerrorfile1'
703    call assert_equal([4, 12], [line('.'), col('.')])
704    cn
705    call assert_equal([6, 19], [line('.'), col('.')])
706    cn
707    call assert_equal([9, 2], [line('.'), col('.')])
708    cn
709    call assert_equal([10, 2], [line('.'), col('.')])
710    cn
711    call assert_equal([11, 1], [line('.'), col('.')])
712    cn
713    call assert_equal([12, 2], [line('.'), col('.')])
714    cn
715    call assert_equal([14, 10], [line('.'), col('.')])
716    cn
717    call assert_equal([15, 3, 10], [line('.'), col('.'), virtcol('.')])
718    cn
719    call assert_equal([16, 2], [line('.'), col('.')])
720    cn
721    call assert_equal([17, 6], [line('.'), col('.')])
722    cn
723    call assert_equal([18, 7], [line('.'), col('.')])
724    cn
725    call assert_equal([19, 8], [line('.'), col('.')])
726    cn
727    call assert_equal([20, 9], [line('.'), col('.')])
728    clast
729    cprev
730    cprev
731    wincmd w
732    call assert_equal(':cf Xerrorfile1', w:quickfix_title)
733    wincmd p
734
735    let &efm = save_efm
736    call delete('Xerrorfile1')
737    call delete('Xerrorfile2')
738    call delete('Xtestfile')
739endfunction
740
741" Test for quickfix directory stack support
742function! s:dir_stack_tests(cchar)
743  call s:setup_commands(a:cchar)
744
745  let save_efm=&efm
746  set efm=%DEntering\ dir\ '%f',%f:%l:%m,%XLeaving\ dir\ '%f'
747
748  let lines = ["Entering dir 'dir1/a'",
749		\ 'habits2.txt:1:Nine Healthy Habits',
750		\ "Entering dir 'b'",
751		\ 'habits3.txt:2:0 Hours of television',
752		\ 'habits2.txt:7:5 Small meals',
753		\ "Entering dir 'dir1/c'",
754		\ 'habits4.txt:3:1 Hour of exercise',
755		\ "Leaving dir 'dir1/c'",
756		\ "Leaving dir 'dir1/a'",
757		\ 'habits1.txt:4:2 Liters of water',
758		\ "Entering dir 'dir2'",
759		\ 'habits5.txt:5:3 Cups of hot green tea',
760		\ "Leaving dir 'dir2'"
761		\]
762
763  Xexpr ""
764  for l in lines
765      Xaddexpr l
766  endfor
767
768  let qf = g:Xgetlist()
769
770  call assert_equal('dir1/a/habits2.txt', bufname(qf[1].bufnr))
771  call assert_equal(1, qf[1].lnum)
772  call assert_equal('dir1/a/b/habits3.txt', bufname(qf[3].bufnr))
773  call assert_equal(2, qf[3].lnum)
774  call assert_equal('dir1/a/habits2.txt', bufname(qf[4].bufnr))
775  call assert_equal(7, qf[4].lnum)
776  call assert_equal('dir1/c/habits4.txt', bufname(qf[6].bufnr))
777  call assert_equal(3, qf[6].lnum)
778  call assert_equal('habits1.txt', bufname(qf[9].bufnr))
779  call assert_equal(4, qf[9].lnum)
780  call assert_equal('dir2/habits5.txt', bufname(qf[11].bufnr))
781  call assert_equal(5, qf[11].lnum)
782
783  let &efm=save_efm
784endfunction
785
786" Tests for %D and %X errorformat options
787function! Test_efm_dirstack()
788  " Create the directory stack and files
789  call mkdir('dir1')
790  call mkdir('dir1/a')
791  call mkdir('dir1/a/b')
792  call mkdir('dir1/c')
793  call mkdir('dir2')
794
795  let lines = ["Nine Healthy Habits",
796		\ "0 Hours of television",
797		\ "1 Hour of exercise",
798		\ "2 Liters of water",
799		\ "3 Cups of hot green tea",
800		\ "4 Short mental breaks",
801		\ "5 Small meals",
802		\ "6 AM wake up time",
803		\ "7 Minutes of laughter",
804		\ "8 Hours of sleep (at least)",
805		\ "9 PM end of the day and off to bed"
806		\ ]
807  call writefile(lines, 'habits1.txt')
808  call writefile(lines, 'dir1/a/habits2.txt')
809  call writefile(lines, 'dir1/a/b/habits3.txt')
810  call writefile(lines, 'dir1/c/habits4.txt')
811  call writefile(lines, 'dir2/habits5.txt')
812
813  call s:dir_stack_tests('c')
814  call s:dir_stack_tests('l')
815
816  call delete('dir1', 'rf')
817  call delete('dir2', 'rf')
818  call delete('habits1.txt')
819endfunction
820
821" Tests for invalid error format specifies
822function Xinvalid_efm_Tests(cchar)
823  call s:setup_commands(a:cchar)
824
825  let save_efm = &efm
826
827  set efm=%f:%l:%m,%f:%f:%l:%m
828  call assert_fails('Xexpr "abc.txt:1:Hello world"', 'E372:')
829
830  set efm=%f:%l:%m,%f:%l:%r:%m
831  call assert_fails('Xexpr "abc.txt:1:Hello world"', 'E373:')
832
833  set efm=%f:%l:%m,%O:%f:%l:%m
834  call assert_fails('Xexpr "abc.txt:1:Hello world"', 'E373:')
835
836  set efm=%f:%l:%m,%f:%l:%*[^a-z
837  call assert_fails('Xexpr "abc.txt:1:Hello world"', 'E374:')
838
839  set efm=%f:%l:%m,%f:%l:%*c
840  call assert_fails('Xexpr "abc.txt:1:Hello world"', 'E375:')
841
842  set efm=%f:%l:%m,%L%M%N
843  call assert_fails('Xexpr "abc.txt:1:Hello world"', 'E376:')
844
845  set efm=%f:%l:%m,%f:%l:%m:%R
846  call assert_fails('Xexpr "abc.txt:1:Hello world"', 'E377:')
847
848  set efm=
849  call assert_fails('Xexpr "abc.txt:1:Hello world"', 'E378:')
850
851  set efm=%DEntering\ dir\ abc,%f:%l:%m
852  call assert_fails('Xexpr ["Entering dir abc", "abc.txt:1:Hello world"]', 'E379:')
853
854  let &efm = save_efm
855endfunction
856
857function Test_invalid_efm()
858  call Xinvalid_efm_Tests('c')
859  call Xinvalid_efm_Tests('l')
860endfunction
861
862" TODO:
863" Add tests for the following formats in 'errorformat'
864"	%r  %O
865function! Test_efm2()
866  let save_efm = &efm
867
868  " Test for %s format in efm
869  set efm=%f:%s
870  cexpr 'Xtestfile:Line search text'
871  let l = getqflist()
872  call assert_equal(l[0].pattern, '^\VLine search text\$')
873  call assert_equal(l[0].lnum, 0)
874
875  " Test for %P, %Q and %t format specifiers
876  let lines=["[Xtestfile1]",
877	      \ "(1,17)  error: ';' missing",
878	      \ "(21,2)  warning: variable 'z' not defined",
879	      \ "(67,3)  error: end of file found before string ended",
880	      \ "",
881	      \ "[Xtestfile2]",
882	      \ "",
883	      \ "[Xtestfile3]",
884	      \ "NEW compiler v1.1",
885	      \ "(2,2)   warning: variable 'x' not defined",
886	      \ "(67,3)  warning: 's' already defined"
887	      \]
888  set efm=%+P[%f],(%l\\,%c)%*[\ ]%t%*[^:]:\ %m,%-Q
889  cexpr ""
890  for l in lines
891      caddexpr l
892  endfor
893  let l = getqflist()
894  call assert_equal(9, len(l))
895  call assert_equal(21, l[2].lnum)
896  call assert_equal(2, l[2].col)
897  call assert_equal('w', l[2].type)
898  call assert_equal('e', l[3].type)
899
900  " Tests for %E, %C and %Z format specifiers
901  let lines = ["Error 275",
902	      \ "line 42",
903	      \ "column 3",
904	      \ "' ' expected after '--'"
905	      \]
906  set efm=%EError\ %n,%Cline\ %l,%Ccolumn\ %c,%Z%m
907  cgetexpr lines
908  let l = getqflist()
909  call assert_equal(275, l[0].nr)
910  call assert_equal(42, l[0].lnum)
911  call assert_equal(3, l[0].col)
912  call assert_equal('E', l[0].type)
913  call assert_equal("\n' ' expected after '--'", l[0].text)
914
915  " Test for %>
916  let lines = ["Error in line 147 of foo.c:",
917	      \"unknown variable 'i'"
918	      \]
919  set efm=unknown\ variable\ %m,%E%>Error\ in\ line\ %l\ of\ %f:,%Z%m
920  cgetexpr lines
921  let l = getqflist()
922  call assert_equal(147, l[0].lnum)
923  call assert_equal('E', l[0].type)
924  call assert_equal("\nunknown variable 'i'", l[0].text)
925
926  " Test for %A, %C and other formats
927  let lines = [
928	  \"==============================================================",
929	  \"FAIL: testGetTypeIdCachesResult (dbfacadeTest.DjsDBFacadeTest)",
930	  \"--------------------------------------------------------------",
931	  \"Traceback (most recent call last):",
932	  \'  File "unittests/dbfacadeTest.py", line 89, in testFoo',
933	  \"    self.assertEquals(34, dtid)",
934	  \'  File "/usr/lib/python2.2/unittest.py", line 286, in',
935	  \" failUnlessEqual",
936	  \"    raise self.failureException, \\",
937	  \"AssertionError: 34 != 33",
938	  \"",
939	  \"--------------------------------------------------------------",
940	  \"Ran 27 tests in 0.063s"
941	  \]
942  set efm=%C\ %.%#,%A\ \ File\ \"%f\"\\,\ line\ %l%.%#,%Z%[%^\ ]%\\@=%m
943  cgetexpr lines
944  let l = getqflist()
945  call assert_equal(8, len(l))
946  call assert_equal(89, l[4].lnum)
947  call assert_equal(1, l[4].valid)
948  call assert_equal('unittests/dbfacadeTest.py', bufname(l[4].bufnr))
949
950  let &efm = save_efm
951endfunction
952
953function XquickfixChangedByAutocmd(cchar)
954  call s:setup_commands(a:cchar)
955  if a:cchar == 'c'
956    let ErrorNr = 'E925'
957    function! ReadFunc()
958      colder
959      cgetexpr []
960    endfunc
961  else
962    let ErrorNr = 'E926'
963    function! ReadFunc()
964      lolder
965      lgetexpr []
966    endfunc
967  endif
968
969  augroup testgroup
970    au!
971    autocmd BufReadCmd test_changed.txt call ReadFunc()
972  augroup END
973
974  new | only
975  let words = [ "a", "b" ]
976  let qflist = []
977  for word in words
978    call add(qflist, {'filename': 'test_changed.txt'})
979    call g:Xsetlist(qflist, ' ')
980  endfor
981  call assert_fails('Xrewind', ErrorNr . ':')
982
983  augroup! testgroup
984endfunc
985
986function Test_quickfix_was_changed_by_autocmd()
987  call XquickfixChangedByAutocmd('c')
988  call XquickfixChangedByAutocmd('l')
989endfunction
990
991func Test_caddbuffer_to_empty()
992  helpgr quickfix
993  call setqflist([], 'r')
994  cad
995  try
996    cn
997  catch
998    " number of matches is unknown
999    call assert_true(v:exception =~ 'E553:')
1000  endtry
1001  quit!
1002endfunc
1003
1004func Test_cgetexpr_works()
1005  " this must not crash Vim
1006  cgetexpr [$x]
1007  lgetexpr [$x]
1008endfunc
1009
1010" Tests for the setqflist() and setloclist() functions
1011function SetXlistTests(cchar, bnum)
1012  call s:setup_commands(a:cchar)
1013
1014  call g:Xsetlist([{'bufnr': a:bnum, 'lnum': 1},
1015	      \  {'bufnr': a:bnum, 'lnum': 2}])
1016  let l = g:Xgetlist()
1017  call assert_equal(2, len(l))
1018  call assert_equal(2, l[1].lnum)
1019
1020  Xnext
1021  call g:Xsetlist([{'bufnr': a:bnum, 'lnum': 3}], 'a')
1022  let l = g:Xgetlist()
1023  call assert_equal(3, len(l))
1024  Xnext
1025  call assert_equal(3, line('.'))
1026
1027  " Appending entries to the list should not change the cursor position
1028  " in the quickfix window
1029  Xwindow
1030  1
1031  call g:Xsetlist([{'bufnr': a:bnum, 'lnum': 4},
1032	      \  {'bufnr': a:bnum, 'lnum': 5}], 'a')
1033  call assert_equal(1, line('.'))
1034  close
1035
1036  call g:Xsetlist([{'bufnr': a:bnum, 'lnum': 3},
1037	      \  {'bufnr': a:bnum, 'lnum': 4},
1038	      \  {'bufnr': a:bnum, 'lnum': 5}], 'r')
1039  let l = g:Xgetlist()
1040  call assert_equal(3, len(l))
1041  call assert_equal(5, l[2].lnum)
1042
1043  call g:Xsetlist([])
1044  let l = g:Xgetlist()
1045  call assert_equal(0, len(l))
1046endfunction
1047
1048function Test_setqflist()
1049  new Xtestfile | only
1050  let bnum = bufnr('%')
1051  call setline(1, range(1,5))
1052
1053  call SetXlistTests('c', bnum)
1054  call SetXlistTests('l', bnum)
1055
1056  enew!
1057  call delete('Xtestfile')
1058endfunction
1059
1060function Xlist_empty_middle(cchar)
1061  call s:setup_commands(a:cchar)
1062
1063  " create three quickfix lists
1064  Xvimgrep Test_ test_quickfix.vim
1065  let testlen = len(g:Xgetlist())
1066  call assert_true(testlen > 0)
1067  Xvimgrep empty test_quickfix.vim
1068  call assert_true(len(g:Xgetlist()) > 0)
1069  Xvimgrep matches test_quickfix.vim
1070  let matchlen = len(g:Xgetlist())
1071  call assert_true(matchlen > 0)
1072  Xolder
1073  " make the middle list empty
1074  call g:Xsetlist([], 'r')
1075  call assert_true(len(g:Xgetlist()) == 0)
1076  Xolder
1077  call assert_equal(testlen, len(g:Xgetlist()))
1078  Xnewer
1079  Xnewer
1080  call assert_equal(matchlen, len(g:Xgetlist()))
1081endfunc
1082
1083function Test_setqflist_empty_middle()
1084  call Xlist_empty_middle('c')
1085  call Xlist_empty_middle('l')
1086endfunction
1087
1088function Xlist_empty_older(cchar)
1089  call s:setup_commands(a:cchar)
1090
1091  " create three quickfix lists
1092  Xvimgrep one test_quickfix.vim
1093  let onelen = len(g:Xgetlist())
1094  call assert_true(onelen > 0)
1095  Xvimgrep two test_quickfix.vim
1096  let twolen = len(g:Xgetlist())
1097  call assert_true(twolen > 0)
1098  Xvimgrep three test_quickfix.vim
1099  let threelen = len(g:Xgetlist())
1100  call assert_true(threelen > 0)
1101  Xolder 2
1102  " make the first list empty, check the others didn't change
1103  call g:Xsetlist([], 'r')
1104  call assert_true(len(g:Xgetlist()) == 0)
1105  Xnewer
1106  call assert_equal(twolen, len(g:Xgetlist()))
1107  Xnewer
1108  call assert_equal(threelen, len(g:Xgetlist()))
1109endfunction
1110
1111function Test_setqflist_empty_older()
1112  call Xlist_empty_older('c')
1113  call Xlist_empty_older('l')
1114endfunction
1115
1116function! XquickfixSetListWithAct(cchar)
1117  call s:setup_commands(a:cchar)
1118
1119  let list1 = [{'filename': 'fnameA', 'text': 'A'},
1120          \    {'filename': 'fnameB', 'text': 'B'}]
1121  let list2 = [{'filename': 'fnameC', 'text': 'C'},
1122          \    {'filename': 'fnameD', 'text': 'D'},
1123          \    {'filename': 'fnameE', 'text': 'E'}]
1124
1125  " {action} is unspecified.  Same as specifing ' '.
1126  new | only
1127  silent! Xnewer 99
1128  call g:Xsetlist(list1)
1129  call g:Xsetlist(list2)
1130  let li = g:Xgetlist()
1131  call assert_equal(3, len(li))
1132  call assert_equal('C', li[0]['text'])
1133  call assert_equal('D', li[1]['text'])
1134  call assert_equal('E', li[2]['text'])
1135  silent! Xolder
1136  let li = g:Xgetlist()
1137  call assert_equal(2, len(li))
1138  call assert_equal('A', li[0]['text'])
1139  call assert_equal('B', li[1]['text'])
1140
1141  " {action} is specified ' '.
1142  new | only
1143  silent! Xnewer 99
1144  call g:Xsetlist(list1)
1145  call g:Xsetlist(list2, ' ')
1146  let li = g:Xgetlist()
1147  call assert_equal(3, len(li))
1148  call assert_equal('C', li[0]['text'])
1149  call assert_equal('D', li[1]['text'])
1150  call assert_equal('E', li[2]['text'])
1151  silent! Xolder
1152  let li = g:Xgetlist()
1153  call assert_equal(2, len(li))
1154  call assert_equal('A', li[0]['text'])
1155  call assert_equal('B', li[1]['text'])
1156
1157  " {action} is specified 'a'.
1158  new | only
1159  silent! Xnewer 99
1160  call g:Xsetlist(list1)
1161  call g:Xsetlist(list2, 'a')
1162  let li = g:Xgetlist()
1163  call assert_equal(5, len(li))
1164  call assert_equal('A', li[0]['text'])
1165  call assert_equal('B', li[1]['text'])
1166  call assert_equal('C', li[2]['text'])
1167  call assert_equal('D', li[3]['text'])
1168  call assert_equal('E', li[4]['text'])
1169
1170  " {action} is specified 'r'.
1171  new | only
1172  silent! Xnewer 99
1173  call g:Xsetlist(list1)
1174  call g:Xsetlist(list2, 'r')
1175  let li = g:Xgetlist()
1176  call assert_equal(3, len(li))
1177  call assert_equal('C', li[0]['text'])
1178  call assert_equal('D', li[1]['text'])
1179  call assert_equal('E', li[2]['text'])
1180
1181  " Test for wrong value.
1182  new | only
1183  call assert_fails("call g:Xsetlist(0)", 'E714:')
1184  call assert_fails("call g:Xsetlist(list1, '')", 'E927:')
1185  call assert_fails("call g:Xsetlist(list1, 'aa')", 'E927:')
1186  call assert_fails("call g:Xsetlist(list1, ' a')", 'E927:')
1187  call assert_fails("call g:Xsetlist(list1, 0)", 'E928:')
1188endfunc
1189
1190function Test_quickfix_set_list_with_act()
1191  call XquickfixSetListWithAct('c')
1192  call XquickfixSetListWithAct('l')
1193endfunction
1194
1195function XLongLinesTests(cchar)
1196  let l = g:Xgetlist()
1197
1198  call assert_equal(4, len(l))
1199  call assert_equal(1, l[0].lnum)
1200  call assert_equal(1, l[0].col)
1201  call assert_equal(1975, len(l[0].text))
1202  call assert_equal(2, l[1].lnum)
1203  call assert_equal(1, l[1].col)
1204  call assert_equal(4070, len(l[1].text))
1205  call assert_equal(3, l[2].lnum)
1206  call assert_equal(1, l[2].col)
1207  call assert_equal(4070, len(l[2].text))
1208  call assert_equal(4, l[3].lnum)
1209  call assert_equal(1, l[3].col)
1210  call assert_equal(10, len(l[3].text))
1211
1212  call g:Xsetlist([], 'r')
1213endfunction
1214
1215function s:long_lines_tests(cchar)
1216  call s:setup_commands(a:cchar)
1217
1218  let testfile = 'samples/quickfix.txt'
1219
1220  " file
1221  exe 'Xgetfile' testfile
1222  call XLongLinesTests(a:cchar)
1223
1224  " list
1225  Xexpr readfile(testfile)
1226  call XLongLinesTests(a:cchar)
1227
1228  " string
1229  Xexpr join(readfile(testfile), "\n")
1230  call XLongLinesTests(a:cchar)
1231
1232  " buffer
1233  exe 'edit' testfile
1234  exe 'Xbuffer' bufnr('%')
1235  call XLongLinesTests(a:cchar)
1236endfunction
1237
1238function Test_long_lines()
1239  call s:long_lines_tests('c')
1240  call s:long_lines_tests('l')
1241endfunction
1242
1243function! s:create_test_file(filename)
1244  let l = []
1245  for i in range(1, 20)
1246      call add(l, 'Line' . i)
1247  endfor
1248  call writefile(l, a:filename)
1249endfunction
1250
1251function! Test_switchbuf()
1252  call s:create_test_file('Xqftestfile1')
1253  call s:create_test_file('Xqftestfile2')
1254  call s:create_test_file('Xqftestfile3')
1255
1256  new | only
1257  edit Xqftestfile1
1258  let file1_winid = win_getid()
1259  new Xqftestfile2
1260  let file2_winid = win_getid()
1261  cgetexpr ['Xqftestfile1:5:Line5',
1262		\ 'Xqftestfile1:6:Line6',
1263		\ 'Xqftestfile2:10:Line10',
1264		\ 'Xqftestfile2:11:Line11',
1265		\ 'Xqftestfile3:15:Line15',
1266		\ 'Xqftestfile3:16:Line16']
1267
1268  new
1269  let winid = win_getid()
1270  cfirst | cnext
1271  call assert_equal(winid, win_getid())
1272  cnext | cnext
1273  call assert_equal(winid, win_getid())
1274  cnext | cnext
1275  call assert_equal(winid, win_getid())
1276  enew
1277
1278  set switchbuf=useopen
1279  cfirst | cnext
1280  call assert_equal(file1_winid, win_getid())
1281  cnext | cnext
1282  call assert_equal(file2_winid, win_getid())
1283  cnext | cnext
1284  call assert_equal(file2_winid, win_getid())
1285
1286  enew | only
1287  set switchbuf=usetab
1288  tabedit Xqftestfile1
1289  tabedit Xqftestfile2
1290  tabfirst
1291  cfirst | cnext
1292  call assert_equal(2, tabpagenr())
1293  cnext | cnext
1294  call assert_equal(3, tabpagenr())
1295  cnext | cnext
1296  call assert_equal(3, tabpagenr())
1297  tabfirst | tabonly | enew
1298
1299  set switchbuf=split
1300  cfirst | cnext
1301  call assert_equal(1, winnr('$'))
1302  cnext | cnext
1303  call assert_equal(2, winnr('$'))
1304  cnext | cnext
1305  call assert_equal(3, winnr('$'))
1306  enew | only
1307
1308  set switchbuf=newtab
1309  cfirst | cnext
1310  call assert_equal(1, tabpagenr('$'))
1311  cnext | cnext
1312  call assert_equal(2, tabpagenr('$'))
1313  cnext | cnext
1314  call assert_equal(3, tabpagenr('$'))
1315  tabfirst | enew | tabonly | only
1316
1317  set switchbuf=
1318  edit Xqftestfile1
1319  let file1_winid = win_getid()
1320  new Xqftestfile2
1321  let file2_winid = win_getid()
1322  copen
1323  exe "normal 1G\<CR>"
1324  call assert_equal(file1_winid, win_getid())
1325  copen
1326  exe "normal 3G\<CR>"
1327  call assert_equal(file2_winid, win_getid())
1328  copen | only
1329  exe "normal 5G\<CR>"
1330  call assert_equal(2, winnr('$'))
1331  call assert_equal(1, bufwinnr('Xqftestfile3'))
1332
1333  enew | only
1334
1335  call delete('Xqftestfile1')
1336  call delete('Xqftestfile2')
1337  call delete('Xqftestfile3')
1338endfunction
1339
1340function! Xadjust_qflnum(cchar)
1341  call s:setup_commands(a:cchar)
1342
1343  enew | only
1344
1345  let fname = 'Xqftestfile' . a:cchar
1346  call s:create_test_file(fname)
1347  exe 'edit ' . fname
1348
1349  Xgetexpr [fname . ':5:Line5',
1350	      \ fname . ':10:Line10',
1351	      \ fname . ':15:Line15',
1352	      \ fname . ':20:Line20']
1353
1354  6,14delete
1355  call append(6, ['Buffer', 'Window'])
1356
1357  let l = g:Xgetlist()
1358
1359  call assert_equal(5, l[0].lnum)
1360  call assert_equal(6, l[2].lnum)
1361  call assert_equal(13, l[3].lnum)
1362
1363  enew!
1364  call delete(fname)
1365endfunction
1366
1367function! Test_adjust_lnum()
1368  call setloclist(0, [])
1369  call Xadjust_qflnum('c')
1370  call setqflist([])
1371  call Xadjust_qflnum('l')
1372endfunction
1373
1374" Tests for the :grep/:lgrep and :grepadd/:lgrepadd commands
1375function! s:test_xgrep(cchar)
1376  call s:setup_commands(a:cchar)
1377
1378  " The following lines are used for the grep test. Don't remove.
1379  " Grep_Test_Text: Match 1
1380  " Grep_Test_Text: Match 2
1381  " GrepAdd_Test_Text: Match 1
1382  " GrepAdd_Test_Text: Match 2
1383  enew! | only
1384  set makeef&vim
1385  silent Xgrep Grep_Test_Text: test_quickfix.vim
1386  call assert_true(len(g:Xgetlist()) == 3)
1387  Xopen
1388  call assert_true(w:quickfix_title =~ '^:grep')
1389  Xclose
1390  enew
1391  set makeef=Temp_File_##
1392  silent Xgrepadd GrepAdd_Test_Text: test_quickfix.vim
1393  call assert_true(len(g:Xgetlist()) == 6)
1394endfunction
1395
1396function! Test_grep()
1397  if !has('unix')
1398    " The grepprg may not be set on non-Unix systems
1399    return
1400  endif
1401
1402  call s:test_xgrep('c')
1403  call s:test_xgrep('l')
1404endfunction
1405
1406function! Test_two_windows()
1407  " Use one 'errorformat' for two windows.  Add an expression to each of them,
1408  " make sure they each keep their own state.
1409  set efm=%DEntering\ dir\ '%f',%f:%l:%m,%XLeaving\ dir\ '%f'
1410  call mkdir('Xone/a', 'p')
1411  call mkdir('Xtwo/a', 'p')
1412  let lines = ['1', '2', 'one one one', '4', 'two two two', '6', '7']
1413  call writefile(lines, 'Xone/a/one.txt')
1414  call writefile(lines, 'Xtwo/a/two.txt')
1415
1416  new one
1417  let one_id = win_getid()
1418  lexpr ""
1419  new two
1420  let two_id = win_getid()
1421  lexpr ""
1422
1423  laddexpr "Entering dir 'Xtwo/a'"
1424  call win_gotoid(one_id)
1425  laddexpr "Entering dir 'Xone/a'"
1426  call win_gotoid(two_id)
1427  laddexpr 'two.txt:5:two two two'
1428  call win_gotoid(one_id)
1429  laddexpr 'one.txt:3:one one one'
1430
1431  let loc_one = getloclist(one_id)
1432echo string(loc_one)
1433  call assert_equal('Xone/a/one.txt', bufname(loc_one[1].bufnr))
1434  call assert_equal(3, loc_one[1].lnum)
1435
1436  let loc_two = getloclist(two_id)
1437echo string(loc_two)
1438  call assert_equal('Xtwo/a/two.txt', bufname(loc_two[1].bufnr))
1439  call assert_equal(5, loc_two[1].lnum)
1440
1441  call win_gotoid(one_id)
1442  bwipe!
1443  call win_gotoid(two_id)
1444  bwipe!
1445  call delete('Xone', 'rf')
1446  call delete('Xtwo', 'rf')
1447endfunc
1448
1449function XbottomTests(cchar)
1450  call s:setup_commands(a:cchar)
1451
1452  call g:Xsetlist([{'filename': 'foo', 'lnum': 42}])
1453  Xopen
1454  let wid = win_getid()
1455  call assert_equal(1, line('.'))
1456  wincmd w
1457  call g:Xsetlist([{'filename': 'var', 'lnum': 24}], 'a')
1458  Xbottom
1459  call win_gotoid(wid)
1460  call assert_equal(2, line('.'))
1461  Xclose
1462endfunc
1463
1464" Tests for the :cbottom and :lbottom commands
1465function Test_cbottom()
1466  call XbottomTests('c')
1467  call XbottomTests('l')
1468endfunction
1469
1470function HistoryTest(cchar)
1471  call s:setup_commands(a:cchar)
1472
1473  call assert_fails(a:cchar . 'older 99', 'E380:')
1474  " clear all lists after the first one, then replace the first one.
1475  call g:Xsetlist([])
1476  Xolder
1477  let entry = {'filename': 'foo', 'lnum': 42}
1478  call g:Xsetlist([entry], 'r')
1479  call g:Xsetlist([entry, entry])
1480  call g:Xsetlist([entry, entry, entry])
1481  let res = split(execute(a:cchar . 'hist'), "\n")
1482  call assert_equal(3, len(res))
1483  let common = 'errors     :set' . (a:cchar == 'c' ? 'qf' : 'loc') . 'list()'
1484  call assert_equal('  error list 1 of 3; 1 ' . common, res[0])
1485  call assert_equal('  error list 2 of 3; 2 ' . common, res[1])
1486  call assert_equal('> error list 3 of 3; 3 ' . common, res[2])
1487endfunc
1488
1489func Test_history()
1490  call HistoryTest('c')
1491  call HistoryTest('l')
1492endfunc
1493
1494func Test_duplicate_buf()
1495  " make sure we can get the highest buffer number
1496  edit DoesNotExist
1497  edit DoesNotExist2
1498  let last_buffer = bufnr("$")
1499
1500  " make sure only one buffer is created
1501  call writefile(['this one', 'that one'], 'Xgrepthis')
1502  vimgrep one Xgrepthis
1503  vimgrep one Xgrepthis
1504  call assert_equal(last_buffer + 1, bufnr("$"))
1505
1506  call delete('Xgrepthis')
1507endfunc
1508
1509" Quickfix/Location list set/get properties tests
1510function Xproperty_tests(cchar)
1511    call s:setup_commands(a:cchar)
1512
1513    " Error cases
1514    call assert_fails('call g:Xgetlist(99)', 'E715:')
1515    call assert_fails('call g:Xsetlist(99)', 'E714:')
1516    call assert_fails('call g:Xsetlist([], "a", [])', 'E715:')
1517
1518    " Set and get the title
1519    Xopen
1520    wincmd p
1521    call g:Xsetlist([{'filename':'foo', 'lnum':27}])
1522    call g:Xsetlist([], 'a', {'title' : 'Sample'})
1523    let d = g:Xgetlist({"title":1})
1524    call assert_equal('Sample', d.title)
1525
1526    Xopen
1527    call assert_equal('Sample', w:quickfix_title)
1528    Xclose
1529
1530    " Tests for action argument
1531    silent! Xolder 999
1532    let qfnr = g:Xgetlist({'all':1}).nr
1533    call g:Xsetlist([], 'r', {'title' : 'N1'})
1534    call assert_equal('N1', g:Xgetlist({'all':1}).title)
1535    call g:Xsetlist([], ' ', {'title' : 'N2'})
1536    call assert_equal(qfnr + 1, g:Xgetlist({'all':1}).nr)
1537    call g:Xsetlist([], ' ', {'title' : 'N3'})
1538    call assert_equal('N2', g:Xgetlist({'nr':2, 'title':1}).title)
1539
1540    " Invalid arguments
1541    call assert_fails('call g:Xgetlist([])', 'E715')
1542    call assert_fails('call g:Xsetlist([], "a", [])', 'E715')
1543    let s = g:Xsetlist([], 'a', {'abc':1})
1544    call assert_equal(-1, s)
1545
1546    call assert_equal({}, g:Xgetlist({'abc':1}))
1547
1548    if a:cchar == 'l'
1549	call assert_equal({}, getloclist(99, ['title']))
1550    endif
1551endfunction
1552
1553function Test_qf_property()
1554    call Xproperty_tests('c')
1555    call Xproperty_tests('l')
1556endfunction
1557
1558" Tests for the QuickFixCmdPre/QuickFixCmdPost autocommands
1559function QfAutoCmdHandler(loc, cmd)
1560  call add(g:acmds, a:loc . a:cmd)
1561endfunction
1562
1563function Test_Autocmd()
1564  autocmd QuickFixCmdPre * call QfAutoCmdHandler('pre', expand('<amatch>'))
1565  autocmd QuickFixCmdPost * call QfAutoCmdHandler('post', expand('<amatch>'))
1566
1567  let g:acmds = []
1568  cexpr "F1:10:Line 10"
1569  caddexpr "F1:20:Line 20"
1570  cgetexpr "F1:30:Line 30"
1571  enew! | call append(0, "F2:10:Line 10")
1572  cbuffer!
1573  enew! | call append(0, "F2:20:Line 20")
1574  cgetbuffer
1575  enew! | call append(0, "F2:30:Line 30")
1576  caddbuffer
1577
1578  let l = ['precexpr',
1579	      \ 'postcexpr',
1580	      \ 'precaddexpr',
1581	      \ 'postcaddexpr',
1582	      \ 'precgetexpr',
1583	      \ 'postcgetexpr',
1584	      \ 'precbuffer',
1585	      \ 'postcbuffer',
1586	      \ 'precgetbuffer',
1587	      \ 'postcgetbuffer',
1588	      \ 'precaddbuffer',
1589	      \ 'postcaddbuffer']
1590  call assert_equal(l, g:acmds)
1591endfunction
1592