Merged refactoring branch

git-svn-id: https://svn.code.sf.net/p/turtle/code/trunk@379 860be788-9bd5-4423-9f1e-828f051e677b
This commit is contained in:
mat007 2011-07-09 15:16:03 +00:00
parent bec0c8aafa
commit a7c62e523a
19 changed files with 558 additions and 263 deletions

View file

@ -168,6 +168,14 @@
RelativePath="..\..\src\libraries\turtle\check.hpp" RelativePath="..\..\src\libraries\turtle\check.hpp"
> >
</File> </File>
<File
RelativePath="..\..\src\libraries\turtle\child.hpp"
>
</File>
<File
RelativePath="..\..\src\libraries\turtle\cleanup.hpp"
>
</File>
<File <File
RelativePath="..\..\src\libraries\turtle\config.hpp" RelativePath="..\..\src\libraries\turtle\config.hpp"
> >
@ -180,6 +188,10 @@
RelativePath="..\..\src\libraries\turtle\constraints.hpp" RelativePath="..\..\src\libraries\turtle\constraints.hpp"
> >
</File> </File>
<File
RelativePath="..\..\src\libraries\turtle\context.hpp"
>
</File>
<File <File
RelativePath="..\..\src\libraries\turtle\default_error.hpp" RelativePath="..\..\src\libraries\turtle\default_error.hpp"
> >
@ -196,6 +208,10 @@
RelativePath="..\..\src\libraries\turtle\function.hpp" RelativePath="..\..\src\libraries\turtle\function.hpp"
> >
</File> </File>
<File
RelativePath="..\..\src\libraries\turtle\group.hpp"
>
</File>
<File <File
RelativePath="..\..\src\libraries\turtle\invocation.hpp" RelativePath="..\..\src\libraries\turtle\invocation.hpp"
> >
@ -216,10 +232,6 @@
RelativePath="..\..\src\libraries\turtle\mock.hpp" RelativePath="..\..\src\libraries\turtle\mock.hpp"
> >
</File> </File>
<File
RelativePath="..\..\src\libraries\turtle\node.hpp"
>
</File>
<File <File
RelativePath="..\..\src\libraries\turtle\object.hpp" RelativePath="..\..\src\libraries\turtle\object.hpp"
> >
@ -228,6 +240,10 @@
RelativePath="..\..\src\libraries\turtle\operators.hpp" RelativePath="..\..\src\libraries\turtle\operators.hpp"
> >
</File> </File>
<File
RelativePath="..\..\src\libraries\turtle\parent.hpp"
>
</File>
<File <File
RelativePath="..\..\src\libraries\turtle\root.hpp" RelativePath="..\..\src\libraries\turtle\root.hpp"
> >

View file

@ -95,7 +95,7 @@
/> />
<Tool <Tool
Name="VCPostBuildEventTool" Name="VCPostBuildEventTool"
CommandLine="cd ../../run/vc80&#x0D;&#x0A;&quot;$(TargetDir)$(TargetName).exe&quot; --result_code=no --report_level=no --log_level=warning --data_directory=../../data/tests/$(ProjectName)&#x0D;&#x0A;" CommandLine="cd ../../run/vc80&#x0D;&#x0A;&quot;$(TargetDir)$(TargetName).exe&quot; --result_code=no --report_level=no --log_level=warning"
/> />
</Configuration> </Configuration>
<Configuration <Configuration
@ -179,7 +179,7 @@
/> />
<Tool <Tool
Name="VCPostBuildEventTool" Name="VCPostBuildEventTool"
CommandLine="cd ../../run/vc80&#x0D;&#x0A;&quot;$(TargetDir)$(TargetName).exe&quot; --result_code=no --report_level=no --log_level=warning --data_directory=../../data/tests/$(ProjectName)&#x0D;&#x0A;" CommandLine="cd ../../run/vc80&#x0D;&#x0A;&quot;$(TargetDir)$(TargetName).exe&quot; --result_code=no --report_level=no --log_level=warning"
/> />
</Configuration> </Configuration>
</Configurations> </Configurations>

View file

@ -9,7 +9,6 @@
#ifndef MOCK_BOOST_TEST_ERROR_POLICY_HPP_INCLUDED #ifndef MOCK_BOOST_TEST_ERROR_POLICY_HPP_INCLUDED
#define MOCK_BOOST_TEST_ERROR_POLICY_HPP_INCLUDED #define MOCK_BOOST_TEST_ERROR_POLICY_HPP_INCLUDED
#include "root.hpp"
#include <boost/test/framework.hpp> #include <boost/test/framework.hpp>
#include <boost/test/test_tools.hpp> #include <boost/test/test_tools.hpp>
#include <boost/test/unit_test_suite.hpp> #include <boost/test/unit_test_suite.hpp>
@ -87,16 +86,6 @@ namespace mock
fail( "untriggered expectation", context, file, line ); fail( "untriggered expectation", context, file, line );
} }
}; };
struct cleanup
{
~cleanup()
{
//mock::verify(); // $$$$ MAT : because of a bug in Boost.Test this will crash if anything needs to be logged
mock::reset();
}
};
BOOST_GLOBAL_FIXTURE( cleanup );
} }
#endif // MOCK_BOOST_TEST_ERROR_POLICY_HPP_INCLUDED #endif // MOCK_BOOST_TEST_ERROR_POLICY_HPP_INCLUDED

View file

@ -0,0 +1,47 @@
//
// 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_CHILD_HPP_INCLUDED
#define MOCK_CHILD_HPP_INCLUDED
#include "parent.hpp"
#include <ostream>
#include <string>
namespace mock
{
namespace detail
{
class child
{
public:
child()
: parent_( 0 )
{}
void update( parent& p, const std::string& instance,
const std::string& type, const std::string& name )
{
if( instance != "?" || name_.empty() )
p = parent( instance, type );
parent_ = &p;
name_ = name;
}
friend std::ostream& operator<<( std::ostream& s, const child& c )
{
if( c.parent_ )
s << *c.parent_;
return s << c.name_;
}
private:
const parent* parent_;
std::string name_;
};
}
}
#endif // MOCK_CHILD_HPP_INCLUDED

View file

@ -0,0 +1,37 @@
//
// 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()
{
//mock::verify(); // $$$$ MAT : because of a bug in Boost.Test this will crash if anything needs to be logged
mock::reset();
}
};
BOOST_GLOBAL_FIXTURE( cleanup );
}
}
#endif
#endif // MOCK_CLEANUP_HPP_INCLUDED

View file

@ -38,4 +38,8 @@
# endif # endif
#endif #endif
#ifdef BOOST_TEST_DECL
# define MOCK_USE_BOOST_TEST
#endif
#endif // MOCK_CONFIG_HPP_INCLUDED #endif // MOCK_CONFIG_HPP_INCLUDED

View file

@ -0,0 +1,38 @@
//
// 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_CONTEXT_HPP_INCLUDED
#define MOCK_CONTEXT_HPP_INCLUDED
#include <boost/noncopyable.hpp>
#include <ostream>
#include <string>
namespace mock
{
class verifiable;
namespace detail
{
class context : boost::noncopyable
{
public:
context() {}
virtual ~context() {}
virtual void add( const void* p, verifiable& v, const std::string& instance,
const std::string& type, const std::string& name ) = 0;
virtual void add( verifiable& v ) = 0;
virtual void remove( verifiable& v ) = 0;
virtual void serialize( std::ostream& s, const verifiable& v ) const = 0;
};
}
}
#endif // MOCK_CONTEXT_HPP_INCLUDED

View file

@ -12,7 +12,7 @@
#include "config.hpp" #include "config.hpp"
#ifndef MOCK_ERROR_POLICY #ifndef MOCK_ERROR_POLICY
# if defined(BOOST_TEST_DECL) || defined(MOCK_USE_BOOST_TEST) # ifdef MOCK_USE_BOOST_TEST
# define MOCK_ERROR_POLICY boost_test_error_policy # define MOCK_ERROR_POLICY boost_test_error_policy
# include "boost_test_error.hpp" # include "boost_test_error.hpp"
# else # else

View file

@ -11,8 +11,9 @@
#include "config.hpp" #include "config.hpp"
#include "error.hpp" #include "error.hpp"
#include "context.hpp"
#include "expectation.hpp" #include "expectation.hpp"
#include "root.hpp" #include "verifiable.hpp"
#include "log.hpp" #include "log.hpp"
#include "args.hpp" #include "args.hpp"
#include <boost/function_types/result_type.hpp> #include <boost/function_types/result_type.hpp>
@ -29,10 +30,7 @@
namespace mock namespace mock
{ {
template< typename Signature, template< typename Signature >
typename ErrorPolicy = MOCK_ERROR_POLICY<
BOOST_DEDUCED_TYPENAME
boost::function_types::result_type< Signature >::type > >
class function class function
{ {
public: public:
@ -52,27 +50,10 @@ namespace mock
detail::expectation< Signature, arity::value > expectation_type; detail::expectation< Signature, arity::value > expectation_type;
public: public:
struct function_tag
{};
function_tag exp_;
function() function()
: impl_( new function_impl() ) : impl_( new function_impl() )
{} {}
void tag( const std::string& name )
{
impl_->tag( name );
}
const std::string& tag() const
{
return impl_->tag();
}
void set_parent( node& parent )
{
impl_->set_parent( parent );
}
bool verify() const bool verify() const
{ {
return impl_->verify(); return impl_->verify();
@ -114,36 +95,57 @@ namespace mock
return s << *e.impl_; return s << *e.impl_;
} }
private: function& _( detail::context& c, const std::string& instance )
class function_impl : private verifiable
{ {
if( ! impl_->context_ )
c.add( *impl_ );
c.add( impl_.get(), *impl_, instance, "", "" );
impl_->context_ = &c;
return *this;
}
void configure( detail::context& c, const void* p,
const std::string& instance, const std::string& type,
const std::string& name ) const
{
if( ! impl_->context_ )
c.add( *impl_ );
c.add( p, *impl_, instance, type, name );
impl_->context_ = &c;
}
private:
class function_impl : public verifiable
{
private:
typedef MOCK_ERROR_POLICY< result_type > error_type;
public: public:
function_impl() function_impl()
: name_( "?" ) : context_( 0 )
, parent_( 0 )
, valid_( true ) , valid_( true )
{} {}
virtual ~function_impl() virtual ~function_impl()
{ {
if( parent_ )
parent_->remove( *this );
if( valid_ && ! std::uncaught_exception() ) if( valid_ && ! std::uncaught_exception() )
for( expectations_cit it = expectations_.begin(); for( expectations_cit it = expectations_.begin();
it != expectations_.end(); ++it ) it != expectations_.end(); ++it )
{ {
if( ! it->verify() ) if( ! it->verify() )
ErrorPolicy::untriggered_expectation( error_type::untriggered_expectation(
boost::unit_test::lazy_ostream::instance() boost::unit_test::lazy_ostream::instance()
<< lazy_context( this ) << lazy_context( this )
<< lazy_expectations( this ), << lazy_expectations( this ),
it->file(), it->line() ); it->file(), it->line() );
else if( ! it->invoked() ) else if( ! it->invoked() )
ErrorPolicy::expected_call( error_type::expected_call(
boost::unit_test::lazy_ostream::instance() boost::unit_test::lazy_ostream::instance()
<< lazy_context( this ) << lazy_context( this )
<< lazy_expectations( this ), << lazy_expectations( this ),
it->file(), it->line() ); it->file(), it->line() );
} }
if( context_ )
context_->remove( *this );
} }
virtual bool verify() const virtual bool verify() const
@ -153,7 +155,7 @@ namespace mock
if( !it->verify() ) if( !it->verify() )
{ {
valid_ = false; valid_ = false;
ErrorPolicy::verification_failed( error_type::verification_failed(
boost::unit_test::lazy_ostream::instance() boost::unit_test::lazy_ostream::instance()
<< lazy_context( this ) << lazy_context( this )
<< lazy_expectations( this ), << lazy_expectations( this ),
@ -167,26 +169,6 @@ namespace mock
valid_ = true; valid_ = true;
expectations_.clear(); expectations_.clear();
} }
virtual void untie()
{
parent_ = 0;
}
void tag( const std::string& name )
{
name_ = name;
}
const std::string& tag() const
{
return name_;
}
void set_parent( node& parent )
{
if( parent_ )
parent_->remove( *this );
parent.add( *this );
parent_ = &parent;
}
expectation_type& expect( const std::string& file, int line ) expectation_type& expect( const std::string& file, int line )
{ {
@ -196,8 +178,6 @@ namespace mock
} }
expectation_type& expect() expectation_type& expect()
{ {
if( ! parent_ )
set_parent( mock::detail::root );
expectations_.push_back( expectation_type() ); expectations_.push_back( expectation_type() );
valid_ = true; valid_ = true;
return expectations_.back(); return expectations_.back();
@ -218,26 +198,26 @@ namespace mock
if( ! it->invoke() ) \ if( ! it->invoke() ) \
{ \ { \
valid_ = false; \ valid_ = false; \
ErrorPolicy::sequence_failed( MOCK_EXPECTATION_CALL_CONTEXT(n), it->file(), it->line() ); \ error_type::sequence_failed( MOCK_EXPECTATION_CALL_CONTEXT(n), it->file(), it->line() ); \
return A; \ return A; \
} \ } \
if( ! it->functor() ) \ if( ! it->functor() ) \
{ \ { \
ErrorPolicy::missing_action( MOCK_EXPECTATION_CALL_CONTEXT(n), it->file(), it->line() ); \ error_type::missing_action( MOCK_EXPECTATION_CALL_CONTEXT(n), it->file(), it->line() ); \
return A; \ return A; \
} \ } \
ErrorPolicy::expected_call( MOCK_EXPECTATION_CALL_CONTEXT(n), it->file(), it->line() ); \ error_type::expected_call( MOCK_EXPECTATION_CALL_CONTEXT(n), it->file(), it->line() ); \
return it->functor()( BOOST_PP_ENUM_PARAMS(n, p) ); \ return it->functor()( BOOST_PP_ENUM_PARAMS(n, p) ); \
} \ } \
valid_ = false; \ valid_ = false; \
ErrorPolicy::unexpected_call( MOCK_EXPECTATION_CALL_CONTEXT(n) ); \ error_type::unexpected_call( MOCK_EXPECTATION_CALL_CONTEXT(n) ); \
return A; \ return A; \
} }
#define MOCK_EXPECTATION_OPERATOR(z, n, P) \ #define MOCK_EXPECTATION_OPERATOR(z, n, P) \
MOCK_DECL(operator(), n, Signature, const, BOOST_DEDUCED_TYPENAME) \ MOCK_DECL(operator(), n, Signature, const, BOOST_DEDUCED_TYPENAME) \
MOCK_EXPECTATION_INVOKE(z, n, P) MOCK_EXPECTATION_INVOKE(z, n, P)
BOOST_PP_REPEAT(BOOST_PP_INC(MOCK_MAX_ARGS), MOCK_EXPECTATION_OPERATOR, ErrorPolicy::abort()) BOOST_PP_REPEAT(BOOST_PP_INC(MOCK_MAX_ARGS), MOCK_EXPECTATION_OPERATOR, error_type::abort())
void test() const void test() const
MOCK_EXPECTATION_INVOKE(, 0,) MOCK_EXPECTATION_INVOKE(, 0,)
@ -259,11 +239,13 @@ namespace mock
{} {}
friend std::ostream& operator<<( std::ostream& s, const lazy_context& e ) friend std::ostream& operator<<( std::ostream& s, const lazy_context& e )
{ {
if( e.impl_->parent_ ) if( e.impl_->context_ )
s << e.impl_->parent_->tag(); e.impl_->context_->serialize( s, *e.impl_ );
return s << e.impl_->name_; else
s << "?";
return s;
} }
const function_impl* impl_; const function_impl* impl_; // $$$$ MAT : use detail::context directly
}; };
struct lazy_expectations struct lazy_expectations
@ -286,12 +268,10 @@ namespace mock
expectations_type::const_iterator expectations_cit; expectations_type::const_iterator expectations_cit;
expectations_type expectations_; expectations_type expectations_;
std::string name_; detail::context* context_;
node* parent_;
mutable bool valid_; mutable bool valid_;
}; };
private:
boost::shared_ptr< function_impl > impl_; boost::shared_ptr< function_impl > impl_;
}; };
} }

View file

@ -0,0 +1,60 @@
//
// 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_GROUP_HPP_INCLUDED
#define MOCK_GROUP_HPP_INCLUDED
#include "verifiable.hpp"
#include <functional>
#include <algorithm>
#include <vector>
namespace mock
{
namespace detail
{
class group
{
public:
void add( verifiable& v )
{
verifiables_.push_back( &v );
}
void remove( verifiable& v )
{
verifiables_.erase(
std::remove( verifiables_.begin(), verifiables_.end(), &v ),
verifiables_.end() );
}
bool verify() const
{
bool valid = true;
for( verifiables_cit it = verifiables_.begin();
it != verifiables_.end(); ++it )
if( ! (*it)->verify() )
valid = false;
return valid;
}
void reset() const
{
std::for_each( verifiables_.begin(), verifiables_.end(),
std::mem_fun( &verifiable::reset ) );
}
private:
typedef std::vector< verifiable* > verifiables_t;
typedef verifiables_t::iterator verifiables_it;
typedef verifiables_t::const_iterator verifiables_cit;
verifiables_t verifiables_;
};
}
}
#endif // MOCK_GROUP_HPP_INCLUDED

View file

@ -10,6 +10,7 @@
#define MOCK_MOCK_HPP_INCLUDED #define MOCK_MOCK_HPP_INCLUDED
#include "config.hpp" #include "config.hpp"
#include "cleanup.hpp"
#include "object.hpp" #include "object.hpp"
#include "function.hpp" #include "function.hpp"
#include "type_name.hpp" #include "type_name.hpp"
@ -19,7 +20,6 @@
#include <boost/function_types/parameter_types.hpp> #include <boost/function_types/parameter_types.hpp>
#include <boost/function_types/function_type.hpp> #include <boost/function_types/function_type.hpp>
#include <boost/function_types/result_type.hpp> #include <boost/function_types/result_type.hpp>
#include <boost/type_traits/is_base_of.hpp>
#include <boost/mpl/joint_view.hpp> #include <boost/mpl/joint_view.hpp>
#include <boost/mpl/single_view.hpp> #include <boost/mpl/single_view.hpp>
#include <boost/mpl/pop_front.hpp> #include <boost/mpl/pop_front.hpp>
@ -81,43 +81,6 @@ namespace detail
> >
{}; {};
template< typename E >
void set_parent( E& e, const std::string& prefix,
const std::string& name, const object& o )
{
o.set_child( e );
o.tag( prefix );
e.tag( name );
}
template< typename E, typename T >
void set_parent( E& e, const std::string& prefix,
const std::string& name, const T&,
BOOST_DEDUCED_TYPENAME boost::disable_if<
BOOST_DEDUCED_TYPENAME boost::is_base_of< object, T >
>::type* = 0 )
{
e.tag( prefix + name );
}
template< typename E >
E& configure( BOOST_DEDUCED_TYPENAME E::function_tag,
const std::string& parent, const std::string& /*name*/, E& e )
{
if( parent != "?" || e.tag() == "?" )
e.tag( parent );
return e;
}
template< typename E, typename T >
E& configure( E& e, const std::string& parent,
const std::string& name, const T& t )
{
if( parent != "?" || e.tag() == "?" )
mock::detail::set_parent( e,
parent + " " + mock::detail::type_name( typeid( T ) ) + "::",
name, t );
return e;
}
template< typename T > template< typename T >
struct base struct base
{ {
@ -134,22 +97,29 @@ namespace detail
mock::function< S > mock::function< S >
#define MOCK_MOCKER(o, t) \ #define MOCK_MOCKER(o, t) \
mock::detail::configure( mock::detail::deref( o ).exp##t, \ mock::detail::deref( o ).t( mock::detail::root, \
BOOST_PP_STRINGIZE(o), BOOST_PP_STRINGIZE(t), \ BOOST_PP_STRINGIZE(o) )
mock::detail::deref( o ) ) #define MOCK_ANONYMOUS_MOCKER(o, t) \
#define MOCK_ANONYMOUS_MOCKER(o, M, t) \ mock::detail::deref( o ).t( mock::detail::root, "?" )
mock::detail::configure( mock::detail::deref( o ).exp##t, \
"?", BOOST_PP_STRINGIZE(M), mock::detail::deref( o ) )
#define MOCK_METHOD_EXPECTATION(S, t) \ #define MOCK_METHOD_EXPECTATION(S, t) \
mutable mock::function< S > exp##t; mutable mock::function< S > t##expectation; \
mock::function< S >& t( const mock::detail::context&, \
const std::string& instance ) const \
{ \
mock::detail::configure( *this, t##expectation, instance, \
mock::detail::type_name( typeid( *this ) ), \
BOOST_PP_STRINGIZE(t) ); \
return t##expectation; \
}
#define MOCK_SIGNATURE(M) \ #define MOCK_SIGNATURE(M) \
mock::detail::signature< BOOST_TYPEOF(&base_type::M) >::type mock::detail::signature< BOOST_TYPEOF(&base_type::M) >::type // $$$$ MAT inline mock::detail::signature
#define MOCK_METHOD_STUB(M, n, S, t, c, tpn) \ #define MOCK_METHOD_STUB(M, n, S, t, c, tpn) \
MOCK_DECL(M, n, S, c, tpn) \ MOCK_DECL(M, n, S, c, tpn) \
{ \ { \
return MOCK_ANONYMOUS_MOCKER(this, t, t)( \ return MOCK_ANONYMOUS_MOCKER(this, t)( \
BOOST_PP_ENUM_PARAMS(n, p) ); \ BOOST_PP_ENUM_PARAMS(n, p) ); \
} }
@ -178,18 +148,18 @@ namespace detail
MOCK_METHOD_EXPECTATION(S, t) MOCK_METHOD_EXPECTATION(S, t)
#define MOCK_DESTRUCTOR(T, t) \ #define MOCK_DESTRUCTOR(T, t) \
~T() { MOCK_ANONYMOUS_MOCKER(this, ~T, t).test(); } \ ~T() { MOCK_ANONYMOUS_MOCKER(this, t).test(); } \
MOCK_METHOD_EXPECTATION(void(), t) MOCK_METHOD_EXPECTATION(void(), t)
#define MOCK_CONST_CONVERSION_OPERATOR(T, t) \ #define MOCK_CONST_CONVERSION_OPERATOR(T, t) \
operator T() const { return MOCK_ANONYMOUS_MOCKER(this, operator T, t)(); } \ operator T() const { return MOCK_ANONYMOUS_MOCKER(this, t)(); } \
MOCK_METHOD_EXPECTATION(T(), t) MOCK_METHOD_EXPECTATION(T(), t)
#define MOCK_NON_CONST_CONVERSION_OPERATOR(T, t) \ #define MOCK_NON_CONST_CONVERSION_OPERATOR(T, t) \
operator T() { return MOCK_ANONYMOUS_MOCKER(this, operator T, t)(); } \ operator T() { return MOCK_ANONYMOUS_MOCKER(this, t)(); } \
MOCK_METHOD_EXPECTATION(T(), t) MOCK_METHOD_EXPECTATION(T(), t)
#define MOCK_CONVERSION_OPERATOR(T, t) \ #define MOCK_CONVERSION_OPERATOR(T, t) \
operator T() const { return MOCK_ANONYMOUS_MOCKER(this, operator T, t)(); } \ operator T() const { return MOCK_ANONYMOUS_MOCKER(this, t)(); } \
operator T() { return MOCK_ANONYMOUS_MOCKER(this, operator T, t)(); } \ operator T() { return MOCK_ANONYMOUS_MOCKER(this, t)(); } \
MOCK_METHOD_EXPECTATION(T(), t) MOCK_METHOD_EXPECTATION(T(), t)
#define MOCK_EXPECT(o,t) MOCK_MOCKER(o,t).expect( __FILE__, __LINE__ ) #define MOCK_EXPECT(o,t) MOCK_MOCKER(o,t).expect( __FILE__, __LINE__ )

View file

@ -17,24 +17,9 @@
namespace mock namespace mock
{ {
class node : protected verifiable class node
{ {
public: public:
virtual ~node()
{
std::for_each( v_.begin(), v_.end(),
std::mem_fun( &verifiable::untie ) );
}
void tag( const std::string& name )
{
name_ = name;
}
const std::string& tag() const
{
return name_;
}
void add( verifiable& v ) void add( verifiable& v )
{ {
v_.push_back( &v ); v_.push_back( &v );

View file

@ -9,8 +9,12 @@
#ifndef MOCK_OBJECT_HPP_INCLUDED #ifndef MOCK_OBJECT_HPP_INCLUDED
#define MOCK_OBJECT_HPP_INCLUDED #define MOCK_OBJECT_HPP_INCLUDED
#include "node.hpp"
#include "root.hpp" #include "root.hpp"
#include "context.hpp"
#include "parent.hpp"
#include "child.hpp"
#include <boost/type_traits/is_base_of.hpp>
#include <boost/utility/enable_if.hpp>
#include <boost/shared_ptr.hpp> #include <boost/shared_ptr.hpp>
#include <string> #include <string>
@ -23,60 +27,101 @@ namespace mock
: impl_( new object_impl() ) : impl_( new object_impl() )
{} {}
template< typename T > bool verify() const // $$$$ MAT : to be deprecated
void set_child( T& t ) const
{
impl_->set_child( t );
}
void tag( const std::string& name ) const
{
impl_->tag( name );
}
bool verify() const
{ {
return impl_->verify(); return impl_->verify();
} }
void reset() void reset() // $$$$ MAT : to be deprecated
{ {
impl_->reset(); impl_->reset();
} }
private: private:
class object_impl : public node class object_impl : public detail::context, private verifiable
{ {
public: public:
object_impl() virtual void add( const void* /*p*/, verifiable& v,
: parent_( 0 ) const std::string& instance, const std::string& type,
{} const std::string& name )
virtual ~object_impl()
{ {
if( parent_ ) if( children_.empty() )
parent_->remove( *this );
}
template< typename T >
void set_child( T& t )
{
if( ! parent_ )
{
mock::detail::root.add( *this ); mock::detail::root.add( *this );
parent_ = &mock::detail::root; children_[ &v ].update( parent_, instance, type, name );
}
t.set_parent( *this );
} }
virtual void add( verifiable& v )
private:
virtual void untie()
{ {
parent_ = 0; group_.add( v );
}
virtual void remove( verifiable& v )
{
group_.remove( v );
children_.erase( &v );
if( children_.empty() )
mock::detail::root.remove( *this );
}
virtual void serialize( std::ostream& s,
const verifiable& v ) const
{
children_cit it = children_.find( &v );
if( it != children_.end() )
s << it->second;
else
s << "?";
}
virtual bool verify() const
{
return group_.verify();
}
virtual void reset()
{
group_.reset();
} }
private: private:
node* parent_; typedef std::map< const verifiable*, detail::child > children_t;
typedef children_t::const_iterator children_cit;
detail::group group_;
detail::parent parent_;
children_t children_;
}; };
public:
boost::shared_ptr< object_impl > impl_; boost::shared_ptr< object_impl > impl_;
}; };
namespace detail
{
template< typename E >
E& configure( const object& o, E& e, const std::string& instance,
const std::string& type, const std::string& name )
{
e.configure( *o.impl_, o.impl_.get(), instance, type, name );
return e;
}
template< typename E, typename T >
E& configure( const T& t, E& e, const std::string& instance,
const std::string& type, const std::string& name,
BOOST_DEDUCED_TYPENAME boost::disable_if<
BOOST_DEDUCED_TYPENAME boost::is_base_of< object, T >
>::type* = 0 )
{
e.configure( mock::detail::root, &t, instance, type, name );
return e;
}
}
inline bool verify( const object& o )
{
return o.impl_->verify();
}
inline void reset( object& o )
{
o.impl_->reset();
}
} }
#endif // MOCK_OBJECT_HPP_INCLUDED #endif // MOCK_OBJECT_HPP_INCLUDED

View file

@ -0,0 +1,42 @@
//
// 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_PARENT_HPP_INCLUDED
#define MOCK_PARENT_HPP_INCLUDED
#include <ostream>
#include <string>
namespace mock
{
namespace detail
{
class parent
{
public:
parent()
{}
parent( const std::string& instance, const std::string& type )
: instance_( instance )
, type_( type )
{}
friend std::ostream& operator<<( std::ostream& s, const parent& p )
{
s << p.instance_;
if( ! p.type_.empty() )
s << " " + p.type_ + "::";
return s;
}
private:
std::string instance_;
std::string type_;
};
}
}
#endif // MOCK_PARENT_HPP_INCLUDED

View file

@ -9,19 +9,118 @@
#ifndef MOCK_ROOT_HPP_INCLUDED #ifndef MOCK_ROOT_HPP_INCLUDED
#define MOCK_ROOT_HPP_INCLUDED #define MOCK_ROOT_HPP_INCLUDED
#include "config.hpp" #include "group.hpp"
#include "node.hpp" #include "context.hpp"
#include "parent.hpp"
#include "child.hpp"
#include "function.hpp"
#include <boost/test/utils/trivial_singleton.hpp> #include <boost/test/utils/trivial_singleton.hpp>
#include <ostream>
#include <string>
#include <map>
namespace mock namespace mock
{ {
namespace detail namespace detail
{ {
class root_t : public boost::unit_test::singleton< root_t >, public node class root_t : public boost::unit_test::singleton< root_t >,
public detail::context
{ {
public:
virtual void add( const void* p, verifiable& v,
const std::string& instance, const std::string& type,
const std::string& name )
{
children_it it = children_.lower_bound( &v );
if( it == children_.end() ||
children_.key_comp()( &v, it->first ) )
it = children_.insert( it,
std::make_pair( &v, counter_child( parents_, p ) ) );
it->second.update( instance, type, name );
}
virtual void add( verifiable& v )
{
group_.add( v );
}
virtual void remove( verifiable& v )
{
group_.remove( v );
children_.erase( &v );
}
bool verify() const
{
return group_.verify();
}
void reset() const
{
group_.reset();
}
virtual void serialize( std::ostream& s, const verifiable& v ) const
{
children_cit it = children_.find( &v );
if( it != children_.end() )
s << it->second;
else
s << "?";
}
private: private:
virtual void untie() typedef std::map< const void*,
{} std::pair< parent, std::size_t > > parents_t;
typedef parents_t::iterator parents_it;
class counter_child
{
public:
counter_child( parents_t& parents, const void* p )
: parents_( &parents )
, it_( parents.insert(
std::make_pair( p, parents_t::mapped_type() ) ).first )
{
++it_->second.second;
}
counter_child( const counter_child& rhs )
: parents_( rhs.parents_ )
, it_( rhs.it_ )
, child_( rhs.child_ )
{
++it_->second.second;
}
~counter_child()
{
if( --it_->second.second == 0 )
parents_->erase( it_ );
}
void update( const std::string& instance, const std::string& type,
const std::string& name )
{
child_.update( it_->second.first, instance, type, name );
}
friend std::ostream& operator<<( std::ostream& s,
const counter_child& c )
{
return s << c.child_;
}
private:
counter_child& operator=( const counter_child& );
parents_t* parents_;
parents_it it_;
child child_;
};
typedef std::map< const verifiable*, counter_child > children_t;
typedef children_t::const_iterator children_cit;
typedef children_t::iterator children_it;
parents_t parents_;
children_t children_;
group group_;
private: private:
BOOST_TEST_SINGLETON_CONS( root_t ); BOOST_TEST_SINGLETON_CONS( root_t );
}; };

View file

@ -22,8 +22,6 @@ namespace mock
virtual bool verify() const = 0; virtual bool verify() const = 0;
virtual void reset() = 0; virtual void reset() = 0;
virtual void untie() = 0;
}; };
} }

View file

@ -629,11 +629,10 @@ BOOST_FIXTURE_TEST_CASE( expectation_can_be_serialized_to_be_human_readable, err
{ {
{ {
mock::function< void( int ) > f; mock::function< void( int ) > f;
f.tag( "my function" );
f.expect().once().with( 1 ); f.expect().once().with( 1 );
f.expect().once().with( 2 ); f.expect().once().with( 2 );
BOOST_CHECK_NO_THROW( f( 2 ) ); BOOST_CHECK_NO_THROW( f( 2 ) );
const std::string expected = "my function\n" const std::string expected = "?\n"
". once().with( 1 )\n" ". once().with( 1 )\n"
"v once().with( 2 )"; "v once().with( 2 )";
BOOST_CHECK_EQUAL( expected, to_string( f ) ); BOOST_CHECK_EQUAL( expected, to_string( f ) );
@ -642,9 +641,8 @@ BOOST_FIXTURE_TEST_CASE( expectation_can_be_serialized_to_be_human_readable, err
} }
{ {
mock::function< void( int ) > f; mock::function< void( int ) > f;
f.tag( "my function" );
f.expect().never().with( 1 ); f.expect().never().with( 1 );
const std::string expected = "my function\n" const std::string expected = "?\n"
"v never().with( 1 )"; "v never().with( 1 )";
BOOST_CHECK_EQUAL( expected, to_string( f ) ); BOOST_CHECK_EQUAL( expected, to_string( f ) );
f.reset(); f.reset();
@ -672,36 +670,32 @@ BOOST_FIXTURE_TEST_CASE( expectation_can_be_serialized_to_be_human_readable, err
} }
{ {
mock::function< void( int ) > f; mock::function< void( int ) > f;
f.tag( "my function" );
f.expect().once(); f.expect().once();
const std::string expected = "my function\n" const std::string expected = "?\n"
". once().with( any )"; ". once().with( any )";
BOOST_CHECK_EQUAL( expected, to_string( f ) ); BOOST_CHECK_EQUAL( expected, to_string( f ) );
f.reset(); f.reset();
} }
{ {
mock::function< void( int ) > f; mock::function< void( int ) > f;
f.tag( "my function" );
f.expect().once().with( mock::any ); f.expect().once().with( mock::any );
const std::string expected = "my function\n" const std::string expected = "?\n"
". once().with( any )"; ". once().with( any )";
BOOST_CHECK_EQUAL( expected, to_string( f ) ); BOOST_CHECK_EQUAL( expected, to_string( f ) );
f.reset(); f.reset();
} }
{ {
mock::function< void( int ) > f; mock::function< void( int ) > f;
f.tag( "my function" );
f.expect().once(); f.expect().once();
const std::string expected = "my function\n" const std::string expected = "?\n"
". once().with( any )"; ". once().with( any )";
BOOST_CHECK_EQUAL( expected, to_string( f ) ); BOOST_CHECK_EQUAL( expected, to_string( f ) );
f.reset(); f.reset();
} }
{ {
mock::function< void( int ) > f; mock::function< void( int ) > f;
f.tag( "my function" );
f.expect().once().with( &custom_constraint ); f.expect().once().with( &custom_constraint );
const std::string expected = "my function\n" const std::string expected = "?\n"
". once().with( ? )"; ". once().with( ? )";
BOOST_CHECK_EQUAL( expected, to_string( f ) ); BOOST_CHECK_EQUAL( expected, to_string( f ) );
f.reset(); f.reset();

View file

@ -160,53 +160,50 @@ namespace
} }
} }
#define MOCK_ANONYMOUS_MOCKER_EXT(o, t) \
MOCK_ANONYMOUS_MOCKER( o, t, t )
BOOST_AUTO_TEST_CASE( mock_object_is_named ) BOOST_AUTO_TEST_CASE( mock_object_is_named )
{ {
my_mock m; my_mock m;
BOOST_CHECK_EQUAL( "? my_mock::my_method", to_string( MOCK_ANONYMOUS_MOCKER_EXT( m, my_method ) ) ); BOOST_CHECK_EQUAL( "? my_mock::my_method", to_string( MOCK_ANONYMOUS_MOCKER( m, my_method ) ) );
BOOST_CHECK_EQUAL( "? my_mock::my_method_2", to_string( MOCK_ANONYMOUS_MOCKER_EXT( m, my_method_2 ) ) ); BOOST_CHECK_EQUAL( "? my_mock::my_method_2", to_string( MOCK_ANONYMOUS_MOCKER( m, my_method_2 ) ) );
BOOST_CHECK_EQUAL( "m my_mock::my_method", to_string( MOCK_MOCKER( m, my_method ) ) ); BOOST_CHECK_EQUAL( "m my_mock::my_method", to_string( MOCK_MOCKER( m, my_method ) ) );
BOOST_CHECK_EQUAL( "m my_mock::my_method_2", to_string( MOCK_ANONYMOUS_MOCKER_EXT( m, my_method_2 ) ) ); BOOST_CHECK_EQUAL( "m my_mock::my_method_2", to_string( MOCK_ANONYMOUS_MOCKER( m, my_method_2 ) ) );
BOOST_CHECK_EQUAL( "m my_mock::my_method", to_string( MOCK_ANONYMOUS_MOCKER_EXT( m, my_method ) ) ); BOOST_CHECK_EQUAL( "m my_mock::my_method", to_string( MOCK_ANONYMOUS_MOCKER( m, my_method ) ) );
BOOST_CHECK_EQUAL( "m my_mock::my_method", to_string( MOCK_MOCKER( m, my_method ) ) ); BOOST_CHECK_EQUAL( "m my_mock::my_method", to_string( MOCK_MOCKER( m, my_method ) ) );
} }
BOOST_AUTO_TEST_CASE( mock_object_auto_pointer_is_named ) BOOST_AUTO_TEST_CASE( mock_object_auto_pointer_is_named )
{ {
std::auto_ptr< my_mock > m( new my_mock ); std::auto_ptr< my_mock > m( new my_mock );
BOOST_CHECK_EQUAL( "? my_mock::my_method", to_string( MOCK_ANONYMOUS_MOCKER_EXT( m, my_method ) ) ); BOOST_CHECK_EQUAL( "? my_mock::my_method", to_string( MOCK_ANONYMOUS_MOCKER( m, my_method ) ) );
BOOST_CHECK_EQUAL( "m my_mock::my_method", to_string( MOCK_MOCKER( m, my_method ) ) ); BOOST_CHECK_EQUAL( "m my_mock::my_method", to_string( MOCK_MOCKER( m, my_method ) ) );
BOOST_CHECK_EQUAL( "m my_mock::my_method", to_string( MOCK_ANONYMOUS_MOCKER_EXT( m, my_method ) ) ); BOOST_CHECK_EQUAL( "m my_mock::my_method", to_string( MOCK_ANONYMOUS_MOCKER( m, my_method ) ) );
BOOST_CHECK_EQUAL( "m my_mock::my_method", to_string( MOCK_MOCKER( m, my_method ) ) ); BOOST_CHECK_EQUAL( "m my_mock::my_method", to_string( MOCK_MOCKER( m, my_method ) ) );
} }
BOOST_AUTO_TEST_CASE( mock_object_const_auto_pointer_is_named ) BOOST_AUTO_TEST_CASE( mock_object_const_auto_pointer_is_named )
{ {
const std::auto_ptr< my_mock > m( new my_mock ); const std::auto_ptr< my_mock > m( new my_mock );
BOOST_CHECK_EQUAL( "? my_mock::my_method", to_string( MOCK_ANONYMOUS_MOCKER_EXT( m, my_method ) ) ); BOOST_CHECK_EQUAL( "? my_mock::my_method", to_string( MOCK_ANONYMOUS_MOCKER( m, my_method ) ) );
BOOST_CHECK_EQUAL( "m my_mock::my_method", to_string( MOCK_MOCKER( m, my_method ) ) ); BOOST_CHECK_EQUAL( "m my_mock::my_method", to_string( MOCK_MOCKER( m, my_method ) ) );
BOOST_CHECK_EQUAL( "m my_mock::my_method", to_string( MOCK_ANONYMOUS_MOCKER_EXT( m, my_method ) ) ); BOOST_CHECK_EQUAL( "m my_mock::my_method", to_string( MOCK_ANONYMOUS_MOCKER( m, my_method ) ) );
BOOST_CHECK_EQUAL( "m my_mock::my_method", to_string( MOCK_MOCKER( m, my_method ) ) ); BOOST_CHECK_EQUAL( "m my_mock::my_method", to_string( MOCK_MOCKER( m, my_method ) ) );
} }
BOOST_AUTO_TEST_CASE( mock_object_shared_pointer_is_named ) BOOST_AUTO_TEST_CASE( mock_object_shared_pointer_is_named )
{ {
boost::shared_ptr< my_mock > m( new my_mock ); boost::shared_ptr< my_mock > m( new my_mock );
BOOST_CHECK_EQUAL( "? my_mock::my_method", to_string( MOCK_ANONYMOUS_MOCKER_EXT( m, my_method ) ) ); BOOST_CHECK_EQUAL( "? my_mock::my_method", to_string( MOCK_ANONYMOUS_MOCKER( m, my_method ) ) );
BOOST_CHECK_EQUAL( "m my_mock::my_method", to_string( MOCK_MOCKER( m, my_method ) ) ); BOOST_CHECK_EQUAL( "m my_mock::my_method", to_string( MOCK_MOCKER( m, my_method ) ) );
BOOST_CHECK_EQUAL( "m my_mock::my_method", to_string( MOCK_ANONYMOUS_MOCKER_EXT( m, my_method ) ) ); BOOST_CHECK_EQUAL( "m my_mock::my_method", to_string( MOCK_ANONYMOUS_MOCKER( m, my_method ) ) );
BOOST_CHECK_EQUAL( "m my_mock::my_method", to_string( MOCK_MOCKER( m, my_method ) ) ); BOOST_CHECK_EQUAL( "m my_mock::my_method", to_string( MOCK_MOCKER( m, my_method ) ) );
} }
BOOST_AUTO_TEST_CASE( mock_object_const_shared_pointer_is_named ) BOOST_AUTO_TEST_CASE( mock_object_const_shared_pointer_is_named )
{ {
const boost::shared_ptr< my_mock > m( new my_mock ); const boost::shared_ptr< my_mock > m( new my_mock );
BOOST_CHECK_EQUAL( "? my_mock::my_method", to_string( MOCK_ANONYMOUS_MOCKER_EXT( m, my_method ) ) ); BOOST_CHECK_EQUAL( "? my_mock::my_method", to_string( MOCK_ANONYMOUS_MOCKER( m, my_method ) ) );
BOOST_CHECK_EQUAL( "m my_mock::my_method", to_string( MOCK_MOCKER( m, my_method ) ) ); BOOST_CHECK_EQUAL( "m my_mock::my_method", to_string( MOCK_MOCKER( m, my_method ) ) );
BOOST_CHECK_EQUAL( "m my_mock::my_method", to_string( MOCK_ANONYMOUS_MOCKER_EXT( m, my_method ) ) ); BOOST_CHECK_EQUAL( "m my_mock::my_method", to_string( MOCK_ANONYMOUS_MOCKER( m, my_method ) ) );
BOOST_CHECK_EQUAL( "m my_mock::my_method", to_string( MOCK_MOCKER( m, my_method ) ) ); BOOST_CHECK_EQUAL( "m my_mock::my_method", to_string( MOCK_MOCKER( m, my_method ) ) );
} }
@ -222,11 +219,11 @@ namespace
BOOST_AUTO_TEST_CASE( custom_mock_object_without_macros_and_without_inheriting_from_object_is_named ) BOOST_AUTO_TEST_CASE( custom_mock_object_without_macros_and_without_inheriting_from_object_is_named )
{ {
my_custom_mock m; my_custom_mock m;
BOOST_CHECK_EQUAL( "? my_custom_mock::my_method", to_string( MOCK_ANONYMOUS_MOCKER_EXT( m, my_method ) ) ); BOOST_CHECK_EQUAL( "? my_custom_mock::my_method", to_string( MOCK_ANONYMOUS_MOCKER( m, my_method ) ) );
BOOST_CHECK_EQUAL( "? my_custom_mock::my_method_2", to_string( MOCK_ANONYMOUS_MOCKER_EXT( m, my_method_2 ) ) ); BOOST_CHECK_EQUAL( "? my_custom_mock::my_method_2", to_string( MOCK_ANONYMOUS_MOCKER( m, my_method_2 ) ) );
BOOST_CHECK_EQUAL( "m my_custom_mock::my_method", to_string( MOCK_MOCKER( m, my_method ) ) ); BOOST_CHECK_EQUAL( "m my_custom_mock::my_method", to_string( MOCK_MOCKER( m, my_method ) ) );
BOOST_CHECK_EQUAL( "? my_custom_mock::my_method_2", to_string( MOCK_ANONYMOUS_MOCKER_EXT( m, my_method_2 ) ) ); BOOST_CHECK_EQUAL( "m my_custom_mock::my_method_2", to_string( MOCK_ANONYMOUS_MOCKER( m, my_method_2 ) ) );
BOOST_CHECK_EQUAL( "m my_custom_mock::my_method", to_string( MOCK_ANONYMOUS_MOCKER_EXT( m, my_method ) ) ); BOOST_CHECK_EQUAL( "m my_custom_mock::my_method", to_string( MOCK_ANONYMOUS_MOCKER( m, my_method ) ) );
BOOST_CHECK_EQUAL( "m my_custom_mock::my_method", to_string( MOCK_MOCKER( m, my_method ) ) ); BOOST_CHECK_EQUAL( "m my_custom_mock::my_method", to_string( MOCK_MOCKER( m, my_method ) ) );
} }
@ -242,11 +239,11 @@ namespace
BOOST_AUTO_TEST_CASE( custom_mock_object_without_macros_is_named ) BOOST_AUTO_TEST_CASE( custom_mock_object_without_macros_is_named )
{ {
my_custom_mock_object m; my_custom_mock_object m;
BOOST_CHECK_EQUAL( "? my_custom_mock_object::my_method", to_string( MOCK_ANONYMOUS_MOCKER_EXT( m, my_method ) ) ); BOOST_CHECK_EQUAL( "? my_custom_mock_object::my_method", to_string( MOCK_ANONYMOUS_MOCKER( m, my_method ) ) );
BOOST_CHECK_EQUAL( "? my_custom_mock_object::my_method_2", to_string( MOCK_ANONYMOUS_MOCKER_EXT( m, my_method_2 ) ) ); BOOST_CHECK_EQUAL( "? my_custom_mock_object::my_method_2", to_string( MOCK_ANONYMOUS_MOCKER( m, my_method_2 ) ) );
BOOST_CHECK_EQUAL( "m my_custom_mock_object::my_method", to_string( MOCK_MOCKER( m, my_method ) ) ); BOOST_CHECK_EQUAL( "m my_custom_mock_object::my_method", to_string( MOCK_MOCKER( m, my_method ) ) );
BOOST_CHECK_EQUAL( "m my_custom_mock_object::my_method_2", to_string( MOCK_ANONYMOUS_MOCKER_EXT( m, my_method_2 ) ) ); BOOST_CHECK_EQUAL( "m my_custom_mock_object::my_method_2", to_string( MOCK_ANONYMOUS_MOCKER( m, my_method_2 ) ) );
BOOST_CHECK_EQUAL( "m my_custom_mock_object::my_method", to_string( MOCK_ANONYMOUS_MOCKER_EXT( m, my_method ) ) ); BOOST_CHECK_EQUAL( "m my_custom_mock_object::my_method", to_string( MOCK_ANONYMOUS_MOCKER( m, my_method ) ) );
BOOST_CHECK_EQUAL( "m my_custom_mock_object::my_method", to_string( MOCK_MOCKER( m, my_method ) ) ); BOOST_CHECK_EQUAL( "m my_custom_mock_object::my_method", to_string( MOCK_MOCKER( m, my_method ) ) );
} }

View file

@ -19,39 +19,43 @@ namespace
BOOST_AUTO_TEST_CASE( verifying_an_empty_object_succeeds ) BOOST_AUTO_TEST_CASE( verifying_an_empty_object_succeeds )
{ {
mock::object o; mock::object o;
BOOST_CHECK( o.verify() ); BOOST_CHECK( mock::verify( o ) );
} }
BOOST_AUTO_TEST_CASE( verifying_an_object_containing_a_failing_expectation_fails ) namespace
{
struct fixture
{
fixture()
{
mock::detail::configure( o, e, "instance", "type", "name" );
}
mock::object o;
mock::function< void() > e;
};
}
BOOST_FIXTURE_TEST_CASE( verifying_an_object_containing_a_failing_expectation_fails, fixture )
{ {
mock::object o;
mock::function< void() > e;
o.set_child( e );
e.expect().once(); e.expect().once();
BOOST_CHECK( ! o.verify() ); BOOST_CHECK( ! mock::verify( o ) );
o.reset(); mock::reset( o );
BOOST_CHECK( o.verify() ); BOOST_CHECK( mock::verify( o ) );
} }
BOOST_AUTO_TEST_CASE( verifying_all_objects_with_one_of_them_containing_a_failing_expectation_fails ) BOOST_FIXTURE_TEST_CASE( verifying_all_objects_with_one_of_them_containing_a_failing_expectation_fails, fixture )
{ {
mock::object o;
mock::function< void() > e;
o.set_child( e );
e.expect().once(); e.expect().once();
BOOST_CHECK( ! mock::verify() ); BOOST_CHECK( ! mock::verify() );
mock::reset(); mock::reset();
BOOST_CHECK( mock::verify() ); BOOST_CHECK( mock::verify() );
} }
BOOST_AUTO_TEST_CASE( resetting_an_object_containing_a_failing_expectation_and_verifying_it_succeeds ) BOOST_FIXTURE_TEST_CASE( resetting_an_object_containing_a_failing_expectation_and_verifying_it_succeeds, fixture )
{ {
mock::object o;
mock::function< void() > e;
o.set_child( e );
e.expect().once(); e.expect().once();
o.reset(); mock::reset( o );
BOOST_CHECK( o.verify() ); BOOST_CHECK( mock::verify( o ) );
} }
BOOST_AUTO_TEST_CASE( an_object_is_assignable_by_sharing_its_state ) BOOST_AUTO_TEST_CASE( an_object_is_assignable_by_sharing_its_state )
@ -60,13 +64,13 @@ BOOST_AUTO_TEST_CASE( an_object_is_assignable_by_sharing_its_state )
mock::function< void() > e; mock::function< void() > e;
{ {
mock::object o2; mock::object o2;
o2.set_child( e ); mock::detail::configure( o2, e, "instance", "type", "name" );
e.expect().once(); e.expect().once();
o1 = o2; o1 = o2;
BOOST_CHECK( ! o2.verify() ); BOOST_CHECK( ! mock::verify( o2 ) );
BOOST_CHECK( ! o1.verify() ); BOOST_CHECK( ! mock::verify( o1 ) );
} }
BOOST_CHECK( ! o1.verify() ); BOOST_CHECK( ! mock::verify( o1 ) );
} }
BOOST_AUTO_TEST_CASE( an_object_is_copiable_by_sharing_its_state ) BOOST_AUTO_TEST_CASE( an_object_is_copiable_by_sharing_its_state )
@ -74,20 +78,10 @@ BOOST_AUTO_TEST_CASE( an_object_is_copiable_by_sharing_its_state )
std::auto_ptr< mock::object > o2( new mock::object ); std::auto_ptr< mock::object > o2( new mock::object );
const mock::object o1( *o2 ); const mock::object o1( *o2 );
mock::function< void() > e; mock::function< void() > e;
o2->set_child( e ); mock::detail::configure( *o2, e, "instance", "type", "name" );
e.expect().once(); e.expect().once();
BOOST_CHECK( ! o2->verify() ); BOOST_CHECK( ! mock::verify( *o2 ) );
BOOST_CHECK( ! o1.verify() ); BOOST_CHECK( ! mock::verify( o1 ) );
o2.reset(); o2.reset();
BOOST_CHECK( ! o1.verify() ); BOOST_CHECK( ! mock::verify( o1 ) );
}
BOOST_AUTO_TEST_CASE( an_object_can_be_destroyed_before_its_children_functions )
{
mock::function< void() > f;
{
mock::object o;
o.set_child( f );
}
f.test();
} }