📄 xmloutputter.cpp
字号:
#include <cppunit/Exception.h>#include <cppunit/Test.h>#include <cppunit/TestFailure.h>#include <cppunit/TestResultCollector.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( TestResultCollector *result, std::ostream &stream, std::string encoding ) : m_result( result ), m_stream( stream ), m_encoding( encoding ){}XmlOutputter::~XmlOutputter(){}void XmlOutputter::write(){ writeProlog(); writeTestsResult();}void XmlOutputter::writeProlog(){ m_stream << "<?xml version=\"1.0\" " "encoding='" << m_encoding << "' 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 TestResultCollector::TestFailures &failures = m_result->failures(); TestResultCollector::TestFailures::const_iterator itFailure = failures.begin(); while ( itFailure != failures.end() ) { TestFailure *failure = *itFailure++; failedTests.insert( std::make_pair(failure->failedTest(), failure ) ); }}voidXmlOutputter::addFailedTests( FailedTests &failedTests, Node *rootNode ){ Node *testsNode = new Node( "FailedTests" ); rootNode->addNode( testsNode ); const TestResultCollector::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 ); }}voidXmlOutputter::addSucessfulTests( FailedTests &failedTests, Node *rootNode ){ Node *testsNode = new Node( "SucessfulTests" ); rootNode->addNode( testsNode ); const TestResultCollector::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 ); }}voidXmlOutputter::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() ) );}voidXmlOutputter::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 );}voidXmlOutputter::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() ) );}voidXmlOutputter::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
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -