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