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  call s:test_xhelpgrep('l')
411endfunc
412
413func Test_errortitle()
414  augroup QfBufWinEnter
415    au!
416    au BufWinEnter * :let g:a=get(w:, 'quickfix_title', 'NONE')
417  augroup END
418  copen
419  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'')'}]
420  call setqflist(a)
421  call assert_equal(':setqflist()', g:a)
422  augroup QfBufWinEnter
423    au!
424  augroup END
425  augroup! QfBufWinEnter
426endfunc
427
428func Test_vimgreptitle()
429  augroup QfBufWinEnter
430    au!
431    au BufWinEnter * :let g:a=get(w:, 'quickfix_title', 'NONE')
432  augroup END
433  try
434    vimgrep /pattern/j file
435  catch /E480/
436  endtry
437  copen
438  call assert_equal(':    vimgrep /pattern/j file', g:a)
439  augroup QfBufWinEnter
440    au!
441  augroup END
442  augroup! QfBufWinEnter
443endfunc
444
445function XqfTitleTests(cchar)
446  call s:setup_commands(a:cchar)
447
448  Xgetexpr ['file:1:1:message']
449  let l = g:Xgetlist()
450  if a:cchar == 'c'
451    call setqflist(l, 'r')
452  else
453    call setloclist(0, l, 'r')
454  endif
455
456  Xopen
457  if a:cchar == 'c'
458    let title = ':setqflist()'
459  else
460    let title = ':setloclist()'
461  endif
462  call assert_equal(title, w:quickfix_title)
463  Xclose
464endfunction
465
466" Tests for quickfix window's title
467function Test_qf_title()
468  call XqfTitleTests('c')
469  call XqfTitleTests('l')
470endfunction
471
472" Tests for 'errorformat'
473function Test_efm()
474  let save_efm = &efm
475  set efm=%EEEE%m,%WWWW%m,%+CCCC%.%#,%-GGGG%.%#
476  cgetexpr ['WWWW', 'EEEE', 'CCCC']
477  let l = strtrans(string(map(getqflist(), '[v:val.text, v:val.valid]')))
478  call assert_equal("[['W', 1], ['E^@CCCC', 1]]", l)
479  cgetexpr ['WWWW', 'GGGG', 'EEEE', 'CCCC']
480  let l = strtrans(string(map(getqflist(), '[v:val.text, v:val.valid]')))
481  call assert_equal("[['W', 1], ['E^@CCCC', 1]]", l)
482  cgetexpr ['WWWW', 'GGGG', 'ZZZZ', 'EEEE', 'CCCC', 'YYYY']
483  let l = strtrans(string(map(getqflist(), '[v:val.text, v:val.valid]')))
484  call assert_equal("[['W', 1], ['ZZZZ', 0], ['E^@CCCC', 1], ['YYYY', 0]]", l)
485  let &efm = save_efm
486endfunction
487
488" This will test for problems in quickfix:
489" A. incorrectly copying location lists which caused the location list to show
490"    a different name than the file that was actually being displayed.
491" B. not reusing the window for which the location list window is opened but
492"    instead creating new windows.
493" C. make sure that the location list window is not reused instead of the
494"    window it belongs to.
495"
496" Set up the test environment:
497function! ReadTestProtocol(name)
498  let base = substitute(a:name, '\v^test://(.*)%(\.[^.]+)?', '\1', '')
499  let word = substitute(base, '\v(.*)\..*', '\1', '')
500
501  setl modifiable
502  setl noreadonly
503  setl noswapfile
504  setl bufhidden=delete
505  %del _
506  " For problem 2:
507  " 'buftype' has to be set to reproduce the constant opening of new windows
508  setl buftype=nofile
509
510  call setline(1, word)
511
512  setl nomodified
513  setl nomodifiable
514  setl readonly
515  exe 'doautocmd BufRead ' . substitute(a:name, '\v^test://(.*)', '\1', '')
516endfunction
517
518function Test_locationlist()
519    enew
520
521    augroup testgroup
522      au!
523      autocmd BufReadCmd test://* call ReadTestProtocol(expand("<amatch>"))
524    augroup END
525
526    let words = [ "foo", "bar", "baz", "quux", "shmoo", "spam", "eggs" ]
527
528    let qflist = []
529    for word in words
530      call add(qflist, {'filename': 'test://' . word . '.txt', 'text': 'file ' . word . '.txt', })
531      " NOTE: problem 1:
532      " intentionally not setting 'lnum' so that the quickfix entries are not
533      " valid
534      call setloclist(0, qflist, ' ')
535    endfor
536
537    " Test A
538    lrewind
539    enew
540    lopen
541    lnext
542    lnext
543    lnext
544    lnext
545    vert split
546    wincmd L
547    lopen
548    wincmd p
549    lnext
550    let fileName = expand("%")
551    wincmd p
552    let locationListFileName = substitute(getline(line('.')), '\([^|]*\)|.*', '\1', '')
553    let fileName = substitute(fileName, '\\', '/', 'g')
554    let locationListFileName = substitute(locationListFileName, '\\', '/', 'g')
555    call assert_equal("test://bar.txt", fileName)
556    call assert_equal("test://bar.txt", locationListFileName)
557
558    wincmd n | only
559
560    " Test B:
561    lrewind
562    lopen
563    2
564    exe "normal \<CR>"
565    wincmd p
566    3
567    exe "normal \<CR>"
568    wincmd p
569    4
570    exe "normal \<CR>"
571    call assert_equal(2, winnr('$'))
572    wincmd n | only
573
574    " Test C:
575    lrewind
576    lopen
577    " Let's move the location list window to the top to check whether it (the
578    " first window found) will be reused when we try to open new windows:
579    wincmd K
580    2
581    exe "normal \<CR>"
582    wincmd p
583    3
584    exe "normal \<CR>"
585    wincmd p
586    4
587    exe "normal \<CR>"
588    1wincmd w
589    call assert_equal('quickfix', &buftype)
590    2wincmd w
591    let bufferName = expand("%")
592    let bufferName = substitute(bufferName, '\\', '/', 'g')
593    call assert_equal('test://quux.txt', bufferName)
594
595    wincmd n | only
596
597    augroup! testgroup
598endfunction
599
600function Test_locationlist_curwin_was_closed()
601    augroup testgroup
602      au!
603      autocmd BufReadCmd test_curwin.txt call R(expand("<amatch>"))
604    augroup END
605
606    function! R(n)
607      quit
608    endfunc
609
610    new
611    let q = []
612    call add(q, {'filename': 'test_curwin.txt' })
613    call setloclist(0, q)
614    call assert_fails('lrewind', 'E924:')
615
616    augroup! testgroup
617endfunction
618
619" More tests for 'errorformat'
620function! Test_efm1()
621    if !has('unix')
622	" The 'errorformat' setting is different on non-Unix systems.
623	" This test works only on Unix-like systems.
624	return
625    endif
626
627    let l = [
628      \ '"Xtestfile", line 4.12: 1506-045 (S) Undeclared identifier fd_set.',
629      \ '"Xtestfile", line 6 col 19; this is an error',
630      \ 'gcc -c -DHAVE_CONFIsing-prototypes -I/usr/X11R6/include  version.c',
631      \ 'Xtestfile:9: parse error before `asd''',
632      \ 'make: *** [vim] Error 1',
633      \ 'in file "Xtestfile" linenr 10: there is an error',
634      \ '',
635      \ '2 returned',
636      \ '"Xtestfile", line 11 col 1; this is an error',
637      \ '"Xtestfile", line 12 col 2; this is another error',
638      \ '"Xtestfile", line 14:10; this is an error in column 10',
639      \ '=Xtestfile=, line 15:10; this is another error, but in vcol 10 this time',
640      \ '"Xtestfile", linenr 16: yet another problem',
641      \ 'Error in "Xtestfile" at line 17:',
642      \ 'x should be a dot',
643      \ '	xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx    line 17',
644      \ '            ^',
645      \ 'Error in "Xtestfile" at line 18:',
646      \ 'x should be a dot',
647      \ '	xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx    line 18',
648      \ '.............^',
649      \ 'Error in "Xtestfile" at line 19:',
650      \ 'x should be a dot',
651      \ '	xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx    line 19',
652      \ '--------------^',
653      \ 'Error in "Xtestfile" at line 20:',
654      \ 'x should be a dot',
655      \ '	xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx    line 20',
656      \ '	       ^',
657      \ '',
658      \ 'Does anyone know what is the problem and how to correction it?',
659      \ '"Xtestfile", line 21 col 9: What is the title of the quickfix window?',
660      \ '"Xtestfile", line 22 col 9: What is the title of the quickfix window?'
661      \ ]
662
663    call writefile(l, 'Xerrorfile1')
664    call writefile(l[:-2], 'Xerrorfile2')
665
666    let m = [
667	\ '	xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx    line  2',
668	\ '	xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx    line  3',
669	\ '	xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx    line  4',
670	\ '	xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx    line  5',
671	\ '	xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx    line  6',
672	\ '	xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx    line  7',
673	\ '	xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx    line  8',
674	\ '	xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx    line  9',
675	\ '	xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx    line 10',
676	\ '	xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx    line 11',
677	\ '	xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx    line 12',
678	\ '	xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx    line 13',
679	\ '	xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx    line 14',
680	\ '	xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx    line 15',
681	\ '	xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx    line 16',
682	\ '	xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx    line 17',
683	\ '	xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx    line 18',
684	\ '	xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx    line 19',
685	\ '	xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx    line 20',
686	\ '	xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx    line 21',
687	\ '	xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx    line 22'
688	\ ]
689    call writefile(m, 'Xtestfile')
690
691    let save_efm = &efm
692    set efm+==%f=\\,\ line\ %l%*\\D%v%*[^\ ]\ %m
693    set efm^=%AError\ in\ \"%f\"\ at\ line\ %l:,%Z%p^,%C%m
694
695    exe 'cf Xerrorfile2'
696    clast
697    copen
698    call assert_equal(':cf Xerrorfile2', w:quickfix_title)
699    wincmd p
700
701    exe 'cf Xerrorfile1'
702    call assert_equal([4, 12], [line('.'), col('.')])
703    cn
704    call assert_equal([6, 19], [line('.'), col('.')])
705    cn
706    call assert_equal([9, 2], [line('.'), col('.')])
707    cn
708    call assert_equal([10, 2], [line('.'), col('.')])
709    cn
710    call assert_equal([11, 1], [line('.'), col('.')])
711    cn
712    call assert_equal([12, 2], [line('.'), col('.')])
713    cn
714    call assert_equal([14, 10], [line('.'), col('.')])
715    cn
716    call assert_equal([15, 3, 10], [line('.'), col('.'), virtcol('.')])
717    cn
718    call assert_equal([16, 2], [line('.'), col('.')])
719    cn
720    call assert_equal([17, 6], [line('.'), col('.')])
721    cn
722    call assert_equal([18, 7], [line('.'), col('.')])
723    cn
724    call assert_equal([19, 8], [line('.'), col('.')])
725    cn
726    call assert_equal([20, 9], [line('.'), col('.')])
727    clast
728    cprev
729    cprev
730    wincmd w
731    call assert_equal(':cf Xerrorfile1', w:quickfix_title)
732    wincmd p
733
734    let &efm = save_efm
735    call delete('Xerrorfile1')
736    call delete('Xerrorfile2')
737    call delete('Xtestfile')
738endfunction
739
740" Test for quickfix directory stack support
741function! s:dir_stack_tests(cchar)
742  call s:setup_commands(a:cchar)
743
744  let save_efm=&efm
745  set efm=%DEntering\ dir\ '%f',%f:%l:%m,%XLeaving\ dir\ '%f'
746
747  let lines = ["Entering dir 'dir1/a'",
748		\ 'habits2.txt:1:Nine Healthy Habits',
749		\ "Entering dir 'b'",
750		\ 'habits3.txt:2:0 Hours of television',
751		\ 'habits2.txt:7:5 Small meals',
752		\ "Entering dir 'dir1/c'",
753		\ 'habits4.txt:3:1 Hour of exercise',
754		\ "Leaving dir 'dir1/c'",
755		\ "Leaving dir 'dir1/a'",
756		\ 'habits1.txt:4:2 Liters of water',
757		\ "Entering dir 'dir2'",
758		\ 'habits5.txt:5:3 Cups of hot green tea',
759		\ "Leaving dir 'dir2'"
760		\]
761
762  Xexpr ""
763  for l in lines
764      Xaddexpr l
765  endfor
766
767  let qf = g:Xgetlist()
768
769  call assert_equal('dir1/a/habits2.txt', bufname(qf[1].bufnr))
770  call assert_equal(1, qf[1].lnum)
771  call assert_equal('dir1/a/b/habits3.txt', bufname(qf[3].bufnr))
772  call assert_equal(2, qf[3].lnum)
773  call assert_equal('dir1/a/habits2.txt', bufname(qf[4].bufnr))
774  call assert_equal(7, qf[4].lnum)
775  call assert_equal('dir1/c/habits4.txt', bufname(qf[6].bufnr))
776  call assert_equal(3, qf[6].lnum)
777  call assert_equal('habits1.txt', bufname(qf[9].bufnr))
778  call assert_equal(4, qf[9].lnum)
779  call assert_equal('dir2/habits5.txt', bufname(qf[11].bufnr))
780  call assert_equal(5, qf[11].lnum)
781
782  let &efm=save_efm
783endfunction
784
785" Tests for %D and %X errorformat options
786function! Test_efm_dirstack()
787  " Create the directory stack and files
788  call mkdir('dir1')
789  call mkdir('dir1/a')
790  call mkdir('dir1/a/b')
791  call mkdir('dir1/c')
792  call mkdir('dir2')
793
794  let lines = ["Nine Healthy Habits",
795		\ "0 Hours of television",
796		\ "1 Hour of exercise",
797		\ "2 Liters of water",
798		\ "3 Cups of hot green tea",
799		\ "4 Short mental breaks",
800		\ "5 Small meals",
801		\ "6 AM wake up time",
802		\ "7 Minutes of laughter",
803		\ "8 Hours of sleep (at least)",
804		\ "9 PM end of the day and off to bed"
805		\ ]
806  call writefile(lines, 'habits1.txt')
807  call writefile(lines, 'dir1/a/habits2.txt')
808  call writefile(lines, 'dir1/a/b/habits3.txt')
809  call writefile(lines, 'dir1/c/habits4.txt')
810  call writefile(lines, 'dir2/habits5.txt')
811
812  call s:dir_stack_tests('c')
813  call s:dir_stack_tests('l')
814
815  call delete('dir1', 'rf')
816  call delete('dir2', 'rf')
817  call delete('habits1.txt')
818endfunction
819
820" Tests for invalid error format specifies
821function Xinvalid_efm_Tests(cchar)
822  call s:setup_commands(a:cchar)
823
824  let save_efm = &efm
825
826  set efm=%f:%l:%m,%f:%f:%l:%m
827  call assert_fails('Xexpr "abc.txt:1:Hello world"', 'E372:')
828
829  set efm=%f:%l:%m,%f:%l:%r:%m
830  call assert_fails('Xexpr "abc.txt:1:Hello world"', 'E373:')
831
832  set efm=%f:%l:%m,%O:%f:%l:%m
833  call assert_fails('Xexpr "abc.txt:1:Hello world"', 'E373:')
834
835  set efm=%f:%l:%m,%f:%l:%*[^a-z
836  call assert_fails('Xexpr "abc.txt:1:Hello world"', 'E374:')
837
838  set efm=%f:%l:%m,%f:%l:%*c
839  call assert_fails('Xexpr "abc.txt:1:Hello world"', 'E375:')
840
841  set efm=%f:%l:%m,%L%M%N
842  call assert_fails('Xexpr "abc.txt:1:Hello world"', 'E376:')
843
844  set efm=%f:%l:%m,%f:%l:%m:%R
845  call assert_fails('Xexpr "abc.txt:1:Hello world"', 'E377:')
846
847  set efm=
848  call assert_fails('Xexpr "abc.txt:1:Hello world"', 'E378:')
849
850  set efm=%DEntering\ dir\ abc,%f:%l:%m
851  call assert_fails('Xexpr ["Entering dir abc", "abc.txt:1:Hello world"]', 'E379:')
852
853  let &efm = save_efm
854endfunction
855
856function Test_invalid_efm()
857  call Xinvalid_efm_Tests('c')
858  call Xinvalid_efm_Tests('l')
859endfunction
860
861" TODO:
862" Add tests for the following formats in 'errorformat'
863"	%r  %O
864function! Test_efm2()
865  let save_efm = &efm
866
867  " Test for %s format in efm
868  set efm=%f:%s
869  cexpr 'Xtestfile:Line search text'
870  let l = getqflist()
871  call assert_equal(l[0].pattern, '^\VLine search text\$')
872  call assert_equal(l[0].lnum, 0)
873
874  " Test for %P, %Q and %t format specifiers
875  let lines=["[Xtestfile1]",
876	      \ "(1,17)  error: ';' missing",
877	      \ "(21,2)  warning: variable 'z' not defined",
878	      \ "(67,3)  error: end of file found before string ended",
879	      \ "",
880	      \ "[Xtestfile2]",
881	      \ "",
882	      \ "[Xtestfile3]",
883	      \ "NEW compiler v1.1",
884	      \ "(2,2)   warning: variable 'x' not defined",
885	      \ "(67,3)  warning: 's' already defined"
886	      \]
887  set efm=%+P[%f],(%l\\,%c)%*[\ ]%t%*[^:]:\ %m,%-Q
888  cexpr ""
889  for l in lines
890      caddexpr l
891  endfor
892  let l = getqflist()
893  call assert_equal(9, len(l))
894  call assert_equal(21, l[2].lnum)
895  call assert_equal(2, l[2].col)
896  call assert_equal('w', l[2].type)
897  call assert_equal('e', l[3].type)
898
899  " Tests for %E, %C and %Z format specifiers
900  let lines = ["Error 275",
901	      \ "line 42",
902	      \ "column 3",
903	      \ "' ' expected after '--'"
904	      \]
905  set efm=%EError\ %n,%Cline\ %l,%Ccolumn\ %c,%Z%m
906  cgetexpr lines
907  let l = getqflist()
908  call assert_equal(275, l[0].nr)
909  call assert_equal(42, l[0].lnum)
910  call assert_equal(3, l[0].col)
911  call assert_equal('E', l[0].type)
912  call assert_equal("\n' ' expected after '--'", l[0].text)
913
914  " Test for %>
915  let lines = ["Error in line 147 of foo.c:",
916	      \"unknown variable 'i'"
917	      \]
918  set efm=unknown\ variable\ %m,%E%>Error\ in\ line\ %l\ of\ %f:,%Z%m
919  cgetexpr lines
920  let l = getqflist()
921  call assert_equal(147, l[0].lnum)
922  call assert_equal('E', l[0].type)
923  call assert_equal("\nunknown variable 'i'", l[0].text)
924
925  " Test for %A, %C and other formats
926  let lines = [
927	  \"==============================================================",
928	  \"FAIL: testGetTypeIdCachesResult (dbfacadeTest.DjsDBFacadeTest)",
929	  \"--------------------------------------------------------------",
930	  \"Traceback (most recent call last):",
931	  \'  File "unittests/dbfacadeTest.py", line 89, in testFoo',
932	  \"    self.assertEquals(34, dtid)",
933	  \'  File "/usr/lib/python2.2/unittest.py", line 286, in',
934	  \" failUnlessEqual",
935	  \"    raise self.failureException, \\",
936	  \"AssertionError: 34 != 33",
937	  \"",
938	  \"--------------------------------------------------------------",
939	  \"Ran 27 tests in 0.063s"
940	  \]
941  set efm=%C\ %.%#,%A\ \ File\ \"%f\"\\,\ line\ %l%.%#,%Z%[%^\ ]%\\@=%m
942  cgetexpr lines
943  let l = getqflist()
944  call assert_equal(8, len(l))
945  call assert_equal(89, l[4].lnum)
946  call assert_equal(1, l[4].valid)
947  call assert_equal('unittests/dbfacadeTest.py', bufname(l[4].bufnr))
948
949  let &efm = save_efm
950endfunction
951
952function XquickfixChangedByAutocmd(cchar)
953  call s:setup_commands(a:cchar)
954  if a:cchar == 'c'
955    let ErrorNr = 'E925'
956    function! ReadFunc()
957      colder
958      cgetexpr []
959    endfunc
960  else
961    let ErrorNr = 'E926'
962    function! ReadFunc()
963      lolder
964      lgetexpr []
965    endfunc
966  endif
967
968  augroup testgroup
969    au!
970    autocmd BufReadCmd test_changed.txt call ReadFunc()
971  augroup END
972
973  new | only
974  let words = [ "a", "b" ]
975  let qflist = []
976  for word in words
977    call add(qflist, {'filename': 'test_changed.txt'})
978    call g:Xsetlist(qflist, ' ')
979  endfor
980  call assert_fails('Xrewind', ErrorNr . ':')
981
982  augroup! testgroup
983endfunc
984
985function Test_quickfix_was_changed_by_autocmd()
986  call XquickfixChangedByAutocmd('c')
987  call XquickfixChangedByAutocmd('l')
988endfunction
989
990func Test_caddbuffer_to_empty()
991  helpgr quickfix
992  call setqflist([], 'r')
993  cad
994  try
995    cn
996  catch
997    " number of matches is unknown
998    call assert_true(v:exception =~ 'E553:')
999  endtry
1000  quit!
1001endfunc
1002
1003func Test_cgetexpr_works()
1004  " this must not crash Vim
1005  cgetexpr [$x]
1006  lgetexpr [$x]
1007endfunc
1008
1009" Tests for the setqflist() and setloclist() functions
1010function SetXlistTests(cchar, bnum)
1011  call s:setup_commands(a:cchar)
1012
1013  call g:Xsetlist([{'bufnr': a:bnum, 'lnum': 1},
1014	      \  {'bufnr': a:bnum, 'lnum': 2}])
1015  let l = g:Xgetlist()
1016  call assert_equal(2, len(l))
1017  call assert_equal(2, l[1].lnum)
1018
1019  Xnext
1020  call g:Xsetlist([{'bufnr': a:bnum, 'lnum': 3}], 'a')
1021  let l = g:Xgetlist()
1022  call assert_equal(3, len(l))
1023  Xnext
1024  call assert_equal(3, line('.'))
1025
1026  " Appending entries to the list should not change the cursor position
1027  " in the quickfix window
1028  Xwindow
1029  1
1030  call g:Xsetlist([{'bufnr': a:bnum, 'lnum': 4},
1031	      \  {'bufnr': a:bnum, 'lnum': 5}], 'a')
1032  call assert_equal(1, line('.'))
1033  close
1034
1035  call g:Xsetlist([{'bufnr': a:bnum, 'lnum': 3},
1036	      \  {'bufnr': a:bnum, 'lnum': 4},
1037	      \  {'bufnr': a:bnum, 'lnum': 5}], 'r')
1038  let l = g:Xgetlist()
1039  call assert_equal(3, len(l))
1040  call assert_equal(5, l[2].lnum)
1041
1042  call g:Xsetlist([])
1043  let l = g:Xgetlist()
1044  call assert_equal(0, len(l))
1045endfunction
1046
1047function Test_setqflist()
1048  new Xtestfile | only
1049  let bnum = bufnr('%')
1050  call setline(1, range(1,5))
1051
1052  call SetXlistTests('c', bnum)
1053  call SetXlistTests('l', bnum)
1054
1055  enew!
1056  call delete('Xtestfile')
1057endfunction
1058
1059function Xlist_empty_middle(cchar)
1060  call s:setup_commands(a:cchar)
1061
1062  " create three quickfix lists
1063  Xvimgrep Test_ test_quickfix.vim
1064  let testlen = len(g:Xgetlist())
1065  call assert_true(testlen > 0)
1066  Xvimgrep empty test_quickfix.vim
1067  call assert_true(len(g:Xgetlist()) > 0)
1068  Xvimgrep matches test_quickfix.vim
1069  let matchlen = len(g:Xgetlist())
1070  call assert_true(matchlen > 0)
1071  Xolder
1072  " make the middle list empty
1073  call g:Xsetlist([], 'r')
1074  call assert_true(len(g:Xgetlist()) == 0)
1075  Xolder
1076  call assert_equal(testlen, len(g:Xgetlist()))
1077  Xnewer
1078  Xnewer
1079  call assert_equal(matchlen, len(g:Xgetlist()))
1080endfunc
1081
1082function Test_setqflist_empty_middle()
1083  call Xlist_empty_middle('c')
1084  call Xlist_empty_middle('l')
1085endfunction
1086
1087function Xlist_empty_older(cchar)
1088  call s:setup_commands(a:cchar)
1089
1090  " create three quickfix lists
1091  Xvimgrep one test_quickfix.vim
1092  let onelen = len(g:Xgetlist())
1093  call assert_true(onelen > 0)
1094  Xvimgrep two test_quickfix.vim
1095  let twolen = len(g:Xgetlist())
1096  call assert_true(twolen > 0)
1097  Xvimgrep three test_quickfix.vim
1098  let threelen = len(g:Xgetlist())
1099  call assert_true(threelen > 0)
1100  Xolder 2
1101  " make the first list empty, check the others didn't change
1102  call g:Xsetlist([], 'r')
1103  call assert_true(len(g:Xgetlist()) == 0)
1104  Xnewer
1105  call assert_equal(twolen, len(g:Xgetlist()))
1106  Xnewer
1107  call assert_equal(threelen, len(g:Xgetlist()))
1108endfunction
1109
1110function Test_setqflist_empty_older()
1111  call Xlist_empty_older('c')
1112  call Xlist_empty_older('l')
1113endfunction
1114
1115function! XquickfixSetListWithAct(cchar)
1116  call s:setup_commands(a:cchar)
1117
1118  let list1 = [{'filename': 'fnameA', 'text': 'A'},
1119          \    {'filename': 'fnameB', 'text': 'B'}]
1120  let list2 = [{'filename': 'fnameC', 'text': 'C'},
1121          \    {'filename': 'fnameD', 'text': 'D'},
1122          \    {'filename': 'fnameE', 'text': 'E'}]
1123
1124  " {action} is unspecified.  Same as specifing ' '.
1125  new | only
1126  silent! Xnewer 99
1127  call g:Xsetlist(list1)
1128  call g:Xsetlist(list2)
1129  let li = g:Xgetlist()
1130  call assert_equal(3, len(li))
1131  call assert_equal('C', li[0]['text'])
1132  call assert_equal('D', li[1]['text'])
1133  call assert_equal('E', li[2]['text'])
1134  silent! Xolder
1135  let li = g:Xgetlist()
1136  call assert_equal(2, len(li))
1137  call assert_equal('A', li[0]['text'])
1138  call assert_equal('B', li[1]['text'])
1139
1140  " {action} is specified ' '.
1141  new | only
1142  silent! Xnewer 99
1143  call g:Xsetlist(list1)
1144  call g:Xsetlist(list2, ' ')
1145  let li = g:Xgetlist()
1146  call assert_equal(3, len(li))
1147  call assert_equal('C', li[0]['text'])
1148  call assert_equal('D', li[1]['text'])
1149  call assert_equal('E', li[2]['text'])
1150  silent! Xolder
1151  let li = g:Xgetlist()
1152  call assert_equal(2, len(li))
1153  call assert_equal('A', li[0]['text'])
1154  call assert_equal('B', li[1]['text'])
1155
1156  " {action} is specified 'a'.
1157  new | only
1158  silent! Xnewer 99
1159  call g:Xsetlist(list1)
1160  call g:Xsetlist(list2, 'a')
1161  let li = g:Xgetlist()
1162  call assert_equal(5, len(li))
1163  call assert_equal('A', li[0]['text'])
1164  call assert_equal('B', li[1]['text'])
1165  call assert_equal('C', li[2]['text'])
1166  call assert_equal('D', li[3]['text'])
1167  call assert_equal('E', li[4]['text'])
1168
1169  " {action} is specified 'r'.
1170  new | only
1171  silent! Xnewer 99
1172  call g:Xsetlist(list1)
1173  call g:Xsetlist(list2, 'r')
1174  let li = g:Xgetlist()
1175  call assert_equal(3, len(li))
1176  call assert_equal('C', li[0]['text'])
1177  call assert_equal('D', li[1]['text'])
1178  call assert_equal('E', li[2]['text'])
1179
1180  " Test for wrong value.
1181  new | only
1182  call assert_fails("call g:Xsetlist(0)", 'E714:')
1183  call assert_fails("call g:Xsetlist(list1, '')", 'E927:')
1184  call assert_fails("call g:Xsetlist(list1, 'aa')", 'E927:')
1185  call assert_fails("call g:Xsetlist(list1, ' a')", 'E927:')
1186  call assert_fails("call g:Xsetlist(list1, 0)", 'E928:')
1187endfunc
1188
1189function Test_quickfix_set_list_with_act()
1190  call XquickfixSetListWithAct('c')
1191  call XquickfixSetListWithAct('l')
1192endfunction
1193
1194function XLongLinesTests(cchar)
1195  let l = g:Xgetlist()
1196
1197  call assert_equal(4, len(l))
1198  call assert_equal(1, l[0].lnum)
1199  call assert_equal(1, l[0].col)
1200  call assert_equal(1975, len(l[0].text))
1201  call assert_equal(2, l[1].lnum)
1202  call assert_equal(1, l[1].col)
1203  call assert_equal(4070, len(l[1].text))
1204  call assert_equal(3, l[2].lnum)
1205  call assert_equal(1, l[2].col)
1206  call assert_equal(4070, len(l[2].text))
1207  call assert_equal(4, l[3].lnum)
1208  call assert_equal(1, l[3].col)
1209  call assert_equal(10, len(l[3].text))
1210
1211  call g:Xsetlist([], 'r')
1212endfunction
1213
1214function s:long_lines_tests(cchar)
1215  call s:setup_commands(a:cchar)
1216
1217  let testfile = 'samples/quickfix.txt'
1218
1219  " file
1220  exe 'Xgetfile' testfile
1221  call XLongLinesTests(a:cchar)
1222
1223  " list
1224  Xexpr readfile(testfile)
1225  call XLongLinesTests(a:cchar)
1226
1227  " string
1228  Xexpr join(readfile(testfile), "\n")
1229  call XLongLinesTests(a:cchar)
1230
1231  " buffer
1232  exe 'edit' testfile
1233  exe 'Xbuffer' bufnr('%')
1234  call XLongLinesTests(a:cchar)
1235endfunction
1236
1237function Test_long_lines()
1238  call s:long_lines_tests('c')
1239  call s:long_lines_tests('l')
1240endfunction
1241
1242function! s:create_test_file(filename)
1243  let l = []
1244  for i in range(1, 20)
1245      call add(l, 'Line' . i)
1246  endfor
1247  call writefile(l, a:filename)
1248endfunction
1249
1250function! Test_switchbuf()
1251  call s:create_test_file('Xqftestfile1')
1252  call s:create_test_file('Xqftestfile2')
1253  call s:create_test_file('Xqftestfile3')
1254
1255  new | only
1256  edit Xqftestfile1
1257  let file1_winid = win_getid()
1258  new Xqftestfile2
1259  let file2_winid = win_getid()
1260  cgetexpr ['Xqftestfile1:5:Line5',
1261		\ 'Xqftestfile1:6:Line6',
1262		\ 'Xqftestfile2:10:Line10',
1263		\ 'Xqftestfile2:11:Line11',
1264		\ 'Xqftestfile3:15:Line15',
1265		\ 'Xqftestfile3:16:Line16']
1266
1267  new
1268  let winid = win_getid()
1269  cfirst | cnext
1270  call assert_equal(winid, win_getid())
1271  cnext | cnext
1272  call assert_equal(winid, win_getid())
1273  cnext | cnext
1274  call assert_equal(winid, win_getid())
1275  enew
1276
1277  set switchbuf=useopen
1278  cfirst | cnext
1279  call assert_equal(file1_winid, win_getid())
1280  cnext | cnext
1281  call assert_equal(file2_winid, win_getid())
1282  cnext | cnext
1283  call assert_equal(file2_winid, win_getid())
1284
1285  enew | only
1286  set switchbuf=usetab
1287  tabedit Xqftestfile1
1288  tabedit Xqftestfile2
1289  tabfirst
1290  cfirst | cnext
1291  call assert_equal(2, tabpagenr())
1292  cnext | cnext
1293  call assert_equal(3, tabpagenr())
1294  cnext | cnext
1295  call assert_equal(3, tabpagenr())
1296  tabfirst | tabonly | enew
1297
1298  set switchbuf=split
1299  cfirst | cnext
1300  call assert_equal(1, winnr('$'))
1301  cnext | cnext
1302  call assert_equal(2, winnr('$'))
1303  cnext | cnext
1304  call assert_equal(3, winnr('$'))
1305  enew | only
1306
1307  set switchbuf=newtab
1308  cfirst | cnext
1309  call assert_equal(1, tabpagenr('$'))
1310  cnext | cnext
1311  call assert_equal(2, tabpagenr('$'))
1312  cnext | cnext
1313  call assert_equal(3, tabpagenr('$'))
1314  tabfirst | enew | tabonly | only
1315
1316  set switchbuf=
1317  edit Xqftestfile1
1318  let file1_winid = win_getid()
1319  new Xqftestfile2
1320  let file2_winid = win_getid()
1321  copen
1322  exe "normal 1G\<CR>"
1323  call assert_equal(file1_winid, win_getid())
1324  copen
1325  exe "normal 3G\<CR>"
1326  call assert_equal(file2_winid, win_getid())
1327  copen | only
1328  exe "normal 5G\<CR>"
1329  call assert_equal(2, winnr('$'))
1330  call assert_equal(1, bufwinnr('Xqftestfile3'))
1331
1332  enew | only
1333
1334  call delete('Xqftestfile1')
1335  call delete('Xqftestfile2')
1336  call delete('Xqftestfile3')
1337endfunction
1338
1339function! Xadjust_qflnum(cchar)
1340  call s:setup_commands(a:cchar)
1341
1342  enew | only
1343
1344  let fname = 'Xqftestfile' . a:cchar
1345  call s:create_test_file(fname)
1346  exe 'edit ' . fname
1347
1348  Xgetexpr [fname . ':5:Line5',
1349	      \ fname . ':10:Line10',
1350	      \ fname . ':15:Line15',
1351	      \ fname . ':20:Line20']
1352
1353  6,14delete
1354  call append(6, ['Buffer', 'Window'])
1355
1356  let l = g:Xgetlist()
1357
1358  call assert_equal(5, l[0].lnum)
1359  call assert_equal(6, l[2].lnum)
1360  call assert_equal(13, l[3].lnum)
1361
1362  enew!
1363  call delete(fname)
1364endfunction
1365
1366function! Test_adjust_lnum()
1367  call setloclist(0, [])
1368  call Xadjust_qflnum('c')
1369  call setqflist([])
1370  call Xadjust_qflnum('l')
1371endfunction
1372
1373" Tests for the :grep/:lgrep and :grepadd/:lgrepadd commands
1374function! s:test_xgrep(cchar)
1375  call s:setup_commands(a:cchar)
1376
1377  " The following lines are used for the grep test. Don't remove.
1378  " Grep_Test_Text: Match 1
1379  " Grep_Test_Text: Match 2
1380  " GrepAdd_Test_Text: Match 1
1381  " GrepAdd_Test_Text: Match 2
1382  enew! | only
1383  set makeef&vim
1384  silent Xgrep Grep_Test_Text: test_quickfix.vim
1385  call assert_true(len(g:Xgetlist()) == 3)
1386  Xopen
1387  call assert_true(w:quickfix_title =~ '^:grep')
1388  Xclose
1389  enew
1390  set makeef=Temp_File_##
1391  silent Xgrepadd GrepAdd_Test_Text: test_quickfix.vim
1392  call assert_true(len(g:Xgetlist()) == 6)
1393endfunction
1394
1395function! Test_grep()
1396  if !has('unix')
1397    " The grepprg may not be set on non-Unix systems
1398    return
1399  endif
1400
1401  call s:test_xgrep('c')
1402  call s:test_xgrep('l')
1403endfunction
1404
1405function! Test_two_windows()
1406  " Use one 'errorformat' for two windows.  Add an expression to each of them,
1407  " make sure they each keep their own state.
1408  set efm=%DEntering\ dir\ '%f',%f:%l:%m,%XLeaving\ dir\ '%f'
1409  call mkdir('Xone/a', 'p')
1410  call mkdir('Xtwo/a', 'p')
1411  let lines = ['1', '2', 'one one one', '4', 'two two two', '6', '7']
1412  call writefile(lines, 'Xone/a/one.txt')
1413  call writefile(lines, 'Xtwo/a/two.txt')
1414
1415  new one
1416  let one_id = win_getid()
1417  lexpr ""
1418  new two
1419  let two_id = win_getid()
1420  lexpr ""
1421
1422  laddexpr "Entering dir 'Xtwo/a'"
1423  call win_gotoid(one_id)
1424  laddexpr "Entering dir 'Xone/a'"
1425  call win_gotoid(two_id)
1426  laddexpr 'two.txt:5:two two two'
1427  call win_gotoid(one_id)
1428  laddexpr 'one.txt:3:one one one'
1429
1430  let loc_one = getloclist(one_id)
1431echo string(loc_one)
1432  call assert_equal('Xone/a/one.txt', bufname(loc_one[1].bufnr))
1433  call assert_equal(3, loc_one[1].lnum)
1434
1435  let loc_two = getloclist(two_id)
1436echo string(loc_two)
1437  call assert_equal('Xtwo/a/two.txt', bufname(loc_two[1].bufnr))
1438  call assert_equal(5, loc_two[1].lnum)
1439
1440  call win_gotoid(one_id)
1441  bwipe!
1442  call win_gotoid(two_id)
1443  bwipe!
1444  call delete('Xone', 'rf')
1445  call delete('Xtwo', 'rf')
1446endfunc
1447
1448function XbottomTests(cchar)
1449  call s:setup_commands(a:cchar)
1450
1451  call g:Xsetlist([{'filename': 'foo', 'lnum': 42}])
1452  Xopen
1453  let wid = win_getid()
1454  call assert_equal(1, line('.'))
1455  wincmd w
1456  call g:Xsetlist([{'filename': 'var', 'lnum': 24}], 'a')
1457  Xbottom
1458  call win_gotoid(wid)
1459  call assert_equal(2, line('.'))
1460  Xclose
1461endfunc
1462
1463" Tests for the :cbottom and :lbottom commands
1464function Test_cbottom()
1465  call XbottomTests('c')
1466  call XbottomTests('l')
1467endfunction
1468
1469function HistoryTest(cchar)
1470  call s:setup_commands(a:cchar)
1471
1472  call assert_fails(a:cchar . 'older 99', 'E380:')
1473  " clear all lists after the first one, then replace the first one.
1474  call g:Xsetlist([])
1475  Xolder
1476  let entry = {'filename': 'foo', 'lnum': 42}
1477  call g:Xsetlist([entry], 'r')
1478  call g:Xsetlist([entry, entry])
1479  call g:Xsetlist([entry, entry, entry])
1480  let res = split(execute(a:cchar . 'hist'), "\n")
1481  call assert_equal(3, len(res))
1482  let common = 'errors     :set' . (a:cchar == 'c' ? 'qf' : 'loc') . 'list()'
1483  call assert_equal('  error list 1 of 3; 1 ' . common, res[0])
1484  call assert_equal('  error list 2 of 3; 2 ' . common, res[1])
1485  call assert_equal('> error list 3 of 3; 3 ' . common, res[2])
1486endfunc
1487
1488func Test_history()
1489  call HistoryTest('c')
1490  call HistoryTest('l')
1491endfunc
1492
1493func Test_duplicate_buf()
1494  " make sure we can get the highest buffer number
1495  edit DoesNotExist
1496  edit DoesNotExist2
1497  let last_buffer = bufnr("$")
1498
1499  " make sure only one buffer is created
1500  call writefile(['this one', 'that one'], 'Xgrepthis')
1501  vimgrep one Xgrepthis
1502  vimgrep one Xgrepthis
1503  call assert_equal(last_buffer + 1, bufnr("$"))
1504
1505  call delete('Xgrepthis')
1506endfunc
1507