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=* -count Xolder <mods><count>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! -count -nargs=* -bang Xnext <mods><count>cnext<bang> <args> 28 command! -count -nargs=* -bang Xprev <mods><count>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 -range Xnfile <mods><count>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 command! -nargs=0 -count Xcc <count>cc 40 let g:Xgetlist = function('getqflist') 41 let g:Xsetlist = function('setqflist') 42 call setqflist([], 'f') 43 else 44 command! -nargs=* -bang Xlist <mods>llist<bang> <args> 45 command! -nargs=* Xgetexpr <mods>lgetexpr <args> 46 command! -nargs=* Xaddexpr <mods>laddexpr <args> 47 command! -nargs=* -count Xolder <mods><count>lolder <args> 48 command! -nargs=* Xnewer <mods>lnewer <args> 49 command! -nargs=* Xopen <mods>lopen <args> 50 command! -nargs=* Xwindow <mods>lwindow <args> 51 command! -nargs=* Xbottom <mods>lbottom <args> 52 command! -nargs=* Xclose <mods>lclose <args> 53 command! -nargs=* -bang Xfile <mods>lfile<bang> <args> 54 command! -nargs=* Xgetfile <mods>lgetfile <args> 55 command! -nargs=* Xaddfile <mods>laddfile <args> 56 command! -nargs=* -bang Xbuffer <mods>lbuffer<bang> <args> 57 command! -nargs=* Xgetbuffer <mods>lgetbuffer <args> 58 command! -nargs=* Xaddbuffer <mods>laddbuffer <args> 59 command! -nargs=* Xrewind <mods>lrewind <args> 60 command! -count -nargs=* -bang Xnext <mods><count>lnext<bang> <args> 61 command! -count -nargs=* -bang Xprev <mods><count>lprev<bang> <args> 62 command! -nargs=* -bang Xfirst <mods>lfirst<bang> <args> 63 command! -nargs=* -bang Xlast <mods>llast<bang> <args> 64 command! -nargs=* -bang -range Xnfile <mods><count>lnfile<bang> <args> 65 command! -nargs=* -bang Xpfile <mods>lpfile<bang> <args> 66 command! -nargs=* Xexpr <mods>lexpr <args> 67 command! -range -nargs=* Xvimgrep <mods><count>lvimgrep <args> 68 command! -nargs=* Xvimgrepadd <mods>lvimgrepadd <args> 69 command! -nargs=* Xgrep <mods> lgrep <args> 70 command! -nargs=* Xgrepadd <mods> lgrepadd <args> 71 command! -nargs=* Xhelpgrep lhelpgrep <args> 72 command! -nargs=0 -count Xcc <count>ll 73 let g:Xgetlist = function('getloclist', [0]) 74 let g:Xsetlist = function('setloclist', [0]) 75 call setloclist(0, [], 'f') 76 endif 77endfunc 78 79" Tests for the :clist and :llist commands 80func XlistTests(cchar) 81 call s:setup_commands(a:cchar) 82 83 if a:cchar == 'l' 84 call assert_fails('llist', 'E776:') 85 endif 86 " With an empty list, command should return error 87 Xgetexpr [] 88 silent! Xlist 89 call assert_true(v:errmsg ==# 'E42: No Errors') 90 91 " Populate the list and then try 92 Xgetexpr ['non-error 1', 'Xtestfile1:1:3:Line1', 93 \ 'non-error 2', 'Xtestfile2:2:2:Line2', 94 \ 'non-error 3', 'Xtestfile3:3:1:Line3'] 95 96 " List only valid entries 97 let l = split(execute('Xlist', ''), "\n") 98 call assert_equal([' 2 Xtestfile1:1 col 3: Line1', 99 \ ' 4 Xtestfile2:2 col 2: Line2', 100 \ ' 6 Xtestfile3:3 col 1: Line3'], l) 101 102 " List all the entries 103 let l = split(execute('Xlist!', ''), "\n") 104 call assert_equal([' 1: non-error 1', ' 2 Xtestfile1:1 col 3: Line1', 105 \ ' 3: non-error 2', ' 4 Xtestfile2:2 col 2: Line2', 106 \ ' 5: non-error 3', ' 6 Xtestfile3:3 col 1: Line3'], l) 107 108 " List a range of errors 109 let l = split(execute('Xlist 3,6', ''), "\n") 110 call assert_equal([' 4 Xtestfile2:2 col 2: Line2', 111 \ ' 6 Xtestfile3:3 col 1: Line3'], l) 112 113 let l = split(execute('Xlist! 3,4', ''), "\n") 114 call assert_equal([' 3: non-error 2', ' 4 Xtestfile2:2 col 2: Line2'], l) 115 116 let l = split(execute('Xlist -6,-4', ''), "\n") 117 call assert_equal([' 2 Xtestfile1:1 col 3: Line1'], l) 118 119 let l = split(execute('Xlist! -5,-3', ''), "\n") 120 call assert_equal([' 2 Xtestfile1:1 col 3: Line1', 121 \ ' 3: non-error 2', ' 4 Xtestfile2:2 col 2: Line2'], l) 122 123 " Test for '+' 124 let l = split(execute('Xlist! +2', ''), "\n") 125 call assert_equal([' 2 Xtestfile1:1 col 3: Line1', 126 \ ' 3: non-error 2', ' 4 Xtestfile2:2 col 2: Line2'], l) 127 128 " Different types of errors 129 call g:Xsetlist([{'lnum':10,'col':5,'type':'W', 'text':'Warning','nr':11}, 130 \ {'lnum':20,'col':10,'type':'e','text':'Error','nr':22}, 131 \ {'lnum':30,'col':15,'type':'i','text':'Info','nr':33}, 132 \ {'lnum':40,'col':20,'type':'x', 'text':'Other','nr':44}, 133 \ {'lnum':50,'col':25,'type':"\<C-A>",'text':'one','nr':55}]) 134 let l = split(execute('Xlist', ""), "\n") 135 call assert_equal([' 1:10 col 5 warning 11: Warning', 136 \ ' 2:20 col 10 error 22: Error', 137 \ ' 3:30 col 15 info 33: Info', 138 \ ' 4:40 col 20 x 44: Other', 139 \ ' 5:50 col 25 55: one'], l) 140 141 " Test for module names, one needs to explicitly set `'valid':v:true` so 142 call g:Xsetlist([ 143 \ {'lnum':10,'col':5,'type':'W','module':'Data.Text','text':'ModuleWarning','nr':11,'valid':v:true}, 144 \ {'lnum':20,'col':10,'type':'W','module':'Data.Text','filename':'Data/Text.hs','text':'ModuleWarning','nr':22,'valid':v:true}, 145 \ {'lnum':30,'col':15,'type':'W','filename':'Data/Text.hs','text':'FileWarning','nr':33,'valid':v:true}]) 146 let l = split(execute('Xlist', ""), "\n") 147 call assert_equal([' 1 Data.Text:10 col 5 warning 11: ModuleWarning', 148 \ ' 2 Data.Text:20 col 10 warning 22: ModuleWarning', 149 \ ' 3 Data/Text.hs:30 col 15 warning 33: FileWarning'], l) 150 151 " Error cases 152 call assert_fails('Xlist abc', 'E488:') 153endfunc 154 155func Test_clist() 156 call XlistTests('c') 157 call XlistTests('l') 158endfunc 159 160" Tests for the :colder, :cnewer, :lolder and :lnewer commands 161" Note that this test assumes that a quickfix/location list is 162" already set by the caller. 163func XageTests(cchar) 164 call s:setup_commands(a:cchar) 165 166 let list = [{'bufnr': bufnr('%'), 'lnum': 1}] 167 call g:Xsetlist(list) 168 169 " Jumping to a non existent list should return error 170 silent! Xolder 99 171 call assert_true(v:errmsg ==# 'E380: At bottom of quickfix stack') 172 173 silent! Xnewer 99 174 call assert_true(v:errmsg ==# 'E381: At top of quickfix stack') 175 176 " Add three quickfix/location lists 177 Xgetexpr ['Xtestfile1:1:3:Line1'] 178 Xgetexpr ['Xtestfile2:2:2:Line2'] 179 Xgetexpr ['Xtestfile3:3:1:Line3'] 180 181 " Go back two lists 182 Xolder 183 let l = g:Xgetlist() 184 call assert_equal('Line2', l[0].text) 185 186 " Go forward two lists 187 Xnewer 188 let l = g:Xgetlist() 189 call assert_equal('Line3', l[0].text) 190 191 " Test for the optional count argument 192 Xolder 2 193 let l = g:Xgetlist() 194 call assert_equal('Line1', l[0].text) 195 196 Xnewer 2 197 let l = g:Xgetlist() 198 call assert_equal('Line3', l[0].text) 199endfunc 200 201func Test_cage() 202 call XageTests('c') 203 call XageTests('l') 204endfunc 205 206" Tests for the :cwindow, :lwindow :cclose, :lclose, :copen and :lopen 207" commands 208func XwindowTests(cchar) 209 call s:setup_commands(a:cchar) 210 211 " Opening the location list window without any errors should fail 212 if a:cchar == 'l' 213 call assert_fails('lopen', 'E776:') 214 endif 215 216 " Create a list with no valid entries 217 Xgetexpr ['non-error 1', 'non-error 2', 'non-error 3'] 218 219 " Quickfix/Location window should not open with no valid errors 220 Xwindow 221 call assert_true(winnr('$') == 1) 222 223 " Create a list with valid entries 224 Xgetexpr ['Xtestfile1:1:3:Line1', 'Xtestfile2:2:2:Line2', 225 \ 'Xtestfile3:3:1:Line3'] 226 227 " Open the window 228 Xwindow 229 call assert_true(winnr('$') == 2 && winnr() == 2 && 230 \ getline('.') ==# 'Xtestfile1|1 col 3| Line1') 231 redraw! 232 233 " Close the window 234 Xclose 235 call assert_true(winnr('$') == 1) 236 237 " Create a list with no valid entries 238 Xgetexpr ['non-error 1', 'non-error 2', 'non-error 3'] 239 240 " Open the window 241 Xopen 5 242 call assert_true(winnr('$') == 2 && getline('.') ==# '|| non-error 1' 243 \ && winheight('.') == 5) 244 245 " Opening the window again, should move the cursor to that window 246 wincmd t 247 Xopen 7 248 call assert_true(winnr('$') == 2 && winnr() == 2 && 249 \ winheight('.') == 7 && 250 \ getline('.') ==# '|| non-error 1') 251 252 253 " Calling cwindow should close the quickfix window with no valid errors 254 Xwindow 255 call assert_true(winnr('$') == 1) 256 257 if a:cchar == 'c' 258 " Opening the quickfix window in multiple tab pages should reuse the 259 " quickfix buffer 260 Xgetexpr ['Xtestfile1:1:3:Line1', 'Xtestfile2:2:2:Line2', 261 \ 'Xtestfile3:3:1:Line3'] 262 Xopen 263 let qfbufnum = bufnr('%') 264 tabnew 265 Xopen 266 call assert_equal(qfbufnum, bufnr('%')) 267 new | only | tabonly 268 endif 269endfunc 270 271func Test_cwindow() 272 call XwindowTests('c') 273 call XwindowTests('l') 274endfunc 275 276" Tests for the :cfile, :lfile, :caddfile, :laddfile, :cgetfile and :lgetfile 277" commands. 278func XfileTests(cchar) 279 call s:setup_commands(a:cchar) 280 281 call writefile(['Xtestfile1:700:10:Line 700', 282 \ 'Xtestfile2:800:15:Line 800'], 'Xqftestfile1') 283 284 enew! 285 Xfile Xqftestfile1 286 let l = g:Xgetlist() 287 call assert_true(len(l) == 2 && 288 \ l[0].lnum == 700 && l[0].col == 10 && l[0].text ==# 'Line 700' && 289 \ l[1].lnum == 800 && l[1].col == 15 && l[1].text ==# 'Line 800') 290 291 " Test with a non existent file 292 call assert_fails('Xfile non_existent_file', 'E40') 293 294 " Run cfile/lfile from a modified buffer 295 enew! 296 silent! put ='Quickfix' 297 silent! Xfile Xqftestfile1 298 call assert_true(v:errmsg ==# 'E37: No write since last change (add ! to override)') 299 300 call writefile(['Xtestfile3:900:30:Line 900'], 'Xqftestfile1') 301 Xaddfile Xqftestfile1 302 let l = g:Xgetlist() 303 call assert_true(len(l) == 3 && 304 \ l[2].lnum == 900 && l[2].col == 30 && l[2].text ==# 'Line 900') 305 306 call writefile(['Xtestfile1:222:77:Line 222', 307 \ 'Xtestfile2:333:88:Line 333'], 'Xqftestfile1') 308 309 enew! 310 Xgetfile Xqftestfile1 311 let l = g:Xgetlist() 312 call assert_true(len(l) == 2 && 313 \ l[0].lnum == 222 && l[0].col == 77 && l[0].text ==# 'Line 222' && 314 \ l[1].lnum == 333 && l[1].col == 88 && l[1].text ==# 'Line 333') 315 316 call delete('Xqftestfile1') 317endfunc 318 319func Test_cfile() 320 call XfileTests('c') 321 call XfileTests('l') 322endfunc 323 324" Tests for the :cbuffer, :lbuffer, :caddbuffer, :laddbuffer, :cgetbuffer and 325" :lgetbuffer commands. 326func XbufferTests(cchar) 327 call s:setup_commands(a:cchar) 328 329 enew! 330 silent! call setline(1, ['Xtestfile7:700:10:Line 700', 331 \ 'Xtestfile8:800:15:Line 800']) 332 Xbuffer! 333 let l = g:Xgetlist() 334 call assert_true(len(l) == 2 && 335 \ l[0].lnum == 700 && l[0].col == 10 && l[0].text ==# 'Line 700' && 336 \ l[1].lnum == 800 && l[1].col == 15 && l[1].text ==# 'Line 800') 337 338 enew! 339 silent! call setline(1, ['Xtestfile9:900:55:Line 900', 340 \ 'Xtestfile10:950:66:Line 950']) 341 Xgetbuffer 342 let l = g:Xgetlist() 343 call assert_true(len(l) == 2 && 344 \ l[0].lnum == 900 && l[0].col == 55 && l[0].text ==# 'Line 900' && 345 \ l[1].lnum == 950 && l[1].col == 66 && l[1].text ==# 'Line 950') 346 347 enew! 348 silent! call setline(1, ['Xtestfile11:700:20:Line 700', 349 \ 'Xtestfile12:750:25:Line 750']) 350 Xaddbuffer 351 let l = g:Xgetlist() 352 call assert_true(len(l) == 4 && 353 \ l[1].lnum == 950 && l[1].col == 66 && l[1].text ==# 'Line 950' && 354 \ l[2].lnum == 700 && l[2].col == 20 && l[2].text ==# 'Line 700' && 355 \ l[3].lnum == 750 && l[3].col == 25 && l[3].text ==# 'Line 750') 356 enew! 357 358 " Check for invalid buffer 359 call assert_fails('Xbuffer 199', 'E474:') 360 361 " Check for unloaded buffer 362 edit Xtestfile1 363 let bnr = bufnr('%') 364 enew! 365 call assert_fails('Xbuffer ' . bnr, 'E681:') 366 367 " Check for invalid range 368 " Using Xbuffer will not run the range check in the cbuffer/lbuffer 369 " commands. So directly call the commands. 370 if (a:cchar == 'c') 371 call assert_fails('900,999cbuffer', 'E16:') 372 else 373 call assert_fails('900,999lbuffer', 'E16:') 374 endif 375endfunc 376 377func Test_cbuffer() 378 call XbufferTests('c') 379 call XbufferTests('l') 380endfunc 381 382func XexprTests(cchar) 383 call s:setup_commands(a:cchar) 384 385 call assert_fails('Xexpr 10', 'E777:') 386endfunc 387 388func Test_cexpr() 389 call XexprTests('c') 390 call XexprTests('l') 391endfunc 392 393" Tests for :cnext, :cprev, :cfirst, :clast commands 394func Xtest_browse(cchar) 395 call s:setup_commands(a:cchar) 396 397 call g:Xsetlist([], 'f') 398 " Jumping to first or next location list entry without any error should 399 " result in failure 400 if a:cchar == 'c' 401 let err = 'E42:' 402 else 403 let err = 'E776:' 404 endif 405 call assert_fails('Xnext', err) 406 call assert_fails('Xprev', err) 407 call assert_fails('Xnfile', err) 408 call assert_fails('Xpfile', err) 409 410 call s:create_test_file('Xqftestfile1') 411 call s:create_test_file('Xqftestfile2') 412 413 Xgetexpr ['Xqftestfile1:5:Line5', 414 \ 'Xqftestfile1:6:Line6', 415 \ 'Xqftestfile2:10:Line10', 416 \ 'Xqftestfile2:11:Line11', 417 \ 'RegularLine1', 418 \ 'RegularLine2'] 419 420 Xfirst 421 call assert_fails('Xprev', 'E553') 422 call assert_fails('Xpfile', 'E553') 423 Xnfile 424 call assert_equal('Xqftestfile2', bufname('%')) 425 call assert_equal(10, line('.')) 426 Xpfile 427 call assert_equal('Xqftestfile1', bufname('%')) 428 call assert_equal(6, line('.')) 429 5Xcc 430 call assert_equal(5, g:Xgetlist({'idx':0}).idx) 431 2Xcc 432 call assert_equal(2, g:Xgetlist({'idx':0}).idx) 433 10Xcc 434 call assert_equal(6, g:Xgetlist({'idx':0}).idx) 435 Xlast 436 Xprev 437 call assert_equal('Xqftestfile2', bufname('%')) 438 call assert_equal(11, line('.')) 439 call assert_fails('Xnext', 'E553') 440 call assert_fails('Xnfile', 'E553') 441 Xrewind 442 call assert_equal('Xqftestfile1', bufname('%')) 443 call assert_equal(5, line('.')) 444 445 10Xnext 446 call assert_equal('Xqftestfile2', bufname('%')) 447 call assert_equal(11, line('.')) 448 10Xprev 449 call assert_equal('Xqftestfile1', bufname('%')) 450 call assert_equal(5, line('.')) 451 452 " Jumping to an error from the error window using cc command 453 Xgetexpr ['Xqftestfile1:5:Line5', 454 \ 'Xqftestfile1:6:Line6', 455 \ 'Xqftestfile2:10:Line10', 456 \ 'Xqftestfile2:11:Line11'] 457 Xopen 458 10Xcc 459 call assert_equal(11, line('.')) 460 call assert_equal('Xqftestfile2', bufname('%')) 461 462 " Jumping to an error from the error window (when only the error window is 463 " present) 464 Xopen | only 465 Xlast 1 466 call assert_equal(5, line('.')) 467 call assert_equal('Xqftestfile1', bufname('%')) 468 469 Xexpr "" 470 call assert_fails('Xnext', 'E42:') 471 472 call delete('Xqftestfile1') 473 call delete('Xqftestfile2') 474 475 " Should be able to use next/prev with invalid entries 476 Xexpr "" 477 call assert_equal(0, g:Xgetlist({'idx' : 0}).idx) 478 call assert_equal(0, g:Xgetlist({'size' : 0}).size) 479 Xaddexpr ['foo', 'bar', 'baz', 'quux', 'shmoo'] 480 call assert_equal(5, g:Xgetlist({'size' : 0}).size) 481 Xlast 482 call assert_equal(5, g:Xgetlist({'idx' : 0}).idx) 483 Xfirst 484 call assert_equal(1, g:Xgetlist({'idx' : 0}).idx) 485 2Xnext 486 call assert_equal(3, g:Xgetlist({'idx' : 0}).idx) 487endfunc 488 489func Test_browse() 490 call Xtest_browse('c') 491 call Xtest_browse('l') 492endfunc 493 494func Test_nomem() 495 call test_alloc_fail(GetAllocId('qf_dirname_start'), 0, 0) 496 call assert_fails('vimgrep vim runtest.vim', 'E342:') 497 498 call test_alloc_fail(GetAllocId('qf_dirname_now'), 0, 0) 499 call assert_fails('vimgrep vim runtest.vim', 'E342:') 500 501 call test_alloc_fail(GetAllocId('qf_namebuf'), 0, 0) 502 call assert_fails('cfile runtest.vim', 'E342:') 503 504 call test_alloc_fail(GetAllocId('qf_errmsg'), 0, 0) 505 call assert_fails('cfile runtest.vim', 'E342:') 506 507 call test_alloc_fail(GetAllocId('qf_pattern'), 0, 0) 508 call assert_fails('cfile runtest.vim', 'E342:') 509 510endfunc 511 512func s:test_xhelpgrep(cchar) 513 call s:setup_commands(a:cchar) 514 Xhelpgrep quickfix 515 Xopen 516 if a:cchar == 'c' 517 let title_text = ':helpgrep quickfix' 518 else 519 let title_text = ':lhelpgrep quickfix' 520 endif 521 call assert_true(w:quickfix_title =~ title_text, w:quickfix_title) 522 523 " Jumping to a help topic should open the help window 524 only 525 Xnext 526 call assert_true(&buftype == 'help') 527 call assert_true(winnr('$') == 2) 528 " Jumping to the next match should reuse the help window 529 Xnext 530 call assert_true(&buftype == 'help') 531 call assert_true(winnr() == 1) 532 call assert_true(winnr('$') == 2) 533 " Jumping to the next match from the quickfix window should reuse the help 534 " window 535 Xopen 536 Xnext 537 call assert_true(&buftype == 'help') 538 call assert_true(winnr() == 1) 539 call assert_true(winnr('$') == 2) 540 541 " This wipes out the buffer, make sure that doesn't cause trouble. 542 Xclose 543 544 if a:cchar == 'l' 545 " When a help window is present, running :lhelpgrep should reuse the 546 " help window and not the current window 547 new | only 548 call g:Xsetlist([], 'f') 549 help index.txt 550 wincmd w 551 lhelpgrep quickfix 552 call assert_equal(1, winnr()) 553 call assert_notequal([], getloclist(1)) 554 call assert_equal([], getloclist(2)) 555 endif 556 557 new | only 558 559 " Search for non existing help string 560 call assert_fails('Xhelpgrep a1b2c3', 'E480:') 561endfunc 562 563func Test_helpgrep() 564 call s:test_xhelpgrep('c') 565 helpclose 566 call s:test_xhelpgrep('l') 567endfunc 568 569func Test_errortitle() 570 augroup QfBufWinEnter 571 au! 572 au BufWinEnter * :let g:a=get(w:, 'quickfix_title', 'NONE') 573 augroup END 574 copen 575 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'')'}] 576 call setqflist(a) 577 call assert_equal(':setqflist()', g:a) 578 augroup QfBufWinEnter 579 au! 580 augroup END 581 augroup! QfBufWinEnter 582endfunc 583 584func Test_vimgreptitle() 585 augroup QfBufWinEnter 586 au! 587 au BufWinEnter * :let g:a=get(w:, 'quickfix_title', 'NONE') 588 augroup END 589 try 590 vimgrep /pattern/j file 591 catch /E480/ 592 endtry 593 copen 594 call assert_equal(': vimgrep /pattern/j file', g:a) 595 augroup QfBufWinEnter 596 au! 597 augroup END 598 augroup! QfBufWinEnter 599endfunc 600 601func XqfTitleTests(cchar) 602 call s:setup_commands(a:cchar) 603 604 Xgetexpr ['file:1:1:message'] 605 let l = g:Xgetlist() 606 if a:cchar == 'c' 607 call setqflist(l, 'r') 608 else 609 call setloclist(0, l, 'r') 610 endif 611 612 Xopen 613 if a:cchar == 'c' 614 let title = ':setqflist()' 615 else 616 let title = ':setloclist()' 617 endif 618 call assert_equal(title, w:quickfix_title) 619 Xclose 620endfunc 621 622" Tests for quickfix window's title 623func Test_qf_title() 624 call XqfTitleTests('c') 625 call XqfTitleTests('l') 626endfunc 627 628" Tests for 'errorformat' 629func Test_efm() 630 let save_efm = &efm 631 set efm=%EEEE%m,%WWWW%m,%+CCCC%.%#,%-GGGG%.%# 632 cgetexpr ['WWWW', 'EEEE', 'CCCC'] 633 let l = strtrans(string(map(getqflist(), '[v:val.text, v:val.valid]'))) 634 call assert_equal("[['W', 1], ['E^@CCCC', 1]]", l) 635 cgetexpr ['WWWW', 'GGGG', 'EEEE', 'CCCC'] 636 let l = strtrans(string(map(getqflist(), '[v:val.text, v:val.valid]'))) 637 call assert_equal("[['W', 1], ['E^@CCCC', 1]]", l) 638 cgetexpr ['WWWW', 'GGGG', 'ZZZZ', 'EEEE', 'CCCC', 'YYYY'] 639 let l = strtrans(string(map(getqflist(), '[v:val.text, v:val.valid]'))) 640 call assert_equal("[['W', 1], ['ZZZZ', 0], ['E^@CCCC', 1], ['YYYY', 0]]", l) 641 let &efm = save_efm 642endfunc 643 644" This will test for problems in quickfix: 645" A. incorrectly copying location lists which caused the location list to show 646" a different name than the file that was actually being displayed. 647" B. not reusing the window for which the location list window is opened but 648" instead creating new windows. 649" C. make sure that the location list window is not reused instead of the 650" window it belongs to. 651" 652" Set up the test environment: 653func ReadTestProtocol(name) 654 let base = substitute(a:name, '\v^test://(.*)%(\.[^.]+)?', '\1', '') 655 let word = substitute(base, '\v(.*)\..*', '\1', '') 656 657 setl modifiable 658 setl noreadonly 659 setl noswapfile 660 setl bufhidden=delete 661 %del _ 662 " For problem 2: 663 " 'buftype' has to be set to reproduce the constant opening of new windows 664 setl buftype=nofile 665 666 call setline(1, word) 667 668 setl nomodified 669 setl nomodifiable 670 setl readonly 671 exe 'doautocmd BufRead ' . substitute(a:name, '\v^test://(.*)', '\1', '') 672endfunc 673 674func Test_locationlist() 675 enew 676 677 augroup testgroup 678 au! 679 autocmd BufReadCmd test://* call ReadTestProtocol(expand("<amatch>")) 680 augroup END 681 682 let words = [ "foo", "bar", "baz", "quux", "shmoo", "spam", "eggs" ] 683 684 let qflist = [] 685 for word in words 686 call add(qflist, {'filename': 'test://' . word . '.txt', 'text': 'file ' . word . '.txt', }) 687 " NOTE: problem 1: 688 " intentionally not setting 'lnum' so that the quickfix entries are not 689 " valid 690 call setloclist(0, qflist, ' ') 691 endfor 692 693 " Test A 694 lrewind 695 enew 696 lopen 697 4lnext 698 vert split 699 wincmd L 700 lopen 701 wincmd p 702 lnext 703 let fileName = expand("%") 704 wincmd p 705 let locationListFileName = substitute(getline(line('.')), '\([^|]*\)|.*', '\1', '') 706 let fileName = substitute(fileName, '\\', '/', 'g') 707 let locationListFileName = substitute(locationListFileName, '\\', '/', 'g') 708 call assert_equal("test://bar.txt", fileName) 709 call assert_equal("test://bar.txt", locationListFileName) 710 711 wincmd n | only 712 713 " Test B: 714 lrewind 715 lopen 716 2 717 exe "normal \<CR>" 718 wincmd p 719 3 720 exe "normal \<CR>" 721 wincmd p 722 4 723 exe "normal \<CR>" 724 call assert_equal(2, winnr('$')) 725 wincmd n | only 726 727 " Test C: 728 lrewind 729 lopen 730 " Let's move the location list window to the top to check whether it (the 731 " first window found) will be reused when we try to open new windows: 732 wincmd K 733 2 734 exe "normal \<CR>" 735 wincmd p 736 3 737 exe "normal \<CR>" 738 wincmd p 739 4 740 exe "normal \<CR>" 741 1wincmd w 742 call assert_equal('quickfix', &buftype) 743 2wincmd w 744 let bufferName = expand("%") 745 let bufferName = substitute(bufferName, '\\', '/', 'g') 746 call assert_equal('test://quux.txt', bufferName) 747 748 wincmd n | only 749 750 augroup! testgroup 751endfunc 752 753func Test_locationlist_curwin_was_closed() 754 augroup testgroup 755 au! 756 autocmd BufReadCmd test_curwin.txt call R(expand("<amatch>")) 757 augroup END 758 759 func! R(n) 760 quit 761 endfunc 762 763 new 764 let q = [] 765 call add(q, {'filename': 'test_curwin.txt' }) 766 call setloclist(0, q) 767 call assert_fails('lrewind', 'E924:') 768 769 augroup! testgroup 770endfunc 771 772func Test_locationlist_cross_tab_jump() 773 call writefile(['loclistfoo'], 'loclistfoo') 774 call writefile(['loclistbar'], 'loclistbar') 775 set switchbuf=usetab 776 777 edit loclistfoo 778 tabedit loclistbar 779 silent lgrep loclistfoo loclist* 780 call assert_equal(1, tabpagenr()) 781 782 enew | only | tabonly 783 set switchbuf&vim 784 call delete('loclistfoo') 785 call delete('loclistbar') 786endfunc 787 788" More tests for 'errorformat' 789func Test_efm1() 790 if !has('unix') 791 " The 'errorformat' setting is different on non-Unix systems. 792 " This test works only on Unix-like systems. 793 return 794 endif 795 796 let l = [ 797 \ '"Xtestfile", line 4.12: 1506-045 (S) Undeclared identifier fd_set.', 798 \ '"Xtestfile", line 6 col 19; this is an error', 799 \ 'gcc -c -DHAVE_CONFIsing-prototypes -I/usr/X11R6/include version.c', 800 \ 'Xtestfile:9: parse error before `asd''', 801 \ 'make: *** [vim] Error 1', 802 \ 'in file "Xtestfile" linenr 10: there is an error', 803 \ '', 804 \ '2 returned', 805 \ '"Xtestfile", line 11 col 1; this is an error', 806 \ '"Xtestfile", line 12 col 2; this is another error', 807 \ '"Xtestfile", line 14:10; this is an error in column 10', 808 \ '=Xtestfile=, line 15:10; this is another error, but in vcol 10 this time', 809 \ '"Xtestfile", linenr 16: yet another problem', 810 \ 'Error in "Xtestfile" at line 17:', 811 \ 'x should be a dot', 812 \ ' xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 17', 813 \ ' ^', 814 \ 'Error in "Xtestfile" at line 18:', 815 \ 'x should be a dot', 816 \ ' xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 18', 817 \ '.............^', 818 \ 'Error in "Xtestfile" at line 19:', 819 \ 'x should be a dot', 820 \ ' xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 19', 821 \ '--------------^', 822 \ 'Error in "Xtestfile" at line 20:', 823 \ 'x should be a dot', 824 \ ' xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 20', 825 \ ' ^', 826 \ '', 827 \ 'Does anyone know what is the problem and how to correction it?', 828 \ '"Xtestfile", line 21 col 9: What is the title of the quickfix window?', 829 \ '"Xtestfile", line 22 col 9: What is the title of the quickfix window?' 830 \ ] 831 832 call writefile(l, 'Xerrorfile1') 833 call writefile(l[:-2], 'Xerrorfile2') 834 835 let m = [ 836 \ ' xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 2', 837 \ ' xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 3', 838 \ ' xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 4', 839 \ ' xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 5', 840 \ ' xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 6', 841 \ ' xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 7', 842 \ ' xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 8', 843 \ ' xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 9', 844 \ ' xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 10', 845 \ ' xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 11', 846 \ ' xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 12', 847 \ ' xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 13', 848 \ ' xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 14', 849 \ ' xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 15', 850 \ ' xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 16', 851 \ ' xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 17', 852 \ ' xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 18', 853 \ ' xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 19', 854 \ ' xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 20', 855 \ ' xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 21', 856 \ ' xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 22' 857 \ ] 858 call writefile(m, 'Xtestfile') 859 860 let save_efm = &efm 861 set efm+==%f=\\,\ line\ %l%*\\D%v%*[^\ ]\ %m 862 set efm^=%AError\ in\ \"%f\"\ at\ line\ %l:,%Z%p^,%C%m 863 864 exe 'cf Xerrorfile2' 865 clast 866 copen 867 call assert_equal(':cf Xerrorfile2', w:quickfix_title) 868 wincmd p 869 870 exe 'cf Xerrorfile1' 871 call assert_equal([4, 12], [line('.'), col('.')]) 872 cn 873 call assert_equal([6, 19], [line('.'), col('.')]) 874 cn 875 call assert_equal([9, 2], [line('.'), col('.')]) 876 cn 877 call assert_equal([10, 2], [line('.'), col('.')]) 878 cn 879 call assert_equal([11, 1], [line('.'), col('.')]) 880 cn 881 call assert_equal([12, 2], [line('.'), col('.')]) 882 cn 883 call assert_equal([14, 10], [line('.'), col('.')]) 884 cn 885 call assert_equal([15, 3, 10], [line('.'), col('.'), virtcol('.')]) 886 cn 887 call assert_equal([16, 2], [line('.'), col('.')]) 888 cn 889 call assert_equal([17, 6], [line('.'), col('.')]) 890 cn 891 call assert_equal([18, 7], [line('.'), col('.')]) 892 cn 893 call assert_equal([19, 8], [line('.'), col('.')]) 894 cn 895 call assert_equal([20, 9], [line('.'), col('.')]) 896 clast 897 cprev 898 cprev 899 wincmd w 900 call assert_equal(':cf Xerrorfile1', w:quickfix_title) 901 wincmd p 902 903 let &efm = save_efm 904 call delete('Xerrorfile1') 905 call delete('Xerrorfile2') 906 call delete('Xtestfile') 907endfunc 908 909" Test for quickfix directory stack support 910func s:dir_stack_tests(cchar) 911 call s:setup_commands(a:cchar) 912 913 let save_efm=&efm 914 set efm=%DEntering\ dir\ '%f',%f:%l:%m,%XLeaving\ dir\ '%f' 915 916 let lines = ["Entering dir 'dir1/a'", 917 \ 'habits2.txt:1:Nine Healthy Habits', 918 \ "Entering dir 'b'", 919 \ 'habits3.txt:2:0 Hours of television', 920 \ 'habits2.txt:7:5 Small meals', 921 \ "Entering dir 'dir1/c'", 922 \ 'habits4.txt:3:1 Hour of exercise', 923 \ "Leaving dir 'dir1/c'", 924 \ "Leaving dir 'dir1/a'", 925 \ 'habits1.txt:4:2 Liters of water', 926 \ "Entering dir 'dir2'", 927 \ 'habits5.txt:5:3 Cups of hot green tea', 928 \ "Leaving dir 'dir2'" 929 \] 930 931 Xexpr "" 932 for l in lines 933 Xaddexpr l 934 endfor 935 936 let qf = g:Xgetlist() 937 938 call assert_equal('dir1/a/habits2.txt', bufname(qf[1].bufnr)) 939 call assert_equal(1, qf[1].lnum) 940 call assert_equal('dir1/a/b/habits3.txt', bufname(qf[3].bufnr)) 941 call assert_equal(2, qf[3].lnum) 942 call assert_equal('dir1/a/habits2.txt', bufname(qf[4].bufnr)) 943 call assert_equal(7, qf[4].lnum) 944 call assert_equal('dir1/c/habits4.txt', bufname(qf[6].bufnr)) 945 call assert_equal(3, qf[6].lnum) 946 call assert_equal('habits1.txt', bufname(qf[9].bufnr)) 947 call assert_equal(4, qf[9].lnum) 948 call assert_equal('dir2/habits5.txt', bufname(qf[11].bufnr)) 949 call assert_equal(5, qf[11].lnum) 950 951 let &efm=save_efm 952endfunc 953 954" Tests for %D and %X errorformat options 955func Test_efm_dirstack() 956 " Create the directory stack and files 957 call mkdir('dir1') 958 call mkdir('dir1/a') 959 call mkdir('dir1/a/b') 960 call mkdir('dir1/c') 961 call mkdir('dir2') 962 963 let lines = ["Nine Healthy Habits", 964 \ "0 Hours of television", 965 \ "1 Hour of exercise", 966 \ "2 Liters of water", 967 \ "3 Cups of hot green tea", 968 \ "4 Short mental breaks", 969 \ "5 Small meals", 970 \ "6 AM wake up time", 971 \ "7 Minutes of laughter", 972 \ "8 Hours of sleep (at least)", 973 \ "9 PM end of the day and off to bed" 974 \ ] 975 call writefile(lines, 'habits1.txt') 976 call writefile(lines, 'dir1/a/habits2.txt') 977 call writefile(lines, 'dir1/a/b/habits3.txt') 978 call writefile(lines, 'dir1/c/habits4.txt') 979 call writefile(lines, 'dir2/habits5.txt') 980 981 call s:dir_stack_tests('c') 982 call s:dir_stack_tests('l') 983 984 call delete('dir1', 'rf') 985 call delete('dir2', 'rf') 986 call delete('habits1.txt') 987endfunc 988 989" Test for resync after continuing an ignored message 990func Xefm_ignore_continuations(cchar) 991 call s:setup_commands(a:cchar) 992 993 let save_efm = &efm 994 995 let &efm = 996 \ '%Eerror %m %l,' . 997 \ '%-Wignored %m %l,' . 998 \ '%+Cmore ignored %m %l,' . 999 \ '%Zignored end' 1000 Xgetexpr ['ignored warning 1', 'more ignored continuation 2', 'ignored end', 'error resync 4'] 1001 let l = map(g:Xgetlist(), '[v:val.text, v:val.valid, v:val.lnum, v:val.type]') 1002 call assert_equal([['resync', 1, 4, 'E']], l) 1003 1004 let &efm = save_efm 1005endfunc 1006 1007func Test_efm_ignore_continuations() 1008 call Xefm_ignore_continuations('c') 1009 call Xefm_ignore_continuations('l') 1010endfunc 1011 1012" Tests for invalid error format specifies 1013func Xinvalid_efm_Tests(cchar) 1014 call s:setup_commands(a:cchar) 1015 1016 let save_efm = &efm 1017 1018 set efm=%f:%l:%m,%f:%f:%l:%m 1019 call assert_fails('Xexpr "abc.txt:1:Hello world"', 'E372:') 1020 1021 set efm=%f:%l:%m,%f:%l:%r:%m 1022 call assert_fails('Xexpr "abc.txt:1:Hello world"', 'E373:') 1023 1024 set efm=%f:%l:%m,%O:%f:%l:%m 1025 call assert_fails('Xexpr "abc.txt:1:Hello world"', 'E373:') 1026 1027 set efm=%f:%l:%m,%f:%l:%*[^a-z 1028 call assert_fails('Xexpr "abc.txt:1:Hello world"', 'E374:') 1029 1030 set efm=%f:%l:%m,%f:%l:%*c 1031 call assert_fails('Xexpr "abc.txt:1:Hello world"', 'E375:') 1032 1033 set efm=%f:%l:%m,%L%M%N 1034 call assert_fails('Xexpr "abc.txt:1:Hello world"', 'E376:') 1035 1036 set efm=%f:%l:%m,%f:%l:%m:%R 1037 call assert_fails('Xexpr "abc.txt:1:Hello world"', 'E377:') 1038 1039 set efm= 1040 call assert_fails('Xexpr "abc.txt:1:Hello world"', 'E378:') 1041 1042 set efm=%DEntering\ dir\ abc,%f:%l:%m 1043 call assert_fails('Xexpr ["Entering dir abc", "abc.txt:1:Hello world"]', 'E379:') 1044 1045 let &efm = save_efm 1046endfunc 1047 1048func Test_invalid_efm() 1049 call Xinvalid_efm_Tests('c') 1050 call Xinvalid_efm_Tests('l') 1051endfunc 1052 1053" TODO: 1054" Add tests for the following formats in 'errorformat' 1055" %r %O 1056func Test_efm2() 1057 let save_efm = &efm 1058 1059 " Test for %s format in efm 1060 set efm=%f:%s 1061 cexpr 'Xtestfile:Line search text' 1062 let l = getqflist() 1063 call assert_equal(l[0].pattern, '^\VLine search text\$') 1064 call assert_equal(l[0].lnum, 0) 1065 1066 let l = split(execute('clist', ''), "\n") 1067 call assert_equal([' 1 Xtestfile:^\VLine search text\$: '], l) 1068 1069 " Test for %P, %Q and %t format specifiers 1070 let lines=["[Xtestfile1]", 1071 \ "(1,17) error: ';' missing", 1072 \ "(21,2) warning: variable 'z' not defined", 1073 \ "(67,3) error: end of file found before string ended", 1074 \ "--", 1075 \ "", 1076 \ "[Xtestfile2]", 1077 \ "--", 1078 \ "", 1079 \ "[Xtestfile3]", 1080 \ "NEW compiler v1.1", 1081 \ "(2,2) warning: variable 'x' not defined", 1082 \ "(67,3) warning: 's' already defined", 1083 \ "--" 1084 \] 1085 set efm=%+P[%f]%r,(%l\\,%c)%*[\ ]%t%*[^:]:\ %m,%+Q--%r 1086 " To exercise the push/pop file functionality in quickfix, the test files 1087 " need to be created. 1088 call writefile(['Line1'], 'Xtestfile1') 1089 call writefile(['Line2'], 'Xtestfile2') 1090 call writefile(['Line3'], 'Xtestfile3') 1091 cexpr "" 1092 for l in lines 1093 caddexpr l 1094 endfor 1095 let l = getqflist() 1096 call assert_equal(12, len(l)) 1097 call assert_equal(21, l[2].lnum) 1098 call assert_equal(2, l[2].col) 1099 call assert_equal('w', l[2].type) 1100 call assert_equal('e', l[3].type) 1101 call delete('Xtestfile1') 1102 call delete('Xtestfile2') 1103 call delete('Xtestfile3') 1104 1105 " Tests for %E, %C and %Z format specifiers 1106 let lines = ["Error 275", 1107 \ "line 42", 1108 \ "column 3", 1109 \ "' ' expected after '--'" 1110 \] 1111 set efm=%EError\ %n,%Cline\ %l,%Ccolumn\ %c,%Z%m 1112 cgetexpr lines 1113 let l = getqflist() 1114 call assert_equal(275, l[0].nr) 1115 call assert_equal(42, l[0].lnum) 1116 call assert_equal(3, l[0].col) 1117 call assert_equal('E', l[0].type) 1118 call assert_equal("\n' ' expected after '--'", l[0].text) 1119 1120 " Test for %> 1121 let lines = ["Error in line 147 of foo.c:", 1122 \"unknown variable 'i'" 1123 \] 1124 set efm=unknown\ variable\ %m,%E%>Error\ in\ line\ %l\ of\ %f:,%Z%m 1125 cgetexpr lines 1126 let l = getqflist() 1127 call assert_equal(147, l[0].lnum) 1128 call assert_equal('E', l[0].type) 1129 call assert_equal("\nunknown variable 'i'", l[0].text) 1130 1131 " Test for %A, %C and other formats 1132 let lines = [ 1133 \"==============================================================", 1134 \"FAIL: testGetTypeIdCachesResult (dbfacadeTest.DjsDBFacadeTest)", 1135 \"--------------------------------------------------------------", 1136 \"Traceback (most recent call last):", 1137 \' File "unittests/dbfacadeTest.py", line 89, in testFoo', 1138 \" self.assertEquals(34, dtid)", 1139 \' File "/usr/lib/python2.2/unittest.py", line 286, in', 1140 \" failUnlessEqual", 1141 \" raise self.failureException, \\", 1142 \"AssertionError: 34 != 33", 1143 \"", 1144 \"--------------------------------------------------------------", 1145 \"Ran 27 tests in 0.063s" 1146 \] 1147 set efm=%C\ %.%#,%A\ \ File\ \"%f\"\\,\ line\ %l%.%#,%Z%[%^\ ]%\\@=%m 1148 cgetexpr lines 1149 let l = getqflist() 1150 call assert_equal(8, len(l)) 1151 call assert_equal(89, l[4].lnum) 1152 call assert_equal(1, l[4].valid) 1153 call assert_equal('unittests/dbfacadeTest.py', bufname(l[4].bufnr)) 1154 1155 " Test for %o 1156 set efm=%f(%o):%l\ %m 1157 cgetexpr ['Xotestfile(Language.PureScript.Types):20 Error'] 1158 call writefile(['Line1'], 'Xotestfile') 1159 let l = getqflist() 1160 call assert_equal(1, len(l), string(l)) 1161 call assert_equal('Language.PureScript.Types', l[0].module) 1162 copen 1163 call assert_equal('Language.PureScript.Types|20| Error', getline(1)) 1164 call feedkeys("\<CR>", 'xn') 1165 call assert_equal('Xotestfile', expand('%:t')) 1166 cclose 1167 bd 1168 call delete("Xotestfile") 1169 1170 " The following sequence of commands used to crash Vim 1171 set efm=%W%m 1172 cgetexpr ['msg1'] 1173 let l = getqflist() 1174 call assert_equal(1, len(l), string(l)) 1175 call assert_equal('msg1', l[0].text) 1176 set efm=%C%m 1177 lexpr 'msg2' 1178 let l = getloclist(0) 1179 call assert_equal(1, len(l), string(l)) 1180 call assert_equal('msg2', l[0].text) 1181 lopen 1182 call setqflist([], 'r') 1183 caddbuf 1184 let l = getqflist() 1185 call assert_equal(1, len(l), string(l)) 1186 call assert_equal('|| msg2', l[0].text) 1187 1188 new | only 1189 let &efm = save_efm 1190endfunc 1191 1192func XquickfixChangedByAutocmd(cchar) 1193 call s:setup_commands(a:cchar) 1194 if a:cchar == 'c' 1195 let ErrorNr = 'E925' 1196 func! ReadFunc() 1197 colder 1198 cgetexpr [] 1199 endfunc 1200 else 1201 let ErrorNr = 'E926' 1202 func! ReadFunc() 1203 lolder 1204 lgetexpr [] 1205 endfunc 1206 endif 1207 1208 augroup testgroup 1209 au! 1210 autocmd BufReadCmd test_changed.txt call ReadFunc() 1211 augroup END 1212 1213 new | only 1214 let words = [ "a", "b" ] 1215 let qflist = [] 1216 for word in words 1217 call add(qflist, {'filename': 'test_changed.txt'}) 1218 call g:Xsetlist(qflist, ' ') 1219 endfor 1220 call assert_fails('Xrewind', ErrorNr . ':') 1221 1222 augroup! testgroup 1223endfunc 1224 1225func Test_quickfix_was_changed_by_autocmd() 1226 call XquickfixChangedByAutocmd('c') 1227 call XquickfixChangedByAutocmd('l') 1228endfunc 1229 1230func Test_caddbuffer_to_empty() 1231 helpgr quickfix 1232 call setqflist([], 'r') 1233 cad 1234 try 1235 cn 1236 catch 1237 " number of matches is unknown 1238 call assert_true(v:exception =~ 'E553:') 1239 endtry 1240 quit! 1241endfunc 1242 1243func Test_cgetexpr_works() 1244 " this must not crash Vim 1245 cgetexpr [$x] 1246 lgetexpr [$x] 1247endfunc 1248 1249" Tests for the setqflist() and setloclist() functions 1250func SetXlistTests(cchar, bnum) 1251 call s:setup_commands(a:cchar) 1252 1253 call g:Xsetlist([{'bufnr': a:bnum, 'lnum': 1}, 1254 \ {'bufnr': a:bnum, 'lnum': 2}]) 1255 let l = g:Xgetlist() 1256 call assert_equal(2, len(l)) 1257 call assert_equal(2, l[1].lnum) 1258 1259 Xnext 1260 call g:Xsetlist([{'bufnr': a:bnum, 'lnum': 3}], 'a') 1261 let l = g:Xgetlist() 1262 call assert_equal(3, len(l)) 1263 Xnext 1264 call assert_equal(3, line('.')) 1265 1266 " Appending entries to the list should not change the cursor position 1267 " in the quickfix window 1268 Xwindow 1269 1 1270 call g:Xsetlist([{'bufnr': a:bnum, 'lnum': 4}, 1271 \ {'bufnr': a:bnum, 'lnum': 5}], 'a') 1272 call assert_equal(1, line('.')) 1273 close 1274 1275 call g:Xsetlist([{'bufnr': a:bnum, 'lnum': 3}, 1276 \ {'bufnr': a:bnum, 'lnum': 4}, 1277 \ {'bufnr': a:bnum, 'lnum': 5}], 'r') 1278 let l = g:Xgetlist() 1279 call assert_equal(3, len(l)) 1280 call assert_equal(5, l[2].lnum) 1281 1282 call g:Xsetlist([]) 1283 let l = g:Xgetlist() 1284 call assert_equal(0, len(l)) 1285 1286 " Tests for setting the 'valid' flag 1287 call g:Xsetlist([{'bufnr':a:bnum, 'lnum':4, 'valid':0}]) 1288 Xwindow 1289 call assert_equal(1, winnr('$')) 1290 let l = g:Xgetlist() 1291 call g:Xsetlist(l) 1292 call assert_equal(0, g:Xgetlist()[0].valid) 1293 call g:Xsetlist([{'text':'Text1', 'valid':1}]) 1294 Xwindow 1295 call assert_equal(2, winnr('$')) 1296 Xclose 1297 let save_efm = &efm 1298 set efm=%m 1299 Xgetexpr 'TestMessage' 1300 let l = g:Xgetlist() 1301 call g:Xsetlist(l) 1302 call assert_equal(1, g:Xgetlist()[0].valid) 1303 let &efm = save_efm 1304 1305 " Error cases: 1306 " Refer to a non-existing buffer and pass a non-dictionary type 1307 call assert_fails("call g:Xsetlist([{'bufnr':998, 'lnum':4}," . 1308 \ " {'bufnr':999, 'lnum':5}])", 'E92:') 1309 call g:Xsetlist([[1, 2,3]]) 1310 call assert_equal(0, len(g:Xgetlist())) 1311endfunc 1312 1313func Test_setqflist() 1314 new Xtestfile | only 1315 let bnum = bufnr('%') 1316 call setline(1, range(1,5)) 1317 1318 call SetXlistTests('c', bnum) 1319 call SetXlistTests('l', bnum) 1320 1321 enew! 1322 call delete('Xtestfile') 1323endfunc 1324 1325func Xlist_empty_middle(cchar) 1326 call s:setup_commands(a:cchar) 1327 1328 " create three quickfix lists 1329 let @/ = 'Test_' 1330 Xvimgrep // test_quickfix.vim 1331 let testlen = len(g:Xgetlist()) 1332 call assert_true(testlen > 0) 1333 Xvimgrep empty test_quickfix.vim 1334 call assert_true(len(g:Xgetlist()) > 0) 1335 Xvimgrep matches test_quickfix.vim 1336 let matchlen = len(g:Xgetlist()) 1337 call assert_true(matchlen > 0) 1338 Xolder 1339 " make the middle list empty 1340 call g:Xsetlist([], 'r') 1341 call assert_true(len(g:Xgetlist()) == 0) 1342 Xolder 1343 call assert_equal(testlen, len(g:Xgetlist())) 1344 Xnewer 1345 Xnewer 1346 call assert_equal(matchlen, len(g:Xgetlist())) 1347endfunc 1348 1349func Test_setqflist_empty_middle() 1350 call Xlist_empty_middle('c') 1351 call Xlist_empty_middle('l') 1352endfunc 1353 1354func Xlist_empty_older(cchar) 1355 call s:setup_commands(a:cchar) 1356 1357 " create three quickfix lists 1358 Xvimgrep one test_quickfix.vim 1359 let onelen = len(g:Xgetlist()) 1360 call assert_true(onelen > 0) 1361 Xvimgrep two test_quickfix.vim 1362 let twolen = len(g:Xgetlist()) 1363 call assert_true(twolen > 0) 1364 Xvimgrep three test_quickfix.vim 1365 let threelen = len(g:Xgetlist()) 1366 call assert_true(threelen > 0) 1367 Xolder 2 1368 " make the first list empty, check the others didn't change 1369 call g:Xsetlist([], 'r') 1370 call assert_true(len(g:Xgetlist()) == 0) 1371 Xnewer 1372 call assert_equal(twolen, len(g:Xgetlist())) 1373 Xnewer 1374 call assert_equal(threelen, len(g:Xgetlist())) 1375endfunc 1376 1377func Test_setqflist_empty_older() 1378 call Xlist_empty_older('c') 1379 call Xlist_empty_older('l') 1380endfunc 1381 1382func XquickfixSetListWithAct(cchar) 1383 call s:setup_commands(a:cchar) 1384 1385 let list1 = [{'filename': 'fnameA', 'text': 'A'}, 1386 \ {'filename': 'fnameB', 'text': 'B'}] 1387 let list2 = [{'filename': 'fnameC', 'text': 'C'}, 1388 \ {'filename': 'fnameD', 'text': 'D'}, 1389 \ {'filename': 'fnameE', 'text': 'E'}] 1390 1391 " {action} is unspecified. Same as specifing ' '. 1392 new | only 1393 silent! Xnewer 99 1394 call g:Xsetlist(list1) 1395 call g:Xsetlist(list2) 1396 let li = g:Xgetlist() 1397 call assert_equal(3, len(li)) 1398 call assert_equal('C', li[0]['text']) 1399 call assert_equal('D', li[1]['text']) 1400 call assert_equal('E', li[2]['text']) 1401 silent! Xolder 1402 let li = g:Xgetlist() 1403 call assert_equal(2, len(li)) 1404 call assert_equal('A', li[0]['text']) 1405 call assert_equal('B', li[1]['text']) 1406 1407 " {action} is specified ' '. 1408 new | only 1409 silent! Xnewer 99 1410 call g:Xsetlist(list1) 1411 call g:Xsetlist(list2, ' ') 1412 let li = g:Xgetlist() 1413 call assert_equal(3, len(li)) 1414 call assert_equal('C', li[0]['text']) 1415 call assert_equal('D', li[1]['text']) 1416 call assert_equal('E', li[2]['text']) 1417 silent! Xolder 1418 let li = g:Xgetlist() 1419 call assert_equal(2, len(li)) 1420 call assert_equal('A', li[0]['text']) 1421 call assert_equal('B', li[1]['text']) 1422 1423 " {action} is specified 'a'. 1424 new | only 1425 silent! Xnewer 99 1426 call g:Xsetlist(list1) 1427 call g:Xsetlist(list2, 'a') 1428 let li = g:Xgetlist() 1429 call assert_equal(5, len(li)) 1430 call assert_equal('A', li[0]['text']) 1431 call assert_equal('B', li[1]['text']) 1432 call assert_equal('C', li[2]['text']) 1433 call assert_equal('D', li[3]['text']) 1434 call assert_equal('E', li[4]['text']) 1435 1436 " {action} is specified 'r'. 1437 new | only 1438 silent! Xnewer 99 1439 call g:Xsetlist(list1) 1440 call g:Xsetlist(list2, 'r') 1441 let li = g:Xgetlist() 1442 call assert_equal(3, len(li)) 1443 call assert_equal('C', li[0]['text']) 1444 call assert_equal('D', li[1]['text']) 1445 call assert_equal('E', li[2]['text']) 1446 1447 " Test for wrong value. 1448 new | only 1449 call assert_fails("call g:Xsetlist(0)", 'E714:') 1450 call assert_fails("call g:Xsetlist(list1, '')", 'E927:') 1451 call assert_fails("call g:Xsetlist(list1, 'aa')", 'E927:') 1452 call assert_fails("call g:Xsetlist(list1, ' a')", 'E927:') 1453 call assert_fails("call g:Xsetlist(list1, 0)", 'E928:') 1454endfunc 1455 1456func Test_setqflist_invalid_nr() 1457 " The following command used to crash Vim 1458 call setqflist([], ' ', {'nr' : $XXX_DOES_NOT_EXIST}) 1459endfunc 1460 1461func Test_quickfix_set_list_with_act() 1462 call XquickfixSetListWithAct('c') 1463 call XquickfixSetListWithAct('l') 1464endfunc 1465 1466func XLongLinesTests(cchar) 1467 let l = g:Xgetlist() 1468 1469 call assert_equal(4, len(l)) 1470 call assert_equal(1, l[0].lnum) 1471 call assert_equal(1, l[0].col) 1472 call assert_equal(1975, len(l[0].text)) 1473 call assert_equal(2, l[1].lnum) 1474 call assert_equal(1, l[1].col) 1475 call assert_equal(4070, len(l[1].text)) 1476 call assert_equal(3, l[2].lnum) 1477 call assert_equal(1, l[2].col) 1478 call assert_equal(4070, len(l[2].text)) 1479 call assert_equal(4, l[3].lnum) 1480 call assert_equal(1, l[3].col) 1481 call assert_equal(10, len(l[3].text)) 1482 1483 call g:Xsetlist([], 'r') 1484endfunc 1485 1486func s:long_lines_tests(cchar) 1487 call s:setup_commands(a:cchar) 1488 1489 let testfile = 'samples/quickfix.txt' 1490 1491 " file 1492 exe 'Xgetfile' testfile 1493 call XLongLinesTests(a:cchar) 1494 1495 " list 1496 Xexpr readfile(testfile) 1497 call XLongLinesTests(a:cchar) 1498 1499 " string 1500 Xexpr join(readfile(testfile), "\n") 1501 call XLongLinesTests(a:cchar) 1502 1503 " buffer 1504 exe 'edit' testfile 1505 exe 'Xbuffer' bufnr('%') 1506 call XLongLinesTests(a:cchar) 1507endfunc 1508 1509func Test_long_lines() 1510 call s:long_lines_tests('c') 1511 call s:long_lines_tests('l') 1512endfunc 1513 1514func s:create_test_file(filename) 1515 let l = [] 1516 for i in range(1, 20) 1517 call add(l, 'Line' . i) 1518 endfor 1519 call writefile(l, a:filename) 1520endfunc 1521 1522func Test_switchbuf() 1523 call s:create_test_file('Xqftestfile1') 1524 call s:create_test_file('Xqftestfile2') 1525 call s:create_test_file('Xqftestfile3') 1526 1527 new | only 1528 edit Xqftestfile1 1529 let file1_winid = win_getid() 1530 new Xqftestfile2 1531 let file2_winid = win_getid() 1532 cgetexpr ['Xqftestfile1:5:Line5', 1533 \ 'Xqftestfile1:6:Line6', 1534 \ 'Xqftestfile2:10:Line10', 1535 \ 'Xqftestfile2:11:Line11', 1536 \ 'Xqftestfile3:15:Line15', 1537 \ 'Xqftestfile3:16:Line16'] 1538 1539 new 1540 let winid = win_getid() 1541 cfirst | cnext 1542 call assert_equal(winid, win_getid()) 1543 2cnext 1544 call assert_equal(winid, win_getid()) 1545 2cnext 1546 call assert_equal(winid, win_getid()) 1547 enew 1548 1549 set switchbuf=useopen 1550 cfirst | cnext 1551 call assert_equal(file1_winid, win_getid()) 1552 2cnext 1553 call assert_equal(file2_winid, win_getid()) 1554 2cnext 1555 call assert_equal(file2_winid, win_getid()) 1556 1557 enew | only 1558 set switchbuf=usetab 1559 tabedit Xqftestfile1 1560 tabedit Xqftestfile2 1561 tabedit Xqftestfile3 1562 tabfirst 1563 cfirst | cnext 1564 call assert_equal(2, tabpagenr()) 1565 2cnext 1566 call assert_equal(3, tabpagenr()) 1567 6cnext 1568 call assert_equal(4, tabpagenr()) 1569 2cpfile 1570 call assert_equal(2, tabpagenr()) 1571 2cnfile 1572 call assert_equal(4, tabpagenr()) 1573 tabfirst | tabonly | enew 1574 1575 set switchbuf=split 1576 cfirst | cnext 1577 call assert_equal(1, winnr('$')) 1578 cnext | cnext 1579 call assert_equal(2, winnr('$')) 1580 cnext | cnext 1581 call assert_equal(3, winnr('$')) 1582 enew | only 1583 1584 set switchbuf=newtab 1585 cfirst | cnext 1586 call assert_equal(1, tabpagenr('$')) 1587 cnext | cnext 1588 call assert_equal(2, tabpagenr('$')) 1589 cnext | cnext 1590 call assert_equal(3, tabpagenr('$')) 1591 tabfirst | enew | tabonly | only 1592 1593 set switchbuf= 1594 edit Xqftestfile1 1595 let file1_winid = win_getid() 1596 new Xqftestfile2 1597 let file2_winid = win_getid() 1598 copen 1599 exe "normal 1G\<CR>" 1600 call assert_equal(file1_winid, win_getid()) 1601 copen 1602 exe "normal 3G\<CR>" 1603 call assert_equal(file2_winid, win_getid()) 1604 copen | only 1605 exe "normal 5G\<CR>" 1606 call assert_equal(2, winnr('$')) 1607 call assert_equal(1, bufwinnr('Xqftestfile3')) 1608 1609 " If only quickfix window is open in the current tabpage, jumping to an 1610 " entry with 'switchubf' set to 'usetab' should search in other tabpages. 1611 enew | only 1612 set switchbuf=usetab 1613 tabedit Xqftestfile1 1614 tabedit Xqftestfile2 1615 tabedit Xqftestfile3 1616 tabfirst 1617 copen | only 1618 clast 1619 call assert_equal(4, tabpagenr()) 1620 tabfirst | tabonly | enew | only 1621 1622 call delete('Xqftestfile1') 1623 call delete('Xqftestfile2') 1624 call delete('Xqftestfile3') 1625 set switchbuf&vim 1626 1627 enew | only 1628endfunc 1629 1630func Xadjust_qflnum(cchar) 1631 call s:setup_commands(a:cchar) 1632 1633 enew | only 1634 1635 let fname = 'Xqftestfile' . a:cchar 1636 call s:create_test_file(fname) 1637 exe 'edit ' . fname 1638 1639 Xgetexpr [fname . ':5:Line5', 1640 \ fname . ':10:Line10', 1641 \ fname . ':15:Line15', 1642 \ fname . ':20:Line20'] 1643 1644 6,14delete 1645 call append(6, ['Buffer', 'Window']) 1646 1647 let l = g:Xgetlist() 1648 1649 call assert_equal(5, l[0].lnum) 1650 call assert_equal(6, l[2].lnum) 1651 call assert_equal(13, l[3].lnum) 1652 1653 enew! 1654 call delete(fname) 1655endfunc 1656 1657func Test_adjust_lnum() 1658 call setloclist(0, []) 1659 call Xadjust_qflnum('c') 1660 call setqflist([]) 1661 call Xadjust_qflnum('l') 1662endfunc 1663 1664" Tests for the :grep/:lgrep and :grepadd/:lgrepadd commands 1665func s:test_xgrep(cchar) 1666 call s:setup_commands(a:cchar) 1667 1668 " The following lines are used for the grep test. Don't remove. 1669 " Grep_Test_Text: Match 1 1670 " Grep_Test_Text: Match 2 1671 " GrepAdd_Test_Text: Match 1 1672 " GrepAdd_Test_Text: Match 2 1673 enew! | only 1674 set makeef&vim 1675 silent Xgrep Grep_Test_Text: test_quickfix.vim 1676 call assert_true(len(g:Xgetlist()) == 3) 1677 Xopen 1678 call assert_true(w:quickfix_title =~ '^:grep') 1679 Xclose 1680 enew 1681 set makeef=Temp_File_## 1682 silent Xgrepadd GrepAdd_Test_Text: test_quickfix.vim 1683 call assert_true(len(g:Xgetlist()) == 6) 1684endfunc 1685 1686func Test_grep() 1687 if !has('unix') 1688 " The grepprg may not be set on non-Unix systems 1689 return 1690 endif 1691 1692 call s:test_xgrep('c') 1693 call s:test_xgrep('l') 1694endfunc 1695 1696func Test_two_windows() 1697 " Use one 'errorformat' for two windows. Add an expression to each of them, 1698 " make sure they each keep their own state. 1699 set efm=%DEntering\ dir\ '%f',%f:%l:%m,%XLeaving\ dir\ '%f' 1700 call mkdir('Xone/a', 'p') 1701 call mkdir('Xtwo/a', 'p') 1702 let lines = ['1', '2', 'one one one', '4', 'two two two', '6', '7'] 1703 call writefile(lines, 'Xone/a/one.txt') 1704 call writefile(lines, 'Xtwo/a/two.txt') 1705 1706 new one 1707 let one_id = win_getid() 1708 lexpr "" 1709 new two 1710 let two_id = win_getid() 1711 lexpr "" 1712 1713 laddexpr "Entering dir 'Xtwo/a'" 1714 call win_gotoid(one_id) 1715 laddexpr "Entering dir 'Xone/a'" 1716 call win_gotoid(two_id) 1717 laddexpr 'two.txt:5:two two two' 1718 call win_gotoid(one_id) 1719 laddexpr 'one.txt:3:one one one' 1720 1721 let loc_one = getloclist(one_id) 1722 call assert_equal('Xone/a/one.txt', bufname(loc_one[1].bufnr)) 1723 call assert_equal(3, loc_one[1].lnum) 1724 1725 let loc_two = getloclist(two_id) 1726 call assert_equal('Xtwo/a/two.txt', bufname(loc_two[1].bufnr)) 1727 call assert_equal(5, loc_two[1].lnum) 1728 1729 call win_gotoid(one_id) 1730 bwipe! 1731 call win_gotoid(two_id) 1732 bwipe! 1733 call delete('Xone', 'rf') 1734 call delete('Xtwo', 'rf') 1735endfunc 1736 1737func XbottomTests(cchar) 1738 call s:setup_commands(a:cchar) 1739 1740 " Calling lbottom without any errors should fail 1741 if a:cchar == 'l' 1742 call assert_fails('lbottom', 'E776:') 1743 endif 1744 1745 call g:Xsetlist([{'filename': 'foo', 'lnum': 42}]) 1746 Xopen 1747 let wid = win_getid() 1748 call assert_equal(1, line('.')) 1749 wincmd w 1750 call g:Xsetlist([{'filename': 'var', 'lnum': 24}], 'a') 1751 Xbottom 1752 call win_gotoid(wid) 1753 call assert_equal(2, line('.')) 1754 Xclose 1755endfunc 1756 1757" Tests for the :cbottom and :lbottom commands 1758func Test_cbottom() 1759 call XbottomTests('c') 1760 call XbottomTests('l') 1761endfunc 1762 1763func HistoryTest(cchar) 1764 call s:setup_commands(a:cchar) 1765 1766 " clear all lists after the first one, then replace the first one. 1767 call g:Xsetlist([]) 1768 call assert_fails('Xolder 99', 'E380:') 1769 let entry = {'filename': 'foo', 'lnum': 42} 1770 call g:Xsetlist([entry], 'r') 1771 call g:Xsetlist([entry, entry]) 1772 call g:Xsetlist([entry, entry, entry]) 1773 let res = split(execute(a:cchar . 'hist'), "\n") 1774 call assert_equal(3, len(res)) 1775 let common = 'errors :set' . (a:cchar == 'c' ? 'qf' : 'loc') . 'list()' 1776 call assert_equal(' error list 1 of 3; 1 ' . common, res[0]) 1777 call assert_equal(' error list 2 of 3; 2 ' . common, res[1]) 1778 call assert_equal('> error list 3 of 3; 3 ' . common, res[2]) 1779 1780 call g:Xsetlist([], 'f') 1781 let l = split(execute(a:cchar . 'hist'), "\n") 1782 call assert_equal('No entries', l[0]) 1783endfunc 1784 1785func Test_history() 1786 call HistoryTest('c') 1787 call HistoryTest('l') 1788endfunc 1789 1790func Test_duplicate_buf() 1791 " make sure we can get the highest buffer number 1792 edit DoesNotExist 1793 edit DoesNotExist2 1794 let last_buffer = bufnr("$") 1795 1796 " make sure only one buffer is created 1797 call writefile(['this one', 'that one'], 'Xgrepthis') 1798 vimgrep one Xgrepthis 1799 vimgrep one Xgrepthis 1800 call assert_equal(last_buffer + 1, bufnr("$")) 1801 1802 call delete('Xgrepthis') 1803endfunc 1804 1805" Quickfix/Location list set/get properties tests 1806func Xproperty_tests(cchar) 1807 call s:setup_commands(a:cchar) 1808 1809 " Error cases 1810 call assert_fails('call g:Xgetlist(99)', 'E715:') 1811 call assert_fails('call g:Xsetlist(99)', 'E714:') 1812 call assert_fails('call g:Xsetlist([], "a", [])', 'E715:') 1813 1814 " Set and get the title 1815 call g:Xsetlist([]) 1816 Xopen 1817 wincmd p 1818 call g:Xsetlist([{'filename':'foo', 'lnum':27}]) 1819 let s = g:Xsetlist([], 'a', {'title' : 'Sample'}) 1820 call assert_equal(0, s) 1821 let d = g:Xgetlist({"title":1}) 1822 call assert_equal('Sample', d.title) 1823 " Try setting title to a non-string value 1824 call assert_equal(-1, g:Xsetlist([], 'a', {'title' : ['Test']})) 1825 call assert_equal('Sample', g:Xgetlist({"title":1}).title) 1826 1827 Xopen 1828 call assert_equal('Sample', w:quickfix_title) 1829 Xclose 1830 1831 " Tests for action argument 1832 silent! Xolder 999 1833 let qfnr = g:Xgetlist({'all':1}).nr 1834 call g:Xsetlist([], 'r', {'title' : 'N1'}) 1835 call assert_equal('N1', g:Xgetlist({'all':1}).title) 1836 call g:Xsetlist([], ' ', {'title' : 'N2'}) 1837 call assert_equal(qfnr + 1, g:Xgetlist({'all':1}).nr) 1838 1839 let res = g:Xgetlist({'nr': 0}) 1840 call assert_equal(qfnr + 1, res.nr) 1841 call assert_equal(['nr'], keys(res)) 1842 1843 call g:Xsetlist([], ' ', {'title' : 'N3'}) 1844 call assert_equal('N2', g:Xgetlist({'nr':2, 'title':1}).title) 1845 1846 " Changing the title of an earlier quickfix list 1847 call g:Xsetlist([], 'r', {'title' : 'NewTitle', 'nr' : 2}) 1848 call assert_equal('NewTitle', g:Xgetlist({'nr':2, 'title':1}).title) 1849 1850 " Changing the title of an invalid quickfix list 1851 call assert_equal(-1, g:Xsetlist([], ' ', 1852 \ {'title' : 'SomeTitle', 'nr' : 99})) 1853 call assert_equal(-1, g:Xsetlist([], ' ', 1854 \ {'title' : 'SomeTitle', 'nr' : 'abc'})) 1855 1856 if a:cchar == 'c' 1857 copen 1858 call assert_equal({'winid':win_getid()}, getqflist({'winid':1})) 1859 cclose 1860 endif 1861 1862 " Invalid arguments 1863 call assert_fails('call g:Xgetlist([])', 'E715') 1864 call assert_fails('call g:Xsetlist([], "a", [])', 'E715') 1865 let s = g:Xsetlist([], 'a', {'abc':1}) 1866 call assert_equal(-1, s) 1867 1868 call assert_equal({}, g:Xgetlist({'abc':1})) 1869 call assert_equal('', g:Xgetlist({'nr':99, 'title':1}).title) 1870 call assert_equal('', g:Xgetlist({'nr':[], 'title':1}).title) 1871 1872 if a:cchar == 'l' 1873 call assert_equal({}, getloclist(99, {'title': 1})) 1874 endif 1875 1876 " Context related tests 1877 let s = g:Xsetlist([], 'a', {'context':[1,2,3]}) 1878 call assert_equal(0, s) 1879 call test_garbagecollect_now() 1880 let d = g:Xgetlist({'context':1}) 1881 call assert_equal([1,2,3], d.context) 1882 call g:Xsetlist([], 'a', {'context':{'color':'green'}}) 1883 let d = g:Xgetlist({'context':1}) 1884 call assert_equal({'color':'green'}, d.context) 1885 call g:Xsetlist([], 'a', {'context':"Context info"}) 1886 let d = g:Xgetlist({'context':1}) 1887 call assert_equal("Context info", d.context) 1888 call g:Xsetlist([], 'a', {'context':246}) 1889 let d = g:Xgetlist({'context':1}) 1890 call assert_equal(246, d.context) 1891 if a:cchar == 'l' 1892 " Test for copying context across two different location lists 1893 new | only 1894 let w1_id = win_getid() 1895 let l = [1] 1896 call setloclist(0, [], 'a', {'context':l}) 1897 new 1898 let w2_id = win_getid() 1899 call add(l, 2) 1900 call assert_equal([1, 2], getloclist(w1_id, {'context':1}).context) 1901 call assert_equal([1, 2], getloclist(w2_id, {'context':1}).context) 1902 unlet! l 1903 call assert_equal([1, 2], getloclist(w2_id, {'context':1}).context) 1904 only 1905 call setloclist(0, [], 'f') 1906 call assert_equal('', getloclist(0, {'context':1}).context) 1907 endif 1908 1909 " Test for changing the context of previous quickfix lists 1910 call g:Xsetlist([], 'f') 1911 Xexpr "One" 1912 Xexpr "Two" 1913 Xexpr "Three" 1914 call g:Xsetlist([], 'r', {'context' : [1], 'nr' : 1}) 1915 call g:Xsetlist([], 'a', {'context' : [2], 'nr' : 2}) 1916 " Also, check for setting the context using quickfix list number zero. 1917 call g:Xsetlist([], 'r', {'context' : [3], 'nr' : 0}) 1918 call test_garbagecollect_now() 1919 let l = g:Xgetlist({'nr' : 1, 'context' : 1}) 1920 call assert_equal([1], l.context) 1921 let l = g:Xgetlist({'nr' : 2, 'context' : 1}) 1922 call assert_equal([2], l.context) 1923 let l = g:Xgetlist({'nr' : 3, 'context' : 1}) 1924 call assert_equal([3], l.context) 1925 1926 " Test for changing the context through reference and for garbage 1927 " collection of quickfix context 1928 let l = ["red"] 1929 call g:Xsetlist([], ' ', {'context' : l}) 1930 call add(l, "blue") 1931 let x = g:Xgetlist({'context' : 1}) 1932 call add(x.context, "green") 1933 call assert_equal(["red", "blue", "green"], l) 1934 call assert_equal(["red", "blue", "green"], x.context) 1935 unlet l 1936 call test_garbagecollect_now() 1937 let m = g:Xgetlist({'context' : 1}) 1938 call assert_equal(["red", "blue", "green"], m.context) 1939 1940 " Test for setting/getting items 1941 Xexpr "" 1942 let qfprev = g:Xgetlist({'nr':0}) 1943 let s = g:Xsetlist([], ' ', {'title':'Green', 1944 \ 'items' : [{'filename':'F1', 'lnum':10}]}) 1945 call assert_equal(0, s) 1946 let qfcur = g:Xgetlist({'nr':0}) 1947 call assert_true(qfcur.nr == qfprev.nr + 1) 1948 let l = g:Xgetlist({'items':1}) 1949 call assert_equal('F1', bufname(l.items[0].bufnr)) 1950 call assert_equal(10, l.items[0].lnum) 1951 call g:Xsetlist([], 'a', {'items' : [{'filename':'F2', 'lnum':20}, 1952 \ {'filename':'F2', 'lnum':30}]}) 1953 let l = g:Xgetlist({'items':1}) 1954 call assert_equal('F2', bufname(l.items[2].bufnr)) 1955 call assert_equal(30, l.items[2].lnum) 1956 call g:Xsetlist([], 'r', {'items' : [{'filename':'F3', 'lnum':40}]}) 1957 let l = g:Xgetlist({'items':1}) 1958 call assert_equal('F3', bufname(l.items[0].bufnr)) 1959 call assert_equal(40, l.items[0].lnum) 1960 call g:Xsetlist([], 'r', {'items' : []}) 1961 let l = g:Xgetlist({'items':1}) 1962 call assert_equal(0, len(l.items)) 1963 1964 call g:Xsetlist([], 'r', {'title' : 'TestTitle'}) 1965 call g:Xsetlist([], 'r', {'items' : [{'filename' : 'F1', 'lnum' : 10, 'text' : 'L10'}]}) 1966 call g:Xsetlist([], 'r', {'items' : [{'filename' : 'F1', 'lnum' : 10, 'text' : 'L10'}]}) 1967 call assert_equal('TestTitle', g:Xgetlist({'title' : 1}).title) 1968 1969 " The following used to crash Vim with address sanitizer 1970 call g:Xsetlist([], 'f') 1971 call g:Xsetlist([], 'a', {'items' : [{'filename':'F1', 'lnum':10}]}) 1972 call assert_equal(10, g:Xgetlist({'items':1}).items[0].lnum) 1973 1974 " Try setting the items using a string 1975 call assert_equal(-1, g:Xsetlist([], ' ', {'items' : 'Test'})) 1976 1977 " Save and restore the quickfix stack 1978 call g:Xsetlist([], 'f') 1979 call assert_equal(0, g:Xgetlist({'nr':'$'}).nr) 1980 Xexpr "File1:10:Line1" 1981 Xexpr "File2:20:Line2" 1982 Xexpr "File3:30:Line3" 1983 let last_qf = g:Xgetlist({'nr':'$'}).nr 1984 call assert_equal(3, last_qf) 1985 let qstack = [] 1986 for i in range(1, last_qf) 1987 let qstack = add(qstack, g:Xgetlist({'nr':i, 'all':1})) 1988 endfor 1989 call g:Xsetlist([], 'f') 1990 for i in range(len(qstack)) 1991 call g:Xsetlist([], ' ', qstack[i]) 1992 endfor 1993 call assert_equal(3, g:Xgetlist({'nr':'$'}).nr) 1994 call assert_equal(10, g:Xgetlist({'nr':1, 'items':1}).items[0].lnum) 1995 call assert_equal(20, g:Xgetlist({'nr':2, 'items':1}).items[0].lnum) 1996 call assert_equal(30, g:Xgetlist({'nr':3, 'items':1}).items[0].lnum) 1997 call g:Xsetlist([], 'f') 1998 1999 " Swap two quickfix lists 2000 Xexpr "File1:10:Line10" 2001 Xexpr "File2:20:Line20" 2002 Xexpr "File3:30:Line30" 2003 call g:Xsetlist([], 'r', {'nr':1,'title':'Colors','context':['Colors']}) 2004 call g:Xsetlist([], 'r', {'nr':2,'title':'Fruits','context':['Fruits']}) 2005 let l1=g:Xgetlist({'nr':1,'all':1}) 2006 let l2=g:Xgetlist({'nr':2,'all':1}) 2007 let save_id = l1.id 2008 let l1.id=l2.id 2009 let l2.id=save_id 2010 call g:Xsetlist([], 'r', l1) 2011 call g:Xsetlist([], 'r', l2) 2012 let newl1=g:Xgetlist({'nr':1,'all':1}) 2013 let newl2=g:Xgetlist({'nr':2,'all':1}) 2014 call assert_equal('Fruits', newl1.title) 2015 call assert_equal(['Fruits'], newl1.context) 2016 call assert_equal('Line20', newl1.items[0].text) 2017 call assert_equal('Colors', newl2.title) 2018 call assert_equal(['Colors'], newl2.context) 2019 call assert_equal('Line10', newl2.items[0].text) 2020 call g:Xsetlist([], 'f') 2021endfunc 2022 2023func Test_qf_property() 2024 call Xproperty_tests('c') 2025 call Xproperty_tests('l') 2026endfunc 2027 2028" Tests for the QuickFixCmdPre/QuickFixCmdPost autocommands 2029func QfAutoCmdHandler(loc, cmd) 2030 call add(g:acmds, a:loc . a:cmd) 2031endfunc 2032 2033func Test_Autocmd() 2034 autocmd QuickFixCmdPre * call QfAutoCmdHandler('pre', expand('<amatch>')) 2035 autocmd QuickFixCmdPost * call QfAutoCmdHandler('post', expand('<amatch>')) 2036 2037 let g:acmds = [] 2038 cexpr "F1:10:Line 10" 2039 caddexpr "F1:20:Line 20" 2040 cgetexpr "F1:30:Line 30" 2041 cexpr "" 2042 caddexpr "" 2043 cgetexpr "" 2044 silent! cexpr non_existing_func() 2045 silent! caddexpr non_existing_func() 2046 silent! cgetexpr non_existing_func() 2047 let l = ['precexpr', 2048 \ 'postcexpr', 2049 \ 'precaddexpr', 2050 \ 'postcaddexpr', 2051 \ 'precgetexpr', 2052 \ 'postcgetexpr', 2053 \ 'precexpr', 2054 \ 'postcexpr', 2055 \ 'precaddexpr', 2056 \ 'postcaddexpr', 2057 \ 'precgetexpr', 2058 \ 'postcgetexpr', 2059 \ 'precexpr', 2060 \ 'precaddexpr', 2061 \ 'precgetexpr'] 2062 call assert_equal(l, g:acmds) 2063 2064 let g:acmds = [] 2065 enew! | call append(0, "F2:10:Line 10") 2066 cbuffer! 2067 enew! | call append(0, "F2:20:Line 20") 2068 cgetbuffer 2069 enew! | call append(0, "F2:30:Line 30") 2070 caddbuffer 2071 new 2072 let bnum = bufnr('%') 2073 bunload 2074 exe 'silent! cbuffer! ' . bnum 2075 exe 'silent! cgetbuffer ' . bnum 2076 exe 'silent! caddbuffer ' . bnum 2077 enew! 2078 let l = ['precbuffer', 2079 \ 'postcbuffer', 2080 \ 'precgetbuffer', 2081 \ 'postcgetbuffer', 2082 \ 'precaddbuffer', 2083 \ 'postcaddbuffer', 2084 \ 'precbuffer', 2085 \ 'precgetbuffer', 2086 \ 'precaddbuffer'] 2087 call assert_equal(l, g:acmds) 2088 2089 call writefile(['Xtest:1:Line1'], 'Xtest') 2090 call writefile([], 'Xempty') 2091 let g:acmds = [] 2092 cfile Xtest 2093 caddfile Xtest 2094 cgetfile Xtest 2095 cfile Xempty 2096 caddfile Xempty 2097 cgetfile Xempty 2098 silent! cfile do_not_exist 2099 silent! caddfile do_not_exist 2100 silent! cgetfile do_not_exist 2101 let l = ['precfile', 2102 \ 'postcfile', 2103 \ 'precaddfile', 2104 \ 'postcaddfile', 2105 \ 'precgetfile', 2106 \ 'postcgetfile', 2107 \ 'precfile', 2108 \ 'postcfile', 2109 \ 'precaddfile', 2110 \ 'postcaddfile', 2111 \ 'precgetfile', 2112 \ 'postcgetfile', 2113 \ 'precfile', 2114 \ 'postcfile', 2115 \ 'precaddfile', 2116 \ 'postcaddfile', 2117 \ 'precgetfile', 2118 \ 'postcgetfile'] 2119 call assert_equal(l, g:acmds) 2120 2121 let g:acmds = [] 2122 helpgrep quickfix 2123 silent! helpgrep non_existing_help_topic 2124 vimgrep test Xtest 2125 vimgrepadd test Xtest 2126 silent! vimgrep non_existing_test Xtest 2127 silent! vimgrepadd non_existing_test Xtest 2128 set makeprg= 2129 silent! make 2130 set makeprg& 2131 let l = ['prehelpgrep', 2132 \ 'posthelpgrep', 2133 \ 'prehelpgrep', 2134 \ 'posthelpgrep', 2135 \ 'previmgrep', 2136 \ 'postvimgrep', 2137 \ 'previmgrepadd', 2138 \ 'postvimgrepadd', 2139 \ 'previmgrep', 2140 \ 'postvimgrep', 2141 \ 'previmgrepadd', 2142 \ 'postvimgrepadd', 2143 \ 'premake', 2144 \ 'postmake'] 2145 call assert_equal(l, g:acmds) 2146 2147 if has('unix') 2148 " Run this test only on Unix-like systems. The grepprg may not be set on 2149 " non-Unix systems. 2150 " The following lines are used for the grep test. Don't remove. 2151 " Grep_Autocmd_Text: Match 1 2152 " GrepAdd_Autocmd_Text: Match 2 2153 let g:acmds = [] 2154 silent grep Grep_Autocmd_Text test_quickfix.vim 2155 silent grepadd GrepAdd_Autocmd_Text test_quickfix.vim 2156 silent grep abc123def Xtest 2157 silent grepadd abc123def Xtest 2158 let l = ['pregrep', 2159 \ 'postgrep', 2160 \ 'pregrepadd', 2161 \ 'postgrepadd', 2162 \ 'pregrep', 2163 \ 'postgrep', 2164 \ 'pregrepadd', 2165 \ 'postgrepadd'] 2166 call assert_equal(l, g:acmds) 2167 endif 2168 2169 call delete('Xtest') 2170 call delete('Xempty') 2171 au! QuickFixCmdPre 2172 au! QuickFixCmdPost 2173endfunc 2174 2175func Test_Autocmd_Exception() 2176 set efm=%m 2177 lgetexpr '?' 2178 2179 try 2180 call DoesNotExit() 2181 catch 2182 lgetexpr '1' 2183 finally 2184 lgetexpr '1' 2185 endtry 2186 2187 call assert_equal('1', getloclist(0)[0].text) 2188 2189 set efm&vim 2190endfunc 2191 2192func Test_caddbuffer_wrong() 2193 " This used to cause a memory access in freed memory. 2194 let save_efm = &efm 2195 set efm=%EEEE%m,%WWWW,%+CCCC%>%#,%GGGG%.# 2196 cgetexpr ['WWWW', 'EEEE', 'CCCC'] 2197 let &efm = save_efm 2198 caddbuffer 2199 bwipe! 2200endfunc 2201 2202func Test_caddexpr_wrong() 2203 " This used to cause a memory access in freed memory. 2204 cbuffer 2205 cbuffer 2206 copen 2207 let save_efm = &efm 2208 set efm=% 2209 call assert_fails('caddexpr ""', 'E376:') 2210 let &efm = save_efm 2211endfunc 2212 2213func Test_dirstack_cleanup() 2214 " This used to cause a memory access in freed memory. 2215 let save_efm = &efm 2216 lexpr '0' 2217 lopen 2218 fun X(c) 2219 let save_efm=&efm 2220 set efm=%D%f 2221 if a:c == 'c' 2222 caddexpr '::' 2223 else 2224 laddexpr ':0:0' 2225 endif 2226 let &efm=save_efm 2227 endfun 2228 call X('c') 2229 call X('l') 2230 call setqflist([], 'r') 2231 caddbuffer 2232 let &efm = save_efm 2233endfunc 2234 2235" Tests for jumping to entries from the location list window and quickfix 2236" window 2237func Test_cwindow_jump() 2238 set efm=%f%%%l%%%m 2239 lgetexpr ["F1%10%Line 10", "F2%20%Line 20", "F3%30%Line 30"] 2240 lopen | only 2241 lfirst 2242 call assert_true(winnr('$') == 2) 2243 call assert_true(winnr() == 1) 2244 " Location list for the new window should be set 2245 call assert_true(getloclist(0)[2].text == 'Line 30') 2246 2247 " Open a scratch buffer 2248 " Open a new window and create a location list 2249 " Open the location list window and close the other window 2250 " Jump to an entry. 2251 " Should create a new window and jump to the entry. The scrtach buffer 2252 " should not be used. 2253 enew | only 2254 set buftype=nofile 2255 below new 2256 lgetexpr ["F1%10%Line 10", "F2%20%Line 20", "F3%30%Line 30"] 2257 lopen 2258 2wincmd c 2259 lnext 2260 call assert_true(winnr('$') == 3) 2261 call assert_true(winnr() == 2) 2262 2263 " Open two windows with two different location lists 2264 " Open the location list window and close the previous window 2265 " Jump to an entry in the location list window 2266 " Should open the file in the first window and not set the location list. 2267 enew | only 2268 lgetexpr ["F1%5%Line 5"] 2269 below new 2270 lgetexpr ["F1%10%Line 10", "F2%20%Line 20", "F3%30%Line 30"] 2271 lopen 2272 2wincmd c 2273 lnext 2274 call assert_true(winnr() == 1) 2275 call assert_true(getloclist(0)[0].text == 'Line 5') 2276 2277 enew | only 2278 cgetexpr ["F1%10%Line 10", "F2%20%Line 20", "F3%30%Line 30"] 2279 copen 2280 cnext 2281 call assert_true(winnr('$') == 2) 2282 call assert_true(winnr() == 1) 2283 2284 enew | only 2285 set efm&vim 2286endfunc 2287 2288func XvimgrepTests(cchar) 2289 call s:setup_commands(a:cchar) 2290 2291 call writefile(['Editor:VIM vim', 2292 \ 'Editor:Emacs EmAcS', 2293 \ 'Editor:Notepad NOTEPAD'], 'Xtestfile1') 2294 call writefile(['Linux', 'MacOS', 'MS-Windows'], 'Xtestfile2') 2295 2296 " Error cases 2297 call assert_fails('Xvimgrep /abc *', 'E682:') 2298 2299 let @/='' 2300 call assert_fails('Xvimgrep // *', 'E35:') 2301 2302 call assert_fails('Xvimgrep abc', 'E683:') 2303 call assert_fails('Xvimgrep a1b2c3 Xtestfile1', 'E480:') 2304 call assert_fails('Xvimgrep pat Xa1b2c3', 'E480:') 2305 2306 Xexpr "" 2307 Xvimgrepadd Notepad Xtestfile1 2308 Xvimgrepadd MacOS Xtestfile2 2309 let l = g:Xgetlist() 2310 call assert_equal(2, len(l)) 2311 call assert_equal('Editor:Notepad NOTEPAD', l[0].text) 2312 2313 Xvimgrep #\cvim#g Xtestfile? 2314 let l = g:Xgetlist() 2315 call assert_equal(2, len(l)) 2316 call assert_equal(8, l[0].col) 2317 call assert_equal(12, l[1].col) 2318 2319 1Xvimgrep ?Editor? Xtestfile* 2320 let l = g:Xgetlist() 2321 call assert_equal(1, len(l)) 2322 call assert_equal('Editor:VIM vim', l[0].text) 2323 2324 edit +3 Xtestfile2 2325 Xvimgrep +\cemacs+j Xtestfile1 2326 let l = g:Xgetlist() 2327 call assert_equal('Xtestfile2', bufname('')) 2328 call assert_equal('Editor:Emacs EmAcS', l[0].text) 2329 2330 " Test for unloading a buffer after vimgrep searched the buffer 2331 %bwipe 2332 Xvimgrep /Editor/j Xtestfile* 2333 call assert_equal(0, getbufinfo('Xtestfile1')[0].loaded) 2334 call assert_equal([], getbufinfo('Xtestfile2')) 2335 2336 call delete('Xtestfile1') 2337 call delete('Xtestfile2') 2338endfunc 2339 2340" Tests for the :vimgrep command 2341func Test_vimgrep() 2342 call XvimgrepTests('c') 2343 call XvimgrepTests('l') 2344endfunc 2345 2346func XfreeTests(cchar) 2347 call s:setup_commands(a:cchar) 2348 2349 enew | only 2350 2351 " Deleting the quickfix stack should work even When the current list is 2352 " somewhere in the middle of the stack 2353 Xexpr ['Xfile1:10:10:Line 10', 'Xfile1:15:15:Line 15'] 2354 Xexpr ['Xfile2:20:20:Line 20', 'Xfile2:25:25:Line 25'] 2355 Xexpr ['Xfile3:30:30:Line 30', 'Xfile3:35:35:Line 35'] 2356 Xolder 2357 call g:Xsetlist([], 'f') 2358 call assert_equal(0, len(g:Xgetlist())) 2359 2360 " After deleting the stack, adding a new list should create a stack with a 2361 " single list. 2362 Xexpr ['Xfile1:10:10:Line 10', 'Xfile1:15:15:Line 15'] 2363 call assert_equal(1, g:Xgetlist({'all':1}).nr) 2364 2365 " Deleting the stack from a quickfix window should update/clear the 2366 " quickfix/location list window. 2367 Xexpr ['Xfile1:10:10:Line 10', 'Xfile1:15:15:Line 15'] 2368 Xexpr ['Xfile2:20:20:Line 20', 'Xfile2:25:25:Line 25'] 2369 Xexpr ['Xfile3:30:30:Line 30', 'Xfile3:35:35:Line 35'] 2370 Xolder 2371 Xwindow 2372 call g:Xsetlist([], 'f') 2373 call assert_equal(2, winnr('$')) 2374 call assert_equal(1, line('$')) 2375 Xclose 2376 2377 " Deleting the stack from a non-quickfix window should update/clear the 2378 " quickfix/location list window. 2379 Xexpr ['Xfile1:10:10:Line 10', 'Xfile1:15:15:Line 15'] 2380 Xexpr ['Xfile2:20:20:Line 20', 'Xfile2:25:25:Line 25'] 2381 Xexpr ['Xfile3:30:30:Line 30', 'Xfile3:35:35:Line 35'] 2382 Xolder 2383 Xwindow 2384 wincmd p 2385 call g:Xsetlist([], 'f') 2386 call assert_equal(0, len(g:Xgetlist())) 2387 wincmd p 2388 call assert_equal(2, winnr('$')) 2389 call assert_equal(1, line('$')) 2390 2391 " After deleting the location list stack, if the location list window is 2392 " opened, then a new location list should be created. So opening the 2393 " location list window again should not create a new window. 2394 if a:cchar == 'l' 2395 lexpr ['Xfile1:10:10:Line 10', 'Xfile1:15:15:Line 15'] 2396 wincmd p 2397 lopen 2398 call assert_equal(2, winnr('$')) 2399 endif 2400 Xclose 2401endfunc 2402 2403" Tests for the quickfix free functionality 2404func Test_qf_free() 2405 call XfreeTests('c') 2406 call XfreeTests('l') 2407endfunc 2408 2409" Test for buffer overflow when parsing lines and adding new entries to 2410" the quickfix list. 2411func Test_bufoverflow() 2412 set efm=%f:%l:%m 2413 cgetexpr ['File1:100:' . repeat('x', 1025)] 2414 2415 set efm=%+GCompiler:\ %.%#,%f:%l:%m 2416 cgetexpr ['Compiler: ' . repeat('a', 1015), 'File1:10:Hello World'] 2417 2418 set efm=%DEntering\ directory\ %f,%f:%l:%m 2419 cgetexpr ['Entering directory ' . repeat('a', 1006), 2420 \ 'File1:10:Hello World'] 2421 set efm&vim 2422endfunc 2423 2424" Tests for getting the quickfix stack size 2425func XsizeTests(cchar) 2426 call s:setup_commands(a:cchar) 2427 2428 call g:Xsetlist([], 'f') 2429 call assert_equal(0, g:Xgetlist({'nr':'$'}).nr) 2430 call assert_equal('', g:Xgetlist({'nr':'$', 'all':1}).title) 2431 call assert_equal(0, g:Xgetlist({'nr':0}).nr) 2432 2433 Xexpr "File1:10:Line1" 2434 Xexpr "File2:20:Line2" 2435 Xexpr "File3:30:Line3" 2436 Xolder | Xolder 2437 call assert_equal(3, g:Xgetlist({'nr':'$'}).nr) 2438 call g:Xsetlist([], 'f') 2439 2440 Xexpr "File1:10:Line1" 2441 Xexpr "File2:20:Line2" 2442 Xexpr "File3:30:Line3" 2443 Xolder | Xolder 2444 call g:Xsetlist([], 'a', {'nr':'$', 'title':'Compiler'}) 2445 call assert_equal('Compiler', g:Xgetlist({'nr':3, 'all':1}).title) 2446endfunc 2447 2448func Test_Qf_Size() 2449 call XsizeTests('c') 2450 call XsizeTests('l') 2451endfunc 2452 2453func Test_cclose_from_copen() 2454 augroup QF_Test 2455 au! 2456 au FileType qf :call assert_fails(':cclose', 'E788') 2457 augroup END 2458 copen 2459 augroup QF_Test 2460 au! 2461 augroup END 2462 augroup! QF_Test 2463endfunc 2464 2465func Test_cclose_in_autocmd() 2466 " Problem is only triggered if "starting" is zero, so that the OptionsSet 2467 " event will be triggered. 2468 call test_override('starting', 1) 2469 augroup QF_Test 2470 au! 2471 au FileType qf :call assert_fails(':cclose', 'E788') 2472 augroup END 2473 copen 2474 augroup QF_Test 2475 au! 2476 augroup END 2477 augroup! QF_Test 2478 call test_override('starting', 0) 2479endfunc 2480 2481func Test_resize_from_copen() 2482 augroup QF_Test 2483 au! 2484 au FileType qf resize 5 2485 augroup END 2486 try 2487 " This should succeed without any exception. No other buffers are 2488 " involved in the autocmd. 2489 copen 2490 finally 2491 augroup QF_Test 2492 au! 2493 augroup END 2494 augroup! QF_Test 2495 endtry 2496endfunc 2497 2498" Tests for the quickfix buffer b:changedtick variable 2499func Xchangedtick_tests(cchar) 2500 call s:setup_commands(a:cchar) 2501 2502 new | only 2503 2504 Xexpr "" | Xexpr "" | Xexpr "" 2505 2506 Xopen 2507 Xolder 2508 Xolder 2509 Xaddexpr "F1:10:Line10" 2510 Xaddexpr "F2:20:Line20" 2511 call g:Xsetlist([{"filename":"F3", "lnum":30, "text":"Line30"}], 'a') 2512 call g:Xsetlist([], 'f') 2513 call assert_equal(8, getbufvar('%', 'changedtick')) 2514 Xclose 2515endfunc 2516 2517func Test_changedtick() 2518 call Xchangedtick_tests('c') 2519 call Xchangedtick_tests('l') 2520endfunc 2521 2522" Tests for parsing an expression using setqflist() 2523func Xsetexpr_tests(cchar) 2524 call s:setup_commands(a:cchar) 2525 2526 let t = ["File1:10:Line10", "File1:20:Line20"] 2527 call g:Xsetlist([], ' ', {'lines' : t}) 2528 call g:Xsetlist([], 'a', {'lines' : ["File1:30:Line30"]}) 2529 2530 let l = g:Xgetlist() 2531 call assert_equal(3, len(l)) 2532 call assert_equal(20, l[1].lnum) 2533 call assert_equal('Line30', l[2].text) 2534 call g:Xsetlist([], 'r', {'lines' : ["File2:5:Line5"]}) 2535 let l = g:Xgetlist() 2536 call assert_equal(1, len(l)) 2537 call assert_equal('Line5', l[0].text) 2538 call assert_equal(-1, g:Xsetlist([], 'a', {'lines' : 10})) 2539 call assert_equal(-1, g:Xsetlist([], 'a', {'lines' : "F1:10:L10"})) 2540 2541 call g:Xsetlist([], 'f') 2542 " Add entries to multiple lists 2543 call g:Xsetlist([], 'a', {'nr' : 1, 'lines' : ["File1:10:Line10"]}) 2544 call g:Xsetlist([], 'a', {'nr' : 2, 'lines' : ["File2:20:Line20"]}) 2545 call g:Xsetlist([], 'a', {'nr' : 1, 'lines' : ["File1:15:Line15"]}) 2546 call g:Xsetlist([], 'a', {'nr' : 2, 'lines' : ["File2:25:Line25"]}) 2547 call assert_equal('Line15', g:Xgetlist({'nr':1, 'items':1}).items[1].text) 2548 call assert_equal('Line25', g:Xgetlist({'nr':2, 'items':1}).items[1].text) 2549 2550 " Adding entries using a custom efm 2551 set efm& 2552 call g:Xsetlist([], ' ', {'efm' : '%f#%l#%m', 2553 \ 'lines' : ["F1#10#L10", "F2#20#L20"]}) 2554 call assert_equal(20, g:Xgetlist({'items':1}).items[1].lnum) 2555 call g:Xsetlist([], 'a', {'efm' : '%f#%l#%m', 'lines' : ["F3:30:L30"]}) 2556 call assert_equal('F3:30:L30', g:Xgetlist({'items':1}).items[2].text) 2557 call assert_equal(20, g:Xgetlist({'items':1}).items[1].lnum) 2558 call assert_equal(-1, g:Xsetlist([], 'a', {'efm' : [], 2559 \ 'lines' : ['F1:10:L10']})) 2560endfunc 2561 2562func Test_setexpr() 2563 call Xsetexpr_tests('c') 2564 call Xsetexpr_tests('l') 2565endfunc 2566 2567" Tests for per quickfix/location list directory stack 2568func Xmultidirstack_tests(cchar) 2569 call s:setup_commands(a:cchar) 2570 2571 call g:Xsetlist([], 'f') 2572 Xexpr "" | Xexpr "" 2573 2574 call g:Xsetlist([], 'a', {'nr' : 1, 'lines' : ["Entering dir 'Xone/a'"]}) 2575 call g:Xsetlist([], 'a', {'nr' : 2, 'lines' : ["Entering dir 'Xtwo/a'"]}) 2576 call g:Xsetlist([], 'a', {'nr' : 1, 'lines' : ["one.txt:3:one one one"]}) 2577 call g:Xsetlist([], 'a', {'nr' : 2, 'lines' : ["two.txt:5:two two two"]}) 2578 2579 let l1 = g:Xgetlist({'nr':1, 'items':1}) 2580 let l2 = g:Xgetlist({'nr':2, 'items':1}) 2581 call assert_equal('Xone/a/one.txt', bufname(l1.items[1].bufnr)) 2582 call assert_equal(3, l1.items[1].lnum) 2583 call assert_equal('Xtwo/a/two.txt', bufname(l2.items[1].bufnr)) 2584 call assert_equal(5, l2.items[1].lnum) 2585endfunc 2586 2587func Test_multidirstack() 2588 call mkdir('Xone/a', 'p') 2589 call mkdir('Xtwo/a', 'p') 2590 let lines = ['1', '2', 'one one one', '4', 'two two two', '6', '7'] 2591 call writefile(lines, 'Xone/a/one.txt') 2592 call writefile(lines, 'Xtwo/a/two.txt') 2593 let save_efm = &efm 2594 set efm=%DEntering\ dir\ '%f',%f:%l:%m,%XLeaving\ dir\ '%f' 2595 2596 call Xmultidirstack_tests('c') 2597 call Xmultidirstack_tests('l') 2598 2599 let &efm = save_efm 2600 call delete('Xone', 'rf') 2601 call delete('Xtwo', 'rf') 2602endfunc 2603 2604" Tests for per quickfix/location list file stack 2605func Xmultifilestack_tests(cchar) 2606 call s:setup_commands(a:cchar) 2607 2608 call g:Xsetlist([], 'f') 2609 Xexpr "" | Xexpr "" 2610 2611 call g:Xsetlist([], 'a', {'nr' : 1, 'lines' : ["[one.txt]"]}) 2612 call g:Xsetlist([], 'a', {'nr' : 2, 'lines' : ["[two.txt]"]}) 2613 call g:Xsetlist([], 'a', {'nr' : 1, 'lines' : ["(3,5) one one one"]}) 2614 call g:Xsetlist([], 'a', {'nr' : 2, 'lines' : ["(5,9) two two two"]}) 2615 2616 let l1 = g:Xgetlist({'nr':1, 'items':1}) 2617 let l2 = g:Xgetlist({'nr':2, 'items':1}) 2618 call assert_equal('one.txt', bufname(l1.items[1].bufnr)) 2619 call assert_equal(3, l1.items[1].lnum) 2620 call assert_equal('two.txt', bufname(l2.items[1].bufnr)) 2621 call assert_equal(5, l2.items[1].lnum) 2622 2623 " Test for start of a new error line in the same line where a previous 2624 " error line ends with a file stack. 2625 let efm_val = 'Error\ l%l\ in\ %f,' 2626 let efm_val .= '%-P%>(%f%r,Error\ l%l\ in\ %m,%-Q)%r' 2627 let l = g:Xgetlist({'lines' : [ 2628 \ '(one.txt', 2629 \ 'Error l4 in one.txt', 2630 \ ') (two.txt', 2631 \ 'Error l6 in two.txt', 2632 \ ')', 2633 \ 'Error l8 in one.txt' 2634 \ ], 'efm' : efm_val}) 2635 call assert_equal(3, len(l.items)) 2636 call assert_equal('one.txt', bufname(l.items[0].bufnr)) 2637 call assert_equal(4, l.items[0].lnum) 2638 call assert_equal('one.txt', l.items[0].text) 2639 call assert_equal('two.txt', bufname(l.items[1].bufnr)) 2640 call assert_equal(6, l.items[1].lnum) 2641 call assert_equal('two.txt', l.items[1].text) 2642 call assert_equal('one.txt', bufname(l.items[2].bufnr)) 2643 call assert_equal(8, l.items[2].lnum) 2644 call assert_equal('', l.items[2].text) 2645endfunc 2646 2647func Test_multifilestack() 2648 let lines = ['1', '2', 'one one one', '4', 'two two two', '6', '7'] 2649 call writefile(lines, 'one.txt') 2650 call writefile(lines, 'two.txt') 2651 let save_efm = &efm 2652 set efm=%+P[%f],(%l\\,%c)\ %m,%-Q 2653 2654 call Xmultifilestack_tests('c') 2655 call Xmultifilestack_tests('l') 2656 2657 let &efm = save_efm 2658 call delete('one.txt') 2659 call delete('two.txt') 2660endfunc 2661 2662" Tests for per buffer 'efm' setting 2663func Test_perbuf_efm() 2664 call writefile(["File1-10-Line10"], 'one.txt') 2665 call writefile(["File2#20#Line20"], 'two.txt') 2666 set efm=%f#%l#%m 2667 new | only 2668 new 2669 setlocal efm=%f-%l-%m 2670 cfile one.txt 2671 wincmd w 2672 caddfile two.txt 2673 2674 let l = getqflist() 2675 call assert_equal(10, l[0].lnum) 2676 call assert_equal('Line20', l[1].text) 2677 2678 set efm& 2679 new | only 2680 call delete('one.txt') 2681 call delete('two.txt') 2682endfunc 2683 2684" Open multiple help windows using ":lhelpgrep 2685" This test used to crash Vim 2686func Test_Multi_LL_Help() 2687 new | only 2688 lhelpgrep window 2689 lopen 2690 e# 2691 lhelpgrep buffer 2692 call assert_equal(3, winnr('$')) 2693 call assert_true(len(getloclist(1)) != 0) 2694 call assert_true(len(getloclist(2)) != 0) 2695 new | only 2696endfunc 2697 2698" Tests for adding new quickfix lists using setqflist() 2699func XaddQf_tests(cchar) 2700 call s:setup_commands(a:cchar) 2701 2702 " Create a new list using ' ' for action 2703 call g:Xsetlist([], 'f') 2704 call g:Xsetlist([], ' ', {'title' : 'Test1'}) 2705 let l = g:Xgetlist({'nr' : '$', 'all' : 1}) 2706 call assert_equal(1, l.nr) 2707 call assert_equal('Test1', l.title) 2708 2709 " Create a new list using ' ' for action and '$' for 'nr' 2710 call g:Xsetlist([], 'f') 2711 call g:Xsetlist([], ' ', {'title' : 'Test2', 'nr' : '$'}) 2712 let l = g:Xgetlist({'nr' : '$', 'all' : 1}) 2713 call assert_equal(1, l.nr) 2714 call assert_equal('Test2', l.title) 2715 2716 " Create a new list using 'a' for action 2717 call g:Xsetlist([], 'f') 2718 call g:Xsetlist([], 'a', {'title' : 'Test3'}) 2719 let l = g:Xgetlist({'nr' : '$', 'all' : 1}) 2720 call assert_equal(1, l.nr) 2721 call assert_equal('Test3', l.title) 2722 2723 " Create a new list using 'a' for action and '$' for 'nr' 2724 call g:Xsetlist([], 'f') 2725 call g:Xsetlist([], 'a', {'title' : 'Test3', 'nr' : '$'}) 2726 call g:Xsetlist([], 'a', {'title' : 'Test4'}) 2727 let l = g:Xgetlist({'nr' : '$', 'all' : 1}) 2728 call assert_equal(1, l.nr) 2729 call assert_equal('Test4', l.title) 2730 2731 " Adding a quickfix list should remove all the lists following the current 2732 " list. 2733 Xexpr "" | Xexpr "" | Xexpr "" 2734 silent! 10Xolder 2735 call g:Xsetlist([], ' ', {'title' : 'Test5'}) 2736 let l = g:Xgetlist({'nr' : '$', 'all' : 1}) 2737 call assert_equal(2, l.nr) 2738 call assert_equal('Test5', l.title) 2739 2740 " Add a quickfix list using '$' as the list number. 2741 let lastqf = g:Xgetlist({'nr':'$'}).nr 2742 silent! 99Xolder 2743 call g:Xsetlist([], ' ', {'nr' : '$', 'title' : 'Test6'}) 2744 let l = g:Xgetlist({'nr' : '$', 'all' : 1}) 2745 call assert_equal(lastqf + 1, l.nr) 2746 call assert_equal('Test6', l.title) 2747 2748 " Add a quickfix list using 'nr' set to one more than the quickfix 2749 " list size. 2750 let lastqf = g:Xgetlist({'nr':'$'}).nr 2751 silent! 99Xolder 2752 call g:Xsetlist([], ' ', {'nr' : lastqf + 1, 'title' : 'Test7'}) 2753 let l = g:Xgetlist({'nr' : '$', 'all' : 1}) 2754 call assert_equal(lastqf + 1, l.nr) 2755 call assert_equal('Test7', l.title) 2756 2757 " Add a quickfix list to a stack with 10 lists using 'nr' set to '$' 2758 exe repeat('Xexpr "" |', 9) . 'Xexpr ""' 2759 silent! 99Xolder 2760 call g:Xsetlist([], ' ', {'nr' : '$', 'title' : 'Test8'}) 2761 let l = g:Xgetlist({'nr' : '$', 'all' : 1}) 2762 call assert_equal(10, l.nr) 2763 call assert_equal('Test8', l.title) 2764 2765 " Add a quickfix list using 'nr' set to a value greater than 10 2766 call assert_equal(-1, g:Xsetlist([], ' ', {'nr' : 12, 'title' : 'Test9'})) 2767 2768 " Try adding a quickfix list with 'nr' set to a value greater than the 2769 " quickfix list size but less than 10. 2770 call g:Xsetlist([], 'f') 2771 Xexpr "" | Xexpr "" | Xexpr "" 2772 silent! 99Xolder 2773 call assert_equal(-1, g:Xsetlist([], ' ', {'nr' : 8, 'title' : 'Test10'})) 2774 2775 " Add a quickfix list using 'nr' set to a some string or list 2776 call assert_equal(-1, g:Xsetlist([], ' ', {'nr' : [1,2], 'title' : 'Test11'})) 2777endfunc 2778 2779func Test_add_qf() 2780 call XaddQf_tests('c') 2781 call XaddQf_tests('l') 2782endfunc 2783 2784" Test for getting the quickfix list items from some text without modifying 2785" the quickfix stack 2786func XgetListFromLines(cchar) 2787 call s:setup_commands(a:cchar) 2788 call g:Xsetlist([], 'f') 2789 2790 let l = g:Xgetlist({'lines' : ["File2:20:Line20", "File2:30:Line30"]}).items 2791 call assert_equal(2, len(l)) 2792 call assert_equal(30, l[1].lnum) 2793 2794 call assert_equal({}, g:Xgetlist({'lines' : 10})) 2795 call assert_equal({}, g:Xgetlist({'lines' : 'File1:10:Line10'})) 2796 call assert_equal([], g:Xgetlist({'lines' : []}).items) 2797 call assert_equal([], g:Xgetlist({'lines' : [10, 20]}).items) 2798 2799 " Parse text using a custom efm 2800 set efm& 2801 let l = g:Xgetlist({'lines':['File3#30#Line30'], 'efm' : '%f#%l#%m'}).items 2802 call assert_equal('Line30', l[0].text) 2803 let l = g:Xgetlist({'lines':['File3:30:Line30'], 'efm' : '%f-%l-%m'}).items 2804 call assert_equal('File3:30:Line30', l[0].text) 2805 let l = g:Xgetlist({'lines':['File3:30:Line30'], 'efm' : [1,2]}) 2806 call assert_equal({}, l) 2807 call assert_fails("call g:Xgetlist({'lines':['abc'], 'efm':'%2'})", 'E376:') 2808 call assert_fails("call g:Xgetlist({'lines':['abc'], 'efm':''})", 'E378:') 2809 2810 " Make sure that the quickfix stack is not modified 2811 call assert_equal(0, g:Xgetlist({'nr' : '$'}).nr) 2812endfunc 2813 2814func Test_get_list_from_lines() 2815 call XgetListFromLines('c') 2816 call XgetListFromLines('l') 2817endfunc 2818 2819" Tests for the quickfix list id 2820func Xqfid_tests(cchar) 2821 call s:setup_commands(a:cchar) 2822 2823 call g:Xsetlist([], 'f') 2824 call assert_equal(0, g:Xgetlist({'id':0}).id) 2825 Xexpr '' 2826 let start_id = g:Xgetlist({'id' : 0}).id 2827 Xexpr '' | Xexpr '' 2828 Xolder 2829 call assert_equal(start_id, g:Xgetlist({'id':0, 'nr':1}).id) 2830 call assert_equal(start_id + 1, g:Xgetlist({'id':0, 'nr':0}).id) 2831 call assert_equal(start_id + 2, g:Xgetlist({'id':0, 'nr':'$'}).id) 2832 call assert_equal(0, g:Xgetlist({'id':0, 'nr':99}).id) 2833 call assert_equal(2, g:Xgetlist({'id':start_id + 1, 'nr':0}).nr) 2834 call assert_equal(0, g:Xgetlist({'id':99, 'nr':0}).id) 2835 call assert_equal(0, g:Xgetlist({'id':"abc", 'nr':0}).id) 2836 2837 call g:Xsetlist([], 'a', {'id':start_id, 'context':[1,2]}) 2838 call assert_equal([1,2], g:Xgetlist({'nr':1, 'context':1}).context) 2839 call g:Xsetlist([], 'a', {'id':start_id+1, 'lines':['F1:10:L10']}) 2840 call assert_equal('L10', g:Xgetlist({'nr':2, 'items':1}).items[0].text) 2841 call assert_equal(-1, g:Xsetlist([], 'a', {'id':999, 'title':'Vim'})) 2842 call assert_equal(-1, g:Xsetlist([], 'a', {'id':'abc', 'title':'Vim'})) 2843 2844 let qfid = g:Xgetlist({'id':0, 'nr':0}) 2845 call g:Xsetlist([], 'f') 2846 call assert_equal(0, g:Xgetlist({'id':qfid, 'nr':0}).id) 2847endfunc 2848 2849func Test_qf_id() 2850 call Xqfid_tests('c') 2851 call Xqfid_tests('l') 2852endfunc 2853 2854func Xqfjump_tests(cchar) 2855 call s:setup_commands(a:cchar) 2856 2857 call writefile(["Line1\tFoo", "Line2"], 'F1') 2858 call writefile(["Line1\tBar", "Line2"], 'F2') 2859 call writefile(["Line1\tBaz", "Line2"], 'F3') 2860 2861 call g:Xsetlist([], 'f') 2862 2863 " Tests for 2864 " Jumping to a line using a pattern 2865 " Jumping to a column greater than the last column in a line 2866 " Jumping to a line greater than the last line in the file 2867 let l = [] 2868 for i in range(1, 7) 2869 call add(l, {}) 2870 endfor 2871 let l[0].filename='F1' 2872 let l[0].pattern='Line1' 2873 let l[1].filename='F2' 2874 let l[1].pattern='Line1' 2875 let l[2].filename='F3' 2876 let l[2].pattern='Line1' 2877 let l[3].filename='F3' 2878 let l[3].lnum=1 2879 let l[3].col=9 2880 let l[3].vcol=1 2881 let l[4].filename='F3' 2882 let l[4].lnum=99 2883 let l[5].filename='F3' 2884 let l[5].lnum=1 2885 let l[5].col=99 2886 let l[5].vcol=1 2887 let l[6].filename='F3' 2888 let l[6].pattern='abcxyz' 2889 2890 call g:Xsetlist([], ' ', {'items' : l}) 2891 Xopen | only 2892 2Xnext 2893 call assert_equal(3, g:Xgetlist({'idx' : 0}).idx) 2894 call assert_equal('F3', bufname('%')) 2895 Xnext 2896 call assert_equal(7, col('.')) 2897 Xnext 2898 call assert_equal(2, line('.')) 2899 Xnext 2900 call assert_equal(9, col('.')) 2901 2 2902 Xnext 2903 call assert_equal(2, line('.')) 2904 2905 if a:cchar == 'l' 2906 " When jumping to a location list entry in the location list window and 2907 " no usable windows are available, then a new window should be opened. 2908 enew! | new | only 2909 call g:Xsetlist([], 'f') 2910 setlocal buftype=nofile 2911 new 2912 call g:Xsetlist([], ' ', {'lines' : ['F1:1:1:Line1', 'F1:2:2:Line2', 'F2:1:1:Line1', 'F2:2:2:Line2', 'F3:1:1:Line1', 'F3:2:2:Line2']}) 2913 Xopen 2914 let winid = win_getid() 2915 wincmd p 2916 close 2917 call win_gotoid(winid) 2918 Xnext 2919 call assert_equal(3, winnr('$')) 2920 call assert_equal(1, winnr()) 2921 call assert_equal(2, line('.')) 2922 2923 " When jumping to an entry in the location list window and the window 2924 " associated with the location list is not present and a window containing 2925 " the file is already present, then that window should be used. 2926 close 2927 belowright new 2928 call g:Xsetlist([], 'f') 2929 edit F3 2930 call win_gotoid(winid) 2931 Xlast 2932 call assert_equal(3, winnr()) 2933 call assert_equal(6, g:Xgetlist({'size' : 1}).size) 2934 call assert_equal(winid, g:Xgetlist({'winid' : 1}).winid) 2935 endif 2936 2937 " Cleanup 2938 enew! 2939 new | only 2940 2941 call delete('F1') 2942 call delete('F2') 2943 call delete('F3') 2944endfunc 2945 2946func Test_qfjump() 2947 call Xqfjump_tests('c') 2948 call Xqfjump_tests('l') 2949endfunc 2950 2951" Tests for the getqflist() and getloclist() functions when the list is not 2952" present or is empty 2953func Xgetlist_empty_tests(cchar) 2954 call s:setup_commands(a:cchar) 2955 2956 " Empty quickfix stack 2957 call g:Xsetlist([], 'f') 2958 call assert_equal('', g:Xgetlist({'context' : 0}).context) 2959 call assert_equal(0, g:Xgetlist({'id' : 0}).id) 2960 call assert_equal(0, g:Xgetlist({'idx' : 0}).idx) 2961 call assert_equal([], g:Xgetlist({'items' : 0}).items) 2962 call assert_equal(0, g:Xgetlist({'nr' : 0}).nr) 2963 call assert_equal(0, g:Xgetlist({'size' : 0}).size) 2964 call assert_equal('', g:Xgetlist({'title' : 0}).title) 2965 call assert_equal(0, g:Xgetlist({'winid' : 0}).winid) 2966 call assert_equal(0, g:Xgetlist({'changedtick' : 0}).changedtick) 2967 call assert_equal({'context' : '', 'id' : 0, 'idx' : 0, 'items' : [], 'nr' : 0, 'size' : 0, 'title' : '', 'winid' : 0, 'changedtick': 0}, g:Xgetlist({'all' : 0})) 2968 2969 " Quickfix window with empty stack 2970 silent! Xopen 2971 let qfwinid = (a:cchar == 'c') ? win_getid() : 0 2972 call assert_equal(qfwinid, g:Xgetlist({'winid' : 0}).winid) 2973 Xclose 2974 2975 " Empty quickfix list 2976 Xexpr "" 2977 call assert_equal('', g:Xgetlist({'context' : 0}).context) 2978 call assert_notequal(0, g:Xgetlist({'id' : 0}).id) 2979 call assert_equal(0, g:Xgetlist({'idx' : 0}).idx) 2980 call assert_equal([], g:Xgetlist({'items' : 0}).items) 2981 call assert_notequal(0, g:Xgetlist({'nr' : 0}).nr) 2982 call assert_equal(0, g:Xgetlist({'size' : 0}).size) 2983 call assert_notequal('', g:Xgetlist({'title' : 0}).title) 2984 call assert_equal(0, g:Xgetlist({'winid' : 0}).winid) 2985 call assert_equal(1, g:Xgetlist({'changedtick' : 0}).changedtick) 2986 2987 let qfid = g:Xgetlist({'id' : 0}).id 2988 call g:Xsetlist([], 'f') 2989 2990 " Non-existing quickfix identifier 2991 call assert_equal('', g:Xgetlist({'id' : qfid, 'context' : 0}).context) 2992 call assert_equal(0, g:Xgetlist({'id' : qfid}).id) 2993 call assert_equal(0, g:Xgetlist({'id' : qfid, 'idx' : 0}).idx) 2994 call assert_equal([], g:Xgetlist({'id' : qfid, 'items' : 0}).items) 2995 call assert_equal(0, g:Xgetlist({'id' : qfid, 'nr' : 0}).nr) 2996 call assert_equal(0, g:Xgetlist({'id' : qfid, 'size' : 0}).size) 2997 call assert_equal('', g:Xgetlist({'id' : qfid, 'title' : 0}).title) 2998 call assert_equal(0, g:Xgetlist({'id' : qfid, 'winid' : 0}).winid) 2999 call assert_equal(0, g:Xgetlist({'id' : qfid, 'changedtick' : 0}).changedtick) 3000 call assert_equal({'context' : '', 'id' : 0, 'idx' : 0, 'items' : [], 'nr' : 0, 'size' : 0, 'title' : '', 'winid' : 0, 'changedtick' : 0}, g:Xgetlist({'id' : qfid, 'all' : 0})) 3001 3002 " Non-existing quickfix list number 3003 call assert_equal('', g:Xgetlist({'nr' : 5, 'context' : 0}).context) 3004 call assert_equal(0, g:Xgetlist({'nr' : 5}).nr) 3005 call assert_equal(0, g:Xgetlist({'nr' : 5, 'idx' : 0}).idx) 3006 call assert_equal([], g:Xgetlist({'nr' : 5, 'items' : 0}).items) 3007 call assert_equal(0, g:Xgetlist({'nr' : 5, 'id' : 0}).id) 3008 call assert_equal(0, g:Xgetlist({'nr' : 5, 'size' : 0}).size) 3009 call assert_equal('', g:Xgetlist({'nr' : 5, 'title' : 0}).title) 3010 call assert_equal(0, g:Xgetlist({'nr' : 5, 'winid' : 0}).winid) 3011 call assert_equal(0, g:Xgetlist({'nr' : 5, 'changedtick' : 0}).changedtick) 3012 call assert_equal({'context' : '', 'id' : 0, 'idx' : 0, 'items' : [], 'nr' : 0, 'size' : 0, 'title' : '', 'winid' : 0, 'changedtick' : 0}, g:Xgetlist({'nr' : 5, 'all' : 0})) 3013endfunc 3014 3015func Test_getqflist() 3016 call Xgetlist_empty_tests('c') 3017 call Xgetlist_empty_tests('l') 3018endfunc 3019 3020func Test_getqflist_invalid_nr() 3021 " The following commands used to crash Vim 3022 cexpr "" 3023 call getqflist({'nr' : $XXX_DOES_NOT_EXIST_XXX}) 3024 3025 " Cleanup 3026 call setqflist([], 'r') 3027endfunc 3028 3029" Tests for the quickfix/location list changedtick 3030func Xqftick_tests(cchar) 3031 call s:setup_commands(a:cchar) 3032 3033 call g:Xsetlist([], 'f') 3034 3035 Xexpr "F1:10:Line10" 3036 let qfid = g:Xgetlist({'id' : 0}).id 3037 call assert_equal(1, g:Xgetlist({'changedtick' : 0}).changedtick) 3038 Xaddexpr "F2:20:Line20\nF2:21:Line21" 3039 call assert_equal(2, g:Xgetlist({'changedtick' : 0}).changedtick) 3040 call g:Xsetlist([], 'a', {'lines' : ["F3:30:Line30", "F3:31:Line31"]}) 3041 call assert_equal(3, g:Xgetlist({'changedtick' : 0}).changedtick) 3042 call g:Xsetlist([], 'r', {'lines' : ["F4:40:Line40"]}) 3043 call assert_equal(4, g:Xgetlist({'changedtick' : 0}).changedtick) 3044 call g:Xsetlist([], 'a', {'title' : 'New Title'}) 3045 call assert_equal(5, g:Xgetlist({'changedtick' : 0}).changedtick) 3046 3047 enew! 3048 call append(0, ["F5:50:L50", "F6:60:L60"]) 3049 Xaddbuffer 3050 call assert_equal(6, g:Xgetlist({'changedtick' : 0}).changedtick) 3051 enew! 3052 3053 call g:Xsetlist([], 'a', {'context' : {'bus' : 'pci'}}) 3054 call assert_equal(7, g:Xgetlist({'changedtick' : 0}).changedtick) 3055 call g:Xsetlist([{'filename' : 'F7', 'lnum' : 10, 'text' : 'L7'}, 3056 \ {'filename' : 'F7', 'lnum' : 11, 'text' : 'L11'}], 'a') 3057 call assert_equal(8, g:Xgetlist({'changedtick' : 0}).changedtick) 3058 call g:Xsetlist([{'filename' : 'F7', 'lnum' : 10, 'text' : 'L7'}, 3059 \ {'filename' : 'F7', 'lnum' : 11, 'text' : 'L11'}], ' ') 3060 call assert_equal(1, g:Xgetlist({'changedtick' : 0}).changedtick) 3061 call g:Xsetlist([{'filename' : 'F7', 'lnum' : 10, 'text' : 'L7'}, 3062 \ {'filename' : 'F7', 'lnum' : 11, 'text' : 'L11'}], 'r') 3063 call assert_equal(2, g:Xgetlist({'changedtick' : 0}).changedtick) 3064 3065 call writefile(["F8:80:L80", "F8:81:L81"], "Xone") 3066 Xfile Xone 3067 call assert_equal(1, g:Xgetlist({'changedtick' : 0}).changedtick) 3068 Xaddfile Xone 3069 call assert_equal(2, g:Xgetlist({'changedtick' : 0}).changedtick) 3070 3071 " Test case for updating a non-current quickfix list 3072 call g:Xsetlist([], 'f') 3073 Xexpr "F1:1:L1" 3074 Xexpr "F2:2:L2" 3075 call g:Xsetlist([], 'a', {'nr' : 1, "lines" : ["F10:10:L10"]}) 3076 call assert_equal(1, g:Xgetlist({'changedtick' : 0}).changedtick) 3077 call assert_equal(2, g:Xgetlist({'nr' : 1, 'changedtick' : 0}).changedtick) 3078 3079 call delete("Xone") 3080endfunc 3081 3082func Test_qf_tick() 3083 call Xqftick_tests('c') 3084 call Xqftick_tests('l') 3085endfunc 3086 3087" The following test used to crash Vim. 3088" Open the location list window and close the regular window associated with 3089" the location list. When the garbage collection runs now, it incorrectly 3090" marks the location list context as not in use and frees the context. 3091func Test_ll_window_ctx() 3092 call setloclist(0, [], 'f') 3093 call setloclist(0, [], 'a', {'context' : []}) 3094 lopen | only 3095 call test_garbagecollect_now() 3096 echo getloclist(0, {'context' : 1}).context 3097 enew | only 3098endfunc 3099 3100" The following test used to crash vim 3101func Test_lfile_crash() 3102 sp Xtest 3103 au QuickFixCmdPre * bw 3104 call assert_fails('lfile', 'E40') 3105 au! QuickFixCmdPre 3106endfunc 3107 3108" The following test used to crash vim 3109func Test_lbuffer_crash() 3110 sv Xtest 3111 augroup QF_Test 3112 au! 3113 au * * bw 3114 augroup END 3115 lbuffer 3116 augroup QF_Test 3117 au! 3118 augroup END 3119endfunc 3120 3121" The following test used to crash vim 3122func Test_lexpr_crash() 3123 augroup QF_Test 3124 au! 3125 au * * call setloclist(0, [], 'f') 3126 augroup END 3127 lexpr "" 3128 augroup QF_Test 3129 au! 3130 augroup END 3131 enew | only 3132endfunc 3133 3134" The following test used to crash Vim 3135func Test_lvimgrep_crash() 3136 sv Xtest 3137 augroup QF_Test 3138 au! 3139 au * * call setloclist(0, [], 'f') 3140 augroup END 3141 lvimgrep quickfix test_quickfix.vim 3142 augroup QF_Test 3143 au! 3144 augroup END 3145 enew | only 3146endfunc 3147 3148" Test for the position of the quickfix and location list window 3149func Test_qfwin_pos() 3150 " Open two windows 3151 new | only 3152 new 3153 cexpr ['F1:10:L10'] 3154 copen 3155 " Quickfix window should be the bottom most window 3156 call assert_equal(3, winnr()) 3157 close 3158 " Open at the very top 3159 wincmd t 3160 topleft copen 3161 call assert_equal(1, winnr()) 3162 close 3163 " open left of the current window 3164 wincmd t 3165 below new 3166 leftabove copen 3167 call assert_equal(2, winnr()) 3168 close 3169 " open right of the current window 3170 rightbelow copen 3171 call assert_equal(3, winnr()) 3172 close 3173endfunc 3174 3175" Tests for quickfix/location lists changed by autocommands when 3176" :vimgrep/:lvimgrep commands are running. 3177func Test_vimgrep_autocmd() 3178 call setqflist([], 'f') 3179 call writefile(['stars'], 'Xtest1.txt') 3180 call writefile(['stars'], 'Xtest2.txt') 3181 3182 " Test 1: 3183 " When searching for a pattern using :vimgrep, if the quickfix list is 3184 " changed by an autocmd, the results should be added to the correct quickfix 3185 " list. 3186 autocmd BufRead Xtest2.txt cexpr '' | cexpr '' 3187 silent vimgrep stars Xtest*.txt 3188 call assert_equal(1, getqflist({'nr' : 0}).nr) 3189 call assert_equal(3, getqflist({'nr' : '$'}).nr) 3190 call assert_equal('Xtest2.txt', bufname(getqflist()[1].bufnr)) 3191 au! BufRead Xtest2.txt 3192 3193 " Test 2: 3194 " When searching for a pattern using :vimgrep, if the quickfix list is 3195 " freed, then a error should be given. 3196 silent! %bwipe! 3197 call setqflist([], 'f') 3198 autocmd BufRead Xtest2.txt for i in range(10) | cexpr '' | endfor 3199 call assert_fails('vimgrep stars Xtest*.txt', 'E925:') 3200 au! BufRead Xtest2.txt 3201 3202 " Test 3: 3203 " When searching for a pattern using :lvimgrep, if the location list is 3204 " freed, then the command should error out. 3205 silent! %bwipe! 3206 let g:save_winid = win_getid() 3207 autocmd BufRead Xtest2.txt call setloclist(g:save_winid, [], 'f') 3208 call assert_fails('lvimgrep stars Xtest*.txt', 'E926:') 3209 au! BufRead Xtest2.txt 3210 3211 call delete('Xtest1.txt') 3212 call delete('Xtest2.txt') 3213 call setqflist([], 'f') 3214endfunc 3215 3216" The following test used to crash Vim 3217func Test_lhelpgrep_autocmd() 3218 lhelpgrep quickfix 3219 autocmd QuickFixCmdPost * call setloclist(0, [], 'f') 3220 lhelpgrep buffer 3221 call assert_equal('help', &filetype) 3222 call assert_equal(0, getloclist(0, {'nr' : '$'}).nr) 3223 lhelpgrep tabpage 3224 call assert_equal('help', &filetype) 3225 call assert_equal(1, getloclist(0, {'nr' : '$'}).nr) 3226 au! QuickFixCmdPost 3227 new | only 3228endfunc 3229 3230" Test for shortening/simplifying the file name when opening the 3231" quickfix window or when displaying the quickfix list 3232func Test_shorten_fname() 3233 if !has('unix') 3234 return 3235 endif 3236 %bwipe 3237 " Create a quickfix list with a absolute path filename 3238 let fname = getcwd() . '/test_quickfix.vim' 3239 call setqflist([], ' ', {'lines':[fname . ":20:Line20"], 'efm':'%f:%l:%m'}) 3240 call assert_equal(fname, bufname('test_quickfix.vim')) 3241 " Opening the quickfix window should simplify the file path 3242 cwindow 3243 call assert_equal('test_quickfix.vim', bufname('test_quickfix.vim')) 3244 cclose 3245 %bwipe 3246 " Create a quickfix list with a absolute path filename 3247 call setqflist([], ' ', {'lines':[fname . ":20:Line20"], 'efm':'%f:%l:%m'}) 3248 call assert_equal(fname, bufname('test_quickfix.vim')) 3249 " Displaying the quickfix list should simplify the file path 3250 silent! clist 3251 call assert_equal('test_quickfix.vim', bufname('test_quickfix.vim')) 3252endfunc 3253