1/*
2 * Copyright (c) 2005-2007 Apple Inc. All Rights Reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. Please obtain a copy of the License at
10 * http://www.opensource.apple.com/apsl/ and read it before using this
11 * file.
12 *
13 * The Original Code and all software distributed under the License are
14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
18 * Please see the License for the specific language governing rights and
19 * limitations under the License.
20 *
21 * @APPLE_LICENSE_HEADER_END@
22 *
23 * testmore.h
24 */
25
26#ifndef _TESTMORE_H_
27#define _TESTMORE_H_  1
28
29#include <errno.h>
30#include <string.h>
31#include <stdio.h>
32
33#ifdef __cplusplus
34extern "C" {
35#endif
36
37/* This is included here, because its already included by all the test case */
38#include "testlist.h"
39
40typedef int (*one_test_entry)(int argc, char *const *argv);
41
42#define ONE_TEST_ENTRY(x) int x(int argc, char *const *argv)
43
44struct one_test_s {
45    char *name;            /* test name */
46    one_test_entry entry;  /* entry point */
47    int sub_tests;         /* number of subtests */
48    int failed_tests;      /* number of failed tests*/
49    unsigned int duration; /* test duration in msecs */
50    /* add more later: timing, etc... */
51};
52
53extern struct one_test_s testlist[];
54
55int run_one_test(struct one_test_s *test, int argc, char * const *argv);
56
57/* this test harnes rely on shadowing for TODO, SKIP and SETUP blocks */
58#pragma GCC diagnostic ignored "-Wshadow"
59
60#define ok(THIS, TESTNAME) \
61    test_ok(!!(THIS), TESTNAME, test_directive, test_reason, \
62		__FILE__, __LINE__, NULL)
63#define is(THIS, THAT, TESTNAME) \
64({ \
65    __typeof__(THIS) _this = (THIS); \
66    __typeof__(THAT) _that = (THAT); \
67    test_ok((_this == _that), TESTNAME, test_directive, test_reason, \
68		__FILE__, __LINE__, \
69		"#          got: '%d'\n" \
70		"#     expected: '%d'\n", \
71		_this, _that); \
72})
73#define isnt(THIS, THAT, TESTNAME) \
74	cmp_ok((THIS), !=, (THAT), (TESTNAME))
75#define diag(MSG, ARGS...) \
76	test_diag(test_directive, test_reason, __FILE__, __LINE__, MSG, ## ARGS)
77#define cmp_ok(THIS, OP, THAT, TESTNAME) \
78({ \
79	__typeof__(THIS) _this = (THIS); \
80	__typeof__(THAT) _that = (THAT); \
81	test_ok((_this OP _that), TESTNAME, test_directive, test_reason, \
82		__FILE__, __LINE__, \
83	   "#     '%d'\n" \
84	   "#         " #OP "\n" \
85	   "#     '%d'\n", \
86	   _this, _that); \
87})
88#define eq_string(THIS, THAT, TESTNAME) \
89({ \
90	const char *_this = (THIS); \
91	const char *_that = (THAT); \
92	test_ok(!strcmp(_this, _that), TESTNAME, test_directive, test_reason, \
93		__FILE__, __LINE__, \
94	   "#     '%s'\n" \
95	   "#         eq\n" \
96	   "#     '%s'\n", \
97	   _this, _that); \
98})
99#define eq_stringn(THIS, THISLEN, THAT, THATLEN, TESTNAME) \
100({ \
101	__typeof__(THISLEN) _thislen = (THISLEN); \
102	__typeof__(THATLEN) _thatlen = (THATLEN); \
103	const char *_this = (THIS); \
104	const char *_that = (THAT); \
105	test_ok(_thislen == _thatlen && !strncmp(_this, _that, _thislen), \
106		TESTNAME, test_directive, test_reason, \
107		__FILE__, __LINE__, \
108	   "#     '%.*s'\n" \
109	   "#         eq\n" \
110	   "#     '%.*s'\n", \
111	   (int)_thislen, _this, (int)_thatlen, _that); \
112})
113#define like(THIS, REGEXP, TESTNAME) like_not_yet_implemented()
114#define unlike(THIS, REGEXP, TESTNAME) unlike_not_yet_implemented()
115#define is_deeply(STRUCT1, STRUCT2, TESTNAME) is_deeply_not_yet_implemented()
116#define TODO switch(0) default
117#define SKIP switch(0) default
118#define SETUP switch(0) default
119#define todo(REASON) const char *test_directive __attribute__((unused)) = "TODO", \
120	*test_reason __attribute__((unused)) = (REASON)
121#define skip(WHY, HOW_MANY, UNLESS) if (!(UNLESS)) \
122    { test_skip((WHY), (HOW_MANY), 0); break; }
123#define setup(REASON) const char *test_directive = "SETUP", \
124	*test_reason = (REASON)
125#define pass(TESTNAME) ok(1, (TESTNAME))
126#define fail(TESTNAME) ok(0, (TESTNAME))
127#define BAIL_OUT(WHY) test_bail_out(WHY, __FILE__, __LINE__)
128#define plan_skip_all(REASON) test_plan_skip_all(REASON)
129#define plan_tests(COUNT) test_plan_tests(COUNT, __FILE__, __LINE__)
130
131#define ok_status(THIS, TESTNAME) \
132({ \
133	OSStatus _this = (THIS); \
134	test_ok(!_this, TESTNAME, test_directive, test_reason, \
135		__FILE__, __LINE__, \
136	   "#     status: %s(%ld)\n", \
137	   sec_errstr(_this), _this); \
138})
139#define is_status(THIS, THAT, TESTNAME) \
140({ \
141    OSStatus _this = (THIS); \
142    OSStatus _that = (THAT); \
143    test_ok(_this == _that, TESTNAME, test_directive, test_reason, \
144		__FILE__, __LINE__, \
145	   "#          got: %s(%ld)\n" \
146	   "#     expected: %s(%ld)\n", \
147	   sec_errstr(_this), _this, sec_errstr(_that), _that); \
148})
149#define ok_unix(THIS, TESTNAME) \
150({ \
151    int _this = (THIS) < 0 ? errno : 0; \
152    test_ok(!_this, TESTNAME, test_directive, test_reason, \
153		__FILE__, __LINE__, \
154	   "#          got: %s(%d)\n", \
155	   strerror(_this), _this); \
156})
157#define is_unix(THIS, THAT, TESTNAME) \
158({ \
159    int _result = (THIS); \
160    int _this = _result < 0 ? errno : 0; \
161    int _that = (THAT); \
162    _that && _result < 0 \
163	? test_ok(_this == _that, TESTNAME, test_directive, test_reason, \
164		__FILE__, __LINE__, \
165		"#          got: %s(%d)\n" \
166		"#     expected: %s(%d)\n", \
167		strerror(_this), _this, strerror(_that), _that) \
168	: test_ok(_this == _that, TESTNAME, test_directive, test_reason, \
169		__FILE__, __LINE__, \
170		"#            got: %d\n" \
171		"# expected errno: %s(%d)\n", \
172		_result, strerror(_that), _that); \
173})
174
175
176extern const char *test_directive;
177extern const char *test_reason;
178
179void test_bail_out(const char *reason, const char *file, unsigned line);
180int test_diag(const char *directive, const char *reason,
181	const char *file, unsigned line, const char *fmt, ...);
182int test_ok(int passed, const char *description, const char *directive,
183	const char *reason, const char *file, unsigned line, const char *fmt, ...);
184void test_plan_skip_all(const char *reason);
185void test_plan_tests(int count, const char *file, unsigned line);
186void test_skip(const char *reason, int how_many, int unless);
187
188const char *sec_errstr(int err);
189
190#ifdef __cplusplus
191}
192#endif /* __cplusplus */
193
194#endif /* !_TESTMORE_H_ */
195