1 /* 2 * Copyright (c) 2003, 2004 3 * Zdenek Nemec 4 * 5 * This material is provided "as is", with absolutely no warranty expressed 6 * or implied. Any use is at your own risk. 7 * 8 * Permission to use or copy this software for any purpose is hereby granted 9 * without fee, provided the above notices are retained on all copies. 10 * Permission to modify the code and to distribute modified code is granted, 11 * provided the above notices are retained, and a notice that the code was 12 * modified is included with the above copyright notice. 13 * 14 */ 15 16 /* $Id$ */ 17 18 #ifndef _CPPUNITMPFR_H_ 19 #define _CPPUNITMPFR_H_ 20 21 #if 0 22 # define CPPUNIT_NS CppUnitMini 23 #else 24 # define CPPUNIT_NS 25 #endif 26 27 #include <string.h> 28 29 #if 0 30 namespace CPPUNIT_NS 31 { 32 #endif 33 class Reporter { 34 public: 35 virtual ~Reporter() {} 36 virtual void error(const char * /*macroName*/, const char * /*in_macro*/, const char * /*in_file*/, int /*in_line*/) {} 37 virtual void message( const char * /*msg*/ ) {} 38 virtual void progress( const char * /*in_className*/, const char * /*in_testName*/, bool /*ignored*/, bool /* explicit */) {} 39 virtual void end() {} 40 virtual void printSummary() {} 41 }; 42 43 class TestFixture { 44 public: 45 virtual ~TestFixture() {} 46 47 //! \brief Set up context before running a test. 48 virtual void setUp() {} 49 50 //! Clean up after the test run. 51 virtual void tearDown() {} 52 }; 53 54 class TestCase : public TestFixture { 55 public: 56 TestCase() { registerTestCase(this); } 57 58 void setUp() { m_failed = false; } 59 static int run(Reporter *in_reporter = 0, const char *in_testName = "", bool invert = false); 60 int numErrors() { return m_numErrors; } 61 static void registerTestCase(TestCase *in_testCase); 62 63 virtual void myRun(const char * /*in_name*/, bool /*invert*/ = false) {} 64 65 virtual void error(const char *in_macroName, const char *in_macro, const char *in_file, int in_line) { 66 m_failed = true; 67 if (m_reporter) { 68 m_reporter->error(in_macroName, in_macro, in_file, in_line); 69 } 70 } 71 72 static void message(const char *msg) { 73 if (m_reporter) { 74 m_reporter->message(msg); 75 } 76 } 77 78 bool equalDoubles(double in_expected, double in_real, double in_maxErr) { 79 double diff = in_expected - in_real; 80 if (diff < 0.) { 81 diff = -diff; 82 } 83 return diff < in_maxErr; 84 } 85 86 virtual void progress(const char *in_className, const char *in_functionName, bool ignored, bool explicitTest) { 87 ++m_numTests; 88 if (m_reporter) { 89 m_reporter->progress(in_className, in_functionName, ignored, explicitTest); 90 } 91 } 92 93 bool shouldRunThis(const char *in_desiredTest, const char *in_className, const char *in_functionName, 94 bool invert, bool explicit_test, bool &do_progress) { 95 if ((in_desiredTest) && (in_desiredTest[0] != '\0')) { 96 do_progress = false; 97 const char *ptr = strstr(in_desiredTest, "::"); 98 if (ptr) { 99 bool match = (strncmp(in_desiredTest, in_className, strlen(in_className)) == 0) && 100 (strncmp(ptr + 2, in_functionName, strlen(in_functionName)) == 0); 101 // Invert shall not make explicit test run: 102 return invert ? (match ? !match : !explicit_test) 103 : match; 104 } 105 bool match = (strcmp(in_desiredTest, in_className) == 0); 106 do_progress = match; 107 return !explicit_test && (match == !invert); 108 } 109 do_progress = true; 110 return !explicit_test; 111 } 112 113 void tearDown() { 114 if (m_failed) 115 ++m_numErrors; 116 m_reporter->end(); 117 } 118 119 protected: 120 static int m_numErrors; 121 static int m_numTests; 122 123 private: 124 static TestCase *m_root; 125 TestCase *m_next; 126 bool m_failed; 127 128 static Reporter *m_reporter; 129 }; 130 #if 0 131 } 132 #endif 133 134 #if !defined (CPPUNIT_MINI_HIDE_UNUSED_VARIABLE) 135 # if defined (_MSC_VER) 136 # define CPPUNIT_MINI_HIDE_UNUSED_VARIABLE(v) (v); 137 # else 138 # define CPPUNIT_MINI_HIDE_UNUSED_VARIABLE(v) 139 # endif 140 #endif 141 142 #define CPPUNIT_TEST_SUITE(X) \ 143 typedef CPPUNIT_NS::TestCase Base; \ 144 virtual void myRun(const char *in_name, bool invert = false) { \ 145 const char *className = #X; CPPUNIT_MINI_HIDE_UNUSED_VARIABLE(className) \ 146 bool ignoring = false; CPPUNIT_MINI_HIDE_UNUSED_VARIABLE(ignoring) 147 148 #if defined CPPUNIT_MINI_USE_EXCEPTIONS 149 # define CPPUNIT_TEST_BASE(X, Y) \ 150 { \ 151 bool do_progress; \ 152 bool shouldRun = shouldRunThis(in_name, className, #X, invert, Y, do_progress); \ 153 if (shouldRun || do_progress) { \ 154 setUp(); \ 155 progress(className, #X, ignoring || !shouldRun, !ignoring && Y); \ 156 if (shouldRun && !ignoring) { \ 157 try { \ 158 X(); \ 159 } \ 160 catch(...) { \ 161 Base::error("Test Failed: An Exception was thrown.", #X, __FILE__, __LINE__); \ 162 } \ 163 } \ 164 tearDown(); \ 165 } \ 166 } 167 #else 168 # define CPPUNIT_TEST_BASE(X, Y) \ 169 { \ 170 bool do_progress; \ 171 bool shouldRun = shouldRunThis(in_name, className, #X, invert, Y, do_progress); \ 172 if (shouldRun || do_progress) { \ 173 setUp(); \ 174 progress(className, #X, ignoring || !shouldRun, !ignoring && Y); \ 175 if (shouldRun && !ignoring) \ 176 X(); \ 177 tearDown(); \ 178 } \ 179 } 180 #endif 181 182 #define CPPUNIT_TEST(X) CPPUNIT_TEST_BASE(X, false) 183 #define CPPUNIT_EXPLICIT_TEST(X) CPPUNIT_TEST_BASE(X, true) 184 185 #define CPPUNIT_IGNORE \ 186 ignoring = true 187 188 #define CPPUNIT_STOP_IGNORE \ 189 ignoring = false 190 191 #define CPPUNIT_TEST_SUITE_END() } 192 193 #define CPPUNIT_TEST_SUITE_REGISTRATION(X) static X local 194 195 #define CPPUNIT_CHECK(X) \ 196 if (!(X)) { \ 197 Base::error("CPPUNIT_CHECK", #X, __FILE__, __LINE__); \ 198 } 199 200 #define CPPUNIT_ASSERT(X) \ 201 if (!(X)) { \ 202 Base::error("CPPUNIT_ASSERT", #X, __FILE__, __LINE__); \ 203 return; \ 204 } 205 206 #define CPPUNIT_FAIL { \ 207 Base::error("CPPUNIT_FAIL", "", __FILE__, __LINE__); \ 208 return; \ 209 } 210 211 #define CPPUNIT_ASSERT_EQUAL(X, Y) \ 212 if ((X) != (Y)) { \ 213 Base::error("CPPUNIT_ASSERT_EQUAL", #X","#Y, __FILE__, __LINE__); \ 214 return; \ 215 } 216 217 #define CPPUNIT_ASSERT_DOUBLES_EQUAL(X, Y, Z) \ 218 if (!equalDoubles((X), (Y), (Z))) { \ 219 Base::error("CPPUNIT_ASSERT_DOUBLES_EQUAL", #X","#Y","#Z, __FILE__, __LINE__); \ 220 return; \ 221 } 222 223 #define CPPUNIT_MESSAGE(m) CPPUNIT_NS::TestCase::message(m) 224 225 #endif 226