First checkin for OpenMesh 2.0
git-svn-id: http://www.openmesh.org/svnrepo/OpenMesh/trunk@2 fdac6126-5c0c-442c-9429-916003d36597
This commit is contained in:
330
Tools/Utils/TestingFramework.hh
Normal file
330
Tools/Utils/TestingFramework.hh
Normal file
@@ -0,0 +1,330 @@
|
||||
// ============================================================================
|
||||
// $Id: TestingFramework.hh,v 1.1.1.1 2006-10-25 16:14:15 habbecke Exp $
|
||||
// ----------------------------------------------------------------------------
|
||||
#ifndef TESTINGFRAMEWORK_HH
|
||||
#define TESTINGFRAMEWORK_HH
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
/** \file TestingFramework.hh
|
||||
This file contains a little framework for test programms
|
||||
*/
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
#include "Config.hh"
|
||||
#include <iosfwd>
|
||||
#include <sstream>
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
#include <stdexcept>
|
||||
#include <OpenMesh/Core/Utils/Noncopyable.hh>
|
||||
|
||||
// ------------------------------------------------------------- namespace ----
|
||||
|
||||
namespace OpenMesh { // BEGIN_NS_OPENMESH
|
||||
namespace Utils { // BEGIN_NS_UTILS
|
||||
|
||||
|
||||
// ----------------------------------------------------------------- class ----
|
||||
//
|
||||
// Usage Example
|
||||
//
|
||||
// #include <iostream>
|
||||
// #include <.../TestingFramework.hh>
|
||||
//
|
||||
// struct test_func : public TestingFramework::TestFunc
|
||||
// {
|
||||
// typedef test_func Self;
|
||||
//
|
||||
// // define ctor and copy-ctor
|
||||
// test_func( TestingFramework& _th, std::string _n ) : TestingFramework::TestFunc( _th, _n ) { }
|
||||
// test_func( Self& _cpy ) : TestingFramework::TestFunc(_cpy) { }
|
||||
//
|
||||
// // overload body()
|
||||
// void body()
|
||||
// {
|
||||
//
|
||||
// // Do the tests
|
||||
// // direct call to verify
|
||||
// verify( testResult, expectedResult, "additional information" );
|
||||
//
|
||||
// // or use the define TH_VERIFY. The test-expression will be used as the message string
|
||||
// TH_VERIFY( testResult, expectedResult );
|
||||
//
|
||||
// ...
|
||||
// }
|
||||
// };
|
||||
//
|
||||
// int main(...)
|
||||
// {
|
||||
// TestingFramework testSuite(std::cout); // send output to stdout
|
||||
//
|
||||
// new test_func(testSuite); // create new test instance. It registers with testSuite.
|
||||
// return testSuite.run();
|
||||
// }
|
||||
//
|
||||
|
||||
//
|
||||
#define TH_VERIFY( expr, expt ) \
|
||||
verify( expr, expt, #expr )
|
||||
|
||||
//
|
||||
#define TH_VERIFY_X( expr, expt ) \
|
||||
verify_x( expr, expt, #expr )
|
||||
|
||||
/** Helper class for test programms.
|
||||
\internal
|
||||
*/
|
||||
class TestingFramework : Noncopyable
|
||||
{
|
||||
public:
|
||||
|
||||
typedef TestingFramework Self;
|
||||
typedef std::logic_error verify_error;
|
||||
|
||||
#ifndef DOXY_IGNORE_THIS
|
||||
class TestFunc
|
||||
{
|
||||
public:
|
||||
TestFunc( TestingFramework& _th, const std::string& _n )
|
||||
: th_(_th), name_(_n)
|
||||
{
|
||||
th_.reg(this);
|
||||
}
|
||||
|
||||
virtual ~TestFunc()
|
||||
{ }
|
||||
|
||||
void operator() ( void )
|
||||
{
|
||||
prolog();
|
||||
try
|
||||
{
|
||||
body();
|
||||
}
|
||||
catch( std::exception& x )
|
||||
{
|
||||
std::cerr << "<<Error>>: Cannot proceed test due to failure of last"
|
||||
<< " test: " << x.what() << std::endl;
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
std::cerr << "Fatal: cannot proceed test due to unknown error!"
|
||||
<< std::endl;
|
||||
}
|
||||
epilog();
|
||||
}
|
||||
|
||||
const TestingFramework& testHelper() const { return th_; }
|
||||
|
||||
protected:
|
||||
|
||||
virtual void prolog(void)
|
||||
{
|
||||
begin(name_);
|
||||
}
|
||||
|
||||
virtual void body(void) = 0;
|
||||
|
||||
virtual void epilog(void)
|
||||
{
|
||||
end();
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
TestingFramework& testHelper() { return th_; }
|
||||
|
||||
TestFunc( const TestFunc& _cpy ) : th_(_cpy.th_), name_(_cpy.name_) { }
|
||||
|
||||
|
||||
// Use the following method in prolog()
|
||||
TestFunc& begin(std::string _title, const std::string& _info = "")
|
||||
{ th_.begin(_title,_info); return *this; }
|
||||
|
||||
|
||||
// Use the following method in epilog()
|
||||
TestFunc& end(void)
|
||||
{ th_.end(); return *this; }
|
||||
|
||||
|
||||
// Use the followin methods in body()
|
||||
|
||||
template <typename ValueType>
|
||||
bool
|
||||
verify( const ValueType& _rc, const ValueType& _expected,
|
||||
std::string _info )
|
||||
{ return th_.verify( _rc, _expected, _info ); }
|
||||
|
||||
template <typename ValueType>
|
||||
void
|
||||
verify_x( const ValueType& _rc, const ValueType& _expected,
|
||||
std::string _info )
|
||||
{
|
||||
if ( !verify(_rc, _expected, _info) )
|
||||
throw verify_error(_info);
|
||||
}
|
||||
|
||||
TestFunc& info(const std::string& _info)
|
||||
{ th_.info(_info); return *this; }
|
||||
|
||||
TestFunc& info(const std::ostringstream& _ostr)
|
||||
{ th_.info(_ostr); return *this; }
|
||||
|
||||
private:
|
||||
TestFunc();
|
||||
|
||||
protected:
|
||||
TestingFramework& th_;
|
||||
std::string name_;
|
||||
};
|
||||
#endif
|
||||
|
||||
typedef TestFunc* TestFuncPtr;
|
||||
typedef std::vector<TestFuncPtr> TestSet;
|
||||
|
||||
public:
|
||||
|
||||
TestingFramework(std::ostream& _os)
|
||||
: errTotal_(0), errCount_(0),
|
||||
verifyTotal_(0), verifyCount_(0),
|
||||
testTotal_(0), testCount_(0),
|
||||
os_(_os)
|
||||
{ }
|
||||
|
||||
protected:
|
||||
|
||||
#ifndef DOXY_IGNORE_THIS
|
||||
struct TestDeleter
|
||||
{
|
||||
void operator() (TestFuncPtr _tfptr) { delete _tfptr; }
|
||||
};
|
||||
#endif
|
||||
|
||||
public:
|
||||
|
||||
virtual ~TestingFramework()
|
||||
{
|
||||
std::for_each(tests_.begin(), tests_.end(), TestDeleter() );
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
template <typename ValueType>
|
||||
bool verify(const ValueType& _rc,
|
||||
const ValueType& _expected,
|
||||
const std::string& _info)
|
||||
{
|
||||
++verifyTotal_;
|
||||
if ( _rc == _expected )
|
||||
{
|
||||
os_ << " " << _info << ", result: " << _rc << ", OK!" << std::endl;
|
||||
return true;
|
||||
}
|
||||
++errTotal_;
|
||||
os_ << " " << _info << ", result: " << _rc << " != " << _expected
|
||||
<< " <<ERROR>>" << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
Self& begin(std::string _title, const std::string& _info = "")
|
||||
{
|
||||
std::ostringstream ostr;
|
||||
|
||||
testTitle_ = _title;
|
||||
errCount_ = errTotal_;
|
||||
++testTotal_;
|
||||
|
||||
ostr << _title;
|
||||
if ( !_info.empty() )
|
||||
ostr << " ["<< _info << "]";
|
||||
testTitle_ = ostr.str();
|
||||
os_ << "Begin " << testTitle_ << std::endl;
|
||||
return *this;
|
||||
}
|
||||
|
||||
Self& end()
|
||||
{
|
||||
if (errorCount()==0)
|
||||
++testCount_;
|
||||
|
||||
os_ << "End " << testTitle_ << ": " << errorCount() << " Error(s)." << std::endl;
|
||||
return *this;
|
||||
}
|
||||
|
||||
Self& info(const std::string& _info)
|
||||
{
|
||||
os_ << " + " << _info << std::endl;
|
||||
return *this;
|
||||
}
|
||||
|
||||
Self& info(const std::ostringstream& _ostr)
|
||||
{
|
||||
os_ << " + " << _ostr.str() << std::endl;
|
||||
return *this;
|
||||
}
|
||||
|
||||
size_t errorTotal() const { return errTotal_; }
|
||||
size_t errorCount() const { return errTotal_ - errCount_; }
|
||||
size_t verifyTotal() const { return verifyTotal_; }
|
||||
size_t verifyCount() const { return verifyTotal_ - verifyCount_; }
|
||||
size_t goodTotal() const { return verifyTotal() - errorTotal(); }
|
||||
size_t goodCount() const { return verifyCount() - errorCount(); }
|
||||
|
||||
size_t testTotal() const { return testTotal_; }
|
||||
size_t testCount() const { return testCount_; }
|
||||
|
||||
public:
|
||||
|
||||
int run(void)
|
||||
{
|
||||
os_ << "Test started\n";
|
||||
TestRunner executer;
|
||||
std::for_each(tests_.begin(), tests_.end(), executer );
|
||||
os_ << std::endl;
|
||||
os_ << "All tests completed" << std::endl
|
||||
<< " #Tests: " << testCount() << "/" << testTotal() << std::endl
|
||||
<< " #Errors: " << errorTotal() << "/" << verifyTotal() << std::endl;
|
||||
return errorTotal();
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
#ifndef DOXY_IGNORE_THIS
|
||||
struct TestRunner
|
||||
{
|
||||
void operator() (TestFuncPtr _tfptr) { (*_tfptr)(); }
|
||||
};
|
||||
#endif
|
||||
|
||||
int reg(TestFuncPtr _tfptr)
|
||||
{
|
||||
tests_.push_back(_tfptr);
|
||||
return true;
|
||||
}
|
||||
|
||||
friend class TestFunc;
|
||||
|
||||
private:
|
||||
|
||||
size_t errTotal_;
|
||||
size_t errCount_;
|
||||
size_t verifyTotal_;
|
||||
size_t verifyCount_;
|
||||
size_t testTotal_; // #Tests
|
||||
size_t testCount_; // #Tests ohne Fehler
|
||||
|
||||
std::string testTitle_;
|
||||
std::ostream& os_;
|
||||
|
||||
TestSet tests_;
|
||||
|
||||
};
|
||||
|
||||
// ============================================================================
|
||||
} // END_NS_UTILS
|
||||
} // END_NS_OPENMESH
|
||||
// ============================================================================
|
||||
#endif // TESTINGFRMEWORK_HH
|
||||
// ============================================================================
|
||||
Reference in New Issue
Block a user