1 /*
2  * Copyright 2017 Patrick O. Perry.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #ifndef TESTUTIL_H
18 #define TESTUTIL_H
19 
20 #include <check.h>
21 #include <stddef.h>
22 #include <stdint.h>
23 
24 struct utf8lite_text;
25 
26 /**
27  * This macro is broken on the old version of check (0.9.8) that Travis CI
28  * uses, so we re-define it.
29  */
30 #ifdef ck_assert_int_eq
31 #  undef ck_assert_int_eq
32 #endif
33 #define ck_assert_int_eq(X, Y) do { \
34 	intmax_t _ck_x = (X); \
35 	intmax_t _ck_y = (Y); \
36 	ck_assert_msg(_ck_x == _ck_y, \
37 			"Assertion '%s' failed: %s == %jd, %s == %jd", \
38 			#X " == " #Y, #X, _ck_x, #Y, _ck_y); \
39 } while (0)
40 
41 
42 /**
43  * This macro doesn't exist on check version 0.9.8.
44  */
45 #ifdef ck_assert_uint_eq
46 #  undef ck_assert_uint_eq
47 #endif
48 #define ck_assert_uint_eq(X, Y) do { \
49 	uintmax_t _ck_x = (X); \
50 	uintmax_t _ck_y = (Y); \
51 	ck_assert_msg(_ck_x == _ck_y, \
52 			"Assertion '%s' failed: %s == %ju, %s == %ju", \
53 			#X " == " #Y, #X, _ck_x, #Y, _ck_y); \
54 } while (0)
55 
56 
57 /**
58  * Broken on check (0.9.8)
59  */
60 #ifdef ck_assert_str_eq
61 #  undef ck_assert_str_eq
62 #endif
63 #define ck_assert_str_eq(X, Y) do { \
64 	const char* _ck_x = (X); \
65 	const char* _ck_y = (Y); \
66 	const char* _ck_x_s; \
67 	const char* _ck_y_s; \
68 	const char* _ck_x_q; \
69 	const char* _ck_y_q; \
70 	if (_ck_x != NULL) { \
71 		_ck_x_q = "\""; \
72 		_ck_x_s = _ck_x; \
73 	} else { \
74 		_ck_x_q = ""; \
75 		_ck_x_s = "(null)"; \
76 	} \
77 	if (_ck_y != NULL) { \
78 		_ck_y_q = "\""; \
79 		_ck_y_s = _ck_y; \
80 	} else { \
81 		_ck_y_q = ""; \
82 		_ck_y_s = "(null)"; \
83 	} \
84 	ck_assert_msg( \
85 		((_ck_x != NULL) && (_ck_y != NULL) \
86 		 && (0 == strcmp(_ck_y, _ck_x))), \
87 		 "Assertion '%s' failed: %s == %s%s%s, %s == %s%s%s", \
88 		#X" == "#Y, \
89 		#X, _ck_x_q, _ck_x_s, _ck_x_q, \
90 		#Y, _ck_y_q, _ck_y_s, _ck_y_q); \
91 } while (0)
92 
93 
94 
95 #define assert_text_eq(X, Y) do { \
96 	const struct utf8lite_text * _ck_x = (X); \
97 	const struct utf8lite_text * _ck_y = (Y); \
98 	ck_assert_msg(utf8lite_text_equals(_ck_y, _ck_x), \
99 		"Assertion '%s == %s' failed: %s == \"%.*s\" (0x%zx)," \
100 		" %s==\"%.*s\" (0x%zx)", \
101 		#X, #Y, \
102 		#X, (int)UTF8LITE_TEXT_SIZE(_ck_x), _ck_x->ptr, _ck_x->attr, \
103 		#Y, (int)UTF8LITE_TEXT_SIZE(_ck_y), _ck_y->ptr, _ck_y->attr); \
104 } while (0)
105 
106 
107 #define assert_text_ne(X, Y) do { \
108 	const struct utf8lite_text * _ck_x = (X); \
109 	const struct utf8lite_text * _ck_y = (Y); \
110 	ck_assert_msg(!utf8lite_text_equals(_ck_y, _ck_x), \
111 		"Assertion '%s != %s' failed: %s == \"%s\" (0x%zx)," \
112 		" %s==\"%s\" (0x%zx)", \
113 		#X, #Y, \
114 		#X, (int)UTF8LITE_TEXT_SIZE(_ck_x), _ck_x->ptr, _ck_x->attr, \
115 		#Y, (int)UTF8LITE_TEXT_SIZE(_ck_y), _ck_y->ptr, _ck_y->attr); \
116 } while (0)
117 
118 
119 /**
120  * Common test framework set up.
121  */
122 void setup(void);
123 
124 /**
125  * Common test framework tear down.
126  */
127 void teardown(void);
128 
129 /**
130  * Allocate memory.
131  */
132 void *alloc(size_t size);
133 
134 /**
135  * Allocate a text object, interpreting JSON-style escape codes.
136  */
137 struct utf8lite_text *JS(const char *str);
138 
139 /**
140  * Cast a raw string as a text object, ignoring escape codes.
141  */
142 struct utf8lite_text *S(const char *str);
143 
144 #endif /* TESTUTIL_H */
145