Prevented a crash when mocking a destructor and throwing out of the object scope

git-svn-id: https://svn.code.sf.net/p/turtle/code/trunk@121 860be788-9bd5-4423-9f1e-828f051e677b
This commit is contained in:
mat007 2010-02-15 22:59:23 +00:00
parent 456869d82b
commit 0e8079d47a
8 changed files with 174 additions and 113 deletions

View file

@ -36,7 +36,7 @@ namespace
}
void reset()
{
missing_result_specification_count = 0;
missing_action_count = 0;
no_match_count = 0;
sequence_failed_count = 0;
verification_failed_count = 0;
@ -44,7 +44,7 @@ namespace
}
bool verify() const
{
return missing_result_specification_count == 0 &&
return missing_action_count == 0 &&
no_match_count == 0 &&
sequence_failed_count == 0 &&
verification_failed_count == 0 &&
@ -331,22 +331,22 @@ BOOST_FIXTURE_TEST_CASE( literal_zero_can_be_used_in_place_of_null_pointers_in_c
// result handling
BOOST_FIXTURE_TEST_CASE( triggering_an_expectation_with_no_return_set_calls_missing_result_specification, error_fixture )
BOOST_FIXTURE_TEST_CASE( triggering_an_expectation_with_no_return_set_calls_missing_action, error_fixture )
{
{
mock::expectation< int() > e;
e.expect();
CHECK_ERROR( e(), missing_result_specification );
CHECK_ERROR( e(), missing_action );
}
{
mock::expectation< int&() > e;
e.expect();
CHECK_ERROR( e(), missing_result_specification );
CHECK_ERROR( e(), missing_action );
}
{
mock::expectation< const std::string&() > e;
e.expect();
CHECK_ERROR( e(), missing_result_specification );
CHECK_ERROR( e(), missing_action );
}
}

View file

@ -259,3 +259,41 @@ BOOST_FIXTURE_TEST_CASE( basic_mock_object_collaboration_usage, fixture )
MOCK_EXPECT( observer, notify ).once().with( 3 );
subject.increment();
}
namespace
{
MOCK_CLASS( my_destroyed_class )
{
MOCK_DESTRUCTOR( my_destroyed_class, destructor )
};
}
BOOST_AUTO_TEST_CASE( mocking_a_destructor )
{
my_destroyed_class c;
MOCK_EXPECT( c, destructor ).once();
}
BOOST_AUTO_TEST_CASE( failed_expectation_in_mocked_destructor_does_not_throw )
{
try
{
my_destroyed_class c;
throw std::runtime_error( "should not crash" );
}
catch( std::runtime_error& )
{
}
}
BOOST_AUTO_TEST_CASE( failed_sequence_in_mocked_destructor_does_not_throw )
{
mock::sequence s;
my_custom_mock m;
{
my_destroyed_class c;
MOCK_EXPECT( c, destructor ).once().in( s );
MOCK_EXPECT( m, my_method ).once().in( s );
m.my_method();
}
}

View file

@ -14,7 +14,7 @@
namespace
{
int missing_result_specification_count = 0;
int missing_action_count = 0;
int no_match_count = 0;
int sequence_failed_count = 0;
int verification_failed_count = 0;
@ -25,27 +25,33 @@ namespace mock
template< typename Result >
struct mock_error
{
static Result missing_result_specification( const std::string& /*context*/, const std::string& /*file*/, int /*line*/ )
static Result abort()
{
++missing_result_specification_count;
static BOOST_DEDUCED_TYPENAME boost::remove_reference< Result >::type r;
return r;
}
static Result no_match( const std::string& /*context*/ )
static void missing_action( const std::string& /*context*/,
const std::string& /*file*/, int /*line*/ )
{
++missing_action_count;
}
static void no_match( const std::string& /*context*/ )
{
++no_match_count;
static BOOST_DEDUCED_TYPENAME boost::remove_reference< Result >::type r;
return r;
}
static void sequence_failed( const std::string& /*context*/, const std::string& /*file*/, int /*line*/ )
static void sequence_failed( const std::string& /*context*/,
const std::string& /*file*/, int /*line*/ )
{
++sequence_failed_count;
}
static void verification_failed( const std::string& /*context*/, const std::string& /*file*/, int /*line*/ )
static void verification_failed( const std::string& /*context*/,
const std::string& /*file*/, int /*line*/ )
{
++verification_failed_count;
}
static void untriggered_expectation( const std::string& /*context*/, const std::string& /*file*/, int /*line*/ )
static void untriggered_expectation( const std::string& /*context*/,
const std::string& /*file*/, int /*line*/ )
{
++untriggered_expectation_count;
}
@ -53,23 +59,29 @@ namespace mock
template<>
struct mock_error< void >
{
static void missing_result_specification( const std::string& /*context*/, const std::string& /*file*/, int /*line*/ )
static void abort()
{}
static void missing_action( const std::string& /*context*/,
const std::string& /*file*/, int /*line*/ )
{
++missing_result_specification_count;
++missing_action_count;
}
static void no_match( const std::string& /*context*/ )
{
++no_match_count;
}
static void sequence_failed( const std::string& /*context*/, const std::string& /*file*/, int /*line*/ )
static void sequence_failed( const std::string& /*context*/,
const std::string& /*file*/, int /*line*/ )
{
++sequence_failed_count;
}
static void verification_failed( const std::string& /*context*/, const std::string& /*file*/, int /*line*/ )
static void verification_failed( const std::string& /*context*/,
const std::string& /*file*/, int /*line*/ )
{
++verification_failed_count;
}
static void untriggered_expectation( const std::string& /*context*/, const std::string& /*file*/, int /*line*/ )
static void untriggered_expectation( const std::string& /*context*/,
const std::string& /*file*/, int /*line*/ )
{
++untriggered_expectation_count;
}

View file

@ -6,6 +6,7 @@
// http://www.boost.org/LICENSE_1_0.txt)
//
#define MOCK_USE_BOOST_TEST
#include <turtle/mock.hpp>
#include <boost/mpl/assert.hpp>
@ -204,20 +205,6 @@ BOOST_AUTO_TEST_CASE( mock_functor_is_named )
BOOST_CHECK_EQUAL( "f", to_string( MOCK_MOCKER( f, _ ) ) );
}
namespace
{
MOCK_CLASS( my_destroyed_class )
{
MOCK_DESTRUCTOR( my_destroyed_class, destructor )
};
}
BOOST_AUTO_TEST_CASE( mocking_a_destructor )
{
my_destroyed_class c;
MOCK_EXPECT( c, destructor ).once();
}
BOOST_MPL_ASSERT(( boost::is_same< float, mock::detail::arg< void( float ), 1, 1 >::type > ));
BOOST_MPL_ASSERT(( boost::is_same< float, mock::detail::arg< void( float, int ), 1, 2 >::type > ));
BOOST_MPL_ASSERT(( boost::is_same< int, mock::detail::arg< void( float, int ), 2, 2 >::type > ));

View file

@ -25,20 +25,18 @@ namespace mock
return s.str();
}
static Result no_match( const std::string& context )
static Result abort()
{
throw std::runtime_error( "no_match : " + context );
}
static Result missing_result_specification( const std::string& context,
const std::string& file, int line )
{
throw std::runtime_error( "missing_result_specification : " + context + " " + file + "(" + to_string( line ) + ")" );
}
static void sequence_failed( const std::string& context,
const std::string& file, int line )
{
throw std::runtime_error( "sequence_failed : " + context + " " + file + "(" + to_string( line ) + ")" );
throw std::runtime_error( "abort" );
}
static void no_match( const std::string& /*context*/ )
{}
static void missing_action( const std::string& /*context*/,
const std::string& /*file*/, int /*line*/ )
{}
static void sequence_failed( const std::string& /*context*/,
const std::string& /*file*/, int /*line*/ )
{}
static void verification_failed( const std::string& /*context*/,
const std::string& /*file*/, int /*line*/ )
{}