micro-test-plus 3.2.0
µTest++, a lightweight testing framework for embedded platforms
Loading...
Searching...
No Matches
test-reporter.cpp
Go to the documentation of this file.
1/*
2 * This file is part of the µOS++ distribution.
3 * (https://github.com/micro-os-plus/)
4 * Copyright (c) 2021 Liviu Ionescu. All rights reserved.
5 *
6 * Permission to use, copy, modify, and/or distribute this software
7 * for any purpose is hereby granted, under the terms of the MIT license.
8 *
9 * If a copy of the license was not distributed with this file, it can
10 * be obtained from <https://opensource.org/licenses/MIT/>.
11 *
12 * Major parts of the code are inspired from v1.1.8 of the Boost UT project,
13 * released under the terms of the Boost Version 1.0 Software License,
14 * which can be obtained from <https://www.boost.org/LICENSE_1_0.txt>.
15 */
16
17// ----------------------------------------------------------------------------
18
19#if defined(MICRO_OS_PLUS_INCLUDE_CONFIG_H)
20#include <micro-os-plus/config.h>
21#endif // MICRO_OS_PLUS_INCLUDE_CONFIG_H
22
24
25// ----------------------------------------------------------------------------
26
27#pragma GCC diagnostic ignored "-Waggregate-return"
28#if defined(__clang__)
29#pragma clang diagnostic ignored "-Wc++98-compat"
30#pragma clang diagnostic ignored "-Wc++98-compat-pedantic"
31#endif
32
34{
35 // --------------------------------------------------------------------------
36
37 test_reporter&
39 {
41 return stream;
42 }
43
44 // --------------------------------------------------------------------------
45
46 void
48 {
49 *this << colors_.pass;
51 {
52 *this << " ";
53 }
54 *this << " ✓ ";
55 *this << colors_.none;
56 if (!message.empty ())
57 {
58 *this << message.c_str ();
59 }
60 }
61
62 void
64 {
65 *this << endl;
66
67 flush ();
68 }
69
70 void
72 std::string& message, const reflection::source_location& location)
73 {
74 *this << colors_.fail;
76 {
77 *this << " ";
78 }
79 *this << " ✗ ";
80 *this << colors_.none;
81 if (!message.empty ())
82 {
83 *this << message.c_str ();
84 *this << " ";
85 }
86 *this << colors_.fail << "FAILED" << colors_.none;
87#pragma GCC diagnostic push
88#if defined(__clang__)
89#pragma clang diagnostic ignored "-Wsign-conversion"
90#elif defined(__GNUC__)
91#pragma GCC diagnostic ignored "-Wnarrowing"
92#pragma GCC diagnostic ignored "-Wsign-conversion"
93#endif
94 *this << " (" << reflection::short_name (location.file_name ()) << ":"
96 location.line ()
97 };
98#pragma GCC diagnostic pop
99 }
100
101 void
103 {
104 *this << ")";
105 if (abort)
106 {
107 *this << " aborted...";
108 }
109 *this << endl;
110
111 flush ();
112 }
113
116 {
117 // Call the endl function.
118 (*func) (*this);
119 return *this;
120 }
121
122 void
124 {
125 out_.append ("\n");
126 flush ();
127 }
128
129 void
131 {
132 fflush (stdout); // Sync STDOUT.
133 }
134
136 test_reporter::operator<< (std::string_view sv)
137 {
138 out_.append (sv);
139 return *this;
140 }
141
144 {
145 out_.append (1, c);
146 return *this;
147 }
148
150 test_reporter::operator<< (const char* s)
151 {
152 out_.append (s);
153 return *this;
154 }
155
158 {
159 out_.append (s);
160 return *this;
161 }
162
165 {
166 out_.append (v ? "true" : "false");
167 return *this;
168 }
169
171 test_reporter::operator<< (std::nullptr_t)
172 {
173 out_.append ("nullptr");
174 return *this;
175 }
176
178 test_reporter::operator<< (signed char c)
179 {
180 out_.append (std::to_string (c));
181 out_.append ("c");
182 return *this;
183 }
184
186 test_reporter::operator<< (unsigned char c)
187 {
188 out_.append (std::to_string (static_cast<int> (c)));
189 out_.append ("uc");
190 return *this;
191 }
192
194 test_reporter::operator<< (signed short v)
195 {
196 out_.append (std::to_string (v));
197 out_.append ("s");
198 return *this;
199 }
200
202 test_reporter::operator<< (unsigned short v)
203 {
204 out_.append (std::to_string (static_cast<long> (v)));
205 out_.append ("us");
206 return *this;
207 }
208
210 test_reporter::operator<< (signed int v)
211 {
212 out_.append (std::to_string (v));
213 return *this;
214 }
215
217 test_reporter::operator<< (unsigned int v)
218 {
219 out_.append (std::to_string (v));
220 out_.append ("u");
221 return *this;
222 }
223
225 test_reporter::operator<< (signed long v)
226 {
227 out_.append (std::to_string (v));
228 out_.append ("l");
229 return *this;
230 }
231
233 test_reporter::operator<< (unsigned long v)
234 {
235 out_.append (std::to_string (v));
236 out_.append ("ul");
237 return *this;
238 }
239
241 test_reporter::operator<< (signed long long v)
242 {
243 out_.append (std::to_string (v));
244 out_.append ("ll");
245 return *this;
246 }
247
249 test_reporter::operator<< (unsigned long long v)
250 {
251 out_.append (std::to_string (v));
252 out_.append ("ull");
253 return *this;
254 }
255
258 {
259 out_.append (std::to_string (v));
260 out_.append ("f");
261 return *this;
262 }
263
266 {
267 out_.append (std::to_string (v));
268 return *this;
269 }
270
272 test_reporter::operator<< (long double v)
273 {
274 out_.append (std::to_string (v));
275 out_.append ("l");
276 return *this;
277 }
278
279 void
280 test_reporter::begin_test_case ([[maybe_unused]] const char* name)
281 {
282 is_in_test_case_ = true;
283
284 if (!out_.empty () && (verbosity == verbosity::verbose))
285 {
286 if (add_empty_line)
287 {
288 printf ("\n");
289 }
290 output ();
291 add_empty_line = true;
292 }
293
294 out_.clear ();
295
296 flush ();
297 }
298
299 void
300 test_reporter::end_test_case ([[maybe_unused]] const char* name)
301 {
303 {
305 {
306 if (true /* add_empty_line */)
307 {
308 printf ("\n");
309 }
310 printf (" • %s - test case started\n", name);
311 output ();
312 printf (
313 " %s✗%s %s - test case %sFAILED%s (%d %s passed, %d "
314 "failed)\n",
318 ? "check"
319 : "checks",
321 add_empty_line = true;
322 }
323 else
324 {
325 if (add_empty_line)
326 {
327 printf ("\n");
328 }
330 {
331 printf (" • %s - test case started\n", name);
332 output ();
333 printf (
334 " %s✓%s %s - test case passed (%d %s)\n", colors_.pass,
335 colors_.none, name,
338 == 1
339 ? "check"
340 : "checks");
341
342 add_empty_line = true;
343 }
344 else
345 {
346 printf (
347 " %s✓%s %s - test case passed (%d %s)\n", colors_.pass,
348 colors_.none, name,
351 == 1
352 ? "check"
353 : "checks");
354
355 add_empty_line = false;
356 }
357 }
358 }
359
360 out_.clear ();
361 flush ();
362
363 is_in_test_case_ = false;
364 }
365
366 void
368 {
369 if (add_empty_line)
370 {
371 flush ();
372 printf ("\n");
373 }
374
376 {
377 add_empty_line = false;
378 return;
379 }
380
381 printf ("• %s - test suite started\n", name);
382
383 add_empty_line = true;
384 }
385
386 void
388 {
390 {
391 return;
392 }
393
394 if (suite.test_cases () > 0 && verbosity != verbosity::quiet)
395 {
396 printf ("\n");
397 add_empty_line = true;
398 }
399
400 // Also fail if none passed.
401 if (suite.failed_checks () == 0 && suite.successful_checks () != 0)
402 {
403 printf ("%s✓%s %s - test suite passed (%d %s in %d test %s)\n",
404 colors_.pass, colors_.none, suite.name (),
405 suite.successful_checks (),
406 suite.successful_checks () == 1 ? "check" : "checks",
407 suite.test_cases (),
408 suite.test_cases () == 1 ? "case" : "cases");
409 }
410 else
411 {
412 printf ("%s✗%s %s - test suite %sFAILED%s (%d %s passed, %d failed, "
413 "in %d test %s)\n",
416 suite.successful_checks () == 1 ? "check" : "checks",
417 suite.failed_checks (), suite.test_cases (),
418 suite.test_cases () == 1 ? "case" : "cases");
419 }
420 flush ();
421 }
422
423 void
425 {
426 printf ("%s", out_.c_str ()); // No `\n` here.
427 out_.clear ();
428 }
429
430 // --------------------------------------------------------------------------
431} // namespace micro_os_plus::micro_test_plus
432
433// ----------------------------------------------------------------------------
Local implementation of the std::source_location.
Definition reflection.h:58
Reporter to display the test results. For failed tests it prints the actual values of the operands,...
void flush(void)
Flush the current buffered content.
test_reporter & operator<<(std::string_view sv)
void output_fail_prefix_(std::string &message, const reflection::source_location &location)
Base class for all test suites.
Definition test-suite.h:51
constexpr const char * name()
Get the suite name.
Definition test-suite.h:107
constexpr int test_cases(void)
Get the number of test cases.
Definition test-suite.h:163
struct micro_os_plus::micro_test_plus::test_suite_base::@0 current_test_case
const char * short_name(const char *name)
verbosity
The verbosity levels.
test_reporter & endl(test_reporter &stream)