# HG changeset patch # User Bram Moolenaar # Date 1599422403 -7200 # Node ID b6d36f0b4f037179388f5a0afa0be4dc5f854689 # Parent b910fd9e1190f12f4aefa2f2febe57b8b0690c11 patch 8.2.1631: test_fails() does not check the context of the line number Commit: https://github.com/vim/vim/commit/9bd5d879c2ecfbdbb168b090e12f4b89724a302e Author: Bram Moolenaar Date: Sun Sep 6 21:47:48 2020 +0200 patch 8.2.1631: test_fails() does not check the context of the line number Problem: test_fails() does not check the context of the line number. Solution: Use another argument to specify the context of the line number. diff --git a/runtime/doc/testing.txt b/runtime/doc/testing.txt --- a/runtime/doc/testing.txt +++ b/runtime/doc/testing.txt @@ -293,7 +293,7 @@ assert_exception({error} [, {msg}]) *a endtry < *assert_fails()* -assert_fails({cmd} [, {error} [, {msg} [, {lnum}]]]) +assert_fails({cmd} [, {error} [, {msg} [, {lnum} [, {context}]]]]) Run {cmd} and add an error message to |v:errors| if it does NOT produce an error or when {error} is not found in the error message. Also see |assert-return|. @@ -320,6 +320,10 @@ assert_fails({cmd} [, {error} [, {msg} [ the line number at which the error was reported. That can be the line number in a function or in a script. + When {context} is present it is used as a pattern and matched + against the context (script name or function name) where + {lnum} is located in. + Note that beeping is not considered an error, and some failing commands only beep. Use |assert_beeps()| for those. diff --git a/src/evalfunc.c b/src/evalfunc.c --- a/src/evalfunc.c +++ b/src/evalfunc.c @@ -495,7 +495,7 @@ static funcentry_T global_functions[] = {"assert_equal", 2, 3, FEARG_2, ret_number, f_assert_equal}, {"assert_equalfile", 2, 3, FEARG_1, ret_number, f_assert_equalfile}, {"assert_exception", 1, 2, 0, ret_number, f_assert_exception}, - {"assert_fails", 1, 4, FEARG_1, ret_number, f_assert_fails}, + {"assert_fails", 1, 5, FEARG_1, ret_number, f_assert_fails}, {"assert_false", 1, 2, FEARG_1, ret_number, f_assert_false}, {"assert_inrange", 3, 4, FEARG_3, ret_number, f_assert_inrange}, {"assert_match", 2, 3, FEARG_2, ret_number, f_assert_match}, diff --git a/src/globals.h b/src/globals.h --- a/src/globals.h +++ b/src/globals.h @@ -224,6 +224,7 @@ EXTERN int emsg_severe INIT(= FALSE); / EXTERN int emsg_assert_fails_used INIT(= FALSE); EXTERN char_u *emsg_assert_fails_msg INIT(= NULL); EXTERN long emsg_assert_fails_lnum INIT(= 0); +EXTERN char_u *emsg_assert_fails_context INIT(= NULL); EXTERN int did_endif INIT(= FALSE); // just had ":endif" #endif diff --git a/src/message.c b/src/message.c --- a/src/message.c +++ b/src/message.c @@ -658,6 +658,9 @@ emsg_core(char_u *s) { emsg_assert_fails_msg = vim_strsave(s); emsg_assert_fails_lnum = SOURCING_LNUM; + vim_free(emsg_assert_fails_context); + emsg_assert_fails_context = vim_strsave( + SOURCING_NAME == NULL ? (char_u *)"" : SOURCING_NAME); } // set "v:errmsg", also when using ":silent! cmd" diff --git a/src/testdir/test_vim9_func.vim b/src/testdir/test_vim9_func.vim --- a/src/testdir/test_vim9_func.vim +++ b/src/testdir/test_vim9_func.vim @@ -30,7 +30,7 @@ enddef def Test_return_something() assert_equal('string', ReturnString()) assert_equal(123, ReturnNumber()) - assert_fails('ReturnGlobal()', 'E1029: Expected number but got string') + assert_fails('ReturnGlobal()', 'E1029: Expected number but got string', '', 1, 'ReturnGlobal') enddef def Test_missing_return() @@ -112,7 +112,7 @@ enddef def Test_call_default_args() assert_equal('string', MyDefaultArgs()) assert_equal('one', MyDefaultArgs('one')) - assert_fails('MyDefaultArgs("one", "two")', 'E118:') + assert_fails('MyDefaultArgs("one", "two")', 'E118:', '', 3, 'Test_call_default_args') assert_equal('test', MyDefaultSecond('test')) assert_equal('test', MyDefaultSecond('test', true)) @@ -139,7 +139,7 @@ enddef func Test_call_default_args_from_func() call assert_equal('string', MyDefaultArgs()) call assert_equal('one', MyDefaultArgs('one')) - call assert_fails('call MyDefaultArgs("one", "two")', 'E118:') + call assert_fails('call MyDefaultArgs("one", "two")', 'E118:', '', 3, 'Test_call_default_args_from_func') endfunc def Test_nested_global_function() @@ -245,7 +245,7 @@ def MyDefVarargs(one: string, two = 'foo enddef def Test_call_def_varargs() - assert_fails('MyDefVarargs()', 'E119:') + assert_fails('MyDefVarargs()', 'E119:', '', 1, 'Test_call_def_varargs') assert_equal('one,foo', MyDefVarargs('one')) assert_equal('one,two', MyDefVarargs('one', 'two')) assert_equal('one,two,three', MyDefVarargs('one', 'two', 'three')) @@ -362,7 +362,7 @@ enddef def Test_using_var_as_arg() writefile(['def Func(x: number)', 'let x = 234', 'enddef', 'defcompile'], 'Xdef') - assert_fails('so Xdef', 'E1006:') + assert_fails('so Xdef', 'E1006:', '', 1, 'Func') delete('Xdef') enddef @@ -388,7 +388,7 @@ enddef def Test_call_func_defined_later() assert_equal('one', g:DefinedLater('one')) - assert_fails('NotDefined("one")', 'E117:') + assert_fails('NotDefined("one")', 'E117:', '', 2, 'Test_call_func_defined_later') enddef func DefinedLater(arg) @@ -397,8 +397,8 @@ endfunc def Test_call_funcref() assert_equal(3, g:SomeFunc('abc')) - assert_fails('NotAFunc()', 'E117:') # comment after call - assert_fails('g:NotAFunc()', 'E117:') + assert_fails('NotAFunc()', 'E117:', '', 2, 'Test_call_funcref') # comment after call + assert_fails('g:NotAFunc()', 'E117:', '', 3, 'Test_call_funcref') let lines =<< trim END vim9script @@ -524,7 +524,7 @@ enddef def Test_error_in_nested_function() # Error in called function requires unwinding the call stack. - assert_fails('FuncWithForwardCall()', 'E1096:') + assert_fails('FuncWithForwardCall()', 'E1096:', 1, 'FuncWithForwardCall') enddef def Test_return_type_wrong() @@ -705,7 +705,7 @@ def Test_vim9script_call_fail_const() defcompile END writefile(lines, 'Xcall_const.vim') - assert_fails('source Xcall_const.vim', 'E46:') + assert_fails('source Xcall_const.vim', 'E46:', '', 1, 'MyFunc') delete('Xcall_const.vim') enddef @@ -736,8 +736,8 @@ def Test_delfunc() CallGoneSoon() END writefile(lines, 'XToDelFunc') - assert_fails('so XToDelFunc', 'E933:') - assert_fails('so XToDelFunc', 'E933:') + assert_fails('so XToDelFunc', 'E933:', '', 1, 'CallGoneSoon') + assert_fails('so XToDelFunc', 'E933:', '', 1, 'CallGoneSoon') delete('XToDelFunc') enddef @@ -748,7 +748,7 @@ def Test_redef_failure() writefile(['def Func1(): string', 'return "Func1"', 'enddef'], 'Xdef') so Xdef writefile(['def! Func0(): string', 'enddef', 'defcompile'], 'Xdef') - assert_fails('so Xdef', 'E1027:') + assert_fails('so Xdef', 'E1027:', '', 1, 'Func0') writefile(['def Func2(): string', 'return "Func2"', 'enddef'], 'Xdef') so Xdef delete('Xdef') @@ -824,7 +824,7 @@ func Test_internalfunc_arg_error() defcompile END call writefile(l, 'Xinvalidarg') - call assert_fails('so Xinvalidarg', 'E118:') + call assert_fails('so Xinvalidarg', 'E118:', '', 1, 'FArgErr') let l =<< trim END def! FArgErr(): float return ceil() @@ -832,7 +832,7 @@ func Test_internalfunc_arg_error() defcompile END call writefile(l, 'Xinvalidarg') - call assert_fails('so Xinvalidarg', 'E119:') + call assert_fails('so Xinvalidarg', 'E119:', '', 1, 'FArgErr') call delete('Xinvalidarg') endfunc diff --git a/src/testing.c b/src/testing.c --- a/src/testing.c +++ b/src/testing.c @@ -573,7 +573,7 @@ f_assert_fails(typval_T *argvars, typval char_u buf[NUMBUFLEN]; char_u *expected; int error_found = FALSE; - int lnum_error_found = FALSE; + int error_found_index = 1; char_u *actual = emsg_assert_fails_msg == NULL ? (char_u *)"[unknown]" : emsg_assert_fails_msg; @@ -616,12 +616,22 @@ f_assert_fails(typval_T *argvars, typval } if (!error_found && argvars[2].v_type != VAR_UNKNOWN - && argvars[3].v_type == VAR_NUMBER - && argvars[3].vval.v_number >= 0 + && argvars[3].v_type == VAR_NUMBER) + { + if (argvars[3].vval.v_number >= 0 && argvars[3].vval.v_number != emsg_assert_fails_lnum) - { - error_found = TRUE; - lnum_error_found = TRUE; + { + error_found = TRUE; + error_found_index = 3; + } + if (!error_found && argvars[4].v_type == VAR_STRING + && argvars[4].vval.v_string != NULL + && !pattern_match(argvars[4].vval.v_string, + emsg_assert_fails_context, FALSE)) + { + error_found = TRUE; + error_found_index = 4; + } } if (error_found) @@ -629,19 +639,23 @@ f_assert_fails(typval_T *argvars, typval typval_T actual_tv; prepare_assert_error(&ga); - if (lnum_error_found) + if (error_found_index == 3) { actual_tv.v_type = VAR_NUMBER; actual_tv.vval.v_number = emsg_assert_fails_lnum; } + else if (error_found_index == 4) + { + actual_tv.v_type = VAR_STRING; + actual_tv.vval.v_string = emsg_assert_fails_context; + } else { actual_tv.v_type = VAR_STRING; actual_tv.vval.v_string = actual; } fill_assert_error(&ga, &argvars[2], NULL, - &argvars[lnum_error_found ? 3 : 1], - &actual_tv, ASSERT_OTHER); + &argvars[error_found_index], &actual_tv, ASSERT_OTHER); ga_concat(&ga, (char_u *)": "); assert_append_cmd_or_arg(&ga, argvars, cmd); assert_error(&ga); diff --git a/src/version.c b/src/version.c --- a/src/version.c +++ b/src/version.c @@ -755,6 +755,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ /**/ + 1631, +/**/ 1630, /**/ 1629,