diff --git a/src/libraries/turtle/function.hpp b/src/libraries/turtle/function.hpp index 7c32045..de6431f 100644 --- a/src/libraries/turtle/function.hpp +++ b/src/libraries/turtle/function.hpp @@ -127,7 +127,8 @@ namespace mock } virtual ~function_impl() { - parent_->remove( *this ); + if( parent_ ) + parent_->remove( *this ); if( ! std::uncaught_exception() ) for( expectations_cit it = expectations_.begin(); it != expectations_.end(); ++it ) @@ -146,7 +147,8 @@ namespace mock } void set_parent( node& parent ) { - parent_->remove( *this ); + if( parent_ ) + parent_->remove( *this ); parent.add( *this ); parent_ = &parent; } @@ -168,6 +170,10 @@ namespace mock valid_ = true; expectations_.clear(); } + virtual void untie() + { + parent_ = 0; + } expectation_type& expect( const std::string& file, int line ) { @@ -285,7 +291,9 @@ namespace mock void serialize( std::ostream& s, const std::string& parameters ) const { - s << parent_->tag() << name_ << parameters; + if( parent_ ) + s << parent_->tag(); + s << name_ << parameters; for( expectations_cit it = expectations_.begin(); it != expectations_.end(); ++it ) s << std::endl << *it; diff --git a/src/libraries/turtle/node.hpp b/src/libraries/turtle/node.hpp index 1c55ab7..593bfbe 100644 --- a/src/libraries/turtle/node.hpp +++ b/src/libraries/turtle/node.hpp @@ -42,6 +42,8 @@ namespace mock std::for_each( v_.begin(), v_.end(), std::mem_fun( &verifiable::reset ) ); } + virtual void untie() + {} void tag( const std::string& name ) { @@ -54,7 +56,10 @@ namespace mock protected: virtual ~node() - {} + { + std::for_each( v_.begin(), v_.end(), + std::mem_fun( &verifiable::untie ) ); + } private: typedef std::vector< verifiable* > verifiables_type; diff --git a/src/libraries/turtle/verifiable.hpp b/src/libraries/turtle/verifiable.hpp index 7069b5d..2bcdc8d 100644 --- a/src/libraries/turtle/verifiable.hpp +++ b/src/libraries/turtle/verifiable.hpp @@ -19,11 +19,11 @@ namespace mock verifiable() {} virtual ~verifiable() {} - // return false if verification fails virtual bool verify() const = 0; - // return to the initial state virtual void reset() = 0; + + virtual void untie() = 0; }; } diff --git a/src/tests/turtle_test/function_test.cpp b/src/tests/turtle_test/function_test.cpp index f76488b..636d6e1 100644 --- a/src/tests/turtle_test/function_test.cpp +++ b/src/tests/turtle_test/function_test.cpp @@ -53,6 +53,13 @@ namespace }; } +// static + +namespace +{ + boost::function< void() > static_f; +} + // functor BOOST_FIXTURE_TEST_CASE( a_function_can_be_passed_as_functor, error_fixture ) diff --git a/src/tests/turtle_test/object_test.cpp b/src/tests/turtle_test/object_test.cpp index 5acda91..0d4fcc2 100644 --- a/src/tests/turtle_test/object_test.cpp +++ b/src/tests/turtle_test/object_test.cpp @@ -81,3 +81,13 @@ BOOST_AUTO_TEST_CASE( an_object_is_copiable_by_sharing_its_state ) o2.reset(); BOOST_CHECK( ! o1.verify() ); } + +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(); +}