diff options
Diffstat (limited to 'src/cppunit')
| -rw-r--r-- | src/cppunit/Makefile.am | 8 | ||||
| -rw-r--r-- | src/cppunit/RepeatedTest.cpp | 9 | ||||
| -rw-r--r-- | src/cppunit/Test.cpp | 93 | ||||
| -rw-r--r-- | src/cppunit/TestCase.cpp | 118 | ||||
| -rw-r--r-- | src/cppunit/TestComposite.cpp | 53 | ||||
| -rw-r--r-- | src/cppunit/TestFailure.cpp | 8 | ||||
| -rw-r--r-- | src/cppunit/TestLeaf.cpp | 28 | ||||
| -rw-r--r-- | src/cppunit/TestPath.cpp | 236 | ||||
| -rw-r--r-- | src/cppunit/TestRunner.cpp | 180 | ||||
| -rw-r--r-- | src/cppunit/TestSuite.cpp | 70 | ||||
| -rw-r--r-- | src/cppunit/TextTestRunner.cpp | 181 | ||||
| -rw-r--r-- | src/cppunit/XmlOutputter.cpp | 26 | ||||
| -rw-r--r-- | src/cppunit/cppunit.dsp | 44 | ||||
| -rw-r--r-- | src/cppunit/cppunit_dll.dsp | 32 |
14 files changed, 797 insertions, 289 deletions
diff --git a/src/cppunit/Makefile.am b/src/cppunit/Makefile.am index 8b239de..3675c00 100644 --- a/src/cppunit/Makefile.am +++ b/src/cppunit/Makefile.am @@ -1,5 +1,5 @@ # -# $Id: Makefile.am,v 1.19 2002-03-28 15:47:08 blep Exp $ +# $Id: Makefile.am,v 1.20 2002-04-12 19:28:47 blep Exp $ # EXTRA_DIST = cppunit.dsw cppunit.dsp cppunit_dll.dsp DllMain.cpp @@ -15,19 +15,25 @@ libcppunit_la_SOURCES = \ RepeatedTest.cpp \ SourceLine.cpp \ SynchronizedObject.cpp \ + Test.cpp \ TestAssert.cpp \ TestCase.cpp \ + TestComposite.cpp \ TestFactoryRegistry.cpp \ TestFailure.cpp \ + TestLeaf.cpp \ + TestPath.cpp \ TestResult.cpp \ TestResultCollector.cpp \ TestRunner.cpp \ TestSetUp.cpp \ TestSucessListener.cpp \ TestSuite.cpp \ + TestTest.cpp \ TextOutputter.cpp \ TextTestProgressListener.cpp \ TextTestResult.cpp \ + TextTestRunner.cpp \ TypeInfoHelper.cpp \ XmlOutputter.cpp diff --git a/src/cppunit/RepeatedTest.cpp b/src/cppunit/RepeatedTest.cpp index bfe1f72..58b1805 100644 --- a/src/cppunit/RepeatedTest.cpp +++ b/src/cppunit/RepeatedTest.cpp @@ -9,17 +9,10 @@ namespace CppUnit { int RepeatedTest::countTestCases() const { - return TestDecorator::countTestCases () * m_timesRepeat; + return TestDecorator::countTestCases() * m_timesRepeat; } -// Returns the name of the test instance. -std::string -RepeatedTest::toString() const -{ - return TestDecorator::toString () + " (repeated)"; -} - // Runs a repeated test void RepeatedTest::run( TestResult *result ) diff --git a/src/cppunit/Test.cpp b/src/cppunit/Test.cpp new file mode 100644 index 0000000..b751bad --- /dev/null +++ b/src/cppunit/Test.cpp @@ -0,0 +1,93 @@ +#include <cppunit/Portability.h> +#include <cppunit/Test.h> +#include <cppunit/TestPath.h> +#include <stdexcept> + + +namespace CppUnit { + +Test * +Test::getChildTestAt( int index ) const +{ + checkIsValidIndex( index ); + return doGetChildTestAt( index ); +} + + +Test * +Test::findTest( const std::string &testName ) const +{ + TestPath path; + // since path is discarded, it is really a const method. + const_cast<Test *>(this)->findTestPath( testName, path ); + if ( !path.isValid() ) + throw std::invalid_argument( "No test named <" + testName + "> found in test <" + + getName() + ">." ); + return path.getChildTest(); +} + + +bool +Test::findTestPath( const std::string &testName, + TestPath &testPath ) +{ + if ( getName() == testName ) + { + testPath.add( this ); + return true; + } + + int childCount = getChildTestCount(); + for ( int childIndex =0; childIndex < childCount; ++childIndex ) + { + if ( getChildTestAt( childIndex )->findTestPath( testName, testPath ) ) + { + testPath.insert( this, 0 ); + return true; + } + } + + return false; +} + + +bool +Test::findTestPath( const Test *test, + TestPath &testPath ) +{ + if ( this == test ) + { + testPath.add( this ); + return true; + } + + int childCount = getChildTestCount(); + for ( int childIndex =0; childIndex < childCount; ++childIndex ) + { + if ( getChildTestAt( childIndex )->findTestPath( test, testPath ) ) + { + testPath.insert( this, 0 ); + return true; + } + } + + return false; +} + + +TestPath +Test::resolveTestPath( const std::string &testPath ) +{ + return TestPath( this, testPath ); +} + + +void +Test::checkIsValidIndex( int index ) const +{ + if ( index < 0 || index >= getChildTestCount() ) + throw std::out_of_range( "Test::checkValidIndex(): invalid index" ); +} + + +} // namespace CppUnit diff --git a/src/cppunit/TestCase.cpp b/src/cppunit/TestCase.cpp index b2edb90..4fb388a 100644 --- a/src/cppunit/TestCase.cpp +++ b/src/cppunit/TestCase.cpp @@ -2,19 +2,21 @@ #include <typeinfo> #include <stdexcept> -#include "cppunit/TestCase.h" -#include "cppunit/Exception.h" -#include "cppunit/TestResult.h" +#include <cppunit/TestCase.h> +#include <cppunit/Exception.h> +#include <cppunit/TestResult.h> namespace CppUnit { -/// Create a default TestResult -CppUnit::TestResult* -TestCase::defaultResult() -{ - return new TestResult; -} + +/** Constructs a test case. + * \param name the name of the TestCase. + **/ +TestCase::TestCase( const std::string &name ) + : m_name(name) +{ +} /// Run the test and catch any exceptions that are triggered by it @@ -24,49 +26,38 @@ TestCase::run( TestResult *result ) result->startTest(this); try { - setUp(); - - try { - runTest(); - } - catch ( Exception &e ) { - Exception *copy = e.clone(); - result->addFailure( this, copy ); - } - catch ( std::exception &e ) { - result->addError( this, new Exception( e.what() ) ); - } - catch (...) { - Exception *e = new Exception( "caught unknown exception" ); - result->addError( this, e ); - } - - try { - tearDown(); - } - catch (...) { - result->addError( this, new Exception( "tearDown() failed" ) ); - } + setUp(); + + try { + runTest(); + } + catch ( Exception &e ) { + Exception *copy = e.clone(); + result->addFailure( this, copy ); + } + catch ( std::exception &e ) { + result->addError( this, new Exception( e.what() ) ); + } + catch (...) { + Exception *e = new Exception( "caught unknown exception" ); + result->addError( this, e ); + } + + try { + tearDown(); + } + catch (...) { + result->addError( this, new Exception( "tearDown() failed" ) ); + } } catch (...) { - result->addError( this, new Exception( "setUp() failed" ) ); + result->addError( this, new Exception( "setUp() failed" ) ); } result->endTest( this ); } -/// A default run method -TestResult * -TestCase::run() -{ - TestResult *result = defaultResult(); - - run (result); - return result; -} - - /// All the work for runTest is deferred to subclasses void TestCase::runTest() @@ -74,17 +65,11 @@ TestCase::runTest() } -/** Constructs a test case. - * \param name the name of the TestCase. - **/ -TestCase::TestCase( std::string name ) - : m_name(name) -{ -} - - /** Constructs a test case for a suite. - * This TestCase is intended for use by the TestCaller and should not + * \deprecated This constructor was used by fixture when TestFixture did not exist. + * Have your fixture inherits TestFixture instead of TestCase. + * \internal + * This TestCase was intended for use by the TestCaller and should not * be used by a test case for which run() is called. **/ TestCase::TestCase() @@ -99,37 +84,12 @@ TestCase::~TestCase() } -/// Returns a count of all the tests executed -int -TestCase::countTestCases() const -{ - return 1; -} - - /// Returns the name of the test case std::string TestCase::getName() const { return m_name; } - - -/// Returns the name of the test case instance -std::string -TestCase::toString() const -{ - std::string className; - -#if CPPUNIT_USE_TYPEINFO_NAME - const std::type_info& thisClass = typeid( *this ); - className = thisClass.name(); -#else - className = "TestCase"; -#endif - - return className + "." + getName(); -} } // namespace CppUnit diff --git a/src/cppunit/TestComposite.cpp b/src/cppunit/TestComposite.cpp new file mode 100644 index 0000000..e5f38c3 --- /dev/null +++ b/src/cppunit/TestComposite.cpp @@ -0,0 +1,53 @@ +#include <cppunit/TestComposite.h> +#include <cppunit/TestResult.h> + + +namespace CppUnit { + +TestComposite::TestComposite( const std::string &name ) + : m_name( name ) +{ +} + + +TestComposite::~TestComposite() +{ +} + + +void +TestComposite::run( TestResult *result ) +{ + int childCount = getChildTestCount(); + for ( int index =0; index < childCount; ++index ) + { + if ( result->shouldStop() ) + break; + + getChildTestAt( index )->run( result ); + } +} + + +int +TestComposite::countTestCases() const +{ + int count = 0; + + int childCount = getChildTestCount(); + for ( int index =0; index < childCount; ++index ) + count += getChildTestAt( index )->countTestCases(); + + return count; +} + + +std::string +TestComposite::getName() const +{ + return m_name; +} + + +} // namespace CppUnit + diff --git a/src/cppunit/TestFailure.cpp b/src/cppunit/TestFailure.cpp index 8404427..474761d 100644 --- a/src/cppunit/TestFailure.cpp +++ b/src/cppunit/TestFailure.cpp @@ -60,14 +60,6 @@ TestFailure::failedTestName() const } -/// Returns a short description of the failure. -std::string -TestFailure::toString() const -{ - return m_failedTest->toString() + ": " + m_thrownException->what(); -} - - TestFailure * TestFailure::clone() const { diff --git a/src/cppunit/TestLeaf.cpp b/src/cppunit/TestLeaf.cpp new file mode 100644 index 0000000..80160cb --- /dev/null +++ b/src/cppunit/TestLeaf.cpp @@ -0,0 +1,28 @@ +#include <cppunit/TestLeaf.h> + + +namespace CppUnit { + + +int +TestLeaf::countTestCases() const +{ + return 1; +} + + +int +TestLeaf::getChildTestCount() const +{ + return 0; +} + + +Test * +TestLeaf::doGetChildTestAt( int index ) const +{ + checkIsValidIndex( index ); + return NULL; // never called, checkIsValidIndex() always throw. +} + +} // namespace CppUnit 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 diff --git a/src/cppunit/TestRunner.cpp b/src/cppunit/TestRunner.cpp index 44c11d9..9bce34d 100644 --- a/src/cppunit/TestRunner.cpp +++ b/src/cppunit/TestRunner.cpp @@ -1,179 +1,99 @@ -#include <cppunit/TestSuite.h> -#include <cppunit/TextTestResult.h> -#include <cppunit/TextOutputter.h> -#include <cppunit/TextTestProgressListener.h> -#include <cppunit/TestResult.h> -#include <cppunit/ui/text/TestRunner.h> -#include <iostream> - - -namespace CppUnit { -namespace TextUi { - -/*! Constructs a new text runner. - * \param outputter used to print text result. Owned by the runner. - */ -TestRunner::TestRunner( Outputter *outputter ) - : m_outputter( outputter ) - , m_suite( new TestSuite( "All Tests" ) ) - , m_result( new TestResultCollector() ) - , m_eventManager( new TestResult() ) -{ - if ( !m_outputter ) - m_outputter = new TextOutputter( m_result, std::cout ); - m_eventManager->addListener( m_result ); -} +#include <cppunit/TestRunner.h> +#include <cppunit/TestPath.h> -TestRunner::~TestRunner() +namespace CppUnit { - delete m_eventManager; - delete m_outputter; - delete m_result; - delete m_suite; -} - -/*! Adds the specified test. - * - * \param test Test to add. - */ -void -TestRunner::addTest( Test *test ) +TestRunner::WrappingSuite::WrappingSuite( const std::string &name ) + : TestSuite( name ) { - if ( test != NULL ) - m_suite->addTest( test ); } -/*! Runs the named test case. - * - * \param testName Name of the test case to run. If an empty is given, then - * all added test are run. The name must be the name of - * of an added test. - * \param doWait if \c true then the user must press the RETURN key - * before the run() method exit. - * \param doPrintResult if \c true (default) then the test result are printed - * on the standard output. - * \param doPrintProgress if \c true (default) then TextTestProgressListener is - * used to show the progress. - * \return \c true is the test was successful, \c false if the test - * failed or was not found. - */ -bool -TestRunner::run( std::string testName, - bool doWait, - bool doPrintResult, - bool doPrintProgress ) +int +TestRunner::WrappingSuite::getChildTestCount() const { - runTestByName( testName, doPrintProgress ); - printResult( doPrintResult ); - wait( doWait ); - return m_result->wasSuccessful(); + if ( hasOnlyOneTest() ) + return getUniqueChildTest()->getChildTestCount(); + return TestSuite::getChildTestCount(); } -bool -TestRunner::runTestByName( std::string testName, - bool doPrintProgress ) +std::string +TestRunner::WrappingSuite::getName() const { - if ( testName.empty() ) - return runTest( m_suite, doPrintProgress ); + if ( hasOnlyOneTest() ) + return getUniqueChildTest()->getName(); + return TestSuite::getName(); +} - Test *test = findTestByName( testName ); - if ( test != NULL ) - return runTest( test, doPrintProgress ); - std::cout << "Test " << testName << " not found." << std::endl; - return false; +Test * +TestRunner::WrappingSuite::doGetChildTestAt( int index ) const +{ + if ( hasOnlyOneTest() ) + return getUniqueChildTest()->getChildTestAt( index ); + return TestSuite::doGetChildTestAt( index ); } void -TestRunner::wait( bool doWait ) +TestRunner::WrappingSuite::run( TestResult *result ) { - if ( doWait ) - { - std::cout << "<RETURN> to continue" << std::endl; - std::cin.get (); - } + if ( hasOnlyOneTest() ) + getUniqueChildTest()->run( result ); + else + TestSuite::run( result ); } -void -TestRunner::printResult( bool doPrintResult ) +bool +TestRunner::WrappingSuite::hasOnlyOneTest() const { - std::cout << std::endl; - if ( doPrintResult ) - m_outputter->write(); + return TestSuite::getChildTestCount() == 1; } -Test * -TestRunner::findTestByName( std::string name ) const +Test * +TestRunner::WrappingSuite::getUniqueChildTest() const { - for ( std::vector<Test *>::const_iterator it = m_suite->getTests().begin(); - it != m_suite->getTests().end(); - ++it ) - { - Test *test = *it; - if ( test->getName() == name ) - return test; - } - return NULL; + return TestSuite::doGetChildTestAt( 0 ); } -bool -TestRunner::runTest( Test *test, - bool doPrintProgress ) -{ - TextTestProgressListener progress; - if ( doPrintProgress ) - m_eventManager->addListener( &progress ); - test->run( m_eventManager ); - if ( doPrintProgress ) - m_eventManager->removeListener( &progress ); - return m_result->wasSuccessful(); + +TestRunner::TestRunner() + : m_suite( new WrappingSuite() ) +{ } -/*! Returns the result of the test run. - * Use this after calling run() to access the result of the test run. - */ -TestResultCollector & -TestRunner::result() const +TestRunner::~TestRunner() { - return *m_result; + delete m_suite; } -/*! Returns the event manager. - * The instance of TestResult results returned is the one that is used to run the - * test. Use this to register additional TestListener before running the tests. - */ -TestResult & -TestRunner::eventManager() const +void +TestRunner::addTest( Test *test ) { - return *m_eventManager; + m_suite->addTest( test ); } -/*! Specifies an alternate outputter. - * - * Notes that the outputter will be use after the test run only if \a printResult was - * \c true. - * \see CompilerOutputter, XmlOutputter, TextOutputter. - */ void -TestRunner::setOutputter( Outputter *outputter ) +TestRunner::run( TestResult &controller, + const std::string &testPath ) { - delete m_outputter; - m_outputter = outputter; + TestPath path = m_suite->resolveTestPath( testPath ); + Test *testToRun = path.getChildTest(); + + testToRun->run( &controller ); } -} // namespace TextUi -} // namespace CppUnit +} // namespace CppUnit + diff --git a/src/cppunit/TestSuite.cpp b/src/cppunit/TestSuite.cpp index 7659939..ff9c88b 100644 --- a/src/cppunit/TestSuite.cpp +++ b/src/cppunit/TestSuite.cpp @@ -1,11 +1,11 @@ -#include "cppunit/TestSuite.h" -#include "cppunit/TestResult.h" +#include <cppunit/TestSuite.h> +#include <cppunit/TestResult.h> namespace CppUnit { /// Default constructor TestSuite::TestSuite( std::string name ) - : m_name( name ) + : TestComposite( name ) { } @@ -21,43 +21,11 @@ TestSuite::~TestSuite() void TestSuite::deleteContents() { - for ( std::vector<Test *>::iterator it = m_tests.begin(); - it != m_tests.end(); - ++it) - delete *it; - m_tests.clear(); -} - - -/// Runs the tests and collects their result in a TestResult. -void -TestSuite::run( TestResult *result ) -{ - for ( std::vector<Test *>::iterator it = m_tests.begin(); - it != m_tests.end(); - ++it ) - { - if ( result->shouldStop() ) - break; - - Test *test = *it; - test->run( result ); - } -} - - -/// Counts the number of test cases that will be run by this test. -int -TestSuite::countTestCases() const -{ - int count = 0; - - for ( std::vector<Test *>::const_iterator it = m_tests.begin(); - it != m_tests.end(); - ++it ) - count += (*it)->countTestCases(); + int childCount = getChildTestCount(); + for ( int index =0; index < childCount; ++index ) + delete getChildTestAt( index ); - return count; + m_tests.clear(); } @@ -69,26 +37,24 @@ TestSuite::addTest( Test *test ) } -/// Returns a string representation of the test suite. -std::string -TestSuite::toString() const -{ - return "suite " + getName(); +const std::vector<Test *> & +TestSuite::getTests() const +{ + return m_tests; } -/// Returns the name of the test suite. -std::string -TestSuite::getName() const -{ - return m_name; +int +TestSuite::getChildTestCount() const +{ + return m_tests.size(); } -const std::vector<Test *> & -TestSuite::getTests() const +Test * +TestSuite::doGetChildTestAt( int index ) const { - return m_tests; + return m_tests[index]; } diff --git a/src/cppunit/TextTestRunner.cpp b/src/cppunit/TextTestRunner.cpp new file mode 100644 index 0000000..d190ebe --- /dev/null +++ b/src/cppunit/TextTestRunner.cpp @@ -0,0 +1,181 @@ +// ==> Implementation of cppunit/ui/text/TestRunner.h + +#include <cppunit/TestSuite.h> +#include <cppunit/TextTestResult.h> +#include <cppunit/TextOutputter.h> +#include <cppunit/TextTestProgressListener.h> +#include <cppunit/TestResult.h> +#include <cppunit/ui/text/TestRunner.h> +#include <iostream> + + +namespace CppUnit { +namespace TextUi { + +/*! Constructs a new text runner. + * \param outputter used to print text result. Owned by the runner. + */ +TestRunner::TestRunner( Outputter *outputter ) + : m_outputter( outputter ) + , m_suite( new TestSuite( "All Tests" ) ) + , m_result( new TestResultCollector() ) + , m_eventManager( new TestResult() ) +{ + if ( !m_outputter ) + m_outputter = new TextOutputter( m_result, std::cout ); + m_eventManager->addListener( m_result ); +} + + +TestRunner::~TestRunner() +{ + delete m_eventManager; + delete m_outputter; + delete m_result; + delete m_suite; +} + + +/*! Adds the specified test. + * + * \param test Test to add. + */ +void +TestRunner::addTest( Test *test ) +{ + if ( test != NULL ) + m_suite->addTest( test ); +} + + +/*! Runs the named test case. + * + * \param testName Name of the test case to run. If an empty is given, then + * all added test are run. The name must be the name of + * of an added test. + * \param doWait if \c true then the user must press the RETURN key + * before the run() method exit. + * \param doPrintResult if \c true (default) then the test result are printed + * on the standard output. + * \param doPrintProgress if \c true (default) then TextTestProgressListener is + * used to show the progress. + * \return \c true is the test was successful, \c false if the test + * failed or was not found. + */ +bool +TestRunner::run( std::string testName, + bool doWait, + bool doPrintResult, + bool doPrintProgress ) +{ + runTestByName( testName, doPrintProgress ); + printResult( doPrintResult ); + wait( doWait ); + return m_result->wasSuccessful(); +} + + +bool +TestRunner::runTestByName( std::string testName, + bool doPrintProgress ) +{ + if ( testName.empty() ) + return runTest( m_suite, doPrintProgress ); + + Test *test = findTestByName( testName ); + if ( test != NULL ) + return runTest( test, doPrintProgress ); + + std::cout << "Test " << testName << " not found." << std::endl; + return false; +} + + +void +TestRunner::wait( bool doWait ) +{ + if ( doWait ) + { + std::cout << "<RETURN> to continue" << std::endl; + std::cin.get (); + } +} + + +void +TestRunner::printResult( bool doPrintResult ) +{ + std::cout << std::endl; + if ( doPrintResult ) + m_outputter->write(); +} + + +Test * +TestRunner::findTestByName( std::string name ) const +{ + for ( std::vector<Test *>::const_iterator it = m_suite->getTests().begin(); + it != m_suite->getTests().end(); + ++it ) + { + Test *test = *it; + if ( test->getName() == name ) + return test; + } + return NULL; +} + + +bool +TestRunner::runTest( Test *test, + bool doPrintProgress ) +{ + TextTestProgressListener progress; + if ( doPrintProgress ) + m_eventManager->addListener( &progress ); + + test->run( m_eventManager ); + + if ( doPrintProgress ) + m_eventManager->removeListener( &progress ); + return m_result->wasSuccessful(); +} + + +/*! Returns the result of the test run. + * Use this after calling run() to access the result of the test run. + */ +TestResultCollector & +TestRunner::result() const +{ + return *m_result; +} + + +/*! Returns the event manager. + * The instance of TestResult results returned is the one that is used to run the + * test. Use this to register additional TestListener before running the tests. + */ +TestResult & +TestRunner::eventManager() const +{ + return *m_eventManager; +} + + +/*! Specifies an alternate outputter. + * + * Notes that the outputter will be use after the test run only if \a printResult was + * \c true. + * \see CompilerOutputter, XmlOutputter, TextOutputter. + */ +void +TestRunner::setOutputter( Outputter *outputter ) +{ + delete m_outputter; + m_outputter = outputter; +} + + +} // namespace TextUi +} // namespace CppUnit diff --git a/src/cppunit/XmlOutputter.cpp b/src/cppunit/XmlOutputter.cpp index 52ed281..7b9b2b7 100644 --- a/src/cppunit/XmlOutputter.cpp +++ b/src/cppunit/XmlOutputter.cpp @@ -77,7 +77,7 @@ XmlOutputter::Node::toString() const element += node->toString(); } - element += m_content; + element += escape( m_content ); element += "</"; element += m_name; @@ -175,11 +175,25 @@ XmlOutputter::write() void +XmlOutputter::setStyleSheet( const std::string &styleSheet ) +{ + m_styleSheet = styleSheet; +} + + +void XmlOutputter::writeProlog() { m_stream << "<?xml version=\"1.0\" " "encoding='" << m_encoding << "' standalone='yes' ?>" << std::endl; + + if ( !m_styleSheet.empty() ) + { + m_stream << "<?xml-stylesheet type=\"text/xsl\" href=\"" + << m_styleSheet << "\"?>" + << std::endl; + } } @@ -270,13 +284,13 @@ XmlOutputter::addStatistics( Node *rootNode ) void XmlOutputter::addFailedTest( Test *test, - TestFailure *failure, - int testNumber, - Node *testsNode ) + TestFailure *failure, + int testNumber, + Node *testsNode ) { Exception *thrownException = failure->thrownException(); - Node *testNode = new Node( "FailedTest", thrownException->what() ); + Node *testNode = new Node( "FailedTest" ); testsNode->addNode( testNode ); testNode->addAttribute( "id", testNumber ); testNode->addNode( new Node( "Name", test->getName() ) ); @@ -285,6 +299,8 @@ XmlOutputter::addFailedTest( Test *test, if ( failure->sourceLine().isValid() ) addFailureLocation( failure, testNode ); + + testNode->addNode( new Node( "Message", thrownException->what() ) ); } diff --git a/src/cppunit/cppunit.dsp b/src/cppunit/cppunit.dsp index f0e9612..3764129 100644 --- a/src/cppunit/cppunit.dsp +++ b/src/cppunit/cppunit.dsp @@ -222,6 +222,10 @@ SOURCE=..\..\include\cppunit\SynchronizedObject.h # End Source File # Begin Source File +SOURCE=.\Test.cpp +# End Source File +# Begin Source File + SOURCE=..\..\include\cppunit\Test.h # End Source File # Begin Source File @@ -242,6 +246,14 @@ SOURCE=..\..\include\cppunit\TestCase.h # End Source File # Begin Source File +SOURCE=.\TestComposite.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\include\cppunit\TestComposite.h +# End Source File +# Begin Source File + SOURCE=.\TestFailure.cpp # End Source File # Begin Source File @@ -254,10 +266,26 @@ SOURCE=..\..\include\cppunit\TestFixture.h # End Source File # Begin Source File +SOURCE=.\TestLeaf.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\include\cppunit\TestLeaf.h +# End Source File +# Begin Source File + SOURCE=..\..\include\cppunit\TestListener.h # End Source File # Begin Source File +SOURCE=.\TestPath.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\include\cppunit\TestPath.h +# End Source File +# Begin Source File + SOURCE=.\TestResult.cpp # End Source File # Begin Source File @@ -266,6 +294,14 @@ SOURCE=..\..\include\cppunit\TestResult.h # End Source File # Begin Source File +SOURCE=.\TestRunner.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\include\cppunit\TestRunner.h +# End Source File +# Begin Source File + SOURCE=.\TestSuite.cpp # End Source File # Begin Source File @@ -331,11 +367,11 @@ SOURCE=..\..\include\cppunit\Portability.h # PROP Default_Filter "" # Begin Source File -SOURCE=.\TestRunner.cpp +SOURCE=..\..\include\cppunit\ui\text\TestRunner.h # End Source File # Begin Source File -SOURCE=..\..\include\cppunitui\text\TestRunner.h +SOURCE=.\TextTestRunner.cpp # End Source File # Begin Source File @@ -393,6 +429,10 @@ SOURCE=..\..\NEWS SOURCE=..\..\doc\other_documentation.dox # End Source File +# Begin Source File + +SOURCE=..\..\TODO +# End Source File # End Group # Begin Source File diff --git a/src/cppunit/cppunit_dll.dsp b/src/cppunit/cppunit_dll.dsp index 4e4f8d1..17d9708 100644 --- a/src/cppunit/cppunit_dll.dsp +++ b/src/cppunit/cppunit_dll.dsp @@ -206,6 +206,10 @@ SOURCE=..\..\include\cppunit\SynchronizedObject.h # End Source File # Begin Source File +SOURCE=.\Test.cpp +# End Source File +# Begin Source File + SOURCE=..\..\include\cppunit\Test.h # End Source File # Begin Source File @@ -226,6 +230,14 @@ SOURCE=..\..\include\cppunit\TestCase.h # End Source File # Begin Source File +SOURCE=.\TestComposite.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\include\cppunit\TestComposite.h +# End Source File +# Begin Source File + SOURCE=.\TestFailure.cpp # End Source File # Begin Source File @@ -238,10 +250,26 @@ SOURCE=..\..\include\cppunit\TestFixture.h # End Source File # Begin Source File +SOURCE=.\TestLeaf.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\include\cppunit\TestLeaf.h +# End Source File +# Begin Source File + SOURCE=..\..\include\cppunit\TestListener.h # End Source File # Begin Source File +SOURCE=.\TestPath.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\include\cppunit\TestPath.h +# End Source File +# Begin Source File + SOURCE=.\TestResult.cpp # End Source File # Begin Source File @@ -342,10 +370,6 @@ SOURCE=.\TestRunner.cpp # End Source File # Begin Source File -SOURCE=..\..\include\cppunitui\text\TestRunner.h -# End Source File -# Begin Source File - SOURCE=..\..\include\cppunit\TextTestRunner.h # End Source File # End Group |
