diff options
| author | Baptiste Lepilleur <gaiacrtn@free.fr> | 2001-10-07 18:37:53 +0000 |
|---|---|---|
| committer | Baptiste Lepilleur <gaiacrtn@free.fr> | 2001-10-07 18:37:53 +0000 |
| commit | 150339335e3c5538c1e496ae01babf148bd29ec5 (patch) | |
| tree | 9f354aaee81e08c27dc6da0709074babde7672f5 /src/cppunit/XmlOutputter.cpp | |
| parent | 4410db53e88dc5aca9f86abaf9dffccbd5f94471 (diff) | |
| download | cppunit-150339335e3c5538c1e496ae01babf148bd29ec5.tar.gz | |
Include/cppunit/CompilerTestResultOutputter.
include/cppunit/CompilerTestResultOutputter.h :
renamed CompilerOutputter.h
* src/cppunit/CompilerTestResultOutputter.cpp :
renamed CompilerOutputter.cpp
* include/cppunit/CompilerTestResultOutputter.h :
* src/cppunit/CompilerTestResultOutputter.cpp : ajust max line length
for wrapping. Added static factory method defaultOutputter(). Print
the number of test runs on success.
* include/cppunit/CompilerTestResultOutputter.h : renamed
CompilerOutputter.h.
* src/cppunit/CompilerTestResultOutputter.cpp : renamed
CompilerOutputter.cpp.
* examples/cppunittest/CppUnitTestMain.cpp : use factory method
CompilerTestResultOutputter::defaultOutputter().
* src/msvc6/DSPlugIn/DSPlugIn.dsp : removed COM registration in
post-build step. IT is automatically done by VC++ when the add-in is
added. Caused build to failed if the add-in was used in VC++.
* NEWS : updated.
* src/cppunit/TestAssert.cpp : modified deprecated assert
implementations to use Asserter.
* examples/cppunittest/XmlTestResultOutputterTest.h :
renamed XmlOutputterTest.h.
* examples/cppunittest/XmlTestResultOutputterTest.cpp :
renamed XmlOutputterTest.cpp.
* NEWS :
* examples/cppunittest/CppUnitTestMain.cpp :
* examples/cppunittest/CppUnitTestMain.dsp :
* examples/cppunittest/Makefile.am :
* examples/cppunittest/XmlTestResultOutputterTest.h :
* examples/cppunittest/XmlTestResultOutputterTest.cpp :
* examples/msvc6/CppUniTestApp/CppUnitTestApp.dsp
* include/cppunit/CompilerOutputter.h :
* include/cppunit/Makefile.am :
* include/cppunit/XmlTestResultOutputter.h :
* src/cppunit/CompilerOutputter.cpp :
* src/cppunit/cppunit.dsp :
* src/cppunit/Makefile.am :
* src/cppunit/XmlTestResultOutputter.cpp : change due to renaming
CompilerTestResultOutputter to CompilerOutputter,
XmlTestResultOutputter to XmlOuputter, XmlTestResultOutputterTest
to XmlOutputterTest.
Diffstat (limited to 'src/cppunit/XmlOutputter.cpp')
| -rw-r--r-- | src/cppunit/XmlOutputter.cpp | 312 |
1 files changed, 312 insertions, 0 deletions
diff --git a/src/cppunit/XmlOutputter.cpp b/src/cppunit/XmlOutputter.cpp new file mode 100644 index 0000000..93cf88f --- /dev/null +++ b/src/cppunit/XmlOutputter.cpp @@ -0,0 +1,312 @@ +#include <cppunit/Exception.h> +#include <cppunit/Test.h> +#include <cppunit/TestResult.h> +#include <cppunit/XmlOutputter.h> +#include <map> +#include <stdlib.h> + + +namespace CppUnit +{ + +// XmlOutputter::Node +// ////////////////////////////////////////////////////////////////// + + +XmlOutputter::Node::Node( std::string elementName, + std::string content ) : + m_name( elementName ), + m_content( content ) +{ +} + + +XmlOutputter::Node::Node( std::string elementName, + int numericContent ) : + m_name( elementName ) +{ + m_content = asString( numericContent ); +} + + +XmlOutputter::Node::~Node() +{ + Nodes::iterator itNode = m_nodes.begin(); + while ( itNode != m_nodes.end() ) + delete *itNode++; +} + + +void +XmlOutputter::Node::addAttribute( std::string attributeName, + std::string value ) +{ + m_attributes.push_back( Attribute( attributeName, value ) ); +} + + +void +XmlOutputter::Node::addAttribute( std::string attributeName, + int numericValue ) +{ + addAttribute( attributeName, asString( numericValue ) ); +} + + +void +XmlOutputter::Node::addNode( Node *node ) +{ + m_nodes.push_back( node ); +} + + +std::string +XmlOutputter::Node::toString() const +{ + std::string element = "<"; + element += m_name; + element += " "; + element += attributesAsString(); + element += " >\n"; + + Nodes::const_iterator itNode = m_nodes.begin(); + while ( itNode != m_nodes.end() ) + { + const Node *node = *itNode++; + element += node->toString(); + } + + element += m_content; + + element += "</"; + element += m_name; + element += ">\n"; + + return element; +} + + +std::string +XmlOutputter::Node::attributesAsString() const +{ + std::string attributes; + Attributes::const_iterator itAttribute = m_attributes.begin(); + while ( itAttribute != m_attributes.end() ) + { + const Attribute &attribute = *itAttribute++; + attributes += attribute.first; + attributes += "=\""; + attributes += escape( attribute.second ); + attributes += "\""; + } + return attributes; +} + + +std::string +XmlOutputter::Node::escape( std::string value ) const +{ + std::string escaped; + for ( int index =0; index < value.length(); ++index ) + { + char c = value[index ]; + switch ( c ) // escape all predefined XML entity (safe?) + { + case '<': + escaped += "<"; + break; + case '>': + escaped += ">"; + break; + case '&': + escaped += "&"; + break; + case '\'': + escaped += "'"; + break; + case '"': + escaped += """; + break; + default: + escaped += c; + } + } + + return escaped; +} + +// should be somewhere else... Future CppUnit::String ? +std::string +XmlOutputter::Node::asString( int value ) +{ + OStringStream stream; + stream << value; + return stream.str(); +} + + + + +// XmlOutputter +// ////////////////////////////////////////////////////////////////// + +XmlOutputter::XmlOutputter( TestResult *result, + std::ostream &stream ) : + m_result( result ), + m_stream( stream ) +{ +} + + +XmlOutputter::~XmlOutputter() +{ +} + + +void +XmlOutputter::write() +{ + writeProlog(); + writeTestsResult(); +} + + +void +XmlOutputter::writeProlog() +{ + m_stream << "<?xml version=\"1.0\" " + "encoding='ISO-8859-1' standalone='yes' ?>" + << std::endl; +} + + +void +XmlOutputter::writeTestsResult() +{ + Node *rootNode = makeRootNode(); + m_stream << rootNode->toString(); + delete rootNode; +} + + +XmlOutputter::Node * +XmlOutputter::makeRootNode() +{ + Node *rootNode = new Node( "TestRun" ); + + FailedTests failedTests; + fillFailedTestsMap( failedTests ); + + addFailedTests( failedTests, rootNode ); + addSucessfulTests( failedTests, rootNode ); + addStatistics( rootNode ); + + return rootNode; +} + + +void +XmlOutputter::fillFailedTestsMap( FailedTests &failedTests ) +{ + const TestResult::TestFailures &failures = m_result->failures(); + TestResult::TestFailures::const_iterator itFailure = failures.begin(); + while ( itFailure != failures.end() ) + { + TestFailure *failure = *itFailure++; + failedTests.insert( std::make_pair(failure->failedTest(), failure ) ); + } +} + + +void +XmlOutputter::addFailedTests( FailedTests &failedTests, + Node *rootNode ) +{ + Node *testsNode = new Node( "FailedTests" ); + rootNode->addNode( testsNode ); + + const TestResult::Tests &tests = m_result->tests(); + for ( int testNumber = 0; testNumber < tests.size(); ++testNumber ) + { + Test *test = tests[testNumber]; + if ( failedTests.find( test ) != failedTests.end() ) + addFailedTest( test, failedTests[test], testNumber+1, testsNode ); + } +} + + +void +XmlOutputter::addSucessfulTests( FailedTests &failedTests, + Node *rootNode ) +{ + Node *testsNode = new Node( "SucessfulTests" ); + rootNode->addNode( testsNode ); + + const TestResult::Tests &tests = m_result->tests(); + for ( int testNumber = 0; testNumber < tests.size(); ++testNumber ) + { + Test *test = tests[testNumber]; + if ( failedTests.find( test ) == failedTests.end() ) + addSucessfulTest( test, testNumber+1, testsNode ); + } +} + + +void +XmlOutputter::addStatistics( Node *rootNode ) +{ + Node *statisticsNode = new Node( "Statistics" ); + rootNode->addNode( statisticsNode ); + statisticsNode->addNode( new Node( "Tests", m_result->runTests() ) ); + statisticsNode->addNode( new Node( "FailuresTotal", + m_result->testFailuresTotal() ) ); + statisticsNode->addNode( new Node( "Errors", m_result->testErrors() ) ); + statisticsNode->addNode( new Node( "Failures", m_result->testFailures() ) ); +} + + +void +XmlOutputter::addFailedTest( Test *test, + TestFailure *failure, + int testNumber, + Node *testsNode ) +{ + Exception *thrownException = failure->thrownException(); + + Node *testNode = new Node( "FailedTest", thrownException->what() ); + testsNode->addNode( testNode ); + testNode->addAttribute( "id", testNumber ); + testNode->addNode( new Node( "Name", test->getName() ) ); + testNode->addNode( new Node( "FailureType", + failure->isError() ? "Error" : "Assertion" ) ); + + if ( failure->sourceLine().isValid() ) + addFailureLocation( failure, testNode ); +} + + +void +XmlOutputter::addFailureLocation( TestFailure *failure, + Node *testNode ) +{ + Node *locationNode = new Node( "Location" ); + testNode->addNode( locationNode ); + SourceLine sourceLine = failure->sourceLine(); + locationNode->addNode( new Node( "File", sourceLine.fileName() ) ); + locationNode->addNode( new Node( "Line", sourceLine.lineNumber() ) ); +} + + +void +XmlOutputter::addSucessfulTest( Test *test, + int testNumber, + Node *testsNode ) +{ + Node *testNode = new Node( "Test" ); + testsNode->addNode( testNode ); + testNode->addAttribute( "id", testNumber ); + testNode->addNode( new Node( "Name", test->getName() ) ); +} + + +} // namespace CppUnit |
