1/* Copyright (C) 2006 MySQL AB
2
3 This program is free software; you can redistribute it and/or modify
4 it under the terms of the GNU General Public License as published by
5 the Free Software Foundation; version 2 of the License.
6
7 This program is distributed in the hope that it will be useful,
8 but WITHOUT ANY WARRANTY; without even the implied warranty of
9 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 GNU General Public License for more details.
11
12 You should have received a copy of the GNU General Public License
13 along with this program; if not, write to the Free Software
14 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
15 MA 02111-1301, USA
16
17 Library for providing TAP support for testing C and C++ was written
18 by Mats Kindahl <mats@mysql.com>.
19*/
20
21#ifndef TAP_H
22#define TAP_H
23
24#include "ma_global.h"
25
26/*
27 @defgroup MyTAP MySQL support for performing unit tests according to
28 the Test Anything Protocol (TAP).
29*/
30
31#define NO_PLAN (0)
32
33/**
34 Data about test plan.
35
36 @ingroup MyTAP_Internal
37
38 @internal We are using the "typedef struct X { ... } X" idiom to
39 create class/struct X both in C and C++.
40 */
41
42typedef struct TEST_DATA {
43 /**
44 Number of tests that is planned to execute.
45
46 Can be zero (<code>NO_PLAN</code>) meaning that the plan string
47 will be printed at the end of test instead.
48 */
49 int plan;
50
51 /** Number of last test that was done or skipped. */
52 int last;
53
54 /** Number of tests that failed. */
55 int failed;
56
57 /** Todo reason. */
58 char todo[128];
59} TEST_DATA;
60
61#ifdef __cplusplus
62extern "C" {
63#endif
64
65/**
66 Defines whether "big" tests should be skipped.
67
68 This variable is set by plan() function unless MYTAP_CONFIG environment
69 variable is set to the string "big". It is supposed to be used as
70
71 @code
72 if (skip_big_tests) {
73 skip(1, "Big test skipped");
74 } else {
75 ok(life_universe_and_everything() == 42, "The answer is CORRECT");
76 }
77 @endcode
78
79 @see SKIP_BIG_TESTS
80*/
81extern int skip_big_tests;
82
83/**
84 @defgroup MyTAP_API MyTAP API
85
86 MySQL support for performing unit tests according to TAP.
87
88 @{
89*/
90
91/**
92 Set number of tests that is planned to execute.
93
94 The function also accepts the predefined constant
95 <code>NO_PLAN</code>. If the function is not called, it is as if
96 it was called with <code>NO_PLAN</code>, i.e., the test plan will
97 be printed after all the test lines.
98
99 The plan() function will install signal handlers for all signals
100 that generate a core, so if you want to override these signals, do
101 it <em>after</em> you have called the plan() function.
102
103 It will also set skip_big_tests variable if MYTAP_CONFIG environment
104 variable is defined.
105
106 @see skip_big_tests
107
108 @param count The planned number of tests to run.
109*/
110
111void plan(int const count);
112
113
114/**
115 Report test result as a TAP line.
116
117 Function used to write status of an individual test. Call this
118 function in the following manner:
119
120 @code
121 ok(ducks == paddling,
122 "%d ducks did not paddle", ducks - paddling);
123 @endcode
124
125 @param pass Zero if the test failed, non-zero if it passed.
126 @param fmt Format string in printf() format. NULL is allowed, in
127 which case nothing is printed.
128*/
129
130void ok(int const pass, char const *fmt, ...)
131 __attribute__((format(printf,2,3)));
132
133
134/**
135 Skip a determined number of tests.
136
137 Function to print that <em>how_many</em> tests have been skipped.
138 The reason is printed for each skipped test. Observe that this
139 function does not do the actual skipping for you, it just prints
140 information that tests have been skipped. This function is not
141 usually used, but rather the macro @c SKIP_BLOCK_IF, which does the
142 skipping for you.
143
144 It shall be used in the following manner:
145
146 @code
147 if (ducks == 0) {
148 skip(2, "No ducks in the pond");
149 } else {
150 int i;
151 for (i = 0 ; i < 2 ; ++i)
152 ok(duck[i] == paddling, "is duck %d paddling?", i);
153 }
154 @endcode
155
156 @see SKIP_BLOCK_IF
157
158 @param how_many Number of tests that are to be skipped.
159 @param reason A reason for skipping the tests
160 */
161
162void skip(int how_many, char const *const reason, ...)
163 __attribute__((format(printf,2,3)));
164
165
166/**
167 Helper macro to skip a block of code. The macro can be used to
168 simplify conditionally skipping a block of code. It is used in the
169 following manner:
170
171 @code
172 SKIP_BLOCK_IF(ducks == 0, 2, "No ducks in the pond")
173 {
174 int i;
175 for (i = 0 ; i < 2 ; ++i)
176 ok(duck[i] == paddling, "is duck %d paddling?", i);
177 }
178 @endcode
179
180 @see skip
181 */
182
183#define SKIP_BLOCK_IF(SKIP_IF_TRUE, COUNT, REASON) \
184 if (SKIP_IF_TRUE) skip((COUNT),(REASON)); else
185
186
187/**
188 Helper macro to skip a group of "big" tests. It is used in the following
189 manner:
190
191 @code
192 SKIP_BIG_TESTS(1)
193 {
194 ok(life_universe_and_everything() == 42, "The answer is CORRECT");
195 }
196 @endcode
197
198 @see skip_big_tests
199 */
200
201#define SKIP_BIG_TESTS(COUNT) \
202 if (skip_big_tests) skip((COUNT), "big test"); else
203
204
205/**
206 Print a diagnostics message.
207
208 @param fmt Diagnostics message in printf() format.
209 */
210
211void diag(char const *fmt, ...)
212 __attribute__((format(printf,1,2)));
213
214
215/**
216 Print a bail out message.
217
218 A bail out message can be issued when no further testing can be
219 done, e.g., when there are missing dependencies.
220
221 The test will exit with status 255. This function does not return.
222
223 @code
224 BAIL_OUT("Lost connection to server %s", server_name);
225 @endcode
226
227 @note A bail out message is printed if a signal that generates a
228 core is raised.
229
230 @param fmt Bail out message in printf() format.
231*/
232
233void BAIL_OUT(char const *fmt, ...)
234 __attribute__((noreturn, format(printf,1,2)));
235
236
237/**
238 Print summary report and return exit status.
239
240 This function will print a summary report of how many tests passed,
241 how many were skipped, and how many remains to do. The function
242 should be called after all tests are executed in the following
243 manner:
244
245 @code
246 return exit_status();
247 @endcode
248
249 @returns @c EXIT_SUCCESS if all tests passed, @c EXIT_FAILURE if
250 one or more tests failed.
251 */
252
253int exit_status(void);
254
255
256/**
257 Skip entire test suite.
258
259 To skip the entire test suite, use this function. It will
260 automatically call exit(), so there is no need to have checks
261 around it.
262 */
263
264void skip_all(char const *reason, ...)
265 __attribute__((noreturn, format(printf, 1, 2)));
266
267
268/**
269 Start section of tests that are not yet ready.
270
271 To start a section of tests that are not ready and are expected to
272 fail, use this function and todo_end() in the following manner:
273
274 @code
275 todo_start("Not ready yet");
276 ok(is_rocketeering(duck), "Rocket-propelled ducks");
277 ok(is_kamikaze(duck), "Kamikaze ducks");
278 todo_end();
279 @endcode
280
281 @see todo_end
282
283 @note
284 It is not possible to nest todo sections.
285
286 @param message Message that will be printed before the todo tests.
287*/
288
289void todo_start(char const *message, ...)
290 __attribute__((format(printf, 1, 2)));
291
292
293/**
294 End a section of tests that are not yet ready.
295*/
296
297void todo_end();
298
299/** @} */
300
301#ifdef __cplusplus
302}
303#endif
304
305#endif /* TAP_H */
306