1//
2// TextTestResult.cpp
3//
4
5
6#include "Poco/CppUnit/TextTestResult.h"
7#include "Poco/CppUnit/CppUnitException.h"
8#include "Poco/CppUnit/Test.h"
9#include "Poco/CppUnit/estring.h"
10#include <iostream>
11#include <iomanip>
12#include <cstdlib>
13#include <cctype>
14
15
16namespace CppUnit {
17
18
19TextTestResult::TextTestResult():
20 _ostr(std::cout)
21{
22 setup();
23}
24
25
26TextTestResult::TextTestResult(std::ostream& ostr):
27 _ostr(ostr)
28{
29 setup();
30}
31
32
33void TextTestResult::setup()
34{
35#if !defined(_WIN32_WCE)
36 const char* env = std::getenv("CPPUNIT_IGNORE");
37 if (env)
38 {
39 std::string ignored = env;
40 std::string::const_iterator it = ignored.begin();
41 std::string::const_iterator end = ignored.end();
42 while (it != end)
43 {
44 while (it != end && (std::isspace(*it) || *it == '"' || *it == '\'')) ++it;
45 std::string test;
46 while (it != end && *it != ',' && *it != '"' && *it != '\'') test += *it++;
47 if (it != end && (*it == ',' || *it == '"' || *it == '\'')) ++it;
48 if (!test.empty()) _ignored.insert(test);
49 }
50 }
51#endif
52}
53
54
55void TextTestResult::addError(Test* test, CppUnitException* e)
56{
57 if (_ignored.find(test->toString()) == _ignored.end())
58 {
59 TestResult::addError(test, e);
60 _ostr << "ERROR" << std::flush;
61 }
62 else
63 {
64 _ostr << "ERROR (ignored)" << std::flush;
65 }
66}
67
68
69void TextTestResult::addFailure(Test* test, CppUnitException* e)
70{
71 if (_ignored.find(test->toString()) == _ignored.end())
72 {
73 TestResult::addFailure(test, e);
74 _ostr << "FAILURE" << std::flush;
75 }
76 else
77 {
78 _ostr << "FAILURE (ignored)" << std::flush;
79 }
80}
81
82
83void TextTestResult::startTest(Test* test)
84{
85 TestResult::startTest(test);
86 _ostr << "\n" << shortName(test->toString()) << ": ";
87}
88
89
90void TextTestResult::printErrors(std::ostream& stream)
91{
92 if (testErrors() != 0)
93 {
94 stream << "\n";
95
96 if (testErrors() == 1)
97 stream << "There was " << testErrors() << " error: " << std::endl;
98 else
99 stream << "There were " << testErrors() << " errors: " << std::endl;
100
101 int i = 1;
102 for (std::vector<TestFailure*>::iterator it = errors().begin(); it != errors().end(); ++it)
103 {
104 TestFailure* failure = *it;
105 CppUnitException* e = failure->thrownException();
106
107 stream << std::setw(2) << i
108 << ": "
109 << failure->failedTest()->toString() << "\n"
110 << " \"" << (e ? e->what() : "") << "\"\n"
111 << " in \""
112 << (e ? e->fileName() : std::string())
113 << "\", line ";
114 if (e == 0)
115 {
116 stream << "0";
117 }
118 else
119 {
120 stream << e->lineNumber();
121 if (e->data2LineNumber() != CppUnitException::CPPUNIT_UNKNOWNLINENUMBER)
122 {
123 stream << " data lines " << e->data1LineNumber()
124 << ", " << e->data2LineNumber();
125 }
126 else if (e->data1LineNumber() != CppUnitException::CPPUNIT_UNKNOWNLINENUMBER)
127 {
128 stream << " data line " << e->data1LineNumber();
129 }
130 }
131 stream << "\n";
132 i++;
133 }
134 }
135}
136
137
138void TextTestResult::printFailures(std::ostream& stream)
139{
140 if (testFailures() != 0)
141 {
142 stream << "\n";
143 if (testFailures() == 1)
144 stream << "There was " << testFailures() << " failure: " << std::endl;
145 else
146 stream << "There were " << testFailures() << " failures: " << std::endl;
147
148 int i = 1;
149
150 for (std::vector<TestFailure*>::iterator it = failures().begin(); it != failures().end(); ++it)
151 {
152 TestFailure* failure = *it;
153 CppUnitException* e = failure->thrownException();
154
155 stream << std::setw(2) << i
156 << ": "
157 << failure->failedTest()->toString() << "\n"
158 << " \"" << (e ? e->what() : "") << "\"\n"
159 << " in \""
160 << (e ? e->fileName() : std::string())
161 << "\", line ";
162 if (e == 0)
163 {
164 stream << "0";
165 }
166 else
167 {
168 stream << e->lineNumber();
169 if (e->data2LineNumber() != CppUnitException::CPPUNIT_UNKNOWNLINENUMBER)
170 {
171 stream << " data lines "
172 << e->data1LineNumber()
173 << ", " << e->data2LineNumber();
174 }
175 else if (e->data1LineNumber() != CppUnitException::CPPUNIT_UNKNOWNLINENUMBER)
176 {
177 stream << " data line " << e->data1LineNumber();
178 }
179 }
180 stream << "\n";
181 i++;
182 }
183 }
184}
185
186
187void TextTestResult::print(std::ostream& stream)
188{
189 printHeader(stream);
190 printErrors(stream);
191 printFailures(stream);
192}
193
194
195void TextTestResult::printHeader(std::ostream& stream)
196{
197 stream << "\n\n";
198 if (wasSuccessful())
199 stream << "OK ("
200 << runTests() << " tests)"
201 << std::endl;
202 else
203 stream << "!!!FAILURES!!!" << std::endl
204 << "Runs: "
205 << runTests ()
206 << " Failures: "
207 << testFailures ()
208 << " Errors: "
209 << testErrors ()
210 << std::endl;
211}
212
213
214std::string TextTestResult::shortName(const std::string& testName)
215{
216 std::string::size_type pos = testName.rfind('.');
217 if (pos != std::string::npos)
218 return std::string(testName, pos + 1);
219 else
220 return testName;
221}
222
223
224} // namespace CppUnit
225