1 #include <test.h>
2
3 #include <string.h>
4 #include <list.c>
5 #include <list.h>
6
7 // Simple initialization test
test_initList(void)8 static void test_initList(void)
9 {
10 List *list = NULL;
11 list = ListNew(NULL, NULL, NULL);
12 assert_true(list != NULL);
13 assert_int_not_equal(list, NULL);
14 assert_int_equal(list->first, NULL);
15 assert_int_equal(list->list, NULL);
16 assert_int_equal(list->last, NULL);
17 assert_int_equal(list->node_count, 0);
18 assert_int_equal(list->state, 0);
19 // We shouldn't use this function yet, but otherwise we leak memory
20 assert_int_equal(ListDestroy(&list), 0);
21 }
22
23 // This function is just an example function for the destroyer
24 #include <stdio.h>
testDestroyer(void * element)25 void testDestroyer(void *element) {
26 // We know the elements are just char *
27 char *s = (char *)element;
28 printf("element: %s \n", s);
29 free (s);
30 }
31
test_destroyer(void)32 static void test_destroyer(void)
33 {
34 List *list = NULL;
35 list = ListNew(NULL, NULL, testDestroyer);
36 assert_true(list != NULL);
37 assert_int_not_equal(list, NULL);
38 assert_int_equal(list->first, NULL);
39 assert_int_equal(list->list, NULL);
40 assert_int_equal(list->last, NULL);
41 assert_int_equal(list->node_count, 0);
42 assert_int_equal(list->state, 0);
43 assert_int_equal(list->compare, NULL);
44 assert_int_equal(list->copy, NULL);
45 assert_int_not_equal(list->destroy, NULL);
46
47 char *element0 = xstrdup("this is a test string");
48 char *element1 = xstrdup("another test string");
49 char *element2 = xstrdup("yet another test string");
50 char *element3 = xstrdup("and one more test string");
51
52 // We add element0 to the list.
53 assert_int_equal(ListPrepend(list, element0), 0);
54 // We add element1 to the list.
55 assert_int_equal(ListPrepend(list, element1), 0);
56 // We add element2 to the list.
57 assert_int_equal(ListPrepend(list, element2), 0);
58 // We add element3 to the list.
59 assert_int_equal(ListPrepend(list, element3), 0);
60
61 // Now we try to destroy the list.
62 assert_int_equal(ListDestroy(&list), 0);
63 }
64
test_prependToList(void)65 static void test_prependToList(void)
66 {
67 List *list = NULL;
68 list = ListNew(NULL, NULL, testDestroyer);
69 assert_true(list != NULL);
70 assert_int_not_equal(list, NULL);
71 assert_int_equal(list->first, NULL);
72 assert_int_equal(list->list, NULL);
73 assert_int_equal(list->last, NULL);
74 assert_int_equal(list->node_count, 0);
75 assert_int_equal(list->state, 0);
76 assert_int_equal(list->compare, NULL);
77 assert_int_equal(list->copy, NULL);
78 assert_int_not_equal(list->destroy, NULL);
79
80 char *element0 = xstrdup("this is a test string");
81 char *element1 = xstrdup("another test string");
82 void *listPointer = NULL;
83 void *firstPointer = NULL;
84 void *lastPointer = NULL;
85
86 // We add element0 to the list.
87 assert_int_equal(ListPrepend(list, element0), 0);
88 // Now we check the list
89 assert_int_not_equal(list->first, NULL);
90 firstPointer = list->first;
91 assert_int_not_equal(list->list, NULL);
92 listPointer = list->list;
93 assert_true(list->list == list->first);
94 assert_int_not_equal(list->last, NULL);
95 lastPointer = list->last;
96 assert_int_equal(list->node_count, 1);
97 // Adding elements does not change the state of the list
98 assert_int_equal(list->state, 0);
99
100 // We add element1 to the list.
101 assert_int_equal(ListPrepend(list, element1), 0);
102 // Now we check the list
103 assert_int_not_equal(list->first, NULL);
104 assert_false(list->first == firstPointer);
105 assert_int_not_equal(list->list, NULL);
106 assert_false(list->list == listPointer);
107 assert_int_not_equal(list->last, NULL);
108 assert_true(list->last == lastPointer);
109 assert_int_equal(list->node_count, 2);
110 assert_int_equal(list->state, 0);
111
112 // Now we try to destroy the list. This should fail because the list is not empty
113 assert_int_equal(ListDestroy(&list), 0);
114 }
115
test_appendToList(void)116 static void test_appendToList(void)
117 {
118 List *list = NULL;
119 list = ListNew(NULL, NULL, testDestroyer);
120 assert_true(list != NULL);
121 assert_int_not_equal(list, NULL);
122 assert_int_equal(list->first, NULL);
123 assert_int_equal(list->list, NULL);
124 assert_int_equal(list->last, NULL);
125 assert_int_equal(list->node_count, 0);
126 assert_int_equal(list->state, 0);
127
128 char *element0 = xstrdup("this is a test string");
129 char *element1 = xstrdup("another test string");
130 void *element0tPointer = NULL;
131
132 // We add element0 to the list.
133 assert_int_equal(ListAppend(list, element0), 0);
134 // Now we check the list
135 assert_int_not_equal(list->first, NULL);
136 element0tPointer = list->first;
137 assert_int_not_equal(list->list, NULL);
138 assert_true(list->list == list->first);
139 assert_int_not_equal(list->last, NULL);
140 assert_true(list->last == list->first);
141 assert_int_equal(list->node_count, 1);
142 // Adding elements does not change the list state
143 assert_int_equal(list->state, 0);
144
145 // We add element1 to the list.
146 assert_int_equal(ListAppend(list, element1), 0);
147 // Now we check the list
148 assert_int_not_equal(list->first, NULL);
149 assert_int_not_equal(list->list, NULL);
150 assert_int_not_equal(list->last, NULL);
151 assert_true(element0tPointer == list->list);
152 assert_true(element0tPointer == list->first);
153 assert_false(list->first == list->last);
154 assert_int_equal(list->node_count, 2);
155 assert_int_equal(list->state, 0);
156
157 // Now we try to destroy the list. This should fail because the list is not empty
158 assert_int_equal(ListDestroy(&list), 0);
159 }
160
compareFunction(const void * a,const void * b)161 static int compareFunction(const void *a, const void *b)
162 {
163 return strcmp(a, b);
164 }
165
copyFunction(const void * s,void ** d)166 static void copyFunction(const void *s, void **d)
167 {
168 if (!s || !d)
169 return;
170 const char *source = s;
171 char **destination = (char **)d;
172
173 *destination = xstrdup(source);
174 }
175
176
test_removeFromList(void)177 static void test_removeFromList(void)
178 {
179 List *list = NULL;
180 list = ListNew(compareFunction, NULL, testDestroyer);
181 assert_true(list != NULL);
182 assert_int_not_equal(list, NULL);
183 assert_int_equal(list->first, NULL);
184 assert_int_equal(list->list, NULL);
185 assert_int_equal(list->last, NULL);
186 assert_int_equal(list->node_count, 0);
187 assert_int_equal(list->state, 0);
188 assert_int_not_equal(list->destroy, NULL);
189 assert_int_not_equal(list->compare, NULL);
190 assert_int_equal(list->copy, NULL);
191
192 char *element0 = xstrdup("this is a test string");
193 char *element1 = xstrdup("another test string");
194 char *element2 = xstrdup("yet another test string");
195 char *element3 = xstrdup("and one more test string");
196 char *element4 = xstrdup("non existing element");
197 void *listPointer = NULL;
198 void *firstPointer = NULL;
199 void *secondPointer = NULL;
200 void *thirdPointer = NULL;
201 void *lastPointer = NULL;
202
203 // We add element0 to the list.
204 assert_int_equal(ListPrepend(list, element0), 0);
205 // Now we check the list
206 assert_int_not_equal(list->first, NULL);
207 firstPointer = list->first;
208 assert_int_not_equal(list->list, NULL);
209 listPointer = list->list;
210 assert_true(list->list == list->first);
211 assert_int_not_equal(list->last, NULL);
212 lastPointer = list->last;
213 assert_int_equal(list->node_count, 1);
214 // Adding elements does not change the list state
215 assert_int_equal(list->state, 0);
216
217 // We add element1 to the list.
218 assert_int_equal(ListPrepend(list, element1), 0);
219 // Now we check the list
220 assert_int_not_equal(list->first, NULL);
221 assert_false(list->first == firstPointer);
222 assert_int_not_equal(list->list, NULL);
223 assert_false(list->list == listPointer);
224 assert_true(list->list == list->first);
225 secondPointer = list->list;
226 assert_int_not_equal(list->last, NULL);
227 assert_true(list->last == lastPointer);
228 assert_int_equal(list->node_count, 2);
229 assert_int_equal(list->state, 0);
230
231 // We add element2 to the list.
232 assert_int_equal(ListPrepend(list, element2), 0);
233 // Now we check the list
234 assert_int_not_equal(list->first, NULL);
235 assert_false(list->first == firstPointer);
236 assert_int_not_equal(list->list, NULL);
237 assert_false(list->list == listPointer);
238 assert_true(list->list == list->first);
239 thirdPointer = list->list;
240 assert_int_not_equal(list->last, NULL);
241 assert_true(list->last == lastPointer);
242 assert_int_equal(list->node_count, 3);
243 assert_int_equal(list->state, 0);
244
245 // We add element3 to the list.
246 assert_int_equal(ListPrepend(list, element3), 0);
247 // Now we check the list
248 assert_int_not_equal(list->first, NULL);
249 assert_false(list->first == firstPointer);
250 assert_int_not_equal(list->list, NULL);
251 assert_false(list->list == listPointer);
252 assert_true(list->list == list->first);
253 assert_int_not_equal(list->last, NULL);
254 assert_true(list->last == lastPointer);
255 assert_int_equal(list->node_count, 4);
256 assert_int_equal(list->state, 0);
257
258 // We remove the non existing element
259 assert_int_equal(ListRemove(list, element4), -1);
260 assert_int_not_equal(list->first, NULL);
261 assert_false(list->first == firstPointer);
262 assert_int_not_equal(list->list, NULL);
263 assert_false(list->list == listPointer);
264 assert_true(list->list == list->first);
265 assert_int_not_equal(list->last, NULL);
266 assert_true(list->last == lastPointer);
267 assert_int_equal(list->node_count, 4);
268 assert_int_equal(list->state, 0);
269
270 // Remove element1 which is in the middle of the list
271 assert_int_equal(ListRemove(list, element1), 0);
272 // Now we check the list
273 assert_int_not_equal(list->first, NULL);
274 assert_false(list->first == firstPointer);
275 assert_int_not_equal(list->list, NULL);
276 assert_false(list->list == listPointer);
277 assert_true(list->list == list->first);
278 assert_int_not_equal(list->last, NULL);
279 assert_true(list->last == lastPointer);
280 assert_int_equal(list->node_count, 3);
281 assert_int_equal(list->state, 1);
282
283 // Remove element3 which is at the beginning of the list
284 assert_int_equal(ListRemove(list, element3), 0);
285 // Now we check the list
286 assert_int_not_equal(list->first, NULL);
287 assert_false(list->first == secondPointer);
288 assert_int_not_equal(list->list, NULL);
289 assert_false(list->list == listPointer);
290 assert_true(list->list == list->first);
291 assert_int_not_equal(list->last, NULL);
292 assert_true(list->last == lastPointer);
293 assert_int_equal(list->node_count, 2);
294 assert_int_equal(list->state, 2);
295
296 // Remove element0 which is at the end of the list
297 assert_int_equal(ListRemove(list, element0), 0);
298 // Now we check the list
299 assert_int_not_equal(list->first, NULL);
300 assert_false(list->first == secondPointer);
301 assert_int_not_equal(list->list, NULL);
302 assert_false(list->list == listPointer);
303 assert_true(list->list == list->first);
304 assert_int_not_equal(list->last, NULL);
305 assert_true(list->last == thirdPointer);
306 assert_int_equal(list->node_count, 1);
307 assert_int_equal(list->state, 3);
308
309 // Remove element2 which is the only element on the list
310 assert_int_equal(ListRemove(list, element2), 0);
311 // Now we check the list
312 assert_int_equal(list->first, NULL);
313 assert_int_equal(list->list, NULL);
314 assert_int_equal(list->last, NULL);
315 assert_int_equal(list->node_count, 0);
316 assert_int_equal(list->state, 4);
317
318 // Now we destroy the list.
319 assert_int_equal(ListDestroy(&list), 0);
320 free (element4);
321 }
322
test_destroyList(void)323 static void test_destroyList(void)
324 {
325 List *list = NULL;
326 list = ListNew(NULL, NULL, testDestroyer);
327 assert_true(list != NULL);
328 assert_int_not_equal(list, NULL);
329 assert_int_equal(list->first, NULL);
330 assert_int_equal(list->list, NULL);
331 assert_int_equal(list->last, NULL);
332 assert_int_equal(list->node_count, 0);
333 assert_int_equal(list->state, 0);
334
335 // Now we destroy the list
336 assert_int_equal(ListDestroy(&list), 0);
337 assert_int_equal(list, NULL);
338 }
339
test_copyList(void)340 static void test_copyList(void)
341 {
342 /*
343 * First try the normal path, i.e. with a copy function. Then try it without a copy function.
344 */
345 List *list1 = NULL;
346 List *list2 = NULL;
347 List *list3 = NULL;
348 List *list4 = NULL;
349 char *element0 = xstrdup("this is a test string");
350 char *element1 = xstrdup("another test string");
351 char *element2 = xstrdup("yet another test string");
352
353 list1 = ListNew(compareFunction, copyFunction, testDestroyer);
354 assert_true(list1 != NULL);
355 assert_int_not_equal(list1, NULL);
356 assert_int_equal(list1->first, NULL);
357 assert_int_equal(list1->list, NULL);
358 assert_int_equal(list1->last, NULL);
359 assert_int_equal(list1->node_count, 0);
360 assert_int_equal(list1->state, 0);
361 assert_int_equal(0, ListPrepend(list1, (void *)element0));
362 assert_int_equal(1, ListCount(list1));
363 /*
364 * Copy the list1 to list2 and prepend one more element
365 */
366 assert_int_equal(0, ListCopy(list1, &list2));
367 assert_int_equal(1, ListCount(list2));
368 assert_true(list1->ref_count == list2->ref_count);
369 assert_int_equal(0, ListPrepend(list2, (void *)element1));
370 /*
371 * The two lists have detached now.
372 */
373 assert_int_equal(1, ListCount(list1));
374 assert_int_equal(2, ListCount(list2));
375 assert_false(list1->ref_count == list2->ref_count);
376 /*
377 * Add one more element to list1 and then attach list3 and list4.
378 * Finally detach list4 by removing one element.
379 */
380 assert_int_equal(0, ListPrepend(list1, (void *)element2));
381 assert_int_equal(0, ListCopy(list1, &list3));
382 assert_int_equal(0, ListCopy(list1, &list4));
383 assert_int_equal(2, ListCount(list1));
384 assert_int_equal(2, ListCount(list3));
385 assert_int_equal(2, ListCount(list4));
386 assert_true(list1->ref_count == list3->ref_count);
387 assert_true(list1->ref_count == list4->ref_count);
388 assert_true(list4->ref_count == list3->ref_count);
389 assert_int_equal(0, ListRemove(list4, (void *)element0));
390 assert_int_equal(2, ListCount(list1));
391 assert_int_equal(2, ListCount(list3));
392 assert_int_equal(1, ListCount(list4));
393 assert_true(list1->ref_count == list3->ref_count);
394 assert_false(list1->ref_count == list4->ref_count);
395 assert_false(list4->ref_count == list3->ref_count);
396
397 assert_int_equal(ListDestroy(&list1), 0);
398 assert_int_equal(ListDestroy(&list2), 0);
399 assert_int_equal(ListDestroy(&list3), 0);
400 assert_int_equal(ListDestroy(&list4), 0);
401 /*
402 * No copy function now, boys don't cry
403 */
404 List *list5 = NULL;
405 List *list6 = NULL;
406 element0 = xstrdup("this is a test string");
407
408 list5 = ListNew(compareFunction, NULL, testDestroyer);
409 assert_true(list5 != NULL);
410 assert_int_not_equal(list5, NULL);
411 assert_int_equal(list5->first, NULL);
412 assert_int_equal(list5->list, NULL);
413 assert_int_equal(list5->last, NULL);
414 assert_int_equal(list5->node_count, 0);
415 assert_int_equal(list5->state, 0);
416 assert_int_equal(0, ListPrepend(list5, (void *)element0));
417 assert_int_equal(1, ListCount(list5));
418 /*
419 * Copy the list5 to list6 and prepend one more element
420 */
421 assert_int_equal(-1, ListCopy(list5, &list6));
422 assert_true(list6 == NULL);
423
424 assert_int_equal(ListDestroy(&list5), 0);
425 }
426
test_iterator(void)427 static void test_iterator(void)
428 {
429 List *list = NULL;
430 list = ListNew(compareFunction, NULL, testDestroyer);
431 assert_true(list != NULL);
432 assert_int_not_equal(list, NULL);
433 assert_int_equal(list->first, NULL);
434 assert_int_equal(list->list, NULL);
435 assert_int_equal(list->last, NULL);
436 assert_int_equal(list->node_count, 0);
437 assert_int_equal(list->state, 0);
438
439 ListIterator *emptyListIterator = NULL;
440 emptyListIterator = ListIteratorGet(list);
441 assert_true(emptyListIterator == NULL);
442 char *element0 = xstrdup("this is a test string");
443 char *element1 = xstrdup("another test string");
444 char *element2 = xstrdup("yet another test string");
445 char *element3 = xstrdup("and one more test string");
446 void *element0Pointer = NULL;
447 void *element1Pointer = NULL;
448 void *element2Pointer = NULL;
449 void *element3Pointer = NULL;
450
451 // We add element0 to the list.
452 assert_int_equal(ListPrepend(list, element0), 0);
453 // Now we check the list
454 assert_int_not_equal(list->first, NULL);
455 element0Pointer = list->first;
456 assert_true(list->first == element0Pointer);
457 assert_int_not_equal(list->list, NULL);
458 assert_true(list->list == list->first);
459 assert_int_not_equal(list->last, NULL);
460 assert_int_equal(list->node_count, 1);
461 assert_int_equal(list->state, 0);
462
463 // We add element1 to the list.
464 assert_int_equal(ListPrepend(list, element1), 0);
465 // Now we check the list
466 assert_int_not_equal(list->first, NULL);
467 assert_false(list->first == element0Pointer);
468 assert_int_not_equal(list->list, NULL);
469 element1Pointer = list->list;
470 assert_true(list->first == element1Pointer);
471 assert_int_not_equal(list->last, NULL);
472 assert_true(list->last == element0Pointer);
473 assert_int_equal(list->node_count, 2);
474 assert_int_equal(list->state, 0);
475
476 // We add element2 to the list.
477 assert_int_equal(ListPrepend(list, element2), 0);
478 // Now we check the list
479 assert_int_not_equal(list->first, NULL);
480 assert_false(list->first == element1Pointer);
481 assert_int_not_equal(list->list, NULL);
482 element2Pointer = list->list;
483 assert_true(list->first == element2Pointer);
484 assert_int_not_equal(list->last, NULL);
485 assert_true(list->last == element0Pointer);
486 assert_int_equal(list->node_count, 3);
487 assert_int_equal(list->state, 0);
488
489 // We add element3 to the list.
490 assert_int_equal(ListPrepend(list, element3), 0);
491 // Now we check the list
492 assert_int_not_equal(list->first, NULL);
493 assert_false(list->first == element2Pointer);
494 assert_int_not_equal(list->list, NULL);
495 element3Pointer = list->list;
496 assert_true(list->first == element3Pointer);
497 assert_int_not_equal(list->last, NULL);
498 assert_true(list->last == element0Pointer);
499 assert_int_equal(list->node_count, 4);
500 assert_int_equal(list->state, 0);
501
502 ListIterator *iterator0 = NULL;
503 iterator0 = ListIteratorGet(list);
504 // Check the iterator
505 assert_true(iterator0 != NULL);
506 assert_int_equal(iterator0->state, 0);
507 assert_true(iterator0->origin == list);
508 assert_true(iterator0->current == list->first);
509
510 // Remove element1 which is in the middle of the list, this will invalidate the iterator
511 assert_int_equal(ListRemove(list, element1), 0);
512 // Check that the iterator is not valid by trying to advance it
513 assert_int_equal(ListIteratorNext(iterator0), -1);
514 // Destroy the iterator
515 assert_int_equal(ListIteratorDestroy(&iterator0), 0);
516 assert_int_equal(iterator0, NULL);
517
518 // Create a new iterator and move it
519 ListIterator *iterator1 = NULL;
520 iterator1 = ListIteratorGet(list);
521 // Check the iterator
522 assert_int_not_equal(iterator1, NULL);
523 assert_int_equal(iterator1->state, 1);
524 assert_true(iterator1->origin == list);
525 assert_true(iterator1->current == list->first);
526 void *value = NULL;
527 value = ListIteratorData(iterator1);
528 assert_true(value == element3);
529
530 // Advance it
531 assert_int_equal(ListIteratorNext(iterator1), 0);
532 // Check the value, it should be equal to element2
533 value = ListIteratorData(iterator1);
534 assert_true(value == element2);
535
536 // Advance it, now we are at the last element
537 assert_int_equal(ListIteratorNext(iterator1), 0);
538 // Check the value, it should be equal to element0
539 value = ListIteratorData(iterator1);
540 assert_true(value == element0);
541
542 // Advance it, should fail and the iterator should stay where it was
543 assert_int_equal(ListIteratorNext(iterator1), -1);
544 // Check the value, it should be equal to element0
545 value = ListIteratorData(iterator1);
546 assert_true(value == element0);
547
548 // Go back
549 assert_int_equal(ListIteratorPrevious(iterator1), 0);
550 // Check the value, it should be equal to element2
551 value = ListIteratorData(iterator1);
552 assert_true(value == element2);
553
554 // Go back, now we are at the beginning of the list
555 assert_int_equal(ListIteratorPrevious(iterator1), 0);
556 // Check the value, it should be equal to element3
557 value = ListIteratorData(iterator1);
558 assert_true(value == element3);
559
560 // Go back, should fail and the iterator should stay where it was
561 assert_int_equal(ListIteratorPrevious(iterator1), -1);
562 // Check the value, it should be equal to element3
563 value = ListIteratorData(iterator1);
564 assert_true(value == element3);
565
566 // Jump to the last element
567 assert_int_equal(ListIteratorLast(iterator1), 0);
568 // Check the value, it should be equal to element0
569 value = ListIteratorData(iterator1);
570 assert_true(value == element0);
571
572 // Go back
573 assert_true(ListIteratorHasPrevious(iterator1));
574 assert_int_equal(ListIteratorPrevious(iterator1), 0);
575 // Check the value, it should be equal to element2
576 value = ListIteratorData(iterator1);
577 assert_true(value == element2);
578
579 // Jump to the first element
580 assert_int_equal(ListIteratorFirst(iterator1), 0);
581 // Check the value, it should be equal to element3
582 value = ListIteratorData(iterator1);
583 assert_true(value == element3);
584
585 // Advance it
586 assert_true(ListIteratorHasNext(iterator1));
587 assert_int_equal(ListIteratorNext(iterator1), 0);
588 // Check the value, it should be equal to element2
589 value = ListIteratorData(iterator1);
590 assert_true(value == element2);
591
592 // Remove the elements
593 assert_int_equal(ListRemove(list, element3), 0);
594 assert_int_equal(ListRemove(list, element0), 0);
595 assert_int_equal(ListRemove(list, element2), 0);
596
597 // Destroy the iterator
598 assert_int_equal(ListIteratorDestroy(&iterator1), 0);
599 // Now we destroy the list.
600 assert_int_equal(ListDestroy(&list), 0);
601 }
602
test_mutableIterator(void)603 static void test_mutableIterator(void)
604 {
605 List *list = NULL;
606 list = ListNew(compareFunction, NULL, testDestroyer);
607 assert_true(list != NULL);
608 assert_int_not_equal(list, NULL);
609 assert_int_equal(list->first, NULL);
610 assert_int_equal(list->list, NULL);
611 assert_int_equal(list->last, NULL);
612 assert_int_equal(list->node_count, 0);
613 assert_int_equal(list->state, 0);
614
615 ListMutableIterator *emptyListIterator = NULL;
616 emptyListIterator = ListMutableIteratorGet(list);
617 assert_true(emptyListIterator == NULL);
618 char *element0 = xstrdup("this is a test string");
619 char *element1 = xstrdup("another test string");
620 char *element2 = xstrdup("yet another test string");
621 char *element3 = xstrdup("and one more test string");
622 char *element4 = xstrdup("prepended by iterator");
623 char *element5 = xstrdup("appended by iterator");
624 char *element6 = xstrdup("appended by iterator, second time");
625 char *element7 = xstrdup("prepended by iterator, second time");
626
627 // We add element0 to the list.
628 assert_int_equal(ListAppend(list, element0), 0);
629 // We add element1 to the list.
630 assert_int_equal(ListAppend(list, element1), 0);
631 // We add element2 to the list.
632 assert_int_equal(ListAppend(list, element2), 0);
633 // We add element3 to the list.
634 assert_int_equal(ListAppend(list, element3), 0);
635
636 // We use a light iterator to check that is valid
637 ListIterator *lightIterator = NULL;
638 lightIterator = ListIteratorGet(list);
639 ListMutableIterator *iterator = NULL;
640 ListMutableIterator *secondIterator = NULL;
641 iterator = ListMutableIteratorGet(list);
642 assert_true(iterator != NULL);
643 // The iterator should be pointing to the first element
644 assert_true(iterator->current == list->first);
645 // Trying to create a second iterator must fail
646 secondIterator = ListMutableIteratorGet(list);
647 assert_true(secondIterator == NULL);
648 // Loop through the list until we get to the last element and then back
649 while (ListMutableIteratorHasNext(iterator))
650 {
651 assert_int_equal(0, ListMutableIteratorNext(iterator));
652 }
653 assert_int_equal(-1, ListMutableIteratorNext(iterator));
654 // and back
655 while (ListMutableIteratorHasPrevious(iterator))
656 {
657 assert_int_equal(0, ListMutableIteratorPrevious(iterator));
658 }
659 assert_int_equal(-1, ListMutableIteratorPrevious(iterator));
660 // Jump to the last element
661 assert_int_equal(0, ListMutableIteratorLast(iterator));
662 // and back to the first element
663 assert_int_equal(0, ListMutableIteratorFirst(iterator));
664 // Prepend one element at the beginning of the list
665 assert_int_equal(0, ListMutableIteratorPrepend(iterator, (void *)element4));
666 assert_int_equal(5, list->node_count);
667 // The light iterator is still valid
668 assert_int_equal(list->state, lightIterator->state);
669 // It should be possible to go back one element now.
670 assert_int_equal(0, ListMutableIteratorPrevious(iterator));
671 // Check that the list and the iterator agree who is the first one.
672 assert_true(list->first == iterator->current);
673 // Append one element after the first element
674 assert_int_equal(0, ListMutableIteratorAppend(iterator, (void *)element5));
675 assert_int_equal(6, list->node_count);
676 // The light iterator is still valid
677 assert_int_equal(list->state, lightIterator->state);
678 // Loop through the list until we get to the last element and then back
679 while (ListMutableIteratorHasNext(iterator))
680 {
681 assert_int_equal(0, ListMutableIteratorNext(iterator));
682 }
683 assert_int_equal(-1, ListMutableIteratorNext(iterator));
684 // and back
685 while (ListMutableIteratorHasPrevious(iterator))
686 {
687 assert_int_equal(0, ListMutableIteratorPrevious(iterator));
688 }
689 assert_int_equal(-1, ListMutableIteratorPrevious(iterator));
690 // Jump to the last element
691 assert_int_equal(0, ListMutableIteratorLast(iterator));
692 // and back to the first element
693 assert_int_equal(0, ListMutableIteratorFirst(iterator));
694 // And back to the last element
695 assert_int_equal(0, ListMutableIteratorLast(iterator));
696 // Append one element after the last element
697 assert_int_equal(0, ListMutableIteratorAppend(iterator, (void *)element6));
698 assert_int_equal(7, list->node_count);
699 // The light iterator is still valid
700 assert_int_equal(list->state, lightIterator->state);
701 // It should be possible to advance one position
702 assert_int_equal(0, ListMutableIteratorNext(iterator));
703 // Check that both the list and the iterator point to the same last element
704 assert_true(iterator->current == list->last);
705 // Prepend one element before the last element
706 assert_int_equal(0, ListMutableIteratorPrepend(iterator, (void *)element7));
707 assert_int_equal(8, list->node_count);
708 // The light iterator is still valid
709 assert_int_equal(list->state, lightIterator->state);
710 // Go back one element and remove the element
711 assert_int_equal(0, ListMutableIteratorPrevious(iterator));
712 // We should be located at element4
713 assert_string_equal(element7, (char *)iterator->current->payload);
714 // Remove the current element
715 assert_int_equal(0, ListMutableIteratorRemove(iterator));
716 // Check that the list agrees
717 assert_int_equal(7, list->node_count);
718 // We should be at element5 now, the last element of the list
719 assert_string_equal(element6, (char *)iterator->current->payload);
720 assert_true(iterator->current == list->last);
721 // The light iterator is not valid anymore
722 assert_false(list->state == lightIterator->state);
723 // Remove the last element, we should go back to element3
724 assert_int_equal(0, ListMutableIteratorRemove(iterator));
725 // Check that the list agrees
726 assert_int_equal(6, list->node_count);
727 // We should be at element3 now, the last element of the list
728 assert_string_equal(element3, (char *)iterator->current->payload);
729 assert_true(iterator->current == list->last);
730 // Jump to the first element of the list
731 assert_int_equal(0, ListMutableIteratorFirst(iterator));
732 // Remove the first element, we should end up in element5
733 assert_int_equal(0, ListMutableIteratorRemove(iterator));
734 // Check that the list agrees
735 assert_int_equal(5, list->node_count);
736 // We should be at element5 now, the first element of the list
737 assert_string_equal(element5, (char *)iterator->current->payload);
738 assert_true(iterator->current == list->first);
739 // Now remove element3, the last element of the list using the Remove function
740 assert_int_equal(0, ListRemove(list, (void *)element3));
741 assert_int_equal(4, list->node_count);
742 // We should be at element5 now, the first element of the list
743 assert_string_equal(element5, (char *)iterator->current->payload);
744 assert_true(iterator->current == list->first);
745 // Jump to the last element of the list
746 assert_int_equal(0, ListMutableIteratorLast(iterator));
747 // This should be element2
748 assert_string_equal(element2, (char *)iterator->current->payload);
749 // Move the iterator to the previous element, element1, and delete it. The iterator should move to element2.
750 assert_int_equal(0, ListMutableIteratorPrevious(iterator));
751 assert_int_equal(0, ListRemove(list, (void *)element1));
752 assert_int_equal(3, list->node_count);
753 assert_string_equal(element2, (char *)iterator->current->payload);
754 assert_true(iterator->current == list->last);
755 // Remove the last element of the list, the iterator should move to element0
756 assert_int_equal(0, ListRemove(list, (void *)element2));
757 assert_int_equal(2, list->node_count);
758 assert_string_equal(element0, (char *)iterator->current->payload);
759 assert_true(iterator->current == list->last);
760 // Jump to the first element
761 assert_int_equal(0, ListMutableIteratorFirst(iterator));
762 // Remove the first element, that should move the iterator to element0
763 assert_int_equal(0, ListRemove(list, (void *)element5));
764 assert_int_equal(1, list->node_count);
765 assert_string_equal(element0, (char *)iterator->current->payload);
766 assert_true(iterator->current == list->last);
767 assert_true(iterator->current == list->first);
768 // Finally try to remove the only element using the iterator, it should fail.
769 assert_int_equal(-1, ListMutableIteratorRemove(iterator));
770 // Remove the final element using the list and check that the iterator is invalid
771 assert_int_equal(0, ListRemove(list, (void *)element0));
772 assert_false(iterator->valid);
773 // Destroy the iterators and the list
774 assert_int_equal(0, ListMutableIteratorRelease(&iterator));
775 assert_int_equal(0, ListIteratorDestroy(&lightIterator));
776 assert_int_equal(0, ListDestroy(&list));
777 }
778
main()779 int main()
780 {
781 PRINT_TEST_BANNER();
782 const UnitTest tests[] =
783 {
784 unit_test(test_initList)
785 , unit_test(test_destroyList)
786 , unit_test(test_destroyer)
787 , unit_test(test_prependToList)
788 , unit_test(test_appendToList)
789 , unit_test(test_removeFromList)
790 , unit_test(test_copyList)
791 , unit_test(test_iterator)
792 , unit_test(test_mutableIterator)
793 };
794
795 return run_tests(tests);
796 }
797