RList
tests/double.c
00001 /*
00002  * Copyright (c) 2011, Stefan Götz <stefan.goetz@web.de>
00003  * 
00004  * Permission to use, copy, modify, and/or distribute this software for any
00005  * purpose with or without fee is hereby granted, provided that the above
00006  * copyright notice and this permission notice appear in all copies.
00007  * 
00008  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
00009  * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
00010  * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
00011  * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
00012  * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
00013  * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
00014  * PERFORMANCE OF THIS SOFTWARE.
00015  */
00016 
00017 #include <stdlib.h>
00018 #include <string.h>
00019 #include <asm/signal.h>
00020 #include <check.h>
00021 
00022 #include "rlist/double.h"
00023 
00024 START_TEST(test_drl_init_valid)
00025 {
00026     struct drl_list list;
00027     struct drl_list cmp = DRL_INIT;
00028 
00029     drl_init(&list, NULL);
00030 
00031     fail_unless(list.node_count == cmp.node_count && list.free_fn == cmp.free_fn && list.head == cmp.head && list.tail == cmp.tail, NULL);
00032 }
00033 END_TEST
00034 
00035 START_TEST(test_drl_init_valid_free_fn)
00036 {
00037     struct drl_list list;
00038     struct drl_list cmp = DRL_INIT_WITH(free);
00039 
00040     drl_init(&list, free);
00041 
00042     fail_unless(list.node_count == cmp.node_count && list.free_fn == cmp.free_fn && list.head == cmp.head && list.tail == cmp.tail, NULL);
00043 }
00044 END_TEST
00045 
00046 START_TEST(test_drl_size_valid)
00047 {
00048     struct drl_list list = DRL_INIT;
00049 
00050     fail_unless(drl_size(&list) == 0, NULL);
00051 }
00052 END_TEST
00053 
00054 START_TEST(test_drl_first_empty)
00055 {
00056     struct drl_list     list = DRL_INIT;
00057     struct drl_iterator iter;
00058 
00059     fail_unless(drl_first(&list, &iter) == &iter, NULL);
00060     fail_unless(drl_is_eol(&iter), NULL);
00061 }
00062 END_TEST
00063 
00064 START_TEST(test_drl_next_valid)
00065 {
00066     struct drl_list     list = DRL_INIT;
00067     struct drl_iterator iter;
00068 
00069     drl_first(&list, &iter);
00070     drl_insert_before(&iter, &list);
00071     drl_insert_before(&iter, &iter);
00072     
00073     /* get the first node */
00074     drl_first(&list, &iter);
00075     /* get the second node */
00076     fail_unless(drl_next(&iter) == &iter, NULL);
00077     /* is this really the second node in terms of the payload? */
00078     fail_unless(drl_payload(&iter) == &iter, NULL);
00079     /* since there are only two nodes, advance iter again to the end of list */
00080     fail_unless(drl_next(&iter) == &iter, NULL);
00081     /* this must be the end of the list */
00082     fail_unless(drl_is_eol(&iter), NULL);
00083 }
00084 END_TEST
00085 
00086 START_TEST(test_drl_next_eol)
00087 {
00088     struct drl_list     list = DRL_INIT;
00089     struct drl_iterator iter;
00090 
00091     /* get the first node */
00092     drl_first(&list, &iter);
00093     /* does drl_next() work? */
00094     fail_unless(drl_next(&iter) == &iter, NULL);
00095     /* is this (again) the end of the list? */
00096     fail_unless(drl_is_eol(&iter), NULL);
00097 }
00098 END_TEST
00099 
00100 START_TEST(test_drl_prev_valid)
00101 {
00102     struct drl_list     list = DRL_INIT;
00103     struct drl_iterator iter;
00104 
00105     drl_first(&list, &iter);
00106     drl_insert_before(&iter, &list);
00107     drl_insert_before(&iter, &iter);
00108     
00109     /* get the last node */
00110     drl_last(&list, &iter);
00111     /* get the previous node */
00112     fail_unless(drl_prev(&iter) == &iter, NULL);
00113     /* is this really the first node in terms of the payload? */
00114     fail_unless(drl_payload(&iter) == &list, NULL);
00115     /* since there are only two nodes, advance iter again to the end of list */
00116     fail_unless(drl_prev(&iter) == &iter, NULL);
00117     /* this must be the end of the list */
00118     fail_unless(drl_is_eol(&iter), NULL);
00119 }
00120 END_TEST
00121 
00122 START_TEST(test_drl_prev_eol)
00123 {
00124     struct drl_list     list = DRL_INIT;
00125     struct drl_iterator iter;
00126 
00127     /* get the first node */
00128     drl_first(&list, &iter);
00129     /* does drl_prev() work? */
00130     fail_unless(drl_prev(&iter) == &iter, NULL);
00131     /* is this (again) the end of the list? */
00132     fail_unless(drl_is_eol(&iter), NULL);
00133 
00134     /* get the last node */
00135     drl_last(&list, &iter);
00136     /* does drl_prev() work? */
00137     fail_unless(drl_prev(&iter) == &iter, NULL);
00138     /* is this (again) the end of the list? */
00139     fail_unless(drl_is_eol(&iter), NULL);
00140 }
00141 END_TEST
00142 
00143 START_TEST(test_drl_insert_before_empty_list)
00144 {
00145     struct drl_list      list = DRL_INIT;
00146     struct drl_iterator  iter;
00147 
00148     drl_first(&list, &iter);
00149     fail_unless(drl_insert_before(&iter, &iter), NULL);
00150     fail_unless(drl_size(&list) == 1, NULL);
00151     fail_unless(drl_is_eol(&iter), NULL);
00152     fail_unless(drl_payload(drl_first(&list, &iter)) == &iter, NULL);
00153 
00154     drl_del_all(&list);
00155     drl_last(&list, &iter);
00156     fail_unless(drl_insert_before(&iter, &iter), NULL);
00157     fail_unless(drl_size(&list) == 1, NULL);
00158     fail_unless(drl_is_eol(&iter), NULL);
00159     fail_unless(drl_payload(drl_first(&list, &iter)) == &iter, NULL);
00160 
00161     drl_del_all(&list);
00162     drl_last(&list, &iter);
00163     fail_unless(drl_insert_before(&iter, &iter), NULL);
00164     fail_unless(drl_size(&list) == 1, NULL);
00165     fail_unless(drl_is_eol(&iter), NULL);
00166     fail_unless(drl_payload(drl_last(&list, &iter)) == &iter, NULL);
00167 
00168     drl_del_all(&list);
00169     drl_first(&list, &iter);
00170     fail_unless(drl_insert_before(&iter, &iter), NULL);
00171     fail_unless(drl_size(&list) == 1, NULL);
00172     fail_unless(drl_is_eol(&iter), NULL);
00173     fail_unless(drl_payload(drl_last(&list, &iter)) == &iter, NULL);
00174 }
00175 END_TEST
00176 
00177 START_TEST(test_drl_size_insert_before_reverse)
00178 {
00179     /* insert numbers in reverse order into a list and check that order */
00180     unsigned            numbers[] = { 0, 1, 2 , 3, 4, 5, 6, 7 };
00181     const unsigned      SIZE = sizeof(numbers) / sizeof(*numbers);
00182     struct drl_iterator iter;
00183     struct drl_list     list = DRL_INIT;
00184 
00185     for (unsigned idx = 0; idx < SIZE; idx += 1) {
00186         /* sanity check */
00187         fail_unless(drl_size(&list) == idx, NULL);
00188         /* get the first node to insert at the list head */
00189         drl_first(&list, &iter);
00190         /* insert the number at idx */
00191         fail_unless(drl_insert_before(&iter, &numbers[idx]), NULL);
00192         /* sanity check */
00193         fail_unless(drl_size(&list) == (idx + 1), NULL);
00194 
00195         /* get the first node to check it */
00196         drl_first(&list, &iter);
00197         /* check the payload pointer */
00198         fail_unless(drl_payload(&iter) == &numbers[idx], NULL);
00199     }
00200 
00201     /* get the first node to iterate from the list head */
00202     drl_first(&list, &iter);
00203     /* do another pass over the list to check whether it has the intended order */
00204     for (int idx = SIZE - 1; idx >= 0; idx -= 1) {
00205         /* check the payload pointer */
00206         fail_unless(drl_payload(&iter) == &numbers[idx], NULL);
00207         /* get the next node to check it */
00208         drl_next(&iter);
00209     }
00210     /* sanity check: are we at the end of the list as expected? */
00211     fail_unless(drl_is_eol(&iter), NULL);
00212 
00213     /* get the last node to iterate from the list tail */
00214     drl_last(&list, &iter);
00215     /* do another pass over the list to check whether it has the intended order */
00216     for (unsigned idx = 0; idx < SIZE; idx += 1) {
00217         /* check the payload pointer */
00218         fail_unless(drl_payload(&iter) == &numbers[idx], NULL);
00219         /* get the previous node to check it */
00220         drl_prev(&iter);
00221     }
00222     /* sanity check: are we at the end of the list as expected? */
00223     fail_unless(drl_is_eol(&iter), NULL);
00224 }
00225 END_TEST
00226 
00227 START_TEST(test_drl_size_insert_before_forward)
00228 {
00229     /* insert numbers into a list and check their order */
00230     unsigned            numbers[] = { 0, 1, 2 , 3, 4, 5, 6, 7 };
00231     const unsigned      SIZE = sizeof(numbers) / sizeof(*numbers);
00232     struct drl_iterator iter;
00233     struct drl_list     list = DRL_INIT;
00234 
00235     /* get the first node to insert the first element */
00236     drl_first(&list, &iter);
00237     for (unsigned idx = 0; idx < SIZE; idx += 1) {
00238         /* sanity check */
00239         fail_unless(drl_size(&list) == idx, NULL);
00240         /* sanity check: we expect iter to always refer to the end of the list */
00241         fail_unless(drl_is_eol(&iter), NULL);
00242         /* insert the number at idx */
00243         fail_unless(drl_insert_before(&iter, &numbers[idx]), NULL);
00244         /* sanity check */
00245         fail_unless(drl_size(&list) == (idx + 1), NULL);
00246     }
00247 
00248     /* get the first node to iterate from the list head */
00249     drl_first(&list, &iter);
00250     /* do another pass over the list to check whether it has the intended order */
00251     for (unsigned idx = 0; idx < SIZE; idx += 1) {
00252         /* check the payload pointer */
00253         fail_unless(drl_payload(&iter) == &numbers[idx], NULL);
00254         /* get the next node to check it */
00255         drl_next(&iter);
00256     }
00257     /* sanity check: are we at the end of the list as expected? */
00258     fail_unless(drl_is_eol(&iter), NULL);
00259 
00260     /* get the last node to iterate from the list tail */
00261     drl_last(&list, &iter);
00262     /* do another pass over the list to check whether it has the intended order */
00263     for (int idx = SIZE - 1; idx >= 0; idx -= 1) {
00264         /* check the payload pointer */
00265         fail_unless(drl_payload(&iter) == &numbers[idx], NULL);
00266         /* get the next node to check it */
00267         drl_prev(&iter);
00268     }
00269     /* sanity check: are we at the end of the list as expected? */
00270     fail_unless(drl_is_eol(&iter), NULL);
00271 }
00272 END_TEST
00273 
00274 START_TEST(test_drl_size_del_first)
00275 {
00276     const unsigned      SIZE = 16;
00277     struct drl_iterator iter;
00278     struct drl_list     list = DRL_INIT_WITH(free);
00279 
00280     for (unsigned i = 0; i < SIZE; i += 1) {
00281         drl_insert_before(drl_first(&list, &iter), malloc(4));
00282     }
00283     for (unsigned i = SIZE; i > 0; i -= 1) {
00284         fail_unless(drl_size(&list) == i, NULL);
00285         fail_unless(drl_del(drl_first(&list, &iter)) == NULL, NULL);
00286         fail_unless(drl_size(&list) == (i - 1), NULL);
00287     }
00288 }
00289 END_TEST
00290 
00291 START_TEST(test_drl_size_del_last)
00292 {
00293     const unsigned      SIZE = 16;
00294     struct drl_iterator iter;
00295     struct drl_list     list = DRL_INIT_WITH(free);
00296 
00297     for (unsigned i = 0; i < SIZE; i += 1) {
00298         drl_insert_before(drl_first(&list, &iter), malloc(4));
00299     }
00300     for (unsigned i = SIZE; i > 0; i -= 1) {
00301         fail_unless(drl_size(&list) == i, NULL);
00302         fail_unless(drl_del(drl_last(&list, &iter)) == NULL, NULL);
00303         fail_unless(drl_size(&list) == (i - 1), NULL);
00304     }
00305 }
00306 END_TEST
00307 
00308 START_TEST(test_drl_size_del_iterate_forward)
00309 {
00310     const unsigned      SIZE = 16;
00311     struct drl_iterator iter;
00312     struct drl_list     list = DRL_INIT_WITH(free);
00313 
00314     for (unsigned i = 0; i < SIZE; i += 1) {
00315         drl_insert_before(drl_first(&list, &iter), malloc(4));
00316     }
00317     drl_first(&list, &iter);
00318     for (unsigned i = 0; i < SIZE; i += 1) {
00319         fail_unless(drl_del(&iter) == NULL, NULL);
00320         fail_unless(drl_next(&iter) == &iter, NULL);
00321     }
00322     fail_unless(drl_size(&list) == 0, NULL);
00323 }
00324 END_TEST
00325 
00326 START_TEST(test_drl_size_del_iterate_backward)
00327 {
00328     const unsigned      SIZE = 16;
00329     struct drl_iterator iter;
00330     struct drl_list     list = DRL_INIT_WITH(free);
00331 
00332     for (unsigned i = 0; i < SIZE; i += 1) {
00333         drl_insert_before(drl_first(&list, &iter), malloc(4));
00334     }
00335     for (unsigned i = 0; i < SIZE; i += 1) {
00336         fail_unless(drl_del(drl_last(&list, &iter)) == NULL, NULL);
00337     }
00338     fail_unless(drl_size(&list) == 0, NULL);
00339 }
00340 END_TEST
00341 
00342 static void reset_number(void *const payload)
00343 {
00344     *(unsigned *) payload = 0;
00345 }
00346 
00347 START_TEST(test_drl_insert_before_first_next_payload_del_valid)
00348 {
00349     unsigned             numbers[16];
00350     const unsigned       SIZE = sizeof(numbers) / sizeof(numbers[0]);
00351     struct drl_list      list = DRL_INIT_WITH(reset_number);
00352     struct drl_iterator  iter;
00353     struct drl_iterator *tmp;
00354     unsigned             i;
00355 
00356     // fill the numbers array slots with their respective index
00357     for (i = 0; i < SIZE; i += 1) {
00358         numbers[i] = i;
00359     }
00360 
00361     // add numbers from 0..SIZE in reverse order to the list
00362     for (i = 0; i < SIZE; i += 1) {
00363         void *payload;
00364 
00365         fail_unless(drl_insert_before(drl_first(&list, &iter), &numbers[i]), NULL);
00366         // check that the first list element looks as expected
00367         fail_unless(drl_first(&list, &iter) != NULL, NULL);
00368         fail_unless((payload = drl_payload(&iter)) != NULL, NULL);
00369         fail_unless(payload == &numbers[i]);
00370         fail_unless(*(unsigned *) payload == numbers[i]);
00371     }
00372 
00373     // iterate through the list and check whether the nodes refer to the
00374     // numbers array in reverse order
00375     i = SIZE - 1;
00376     for (tmp = drl_first(&list, &iter); !drl_is_eol(tmp); drl_next(tmp)) {
00377         void *payload;
00378 
00379         fail_unless((payload = drl_payload(&iter)) != NULL, NULL);
00380         fail_unless(payload == &numbers[i]);
00381         fail_unless(*(unsigned *) payload == numbers[i]);
00382 
00383         i -= 1;
00384     }
00385 
00386     // iterate through the list and check whether nodes can be deleted in the
00387     // iteration and if the registered call-back function is called
00388     i = SIZE - 1;
00389     for (tmp = drl_first(&list, &iter); !drl_is_eol(tmp); drl_next(tmp)) {
00390         fail_unless(numbers[i] == i, NULL);
00391         fail_unless(drl_del(&iter) == NULL, NULL);
00392         fail_unless(numbers[i] == 0, NULL);
00393 
00394         i -= 1;
00395     }
00396 
00397     fail_unless(drl_size(&list) == 0, NULL);
00398 }
00399 END_TEST
00400 
00401 START_TEST(test_drl_insert_before_null_payload)
00402 {
00403     struct drl_list     list = DRL_INIT_WITH(free);
00404     struct drl_iterator iter;
00405 
00406     fail_unless(drl_insert_before(drl_first(&list, &iter), NULL), NULL);
00407     // check that the first list element looks as expected
00408     fail_unless(drl_first(&list, &iter) != NULL, NULL);
00409     fail_unless(drl_payload(&iter) == NULL, NULL);
00410     // check that the last list element looks as expected
00411     fail_unless(drl_last(&list, &iter) != NULL, NULL);
00412     fail_unless(drl_payload(&iter) == NULL, NULL);
00413 }
00414 END_TEST
00415 
00416 START_TEST(test_drl_del_all_valid)
00417 {
00418     const unsigned      SIZE = 16;
00419     struct drl_iterator iter;
00420     struct drl_list     list = DRL_INIT_WITH(free);
00421 
00422     drl_first(&list, &iter);
00423     for (unsigned i = 0; i < SIZE; i += 1) {
00424         fail_unless(drl_insert_before(&iter, malloc(4)), NULL);
00425     }
00426     fail_unless(drl_size(&list) == SIZE, NULL);
00427     drl_del_all(&list);
00428     fail_unless(drl_size(&list) == 0, NULL);
00429     fail_unless(drl_is_eol(drl_first(&list, &iter)), NULL);
00430     fail_unless(drl_is_eol(drl_last(&list, &iter)), NULL);
00431 }
00432 END_TEST
00433 
00434 static bool match_unsigned(void *const payload,
00435                            void *const context)
00436 {
00437     return *(unsigned *)payload == *(unsigned *)context;
00438 }
00439 
00440 START_TEST(test_drl_find_valid)
00441 {
00442     unsigned numbers[] = { 0, 1, 2, 3, 4, 5, 6, 0 };
00443     unsigned needle = 0;
00444     struct drl_iterator iter;
00445     struct drl_list list = DRL_INIT;
00446     
00447     // append numbers in ascending order
00448     drl_first(&list, &iter);
00449     for (unsigned idx = 0; idx < sizeof(numbers) / sizeof(numbers[0]); idx += 1) {
00450         drl_insert_before(&iter, &numbers[idx]);
00451     }
00452     
00453     drl_first(&list, &iter);
00454     // does drl_find() return a non-NULL value as advertised?
00455     fail_unless(drl_find(&iter, match_unsigned, &needle) != NULL, NULL);
00456     // drl_find() should find something
00457     fail_unless(!drl_is_eol(&iter), NULL);
00458     // drl_find() should find the correct number
00459     fail_unless(drl_payload(&iter) == &numbers[0], NULL);
00460 
00461     // go to the next list node
00462     drl_next(&iter);
00463     // does drl_find() return iter as advertised?
00464     fail_unless(drl_find(&iter, match_unsigned, &needle) == &iter, NULL);
00465     // drl_find() should find something
00466     fail_unless(!drl_is_eol(&iter), NULL);
00467     // drl_find() should find the correct number
00468     fail_unless(drl_payload(&iter) == &numbers[7], NULL);
00469 
00470     // go to the next list node (i.e., EOL)
00471     drl_next(&iter);
00472     // does drl_find() return iter as advertised?
00473     fail_unless(drl_find(&iter, match_unsigned, &needle) == &iter, NULL);
00474     // drl_find() should not find anything
00475     fail_unless(drl_is_eol(&iter), NULL);
00476 
00477     needle = 2;
00478     drl_first(&list, &iter);
00479     // does drl_find() return iter as advertised?
00480     fail_unless(drl_find(&iter, match_unsigned, &needle) == &iter, NULL);
00481     // drl_find() should find something
00482     fail_unless(!drl_is_eol(&iter), NULL);
00483     // drl_find() should find the correct number
00484     fail_unless(drl_payload(&iter) == &numbers[needle], NULL);
00485 
00486     // go to the next list node
00487     drl_next(&iter);
00488     // does drl_find() return iter as advertised?
00489     fail_unless(drl_find(&iter, match_unsigned, &needle) == &iter, NULL);
00490     // drl_find() should not find anything
00491     fail_unless(drl_is_eol(&iter), NULL);
00492 }
00493 END_TEST
00494 
00495 START_TEST(test_drl_find_payload_valid)
00496 {
00497     unsigned numbers[] = { 0, 1, 2, 3, 4, 5, 6, 7 };
00498     struct drl_iterator iter;
00499     struct drl_list list = DRL_INIT;
00500     
00501     // append numbers in ascending order
00502     drl_first(&list, &iter);
00503     for (unsigned idx = 0; idx < sizeof(numbers) / sizeof(numbers[0]); idx += 1) {
00504         drl_insert_before(&iter, &numbers[idx]);
00505     }
00506     
00507     // find '0' from list head
00508     drl_first(&list, &iter);
00509     // does drl_find_payload() return iter as advertised?
00510     fail_unless(drl_find_payload(&iter, &numbers[0]) == &iter, NULL);
00511     // drl_find_payload() should find something
00512     fail_unless(!drl_is_eol(&iter), NULL);
00513     // drl_find_payload() should find the correct number
00514     fail_unless(drl_payload(&iter) == &numbers[0], NULL);
00515 
00516     // find '2' from '0' (== list head)
00517     // does drl_find_payload() return iter as advertised?
00518     fail_unless(drl_find_payload(&iter, &numbers[2]) == &iter, NULL);
00519     // drl_find_payload() should find something
00520     fail_unless(!drl_is_eol(&iter), NULL);
00521     // drl_find_payload() should find the correct number
00522     fail_unless(drl_payload(&iter) == &numbers[2], NULL);
00523 
00524     // find '0' from '2'
00525     // does drl_find_payload() return iter as advertised?
00526     fail_unless(drl_find_payload(&iter, &numbers[0]) == &iter, NULL);
00527     // drl_find_payload() should not find anything
00528     fail_unless(drl_is_eol(&iter), NULL);
00529 
00530     // find '7' (last node) from list head
00531     drl_first(&list, &iter);
00532     // does drl_find_payload() return iter as advertised?
00533     fail_unless(drl_find_payload(&iter, &numbers[7]) == &iter, NULL);
00534     // drl_find_payload() should find something
00535     fail_unless(!drl_is_eol(&iter), NULL);
00536     // drl_find_payload() should find the correct number
00537     fail_unless(drl_payload(&iter) == &numbers[7], NULL);
00538 
00539     // find NULL
00540     drl_first(&list, &iter);
00541     // does drl_find_payload() return iter as advertised?
00542     fail_unless(drl_find_payload(&iter, NULL) == &iter, NULL);
00543     // drl_find_payload() should not find anything
00544     fail_unless(drl_is_eol(&iter), NULL);
00545 
00546     // find pointer not in list
00547     drl_first(&list, &iter);
00548     // does drl_find_payload() return iter as advertised?
00549     fail_unless(drl_find_payload(&iter, &iter) == &iter, NULL);
00550     // drl_find_payload() should not find anything
00551     fail_unless(drl_is_eol(&iter), NULL);
00552 }
00553 END_TEST
00554 
00555 static int map_multiply(struct drl_iterator *const iter,
00556                         void *const context)
00557 {
00558     unsigned *const number = drl_payload(iter);
00559     unsigned *const sum = context;
00560     
00561     *number *= 3;
00562     *sum += *number;
00563 
00564     return 0;
00565 }
00566 
00567 static int map_return_one(__attribute__ ((unused)) struct drl_iterator *const iter,
00568                           __attribute__ ((unused)) void *const context)
00569 {
00570     return 1;
00571 }
00572 
00573 static bool match_first_two(__attribute__ ((unused)) void *const payload,
00574                             __attribute__ ((unused)) void *const context)
00575 {
00576     static unsigned invocations = 0;
00577     invocations += 1;
00578     return invocations <= 2;
00579 }
00580 
00581 START_TEST(test_drl_map_valid)
00582 {
00583     unsigned numbers[] = { 0, 1, 2, 3, 4, 5, 6, 7 };
00584     unsigned sum = 0;
00585     struct drl_iterator iter;
00586     struct drl_list list = DRL_INIT;
00587     
00588     // append numbers in ascending order
00589     drl_first(&list, &iter);
00590     for (unsigned idx = 0; idx < sizeof(numbers) / sizeof(numbers[0]); idx += 1) {
00591         drl_insert_before(&iter, &numbers[idx]);
00592     }
00593     
00594     // multiply the values of all list nodes by 3 and store the total in sum
00595     fail_unless(drl_map(drl_first(&list, &iter), map_multiply, &sum, NULL, NULL) == 0, NULL);
00596     // map should have covered the whole list
00597     fail_unless(drl_is_eol(&iter), NULL);
00598     // all numbers in the array should have been multiplied by three
00599     for (unsigned idx = 0; idx < sizeof(numbers) / sizeof(numbers[0]); idx += 1) {
00600         fail_unless(numbers[idx] == idx * 3, NULL);
00601     }
00602     // the sum of the array elements should have been correctly computed by the map function
00603     fail_unless(sum == 84, NULL);
00604     
00605     sum = 0;
00606     // multiply the value of only the second and third list node and store the total sum
00607     fail_unless(drl_map(drl_next(drl_first(&list, &iter)), map_multiply, &sum, match_first_two, NULL) == 0, NULL);
00608     // map should have covered the whole list
00609     fail_unless(drl_is_eol(&iter), NULL);
00610     // the second and third number in the array should have been multiplied by three
00611     fail_unless(numbers[0] == 0);
00612     for (unsigned idx = 1; idx < 3; idx += 1) {
00613         fail_unless(numbers[idx] == idx * 9, NULL);
00614     }
00615     for (unsigned idx = 3; idx < sizeof(numbers) / sizeof(numbers[0]); idx += 1) {
00616         fail_unless(numbers[idx] == idx * 3, NULL);
00617     }
00618     // the sum of the array elements should have been correctly computed by the map function
00619     fail_unless(sum == 27, NULL);
00620     
00621     // does map() return the value the map callback function returns?
00622     fail_unless(drl_map(drl_first(&list, &iter), map_return_one, NULL, NULL, NULL) == 1, NULL);
00623 }
00624 END_TEST
00625 
00626 #ifndef NDEBUG // The following tests rely on assertions being enabled
00627 START_TEST(test_drl_init_null)
00628 {
00629     drl_init(NULL, NULL);
00630 }
00631 END_TEST
00632 
00633 START_TEST(test_drl_size_null)
00634 {
00635     drl_size(NULL);
00636 }
00637 END_TEST
00638 
00639 START_TEST(test_drl_insert_before_null_iter)
00640 {
00641     drl_insert_before(NULL, NULL);
00642 }
00643 END_TEST
00644 
00645 START_TEST(test_drl_first_null_list)
00646 {
00647     struct drl_iterator i;
00648     drl_first(NULL, &i);
00649 }
00650 END_TEST
00651 
00652 START_TEST(test_drl_first_null_iter)
00653 {
00654     struct drl_list l = DRL_INIT;
00655 
00656     drl_first(&l, NULL);
00657 }
00658 END_TEST
00659 
00660 START_TEST(test_drl_next_null)
00661 {
00662     drl_next(NULL);
00663 }
00664 END_TEST
00665 
00666 START_TEST(test_drl_del_null)
00667 {
00668     drl_del(NULL);
00669 }
00670 END_TEST
00671 
00672 START_TEST(test_drl_del_eol)
00673 {
00674     struct drl_list     l = DRL_INIT;
00675     struct drl_iterator i;
00676 
00677     drl_del(drl_first(&l, &i));
00678 }
00679 END_TEST
00680 
00681 START_TEST(test_drl_del_all_null)
00682 {
00683     drl_del_all(NULL);
00684 }
00685 END_TEST
00686 
00687 START_TEST(test_drl_find_iter_null)
00688 {
00689     drl_find(NULL, match_unsigned, NULL);
00690 }
00691 END_TEST
00692 
00693 START_TEST(test_drl_find_match_fn_null)
00694 {
00695     struct drl_list list = DRL_INIT;
00696     struct drl_iterator iter;
00697     
00698     drl_find(drl_first(&list, &iter), NULL, NULL);
00699 }
00700 END_TEST
00701 
00702 START_TEST(test_drl_find_payload_iter_null)
00703 {
00704     drl_find_payload(NULL, NULL);
00705 }
00706 END_TEST
00707 
00708 START_TEST(test_drl_map_iter_null)
00709 {
00710     unsigned sum = 0;
00711 
00712     drl_map(NULL, map_multiply, &sum, match_first_two, NULL);
00713 }
00714 END_TEST
00715 
00716 START_TEST(test_drl_map_map_fn_null)
00717 {
00718     struct drl_list list = DRL_INIT;
00719     struct drl_iterator iter;
00720     drl_map(drl_first(&list, &iter), NULL, NULL, match_first_two, NULL);
00721 }
00722 END_TEST
00723 #endif // NDEBUG
00724 
00725 Suite *drl(void);
00726 
00727 Suite *drl(void)
00728 {
00729     Suite *s = suite_create("double");
00730 
00731     TCase *tc_core = tcase_create("Core");
00732     tcase_add_test(tc_core, test_drl_init_valid);
00733     tcase_add_test(tc_core, test_drl_init_valid_free_fn);
00734     tcase_add_test(tc_core, test_drl_size_valid);
00735     tcase_add_test(tc_core, test_drl_first_empty);
00736     tcase_add_test(tc_core, test_drl_next_valid);
00737     tcase_add_test(tc_core, test_drl_next_eol);
00738     tcase_add_test(tc_core, test_drl_prev_valid);
00739     tcase_add_test(tc_core, test_drl_prev_eol);
00740     tcase_add_test(tc_core, test_drl_insert_before_empty_list);
00741     tcase_add_test(tc_core, test_drl_size_insert_before_reverse);
00742     tcase_add_test(tc_core, test_drl_size_insert_before_forward);
00743     tcase_add_test(tc_core, test_drl_size_del_first);
00744     tcase_add_test(tc_core, test_drl_size_del_last);
00745     tcase_add_test(tc_core, test_drl_size_del_iterate_forward);
00746     tcase_add_test(tc_core, test_drl_size_del_iterate_backward);
00747     tcase_add_test(tc_core, test_drl_insert_before_first_next_payload_del_valid);
00748     tcase_add_test(tc_core, test_drl_insert_before_null_payload);
00749     tcase_add_test(tc_core, test_drl_del_all_valid);
00750     tcase_add_test(tc_core, test_drl_find_valid);
00751     tcase_add_test(tc_core, test_drl_find_payload_valid);
00752     tcase_add_test(tc_core, test_drl_map_valid);
00753 
00754 #ifndef NDEBUG // The following tests rely on assertions being enabled
00755     tcase_add_test_raise_signal(tc_core, test_drl_init_null, SIGABRT);
00756     tcase_add_test_raise_signal(tc_core, test_drl_size_null, SIGABRT);
00757     tcase_add_test_raise_signal(tc_core, test_drl_insert_before_null_iter, SIGABRT);
00758     tcase_add_test_raise_signal(tc_core, test_drl_first_null_list, SIGABRT);
00759     tcase_add_test_raise_signal(tc_core, test_drl_first_null_iter, SIGABRT);
00760     tcase_add_test_raise_signal(tc_core, test_drl_next_null, SIGABRT);
00761     tcase_add_test_raise_signal(tc_core, test_drl_del_null, SIGABRT);
00762     tcase_add_test_raise_signal(tc_core, test_drl_del_eol, SIGABRT);
00763     tcase_add_test_raise_signal(tc_core, test_drl_del_all_null, SIGABRT);
00764     tcase_add_test_raise_signal(tc_core, test_drl_find_iter_null, SIGABRT);
00765     tcase_add_test_raise_signal(tc_core, test_drl_find_match_fn_null, SIGABRT);
00766     tcase_add_test_raise_signal(tc_core, test_drl_find_payload_iter_null, SIGABRT);
00767     tcase_add_test_raise_signal(tc_core, test_drl_map_iter_null, SIGABRT);
00768     tcase_add_test_raise_signal(tc_core, test_drl_map_map_fn_null, SIGABRT);
00769 #endif // NDEBUG
00770 
00771     suite_add_tcase(s, tc_core);
00772 
00773     return s;
00774 }