mirror of
https://github.com/mat007/turtle.git
synced 2026-06-22 12:13:43 +00:00
Moved some components into a detail sub-directory
git-svn-id: https://svn.code.sf.net/p/turtle/code/trunk@482 860be788-9bd5-4423-9f1e-828f051e677b
This commit is contained in:
parent
24e618ee8c
commit
3ab7fea2a0
26 changed files with 78 additions and 78 deletions
219
turtle/detail/action.hpp
Normal file
219
turtle/detail/action.hpp
Normal file
|
|
@ -0,0 +1,219 @@
|
|||
// http://turtle.sourceforge.net
|
||||
//
|
||||
// Copyright Mathieu Champlon 2008
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef MOCK_ACTION_HPP_INCLUDED
|
||||
#define MOCK_ACTION_HPP_INCLUDED
|
||||
|
||||
#include "lambda.hpp"
|
||||
#include <boost/type_traits/remove_reference.hpp>
|
||||
#include <boost/type_traits/remove_const.hpp>
|
||||
#include <boost/shared_ptr.hpp>
|
||||
#include <boost/function.hpp>
|
||||
#include <boost/ref.hpp>
|
||||
|
||||
namespace mock
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
template< typename Result, typename Signature >
|
||||
class action
|
||||
{
|
||||
typedef BOOST_DEDUCED_TYPENAME
|
||||
boost::function< Signature > functor_type;
|
||||
typedef BOOST_DEDUCED_TYPENAME
|
||||
boost::remove_reference<
|
||||
BOOST_DEDUCED_TYPENAME boost::remove_const< Result >::type
|
||||
>::type result_type;
|
||||
|
||||
typedef lambda< Result, Signature > lambda_type;
|
||||
|
||||
public:
|
||||
template< typename Value >
|
||||
void returns( Value v )
|
||||
{
|
||||
// if an error is generated by the line below it means a value
|
||||
// passed to 'returns' was of the wrong type as it cannot be
|
||||
// used to copy construct a Result
|
||||
r_.reset( new result_type( v ) );
|
||||
f_ = lambda_type::make_val( boost::ref( *r_ ) );
|
||||
}
|
||||
template< typename Y >
|
||||
void returns( boost::reference_wrapper< Y > r )
|
||||
{
|
||||
f_ = lambda_type::make_val( r );
|
||||
}
|
||||
|
||||
void calls( const functor_type& f )
|
||||
{
|
||||
if( !f )
|
||||
throw std::invalid_argument( "null functor" );
|
||||
f_ = f;
|
||||
}
|
||||
|
||||
template< typename Exception >
|
||||
void throws( Exception e )
|
||||
{
|
||||
f_ = lambda_type::make_throw( e );
|
||||
}
|
||||
|
||||
const functor_type& functor() const
|
||||
{
|
||||
return f_;
|
||||
}
|
||||
|
||||
private:
|
||||
boost::shared_ptr< result_type > r_;
|
||||
functor_type f_;
|
||||
};
|
||||
|
||||
template< typename Result, typename Signature >
|
||||
class action< Result*, Signature >
|
||||
{
|
||||
typedef BOOST_DEDUCED_TYPENAME
|
||||
boost::function< Signature > functor_type;
|
||||
|
||||
typedef lambda< Result*, Signature > lambda_type;
|
||||
|
||||
public:
|
||||
void returns( Result* r )
|
||||
{
|
||||
f_ = lambda_type::make_val( r );
|
||||
}
|
||||
template< typename Y >
|
||||
void returns( boost::reference_wrapper< Y > r )
|
||||
{
|
||||
f_ = lambda_type::make_val( r );
|
||||
}
|
||||
|
||||
void calls( const functor_type& f )
|
||||
{
|
||||
if( !f )
|
||||
throw std::invalid_argument( "null functor" );
|
||||
f_ = f;
|
||||
}
|
||||
|
||||
template< typename Exception >
|
||||
void throws( Exception e )
|
||||
{
|
||||
f_ = lambda_type::make_throw( e );
|
||||
}
|
||||
|
||||
const functor_type& functor() const
|
||||
{
|
||||
return f_;
|
||||
}
|
||||
|
||||
private:
|
||||
functor_type f_;
|
||||
};
|
||||
|
||||
template< typename Signature >
|
||||
class action< void, Signature >
|
||||
{
|
||||
typedef BOOST_DEDUCED_TYPENAME
|
||||
boost::function< Signature > functor_type;
|
||||
|
||||
typedef lambda< void, Signature > lambda_type;
|
||||
|
||||
public:
|
||||
action()
|
||||
: f_( lambda_type::make_nothing() )
|
||||
{}
|
||||
|
||||
void calls( const functor_type& f )
|
||||
{
|
||||
if( !f )
|
||||
throw std::invalid_argument( "null functor" );
|
||||
f_ = f;
|
||||
}
|
||||
|
||||
template< typename Exception >
|
||||
void throws( Exception e )
|
||||
{
|
||||
f_ = lambda_type::make_throw( e );
|
||||
}
|
||||
|
||||
const functor_type& functor() const
|
||||
{
|
||||
return f_;
|
||||
}
|
||||
|
||||
private:
|
||||
functor_type f_;
|
||||
};
|
||||
|
||||
template< typename Result, typename Signature >
|
||||
class action< std::auto_ptr< Result >, Signature >
|
||||
{
|
||||
typedef BOOST_DEDUCED_TYPENAME
|
||||
boost::function< Signature > functor_type;
|
||||
|
||||
typedef lambda< std::auto_ptr< Result >, Signature > lambda_type;
|
||||
|
||||
public:
|
||||
action()
|
||||
{}
|
||||
action( const action& rhs )
|
||||
: r_( const_cast< action& >( rhs ).r_.release() )
|
||||
, f_( r_.get()
|
||||
? lambda_type::make_val( boost::ref( r_ ) )
|
||||
: rhs.f_ )
|
||||
{}
|
||||
|
||||
template< typename Value >
|
||||
void returns( Value v )
|
||||
{
|
||||
set( v );
|
||||
}
|
||||
|
||||
void calls( const functor_type& f )
|
||||
{
|
||||
if( !f )
|
||||
throw std::invalid_argument( "null functor" );
|
||||
f_ = f;
|
||||
}
|
||||
|
||||
template< typename Exception >
|
||||
void throws( Exception e )
|
||||
{
|
||||
f_ = lambda_type::make_throw( e );
|
||||
r_.reset();
|
||||
}
|
||||
|
||||
const functor_type& functor() const
|
||||
{
|
||||
return f_;
|
||||
}
|
||||
|
||||
private:
|
||||
template< typename Y >
|
||||
void set( std::auto_ptr< Y > r )
|
||||
{
|
||||
r_ = r;
|
||||
f_ = lambda_type::make_val( boost::ref( r_ ) );
|
||||
}
|
||||
template< typename Y >
|
||||
void set( boost::reference_wrapper< Y > r )
|
||||
{
|
||||
f_ = lambda_type::make_val( r );
|
||||
r_.reset();
|
||||
}
|
||||
template< typename Y >
|
||||
void set( Y* r )
|
||||
{
|
||||
r_.reset( r );
|
||||
f_ = lambda_type::make_val( boost::ref( r_ ) );
|
||||
}
|
||||
|
||||
std::auto_ptr< Result > r_;
|
||||
functor_type f_;
|
||||
};
|
||||
}
|
||||
} // mock
|
||||
|
||||
#endif // MOCK_ACTION_HPP_INCLUDED
|
||||
107
turtle/detail/check.hpp
Normal file
107
turtle/detail/check.hpp
Normal file
|
|
@ -0,0 +1,107 @@
|
|||
// http://turtle.sourceforge.net
|
||||
//
|
||||
// Copyright Mathieu Champlon 2008
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef MOCK_CHECK_HPP_INCLUDED
|
||||
#define MOCK_CHECK_HPP_INCLUDED
|
||||
|
||||
#include "operators.hpp"
|
||||
#include "../log.hpp"
|
||||
#include "../is_functor.hpp"
|
||||
#include <boost/utility/enable_if.hpp>
|
||||
#include <boost/noncopyable.hpp>
|
||||
#include <boost/ref.hpp>
|
||||
|
||||
namespace mock
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
template< typename Actual >
|
||||
class check_base : boost::noncopyable
|
||||
{
|
||||
public:
|
||||
virtual ~check_base() {}
|
||||
|
||||
virtual bool operator()( Actual ) = 0;
|
||||
|
||||
friend std::ostream& operator<<( std::ostream& s, const check_base& c )
|
||||
{
|
||||
c.serialize( s );
|
||||
return s;
|
||||
}
|
||||
private:
|
||||
virtual void serialize( std::ostream& ) const = 0;
|
||||
};
|
||||
|
||||
template< typename Actual, typename Expected, typename Enable = void >
|
||||
class check : public check_base< Actual >
|
||||
{
|
||||
public:
|
||||
explicit check( Expected expected )
|
||||
: expected_( expected )
|
||||
{}
|
||||
private:
|
||||
virtual bool operator()( Actual actual )
|
||||
{
|
||||
return actual == boost::unwrap_ref( expected_ );
|
||||
}
|
||||
virtual void serialize( std::ostream& s ) const
|
||||
{
|
||||
s << mock::format( expected_ );
|
||||
}
|
||||
private:
|
||||
Expected expected_;
|
||||
};
|
||||
|
||||
template< typename Actual, typename Constraint >
|
||||
class check< Actual, mock::constraint< Constraint > >
|
||||
: public check_base< Actual >
|
||||
{
|
||||
public:
|
||||
explicit check( const constraint< Constraint >& c )
|
||||
: c_( c.f_ )
|
||||
{}
|
||||
private:
|
||||
virtual bool operator()( Actual actual )
|
||||
{
|
||||
return c_( actual );
|
||||
}
|
||||
virtual void serialize( std::ostream& s ) const
|
||||
{
|
||||
s << mock::format( c_ );
|
||||
}
|
||||
private:
|
||||
Constraint c_;
|
||||
};
|
||||
|
||||
template< typename Actual, typename Functor >
|
||||
class check< Actual, Functor,
|
||||
BOOST_DEDUCED_TYPENAME boost::enable_if<
|
||||
detail::is_functor< Functor >
|
||||
>::type
|
||||
> : public check_base< Actual >
|
||||
{
|
||||
public:
|
||||
explicit check( const Functor& f )
|
||||
: f_( f )
|
||||
{}
|
||||
private:
|
||||
virtual bool operator()( Actual actual )
|
||||
{
|
||||
return f_( actual );
|
||||
}
|
||||
virtual void serialize( std::ostream& s ) const
|
||||
{
|
||||
s << mock::format( f_ );
|
||||
}
|
||||
private:
|
||||
Functor f_;
|
||||
};
|
||||
}
|
||||
} // mock
|
||||
|
||||
#endif // MOCK_CHECK_HPP_INCLUDED
|
||||
|
|
@ -9,8 +9,8 @@
|
|||
#ifndef MOCK_CHILD_HPP_INCLUDED
|
||||
#define MOCK_CHILD_HPP_INCLUDED
|
||||
|
||||
#include "detail/type_name.hpp"
|
||||
#include "detail/parent.hpp"
|
||||
#include "type_name.hpp"
|
||||
#include "parent.hpp"
|
||||
#include <boost/test/utils/basic_cstring/basic_cstring.hpp>
|
||||
#include <boost/optional.hpp>
|
||||
#include <ostream>
|
||||
|
|
|
|||
40
turtle/detail/cleanup.hpp
Normal file
40
turtle/detail/cleanup.hpp
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
// http://turtle.sourceforge.net
|
||||
//
|
||||
// Copyright Mathieu Champlon 2011
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef MOCK_CLEANUP_HPP_INCLUDED
|
||||
#define MOCK_CLEANUP_HPP_INCLUDED
|
||||
|
||||
#include "../config.hpp"
|
||||
|
||||
#ifdef MOCK_USE_BOOST_TEST
|
||||
|
||||
#include "root.hpp"
|
||||
#include <boost/test/unit_test_suite.hpp>
|
||||
|
||||
namespace mock
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
struct cleanup
|
||||
{
|
||||
~cleanup()
|
||||
{
|
||||
// $$$$ MAT : because of a bug in Boost.Test
|
||||
// this will crash if anything needs to be logged
|
||||
// see https://svn.boost.org/trac/boost/ticket/5563
|
||||
//mock::verify();
|
||||
mock::reset();
|
||||
}
|
||||
};
|
||||
BOOST_GLOBAL_FIXTURE( cleanup );
|
||||
}
|
||||
} // mock
|
||||
|
||||
#endif
|
||||
|
||||
#endif // MOCK_CLEANUP_HPP_INCLUDED
|
||||
|
|
@ -9,7 +9,7 @@
|
|||
#ifndef MOCK_CONTEXT_HPP_INCLUDED
|
||||
#define MOCK_CONTEXT_HPP_INCLUDED
|
||||
|
||||
#include "detail/type_name.hpp"
|
||||
#include "type_name.hpp"
|
||||
#include <boost/noncopyable.hpp>
|
||||
#include <boost/optional.hpp>
|
||||
#include <boost/test/utils/basic_cstring/basic_cstring.hpp>
|
||||
|
|
|
|||
101
turtle/detail/expectation_base.hpp
Normal file
101
turtle/detail/expectation_base.hpp
Normal file
|
|
@ -0,0 +1,101 @@
|
|||
// http://turtle.sourceforge.net
|
||||
//
|
||||
// Copyright Mathieu Champlon 2012
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef MOCK_EXPECTATION_BASE_HPP_INCLUDED
|
||||
#define MOCK_EXPECTATION_BASE_HPP_INCLUDED
|
||||
|
||||
#include "invocation.hpp"
|
||||
#include "../sequence.hpp"
|
||||
#include <boost/shared_ptr.hpp>
|
||||
#include <vector>
|
||||
|
||||
namespace mock
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
class expectation_base
|
||||
{
|
||||
public:
|
||||
expectation_base()
|
||||
: i_( new detail::unlimited() )
|
||||
, file_( "unknown location" )
|
||||
, line_( 0 )
|
||||
{}
|
||||
void set_location( const char* file, int line )
|
||||
{
|
||||
file_ = file;
|
||||
line_ = line;
|
||||
}
|
||||
|
||||
bool verify() const
|
||||
{
|
||||
return i_->verify();
|
||||
}
|
||||
|
||||
bool invoke() const
|
||||
{
|
||||
for( sequences_cit it = sequences_.begin();
|
||||
it != sequences_.end(); ++it )
|
||||
if( ! (*it)->is_valid( this ) )
|
||||
return false;
|
||||
bool result = i_->invoke();
|
||||
for( sequences_cit it = sequences_.begin();
|
||||
it != sequences_.end(); ++it )
|
||||
(*it)->invalidate( this );
|
||||
return result;
|
||||
}
|
||||
|
||||
bool invoked() const
|
||||
{
|
||||
return i_->invoked();
|
||||
}
|
||||
|
||||
const char* file() const
|
||||
{
|
||||
return file_;
|
||||
}
|
||||
int line() const
|
||||
{
|
||||
return line_;
|
||||
}
|
||||
|
||||
protected:
|
||||
~expectation_base()
|
||||
{
|
||||
for( sequences_cit it = sequences_.begin();
|
||||
it != sequences_.end(); ++it )
|
||||
(*it)->remove( this );
|
||||
}
|
||||
|
||||
void expect( detail::invocation* i )
|
||||
{
|
||||
i_.reset( i );
|
||||
}
|
||||
|
||||
void add( boost::shared_ptr< detail::sequence_impl > s )
|
||||
{
|
||||
s->add( this );
|
||||
sequences_.push_back( s );
|
||||
}
|
||||
|
||||
boost::shared_ptr< detail::invocation > i_;
|
||||
|
||||
private:
|
||||
typedef std::vector<
|
||||
boost::shared_ptr< detail::sequence_impl >
|
||||
> sequences_type;
|
||||
typedef sequences_type::const_iterator sequences_cit;
|
||||
|
||||
sequences_type sequences_;
|
||||
const char* file_;
|
||||
int line_;
|
||||
};
|
||||
}
|
||||
} // mock
|
||||
|
||||
#endif // MOCK_EXPECTATION_BASE_HPP_INCLUDED
|
||||
139
turtle/detail/expectation_template.hpp
Normal file
139
turtle/detail/expectation_template.hpp
Normal file
|
|
@ -0,0 +1,139 @@
|
|||
// http://turtle.sourceforge.net
|
||||
//
|
||||
// Copyright Mathieu Champlon 2012
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#define MOCK_EXPECTATION_TYPEDEF(z, n, d) \
|
||||
typedef T##n arg##n##_type;
|
||||
|
||||
#define MOCK_EXPECTATION_INITIALIZE(z, n, d) \
|
||||
BOOST_PP_COMMA_IF(n) c##n##_( \
|
||||
new detail::check< \
|
||||
arg##n##_type, \
|
||||
constraint< detail::any > \
|
||||
>( mock::any ) )
|
||||
|
||||
#define MOCK_EXPECTATION_WITH(z, n, d) \
|
||||
c##n##_.reset( \
|
||||
new detail::check< \
|
||||
arg##n##_type, \
|
||||
Constraint_##n \
|
||||
>( c##n ) );
|
||||
|
||||
#define MOCK_EXPECTATION_MEMBER(z, n, d) \
|
||||
boost::shared_ptr< detail::check_base< arg##n##_type > > c##n##_;
|
||||
|
||||
#define MOCK_EXPECTATION_ARGS(z, n, d) \
|
||||
BOOST_PP_COMMA_IF(n) arg##n##_type a##n
|
||||
|
||||
#define MOCK_EXPECTATION_IS_VALID(z, n, d) \
|
||||
&& (*c##n##_)( a##n )
|
||||
|
||||
#define MOCK_EXPECTATION_SERIALIZE(z, n, d) \
|
||||
BOOST_PP_IF(n, << ", " <<,) *m.c##n##_
|
||||
|
||||
namespace mock
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
template< typename Signature > class expectation;
|
||||
|
||||
template< typename R BOOST_PP_COMMA_IF(MOCK_NUM_ARGS)
|
||||
BOOST_PP_ENUM_PARAMS(MOCK_NUM_ARGS, typename T) >
|
||||
class expectation< R (BOOST_PP_ENUM_PARAMS(MOCK_NUM_ARGS,T)) >
|
||||
: public expectation_base
|
||||
, public action< R, R (BOOST_PP_ENUM_PARAMS(MOCK_NUM_ARGS,T)) >
|
||||
{
|
||||
BOOST_PP_REPEAT(MOCK_NUM_ARGS,
|
||||
MOCK_EXPECTATION_TYPEDEF, BOOST_PP_EMPTY)
|
||||
public:
|
||||
#ifndef MOCK_NUM_ARGS_0
|
||||
expectation()
|
||||
:
|
||||
BOOST_PP_REPEAT(MOCK_NUM_ARGS,
|
||||
MOCK_EXPECTATION_INITIALIZE, BOOST_PP_EMPTY)
|
||||
{}
|
||||
template< BOOST_PP_ENUM_PARAMS(MOCK_NUM_ARGS, typename Constraint_) >
|
||||
expectation& with(
|
||||
BOOST_PP_ENUM_BINARY_PARAMS(MOCK_NUM_ARGS, Constraint_, c) )
|
||||
{
|
||||
BOOST_PP_REPEAT(MOCK_NUM_ARGS,
|
||||
MOCK_EXPECTATION_WITH, BOOST_PP_EMPTY)
|
||||
return *this;
|
||||
}
|
||||
#endif
|
||||
bool is_valid(
|
||||
BOOST_PP_REPEAT(MOCK_NUM_ARGS,
|
||||
MOCK_EXPECTATION_ARGS, BOOST_PP_EMPTY) ) const
|
||||
{
|
||||
return ! i_->exhausted()
|
||||
BOOST_PP_REPEAT(MOCK_NUM_ARGS,
|
||||
MOCK_EXPECTATION_IS_VALID, BOOST_PP_EMPTY);
|
||||
}
|
||||
|
||||
expectation& in( sequence& s )
|
||||
{
|
||||
add( s.impl_ );
|
||||
return *this;
|
||||
}
|
||||
expectation& once()
|
||||
{
|
||||
expect( new detail::once() );
|
||||
return *this;
|
||||
}
|
||||
expectation& never()
|
||||
{
|
||||
expect( new detail::never() );
|
||||
return *this;
|
||||
}
|
||||
expectation& exactly( std::size_t count )
|
||||
{
|
||||
expect( new detail::exactly( count ) );
|
||||
return *this;
|
||||
}
|
||||
expectation& at_least( std::size_t min )
|
||||
{
|
||||
expect( new detail::at_least( min ) );
|
||||
return *this;
|
||||
}
|
||||
expectation& at_most( std::size_t max )
|
||||
{
|
||||
expect( new detail::at_most( max ) );
|
||||
return *this;
|
||||
}
|
||||
expectation& between( std::size_t min, std::size_t max )
|
||||
{
|
||||
expect( new detail::between( min, max ) );
|
||||
return *this;
|
||||
}
|
||||
|
||||
friend std::ostream& operator<<(
|
||||
std::ostream& s, const expectation& m )
|
||||
{
|
||||
return s << (m.i_->exhausted() ? 'v' : '.')
|
||||
<< ' ' << *m.i_
|
||||
#ifndef MOCK_NUM_ARGS_0
|
||||
<< ".with( "
|
||||
<< BOOST_PP_REPEAT(MOCK_NUM_ARGS,
|
||||
MOCK_EXPECTATION_SERIALIZE, BOOST_PP_EMPTY)
|
||||
<< " )"
|
||||
#endif
|
||||
;
|
||||
}
|
||||
private:
|
||||
BOOST_PP_REPEAT(MOCK_NUM_ARGS, MOCK_EXPECTATION_MEMBER, BOOST_PP_EMPTY)
|
||||
};
|
||||
}
|
||||
} // mock
|
||||
|
||||
#undef MOCK_EXPECTATION_TYPEDEF
|
||||
#undef MOCK_EXPECTATION_INITIALIZE
|
||||
#undef MOCK_EXPECTATION_WITH
|
||||
#undef MOCK_EXPECTATION_MEMBER
|
||||
#undef MOCK_EXPECTATION_ARGS
|
||||
#undef MOCK_EXPECTATION_IS_VALID
|
||||
#undef MOCK_EXPECTATION_SERIALIZE
|
||||
#undef MOCK_EXPECTATION
|
||||
62
turtle/detail/function.hpp
Normal file
62
turtle/detail/function.hpp
Normal file
|
|
@ -0,0 +1,62 @@
|
|||
// http://turtle.sourceforge.net
|
||||
//
|
||||
// Copyright Mathieu Champlon 2008
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef MOCK_FUNCTION_HPP_INCLUDED
|
||||
#define MOCK_FUNCTION_HPP_INCLUDED
|
||||
|
||||
#include "../config.hpp"
|
||||
#include "../error.hpp"
|
||||
#include "../log.hpp"
|
||||
#include "../constraints.hpp"
|
||||
#include "../sequence.hpp"
|
||||
#include "check.hpp"
|
||||
#include "action.hpp"
|
||||
#include "verifiable.hpp"
|
||||
#include "type_name.hpp"
|
||||
#include "context.hpp"
|
||||
#include "invocation.hpp"
|
||||
#include "expectation_base.hpp"
|
||||
#include <boost/preprocessor/repetition/repeat_from_to.hpp>
|
||||
#include <boost/preprocessor/repetition/enum_params.hpp>
|
||||
#include <boost/preprocessor/repetition/enum_binary_params.hpp>
|
||||
#include <boost/preprocessor/comparison/equal.hpp>
|
||||
#include <boost/test/utils/basic_cstring/basic_cstring.hpp>
|
||||
#include <boost/test/utils/lazy_ostream.hpp>
|
||||
#include <boost/function_types/result_type.hpp>
|
||||
#include <boost/enable_shared_from_this.hpp>
|
||||
#include <boost/optional.hpp>
|
||||
#include <ostream>
|
||||
#include <vector>
|
||||
#include <list>
|
||||
|
||||
#define MOCK_NUM_ARGS 0
|
||||
#define MOCK_NUM_ARGS_0
|
||||
#include "function_template.hpp"
|
||||
#undef MOCK_NUM_ARGS_0
|
||||
#undef MOCK_NUM_ARGS
|
||||
|
||||
#define BOOST_PP_ITERATION_PARAMS_1 \
|
||||
(3,(1,MOCK_MAX_ARGS,"function_iterate.hpp"))
|
||||
#include BOOST_PP_ITERATE()
|
||||
#undef BOOST_PP_ITERATION_PARAMS_1
|
||||
|
||||
namespace mock
|
||||
{
|
||||
template< typename Signature >
|
||||
bool verify( const function< Signature >& f )
|
||||
{
|
||||
return f.verify();
|
||||
}
|
||||
template< typename Signature >
|
||||
void reset( function< Signature >& f )
|
||||
{
|
||||
f.reset();
|
||||
}
|
||||
} // mock
|
||||
|
||||
#endif // MOCK_FUNCTION_HPP_INCLUDED
|
||||
11
turtle/detail/function_iterate.hpp
Normal file
11
turtle/detail/function_iterate.hpp
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
// http://turtle.sourceforge.net
|
||||
//
|
||||
// Copyright Mathieu Champlon 2012
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#define MOCK_NUM_ARGS BOOST_PP_ITERATION()
|
||||
#include "function_template.hpp"
|
||||
#undef MOCK_NUM_ARGS
|
||||
275
turtle/detail/function_template.hpp
Normal file
275
turtle/detail/function_template.hpp
Normal file
|
|
@ -0,0 +1,275 @@
|
|||
// http://turtle.sourceforge.net
|
||||
//
|
||||
// Copyright Mathieu Champlon 2008
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#include "expectation_template.hpp"
|
||||
|
||||
namespace mock
|
||||
{
|
||||
template< typename Signature > class function;
|
||||
|
||||
template< typename R BOOST_PP_COMMA_IF(MOCK_NUM_ARGS)
|
||||
BOOST_PP_ENUM_PARAMS(MOCK_NUM_ARGS, typename T) >
|
||||
class function< R ( BOOST_PP_ENUM_PARAMS(MOCK_NUM_ARGS, T) ) >
|
||||
{
|
||||
public:
|
||||
typedef R result_type;
|
||||
|
||||
template< typename Args >
|
||||
struct sig
|
||||
{
|
||||
typedef R type;
|
||||
};
|
||||
|
||||
private:
|
||||
typedef detail::expectation<
|
||||
R ( BOOST_PP_ENUM_PARAMS(MOCK_NUM_ARGS, T) )
|
||||
> expectation_type;
|
||||
|
||||
public:
|
||||
function()
|
||||
: impl_( new function_impl() )
|
||||
{}
|
||||
|
||||
bool verify() const
|
||||
{
|
||||
return impl_->verify();
|
||||
}
|
||||
bool verify( const char* file, int line ) const
|
||||
{
|
||||
function_impl::error_type::checkpoint( file, line );
|
||||
return impl_->verify();
|
||||
}
|
||||
void reset()
|
||||
{
|
||||
impl_->reset();
|
||||
}
|
||||
void reset( const char* file, int line )
|
||||
{
|
||||
function_impl::error_type::checkpoint( file, line );
|
||||
return impl_->reset();
|
||||
}
|
||||
|
||||
expectation_type& expect( const char* file, int line )
|
||||
{
|
||||
function_impl::error_type::checkpoint( file, line );
|
||||
return impl_->expect();
|
||||
}
|
||||
expectation_type& expect()
|
||||
{
|
||||
return impl_->expect();
|
||||
}
|
||||
|
||||
void test() const
|
||||
{
|
||||
impl_->test();
|
||||
}
|
||||
|
||||
R operator()( BOOST_PP_ENUM_BINARY_PARAMS(MOCK_NUM_ARGS, T, t) ) const
|
||||
{
|
||||
return (*impl_)( BOOST_PP_ENUM_PARAMS(MOCK_NUM_ARGS, t) );
|
||||
}
|
||||
|
||||
friend std::ostream& operator<<( std::ostream& s, const function& e )
|
||||
{
|
||||
return s << *e.impl_;
|
||||
}
|
||||
|
||||
function& operator()( detail::context& c,
|
||||
boost::unit_test::const_string instance )
|
||||
{
|
||||
if( ! impl_->context_ )
|
||||
c.add( *impl_ );
|
||||
c.add( impl_.get(), *impl_, instance,
|
||||
boost::optional< detail::type_name >(), "" );
|
||||
impl_->context_ = &c;
|
||||
return *this;
|
||||
}
|
||||
|
||||
void configure( detail::context& c, const void* p,
|
||||
boost::unit_test::const_string instance,
|
||||
const boost::optional< detail::type_name >& type,
|
||||
boost::unit_test::const_string name ) const
|
||||
{
|
||||
if( ! impl_->context_ )
|
||||
c.add( *impl_ );
|
||||
c.add( p, *impl_, instance, type, name );
|
||||
impl_->context_ = &c;
|
||||
}
|
||||
|
||||
private:
|
||||
class function_impl : public detail::verifiable,
|
||||
public boost::enable_shared_from_this< function_impl >
|
||||
{
|
||||
public:
|
||||
typedef MOCK_ERROR_POLICY< result_type > error_type;
|
||||
|
||||
public:
|
||||
function_impl()
|
||||
: context_( 0 )
|
||||
, valid_( true )
|
||||
{}
|
||||
virtual ~function_impl()
|
||||
{
|
||||
if( valid_ && ! std::uncaught_exception() )
|
||||
for( expectations_cit it = expectations_.begin();
|
||||
it != expectations_.end(); ++it )
|
||||
{
|
||||
if( ! it->verify() )
|
||||
error_type::untriggered_expectation(
|
||||
boost::unit_test::lazy_ostream::instance()
|
||||
<< lazy_context( this )
|
||||
<< lazy_expectations( this ),
|
||||
it->file(), it->line() );
|
||||
else if( ! it->invoked() )
|
||||
error_type::expected_call(
|
||||
boost::unit_test::lazy_ostream::instance()
|
||||
<< lazy_context( this )
|
||||
<< lazy_expectations( this ),
|
||||
it->file(), it->line() );
|
||||
}
|
||||
if( context_ )
|
||||
context_->remove( *this );
|
||||
}
|
||||
|
||||
virtual bool verify() const
|
||||
{
|
||||
for( expectations_cit it = expectations_.begin();
|
||||
it != expectations_.end(); ++it )
|
||||
if( !it->verify() )
|
||||
{
|
||||
valid_ = false;
|
||||
error_type::verification_failed(
|
||||
boost::unit_test::lazy_ostream::instance()
|
||||
<< lazy_context( this )
|
||||
<< lazy_expectations( this ),
|
||||
it->file(), it->line() );
|
||||
}
|
||||
return valid_;
|
||||
}
|
||||
|
||||
virtual void reset()
|
||||
{
|
||||
valid_ = true;
|
||||
boost::shared_ptr< function_impl > guard =
|
||||
this->shared_from_this();
|
||||
expectations_.clear();
|
||||
}
|
||||
|
||||
expectation_type& expect( const char* file, int line )
|
||||
{
|
||||
expectation_type& e = expect();
|
||||
e.set_location( file, line );
|
||||
return e;
|
||||
}
|
||||
expectation_type& expect()
|
||||
{
|
||||
expectations_.push_back( expectation_type() );
|
||||
valid_ = true;
|
||||
return expectations_.back();
|
||||
}
|
||||
|
||||
#define MOCK_FORMAT(z, n, N) \
|
||||
<< " " << mock::format( t##n ) \
|
||||
<< BOOST_PP_IF(BOOST_PP_EQUAL(N,n), " ", ",")
|
||||
#define MOCK_CONTEXT(n) \
|
||||
boost::unit_test::lazy_ostream::instance() \
|
||||
<< lazy_context( this ) \
|
||||
<< "(" BOOST_PP_REPEAT(n, MOCK_FORMAT, BOOST_PP_DEC(n)) \
|
||||
<< ")" \
|
||||
<< lazy_expectations( this )
|
||||
#define MOCK_INVOKE(z, n, A) \
|
||||
{ \
|
||||
valid_ = false; \
|
||||
for( expectations_cit it = expectations_.begin(); \
|
||||
it != expectations_.end(); ++it ) \
|
||||
if( it->is_valid( BOOST_PP_ENUM_PARAMS(n, t) ) ) \
|
||||
{ \
|
||||
if( ! it->invoke() ) \
|
||||
{ \
|
||||
error_type::sequence_failed( \
|
||||
MOCK_CONTEXT(n), it->file(), it->line() ); \
|
||||
return A; \
|
||||
} \
|
||||
if( ! it->functor() ) \
|
||||
{ \
|
||||
error_type::missing_action( \
|
||||
MOCK_CONTEXT(n), it->file(), it->line() ); \
|
||||
return A; \
|
||||
} \
|
||||
valid_ = true; \
|
||||
error_type::expected_call( \
|
||||
MOCK_CONTEXT(n), it->file(), it->line() ); \
|
||||
return it->functor()( BOOST_PP_ENUM_PARAMS(n, t) ); \
|
||||
} \
|
||||
error_type::unexpected_call( MOCK_CONTEXT(n) ); \
|
||||
return A; \
|
||||
}
|
||||
|
||||
result_type operator()(
|
||||
BOOST_PP_ENUM_BINARY_PARAMS(MOCK_NUM_ARGS, T, t) ) const
|
||||
MOCK_INVOKE(, MOCK_NUM_ARGS, error_type::abort())
|
||||
|
||||
void test() const
|
||||
MOCK_INVOKE(, 0,)
|
||||
|
||||
#undef MOCK_FORMAT
|
||||
#undef MOCK_OPERATOR
|
||||
#undef MOCK_INVOKE
|
||||
#undef MOCK_CONTEXT
|
||||
|
||||
friend std::ostream& operator<<(
|
||||
std::ostream& s, const function_impl& e )
|
||||
{
|
||||
return s << lazy_context( &e ) << lazy_expectations( &e );
|
||||
}
|
||||
|
||||
struct lazy_context
|
||||
{
|
||||
lazy_context( const function_impl* impl )
|
||||
: impl_( impl )
|
||||
{}
|
||||
friend std::ostream& operator<<(
|
||||
std::ostream& s, const lazy_context& c )
|
||||
{
|
||||
if( c.impl_->context_ )
|
||||
c.impl_->context_->serialize( s, *c.impl_ );
|
||||
else
|
||||
s << "?";
|
||||
return s;
|
||||
}
|
||||
const function_impl* impl_;
|
||||
};
|
||||
|
||||
struct lazy_expectations
|
||||
{
|
||||
lazy_expectations( const function_impl* impl )
|
||||
: impl_( impl )
|
||||
{}
|
||||
friend std::ostream& operator<<(
|
||||
std::ostream& s, const lazy_expectations& e )
|
||||
{
|
||||
for( expectations_cit it = e.impl_->expectations_.begin();
|
||||
it != e.impl_->expectations_.end(); ++it )
|
||||
s << std::endl << *it;
|
||||
return s;
|
||||
}
|
||||
const function_impl* impl_;
|
||||
};
|
||||
|
||||
typedef std::list< expectation_type > expectations_type;
|
||||
typedef BOOST_DEDUCED_TYPENAME
|
||||
expectations_type::const_iterator expectations_cit;
|
||||
|
||||
expectations_type expectations_;
|
||||
detail::context* context_;
|
||||
mutable bool valid_;
|
||||
};
|
||||
|
||||
boost::shared_ptr< function_impl > impl_;
|
||||
};
|
||||
} // mock
|
||||
|
|
@ -9,7 +9,7 @@
|
|||
#ifndef MOCK_GROUP_HPP_INCLUDED
|
||||
#define MOCK_GROUP_HPP_INCLUDED
|
||||
|
||||
#include "detail/verifiable.hpp"
|
||||
#include "verifiable.hpp"
|
||||
#include <functional>
|
||||
#include <algorithm>
|
||||
#include <vector>
|
||||
|
|
|
|||
176
turtle/detail/invocation.hpp
Normal file
176
turtle/detail/invocation.hpp
Normal file
|
|
@ -0,0 +1,176 @@
|
|||
// http://turtle.sourceforge.net
|
||||
//
|
||||
// Copyright Mathieu Champlon 2008
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef MOCK_INVOCATION_HPP_INCLUDED
|
||||
#define MOCK_INVOCATION_HPP_INCLUDED
|
||||
|
||||
#include <boost/noncopyable.hpp>
|
||||
#include <stdexcept>
|
||||
#include <ostream>
|
||||
#include <limits>
|
||||
|
||||
namespace mock
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
class invocation : private boost::noncopyable
|
||||
{
|
||||
public:
|
||||
invocation() {}
|
||||
virtual ~invocation() {}
|
||||
|
||||
virtual bool invoke() = 0;
|
||||
virtual bool verify() const = 0;
|
||||
|
||||
virtual bool invoked() const = 0;
|
||||
virtual bool exhausted() const = 0;
|
||||
|
||||
friend inline std::ostream& operator<<(
|
||||
std::ostream& s, const invocation& i )
|
||||
{
|
||||
return i.serialize( s );
|
||||
}
|
||||
|
||||
private:
|
||||
virtual std::ostream& serialize( std::ostream& s ) const = 0;
|
||||
};
|
||||
|
||||
class between : public invocation
|
||||
{
|
||||
public:
|
||||
between( std::size_t min, std::size_t max )
|
||||
: min_( min )
|
||||
, max_( max )
|
||||
, count_( 0 )
|
||||
{
|
||||
if( min > max )
|
||||
throw std::invalid_argument( "'min' > 'max'" );
|
||||
}
|
||||
|
||||
virtual bool invoke()
|
||||
{
|
||||
if( count_ == max_ )
|
||||
return false;
|
||||
++count_;
|
||||
return true;
|
||||
}
|
||||
|
||||
virtual bool invoked() const
|
||||
{
|
||||
return count_ > 0;
|
||||
}
|
||||
|
||||
virtual bool exhausted() const
|
||||
{
|
||||
return count_ >= max_;
|
||||
}
|
||||
|
||||
virtual bool verify() const
|
||||
{
|
||||
return min_ <= count_ && count_ <= max_;
|
||||
}
|
||||
|
||||
protected:
|
||||
const std::size_t min_, max_;
|
||||
std::size_t count_;
|
||||
|
||||
private:
|
||||
virtual std::ostream& serialize( std::ostream& s ) const
|
||||
{
|
||||
return s << "between( " << count_
|
||||
<< "/[" << min_ << ',' << max_ << "] )";
|
||||
}
|
||||
};
|
||||
|
||||
class exactly : public between
|
||||
{
|
||||
public:
|
||||
explicit exactly( std::size_t count )
|
||||
: between( count, count )
|
||||
{}
|
||||
|
||||
private:
|
||||
virtual std::ostream& serialize( std::ostream& s ) const
|
||||
{
|
||||
return s << "exactly( " << count_ << '/' << max_ << " )";
|
||||
}
|
||||
};
|
||||
|
||||
class never : public exactly
|
||||
{
|
||||
public:
|
||||
never()
|
||||
: exactly( 0 )
|
||||
{}
|
||||
|
||||
private:
|
||||
virtual std::ostream& serialize( std::ostream& s ) const
|
||||
{
|
||||
return s << "never()";
|
||||
}
|
||||
};
|
||||
|
||||
class once : public exactly
|
||||
{
|
||||
public:
|
||||
once()
|
||||
: exactly( 1 )
|
||||
{}
|
||||
|
||||
private:
|
||||
virtual std::ostream& serialize( std::ostream& s ) const
|
||||
{
|
||||
return s << "once()";
|
||||
}
|
||||
};
|
||||
|
||||
class at_least : public between
|
||||
{
|
||||
public:
|
||||
explicit at_least( std::size_t min )
|
||||
: between( min, std::numeric_limits< std::size_t >::max() )
|
||||
{}
|
||||
|
||||
private:
|
||||
virtual std::ostream& serialize( std::ostream& s ) const
|
||||
{
|
||||
return s << "at_least( " << count_ << '/' << min_ << " )";
|
||||
}
|
||||
};
|
||||
|
||||
class at_most : public between
|
||||
{
|
||||
public:
|
||||
explicit at_most( std::size_t max )
|
||||
: between( 0, max )
|
||||
{}
|
||||
|
||||
private:
|
||||
virtual std::ostream& serialize( std::ostream& s ) const
|
||||
{
|
||||
return s << "at_most( " << count_ << '/' << max_ << " )";
|
||||
}
|
||||
};
|
||||
|
||||
class unlimited : public at_least
|
||||
{
|
||||
public:
|
||||
unlimited()
|
||||
: at_least( 0 )
|
||||
{}
|
||||
|
||||
private:
|
||||
virtual std::ostream& serialize( std::ostream& s ) const
|
||||
{
|
||||
return s << "unlimited()";
|
||||
}
|
||||
};
|
||||
}
|
||||
} // mock
|
||||
|
||||
#endif // MOCK_INVOCATION_HPP_INCLUDED
|
||||
110
turtle/detail/operators.hpp
Normal file
110
turtle/detail/operators.hpp
Normal file
|
|
@ -0,0 +1,110 @@
|
|||
// http://turtle.sourceforge.net
|
||||
//
|
||||
// Copyright Mathieu Champlon 2010
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef MOCK_OPERATORS_HPP_INCLUDED
|
||||
#define MOCK_OPERATORS_HPP_INCLUDED
|
||||
|
||||
#include "../constraint.hpp"
|
||||
#include "../log.hpp"
|
||||
|
||||
namespace mock
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
template< typename Constraint1, typename Constraint2 >
|
||||
class and_
|
||||
{
|
||||
public:
|
||||
and_( const Constraint1& c1, const Constraint2& c2 )
|
||||
: c1_( c1 )
|
||||
, c2_( c2 )
|
||||
{}
|
||||
template< typename Actual >
|
||||
bool operator()( const Actual& actual ) const
|
||||
{
|
||||
return c1_( actual ) && c2_( actual );
|
||||
}
|
||||
friend std::ostream& operator<<( std::ostream& s, const and_& a )
|
||||
{
|
||||
return s << "( " << mock::format( a.c1_ )
|
||||
<< " && " << mock::format( a.c2_ ) << " )";
|
||||
}
|
||||
private:
|
||||
Constraint1 c1_;
|
||||
Constraint2 c2_;
|
||||
};
|
||||
|
||||
template< typename Constraint1, typename Constraint2 >
|
||||
class or_
|
||||
{
|
||||
public:
|
||||
or_( const Constraint1& c1, const Constraint2& c2 )
|
||||
: c1_( c1 )
|
||||
, c2_( c2 )
|
||||
{}
|
||||
template< typename Actual >
|
||||
bool operator()( const Actual& actual ) const
|
||||
{
|
||||
return c1_( actual ) || c2_( actual );
|
||||
}
|
||||
friend std::ostream& operator<<( std::ostream& s, const or_& o )
|
||||
{
|
||||
return s << "( " << mock::format( o.c1_ )
|
||||
<< " || " << mock::format( o.c2_ )<< " )";
|
||||
}
|
||||
private:
|
||||
Constraint1 c1_;
|
||||
Constraint2 c2_;
|
||||
};
|
||||
|
||||
template< typename Constraint >
|
||||
class not_
|
||||
{
|
||||
public:
|
||||
explicit not_( const Constraint& f )
|
||||
: f_( f )
|
||||
{}
|
||||
template< typename Actual >
|
||||
bool operator()( const Actual& actual ) const
|
||||
{
|
||||
return ! f_( actual );
|
||||
}
|
||||
friend std::ostream& operator<<( std::ostream& s, const not_& n )
|
||||
{
|
||||
return s << "! " << mock::format( n.f_ );
|
||||
}
|
||||
private:
|
||||
Constraint f_;
|
||||
};
|
||||
}
|
||||
|
||||
template< typename Constraint1, typename Constraint2 >
|
||||
const constraint< detail::or_< Constraint1, Constraint2 > >
|
||||
operator||( const constraint< Constraint1 >& lhs,
|
||||
const constraint< Constraint2 >& rhs )
|
||||
{
|
||||
return detail::or_< Constraint1, Constraint2 >( lhs.f_, rhs.f_ );
|
||||
}
|
||||
|
||||
template< typename Constraint1, typename Constraint2 >
|
||||
const constraint< detail::and_< Constraint1, Constraint2 > >
|
||||
operator&&( const constraint< Constraint1 >& lhs,
|
||||
const constraint< Constraint2 >& rhs )
|
||||
{
|
||||
return detail::and_< Constraint1, Constraint2 >( lhs.f_, rhs.f_ );
|
||||
}
|
||||
|
||||
template< typename Constraint >
|
||||
const constraint< detail::not_< Constraint > >
|
||||
operator!( const constraint< Constraint >& c )
|
||||
{
|
||||
return detail::not_< Constraint >( c.f_ );
|
||||
}
|
||||
} // mock
|
||||
|
||||
#endif // MOCK_OPERATORS_HPP_INCLUDED
|
||||
|
|
@ -9,7 +9,7 @@
|
|||
#ifndef MOCK_PARENT_HPP_INCLUDED
|
||||
#define MOCK_PARENT_HPP_INCLUDED
|
||||
|
||||
#include "detail/type_name.hpp"
|
||||
#include "type_name.hpp"
|
||||
#include <boost/optional.hpp>
|
||||
#include <boost/test/utils/basic_cstring/io.hpp>
|
||||
#include <ostream>
|
||||
|
|
|
|||
|
|
@ -9,10 +9,10 @@
|
|||
#ifndef MOCK_ROOT_HPP_INCLUDED
|
||||
#define MOCK_ROOT_HPP_INCLUDED
|
||||
|
||||
#include "detail/parent.hpp"
|
||||
#include "detail/group.hpp"
|
||||
#include "detail/context.hpp"
|
||||
#include "detail/child.hpp"
|
||||
#include "parent.hpp"
|
||||
#include "group.hpp"
|
||||
#include "context.hpp"
|
||||
#include "child.hpp"
|
||||
#include <boost/test/utils/trivial_singleton.hpp>
|
||||
#include <ostream>
|
||||
#include <map>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue