# HG changeset patch # User Bram Moolenaar # Date 1647799203 -3600 # Node ID b96409b84eaf4a2d226f5663b43285dd67a7c8fb # Parent ed461ca13cad4334100d459b8a1cb94a26299f0d patch 8.2.4600: Vim9: not enough test coverage for executing :def function Commit: https://github.com/vim/vim/commit/6b8c7ba062ca4b50e8f983e0485be7afa4eef691 Author: Bram Moolenaar Date: Sun Mar 20 17:46:06 2022 +0000 patch 8.2.4600: Vim9: not enough test coverage for executing :def function Problem: Vim9: not enough test coverage for executing :def function. Solution: Add a few more tests. Fix inconsistencies. diff --git a/src/evalvars.c b/src/evalvars.c --- a/src/evalvars.c +++ b/src/evalvars.c @@ -1804,20 +1804,14 @@ do_unlet_var( && value_check_lock(lp->ll_dict->dv_lock, lp->ll_name, FALSE))) return FAIL; else if (lp->ll_range) - { - if (list_unlet_range(lp->ll_list, lp->ll_li, lp->ll_name, lp->ll_n1, - !lp->ll_empty2, lp->ll_n2) == FAIL) - return FAIL; - } + list_unlet_range(lp->ll_list, lp->ll_li, lp->ll_n1, + !lp->ll_empty2, lp->ll_n2); + else if (lp->ll_list != NULL) + // unlet a List item. + listitem_remove(lp->ll_list, lp->ll_li); else - { - if (lp->ll_list != NULL) - // unlet a List item. - listitem_remove(lp->ll_list, lp->ll_li); - else - // unlet a Dictionary item. - dictitem_remove(lp->ll_dict, lp->ll_di); - } + // unlet a Dictionary item. + dictitem_remove(lp->ll_dict, lp->ll_di); return ret; } @@ -1826,11 +1820,10 @@ do_unlet_var( * Unlet one item or a range of items from a list. * Return OK or FAIL. */ - int + void list_unlet_range( list_T *l, listitem_T *li_first, - char_u *name, long n1_arg, int has_n2, long n2) @@ -1838,14 +1831,6 @@ list_unlet_range( listitem_T *li = li_first; int n1 = n1_arg; - while (li != NULL && (!has_n2 || n2 >= n1)) - { - if (value_check_lock(li->li_tv.v_lock, name, FALSE)) - return FAIL; - li = li->li_next; - ++n1; - } - // Delete a range of List items. li = li_first; n1 = n1_arg; @@ -1857,7 +1842,6 @@ list_unlet_range( li = next; ++n1; } - return OK; } /* * "unlet" a variable. Return OK if it existed, FAIL if not. diff --git a/src/proto/evalvars.pro b/src/proto/evalvars.pro --- a/src/proto/evalvars.pro +++ b/src/proto/evalvars.pro @@ -23,7 +23,7 @@ void list_hashtable_vars(hashtab_T *ht, void ex_unlet(exarg_T *eap); void ex_lockvar(exarg_T *eap); void ex_unletlock(exarg_T *eap, char_u *argstart, int deep, int glv_flags, int (*callback)(lval_T *, char_u *, exarg_T *, int, void *), void *cookie); -int list_unlet_range(list_T *l, listitem_T *li_first, char_u *name, long n1_arg, int has_n2, long n2); +void list_unlet_range(list_T *l, listitem_T *li_first, long n1_arg, int has_n2, long n2); int do_unlet(char_u *name, int forceit); void item_lock(typval_T *tv, int deep, int lock, int check_refcount); void del_menutrans_vars(void); 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 @@ -721,10 +721,13 @@ func Test_list_locked_var_unlet() endfor endfor - " Deleting a list range should fail if the range is locked + " Deleting a list range with locked items works, but changing the items + " fails. let l = [1, 2, 3, 4] lockvar l[1:2] - call assert_fails('unlet l[1:2]', 'E741:') + call assert_fails('let l[1:2] = [8, 9]', 'E741:') + unlet l[1:2] + call assert_equal([1, 4], l) unlet l endfunc diff --git a/src/testdir/test_vim9_assign.vim b/src/testdir/test_vim9_assign.vim --- a/src/testdir/test_vim9_assign.vim +++ b/src/testdir/test_vim9_assign.vim @@ -2209,6 +2209,11 @@ def Test_unlet() unlet dd[4] assert_equal({b: 2}, dd) + # null key works like empty string + dd = {'': 1, x: 9} + unlet dd[null_string] + assert_equal({x: 9}, dd) + # list unlet var ll = [1, 2, 3, 4] unlet ll[1] diff --git a/src/testdir/test_vim9_cmd.vim b/src/testdir/test_vim9_cmd.vim --- a/src/testdir/test_vim9_cmd.vim +++ b/src/testdir/test_vim9_cmd.vim @@ -1573,6 +1573,36 @@ def Test_lockvar() END v9.CheckScriptFailure(lines, 'E741', 2) + # can unlet a locked list item but not change it + lines =<< trim END + var ll = [1, 2, 3] + lockvar ll[1] + unlet ll[1] + assert_equal([1, 3], ll) + END + v9.CheckDefAndScriptSuccess(lines) + lines =<< trim END + var ll = [1, 2, 3] + lockvar ll[1] + ll[1] = 9 + END + v9.CheckDefExecAndScriptFailure(lines, ['E1119:', 'E741'], 3) + + # can unlet a locked dict item but not change it + lines =<< trim END + var dd = {a: 1, b: 2} + lockvar dd.a + unlet dd.a + assert_equal({b: 2}, dd) + END + v9.CheckDefAndScriptSuccess(lines) + lines =<< trim END + var dd = {a: 1, b: 2} + lockvar dd.a + dd.a = 3 + END + v9.CheckDefExecAndScriptFailure(lines, ['E1121:', 'E741'], 3) + lines =<< trim END var theList = [1, 2, 3] lockvar theList diff --git a/src/version.c b/src/version.c --- a/src/version.c +++ b/src/version.c @@ -751,6 +751,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ /**/ + 4600, +/**/ 4599, /**/ 4598, diff --git a/src/vim9execute.c b/src/vim9execute.c --- a/src/vim9execute.c +++ b/src/vim9execute.c @@ -2048,9 +2048,6 @@ execute_unletindex(isn_T *iptr, ectx_T * semsg(_(e_list_index_out_of_range_nr), n); status = FAIL; } - else if (value_check_lock(li->li_tv.v_lock, - NULL, FALSE)) - status = FAIL; else listitem_remove(l, li); } @@ -2133,11 +2130,9 @@ execute_unletrange(isn_T *iptr, ectx_T * semsg(_(e_list_index_out_of_range_nr), n2); status = FAIL; } - if (status != FAIL - && list_unlet_range(l, li, NULL, n1, - tv_idx2->v_type != VAR_SPECIAL, n2) - == FAIL) - status = FAIL; + if (status != FAIL) + list_unlet_range(l, li, n1, + tv_idx2->v_type != VAR_SPECIAL, n2); } } }