1 // (C) Copyright Gennadiy Rozental 2005-2008. 2 // Distributed under the Boost Software License, Version 1.0. 3 // (See accompanying file LICENSE_1_0.txt or copy at 4 // http://www.boost.org/LICENSE_1_0.txt) 5 6 // See http://www.boost.org/libs/test for the library home page. 7 // 8 // File : $RCSfile$ 9 // 10 // Version : $Revision: 49312 $ 11 // 12 // Description : Facilities to perform interaction-based testing 13 // *************************************************************************** 14 15 #ifndef BOOST_TEST_INTERACTION_BASED_HPP_112105GER 16 #define BOOST_TEST_INTERACTION_BASED_HPP_112105GER 17 18 // Boost.Test 19 #include <boost/test/detail/config.hpp> 20 #include <boost/test/detail/global_typedef.hpp> 21 22 #include <boost/test/utils/wrap_stringstream.hpp> 23 24 #include <boost/test/detail/suppress_warnings.hpp> 25 26 // Boost 27 #include <boost/lexical_cast.hpp> 28 29 //____________________________________________________________________________// 30 31 // ************************************************************************** // 32 // ************** BOOST_ITEST_EPOINT ************** // 33 // ************************************************************************** // 34 35 #define BOOST_ITEST_EPOINT( description ) \ 36 ::boost::itest::manager::instance().exception_point( BOOST_TEST_L(__FILE__), __LINE__, description ) 37 /**/ 38 39 // ************************************************************************** // 40 // ************** BOOST_ITEST_DPOINT ************** // 41 // ************************************************************************** // 42 43 #define BOOST_ITEST_DPOINT() \ 44 ::boost::itest::manager::instance().decision_point( BOOST_TEST_L(__FILE__), __LINE__ ) 45 /**/ 46 47 // ************************************************************************** // 48 // ************** BOOST_ITEST_SCOPE ************** // 49 // ************************************************************************** // 50 51 #define BOOST_ITEST_SCOPE( scope_name ) \ 52 ::boost::itest::scope_guard itest_scope_guard ## __LINE__( BOOST_TEST_L(__FILE__), __LINE__, BOOST_STRINGIZE(scope_name) ) 53 /**/ 54 55 // ************************************************************************** // 56 // ************** BOOST_ITEST_NEW ************** // 57 // ************************************************************************** // 58 59 #define BOOST_ITEST_NEW( type_name ) \ 60 new ( ::boost::itest::location( BOOST_TEST_L(__FILE__), __LINE__ ) ) type_name 61 /**/ 62 63 // ************************************************************************** // 64 // ************** BOOST_ITEST_DATA_FLOW ************** // 65 // ************************************************************************** // 66 67 #define BOOST_ITEST_DATA_FLOW( v ) \ 68 ::boost::itest::manager::instance().generic_data_flow( v ) 69 /**/ 70 71 // ************************************************************************** // 72 // ************** BOOST_ITEST_RETURN ************** // 73 // ************************************************************************** // 74 75 #define BOOST_ITEST_RETURN( type, default_value ) \ 76 ::boost::itest::manager::instance().generic_return<type>( default_value ) 77 /**/ 78 79 // ************************************************************************** // 80 // ************** BOOST_ITEST_MOCK_FUNC ************** // 81 // ************************************************************************** // 82 83 #define BOOST_ITEST_MOCK_FUNC( function_name ) \ 84 BOOST_ITEST_SCOPE( function_name ); \ 85 BOOST_ITEST_EPOINT( 0 ); \ 86 return ::boost::itest::mock_object<>::prototype(); \ 87 /**/ 88 89 namespace boost { 90 91 namespace itest { // interaction-based testing 92 93 using unit_test::const_string; 94 95 // ************************************************************************** // 96 // ************** manager ************** // 97 // ************************************************************************** // 98 99 class BOOST_TEST_DECL manager { 100 public: 101 // instance access 102 static manager& instance() { return *instance_ptr(); } 103 104 // Mock objects interface hooks 105 virtual void exception_point( const_string /*file*/, 106 std::size_t /*line_num*/, 107 const_string /*descr*/ ){} 108 virtual bool decision_point( const_string /*file*/, 109 std::size_t /*line_num*/ ) { return true; } 110 virtual unsigned enter_scope( const_string /*file*/, 111 std::size_t /*line_num*/, 112 const_string /*scope_name*/){ return 0; } 113 virtual void leave_scope( unsigned ) {} 114 virtual void allocated( const_string /*file*/, 115 std::size_t /*line_num*/, 116 void* /*p*/, std::size_t /*s*/ ) {} 117 virtual void freed( void* /*p*/ ) {} 118 virtual void data_flow( const_string /*d*/ ) {} 119 virtual std::string return_value( const_string /*default_value */ ) { return ""; } 120 121 template<typename T> 122 void generic_data_flow( T const& t ) 123 { 124 wrap_stringstream ws; 125 126 data_flow( (ws << t).str() ); 127 } 128 template<typename T, typename DefaultValueType> 129 T generic_return( DefaultValueType const& dv ) 130 { 131 wrap_stringstream ws; 132 133 std::string const& res = return_value( (ws << dv).str() ); 134 135 if( res.empty() ) 136 return dv; 137 138 return lexical_cast<T>( res ); 139 } 140 141 protected: 142 manager(); 143 #if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564)) 144 public: 145 #endif 146 BOOST_TEST_PROTECTED_VIRTUAL ~manager(); 147 148 private: 149 struct dummy_constr{}; 150 explicit manager( dummy_constr* ) {} 151 152 static manager* instance_ptr( bool reset = false, manager* ptr = 0 ); 153 }; // manager 154 155 // ************************************************************************** // 156 // ************** scope_guard ************** // 157 // ************************************************************************** // 158 159 class scope_guard { 160 public: 161 // Constructor 162 scope_guard( const_string file, std::size_t line_num, const_string scope_name ) 163 { 164 m_scope_index = manager::instance().enter_scope( file, line_num, scope_name ); 165 } 166 ~scope_guard() 167 { 168 manager::instance().leave_scope( m_scope_index ); 169 } 170 171 unsigned m_scope_index; 172 }; 173 174 // ************************************************************************** // 175 // ************** location ************** // 176 // ************************************************************************** // 177 178 struct location { 179 location( const_string file, std::size_t line ) 180 : m_file_name( file ) 181 , m_line_num( line ) 182 {} 183 184 const_string m_file_name; 185 std::size_t m_line_num; 186 }; 187 188 } // namespace itest 189 190 } // namespace boost 191 192 // ************************************************************************** // 193 // ************** operator new overload ************** // 194 // ************************************************************************** // 195 196 #if !defined(BOOST_ITEST_NO_NEW_OVERLOADS) 197 198 // STL 199 #include <cstdlib> 200 201 # ifdef BOOST_NO_STDC_NAMESPACE 202 namespace std { using ::malloc; using ::free; } 203 # endif 204 # ifdef _CRTDBG_MAP_ALLOC 205 namespace std { using ::_malloc_dbg; using ::_free_dbg; } 206 # endif 207 208 inline void* 209 operator new( std::size_t s, ::boost::itest::location const& l ) 210 { 211 void* res = std::malloc(s ? s : 1); 212 213 if( res ) 214 ::boost::itest::manager::instance().allocated( l.m_file_name, l.m_line_num, res, s ); 215 else 216 throw std::bad_alloc(); 217 218 return res; 219 } 220 221 //____________________________________________________________________________// 222 223 inline void* 224 operator new[]( std::size_t s, ::boost::itest::location const& l ) 225 { 226 void* res = std::malloc(s ? s : 1); 227 228 if( res ) 229 ::boost::itest::manager::instance().allocated( l.m_file_name, l.m_line_num, res, s ); 230 else 231 throw std::bad_alloc(); 232 233 return res; 234 } 235 236 //____________________________________________________________________________// 237 238 inline void 239 operator delete( void* p, ::boost::itest::location const& ) 240 { 241 ::boost::itest::manager::instance().freed( p ); 242 243 std::free( p ); 244 } 245 246 //____________________________________________________________________________// 247 248 inline void 249 operator delete[]( void* p, ::boost::itest::location const& ) 250 { 251 ::boost::itest::manager::instance().freed( p ); 252 253 std::free( p ); 254 } 255 256 //____________________________________________________________________________// 257 258 #endif 259 260 #include <boost/test/detail/enable_warnings.hpp> 261 262 #endif // BOOST_TEST_INTERACTION_BASED_HPP_112105GER 263