changeset 35190:ddd5eaa2c0dc v9.1.0415

patch 9.1.0415: Some functions are not tested Commit: https://github.com/vim/vim/commit/fe424d13ef6e5486923f23f15bb6951e3079412e Author: Yegappan Lakshmanan <yegappan@yahoo.com> Date: Fri May 17 18:20:43 2024 +0200 patch 9.1.0415: Some functions are not tested Problem: Some functions are not tested Solution: Add a few more tests, fix a few minor problems (Yegappan Lakshmanan) closes: #14789 Signed-off-by: Yegappan Lakshmanan <yegappan@yahoo.com> Signed-off-by: Christian Brabandt <cb@256bit.org>
author Christian Brabandt <cb@256bit.org>
date Fri, 17 May 2024 18:30:06 +0200
parents 945f1fec1802
children 39d9649a3ca9
files src/eval.c src/evalfunc.c src/testdir/test_blob.vim src/testdir/test_edit.vim src/testdir/test_fold.vim src/testdir/test_functions.vim src/testdir/test_listdict.vim src/testdir/test_method.vim src/testdir/test_partial.vim src/testdir/test_vim9_assign.vim src/testdir/test_vim9_builtin.vim src/testdir/test_vim9_expr.vim src/testdir/test_vim9_import.vim src/testdir/test_vim9_script.vim src/testdir/test_vimscript.vim src/version.c
diffstat 16 files changed, 184 insertions(+), 14 deletions(-) [+]
line wrap: on
line diff
--- a/src/eval.c
+++ b/src/eval.c
@@ -2281,9 +2281,16 @@ tv_op_blob(typval_T *tv1, typval_T *tv2,
 	return FAIL;
 
     // Blob += Blob
-    if (tv1->vval.v_blob == NULL || tv2->vval.v_blob == NULL)
+    if (tv2->vval.v_blob == NULL)
 	return OK;
 
+    if (tv1->vval.v_blob == NULL)
+    {
+	tv1->vval.v_blob = tv2->vval.v_blob;
+	++tv1->vval.v_blob->bv_refcount;
+	return OK;
+    }
+
     blob_T	*b1 = tv1->vval.v_blob;
     blob_T	*b2 = tv2->vval.v_blob;
     int		len = blob_len(b2);
@@ -2455,12 +2462,6 @@ tv_op(typval_T *tv1, typval_T *tv2, char
 	return FAIL;
     }
 
-    if (tv2->v_type == VAR_CLASS || tv2->v_type == VAR_TYPEALIAS)
-    {
-	check_typval_is_value(tv2);
-	return FAIL;
-    }
-
     int retval = FAIL;
     switch (tv1->v_type)
     {
@@ -2476,12 +2477,9 @@ tv_op(typval_T *tv1, typval_T *tv2, char
 	case VAR_CHANNEL:
 	case VAR_INSTR:
 	case VAR_OBJECT:
-	    break;
-
 	case VAR_CLASS:
 	case VAR_TYPEALIAS:
-	    check_typval_is_value(tv1);
-	    return FAIL;
+	    break;
 
 	case VAR_BLOB:
 	    retval = tv_op_blob(tv1, tv2, op);
@@ -5162,7 +5160,7 @@ eval_method(
 	{
 	    *arg = name;
 
-	    // Truncate the name a the "(".  Avoid trying to get another line
+	    // Truncate the name at the "(".  Avoid trying to get another line
 	    // by making "getline" NULL.
 	    *paren = NUL;
 	    char_u	*(*getline)(int, void *, int, getline_opt_T) = NULL;
@@ -5217,6 +5215,9 @@ eval_method(
 	clear_tv(&base);
     vim_free(tofree);
 
+    if (alias != NULL)
+	vim_free(alias);
+
     return ret;
 }
 
@@ -5434,7 +5435,7 @@ f_slice(typval_T *argvars, typval_T *ret
 		|| check_for_opt_number_arg(argvars, 2) == FAIL))
 	return;
 
-    if (check_can_index(argvars, TRUE, FALSE) != OK)
+    if (check_can_index(&argvars[0], TRUE, FALSE) != OK)
 	return;
 
     copy_tv(argvars, rettv);
--- a/src/evalfunc.c
+++ b/src/evalfunc.c
@@ -7533,6 +7533,7 @@ indexof_blob(blob_T *b, long startidx, t
     set_vim_var_type(VV_KEY, VAR_NUMBER);
     set_vim_var_type(VV_VAL, VAR_NUMBER);
 
+    int		called_emsg_start = called_emsg;
     for (idx = startidx; idx < blob_len(b); ++idx)
     {
 	set_vim_var_nr(VV_KEY, idx);
@@ -7540,6 +7541,9 @@ indexof_blob(blob_T *b, long startidx, t
 
 	if (indexof_eval_expr(expr))
 	    return idx;
+
+	if (called_emsg != called_emsg_start)
+	    return -1;
     }
 
     return -1;
@@ -7575,6 +7579,7 @@ indexof_list(list_T *l, long startidx, t
 
     set_vim_var_type(VV_KEY, VAR_NUMBER);
 
+    int		called_emsg_start = called_emsg;
     for ( ; item != NULL; item = item->li_next, ++idx)
     {
 	set_vim_var_nr(VV_KEY, idx);
@@ -7585,6 +7590,9 @@ indexof_list(list_T *l, long startidx, t
 
 	if (found)
 	    return idx;
+
+	if (called_emsg != called_emsg_start)
+	    return -1;
     }
 
     return -1;
@@ -7608,7 +7616,9 @@ f_indexof(typval_T *argvars, typval_T *r
 	    || check_for_opt_dict_arg(argvars, 2) == FAIL)
 	return;
 
-    if ((argvars[1].v_type == VAR_STRING && argvars[1].vval.v_string == NULL)
+    if ((argvars[1].v_type == VAR_STRING &&
+		(argvars[1].vval.v_string == NULL
+		 || *argvars[1].vval.v_string == NUL))
 	    || (argvars[1].v_type == VAR_FUNC
 		&& argvars[1].vval.v_partial == NULL))
 	return;
--- a/src/testdir/test_blob.vim
+++ b/src/testdir/test_blob.vim
@@ -74,6 +74,13 @@ func Test_blob_assign()
       VAR l = [0z12]
       VAR m = deepcopy(l)
       LET m[0] = 0z34	#" E742 or E741 should not occur.
+
+      VAR blob1 = 0z10
+      LET blob1 += test_null_blob()
+      call assert_equal(0z10, blob1)
+      LET blob1 = test_null_blob()
+      LET blob1 += 0z20
+      call assert_equal(0z20, blob1)
   END
   call v9.CheckLegacyAndVim9Success(lines)
 
@@ -343,6 +350,17 @@ func Test_blob_for_loop()
       call assert_equal(5, i)
   END
   call v9.CheckLegacyAndVim9Success(lines)
+
+  " Test for skipping the loop var assignment in a for loop
+  let lines =<< trim END
+    VAR blob = 0z998877
+    VAR c = 0
+    for _ in blob
+      LET c += 1
+    endfor
+    call assert_equal(3, c)
+  END
+  call v9.CheckLegacyAndVim9Success(lines)
 endfunc
 
 func Test_blob_concatenate()
@@ -831,6 +849,7 @@ func Test_indexof()
   call assert_equal(-1, indexof(test_null_blob(), "v:val == 0xde"))
   call assert_equal(-1, indexof(b, test_null_string()))
   call assert_equal(-1, indexof(b, test_null_function()))
+  call assert_equal(-1, indexof(b, ""))
 
   let b = 0z01020102
   call assert_equal(1, indexof(b, "v:val == 0x02", #{startidx: 0}))
@@ -842,6 +861,7 @@ func Test_indexof()
   " failure cases
   call assert_fails('let i = indexof(b, "val == 0xde")', 'E121:')
   call assert_fails('let i = indexof(b, {})', 'E1256:')
+  call assert_fails('let i = indexof(b, " ")', 'E15:')
 endfunc
 
 " vim: shiftwidth=2 sts=2 expandtab
--- a/src/testdir/test_edit.vim
+++ b/src/testdir/test_edit.vim
@@ -1952,6 +1952,11 @@ func Test_edit_insert_reg()
   let @r = 'sample'
   call feedkeys("a\<C-R>=SaveFirstLine()\<CR>", "xt")
   call assert_equal('"', g:Line)
+
+  " Test for inserting an null and an empty list
+  call feedkeys("a\<C-R>=test_null_list()\<CR>", "xt")
+  call feedkeys("a\<C-R>=[]\<CR>", "xt")
+  call assert_equal(['r'], getbufline('', 1, '$'))
   call test_override('ALL', 0)
   close!
 endfunc
--- a/src/testdir/test_fold.vim
+++ b/src/testdir/test_fold.vim
@@ -1601,6 +1601,34 @@ func Test_foldtext_scriptlocal_func()
   delfunc s:FoldText
 endfunc
 
+" Test for setting 'foldtext' from the modeline and executing the expression
+" in a sandbox
+func Test_foldtext_in_modeline()
+  func ModelineFoldText()
+    call feedkeys('aFoo', 'xt')
+    return "folded text"
+  endfunc
+  let lines =<< trim END
+    func T()
+      let i = 1
+    endfunc
+    " vim: foldenable foldtext=ModelineFoldText()
+  END
+  call writefile(lines, 'Xmodelinefoldtext', 'D')
+
+  set modeline modelineexpr
+  split Xmodelinefoldtext
+
+  call cursor(1, 1)
+  normal! zf3j
+  call assert_equal('folded text', foldtextresult(1))
+  call assert_equal(lines, getbufline('', 1, '$'))
+
+  bw!
+  set modeline& modelineexpr&
+  delfunc ModelineFoldText
+endfunc
+
 " Make sure a fold containing a nested fold is split correctly when using
 " foldmethod=indent
 func Test_fold_split()
--- a/src/testdir/test_functions.vim
+++ b/src/testdir/test_functions.vim
@@ -4106,6 +4106,8 @@ func Test_slice()
     call assert_equal('', 'ὰ̳β̳́γ̳̂δ̳̃ε̳̄ζ̳̅'->slice(1, -6))
   END
   call v9.CheckLegacyAndVim9Success(lines)
+
+  call assert_equal(0, slice(v:true, 1))
 endfunc
 
 " vim: shiftwidth=2 sts=2 expandtab
--- a/src/testdir/test_listdict.vim
+++ b/src/testdir/test_listdict.vim
@@ -60,6 +60,9 @@ func Test_list_slice()
       assert_equal([1, 2], l[-3 : -1])
   END
   call v9.CheckDefAndScriptSuccess(lines)
+
+  call assert_fails('let l[[]] = 1', 'E730: Using a List as a String')
+  call assert_fails('let l[1 : []] = [1]', 'E730: Using a List as a String')
 endfunc
 
 " List identity
@@ -178,6 +181,19 @@ func Test_list_assign()
   END
   call v9.CheckScriptFailure(['vim9script'] + lines, 'E688:')
   call v9.CheckDefExecFailure(lines, 'E1093: Expected 2 items but got 1')
+
+  let lines =<< trim END
+    VAR l = [2]
+    LET l += test_null_list()
+    call assert_equal([2], l)
+    LET l = test_null_list()
+    LET l += [1]
+    call assert_equal([1], l)
+  END
+  call v9.CheckLegacyAndVim9Success(lines)
+
+  let d = {'abc': [1, 2, 3]}
+  call assert_fails('let d.abc[0:0z10] = [10, 20]', 'E976: Using a Blob as a String')
 endfunc
 
 " test for range assign
@@ -447,6 +463,9 @@ func Test_dict_assign()
     n.key = 3
   END
   call v9.CheckDefFailure(lines, 'E1141:')
+
+  let d = {'abc': {}}
+  call assert_fails("let d.abc[0z10] = 10", 'E976: Using a Blob as a String')
 endfunc
 
 " Function in script-local List or Dict
@@ -1505,6 +1524,8 @@ func Test_indexof()
   call assert_equal(-1, indexof(test_null_list(), {i, v -> v == 'a'}))
   call assert_equal(-1, indexof(l, test_null_string()))
   call assert_equal(-1, indexof(l, test_null_function()))
+  call assert_equal(-1, indexof(l, ""))
+  call assert_fails('let i = indexof(l, " ")', 'E15:')
 
   " failure cases
   call assert_fails('let i = indexof(l, "v:val == ''cyan''")', 'E735:')
--- a/src/testdir/test_method.vim
+++ b/src/testdir/test_method.vim
@@ -136,6 +136,13 @@ func Test_method_syntax()
   call assert_fails('eval [1, 2, 3] ->sort ()', 'E274:')
   call assert_fails('eval [1, 2, 3]-> sort ()', 'E274:')
   call assert_fails('eval [1, 2, 3]-> sort()', 'E274:')
+
+  " Test for using a method name containing a curly brace name
+  let s = 'len'
+  call assert_equal(4, "xxxx"->str{s}())
+
+  " Test for using a method in an interpolated string
+  call assert_equal('4', $'{"xxxx"->strlen()}')
 endfunc
 
 func Test_method_lambda()
--- a/src/testdir/test_partial.vim
+++ b/src/testdir/test_partial.vim
@@ -406,4 +406,18 @@ func Test_compare_partials()
   call assert_false(F1 is N1)
 endfunc
 
+func Test_partial_method()
+  func Foo(x, y, z)
+    return x + y + z
+  endfunc
+  let d = {"Fn": function('Foo', [10, 20])}
+  call assert_fails('echo 30->d.Fn()', 'E1265: Cannot use a partial here')
+  delfunc Foo
+endfunc
+
+func Test_non_callable_type_as_method()
+  let d = {"Fn": 10}
+  call assert_fails('echo 30->d.Fn()', 'E1085: Not a callable type: d.Fn')
+endfunc
+
 " vim: shiftwidth=2 sts=2 expandtab
--- a/src/testdir/test_vim9_assign.vim
+++ b/src/testdir/test_vim9_assign.vim
@@ -3687,4 +3687,16 @@ def Test_final_var_with_blob_value()
   v9.CheckScriptSuccess(lines)
 enddef
 
+" Test for overwriting a script-local function using the s: dictionary
+def Test_override_script_local_func()
+  var lines =<< trim END
+    vim9script
+    def MyFunc()
+    enddef
+    var d: dict<any> = s:
+    d.MyFunc = function('min')
+  END
+  v9.CheckScriptFailure(lines, 'E705: Variable name conflicts with existing function: MyFunc', 5)
+enddef
+
 " vim: ts=8 sw=2 sts=2 expandtab tw=80 fdm=marker
--- a/src/testdir/test_vim9_builtin.vim
+++ b/src/testdir/test_vim9_builtin.vim
@@ -2195,6 +2195,7 @@ def Test_indexof()
   indexof(l, (i, v) => v.color == 'blue')->assert_equal(1)
   indexof(l, (i, v) => v.color == 'blue', {startidx: 1})->assert_equal(1)
   indexof(l, (i, v) => v.color == 'blue', {startidx: 2})->assert_equal(3)
+  indexof(l, "")->assert_equal(-1)
   var b = 0zdeadbeef
   indexof(b, "v:val == 0xef")->assert_equal(3)
 
--- a/src/testdir/test_vim9_expr.vim
+++ b/src/testdir/test_vim9_expr.vim
@@ -309,6 +309,9 @@ def Test_expr2()
         g:vals = [1]
       endif
       assert_equal([1], g:vals)
+
+      # string interpolation with ||
+      assert_equal('true', $"{0 || 1}")
   END
   v9.CheckDefAndScriptSuccess(lines)
 
@@ -415,6 +418,7 @@ def Test_expr2_fails()
   v9.CheckDefExecAndScriptFailure(['var x = 3', 'if x', 'endif'], 'E1023:', 2)
 
   v9.CheckDefAndScriptFailure(["var x = [] || false"], ['E1012: Type mismatch; expected bool but got list<any>', 'E745:'], 1)
+  v9.CheckDefAndScriptFailure(["var x = $'{false || []}'"], ['E1012: Type mismatch; expected bool but got list<any>', 'E745:'], 1)
 
   var lines =<< trim END
     vim9script
@@ -475,6 +479,9 @@ def Test_expr3()
         failed = true
       endif
       assert_false(failed)
+
+      # string interpolation with &&
+      assert_equal('false', $"{1 && 0}")
   END
   v9.CheckDefAndScriptSuccess(lines)
 enddef
@@ -574,6 +581,8 @@ def Test_expr3_fails()
       echo true && s
   END
   v9.CheckDefAndScriptFailure(lines, ['E1012: Type mismatch; expected bool but got string', 'E1135: Using a String as a Bool: "asdf"'])
+
+  v9.CheckDefAndScriptFailure(["var x = $'{true && []}'"], ['E1012: Type mismatch; expected bool but got list<any>', 'E745:'], 1)
 enddef
 
 " global variables to use for tests with the "any" type
@@ -2152,6 +2161,7 @@ def Test_expr9_blob()
   v9.CheckDefAndScriptSuccess(lines)
 
   v9.CheckDefAndScriptFailure(["var x = 0z123"], 'E973:', 1)
+  v9.CheckDefAndScriptFailure(["var x = null_blox"], ['E1001:', 'E121:'], 1)
 enddef
 
 def Test_expr9_string()
--- a/src/testdir/test_vim9_import.vim
+++ b/src/testdir/test_vim9_import.vim
@@ -3311,4 +3311,20 @@ def Test_import_from_vimrc()
   delete('Xoutput.log')
 enddef
 
+" Test for changing a locked imported variable
+def Test_import_locked_var()
+  var lines =<< trim END
+    vim9script
+    export var Foo: number = 10
+    lockvar Foo
+  END
+  writefile(lines, 'Ximportlockedvar.vim', 'D')
+  lines =<< trim END
+    vim9script
+    import './Ximportlockedvar.vim' as Bar
+    Bar.Foo = 20
+  END
+  v9.CheckScriptFailure(lines, 'E741: Value is locked: Foo', 3)
+enddef
+
 " vim: ts=8 sw=2 sts=2 expandtab tw=80 fdm=marker
--- a/src/testdir/test_vim9_script.vim
+++ b/src/testdir/test_vim9_script.vim
@@ -2512,6 +2512,13 @@ def Test_for_loop()
       assert_equal(['x', 'x', 'x'], reslist)
   END
   v9.CheckDefAndScriptSuccess(lines)
+
+  lines =<< trim END
+    for i : number : [1, 2]
+      echo i
+    endfor
+  END
+  v9.CheckSourceDefAndScriptFailure(lines, 'E1059: No white space allowed before colon: : [1, 2]', 1)
 enddef
 
 def Test_for_loop_list_of_lists()
@@ -5096,6 +5103,13 @@ def Test_unknown_type_in_typecast()
     var Fn = <funcx(number, number): number>b
   END
   v9.CheckSourceFailure(lines, 'E1010: Type not recognized: funcx(number, number): number', 2)
+
+  # Wrong type in a type cast
+  lines =<< trim END
+    vim9script
+    var i: number = <number>true
+  END
+  v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected number but got bool', 2)
 enddef
 
 " Keep this last, it messes up highlighting.
--- a/src/testdir/test_vimscript.vim
+++ b/src/testdir/test_vimscript.vim
@@ -7509,6 +7509,13 @@ func Test_for_over_string()
     let res ..= c .. '-'
   endfor
   call assert_equal('', res)
+
+  " Test for ignoring loop var assignment
+  let c = 0
+  for _ in 'abc'
+    let c += 1
+  endfor
+  call assert_equal(3, c)
 endfunc
 
 " Test for deeply nested :source command  {{{1
--- a/src/version.c
+++ b/src/version.c
@@ -705,6 +705,8 @@ static char *(features[]) =
 static int included_patches[] =
 {   /* Add new patch number below this line */
 /**/
+    415,
+/**/
     414,
 /**/
     413,