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 enew! | call append(0, "F2:10:Line 10") 1970 cbuffer! 1971 enew! | call append(0, "F2:20:Line 20") 1972 cgetbuffer 1973 enew! | call append(0, "F2:30:Line 30") 1974 caddbuffer 1975 1976 let l = ['precexpr', 1977 \ 'postcexpr', 1978 \ 'precaddexpr', 1979 \ 'postcaddexpr', 1980 \ 'precgetexpr', 1981 \ 'postcgetexpr', 1982 \ 'precbuffer', 1983 \ 'postcbuffer', 1984 \ 'precgetbuffer', 1985 \ 'postcgetbuffer', 1986 \ 'precaddbuffer', 1987 \ 'postcaddbuffer'] 1988 call assert_equal(l, g:acmds) 1989endfunc 1990 1991func Test_Autocmd_Exception() 1992 set efm=%m 1993 lgetexpr '?' 1994 1995 try 1996 call DoesNotExit() 1997 catch 1998 lgetexpr '1' 1999 finally 2000 lgetexpr '1' 2001 endtry 2002 2003 call assert_equal('1', getloclist(0)[0].text) 2004 2005 set efm&vim 2006endfunc 2007 2008func Test_caddbuffer_wrong() 2009 " This used to cause a memory access in freed memory. 2010 let save_efm = &efm 2011 set efm=%EEEE%m,%WWWW,%+CCCC%>%#,%GGGG%.# 2012 cgetexpr ['WWWW', 'EEEE', 'CCCC'] 2013 let &efm = save_efm 2014 caddbuffer 2015 bwipe! 2016endfunc 2017 2018func Test_caddexpr_wrong() 2019 " This used to cause a memory access in freed memory. 2020 cbuffer 2021 cbuffer 2022 copen 2023 let save_efm = &efm 2024 set efm=% 2025 call assert_fails('caddexpr ""', 'E376:') 2026 let &efm = save_efm 2027endfunc 2028 2029func Test_dirstack_cleanup() 2030 " This used to cause a memory access in freed memory. 2031 let save_efm = &efm 2032 lexpr '0' 2033 lopen 2034 fun X(c) 2035 let save_efm=&efm 2036 set efm=%D%f 2037 if a:c == 'c' 2038 caddexpr '::' 2039 else 2040 laddexpr ':0:0' 2041 endif 2042 let &efm=save_efm 2043 endfun 2044 call X('c') 2045 call X('l') 2046 call setqflist([], 'r') 2047 caddbuffer 2048 let &efm = save_efm 2049endfunc 2050 2051" Tests for jumping to entries from the location list window and quickfix 2052" window 2053func Test_cwindow_jump() 2054 set efm=%f%%%l%%%m 2055 lgetexpr ["F1%10%Line 10", "F2%20%Line 20", "F3%30%Line 30"] 2056 lopen | only 2057 lfirst 2058 call assert_true(winnr('$') == 2) 2059 call assert_true(winnr() == 1) 2060 " Location list for the new window should be set 2061 call assert_true(getloclist(0)[2].text == 'Line 30') 2062 2063 " Open a scratch buffer 2064 " Open a new window and create a location list 2065 " Open the location list window and close the other window 2066 " Jump to an entry. 2067 " Should create a new window and jump to the entry. The scrtach buffer 2068 " should not be used. 2069 enew | only 2070 set buftype=nofile 2071 below new 2072 lgetexpr ["F1%10%Line 10", "F2%20%Line 20", "F3%30%Line 30"] 2073 lopen 2074 2wincmd c 2075 lnext 2076 call assert_true(winnr('$') == 3) 2077 call assert_true(winnr() == 2) 2078 2079 " Open two windows with two different location lists 2080 " Open the location list window and close the previous window 2081 " Jump to an entry in the location list window 2082 " Should open the file in the first window and not set the location list. 2083 enew | only 2084 lgetexpr ["F1%5%Line 5"] 2085 below new 2086 lgetexpr ["F1%10%Line 10", "F2%20%Line 20", "F3%30%Line 30"] 2087 lopen 2088 2wincmd c 2089 lnext 2090 call assert_true(winnr() == 1) 2091 call assert_true(getloclist(0)[0].text == 'Line 5') 2092 2093 enew | only 2094 cgetexpr ["F1%10%Line 10", "F2%20%Line 20", "F3%30%Line 30"] 2095 copen 2096 cnext 2097 call assert_true(winnr('$') == 2) 2098 call assert_true(winnr() == 1) 2099 2100 enew | only 2101 set efm&vim 2102endfunc 2103 2104func XvimgrepTests(cchar) 2105 call s:setup_commands(a:cchar) 2106 2107 call writefile(['Editor:VIM vim', 2108 \ 'Editor:Emacs EmAcS', 2109 \ 'Editor:Notepad NOTEPAD'], 'Xtestfile1') 2110 call writefile(['Linux', 'MacOS', 'MS-Windows'], 'Xtestfile2') 2111 2112 " Error cases 2113 call assert_fails('Xvimgrep /abc *', 'E682:') 2114 2115 let @/='' 2116 call assert_fails('Xvimgrep // *', 'E35:') 2117 2118 call assert_fails('Xvimgrep abc', 'E683:') 2119 call assert_fails('Xvimgrep a1b2c3 Xtestfile1', 'E480:') 2120 call assert_fails('Xvimgrep pat Xa1b2c3', 'E480:') 2121 2122 Xexpr "" 2123 Xvimgrepadd Notepad Xtestfile1 2124 Xvimgrepadd MacOS Xtestfile2 2125 let l = g:Xgetlist() 2126 call assert_equal(2, len(l)) 2127 call assert_equal('Editor:Notepad NOTEPAD', l[0].text) 2128 2129 Xvimgrep #\cvim#g Xtestfile? 2130 let l = g:Xgetlist() 2131 call assert_equal(2, len(l)) 2132 call assert_equal(8, l[0].col) 2133 call assert_equal(12, l[1].col) 2134 2135 1Xvimgrep ?Editor? Xtestfile* 2136 let l = g:Xgetlist() 2137 call assert_equal(1, len(l)) 2138 call assert_equal('Editor:VIM vim', l[0].text) 2139 2140 edit +3 Xtestfile2 2141 Xvimgrep +\cemacs+j Xtestfile1 2142 let l = g:Xgetlist() 2143 call assert_equal('Xtestfile2', bufname('')) 2144 call assert_equal('Editor:Emacs EmAcS', l[0].text) 2145 2146 call delete('Xtestfile1') 2147 call delete('Xtestfile2') 2148endfunc 2149 2150" Tests for the :vimgrep command 2151func Test_vimgrep() 2152 call XvimgrepTests('c') 2153 call XvimgrepTests('l') 2154endfunc 2155 2156func XfreeTests(cchar) 2157 call s:setup_commands(a:cchar) 2158 2159 enew | only 2160 2161 " Deleting the quickfix stack should work even When the current list is 2162 " somewhere in the middle of the stack 2163 Xexpr ['Xfile1:10:10:Line 10', 'Xfile1:15:15:Line 15'] 2164 Xexpr ['Xfile2:20:20:Line 20', 'Xfile2:25:25:Line 25'] 2165 Xexpr ['Xfile3:30:30:Line 30', 'Xfile3:35:35:Line 35'] 2166 Xolder 2167 call g:Xsetlist([], 'f') 2168 call assert_equal(0, len(g:Xgetlist())) 2169 2170 " After deleting the stack, adding a new list should create a stack with a 2171 " single list. 2172 Xexpr ['Xfile1:10:10:Line 10', 'Xfile1:15:15:Line 15'] 2173 call assert_equal(1, g:Xgetlist({'all':1}).nr) 2174 2175 " Deleting the stack from a quickfix window should update/clear the 2176 " quickfix/location list window. 2177 Xexpr ['Xfile1:10:10:Line 10', 'Xfile1:15:15:Line 15'] 2178 Xexpr ['Xfile2:20:20:Line 20', 'Xfile2:25:25:Line 25'] 2179 Xexpr ['Xfile3:30:30:Line 30', 'Xfile3:35:35:Line 35'] 2180 Xolder 2181 Xwindow 2182 call g:Xsetlist([], 'f') 2183 call assert_equal(2, winnr('$')) 2184 call assert_equal(1, line('$')) 2185 Xclose 2186 2187 " Deleting the stack from a non-quickfix window should update/clear the 2188 " quickfix/location list window. 2189 Xexpr ['Xfile1:10:10:Line 10', 'Xfile1:15:15:Line 15'] 2190 Xexpr ['Xfile2:20:20:Line 20', 'Xfile2:25:25:Line 25'] 2191 Xexpr ['Xfile3:30:30:Line 30', 'Xfile3:35:35:Line 35'] 2192 Xolder 2193 Xwindow 2194 wincmd p 2195 call g:Xsetlist([], 'f') 2196 call assert_equal(0, len(g:Xgetlist())) 2197 wincmd p 2198 call assert_equal(2, winnr('$')) 2199 call assert_equal(1, line('$')) 2200 2201 " After deleting the location list stack, if the location list window is 2202 " opened, then a new location list should be created. So opening the 2203 " location list window again should not create a new window. 2204 if a:cchar == 'l' 2205 lexpr ['Xfile1:10:10:Line 10', 'Xfile1:15:15:Line 15'] 2206 wincmd p 2207 lopen 2208 call assert_equal(2, winnr('$')) 2209 endif 2210 Xclose 2211endfunc 2212 2213" Tests for the quickifx free functionality 2214func Test_qf_free() 2215 call XfreeTests('c') 2216 call XfreeTests('l') 2217endfunc 2218 2219" Test for buffer overflow when parsing lines and adding new entries to 2220" the quickfix list. 2221func Test_bufoverflow() 2222 set efm=%f:%l:%m 2223 cgetexpr ['File1:100:' . repeat('x', 1025)] 2224 2225 set efm=%+GCompiler:\ %.%#,%f:%l:%m 2226 cgetexpr ['Compiler: ' . repeat('a', 1015), 'File1:10:Hello World'] 2227 2228 set efm=%DEntering\ directory\ %f,%f:%l:%m 2229 cgetexpr ['Entering directory ' . repeat('a', 1006), 2230 \ 'File1:10:Hello World'] 2231 set efm&vim 2232endfunc 2233 2234" Tests for getting the quickfix stack size 2235func XsizeTests(cchar) 2236 call s:setup_commands(a:cchar) 2237 2238 call g:Xsetlist([], 'f') 2239 call assert_equal(0, g:Xgetlist({'nr':'$'}).nr) 2240 call assert_equal(1, len(g:Xgetlist({'nr':'$', 'all':1}))) 2241 call assert_equal(0, len(g:Xgetlist({'nr':0}))) 2242 2243 Xexpr "File1:10:Line1" 2244 Xexpr "File2:20:Line2" 2245 Xexpr "File3:30:Line3" 2246 Xolder | Xolder 2247 call assert_equal(3, g:Xgetlist({'nr':'$'}).nr) 2248 call g:Xsetlist([], 'f') 2249 2250 Xexpr "File1:10:Line1" 2251 Xexpr "File2:20:Line2" 2252 Xexpr "File3:30:Line3" 2253 Xolder | Xolder 2254 call g:Xsetlist([], 'a', {'nr':'$', 'title':'Compiler'}) 2255 call assert_equal('Compiler', g:Xgetlist({'nr':3, 'all':1}).title) 2256endfunc 2257 2258func Test_Qf_Size() 2259 call XsizeTests('c') 2260 call XsizeTests('l') 2261endfunc 2262 2263func Test_cclose_from_copen() 2264 augroup QF_Test 2265 au! 2266 au FileType qf :call assert_fails(':cclose', 'E788') 2267 augroup END 2268 copen 2269 augroup QF_Test 2270 au! 2271 augroup END 2272 augroup! QF_Test 2273endfunc 2274 2275func Test_cclose_in_autocmd() 2276 " Problem is only triggered if "starting" is zero, so that the OptionsSet 2277 " event will be triggered. 2278 call test_override('starting', 1) 2279 augroup QF_Test 2280 au! 2281 au FileType qf :call assert_fails(':cclose', 'E788') 2282 augroup END 2283 copen 2284 augroup QF_Test 2285 au! 2286 augroup END 2287 augroup! QF_Test 2288 call test_override('starting', 0) 2289endfunc 2290 2291func Test_resize_from_copen() 2292 augroup QF_Test 2293 au! 2294 au FileType qf resize 5 2295 augroup END 2296 try 2297 " This should succeed without any exception. No other buffers are 2298 " involved in the autocmd. 2299 copen 2300 finally 2301 augroup QF_Test 2302 au! 2303 augroup END 2304 augroup! QF_Test 2305 endtry 2306endfunc 2307 2308" Tests for the quickfix buffer b:changedtick variable 2309func Xchangedtick_tests(cchar) 2310 call s:setup_commands(a:cchar) 2311 2312 new | only 2313 2314 Xexpr "" | Xexpr "" | Xexpr "" 2315 2316 Xopen 2317 Xolder 2318 Xolder 2319 Xaddexpr "F1:10:Line10" 2320 Xaddexpr "F2:20:Line20" 2321 call g:Xsetlist([{"filename":"F3", "lnum":30, "text":"Line30"}], 'a') 2322 call g:Xsetlist([], 'f') 2323 call assert_equal(8, getbufvar('%', 'changedtick')) 2324 Xclose 2325endfunc 2326 2327func Test_changedtick() 2328 call Xchangedtick_tests('c') 2329 call Xchangedtick_tests('l') 2330endfunc 2331 2332" Tests for parsing an expression using setqflist() 2333func Xsetexpr_tests(cchar) 2334 call s:setup_commands(a:cchar) 2335 2336 let t = ["File1:10:Line10", "File1:20:Line20"] 2337 call g:Xsetlist([], ' ', {'lines' : t}) 2338 call g:Xsetlist([], 'a', {'lines' : ["File1:30:Line30"]}) 2339 2340 let l = g:Xgetlist() 2341 call assert_equal(3, len(l)) 2342 call assert_equal(20, l[1].lnum) 2343 call assert_equal('Line30', l[2].text) 2344 call g:Xsetlist([], 'r', {'lines' : ["File2:5:Line5"]}) 2345 let l = g:Xgetlist() 2346 call assert_equal(1, len(l)) 2347 call assert_equal('Line5', l[0].text) 2348 call assert_equal(-1, g:Xsetlist([], 'a', {'lines' : 10})) 2349 call assert_equal(-1, g:Xsetlist([], 'a', {'lines' : "F1:10:L10"})) 2350 2351 call g:Xsetlist([], 'f') 2352 " Add entries to multiple lists 2353 call g:Xsetlist([], 'a', {'nr' : 1, 'lines' : ["File1:10:Line10"]}) 2354 call g:Xsetlist([], 'a', {'nr' : 2, 'lines' : ["File2:20:Line20"]}) 2355 call g:Xsetlist([], 'a', {'nr' : 1, 'lines' : ["File1:15:Line15"]}) 2356 call g:Xsetlist([], 'a', {'nr' : 2, 'lines' : ["File2:25:Line25"]}) 2357 call assert_equal('Line15', g:Xgetlist({'nr':1, 'items':1}).items[1].text) 2358 call assert_equal('Line25', g:Xgetlist({'nr':2, 'items':1}).items[1].text) 2359 2360 " Adding entries using a custom efm 2361 set efm& 2362 call g:Xsetlist([], ' ', {'efm' : '%f#%l#%m', 2363 \ 'lines' : ["F1#10#L10", "F2#20#L20"]}) 2364 call assert_equal(20, g:Xgetlist({'items':1}).items[1].lnum) 2365 call g:Xsetlist([], 'a', {'efm' : '%f#%l#%m', 'lines' : ["F3:30:L30"]}) 2366 call assert_equal('F3:30:L30', g:Xgetlist({'items':1}).items[2].text) 2367 call assert_equal(20, g:Xgetlist({'items':1}).items[1].lnum) 2368 call assert_equal(-1, g:Xsetlist([], 'a', {'efm' : [], 2369 \ 'lines' : ['F1:10:L10']})) 2370endfunc 2371 2372func Test_setexpr() 2373 call Xsetexpr_tests('c') 2374 call Xsetexpr_tests('l') 2375endfunc 2376 2377" Tests for per quickfix/location list directory stack 2378func Xmultidirstack_tests(cchar) 2379 call s:setup_commands(a:cchar) 2380 2381 call g:Xsetlist([], 'f') 2382 Xexpr "" | Xexpr "" 2383 2384 call g:Xsetlist([], 'a', {'nr' : 1, 'lines' : ["Entering dir 'Xone/a'"]}) 2385 call g:Xsetlist([], 'a', {'nr' : 2, 'lines' : ["Entering dir 'Xtwo/a'"]}) 2386 call g:Xsetlist([], 'a', {'nr' : 1, 'lines' : ["one.txt:3:one one one"]}) 2387 call g:Xsetlist([], 'a', {'nr' : 2, 'lines' : ["two.txt:5:two two two"]}) 2388 2389 let l1 = g:Xgetlist({'nr':1, 'items':1}) 2390 let l2 = g:Xgetlist({'nr':2, 'items':1}) 2391 call assert_equal('Xone/a/one.txt', bufname(l1.items[1].bufnr)) 2392 call assert_equal(3, l1.items[1].lnum) 2393 call assert_equal('Xtwo/a/two.txt', bufname(l2.items[1].bufnr)) 2394 call assert_equal(5, l2.items[1].lnum) 2395endfunc 2396 2397func Test_multidirstack() 2398 call mkdir('Xone/a', 'p') 2399 call mkdir('Xtwo/a', 'p') 2400 let lines = ['1', '2', 'one one one', '4', 'two two two', '6', '7'] 2401 call writefile(lines, 'Xone/a/one.txt') 2402 call writefile(lines, 'Xtwo/a/two.txt') 2403 let save_efm = &efm 2404 set efm=%DEntering\ dir\ '%f',%f:%l:%m,%XLeaving\ dir\ '%f' 2405 2406 call Xmultidirstack_tests('c') 2407 call Xmultidirstack_tests('l') 2408 2409 let &efm = save_efm 2410 call delete('Xone', 'rf') 2411 call delete('Xtwo', 'rf') 2412endfunc 2413 2414" Tests for per quickfix/location list file stack 2415func Xmultifilestack_tests(cchar) 2416 call s:setup_commands(a:cchar) 2417 2418 call g:Xsetlist([], 'f') 2419 Xexpr "" | Xexpr "" 2420 2421 call g:Xsetlist([], 'a', {'nr' : 1, 'lines' : ["[one.txt]"]}) 2422 call g:Xsetlist([], 'a', {'nr' : 2, 'lines' : ["[two.txt]"]}) 2423 call g:Xsetlist([], 'a', {'nr' : 1, 'lines' : ["(3,5) one one one"]}) 2424 call g:Xsetlist([], 'a', {'nr' : 2, 'lines' : ["(5,9) two two two"]}) 2425 2426 let l1 = g:Xgetlist({'nr':1, 'items':1}) 2427 let l2 = g:Xgetlist({'nr':2, 'items':1}) 2428 call assert_equal('one.txt', bufname(l1.items[1].bufnr)) 2429 call assert_equal(3, l1.items[1].lnum) 2430 call assert_equal('two.txt', bufname(l2.items[1].bufnr)) 2431 call assert_equal(5, l2.items[1].lnum) 2432endfunc 2433 2434func Test_multifilestack() 2435 let lines = ['1', '2', 'one one one', '4', 'two two two', '6', '7'] 2436 call writefile(lines, 'one.txt') 2437 call writefile(lines, 'two.txt') 2438 let save_efm = &efm 2439 set efm=%+P[%f],(%l\\,%c)\ %m,%-Q 2440 2441 call Xmultifilestack_tests('c') 2442 call Xmultifilestack_tests('l') 2443 2444 let &efm = save_efm 2445 call delete('one.txt') 2446 call delete('two.txt') 2447endfunc 2448 2449" Tests for per buffer 'efm' setting 2450func Test_perbuf_efm() 2451 call writefile(["File1-10-Line10"], 'one.txt') 2452 call writefile(["File2#20#Line20"], 'two.txt') 2453 set efm=%f#%l#%m 2454 new | only 2455 new 2456 setlocal efm=%f-%l-%m 2457 cfile one.txt 2458 wincmd w 2459 caddfile two.txt 2460 2461 let l = getqflist() 2462 call assert_equal(10, l[0].lnum) 2463 call assert_equal('Line20', l[1].text) 2464 2465 set efm& 2466 new | only 2467 call delete('one.txt') 2468 call delete('two.txt') 2469endfunc 2470 2471" Open multiple help windows using ":lhelpgrep 2472" This test used to crash Vim 2473func Test_Multi_LL_Help() 2474 new | only 2475 lhelpgrep window 2476 lopen 2477 e# 2478 lhelpgrep buffer 2479 call assert_equal(3, winnr('$')) 2480 call assert_true(len(getloclist(1)) != 0) 2481 call assert_true(len(getloclist(2)) != 0) 2482 new | only 2483endfunc 2484 2485" Tests for adding new quickfix lists using setqflist() 2486func XaddQf_tests(cchar) 2487 call s:setup_commands(a:cchar) 2488 2489 " Create a new list using ' ' for action 2490 call g:Xsetlist([], 'f') 2491 call g:Xsetlist([], ' ', {'title' : 'Test1'}) 2492 let l = g:Xgetlist({'nr' : '$', 'all' : 1}) 2493 call assert_equal(1, l.nr) 2494 call assert_equal('Test1', l.title) 2495 2496 " Create a new list using ' ' for action and '$' for 'nr' 2497 call g:Xsetlist([], 'f') 2498 call g:Xsetlist([], ' ', {'title' : 'Test2', 'nr' : '$'}) 2499 let l = g:Xgetlist({'nr' : '$', 'all' : 1}) 2500 call assert_equal(1, l.nr) 2501 call assert_equal('Test2', l.title) 2502 2503 " Create a new list using 'a' for action 2504 call g:Xsetlist([], 'f') 2505 call g:Xsetlist([], 'a', {'title' : 'Test3'}) 2506 let l = g:Xgetlist({'nr' : '$', 'all' : 1}) 2507 call assert_equal(1, l.nr) 2508 call assert_equal('Test3', l.title) 2509 2510 " Create a new list using 'a' for action and '$' for 'nr' 2511 call g:Xsetlist([], 'f') 2512 call g:Xsetlist([], 'a', {'title' : 'Test3', 'nr' : '$'}) 2513 call g:Xsetlist([], 'a', {'title' : 'Test4'}) 2514 let l = g:Xgetlist({'nr' : '$', 'all' : 1}) 2515 call assert_equal(1, l.nr) 2516 call assert_equal('Test4', l.title) 2517 2518 " Adding a quickfix list should remove all the lists following the current 2519 " list. 2520 Xexpr "" | Xexpr "" | Xexpr "" 2521 silent! 10Xolder 2522 call g:Xsetlist([], ' ', {'title' : 'Test5'}) 2523 let l = g:Xgetlist({'nr' : '$', 'all' : 1}) 2524 call assert_equal(2, l.nr) 2525 call assert_equal('Test5', l.title) 2526 2527 " Add a quickfix list using '$' as the list number. 2528 let lastqf = g:Xgetlist({'nr':'$'}).nr 2529 silent! 99Xolder 2530 call g:Xsetlist([], ' ', {'nr' : '$', 'title' : 'Test6'}) 2531 let l = g:Xgetlist({'nr' : '$', 'all' : 1}) 2532 call assert_equal(lastqf + 1, l.nr) 2533 call assert_equal('Test6', l.title) 2534 2535 " Add a quickfix list using 'nr' set to one more than the quickfix 2536 " list size. 2537 let lastqf = g:Xgetlist({'nr':'$'}).nr 2538 silent! 99Xolder 2539 call g:Xsetlist([], ' ', {'nr' : lastqf + 1, 'title' : 'Test7'}) 2540 let l = g:Xgetlist({'nr' : '$', 'all' : 1}) 2541 call assert_equal(lastqf + 1, l.nr) 2542 call assert_equal('Test7', l.title) 2543 2544 " Add a quickfix list to a stack with 10 lists using 'nr' set to '$' 2545 exe repeat('Xexpr "" |', 9) . 'Xexpr ""' 2546 silent! 99Xolder 2547 call g:Xsetlist([], ' ', {'nr' : '$', 'title' : 'Test8'}) 2548 let l = g:Xgetlist({'nr' : '$', 'all' : 1}) 2549 call assert_equal(10, l.nr) 2550 call assert_equal('Test8', l.title) 2551 2552 " Add a quickfix list using 'nr' set to a value greater than 10 2553 call assert_equal(-1, g:Xsetlist([], ' ', {'nr' : 12, 'title' : 'Test9'})) 2554 2555 " Try adding a quickfix list with 'nr' set to a value greater than the 2556 " quickfix list size but less than 10. 2557 call g:Xsetlist([], 'f') 2558 Xexpr "" | Xexpr "" | Xexpr "" 2559 silent! 99Xolder 2560 call assert_equal(-1, g:Xsetlist([], ' ', {'nr' : 8, 'title' : 'Test10'})) 2561 2562 " Add a quickfix list using 'nr' set to a some string or list 2563 call assert_equal(-1, g:Xsetlist([], ' ', {'nr' : [1,2], 'title' : 'Test11'})) 2564endfunc 2565 2566func Test_add_qf() 2567 call XaddQf_tests('c') 2568 call XaddQf_tests('l') 2569endfunc 2570 2571" Test for getting the quickfix list items from some text without modifying 2572" the quickfix stack 2573func XgetListFromLines(cchar) 2574 call s:setup_commands(a:cchar) 2575 call g:Xsetlist([], 'f') 2576 2577 let l = g:Xgetlist({'lines' : ["File2:20:Line20", "File2:30:Line30"]}).items 2578 call assert_equal(2, len(l)) 2579 call assert_equal(30, l[1].lnum) 2580 2581 call assert_equal({}, g:Xgetlist({'lines' : 10})) 2582 call assert_equal({}, g:Xgetlist({'lines' : 'File1:10:Line10'})) 2583 call assert_equal([], g:Xgetlist({'lines' : []}).items) 2584 call assert_equal([], g:Xgetlist({'lines' : [10, 20]}).items) 2585 2586 " Parse text using a custom efm 2587 set efm& 2588 let l = g:Xgetlist({'lines':['File3#30#Line30'], 'efm' : '%f#%l#%m'}).items 2589 call assert_equal('Line30', l[0].text) 2590 let l = g:Xgetlist({'lines':['File3:30:Line30'], 'efm' : '%f-%l-%m'}).items 2591 call assert_equal('File3:30:Line30', l[0].text) 2592 let l = g:Xgetlist({'lines':['File3:30:Line30'], 'efm' : [1,2]}) 2593 call assert_equal({}, l) 2594 call assert_fails("call g:Xgetlist({'lines':['abc'], 'efm':'%2'})", 'E376:') 2595 call assert_fails("call g:Xgetlist({'lines':['abc'], 'efm':''})", 'E378:') 2596 2597 " Make sure that the quickfix stack is not modified 2598 call assert_equal(0, g:Xgetlist({'nr' : '$'}).nr) 2599endfunc 2600 2601func Test_get_list_from_lines() 2602 call XgetListFromLines('c') 2603 call XgetListFromLines('l') 2604endfunc 2605 2606" Tests for the quickfix list id 2607func Xqfid_tests(cchar) 2608 call s:setup_commands(a:cchar) 2609 2610 call g:Xsetlist([], 'f') 2611 call assert_equal({}, g:Xgetlist({'id':0})) 2612 Xexpr '' 2613 let start_id = g:Xgetlist({'id' : 0}).id 2614 Xexpr '' | Xexpr '' 2615 Xolder 2616 call assert_equal(start_id, g:Xgetlist({'id':0, 'nr':1}).id) 2617 call assert_equal(start_id + 1, g:Xgetlist({'id':0, 'nr':0}).id) 2618 call assert_equal(start_id + 2, g:Xgetlist({'id':0, 'nr':'$'}).id) 2619 call assert_equal({}, g:Xgetlist({'id':0, 'nr':99})) 2620 call assert_equal(2, g:Xgetlist({'id':start_id + 1, 'nr':0}).nr) 2621 call assert_equal({}, g:Xgetlist({'id':99, 'nr':0})) 2622 call assert_equal({}, g:Xgetlist({'id':"abc", 'nr':0})) 2623 2624 call g:Xsetlist([], 'a', {'id':start_id, 'context':[1,2]}) 2625 call assert_equal([1,2], g:Xgetlist({'nr':1, 'context':1}).context) 2626 call g:Xsetlist([], 'a', {'id':start_id+1, 'lines':['F1:10:L10']}) 2627 call assert_equal('L10', g:Xgetlist({'nr':2, 'items':1}).items[0].text) 2628 call assert_equal(-1, g:Xsetlist([], 'a', {'id':999, 'title':'Vim'})) 2629 call assert_equal(-1, g:Xsetlist([], 'a', {'id':'abc', 'title':'Vim'})) 2630 2631 let qfid = g:Xgetlist({'id':0, 'nr':0}) 2632 call g:Xsetlist([], 'f') 2633 call assert_equal({}, g:Xgetlist({'id':qfid, 'nr':0})) 2634endfunc 2635 2636func Test_qf_id() 2637 call Xqfid_tests('c') 2638 call Xqfid_tests('l') 2639endfunc 2640