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
16#if !defined(_CRT_SECURE_NO_WARNINGS)
17#define _CRT_SECURE_NO_WARNINGS
18#endif
20
21#include <sstream>
22#include <vector>
23#include <array>
24#include <list>
25#include <string>
26#include <cmath>
27#include <cstring>
28
33
40#ifdef CHECK
41#error Macro CHECK is already defined
42#endif
43#define CHECK(value) \
44 do \
45 { \
46 try { \
47 if (!UnitTest::Check(value)) \
48 UnitTest::ReportFailure (__FILE__, __LINE__, "Check failed: " #value);\
49 } \
50 catch (...) { \
51 UnitTest::ReportFailure (__FILE__, __LINE__, \
52 "Unhandled exception in CHECK(" #value ")"); \
53 } \
54 } while (0)
55
62#ifdef CHECK_EX
63#error Macro CHECK_EX is already defined
64#endif
65#define CHECK_EX(value, ...) \
66 do \
67 { \
68 try { \
69 if (!UnitTest::Check(value)){ \
70 char message[UnitTest::MAX_MESSAGE_SIZE]; \
71 snprintf (message, UnitTest::MAX_MESSAGE_SIZE, __VA_ARGS__); \
72 UnitTest::ReportFailure (__FILE__, __LINE__, message); \
73 } \
74 } \
75 catch (...) { \
76 UnitTest::ReportFailure (__FILE__, __LINE__, \
77 "Unhandled exception in CHECK_EX(" #value ")"); \
78 } \
79 } while (0)
80
87#ifdef CHECK_EQUAL
88#error Macro CHECK_EQUAL is already defined
89#endif
90
91#define CHECK_EQUAL(expected, actual) \
92 do \
93 { \
94 try { \
95 std::string str__; \
96 if (!UnitTest::CheckEqual((expected), (actual), str__)) \
97 UnitTest::ReportFailure (__FILE__, __LINE__, str__); \
98 } \
99 catch (...) { \
100 UnitTest::ReportFailure (__FILE__, __LINE__, \
101 "Unhandled exception in CHECK_EQUAL(" #expected ", " #actual ")"); \
102 } \
103 } while (0)
104
111#ifdef CHECK_NAN
112#error Macro CHECK_NAN is already defined
113#endif
114
115#define CHECK_NAN(value) \
116 do \
117 { \
118 try { \
119 if (!UnitTest::CheckNaN(value)) \
120 UnitTest::ReportFailure (__FILE__, __LINE__, "Check failed: " #value " is not NaN");\
121 } \
122 catch (...) { \
123 UnitTest::ReportFailure (__FILE__, __LINE__, \
124 "Unhandled exception in CHECK_NAN(" #value ")"); \
125 } \
126 } while (0)
127
135#ifdef CHECK_EQUAL_EX
136#error Macro CHECK_EQUAL_EX is already defined
137#endif
138#define CHECK_EQUAL_EX(expected, actual, ...) \
139 do \
140 { \
141 try { \
142 std::string str__; \
143 if (!UnitTest::CheckEqual((expected), (actual), str__)) \
144 { \
145 char message[UnitTest::MAX_MESSAGE_SIZE]; \
146 snprintf (message, UnitTest::MAX_MESSAGE_SIZE, __VA_ARGS__); \
147 str__ += " - "; \
148 str__ += message; \
149 UnitTest::ReportFailure (__FILE__, __LINE__, str__); \
150 } \
151 } \
152 catch (...) { \
153 UnitTest::ReportFailure (__FILE__, __LINE__, \
154 "Unhandled exception in CHECK_EQUAL_EX(" #expected ", " #actual ")"); \
155 } \
156 } while (0)
157
165
166#ifdef CHECK_CLOSE
167#error Macro CHECK_CLOSE is already defined
168#endif
169#define CHECK_CLOSE(expected, actual,...) \
170 do \
171 { \
172 try { \
173 std::string str__; \
174 if (!UnitTest::CheckClose ((expected), (actual), (__VA_ARGS__+0), str__)) \
175 UnitTest::ReportFailure (__FILE__, __LINE__, str__); \
176 } \
177 catch (UnitTest::tolerance_not_set&) \
178 { \
179 throw UnitTest::test_abort (__FILE__, __LINE__, "UnitTest::default_tolerance not set"); \
180 } \
181 catch (...) { \
182 UnitTest::ReportFailure (__FILE__, __LINE__, \
183 "Unhandled exception in CHECK_CLOSE(" #expected ", " #actual ")"); \
184 } \
185 } while (0)
186
194
195#ifdef CHECK_CLOSE_EX
196#error Macro CHECK_CLOSE_EX is already defined
197#endif
198#define CHECK_CLOSE_EX(expected, actual, tolerance, ...) \
199 do \
200 { \
201 try { \
202 std::string str__; \
203 if (!UnitTest::CheckClose ((expected), (actual), (tolerance), str__)) \
204 { \
205 char message[UnitTest::MAX_MESSAGE_SIZE]; \
206 snprintf (message, UnitTest::MAX_MESSAGE_SIZE, __VA_ARGS__); \
207 str__ += " - "; \
208 str__ += message; \
209 UnitTest::ReportFailure (__FILE__, __LINE__, str__); \
210 } \
211 } \
212 catch (UnitTest::tolerance_not_set&) \
213 { \
214 throw UnitTest::test_abort (__FILE__, __LINE__, "UnitTest::default_tolerance not set"); \
215 } \
216 catch (...) { \
217 UnitTest::ReportFailure (__FILE__, __LINE__, \
218 "Unhandled exception in CHECK_CLOSE_EX(" #expected ", " #actual ")"); \
219 } \
220 } while (0)
221
228#ifdef CHECK_ARRAY_EQUAL
229#error Macro CHECK_ARRAY_EQUAL is already defined
230#endif
231
232#define CHECK_ARRAY_EQUAL(expected, actual, count) \
233 do \
234 { \
235 try { \
236 std::string str__; \
237 if (!UnitTest::CheckArrayEqual ((expected), (actual), (count), str__)) \
238 UnitTest::ReportFailure (__FILE__, __LINE__, str__); \
239 } \
240 catch (...) { \
241 UnitTest::ReportFailure (__FILE__, __LINE__, \
242 "Unhandled exception in CHECK_ARRAY_EQUAL(" #expected ", " #actual ")"); \
243 } \
244 } while (0)
245
253#ifdef CHECK_ARRAY_CLOSE
254#error Macro CHECK_ARRAY_CLOSE is already defined
255#endif
256
257#define CHECK_ARRAY_CLOSE(expected, actual, count, ...) \
258 do \
259 { \
260 try { \
261 std::string str__; \
262 if (!UnitTest::CheckArrayClose ((expected), (actual), (count), (__VA_ARGS__+0), str__)) \
263 UnitTest::ReportFailure (__FILE__, __LINE__, str__); \
264 } \
265 catch (UnitTest::tolerance_not_set&) \
266 { \
267 throw UnitTest::test_abort (__FILE__, __LINE__, "UnitTest::default_tolerance not set"); \
268 } \
269 catch (...) { \
270 UnitTest::ReportFailure (__FILE__, __LINE__, \
271 "Unhandled exception in CHECK_ARRAY_CLOSE(" #expected ", " #actual ")"); \
272 } \
273 } while (0)
274
281
282#ifdef CHECK_ARRAY2D_EQUAL
283#error Macro CHECK_ARRAY2D_EQUAL is already defined
284#endif
285
286#define CHECK_ARRAY2D_EQUAL(expected, actual, rows, columns) \
287 do \
288 { \
289 try { \
290 std::string str__; \
291 if (!UnitTest::CheckArray2DEqual ((expected), (actual), (rows), (columns), str__)) \
292 UnitTest::ReportFailure (__FILE__, __LINE__, str__); \
293 } \
294 catch (...) { \
295 UnitTest::ReportFailure (__FILE__, __LINE__, \
296 "Unhandled exception in CHECK_ARRAY2D_EQUAL(" #expected ", " #actual ")"); \
297 } \
298 } while (0)
299
300
308#ifdef CHECK_ARRAY2D_CLOSE
309#error Macro CHECK_ARRAY2D_CLOSE is already defined
310#endif
311
312#define CHECK_ARRAY2D_CLOSE(expected, actual, rows, columns, ...) \
313 do \
314 { \
315 try { \
316 std::string str__; \
317 if (!UnitTest::CheckArray2DClose (expected, actual, rows, columns, (__VA_ARGS__+0), str__)) \
318 UnitTest::ReportFailure (__FILE__, __LINE__, str__); \
319 } \
320 catch (UnitTest::tolerance_not_set&) \
321 { \
322 throw UnitTest::test_abort (__FILE__, __LINE__, "UnitTest::default_tolerance not set"); \
323 } \
324 catch (...) { \
325 UnitTest::ReportFailure (__FILE__, __LINE__, \
326 "Unhandled exception in CHECK_ARRAY2D_CLOSE(" #expected ", " #actual ")"); \
327 } \
328 } while (0)
329
338#ifdef CHECK_THROW
339#error Macro CHECK_THROW is already defined
340#endif
341#define CHECK_THROW(expr, except) \
342 do \
343 { \
344 bool caught_ = false; \
345 try { (expr); } \
346 catch (const except& ) { caught_ = true; } \
347 catch (...) { \
348 UnitTest::ReportFailure (__FILE__, __LINE__, \
349 "Unexpected exception in CHECK_THROW"); \
350 } \
351 if (!caught_) \
352 UnitTest::ReportFailure (__FILE__, __LINE__, \
353 "Expected exception: \"" #except "\", not thrown"); \
354 } while(0)
355
364#ifdef CHECK_THROW_EX
365#error Macro CHECK_THROW_EX is already defined
366#endif
367#define CHECK_THROW_EX(expr, except, ...) \
368 do \
369 { \
370 bool caught_ = false; \
371 try { (expr); } \
372 catch (const except& ) { caught_ = true; } \
373 catch (...) { \
374 UnitTest::ReportFailure (__FILE__, __LINE__, \
375 "Unexpected exception in CHECK_THROW_EX"); \
376 } \
377 if (!caught_) { \
378 std::string str__{"Expected exception: \"" #except "\", not thrown"}; \
379 char message[UnitTest::MAX_MESSAGE_SIZE]; \
380 snprintf (message, UnitTest::MAX_MESSAGE_SIZE, __VA_ARGS__); \
381 str__ += " - "; \
382 str__ += message; \
383 UnitTest::ReportFailure (__FILE__, __LINE__, str__); \
384 } \
385 } while(0)
386
394
395#ifdef CHECK_THROW_EQUAL
396#error Macro CHECK_THROW_EQUAL is already defined
397#endif
398#define CHECK_THROW_EQUAL(expression, value, except) \
399 do \
400 { \
401 bool caught_ = false; \
402 try { expression; } \
403 catch (const except& actual) { \
404 caught_ = true; \
405 std::string str__; \
406 if (!UnitTest::CheckEqual(value, actual, str__)) \
407 UnitTest::ReportFailure (__FILE__, __LINE__, str__); \
408 } \
409 catch (...) { \
410 UnitTest::ReportFailure (__FILE__, __LINE__, \
411 "Unexpected exception in CHECK_THROW_EQUAL"); \
412 } \
413 if (!caught_) \
414 UnitTest::ReportFailure (__FILE__, __LINE__, \
415 "Expected exception: \"" #except "\", not thrown"); \
416 } while(0)
417
426
427#ifdef CHECK_THROW_EQUAL_EX
428#error Macro CHECK_THROW_EQUAL_EX is already defined
429#endif
430#define CHECK_THROW_EQUAL_EX(expression, value, except, ...) \
431 do \
432 { \
433 bool caught_ = false; \
434 try { expression; } \
435 catch (const except& actual) { \
436 caught_ = true; \
437 std::string str__; \
438 if (!UnitTest::CheckEqual(value, actual, str__)) \
439 { \
440 char message[UnitTest::MAX_MESSAGE_SIZE]; \
441 snprintf (message, UnitTest::MAX_MESSAGE_SIZE, __VA_ARGS__); \
442 str__ += " - "; \
443 str__ += message; \
444 UnitTest::ReportFailure (__FILE__, __LINE__, str__); \
445 } \
446 } \
447 catch (...) { \
448 UnitTest::ReportFailure (__FILE__, __LINE__, \
449 "Unexpected exception in CHECK_THROW_EQUAL"); \
450 } \
451 if (!caught_) \
452 { \
453 std::string str__{ "Expected exception: \"" #except "\", not thrown" }; \
454 char message[UnitTest::MAX_MESSAGE_SIZE]; \
455 snprintf (message, UnitTest::MAX_MESSAGE_SIZE, __VA_ARGS__); \
456 str__ += " - "; \
457 str__ += message; \
458 UnitTest::ReportFailure (__FILE__, __LINE__, \
459 "Expected exception: \"" #except "\", not thrown"); \
460 } \
461 } while(0)
462
469#ifdef CHECK_FILE_EQUAL
470#error Macro CHECK_FILE_EQUAL is already defined
471#endif
472#define CHECK_FILE_EQUAL(expected, actual) \
473 do \
474 { \
475 try { \
476 std::string str__; \
477 if (!UnitTest::CheckFileEqual((expected), (actual), str__)) \
478 UnitTest::ReportFailure (__FILE__, __LINE__, str__); \
479 } \
480 catch (...) { \
481 UnitTest::ReportFailure (__FILE__, __LINE__, \
482 "Unhandled exception in CHECK_EQUAL(" #expected ", " #actual ")"); \
483 } \
484 } while (0)
485
492#ifdef FAILURE
493#error Macro FAILURE is already defined
494#endif
495#define FAILURE(...) \
496 do \
497 { \
498 char message[UnitTest::MAX_MESSAGE_SIZE]; \
499 snprintf (message, UnitTest::MAX_MESSAGE_SIZE, __VA_ARGS__); \
500 UnitTest::ReportFailure (__FILE__, __LINE__, message); \
501 } while (0)
502
504
505namespace UnitTest {
506
507#if _MSVC_LANG < 201703L
509extern double default_tolerance;
510#else
512inline double default_tolerance = 0;
513#endif
514
515//------------------ Check functions -----------------------------------------
516
523
524template <typename Value>
525bool Check (Value const value)
526{
527 return (bool)value;
528}
529
536template <typename Value>
537bool CheckNaN (Value const value)
538{
539 return std::isnan(value);
540}
541
551template <typename expected_T, typename actual_T>
552bool CheckEqual (const expected_T& expected, const actual_T& actual, std::string& msg)
553{
554 if (!(expected == actual))
555 {
556 std::stringstream stream;
557 stream << "Expected " << expected << " but was " << actual;
558 msg = stream.str ();
559 return false;
560 }
561 else
562 msg.clear ();
563 return true;
564}
565
566template <typename expected_T, typename actual_T>
567bool CheckEqual (const expected_T* expected, const actual_T* actual, std::string& msg)
568{
569 if (!(*expected == *actual))
570 {
571 std::stringstream stream;
572 stream << "Expected " << *expected << " but was " << *actual;
573 msg = stream.str ();
574 return false;
575 }
576 else
577 msg.clear ();
578 return true;
579}
580
581
593template <typename expected_T, typename actual_T>
594inline
595bool CheckEqual (const std::vector<expected_T>& expected, const std::vector<actual_T>& actual, std::string& msg)
596{
597 if (expected != actual)
598 {
599 std::stringstream stream;
600 stream << "Expected [ ";
601 for (auto& p : expected)
602 stream << p << " ";
603
604 stream << "] but was [ ";
605 for (auto& p : actual)
606 stream << p << " ";
607
608 stream << "]";
609 msg = stream.str ();
610 return false;
611 }
612 else
613 msg.clear ();
614 return true;
615}
616
628template <typename expected_T, typename actual_T, size_t N>
629inline
630bool CheckEqual (const std::array<expected_T,N>& expected, const std::array<actual_T,N>& actual, std::string& msg)
631{
632 if (expected != actual)
633 {
634 std::stringstream stream;
635 stream << "Expected [ ";
636 for (size_t i = 0; i < N; ++i)
637 stream << expected[i] << " ";
638
639 stream << "] but was [ ";
640 for (size_t i = 0; i < N; ++i)
641 stream << actual[i] << " ";
642
643 stream << "]";
644 msg = stream.str ();
645 return false;
646 }
647 else
648 msg.clear ();
649 return true;
650}
651
663template <typename expected_T, typename actual_T>
664inline
665bool CheckEqual (const std::list<expected_T>& expected, const std::list<actual_T>& actual, std::string& msg)
666{
667 if (expected != actual)
668 {
669 std::stringstream stream;
670 stream << "Expected ( ";
671 for (auto const& x : expected)
672 stream << x << " ";
673
674 stream << ") but was ( ";
675 for (auto const& x : actual)
676 stream << x << " ";
677
678 stream << ")";
679 msg = stream.str ();
680 return false;
681 }
682 else
683 msg.clear ();
684 return true;
685}
686
687
689#if __WCHAR_MAX__ > 0x10000 //4-bytes wchar_t
690inline
691std::string to_utf8 (const std::wstring& ws)
692{
693 std::string out;
694 auto in = ws.cbegin ();
695 while (in != ws.end ())
696 {
697 unsigned int c = (unsigned int)*in++;
698 if (c < 0x7f)
699 out.push_back ((char)c);
700 else if (c < 0x7ff)
701 {
702 out.push_back (0xC0 | (c >> 6));
703 out.push_back (0x80 | (c & 0x3f));
704 }
705 else if (c < 0xffff)
706 {
707 out.push_back (0xE0 | (c >> 12));
708 out.push_back (0x80 | ((c >> 6) & 0x3f));
709 out.push_back (0x80 | (c & 0x3f));
710 }
711 else
712 {
713 out.push_back (0xF0 | (c >> 18));
714 out.push_back (0x80 | ((c >> 12) & 0x3f));
715 out.push_back (0x80 | ((c >> 6) & 0x3f));
716 out.push_back (0x80 | (c & 0x3f));
717 }
718 }
719 return out;
720}
721#else //2-bytes wchar_t
722inline
723std::string to_utf8 (const std::wstring& ws)
724{
725 std::string out;
726 auto in = ws.cbegin ();
727 while (in != ws.end ())
728 {
729 unsigned int c1 = (unsigned int)*in++;
730 if (c1 < 0xD800 || c1 > 0xe000)
731 {
732 if (c1 < 0x7f)
733 out.push_back ((char)c1);
734 else if (c1 < 0x7ff)
735 {
736 out.push_back (char(0xC0 | (c1 >> 6)));
737 out.push_back (char(0x80 | (c1 & 0x3f)));
738 }
739 else
740 {
741 out.push_back (char(0xE0 | (c1 >> 12)));
742 out.push_back (char(0x80 | ((c1 >> 6) & 0x3f)));
743 out.push_back (char(0x80 | (c1 & 0x3f)));
744 }
745 }
746 else if (in != ws.end ())
747 {
748 unsigned int c2 = (unsigned int)*in++;
749 if (c1 > 0xdbff || c2 < 0xdc00)
750 break; // invalid high/low surrogates order
751
752 c1 &= 0x3ff;
753 c2 &= 0x3ff;
754
755 unsigned int c = ((c1 << 10) | c2) + 0x10000;
756
757 out.push_back (char(0xF0 | (c >> 18)));
758 out.push_back (char(0x80 | ((c >> 12) & 0x3f)));
759 out.push_back (char(0x80 | ((c >> 6) & 0x3f)));
760 out.push_back (char(0x80 | (c & 0x3f)));
761 }
762 else
763 break; //malformed input; just bail out
764 }
765 return out;
766}
767#endif
778inline
779bool CheckEqual (const std::wstring expected, const std::wstring actual,
780 std::string& msg)
781{
782 if (expected != actual)
783 {
784 std::stringstream stream;
785 auto u8exp = to_utf8 (expected);
786 auto u8act = to_utf8 (actual);
787 stream << "Expected \'" << u8exp << "\' but was \'" << u8act << "\'";
788 msg = stream.str ();
789 return false;
790 }
791 else
792 msg.clear ();
793 return true;
794}
795
806inline
807bool CheckEqual (const wchar_t *expected, const wchar_t *actual,
808 std::string &msg)
809{
810 if (wcscmp (expected, actual))
811 {
812 std::stringstream stream;
813 std::string u8exp = to_utf8 (expected);
814 std::string u8act = to_utf8 (actual);
815 stream << "Expected \'" << u8exp << "\' but was \'" << u8act << "\'";
816 msg = stream.str ();
817 return false;
818 }
819 else
820 msg.clear ();
821 return true;
822}
823
824
825inline
826bool CheckEqual (wchar_t *expected, wchar_t *actual, std::string &msg)
827{
828 return CheckEqual (const_cast<const wchar_t *> (expected), const_cast<const wchar_t *> (actual), msg);
829}
830
831inline
832bool CheckEqual (const wchar_t *expected, wchar_t *actual, std::string &msg)
833{
834 return CheckEqual (expected, const_cast<const wchar_t *> (actual), msg);
835}
836
837inline
838bool CheckEqual (wchar_t *expected, const wchar_t *actual, std::string &msg)
839{
840 return CheckEqual (const_cast<const wchar_t *> (expected), actual, msg);
841}
842
844
849inline
850bool CheckEqual (const char* expected, const char* actual, std::string& msg)
851{
852 if (strcmp (expected, actual))
853 {
854 std::stringstream stream;
855 stream << "Expected \'" << expected << "\' but was \'" << actual << "\'";
856 msg = stream.str ();
857 return false;
858 }
859 return true;
860}
861
862inline
863bool CheckEqual (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 (const char* expected, char* actual, std::string& msg)
870{
871 return CheckEqual (const_cast<const char *>(expected), const_cast<const char*>(actual), msg);
872}
873
874inline
875bool CheckEqual (char* expected, const char* actual, std::string& msg)
876{
877 return CheckEqual (const_cast<const char *>(expected), const_cast<const char*>(actual), msg);
878}
879
880
881#if _MSVC_LANG > 201703L
886inline
887bool CheckEqual (const char8_t* expected, const std::string& actual, std::string& msg)
888{
889 return CheckEqual ((const char*)expected, actual, msg);
890}
891
892inline
893bool CheckEqual (const std::string& expected, const char8_t* actual, std::string& msg)
894{
895 return CheckEqual (expected, (const char*)actual, msg);
896}
897
898inline
899bool CheckEqual (const char8_t* expected, const char8_t* actual, std::string& msg)
900{
901 return CheckEqual ((const char*)expected, (const char*)actual, msg);
902}
903
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}
918
919#endif
920
936template <typename expected_T, typename actual_T>
937bool isClose (const expected_T& expected, const actual_T& actual, double tolerance)
938{
939 if (tolerance == 0)
940 {
943 tolerance = UnitTest::default_tolerance;
944 }
945 return fabs ((double)(actual - expected)) <= tolerance;
946}
947
958template <typename expected_T, typename actual_T>
959bool CheckClose (const expected_T& expected, const actual_T& actual, double tolerance,
960 std::string& msg)
961{
962 if (!isClose(actual, expected, tolerance))
963 {
964 auto fail_tol = tolerance ? tolerance : UnitTest::default_tolerance;
965 int prec = (int)(1 - log10 (fail_tol));
966 std::stringstream stream;
967 stream.precision (prec);
968 stream.setf (std::ios::fixed);
969 stream << "Expected " << expected << " +/- " << fail_tol << " but was " << actual;
970 msg = stream.str ();
971 return false;
972 }
973 else
974 msg.clear ();
975 return true;
976}
977
986template <typename expected_T, typename actual_T>
987bool Equal1D (const expected_T& expected, const actual_T& actual, size_t count)
988{
989 for (size_t i = 0; i < count; ++i)
990 if (expected[i] != actual[i])
991 return false;
992 return true;
993}
994
1004template <typename expected_T, typename actual_T>
1005bool CheckArrayEqual (const expected_T& expected, const actual_T& actual,
1006 size_t count, std::string& msg)
1007{
1008 if (!Equal1D (expected, actual, count))
1009 {
1010 std::stringstream stream;
1011 stream << "Expected [ ";
1012 for (size_t i = 0; i < count; ++i)
1013 stream << expected[i] << " ";
1014
1015 stream << "] but was [ ";
1016 for (size_t i = 0; i < count; ++i)
1017 stream << actual[i] << " ";
1018
1019 stream << "]";
1020 msg = stream.str ();
1021 return false;
1022 }
1023 return true;
1024}
1025
1039template <typename expected_T, typename actual_T>
1040bool isClose1D (const expected_T& expected, const actual_T& actual, size_t count, double tolerance)
1041{
1042 for (size_t i = 0; i < count; ++i)
1043 {
1044 if (!isClose(expected[i], actual[i], tolerance))
1045 return false;
1046 }
1047 return true;
1048}
1049
1050
1063template <typename expected_T, typename actual_T>
1064bool CheckArrayClose (const expected_T& expected, const actual_T& actual, size_t count,
1065 double tolerance, std::string& msg)
1066{
1067 if (!isClose1D (expected, actual, count, tolerance))
1068 {
1069 auto fail_tol = tolerance ? tolerance : UnitTest::default_tolerance;
1070 int prec = (int)(1 - log10 (fail_tol));
1071
1072 std::stringstream stream;
1073 stream.precision (prec);
1074 stream.setf (std::ios::fixed);
1075 stream << "Expected [ ";
1076 for (size_t i = 0; i < count; ++i)
1077 stream << expected[i] << " ";
1078
1079 stream << "] +/- " << fail_tol << " but was [ ";
1080 for (size_t i = 0; i < count; ++i)
1081 stream << actual[i] << " ";
1082 stream << "]";
1083 msg = stream.str ();
1084 return false;
1085 }
1086 return true;
1087}
1088
1098template <>
1099inline
1100bool CheckEqual<void, void>(const void* expected, const void* actual, std::string& msg)
1101{
1102 if (!(expected == actual)) {
1103 std::stringstream stream;
1104 stream << "Expected " << expected << " but was " << actual;
1105 msg = stream.str();
1106 return false;
1107 } else
1108 msg.clear();
1109 return true;
1110}
1111
1122template <typename expected_T, typename actual_T>
1123bool CheckClose (const std::vector<expected_T>& expected, const std::vector<actual_T>& actual, double tolerance,
1124 std::string& msg)
1125{
1126 if (expected.size () != actual.size ()
1127 || !isClose1D (&expected[0], &actual[0], expected.size(), tolerance))
1128 {
1129 auto fail_tol = tolerance ? tolerance : UnitTest::default_tolerance;
1130 int prec = (int)(1 - log10 (fail_tol));
1131 std::stringstream stream;
1132 stream.precision (prec);
1133 stream.setf (std::ios::fixed);
1134 stream << "Expected [ ";
1135 for (auto& p : expected)
1136 stream << p << " ";
1137
1138 stream << "] +/- " << fail_tol << " but was [ ";
1139 for (auto& p : actual)
1140 stream << p << " ";
1141 stream << "]";
1142 msg = stream.str ();
1143 return false;
1144 }
1145 return true;
1146}
1147
1158template <typename expected_T, typename actual_T, size_t N>
1159bool CheckClose (const std::array<expected_T, N>& expected, const std::array<actual_T, N>& actual, double tolerance,
1160 std::string& msg)
1161{
1162 if (!isClose1D (&expected[0], &actual[0], N, tolerance))
1163 {
1164 auto fail_tol = tolerance ? tolerance : UnitTest::default_tolerance;
1165 int prec = (int)(1 - log10 (fail_tol));
1166 std::stringstream stream;
1167 stream.precision (prec);
1168 stream.setf (std::ios::fixed);
1169 stream << "Expected [ ";
1170 for (auto& p : expected)
1171 stream << p << " ";
1172
1173 stream << "] +/- " << fail_tol << " but was [ ";
1174 for (auto& p : actual)
1175 stream << p << " ";
1176 stream << "]";
1177 msg = stream.str ();
1178 return false;
1179 }
1180 return true;
1181}
1182
1192template <typename expected_T, typename actual_T>
1193bool Equal2D (const expected_T& expected, const actual_T& actual, size_t rows, size_t columns)
1194{
1195 for (size_t i = 0; i < rows; ++i)
1196 if (!Equal1D (expected[i], actual[i], columns))
1197 return false;
1198 return true;
1199}
1200
1211template <typename expected_T, typename actual_T>
1212bool CheckArray2DEqual (const expected_T& expected, const actual_T& actual,
1213 size_t rows, size_t columns, std::string& msg)
1214{
1215 if (!Equal2D (expected, actual, rows, columns))
1216 {
1217 std::stringstream stream;
1218 size_t i, j;
1219 stream << "Expected [\n";
1220 for (i = 0; i < rows; ++i)
1221 {
1222 stream << " [";
1223 for (j = 0; j < columns; ++j)
1224 stream << expected[i][j] << " ";
1225 stream << "]\n";
1226 }
1227
1228 stream << "] but was [\n";
1229 for (i = 0; i < rows; ++i)
1230 {
1231 stream << " [";
1232 for (j = 0; j < columns; ++j)
1233 stream << actual[i][j] << " ";
1234 stream << "]\n";
1235 }
1236 stream << "]";
1237 msg = stream.str ();
1238 return false;
1239 }
1240 return true;
1241}
1242
1253template <typename expected_T, typename actual_T>
1254bool isClose2D (const expected_T& expected, const actual_T& actual, size_t rows, size_t columns,
1255 double tolerance)
1256{
1257 for (size_t i = 0; i < rows; ++i)
1258 if (!isClose1D (expected[i], actual[i], columns, tolerance))
1259 return false;
1260 return true;
1261}
1262
1275template <typename expected_T, typename actual_T>
1276bool CheckArray2DClose (const expected_T& expected, const actual_T& actual,
1277 size_t rows, size_t columns, double tolerance, std::string& msg)
1278{
1279 if (!isClose2D (expected, actual, rows, columns, tolerance))
1280 {
1281 auto fail_tol = tolerance ? tolerance : UnitTest::default_tolerance;
1282 int prec = (int)(1 - log10 (fail_tol));
1283 std::stringstream stream;
1284 stream.precision (prec);
1285 stream.setf (std::ios::fixed);
1286 stream << "Expected [\n";
1287 size_t i, j;
1288 for (i = 0; i < rows; ++i)
1289 {
1290 stream << " [ ";
1291 for (j = 0; j < columns; ++j)
1292 stream << expected[i][j] << " ";
1293 stream << "]\n";
1294 }
1295
1296 stream << "] +/- " << fail_tol << " but was [\n";
1297 for (i = 0; i < rows; ++i)
1298 {
1299 stream << " [ ";
1300 for (j = 0; j < columns; ++j)
1301 stream << actual[i][j] << " ";
1302 stream << "]\n";
1303 }
1304 stream << "]";
1305 msg = stream.str ();
1306 return false;
1307 }
1308 msg.clear ();
1309 return true;
1310}
1311
1322inline
1323bool CheckFileEqual (const std::string& ref, const std::string& actual, std::string& message)
1324{
1325 struct stat st1, st2;
1326 std::ostringstream buf;
1327
1328 stat (ref.c_str(), &st1);
1329 stat (actual.c_str(), &st2);
1330 if (st1.st_size != st2.st_size)
1331 {
1332 buf << "Size is different (" << st1.st_size << " vs " << st2.st_size
1333 << ") while comparing " << ref << " and " << actual;
1334 message = buf.str();
1335 return false;
1336 }
1337
1338 FILE* f1, * f2;
1339 f1 = fopen (ref.c_str(), "r");
1340 f2 = fopen (actual.c_str(), "r");
1341 if (!f1 || !f2)
1342 {
1343 if (f1) fclose (f1);
1344 if (f2) fclose (f2);
1345 buf << "Failed to open files while comparing "
1346 << ref << " and " << actual;
1347 message = buf.str();
1348 return false; //something wrong with files
1349 }
1350
1351 size_t ln = 0;
1352 bool ok = true;
1353 char ln1[1024], ln2[1024];
1354 while (ok)
1355 {
1356 ln++;
1357 if (fgets (ln1, sizeof (ln1), f1)
1358 && fgets (ln2, sizeof (ln2), f2))
1359 ok = !strcmp (ln1, ln2);
1360 else
1361 break;
1362 }
1363 fclose (f1);
1364 fclose (f2);
1365 if (!ok)
1366 {
1367 char* p1, * p2;
1368 int off;
1369 for (off = 0, p1 = ln1, p2 = ln2;
1370 *p1 && *p2 && *p1 == *p2;
1371 p1++, p2++, off++)
1372 ;
1373 buf << "Difference at line " << ln << " position " << off
1374 << " while comparing " << ref << " and " << actual;
1375 message = buf.str();
1376 }
1377 else
1378 message.clear ();
1379 return ok;
1380}
1381
1382} //end namespace
1383
1389
1390#define EXPECT_TRUE(x) CHECK (x)
1391#define EXPECT_FALSE(x) CHECK (!(x))
1392#define EXPECT_EQ(A, B) CHECK_EQUAL (B, A)
1393#define EXPECT_NE(A, B) \
1394 do \
1395 { \
1396 try { \
1397 std::string str__; \
1398 if (UnitTest::CheckEqual ((A), (B), str__)) \
1399 UnitTest::ReportFailure (__FILE__, __LINE__, str__); \
1400 } \
1401 catch (...) { \
1402 UnitTest::ReportFailure (__FILE__, __LINE__, \
1403 "Unhandled exception in CHECK_EQUAL(" #A ", " #B ")"); \
1404 } \
1405 } while (0)
1406
1407#define EXPECT_GE(A, B) CHECK ((A) >= (B))
1408#define EXPECT_GT(A, B) CHECK ((A) > (B))
1409#define EXPECT_LE(A, B) CHECK ((A) <= (B))
1410#define EXPECT_LT(A, B) CHECK ((A) < (B))
1411
1412#define EXPECT_NEAR(A, B, tol) CHECK_CLOSE(B, A, tol)
1413#define EXPECT_THROW(expr, except) CHECK_THROW(expr, except)
1414
1415#define ASSERT_TRUE(expr) ABORT (!(expr))
1416#define ASSERT_FALSE(expr) ABORT (expr)
1417#define ASSERT_EQ(e1, e2) \
1418 do \
1419 { \
1420 std::string str__; \
1421 if (!UnitTest::CheckEqual((e1), (e2), str__)) \
1422 throw UnitTest::test_abort (__FILE__, __LINE__, str__.c_str()); \
1423 } while (0)
1424
1425#define ASSERT_NE(e1, e2) \
1426 do \
1427 { \
1428 std::string str__; \
1429 if (UnitTest::CheckEqual ((e1), (e2), str__)) \
1430 { \
1431 std::stringstream stream__; \
1432 stream__ << (e1) << " and " << (e2) << " should be different"; \
1433 throw UnitTest::test_abort (__FILE__, __LINE__, stream__.str ().c_str ());\
1434 } \
1435 } while (0)
1436
1437#define ASSERT_GE(e1, e2) ABORT ((e1) < (e2))
1438#define ASSERT_GT(e1, e2) ABORT ((e1) <= (e2))
1439#define ASSERT_LE(e1, e2) ABORT ((e1) > (e2))
1440#define ASSERT_LT(e1, e2) ABORT ((e1) >= (e2))
1442
bool CheckNaN(Value const value)
Definition checks.h:537
double default_tolerance
Default tolerance for CLOSE... macros.
std::string to_utf8(const std::wstring &ws)
Internal function for conversion from UTF-16 to UTF-8.
Definition checks.h:723
bool CheckArray2DClose(const expected_T &expected, const actual_T &actual, size_t rows, size_t columns, double tolerance, std::string &msg)
Definition checks.h:1276
bool CheckClose(const expected_T &expected, const actual_T &actual, double tolerance, std::string &msg)
Definition checks.h:959
bool Check(Value const value)
Definition checks.h:525
bool isClose1D(const expected_T &expected, const actual_T &actual, size_t count, double tolerance)
Definition checks.h:1040
bool CheckArrayClose(const expected_T &expected, const actual_T &actual, size_t count, double tolerance, std::string &msg)
Definition checks.h:1064
bool CheckArrayEqual(const expected_T &expected, const actual_T &actual, size_t count, std::string &msg)
Definition checks.h:1005
bool CheckArray2DEqual(const expected_T &expected, const actual_T &actual, size_t rows, size_t columns, std::string &msg)
Definition checks.h:1212
bool CheckEqual(const expected_T &expected, const actual_T &actual, std::string &msg)
Definition checks.h:552
bool Equal1D(const expected_T &expected, const actual_T &actual, size_t count)
Definition checks.h:987
bool isClose2D(const expected_T &expected, const actual_T &actual, size_t rows, size_t columns, double tolerance)
Definition checks.h:1254
bool CheckFileEqual(const std::string &ref, const std::string &actual, std::string &message)
Definition checks.h:1323
bool Equal2D(const expected_T &expected, const actual_T &actual, size_t rows, size_t columns)
Definition checks.h:1193
bool isClose(const expected_T &expected, const actual_T &actual, double tolerance)
Definition checks.h:937
Definition utpp.h:464