From 619cb143f93fbf75adde9710415a74d36c8eb63d Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Tue, 30 Jul 2024 13:38:13 +0800 Subject: [PATCH] vim-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: vim/vim#14789 https://github.com/vim/vim/commit/fe424d13ef6e5486923f23f15bb6951e3079412e Co-authored-by: Yegappan Lakshmanan --- src/nvim/eval.c | 6 +++++- src/nvim/eval/executor.c | 8 +++++++- src/nvim/eval/funcs.c | 13 ++++++++++++- test/functional/legacy/edit_spec.lua | 6 ++++++ test/old/testdir/test_blob.vim | 20 ++++++++++++++++++++ test/old/testdir/test_edit.vim | 5 +++++ test/old/testdir/test_fold.vim | 28 ++++++++++++++++++++++++++++ test/old/testdir/test_functions.vim | 2 ++ test/old/testdir/test_listdict.vim | 21 +++++++++++++++++++++ test/old/testdir/test_method.vim | 7 +++++++ test/old/testdir/test_partial.vim | 14 ++++++++++++++ test/old/testdir/test_vimscript.vim | 7 +++++++ 12 files changed, 134 insertions(+), 3 deletions(-) diff --git a/src/nvim/eval.c b/src/nvim/eval.c index 176d75b04d..d1f9adf2d0 100644 --- a/src/nvim/eval.c +++ b/src/nvim/eval.c @@ -3678,6 +3678,10 @@ static int eval_method(char **const arg, typval_T *const rettv, evalarg_T *const } xfree(tofree); + if (alias != NULL) { + xfree(alias); + } + return ret; } @@ -3815,7 +3819,7 @@ static int check_can_index(typval_T *rettv, bool evaluate, bool verbose) /// slice() function void f_slice(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) { - if (check_can_index(argvars, true, false) != OK) { + if (check_can_index(&argvars[0], true, false) != OK) { return; } diff --git a/src/nvim/eval/executor.c b/src/nvim/eval/executor.c index 26b7a627a6..5b92f217d1 100644 --- a/src/nvim/eval/executor.c +++ b/src/nvim/eval/executor.c @@ -31,7 +31,13 @@ static int tv_op_blob(typval_T *tv1, const typval_T *tv2, const char *op) } // 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; } diff --git a/src/nvim/eval/funcs.c b/src/nvim/eval/funcs.c index 22e7f383a5..bd977523c6 100644 --- a/src/nvim/eval/funcs.c +++ b/src/nvim/eval/funcs.c @@ -3880,6 +3880,7 @@ static varnumber_T indexof_blob(blob_T *b, varnumber_T startidx, typval_T *expr) } } + const int called_emsg_start = called_emsg; for (varnumber_T idx = startidx; idx < tv_blob_len(b); idx++) { set_vim_var_nr(VV_KEY, idx); set_vim_var_nr(VV_VAL, tv_blob_get(b, (int)idx)); @@ -3887,6 +3888,10 @@ static varnumber_T indexof_blob(blob_T *b, varnumber_T startidx, typval_T *expr) if (indexof_eval_expr(expr)) { return idx; } + + if (called_emsg != called_emsg_start) { + return -1; + } } return -1; @@ -3916,6 +3921,7 @@ static varnumber_T indexof_list(list_T *l, varnumber_T startidx, typval_T *expr) } } + const int called_emsg_start = called_emsg; for (; item != NULL; item = TV_LIST_ITEM_NEXT(l, item), idx++) { set_vim_var_nr(VV_KEY, idx); tv_copy(TV_LIST_ITEM_TV(item), get_vim_var_tv(VV_VAL)); @@ -3926,6 +3932,10 @@ static varnumber_T indexof_list(list_T *l, varnumber_T startidx, typval_T *expr) if (found) { return idx; } + + if (called_emsg != called_emsg_start) { + return -1; + } } return -1; @@ -3942,7 +3952,8 @@ static void f_indexof(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) 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; } diff --git a/test/functional/legacy/edit_spec.lua b/test/functional/legacy/edit_spec.lua index f3d18a2541..2d98188f9b 100644 --- a/test/functional/legacy/edit_spec.lua +++ b/test/functional/legacy/edit_spec.lua @@ -44,6 +44,12 @@ describe('edit', function() {1:~ }|*4 =^ | ]]) + feed([['r']]) + expect('r') + -- Test for inserting null and empty list + feed('a=v:_null_list') + feed('a=[]') + expect('r') end) -- oldtest: Test_edit_ctrl_r_failed() diff --git a/test/old/testdir/test_blob.vim b/test/old/testdir/test_blob.vim index 3886be48bd..fbc080059e 100644 --- a/test/old/testdir/test_blob.vim +++ b/test/old/testdir/test_blob.vim @@ -75,6 +75,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 += v:_null_blob + call assert_equal(0z10, blob1) + LET blob1 = v:_null_blob + LET blob1 += 0z20 + call assert_equal(0z20, blob1) END call CheckLegacyAndVim9Success(lines) @@ -332,6 +339,17 @@ func Test_blob_for_loop() call assert_equal(5, i) END call 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 CheckLegacyAndVim9Success(lines) endfunc func Test_blob_concatenate() @@ -851,6 +869,7 @@ func Test_indexof() call assert_equal(-1, indexof(b, v:_null_string)) " Nvim doesn't have null functions " 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})) @@ -862,6 +881,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 diff --git a/test/old/testdir/test_edit.vim b/test/old/testdir/test_edit.vim index d43dcc40c1..037282bf1a 100644 --- a/test/old/testdir/test_edit.vim +++ b/test/old/testdir/test_edit.vim @@ -1973,6 +1973,11 @@ func Test_edit_insert_reg() let @r = 'sample' call feedkeys("a\=SaveFirstLine()\", "xt") call assert_equal('"', g:Line) + + " Test for inserting an null and an empty list + call feedkeys("a\=test_null_list()\", "xt") + call feedkeys("a\=[]\", "xt") + call assert_equal(['r'], getbufline('', 1, '$')) call test_override('ALL', 0) close! endfunc diff --git a/test/old/testdir/test_fold.vim b/test/old/testdir/test_fold.vim index a9842ae437..7b4e56508d 100644 --- a/test/old/testdir/test_fold.vim +++ b/test/old/testdir/test_fold.vim @@ -1469,6 +1469,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() diff --git a/test/old/testdir/test_functions.vim b/test/old/testdir/test_functions.vim index 3faa720850..01e9ae3bf2 100644 --- a/test/old/testdir/test_functions.vim +++ b/test/old/testdir/test_functions.vim @@ -3731,6 +3731,8 @@ func Test_slice() call assert_equal('', 'ὰ̳β̳́γ̳̂δ̳̃ε̳̄ζ̳̅'->slice(1, -6)) END call CheckLegacyAndVim9Success(lines) + + call assert_equal(0, slice(v:true, 1)) endfunc " vim: shiftwidth=2 sts=2 expandtab diff --git a/test/old/testdir/test_listdict.vim b/test/old/testdir/test_listdict.vim index 5e4a3fd1f8..678734dafb 100644 --- a/test/old/testdir/test_listdict.vim +++ b/test/old/testdir/test_listdict.vim @@ -57,6 +57,9 @@ func Test_list_slice() assert_equal([1, 2], l[-3 : -1]) END call 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 @@ -175,6 +178,19 @@ func Test_list_assign() END call CheckScriptFailure(['vim9script'] + lines, 'E688:') call CheckDefExecFailure(lines, 'E1093: Expected 2 items but got 1') + + let lines =<< trim END + VAR l = [2] + LET l += v:_null_list + call assert_equal([2], l) + LET l = v:_null_list + LET l += [1] + call assert_equal([1], l) + END + call 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 @@ -440,6 +456,9 @@ func Test_dict_assign() n.key = 3 END call 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 @@ -1449,6 +1468,8 @@ func Test_indexof() call assert_equal(-1, indexof(l, v:_null_string)) " Nvim doesn't have null functions " 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:') diff --git a/test/old/testdir/test_method.vim b/test/old/testdir/test_method.vim index 1b57bba282..ca1ca7d573 100644 --- a/test/old/testdir/test_method.vim +++ b/test/old/testdir/test_method.vim @@ -134,6 +134,13 @@ func Test_method_syntax() call assert_fails('eval [1, 2, 3]-> sort()', 'E15:') call assert_fails('eval [1, 2, 3]->sort ()', 'E274:') call assert_fails('eval [1, 2, 3]-> sort ()', 'E15:') + + " 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() diff --git a/test/old/testdir/test_partial.vim b/test/old/testdir/test_partial.vim index d049cc9e4b..b5933cdd6d 100644 --- a/test/old/testdir/test_partial.vim +++ b/test/old/testdir/test_partial.vim @@ -403,4 +403,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 diff --git a/test/old/testdir/test_vimscript.vim b/test/old/testdir/test_vimscript.vim index 28868a07d6..108321e8ad 100644 --- a/test/old/testdir/test_vimscript.vim +++ b/test/old/testdir/test_vimscript.vim @@ -7449,6 +7449,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