Destroying a sequence does not remove order call enforcement anymore

git-svn-id: https://svn.code.sf.net/p/turtle/code/trunk@159 860be788-9bd5-4423-9f1e-828f051e677b
This commit is contained in:
mat007 2010-06-15 18:06:10 +00:00
parent df46dec9e0
commit 0d4db2424b
5 changed files with 44 additions and 89 deletions

View file

@ -228,10 +228,6 @@
RelativePath="..\..\src\libraries\turtle\sequence.hpp" RelativePath="..\..\src\libraries\turtle\sequence.hpp"
> >
</File> </File>
<File
RelativePath="..\..\src\libraries\turtle\sequenceable.hpp"
>
</File>
<File <File
RelativePath="..\..\src\libraries\turtle\type_name.hpp" RelativePath="..\..\src\libraries\turtle\type_name.hpp"
> >

View file

@ -29,7 +29,7 @@ namespace mock
{ {
namespace detail namespace detail
{ {
class expectation_base : private sequenceable class expectation_base
{ {
public: public:
expectation_base() expectation_base()
@ -41,7 +41,7 @@ namespace detail
{ {
for( sequences_cit it = sequences_.begin(); for( sequences_cit it = sequences_.begin();
it != sequences_.end(); ++it ) it != sequences_.end(); ++it )
(*it)->remove( *this ); (*it)->remove( this );
} }
void set_location( const std::string& file, int line ) void set_location( const std::string& file, int line )
@ -59,12 +59,12 @@ namespace detail
{ {
for( sequences_cit it = sequences_.begin(); for( sequences_cit it = sequences_.begin();
it != sequences_.end(); ++it ) it != sequences_.end(); ++it )
if( ! (*it)->is_valid( *this ) ) if( ! (*it)->is_valid( this ) )
return false; return false;
bool result = i_->invoke(); bool result = i_->invoke();
for( sequences_cit it = sequences_.begin(); for( sequences_cit it = sequences_.begin();
it != sequences_.end(); ++it ) it != sequences_.end(); ++it )
(*it)->call( *this ); (*it)->invalidate( this );
return result; return result;
} }
@ -85,20 +85,14 @@ namespace detail
i_.reset( i ); i_.reset( i );
} }
void add( sequence& s ) void add( boost::shared_ptr< detail::sequence_impl > s )
{ {
s.add( *this ); s->add( this );
sequences_.push_back( &s ); sequences_.push_back( s );
} }
private: private:
virtual void remove( sequence& s ) typedef std::vector< boost::shared_ptr< detail::sequence_impl > > sequences_type;
{
sequences_.erase( std::remove( sequences_.begin(),
sequences_.end(), &s ), sequences_.end() );
}
typedef std::vector< sequence* > sequences_type;
typedef sequences_type::const_iterator sequences_cit; typedef sequences_type::const_iterator sequences_cit;
sequences_type sequences_; sequences_type sequences_;
@ -114,7 +108,7 @@ namespace detail
#define MOCK_EXPECTATION_METHODS \ #define MOCK_EXPECTATION_METHODS \
expectation& in( sequence& s ) \ expectation& in( sequence& s ) \
{ \ { \
add( s ); \ add( s.impl_ ); \
return *this; \ return *this; \
} \ } \
expectation& once() \ expectation& once() \

View file

@ -9,61 +9,58 @@
#ifndef MOCK_SEQUENCE_HPP_INCLUDED #ifndef MOCK_SEQUENCE_HPP_INCLUDED
#define MOCK_SEQUENCE_HPP_INCLUDED #define MOCK_SEQUENCE_HPP_INCLUDED
#include "sequenceable.hpp"
#include <boost/noncopyable.hpp> #include <boost/noncopyable.hpp>
#include <boost/shared_ptr.hpp>
#include <algorithm> #include <algorithm>
#include <vector> #include <vector>
namespace mock namespace mock
{ {
class sequence : private boost::noncopyable namespace detail
{
class sequence_impl : private boost::noncopyable
{ {
public: public:
~sequence() void add( void* e )
{ {
for( orderables_it it = orderables_.begin(); elements_.push_back( e );
it != orderables_.end(); ++it ) }
(*it)->remove( *this ); void remove( void* e )
for( orderables_it it = called_.begin(); {
it != called_.end(); ++it ) elements_.erase( std::remove( elements_.begin(),
(*it)->remove( *this ); elements_.end(), e ), elements_.end() );
} }
void add( detail::sequenceable& o ) bool is_valid( const void* e ) const
{ {
orderables_.push_back( &o ); return std::find( elements_.begin(), elements_.end(), e )
} != elements_.end();
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() );
} }
bool is_valid( const detail::sequenceable& o ) const void invalidate( const void* e )
{ {
return std::find( called_.begin(), called_.end(), &o ) elements_it it =
== called_.end(); std::find( elements_.begin(), elements_.end(), e );
} if( it != elements_.end() )
elements_.erase( elements_.begin(), it );
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 );
}
} }
private: private:
typedef std::vector< detail::sequenceable* > orderables_type; typedef std::vector< void* > elements_type;
typedef orderables_type::iterator orderables_it; 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_;
}; };
} }

View file

@ -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

View file

@ -70,7 +70,7 @@ BOOST_AUTO_TEST_CASE( registering_to_a_sequence_enforces_call_order_verification
BOOST_CHECK_THROW( e1(), std::exception ); 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; 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 ); e2.expect().once().in( s );
} }
BOOST_CHECK_NO_THROW( e2() ); BOOST_CHECK_NO_THROW( e2() );
BOOST_CHECK_NO_THROW( e1() ); BOOST_CHECK_THROW( e1(), std::exception );
BOOST_CHECK( e1.verify() );
BOOST_CHECK( e2.verify() );
} }
BOOST_AUTO_TEST_CASE( resetting_an_expectation_removes_it_from_order_call_enforcement ) BOOST_AUTO_TEST_CASE( resetting_an_expectation_removes_it_from_order_call_enforcement )