diff --git a/src/libraries/turtle/check.hpp b/src/libraries/turtle/check.hpp index 3abc59b..f1521d8 100644 --- a/src/libraries/turtle/check.hpp +++ b/src/libraries/turtle/check.hpp @@ -15,6 +15,8 @@ #include "format.hpp" #include #include +#include +#include #include #include @@ -22,47 +24,84 @@ namespace mock { namespace detail { + template< typename Constraint, typename Actual > + struct ConstraintCompatible : private boost::noncopyable + { + public: + BOOST_CONCEPT_USAGE( ConstraintCompatible ) + { + // if an error is generated by the line below it means an argument + // passed to 'with' was of the wrong type. + constraint_accepts( actual_argument_type ); + } + private: + ConstraintCompatible( int ) {} + Constraint constraint_accepts; + Actual actual_argument_type; + }; + + template< typename Expected, typename Actual > + struct EqualityComparable : private boost::noncopyable + { + public: + BOOST_CONCEPT_USAGE( EqualityComparable ) + { + boost::require_boolean_expr( + // if an error is generated by the line below it means an argument + // passed to 'with' was of the wrong type. + actual_argument_type == expected_argument_type + ); + } + private: + EqualityComparable( int ) {} + Expected expected_argument_type; + Actual actual_argument_type; + }; + template< typename Actual > class check { typedef BOOST_DEDUCED_TYPENAME - boost::function< bool( Actual ) > functor_type; + boost::function< bool( Actual ) > constraint_type; public: - template< typename Functor > - explicit check( const Functor& functor, + template< typename Constraint > + explicit check( const Constraint& constraint, BOOST_DEDUCED_TYPENAME boost::enable_if< - BOOST_DEDUCED_TYPENAME detail::is_functor< Functor > + BOOST_DEDUCED_TYPENAME detail::is_functor< Constraint > >::type* = 0 ) - : functor_( functor ) - , desc_ ( "?" ) + : desc_( "?" ) { - if( !functor_ ) - std::invalid_argument( "invalid functor" ); + BOOST_CONCEPT_ASSERT(( ConstraintCompatible< Constraint, Actual > )); + constraint_ = constraint; + if( !constraint_ ) + std::invalid_argument( "invalid constraint" ); } template< typename Expected > explicit check( const Expected& expected, BOOST_DEDUCED_TYPENAME boost::disable_if< BOOST_DEDUCED_TYPENAME detail::is_functor< Expected > >::type* = 0 ) - : functor_( mock::equal( expected ).functor_ ) - , desc_ ( format( expected ) ) + : desc_( format( expected ) ) { - if( !functor_ ) - std::invalid_argument( "invalid functor" ); + BOOST_CONCEPT_ASSERT(( EqualityComparable< Expected, Actual > )); + constraint_ = mock::equal( expected ).constraint_; + if( !constraint_ ) + std::invalid_argument( "invalid constraint" ); } template< typename Constraint > explicit check( const placeholder< Constraint >& ph ) - : functor_( ph.functor_ ) - , desc_ ( ph.desc_ ) + : desc_( ph.desc_ ) { - if( !functor_ ) - std::invalid_argument( "invalid functor" ); + BOOST_CONCEPT_ASSERT(( ConstraintCompatible< Constraint, Actual > )); + constraint_ = ph.constraint_; + if( !constraint_ ) + std::invalid_argument( "invalid constraint" ); } bool operator()( Actual actual ) const { - return functor_( actual ); + return constraint_( actual ); } friend std::ostream& operator<<( std::ostream& s, const check& c ) @@ -71,7 +110,7 @@ namespace detail } private: - functor_type functor_; + constraint_type constraint_; std::string desc_; }; } diff --git a/src/libraries/turtle/constraint.hpp b/src/libraries/turtle/constraint.hpp index 507fe43..72b42d5 100644 --- a/src/libraries/turtle/constraint.hpp +++ b/src/libraries/turtle/constraint.hpp @@ -46,7 +46,7 @@ namespace detail placeholder() : desc_( "any" ) {} - any functor_; + any constraint_; std::string desc_; }; template<> @@ -55,7 +55,7 @@ namespace detail placeholder() : desc_( "negate" ) {} - negate functor_; + negate constraint_; std::string desc_; }; template<> @@ -64,7 +64,7 @@ namespace detail placeholder() : desc_( "evaluate" ) {} - evaluate functor_; + evaluate constraint_; std::string desc_; }; } @@ -102,7 +102,7 @@ namespace detail detail::or_< detail::less< T >, detail::equal< T > > > less_equal( T t ) { - return constraint( (less( t ) || equal( t )).functor_, + return constraint( (less( t ) || equal( t )).constraint_, "less_equal", t ); } @@ -111,7 +111,7 @@ namespace detail detail::or_< detail::greater< T >, detail::equal< T > > > greater_equal( T t ) { - return constraint( (greater( t ) || equal( t )).functor_, + return constraint( (greater( t ) || equal( t )).constraint_, "greater_equal", t ); } diff --git a/src/libraries/turtle/placeholder.hpp b/src/libraries/turtle/placeholder.hpp index b15548b..789d761 100644 --- a/src/libraries/turtle/placeholder.hpp +++ b/src/libraries/turtle/placeholder.hpp @@ -15,14 +15,14 @@ namespace mock { namespace detail { - template< typename Functor > + template< typename Constraint > struct placeholder { - placeholder( const Functor& f, const std::string& desc ) - : functor_( f ) - , desc_ ( desc ) + placeholder( const Constraint& c, const std::string& desc ) + : constraint_( c ) + , desc_ ( desc ) {} - Functor functor_; + Constraint constraint_; std::string desc_; }; @@ -84,7 +84,7 @@ namespace detail const placeholder< F2 >& rhs ) { return placeholder< or_< F1, F2 > >( - or_< F1, F2 >( lhs.functor_, rhs.functor_ ), + or_< F1, F2 >( lhs.constraint_, rhs.constraint_ ), "(" + lhs.desc_ + " || " + rhs.desc_ + ")" ); } @@ -94,7 +94,7 @@ namespace detail const placeholder< F2 >& rhs ) { return placeholder< and_< F1, F2 > >( - and_< F1, F2 >( lhs.functor_, rhs.functor_ ), + and_< F1, F2 >( lhs.constraint_, rhs.constraint_ ), "(" + lhs.desc_ + " && " + rhs.desc_ + ")" ); } @@ -103,7 +103,7 @@ namespace detail operator!( const placeholder< F >& ph ) { return placeholder< not_< F > >( - not_< F >( ph.functor_ ), "! " + ph.desc_ ); + not_< F >( ph.constraint_ ), "! " + ph.desc_ ); } } } diff --git a/src/tests/turtle_test/constraint_test.cpp b/src/tests/turtle_test/constraint_test.cpp index 466e423..8366af3 100644 --- a/src/tests/turtle_test/constraint_test.cpp +++ b/src/tests/turtle_test/constraint_test.cpp @@ -48,21 +48,21 @@ BOOST_AUTO_TEST_CASE( same ) int i = 0; int j = 0; BOOST_CHECK_EQUAL( i, j ); - BOOST_CHECK( ! mock::same( i ).functor_( j ) ); - BOOST_CHECK( mock::same( i ).functor_( i ) ); + BOOST_CHECK( ! mock::same( i ).constraint_( j ) ); + BOOST_CHECK( mock::same( i ).constraint_( i ) ); } BOOST_AUTO_TEST_CASE( assign ) { { int i = 0; - BOOST_CHECK( mock::assign( 3 ).functor_( i ) ); + BOOST_CHECK( mock::assign( 3 ).constraint_( i ) ); BOOST_CHECK_EQUAL( 3, i ); } { const int* i = 0; const int j = 1; - BOOST_CHECK( mock::assign( &j ).functor_( i ) ); + BOOST_CHECK( mock::assign( &j ).constraint_( i ) ); BOOST_CHECK_EQUAL( i, &j ); } } @@ -72,49 +72,49 @@ BOOST_AUTO_TEST_CASE( retrieve ) { int i = 0; const int j = 1; - BOOST_CHECK( mock::retrieve( i ).functor_( j ) ); + BOOST_CHECK( mock::retrieve( i ).constraint_( j ) ); BOOST_CHECK_EQUAL( i, j ); } { int* i = 0; int j = 1; - BOOST_CHECK( mock::retrieve( i ).functor_( &j ) ); + BOOST_CHECK( mock::retrieve( i ).constraint_( &j ) ); BOOST_CHECK_EQUAL( i, &j ); } { const int* i = 0; const int j = 1; - BOOST_CHECK( mock::retrieve( i ).functor_( j ) ); + BOOST_CHECK( mock::retrieve( i ).constraint_( j ) ); BOOST_CHECK_EQUAL( i, &j ); } { const int* i = 0; int j = 1; - BOOST_CHECK( mock::retrieve( i ).functor_( j ) ); + BOOST_CHECK( mock::retrieve( i ).constraint_( j ) ); BOOST_CHECK_EQUAL( i, &j ); } { int* i = 0; int j = 1; - BOOST_CHECK( mock::retrieve( i ).functor_( j ) ); + BOOST_CHECK( mock::retrieve( i ).constraint_( j ) ); BOOST_CHECK_EQUAL( i, &j ); } { const int* i = 0; const int j = 1; - BOOST_CHECK( mock::retrieve( i ).functor_( j ) ); + BOOST_CHECK( mock::retrieve( i ).constraint_( j ) ); BOOST_CHECK_EQUAL( i, &j ); } { int** i = 0; int* j = 0; - BOOST_CHECK( mock::retrieve( i ).functor_( j ) ); + BOOST_CHECK( mock::retrieve( i ).constraint_( j ) ); BOOST_CHECK_EQUAL( i, &j ); } { const int** i = 0; const int* j = 0; - BOOST_CHECK( mock::retrieve( i ).functor_( j ) ); + BOOST_CHECK( mock::retrieve( i ).constraint_( j ) ); BOOST_CHECK_EQUAL( i, &j ); } } @@ -137,15 +137,15 @@ BOOST_AUTO_TEST_CASE( retrieve_uses_assignment_operator ) { B b; const A a = A(); - mock::retrieve( b ).functor_( a ); + mock::retrieve( b ).constraint_( a ); } BOOST_AUTO_TEST_CASE( negate ) { int* i = 0; int j; - BOOST_CHECK( mock::negate.functor_( i ) ); - BOOST_CHECK( ! mock::negate.functor_( &j ) ); + BOOST_CHECK( mock::negate.constraint_( i ) ); + BOOST_CHECK( ! mock::negate.constraint_( &j ) ); } namespace @@ -162,12 +162,12 @@ namespace BOOST_AUTO_TEST_CASE( evaluate ) { - BOOST_CHECK( mock::evaluate.functor_( &return_true ) ); - BOOST_CHECK( ! mock::evaluate.functor_( &return_false ) ); + BOOST_CHECK( mock::evaluate.constraint_( &return_true ) ); + BOOST_CHECK( ! mock::evaluate.constraint_( &return_false ) ); } BOOST_AUTO_TEST_CASE( contain ) { - BOOST_CHECK( mock::contain( "string" ).functor_( "this is a string" ) ); - BOOST_CHECK( ! mock::contain( "not found" ).functor_( "this is a string" ) ); + BOOST_CHECK( mock::contain( "string" ).constraint_( "this is a string" ) ); + BOOST_CHECK( ! mock::contain( "not found" ).constraint_( "this is a string" ) ); }