1 // -*- coding: utf-8 -*-
2 
3 #ifndef SG_MISC_TEST_MACROS_HXX
4 #define SG_MISC_TEST_MACROS_HXX
5 
6 #include <iostream>
7 #include <cmath>                // for std::fabs()
8 
9 
10 // Assertion-like test
11 #define SG_VERIFY(a) \
12     if (!(a))  { \
13         std::cerr << "failed: " << #a << std::endl; \
14         std::cerr << "\tat " << __FILE__ << ":" << __LINE__ << std::endl; \
15         exit(1); \
16     }
17 
18 // Internal macro (implementation detail). 'a' and 'b' don't always support
19 // operator<<. This is why we use (a0) and (b0) after '<<', otherwise in such
20 // cases the test couldn't be compiled, even if 'stream' is false.
21 #define SG_CHECK_EQUAL0(a, b, stream, a0, b0) \
22     if ( !((a) == (b)) )  { \
23         std::cerr << "failed: " << #a << " == " << #b << std::endl; \
24         if (stream) { \
25           std::cerr << "\tgot '" << (a0) << "' and '" << (b0) << "'" \
26                     << std::endl; \
27         }; \
28         std::cerr << "\tat " << __FILE__ << ":" << __LINE__ << std::endl; \
29         exit(1); \
30     }
31 
32 // Test macros for user consumption. The _NOSTREAM variant is for cases where
33 // 'a' or 'b' doesn't support operator<< (or where using it would have
34 // undesirable side effects).
35 #define SG_CHECK_EQUAL(a, b) SG_CHECK_EQUAL0((a), (b), true, (a), (b))
36 #define SG_CHECK_EQUAL_NOSTREAM(a, b) SG_CHECK_EQUAL0((a), (b), false, "", "")
37 
38 // “Approximate equality” test (EP stands for “epsilon”)
39 #define SG_CHECK_EQUAL_EP0(a, b, stream, a0, b0) \
40     if (std::fabs((a) - (b)) > SG_EPSILON)  { \
41         std::cerr << "failed: " << #a << " ~= " << #b << std::endl; \
42         if (stream) { \
43           std::cerr << "\tgot '" << (a0) << "' and '" << (b0) << "'" \
44                     << std::endl; \
45         }; \
46         std::cerr << "\tat " << __FILE__ << ":" << __LINE__ << std::endl; \
47         exit(1); \
48     }
49 
50 #define SG_CHECK_EQUAL_EP(a, b) SG_CHECK_EQUAL_EP0((a), (b), true, (a), (b))
51 #define SG_CHECK_EQUAL_EP_NOSTREAM(a, b) \
52     SG_CHECK_EQUAL_EP0((a), (b), false, "", "")
53 
54 // Same as SG_CHECK_EQUAL_EP*, except the “epsilon” can be chosen by the caller
55 #define SG_CHECK_EQUAL_EP2_0(a, b, ep, stream, a0, b0) \
56   if (std::fabs((a) - (b)) > (ep))  {                  \
57         std::cerr << "failed: " << #a << " ~= " << #b << std::endl; \
58         if (stream) { \
59           std::cerr << "\tgot '" << (a0) << "' and '" << (b0) << "'" \
60                     << std::endl; \
61         }; \
62         std::cerr << "\tat " << __FILE__ << ":" << __LINE__ << std::endl; \
63         exit(1); \
64     }
65 
66 #define SG_CHECK_EQUAL_EP2(a, b, ep) \
67     SG_CHECK_EQUAL_EP2_0((a), (b), ep, true, (a), (b))
68 #define SG_CHECK_EQUAL_EP2_NOSTREAM(a, b) \
69     SG_CHECK_EQUAL_EP2_0((a), (b), ep, false, "", "")
70 
71 // “Non-equal” test
72 #define SG_CHECK_NE0(a, b, stream, a0, b0) \
73     if ( !((a) != (b)) )  { \
74         std::cerr << "failed: " << #a << " != " << #b << std::endl; \
75         if (stream) { \
76           std::cerr << "\tgot '" << (a0) << "' and '" << (b0) << "'" \
77                     << std::endl; \
78         }; \
79         std::cerr << "\tat " << __FILE__ << ":" << __LINE__ << std::endl; \
80         exit(1); \
81     }
82 
83 #define SG_CHECK_NE(a, b) SG_CHECK_NE0((a), (b), true, (a), (b))
84 #define SG_CHECK_NE_NOSTREAM(a, b) SG_CHECK_NE0((a), (b), false, "", "")
85 
86 // “Lower than” test
87 #define SG_CHECK_LT0(a, b, stream, a0, b0) \
88     if ( !((a) < (b)) )  { \
89         std::cerr << "failed: " << #a << " < " << #b << std::endl; \
90         if (stream) { \
91           std::cerr << "\tgot '" << (a0) << "' and '" << (b0) << "'" \
92                     << std::endl; \
93         }; \
94         std::cerr << "\tat " << __FILE__ << ":" << __LINE__ << std::endl; \
95         exit(1); \
96     }
97 
98 #define SG_CHECK_LT(a, b) SG_CHECK_LT0((a), (b), true, (a), (b))
99 #define SG_CHECK_LT_NOSTREAM(a, b) SG_CHECK_LT0((a), (b), false, "", "")
100 
101 // “Lower than or equal” test
102 #define SG_CHECK_LE0(a, b, stream, a0, b0) \
103     if ( !((a) <= (b)) )  { \
104         std::cerr << "failed: " << #a << " <= " << #b << std::endl; \
105         if (stream) { \
106           std::cerr << "\tgot '" << (a0) << "' and '" << (b0) << "'" \
107                     << std::endl; \
108         }; \
109         std::cerr << "\tat " << __FILE__ << ":" << __LINE__ << std::endl; \
110         exit(1); \
111     }
112 
113 #define SG_CHECK_LE(a, b) SG_CHECK_LE0((a), (b), true, (a), (b))
114 #define SG_CHECK_LE_NOSTREAM(a, b) SG_CHECK_LE0((a), (b), false, "", "")
115 
116 // “Greater than” test
117 #define SG_CHECK_GT0(a, b, stream, a0, b0) \
118     if ( !((a) > (b)) )  { \
119         std::cerr << "failed: " << #a << " > " << #b << std::endl; \
120         if (stream) { \
121           std::cerr << "\tgot '" << (a0) << "' and '" << (b0) << "'" \
122                     << std::endl; \
123         }; \
124         std::cerr << "\tat " << __FILE__ << ":" << __LINE__ << std::endl; \
125         exit(1); \
126     }
127 
128 #define SG_CHECK_GT(a, b) SG_CHECK_GT0((a), (b), true, (a), (b))
129 #define SG_CHECK_GT_NOSTREAM(a, b) SG_CHECK_GT0((a), (b), false, "", "")
130 
131 // “Greater than or equal” test
132 #define SG_CHECK_GE0(a, b, stream, a0, b0) \
133     if ( !((a) >= (b)) )  { \
134         std::cerr << "failed: " << #a << " >= " << #b << std::endl; \
135         if (stream) { \
136           std::cerr << "\tgot '" << (a0) << "' and '" << (b0) << "'" \
137                     << std::endl; \
138         }; \
139         std::cerr << "\tat " << __FILE__ << ":" << __LINE__ << std::endl; \
140         exit(1); \
141     }
142 
143 #define SG_CHECK_GE(a, b) SG_CHECK_GE0((a), (b), true, (a), (b))
144 #define SG_CHECK_GE_NOSTREAM(a, b) SG_CHECK_GE0((a), (b), false, "", "")
145 
146 // “Is NULL” test
147 #define SG_CHECK_IS_NULL0(a, stream, a0) \
148     if ( !((a) == nullptr) )  { \
149         std::cerr << "failed: " << #a << " == nullptr" << std::endl; \
150         if (stream) { \
151           std::cerr << "\tgot '" << (a0) << "'" << std::endl; \
152         }; \
153         std::cerr << "\tat " << __FILE__ << ":" << __LINE__ << std::endl; \
154         exit(1); \
155     }
156 
157 #define SG_CHECK_IS_NULL(a) SG_CHECK_IS_NULL0((a), true, (a))
158 #define SG_CHECK_IS_NULL_NOSTREAM(a) SG_CHECK_IS_NULL0((a), false, "")
159 
160 // “Is not NULL” test
161 #define SG_CHECK_IS_NOT_NULL0(a, stream, a0) \
162     if ( !((a) != nullptr) )  { \
163         std::cerr << "failed: " << #a << " != nullptr" << std::endl; \
164         if (stream) { \
165           std::cerr << "\tgot '" << (a0) << "'" << std::endl; \
166         }; \
167         std::cerr << "\tat " << __FILE__ << ":" << __LINE__ << std::endl; \
168         exit(1); \
169     }
170 
171 #define SG_CHECK_IS_NOT_NULL(a) SG_CHECK_IS_NOT_NULL0((a), true, (a))
172 #define SG_CHECK_IS_NOT_NULL_NOSTREAM(a) SG_CHECK_IS_NOT_NULL0((a), false, "")
173 
174 // “Always failing” test
175 #define SG_TEST_FAIL(msg) \
176   std::cerr << "failure: " << msg; \
177   exit(1);
178 
179 
180 #endif // of SG_MISC_TEST_MACROS_HXX
181