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