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_quickfix_set_list_with_act() 1432 call XquickfixSetListWithAct('c') 1433 call XquickfixSetListWithAct('l') 1434endfunc 1435 1436func XLongLinesTests(cchar) 1437 let l = g:Xgetlist() 1438 1439 call assert_equal(4, len(l)) 1440 call assert_equal(1, l[0].lnum) 1441 call assert_equal(1, l[0].col) 1442 call assert_equal(1975, len(l[0].text)) 1443 call assert_equal(2, l[1].lnum) 1444 call assert_equal(1, l[1].col) 1445 call assert_equal(4070, len(l[1].text)) 1446 call assert_equal(3, l[2].lnum) 1447 call assert_equal(1, l[2].col) 1448 call assert_equal(4070, len(l[2].text)) 1449 call assert_equal(4, l[3].lnum) 1450 call assert_equal(1, l[3].col) 1451 call assert_equal(10, len(l[3].text)) 1452 1453 call g:Xsetlist([], 'r') 1454endfunc 1455 1456func s:long_lines_tests(cchar) 1457 call s:setup_commands(a:cchar) 1458 1459 let testfile = 'samples/quickfix.txt' 1460 1461 " file 1462 exe 'Xgetfile' testfile 1463 call XLongLinesTests(a:cchar) 1464 1465 " list 1466 Xexpr readfile(testfile) 1467 call XLongLinesTests(a:cchar) 1468 1469 " string 1470 Xexpr join(readfile(testfile), "\n") 1471 call XLongLinesTests(a:cchar) 1472 1473 " buffer 1474 exe 'edit' testfile 1475 exe 'Xbuffer' bufnr('%') 1476 call XLongLinesTests(a:cchar) 1477endfunc 1478 1479func Test_long_lines() 1480 call s:long_lines_tests('c') 1481 call s:long_lines_tests('l') 1482endfunc 1483 1484func s:create_test_file(filename) 1485 let l = [] 1486 for i in range(1, 20) 1487 call add(l, 'Line' . i) 1488 endfor 1489 call writefile(l, a:filename) 1490endfunc 1491 1492func Test_switchbuf() 1493 call s:create_test_file('Xqftestfile1') 1494 call s:create_test_file('Xqftestfile2') 1495 call s:create_test_file('Xqftestfile3') 1496 1497 new | only 1498 edit Xqftestfile1 1499 let file1_winid = win_getid() 1500 new Xqftestfile2 1501 let file2_winid = win_getid() 1502 cgetexpr ['Xqftestfile1:5:Line5', 1503 \ 'Xqftestfile1:6:Line6', 1504 \ 'Xqftestfile2:10:Line10', 1505 \ 'Xqftestfile2:11:Line11', 1506 \ 'Xqftestfile3:15:Line15', 1507 \ 'Xqftestfile3:16:Line16'] 1508 1509 new 1510 let winid = win_getid() 1511 cfirst | cnext 1512 call assert_equal(winid, win_getid()) 1513 2cnext 1514 call assert_equal(winid, win_getid()) 1515 2cnext 1516 call assert_equal(winid, win_getid()) 1517 enew 1518 1519 set switchbuf=useopen 1520 cfirst | cnext 1521 call assert_equal(file1_winid, win_getid()) 1522 2cnext 1523 call assert_equal(file2_winid, win_getid()) 1524 2cnext 1525 call assert_equal(file2_winid, win_getid()) 1526 1527 enew | only 1528 set switchbuf=usetab 1529 tabedit Xqftestfile1 1530 tabedit Xqftestfile2 1531 tabedit Xqftestfile3 1532 tabfirst 1533 cfirst | cnext 1534 call assert_equal(2, tabpagenr()) 1535 2cnext 1536 call assert_equal(3, tabpagenr()) 1537 6cnext 1538 call assert_equal(4, tabpagenr()) 1539 2cpfile 1540 call assert_equal(2, tabpagenr()) 1541 2cnfile 1542 call assert_equal(4, tabpagenr()) 1543 tabfirst | tabonly | enew 1544 1545 set switchbuf=split 1546 cfirst | cnext 1547 call assert_equal(1, winnr('$')) 1548 cnext | cnext 1549 call assert_equal(2, winnr('$')) 1550 cnext | cnext 1551 call assert_equal(3, winnr('$')) 1552 enew | only 1553 1554 set switchbuf=newtab 1555 cfirst | cnext 1556 call assert_equal(1, tabpagenr('$')) 1557 cnext | cnext 1558 call assert_equal(2, tabpagenr('$')) 1559 cnext | cnext 1560 call assert_equal(3, tabpagenr('$')) 1561 tabfirst | enew | tabonly | only 1562 1563 set switchbuf= 1564 edit Xqftestfile1 1565 let file1_winid = win_getid() 1566 new Xqftestfile2 1567 let file2_winid = win_getid() 1568 copen 1569 exe "normal 1G\<CR>" 1570 call assert_equal(file1_winid, win_getid()) 1571 copen 1572 exe "normal 3G\<CR>" 1573 call assert_equal(file2_winid, win_getid()) 1574 copen | only 1575 exe "normal 5G\<CR>" 1576 call assert_equal(2, winnr('$')) 1577 call assert_equal(1, bufwinnr('Xqftestfile3')) 1578 1579 " If only quickfix window is open in the current tabpage, jumping to an 1580 " entry with 'switchubf' set to 'usetab' should search in other tabpages. 1581 enew | only 1582 set switchbuf=usetab 1583 tabedit Xqftestfile1 1584 tabedit Xqftestfile2 1585 tabedit Xqftestfile3 1586 tabfirst 1587 copen | only 1588 clast 1589 call assert_equal(4, tabpagenr()) 1590 tabfirst | tabonly | enew | only 1591 1592 call delete('Xqftestfile1') 1593 call delete('Xqftestfile2') 1594 call delete('Xqftestfile3') 1595 set switchbuf&vim 1596 1597 enew | only 1598endfunc 1599 1600func Xadjust_qflnum(cchar) 1601 call s:setup_commands(a:cchar) 1602 1603 enew | only 1604 1605 let fname = 'Xqftestfile' . a:cchar 1606 call s:create_test_file(fname) 1607 exe 'edit ' . fname 1608 1609 Xgetexpr [fname . ':5:Line5', 1610 \ fname . ':10:Line10', 1611 \ fname . ':15:Line15', 1612 \ fname . ':20:Line20'] 1613 1614 6,14delete 1615 call append(6, ['Buffer', 'Window']) 1616 1617 let l = g:Xgetlist() 1618 1619 call assert_equal(5, l[0].lnum) 1620 call assert_equal(6, l[2].lnum) 1621 call assert_equal(13, l[3].lnum) 1622 1623 enew! 1624 call delete(fname) 1625endfunc 1626 1627func Test_adjust_lnum() 1628 call setloclist(0, []) 1629 call Xadjust_qflnum('c') 1630 call setqflist([]) 1631 call Xadjust_qflnum('l') 1632endfunc 1633 1634" Tests for the :grep/:lgrep and :grepadd/:lgrepadd commands 1635func s:test_xgrep(cchar) 1636 call s:setup_commands(a:cchar) 1637 1638 " The following lines are used for the grep test. Don't remove. 1639 " Grep_Test_Text: Match 1 1640 " Grep_Test_Text: Match 2 1641 " GrepAdd_Test_Text: Match 1 1642 " GrepAdd_Test_Text: Match 2 1643 enew! | only 1644 set makeef&vim 1645 silent Xgrep Grep_Test_Text: test_quickfix.vim 1646 call assert_true(len(g:Xgetlist()) == 3) 1647 Xopen 1648 call assert_true(w:quickfix_title =~ '^:grep') 1649 Xclose 1650 enew 1651 set makeef=Temp_File_## 1652 silent Xgrepadd GrepAdd_Test_Text: test_quickfix.vim 1653 call assert_true(len(g:Xgetlist()) == 6) 1654endfunc 1655 1656func Test_grep() 1657 if !has('unix') 1658 " The grepprg may not be set on non-Unix systems 1659 return 1660 endif 1661 1662 call s:test_xgrep('c') 1663 call s:test_xgrep('l') 1664endfunc 1665 1666func Test_two_windows() 1667 " Use one 'errorformat' for two windows. Add an expression to each of them, 1668 " make sure they each keep their own state. 1669 set efm=%DEntering\ dir\ '%f',%f:%l:%m,%XLeaving\ dir\ '%f' 1670 call mkdir('Xone/a', 'p') 1671 call mkdir('Xtwo/a', 'p') 1672 let lines = ['1', '2', 'one one one', '4', 'two two two', '6', '7'] 1673 call writefile(lines, 'Xone/a/one.txt') 1674 call writefile(lines, 'Xtwo/a/two.txt') 1675 1676 new one 1677 let one_id = win_getid() 1678 lexpr "" 1679 new two 1680 let two_id = win_getid() 1681 lexpr "" 1682 1683 laddexpr "Entering dir 'Xtwo/a'" 1684 call win_gotoid(one_id) 1685 laddexpr "Entering dir 'Xone/a'" 1686 call win_gotoid(two_id) 1687 laddexpr 'two.txt:5:two two two' 1688 call win_gotoid(one_id) 1689 laddexpr 'one.txt:3:one one one' 1690 1691 let loc_one = getloclist(one_id) 1692 call assert_equal('Xone/a/one.txt', bufname(loc_one[1].bufnr)) 1693 call assert_equal(3, loc_one[1].lnum) 1694 1695 let loc_two = getloclist(two_id) 1696 call assert_equal('Xtwo/a/two.txt', bufname(loc_two[1].bufnr)) 1697 call assert_equal(5, loc_two[1].lnum) 1698 1699 call win_gotoid(one_id) 1700 bwipe! 1701 call win_gotoid(two_id) 1702 bwipe! 1703 call delete('Xone', 'rf') 1704 call delete('Xtwo', 'rf') 1705endfunc 1706 1707func XbottomTests(cchar) 1708 call s:setup_commands(a:cchar) 1709 1710 " Calling lbottom without any errors should fail 1711 if a:cchar == 'l' 1712 call assert_fails('lbottom', 'E776:') 1713 endif 1714 1715 call g:Xsetlist([{'filename': 'foo', 'lnum': 42}]) 1716 Xopen 1717 let wid = win_getid() 1718 call assert_equal(1, line('.')) 1719 wincmd w 1720 call g:Xsetlist([{'filename': 'var', 'lnum': 24}], 'a') 1721 Xbottom 1722 call win_gotoid(wid) 1723 call assert_equal(2, line('.')) 1724 Xclose 1725endfunc 1726 1727" Tests for the :cbottom and :lbottom commands 1728func Test_cbottom() 1729 call XbottomTests('c') 1730 call XbottomTests('l') 1731endfunc 1732 1733func HistoryTest(cchar) 1734 call s:setup_commands(a:cchar) 1735 1736 " clear all lists after the first one, then replace the first one. 1737 call g:Xsetlist([]) 1738 call assert_fails('Xolder 99', 'E380:') 1739 let entry = {'filename': 'foo', 'lnum': 42} 1740 call g:Xsetlist([entry], 'r') 1741 call g:Xsetlist([entry, entry]) 1742 call g:Xsetlist([entry, entry, entry]) 1743 let res = split(execute(a:cchar . 'hist'), "\n") 1744 call assert_equal(3, len(res)) 1745 let common = 'errors :set' . (a:cchar == 'c' ? 'qf' : 'loc') . 'list()' 1746 call assert_equal(' error list 1 of 3; 1 ' . common, res[0]) 1747 call assert_equal(' error list 2 of 3; 2 ' . common, res[1]) 1748 call assert_equal('> error list 3 of 3; 3 ' . common, res[2]) 1749 1750 call g:Xsetlist([], 'f') 1751 let l = split(execute(a:cchar . 'hist'), "\n") 1752 call assert_equal('No entries', l[0]) 1753endfunc 1754 1755func Test_history() 1756 call HistoryTest('c') 1757 call HistoryTest('l') 1758endfunc 1759 1760func Test_duplicate_buf() 1761 " make sure we can get the highest buffer number 1762 edit DoesNotExist 1763 edit DoesNotExist2 1764 let last_buffer = bufnr("$") 1765 1766 " make sure only one buffer is created 1767 call writefile(['this one', 'that one'], 'Xgrepthis') 1768 vimgrep one Xgrepthis 1769 vimgrep one Xgrepthis 1770 call assert_equal(last_buffer + 1, bufnr("$")) 1771 1772 call delete('Xgrepthis') 1773endfunc 1774 1775" Quickfix/Location list set/get properties tests 1776func Xproperty_tests(cchar) 1777 call s:setup_commands(a:cchar) 1778 1779 " Error cases 1780 call assert_fails('call g:Xgetlist(99)', 'E715:') 1781 call assert_fails('call g:Xsetlist(99)', 'E714:') 1782 call assert_fails('call g:Xsetlist([], "a", [])', 'E715:') 1783 1784 " Set and get the title 1785 call g:Xsetlist([]) 1786 Xopen 1787 wincmd p 1788 call g:Xsetlist([{'filename':'foo', 'lnum':27}]) 1789 let s = g:Xsetlist([], 'a', {'title' : 'Sample'}) 1790 call assert_equal(0, s) 1791 let d = g:Xgetlist({"title":1}) 1792 call assert_equal('Sample', d.title) 1793 1794 Xopen 1795 call assert_equal('Sample', w:quickfix_title) 1796 Xclose 1797 1798 " Tests for action argument 1799 silent! Xolder 999 1800 let qfnr = g:Xgetlist({'all':1}).nr 1801 call g:Xsetlist([], 'r', {'title' : 'N1'}) 1802 call assert_equal('N1', g:Xgetlist({'all':1}).title) 1803 call g:Xsetlist([], ' ', {'title' : 'N2'}) 1804 call assert_equal(qfnr + 1, g:Xgetlist({'all':1}).nr) 1805 1806 let res = g:Xgetlist({'nr': 0}) 1807 call assert_equal(qfnr + 1, res.nr) 1808 call assert_equal(['nr'], keys(res)) 1809 1810 call g:Xsetlist([], ' ', {'title' : 'N3'}) 1811 call assert_equal('N2', g:Xgetlist({'nr':2, 'title':1}).title) 1812 1813 " Changing the title of an earlier quickfix list 1814 call g:Xsetlist([], 'r', {'title' : 'NewTitle', 'nr' : 2}) 1815 call assert_equal('NewTitle', g:Xgetlist({'nr':2, 'title':1}).title) 1816 1817 " Changing the title of an invalid quickfix list 1818 call assert_equal(-1, g:Xsetlist([], ' ', 1819 \ {'title' : 'SomeTitle', 'nr' : 99})) 1820 call assert_equal(-1, g:Xsetlist([], ' ', 1821 \ {'title' : 'SomeTitle', 'nr' : 'abc'})) 1822 1823 if a:cchar == 'c' 1824 copen 1825 call assert_equal({'winid':win_getid()}, getqflist({'winid':1})) 1826 cclose 1827 endif 1828 1829 " Invalid arguments 1830 call assert_fails('call g:Xgetlist([])', 'E715') 1831 call assert_fails('call g:Xsetlist([], "a", [])', 'E715') 1832 let s = g:Xsetlist([], 'a', {'abc':1}) 1833 call assert_equal(-1, s) 1834 1835 call assert_equal({}, g:Xgetlist({'abc':1})) 1836 call assert_equal('', g:Xgetlist({'nr':99, 'title':1}).title) 1837 call assert_equal('', g:Xgetlist({'nr':[], 'title':1}).title) 1838 1839 if a:cchar == 'l' 1840 call assert_equal({}, getloclist(99, {'title': 1})) 1841 endif 1842 1843 " Context related tests 1844 let s = g:Xsetlist([], 'a', {'context':[1,2,3]}) 1845 call assert_equal(0, s) 1846 call test_garbagecollect_now() 1847 let d = g:Xgetlist({'context':1}) 1848 call assert_equal([1,2,3], d.context) 1849 call g:Xsetlist([], 'a', {'context':{'color':'green'}}) 1850 let d = g:Xgetlist({'context':1}) 1851 call assert_equal({'color':'green'}, d.context) 1852 call g:Xsetlist([], 'a', {'context':"Context info"}) 1853 let d = g:Xgetlist({'context':1}) 1854 call assert_equal("Context info", d.context) 1855 call g:Xsetlist([], 'a', {'context':246}) 1856 let d = g:Xgetlist({'context':1}) 1857 call assert_equal(246, d.context) 1858 if a:cchar == 'l' 1859 " Test for copying context across two different location lists 1860 new | only 1861 let w1_id = win_getid() 1862 let l = [1] 1863 call setloclist(0, [], 'a', {'context':l}) 1864 new 1865 let w2_id = win_getid() 1866 call add(l, 2) 1867 call assert_equal([1, 2], getloclist(w1_id, {'context':1}).context) 1868 call assert_equal([1, 2], getloclist(w2_id, {'context':1}).context) 1869 unlet! l 1870 call assert_equal([1, 2], getloclist(w2_id, {'context':1}).context) 1871 only 1872 call setloclist(0, [], 'f') 1873 call assert_equal('', getloclist(0, {'context':1}).context) 1874 endif 1875 1876 " Test for changing the context of previous quickfix lists 1877 call g:Xsetlist([], 'f') 1878 Xexpr "One" 1879 Xexpr "Two" 1880 Xexpr "Three" 1881 call g:Xsetlist([], 'r', {'context' : [1], 'nr' : 1}) 1882 call g:Xsetlist([], 'a', {'context' : [2], 'nr' : 2}) 1883 " Also, check for setting the context using quickfix list number zero. 1884 call g:Xsetlist([], 'r', {'context' : [3], 'nr' : 0}) 1885 call test_garbagecollect_now() 1886 let l = g:Xgetlist({'nr' : 1, 'context' : 1}) 1887 call assert_equal([1], l.context) 1888 let l = g:Xgetlist({'nr' : 2, 'context' : 1}) 1889 call assert_equal([2], l.context) 1890 let l = g:Xgetlist({'nr' : 3, 'context' : 1}) 1891 call assert_equal([3], l.context) 1892 1893 " Test for changing the context through reference and for garbage 1894 " collection of quickfix context 1895 let l = ["red"] 1896 call g:Xsetlist([], ' ', {'context' : l}) 1897 call add(l, "blue") 1898 let x = g:Xgetlist({'context' : 1}) 1899 call add(x.context, "green") 1900 call assert_equal(["red", "blue", "green"], l) 1901 call assert_equal(["red", "blue", "green"], x.context) 1902 unlet l 1903 call test_garbagecollect_now() 1904 let m = g:Xgetlist({'context' : 1}) 1905 call assert_equal(["red", "blue", "green"], m.context) 1906 1907 " Test for setting/getting items 1908 Xexpr "" 1909 let qfprev = g:Xgetlist({'nr':0}) 1910 let s = g:Xsetlist([], ' ', {'title':'Green', 1911 \ 'items' : [{'filename':'F1', 'lnum':10}]}) 1912 call assert_equal(0, s) 1913 let qfcur = g:Xgetlist({'nr':0}) 1914 call assert_true(qfcur.nr == qfprev.nr + 1) 1915 let l = g:Xgetlist({'items':1}) 1916 call assert_equal('F1', bufname(l.items[0].bufnr)) 1917 call assert_equal(10, l.items[0].lnum) 1918 call g:Xsetlist([], 'a', {'items' : [{'filename':'F2', 'lnum':20}, 1919 \ {'filename':'F2', 'lnum':30}]}) 1920 let l = g:Xgetlist({'items':1}) 1921 call assert_equal('F2', bufname(l.items[2].bufnr)) 1922 call assert_equal(30, l.items[2].lnum) 1923 call g:Xsetlist([], 'r', {'items' : [{'filename':'F3', 'lnum':40}]}) 1924 let l = g:Xgetlist({'items':1}) 1925 call assert_equal('F3', bufname(l.items[0].bufnr)) 1926 call assert_equal(40, l.items[0].lnum) 1927 call g:Xsetlist([], 'r', {'items' : []}) 1928 let l = g:Xgetlist({'items':1}) 1929 call assert_equal(0, len(l.items)) 1930 1931 call g:Xsetlist([], 'r', {'title' : 'TestTitle'}) 1932 call g:Xsetlist([], 'r', {'items' : [{'filename' : 'F1', 'lnum' : 10, 'text' : 'L10'}]}) 1933 call g:Xsetlist([], 'r', {'items' : [{'filename' : 'F1', 'lnum' : 10, 'text' : 'L10'}]}) 1934 call assert_equal('TestTitle', g:Xgetlist({'title' : 1}).title) 1935 1936 " The following used to crash Vim with address sanitizer 1937 call g:Xsetlist([], 'f') 1938 call g:Xsetlist([], 'a', {'items' : [{'filename':'F1', 'lnum':10}]}) 1939 call assert_equal(10, g:Xgetlist({'items':1}).items[0].lnum) 1940 1941 " Save and restore the quickfix stack 1942 call g:Xsetlist([], 'f') 1943 call assert_equal(0, g:Xgetlist({'nr':'$'}).nr) 1944 Xexpr "File1:10:Line1" 1945 Xexpr "File2:20:Line2" 1946 Xexpr "File3:30:Line3" 1947 let last_qf = g:Xgetlist({'nr':'$'}).nr 1948 call assert_equal(3, last_qf) 1949 let qstack = [] 1950 for i in range(1, last_qf) 1951 let qstack = add(qstack, g:Xgetlist({'nr':i, 'all':1})) 1952 endfor 1953 call g:Xsetlist([], 'f') 1954 for i in range(len(qstack)) 1955 call g:Xsetlist([], ' ', qstack[i]) 1956 endfor 1957 call assert_equal(3, g:Xgetlist({'nr':'$'}).nr) 1958 call assert_equal(10, g:Xgetlist({'nr':1, 'items':1}).items[0].lnum) 1959 call assert_equal(20, g:Xgetlist({'nr':2, 'items':1}).items[0].lnum) 1960 call assert_equal(30, g:Xgetlist({'nr':3, 'items':1}).items[0].lnum) 1961 call g:Xsetlist([], 'f') 1962 1963 " Swap two quickfix lists 1964 Xexpr "File1:10:Line10" 1965 Xexpr "File2:20:Line20" 1966 Xexpr "File3:30:Line30" 1967 call g:Xsetlist([], 'r', {'nr':1,'title':'Colors','context':['Colors']}) 1968 call g:Xsetlist([], 'r', {'nr':2,'title':'Fruits','context':['Fruits']}) 1969 let l1=g:Xgetlist({'nr':1,'all':1}) 1970 let l2=g:Xgetlist({'nr':2,'all':1}) 1971 let save_id = l1.id 1972 let l1.id=l2.id 1973 let l2.id=save_id 1974 call g:Xsetlist([], 'r', l1) 1975 call g:Xsetlist([], 'r', l2) 1976 let newl1=g:Xgetlist({'nr':1,'all':1}) 1977 let newl2=g:Xgetlist({'nr':2,'all':1}) 1978 call assert_equal('Fruits', newl1.title) 1979 call assert_equal(['Fruits'], newl1.context) 1980 call assert_equal('Line20', newl1.items[0].text) 1981 call assert_equal('Colors', newl2.title) 1982 call assert_equal(['Colors'], newl2.context) 1983 call assert_equal('Line10', newl2.items[0].text) 1984 call g:Xsetlist([], 'f') 1985endfunc 1986 1987func Test_qf_property() 1988 call Xproperty_tests('c') 1989 call Xproperty_tests('l') 1990endfunc 1991 1992" Tests for the QuickFixCmdPre/QuickFixCmdPost autocommands 1993func QfAutoCmdHandler(loc, cmd) 1994 call add(g:acmds, a:loc . a:cmd) 1995endfunc 1996 1997func Test_Autocmd() 1998 autocmd QuickFixCmdPre * call QfAutoCmdHandler('pre', expand('<amatch>')) 1999 autocmd QuickFixCmdPost * call QfAutoCmdHandler('post', expand('<amatch>')) 2000 2001 let g:acmds = [] 2002 cexpr "F1:10:Line 10" 2003 caddexpr "F1:20:Line 20" 2004 cgetexpr "F1:30:Line 30" 2005 cexpr "" 2006 caddexpr "" 2007 cgetexpr "" 2008 silent! cexpr non_existing_func() 2009 silent! caddexpr non_existing_func() 2010 silent! cgetexpr non_existing_func() 2011 let l = ['precexpr', 2012 \ 'postcexpr', 2013 \ 'precaddexpr', 2014 \ 'postcaddexpr', 2015 \ 'precgetexpr', 2016 \ 'postcgetexpr', 2017 \ 'precexpr', 2018 \ 'postcexpr', 2019 \ 'precaddexpr', 2020 \ 'postcaddexpr', 2021 \ 'precgetexpr', 2022 \ 'postcgetexpr', 2023 \ 'precexpr', 2024 \ 'precaddexpr', 2025 \ 'precgetexpr'] 2026 call assert_equal(l, g:acmds) 2027 2028 let g:acmds = [] 2029 enew! | call append(0, "F2:10:Line 10") 2030 cbuffer! 2031 enew! | call append(0, "F2:20:Line 20") 2032 cgetbuffer 2033 enew! | call append(0, "F2:30:Line 30") 2034 caddbuffer 2035 new 2036 let bnum = bufnr('%') 2037 bunload 2038 exe 'silent! cbuffer! ' . bnum 2039 exe 'silent! cgetbuffer ' . bnum 2040 exe 'silent! caddbuffer ' . bnum 2041 enew! 2042 let l = ['precbuffer', 2043 \ 'postcbuffer', 2044 \ 'precgetbuffer', 2045 \ 'postcgetbuffer', 2046 \ 'precaddbuffer', 2047 \ 'postcaddbuffer', 2048 \ 'precbuffer', 2049 \ 'precgetbuffer', 2050 \ 'precaddbuffer'] 2051 call assert_equal(l, g:acmds) 2052 2053 call writefile(['Xtest:1:Line1'], 'Xtest') 2054 call writefile([], 'Xempty') 2055 let g:acmds = [] 2056 cfile Xtest 2057 caddfile Xtest 2058 cgetfile Xtest 2059 cfile Xempty 2060 caddfile Xempty 2061 cgetfile Xempty 2062 silent! cfile do_not_exist 2063 silent! caddfile do_not_exist 2064 silent! cgetfile do_not_exist 2065 let l = ['precfile', 2066 \ 'postcfile', 2067 \ 'precaddfile', 2068 \ 'postcaddfile', 2069 \ 'precgetfile', 2070 \ 'postcgetfile', 2071 \ 'precfile', 2072 \ 'postcfile', 2073 \ 'precaddfile', 2074 \ 'postcaddfile', 2075 \ 'precgetfile', 2076 \ 'postcgetfile', 2077 \ 'precfile', 2078 \ 'postcfile', 2079 \ 'precaddfile', 2080 \ 'postcaddfile', 2081 \ 'precgetfile', 2082 \ 'postcgetfile'] 2083 call assert_equal(l, g:acmds) 2084 2085 let g:acmds = [] 2086 helpgrep quickfix 2087 silent! helpgrep non_existing_help_topic 2088 vimgrep test Xtest 2089 vimgrepadd test Xtest 2090 silent! vimgrep non_existing_test Xtest 2091 silent! vimgrepadd non_existing_test Xtest 2092 set makeprg= 2093 silent! make 2094 set makeprg& 2095 let l = ['prehelpgrep', 2096 \ 'posthelpgrep', 2097 \ 'prehelpgrep', 2098 \ 'posthelpgrep', 2099 \ 'previmgrep', 2100 \ 'postvimgrep', 2101 \ 'previmgrepadd', 2102 \ 'postvimgrepadd', 2103 \ 'previmgrep', 2104 \ 'postvimgrep', 2105 \ 'previmgrepadd', 2106 \ 'postvimgrepadd', 2107 \ 'premake', 2108 \ 'postmake'] 2109 call assert_equal(l, g:acmds) 2110 2111 if has('unix') 2112 " Run this test only on Unix-like systems. The grepprg may not be set on 2113 " non-Unix systems. 2114 " The following lines are used for the grep test. Don't remove. 2115 " Grep_Autocmd_Text: Match 1 2116 " GrepAdd_Autocmd_Text: Match 2 2117 let g:acmds = [] 2118 silent grep Grep_Autocmd_Text test_quickfix.vim 2119 silent grepadd GrepAdd_Autocmd_Text test_quickfix.vim 2120 silent grep abc123def Xtest 2121 silent grepadd abc123def Xtest 2122 let l = ['pregrep', 2123 \ 'postgrep', 2124 \ 'pregrepadd', 2125 \ 'postgrepadd', 2126 \ 'pregrep', 2127 \ 'postgrep', 2128 \ 'pregrepadd', 2129 \ 'postgrepadd'] 2130 call assert_equal(l, g:acmds) 2131 endif 2132 2133 call delete('Xtest') 2134 call delete('Xempty') 2135endfunc 2136 2137func Test_Autocmd_Exception() 2138 set efm=%m 2139 lgetexpr '?' 2140 2141 try 2142 call DoesNotExit() 2143 catch 2144 lgetexpr '1' 2145 finally 2146 lgetexpr '1' 2147 endtry 2148 2149 call assert_equal('1', getloclist(0)[0].text) 2150 2151 set efm&vim 2152endfunc 2153 2154func Test_caddbuffer_wrong() 2155 " This used to cause a memory access in freed memory. 2156 let save_efm = &efm 2157 set efm=%EEEE%m,%WWWW,%+CCCC%>%#,%GGGG%.# 2158 cgetexpr ['WWWW', 'EEEE', 'CCCC'] 2159 let &efm = save_efm 2160 caddbuffer 2161 bwipe! 2162endfunc 2163 2164func Test_caddexpr_wrong() 2165 " This used to cause a memory access in freed memory. 2166 cbuffer 2167 cbuffer 2168 copen 2169 let save_efm = &efm 2170 set efm=% 2171 call assert_fails('caddexpr ""', 'E376:') 2172 let &efm = save_efm 2173endfunc 2174 2175func Test_dirstack_cleanup() 2176 " This used to cause a memory access in freed memory. 2177 let save_efm = &efm 2178 lexpr '0' 2179 lopen 2180 fun X(c) 2181 let save_efm=&efm 2182 set efm=%D%f 2183 if a:c == 'c' 2184 caddexpr '::' 2185 else 2186 laddexpr ':0:0' 2187 endif 2188 let &efm=save_efm 2189 endfun 2190 call X('c') 2191 call X('l') 2192 call setqflist([], 'r') 2193 caddbuffer 2194 let &efm = save_efm 2195endfunc 2196 2197" Tests for jumping to entries from the location list window and quickfix 2198" window 2199func Test_cwindow_jump() 2200 set efm=%f%%%l%%%m 2201 lgetexpr ["F1%10%Line 10", "F2%20%Line 20", "F3%30%Line 30"] 2202 lopen | only 2203 lfirst 2204 call assert_true(winnr('$') == 2) 2205 call assert_true(winnr() == 1) 2206 " Location list for the new window should be set 2207 call assert_true(getloclist(0)[2].text == 'Line 30') 2208 2209 " Open a scratch buffer 2210 " Open a new window and create a location list 2211 " Open the location list window and close the other window 2212 " Jump to an entry. 2213 " Should create a new window and jump to the entry. The scrtach buffer 2214 " should not be used. 2215 enew | only 2216 set buftype=nofile 2217 below new 2218 lgetexpr ["F1%10%Line 10", "F2%20%Line 20", "F3%30%Line 30"] 2219 lopen 2220 2wincmd c 2221 lnext 2222 call assert_true(winnr('$') == 3) 2223 call assert_true(winnr() == 2) 2224 2225 " Open two windows with two different location lists 2226 " Open the location list window and close the previous window 2227 " Jump to an entry in the location list window 2228 " Should open the file in the first window and not set the location list. 2229 enew | only 2230 lgetexpr ["F1%5%Line 5"] 2231 below new 2232 lgetexpr ["F1%10%Line 10", "F2%20%Line 20", "F3%30%Line 30"] 2233 lopen 2234 2wincmd c 2235 lnext 2236 call assert_true(winnr() == 1) 2237 call assert_true(getloclist(0)[0].text == 'Line 5') 2238 2239 enew | only 2240 cgetexpr ["F1%10%Line 10", "F2%20%Line 20", "F3%30%Line 30"] 2241 copen 2242 cnext 2243 call assert_true(winnr('$') == 2) 2244 call assert_true(winnr() == 1) 2245 2246 enew | only 2247 set efm&vim 2248endfunc 2249 2250func XvimgrepTests(cchar) 2251 call s:setup_commands(a:cchar) 2252 2253 call writefile(['Editor:VIM vim', 2254 \ 'Editor:Emacs EmAcS', 2255 \ 'Editor:Notepad NOTEPAD'], 'Xtestfile1') 2256 call writefile(['Linux', 'MacOS', 'MS-Windows'], 'Xtestfile2') 2257 2258 " Error cases 2259 call assert_fails('Xvimgrep /abc *', 'E682:') 2260 2261 let @/='' 2262 call assert_fails('Xvimgrep // *', 'E35:') 2263 2264 call assert_fails('Xvimgrep abc', 'E683:') 2265 call assert_fails('Xvimgrep a1b2c3 Xtestfile1', 'E480:') 2266 call assert_fails('Xvimgrep pat Xa1b2c3', 'E480:') 2267 2268 Xexpr "" 2269 Xvimgrepadd Notepad Xtestfile1 2270 Xvimgrepadd MacOS Xtestfile2 2271 let l = g:Xgetlist() 2272 call assert_equal(2, len(l)) 2273 call assert_equal('Editor:Notepad NOTEPAD', l[0].text) 2274 2275 Xvimgrep #\cvim#g Xtestfile? 2276 let l = g:Xgetlist() 2277 call assert_equal(2, len(l)) 2278 call assert_equal(8, l[0].col) 2279 call assert_equal(12, l[1].col) 2280 2281 1Xvimgrep ?Editor? Xtestfile* 2282 let l = g:Xgetlist() 2283 call assert_equal(1, len(l)) 2284 call assert_equal('Editor:VIM vim', l[0].text) 2285 2286 edit +3 Xtestfile2 2287 Xvimgrep +\cemacs+j Xtestfile1 2288 let l = g:Xgetlist() 2289 call assert_equal('Xtestfile2', bufname('')) 2290 call assert_equal('Editor:Emacs EmAcS', l[0].text) 2291 2292 call delete('Xtestfile1') 2293 call delete('Xtestfile2') 2294endfunc 2295 2296" Tests for the :vimgrep command 2297func Test_vimgrep() 2298 call XvimgrepTests('c') 2299 call XvimgrepTests('l') 2300endfunc 2301 2302func XfreeTests(cchar) 2303 call s:setup_commands(a:cchar) 2304 2305 enew | only 2306 2307 " Deleting the quickfix stack should work even When the current list is 2308 " somewhere in the middle of the stack 2309 Xexpr ['Xfile1:10:10:Line 10', 'Xfile1:15:15:Line 15'] 2310 Xexpr ['Xfile2:20:20:Line 20', 'Xfile2:25:25:Line 25'] 2311 Xexpr ['Xfile3:30:30:Line 30', 'Xfile3:35:35:Line 35'] 2312 Xolder 2313 call g:Xsetlist([], 'f') 2314 call assert_equal(0, len(g:Xgetlist())) 2315 2316 " After deleting the stack, adding a new list should create a stack with a 2317 " single list. 2318 Xexpr ['Xfile1:10:10:Line 10', 'Xfile1:15:15:Line 15'] 2319 call assert_equal(1, g:Xgetlist({'all':1}).nr) 2320 2321 " Deleting the stack from a quickfix window should update/clear the 2322 " quickfix/location list window. 2323 Xexpr ['Xfile1:10:10:Line 10', 'Xfile1:15:15:Line 15'] 2324 Xexpr ['Xfile2:20:20:Line 20', 'Xfile2:25:25:Line 25'] 2325 Xexpr ['Xfile3:30:30:Line 30', 'Xfile3:35:35:Line 35'] 2326 Xolder 2327 Xwindow 2328 call g:Xsetlist([], 'f') 2329 call assert_equal(2, winnr('$')) 2330 call assert_equal(1, line('$')) 2331 Xclose 2332 2333 " Deleting the stack from a non-quickfix window should update/clear the 2334 " quickfix/location list window. 2335 Xexpr ['Xfile1:10:10:Line 10', 'Xfile1:15:15:Line 15'] 2336 Xexpr ['Xfile2:20:20:Line 20', 'Xfile2:25:25:Line 25'] 2337 Xexpr ['Xfile3:30:30:Line 30', 'Xfile3:35:35:Line 35'] 2338 Xolder 2339 Xwindow 2340 wincmd p 2341 call g:Xsetlist([], 'f') 2342 call assert_equal(0, len(g:Xgetlist())) 2343 wincmd p 2344 call assert_equal(2, winnr('$')) 2345 call assert_equal(1, line('$')) 2346 2347 " After deleting the location list stack, if the location list window is 2348 " opened, then a new location list should be created. So opening the 2349 " location list window again should not create a new window. 2350 if a:cchar == 'l' 2351 lexpr ['Xfile1:10:10:Line 10', 'Xfile1:15:15:Line 15'] 2352 wincmd p 2353 lopen 2354 call assert_equal(2, winnr('$')) 2355 endif 2356 Xclose 2357endfunc 2358 2359" Tests for the quickfix free functionality 2360func Test_qf_free() 2361 call XfreeTests('c') 2362 call XfreeTests('l') 2363endfunc 2364 2365" Test for buffer overflow when parsing lines and adding new entries to 2366" the quickfix list. 2367func Test_bufoverflow() 2368 set efm=%f:%l:%m 2369 cgetexpr ['File1:100:' . repeat('x', 1025)] 2370 2371 set efm=%+GCompiler:\ %.%#,%f:%l:%m 2372 cgetexpr ['Compiler: ' . repeat('a', 1015), 'File1:10:Hello World'] 2373 2374 set efm=%DEntering\ directory\ %f,%f:%l:%m 2375 cgetexpr ['Entering directory ' . repeat('a', 1006), 2376 \ 'File1:10:Hello World'] 2377 set efm&vim 2378endfunc 2379 2380" Tests for getting the quickfix stack size 2381func XsizeTests(cchar) 2382 call s:setup_commands(a:cchar) 2383 2384 call g:Xsetlist([], 'f') 2385 call assert_equal(0, g:Xgetlist({'nr':'$'}).nr) 2386 call assert_equal('', g:Xgetlist({'nr':'$', 'all':1}).title) 2387 call assert_equal(0, g:Xgetlist({'nr':0}).nr) 2388 2389 Xexpr "File1:10:Line1" 2390 Xexpr "File2:20:Line2" 2391 Xexpr "File3:30:Line3" 2392 Xolder | Xolder 2393 call assert_equal(3, g:Xgetlist({'nr':'$'}).nr) 2394 call g:Xsetlist([], 'f') 2395 2396 Xexpr "File1:10:Line1" 2397 Xexpr "File2:20:Line2" 2398 Xexpr "File3:30:Line3" 2399 Xolder | Xolder 2400 call g:Xsetlist([], 'a', {'nr':'$', 'title':'Compiler'}) 2401 call assert_equal('Compiler', g:Xgetlist({'nr':3, 'all':1}).title) 2402endfunc 2403 2404func Test_Qf_Size() 2405 call XsizeTests('c') 2406 call XsizeTests('l') 2407endfunc 2408 2409func Test_cclose_from_copen() 2410 augroup QF_Test 2411 au! 2412 au FileType qf :call assert_fails(':cclose', 'E788') 2413 augroup END 2414 copen 2415 augroup QF_Test 2416 au! 2417 augroup END 2418 augroup! QF_Test 2419endfunc 2420 2421func Test_cclose_in_autocmd() 2422 " Problem is only triggered if "starting" is zero, so that the OptionsSet 2423 " event will be triggered. 2424 call test_override('starting', 1) 2425 augroup QF_Test 2426 au! 2427 au FileType qf :call assert_fails(':cclose', 'E788') 2428 augroup END 2429 copen 2430 augroup QF_Test 2431 au! 2432 augroup END 2433 augroup! QF_Test 2434 call test_override('starting', 0) 2435endfunc 2436 2437func Test_resize_from_copen() 2438 augroup QF_Test 2439 au! 2440 au FileType qf resize 5 2441 augroup END 2442 try 2443 " This should succeed without any exception. No other buffers are 2444 " involved in the autocmd. 2445 copen 2446 finally 2447 augroup QF_Test 2448 au! 2449 augroup END 2450 augroup! QF_Test 2451 endtry 2452endfunc 2453 2454" Tests for the quickfix buffer b:changedtick variable 2455func Xchangedtick_tests(cchar) 2456 call s:setup_commands(a:cchar) 2457 2458 new | only 2459 2460 Xexpr "" | Xexpr "" | Xexpr "" 2461 2462 Xopen 2463 Xolder 2464 Xolder 2465 Xaddexpr "F1:10:Line10" 2466 Xaddexpr "F2:20:Line20" 2467 call g:Xsetlist([{"filename":"F3", "lnum":30, "text":"Line30"}], 'a') 2468 call g:Xsetlist([], 'f') 2469 call assert_equal(8, getbufvar('%', 'changedtick')) 2470 Xclose 2471endfunc 2472 2473func Test_changedtick() 2474 call Xchangedtick_tests('c') 2475 call Xchangedtick_tests('l') 2476endfunc 2477 2478" Tests for parsing an expression using setqflist() 2479func Xsetexpr_tests(cchar) 2480 call s:setup_commands(a:cchar) 2481 2482 let t = ["File1:10:Line10", "File1:20:Line20"] 2483 call g:Xsetlist([], ' ', {'lines' : t}) 2484 call g:Xsetlist([], 'a', {'lines' : ["File1:30:Line30"]}) 2485 2486 let l = g:Xgetlist() 2487 call assert_equal(3, len(l)) 2488 call assert_equal(20, l[1].lnum) 2489 call assert_equal('Line30', l[2].text) 2490 call g:Xsetlist([], 'r', {'lines' : ["File2:5:Line5"]}) 2491 let l = g:Xgetlist() 2492 call assert_equal(1, len(l)) 2493 call assert_equal('Line5', l[0].text) 2494 call assert_equal(-1, g:Xsetlist([], 'a', {'lines' : 10})) 2495 call assert_equal(-1, g:Xsetlist([], 'a', {'lines' : "F1:10:L10"})) 2496 2497 call g:Xsetlist([], 'f') 2498 " Add entries to multiple lists 2499 call g:Xsetlist([], 'a', {'nr' : 1, 'lines' : ["File1:10:Line10"]}) 2500 call g:Xsetlist([], 'a', {'nr' : 2, 'lines' : ["File2:20:Line20"]}) 2501 call g:Xsetlist([], 'a', {'nr' : 1, 'lines' : ["File1:15:Line15"]}) 2502 call g:Xsetlist([], 'a', {'nr' : 2, 'lines' : ["File2:25:Line25"]}) 2503 call assert_equal('Line15', g:Xgetlist({'nr':1, 'items':1}).items[1].text) 2504 call assert_equal('Line25', g:Xgetlist({'nr':2, 'items':1}).items[1].text) 2505 2506 " Adding entries using a custom efm 2507 set efm& 2508 call g:Xsetlist([], ' ', {'efm' : '%f#%l#%m', 2509 \ 'lines' : ["F1#10#L10", "F2#20#L20"]}) 2510 call assert_equal(20, g:Xgetlist({'items':1}).items[1].lnum) 2511 call g:Xsetlist([], 'a', {'efm' : '%f#%l#%m', 'lines' : ["F3:30:L30"]}) 2512 call assert_equal('F3:30:L30', g:Xgetlist({'items':1}).items[2].text) 2513 call assert_equal(20, g:Xgetlist({'items':1}).items[1].lnum) 2514 call assert_equal(-1, g:Xsetlist([], 'a', {'efm' : [], 2515 \ 'lines' : ['F1:10:L10']})) 2516endfunc 2517 2518func Test_setexpr() 2519 call Xsetexpr_tests('c') 2520 call Xsetexpr_tests('l') 2521endfunc 2522 2523" Tests for per quickfix/location list directory stack 2524func Xmultidirstack_tests(cchar) 2525 call s:setup_commands(a:cchar) 2526 2527 call g:Xsetlist([], 'f') 2528 Xexpr "" | Xexpr "" 2529 2530 call g:Xsetlist([], 'a', {'nr' : 1, 'lines' : ["Entering dir 'Xone/a'"]}) 2531 call g:Xsetlist([], 'a', {'nr' : 2, 'lines' : ["Entering dir 'Xtwo/a'"]}) 2532 call g:Xsetlist([], 'a', {'nr' : 1, 'lines' : ["one.txt:3:one one one"]}) 2533 call g:Xsetlist([], 'a', {'nr' : 2, 'lines' : ["two.txt:5:two two two"]}) 2534 2535 let l1 = g:Xgetlist({'nr':1, 'items':1}) 2536 let l2 = g:Xgetlist({'nr':2, 'items':1}) 2537 call assert_equal('Xone/a/one.txt', bufname(l1.items[1].bufnr)) 2538 call assert_equal(3, l1.items[1].lnum) 2539 call assert_equal('Xtwo/a/two.txt', bufname(l2.items[1].bufnr)) 2540 call assert_equal(5, l2.items[1].lnum) 2541endfunc 2542 2543func Test_multidirstack() 2544 call mkdir('Xone/a', 'p') 2545 call mkdir('Xtwo/a', 'p') 2546 let lines = ['1', '2', 'one one one', '4', 'two two two', '6', '7'] 2547 call writefile(lines, 'Xone/a/one.txt') 2548 call writefile(lines, 'Xtwo/a/two.txt') 2549 let save_efm = &efm 2550 set efm=%DEntering\ dir\ '%f',%f:%l:%m,%XLeaving\ dir\ '%f' 2551 2552 call Xmultidirstack_tests('c') 2553 call Xmultidirstack_tests('l') 2554 2555 let &efm = save_efm 2556 call delete('Xone', 'rf') 2557 call delete('Xtwo', 'rf') 2558endfunc 2559 2560" Tests for per quickfix/location list file stack 2561func Xmultifilestack_tests(cchar) 2562 call s:setup_commands(a:cchar) 2563 2564 call g:Xsetlist([], 'f') 2565 Xexpr "" | Xexpr "" 2566 2567 call g:Xsetlist([], 'a', {'nr' : 1, 'lines' : ["[one.txt]"]}) 2568 call g:Xsetlist([], 'a', {'nr' : 2, 'lines' : ["[two.txt]"]}) 2569 call g:Xsetlist([], 'a', {'nr' : 1, 'lines' : ["(3,5) one one one"]}) 2570 call g:Xsetlist([], 'a', {'nr' : 2, 'lines' : ["(5,9) two two two"]}) 2571 2572 let l1 = g:Xgetlist({'nr':1, 'items':1}) 2573 let l2 = g:Xgetlist({'nr':2, 'items':1}) 2574 call assert_equal('one.txt', bufname(l1.items[1].bufnr)) 2575 call assert_equal(3, l1.items[1].lnum) 2576 call assert_equal('two.txt', bufname(l2.items[1].bufnr)) 2577 call assert_equal(5, l2.items[1].lnum) 2578endfunc 2579 2580func Test_multifilestack() 2581 let lines = ['1', '2', 'one one one', '4', 'two two two', '6', '7'] 2582 call writefile(lines, 'one.txt') 2583 call writefile(lines, 'two.txt') 2584 let save_efm = &efm 2585 set efm=%+P[%f],(%l\\,%c)\ %m,%-Q 2586 2587 call Xmultifilestack_tests('c') 2588 call Xmultifilestack_tests('l') 2589 2590 let &efm = save_efm 2591 call delete('one.txt') 2592 call delete('two.txt') 2593endfunc 2594 2595" Tests for per buffer 'efm' setting 2596func Test_perbuf_efm() 2597 call writefile(["File1-10-Line10"], 'one.txt') 2598 call writefile(["File2#20#Line20"], 'two.txt') 2599 set efm=%f#%l#%m 2600 new | only 2601 new 2602 setlocal efm=%f-%l-%m 2603 cfile one.txt 2604 wincmd w 2605 caddfile two.txt 2606 2607 let l = getqflist() 2608 call assert_equal(10, l[0].lnum) 2609 call assert_equal('Line20', l[1].text) 2610 2611 set efm& 2612 new | only 2613 call delete('one.txt') 2614 call delete('two.txt') 2615endfunc 2616 2617" Open multiple help windows using ":lhelpgrep 2618" This test used to crash Vim 2619func Test_Multi_LL_Help() 2620 new | only 2621 lhelpgrep window 2622 lopen 2623 e# 2624 lhelpgrep buffer 2625 call assert_equal(3, winnr('$')) 2626 call assert_true(len(getloclist(1)) != 0) 2627 call assert_true(len(getloclist(2)) != 0) 2628 new | only 2629endfunc 2630 2631" Tests for adding new quickfix lists using setqflist() 2632func XaddQf_tests(cchar) 2633 call s:setup_commands(a:cchar) 2634 2635 " Create a new list using ' ' for action 2636 call g:Xsetlist([], 'f') 2637 call g:Xsetlist([], ' ', {'title' : 'Test1'}) 2638 let l = g:Xgetlist({'nr' : '$', 'all' : 1}) 2639 call assert_equal(1, l.nr) 2640 call assert_equal('Test1', l.title) 2641 2642 " Create a new list using ' ' for action and '$' for 'nr' 2643 call g:Xsetlist([], 'f') 2644 call g:Xsetlist([], ' ', {'title' : 'Test2', 'nr' : '$'}) 2645 let l = g:Xgetlist({'nr' : '$', 'all' : 1}) 2646 call assert_equal(1, l.nr) 2647 call assert_equal('Test2', l.title) 2648 2649 " Create a new list using 'a' for action 2650 call g:Xsetlist([], 'f') 2651 call g:Xsetlist([], 'a', {'title' : 'Test3'}) 2652 let l = g:Xgetlist({'nr' : '$', 'all' : 1}) 2653 call assert_equal(1, l.nr) 2654 call assert_equal('Test3', l.title) 2655 2656 " Create a new list using 'a' for action and '$' for 'nr' 2657 call g:Xsetlist([], 'f') 2658 call g:Xsetlist([], 'a', {'title' : 'Test3', 'nr' : '$'}) 2659 call g:Xsetlist([], 'a', {'title' : 'Test4'}) 2660 let l = g:Xgetlist({'nr' : '$', 'all' : 1}) 2661 call assert_equal(1, l.nr) 2662 call assert_equal('Test4', l.title) 2663 2664 " Adding a quickfix list should remove all the lists following the current 2665 " list. 2666 Xexpr "" | Xexpr "" | Xexpr "" 2667 silent! 10Xolder 2668 call g:Xsetlist([], ' ', {'title' : 'Test5'}) 2669 let l = g:Xgetlist({'nr' : '$', 'all' : 1}) 2670 call assert_equal(2, l.nr) 2671 call assert_equal('Test5', l.title) 2672 2673 " Add a quickfix list using '$' as the list number. 2674 let lastqf = g:Xgetlist({'nr':'$'}).nr 2675 silent! 99Xolder 2676 call g:Xsetlist([], ' ', {'nr' : '$', 'title' : 'Test6'}) 2677 let l = g:Xgetlist({'nr' : '$', 'all' : 1}) 2678 call assert_equal(lastqf + 1, l.nr) 2679 call assert_equal('Test6', l.title) 2680 2681 " Add a quickfix list using 'nr' set to one more than the quickfix 2682 " list size. 2683 let lastqf = g:Xgetlist({'nr':'$'}).nr 2684 silent! 99Xolder 2685 call g:Xsetlist([], ' ', {'nr' : lastqf + 1, 'title' : 'Test7'}) 2686 let l = g:Xgetlist({'nr' : '$', 'all' : 1}) 2687 call assert_equal(lastqf + 1, l.nr) 2688 call assert_equal('Test7', l.title) 2689 2690 " Add a quickfix list to a stack with 10 lists using 'nr' set to '$' 2691 exe repeat('Xexpr "" |', 9) . 'Xexpr ""' 2692 silent! 99Xolder 2693 call g:Xsetlist([], ' ', {'nr' : '$', 'title' : 'Test8'}) 2694 let l = g:Xgetlist({'nr' : '$', 'all' : 1}) 2695 call assert_equal(10, l.nr) 2696 call assert_equal('Test8', l.title) 2697 2698 " Add a quickfix list using 'nr' set to a value greater than 10 2699 call assert_equal(-1, g:Xsetlist([], ' ', {'nr' : 12, 'title' : 'Test9'})) 2700 2701 " Try adding a quickfix list with 'nr' set to a value greater than the 2702 " quickfix list size but less than 10. 2703 call g:Xsetlist([], 'f') 2704 Xexpr "" | Xexpr "" | Xexpr "" 2705 silent! 99Xolder 2706 call assert_equal(-1, g:Xsetlist([], ' ', {'nr' : 8, 'title' : 'Test10'})) 2707 2708 " Add a quickfix list using 'nr' set to a some string or list 2709 call assert_equal(-1, g:Xsetlist([], ' ', {'nr' : [1,2], 'title' : 'Test11'})) 2710endfunc 2711 2712func Test_add_qf() 2713 call XaddQf_tests('c') 2714 call XaddQf_tests('l') 2715endfunc 2716 2717" Test for getting the quickfix list items from some text without modifying 2718" the quickfix stack 2719func XgetListFromLines(cchar) 2720 call s:setup_commands(a:cchar) 2721 call g:Xsetlist([], 'f') 2722 2723 let l = g:Xgetlist({'lines' : ["File2:20:Line20", "File2:30:Line30"]}).items 2724 call assert_equal(2, len(l)) 2725 call assert_equal(30, l[1].lnum) 2726 2727 call assert_equal({}, g:Xgetlist({'lines' : 10})) 2728 call assert_equal({}, g:Xgetlist({'lines' : 'File1:10:Line10'})) 2729 call assert_equal([], g:Xgetlist({'lines' : []}).items) 2730 call assert_equal([], g:Xgetlist({'lines' : [10, 20]}).items) 2731 2732 " Parse text using a custom efm 2733 set efm& 2734 let l = g:Xgetlist({'lines':['File3#30#Line30'], 'efm' : '%f#%l#%m'}).items 2735 call assert_equal('Line30', l[0].text) 2736 let l = g:Xgetlist({'lines':['File3:30:Line30'], 'efm' : '%f-%l-%m'}).items 2737 call assert_equal('File3:30:Line30', l[0].text) 2738 let l = g:Xgetlist({'lines':['File3:30:Line30'], 'efm' : [1,2]}) 2739 call assert_equal({}, l) 2740 call assert_fails("call g:Xgetlist({'lines':['abc'], 'efm':'%2'})", 'E376:') 2741 call assert_fails("call g:Xgetlist({'lines':['abc'], 'efm':''})", 'E378:') 2742 2743 " Make sure that the quickfix stack is not modified 2744 call assert_equal(0, g:Xgetlist({'nr' : '$'}).nr) 2745endfunc 2746 2747func Test_get_list_from_lines() 2748 call XgetListFromLines('c') 2749 call XgetListFromLines('l') 2750endfunc 2751 2752" Tests for the quickfix list id 2753func Xqfid_tests(cchar) 2754 call s:setup_commands(a:cchar) 2755 2756 call g:Xsetlist([], 'f') 2757 call assert_equal(0, g:Xgetlist({'id':0}).id) 2758 Xexpr '' 2759 let start_id = g:Xgetlist({'id' : 0}).id 2760 Xexpr '' | Xexpr '' 2761 Xolder 2762 call assert_equal(start_id, g:Xgetlist({'id':0, 'nr':1}).id) 2763 call assert_equal(start_id + 1, g:Xgetlist({'id':0, 'nr':0}).id) 2764 call assert_equal(start_id + 2, g:Xgetlist({'id':0, 'nr':'$'}).id) 2765 call assert_equal(0, g:Xgetlist({'id':0, 'nr':99}).id) 2766 call assert_equal(2, g:Xgetlist({'id':start_id + 1, 'nr':0}).nr) 2767 call assert_equal(0, g:Xgetlist({'id':99, 'nr':0}).id) 2768 call assert_equal(0, g:Xgetlist({'id':"abc", 'nr':0}).id) 2769 2770 call g:Xsetlist([], 'a', {'id':start_id, 'context':[1,2]}) 2771 call assert_equal([1,2], g:Xgetlist({'nr':1, 'context':1}).context) 2772 call g:Xsetlist([], 'a', {'id':start_id+1, 'lines':['F1:10:L10']}) 2773 call assert_equal('L10', g:Xgetlist({'nr':2, 'items':1}).items[0].text) 2774 call assert_equal(-1, g:Xsetlist([], 'a', {'id':999, 'title':'Vim'})) 2775 call assert_equal(-1, g:Xsetlist([], 'a', {'id':'abc', 'title':'Vim'})) 2776 2777 let qfid = g:Xgetlist({'id':0, 'nr':0}) 2778 call g:Xsetlist([], 'f') 2779 call assert_equal(0, g:Xgetlist({'id':qfid, 'nr':0}).id) 2780endfunc 2781 2782func Test_qf_id() 2783 call Xqfid_tests('c') 2784 call Xqfid_tests('l') 2785endfunc 2786 2787func Xqfjump_tests(cchar) 2788 call s:setup_commands(a:cchar) 2789 2790 call writefile(["Line1\tFoo", "Line2"], 'F1') 2791 call writefile(["Line1\tBar", "Line2"], 'F2') 2792 call writefile(["Line1\tBaz", "Line2"], 'F3') 2793 2794 call g:Xsetlist([], 'f') 2795 2796 " Tests for 2797 " Jumping to a line using a pattern 2798 " Jumping to a column greater than the last column in a line 2799 " Jumping to a line greater than the last line in the file 2800 let l = [] 2801 for i in range(1, 7) 2802 call add(l, {}) 2803 endfor 2804 let l[0].filename='F1' 2805 let l[0].pattern='Line1' 2806 let l[1].filename='F2' 2807 let l[1].pattern='Line1' 2808 let l[2].filename='F3' 2809 let l[2].pattern='Line1' 2810 let l[3].filename='F3' 2811 let l[3].lnum=1 2812 let l[3].col=9 2813 let l[3].vcol=1 2814 let l[4].filename='F3' 2815 let l[4].lnum=99 2816 let l[5].filename='F3' 2817 let l[5].lnum=1 2818 let l[5].col=99 2819 let l[5].vcol=1 2820 let l[6].filename='F3' 2821 let l[6].pattern='abcxyz' 2822 2823 call g:Xsetlist([], ' ', {'items' : l}) 2824 Xopen | only 2825 2Xnext 2826 call assert_equal(3, g:Xgetlist({'idx' : 0}).idx) 2827 call assert_equal('F3', bufname('%')) 2828 Xnext 2829 call assert_equal(7, col('.')) 2830 Xnext 2831 call assert_equal(2, line('.')) 2832 Xnext 2833 call assert_equal(9, col('.')) 2834 2 2835 Xnext 2836 call assert_equal(2, line('.')) 2837 2838 if a:cchar == 'l' 2839 " When jumping to a location list entry in the location list window and 2840 " no usable windows are available, then a new window should be opened. 2841 enew! | new | only 2842 call g:Xsetlist([], 'f') 2843 setlocal buftype=nofile 2844 new 2845 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']}) 2846 Xopen 2847 let winid = win_getid() 2848 wincmd p 2849 close 2850 call win_gotoid(winid) 2851 Xnext 2852 call assert_equal(3, winnr('$')) 2853 call assert_equal(1, winnr()) 2854 call assert_equal(2, line('.')) 2855 2856 " When jumping to an entry in the location list window and the window 2857 " associated with the location list is not present and a window containing 2858 " the file is already present, then that window should be used. 2859 close 2860 belowright new 2861 call g:Xsetlist([], 'f') 2862 edit F3 2863 call win_gotoid(winid) 2864 Xlast 2865 call assert_equal(3, winnr()) 2866 call assert_equal(6, g:Xgetlist({'size' : 1}).size) 2867 call assert_equal(winid, g:Xgetlist({'winid' : 1}).winid) 2868 endif 2869 2870 " Cleanup 2871 enew! 2872 new | only 2873 2874 call delete('F1') 2875 call delete('F2') 2876 call delete('F3') 2877endfunc 2878 2879func Test_qfjump() 2880 call Xqfjump_tests('c') 2881 call Xqfjump_tests('l') 2882endfunc 2883 2884" Tests for the getqflist() and getloclist() functions when the list is not 2885" present or is empty 2886func Xgetlist_empty_tests(cchar) 2887 call s:setup_commands(a:cchar) 2888 2889 " Empty quickfix stack 2890 call g:Xsetlist([], 'f') 2891 call assert_equal('', g:Xgetlist({'context' : 0}).context) 2892 call assert_equal(0, g:Xgetlist({'id' : 0}).id) 2893 call assert_equal(0, g:Xgetlist({'idx' : 0}).idx) 2894 call assert_equal([], g:Xgetlist({'items' : 0}).items) 2895 call assert_equal(0, g:Xgetlist({'nr' : 0}).nr) 2896 call assert_equal(0, g:Xgetlist({'size' : 0}).size) 2897 call assert_equal('', g:Xgetlist({'title' : 0}).title) 2898 call assert_equal(0, g:Xgetlist({'winid' : 0}).winid) 2899 call assert_equal({'context' : '', 'id' : 0, 'idx' : 0, 'items' : [], 'nr' : 0, 'size' : 0, 'title' : '', 'winid' : 0}, g:Xgetlist({'all' : 0})) 2900 2901 " Empty quickfix list 2902 Xexpr "" 2903 call assert_equal('', g:Xgetlist({'context' : 0}).context) 2904 call assert_notequal(0, g:Xgetlist({'id' : 0}).id) 2905 call assert_equal(0, g:Xgetlist({'idx' : 0}).idx) 2906 call assert_equal([], g:Xgetlist({'items' : 0}).items) 2907 call assert_notequal(0, g:Xgetlist({'nr' : 0}).nr) 2908 call assert_equal(0, g:Xgetlist({'size' : 0}).size) 2909 call assert_notequal('', g:Xgetlist({'title' : 0}).title) 2910 call assert_equal(0, g:Xgetlist({'winid' : 0}).winid) 2911 2912 let qfid = g:Xgetlist({'id' : 0}).id 2913 call g:Xsetlist([], 'f') 2914 2915 " Non-existing quickfix identifier 2916 call assert_equal('', g:Xgetlist({'id' : qfid, 'context' : 0}).context) 2917 call assert_equal(0, g:Xgetlist({'id' : qfid}).id) 2918 call assert_equal(0, g:Xgetlist({'id' : qfid, 'idx' : 0}).idx) 2919 call assert_equal([], g:Xgetlist({'id' : qfid, 'items' : 0}).items) 2920 call assert_equal(0, g:Xgetlist({'id' : qfid, 'nr' : 0}).nr) 2921 call assert_equal(0, g:Xgetlist({'id' : qfid, 'size' : 0}).size) 2922 call assert_equal('', g:Xgetlist({'id' : qfid, 'title' : 0}).title) 2923 call assert_equal(0, g:Xgetlist({'id' : qfid, 'winid' : 0}).winid) 2924 call assert_equal({'context' : '', 'id' : 0, 'idx' : 0, 'items' : [], 'nr' : 0, 'size' : 0, 'title' : '', 'winid' : 0}, g:Xgetlist({'id' : qfid, 'all' : 0})) 2925 2926 " Non-existing quickfix list number 2927 call assert_equal('', g:Xgetlist({'nr' : 5, 'context' : 0}).context) 2928 call assert_equal(0, g:Xgetlist({'nr' : 5}).nr) 2929 call assert_equal(0, g:Xgetlist({'nr' : 5, 'idx' : 0}).idx) 2930 call assert_equal([], g:Xgetlist({'nr' : 5, 'items' : 0}).items) 2931 call assert_equal(0, g:Xgetlist({'nr' : 5, 'id' : 0}).id) 2932 call assert_equal(0, g:Xgetlist({'nr' : 5, 'size' : 0}).size) 2933 call assert_equal('', g:Xgetlist({'nr' : 5, 'title' : 0}).title) 2934 call assert_equal(0, g:Xgetlist({'nr' : 5, 'winid' : 0}).winid) 2935 call assert_equal({'context' : '', 'id' : 0, 'idx' : 0, 'items' : [], 'nr' : 0, 'size' : 0, 'title' : '', 'winid' : 0}, g:Xgetlist({'nr' : 5, 'all' : 0})) 2936endfunc 2937 2938func Test_getqflist() 2939 call Xgetlist_empty_tests('c') 2940 call Xgetlist_empty_tests('l') 2941endfunc 2942