To: vim_dev@googlegroups.com Subject: Patch 7.4.1663 Fcc: outbox From: Bram Moolenaar Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ------------ Patch 7.4.1663 Problem: In tests it's often useful to check if a pattern matches. Solution: Add assert_match(). Files: src/eval.c, src/testdir/test_assert.vim, src/testdir/test_channel.vim, runtime/doc/eval.txt *** ../vim-7.4.1662/src/eval.c 2016-03-26 21:24:10.548534905 +0100 --- src/eval.c 2016-03-27 14:52:39.570899567 +0200 *************** *** 475,480 **** --- 475,481 ---- 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_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); #ifdef FEAT_FLOAT static void f_asin(typval_T *argvars, typval_T *rettv); *************** *** 4106,4111 **** --- 4107,4137 ---- #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. */ typedef enum *************** *** 4403,4411 **** long n1, n2; char_u *s1, *s2; char_u buf1[NUMBUFLEN], buf2[NUMBUFLEN]; - regmatch_T regmatch; int ic; - char_u *save_cpo; /* * Get the first variable. --- 4429,4435 ---- *************** *** 4646,4665 **** case TYPE_MATCH: case TYPE_NOMATCH: ! /* avoid 'l' flag in 'cpoptions' */ ! 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) ! n1 = !n1; ! } ! p_cpo = save_cpo; break; case TYPE_UNKNOWN: break; /* avoid gcc warning */ --- 4670,4678 ---- case TYPE_MATCH: case TYPE_NOMATCH: ! n1 = pattern_match(s2, s1, ic); ! if (type == TYPE_NOMATCH) ! n1 = !n1; break; case TYPE_UNKNOWN: break; /* avoid gcc warning */ *************** *** 8154,8159 **** --- 8167,8173 ---- {"assert_exception", 1, 2, f_assert_exception}, {"assert_fails", 1, 2, f_assert_fails}, {"assert_false", 1, 2, f_assert_false}, + {"assert_match", 2, 3, f_assert_match}, {"assert_true", 1, 2, f_assert_true}, #ifdef FEAT_FLOAT {"atan", 1, 1, f_atan}, *************** *** 9295,9301 **** } 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 assert_error(garray_T *gap); static void assert_bool(typval_T *argvars, int isTrue); --- 9309,9315 ---- } 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 assert_error(garray_T *gap); static void assert_bool(typval_T *argvars, int isTrue); *************** *** 9370,9376 **** typval_T *opt_msg_tv, char_u *exp_str, typval_T *exp_tv, ! typval_T *got_tv) { char_u numbuf[NUMBUFLEN]; char_u *tofree; --- 9384,9391 ---- typval_T *opt_msg_tv, char_u *exp_str, typval_T *exp_tv, ! typval_T *got_tv, ! int is_match) { char_u numbuf[NUMBUFLEN]; char_u *tofree; *************** *** 9382,9388 **** } else { ! ga_concat(gap, (char_u *)"Expected "); if (exp_str == NULL) { ga_concat_esc(gap, tv2string(exp_tv, &tofree, numbuf, 0)); --- 9397,9406 ---- } else { ! if (is_match) ! ga_concat(gap, (char_u *)"Pattern "); ! else ! ga_concat(gap, (char_u *)"Expected "); if (exp_str == NULL) { ga_concat_esc(gap, tv2string(exp_tv, &tofree, numbuf, 0)); *************** *** 9390,9396 **** } else ga_concat_esc(gap, exp_str); ! ga_concat(gap, (char_u *)" but got "); ga_concat_esc(gap, tv2string(got_tv, &tofree, numbuf, 0)); vim_free(tofree); } --- 9408,9417 ---- } else 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_esc(gap, tv2string(got_tv, &tofree, numbuf, 0)); vim_free(tofree); } *************** *** 9421,9427 **** if (!tv_equal(&argvars[0], &argvars[1], FALSE, FALSE)) { prepare_assert_error(&ga); ! fill_assert_error(&ga, &argvars[2], NULL, &argvars[0], &argvars[1]); assert_error(&ga); ga_clear(&ga); } --- 9442,9449 ---- 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); } *************** *** 9449,9455 **** { prepare_assert_error(&ga); fill_assert_error(&ga, &argvars[1], NULL, &argvars[0], ! &vimvars[VV_EXCEPTION].vv_tv); assert_error(&ga); ga_clear(&ga); } --- 9471,9477 ---- { prepare_assert_error(&ga); fill_assert_error(&ga, &argvars[1], NULL, &argvars[0], ! &vimvars[VV_EXCEPTION].vv_tv, FALSE); assert_error(&ga); ga_clear(&ga); } *************** *** 9486,9492 **** { prepare_assert_error(&ga); fill_assert_error(&ga, &argvars[2], NULL, &argvars[1], ! &vimvars[VV_ERRMSG].vv_tv); assert_error(&ga); ga_clear(&ga); } --- 9508,9514 ---- { prepare_assert_error(&ga); fill_assert_error(&ga, &argvars[2], NULL, &argvars[1], ! &vimvars[VV_ERRMSG].vv_tv, FALSE); assert_error(&ga); ga_clear(&ga); } *************** *** 9518,9524 **** prepare_assert_error(&ga); fill_assert_error(&ga, &argvars[1], (char_u *)(isTrue ? "True" : "False"), ! NULL, &argvars[0]); assert_error(&ga); ga_clear(&ga); } --- 9540,9546 ---- prepare_assert_error(&ga); fill_assert_error(&ga, &argvars[1], (char_u *)(isTrue ? "True" : "False"), ! NULL, &argvars[0], FALSE); assert_error(&ga); ga_clear(&ga); } *************** *** 9534,9539 **** --- 9556,9583 ---- } /* + * "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 */ static void *** ../vim-7.4.1662/src/testdir/test_assert.vim 2016-03-15 13:33:50.709244886 +0100 --- src/testdir/test_assert.vim 2016-03-27 14:54:52.333529707 +0200 *************** *** 57,70 **** call assert_equal(s:w, '') catch call assert_exception('E724:') ! call assert_true(v:errors[0] =~ "Expected NULL but got ''") call remove(v:errors, 0) endtry endfunc func Test_assert_fail_fails() call assert_fails('xxx', {}) ! call assert_true(v:errors[0] =~ "Expected {} but got 'E731:") call remove(v:errors, 0) endfunc --- 57,82 ---- call assert_equal(s:w, '') catch call assert_exception('E724:') ! call assert_match("Expected NULL but got ''", v:errors[0]) call remove(v:errors, 0) endtry 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() call assert_fails('xxx', {}) ! call assert_match("Expected {} but got 'E731:", v:errors[0]) call remove(v:errors, 0) endfunc *** ../vim-7.4.1662/src/testdir/test_channel.vim 2016-03-26 22:56:41.879646383 +0100 --- src/testdir/test_channel.vim 2016-03-27 14:58:52.667051107 +0200 *************** *** 154,160 **** " Request command "foo bar", which fails silently. call assert_equal('ok', ch_evalexpr(handle, 'bad command')) call s:waitFor('v:errmsg =~ "E492"') ! call assert_true(v:errmsg =~ 'E492:.*foo bar') call assert_equal('ok', ch_evalexpr(handle, 'do normal', {'timeout': 100})) call s:waitFor('"added more" == getline("$")') --- 154,160 ---- " Request command "foo bar", which fails silently. call assert_equal('ok', ch_evalexpr(handle, 'bad command')) call s:waitFor('v:errmsg =~ "E492"') ! call assert_match('E492:.*foo bar', v:errmsg) call assert_equal('ok', ch_evalexpr(handle, 'do normal', {'timeout': 100})) call s:waitFor('"added more" == getline("$")') *** ../vim-7.4.1662/runtime/doc/eval.txt 2016-03-26 20:59:48.111431615 +0100 --- runtime/doc/eval.txt 2016-03-27 14:57:21.339992803 +0200 *************** *** 1783,1793 **** 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_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_true( {actual} [, {msg}]) none assert {actual} is true asin( {expr}) Float arc sine of {expr} atan( {expr}) Float arc tangent of {expr} --- 1800,1811 ---- 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_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_true( {actual} [, {msg}]) none assert {actual} is true asin( {expr}) Float arc sine of {expr} atan( {expr}) Float arc tangent of {expr} *************** *** 2293,2303 **** assert_false({actual} [, {msg}]) *assert_false()* When {actual} is not false an error message is added to |v:errors|, like with |assert_equal()|. ! A value is false when it is zero. When "{actual}" is not a number the assert fails. When {msg} is omitted an error in the form "Expected False but got {actual}" is produced. assert_true({actual} [, {msg}]) *assert_true()* When {actual} is not true an error message is added to |v:errors|, like with |assert_equal()|. --- 2311,2341 ---- assert_false({actual} [, {msg}]) *assert_false()* When {actual} is not false an error message is added to |v:errors|, like with |assert_equal()|. ! A value is false when it is zero. When {actual} is not a number the assert fails. When {msg} is omitted an error in the form "Expected False but 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()* When {actual} is not true an error message is added to |v:errors|, like with |assert_equal()|. *** ../vim-7.4.1662/src/version.c 2016-03-26 22:56:41.883646341 +0100 --- src/version.c 2016-03-27 14:58:18.059407930 +0200 *************** *** 750,751 **** --- 750,753 ---- { /* Add new patch number below this line */ + /**/ + 1663, /**/ -- hundred-and-one symptoms of being an internet addict: 138. You develop a liking for cold coffee. /// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net \\\ /// sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\ \\\ an exciting new programming language -- http://www.Zimbu.org /// \\\ help me help AIDS victims -- http://ICCF-Holland.org ///