66
77#define CLIP_STRING_LENGTH 16
88
9- #define expect (...) cest::expectFunction(__FILE__, __LINE__, __VA_ARGS__)
9+ #define expect (...) cest::expectFunction(__FILE__, (( __LINE__ - 1 )) , __VA_ARGS__)
1010#define passTest () cest::forcedPass()
1111#define failTest () cest::forcedFailure(__FILE__, __LINE__)
1212#define Regex (x ) x, std::regex(x)
@@ -45,28 +45,33 @@ namespace cest
4545 class Assertion
4646 {
4747 public:
48- Assertion (const char *file, int line, T value)
48+ Assertion (const char *file, int line, T value, bool negated = false ) : negated( false )
4949 {
5050 actual = value;
5151 assertion_file = std::string (file);
5252 assertion_line = line;
53+
54+ if (!negated)
55+ this ->Not = new Assertion<T>(file, line, value, true );
56+ else
57+ this ->negated = true ;
5358 }
5459
5560 void toBeTruthy ()
5661 {
57- if (!actual)
62+ if (!actual ^ this -> negated )
5863 throw AssertionError (assertion_file, assertion_line, " Expresion is not truthy" );
5964 }
6065
6166 void toBeFalsy ()
6267 {
63- if (actual)
68+ if (actual ^ this -> negated )
6469 throw AssertionError (assertion_file, assertion_line, " Expresion is not falsy" );
6570 }
6671
6772 void toBe (T expected)
6873 {
69- if (expected != actual)
74+ if (( expected != actual) ^ this -> negated )
7075 {
7176
7277 std::stringstream message;
@@ -83,22 +88,23 @@ namespace cest
8388 void toEqualMemory (T expected, int64_t length)
8489 {
8590 int i;
91+ bool any_byte_differs = false ;
8692
8793 for (i = 0 ; i < length; ++i)
94+ any_byte_differs |= expected[i] != actual[i];
95+
96+ if (any_byte_differs ^ negated)
8897 {
89- if (expected[i] != actual[i])
90- {
91- std::stringstream message;
92- message << " Memory mismatch at byte " << i << " , expected " ;
93- message << std::hex << std::uppercase << (int )expected[i] << " but was " << std::hex << std::uppercase << (int )actual[i];
94- throw AssertionError (assertion_file, assertion_line, message.str ());
95- }
98+ std::stringstream message;
99+ message << " Memory mismatch at byte " << i << " , expected " ;
100+ message << std::hex << std::uppercase << (int )expected[i] << " but was " << std::hex << std::uppercase << (int )actual[i];
101+ throw AssertionError (assertion_file, assertion_line, message.str ());
96102 }
97103 }
98104
99105 void toBeNotNull ()
100106 {
101- if (actual == NULL )
107+ if (( actual == NULL ) ^ negated )
102108 {
103109 std::stringstream message;
104110 message << " Expected 0x" << std::hex << std::uppercase << actual << " to be not null" ;
@@ -108,15 +114,18 @@ namespace cest
108114
109115 void toBeNull ()
110116 {
111- if (actual != NULL )
117+ if (( actual != NULL ) ^ negated )
112118 {
113119 std::stringstream message;
114120 message << " Expected 0x" << std::hex << std::uppercase << actual << " to be null" ;
115121 throw AssertionError (assertion_file, assertion_line, message.str ());
116122 }
117123 }
118124
125+ Assertion<T> *Not;
126+
119127 private:
128+ bool negated;
120129 T actual;
121130 std::string assertion_file;
122131 int assertion_line;
@@ -126,16 +135,21 @@ namespace cest
126135 class Assertion <double >
127136 {
128137 public:
129- Assertion (const char *file, int line, double value)
138+ Assertion (const char *file, int line, double value, bool negated = false ) : negated( false )
130139 {
131140 actual = value;
132141 assertion_file = std::string (file);
133142 assertion_line = line;
143+
144+ if (!negated)
145+ this ->Not = new Assertion<double >(file, line, value, true );
146+ else
147+ this ->negated = true ;
134148 }
135149
136150 void toBe (double expected, double epsilon = 0.0000001 )
137151 {
138- if (fabs (actual - expected) > epsilon)
152+ if (( fabs (actual - expected) > epsilon) ^ negated )
139153 {
140154 std::stringstream message;
141155 message << " Expected " << expected << " , was " << actual;
@@ -150,7 +164,7 @@ namespace cest
150164
151165 void toBeGreaterThan (double expected)
152166 {
153- if (actual < expected)
167+ if (( actual < expected) ^ negated )
154168 {
155169 std::stringstream message;
156170 message << " Expected " << expected << " to be greather than" << actual;
@@ -160,15 +174,18 @@ namespace cest
160174
161175 void toBeLessThan (double expected)
162176 {
163- if (actual > expected)
177+ if (( actual > expected) ^ negated )
164178 {
165179 std::stringstream message;
166180 message << " Expected " << expected << " to be less than" << actual;
167181 throw AssertionError (assertion_file, assertion_line, message.str ());
168182 }
169183 }
170184
185+ Assertion<double > *Not;
186+
171187 private:
188+ bool negated;
172189 double actual;
173190 std::string assertion_file;
174191 int assertion_line;
@@ -178,16 +195,21 @@ namespace cest
178195 class Assertion <float >
179196 {
180197 public:
181- Assertion (const char *file, int line, float value)
198+ Assertion (const char *file, int line, float value, bool negated = false ) : negated( false )
182199 {
183200 actual = value;
184201 assertion_file = std::string (file);
185202 assertion_line = line;
203+
204+ if (!negated)
205+ this ->Not = new Assertion<float >(file, line, value, true );
206+ else
207+ this ->negated = true ;
186208 }
187209
188210 void toBe (float expected, float epsilon = 0 .00001f )
189211 {
190- if (fabs (actual - expected) > epsilon)
212+ if (( fabs (actual - expected) > epsilon) ^ negated )
191213 {
192214 std::stringstream message;
193215 message << " Expected " << expected << " , was " << actual;
@@ -202,7 +224,7 @@ namespace cest
202224
203225 void toBeGreaterThan (float expected)
204226 {
205- if (actual < expected)
227+ if (( actual < expected) ^ negated )
206228 {
207229 std::stringstream message;
208230 message << " Expected " << expected << " to be greather than" << actual;
@@ -212,15 +234,18 @@ namespace cest
212234
213235 void toBeLessThan (float expected)
214236 {
215- if (actual > expected)
237+ if (( actual > expected) ^ negated )
216238 {
217239 std::stringstream message;
218240 message << " Expected " << expected << " to be less than" << actual;
219241 throw AssertionError (assertion_file, assertion_line, message.str ());
220242 }
221243 }
222244
245+ Assertion<float > *Not;
246+
223247 private:
248+ bool negated;
224249 float actual;
225250 std::string assertion_file;
226251 int assertion_line;
@@ -230,30 +255,43 @@ namespace cest
230255 class Assertion <std::vector<T>>
231256 {
232257 public:
233- Assertion (const char *file, int line, std::vector<T> value)
258+ Assertion (const char *file, int line, std::vector<T> value, bool negated = false ) : negated( false )
234259 {
235260 actual = value;
236261 assertion_file = std::string (file);
237262 assertion_line = line;
263+
264+ if (!negated)
265+ this ->Not = new Assertion<std::vector<T>>(file, line, value, true );
266+ else
267+ this ->negated = true ;
238268 }
239269
240270 void toBe (std::vector<T> expected)
241271 {
242- if (expected.size () != actual.size ())
272+ if (( expected.size () != actual.size ()) ^ negated )
243273 {
244274 std::stringstream message;
245275 message << " Vector sizes do not match, expected " << expected.size () << " items but had " << actual.size () << " items" ;
246276 throw AssertionError (assertion_file, assertion_line, message.str ());
247277 }
248278
279+ bool any_item_differs = false ;
280+ size_t found_difference = 0 ;
281+
249282 for (size_t i = 0 ; i < expected.size (); ++i)
250283 {
284+ any_item_differs |= expected[i] != actual[i];
285+
251286 if (expected[i] != actual[i])
252- {
253- std::stringstream message;
254- message << " Vector item mismatch at position " << i << " , expected " << expected[i] << " but was " << actual[i];
255- throw AssertionError (assertion_file, assertion_line, message.str ());
256- }
287+ found_difference = i;
288+ }
289+
290+ if (any_item_differs ^ negated)
291+ {
292+ std::stringstream message;
293+ message << " Vector item mismatch at position " << found_difference << " , expected " << expected[found_difference] << " but was " << actual[found_difference];
294+ throw AssertionError (assertion_file, assertion_line, message.str ());
257295 }
258296 }
259297
@@ -275,7 +313,7 @@ namespace cest
275313 }
276314 }
277315
278- if (!found)
316+ if (!found ^ negated )
279317 {
280318 std::stringstream message;
281319 message << " Item " << item << " not found in vector" ;
@@ -285,15 +323,18 @@ namespace cest
285323
286324 void toHaveLength (size_t size)
287325 {
288- if (actual.size () != size)
326+ if (( actual.size () != size) ^ negated )
289327 {
290328 std::stringstream message;
291329 message << " Vector sizes does not match, expected " << size << " items but had " << actual.size () << " items" ;
292330 throw AssertionError (assertion_file, assertion_line, message.str ());
293331 }
294332 }
295333
334+ Assertion<std::vector<T>> *Not;
335+
296336 private:
337+ bool negated;
297338 std::vector<T> actual;
298339 std::string assertion_file;
299340 int assertion_line;
@@ -303,16 +344,21 @@ namespace cest
303344 class Assertion <std::string>
304345 {
305346 public:
306- Assertion (const char *file, int line, std::string value)
347+ Assertion (const char *file, int line, std::string value, bool negated = false ) : negated( false )
307348 {
308349 actual = value;
309350 assertion_file = std::string (file);
310351 assertion_line = line;
352+
353+ if (!negated)
354+ this ->Not = new Assertion<std::string>(file, line, value, true );
355+ else
356+ this ->negated = true ;
311357 }
312358
313359 void toBe (std::string expected)
314360 {
315- if (expected != actual)
361+ if (( expected != actual) ^ negated )
316362 {
317363 std::stringstream message;
318364
@@ -338,7 +384,7 @@ namespace cest
338384
339385 void toMatch (std::string expected_string, std::regex expected)
340386 {
341- if (!std::regex_search (actual, expected))
387+ if (!std::regex_search (actual, expected) ^ negated )
342388 {
343389 std::stringstream message;
344390 if (expected_string.size () > CLIP_STRING_LENGTH || actual.size () > CLIP_STRING_LENGTH)
@@ -363,7 +409,7 @@ namespace cest
363409
364410 void toContain (std::string expected)
365411 {
366- if (actual.find (expected) == std::string::npos)
412+ if (( actual.find (expected) == std::string::npos) ^ negated )
367413 {
368414 std::stringstream message;
369415
@@ -384,15 +430,18 @@ namespace cest
384430
385431 void toHaveLength (size_t length)
386432 {
387- if (actual.length () != length)
433+ if (( actual.length () != length) ^ negated )
388434 {
389435 std::stringstream message;
390436 message << " Length of \" " << actual << " \" expected to be " << length << " , was " << actual.length ();
391437 throw AssertionError (assertion_file, assertion_line, message.str ());
392438 }
393439 }
394440
441+ Assertion<std::string> *Not;
442+
395443 private:
444+ bool negated;
396445 std::string actual;
397446 std::string assertion_file;
398447
@@ -424,4 +473,4 @@ namespace cest
424473 {
425474 return Assertion<std::string>(file, line, (std::string)actual);
426475 }
427- }
476+ }
0 commit comments