CppUnit project page FAQ CppUnit home page

TestAssert.h
Go to the documentation of this file.
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 #include <stdio.h>
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 #ifdef __STDC_SECURE_LIB__ // Use secure version with visual studio 2005 to avoid warning.
00080        sprintf_s(buffer, sizeof(buffer), "%.*g", precision, x); 
00081 #else   
00082        sprintf(buffer, "%.*g", precision, x); 
00083 #endif
00084        return buffer;
00085     }
00086 };
00087 
00088 
00093 template <class T>
00094 void assertEquals( const T& expected,
00095                    const T& actual,
00096                    SourceLine sourceLine,
00097                    const std::string &message )
00098 {
00099   if ( !assertion_traits<T>::equal(expected,actual) ) // lazy toString conversion...
00100   {
00101     Asserter::failNotEqual( assertion_traits<T>::toString(expected),
00102                             assertion_traits<T>::toString(actual),
00103                             sourceLine,
00104                             message );
00105   }
00106 }
00107 
00108 
00114 void CPPUNIT_API assertDoubleEquals( double expected,
00115                                      double actual,
00116                                      double delta,
00117                                      SourceLine sourceLine, 
00118                                      const std::string &message );
00119 
00120 
00121 /* A set of macros which allow us to get the line number
00122  * and file name at the point of an error.
00123  * Just goes to show that preprocessors do have some
00124  * redeeming qualities.
00125  */
00126 #if CPPUNIT_HAVE_CPP_SOURCE_ANNOTATION
00127 
00130 #define CPPUNIT_ASSERT(condition)                                                 \
00131   ( CPPUNIT_NS::Asserter::failIf( !(condition),                                   \
00132                                  CPPUNIT_NS::Message( "assertion failed",         \
00133                                                       "Expression: " #condition), \
00134                                  CPPUNIT_SOURCELINE() ) )
00135 #else
00136 #define CPPUNIT_ASSERT(condition)                                            \
00137   ( CPPUNIT_NS::Asserter::failIf( !(condition),                              \
00138                                   CPPUNIT_NS::Message( "assertion failed" ), \
00139                                   CPPUNIT_SOURCELINE() ) )
00140 #endif
00141 
00149 #define CPPUNIT_ASSERT_MESSAGE(message,condition)                          \
00150   ( CPPUNIT_NS::Asserter::failIf( !(condition),                            \
00151                                   CPPUNIT_NS::Message( "assertion failed", \
00152                                                        "Expression: "      \
00153                                                        #condition,         \
00154                                                        message ),          \
00155                                   CPPUNIT_SOURCELINE() ) )
00156 
00161 #define CPPUNIT_FAIL( message )                                         \
00162   ( CPPUNIT_NS::Asserter::fail( CPPUNIT_NS::Message( "forced failure",  \
00163                                                      message ),         \
00164                                 CPPUNIT_SOURCELINE() ) )
00165 
00166 #ifdef CPPUNIT_ENABLE_SOURCELINE_DEPRECATED
00167 
00168 #define CPPUNIT_ASSERT_EQUAL(expected,actual)                     \
00169   ( CPPUNIT_NS::assertEquals( (expected),             \
00170                               (actual),               \
00171                               __LINE__, __FILE__ ) )
00172 #else
00173 
00189 #define CPPUNIT_ASSERT_EQUAL(expected,actual)          \
00190   ( CPPUNIT_NS::assertEquals( (expected),              \
00191                               (actual),                \
00192                               CPPUNIT_SOURCELINE(),    \
00193                               "" ) )
00194 
00213 #define CPPUNIT_ASSERT_EQUAL_MESSAGE(message,expected,actual)      \
00214   ( CPPUNIT_NS::assertEquals( (expected),              \
00215                               (actual),                \
00216                               CPPUNIT_SOURCELINE(),    \
00217                               (message) ) )
00218 #endif
00219 
00230 #define CPPUNIT_ASSERT_DOUBLES_EQUAL(expected,actual,delta)        \
00231   ( CPPUNIT_NS::assertDoubleEquals( (expected),            \
00232                                     (actual),              \
00233                                     (delta),               \
00234                                     CPPUNIT_SOURCELINE(),  \
00235                                     "" ) )
00236 
00237 
00243 #define CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE(message,expected,actual,delta)  \
00244   ( CPPUNIT_NS::assertDoubleEquals( (expected),            \
00245                                     (actual),              \
00246                                     (delta),               \
00247                                     CPPUNIT_SOURCELINE(),  \
00248                                     (message) ) )
00249 
00250 
00259 # define CPPUNIT_ASSERT_THROW( expression, ExceptionType )              \
00260    CPPUNIT_ASSERT_THROW_MESSAGE( CPPUNIT_NS::AdditionalMessage(),       \
00261                                  expression,                            \
00262                                  ExceptionType )
00263 
00264 
00265 // implementation detail
00266 #if CPPUNIT_USE_TYPEINFO_NAME
00267 #define CPPUNIT_EXTRACT_EXCEPTION_TYPE_( exception, no_rtti_message ) \
00268    CPPUNIT_NS::TypeInfoHelper::getClassName( typeid(exception) )
00269 #else
00270 #define CPPUNIT_EXTRACT_EXCEPTION_TYPE_( exception, no_rtti_message ) \
00271    std::string( no_rtti_message )
00272 #endif // CPPUNIT_USE_TYPEINFO_NAME
00273 
00274 // implementation detail
00275 #define CPPUNIT_GET_PARAMETER_STRING( parameter ) #parameter
00276 
00286 # define CPPUNIT_ASSERT_THROW_MESSAGE( message, expression, ExceptionType )   \
00287    do {                                                                       \
00288       bool cpputCorrectExceptionThrown_ = false;                              \
00289       CPPUNIT_NS::Message cpputMsg_( "expected exception not thrown" );       \
00290       cpputMsg_.addDetail( message );                                         \
00291       cpputMsg_.addDetail( "Expected: "                                       \
00292                            CPPUNIT_GET_PARAMETER_STRING( ExceptionType ) );   \
00293                                                                               \
00294       try {                                                                   \
00295          expression;                                                          \
00296       } catch ( const ExceptionType & ) {                                     \
00297          cpputCorrectExceptionThrown_ = true;                                 \
00298       } catch ( const std::exception &e) {                                    \
00299          cpputMsg_.addDetail( "Actual  : " +                                  \
00300                               CPPUNIT_EXTRACT_EXCEPTION_TYPE_( e,             \
00301                                           "std::exception or derived") );     \
00302          cpputMsg_.addDetail( std::string("What()  : ") + e.what() );         \
00303       } catch ( ... ) {                                                       \
00304          cpputMsg_.addDetail( "Actual  : unknown.");                          \
00305       }                                                                       \
00306                                                                               \
00307       if ( cpputCorrectExceptionThrown_ )                                     \
00308          break;                                                               \
00309                                                                               \
00310       CPPUNIT_NS::Asserter::fail( cpputMsg_,                                  \
00311                                   CPPUNIT_SOURCELINE() );                     \
00312    } while ( false )
00313 
00314 
00324 # define CPPUNIT_ASSERT_NO_THROW( expression )                             \
00325    CPPUNIT_ASSERT_NO_THROW_MESSAGE( CPPUNIT_NS::AdditionalMessage(),       \
00326                                     expression )
00327 
00328 
00339 # define CPPUNIT_ASSERT_NO_THROW_MESSAGE( message, expression )               \
00340    do {                                                                       \
00341       CPPUNIT_NS::Message cpputMsg_( "unexpected exception caught" );         \
00342       cpputMsg_.addDetail( message );                                         \
00343                                                                               \
00344       try {                                                                   \
00345          expression;                                                          \
00346       } catch ( const std::exception &e ) {                                   \
00347          cpputMsg_.addDetail( "Caught: " +                                    \
00348                               CPPUNIT_EXTRACT_EXCEPTION_TYPE_( e,             \
00349                                           "std::exception or derived" ) );    \
00350          cpputMsg_.addDetail( std::string("What(): ") + e.what() );           \
00351          CPPUNIT_NS::Asserter::fail( cpputMsg_,                               \
00352                                      CPPUNIT_SOURCELINE() );                  \
00353       } catch ( ... ) {                                                       \
00354          cpputMsg_.addDetail( "Caught: unknown." );                           \
00355          CPPUNIT_NS::Asserter::fail( cpputMsg_,                               \
00356                                      CPPUNIT_SOURCELINE() );                  \
00357       }                                                                       \
00358    } while ( false )
00359 
00360 
00369 # define CPPUNIT_ASSERT_ASSERTION_FAIL( assertion )                 \
00370    CPPUNIT_ASSERT_THROW( assertion, CPPUNIT_NS::Exception )
00371 
00372 
00382 # define CPPUNIT_ASSERT_ASSERTION_FAIL_MESSAGE( message, assertion )    \
00383    CPPUNIT_ASSERT_THROW_MESSAGE( message, assertion, CPPUNIT_NS::Exception )
00384 
00385 
00394 # define CPPUNIT_ASSERT_ASSERTION_PASS( assertion )                 \
00395    CPPUNIT_ASSERT_NO_THROW( assertion )
00396 
00397 
00407 # define CPPUNIT_ASSERT_ASSERTION_PASS_MESSAGE( message, assertion )    \
00408    CPPUNIT_ASSERT_NO_THROW_MESSAGE( message, assertion )
00409 
00410 
00411 
00412 
00413 // Backwards compatibility
00414 
00415 #if CPPUNIT_ENABLE_NAKED_ASSERT
00416 
00417 #undef assert
00418 #define assert(c)                 CPPUNIT_ASSERT(c)
00419 #define assertEqual(e,a)          CPPUNIT_ASSERT_EQUAL(e,a)
00420 #define assertDoublesEqual(e,a,d) CPPUNIT_ASSERT_DOUBLES_EQUAL(e,a,d)
00421 #define assertLongsEqual(e,a)     CPPUNIT_ASSERT_EQUAL(e,a)
00422 
00423 #endif
00424 
00425 
00426 CPPUNIT_NS_END
00427 
00428 #endif  // CPPUNIT_TESTASSERT_H

SourceForge Logo hosts this site. Send comments to:
CppUnit Developers