1" Tests for the List and Dict types 2 3source vim9.vim 4 5func TearDown() 6 " Run garbage collection after every test 7 call test_garbagecollect_now() 8endfunc 9 10" Tests for List type 11 12" List creation 13func Test_list_create() 14 " Creating List directly with different types 15 let l = [1, 'as''d', [1, 2, function("strlen")], {'a': 1},] 16 call assert_equal("[1, 'as''d', [1, 2, function('strlen')], {'a': 1}]", string(l)) 17 call assert_equal({'a' : 1}, l[-1]) 18 call assert_equal(1, l[-4]) 19 let x = 10 20 try 21 let x = l[-5] 22 catch 23 call assert_match('E684:', v:exception) 24 endtry 25 call assert_equal(10, x) 26endfunc 27 28" This was allowed in legacy Vim script 29let s:list_with_spaces = [1 , 2 , 3] 30 31" List slices 32func Test_list_slice() 33 let l = [1, 'as''d', [1, 2, function("strlen")], {'a': 1},] 34 call assert_equal([1, 'as''d', [1, 2, function('strlen')], {'a': 1}], l[:]) 35 call assert_equal(['as''d', [1, 2, function('strlen')], {'a': 1}], l[1:]) 36 call assert_equal([1, 'as''d', [1, 2, function('strlen')]], l[:-2]) 37 call assert_equal([1, 'as''d', [1, 2, function('strlen')], {'a': 1}], l[0:8]) 38 call assert_equal([], l[8:-1]) 39 call assert_equal([], l[0:-10]) 40 " perform an operation on a list slice 41 let l = [1, 2, 3] 42 let l[:1] += [1, 2] 43 let l[2:] -= [1] 44 call assert_equal([2, 4, 2], l) 45endfunc 46 47" List identity 48func Test_list_identity() 49 let lines =<< trim END 50 VAR l = [1, 'as''d', [1, 2, function("strlen")], {'a': 1},] 51 VAR ll = l 52 VAR lx = copy(l) 53 call assert_true(l == ll) 54 call assert_false(l isnot ll) 55 call assert_true(l is ll) 56 call assert_true(l == lx) 57 call assert_false(l is lx) 58 call assert_true(l isnot lx) 59 END 60 call CheckLegacyAndVim9Success(lines) 61endfunc 62 63" removing items with :unlet 64func Test_list_unlet() 65 let lines =<< trim END 66 VAR l = [1, 'as''d', [1, 2, function("strlen")], {'a': 1},] 67 unlet l[2] 68 call assert_equal([1, 'as''d', {'a': 1}], l) 69 LET l = range(8) 70 unlet l[: 3] 71 unlet l[1 :] 72 call assert_equal([4], l) 73 74 #" removing items out of range: silently skip items that don't exist 75 LET l = [0, 1, 2, 3] 76 unlet l[2 : 2] 77 call assert_equal([0, 1, 3], l) 78 LET l = [0, 1, 2, 3] 79 unlet l[2 : 3] 80 call assert_equal([0, 1], l) 81 LET l = [0, 1, 2, 3] 82 unlet l[2 : 4] 83 call assert_equal([0, 1], l) 84 LET l = [0, 1, 2, 3] 85 unlet l[2 : 5] 86 call assert_equal([0, 1], l) 87 LET l = [0, 1, 2, 3] 88 unlet l[-2 : 2] 89 call assert_equal([0, 1, 3], l) 90 LET l = [0, 1, 2, 3] 91 unlet l[-3 : 2] 92 call assert_equal([0, 3], l) 93 LET l = [0, 1, 2, 3] 94 unlet l[-4 : 2] 95 call assert_equal([3], l) 96 LET l = [0, 1, 2, 3] 97 unlet l[-5 : 2] 98 call assert_equal([3], l) 99 LET l = [0, 1, 2, 3] 100 unlet l[-6 : 2] 101 call assert_equal([3], l) 102 END 103 call CheckLegacyAndVim9Success(lines) 104 105 let l = [0, 1, 2, 3] 106 unlet l[2:2] 107 call assert_equal([0, 1, 3], l) 108 let l = [0, 1, 2, 3] 109 unlet l[2:3] 110 call assert_equal([0, 1], l) 111 112 let lines =<< trim END 113 VAR l = [0, 1, 2, 3] 114 unlet l[2 : 1] 115 END 116 call CheckLegacyAndVim9Failure(lines, 'E684:') 117 118 let lines =<< trim END 119 VAR l = [0, 1, 2, 3] 120 unlet l[-1 : 2] 121 END 122 call CheckLegacyAndVim9Failure(lines, 'E684:') 123endfunc 124 125" assignment to a list 126func Test_list_assign() 127 let lines =<< trim END 128 VAR l = [0, 1, 2, 3] 129 VAR va = 0 130 VAR vb = 0 131 LET [va, vb] = l[2 : 3] 132 call assert_equal([2, 3], [va, vb]) 133 END 134 call CheckLegacyAndVim9Success(lines) 135 136 let lines =<< trim END 137 let l = [0, 1, 2, 3] 138 let [va, vb] = l 139 END 140 call CheckScriptFailure(lines, 'E687:') 141 let lines =<< trim END 142 var l = [0, 1, 2, 3] 143 var va = 0 144 var vb = 0 145 [va, vb] = l 146 END 147 call CheckScriptFailure(['vim9script'] + lines, 'E687:') 148 call CheckDefExecFailure(lines, 'E1093: Expected 2 items but got 4') 149 150 let lines =<< trim END 151 let l = [0, 1, 2, 3] 152 let [va, vb] = l[1:1] 153 END 154 call CheckScriptFailure(lines, 'E688:') 155 let lines =<< trim END 156 var l = [0, 1, 2, 3] 157 var va = 0 158 var vb = 0 159 [va, vb] = l[1 : 1] 160 END 161 call CheckScriptFailure(['vim9script'] + lines, 'E688:') 162 call CheckDefExecFailure(lines, 'E1093: Expected 2 items but got 1') 163endfunc 164 165" test for range assign 166func Test_list_range_assign() 167 let lines =<< trim END 168 VAR l = [0] 169 LET l[:] = [1, 2] 170 call assert_equal([1, 2], l) 171 LET l[-4 : -1] = [5, 6] 172 call assert_equal([5, 6], l) 173 END 174 call CheckLegacyAndVim9Success(lines) 175endfunc 176 177" Test removing items in list 178func Test_list_func_remove() 179 let lines =<< trim END 180 #" Test removing 1 element 181 VAR l = [1, 2, 3, 4] 182 call assert_equal(1, remove(l, 0)) 183 call assert_equal([2, 3, 4], l) 184 185 LET l = [1, 2, 3, 4] 186 call assert_equal(2, remove(l, 1)) 187 call assert_equal([1, 3, 4], l) 188 189 LET l = [1, 2, 3, 4] 190 call assert_equal(4, remove(l, -1)) 191 call assert_equal([1, 2, 3], l) 192 193 #" Test removing range of element(s) 194 LET l = [1, 2, 3, 4] 195 call assert_equal([3], remove(l, 2, 2)) 196 call assert_equal([1, 2, 4], l) 197 198 LET l = [1, 2, 3, 4] 199 call assert_equal([2, 3], remove(l, 1, 2)) 200 call assert_equal([1, 4], l) 201 202 LET l = [1, 2, 3, 4] 203 call assert_equal([2, 3], remove(l, -3, -2)) 204 call assert_equal([1, 4], l) 205 END 206 call CheckLegacyAndVim9Success(lines) 207 208 " Test invalid cases 209 let l = [1, 2, 3, 4] 210 call assert_fails("call remove(l, 5)", 'E684:') 211 call assert_fails("call remove(l, 1, 5)", 'E684:') 212 call assert_fails("call remove(l, 3, 2)", 'E16:') 213 call assert_fails("call remove(1, 0)", 'E896:') 214 call assert_fails("call remove(l, l)", 'E745:') 215endfunc 216 217" List add() function 218func Test_list_add() 219 let lines =<< trim END 220 VAR l = [] 221 call add(l, 1) 222 call add(l, [2, 3]) 223 call add(l, []) 224 call add(l, test_null_list()) 225 call add(l, {'k': 3}) 226 call add(l, {}) 227 call add(l, test_null_dict()) 228 call assert_equal([1, [2, 3], [], [], {'k': 3}, {}, {}], l) 229 END 230 call CheckLegacyAndVim9Success(lines) 231 232 " weird legacy behavior 233 call assert_equal(1, add(test_null_list(), 4)) 234endfunc 235 236" Tests for Dictionary type 237 238func Test_dict() 239 " Creating Dictionary directly with different types 240 let lines =<< trim END 241 VAR d = {'1': 'asd', 'b': [1, 2, function('strlen')], '-1': {'a': 1}, } 242 call assert_equal("{'1': 'asd', 'b': [1, 2, function('strlen')], '-1': {'a': 1}}", string(d)) 243 call assert_equal('asd', d.1) 244 call assert_equal(['-1', '1', 'b'], sort(keys(d))) 245 call assert_equal(['asd', [1, 2, function('strlen')], {'a': 1}], values(d)) 246 call extend(d, {3: 33, 1: 99}) 247 call extend(d, {'b': 'bbb', 'c': 'ccc'}, "keep") 248 call assert_equal({'c': 'ccc', '1': 99, 'b': [1, 2, function('strlen')], '3': 33, '-1': {'a': 1}}, d) 249 END 250 call CheckLegacyAndVim9Success(lines) 251 252 let d = {001: 'asd', 'b': [1, 2, function('strlen')], -1: {'a': 1},} 253 call assert_equal("{'1': 'asd', 'b': [1, 2, function('strlen')], '-1': {'a': 1}}", string(d)) 254 255 let v = [] 256 for [key, val] in items(d) 257 call extend(v, [key, val]) 258 unlet key val 259 endfor 260 call assert_equal(['1','asd','b',[1, 2, function('strlen')],'-1',{'a': 1}], v) 261 262 call extend(d, {3: 33, 1: 99}) 263 call assert_fails("call extend(d, {3:333,4:444}, 'error')", 'E737:') 264 265 " duplicate key 266 call assert_fails("let d = {'k' : 10, 'k' : 20}", 'E721:') 267 " missing comma 268 call assert_fails("let d = {'k' : 10 'k' : 20}", 'E722:') 269 " missing curly brace 270 call assert_fails("let d = {'k' : 10,", 'E723:') 271 " invalid key 272 call assert_fails('let d = #{++ : 10}', 'E15:') 273 " wrong type for key 274 call assert_fails('let d={[] : 10}', 'E730:') 275 " undefined variable as value 276 call assert_fails("let d={'k' : i}", 'E121:') 277endfunc 278 279" This was allowed in legacy Vim script 280let s:dict_with_spaces = {'one' : 1 , 'two' : 2 , 'three' : 3} 281let s:dict_with_spaces_lit = #{one : 1 , two : 2 , three : 3} 282 283" Dictionary identity 284func Test_dict_identity() 285 let lines =<< trim END 286 VAR d = {'1': 'asd', 'b': [1, 2, function('strlen')], -1: {'a': 1}, } 287 VAR dd = d 288 VAR dx = copy(d) 289 call assert_true(d == dd) 290 call assert_false(d isnot dd) 291 call assert_true(d is dd) 292 call assert_true(d == dx) 293 call assert_false(d is dx) 294 call assert_true(d isnot dx) 295 END 296 call CheckLegacyAndVim9Success(lines) 297endfunc 298 299" removing items with :unlet 300func Test_dict_unlet() 301 let lines =<< trim END 302 VAR d = {'b': 'bbb', '1': 99, '3': 33, '-1': {'a': 1}} 303 unlet d.b 304 unlet d[-1] 305 call assert_equal({'1': 99, '3': 33}, d) 306 END 307 call CheckLegacyAndVim9Success(lines) 308endfunc 309 310" manipulating a big Dictionary (hashtable.c has a border of 1000 entries) 311func Test_dict_big() 312 let d = {} 313 for i in range(1500) 314 let d[i] = 3000 - i 315 endfor 316 call assert_equal([3000, 2900, 2001, 1600, 1501], [d[0], d[100], d[999], d[1400], d[1499]]) 317 let str = '' 318 try 319 let n = d[1500] 320 catch 321 let str = substitute(v:exception, '\v(.{14}).*( "\d{4}").*', '\1\2', '') 322 endtry 323 call assert_equal('Vim(let):E716: "1500"', str) 324 325 " lookup each items 326 for i in range(1500) 327 call assert_equal(3000 - i, d[i]) 328 endfor 329 let i += 1 330 331 " delete even items 332 while i >= 2 333 let i -= 2 334 unlet d[i] 335 endwhile 336 call assert_equal('NONE', get(d, 1500 - 100, 'NONE')) 337 call assert_equal(2999, d[1]) 338 339 " delete odd items, checking value, one intentionally wrong 340 let d[33] = 999 341 let i = 1 342 while i < 1500 343 if i != 33 344 call assert_equal(3000 - i, d[i]) 345 else 346 call assert_equal(999, d[i]) 347 endif 348 unlet d[i] 349 let i += 2 350 endwhile 351 call assert_equal({}, d) 352 unlet d 353endfunc 354 355" Dictionary function 356func Test_dict_func() 357 let d = {} 358 func d.func(a) dict 359 return a:a . len(self.data) 360 endfunc 361 let d.data = [1,2,3] 362 call assert_equal('len: 3', d.func('len: ')) 363 let x = d.func('again: ') 364 call assert_equal('again: 3', x) 365 let Fn = d.func 366 call assert_equal('xxx3', Fn('xxx')) 367endfunc 368 369func Test_dict_assign() 370 let d = {} 371 let d.1 = 1 372 let d._ = 2 373 call assert_equal({'1': 1, '_': 2}, d) 374 375 let lines =<< trim END 376 VAR d = {} 377 LET d.a = 1 378 LET d._ = 2 379 call assert_equal({'a': 1, '_': 2}, d) 380 END 381 call CheckLegacyAndVim9Success(lines) 382 383 let lines =<< trim END 384 let n = 0 385 let n.key = 3 386 END 387 call CheckScriptFailure(lines, 'E1203: Dot can only be used on a dictionary: n.key = 3') 388 let lines =<< trim END 389 vim9script 390 var n = 0 391 n.key = 3 392 END 393 call CheckScriptFailure(lines, 'E1203: Dot can only be used on a dictionary: n.key = 3') 394 let lines =<< trim END 395 var n = 0 396 n.key = 3 397 END 398 call CheckDefFailure(lines, 'E1141:') 399endfunc 400 401" Function in script-local List or Dict 402func Test_script_local_dict_func() 403 let g:dict = {} 404 function g:dict.func() dict 405 return 'g:dict.func' . self.foo[1] . self.foo[0]('asdf') 406 endfunc 407 let g:dict.foo = ['-', 2, 3] 408 call insert(g:dict.foo, function('strlen')) 409 call assert_equal('g:dict.func-4', g:dict.func()) 410 unlet g:dict 411endfunc 412 413" Test removing items in a dictionary 414func Test_dict_func_remove() 415 let lines =<< trim END 416 VAR d = {1: 'a', 2: 'b', 3: 'c'} 417 call assert_equal('b', remove(d, 2)) 418 call assert_equal({1: 'a', 3: 'c'}, d) 419 END 420 call CheckLegacyAndVim9Success(lines) 421 422 let lines =<< trim END 423 VAR d = {1: 'a', 3: 'c'} 424 call remove(d, 1, 2) 425 END 426 call CheckLegacyAndVim9Failure(lines, 'E118:') 427 428 let lines =<< trim END 429 VAR d = {1: 'a', 3: 'c'} 430 call remove(d, 'a') 431 END 432 call CheckLegacyAndVim9Failure(lines, 'E716:') 433 434 let lines =<< trim END 435 let d = {1: 'a', 3: 'c'} 436 call remove(d, []) 437 END 438 call CheckScriptFailure(lines, 'E730:') 439 let lines =<< trim END 440 vim9script 441 var d = {1: 'a', 3: 'c'} 442 call remove(d, []) 443 END 444 call CheckScriptFailure(lines, 'E1220: String or Number required for argument 2') 445 let lines =<< trim END 446 var d = {1: 'a', 3: 'c'} 447 call remove(d, []) 448 END 449 call CheckDefExecFailure(lines, 'E1013: Argument 2: type mismatch, expected string but got list<unknown>') 450endfunc 451 452" Nasty: remove func from Dict that's being called (works) 453func Test_dict_func_remove_in_use() 454 let d = {1:1} 455 func d.func(a) 456 return "a:" . a:a 457 endfunc 458 let expected = 'a:' . string(get(d, 'func')) 459 call assert_equal(expected, d.func(string(remove(d, 'func')))) 460 461 " similar, in a way it also works in Vim9 462 let lines =<< trim END 463 VAR d = {1: 1, 2: 'x'} 464 func GetArg(a) 465 return "a:" .. a:a 466 endfunc 467 LET d.func = function('GetArg') 468 VAR expected = 'a:' .. string(get(d, 'func')) 469 call assert_equal(expected, d.func(string(remove(d, 'func')))) 470 END 471 call CheckTransLegacySuccess(lines) 472 call CheckTransVim9Success(lines) 473endfunc 474 475func Test_dict_literal_keys() 476 call assert_equal({'one': 1, 'two2': 2, '3three': 3, '44': 4}, #{one: 1, two2: 2, 3three: 3, 44: 4},) 477 478 " why *{} cannot be used for a literal dictionary 479 let blue = 'blue' 480 call assert_equal('6', trim(execute('echo 2 *{blue: 3}.blue'))) 481endfunc 482 483" Nasty: deepcopy() dict that refers to itself (fails when noref used) 484func Test_dict_deepcopy() 485 let lines =<< trim END 486 VAR d = {1: 1, 2: '2'} 487 VAR l = [4, d, 6] 488 LET d[3] = l 489 VAR dc = deepcopy(d) 490 call deepcopy(d, 1) 491 END 492 call CheckLegacyAndVim9Failure(lines, 'E698:') 493 494 let lines =<< trim END 495 VAR d = {1: 1, 2: '2'} 496 VAR l = [4, d, 6] 497 LET d[3] = l 498 VAR l2 = [0, l, l, 3] 499 LET l[1] = l2 500 VAR l3 = deepcopy(l2) 501 call assert_true(l3[1] is l3[2]) 502 END 503 call CheckLegacyAndVim9Success(lines) 504 505 call assert_fails("call deepcopy([1, 2], 2)", 'E1023:') 506endfunc 507 508" Locked variables 509func Test_list_locked_var() 510 " Not tested with :def function, local vars cannot be locked. 511 let lines =<< trim END 512 VAR expected = [ 513 \ [['1000-000', 'ppppppF'], 514 \ ['0000-000', 'ppppppp'], 515 \ ['0000-000', 'ppppppp']], 516 \ [['1000-000', 'ppppppF'], 517 \ ['0000-000', 'ppppppp'], 518 \ ['0000-000', 'ppppppp']], 519 \ [['1100-100', 'ppFppFF'], 520 \ ['0000-000', 'ppppppp'], 521 \ ['0000-000', 'ppppppp']], 522 \ [['1110-110', 'pFFpFFF'], 523 \ ['0010-010', 'pFppFpp'], 524 \ ['0000-000', 'ppppppp']], 525 \ [['1111-111', 'FFFFFFF'], 526 \ ['0011-011', 'FFpFFpp'], 527 \ ['0000-000', 'ppppppp']] 528 \ ] 529 for depth in range(5) 530 for u in range(3) 531 VAR l = [0, [1, [2, 3]], {4: 5, 6: {7: 8}}] 532 exe "lockvar " .. depth .. " l" 533 if u == 1 534 exe "unlockvar l" 535 elseif u == 2 536 exe "unlockvar " .. depth .. " l" 537 endif 538 VAR ps = islocked("l") .. islocked("l[1]") .. islocked("l[1][1]") .. islocked("l[1][1][0]") .. '-' .. islocked("l[2]") .. islocked("l[2]['6']") .. islocked("l[2]['6'][7]") 539 call assert_equal(expected[depth][u][0], ps, 'depth: ' .. depth) 540 LET ps = '' 541 try 542 LET l[1][1][0] = 99 543 LET ps ..= 'p' 544 catch 545 LET ps ..= 'F' 546 endtry 547 try 548 LET l[1][1] = [99] 549 LET ps ..= 'p' 550 catch 551 LET ps ..= 'F' 552 endtry 553 try 554 LET l[1] = [99] 555 LET ps ..= 'p' 556 catch 557 LET ps ..= 'F' 558 endtry 559 try 560 LET l[2]['6'][7] = 99 561 LET ps ..= 'p' 562 catch 563 LET ps ..= 'F' 564 endtry 565 try 566 LET l[2][6] = {99: 99} 567 LET ps ..= 'p' 568 catch 569 LET ps ..= 'F' 570 endtry 571 try 572 LET l[2] = {99: 99} 573 LET ps ..= 'p' 574 catch 575 LET ps ..= 'F' 576 endtry 577 try 578 LET l = [99] 579 LET ps ..= 'p' 580 catch 581 LET ps ..= 'F' 582 endtry 583 call assert_equal(expected[depth][u][1], ps, 'depth: ' .. depth) 584 unlock! l 585 endfor 586 endfor 587 END 588 call CheckTransLegacySuccess(lines) 589 call CheckTransVim9Success(lines) 590 591 call assert_fails("let x=islocked('a b')", 'E488:') 592 let mylist = [1, 2, 3] 593 call assert_fails("let x = islocked('mylist[1:2]')", 'E786:') 594 let mydict = {'k' : 'v'} 595 call assert_fails("let x = islocked('mydict.a')", 'E716:') 596endfunc 597 598" Unletting locked variables 599func Test_list_locked_var_unlet() 600 " Not tested with Vim9: script and local variables cannot be unlocked 601 let expected = [ 602 \ [['1000-000', 'ppppppp'], 603 \ ['0000-000', 'ppppppp'], 604 \ ['0000-000', 'ppppppp']], 605 \ [['1000-000', 'ppFppFp'], 606 \ ['0000-000', 'ppppppp'], 607 \ ['0000-000', 'ppppppp']], 608 \ [['1100-100', 'pFFpFFp'], 609 \ ['0000-000', 'ppppppp'], 610 \ ['0000-000', 'ppppppp']], 611 \ [['1110-110', 'FFFFFFp'], 612 \ ['0010-010', 'FppFppp'], 613 \ ['0000-000', 'ppppppp']], 614 \ [['1111-111', 'FFFFFFp'], 615 \ ['0011-011', 'FppFppp'], 616 \ ['0000-000', 'ppppppp']] 617 \ ] 618 619 for depth in range(5) 620 for u in range(3) 621 unlet! l 622 let l = [0, [1, [2, 3]], {4: 5, 6: {7: 8}}] 623 exe "lockvar " . depth . " l" 624 if u == 1 625 exe "unlockvar l" 626 elseif u == 2 627 exe "unlockvar " . depth . " l" 628 endif 629 let ps = islocked("l").islocked("l[1]").islocked("l[1][1]").islocked("l[1][1][0]").'-'.islocked("l[2]").islocked("l[2]['6']").islocked("l[2]['6'][7]") 630 call assert_equal(expected[depth][u][0], ps, 'depth: ' .. depth) 631 let ps = '' 632 try 633 unlet l[2]['6'][7] 634 let ps .= 'p' 635 catch 636 let ps .= 'F' 637 endtry 638 try 639 unlet l[2][6] 640 let ps .= 'p' 641 catch 642 let ps .= 'F' 643 endtry 644 try 645 unlet l[2] 646 let ps .= 'p' 647 catch 648 let ps .= 'F' 649 endtry 650 try 651 unlet l[1][1][0] 652 let ps .= 'p' 653 catch 654 let ps .= 'F' 655 endtry 656 try 657 unlet l[1][1] 658 let ps .= 'p' 659 catch 660 let ps .= 'F' 661 endtry 662 try 663 unlet l[1] 664 let ps .= 'p' 665 catch 666 let ps .= 'F' 667 endtry 668 try 669 unlet l 670 let ps .= 'p' 671 catch 672 let ps .= 'F' 673 endtry 674 call assert_equal(expected[depth][u][1], ps) 675 endfor 676 endfor 677 " Deleting a list range should fail if the range is locked 678 let l = [1, 2, 3, 4] 679 lockvar l[1:2] 680 call assert_fails('unlet l[1:2]', 'E741:') 681 unlet l 682endfunc 683 684" Locked variables and :unlet or list / dict functions 685 686" No :unlet after lock on dict: 687func Test_dict_lock_unlet() 688 let d = {'a': 99, 'b': 100} 689 lockvar 1 d 690 call assert_fails('unlet d.a', 'E741:') 691endfunc 692 693" unlet after lock on dict item 694func Test_dict_item_lock_unlet() 695 let lines =<< trim END 696 VAR d = {'a': 99, 'b': 100} 697 lockvar d.a 698 unlet d.a 699 call assert_equal({'b': 100}, d) 700 END 701 " TODO: make this work in a :def function 702 "call CheckLegacyAndVim9Success(lines) 703 call CheckTransLegacySuccess(lines) 704 call CheckTransVim9Success(lines) 705endfunc 706 707" filter() after lock on dict item 708func Test_dict_lock_filter() 709 let lines =<< trim END 710 VAR d = {'a': 99, 'b': 100} 711 lockvar d.a 712 call filter(d, 'v:key != "a"') 713 call assert_equal({'b': 100}, d) 714 END 715 " TODO: make this work in a :def function 716 "call CheckLegacyAndVim9Success(lines) 717 call CheckTransLegacySuccess(lines) 718 call CheckTransVim9Success(lines) 719endfunc 720 721" map() after lock on dict 722func Test_dict_lock_map() 723 let lines =<< trim END 724 VAR d = {'a': 99, 'b': 100} 725 lockvar 1 d 726 call map(d, 'v:val + 200') 727 call assert_equal({'a': 299, 'b': 300}, d) 728 END 729 " This won't work in a :def function 730 call CheckTransLegacySuccess(lines) 731 call CheckTransVim9Success(lines) 732endfunc 733 734" No extend() after lock on dict item 735func Test_dict_lock_extend() 736 let d = {'a': 99, 'b': 100} 737 lockvar d.a 738 call assert_fails("call extend(d, {'a' : 123})", 'E741:') 739 call assert_equal({'a': 99, 'b': 100}, d) 740endfunc 741 742" Cannot use += with a locked dict 743func Test_dict_lock_operator() 744 let d = {} 745 lockvar d 746 call assert_fails("let d += {'k' : 10}", 'E741:') 747 unlockvar d 748endfunc 749 750" No remove() of write-protected scope-level variable 751func Tfunc1(this_is_a_long_parameter_name) 752 call assert_fails("call remove(a:, 'this_is_a_long_parameter_name')", 'E742:') 753endfunc 754func Test_dict_scope_var_remove() 755 call Tfunc1('testval') 756endfunc 757 758" No extend() of write-protected scope-level variable 759func Test_dict_scope_var_extend() 760 call assert_fails("call extend(a:, {'this_is_a_long_parameter_name': 1234})", 'E742:') 761endfunc 762 763func Tfunc2(this_is_a_long_parameter_name) 764 call assert_fails("call extend(a:, {'this_is_a_long_parameter_name': 1234})", 'E742:') 765endfunc 766func Test_dict_scope_var_extend_overwrite() 767 call Tfunc2('testval') 768endfunc 769 770" No :unlet of variable in locked scope 771func Test_lock_var_unlet() 772 let b:testvar = 123 773 lockvar 1 b: 774 call assert_fails('unlet b:testvar', 'E741:') 775 unlockvar 1 b: 776 unlet! b:testvar 777endfunc 778 779" No :let += of locked list variable 780func Test_let_lock_list() 781 let l = ['a', 'b', 3] 782 lockvar 1 l 783 call assert_fails("let l += ['x']", 'E741:') 784 call assert_equal(['a', 'b', 3], l) 785 786 unlet l 787 let l = [1, 2, 3, 4] 788 lockvar! l 789 call assert_equal([1, 2, 3, 4], l) 790 unlockvar l[1] 791 call assert_fails('unlet l[0:1]', 'E741:') 792 call assert_equal([1, 2, 3, 4], l) 793 call assert_fails('unlet l[1:2]', 'E741:') 794 call assert_equal([1, 2, 3, 4], l) 795 unlockvar l[1] 796 call assert_fails('let l[0:1] = [0, 1]', 'E741:') 797 call assert_equal([1, 2, 3, 4], l) 798 call assert_fails('let l[1:2] = [0, 1]', 'E741:') 799 call assert_equal([1, 2, 3, 4], l) 800 unlet l 801endfunc 802 803" Locking part of the list 804func Test_let_lock_list_items() 805 let l = [1, 2, 3, 4] 806 lockvar l[2:] 807 call assert_equal(0, islocked('l[0]')) 808 call assert_equal(1, islocked('l[2]')) 809 call assert_equal(1, islocked('l[3]')) 810 call assert_fails('let l[2] = 10', 'E741:') 811 call assert_fails('let l[3] = 20', 'E741:') 812 unlet l 813endfunc 814 815" lockvar/islocked() triggering script autoloading 816func Test_lockvar_script_autoload() 817 let old_rtp = &rtp 818 set rtp+=./sautest 819 lockvar g:footest#x 820 unlockvar g:footest#x 821 call assert_equal(-1, 'g:footest#x'->islocked()) 822 call assert_equal(0, exists('g:footest#x')) 823 call assert_equal(1, g:footest#x) 824 let &rtp = old_rtp 825endfunc 826 827" a:000 function argument test 828func s:arg_list_test(...) 829 call assert_fails('let a:000 = [1, 2]', 'E46:') 830 call assert_fails('let a:000[0] = 9', 'E742:') 831 call assert_fails('let a:000[2] = [9, 10]', 'E742:') 832 call assert_fails('let a:000[3] = {9 : 10}', 'E742:') 833 834 " now the tests that should pass 835 let a:000[2][1] = 9 836 call extend(a:000[2], [5, 6]) 837 let a:000[3][5] = 8 838 let a:000[3]['a'] = 12 839 call assert_equal([1, 2, [3, 9, 5, 6], {'a': 12, '5': 8}], a:000) 840endfunc 841 842func Test_func_arg_list() 843 call s:arg_list_test(1, 2, [3, 4], {5: 6}) 844endfunc 845 846" Tests for reverse(), sort(), uniq() 847func Test_reverse_sort_uniq() 848 let lines =<< trim END 849 VAR l = ['-0', 'A11', 2, 2, 'xaaa', 4, 'foo', 'foo6', 'foo', [0, 1, 2], 'x8', [0, 1, 2], 1.5] 850 call assert_equal(['-0', 'A11', 2, 'xaaa', 4, 'foo', 'foo6', 'foo', [0, 1, 2], 'x8', [0, 1, 2], 1.5], uniq(copy(l))) 851 call assert_equal([1.5, [0, 1, 2], 'x8', [0, 1, 2], 'foo', 'foo6', 'foo', 4, 'xaaa', 2, 2, 'A11', '-0'], reverse(l)) 852 call assert_equal([1.5, [0, 1, 2], 'x8', [0, 1, 2], 'foo', 'foo6', 'foo', 4, 'xaaa', 2, 2, 'A11', '-0'], reverse(reverse(l))) 853 if has('float') 854 call assert_equal(['-0', 'A11', 'foo', 'foo', 'foo6', 'x8', 'xaaa', 1.5, 2, 2, 4, [0, 1, 2], [0, 1, 2]], sort(l)) 855 call assert_equal([[0, 1, 2], [0, 1, 2], 4, 2, 2, 1.5, 'xaaa', 'x8', 'foo6', 'foo', 'foo', 'A11', '-0'], reverse(sort(l))) 856 call assert_equal(['-0', 'A11', 'foo', 'foo', 'foo6', 'x8', 'xaaa', 1.5, 2, 2, 4, [0, 1, 2], [0, 1, 2]], sort(reverse(sort(l)))) 857 call assert_equal(['-0', 'A11', 'foo', 'foo6', 'x8', 'xaaa', 1.5, 2, 4, [0, 1, 2]], uniq(sort(l))) 858 859 LET l = [7, 9, 'one', 18, 12, 22, 'two', 10.0e-16, -1, 'three', 0xff, 0.22, 'four'] 860 call assert_equal([-1, 'one', 'two', 'three', 'four', 1.0e-15, 0.22, 7, 9, 12, 18, 22, 255], sort(copy(l), 'n')) 861 862 LET l = [7, 9, 18, 12, 22, 10.0e-16, -1, 0xff, 0, -0, 0.22, 'bar', 'BAR', 'Bar', 'Foo', 'FOO', 'foo', 'FOOBAR', {}, []] 863 call assert_equal(['bar', 'BAR', 'Bar', 'Foo', 'FOO', 'foo', 'FOOBAR', -1, 0, 0, 0.22, 1.0e-15, 12, 18, 22, 255, 7, 9, [], {}], sort(copy(l), 1)) 864 call assert_equal(['bar', 'BAR', 'Bar', 'Foo', 'FOO', 'foo', 'FOOBAR', -1, 0, 0, 0.22, 1.0e-15, 12, 18, 22, 255, 7, 9, [], {}], sort(copy(l), 'i')) 865 call assert_equal(['BAR', 'Bar', 'FOO', 'FOOBAR', 'Foo', 'bar', 'foo', -1, 0, 0, 0.22, 1.0e-15, 12, 18, 22, 255, 7, 9, [], {}], sort(copy(l))) 866 endif 867 END 868 call CheckLegacyAndVim9Success(lines) 869 870 call assert_fails('call reverse("")', 'E899:') 871 call assert_fails('call uniq([1, 2], {x, y -> []})', 'E745:') 872 call assert_fails("call sort([1, 2], function('min'), 1)", "E715:") 873 call assert_fails("call sort([1, 2], function('invalid_func'))", "E700:") 874 call assert_fails("call sort([1, 2], function('min'))", "E118:") 875endfunc 876 877" reduce a list or a blob 878func Test_reduce() 879 let lines =<< trim END 880 call assert_equal(1, reduce([], LSTART acc, val LMIDDLE acc + val LEND, 1)) 881 call assert_equal(10, reduce([1, 3, 5], LSTART acc, val LMIDDLE acc + val LEND, 1)) 882 call assert_equal(2 * (2 * ((2 * 1) + 2) + 3) + 4, reduce([2, 3, 4], LSTART acc, val LMIDDLE 2 * acc + val LEND, 1)) 883 call assert_equal('a x y z', ['x', 'y', 'z']->reduce(LSTART acc, val LMIDDLE acc .. ' ' .. val LEND, 'a')) 884 call assert_equal([0, 1, 2, 3], reduce([1, 2, 3], function('add'), [0])) 885 886 VAR l = ['x', 'y', 'z'] 887 call assert_equal(42, reduce(l, function('get'), {'x': {'y': {'z': 42 } } })) 888 call assert_equal(['x', 'y', 'z'], l) 889 890 call assert_equal(1, reduce([1], LSTART acc, val LMIDDLE acc + val LEND)) 891 call assert_equal('x y z', reduce(['x', 'y', 'z'], LSTART acc, val LMIDDLE acc .. ' ' .. val LEND)) 892 call assert_equal(120, range(1, 5)->reduce(LSTART acc, val LMIDDLE acc * val LEND)) 893 894 call assert_equal(1, reduce(0z, LSTART acc, val LMIDDLE acc + val LEND, 1)) 895 call assert_equal(1 + 0xaf + 0xbf + 0xcf, reduce(0zAFBFCF, LSTART acc, val LMIDDLE acc + val LEND, 1)) 896 call assert_equal(2 * (2 * 1 + 0xaf) + 0xbf, 0zAFBF->reduce(LSTART acc, val LMIDDLE 2 * acc + val LEND, 1)) 897 898 call assert_equal(0xff, reduce(0zff, LSTART acc, val LMIDDLE acc + val LEND)) 899 call assert_equal(2 * (2 * 0xaf + 0xbf) + 0xcf, reduce(0zAFBFCF, LSTART acc, val LMIDDLE 2 * acc + val LEND)) 900 END 901 call CheckLegacyAndVim9Success(lines) 902 903 call assert_equal({'x': 1, 'y': 1, 'z': 1 }, ['x', 'y', 'z']->reduce({ acc, val -> extend(acc, { val: 1 }) }, {})) 904 vim9 assert_equal({'x': 1, 'y': 1, 'z': 1 }, ['x', 'y', 'z']->reduce((acc, val) => extend(acc, {[val]: 1 }), {})) 905 906 call assert_fails("call reduce([], { acc, val -> acc + val })", 'E998: Reduce of an empty List with no initial value') 907 call assert_fails("call reduce(0z, { acc, val -> acc + val })", 'E998: Reduce of an empty Blob with no initial value') 908 909 call assert_fails("call reduce({}, { acc, val -> acc + val }, 1)", 'E897:') 910 call assert_fails("call reduce(0, { acc, val -> acc + val }, 1)", 'E897:') 911 call assert_fails("call reduce('', { acc, val -> acc + val }, 1)", 'E897:') 912 call assert_fails("call reduce([1, 2], 'Xdoes_not_exist')", 'E117:') 913 call assert_fails("echo reduce(0z01, { acc, val -> 2 * acc + val }, '')", 'E39:') 914 915 let g:lut = [1, 2, 3, 4] 916 func EvilRemove() 917 call remove(g:lut, 1) 918 return 1 919 endfunc 920 call assert_fails("call reduce(g:lut, { acc, val -> EvilRemove() }, 1)", 'E742:') 921 unlet g:lut 922 delfunc EvilRemove 923 924 call assert_equal(42, reduce(test_null_list(), function('add'), 42)) 925 call assert_equal(42, reduce(test_null_blob(), function('add'), 42)) 926 927 " should not crash 928 call assert_fails('echo reduce([1], test_null_function())', 'E1132:') 929 call assert_fails('echo reduce([1], test_null_partial())', 'E1132:') 930endfunc 931 932" splitting a string to a List using split() 933func Test_str_split() 934 let lines =<< trim END 935 call assert_equal(['aa', 'bb'], split(' aa bb ')) 936 call assert_equal(['aa', 'bb'], split(' aa bb ', '\W\+', 0)) 937 call assert_equal(['', 'aa', 'bb', ''], split(' aa bb ', '\W\+', 1)) 938 call assert_equal(['', '', 'aa', '', 'bb', '', ''], split(' aa bb ', '\W', 1)) 939 call assert_equal(['aa', '', 'bb'], split(':aa::bb:', ':', 0)) 940 call assert_equal(['', 'aa', '', 'bb', ''], split(':aa::bb:', ':', 1)) 941 call assert_equal(['aa', '', 'bb', 'cc', ''], split('aa,,bb, cc,', ',\s*', 1)) 942 call assert_equal(['a', 'b', 'c'], split('abc', '\zs')) 943 call assert_equal(['', 'a', '', 'b', '', 'c', ''], split('abc', '\zs', 1)) 944 call assert_equal(['abc'], split('abc', '\\%(')) 945 END 946 call CheckLegacyAndVim9Success(lines) 947 948 call assert_fails("call split('abc', [])", 'E730:') 949 call assert_fails("call split('abc', 'b', [])", 'E745:') 950endfunc 951 952" compare recursively linked list and dict 953func Test_listdict_compare() 954 let lines =<< trim END 955 VAR l = [1, 2, 3, '4'] 956 VAR d = {'1': 1, '2': l, '3': 3} 957 LET l[1] = d 958 call assert_true(l == l) 959 call assert_true(d == d) 960 call assert_false(l != deepcopy(l)) 961 call assert_false(d != deepcopy(d)) 962 END 963 call CheckLegacyAndVim9Success(lines) 964 965 " comparison errors 966 call assert_fails('echo [1, 2] =~ {}', 'E691:') 967 call assert_fails('echo [1, 2] =~ [1, 2]', 'E692:') 968 call assert_fails('echo {} =~ 5', 'E735:') 969 call assert_fails('echo {} =~ {}', 'E736:') 970endfunc 971 972 " compare complex recursively linked list and dict 973func Test_listdict_compare_complex() 974 let lines =<< trim END 975 VAR l = [] 976 call add(l, l) 977 VAR dict4 = {"l": l} 978 call add(dict4.l, dict4) 979 VAR lcopy = deepcopy(l) 980 VAR dict4copy = deepcopy(dict4) 981 call assert_true(l == lcopy) 982 call assert_true(dict4 == dict4copy) 983 END 984 call CheckLegacyAndVim9Success(lines) 985endfunc 986 987" Test for extending lists and dictionaries 988func Test_listdict_extend() 989 " Test extend() with lists 990 991 " Pass the same List to extend() 992 let lines =<< trim END 993 VAR l = [1, 2, 3] 994 call assert_equal([1, 2, 3, 1, 2, 3], extend(l, l)) 995 call assert_equal([1, 2, 3, 1, 2, 3], l) 996 997 LET l = [1, 2, 3] 998 call assert_equal([1, 2, 3, 4, 5, 6], extend(l, [4, 5, 6])) 999 call assert_equal([1, 2, 3, 4, 5, 6], l) 1000 1001 LET l = [1, 2, 3] 1002 call extend(l, [4, 5, 6], 0) 1003 call assert_equal([4, 5, 6, 1, 2, 3], l) 1004 1005 LET l = [1, 2, 3] 1006 call extend(l, [4, 5, 6], 1) 1007 call assert_equal([1, 4, 5, 6, 2, 3], l) 1008 1009 LET l = [1, 2, 3] 1010 call extend(l, [4, 5, 6], 3) 1011 call assert_equal([1, 2, 3, 4, 5, 6], l) 1012 1013 LET l = [1, 2, 3] 1014 call extend(l, [4, 5, 6], -1) 1015 call assert_equal([1, 2, 4, 5, 6, 3], l) 1016 1017 LET l = [1, 2, 3] 1018 call extend(l, [4, 5, 6], -3) 1019 call assert_equal([4, 5, 6, 1, 2, 3], l) 1020 END 1021 call CheckLegacyAndVim9Success(lines) 1022 1023 let l = [1, 2, 3] 1024 call assert_fails("call extend(l, [4, 5, 6], 4)", 'E684:') 1025 call assert_fails("call extend(l, [4, 5, 6], -4)", 'E684:') 1026 if has('float') 1027 call assert_fails("call extend(l, [4, 5, 6], 1.2)", 'E805:') 1028 endif 1029 1030 " Test extend() with dictionaries. 1031 1032 " Pass the same Dict to extend() 1033 let lines =<< trim END 1034 VAR d = {'a': {'b': 'B'}, 'x': 9} 1035 call extend(d, d) 1036 call assert_equal({'a': {'b': 'B'}, 'x': 9}, d) 1037 1038 LET d = {'a': 'A', 'b': 9} 1039 call assert_equal({'a': 'A', 'b': 0, 'c': 'C'}, extend(d, {'b': 0, 'c': 'C'})) 1040 call assert_equal({'a': 'A', 'b': 0, 'c': 'C'}, d) 1041 1042 LET d = {'a': 'A', 'b': 9} 1043 call extend(d, {'a': 'A', 'b': 0, 'c': 'C'}, "force") 1044 call assert_equal({'a': 'A', 'b': 0, 'c': 'C'}, d) 1045 1046 LET d = {'a': 'A', 'b': 9} 1047 call extend(d, {'b': 0, 'c': 'C'}, "keep") 1048 call assert_equal({'a': 'A', 'b': 9, 'c': 'C'}, d) 1049 END 1050 call CheckLegacyAndVim9Success(lines) 1051 1052 let d = {'a': 'A', 'b': 'B'} 1053 call assert_fails("call extend(d, {'b': 0, 'c':'C'}, 'error')", 'E737:') 1054 call assert_fails("call extend(d, {'b': 0, 'c':'C'}, 'xxx')", 'E475:') 1055 if has('float') 1056 call assert_fails("call extend(d, {'b': 0, 'c':'C'}, 1.2)", 'E475:') 1057 endif 1058 call assert_equal({'a': 'A', 'b': 'B'}, d) 1059 1060 call assert_fails("call extend([1, 2], 1)", 'E712:') 1061 call assert_fails("call extend([1, 2], {})", 'E712:') 1062 1063 " Extend g: dictionary with an invalid variable name 1064 call assert_fails("call extend(g:, {'-!' : 10})", 'E461:') 1065 1066 " Extend a list with itself. 1067 let lines =<< trim END 1068 VAR l = [1, 5, 7] 1069 call extend(l, l, 0) 1070 call assert_equal([1, 5, 7, 1, 5, 7], l) 1071 LET l = [1, 5, 7] 1072 call extend(l, l, 1) 1073 call assert_equal([1, 1, 5, 7, 5, 7], l) 1074 LET l = [1, 5, 7] 1075 call extend(l, l, 2) 1076 call assert_equal([1, 5, 1, 5, 7, 7], l) 1077 LET l = [1, 5, 7] 1078 call extend(l, l, 3) 1079 call assert_equal([1, 5, 7, 1, 5, 7], l) 1080 END 1081 call CheckLegacyAndVim9Success(lines) 1082endfunc 1083 1084func Test_listdict_extendnew() 1085 " Test extendnew() with lists 1086 let l = [1, 2, 3] 1087 call assert_equal([1, 2, 3, 4, 5], extendnew(l, [4, 5])) 1088 call assert_equal([1, 2, 3], l) 1089 1090 " Test extend() with dictionaries. 1091 let d = {'a': {'b': 'B'}} 1092 call assert_equal({'a': {'b': 'B'}, 'c': 'cc'}, extendnew(d, {'c': 'cc'})) 1093 call assert_equal({'a': {'b': 'B'}}, d) 1094endfunc 1095 1096func s:check_scope_dict(x, fixed) 1097 func s:gen_cmd(cmd, x) 1098 return substitute(a:cmd, '\<x\ze:', a:x, 'g') 1099 endfunc 1100 1101 let cmd = s:gen_cmd('let x:foo = 1', a:x) 1102 if a:fixed 1103 call assert_fails(cmd, 'E461:') 1104 else 1105 exe cmd 1106 exe s:gen_cmd('call assert_equal(1, x:foo)', a:x) 1107 endif 1108 1109 let cmd = s:gen_cmd('let x:["bar"] = 2', a:x) 1110 if a:fixed 1111 call assert_fails(cmd, 'E461:') 1112 else 1113 exe cmd 1114 exe s:gen_cmd('call assert_equal(2, x:bar)', a:x) 1115 endif 1116 1117 let cmd = s:gen_cmd('call extend(x:, {"baz": 3})', a:x) 1118 if a:fixed 1119 call assert_fails(cmd, 'E742:') 1120 else 1121 exe cmd 1122 exe s:gen_cmd('call assert_equal(3, x:baz)', a:x) 1123 endif 1124 1125 if a:fixed 1126 if a:x ==# 'a' 1127 call assert_fails('unlet a:x', 'E795:') 1128 call assert_fails('call remove(a:, "x")', 'E742:') 1129 elseif a:x ==# 'v' 1130 call assert_fails('unlet v:count', 'E795:') 1131 call assert_fails('call remove(v:, "count")', 'E742:') 1132 endif 1133 else 1134 exe s:gen_cmd('unlet x:foo', a:x) 1135 exe s:gen_cmd('unlet x:bar', a:x) 1136 exe s:gen_cmd('call remove(x:, "baz")', a:x) 1137 endif 1138 1139 delfunc s:gen_cmd 1140endfunc 1141 1142func Test_scope_dict() 1143 " Test for g: 1144 call s:check_scope_dict('g', v:false) 1145 1146 " Test for s: 1147 call s:check_scope_dict('s', v:false) 1148 1149 " Test for l: 1150 call s:check_scope_dict('l', v:false) 1151 1152 " Test for a: 1153 call s:check_scope_dict('a', v:true) 1154 1155 " Test for b: 1156 call s:check_scope_dict('b', v:false) 1157 1158 " Test for w: 1159 call s:check_scope_dict('w', v:false) 1160 1161 " Test for t: 1162 call s:check_scope_dict('t', v:false) 1163 1164 " Test for v: 1165 call s:check_scope_dict('v', v:true) 1166endfunc 1167 1168" Test for deep nesting of lists (> 100) 1169func Test_deep_nested_list() 1170 let deep_list = [] 1171 let l = deep_list 1172 for i in range(102) 1173 let newlist = [] 1174 call add(l, newlist) 1175 let l = newlist 1176 endfor 1177 call add(l, 102) 1178 1179 call assert_fails('let m = deepcopy(deep_list)', 'E698:') 1180 call assert_fails('lockvar 110 deep_list', 'E743:') 1181 call assert_fails('unlockvar 110 deep_list', 'E743:') 1182 call assert_fails('let x = execute("echo deep_list")', 'E724:') 1183 call test_garbagecollect_now() 1184 unlet deep_list 1185endfunc 1186 1187" Test for deep nesting of dicts (> 100) 1188func Test_deep_nested_dict() 1189 let deep_dict = {} 1190 let d = deep_dict 1191 for i in range(102) 1192 let newdict = {} 1193 let d.k = newdict 1194 let d = newdict 1195 endfor 1196 let d.k = 'v' 1197 1198 call assert_fails('let m = deepcopy(deep_dict)', 'E698:') 1199 call assert_fails('lockvar 110 deep_dict', 'E743:') 1200 call assert_fails('unlockvar 110 deep_dict', 'E743:') 1201 call assert_fails('let x = execute("echo deep_dict")', 'E724:') 1202 call test_garbagecollect_now() 1203 unlet deep_dict 1204endfunc 1205 1206" List and dict indexing tests 1207func Test_listdict_index() 1208 call assert_fails('echo function("min")[0]', 'E695:') 1209 call assert_fails('echo v:true[0]', 'E909:') 1210 let d = {'k' : 10} 1211 call assert_fails('echo d.', 'E15:') 1212 call assert_fails('echo d[1:2]', 'E719:') 1213 call assert_fails("let v = [4, 6][{-> 1}]", 'E729:') 1214 call assert_fails("let v = range(5)[2:[]]", 'E730:') 1215 call assert_fails("let v = range(5)[2:{-> 2}(]", ['E15:', 'E116:']) 1216 call assert_fails("let v = range(5)[2:3", 'E111:') 1217 call assert_fails("let l = insert([1,2,3], 4, 10)", 'E684:') 1218 call assert_fails("let l = insert([1,2,3], 4, -10)", 'E684:') 1219 call assert_fails("let l = insert([1,2,3], 4, [])", 'E745:') 1220 let l = [1, 2, 3] 1221 call assert_fails("let l[i] = 3", 'E121:') 1222 call assert_fails("let l[1.1] = 4", 'E805:') 1223 call assert_fails("let l[:i] = [4, 5]", 'E121:') 1224 call assert_fails("let l[:3.2] = [4, 5]", 'E805:') 1225 let t = test_unknown() 1226 call assert_fails("echo t[0]", 'E685:') 1227endfunc 1228 1229" Test for a null list 1230func Test_null_list() 1231 let lines =<< trim END 1232 VAR l = test_null_list() 1233 call assert_equal('', join(test_null_list())) 1234 call assert_equal('', join(l)) 1235 call assert_equal(0, len(l)) 1236 call assert_equal(1, empty(l)) 1237 call assert_equal([], split(test_null_string())) 1238 call assert_equal([], l[ : 2]) 1239 call assert_true([] == l) 1240 call assert_equal('[]', string(l)) 1241 call assert_equal([], sort(test_null_list())) 1242 call assert_equal([], sort(l)) 1243 call assert_equal([], uniq(test_null_list())) 1244 call assert_equal([], uniq(l)) 1245 VAR k = [] + l 1246 call assert_equal([], k) 1247 LET k = l + [] 1248 call assert_equal([], k) 1249 call assert_equal(0, len(copy(l))) 1250 call assert_equal(0, count(l, 5)) 1251 call assert_equal([], deepcopy(l)) 1252 call assert_equal(5, get(l, 2, 5)) 1253 call assert_equal(-1, index(l, 2, 5)) 1254 call assert_equal(0, min(l)) 1255 call assert_equal(0, max(l)) 1256 call assert_equal(0, remove(test_null_list(), 0, 2)) 1257 call assert_equal([], repeat(l, 2)) 1258 call assert_equal([], reverse(test_null_list())) 1259 call assert_equal([], reverse(l)) 1260 call assert_equal([], sort(test_null_list())) 1261 call assert_equal([], sort(l)) 1262 call assert_equal('[]', string(l)) 1263 END 1264 call CheckLegacyAndVim9Success(lines) 1265 1266 let l = test_null_list() 1267 call assert_equal([], extend(l, l, 0)) 1268 call assert_equal(0, insert(test_null_list(), 2, -1)) 1269 call assert_fails('let s = join([1, 2], [])', 'E730:') 1270 call assert_fails('call remove(l, 0, 2)', 'E684:') 1271 call assert_fails('call insert(l, 2, -1)', 'E684:') 1272 call assert_fails('call extend(test_null_list(), test_null_list())', 'E1134:') 1273 1274 lockvar l 1275 call assert_equal(1, islocked('l')) 1276 unlockvar l 1277endfunc 1278 1279" Test for a null dict 1280func Test_null_dict() 1281 let lines =<< trim END 1282 call assert_equal(test_null_dict(), test_null_dict()) 1283 VAR d = test_null_dict() 1284 call assert_equal({}, d) 1285 call assert_equal(0, len(d)) 1286 call assert_equal(1, empty(d)) 1287 call assert_equal([], items(test_null_dict())) 1288 call assert_equal([], items(d)) 1289 call assert_equal([], keys(test_null_dict())) 1290 call assert_equal([], keys(d)) 1291 call assert_equal([], values(test_null_dict())) 1292 call assert_equal([], values(d)) 1293 call assert_false(has_key(d, 'k')) 1294 call assert_equal('{}', string(d)) 1295 call assert_equal({}, {}) 1296 call assert_equal(0, len(copy(d))) 1297 call assert_equal(0, count(d, 'k')) 1298 call assert_equal({}, deepcopy(d)) 1299 call assert_equal(20, get(d, 'k', 20)) 1300 call assert_equal(0, min(d)) 1301 call assert_equal(0, max(d)) 1302 call assert_equal(0, remove(test_null_dict(), 'k')) 1303 call assert_equal('{}', string(d)) 1304 END 1305 call CheckLegacyAndVim9Success(lines) 1306 1307 let d = test_null_dict() 1308 call assert_equal({}, extend(d, d, 'keep')) 1309 call assert_fails("call remove(d, 'k')", 'E716:') 1310 call assert_fails('let x = d[10]', 'E716:') 1311 call assert_fails('call extend(test_null_dict(), test_null_dict())', 'E1133:') 1312 lockvar d 1313 call assert_equal(1, islocked('d')) 1314 unlockvar d 1315endfunc 1316 1317" vim: shiftwidth=2 sts=2 expandtab 1318