patch 8.2.4600: Vim9: not enough test coverage for executing :def function v8.2.4600
authorBram Moolenaar <Bram@vim.org>
Sun, 20 Mar 2022 17:46:06 +0000 (17:46 +0000)
committerBram Moolenaar <Bram@vim.org>
Sun, 20 Mar 2022 17:46:06 +0000 (17:46 +0000)
Problem:    Vim9: not enough test coverage for executing :def function.
Solution:   Add a few more tests.  Fix inconsistencies.

src/evalvars.c
src/proto/evalvars.pro
src/testdir/test_listdict.vim
src/testdir/test_vim9_assign.vim
src/testdir/test_vim9_cmd.vim
src/version.c
src/vim9execute.c

index 4f7252c5c68fdc0e36b61253e2471843ad594142..058e8048f6e3832ece75c870fd904fc5fed70ae4 100644 (file)
@@ -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.
index df4fb16fb291137c37ddc2b268f3b61a72267f1a..9e08f667e019a635b6a78a5e49ad67c952d5bae2 100644 (file)
@@ -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);
index 89b7f041acf98e47cd84be26f64110f6e78ff24a..38eb338bfbbc0c13a41ffe6866c5671edbe662f8 100644 (file)
@@ -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
 
index 44a8fcbefba66dd627b2741c4dcc3c6c37a7cbe2..0a25ca4a7ee23b7202921f56e253fe1319033a91 100644 (file)
@@ -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]
index 47b6f779cbcacffeeb9cef29acd8e1cd1973a795..ca63709eef19f917942cbd097ac11051ff3e4283 100644 (file)
@@ -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
index 0a6c036231efa1eed30a53b3dd4a8f7181b47382..0a070938cf2015595d9b05eae28018cc9342fc79 100644 (file)
@@ -750,6 +750,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    4600,
 /**/
     4599,
 /**/
index 5bc7708b6c2bf01ef98b1ab898bf48b8487602ee..312c5fad0f9dcd645872fe5129dd0e9b4c9627cc 100644 (file)
@@ -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);
            }
        }
     }