2 This file is a part of libcds - Concurrent Data Structures library
4 (C) Copyright Maxim Khizhinsky (libcds.dev@gmail.com) 2006-2016
6 Source code repo: http://github.com/khizmax/libcds/
7 Download: http://sourceforge.net/projects/libcds/files/
9 Redistribution and use in source and binary forms, with or without
10 modification, are permitted provided that the following conditions are met:
12 * Redistributions of source code must retain the above copyright notice, this
13 list of conditions and the following disclaimer.
15 * Redistributions in binary form must reproduce the above copyright notice,
16 this list of conditions and the following disclaimer in the documentation
17 and/or other materials provided with the distribution.
19 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
23 FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
25 SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
26 CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
27 OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 * Copyright (c) 2003, 2004
35 * This material is provided "as is", with absolutely no warranty expressed
36 * or implied. Any use is at your own risk.
38 * Permission to use or copy this software for any purpose is hereby granted
39 * without fee, provided the above notices are retained on all copies.
40 * Permission to modify the code and to distribute modified code is granted,
41 * provided the above notices are retained, and a notice that the code was
42 * modified is included with the above copyright notice.
47 Partially changed and expanded by Maxim Khiszinsky (cds), 2009
52 #ifndef CDS_CPPUNIT_MPFR_H_
53 #define CDS_CPPUNIT_MPFR_H_
65 #include <boost/lexical_cast.hpp>
71 virtual ~Reporter() {}
72 virtual void error(const char * /*macroName*/, const char * /*in_macro*/, const char * /*in_file*/, int /*in_line*/) {}
73 virtual void message( const char * /*msg*/ ) {}
74 virtual void progress( const char * /*in_className*/, const char * /*in_testName*/, bool /*ignored*/, bool /* explicit */) {}
76 virtual void printSummary() {}
81 typedef std::map< std::string, std::string > cfg_map;
82 cfg_map m_Cfg ; // map param_name => value
85 T get( const std::string& strParamName, T defVal ) const
87 cfg_map::const_iterator it = m_Cfg.find( strParamName );
88 if ( it == m_Cfg.end() )
89 return defVal ; // param not found -> returns default value
91 return boost::lexical_cast< T >( it->second );
93 catch ( boost::bad_lexical_cast& ex )
95 std::cerr << "bad_lexical_cast encountered while getting parameter "
96 << strParamName << "=" << it->second
104 template <typename T>
105 T get( const char * pszParamName, T defVal ) const
107 return get( std::string( pszParamName ), defVal );
110 int getInt( const char * pszParamName, int nDefVal = 0 ) const { return get( pszParamName, nDefVal ) ; }
111 unsigned int getUInt( const char * pszParamName, unsigned int nDefVal = 0 ) const { return get( pszParamName, nDefVal ) ; }
112 long getLong( const char * pszParamName, long nDefVal = 0 ) const { return get( pszParamName, nDefVal ) ; }
113 unsigned long getULong( const char * pszParamName, unsigned long nDefVal = 0 ) const { return get( pszParamName, nDefVal ) ; }
114 size_t getSizeT( const char * pszParamName, size_t nDefVal = 0 ) const
116 return static_cast<size_t>( getULong( pszParamName, static_cast<unsigned long>(nDefVal)));
119 bool getBool( const char * pszParamName, bool bDefVal = false ) const
121 std::string strParamName( pszParamName );
122 cfg_map::const_iterator it = m_Cfg.find( strParamName );
123 if ( it == m_Cfg.end() )
124 return bDefVal ; // param not found -> returns default value
126 return boost::lexical_cast< int >( it->second ) != 0;
128 catch ( boost::bad_lexical_cast& ex )
130 std::cerr << "bad_lexical_cast encountered while getting parameter "
131 << strParamName << "=" << it->second
141 std::map< std::string, TestCfg> m_Cfg;
146 void load( const char * fileName );
148 TestCfg& get( const std::string& strTestName )
150 return m_Cfg[ strTestName ];
156 virtual ~TestFixture() {}
158 //! \brief Set up context before running a test.
159 virtual void setUp() {}
161 //! Clean up after the test run.
162 virtual void tearDown() {}
165 class TestCase : public TestFixture {
169 registerTestCase(this);
172 void setUp() { m_failed = false; }
173 static int run(Reporter *in_reporter = 0, const char *in_testName = "", bool invert = false);
174 int numErrors() { return m_numErrors; }
175 static void registerTestCase(TestCase *in_testCase);
177 static TestCase * current_test()
179 assert( m_pCurTestCase );
180 return m_pCurTestCase;
183 virtual void setUpParams( const TestCfg& /*cfg*/ ) {}
184 virtual void endTestCase() {}
185 virtual void myRun(const char * /*in_name*/, bool /*invert*/ = false) {}
187 virtual void error(const char *in_macroName, const char *in_macro, const char *in_file, int in_line) {
190 m_reporter->error(in_macroName, in_macro, in_file, in_line);
193 virtual char const * test_name() const = 0;
195 static void message(const char *msg) {
197 m_reporter->message(msg);
201 bool equalDoubles(double in_expected, double in_real, double in_maxErr) {
202 double diff = in_expected - in_real;
206 return diff < in_maxErr;
209 virtual void progress(const char *in_className, const char *in_functionName, bool ignored, bool explicitTest) {
212 m_reporter->progress(in_className, in_functionName, ignored, explicitTest);
216 bool shouldRunThis( const char *in_desiredTest, const char *in_className, const char *in_functionName,
217 bool invert, bool explicit_test, bool &do_progress );
226 static void print_gc_state();
228 static std::vector<std::string> const& getTestStrings();
230 template <typename RandomIt>
231 static void shuffle( RandomIt first, RandomIt last )
233 std::shuffle( first, last, m_RandomGen );
236 static void print_test_list();
239 static std::vector<std::string> m_arrStrings ; // array of test strings
242 static bool m_bPrintGCState ; // print GC state after each test
244 static std::string m_strTestDataDir;
245 static bool m_bExactMatch;
247 // random shuffle support
248 static std::random_device m_RandomDevice;
249 static std::mt19937 m_RandomGen;
252 static int m_numErrors;
253 static int m_numTests;
255 static TestCase * m_pCurTestCase;
258 static TestCase *m_root;
262 static Reporter *m_reporter;
267 #if !defined (CPPUNIT_MINI_HIDE_UNUSED_VARIABLE)
268 # if defined (_MSC_VER)
269 # define CPPUNIT_MINI_HIDE_UNUSED_VARIABLE(v) (v);
271 # define CPPUNIT_MINI_HIDE_UNUSED_VARIABLE(v)
275 #define CPPUNIT_TEST_SUITE_(X, cfgBranchName) \
276 typedef CppUnitMini::TestCase Base; \
277 virtual char const * test_name() const { return #X; } \
278 virtual void myRun(const char *in_name, bool invert = false) { \
279 const char *className = #X; CPPUNIT_MINI_HIDE_UNUSED_VARIABLE(className) \
280 bool ignoring = false; CPPUNIT_MINI_HIDE_UNUSED_VARIABLE(ignoring) \
281 setUpParams( m_Cfg.get( cfgBranchName ));
283 #define CPPUNIT_TEST_SUITE(X) CPPUNIT_TEST_SUITE_(X, #X)
285 #if defined CPPUNIT_MINI_USE_EXCEPTIONS
286 # define CPPUNIT_TEST_BASE(X, Y) \
289 bool shouldRun = shouldRunThis(in_name, className, #X, invert, Y, do_progress); \
290 if (shouldRun || do_progress) { \
292 progress(className, #X, ignoring || !shouldRun, !ignoring && Y); \
293 if (shouldRun && !ignoring) { \
298 Base::error("Test Failed: An exception was thrown.", #X, __FILE__, __LINE__); \
305 # define CPPUNIT_TEST_BASE(X, Y) \
308 bool shouldRun = shouldRunThis(in_name, className, #X, invert, Y, do_progress); \
309 if (shouldRun || do_progress) { \
311 progress(className, #X, ignoring || !shouldRun, !ignoring && Y); \
312 if (shouldRun && !ignoring) \
319 #define CPPUNIT_TEST(X) CPPUNIT_TEST_BASE(X, false)
320 #define CPPUNIT_EXPLICIT_TEST(X) CPPUNIT_TEST_BASE(X, true)
322 #define CDSUNIT_DECLARE_TEST(X) void X();
324 #define CPPUNIT_IGNORE \
327 #define CPPUNIT_STOP_IGNORE \
330 #define CPPUNIT_TEST_SUITE_END() endTestCase(); }
331 #define CPPUNIT_TEST_SUITE_END_PART() }
333 #define CPPUNIT_TEST_SUITE_REGISTRATION_(X, NAME) static X NAME
334 #define CPPUNIT_TEST_SUITE_REGISTRATION(X) CPPUNIT_TEST_SUITE_REGISTRATION_(X, local)
336 #define CPPUNIT_CHECK(X) \
338 Base::error("CPPUNIT_CHECK", #X, __FILE__, __LINE__); \
341 #define CPPUNIT_CHECK_CURRENT(X) \
343 CppUnitMini::TestCase::current_test()->error("CPPUNIT_CHECK", #X, __FILE__, __LINE__); \
346 #define CPPUNIT_CHECK_EX(X, Y) \
348 std::stringstream st ; \
349 st << #X << ": " << Y ; \
350 Base::error("CPPUNIT_CHECK", st.str().c_str(), __FILE__, __LINE__); \
353 #define CPPUNIT_CHECK_CURRENT_EX(X, Y) \
355 std::stringstream st ; \
356 st << #X << ": " << Y ; \
357 CppUnitMini::TestCase::current_test()->error("CPPUNIT_CHECK", st.str().c_str(), __FILE__, __LINE__); \
360 #define CPPUNIT_ASSERT(X) \
362 Base::error("CPPUNIT_ASSERT", #X, __FILE__, __LINE__); \
366 #define CPPUNIT_ASSERT_CURRENT(X) \
368 CppUnitMini::TestCase::current_test()->error("CPPUNIT_ASSERT", #X, __FILE__, __LINE__); \
373 #define CPPUNIT_ASSERT_EX(A, X) \
375 std::stringstream st ; \
376 st << #A << ": " << X ; \
377 Base::error("CPPUNIT_ASSERT", st.str().c_str(), __FILE__, __LINE__); \
381 #define CPPUNIT_FAIL { \
382 Base::error("CPPUNIT_FAIL", "", __FILE__, __LINE__); \
386 #define CPPUNIT_ASSERT_EQUAL(X, Y) \
388 Base::error("CPPUNIT_ASSERT_EQUAL", #X","#Y, __FILE__, __LINE__); \
392 #define CPPUNIT_ASSERT_DOUBLES_EQUAL(X, Y, Z) \
393 if (!equalDoubles((X), (Y), (Z))) { \
394 Base::error("CPPUNIT_ASSERT_DOUBLES_EQUAL", #X","#Y","#Z, __FILE__, __LINE__); \
399 #define CPPUNIT_MSG( X ) \
401 std::stringstream st ; \
403 if ( !st.str().empty() ) \
404 CppUnitMini::TestCase::message( st.str().c_str() ); \
407 #define CPPUNIT_MESSAGE(m) CppUnitMini::TestCase::message(m)
409 #define CPPUNIT_ASSERT_MSG( A, X ) \
411 std::stringstream st ; \
412 st << #A << ": " << X ; \
413 error( "CPPUNIT_ASSERT_MSG", st.str().c_str(), __FILE__, __LINE__ ) ; \
416 #endif // #ifndef CDS_CPPUNIT_MPFR_H_