MeterLogger
greatest.h
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2011 Scott Vokes <vokes.s@gmail.com>
3  *
4  * Permission to use, copy, modify, and/or distribute this software for any
5  * purpose with or without fee is hereby granted, provided that the above
6  * copyright notice and this permission notice appear in all copies.
7  *
8  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15  */
16 
17 #ifndef GREATEST_H
18 #define GREATEST_H
19 
20 #define GREATEST_VERSION_MAJOR 0
21 #define GREATEST_VERSION_MINOR 9
22 #define GREATEST_VERSION_PATCH 3
23 
24 /* A unit testing system for C, contained in 1 file.
25  * It doesn't use dynamic allocation or depend on anything
26  * beyond ANSI C89. */
27 
28 
29 /*********************************************************************
30  * Minimal test runner template
31  *********************************************************************/
32 #if 0
33 
34 #include "greatest.h"
35 
36 TEST foo_should_foo() {
37  PASS();
38 }
39 
40 static void setup_cb(void *data) {
41  printf("setup callback for each test case\n");
42 }
43 
44 static void teardown_cb(void *data) {
45  printf("teardown callback for each test case\n");
46 }
47 
48 SUITE(suite) {
49  /* Optional setup/teardown callbacks which will be run before/after
50  * every test case in the suite.
51  * Cleared when the suite finishes. */
52  SET_SETUP(setup_cb, voidp_to_callback_data);
53  SET_TEARDOWN(teardown_cb, voidp_to_callback_data);
54 
55  RUN_TEST(foo_should_foo);
56 }
57 
58 /* Add all the definitions that need to be in the test runner's main file. */
60 
61 int main(int argc, char **argv) {
62  GREATEST_MAIN_BEGIN(); /* command-line arguments, initialization. */
63  RUN_SUITE(suite);
64  GREATEST_MAIN_END(); /* display results */
65 }
66 
67 #endif
68 /*********************************************************************/
69 
70 
71 #include <stdlib.h>
72 #include <stdio.h>
73 #include <string.h>
74 #include <time.h>
75 
76 
77 /***********
78  * Options *
79  ***********/
80 
81 /* Default column width for non-verbose output. */
82 #ifndef GREATEST_DEFAULT_WIDTH
83 #define GREATEST_DEFAULT_WIDTH 72
84 #endif
85 
86 /* FILE *, for test logging. */
87 #ifndef GREATEST_STDOUT
88 #define GREATEST_STDOUT stdout
89 #endif
90 
91 /* Remove GREATEST_ prefix from most commonly used symbols? */
92 #ifndef GREATEST_USE_ABBREVS
93 #define GREATEST_USE_ABBREVS 1
94 #endif
95 
96 
97 /*********
98  * Types *
99  *********/
100 
101 /* Info for the current running suite. */
102 typedef struct greatest_suite_info {
103  unsigned int tests_run;
104  unsigned int passed;
105  unsigned int failed;
106  unsigned int skipped;
107 
108  /* timers, pre/post running suite and individual tests */
109  clock_t pre_suite;
110  clock_t post_suite;
111  clock_t pre_test;
112  clock_t post_test;
114 
115 /* Type for a suite function. */
116 typedef void (greatest_suite_cb)(void);
117 
118 /* Types for setup/teardown callbacks. If non-NULL, these will be run
119  * and passed the pointer to their additional data. */
120 typedef void (greatest_setup_cb)(void *udata);
121 typedef void (greatest_teardown_cb)(void *udata);
122 
123 typedef enum {
127 } GREATEST_FLAG;
128 
129 typedef struct greatest_run_info {
130  unsigned int flags;
131  unsigned int tests_run; /* total test count */
132 
133  /* Overall pass/fail/skip counts. */
134  unsigned int passed;
135  unsigned int failed;
136  unsigned int skipped;
137 
138  /* currently running test suite */
140 
141  /* info to print about the most recent failure */
142  const char *fail_file;
143  unsigned int fail_line;
144  const char *msg;
145 
146  /* current setup/teardown hooks and userdata */
148  void *setup_udata;
151 
152  /* formatting info for ".....s...F"-style output */
153  unsigned int col;
154  unsigned int width;
155 
156  /* only run a specific suite or test */
158  char *test_filter;
159 
160  /* overall timers */
161  clock_t begin;
162  clock_t end;
164 
165 /* Global var for the current testing context.
166  * Initialized by GREATEST_MAIN_DEFS(). */
168 
169 
170 /**********************
171  * Exported functions *
172  **********************/
173 
174 void greatest_do_pass(const char *name);
175 void greatest_do_fail(const char *name);
176 void greatest_do_skip(const char *name);
177 int greatest_pre_test(const char *name);
178 void greatest_post_test(const char *name, int res);
179 void greatest_usage(const char *name);
180 void GREATEST_SET_SETUP_CB(greatest_setup_cb *cb, void *udata);
181 void GREATEST_SET_TEARDOWN_CB(greatest_teardown_cb *cb, void *udata);
182 
183 
184 /**********
185  * Macros *
186  **********/
187 
188 /* Define a suite. */
189 #define GREATEST_SUITE(NAME) void NAME(void)
190 
191 /* Start defining a test function.
192  * The arguments are not included, to allow parametric testing. */
193 #define GREATEST_TEST static int
194 
195 /* Run a suite. */
196 #define GREATEST_RUN_SUITE(S_NAME) greatest_run_suite(S_NAME, #S_NAME)
197 
198 /* Run a test in the current suite. */
199 #define GREATEST_RUN_TEST(TEST) \
200  do { \
201  if (greatest_pre_test(#TEST) == 1) { \
202  int res = TEST(); \
203  greatest_post_test(#TEST, res); \
204  } else if (GREATEST_LIST_ONLY()) { \
205  fprintf(GREATEST_STDOUT, " %s\n", #TEST); \
206  } \
207  } while (0)
208 
209 /* Run a test in the current suite with one void* argument,
210  * which can be a pointer to a struct with multiple arguments. */
211 #define GREATEST_RUN_TEST1(TEST, ENV) \
212  do { \
213  if (greatest_pre_test(#TEST) == 1) { \
214  int res = TEST(ENV); \
215  greatest_post_test(#TEST, res); \
216  } else if (GREATEST_LIST_ONLY()) { \
217  fprintf(GREATEST_STDOUT, " %s\n", #TEST); \
218  } \
219  } while (0)
220 
221 /* If __VA_ARGS__ (C99) is supported, allow parametric testing
222  * without needing to manually manage the argument struct. */
223 #if __STDC_VERSION__ >= 19901L
224 #define GREATEST_RUN_TESTp(TEST, ...) \
225  do { \
226  if (greatest_pre_test(#TEST) == 1) { \
227  int res = TEST(__VA_ARGS__); \
228  greatest_post_test(#TEST, res); \
229  } else if (GREATEST_LIST_ONLY()) { \
230  fprintf(GREATEST_STDOUT, " %s\n", #TEST); \
231  } \
232  } while (0)
233 #endif
234 
235 
236 /* Check if the test runner is in verbose mode. */
237 #define GREATEST_IS_VERBOSE() (greatest_info.flags & GREATEST_FLAG_VERBOSE)
238 #define GREATEST_LIST_ONLY() (greatest_info.flags & GREATEST_FLAG_LIST_ONLY)
239 #define GREATEST_FIRST_FAIL() (greatest_info.flags & GREATEST_FLAG_FIRST_FAIL)
240 #define GREATEST_FAILURE_ABORT() (greatest_info.suite.failed > 0 && GREATEST_FIRST_FAIL())
241 
242 /* Message-less forms. */
243 #define GREATEST_PASS() GREATEST_PASSm(NULL)
244 #define GREATEST_FAIL() GREATEST_FAILm(NULL)
245 #define GREATEST_SKIP() GREATEST_SKIPm(NULL)
246 #define GREATEST_ASSERT(COND) GREATEST_ASSERTm(#COND, COND)
247 #define GREATEST_ASSERT_FALSE(COND) GREATEST_ASSERT_FALSEm(#COND, COND)
248 #define GREATEST_ASSERT_EQ(EXP, GOT) GREATEST_ASSERT_EQm(#EXP " != " #GOT, EXP, GOT)
249 #define GREATEST_ASSERT_STR_EQ(EXP, GOT) GREATEST_ASSERT_STR_EQm(#EXP " != " #GOT, EXP, GOT)
250 
251 /* The following forms take an additional message argument first,
252  * to be displayed by the test runner. */
253 
254 /* Fail if a condition is not true, with message. */
255 #define GREATEST_ASSERTm(MSG, COND) \
256  do { \
257  greatest_info.msg = MSG; \
258  greatest_info.fail_file = __FILE__; \
259  greatest_info.fail_line = __LINE__; \
260  if (!(COND)) return -1; \
261  greatest_info.msg = NULL; \
262  } while (0)
263 
264 #define GREATEST_ASSERT_FALSEm(MSG, COND) \
265  do { \
266  greatest_info.msg = MSG; \
267  greatest_info.fail_file = __FILE__; \
268  greatest_info.fail_line = __LINE__; \
269  if ((COND)) return -1; \
270  greatest_info.msg = NULL; \
271  } while (0)
272 
273 #define GREATEST_ASSERT_EQm(MSG, EXP, GOT) \
274  do { \
275  greatest_info.msg = MSG; \
276  greatest_info.fail_file = __FILE__; \
277  greatest_info.fail_line = __LINE__; \
278  if ((EXP) != (GOT)) return -1; \
279  greatest_info.msg = NULL; \
280  } while (0)
281 
282 #define GREATEST_ASSERT_STR_EQm(MSG, EXP, GOT) \
283  do { \
284  const char *exp_s = (EXP); \
285  const char *got_s = (GOT); \
286  greatest_info.msg = MSG; \
287  greatest_info.fail_file = __FILE__; \
288  greatest_info.fail_line = __LINE__; \
289  if (0 != strcmp(exp_s, got_s)) { \
290  fprintf(GREATEST_STDOUT, \
291  "Expected:\n####\n%s\n####\n", exp_s); \
292  fprintf(GREATEST_STDOUT, \
293  "Got:\n####\n%s\n####\n", got_s); \
294  return -1; \
295  } \
296  greatest_info.msg = NULL; \
297  } while (0)
298 
299 #define GREATEST_PASSm(MSG) \
300  do { \
301  greatest_info.msg = MSG; \
302  return 0; \
303  } while (0)
304 
305 #define GREATEST_FAILm(MSG) \
306  do { \
307  greatest_info.fail_file = __FILE__; \
308  greatest_info.fail_line = __LINE__; \
309  greatest_info.msg = MSG; \
310  return -1; \
311  } while (0)
312 
313 #define GREATEST_SKIPm(MSG) \
314  do { \
315  greatest_info.msg = MSG; \
316  return 1; \
317  } while (0)
318 
319 #define GREATEST_SET_TIME(NAME) \
320  NAME = clock(); \
321  if (NAME == (clock_t) -1) { \
322  fprintf(GREATEST_STDOUT, \
323  "clock error: %s\n", #NAME); \
324  exit(EXIT_FAILURE); \
325  }
326 
327 #define GREATEST_CLOCK_DIFF(C1, C2) \
328  fprintf(GREATEST_STDOUT, " (%lu ticks, %.3f sec)", \
329  (long unsigned int) (C2) - (C1), \
330  (double)((C2) - (C1)) / (1.0 * (double)CLOCKS_PER_SEC)) \
331 
332 /* Include several function definitions in the main test file. */
333 #define GREATEST_MAIN_DEFS() \
334  \
335 /* Is FILTER a subset of NAME? */ \
336 static int greatest_name_match(const char *name, \
337  const char *filter) { \
338  size_t offset = 0; \
339  size_t filter_len = strlen(filter); \
340  while (name[offset] != '\0') { \
341  if (name[offset] == filter[0]) { \
342  if (0 == strncmp(&name[offset], filter, filter_len)) { \
343  return 1; \
344  } \
345  } \
346  offset++; \
347  } \
348  \
349  return 0; \
350 } \
351  \
352 int greatest_pre_test(const char *name) { \
353  if (!GREATEST_LIST_ONLY() \
354  && (!GREATEST_FIRST_FAIL() || greatest_info.suite.failed == 0) \
355  && (greatest_info.test_filter == NULL || \
356  greatest_name_match(name, greatest_info.test_filter))) { \
357  GREATEST_SET_TIME(greatest_info.suite.pre_test); \
358  if (greatest_info.setup) { \
359  greatest_info.setup(greatest_info.setup_udata); \
360  } \
361  return 1; /* test should be run */ \
362  } else { \
363  return 0; /* skipped */ \
364  } \
365 } \
366  \
367 void greatest_post_test(const char *name, int res) { \
368  GREATEST_SET_TIME(greatest_info.suite.post_test); \
369  if (greatest_info.teardown) { \
370  void *udata = greatest_info.teardown_udata; \
371  greatest_info.teardown(udata); \
372  } \
373  \
374  if (res < 0) { \
375  greatest_do_fail(name); \
376  } else if (res > 0) { \
377  greatest_do_skip(name); \
378  } else if (res == 0) { \
379  greatest_do_pass(name); \
380  } \
381  greatest_info.suite.tests_run++; \
382  greatest_info.col++; \
383  if (GREATEST_IS_VERBOSE()) { \
384  GREATEST_CLOCK_DIFF(greatest_info.suite.pre_test, \
385  greatest_info.suite.post_test); \
386  fprintf(GREATEST_STDOUT, "\n"); \
387  } else if (greatest_info.col % greatest_info.width == 0) { \
388  fprintf(GREATEST_STDOUT, "\n"); \
389  greatest_info.col = 0; \
390  } \
391  if (GREATEST_STDOUT == stdout) fflush(stdout); \
392 } \
393  \
394 static void greatest_run_suite(greatest_suite_cb *suite_cb, \
395  const char *suite_name) { \
396  if (greatest_info.suite_filter && \
397  !greatest_name_match(suite_name, greatest_info.suite_filter)) \
398  return; \
399  if (GREATEST_FIRST_FAIL() && greatest_info.failed > 0) return; \
400  greatest_info.suite.tests_run = 0; \
401  greatest_info.suite.failed = 0; \
402  greatest_info.suite.passed = 0; \
403  greatest_info.suite.skipped = 0; \
404  greatest_info.suite.pre_suite = 0; \
405  greatest_info.suite.post_suite = 0; \
406  greatest_info.suite.pre_test = 0; \
407  greatest_info.suite.post_test = 0; \
408  greatest_info.col = 0; \
409  fprintf(GREATEST_STDOUT, "\n* Suite %s:\n", suite_name); \
410  GREATEST_SET_TIME(greatest_info.suite.pre_suite); \
411  suite_cb(); \
412  GREATEST_SET_TIME(greatest_info.suite.post_suite); \
413  if (greatest_info.suite.tests_run > 0) { \
414  fprintf(GREATEST_STDOUT, \
415  "\n%u tests - %u pass, %u fail, %u skipped", \
416  greatest_info.suite.tests_run, \
417  greatest_info.suite.passed, \
418  greatest_info.suite.failed, \
419  greatest_info.suite.skipped); \
420  GREATEST_CLOCK_DIFF(greatest_info.suite.pre_suite, \
421  greatest_info.suite.post_suite); \
422  fprintf(GREATEST_STDOUT, "\n"); \
423  } \
424  greatest_info.setup = NULL; \
425  greatest_info.setup_udata = NULL; \
426  greatest_info.teardown = NULL; \
427  greatest_info.teardown_udata = NULL; \
428  greatest_info.passed += greatest_info.suite.passed; \
429  greatest_info.failed += greatest_info.suite.failed; \
430  greatest_info.skipped += greatest_info.suite.skipped; \
431  greatest_info.tests_run += greatest_info.suite.tests_run; \
432 } \
433  \
434 void greatest_do_pass(const char *name) { \
435  if (GREATEST_IS_VERBOSE()) { \
436  fprintf(GREATEST_STDOUT, "PASS %s: %s", \
437  name, greatest_info.msg ? greatest_info.msg : ""); \
438  } else { \
439  fprintf(GREATEST_STDOUT, "."); \
440  } \
441  greatest_info.suite.passed++; \
442 } \
443  \
444 void greatest_do_fail(const char *name) { \
445  if (GREATEST_IS_VERBOSE()) { \
446  fprintf(GREATEST_STDOUT, \
447  "FAIL %s: %s (%s:%u)", \
448  name, greatest_info.msg ? greatest_info.msg : "", \
449  greatest_info.fail_file, greatest_info.fail_line); \
450  } else { \
451  fprintf(GREATEST_STDOUT, "F"); \
452  /* add linebreak if in line of '.'s */ \
453  if (greatest_info.col % greatest_info.width != 0) \
454  fprintf(GREATEST_STDOUT, "\n"); \
455  greatest_info.col = 0; \
456  fprintf(GREATEST_STDOUT, "FAIL %s: %s (%s:%u)\n", \
457  name, \
458  greatest_info.msg ? greatest_info.msg : "", \
459  greatest_info.fail_file, greatest_info.fail_line); \
460  } \
461  greatest_info.suite.failed++; \
462 } \
463  \
464 void greatest_do_skip(const char *name) { \
465  if (GREATEST_IS_VERBOSE()) { \
466  fprintf(GREATEST_STDOUT, "SKIP %s: %s", \
467  name, \
468  greatest_info.msg ? \
469  greatest_info.msg : "" ); \
470  } else { \
471  fprintf(GREATEST_STDOUT, "s"); \
472  } \
473  greatest_info.suite.skipped++; \
474 } \
475  \
476 void greatest_usage(const char *name) { \
477  fprintf(GREATEST_STDOUT, \
478  "Usage: %s [-hlfv] [-s SUITE] [-t TEST]\n" \
479  " -h print this Help\n" \
480  " -l List suites and their tests, then exit\n" \
481  " -f Stop runner after first failure\n" \
482  " -v Verbose output\n" \
483  " -s SUITE only run suite named SUITE\n" \
484  " -t TEST only run test named TEST\n", \
485  name); \
486 } \
487  \
488 void GREATEST_SET_SETUP_CB(greatest_setup_cb *cb, void *udata) { \
489  greatest_info.setup = cb; \
490  greatest_info.setup_udata = udata; \
491 } \
492  \
493 void GREATEST_SET_TEARDOWN_CB(greatest_teardown_cb *cb, \
494  void *udata) { \
495  greatest_info.teardown = cb; \
496  greatest_info.teardown_udata = udata; \
497 } \
498  \
499 greatest_run_info greatest_info
500 
501 /* Handle command-line arguments, etc. */
502 #define GREATEST_MAIN_BEGIN() \
503  do { \
504  int i = 0; \
505  memset(&greatest_info, 0, sizeof(greatest_info)); \
506  if (greatest_info.width == 0) { \
507  greatest_info.width = GREATEST_DEFAULT_WIDTH; \
508  } \
509  for (i = 1; i < argc; i++) { \
510  if (0 == strcmp("-t", argv[i])) { \
511  if (argc <= i + 1) { \
512  greatest_usage(argv[0]); \
513  exit(EXIT_FAILURE); \
514  } \
515  greatest_info.test_filter = argv[i+1]; \
516  i++; \
517  } else if (0 == strcmp("-s", argv[i])) { \
518  if (argc <= i + 1) { \
519  greatest_usage(argv[0]); \
520  exit(EXIT_FAILURE); \
521  } \
522  greatest_info.suite_filter = argv[i+1]; \
523  i++; \
524  } else if (0 == strcmp("-f", argv[i])) { \
525  greatest_info.flags |= GREATEST_FLAG_FIRST_FAIL; \
526  } else if (0 == strcmp("-v", argv[i])) { \
527  greatest_info.flags |= GREATEST_FLAG_VERBOSE; \
528  } else if (0 == strcmp("-l", argv[i])) { \
529  greatest_info.flags |= GREATEST_FLAG_LIST_ONLY; \
530  } else if (0 == strcmp("-h", argv[i])) { \
531  greatest_usage(argv[0]); \
532  exit(EXIT_SUCCESS); \
533  } else { \
534  fprintf(GREATEST_STDOUT, \
535  "Unknown argument '%s'\n", argv[i]); \
536  greatest_usage(argv[0]); \
537  exit(EXIT_FAILURE); \
538  } \
539  } \
540  } while (0); \
541  GREATEST_SET_TIME(greatest_info.begin)
542 
543 #define GREATEST_MAIN_END() \
544  do { \
545  if (!GREATEST_LIST_ONLY()) { \
546  GREATEST_SET_TIME(greatest_info.end); \
547  fprintf(GREATEST_STDOUT, \
548  "\nTotal: %u tests", greatest_info.tests_run); \
549  GREATEST_CLOCK_DIFF(greatest_info.begin, \
550  greatest_info.end); \
551  fprintf(GREATEST_STDOUT, "\n"); \
552  fprintf(GREATEST_STDOUT, \
553  "Pass: %u, fail: %u, skip: %u.\n", \
554  greatest_info.passed, \
555  greatest_info.failed, greatest_info.skipped); \
556  } \
557  return (greatest_info.failed > 0 \
558  ? EXIT_FAILURE : EXIT_SUCCESS); \
559  } while (0)
560 
561 /* Make abbreviations without the GREATEST_ prefix for the
562  * most commonly used symbols. */
563 #if GREATEST_USE_ABBREVS
564 #define TEST GREATEST_TEST
565 #define SUITE GREATEST_SUITE
566 #define RUN_TEST GREATEST_RUN_TEST
567 #define RUN_TEST1 GREATEST_RUN_TEST1
568 #define RUN_SUITE GREATEST_RUN_SUITE
569 #define ASSERT GREATEST_ASSERT
570 #define ASSERTm GREATEST_ASSERTm
571 #define ASSERT_FALSE GREATEST_ASSERT_FALSE
572 #define ASSERT_EQ GREATEST_ASSERT_EQ
573 #define ASSERT_STR_EQ GREATEST_ASSERT_STR_EQ
574 #define ASSERT_FALSEm GREATEST_ASSERT_FALSEm
575 #define ASSERT_EQm GREATEST_ASSERT_EQm
576 #define ASSERT_STR_EQm GREATEST_ASSERT_STR_EQm
577 #define PASS GREATEST_PASS
578 #define FAIL GREATEST_FAIL
579 #define SKIP GREATEST_SKIP
580 #define PASSm GREATEST_PASSm
581 #define FAILm GREATEST_FAILm
582 #define SKIPm GREATEST_SKIPm
583 #define SET_SETUP GREATEST_SET_SETUP_CB
584 #define SET_TEARDOWN GREATEST_SET_TEARDOWN_CB
585 
586 #if __STDC_VERSION__ >= 19901L
587 #endif /* C99 */
588 #define RUN_TESTp GREATEST_RUN_TESTp
589 #endif /* USE_ABBREVS */
590 
591 #endif
void GREATEST_SET_TEARDOWN_CB(greatest_teardown_cb *cb, void *udata)
void greatest_do_skip(const char *name)
unsigned int skipped
Definition: greatest.h:136
greatest_run_info greatest_info
#define RUN_SUITE
Definition: greatest.h:568
char * suite_filter
Definition: greatest.h:157
int greatest_pre_test(const char *name)
char * test_filter
Definition: greatest.h:158
greatest_setup_cb * setup
Definition: greatest.h:147
#define RUN_TEST
Definition: greatest.h:566
#define SET_TEARDOWN
Definition: greatest.h:584
unsigned int skipped
Definition: greatest.h:106
#define PASS
Definition: greatest.h:577
#define TEST
Definition: greatest.h:564
void() greatest_teardown_cb(void *udata)
Definition: greatest.h:121
void * setup_udata
Definition: greatest.h:148
greatest_teardown_cb * teardown
Definition: greatest.h:149
unsigned int passed
Definition: greatest.h:134
void() greatest_setup_cb(void *udata)
Definition: greatest.h:120
void() greatest_suite_cb(void)
Definition: greatest.h:116
void greatest_do_fail(const char *name)
struct greatest_run_info greatest_run_info
unsigned int col
Definition: greatest.h:153
unsigned int tests_run
Definition: greatest.h:131
unsigned int passed
Definition: greatest.h:104
void greatest_do_pass(const char *name)
void * teardown_udata
Definition: greatest.h:150
int main(int argc, char **argv)
Definition: heatshrink.c:422
unsigned int failed
Definition: greatest.h:135
unsigned int width
Definition: greatest.h:154
unsigned int fail_line
Definition: greatest.h:143
const char * fail_file
Definition: greatest.h:142
#define SUITE
Definition: greatest.h:565
void GREATEST_SET_SETUP_CB(greatest_setup_cb *cb, void *udata)
struct greatest_suite_info greatest_suite_info
#define GREATEST_MAIN_DEFS()
Definition: greatest.h:333
greatest_suite_info suite
Definition: greatest.h:139
const char * msg
Definition: greatest.h:144
void greatest_usage(const char *name)
unsigned int failed
Definition: greatest.h:105
#define SET_SETUP
Definition: greatest.h:583
#define printf(...)
Definition: platform.h:13
void greatest_post_test(const char *name, int res)
unsigned int tests_run
Definition: greatest.h:103
#define GREATEST_MAIN_BEGIN()
Definition: greatest.h:502
unsigned int flags
Definition: greatest.h:130
#define GREATEST_MAIN_END()
Definition: greatest.h:543
GREATEST_FLAG
Definition: greatest.h:123
clock_t post_suite
Definition: greatest.h:110