UTPP
Loading...
Searching...
No Matches
checks.h
Go to the documentation of this file.
1#pragma once
2/*
3 UTPP - A New Generation of UnitTest++
4 (c) Mircea Neacsu 2017-2024
5
6 See LICENSE file for full copyright information.
7*/
8
14
15#include <sstream>
16#include <vector>
17#include <array>
18#include <list>
19#include <string>
20#include <cmath>
21#include <cstring>
22
27
34#ifdef CHECK
35#error Macro CHECK is already defined
36#endif
37#define CHECK(value) \
38 do \
39 { \
40 try { \
41 if (!UnitTest::Check(value)) \
42 UnitTest::ReportFailure (__FILE__, __LINE__, "Check failed: " #value);\
43 } \
44 catch (...) { \
45 UnitTest::ReportFailure (__FILE__, __LINE__, \
46 "Unhandled exception in CHECK(" #value ")"); \
47 } \
48 } while (0)
49
56#ifdef CHECK_EX
57#error Macro CHECK_EX is already defined
58#endif
59#define CHECK_EX(value, ...) \
60 do \
61 { \
62 try { \
63 if (!UnitTest::Check(value)){ \
64 char message[UnitTest::MAX_MESSAGE_SIZE]; \
65 snprintf (message, UnitTest::MAX_MESSAGE_SIZE, __VA_ARGS__); \
66 UnitTest::ReportFailure (__FILE__, __LINE__, message); \
67 } \
68 } \
69 catch (...) { \
70 UnitTest::ReportFailure (__FILE__, __LINE__, \
71 "Unhandled exception in CHECK_EX(" #value ")"); \
72 } \
73 } while (0)
74
81#ifdef CHECK_EQUAL
82#error Macro CHECK_EQUAL is already defined
83#endif
84
85#define CHECK_EQUAL(expected, actual) \
86 do \
87 { \
88 try { \
89 std::string str__; \
90 if (!UnitTest::CheckEqual((expected), (actual), str__)) \
91 UnitTest::ReportFailure (__FILE__, __LINE__, str__); \
92 } \
93 catch (...) { \
94 UnitTest::ReportFailure (__FILE__, __LINE__, \
95 "Unhandled exception in CHECK_EQUAL(" #expected ", " #actual ")"); \
96 } \
97 } while (0)
98
105#ifdef CHECK_NAN
106#error Macro CHECK_NAN is already defined
107#endif
108
109#define CHECK_NAN(value) \
110 do \
111 { \
112 try { \
113 if (!UnitTest::CheckNaN(value)) \
114 UnitTest::ReportFailure (__FILE__, __LINE__, "Check failed: " #value " is not NaN");\
115 } \
116 catch (...) { \
117 UnitTest::ReportFailure (__FILE__, __LINE__, \
118 "Unhandled exception in CHECK_NAN(" #value ")"); \
119 } \
120 } while (0)
121
129#ifdef CHECK_EQUAL_EX
130#error Macro CHECK_EQUAL_EX is already defined
131#endif
132#define CHECK_EQUAL_EX(expected, actual, ...) \
133 do \
134 { \
135 try { \
136 std::string str__; \
137 if (!UnitTest::CheckEqual((expected), (actual), str__)) \
138 { \
139 char message[UnitTest::MAX_MESSAGE_SIZE]; \
140 snprintf (message, UnitTest::MAX_MESSAGE_SIZE, __VA_ARGS__); \
141 str__ += " - "; \
142 str__ += message; \
143 UnitTest::ReportFailure (__FILE__, __LINE__, str__); \
144 } \
145 } \
146 catch (...) { \
147 UnitTest::ReportFailure (__FILE__, __LINE__, \
148 "Unhandled exception in CHECK_EQUAL_EX(" #expected ", " #actual ")"); \
149 } \
150 } while (0)
151
159
160#ifdef CHECK_CLOSE
161#error Macro CHECK_CLOSE is already defined
162#endif
163#define CHECK_CLOSE(expected, actual,...) \
164 do \
165 { \
166 try { \
167 std::string str__; \
168 if (!UnitTest::CheckClose ((expected), (actual), (__VA_ARGS__+0), str__)) \
169 UnitTest::ReportFailure (__FILE__, __LINE__, str__); \
170 } \
171 catch (UnitTest::tolerance_not_set&) \
172 { \
173 throw UnitTest::test_abort (__FILE__, __LINE__, "UnitTest::default_tolerance not set"); \
174 } \
175 catch (...) { \
176 UnitTest::ReportFailure (__FILE__, __LINE__, \
177 "Unhandled exception in CHECK_CLOSE(" #expected ", " #actual ")"); \
178 } \
179 } while (0)
180
188
189#ifdef CHECK_CLOSE_EX
190#error Macro CHECK_CLOSE_EX is already defined
191#endif
192#define CHECK_CLOSE_EX(expected, actual, tolerance, ...) \
193 do \
194 { \
195 try { \
196 std::string str__; \
197 if (!UnitTest::CheckClose ((expected), (actual), (tolerance), str__)) \
198 { \
199 char message[UnitTest::MAX_MESSAGE_SIZE]; \
200 snprintf (message, UnitTest::MAX_MESSAGE_SIZE, __VA_ARGS__); \
201 str__ += " - "; \
202 str__ += message; \
203 UnitTest::ReportFailure (__FILE__, __LINE__, str__); \
204 } \
205 } \
206 catch (UnitTest::tolerance_not_set&) \
207 { \
208 throw UnitTest::test_abort (__FILE__, __LINE__, "UnitTest::default_tolerance not set"); \
209 } \
210 catch (...) { \
211 UnitTest::ReportFailure (__FILE__, __LINE__, \
212 "Unhandled exception in CHECK_CLOSE_EX(" #expected ", " #actual ")"); \
213 } \
214 } while (0)
215
222#ifdef CHECK_ARRAY_EQUAL
223#error Macro CHECK_ARRAY_EQUAL is already defined
224#endif
225
226#define CHECK_ARRAY_EQUAL(expected, actual, count) \
227 do \
228 { \
229 try { \
230 std::string str__; \
231 if (!UnitTest::CheckArrayEqual ((expected), (actual), (count), str__)) \
232 UnitTest::ReportFailure (__FILE__, __LINE__, str__); \
233 } \
234 catch (...) { \
235 UnitTest::ReportFailure (__FILE__, __LINE__, \
236 "Unhandled exception in CHECK_ARRAY_EQUAL(" #expected ", " #actual ")"); \
237 } \
238 } while (0)
239
247#ifdef CHECK_ARRAY_CLOSE
248#error Macro CHECK_ARRAY_CLOSE is already defined
249#endif
250
251#define CHECK_ARRAY_CLOSE(expected, actual, count, ...) \
252 do \
253 { \
254 try { \
255 std::string str__; \
256 if (!UnitTest::CheckArrayClose ((expected), (actual), (count), (__VA_ARGS__+0), str__)) \
257 UnitTest::ReportFailure (__FILE__, __LINE__, str__); \
258 } \
259 catch (UnitTest::tolerance_not_set&) \
260 { \
261 throw UnitTest::test_abort (__FILE__, __LINE__, "UnitTest::default_tolerance not set"); \
262 } \
263 catch (...) { \
264 UnitTest::ReportFailure (__FILE__, __LINE__, \
265 "Unhandled exception in CHECK_ARRAY_CLOSE(" #expected ", " #actual ")"); \
266 } \
267 } while (0)
268
275
276#ifdef CHECK_ARRAY2D_EQUAL
277#error Macro CHECK_ARRAY2D_EQUAL is already defined
278#endif
279
280#define CHECK_ARRAY2D_EQUAL(expected, actual, rows, columns) \
281 do \
282 { \
283 try { \
284 std::string str__; \
285 if (!UnitTest::CheckArray2DEqual ((expected), (actual), (rows), (columns), str__)) \
286 UnitTest::ReportFailure (__FILE__, __LINE__, str__); \
287 } \
288 catch (...) { \
289 UnitTest::ReportFailure (__FILE__, __LINE__, \
290 "Unhandled exception in CHECK_ARRAY2D_EQUAL(" #expected ", " #actual ")"); \
291 } \
292 } while (0)
293
294
302#ifdef CHECK_ARRAY2D_CLOSE
303#error Macro CHECK_ARRAY2D_CLOSE is already defined
304#endif
305
306#define CHECK_ARRAY2D_CLOSE(expected, actual, rows, columns, ...) \
307 do \
308 { \
309 try { \
310 std::string str__; \
311 if (!UnitTest::CheckArray2DClose (expected, actual, rows, columns, (__VA_ARGS__+0), str__)) \
312 UnitTest::ReportFailure (__FILE__, __LINE__, str__); \
313 } \
314 catch (UnitTest::tolerance_not_set&) \
315 { \
316 throw UnitTest::test_abort (__FILE__, __LINE__, "UnitTest::default_tolerance not set"); \
317 } \
318 catch (...) { \
319 UnitTest::ReportFailure (__FILE__, __LINE__, \
320 "Unhandled exception in CHECK_ARRAY2D_CLOSE(" #expected ", " #actual ")"); \
321 } \
322 } while (0)
323
332#ifdef CHECK_THROW
333#error Macro CHECK_THROW is already defined
334#endif
335#define CHECK_THROW(expr, except) \
336 do \
337 { \
338 bool caught_ = false; \
339 try { (expr); } \
340 catch (const except& ) { caught_ = true; } \
341 catch (...) { \
342 UnitTest::ReportFailure (__FILE__, __LINE__, \
343 "Unexpected exception in CHECK_THROW"); \
344 } \
345 if (!caught_) \
346 UnitTest::ReportFailure (__FILE__, __LINE__, \
347 "Expected exception: \"" #except "\", not thrown"); \
348 } while(0)
349
358#ifdef CHECK_THROW_EX
359#error Macro CHECK_THROW_EX is already defined
360#endif
361#define CHECK_THROW_EX(expr, except, ...) \
362 do \
363 { \
364 bool caught_ = false; \
365 try { (expr); } \
366 catch (const except& ) { caught_ = true; } \
367 catch (...) { \
368 UnitTest::ReportFailure (__FILE__, __LINE__, \
369 "Unexpected exception in CHECK_THROW_EX"); \
370 } \
371 if (!caught_) { \
372 std::string str__{"Expected exception: \"" #except "\", not thrown"}; \
373 char message[UnitTest::MAX_MESSAGE_SIZE]; \
374 snprintf (message, UnitTest::MAX_MESSAGE_SIZE, __VA_ARGS__); \
375 str__ += " - "; \
376 str__ += message; \
377 UnitTest::ReportFailure (__FILE__, __LINE__, str__); \
378 } \
379 } while(0)
380
388
389#ifdef CHECK_THROW_EQUAL
390#error Macro CHECK_THROW_EQUAL is already defined
391#endif
392#define CHECK_THROW_EQUAL(expression, value, except) \
393 do \
394 { \
395 bool caught_ = false; \
396 try { expression; } \
397 catch (const except& actual) { \
398 caught_ = true; \
399 std::string str__; \
400 if (!UnitTest::CheckEqual(value, actual, str__)) \
401 UnitTest::ReportFailure (__FILE__, __LINE__, str__); \
402 } \
403 catch (...) { \
404 UnitTest::ReportFailure (__FILE__, __LINE__, \
405 "Unexpected exception in CHECK_THROW_EQUAL"); \
406 } \
407 if (!caught_) \
408 UnitTest::ReportFailure (__FILE__, __LINE__, \
409 "Expected exception: \"" #except "\", not thrown"); \
410 } while(0)
411
420
421#ifdef CHECK_THROW_EQUAL_EX
422#error Macro CHECK_THROW_EQUAL_EX is already defined
423#endif
424#define CHECK_THROW_EQUAL_EX(expression, value, except, ...) \
425 do \
426 { \
427 bool caught_ = false; \
428 try { expression; } \
429 catch (const except& actual) { \
430 caught_ = true; \
431 std::string str__; \
432 if (!UnitTest::CheckEqual(value, actual, str__)) \
433 { \
434 char message[UnitTest::MAX_MESSAGE_SIZE]; \
435 snprintf (message, UnitTest::MAX_MESSAGE_SIZE, __VA_ARGS__); \
436 str__ += " - "; \
437 str__ += message; \
438 UnitTest::ReportFailure (__FILE__, __LINE__, str__); \
439 } \
440 } \
441 catch (...) { \
442 UnitTest::ReportFailure (__FILE__, __LINE__, \
443 "Unexpected exception in CHECK_THROW_EQUAL"); \
444 } \
445 if (!caught_) \
446 { \
447 std::string str__{ "Expected exception: \"" #except "\", not thrown" }; \
448 char message[UnitTest::MAX_MESSAGE_SIZE]; \
449 snprintf (message, UnitTest::MAX_MESSAGE_SIZE, __VA_ARGS__); \
450 str__ += " - "; \
451 str__ += message; \
452 UnitTest::ReportFailure (__FILE__, __LINE__, \
453 "Expected exception: \"" #except "\", not thrown"); \
454 } \
455 } while(0)
456
463#ifdef CHECK_FILE_EQUAL
464#error Macro CHECK_FILE_EQUAL is already defined
465#endif
466#define CHECK_FILE_EQUAL(expected, actual) \
467 do \
468 { \
469 try { \
470 std::string str__; \
471 if (!UnitTest::CheckFileEqual((expected), (actual), str__)) \
472 UnitTest::ReportFailure (__FILE__, __LINE__, str__); \
473 } \
474 catch (...) { \
475 UnitTest::ReportFailure (__FILE__, __LINE__, \
476 "Unhandled exception in CHECK_EQUAL(" #expected ", " #actual ")"); \
477 } \
478 } while (0)
479
486#ifdef FAILURE
487#error Macro FAILURE is already defined
488#endif
489#define FAILURE(...) \
490 do \
491 { \
492 char message[UnitTest::MAX_MESSAGE_SIZE]; \
493 snprintf (message, UnitTest::MAX_MESSAGE_SIZE, __VA_ARGS__); \
494 UnitTest::ReportFailure (__FILE__, __LINE__, message); \
495 } while (0)
496
498
499namespace UnitTest {
500
501#if _MSVC_LANG < 201703L
503extern double default_tolerance;
504#else
506inline double default_tolerance = 0;
507#endif
508
509//------------------ Check functions -----------------------------------------
510
517
518template <typename Value>
519bool Check (Value const value)
520{
521 return (bool)value;
522}
523
530template <typename Value>
531bool CheckNaN (Value const value)
532{
533 return std::isnan(value);
534}
535
545template <typename expected_T, typename actual_T>
546bool CheckEqual (const expected_T& expected, const actual_T& actual, std::string& msg)
547{
548 if (!(expected == actual))
549 {
550 std::stringstream stream;
551 stream << "Expected " << expected << " but was " << actual;
552 msg = stream.str ();
553 return false;
554 }
555 else
556 msg.clear ();
557 return true;
558}
559
560template <typename expected_T, typename actual_T>
561bool CheckEqual (const expected_T* expected, const actual_T* actual, std::string& msg)
562{
563 if (!(*expected == *actual))
564 {
565 std::stringstream stream;
566 stream << "Expected " << *expected << " but was " << *actual;
567 msg = stream.str ();
568 return false;
569 }
570 else
571 msg.clear ();
572 return true;
573}
574
575
587template <typename expected_T, typename actual_T>
588inline
589bool CheckEqual (const std::vector<expected_T>& expected, const std::vector<actual_T>& actual, std::string& msg)
590{
591 if (expected != actual)
592 {
593 std::stringstream stream;
594 stream << "Expected [ ";
595 for (auto& p : expected)
596 stream << p << " ";
597
598 stream << "] but was [ ";
599 for (auto& p : actual)
600 stream << p << " ";
601
602 stream << "]";
603 msg = stream.str ();
604 return false;
605 }
606 else
607 msg.clear ();
608 return true;
609}
610
622template <typename expected_T, typename actual_T, size_t N>
623inline
624bool CheckEqual (const std::array<expected_T,N>& expected, const std::array<actual_T,N>& actual, std::string& msg)
625{
626 if (expected != actual)
627 {
628 std::stringstream stream;
629 stream << "Expected [ ";
630 for (size_t i = 0; i < N; ++i)
631 stream << expected[i] << " ";
632
633 stream << "] but was [ ";
634 for (size_t i = 0; i < N; ++i)
635 stream << actual[i] << " ";
636
637 stream << "]";
638 msg = stream.str ();
639 return false;
640 }
641 else
642 msg.clear ();
643 return true;
644}
645
657template <typename expected_T, typename actual_T>
658inline
659bool CheckEqual (const std::list<expected_T>& expected, const std::list<actual_T>& actual, std::string& msg)
660{
661 if (expected != actual)
662 {
663 std::stringstream stream;
664 stream << "Expected ( ";
665 for (auto const& x : expected)
666 stream << x << " ";
667
668 stream << ") but was ( ";
669 for (auto const& x : actual)
670 stream << x << " ";
671
672 stream << ")";
673 msg = stream.str ();
674 return false;
675 }
676 else
677 msg.clear ();
678 return true;
679}
680
681
683#if __WCHAR_MAX__ > 0x10000 //4-bytes wchar_t
684inline
685std::string to_utf8 (const std::wstring& ws)
686{
687 std::string out;
688 auto in = ws.cbegin ();
689 while (in != ws.end ())
690 {
691 unsigned int c = (unsigned int)*in++;
692 if (c < 0x7f)
693 out.push_back ((char)c);
694 else if (c < 0x7ff)
695 {
696 out.push_back (0xC0 | (c >> 6));
697 out.push_back (0x80 | (c & 0x3f));
698 }
699 else if (c < 0xffff)
700 {
701 out.push_back (0xE0 | (c >> 12));
702 out.push_back (0x80 | ((c >> 6) & 0x3f));
703 out.push_back (0x80 | (c & 0x3f));
704 }
705 else
706 {
707 out.push_back (0xF0 | (c >> 18));
708 out.push_back (0x80 | ((c >> 12) & 0x3f));
709 out.push_back (0x80 | ((c >> 6) & 0x3f));
710 out.push_back (0x80 | (c & 0x3f));
711 }
712 }
713 return out;
714}
715#else //2-bytes wchar_t
716inline
717std::string to_utf8 (const std::wstring& ws)
718{
719 std::string out;
720 auto in = ws.cbegin ();
721 while (in != ws.end ())
722 {
723 unsigned int c1 = (unsigned int)*in++;
724 if (c1 < 0xD800 || c1 > 0xe000)
725 {
726 if (c1 < 0x7f)
727 out.push_back ((char)c1);
728 else if (c1 < 0x7ff)
729 {
730 out.push_back (char(0xC0 | (c1 >> 6)));
731 out.push_back (char(0x80 | (c1 & 0x3f)));
732 }
733 else
734 {
735 out.push_back (char(0xE0 | (c1 >> 12)));
736 out.push_back (char(0x80 | ((c1 >> 6) & 0x3f)));
737 out.push_back (char(0x80 | (c1 & 0x3f)));
738 }
739 }
740 else if (in != ws.end ())
741 {
742 unsigned int c2 = (unsigned int)*in++;
743 if (c1 > 0xdbff || c2 < 0xdc00)
744 break; // invalid high/low surrogates order
745
746 c1 &= 0x3ff;
747 c2 &= 0x3ff;
748
749 unsigned int c = ((c1 << 10) | c2) + 0x10000;
750
751 out.push_back (char(0xF0 | (c >> 18)));
752 out.push_back (char(0x80 | ((c >> 12) & 0x3f)));
753 out.push_back (char(0x80 | ((c >> 6) & 0x3f)));
754 out.push_back (char(0x80 | (c & 0x3f)));
755 }
756 else
757 break; //malformed input; just bail out
758 }
759 return out;
760}
761#endif
772inline
773bool CheckEqual (const std::wstring expected, const std::wstring actual,
774 std::string& msg)
775{
776 if (expected != actual)
777 {
778 std::stringstream stream;
779 auto u8exp = to_utf8 (expected);
780 auto u8act = to_utf8 (actual);
781 stream << "Expected \'" << u8exp << "\' but was \'" << u8act << "\'";
782 msg = stream.str ();
783 return false;
784 }
785 else
786 msg.clear ();
787 return true;
788}
789
800inline
801bool CheckEqual (const wchar_t *expected, const wchar_t *actual,
802 std::string &msg)
803{
804 if (wcscmp (expected, actual))
805 {
806 std::stringstream stream;
807 std::string u8exp = to_utf8 (expected);
808 std::string u8act = to_utf8 (actual);
809 stream << "Expected \'" << u8exp << "\' but was \'" << u8act << "\'";
810 msg = stream.str ();
811 return false;
812 }
813 else
814 msg.clear ();
815 return true;
816}
817
818
819inline
820bool CheckEqual (wchar_t *expected, wchar_t *actual, std::string &msg)
821{
822 return CheckEqual (const_cast<const wchar_t *> (expected), const_cast<const wchar_t *> (actual), msg);
823}
824
825inline
826bool CheckEqual (const wchar_t *expected, wchar_t *actual, std::string &msg)
827{
828 return CheckEqual (expected, const_cast<const wchar_t *> (actual), msg);
829}
830
831inline
832bool CheckEqual (wchar_t *expected, const wchar_t *actual, std::string &msg)
833{
834 return CheckEqual (const_cast<const wchar_t *> (expected), actual, msg);
835}
836
838
843inline
844bool CheckEqual (const char* expected, const char* actual, std::string& msg)
845{
846 if (strcmp (expected, actual))
847 {
848 std::stringstream stream;
849 stream << "Expected \'" << expected << "\' but was \'" << actual << "\'";
850 msg = stream.str ();
851 return false;
852 }
853 return true;
854}
855
856inline
857bool CheckEqual (char* expected, char* actual, std::string& msg)
858{
859 return CheckEqual (const_cast<const char *>(expected), const_cast<const char*>(actual), msg);
860}
861
862inline
863bool CheckEqual (const char* expected, char* actual, std::string& msg)
864{
865 return CheckEqual (const_cast<const char *>(expected), const_cast<const char*>(actual), msg);
866}
867
868inline
869bool CheckEqual (char* expected, const char* actual, std::string& msg)
870{
871 return CheckEqual (const_cast<const char *>(expected), const_cast<const char*>(actual), msg);
872}
873
874
875#if _MSVC_LANG > 201703L
876#if defined(__cpp_char8_t)
881inline
882bool CheckEqual (const char8_t* expected, const std::string& actual, std::string& msg)
883{
884 return CheckEqual ((const char*)expected, actual, msg);
885}
886
887inline
888bool CheckEqual (const std::string& expected, const char8_t* actual, std::string& msg)
889{
890 return CheckEqual (expected, (const char*)actual, msg);
891}
892
893inline
894bool CheckEqual (const char8_t* expected, const char8_t* actual, std::string& msg)
895{
896 return CheckEqual ((const char*)expected, (const char*)actual, msg);
897}
899#endif
900
904inline
905bool CheckEqual (char32_t expected, char32_t actual, std::string& msg)
906{
907 if (expected != actual)
908 {
909 std::stringstream stream;
910 stream << std::hex << "Expected (char32_t)U\'\\x" << static_cast<uint32_t>(expected)
911 << "\' but was (char32_t)U\'\\x" << static_cast<uint32_t>(actual) << "\'";
912 msg = stream.str ();
913 return false;
914 }
915 return true;
916}
917#endif
918
934template <typename expected_T, typename actual_T>
935bool isClose (const expected_T& expected, const actual_T& actual, double tolerance)
936{
937 if (tolerance == 0)
938 {
941 tolerance = UnitTest::default_tolerance;
942 }
943 return fabs ((double)(actual - expected)) <= tolerance;
944}
945
956template <typename expected_T, typename actual_T>
957bool CheckClose (const expected_T& expected, const actual_T& actual, double tolerance,
958 std::string& msg)
959{
960 if (!isClose(actual, expected, tolerance))
961 {
962 auto fail_tol = tolerance ? tolerance : UnitTest::default_tolerance;
963 int prec = (int)(1 - log10 (fail_tol));
964 std::stringstream stream;
965 stream.precision (prec);
966 stream.setf (std::ios::fixed);
967 stream << "Expected " << expected << " +/- " << fail_tol << " but was " << actual;
968 msg = stream.str ();
969 return false;
970 }
971 else
972 msg.clear ();
973 return true;
974}
975
984template <typename expected_T, typename actual_T>
985bool Equal1D (const expected_T& expected, const actual_T& actual, size_t count)
986{
987 for (size_t i = 0; i < count; ++i)
988 if (expected[i] != actual[i])
989 return false;
990 return true;
991}
992
1002template <typename expected_T, typename actual_T>
1003bool CheckArrayEqual (const expected_T& expected, const actual_T& actual,
1004 size_t count, std::string& msg)
1005{
1006 if (!Equal1D (expected, actual, count))
1007 {
1008 std::stringstream stream;
1009 stream << "Expected [ ";
1010 for (size_t i = 0; i < count; ++i)
1011 stream << expected[i] << " ";
1012
1013 stream << "] but was [ ";
1014 for (size_t i = 0; i < count; ++i)
1015 stream << actual[i] << " ";
1016
1017 stream << "]";
1018 msg = stream.str ();
1019 return false;
1020 }
1021 return true;
1022}
1023
1037template <typename expected_T, typename actual_T>
1038bool isClose1D (const expected_T& expected, const actual_T& actual, size_t count, double tolerance)
1039{
1040 for (size_t i = 0; i < count; ++i)
1041 {
1042 if (!isClose(expected[i], actual[i], tolerance))
1043 return false;
1044 }
1045 return true;
1046}
1047
1048
1061template <typename expected_T, typename actual_T>
1062bool CheckArrayClose (const expected_T& expected, const actual_T& actual, size_t count,
1063 double tolerance, std::string& msg)
1064{
1065 if (!isClose1D (expected, actual, count, tolerance))
1066 {
1067 auto fail_tol = tolerance ? tolerance : UnitTest::default_tolerance;
1068 int prec = (int)(1 - log10 (fail_tol));
1069
1070 std::stringstream stream;
1071 stream.precision (prec);
1072 stream.setf (std::ios::fixed);
1073 stream << "Expected [ ";
1074 for (size_t i = 0; i < count; ++i)
1075 stream << expected[i] << " ";
1076
1077 stream << "] +/- " << fail_tol << " but was [ ";
1078 for (size_t i = 0; i < count; ++i)
1079 stream << actual[i] << " ";
1080 stream << "]";
1081 msg = stream.str ();
1082 return false;
1083 }
1084 return true;
1085}
1086
1096template <>
1097inline
1098bool CheckEqual<void, void>(const void* expected, const void* actual, std::string& msg)
1099{
1100 if (!(expected == actual)) {
1101 std::stringstream stream;
1102 stream << "Expected " << expected << " but was " << actual;
1103 msg = stream.str();
1104 return false;
1105 } else
1106 msg.clear();
1107 return true;
1108}
1109
1120template <typename expected_T, typename actual_T>
1121bool CheckClose (const std::vector<expected_T>& expected, const std::vector<actual_T>& actual, double tolerance,
1122 std::string& msg)
1123{
1124 if (expected.size () != actual.size ()
1125 || !isClose1D (&expected[0], &actual[0], expected.size(), tolerance))
1126 {
1127 auto fail_tol = tolerance ? tolerance : UnitTest::default_tolerance;
1128 int prec = (int)(1 - log10 (fail_tol));
1129 std::stringstream stream;
1130 stream.precision (prec);
1131 stream.setf (std::ios::fixed);
1132 stream << "Expected [ ";
1133 for (auto& p : expected)
1134 stream << p << " ";
1135
1136 stream << "] +/- " << fail_tol << " but was [ ";
1137 for (auto& p : actual)
1138 stream << p << " ";
1139 stream << "]";
1140 msg = stream.str ();
1141 return false;
1142 }
1143 return true;
1144}
1145
1156template <typename expected_T, typename actual_T, size_t N>
1157bool CheckClose (const std::array<expected_T, N>& expected, const std::array<actual_T, N>& actual, double tolerance,
1158 std::string& msg)
1159{
1160 if (!isClose1D (&expected[0], &actual[0], N, tolerance))
1161 {
1162 auto fail_tol = tolerance ? tolerance : UnitTest::default_tolerance;
1163 int prec = (int)(1 - log10 (fail_tol));
1164 std::stringstream stream;
1165 stream.precision (prec);
1166 stream.setf (std::ios::fixed);
1167 stream << "Expected [ ";
1168 for (auto& p : expected)
1169 stream << p << " ";
1170
1171 stream << "] +/- " << fail_tol << " but was [ ";
1172 for (auto& p : actual)
1173 stream << p << " ";
1174 stream << "]";
1175 msg = stream.str ();
1176 return false;
1177 }
1178 return true;
1179}
1180
1190template <typename expected_T, typename actual_T>
1191bool Equal2D (const expected_T& expected, const actual_T& actual, size_t rows, size_t columns)
1192{
1193 for (size_t i = 0; i < rows; ++i)
1194 if (!Equal1D (expected[i], actual[i], columns))
1195 return false;
1196 return true;
1197}
1198
1209template <typename expected_T, typename actual_T>
1210bool CheckArray2DEqual (const expected_T& expected, const actual_T& actual,
1211 size_t rows, size_t columns, std::string& msg)
1212{
1213 if (!Equal2D (expected, actual, rows, columns))
1214 {
1215 std::stringstream stream;
1216 size_t i, j;
1217 stream << "Expected [\n";
1218 for (i = 0; i < rows; ++i)
1219 {
1220 stream << " [";
1221 for (j = 0; j < columns; ++j)
1222 stream << expected[i][j] << " ";
1223 stream << "]\n";
1224 }
1225
1226 stream << "] but was [\n";
1227 for (i = 0; i < rows; ++i)
1228 {
1229 stream << " [";
1230 for (j = 0; j < columns; ++j)
1231 stream << actual[i][j] << " ";
1232 stream << "]\n";
1233 }
1234 stream << "]";
1235 msg = stream.str ();
1236 return false;
1237 }
1238 return true;
1239}
1240
1251template <typename expected_T, typename actual_T>
1252bool isClose2D (const expected_T& expected, const actual_T& actual, size_t rows, size_t columns,
1253 double tolerance)
1254{
1255 for (size_t i = 0; i < rows; ++i)
1256 if (!isClose1D (expected[i], actual[i], columns, tolerance))
1257 return false;
1258 return true;
1259}
1260
1273template <typename expected_T, typename actual_T>
1274bool CheckArray2DClose (const expected_T& expected, const actual_T& actual,
1275 size_t rows, size_t columns, double tolerance, std::string& msg)
1276{
1277 if (!isClose2D (expected, actual, rows, columns, tolerance))
1278 {
1279 auto fail_tol = tolerance ? tolerance : UnitTest::default_tolerance;
1280 int prec = (int)(1 - log10 (fail_tol));
1281 std::stringstream stream;
1282 stream.precision (prec);
1283 stream.setf (std::ios::fixed);
1284 stream << "Expected [\n";
1285 size_t i, j;
1286 for (i = 0; i < rows; ++i)
1287 {
1288 stream << " [ ";
1289 for (j = 0; j < columns; ++j)
1290 stream << expected[i][j] << " ";
1291 stream << "]\n";
1292 }
1293
1294 stream << "] +/- " << fail_tol << " but was [\n";
1295 for (i = 0; i < rows; ++i)
1296 {
1297 stream << " [ ";
1298 for (j = 0; j < columns; ++j)
1299 stream << actual[i][j] << " ";
1300 stream << "]\n";
1301 }
1302 stream << "]";
1303 msg = stream.str ();
1304 return false;
1305 }
1306 msg.clear ();
1307 return true;
1308}
1309
1320inline
1321bool CheckFileEqual (const std::string& ref, const std::string& actual, std::string& message)
1322{
1323 struct stat st1, st2;
1324 std::ostringstream buf;
1325
1326 stat (ref.c_str(), &st1);
1327 stat (actual.c_str(), &st2);
1328 if (st1.st_size != st2.st_size)
1329 {
1330 buf << "Size is different (" << st1.st_size << " vs " << st2.st_size
1331 << ") while comparing " << ref << " and " << actual;
1332 message = buf.str();
1333 return false;
1334 }
1335
1336 FILE* f1, * f2;
1337 f1 = fopen (ref.c_str(), "r");
1338 f2 = fopen (actual.c_str(), "r");
1339 if (!f1 || !f2)
1340 {
1341 if (f1) fclose (f1);
1342 if (f2) fclose (f2);
1343 buf << "Failed to open files while comparing "
1344 << ref << " and " << actual;
1345 message = buf.str();
1346 return false; //something wrong with files
1347 }
1348
1349 size_t ln = 0;
1350 bool ok = true;
1351 char ln1[1024], ln2[1024];
1352 while (ok)
1353 {
1354 ln++;
1355 if (fgets (ln1, sizeof (ln1), f1)
1356 && fgets (ln2, sizeof (ln2), f2))
1357 ok = !strcmp (ln1, ln2);
1358 else
1359 break;
1360 }
1361 fclose (f1);
1362 fclose (f2);
1363 if (!ok)
1364 {
1365 char* p1, * p2;
1366 int off;
1367 for (off = 0, p1 = ln1, p2 = ln2;
1368 *p1 && *p2 && *p1 == *p2;
1369 p1++, p2++, off++)
1370 ;
1371 buf << "Difference at line " << ln << " position " << off
1372 << " while comparing " << ref << " and " << actual;
1373 message = buf.str();
1374 }
1375 else
1376 message.clear ();
1377 return ok;
1378}
1379
1380} //end namespace
1381
1387
1388#define EXPECT_TRUE(x) CHECK (x)
1389#define EXPECT_FALSE(x) CHECK (!(x))
1390#define EXPECT_EQ(A, B) CHECK_EQUAL (B, A)
1391#define EXPECT_NE(A, B) \
1392 do \
1393 { \
1394 try { \
1395 std::string str__; \
1396 if (UnitTest::CheckEqual ((A), (B), str__)) \
1397 UnitTest::ReportFailure (__FILE__, __LINE__, str__); \
1398 } \
1399 catch (...) { \
1400 UnitTest::ReportFailure (__FILE__, __LINE__, \
1401 "Unhandled exception in CHECK_EQUAL(" #A ", " #B ")"); \
1402 } \
1403 } while (0)
1404
1405#define EXPECT_GE(A, B) CHECK ((A) >= (B))
1406#define EXPECT_GT(A, B) CHECK ((A) > (B))
1407#define EXPECT_LE(A, B) CHECK ((A) <= (B))
1408#define EXPECT_LT(A, B) CHECK ((A) < (B))
1409
1410#define EXPECT_NEAR(A, B, tol) CHECK_CLOSE(B, A, tol)
1411#define EXPECT_THROW(expr, except) CHECK_THROW(expr, except)
1412
1413#define ASSERT_TRUE(expr) ABORT (!(expr))
1414#define ASSERT_FALSE(expr) ABORT (expr)
1415#define ASSERT_EQ(e1, e2) \
1416 do \
1417 { \
1418 std::string str__; \
1419 if (!UnitTest::CheckEqual((e1), (e2), str__)) \
1420 throw UnitTest::test_abort (__FILE__, __LINE__, str__.c_str()); \
1421 } while (0)
1422
1423#define ASSERT_NE(e1, e2) \
1424 do \
1425 { \
1426 std::string str__; \
1427 if (UnitTest::CheckEqual ((e1), (e2), str__)) \
1428 { \
1429 std::stringstream stream__; \
1430 stream__ << (e1) << " and " << (e2) << " should be different"; \
1431 throw UnitTest::test_abort (__FILE__, __LINE__, stream__.str ().c_str ());\
1432 } \
1433 } while (0)
1434
1435#define ASSERT_GE(e1, e2) ABORT ((e1) < (e2))
1436#define ASSERT_GT(e1, e2) ABORT ((e1) <= (e2))
1437#define ASSERT_LE(e1, e2) ABORT ((e1) > (e2))
1438#define ASSERT_LT(e1, e2) ABORT ((e1) >= (e2))
1440
bool CheckNaN(Value const value)
Definition checks.h:531
double default_tolerance
Default tolerance for CLOSE... macros.
std::string to_utf8(const std::wstring &ws)
Internal function for conversion from wstring to UTF-8.
Definition checks.h:717
bool CheckArray2DClose(const expected_T &expected, const actual_T &actual, size_t rows, size_t columns, double tolerance, std::string &msg)
Definition checks.h:1274
bool CheckClose(const expected_T &expected, const actual_T &actual, double tolerance, std::string &msg)
Definition checks.h:957
bool Check(Value const value)
Definition checks.h:519
bool isClose1D(const expected_T &expected, const actual_T &actual, size_t count, double tolerance)
Definition checks.h:1038
bool CheckArrayClose(const expected_T &expected, const actual_T &actual, size_t count, double tolerance, std::string &msg)
Definition checks.h:1062
bool CheckArrayEqual(const expected_T &expected, const actual_T &actual, size_t count, std::string &msg)
Definition checks.h:1003
bool CheckArray2DEqual(const expected_T &expected, const actual_T &actual, size_t rows, size_t columns, std::string &msg)
Definition checks.h:1210
bool CheckEqual(const expected_T &expected, const actual_T &actual, std::string &msg)
Definition checks.h:546
bool Equal1D(const expected_T &expected, const actual_T &actual, size_t count)
Definition checks.h:985
bool isClose2D(const expected_T &expected, const actual_T &actual, size_t rows, size_t columns, double tolerance)
Definition checks.h:1252
bool CheckFileEqual(const std::string &ref, const std::string &actual, std::string &message)
Definition checks.h:1321
bool Equal2D(const expected_T &expected, const actual_T &actual, size_t rows, size_t columns)
Definition checks.h:1191
bool isClose(const expected_T &expected, const actual_T &actual, double tolerance)
Definition checks.h:935
Definition utpp.h:465