RList
|
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 }