summaryrefslogtreecommitdiff
path: root/src/cppunit/XmlOutputter.cpp
diff options
context:
space:
mode:
authorBaptiste Lepilleur <gaiacrtn@free.fr>2001-10-07 18:37:53 +0000
committerBaptiste Lepilleur <gaiacrtn@free.fr>2001-10-07 18:37:53 +0000
commit150339335e3c5538c1e496ae01babf148bd29ec5 (patch)
tree9f354aaee81e08c27dc6da0709074babde7672f5 /src/cppunit/XmlOutputter.cpp
parent4410db53e88dc5aca9f86abaf9dffccbd5f94471 (diff)
downloadcppunit-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.cpp312
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 += "&lt;";
+ break;
+ case '>':
+ escaped += "&gt;";
+ break;
+ case '&':
+ escaped += "&amp;";
+ break;
+ case '\'':
+ escaped += "&apos;";
+ break;
+ case '"':
+ escaped += "&quot;";
+ 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