1/*
2 * Copyright (c) 2005-2007,2012-2014 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 <inttypes.h>
31#include <string.h>
32#include <stdio.h>
33#include <CoreFoundation/CFString.h>
34
35__BEGIN_DECLS
36
37/* Macros to be used in testlist.h style headers. */
38#define ONE_TEST(x) int x(int argc, char *const *argv);
39#define DISABLED_ONE_TEST(x) ONE_TEST(x)
40#define OFF_ONE_TEST(x) ONE_TEST(x)
41
42typedef int (*one_test_entry)(int argc, char *const *argv);
43
44#define ONE_TEST_ENTRY(x) int x(int argc, char *const *argv)
45
46struct one_test_s {
47    char *name;            /* test name */
48    one_test_entry entry;  /* entry point */
49    int off;               /* off by default */
50    int sub_tests;         /* number of subtests */
51    int failed_tests;      /* number of failed tests*/
52    unsigned long duration; /* test duration in msecs */
53    /* add more later: timing, etc... */
54};
55
56extern struct one_test_s testlist[];
57
58int run_one_test(struct one_test_s *test, int argc, char * const *argv);
59
60/* this test harnes rely on shadowing for TODO, SKIP and SETUP blocks */
61#pragma GCC diagnostic ignored "-Wshadow"
62
63#define test_create_description(TESTNAME, ...) \
64    CFStringCreateWithFormat(NULL, NULL, CFSTR(TESTNAME), ## __VA_ARGS__)
65
66#define ok(THIS, ...) \
67({ \
68    bool is_ok = !!(THIS); \
69    test_ok(is_ok, test_create_description(__VA_ARGS__), test_directive, \
70        test_reason, __FILE__, __LINE__, NULL); \
71})
72#define is(THIS, THAT, ...) \
73({ \
74    __typeof__(THIS) _this = (THIS); \
75    __typeof__(THAT) _that = (THAT); \
76    test_ok((_this == _that), test_create_description(__VA_ARGS__), \
77        test_directive, test_reason, __FILE__, __LINE__, \
78		"#          got: '%d'\n" \
79		"#     expected: '%d'\n", \
80		_this, _that); \
81})
82#define isnt(THIS, THAT, ...) \
83	cmp_ok((THIS), !=, (THAT), __VA_ARGS__)
84#define diag(MSG, ARGS...) \
85	test_diag(test_directive, test_reason, __FILE__, __LINE__, MSG, ## ARGS)
86#define cmp_ok(THIS, OP, THAT, ...) \
87({ \
88	__typeof__(THIS) _this = (THIS); \
89	__typeof__(THAT) _that = (THAT); \
90	test_ok((_this OP _that), test_create_description(__VA_ARGS__), \
91        test_directive, test_reason, __FILE__, __LINE__, \
92	   "#     '%d'\n" \
93	   "#         " #OP "\n" \
94	   "#     '%d'\n", \
95	   _this, _that); \
96})
97#define eq_string(THIS, THAT, ...) \
98({ \
99	const char *_this = (THIS); \
100	const char *_that = (THAT); \
101	test_ok(!strcmp(_this, _that), test_create_description(__VA_ARGS__), \
102        test_directive, test_reason, __FILE__, __LINE__, \
103	   "#     '%s'\n" \
104	   "#         eq\n" \
105	   "#     '%s'\n", \
106	   _this, _that); \
107})
108#define eq_stringn(THIS, THISLEN, THAT, THATLEN, ...) \
109({ \
110	__typeof__(THISLEN) _thislen = (THISLEN); \
111	__typeof__(THATLEN) _thatlen = (THATLEN); \
112	const char *_this = (THIS); \
113	const char *_that = (THAT); \
114	test_ok(_thislen == _thatlen && !strncmp(_this, _that, _thislen), \
115		test_create_description(__VA_ARGS__), test_directive, test_reason, \
116		__FILE__, __LINE__, \
117	   "#     '%.*s'\n" \
118	   "#         eq\n" \
119	   "#     '%.*s'\n", \
120	   (int)_thislen, _this, (int)_thatlen, _that); \
121})
122#define eq_cf(THIS, THAT, ...) \
123({ \
124    CFTypeRef _this = (THIS); \
125    CFTypeRef _that = (THAT); \
126    test_ok(CFEqualSafe(_this, _that), test_create_description(__VA_ARGS__), test_directive, test_reason, \
127    __FILE__, __LINE__, \
128    "#     '%@'\n" \
129    "#      eq\n" \
130    "#     '%@'\n", \
131    _this, _that); \
132})
133
134#define like(THIS, REGEXP, ...) like_not_yet_implemented()
135#define unlike(THIS, REGEXP, ...) unlike_not_yet_implemented()
136#define is_deeply(STRUCT1, STRUCT2, ...) is_deeply_not_yet_implemented()
137#define TODO switch(0) default
138#define SKIP switch(0) default
139#define SETUP switch(0) default
140#define todo(REASON) const char *test_directive __attribute__((unused)) = "TODO", \
141	*test_reason __attribute__((unused)) = (REASON)
142#define skip(WHY, HOW_MANY, UNLESS) if (!(UNLESS)) \
143    { test_skip((WHY), (HOW_MANY), 0); break; }
144#define setup(REASON) const char *test_directive = "SETUP", \
145	*test_reason = (REASON)
146#define pass(...) ok(1, __VA_ARGS__)
147#define fail(...) ok(0, __VA_ARGS__)
148#define BAIL_OUT(WHY) test_bail_out(WHY, __FILE__, __LINE__)
149#define plan_skip_all(REASON) test_plan_skip_all(REASON)
150#define plan_tests(COUNT) test_plan_tests(COUNT, __FILE__, __LINE__)
151
152#define ok_status(THIS, ...) \
153({ \
154	OSStatus _this = (THIS); \
155	test_ok(!_this, test_create_description(__VA_ARGS__), \
156        test_directive, test_reason, __FILE__, __LINE__, \
157	   "#     status: %s(%" PRId32 ")\n", \
158	   sec_errstr(_this), _this); \
159})
160#define is_status(THIS, THAT, ...) \
161({ \
162    OSStatus _this = (THIS); \
163    OSStatus _that = (THAT); \
164    test_ok(_this == _that, test_create_description(__VA_ARGS__), \
165        test_directive, test_reason, __FILE__, __LINE__, \
166	   "#          got: %s(%" PRId32 ")\n" \
167	   "#     expected: %s(%" PRId32 ")\n", \
168	   sec_errstr(_this), _this, sec_errstr(_that), _that); \
169})
170#define ok_unix(THIS, ...) \
171({ \
172    int _this = (THIS) < 0 ? errno : 0; \
173    test_ok(!_this, test_create_description(__VA_ARGS__), \
174        test_directive, test_reason, __FILE__, __LINE__, \
175	   "#          got: %s(%d)\n", \
176	   strerror(_this), _this); \
177})
178#define is_unix(THIS, THAT, ...) \
179({ \
180    int _result = (THIS); \
181    int _this = _result < 0 ? errno : 0; \
182    int _that = (THAT); \
183    _that && _result < 0 \
184	? test_ok(_this == _that, test_create_description(__VA_ARGS__), \
185        test_directive, test_reason, __FILE__, __LINE__, \
186		"#          got: %s(%d)\n" \
187		"#     expected: %s(%d)\n", \
188		strerror(_this), _this, strerror(_that), _that) \
189	: test_ok(_this == _that, test_create_description(__VA_ARGS__), \
190        test_directive, test_reason, __FILE__, __LINE__, \
191		"#            got: %d\n" \
192		"# expected errno: %s(%d)\n", \
193		_result, strerror(_that), _that); \
194})
195
196
197extern const char *test_directive;
198extern const char *test_reason;
199
200void test_bail_out(const char *reason, const char *file, unsigned line);
201int test_diag(const char *directive, const char *reason,
202	const char *file, unsigned line, const char *fmt, ...);
203int test_ok(int passed, __attribute((cf_consumed)) CFStringRef description, const char *directive,
204	const char *reason, const char *file, unsigned line, const char *fmt, ...);
205void test_plan_skip_all(const char *reason);
206void test_plan_tests(int count, const char *file, unsigned line);
207void test_skip(const char *reason, int how_many, int unless);
208
209const char *sec_errstr(int err);
210
211__END_DECLS
212
213#endif /* !_TESTMORE_H_ */
214