cppunit_mini.h revision e46c9386c4f79aa40185f79a19fc5b2a7ef528b3
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
30namespace 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