mirror of
https://github.com/mat007/turtle.git
synced 2026-06-22 12:13:43 +00:00
Added concept checks
git-svn-id: https://svn.code.sf.net/p/turtle/code/trunk@129 860be788-9bd5-4423-9f1e-828f051e677b
This commit is contained in:
parent
1167f2afca
commit
f02dd801b5
4 changed files with 89 additions and 50 deletions
|
|
@ -15,6 +15,8 @@
|
|||
#include "format.hpp"
|
||||
#include <boost/function.hpp>
|
||||
#include <boost/utility/enable_if.hpp>
|
||||
#include <boost/concept/assert.hpp>
|
||||
#include <boost/concept_check.hpp>
|
||||
#include <stdexcept>
|
||||
#include <ostream>
|
||||
|
||||
|
|
@ -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_;
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 );
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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 )
|
||||
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_ );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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" ) );
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue