00001 /* 00002 ------------------------------------------------------------------- 00003 00004 Copyright (C) 2006, 2007, 2008, 2009, Andrew W. Steiner 00005 00006 This file is part of O2scl. 00007 00008 O2scl is free software; you can redistribute it and/or modify 00009 it under the terms of the GNU General Public License as published by 00010 the Free Software Foundation; either version 3 of the License, or 00011 (at your option) any later version. 00012 00013 O2scl is distributed in the hope that it will be useful, 00014 but WITHOUT ANY WARRANTY; without even the implied warranty of 00015 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00016 GNU General Public License for more details. 00017 00018 You should have received a copy of the GNU General Public License 00019 along with O2scl. If not, see <http://www.gnu.org/licenses/>. 00020 00021 ------------------------------------------------------------------- 00022 */ 00023 #ifndef O2SCL_TEST_MGR_H 00024 #define O2SCL_TEST_MGR_H 00025 #include <string> 00026 #include <o2scl/string_conv.h> 00027 00028 #ifndef DOXYGENP 00029 namespace o2scl { 00030 #endif 00031 00032 /** 00033 \brief A class to manage testing and record success and failure 00034 00035 \future test_mgr::success and test_mgr::last_fail should be protected, 00036 but that breaks the operator+() function. Can this be fixed? 00037 */ 00038 class test_mgr { 00039 00040 protected: 00041 00042 #ifndef DOXYGEN_INTERNAL 00043 00044 /// The number of tests performed 00045 int ntests; 00046 00047 /// The output level 00048 int output_level; 00049 00050 /// A helper function for processing tests 00051 void process_test(bool ret, std::string d2, std::string description); 00052 00053 #endif 00054 00055 public: 00056 00057 test_mgr() { 00058 success=true; 00059 ntests=0; 00060 output_level=0; 00061 } 00062 00063 /// Provide a report of all tests so far. 00064 00065 /// Returns true if all tests have passed and false if at least 00066 /// one test failed. 00067 bool report(); 00068 00069 /// Returns the description of the last test that failed. 00070 std::string get_last_fail() {return last_fail;}; 00071 00072 /// Set the output level 00073 00074 /// Possible values: 00075 /// - 0 = No output 00076 /// - 1 = Output only tests that fail 00077 /// - 2 = Output all tests 00078 void set_output_level(int l) {output_level=l;}; 00079 00080 /// Return the number of tests performed so far 00081 int get_ntests() {return ntests;}; 00082 00083 /// \name The testing methods 00084 ///@{ 00085 00086 /** \brief Test for \f$|\mathrm{result}-\mathrm{expected}|/ 00087 \mathrm{expected}<\mathrm{rel\_error}\f$ 00088 */ 00089 bool test_rel(double result, double expected, double rel_error, 00090 std::string description); 00091 00092 /** \brief Test for \f$|\mathrm{result}-\mathrm{expected}|/ 00093 <\mathrm{abs\_error}\f$ 00094 */ 00095 bool test_abs(double result, double expected, double abs_error, 00096 std::string description); 00097 00098 /// Test for \f$1/factor < result/expected < factor\f$ 00099 bool test_fact(double result, double expected, double factor, 00100 std::string description); 00101 00102 /// Test for \f$\mathrm{result}=\mathrm{expected}\f$ 00103 bool test_str(std::string result, std::string expected, 00104 std::string description); 00105 00106 /// Test for \f$\mathrm{result}=\mathrm{expected}\f$ 00107 bool test_gen(bool value, std::string description); 00108 00109 /** \brief Test for \f$|\mathrm{result}-\mathrm{expected}|/ 00110 \mathrm{expected}<\mathrm{rel\_error}\f$ over each element 00111 of an array 00112 */ 00113 template<class vec_t, class vec2_t> 00114 bool test_rel_arr(int nv, vec_t &result, vec2_t &expected, 00115 double rel_error, std::string description) { 00116 bool ret=true; 00117 double max=0.0; 00118 int i; 00119 00120 for(i=0;i<nv;i++) { 00121 if (isnan(expected[i])) { 00122 ret=(ret && (isnan(expected[i])==isnan(result[i]))); 00123 } else if (isinf(expected[i])) { 00124 ret=(ret && (isinf(expected[i])==isinf(result[i]))); 00125 } else if (expected[i]==0.0) { 00126 ret=(ret && test_abs(result[i],expected[i],rel_error,description)); 00127 if (fabs(result[i]-expected[i])>max) { 00128 max=fabs(result[i]-expected[i]); 00129 } 00130 } else { 00131 ret=(ret && ((fabs(expected[i]-result[i]))/ 00132 fabs(expected[i])<rel_error)); 00133 if (fabs(expected[i]-result[i])/fabs(expected[i])>max) { 00134 max=fabs(expected[i]-result[i])/fabs(expected[i]); 00135 } 00136 } 00137 } 00138 00139 process_test(ret,((std::string)"relative array, max=")+dtos(max), 00140 description); 00141 00142 return ret; 00143 00144 } 00145 00146 /** \brief Test for \f$|\mathrm{result}-\mathrm{expected}|/ 00147 \mathrm{expected}<\mathrm{rel\_error}\f$ over each element 00148 of an array 00149 */ 00150 template<class mat_t, class mat2_t> 00151 bool test_rel_mat(int nr, int nc, mat_t &result, mat2_t &expected, 00152 double rel_error, std::string description) { 00153 bool ret=true; 00154 double max=0.0; 00155 int i, j; 00156 00157 for(i=0;i<nr;i++) { 00158 for(j=0;j<nc;j++) { 00159 if (isnan(expected[i][j])) { 00160 ret=(ret && (isnan(expected[i][j])==isnan(result[i][j]))); 00161 } else if (isinf(expected[i][j])) { 00162 ret=(ret && (isinf(expected[i][j])==isinf(result[i][j]))); 00163 } else if (expected[i][j]==0.0) { 00164 ret=(ret && test_abs(result[i][j],expected[i][j],rel_error, 00165 description)); 00166 if (fabs(result[i][j]-expected[i][j])>max) { 00167 max=fabs(result[i][j]-expected[i][j]); 00168 } 00169 } else { 00170 ret=(ret && ((fabs(expected[i][j]-result[i][j]))/ 00171 fabs(expected[i][j])<rel_error)); 00172 if (fabs(expected[i][j]-result[i][j])/fabs(expected[i][j])>max) { 00173 max=fabs(expected[i][j]-result[i][j])/fabs(expected[i][j]); 00174 } 00175 } 00176 } 00177 } 00178 00179 process_test(ret,((std::string)"relative matrix, max=")+dtos(max), 00180 description); 00181 00182 return ret; 00183 00184 } 00185 00186 /** \brief Test for \f$|\mathrm{result}-\mathrm{expected}|/ 00187 <\mathrm{abs\_error}\f$ over each element 00188 of an array 00189 */ 00190 template<class vec_t, class vec2_t> 00191 bool test_abs_arr(int nv, vec_t &result, vec2_t &expected, 00192 double rel_error, std::string description) { 00193 bool ret=true; 00194 int i; 00195 00196 for(i=0;i<nv;i++) { 00197 if (isnan(expected[i])) { 00198 ret=(ret && (isnan(expected[i])==isnan(result[i]))); 00199 } else if (isinf(expected[i])) { 00200 ret=(ret && (isinf(expected[i])==isinf(result[i]))); 00201 } else { 00202 ret=(ret && (fabs(expected[i]-result[i])<rel_error)); 00203 } 00204 } 00205 00206 process_test(ret,"absolute array",description); 00207 00208 return ret; 00209 } 00210 00211 /** \brief Test for \f$ 1/factor < result/expected < factor \f$ 00212 over each element of an array 00213 */ 00214 template<class vec_t, class vec2_t> 00215 bool test_fact_arr(int nv, vec_t &result, vec2_t &expected, 00216 double factor, std::string description) { 00217 bool ret=true; 00218 int i; 00219 double ratio; 00220 00221 for(i=0;i<nv;i++) { 00222 if (isnan(expected[i])) { 00223 ret=(ret && (isnan(expected[i])==isnan(result[i]))); 00224 } else if (isinf(expected[i])) { 00225 ret=(ret && (isinf(expected[i])==isinf(result[i]))); 00226 } else { 00227 ratio=expected[i]/result[i]; 00228 ret=(ret && (ratio<factor && ratio>1.0/factor)); 00229 } 00230 } 00231 00232 process_test(ret,"factor array",description); 00233 00234 return ret; 00235 } 00236 00237 /// Test for equality of a generic array 00238 template<class vec_t> 00239 bool test_gen_arr(int nv, vec_t &result, vec_t &expected, 00240 std::string description) { 00241 bool ret=true; 00242 int i; 00243 00244 for(i=0;i<nv;i++) { 00245 ret=(ret && (result[i]==expected[i])); 00246 } 00247 00248 process_test(ret,"generic array",description); 00249 00250 return ret; 00251 } 00252 ///@} 00253 00254 /// Add two test_mgr objects (if either failed, the sum fails) 00255 friend const test_mgr operator+(const test_mgr& left, 00256 const test_mgr& right); 00257 00258 /// True if all tests have passed 00259 bool success; 00260 00261 /// The description of the last failed test 00262 std::string last_fail; 00263 00264 }; 00265 00266 #ifndef DOXYGENP 00267 } 00268 #endif 00269 00270 #endif
Documentation generated with Doxygen and provided under the GNU Free Documentation License. See License Information for details.
Project hosting provided by
,
O2scl Sourceforge Project Page