Remove unused vars
[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 _CPPUNITMPFR_H_
25 #define _CPPUNITMPFR_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
85       bool getBool( const char * pszParamName, bool bDefVal = false ) const
86       {
87           std::string strParamName( pszParamName );
88           cfg_map::const_iterator it = m_Cfg.find( strParamName );
89           if ( it == m_Cfg.end() )
90               return bDefVal ; // param not found -> returns default value
91           try {
92               return boost::lexical_cast< int >( it->second ) != 0;
93           }
94           catch ( boost::bad_lexical_cast& ex )
95           {
96               std::cerr << "bad_lexical_cast encountered while getting parameter "
97                   << strParamName << "=" << it->second
98                   << ": " << ex.what()
99                   << std::endl
100 ;
101           }
102           return bDefVal;
103       }
104
105   };
106
107   class Config {
108       std::map< std::string, TestCfg>  m_Cfg;
109
110   public:
111       Config() {}
112
113       void load( const char * fileName );
114
115       TestCfg& get( const std::string& strTestName )
116       {
117           return m_Cfg[ strTestName ];
118       }
119   };
120
121   class TestFixture {
122   public:
123     virtual ~TestFixture() {}
124
125     //! \brief Set up context before running a test.
126     virtual void setUp() {}
127
128     //! Clean up after the test run.
129     virtual void tearDown() {}
130   };
131
132   class TestCase : public TestFixture {
133   public:
134     TestCase() { registerTestCase(this); }
135
136     void setUp() { m_failed = false; }
137     static int run(Reporter *in_reporter = 0, const char *in_testName = "", bool invert = false);
138     int numErrors() { return m_numErrors; }
139     static void registerTestCase(TestCase *in_testCase);
140
141     static TestCase * current_test()
142     {
143         assert( m_pCurTestCase );
144         return m_pCurTestCase;
145     }
146
147     virtual void setUpParams( const TestCfg& /*cfg*/ ) {}
148     virtual void endTestCase() {}
149     virtual void myRun(const char * /*in_name*/, bool /*invert*/ = false) {}
150
151     virtual void error(const char *in_macroName, const char *in_macro, const char *in_file, int in_line) {
152       m_failed = true;
153       if (m_reporter) {
154         m_reporter->error(in_macroName, in_macro, in_file, in_line);
155       }
156     }
157
158     static void message(const char *msg) {
159       if (m_reporter) {
160         m_reporter->message(msg);
161       }
162     }
163
164     bool equalDoubles(double in_expected, double in_real, double in_maxErr) {
165       double diff = in_expected - in_real;
166       if (diff < 0.) {
167         diff = -diff;
168       }
169       return diff < in_maxErr;
170     }
171
172     virtual void progress(const char *in_className, const char *in_functionName, bool ignored, bool explicitTest) {
173       ++m_numTests;
174       if (m_reporter) {
175         m_reporter->progress(in_className, in_functionName, ignored, explicitTest);
176       }
177     }
178
179     bool shouldRunThis(const char *in_desiredTest, const char *in_className, const char *in_functionName,
180                        bool invert, bool explicit_test, bool &do_progress) {
181       if ((in_desiredTest) && (in_desiredTest[0] != '\0')) {
182         do_progress = false;
183         const char *ptr = strstr(in_desiredTest, "::");
184         if (ptr) {
185             bool match = (strncmp(in_desiredTest, in_className, strlen(in_className)) == 0 && in_desiredTest[strlen(in_className)] == ':' )
186                       && (strncmp(ptr + 2, in_functionName, strlen(ptr + 2)) == 0);
187           // Invert shall not make explicit test run:
188           return invert ? (match ? !match : !explicit_test)
189                         : match;
190         }
191         bool match = (strcmp(in_desiredTest, in_className) == 0);
192         do_progress = match;
193         return !explicit_test && (match == !invert);
194       }
195       do_progress = true;
196       return !explicit_test;
197     }
198
199     void tearDown() {
200       print_gc_state();
201       if (m_failed)
202         ++m_numErrors;
203       m_reporter->end();
204     }
205
206     static void print_gc_state();
207
208     static std::vector<std::string> const &    getTestStrings();
209
210   protected:
211     static std::vector<std::string>  m_arrStrings ;   // array of test strings
212
213   public:
214       static bool m_bPrintGCState   ;   // print GC state after each test
215       static Config m_Cfg;
216       static std::string    m_strTestDataDir;
217
218   protected:
219     static int m_numErrors;
220     static int m_numTests;
221
222     static TestCase * m_pCurTestCase;
223
224   private:
225     static TestCase *m_root;
226     TestCase *m_next;
227     bool m_failed;
228
229     static Reporter *m_reporter;
230   };
231
232 }
233
234 #if !defined (CPPUNIT_MINI_HIDE_UNUSED_VARIABLE)
235 #  if defined (_MSC_VER)
236 #    define CPPUNIT_MINI_HIDE_UNUSED_VARIABLE(v) (v);
237 #  else
238 #    define CPPUNIT_MINI_HIDE_UNUSED_VARIABLE(v)
239 #  endif
240 #endif
241
242 #define CPPUNIT_TEST_SUITE_(X, cfgBranchName) \
243     typedef CppUnitMini::TestCase Base; \
244     virtual void myRun(const char *in_name, bool invert = false) { \
245     const char *className = #X; CPPUNIT_MINI_HIDE_UNUSED_VARIABLE(className) \
246     bool ignoring = false; CPPUNIT_MINI_HIDE_UNUSED_VARIABLE(ignoring) \
247     setUpParams( m_Cfg.get( cfgBranchName ));
248
249 #define CPPUNIT_TEST_SUITE_PART(X, func) \
250     void X::func(const char *in_name, bool invert /*= false*/) { \
251     const char *className = #X; CPPUNIT_MINI_HIDE_UNUSED_VARIABLE(className) \
252     bool ignoring = false; CPPUNIT_MINI_HIDE_UNUSED_VARIABLE(ignoring)
253
254 #define CPPUNIT_TEST_SUITE(X) CPPUNIT_TEST_SUITE_(X, #X)
255
256 #if defined CPPUNIT_MINI_USE_EXCEPTIONS
257 #  define CPPUNIT_TEST_BASE(X, Y) \
258   { \
259     bool do_progress; \
260     bool shouldRun = shouldRunThis(in_name, className, #X, invert, Y, do_progress); \
261     if (shouldRun || do_progress) { \
262       setUp(); \
263       progress(className, #X, ignoring || !shouldRun, !ignoring && Y); \
264       if (shouldRun && !ignoring) { \
265         try { \
266           X(); \
267         } \
268         catch(...) { \
269           Base::error("Test Failed: An Exception was thrown.", #X, __FILE__, __LINE__); \
270         } \
271       } \
272       tearDown(); \
273     } \
274   }
275 #else
276 #  define CPPUNIT_TEST_BASE(X, Y) \
277   { \
278     bool do_progress; \
279     bool shouldRun = shouldRunThis(in_name, className, #X, invert, Y, do_progress); \
280     if (shouldRun || do_progress) { \
281       setUp(); \
282       progress(className, #X, ignoring || !shouldRun, !ignoring && Y); \
283       if (shouldRun && !ignoring) \
284         X(); \
285       tearDown(); \
286     } \
287   }
288 #endif
289
290 #define CPPUNIT_TEST(X) CPPUNIT_TEST_BASE(X, false)
291 #define CPPUNIT_EXPLICIT_TEST(X) CPPUNIT_TEST_BASE(X, true)
292
293 #define CPPUNIT_IGNORE \
294   ignoring = true
295
296 #define CPPUNIT_STOP_IGNORE \
297   ignoring = false
298
299 #define CPPUNIT_TEST_SUITE_END() endTestCase(); }
300 #define CPPUNIT_TEST_SUITE_END_PART() }
301
302 #define CPPUNIT_TEST_SUITE_REGISTRATION(X) static X local
303 #define CPPUNIT_TEST_SUITE_REGISTRATION_(X, NAME) static X NAME
304
305 #define CPPUNIT_CHECK(X) \
306   if (!(X)) { \
307     Base::error("CPPUNIT_CHECK", #X, __FILE__, __LINE__); \
308   }
309
310 #define CPPUNIT_CHECK_CURRENT(X) \
311   if (!(X)) { \
312     CppUnitMini::TestCase::current_test()->error("CPPUNIT_CHECK", #X, __FILE__, __LINE__); \
313   }
314
315 #define CPPUNIT_CHECK_EX(X, Y) \
316     if (!(X)) { \
317         std::stringstream st    ;   \
318         st << #X << ": " << Y   ;   \
319         Base::error("CPPUNIT_CHECK", st.str().c_str(), __FILE__, __LINE__); \
320     }
321
322 #define CPPUNIT_CHECK_CURRENT_EX(X, Y) \
323     if (!(X)) { \
324         std::stringstream st    ;   \
325         st << #X << ": " << Y   ;   \
326         CppUnitMini::TestCase::current_test()->error("CPPUNIT_CHECK", st.str().c_str(), __FILE__, __LINE__); \
327     }
328
329 #define CPPUNIT_ASSERT(X) \
330   if (!(X)) { \
331     Base::error("CPPUNIT_ASSERT", #X, __FILE__, __LINE__); \
332     return; \
333   }
334
335 #define CPPUNIT_ASSERT_CURRENT(X) \
336     if (!(X)) { \
337         CppUnitMini::TestCase::current_test()->error("CPPUNIT_ASSERT", #X, __FILE__, __LINE__); \
338         return; \
339     }
340
341
342 #define CPPUNIT_ASSERT_EX(A, X) \
343     if (!(A)) { \
344         std::stringstream st    ;   \
345         st << #A << ": " << X   ;   \
346         Base::error("CPPUNIT_ASSERT", st.str().c_str(), __FILE__, __LINE__); \
347         return; \
348     }
349
350 #define CPPUNIT_FAIL { \
351     Base::error("CPPUNIT_FAIL", "", __FILE__, __LINE__); \
352     return; \
353   }
354
355 #define CPPUNIT_ASSERT_EQUAL(X, Y) \
356   if ((X) != (Y)) { \
357     Base::error("CPPUNIT_ASSERT_EQUAL", #X","#Y, __FILE__, __LINE__); \
358     return; \
359   }
360
361 #define CPPUNIT_ASSERT_DOUBLES_EQUAL(X, Y, Z) \
362   if (!equalDoubles((X), (Y), (Z))) { \
363     Base::error("CPPUNIT_ASSERT_DOUBLES_EQUAL", #X","#Y","#Z, __FILE__, __LINE__); \
364     return; \
365   }
366
367 // added by cds
368 #define CPPUNIT_MSG( X ) \
369     {   \
370         std::stringstream st    ;   \
371         st << X ;   \
372         if ( !st.str().empty() ) \
373             CppUnitMini::TestCase::message( st.str().c_str() );   \
374     }
375
376 #define CPPUNIT_MESSAGE(m) CppUnitMini::TestCase::message(m)
377
378 #define CPPUNIT_ASSERT_MSG( A, X ) \
379     if ( !(A) ){   \
380         std::stringstream st    ;   \
381         st << #A << ": " << X ;   \
382         error( "CPPUNIT_ASSERT_MSG", st.str().c_str(), __FILE__, __LINE__ )     ;   \
383     }
384
385 #endif