| #include "Config.h" |
| #ifndef UNITTEST_NO_DEFERRED_REPORTER |
| |
| #include "XmlTestReporter.h" |
| |
| #include <iostream> |
| #include <sstream> |
| #include <string> |
| |
| using std::string; |
| using std::ostringstream; |
| using std::ostream; |
| |
| namespace { |
| |
| void ReplaceChar(string& str, char c, string const& replacement) |
| { |
| for (size_t pos = str.find(c); pos != string::npos; pos = str.find(c, pos + 1)) |
| str.replace(pos, 1, replacement); |
| } |
| |
| string XmlEscape(string const& value) |
| { |
| string escaped = value; |
| |
| ReplaceChar(escaped, '&', "&"); |
| ReplaceChar(escaped, '<', "<"); |
| ReplaceChar(escaped, '>', ">"); |
| ReplaceChar(escaped, '\'', "'"); |
| ReplaceChar(escaped, '\"', """); |
| |
| return escaped; |
| } |
| |
| string BuildFailureMessage(string const& file, int line, string const& message) |
| { |
| ostringstream failureMessage; |
| failureMessage << file << "(" << line << ") : " << message; |
| return failureMessage.str(); |
| } |
| |
| } |
| |
| namespace UnitTest { |
| |
| XmlTestReporter::XmlTestReporter(ostream& ostream) |
| : m_ostream(ostream) |
| { |
| } |
| |
| void XmlTestReporter::ReportSummary(int totalTestCount, int failedTestCount, |
| int failureCount, float secondsElapsed) |
| { |
| AddXmlElement(m_ostream, NULL); |
| |
| BeginResults(m_ostream, totalTestCount, failedTestCount, failureCount, secondsElapsed); |
| |
| DeferredTestResultList const& results = GetResults(); |
| for (DeferredTestResultList::const_iterator i = results.begin(); i != results.end(); ++i) |
| { |
| BeginTest(m_ostream, *i); |
| |
| if (i->failed) |
| AddFailure(m_ostream, *i); |
| |
| EndTest(m_ostream, *i); |
| } |
| |
| EndResults(m_ostream); |
| } |
| |
| void XmlTestReporter::AddXmlElement(ostream& os, char const* encoding) |
| { |
| os << "<?xml version=\"1.0\""; |
| |
| if (encoding != NULL) |
| os << " encoding=\"" << encoding << "\""; |
| |
| os << "?>"; |
| } |
| |
| void XmlTestReporter::BeginResults(std::ostream& os, int totalTestCount, int failedTestCount, |
| int failureCount, float secondsElapsed) |
| { |
| os << "<unittest-results" |
| << " tests=\"" << totalTestCount << "\"" |
| << " failedtests=\"" << failedTestCount << "\"" |
| << " failures=\"" << failureCount << "\"" |
| << " time=\"" << secondsElapsed << "\"" |
| << ">"; |
| } |
| |
| void XmlTestReporter::EndResults(std::ostream& os) |
| { |
| os << "</unittest-results>"; |
| } |
| |
| void XmlTestReporter::BeginTest(std::ostream& os, DeferredTestResult const& result) |
| { |
| os << "<test" |
| << " suite=\"" << result.suiteName << "\"" |
| << " name=\"" << result.testName << "\"" |
| << " time=\"" << result.timeElapsed << "\""; |
| } |
| |
| void XmlTestReporter::EndTest(std::ostream& os, DeferredTestResult const& result) |
| { |
| if (result.failed) |
| os << "</test>"; |
| else |
| os << "/>"; |
| } |
| |
| void XmlTestReporter::AddFailure(std::ostream& os, DeferredTestResult const& result) |
| { |
| os << ">"; // close <test> element |
| |
| for (DeferredTestResult::FailureVec::const_iterator it = result.failures.begin(); |
| it != result.failures.end(); |
| ++it) |
| { |
| string const escapedMessage = XmlEscape(std::string(it->failureStr)); |
| string const message = BuildFailureMessage(result.failureFile, it->lineNumber, escapedMessage); |
| |
| os << "<failure" << " message=\"" << message << "\"" << "/>"; |
| } |
| } |
| |
| } |
| |
| #endif |