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