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