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=* Xolder <mods>colder <args>
14    command! -nargs=* Xnewer <mods>cnewer <args>
15    command! -nargs=* Xopen <mods>copen <args>
16    command! -nargs=* Xwindow <mods>cwindow <args>
17    command! -nargs=* Xclose <mods>cclose <args>
18    command! -nargs=* -bang Xfile <mods>cfile<bang> <args>
19    command! -nargs=* Xgetfile <mods>cgetfile <args>
20    command! -nargs=* Xaddfile <mods>caddfile <args>
21    command! -nargs=* -bang Xbuffer <mods>cbuffer<bang> <args>
22    command! -nargs=* Xgetbuffer <mods>cgetbuffer <args>
23    command! -nargs=* Xaddbuffer <mods>caddbuffer <args>
24    command! -nargs=* Xrewind <mods>crewind <args>
25    command! -nargs=* -bang Xnext <mods>cnext<bang> <args>
26    command! -nargs=* Xexpr <mods>cexpr <args>
27    command! -nargs=* Xvimgrep <mods>vimgrep <args>
28    command! -nargs=* Xgrep <mods> grep <args>
29    command! -nargs=* Xgrepadd <mods> grepadd <args>
30    command! -nargs=* Xhelpgrep helpgrep <args>
31    let g:Xgetlist = function('getqflist')
32    let g:Xsetlist = function('setqflist')
33  else
34    command! -nargs=* -bang Xlist <mods>llist<bang> <args>
35    command! -nargs=* Xgetexpr <mods>lgetexpr <args>
36    command! -nargs=* Xolder <mods>lolder <args>
37    command! -nargs=* Xnewer <mods>lnewer <args>
38    command! -nargs=* Xopen <mods>lopen <args>
39    command! -nargs=* Xwindow <mods>lwindow <args>
40    command! -nargs=* Xclose <mods>lclose <args>
41    command! -nargs=* -bang Xfile <mods>lfile<bang> <args>
42    command! -nargs=* Xgetfile <mods>lgetfile <args>
43    command! -nargs=* Xaddfile <mods>laddfile <args>
44    command! -nargs=* -bang Xbuffer <mods>lbuffer<bang> <args>
45    command! -nargs=* Xgetbuffer <mods>lgetbuffer <args>
46    command! -nargs=* Xaddbuffer <mods>laddbuffer <args>
47    command! -nargs=* Xrewind <mods>lrewind <args>
48    command! -nargs=* -bang Xnext <mods>lnext<bang> <args>
49    command! -nargs=* Xexpr <mods>lexpr <args>
50    command! -nargs=* Xvimgrep <mods>lvimgrep <args>
51    command! -nargs=* Xgrep <mods> lgrep <args>
52    command! -nargs=* Xgrepadd <mods> lgrepadd <args>
53    command! -nargs=* Xhelpgrep lhelpgrep <args>
54    let g:Xgetlist = function('getloclist', [0])
55    let g:Xsetlist = function('setloclist', [0])
56  endif
57endfunction
58
59" Tests for the :clist and :llist commands
60function XlistTests(cchar)
61  call s:setup_commands(a:cchar)
62
63  " With an empty list, command should return error
64  Xgetexpr []
65  silent! Xlist
66  call assert_true(v:errmsg ==# 'E42: No Errors')
67
68  " Populate the list and then try
69  Xgetexpr ['non-error 1', 'Xtestfile1:1:3:Line1',
70		  \ 'non-error 2', 'Xtestfile2:2:2:Line2',
71		  \ 'non-error 3', 'Xtestfile3:3:1:Line3']
72
73  " List only valid entries
74  redir => result
75  Xlist
76  redir END
77  let l = split(result, "\n")
78  call assert_equal([' 2 Xtestfile1:1 col 3: Line1',
79		   \ ' 4 Xtestfile2:2 col 2: Line2',
80		   \ ' 6 Xtestfile3:3 col 1: Line3'], l)
81
82  " List all the entries
83  redir => result
84  Xlist!
85  redir END
86  let l = split(result, "\n")
87  call assert_equal([' 1: non-error 1', ' 2 Xtestfile1:1 col 3: Line1',
88		   \ ' 3: non-error 2', ' 4 Xtestfile2:2 col 2: Line2',
89		   \ ' 5: non-error 3', ' 6 Xtestfile3:3 col 1: Line3'], l)
90
91  " List a range of errors
92  redir => result
93  Xlist 3,6
94  redir END
95  let l = split(result, "\n")
96  call assert_equal([' 4 Xtestfile2:2 col 2: Line2',
97		   \ ' 6 Xtestfile3:3 col 1: Line3'], l)
98
99  redir => result
100  Xlist! 3,4
101  redir END
102  let l = split(result, "\n")
103  call assert_equal([' 3: non-error 2', ' 4 Xtestfile2:2 col 2: Line2'], l)
104
105  redir => result
106  Xlist -6,-4
107  redir END
108  let l = split(result, "\n")
109  call assert_equal([' 2 Xtestfile1:1 col 3: Line1'], l)
110
111  redir => result
112  Xlist! -5,-3
113  redir END
114  let l = split(result, "\n")
115  call assert_equal([' 2 Xtestfile1:1 col 3: Line1',
116		   \ ' 3: non-error 2', ' 4 Xtestfile2:2 col 2: Line2'], l)
117endfunction
118
119function Test_clist()
120  call XlistTests('c')
121  call XlistTests('l')
122endfunction
123
124" Tests for the :colder, :cnewer, :lolder and :lnewer commands
125" Note that this test assumes that a quickfix/location list is
126" already set by the caller.
127function XageTests(cchar)
128  call s:setup_commands(a:cchar)
129
130  " Jumping to a non existent list should return error
131  silent! Xolder 99
132  call assert_true(v:errmsg ==# 'E380: At bottom of quickfix stack')
133
134  silent! Xnewer 99
135  call assert_true(v:errmsg ==# 'E381: At top of quickfix stack')
136
137  " Add three quickfix/location lists
138  Xgetexpr ['Xtestfile1:1:3:Line1']
139  Xgetexpr ['Xtestfile2:2:2:Line2']
140  Xgetexpr ['Xtestfile3:3:1:Line3']
141
142  " Go back two lists
143  Xolder
144  let l = g:Xgetlist()
145  call assert_equal('Line2', l[0].text)
146
147  " Go forward two lists
148  Xnewer
149  let l = g:Xgetlist()
150  call assert_equal('Line3', l[0].text)
151
152  " Test for the optional count argument
153  Xolder 2
154  let l = g:Xgetlist()
155  call assert_equal('Line1', l[0].text)
156
157  Xnewer 2
158  let l = g:Xgetlist()
159  call assert_equal('Line3', l[0].text)
160endfunction
161
162function Test_cage()
163  let list = [{'bufnr': 1, 'lnum': 1}]
164  call setqflist(list)
165  call XageTests('c')
166
167  call setloclist(0, list)
168  call XageTests('l')
169endfunction
170
171" Tests for the :cwindow, :lwindow :cclose, :lclose, :copen and :lopen
172" commands
173function XwindowTests(cchar)
174  call s:setup_commands(a:cchar)
175
176  " Create a list with no valid entries
177  Xgetexpr ['non-error 1', 'non-error 2', 'non-error 3']
178
179  " Quickfix/Location window should not open with no valid errors
180  Xwindow
181  call assert_true(winnr('$') == 1)
182
183  " Create a list with valid entries
184  Xgetexpr ['Xtestfile1:1:3:Line1', 'Xtestfile2:2:2:Line2',
185		  \ 'Xtestfile3:3:1:Line3']
186
187  " Open the window
188  Xwindow
189  call assert_true(winnr('$') == 2 && winnr() == 2 &&
190	\ getline('.') ==# 'Xtestfile1|1 col 3| Line1')
191
192  " Close the window
193  Xclose
194  call assert_true(winnr('$') == 1)
195
196  " Create a list with no valid entries
197  Xgetexpr ['non-error 1', 'non-error 2', 'non-error 3']
198
199  " Open the window
200  Xopen 5
201  call assert_true(winnr('$') == 2 && getline('.') ==# '|| non-error 1'
202		      \  && winheight('.') == 5)
203
204  " Opening the window again, should move the cursor to that window
205  wincmd t
206  Xopen 7
207  call assert_true(winnr('$') == 2 && winnr() == 2 &&
208	\ winheight('.') == 7 &&
209	\ getline('.') ==# '|| non-error 1')
210
211
212  " Calling cwindow should close the quickfix window with no valid errors
213  Xwindow
214  call assert_true(winnr('$') == 1)
215endfunction
216
217function Test_cwindow()
218  call XwindowTests('c')
219  call XwindowTests('l')
220endfunction
221
222" Tests for the :cfile, :lfile, :caddfile, :laddfile, :cgetfile and :lgetfile
223" commands.
224function XfileTests(cchar)
225  call s:setup_commands(a:cchar)
226
227  call writefile(['Xtestfile1:700:10:Line 700',
228	\ 'Xtestfile2:800:15:Line 800'], 'Xqftestfile1')
229
230  enew!
231  Xfile Xqftestfile1
232  let l = g:Xgetlist()
233  call assert_true(len(l) == 2 &&
234	\ l[0].lnum == 700 && l[0].col == 10 && l[0].text ==# 'Line 700' &&
235	\ l[1].lnum == 800 && l[1].col == 15 && l[1].text ==# 'Line 800')
236
237  " Test with a non existent file
238  call assert_fails('Xfile non_existent_file', 'E40')
239
240  " Run cfile/lfile from a modified buffer
241  enew!
242  silent! put ='Quickfix'
243  silent! Xfile Xqftestfile1
244  call assert_true(v:errmsg ==# 'E37: No write since last change (add ! to override)')
245
246  call writefile(['Xtestfile3:900:30:Line 900'], 'Xqftestfile1')
247  Xaddfile Xqftestfile1
248  let l = g:Xgetlist()
249  call assert_true(len(l) == 3 &&
250	\ l[2].lnum == 900 && l[2].col == 30 && l[2].text ==# 'Line 900')
251
252  call writefile(['Xtestfile1:222:77:Line 222',
253	\ 'Xtestfile2:333:88:Line 333'], 'Xqftestfile1')
254
255  enew!
256  Xgetfile Xqftestfile1
257  let l = g:Xgetlist()
258  call assert_true(len(l) == 2 &&
259	\ l[0].lnum == 222 && l[0].col == 77 && l[0].text ==# 'Line 222' &&
260	\ l[1].lnum == 333 && l[1].col == 88 && l[1].text ==# 'Line 333')
261
262  call delete('Xqftestfile1')
263endfunction
264
265function Test_cfile()
266  call XfileTests('c')
267  call XfileTests('l')
268endfunction
269
270" Tests for the :cbuffer, :lbuffer, :caddbuffer, :laddbuffer, :cgetbuffer and
271" :lgetbuffer commands.
272function XbufferTests(cchar)
273  call s:setup_commands(a:cchar)
274
275  enew!
276  silent! call setline(1, ['Xtestfile7:700:10:Line 700',
277	\ 'Xtestfile8:800:15:Line 800'])
278  Xbuffer!
279  let l = g:Xgetlist()
280  call assert_true(len(l) == 2 &&
281	\ l[0].lnum == 700 && l[0].col == 10 && l[0].text ==# 'Line 700' &&
282	\ l[1].lnum == 800 && l[1].col == 15 && l[1].text ==# 'Line 800')
283
284  enew!
285  silent! call setline(1, ['Xtestfile9:900:55:Line 900',
286	\ 'Xtestfile10:950:66:Line 950'])
287  Xgetbuffer
288  let l = g:Xgetlist()
289  call assert_true(len(l) == 2 &&
290	\ l[0].lnum == 900 && l[0].col == 55 && l[0].text ==# 'Line 900' &&
291	\ l[1].lnum == 950 && l[1].col == 66 && l[1].text ==# 'Line 950')
292
293  enew!
294  silent! call setline(1, ['Xtestfile11:700:20:Line 700',
295	\ 'Xtestfile12:750:25:Line 750'])
296  Xaddbuffer
297  let l = g:Xgetlist()
298  call assert_true(len(l) == 4 &&
299	\ l[1].lnum == 950 && l[1].col == 66 && l[1].text ==# 'Line 950' &&
300	\ l[2].lnum == 700 && l[2].col == 20 && l[2].text ==# 'Line 700' &&
301	\ l[3].lnum == 750 && l[3].col == 25 && l[3].text ==# 'Line 750')
302  enew!
303
304endfunction
305
306function Test_cbuffer()
307  call XbufferTests('c')
308  call XbufferTests('l')
309endfunction
310
311function Test_nomem()
312  call test_alloc_fail(GetAllocId('qf_dirname_start'), 0, 0)
313  call assert_fails('vimgrep vim runtest.vim', 'E342:')
314
315  call test_alloc_fail(GetAllocId('qf_dirname_now'), 0, 0)
316  call assert_fails('vimgrep vim runtest.vim', 'E342:')
317
318  call test_alloc_fail(GetAllocId('qf_namebuf'), 0, 0)
319  call assert_fails('cfile runtest.vim', 'E342:')
320
321  call test_alloc_fail(GetAllocId('qf_errmsg'), 0, 0)
322  call assert_fails('cfile runtest.vim', 'E342:')
323
324  call test_alloc_fail(GetAllocId('qf_pattern'), 0, 0)
325  call assert_fails('cfile runtest.vim', 'E342:')
326
327endfunc
328
329function! s:test_xhelpgrep(cchar)
330  call s:setup_commands(a:cchar)
331  Xhelpgrep quickfix
332  Xopen
333  if a:cchar == 'c'
334    let title_text = ':helpgrep quickfix'
335  else
336    let title_text = ':lhelpgrep quickfix'
337  endif
338  call assert_true(w:quickfix_title =~ title_text, w:quickfix_title)
339  " This wipes out the buffer, make sure that doesn't cause trouble.
340  Xclose
341endfunction
342
343function Test_helpgrep()
344  call s:test_xhelpgrep('c')
345  call s:test_xhelpgrep('l')
346endfunc
347
348func Test_errortitle()
349  augroup QfBufWinEnter
350    au!
351    au BufWinEnter * :let g:a=get(w:, 'quickfix_title', 'NONE')
352  augroup END
353  copen
354  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'')'}]
355  call setqflist(a)
356  call assert_equal(':setqflist()', g:a)
357  augroup QfBufWinEnter
358    au!
359  augroup END
360  augroup! QfBufWinEnter
361endfunc
362
363func Test_vimgreptitle()
364  augroup QfBufWinEnter
365    au!
366    au BufWinEnter * :let g:a=get(w:, 'quickfix_title', 'NONE')
367  augroup END
368  try
369    vimgrep /pattern/j file
370  catch /E480/
371  endtry
372  copen
373  call assert_equal(':    vimgrep /pattern/j file', g:a)
374  augroup QfBufWinEnter
375    au!
376  augroup END
377  augroup! QfBufWinEnter
378endfunc
379
380function XqfTitleTests(cchar)
381  call s:setup_commands(a:cchar)
382
383  Xgetexpr ['file:1:1:message']
384  let l = g:Xgetlist()
385  if a:cchar == 'c'
386    call setqflist(l, 'r')
387  else
388    call setloclist(0, l, 'r')
389  endif
390
391  Xopen
392  if a:cchar == 'c'
393    let title = ':setqflist()'
394  else
395    let title = ':setloclist()'
396  endif
397  call assert_equal(title, w:quickfix_title)
398  Xclose
399endfunction
400
401" Tests for quickfix window's title
402function Test_qf_title()
403  call XqfTitleTests('c')
404  call XqfTitleTests('l')
405endfunction
406
407" Tests for 'errorformat'
408function Test_efm()
409  let save_efm = &efm
410  set efm=%EEEE%m,%WWWW%m,%+CCCC%.%#,%-GGGG%.%#
411  cgetexpr ['WWWW', 'EEEE', 'CCCC']
412  let l = strtrans(string(map(getqflist(), '[v:val.text, v:val.valid]')))
413  call assert_equal("[['W', 1], ['E^@CCCC', 1]]", l)
414  cgetexpr ['WWWW', 'GGGG', 'EEEE', 'CCCC']
415  let l = strtrans(string(map(getqflist(), '[v:val.text, v:val.valid]')))
416  call assert_equal("[['W', 1], ['E^@CCCC', 1]]", l)
417  cgetexpr ['WWWW', 'GGGG', 'ZZZZ', 'EEEE', 'CCCC', 'YYYY']
418  let l = strtrans(string(map(getqflist(), '[v:val.text, v:val.valid]')))
419  call assert_equal("[['W', 1], ['ZZZZ', 0], ['E^@CCCC', 1], ['YYYY', 0]]", l)
420  let &efm = save_efm
421endfunction
422
423" This will test for problems in quickfix:
424" A. incorrectly copying location lists which caused the location list to show
425"    a different name than the file that was actually being displayed.
426" B. not reusing the window for which the location list window is opened but
427"    instead creating new windows.
428" C. make sure that the location list window is not reused instead of the
429"    window it belongs to.
430"
431" Set up the test environment:
432function! ReadTestProtocol(name)
433  let base = substitute(a:name, '\v^test://(.*)%(\.[^.]+)?', '\1', '')
434  let word = substitute(base, '\v(.*)\..*', '\1', '')
435
436  setl modifiable
437  setl noreadonly
438  setl noswapfile
439  setl bufhidden=delete
440  %del _
441  " For problem 2:
442  " 'buftype' has to be set to reproduce the constant opening of new windows
443  setl buftype=nofile
444
445  call setline(1, word)
446
447  setl nomodified
448  setl nomodifiable
449  setl readonly
450  exe 'doautocmd BufRead ' . substitute(a:name, '\v^test://(.*)', '\1', '')
451endfunction
452
453function Test_locationlist()
454    enew
455
456    augroup testgroup
457      au!
458      autocmd BufReadCmd test://* call ReadTestProtocol(expand("<amatch>"))
459    augroup END
460
461    let words = [ "foo", "bar", "baz", "quux", "shmoo", "spam", "eggs" ]
462
463    let qflist = []
464    for word in words
465      call add(qflist, {'filename': 'test://' . word . '.txt', 'text': 'file ' . word . '.txt', })
466      " NOTE: problem 1:
467      " intentionally not setting 'lnum' so that the quickfix entries are not
468      " valid
469      call setloclist(0, qflist, ' ')
470    endfor
471
472    " Test A
473    lrewind
474    enew
475    lopen
476    lnext
477    lnext
478    lnext
479    lnext
480    vert split
481    wincmd L
482    lopen
483    wincmd p
484    lnext
485    let fileName = expand("%")
486    wincmd p
487    let locationListFileName = substitute(getline(line('.')), '\([^|]*\)|.*', '\1', '')
488    let fileName = substitute(fileName, '\\', '/', 'g')
489    let locationListFileName = substitute(locationListFileName, '\\', '/', 'g')
490    call assert_equal("test://bar.txt", fileName)
491    call assert_equal("test://bar.txt", locationListFileName)
492
493    wincmd n | only
494
495    " Test B:
496    lrewind
497    lopen
498    2
499    exe "normal \<CR>"
500    wincmd p
501    3
502    exe "normal \<CR>"
503    wincmd p
504    4
505    exe "normal \<CR>"
506    call assert_equal(2, winnr('$'))
507    wincmd n | only
508
509    " Test C:
510    lrewind
511    lopen
512    " Let's move the location list window to the top to check whether it (the
513    " first window found) will be reused when we try to open new windows:
514    wincmd K
515    2
516    exe "normal \<CR>"
517    wincmd p
518    3
519    exe "normal \<CR>"
520    wincmd p
521    4
522    exe "normal \<CR>"
523    1wincmd w
524    call assert_equal('quickfix', &buftype)
525    2wincmd w
526    let bufferName = expand("%")
527    let bufferName = substitute(bufferName, '\\', '/', 'g')
528    call assert_equal('test://quux.txt', bufferName)
529
530    wincmd n | only
531
532    augroup! testgroup
533endfunction
534
535function Test_locationlist_curwin_was_closed()
536    augroup testgroup
537      au!
538      autocmd BufReadCmd test_curwin.txt call R(expand("<amatch>"))
539    augroup END
540
541    function! R(n)
542      quit
543    endfunc
544
545    new
546    let q = []
547    call add(q, {'filename': 'test_curwin.txt' })
548    call setloclist(0, q)
549    call assert_fails('lrewind', 'E924:')
550
551    augroup! testgroup
552endfunction
553
554" More tests for 'errorformat'
555function! Test_efm1()
556    if !has('unix')
557	" The 'errorformat' setting is different on non-Unix systems.
558	" This test works only on Unix-like systems.
559	return
560    endif
561
562    let l = [
563      \ '"Xtestfile", line 4.12: 1506-045 (S) Undeclared identifier fd_set.',
564      \ '"Xtestfile", line 6 col 19; this is an error',
565      \ 'gcc -c -DHAVE_CONFIsing-prototypes -I/usr/X11R6/include  version.c',
566      \ 'Xtestfile:9: parse error before `asd''',
567      \ 'make: *** [vim] Error 1',
568      \ 'in file "Xtestfile" linenr 10: there is an error',
569      \ '',
570      \ '2 returned',
571      \ '"Xtestfile", line 11 col 1; this is an error',
572      \ '"Xtestfile", line 12 col 2; this is another error',
573      \ '"Xtestfile", line 14:10; this is an error in column 10',
574      \ '=Xtestfile=, line 15:10; this is another error, but in vcol 10 this time',
575      \ '"Xtestfile", linenr 16: yet another problem',
576      \ 'Error in "Xtestfile" at line 17:',
577      \ 'x should be a dot',
578      \ '	xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx    line 17',
579      \ '            ^',
580      \ 'Error in "Xtestfile" at line 18:',
581      \ 'x should be a dot',
582      \ '	xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx    line 18',
583      \ '.............^',
584      \ 'Error in "Xtestfile" at line 19:',
585      \ 'x should be a dot',
586      \ '	xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx    line 19',
587      \ '--------------^',
588      \ 'Error in "Xtestfile" at line 20:',
589      \ 'x should be a dot',
590      \ '	xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx    line 20',
591      \ '	       ^',
592      \ '',
593      \ 'Does anyone know what is the problem and how to correction it?',
594      \ '"Xtestfile", line 21 col 9: What is the title of the quickfix window?',
595      \ '"Xtestfile", line 22 col 9: What is the title of the quickfix window?'
596      \ ]
597
598    call writefile(l, 'Xerrorfile1')
599    call writefile(l[:-2], 'Xerrorfile2')
600
601    let m = [
602	\ '	xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx    line  2',
603	\ '	xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx    line  3',
604	\ '	xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx    line  4',
605	\ '	xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx    line  5',
606	\ '	xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx    line  6',
607	\ '	xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx    line  7',
608	\ '	xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx    line  8',
609	\ '	xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx    line  9',
610	\ '	xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx    line 10',
611	\ '	xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx    line 11',
612	\ '	xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx    line 12',
613	\ '	xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx    line 13',
614	\ '	xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx    line 14',
615	\ '	xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx    line 15',
616	\ '	xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx    line 16',
617	\ '	xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx    line 17',
618	\ '	xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx    line 18',
619	\ '	xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx    line 19',
620	\ '	xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx    line 20',
621	\ '	xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx    line 21',
622	\ '	xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx    line 22'
623	\ ]
624    call writefile(m, 'Xtestfile')
625
626    let save_efm = &efm
627    set efm+==%f=\\,\ line\ %l%*\\D%v%*[^\ ]\ %m
628    set efm^=%AError\ in\ \"%f\"\ at\ line\ %l:,%Z%p^,%C%m
629
630    exe 'cf Xerrorfile2'
631    clast
632    copen
633    call assert_equal(':cf Xerrorfile2', w:quickfix_title)
634    wincmd p
635
636    exe 'cf Xerrorfile1'
637    call assert_equal([4, 12], [line('.'), col('.')])
638    cn
639    call assert_equal([6, 19], [line('.'), col('.')])
640    cn
641    call assert_equal([9, 2], [line('.'), col('.')])
642    cn
643    call assert_equal([10, 2], [line('.'), col('.')])
644    cn
645    call assert_equal([11, 1], [line('.'), col('.')])
646    cn
647    call assert_equal([12, 2], [line('.'), col('.')])
648    cn
649    call assert_equal([14, 10], [line('.'), col('.')])
650    cn
651    call assert_equal([15, 3, 10], [line('.'), col('.'), virtcol('.')])
652    cn
653    call assert_equal([16, 2], [line('.'), col('.')])
654    cn
655    call assert_equal([17, 6], [line('.'), col('.')])
656    cn
657    call assert_equal([18, 7], [line('.'), col('.')])
658    cn
659    call assert_equal([19, 8], [line('.'), col('.')])
660    cn
661    call assert_equal([20, 9], [line('.'), col('.')])
662    clast
663    cprev
664    cprev
665    wincmd w
666    call assert_equal(':cf Xerrorfile1', w:quickfix_title)
667    wincmd p
668
669    let &efm = save_efm
670    call delete('Xerrorfile1')
671    call delete('Xerrorfile2')
672    call delete('Xtestfile')
673endfunction
674
675" Test for quickfix directory stack support
676function! s:dir_stack_tests(cchar)
677  call s:setup_commands(a:cchar)
678
679  let save_efm=&efm
680  set efm=%DEntering\ dir\ '%f',%f:%l:%m,%XLeaving\ dir\ '%f'
681
682  let l = "Entering dir 'dir1/a'\n" .
683		\ 'habits2.txt:1:Nine Healthy Habits' . "\n" .
684		\ "Entering dir 'b'\n" .
685		\ 'habits3.txt:2:0 Hours of television' . "\n" .
686		\ 'habits2.txt:7:5 Small meals' . "\n" .
687		\ "Entering dir 'dir1/c'\n" .
688		\ 'habits4.txt:3:1 Hour of exercise' . "\n" .
689		\ "Leaving dir 'dir1/c'\n" .
690		\ "Leaving dir 'dir1/a'\n" .
691		\ 'habits1.txt:4:2 Liters of water' . "\n" .
692		\ "Entering dir 'dir2'\n" .
693		\ 'habits5.txt:5:3 Cups of hot green tea' . "\n"
694		\ "Leaving dir 'dir2'\n"
695
696  Xgetexpr l
697
698  let qf = g:Xgetlist()
699
700  call assert_equal('dir1/a/habits2.txt', bufname(qf[1].bufnr))
701  call assert_equal(1, qf[1].lnum)
702  call assert_equal('dir1/a/b/habits3.txt', bufname(qf[3].bufnr))
703  call assert_equal(2, qf[3].lnum)
704  call assert_equal('dir1/a/habits2.txt', bufname(qf[4].bufnr))
705  call assert_equal(7, qf[4].lnum)
706  call assert_equal('dir1/c/habits4.txt', bufname(qf[6].bufnr))
707  call assert_equal(3, qf[6].lnum)
708  call assert_equal('habits1.txt', bufname(qf[9].bufnr))
709  call assert_equal(4, qf[9].lnum)
710  call assert_equal('dir2/habits5.txt', bufname(qf[11].bufnr))
711  call assert_equal(5, qf[11].lnum)
712
713  let &efm=save_efm
714endfunction
715
716" Tests for %D and %X errorformat options
717function! Test_efm_dirstack()
718  " Create the directory stack and files
719  call mkdir('dir1')
720  call mkdir('dir1/a')
721  call mkdir('dir1/a/b')
722  call mkdir('dir1/c')
723  call mkdir('dir2')
724
725  let lines = ["Nine Healthy Habits",
726		\ "0 Hours of television",
727		\ "1 Hour of exercise",
728		\ "2 Liters of water",
729		\ "3 Cups of hot green tea",
730		\ "4 Short mental breaks",
731		\ "5 Small meals",
732		\ "6 AM wake up time",
733		\ "7 Minutes of laughter",
734		\ "8 Hours of sleep (at least)",
735		\ "9 PM end of the day and off to bed"
736		\ ]
737  call writefile(lines, 'habits1.txt')
738  call writefile(lines, 'dir1/a/habits2.txt')
739  call writefile(lines, 'dir1/a/b/habits3.txt')
740  call writefile(lines, 'dir1/c/habits4.txt')
741  call writefile(lines, 'dir2/habits5.txt')
742
743  call s:dir_stack_tests('c')
744  call s:dir_stack_tests('l')
745
746  call delete('dir1', 'rf')
747  call delete('dir2', 'rf')
748  call delete('habits1.txt')
749endfunction
750
751" TODO:
752" Add tests for the following formats in 'errorformat'
753"	%n  %t  %r  %+  %-  %O
754function! Test_efm2()
755  let save_efm = &efm
756
757  " Test for invalid efm
758  set efm=%L%M%N
759  call assert_fails('cexpr "abc.txt:1:Hello world"', 'E376:')
760  call assert_fails('lexpr "abc.txt:1:Hello world"', 'E376:')
761
762  " Test for %s format in efm
763  set efm=%f:%s
764  cexpr 'Xtestfile:Line search text'
765
766  let l = getqflist()
767  call assert_equal(l[0].pattern, '^\VLine search text\$')
768  call assert_equal(l[0].lnum, 0)
769
770  let lines=["[Xtestfile1]",
771	      \ "(1,17)  error: ';' missing",
772	      \ "(21,2)  warning: variable 'z' not defined",
773	      \ "(67,3)  error: end of file found before string ended",
774	      \ "",
775	      \ "[Xtestfile2]",
776	      \ "",
777	      \ "[Xtestfile3]",
778	      \ "NEW compiler v1.1",
779	      \ "(2,2)   warning: variable 'x' not defined",
780	      \ "(67,3)  warning: 's' already defined"
781	      \]
782  set efm=%+P[%f],(%l\\,%c)%*[\ ]%t%*[^:]:\ %m,%-Q
783  cgetexpr lines
784  let l = getqflist()
785  call assert_equal(9, len(l))
786  call assert_equal(21, l[2].lnum)
787  call assert_equal(2, l[2].col)
788
789  let &efm = save_efm
790endfunction
791
792function XquickfixChangedByAutocmd(cchar)
793  call s:setup_commands(a:cchar)
794  if a:cchar == 'c'
795    let ErrorNr = 'E925'
796    function! ReadFunc()
797      colder
798      cgetexpr []
799    endfunc
800  else
801    let ErrorNr = 'E926'
802    function! ReadFunc()
803      lolder
804      lgetexpr []
805    endfunc
806  endif
807
808  augroup testgroup
809    au!
810    autocmd BufReadCmd test_changed.txt call ReadFunc()
811  augroup END
812
813  new | only
814  let words = [ "a", "b" ]
815  let qflist = []
816  for word in words
817    call add(qflist, {'filename': 'test_changed.txt'})
818    call g:Xsetlist(qflist, ' ')
819  endfor
820  call assert_fails('Xrewind', ErrorNr . ':')
821
822  augroup! testgroup
823endfunc
824
825function Test_quickfix_was_changed_by_autocmd()
826  call XquickfixChangedByAutocmd('c')
827  call XquickfixChangedByAutocmd('l')
828endfunction
829
830func Test_caddbuffer_to_empty()
831  helpgr quickfix
832  call setqflist([], 'r')
833  cad
834  try
835    cn
836  catch
837    " number of matches is unknown
838    call assert_true(v:exception =~ 'E553:')
839  endtry
840  quit!
841endfunc
842
843func Test_cgetexpr_works()
844  " this must not crash Vim
845  cgetexpr [$x]
846  lgetexpr [$x]
847endfunc
848
849" Tests for the setqflist() and setloclist() functions
850function SetXlistTests(cchar, bnum)
851  call s:setup_commands(a:cchar)
852
853  call g:Xsetlist([{'bufnr': a:bnum, 'lnum': 1},
854	      \  {'bufnr': a:bnum, 'lnum': 2}])
855  let l = g:Xgetlist()
856  call assert_equal(2, len(l))
857  call assert_equal(2, l[1].lnum)
858
859  Xnext
860  call g:Xsetlist([{'bufnr': a:bnum, 'lnum': 3}], 'a')
861  let l = g:Xgetlist()
862  call assert_equal(3, len(l))
863  Xnext
864  call assert_equal(3, line('.'))
865
866  " Appending entries to the list should not change the cursor position
867  " in the quickfix window
868  Xwindow
869  1
870  call g:Xsetlist([{'bufnr': a:bnum, 'lnum': 4},
871	      \  {'bufnr': a:bnum, 'lnum': 5}], 'a')
872  call assert_equal(1, line('.'))
873  close
874
875  call g:Xsetlist([{'bufnr': a:bnum, 'lnum': 3},
876	      \  {'bufnr': a:bnum, 'lnum': 4},
877	      \  {'bufnr': a:bnum, 'lnum': 5}], 'r')
878  let l = g:Xgetlist()
879  call assert_equal(3, len(l))
880  call assert_equal(5, l[2].lnum)
881
882  call g:Xsetlist([])
883  let l = g:Xgetlist()
884  call assert_equal(0, len(l))
885endfunction
886
887function Test_setqflist()
888  new Xtestfile | only
889  let bnum = bufnr('%')
890  call setline(1, range(1,5))
891
892  call SetXlistTests('c', bnum)
893  call SetXlistTests('l', bnum)
894
895  enew!
896  call delete('Xtestfile')
897endfunction
898
899function Xlist_empty_middle(cchar)
900  call s:setup_commands(a:cchar)
901
902  " create three quickfix lists
903  Xvimgrep Test_ test_quickfix.vim
904  let testlen = len(g:Xgetlist())
905  call assert_true(testlen > 0)
906  Xvimgrep empty test_quickfix.vim
907  call assert_true(len(g:Xgetlist()) > 0)
908  Xvimgrep matches test_quickfix.vim
909  let matchlen = len(g:Xgetlist())
910  call assert_true(matchlen > 0)
911  Xolder
912  " make the middle list empty
913  call g:Xsetlist([], 'r')
914  call assert_true(len(g:Xgetlist()) == 0)
915  Xolder
916  call assert_equal(testlen, len(g:Xgetlist()))
917  Xnewer
918  Xnewer
919  call assert_equal(matchlen, len(g:Xgetlist()))
920endfunc
921
922function Test_setqflist_empty_middle()
923  call Xlist_empty_middle('c')
924  call Xlist_empty_middle('l')
925endfunction
926
927function Xlist_empty_older(cchar)
928  call s:setup_commands(a:cchar)
929
930  " create three quickfix lists
931  Xvimgrep one test_quickfix.vim
932  let onelen = len(g:Xgetlist())
933  call assert_true(onelen > 0)
934  Xvimgrep two test_quickfix.vim
935  let twolen = len(g:Xgetlist())
936  call assert_true(twolen > 0)
937  Xvimgrep three test_quickfix.vim
938  let threelen = len(g:Xgetlist())
939  call assert_true(threelen > 0)
940  Xolder 2
941  " make the first list empty, check the others didn't change
942  call g:Xsetlist([], 'r')
943  call assert_true(len(g:Xgetlist()) == 0)
944  Xnewer
945  call assert_equal(twolen, len(g:Xgetlist()))
946  Xnewer
947  call assert_equal(threelen, len(g:Xgetlist()))
948endfunction
949
950function Test_setqflist_empty_older()
951  call Xlist_empty_older('c')
952  call Xlist_empty_older('l')
953endfunction
954
955function! XquickfixSetListWithAct(cchar)
956  call s:setup_commands(a:cchar)
957
958  let list1 = [{'filename': 'fnameA', 'text': 'A'},
959          \    {'filename': 'fnameB', 'text': 'B'}]
960  let list2 = [{'filename': 'fnameC', 'text': 'C'},
961          \    {'filename': 'fnameD', 'text': 'D'},
962          \    {'filename': 'fnameE', 'text': 'E'}]
963
964  " {action} is unspecified.  Same as specifing ' '.
965  new | only
966  silent! Xnewer 99
967  call g:Xsetlist(list1)
968  call g:Xsetlist(list2)
969  let li = g:Xgetlist()
970  call assert_equal(3, len(li))
971  call assert_equal('C', li[0]['text'])
972  call assert_equal('D', li[1]['text'])
973  call assert_equal('E', li[2]['text'])
974  silent! Xolder
975  let li = g:Xgetlist()
976  call assert_equal(2, len(li))
977  call assert_equal('A', li[0]['text'])
978  call assert_equal('B', li[1]['text'])
979
980  " {action} is specified ' '.
981  new | only
982  silent! Xnewer 99
983  call g:Xsetlist(list1)
984  call g:Xsetlist(list2, ' ')
985  let li = g:Xgetlist()
986  call assert_equal(3, len(li))
987  call assert_equal('C', li[0]['text'])
988  call assert_equal('D', li[1]['text'])
989  call assert_equal('E', li[2]['text'])
990  silent! Xolder
991  let li = g:Xgetlist()
992  call assert_equal(2, len(li))
993  call assert_equal('A', li[0]['text'])
994  call assert_equal('B', li[1]['text'])
995
996  " {action} is specified 'a'.
997  new | only
998  silent! Xnewer 99
999  call g:Xsetlist(list1)
1000  call g:Xsetlist(list2, 'a')
1001  let li = g:Xgetlist()
1002  call assert_equal(5, len(li))
1003  call assert_equal('A', li[0]['text'])
1004  call assert_equal('B', li[1]['text'])
1005  call assert_equal('C', li[2]['text'])
1006  call assert_equal('D', li[3]['text'])
1007  call assert_equal('E', li[4]['text'])
1008
1009  " {action} is specified 'r'.
1010  new | only
1011  silent! Xnewer 99
1012  call g:Xsetlist(list1)
1013  call g:Xsetlist(list2, 'r')
1014  let li = g:Xgetlist()
1015  call assert_equal(3, len(li))
1016  call assert_equal('C', li[0]['text'])
1017  call assert_equal('D', li[1]['text'])
1018  call assert_equal('E', li[2]['text'])
1019
1020  " Test for wrong value.
1021  new | only
1022  call assert_fails("call g:Xsetlist(0)", 'E714:')
1023  call assert_fails("call g:Xsetlist(list1, '')", 'E927:')
1024  call assert_fails("call g:Xsetlist(list1, 'aa')", 'E927:')
1025  call assert_fails("call g:Xsetlist(list1, ' a')", 'E927:')
1026  call assert_fails("call g:Xsetlist(list1, 0)", 'E928:')
1027endfunc
1028
1029function Test_quickfix_set_list_with_act()
1030  call XquickfixSetListWithAct('c')
1031  call XquickfixSetListWithAct('l')
1032endfunction
1033
1034function XLongLinesTests(cchar)
1035  let l = g:Xgetlist()
1036
1037  call assert_equal(4, len(l))
1038  call assert_equal(1, l[0].lnum)
1039  call assert_equal(1, l[0].col)
1040  call assert_equal(1975, len(l[0].text))
1041  call assert_equal(2, l[1].lnum)
1042  call assert_equal(1, l[1].col)
1043  call assert_equal(4070, len(l[1].text))
1044  call assert_equal(3, l[2].lnum)
1045  call assert_equal(1, l[2].col)
1046  call assert_equal(4070, len(l[2].text))
1047  call assert_equal(4, l[3].lnum)
1048  call assert_equal(1, l[3].col)
1049  call assert_equal(10, len(l[3].text))
1050
1051  call g:Xsetlist([], 'r')
1052endfunction
1053
1054function s:long_lines_tests(cchar)
1055  call s:setup_commands(a:cchar)
1056
1057  let testfile = 'samples/quickfix.txt'
1058
1059  " file
1060  exe 'Xgetfile' testfile
1061  call XLongLinesTests(a:cchar)
1062
1063  " list
1064  Xexpr readfile(testfile)
1065  call XLongLinesTests(a:cchar)
1066
1067  " string
1068  Xexpr join(readfile(testfile), "\n")
1069  call XLongLinesTests(a:cchar)
1070
1071  " buffer
1072  exe 'edit' testfile
1073  exe 'Xbuffer' bufnr('%')
1074  call XLongLinesTests(a:cchar)
1075endfunction
1076
1077function Test_long_lines()
1078  call s:long_lines_tests('c')
1079  call s:long_lines_tests('l')
1080endfunction
1081
1082function! s:create_test_file(filename)
1083  let l = []
1084  for i in range(1, 20)
1085      call add(l, 'Line' . i)
1086  endfor
1087  call writefile(l, a:filename)
1088endfunction
1089
1090function! Test_switchbuf()
1091  call s:create_test_file('Xqftestfile1')
1092  call s:create_test_file('Xqftestfile2')
1093  call s:create_test_file('Xqftestfile3')
1094
1095  new | only
1096  edit Xqftestfile1
1097  let file1_winid = win_getid()
1098  new Xqftestfile2
1099  let file2_winid = win_getid()
1100  cgetexpr ['Xqftestfile1:5:Line5',
1101		\ 'Xqftestfile1:6:Line6',
1102		\ 'Xqftestfile2:10:Line10',
1103		\ 'Xqftestfile2:11:Line11',
1104		\ 'Xqftestfile3:15:Line15',
1105		\ 'Xqftestfile3:16:Line16']
1106
1107  new
1108  let winid = win_getid()
1109  cfirst | cnext
1110  call assert_equal(winid, win_getid())
1111  cnext | cnext
1112  call assert_equal(winid, win_getid())
1113  cnext | cnext
1114  call assert_equal(winid, win_getid())
1115  enew
1116
1117  set switchbuf=useopen
1118  cfirst | cnext
1119  call assert_equal(file1_winid, win_getid())
1120  cnext | cnext
1121  call assert_equal(file2_winid, win_getid())
1122  cnext | cnext
1123  call assert_equal(file2_winid, win_getid())
1124
1125  enew | only
1126  set switchbuf=usetab
1127  tabedit Xqftestfile1
1128  tabedit Xqftestfile2
1129  tabfirst
1130  cfirst | cnext
1131  call assert_equal(2, tabpagenr())
1132  cnext | cnext
1133  call assert_equal(3, tabpagenr())
1134  cnext | cnext
1135  call assert_equal(3, tabpagenr())
1136  tabfirst | tabonly | enew
1137
1138  set switchbuf=split
1139  cfirst | cnext
1140  call assert_equal(1, winnr('$'))
1141  cnext | cnext
1142  call assert_equal(2, winnr('$'))
1143  cnext | cnext
1144  call assert_equal(3, winnr('$'))
1145  enew | only
1146
1147  set switchbuf=newtab
1148  cfirst | cnext
1149  call assert_equal(1, tabpagenr('$'))
1150  cnext | cnext
1151  call assert_equal(2, tabpagenr('$'))
1152  cnext | cnext
1153  call assert_equal(3, tabpagenr('$'))
1154  tabfirst | enew | tabonly | only
1155
1156  set switchbuf=
1157  edit Xqftestfile1
1158  let file1_winid = win_getid()
1159  new Xqftestfile2
1160  let file2_winid = win_getid()
1161  copen
1162  exe "normal 1G\<CR>"
1163  call assert_equal(file1_winid, win_getid())
1164  copen
1165  exe "normal 3G\<CR>"
1166  call assert_equal(file2_winid, win_getid())
1167  copen | only
1168  exe "normal 5G\<CR>"
1169  call assert_equal(2, winnr('$'))
1170  call assert_equal(1, bufwinnr('Xqftestfile3'))
1171
1172  enew | only
1173
1174  call delete('Xqftestfile1')
1175  call delete('Xqftestfile2')
1176  call delete('Xqftestfile3')
1177endfunction
1178
1179function! Xadjust_qflnum(cchar)
1180  call s:setup_commands(a:cchar)
1181
1182  enew | only
1183
1184  call s:create_test_file('Xqftestfile')
1185  edit Xqftestfile
1186
1187  Xgetexpr ['Xqftestfile:5:Line5',
1188		\ 'Xqftestfile:10:Line10',
1189		\ 'Xqftestfile:15:Line15',
1190		\ 'Xqftestfile:20:Line20']
1191
1192  6,14delete
1193  call append(6, ['Buffer', 'Window'])
1194
1195  let l = g:Xgetlist()
1196
1197  call assert_equal(5, l[0].lnum)
1198  call assert_equal(6, l[2].lnum)
1199  call assert_equal(13, l[3].lnum)
1200
1201  enew!
1202  call delete('Xqftestfile')
1203endfunction
1204
1205function! Test_adjust_lnum()
1206  call Xadjust_qflnum('c')
1207  call Xadjust_qflnum('l')
1208endfunction
1209
1210" Tests for the :grep/:lgrep and :grepadd/:lgrepadd commands
1211function! s:test_xgrep(cchar)
1212  call s:setup_commands(a:cchar)
1213
1214  " The following lines are used for the grep test. Don't remove.
1215  " Grep_Test_Text: Match 1
1216  " Grep_Test_Text: Match 2
1217  " GrepAdd_Test_Text: Match 1
1218  " GrepAdd_Test_Text: Match 2
1219  enew! | only
1220  set makeef&vim
1221  silent Xgrep Grep_Test_Text: test_quickfix.vim
1222  call assert_true(len(g:Xgetlist()) == 3)
1223  Xopen
1224  call assert_true(w:quickfix_title =~ '^:grep')
1225  Xclose
1226  enew
1227  set makeef=Temp_File_##
1228  silent Xgrepadd GrepAdd_Test_Text: test_quickfix.vim
1229  call assert_true(len(g:Xgetlist()) == 6)
1230endfunction
1231
1232function! Test_grep()
1233  if !has('unix')
1234    " The grepprg may not be set on non-Unix systems
1235    return
1236  endif
1237
1238  call s:test_xgrep('c')
1239  call s:test_xgrep('l')
1240endfunction
1241