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