00001 #ifndef __KDAB__UNITTEST__TEST_H__
00002 #define __KDAB__UNITTEST__TEST_H__
00003
00004 #ifndef KDAB_NO_UNIT_TESTS
00005
00006 #include <string>
00007 #include <iostream>
00008
00009 #include "kdchart_export.h"
00010
00011 namespace KDAB {
00012 namespace UnitTest {
00013
00014 #define assertNotNull( x ) _assertNotNull( ( x ), #x, __FILE__, __LINE__ )
00015 #define assertNull( x ) _assertNull( ( x ), #x, __FILE__, __LINE__ )
00016 #define assertTrue( x ) _assertTrue( (x), #x, __FILE__, __LINE__ )
00017 #define assertFalse( x ) _assertFalse( (x), #x, __FILE__, __LINE__ )
00018 #define assertEqual( x, y ) _assertEqual( (x), (y), #x, #y, __FILE__, __LINE__ )
00019 #define assertNotEqual( x, y ) _assertNotEqual( (x), (y), #x, #y, __FILE__, __LINE__ )
00020
00021 #define assertNearEqual( x, y, z )
00022 #define assertEqualWithEpsilons( x, y, z ) _assertEqualWithEpsilons( (x), (y), (z), #x, #y, #z, __FILE__, __LINE__ )
00023 #if 0
00024 #define assertIsNaN( x ) _assertIsNaN( (x), #x, __FILE__, __LINE__ )
00025 #define assertIsNotNaN( x ) _assertIsNotNaN( (x), #x, __FILE__, __LINE__ )
00026 #endif
00027
00028 #define assertThrowsExceptionWithCode( x, E, code ) \
00029 do { \
00030 try { \
00031 x; \
00032 fail( __FILE__, __LINE__ ) \
00033 << "\"" #x "\" didn't throw \"" #E "\"" << std::endl; \
00034 } catch ( E & ppq_ut_thrown ) { \
00035 success(); \
00036 ( void )ppq_ut_thrown; \
00037 code; \
00038 } catch ( ... ) { \
00039 fail( __FILE__, __LINE__ ) \
00040 << "\"" #x "\" threw something, but it wasn't \"" #E "\"" << std::endl; \
00041 } \
00042 } while ( false )
00043
00044 #define assertThrowsException( x, E ) assertThrowsExceptionWithCode( x, E, do{}while(0) )
00045
00046 #define assertDoesNotThrowException( x, E ) \
00047 do { \
00048 try { \
00049 x; \
00050 success(); \
00051 } catch ( E & ) { \
00052 fail( __FILE__, __LINE__ ) \
00053 << "\"" #x "\" threw \"" #E "\", but shouldn't" << std::endl; \
00054 } catch ( ... ) { \
00055 fail( __FILE__, __LINE__ ) \
00056 << "\"" #x "\" threw something, but it wasn't \"" #E "\"" << std::endl; \
00057 } \
00058 } while ( false )
00059
00060
00061 class Test {
00062 const std::string mName;
00063 unsigned int mFailed, mSucceeded;
00064 public:
00065 Test( const std::string & name );
00066 virtual ~Test() {}
00067
00068 const std::string & name() const { return mName; }
00069 unsigned int failed() const { return mFailed; }
00070 unsigned int succeeded() const { return mSucceeded; }
00071
00072 virtual void run() = 0;
00073
00074 protected:
00075 void _assertNotNull( const void * x, const char * expression, const char * file, unsigned int line );
00076 void _assertNull( const void * x, const char * expression, const char * file, unsigned int line );
00077 #if 0
00078 void _assertIsNaN( double v, const char * expression, const char * file, unsigned int line );
00079 void _assertIsNotNaN( double v, const char * expression, const char * file, unsigned int line );
00080 #endif
00081 void _assertTrue( bool x, const char * expression, const char * file, unsigned int line );
00082 void _assertFalse( bool x, const char * expression, const char * file, unsigned int line );
00083
00084 void _assertEqualWithEpsilons( float x1, float x2, int prec, const char * expr1, const char * expr2, const char * exprPrec, const char * file, unsigned int line );
00085 void _assertEqualWithEpsilons( double x1, double x2, int prec, const char * expr1, const char * expr2, const char * exprPrec, const char * file, unsigned int line );
00086 void _assertEqualWithEpsilons( long double x1, long double x2, int prec, const char * expr1, const char * expr2, const char * exprPrec, const char * file, unsigned int line );
00087
00088 template <typename T, typename S>
00089 void _assertEqual( const T & x1, const S & x2, const char * expr1, const char * expr2, const char * file, unsigned int line ) {
00090 if ( x1 == x2 ) this->success();
00091 else {
00092 this->fail( file, line ) << '"' << expr1 << "\" yielded " << x1 << "; expected: " << x2 << "(\"" << expr2 << "\")" << std::endl;
00093 }
00094 }
00095 template <typename T, typename S>
00096 void _assertNotEqual( const T & x1, const S & x2, const char * expr1, const char * expr2, const char * file, unsigned int line ) {
00097 if ( x1 != x2 ) this->success();
00098 else {
00099 this->fail( file, line ) << '"' << expr1 << "\" yielded " << x1 << "; expected something not equal to: " << x2 << "(\"" << expr2 << "\")" << std::endl;
00100 }
00101 }
00102
00103 protected:
00104 std::ostream & fail( const char * file, unsigned int line );
00105 void success() {
00106 ++mSucceeded;
00107 }
00108 };
00109
00110 class TestFactory {
00111 public:
00112 virtual ~TestFactory() {}
00113 virtual Test * create() const = 0;
00114 };
00115
00116 }
00117 }
00118
00119 #include "testregistry.h"
00120
00121 namespace KDAB {
00122 namespace UnitTest {
00123
00124 template <typename T_Test>
00125 class GenericFactory : public TestFactory {
00126 public:
00127 GenericFactory( const char * group=0 ) {
00128 TestRegistry::instance()->registerTestFactory( this, group );
00129 }
00130 Test * create() const { return new T_Test(); }
00131 };
00132
00133 }
00134 }
00135
00136 #include "libutil.h"
00137
00138
00139
00140
00141
00142
00143
00144 #define KDAB_EXPORT_UNITTEST( Class, Group ) \
00145 static const KDAB::UnitTest::GenericFactory< Class > __##Class##_unittest( Group ); \
00146 KDAB_EXPORT_STATIC_SYMBOLS( Class )
00147
00148 #define KDAB_EXPORT_SCOPED_UNITTEST( Namespace, Class, Group ) \
00149 static const KDAB::UnitTest::GenericFactory< Namespace::Class > __##Class##_unittest( Group ); \
00150 KDAB_EXPORT_STATIC_SYMBOLS( Class )
00151
00152
00153 #define KDAB_IMPORT_UNITTEST( Class ) KDAB_IMPORT_STATIC_SYMBOLS( Class )
00154
00155
00156
00157 #define KDAB_UNITTEST_SIMPLE( Class, Group ) \
00158 class Class##Test : public KDAB::UnitTest::Test { \
00159 public: \
00160 Class##Test() : Test( #Class ) {} \
00161 void run(); \
00162 }; \
00163 KDAB_EXPORT_UNITTEST( Class##Test, Group ) \
00164 void Class##Test::run()
00165
00166 #define KDAB_SCOPED_UNITTEST_SIMPLE( Namespace, Class, Group ) \
00167 namespace Namespace { \
00168 class Class##Test : public KDAB::UnitTest::Test { \
00169 public: \
00170 Class##Test() : Test( #Namespace "::" #Class ){} \
00171 void run(); \
00172 }; \
00173 } \
00174 KDAB_EXPORT_SCOPED_UNITTEST( Namespace, Class##Test, Group ) \
00175 void Namespace::Class##Test::run()
00176
00177 #endif // KDAB_NO_UNIT_TESTS
00178
00179 #endif // __KDAB__UNITTEST__TEST_H__