test_mgr.h

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>
00113       bool test_rel_arr(int nv, vec_t &result, vec_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{abs\_error}\f$
00147     */
00148     template<class vec_t>
00149       bool test_abs_arr(int nv, vec_t &result, vec_t &expected, 
00150                         double rel_error, std::string description) {
00151       bool ret=true;
00152       int i;
00153   
00154       for(i=0;i<nv;i++) {
00155         if (isnan(expected[i])) {
00156           ret=(ret && (isnan(expected[i])==isnan(result[i])));
00157         } else if (isinf(expected[i])) {
00158           ret=(ret && (isinf(expected[i])==isinf(result[i])));
00159         } else {
00160           ret=(ret && (fabs(expected[i]-result[i])<rel_error));
00161         }
00162       }
00163   
00164       process_test(ret,"absolute array",description);
00165   
00166       return ret;
00167     }
00168 
00169     /// Test for \f$1/factor<result/expected<factor\f$ ??
00170     template<class vec_t>
00171       bool test_fact_arr(int nv, vec_t &result, vec_t &expected, 
00172                          double factor, std::string description) {
00173       bool ret=true;
00174       int i;
00175       double ratio;
00176   
00177       for(i=0;i<nv;i++) {
00178         if (isnan(expected[i])) {
00179           ret=(ret && (isnan(expected[i])==isnan(result[i])));
00180         } else if (isinf(expected[i])) {
00181           ret=(ret && (isinf(expected[i])==isinf(result[i])));
00182         } else {
00183           ratio=expected[i]/result[i];
00184           ret=(ret && (ratio<factor && ratio>1.0/factor));
00185         }
00186       }
00187   
00188       process_test(ret,"factor array",description);
00189   
00190       return ret;
00191     }
00192 
00193     /// Test for \f$\mathrm{result}=\mathrm{expected}\f$
00194     bool test_int_arr(int nv, int *result, int *expected, 
00195                       std::string description);
00196     ///@}
00197 
00198     /// Add two test_mgr objects (if either failed, the sum fails)
00199     friend const test_mgr operator+(const test_mgr& left, 
00200                                     const test_mgr& right);
00201 
00202     /// True if all tests have passed
00203     bool success;
00204 
00205     /// The description of the last failed test
00206     std::string last_fail;
00207 
00208   };
00209 
00210 #ifndef DOXYGENP
00211 }
00212 #endif
00213 
00214 #endif

Documentation generated with Doxygen and provided under the GNU Free Documentation License. See License Information for details.

Project hosting provided by SourceForge.net Logo, O2scl Sourceforge Project Page