# HG changeset patch # User Christian Brabandt # Date 1459710005 -7200 # Node ID 6f41d68aa68ea526dc1b4b61b0a51dae3d547847 # Parent d15abeac22c680a0e267c4786da68d5df8ec83d8 commit https://github.com/vim/vim/commit/b50e5f56861deb867478997397f7c784a7043233 Author: Bram Moolenaar Date: Sun Apr 3 20:57:20 2016 +0200 patch 7.4.1703 Problem: Can't assert for not equal and not matching. Solution: Add assert_notmatch() and assert_notequal(). diff --git a/runtime/doc/eval.txt b/runtime/doc/eval.txt --- a/runtime/doc/eval.txt +++ b/runtime/doc/eval.txt @@ -1801,11 +1801,13 @@ arglistid( [{winnr} [, {tabnr}]]) Number argument list id argv( {nr}) String {nr} entry of the argument list argv() List the argument list -assert_equal( {exp}, {act} [, {msg}]) none assert {exp} equals {act} +assert_equal( {exp}, {act} [, {msg}]) none assert {exp} is equal to {act} assert_exception( {error} [, {msg}]) none assert {error} is in v:exception assert_fails( {cmd} [, {error}]) none assert {cmd} fails assert_false( {actual} [, {msg}]) none assert {actual} is false assert_match( {pat}, {text} [, {msg}]) none assert {pat} matches {text} +assert_notequal( {exp}, {act} [, {msg}]) none assert {exp} is not equal {act} +assert_notmatch( {pat}, {text} [, {msg}]) none assert {pat} not matches {text} assert_true( {actual} [, {msg}]) none assert {actual} is true asin( {expr}) Float arc sine of {expr} atan( {expr}) Float arc tangent of {expr} @@ -2338,6 +2340,16 @@ assert_match({pattern}, {actual} [, {msg < Will result in a string to be added to |v:errors|: test.vim line 12: Pattern '^f.*o$' does not match 'foobar' ~ + *assert_notequal()* +assert_notequal({expected}, {actual} [, {msg}]) + The opposite of `assert_equal()`: add an error message to + |v:errors| when {expected} and {actual} are equal. + + *assert_notmatch()* +assert_notmatch({pattern}, {actual} [, {msg}]) + The opposite of `assert_match()`: add an error message to + |v:errors| when {pattern} matches {actual}. + assert_true({actual} [, {msg}]) *assert_true()* When {actual} is not true an error message is added to |v:errors|, like with |assert_equal()|. diff --git a/src/eval.c b/src/eval.c --- a/src/eval.c +++ b/src/eval.c @@ -476,6 +476,8 @@ static void f_assert_exception(typval_T 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_match(typval_T *argvars, typval_T *rettv); +static void f_assert_notequal(typval_T *argvars, typval_T *rettv); +static void f_assert_notmatch(typval_T *argvars, typval_T *rettv); static void f_assert_true(typval_T *argvars, typval_T *rettv); #ifdef FEAT_FLOAT static void f_asin(typval_T *argvars, typval_T *rettv); @@ -8182,6 +8184,8 @@ static struct fst {"assert_fails", 1, 2, f_assert_fails}, {"assert_false", 1, 2, f_assert_false}, {"assert_match", 2, 3, f_assert_match}, + {"assert_notequal", 2, 3, f_assert_notequal}, + {"assert_notmatch", 2, 3, f_assert_notmatch}, {"assert_true", 1, 2, f_assert_true}, #ifdef FEAT_FLOAT {"atan", 1, 1, f_atan}, @@ -9323,8 +9327,17 @@ f_argv(typval_T *argvars, typval_T *rett alist_name(&ARGLIST[idx]), -1); } +typedef enum +{ + ASSERT_EQUAL, + ASSERT_NOTEQUAL, + ASSERT_MATCH, + ASSERT_NOTMATCH, + ASSERT_OTHER, +} assert_type_T; + 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, int is_match); +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, assert_type_T is_match); static void assert_error(garray_T *gap); static void assert_bool(typval_T *argvars, int isTrue); @@ -9400,7 +9413,7 @@ fill_assert_error( char_u *exp_str, typval_T *exp_tv, typval_T *got_tv, - int is_match) + assert_type_T atype) { char_u numbuf[NUMBUFLEN]; char_u *tofree; @@ -9412,7 +9425,7 @@ fill_assert_error( } else { - if (is_match) + if (atype == ASSERT_MATCH || atype == ASSERT_NOTMATCH) ga_concat(gap, (char_u *)"Pattern "); else ga_concat(gap, (char_u *)"Expected "); @@ -9423,8 +9436,12 @@ fill_assert_error( } else ga_concat_esc(gap, exp_str); - if (is_match) + if (atype == ASSERT_MATCH) ga_concat(gap, (char_u *)" does not match "); + else if (atype == ASSERT_NOTMATCH) + ga_concat(gap, (char_u *)" does match "); + else if (atype == ASSERT_NOTEQUAL) + ga_concat(gap, (char_u *)" differs from "); else ga_concat(gap, (char_u *)" but got "); ga_concat_esc(gap, tv2string(got_tv, &tofree, numbuf, 0)); @@ -9446,22 +9463,38 @@ assert_error(garray_T *gap) list_append_string(vimvars[VV_ERRORS].vv_list, gap->ga_data, gap->ga_len); } + static void +assert_equal_common(typval_T *argvars, assert_type_T atype) +{ + garray_T ga; + + if (tv_equal(&argvars[0], &argvars[1], FALSE, FALSE) + != (atype == ASSERT_EQUAL)) + { + prepare_assert_error(&ga); + fill_assert_error(&ga, &argvars[2], NULL, &argvars[0], &argvars[1], + atype); + assert_error(&ga); + ga_clear(&ga); + } +} + /* * "assert_equal(expected, actual[, msg])" function */ static void f_assert_equal(typval_T *argvars, typval_T *rettv UNUSED) { - garray_T ga; - - if (!tv_equal(&argvars[0], &argvars[1], FALSE, FALSE)) - { - prepare_assert_error(&ga); - fill_assert_error(&ga, &argvars[2], NULL, &argvars[0], &argvars[1], - FALSE); - assert_error(&ga); - ga_clear(&ga); - } + assert_equal_common(argvars, ASSERT_EQUAL); +} + +/* + * "assert_notequal(expected, actual[, msg])" function + */ + static void +f_assert_notequal(typval_T *argvars, typval_T *rettv UNUSED) +{ + assert_equal_common(argvars, ASSERT_NOTEQUAL); } /* @@ -9486,7 +9519,7 @@ f_assert_exception(typval_T *argvars, ty { prepare_assert_error(&ga); fill_assert_error(&ga, &argvars[1], NULL, &argvars[0], - &vimvars[VV_EXCEPTION].vv_tv, FALSE); + &vimvars[VV_EXCEPTION].vv_tv, ASSERT_OTHER); assert_error(&ga); ga_clear(&ga); } @@ -9523,7 +9556,7 @@ f_assert_fails(typval_T *argvars, typval { prepare_assert_error(&ga); fill_assert_error(&ga, &argvars[2], NULL, &argvars[1], - &vimvars[VV_ERRMSG].vv_tv, FALSE); + &vimvars[VV_ERRMSG].vv_tv, ASSERT_OTHER); assert_error(&ga); ga_clear(&ga); } @@ -9555,7 +9588,7 @@ assert_bool(typval_T *argvars, int isTru prepare_assert_error(&ga); fill_assert_error(&ga, &argvars[1], (char_u *)(isTrue ? "True" : "False"), - NULL, &argvars[0], FALSE); + NULL, &argvars[0], ASSERT_OTHER); assert_error(&ga); ga_clear(&ga); } @@ -9570,11 +9603,8 @@ f_assert_false(typval_T *argvars, typval assert_bool(argvars, FALSE); } -/* - * "assert_match(pattern, actual[, msg])" function - */ - static void -f_assert_match(typval_T *argvars, typval_T *rettv UNUSED) + static void +assert_match_common(typval_T *argvars, assert_type_T atype) { garray_T ga; char_u buf1[NUMBUFLEN]; @@ -9584,17 +9614,35 @@ f_assert_match(typval_T *argvars, typval if (pat == NULL || text == NULL) EMSG(_(e_invarg)); - else if (!pattern_match(pat, text, FALSE)) + else if (pattern_match(pat, text, FALSE) != (atype == ASSERT_MATCH)) { prepare_assert_error(&ga); fill_assert_error(&ga, &argvars[2], NULL, &argvars[0], &argvars[1], - TRUE); + atype); assert_error(&ga); ga_clear(&ga); } } /* + * "assert_match(pattern, actual[, msg])" function + */ + static void +f_assert_match(typval_T *argvars, typval_T *rettv UNUSED) +{ + assert_match_common(argvars, ASSERT_MATCH); +} + +/* + * "assert_notmatch(pattern, actual[, msg])" function + */ + static void +f_assert_notmatch(typval_T *argvars, typval_T *rettv UNUSED) +{ + assert_match_common(argvars, ASSERT_NOTMATCH); +} + +/* * "assert_true(actual[, msg])" function */ static void diff --git a/src/testdir/test_assert.vim b/src/testdir/test_assert.vim --- a/src/testdir/test_assert.vim +++ b/src/testdir/test_assert.vim @@ -18,6 +18,22 @@ func Test_assert_equal() call assert_equal(4, n) let l = [1, 2, 3] call assert_equal([1, 2, 3], l) + + let s = 'foo' + call assert_equal('bar', s) + call assert_match("Expected 'bar' but got 'foo'", v:errors[0]) + call remove(v:errors, 0) +endfunc + +func Test_assert_notequal() + let n = 4 + call assert_notequal('foo', n) + let s = 'foo' + call assert_notequal([1, 2, 3], s) + + call assert_notequal('foo', s) + call assert_match("Expected 'foo' differs from 'foo'", v:errors[0]) + call remove(v:errors, 0) endfunc func Test_assert_exception() @@ -74,6 +90,15 @@ func Test_match() call remove(v:errors, 0) endfunc +func Test_notmatch() + call assert_notmatch('foo', 'bar') + call assert_notmatch('^foobar$', 'foobars') + + call assert_notmatch('foo', 'foobar') + call assert_match("Pattern 'foo' does match 'foobar'", v:errors[0]) + call remove(v:errors, 0) +endfunc + func Test_assert_fail_fails() call assert_fails('xxx', {}) call assert_match("Expected {} but got 'E731:", v:errors[0]) diff --git a/src/version.c b/src/version.c --- a/src/version.c +++ b/src/version.c @@ -749,6 +749,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ /**/ + 1703, +/**/ 1702, /**/ 1701,