00001 /*!@file TestSuite/TestSuite.H Class to manage a suite of tests */ 00002 00003 // //////////////////////////////////////////////////////////////////// // 00004 // The iLab Neuromorphic Vision C++ Toolkit - Copyright (C) 2001 by the // 00005 // University of Southern California (USC) and the iLab at USC. // 00006 // See http://iLab.usc.edu for information about this project. // 00007 // //////////////////////////////////////////////////////////////////// // 00008 // Major portions of the iLab Neuromorphic Vision Toolkit are protected // 00009 // under the U.S. patent ``Computation of Intrinsic Perceptual Saliency // 00010 // in Visual Environments, and Applications'' by Christof Koch and // 00011 // Laurent Itti, California Institute of Technology, 2001 (patent // 00012 // pending; application number 09/912,225 filed July 23, 2001; see // 00013 // http://pair.uspto.gov/cgi-bin/final/home.pl for current status). // 00014 // //////////////////////////////////////////////////////////////////// // 00015 // This file is part of the iLab Neuromorphic Vision C++ Toolkit. // 00016 // // 00017 // The iLab Neuromorphic Vision C++ Toolkit is free software; you can // 00018 // redistribute it and/or modify it under the terms of the GNU General // 00019 // Public License as published by the Free Software Foundation; either // 00020 // version 2 of the License, or (at your option) any later version. // 00021 // // 00022 // The iLab Neuromorphic Vision C++ Toolkit is distributed in the hope // 00023 // that it will be useful, but WITHOUT ANY WARRANTY; without even the // 00024 // implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // 00025 // PURPOSE. See the GNU General Public License for more details. // 00026 // // 00027 // You should have received a copy of the GNU General Public License // 00028 // along with the iLab Neuromorphic Vision C++ Toolkit; if not, write // 00029 // to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, // 00030 // Boston, MA 02111-1307 USA. // 00031 // //////////////////////////////////////////////////////////////////// // 00032 // 00033 // Primary maintainer for this file: Rob Peters <rjpeters@klab.caltech.edu> 00034 // $HeadURL: svn://isvn.usc.edu/software/invt/trunk/saliency/src/TestSuite/TestSuite.H $ 00035 // $Id: TestSuite.H 12962 2010-03-06 02:13:53Z irock $ 00036 // 00037 00038 #ifndef TESTSUITE_H_DEFINED 00039 #define TESTSUITE_H_DEFINED 00040 00041 #include "Util/StringConversions.H" 00042 #include "Util/Types.H" // for uint 00043 00044 #include <string> 00045 00046 class TestSuite; 00047 00048 typedef void (*TestFunc)(TestSuite&); 00049 00050 template <class T> class Image; 00051 00052 //! TestSuite manages a set of tests. 00053 /*! The tests can be run one at a time or all at once. Each "test" is a 00054 function whose signature matches the TestFunc typedef. Such functions 00055 receive a TestSuite as a reference parameter. This allows the 00056 TestFunc's to use TestSuite's diagnostic functions (such as require() 00057 and requireEq()) to verify whatever the test is testing. */ 00058 class TestSuite 00059 { 00060 TestSuite(const TestSuite&); // not allowed 00061 TestSuite& operator=(const TestSuite&); // not allowed 00062 00063 public: 00064 //! Default constructor builds an empty test suite. 00065 TestSuite(); 00066 00067 //! Destructor. 00068 ~TestSuite(); 00069 00070 //! Add a test to the test suite. 00071 /*! (Note that the ADD_TEST macro below makes it easier to have the string 00072 name of the function be the same as the C++ function name, without 00073 having to type it twice.) */ 00074 void addTest(const char* name, TestFunc func); 00075 00076 //! Print all the available tests to stdout. 00077 void printAvailableTests() const; 00078 00079 //! Print all the available tests to stdout. 00080 void printAvailableTestsForPerl() const; 00081 00082 //! Run a single test, optionally repeating it multiple times. 00083 /*! (Multiple repeats may be useful for profiling.) The output of the 00084 test is printed to standard output: on the first line is a boolean 00085 code indicating whether the test succeeded (code==1) or failed 00086 (code==0), and on subsequent lines are any diagnostic messages that 00087 may relate to the success or failure of the test (e.g., require() and 00088 requireEq() will generate a diagnostic message on failure). */ 00089 void runTest(int test_n, int repeat_n = 1); 00090 00091 //! Parse command-line args and take appropriate action. 00092 /*! This may involve either printing a list of available tests, or 00093 running a specific test. */ 00094 void parseAndRun(int argc, const char** argv); 00095 00096 //! Require that the expression evaluates to true. 00097 /** Return the truth value of the expression. */ 00098 bool require(bool expr, const char* srcfile, int line, const char* expr_str); 00099 00100 //! Different types of arithmetic conditions that can be required. 00101 enum Op 00102 { 00103 EQ, // == 00104 NEQ, // != 00105 LT, // < 00106 LTE, // <= 00107 GT, // > 00108 GTE // >= 00109 }; 00110 00111 //! Check that the given "int" expressions compare equal. 00112 /** Return the truth value of the comparison. */ 00113 bool requireEq(int expr, int expected, 00114 const char* srcfile, int line, const char* expr_str); 00115 00116 //! Check that the given "unsigned int" expressions compare equal. 00117 /** Return the truth value of the comparison. */ 00118 bool requireEq(uint expr, uint expected, 00119 const char* srcfile, int line, const char* expr_str); 00120 00121 //! Check that the given "long" expressions compare equal. 00122 /** Return the truth value of the comparison. */ 00123 bool requireEq(long expr, long expected, 00124 const char* srcfile, int line, const char* expr_str); 00125 00126 //! Check that the given "unsigned long" expressions compare equal. 00127 /** Return the truth value of the comparison. */ 00128 bool requireEq(unsigned long expr, unsigned long expected, 00129 const char* srcfile, int line, const char* expr_str); 00130 00131 //! Check that the given std::string expressions compare equal (as strings). 00132 /** Return the truth value of the comparison. */ 00133 bool requireEq(const std::string& expr, const std::string& expected, 00134 const char* srcfile, int line, const char* expr_str); 00135 00136 //! Check that the given "double" expressions compare equal. 00137 /** Return the truth value of the comparison. */ 00138 bool requireEq(double expr, double expected, 00139 const char* srcfile, int line, const char* expr_str); 00140 00141 //! Check that the expression "lhs OP rhs" is true. 00142 /** Return the truth value of the comparison. */ 00143 bool require(int lhs, Op op, int rhs, 00144 const char* srcfile, int line, 00145 const char* lhs_str, const char* rhs_str); 00146 00147 //! Check that the expression "lhs OP rhs" is true. 00148 /** Return the truth value of the comparison. */ 00149 bool require(long lhs, Op op, long rhs, 00150 const char* srcfile, int line, 00151 const char* lhs_str, const char* rhs_str); 00152 00153 //! Check that the expression "lhs OP rhs" is true. 00154 /** Return the truth value of the comparison. */ 00155 bool require(double lhs, Op op, double rhs, 00156 const char* srcfile, int line, 00157 const char* lhs_str, const char* rhs_str); 00158 00159 //! Check that the given Image objects compare equal. 00160 template <class T_or_RGB> 00161 /** Return the truth value of the comparison. */ 00162 bool requireEq(const Image<T_or_RGB>& expr, const Image<T_or_RGB>& expected, 00163 const char* srcfile, int line, const char* expr_str); 00164 00165 //! Check that the given Image objects compare equal to given precision 00166 /** Return the truth value of the comparison. */ 00167 bool requireEq(const Image<float>& expr, const Image<float>& expected, 00168 const float prec, const char* srcfile, int line, 00169 const char* expr_str); 00170 00171 //! Check that the given user-defined objects compare equal to given precision 00172 /** Return the truth value of the comparison. */ 00173 template <class T> 00174 bool requireEqUserType(const T& expr, const T& expected, 00175 const char* srcfile, int line, 00176 const char* expr_str) 00177 { 00178 return this->requireEqUserTypeImpl 00179 (expr == expected, 00180 convertToString(expr), 00181 convertToString(expected), 00182 srcfile, line, expr_str); 00183 } 00184 00185 private: 00186 bool requireEqUserTypeImpl(const bool ok, 00187 const std::string& expr, 00188 const std::string& expected, 00189 const char* srcfile, int line, 00190 const char* expr_str); 00191 00192 struct Impl; 00193 Impl* const rep; 00194 }; 00195 00196 #define ADD_TEST(x) addTest(#x, &x); 00197 00198 // These macros hackily assumes that "suite" is already declared as a local 00199 // variable (or function parameter, as it should be in the test functions) 00200 00201 #define REQUIRE_EQ(expr, targ) \ 00202 suite.requireEq((expr), (targ), __FILE__, __LINE__, #expr) 00203 00204 #define REQUIRE_EQFP(expr, targ, prec) \ 00205 suite.requireEq((expr), (targ), prec, __FILE__, __LINE__, #expr) 00206 00207 #define REQUIRE_EQ_USERTYPE(expr, targ) \ 00208 suite.requireEqUserType((expr), (targ), __FILE__, __LINE__, #expr) 00209 00210 #define REQUIRE(expr) \ 00211 suite.require((expr), __FILE__, __LINE__, #expr) 00212 00213 #define REQUIRE_NEQ(lhs, rhs) \ 00214 suite.require((lhs), TestSuite::NEQ, (rhs), __FILE__, __LINE__, #lhs, #rhs) 00215 00216 #define REQUIRE_LT(lhs, rhs) \ 00217 suite.require((lhs), TestSuite::LT, (rhs), __FILE__, __LINE__, #lhs, #rhs) 00218 00219 #define REQUIRE_LTE(lhs, rhs) \ 00220 suite.require((lhs), TestSuite::LTE, (rhs), __FILE__, __LINE__, #lhs, #rhs) 00221 00222 #define REQUIRE_GT(lhs, rhs) \ 00223 suite.require((lhs), TestSuite::GT, (rhs), __FILE__, __LINE__, #lhs, #rhs) 00224 00225 #define REQUIRE_GTE(lhs, rhs) \ 00226 suite.require((lhs), TestSuite::GTE, (rhs), __FILE__, __LINE__, #lhs, #rhs) 00227 00228 00229 /* So things look consistent in everyone's emacs... */ 00230 /* Local Variables: */ 00231 /* indent-tabs-mode: nil */ 00232 /* End: */ 00233 00234 #endif // !TESTSUITE_H_DEFINED