1 /**
2 * @file check_element.c
3 * @brief Unit testing for SCEW lists
4 * @author Aleix Conchillo Flaque <aconchillo@gmail.com>
5 * @date Fri Aug 03, 2007 17:11
6 *
7 * @if copyright
8 *
9 * Copyright (C) 2007-2009 Aleix Conchillo Flaque
10 *
11 * SCEW is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU Lesser General Public
13 * License as published by the Free Software Foundation; either
14 * version 2.1 of the License, or (at your option) any later version.
15 *
16 * SCEW is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 * Lesser General Public License for more details.
20 *
21 * You should have received a copy of the GNU Lesser General Public
22 * License along with this library; if not, write to the Free Software
23 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
24 * 02110-1301, USA.
25 *
26 * @endif
27 */
28
29 #include "test.h"
30
31 #include <scew/list.h>
32
33 #include <check.h>
34
35
36 /* Private */
37
38 typedef struct
39 {
40 int value;
41 } item_t;
42
43 enum { N_ELEMENTS_ = 10 };
44
45 static item_t data_[N_ELEMENTS_];
46
47
48 /* Unit tests */
49
50 /* Allocation */
51
START_TEST(test_alloc)52 START_TEST (test_alloc)
53 {
54 item_t data = { 3 };
55
56 scew_list *list = scew_list_create (&data);
57
58 CHECK_PTR (list, "Unable to create list");
59
60 CHECK_BOOL (scew_list_data (list) == &data, SCEW_TRUE,
61 "Invalid data pointer");
62
63 scew_list_free (list);
64 }
65 END_TEST
66
67
68 /* Accessors */
69
START_TEST(test_accessors)70 START_TEST (test_accessors)
71 {
72 /* Add items to list */
73 scew_list *list = NULL;
74 scew_list *last = NULL;
75 unsigned int i = 0;
76 for (i = 0; i < N_ELEMENTS_; ++i)
77 {
78 last = scew_list_append (last, &data_[i]);
79
80 CHECK_PTR (last, "Unable to append item %d", i);
81 CHECK_BOOL (scew_list_data (last) == &data_[i], SCEW_TRUE,
82 "Invalid data pointer (item %d)", i);
83
84 item_t *tmp = scew_list_data (last);
85 CHECK_S_INT (tmp->value, i, "Invalid data value (item %d)", i);
86
87 if (list == NULL)
88 {
89 list = last;
90 CHECK_NULL_PTR (scew_list_previous (list),
91 "First item should have no previous");
92 }
93 }
94
95 CHECK_U_INT (scew_list_size (list), N_ELEMENTS_, "Number of items mismatch");
96
97 scew_list_free (list);
98 }
99 END_TEST
100
101
102 /* Append */
103
START_TEST(test_append)104 START_TEST (test_append)
105 {
106 /* Append items to list */
107 scew_list *list = NULL;
108 unsigned int i = 0;
109 for (i = 0; i < N_ELEMENTS_; ++i)
110 {
111 scew_list *item = scew_list_append (list, &data_[i]);
112 if (list == NULL)
113 {
114 list = item;
115 }
116 CHECK_PTR (item, "Unable to append item %d", i);
117 CHECK_BOOL (scew_list_data (item) == &data_[i], SCEW_TRUE,
118 "Invalid data pointer (item %d)", i);
119
120 item_t *tmp = scew_list_data (item);
121 CHECK_S_INT (tmp->value, i, "Invalid data value (item %d)", i);
122 }
123
124 CHECK_U_INT (scew_list_size (list), N_ELEMENTS_, "Number of items mismatch");
125
126 scew_list_free (list);
127 }
128 END_TEST
129
130
131 /* Prepend */
132
START_TEST(test_prepend)133 START_TEST (test_prepend)
134 {
135 /* Prepend items to list */
136 scew_list *list = NULL;
137 unsigned int i = 0;
138 for (i = 0; i < N_ELEMENTS_; ++i)
139 {
140 list = scew_list_prepend (list, &data_[i]);
141
142 CHECK_PTR (list, "Unable to prepend item %d", i);
143 CHECK_BOOL (scew_list_data (list) == &data_[i], SCEW_TRUE,
144 "Invalid data pointer (item %d)", i);
145
146 item_t *tmp = scew_list_data (list);
147 CHECK_S_INT (tmp->value, i, "Invalid data value (item %d)", i);
148 }
149
150 CHECK_U_INT (scew_list_size (list), N_ELEMENTS_, "Number of items mismatch");
151
152 scew_list_free (list);
153 }
154 END_TEST
155
156
157 /* Delete */
158
START_TEST(test_delete)159 START_TEST (test_delete)
160 {
161 /* Append items to list */
162 scew_list *list = NULL;
163 unsigned int i = 0;
164 for (i = 0; i < N_ELEMENTS_; ++i)
165 {
166 scew_list *item = scew_list_append (list, &data_[i]);
167 if (list == NULL)
168 {
169 list = item;
170 }
171 }
172
173 /* Delete items 2 and 6 */
174 list = scew_list_delete (list, &data_[2]);
175 list = scew_list_delete (list, &data_[6]);
176
177 CHECK_U_INT (scew_list_size (list), N_ELEMENTS_ - 2,
178 "Number of items mismatch");
179
180 /* Delete item 1 */
181 scew_list *item = scew_list_next (list);
182 list = scew_list_delete_item (list, item);
183
184 CHECK_U_INT (scew_list_size (list), N_ELEMENTS_ - 3,
185 "Number of items mismatch");
186
187 /* Check for all remaining items */
188 enum { N_REMOVED = 3 };
189 unsigned int const REMOVED[N_REMOVED] = { 1, 2, 6 };
190 item = list;
191 while (item != NULL)
192 {
193 item_t *tmp = scew_list_data (item);
194 unsigned int j = 0;
195 for (j = 0; j < N_REMOVED; ++j)
196 {
197 CHECK_BOOL (tmp->value != REMOVED[j], SCEW_TRUE,
198 "Item %d should have been previously removed",
199 tmp->value);
200 }
201 item = scew_list_next (item);
202 }
203
204 scew_list_free (list);
205 }
206 END_TEST
207
208
209 /* Traverse */
210
START_TEST(test_traverse)211 START_TEST (test_traverse)
212 {
213 /* Append items to list */
214 scew_list *item = NULL;
215 scew_list *list = NULL;
216 unsigned int i = 0;
217 for (i = 0; i < N_ELEMENTS_; ++i)
218 {
219 item = scew_list_append (list, &data_[i]);
220 if (list == NULL)
221 {
222 list = item;
223 }
224 }
225
226 CHECK_BOOL (list == scew_list_first (list), SCEW_TRUE,
227 "First list item should be itself");
228
229 CHECK_BOOL (item == scew_list_last (list), SCEW_TRUE,
230 "Last list item should be last item added");
231
232 CHECK_NULL_PTR (scew_list_previous (list),
233 "First previous item should be NULL");
234
235 CHECK_NULL_PTR (scew_list_next (item),
236 "Last next item should be NULL");
237
238 item = list;
239 while (item != NULL)
240 {
241 scew_list *old_item = item;
242
243 item = scew_list_next (item);
244
245 if (item != NULL)
246 {
247 CHECK_BOOL (old_item == scew_list_previous (item), SCEW_TRUE,
248 "Wrong previous item");
249 }
250 }
251 }
252 END_TEST
253
254
255 /* Traverse (foreach) */
256
257 static unsigned int foreach_calls_ = 0; /* keep track of number of calls */
258
259 static void
foreach_check_(scew_list * item,void * user_data)260 foreach_check_ (scew_list *item, void *user_data)
261 {
262 item_t *fe_data = (item_t *) user_data;
263
264 item_t *tmp = scew_list_data (item);
265
266 CHECK_BOOL (tmp == &fe_data[foreach_calls_], SCEW_TRUE,
267 "Data pointer does not match in foreach call");
268
269 CHECK_S_INT (tmp->value, foreach_calls_,
270 "Invalid data value in foreach call (item %d)", foreach_calls_);
271
272 ++foreach_calls_;
273 }
274
START_TEST(test_traverse_foreach)275 START_TEST (test_traverse_foreach)
276 {
277 /* Append items to list */
278 scew_list *list = NULL;
279 unsigned int i = 0;
280 for (i = 0; i < N_ELEMENTS_; ++i)
281 {
282 scew_list *item = scew_list_append (list, &data_[i]);
283 if (list == NULL)
284 {
285 list = item;
286 }
287 }
288
289 foreach_calls_ = 0;
290
291 scew_list_foreach (list, foreach_check_, data_);
292
293 CHECK_U_INT (foreach_calls_, N_ELEMENTS_,
294 "Number of foreach calls mismatch");
295 }
296 END_TEST
297
298
299 /* Search */
300
301 static scew_bool
search_cmp_(void const * a,void const * b)302 search_cmp_ (void const *a, void const *b)
303 {
304 return (((item_t *) a)->value == ((item_t *) b)->value);
305 }
306
START_TEST(test_search)307 START_TEST (test_search)
308 {
309 /* Append items to list */
310 scew_list *item_5 = NULL;
311 scew_list *list = NULL;
312 unsigned int i = 0;
313 for (i = 0; i < N_ELEMENTS_; ++i)
314 {
315 scew_list *item = scew_list_append (list, &data_[i]);
316 if (i == 5)
317 {
318 item_5 = item;
319 }
320 if (list == NULL)
321 {
322 list = item;
323 }
324 }
325
326 CHECK_BOOL (item_5 == scew_list_find (list, &data_[5]), SCEW_TRUE,
327 "Item 5 search failed");
328
329 item_t value_5 = { 5 };
330 CHECK_BOOL (item_5 == scew_list_find_custom (list, &value_5, search_cmp_),
331 SCEW_TRUE, "Item 5 custom search failed");
332
333 /* Sequential indexing */
334 scew_list *item = list;
335 for (i = 0; i < N_ELEMENTS_; ++i)
336 {
337 CHECK_BOOL (item == scew_list_index (list, i), SCEW_TRUE,
338 "Sequential index item mismatch");
339 item = scew_list_next (item);
340 }
341
342 CHECK_NULL_PTR (scew_list_index (list, N_ELEMENTS_),
343 "Sequential index out of range");
344 }
345 END_TEST
346
347
348 /* Suite */
349
350 static Suite*
list_suite(void)351 list_suite (void)
352 {
353 Suite *s = suite_create ("SCEW lists");
354
355 /* Setup items */
356 unsigned int i = 0;
357 for (i = 0; i < N_ELEMENTS_; ++i)
358 {
359 data_[i].value = i;
360 }
361
362 /* Core test case */
363 TCase *tc_core = tcase_create ("Core");
364 tcase_add_test (tc_core, test_alloc);
365 tcase_add_test (tc_core, test_accessors);
366 tcase_add_test (tc_core, test_append);
367 tcase_add_test (tc_core, test_prepend);
368 tcase_add_test (tc_core, test_delete);
369 tcase_add_test (tc_core, test_traverse);
370 tcase_add_test (tc_core, test_traverse_foreach);
371 tcase_add_test (tc_core, test_search);
372 suite_add_tcase (s, tc_core);
373
374 return s;
375 }
376
377 void
run_tests(SRunner * sr)378 run_tests (SRunner *sr)
379 {
380 srunner_add_suite (sr, list_suite ());
381 }
382