test: Introduce TEST_DESTRUCTOR macro
[libisds.git] / test / test.h
blobd7d5ef6b01b89221dbd3591f6ae51d38b0eb0ad1
1 #ifndef __ISDS_TEST_H
2 #define __ISDS_TEST_H
4 #ifndef _XOPEN_SOURCE
5 #define _XOPEN_SOURCE 700 /* strndup */
6 #endif
7 #include <stdlib.h>
8 #include <stdio.h>
9 #include <locale.h>
10 #include <stdint.h>
11 #include <stdarg.h>
12 #include <string.h>
14 #include "test-tools.h"
16 char *unit_name, *reason = NULL;
17 unsigned int passed, failed;
18 void (*test_destructor_function)(void *) = NULL;
19 void *test_destructor_argument;
21 #define INIT_TEST(name) { \
22 setlocale(LC_ALL, "C"); \
23 unit_name = name; \
24 passed = failed = 0; \
25 printf("Testing unit: %s\n", unit_name); \
28 #define SUM_TEST() { \
29 printf("Test results: unit = %s, passed = %u, failed = %u\n\n", \
30 unit_name, passed, failed); \
31 exit(failed ? EXIT_FAILURE : EXIT_SUCCESS ); \
34 #define TEST_DESTRUCTOR(function, argument) { \
35 test_destructor_function = function; \
36 test_destructor_argument = argument; \
39 #define PASS_TEST { \
40 if (NULL != test_destructor_function) \
41 test_destructor_function(test_destructor_argument); \
42 return 0; \
43 } \
45 #define FAILURE_REASON(...) { \
46 if (!reason) \
47 test_asprintf(&reason, __VA_ARGS__); \
50 #define FAIL_TEST(...) { \
51 FAILURE_REASON(__VA_ARGS__); \
52 if (NULL != test_destructor_function) \
53 test_destructor_function(test_destructor_argument); \
54 return 1; \
57 #define ABORT_UNIT(message) { \
58 printf("Unit %s procedure aborted: %s\n", unit_name, (message)); \
59 exit(EXIT_FAILURE); \
63 #define TEST(name, function, ...) { \
64 const char *test_message; \
65 free(reason); reason = NULL; \
66 test_destructor_function = NULL; \
67 int status = (function)(__VA_ARGS__); \
68 if (status) { \
69 failed++; \
70 test_message = "failed"; \
71 } else { \
72 passed++; \
73 test_message = "passed"; \
74 } \
75 printf("\t%s: %s\n", (name), test_message); \
76 if (status) printf("\t\treason: %s\n", reason); \
77 free(reason); reason = NULL; \
80 #define TEST_CALLOC(pointer) { \
81 (pointer) = calloc(1, sizeof(*(pointer))); \
82 if (!(pointer)) \
83 ABORT_UNIT("No enough memory"); \
86 #define TEST_FILL_STRING(pointer) { \
87 (pointer) = strdup("DATA"); \
88 if (!(pointer)) \
89 ABORT_UNIT("No enough memory"); \
92 #define TEST_FILL_INT(pointer) { \
93 (pointer) = malloc(sizeof(*(pointer))); \
94 if (!(pointer)) \
95 ABORT_UNIT("No enough memory"); \
96 *(pointer) = 42; \
100 #define STR(x) #x
102 #define TEST_POINTER_DUPLICITY(x, y) { \
103 if (x == NULL && y != NULL) \
104 FAIL_TEST(STR(x) " is NULL, " STR(y) " is not NULL and should be"); \
105 if (x != NULL && y == NULL) \
106 FAIL_TEST(STR(x) " is not NULL, " STR(y) " is NULL and shouldn't be"); \
107 if (x == y && x != NULL) \
108 FAIL_TEST(STR(y) " is the same pointer as " STR(x)); \
111 #define TEST_STRING_DUPLICITY(x, y) { \
112 TEST_POINTER_DUPLICITY(x, y); \
113 if (x != NULL && y != NULL) { \
114 if (strcmp(x, y)) \
115 FAIL_TEST(STR(y) " differs: expected=`%s' is=`%s'", x, y); \
119 #define TEST_INT_DUPLICITY(x, y) { \
120 if ((x) != (y)) \
121 FAIL_TEST(STR(y) " differs: expected=%ld is=%ld", (x), (y)); \
124 #define TEST_INTPTR_DUPLICITY(x, y) { \
125 TEST_POINTER_DUPLICITY(x, y); \
126 if (x != NULL && y != NULL) { \
127 if (*(x) != *(y)) \
128 FAIL_TEST(STR(y) " differs: expected=%ld is=%ld", *(x), *(y)); \
132 #define TEST_BOOLEAN_DUPLICITY(x, y) { \
133 if ((x) != (y)) \
134 FAIL_TEST(STR(y) " differs: expected=%d is=%d", !!(x), !!(y)); \
137 #define TEST_BOOLEANPTR_DUPLICITY(x, y) { \
138 TEST_POINTER_DUPLICITY(x, y); \
139 if (x != NULL && y != NULL) { \
140 if (*(x) != *(y)) \
141 FAIL_TEST(STR(y) " differs: expected=%d is=%d", !!*(x), !!*(y)); \
145 #define TEST_TIMEVALPTR_DUPLICITY(x, y) { \
146 TEST_POINTER_DUPLICITY(x, y); \
147 if ((x) != NULL && (y) != NULL) { \
148 if ((x)->tv_sec != (y)->tv_sec) \
149 FAIL_TEST("struct timeval * differs in tv_sec: " \
150 "expected=%d, got=%d", (x)->tv_sec, (y)->tv_sec); \
151 if ((x)->tv_usec != (y)->tv_usec) \
152 FAIL_TEST("struct timeval * differs in tv_usec: " \
153 "expected=%d, got=%d", (x)->tv_usec, (y)->tv_usec); \
157 #define TEST_TMPTR_DUPLICITY(x, y) { \
158 TEST_POINTER_DUPLICITY(x, y); \
159 if ((x) != NULL && (y) != NULL) { \
160 if ((x)->tm_year != (y)->tm_year) \
161 FAIL_TEST("struct tm * differs in tm_year: " \
162 "expected=%d, got=%d", (x)->tm_year, (y)->tm_year); \
163 if ((x)->tm_mon != (y)->tm_mon) \
164 FAIL_TEST("struct tm * differs in tm_mon: " \
165 "expected=%d, got=%d", (x)->tm_mon, (y)->tm_mon); \
166 if ((x)->tm_mday != (y)->tm_mday) \
167 FAIL_TEST("struct tm * differs in tm_mday: " \
168 "expected=%d, got=%d", (x)->tm_mday, (y)->tm_mday); \
171 #endif