Chris@16: // (C) Copyright Gennadiy Rozental 2005-2008. Chris@16: // Distributed under the Boost Software License, Version 1.0. Chris@16: // (See accompanying file LICENSE_1_0.txt or copy at Chris@16: // http://www.boost.org/LICENSE_1_0.txt) Chris@16: Chris@16: // See http://www.boost.org/libs/test for the library home page. Chris@16: // Chris@16: // File : $RCSfile$ Chris@16: // Chris@101: // Version : $Revision$ Chris@16: // Chris@16: // Description : Facilities to perform interaction-based testing Chris@16: // *************************************************************************** Chris@16: Chris@16: #ifndef BOOST_TEST_INTERACTION_BASED_HPP_112105GER Chris@16: #define BOOST_TEST_INTERACTION_BASED_HPP_112105GER Chris@16: Chris@16: // Boost.Test Chris@16: #include Chris@16: #include Chris@16: Chris@16: #include Chris@16: Chris@16: #include Chris@16: Chris@16: // Boost Chris@16: #include Chris@16: Chris@16: //____________________________________________________________________________// Chris@16: Chris@16: // ************************************************************************** // Chris@16: // ************** BOOST_ITEST_EPOINT ************** // Chris@16: // ************************************************************************** // Chris@16: Chris@16: #define BOOST_ITEST_EPOINT( description ) \ Chris@16: ::boost::itest::manager::instance().exception_point( BOOST_TEST_L(__FILE__), __LINE__, description ) Chris@16: /**/ Chris@16: Chris@16: // ************************************************************************** // Chris@16: // ************** BOOST_ITEST_DPOINT ************** // Chris@16: // ************************************************************************** // Chris@16: Chris@16: #define BOOST_ITEST_DPOINT() \ Chris@16: ::boost::itest::manager::instance().decision_point( BOOST_TEST_L(__FILE__), __LINE__ ) Chris@16: /**/ Chris@16: Chris@16: // ************************************************************************** // Chris@16: // ************** BOOST_ITEST_SCOPE ************** // Chris@16: // ************************************************************************** // Chris@16: Chris@16: #define BOOST_ITEST_SCOPE( scope_name ) \ Chris@16: ::boost::itest::scope_guard itest_scope_guard ## __LINE__( BOOST_TEST_L(__FILE__), __LINE__, BOOST_STRINGIZE(scope_name) ) Chris@16: /**/ Chris@16: Chris@16: // ************************************************************************** // Chris@16: // ************** BOOST_ITEST_NEW ************** // Chris@16: // ************************************************************************** // Chris@16: Chris@16: #define BOOST_ITEST_NEW( type_name ) \ Chris@16: new ( ::boost::itest::location( BOOST_TEST_L(__FILE__), __LINE__ ) ) type_name Chris@16: /**/ Chris@16: Chris@16: // ************************************************************************** // Chris@16: // ************** BOOST_ITEST_DATA_FLOW ************** // Chris@16: // ************************************************************************** // Chris@16: Chris@16: #define BOOST_ITEST_DATA_FLOW( v ) \ Chris@16: ::boost::itest::manager::instance().generic_data_flow( v ) Chris@16: /**/ Chris@16: Chris@16: // ************************************************************************** // Chris@16: // ************** BOOST_ITEST_RETURN ************** // Chris@16: // ************************************************************************** // Chris@16: Chris@16: #define BOOST_ITEST_RETURN( type, default_value ) \ Chris@16: ::boost::itest::manager::instance().generic_return( default_value ) Chris@16: /**/ Chris@16: Chris@16: // ************************************************************************** // Chris@16: // ************** BOOST_ITEST_MOCK_FUNC ************** // Chris@16: // ************************************************************************** // Chris@16: Chris@16: #define BOOST_ITEST_MOCK_FUNC( function_name ) \ Chris@16: BOOST_ITEST_SCOPE( function_name ); \ Chris@16: BOOST_ITEST_EPOINT( 0 ); \ Chris@16: return ::boost::itest::mock_object<>::prototype(); \ Chris@16: /**/ Chris@16: Chris@16: namespace boost { Chris@16: Chris@16: namespace itest { // interaction-based testing Chris@16: Chris@16: using unit_test::const_string; Chris@16: Chris@16: // ************************************************************************** // Chris@16: // ************** manager ************** // Chris@16: // ************************************************************************** // Chris@16: Chris@16: class BOOST_TEST_DECL manager { Chris@16: public: Chris@16: // instance access Chris@16: static manager& instance() { return *instance_ptr(); } Chris@16: Chris@16: // Mock objects interface hooks Chris@16: virtual void exception_point( const_string /*file*/, Chris@16: std::size_t /*line_num*/, Chris@16: const_string /*descr*/ ){} Chris@16: virtual bool decision_point( const_string /*file*/, Chris@16: std::size_t /*line_num*/ ) { return true; } Chris@16: virtual unsigned enter_scope( const_string /*file*/, Chris@16: std::size_t /*line_num*/, Chris@16: const_string /*scope_name*/){ return 0; } Chris@16: virtual void leave_scope( unsigned ) {} Chris@16: virtual void allocated( const_string /*file*/, Chris@16: std::size_t /*line_num*/, Chris@16: void* /*p*/, std::size_t /*s*/ ) {} Chris@16: virtual void freed( void* /*p*/ ) {} Chris@16: virtual void data_flow( const_string /*d*/ ) {} Chris@16: virtual std::string return_value( const_string /*default_value */ ) { return ""; } Chris@16: Chris@16: template Chris@16: void generic_data_flow( T const& t ) Chris@16: { Chris@16: wrap_stringstream ws; Chris@16: Chris@16: data_flow( (ws << t).str() ); Chris@16: } Chris@16: template Chris@16: T generic_return( DefaultValueType const& dv ) Chris@16: { Chris@16: wrap_stringstream ws; Chris@16: Chris@16: std::string const& res = return_value( (ws << dv).str() ); Chris@16: Chris@16: if( res.empty() ) Chris@16: return dv; Chris@16: Chris@16: return lexical_cast( res ); Chris@16: } Chris@16: Chris@16: protected: Chris@16: manager(); Chris@16: #if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564)) Chris@16: public: Chris@16: #endif Chris@16: BOOST_TEST_PROTECTED_VIRTUAL ~manager(); Chris@16: Chris@16: private: Chris@16: struct dummy_constr{}; Chris@16: explicit manager( dummy_constr* ) {} Chris@16: Chris@16: static manager* instance_ptr( bool reset = false, manager* ptr = 0 ); Chris@16: }; // manager Chris@16: Chris@16: // ************************************************************************** // Chris@16: // ************** scope_guard ************** // Chris@16: // ************************************************************************** // Chris@16: Chris@16: class scope_guard { Chris@16: public: Chris@16: // Constructor Chris@16: scope_guard( const_string file, std::size_t line_num, const_string scope_name ) Chris@16: { Chris@16: m_scope_index = manager::instance().enter_scope( file, line_num, scope_name ); Chris@16: } Chris@16: ~scope_guard() Chris@16: { Chris@16: manager::instance().leave_scope( m_scope_index ); Chris@16: } Chris@16: Chris@16: unsigned m_scope_index; Chris@16: }; Chris@16: Chris@16: // ************************************************************************** // Chris@16: // ************** location ************** // Chris@16: // ************************************************************************** // Chris@16: Chris@16: struct location { Chris@16: location( const_string file, std::size_t line ) Chris@16: : m_file_name( file ) Chris@16: , m_line_num( line ) Chris@16: {} Chris@16: Chris@16: const_string m_file_name; Chris@16: std::size_t m_line_num; Chris@16: }; Chris@16: Chris@16: } // namespace itest Chris@16: Chris@16: } // namespace boost Chris@16: Chris@16: // ************************************************************************** // Chris@16: // ************** operator new overload ************** // Chris@16: // ************************************************************************** // Chris@16: Chris@16: #if !defined(BOOST_ITEST_NO_NEW_OVERLOADS) Chris@16: Chris@16: // STL Chris@16: #include Chris@16: Chris@16: # ifdef BOOST_NO_STDC_NAMESPACE Chris@16: namespace std { using ::malloc; using ::free; } Chris@16: # endif Chris@16: # ifdef _CRTDBG_MAP_ALLOC Chris@16: namespace std { using ::_malloc_dbg; using ::_free_dbg; } Chris@16: # endif Chris@16: Chris@16: inline void* Chris@16: operator new( std::size_t s, ::boost::itest::location const& l ) Chris@16: { Chris@16: void* res = std::malloc(s ? s : 1); Chris@16: Chris@16: if( res ) Chris@16: ::boost::itest::manager::instance().allocated( l.m_file_name, l.m_line_num, res, s ); Chris@16: else Chris@16: throw std::bad_alloc(); Chris@16: Chris@16: return res; Chris@16: } Chris@16: Chris@16: //____________________________________________________________________________// Chris@16: Chris@16: inline void* Chris@16: operator new[]( std::size_t s, ::boost::itest::location const& l ) Chris@16: { Chris@16: void* res = std::malloc(s ? s : 1); Chris@16: Chris@16: if( res ) Chris@16: ::boost::itest::manager::instance().allocated( l.m_file_name, l.m_line_num, res, s ); Chris@16: else Chris@16: throw std::bad_alloc(); Chris@16: Chris@16: return res; Chris@16: } Chris@16: Chris@16: //____________________________________________________________________________// Chris@16: Chris@16: inline void Chris@16: operator delete( void* p, ::boost::itest::location const& ) Chris@16: { Chris@16: ::boost::itest::manager::instance().freed( p ); Chris@16: Chris@16: std::free( p ); Chris@16: } Chris@16: Chris@16: //____________________________________________________________________________// Chris@16: Chris@16: inline void Chris@16: operator delete[]( void* p, ::boost::itest::location const& ) Chris@16: { Chris@16: ::boost::itest::manager::instance().freed( p ); Chris@16: Chris@16: std::free( p ); Chris@16: } Chris@16: Chris@16: //____________________________________________________________________________// Chris@16: Chris@16: #endif Chris@16: Chris@16: #include Chris@16: Chris@16: #endif // BOOST_TEST_INTERACTION_BASED_HPP_112105GER