From 6b8c7ba062ca4b50e8f983e0485be7afa4eef691 Mon Sep 17 00:00:00 2001 From: Bram Moolenaar Date: Sun, 20 Mar 2022 17:46:06 +0000 Subject: 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. --- src/evalvars.c | 32 ++++++++------------------------ src/proto/evalvars.pro | 2 +- src/testdir/test_listdict.vim | 7 +++++-- src/testdir/test_vim9_assign.vim | 5 +++++ src/testdir/test_vim9_cmd.vim | 30 ++++++++++++++++++++++++++++++ src/version.c | 2 ++ src/vim9execute.c | 11 +++-------- 7 files changed, 54 insertions(+), 35 deletions(-) diff --git a/src/evalvars.c b/src/evalvars.c index 4f7252c5c6..058e8048f6 100644 --- 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 index df4fb16fb2..9e08f667e0 100644 --- a/src/proto/evalvars.pro +++ b/src/proto/evalvars.pro @@ -23,7 +23,7 @@ void list_hashtable_vars(hashtab_T *ht, char *prefix, int empty, int *first); 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 index 89b7f041ac..38eb338bfb 100644 --- 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 index 44a8fcbefb..0a25ca4a7e 100644 --- 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 index 47b6f779cb..ca63709eef 100644 --- 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 index 0a6c036231..0a070938cf 100644 --- a/src/version.c +++ b/src/version.c @@ -750,6 +750,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ +/**/ + 4600, /**/ 4599, /**/ diff --git a/src/vim9execute.c b/src/vim9execute.c index 5bc7708b6c..312c5fad0f 100644 --- a/src/vim9execute.c +++ b/src/vim9execute.c @@ -2048,9 +2048,6 @@ execute_unletindex(isn_T *iptr, ectx_T *ectx) 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 *ectx) 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); } } } -- cgit v1.2.3