Fix the compilation for c++98 by not supporting async

This commit is contained in:
Thomas Bernard 2016-01-20 01:01:47 +01:00
parent 7024b37789
commit 98e61a5d9b
9 changed files with 108 additions and 38 deletions

View file

@ -82,4 +82,10 @@
# endif # endif
#endif #endif
#if defined(MOCK_RVALUE_REFERENCES) && defined(MOCK_THREAD_SAFE)
# ifndef MOCK_NO_ASYNC
# define MOCK_ASYNC
# endif
#endif
#endif // MOCK_CONFIG_HPP_INCLUDED #endif // MOCK_CONFIG_HPP_INCLUDED

View file

@ -127,7 +127,7 @@ namespace detail
value_imp( BOOST_RV_REF( value_type ) t ) value_imp( BOOST_RV_REF( value_type ) t )
: t_( boost::move( t ) ) : t_( boost::move( t ) )
{} {}
value_imp( const T& t ) value_imp( const typename boost::remove_reference<T>::type & t )
: t_( t ) : t_( t )
{} {}
template< typename Y > template< typename Y >
@ -150,10 +150,10 @@ namespace detail
return static_cast< value_imp< T >& >( *v_ ).t_; return static_cast< value_imp< T >& >( *v_ ).t_;
} }
template< typename T > template< typename T >
Result& store( T* t ) typename boost::remove_reference<Result>::type & store( T* t )
{ {
v_.reset( new value_imp< Result >( t ) ); v_.reset( new value_imp< Result >( t ) );
return static_cast< value_imp< Result >& >( *v_ ).t_; return static_cast< value_imp< typename boost::remove_reference< Result >::type >& >( *v_ ).t_;
} }
boost::shared_ptr< value > v_; boost::shared_ptr< value > v_;

View file

@ -7,7 +7,7 @@
// http://www.boost.org/LICENSE_1_0.txt) // http://www.boost.org/LICENSE_1_0.txt)
#include "matcher_base_template.hpp" #include "matcher_base_template.hpp"
#include <atomic> #include <boost/atomic.hpp>
#define MOCK_EXPECTATION_INITIALIZE(z, n, d) \ #define MOCK_EXPECTATION_INITIALIZE(z, n, d) \
BOOST_PP_COMMA_IF(n) c##n##_( c##n ) BOOST_PP_COMMA_IF(n) c##n##_( c##n )
@ -134,7 +134,7 @@ namespace detail
> () ) > () )
, file_( "unknown location" ) , file_( "unknown location" )
, line_( 0 ) , line_( 0 )
#if defined(MOCK_THREAD_SAFE) #if defined(MOCK_ASYNC)
, blocked(false) , blocked(false)
#endif #endif
{ } { }
@ -148,21 +148,32 @@ namespace detail
> () ) > () )
, file_( file ) , file_( file )
, line_( line ) , line_( line )
#if defined(MOCK_THREAD_SAFE) #if defined(MOCK_ASYNC)
, blocked(false) , blocked(false)
#endif #endif
{ } { }
expectation(expectation && e) expectation(BOOST_RV_REF(expectation) e)
: invocation_ ( e.invocation_) : invocation_ ( e.invocation_)
, matcher_(e.matcher_) , matcher_(e.matcher_)
, file_(e.file_) , file_(e.file_)
, line_(e.line_) , line_(e.line_)
#if defined(MOCK_THREAD_SAFE) #if defined(MOCK_ASYNC)
, blocked(false) , blocked(false)
#endif #endif
{} {}
expectation &operator=(BOOST_RV_REF(expectation) e)
{
invocation_ = e.invocation_;
matcher_ =e.matcher_;
file_ = e.file_;
line_ = e.line_;
#if defined(MOCK_ASYNC)
blocked.store(false, boost::memory_order_release);
#endif
}
~expectation() ~expectation()
{ {
for( sequences_cit it = sequences_.begin(); for( sequences_cit it = sequences_.begin();
@ -202,12 +213,12 @@ namespace detail
} }
#endif #endif
#endif #endif
#if defined(MOCK_THREAD_SAFE) #if defined(MOCK_ASYNC)
template < typename duration> template < typename duration>
expectation &async(const duration timeout) expectation &async(const duration timeout)
{ {
timeout_ = timeout; timeout_ = timeout;
blocked.store(false,std::memory_order_release); blocked.store(false,boost::memory_order_release);
return *this; return *this;
} }
#endif #endif
@ -221,7 +232,7 @@ namespace detail
{ {
return invocation_->verify(); return invocation_->verify();
} }
#if defined(MOCK_THREAD_SAFE) #if defined(MOCK_ASYNC)
bool verify(const boost::shared_ptr< condition_variable> &cv, lock &lk) const bool verify(const boost::shared_ptr< condition_variable> &cv, lock &lk) const
{ {
if (timeout_) if (timeout_)
@ -230,7 +241,7 @@ namespace detail
{ {
if (MOCK_THREAD_NAMESPACE::cv_status::timeout == cv->wait_for(lk.get_unique_lock(), *timeout_)) if (MOCK_THREAD_NAMESPACE::cv_status::timeout == cv->wait_for(lk.get_unique_lock(), *timeout_))
{ {
blocked.store(true, std::memory_order_release); blocked.store(true, boost::memory_order_release);
return false; return false;
} }
} }
@ -241,8 +252,8 @@ namespace detail
bool is_valid( bool is_valid(
BOOST_PP_ENUM_BINARY_PARAMS(MOCK_NUM_ARGS, T, a) ) const BOOST_PP_ENUM_BINARY_PARAMS(MOCK_NUM_ARGS, T, a) ) const
{ {
#if defined(MOCK_THREAD_SAFE) #if defined(MOCK_ASYNC)
return !blocked.load(std::memory_order_acquire) && !invocation_->exhausted() return !blocked.load(boost::memory_order_acquire) && !invocation_->exhausted()
&& (*matcher_)( BOOST_PP_ENUM_PARAMS(MOCK_NUM_ARGS, a) ); && (*matcher_)( BOOST_PP_ENUM_PARAMS(MOCK_NUM_ARGS, a) );
#else #else
return !invocation_->exhausted() return !invocation_->exhausted()
@ -252,8 +263,8 @@ namespace detail
bool invoke() const bool invoke() const
{ {
#if defined(MOCK_THREAD_SAFE) #if defined(MOCK_ASYNC)
if (blocked.load(std::memory_order_acquire)) if (blocked.load(boost::memory_order_acquire))
return false; return false;
#endif #endif
for( sequences_cit it = sequences_.begin(); for( sequences_cit it = sequences_.begin();
@ -302,9 +313,9 @@ namespace detail
sequences_type sequences_; sequences_type sequences_;
const char* file_; const char* file_;
int line_; int line_;
#if defined(MOCK_THREAD_SAFE) #if defined(MOCK_ASYNC)
boost::optional<nanoseconds> timeout_; boost::optional<nanoseconds> timeout_;
mutable std::atomic<bool> blocked; mutable boost::atomic<bool> blocked;
#endif #endif
}; };
} }

View file

@ -49,7 +49,7 @@ namespace detail
: e_( &e ) : e_( &e )
{} {}
wrapper_base( wrapper_base && w ) wrapper_base( BOOST_RV_REF(wrapper_base) w )
: e_( w.e_ ) : e_( w.e_ )
{} {}
@ -68,7 +68,7 @@ namespace detail
: e_( &e ) : e_( &e )
{} {}
wrapper_base( wrapper_base && w ) wrapper_base( BOOST_RV_REF(wrapper_base) w )
: e_( w.e_ ) : e_( w.e_ )
{} {}
@ -82,7 +82,7 @@ namespace detail
: e_( &e ) : e_( &e )
{} {}
wrapper_base( wrapper_base && w ) wrapper_base( BOOST_RV_REF(wrapper_base) w )
: e_( w.e_ ) : e_( w.e_ )
{} {}

View file

@ -8,7 +8,8 @@
#include "expectation_template.hpp" #include "expectation_template.hpp"
#include <boost/move/utility.hpp> #include <boost/move/utility.hpp>
#include <atomic> #include <boost/atomic.hpp>
#include <iostream>
#ifndef MOCK_ERROR_POLICY #ifndef MOCK_ERROR_POLICY
# error no error policy has been set # error no error policy has been set
@ -46,7 +47,7 @@ namespace detail
: context_( 0 ) : context_( 0 )
, valid_( true ) , valid_( true )
, mutex_( boost::make_shared< mutex >() ) , mutex_( boost::make_shared< mutex >() )
#if defined(MOCK_THREAD_SAFE) #if defined(MOCK_ASYNC)
, cv_( boost::make_shared< condition_variable>() ) , cv_( boost::make_shared< condition_variable>() )
#endif #endif
{} {}
@ -56,7 +57,7 @@ namespace detail
lock _(mutex_); lock _(mutex_);
for (expectations_cit it = expectations_.begin(); for (expectations_cit it = expectations_.begin();
it != expectations_.end(); ++it) it != expectations_.end(); ++it)
#if defined(MOCK_THREAD_SAFE) #if defined(MOCK_ASYNC)
if (!it->verify(cv_, _)) if (!it->verify(cv_, _))
#else #else
if (!it->verify()) if (!it->verify())
@ -67,7 +68,7 @@ namespace detail
<< lazy_expectations(this), << lazy_expectations(this),
it->file(), it->line()); it->file(), it->line());
} }
context *c = context_.load(std::memory_order_acquire); context *c = context_.load(boost::memory_order_acquire);
if (c) if (c)
c->remove( *this ); c->remove( *this );
} }
@ -77,7 +78,7 @@ namespace detail
lock _( mutex_ ); lock _( mutex_ );
for( expectations_cit it = expectations_.begin(); for( expectations_cit it = expectations_.begin();
it != expectations_.end(); ++it ) it != expectations_.end(); ++it )
#if defined(MOCK_THREAD_SAFE) #if defined(MOCK_ASYNC)
if( ! it->verify(cv_,_) ) if( ! it->verify(cv_,_) )
#else #else
if( ! it->verify() ) if( ! it->verify() )
@ -121,7 +122,7 @@ namespace detail
wrapper( BOOST_RV_REF(wrapper) w) wrapper( BOOST_RV_REF(wrapper) w)
: wrapper_base< R, expectation_type > (*w.e_) : wrapper_base< R, expectation_type > (*w.e_)
, lock_( std::move(w.lock_) ) , lock_( boost::move(w.lock_) )
{ {
} }
@ -197,7 +198,7 @@ namespace detail
#undef MOCK_FUNCTION_IN #undef MOCK_FUNCTION_IN
#undef MOCK_FUNCTION_IN_ADD #undef MOCK_FUNCTION_IN_ADD
#if defined(MOCK_THREAD_SAFE) #if defined(MOCK_ASYNC)
wrapper &async(const nanoseconds &timeout) wrapper &async(const nanoseconds &timeout)
{ {
this->e_->async(timeout); this->e_->async(timeout);
@ -245,7 +246,7 @@ namespace detail
BOOST_PP_ENUM_BINARY_PARAMS(MOCK_NUM_ARGS, T, t) ) const BOOST_PP_ENUM_BINARY_PARAMS(MOCK_NUM_ARGS, T, t) ) const
{ {
lock _( mutex_ ); lock _( mutex_ );
#if defined(MOCK_THREAD_SAFE) #if defined(MOCK_ASYNC)
struct notify_cv_on_exit struct notify_cv_on_exit
{ {
notify_cv_on_exit(condition_variable &cv) notify_cv_on_exit(condition_variable &cv)
@ -293,7 +294,7 @@ namespace detail
boost::optional< type_name > type, boost::optional< type_name > type,
boost::unit_test::const_string name ) boost::unit_test::const_string name )
{ {
if (!context_.exchange(&c,std::memory_order_release)) if (!context_.exchange(&c,boost::memory_order_release))
c.add( *this ); c.add( *this );
c.add( p, *this, instance, type, name ); c.add( p, *this, instance, type, name );
} }
@ -314,7 +315,7 @@ namespace detail
std::ostream& s, const lazy_context& c ) std::ostream& s, const lazy_context& c )
{ {
context *pContext = c.impl_->context_.load(std::memory_order_acquire); context *pContext = c.impl_->context_.load(boost::memory_order_acquire);
if( pContext ) if( pContext )
pContext->serialize( s, *c.impl_ ); pContext->serialize( s, *c.impl_ );
else else
@ -344,10 +345,10 @@ namespace detail
typedef typename expectations_type::const_iterator expectations_cit; typedef typename expectations_type::const_iterator expectations_cit;
expectations_type expectations_; expectations_type expectations_;
std::atomic<context*> context_; boost::atomic<context*> context_;
mutable bool valid_; mutable bool valid_;
const boost::shared_ptr< mutex > mutex_; const boost::shared_ptr< mutex > mutex_;
#if defined(MOCK_THREAD_SAFE) #if defined(MOCK_ASYNC)
const boost::shared_ptr<condition_variable> cv_; const boost::shared_ptr<condition_variable> cv_;
#endif #endif
}; };

View file

@ -42,6 +42,7 @@ namespace detail
typedef MOCK_THREAD_NAMESPACE::chrono::nanoseconds nanoseconds; typedef MOCK_THREAD_NAMESPACE::chrono::nanoseconds nanoseconds;
typedef MOCK_THREAD_NAMESPACE::unique_lock<mutex> lock_base; typedef MOCK_THREAD_NAMESPACE::unique_lock<mutex> lock_base;
#if defined(MOCK_ASYNC)
struct lock : public lock_base struct lock : public lock_base
{ {
lock(const boost::shared_ptr< detail::mutex > &m) lock(const boost::shared_ptr< detail::mutex > &m)
@ -49,7 +50,7 @@ namespace detail
, m_(m) , m_(m)
{} {}
lock(lock && l) lock(BOOST_RV_REF(lock) l)
: lock_base(*l.m_) : lock_base(*l.m_)
, m_(l.m_) , m_(l.m_)
{ {
@ -62,6 +63,31 @@ namespace detail
boost::shared_ptr< detail::mutex > m_; boost::shared_ptr< detail::mutex > m_;
}; };
#else // MOCK_ASYNC
struct lock
{
lock(const boost::shared_ptr< detail::mutex > &m)
: m_(m)
{
m_->lock();
}
lock( const lock & rhs)
{
m_.swap(rhs.m_);
}
~lock()
{
if(m_)
m_->unlock();
}
private:
lock & operator=(const lock &rhs);
mutable boost::shared_ptr< detail::mutex > m_;
};
#endif // MOCK_ASYNC
} }
} // mock } // mock

View file

@ -23,12 +23,14 @@ namespace
MOCK_CLASS( mock_class ) MOCK_CLASS( mock_class )
{ {
MOCK_METHOD_EXT( my_method, 1, void( const std::string& ), my_tag ) MOCK_METHOD_EXT( my_method, 1, void( const std::string& ), my_tag )
MOCK_METHOD_EXT( my_method2, 1, void( const std::string& ), my_tag2 )
}; };
} }
BOOST_FIXTURE_TEST_CASE( mock_object_asynchonous_call_expectation, mock_error_fixture ) BOOST_FIXTURE_TEST_CASE( mock_object_asynchonous_call_expectation, mock_error_fixture )
{ {
#if defined(MOCK_THREAD_SAFE) #if defined(MOCK_ASYNC)
const mock_class m{}; const mock_class m{};
MOCK_EXPECT( m.my_tag ).async(MOCK_THREAD_NAMESPACE::chrono::milliseconds(50)).once().with( "some parameter" ); MOCK_EXPECT( m.my_tag ).async(MOCK_THREAD_NAMESPACE::chrono::milliseconds(50)).once().with( "some parameter" );
MOCK_THREAD_NAMESPACE::thread context([&](){ MOCK_THREAD_NAMESPACE::thread context([&](){
@ -42,9 +44,33 @@ BOOST_FIXTURE_TEST_CASE( mock_object_asynchonous_call_expectation, mock_error_fi
} }
BOOST_FIXTURE_TEST_CASE( mock_object_asynchonous_call_expectation_in_sequence, mock_error_fixture )
{
#if defined(MOCK_ASYNC)
const mock_class m{};
mock::sequence s;
MOCK_EXPECT( m.my_tag ).async(MOCK_THREAD_NAMESPACE::chrono::milliseconds(50)).once().in(s).with( "some parameter" );
MOCK_EXPECT( m.my_tag ).async(MOCK_THREAD_NAMESPACE::chrono::milliseconds(150)).once().in(s).with( "some parameter2" );
MOCK_THREAD_NAMESPACE::thread context([&](){
MOCK_THREAD_NAMESPACE::this_thread::sleep_for(MOCK_THREAD_NAMESPACE::chrono::milliseconds(10));
m.my_method("some parameter");
MOCK_THREAD_NAMESPACE::this_thread::sleep_for(MOCK_THREAD_NAMESPACE::chrono::milliseconds(20));
m.my_method("some parameter2");
});
mock::verify();
CHECK_CALLS( 2 );
context.join();
#endif
}
BOOST_AUTO_TEST_CASE( mock_object_asynchonous_call_expectation_fails ) BOOST_AUTO_TEST_CASE( mock_object_asynchonous_call_expectation_fails )
{ {
#if defined(MOCK_THREAD_SAFE) #if defined(MOCK_ASYNC)
mock::reset();
mock_error_data.reset();
const mock_class m{}; const mock_class m{};
bool unexpected_call_received = false; bool unexpected_call_received = false;
MOCK_EXPECT( m.my_tag ).async(MOCK_THREAD_NAMESPACE::chrono::milliseconds(50)).once().with( "some parameter" ); MOCK_EXPECT( m.my_tag ).async(MOCK_THREAD_NAMESPACE::chrono::milliseconds(50)).once().with( "some parameter" );

View file

@ -128,7 +128,7 @@ BOOST_FIXTURE_TEST_CASE( mock_object_method_const_disambiguation, mock_error_fix
my_const_ambiguited_mock mock; my_const_ambiguited_mock mock;
MOCK_EXPECT( mock.tag1 ); MOCK_EXPECT( mock.tag1 );
BOOST_CHECK_NO_THROW( mock.my_method() ); BOOST_CHECK_NO_THROW( mock.my_method() );
const my_const_ambiguited_mock const_mock{}; const my_const_ambiguited_mock const_mock;
CHECK_ERROR( const_mock.my_method(), "unexpected call", 1, "?.my_const_ambiguited_mock::tag_2()" ); CHECK_ERROR( const_mock.my_method(), "unexpected call", 1, "?.my_const_ambiguited_mock::tag_2()" );
} }

View file

@ -367,7 +367,7 @@ namespace
MOCK_BASE_CLASS( variadic, base ) MOCK_BASE_CLASS( variadic, base )
{ {
MOCK_METHOD( m1, 0 ) MOCK_METHOD( m1, 0, void() )
MOCK_METHOD( m2, 0, void() ) MOCK_METHOD( m2, 0, void() )
MOCK_METHOD( m3, 0, void(), m3 ) MOCK_METHOD( m3, 0, void(), m3 )
MOCK_CONST_METHOD( m4, 0, void() ) MOCK_CONST_METHOD( m4, 0, void() )