1" Test Vim9 assignments 2 3source check.vim 4source vim9.vim 5 6let s:appendToMe = 'xxx' 7let s:addToMe = 111 8let g:existing = 'yes' 9let g:inc_counter = 1 10let $SOME_ENV_VAR = 'some' 11let g:alist = [7] 12let g:astring = 'text' 13 14def Test_assignment_bool() 15 var bool1: bool = true 16 assert_equal(v:true, bool1) 17 var bool2: bool = false 18 assert_equal(v:false, bool2) 19 20 var bool3: bool = 0 21 assert_equal(false, bool3) 22 var bool4: bool = 1 23 assert_equal(true, bool4) 24 25 var bool5: bool = 1 && true 26 assert_equal(true, bool5) 27 var bool6: bool = 0 && 1 28 assert_equal(false, bool6) 29 var bool7: bool = 0 || 1 && true 30 assert_equal(true, bool7) 31 32 var lines =<< trim END 33 vim9script 34 def GetFlag(): bool 35 var flag: bool = 1 36 return flag 37 enddef 38 var flag: bool = GetFlag() 39 assert_equal(true, flag) 40 flag = 0 41 assert_equal(false, flag) 42 flag = 1 43 assert_equal(true, flag) 44 flag = 1 || true 45 assert_equal(true, flag) 46 flag = 1 && false 47 assert_equal(false, flag) 48 49 var cp: bool = &cp 50 var fen: bool = &l:fen 51 END 52 CheckScriptSuccess(lines) 53 CheckDefAndScriptFailure(['var x: bool = 2'], 'E1012:') 54 CheckDefAndScriptFailure(['var x: bool = -1'], 'E1012:') 55 CheckDefAndScriptFailure(['var x: bool = [1]'], 'E1012:') 56 CheckDefAndScriptFailure(['var x: bool = {}'], 'E1012:') 57 CheckDefAndScriptFailure(['var x: bool = "x"'], 'E1012:') 58 59 CheckDefAndScriptFailure(['var x: bool = "x"', '', 'eval 0'], 'E1012:', 1) 60enddef 61 62def Test_syntax() 63 var name = 234 64 var other: list<string> = ['asdf'] 65enddef 66 67def Test_assignment() 68 CheckDefFailure(['var x:string'], 'E1069:') 69 CheckDefFailure(['var x:string = "x"'], 'E1069:') 70 CheckDefFailure(['var a:string = "x"'], 'E1069:') 71 CheckDefFailure(['var lambda = () => "lambda"'], 'E704:') 72 CheckScriptFailure(['var x = "x"'], 'E1124:') 73 74 var nr: number = 1234 75 CheckDefFailure(['var nr: number = "asdf"'], 'E1012:') 76 77 var a: number = 6 #comment 78 assert_equal(6, a) 79 80 if has('channel') 81 var chan1: channel 82 assert_equal('fail', ch_status(chan1)) 83 84 var job1: job 85 assert_equal('fail', job_status(job1)) 86 87 # calling job_start() is in test_vim9_fails.vim, it causes leak reports 88 endif 89 if has('float') 90 var float1: float = 3.4 91 endif 92 var Funky1: func 93 var Funky2: func = function('len') 94 var Party2: func = funcref('g:Test_syntax') 95 96 g:newvar = 'new' #comment 97 assert_equal('new', g:newvar) 98 99 assert_equal('yes', g:existing) 100 g:existing = 'no' 101 assert_equal('no', g:existing) 102 103 v:char = 'abc' 104 assert_equal('abc', v:char) 105 106 $ENVVAR = 'foobar' 107 assert_equal('foobar', $ENVVAR) 108 $ENVVAR = '' 109 110 var lines =<< trim END 111 vim9script 112 $ENVVAR = 'barfoo' 113 assert_equal('barfoo', $ENVVAR) 114 $ENVVAR = '' 115 END 116 CheckScriptSuccess(lines) 117 118 s:appendToMe ..= 'yyy' 119 assert_equal('xxxyyy', s:appendToMe) 120 s:addToMe += 222 121 assert_equal(333, s:addToMe) 122 s:newVar = 'new' 123 assert_equal('new', s:newVar) 124 125 set ts=7 126 var ts: number = &ts 127 assert_equal(7, ts) 128 &ts += 1 129 assert_equal(8, &ts) 130 &ts -= 3 131 assert_equal(5, &ts) 132 &ts *= 2 133 assert_equal(10, &ts) 134 &ts /= 3 135 assert_equal(3, &ts) 136 set ts=10 137 &ts %= 4 138 assert_equal(2, &ts) 139 140 if has('float') 141 var f100: float = 100.0 142 f100 /= 5 143 assert_equal(20.0, f100) 144 145 var f200: float = 200.0 146 f200 /= 5.0 147 assert_equal(40.0, f200) 148 149 CheckDefFailure(['var nr: number = 200', 'nr /= 5.0'], 'E1012:') 150 endif 151 152 lines =<< trim END 153 &ts = 6 154 &ts += 3 155 assert_equal(9, &ts) 156 157 &l:ts = 6 158 assert_equal(6, &ts) 159 &l:ts += 2 160 assert_equal(8, &ts) 161 162 &g:ts = 6 163 assert_equal(6, &g:ts) 164 &g:ts += 2 165 assert_equal(8, &g:ts) 166 167 &number = true 168 assert_equal(true, &number) 169 &number = 0 170 assert_equal(false, &number) 171 &number = 1 172 assert_equal(true, &number) 173 &number = false 174 assert_equal(false, &number) 175 END 176 CheckDefAndScriptSuccess(lines) 177 178 CheckDefFailure(['¬ex += 3'], 'E113:') 179 CheckDefFailure(['&ts ..= "xxx"'], 'E1019:') 180 CheckDefFailure(['&ts = [7]'], 'E1012:') 181 CheckDefExecFailure(['&ts = g:alist'], 'E1012: Type mismatch; expected number but got list<number>') 182 CheckDefFailure(['&ts = "xx"'], 'E1012:') 183 CheckDefExecFailure(['&ts = g:astring'], 'E1012: Type mismatch; expected number but got string') 184 CheckDefFailure(['&path += 3'], 'E1012:') 185 CheckDefExecFailure(['&bs = "asdf"'], 'E474:') 186 # test freeing ISN_STOREOPT 187 CheckDefFailure(['&ts = 3', 'var asdf'], 'E1022:') 188 &ts = 8 189 190 lines =<< trim END 191 var save_TI = &t_TI 192 &t_TI = '' 193 assert_equal('', &t_TI) 194 &t_TI = 'xxx' 195 assert_equal('xxx', &t_TI) 196 &t_TI = save_TI 197 END 198 CheckDefAndScriptSuccess(lines) 199 200 CheckDefFailure(['&t_TI = 123'], 'E1012:') 201 CheckScriptFailure(['vim9script', '&t_TI = 123'], 'E928:') 202 203 CheckDefFailure(['var s:var = 123'], 'E1101:') 204 CheckDefFailure(['var s:var: number'], 'E1101:') 205 206 lines =<< trim END 207 vim9script 208 def SomeFunc() 209 s:var = 123 210 enddef 211 defcompile 212 END 213 CheckScriptFailure(lines, 'E1089:') 214 215 g:inc_counter += 1 216 assert_equal(2, g:inc_counter) 217 218 $SOME_ENV_VAR ..= 'more' 219 assert_equal('somemore', $SOME_ENV_VAR) 220 CheckDefFailure(['$SOME_ENV_VAR += "more"'], 'E1051:') 221 CheckDefFailure(['$SOME_ENV_VAR += 123'], 'E1012:') 222 223 lines =<< trim END 224 @c = 'areg' 225 @c ..= 'add' 226 assert_equal('aregadd', @c) 227 END 228 CheckDefAndScriptSuccess(lines) 229 230 CheckDefFailure(['@a += "more"'], 'E1051:') 231 CheckDefFailure(['@a += 123'], 'E1012:') 232 233 v:errmsg = 'none' 234 v:errmsg ..= 'again' 235 assert_equal('noneagain', v:errmsg) 236 CheckDefFailure(['v:errmsg += "more"'], 'E1051:') 237 CheckDefFailure(['v:errmsg += 123'], 'E1012:') 238 239 var text =<< trim END 240 some text 241 END 242enddef 243 244def Test_assign_unpack() 245 var lines =<< trim END 246 var v1: number 247 var v2: number 248 [v1, v2] = [1, 2] 249 assert_equal(1, v1) 250 assert_equal(2, v2) 251 END 252 CheckDefAndScriptSuccess(lines) 253 254 lines =<< trim END 255 var v1: number 256 var v2: number 257 [v1, v2] = 258 END 259 CheckDefFailure(lines, 'E1097:', 5) 260 261 lines =<< trim END 262 var v1: number 263 var v2: number 264 [v1, v2] = xxx 265 END 266 CheckDefFailure(lines, 'E1001:', 3) 267 268 lines =<< trim END 269 var v1: number 270 var v2: number 271 [v1, v2] = popup_clear() 272 END 273 CheckDefFailure(lines, 'E1031:', 3) 274 275 lines =<< trim END 276 [v1, v2] = [1, 2] 277 END 278 CheckDefFailure(lines, 'E1089', 1) 279 CheckScriptFailure(['vim9script'] + lines, 'E1089', 2) 280 281 lines =<< trim END 282 var v1: number 283 var v2: number 284 [v1, v2] = '' 285 END 286 CheckDefFailure(lines, 'E1012: Type mismatch; expected list<any> but got string', 3) 287enddef 288 289def Test_assign_linebreak() 290 var nr: number 291 nr = 292 123 293 assert_equal(123, nr) 294 295 var n2: number 296 [nr, n2] = 297 [12, 34] 298 assert_equal(12, nr) 299 assert_equal(34, n2) 300 301 CheckDefFailure(["var x = #"], 'E1097:', 3) 302enddef 303 304def Test_assign_index() 305 # list of list 306 var l1: list<number> 307 l1[0] = 123 308 assert_equal([123], l1) 309 310 var l2: list<list<number>> 311 l2[0] = [] 312 l2[0][0] = 123 313 assert_equal([[123]], l2) 314 315 var l3: list<list<list<number>>> 316 l3[0] = [] 317 l3[0][0] = [] 318 l3[0][0][0] = 123 319 assert_equal([[[123]]], l3) 320 321 var lines =<< trim END 322 var l3: list<list<number>> 323 l3[0] = [] 324 l3[0][0] = [] 325 END 326 CheckDefFailure(lines, 'E1012: Type mismatch; expected number but got list<unknown>', 3) 327 328 # dict of dict 329 var d1: dict<number> 330 d1.one = 1 331 assert_equal({one: 1}, d1) 332 333 var d2: dict<dict<number>> 334 d2.one = {} 335 d2.one.two = 123 336 assert_equal({one: {two: 123}}, d2) 337 338 var d3: dict<dict<dict<number>>> 339 d3.one = {} 340 d3.one.two = {} 341 d3.one.two.three = 123 342 assert_equal({one: {two: {three: 123}}}, d3) 343 344 lines =<< trim END 345 var d3: dict<dict<number>> 346 d3.one = {} 347 d3.one.two = {} 348 END 349 CheckDefFailure(lines, 'E1012: Type mismatch; expected number but got dict<unknown>', 3) 350 351 lines =<< trim END 352 var lines: list<string> 353 lines['a'] = 'asdf' 354 END 355 CheckDefFailure(lines, 'E1012:', 2) 356 357 lines =<< trim END 358 var lines: string 359 lines[9] = 'asdf' 360 END 361 CheckDefFailure(lines, 'E1141:', 2) 362 363 # list of dict 364 var ld: list<dict<number>> 365 ld[0] = {} 366 ld[0].one = 123 367 assert_equal([{one: 123}], ld) 368 369 lines =<< trim END 370 var ld: list<dict<number>> 371 ld[0] = [] 372 END 373 CheckDefFailure(lines, 'E1012: Type mismatch; expected dict<number> but got list<unknown>', 2) 374 375 # dict of list 376 var dl: dict<list<number>> 377 dl.one = [] 378 dl.one[0] = 123 379 assert_equal({one: [123]}, dl) 380 381 lines =<< trim END 382 var dl: dict<list<number>> 383 dl.one = {} 384 END 385 CheckDefFailure(lines, 'E1012: Type mismatch; expected list<number> but got dict<unknown>', 2) 386enddef 387 388def Test_extend_list() 389 var lines =<< trim END 390 vim9script 391 var l: list<number> 392 l += [123] 393 assert_equal([123], l) 394 END 395 CheckScriptSuccess(lines) 396 397 lines =<< trim END 398 vim9script 399 var list: list<string> 400 extend(list, ['x']) 401 assert_equal(['x'], list) 402 END 403 CheckScriptSuccess(lines) 404 405 # appending to NULL list from a function 406 lines =<< trim END 407 vim9script 408 var list: list<string> 409 def Func() 410 list += ['a', 'b'] 411 enddef 412 Func() 413 assert_equal(['a', 'b'], list) 414 END 415 CheckScriptSuccess(lines) 416 lines =<< trim END 417 vim9script 418 var list: list<string> 419 def Func() 420 extend(list, ['x', 'b']) 421 enddef 422 Func() 423 assert_equal(['x', 'b'], list) 424 END 425 CheckScriptSuccess(lines) 426 427 lines =<< trim END 428 vim9script 429 var l: list<string> = test_null_list() 430 extend(l, ['x']) 431 assert_equal(['x'], l) 432 END 433 CheckScriptSuccess(lines) 434 435 lines =<< trim END 436 vim9script 437 extend(test_null_list(), ['x']) 438 END 439 CheckScriptFailure(lines, 'E1134:', 2) 440enddef 441 442def Test_extend_dict() 443 var lines =<< trim END 444 vim9script 445 var d: dict<number> 446 extend(d, {a: 1}) 447 assert_equal({a: 1}, d) 448 449 var d2: dict<number> 450 d2['one'] = 1 451 assert_equal({one: 1}, d2) 452 END 453 CheckScriptSuccess(lines) 454 455 lines =<< trim END 456 vim9script 457 var d: dict<string> = test_null_dict() 458 extend(d, {a: 'x'}) 459 assert_equal({a: 'x'}, d) 460 END 461 CheckScriptSuccess(lines) 462 463 lines =<< trim END 464 vim9script 465 extend(test_null_dict(), {a: 'x'}) 466 END 467 CheckScriptFailure(lines, 'E1133:', 2) 468enddef 469 470def Test_single_letter_vars() 471 # single letter variables 472 var a: number = 123 473 a = 123 474 assert_equal(123, a) 475 var b: number 476 b = 123 477 assert_equal(123, b) 478 var g: number 479 g = 123 480 assert_equal(123, g) 481 var s: number 482 s = 123 483 assert_equal(123, s) 484 var t: number 485 t = 123 486 assert_equal(123, t) 487 var v: number 488 v = 123 489 assert_equal(123, v) 490 var w: number 491 w = 123 492 assert_equal(123, w) 493enddef 494 495def Test_vim9_single_char_vars() 496 var lines =<< trim END 497 vim9script 498 499 # single character variable declarations work 500 var a: string 501 var b: number 502 var l: list<any> 503 var s: string 504 var t: number 505 var v: number 506 var w: number 507 508 # script-local variables can be used without s: prefix 509 a = 'script-a' 510 b = 111 511 l = [1, 2, 3] 512 s = 'script-s' 513 t = 222 514 v = 333 515 w = 444 516 517 assert_equal('script-a', a) 518 assert_equal(111, b) 519 assert_equal([1, 2, 3], l) 520 assert_equal('script-s', s) 521 assert_equal(222, t) 522 assert_equal(333, v) 523 assert_equal(444, w) 524 END 525 writefile(lines, 'Xsinglechar') 526 source Xsinglechar 527 delete('Xsinglechar') 528enddef 529 530def Test_assignment_list() 531 var list1: list<bool> = [false, true, false] 532 var list2: list<number> = [1, 2, 3] 533 var list3: list<string> = ['sdf', 'asdf'] 534 var list4: list<any> = ['yes', true, 1234] 535 var list5: list<blob> = [0z01, 0z02] 536 537 var listS: list<string> = [] 538 var listN: list<number> = [] 539 540 assert_equal([1, 2, 3], list2) 541 list2[-1] = 99 542 assert_equal([1, 2, 99], list2) 543 list2[-2] = 88 544 assert_equal([1, 88, 99], list2) 545 list2[-3] = 77 546 assert_equal([77, 88, 99], list2) 547 list2 += [100] 548 assert_equal([77, 88, 99, 100], list2) 549 550 list3 += ['end'] 551 assert_equal(['sdf', 'asdf', 'end'], list3) 552 553 CheckDefExecFailure(['var ll = [1, 2, 3]', 'll[-4] = 6'], 'E684:') 554 CheckDefExecFailure(['var [v1, v2] = [1, 2]'], 'E1092:') 555 556 # type becomes list<any> 557 var somelist = rand() > 0 ? [1, 2, 3] : ['a', 'b', 'c'] 558 559 var lines =<< trim END 560 var d = {dd: test_null_list()} 561 d.dd[0] = 0 562 END 563 CheckDefExecFailure(lines, 'E1147:', 2) 564enddef 565 566def Test_assignment_list_any_index() 567 var l: list<number> = [1, 2] 568 for [x, y, _] 569 in [[0, 1, ''], [1, 3, '']] 570 l[x] = l[x] + y 571 endfor 572 assert_equal([2, 5], l) 573enddef 574 575def Test_assignment_list_vim9script() 576 var lines =<< trim END 577 vim9script 578 var v1: number 579 var v2: number 580 var v3: number 581 [v1, v2, v3] = [1, 2, 3] 582 assert_equal([1, 2, 3], [v1, v2, v3]) 583 END 584 CheckScriptSuccess(lines) 585enddef 586 587def Test_assignment_dict() 588 var dict1: dict<bool> = {one: false, two: true} 589 var dict2: dict<number> = {one: 1, two: 2} 590 var dict3: dict<string> = {key: 'value'} 591 var dict4: dict<any> = {one: 1, two: '2'} 592 var dict5: dict<blob> = {one: 0z01, two: 0z02} 593 594 # overwrite 595 dict3['key'] = 'another' 596 assert_equal(dict3, {key: 'another'}) 597 dict3.key = 'yet another' 598 assert_equal(dict3, {key: 'yet another'}) 599 600 # member "any" can also be a dict and assigned to 601 var anydict: dict<any> = {nest: {}, nr: 0} 602 anydict.nest['this'] = 123 603 anydict.nest.that = 456 604 assert_equal({nest: {this: 123, that: 456}, nr: 0}, anydict) 605 606 var lines =<< trim END 607 var dd = {} 608 dd.two = 2 609 assert_equal({two: 2}, dd) 610 END 611 CheckDefAndScriptSuccess(lines) 612 613 lines =<< trim END 614 var d = {dd: {}} 615 d.dd[0] = 2 616 d.dd['x'] = 3 617 d.dd.y = 4 618 assert_equal({dd: {0: 2, x: 3, y: 4}}, d) 619 END 620 CheckDefAndScriptSuccess(lines) 621 622 lines =<< trim END 623 var dd = {one: 1} 624 dd.one) = 2 625 END 626 CheckDefFailure(lines, 'E488:', 2) 627 628 lines =<< trim END 629 var dd = {one: 1} 630 var dd.one = 2 631 END 632 CheckDefAndScriptFailure(lines, 'E1017:', 2) 633 634 # empty key can be used 635 var dd = {} 636 dd[""] = 6 637 assert_equal({['']: 6}, dd) 638 639 # type becomes dict<any> 640 var somedict = rand() > 0 ? {a: 1, b: 2} : {a: 'a', b: 'b'} 641 642 # assignment to script-local dict 643 lines =<< trim END 644 vim9script 645 var test: dict<any> = {} 646 def FillDict(): dict<any> 647 test['a'] = 43 648 return test 649 enddef 650 assert_equal({a: 43}, FillDict()) 651 END 652 CheckScriptSuccess(lines) 653 654 lines =<< trim END 655 vim9script 656 var test: dict<any> 657 def FillDict(): dict<any> 658 test['a'] = 43 659 return test 660 enddef 661 FillDict() 662 assert_equal({a: 43}, test) 663 END 664 CheckScriptSuccess(lines) 665 666 # assignment to global dict 667 lines =<< trim END 668 vim9script 669 g:test = {} 670 def FillDict(): dict<any> 671 g:test['a'] = 43 672 return g:test 673 enddef 674 assert_equal({a: 43}, FillDict()) 675 END 676 CheckScriptSuccess(lines) 677 678 # assignment to buffer dict 679 lines =<< trim END 680 vim9script 681 b:test = {} 682 def FillDict(): dict<any> 683 b:test['a'] = 43 684 return b:test 685 enddef 686 assert_equal({a: 43}, FillDict()) 687 END 688 CheckScriptSuccess(lines) 689 690 lines =<< trim END 691 var d = {dd: test_null_dict()} 692 d.dd[0] = 0 693 END 694 CheckDefExecFailure(lines, 'E1103:', 2) 695 696 lines =<< trim END 697 var d = {dd: 'string'} 698 d.dd[0] = 0 699 END 700 CheckDefExecFailure(lines, 'E1148:', 2) 701enddef 702 703def Test_assignment_local() 704 # Test in a separated file in order not to the current buffer/window/tab is 705 # changed. 706 var script_lines: list<string> =<< trim END 707 let b:existing = 'yes' 708 let w:existing = 'yes' 709 let t:existing = 'yes' 710 711 def Test_assignment_local_internal() 712 b:newvar = 'new' 713 assert_equal('new', b:newvar) 714 assert_equal('yes', b:existing) 715 b:existing = 'no' 716 assert_equal('no', b:existing) 717 b:existing ..= 'NO' 718 assert_equal('noNO', b:existing) 719 720 w:newvar = 'new' 721 assert_equal('new', w:newvar) 722 assert_equal('yes', w:existing) 723 w:existing = 'no' 724 assert_equal('no', w:existing) 725 w:existing ..= 'NO' 726 assert_equal('noNO', w:existing) 727 728 t:newvar = 'new' 729 assert_equal('new', t:newvar) 730 assert_equal('yes', t:existing) 731 t:existing = 'no' 732 assert_equal('no', t:existing) 733 t:existing ..= 'NO' 734 assert_equal('noNO', t:existing) 735 enddef 736 call Test_assignment_local_internal() 737 END 738 CheckScriptSuccess(script_lines) 739enddef 740 741def Test_assignment_default() 742 # Test default values. 743 var thebool: bool 744 assert_equal(v:false, thebool) 745 746 var thenumber: number 747 assert_equal(0, thenumber) 748 749 if has('float') 750 var thefloat: float 751 assert_equal(0.0, thefloat) 752 endif 753 754 var thestring: string 755 assert_equal('', thestring) 756 757 var theblob: blob 758 assert_equal(0z, theblob) 759 760 var Thefunc: func 761 assert_equal(test_null_function(), Thefunc) 762 763 var thelist: list<any> 764 assert_equal([], thelist) 765 766 var thedict: dict<any> 767 assert_equal({}, thedict) 768 769 if has('channel') 770 var thejob: job 771 assert_equal(test_null_job(), thejob) 772 773 var thechannel: channel 774 assert_equal(test_null_channel(), thechannel) 775 776 if has('unix') && executable('cat') 777 # check with non-null job and channel, types must match 778 thejob = job_start("cat ", {}) 779 thechannel = job_getchannel(thejob) 780 job_stop(thejob, 'kill') 781 endif 782 endif 783 784 var nr = 1234 | nr = 5678 785 assert_equal(5678, nr) 786enddef 787 788let scriptvar = 'init' 789 790def Test_assignment_var_list() 791 var lines =<< trim END 792 var v1: string 793 var v2: string 794 var vrem: list<string> 795 [v1] = ['aaa'] 796 assert_equal('aaa', v1) 797 798 [v1, v2] = ['one', 'two'] 799 assert_equal('one', v1) 800 assert_equal('two', v2) 801 802 [v1, v2; vrem] = ['one', 'two'] 803 assert_equal('one', v1) 804 assert_equal('two', v2) 805 assert_equal([], vrem) 806 807 [v1, v2; vrem] = ['one', 'two', 'three'] 808 assert_equal('one', v1) 809 assert_equal('two', v2) 810 assert_equal(['three'], vrem) 811 812 [&ts, &sw] = [3, 4] 813 assert_equal(3, &ts) 814 assert_equal(4, &sw) 815 set ts=8 sw=4 816 817 [@a, @z] = ['aa', 'zz'] 818 assert_equal('aa', @a) 819 assert_equal('zz', @z) 820 821 [$SOME_VAR, $OTHER_VAR] = ['some', 'other'] 822 assert_equal('some', $SOME_VAR) 823 assert_equal('other', $OTHER_VAR) 824 825 [g:globalvar, b:bufvar, w:winvar, t:tabvar, v:errmsg] = 826 ['global', 'buf', 'win', 'tab', 'error'] 827 assert_equal('global', g:globalvar) 828 assert_equal('buf', b:bufvar) 829 assert_equal('win', w:winvar) 830 assert_equal('tab', t:tabvar) 831 assert_equal('error', v:errmsg) 832 unlet g:globalvar 833 END 834 CheckDefAndScriptSuccess(lines) 835 836 [g:globalvar, s:scriptvar, b:bufvar] = ['global', 'script', 'buf'] 837 assert_equal('global', g:globalvar) 838 assert_equal('script', s:scriptvar) 839 assert_equal('buf', b:bufvar) 840 841 lines =<< trim END 842 vim9script 843 var s:scriptvar = 'init' 844 [g:globalvar, s:scriptvar, w:winvar] = ['global', 'script', 'win'] 845 assert_equal('global', g:globalvar) 846 assert_equal('script', s:scriptvar) 847 assert_equal('win', w:winvar) 848 END 849 CheckScriptSuccess(lines) 850enddef 851 852def Test_assignment_vim9script() 853 var lines =<< trim END 854 vim9script 855 def Func(): list<number> 856 return [1, 2] 857 enddef 858 var name1: number 859 var name2: number 860 [name1, name2] = 861 Func() 862 assert_equal(1, name1) 863 assert_equal(2, name2) 864 var ll = 865 Func() 866 assert_equal([1, 2], ll) 867 868 @/ = 'text' 869 assert_equal('text', @/) 870 @0 = 'zero' 871 assert_equal('zero', @0) 872 @1 = 'one' 873 assert_equal('one', @1) 874 @9 = 'nine' 875 assert_equal('nine', @9) 876 @- = 'minus' 877 assert_equal('minus', @-) 878 if has('clipboard_working') 879 @* = 'star' 880 assert_equal('star', @*) 881 @+ = 'plus' 882 assert_equal('plus', @+) 883 endif 884 885 var a: number = 123 886 assert_equal(123, a) 887 var s: string = 'yes' 888 assert_equal('yes', s) 889 var b: number = 42 890 assert_equal(42, b) 891 var w: number = 43 892 assert_equal(43, w) 893 var t: number = 44 894 assert_equal(44, t) 895 896 var to_var = 0 897 to_var = 3 898 assert_equal(3, to_var) 899 END 900 CheckScriptSuccess(lines) 901 902 lines =<< trim END 903 vim9script 904 var n: number 905 def Func() 906 n = 'string' 907 enddef 908 defcompile 909 END 910 CheckScriptFailure(lines, 'E1012: Type mismatch; expected number but got string') 911enddef 912 913def Mess(): string 914 v:foldstart = 123 915 return 'xxx' 916enddef 917 918def Test_assignment_failure() 919 CheckDefFailure(['var name=234'], 'E1004:') 920 CheckDefFailure(['var name =234'], 'E1004:') 921 CheckDefFailure(['var name= 234'], 'E1004:') 922 923 CheckScriptFailure(['vim9script', 'var name=234'], 'E1004:') 924 CheckScriptFailure(['vim9script', 'var name=234'], "before and after '='") 925 CheckScriptFailure(['vim9script', 'var name =234'], 'E1004:') 926 CheckScriptFailure(['vim9script', 'var name= 234'], 'E1004:') 927 CheckScriptFailure(['vim9script', 'var name = 234', 'name+=234'], 'E1004:') 928 CheckScriptFailure(['vim9script', 'var name = 234', 'name+=234'], "before and after '+='") 929 CheckScriptFailure(['vim9script', 'var name = "x"', 'name..="y"'], 'E1004:') 930 CheckScriptFailure(['vim9script', 'var name = "x"', 'name..="y"'], "before and after '..='") 931 932 CheckDefFailure(['var true = 1'], 'E1034:') 933 CheckDefFailure(['var false = 1'], 'E1034:') 934 935 CheckDefFailure(['[a; b; c] = g:list'], 'E452:') 936 CheckDefExecFailure(['var a: number', 937 '[a] = test_null_list()'], 'E1093:') 938 CheckDefExecFailure(['var a: number', 939 '[a] = []'], 'E1093:') 940 CheckDefExecFailure(['var x: number', 941 'var y: number', 942 '[x, y] = [1]'], 'E1093:') 943 CheckDefExecFailure(['var x: string', 944 'var y: string', 945 '[x, y] = ["x"]'], 'E1093:') 946 CheckDefExecFailure(['var x: number', 947 'var y: number', 948 'var z: list<number>', 949 '[x, y; z] = [1]'], 'E1093:') 950 951 CheckDefFailure(['var somevar'], "E1022:") 952 CheckDefFailure(['var &tabstop = 4'], 'E1052:') 953 CheckDefFailure(['&g:option = 5'], 'E113:') 954 CheckScriptFailure(['vim9script', 'var &tabstop = 4'], 'E1052:') 955 956 CheckDefFailure(['var $VAR = 5'], 'E1016: Cannot declare an environment variable:') 957 CheckScriptFailure(['vim9script', 'var $ENV = "xxx"'], 'E1016:') 958 959 if has('dnd') 960 CheckDefFailure(['var @~ = 5'], 'E1066:') 961 else 962 CheckDefFailure(['var @~ = 5'], 'E354:') 963 CheckDefFailure(['@~ = 5'], 'E354:') 964 endif 965 CheckDefFailure(['var @a = 5'], 'E1066:') 966 CheckDefFailure(['var @/ = "x"'], 'E1066:') 967 CheckScriptFailure(['vim9script', 'var @a = "abc"'], 'E1066:') 968 969 CheckDefFailure(['var g:var = 5'], 'E1016: Cannot declare a global variable:') 970 CheckDefFailure(['var w:var = 5'], 'E1016: Cannot declare a window variable:') 971 CheckDefFailure(['var b:var = 5'], 'E1016: Cannot declare a buffer variable:') 972 CheckDefFailure(['var t:var = 5'], 'E1016: Cannot declare a tab variable:') 973 974 CheckDefFailure(['var anr = 4', 'anr ..= "text"'], 'E1019:') 975 CheckDefFailure(['var xnr += 4'], 'E1020:', 1) 976 CheckScriptFailure(['vim9script', 'var xnr += 4'], 'E1020:') 977 CheckDefFailure(["var xnr = xnr + 1"], 'E1001:', 1) 978 CheckScriptFailure(['vim9script', 'var xnr = xnr + 4'], 'E121:') 979 980 CheckScriptFailure(['vim9script', 'def Func()', 'var dummy = s:notfound', 'enddef', 'defcompile'], 'E1108:') 981 982 CheckDefFailure(['var name: list<string> = [123]'], 'expected list<string> but got list<number>') 983 CheckDefFailure(['var name: list<number> = ["xx"]'], 'expected list<number> but got list<string>') 984 985 CheckDefFailure(['var name: dict<string> = {key: 123}'], 'expected dict<string> but got dict<number>') 986 CheckDefFailure(['var name: dict<number> = {key: "xx"}'], 'expected dict<number> but got dict<string>') 987 988 CheckDefFailure(['var name = feedkeys("0")'], 'E1031:') 989 CheckDefFailure(['var name: number = feedkeys("0")'], 'expected number but got void') 990 991 CheckDefFailure(['var name: dict <number>'], 'E1068:') 992 CheckDefFailure(['var name: dict<number'], 'E1009:') 993 994 assert_fails('s/^/\=Mess()/n', 'E794:') 995 CheckDefFailure(['var name: dict<number'], 'E1009:') 996 997 CheckDefFailure(['w:foo: number = 10'], 998 'E488: Trailing characters: : number = 1') 999 CheckDefFailure(['t:foo: bool = true'], 1000 'E488: Trailing characters: : bool = true') 1001 CheckDefFailure(['b:foo: string = "x"'], 1002 'E488: Trailing characters: : string = "x"') 1003 CheckDefFailure(['g:foo: number = 123'], 1004 'E488: Trailing characters: : number = 123') 1005enddef 1006 1007def Test_assign_list() 1008 var l: list<string> = [] 1009 l[0] = 'value' 1010 assert_equal('value', l[0]) 1011 1012 l[1] = 'asdf' 1013 assert_equal('value', l[0]) 1014 assert_equal('asdf', l[1]) 1015 assert_equal('asdf', l[-1]) 1016 assert_equal('value', l[-2]) 1017 1018 var nrl: list<number> = [] 1019 for i in range(5) 1020 nrl[i] = i 1021 endfor 1022 assert_equal([0, 1, 2, 3, 4], nrl) 1023 1024 CheckDefFailure(["var l: list<number> = ['', true]"], 'E1012: Type mismatch; expected list<number> but got list<any>', 1) 1025 CheckDefFailure(["var l: list<list<number>> = [['', true]]"], 'E1012: Type mismatch; expected list<list<number>> but got list<list<any>>', 1) 1026enddef 1027 1028def Test_assign_dict() 1029 var lines =<< trim END 1030 var d: dict<string> = {} 1031 d['key'] = 'value' 1032 assert_equal('value', d['key']) 1033 1034 d[123] = 'qwerty' 1035 assert_equal('qwerty', d[123]) 1036 assert_equal('qwerty', d['123']) 1037 1038 var nrd: dict<number> = {} 1039 for i in range(3) 1040 nrd[i] = i 1041 endfor 1042 assert_equal({0: 0, 1: 1, 2: 2}, nrd) 1043 1044 d.somekey = 'someval' 1045 assert_equal({key: 'value', '123': 'qwerty', somekey: 'someval'}, d) 1046 # unlet d.somekey 1047 # assert_equal({key: 'value', '123': 'qwerty'}, d) 1048 END 1049 CheckDefAndScriptSuccess(lines) 1050 1051 # TODO: move to above once "unlet d.somekey" in :def is implemented 1052 lines =<< trim END 1053 vim9script 1054 var d: dict<string> = {} 1055 d['key'] = 'value' 1056 d.somekey = 'someval' 1057 assert_equal({key: 'value', somekey: 'someval'}, d) 1058 unlet d.somekey 1059 assert_equal({key: 'value'}, d) 1060 END 1061 CheckScriptSuccess(lines) 1062 1063 CheckDefFailure(["var d: dict<number> = {a: '', b: true}"], 'E1012: Type mismatch; expected dict<number> but got dict<any>', 1) 1064 CheckDefFailure(["var d: dict<dict<number>> = {x: {a: '', b: true}}"], 'E1012: Type mismatch; expected dict<dict<number>> but got dict<dict<any>>', 1) 1065enddef 1066 1067def Test_assign_dict_unknown_type() 1068 var lines =<< trim END 1069 vim9script 1070 var mylist = [] 1071 mylist += [{one: 'one'}] 1072 def Func() 1073 var dd = mylist[0] 1074 assert_equal('one', dd.one) 1075 enddef 1076 Func() 1077 END 1078 CheckScriptSuccess(lines) 1079 1080 lines =<< trim END 1081 vim9script 1082 var mylist = [[]] 1083 mylist[0] += [{one: 'one'}] 1084 def Func() 1085 var dd = mylist[0][0] 1086 assert_equal('one', dd.one) 1087 enddef 1088 Func() 1089 END 1090 CheckScriptSuccess(lines) 1091enddef 1092 1093def Test_assign_lambda() 1094 # check if assign a lambda to a variable which type is func or any. 1095 var lines =<< trim END 1096 vim9script 1097 var FuncRef = () => 123 1098 assert_equal(123, FuncRef()) 1099 var FuncRef_Func: func = () => 123 1100 assert_equal(123, FuncRef_Func()) 1101 var FuncRef_Any: any = () => 123 1102 assert_equal(123, FuncRef_Any()) 1103 END 1104 CheckScriptSuccess(lines) 1105 1106 lines =<< trim END 1107 var Ref: func(number) 1108 Ref = (j) => !j 1109 END 1110 CheckDefFailure(lines, 'E1012: Type mismatch; expected func(number) but got func(any): bool') 1111 CheckScriptFailure(['vim9script'] + lines, 'E1012: Type mismatch; expected func(number) but got func(any): any') 1112enddef 1113 1114def Test_heredoc() 1115 var lines =<< trim END # comment 1116 text 1117 END 1118 assert_equal(['text'], lines) 1119 1120 CheckDefFailure(['var lines =<< trim END X', 'END'], 'E488:') 1121 CheckDefFailure(['var lines =<< trim END " comment', 'END'], 'E488:') 1122 1123 lines =<< trim [END] 1124 def Func() 1125 var&lines =<< trim END 1126 x 1127 x 1128 enddef 1129 defcompile 1130 [END] 1131 CheckScriptFailure(lines, 'E1145: Missing heredoc end marker: END') 1132 delfunc! g:Func 1133 1134 lines =<< trim [END] 1135 def Func() 1136 var lines =<< trim END 1137 x 1138 x 1139 x 1140 x 1141 x 1142 x 1143 x 1144 x 1145 enddef 1146 call Func() 1147 [END] 1148 CheckScriptFailure(lines, 'E1145: Missing heredoc end marker: END') 1149 delfunc! g:Func 1150enddef 1151 1152def Test_var_func_call() 1153 var lines =<< trim END 1154 vim9script 1155 func GetValue() 1156 if exists('g:count') 1157 let g:count += 1 1158 else 1159 let g:count = 1 1160 endif 1161 return 'this' 1162 endfunc 1163 var val: string = GetValue() 1164 # env var is always a string 1165 var env = $TERM 1166 END 1167 writefile(lines, 'Xfinished') 1168 source Xfinished 1169 # GetValue() is not called during discovery phase 1170 assert_equal(1, g:count) 1171 1172 unlet g:count 1173 delete('Xfinished') 1174enddef 1175 1176def Test_var_missing_type() 1177 var lines =<< trim END 1178 vim9script 1179 var name = g:unknown 1180 END 1181 CheckScriptFailure(lines, 'E121:') 1182 1183 lines =<< trim END 1184 vim9script 1185 var nr: number = 123 1186 var name = nr 1187 END 1188 CheckScriptSuccess(lines) 1189enddef 1190 1191def Test_var_declaration() 1192 var lines =<< trim END 1193 vim9script 1194 var name: string 1195 g:var_uninit = name 1196 name = 'text' 1197 g:var_test = name 1198 # prefixing s: is optional 1199 s:name = 'prefixed' 1200 g:var_prefixed = s:name 1201 1202 const FOO: number = 123 1203 assert_equal(123, FOO) 1204 const FOOS = 'foos' 1205 assert_equal('foos', FOOS) 1206 final FLIST = [1] 1207 assert_equal([1], FLIST) 1208 FLIST[0] = 11 1209 assert_equal([11], FLIST) 1210 1211 const g:FOO: number = 321 1212 assert_equal(321, g:FOO) 1213 const g:FOOS = 'gfoos' 1214 assert_equal('gfoos', g:FOOS) 1215 final g:FLIST = [2] 1216 assert_equal([2], g:FLIST) 1217 g:FLIST[0] = 22 1218 assert_equal([22], g:FLIST) 1219 1220 const w:FOO: number = 46 1221 assert_equal(46, w:FOO) 1222 const w:FOOS = 'wfoos' 1223 assert_equal('wfoos', w:FOOS) 1224 final w:FLIST = [3] 1225 assert_equal([3], w:FLIST) 1226 w:FLIST[0] = 33 1227 assert_equal([33], w:FLIST) 1228 1229 var s:other: number 1230 other = 1234 1231 g:other_var = other 1232 1233 # type is inferred 1234 var s:dict = {['a']: 222} 1235 def GetDictVal(key: any) 1236 g:dict_val = s:dict[key] 1237 enddef 1238 GetDictVal('a') 1239 1240 final adict: dict<string> = {} 1241 def ChangeAdict() 1242 adict.foo = 'foo' 1243 enddef 1244 ChangeAdict() 1245 END 1246 CheckScriptSuccess(lines) 1247 assert_equal('', g:var_uninit) 1248 assert_equal('text', g:var_test) 1249 assert_equal('prefixed', g:var_prefixed) 1250 assert_equal(1234, g:other_var) 1251 assert_equal(222, g:dict_val) 1252 1253 unlet g:var_uninit 1254 unlet g:var_test 1255 unlet g:var_prefixed 1256 unlet g:other_var 1257 unlet g:FOO 1258 unlet g:FOOS 1259 unlet g:FLIST 1260 unlet w:FOO 1261 unlet w:FOOS 1262 unlet w:FLIST 1263enddef 1264 1265def Test_var_declaration_fails() 1266 var lines =<< trim END 1267 vim9script 1268 final var: string 1269 END 1270 CheckScriptFailure(lines, 'E1125:') 1271 1272 lines =<< trim END 1273 vim9script 1274 const g:constvar = 'string' 1275 g:constvar = 'xx' 1276 END 1277 CheckScriptFailure(lines, 'E741:') 1278 unlet g:constvar 1279 1280 lines =<< trim END 1281 vim9script 1282 const cdict: dict<string> = {} 1283 def Change() 1284 cdict.foo = 'foo' 1285 enddef 1286 defcompile 1287 END 1288 CheckScriptFailure(lines, 'E46:') 1289 1290 lines =<< trim END 1291 vim9script 1292 final w:finalvar = [9] 1293 w:finalvar = [8] 1294 END 1295 CheckScriptFailure(lines, 'E1122:') 1296 unlet w:finalvar 1297 1298 lines =<< trim END 1299 vim9script 1300 const var: string 1301 END 1302 CheckScriptFailure(lines, 'E1021:') 1303 1304 lines =<< trim END 1305 vim9script 1306 var 9var: string 1307 END 1308 CheckScriptFailure(lines, 'E475:') 1309 1310 CheckDefFailure(['var foo.bar = 2'], 'E1087:') 1311 CheckDefFailure(['var foo[3] = 2'], 'E1087:') 1312 CheckDefFailure(['const foo: number'], 'E1021:') 1313enddef 1314 1315def Test_var_type_check() 1316 var lines =<< trim END 1317 vim9script 1318 var name: string 1319 name = 1234 1320 END 1321 CheckScriptFailure(lines, 'E1012:') 1322 1323 lines =<< trim END 1324 vim9script 1325 var name:string 1326 END 1327 CheckScriptFailure(lines, 'E1069:') 1328 1329 lines =<< trim END 1330 vim9script 1331 var name: asdf 1332 END 1333 CheckScriptFailure(lines, 'E1010:') 1334 1335 lines =<< trim END 1336 vim9script 1337 var s:l: list<number> 1338 s:l = [] 1339 END 1340 CheckScriptSuccess(lines) 1341 1342 lines =<< trim END 1343 vim9script 1344 var s:d: dict<number> 1345 s:d = {} 1346 END 1347 CheckScriptSuccess(lines) 1348enddef 1349 1350let g:dict_number = #{one: 1, two: 2} 1351 1352def Test_var_list_dict_type() 1353 var ll: list<number> 1354 ll = [1, 2, 2, 3, 3, 3]->uniq() 1355 ll->assert_equal([1, 2, 3]) 1356 1357 var dd: dict<number> 1358 dd = g:dict_number 1359 dd->assert_equal(g:dict_number) 1360 1361 var lines =<< trim END 1362 var ll: list<number> 1363 ll = [1, 2, 3]->map('"one"') 1364 END 1365 CheckDefExecFailure(lines, 'E1012: Type mismatch; expected number but got string') 1366enddef 1367 1368def Test_cannot_use_let() 1369 CheckDefAndScriptFailure(['let a = 34'], 'E1126:', 1) 1370enddef 1371 1372def Test_unlet() 1373 g:somevar = 'yes' 1374 assert_true(exists('g:somevar')) 1375 unlet g:somevar 1376 assert_false(exists('g:somevar')) 1377 unlet! g:somevar 1378 1379 # also works for script-local variable in legacy Vim script 1380 s:somevar = 'legacy' 1381 assert_true(exists('s:somevar')) 1382 unlet s:somevar 1383 assert_false(exists('s:somevar')) 1384 unlet! s:somevar 1385 1386 CheckDefExecFailure([ 1387 'var dd = 111', 1388 'unlet dd', 1389 ], 'E1081:', 2) 1390 1391 # dict unlet 1392 var dd = {a: 1, b: 2, c: 3} 1393 unlet dd['a'] 1394 unlet dd.c 1395 assert_equal({b: 2}, dd) 1396 1397 # list unlet 1398 var ll = [1, 2, 3, 4] 1399 unlet ll[1] 1400 unlet ll[-1] 1401 assert_equal([1, 3], ll) 1402 1403 # list of dict unlet 1404 var dl = [{a: 1, b: 2}, {c: 3}] 1405 unlet dl[0]['b'] 1406 assert_equal([{a: 1}, {c: 3}], dl) 1407 1408 CheckDefExecFailure([ 1409 'var ll = test_null_list()', 1410 'unlet ll[0]', 1411 ], 'E684:', 2) 1412 CheckDefExecFailure([ 1413 'var ll = [1]', 1414 'unlet ll[2]', 1415 ], 'E684:', 2) 1416 CheckDefExecFailure([ 1417 'var ll = [1]', 1418 'unlet ll[g:astring]', 1419 ], 'E1012:', 2) 1420 CheckDefExecFailure([ 1421 'var dd = test_null_dict()', 1422 'unlet dd["a"]', 1423 ], 'E716:', 2) 1424 CheckDefExecFailure([ 1425 'var dd = {a: 1}', 1426 'unlet dd["b"]', 1427 ], 'E716:', 2) 1428 CheckDefExecFailure([ 1429 'var dd = {a: 1}', 1430 'unlet dd[g:alist]', 1431 ], 'E1105:', 2) 1432 1433 # can compile unlet before variable exists 1434 g:someDict = {key: 'val'} 1435 var k = 'key' 1436 unlet g:someDict[k] 1437 assert_equal({}, g:someDict) 1438 unlet g:someDict 1439 assert_false(exists('g:someDict')) 1440 1441 CheckScriptFailure([ 1442 'vim9script', 1443 'var svar = 123', 1444 'unlet svar', 1445 ], 'E1081:') 1446 CheckScriptFailure([ 1447 'vim9script', 1448 'var svar = 123', 1449 'unlet s:svar', 1450 ], 'E1081:') 1451 CheckScriptFailure([ 1452 'vim9script', 1453 'var svar = 123', 1454 'def Func()', 1455 ' unlet svar', 1456 'enddef', 1457 'defcompile', 1458 ], 'E1081:') 1459 CheckScriptFailure([ 1460 'vim9script', 1461 'var svar = 123', 1462 'func Func()', 1463 ' unlet s:svar', 1464 'endfunc', 1465 'Func()', 1466 ], 'E1081:') 1467 CheckScriptFailure([ 1468 'vim9script', 1469 'var svar = 123', 1470 'def Func()', 1471 ' unlet s:svar', 1472 'enddef', 1473 'defcompile', 1474 ], 'E1081:') 1475 1476 writefile(['vim9script', 'export var svar = 1234'], 'XunletExport.vim') 1477 var lines =<< trim END 1478 vim9script 1479 import svar from './XunletExport.vim' 1480 def UnletSvar() 1481 unlet svar 1482 enddef 1483 defcompile 1484 END 1485 CheckScriptFailure(lines, 'E1081:', 1) 1486 delete('XunletExport.vim') 1487 1488 $ENVVAR = 'foobar' 1489 assert_equal('foobar', $ENVVAR) 1490 unlet $ENVVAR 1491 assert_equal('', $ENVVAR) 1492enddef 1493 1494def Test_expr_error_no_assign() 1495 var lines =<< trim END 1496 vim9script 1497 var x = invalid 1498 echo x 1499 END 1500 CheckScriptFailureList(lines, ['E121:', 'E121:']) 1501 1502 lines =<< trim END 1503 vim9script 1504 var x = 1 / 0 1505 echo x 1506 END 1507 CheckScriptFailureList(lines, ['E1154:', 'E121:']) 1508 1509 lines =<< trim END 1510 vim9script 1511 var x = 1 % 0 1512 echo x 1513 END 1514 CheckScriptFailureList(lines, ['E1154:', 'E121:']) 1515enddef 1516 1517 1518def Test_assign_command_modifier() 1519 var lines =<< trim END 1520 var verbose = 0 1521 verbose = 1 1522 assert_equal(1, verbose) 1523 silent verbose = 2 1524 assert_equal(2, verbose) 1525 silent verbose += 2 1526 assert_equal(4, verbose) 1527 silent verbose -= 1 1528 assert_equal(3, verbose) 1529 1530 var topleft = {one: 1} 1531 sandbox topleft.one = 3 1532 assert_equal({one: 3}, topleft) 1533 leftabove topleft[' '] = 4 1534 assert_equal({one: 3, ' ': 4}, topleft) 1535 1536 var x: number 1537 var y: number 1538 silent [x, y] = [1, 2] 1539 assert_equal(1, x) 1540 assert_equal(2, y) 1541 END 1542 CheckDefAndScriptSuccess(lines) 1543enddef 1544 1545 1546" vim: ts=8 sw=2 sts=2 expandtab tw=80 fdm=marker 1547