# HG changeset patch # User Bram Moolenaar # Date 1626813005 -7200 # Node ID a386f83499edbde0fa5d2eb94962a7741ffe0c88 # Parent 10e0c155813d1c890d8d71e25d6d0a3932406339 patch 8.2.3191: Vim9: not enough code is tested Commit: https://github.com/vim/vim/commit/63cb6567f0153c35dc75cbc09039ff5d0a7b60e3 Author: Bram Moolenaar Date: Tue Jul 20 22:21:59 2021 +0200 patch 8.2.3191: Vim9: not enough code is tested Problem: Vim9: not enough code is tested. Solution: Use CheckLegacyAndVim9Success() in more places. Fix uncovered problems. diff --git a/src/testdir/test_listdict.vim b/src/testdir/test_listdict.vim --- a/src/testdir/test_listdict.vim +++ b/src/testdir/test_listdict.vim @@ -1,5 +1,7 @@ " Tests for the List and Dict types +source vim9.vim + func TearDown() " Run garbage collection after every test call test_garbagecollect_now() @@ -44,66 +46,87 @@ endfunc " List identity func Test_list_identity() - let l = [1, 'as''d', [1, 2, function("strlen")], {'a': 1},] - let ll = l - let lx = copy(l) - call assert_true(l == ll) - call assert_false(l isnot ll) - call assert_true(l is ll) - call assert_true(l == lx) - call assert_false(l is lx) - call assert_true(l isnot lx) + let lines =<< trim END + VAR l = [1, 'as''d', [1, 2, function("strlen")], {'a': 1},] + VAR ll = l + VAR lx = copy(l) + call assert_true(l == ll) + call assert_false(l isnot ll) + call assert_true(l is ll) + call assert_true(l == lx) + call assert_false(l is lx) + call assert_true(l isnot lx) + END + call CheckLegacyAndVim9Success(lines) endfunc " removing items with :unlet func Test_list_unlet() - let l = [1, 'as''d', [1, 2, function("strlen")], {'a': 1},] - unlet l[2] - call assert_equal([1, 'as''d', {'a': 1}], l) - let l = range(8) - unlet l[:3] - unlet l[1:] - call assert_equal([4], l) + let lines =<< trim END + VAR l = [1, 'as''d', [1, 2, function("strlen")], {'a': 1},] + unlet l[2] + call assert_equal([1, 'as''d', {'a': 1}], l) + LET l = range(8) + unlet l[: 3] + unlet l[1 :] + call assert_equal([4], l) - " removing items out of range: silently skip items that don't exist - let l = [0, 1, 2, 3] - call assert_fails('unlet l[2:1]', 'E684:') + #" removing items out of range: silently skip items that don't exist + LET l = [0, 1, 2, 3] + unlet l[2 : 2] + call assert_equal([0, 1, 3], l) + LET l = [0, 1, 2, 3] + unlet l[2 : 3] + call assert_equal([0, 1], l) + LET l = [0, 1, 2, 3] + unlet l[2 : 4] + call assert_equal([0, 1], l) + LET l = [0, 1, 2, 3] + unlet l[2 : 5] + call assert_equal([0, 1], l) + LET l = [0, 1, 2, 3] + unlet l[-2 : 2] + call assert_equal([0, 1, 3], l) + LET l = [0, 1, 2, 3] + unlet l[-3 : 2] + call assert_equal([0, 3], l) + LET l = [0, 1, 2, 3] + unlet l[-4 : 2] + call assert_equal([3], l) + LET l = [0, 1, 2, 3] + unlet l[-5 : 2] + call assert_equal([3], l) + LET l = [0, 1, 2, 3] + unlet l[-6 : 2] + call assert_equal([3], l) + END + call CheckLegacyAndVim9Success(lines) + let l = [0, 1, 2, 3] unlet l[2:2] call assert_equal([0, 1, 3], l) let l = [0, 1, 2, 3] unlet l[2:3] call assert_equal([0, 1], l) + let l = [0, 1, 2, 3] - unlet l[2:4] - call assert_equal([0, 1], l) - let l = [0, 1, 2, 3] - unlet l[2:5] - call assert_equal([0, 1], l) + call assert_fails('unlet l[2:1]', 'E684:') let l = [0, 1, 2, 3] call assert_fails('unlet l[-1:2]', 'E684:') - let l = [0, 1, 2, 3] - unlet l[-2:2] - call assert_equal([0, 1, 3], l) - let l = [0, 1, 2, 3] - unlet l[-3:2] - call assert_equal([0, 3], l) - let l = [0, 1, 2, 3] - unlet l[-4:2] - call assert_equal([3], l) - let l = [0, 1, 2, 3] - unlet l[-5:2] - call assert_equal([3], l) - let l = [0, 1, 2, 3] - unlet l[-6:2] - call assert_equal([3], l) endfunc " assignment to a list func Test_list_assign() + let lines =<< trim END + VAR l = [0, 1, 2, 3] + VAR va = 0 + VAR vb = 0 + LET [va, vb] = l[2 : 3] + call assert_equal([2, 3], [va, vb]) + END + call CheckLegacyAndVim9Success(lines) + let l = [0, 1, 2, 3] - let [va, vb] = l[2:3] - call assert_equal([2, 3], [va, vb]) call assert_fails('let [va, vb] = l', 'E687:') call assert_fails('let [va, vb] = l[1:1]', 'E688:') endfunc @@ -119,31 +142,34 @@ endfunc " Test removing items in list func Test_list_func_remove() - " Test removing 1 element - let l = [1, 2, 3, 4] - call assert_equal(1, remove(l, 0)) - call assert_equal([2, 3, 4], l) + let lines =<< trim END + #" Test removing 1 element + VAR l = [1, 2, 3, 4] + call assert_equal(1, remove(l, 0)) + call assert_equal([2, 3, 4], l) - let l = [1, 2, 3, 4] - call assert_equal(2, remove(l, 1)) - call assert_equal([1, 3, 4], l) + LET l = [1, 2, 3, 4] + call assert_equal(2, remove(l, 1)) + call assert_equal([1, 3, 4], l) - let l = [1, 2, 3, 4] - call assert_equal(4, remove(l, -1)) - call assert_equal([1, 2, 3], l) + LET l = [1, 2, 3, 4] + call assert_equal(4, remove(l, -1)) + call assert_equal([1, 2, 3], l) - " Test removing range of element(s) - let l = [1, 2, 3, 4] - call assert_equal([3], remove(l, 2, 2)) - call assert_equal([1, 2, 4], l) + #" Test removing range of element(s) + LET l = [1, 2, 3, 4] + call assert_equal([3], remove(l, 2, 2)) + call assert_equal([1, 2, 4], l) - let l = [1, 2, 3, 4] - call assert_equal([2, 3], remove(l, 1, 2)) - call assert_equal([1, 4], l) + LET l = [1, 2, 3, 4] + call assert_equal([2, 3], remove(l, 1, 2)) + call assert_equal([1, 4], l) - let l = [1, 2, 3, 4] - call assert_equal([2, 3], remove(l, -3, -2)) - call assert_equal([1, 4], l) + LET l = [1, 2, 3, 4] + call assert_equal([2, 3], remove(l, -3, -2)) + call assert_equal([1, 4], l) + END + call CheckLegacyAndVim9Success(lines) " Test invalid cases let l = [1, 2, 3, 4] @@ -156,15 +182,20 @@ endfunc " List add() function func Test_list_add() - let l = [] - call add(l, 1) - call add(l, [2, 3]) - call add(l, []) - call add(l, test_null_list()) - call add(l, {'k' : 3}) - call add(l, {}) - call add(l, test_null_dict()) - call assert_equal([1, [2, 3], [], [], {'k' : 3}, {}, {}], l) + let lines =<< trim END + VAR l = [] + call add(l, 1) + call add(l, [2, 3]) + call add(l, []) + call add(l, test_null_list()) + call add(l, {'k': 3}) + call add(l, {}) + call add(l, test_null_dict()) + call assert_equal([1, [2, 3], [], [], {'k': 3}, {}, {}], l) + END + call CheckLegacyAndVim9Success(lines) + + " weird legacy behavior call assert_equal(1, add(test_null_list(), 4)) endfunc @@ -172,11 +203,21 @@ endfunc func Test_dict() " Creating Dictionary directly with different types + let lines =<< trim END + VAR d = {'1': 'asd', 'b': [1, 2, function('strlen')], '-1': {'a': 1}, } + call assert_equal("{'1': 'asd', 'b': [1, 2, function('strlen')], '-1': {'a': 1}}", string(d)) + call assert_equal('asd', d.1) + call assert_equal(['-1', '1', 'b'], sort(keys(d))) + call assert_equal(['asd', [1, 2, function('strlen')], {'a': 1}], values(d)) + call extend(d, {3: 33, 1: 99}) + call extend(d, {'b': 'bbb', 'c': 'ccc'}, "keep") + call assert_equal({'c': 'ccc', '1': 99, 'b': [1, 2, function('strlen')], '3': 33, '-1': {'a': 1}}, d) + END + call CheckLegacyAndVim9Success(lines) + let d = {001: 'asd', 'b': [1, 2, function('strlen')], -1: {'a': 1},} call assert_equal("{'1': 'asd', 'b': [1, 2, function('strlen')], '-1': {'a': 1}}", string(d)) - call assert_equal('asd', d.1) - call assert_equal(['-1', '1', 'b'], sort(keys(d))) - call assert_equal(['asd', [1, 2, function('strlen')], {'a': 1}], values(d)) + let v = [] for [key, val] in items(d) call extend(v, [key, val]) @@ -184,12 +225,8 @@ func Test_dict() endfor call assert_equal(['1','asd','b',[1, 2, function('strlen')],'-1',{'a': 1}], v) - call extend(d, {3:33, 1:99}) - call extend(d, {'b':'bbb', 'c':'ccc'}, "keep") + call extend(d, {3: 33, 1: 99}) call assert_fails("call extend(d, {3:333,4:444}, 'error')", 'E737:') - call assert_equal({'c': 'ccc', '1': 99, 'b': [1, 2, function('strlen')], '3': 33, '-1': {'a': 1}}, d) - call filter(d, 'v:key =~ ''[ac391]''') - call assert_equal({'c': 'ccc', '1': 99, '3': 33, '-1': {'a': 1}}, d) " duplicate key call assert_fails("let d = {'k' : 10, 'k' : 20}", 'E721:') diff --git a/src/version.c b/src/version.c --- a/src/version.c +++ b/src/version.c @@ -756,6 +756,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ /**/ + 3191, +/**/ 3190, /**/ 3189, diff --git a/src/vim9compile.c b/src/vim9compile.c --- a/src/vim9compile.c +++ b/src/vim9compile.c @@ -6599,7 +6599,7 @@ compile_assign_unlet( return FAIL; } type = ((type_T **)stack->ga_data)[stack->ga_len - 1]; - if ((dest_type != VAR_BLOB || type != &t_special) + if ((dest_type != VAR_BLOB && type != &t_special) && need_type(type, &t_number, -1, 0, cctx, FALSE, FALSE) == FAIL) return FAIL; diff --git a/src/vim9execute.c b/src/vim9execute.c --- a/src/vim9execute.c +++ b/src/vim9execute.c @@ -2679,7 +2679,8 @@ exec_instructions(ectx_T *ectx) // indexes must be a number SOURCING_LNUM = iptr->isn_lnum; if (check_for_number(tv_idx1) == FAIL - || check_for_number(tv_idx2) == FAIL) + || (tv_idx2->v_type != VAR_SPECIAL + && check_for_number(tv_idx2) == FAIL)) { status = FAIL; } @@ -2687,14 +2688,32 @@ exec_instructions(ectx_T *ectx) { list_T *l = tv_dest->vval.v_list; long n1 = (long)tv_idx1->vval.v_number; - long n2 = (long)tv_idx2->vval.v_number; + long n2 = tv_idx2->v_type == VAR_SPECIAL + ? 0 : (long)tv_idx2->vval.v_number; listitem_T *li; li = list_find_index(l, &n1); - if (li == NULL - || list_unlet_range(l, li, NULL, n1, - TRUE, n2) == FAIL) + if (li == NULL) status = FAIL; + else + { + if (n1 < 0) + n1 = list_idx_of_item(l, li); + if (n2 < 0) + { + listitem_T *li2 = list_find(l, n2); + + if (li2 == NULL) + status = FAIL; + else + n2 = list_idx_of_item(l, li2); + } + if (status != FAIL + && list_unlet_range(l, li, NULL, n1, + tv_idx2->v_type != VAR_SPECIAL, n2) + == FAIL) + status = FAIL; + } } } else