1" Test for the quickfix commands.
2
3if !has('quickfix')
4  finish
5endif
6
7set encoding=utf-8
8
9func s:setup_commands(cchar)
10  if a:cchar == 'c'
11    command! -nargs=* -bang Xlist <mods>clist<bang> <args>
12    command! -nargs=* Xgetexpr <mods>cgetexpr <args>
13    command! -nargs=* Xaddexpr <mods>caddexpr <args>
14    command! -nargs=* Xolder <mods>colder <args>
15    command! -nargs=* Xnewer <mods>cnewer <args>
16    command! -nargs=* Xopen <mods>copen <args>
17    command! -nargs=* Xwindow <mods>cwindow <args>
18    command! -nargs=* Xbottom <mods>cbottom <args>
19    command! -nargs=* Xclose <mods>cclose <args>
20    command! -nargs=* -bang Xfile <mods>cfile<bang> <args>
21    command! -nargs=* Xgetfile <mods>cgetfile <args>
22    command! -nargs=* Xaddfile <mods>caddfile <args>
23    command! -nargs=* -bang Xbuffer <mods>cbuffer<bang> <args>
24    command! -nargs=* Xgetbuffer <mods>cgetbuffer <args>
25    command! -nargs=* Xaddbuffer <mods>caddbuffer <args>
26    command! -nargs=* Xrewind <mods>crewind <args>
27    command! -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
71endfunc
72
73" Tests for the :clist and :llist commands
74func 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)
131endfunc
132
133func Test_clist()
134  call XlistTests('c')
135  call XlistTests('l')
136endfunc
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.
141func 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)
174endfunc
175
176func 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')
183endfunc
184
185" Tests for the :cwindow, :lwindow :cclose, :lclose, :copen and :lopen
186" commands
187func 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)
230endfunc
231
232func Test_cwindow()
233  call XwindowTests('c')
234  call XwindowTests('l')
235endfunc
236
237" Tests for the :cfile, :lfile, :caddfile, :laddfile, :cgetfile and :lgetfile
238" commands.
239func 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')
278endfunc
279
280func Test_cfile()
281  call XfileTests('c')
282  call XfileTests('l')
283endfunc
284
285" Tests for the :cbuffer, :lbuffer, :caddbuffer, :laddbuffer, :cgetbuffer and
286" :lgetbuffer commands.
287func 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
319endfunc
320
321func Test_cbuffer()
322  call XbufferTests('c')
323  call XbufferTests('l')
324endfunc
325
326func XexprTests(cchar)
327  call s:setup_commands(a:cchar)
328
329  call assert_fails('Xexpr 10', 'E777:')
330endfunc
331
332func Test_cexpr()
333  call XexprTests('c')
334  call XexprTests('l')
335endfunc
336
337" Tests for :cnext, :cprev, :cfirst, :clast commands
338func 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')
369endfunc
370
371func Test_browse()
372  call Xtest_browse('c')
373  call Xtest_browse('l')
374endfunc
375
376func 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
394func 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
406endfunc
407
408func 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
446func 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
465endfunc
466
467" Tests for quickfix window's title
468func Test_qf_title()
469  call XqfTitleTests('c')
470  call XqfTitleTests('l')
471endfunc
472
473" Tests for 'errorformat'
474func 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
487endfunc
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:
498func 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', '')
517endfunc
518
519func 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
599  endfunc
600
601func 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    func! 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
618  endfunc
619
620func Test_locationlist_cross_tab_jump()
621  call writefile(['loclistfoo'], 'loclistfoo')
622  call writefile(['loclistbar'], 'loclistbar')
623  set switchbuf=usetab
624
625  edit loclistfoo
626  tabedit loclistbar
627  silent lgrep loclistfoo loclist*
628  call assert_equal(1, tabpagenr())
629
630  enew | only | tabonly
631  set switchbuf&vim
632  call delete('loclistfoo')
633  call delete('loclistbar')
634endfunc
635
636" More tests for 'errorformat'
637func Test_efm1()
638    if !has('unix')
639	" The 'errorformat' setting is different on non-Unix systems.
640	" This test works only on Unix-like systems.
641	return
642    endif
643
644    let l = [
645      \ '"Xtestfile", line 4.12: 1506-045 (S) Undeclared identifier fd_set.',
646      \ '"Xtestfile", line 6 col 19; this is an error',
647      \ 'gcc -c -DHAVE_CONFIsing-prototypes -I/usr/X11R6/include  version.c',
648      \ 'Xtestfile:9: parse error before `asd''',
649      \ 'make: *** [vim] Error 1',
650      \ 'in file "Xtestfile" linenr 10: there is an error',
651      \ '',
652      \ '2 returned',
653      \ '"Xtestfile", line 11 col 1; this is an error',
654      \ '"Xtestfile", line 12 col 2; this is another error',
655      \ '"Xtestfile", line 14:10; this is an error in column 10',
656      \ '=Xtestfile=, line 15:10; this is another error, but in vcol 10 this time',
657      \ '"Xtestfile", linenr 16: yet another problem',
658      \ 'Error in "Xtestfile" at line 17:',
659      \ 'x should be a dot',
660      \ '	xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx    line 17',
661      \ '            ^',
662      \ 'Error in "Xtestfile" at line 18:',
663      \ 'x should be a dot',
664      \ '	xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx    line 18',
665      \ '.............^',
666      \ 'Error in "Xtestfile" at line 19:',
667      \ 'x should be a dot',
668      \ '	xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx    line 19',
669      \ '--------------^',
670      \ 'Error in "Xtestfile" at line 20:',
671      \ 'x should be a dot',
672      \ '	xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx    line 20',
673      \ '	       ^',
674      \ '',
675      \ 'Does anyone know what is the problem and how to correction it?',
676      \ '"Xtestfile", line 21 col 9: What is the title of the quickfix window?',
677      \ '"Xtestfile", line 22 col 9: What is the title of the quickfix window?'
678      \ ]
679
680    call writefile(l, 'Xerrorfile1')
681    call writefile(l[:-2], 'Xerrorfile2')
682
683    let m = [
684	\ '	xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx    line  2',
685	\ '	xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx    line  3',
686	\ '	xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx    line  4',
687	\ '	xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx    line  5',
688	\ '	xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx    line  6',
689	\ '	xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx    line  7',
690	\ '	xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx    line  8',
691	\ '	xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx    line  9',
692	\ '	xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx    line 10',
693	\ '	xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx    line 11',
694	\ '	xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx    line 12',
695	\ '	xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx    line 13',
696	\ '	xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx    line 14',
697	\ '	xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx    line 15',
698	\ '	xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx    line 16',
699	\ '	xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx    line 17',
700	\ '	xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx    line 18',
701	\ '	xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx    line 19',
702	\ '	xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx    line 20',
703	\ '	xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx    line 21',
704	\ '	xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx    line 22'
705	\ ]
706    call writefile(m, 'Xtestfile')
707
708    let save_efm = &efm
709    set efm+==%f=\\,\ line\ %l%*\\D%v%*[^\ ]\ %m
710    set efm^=%AError\ in\ \"%f\"\ at\ line\ %l:,%Z%p^,%C%m
711
712    exe 'cf Xerrorfile2'
713    clast
714    copen
715    call assert_equal(':cf Xerrorfile2', w:quickfix_title)
716    wincmd p
717
718    exe 'cf Xerrorfile1'
719    call assert_equal([4, 12], [line('.'), col('.')])
720    cn
721    call assert_equal([6, 19], [line('.'), col('.')])
722    cn
723    call assert_equal([9, 2], [line('.'), col('.')])
724    cn
725    call assert_equal([10, 2], [line('.'), col('.')])
726    cn
727    call assert_equal([11, 1], [line('.'), col('.')])
728    cn
729    call assert_equal([12, 2], [line('.'), col('.')])
730    cn
731    call assert_equal([14, 10], [line('.'), col('.')])
732    cn
733    call assert_equal([15, 3, 10], [line('.'), col('.'), virtcol('.')])
734    cn
735    call assert_equal([16, 2], [line('.'), col('.')])
736    cn
737    call assert_equal([17, 6], [line('.'), col('.')])
738    cn
739    call assert_equal([18, 7], [line('.'), col('.')])
740    cn
741    call assert_equal([19, 8], [line('.'), col('.')])
742    cn
743    call assert_equal([20, 9], [line('.'), col('.')])
744    clast
745    cprev
746    cprev
747    wincmd w
748    call assert_equal(':cf Xerrorfile1', w:quickfix_title)
749    wincmd p
750
751    let &efm = save_efm
752    call delete('Xerrorfile1')
753    call delete('Xerrorfile2')
754    call delete('Xtestfile')
755  endfunc
756
757" Test for quickfix directory stack support
758func s:dir_stack_tests(cchar)
759  call s:setup_commands(a:cchar)
760
761  let save_efm=&efm
762  set efm=%DEntering\ dir\ '%f',%f:%l:%m,%XLeaving\ dir\ '%f'
763
764  let lines = ["Entering dir 'dir1/a'",
765		\ 'habits2.txt:1:Nine Healthy Habits',
766		\ "Entering dir 'b'",
767		\ 'habits3.txt:2:0 Hours of television',
768		\ 'habits2.txt:7:5 Small meals',
769		\ "Entering dir 'dir1/c'",
770		\ 'habits4.txt:3:1 Hour of exercise',
771		\ "Leaving dir 'dir1/c'",
772		\ "Leaving dir 'dir1/a'",
773		\ 'habits1.txt:4:2 Liters of water',
774		\ "Entering dir 'dir2'",
775		\ 'habits5.txt:5:3 Cups of hot green tea',
776		\ "Leaving dir 'dir2'"
777		\]
778
779  Xexpr ""
780  for l in lines
781      Xaddexpr l
782  endfor
783
784  let qf = g:Xgetlist()
785
786  call assert_equal('dir1/a/habits2.txt', bufname(qf[1].bufnr))
787  call assert_equal(1, qf[1].lnum)
788  call assert_equal('dir1/a/b/habits3.txt', bufname(qf[3].bufnr))
789  call assert_equal(2, qf[3].lnum)
790  call assert_equal('dir1/a/habits2.txt', bufname(qf[4].bufnr))
791  call assert_equal(7, qf[4].lnum)
792  call assert_equal('dir1/c/habits4.txt', bufname(qf[6].bufnr))
793  call assert_equal(3, qf[6].lnum)
794  call assert_equal('habits1.txt', bufname(qf[9].bufnr))
795  call assert_equal(4, qf[9].lnum)
796  call assert_equal('dir2/habits5.txt', bufname(qf[11].bufnr))
797  call assert_equal(5, qf[11].lnum)
798
799  let &efm=save_efm
800endfunc
801
802" Tests for %D and %X errorformat options
803func Test_efm_dirstack()
804  " Create the directory stack and files
805  call mkdir('dir1')
806  call mkdir('dir1/a')
807  call mkdir('dir1/a/b')
808  call mkdir('dir1/c')
809  call mkdir('dir2')
810
811  let lines = ["Nine Healthy Habits",
812		\ "0 Hours of television",
813		\ "1 Hour of exercise",
814		\ "2 Liters of water",
815		\ "3 Cups of hot green tea",
816		\ "4 Short mental breaks",
817		\ "5 Small meals",
818		\ "6 AM wake up time",
819		\ "7 Minutes of laughter",
820		\ "8 Hours of sleep (at least)",
821		\ "9 PM end of the day and off to bed"
822		\ ]
823  call writefile(lines, 'habits1.txt')
824  call writefile(lines, 'dir1/a/habits2.txt')
825  call writefile(lines, 'dir1/a/b/habits3.txt')
826  call writefile(lines, 'dir1/c/habits4.txt')
827  call writefile(lines, 'dir2/habits5.txt')
828
829  call s:dir_stack_tests('c')
830  call s:dir_stack_tests('l')
831
832  call delete('dir1', 'rf')
833  call delete('dir2', 'rf')
834  call delete('habits1.txt')
835endfunc
836
837" Test for resync after continuing an ignored message
838func Xefm_ignore_continuations(cchar)
839  call s:setup_commands(a:cchar)
840
841  let save_efm = &efm
842
843  let &efm =
844	\ '%Eerror %m %l,' .
845	\ '%-Wignored %m %l,' .
846	\ '%+Cmore ignored %m %l,' .
847	\ '%Zignored end'
848  Xgetexpr ['ignored warning 1', 'more ignored continuation 2', 'ignored end', 'error resync 4']
849  let l = map(g:Xgetlist(), '[v:val.text, v:val.valid, v:val.lnum, v:val.type]')
850  call assert_equal([['resync', 1, 4, 'E']], l)
851
852  let &efm = save_efm
853endfunc
854
855func Test_efm_ignore_continuations()
856  call Xefm_ignore_continuations('c')
857  call Xefm_ignore_continuations('l')
858endfunc
859
860" Tests for invalid error format specifies
861func Xinvalid_efm_Tests(cchar)
862  call s:setup_commands(a:cchar)
863
864  let save_efm = &efm
865
866  set efm=%f:%l:%m,%f:%f:%l:%m
867  call assert_fails('Xexpr "abc.txt:1:Hello world"', 'E372:')
868
869  set efm=%f:%l:%m,%f:%l:%r:%m
870  call assert_fails('Xexpr "abc.txt:1:Hello world"', 'E373:')
871
872  set efm=%f:%l:%m,%O:%f:%l:%m
873  call assert_fails('Xexpr "abc.txt:1:Hello world"', 'E373:')
874
875  set efm=%f:%l:%m,%f:%l:%*[^a-z
876  call assert_fails('Xexpr "abc.txt:1:Hello world"', 'E374:')
877
878  set efm=%f:%l:%m,%f:%l:%*c
879  call assert_fails('Xexpr "abc.txt:1:Hello world"', 'E375:')
880
881  set efm=%f:%l:%m,%L%M%N
882  call assert_fails('Xexpr "abc.txt:1:Hello world"', 'E376:')
883
884  set efm=%f:%l:%m,%f:%l:%m:%R
885  call assert_fails('Xexpr "abc.txt:1:Hello world"', 'E377:')
886
887  set efm=
888  call assert_fails('Xexpr "abc.txt:1:Hello world"', 'E378:')
889
890  set efm=%DEntering\ dir\ abc,%f:%l:%m
891  call assert_fails('Xexpr ["Entering dir abc", "abc.txt:1:Hello world"]', 'E379:')
892
893  let &efm = save_efm
894endfunc
895
896func Test_invalid_efm()
897  call Xinvalid_efm_Tests('c')
898  call Xinvalid_efm_Tests('l')
899endfunc
900
901" TODO:
902" Add tests for the following formats in 'errorformat'
903"	%r  %O
904func Test_efm2()
905  let save_efm = &efm
906
907  " Test for %s format in efm
908  set efm=%f:%s
909  cexpr 'Xtestfile:Line search text'
910  let l = getqflist()
911  call assert_equal(l[0].pattern, '^\VLine search text\$')
912  call assert_equal(l[0].lnum, 0)
913
914  " Test for %P, %Q and %t format specifiers
915  let lines=["[Xtestfile1]",
916	      \ "(1,17)  error: ';' missing",
917	      \ "(21,2)  warning: variable 'z' not defined",
918	      \ "(67,3)  error: end of file found before string ended",
919	      \ "",
920	      \ "[Xtestfile2]",
921	      \ "",
922	      \ "[Xtestfile3]",
923	      \ "NEW compiler v1.1",
924	      \ "(2,2)   warning: variable 'x' not defined",
925	      \ "(67,3)  warning: 's' already defined"
926	      \]
927  set efm=%+P[%f],(%l\\,%c)%*[\ ]%t%*[^:]:\ %m,%-Q
928  cexpr ""
929  for l in lines
930      caddexpr l
931  endfor
932  let l = getqflist()
933  call assert_equal(9, len(l))
934  call assert_equal(21, l[2].lnum)
935  call assert_equal(2, l[2].col)
936  call assert_equal('w', l[2].type)
937  call assert_equal('e', l[3].type)
938
939  " Tests for %E, %C and %Z format specifiers
940  let lines = ["Error 275",
941	      \ "line 42",
942	      \ "column 3",
943	      \ "' ' expected after '--'"
944	      \]
945  set efm=%EError\ %n,%Cline\ %l,%Ccolumn\ %c,%Z%m
946  cgetexpr lines
947  let l = getqflist()
948  call assert_equal(275, l[0].nr)
949  call assert_equal(42, l[0].lnum)
950  call assert_equal(3, l[0].col)
951  call assert_equal('E', l[0].type)
952  call assert_equal("\n' ' expected after '--'", l[0].text)
953
954  " Test for %>
955  let lines = ["Error in line 147 of foo.c:",
956	      \"unknown variable 'i'"
957	      \]
958  set efm=unknown\ variable\ %m,%E%>Error\ in\ line\ %l\ of\ %f:,%Z%m
959  cgetexpr lines
960  let l = getqflist()
961  call assert_equal(147, l[0].lnum)
962  call assert_equal('E', l[0].type)
963  call assert_equal("\nunknown variable 'i'", l[0].text)
964
965  " Test for %A, %C and other formats
966  let lines = [
967	  \"==============================================================",
968	  \"FAIL: testGetTypeIdCachesResult (dbfacadeTest.DjsDBFacadeTest)",
969	  \"--------------------------------------------------------------",
970	  \"Traceback (most recent call last):",
971	  \'  File "unittests/dbfacadeTest.py", line 89, in testFoo',
972	  \"    self.assertEquals(34, dtid)",
973	  \'  File "/usr/lib/python2.2/unittest.py", line 286, in',
974	  \" failUnlessEqual",
975	  \"    raise self.failureException, \\",
976	  \"AssertionError: 34 != 33",
977	  \"",
978	  \"--------------------------------------------------------------",
979	  \"Ran 27 tests in 0.063s"
980	  \]
981  set efm=%C\ %.%#,%A\ \ File\ \"%f\"\\,\ line\ %l%.%#,%Z%[%^\ ]%\\@=%m
982  cgetexpr lines
983  let l = getqflist()
984  call assert_equal(8, len(l))
985  call assert_equal(89, l[4].lnum)
986  call assert_equal(1, l[4].valid)
987  call assert_equal('unittests/dbfacadeTest.py', bufname(l[4].bufnr))
988
989  let &efm = save_efm
990endfunc
991
992func XquickfixChangedByAutocmd(cchar)
993  call s:setup_commands(a:cchar)
994  if a:cchar == 'c'
995    let ErrorNr = 'E925'
996    func! ReadFunc()
997      colder
998      cgetexpr []
999    endfunc
1000  else
1001    let ErrorNr = 'E926'
1002    func! ReadFunc()
1003      lolder
1004      lgetexpr []
1005    endfunc
1006  endif
1007
1008  augroup testgroup
1009    au!
1010    autocmd BufReadCmd test_changed.txt call ReadFunc()
1011  augroup END
1012
1013  new | only
1014  let words = [ "a", "b" ]
1015  let qflist = []
1016  for word in words
1017    call add(qflist, {'filename': 'test_changed.txt'})
1018    call g:Xsetlist(qflist, ' ')
1019  endfor
1020  call assert_fails('Xrewind', ErrorNr . ':')
1021
1022  augroup! testgroup
1023endfunc
1024
1025func Test_quickfix_was_changed_by_autocmd()
1026  call XquickfixChangedByAutocmd('c')
1027  call XquickfixChangedByAutocmd('l')
1028endfunc
1029
1030func Test_caddbuffer_to_empty()
1031  helpgr quickfix
1032  call setqflist([], 'r')
1033  cad
1034  try
1035    cn
1036  catch
1037    " number of matches is unknown
1038    call assert_true(v:exception =~ 'E553:')
1039  endtry
1040  quit!
1041endfunc
1042
1043func Test_cgetexpr_works()
1044  " this must not crash Vim
1045  cgetexpr [$x]
1046  lgetexpr [$x]
1047endfunc
1048
1049" Tests for the setqflist() and setloclist() functions
1050func SetXlistTests(cchar, bnum)
1051  call s:setup_commands(a:cchar)
1052
1053  call g:Xsetlist([{'bufnr': a:bnum, 'lnum': 1},
1054	      \  {'bufnr': a:bnum, 'lnum': 2}])
1055  let l = g:Xgetlist()
1056  call assert_equal(2, len(l))
1057  call assert_equal(2, l[1].lnum)
1058
1059  Xnext
1060  call g:Xsetlist([{'bufnr': a:bnum, 'lnum': 3}], 'a')
1061  let l = g:Xgetlist()
1062  call assert_equal(3, len(l))
1063  Xnext
1064  call assert_equal(3, line('.'))
1065
1066  " Appending entries to the list should not change the cursor position
1067  " in the quickfix window
1068  Xwindow
1069  1
1070  call g:Xsetlist([{'bufnr': a:bnum, 'lnum': 4},
1071	      \  {'bufnr': a:bnum, 'lnum': 5}], 'a')
1072  call assert_equal(1, line('.'))
1073  close
1074
1075  call g:Xsetlist([{'bufnr': a:bnum, 'lnum': 3},
1076	      \  {'bufnr': a:bnum, 'lnum': 4},
1077	      \  {'bufnr': a:bnum, 'lnum': 5}], 'r')
1078  let l = g:Xgetlist()
1079  call assert_equal(3, len(l))
1080  call assert_equal(5, l[2].lnum)
1081
1082  call g:Xsetlist([])
1083  let l = g:Xgetlist()
1084  call assert_equal(0, len(l))
1085endfunc
1086
1087func Test_setqflist()
1088  new Xtestfile | only
1089  let bnum = bufnr('%')
1090  call setline(1, range(1,5))
1091
1092  call SetXlistTests('c', bnum)
1093  call SetXlistTests('l', bnum)
1094
1095  enew!
1096  call delete('Xtestfile')
1097endfunc
1098
1099func Xlist_empty_middle(cchar)
1100  call s:setup_commands(a:cchar)
1101
1102  " create three quickfix lists
1103  Xvimgrep Test_ test_quickfix.vim
1104  let testlen = len(g:Xgetlist())
1105  call assert_true(testlen > 0)
1106  Xvimgrep empty test_quickfix.vim
1107  call assert_true(len(g:Xgetlist()) > 0)
1108  Xvimgrep matches test_quickfix.vim
1109  let matchlen = len(g:Xgetlist())
1110  call assert_true(matchlen > 0)
1111  Xolder
1112  " make the middle list empty
1113  call g:Xsetlist([], 'r')
1114  call assert_true(len(g:Xgetlist()) == 0)
1115  Xolder
1116  call assert_equal(testlen, len(g:Xgetlist()))
1117  Xnewer
1118  Xnewer
1119  call assert_equal(matchlen, len(g:Xgetlist()))
1120endfunc
1121
1122func Test_setqflist_empty_middle()
1123  call Xlist_empty_middle('c')
1124  call Xlist_empty_middle('l')
1125endfunc
1126
1127func Xlist_empty_older(cchar)
1128  call s:setup_commands(a:cchar)
1129
1130  " create three quickfix lists
1131  Xvimgrep one test_quickfix.vim
1132  let onelen = len(g:Xgetlist())
1133  call assert_true(onelen > 0)
1134  Xvimgrep two test_quickfix.vim
1135  let twolen = len(g:Xgetlist())
1136  call assert_true(twolen > 0)
1137  Xvimgrep three test_quickfix.vim
1138  let threelen = len(g:Xgetlist())
1139  call assert_true(threelen > 0)
1140  Xolder 2
1141  " make the first list empty, check the others didn't change
1142  call g:Xsetlist([], 'r')
1143  call assert_true(len(g:Xgetlist()) == 0)
1144  Xnewer
1145  call assert_equal(twolen, len(g:Xgetlist()))
1146  Xnewer
1147  call assert_equal(threelen, len(g:Xgetlist()))
1148endfunc
1149
1150func Test_setqflist_empty_older()
1151  call Xlist_empty_older('c')
1152  call Xlist_empty_older('l')
1153endfunc
1154
1155func XquickfixSetListWithAct(cchar)
1156  call s:setup_commands(a:cchar)
1157
1158  let list1 = [{'filename': 'fnameA', 'text': 'A'},
1159          \    {'filename': 'fnameB', 'text': 'B'}]
1160  let list2 = [{'filename': 'fnameC', 'text': 'C'},
1161          \    {'filename': 'fnameD', 'text': 'D'},
1162          \    {'filename': 'fnameE', 'text': 'E'}]
1163
1164  " {action} is unspecified.  Same as specifing ' '.
1165  new | only
1166  silent! Xnewer 99
1167  call g:Xsetlist(list1)
1168  call g:Xsetlist(list2)
1169  let li = g:Xgetlist()
1170  call assert_equal(3, len(li))
1171  call assert_equal('C', li[0]['text'])
1172  call assert_equal('D', li[1]['text'])
1173  call assert_equal('E', li[2]['text'])
1174  silent! Xolder
1175  let li = g:Xgetlist()
1176  call assert_equal(2, len(li))
1177  call assert_equal('A', li[0]['text'])
1178  call assert_equal('B', li[1]['text'])
1179
1180  " {action} is specified ' '.
1181  new | only
1182  silent! Xnewer 99
1183  call g:Xsetlist(list1)
1184  call g:Xsetlist(list2, ' ')
1185  let li = g:Xgetlist()
1186  call assert_equal(3, len(li))
1187  call assert_equal('C', li[0]['text'])
1188  call assert_equal('D', li[1]['text'])
1189  call assert_equal('E', li[2]['text'])
1190  silent! Xolder
1191  let li = g:Xgetlist()
1192  call assert_equal(2, len(li))
1193  call assert_equal('A', li[0]['text'])
1194  call assert_equal('B', li[1]['text'])
1195
1196  " {action} is specified 'a'.
1197  new | only
1198  silent! Xnewer 99
1199  call g:Xsetlist(list1)
1200  call g:Xsetlist(list2, 'a')
1201  let li = g:Xgetlist()
1202  call assert_equal(5, len(li))
1203  call assert_equal('A', li[0]['text'])
1204  call assert_equal('B', li[1]['text'])
1205  call assert_equal('C', li[2]['text'])
1206  call assert_equal('D', li[3]['text'])
1207  call assert_equal('E', li[4]['text'])
1208
1209  " {action} is specified 'r'.
1210  new | only
1211  silent! Xnewer 99
1212  call g:Xsetlist(list1)
1213  call g:Xsetlist(list2, 'r')
1214  let li = g:Xgetlist()
1215  call assert_equal(3, len(li))
1216  call assert_equal('C', li[0]['text'])
1217  call assert_equal('D', li[1]['text'])
1218  call assert_equal('E', li[2]['text'])
1219
1220  " Test for wrong value.
1221  new | only
1222  call assert_fails("call g:Xsetlist(0)", 'E714:')
1223  call assert_fails("call g:Xsetlist(list1, '')", 'E927:')
1224  call assert_fails("call g:Xsetlist(list1, 'aa')", 'E927:')
1225  call assert_fails("call g:Xsetlist(list1, ' a')", 'E927:')
1226  call assert_fails("call g:Xsetlist(list1, 0)", 'E928:')
1227endfunc
1228
1229func Test_quickfix_set_list_with_act()
1230  call XquickfixSetListWithAct('c')
1231  call XquickfixSetListWithAct('l')
1232endfunc
1233
1234func XLongLinesTests(cchar)
1235  let l = g:Xgetlist()
1236
1237  call assert_equal(4, len(l))
1238  call assert_equal(1, l[0].lnum)
1239  call assert_equal(1, l[0].col)
1240  call assert_equal(1975, len(l[0].text))
1241  call assert_equal(2, l[1].lnum)
1242  call assert_equal(1, l[1].col)
1243  call assert_equal(4070, len(l[1].text))
1244  call assert_equal(3, l[2].lnum)
1245  call assert_equal(1, l[2].col)
1246  call assert_equal(4070, len(l[2].text))
1247  call assert_equal(4, l[3].lnum)
1248  call assert_equal(1, l[3].col)
1249  call assert_equal(10, len(l[3].text))
1250
1251  call g:Xsetlist([], 'r')
1252endfunc
1253
1254func s:long_lines_tests(cchar)
1255  call s:setup_commands(a:cchar)
1256
1257  let testfile = 'samples/quickfix.txt'
1258
1259  " file
1260  exe 'Xgetfile' testfile
1261  call XLongLinesTests(a:cchar)
1262
1263  " list
1264  Xexpr readfile(testfile)
1265  call XLongLinesTests(a:cchar)
1266
1267  " string
1268  Xexpr join(readfile(testfile), "\n")
1269  call XLongLinesTests(a:cchar)
1270
1271  " buffer
1272  exe 'edit' testfile
1273  exe 'Xbuffer' bufnr('%')
1274  call XLongLinesTests(a:cchar)
1275endfunc
1276
1277func Test_long_lines()
1278  call s:long_lines_tests('c')
1279  call s:long_lines_tests('l')
1280endfunc
1281
1282func s:create_test_file(filename)
1283  let l = []
1284  for i in range(1, 20)
1285      call add(l, 'Line' . i)
1286  endfor
1287  call writefile(l, a:filename)
1288endfunc
1289
1290func Test_switchbuf()
1291  call s:create_test_file('Xqftestfile1')
1292  call s:create_test_file('Xqftestfile2')
1293  call s:create_test_file('Xqftestfile3')
1294
1295  new | only
1296  edit Xqftestfile1
1297  let file1_winid = win_getid()
1298  new Xqftestfile2
1299  let file2_winid = win_getid()
1300  cgetexpr ['Xqftestfile1:5:Line5',
1301		\ 'Xqftestfile1:6:Line6',
1302		\ 'Xqftestfile2:10:Line10',
1303		\ 'Xqftestfile2:11:Line11',
1304		\ 'Xqftestfile3:15:Line15',
1305		\ 'Xqftestfile3:16:Line16']
1306
1307  new
1308  let winid = win_getid()
1309  cfirst | cnext
1310  call assert_equal(winid, win_getid())
1311  cnext | cnext
1312  call assert_equal(winid, win_getid())
1313  cnext | cnext
1314  call assert_equal(winid, win_getid())
1315  enew
1316
1317  set switchbuf=useopen
1318  cfirst | cnext
1319  call assert_equal(file1_winid, win_getid())
1320  cnext | cnext
1321  call assert_equal(file2_winid, win_getid())
1322  cnext | cnext
1323  call assert_equal(file2_winid, win_getid())
1324
1325  enew | only
1326  set switchbuf=usetab
1327  tabedit Xqftestfile1
1328  tabedit Xqftestfile2
1329  tabfirst
1330  cfirst | cnext
1331  call assert_equal(2, tabpagenr())
1332  cnext | cnext
1333  call assert_equal(3, tabpagenr())
1334  cnext | cnext
1335  call assert_equal(3, tabpagenr())
1336  tabfirst | tabonly | enew
1337
1338  set switchbuf=split
1339  cfirst | cnext
1340  call assert_equal(1, winnr('$'))
1341  cnext | cnext
1342  call assert_equal(2, winnr('$'))
1343  cnext | cnext
1344  call assert_equal(3, winnr('$'))
1345  enew | only
1346
1347  set switchbuf=newtab
1348  cfirst | cnext
1349  call assert_equal(1, tabpagenr('$'))
1350  cnext | cnext
1351  call assert_equal(2, tabpagenr('$'))
1352  cnext | cnext
1353  call assert_equal(3, tabpagenr('$'))
1354  tabfirst | enew | tabonly | only
1355
1356  set switchbuf=
1357  edit Xqftestfile1
1358  let file1_winid = win_getid()
1359  new Xqftestfile2
1360  let file2_winid = win_getid()
1361  copen
1362  exe "normal 1G\<CR>"
1363  call assert_equal(file1_winid, win_getid())
1364  copen
1365  exe "normal 3G\<CR>"
1366  call assert_equal(file2_winid, win_getid())
1367  copen | only
1368  exe "normal 5G\<CR>"
1369  call assert_equal(2, winnr('$'))
1370  call assert_equal(1, bufwinnr('Xqftestfile3'))
1371
1372  enew | only
1373
1374  call delete('Xqftestfile1')
1375  call delete('Xqftestfile2')
1376  call delete('Xqftestfile3')
1377endfunc
1378
1379func Xadjust_qflnum(cchar)
1380  call s:setup_commands(a:cchar)
1381
1382  enew | only
1383
1384  let fname = 'Xqftestfile' . a:cchar
1385  call s:create_test_file(fname)
1386  exe 'edit ' . fname
1387
1388  Xgetexpr [fname . ':5:Line5',
1389	      \ fname . ':10:Line10',
1390	      \ fname . ':15:Line15',
1391	      \ fname . ':20:Line20']
1392
1393  6,14delete
1394  call append(6, ['Buffer', 'Window'])
1395
1396  let l = g:Xgetlist()
1397
1398  call assert_equal(5, l[0].lnum)
1399  call assert_equal(6, l[2].lnum)
1400  call assert_equal(13, l[3].lnum)
1401
1402  enew!
1403  call delete(fname)
1404endfunc
1405
1406func Test_adjust_lnum()
1407  call setloclist(0, [])
1408  call Xadjust_qflnum('c')
1409  call setqflist([])
1410  call Xadjust_qflnum('l')
1411endfunc
1412
1413" Tests for the :grep/:lgrep and :grepadd/:lgrepadd commands
1414func s:test_xgrep(cchar)
1415  call s:setup_commands(a:cchar)
1416
1417  " The following lines are used for the grep test. Don't remove.
1418  " Grep_Test_Text: Match 1
1419  " Grep_Test_Text: Match 2
1420  " GrepAdd_Test_Text: Match 1
1421  " GrepAdd_Test_Text: Match 2
1422  enew! | only
1423  set makeef&vim
1424  silent Xgrep Grep_Test_Text: test_quickfix.vim
1425  call assert_true(len(g:Xgetlist()) == 3)
1426  Xopen
1427  call assert_true(w:quickfix_title =~ '^:grep')
1428  Xclose
1429  enew
1430  set makeef=Temp_File_##
1431  silent Xgrepadd GrepAdd_Test_Text: test_quickfix.vim
1432  call assert_true(len(g:Xgetlist()) == 6)
1433endfunc
1434
1435func Test_grep()
1436  if !has('unix')
1437    " The grepprg may not be set on non-Unix systems
1438    return
1439  endif
1440
1441  call s:test_xgrep('c')
1442  call s:test_xgrep('l')
1443endfunc
1444
1445func Test_two_windows()
1446  " Use one 'errorformat' for two windows.  Add an expression to each of them,
1447  " make sure they each keep their own state.
1448  set efm=%DEntering\ dir\ '%f',%f:%l:%m,%XLeaving\ dir\ '%f'
1449  call mkdir('Xone/a', 'p')
1450  call mkdir('Xtwo/a', 'p')
1451  let lines = ['1', '2', 'one one one', '4', 'two two two', '6', '7']
1452  call writefile(lines, 'Xone/a/one.txt')
1453  call writefile(lines, 'Xtwo/a/two.txt')
1454
1455  new one
1456  let one_id = win_getid()
1457  lexpr ""
1458  new two
1459  let two_id = win_getid()
1460  lexpr ""
1461
1462  laddexpr "Entering dir 'Xtwo/a'"
1463  call win_gotoid(one_id)
1464  laddexpr "Entering dir 'Xone/a'"
1465  call win_gotoid(two_id)
1466  laddexpr 'two.txt:5:two two two'
1467  call win_gotoid(one_id)
1468  laddexpr 'one.txt:3:one one one'
1469
1470  let loc_one = getloclist(one_id)
1471  call assert_equal('Xone/a/one.txt', bufname(loc_one[1].bufnr))
1472  call assert_equal(3, loc_one[1].lnum)
1473
1474  let loc_two = getloclist(two_id)
1475  call assert_equal('Xtwo/a/two.txt', bufname(loc_two[1].bufnr))
1476  call assert_equal(5, loc_two[1].lnum)
1477
1478  call win_gotoid(one_id)
1479  bwipe!
1480  call win_gotoid(two_id)
1481  bwipe!
1482  call delete('Xone', 'rf')
1483  call delete('Xtwo', 'rf')
1484endfunc
1485
1486func XbottomTests(cchar)
1487  call s:setup_commands(a:cchar)
1488
1489  call g:Xsetlist([{'filename': 'foo', 'lnum': 42}])
1490  Xopen
1491  let wid = win_getid()
1492  call assert_equal(1, line('.'))
1493  wincmd w
1494  call g:Xsetlist([{'filename': 'var', 'lnum': 24}], 'a')
1495  Xbottom
1496  call win_gotoid(wid)
1497  call assert_equal(2, line('.'))
1498  Xclose
1499endfunc
1500
1501" Tests for the :cbottom and :lbottom commands
1502func Test_cbottom()
1503  call XbottomTests('c')
1504  call XbottomTests('l')
1505endfunc
1506
1507func HistoryTest(cchar)
1508  call s:setup_commands(a:cchar)
1509
1510  call assert_fails(a:cchar . 'older 99', 'E380:')
1511  " clear all lists after the first one, then replace the first one.
1512  call g:Xsetlist([])
1513  Xolder
1514  let entry = {'filename': 'foo', 'lnum': 42}
1515  call g:Xsetlist([entry], 'r')
1516  call g:Xsetlist([entry, entry])
1517  call g:Xsetlist([entry, entry, entry])
1518  let res = split(execute(a:cchar . 'hist'), "\n")
1519  call assert_equal(3, len(res))
1520  let common = 'errors     :set' . (a:cchar == 'c' ? 'qf' : 'loc') . 'list()'
1521  call assert_equal('  error list 1 of 3; 1 ' . common, res[0])
1522  call assert_equal('  error list 2 of 3; 2 ' . common, res[1])
1523  call assert_equal('> error list 3 of 3; 3 ' . common, res[2])
1524endfunc
1525
1526func Test_history()
1527  call HistoryTest('c')
1528  call HistoryTest('l')
1529endfunc
1530
1531func Test_duplicate_buf()
1532  " make sure we can get the highest buffer number
1533  edit DoesNotExist
1534  edit DoesNotExist2
1535  let last_buffer = bufnr("$")
1536
1537  " make sure only one buffer is created
1538  call writefile(['this one', 'that one'], 'Xgrepthis')
1539  vimgrep one Xgrepthis
1540  vimgrep one Xgrepthis
1541  call assert_equal(last_buffer + 1, bufnr("$"))
1542
1543  call delete('Xgrepthis')
1544endfunc
1545
1546" Quickfix/Location list set/get properties tests
1547func Xproperty_tests(cchar)
1548    call s:setup_commands(a:cchar)
1549
1550    " Error cases
1551    call assert_fails('call g:Xgetlist(99)', 'E715:')
1552    call assert_fails('call g:Xsetlist(99)', 'E714:')
1553    call assert_fails('call g:Xsetlist([], "a", [])', 'E715:')
1554
1555    " Set and get the title
1556    Xopen
1557    wincmd p
1558    call g:Xsetlist([{'filename':'foo', 'lnum':27}])
1559    call g:Xsetlist([], 'a', {'title' : 'Sample'})
1560    let d = g:Xgetlist({"title":1})
1561    call assert_equal('Sample', d.title)
1562
1563    Xopen
1564    call assert_equal('Sample', w:quickfix_title)
1565    Xclose
1566
1567    " Tests for action argument
1568    silent! Xolder 999
1569    let qfnr = g:Xgetlist({'all':1}).nr
1570    call g:Xsetlist([], 'r', {'title' : 'N1'})
1571    call assert_equal('N1', g:Xgetlist({'all':1}).title)
1572    call g:Xsetlist([], ' ', {'title' : 'N2'})
1573    call assert_equal(qfnr + 1, g:Xgetlist({'all':1}).nr)
1574
1575    let res = g:Xgetlist({'nr': 0})
1576    call assert_equal(qfnr + 1, res.nr)
1577    call assert_equal(['nr'], keys(res))
1578
1579    call g:Xsetlist([], ' ', {'title' : 'N3'})
1580    call assert_equal('N2', g:Xgetlist({'nr':2, 'title':1}).title)
1581
1582    " Invalid arguments
1583    call assert_fails('call g:Xgetlist([])', 'E715')
1584    call assert_fails('call g:Xsetlist([], "a", [])', 'E715')
1585    let s = g:Xsetlist([], 'a', {'abc':1})
1586    call assert_equal(-1, s)
1587
1588    call assert_equal({}, g:Xgetlist({'abc':1}))
1589
1590    if a:cchar == 'l'
1591	call assert_equal({}, getloclist(99, {'title': 1}))
1592    endif
1593  endfunc
1594
1595func Test_qf_property()
1596    call Xproperty_tests('c')
1597    call Xproperty_tests('l')
1598  endfunc
1599
1600" Tests for the QuickFixCmdPre/QuickFixCmdPost autocommands
1601func QfAutoCmdHandler(loc, cmd)
1602  call add(g:acmds, a:loc . a:cmd)
1603endfunc
1604
1605func Test_Autocmd()
1606  autocmd QuickFixCmdPre * call QfAutoCmdHandler('pre', expand('<amatch>'))
1607  autocmd QuickFixCmdPost * call QfAutoCmdHandler('post', expand('<amatch>'))
1608
1609  let g:acmds = []
1610  cexpr "F1:10:Line 10"
1611  caddexpr "F1:20:Line 20"
1612  cgetexpr "F1:30:Line 30"
1613  enew! | call append(0, "F2:10:Line 10")
1614  cbuffer!
1615  enew! | call append(0, "F2:20:Line 20")
1616  cgetbuffer
1617  enew! | call append(0, "F2:30:Line 30")
1618  caddbuffer
1619
1620  let l = ['precexpr',
1621	      \ 'postcexpr',
1622	      \ 'precaddexpr',
1623	      \ 'postcaddexpr',
1624	      \ 'precgetexpr',
1625	      \ 'postcgetexpr',
1626	      \ 'precbuffer',
1627	      \ 'postcbuffer',
1628	      \ 'precgetbuffer',
1629	      \ 'postcgetbuffer',
1630	      \ 'precaddbuffer',
1631	      \ 'postcaddbuffer']
1632  call assert_equal(l, g:acmds)
1633endfunc
1634
1635func Test_Autocmd_Exception()
1636  set efm=%m
1637  lgetexpr '?'
1638
1639  try
1640    call DoesNotExit()
1641  catch
1642    lgetexpr '1'
1643  finally
1644    lgetexpr '1'
1645  endtry
1646
1647  call assert_equal('1', getloclist(0)[0].text)
1648
1649  set efm&vim
1650endfunc
1651
1652func Test_caddbuffer_wrong()
1653  " This used to cause a memory access in freed memory.
1654  let save_efm = &efm
1655  set efm=%EEEE%m,%WWWW,%+CCCC%>%#,%GGGG%.#
1656  cgetexpr ['WWWW', 'EEEE', 'CCCC']
1657  let &efm = save_efm
1658  caddbuffer
1659  bwipe!
1660endfunc
1661
1662func Test_caddexpr_wrong()
1663  " This used to cause a memory access in freed memory.
1664  cbuffer
1665  cbuffer
1666  copen
1667  let save_efm = &efm
1668  set efm=%
1669  call assert_fails('caddexpr ""', 'E376:')
1670  let &efm = save_efm
1671endfunc
1672
1673func Test_dirstack_cleanup()
1674  " This used to cause a memory access in freed memory.
1675  let save_efm = &efm
1676  lexpr '0'
1677  lopen
1678  fun X(c)
1679    let save_efm=&efm
1680    set efm=%D%f
1681    if a:c == 'c'
1682      caddexpr '::'
1683    else
1684      laddexpr ':0:0'
1685    endif
1686    let &efm=save_efm
1687  endfun
1688  call X('c')
1689  call X('l')
1690  call setqflist([], 'r')
1691  caddbuffer
1692  let &efm = save_efm
1693endfunc
1694