00001 #ifndef TEST_TEST_H 00002 #define TEST_TEST_H 00003 00011 #include <config.h> 00012 #include <QTextStream> 00013 #include <util/random.h> 00014 #include <util/vector.h> 00015 00016 #ifndef TEST_RESULT 00017 # define TEST_RESULT test::result 00018 #endif 00019 00028 #define CHECK( tst ) \ 00029 TEST_RESULT &= test::check(tst, __LINE__, #tst) 00030 00041 #define CHECK_EQUAL( tst, value ) \ 00042 TEST_RESULT &= test::check_equal(tst, value, __LINE__, #tst, #value) 00043 00054 #define CHECK_NOTEQUAL( tst, value ) \ 00055 TEST_RESULT &= test::check_notequal(tst, value, __LINE__, #tst, #value) 00056 00065 #define CHECK_FLOAT( tst, value, epsilon ) \ 00066 TEST_RESULT &= test::check_float(tst, value, epsilon, __LINE__, #tst, #value) 00067 00076 #define CHECK_FLOAT_DIFF( tst, value, epsilon ) \ 00077 TEST_RESULT &= test::check_float_diff(tst, value, epsilon, __LINE__, #tst, #value) 00078 00085 #define CHECK_ZERO( tst, epsilon ) \ 00086 TEST_RESULT &= test::check_zero(tst, epsilon, __LINE__, #tst) 00087 00098 #define TEST_FCT( tst, failed ) \ 00099 { \ 00100 bool _11532fd4s85fds_test_failed = !test_##tst(); \ 00101 if(_11532fd4s85fds_test_failed) \ 00102 { \ 00103 failed = true; \ 00104 test::out << #tst " test failed" << endl; \ 00105 setExitCode(10); \ 00106 } \ 00107 else \ 00108 test::out << #tst " test passed" << endl;\ 00109 } 00110 00111 #define FAILED_TEST(line, tst) \ 00112 test::out << "Test line " << line << " " << tst << " failed as "; 00113 00114 #define FAILED_FUNCTION(line) \ 00115 test::out << "Test line " << line << " " << __PRETTY_FUNCTION__ << "() failed as "; 00116 00120 namespace test 00121 { 00122 extern QTextStream out; 00123 extern bool result; 00124 00125 inline void resetResult() { result = true; } 00126 00127 template <size_t N, typename T> 00128 void shuffle(T array[]) 00129 { 00130 for(size_t i = 0 ; i < N ; ++i) 00131 { 00132 long int n = util::random(N-i); 00133 T dropped = array[i]; 00134 array[i] = array[n+i]; 00135 array[n+i] = dropped; 00136 } 00137 } 00138 00139 inline bool check(bool tst, size_t line_nb, const char* tst_str) 00140 { 00141 if(!tst) 00142 { 00143 test::out << "Test line " << line_nb << " " << tst_str << " failed" << endl; 00144 } 00145 return tst; 00146 } 00147 00148 template <typename T1, typename T2> 00149 bool check_equal(const T1& tst, const T2& value, size_t line_nb, 00150 const char* tst_str, const char* value_str) 00151 { 00152 if(not (tst == value)) 00153 { 00154 FAILED_TEST(line_nb, tst_str << " == " << value_str); 00155 test::out << tst_str << " = " << tst << " and " << value_str << " = " 00156 << value << endl; 00157 return false; 00158 } 00159 return true; 00160 } 00161 00162 template <typename T1, typename T2> 00163 bool check_notequal(const T1& tst, const T2& value, size_t line_nb, 00164 const char* tst_str, const char* value_str) 00165 { 00166 if(not (tst != value)) 00167 { 00168 FAILED_TEST(line_nb, tst_str << " != " << value_str); 00169 test::out << tst_str << " = " << tst << " and " << value_str << " = " 00170 << value << endl; 00171 return false; 00172 } 00173 return true; 00174 } 00175 00176 template <typename T1, typename T2, typename T3> 00177 bool check_float(const T1& tst, const T2& value, const T3& epsilon, size_t line_nb, 00178 const char* tst_str, const char* value_str) 00179 { 00180 if( util::norm(tst-value) > epsilon*std::max(util::norm(tst), util::norm(value)) ) 00181 { 00182 FAILED_TEST(line_nb, tst_str << " ~= " << value_str); 00183 test::out << tst_str << " = " << tst << " and " 00184 << value_str << " = " << value << endl; 00185 return false; 00186 } 00187 return true; 00188 } 00189 00190 template <typename T1, typename T2, typename T3> 00191 bool check_float_diff(const T1& tst, const T2& value, const T3& epsilon, size_t line_nb, 00192 const char* tst_str, const char* value_str) 00193 { 00194 if( util::norm(tst-value) <= epsilon*std::max(util::norm(tst), util::norm(value)) ) 00195 { 00196 FAILED_TEST(line_nb, tst_str << " != " << value_str); 00197 test::out << tst_str << " = " << tst << " and " 00198 << value_str << " = " << value << endl; 00199 return false; 00200 } 00201 return true; 00202 } 00203 00204 template <typename T1, typename T2> 00205 bool check_zero(const T1& tst, const T2& epsilon, size_t line_nb, 00206 const char* tst_str) 00207 { 00208 if( util::norm(tst) > epsilon ) 00209 { 00210 FAILED_TEST(line_nb, tst_str << " ~= 0"); 00211 test::out << tst_str << " = " << tst << endl; 00212 return false; 00213 } 00214 return true; 00215 } 00216 00217 } 00218 00219 #endif // TEST_TEST_H 00220