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