Commit | Line | Data |
---|---|---|
1479465f GJ |
1 | /* |
2 | * libdpkg - Debian packaging suite library routines | |
3 | * test.h - test suite support | |
4 | * | |
5 | * Copyright © 2009-2014 Guillem Jover <guillem@debian.org> | |
6 | * | |
7 | * This is free software; you can redistribute it and/or modify | |
8 | * it under the terms of the GNU General Public License as published by | |
9 | * the Free Software Foundation; either version 2 of the License, or | |
10 | * (at your option) any later version. | |
11 | * | |
12 | * This is distributed in the hope that it will be useful, | |
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
15 | * GNU General Public License for more details. | |
16 | * | |
17 | * You should have received a copy of the GNU General Public License | |
18 | * along with this program. If not, see <https://www.gnu.org/licenses/>. | |
19 | */ | |
20 | ||
21 | #ifndef LIBDPKG_TEST_H | |
22 | #define LIBDPKG_TEST_H | |
23 | ||
24 | #include <string.h> | |
25 | #include <stdlib.h> | |
26 | #include <stdio.h> | |
27 | ||
28 | #ifndef TEST_MAIN_CTOR | |
29 | #include <dpkg/ehandle.h> | |
30 | #define TEST_MAIN_CTOR push_error_context() | |
31 | #define TEST_MAIN_DTOR pop_error_context(ehflag_normaltidy) | |
32 | #endif | |
33 | ||
34 | /** | |
35 | * @defgroup dpkg_test Test suite support | |
36 | * @ingroup dpkg-internal | |
37 | * @{ | |
38 | */ | |
39 | ||
40 | #define test_bail(reason) \ | |
41 | do { \ | |
42 | printf("Bail out! %s\n", (reason)); \ | |
43 | exit(255); \ | |
44 | } while (0) | |
45 | ||
46 | #define test_xstringify(str) \ | |
47 | #str | |
48 | #define test_stringify(str) \ | |
49 | test_xstringify(str) | |
50 | ||
51 | static inline void * | |
52 | test_alloc(void *ptr, const char *reason) | |
53 | { | |
54 | if (ptr == NULL) | |
55 | test_bail(reason); | |
56 | return ptr; | |
57 | } | |
58 | ||
59 | #define test_alloc(ptr) \ | |
60 | test_alloc((ptr), "cannot allocate memory for " #ptr " in " __FILE__ ":" test_stringify(__LINE__)) | |
61 | ||
62 | static int test_id = 1; | |
63 | static int test_skip_code; | |
64 | static const char *test_skip_prefix; | |
65 | static const char *test_skip_reason; | |
66 | ||
67 | #define test_plan(n) \ | |
68 | printf("1..%d\n", n); | |
69 | ||
70 | #define test_skip_all(reason) \ | |
71 | do { \ | |
72 | printf("1..0 # SKIP %s\n", (reason)); \ | |
73 | exit(0); \ | |
74 | } while (0) | |
75 | #define test_skip(reason) \ | |
76 | printf("ok %d # SKIP %s\n", test_id++, (reason)) | |
77 | #define test_skip_block(cond) \ | |
78 | for (test_skip_prefix = " # SKIP ", \ | |
79 | test_skip_reason = cond ? #cond : NULL, \ | |
80 | test_skip_code = 1; \ | |
81 | test_skip_prefix; \ | |
82 | test_skip_prefix = test_skip_reason = NULL, test_skip_code = 0) | |
83 | ||
84 | #define test_todo(a, reason, desc) \ | |
85 | do { \ | |
86 | test_skip_prefix = " # TODO "; \ | |
87 | test_skip_reason = reason; \ | |
88 | test_case(a, "%s", desc); \ | |
89 | test_skip_prefix = test_skip_reason = NULL; \ | |
90 | } while(0) | |
91 | #define test_todo_block(reason) \ | |
92 | for (test_skip_prefix = " # TODO ", test_skip_reason = reason; \ | |
93 | test_skip_prefix; \ | |
94 | test_skip_prefix = test_skip_reason = NULL) | |
95 | ||
96 | #define test_case(a, fmt, ...) \ | |
97 | printf("%sok %d - " fmt "%s%s\n", \ | |
98 | test_skip_code || (a) ? "" : "not ", \ | |
99 | test_id++, __VA_ARGS__, \ | |
100 | test_skip_reason ? test_skip_prefix : "", \ | |
101 | test_skip_reason ? test_skip_reason : "") | |
102 | ||
103 | #define test_pass(a) \ | |
104 | test_case((a), "pass %s", #a) | |
105 | #define test_fail(a) \ | |
106 | test_case(!(a), "fail %s", #a) | |
107 | #define test_str(a, op, b) \ | |
108 | test_case(strcmp((a), (b)) op 0, "strcmp '%s' %s '%s'", a, #op, b) | |
109 | #define test_mem(a, op, b, size) \ | |
110 | test_case(memcmp((a), (b), (size)) op 0, "memcmp %p %s %p", a, #op, b) | |
111 | ||
112 | /* Specific test macros. */ | |
113 | #define test_warn(e) \ | |
114 | do { \ | |
115 | test_pass((e).type == DPKG_MSG_WARN); \ | |
116 | dpkg_error_destroy(&(e)); \ | |
117 | } while (0) | |
118 | #define test_error(e) \ | |
119 | do { \ | |
120 | test_pass((e).type == DPKG_MSG_ERROR); \ | |
121 | dpkg_error_destroy(&(e)); \ | |
122 | } while (0) | |
123 | ||
124 | /** @} */ | |
125 | ||
126 | #define TEST_ENTRY(name) \ | |
127 | static void name(void); \ | |
128 | int \ | |
129 | main(int argc, char **argv) \ | |
130 | { \ | |
131 | setvbuf(stdout, NULL, _IOLBF, 0); \ | |
132 | \ | |
133 | TEST_MAIN_CTOR; \ | |
134 | name(); \ | |
135 | TEST_MAIN_DTOR; \ | |
136 | return 0; \ | |
137 | } \ | |
138 | static void \ | |
139 | name(void) | |
140 | ||
141 | #endif |