diff --git a/build/vc80/turtle.vcproj b/build/vc80/turtle.vcproj index 25b6967..12d874f 100644 --- a/build/vc80/turtle.vcproj +++ b/build/vc80/turtle.vcproj @@ -228,10 +228,6 @@ RelativePath="..\..\src\libraries\turtle\sequence.hpp" > - - diff --git a/src/libraries/turtle/expectation.hpp b/src/libraries/turtle/expectation.hpp index 398f743..6d6f312 100644 --- a/src/libraries/turtle/expectation.hpp +++ b/src/libraries/turtle/expectation.hpp @@ -29,7 +29,7 @@ namespace mock { namespace detail { - class expectation_base : private sequenceable + class expectation_base { public: expectation_base() @@ -41,7 +41,7 @@ namespace detail { for( sequences_cit it = sequences_.begin(); it != sequences_.end(); ++it ) - (*it)->remove( *this ); + (*it)->remove( this ); } void set_location( const std::string& file, int line ) @@ -59,12 +59,12 @@ namespace detail { for( sequences_cit it = sequences_.begin(); it != sequences_.end(); ++it ) - if( ! (*it)->is_valid( *this ) ) + if( ! (*it)->is_valid( this ) ) return false; bool result = i_->invoke(); for( sequences_cit it = sequences_.begin(); it != sequences_.end(); ++it ) - (*it)->call( *this ); + (*it)->invalidate( this ); return result; } @@ -85,20 +85,14 @@ namespace detail i_.reset( i ); } - void add( sequence& s ) + void add( boost::shared_ptr< detail::sequence_impl > s ) { - s.add( *this ); - sequences_.push_back( &s ); + s->add( this ); + sequences_.push_back( s ); } private: - virtual void remove( sequence& s ) - { - sequences_.erase( std::remove( sequences_.begin(), - sequences_.end(), &s ), sequences_.end() ); - } - - typedef std::vector< sequence* > sequences_type; + typedef std::vector< boost::shared_ptr< detail::sequence_impl > > sequences_type; typedef sequences_type::const_iterator sequences_cit; sequences_type sequences_; @@ -114,7 +108,7 @@ namespace detail #define MOCK_EXPECTATION_METHODS \ expectation& in( sequence& s ) \ { \ - add( s ); \ + add( s.impl_ ); \ return *this; \ } \ expectation& once() \ diff --git a/src/libraries/turtle/sequence.hpp b/src/libraries/turtle/sequence.hpp index 1dae7d2..00c291f 100644 --- a/src/libraries/turtle/sequence.hpp +++ b/src/libraries/turtle/sequence.hpp @@ -9,61 +9,58 @@ #ifndef MOCK_SEQUENCE_HPP_INCLUDED #define MOCK_SEQUENCE_HPP_INCLUDED -#include "sequenceable.hpp" #include +#include #include #include namespace mock { - class sequence : private boost::noncopyable +namespace detail +{ + class sequence_impl : private boost::noncopyable { public: - ~sequence() + void add( void* e ) { - for( orderables_it it = orderables_.begin(); - it != orderables_.end(); ++it ) - (*it)->remove( *this ); - for( orderables_it it = called_.begin(); - it != called_.end(); ++it ) - (*it)->remove( *this ); + elements_.push_back( e ); + } + void remove( void* e ) + { + elements_.erase( std::remove( elements_.begin(), + elements_.end(), e ), elements_.end() ); } - void add( detail::sequenceable& o ) + bool is_valid( const void* e ) const { - orderables_.push_back( &o ); - } - void remove( detail::sequenceable& o ) - { - orderables_.erase( std::remove( orderables_.begin(), - orderables_.end(), &o ), orderables_.end() ); - called_.erase( std::remove( called_.begin(), - called_.end(), &o ), called_.end() ); + return std::find( elements_.begin(), elements_.end(), e ) + != elements_.end(); } - bool is_valid( const detail::sequenceable& o ) const + void invalidate( const void* e ) { - return std::find( called_.begin(), called_.end(), &o ) - == called_.end(); - } - - void call( const detail::sequenceable& o ) - { - orderables_it it = - std::find( orderables_.begin(), orderables_.end(), &o ); - if( it != orderables_.end() ) - { - std::copy( orderables_.begin(), it, - std::back_inserter( called_ ) ); - orderables_.erase( orderables_.begin(), it ); - } + elements_it it = + std::find( elements_.begin(), elements_.end(), e ); + if( it != elements_.end() ) + elements_.erase( elements_.begin(), it ); } private: - typedef std::vector< detail::sequenceable* > orderables_type; - typedef orderables_type::iterator orderables_it; + typedef std::vector< void* > elements_type; + typedef elements_type::iterator elements_it; - orderables_type orderables_, called_; + elements_type elements_; + }; +} + + class sequence + { + public: + sequence() + : impl_( new detail::sequence_impl() ) + {} + + boost::shared_ptr< detail::sequence_impl > impl_; }; } diff --git a/src/libraries/turtle/sequenceable.hpp b/src/libraries/turtle/sequenceable.hpp deleted file mode 100644 index 694ce94..0000000 --- a/src/libraries/turtle/sequenceable.hpp +++ /dev/null @@ -1,30 +0,0 @@ -// -// Copyright Mathieu Champlon 2009 -// -// 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_SEQUENCEABLE_HPP_INCLUDED -#define MOCK_SEQUENCEABLE_HPP_INCLUDED - -namespace mock -{ - class sequence; - -namespace detail -{ - class sequenceable - { - public: - sequenceable() {} - virtual ~sequenceable() {} - - virtual void remove( sequence& s ) = 0; - }; -} - -} - -#endif // #ifndef MOCK_SEQUENCEABLE_HPP_INCLUDED diff --git a/src/tests/turtle_test/sequence_test.cpp b/src/tests/turtle_test/sequence_test.cpp index b3b49ab..65eb4cc 100644 --- a/src/tests/turtle_test/sequence_test.cpp +++ b/src/tests/turtle_test/sequence_test.cpp @@ -70,7 +70,7 @@ BOOST_AUTO_TEST_CASE( registering_to_a_sequence_enforces_call_order_verification BOOST_CHECK_THROW( e1(), std::exception ); } -BOOST_AUTO_TEST_CASE( destroying_a_sequence_removes_order_call_enforcement ) +BOOST_AUTO_TEST_CASE( destroying_a_sequence_does_not_remove_order_call_enforcement ) { mock::function< void() > e1, e2; { @@ -79,9 +79,7 @@ BOOST_AUTO_TEST_CASE( destroying_a_sequence_removes_order_call_enforcement ) e2.expect().once().in( s ); } BOOST_CHECK_NO_THROW( e2() ); - BOOST_CHECK_NO_THROW( e1() ); - BOOST_CHECK( e1.verify() ); - BOOST_CHECK( e2.verify() ); + BOOST_CHECK_THROW( e1(), std::exception ); } BOOST_AUTO_TEST_CASE( resetting_an_expectation_removes_it_from_order_call_enforcement )