1 ///////////////////////////////////////////////////////////////////////////////
2 // test_assert.cpp
3 //
4 //  Copyright 2008 Eric Niebler. Distributed under the Boost
5 //  Software License, Version 1.0. (See accompanying file
6 //  LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
7 
8 #include <iostream>
9 #include <boost/xpressive/xpressive_static.hpp>
10 #include <boost/xpressive/regex_actions.hpp>
11 #include <boost/test/unit_test.hpp>
12 
13 using namespace boost::xpressive;
14 
three_or_six(ssub_match const & sub)15 bool three_or_six(ssub_match const &sub)
16 {
17     return sub.length() == 3 || sub.length() == 6;
18 }
19 
20 ///////////////////////////////////////////////////////////////////////////////
21 // test1
22 //  simple custom assert that checks the length of a matched sub-expression
test1()23 void test1()
24 {
25     std::string str("foo barbaz fink");
26     // match words of 3 characters or 6 characters.
27     sregex rx = (bow >> +_w >> eow)[ check(&three_or_six) ] ;
28 
29     sregex_iterator first(str.begin(), str.end(), rx), last;
30     BOOST_CHECK_EQUAL(std::distance(first, last), 2);
31 }
32 
33 ///////////////////////////////////////////////////////////////////////////////
34 // test2
35 //  same as above, but using a lambda
test2()36 void test2()
37 {
38     std::string str("foo barbaz fink");
39     // match words of 3 characters or 6 characters.
40     sregex rx = (bow >> +_w >> eow)[ check(length(_)==3 || length(_)==6) ] ;
41 
42     sregex_iterator first(str.begin(), str.end(), rx), last;
43     BOOST_CHECK_EQUAL(std::distance(first, last), 2);
44 }
45 
46 ///////////////////////////////////////////////////////////////////////////////
47 // test3
48 //  more complicated use of custom assertions to validate a date
test3()49 void test3()
50 {
51     int const days_per_month[] =
52         {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 31, 31};
53 
54     mark_tag month(1), day(2);
55     // find a valid date of the form month/day/year.
56     sregex date =
57         (
58             // Month must be between 1 and 12 inclusive
59             (month= _d >> !_d)     [ check(as<int>(_) >= 1
60                                         && as<int>(_) <= 12) ]
61         >>  '/'
62             // Day must be between 1 and 31 inclusive
63         >>  (day=   _d >> !_d)     [ check(as<int>(_) >= 1
64                                         && as<int>(_) <= 31) ]
65         >>  '/'
66             // Only consider years between 1970 and 2038
67         >>  (_d >> _d >> _d >> _d) [ check(as<int>(_) >= 1970
68                                         && as<int>(_) <= 2038) ]
69         )
70         // Ensure the month actually has that many days.
71         [ check( ref(days_per_month)[as<int>(month)-1] >= as<int>(day) ) ]
72     ;
73 
74     smatch what;
75     std::string str("99/99/9999 2/30/2006 2/28/2006");
76 
77     BOOST_REQUIRE(regex_search(str, what, date));
78     BOOST_CHECK_EQUAL(what[0], "2/28/2006");
79 }
80 
81 using namespace boost::unit_test;
82 
83 ///////////////////////////////////////////////////////////////////////////////
84 // init_unit_test_suite
85 //
init_unit_test_suite(int argc,char * argv[])86 test_suite* init_unit_test_suite( int argc, char* argv[] )
87 {
88     test_suite *test = BOOST_TEST_SUITE("test_assert");
89     test->add(BOOST_TEST_CASE(&test1));
90     test->add(BOOST_TEST_CASE(&test2));
91     test->add(BOOST_TEST_CASE(&test3));
92     return test;
93 }
94 
95