diff --git a/build/vc80/turtle_test.vcproj b/build/vc80/turtle_test.vcproj index 6816e39..aa647a5 100644 --- a/build/vc80/turtle_test.vcproj +++ b/build/vc80/turtle_test.vcproj @@ -216,6 +216,10 @@ RelativePath="..\..\src\tests\turtle_test\is_functor_test.cpp" > + + @@ -228,6 +232,10 @@ RelativePath="..\..\src\tests\turtle_test\sequence_test.cpp" > + + diff --git a/src/libraries/turtle/config.hpp b/src/libraries/turtle/config.hpp index 28e7f7f..6d23dc8 100644 --- a/src/libraries/turtle/config.hpp +++ b/src/libraries/turtle/config.hpp @@ -23,4 +23,12 @@ BOOST_PP_ASSERT( BOOST_PP_LESS_EQUAL(MOCK_MAX_ARGS, BOOST_FUNCTION_MAX_ARGS) ) # define MOCK_USE_BOOST_TEST #endif +#ifndef MOCK_ERROR_POLICY +# ifdef MOCK_USE_BOOST_TEST +# define MOCK_ERROR_POLICY boost_test_error_policy +# else +# define MOCK_ERROR_POLICY basic_error_policy +# endif +#endif + #endif // #ifndef MOCK_CONFIG_HPP_INCLUDED diff --git a/src/libraries/turtle/error.hpp b/src/libraries/turtle/error.hpp index 37bcbf6..2da4b1f 100644 --- a/src/libraries/turtle/error.hpp +++ b/src/libraries/turtle/error.hpp @@ -9,54 +9,43 @@ #ifndef MOCK_ERROR_HPP_INCLUDED #define MOCK_ERROR_HPP_INCLUDED +#include "config.hpp" +#include #include +#include #include -#include #include +#include namespace mock { -namespace detail -{ - class errors_t : public boost::unit_test::singleton< errors_t > - { - private: - friend class boost::unit_test::singleton< errors_t >; - }; - BOOST_TEST_SINGLETON_INST( errors ) -} - - class exception : public boost::execution_exception - { - public: - explicit exception( const std::string& s ) - : boost::execution_exception( boost::execution_exception::user_error, s ) - {} - }; - template< typename Result > struct boost_test_error_policy { - static void missing_result_specification() + static Result missing_result_specification( const std::string& context, + const std::string& file, int line ) { - static std::string m; - m = "mock error : missing result specification"; - throw boost::enable_current_exception( mock::exception( m ) ); + notify( "mock error : missing result specification : " + context, + file, line ); + throw boost::enable_current_exception( + boost::execution_aborted() ); } static Result no_match( const std::string& context ) { - static std::string m; - m = "mock error : unexpected call : " + context; - throw boost::enable_current_exception( mock::exception( m ) ); + notify( "mock error : unexpected call : " + context, + "unknown location", 0 ); + throw boost::enable_current_exception( + boost::execution_aborted() ); } static void sequence_failed( const std::string& context, const std::string& /*file*/, int /*line*/ ) { - static std::string m; - m = "mock error : sequence failed : " + context; - throw boost::enable_current_exception( mock::exception( m ) ); + notify( "mock error : sequence failed : " + context, + "unknown location", 0 ); + throw boost::enable_current_exception( + boost::execution_aborted() ); } static void verification_failed( const std::string& context, @@ -74,13 +63,58 @@ namespace detail static void notify( const std::string& message, const std::string& file, int line ) { - boost::test_tools::tt_detail::check_impl( - false, - boost::unit_test::lazy_ostream::instance() << message, - file, (std::size_t)line, - boost::test_tools::tt_detail::CHECK, - boost::test_tools::tt_detail::CHECK_MSG, - 0 ); + boost::unit_test::unit_test_log + << boost::unit_test::log::begin( file, (std::size_t)line ) + << boost::unit_test::log_all_errors + << boost::unit_test::lazy_ostream::instance() << message + << boost::unit_test::log::end(); + } + }; + + struct exception + {}; + + template< typename Result > + struct basic_error_policy + { + static void log( const std::string& message, + const std::string& context, + const std::string& file = "unknown location", int line = 0 ) + { + std::cerr << file << '(' << line << "): " + << "mock error: " << message << ": " << context << std::endl; + } + + static Result missing_result_specification( const std::string& context, + const std::string& file, int line ) + { + log( "missing result specification", context, file, line ); + throw exception(); + } + + static Result no_match( const std::string& context ) + { + log( "unexpected call", context ); + throw exception(); + } + + static void sequence_failed( const std::string& context, + const std::string& /*file*/, int /*line*/ ) + { + log( "sequence failed", context ); + throw exception(); + } + + static void verification_failed( const std::string& context, + const std::string& file, int line ) + { + log( "verification failed", context, file, line ); + } + + static void untriggered_expectation( const std::string& context, + const std::string& file, int line ) + { + log( "untriggered expectation", context, file, line ); } }; } diff --git a/src/libraries/turtle/expectation.hpp b/src/libraries/turtle/expectation.hpp index 34f1be2..944572b 100644 --- a/src/libraries/turtle/expectation.hpp +++ b/src/libraries/turtle/expectation.hpp @@ -29,9 +29,9 @@ namespace mock { template< typename Signature, - typename ErrorPolicy = boost_test_error_policy< + typename ErrorPolicy = MOCK_ERROR_POLICY< BOOST_DEDUCED_TYPENAME boost::function< - Signature >::result_type > > // $$$$ MAT : concept check Signature is actually a signature + Signature >::result_type > > class expectation { public: @@ -47,7 +47,6 @@ namespace mock private: typedef detail::matcher< result_type, Signature, - ErrorPolicy, boost::function< Signature >::arity > matcher_type; @@ -185,12 +184,15 @@ namespace mock it != matchers_.end(); ++it ) if( it->is_valid() ) { - if( !it->invoke() ) + if( ! it->invoke() ) { valid_ = false; ErrorPolicy::sequence_failed( context( "" ), it->file(), it->line() ); } + if( ! it->functor() ) + return ErrorPolicy::missing_result_specification( + context( "" ), it->file(), it->line() ); return it->functor()(); } valid_ = false; @@ -208,11 +210,14 @@ namespace mock for( matchers_cit it = matchers_.begin(); it != matchers_.end(); ++it ) \ if( it->is_valid( BOOST_PP_REPEAT_FROM_TO(0, n, MOCK_EXPECTATION_PARAMETER, BOOST_PP_EMPTY) ) ) \ { \ - if( !it->invoke() ) \ + if( ! it->invoke() ) \ { \ valid_ = false; \ ErrorPolicy::sequence_failed( context( MOCK_EXPECTATION_PARAMETERS(n) ), it->file(), it->line() ); \ } \ + if( ! it->functor() ) \ + return ErrorPolicy::missing_result_specification( \ + context( MOCK_EXPECTATION_PARAMETERS(n) ), it->file(), it->line() ); \ return it->functor()( BOOST_PP_REPEAT_FROM_TO(0, n, MOCK_EXPECTATION_PARAMETER, BOOST_PP_EMPTY) ); \ } \ valid_ = false; \ diff --git a/src/libraries/turtle/matcher.hpp b/src/libraries/turtle/matcher.hpp index 3688685..8af5470 100644 --- a/src/libraries/turtle/matcher.hpp +++ b/src/libraries/turtle/matcher.hpp @@ -104,7 +104,7 @@ namespace detail int line_; }; - template< typename Result, typename Signature, typename ErrorPolicy, int > + template< typename Result, typename Signature, int > class matcher { }; @@ -146,9 +146,9 @@ namespace detail return *this; \ } - template< typename Result, typename Signature, typename ErrorPolicy > - class matcher< Result, Signature, ErrorPolicy, 0 > - : public matcher_base, public result< Result, Signature, ErrorPolicy > + template< typename Result, typename Signature > + class matcher< Result, Signature, 0 > + : public matcher_base, public result< Result, Signature > { public: bool is_valid() const @@ -176,9 +176,9 @@ namespace detail #define MOCK_MATCHER_IS_VALID(z, n, d) && c##n##_( a##n ) #define MOCK_MATCHER_SERIALIZE(z, n, d) << ", " << m.c##n##_ #define MOCK_MATCHER(z, n, d) \ - template< typename Result, typename Signature, typename ErrorPolicy > \ - class matcher< Result, Signature, ErrorPolicy, n > \ - : public matcher_base, public result< Result, Signature, ErrorPolicy > \ + template< typename Result, typename Signature > \ + class matcher< Result, Signature, n > \ + : public matcher_base, public result< Result, Signature > \ { \ BOOST_PP_REPEAT_FROM_TO(0, n, MOCK_MATCHER_TYPEDEF, BOOST_PP_EMPTY) \ public: \ diff --git a/src/libraries/turtle/result.hpp b/src/libraries/turtle/result.hpp index 013bc14..dd0da84 100644 --- a/src/libraries/turtle/result.hpp +++ b/src/libraries/turtle/result.hpp @@ -18,7 +18,7 @@ namespace mock { namespace detail { - template< typename T, typename Signature, typename ErrorPolicy > + template< typename T, typename Signature > class result { typedef BOOST_DEDUCED_TYPENAME @@ -46,8 +46,6 @@ namespace detail const functor_type& functor() const { - if( !f_ ) - ErrorPolicy::missing_result_specification(); return f_; } @@ -76,8 +74,8 @@ namespace detail functor_type f_; }; - template< typename T, typename Signature, typename ErrorPolicy > - class result< T*, Signature, ErrorPolicy > + template< typename T, typename Signature > + class result< T*, Signature > { typedef BOOST_DEDUCED_TYPENAME boost::function< Signature > functor_type; @@ -108,8 +106,6 @@ namespace detail const functor_type& functor() const { - if( !f_ ) - ErrorPolicy::missing_result_specification(); return f_; } @@ -128,8 +124,8 @@ namespace detail functor_type f_; }; - template< typename Signature, typename ErrorPolicy > - class result< void, Signature, ErrorPolicy > + template< typename Signature > + class result< void, Signature > { typedef BOOST_DEDUCED_TYPENAME boost::function< Signature > functor_type; @@ -170,8 +166,8 @@ namespace detail functor_type f_; }; - template< typename T, typename Signature, typename ErrorPolicy > - class result< std::auto_ptr< T >, Signature, ErrorPolicy > + template< typename T, typename Signature > + class result< std::auto_ptr< T >, Signature > { typedef BOOST_DEDUCED_TYPENAME boost::function< Signature > functor_type; @@ -208,8 +204,6 @@ namespace detail const functor_type& functor() const { - if( !f_ ) - ErrorPolicy::missing_result_specification(); return f_; } diff --git a/src/libraries/turtle/root.hpp b/src/libraries/turtle/root.hpp index addb59b..e6fb519 100644 --- a/src/libraries/turtle/root.hpp +++ b/src/libraries/turtle/root.hpp @@ -9,6 +9,7 @@ #ifndef MOCK_ROOT_HPP_INCLUDED #define MOCK_ROOT_HPP_INCLUDED +#include "config.hpp" #include "node.hpp" #include diff --git a/src/tests/turtle_test/error_test.cpp b/src/tests/turtle_test/error_test.cpp index 9cc0e7d..089e88d 100644 --- a/src/tests/turtle_test/error_test.cpp +++ b/src/tests/turtle_test/error_test.cpp @@ -16,7 +16,7 @@ BOOST_AUTO_TEST_CASE( a_mock_exception_is_not_an_std_exception_to_not_mess_with_ { try { - throw mock::exception( "" ); + throw mock::exception(); } catch( std::exception& ) { diff --git a/src/tests/turtle_test/expectation_test.cpp b/src/tests/turtle_test/expectation_test.cpp index 8166de3..3d748e5 100644 --- a/src/tests/turtle_test/expectation_test.cpp +++ b/src/tests/turtle_test/expectation_test.cpp @@ -6,33 +6,62 @@ // http://www.boost.org/LICENSE_1_0.txt) // -#define BOOST_AUTO_TEST_MAIN -#include -#include +#include "mock_error.hpp" +#define BOOST_AUTO_TEST_MAIN #include #define BOOST_LIB_NAME boost_unit_test_framework #include +#define MOCK_ERROR_POLICY mock_error +#include + +#define CHECK_ERROR( expr, error ) \ + BOOST_CHECK( verify() ); \ + expr; \ + BOOST_CHECK_EQUAL( 1, error##_count ); \ + reset(); + namespace { - bool check_exception_contains( const mock::exception& e, const std::string& str ) + struct error_fixture { - return e.what().find( str ) != std::string::npos; - } + error_fixture() + { + reset(); + } + ~error_fixture() + { + BOOST_CHECK( verify() ); + } + void reset() + { + missing_result_specification_count = 0; + no_match_count = 0; + sequence_failed_count = 0; + verification_failed_count = 0; + untriggered_expectation_count = 0; + } + bool verify() const + { + return missing_result_specification_count == 0 && + no_match_count == 0 && + sequence_failed_count == 0 && + verification_failed_count == 0 && + untriggered_expectation_count == 0; + } + }; } -#define BOOST_CHECK_EXCEPTION_CONTAINS( S, C ) \ - BOOST_CHECK_EXCEPTION( S, mock::exception, boost::bind( &check_exception_contains, _1, C ) ); // functor -BOOST_AUTO_TEST_CASE( an_expectation_can_be_passed_as_functor ) +BOOST_FIXTURE_TEST_CASE( an_expectation_can_be_passed_as_functor, error_fixture ) { mock::expectation< void() > e; boost::function< void() > f = e; } -BOOST_AUTO_TEST_CASE( an_expectation_can_be_passed_as_functor_using_boost_bind_and_boost_ref ) +BOOST_FIXTURE_TEST_CASE( an_expectation_can_be_passed_as_functor_using_boost_bind_and_boost_ref, error_fixture ) { mock::expectation< void() > e; boost::function< void() > f = boost::bind( boost::ref( e ) ); @@ -40,66 +69,66 @@ BOOST_AUTO_TEST_CASE( an_expectation_can_be_passed_as_functor_using_boost_bind_a // invocations -BOOST_AUTO_TEST_CASE( triggering_an_empty_expectation_throws ) +BOOST_FIXTURE_TEST_CASE( triggering_an_empty_expectation_calls_no_match_error, error_fixture ) { { mock::expectation< void() > e; - BOOST_CHECK_EXCEPTION_CONTAINS( e(), "unexpected call" ); + CHECK_ERROR( e(), no_match ); } { mock::expectation< int( int, const std::string& ) > e; - BOOST_CHECK_EXCEPTION_CONTAINS( e( 1, "s" ), "unexpected call" ); + CHECK_ERROR( e( 1, "s" ), no_match ); } } -BOOST_AUTO_TEST_CASE( triggering_a_never_expectation_throws ) +BOOST_FIXTURE_TEST_CASE( triggering_a_never_expectation_calls_no_match_error, error_fixture ) { { mock::expectation< void() > e; e.expect().never(); - BOOST_CHECK_EXCEPTION_CONTAINS( e(), "unexpected call" ); + CHECK_ERROR( e(), no_match ); } { mock::expectation< int( int, const std::string& ) > e; e.expect().never(); - BOOST_CHECK_EXCEPTION_CONTAINS( e( 1, "s" ), "unexpected call" ); + CHECK_ERROR( e( 1, "s" ), no_match ); } } -BOOST_AUTO_TEST_CASE( triggering_an_unlimited_expectation_never_throws ) +BOOST_FIXTURE_TEST_CASE( triggering_an_unlimited_expectation_is_valid, error_fixture ) { { mock::expectation< void() > e; e.expect(); - BOOST_CHECK_NO_THROW( e() ); - BOOST_CHECK_NO_THROW( e() ); + e(); + e(); } { mock::expectation< void( int, const std::string& ) > e; e.expect(); - BOOST_CHECK_NO_THROW( e( 1, "s" ) ); - BOOST_CHECK_NO_THROW( e( 1, "s" ) ); + e( 1, "s" ); + e( 1, "s" ); } } -BOOST_AUTO_TEST_CASE( triggering_a_once_expectation_throws_after_one_call ) +BOOST_FIXTURE_TEST_CASE( triggering_a_once_expectation_calls_no_match_error_after_one_call, error_fixture ) { { mock::expectation< void() > e; e.expect().once(); - BOOST_CHECK_NO_THROW( e() ); - BOOST_CHECK_EXCEPTION_CONTAINS( e(), "unexpected call" ); + e(); + CHECK_ERROR( e(), no_match ); } { mock::expectation< void( int, const std::string& ) > e; e.expect().once(); - BOOST_CHECK_NO_THROW( e( 1, "s" ) ); - BOOST_CHECK_EXCEPTION_CONTAINS( e( 1, "s" ), "unexpected call" ); + e( 1, "s" ); + CHECK_ERROR( e( 1, "s" ), no_match ); } } /* -BOOST_AUTO_TEST_CASE( literal_zero_can_be_used_in_expectation_operator_call_as_pointers ) +BOOST_FIXTURE_TEST_CASE( literal_zero_can_be_used_in_expectation_operator_call_as_pointers, error_fixture ) { mock::expectation< void( int* ) > e; e( 0 ); @@ -108,7 +137,7 @@ BOOST_AUTO_TEST_CASE( literal_zero_can_be_used_in_expectation_operator_call_as_p // verify -BOOST_AUTO_TEST_CASE( verifying_an_empty_expectation_succeeds ) +BOOST_FIXTURE_TEST_CASE( verifying_an_empty_expectation_succeeds, error_fixture ) { { mock::expectation< void() > e; @@ -120,7 +149,7 @@ BOOST_AUTO_TEST_CASE( verifying_an_empty_expectation_succeeds ) } } -BOOST_AUTO_TEST_CASE( verifying_an_unlimited_expectation_succeeds ) +BOOST_FIXTURE_TEST_CASE( verifying_an_unlimited_expectation_succeeds, error_fixture ) { { mock::expectation< void() > e; @@ -134,7 +163,7 @@ BOOST_AUTO_TEST_CASE( verifying_an_unlimited_expectation_succeeds ) } } -BOOST_AUTO_TEST_CASE( verifying_a_once_expectation_after_one_call_succeeds ) +BOOST_FIXTURE_TEST_CASE( verifying_a_once_expectation_after_one_call_succeeds, error_fixture ) { { mock::expectation< void() > e; @@ -150,60 +179,39 @@ BOOST_AUTO_TEST_CASE( verifying_a_once_expectation_after_one_call_succeeds ) } } -namespace -{ - template< typename Result > - struct silent_error - { - static Result no_match( const std::string& context ) - { - throw std::runtime_error( __FUNCTION__ ); - } - 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*/ ) - {} - static void untriggered_expectation( const std::string& /*context*/, - const std::string& /*file*/, int /*line*/ ) - {} - }; -} - -BOOST_AUTO_TEST_CASE( verifying_a_once_expectation_before_the_call_fails ) +BOOST_FIXTURE_TEST_CASE( verifying_a_once_expectation_before_the_call_fails, error_fixture ) { { - mock::expectation< void(), silent_error< void > > e; + mock::expectation< void() > e; e.expect().once(); - BOOST_CHECK( ! e.verify() ); + CHECK_ERROR( BOOST_CHECK( ! e.verify() ), verification_failed ); } { - mock::expectation< int( int, const std::string& ), silent_error< int > > e; + mock::expectation< int( int, const std::string& ) > e; e.expect().once(); - BOOST_CHECK( ! e.verify() ); + CHECK_ERROR( BOOST_CHECK( ! e.verify() ), verification_failed ); } } // reset -BOOST_AUTO_TEST_CASE( triggering_a_reset_expectation_throws ) +BOOST_FIXTURE_TEST_CASE( triggering_a_reset_expectation_calls_no_match_error, error_fixture ) { { mock::expectation< void() > e; e.expect(); e.reset(); - BOOST_CHECK_EXCEPTION_CONTAINS( e(), "unexpected call" ); + CHECK_ERROR( e(), no_match ); } { mock::expectation< int( int, const std::string& ) > e; e.expect(); e.reset(); - BOOST_CHECK_EXCEPTION_CONTAINS( e( 1, "s" ), "unexpected call" ); + CHECK_ERROR( e( 1, "s" ), no_match ); } } -BOOST_AUTO_TEST_CASE( verifying_a_reset_expectation_succeeds ) +BOOST_FIXTURE_TEST_CASE( verifying_a_reset_expectation_succeeds, error_fixture ) { { mock::expectation< void() > e; @@ -221,49 +229,35 @@ BOOST_AUTO_TEST_CASE( verifying_a_reset_expectation_succeeds ) // constraints -BOOST_AUTO_TEST_CASE( triggering_an_expectation_with_wrong_parameter_value_in_equal_constraint_throws ) +BOOST_FIXTURE_TEST_CASE( triggering_an_expectation_with_wrong_parameter_value_in_equal_constraint_calls_no_match_error, error_fixture ) { { mock::expectation< void( int ) > e; e.expect().with( 42 ); - BOOST_CHECK_EXCEPTION_CONTAINS( e( 43 ), "unexpected call" ); + CHECK_ERROR( e( 43 ), no_match ); } { mock::expectation< int( int, const std::string& ) > e; e.expect().with( 42, "expected" ); - BOOST_CHECK_EXCEPTION_CONTAINS( e( 42, "actual" ), "unexpected call" ); + CHECK_ERROR( e( 42, "actual" ), no_match ); } } -BOOST_AUTO_TEST_CASE( passing_raw_parameter_as_constraint_falls_back_to_using_the_equal_constraint ) -{ - { - mock::expectation< void( int ) > e; - e.expect().with( 42 ); - BOOST_CHECK_EXCEPTION_CONTAINS( e( 43 ), "unexpected call" ); - } - { - mock::expectation< int( int, const std::string& ) > e; - e.expect().with( 42, "expected" ); - BOOST_CHECK_EXCEPTION_CONTAINS( e( 42, "actual" ), "unexpected call" ); - } -} - -BOOST_AUTO_TEST_CASE( triggering_an_expectation_with_wrong_parameter_value_in_equal_or_less_constraint_throws ) +BOOST_FIXTURE_TEST_CASE( triggering_an_expectation_with_wrong_parameter_value_in_equal_or_less_constraint_calls_no_match_error, error_fixture ) { mock::expectation< void( int ) > e; e.expect().with( mock::equal( 42 ) || mock::less( 42 ) ); - BOOST_CHECK_NO_THROW( e( 41 ) ); - BOOST_CHECK_NO_THROW( e( 42 ) ); - BOOST_CHECK_EXCEPTION_CONTAINS( e( 43 ), "unexpected call" ); + e( 41 ); + e( 42 ); + CHECK_ERROR( e( 43 ), no_match ); } -BOOST_AUTO_TEST_CASE( triggering_an_expectation_with_wrong_parameter_value_in_equal_and_not_less_constraint_throws ) +BOOST_FIXTURE_TEST_CASE( triggering_an_expectation_with_wrong_parameter_value_in_equal_and_not_less_constraint_calls_no_match_error, error_fixture ) { mock::expectation< void( int ) > e; e.expect().with( mock::equal( 42 ) && ! mock::less( 41 ) ); - BOOST_CHECK_NO_THROW( e( 42 ) ); - BOOST_CHECK_EXCEPTION_CONTAINS( e( 43 ), "unexpected call" ); + e( 42 ); + CHECK_ERROR( e( 43 ), no_match ); } namespace @@ -281,7 +275,7 @@ namespace }; } -BOOST_AUTO_TEST_CASE( passing_call_values_by_reference_is_transparent ) +BOOST_FIXTURE_TEST_CASE( passing_call_values_by_reference_is_transparent, error_fixture ) { { mock::expectation< void( my_interface& ) > e; @@ -305,28 +299,29 @@ namespace } } -BOOST_AUTO_TEST_CASE( triggering_an_expectation_with_failing_custom_constraint_throws ) +BOOST_FIXTURE_TEST_CASE( triggering_an_expectation_with_failing_custom_constraint_calls_no_match_error, error_fixture ) { { mock::expectation< void( int ) > e; e.expect().with( &custom_constraint ); - BOOST_CHECK_EXCEPTION_CONTAINS( e( 42 ), "unexpected call" ); + CHECK_ERROR( e( 42 ), no_match ); } { mock::expectation< int( int, const std::string& ) > e; e.expect().with( &custom_constraint, "actual" ); - BOOST_CHECK_EXCEPTION_CONTAINS( e( 42, "actual" ), "unexpected call" ); + CHECK_ERROR( e( 42, "actual" ), no_match ); } } -BOOST_AUTO_TEST_CASE( triggering_an_expectation_with_wrong_parameter_value_in_custom_constraint_throws ) +BOOST_FIXTURE_TEST_CASE( triggering_an_expectation_with_wrong_parameter_value_in_custom_constraint_calls_no_match_error, error_fixture ) { mock::expectation< void( int ) > e; e.expect().with( mock::constraint( &custom_constraint, "custom constraint" ) ); - BOOST_CHECK_EXCEPTION_CONTAINS( e( 42 ), "custom constraint" ); + CHECK_ERROR( e( 42 ), no_match ); } + /* -BOOST_AUTO_TEST_CASE( literal_zero_can_be_used_in_place_of_null_pointers_in_constraints ) +BOOST_FIXTURE_TEST_CASE( literal_zero_can_be_used_in_place_of_null_pointers_in_constraints, error_fixture ) { mock::expectation< void( int* ) > e; e.expect().with( 0 ); @@ -336,26 +331,26 @@ BOOST_AUTO_TEST_CASE( literal_zero_can_be_used_in_place_of_null_pointers_in_cons // result handling -BOOST_AUTO_TEST_CASE( triggering_an_expectation_with_no_return_set_throws ) +BOOST_FIXTURE_TEST_CASE( triggering_an_expectation_with_no_return_set_calls_missing_result_specification, error_fixture ) { { mock::expectation< int() > e; e.expect(); - BOOST_CHECK_EXCEPTION_CONTAINS( e(), "missing result specification" ); + CHECK_ERROR( e(), missing_result_specification ); } { mock::expectation< int&() > e; e.expect(); - BOOST_CHECK_EXCEPTION_CONTAINS( e(), "missing result specification" ); + CHECK_ERROR( e(), missing_result_specification ); } { mock::expectation< const std::string&() > e; e.expect(); - BOOST_CHECK_EXCEPTION_CONTAINS( e(), "missing result specification" ); + CHECK_ERROR( e(), missing_result_specification ); } } -BOOST_AUTO_TEST_CASE( triggering_an_expectation_returns_the_set_value ) +BOOST_FIXTURE_TEST_CASE( triggering_an_expectation_returns_the_set_value, error_fixture ) { { mock::expectation< int() > e; @@ -435,7 +430,7 @@ namespace struct B : A {}; } -BOOST_AUTO_TEST_CASE( triggering_an_expectation_returns_the_set_auto_ptr_value ) +BOOST_FIXTURE_TEST_CASE( triggering_an_expectation_returns_the_set_auto_ptr_value, error_fixture ) { { mock::expectation< std::auto_ptr< int >() > e; @@ -491,7 +486,7 @@ namespace } } -BOOST_AUTO_TEST_CASE( triggering_an_expectation_calls_the_custom_functor ) +BOOST_FIXTURE_TEST_CASE( triggering_an_expectation_calls_the_custom_functor, error_fixture ) { mock::expectation< int() > e; e.expect().calls( &custom_result ); @@ -506,21 +501,21 @@ namespace } } -BOOST_AUTO_TEST_CASE( triggering_an_expectation_calls_the_custom_functor_with_parameters ) +BOOST_FIXTURE_TEST_CASE( triggering_an_expectation_calls_the_custom_functor_with_parameters, error_fixture ) { mock::expectation< int( int ) > e; e.expect().calls( &custom_result_with_parameter ); BOOST_CHECK_EQUAL( 42, e( 42 ) ); } -BOOST_AUTO_TEST_CASE( triggering_an_expectation_calls_the_custom_functor_without_parameters_thanks_to_boost_bind ) +BOOST_FIXTURE_TEST_CASE( triggering_an_expectation_calls_the_custom_functor_without_parameters_thanks_to_boost_bind, error_fixture ) { mock::expectation< int( int ) > e; e.expect().calls( boost::bind( &custom_result ) ); BOOST_CHECK_EQUAL( 42, e( 17 ) ); } -BOOST_AUTO_TEST_CASE( triggering_an_expectation_throws_the_set_exception ) +BOOST_FIXTURE_TEST_CASE( triggering_an_expectation_throws_the_set_exception, error_fixture ) { mock::expectation< void() > e; e.expect().throws( std::runtime_error( "some exception" ) ); @@ -538,43 +533,43 @@ BOOST_AUTO_TEST_CASE( triggering_an_expectation_throws_the_set_exception ) // multiple matchers -BOOST_AUTO_TEST_CASE( expecting_twice_a_single_expectation_makes_it_callable_twice ) +BOOST_FIXTURE_TEST_CASE( expecting_twice_a_single_expectation_makes_it_callable_twice, error_fixture ) { { mock::expectation< void() > e; e.expect().once(); e.expect().once(); - BOOST_CHECK_NO_THROW( e() ); - BOOST_CHECK_NO_THROW( e() ); - BOOST_CHECK_EXCEPTION_CONTAINS( e(), "unexpected call" ); + e(); + e(); + CHECK_ERROR( e(), no_match ); } { mock::expectation< void( const std::string& ) > e; e.expect().once().with( "first" ); e.expect().once().with( "second" ); - BOOST_CHECK_NO_THROW( e( "first" ) ); - BOOST_CHECK_NO_THROW( e( "second" ) ); - BOOST_CHECK_EXCEPTION_CONTAINS( e( "third" ), "unexpected call" ); + e( "first" ); + e( "second" ); + CHECK_ERROR( e( "third"), no_match ); } } -BOOST_AUTO_TEST_CASE( best_matcher_is_selected_first ) +BOOST_FIXTURE_TEST_CASE( best_matcher_is_selected_first, error_fixture ) { { mock::expectation< void( int ) > e; e.expect().once().with( 1 ); e.expect().once().with( 2 ); - BOOST_CHECK_NO_THROW( e( 2 ) ); - BOOST_CHECK_NO_THROW( e( 1 ) ); - BOOST_CHECK_EXCEPTION_CONTAINS( e( 3 ), "unexpected call" ); + e( 2 ); + e( 1 ); + CHECK_ERROR( e( 3 ), no_match ); } { mock::expectation< void( const std::string& ) > e; e.expect().once().with( "first" ); e.expect().once().with( "second" ); - BOOST_CHECK_NO_THROW( e( "second" ) ); - BOOST_CHECK_NO_THROW( e( "first" ) ); - BOOST_CHECK_EXCEPTION_CONTAINS( e( "third" ), "unexpected call" ); + e( "second" ); + e( "first" ); + CHECK_ERROR( e( "third"), no_match ); } } @@ -591,7 +586,7 @@ namespace } } -BOOST_AUTO_TEST_CASE( expectation_can_be_serialized_to_be_human_readable ) +BOOST_FIXTURE_TEST_CASE( expectation_can_be_serialized_to_be_human_readable, error_fixture ) { { mock::expectation< void( int ) > e; @@ -690,91 +685,39 @@ BOOST_AUTO_TEST_CASE( expectation_can_be_serialized_to_be_human_readable ) } } -namespace +BOOST_FIXTURE_TEST_CASE( expectation_with_remaining_untriggered_matches_upon_destruction_calls_untriggered_expectation, error_fixture ) { - mock::expectation< void() > no_match_exp; - mock::expectation< void() > sequence_failed_exp; - mock::expectation< void() > verification_failed_exp; - mock::expectation< void() > untriggered_expectation_exp; - - struct error_fixture - { - error_fixture() - { - no_match_exp.tag( "no_match" ); - sequence_failed_exp.tag( "sequence_failed" ); - verification_failed_exp.tag( "verification_failed" ); - untriggered_expectation_exp.tag( "untriggered_expectation" ); - } - ~error_fixture() - { - no_match_exp.verify(); - no_match_exp.reset(); - sequence_failed_exp.verify(); - sequence_failed_exp.reset(); - verification_failed_exp.verify(); - verification_failed_exp.reset(); - untriggered_expectation_exp.verify(); - untriggered_expectation_exp.reset(); - } - static void no_match( const std::string& /*context*/ ) - { - no_match_exp(); - } - static void sequence_failed( const std::string& /*context*/, - const std::string& /*file*/, int /*line*/ ) - { - sequence_failed_exp(); - } - static void verification_failed( const std::string& /*context*/, - const std::string& /*file*/, int /*line*/ ) - { - verification_failed_exp(); - } - static void untriggered_expectation( const std::string& /*context*/, - const std::string& /*file*/, int /*line*/ ) - { - untriggered_expectation_exp(); - } - }; -} - -BOOST_FIXTURE_TEST_CASE( expectation_with_remaining_untriggered_matches_notifies_an_error_upon_destructions, error_fixture ) -{ - mock::expectation< void(), error_fixture > e; - e.expect().once(); - untriggered_expectation_exp.expect().once(); + std::auto_ptr< mock::expectation< void() > > e( new mock::expectation< void() > ); + e->expect().once(); + CHECK_ERROR( e.reset(), untriggered_expectation ); } BOOST_FIXTURE_TEST_CASE( verifying_expectation_with_remaining_matches_disables_the_automatic_verification_upon_destruction, error_fixture ) { - mock::expectation< void(), error_fixture > e; + mock::expectation< void() > e; e.expect().once(); - verification_failed_exp.expect(); - e.verify(); + CHECK_ERROR( e.verify(), verification_failed ); } BOOST_FIXTURE_TEST_CASE( triggering_no_match_call_disables_the_automatic_verification_upon_destruction, error_fixture ) { - mock::expectation< void(), error_fixture > e; - no_match_exp.expect(); - e(); + mock::expectation< void() > e; + CHECK_ERROR( e(), no_match ); } BOOST_FIXTURE_TEST_CASE( adding_a_matcher_reactivates_the_verification_upon_destruction, error_fixture ) { - mock::expectation< void(), error_fixture > e; - no_match_exp.expect(); - e(); - e.expect().once(); - untriggered_expectation_exp.expect().once(); + std::auto_ptr< mock::expectation< void() > > e( new mock::expectation< void() > ); + CHECK_ERROR( (*e)(), no_match ); + e->expect().once(); + CHECK_ERROR( e.reset(), untriggered_expectation ); } BOOST_FIXTURE_TEST_CASE( throwing_an_exception_disables_the_automatic_verification_upon_destruction, error_fixture ) { try { - mock::expectation< void(), error_fixture > e; + mock::expectation< void() > e; e.expect().once(); throw std::exception(); } diff --git a/src/tests/turtle_test/integration_test.cpp b/src/tests/turtle_test/integration_test.cpp index fa55b99..44d39a0 100644 --- a/src/tests/turtle_test/integration_test.cpp +++ b/src/tests/turtle_test/integration_test.cpp @@ -6,12 +6,15 @@ // http://www.boost.org/LICENSE_1_0.txt) // -#include +#include "silent_error.hpp" #include #define BOOST_LIB_NAME boost_unit_test_framework #include +#define MOCK_ERROR_POLICY silent_error +#include + #include #include @@ -91,7 +94,7 @@ BOOST_AUTO_TEST_CASE( mock_object_method_disambiguation ) my_ambiguited_mock mock; MOCK_EXPECT( mock, tag1 ); BOOST_CHECK_NO_THROW( mock.my_method() ); - BOOST_CHECK_THROW( mock.my_method( 12 ), mock::exception ); + BOOST_CHECK_THROW( mock.my_method( 12 ), std::exception ); } namespace @@ -118,7 +121,7 @@ BOOST_AUTO_TEST_CASE( mock_object_method_const_disambiguation ) MOCK_EXPECT( mock, tag1 ); BOOST_CHECK_NO_THROW( mock.my_method() ); const my_const_ambiguited_mock const_mock; - BOOST_CHECK_THROW( const_mock.my_method(), mock::exception ); + BOOST_CHECK_THROW( const_mock.my_method(), std::exception ); } BOOST_AUTO_TEST_CASE( mock_functor_in_function_is_supported ) diff --git a/src/tests/turtle_test/mock_error.hpp b/src/tests/turtle_test/mock_error.hpp new file mode 100644 index 0000000..ed78fe2 --- /dev/null +++ b/src/tests/turtle_test/mock_error.hpp @@ -0,0 +1,79 @@ +// +// Copyright Mathieu Champlon 2008 +// +// 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_TEST_MOCK_ERROR_HPP_INCLUDED +#define MOCK_TEST_MOCK_ERROR_HPP_INCLUDED + +#include +#include + +namespace +{ + int missing_result_specification_count = 0; + int no_match_count = 0; + int sequence_failed_count = 0; + int verification_failed_count = 0; + int untriggered_expectation_count = 0; +} +namespace mock +{ + template< typename Result > + struct mock_error + { + static Result missing_result_specification( const std::string& /*context*/, const std::string& /*file*/, int /*line*/ ) + { + ++missing_result_specification_count; + static BOOST_DEDUCED_TYPENAME boost::remove_reference< Result >::type r; + return r; + } + static Result 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*/ ) + { + ++sequence_failed_count; + } + 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*/ ) + { + ++untriggered_expectation_count; + } + }; + template<> + struct mock_error< void > + { + static void missing_result_specification( const std::string& /*context*/, const std::string& /*file*/, int /*line*/ ) + { + ++missing_result_specification_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*/ ) + { + ++sequence_failed_count; + } + 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*/ ) + { + ++untriggered_expectation_count; + } + }; +} + +#endif // #ifndef MOCK_TEST_MOCK_ERROR_HPP_INCLUDED diff --git a/src/tests/turtle_test/object_test.cpp b/src/tests/turtle_test/object_test.cpp index d8a426f..37d4f66 100644 --- a/src/tests/turtle_test/object_test.cpp +++ b/src/tests/turtle_test/object_test.cpp @@ -6,36 +6,26 @@ // http://www.boost.org/LICENSE_1_0.txt) // -#include -#include +#include "silent_error.hpp" #include #define BOOST_LIB_NAME boost_unit_test_framework #include +#define MOCK_ERROR_POLICY silent_error +#include +#include + BOOST_AUTO_TEST_CASE( verifying_an_empty_object_succeeds ) { mock::object o; BOOST_CHECK( o.verify() ); } -namespace -{ - struct silent_error - { - static void verification_failed( const std::string& /*context*/, - const std::string& /*file*/, int /*line*/ ) - {} - static void untriggered_expectation( const std::string& /*context*/, - const std::string& /*file*/, int /*line*/ ) - {} - }; -} - BOOST_AUTO_TEST_CASE( verifying_an_object_containing_a_failing_expectation_fails ) { mock::object o; - mock::expectation< void(), silent_error > e; + mock::expectation< void() > e; o.set_parent( e ); e.expect().once(); BOOST_CHECK( ! o.verify() ); @@ -46,7 +36,7 @@ BOOST_AUTO_TEST_CASE( verifying_an_object_containing_a_failing_expectation_fails BOOST_AUTO_TEST_CASE( verifying_all_objects_with_one_of_them_containing_a_failing_expectation_fails ) { mock::object o; - mock::expectation< void(), silent_error > e; + mock::expectation< void() > e; o.set_parent( e ); e.expect().once(); BOOST_CHECK( ! mock::verify() ); @@ -67,7 +57,7 @@ BOOST_AUTO_TEST_CASE( resetting_an_object_containing_a_failing_expectation_and_v BOOST_AUTO_TEST_CASE( an_object_is_assignable_by_sharing_its_state ) { mock::object o1; - mock::expectation< void(), silent_error > e; + mock::expectation< void() > e; { mock::object o2; o2.set_parent( e ); @@ -83,7 +73,7 @@ BOOST_AUTO_TEST_CASE( an_object_is_copiable_by_sharing_its_state ) { std::auto_ptr< mock::object > o2( new mock::object ); const mock::object o1( *o2 ); - mock::expectation< void(), silent_error > e; + mock::expectation< void() > e; o2->set_parent( e ); e.expect().once(); BOOST_CHECK( ! o2->verify() ); diff --git a/src/tests/turtle_test/sequence_test.cpp b/src/tests/turtle_test/sequence_test.cpp index 9c7dd05..ccb90f3 100644 --- a/src/tests/turtle_test/sequence_test.cpp +++ b/src/tests/turtle_test/sequence_test.cpp @@ -6,14 +6,15 @@ // http://www.boost.org/LICENSE_1_0.txt) // -#include -#include -#include +#include "silent_error.hpp" #include #define BOOST_LIB_NAME boost_unit_test_framework #include +#define MOCK_ERROR_POLICY mock::silent_error +#include + BOOST_AUTO_TEST_CASE( registering_to_a_sequence_and_calling_out_of_order_throws ) { mock::sequence s; @@ -21,7 +22,7 @@ BOOST_AUTO_TEST_CASE( registering_to_a_sequence_and_calling_out_of_order_throws e.expect().once().with( 1 ).in( s ); e.expect().once().with( 2 ).in( s ); BOOST_CHECK_NO_THROW( e( 2 ) ); - BOOST_CHECK_THROW( e( 1 ), mock::exception ); + BOOST_CHECK_THROW( e( 1 ), std::exception ); } BOOST_AUTO_TEST_CASE( registering_to_a_sequence_and_calling_out_of_order_multiple_invocations_throws ) @@ -32,7 +33,7 @@ BOOST_AUTO_TEST_CASE( registering_to_a_sequence_and_calling_out_of_order_multipl e.expect().once().with( 2 ).in( s ); BOOST_CHECK_NO_THROW( e( 1 ) ); BOOST_CHECK_NO_THROW( e( 2 ) ); - BOOST_CHECK_THROW( e( 1 ), mock::exception ); + BOOST_CHECK_THROW( e( 1 ), std::exception ); } BOOST_AUTO_TEST_CASE( registering_to_a_sequence_and_calling_in_order_is_valid ) @@ -52,7 +53,7 @@ BOOST_AUTO_TEST_CASE( registering_to_a_sequence_enforces_call_order_verification e1.expect().once().in( s ); e2.expect().once().in( s ); BOOST_CHECK_NO_THROW( e2() ); - BOOST_CHECK_THROW( e1(), mock::exception ); + BOOST_CHECK_THROW( e1(), std::exception ); } BOOST_AUTO_TEST_CASE( destroying_a_sequence_removes_order_call_enforcement ) diff --git a/src/tests/turtle_test/silent_error.hpp b/src/tests/turtle_test/silent_error.hpp new file mode 100644 index 0000000..631e526 --- /dev/null +++ b/src/tests/turtle_test/silent_error.hpp @@ -0,0 +1,43 @@ +// +// Copyright Mathieu Champlon 2008 +// +// 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_TEST_SILENT_ERROR_HPP_INCLUDED +#define MOCK_TEST_SILENT_ERROR_HPP_INCLUDED + +#include +#include + +namespace mock +{ + template< typename Result > + struct silent_error + { + static Result no_match( const std::string& /*context*/ ) + { + throw std::exception(); + } + static Result missing_result_specification( const std::string& /*context*/, + const std::string& /*file*/, int /*line*/ ) + { + throw std::exception(); + } + static void sequence_failed( const std::string& /*context*/, + const std::string& /*file*/, int /*line*/ ) + { + throw std::exception(); + } + static void verification_failed( const std::string& /*context*/, + const std::string& /*file*/, int /*line*/ ) + {} + static void untriggered_expectation( const std::string& /*context*/, + const std::string& /*file*/, int /*line*/ ) + {} + }; +} + +#endif // #ifndef MOCK_TEST_SILENT_ERROR_HPP_INCLUDED