Moved UnitTestFramework from core osg lib into osgunittests example
This commit is contained in:
@@ -111,8 +111,6 @@ CXXFILES =\
|
||||
Timer.cpp\
|
||||
Transform.cpp\
|
||||
Uniform.cpp\
|
||||
UnitTestFramework.cpp\
|
||||
Vec3.cpp\
|
||||
Version.cpp\
|
||||
VertexProgram.cpp\
|
||||
View.cpp\
|
||||
|
||||
@@ -14,14 +14,6 @@
|
||||
#include <osg/Matrixd>
|
||||
#include <osg/Matrixf>
|
||||
|
||||
#ifdef OSG_COMPILE_UNIT_TESTS
|
||||
|
||||
|
||||
#include <osg/UnitTestFramework>
|
||||
|
||||
#include <sstream>
|
||||
#endif
|
||||
|
||||
// specialise Matrix_implementaiton to be Matrixd
|
||||
#define Matrix_implementation Matrixd
|
||||
|
||||
@@ -44,64 +36,3 @@ void osg::Matrixd::set(const osg::Matrixf& rhs)
|
||||
// now compile up Matrix via Matrix_implementation
|
||||
#include "Matrix_implementation.cpp"
|
||||
|
||||
//#if 1
|
||||
#ifdef OSG_COMPILE_UNIT_TESTS
|
||||
|
||||
#include <osg/Vec3>
|
||||
#include <osg/UnitTestFramework>
|
||||
|
||||
#include <sstream>
|
||||
|
||||
namespace osg
|
||||
{
|
||||
|
||||
class MatrixdTestFixture
|
||||
{
|
||||
public:
|
||||
|
||||
MatrixdTestFixture();
|
||||
|
||||
void testMatrixToQuat(const osgUtx::TestContext& ctx);
|
||||
|
||||
private:
|
||||
|
||||
// Some convenience variables for use in the tests
|
||||
Matrixd m1_, m2_;
|
||||
double l1_, l2_;
|
||||
|
||||
};
|
||||
|
||||
MatrixdTestFixture::MatrixdTestFixture():
|
||||
m1_(0.3583681546368404100000000000000, -0.933580347769909500000000000000, 3.006977197034146200000000000000e-011, 000000000000000,
|
||||
-0.933580347769909500000000000000, -0.3583681546368404100000000000000, -1.275368738108216700000000000000e-010, 000000000000000,
|
||||
1.298419676971558500000000000000e-010, 1.763260594230249800000000000000e-011, -0.9999999999999997800000000000000, 000000000000000,
|
||||
-4.134153519264493800000000000000e-005, 8.473552245044272300000000000000e-008, 0.9999996934706840700000000000000, 100000000000000.0 ),
|
||||
|
||||
m2_( 0.3583681546368407400000000000000, -0.9335803477699099500000000000000, 3.007582030796253300000000000000e-011, 000000000000000,
|
||||
-0.9335803477699099500000000000000, -0.3583681546368407400000000000000, -1.265511449721884600000000000000e-010, 000000000000000,
|
||||
1.289238781567697100000000000000e-010, 1.727370550828948600000000000000e-011, -1.000000000000000400000000000000, 000000000000000,
|
||||
-4.134153473360120600000000000000e-005, 8.473570190103158800000000000000e-008, 0.999999693471385400000000000000, 100000000000000.0),
|
||||
l1_(1),
|
||||
l2_(1)
|
||||
{
|
||||
}
|
||||
|
||||
void MatrixdTestFixture::testMatrixToQuat(const osgUtx::TestContext&)
|
||||
{
|
||||
Quat q1,q2;
|
||||
q1.set(m1_);
|
||||
q2.set(m2_);
|
||||
OSGUTX_TEST_F( q1.length() == l1_ )
|
||||
OSGUTX_TEST_F( q2.length() == l2_ )
|
||||
}
|
||||
|
||||
|
||||
OSGUTX_BEGIN_TESTSUITE(Matrixd)
|
||||
OSGUTX_ADD_TESTCASE(MatrixdTestFixture, testMatrixToQuat)
|
||||
OSGUTX_END_TESTSUITE
|
||||
|
||||
OSGUTX_AUTOREGISTER_TESTSUITE_AT(Matrixd, root.osg)
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,395 +0,0 @@
|
||||
/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield
|
||||
*
|
||||
* This library is open source and may be redistributed and/or modified under
|
||||
* the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
|
||||
* (at your option) any later version. The full license is in LICENSE file
|
||||
* included with this distribution, and on the openscenegraph.org website.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* OpenSceneGraph Public License for more details.
|
||||
*/
|
||||
#include <osg/UnitTestFramework>
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
namespace osgUtx
|
||||
{
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
TestContext::TestContext()
|
||||
{
|
||||
}
|
||||
|
||||
void TestContext::setTraceLevel(TraceLevel tl)
|
||||
{
|
||||
_tout.setTraceLevel(tl);
|
||||
}
|
||||
|
||||
TestContext::TraceLevel TestContext::getTraceLevel() const
|
||||
{
|
||||
return _tout.getTraceLevel();
|
||||
}
|
||||
|
||||
std::ostream& TestContext::tout(TraceLevel tl) const
|
||||
{
|
||||
return _tout.stream(tl);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
TestContext::TraceStream::TraceStream(std::ostream& o, TraceLevel tl):
|
||||
_traceLevel(tl),
|
||||
_outputStreamPtr(&o),
|
||||
#if defined(WIN32) && !(defined(__CYGWIN__) || defined(__MINGW32__))
|
||||
_nullStream("nul")
|
||||
#else
|
||||
_nullStream("/dev/null")
|
||||
#endif
|
||||
{
|
||||
}
|
||||
|
||||
TestContext::TraceStream::~TraceStream()
|
||||
{
|
||||
_nullStream.close();
|
||||
}
|
||||
|
||||
void TestContext::TraceStream::setTraceLevel(TraceLevel tl)
|
||||
{
|
||||
_traceLevel = tl;
|
||||
}
|
||||
|
||||
TestContext::TraceLevel TestContext::TraceStream::getTraceLevel() const
|
||||
{
|
||||
return _traceLevel;
|
||||
}
|
||||
|
||||
std::ostream& TestContext::TraceStream::stream(TestContext::TraceLevel tl)
|
||||
{
|
||||
if(_traceLevel >= tl){
|
||||
return *_outputStreamPtr;
|
||||
}
|
||||
return _nullStream;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
TestGraph& TestGraph::instance()
|
||||
{
|
||||
static TestGraph instance_;
|
||||
return instance_;
|
||||
}
|
||||
|
||||
TestSuite* TestGraph::root()
|
||||
{
|
||||
return root_.get();
|
||||
}
|
||||
|
||||
TestSuite* TestGraph::suite(const std::string& path, TestSuite* tsuite, bool createIfNecessary)
|
||||
{
|
||||
using namespace std;
|
||||
|
||||
list<string> pathComponents;
|
||||
|
||||
std::string::const_iterator it1 = path.begin();
|
||||
std::string::const_iterator it2 = it1;
|
||||
|
||||
// Dissect the path into it's constituent components
|
||||
do{
|
||||
|
||||
while( *it2 != '.' && it2 != path.end() ) ++it2;
|
||||
|
||||
// Consider a check for "" empty strings?
|
||||
pathComponents.push_back( std::string(it1,it2) );
|
||||
|
||||
if( it2 != path.end()) ++it2;
|
||||
|
||||
it1 = it2;
|
||||
|
||||
}while( it2 != path.end());
|
||||
|
||||
return suite(pathComponents.begin(), pathComponents.end(),
|
||||
tsuite, createIfNecessary);
|
||||
|
||||
}
|
||||
|
||||
TestSuite* TestGraph::suite(
|
||||
std::list<std::string>::iterator it,
|
||||
std::list<std::string>::iterator end,
|
||||
TestSuite* tsuite, bool createIfNecessary)
|
||||
{
|
||||
using namespace std;
|
||||
|
||||
if( ! tsuite) tsuite = root();
|
||||
|
||||
// Make sure these tie up
|
||||
if(*it != tsuite->name()) return 0;
|
||||
|
||||
++it;
|
||||
if(it == end) return tsuite;
|
||||
|
||||
Test* child = tsuite->findChild(*it);
|
||||
|
||||
if(child){
|
||||
|
||||
// We've found a child with the right name. But is it a
|
||||
// test suite?
|
||||
|
||||
if(TestSuite* childSuite = dynamic_cast<TestSuite*>(child)){
|
||||
return suite(it, end, childSuite, createIfNecessary);
|
||||
}
|
||||
|
||||
// We could return 0 here, to indicate that someone is
|
||||
// trying to add a TestSuite named 'xxx' to a suite with a
|
||||
// Test already named 'xxx'. But we don't enforce uniqueness
|
||||
// the other way round, so we don't do it this way round
|
||||
// either. Carry on as normal, and create a TestSuite of
|
||||
// the same name if createIfNecessary is true.
|
||||
|
||||
}
|
||||
|
||||
if(createIfNecessary){
|
||||
|
||||
TestSuite* childSuite = new TestSuite(*it);
|
||||
tsuite->add(childSuite);
|
||||
return suite(it, end, childSuite, createIfNecessary);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
TestGraph::TestGraph(): root_(new TestSuite("root"))
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
bool TestQualifier::visitEnter( TestSuite* pSuite )
|
||||
{
|
||||
_path.append( pSuite->name() );
|
||||
_path += SEPCHAR;
|
||||
return true;
|
||||
}
|
||||
|
||||
// Leaving a composite: Pop its name from the Path
|
||||
bool TestQualifier::visitLeave( TestSuite* pSuite )
|
||||
{
|
||||
// assert( _path.rfind( pSuite->name() + static_cast<const char>(SEPCHAR))
|
||||
// == _path.size() - pSuite->name().size() - 1);
|
||||
|
||||
_path.erase( _path.size() - pSuite->name().size() -1 );
|
||||
return true;
|
||||
}
|
||||
|
||||
// Provide read-only access to the current qualifier
|
||||
const std::string& TestQualifier::currentPath() const
|
||||
{
|
||||
return _path;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
osg::Timer TestRecord::timer_;
|
||||
|
||||
void TestRecord::start()
|
||||
{
|
||||
start_ = timer_.tick();
|
||||
}
|
||||
|
||||
void TestRecord::stop()
|
||||
{
|
||||
stop_ = timer_.tick();
|
||||
}
|
||||
|
||||
void TestRecord::log(const TestFailureX& e)
|
||||
{
|
||||
stop();
|
||||
result_ = Failure;
|
||||
problem_ = e.what();
|
||||
}
|
||||
|
||||
void TestRecord::log(const TestErrorX& e)
|
||||
{
|
||||
stop();
|
||||
result_ = Error;
|
||||
problem_ = e.what();
|
||||
}
|
||||
|
||||
void TestRecord::log(const std::exception& e)
|
||||
{
|
||||
stop();
|
||||
result_ = Error;
|
||||
problem_ = e.what();
|
||||
}
|
||||
|
||||
void TestRecord::log(const std::string& s)
|
||||
{
|
||||
stop();
|
||||
result_ = Error;
|
||||
problem_ = s;
|
||||
}
|
||||
|
||||
TestRecord::TestRecord(const std::string& name):
|
||||
name_(name),
|
||||
start_(0),
|
||||
stop_(0),
|
||||
result_(Success),
|
||||
problem_("No problem")
|
||||
{
|
||||
}
|
||||
|
||||
std::ostream& operator<<(std::ostream& o,const TestRecord& tr)
|
||||
{
|
||||
if(tr.result_ == TestRecord::Success) o<<"pass";
|
||||
else if(tr.result_ == TestRecord::Failure) o<<"fail";
|
||||
else o<<"error";
|
||||
|
||||
o<<"\t"<<tr.name_;
|
||||
|
||||
|
||||
//o<<tr.start_<<'\t'<<tr.stop_<<'\t'<<TestRecord::timer_.delta_s(tr.start_,tr.stop_);
|
||||
|
||||
// Just print out the duration
|
||||
o<<'\t'<<TestRecord::timer_.delta_s(tr.start_,tr.stop_)<<'s';
|
||||
|
||||
if(tr.result_ != TestRecord::Success){
|
||||
o<<'\t'<<tr.problem_;
|
||||
}
|
||||
|
||||
return o;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
TestRunner::TestRunner( TestContext& ctx ) : _ctx( ctx )
|
||||
{
|
||||
}
|
||||
|
||||
void TestRunner::specify( const std::string& sQualifiedName )
|
||||
{
|
||||
_tests.push_back( sQualifiedName );
|
||||
}
|
||||
|
||||
bool TestRunner::visitEnter( TestSuite* pSuite )
|
||||
{
|
||||
TestQualifier::visitEnter( pSuite );
|
||||
return !_ctx.shouldStop();
|
||||
}
|
||||
|
||||
#ifndef DOXYGEN_SHOULD_SKIP_THIS
|
||||
|
||||
namespace osgUtx{
|
||||
|
||||
struct isSpecified{
|
||||
|
||||
const std::string& pTestName_;
|
||||
|
||||
isSpecified(const std::string& s): pTestName_(s) {}
|
||||
|
||||
bool operator()(const std::string& specifiedTest){
|
||||
return pTestName_.find(specifiedTest) == 0;
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif /* DOXYGEN_SHOULD_SKIP_THIS */
|
||||
|
||||
bool TestRunner::visit( TestCase* pTest )
|
||||
{
|
||||
if ( std::find_if(_tests.begin(),_tests.end(),
|
||||
osgUtx::isSpecified(currentPath() + pTest->name() ) ) != _tests.end()) perform( pTest );
|
||||
|
||||
return !_ctx.shouldStop();
|
||||
}
|
||||
|
||||
bool TestRunner::visitLeave( TestSuite* pSuite )
|
||||
{
|
||||
TestQualifier::visitLeave( pSuite );
|
||||
return !_ctx.shouldStop();
|
||||
}
|
||||
|
||||
void TestRunner::perform( TestCase* pTest )
|
||||
{
|
||||
TestRecord& record = _db.createRecord( currentPath() + pTest->name() );
|
||||
|
||||
try
|
||||
{
|
||||
record.start();
|
||||
pTest->run( _ctx );
|
||||
record.stop();
|
||||
}
|
||||
|
||||
catch ( const TestFailureX& e )
|
||||
{
|
||||
record.log( e );
|
||||
}
|
||||
catch ( const TestErrorX& e )
|
||||
{
|
||||
record.log( e );
|
||||
}
|
||||
catch ( const std::exception& e )
|
||||
{
|
||||
record.log( e );
|
||||
}
|
||||
catch ( ... )
|
||||
{
|
||||
record.log( std::string("Unknown") );
|
||||
}
|
||||
|
||||
|
||||
_ctx.tout(TestContext::Results) << record << std::endl;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
TestSuite::TestSuite( const std::string& name ) : Test( name )
|
||||
{
|
||||
}
|
||||
|
||||
void TestSuite::add( Test* pTest )
|
||||
{
|
||||
_tests.push_back( pTest );
|
||||
}
|
||||
|
||||
Test* TestSuite::findChild(const std::string& name)
|
||||
{
|
||||
for(Tests::iterator it = _tests.begin();
|
||||
it != _tests.end();
|
||||
++it){
|
||||
|
||||
if ((*it)->name() == name) return (*it).get();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool TestSuite::accept( Test::Visitor& v )
|
||||
{
|
||||
if ( v.visitEnter( this ) )
|
||||
{
|
||||
Tests::iterator end = _tests.end();
|
||||
for ( Tests::iterator at = _tests.begin(); at != end; ++at )
|
||||
if ( !(*at)->accept( v ) )
|
||||
break;
|
||||
}
|
||||
|
||||
return v.visitLeave( this ); // continue with siblings?
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
bool QualifiedTestPrinter::visit( TestCase* pTest )
|
||||
{
|
||||
osg::notify(osg::NOTICE) << currentPath() + pTest->name() << std::endl;
|
||||
return true;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
};
|
||||
@@ -1,82 +0,0 @@
|
||||
/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield
|
||||
*
|
||||
* This library is open source and may be redistributed and/or modified under
|
||||
* the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
|
||||
* (at your option) any later version. The full license is in LICENSE file
|
||||
* included with this distribution, and on the openscenegraph.org website.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* OpenSceneGraph Public License for more details.
|
||||
*/
|
||||
// Vec3 is implemented entirely in the header. This .cpp file just
|
||||
// contains utx test code
|
||||
|
||||
#ifdef OSG_COMPILE_UNIT_TESTS
|
||||
|
||||
#include <osg/Vec3>
|
||||
#include <osg/UnitTestFramework>
|
||||
|
||||
#include <sstream>
|
||||
|
||||
namespace osg
|
||||
{
|
||||
|
||||
class Vec3TestFixture
|
||||
{
|
||||
public:
|
||||
|
||||
Vec3TestFixture();
|
||||
|
||||
void testAddition(const osgUtx::TestContext& ctx);
|
||||
void testSubtraction(const osgUtx::TestContext& ctx);
|
||||
void testScalarMultiplication(const osgUtx::TestContext& ctx);
|
||||
void testDotProduct(const osgUtx::TestContext& ctx);
|
||||
|
||||
private:
|
||||
|
||||
// Some convenience variables for use in the tests
|
||||
Vec3 v1_, v2_, v3_;
|
||||
|
||||
};
|
||||
|
||||
Vec3TestFixture::Vec3TestFixture():
|
||||
v1_(1.0f, 1.0f, 1.0f),
|
||||
v2_(2.0f, 2.0f, 2.0f),
|
||||
v3_(3.0f, 3.0f, 3.0f)
|
||||
{
|
||||
}
|
||||
|
||||
void Vec3TestFixture::testAddition(const osgUtx::TestContext&)
|
||||
{
|
||||
OSGUTX_TEST_F( v1_ + v2_ == v3_ )
|
||||
}
|
||||
|
||||
void Vec3TestFixture::testSubtraction(const osgUtx::TestContext&)
|
||||
{
|
||||
OSGUTX_TEST_F( v3_ - v1_ == v2_ )
|
||||
}
|
||||
|
||||
void Vec3TestFixture::testScalarMultiplication(const osgUtx::TestContext&)
|
||||
{
|
||||
OSGUTX_TEST_F( v1_ * 3 == v3_ )
|
||||
}
|
||||
|
||||
void Vec3TestFixture::testDotProduct(const osgUtx::TestContext&)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
OSGUTX_BEGIN_TESTSUITE(Vec3)
|
||||
OSGUTX_ADD_TESTCASE(Vec3TestFixture, testAddition)
|
||||
OSGUTX_ADD_TESTCASE(Vec3TestFixture, testSubtraction)
|
||||
OSGUTX_ADD_TESTCASE(Vec3TestFixture, testScalarMultiplication)
|
||||
OSGUTX_ADD_TESTCASE(Vec3TestFixture, testDotProduct)
|
||||
OSGUTX_END_TESTSUITE
|
||||
|
||||
OSGUTX_AUTOREGISTER_TESTSUITE_AT(Vec3, root.osg)
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user