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
818inline
819bool CheckEqual(const wchar_t* expected, const std::wstring actual,
820 std::string& msg)
821{
822 return CheckEqual(std::wstring(expected), actual, msg);
823}
824
825inline
826bool CheckEqual(const std::wstring expected, const wchar_t* actual,
827 std::string& msg)
828{
829 return CheckEqual(expected, std::wstring(actual), msg);
830}
831
832inline
833bool CheckEqual(const std::wstring expected, wchar_t* actual,
834 std::string& msg)
835{
836 return CheckEqual(expected, std::wstring(actual), msg);
837}
838
839inline
840bool CheckEqual (wchar_t *expected, wchar_t *actual, std::string &msg)
841{
842 return CheckEqual (const_cast<const wchar_t *> (expected), const_cast<const wchar_t *> (actual), msg);
843}
844
845inline
846bool CheckEqual (const wchar_t *expected, wchar_t *actual, std::string &msg)
847{
848 return CheckEqual (expected, const_cast<const wchar_t *> (actual), msg);
849}
850
851inline
852bool CheckEqual (wchar_t *expected, const wchar_t *actual, std::string &msg)
853{
854 return CheckEqual (const_cast<const wchar_t *> (expected), actual, msg);
855}
856
858
863inline
864bool CheckEqual (const char* expected, const char* actual, std::string& msg)
865{
866 if (strcmp (expected, actual))
867 {
868 std::stringstream stream;
869 stream << "Expected \'" << expected << "\' but was \'" << actual << "\'";
870 msg = stream.str ();
871 return false;
872 }
873 return true;
874}
875
876inline
877bool CheckEqual (char* expected, char* actual, std::string& msg)
878{
879 return CheckEqual (const_cast<const char *>(expected), const_cast<const char*>(actual), msg);
880}
881
882inline
883bool CheckEqual (const char* expected, char* actual, std::string& msg)
884{
885 return CheckEqual (const_cast<const char *>(expected), const_cast<const char*>(actual), msg);
886}
887
888inline
889bool CheckEqual (char* expected, const char* actual, std::string& msg)
890{
891 return CheckEqual (const_cast<const char *>(expected), const_cast<const char*>(actual), msg);
892}
893
894
895#if _MSVC_LANG > 201703L
896#if defined(__cpp_char8_t)
901inline
902bool CheckEqual (const char8_t* expected, const std::string& actual, std::string& msg)
903{
904 return CheckEqual ((const char*)expected, actual, msg);
905}
906
907inline
908bool CheckEqual (const std::string& expected, const char8_t* actual, std::string& msg)
909{
910 return CheckEqual (expected, (const char*)actual, msg);
911}
912
913inline
914bool CheckEqual (const char8_t* expected, const char8_t* actual, std::string& msg)
915{
916 return CheckEqual ((const char*)expected, (const char*)actual, msg);
917}
919#endif
920
924inline
925bool CheckEqual (char32_t expected, char32_t actual, std::string& msg)
926{
927 if (expected != actual)
928 {
929 std::stringstream stream;
930 stream << std::hex << "Expected (char32_t)U\'\\x" << static_cast<uint32_t>(expected)
931 << "\' but was (char32_t)U\'\\x" << static_cast<uint32_t>(actual) << "\'";
932 msg = stream.str ();
933 return false;
934 }
935 return true;
936}
937#endif
938
954template <typename expected_T, typename actual_T>
955bool isClose (const expected_T& expected, const actual_T& actual, double tolerance)
956{
957 if (tolerance == 0)
958 {
961 tolerance = UnitTest::default_tolerance;
962 }
963 return fabs ((double)(actual - expected)) <= tolerance;
964}
965
976template <typename expected_T, typename actual_T>
977bool CheckClose (const expected_T& expected, const actual_T& actual, double tolerance,
978 std::string& msg)
979{
980 if (!isClose(actual, expected, tolerance))
981 {
982 auto fail_tol = tolerance ? tolerance : UnitTest::default_tolerance;
983 int prec = (int)(1 - log10 (fail_tol));
984 std::stringstream stream;
985 stream.precision (prec);
986 stream.setf (std::ios::fixed);
987 stream << "Expected " << expected << " +/- " << fail_tol << " but was " << actual;
988 msg = stream.str ();
989 return false;
990 }
991 else
992 msg.clear ();
993 return true;
994}
995
1004template <typename expected_T, typename actual_T>
1005bool Equal1D (const expected_T& expected, const actual_T& actual, size_t count)
1006{
1007 for (size_t i = 0; i < count; ++i)
1008 if (expected[i] != actual[i])
1009 return false;
1010 return true;
1011}
1012
1022template <typename expected_T, typename actual_T>
1023bool CheckArrayEqual (const expected_T& expected, const actual_T& actual,
1024 size_t count, std::string& msg)
1025{
1026 if (!Equal1D (expected, actual, count))
1027 {
1028 std::stringstream stream;
1029 stream << "Expected [ ";
1030 for (size_t i = 0; i < count; ++i)
1031 stream << expected[i] << " ";
1032
1033 stream << "] but was [ ";
1034 for (size_t i = 0; i < count; ++i)
1035 stream << actual[i] << " ";
1036
1037 stream << "]";
1038 msg = stream.str ();
1039 return false;
1040 }
1041 return true;
1042}
1043
1057template <typename expected_T, typename actual_T>
1058bool isClose1D (const expected_T& expected, const actual_T& actual, size_t count, double tolerance)
1059{
1060 for (size_t i = 0; i < count; ++i)
1061 {
1062 if (!isClose(expected[i], actual[i], tolerance))
1063 return false;
1064 }
1065 return true;
1066}
1067
1068
1081template <typename expected_T, typename actual_T>
1082bool CheckArrayClose (const expected_T& expected, const actual_T& actual, size_t count,
1083 double tolerance, std::string& msg)
1084{
1085 if (!isClose1D (expected, actual, count, tolerance))
1086 {
1087 auto fail_tol = tolerance ? tolerance : UnitTest::default_tolerance;
1088 int prec = (int)(1 - log10 (fail_tol));
1089
1090 std::stringstream stream;
1091 stream.precision (prec);
1092 stream.setf (std::ios::fixed);
1093 stream << "Expected [ ";
1094 for (size_t i = 0; i < count; ++i)
1095 stream << expected[i] << " ";
1096
1097 stream << "] +/- " << fail_tol << " but was [ ";
1098 for (size_t i = 0; i < count; ++i)
1099 stream << actual[i] << " ";
1100 stream << "]";
1101 msg = stream.str ();
1102 return false;
1103 }
1104 return true;
1105}
1106
1116template <>
1117inline
1118bool CheckEqual<void, void>(const void* expected, const void* actual, std::string& msg)
1119{
1120 if (!(expected == actual)) {
1121 std::stringstream stream;
1122 stream << "Expected " << expected << " but was " << actual;
1123 msg = stream.str();
1124 return false;
1125 } else
1126 msg.clear();
1127 return true;
1128}
1129
1140template <typename expected_T, typename actual_T>
1141bool CheckClose (const std::vector<expected_T>& expected, const std::vector<actual_T>& actual, double tolerance,
1142 std::string& msg)
1143{
1144 if (expected.size () != actual.size ()
1145 || !isClose1D (&expected[0], &actual[0], expected.size(), tolerance))
1146 {
1147 auto fail_tol = tolerance ? tolerance : UnitTest::default_tolerance;
1148 int prec = (int)(1 - log10 (fail_tol));
1149 std::stringstream stream;
1150 stream.precision (prec);
1151 stream.setf (std::ios::fixed);
1152 stream << "Expected [ ";
1153 for (auto& p : expected)
1154 stream << p << " ";
1155
1156 stream << "] +/- " << fail_tol << " but was [ ";
1157 for (auto& p : actual)
1158 stream << p << " ";
1159 stream << "]";
1160 msg = stream.str ();
1161 return false;
1162 }
1163 return true;
1164}
1165
1176template <typename expected_T, typename actual_T, size_t N>
1177bool CheckClose (const std::array<expected_T, N>& expected, const std::array<actual_T, N>& actual, double tolerance,
1178 std::string& msg)
1179{
1180 if (!isClose1D (&expected[0], &actual[0], N, tolerance))
1181 {
1182 auto fail_tol = tolerance ? tolerance : UnitTest::default_tolerance;
1183 int prec = (int)(1 - log10 (fail_tol));
1184 std::stringstream stream;
1185 stream.precision (prec);
1186 stream.setf (std::ios::fixed);
1187 stream << "Expected [ ";
1188 for (auto& p : expected)
1189 stream << p << " ";
1190
1191 stream << "] +/- " << fail_tol << " but was [ ";
1192 for (auto& p : actual)
1193 stream << p << " ";
1194 stream << "]";
1195 msg = stream.str ();
1196 return false;
1197 }
1198 return true;
1199}
1200
1210template <typename expected_T, typename actual_T>
1211bool Equal2D (const expected_T& expected, const actual_T& actual, size_t rows, size_t columns)
1212{
1213 for (size_t i = 0; i < rows; ++i)
1214 if (!Equal1D (expected[i], actual[i], columns))
1215 return false;
1216 return true;
1217}
1218
1229template <typename expected_T, typename actual_T>
1230bool CheckArray2DEqual (const expected_T& expected, const actual_T& actual,
1231 size_t rows, size_t columns, std::string& msg)
1232{
1233 if (!Equal2D (expected, actual, rows, columns))
1234 {
1235 std::stringstream stream;
1236 size_t i, j;
1237 stream << "Expected [\n";
1238 for (i = 0; i < rows; ++i)
1239 {
1240 stream << " [";
1241 for (j = 0; j < columns; ++j)
1242 stream << expected[i][j] << " ";
1243 stream << "]\n";
1244 }
1245
1246 stream << "] but was [\n";
1247 for (i = 0; i < rows; ++i)
1248 {
1249 stream << " [";
1250 for (j = 0; j < columns; ++j)
1251 stream << actual[i][j] << " ";
1252 stream << "]\n";
1253 }
1254 stream << "]";
1255 msg = stream.str ();
1256 return false;
1257 }
1258 return true;
1259}
1260
1271template <typename expected_T, typename actual_T>
1272bool isClose2D (const expected_T& expected, const actual_T& actual, size_t rows, size_t columns,
1273 double tolerance)
1274{
1275 for (size_t i = 0; i < rows; ++i)
1276 if (!isClose1D (expected[i], actual[i], columns, tolerance))
1277 return false;
1278 return true;
1279}
1280
1293template <typename expected_T, typename actual_T>
1294bool CheckArray2DClose (const expected_T& expected, const actual_T& actual,
1295 size_t rows, size_t columns, double tolerance, std::string& msg)
1296{
1297 if (!isClose2D (expected, actual, rows, columns, tolerance))
1298 {
1299 auto fail_tol = tolerance ? tolerance : UnitTest::default_tolerance;
1300 int prec = (int)(1 - log10 (fail_tol));
1301 std::stringstream stream;
1302 stream.precision (prec);
1303 stream.setf (std::ios::fixed);
1304 stream << "Expected [\n";
1305 size_t i, j;
1306 for (i = 0; i < rows; ++i)
1307 {
1308 stream << " [ ";
1309 for (j = 0; j < columns; ++j)
1310 stream << expected[i][j] << " ";
1311 stream << "]\n";
1312 }
1313
1314 stream << "] +/- " << fail_tol << " but was [\n";
1315 for (i = 0; i < rows; ++i)
1316 {
1317 stream << " [ ";
1318 for (j = 0; j < columns; ++j)
1319 stream << actual[i][j] << " ";
1320 stream << "]\n";
1321 }
1322 stream << "]";
1323 msg = stream.str ();
1324 return false;
1325 }
1326 msg.clear ();
1327 return true;
1328}
1329
1340inline
1341bool CheckFileEqual (const std::string& ref, const std::string& actual, std::string& message)
1342{
1343 struct stat st1, st2;
1344 std::ostringstream buf;
1345
1346 stat (ref.c_str(), &st1);
1347 stat (actual.c_str(), &st2);
1348 if (st1.st_size != st2.st_size)
1349 {
1350 buf << "Size is different (" << st1.st_size << " vs " << st2.st_size
1351 << ") while comparing " << ref << " and " << actual;
1352 message = buf.str();
1353 return false;
1354 }
1355
1356 FILE* f1, * f2;
1357 f1 = fopen (ref.c_str(), "r");
1358 f2 = fopen (actual.c_str(), "r");
1359 if (!f1 || !f2)
1360 {
1361 if (f1) fclose (f1);
1362 if (f2) fclose (f2);
1363 buf << "Failed to open files while comparing "
1364 << ref << " and " << actual;
1365 message = buf.str();
1366 return false; //something wrong with files
1367 }
1368
1369 size_t ln = 0;
1370 bool ok = true;
1371 char ln1[1024], ln2[1024];
1372 while (ok)
1373 {
1374 ln++;
1375 if (fgets (ln1, sizeof (ln1), f1)
1376 && fgets (ln2, sizeof (ln2), f2))
1377 ok = !strcmp (ln1, ln2);
1378 else
1379 break;
1380 }
1381 fclose (f1);
1382 fclose (f2);
1383 if (!ok)
1384 {
1385 char* p1, * p2;
1386 int off;
1387 for (off = 0, p1 = ln1, p2 = ln2;
1388 *p1 && *p2 && *p1 == *p2;
1389 p1++, p2++, off++)
1390 ;
1391 buf << "Difference at line " << ln << " position " << off
1392 << " while comparing " << ref << " and " << actual;
1393 message = buf.str();
1394 }
1395 else
1396 message.clear ();
1397 return ok;
1398}
1399
1400} //end namespace
1401
1407
1408#define EXPECT_TRUE(x) CHECK (x)
1409#define EXPECT_FALSE(x) CHECK (!(x))
1410#define EXPECT_EQ(A, B) CHECK_EQUAL (B, A)
1411#define EXPECT_NE(A, B) \
1412 do \
1413 { \
1414 try { \
1415 std::string str__; \
1416 if (UnitTest::CheckEqual ((A), (B), str__)) \
1417 UnitTest::ReportFailure (__FILE__, __LINE__, str__); \
1418 } \
1419 catch (...) { \
1420 UnitTest::ReportFailure (__FILE__, __LINE__, \
1421 "Unhandled exception in CHECK_EQUAL(" #A ", " #B ")"); \
1422 } \
1423 } while (0)
1424
1425#define EXPECT_GE(A, B) CHECK ((A) >= (B))
1426#define EXPECT_GT(A, B) CHECK ((A) > (B))
1427#define EXPECT_LE(A, B) CHECK ((A) <= (B))
1428#define EXPECT_LT(A, B) CHECK ((A) < (B))
1429
1430#define EXPECT_NEAR(A, B, tol) CHECK_CLOSE(B, A, tol)
1431#define EXPECT_THROW(expr, except) CHECK_THROW(expr, except)
1432
1433#define ASSERT_TRUE(expr) ABORT (!(expr))
1434#define ASSERT_FALSE(expr) ABORT (expr)
1435#define ASSERT_EQ(e1, e2) \
1436 do \
1437 { \
1438 std::string str__; \
1439 if (!UnitTest::CheckEqual((e1), (e2), str__)) \
1440 throw UnitTest::test_abort (__FILE__, __LINE__, str__.c_str()); \
1441 } while (0)
1442
1443#define ASSERT_NE(e1, e2) \
1444 do \
1445 { \
1446 std::string str__; \
1447 if (UnitTest::CheckEqual ((e1), (e2), str__)) \
1448 { \
1449 std::stringstream stream__; \
1450 stream__ << (e1) << " and " << (e2) << " should be different"; \
1451 throw UnitTest::test_abort (__FILE__, __LINE__, stream__.str ().c_str ());\
1452 } \
1453 } while (0)
1454
1455#define ASSERT_GE(e1, e2) ABORT ((e1) < (e2))
1456#define ASSERT_GT(e1, e2) ABORT ((e1) <= (e2))
1457#define ASSERT_LE(e1, e2) ABORT ((e1) > (e2))
1458#define ASSERT_LT(e1, e2) ABORT ((e1) >= (e2))
1460
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:1294
bool CheckClose(const expected_T &expected, const actual_T &actual, double tolerance, std::string &msg)
Definition checks.h:977
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:1058
bool CheckArrayClose(const expected_T &expected, const actual_T &actual, size_t count, double tolerance, std::string &msg)
Definition checks.h:1082
bool CheckArrayEqual(const expected_T &expected, const actual_T &actual, size_t count, std::string &msg)
Definition checks.h:1023
bool CheckArray2DEqual(const expected_T &expected, const actual_T &actual, size_t rows, size_t columns, std::string &msg)
Definition checks.h:1230
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:1005
bool isClose2D(const expected_T &expected, const actual_T &actual, size_t rows, size_t columns, double tolerance)
Definition checks.h:1272
bool CheckFileEqual(const std::string &ref, const std::string &actual, std::string &message)
Definition checks.h:1341
bool Equal2D(const expected_T &expected, const actual_T &actual, size_t rows, size_t columns)
Definition checks.h:1211
bool isClose(const expected_T &expected, const actual_T &actual, double tolerance)
Definition checks.h:955
Definition utpp.h:465