Fri, 18 Nov 2016 15:17:04 +0100
adds ucx_list_append_once() and ucx_list_prepend_once()
1 /*
2 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3 *
4 * Copyright 2016 Olaf Wintermann. All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions are met:
8 *
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 *
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
20 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26 * POSSIBILITY OF SUCH DAMAGE.
27 */
29 #include "list_tests.h"
30 #include "ucx/utils.h"
32 UCX_TEST(test_ucx_list_append) {
33 UcxList *list, *first;
34 list = first = ucx_list_append(NULL, (void*)"Hello");
35 UCX_TEST_BEGIN
37 UCX_TEST_ASSERT(strncmp((const char*)list->data, "Hello", 5) == 0,
38 "failed");
40 list = ucx_list_append(list, (void*)" World!");
42 UCX_TEST_ASSERT(list == first, "does not return first element");
43 UCX_TEST_ASSERT(strncmp((const char*)list->next->data, " World!", 7) == 0,
44 "failed");
45 UCX_TEST_ASSERT(list->next->prev == list, "failed");
46 UCX_TEST_ASSERT(list->next->next == NULL, "failed");
47 UCX_TEST_END
49 ucx_list_free(list);
50 }
52 UCX_TEST(test_ucx_list_prepend) {
53 UcxList *list, *last;
54 list = last = ucx_list_prepend(NULL, (void*)" World!");
55 UCX_TEST_BEGIN
57 list = ucx_list_prepend(list, (void*)"Hello");
59 UCX_TEST_ASSERT(strncmp((const char*)list->data, "Hello", 5) == 0,
60 "failed");
61 UCX_TEST_ASSERT(strncmp((const char*)list->next->data, " World!", 7) == 0,
62 "failed");
63 UCX_TEST_ASSERT(list == last->prev, "does not return first element");
64 UCX_TEST_ASSERT(list->next->next == NULL, "failed");
65 UCX_TEST_ASSERT(list->prev == NULL, "failed");
67 UCX_TEST_END
68 ucx_list_free(list);
69 }
71 UCX_TEST(test_ucx_list_append_once) {
72 UcxList *list, *first;
73 list = first = ucx_list_append_once(NULL, (void*)"Hello", ucx_strcmp, NULL);
74 UCX_TEST_BEGIN
76 UCX_TEST_ASSERT(strncmp((const char*)list->data, "Hello", 5) == 0,
77 "failed");
79 list = ucx_list_append_once(list, (void*)"Hello", ucx_strcmp, NULL);
80 list = ucx_list_append_once(list, (void*)" World!", ucx_strcmp, NULL);
82 UCX_TEST_ASSERT(list == first, "does not return first element");
83 UCX_TEST_ASSERT(strncmp((const char*)list->next->data, " World!", 7) == 0,
84 "'Hello' was not inserted _once_");
85 UCX_TEST_ASSERT(list->next->prev == list, "failed");
86 UCX_TEST_ASSERT(list->next->next == NULL, "right not terminated");
87 UCX_TEST_END
89 ucx_list_free(list);
90 }
92 UCX_TEST(test_ucx_list_prepend_once) {
93 UcxList *list, *last, *first;
94 list = last = ucx_list_prepend_once(NULL, (void*)" World!",
95 ucx_strcmp, NULL);
96 UCX_TEST_BEGIN
98 list = ucx_list_prepend_once(list, (void*)"Hello", ucx_strcmp, NULL);
99 first = ucx_list_prepend_once(list, (void*)"Hello", ucx_strcmp, NULL);
101 UCX_TEST_ASSERT(list == first, "'Hello' was not prepended _once_");
102 UCX_TEST_ASSERT(first == last->prev, "does not return first element");
103 UCX_TEST_ASSERT(strncmp((const char*)list->data, "Hello", 5) == 0,
104 "failed");
105 UCX_TEST_ASSERT(strncmp((const char*)list->next->data, " World!", 7) == 0,
106 "failed");
107 UCX_TEST_ASSERT(list->next->next == NULL, "right not terminated");
108 UCX_TEST_ASSERT(list->prev == NULL, "left not terminated");
110 UCX_TEST_END
111 ucx_list_free(list);
112 }
114 UCX_TEST(test_ucx_list_equals) {
115 const char *hello = "Hello";
116 const char *world = " World!";
117 UcxList *list = ucx_list_append(NULL, (void*)hello);
118 list = ucx_list_append(list, (void*)world);
119 UcxList *list2 = ucx_list_prepend(NULL, (void*)world);
120 list2 = ucx_list_prepend(list2, (void*)hello);
121 UcxList *list3 = ucx_list_prepend(NULL, (void*)" Welt!");
122 list3 = ucx_list_prepend(list3, (void*)"Hallo");
123 UcxList *list4 = ucx_list_prepend(NULL, (void*)" World!");
124 list4 = ucx_list_prepend(list4, (void*)"Hello");
125 UCX_TEST_BEGIN
127 UCX_TEST_ASSERT(ucx_list_equals(list, list4, ucx_strcmp, NULL), "failed");
128 UCX_TEST_ASSERT(!ucx_list_equals(list, list3, ucx_strcmp, NULL), "failed");
129 UCX_TEST_ASSERT(ucx_list_equals(list, list2, NULL, NULL), "failed");
131 UCX_TEST_END
132 ucx_list_free(list4);
133 ucx_list_free(list3);
134 ucx_list_free(list2);
135 ucx_list_free(list);
136 }
138 UCX_TEST(test_ucx_list_concat) {
139 UcxList *list = ucx_list_append(NULL, (void*)"Hello");
140 list = ucx_list_append(list, (void*)" my ");
141 UcxList *list2 = ucx_list_prepend(NULL, (void*)" World!");
142 list2 = ucx_list_prepend(list2, (void*)" sweet ");
143 UCX_TEST_BEGIN
145 list = ucx_list_concat(list, list2);
146 list = ucx_list_concat(list, NULL);
147 list = ucx_list_concat(NULL, list);
149 UCX_TEST_ASSERT(!strncmp((const char*)list->data, "Hello", 5),
150 "failed");
151 UCX_TEST_ASSERT(!strncmp((const char*)list->next->data, " my ", 4),
152 "failed");
153 UCX_TEST_ASSERT(!strncmp((const char*)list->next->next->data, " sweet ", 7),
154 "failed");
155 UCX_TEST_ASSERT(!strncmp((const char*)ucx_list_last(list)->data,
156 " World!", 7), "failed");
158 UCX_TEST_ASSERT(list->prev == NULL, "failed");
160 UCX_TEST_END
161 // don't free list2, as it is freed by freeing list;
162 ucx_list_free(list);
163 }
165 UCX_TEST(test_ucx_list_size) {
166 UcxList *list = ucx_list_append(NULL, (void*)"This ");
167 list = ucx_list_append(list, (void*)"list ");
168 list = ucx_list_append(list, (void*)"has ");
169 list = ucx_list_append(list, (void*)"size ");
170 list = ucx_list_append(list, (void*)"5!");
172 UCX_TEST_BEGIN
174 UCX_TEST_ASSERT(ucx_list_size(list) == 5, "failed");
175 list = ucx_list_remove(list, ucx_list_get(list, 2));
176 UCX_TEST_ASSERT(ucx_list_size(list) == 4, "failed after removal");
178 UCX_TEST_END
179 ucx_list_free(list);
180 }
182 UCX_TEST(test_ucx_list_first) {
183 UcxList *list = ucx_list_append(NULL, (void*)"Find ");
184 list = ucx_list_append(list, (void*)"the ");
185 list = ucx_list_append(list, (void*)"first!");
187 UCX_TEST_BEGIN
189 const char* first = (const char*) (ucx_list_first(list)->data);
191 UCX_TEST_ASSERT(strncmp(first, "Find ", 5) == 0, "failed");
192 UCX_TEST_ASSERT(ucx_list_first(list->next->next) == list, "failed");
193 UCX_TEST_ASSERT(!ucx_list_first(NULL),
194 "does not return NULL on an empty list");
196 UCX_TEST_END
197 ucx_list_free(list);
198 }
200 UCX_TEST(test_ucx_list_last) {
201 UcxList *list = ucx_list_append(NULL, (void*)"Find ");
202 list = ucx_list_append(list, (void*)"the ");
203 list = ucx_list_append(list, (void*)"last!");
205 UCX_TEST_BEGIN
207 const char* last = (const char*) (ucx_list_last(list->next->next)->data);
209 UCX_TEST_ASSERT(strncmp(last, "last!", 5) == 0, "failed");
210 UCX_TEST_ASSERT(ucx_list_last(list) == list->next->next, "failed");
211 UCX_TEST_ASSERT(!ucx_list_last(NULL),
212 "does not return NULL on an empty list");
214 UCX_TEST_END
215 ucx_list_free(list);
216 }
218 UCX_TEST(test_ucx_list_get) {
219 UcxList *list = ucx_list_append(NULL, (void*)"Find ");
220 list = ucx_list_append(list, (void*)"the ");
221 list = ucx_list_append(list, (void*)"mid!");
223 UCX_TEST_BEGIN
225 const char* first = (const char*) (ucx_list_get(list, 0)->data);
226 const char* mid = (const char*) (ucx_list_get(list, 1)->data);
227 const char* last = (const char*) (ucx_list_get(list, 2)->data);
229 UCX_TEST_ASSERT(strncmp(first, "Find ", 5) == 0, "failed");
230 UCX_TEST_ASSERT(strncmp(mid, "the ", 4) == 0, "failed");
231 UCX_TEST_ASSERT(strncmp(last, "mid!", 4) == 0, "failed");
232 UCX_TEST_ASSERT(!ucx_list_get(list, -1), "out of bounds (neg)");
233 UCX_TEST_ASSERT(!ucx_list_get(list, 3), "out of bounds");
234 UCX_TEST_ASSERT(!ucx_list_get(NULL, 0), "empty list");
236 UCX_TEST_END
237 ucx_list_free(list);
238 }
240 UCX_TEST(test_ucx_list_indexof) {
241 UcxList *list = ucx_list_append(NULL, (void*)"Find ");
242 list = ucx_list_append(list, (void*)"the ");
243 list = ucx_list_append(list, (void*)"mid!");
245 UCX_TEST_BEGIN
247 UCX_TEST_ASSERT(ucx_list_indexof(list, list) == 0, "failed");
248 UCX_TEST_ASSERT(ucx_list_indexof(list, list->next) == 1, "failed");
249 UCX_TEST_ASSERT(ucx_list_indexof(list, ucx_list_get(list, 2)) == 2,
250 "failed");
252 UcxList *otherlist = ucx_list_append(NULL, (void*) "the ");
253 UCX_TEST_ASSERT(ucx_list_indexof(list, otherlist) == -1, "failed");
254 UCX_TEST_ASSERT(ucx_list_indexof(NULL, otherlist) == -1, "empty list");
256 ucx_list_free(otherlist);
258 UCX_TEST_END
259 ucx_list_free(list);
260 }
262 UCX_TEST(test_ucx_list_find) {
263 const char* teststr = "string!";
264 UcxList *l = ucx_list_append(NULL, (void*)"find ");
265 l = ucx_list_append(l, (void*)"some ");
266 l = ucx_list_append(l, (void*)teststr);
268 UCX_TEST_BEGIN
270 UCX_TEST_ASSERT(ucx_list_find(l,(void*)"some ",ucx_strcmp,NULL) == 1,
271 "doesn't find string");
272 UCX_TEST_ASSERT(ucx_list_find(l,(void*)"a",ucx_strcmp,NULL) == -1,
273 "finds non-existing string");
275 UCX_TEST_ASSERT(ucx_list_find(l,(void*)teststr,NULL,NULL) == 2,
276 "doesn't find integer without cmp_func");
278 UCX_TEST_ASSERT(ucx_list_find(NULL, (void*)"some ",ucx_strcmp,NULL) == -1,
279 "empty list");
281 UCX_TEST_END
282 ucx_list_free(l);
283 }
285 UCX_TEST(test_ucx_list_contains) {
286 UcxList *l = ucx_list_append(NULL, (void*)"Contains ");
287 l = ucx_list_append(l, (void*)"a ");
288 l = ucx_list_append(l, (void*)"string!");
290 UCX_TEST_BEGIN
292 UCX_TEST_ASSERT(ucx_list_contains(l,(void*)"a ",ucx_strcmp,NULL),
293 "false negative");
294 UCX_TEST_ASSERT(!ucx_list_contains(l,(void*)"a",ucx_strcmp,NULL),
295 "false positive");
297 UCX_TEST_END
298 ucx_list_free(l);
299 }
301 UCX_TEST(test_ucx_list_remove) {
302 UcxList *list = ucx_list_append(NULL, (void*)"Hello");
303 list = ucx_list_append(list, (void*)"fucking");
304 list = ucx_list_append(list, (void*)"World!");
306 UcxList *list2 = ucx_list_append(NULL, (void*)"A");
307 list2 = ucx_list_append(list2, (void*)"B");
308 list2 = ucx_list_append(list2, (void*)"C");
309 list2 = ucx_list_append(list2, (void*)"D");
310 list2 = ucx_list_append(list2, (void*)"E");
311 list2 = ucx_list_append(list2, (void*)"F");
312 list2 = ucx_list_append(list2, (void*)"G");
314 UCX_TEST_BEGIN
316 list = ucx_list_remove(list, ucx_list_get(list, 1));
318 UCX_TEST_ASSERT(strncmp((const char*)list->data, "Hello", 5) == 0,
319 "failed");
320 UCX_TEST_ASSERT(strncmp((const char*)list->next->data, "World!", 7) == 0,
321 "failed");
322 UCX_TEST_ASSERT(list->next->next == NULL, "failed");
324 // remove first element: B, C, D, E, F, G
325 list2 = ucx_list_remove(list2, list2);
327 UCX_TEST_ASSERT(ucx_list_size(list2) == 6, "list2 has wrong size");
328 UCX_TEST_ASSERT(strncmp((const char*)list2->data, "B", 1) == 0,
329 "wrong first element");
330 UCX_TEST_ASSERT(strncmp((const char*)ucx_list_get(list2, 5)->data, "G", 1)
331 == 0, "wrong last element");
333 // remove second element: B, D, E, F, G
334 list2 = ucx_list_remove(list2, list2->next);
336 UCX_TEST_ASSERT(ucx_list_size(list2) == 5, "list2 has wrong size");
337 UCX_TEST_ASSERT(strncmp((const char*)list2->next->data, "D", 1) == 0,
338 "wrong second element");
340 UcxList *last = ucx_list_get(list2, 4);
341 list2 = ucx_list_remove(list2, last->prev);
343 UCX_TEST_ASSERT(ucx_list_size(list2) == 4, "list2 has wrong size");
344 UCX_TEST_ASSERT(strncmp((const char*)last->prev->data, "E", 1) == 0,
345 "wrong element");
347 // remove last element: B, D, E, F
348 list2 = ucx_list_remove(list2, last);
349 UCX_TEST_ASSERT(ucx_list_size(list2) == 3, "list2 has wrong size");
350 UCX_TEST_ASSERT(strncmp((const char*)ucx_list_get(list2, 2)->data, "E", 1)
351 == 0, "wrong last element");
353 UCX_TEST_ASSERT(strncmp((const char*)list2->data, "B", 1) == 0,
354 "wrong element");
356 list2 = ucx_list_remove(list2, list2);
357 UCX_TEST_ASSERT(ucx_list_size(list2) == 2, "list2 has wrong size");
358 list2 = ucx_list_remove(list2, list2);
359 UCX_TEST_ASSERT(ucx_list_size(list2) == 1, "list2 has wrong size");
360 list2 = ucx_list_remove(list2, list2);
361 UCX_TEST_ASSERT(list2 == NULL, "list2 is not null");
363 UCX_TEST_END
364 ucx_list_free(list);
365 }
367 UCX_TEST(test_ucx_list_clone) {
369 char *hello = (char*)malloc(6);
370 char *world = (char*)malloc(8);
372 memcpy(hello, "Hello", 6);
373 memcpy(world, " World!", 8);
375 UcxList *list = ucx_list_append(NULL, hello);
376 list = ucx_list_append(list, world);
378 UcxList *copy = ucx_list_clone(list, ucx_strcpy, NULL);
379 UCX_TEST_BEGIN
381 UCX_TEST_ASSERT(ucx_list_equals(list, copy, ucx_strcmp, NULL), "failed");
382 UCX_TEST_ASSERT(hello != copy->data, "first element is no copy");
383 UCX_TEST_ASSERT(world != copy->next->data, "second element is no copy");
385 UCX_TEST_END
387 ucx_list_free_content(copy, free);
389 free(world);
390 free(hello);
391 ucx_list_free(list);
392 ucx_list_free(copy);
393 }
395 UCX_TEST(test_ucx_list_sort) {
396 UcxList *list = ucx_list_append(NULL, (void*)"this");
397 list = ucx_list_append(list, (void*)"is");
398 list = ucx_list_append(list, (void*)"a");
399 list = ucx_list_append(list, (void*)"test");
400 list = ucx_list_append(list, (void*)"for");
401 list = ucx_list_append(list, (void*)"partial");
402 list = ucx_list_append(list, (void*)"correctness");
403 list = ucx_list_append(list, (void*)"of");
404 list = ucx_list_append(list, (void*)"the");
405 list = ucx_list_append(list, (void*)"sort");
406 list = ucx_list_append(list, (void*)"function");
407 list = ucx_list_append(list, (void*)"that");
408 list = ucx_list_append(list, (void*)"shall");
409 list = ucx_list_append(list, (void*)"pass");
410 list = ucx_list_append(list, (void*)"this");
411 list = ucx_list_append(list, (void*)"test");
413 UcxList *expected = ucx_list_append(NULL, (void*)"a");
414 expected = ucx_list_append(expected, (void*)"correctness");
415 expected = ucx_list_append(expected, (void*)"for");
416 expected = ucx_list_append(expected, (void*)"function");
417 expected = ucx_list_append(expected, (void*)"is");
418 expected = ucx_list_append(expected, (void*)"of");
419 expected = ucx_list_append(expected, (void*)"partial");
420 expected = ucx_list_append(expected, (void*)"pass");
421 expected = ucx_list_append(expected, (void*)"shall");
422 expected = ucx_list_append(expected, (void*)"sort");
423 expected = ucx_list_append(expected, (void*)"test");
424 expected = ucx_list_append(expected, (void*)"test");
425 expected = ucx_list_append(expected, (void*)"that");
426 expected = ucx_list_append(expected, (void*)"the");
427 expected = ucx_list_append(expected, (void*)"this");
428 expected = ucx_list_append(expected, (void*)"this");
430 list = ucx_list_sort(list, ucx_strcmp, NULL);
432 UCX_TEST_BEGIN
433 UCX_TEST_ASSERT(
434 ucx_list_equals(list, expected, ucx_strcmp, NULL), "failed");
435 UCX_TEST_ASSERT(ucx_list_size(list) == 16, "list has now a wrong size");
436 UcxList *l = list;
437 UCX_TEST_ASSERT(l->prev == NULL, "prev field of first entry is not null");
438 while (l->next != NULL) {
439 UCX_TEST_ASSERT(l->next->prev == l, "next or prev pointer corrupted");
440 l = l->next;
441 }
442 UCX_TEST_ASSERT(!ucx_list_sort(NULL, ucx_strcmp, NULL),
443 "failed to sort empty list");
444 UCX_TEST_END
446 ucx_list_free(expected);
447 ucx_list_free(list);
448 }