1 /*
2 -------------------------------------------------------------------------
3  CxxTest: A lightweight C++ unit testing library.
4  Copyright (c) 2008 Sandia Corporation.
5  This software is distributed under the LGPL License v3
6  For more information, see the COPYING file in the top CxxTest directory.
7  Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
8  the U.S. Government retains certain rights in this software.
9 -------------------------------------------------------------------------
10 */
11 
12 #ifndef UNIX_ERROR_PRINTER_H_N4C6JUX4
13 #define UNIX_ERROR_PRINTER_H_N4C6JUX4
14 
15 #ifndef _CXXTEST_HAVE_STD
16 #   define _CXXTEST_HAVE_STD
17 #endif // _CXXTEST_HAVE_STD
18 
19 #include <cxxtest/Flags.h>
20 #include <cxxtest/TestRunner.h>
21 #include <cxxtest/TestListener.h>
22 #include <cxxtest/TestTracker.h>
23 #include <cxxtest/ValueTraits.h>
24 #include <cxxtest/StdValueTraits.h>
25 #include <cxxtest/ErrorFormatter.h> // CxxTest::OutputStream
26 
27 namespace CxxTest
28 {
29 class UNIXErrorFormatter : public TestListener
30 {
31 public:
32     UNIXErrorFormatter(OutputStream *o, const char *preLine = ":", const char *postLine = "") :
_reported(false)33         _reported(false),
34         _o(o),
35         _preLine(preLine),
36         _postLine(postLine)
37     {
38     }
39 
run()40     int run()
41     {
42         TestRunner::runAllTests(*this);
43         return tracker().failedTests();
44     }
45 
totalTests(OutputStream & o)46     static void totalTests(OutputStream &o)
47     {
48         char s[WorldDescription::MAX_STRLEN_TOTAL_TESTS];
49         const WorldDescription &wd = tracker().world();
50         o << wd.strTotalTests(s) << (wd.numTotalTests() == 1 ? " test" : " tests");
51     }
52 
enterTest(const TestDescription &)53     void enterTest(const TestDescription &)
54     {
55         _reported = false;
56     }
57 
leaveWorld(const WorldDescription & desc)58     void leaveWorld(const WorldDescription &desc)
59     {
60         if (tracker().failedTests())
61         {
62             (*_o) << "Failed " << tracker().failedTests() << " of " << totalTests << endl;
63             unsigned numPassed = desc.numTotalTests() - tracker().failedTests() - tracer().skippedTests();
64             unsigned numTotal = desc.numTotalTests() - tracker().skippedTests();
65             if (numTotal == 0)
66             {
67                 (*_o) << "Success rate: 100%" << endl;
68             }
69             else
70             {
71                 (*_o) << "Success rate: " << (unsigned)(numPassed * 100.0 / numTotal) << "%" << endl;
72             }
73         }
74     }
75 
trace(const char * file,int line,const char * expression)76     void trace(const char *file, int line, const char *expression)
77     {
78         stop(file, line) << "Trace: " <<
79                          expression << endl;
80     }
81 
warning(const char * file,int line,const char * expression)82     void warning(const char *file, int line, const char *expression)
83     {
84         stop(file, line) << "Warning: " <<
85                          expression << endl;
86     }
87 
skippedTest(const char * file,int line,const char * expression)88     void skippedTest(const char *file, int line, const char *expression)
89     {
90         stop(file, line) << "Warning: Test skipped: " <<
91                          expression << endl;
92     }
93 
failedTest(const char * file,int line,const char * expression)94     void failedTest(const char *file, int line, const char *expression)
95     {
96         stop(file, line) << "Error: Test failed: " <<
97                          expression << endl;
98     }
99 
failedAssert(const char * file,int line,const char * expression)100     void failedAssert(const char *file, int line, const char *expression)
101     {
102         stop(file, line) << "Error: Assertion failed: " <<
103                          expression << endl;
104     }
105 
failedAssertEquals(const char * file,int line,const char * xStr,const char * yStr,const char * x,const char * y)106     void failedAssertEquals(const char *file, int line,
107                             const char *xStr, const char *yStr,
108                             const char *x, const char *y)
109     {
110         stop(file, line) << "Error: Expected (" <<
111                          xStr << " == " << yStr << "), found (" <<
112                          x << " != " << y << ")" << endl;
113     }
114 
failedAssertSameData(const char * file,int line,const char * xStr,const char * yStr,const char * sizeStr,const void * x,const void * y,unsigned size)115     void failedAssertSameData(const char *file, int line,
116                               const char *xStr, const char *yStr,
117                               const char *sizeStr, const void *x,
118                               const void *y, unsigned size)
119     {
120         stop(file, line) << "Error: Expected " << sizeStr << " (" << size << ") bytes to be equal at (" <<
121                          xStr << ") and (" << yStr << "), found:" << endl;
122         dump(x, size);
123         (*_o) << "     differs from" << endl;
124         dump(y, size);
125     }
126 
failedAssertSameFiles(const char * file,int line,const char *,const char *,const char * explanation)127     void failedAssertSameFiles(const char* file, int line,
128                                const char*, const char*,
129                                const char* explanation
130                               )
131     {
132         stop(file, line) << "Error: " << explanation << endl;
133     }
134 
failedAssertDelta(const char * file,int line,const char * xStr,const char * yStr,const char * dStr,const char * x,const char * y,const char * d)135     void failedAssertDelta(const char *file, int line,
136                            const char *xStr, const char *yStr, const char *dStr,
137                            const char *x, const char *y, const char *d)
138     {
139         stop(file, line) << "Error: Expected (" <<
140                          xStr << " == " << yStr << ") up to " << dStr << " (" << d << "), found (" <<
141                          x << " != " << y << ")" << endl;
142     }
143 
failedAssertDiffers(const char * file,int line,const char * xStr,const char * yStr,const char * value)144     void failedAssertDiffers(const char *file, int line,
145                              const char *xStr, const char *yStr,
146                              const char *value)
147     {
148         stop(file, line) << "Error: Expected (" <<
149                          xStr << " != " << yStr << "), found (" <<
150                          value << ")" << endl;
151     }
152 
failedAssertLessThan(const char * file,int line,const char * xStr,const char * yStr,const char * x,const char * y)153     void failedAssertLessThan(const char *file, int line,
154                               const char *xStr, const char *yStr,
155                               const char *x, const char *y)
156     {
157         stop(file, line) << "Error: Expected (" <<
158                          xStr << " < " << yStr << "), found (" <<
159                          x << " >= " << y << ")" << endl;
160     }
161 
failedAssertLessThanEquals(const char * file,int line,const char * xStr,const char * yStr,const char * x,const char * y)162     void failedAssertLessThanEquals(const char *file, int line,
163                                     const char *xStr, const char *yStr,
164                                     const char *x, const char *y)
165     {
166         stop(file, line) << "Error: Expected (" <<
167                          xStr << " <= " << yStr << "), found (" <<
168                          x << " > " << y << ")" << endl;
169     }
170 
failedAssertRelation(const char * file,int line,const char * relation,const char * xStr,const char * yStr,const char * x,const char * y)171     void failedAssertRelation(const char *file, int line,
172                               const char *relation, const char *xStr, const char *yStr,
173                               const char *x, const char *y)
174     {
175         stop(file, line) << "Error: Expected " << relation << "( " <<
176                          xStr << ", " << yStr << " ), found !" << relation << "( " << x << ", " << y << " )" << endl;
177     }
178 
failedAssertPredicate(const char * file,int line,const char * predicate,const char * xStr,const char * x)179     void failedAssertPredicate(const char *file, int line,
180                                const char *predicate, const char *xStr, const char *x)
181     {
182         stop(file, line) << "Error: Expected " << predicate << "( " <<
183                          xStr << " ), found !" << predicate << "( " << x << " )" << endl;
184     }
185 
failedAssertThrows(const char * file,int line,const char * expression,const char * type,bool otherThrown)186     void failedAssertThrows(const char *file, int line,
187                             const char *expression, const char *type,
188                             bool otherThrown)
189     {
190         stop(file, line) << "Error: Expected (" << expression << ") to throw (" <<
191                          type << ") but it " << (otherThrown ? "threw something else" : "didn't throw") <<
192                          endl;
193     }
194 
failedAssertThrowsNot(const char * file,int line,const char * expression)195     void failedAssertThrowsNot(const char *file, int line, const char *expression)
196     {
197         stop(file, line) << "Error: Expected (" << expression << ") not to throw, but it did" <<
198                          endl;
199     }
200 
201 protected:
outputStream()202     OutputStream *outputStream() const
203     {
204         return _o;
205     }
206 
207 private:
208     UNIXErrorFormatter(const UNIXErrorFormatter &);
209     UNIXErrorFormatter &operator=(const UNIXErrorFormatter &);
210 
stop(const char * file,int line)211     OutputStream &stop(const char *file, int line)
212     {
213         reportTest();
214         return (*_o) << file << _preLine << line << _postLine << ": ";
215     }
216 
reportTest(void)217     void reportTest(void)
218     {
219         if (_reported)
220         {
221             return;
222         }
223         (*_o) << tracker().suite().file() << ": In " << tracker().suite().suiteName() << "::" << tracker().test().testName() << ":" << endl;
224         _reported = true;
225     }
226 
dump(const void * buffer,unsigned size)227     void dump(const void *buffer, unsigned size)
228     {
229         if (!buffer)
230         {
231             dumpNull();
232         }
233         else
234         {
235             dumpBuffer(buffer, size);
236         }
237     }
238 
dumpNull()239     void dumpNull()
240     {
241         (*_o) << "   (null)" << endl;
242     }
243 
dumpBuffer(const void * buffer,unsigned size)244     void dumpBuffer(const void *buffer, unsigned size)
245     {
246         unsigned dumpSize = size;
247         if (maxDumpSize() && dumpSize > maxDumpSize())
248         {
249             dumpSize = maxDumpSize();
250         }
251 
252         const unsigned char *p = (const unsigned char *)buffer;
253         (*_o) << "   { ";
254         for (unsigned i = 0; i < dumpSize; ++ i)
255         {
256             (*_o) << byteToHex(*p++) << " ";
257         }
258         if (dumpSize < size)
259         {
260             (*_o) << "... ";
261         }
262         (*_o) << "}" << endl;
263     }
264 
endl(OutputStream & o)265     static void endl(OutputStream &o)
266     {
267         OutputStream::endl(o);
268     }
269 
270     bool _reported;
271     OutputStream *_o;
272     const char *_preLine;
273     const char *_postLine;
274 };
275 
276 // ========================================================================================
277 // = Actual runner is a subclass only because that is how the original ErrorPrinter works =
278 // ========================================================================================
279 
280 class unix : public UNIXErrorFormatter
281 {
282 public:
CXXTEST_STD(ostream)283     unix(CXXTEST_STD(ostream) &o = CXXTEST_STD(cerr), const char *preLine = ":", const char *postLine = "") :
284         UNIXErrorFormatter(new Adapter(o), preLine, postLine) {}
~unix()285     virtual ~unix() { delete outputStream(); }
286 
287 private:
288     class Adapter : public OutputStream
289     {
290         CXXTEST_STD(ostream) &_o;
291     public:
Adapter(CXXTEST_STD (ostream)& o)292         Adapter(CXXTEST_STD(ostream) &o) : _o(o) {}
flush()293         void flush() { _o.flush(); }
294         OutputStream &operator<<(const char *s) { _o << s; return *this; }
295         OutputStream &operator<<(Manipulator m) { return OutputStream::operator<<(m); }
296         OutputStream &operator<<(unsigned i)
297         {
298             char s[1 + 3 * sizeof(unsigned)];
299             numberToString(i, s);
300             _o << s;
301             return *this;
302         }
303     };
304 };
305 }
306 
307 #endif /* end of include guard: UNIX_ERROR_PRINTER_H_N4C6JUX4 */
308 
309 // Copyright 2008 Sandia Corporation. Under the terms of Contract
310 // DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government
311 // retains certain rights in this software.
312