4 * Copyright (c) 2003, 2004
7 * This material is provided "as is", with absolutely no warranty expressed
8 * or implied. Any use is at your own risk.
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.
19 Partially changed and expanded by Maxim Khiszinsky (cds), 2009
24 #ifndef CDS_CPPUNIT_MPFR_H_
25 #define CDS_CPPUNIT_MPFR_H_
37 #include <boost/lexical_cast.hpp>
43 virtual ~Reporter() {}
44 virtual void error(const char * /*macroName*/, const char * /*in_macro*/, const char * /*in_file*/, int /*in_line*/) {}
45 virtual void message( const char * /*msg*/ ) {}
46 virtual void progress( const char * /*in_className*/, const char * /*in_testName*/, bool /*ignored*/, bool /* explicit */) {}
48 virtual void printSummary() {}
53 typedef std::map< std::string, std::string > cfg_map;
54 cfg_map m_Cfg ; // map param_name => value
57 T get( const std::string& strParamName, T defVal ) const
59 cfg_map::const_iterator it = m_Cfg.find( strParamName );
60 if ( it == m_Cfg.end() )
61 return defVal ; // param not found -> returns default value
63 return boost::lexical_cast< T >( it->second );
65 catch ( boost::bad_lexical_cast& ex )
67 std::cerr << "bad_lexical_cast encountered while getting parameter "
68 << strParamName << "=" << it->second
77 T get( const char * pszParamName, T defVal ) const
79 return get( std::string( pszParamName ), defVal );
82 int getInt( const char * pszParamName, int nDefVal = 0 ) const { return get( pszParamName, nDefVal ) ; }
83 unsigned int getUInt( const char * pszParamName, unsigned int nDefVal = 0 ) const { return get( pszParamName, nDefVal ) ; }
84 long getLong( const char * pszParamName, long nDefVal = 0 ) const { return get( pszParamName, nDefVal ) ; }
85 unsigned long getULong( const char * pszParamName, unsigned long nDefVal = 0 ) const { return get( pszParamName, nDefVal ) ; }
86 size_t getSizeT( const char * pszParamName, size_t nDefVal = 0 ) const
88 return static_cast<size_t>( getULong( pszParamName, static_cast<unsigned long>(nDefVal)));
91 bool getBool( const char * pszParamName, bool bDefVal = false ) const
93 std::string strParamName( pszParamName );
94 cfg_map::const_iterator it = m_Cfg.find( strParamName );
95 if ( it == m_Cfg.end() )
96 return bDefVal ; // param not found -> returns default value
98 return boost::lexical_cast< int >( it->second ) != 0;
100 catch ( boost::bad_lexical_cast& ex )
102 std::cerr << "bad_lexical_cast encountered while getting parameter "
103 << strParamName << "=" << it->second
113 std::map< std::string, TestCfg> m_Cfg;
118 void load( const char * fileName );
120 TestCfg& get( const std::string& strTestName )
122 return m_Cfg[ strTestName ];
128 virtual ~TestFixture() {}
130 //! \brief Set up context before running a test.
131 virtual void setUp() {}
133 //! Clean up after the test run.
134 virtual void tearDown() {}
137 class TestCase : public TestFixture {
139 TestCase() { registerTestCase(this); }
141 void setUp() { m_failed = false; }
142 static int run(Reporter *in_reporter = 0, const char *in_testName = "", bool invert = false);
143 int numErrors() { return m_numErrors; }
144 static void registerTestCase(TestCase *in_testCase);
146 static TestCase * current_test()
148 assert( m_pCurTestCase );
149 return m_pCurTestCase;
152 virtual void setUpParams( const TestCfg& /*cfg*/ ) {}
153 virtual void endTestCase() {}
154 virtual void myRun(const char * /*in_name*/, bool /*invert*/ = false) {}
156 virtual void error(const char *in_macroName, const char *in_macro, const char *in_file, int in_line) {
159 m_reporter->error(in_macroName, in_macro, in_file, in_line);
163 static void message(const char *msg) {
165 m_reporter->message(msg);
169 bool equalDoubles(double in_expected, double in_real, double in_maxErr) {
170 double diff = in_expected - in_real;
174 return diff < in_maxErr;
177 virtual void progress(const char *in_className, const char *in_functionName, bool ignored, bool explicitTest) {
180 m_reporter->progress(in_className, in_functionName, ignored, explicitTest);
184 bool shouldRunThis( const char *in_desiredTest, const char *in_className, const char *in_functionName,
185 bool invert, bool explicit_test, bool &do_progress );
194 static void print_gc_state();
196 static std::vector<std::string> const& getTestStrings();
198 template <typename RandomIt>
199 static void shuffle( RandomIt first, RandomIt last )
201 std::shuffle( first, last, m_RandomGen );
205 static std::vector<std::string> m_arrStrings ; // array of test strings
208 static bool m_bPrintGCState ; // print GC state after each test
210 static std::string m_strTestDataDir;
211 static bool m_bExactMatch;
213 // random shuffle support
214 static std::random_device m_RandomDevice;
215 static std::mt19937 m_RandomGen;
218 static int m_numErrors;
219 static int m_numTests;
221 static TestCase * m_pCurTestCase;
224 static TestCase *m_root;
228 static Reporter *m_reporter;
233 #if !defined (CPPUNIT_MINI_HIDE_UNUSED_VARIABLE)
234 # if defined (_MSC_VER)
235 # define CPPUNIT_MINI_HIDE_UNUSED_VARIABLE(v) (v);
237 # define CPPUNIT_MINI_HIDE_UNUSED_VARIABLE(v)
241 #define CPPUNIT_TEST_SUITE_(X, cfgBranchName) \
242 typedef CppUnitMini::TestCase Base; \
243 virtual void myRun(const char *in_name, bool invert = false) { \
244 const char *className = #X; CPPUNIT_MINI_HIDE_UNUSED_VARIABLE(className) \
245 bool ignoring = false; CPPUNIT_MINI_HIDE_UNUSED_VARIABLE(ignoring) \
246 setUpParams( m_Cfg.get( cfgBranchName ));
248 #define CPPUNIT_TEST_SUITE_PART(X, func) \
249 void X::func(const char *in_name, bool invert /*= false*/) { \
250 const char *className = #X; CPPUNIT_MINI_HIDE_UNUSED_VARIABLE(className) \
251 bool ignoring = false; CPPUNIT_MINI_HIDE_UNUSED_VARIABLE(ignoring)
253 #define CPPUNIT_TEST_SUITE(X) CPPUNIT_TEST_SUITE_(X, #X)
255 #if defined CPPUNIT_MINI_USE_EXCEPTIONS
256 # define CPPUNIT_TEST_BASE(X, Y) \
259 bool shouldRun = shouldRunThis(in_name, className, #X, invert, Y, do_progress); \
260 if (shouldRun || do_progress) { \
262 progress(className, #X, ignoring || !shouldRun, !ignoring && Y); \
263 if (shouldRun && !ignoring) { \
268 Base::error("Test Failed: An exception was thrown.", #X, __FILE__, __LINE__); \
275 # define CPPUNIT_TEST_BASE(X, Y) \
278 bool shouldRun = shouldRunThis(in_name, className, #X, invert, Y, do_progress); \
279 if (shouldRun || do_progress) { \
281 progress(className, #X, ignoring || !shouldRun, !ignoring && Y); \
282 if (shouldRun && !ignoring) \
289 #define CPPUNIT_TEST(X) CPPUNIT_TEST_BASE(X, false)
290 #define CPPUNIT_EXPLICIT_TEST(X) CPPUNIT_TEST_BASE(X, true)
292 #define CDSUNIT_DECLARE_TEST(X) void X();
294 #define CPPUNIT_IGNORE \
297 #define CPPUNIT_STOP_IGNORE \
300 #define CPPUNIT_TEST_SUITE_END() endTestCase(); }
301 #define CPPUNIT_TEST_SUITE_END_PART() }
303 #define CPPUNIT_TEST_SUITE_REGISTRATION(X) static X local
304 #define CPPUNIT_TEST_SUITE_REGISTRATION_(X, NAME) static X NAME
306 #define CPPUNIT_CHECK(X) \
308 Base::error("CPPUNIT_CHECK", #X, __FILE__, __LINE__); \
311 #define CPPUNIT_CHECK_CURRENT(X) \
313 CppUnitMini::TestCase::current_test()->error("CPPUNIT_CHECK", #X, __FILE__, __LINE__); \
316 #define CPPUNIT_CHECK_EX(X, Y) \
318 std::stringstream st ; \
319 st << #X << ": " << Y ; \
320 Base::error("CPPUNIT_CHECK", st.str().c_str(), __FILE__, __LINE__); \
323 #define CPPUNIT_CHECK_CURRENT_EX(X, Y) \
325 std::stringstream st ; \
326 st << #X << ": " << Y ; \
327 CppUnitMini::TestCase::current_test()->error("CPPUNIT_CHECK", st.str().c_str(), __FILE__, __LINE__); \
330 #define CPPUNIT_ASSERT(X) \
332 Base::error("CPPUNIT_ASSERT", #X, __FILE__, __LINE__); \
336 #define CPPUNIT_ASSERT_CURRENT(X) \
338 CppUnitMini::TestCase::current_test()->error("CPPUNIT_ASSERT", #X, __FILE__, __LINE__); \
343 #define CPPUNIT_ASSERT_EX(A, X) \
345 std::stringstream st ; \
346 st << #A << ": " << X ; \
347 Base::error("CPPUNIT_ASSERT", st.str().c_str(), __FILE__, __LINE__); \
351 #define CPPUNIT_FAIL { \
352 Base::error("CPPUNIT_FAIL", "", __FILE__, __LINE__); \
356 #define CPPUNIT_ASSERT_EQUAL(X, Y) \
358 Base::error("CPPUNIT_ASSERT_EQUAL", #X","#Y, __FILE__, __LINE__); \
362 #define CPPUNIT_ASSERT_DOUBLES_EQUAL(X, Y, Z) \
363 if (!equalDoubles((X), (Y), (Z))) { \
364 Base::error("CPPUNIT_ASSERT_DOUBLES_EQUAL", #X","#Y","#Z, __FILE__, __LINE__); \
369 #define CPPUNIT_MSG( X ) \
371 std::stringstream st ; \
373 if ( !st.str().empty() ) \
374 CppUnitMini::TestCase::message( st.str().c_str() ); \
377 #define CPPUNIT_MESSAGE(m) CppUnitMini::TestCase::message(m)
379 #define CPPUNIT_ASSERT_MSG( A, X ) \
381 std::stringstream st ; \
382 st << #A << ": " << X ; \
383 error( "CPPUNIT_ASSERT_MSG", st.str().c_str(), __FILE__, __LINE__ ) ; \
386 #endif // #ifndef CDS_CPPUNIT_MPFR_H_