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