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