From 73a038f1eaa268cec330d971fb550befec6f7798 Mon Sep 17 00:00:00 2001 From: Baptiste Lepilleur Date: Fri, 14 Jun 2002 19:21:01 +0000 Subject: Include/cppunit/plugin/PlugInManager. include/cppunit/plugin/PlugInManager.h: * src/cppunit/PlugInManager.cpp: added two methods to use the plug-in interface for Xml Outputter hooks. * include/cppunit/plugin/TestPlugIn.h: added two methods to the plug-in interface for Xml Outputter hooks. * include/cppunit/plugin/TestPlugInAdapter.h: * src/cppunit/plugin/TestPlugInAdapter.cpp: renamed TestPlugInDefaultImpl. Added empty implementation for Xml outputter hook methods. * include/cppunit/tools/StringTools.h: * src/cppunit/tools/StringTools.cpp: added. Functions to manipulate string (conversion, wrapping...) * include/cppunit/tools/XmlElement.h: * src/cppunit/XmlElement.cpp: renamed addNode() to addElement(). Added methods to walk and modify XmlElement (for hook). Added documentation. Use StringTools. * include/cppunit/XmlOutputter.h: * src/cppunit/XmlOutputter.cpp: added hook calls & management. * include/cppunit/XmlOutputterHook.h: * src/cppunit/XmlOutputterHook.cpp: added. Hook to customize XML output. * src/DllPlugInTester/DllPlugInTester.cpp: call plug-in XmlOutputterHook when writing XML output. Modified so that memory is freed before unloading the test plug-in (caused crash when freeing the XmlDocument). * examples/ReadMe.txt: * examples/ClockerPlugIn/ReadMe.txt: added details about the plug-in (usage, xml content...) * examples/ClockerPlugIn/ClockerModel.h: * examples/ClockerPlugIn/ClockerModel.cpp: extracted from ClockerListener. Represents the test hierarchy and tracked time for each test. * examples/ClockerPlugIn/ClockerListener.h: * examples/ClockerPlugIn/ClockerListener.cpp: extracted test hierarchy tracking to ClockerModel. Replaced the 'flat' view option with a 'text' option to print the timed test tree to stdout. * examples/ClockerPlugIn/ClockerPlugIn.cpp: updated to hook the XML output and use the new classes. * examples/ClockerPlugIn/ClockerXmlHook.h: * examples/ClockerPlugIn/ClockerXmlHook.cpp: added. XmlOutputterHook to includes the timed test hierarchy and test timing in the XML output. * examples/cppunittest/XmlElementTest.h: * examples/cppunittest/XmlElementTest.cpp: added new test cases. * examples/cppunittest/XmlOutputterTest.h: * examples/cppunittest/XmlOutputterTest.cpp: added tests for XmlOutputterHook. --- src/cppunit/Makefile.am | 6 ++- src/cppunit/PlugInManager.cpp | 17 +++++++ src/cppunit/StringTools.cpp | 29 ++++++++++++ src/cppunit/TestPlugInAdapter.cpp | 51 --------------------- src/cppunit/TestPlugInDefaultImpl.cpp | 63 +++++++++++++++++++++++++ src/cppunit/XmlElement.cpp | 86 ++++++++++++++++++++++++++++++----- src/cppunit/XmlOutputter.cpp | 74 +++++++++++++++++++++--------- src/cppunit/XmlOutputterHook.cpp | 47 +++++++++++++++++++ src/cppunit/cppunit.dsp | 20 +++++++- src/cppunit/cppunit_dll.dsp | 20 +++++++- 10 files changed, 323 insertions(+), 90 deletions(-) create mode 100644 src/cppunit/StringTools.cpp delete mode 100644 src/cppunit/TestPlugInAdapter.cpp create mode 100644 src/cppunit/TestPlugInDefaultImpl.cpp create mode 100644 src/cppunit/XmlOutputterHook.cpp (limited to 'src/cppunit') diff --git a/src/cppunit/Makefile.am b/src/cppunit/Makefile.am index 80b1888..3846e64 100644 --- a/src/cppunit/Makefile.am +++ b/src/cppunit/Makefile.am @@ -1,5 +1,5 @@ # -# $Id: Makefile.am,v 1.34 2002-06-13 18:17:42 blep Exp $ +# $Id: Makefile.am,v 1.35 2002-06-14 20:21:00 blep Exp $ # EXTRA_DIST = cppunit.dsp cppunit_dll.dsp DllMain.cpp @@ -19,6 +19,7 @@ libcppunit_la_SOURCES = \ RepeatedTest.cpp \ PlugInManager.cpp \ SourceLine.cpp \ + StringTools.cpp \ SynchronizedObject.cpp \ Test.cpp \ TestAssert.cpp \ @@ -29,7 +30,7 @@ libcppunit_la_SOURCES = \ TestLeaf.cpp \ TestNamer.cpp \ TestPath.cpp \ - TestPlugInAdapter.cpp \ + TestPlugInDefaultImpl.cpp \ TestResult.cpp \ TestResultCollector.cpp \ TestRunner.cpp \ @@ -45,6 +46,7 @@ libcppunit_la_SOURCES = \ XmlDocument.cpp \ XmlElement.cpp \ XmlOutputter.cpp \ + XmlOutputterHook.cpp \ Win32DynamicLibraryManager.cpp libcppunit_la_LDFLAGS= \ diff --git a/src/cppunit/PlugInManager.cpp b/src/cppunit/PlugInManager.cpp index f339c63..8f2476d 100644 --- a/src/cppunit/PlugInManager.cpp +++ b/src/cppunit/PlugInManager.cpp @@ -1,3 +1,4 @@ +#include #include #include #include @@ -87,5 +88,21 @@ PlugInManager::unload( PlugInInfo &plugIn ) } +void +PlugInManager::addXmlOutputterHooks( XmlOutputter *outputter ) +{ + for ( PlugIns::iterator it = m_plugIns.begin(); it != m_plugIns.end(); ++it ) + it->m_interface->addXmlOutputterHooks( outputter ); +} + + +void +PlugInManager::removeXmlOutputterHooks() +{ + for ( PlugIns::iterator it = m_plugIns.begin(); it != m_plugIns.end(); ++it ) + it->m_interface->removeXmlOutputterHooks(); +} + + } // namespace CppUnit diff --git a/src/cppunit/StringTools.cpp b/src/cppunit/StringTools.cpp new file mode 100644 index 0000000..9bfb939 --- /dev/null +++ b/src/cppunit/StringTools.cpp @@ -0,0 +1,29 @@ +#include + + +namespace CppUnit +{ + +namespace StringTools +{ + + std::string toString( int value ) + { + OStringStream stream; + stream << value; + return stream.str(); + } + + std::string toString( double value ) + { + OStringStream stream; + stream << value; + return stream.str(); + } + + +} // namespace StringTools + + +} // namespace CppUnit + diff --git a/src/cppunit/TestPlugInAdapter.cpp b/src/cppunit/TestPlugInAdapter.cpp deleted file mode 100644 index 87f761a..0000000 --- a/src/cppunit/TestPlugInAdapter.cpp +++ /dev/null @@ -1,51 +0,0 @@ -#include - -#if !defined(CPPUNIT_NO_TESTPLUGIN) - -#include -#include -#include - - -namespace CppUnit -{ - -TestPlugInAdapter::TestPlugInAdapter() -{ -} - - -TestPlugInAdapter::~TestPlugInAdapter() -{ -} - - -void -TestPlugInAdapter::initialize( TestFactoryRegistry *registry, - const Parameters ¶meters ) -{ -} - - -void -TestPlugInAdapter::addListener( TestResult *eventManager ) -{ -} - - -void -TestPlugInAdapter::removeListener( TestResult *eventManager ) -{ -} - - -void -TestPlugInAdapter::uninitialize( TestFactoryRegistry *registry ) -{ -} - - -} // namespace CppUnit - - -#endif // !defined(CPPUNIT_NO_TESTPLUGIN) diff --git a/src/cppunit/TestPlugInDefaultImpl.cpp b/src/cppunit/TestPlugInDefaultImpl.cpp new file mode 100644 index 0000000..55010ed --- /dev/null +++ b/src/cppunit/TestPlugInDefaultImpl.cpp @@ -0,0 +1,63 @@ +#include + +#if !defined(CPPUNIT_NO_TESTPLUGIN) + +#include +#include +#include + + +namespace CppUnit +{ + +TestPlugInDefaultImpl::TestPlugInDefaultImpl() +{ +} + + +TestPlugInDefaultImpl::~TestPlugInDefaultImpl() +{ +} + + +void +TestPlugInDefaultImpl::initialize( TestFactoryRegistry *registry, + const Parameters ¶meters ) +{ +} + + +void +TestPlugInDefaultImpl::addListener( TestResult *eventManager ) +{ +} + + +void +TestPlugInDefaultImpl::removeListener( TestResult *eventManager ) +{ +} + + +void +TestPlugInDefaultImpl::addXmlOutputterHooks( XmlOutputter *outputter ) +{ +} + + +void +TestPlugInDefaultImpl::removeXmlOutputterHooks() +{ +} + + +void +TestPlugInDefaultImpl::uninitialize( TestFactoryRegistry *registry ) +{ +} + + +} // namespace CppUnit + + +#endif // !defined(CPPUNIT_NO_TESTPLUGIN) diff --git a/src/cppunit/XmlElement.cpp b/src/cppunit/XmlElement.cpp index 4a01405..be06941 100644 --- a/src/cppunit/XmlElement.cpp +++ b/src/cppunit/XmlElement.cpp @@ -1,3 +1,4 @@ +#include #include @@ -17,7 +18,7 @@ XmlElement::XmlElement( std::string elementName, int numericContent ) : m_name( elementName ) { - m_content = asString( numericContent ); + setContent( numericContent ); } @@ -25,7 +26,45 @@ XmlElement::~XmlElement() { Elements::iterator itNode = m_elements.begin(); while ( itNode != m_elements.end() ) + { + XmlElement *element = *itNode; delete *itNode++; + } +} + + +std::string +XmlElement::name() const +{ + return m_name; +} + + +std::string +XmlElement::content() const +{ + return m_content; +} + + +void +XmlElement::setName( const std::string &name ) +{ + m_name = name; +} + + +void +XmlElement::setContent( const std::string &content ) +{ + m_content = content; +} + + +void +XmlElement::setContent( int numericContent ) +{ + m_content = StringTools::toString( numericContent ); } @@ -41,17 +80,49 @@ void XmlElement::addAttribute( std::string attributeName, int numericValue ) { - addAttribute( attributeName, asString( numericValue ) ); + addAttribute( attributeName, StringTools::toString( numericValue ) ); } void -XmlElement::addNode( XmlElement *node ) +XmlElement::addElement( XmlElement *node ) { m_elements.push_back( node ); } +int +XmlElement::elementCount() const +{ + return m_elements.size(); +} + + +XmlElement * +XmlElement::elementAt( int index ) const +{ + if ( index < 0 || index >= elementCount() ) + throw std::invalid_argument( "XmlElement::elementAt(), out of range index" ); + + return m_elements[ index ]; +} + + +XmlElement * +XmlElement::elementFor( const std::string &name ) const +{ + Elements::const_iterator itElement = m_elements.begin(); + for ( ; itElement != m_elements.end(); ++itElement ) + { + if ( (*itElement)->name() == name ) + return *itElement; + } + + throw std::invalid_argument( "XmlElement::elementFor(), not matching child element found" ); + return NULL; // make some compilers happy. +} + + std::string XmlElement::toString( const std::string &indent ) const { @@ -147,15 +218,6 @@ XmlElement::escape( std::string value ) const return escaped; } -// should be somewhere else... Future CppUnit::String ? -std::string -XmlElement::asString( int value ) -{ - OStringStream stream; - stream << value; - return stream.str(); -} - } // namespace CppUnit diff --git a/src/cppunit/XmlOutputter.cpp b/src/cppunit/XmlOutputter.cpp index 42e6b32..9fc59f7 100644 --- a/src/cppunit/XmlOutputter.cpp +++ b/src/cppunit/XmlOutputter.cpp @@ -3,9 +3,11 @@ #include #include #include +#include #include #include #include +#include namespace CppUnit @@ -38,6 +40,20 @@ XmlOutputter::~XmlOutputter() } +void +XmlOutputter::addHook( XmlOutputterHook *hook ) +{ + m_hooks.push_back( hook ); +} + + +void +XmlOutputter::removeHook( XmlOutputterHook *hook ) +{ + m_hooks.erase( std::find( m_hooks.begin(), m_hooks.end(), hook ) ); +} + + void XmlOutputter::write() { @@ -58,6 +74,9 @@ XmlOutputter::makeRootNode() { XmlElement *rootNode = new XmlElement( "TestRun" ); + for ( Hooks::const_iterator it = m_hooks.begin(); it != m_hooks.end(); ++it ) + (*it)->beginDocument( m_xml, rootNode ); + FailedTests failedTests; fillFailedTestsMap( failedTests ); @@ -65,6 +84,9 @@ XmlOutputter::makeRootNode() addSuccessfulTests( failedTests, rootNode ); addStatistics( rootNode ); + for ( Hooks::const_iterator itEnd = m_hooks.begin(); itEnd != m_hooks.end(); ++itEnd ) + (*itEnd)->endDocument( m_xml, rootNode ); + return rootNode; } @@ -87,7 +109,7 @@ XmlOutputter::addFailedTests( FailedTests &failedTests, XmlElement *rootNode ) { XmlElement *testsNode = new XmlElement( "FailedTests" ); - rootNode->addNode( testsNode ); + rootNode->addElement( testsNode ); const TestResultCollector::Tests &tests = m_result->tests(); for ( int testNumber = 0; testNumber < tests.size(); ++testNumber ) @@ -104,7 +126,7 @@ XmlOutputter::addSuccessfulTests( FailedTests &failedTests, XmlElement *rootNode ) { XmlElement *testsNode = new XmlElement( "SuccessfulTests" ); - rootNode->addNode( testsNode ); + rootNode->addElement( testsNode ); const TestResultCollector::Tests &tests = m_result->tests(); for ( int testNumber = 0; testNumber < tests.size(); ++testNumber ) @@ -120,12 +142,15 @@ void XmlOutputter::addStatistics( XmlElement *rootNode ) { XmlElement *statisticsNode = new XmlElement( "Statistics" ); - rootNode->addNode( statisticsNode ); - statisticsNode->addNode( new XmlElement( "Tests", m_result->runTests() ) ); - statisticsNode->addNode( new XmlElement( "FailuresTotal", - m_result->testFailuresTotal() ) ); - statisticsNode->addNode( new XmlElement( "Errors", m_result->testErrors() ) ); - statisticsNode->addNode( new XmlElement( "Failures", m_result->testFailures() ) ); + rootNode->addElement( statisticsNode ); + statisticsNode->addElement( new XmlElement( "Tests", m_result->runTests() ) ); + statisticsNode->addElement( new XmlElement( "FailuresTotal", + m_result->testFailuresTotal() ) ); + statisticsNode->addElement( new XmlElement( "Errors", m_result->testErrors() ) ); + statisticsNode->addElement( new XmlElement( "Failures", m_result->testFailures() ) ); + + for ( Hooks::const_iterator it = m_hooks.begin(); it != m_hooks.end(); ++it ) + (*it)->statisticsAdded( m_xml, statisticsNode ); } @@ -138,40 +163,47 @@ XmlOutputter::addFailedTest( Test *test, Exception *thrownException = failure->thrownException(); XmlElement *testNode = new XmlElement( "FailedTest" ); - testsNode->addNode( testNode ); + testsNode->addElement( testNode ); testNode->addAttribute( "id", testNumber ); - testNode->addNode( new XmlElement( "Name", test->getName() ) ); - testNode->addNode( new XmlElement( "FailureType", - failure->isError() ? "Error" : "Assertion" ) ); + testNode->addElement( new XmlElement( "Name", test->getName() ) ); + testNode->addElement( new XmlElement( "FailureType", + failure->isError() ? "Error" : + "Assertion" ) ); if ( failure->sourceLine().isValid() ) addFailureLocation( failure, testNode ); - testNode->addNode( new XmlElement( "Message", thrownException->what() ) ); + testNode->addElement( new XmlElement( "Message", thrownException->what() ) ); + + for ( Hooks::const_iterator it = m_hooks.begin(); it != m_hooks.end(); ++it ) + (*it)->failTestAdded( m_xml, testNode, test, failure ); } void XmlOutputter::addFailureLocation( TestFailure *failure, - XmlElement *testNode ) + XmlElement *testNode ) { XmlElement *locationNode = new XmlElement( "Location" ); - testNode->addNode( locationNode ); + testNode->addElement( locationNode ); SourceLine sourceLine = failure->sourceLine(); - locationNode->addNode( new XmlElement( "File", sourceLine.fileName() ) ); - locationNode->addNode( new XmlElement( "Line", sourceLine.lineNumber() ) ); + locationNode->addElement( new XmlElement( "File", sourceLine.fileName() ) ); + locationNode->addElement( new XmlElement( "Line", sourceLine.lineNumber() ) ); } void XmlOutputter::addSuccessfulTest( Test *test, - int testNumber, - XmlElement *testsNode ) + int testNumber, + XmlElement *testsNode ) { XmlElement *testNode = new XmlElement( "Test" ); - testsNode->addNode( testNode ); + testsNode->addElement( testNode ); testNode->addAttribute( "id", testNumber ); - testNode->addNode( new XmlElement( "Name", test->getName() ) ); + testNode->addElement( new XmlElement( "Name", test->getName() ) ); + + for ( Hooks::const_iterator it = m_hooks.begin(); it != m_hooks.end(); ++it ) + (*it)->successfulTestAdded( m_xml, testNode, test ); } diff --git a/src/cppunit/XmlOutputterHook.cpp b/src/cppunit/XmlOutputterHook.cpp new file mode 100644 index 0000000..4cacd06 --- /dev/null +++ b/src/cppunit/XmlOutputterHook.cpp @@ -0,0 +1,47 @@ +#include + + +namespace CppUnit +{ + + +void +XmlOutputterHook::beginDocument( XmlDocument *document, + XmlElement *rootNode ) +{ +} + + +void +XmlOutputterHook::endDocument( XmlDocument *document, + XmlElement *rootNode ) +{ +} + + +void +XmlOutputterHook::failTestAdded( XmlDocument *document, + XmlElement *testNode, + Test *test, + TestFailure *failure ) +{ +} + + +void +XmlOutputterHook::successfulTestAdded( XmlDocument *document, + XmlElement *testNode, + Test *test ) +{ +} + + +void +XmlOutputterHook::statisticsAdded( XmlDocument *document, + XmlElement *statisticsNode ) +{ +} + + +} // namespace CppUnit + diff --git a/src/cppunit/cppunit.dsp b/src/cppunit/cppunit.dsp index abaa6ba..2111bbd 100644 --- a/src/cppunit/cppunit.dsp +++ b/src/cppunit/cppunit.dsp @@ -231,6 +231,14 @@ SOURCE=.\XmlOutputter.cpp SOURCE=..\..\include\cppunit\XmlOutputter.h # End Source File +# Begin Source File + +SOURCE=.\XmlOutputterHook.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\include\cppunit\XmlOutputterHook.h +# End Source File # End Group # Begin Group "core" @@ -485,11 +493,11 @@ SOURCE=..\..\include\cppunit\plugin\TestPlugIn.h # End Source File # Begin Source File -SOURCE=.\TestPlugInAdapter.cpp +SOURCE=.\TestPlugInDefaultImpl.cpp # End Source File # Begin Source File -SOURCE=..\..\include\cppunit\plugin\TestPlugInAdapter.h +SOURCE=..\..\include\cppunit\plugin\TestPlugInDefaultImpl.h # End Source File # Begin Source File @@ -505,6 +513,14 @@ SOURCE=.\Win32DynamicLibraryManager.cpp # PROP Default_Filter "" # Begin Source File +SOURCE=.\StringTools.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\include\cppunit\tools\StringTools.h +# End Source File +# Begin Source File + SOURCE=.\XmlDocument.cpp # End Source File # Begin Source File diff --git a/src/cppunit/cppunit_dll.dsp b/src/cppunit/cppunit_dll.dsp index 4336150..4ab8bab 100644 --- a/src/cppunit/cppunit_dll.dsp +++ b/src/cppunit/cppunit_dll.dsp @@ -349,6 +349,14 @@ SOURCE=.\XmlOutputter.cpp SOURCE=..\..\include\cppunit\XmlOutputter.h # End Source File +# Begin Source File + +SOURCE=.\XmlOutputterHook.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\include\cppunit\XmlOutputterHook.h +# End Source File # End Group # Begin Group "portability" @@ -487,11 +495,11 @@ SOURCE=..\..\include\cppunit\plugin\TestPlugIn.h # End Source File # Begin Source File -SOURCE=.\TestPlugInAdapter.cpp +SOURCE=.\TestPlugInDefaultImpl.cpp # End Source File # Begin Source File -SOURCE=..\..\include\cppunit\plugin\TestPlugInAdapter.h +SOURCE=..\..\include\cppunit\plugin\TestPlugInDefaultImpl.h # End Source File # Begin Source File @@ -507,6 +515,14 @@ SOURCE=.\Win32DynamicLibraryManager.cpp # PROP Default_Filter "" # Begin Source File +SOURCE=.\StringTools.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\include\cppunit\tools\StringTools.h +# End Source File +# Begin Source File + SOURCE=.\XmlDocument.cpp # End Source File # Begin Source File -- cgit v1.2.1