summaryrefslogtreecommitdiff
path: root/src/cppunit/TestPath.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/cppunit/TestPath.cpp')
-rw-r--r--src/cppunit/TestPath.cpp236
1 files changed, 236 insertions, 0 deletions
diff --git a/src/cppunit/TestPath.cpp b/src/cppunit/TestPath.cpp
new file mode 100644
index 0000000..ecb89fd
--- /dev/null
+++ b/src/cppunit/TestPath.cpp
@@ -0,0 +1,236 @@
+#include <cppunit/Portability.h>
+#include <cppunit/Test.h>
+#include <cppunit/TestPath.h>
+#include <stdexcept>
+
+
+namespace CppUnit {
+
+
+TestPath::TestPath()
+{
+}
+
+
+TestPath::TestPath( Test *root )
+{
+ add( root );
+}
+
+
+TestPath::TestPath( const TestPath &other,
+ int indexFirst,
+ int count )
+{
+ int countAdjustment = 0;
+ if ( indexFirst < 0 )
+ {
+ countAdjustment = indexFirst;
+ indexFirst = 0;
+ }
+
+ if ( count < 0 )
+ count = other.getTestCount();
+ else
+ count += countAdjustment;
+
+ int index = indexFirst;
+ while ( count-- > 0 && index < other.getTestCount() )
+ add( other.getTestAt( index++ ) );
+}
+
+
+TestPath::TestPath( Test *searchRoot,
+ const std::string &pathAsString )
+{
+ PathTestNames testNames;
+
+ Test *parentTest = findActualRoot( searchRoot, pathAsString, testNames );
+ add( parentTest );
+
+ for ( int index = 1; index < testNames.size(); ++index )
+ {
+ bool childFound = false;
+ for ( int childIndex =0; childIndex < parentTest->getChildTestCount(); ++childIndex )
+ {
+ if ( parentTest->getChildTestAt( childIndex )->getName() == testNames[index] )
+ {
+ childFound = true;
+ parentTest = parentTest->getChildTestAt( childIndex );
+ break;
+ }
+ }
+
+ if ( !childFound )
+ throw std::invalid_argument( "TestPath::TestPath(): failed to resolve test name <"+
+ testNames[index] + "> of path <" + pathAsString + ">" );
+
+ add( parentTest );
+ }
+}
+
+
+TestPath::~TestPath()
+{
+}
+
+
+bool
+TestPath::isValid() const
+{
+ return getTestCount() > 0;
+}
+
+
+void
+TestPath::add( Test *test )
+{
+ _tests.push_back( test );
+}
+
+
+void
+TestPath::add( const TestPath &path )
+{
+ for ( int index =0; index < path.getTestCount(); ++index )
+ add( path.getTestAt( index ) );
+}
+
+
+void
+TestPath::insert( Test *test,
+ int index )
+{
+ if ( index < 0 || index > getTestCount() )
+ throw std::out_of_range( "TestPath::insert(): index out of range" );
+ _tests.insert( _tests.begin() + index, test );
+}
+
+void
+TestPath::insert( const TestPath &path,
+ int index )
+{
+ int itemIndex = path.getTestCount() -1;
+ while ( itemIndex >= 0 )
+ insert( path.getTestAt( itemIndex-- ), index );
+}
+
+
+void
+TestPath::removeTests()
+{
+ while ( isValid() )
+ removeTest( 0 );
+}
+
+
+void
+TestPath::removeTest( int index )
+{
+ checkIndexValid( index );
+ _tests.erase( _tests.begin() + index );
+}
+
+
+void
+TestPath::up()
+{
+ checkIndexValid( 0 );
+ removeTest( getTestCount() -1 );
+}
+
+
+int
+TestPath::getTestCount() const
+{
+ return _tests.size();
+}
+
+
+Test *
+TestPath::getTestAt( int index ) const
+{
+ checkIndexValid( index );
+ return _tests[index];
+}
+
+
+Test *
+TestPath::getChildTest() const
+{
+ return getTestAt( getTestCount() -1 );
+}
+
+
+void
+TestPath::checkIndexValid( int index ) const
+{
+ if ( index < 0 || index >= getTestCount() )
+ throw std::out_of_range( "TestPath::checkIndexValid(): index out of range" );
+}
+
+
+std::string
+TestPath::toString() const
+{
+ std::string asString( "/" );
+ for ( int index =0; index < getTestCount(); ++index )
+ {
+ if ( index > 0 )
+ asString += '/';
+ asString += getTestAt(index)->getName();
+ }
+
+ return asString;
+}
+
+
+Test *
+TestPath::findActualRoot( Test *searchRoot,
+ const std::string &pathAsString,
+ PathTestNames &testNames )
+{
+ bool isRelative = splitPathString( pathAsString, testNames );
+
+ if ( isRelative && pathAsString.empty() )
+ return searchRoot;
+
+ if ( testNames.empty() )
+ throw std::invalid_argument( "TestPath::TestPath(): invalid root or root name in absolute path" );
+
+ Test *root = isRelative ? searchRoot->findTest( testNames[0] ) // throw if bad test name
+ : searchRoot;
+ if ( root->getName() != testNames[0] )
+ throw std::invalid_argument( "TestPath::TestPath(): searchRoot does not match path root name" );
+
+ return root;
+}
+
+
+bool
+TestPath::splitPathString( const std::string &pathAsString,
+ PathTestNames &testNames )
+{
+ bool isRelative = (pathAsString.substr(0,1) != "/");
+
+ int index = (isRelative ? 0 : 1);
+ while ( true )
+ {
+ int separatorIndex = pathAsString.find( '/', index );
+ if ( separatorIndex >= 0 )
+ {
+ testNames.push_back( pathAsString.substr( index, separatorIndex - index ) );
+ index = separatorIndex + 1;
+ }
+ else
+ {
+ testNames.push_back( pathAsString.substr( index ) );
+ break;
+ }
+ }
+
+ return isRelative;
+}
+
+
+} // namespace CppUnit