]> git.ipfire.org Git - thirdparty/strongswan.git/blob - src/libstrongswan/tests/test_enumerator.c
b5dde465095c552855af5f01fe34b8dfa6b9bf44
[thirdparty/strongswan.git] / src / libstrongswan / tests / test_enumerator.c
1 /*
2 * Copyright (C) 2013 Tobias Brunner
3 * Copyright (C) 2007 Martin Willi
4 * Hochschule fuer Technik Rapperswil
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; either version 2 of the License, or (at your
9 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
10 *
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * for more details.
15 */
16
17 #include "test_suite.h"
18
19 #include <collections/enumerator.h>
20 #include <collections/linked_list.h>
21
22 /*******************************************************************************
23 * token test
24 */
25
26 static const char *token_results1[] = { "abc", "cde", "efg" };
27 static const char *token_results2[] = { "a", "b", "c" };
28
29 static struct {
30 char *string;
31 char *sep;
32 char *trim;
33 const char **results;
34 } token_tests[] = {
35 {"abc, cde, efg", ",", " ", token_results1},
36 {" abc 1:2 cde;3 4efg5. ", ":;.,", " 12345", token_results1},
37 {"abc.cde,efg", ",.", "", token_results1},
38 {" abc cde efg ", " ", " ", token_results1},
39 {"a'abc' c 'cde' cefg", " ", " abcd", token_results1},
40 {"'abc' abc 'cde'd 'efg'", " ", " abcd", token_results1},
41
42 {"a, b, c", ",", " ", token_results2},
43 {"a,b,c", ",", " ", token_results2},
44 {" a 1:2 b;3 4c5. ", ":;.,", " 12345", token_results2},
45 {"a.b,c", ",.", "", token_results2},
46 {" a b c ", " ", " ", token_results2},
47 };
48
49 START_TEST(test_token)
50 {
51 enumerator_t *enumerator;
52 const char **results;
53 char *token;
54 int tok = 0;
55
56 enumerator = enumerator_create_token(token_tests[_i].string,
57 token_tests[_i].sep, token_tests[_i].trim);
58 results = token_tests[_i].results;
59 while (enumerator->enumerate(enumerator, &token))
60 {
61 switch (tok)
62 {
63 case 0:
64 case 1:
65 case 2:
66 ck_assert_str_eq(token, results[tok]);
67 break;
68 default:
69 fail("unexpected token '%s'", token);
70 }
71 tok++;
72 }
73 fail_if(tok != 3, "not enough tokens (%d) extracted from '%s'",
74 tok, token_tests[_i].string);
75 enumerator->destroy(enumerator);
76 }
77 END_TEST
78
79 /*******************************************************************************
80 * utilities for filtered, nested and cleaner tests
81 */
82
83 static int destroy_data_called;
84
85 START_SETUP(setup_destroy_data)
86 {
87 destroy_data_called = 0;
88 }
89 END_SETUP
90
91 START_TEARDOWN(teardown_destroy_data)
92 {
93 ck_assert_int_eq(destroy_data_called, 1);
94 }
95 END_TEARDOWN
96
97 static void destroy_data(void *data)
98 {
99 fail_if(data != (void*)101, "data does not match '101' in destructor");
100 destroy_data_called++;
101 }
102
103 /*******************************************************************************
104 * filtered test
105 */
106
107 static bool filter(void *data, int *v, int *vo, int *w, int *wo,
108 int *x, int *xo, int *y, int *yo, int *z, int *zo)
109 {
110 int val = *v;
111
112 *vo = val++;
113 *wo = val++;
114 *xo = val++;
115 *yo = val++;
116 *zo = val++;
117 fail_if(data != (void*)101, "data does not match '101' in filter function");
118 return TRUE;
119 }
120
121 static bool filter_odd(void *data, int *item, int *out)
122 {
123 fail_if(data != (void*)101, "data does not match '101' in filter function");
124 *out = *item;
125 return *item % 2 == 0;
126 }
127
128 START_TEST(test_filtered)
129 {
130 int round, v, w, x, y, z;
131 linked_list_t *list;
132 enumerator_t *enumerator;
133
134 list = linked_list_create_with_items((void*)1, (void*)2, (void*)3, (void*)4,
135 (void*)5, NULL);
136
137 round = 1;
138 enumerator = enumerator_create_filter(list->create_enumerator(list),
139 (void*)filter, (void*)101, destroy_data);
140 while (enumerator->enumerate(enumerator, &v, &w, &x, &y, &z))
141 {
142 ck_assert_int_eq(v, round);
143 ck_assert_int_eq(w, round + 1);
144 ck_assert_int_eq(x, round + 2);
145 ck_assert_int_eq(y, round + 3);
146 ck_assert_int_eq(z, round + 4);
147 round++;
148 }
149 enumerator->destroy(enumerator);
150 ck_assert_int_eq(round, 6);
151
152 list->destroy(list);
153 }
154 END_TEST
155
156 START_TEST(test_filtered_filter)
157 {
158 int count, x;
159 linked_list_t *list;
160 enumerator_t *enumerator;
161
162 list = linked_list_create_with_items((void*)1, (void*)2, (void*)3, (void*)4,
163 (void*)5, NULL);
164
165 count = 0;
166 /* should also work without destructor, so set this manually */
167 destroy_data_called = 1;
168 enumerator = enumerator_create_filter(list->create_enumerator(list),
169 (void*)filter_odd, (void*)101, NULL);
170 while (enumerator->enumerate(enumerator, &x))
171 {
172 ck_assert(x % 2 == 0);
173 count++;
174 }
175 enumerator->destroy(enumerator);
176 ck_assert_int_eq(count, 2);
177
178 list->destroy(list);
179 }
180 END_TEST
181
182 /*******************************************************************************
183 * nested test
184 */
185
186 static enumerator_t* create_inner(linked_list_t *outer, void *data)
187 {
188 fail_if(data != (void*)101, "data does not match '101' in nested constr.");
189 return outer->create_enumerator(outer);
190 }
191
192 static enumerator_t* create_inner_null(void *outer, void *data)
193 {
194 ck_assert(outer == (void*)1);
195 fail_if(data != (void*)101, "data does not match '101' in nested constr.");
196 return NULL;
197 }
198
199 START_TEST(test_nested)
200 {
201 linked_list_t *list, *l1, *l2, *l3;
202 enumerator_t *enumerator;
203 intptr_t x;
204 int round;
205
206 l1 = linked_list_create_with_items((void*)1, (void*)2, NULL);
207 l2 = linked_list_create();
208 l3 = linked_list_create_with_items((void*)3, (void*)4, (void*)5, NULL);
209 list = linked_list_create_with_items(l1, l2, l3, NULL);
210
211 round = 1;
212 enumerator = enumerator_create_nested(list->create_enumerator(list),
213 (void*)create_inner, (void*)101, destroy_data);
214 while (enumerator->enumerate(enumerator, &x))
215 {
216 ck_assert_int_eq(round, x);
217 round++;
218 }
219 enumerator->destroy(enumerator);
220 ck_assert_int_eq(round, 6);
221
222 list->destroy(list);
223 l1->destroy(l1);
224 l2->destroy(l2);
225 l3->destroy(l3);
226 }
227 END_TEST
228
229 START_TEST(test_nested_reset)
230 {
231 linked_list_t *list, *l1, *l2, *l3;
232 enumerator_t *outer, *enumerator;
233 intptr_t x;
234 int count = 0;
235
236 l1 = linked_list_create_with_items((void*)1, (void*)2, NULL);
237 l2 = linked_list_create();
238 l3 = linked_list_create_with_items((void*)3, (void*)4, (void*)5, NULL);
239 list = linked_list_create_with_items(l1, l2, l3, NULL);
240
241 outer = list->create_enumerator(list);
242 enumerator = enumerator_create_nested(outer, (void*)create_inner,
243 (void*)101, destroy_data);
244 while (enumerator->enumerate(enumerator, &x))
245 {
246 count++;
247 }
248 ck_assert_int_eq(count, 5);
249
250 list->reset_enumerator(list, outer);
251 ck_assert(enumerator->enumerate(enumerator, &x));
252 ck_assert_int_eq(x, 1);
253 enumerator->destroy(enumerator);
254
255 list->destroy(list);
256 l1->destroy(l1);
257 l2->destroy(l2);
258 l3->destroy(l3);
259 }
260 END_TEST
261
262 START_TEST(test_nested_empty)
263 {
264 linked_list_t *list;
265 enumerator_t *enumerator;
266 intptr_t x;
267 int count;
268
269 list = linked_list_create();
270 count = 0;
271 enumerator = enumerator_create_nested(list->create_enumerator(list),
272 (void*)create_inner, (void*)101, destroy_data);
273 while (enumerator->enumerate(enumerator, &x))
274 {
275 count++;
276 }
277 enumerator->destroy(enumerator);
278 ck_assert_int_eq(count, 0);
279
280 list->destroy(list);
281 }
282 END_TEST
283
284 START_TEST(test_nested_null)
285 {
286 linked_list_t *list;
287 enumerator_t *enumerator;
288 intptr_t x;
289 int count;
290
291 list = linked_list_create_with_items((void*)1, NULL);
292
293 count = 0;
294 /* should also work without destructor, so set this manually */
295 destroy_data_called = 1;
296 enumerator = enumerator_create_nested(list->create_enumerator(list),
297 (void*)create_inner_null, (void*)101, NULL);
298 while (enumerator->enumerate(enumerator, &x))
299 {
300 count++;
301 }
302 enumerator->destroy(enumerator);
303 ck_assert_int_eq(count, 0);
304
305 list->destroy(list);
306 }
307 END_TEST
308
309 /*******************************************************************************
310 * cleaner test
311 */
312
313 START_TEST(test_cleaner)
314 {
315 enumerator_t *enumerator;
316 linked_list_t *list;
317 intptr_t x;
318 int round;
319
320 list = linked_list_create_with_items((void*)1, (void*)2, NULL);
321
322 round = 1;
323 enumerator = enumerator_create_cleaner(list->create_enumerator(list),
324 destroy_data, (void*)101);
325 while (enumerator->enumerate(enumerator, &x))
326 {
327 ck_assert_int_eq(round, x);
328 round++;
329 }
330 ck_assert_int_eq(round, 3);
331 enumerator->destroy(enumerator);
332 list->destroy(list);
333 }
334 END_TEST
335
336 /*******************************************************************************
337 * single test
338 */
339
340 static void single_cleanup(void *data)
341 {
342 ck_assert_int_eq((intptr_t)data, 1);
343 }
344
345 static void do_test_single(enumerator_t *enumerator)
346 {
347 intptr_t x;
348
349 ck_assert(enumerator->enumerate(enumerator, &x));
350 ck_assert_int_eq(x, 1);
351 ck_assert(!enumerator->enumerate(enumerator, &x));
352 enumerator->destroy(enumerator);
353 }
354
355 START_TEST(test_single)
356 {
357 enumerator_t *enumerator;
358
359 enumerator = enumerator_create_single((void*)1, NULL);
360 do_test_single(enumerator);
361 }
362 END_TEST
363
364 START_TEST(test_single_cleanup)
365 {
366 enumerator_t *enumerator;
367
368 enumerator = enumerator_create_single((void*)1, single_cleanup);
369 do_test_single(enumerator);
370 }
371 END_TEST
372
373 Suite *enumerator_suite_create()
374 {
375 Suite *s;
376 TCase *tc;
377
378 s = suite_create("enumerator");
379
380 tc = tcase_create("tokens");
381 tcase_add_loop_test(tc, test_token, 0, countof(token_tests));
382 suite_add_tcase(s, tc);
383
384 tc = tcase_create("filtered");
385 tcase_add_checked_fixture(tc, setup_destroy_data, teardown_destroy_data);
386 tcase_add_test(tc, test_filtered);
387 tcase_add_test(tc, test_filtered_filter);
388 suite_add_tcase(s, tc);
389
390 tc = tcase_create("nested");
391 tcase_add_checked_fixture(tc, setup_destroy_data, teardown_destroy_data);
392 tcase_add_test(tc, test_nested);
393 tcase_add_test(tc, test_nested_reset);
394 tcase_add_test(tc, test_nested_empty);
395 tcase_add_test(tc, test_nested_null);
396 suite_add_tcase(s, tc);
397
398 tc = tcase_create("cleaner");
399 tcase_add_checked_fixture(tc, setup_destroy_data, teardown_destroy_data);
400 tcase_add_test(tc, test_cleaner);
401 suite_add_tcase(s, tc);
402
403 tc = tcase_create("single");
404 tcase_add_test(tc, test_single);
405 tcase_add_test(tc, test_single_cleanup);
406 suite_add_tcase(s, tc);
407
408 return s;
409 }