1 /* mutest-private.h: Private declarations
2  *
3  * µTest
4  *
5  * Copyright 2019  Emmanuele Bassi
6  *
7  * SPDX-License-Identifier: MIT
8  */
9 
10 #pragma once
11 
12 #include "config.h"
13 
14 #include "mutest.h"
15 
16 #include <stdio.h>
17 #include <stdint.h>
18 #include <stdarg.h>
19 
20 MUTEST_BEGIN_DECLS
21 
22 typedef enum {
23   MUTEST_RESULT_PASS,
24   MUTEST_RESULT_FAIL,
25   MUTEST_RESULT_SKIP
26 } mutest_result_t;
27 
28 typedef enum {
29   MUTEST_EXPECT_INVALID,
30 
31   MUTEST_EXPECT_BOOLEAN,
32   MUTEST_EXPECT_INT,
33   MUTEST_EXPECT_INT_RANGE,
34   MUTEST_EXPECT_FLOAT,
35   MUTEST_EXPECT_FLOAT_RANGE,
36   MUTEST_EXPECT_STR,
37   MUTEST_EXPECT_POINTER
38 } mutest_expect_type_t;
39 
40 typedef enum {
41   MUTEST_COLLECT_NONE = 0,
42   MUTEST_COLLECT_INT = 1 << 0,
43   MUTEST_COLLECT_FLOAT = 1 << 1,
44   MUTEST_COLLECT_STRING = 1 << 2,
45   MUTEST_COLLECT_POINTER = 1 << 3,
46   MUTEST_COLLECT_BOOLEAN = 1 << 4,
47   MUTEST_COLLECT_PRECISION = 1 << 5,
48   MUTEST_COLLECT_RANGE = 1 << 6,
49   MUTEST_COLLECT_MATCHING_TYPE = 1 << 7,
50 
51   MUTEST_COLLECT_NUMBER = MUTEST_COLLECT_INT | MUTEST_COLLECT_FLOAT,
52   MUTEST_COLLECT_SCALAR = MUTEST_COLLECT_INT |
53                           MUTEST_COLLECT_FLOAT |
54                           MUTEST_COLLECT_STRING |
55                           MUTEST_COLLECT_POINTER |
56                           MUTEST_COLLECT_BOOLEAN
57 } mutest_collect_type_t;
58 
59 typedef enum {
60   MUTEST_OUTPUT_MOCHA,
61   MUTEST_OUTPUT_TAP
62 } mutest_output_format_t;
63 
64 typedef struct {
65   bool initialized;
66 
67   int term_width;
68   int term_height;
69 
70   bool is_tty;
71   bool use_colors;
72 
73   mutest_suite_t *current_suite;
74   mutest_spec_t *current_spec;
75 
76   int n_suites;
77   int total_tests;
78   int total_pass;
79   int total_fail;
80   int total_skip;
81 
82   int64_t start_time;
83   int64_t end_time;
84 
85   mutest_output_format_t output_format;
86 
87   mutest_hook_func_t before_hook;
88   mutest_hook_func_t after_hook;
89 } mutest_state_t;
90 
91 typedef struct {
92   void (* suite_preamble) (mutest_suite_t *suite);
93   void (* spec_preamble) (mutest_spec_t *spec);
94   void (* expect_result) (mutest_expect_t *expect);
95   void (* expect_fail) (mutest_expect_t *expect,
96                         bool negate,
97                         mutest_expect_res_t *check,
98                         const char *check_repr);
99   void (* spec_results) (mutest_spec_t *spec);
100   void (* suite_results) (mutest_suite_t *suite);
101   void (* total_results) (mutest_state_t *state);
102 } mutest_formatter_t;
103 
104 typedef mutest_expect_res_t *(* mutest_collect_func_t) (mutest_expect_type_t expect_type,
105                                                         mutest_collect_type_t collect_type,
106                                                         va_list *args);
107 
108 struct _mutest_expect_res_t
109 {
110   mutest_expect_type_t expect_type;
111 
112   union {
113     bool v_bool;
114 
115     struct {
116       int value;
117       int tolerance;
118     } v_int;
119 
120     struct {
121       int min;
122       int max;
123     } v_irange;
124 
125     struct {
126       double value;
127       double tolerance;
128     } v_float;
129 
130     struct {
131       double min;
132       double max;
133     } v_frange;
134 
135     struct {
136       char *str;
137       size_t len;
138     } v_str;
139 
140     void *v_pointer;
141   } expect;
142 };
143 
144 struct _mutest_expect_t
145 {
146   const char *file;
147   int line;
148   const char *func_name;
149 
150   const char *description;
151 
152   const char *skip_reason;
153 
154   mutest_expect_res_t *value;
155 
156   mutest_result_t result;
157 };
158 
159 struct _mutest_spec_t
160 {
161   const char *file;
162   int line;
163   const char *func_name;
164 
165   const char *description;
166 
167   int n_expects;
168   int pass;
169   int fail;
170   int skip;
171 
172   int64_t start_time;
173   int64_t end_time;
174 
175   bool skip_all;
176   const char *skip_reason;
177 };
178 
179 struct _mutest_suite_t
180 {
181   const char *file;
182   int line;
183   const char *func_name;
184 
185   const char *description;
186 
187   int64_t start_time;
188   int64_t end_time;
189 
190   mutest_hook_func_t before_each_hook;
191   mutest_hook_func_t after_each_hook;
192 
193   int n_specs;
194   int pass;
195   int fail;
196   int skip;
197 
198   bool skip_all;
199   const char *skip_reason;
200 };
201 
202 #define mutest_oom_abort() \
203   mutest_assert_message (__FILE__, __LINE__, __func__, "out-of-memory")
204 
205 #define mutest_assert_if_reached(str) \
206   mutest_assert_message (__FILE__, __LINE__, __func__, (str))
207 
208 #define mutest_assert(x) \
209   mutest_assert_message (__FILE__, __LINE__, __func__, #x)
210 
211 #if defined(__GNUC__) && __GNUC__ > 3
212 # define mutest_likely(x)       (__builtin_expect((x) ? 1 : 0, 1))
213 # define mutest_unlikely(x)     (__builtin_expect((x) ? 1 : 0, 0))
214 #else
215 # define mutest_likely(x)       (x)
216 # define mutest_unlikely(x)     (x)
217 #endif
218 
219 #define ANSI_ESCAPE "\033"
220 
221 #define MUTEST_COLOR_NONE               ANSI_ESCAPE "[0m"
222 #define MUTEST_COLOR_RED                ANSI_ESCAPE "[1;31m"
223 #define MUTEST_COLOR_GREEN              ANSI_ESCAPE "[1;32m"
224 #define MUTEST_COLOR_YELLOW             ANSI_ESCAPE "[1;33m"
225 #define MUTEST_COLOR_BLUE               ANSI_ESCAPE "[1;34m"
226 #define MUTEST_COLOR_LIGHT_GREY         ANSI_ESCAPE "[1;37m"
227 #define MUTEST_COLOR_DARK_GREY          ANSI_ESCAPE "[1;90m"
228 
229 #define MUTEST_BOLD_DEFAULT             ANSI_ESCAPE "[1;39m"
230 #define MUTEST_DIM_DEFAULT              ANSI_ESCAPE "[2;39m"
231 #define MUTEST_UNDERLINE_DEFAULT        ANSI_ESCAPE "[4;39m"
232 
233 mutest_expect_res_t *
234 mutest_expect_res_alloc (mutest_expect_type_t type);
235 
236 void
237 mutest_expect_res_free (mutest_expect_res_t *res);
238 
239 char *
240 mutest_strdup (const char *str);
241 
242 char *
243 mutest_strndup (const char *str,
244                 size_t len);
245 
246 char *
247 mutest_strdup_and_len (const char *str,
248                        size_t *len);
249 
250 char *
251 mutest_getenv (const char *env_name);
252 
253 void
254 mutest_print (FILE *stram,
255               const char *first_fragment,
256               ...) MUTEST_NULL_TERMINATED;
257 
258 void
259 mutest_assert_message (const char *file,
260                        int line,
261                        const char *func,
262                        const char *message) MUTEST_NO_RETURN;
263 
264 mutest_state_t *
265 mutest_get_global_state (void);
266 
267 int
268 mutest_get_term_width (void);
269 
270 int
271 mutest_get_term_height (void);
272 
273 bool
274 mutest_is_term_tty (void);
275 
276 bool
277 mutest_use_colors (void);
278 
279 mutest_output_format_t
280 mutest_get_output_format (void);
281 
282 void
283 mutest_set_current_suite (mutest_suite_t *suite);
284 
285 mutest_suite_t *
286 mutest_get_current_suite (void);
287 
288 void
289 mutest_set_current_spec (mutest_spec_t *spec);
290 
291 mutest_spec_t *
292 mutest_get_current_spec (void);
293 
294 int64_t
295 mutest_get_current_time (void);
296 
297 double
298 mutest_format_time (int64_t t,
299                     const char **unit);
300 
301 char *
302 mutest_format_string_for_display (const char *str,
303                                   char indent_ch,
304                                   size_t indent_len);
305 
306 void
307 mutest_expect_res_to_string (mutest_expect_res_t *res,
308                              char *buf,
309                              size_t len);
310 
311 void
312 mutest_expect_diagnostic (mutest_expect_t *expect,
313                           bool negate,
314                           mutest_expect_res_t *check,
315                           const char *check_repr,
316                           char **diagnostic,
317                           char **location);
318 
319 void
320 mutest_spec_add_expect_result (mutest_spec_t *spec,
321                                mutest_expect_t *expect);
322 
323 void
324 mutest_suite_add_spec_results (mutest_suite_t *suite,
325                                mutest_spec_t *spec);
326 
327 void
328 mutest_add_suite_results (mutest_suite_t *suite);
329 
330 int
331 mutest_get_results (int *total_pass,
332                     int *total_fail,
333                     int *total_skip);
334 
335 void
336 mutest_format_suite_preamble (mutest_suite_t *suite);
337 
338 void
339 mutest_format_spec_preamble (mutest_spec_t *spec);
340 
341 void
342 mutest_format_expect_result (mutest_expect_t *expect);
343 
344 void
345 mutest_format_expect_fail (mutest_expect_t *expect,
346                            bool negate,
347                            mutest_expect_res_t *check,
348                            const char *check_repr);
349 void
350 mutest_format_spec_results (mutest_spec_t *spec);
351 
352 void
353 mutest_format_suite_results (mutest_suite_t *suite);
354 
355 void
356 mutest_format_total_results (mutest_state_t *state);
357 
358 const mutest_formatter_t *
359 mutest_get_mocha_formatter (void);
360 
361 const mutest_formatter_t *
362 mutest_get_tap_formatter (void);
363 
364 MUTEST_END_DECLS
365