Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042 #ifndef TESTINGFRAMEWORK_HH
00043 #define TESTINGFRAMEWORK_HH
00044
00045
00051
00052
00053 #include "Config.hh"
00054 #include <iosfwd>
00055 #include <sstream>
00056 #include <vector>
00057 #include <algorithm>
00058 #include <stdexcept>
00059 #include <OpenMesh/Core/Utils/Noncopyable.hh>
00060
00061
00062
00063 namespace OpenMesh {
00064 namespace Utils {
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107 #define TH_VERIFY( expr, expt ) \
00108 verify( expr, expt, #expr )
00109
00110
00111 #define TH_VERIFY_X( expr, expt ) \
00112 verify_x( expr, expt, #expr )
00113
00117 class TestingFramework : Noncopyable
00118 {
00119 public:
00120
00121 typedef TestingFramework Self;
00122 typedef std::logic_error verify_error;
00123
00124 #ifndef DOXY_IGNORE_THIS
00125 class TestFunc
00126 {
00127 public:
00128 TestFunc( TestingFramework& _th, const std::string& _n )
00129 : th_(_th), name_(_n)
00130 {
00131 th_.reg(this);
00132 }
00133
00134 virtual ~TestFunc()
00135 { }
00136
00137 void operator() ( void )
00138 {
00139 prolog();
00140 try
00141 {
00142 body();
00143 }
00144 catch( std::exception& x )
00145 {
00146 std::cerr << "<<Error>>: Cannot proceed test due to failure of last"
00147 << " test: " << x.what() << std::endl;
00148 }
00149 catch(...)
00150 {
00151 std::cerr << "Fatal: cannot proceed test due to unknown error!"
00152 << std::endl;
00153 }
00154 epilog();
00155 }
00156
00157 const TestingFramework& testHelper() const { return th_; }
00158
00159 protected:
00160
00161 virtual void prolog(void)
00162 {
00163 begin(name_);
00164 }
00165
00166 virtual void body(void) = 0;
00167
00168 virtual void epilog(void)
00169 {
00170 end();
00171 }
00172
00173 protected:
00174
00175 TestingFramework& testHelper() { return th_; }
00176
00177 TestFunc( const TestFunc& _cpy ) : th_(_cpy.th_), name_(_cpy.name_) { }
00178
00179
00180
00181 TestFunc& begin(std::string _title, const std::string& _info = "")
00182 { th_.begin(_title,_info); return *this; }
00183
00184
00185
00186 TestFunc& end(void)
00187 { th_.end(); return *this; }
00188
00189
00190
00191
00192 template <typename ValueType>
00193 bool
00194 verify( const ValueType& _rc, const ValueType& _expected,
00195 std::string _info )
00196 { return th_.verify( _rc, _expected, _info ); }
00197
00198 template <typename ValueType>
00199 void
00200 verify_x( const ValueType& _rc, const ValueType& _expected,
00201 std::string _info )
00202 {
00203 if ( !verify(_rc, _expected, _info) )
00204 throw verify_error(_info);
00205 }
00206
00207 TestFunc& info(const std::string& _info)
00208 { th_.info(_info); return *this; }
00209
00210 TestFunc& info(const std::ostringstream& _ostr)
00211 { th_.info(_ostr); return *this; }
00212
00213 private:
00214 TestFunc();
00215
00216 protected:
00217 TestingFramework& th_;
00218 std::string name_;
00219 };
00220 #endif
00221
00222 typedef TestFunc* TestFuncPtr;
00223 typedef std::vector<TestFuncPtr> TestSet;
00224
00225 public:
00226
00227 TestingFramework(std::ostream& _os)
00228 : errTotal_(0), errCount_(0),
00229 verifyTotal_(0), verifyCount_(0),
00230 testTotal_(0), testCount_(0),
00231 os_(_os)
00232 { }
00233
00234 protected:
00235
00236 #ifndef DOXY_IGNORE_THIS
00237 struct TestDeleter
00238 {
00239 void operator() (TestFuncPtr _tfptr) { delete _tfptr; }
00240 };
00241 #endif
00242
00243 public:
00244
00245 virtual ~TestingFramework()
00246 {
00247 std::for_each(tests_.begin(), tests_.end(), TestDeleter() );
00248 }
00249
00250 public:
00251
00252 template <typename ValueType>
00253 bool verify(const ValueType& _rc,
00254 const ValueType& _expected,
00255 const std::string& _info)
00256 {
00257 ++verifyTotal_;
00258 if ( _rc == _expected )
00259 {
00260 os_ << " " << _info << ", result: " << _rc << ", OK!" << std::endl;
00261 return true;
00262 }
00263 ++errTotal_;
00264 os_ << " " << _info << ", result: " << _rc << " != " << _expected
00265 << " <<ERROR>>" << std::endl;
00266 return false;
00267 }
00268
00269 Self& begin(std::string _title, const std::string& _info = "")
00270 {
00271 std::ostringstream ostr;
00272
00273 testTitle_ = _title;
00274 errCount_ = errTotal_;
00275 ++testTotal_;
00276
00277 ostr << _title;
00278 if ( !_info.empty() )
00279 ostr << " ["<< _info << "]";
00280 testTitle_ = ostr.str();
00281 os_ << "Begin " << testTitle_ << std::endl;
00282 return *this;
00283 }
00284
00285 Self& end()
00286 {
00287 if (errorCount()==0)
00288 ++testCount_;
00289
00290 os_ << "End " << testTitle_ << ": " << errorCount() << " Error(s)." << std::endl;
00291 return *this;
00292 }
00293
00294 Self& info(const std::string& _info)
00295 {
00296 os_ << " + " << _info << std::endl;
00297 return *this;
00298 }
00299
00300 Self& info(const std::ostringstream& _ostr)
00301 {
00302 os_ << " + " << _ostr.str() << std::endl;
00303 return *this;
00304 }
00305
00306 size_t errorTotal() const { return errTotal_; }
00307 size_t errorCount() const { return errTotal_ - errCount_; }
00308 size_t verifyTotal() const { return verifyTotal_; }
00309 size_t verifyCount() const { return verifyTotal_ - verifyCount_; }
00310 size_t goodTotal() const { return verifyTotal() - errorTotal(); }
00311 size_t goodCount() const { return verifyCount() - errorCount(); }
00312
00313 size_t testTotal() const { return testTotal_; }
00314 size_t testCount() const { return testCount_; }
00315
00316 public:
00317
00318 int run(void)
00319 {
00320 os_ << "Test started\n";
00321 TestRunner executer;
00322 std::for_each(tests_.begin(), tests_.end(), executer );
00323 os_ << std::endl;
00324 os_ << "All tests completed" << std::endl
00325 << " #Tests: " << testCount() << "/" << testTotal() << std::endl
00326 << " #Errors: " << errorTotal() << "/" << verifyTotal() << std::endl;
00327 return errorTotal();
00328 }
00329
00330 protected:
00331
00332 #ifndef DOXY_IGNORE_THIS
00333 struct TestRunner
00334 {
00335 void operator() (TestFuncPtr _tfptr) { (*_tfptr)(); }
00336 };
00337 #endif
00338
00339 int reg(TestFuncPtr _tfptr)
00340 {
00341 tests_.push_back(_tfptr);
00342 return true;
00343 }
00344
00345 friend class TestFunc;
00346
00347 private:
00348
00349 size_t errTotal_;
00350 size_t errCount_;
00351 size_t verifyTotal_;
00352 size_t verifyCount_;
00353 size_t testTotal_;
00354 size_t testCount_;
00355
00356 std::string testTitle_;
00357 std::ostream& os_;
00358
00359 TestSet tests_;
00360
00361 };
00362
00363
00364 }
00365 }
00366
00367 #endif // TESTINGFRMEWORK_HH
00368