[Cppunit-cvs] cppunit2/include/opentest texttestdriver.h,NONE,1.1
Brought to you by:
blep
From: Baptiste L. <bl...@us...> - 2004-11-15 08:34:22
|
Update of /cvsroot/cppunit/cppunit2/include/opentest In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv1882 Added Files: texttestdriver.h Log Message: * rough implementation of a simple TextTestDriver. --- NEW FILE: texttestdriver.h --- #ifndef OPENTEST_TEXTTESTDRIVER_H_INCLUDED # define OPENTEST_TEXTTESTDRIVER_H_INCLUDED # include <opentest/properties.h> # include <opentest/testplan.h> # include <opentest/testrunner.h> # include <deque> # include <map> # include <iostream> // for progress # include <set> # include <stack> namespace OpenTest { class OPENTEST_API TestDriverTestPlan : public TestPlan { public: // overriden from TestPlan TestPlanEntryPtrEnum entries() const; public: void add( const TestPlanEntryPtr &entry ); private: std::deque<TestPlanEntryPtr> entries_; }; class OPENTEST_API TestResult { public: TestResult( TestPlanEntryId id, TestId test ); void addTestResultInfo( const Properties &result ); TestPlanEntryId id() const; TestId test() const; const Properties &result() const; Properties &result(); private: TestPlanEntryId id_; TestId test_; Properties result_; }; class OPENTEST_API TestDriverTestPlanEntry : public TestPlanEntry { public: TestDriverTestPlanEntry( TestPlanEntryId id, TestId test, const Properties &configuration ); public: // overriden from TestPlanEntry TestPlanEntryId id() const; /// Test to run TestId test() const; /// Used to pass configuration data to the test runner or the test itself const Properties &configuration() const; private: TestPlanEntryId id_; TestId test_; Properties configuration_; }; class OPENTEST_API TextTestDriver : private TestRunTracker , private TestDeclarator { public: TextTestDriver( TestRunner &runner ); // void selectTest( const std::string &name ); bool run(); private: // overriden from TestDeclarator TestId beginSuite( const std::string &name, const Properties &data ); TestId addTest( const std::string &name, const Properties &data ); void addSuite( TestId suite ); void endSuite(); private: // overriden from TestRunTracker void startTestRun(); void startTest( const TestPlanEntry &testEntry ); void addTestInfo( const TestPlanEntry &testEntry, const Properties &data ); void endTest( const TestPlanEntry &testEntry ); void endTestRun(); bool shouldStopTestRun(); void aqcuireResources( const ResourceList &resources ) {} void releaseResources( const ResourceList &resources ) {} private: struct TestInfo { TestInfo( TestId id, const std::string &name, const Properties &info ) : id_( id ) , name_( name ) , info_( info ) { } TestId id_; std::string name_; Properties info_; }; typedef std::set<TestId> Tests; typedef std::map<TestId,TestId> Hierarchy; // suite <-> tests typedef std::stack<TestId> DeclarationSuites; typedef std::deque<TestResult> Results; typedef std::vector<unsigned int> TestResultIndexes; typedef std::map<TestId,TestInfo> TestInfos; TestId nextTestId(); void outputFailures(); const TestInfo &getTestInfo( TestId id ) const; TestRunner &runner_; TestInfos testInfos_; Tests tests_; Tests suites_; Hierarchy hierarchy_; DeclarationSuites declarationSuites_; Tests testsToRun_; Results results_; TestResultIndexes failures_; TestResultIndexes successes_; TestId nextTestId_; }; // Inline implementation of TextTestDriver // ////////////////////////////////////////////////////////////////// TestPlanEntryPtrEnum TestDriverTestPlan::entries() const { return CppTL::Enum::anyContainer( entries_ ); } void TestDriverTestPlan::add( const TestPlanEntryPtr &entry ) { entries_.push_back( entry ); } // Inline implementation of TestResult // ////////////////////////////////////////////////////////////////// inline TestResult::TestResult( TestPlanEntryId id, TestId test ) : id_( id ) , test_( test ) { } inline void TestResult::addTestResultInfo( const Properties &result ) { result_.mergeReplacingExisting( result ); } inline TestPlanEntryId TestResult::id() const { return id_; } inline TestId TestResult::test() const { return test_; } inline const Properties & TestResult::result() const { return result_; } inline Properties & TestResult::result() { return result_; } // Inline implementation of TestDriverTestPlanEntry // ////////////////////////////////////////////////////////////////// inline TestDriverTestPlanEntry::TestDriverTestPlanEntry( TestPlanEntryId id, TestId test, const Properties &configuration ) : id_( id ) , test_( test ) , configuration_( configuration ) { } TestPlanEntryId TestDriverTestPlanEntry::id() const { return id_; } /// Test to run TestId TestDriverTestPlanEntry::test() const { return test_; } /// Used to pass configuration data to the test runner or the test itself const Properties & TestDriverTestPlanEntry::configuration() const { return configuration_; } // Inline implementation of TextTestDriver // ////////////////////////////////////////////////////////////////// inline TextTestDriver::TextTestDriver( TestRunner &runner ) : runner_( runner ) , nextTestId_( 0 ) { runner_.declareTests( *this ); std::cout << "Declared suites: " << suites_.size() << "\n" << "Declared tests: " << tests_.size() << std::endl; } inline bool TextTestDriver::run() { if ( testsToRun_.empty() ) testsToRun_ = tests_; TestDriverTestPlan plan; Tests::const_iterator itTest = testsToRun_.begin(); unsigned int entryId = 0; for ( ; itTest != testsToRun_.end(); ++itTest ) plan.add( TestPlanEntryPtr( new TestDriverTestPlanEntry( ++entryId, *itTest, Properties() ) ) ); runner_.runTests( plan, *this, Properties() ); outputFailures(); return failures_.empty(); } inline TestId TextTestDriver::beginSuite( const std::string &name, const Properties &data ) { TestId id = nextTestId(); declarationSuites_.push( id ); suites_.insert( id ); TestInfo info( id, name, data ); testInfos_.insert( TestInfos::value_type( id, info ) ); return id; } inline TestId TextTestDriver::addTest( const std::string &name, const Properties &data ) { TestId id = nextTestId(); hierarchy_.insert( Hierarchy::value_type( declarationSuites_.top(), id ) ); tests_.insert( id ); TestInfo info( id, name, data ); testInfos_.insert( TestInfos::value_type( id, info ) ); return id; } inline void TextTestDriver::addSuite( TestId suite ) { hierarchy_.insert( Hierarchy::value_type( declarationSuites_.top(), suite ) ); } inline void TextTestDriver::endSuite() { declarationSuites_.pop(); } inline TestId TextTestDriver::nextTestId() { return ++nextTestId_; } inline void TextTestDriver::startTestRun() { results_.clear(); successes_.clear(); failures_.clear(); } inline void TextTestDriver::startTest( const TestPlanEntry &testEntry ) { TestResult result( testEntry.id(), testEntry.test() ); // should add descriptive test data first result.addTestResultInfo( testEntry.configuration() ); results_.push_back( result ); std::cout << "Testing '" << getTestInfo( testEntry.test() ).name_ << "' : "; std::cout.flush(); } inline void TextTestDriver::addTestInfo( const TestPlanEntry &testEntry, const Properties &data ) { results_.back().addTestResultInfo( data ); } inline void TextTestDriver::endTest( const TestPlanEntry &testEntry ) { const Properties &result = results_.back().result(); PropertiesAccessor status = result.accessor()["result"]["status"]; bool succeeded = status.getValue( "success", false ).asBool(); std::string statusInfo = succeeded ? "OK" : "FAIL"; if ( succeeded ) successes_.push_back( results_.size() - 1 ); else failures_.push_back( results_.size() - 1 ); std::string resultType = status.getValue( "type", "" ).asString(); if ( !resultType.empty() ) statusInfo += " (" + resultType + ")"; std::cout << statusInfo << std::endl; std::cout.flush(); } inline void TextTestDriver::endTestRun() { } inline bool TextTestDriver::shouldStopTestRun() { return false; } inline const TextTestDriver::TestInfo & TextTestDriver::getTestInfo( TestId test ) const { TestInfos::const_iterator it = testInfos_.find( test ); if ( it == testInfos_.end() ) throw std::invalid_argument( "TextTestDriver::getTestInfo() : bad TestId." ); return it->second; } inline void TextTestDriver::outputFailures() { if ( failures_.empty() ) { std::cout << "All " << testsToRun_.size() << " tests passed..." << std::endl; return; } TestResultIndexes::const_iterator failuresIt = failures_.begin(); for ( ; failuresIt != failures_.end(); ++failuresIt ) { const TestResult &testResult = results_.at( *failuresIt ); PropertiesAccessor info = testResult.result().accessor(); PropertiesAccessor locationInfo = info["result"]["status"]["location"]; if ( locationInfo.isValid() ) { std::cout << locationInfo.getValue("file").asString() << "(" << locationInfo.getValue("line").asInt() << ") : "; } else { std::cout << "Unknown failure location : "; } std::cout << getTestInfo( testResult.test() ).name_ << std::endl; std::string failureType = info["result"]["status"].getValue("type","").asString(); if ( !failureType.empty() ) std::cout << "Failure type : " << failureType << std::endl; std::string message = info["result"]["status"].getValue("message","").asString(); if ( !message.empty() ) std::cout << message << std::endl; std::cout << "Failures: " << failures_.size() << ", "; std::cout << "Tested: " << testsToRun_.size() << std::endl; } } } // namespace OpenTest #endif // OPENTEST_TEXTTESTDRIVER_H_INCLUDED |