Object-oriented Scientific Computing Library: Version 0.910
test_mgr.h
00001 /*
00002   -------------------------------------------------------------------
00003   
00004   Copyright (C) 2006-2012, 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   /** \brief A class to manage testing and record success and failure
00033 
00034       \future test_mgr::success and test_mgr::last_fail should be protected,
00035       but that breaks the operator+() function. Can this be fixed?
00036   */
00037   class test_mgr {
00038 
00039   protected:
00040 
00041 #ifndef DOXYGEN_INTERNAL
00042 
00043     /// The number of tests performed
00044     int ntests;
00045 
00046     /// The output level
00047     int output_level;
00048   
00049     /// A helper function for processing tests
00050     void process_test(bool ret, std::string d2, std::string description);
00051 
00052 #endif
00053   
00054   public:
00055 
00056     test_mgr() {
00057       success=true; 
00058       ntests=0; 
00059       output_level=1;
00060     }
00061 
00062     /** \brief Provide a report of all tests so far.
00063 
00064         Returns true if all tests have passed and false if at least
00065         one test failed.
00066     */
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     /** \brief 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     */
00079     void set_output_level(int l) { output_level=l; };
00080 
00081     /// Return the number of tests performed so far
00082     int get_ntests() {return ntests;};
00083 
00084     /// \name The testing methods
00085     ///@{
00086 
00087     /** \brief Test for \f$|\mathrm{result}-\mathrm{expected}|/
00088         \mathrm{expected}<\mathrm{rel\_error}\f$
00089     */
00090     bool test_rel(double result, double expected, double rel_error,
00091                   std::string description);
00092 
00093     /** \brief Test for \f$|\mathrm{result}-\mathrm{expected}|/
00094         <\mathrm{abs\_error}\f$
00095     */
00096     bool test_abs(double result, double expected, double abs_error,
00097                   std::string description);
00098 
00099     /** \brief  Test for \f$1/\mathrm{factor} < \mathrm{result/expected} 
00100         < \mathrm{factor}\f$
00101     */
00102     bool test_fact(double result, double expected, double factor,
00103                    std::string description);
00104 
00105     /// Test for \f$\mathrm{result}=\mathrm{expected}\f$
00106     bool test_str(std::string result, std::string expected, 
00107                   std::string description);
00108 
00109     /// Test for \f$\mathrm{result}=\mathrm{expected}\f$
00110     bool test_gen(bool value, std::string description);
00111 
00112     /** \brief Test for \f$|\mathrm{result}-\mathrm{expected}|/
00113         \mathrm{expected}<\mathrm{rel\_error}\f$ over each element
00114         of an array
00115     */
00116     template<class vec_t, class vec2_t>
00117       bool test_rel_arr(int nv, const vec_t &result, const vec2_t &expected, 
00118                         double rel_error, std::string description) {
00119       bool ret=true;
00120       double max=0.0;
00121       int i;
00122   
00123       for(i=0;i<nv;i++) {
00124         if (isnan(expected[i])) {
00125           ret=(ret && (isnan(expected[i])==isnan(result[i])));
00126         } else if (isinf(expected[i])) {
00127           ret=(ret && (isinf(expected[i])==isinf(result[i])));
00128         } else if (expected[i]==0.0) {
00129           ret=(ret && test_abs(result[i],expected[i],rel_error,description));
00130           if (fabs(result[i]-expected[i])>max) {
00131             max=fabs(result[i]-expected[i]);
00132           }
00133         } else {
00134           ret=(ret && ((fabs(expected[i]-result[i]))/
00135                        fabs(expected[i])<rel_error));
00136           if (fabs(expected[i]-result[i])/fabs(expected[i])>max) {
00137             max=fabs(expected[i]-result[i])/fabs(expected[i]);
00138           }
00139         }
00140       }
00141       
00142       process_test(ret,((std::string)"relative array, max=")+dtos(max),
00143                    description);
00144       
00145       return ret;
00146       
00147     }
00148     
00149     /** \brief Test for \f$|\mathrm{result}-\mathrm{expected}|/
00150         \mathrm{expected}<\mathrm{rel\_error}\f$ over each element
00151         of an array
00152     */
00153     template<class mat_t, class mat2_t>
00154       bool test_rel_mat(int nr, int nc, const mat_t &result, 
00155                         const mat2_t &expected, 
00156                         double rel_error, std::string description) {
00157       bool ret=true;
00158       double max=0.0;
00159       int i, j;
00160   
00161       for(i=0;i<nr;i++) {
00162         for(j=0;j<nc;j++) {
00163           if (isnan(expected[i][j])) {
00164             ret=(ret && (isnan(expected[i][j])==isnan(result[i][j])));
00165           } else if (isinf(expected[i][j])) {
00166             ret=(ret && (isinf(expected[i][j])==isinf(result[i][j])));
00167           } else if (expected[i][j]==0.0) {
00168             ret=(ret && test_abs(result[i][j],expected[i][j],rel_error,
00169                                  description));
00170             if (fabs(result[i][j]-expected[i][j])>max) {
00171               max=fabs(result[i][j]-expected[i][j]);
00172             }
00173           } else {
00174             ret=(ret && ((fabs(expected[i][j]-result[i][j]))/
00175                          fabs(expected[i][j])<rel_error));
00176             if (fabs(expected[i][j]-result[i][j])/fabs(expected[i][j])>max) {
00177               max=fabs(expected[i][j]-result[i][j])/fabs(expected[i][j]);
00178             }
00179           }
00180         }
00181       }
00182       
00183       process_test(ret,((std::string)"relative matrix, max=")+dtos(max),
00184                    description);
00185       
00186       return ret;
00187       
00188     }
00189     
00190     /** \brief Test for \f$|\mathrm{result}-\mathrm{expected}|/
00191         <\mathrm{abs\_error}\f$ over each element
00192         of an array
00193     */
00194     template<class vec_t, class vec2_t>
00195       bool test_abs_arr(int nv, const vec_t &result, const vec2_t &expected, 
00196                         double rel_error, std::string description) {
00197       bool ret=true;
00198       int i;
00199   
00200       for(i=0;i<nv;i++) {
00201         if (isnan(expected[i])) {
00202           ret=(ret && (isnan(expected[i])==isnan(result[i])));
00203         } else if (isinf(expected[i])) {
00204           ret=(ret && (isinf(expected[i])==isinf(result[i])));
00205         } else {
00206           ret=(ret && (fabs(expected[i]-result[i])<rel_error));
00207         }
00208       }
00209   
00210       process_test(ret,"absolute array",description);
00211   
00212       return ret;
00213     }
00214 
00215     /** \brief Test for \f$ 1/factor < result/expected < factor \f$ 
00216         over each element of an array
00217     */
00218     template<class vec_t, class vec2_t>
00219       bool test_fact_arr(int nv, const vec_t &result, const vec2_t &expected, 
00220                          double factor, std::string description) {
00221       bool ret=true;
00222       int i;
00223       double ratio;
00224   
00225       for(i=0;i<nv;i++) {
00226         if (isnan(expected[i])) {
00227           ret=(ret && (isnan(expected[i])==isnan(result[i])));
00228         } else if (isinf(expected[i])) {
00229           ret=(ret && (isinf(expected[i])==isinf(result[i])));
00230         } else {
00231           ratio=expected[i]/result[i];
00232           ret=(ret && (ratio<factor && ratio>1.0/factor));
00233         }
00234       }
00235   
00236       process_test(ret,"factor array",description);
00237   
00238       return ret;
00239     }
00240     
00241     /// Test for equality of a generic array
00242     template<class vec_t>
00243       bool test_gen_arr(int nv, const vec_t &result, const vec_t &expected, 
00244                         std::string description) {
00245       bool ret=true;
00246       int i;
00247       
00248       for(i=0;i<nv;i++) {
00249         ret=(ret && (result[i]==expected[i]));
00250       }
00251       
00252       process_test(ret,"generic array",description);
00253       
00254       return ret;
00255     }
00256     ///@}
00257 
00258     /// Add two test_mgr objects (if either failed, the sum fails)
00259     friend const test_mgr operator+(const test_mgr& left, 
00260                                     const test_mgr& right);
00261 
00262     /// True if all tests have passed
00263     bool success;
00264 
00265     /// The description of the last failed test
00266     std::string last_fail;
00267 
00268   };
00269 
00270 #ifndef DOXYGENP
00271 }
00272 #endif
00273 
00274 #endif
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines

Documentation generated with Doxygen. Provided under the GNU Free Documentation License (see License Information).

Get Object-oriented Scientific Computing
Lib at SourceForge.net. Fast, secure and Free Open Source software
downloads.