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 1799 Xopen 1800 call assert_equal('Sample', w:quickfix_title) 1801 Xclose 1802 1803 " Tests for action argument 1804 silent! Xolder 999 1805 let qfnr = g:Xgetlist({'all':1}).nr 1806 call g:Xsetlist([], 'r', {'title' : 'N1'}) 1807 call assert_equal('N1', g:Xgetlist({'all':1}).title) 1808 call g:Xsetlist([], ' ', {'title' : 'N2'}) 1809 call assert_equal(qfnr + 1, g:Xgetlist({'all':1}).nr) 1810 1811 let res = g:Xgetlist({'nr': 0}) 1812 call assert_equal(qfnr + 1, res.nr) 1813 call assert_equal(['nr'], keys(res)) 1814 1815 call g:Xsetlist([], ' ', {'title' : 'N3'}) 1816 call assert_equal('N2', g:Xgetlist({'nr':2, 'title':1}).title) 1817 1818 " Changing the title of an earlier quickfix list 1819 call g:Xsetlist([], 'r', {'title' : 'NewTitle', 'nr' : 2}) 1820 call assert_equal('NewTitle', g:Xgetlist({'nr':2, 'title':1}).title) 1821 1822 " Changing the title of an invalid quickfix list 1823 call assert_equal(-1, g:Xsetlist([], ' ', 1824 \ {'title' : 'SomeTitle', 'nr' : 99})) 1825 call assert_equal(-1, g:Xsetlist([], ' ', 1826 \ {'title' : 'SomeTitle', 'nr' : 'abc'})) 1827 1828 if a:cchar == 'c' 1829 copen 1830 call assert_equal({'winid':win_getid()}, getqflist({'winid':1})) 1831 cclose 1832 endif 1833 1834 " Invalid arguments 1835 call assert_fails('call g:Xgetlist([])', 'E715') 1836 call assert_fails('call g:Xsetlist([], "a", [])', 'E715') 1837 let s = g:Xsetlist([], 'a', {'abc':1}) 1838 call assert_equal(-1, s) 1839 1840 call assert_equal({}, g:Xgetlist({'abc':1})) 1841 call assert_equal('', g:Xgetlist({'nr':99, 'title':1}).title) 1842 call assert_equal('', g:Xgetlist({'nr':[], 'title':1}).title) 1843 1844 if a:cchar == 'l' 1845 call assert_equal({}, getloclist(99, {'title': 1})) 1846 endif 1847 1848 " Context related tests 1849 let s = g:Xsetlist([], 'a', {'context':[1,2,3]}) 1850 call assert_equal(0, s) 1851 call test_garbagecollect_now() 1852 let d = g:Xgetlist({'context':1}) 1853 call assert_equal([1,2,3], d.context) 1854 call g:Xsetlist([], 'a', {'context':{'color':'green'}}) 1855 let d = g:Xgetlist({'context':1}) 1856 call assert_equal({'color':'green'}, d.context) 1857 call g:Xsetlist([], 'a', {'context':"Context info"}) 1858 let d = g:Xgetlist({'context':1}) 1859 call assert_equal("Context info", d.context) 1860 call g:Xsetlist([], 'a', {'context':246}) 1861 let d = g:Xgetlist({'context':1}) 1862 call assert_equal(246, d.context) 1863 if a:cchar == 'l' 1864 " Test for copying context across two different location lists 1865 new | only 1866 let w1_id = win_getid() 1867 let l = [1] 1868 call setloclist(0, [], 'a', {'context':l}) 1869 new 1870 let w2_id = win_getid() 1871 call add(l, 2) 1872 call assert_equal([1, 2], getloclist(w1_id, {'context':1}).context) 1873 call assert_equal([1, 2], getloclist(w2_id, {'context':1}).context) 1874 unlet! l 1875 call assert_equal([1, 2], getloclist(w2_id, {'context':1}).context) 1876 only 1877 call setloclist(0, [], 'f') 1878 call assert_equal('', getloclist(0, {'context':1}).context) 1879 endif 1880 1881 " Test for changing the context of previous quickfix lists 1882 call g:Xsetlist([], 'f') 1883 Xexpr "One" 1884 Xexpr "Two" 1885 Xexpr "Three" 1886 call g:Xsetlist([], 'r', {'context' : [1], 'nr' : 1}) 1887 call g:Xsetlist([], 'a', {'context' : [2], 'nr' : 2}) 1888 " Also, check for setting the context using quickfix list number zero. 1889 call g:Xsetlist([], 'r', {'context' : [3], 'nr' : 0}) 1890 call test_garbagecollect_now() 1891 let l = g:Xgetlist({'nr' : 1, 'context' : 1}) 1892 call assert_equal([1], l.context) 1893 let l = g:Xgetlist({'nr' : 2, 'context' : 1}) 1894 call assert_equal([2], l.context) 1895 let l = g:Xgetlist({'nr' : 3, 'context' : 1}) 1896 call assert_equal([3], l.context) 1897 1898 " Test for changing the context through reference and for garbage 1899 " collection of quickfix context 1900 let l = ["red"] 1901 call g:Xsetlist([], ' ', {'context' : l}) 1902 call add(l, "blue") 1903 let x = g:Xgetlist({'context' : 1}) 1904 call add(x.context, "green") 1905 call assert_equal(["red", "blue", "green"], l) 1906 call assert_equal(["red", "blue", "green"], x.context) 1907 unlet l 1908 call test_garbagecollect_now() 1909 let m = g:Xgetlist({'context' : 1}) 1910 call assert_equal(["red", "blue", "green"], m.context) 1911 1912 " Test for setting/getting items 1913 Xexpr "" 1914 let qfprev = g:Xgetlist({'nr':0}) 1915 let s = g:Xsetlist([], ' ', {'title':'Green', 1916 \ 'items' : [{'filename':'F1', 'lnum':10}]}) 1917 call assert_equal(0, s) 1918 let qfcur = g:Xgetlist({'nr':0}) 1919 call assert_true(qfcur.nr == qfprev.nr + 1) 1920 let l = g:Xgetlist({'items':1}) 1921 call assert_equal('F1', bufname(l.items[0].bufnr)) 1922 call assert_equal(10, l.items[0].lnum) 1923 call g:Xsetlist([], 'a', {'items' : [{'filename':'F2', 'lnum':20}, 1924 \ {'filename':'F2', 'lnum':30}]}) 1925 let l = g:Xgetlist({'items':1}) 1926 call assert_equal('F2', bufname(l.items[2].bufnr)) 1927 call assert_equal(30, l.items[2].lnum) 1928 call g:Xsetlist([], 'r', {'items' : [{'filename':'F3', 'lnum':40}]}) 1929 let l = g:Xgetlist({'items':1}) 1930 call assert_equal('F3', bufname(l.items[0].bufnr)) 1931 call assert_equal(40, l.items[0].lnum) 1932 call g:Xsetlist([], 'r', {'items' : []}) 1933 let l = g:Xgetlist({'items':1}) 1934 call assert_equal(0, len(l.items)) 1935 1936 call g:Xsetlist([], 'r', {'title' : 'TestTitle'}) 1937 call g:Xsetlist([], 'r', {'items' : [{'filename' : 'F1', 'lnum' : 10, 'text' : 'L10'}]}) 1938 call g:Xsetlist([], 'r', {'items' : [{'filename' : 'F1', 'lnum' : 10, 'text' : 'L10'}]}) 1939 call assert_equal('TestTitle', g:Xgetlist({'title' : 1}).title) 1940 1941 " The following used to crash Vim with address sanitizer 1942 call g:Xsetlist([], 'f') 1943 call g:Xsetlist([], 'a', {'items' : [{'filename':'F1', 'lnum':10}]}) 1944 call assert_equal(10, g:Xgetlist({'items':1}).items[0].lnum) 1945 1946 " Save and restore the quickfix stack 1947 call g:Xsetlist([], 'f') 1948 call assert_equal(0, g:Xgetlist({'nr':'$'}).nr) 1949 Xexpr "File1:10:Line1" 1950 Xexpr "File2:20:Line2" 1951 Xexpr "File3:30:Line3" 1952 let last_qf = g:Xgetlist({'nr':'$'}).nr 1953 call assert_equal(3, last_qf) 1954 let qstack = [] 1955 for i in range(1, last_qf) 1956 let qstack = add(qstack, g:Xgetlist({'nr':i, 'all':1})) 1957 endfor 1958 call g:Xsetlist([], 'f') 1959 for i in range(len(qstack)) 1960 call g:Xsetlist([], ' ', qstack[i]) 1961 endfor 1962 call assert_equal(3, g:Xgetlist({'nr':'$'}).nr) 1963 call assert_equal(10, g:Xgetlist({'nr':1, 'items':1}).items[0].lnum) 1964 call assert_equal(20, g:Xgetlist({'nr':2, 'items':1}).items[0].lnum) 1965 call assert_equal(30, g:Xgetlist({'nr':3, 'items':1}).items[0].lnum) 1966 call g:Xsetlist([], 'f') 1967 1968 " Swap two quickfix lists 1969 Xexpr "File1:10:Line10" 1970 Xexpr "File2:20:Line20" 1971 Xexpr "File3:30:Line30" 1972 call g:Xsetlist([], 'r', {'nr':1,'title':'Colors','context':['Colors']}) 1973 call g:Xsetlist([], 'r', {'nr':2,'title':'Fruits','context':['Fruits']}) 1974 let l1=g:Xgetlist({'nr':1,'all':1}) 1975 let l2=g:Xgetlist({'nr':2,'all':1}) 1976 let save_id = l1.id 1977 let l1.id=l2.id 1978 let l2.id=save_id 1979 call g:Xsetlist([], 'r', l1) 1980 call g:Xsetlist([], 'r', l2) 1981 let newl1=g:Xgetlist({'nr':1,'all':1}) 1982 let newl2=g:Xgetlist({'nr':2,'all':1}) 1983 call assert_equal('Fruits', newl1.title) 1984 call assert_equal(['Fruits'], newl1.context) 1985 call assert_equal('Line20', newl1.items[0].text) 1986 call assert_equal('Colors', newl2.title) 1987 call assert_equal(['Colors'], newl2.context) 1988 call assert_equal('Line10', newl2.items[0].text) 1989 call g:Xsetlist([], 'f') 1990endfunc 1991 1992func Test_qf_property() 1993 call Xproperty_tests('c') 1994 call Xproperty_tests('l') 1995endfunc 1996 1997" Tests for the QuickFixCmdPre/QuickFixCmdPost autocommands 1998func QfAutoCmdHandler(loc, cmd) 1999 call add(g:acmds, a:loc . a:cmd) 2000endfunc 2001 2002func Test_Autocmd() 2003 autocmd QuickFixCmdPre * call QfAutoCmdHandler('pre', expand('<amatch>')) 2004 autocmd QuickFixCmdPost * call QfAutoCmdHandler('post', expand('<amatch>')) 2005 2006 let g:acmds = [] 2007 cexpr "F1:10:Line 10" 2008 caddexpr "F1:20:Line 20" 2009 cgetexpr "F1:30:Line 30" 2010 cexpr "" 2011 caddexpr "" 2012 cgetexpr "" 2013 silent! cexpr non_existing_func() 2014 silent! caddexpr non_existing_func() 2015 silent! cgetexpr non_existing_func() 2016 let l = ['precexpr', 2017 \ 'postcexpr', 2018 \ 'precaddexpr', 2019 \ 'postcaddexpr', 2020 \ 'precgetexpr', 2021 \ 'postcgetexpr', 2022 \ 'precexpr', 2023 \ 'postcexpr', 2024 \ 'precaddexpr', 2025 \ 'postcaddexpr', 2026 \ 'precgetexpr', 2027 \ 'postcgetexpr', 2028 \ 'precexpr', 2029 \ 'precaddexpr', 2030 \ 'precgetexpr'] 2031 call assert_equal(l, g:acmds) 2032 2033 let g:acmds = [] 2034 enew! | call append(0, "F2:10:Line 10") 2035 cbuffer! 2036 enew! | call append(0, "F2:20:Line 20") 2037 cgetbuffer 2038 enew! | call append(0, "F2:30:Line 30") 2039 caddbuffer 2040 new 2041 let bnum = bufnr('%') 2042 bunload 2043 exe 'silent! cbuffer! ' . bnum 2044 exe 'silent! cgetbuffer ' . bnum 2045 exe 'silent! caddbuffer ' . bnum 2046 enew! 2047 let l = ['precbuffer', 2048 \ 'postcbuffer', 2049 \ 'precgetbuffer', 2050 \ 'postcgetbuffer', 2051 \ 'precaddbuffer', 2052 \ 'postcaddbuffer', 2053 \ 'precbuffer', 2054 \ 'precgetbuffer', 2055 \ 'precaddbuffer'] 2056 call assert_equal(l, g:acmds) 2057 2058 call writefile(['Xtest:1:Line1'], 'Xtest') 2059 call writefile([], 'Xempty') 2060 let g:acmds = [] 2061 cfile Xtest 2062 caddfile Xtest 2063 cgetfile Xtest 2064 cfile Xempty 2065 caddfile Xempty 2066 cgetfile Xempty 2067 silent! cfile do_not_exist 2068 silent! caddfile do_not_exist 2069 silent! cgetfile do_not_exist 2070 let l = ['precfile', 2071 \ 'postcfile', 2072 \ 'precaddfile', 2073 \ 'postcaddfile', 2074 \ 'precgetfile', 2075 \ 'postcgetfile', 2076 \ 'precfile', 2077 \ 'postcfile', 2078 \ 'precaddfile', 2079 \ 'postcaddfile', 2080 \ 'precgetfile', 2081 \ 'postcgetfile', 2082 \ 'precfile', 2083 \ 'postcfile', 2084 \ 'precaddfile', 2085 \ 'postcaddfile', 2086 \ 'precgetfile', 2087 \ 'postcgetfile'] 2088 call assert_equal(l, g:acmds) 2089 2090 let g:acmds = [] 2091 helpgrep quickfix 2092 silent! helpgrep non_existing_help_topic 2093 vimgrep test Xtest 2094 vimgrepadd test Xtest 2095 silent! vimgrep non_existing_test Xtest 2096 silent! vimgrepadd non_existing_test Xtest 2097 set makeprg= 2098 silent! make 2099 set makeprg& 2100 let l = ['prehelpgrep', 2101 \ 'posthelpgrep', 2102 \ 'prehelpgrep', 2103 \ 'posthelpgrep', 2104 \ 'previmgrep', 2105 \ 'postvimgrep', 2106 \ 'previmgrepadd', 2107 \ 'postvimgrepadd', 2108 \ 'previmgrep', 2109 \ 'postvimgrep', 2110 \ 'previmgrepadd', 2111 \ 'postvimgrepadd', 2112 \ 'premake', 2113 \ 'postmake'] 2114 call assert_equal(l, g:acmds) 2115 2116 if has('unix') 2117 " Run this test only on Unix-like systems. The grepprg may not be set on 2118 " non-Unix systems. 2119 " The following lines are used for the grep test. Don't remove. 2120 " Grep_Autocmd_Text: Match 1 2121 " GrepAdd_Autocmd_Text: Match 2 2122 let g:acmds = [] 2123 silent grep Grep_Autocmd_Text test_quickfix.vim 2124 silent grepadd GrepAdd_Autocmd_Text test_quickfix.vim 2125 silent grep abc123def Xtest 2126 silent grepadd abc123def Xtest 2127 let l = ['pregrep', 2128 \ 'postgrep', 2129 \ 'pregrepadd', 2130 \ 'postgrepadd', 2131 \ 'pregrep', 2132 \ 'postgrep', 2133 \ 'pregrepadd', 2134 \ 'postgrepadd'] 2135 call assert_equal(l, g:acmds) 2136 endif 2137 2138 call delete('Xtest') 2139 call delete('Xempty') 2140 au! QuickFixCmdPre 2141 au! QuickFixCmdPost 2142endfunc 2143 2144func Test_Autocmd_Exception() 2145 set efm=%m 2146 lgetexpr '?' 2147 2148 try 2149 call DoesNotExit() 2150 catch 2151 lgetexpr '1' 2152 finally 2153 lgetexpr '1' 2154 endtry 2155 2156 call assert_equal('1', getloclist(0)[0].text) 2157 2158 set efm&vim 2159endfunc 2160 2161func Test_caddbuffer_wrong() 2162 " This used to cause a memory access in freed memory. 2163 let save_efm = &efm 2164 set efm=%EEEE%m,%WWWW,%+CCCC%>%#,%GGGG%.# 2165 cgetexpr ['WWWW', 'EEEE', 'CCCC'] 2166 let &efm = save_efm 2167 caddbuffer 2168 bwipe! 2169endfunc 2170 2171func Test_caddexpr_wrong() 2172 " This used to cause a memory access in freed memory. 2173 cbuffer 2174 cbuffer 2175 copen 2176 let save_efm = &efm 2177 set efm=% 2178 call assert_fails('caddexpr ""', 'E376:') 2179 let &efm = save_efm 2180endfunc 2181 2182func Test_dirstack_cleanup() 2183 " This used to cause a memory access in freed memory. 2184 let save_efm = &efm 2185 lexpr '0' 2186 lopen 2187 fun X(c) 2188 let save_efm=&efm 2189 set efm=%D%f 2190 if a:c == 'c' 2191 caddexpr '::' 2192 else 2193 laddexpr ':0:0' 2194 endif 2195 let &efm=save_efm 2196 endfun 2197 call X('c') 2198 call X('l') 2199 call setqflist([], 'r') 2200 caddbuffer 2201 let &efm = save_efm 2202endfunc 2203 2204" Tests for jumping to entries from the location list window and quickfix 2205" window 2206func Test_cwindow_jump() 2207 set efm=%f%%%l%%%m 2208 lgetexpr ["F1%10%Line 10", "F2%20%Line 20", "F3%30%Line 30"] 2209 lopen | only 2210 lfirst 2211 call assert_true(winnr('$') == 2) 2212 call assert_true(winnr() == 1) 2213 " Location list for the new window should be set 2214 call assert_true(getloclist(0)[2].text == 'Line 30') 2215 2216 " Open a scratch buffer 2217 " Open a new window and create a location list 2218 " Open the location list window and close the other window 2219 " Jump to an entry. 2220 " Should create a new window and jump to the entry. The scrtach buffer 2221 " should not be used. 2222 enew | only 2223 set buftype=nofile 2224 below new 2225 lgetexpr ["F1%10%Line 10", "F2%20%Line 20", "F3%30%Line 30"] 2226 lopen 2227 2wincmd c 2228 lnext 2229 call assert_true(winnr('$') == 3) 2230 call assert_true(winnr() == 2) 2231 2232 " Open two windows with two different location lists 2233 " Open the location list window and close the previous window 2234 " Jump to an entry in the location list window 2235 " Should open the file in the first window and not set the location list. 2236 enew | only 2237 lgetexpr ["F1%5%Line 5"] 2238 below new 2239 lgetexpr ["F1%10%Line 10", "F2%20%Line 20", "F3%30%Line 30"] 2240 lopen 2241 2wincmd c 2242 lnext 2243 call assert_true(winnr() == 1) 2244 call assert_true(getloclist(0)[0].text == 'Line 5') 2245 2246 enew | only 2247 cgetexpr ["F1%10%Line 10", "F2%20%Line 20", "F3%30%Line 30"] 2248 copen 2249 cnext 2250 call assert_true(winnr('$') == 2) 2251 call assert_true(winnr() == 1) 2252 2253 enew | only 2254 set efm&vim 2255endfunc 2256 2257func XvimgrepTests(cchar) 2258 call s:setup_commands(a:cchar) 2259 2260 call writefile(['Editor:VIM vim', 2261 \ 'Editor:Emacs EmAcS', 2262 \ 'Editor:Notepad NOTEPAD'], 'Xtestfile1') 2263 call writefile(['Linux', 'MacOS', 'MS-Windows'], 'Xtestfile2') 2264 2265 " Error cases 2266 call assert_fails('Xvimgrep /abc *', 'E682:') 2267 2268 let @/='' 2269 call assert_fails('Xvimgrep // *', 'E35:') 2270 2271 call assert_fails('Xvimgrep abc', 'E683:') 2272 call assert_fails('Xvimgrep a1b2c3 Xtestfile1', 'E480:') 2273 call assert_fails('Xvimgrep pat Xa1b2c3', 'E480:') 2274 2275 Xexpr "" 2276 Xvimgrepadd Notepad Xtestfile1 2277 Xvimgrepadd MacOS Xtestfile2 2278 let l = g:Xgetlist() 2279 call assert_equal(2, len(l)) 2280 call assert_equal('Editor:Notepad NOTEPAD', l[0].text) 2281 2282 Xvimgrep #\cvim#g Xtestfile? 2283 let l = g:Xgetlist() 2284 call assert_equal(2, len(l)) 2285 call assert_equal(8, l[0].col) 2286 call assert_equal(12, l[1].col) 2287 2288 1Xvimgrep ?Editor? Xtestfile* 2289 let l = g:Xgetlist() 2290 call assert_equal(1, len(l)) 2291 call assert_equal('Editor:VIM vim', l[0].text) 2292 2293 edit +3 Xtestfile2 2294 Xvimgrep +\cemacs+j Xtestfile1 2295 let l = g:Xgetlist() 2296 call assert_equal('Xtestfile2', bufname('')) 2297 call assert_equal('Editor:Emacs EmAcS', l[0].text) 2298 2299 call delete('Xtestfile1') 2300 call delete('Xtestfile2') 2301endfunc 2302 2303" Tests for the :vimgrep command 2304func Test_vimgrep() 2305 call XvimgrepTests('c') 2306 call XvimgrepTests('l') 2307endfunc 2308 2309func XfreeTests(cchar) 2310 call s:setup_commands(a:cchar) 2311 2312 enew | only 2313 2314 " Deleting the quickfix stack should work even When the current list is 2315 " somewhere in the middle of the stack 2316 Xexpr ['Xfile1:10:10:Line 10', 'Xfile1:15:15:Line 15'] 2317 Xexpr ['Xfile2:20:20:Line 20', 'Xfile2:25:25:Line 25'] 2318 Xexpr ['Xfile3:30:30:Line 30', 'Xfile3:35:35:Line 35'] 2319 Xolder 2320 call g:Xsetlist([], 'f') 2321 call assert_equal(0, len(g:Xgetlist())) 2322 2323 " After deleting the stack, adding a new list should create a stack with a 2324 " single list. 2325 Xexpr ['Xfile1:10:10:Line 10', 'Xfile1:15:15:Line 15'] 2326 call assert_equal(1, g:Xgetlist({'all':1}).nr) 2327 2328 " Deleting the stack from a quickfix window should update/clear the 2329 " quickfix/location list window. 2330 Xexpr ['Xfile1:10:10:Line 10', 'Xfile1:15:15:Line 15'] 2331 Xexpr ['Xfile2:20:20:Line 20', 'Xfile2:25:25:Line 25'] 2332 Xexpr ['Xfile3:30:30:Line 30', 'Xfile3:35:35:Line 35'] 2333 Xolder 2334 Xwindow 2335 call g:Xsetlist([], 'f') 2336 call assert_equal(2, winnr('$')) 2337 call assert_equal(1, line('$')) 2338 Xclose 2339 2340 " Deleting the stack from a non-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 wincmd p 2348 call g:Xsetlist([], 'f') 2349 call assert_equal(0, len(g:Xgetlist())) 2350 wincmd p 2351 call assert_equal(2, winnr('$')) 2352 call assert_equal(1, line('$')) 2353 2354 " After deleting the location list stack, if the location list window is 2355 " opened, then a new location list should be created. So opening the 2356 " location list window again should not create a new window. 2357 if a:cchar == 'l' 2358 lexpr ['Xfile1:10:10:Line 10', 'Xfile1:15:15:Line 15'] 2359 wincmd p 2360 lopen 2361 call assert_equal(2, winnr('$')) 2362 endif 2363 Xclose 2364endfunc 2365 2366" Tests for the quickfix free functionality 2367func Test_qf_free() 2368 call XfreeTests('c') 2369 call XfreeTests('l') 2370endfunc 2371 2372" Test for buffer overflow when parsing lines and adding new entries to 2373" the quickfix list. 2374func Test_bufoverflow() 2375 set efm=%f:%l:%m 2376 cgetexpr ['File1:100:' . repeat('x', 1025)] 2377 2378 set efm=%+GCompiler:\ %.%#,%f:%l:%m 2379 cgetexpr ['Compiler: ' . repeat('a', 1015), 'File1:10:Hello World'] 2380 2381 set efm=%DEntering\ directory\ %f,%f:%l:%m 2382 cgetexpr ['Entering directory ' . repeat('a', 1006), 2383 \ 'File1:10:Hello World'] 2384 set efm&vim 2385endfunc 2386 2387" Tests for getting the quickfix stack size 2388func XsizeTests(cchar) 2389 call s:setup_commands(a:cchar) 2390 2391 call g:Xsetlist([], 'f') 2392 call assert_equal(0, g:Xgetlist({'nr':'$'}).nr) 2393 call assert_equal('', g:Xgetlist({'nr':'$', 'all':1}).title) 2394 call assert_equal(0, g:Xgetlist({'nr':0}).nr) 2395 2396 Xexpr "File1:10:Line1" 2397 Xexpr "File2:20:Line2" 2398 Xexpr "File3:30:Line3" 2399 Xolder | Xolder 2400 call assert_equal(3, g:Xgetlist({'nr':'$'}).nr) 2401 call g:Xsetlist([], 'f') 2402 2403 Xexpr "File1:10:Line1" 2404 Xexpr "File2:20:Line2" 2405 Xexpr "File3:30:Line3" 2406 Xolder | Xolder 2407 call g:Xsetlist([], 'a', {'nr':'$', 'title':'Compiler'}) 2408 call assert_equal('Compiler', g:Xgetlist({'nr':3, 'all':1}).title) 2409endfunc 2410 2411func Test_Qf_Size() 2412 call XsizeTests('c') 2413 call XsizeTests('l') 2414endfunc 2415 2416func Test_cclose_from_copen() 2417 augroup QF_Test 2418 au! 2419 au FileType qf :call assert_fails(':cclose', 'E788') 2420 augroup END 2421 copen 2422 augroup QF_Test 2423 au! 2424 augroup END 2425 augroup! QF_Test 2426endfunc 2427 2428func Test_cclose_in_autocmd() 2429 " Problem is only triggered if "starting" is zero, so that the OptionsSet 2430 " event will be triggered. 2431 call test_override('starting', 1) 2432 augroup QF_Test 2433 au! 2434 au FileType qf :call assert_fails(':cclose', 'E788') 2435 augroup END 2436 copen 2437 augroup QF_Test 2438 au! 2439 augroup END 2440 augroup! QF_Test 2441 call test_override('starting', 0) 2442endfunc 2443 2444func Test_resize_from_copen() 2445 augroup QF_Test 2446 au! 2447 au FileType qf resize 5 2448 augroup END 2449 try 2450 " This should succeed without any exception. No other buffers are 2451 " involved in the autocmd. 2452 copen 2453 finally 2454 augroup QF_Test 2455 au! 2456 augroup END 2457 augroup! QF_Test 2458 endtry 2459endfunc 2460 2461" Tests for the quickfix buffer b:changedtick variable 2462func Xchangedtick_tests(cchar) 2463 call s:setup_commands(a:cchar) 2464 2465 new | only 2466 2467 Xexpr "" | Xexpr "" | Xexpr "" 2468 2469 Xopen 2470 Xolder 2471 Xolder 2472 Xaddexpr "F1:10:Line10" 2473 Xaddexpr "F2:20:Line20" 2474 call g:Xsetlist([{"filename":"F3", "lnum":30, "text":"Line30"}], 'a') 2475 call g:Xsetlist([], 'f') 2476 call assert_equal(8, getbufvar('%', 'changedtick')) 2477 Xclose 2478endfunc 2479 2480func Test_changedtick() 2481 call Xchangedtick_tests('c') 2482 call Xchangedtick_tests('l') 2483endfunc 2484 2485" Tests for parsing an expression using setqflist() 2486func Xsetexpr_tests(cchar) 2487 call s:setup_commands(a:cchar) 2488 2489 let t = ["File1:10:Line10", "File1:20:Line20"] 2490 call g:Xsetlist([], ' ', {'lines' : t}) 2491 call g:Xsetlist([], 'a', {'lines' : ["File1:30:Line30"]}) 2492 2493 let l = g:Xgetlist() 2494 call assert_equal(3, len(l)) 2495 call assert_equal(20, l[1].lnum) 2496 call assert_equal('Line30', l[2].text) 2497 call g:Xsetlist([], 'r', {'lines' : ["File2:5:Line5"]}) 2498 let l = g:Xgetlist() 2499 call assert_equal(1, len(l)) 2500 call assert_equal('Line5', l[0].text) 2501 call assert_equal(-1, g:Xsetlist([], 'a', {'lines' : 10})) 2502 call assert_equal(-1, g:Xsetlist([], 'a', {'lines' : "F1:10:L10"})) 2503 2504 call g:Xsetlist([], 'f') 2505 " Add entries to multiple lists 2506 call g:Xsetlist([], 'a', {'nr' : 1, 'lines' : ["File1:10:Line10"]}) 2507 call g:Xsetlist([], 'a', {'nr' : 2, 'lines' : ["File2:20:Line20"]}) 2508 call g:Xsetlist([], 'a', {'nr' : 1, 'lines' : ["File1:15:Line15"]}) 2509 call g:Xsetlist([], 'a', {'nr' : 2, 'lines' : ["File2:25:Line25"]}) 2510 call assert_equal('Line15', g:Xgetlist({'nr':1, 'items':1}).items[1].text) 2511 call assert_equal('Line25', g:Xgetlist({'nr':2, 'items':1}).items[1].text) 2512 2513 " Adding entries using a custom efm 2514 set efm& 2515 call g:Xsetlist([], ' ', {'efm' : '%f#%l#%m', 2516 \ 'lines' : ["F1#10#L10", "F2#20#L20"]}) 2517 call assert_equal(20, g:Xgetlist({'items':1}).items[1].lnum) 2518 call g:Xsetlist([], 'a', {'efm' : '%f#%l#%m', 'lines' : ["F3:30:L30"]}) 2519 call assert_equal('F3:30:L30', g:Xgetlist({'items':1}).items[2].text) 2520 call assert_equal(20, g:Xgetlist({'items':1}).items[1].lnum) 2521 call assert_equal(-1, g:Xsetlist([], 'a', {'efm' : [], 2522 \ 'lines' : ['F1:10:L10']})) 2523endfunc 2524 2525func Test_setexpr() 2526 call Xsetexpr_tests('c') 2527 call Xsetexpr_tests('l') 2528endfunc 2529 2530" Tests for per quickfix/location list directory stack 2531func Xmultidirstack_tests(cchar) 2532 call s:setup_commands(a:cchar) 2533 2534 call g:Xsetlist([], 'f') 2535 Xexpr "" | Xexpr "" 2536 2537 call g:Xsetlist([], 'a', {'nr' : 1, 'lines' : ["Entering dir 'Xone/a'"]}) 2538 call g:Xsetlist([], 'a', {'nr' : 2, 'lines' : ["Entering dir 'Xtwo/a'"]}) 2539 call g:Xsetlist([], 'a', {'nr' : 1, 'lines' : ["one.txt:3:one one one"]}) 2540 call g:Xsetlist([], 'a', {'nr' : 2, 'lines' : ["two.txt:5:two two two"]}) 2541 2542 let l1 = g:Xgetlist({'nr':1, 'items':1}) 2543 let l2 = g:Xgetlist({'nr':2, 'items':1}) 2544 call assert_equal('Xone/a/one.txt', bufname(l1.items[1].bufnr)) 2545 call assert_equal(3, l1.items[1].lnum) 2546 call assert_equal('Xtwo/a/two.txt', bufname(l2.items[1].bufnr)) 2547 call assert_equal(5, l2.items[1].lnum) 2548endfunc 2549 2550func Test_multidirstack() 2551 call mkdir('Xone/a', 'p') 2552 call mkdir('Xtwo/a', 'p') 2553 let lines = ['1', '2', 'one one one', '4', 'two two two', '6', '7'] 2554 call writefile(lines, 'Xone/a/one.txt') 2555 call writefile(lines, 'Xtwo/a/two.txt') 2556 let save_efm = &efm 2557 set efm=%DEntering\ dir\ '%f',%f:%l:%m,%XLeaving\ dir\ '%f' 2558 2559 call Xmultidirstack_tests('c') 2560 call Xmultidirstack_tests('l') 2561 2562 let &efm = save_efm 2563 call delete('Xone', 'rf') 2564 call delete('Xtwo', 'rf') 2565endfunc 2566 2567" Tests for per quickfix/location list file stack 2568func Xmultifilestack_tests(cchar) 2569 call s:setup_commands(a:cchar) 2570 2571 call g:Xsetlist([], 'f') 2572 Xexpr "" | Xexpr "" 2573 2574 call g:Xsetlist([], 'a', {'nr' : 1, 'lines' : ["[one.txt]"]}) 2575 call g:Xsetlist([], 'a', {'nr' : 2, 'lines' : ["[two.txt]"]}) 2576 call g:Xsetlist([], 'a', {'nr' : 1, 'lines' : ["(3,5) one one one"]}) 2577 call g:Xsetlist([], 'a', {'nr' : 2, 'lines' : ["(5,9) two two two"]}) 2578 2579 let l1 = g:Xgetlist({'nr':1, 'items':1}) 2580 let l2 = g:Xgetlist({'nr':2, 'items':1}) 2581 call assert_equal('one.txt', bufname(l1.items[1].bufnr)) 2582 call assert_equal(3, l1.items[1].lnum) 2583 call assert_equal('two.txt', bufname(l2.items[1].bufnr)) 2584 call assert_equal(5, l2.items[1].lnum) 2585endfunc 2586 2587func Test_multifilestack() 2588 let lines = ['1', '2', 'one one one', '4', 'two two two', '6', '7'] 2589 call writefile(lines, 'one.txt') 2590 call writefile(lines, 'two.txt') 2591 let save_efm = &efm 2592 set efm=%+P[%f],(%l\\,%c)\ %m,%-Q 2593 2594 call Xmultifilestack_tests('c') 2595 call Xmultifilestack_tests('l') 2596 2597 let &efm = save_efm 2598 call delete('one.txt') 2599 call delete('two.txt') 2600endfunc 2601 2602" Tests for per buffer 'efm' setting 2603func Test_perbuf_efm() 2604 call writefile(["File1-10-Line10"], 'one.txt') 2605 call writefile(["File2#20#Line20"], 'two.txt') 2606 set efm=%f#%l#%m 2607 new | only 2608 new 2609 setlocal efm=%f-%l-%m 2610 cfile one.txt 2611 wincmd w 2612 caddfile two.txt 2613 2614 let l = getqflist() 2615 call assert_equal(10, l[0].lnum) 2616 call assert_equal('Line20', l[1].text) 2617 2618 set efm& 2619 new | only 2620 call delete('one.txt') 2621 call delete('two.txt') 2622endfunc 2623 2624" Open multiple help windows using ":lhelpgrep 2625" This test used to crash Vim 2626func Test_Multi_LL_Help() 2627 new | only 2628 lhelpgrep window 2629 lopen 2630 e# 2631 lhelpgrep buffer 2632 call assert_equal(3, winnr('$')) 2633 call assert_true(len(getloclist(1)) != 0) 2634 call assert_true(len(getloclist(2)) != 0) 2635 new | only 2636endfunc 2637 2638" Tests for adding new quickfix lists using setqflist() 2639func XaddQf_tests(cchar) 2640 call s:setup_commands(a:cchar) 2641 2642 " Create a new list using ' ' for action 2643 call g:Xsetlist([], 'f') 2644 call g:Xsetlist([], ' ', {'title' : 'Test1'}) 2645 let l = g:Xgetlist({'nr' : '$', 'all' : 1}) 2646 call assert_equal(1, l.nr) 2647 call assert_equal('Test1', l.title) 2648 2649 " Create a new list using ' ' for action and '$' for 'nr' 2650 call g:Xsetlist([], 'f') 2651 call g:Xsetlist([], ' ', {'title' : 'Test2', 'nr' : '$'}) 2652 let l = g:Xgetlist({'nr' : '$', 'all' : 1}) 2653 call assert_equal(1, l.nr) 2654 call assert_equal('Test2', l.title) 2655 2656 " Create a new list using 'a' for action 2657 call g:Xsetlist([], 'f') 2658 call g:Xsetlist([], 'a', {'title' : 'Test3'}) 2659 let l = g:Xgetlist({'nr' : '$', 'all' : 1}) 2660 call assert_equal(1, l.nr) 2661 call assert_equal('Test3', l.title) 2662 2663 " Create a new list using 'a' for action and '$' for 'nr' 2664 call g:Xsetlist([], 'f') 2665 call g:Xsetlist([], 'a', {'title' : 'Test3', 'nr' : '$'}) 2666 call g:Xsetlist([], 'a', {'title' : 'Test4'}) 2667 let l = g:Xgetlist({'nr' : '$', 'all' : 1}) 2668 call assert_equal(1, l.nr) 2669 call assert_equal('Test4', l.title) 2670 2671 " Adding a quickfix list should remove all the lists following the current 2672 " list. 2673 Xexpr "" | Xexpr "" | Xexpr "" 2674 silent! 10Xolder 2675 call g:Xsetlist([], ' ', {'title' : 'Test5'}) 2676 let l = g:Xgetlist({'nr' : '$', 'all' : 1}) 2677 call assert_equal(2, l.nr) 2678 call assert_equal('Test5', l.title) 2679 2680 " Add a quickfix list using '$' as the list number. 2681 let lastqf = g:Xgetlist({'nr':'$'}).nr 2682 silent! 99Xolder 2683 call g:Xsetlist([], ' ', {'nr' : '$', 'title' : 'Test6'}) 2684 let l = g:Xgetlist({'nr' : '$', 'all' : 1}) 2685 call assert_equal(lastqf + 1, l.nr) 2686 call assert_equal('Test6', l.title) 2687 2688 " Add a quickfix list using 'nr' set to one more than the quickfix 2689 " list size. 2690 let lastqf = g:Xgetlist({'nr':'$'}).nr 2691 silent! 99Xolder 2692 call g:Xsetlist([], ' ', {'nr' : lastqf + 1, 'title' : 'Test7'}) 2693 let l = g:Xgetlist({'nr' : '$', 'all' : 1}) 2694 call assert_equal(lastqf + 1, l.nr) 2695 call assert_equal('Test7', l.title) 2696 2697 " Add a quickfix list to a stack with 10 lists using 'nr' set to '$' 2698 exe repeat('Xexpr "" |', 9) . 'Xexpr ""' 2699 silent! 99Xolder 2700 call g:Xsetlist([], ' ', {'nr' : '$', 'title' : 'Test8'}) 2701 let l = g:Xgetlist({'nr' : '$', 'all' : 1}) 2702 call assert_equal(10, l.nr) 2703 call assert_equal('Test8', l.title) 2704 2705 " Add a quickfix list using 'nr' set to a value greater than 10 2706 call assert_equal(-1, g:Xsetlist([], ' ', {'nr' : 12, 'title' : 'Test9'})) 2707 2708 " Try adding a quickfix list with 'nr' set to a value greater than the 2709 " quickfix list size but less than 10. 2710 call g:Xsetlist([], 'f') 2711 Xexpr "" | Xexpr "" | Xexpr "" 2712 silent! 99Xolder 2713 call assert_equal(-1, g:Xsetlist([], ' ', {'nr' : 8, 'title' : 'Test10'})) 2714 2715 " Add a quickfix list using 'nr' set to a some string or list 2716 call assert_equal(-1, g:Xsetlist([], ' ', {'nr' : [1,2], 'title' : 'Test11'})) 2717endfunc 2718 2719func Test_add_qf() 2720 call XaddQf_tests('c') 2721 call XaddQf_tests('l') 2722endfunc 2723 2724" Test for getting the quickfix list items from some text without modifying 2725" the quickfix stack 2726func XgetListFromLines(cchar) 2727 call s:setup_commands(a:cchar) 2728 call g:Xsetlist([], 'f') 2729 2730 let l = g:Xgetlist({'lines' : ["File2:20:Line20", "File2:30:Line30"]}).items 2731 call assert_equal(2, len(l)) 2732 call assert_equal(30, l[1].lnum) 2733 2734 call assert_equal({}, g:Xgetlist({'lines' : 10})) 2735 call assert_equal({}, g:Xgetlist({'lines' : 'File1:10:Line10'})) 2736 call assert_equal([], g:Xgetlist({'lines' : []}).items) 2737 call assert_equal([], g:Xgetlist({'lines' : [10, 20]}).items) 2738 2739 " Parse text using a custom efm 2740 set efm& 2741 let l = g:Xgetlist({'lines':['File3#30#Line30'], 'efm' : '%f#%l#%m'}).items 2742 call assert_equal('Line30', l[0].text) 2743 let l = g:Xgetlist({'lines':['File3:30:Line30'], 'efm' : '%f-%l-%m'}).items 2744 call assert_equal('File3:30:Line30', l[0].text) 2745 let l = g:Xgetlist({'lines':['File3:30:Line30'], 'efm' : [1,2]}) 2746 call assert_equal({}, l) 2747 call assert_fails("call g:Xgetlist({'lines':['abc'], 'efm':'%2'})", 'E376:') 2748 call assert_fails("call g:Xgetlist({'lines':['abc'], 'efm':''})", 'E378:') 2749 2750 " Make sure that the quickfix stack is not modified 2751 call assert_equal(0, g:Xgetlist({'nr' : '$'}).nr) 2752endfunc 2753 2754func Test_get_list_from_lines() 2755 call XgetListFromLines('c') 2756 call XgetListFromLines('l') 2757endfunc 2758 2759" Tests for the quickfix list id 2760func Xqfid_tests(cchar) 2761 call s:setup_commands(a:cchar) 2762 2763 call g:Xsetlist([], 'f') 2764 call assert_equal(0, g:Xgetlist({'id':0}).id) 2765 Xexpr '' 2766 let start_id = g:Xgetlist({'id' : 0}).id 2767 Xexpr '' | Xexpr '' 2768 Xolder 2769 call assert_equal(start_id, g:Xgetlist({'id':0, 'nr':1}).id) 2770 call assert_equal(start_id + 1, g:Xgetlist({'id':0, 'nr':0}).id) 2771 call assert_equal(start_id + 2, g:Xgetlist({'id':0, 'nr':'$'}).id) 2772 call assert_equal(0, g:Xgetlist({'id':0, 'nr':99}).id) 2773 call assert_equal(2, g:Xgetlist({'id':start_id + 1, 'nr':0}).nr) 2774 call assert_equal(0, g:Xgetlist({'id':99, 'nr':0}).id) 2775 call assert_equal(0, g:Xgetlist({'id':"abc", 'nr':0}).id) 2776 2777 call g:Xsetlist([], 'a', {'id':start_id, 'context':[1,2]}) 2778 call assert_equal([1,2], g:Xgetlist({'nr':1, 'context':1}).context) 2779 call g:Xsetlist([], 'a', {'id':start_id+1, 'lines':['F1:10:L10']}) 2780 call assert_equal('L10', g:Xgetlist({'nr':2, 'items':1}).items[0].text) 2781 call assert_equal(-1, g:Xsetlist([], 'a', {'id':999, 'title':'Vim'})) 2782 call assert_equal(-1, g:Xsetlist([], 'a', {'id':'abc', 'title':'Vim'})) 2783 2784 let qfid = g:Xgetlist({'id':0, 'nr':0}) 2785 call g:Xsetlist([], 'f') 2786 call assert_equal(0, g:Xgetlist({'id':qfid, 'nr':0}).id) 2787endfunc 2788 2789func Test_qf_id() 2790 call Xqfid_tests('c') 2791 call Xqfid_tests('l') 2792endfunc 2793 2794func Xqfjump_tests(cchar) 2795 call s:setup_commands(a:cchar) 2796 2797 call writefile(["Line1\tFoo", "Line2"], 'F1') 2798 call writefile(["Line1\tBar", "Line2"], 'F2') 2799 call writefile(["Line1\tBaz", "Line2"], 'F3') 2800 2801 call g:Xsetlist([], 'f') 2802 2803 " Tests for 2804 " Jumping to a line using a pattern 2805 " Jumping to a column greater than the last column in a line 2806 " Jumping to a line greater than the last line in the file 2807 let l = [] 2808 for i in range(1, 7) 2809 call add(l, {}) 2810 endfor 2811 let l[0].filename='F1' 2812 let l[0].pattern='Line1' 2813 let l[1].filename='F2' 2814 let l[1].pattern='Line1' 2815 let l[2].filename='F3' 2816 let l[2].pattern='Line1' 2817 let l[3].filename='F3' 2818 let l[3].lnum=1 2819 let l[3].col=9 2820 let l[3].vcol=1 2821 let l[4].filename='F3' 2822 let l[4].lnum=99 2823 let l[5].filename='F3' 2824 let l[5].lnum=1 2825 let l[5].col=99 2826 let l[5].vcol=1 2827 let l[6].filename='F3' 2828 let l[6].pattern='abcxyz' 2829 2830 call g:Xsetlist([], ' ', {'items' : l}) 2831 Xopen | only 2832 2Xnext 2833 call assert_equal(3, g:Xgetlist({'idx' : 0}).idx) 2834 call assert_equal('F3', bufname('%')) 2835 Xnext 2836 call assert_equal(7, col('.')) 2837 Xnext 2838 call assert_equal(2, line('.')) 2839 Xnext 2840 call assert_equal(9, col('.')) 2841 2 2842 Xnext 2843 call assert_equal(2, line('.')) 2844 2845 if a:cchar == 'l' 2846 " When jumping to a location list entry in the location list window and 2847 " no usable windows are available, then a new window should be opened. 2848 enew! | new | only 2849 call g:Xsetlist([], 'f') 2850 setlocal buftype=nofile 2851 new 2852 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']}) 2853 Xopen 2854 let winid = win_getid() 2855 wincmd p 2856 close 2857 call win_gotoid(winid) 2858 Xnext 2859 call assert_equal(3, winnr('$')) 2860 call assert_equal(1, winnr()) 2861 call assert_equal(2, line('.')) 2862 2863 " When jumping to an entry in the location list window and the window 2864 " associated with the location list is not present and a window containing 2865 " the file is already present, then that window should be used. 2866 close 2867 belowright new 2868 call g:Xsetlist([], 'f') 2869 edit F3 2870 call win_gotoid(winid) 2871 Xlast 2872 call assert_equal(3, winnr()) 2873 call assert_equal(6, g:Xgetlist({'size' : 1}).size) 2874 call assert_equal(winid, g:Xgetlist({'winid' : 1}).winid) 2875 endif 2876 2877 " Cleanup 2878 enew! 2879 new | only 2880 2881 call delete('F1') 2882 call delete('F2') 2883 call delete('F3') 2884endfunc 2885 2886func Test_qfjump() 2887 call Xqfjump_tests('c') 2888 call Xqfjump_tests('l') 2889endfunc 2890 2891" Tests for the getqflist() and getloclist() functions when the list is not 2892" present or is empty 2893func Xgetlist_empty_tests(cchar) 2894 call s:setup_commands(a:cchar) 2895 2896 " Empty quickfix stack 2897 call g:Xsetlist([], 'f') 2898 call assert_equal('', g:Xgetlist({'context' : 0}).context) 2899 call assert_equal(0, g:Xgetlist({'id' : 0}).id) 2900 call assert_equal(0, g:Xgetlist({'idx' : 0}).idx) 2901 call assert_equal([], g:Xgetlist({'items' : 0}).items) 2902 call assert_equal(0, g:Xgetlist({'nr' : 0}).nr) 2903 call assert_equal(0, g:Xgetlist({'size' : 0}).size) 2904 call assert_equal('', g:Xgetlist({'title' : 0}).title) 2905 call assert_equal(0, g:Xgetlist({'winid' : 0}).winid) 2906 call assert_equal(0, g:Xgetlist({'changedtick' : 0}).changedtick) 2907 call assert_equal({'context' : '', 'id' : 0, 'idx' : 0, 'items' : [], 'nr' : 0, 'size' : 0, 'title' : '', 'winid' : 0, 'changedtick': 0}, g:Xgetlist({'all' : 0})) 2908 2909 " Quickfix window with empty stack 2910 silent! Xopen 2911 let qfwinid = (a:cchar == 'c') ? win_getid() : 0 2912 call assert_equal(qfwinid, g:Xgetlist({'winid' : 0}).winid) 2913 Xclose 2914 2915 " Empty quickfix list 2916 Xexpr "" 2917 call assert_equal('', g:Xgetlist({'context' : 0}).context) 2918 call assert_notequal(0, g:Xgetlist({'id' : 0}).id) 2919 call assert_equal(0, g:Xgetlist({'idx' : 0}).idx) 2920 call assert_equal([], g:Xgetlist({'items' : 0}).items) 2921 call assert_notequal(0, g:Xgetlist({'nr' : 0}).nr) 2922 call assert_equal(0, g:Xgetlist({'size' : 0}).size) 2923 call assert_notequal('', g:Xgetlist({'title' : 0}).title) 2924 call assert_equal(0, g:Xgetlist({'winid' : 0}).winid) 2925 call assert_equal(1, g:Xgetlist({'changedtick' : 0}).changedtick) 2926 2927 let qfid = g:Xgetlist({'id' : 0}).id 2928 call g:Xsetlist([], 'f') 2929 2930 " Non-existing quickfix identifier 2931 call assert_equal('', g:Xgetlist({'id' : qfid, 'context' : 0}).context) 2932 call assert_equal(0, g:Xgetlist({'id' : qfid}).id) 2933 call assert_equal(0, g:Xgetlist({'id' : qfid, 'idx' : 0}).idx) 2934 call assert_equal([], g:Xgetlist({'id' : qfid, 'items' : 0}).items) 2935 call assert_equal(0, g:Xgetlist({'id' : qfid, 'nr' : 0}).nr) 2936 call assert_equal(0, g:Xgetlist({'id' : qfid, 'size' : 0}).size) 2937 call assert_equal('', g:Xgetlist({'id' : qfid, 'title' : 0}).title) 2938 call assert_equal(0, g:Xgetlist({'id' : qfid, 'winid' : 0}).winid) 2939 call assert_equal(0, g:Xgetlist({'id' : qfid, 'changedtick' : 0}).changedtick) 2940 call assert_equal({'context' : '', 'id' : 0, 'idx' : 0, 'items' : [], 'nr' : 0, 'size' : 0, 'title' : '', 'winid' : 0, 'changedtick' : 0}, g:Xgetlist({'id' : qfid, 'all' : 0})) 2941 2942 " Non-existing quickfix list number 2943 call assert_equal('', g:Xgetlist({'nr' : 5, 'context' : 0}).context) 2944 call assert_equal(0, g:Xgetlist({'nr' : 5}).nr) 2945 call assert_equal(0, g:Xgetlist({'nr' : 5, 'idx' : 0}).idx) 2946 call assert_equal([], g:Xgetlist({'nr' : 5, 'items' : 0}).items) 2947 call assert_equal(0, g:Xgetlist({'nr' : 5, 'id' : 0}).id) 2948 call assert_equal(0, g:Xgetlist({'nr' : 5, 'size' : 0}).size) 2949 call assert_equal('', g:Xgetlist({'nr' : 5, 'title' : 0}).title) 2950 call assert_equal(0, g:Xgetlist({'nr' : 5, 'winid' : 0}).winid) 2951 call assert_equal(0, g:Xgetlist({'nr' : 5, 'changedtick' : 0}).changedtick) 2952 call assert_equal({'context' : '', 'id' : 0, 'idx' : 0, 'items' : [], 'nr' : 0, 'size' : 0, 'title' : '', 'winid' : 0, 'changedtick' : 0}, g:Xgetlist({'nr' : 5, 'all' : 0})) 2953endfunc 2954 2955func Test_getqflist() 2956 call Xgetlist_empty_tests('c') 2957 call Xgetlist_empty_tests('l') 2958endfunc 2959 2960func Test_getqflist_invalid_nr() 2961 " The following commands used to crash Vim 2962 cexpr "" 2963 call getqflist({'nr' : $XXX_DOES_NOT_EXIST_XXX}) 2964 2965 " Cleanup 2966 call setqflist([], 'r') 2967endfunc 2968 2969" Tests for the quickfix/location list changedtick 2970func Xqftick_tests(cchar) 2971 call s:setup_commands(a:cchar) 2972 2973 call g:Xsetlist([], 'f') 2974 2975 Xexpr "F1:10:Line10" 2976 let qfid = g:Xgetlist({'id' : 0}).id 2977 call assert_equal(1, g:Xgetlist({'changedtick' : 0}).changedtick) 2978 Xaddexpr "F2:20:Line20\nF2:21:Line21" 2979 call assert_equal(2, g:Xgetlist({'changedtick' : 0}).changedtick) 2980 call g:Xsetlist([], 'a', {'lines' : ["F3:30:Line30", "F3:31:Line31"]}) 2981 call assert_equal(3, g:Xgetlist({'changedtick' : 0}).changedtick) 2982 call g:Xsetlist([], 'r', {'lines' : ["F4:40:Line40"]}) 2983 call assert_equal(4, g:Xgetlist({'changedtick' : 0}).changedtick) 2984 call g:Xsetlist([], 'a', {'title' : 'New Title'}) 2985 call assert_equal(5, g:Xgetlist({'changedtick' : 0}).changedtick) 2986 2987 enew! 2988 call append(0, ["F5:50:L50", "F6:60:L60"]) 2989 Xaddbuffer 2990 call assert_equal(6, g:Xgetlist({'changedtick' : 0}).changedtick) 2991 enew! 2992 2993 call g:Xsetlist([], 'a', {'context' : {'bus' : 'pci'}}) 2994 call assert_equal(7, g:Xgetlist({'changedtick' : 0}).changedtick) 2995 call g:Xsetlist([{'filename' : 'F7', 'lnum' : 10, 'text' : 'L7'}, 2996 \ {'filename' : 'F7', 'lnum' : 11, 'text' : 'L11'}], 'a') 2997 call assert_equal(8, g:Xgetlist({'changedtick' : 0}).changedtick) 2998 call g:Xsetlist([{'filename' : 'F7', 'lnum' : 10, 'text' : 'L7'}, 2999 \ {'filename' : 'F7', 'lnum' : 11, 'text' : 'L11'}], ' ') 3000 call assert_equal(1, g:Xgetlist({'changedtick' : 0}).changedtick) 3001 call g:Xsetlist([{'filename' : 'F7', 'lnum' : 10, 'text' : 'L7'}, 3002 \ {'filename' : 'F7', 'lnum' : 11, 'text' : 'L11'}], 'r') 3003 call assert_equal(2, g:Xgetlist({'changedtick' : 0}).changedtick) 3004 3005 call writefile(["F8:80:L80", "F8:81:L81"], "Xone") 3006 Xfile Xone 3007 call assert_equal(1, g:Xgetlist({'changedtick' : 0}).changedtick) 3008 Xaddfile Xone 3009 call assert_equal(2, g:Xgetlist({'changedtick' : 0}).changedtick) 3010 3011 " Test case for updating a non-current quickfix list 3012 call g:Xsetlist([], 'f') 3013 Xexpr "F1:1:L1" 3014 Xexpr "F2:2:L2" 3015 call g:Xsetlist([], 'a', {'nr' : 1, "lines" : ["F10:10:L10"]}) 3016 call assert_equal(1, g:Xgetlist({'changedtick' : 0}).changedtick) 3017 call assert_equal(2, g:Xgetlist({'nr' : 1, 'changedtick' : 0}).changedtick) 3018 3019 call delete("Xone") 3020endfunc 3021 3022func Test_qf_tick() 3023 call Xqftick_tests('c') 3024 call Xqftick_tests('l') 3025endfunc 3026 3027" The following test used to crash Vim. 3028" Open the location list window and close the regular window associated with 3029" the location list. When the garbage collection runs now, it incorrectly 3030" marks the location list context as not in use and frees the context. 3031func Test_ll_window_ctx() 3032 call setloclist(0, [], 'f') 3033 call setloclist(0, [], 'a', {'context' : []}) 3034 lopen | only 3035 call test_garbagecollect_now() 3036 echo getloclist(0, {'context' : 1}).context 3037 enew | only 3038endfunc 3039 3040" The following test used to crash vim 3041func Test_lfile_crash() 3042 sp Xtest 3043 au QuickFixCmdPre * bw 3044 call assert_fails('lfile', 'E40') 3045 au! QuickFixCmdPre 3046endfunc 3047 3048" The following test used to crash vim 3049func Test_lbuffer_crash() 3050 sv Xtest 3051 augroup QF_Test 3052 au! 3053 au * * bw 3054 augroup END 3055 lbuffer 3056 augroup QF_Test 3057 au! 3058 augroup END 3059endfunc 3060 3061" The following test used to crash vim 3062func Test_lexpr_crash() 3063 augroup QF_Test 3064 au! 3065 au * * call setloclist(0, [], 'f') 3066 augroup END 3067 lexpr "" 3068 augroup QF_Test 3069 au! 3070 augroup END 3071 enew | only 3072endfunc 3073 3074" The following test used to crash Vim 3075func Test_lvimgrep_crash() 3076 sv Xtest 3077 augroup QF_Test 3078 au! 3079 au * * call setloclist(0, [], 'f') 3080 augroup END 3081 lvimgrep quickfix test_quickfix.vim 3082 augroup QF_Test 3083 au! 3084 augroup END 3085 enew | only 3086endfunc 3087 3088" Test for the position of the quickfix and location list window 3089func Test_qfwin_pos() 3090 " Open two windows 3091 new | only 3092 new 3093 cexpr ['F1:10:L10'] 3094 copen 3095 " Quickfix window should be the bottom most window 3096 call assert_equal(3, winnr()) 3097 close 3098 " Open at the very top 3099 wincmd t 3100 topleft copen 3101 call assert_equal(1, winnr()) 3102 close 3103 " open left of the current window 3104 wincmd t 3105 below new 3106 leftabove copen 3107 call assert_equal(2, winnr()) 3108 close 3109 " open right of the current window 3110 rightbelow copen 3111 call assert_equal(3, winnr()) 3112 close 3113endfunc 3114