/builds/xfbs/passgen/src/tests/tests.h
Line | Count | Source (jump to first uncovered line) |
1 | | /// @file tests.h |
2 | | /// @author Patrick M. Elsen |
3 | | /// @license MIT. |
4 | | /// |
5 | | /// Small testing framework. |
6 | | |
7 | | #pragma once |
8 | | #include <stdbool.h> |
9 | | #include <stdio.h> |
10 | | #include <string.h> |
11 | | |
12 | | /// Result of a test. |
13 | | typedef struct { |
14 | | /// True if the test worked okay, false if there was an error. |
15 | | bool ok; |
16 | | /// If false, a string of the assertion that failed. |
17 | | const char *assertion; |
18 | | /// If false, the name of the function in which the failure happened. |
19 | | const char *func; |
20 | | /// The line in which the assertion failed. |
21 | | size_t line; |
22 | | } test_result; |
23 | | |
24 | | extern test_result test_ok; |
25 | | |
26 | | typedef test_result test_func(void); |
27 | | |
28 | | typedef struct { |
29 | | const char *name; |
30 | | test_func *func; |
31 | | } test_entry; |
32 | | |
33 | | typedef struct { |
34 | | test_entry entry; |
35 | | int number; |
36 | | int amount; |
37 | | int verbosity; |
38 | | } test_run; |
39 | | |
40 | | bool run(test_run test); |
41 | | |
42 | | #define test(id) \ |
43 | | { .name = #id, .func = test_##id } |
44 | | |
45 | | #define assert(some) \ |
46 | 1.02M | if(!(some)) \ |
47 | 1.02M | return (test_result){ \ |
48 | 0 | .ok = false, \ |
49 | 0 | .assertion = #some, \ |
50 | 0 | .line = __LINE__, \ |
51 | 0 | .func = __func__}; |
52 | | |
53 | | #define assert_eq(lhs, rhs) \ |
54 | 26.8M | if(lhs != rhs) \ |
55 | 26.8M | return (test_result){ \ |
56 | 0 | .ok = false, \ |
57 | 0 | .assertion = #lhs " == " #rhs, \ |
58 | 0 | .line = __LINE__, \ |
59 | 0 | .func = __func__}; |
60 | | |
61 | | #define assert_ne(lhs, rhs) \ |
62 | | if(lhs == rhs) \ |
63 | | return (test_result){ \ |
64 | | .ok = false, \ |
65 | | .assertion = #lhs " != " #rhs, \ |
66 | | .line = __LINE__, \ |
67 | | .func = __func__}; |
68 | | |
69 | | #define assert_gt(lhs, rhs) \ |
70 | | if(lhs <= rhs) \ |
71 | | return (test_result){ \ |
72 | | .ok = false, \ |
73 | | .assertion = #lhs " > " #rhs, \ |
74 | | .line = __LINE__, \ |
75 | | .func = __func__}; |
76 | | |
77 | | #define assert_ge(lhs, rhs) \ |
78 | | if(lhs < rhs) \ |
79 | | return (test_result){ \ |
80 | | .ok = false, \ |
81 | | .assertion = #lhs " >= " #rhs, \ |
82 | | .line = __LINE__, \ |
83 | | .func = __func__}; |
84 | | |
85 | | #define assert_lt(lhs, rhs) \ |
86 | | if(lhs >= rhs) \ |
87 | | return (test_result){ \ |
88 | | .ok = false, \ |
89 | | .assertion = #lhs " < " #rhs, \ |
90 | | .line = __LINE__, \ |
91 | | .func = __func__}; |
92 | | |
93 | | #define assert_le(lhs, rhs) \ |
94 | | if(lhs > rhs) \ |
95 | | return (test_result){ \ |
96 | | .ok = false, \ |
97 | | .assertion = #lhs " <= " #rhs, \ |
98 | | .line = __LINE__, \ |
99 | | .func = __func__}; |
100 | | |
101 | | #define assert_streq(lhs, rhs) \ |
102 | 2 | if(strcmp(lhs, rhs) != 0) \ |
103 | 2 | return (test_result){ \ |
104 | 0 | .ok = false, \ |
105 | 0 | .assertion = #lhs " == " #rhs, \ |
106 | 0 | .line = __LINE__, \ |
107 | 0 | .func = __func__}; |
108 | | |
109 | | extern test_entry tests[]; |
110 | | extern size_t tests_len; |