00001 #ifndef CPPUNIT_TESTASSERT_H 00002 #define CPPUNIT_TESTASSERT_H 00003 00004 #include <cppunit/Portability.h> 00005 #include <cppunit/Exception.h> 00006 #include <cppunit/Asserter.h> 00007 #include <cppunit/portability/Stream.h> 00008 00009 #include <float.h> // For struct assertion_traits<double> 00010 00011 00012 CPPUNIT_NS_BEGIN 00013 00014 00038 template <class T> 00039 struct assertion_traits 00040 { 00041 static bool equal( const T& x, const T& y ) 00042 { 00043 return x == y; 00044 } 00045 00046 static std::string toString( const T& x ) 00047 { 00048 OStringStream ost; 00049 ost << x; 00050 return ost.str(); 00051 } 00052 }; 00053 00054 00063 template <> 00064 struct assertion_traits<double> 00065 { 00066 static bool equal( double x, double y ) 00067 { 00068 return x == y; 00069 } 00070 00071 static std::string toString( double x ) 00072 { 00073 #ifdef DBL_DIG 00074 const int precision = DBL_DIG; 00075 #else 00076 const int precision = 15; 00077 #endif // #ifdef DBL_DIG 00078 char buffer[128]; 00079 sprintf(buffer, "%.*g", precision, x); 00080 return buffer; 00081 } 00082 }; 00083 00084 00089 template <class T> 00090 void assertEquals( const T& expected, 00091 const T& actual, 00092 SourceLine sourceLine, 00093 const std::string &message ) 00094 { 00095 if ( !assertion_traits<T>::equal(expected,actual) ) // lazy toString conversion... 00096 { 00097 Asserter::failNotEqual( assertion_traits<T>::toString(expected), 00098 assertion_traits<T>::toString(actual), 00099 sourceLine, 00100 message ); 00101 } 00102 } 00103 00104 00109 void CPPUNIT_API assertDoubleEquals( double expected, 00110 double actual, 00111 double delta, 00112 SourceLine sourceLine, 00113 const std::string &message ); 00114 00115 00116 /* A set of macros which allow us to get the line number 00117 * and file name at the point of an error. 00118 * Just goes to show that preprocessors do have some 00119 * redeeming qualities. 00120 */ 00121 #if CPPUNIT_HAVE_CPP_SOURCE_ANNOTATION 00122 00125 #define CPPUNIT_ASSERT(condition) \ 00126 ( CPPUNIT_NS::Asserter::failIf( !(condition), \ 00127 CPPUNIT_NS::Message( "assertion failed", \ 00128 "Expression: " #condition), \ 00129 CPPUNIT_SOURCELINE() ) ) 00130 #else 00131 #define CPPUNIT_ASSERT(condition) \ 00132 ( CPPUNIT_NS::Asserter::failIf( !(condition), \ 00133 CPPUNIT_NS::Message( "assertion failed" ), \ 00134 CPPUNIT_SOURCELINE() ) ) 00135 #endif 00136 00144 #define CPPUNIT_ASSERT_MESSAGE(message,condition) \ 00145 ( CPPUNIT_NS::Asserter::failIf( !(condition), \ 00146 CPPUNIT_NS::Message( "assertion failed", \ 00147 "Expression: " \ 00148 #condition, \ 00149 message ), \ 00150 CPPUNIT_SOURCELINE() ) ) 00151 00156 #define CPPUNIT_FAIL( message ) \ 00157 ( CPPUNIT_NS::Asserter::fail( CPPUNIT_NS::Message( "forced failure", \ 00158 message ), \ 00159 CPPUNIT_SOURCELINE() ) ) 00160 00161 #ifdef CPPUNIT_ENABLE_SOURCELINE_DEPRECATED 00162 00163 #define CPPUNIT_ASSERT_EQUAL(expected,actual) \ 00164 ( CPPUNIT_NS::assertEquals( (expected), \ 00165 (actual), \ 00166 __LINE__, __FILE__ ) ) 00167 #else 00168 00184 #define CPPUNIT_ASSERT_EQUAL(expected,actual) \ 00185 ( CPPUNIT_NS::assertEquals( (expected), \ 00186 (actual), \ 00187 CPPUNIT_SOURCELINE(), \ 00188 "" ) ) 00189 00208 #define CPPUNIT_ASSERT_EQUAL_MESSAGE(message,expected,actual) \ 00209 ( CPPUNIT_NS::assertEquals( (expected), \ 00210 (actual), \ 00211 CPPUNIT_SOURCELINE(), \ 00212 (message) ) ) 00213 #endif 00214 00218 #define CPPUNIT_ASSERT_DOUBLES_EQUAL(expected,actual,delta) \ 00219 ( CPPUNIT_NS::assertDoubleEquals( (expected), \ 00220 (actual), \ 00221 (delta), \ 00222 CPPUNIT_SOURCELINE(), \ 00223 "" ) ) 00224 00225 00230 #define CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE(message,expected,actual,delta) \ 00231 ( CPPUNIT_NS::assertDoubleEquals( (expected), \ 00232 (actual), \ 00233 (delta), \ 00234 CPPUNIT_SOURCELINE(), \ 00235 (message) ) ) 00236 00237 00246 # define CPPUNIT_ASSERT_THROW( expression, ExceptionType ) \ 00247 CPPUNIT_ASSERT_THROW_MESSAGE( CPPUNIT_NS::AdditionalMessage(), \ 00248 expression, \ 00249 ExceptionType ) 00250 00251 00252 // implementation detail 00253 #if CPPUNIT_USE_TYPEINFO_NAME 00254 #define CPPUNIT_EXTRACT_EXCEPTION_TYPE_( exception, no_rtti_message ) \ 00255 CPPUNIT_NS::TypeInfoHelper::getClassName( typeid(exception) ) 00256 #else 00257 #define CPPUNIT_EXTRACT_EXCEPTION_TYPE_( exception, no_rtti_message ) \ 00258 std::string( no_rtti_message ) 00259 #endif // CPPUNIT_USE_TYPEINFO_NAME 00260 00261 // implementation detail 00262 #define CPPUNIT_GET_PARAMETER_STRING( parameter ) #parameter 00263 00273 # define CPPUNIT_ASSERT_THROW_MESSAGE( message, expression, ExceptionType ) \ 00274 do { \ 00275 bool cpputCorrectExceptionThrown_ = false; \ 00276 CPPUNIT_NS::Message cpputMsg_( "expected exception not thrown" ); \ 00277 cpputMsg_.addDetail( message ); \ 00278 cpputMsg_.addDetail( "Expected: " \ 00279 CPPUNIT_GET_PARAMETER_STRING( ExceptionType ) ); \ 00280 \ 00281 try { \ 00282 expression; \ 00283 } catch ( const ExceptionType & ) { \ 00284 cpputCorrectExceptionThrown_ = true; \ 00285 } catch ( const std::exception &e) { \ 00286 cpputMsg_.addDetail( "Actual : " + \ 00287 CPPUNIT_EXTRACT_EXCEPTION_TYPE_( e, \ 00288 "std::exception or derived") ); \ 00289 cpputMsg_.addDetail( std::string("What() : ") + e.what() ); \ 00290 } catch ( ... ) { \ 00291 cpputMsg_.addDetail( "Actual : unknown."); \ 00292 } \ 00293 \ 00294 if ( cpputCorrectExceptionThrown_ ) \ 00295 break; \ 00296 \ 00297 CPPUNIT_NS::Asserter::fail( cpputMsg_, \ 00298 CPPUNIT_SOURCELINE() ); \ 00299 } while ( false ) 00300 00301 00311 # define CPPUNIT_ASSERT_NO_THROW( expression ) \ 00312 CPPUNIT_ASSERT_NO_THROW_MESSAGE( CPPUNIT_NS::AdditionalMessage(), \ 00313 expression ) 00314 00315 00326 # define CPPUNIT_ASSERT_NO_THROW_MESSAGE( message, expression ) \ 00327 do { \ 00328 CPPUNIT_NS::Message cpputMsg_( "unexpected exception caught" ); \ 00329 cpputMsg_.addDetail( message ); \ 00330 \ 00331 try { \ 00332 expression; \ 00333 } catch ( const std::exception &e ) { \ 00334 cpputMsg_.addDetail( "Caught: " + \ 00335 CPPUNIT_EXTRACT_EXCEPTION_TYPE_( e, \ 00336 "std::exception or derived" ) ); \ 00337 cpputMsg_.addDetail( std::string("What(): ") + e.what() ); \ 00338 CPPUNIT_NS::Asserter::fail( cpputMsg_, \ 00339 CPPUNIT_SOURCELINE() ); \ 00340 } catch ( ... ) { \ 00341 cpputMsg_.addDetail( "Caught: unknown." ); \ 00342 CPPUNIT_NS::Asserter::fail( cpputMsg_, \ 00343 CPPUNIT_SOURCELINE() ); \ 00344 } \ 00345 } while ( false ) 00346 00347 00356 # define CPPUNIT_ASSERT_ASSERTION_FAIL( assertion ) \ 00357 CPPUNIT_ASSERT_THROW( assertion, CPPUNIT_NS::Exception ) 00358 00359 00369 # define CPPUNIT_ASSERT_ASSERTION_FAIL_MESSAGE( message, assertion ) \ 00370 CPPUNIT_ASSERT_THROW_MESSAGE( message, assertion, CPPUNIT_NS::Exception ) 00371 00372 00381 # define CPPUNIT_ASSERT_ASSERTION_PASS( assertion ) \ 00382 CPPUNIT_ASSERT_NO_THROW( assertion ) 00383 00384 00394 # define CPPUNIT_ASSERT_ASSERTION_PASS_MESSAGE( message, assertion ) \ 00395 CPPUNIT_ASSERT_NO_THROW_MESSAGE( message, assertion ) 00396 00397 00398 00399 00400 // Backwards compatibility 00401 00402 #if CPPUNIT_ENABLE_NAKED_ASSERT 00403 00404 #undef assert 00405 #define assert(c) CPPUNIT_ASSERT(c) 00406 #define assertEqual(e,a) CPPUNIT_ASSERT_EQUAL(e,a) 00407 #define assertDoublesEqual(e,a,d) CPPUNIT_ASSERT_DOUBLES_EQUAL(e,a,d) 00408 #define assertLongsEqual(e,a) CPPUNIT_ASSERT_EQUAL(e,a) 00409 00410 #endif 00411 00412 00413 CPPUNIT_NS_END 00414 00415 #endif // CPPUNIT_TESTASSERT_H