1" Test using builtin functions in the Vim9 script language. 2 3source check.vim 4source vim9.vim 5 6" Test for passing too many or too few arguments to builtin functions 7func Test_internalfunc_arg_error() 8 let l =<< trim END 9 def! FArgErr(): float 10 return ceil(1.1, 2) 11 enddef 12 defcompile 13 END 14 call writefile(l, 'Xinvalidarg') 15 call assert_fails('so Xinvalidarg', 'E118:', '', 1, 'FArgErr') 16 let l =<< trim END 17 def! FArgErr(): float 18 return ceil() 19 enddef 20 defcompile 21 END 22 call writefile(l, 'Xinvalidarg') 23 call assert_fails('so Xinvalidarg', 'E119:', '', 1, 'FArgErr') 24 call delete('Xinvalidarg') 25endfunc 26 27" Test for builtin functions returning different types 28func Test_InternalFuncRetType() 29 let lines =<< trim END 30 def RetFloat(): float 31 return ceil(1.456) 32 enddef 33 34 def RetListAny(): list<any> 35 return items({k: 'v'}) 36 enddef 37 38 def RetListString(): list<string> 39 return split('a:b:c', ':') 40 enddef 41 42 def RetListDictAny(): list<dict<any>> 43 return getbufinfo() 44 enddef 45 46 def RetDictNumber(): dict<number> 47 return wordcount() 48 enddef 49 50 def RetDictString(): dict<string> 51 return environ() 52 enddef 53 END 54 call writefile(lines, 'Xscript') 55 source Xscript 56 57 call RetFloat()->assert_equal(2.0) 58 call RetListAny()->assert_equal([['k', 'v']]) 59 call RetListString()->assert_equal(['a', 'b', 'c']) 60 call RetListDictAny()->assert_notequal([]) 61 call RetDictNumber()->assert_notequal({}) 62 call RetDictString()->assert_notequal({}) 63 call delete('Xscript') 64endfunc 65 66def Test_abs() 67 assert_equal(0, abs(0)) 68 assert_equal(2, abs(-2)) 69 assert_equal(3, abs(3)) 70 CheckDefFailure(['abs("text")'], 'E1013: Argument 1: type mismatch, expected number but got string', 1) 71 if has('float') 72 assert_equal(0, abs(0)) 73 assert_equal(2.0, abs(-2.0)) 74 assert_equal(3.0, abs(3.0)) 75 endif 76enddef 77 78def Test_add_list() 79 var l: list<number> # defaults to empty list 80 add(l, 9) 81 assert_equal([9], l) 82 83 var lines =<< trim END 84 var l: list<number> 85 add(l, "x") 86 END 87 CheckDefFailure(lines, 'E1012:', 2) 88 89 lines =<< trim END 90 var l: list<number> = test_null_list() 91 add(l, 123) 92 END 93 CheckDefExecFailure(lines, 'E1130:', 2) 94enddef 95 96def Test_add_blob() 97 var b1: blob = 0z12 98 add(b1, 0x34) 99 assert_equal(0z1234, b1) 100 101 var b2: blob # defaults to empty blob 102 add(b2, 0x67) 103 assert_equal(0z67, b2) 104 105 var lines =<< trim END 106 var b: blob 107 add(b, "x") 108 END 109 CheckDefFailure(lines, 'E1012:', 2) 110 111 lines =<< trim END 112 var b: blob = test_null_blob() 113 add(b, 123) 114 END 115 CheckDefExecFailure(lines, 'E1131:', 2) 116enddef 117 118def Test_bufname() 119 split SomeFile 120 bufname('%')->assert_equal('SomeFile') 121 edit OtherFile 122 bufname('#')->assert_equal('SomeFile') 123 close 124enddef 125 126def Test_bufnr() 127 var buf = bufnr() 128 bufnr('%')->assert_equal(buf) 129 130 buf = bufnr('Xdummy', true) 131 buf->assert_notequal(-1) 132 exe 'bwipe! ' .. buf 133enddef 134 135def Test_bufwinid() 136 var origwin = win_getid() 137 below split SomeFile 138 var SomeFileID = win_getid() 139 below split OtherFile 140 below split SomeFile 141 bufwinid('SomeFile')->assert_equal(SomeFileID) 142 143 win_gotoid(origwin) 144 only 145 bwipe SomeFile 146 bwipe OtherFile 147enddef 148 149def Test_call_call() 150 var l = [3, 2, 1] 151 call('reverse', [l]) 152 l->assert_equal([1, 2, 3]) 153enddef 154 155def Test_char2nr() 156 char2nr('あ', true)->assert_equal(12354) 157enddef 158 159def Test_col() 160 new 161 setline(1, 'asdf') 162 col([1, '$'])->assert_equal(5) 163enddef 164 165def Test_copy_return_type() 166 var l = copy([1, 2, 3]) 167 var res = 0 168 for n in l 169 res += n 170 endfor 171 res->assert_equal(6) 172 173 var dl = deepcopy([1, 2, 3]) 174 res = 0 175 for n in dl 176 res += n 177 endfor 178 res->assert_equal(6) 179 180 dl = deepcopy([1, 2, 3], true) 181enddef 182 183def Test_count() 184 count('ABC ABC ABC', 'b', true)->assert_equal(3) 185 count('ABC ABC ABC', 'b', false)->assert_equal(0) 186enddef 187 188def Test_cursor() 189 new 190 setline(1, range(4)) 191 cursor(2, 1) 192 assert_equal(2, getcurpos()[1]) 193 cursor('$', 1) 194 assert_equal(4, getcurpos()[1]) 195 196 var lines =<< trim END 197 cursor('2', 1) 198 END 199 CheckDefExecAndScriptFailure(lines, 'E475:') 200enddef 201 202def Test_executable() 203 assert_false(executable("")) 204 assert_false(executable(test_null_string())) 205 206 CheckDefExecFailure(['echo executable(123)'], 'E928:') 207 CheckDefExecFailure(['echo executable(true)'], 'E928:') 208enddef 209 210def Test_exepath() 211 CheckDefExecFailure(['echo exepath(true)'], 'E928:') 212 CheckDefExecFailure(['echo exepath(v:null)'], 'E928:') 213 CheckDefExecFailure(['echo exepath("")'], 'E1142:') 214enddef 215 216def Test_expand() 217 split SomeFile 218 expand('%', true, true)->assert_equal(['SomeFile']) 219 close 220enddef 221 222def Test_extend_arg_types() 223 assert_equal([1, 2, 3], extend([1, 2], [3])) 224 assert_equal([3, 1, 2], extend([1, 2], [3], 0)) 225 assert_equal([1, 3, 2], extend([1, 2], [3], 1)) 226 assert_equal([1, 3, 2], extend([1, 2], [3], s:number_one)) 227 228 assert_equal({a: 1, b: 2, c: 3}, extend({a: 1, b: 2}, {c: 3})) 229 assert_equal({a: 1, b: 4}, extend({a: 1, b: 2}, {b: 4})) 230 assert_equal({a: 1, b: 2}, extend({a: 1, b: 2}, {b: 4}, 'keep')) 231 assert_equal({a: 1, b: 2}, extend({a: 1, b: 2}, {b: 4}, s:string_keep)) 232 233 var res: list<dict<any>> 234 extend(res, map([1, 2], {_, v -> {}})) 235 assert_equal([{}, {}], res) 236 237 CheckDefFailure(['extend([1, 2], 3)'], 'E1013: Argument 2: type mismatch, expected list<number> but got number') 238 CheckDefFailure(['extend([1, 2], ["x"])'], 'E1013: Argument 2: type mismatch, expected list<number> but got list<string>') 239 CheckDefFailure(['extend([1, 2], [3], "x")'], 'E1013: Argument 3: type mismatch, expected number but got string') 240 241 CheckDefFailure(['extend({a: 1}, 42)'], 'E1013: Argument 2: type mismatch, expected dict<number> but got number') 242 CheckDefFailure(['extend({a: 1}, {b: "x"})'], 'E1013: Argument 2: type mismatch, expected dict<number> but got dict<string>') 243 CheckDefFailure(['extend({a: 1}, {b: 2}, 1)'], 'E1013: Argument 3: type mismatch, expected string but got number') 244enddef 245 246def Test_extend_return_type() 247 var l = extend([1, 2], [3]) 248 var res = 0 249 for n in l 250 res += n 251 endfor 252 res->assert_equal(6) 253enddef 254 255 256def Wrong_dict_key_type(items: list<number>): list<number> 257 return filter(items, {_, val -> get({[val]: 1}, 'x')}) 258enddef 259 260def Test_map_function_arg() 261 var lines =<< trim END 262 def MapOne(i: number, v: string): string 263 return i .. ':' .. v 264 enddef 265 var l = ['a', 'b', 'c'] 266 map(l, MapOne) 267 assert_equal(['0:a', '1:b', '2:c'], l) 268 END 269 CheckDefAndScriptSuccess(lines) 270enddef 271 272def Test_filereadable() 273 assert_false(filereadable("")) 274 assert_false(filereadable(test_null_string())) 275 276 CheckDefExecFailure(['echo filereadable(123)'], 'E928:') 277 CheckDefExecFailure(['echo filereadable(true)'], 'E928:') 278enddef 279 280def Test_filewritable() 281 assert_false(filewritable("")) 282 assert_false(filewritable(test_null_string())) 283 284 CheckDefExecFailure(['echo filewritable(123)'], 'E928:') 285 CheckDefExecFailure(['echo filewritable(true)'], 'E928:') 286enddef 287 288def Test_finddir() 289 CheckDefExecFailure(['echo finddir(true)'], 'E928:') 290 CheckDefExecFailure(['echo finddir(v:null)'], 'E928:') 291 CheckDefExecFailure(['echo finddir("")'], 'E1142:') 292enddef 293 294def Test_findfile() 295 CheckDefExecFailure(['echo findfile(true)'], 'E928:') 296 CheckDefExecFailure(['echo findfile(v:null)'], 'E928:') 297 CheckDefExecFailure(['echo findfile("")'], 'E1142:') 298enddef 299 300def Test_fnamemodify() 301 CheckDefSuccess(['echo fnamemodify(test_null_string(), ":p")']) 302 CheckDefSuccess(['echo fnamemodify("", ":p")']) 303 CheckDefSuccess(['echo fnamemodify("file", test_null_string())']) 304 CheckDefSuccess(['echo fnamemodify("file", "")']) 305 306 CheckDefExecFailure(['echo fnamemodify(true, ":p")'], 'E928:') 307 CheckDefExecFailure(['echo fnamemodify(v:null, ":p")'], 'E928:') 308 CheckDefExecFailure(['echo fnamemodify("file", true)'], 'E928:') 309enddef 310 311def Test_filter_wrong_dict_key_type() 312 assert_fails('Wrong_dict_key_type([1, 2, 3])', 'E1012:') 313enddef 314 315def Test_filter_return_type() 316 var l = filter([1, 2, 3], {-> 1}) 317 var res = 0 318 for n in l 319 res += n 320 endfor 321 res->assert_equal(6) 322enddef 323 324 325def Test_garbagecollect() 326 garbagecollect(true) 327enddef 328 329def Test_getbufinfo() 330 var bufinfo = getbufinfo(bufnr()) 331 getbufinfo('%')->assert_equal(bufinfo) 332 333 edit Xtestfile1 334 hide edit Xtestfile2 335 hide enew 336 getbufinfo({bufloaded: true, buflisted: true, bufmodified: false}) 337 ->len()->assert_equal(3) 338 bwipe Xtestfile1 Xtestfile2 339enddef 340 341def Test_getbufline() 342 e SomeFile 343 var buf = bufnr() 344 e # 345 var lines = ['aaa', 'bbb', 'ccc'] 346 setbufline(buf, 1, lines) 347 getbufline('#', 1, '$')->assert_equal(lines) 348 getbufline(-1, '$', '$')->assert_equal([]) 349 getbufline(-1, 1, '$')->assert_equal([]) 350 351 bwipe! 352enddef 353 354def Test_getchangelist() 355 new 356 setline(1, 'some text') 357 var changelist = bufnr()->getchangelist() 358 getchangelist('%')->assert_equal(changelist) 359 bwipe! 360enddef 361 362def Test_getchar() 363 while getchar(0) 364 endwhile 365 getchar(true)->assert_equal(0) 366enddef 367 368def Test_getcompletion() 369 set wildignore=*.vim,*~ 370 var l = getcompletion('run', 'file', true) 371 l->assert_equal([]) 372 set wildignore& 373enddef 374 375def Test_getloclist_return_type() 376 var l = getloclist(1) 377 l->assert_equal([]) 378 379 var d = getloclist(1, {items: 0}) 380 d->assert_equal({items: []}) 381enddef 382 383def Test_getfperm() 384 assert_equal('', getfperm("")) 385 assert_equal('', getfperm(test_null_string())) 386 387 CheckDefExecFailure(['echo getfperm(true)'], 'E928:') 388 CheckDefExecFailure(['echo getfperm(v:null)'], 'E928:') 389enddef 390 391def Test_getfsize() 392 assert_equal(-1, getfsize("")) 393 assert_equal(-1, getfsize(test_null_string())) 394 395 CheckDefExecFailure(['echo getfsize(true)'], 'E928:') 396 CheckDefExecFailure(['echo getfsize(v:null)'], 'E928:') 397enddef 398 399def Test_getftime() 400 assert_equal(-1, getftime("")) 401 assert_equal(-1, getftime(test_null_string())) 402 403 CheckDefExecFailure(['echo getftime(true)'], 'E928:') 404 CheckDefExecFailure(['echo getftime(v:null)'], 'E928:') 405enddef 406 407def Test_getftype() 408 assert_equal('', getftype("")) 409 assert_equal('', getftype(test_null_string())) 410 411 CheckDefExecFailure(['echo getftype(true)'], 'E928:') 412 CheckDefExecFailure(['echo getftype(v:null)'], 'E928:') 413enddef 414 415def Test_getqflist_return_type() 416 var l = getqflist() 417 l->assert_equal([]) 418 419 var d = getqflist({items: 0}) 420 d->assert_equal({items: []}) 421enddef 422 423def Test_getreg() 424 var lines = ['aaa', 'bbb', 'ccc'] 425 setreg('a', lines) 426 getreg('a', true, true)->assert_equal(lines) 427enddef 428 429def Test_getreg_return_type() 430 var s1: string = getreg('"') 431 var s2: string = getreg('"', 1) 432 var s3: list<string> = getreg('"', 1, 1) 433enddef 434 435def Test_glob() 436 glob('runtest.vim', true, true, true)->assert_equal(['runtest.vim']) 437enddef 438 439def Test_globpath() 440 globpath('.', 'runtest.vim', true, true, true)->assert_equal(['./runtest.vim']) 441enddef 442 443def Test_has() 444 has('eval', true)->assert_equal(1) 445enddef 446 447def Test_hasmapto() 448 hasmapto('foobar', 'i', true)->assert_equal(0) 449 iabbrev foo foobar 450 hasmapto('foobar', 'i', true)->assert_equal(1) 451 iunabbrev foo 452enddef 453 454def Test_index() 455 index(['a', 'b', 'a', 'B'], 'b', 2, true)->assert_equal(3) 456enddef 457 458let s:number_one = 1 459let s:number_two = 2 460let s:string_keep = 'keep' 461 462def Test_insert() 463 var l = insert([2, 1], 3) 464 var res = 0 465 for n in l 466 res += n 467 endfor 468 res->assert_equal(6) 469 470 assert_equal([1, 2, 3], insert([2, 3], 1)) 471 assert_equal([1, 2, 3], insert([2, 3], s:number_one)) 472 assert_equal([1, 2, 3], insert([1, 2], 3, 2)) 473 assert_equal([1, 2, 3], insert([1, 2], 3, s:number_two)) 474 assert_equal(['a', 'b', 'c'], insert(['b', 'c'], 'a')) 475 assert_equal(0z1234, insert(0z34, 0x12)) 476 477 CheckDefFailure(['insert([2, 3], "a")'], 'E1013: Argument 2: type mismatch, expected number but got string', 1) 478 CheckDefFailure(['insert([2, 3], 1, "x")'], 'E1013: Argument 3: type mismatch, expected number but got string', 1) 479enddef 480 481def Test_keys_return_type() 482 const var: list<string> = {a: 1, b: 2}->keys() 483 var->assert_equal(['a', 'b']) 484enddef 485 486def Test_list2str_str2list_utf8() 487 var s = "\u3042\u3044" 488 var l = [0x3042, 0x3044] 489 str2list(s, true)->assert_equal(l) 490 list2str(l, true)->assert_equal(s) 491enddef 492 493def SID(): number 494 return expand('<SID>') 495 ->matchstr('<SNR>\zs\d\+\ze_$') 496 ->str2nr() 497enddef 498 499def Test_maparg() 500 var lnum = str2nr(expand('<sflnum>')) 501 map foo bar 502 maparg('foo', '', false, true)->assert_equal({ 503 lnum: lnum + 1, 504 script: 0, 505 mode: ' ', 506 silent: 0, 507 noremap: 0, 508 lhs: 'foo', 509 lhsraw: 'foo', 510 nowait: 0, 511 expr: 0, 512 sid: SID(), 513 rhs: 'bar', 514 buffer: 0}) 515 unmap foo 516enddef 517 518def Test_mapcheck() 519 iabbrev foo foobar 520 mapcheck('foo', 'i', true)->assert_equal('foobar') 521 iunabbrev foo 522enddef 523 524def Test_maparg_mapset() 525 nnoremap <F3> :echo "hit F3"<CR> 526 var mapsave = maparg('<F3>', 'n', false, true) 527 mapset('n', false, mapsave) 528 529 nunmap <F3> 530enddef 531 532def Test_nr2char() 533 nr2char(97, true)->assert_equal('a') 534enddef 535 536def Test_readdir() 537 eval expand('sautest')->readdir({e -> e[0] !=# '.'}) 538 eval expand('sautest')->readdirex({e -> e.name[0] !=# '.'}) 539enddef 540 541def Test_remove_return_type() 542 var l = remove({one: [1, 2], two: [3, 4]}, 'one') 543 var res = 0 544 for n in l 545 res += n 546 endfor 547 res->assert_equal(3) 548enddef 549 550def Test_reverse_return_type() 551 var l = reverse([1, 2, 3]) 552 var res = 0 553 for n in l 554 res += n 555 endfor 556 res->assert_equal(6) 557enddef 558 559def Test_search() 560 new 561 setline(1, ['foo', 'bar']) 562 var val = 0 563 # skip expr returns boolean 564 search('bar', 'W', 0, 0, {-> val == 1})->assert_equal(2) 565 :1 566 search('bar', 'W', 0, 0, {-> val == 0})->assert_equal(0) 567 # skip expr returns number, only 0 and 1 are accepted 568 :1 569 search('bar', 'W', 0, 0, {-> 0})->assert_equal(2) 570 :1 571 search('bar', 'W', 0, 0, {-> 1})->assert_equal(0) 572 assert_fails("search('bar', '', 0, 0, {-> -1})", 'E1023:') 573 assert_fails("search('bar', '', 0, 0, {-> -1})", 'E1023:') 574enddef 575 576def Test_searchcount() 577 new 578 setline(1, "foo bar") 579 :/foo 580 searchcount({recompute: true}) 581 ->assert_equal({ 582 exact_match: 1, 583 current: 1, 584 total: 1, 585 maxcount: 99, 586 incomplete: 0}) 587 bwipe! 588enddef 589 590def Test_searchdecl() 591 searchdecl('blah', true, true)->assert_equal(1) 592enddef 593 594def Test_setbufvar() 595 setbufvar(bufnr('%'), '&syntax', 'vim') 596 &syntax->assert_equal('vim') 597 setbufvar(bufnr('%'), '&ts', 16) 598 &ts->assert_equal(16) 599 settabwinvar(1, 1, '&syntax', 'vam') 600 &syntax->assert_equal('vam') 601 settabwinvar(1, 1, '&ts', 15) 602 &ts->assert_equal(15) 603 setlocal ts=8 604 605 setbufvar('%', 'myvar', 123) 606 getbufvar('%', 'myvar')->assert_equal(123) 607enddef 608 609def Test_setloclist() 610 var items = [{filename: '/tmp/file', lnum: 1, valid: true}] 611 var what = {items: items} 612 setqflist([], ' ', what) 613 setloclist(0, [], ' ', what) 614enddef 615 616def Test_setreg() 617 setreg('a', ['aaa', 'bbb', 'ccc']) 618 var reginfo = getreginfo('a') 619 setreg('a', reginfo) 620 getreginfo('a')->assert_equal(reginfo) 621enddef 622 623def Test_spellsuggest() 624 if !has('spell') 625 MissingFeature 'spell' 626 else 627 spellsuggest('marrch', 1, true)->assert_equal(['March']) 628 endif 629enddef 630 631def Test_sort_return_type() 632 var res: list<number> 633 res = [1, 2, 3]->sort() 634enddef 635 636def Test_sort_argument() 637 var lines =<< trim END 638 var res = ['b', 'a', 'c']->sort('i') 639 res->assert_equal(['a', 'b', 'c']) 640 641 def Compare(a: number, b: number): number 642 return a - b 643 enddef 644 var l = [3, 6, 7, 1, 8, 2, 4, 5] 645 sort(l, Compare) 646 assert_equal([1, 2, 3, 4, 5, 6, 7, 8], l) 647 END 648 CheckDefAndScriptSuccess(lines) 649enddef 650 651def Test_split() 652 split(' aa bb ', '\W\+', true)->assert_equal(['', 'aa', 'bb', '']) 653enddef 654 655def Test_str2nr() 656 str2nr("1'000'000", 10, true)->assert_equal(1000000) 657enddef 658 659def Test_strchars() 660 strchars("A\u20dd", true)->assert_equal(1) 661enddef 662 663def Test_submatch() 664 var pat = 'A\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)' 665 var Rep = {-> range(10)->map({_, v -> submatch(v, true)})->string()} 666 var actual = substitute('A123456789', pat, Rep, '') 667 var expected = "[['A123456789'], ['1'], ['2'], ['3'], ['4'], ['5'], ['6'], ['7'], ['8'], ['9']]" 668 actual->assert_equal(expected) 669enddef 670 671def Test_synID() 672 new 673 setline(1, "text") 674 synID(1, 1, true)->assert_equal(0) 675 bwipe! 676enddef 677 678def Test_term_gettty() 679 if !has('terminal') 680 MissingFeature 'terminal' 681 else 682 var buf = Run_shell_in_terminal({}) 683 term_gettty(buf, true)->assert_notequal('') 684 StopShellInTerminal(buf) 685 endif 686enddef 687 688def Test_term_start() 689 if !has('terminal') 690 MissingFeature 'terminal' 691 else 692 botright new 693 var winnr = winnr() 694 term_start(&shell, {curwin: true}) 695 winnr()->assert_equal(winnr) 696 bwipe! 697 endif 698enddef 699 700def Test_timer_paused() 701 var id = timer_start(50, {-> 0}) 702 timer_pause(id, true) 703 var info = timer_info(id) 704 info[0]['paused']->assert_equal(1) 705 timer_stop(id) 706enddef 707 708def Test_win_splitmove() 709 split 710 win_splitmove(1, 2, {vertical: true, rightbelow: true}) 711 close 712enddef 713 714 715" vim: ts=8 sw=2 sts=2 expandtab tw=80 fdm=marker 716