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