]> granicus.if.org Git - vim/commitdiff
patch 7.4.1663 v7.4.1663
authorBram Moolenaar <Bram@vim.org>
Sun, 27 Mar 2016 13:13:38 +0000 (15:13 +0200)
committerBram Moolenaar <Bram@vim.org>
Sun, 27 Mar 2016 13:13:38 +0000 (15:13 +0200)
Problem:    In tests it's often useful to check if a pattern matches.
Solution:   Add assert_match().

runtime/doc/eval.txt
src/eval.c
src/testdir/test_assert.vim
src/testdir/test_channel.vim
src/version.c

index c2e9a7160a044584a40669c193019ffa5aba1827..79cf58cf961ac4ff4c06c69c8a46a3ac56b8c1dd 100644 (file)
@@ -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
@@ -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_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}
@@ -2315,6 +2316,26 @@ assert_false({actual} [, {msg}])                         *assert_false()*
                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()|.
index 49289070d22d86d03e099691d8906303e3e623a2..ea7f9090aae794c83d400c5ac9a294216d2858da 100644 (file)
@@ -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_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);
@@ -4105,6 +4106,31 @@ get_user_var_name(expand_T *xp, int idx)
 
 #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(&regmatch, text, (colnr_T)0);
+       vim_regfree(regmatch.regprog);
+    }
+    p_cpo = save_cpo;
+    return matches;
+}
+
 /*
  * types for expressions.
  */
@@ -4403,9 +4429,7 @@ eval4(char_u **arg, typval_T *rettv, int evaluate)
     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.
@@ -4646,20 +4670,9 @@ eval4(char_u **arg, typval_T *rettv, int evaluate)
 
                    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(&regmatch, s1, (colnr_T)0);
-                               vim_regfree(regmatch.regprog);
-                               if (type == TYPE_NOMATCH)
-                                   n1 = !n1;
-                           }
-                           p_cpo = save_cpo;
+                           n1 = pattern_match(s2, s1, ic);
+                           if (type == TYPE_NOMATCH)
+                               n1 = !n1;
                            break;
 
                    case TYPE_UNKNOWN:  break;  /* avoid gcc warning */
@@ -8154,6 +8167,7 @@ static struct fst
     {"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,7 +9309,7 @@ f_argv(typval_T *argvars, typval_T *rettv)
 }
 
 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_bool(typval_T *argvars, int isTrue);
 
@@ -9370,7 +9384,8 @@ fill_assert_error(
     typval_T   *opt_msg_tv,
     char_u      *exp_str,
     typval_T   *exp_tv,
-    typval_T   *got_tv)
+    typval_T   *got_tv,
+    int                is_match)
 {
     char_u     numbuf[NUMBUFLEN];
     char_u     *tofree;
@@ -9382,7 +9397,10 @@ fill_assert_error(
     }
     else
     {
-       ga_concat(gap, (char_u *)"Expected ");
+       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,7 +9408,10 @@ fill_assert_error(
        }
        else
            ga_concat_esc(gap, exp_str);
-       ga_concat(gap, (char_u *)" but got ");
+       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,7 +9442,8 @@ f_assert_equal(typval_T *argvars, typval_T *rettv UNUSED)
     if (!tv_equal(&argvars[0], &argvars[1], FALSE, FALSE))
     {
        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);
        ga_clear(&ga);
     }
@@ -9449,7 +9471,7 @@ f_assert_exception(typval_T *argvars, typval_T *rettv UNUSED)
     {
        prepare_assert_error(&ga);
        fill_assert_error(&ga, &argvars[1], NULL, &argvars[0],
-                                               &vimvars[VV_EXCEPTION].vv_tv);
+                                        &vimvars[VV_EXCEPTION].vv_tv, FALSE);
        assert_error(&ga);
        ga_clear(&ga);
     }
@@ -9486,7 +9508,7 @@ f_assert_fails(typval_T *argvars, typval_T *rettv UNUSED)
        {
            prepare_assert_error(&ga);
            fill_assert_error(&ga, &argvars[2], NULL, &argvars[1],
-                                               &vimvars[VV_ERRMSG].vv_tv);
+                                           &vimvars[VV_ERRMSG].vv_tv, FALSE);
            assert_error(&ga);
            ga_clear(&ga);
        }
@@ -9518,7 +9540,7 @@ assert_bool(typval_T *argvars, int isTrue)
        prepare_assert_error(&ga);
        fill_assert_error(&ga, &argvars[1],
                (char_u *)(isTrue ? "True" : "False"),
-               NULL, &argvars[0]);
+               NULL, &argvars[0], FALSE);
        assert_error(&ga);
        ga_clear(&ga);
     }
@@ -9533,6 +9555,28 @@ f_assert_false(typval_T *argvars, typval_T *rettv UNUSED)
     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
  */
index 2ac828b282f946a644f2d2a487185e453d2208fd..bc025b4c4352b2c4946a2c6b3ecace31243507c2 100644 (file)
@@ -57,14 +57,26 @@ func Test_compare_fail()
     call assert_equal(s:w, '')
   catch
     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)
   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_true(v:errors[0] =~ "Expected {} but got 'E731:")
+  call assert_match("Expected {} but got 'E731:", v:errors[0])
   call remove(v:errors, 0)
 endfunc
 
index 705122317ab6c65ed07187444730ae02470baf91..94311e9a69d8c376a11c937485b89d29083949e2 100644 (file)
@@ -154,7 +154,7 @@ func s:communicate(port)
   " 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_match('E492:.*foo bar', v:errmsg)
 
   call assert_equal('ok', ch_evalexpr(handle, 'do normal', {'timeout': 100}))
   call s:waitFor('"added more" == getline("$")')
index b19190daa36f451c018aa8a15c238b86e162bc8c..f21fb6bb1552b1a2cc8cdbabaa3198589e09d90c 100644 (file)
@@ -748,6 +748,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    1663,
 /**/
     1662,
 /**/