]>
Commit | Line | Data |
---|---|---|
f15fcdc9 TB |
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 | ||
95e99150 | 17 | #include "test_suite.h" |
f15fcdc9 TB |
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 | /******************************************************************************* | |
7e9f6b27 | 80 | * utilities for filtered, nested and cleaner tests |
f15fcdc9 TB |
81 | */ |
82 | ||
7e9f6b27 TB |
83 | static int destroy_data_called; |
84 | ||
95e99150 | 85 | START_SETUP(setup_destroy_data) |
7e9f6b27 TB |
86 | { |
87 | destroy_data_called = 0; | |
88 | } | |
95e99150 | 89 | END_SETUP |
7e9f6b27 | 90 | |
95e99150 | 91 | START_TEARDOWN(teardown_destroy_data) |
7e9f6b27 TB |
92 | { |
93 | ck_assert_int_eq(destroy_data_called, 1); | |
94 | } | |
95e99150 | 95 | END_TEARDOWN |
7e9f6b27 | 96 | |
f15fcdc9 TB |
97 | static void destroy_data(void *data) |
98 | { | |
99 | fail_if(data != (void*)101, "data does not match '101' in destructor"); | |
7e9f6b27 | 100 | destroy_data_called++; |
f15fcdc9 TB |
101 | } |
102 | ||
103 | /******************************************************************************* | |
104 | * filtered test | |
105 | */ | |
106 | ||
0462304d TB |
107 | static bool filter(int *data, int **v, int *vo, int **w, int *wo, |
108 | int **x, int *xo, int **y, int *yo, int **z, int *zo) | |
f15fcdc9 | 109 | { |
0462304d | 110 | int val = **v; |
f15fcdc9 TB |
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 | ||
0462304d | 121 | static bool filter_odd(void *data, int **item, int *out) |
7e9f6b27 TB |
122 | { |
123 | fail_if(data != (void*)101, "data does not match '101' in filter function"); | |
0462304d TB |
124 | *out = **item; |
125 | return **item % 2 == 0; | |
7e9f6b27 TB |
126 | } |
127 | ||
f15fcdc9 TB |
128 | START_TEST(test_filtered) |
129 | { | |
0462304d | 130 | int data[5] = {1,2,3,4,5}, round, v, w, x, y, z; |
f15fcdc9 TB |
131 | linked_list_t *list; |
132 | enumerator_t *enumerator; | |
133 | ||
0462304d TB |
134 | list = linked_list_create_with_items(&data[0], &data[1], &data[2], &data[3], |
135 | &data[4], NULL); | |
f15fcdc9 TB |
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); | |
7e9f6b27 TB |
150 | ck_assert_int_eq(round, 6); |
151 | ||
152 | list->destroy(list); | |
153 | } | |
154 | END_TEST | |
155 | ||
156 | START_TEST(test_filtered_filter) | |
157 | { | |
0462304d | 158 | int data[5] = {1,2,3,4,5}, count, x; |
7e9f6b27 TB |
159 | linked_list_t *list; |
160 | enumerator_t *enumerator; | |
161 | ||
0462304d TB |
162 | list = linked_list_create_with_items(&data[0], &data[1], &data[2], &data[3], |
163 | &data[4], NULL); | |
7e9f6b27 TB |
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); | |
f15fcdc9 TB |
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 | ||
7e9f6b27 TB |
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 | ||
f15fcdc9 TB |
199 | START_TEST(test_nested) |
200 | { | |
f15fcdc9 TB |
201 | linked_list_t *list, *l1, *l2, *l3; |
202 | enumerator_t *enumerator; | |
7e9f6b27 TB |
203 | intptr_t x; |
204 | int round; | |
f15fcdc9 TB |
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), | |
7e9f6b27 | 213 | (void*)create_inner, (void*)101, destroy_data); |
f15fcdc9 TB |
214 | while (enumerator->enumerate(enumerator, &x)) |
215 | { | |
216 | ck_assert_int_eq(round, x); | |
217 | round++; | |
218 | } | |
219 | enumerator->destroy(enumerator); | |
7e9f6b27 TB |
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); | |
f15fcdc9 TB |
254 | |
255 | list->destroy(list); | |
256 | l1->destroy(l1); | |
257 | l2->destroy(l2); | |
258 | l3->destroy(l3); | |
259 | } | |
260 | END_TEST | |
261 | ||
7e9f6b27 TB |
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 | ||
f15fcdc9 TB |
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"); | |
7e9f6b27 | 385 | tcase_add_checked_fixture(tc, setup_destroy_data, teardown_destroy_data); |
f15fcdc9 | 386 | tcase_add_test(tc, test_filtered); |
7e9f6b27 | 387 | tcase_add_test(tc, test_filtered_filter); |
f15fcdc9 TB |
388 | suite_add_tcase(s, tc); |
389 | ||
390 | tc = tcase_create("nested"); | |
7e9f6b27 | 391 | tcase_add_checked_fixture(tc, setup_destroy_data, teardown_destroy_data); |
f15fcdc9 | 392 | tcase_add_test(tc, test_nested); |
7e9f6b27 TB |
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); | |
f15fcdc9 TB |
406 | suite_add_tcase(s, tc); |
407 | ||
408 | return s; | |
409 | } |