Home | History | Annotate | Download | only in cppunit
      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