1 // (C) Copyright Gennadiy Rozental 2011-2015.
2 // Distributed under the Boost Software License, Version 1.0.
3 // (See accompanying file LICENSE_1_0.txt or copy at
4 // http://www.boost.org/LICENSE_1_0.txt)
6 // See http://www.boost.org/libs/test for the library home page.
10 // Version : $Revision: 62023 $
12 // Description : unit test for new assertion construction based on input expression
13 // ***************************************************************************
16 #define BOOST_TEST_MODULE Boost.Test assertion consruction test
17 #include <boost/test/unit_test.hpp>
18 #include <boost/test/tools/assertion.hpp>
19 #include <boost/test/utils/is_forward_iterable.hpp>
21 #include <boost/noncopyable.hpp>
26 namespace utf
= boost::unit_test
;
28 //____________________________________________________________________________//
30 #define EXPR_TYPE( expr ) ( assertion::seed() ->* expr )
32 // some broken compilers do not implement properly decltype on expressions
33 // partial implementation of is_forward_iterable when decltype not available
34 struct not_fwd_iterable_1
{
35 typedef int const_iterator
;
36 typedef int value_type
;
41 struct not_fwd_iterable_2
{
42 typedef int const_iterator
;
43 typedef int value_type
;
48 struct not_fwd_iterable_3
{
49 typedef int value_type
;
54 BOOST_AUTO_TEST_CASE( test_forward_iterable_concept
)
57 typedef std::vector
<int> type
;
58 BOOST_CHECK_MESSAGE(utf::ut_detail::has_member_size
<type
>::value
, "has_member_size failed");
59 BOOST_CHECK_MESSAGE(utf::ut_detail::has_member_begin
<type
>::value
, "has_member_begin failed");
60 BOOST_CHECK_MESSAGE(utf::is_forward_iterable
< type
>::value
, "is_forward_iterable failed");
64 // should also work for references, but from is_forward_iterable
65 typedef std::vector
<int>& type
;
66 BOOST_CHECK_MESSAGE(utf::is_forward_iterable
< type
>::value
, "is_forward_iterable failed");
71 typedef std::list
<int> type
;
72 BOOST_CHECK_MESSAGE(utf::ut_detail::has_member_size
<type
>::value
, "has_member_size failed");
73 BOOST_CHECK_MESSAGE(utf::ut_detail::has_member_begin
<type
>::value
, "has_member_begin failed");
74 BOOST_CHECK_MESSAGE(utf::is_forward_iterable
< type
>::value
, "is_forward_iterable failed");
78 typedef std::map
<int, int> type
;
79 BOOST_CHECK_MESSAGE(utf::ut_detail::has_member_size
<type
>::value
, "has_member_size failed");
80 BOOST_CHECK_MESSAGE(utf::ut_detail::has_member_begin
<type
>::value
, "has_member_begin failed");
81 BOOST_CHECK_MESSAGE(utf::is_forward_iterable
< type
>::value
, "is_forward_iterable failed");
85 typedef std::set
<int, int> type
;
86 BOOST_CHECK_MESSAGE(utf::ut_detail::has_member_size
<type
>::value
, "has_member_size failed");
87 BOOST_CHECK_MESSAGE(utf::ut_detail::has_member_begin
<type
>::value
, "has_member_begin failed");
88 BOOST_CHECK_MESSAGE(utf::is_forward_iterable
< type
>::value
, "is_forward_iterable failed");
94 BOOST_CHECK_MESSAGE(!utf::ut_detail::has_member_size
<type
>::value
, "has_member_size failed");
95 BOOST_CHECK_MESSAGE(!utf::ut_detail::has_member_begin
<type
>::value
, "has_member_begin failed");
96 BOOST_CHECK_MESSAGE(!utf::is_forward_iterable
< type
>::value
, "is_forward_iterable failed");
100 typedef not_fwd_iterable_1 type
;
101 BOOST_CHECK_MESSAGE(utf::ut_detail::has_member_size
<type
>::value
, "has_member_size failed");
102 BOOST_CHECK_MESSAGE(!utf::ut_detail::has_member_begin
<type
>::value
, "has_member_begin failed");
103 BOOST_CHECK_MESSAGE(!utf::is_forward_iterable
< type
>::value
, "is_forward_iterable failed");
107 typedef not_fwd_iterable_2 type
;
108 BOOST_CHECK_MESSAGE(!utf::ut_detail::has_member_size
<type
>::value
, "has_member_size failed");
109 BOOST_CHECK_MESSAGE(utf::ut_detail::has_member_begin
<type
>::value
, "has_member_begin failed");
110 BOOST_CHECK_MESSAGE(!utf::is_forward_iterable
< type
>::value
, "is_forward_iterable failed");
114 typedef not_fwd_iterable_3 type
;
115 BOOST_CHECK_MESSAGE(utf::ut_detail::has_member_size
<type
>::value
, "has_member_size failed");
116 BOOST_CHECK_MESSAGE(utf::ut_detail::has_member_begin
<type
>::value
, "has_member_begin failed");
117 BOOST_CHECK_MESSAGE(!utf::is_forward_iterable
< type
>::value
, "is_forward_iterable failed");
122 BOOST_CHECK_MESSAGE(!utf::ut_detail::has_member_size
<type
>::value
, "has_member_size failed");
123 BOOST_CHECK_MESSAGE(!utf::ut_detail::has_member_begin
<type
>::value
, "has_member_begin failed");
124 BOOST_CHECK_MESSAGE(!utf::is_forward_iterable
< type
>::value
, "is_forward_iterable failed");
128 // tables are not in the forward_iterable concept
129 typedef int type
[10];
130 BOOST_CHECK_MESSAGE(!utf::ut_detail::has_member_size
<type
>::value
, "has_member_size failed");
131 BOOST_CHECK_MESSAGE(!utf::ut_detail::has_member_begin
<type
>::value
, "has_member_begin failed");
132 BOOST_CHECK_MESSAGE(!utf::is_forward_iterable
< type
>::value
, "is_forward_iterable failed");
136 BOOST_AUTO_TEST_CASE( test_basic_value_expression_construction
)
138 using namespace boost::test_tools
;
141 predicate_result
const& res
= EXPR_TYPE( 1 ).evaluate();
143 BOOST_TEST( res
.message().is_empty() );
147 predicate_result
const& res
= EXPR_TYPE( 0 ).evaluate();
149 BOOST_TEST( res
.message() == " [(bool)0 is false]" );
153 predicate_result
const& res
= EXPR_TYPE( true ).evaluate();
155 BOOST_TEST( res
.message().is_empty() );
159 predicate_result
const& res
= EXPR_TYPE( 1.5 ).evaluate();
164 predicate_result
const& res
= EXPR_TYPE( "abc" ).evaluate();
169 predicate_result
const& res
= EXPR_TYPE( 1>2 ).evaluate();
171 BOOST_TEST( res
.message() == " [1 <= 2]" );
176 //____________________________________________________________________________//
178 BOOST_AUTO_TEST_CASE( test_comparison_expression
)
180 using namespace boost::test_tools
;
183 predicate_result
const& res
= EXPR_TYPE( 1>2 ).evaluate();
185 BOOST_TEST( res
.message() == " [1 <= 2]" );
189 predicate_result
const& res
= EXPR_TYPE( 100 < 50 ).evaluate();
191 BOOST_TEST( res
.message() == " [100 >= 50]" );
195 predicate_result
const& res
= EXPR_TYPE( 5 <= 4 ).evaluate();
197 BOOST_TEST( res
.message() == " [5 > 4]" );
201 predicate_result
const& res
= EXPR_TYPE( 10>=20 ).evaluate();
203 BOOST_TEST( res
.message() == " [10 < 20]" );
208 predicate_result
const& res
= EXPR_TYPE( i
!= 10 ).evaluate();
210 BOOST_TEST( res
.message() == " [10 == 10]" );
215 predicate_result
const& res
= EXPR_TYPE( i
== 3 ).evaluate();
217 BOOST_TEST( res
.message() == " [5 != 3]" );
221 //____________________________________________________________________________//
223 BOOST_AUTO_TEST_CASE( test_arithmetic_ops
)
225 using namespace boost::test_tools
;
230 predicate_result
const& res
= EXPR_TYPE( i
+j
!=8 ).evaluate();
232 BOOST_TEST( res
.message() == " [3 + 5 == 8]" );
238 predicate_result
const& res
= EXPR_TYPE( 2*i
-j
> 1 ).evaluate();
240 BOOST_TEST( res
.message() == " [2 * 3 - 5 <= 1]" );
245 predicate_result
const& res
= EXPR_TYPE( 2<<j
< 30 ).evaluate();
247 BOOST_TEST( res
.message() == " [2 << 5 >= 30]" );
253 predicate_result
const& res
= EXPR_TYPE( i
&j
).evaluate();
255 BOOST_TEST( res
.message() == " [2 & 5]" );
261 predicate_result
const& res
= EXPR_TYPE( i
^j
^6 ).evaluate();
263 BOOST_TEST( res
.message() == " [3 ^ 5 ^ 6]" );
267 // EXPR_TYPE( 99/2 == 48 || 101/2 > 50 );
268 // EXPR_TYPE( a ? 100 < 50 : 25*2 == 50 );
269 // EXPR_TYPE( true,false );
272 //____________________________________________________________________________//
275 static int s_copy_counter
;
277 Testee() : m_value( false ) {}
278 Testee( Testee
const& ) : m_value(false) { s_copy_counter
++; }
279 Testee( Testee
&& ) : m_value(false) {}
280 Testee( Testee
const&& ) : m_value(false) {}
282 bool foo() { return m_value
; }
283 operator bool() const { return m_value
; }
285 friend std::ostream
& operator<<( std::ostream
& ostr
, Testee
const& ) { return ostr
<< "Testee"; }
290 int Testee::s_copy_counter
= 0;
292 Testee
get_obj() { return Testee(); }
293 Testee
const get_const_obj() { return Testee(); }
295 class NC
: boost::noncopyable
{
299 bool operator==(NC
const&) const { return false; }
300 friend std::ostream
& operator<<(std::ostream
& ostr
, NC
const&)
306 BOOST_AUTO_TEST_CASE( test_objects
)
308 using namespace boost::test_tools
;
310 int expected_copy_count
= 0;
314 Testee::s_copy_counter
= 0;
316 predicate_result
const& res
= EXPR_TYPE( obj
).evaluate();
318 BOOST_TEST( res
.message() == " [(bool)Testee is false]" );
319 BOOST_TEST( Testee::s_copy_counter
== expected_copy_count
);
324 Testee::s_copy_counter
= 0;
326 predicate_result
const& res
= EXPR_TYPE( obj
).evaluate();
328 BOOST_TEST( res
.message() == " [(bool)Testee is false]" );
329 BOOST_TEST( Testee::s_copy_counter
== expected_copy_count
);
333 Testee::s_copy_counter
= 0;
335 predicate_result
const& res
= EXPR_TYPE( get_obj() ).evaluate();
337 BOOST_TEST( res
.message() == " [(bool)Testee is false]" );
338 BOOST_TEST( Testee::s_copy_counter
== expected_copy_count
);
342 Testee::s_copy_counter
= 0;
344 predicate_result
const& res
= EXPR_TYPE( get_const_obj() ).evaluate();
346 BOOST_TEST( res
.message() == " [(bool)Testee is false]" );
347 BOOST_TEST( Testee::s_copy_counter
== expected_copy_count
);
351 Testee::s_copy_counter
= 0;
356 predicate_result
const& res
= EXPR_TYPE( t1
!= t2
).evaluate();
358 BOOST_TEST( res
.message() == " [Testee == Testee]" );
359 BOOST_TEST( Testee::s_copy_counter
== 0 );
366 predicate_result
const& res
= EXPR_TYPE( nc1
== nc2
).evaluate();
368 BOOST_TEST( res
.message() == " [NC != NC]" );
372 //____________________________________________________________________________//
374 BOOST_AUTO_TEST_CASE( test_pointers
)
376 using namespace boost::test_tools
;
381 predicate_result
const& res
= EXPR_TYPE( ptr
).evaluate();
389 predicate_result
const& res
= EXPR_TYPE( &obj1
== &obj2
).evaluate();
397 predicate_result
const& res
= EXPR_TYPE( *ptr
).evaluate();
399 BOOST_TEST( res
.message() == " [(bool)Testee is false]" );
405 bool Testee::* mem_ptr
=&Testee::m_value
;
407 predicate_result
const& res
= EXPR_TYPE( ptr
->*mem_ptr
).evaluate();
413 // bool Testee::* mem_ptr =&Testee::m_value;
414 // EXPR_TYPE( obj.*mem_ptr );
417 //____________________________________________________________________________//
419 BOOST_AUTO_TEST_CASE( test_mutating_ops
)
421 using namespace boost::test_tools
;
426 predicate_result
const& res
= EXPR_TYPE( j
= 0 ).evaluate();
428 BOOST_TEST( res
.message() == " [(bool)0 is false]" );
429 BOOST_TEST( j
== 0 );
435 predicate_result
const& res
= EXPR_TYPE( j
-= 5 ).evaluate();
437 BOOST_TEST( res
.message() == " [(bool)0 is false]" );
438 BOOST_TEST( j
== 0 );
444 predicate_result
const& res
= EXPR_TYPE( j
*= 0 ).evaluate();
446 BOOST_TEST( res
.message() == " [(bool)0 is false]" );
447 BOOST_TEST( j
== 0 );
453 predicate_result
const& res
= EXPR_TYPE( j
/= 10 ).evaluate();
455 BOOST_TEST( res
.message() == " [(bool)0 is false]" );
456 BOOST_TEST( j
== 0 );
462 predicate_result
const& res
= EXPR_TYPE( j
%= 2 ).evaluate();
464 BOOST_TEST( res
.message() == " [(bool)0 is false]" );
465 BOOST_TEST( j
== 0 );
471 predicate_result
const& res
= EXPR_TYPE( j
^= j
).evaluate();
473 BOOST_TEST( res
.message() == " [(bool)0 is false]" );
474 BOOST_TEST( j
== 0 );