1 /* mutest-matchers.c: Matching functions
2 *
3 * µTest - Copyright 2019 Emmanuele Bassi
4 *
5 * SPDX-License-Identifier: MIT
6 */
7
8 #include "mutest-private.h"
9
10 #include <string.h>
11 #include <stdlib.h>
12 #include <stdarg.h>
13 #include <math.h>
14
15 bool
mutest_not(mutest_expect_t * e MUTEST_UNUSED,mutest_expect_res_t * check MUTEST_UNUSED)16 mutest_not (mutest_expect_t *e MUTEST_UNUSED,
17 mutest_expect_res_t *check MUTEST_UNUSED)
18 {
19 return true;
20 }
21
22 bool
mutest_skip(mutest_expect_t * e MUTEST_UNUSED,mutest_expect_res_t * check MUTEST_UNUSED)23 mutest_skip (mutest_expect_t *e MUTEST_UNUSED,
24 mutest_expect_res_t *check MUTEST_UNUSED)
25 {
26 return true;
27 }
28
29 static bool
mutest_to_be_boolean(mutest_expect_t * e,mutest_expect_res_t * check)30 mutest_to_be_boolean (mutest_expect_t *e,
31 mutest_expect_res_t *check)
32 {
33 mutest_expect_res_t *value = e->value;
34
35 if (value->expect_type == MUTEST_EXPECT_BOOLEAN &&
36 check->expect_type == MUTEST_EXPECT_BOOLEAN)
37 return value->expect.v_bool == check->expect.v_bool;
38
39 return false;
40 }
41
42 static inline bool
int_near_equal(int a,int b,int epsilon)43 int_near_equal (int a,
44 int b,
45 int epsilon)
46 {
47 return (a > b ? (a - b) : (b - a)) <= epsilon;
48 }
49
50 static bool
mutest_to_be_int_value(mutest_expect_t * e,mutest_expect_res_t * check)51 mutest_to_be_int_value (mutest_expect_t *e,
52 mutest_expect_res_t *check)
53 {
54 mutest_expect_res_t *value = e->value;
55
56 if (value->expect_type == MUTEST_EXPECT_INT &&
57 check->expect_type == MUTEST_EXPECT_INT)
58 {
59 return int_near_equal (value->expect.v_int.value,
60 check->expect.v_int.value,
61 check->expect.v_int.tolerance);
62 }
63
64 return false;
65 }
66
67 static bool
mutest_to_be_in_int_range(mutest_expect_t * e,mutest_expect_res_t * check)68 mutest_to_be_in_int_range (mutest_expect_t *e,
69 mutest_expect_res_t *check)
70 {
71 if (e->value->expect_type == MUTEST_EXPECT_INT &&
72 check->expect_type == MUTEST_EXPECT_INT_RANGE)
73 {
74 if (e->value->expect.v_int.value >= check->expect.v_irange.min &&
75 e->value->expect.v_int.value <= check->expect.v_irange.max)
76 return true;
77 }
78
79 return false;
80 }
81
82 static inline bool
float_near_equal(double a,double b,double epsilon)83 float_near_equal (double a,
84 double b,
85 double epsilon)
86 {
87 return (a > b ? (a - b) : (b - a)) <= epsilon;
88 }
89
90 static bool
mutest_to_be_float_value(mutest_expect_t * e,mutest_expect_res_t * check)91 mutest_to_be_float_value (mutest_expect_t *e,
92 mutest_expect_res_t *check)
93 {
94 mutest_expect_res_t *value = e->value;
95
96 if (value->expect_type == MUTEST_EXPECT_FLOAT &&
97 check->expect_type == MUTEST_EXPECT_FLOAT)
98 {
99 return float_near_equal (value->expect.v_float.value,
100 check->expect.v_float.value,
101 check->expect.v_float.tolerance);
102 }
103
104 return false;
105 }
106
107 static bool
mutest_to_be_in_float_range(mutest_expect_t * e,mutest_expect_res_t * check)108 mutest_to_be_in_float_range (mutest_expect_t *e,
109 mutest_expect_res_t *check)
110 {
111 if (e->value->expect_type == MUTEST_EXPECT_FLOAT &&
112 check->expect_type == MUTEST_EXPECT_FLOAT_RANGE)
113 {
114 if (e->value->expect.v_float.value >= check->expect.v_frange.min &&
115 e->value->expect.v_float.value <= check->expect.v_frange.max)
116 return true;
117 }
118
119 return false;
120 }
121
122 static bool
mutest_to_be_pointer(mutest_expect_t * e,mutest_expect_res_t * check)123 mutest_to_be_pointer (mutest_expect_t *e,
124 mutest_expect_res_t *check)
125 {
126 mutest_expect_res_t *value = e->value;
127
128 if (value->expect_type == MUTEST_EXPECT_POINTER &&
129 check->expect_type == MUTEST_EXPECT_POINTER)
130 return value->expect.v_pointer == check->expect.v_pointer;
131
132 return false;
133 }
134
135 static bool
mutest_to_be_string(mutest_expect_t * e,mutest_expect_res_t * check)136 mutest_to_be_string (mutest_expect_t *e,
137 mutest_expect_res_t *check)
138 {
139 if (e->value->expect_type == MUTEST_EXPECT_STR &&
140 check->expect_type == MUTEST_EXPECT_STR)
141 {
142 if (e->value->expect.v_str.len != check->expect.v_str.len)
143 return false;
144
145 if (e->value->expect.v_str.str == NULL && check->expect.v_str.str == NULL)
146 return true;
147
148 if (e->value->expect.v_str.str != NULL &&
149 check->expect.v_str.str != NULL &&
150 strcmp (e->value->expect.v_str.str, check->expect.v_str.str) == 0)
151 return true;
152 }
153
154 return false;
155 }
156
157 bool
mutest_to_be(mutest_expect_t * e,mutest_expect_res_t * check)158 mutest_to_be (mutest_expect_t *e,
159 mutest_expect_res_t *check)
160 {
161 mutest_expect_res_t *value = e->value;
162
163 if (value->expect_type != check->expect_type)
164 return false;
165
166 switch (value->expect_type)
167 {
168 case MUTEST_EXPECT_BOOLEAN:
169 return mutest_to_be_boolean (e, check);
170
171 case MUTEST_EXPECT_INT:
172 return mutest_to_be_int_value (e, check);
173
174 case MUTEST_EXPECT_INT_RANGE:
175 return mutest_to_be_in_int_range (e, check);
176
177 case MUTEST_EXPECT_FLOAT:
178 return mutest_to_be_float_value (e, check);
179
180 case MUTEST_EXPECT_FLOAT_RANGE:
181 return mutest_to_be_in_float_range (e, check);
182
183 case MUTEST_EXPECT_POINTER:
184 return mutest_to_be_pointer (e, check);
185
186 case MUTEST_EXPECT_STR:
187 return mutest_to_be_string (e, check);
188
189 case MUTEST_EXPECT_INVALID:
190 mutest_assert_if_reached ("invalid expect value");
191 break;
192 }
193
194 return false;
195 }
196
197 bool
mutest_to_be_close_to(mutest_expect_t * e,mutest_expect_res_t * check)198 mutest_to_be_close_to (mutest_expect_t *e,
199 mutest_expect_res_t *check)
200 {
201 mutest_expect_res_t *value = e->value;
202
203 if (value->expect_type == MUTEST_EXPECT_FLOAT)
204 return mutest_to_be_float_value (e, check);
205
206 if (value->expect_type == MUTEST_EXPECT_INT)
207 return mutest_to_be_int_value (e, check);
208
209 return false;
210 }
211
212 bool
mutest_to_be_nan(mutest_expect_t * e,mutest_expect_res_t * check MUTEST_UNUSED)213 mutest_to_be_nan (mutest_expect_t *e,
214 mutest_expect_res_t *check MUTEST_UNUSED)
215 {
216 mutest_expect_res_t *value = e->value;
217
218 if (value->expect_type == MUTEST_EXPECT_FLOAT)
219 return isnan (value->expect.v_float.value) != 0;
220
221 return false;
222 }
223
224 bool
mutest_to_be_positive_infinity(mutest_expect_t * e,mutest_expect_res_t * check MUTEST_UNUSED)225 mutest_to_be_positive_infinity (mutest_expect_t *e,
226 mutest_expect_res_t *check MUTEST_UNUSED)
227 {
228 mutest_expect_res_t *value = e->value;
229
230 if (value->expect_type == MUTEST_EXPECT_FLOAT)
231 return isinf (value->expect.v_float.value) != 0 && signbit (value->expect.v_float.value) == 0;
232
233 return false;
234 }
235
236 bool
mutest_to_be_negative_infinity(mutest_expect_t * e,mutest_expect_res_t * check MUTEST_UNUSED)237 mutest_to_be_negative_infinity (mutest_expect_t *e,
238 mutest_expect_res_t *check MUTEST_UNUSED)
239 {
240 mutest_expect_res_t *value = e->value;
241
242 if (value->expect_type == MUTEST_EXPECT_FLOAT)
243 return isinf (value->expect.v_float.value) != 0 && signbit (value->expect.v_float.value) != 0;
244
245 return false;
246 }
247
248 bool
mutest_to_be_true(mutest_expect_t * e,mutest_expect_res_t * check MUTEST_UNUSED)249 mutest_to_be_true (mutest_expect_t *e,
250 mutest_expect_res_t *check MUTEST_UNUSED)
251 {
252 mutest_expect_res_t *value = e->value;
253
254 if (value->expect_type == MUTEST_EXPECT_BOOLEAN)
255 return value->expect.v_bool;
256
257 if (value->expect_type == MUTEST_EXPECT_INT)
258 return value->expect.v_int.value != 0;
259
260 return false;
261 }
262
263 bool
mutest_to_be_false(mutest_expect_t * e,mutest_expect_res_t * check MUTEST_UNUSED)264 mutest_to_be_false (mutest_expect_t *e,
265 mutest_expect_res_t *check MUTEST_UNUSED)
266 {
267 mutest_expect_res_t *value = e->value;
268
269 if (value->expect_type == MUTEST_EXPECT_BOOLEAN)
270 return !value->expect.v_bool;
271
272 if (value->expect_type == MUTEST_EXPECT_INT)
273 return value->expect.v_int.value == 0;
274
275 return false;
276 }
277
278 bool
mutest_to_be_null(mutest_expect_t * e,mutest_expect_res_t * check MUTEST_UNUSED)279 mutest_to_be_null (mutest_expect_t *e,
280 mutest_expect_res_t *check MUTEST_UNUSED)
281 {
282 mutest_expect_res_t *value = e->value;
283
284 if (value->expect_type == MUTEST_EXPECT_POINTER)
285 return value->expect.v_pointer == NULL;
286
287 return false;
288 }
289
290 bool
mutest_to_be_greater_than(mutest_expect_t * e,mutest_expect_res_t * check)291 mutest_to_be_greater_than (mutest_expect_t *e,
292 mutest_expect_res_t *check)
293 {
294 mutest_expect_res_t *value = e->value;
295
296 if (value->expect_type == MUTEST_EXPECT_INT && check->expect_type == MUTEST_EXPECT_INT)
297 return value->expect.v_int.value > check->expect.v_int.value;
298
299 if (value->expect_type == MUTEST_EXPECT_FLOAT && check->expect_type == MUTEST_EXPECT_FLOAT)
300 return value->expect.v_float.value > check->expect.v_float.value;
301
302 return false;
303 }
304
305 bool
mutest_to_be_greater_than_or_equal(mutest_expect_t * e,mutest_expect_res_t * check)306 mutest_to_be_greater_than_or_equal (mutest_expect_t *e,
307 mutest_expect_res_t *check)
308 {
309 mutest_expect_res_t *value = e->value;
310
311 if (value->expect_type == MUTEST_EXPECT_INT && check->expect_type == MUTEST_EXPECT_INT)
312 return value->expect.v_int.value >= check->expect.v_int.value;
313
314 if (value->expect_type == MUTEST_EXPECT_FLOAT && check->expect_type == MUTEST_EXPECT_FLOAT)
315 return value->expect.v_float.value >= check->expect.v_float.value;
316
317 return false;
318 }
319
320 bool
mutest_to_be_less_than_or_equal(mutest_expect_t * e,mutest_expect_res_t * check)321 mutest_to_be_less_than_or_equal (mutest_expect_t *e,
322 mutest_expect_res_t *check)
323 {
324 mutest_expect_res_t *value = e->value;
325
326 if (value->expect_type == MUTEST_EXPECT_INT && check->expect_type == MUTEST_EXPECT_INT)
327 return value->expect.v_int.value <= check->expect.v_int.value;
328
329 if (value->expect_type == MUTEST_EXPECT_FLOAT && check->expect_type == MUTEST_EXPECT_FLOAT)
330 return value->expect.v_float.value <= check->expect.v_float.value;
331
332 return false;
333 }
334
335 bool
mutest_to_be_less_than(mutest_expect_t * e,mutest_expect_res_t * check)336 mutest_to_be_less_than (mutest_expect_t *e,
337 mutest_expect_res_t *check)
338 {
339 mutest_expect_res_t *value = e->value;
340
341 if (value->expect_type == MUTEST_EXPECT_INT && check->expect_type == MUTEST_EXPECT_INT)
342 return value->expect.v_int.value < check->expect.v_int.value;
343
344 if (value->expect_type == MUTEST_EXPECT_FLOAT && check->expect_type == MUTEST_EXPECT_FLOAT)
345 return value->expect.v_float.value < check->expect.v_float.value;
346
347 return false;
348 }
349
350 bool
mutest_to_be_in_range(mutest_expect_t * e,mutest_expect_res_t * check)351 mutest_to_be_in_range (mutest_expect_t *e,
352 mutest_expect_res_t *check)
353 {
354 mutest_expect_res_t *value = e->value;
355
356 if (value->expect_type == MUTEST_EXPECT_INT)
357 return mutest_to_be_in_int_range (e, check);
358
359 if (value->expect_type == MUTEST_EXPECT_FLOAT)
360 return mutest_to_be_in_float_range (e, check);
361
362 return false;
363 }
364
365 bool
mutest_to_contain(mutest_expect_t * e,mutest_expect_res_t * check)366 mutest_to_contain (mutest_expect_t *e,
367 mutest_expect_res_t *check)
368 {
369 mutest_expect_res_t *value = e->value;
370
371 if (value->expect_type == MUTEST_EXPECT_INT_RANGE &&
372 check->expect_type == MUTEST_EXPECT_INT)
373 {
374 if (check->expect.v_int.value >= value->expect.v_irange.min &&
375 check->expect.v_int.value <= value->expect.v_irange.max)
376 return true;
377
378 return false;
379 }
380
381 if (value->expect_type == MUTEST_EXPECT_FLOAT_RANGE &&
382 check->expect_type == MUTEST_EXPECT_FLOAT)
383 {
384 if (check->expect.v_float.value >= value->expect.v_frange.min &&
385 check->expect.v_float.value <= value->expect.v_frange.max)
386 return true;
387
388 return false;
389 }
390
391 if (value->expect_type == MUTEST_EXPECT_STR &&
392 check->expect_type == MUTEST_EXPECT_STR)
393 {
394 if (value->expect.v_str.len < check->expect.v_str.len)
395 return false;
396
397 if (strstr (value->expect.v_str.str, check->expect.v_str.str) != NULL)
398 return true;
399 }
400
401 return false;
402 }
403
404 bool
mutest_to_contain_string(mutest_expect_t * e,mutest_expect_res_t * check)405 mutest_to_contain_string (mutest_expect_t *e,
406 mutest_expect_res_t *check)
407 {
408 if (e->value->expect_type == MUTEST_EXPECT_STR &&
409 check->expect_type == MUTEST_EXPECT_STR)
410 {
411 if (e->value->expect.v_str.len < check->expect.v_str.len)
412 return false;
413
414 if (strstr (e->value->expect.v_str.str, check->expect.v_str.str) != NULL)
415 return true;
416 }
417
418 return false;
419 }
420
421 bool
mutest_to_start_with_string(mutest_expect_t * e,mutest_expect_res_t * check)422 mutest_to_start_with_string (mutest_expect_t *e,
423 mutest_expect_res_t *check)
424 {
425 if (e->value->expect_type == MUTEST_EXPECT_STR &&
426 check->expect_type == MUTEST_EXPECT_STR)
427 {
428 if (e->value->expect.v_str.len < check->expect.v_str.len)
429 return false;
430
431 const char *str = e->value->expect.v_str.str;
432 const char *prefix = check->expect.v_str.str;
433
434 size_t prefix_len = check->expect.v_str.len;
435
436 return strncmp (str, prefix, prefix_len) == 0;
437 }
438
439 return false;
440 }
441
442 bool
mutest_to_end_with_string(mutest_expect_t * e,mutest_expect_res_t * check)443 mutest_to_end_with_string (mutest_expect_t *e,
444 mutest_expect_res_t *check)
445 {
446 if (e->value->expect_type == MUTEST_EXPECT_STR &&
447 check->expect_type == MUTEST_EXPECT_STR)
448 {
449 if (e->value->expect.v_str.len < check->expect.v_str.len)
450 return false;
451
452 const char *str = e->value->expect.v_str.str;
453 const char *suffix = check->expect.v_str.str;
454
455 size_t str_len = e->value->expect.v_str.len;
456 size_t suffix_len = check->expect.v_str.len;
457
458 return strcmp (str + str_len - suffix_len, suffix) == 0;
459 }
460
461 return false;
462 }
463