]> git.stg.codes - stg.git/blob - tests/tut/tut_console_reporter.hpp
Added specialization of str2x for doubles.
[stg.git] / tests / tut / tut_console_reporter.hpp
1 #ifndef TUT_CONSOLE_REPORTER
2 #define TUT_CONSOLE_REPORTER
3 #include <tut/tut.hpp>
4 #include <cassert>
5
6 /**
7  * Template Unit Tests Framework for C++.
8  * http://tut.dozen.ru
9  *
10  * @author Vladimir Dyuzhev, Vladimir.Dyuzhev@gmail.com
11  */
12 namespace
13 {
14
15 std::ostream& operator<<(std::ostream& os, const tut::test_result& tr)
16 {
17     switch(tr.result)
18     {
19         case tut::test_result::ok:
20             os << '.';
21             break;
22         case tut::test_result::fail:
23             os << '[' << tr.test << "=F]";
24             break;
25         case tut::test_result::ex_ctor:
26             os << '[' << tr.test << "=C]";
27             break;
28         case tut::test_result::ex:
29             os << '[' << tr.test << "=X]";
30             break;
31         case tut::test_result::warn:
32             os << '[' << tr.test << "=W]";
33             break;
34         case tut::test_result::term:
35             os << '[' << tr.test << "=T]";
36             break;
37         case tut::test_result::rethrown:
38             os << '[' << tr.test << "=P]";
39             break;
40         case tut::test_result::skipped:
41             os << '[' << tr.test << "=S]";
42             break;
43         case tut::test_result::dummy:
44             throw tut::tut_error("console reporter called for dummy test result");
45     }
46
47     return os;
48 }
49
50 } // end of namespace
51
52 namespace tut
53 {
54
55 /**
56  * Default TUT callback handler.
57  */
58 class console_reporter : public tut::callback
59 {
60     std::string current_group;
61     typedef std::vector<tut::test_result> not_passed_list;
62     not_passed_list not_passed;
63     std::ostream& os;
64
65     console_reporter(const console_reporter &);
66     console_reporter &operator=(const console_reporter &);
67 public:
68
69     int ok_count;
70     int exceptions_count;
71     int failures_count;
72     int terminations_count;
73     int warnings_count;
74     int skipped_count;
75
76     console_reporter()
77         : current_group(),
78           not_passed(),
79           os(std::cout),
80           ok_count(0),
81           exceptions_count(0),
82           failures_count(0),
83           terminations_count(0),
84           warnings_count(0),
85           skipped_count(0)
86     {
87         init();
88     }
89
90     console_reporter(std::ostream& out)
91         : current_group(),
92           not_passed(),
93           os(out),
94           ok_count(0),
95           exceptions_count(0),
96           failures_count(0),
97           terminations_count(0),
98           warnings_count(0),
99           skipped_count(0)
100
101     {
102         init();
103     }
104
105     void run_started()
106     {
107         init();
108     }
109
110     void test_completed(const tut::test_result& tr)
111     {
112         if (tr.group != current_group)
113         {
114             os << std::endl << tr.group << ": " << std::flush;
115             current_group = tr.group;
116         }
117
118         os << tr << std::flush;
119
120         // update global statistics
121         switch (tr.result) {
122             case test_result::ok:
123                 ok_count++;
124                 break;
125             case test_result::fail:
126             case test_result::rethrown:
127                 failures_count++;
128                 break;
129             case test_result::ex:
130             case test_result::ex_ctor:
131                 exceptions_count++;
132                 break;
133             case test_result::warn:
134                 warnings_count++;
135                 break;
136             case test_result::term:
137                 terminations_count++;
138                 break;
139             case test_result::skipped:
140                 skipped_count++;
141                 break;
142             case tut::test_result::dummy:
143                 assert( (tr.result != tut::test_result::dummy) && "Should never be called");
144         } // switch
145
146         if ( (tr.result != tut::test_result::ok) &&
147              (tr.result != tut::test_result::skipped) )
148         {
149             not_passed.push_back(tr);
150         }
151     }
152
153     void run_completed()
154     {
155         os << std::endl;
156
157         if (not_passed.size() > 0)
158         {
159             not_passed_list::const_iterator i = not_passed.begin();
160             while (i != not_passed.end())
161             {
162                 tut::test_result tr = *i;
163
164                 os << std::endl;
165
166                 os << "---> " << "group: " << tr.group
167                 << ", test: test<" << tr.test << ">"
168                 << (!tr.name.empty() ? (std::string(" : ") + tr.name) : std::string())
169                 << std::endl;
170
171 #if defined(TUT_USE_POSIX)
172                 if(tr.pid != getpid())
173                 {
174                     os << "     child pid: " << tr.pid << std::endl;
175                 }
176 #endif
177                 os << "     problem: ";
178                 switch(tr.result)
179                 {
180                 case test_result::rethrown:
181                     os << "assertion failed in child" << std::endl;
182                     break;
183                 case test_result::fail:
184                     os << "assertion failed" << std::endl;
185                     break;
186                 case test_result::ex:
187                 case test_result::ex_ctor:
188                     os << "unexpected exception" << std::endl;
189                     if( tr.exception_typeid != "" )
190                     {
191                         os << "     exception typeid: "
192                         << tr.exception_typeid << std::endl;
193                     }
194                     break;
195                 case test_result::term:
196                     os << "would be terminated" << std::endl;
197                     break;
198                 case test_result::warn:
199                     os << "test passed, but cleanup code (destructor) raised"
200                         " an exception" << std::endl;
201                     break;
202                 default:
203                     break;
204                 }
205
206                 if (!tr.message.empty())
207                 {
208                     if (tr.result == test_result::fail)
209                     {
210                         os << "     failed assertion: `" << tr.message << "`"
211                             << std::endl;
212                     }
213                     else
214                     {
215                         os << "     message: `" << tr.message << "`"
216                             << std::endl;
217                     }
218                 }
219
220                 ++i;
221             }
222         }
223
224         os << std::endl;
225
226         os << "tests summary:";
227         if (terminations_count > 0)
228         {
229             os << " terminations:" << terminations_count;
230         }
231         if (exceptions_count > 0)
232         {
233             os << " exceptions:" << exceptions_count;
234         }
235         if (failures_count > 0)
236         {
237             os << " failures:" << failures_count;
238         }
239         if (warnings_count > 0)
240         {
241             os << " warnings:" << warnings_count;
242         }
243
244         os << " ok:" << ok_count;
245
246         if(skipped_count > 0)
247         {
248             os << " skipped:" << skipped_count;
249         }
250         os << std::endl;
251     }
252
253     virtual bool all_ok() const
254     {
255         return not_passed.empty();
256     }
257
258 private:
259
260     void init()
261     {
262         ok_count = 0;
263         exceptions_count = 0;
264         failures_count = 0;
265         terminations_count = 0;
266         warnings_count = 0;
267         skipped_count = 0;
268         not_passed.clear();
269     }
270 };
271
272 }
273
274 #endif