From 98e61a5d9b9ee3d9dcb706ca614d63dd44f70a22 Mon Sep 17 00:00:00 2001 From: Thomas Bernard Date: Wed, 20 Jan 2016 01:01:47 +0100 Subject: [PATCH] Fix the compilation for c++98 by not supporting async --- include/turtle/config.hpp | 6 +++ include/turtle/detail/action.hpp | 6 +-- .../turtle/detail/expectation_template.hpp | 41 ++++++++++++------- include/turtle/detail/function.hpp | 6 +-- .../turtle/detail/function_impl_template.hpp | 25 +++++------ include/turtle/detail/mutex.hpp | 28 ++++++++++++- test/test_async.cpp | 30 +++++++++++++- test/test_integration.cpp | 2 +- test/test_mock.cpp | 2 +- 9 files changed, 108 insertions(+), 38 deletions(-) diff --git a/include/turtle/config.hpp b/include/turtle/config.hpp index 54000f6..451d61a 100644 --- a/include/turtle/config.hpp +++ b/include/turtle/config.hpp @@ -82,4 +82,10 @@ # 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 diff --git a/include/turtle/detail/action.hpp b/include/turtle/detail/action.hpp index db98aad..0dabb5d 100644 --- a/include/turtle/detail/action.hpp +++ b/include/turtle/detail/action.hpp @@ -127,7 +127,7 @@ namespace detail value_imp( BOOST_RV_REF( value_type ) t ) : t_( boost::move( t ) ) {} - value_imp( const T& t ) + value_imp( const typename boost::remove_reference::type & t ) : t_( t ) {} template< typename Y > @@ -150,10 +150,10 @@ namespace detail return static_cast< value_imp< T >& >( *v_ ).t_; } template< typename T > - Result& store( T* t ) + typename boost::remove_reference::type & store( T* 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_; diff --git a/include/turtle/detail/expectation_template.hpp b/include/turtle/detail/expectation_template.hpp index ca9f644..d1c8761 100644 --- a/include/turtle/detail/expectation_template.hpp +++ b/include/turtle/detail/expectation_template.hpp @@ -7,7 +7,7 @@ // http://www.boost.org/LICENSE_1_0.txt) #include "matcher_base_template.hpp" -#include +#include #define MOCK_EXPECTATION_INITIALIZE(z, n, d) \ BOOST_PP_COMMA_IF(n) c##n##_( c##n ) @@ -134,7 +134,7 @@ namespace detail > () ) , file_( "unknown location" ) , line_( 0 ) -#if defined(MOCK_THREAD_SAFE) +#if defined(MOCK_ASYNC) , blocked(false) #endif { } @@ -148,21 +148,32 @@ namespace detail > () ) , file_( file ) , line_( line ) -#if defined(MOCK_THREAD_SAFE) +#if defined(MOCK_ASYNC) , blocked(false) #endif { } - expectation(expectation && e) + expectation(BOOST_RV_REF(expectation) e) : invocation_ ( e.invocation_) , matcher_(e.matcher_) , file_(e.file_) , line_(e.line_) -#if defined(MOCK_THREAD_SAFE) +#if defined(MOCK_ASYNC) , blocked(false) #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() { for( sequences_cit it = sequences_.begin(); @@ -202,12 +213,12 @@ namespace detail } #endif #endif -#if defined(MOCK_THREAD_SAFE) +#if defined(MOCK_ASYNC) template < typename duration> expectation &async(const duration timeout) { timeout_ = timeout; - blocked.store(false,std::memory_order_release); + blocked.store(false,boost::memory_order_release); return *this; } #endif @@ -221,7 +232,7 @@ namespace detail { return invocation_->verify(); } -#if defined(MOCK_THREAD_SAFE) +#if defined(MOCK_ASYNC) bool verify(const boost::shared_ptr< condition_variable> &cv, lock &lk) const { if (timeout_) @@ -230,7 +241,7 @@ namespace detail { 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; } } @@ -241,8 +252,8 @@ namespace detail bool is_valid( BOOST_PP_ENUM_BINARY_PARAMS(MOCK_NUM_ARGS, T, a) ) const { -#if defined(MOCK_THREAD_SAFE) - return !blocked.load(std::memory_order_acquire) && !invocation_->exhausted() +#if defined(MOCK_ASYNC) + return !blocked.load(boost::memory_order_acquire) && !invocation_->exhausted() && (*matcher_)( BOOST_PP_ENUM_PARAMS(MOCK_NUM_ARGS, a) ); #else return !invocation_->exhausted() @@ -252,8 +263,8 @@ namespace detail bool invoke() const { -#if defined(MOCK_THREAD_SAFE) - if (blocked.load(std::memory_order_acquire)) +#if defined(MOCK_ASYNC) + if (blocked.load(boost::memory_order_acquire)) return false; #endif for( sequences_cit it = sequences_.begin(); @@ -302,9 +313,9 @@ namespace detail sequences_type sequences_; const char* file_; int line_; -#if defined(MOCK_THREAD_SAFE) +#if defined(MOCK_ASYNC) boost::optional timeout_; - mutable std::atomic blocked; + mutable boost::atomic blocked; #endif }; } diff --git a/include/turtle/detail/function.hpp b/include/turtle/detail/function.hpp index f29aa65..19a016c 100644 --- a/include/turtle/detail/function.hpp +++ b/include/turtle/detail/function.hpp @@ -49,7 +49,7 @@ namespace detail : e_( &e ) {} - wrapper_base( wrapper_base && w ) + wrapper_base( BOOST_RV_REF(wrapper_base) w ) : e_( w.e_ ) {} @@ -68,7 +68,7 @@ namespace detail : e_( &e ) {} - wrapper_base( wrapper_base && w ) + wrapper_base( BOOST_RV_REF(wrapper_base) w ) : e_( w.e_ ) {} @@ -82,7 +82,7 @@ namespace detail : e_( &e ) {} - wrapper_base( wrapper_base && w ) + wrapper_base( BOOST_RV_REF(wrapper_base) w ) : e_( w.e_ ) {} diff --git a/include/turtle/detail/function_impl_template.hpp b/include/turtle/detail/function_impl_template.hpp index 116b4e1..a8fa1e2 100644 --- a/include/turtle/detail/function_impl_template.hpp +++ b/include/turtle/detail/function_impl_template.hpp @@ -8,7 +8,8 @@ #include "expectation_template.hpp" #include -#include +#include +#include #ifndef MOCK_ERROR_POLICY # error no error policy has been set @@ -46,7 +47,7 @@ namespace detail : context_( 0 ) , valid_( true ) , mutex_( boost::make_shared< mutex >() ) -#if defined(MOCK_THREAD_SAFE) +#if defined(MOCK_ASYNC) , cv_( boost::make_shared< condition_variable>() ) #endif {} @@ -56,7 +57,7 @@ namespace detail lock _(mutex_); for (expectations_cit it = expectations_.begin(); it != expectations_.end(); ++it) -#if defined(MOCK_THREAD_SAFE) +#if defined(MOCK_ASYNC) if (!it->verify(cv_, _)) #else if (!it->verify()) @@ -67,7 +68,7 @@ namespace detail << lazy_expectations(this), it->file(), it->line()); } - context *c = context_.load(std::memory_order_acquire); + context *c = context_.load(boost::memory_order_acquire); if (c) c->remove( *this ); } @@ -77,7 +78,7 @@ namespace detail lock _( mutex_ ); for( expectations_cit it = expectations_.begin(); it != expectations_.end(); ++it ) -#if defined(MOCK_THREAD_SAFE) +#if defined(MOCK_ASYNC) if( ! it->verify(cv_,_) ) #else if( ! it->verify() ) @@ -121,7 +122,7 @@ namespace detail wrapper( BOOST_RV_REF(wrapper) w) : 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_ADD -#if defined(MOCK_THREAD_SAFE) +#if defined(MOCK_ASYNC) wrapper &async(const nanoseconds &timeout) { this->e_->async(timeout); @@ -245,7 +246,7 @@ namespace detail BOOST_PP_ENUM_BINARY_PARAMS(MOCK_NUM_ARGS, T, t) ) const { lock _( mutex_ ); -#if defined(MOCK_THREAD_SAFE) +#if defined(MOCK_ASYNC) struct notify_cv_on_exit { notify_cv_on_exit(condition_variable &cv) @@ -293,7 +294,7 @@ namespace detail boost::optional< type_name > type, 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( p, *this, instance, type, name ); } @@ -314,7 +315,7 @@ namespace detail 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 ) pContext->serialize( s, *c.impl_ ); else @@ -344,10 +345,10 @@ namespace detail typedef typename expectations_type::const_iterator expectations_cit; expectations_type expectations_; - std::atomic context_; + boost::atomic context_; mutable bool valid_; const boost::shared_ptr< mutex > mutex_; -#if defined(MOCK_THREAD_SAFE) +#if defined(MOCK_ASYNC) const boost::shared_ptr cv_; #endif }; diff --git a/include/turtle/detail/mutex.hpp b/include/turtle/detail/mutex.hpp index 29b5fe8..1c4deb6 100644 --- a/include/turtle/detail/mutex.hpp +++ b/include/turtle/detail/mutex.hpp @@ -42,6 +42,7 @@ namespace detail typedef MOCK_THREAD_NAMESPACE::chrono::nanoseconds nanoseconds; typedef MOCK_THREAD_NAMESPACE::unique_lock lock_base; +#if defined(MOCK_ASYNC) struct lock : public lock_base { lock(const boost::shared_ptr< detail::mutex > &m) @@ -49,7 +50,7 @@ namespace detail , m_(m) {} - lock(lock && l) + lock(BOOST_RV_REF(lock) l) : lock_base(*l.m_) , m_(l.m_) { @@ -62,6 +63,31 @@ namespace detail 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 diff --git a/test/test_async.cpp b/test/test_async.cpp index 57f9b65..8e314be 100644 --- a/test/test_async.cpp +++ b/test/test_async.cpp @@ -23,12 +23,14 @@ namespace MOCK_CLASS( mock_class ) { 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 ) { -#if defined(MOCK_THREAD_SAFE) +#if defined(MOCK_ASYNC) const mock_class m{}; MOCK_EXPECT( m.my_tag ).async(MOCK_THREAD_NAMESPACE::chrono::milliseconds(50)).once().with( "some parameter" ); 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 ) { -#if defined(MOCK_THREAD_SAFE) +#if defined(MOCK_ASYNC) + mock::reset(); + mock_error_data.reset(); const mock_class m{}; bool unexpected_call_received = false; MOCK_EXPECT( m.my_tag ).async(MOCK_THREAD_NAMESPACE::chrono::milliseconds(50)).once().with( "some parameter" ); diff --git a/test/test_integration.cpp b/test/test_integration.cpp index 8562da3..71ed0c6 100644 --- a/test/test_integration.cpp +++ b/test/test_integration.cpp @@ -128,7 +128,7 @@ BOOST_FIXTURE_TEST_CASE( mock_object_method_const_disambiguation, mock_error_fix my_const_ambiguited_mock mock; MOCK_EXPECT( mock.tag1 ); 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()" ); } diff --git a/test/test_mock.cpp b/test/test_mock.cpp index 7a41f6f..dbb8658 100644 --- a/test/test_mock.cpp +++ b/test/test_mock.cpp @@ -367,7 +367,7 @@ namespace MOCK_BASE_CLASS( variadic, base ) { - MOCK_METHOD( m1, 0 ) + MOCK_METHOD( m1, 0, void() ) MOCK_METHOD( m2, 0, void() ) MOCK_METHOD( m3, 0, void(), m3 ) MOCK_CONST_METHOD( m4, 0, void() )