Mercurial > hg > th-libs
comparison tests.c @ 282:f0cb48b34463
Implement selectable tests.
author | Matti Hamalainen <ccr@tnsp.org> |
---|---|
date | Mon, 22 Feb 2016 13:14:48 +0200 |
parents | 56b0de9f9d44 |
children | 89c7696acb82 |
comparison
equal
deleted
inserted
replaced
281:0c70dcfb6796 | 282:f0cb48b34463 |
---|---|
3 #include "th_util.h" | 3 #include "th_util.h" |
4 #include "th_string.h" | 4 #include "th_string.h" |
5 #include "th_crypto.h" | 5 #include "th_crypto.h" |
6 | 6 |
7 #define SET_BUF_SIZE 128 | 7 #define SET_BUF_SIZE 128 |
8 #define SET_MAX_TESTS 64 | |
8 | 9 |
9 char *test_str_header = NULL, | 10 char *test_str_header = NULL, |
10 *test_str_res = NULL; | 11 *test_str_res = NULL; |
11 | 12 |
12 int tests_failed, tests_passed, tests_total, tests_set; | 13 int tests_failed, tests_passed, tests_total, tests_sets, tests_nenabled; |
14 int tests_enabled[SET_MAX_TESTS]; | |
13 | 15 |
14 char buf1[SET_BUF_SIZE+2], buf2[SET_BUF_SIZE+2]; | 16 char buf1[SET_BUF_SIZE+2], buf2[SET_BUF_SIZE+2]; |
15 | 17 |
16 | 18 |
17 // Define option arguments | 19 // Define option arguments |
18 static const th_optarg_t arg_opts[] = | 20 static const th_optarg_t arg_opts[] = |
19 { | 21 { |
20 { 0, '?', "help", "Show this help", OPT_NONE }, | 22 { 0, '?', "help", "Show this help", OPT_NONE }, |
21 { 1, 'v', "verbose", "Be more verbose", OPT_NONE }, | 23 { 1, 'v', "verbose", "Be more verbose", OPT_NONE }, |
24 { 2, 't', "tests", "Perform tests -t <set>[,<set2>..]", OPT_ARGREQ }, | |
22 }; | 25 }; |
23 | 26 |
24 static const int arg_nopts = sizeof(arg_opts) / sizeof(arg_opts[0]); | 27 static const int arg_nopts = sizeof(arg_opts) / sizeof(arg_opts[0]); |
25 | 28 |
26 | 29 |
40 exit(0); | 43 exit(0); |
41 break; | 44 break; |
42 | 45 |
43 case 1: | 46 case 1: |
44 th_verbosityLevel++; | 47 th_verbosityLevel++; |
48 break; | |
49 | |
50 case 2: | |
51 { | |
52 BOOL ret = TRUE; | |
53 char *pos, *pstr, *next; | |
54 pos = pstr = th_strdup(optArg); | |
55 memset(tests_enabled, 0, sizeof(tests_enabled)); | |
56 | |
57 do { | |
58 next = strchr(pos, ','); | |
59 if (next != NULL) | |
60 *next = 0; | |
61 | |
62 char *tmp = th_strdup_trim(pos, TH_TRIM_BOTH); | |
63 if (tmp != NULL) | |
64 { | |
65 int val = atoi(tmp); | |
66 if (val > 0 && val <= SET_MAX_TESTS) | |
67 tests_enabled[val] = 1; | |
68 else | |
69 { | |
70 THERR("Invalid test number #%d, out of range [%d .. %d]\n", val, 1, SET_MAX_TESTS); | |
71 ret = FALSE; | |
72 } | |
73 th_free(tmp); | |
74 } | |
75 | |
76 if (next != NULL) | |
77 pos = next + 1; | |
78 } while (next != NULL); | |
79 th_free(pstr); | |
80 return ret; | |
81 } | |
45 break; | 82 break; |
46 | 83 |
47 default: | 84 default: |
48 THERR("Unknown option '%s'.\n", currArg); | 85 THERR("Unknown option '%s'.\n", currArg); |
49 return FALSE; | 86 return FALSE; |
129 ret1 = th_vsnprintf(buf1, len, fmt, ap); | 166 ret1 = th_vsnprintf(buf1, len, fmt, ap); |
130 ret2 = vsnprintf(buf2, len, fmt, tmp); | 167 ret2 = vsnprintf(buf2, len, fmt, tmp); |
131 | 168 |
132 test_result_msg(ret1 == ret2, "retval mismatch %d != %d", ret1, ret2); | 169 test_result_msg(ret1 == ret2, "retval mismatch %d != %d", ret1, ret2); |
133 test_result_msg(strcmp(buf1, buf2) == 0, "result mismatch '%s' != '%s'", buf1, buf2); | 170 test_result_msg(strcmp(buf1, buf2) == 0, "result mismatch '%s' != '%s'", buf1, buf2); |
134 | 171 |
135 test_result_msg((unsigned char) buf1[len] == SET_SENTINEL_BYTE, "buffer #1 overflow, sentinel 0x%02x", buf1[len]); | 172 test_result_msg((unsigned char) buf1[len] == SET_SENTINEL_BYTE, "buffer #1 overflow, sentinel 0x%02x", buf1[len]); |
136 test_result_msg((unsigned char) buf2[len] == SET_SENTINEL_BYTE, "buffer #2 overflow, sentinel 0x%02x", buf2[len]); | 173 test_result_msg((unsigned char) buf2[len] == SET_SENTINEL_BYTE, "buffer #2 overflow, sentinel 0x%02x", buf2[len]); |
137 | 174 |
138 // Test th_strdup_vprintf() | 175 // Test th_strdup_vprintf() |
139 test_start("th_strdup_vprintf('%s')", fmt); | 176 test_start("th_strdup_vprintf('%s')", fmt); |
150 va_copy(tmp, ap); test_snprintf_do(0, fmt, tmp, "0"); | 187 va_copy(tmp, ap); test_snprintf_do(0, fmt, tmp, "0"); |
151 va_copy(tmp, ap); test_snprintf_do(1, fmt, tmp, "1"); | 188 va_copy(tmp, ap); test_snprintf_do(1, fmt, tmp, "1"); |
152 va_copy(tmp, ap); test_snprintf_do(2, fmt, tmp, "2"); | 189 va_copy(tmp, ap); test_snprintf_do(2, fmt, tmp, "2"); |
153 va_copy(tmp, ap); test_snprintf_do(16, fmt, tmp, "16"); | 190 va_copy(tmp, ap); test_snprintf_do(16, fmt, tmp, "16"); |
154 va_copy(tmp, ap); test_snprintf_do(SET_BUF_SIZE, fmt, tmp, "SET_BUF_SIZE"); | 191 va_copy(tmp, ap); test_snprintf_do(SET_BUF_SIZE, fmt, tmp, "SET_BUF_SIZE"); |
155 va_end(ap); | 192 va_end(ap); |
156 THPRINT(2, "----------------------------------------------\n"); | 193 THPRINT(2, "----------------------------------------------\n"); |
157 } | 194 } |
158 | 195 |
159 | 196 |
160 void tests_header(const char *str) | 197 BOOL test_set_start(const char *str) |
161 { | 198 { |
162 THPRINT(1, | 199 if (tests_enabled[tests_sets++]) |
163 "======================================================\n" | 200 { |
164 " Set #%d : %s tests\n" | 201 tests_nenabled++; |
165 "======================================================\n", | 202 THPRINT(1, |
166 ++tests_set, | 203 "======================================================\n" |
167 str); | 204 " Set #%d : %s tests\n" |
168 } | 205 "======================================================\n", |
169 | 206 tests_sets, str); |
170 | 207 |
171 int main(int argc, char *argv[]) | 208 return TRUE; |
172 { | 209 } |
173 // | 210 else |
174 // Initialization | 211 return FALSE; |
175 // | 212 } |
176 th_init("th-test", "th-libs unit tests", "0.0.1", NULL, NULL); | 213 |
177 th_verbosityLevel = 0; | |
178 | |
179 if (sizeof(char) != sizeof(unsigned char)) | |
180 { | |
181 THERR("sizeof(char) != sizeof(unsigned char)???\n"); | |
182 return -1; | |
183 } | |
184 | |
185 tests_failed = tests_passed = tests_total = tests_set = 0; | |
186 | |
187 // | |
188 // Parse command line arguments | |
189 // | |
190 if (!th_args_process(argc, argv, arg_opts, arg_nopts, | |
191 arg_handle_opt, NULL, 0)) | |
192 return 0; | |
193 | |
194 | |
195 // | |
196 // Test series #1 | |
197 // | |
198 tests_header("printf() function family"); | |
199 int i_vals[] = { 2, 612342, -2, -612342, 0x1fff, 0x8000000, }; | |
200 char *i_fmts[] = { "%d", "%x", "%05d", "%5d", "%-5d", "%05x", "%5x", "", }; | |
201 size_t i1, i2; | |
202 | |
203 for (i1 = 0; i1 < sizeof(i_vals) / sizeof(i_vals[0]); i1++) | |
204 for (i2 = 0; i2 < sizeof(i_fmts) / sizeof(i_fmts[0]); i2++) | |
205 test_snprintf(i_fmts[i2], i_vals); | |
206 | |
207 char *s_vals[] = { "", "asdf", "xxx yyy zzz ppp fff", NULL, "X", "abcde", }; | |
208 char *s_fmts[] = { "%s", "%2s", "%-2s", "%5s", "%-5s", "%16s", "%-16s", "%1s", "%-1s", }; | |
209 | |
210 for (i1 = 0; i1 < sizeof(s_vals) / sizeof(s_vals[0]); i1++) | |
211 for (i2 = 0; i2 < sizeof(s_fmts) / sizeof(s_fmts[0]); i2++) | |
212 test_snprintf(s_fmts[i2], s_vals); | |
213 | |
214 test_snprintf("a%cBC", 'x'); | |
215 test_snprintf("%c", 'x'); | |
216 test_snprintf("", 'x'); | |
217 | |
218 // | |
219 // String matching functions | |
220 // | |
221 tests_header("String matching"); | |
222 | 214 |
223 #define TEST2(fun, str1, str2, ret) do { \ | 215 #define TEST2(fun, str1, str2, ret) do { \ |
224 test_start(# fun "('%s', '%s')", str1, str2); \ | 216 test_start(# fun "('%s', '%s')", str1, str2); \ |
225 test_result(( fun (str1, str2) == 0) == ret); \ | 217 test_result(( fun (str1, str2) == 0) == ret); \ |
226 } while (0) | 218 } while (0) |
233 #define TEST3(fun, str1, str2, len, ret) do { \ | 225 #define TEST3(fun, str1, str2, len, ret) do { \ |
234 test_start(# fun "('%s', '%s', %d)", str1, str2, len); \ | 226 test_start(# fun "('%s', '%s', %d)", str1, str2, len); \ |
235 test_result(( fun (str1, str2, len) == 0) == ret); \ | 227 test_result(( fun (str1, str2, len) == 0) == ret); \ |
236 } while (0) | 228 } while (0) |
237 | 229 |
238 TEST2(th_strcasecmp, "aSdFq", "asdfq", TRUE); | 230 |
239 TEST2(th_strcasecmp, "aSdFq", "asFfq", FALSE); | 231 |
240 TEST2(th_strcasecmp, "abcde", "abcde", TRUE); | 232 int main(int argc, char *argv[]) |
241 TEST2(th_strcasecmp, "öäå", "öäå", TRUE); | 233 { |
242 TEST2(th_strcasecmp, "aöäå", "aöäå", TRUE); | 234 size_t i1, i2; |
243 | 235 |
244 TEST3(th_strncasecmp, "aSdFq", "asFfq", 4, FALSE); | 236 // |
245 TEST3(th_strncasecmp, "aSdFq", "asFfq", 2, TRUE); | 237 // Initialization |
246 TEST3(th_strncasecmp, "aSdFq", "asDfq", 3, TRUE); | 238 // |
247 TEST3(th_strncasecmp, "aSdFq", "asDfq", 2, TRUE); | 239 th_init("th-test", "th-libs unit tests", "0.0.1", NULL, NULL); |
248 TEST3(th_strncasecmp, "aSdFq", "asDfq", 0, TRUE); | 240 th_verbosityLevel = 0; |
249 TEST3(th_strncasecmp, "aSdFq", "QsDfq", 0, TRUE); | 241 |
250 TEST3(th_strncasecmp, "aSdFq", "QsDfq", 1, FALSE); | 242 if (sizeof(char) != sizeof(unsigned char)) |
251 | 243 { |
252 TEST2B(th_strmatch, "abba ABBAkukka lol", "*lol", TRUE); | 244 THERR("sizeof(char) != sizeof(unsigned char)???\n"); |
253 TEST2B(th_strmatch, "abba ABBAkukka lol", "*lo*", TRUE); | 245 return -1; |
254 TEST2B(th_strmatch, "abba ABBAkukka lol", "*lo", FALSE); | 246 } |
255 TEST2B(th_strmatch, "abba ABBAkukka lol", "abba", FALSE); | 247 |
256 TEST2B(th_strmatch, "abba ABBAkukka lol", "abba*", TRUE); | 248 tests_failed = tests_passed = tests_total = tests_sets = tests_nenabled = 0; |
257 TEST2B(th_strmatch, "abba ABBAkukka lol", "abbak*", FALSE); | 249 for (i1 = 0; i1 < SET_MAX_TESTS; i1++) |
258 TEST2B(th_strcasematch, "abba ABBAkukka lol", "abbak*", FALSE); | 250 tests_enabled[i1] = 1; |
259 TEST2B(th_strcasematch, "abba ABBAkukka lol", "*abbak*", TRUE); | 251 |
260 TEST2B(th_strcasematch, "abba ABBAkukka lol", "*abbak?", FALSE); | 252 // |
261 TEST2B(th_strcasematch, "abba ABBAkukka lol", "?bba?abba*", TRUE); | 253 // Parse command line arguments |
262 TEST2B(th_strmatch, "abba ABBAöökukka lol", "*abbaö?", FALSE); | 254 // |
255 if (!th_args_process(argc, argv, arg_opts, arg_nopts, | |
256 arg_handle_opt, NULL, 0)) | |
257 return 0; | |
258 | |
259 | |
260 // | |
261 // Test series #1 | |
262 // | |
263 if (test_set_start("printf() function family #1")) | |
264 { | |
265 int i_vals[] = { 2, 612342, -2, -612342, 0x1fff, 0x8000000, }; | |
266 char *i_fmts[] = { "%d", "%x", "%05d", "%5d", "%-5d", "%05x", "%5x", "", }; | |
267 | |
268 for (i1 = 0; i1 < sizeof(i_vals) / sizeof(i_vals[0]); i1++) | |
269 for (i2 = 0; i2 < sizeof(i_fmts) / sizeof(i_fmts[0]); i2++) | |
270 test_snprintf(i_fmts[i2], i_vals); | |
271 } | |
272 | |
273 if (test_set_start("printf() function family #2")) | |
274 { | |
275 char *s_vals[] = { "", "asdf", "xxx yyy zzz ppp fff", NULL, "X", "abcde", }; | |
276 char *s_fmts[] = { "%s", "%2s", "%-2s", "%5s", "%-5s", "%16s", "%-16s", "%1s", "%-1s", }; | |
277 | |
278 for (i1 = 0; i1 < sizeof(s_vals) / sizeof(s_vals[0]); i1++) | |
279 for (i2 = 0; i2 < sizeof(s_fmts) / sizeof(s_fmts[0]); i2++) | |
280 test_snprintf(s_fmts[i2], s_vals); | |
281 | |
282 test_snprintf("a%cBC", 'x'); | |
283 test_snprintf("%c", 'x'); | |
284 test_snprintf("", 'x'); | |
285 } | |
286 | |
287 // | |
288 // String matching functions | |
289 // | |
290 if (test_set_start("String matching #1")) | |
291 { | |
292 TEST2(th_strcasecmp, "aSdFq", "asdfq", TRUE); | |
293 TEST2(th_strcasecmp, "aSdFq", "asFfq", FALSE); | |
294 TEST2(th_strcasecmp, "abcde", "abcde", TRUE); | |
295 TEST2(th_strcasecmp, "öäå", "öäå", TRUE); | |
296 TEST2(th_strcasecmp, "aöäå", "aöäå", TRUE); | |
297 } | |
298 | |
299 if (test_set_start("String matching #2")) | |
300 { | |
301 TEST3(th_strncasecmp, "aSdFq", "asFfq", 4, FALSE); | |
302 TEST3(th_strncasecmp, "aSdFq", "asFfq", 2, TRUE); | |
303 TEST3(th_strncasecmp, "aSdFq", "asDfq", 3, TRUE); | |
304 TEST3(th_strncasecmp, "aSdFq", "asDfq", 2, TRUE); | |
305 TEST3(th_strncasecmp, "aSdFq", "asDfq", 0, TRUE); | |
306 TEST3(th_strncasecmp, "aSdFq", "QsDfq", 0, TRUE); | |
307 TEST3(th_strncasecmp, "aSdFq", "QsDfq", 1, FALSE); | |
308 } | |
309 | |
310 if (test_set_start("String matching #3")) | |
311 { | |
312 TEST2B(th_strmatch, "abba ABBAkukka lol", "*lol", TRUE); | |
313 TEST2B(th_strmatch, "abba ABBAkukka lol", "*lo*", TRUE); | |
314 TEST2B(th_strmatch, "abba ABBAkukka lol", "*lo", FALSE); | |
315 TEST2B(th_strmatch, "abba ABBAkukka lol", "abba", FALSE); | |
316 TEST2B(th_strmatch, "abba ABBAkukka lol", "abba*", TRUE); | |
317 TEST2B(th_strmatch, "abba ABBAkukka lol", "abbak*", FALSE); | |
318 TEST2B(th_strmatch, "abba ABBAöökukka lol", "*abbaö?", FALSE); | |
319 } | |
320 | |
321 if (test_set_start("String matching #4")) | |
322 { | |
323 TEST2B(th_strcasematch, "abba ABBAkukka lol", "abbak*", FALSE); | |
324 TEST2B(th_strcasematch, "abba ABBAkukka lol", "*abbak*", TRUE); | |
325 TEST2B(th_strcasematch, "abba ABBAkukka lol", "*abbak?", FALSE); | |
326 TEST2B(th_strcasematch, "abba ABBAkukka lol", "?bba?abba*", TRUE); | |
327 } | |
263 | 328 |
264 // Tests that test for things that do not work correctly yet | 329 // Tests that test for things that do not work correctly yet |
265 // Unicode / multibyte UTF-8 causes problems here | 330 // Unicode / multibyte UTF-8 causes problems here |
266 tests_header("Invalid"); | 331 if (test_set_start("Invalid")) |
267 TEST2(th_strcasecmp, "ÖÄÅ", "öäå", FALSE); // SHOULD match | 332 { |
268 TEST3(th_strncasecmp, "Aäöå", "aöå", 2, TRUE); // should NOT match | 333 TEST2(th_strcasecmp, "ÖÄÅ", "öäå", FALSE); // SHOULD match |
269 | 334 TEST3(th_strncasecmp, "Aäöå", "aöå", 2, TRUE); // should NOT match |
270 TEST2B(th_strmatch, "öriÖRI! lol", "?ri?RI!*", FALSE); // should match | 335 TEST2B(th_strmatch, "öriÖRI! lol", "?ri?RI!*", FALSE); // should match |
271 | 336 } |
272 | 337 |
273 // | 338 // |
274 // Print summary and exit | 339 // Print summary and exit |
275 // | 340 // |
276 THPRINT(1, | 341 THPRINT(1, |
277 "======================================================\n"); | 342 "======================================================\n"); |
278 | 343 |
279 THPRINT(0, | 344 THPRINT(0, |
280 "%d tests failed, %d passed (%d main tests), %d test sets.\n", | 345 "%d tests failed, %d passed (%d main tests), %d test sets of %d sets total.\n", |
281 tests_failed, tests_passed, tests_total, tests_set); | 346 tests_failed, tests_passed, tests_total, tests_nenabled, tests_sets); |
282 | 347 |
283 return 0; | 348 return 0; |
284 } | 349 } |