Splitted up map_find_string test to reduce compiling time and memory requirements
[libcds.git] / tests / cppunit / cppunit_mini.h
1 //$$CDS-header$$
2
3 /*
4  * Copyright (c) 2003, 2004
5  * Zdenek Nemec
6  *
7  * This material is provided "as is", with absolutely no warranty expressed
8  * or implied. Any use is at your own risk.
9  *
10  * Permission to use or copy this software for any purpose is hereby granted
11  * without fee, provided the above notices are retained on all copies.
12  * Permission to modify the code and to distribute modified code is granted,
13  * provided the above notices are retained, and a notice that the code was
14  * modified is included with the above copyright notice.
15  *
16  */
17
18 /*
19     Partially changed and expanded by Maxim Khiszinsky (cds), 2009
20 */
21
22 /* $Id$ */
23
24 #ifndef CDS_CPPUNIT_MPFR_H_
25 #define CDS_CPPUNIT_MPFR_H_
26
27 #include <string.h>
28 #include <sstream>
29 #include <iostream>
30 #include <vector>
31 #include <string>
32 #include <map>
33 #include <assert.h>
34
35 #include <boost/lexical_cast.hpp>
36
37 namespace CppUnitMini
38 {
39   class Reporter {
40   public:
41     virtual ~Reporter() {}
42     virtual void error(const char * /*macroName*/, const char * /*in_macro*/, const char * /*in_file*/, int /*in_line*/) {}
43     virtual void message( const char * /*msg*/ ) {}
44     virtual void progress( const char * /*in_className*/, const char * /*in_testName*/, bool /*ignored*/, bool /* explicit */) {}
45     virtual void end() {}
46     virtual void printSummary() {}
47   };
48
49   struct TestCfg
50   {
51       typedef std::map< std::string, std::string >  cfg_map;
52       cfg_map    m_Cfg ; // map param_name => value
53
54       template <typename T>
55       T get( const std::string& strParamName, T defVal ) const
56       {
57           cfg_map::const_iterator it = m_Cfg.find( strParamName );
58           if ( it == m_Cfg.end() )
59               return defVal ; // param not found -> returns default value
60           try {
61               return boost::lexical_cast< T >( it->second );
62           }
63           catch ( boost::bad_lexical_cast& ex )
64           {
65               std::cerr << "bad_lexical_cast encountered while getting parameter "
66                   << strParamName << "=" << it->second
67                   << ": " << ex.what()
68                   << std::endl
69 ;
70           }
71           return defVal;
72       }
73
74       template <typename T>
75       T get( const char * pszParamName, T defVal ) const
76       {
77           return get( std::string( pszParamName ), defVal );
78       }
79
80       int getInt( const char * pszParamName, int nDefVal = 0 ) const { return get( pszParamName, nDefVal ) ; }
81       unsigned int getUInt( const char * pszParamName, unsigned int nDefVal = 0 ) const { return get( pszParamName, nDefVal ) ; }
82       long getLong( const char * pszParamName, long nDefVal = 0 ) const { return get( pszParamName, nDefVal ) ; }
83       unsigned long getULong( const char * pszParamName, unsigned long nDefVal = 0 ) const { return get( pszParamName, nDefVal ) ; }
84       size_t getSizeT( const char * pszParamName, size_t nDefVal = 0 ) const 
85       {
86           return static_cast<size_t>( getULong( pszParamName, static_cast<unsigned long>(nDefVal)));
87       }
88
89       bool getBool( const char * pszParamName, bool bDefVal = false ) const
90       {
91           std::string strParamName( pszParamName );
92           cfg_map::const_iterator it = m_Cfg.find( strParamName );
93           if ( it == m_Cfg.end() )
94               return bDefVal ; // param not found -> returns default value
95           try {
96               return boost::lexical_cast< int >( it->second ) != 0;
97           }
98           catch ( boost::bad_lexical_cast& ex )
99           {
100               std::cerr << "bad_lexical_cast encountered while getting parameter "
101                   << strParamName << "=" << it->second
102                   << ": " << ex.what()
103                   << std::endl;
104           }
105           return bDefVal;
106       }
107
108   };
109
110   class Config {
111       std::map< std::string, TestCfg>  m_Cfg;
112
113   public:
114       Config() {}
115
116       void load( const char * fileName );
117
118       TestCfg& get( const std::string& strTestName )
119       {
120           return m_Cfg[ strTestName ];
121       }
122   };
123
124   class TestFixture {
125   public:
126     virtual ~TestFixture() {}
127
128     //! \brief Set up context before running a test.
129     virtual void setUp() {}
130
131     //! Clean up after the test run.
132     virtual void tearDown() {}
133   };
134
135   class TestCase : public TestFixture {
136   public:
137     TestCase() { registerTestCase(this); }
138
139     void setUp() { m_failed = false; }
140     static int run(Reporter *in_reporter = 0, const char *in_testName = "", bool invert = false);
141     int numErrors() { return m_numErrors; }
142     static void registerTestCase(TestCase *in_testCase);
143
144     static TestCase * current_test()
145     {
146         assert( m_pCurTestCase );
147         return m_pCurTestCase;
148     }
149
150     virtual void setUpParams( const TestCfg& /*cfg*/ ) {}
151     virtual void endTestCase() {}
152     virtual void myRun(const char * /*in_name*/, bool /*invert*/ = false) {}
153
154     virtual void error(const char *in_macroName, const char *in_macro, const char *in_file, int in_line) {
155       m_failed = true;
156       if (m_reporter) {
157         m_reporter->error(in_macroName, in_macro, in_file, in_line);
158       }
159     }
160
161     static void message(const char *msg) {
162       if (m_reporter) {
163         m_reporter->message(msg);
164       }
165     }
166
167     bool equalDoubles(double in_expected, double in_real, double in_maxErr) {
168       double diff = in_expected - in_real;
169       if (diff < 0.) {
170         diff = -diff;
171       }
172       return diff < in_maxErr;
173     }
174
175     virtual void progress(const char *in_className, const char *in_functionName, bool ignored, bool explicitTest) {
176       ++m_numTests;
177       if (m_reporter) {
178         m_reporter->progress(in_className, in_functionName, ignored, explicitTest);
179       }
180     }
181
182     bool shouldRunThis( const char *in_desiredTest, const char *in_className, const char *in_functionName,
183                         bool invert, bool explicit_test, bool &do_progress );
184
185     void tearDown() {
186       print_gc_state();
187       if (m_failed)
188         ++m_numErrors;
189       m_reporter->end();
190     }
191
192     static void print_gc_state();
193
194     static std::vector<std::string> const &    getTestStrings();
195
196   protected:
197     static std::vector<std::string>  m_arrStrings ;   // array of test strings
198
199   public:
200       static bool m_bPrintGCState   ;   // print GC state after each test
201       static Config m_Cfg;
202       static std::string m_strTestDataDir;
203       static bool m_bExactMatch;
204
205   protected:
206     static int m_numErrors;
207     static int m_numTests;
208
209     static TestCase * m_pCurTestCase;
210
211   private:
212     static TestCase *m_root;
213     TestCase *m_next;
214     bool m_failed;
215
216     static Reporter *m_reporter;
217   };
218
219 }
220
221 #if !defined (CPPUNIT_MINI_HIDE_UNUSED_VARIABLE)
222 #  if defined (_MSC_VER)
223 #    define CPPUNIT_MINI_HIDE_UNUSED_VARIABLE(v) (v);
224 #  else
225 #    define CPPUNIT_MINI_HIDE_UNUSED_VARIABLE(v)
226 #  endif
227 #endif
228
229 #define CPPUNIT_TEST_SUITE_(X, cfgBranchName) \
230     typedef CppUnitMini::TestCase Base; \
231     virtual void myRun(const char *in_name, bool invert = false) { \
232     const char *className = #X; CPPUNIT_MINI_HIDE_UNUSED_VARIABLE(className) \
233     bool ignoring = false; CPPUNIT_MINI_HIDE_UNUSED_VARIABLE(ignoring) \
234     setUpParams( m_Cfg.get( cfgBranchName ));
235
236 #define CPPUNIT_TEST_SUITE_PART(X, func) \
237     void X::func(const char *in_name, bool invert /*= false*/) { \
238     const char *className = #X; CPPUNIT_MINI_HIDE_UNUSED_VARIABLE(className) \
239     bool ignoring = false; CPPUNIT_MINI_HIDE_UNUSED_VARIABLE(ignoring)
240
241 #define CPPUNIT_TEST_SUITE(X) CPPUNIT_TEST_SUITE_(X, #X)
242
243 #if defined CPPUNIT_MINI_USE_EXCEPTIONS
244 #  define CPPUNIT_TEST_BASE(X, Y) \
245   { \
246     bool do_progress; \
247     bool shouldRun = shouldRunThis(in_name, className, #X, invert, Y, do_progress); \
248     if (shouldRun || do_progress) { \
249       setUp(); \
250       progress(className, #X, ignoring || !shouldRun, !ignoring && Y); \
251       if (shouldRun && !ignoring) { \
252         try { \
253           X(); \
254         } \
255         catch(...) { \
256           Base::error("Test Failed: An exception was thrown.", #X, __FILE__, __LINE__); \
257         } \
258       } \
259       tearDown(); \
260     } \
261   }
262 #else
263 #  define CPPUNIT_TEST_BASE(X, Y) \
264   { \
265     bool do_progress; \
266     bool shouldRun = shouldRunThis(in_name, className, #X, invert, Y, do_progress); \
267     if (shouldRun || do_progress) { \
268       setUp(); \
269       progress(className, #X, ignoring || !shouldRun, !ignoring && Y); \
270       if (shouldRun && !ignoring) \
271         X(); \
272       tearDown(); \
273     } \
274   }
275 #endif
276
277 #define CPPUNIT_TEST(X) CPPUNIT_TEST_BASE(X, false)
278 #define CPPUNIT_EXPLICIT_TEST(X) CPPUNIT_TEST_BASE(X, true)
279
280 #define CPPUNIT_IGNORE \
281   ignoring = true
282
283 #define CPPUNIT_STOP_IGNORE \
284   ignoring = false
285
286 #define CPPUNIT_TEST_SUITE_END() endTestCase(); }
287 #define CPPUNIT_TEST_SUITE_END_PART() }
288
289 #define CPPUNIT_TEST_SUITE_REGISTRATION(X) static X local
290 #define CPPUNIT_TEST_SUITE_REGISTRATION_(X, NAME) static X NAME
291
292 #define CPPUNIT_CHECK(X) \
293   if (!(X)) { \
294     Base::error("CPPUNIT_CHECK", #X, __FILE__, __LINE__); \
295   }
296
297 #define CPPUNIT_CHECK_CURRENT(X) \
298   if (!(X)) { \
299     CppUnitMini::TestCase::current_test()->error("CPPUNIT_CHECK", #X, __FILE__, __LINE__); \
300   }
301
302 #define CPPUNIT_CHECK_EX(X, Y) \
303     if (!(X)) { \
304         std::stringstream st    ;   \
305         st << #X << ": " << Y   ;   \
306         Base::error("CPPUNIT_CHECK", st.str().c_str(), __FILE__, __LINE__); \
307     }
308
309 #define CPPUNIT_CHECK_CURRENT_EX(X, Y) \
310     if (!(X)) { \
311         std::stringstream st    ;   \
312         st << #X << ": " << Y   ;   \
313         CppUnitMini::TestCase::current_test()->error("CPPUNIT_CHECK", st.str().c_str(), __FILE__, __LINE__); \
314     }
315
316 #define CPPUNIT_ASSERT(X) \
317   if (!(X)) { \
318     Base::error("CPPUNIT_ASSERT", #X, __FILE__, __LINE__); \
319     return; \
320   }
321
322 #define CPPUNIT_ASSERT_CURRENT(X) \
323     if (!(X)) { \
324         CppUnitMini::TestCase::current_test()->error("CPPUNIT_ASSERT", #X, __FILE__, __LINE__); \
325         return; \
326     }
327
328
329 #define CPPUNIT_ASSERT_EX(A, X) \
330     if (!(A)) { \
331         std::stringstream st    ;   \
332         st << #A << ": " << X   ;   \
333         Base::error("CPPUNIT_ASSERT", st.str().c_str(), __FILE__, __LINE__); \
334         return; \
335     }
336
337 #define CPPUNIT_FAIL { \
338     Base::error("CPPUNIT_FAIL", "", __FILE__, __LINE__); \
339     return; \
340   }
341
342 #define CPPUNIT_ASSERT_EQUAL(X, Y) \
343   if ((X) != (Y)) { \
344     Base::error("CPPUNIT_ASSERT_EQUAL", #X","#Y, __FILE__, __LINE__); \
345     return; \
346   }
347
348 #define CPPUNIT_ASSERT_DOUBLES_EQUAL(X, Y, Z) \
349   if (!equalDoubles((X), (Y), (Z))) { \
350     Base::error("CPPUNIT_ASSERT_DOUBLES_EQUAL", #X","#Y","#Z, __FILE__, __LINE__); \
351     return; \
352   }
353
354 // added by cds
355 #define CPPUNIT_MSG( X ) \
356     {   \
357         std::stringstream st    ;   \
358         st << X ;   \
359         if ( !st.str().empty() ) \
360             CppUnitMini::TestCase::message( st.str().c_str() );   \
361     }
362
363 #define CPPUNIT_MESSAGE(m) CppUnitMini::TestCase::message(m)
364
365 #define CPPUNIT_ASSERT_MSG( A, X ) \
366     if ( !(A) ){   \
367         std::stringstream st    ;   \
368         st << #A << ": " << X ;   \
369         error( "CPPUNIT_ASSERT_MSG", st.str().c_str(), __FILE__, __LINE__ )     ;   \
370     }
371
372 #endif // #ifndef CDS_CPPUNIT_MPFR_H_