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