XmlTestReporter.cpp 3.2 KB

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