1 #include "Config.h" 2 #ifndef UNITTEST_NO_DEFERRED_REPORTER 3 4 #include "XmlTestReporter.h" 5 6 #include <iostream> 7 #include <sstream> 8 #include <string> 9 10 using std::string; 11 using std::ostringstream; 12 using std::ostream; 13 14 namespace { 15 ReplaceChar(string & str,char c,string const & replacement)16 void ReplaceChar(string& str, char c, string const& replacement) 17 { 18 for (size_t pos = str.find(c); pos != string::npos; pos = str.find(c, pos + 1)) 19 str.replace(pos, 1, replacement); 20 } 21 XmlEscape(string const & value)22 string XmlEscape(string const& value) 23 { 24 string escaped = value; 25 26 ReplaceChar(escaped, '&', "&"); 27 ReplaceChar(escaped, '<', "<"); 28 ReplaceChar(escaped, '>', ">"); 29 ReplaceChar(escaped, '\'', "'"); 30 ReplaceChar(escaped, '\"', """); 31 32 return escaped; 33 } 34 BuildFailureMessage(string const & file,int line,string const & message)35 string BuildFailureMessage(string const& file, int line, string const& message) 36 { 37 ostringstream failureMessage; 38 failureMessage << file << "(" << line << ") : " << message; 39 return failureMessage.str(); 40 } 41 42 } 43 44 namespace UnitTest { 45 XmlTestReporter(ostream & ostream)46 XmlTestReporter::XmlTestReporter(ostream& ostream) 47 : m_ostream(ostream) 48 {} 49 ReportSummary(int totalTestCount,int failedTestCount,int failureCount,float secondsElapsed)50 void XmlTestReporter::ReportSummary(int totalTestCount, int failedTestCount, 51 int failureCount, float secondsElapsed) 52 { 53 AddXmlElement(m_ostream, NULL); 54 55 BeginResults(m_ostream, totalTestCount, failedTestCount, failureCount, secondsElapsed); 56 57 DeferredTestResultList const& results = GetResults(); 58 for (DeferredTestResultList::const_iterator i = results.begin(); i != results.end(); ++i) 59 { 60 BeginTest(m_ostream, *i); 61 62 if (i->failed) 63 AddFailure(m_ostream, *i); 64 65 EndTest(m_ostream, *i); 66 } 67 68 EndResults(m_ostream); 69 } 70 AddXmlElement(ostream & os,char const * encoding)71 void XmlTestReporter::AddXmlElement(ostream& os, char const* encoding) 72 { 73 os << "<?xml version=\"1.0\""; 74 75 if (encoding != NULL) 76 os << " encoding=\"" << encoding << "\""; 77 78 os << "?>"; 79 } 80 BeginResults(std::ostream & os,int totalTestCount,int failedTestCount,int failureCount,float secondsElapsed)81 void XmlTestReporter::BeginResults(std::ostream& os, int totalTestCount, int failedTestCount, 82 int failureCount, float secondsElapsed) 83 { 84 os << "<unittest-results" 85 << " tests=\"" << totalTestCount << "\"" 86 << " failedtests=\"" << failedTestCount << "\"" 87 << " failures=\"" << failureCount << "\"" 88 << " time=\"" << secondsElapsed << "\"" 89 << ">"; 90 } 91 EndResults(std::ostream & os)92 void XmlTestReporter::EndResults(std::ostream& os) 93 { 94 os << "</unittest-results>"; 95 } 96 BeginTest(std::ostream & os,DeferredTestResult const & result)97 void XmlTestReporter::BeginTest(std::ostream& os, DeferredTestResult const& result) 98 { 99 os << "<test" 100 << " suite=\"" << result.suiteName << "\"" 101 << " name=\"" << result.testName << "\"" 102 << " time=\"" << result.timeElapsed << "\""; 103 } 104 EndTest(std::ostream & os,DeferredTestResult const & result)105 void XmlTestReporter::EndTest(std::ostream& os, DeferredTestResult const& result) 106 { 107 if (result.failed) 108 os << "</test>"; 109 else 110 os << "/>"; 111 } 112 AddFailure(std::ostream & os,DeferredTestResult const & result)113 void XmlTestReporter::AddFailure(std::ostream& os, DeferredTestResult const& result) 114 { 115 os << ">"; // close <test> element 116 117 for (DeferredTestResult::FailureVec::const_iterator it = result.failures.begin(); 118 it != result.failures.end(); 119 ++it) 120 { 121 string const escapedMessage = XmlEscape(std::string(it->failureStr)); 122 string const message = BuildFailureMessage(result.failureFile, it->lineNumber, escapedMessage); 123 124 os << "<failure" << " message=\"" << message << "\"" << "/>"; 125 } 126 } 127 128 } 129 130 #endif 131