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#include <sys/stat.h>
23
28
35#ifdef CHECK
36#error Macro CHECK is already defined
37#endif
38#define CHECK(value) \
39 do \
40 { \
41 try { \
42 if (!UnitTest::Check(value)) \
43 UnitTest::ReportFailure (__FILE__, __LINE__, "Check failed: " #value);\
44 } \
45 catch (...) { \
46 UnitTest::ReportFailure (__FILE__, __LINE__, \
47 "Unhandled exception in CHECK(" #value ")"); \
48 } \
49 } while (0)
50
57#ifdef CHECK_EX
58#error Macro CHECK_EX is already defined
59#endif
60#define CHECK_EX(value, ...) \
61 do \
62 { \
63 try { \
64 if (!UnitTest::Check(value)){ \
65 char message[UnitTest::MAX_MESSAGE_SIZE]; \
66 snprintf (message, UnitTest::MAX_MESSAGE_SIZE, __VA_ARGS__); \
67 UnitTest::ReportFailure (__FILE__, __LINE__, message); \
68 } \
69 } \
70 catch (...) { \
71 UnitTest::ReportFailure (__FILE__, __LINE__, \
72 "Unhandled exception in CHECK_EX(" #value ")"); \
73 } \
74 } while (0)
75
82#ifdef CHECK_EQUAL
83#error Macro CHECK_EQUAL is already defined
84#endif
85
86#define CHECK_EQUAL(expected, actual) \
87 do \
88 { \
89 try { \
90 std::string str__; \
91 if (!UnitTest::CheckEqual((expected), (actual), str__)) \
92 UnitTest::ReportFailure (__FILE__, __LINE__, str__); \
93 } \
94 catch (...) { \
95 UnitTest::ReportFailure (__FILE__, __LINE__, \
96 "Unhandled exception in CHECK_EQUAL(" #expected ", " #actual ")"); \
97 } \
98 } while (0)
99
106#ifdef CHECK_NAN
107#error Macro CHECK_NAN is already defined
108#endif
109
110#define CHECK_NAN(value) \
111 do \
112 { \
113 try { \
114 if (!UnitTest::CheckNaN(value)) \
115 UnitTest::ReportFailure (__FILE__, __LINE__, "Check failed: " #value " is not NaN");\
116 } \
117 catch (...) { \
118 UnitTest::ReportFailure (__FILE__, __LINE__, \
119 "Unhandled exception in CHECK_NAN(" #value ")"); \
120 } \
121 } while (0)
122
130#ifdef CHECK_EQUAL_EX
131#error Macro CHECK_EQUAL_EX is already defined
132#endif
133#define CHECK_EQUAL_EX(expected, actual, ...) \
134 do \
135 { \
136 try { \
137 std::string str__; \
138 if (!UnitTest::CheckEqual((expected), (actual), str__)) \
139 { \
140 char message[UnitTest::MAX_MESSAGE_SIZE]; \
141 snprintf (message, UnitTest::MAX_MESSAGE_SIZE, __VA_ARGS__); \
142 str__ += " - "; \
143 str__ += message; \
144 UnitTest::ReportFailure (__FILE__, __LINE__, str__); \
145 } \
146 } \
147 catch (...) { \
148 UnitTest::ReportFailure (__FILE__, __LINE__, \
149 "Unhandled exception in CHECK_EQUAL_EX(" #expected ", " #actual ")"); \
150 } \
151 } while (0)
152
160
161#ifdef CHECK_CLOSE
162#error Macro CHECK_CLOSE is already defined
163#endif
164#define CHECK_CLOSE(expected, actual,...) \
165 do \
166 { \
167 try { \
168 std::string str__; \
169 if (!UnitTest::CheckClose ((expected), (actual), (__VA_ARGS__+0), str__)) \
170 UnitTest::ReportFailure (__FILE__, __LINE__, str__); \
171 } \
172 catch (UnitTest::tolerance_not_set&) \
173 { \
174 throw UnitTest::test_abort (__FILE__, __LINE__, "UnitTest::default_tolerance not set"); \
175 } \
176 catch (...) { \
177 UnitTest::ReportFailure (__FILE__, __LINE__, \
178 "Unhandled exception in CHECK_CLOSE(" #expected ", " #actual ")"); \
179 } \
180 } while (0)
181
189
190#ifdef CHECK_CLOSE_EX
191#error Macro CHECK_CLOSE_EX is already defined
192#endif
193#define CHECK_CLOSE_EX(expected, actual, tolerance, ...) \
194 do \
195 { \
196 try { \
197 std::string str__; \
198 if (!UnitTest::CheckClose ((expected), (actual), (tolerance), str__)) \
199 { \
200 char message[UnitTest::MAX_MESSAGE_SIZE]; \
201 snprintf (message, UnitTest::MAX_MESSAGE_SIZE, __VA_ARGS__); \
202 str__ += " - "; \
203 str__ += message; \
204 UnitTest::ReportFailure (__FILE__, __LINE__, str__); \
205 } \
206 } \
207 catch (UnitTest::tolerance_not_set&) \
208 { \
209 throw UnitTest::test_abort (__FILE__, __LINE__, "UnitTest::default_tolerance not set"); \
210 } \
211 catch (...) { \
212 UnitTest::ReportFailure (__FILE__, __LINE__, \
213 "Unhandled exception in CHECK_CLOSE_EX(" #expected ", " #actual ")"); \
214 } \
215 } while (0)
216
223#ifdef CHECK_ARRAY_EQUAL
224#error Macro CHECK_ARRAY_EQUAL is already defined
225#endif
226
227#define CHECK_ARRAY_EQUAL(expected, actual, count) \
228 do \
229 { \
230 try { \
231 std::string str__; \
232 if (!UnitTest::CheckArrayEqual ((expected), (actual), (count), str__)) \
233 UnitTest::ReportFailure (__FILE__, __LINE__, str__); \
234 } \
235 catch (...) { \
236 UnitTest::ReportFailure (__FILE__, __LINE__, \
237 "Unhandled exception in CHECK_ARRAY_EQUAL(" #expected ", " #actual ")"); \
238 } \
239 } while (0)
240
248#ifdef CHECK_ARRAY_CLOSE
249#error Macro CHECK_ARRAY_CLOSE is already defined
250#endif
251
252#define CHECK_ARRAY_CLOSE(expected, actual, count, ...) \
253 do \
254 { \
255 try { \
256 std::string str__; \
257 if (!UnitTest::CheckArrayClose ((expected), (actual), (count), (__VA_ARGS__+0), str__)) \
258 UnitTest::ReportFailure (__FILE__, __LINE__, str__); \
259 } \
260 catch (UnitTest::tolerance_not_set&) \
261 { \
262 throw UnitTest::test_abort (__FILE__, __LINE__, "UnitTest::default_tolerance not set"); \
263 } \
264 catch (...) { \
265 UnitTest::ReportFailure (__FILE__, __LINE__, \
266 "Unhandled exception in CHECK_ARRAY_CLOSE(" #expected ", " #actual ")"); \
267 } \
268 } while (0)
269
276
277#ifdef CHECK_ARRAY2D_EQUAL
278#error Macro CHECK_ARRAY2D_EQUAL is already defined
279#endif
280
281#define CHECK_ARRAY2D_EQUAL(expected, actual, rows, columns) \
282 do \
283 { \
284 try { \
285 std::string str__; \
286 if (!UnitTest::CheckArray2DEqual ((expected), (actual), (rows), (columns), str__)) \
287 UnitTest::ReportFailure (__FILE__, __LINE__, str__); \
288 } \
289 catch (...) { \
290 UnitTest::ReportFailure (__FILE__, __LINE__, \
291 "Unhandled exception in CHECK_ARRAY2D_EQUAL(" #expected ", " #actual ")"); \
292 } \
293 } while (0)
294
295
303#ifdef CHECK_ARRAY2D_CLOSE
304#error Macro CHECK_ARRAY2D_CLOSE is already defined
305#endif
306
307#define CHECK_ARRAY2D_CLOSE(expected, actual, rows, columns, ...) \
308 do \
309 { \
310 try { \
311 std::string str__; \
312 if (!UnitTest::CheckArray2DClose (expected, actual, rows, columns, (__VA_ARGS__+0), str__)) \
313 UnitTest::ReportFailure (__FILE__, __LINE__, str__); \
314 } \
315 catch (UnitTest::tolerance_not_set&) \
316 { \
317 throw UnitTest::test_abort (__FILE__, __LINE__, "UnitTest::default_tolerance not set"); \
318 } \
319 catch (...) { \
320 UnitTest::ReportFailure (__FILE__, __LINE__, \
321 "Unhandled exception in CHECK_ARRAY2D_CLOSE(" #expected ", " #actual ")"); \
322 } \
323 } while (0)
324
333#ifdef CHECK_THROW
334#error Macro CHECK_THROW is already defined
335#endif
336#define CHECK_THROW(expr, except) \
337 do \
338 { \
339 bool caught_ = false; \
340 try { (expr); } \
341 catch (const except& ) { caught_ = true; } \
342 catch (...) { \
343 UnitTest::ReportFailure (__FILE__, __LINE__, \
344 "Unexpected exception in CHECK_THROW"); \
345 } \
346 if (!caught_) \
347 UnitTest::ReportFailure (__FILE__, __LINE__, \
348 "Expected exception: \"" #except "\", not thrown"); \
349 } while(0)
350
359#ifdef CHECK_THROW_EX
360#error Macro CHECK_THROW_EX is already defined
361#endif
362#define CHECK_THROW_EX(expr, except, ...) \
363 do \
364 { \
365 bool caught_ = false; \
366 try { (expr); } \
367 catch (const except& ) { caught_ = true; } \
368 catch (...) { \
369 UnitTest::ReportFailure (__FILE__, __LINE__, \
370 "Unexpected exception in CHECK_THROW_EX"); \
371 } \
372 if (!caught_) { \
373 std::string str__{"Expected exception: \"" #except "\", not thrown"}; \
374 char message[UnitTest::MAX_MESSAGE_SIZE]; \
375 snprintf (message, UnitTest::MAX_MESSAGE_SIZE, __VA_ARGS__); \
376 str__ += " - "; \
377 str__ += message; \
378 UnitTest::ReportFailure (__FILE__, __LINE__, str__); \
379 } \
380 } while(0)
381
389
390#ifdef CHECK_THROW_EQUAL
391#error Macro CHECK_THROW_EQUAL is already defined
392#endif
393#define CHECK_THROW_EQUAL(expression, value, except) \
394 do \
395 { \
396 bool caught_ = false; \
397 try { expression; } \
398 catch (const except& actual) { \
399 caught_ = true; \
400 std::string str__; \
401 if (!UnitTest::CheckEqual(value, actual, str__)) \
402 UnitTest::ReportFailure (__FILE__, __LINE__, str__); \
403 } \
404 catch (...) { \
405 UnitTest::ReportFailure (__FILE__, __LINE__, \
406 "Unexpected exception in CHECK_THROW_EQUAL"); \
407 } \
408 if (!caught_) \
409 UnitTest::ReportFailure (__FILE__, __LINE__, \
410 "Expected exception: \"" #except "\", not thrown"); \
411 } while(0)
412
421
422#ifdef CHECK_THROW_EQUAL_EX
423#error Macro CHECK_THROW_EQUAL_EX is already defined
424#endif
425#define CHECK_THROW_EQUAL_EX(expression, value, except, ...) \
426 do \
427 { \
428 bool caught_ = false; \
429 try { expression; } \
430 catch (const except& actual) { \
431 caught_ = true; \
432 std::string str__; \
433 if (!UnitTest::CheckEqual(value, actual, str__)) \
434 { \
435 char message[UnitTest::MAX_MESSAGE_SIZE]; \
436 snprintf (message, UnitTest::MAX_MESSAGE_SIZE, __VA_ARGS__); \
437 str__ += " - "; \
438 str__ += message; \
439 UnitTest::ReportFailure (__FILE__, __LINE__, str__); \
440 } \
441 } \
442 catch (...) { \
443 UnitTest::ReportFailure (__FILE__, __LINE__, \
444 "Unexpected exception in CHECK_THROW_EQUAL"); \
445 } \
446 if (!caught_) \
447 { \
448 std::string str__{ "Expected exception: \"" #except "\", not thrown" }; \
449 char message[UnitTest::MAX_MESSAGE_SIZE]; \
450 snprintf (message, UnitTest::MAX_MESSAGE_SIZE, __VA_ARGS__); \
451 str__ += " - "; \
452 str__ += message; \
453 UnitTest::ReportFailure (__FILE__, __LINE__, \
454 "Expected exception: \"" #except "\", not thrown"); \
455 } \
456 } while(0)
457
464#ifdef CHECK_FILE_EQUAL
465#error Macro CHECK_FILE_EQUAL is already defined
466#endif
467#define CHECK_FILE_EQUAL(expected, actual) \
468 do \
469 { \
470 try { \
471 std::string str__; \
472 if (!UnitTest::CheckFileEqual((expected), (actual), str__)) \
473 UnitTest::ReportFailure (__FILE__, __LINE__, str__); \
474 } \
475 catch (...) { \
476 UnitTest::ReportFailure (__FILE__, __LINE__, \
477 "Unhandled exception in CHECK_EQUAL(" #expected ", " #actual ")"); \
478 } \
479 } while (0)
480
487#ifdef FAILURE
488#error Macro FAILURE is already defined
489#endif
490#define FAILURE(...) \
491 do \
492 { \
493 char message[UnitTest::MAX_MESSAGE_SIZE]; \
494 snprintf (message, UnitTest::MAX_MESSAGE_SIZE, __VA_ARGS__); \
495 UnitTest::ReportFailure (__FILE__, __LINE__, message); \
496 } while (0)
497
499
500namespace UnitTest {
501
502#if UTPP_CPP_LANG < 201703L
504extern double default_tolerance;
505#else
507inline double default_tolerance = 0;
508#endif
509
510//------------------ Check functions -----------------------------------------
511
518
519template <typename Value>
520bool Check (Value const value)
521{
522 return (bool)value;
523}
524
531template <typename Value>
532bool CheckNaN (Value const value)
533{
534 return std::isnan(value);
535}
536
546template <typename expected_T, typename actual_T>
547bool CheckEqual (const expected_T& expected, const actual_T& actual, std::string& msg)
548{
549 if (!(expected == actual))
550 {
551 std::stringstream stream;
552 stream << "Expected " << expected << " but was " << actual;
553 msg = stream.str ();
554 return false;
555 }
556 else
557 msg.clear ();
558 return true;
559}
560
561template <typename expected_T, typename actual_T>
562bool CheckEqual (const expected_T* expected, const actual_T* actual, std::string& msg)
563{
564 if (!(*expected == *actual))
565 {
566 std::stringstream stream;
567 stream << "Expected " << *expected << " but was " << *actual;
568 msg = stream.str ();
569 return false;
570 }
571 else
572 msg.clear ();
573 return true;
574}
575
576
588template <typename expected_T, typename actual_T>
589inline
590bool CheckEqual (const std::vector<expected_T>& expected, const std::vector<actual_T>& actual, std::string& msg)
591{
592 if (expected != actual)
593 {
594 std::stringstream stream;
595 stream << "Expected [ ";
596 for (auto& p : expected)
597 stream << p << " ";
598
599 stream << "] but was [ ";
600 for (auto& p : actual)
601 stream << p << " ";
602
603 stream << "]";
604 msg = stream.str ();
605 return false;
606 }
607 else
608 msg.clear ();
609 return true;
610}
611
623template <typename expected_T, typename actual_T, size_t N>
624inline
625bool CheckEqual (const std::array<expected_T,N>& expected, const std::array<actual_T,N>& actual, std::string& msg)
626{
627 if (expected != actual)
628 {
629 std::stringstream stream;
630 stream << "Expected [ ";
631 for (size_t i = 0; i < N; ++i)
632 stream << expected[i] << " ";
633
634 stream << "] but was [ ";
635 for (size_t i = 0; i < N; ++i)
636 stream << actual[i] << " ";
637
638 stream << "]";
639 msg = stream.str ();
640 return false;
641 }
642 else
643 msg.clear ();
644 return true;
645}
646
658template <typename expected_T, typename actual_T>
659inline
660bool CheckEqual (const std::list<expected_T>& expected, const std::list<actual_T>& actual, std::string& msg)
661{
662 if (expected != actual)
663 {
664 std::stringstream stream;
665 stream << "Expected ( ";
666 for (auto const& x : expected)
667 stream << x << " ";
668
669 stream << ") but was ( ";
670 for (auto const& x : actual)
671 stream << x << " ";
672
673 stream << ")";
674 msg = stream.str ();
675 return false;
676 }
677 else
678 msg.clear ();
679 return true;
680}
681
682
684#if __WCHAR_MAX__ > 0x10000 //4-bytes wchar_t
685inline
686std::string to_utf8 (const std::wstring& ws)
687{
688 std::string out;
689 auto in = ws.cbegin ();
690 while (in != ws.end ())
691 {
692 unsigned int c = (unsigned int)*in++;
693 if (c < 0x7f)
694 out.push_back ((char)c);
695 else if (c < 0x7ff)
696 {
697 out.push_back (0xC0 | (c >> 6));
698 out.push_back (0x80 | (c & 0x3f));
699 }
700 else if (c < 0xffff)
701 {
702 out.push_back (0xE0 | (c >> 12));
703 out.push_back (0x80 | ((c >> 6) & 0x3f));
704 out.push_back (0x80 | (c & 0x3f));
705 }
706 else
707 {
708 out.push_back (0xF0 | (c >> 18));
709 out.push_back (0x80 | ((c >> 12) & 0x3f));
710 out.push_back (0x80 | ((c >> 6) & 0x3f));
711 out.push_back (0x80 | (c & 0x3f));
712 }
713 }
714 return out;
715}
716#else //2-bytes wchar_t
717inline
718std::string to_utf8 (const std::wstring& ws)
719{
720 std::string out;
721 auto in = ws.cbegin ();
722 while (in != ws.end ())
723 {
724 unsigned int c1 = (unsigned int)*in++;
725 if (c1 < 0xD800 || c1 > 0xe000)
726 {
727 if (c1 < 0x7f)
728 out.push_back ((char)c1);
729 else if (c1 < 0x7ff)
730 {
731 out.push_back (char(0xC0 | (c1 >> 6)));
732 out.push_back (char(0x80 | (c1 & 0x3f)));
733 }
734 else
735 {
736 out.push_back (char(0xE0 | (c1 >> 12)));
737 out.push_back (char(0x80 | ((c1 >> 6) & 0x3f)));
738 out.push_back (char(0x80 | (c1 & 0x3f)));
739 }
740 }
741 else if (in != ws.end ())
742 {
743 unsigned int c2 = (unsigned int)*in++;
744 if (c1 > 0xdbff || c2 < 0xdc00)
745 break; // invalid high/low surrogates order
746
747 c1 &= 0x3ff;
748 c2 &= 0x3ff;
749
750 unsigned int c = ((c1 << 10) | c2) + 0x10000;
751
752 out.push_back (char(0xF0 | (c >> 18)));
753 out.push_back (char(0x80 | ((c >> 12) & 0x3f)));
754 out.push_back (char(0x80 | ((c >> 6) & 0x3f)));
755 out.push_back (char(0x80 | (c & 0x3f)));
756 }
757 else
758 break; //malformed input; just bail out
759 }
760 return out;
761}
762#endif
773inline
774bool CheckEqual (const std::wstring expected, const std::wstring actual,
775 std::string& msg)
776{
777 if (expected != actual)
778 {
779 std::stringstream stream;
780 auto u8exp = to_utf8 (expected);
781 auto u8act = to_utf8 (actual);
782 stream << "Expected \'" << u8exp << "\' but was \'" << u8act << "\'";
783 msg = stream.str ();
784 return false;
785 }
786 else
787 msg.clear ();
788 return true;
789}
790
801inline
802bool CheckEqual (const wchar_t *expected, const wchar_t *actual,
803 std::string &msg)
804{
805 if (wcscmp (expected, actual))
806 {
807 std::stringstream stream;
808 std::string u8exp = to_utf8 (expected);
809 std::string u8act = to_utf8 (actual);
810 stream << "Expected \'" << u8exp << "\' but was \'" << u8act << "\'";
811 msg = stream.str ();
812 return false;
813 }
814 else
815 msg.clear ();
816 return true;
817}
818
819inline
820bool CheckEqual(const wchar_t* expected, const std::wstring actual,
821 std::string& msg)
822{
823 return CheckEqual(std::wstring(expected), actual, msg);
824}
825
826inline
827bool CheckEqual(const std::wstring expected, const wchar_t* actual,
828 std::string& msg)
829{
830 return CheckEqual(expected, std::wstring(actual), msg);
831}
832
833inline
834bool CheckEqual(const std::wstring expected, wchar_t* actual,
835 std::string& msg)
836{
837 return CheckEqual(expected, std::wstring(actual), msg);
838}
839
840inline
841bool CheckEqual (wchar_t *expected, wchar_t *actual, std::string &msg)
842{
843 return CheckEqual (const_cast<const wchar_t *> (expected), const_cast<const wchar_t *> (actual), msg);
844}
845
846inline
847bool CheckEqual (const wchar_t *expected, wchar_t *actual, std::string &msg)
848{
849 return CheckEqual (expected, const_cast<const wchar_t *> (actual), msg);
850}
851
852inline
853bool CheckEqual (wchar_t *expected, const wchar_t *actual, std::string &msg)
854{
855 return CheckEqual (const_cast<const wchar_t *> (expected), actual, msg);
856}
857
859
864inline
865bool CheckEqual (const char* expected, const char* actual, std::string& msg)
866{
867 if (strcmp (expected, actual))
868 {
869 std::stringstream stream;
870 stream << "Expected \'" << expected << "\' but was \'" << actual << "\'";
871 msg = stream.str ();
872 return false;
873 }
874 return true;
875}
876
877inline
878bool CheckEqual (char* expected, char* actual, std::string& msg)
879{
880 return CheckEqual (const_cast<const char *>(expected), const_cast<const char*>(actual), msg);
881}
882
883inline
884bool CheckEqual (const char* expected, char* actual, std::string& msg)
885{
886 return CheckEqual (const_cast<const char *>(expected), const_cast<const char*>(actual), msg);
887}
888
889inline
890bool CheckEqual (char* expected, const char* actual, std::string& msg)
891{
892 return CheckEqual (const_cast<const char *>(expected), const_cast<const char*>(actual), msg);
893}
894
895
896#if UTPP_CPP_LANG > 201703L
897#if defined(__cpp_char8_t)
902inline
903bool CheckEqual (const char8_t* expected, const std::string& actual, std::string& msg)
904{
905 return CheckEqual ((const char*)expected, actual, msg);
906}
907
908inline
909bool CheckEqual (const std::string& expected, const char8_t* actual, std::string& msg)
910{
911 return CheckEqual (expected, (const char*)actual, msg);
912}
913
914inline
915bool CheckEqual (const char8_t* expected, const char8_t* actual, std::string& msg)
916{
917 return CheckEqual ((const char*)expected, (const char*)actual, msg);
918}
920#endif
921
925inline
926bool CheckEqual (char32_t expected, char32_t actual, std::string& msg)
927{
928 if (expected != actual)
929 {
930 std::stringstream stream;
931 stream << std::hex << "Expected (char32_t)U\'\\x" << static_cast<uint32_t>(expected)
932 << "\' but was (char32_t)U\'\\x" << static_cast<uint32_t>(actual) << "\'";
933 msg = stream.str ();
934 return false;
935 }
936 return true;
937}
938#endif
939
955template <typename expected_T, typename actual_T>
956bool isClose (const expected_T& expected, const actual_T& actual, double tolerance)
957{
958 if (tolerance == 0)
959 {
962 tolerance = UnitTest::default_tolerance;
963 }
964 return fabs ((double)(actual - expected)) <= tolerance;
965}
966
977template <typename expected_T, typename actual_T>
978bool CheckClose (const expected_T& expected, const actual_T& actual, double tolerance,
979 std::string& msg)
980{
981 if (!isClose(actual, expected, tolerance))
982 {
983 auto fail_tol = tolerance ? tolerance : UnitTest::default_tolerance;
984 int prec = (int)(1 - log10 (fail_tol));
985 std::stringstream stream;
986 stream.precision (prec);
987 stream.setf (std::ios::fixed);
988 stream << "Expected " << expected << " +/- " << fail_tol << " but was " << actual;
989 msg = stream.str ();
990 return false;
991 }
992 else
993 msg.clear ();
994 return true;
995}
996
1005template <typename expected_T, typename actual_T>
1006bool Equal1D (const expected_T& expected, const actual_T& actual, size_t count)
1007{
1008 for (size_t i = 0; i < count; ++i)
1009 if (expected[i] != actual[i])
1010 return false;
1011 return true;
1012}
1013
1023template <typename expected_T, typename actual_T>
1024bool CheckArrayEqual (const expected_T& expected, const actual_T& actual,
1025 size_t count, std::string& msg)
1026{
1027 if (!Equal1D (expected, actual, count))
1028 {
1029 std::stringstream stream;
1030 stream << "Expected [ ";
1031 for (size_t i = 0; i < count; ++i)
1032 stream << expected[i] << " ";
1033
1034 stream << "] but was [ ";
1035 for (size_t i = 0; i < count; ++i)
1036 stream << actual[i] << " ";
1037
1038 stream << "]";
1039 msg = stream.str ();
1040 return false;
1041 }
1042 return true;
1043}
1044
1058template <typename expected_T, typename actual_T>
1059bool isClose1D (const expected_T& expected, const actual_T& actual, size_t count, double tolerance)
1060{
1061 for (size_t i = 0; i < count; ++i)
1062 {
1063 if (!isClose(expected[i], actual[i], tolerance))
1064 return false;
1065 }
1066 return true;
1067}
1068
1069
1082template <typename expected_T, typename actual_T>
1083bool CheckArrayClose (const expected_T& expected, const actual_T& actual, size_t count,
1084 double tolerance, std::string& msg)
1085{
1086 if (!isClose1D (expected, actual, count, tolerance))
1087 {
1088 auto fail_tol = tolerance ? tolerance : UnitTest::default_tolerance;
1089 int prec = (int)(1 - log10 (fail_tol));
1090
1091 std::stringstream stream;
1092 stream.precision (prec);
1093 stream.setf (std::ios::fixed);
1094 stream << "Expected [ ";
1095 for (size_t i = 0; i < count; ++i)
1096 stream << expected[i] << " ";
1097
1098 stream << "] +/- " << fail_tol << " but was [ ";
1099 for (size_t i = 0; i < count; ++i)
1100 stream << actual[i] << " ";
1101 stream << "]";
1102 msg = stream.str ();
1103 return false;
1104 }
1105 return true;
1106}
1107
1117template <>
1118inline
1119bool CheckEqual<void, void>(const void* expected, const void* actual, std::string& msg)
1120{
1121 if (!(expected == actual)) {
1122 std::stringstream stream;
1123 stream << "Expected " << expected << " but was " << actual;
1124 msg = stream.str();
1125 return false;
1126 } else
1127 msg.clear();
1128 return true;
1129}
1130
1141template <typename expected_T, typename actual_T>
1142bool CheckClose (const std::vector<expected_T>& expected, const std::vector<actual_T>& actual, double tolerance,
1143 std::string& msg)
1144{
1145 if (expected.size () != actual.size ()
1146 || !isClose1D (&expected[0], &actual[0], expected.size(), tolerance))
1147 {
1148 auto fail_tol = tolerance ? tolerance : UnitTest::default_tolerance;
1149 int prec = (int)(1 - log10 (fail_tol));
1150 std::stringstream stream;
1151 stream.precision (prec);
1152 stream.setf (std::ios::fixed);
1153 stream << "Expected [ ";
1154 for (auto& p : expected)
1155 stream << p << " ";
1156
1157 stream << "] +/- " << fail_tol << " but was [ ";
1158 for (auto& p : actual)
1159 stream << p << " ";
1160 stream << "]";
1161 msg = stream.str ();
1162 return false;
1163 }
1164 return true;
1165}
1166
1177template <typename expected_T, typename actual_T, size_t N>
1178bool CheckClose (const std::array<expected_T, N>& expected, const std::array<actual_T, N>& actual, double tolerance,
1179 std::string& msg)
1180{
1181 if (!isClose1D (&expected[0], &actual[0], N, tolerance))
1182 {
1183 auto fail_tol = tolerance ? tolerance : UnitTest::default_tolerance;
1184 int prec = (int)(1 - log10 (fail_tol));
1185 std::stringstream stream;
1186 stream.precision (prec);
1187 stream.setf (std::ios::fixed);
1188 stream << "Expected [ ";
1189 for (auto& p : expected)
1190 stream << p << " ";
1191
1192 stream << "] +/- " << fail_tol << " but was [ ";
1193 for (auto& p : actual)
1194 stream << p << " ";
1195 stream << "]";
1196 msg = stream.str ();
1197 return false;
1198 }
1199 return true;
1200}
1201
1211template <typename expected_T, typename actual_T>
1212bool Equal2D (const expected_T& expected, const actual_T& actual, size_t rows, size_t columns)
1213{
1214 for (size_t i = 0; i < rows; ++i)
1215 if (!Equal1D (expected[i], actual[i], columns))
1216 return false;
1217 return true;
1218}
1219
1230template <typename expected_T, typename actual_T>
1231bool CheckArray2DEqual (const expected_T& expected, const actual_T& actual,
1232 size_t rows, size_t columns, std::string& msg)
1233{
1234 if (!Equal2D (expected, actual, rows, columns))
1235 {
1236 std::stringstream stream;
1237 size_t i, j;
1238 stream << "Expected [\n";
1239 for (i = 0; i < rows; ++i)
1240 {
1241 stream << " [";
1242 for (j = 0; j < columns; ++j)
1243 stream << expected[i][j] << " ";
1244 stream << "]\n";
1245 }
1246
1247 stream << "] but was [\n";
1248 for (i = 0; i < rows; ++i)
1249 {
1250 stream << " [";
1251 for (j = 0; j < columns; ++j)
1252 stream << actual[i][j] << " ";
1253 stream << "]\n";
1254 }
1255 stream << "]";
1256 msg = stream.str ();
1257 return false;
1258 }
1259 return true;
1260}
1261
1272template <typename expected_T, typename actual_T>
1273bool isClose2D (const expected_T& expected, const actual_T& actual, size_t rows, size_t columns,
1274 double tolerance)
1275{
1276 for (size_t i = 0; i < rows; ++i)
1277 if (!isClose1D (expected[i], actual[i], columns, tolerance))
1278 return false;
1279 return true;
1280}
1281
1294template <typename expected_T, typename actual_T>
1295bool CheckArray2DClose (const expected_T& expected, const actual_T& actual,
1296 size_t rows, size_t columns, double tolerance, std::string& msg)
1297{
1298 if (!isClose2D (expected, actual, rows, columns, tolerance))
1299 {
1300 auto fail_tol = tolerance ? tolerance : UnitTest::default_tolerance;
1301 int prec = (int)(1 - log10 (fail_tol));
1302 std::stringstream stream;
1303 stream.precision (prec);
1304 stream.setf (std::ios::fixed);
1305 stream << "Expected [\n";
1306 size_t i, j;
1307 for (i = 0; i < rows; ++i)
1308 {
1309 stream << " [ ";
1310 for (j = 0; j < columns; ++j)
1311 stream << expected[i][j] << " ";
1312 stream << "]\n";
1313 }
1314
1315 stream << "] +/- " << fail_tol << " but was [\n";
1316 for (i = 0; i < rows; ++i)
1317 {
1318 stream << " [ ";
1319 for (j = 0; j < columns; ++j)
1320 stream << actual[i][j] << " ";
1321 stream << "]\n";
1322 }
1323 stream << "]";
1324 msg = stream.str ();
1325 return false;
1326 }
1327 msg.clear ();
1328 return true;
1329}
1330
1341inline
1342bool CheckFileEqual (const std::string& ref, const std::string& actual, std::string& message)
1343{
1344 struct stat st1, st2;
1345 std::ostringstream buf;
1346
1347 stat (ref.c_str(), &st1);
1348 stat (actual.c_str(), &st2);
1349 if (st1.st_size != st2.st_size)
1350 {
1351 buf << "Size is different (" << st1.st_size << " vs " << st2.st_size
1352 << ") while comparing " << ref << " and " << actual;
1353 message = buf.str();
1354 return false;
1355 }
1356
1357 FILE* f1, * f2;
1358 f1 = fopen (ref.c_str(), "r");
1359 f2 = fopen (actual.c_str(), "r");
1360 if (!f1 || !f2)
1361 {
1362 if (f1) fclose (f1);
1363 if (f2) fclose (f2);
1364 buf << "Failed to open files while comparing "
1365 << ref << " and " << actual;
1366 message = buf.str();
1367 return false; //something wrong with files
1368 }
1369
1370 size_t ln = 0;
1371 bool ok = true;
1372 char ln1[1024], ln2[1024];
1373 while (ok)
1374 {
1375 ln++;
1376 if (fgets (ln1, sizeof (ln1), f1)
1377 && fgets (ln2, sizeof (ln2), f2))
1378 ok = !strcmp (ln1, ln2);
1379 else
1380 break;
1381 }
1382 fclose (f1);
1383 fclose (f2);
1384 if (!ok)
1385 {
1386 char* p1, * p2;
1387 int off;
1388 for (off = 0, p1 = ln1, p2 = ln2;
1389 *p1 && *p2 && *p1 == *p2;
1390 p1++, p2++, off++)
1391 ;
1392 buf << "Difference at line " << ln << " position " << off
1393 << " while comparing " << ref << " and " << actual;
1394 message = buf.str();
1395 }
1396 else
1397 message.clear ();
1398 return ok;
1399}
1400
1401} //end namespace
1402
1408
1409#define EXPECT_TRUE(x) CHECK (x)
1410#define EXPECT_FALSE(x) CHECK (!(x))
1411#define EXPECT_EQ(A, B) CHECK_EQUAL (B, A)
1412#define EXPECT_NE(A, B) \
1413 do \
1414 { \
1415 try { \
1416 std::string str__; \
1417 if (UnitTest::CheckEqual ((A), (B), str__)) \
1418 UnitTest::ReportFailure (__FILE__, __LINE__, str__); \
1419 } \
1420 catch (...) { \
1421 UnitTest::ReportFailure (__FILE__, __LINE__, \
1422 "Unhandled exception in CHECK_EQUAL(" #A ", " #B ")"); \
1423 } \
1424 } while (0)
1425
1426#define EXPECT_GE(A, B) CHECK ((A) >= (B))
1427#define EXPECT_GT(A, B) CHECK ((A) > (B))
1428#define EXPECT_LE(A, B) CHECK ((A) <= (B))
1429#define EXPECT_LT(A, B) CHECK ((A) < (B))
1430
1431#define EXPECT_NEAR(A, B, tol) CHECK_CLOSE(B, A, tol)
1432#define EXPECT_THROW(expr, except) CHECK_THROW(expr, except)
1433
1434#define ASSERT_TRUE(expr) ABORT (!(expr))
1435#define ASSERT_FALSE(expr) ABORT (expr)
1436#define ASSERT_EQ(e1, e2) \
1437 do \
1438 { \
1439 std::string str__; \
1440 if (!UnitTest::CheckEqual((e1), (e2), str__)) \
1441 throw UnitTest::test_abort (__FILE__, __LINE__, str__.c_str()); \
1442 } while (0)
1443
1444#define ASSERT_NE(e1, e2) \
1445 do \
1446 { \
1447 std::string str__; \
1448 if (UnitTest::CheckEqual ((e1), (e2), str__)) \
1449 { \
1450 std::stringstream stream__; \
1451 stream__ << (e1) << " and " << (e2) << " should be different"; \
1452 throw UnitTest::test_abort (__FILE__, __LINE__, stream__.str ().c_str ());\
1453 } \
1454 } while (0)
1455
1456#define ASSERT_GE(e1, e2) ABORT ((e1) < (e2))
1457#define ASSERT_GT(e1, e2) ABORT ((e1) <= (e2))
1458#define ASSERT_LE(e1, e2) ABORT ((e1) > (e2))
1459#define ASSERT_LT(e1, e2) ABORT ((e1) >= (e2))
1461
bool CheckNaN(Value const value)
Definition checks.h:532
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:718
bool CheckArray2DClose(const expected_T &expected, const actual_T &actual, size_t rows, size_t columns, double tolerance, std::string &msg)
Definition checks.h:1295
bool CheckClose(const expected_T &expected, const actual_T &actual, double tolerance, std::string &msg)
Definition checks.h:978
bool Check(Value const value)
Definition checks.h:520
bool isClose1D(const expected_T &expected, const actual_T &actual, size_t count, double tolerance)
Definition checks.h:1059
bool CheckArrayClose(const expected_T &expected, const actual_T &actual, size_t count, double tolerance, std::string &msg)
Definition checks.h:1083
bool CheckArrayEqual(const expected_T &expected, const actual_T &actual, size_t count, std::string &msg)
Definition checks.h:1024
bool CheckArray2DEqual(const expected_T &expected, const actual_T &actual, size_t rows, size_t columns, std::string &msg)
Definition checks.h:1231
bool CheckEqual(const expected_T &expected, const actual_T &actual, std::string &msg)
Definition checks.h:547
bool Equal1D(const expected_T &expected, const actual_T &actual, size_t count)
Definition checks.h:1006
bool isClose2D(const expected_T &expected, const actual_T &actual, size_t rows, size_t columns, double tolerance)
Definition checks.h:1273
bool CheckFileEqual(const std::string &ref, const std::string &actual, std::string &message)
Definition checks.h:1342
bool Equal2D(const expected_T &expected, const actual_T &actual, size_t rows, size_t columns)
Definition checks.h:1212
bool isClose(const expected_T &expected, const actual_T &actual, double tolerance)
Definition checks.h:956
Definition utpp.h:462