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