summaryrefslogtreecommitdiff
path: root/libtest/formatter.cc
diff options
context:
space:
mode:
Diffstat (limited to 'libtest/formatter.cc')
-rw-r--r--libtest/formatter.cc88
1 files changed, 78 insertions, 10 deletions
diff --git a/libtest/formatter.cc b/libtest/formatter.cc
index 01c57609..7cb3ea0a 100644
--- a/libtest/formatter.cc
+++ b/libtest/formatter.cc
@@ -44,6 +44,56 @@
namespace libtest {
+std::string& escape4XML(std::string const& arg, std::string& escaped_string)
+{
+ escaped_string.clear();
+
+ escaped_string+= '"';
+ for (std::string::const_iterator x= arg.begin(), end= arg.end(); x != end; ++x)
+ {
+ unsigned char c= *x;
+ if (c == '&')
+ {
+ escaped_string+= "&";
+ }
+ else if (c == '>')
+ {
+ escaped_string+= ">";
+ }
+ else if (c == '<')
+ {
+ escaped_string+= "&lt;";
+ }
+ else if (c == '\'')
+ {
+ escaped_string+= "&apos;"; break;
+ }
+ else if (c == '"')
+ {
+ escaped_string+= "&quot;";
+ }
+ else if (c == ' ')
+ {
+ escaped_string+= ' ';
+ }
+ else if (isalnum(c))
+ {
+ escaped_string+= c;
+ }
+ else
+ {
+ char const* const hexdig= "0123456789ABCDEF";
+ escaped_string+= "&#x";
+ escaped_string+= hexdig[c >> 4];
+ escaped_string+= hexdig[c & 0xF];
+ escaped_string+= ';';
+ }
+ }
+ escaped_string+= '"';
+
+ return escaped_string;
+}
+
class TestCase {
public:
TestCase(const std::string& arg):
@@ -110,7 +160,10 @@ TestCase* Formatter::current()
void Formatter::skipped()
{
current()->result(TEST_SKIPPED);
- Out << name() << "." << current()->name() << "\t\t\t\t\t" << "[ " << test_strerror(current()->result()) << " ]";
+ Out << name() << "."
+ << current()->name()
+ << "\t\t\t\t\t"
+ << "[ " << test_strerror(current()->result()) << " ]";
reset();
}
@@ -120,7 +173,9 @@ void Formatter::failed()
assert(current());
current()->result(TEST_FAILURE);
- Out << name() << "." << current()->name() << "\t\t\t\t\t" << "[ " << test_strerror(current()->result()) << " ]";
+ Out << name()
+ << "." << current()->name() << "\t\t\t\t\t"
+ << "[ " << test_strerror(current()->result()) << " ]";
reset();
}
@@ -129,6 +184,7 @@ void Formatter::success(const libtest::Timer& timer_)
{
assert(current());
current()->result(TEST_SUCCESS, timer_);
+ std::string escaped_string;
Out << name() << "."
<< current()->name()
@@ -141,38 +197,50 @@ void Formatter::success(const libtest::Timer& timer_)
void Formatter::xml(libtest::Framework& framework_, std::ofstream& output)
{
- output << "<testsuites name=\"" << framework_.name() << "\">" << std::endl;
+ std::string escaped_string;
+
+ output << "<testsuites name="
+ << escape4XML(framework_.name(), escaped_string) << ">" << std::endl;
+
for (Suites::iterator framework_iter= framework_.suites().begin();
framework_iter != framework_.suites().end();
++framework_iter)
{
- output << "\t<testsuite name=\"" << (*framework_iter)->name() << "\" classname=\"\" package=\"\">" << std::endl;
+ output << "\t<testsuite name="
+ << escape4XML((*framework_iter)->name(), escaped_string)
+#if 0
+ << " classname=\"\" package=\"\""
+#endif
+ << ">" << std::endl;
for (TestCases::iterator case_iter= (*framework_iter)->formatter()->testcases().begin();
case_iter != (*framework_iter)->formatter()->testcases().end();
++case_iter)
{
- output << "\t\t<testcase name=\""
- << (*case_iter)->name()
- << "\" time=\""
+ output << "\t\t<testcase name="
+ << escape4XML((*case_iter)->name(), escaped_string)
+ << " time=\""
<< (*case_iter)->timer().elapsed_milliseconds()
- << "\">"
- << std::endl;
+ << "\"";
switch ((*case_iter)->result())
{
case TEST_SKIPPED:
+ output << ">" << std::endl;
output << "\t\t <skipped/>" << std::endl;
+ output << "\t\t</testcase>" << std::endl;
break;
case TEST_FAILURE:
+ output << ">" << std::endl;
output << "\t\t <failure message=\"\" type=\"\"/>"<< std::endl;
+ output << "\t\t</testcase>" << std::endl;
break;
case TEST_SUCCESS:
+ output << "/>" << std::endl;
break;
}
- output << "\t\t</testcase>" << std::endl;
}
output << "\t</testsuite>" << std::endl;
}