|
Rapicorn - Experimental UI Toolkit - Source Code 10.08.1
|
00001 /* Rapicorn 00002 * Copyright (C) 2008 Tim Janik 00003 * 00004 * This library is free software; you can redistribute it and/or 00005 * modify it under the terms of the GNU Lesser General Public 00006 * License as published by the Free Software Foundation; either 00007 * version 2.1 of the License, or (at your option) any later version. 00008 * 00009 * This library is distributed in the hope that it will be useful, 00010 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00012 * Lesser General Public License for more details. 00013 * 00014 * A copy of the GNU Lesser General Public License should ship along 00015 * with this library; if not, see http://www.gnu.org/copyleft/. 00016 */ 00017 #ifndef __RAPICORN_TESTUTILS_HH__ 00018 #define __RAPICORN_TESTUTILS_HH__ 00019 00020 #include <rcore/rcore.hh> 00021 00022 // Test Macros 00023 #define TTITLE(...) Rapicorn::Test::test_output (3, __VA_ARGS__) 00024 #define TSTART(...) Rapicorn::Test::test_output (4, __VA_ARGS__) 00025 #define TDONE() Rapicorn::Test::test_output (5, "%s", "") 00026 #define TOUT(...) Rapicorn::Test::test_output (0, __VA_ARGS__) 00027 #define TMSG(...) Rapicorn::Test::test_output (1, __VA_ARGS__) 00028 #define TINFO(...) Rapicorn::Test::test_output (2, __VA_ARGS__) 00029 #define TWARN(...) Rapicorn::Test::test_output (6, __VA_ARGS__) 00030 #define TRUN(name, func) ({ TSTART (name); func(); TDONE(); }) 00031 #define TCMP(a,cmp,b) TCMP_implf (a,cmp,b) 00032 #define TCMPHEX(a,cmp,b) TCMP_implx (a,cmp,b) 00033 #define TCMPSIGNED(a,cmp,b) TCMP_impls (a,cmp,b) 00034 #define TCHECK(code) TCHECK_impl (code) 00035 #define TASSERT(code) TCHECK_impl (code) 00036 #define TOK() do {} while (0) // printerr (".") 00037 #define TCHECK_impl(code) do { if (code) TOK(); else \ 00038 Rapicorn::Logging::message ("ABORT", RAPICORN__FILE__, __LINE__, RAPICORN__FUNC__.c_str(), \ 00039 "assertion failed: %s", #code); \ 00040 } while (0) 00041 #define TCMP_implf(a,cmp,b) do { if (a cmp b) TOK(); else { \ 00042 double __tassert_va = a; double __tassert_vb = b; \ 00043 Rapicorn::Logging::message ("ABORT", RAPICORN__FILE__, __LINE__, RAPICORN__FUNC__.c_str(), \ 00044 "assertion failed: %s %s %s: %.17g %s %.17g", \ 00045 #a, #cmp, #b, __tassert_va, #cmp, __tassert_vb); \ 00046 } } while (0) 00047 #define TCMP_implx(a,cmp,b) do { if (a cmp b) TOK(); else { \ 00048 uint64 __tassert_va = a; uint64 __tassert_vb = b; \ 00049 Rapicorn::Logging::message ("ABORT", RAPICORN__FILE__, __LINE__, RAPICORN__FUNC__.c_str(), \ 00050 "assertion failed: %s %s %s: 0x%08Lx %s 0x%08Lx", \ 00051 #a, #cmp, #b, __tassert_va, #cmp, __tassert_vb); \ 00052 } } while (0) 00053 #define TCMP_impls(a,cmp,b) do { if (a cmp b) TOK(); else { \ 00054 int64 __tassert_va = a; int64 __tassert_vb = b; \ 00055 Rapicorn::Logging::message ("ABORT", RAPICORN__FILE__, __LINE__, RAPICORN__FUNC__.c_str(), \ 00056 "assertion failed: %s %s %s: %lld %s %lld", \ 00057 #a, #cmp, #b, __tassert_va, #cmp, __tassert_vb); \ 00058 } } while (0) 00059 00060 namespace Rapicorn { 00061 00062 void init_core_test (const String &app_ident, int *argcp, char **argv, const StringVector &args = StringVector()); 00063 00064 namespace Test { 00065 00070 class Timer { 00071 const double m_deadline; 00072 vector<double> m_samples; 00073 double m_test_duration; 00074 int64 m_n_runs; 00075 int64 loops_needed () const; 00076 void reset (); 00077 void submit (double elapsed, int64 repetitions); 00078 static double bench_time (); 00079 public: 00081 explicit Timer (double deadline_in_secs = 0); 00082 virtual ~Timer (); 00083 int64 n_runs () const { return m_n_runs; } 00084 double test_elapsed () const { return m_test_duration; } 00085 double min_elapsed () const; 00086 double max_elapsed () const; 00087 template<typename Callee> 00088 double benchmark (Callee callee); 00089 }; 00090 00096 template<typename Callee> double 00097 Timer::benchmark (Callee callee) 00098 { 00099 reset(); 00100 for (int64 runs = loops_needed(); runs; runs = loops_needed()) 00101 { 00102 int64 n = runs; 00103 const double start = bench_time(); 00104 while (RAPICORN_LIKELY (n--)) 00105 callee(); 00106 const double stop = bench_time(); 00107 submit (stop - start, runs); 00108 } 00109 return min_elapsed(); 00110 } 00111 00112 // === test maintenance === 00113 int run (void); 00114 bool verbose (void); 00115 bool logging (void); 00116 bool slow (void); 00117 bool ui_test (void); 00118 00119 void test_output (int kind, const char *format, ...) RAPICORN_PRINTF (2, 3); 00120 00121 void add_internal (const String &testname, 00122 void (*test_func) (void*), 00123 void *data); 00124 void add (const String &funcname, 00125 void (*test_func) (void)); 00126 template<typename D> 00127 void add (const String &testname, 00128 void (*test_func) (D*), 00129 D *data) 00130 { 00131 add_internal (testname, (void(*)(void*)) test_func, (void*) data); 00132 } 00133 00134 class RegisterTest { 00135 static void add_test (char kind, const String &testname, void (*test_func) (void*), void *data); 00136 public: 00137 RegisterTest (const char k, const String &testname, void (*test_func) (void)) 00138 { add_test (k, testname, (void(*)(void*)) test_func, NULL); } 00139 RegisterTest (const char k, const String &testname, void (*test_func) (ptrdiff_t), ptrdiff_t data) 00140 { add_test (k, testname, (void(*)(void*)) test_func, (void*) data); } 00141 template<typename D> 00142 RegisterTest (const char k, const String &testname, void (*test_func) (D*), D *data) 00143 { add_test (k, testname, (void(*)(void*)) test_func, (void*) data); } 00144 typedef void (*TestTrigger) (void (*runner) (void)); 00145 static void test_set_trigger (TestTrigger func); 00146 }; 00147 00149 #define REGISTER_TEST(name, ...) static const Rapicorn::Test::RegisterTest \ 00150 RAPICORN_CPP_PASTE2 (__Rapicorn_RegisterTest__line, __LINE__) ('t', name, __VA_ARGS__) 00151 00153 #define REGISTER_SLOWTEST(name, ...) static const Rapicorn::Test::RegisterTest \ 00154 RAPICORN_CPP_PASTE2 (__Rapicorn_RegisterTest__line, __LINE__) ('s', name, __VA_ARGS__) 00155 00157 #define REGISTER_LOGTEST(name, ...) static const Rapicorn::Test::RegisterTest \ 00158 RAPICORN_CPP_PASTE2 (__Rapicorn_RegisterTest__line, __LINE__) ('l', name, __VA_ARGS__) 00159 00160 // == Deterministic random numbers for tests === 00161 char rand_bit (void); 00162 int32 rand_int (void); 00163 int32 rand_int_range (int32 begin, int32 end); 00164 double test_rand_double (void); 00165 double test_rand_double_range (double range_start, double range_end); 00166 00167 } // Test 00168 } // Rapicorn 00169 00170 #endif /* __RAPICORN_TESTUTILS_HH__ */
1.7.4