Fixed crash when resetting self-referenced object

git-svn-id: https://svn.code.sf.net/p/turtle/code/trunk@450 860be788-9bd5-4423-9f1e-828f051e677b
This commit is contained in:
mat007 2012-05-08 20:49:15 +00:00
parent 8bbf00599c
commit 6bec05c668
5 changed files with 50 additions and 6 deletions

View file

@ -27,6 +27,7 @@
#include <boost/preprocessor/comparison/equal.hpp> #include <boost/preprocessor/comparison/equal.hpp>
#include <boost/test/utils/basic_cstring/basic_cstring.hpp> #include <boost/test/utils/basic_cstring/basic_cstring.hpp>
#include <boost/test/utils/lazy_ostream.hpp> #include <boost/test/utils/lazy_ostream.hpp>
#include <boost/enable_shared_from_this.hpp>
#include <boost/shared_ptr.hpp> #include <boost/shared_ptr.hpp>
#include <boost/optional.hpp> #include <boost/optional.hpp>
#include <ostream> #include <ostream>
@ -139,7 +140,7 @@ namespace mock
} }
private: private:
class function_impl : public detail::verifiable class function_impl : public detail::verifiable, public boost::enable_shared_from_this< function_impl >
{ {
public: public:
typedef MOCK_ERROR_POLICY< result_type > error_type; typedef MOCK_ERROR_POLICY< result_type > error_type;
@ -191,6 +192,7 @@ namespace mock
virtual void reset() virtual void reset()
{ {
valid_ = true; valid_ = true;
boost::shared_ptr< function_impl > guard = shared_from_this();
expectations_.clear(); expectations_.clear();
} }

View file

@ -42,10 +42,14 @@ namespace detail
valid = false; valid = false;
return valid; return valid;
} }
void reset() const void reset()
{ {
std::for_each( verifiables_.begin(), verifiables_.end(), const verifiables_t verifiables = verifiables_;
std::mem_fun( &verifiable::reset ) ); for( verifiables_cit it = verifiables.begin();
it != verifiables.end(); ++it )
if( std::find( verifiables_.begin(), verifiables_.end(), *it )
!= verifiables_.end() )
(*it)->reset();
} }
private: private:

View file

@ -15,6 +15,7 @@
#include "parent.hpp" #include "parent.hpp"
#include "child.hpp" #include "child.hpp"
#include "type_name.hpp" #include "type_name.hpp"
#include <boost/enable_shared_from_this.hpp>
#include <boost/type_traits/is_base_of.hpp> #include <boost/type_traits/is_base_of.hpp>
#include <boost/utility/enable_if.hpp> #include <boost/utility/enable_if.hpp>
#include <boost/shared_ptr.hpp> #include <boost/shared_ptr.hpp>
@ -33,7 +34,7 @@ namespace mock
{} {}
private: private:
class object_impl : public detail::context, private detail::verifiable class object_impl : public detail::context, public detail::verifiable, public boost::enable_shared_from_this< object_impl >
{ {
public: public:
virtual void add( const void* /*p*/, detail::verifiable& v, virtual void add( const void* /*p*/, detail::verifiable& v,
@ -73,6 +74,7 @@ namespace mock
} }
virtual void reset() virtual void reset()
{ {
boost::shared_ptr< object_impl > guard = shared_from_this();
group_.reset(); group_.reset();
} }

View file

@ -54,7 +54,7 @@ namespace detail
{ {
return group_.verify(); return group_.verify();
} }
void reset() const void reset()
{ {
group_.reset(); group_.reset();
} }

View file

@ -535,3 +535,39 @@ BOOST_AUTO_TEST_CASE( a_static_method_in_a_template_class_can_be_mocked )
BOOST_CHECK( MOCK_VERIFY( some_template_class< int >::some_static_method ) ); BOOST_CHECK( MOCK_VERIFY( some_template_class< int >::some_static_method ) );
MOCK_RESET( some_template_class< int >::some_static_method ); MOCK_RESET( some_template_class< int >::some_static_method );
} }
namespace
{
MOCK_CLASS( mock_class )
{
MOCK_METHOD_EXT( m, 0, void(), m );
};
}
BOOST_AUTO_TEST_CASE( resetting_referenced_mock_class_does_not_crash )
{
MOCK_FUNCTOR( f, mock_class() );
{
mock_class c;
MOCK_EXPECT( f ).returns( c );
MOCK_EXPECT( c.m );
}
mock::reset();
}
namespace
{
MOCK_CLASS( mock_class2 )
{
MOCK_METHOD_EXT( m, 0, mock_class2(), m );
};
}
BOOST_AUTO_TEST_CASE( resetting_self_referenced_mock_class_does_not_crash )
{
{
mock_class2 c;
MOCK_EXPECT( c.m ).returns( c );
}
mock::reset();
}