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