00001 /* 00002 ------------------------------------------------------------------- 00003 00004 Copyright (C) 2006, 2007, 2008, 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$ 00111 */ 00112 template<class vec_t, class vec2_t> 00113 bool test_rel_arr(int nv, vec_t &result, vec2_t &expected, 00114 double rel_error, std::string description) { 00115 bool ret=true; 00116 double max=0.0; 00117 int i; 00118 00119 for(i=0;i<nv;i++) { 00120 if (isnan(expected[i])) { 00121 ret=(ret && (isnan(expected[i])==isnan(result[i]))); 00122 } else if (isinf(expected[i])) { 00123 ret=(ret && (isinf(expected[i])==isinf(result[i]))); 00124 } else if (expected[i]==0.0) { 00125 ret=(ret && test_abs(result[i],expected[i],rel_error,description)); 00126 if (fabs(result[i]-expected[i])>max) { 00127 max=fabs(result[i]-expected[i]); 00128 } 00129 } else { 00130 ret=(ret && ((fabs(expected[i]-result[i]))/ 00131 fabs(expected[i])<rel_error)); 00132 if (fabs(expected[i]-result[i])/fabs(expected[i])>max) { 00133 max=fabs(expected[i]-result[i])/fabs(expected[i]); 00134 } 00135 } 00136 } 00137 00138 process_test(ret,((std::string)"relative array, max=")+dtos(max), 00139 description); 00140 00141 return ret; 00142 00143 } 00144 00145 /** \brief Test for \f$|\mathrm{result}-\mathrm{expected}|/ 00146 \mathrm{expected}<\mathrm{rel\_error}\f$ 00147 */ 00148 template<class mat_t, class mat2_t> 00149 bool test_rel_mat(int nr, int nc, mat_t &result, mat2_t &expected, 00150 double rel_error, std::string description) { 00151 bool ret=true; 00152 double max=0.0; 00153 int i, j; 00154 00155 for(i=0;i<nr;i++) { 00156 for(j=0;j<nc;j++) { 00157 if (isnan(expected[i][j])) { 00158 ret=(ret && (isnan(expected[i][j])==isnan(result[i][j]))); 00159 } else if (isinf(expected[i][j])) { 00160 ret=(ret && (isinf(expected[i][j])==isinf(result[i][j]))); 00161 } else if (expected[i][j]==0.0) { 00162 ret=(ret && test_abs(result[i][j],expected[i][j],rel_error, 00163 description)); 00164 if (fabs(result[i][j]-expected[i][j])>max) { 00165 max=fabs(result[i][j]-expected[i][j]); 00166 } 00167 } else { 00168 ret=(ret && ((fabs(expected[i][j]-result[i][j]))/ 00169 fabs(expected[i][j])<rel_error)); 00170 if (fabs(expected[i][j]-result[i][j])/fabs(expected[i][j])>max) { 00171 max=fabs(expected[i][j]-result[i][j])/fabs(expected[i][j]); 00172 } 00173 } 00174 } 00175 } 00176 00177 process_test(ret,((std::string)"relative matrix, max=")+dtos(max), 00178 description); 00179 00180 return ret; 00181 00182 } 00183 00184 /** \brief Test for \f$|\mathrm{result}-\mathrm{expected}|/ 00185 <\mathrm{abs\_error}\f$ 00186 */ 00187 template<class vec_t, class vec2_t> 00188 bool test_abs_arr(int nv, vec_t &result, vec2_t &expected, 00189 double rel_error, std::string description) { 00190 bool ret=true; 00191 int i; 00192 00193 for(i=0;i<nv;i++) { 00194 if (isnan(expected[i])) { 00195 ret=(ret && (isnan(expected[i])==isnan(result[i]))); 00196 } else if (isinf(expected[i])) { 00197 ret=(ret && (isinf(expected[i])==isinf(result[i]))); 00198 } else { 00199 ret=(ret && (fabs(expected[i]-result[i])<rel_error)); 00200 } 00201 } 00202 00203 process_test(ret,"absolute array",description); 00204 00205 return ret; 00206 } 00207 00208 /// Test for \f$1/factor<result/expected<factor\f$ ?? 00209 template<class vec_t, class vec2_t> 00210 bool test_fact_arr(int nv, vec_t &result, vec2_t &expected, 00211 double factor, std::string description) { 00212 bool ret=true; 00213 int i; 00214 double ratio; 00215 00216 for(i=0;i<nv;i++) { 00217 if (isnan(expected[i])) { 00218 ret=(ret && (isnan(expected[i])==isnan(result[i]))); 00219 } else if (isinf(expected[i])) { 00220 ret=(ret && (isinf(expected[i])==isinf(result[i]))); 00221 } else { 00222 ratio=expected[i]/result[i]; 00223 ret=(ret && (ratio<factor && ratio>1.0/factor)); 00224 } 00225 } 00226 00227 process_test(ret,"factor array",description); 00228 00229 return ret; 00230 } 00231 00232 /// Test for equality of a generic array 00233 template<class vec_t> 00234 bool test_gen_arr(int nv, vec_t &result, vec_t &expected, 00235 std::string description) { 00236 bool ret=true; 00237 int i; 00238 00239 for(i=0;i<nv;i++) { 00240 ret=(ret && (result[i]==expected[i])); 00241 } 00242 00243 process_test(ret,"generic array",description); 00244 00245 return ret; 00246 } 00247 ///@} 00248 00249 /// Add two test_mgr objects (if either failed, the sum fails) 00250 friend const test_mgr operator+(const test_mgr& left, 00251 const test_mgr& right); 00252 00253 /// True if all tests have passed 00254 bool success; 00255 00256 /// The description of the last failed test 00257 std::string last_fail; 00258 00259 }; 00260 00261 #ifndef DOXYGENP 00262 } 00263 #endif 00264 00265 #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