forked from aniani/vim
patch 7.4.1663
Problem: In tests it's often useful to check if a pattern matches. Solution: Add assert_match().
This commit is contained in:
@@ -1,4 +1,4 @@
|
|||||||
*eval.txt* For Vim version 7.4. Last change: 2016 Mar 26
|
*eval.txt* For Vim version 7.4. Last change: 2016 Mar 27
|
||||||
|
|
||||||
|
|
||||||
VIM REFERENCE MANUAL by Bram Moolenaar
|
VIM REFERENCE MANUAL by Bram Moolenaar
|
||||||
@@ -1805,6 +1805,7 @@ assert_equal( {exp}, {act} [, {msg}]) none assert {exp} equals {act}
|
|||||||
assert_exception( {error} [, {msg}]) none assert {error} is in v:exception
|
assert_exception( {error} [, {msg}]) none assert {error} is in v:exception
|
||||||
assert_fails( {cmd} [, {error}]) none assert {cmd} fails
|
assert_fails( {cmd} [, {error}]) none assert {cmd} fails
|
||||||
assert_false( {actual} [, {msg}]) none assert {actual} is false
|
assert_false( {actual} [, {msg}]) none assert {actual} is false
|
||||||
|
assert_match( {pat}, {text} [, {msg}]) none assert {pat} matches {text}
|
||||||
assert_true( {actual} [, {msg}]) none assert {actual} is true
|
assert_true( {actual} [, {msg}]) none assert {actual} is true
|
||||||
asin( {expr}) Float arc sine of {expr}
|
asin( {expr}) Float arc sine of {expr}
|
||||||
atan( {expr}) Float arc tangent of {expr}
|
atan( {expr}) Float arc tangent of {expr}
|
||||||
@@ -2315,6 +2316,26 @@ assert_false({actual} [, {msg}]) *assert_false()*
|
|||||||
When {msg} is omitted an error in the form "Expected False but
|
When {msg} is omitted an error in the form "Expected False but
|
||||||
got {actual}" is produced.
|
got {actual}" is produced.
|
||||||
|
|
||||||
|
*assert_match()*
|
||||||
|
assert_match({pattern}, {actual} [, {msg}])
|
||||||
|
When {pattern} does not match {actual} an error message is
|
||||||
|
added to |v:errors|.
|
||||||
|
|
||||||
|
{pattern} is used as with |=~|: The matching is always done
|
||||||
|
like 'magic' was set and 'cpoptions' is empty, no matter what
|
||||||
|
the actual value of 'magic' or 'cpoptions' is.
|
||||||
|
|
||||||
|
{actual} is used as a string, automatic conversion applies.
|
||||||
|
Use "^" and "$" to match with the start and end of the text.
|
||||||
|
Use both to match the whole text.
|
||||||
|
|
||||||
|
When {msg} is omitted an error in the form "Pattern {pattern}
|
||||||
|
does not match {actual}" is produced.
|
||||||
|
Example: >
|
||||||
|
assert_match('^f.*o$', 'foobar')
|
||||||
|
< Will result in a string to be added to |v:errors|:
|
||||||
|
test.vim line 12: Pattern '^f.*o$' does not match 'foobar' ~
|
||||||
|
|
||||||
assert_true({actual} [, {msg}]) *assert_true()*
|
assert_true({actual} [, {msg}]) *assert_true()*
|
||||||
When {actual} is not true an error message is added to
|
When {actual} is not true an error message is added to
|
||||||
|v:errors|, like with |assert_equal()|.
|
|v:errors|, like with |assert_equal()|.
|
||||||
|
|||||||
84
src/eval.c
84
src/eval.c
@@ -475,6 +475,7 @@ static void f_assert_equal(typval_T *argvars, typval_T *rettv);
|
|||||||
static void f_assert_exception(typval_T *argvars, typval_T *rettv);
|
static void f_assert_exception(typval_T *argvars, typval_T *rettv);
|
||||||
static void f_assert_fails(typval_T *argvars, typval_T *rettv);
|
static void f_assert_fails(typval_T *argvars, typval_T *rettv);
|
||||||
static void f_assert_false(typval_T *argvars, typval_T *rettv);
|
static void f_assert_false(typval_T *argvars, typval_T *rettv);
|
||||||
|
static void f_assert_match(typval_T *argvars, typval_T *rettv);
|
||||||
static void f_assert_true(typval_T *argvars, typval_T *rettv);
|
static void f_assert_true(typval_T *argvars, typval_T *rettv);
|
||||||
#ifdef FEAT_FLOAT
|
#ifdef FEAT_FLOAT
|
||||||
static void f_asin(typval_T *argvars, typval_T *rettv);
|
static void f_asin(typval_T *argvars, typval_T *rettv);
|
||||||
@@ -4105,6 +4106,31 @@ get_user_var_name(expand_T *xp, int idx)
|
|||||||
|
|
||||||
#endif /* FEAT_CMDL_COMPL */
|
#endif /* FEAT_CMDL_COMPL */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Return TRUE if "pat" matches "text".
|
||||||
|
* Does not use 'cpo' and always uses 'magic'.
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
pattern_match(char_u *pat, char_u *text, int ic)
|
||||||
|
{
|
||||||
|
int matches = FALSE;
|
||||||
|
char_u *save_cpo;
|
||||||
|
regmatch_T regmatch;
|
||||||
|
|
||||||
|
/* avoid 'l' flag in 'cpoptions' */
|
||||||
|
save_cpo = p_cpo;
|
||||||
|
p_cpo = (char_u *)"";
|
||||||
|
regmatch.regprog = vim_regcomp(pat, RE_MAGIC + RE_STRING);
|
||||||
|
if (regmatch.regprog != NULL)
|
||||||
|
{
|
||||||
|
regmatch.rm_ic = ic;
|
||||||
|
matches = vim_regexec_nl(®match, text, (colnr_T)0);
|
||||||
|
vim_regfree(regmatch.regprog);
|
||||||
|
}
|
||||||
|
p_cpo = save_cpo;
|
||||||
|
return matches;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* types for expressions.
|
* types for expressions.
|
||||||
*/
|
*/
|
||||||
@@ -4403,9 +4429,7 @@ eval4(char_u **arg, typval_T *rettv, int evaluate)
|
|||||||
long n1, n2;
|
long n1, n2;
|
||||||
char_u *s1, *s2;
|
char_u *s1, *s2;
|
||||||
char_u buf1[NUMBUFLEN], buf2[NUMBUFLEN];
|
char_u buf1[NUMBUFLEN], buf2[NUMBUFLEN];
|
||||||
regmatch_T regmatch;
|
|
||||||
int ic;
|
int ic;
|
||||||
char_u *save_cpo;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Get the first variable.
|
* Get the first variable.
|
||||||
@@ -4646,20 +4670,9 @@ eval4(char_u **arg, typval_T *rettv, int evaluate)
|
|||||||
|
|
||||||
case TYPE_MATCH:
|
case TYPE_MATCH:
|
||||||
case TYPE_NOMATCH:
|
case TYPE_NOMATCH:
|
||||||
/* avoid 'l' flag in 'cpoptions' */
|
n1 = pattern_match(s2, s1, ic);
|
||||||
save_cpo = p_cpo;
|
|
||||||
p_cpo = (char_u *)"";
|
|
||||||
regmatch.regprog = vim_regcomp(s2,
|
|
||||||
RE_MAGIC + RE_STRING);
|
|
||||||
regmatch.rm_ic = ic;
|
|
||||||
if (regmatch.regprog != NULL)
|
|
||||||
{
|
|
||||||
n1 = vim_regexec_nl(®match, s1, (colnr_T)0);
|
|
||||||
vim_regfree(regmatch.regprog);
|
|
||||||
if (type == TYPE_NOMATCH)
|
if (type == TYPE_NOMATCH)
|
||||||
n1 = !n1;
|
n1 = !n1;
|
||||||
}
|
|
||||||
p_cpo = save_cpo;
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case TYPE_UNKNOWN: break; /* avoid gcc warning */
|
case TYPE_UNKNOWN: break; /* avoid gcc warning */
|
||||||
@@ -8154,6 +8167,7 @@ static struct fst
|
|||||||
{"assert_exception", 1, 2, f_assert_exception},
|
{"assert_exception", 1, 2, f_assert_exception},
|
||||||
{"assert_fails", 1, 2, f_assert_fails},
|
{"assert_fails", 1, 2, f_assert_fails},
|
||||||
{"assert_false", 1, 2, f_assert_false},
|
{"assert_false", 1, 2, f_assert_false},
|
||||||
|
{"assert_match", 2, 3, f_assert_match},
|
||||||
{"assert_true", 1, 2, f_assert_true},
|
{"assert_true", 1, 2, f_assert_true},
|
||||||
#ifdef FEAT_FLOAT
|
#ifdef FEAT_FLOAT
|
||||||
{"atan", 1, 1, f_atan},
|
{"atan", 1, 1, f_atan},
|
||||||
@@ -9295,7 +9309,7 @@ f_argv(typval_T *argvars, typval_T *rettv)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void prepare_assert_error(garray_T*gap);
|
static void prepare_assert_error(garray_T*gap);
|
||||||
static void fill_assert_error(garray_T *gap, typval_T *opt_msg_tv, char_u *exp_str, typval_T *exp_tv, typval_T *got_tv);
|
static void fill_assert_error(garray_T *gap, typval_T *opt_msg_tv, char_u *exp_str, typval_T *exp_tv, typval_T *got_tv, int is_match);
|
||||||
static void assert_error(garray_T *gap);
|
static void assert_error(garray_T *gap);
|
||||||
static void assert_bool(typval_T *argvars, int isTrue);
|
static void assert_bool(typval_T *argvars, int isTrue);
|
||||||
|
|
||||||
@@ -9370,7 +9384,8 @@ fill_assert_error(
|
|||||||
typval_T *opt_msg_tv,
|
typval_T *opt_msg_tv,
|
||||||
char_u *exp_str,
|
char_u *exp_str,
|
||||||
typval_T *exp_tv,
|
typval_T *exp_tv,
|
||||||
typval_T *got_tv)
|
typval_T *got_tv,
|
||||||
|
int is_match)
|
||||||
{
|
{
|
||||||
char_u numbuf[NUMBUFLEN];
|
char_u numbuf[NUMBUFLEN];
|
||||||
char_u *tofree;
|
char_u *tofree;
|
||||||
@@ -9382,6 +9397,9 @@ fill_assert_error(
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
if (is_match)
|
||||||
|
ga_concat(gap, (char_u *)"Pattern ");
|
||||||
|
else
|
||||||
ga_concat(gap, (char_u *)"Expected ");
|
ga_concat(gap, (char_u *)"Expected ");
|
||||||
if (exp_str == NULL)
|
if (exp_str == NULL)
|
||||||
{
|
{
|
||||||
@@ -9390,6 +9408,9 @@ fill_assert_error(
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
ga_concat_esc(gap, exp_str);
|
ga_concat_esc(gap, exp_str);
|
||||||
|
if (is_match)
|
||||||
|
ga_concat(gap, (char_u *)" does not match ");
|
||||||
|
else
|
||||||
ga_concat(gap, (char_u *)" but got ");
|
ga_concat(gap, (char_u *)" but got ");
|
||||||
ga_concat_esc(gap, tv2string(got_tv, &tofree, numbuf, 0));
|
ga_concat_esc(gap, tv2string(got_tv, &tofree, numbuf, 0));
|
||||||
vim_free(tofree);
|
vim_free(tofree);
|
||||||
@@ -9421,7 +9442,8 @@ f_assert_equal(typval_T *argvars, typval_T *rettv UNUSED)
|
|||||||
if (!tv_equal(&argvars[0], &argvars[1], FALSE, FALSE))
|
if (!tv_equal(&argvars[0], &argvars[1], FALSE, FALSE))
|
||||||
{
|
{
|
||||||
prepare_assert_error(&ga);
|
prepare_assert_error(&ga);
|
||||||
fill_assert_error(&ga, &argvars[2], NULL, &argvars[0], &argvars[1]);
|
fill_assert_error(&ga, &argvars[2], NULL, &argvars[0], &argvars[1],
|
||||||
|
FALSE);
|
||||||
assert_error(&ga);
|
assert_error(&ga);
|
||||||
ga_clear(&ga);
|
ga_clear(&ga);
|
||||||
}
|
}
|
||||||
@@ -9449,7 +9471,7 @@ f_assert_exception(typval_T *argvars, typval_T *rettv UNUSED)
|
|||||||
{
|
{
|
||||||
prepare_assert_error(&ga);
|
prepare_assert_error(&ga);
|
||||||
fill_assert_error(&ga, &argvars[1], NULL, &argvars[0],
|
fill_assert_error(&ga, &argvars[1], NULL, &argvars[0],
|
||||||
&vimvars[VV_EXCEPTION].vv_tv);
|
&vimvars[VV_EXCEPTION].vv_tv, FALSE);
|
||||||
assert_error(&ga);
|
assert_error(&ga);
|
||||||
ga_clear(&ga);
|
ga_clear(&ga);
|
||||||
}
|
}
|
||||||
@@ -9486,7 +9508,7 @@ f_assert_fails(typval_T *argvars, typval_T *rettv UNUSED)
|
|||||||
{
|
{
|
||||||
prepare_assert_error(&ga);
|
prepare_assert_error(&ga);
|
||||||
fill_assert_error(&ga, &argvars[2], NULL, &argvars[1],
|
fill_assert_error(&ga, &argvars[2], NULL, &argvars[1],
|
||||||
&vimvars[VV_ERRMSG].vv_tv);
|
&vimvars[VV_ERRMSG].vv_tv, FALSE);
|
||||||
assert_error(&ga);
|
assert_error(&ga);
|
||||||
ga_clear(&ga);
|
ga_clear(&ga);
|
||||||
}
|
}
|
||||||
@@ -9518,7 +9540,7 @@ assert_bool(typval_T *argvars, int isTrue)
|
|||||||
prepare_assert_error(&ga);
|
prepare_assert_error(&ga);
|
||||||
fill_assert_error(&ga, &argvars[1],
|
fill_assert_error(&ga, &argvars[1],
|
||||||
(char_u *)(isTrue ? "True" : "False"),
|
(char_u *)(isTrue ? "True" : "False"),
|
||||||
NULL, &argvars[0]);
|
NULL, &argvars[0], FALSE);
|
||||||
assert_error(&ga);
|
assert_error(&ga);
|
||||||
ga_clear(&ga);
|
ga_clear(&ga);
|
||||||
}
|
}
|
||||||
@@ -9533,6 +9555,28 @@ f_assert_false(typval_T *argvars, typval_T *rettv UNUSED)
|
|||||||
assert_bool(argvars, FALSE);
|
assert_bool(argvars, FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* "assert_match(pattern, actual[, msg])" function
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
f_assert_match(typval_T *argvars, typval_T *rettv UNUSED)
|
||||||
|
{
|
||||||
|
garray_T ga;
|
||||||
|
char_u buf1[NUMBUFLEN];
|
||||||
|
char_u buf2[NUMBUFLEN];
|
||||||
|
char_u *pat = get_tv_string_buf_chk(&argvars[0], buf1);
|
||||||
|
char_u *text = get_tv_string_buf_chk(&argvars[1], buf2);
|
||||||
|
|
||||||
|
if (!pattern_match(pat, text, FALSE))
|
||||||
|
{
|
||||||
|
prepare_assert_error(&ga);
|
||||||
|
fill_assert_error(&ga, &argvars[2], NULL, &argvars[0], &argvars[1],
|
||||||
|
TRUE);
|
||||||
|
assert_error(&ga);
|
||||||
|
ga_clear(&ga);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* "assert_true(actual[, msg])" function
|
* "assert_true(actual[, msg])" function
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -57,14 +57,26 @@ func Test_compare_fail()
|
|||||||
call assert_equal(s:w, '')
|
call assert_equal(s:w, '')
|
||||||
catch
|
catch
|
||||||
call assert_exception('E724:')
|
call assert_exception('E724:')
|
||||||
call assert_true(v:errors[0] =~ "Expected NULL but got ''")
|
call assert_match("Expected NULL but got ''", v:errors[0])
|
||||||
call remove(v:errors, 0)
|
call remove(v:errors, 0)
|
||||||
endtry
|
endtry
|
||||||
endfunc
|
endfunc
|
||||||
|
|
||||||
|
func Test_match()
|
||||||
|
call assert_match('^f.*b.*r$', 'foobar')
|
||||||
|
|
||||||
|
call assert_match('bar.*foo', 'foobar')
|
||||||
|
call assert_match("Pattern 'bar.*foo' does not match 'foobar'", v:errors[0])
|
||||||
|
call remove(v:errors, 0)
|
||||||
|
|
||||||
|
call assert_match('bar.*foo', 'foobar', 'wrong')
|
||||||
|
call assert_match('wrong', v:errors[0])
|
||||||
|
call remove(v:errors, 0)
|
||||||
|
endfunc
|
||||||
|
|
||||||
func Test_assert_fail_fails()
|
func Test_assert_fail_fails()
|
||||||
call assert_fails('xxx', {})
|
call assert_fails('xxx', {})
|
||||||
call assert_true(v:errors[0] =~ "Expected {} but got 'E731:")
|
call assert_match("Expected {} but got 'E731:", v:errors[0])
|
||||||
call remove(v:errors, 0)
|
call remove(v:errors, 0)
|
||||||
endfunc
|
endfunc
|
||||||
|
|
||||||
|
|||||||
@@ -154,7 +154,7 @@ func s:communicate(port)
|
|||||||
" Request command "foo bar", which fails silently.
|
" Request command "foo bar", which fails silently.
|
||||||
call assert_equal('ok', ch_evalexpr(handle, 'bad command'))
|
call assert_equal('ok', ch_evalexpr(handle, 'bad command'))
|
||||||
call s:waitFor('v:errmsg =~ "E492"')
|
call s:waitFor('v:errmsg =~ "E492"')
|
||||||
call assert_true(v:errmsg =~ 'E492:.*foo bar')
|
call assert_match('E492:.*foo bar', v:errmsg)
|
||||||
|
|
||||||
call assert_equal('ok', ch_evalexpr(handle, 'do normal', {'timeout': 100}))
|
call assert_equal('ok', ch_evalexpr(handle, 'do normal', {'timeout': 100}))
|
||||||
call s:waitFor('"added more" == getline("$")')
|
call s:waitFor('"added more" == getline("$")')
|
||||||
|
|||||||
@@ -748,6 +748,8 @@ static char *(features[]) =
|
|||||||
|
|
||||||
static int included_patches[] =
|
static int included_patches[] =
|
||||||
{ /* Add new patch number below this line */
|
{ /* Add new patch number below this line */
|
||||||
|
/**/
|
||||||
|
1663,
|
||||||
/**/
|
/**/
|
||||||
1662,
|
1662,
|
||||||
/**/
|
/**/
|
||||||
|
|||||||
Reference in New Issue
Block a user