1 /*
2  * Copyright (c) Vicent Marti. All rights reserved.
3  *
4  * This file is part of clar, distributed under the ISC license.
5  * For full terms see the included COPYING file.
6  */
7 #ifndef __CLAR_TEST_H__
8 #define __CLAR_TEST_H__
9 
10 #include <stdlib.h>
11 
12 enum cl_test_status {
13 	CL_TEST_OK,
14 	CL_TEST_FAILURE,
15 	CL_TEST_SKIP,
16 	CL_TEST_NOTRUN,
17 };
18 
19 enum cl_output_format {
20 	CL_OUTPUT_CLAP,
21 	CL_OUTPUT_TAP,
22 };
23 
24 /** Setup clar environment */
25 void clar_test_init(int argc, char *argv[]);
26 int clar_test_run(void);
27 void clar_test_shutdown(void);
28 
29 /** One shot setup & run */
30 int clar_test(int argc, char *argv[]);
31 
32 const char *clar_sandbox_path(void);
33 
34 void cl_set_cleanup(void (*cleanup)(void *), void *opaque);
35 void cl_fs_cleanup(void);
36 
37 /**
38  * cl_trace_* is a hook to provide a simple global tracing
39  * mechanism.
40  *
41  * The goal here is to let main() provide clar-proper
42  * with a callback to optionally write log info for
43  * test operations into the same stream used by their
44  * actual tests.  This would let them print test names
45  * and maybe performance data as they choose.
46  *
47  * The goal is NOT to alter the flow of control or to
48  * override test selection/skipping.  (So the callback
49  * does not return a value.)
50  *
51  * The goal is NOT to duplicate the existing
52  * pass/fail/skip reporting.  (So the callback
53  * does not accept a status/errorcode argument.)
54  *
55  */
56 typedef enum cl_trace_event {
57 	CL_TRACE__SUITE_BEGIN,
58 	CL_TRACE__SUITE_END,
59 	CL_TRACE__TEST__BEGIN,
60 	CL_TRACE__TEST__END,
61 	CL_TRACE__TEST__RUN_BEGIN,
62 	CL_TRACE__TEST__RUN_END,
63 	CL_TRACE__TEST__LONGJMP,
64 } cl_trace_event;
65 
66 typedef void (cl_trace_cb)(
67 	cl_trace_event ev,
68 	const char *suite_name,
69 	const char *test_name,
70 	void *payload);
71 
72 /**
73  * Register a callback into CLAR to send global trace events.
74  * Pass NULL to disable.
75  */
76 void cl_trace_register(cl_trace_cb *cb, void *payload);
77 
78 
79 #ifdef CLAR_FIXTURE_PATH
80 const char *cl_fixture(const char *fixture_name);
81 void cl_fixture_sandbox(const char *fixture_name);
82 void cl_fixture_cleanup(const char *fixture_name);
83 const char *cl_fixture_basename(const char *fixture_name);
84 #endif
85 
86 /**
87  * Assertion macros with explicit error message
88  */
89 #define cl_must_pass_(expr, desc) clar__assert((expr) >= 0, __FILE__, __func__, __LINE__, "Function call failed: " #expr, desc, 1)
90 #define cl_must_fail_(expr, desc) clar__assert((expr) < 0, __FILE__, __func__, __LINE__, "Expected function call to fail: " #expr, desc, 1)
91 #define cl_assert_(expr, desc) clar__assert((expr) != 0, __FILE__, __func__, __LINE__, "Expression is not true: " #expr, desc, 1)
92 
93 /**
94  * Check macros with explicit error message
95  */
96 #define cl_check_pass_(expr, desc) clar__assert((expr) >= 0, __FILE__, __func__, __LINE__, "Function call failed: " #expr, desc, 0)
97 #define cl_check_fail_(expr, desc) clar__assert((expr) < 0, __FILE__, __func__, __LINE__, "Expected function call to fail: " #expr, desc, 0)
98 #define cl_check_(expr, desc) clar__assert((expr) != 0, __FILE__, __func__, __LINE__, "Expression is not true: " #expr, desc, 0)
99 
100 /**
101  * Assertion macros with no error message
102  */
103 #define cl_must_pass(expr) cl_must_pass_(expr, NULL)
104 #define cl_must_fail(expr) cl_must_fail_(expr, NULL)
105 #define cl_assert(expr) cl_assert_(expr, NULL)
106 
107 /**
108  * Check macros with no error message
109  */
110 #define cl_check_pass(expr) cl_check_pass_(expr, NULL)
111 #define cl_check_fail(expr) cl_check_fail_(expr, NULL)
112 #define cl_check(expr) cl_check_(expr, NULL)
113 
114 /**
115  * Forced failure/warning
116  */
117 #define cl_fail(desc) clar__fail(__FILE__, __func__, __LINE__, "Test failed.", desc, 1)
118 #define cl_warning(desc) clar__fail(__FILE__, __func__, __LINE__, "Warning during test execution:", desc, 0)
119 
120 #define cl_skip() clar__skip()
121 
122 /**
123  * Typed assertion macros
124  */
125 #define cl_assert_equal_s(s1,s2) clar__assert_equal(__FILE__,__func__,__LINE__,"String mismatch: " #s1 " != " #s2, 1, "%s", (s1), (s2))
126 #define cl_assert_equal_s_(s1,s2,note) clar__assert_equal(__FILE__,__func__,__LINE__,"String mismatch: " #s1 " != " #s2 " (" #note ")", 1, "%s", (s1), (s2))
127 
128 #define cl_assert_equal_wcs(wcs1,wcs2) clar__assert_equal(__FILE__,__func__,__LINE__,"String mismatch: " #wcs1 " != " #wcs2, 1, "%ls", (wcs1), (wcs2))
129 #define cl_assert_equal_wcs_(wcs1,wcs2,note) clar__assert_equal(__FILE__,__func__,__LINE__,"String mismatch: " #wcs1 " != " #wcs2 " (" #note ")", 1, "%ls", (wcs1), (wcs2))
130 
131 #define cl_assert_equal_strn(s1,s2,len) clar__assert_equal(__FILE__,__func__,__LINE__,"String mismatch: " #s1 " != " #s2, 1, "%.*s", (s1), (s2), (int)(len))
132 #define cl_assert_equal_strn_(s1,s2,len,note) clar__assert_equal(__FILE__,__func__,__LINE__,"String mismatch: " #s1 " != " #s2 " (" #note ")", 1, "%.*s", (s1), (s2), (int)(len))
133 
134 #define cl_assert_equal_wcsn(wcs1,wcs2,len) clar__assert_equal(__FILE__,__func__,__LINE__,"String mismatch: " #wcs1 " != " #wcs2, 1, "%.*ls", (wcs1), (wcs2), (int)(len))
135 #define cl_assert_equal_wcsn_(wcs1,wcs2,len,note) clar__assert_equal(__FILE__,__func__,__LINE__,"String mismatch: " #wcs1 " != " #wcs2 " (" #note ")", 1, "%.*ls", (wcs1), (wcs2), (int)(len))
136 
137 #define cl_assert_equal_i(i1,i2) clar__assert_equal(__FILE__,__func__,__LINE__,#i1 " != " #i2, 1, "%d", (int)(i1), (int)(i2))
138 #define cl_assert_equal_i_(i1,i2,note) clar__assert_equal(__FILE__,__func__,__LINE__,#i1 " != " #i2 " (" #note ")", 1, "%d", (i1), (i2))
139 #define cl_assert_equal_i_fmt(i1,i2,fmt) clar__assert_equal(__FILE__,__func__,__LINE__,#i1 " != " #i2, 1, (fmt), (int)(i1), (int)(i2))
140 
141 #define cl_assert_equal_b(b1,b2) clar__assert_equal(__FILE__,__func__,__LINE__,#b1 " != " #b2, 1, "%d", (int)((b1) != 0),(int)((b2) != 0))
142 
143 #define cl_assert_equal_p(p1,p2) clar__assert_equal(__FILE__,__func__,__LINE__,"Pointer mismatch: " #p1 " != " #p2, 1, "%p", (p1), (p2))
144 
145 void clar__skip(void);
146 
147 void clar__fail(
148 	const char *file,
149 	const char *func,
150 	size_t line,
151 	const char *error,
152 	const char *description,
153 	int should_abort);
154 
155 void clar__assert(
156 	int condition,
157 	const char *file,
158 	const char *func,
159 	size_t line,
160 	const char *error,
161 	const char *description,
162 	int should_abort);
163 
164 void clar__assert_equal(
165 	const char *file,
166 	const char *func,
167 	size_t line,
168 	const char *err,
169 	int should_abort,
170 	const char *fmt,
171 	...);
172 
173 #endif
174