unit1300.c 9.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275
  1. /***************************************************************************
  2. * _ _ ____ _
  3. * Project ___| | | | _ \| |
  4. * / __| | | | |_) | |
  5. * | (__| |_| | _ <| |___
  6. * \___|\___/|_| \_\_____|
  7. *
  8. * Copyright (C) Daniel Stenberg, <daniel@haxx.se>, et al.
  9. *
  10. * This software is licensed as described in the file COPYING, which
  11. * you should have received as part of this distribution. The terms
  12. * are also available at https://curl.se/docs/copyright.html.
  13. *
  14. * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  15. * copies of the Software, and permit persons to whom the Software is
  16. * furnished to do so, under the terms of the COPYING file.
  17. *
  18. * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
  19. * KIND, either express or implied.
  20. *
  21. * SPDX-License-Identifier: curl
  22. *
  23. ***************************************************************************/
  24. #include "curlcheck.h"
  25. #include "llist.h"
  26. static struct Curl_llist llist;
  27. static struct Curl_llist llist_destination;
  28. static void test_Curl_llist_dtor(void *key, void *value)
  29. {
  30. /* used by the llist API, does nothing here */
  31. (void)key;
  32. (void)value;
  33. }
  34. static CURLcode unit_setup(void)
  35. {
  36. Curl_llist_init(&llist, test_Curl_llist_dtor);
  37. Curl_llist_init(&llist_destination, test_Curl_llist_dtor);
  38. return CURLE_OK;
  39. }
  40. static void unit_stop(void)
  41. {
  42. }
  43. UNITTEST_START
  44. {
  45. int unusedData_case1 = 1;
  46. int unusedData_case2 = 2;
  47. int unusedData_case3 = 3;
  48. struct Curl_llist_node case1_list;
  49. struct Curl_llist_node case2_list;
  50. struct Curl_llist_node case3_list;
  51. struct Curl_llist_node case4_list;
  52. struct Curl_llist_node *head;
  53. struct Curl_llist_node *element_next;
  54. struct Curl_llist_node *element_prev;
  55. struct Curl_llist_node *to_remove;
  56. size_t llist_size = Curl_llist_count(&llist);
  57. /**
  58. * testing llist_init
  59. * case 1:
  60. * list initiation
  61. * @assumptions:
  62. * 1: list size will be 0
  63. * 2: list head will be NULL
  64. * 3: list tail will be NULL
  65. * 4: list dtor will be NULL
  66. */
  67. fail_unless(Curl_llist_count(&llist) == 0,
  68. "list initial size should be zero");
  69. fail_unless(Curl_llist_head(&llist) == NULL,
  70. "list head should initiate to NULL");
  71. fail_unless(Curl_llist_tail(&llist) == NULL,
  72. "list tail should initiate to NULL");
  73. /**
  74. * testing Curl_llist_insert_next
  75. * case 1:
  76. * list is empty
  77. * @assumptions:
  78. * 1: list size will be 1
  79. * 2: list head will hold the data "unusedData_case1"
  80. * 3: list tail will be the same as list head
  81. */
  82. Curl_llist_insert_next(&llist, Curl_llist_head(&llist), &unusedData_case1,
  83. &case1_list);
  84. fail_unless(Curl_llist_count(&llist) == 1,
  85. "List size should be 1 after adding a new element");
  86. /* test that the list head data holds my unusedData */
  87. fail_unless(Curl_node_elem(Curl_llist_head(&llist)) == &unusedData_case1,
  88. "head ptr should be first entry");
  89. /* same goes for the list tail */
  90. fail_unless(Curl_llist_tail(&llist) == Curl_llist_head(&llist),
  91. "tail and head should be the same");
  92. /**
  93. * testing Curl_llist_insert_next
  94. * case 2:
  95. * list has 1 element, adding one element after the head
  96. * @assumptions:
  97. * 1: the element next to head should be our newly created element
  98. * 2: the list tail should be our newly created element
  99. */
  100. Curl_llist_insert_next(&llist, Curl_llist_head(&llist),
  101. &unusedData_case3, &case3_list);
  102. fail_unless(Curl_node_elem(Curl_node_next(Curl_llist_head(&llist))) ==
  103. &unusedData_case3,
  104. "the node next to head is not getting set correctly");
  105. fail_unless(Curl_node_elem(Curl_llist_tail(&llist)) == &unusedData_case3,
  106. "the list tail is not getting set correctly");
  107. /**
  108. * testing Curl_llist_insert_next
  109. * case 3:
  110. * list has >1 element, adding one element after "NULL"
  111. * @assumptions:
  112. * 1: the element next to head should be our newly created element
  113. * 2: the list tail should different from newly created element
  114. */
  115. Curl_llist_insert_next(&llist, Curl_llist_head(&llist),
  116. &unusedData_case2, &case2_list);
  117. fail_unless(Curl_node_elem(Curl_node_next(Curl_llist_head(&llist))) ==
  118. &unusedData_case2,
  119. "the node next to head is not getting set correctly");
  120. /* better safe than sorry, check that the tail isn't corrupted */
  121. fail_unless(Curl_node_elem(Curl_llist_tail(&llist)) != &unusedData_case2,
  122. "the list tail is not getting set correctly");
  123. /* unit tests for Curl_node_remove */
  124. /**
  125. * case 1:
  126. * list has >1 element, removing head
  127. * @assumptions:
  128. * 1: list size will be decremented by one
  129. * 2: head will be the head->next
  130. * 3: "new" head's previous will be NULL
  131. */
  132. head = Curl_llist_head(&llist);
  133. abort_unless(head, "llist.head is NULL");
  134. element_next = Curl_node_next(head);
  135. llist_size = Curl_llist_count(&llist);
  136. Curl_node_remove(Curl_llist_head(&llist));
  137. fail_unless(Curl_llist_count(&llist) == (llist_size-1),
  138. "llist size not decremented as expected");
  139. fail_unless(Curl_llist_head(&llist) == element_next,
  140. "llist new head not modified properly");
  141. abort_unless(Curl_llist_head(&llist), "llist.head is NULL");
  142. fail_unless(Curl_node_prev(Curl_llist_head(&llist)) == NULL,
  143. "new head previous not set to null");
  144. /**
  145. * case 2:
  146. * removing non head element, with list having >=2 elements
  147. * @setup:
  148. * 1: insert another element to the list to make element >=2
  149. * @assumptions:
  150. * 1: list size will be decremented by one ; tested
  151. * 2: element->previous->next will be element->next
  152. * 3: element->next->previous will be element->previous
  153. */
  154. Curl_llist_insert_next(&llist, Curl_llist_head(&llist), &unusedData_case3,
  155. &case4_list);
  156. llist_size = Curl_llist_count(&llist);
  157. fail_unless(llist_size == 3, "should be 3 list members");
  158. to_remove = Curl_node_next(Curl_llist_head(&llist));
  159. abort_unless(to_remove, "to_remove is NULL");
  160. element_next = Curl_node_next(to_remove);
  161. element_prev = Curl_node_prev(to_remove);
  162. Curl_node_uremove(to_remove, NULL);
  163. fail_unless(Curl_node_next(element_prev) == element_next,
  164. "element previous->next is not being adjusted");
  165. abort_unless(element_next, "element_next is NULL");
  166. fail_unless(Curl_node_prev(element_next) == element_prev,
  167. "element next->previous is not being adjusted");
  168. /**
  169. * case 3:
  170. * removing the tail with list having >=1 element
  171. * @assumptions
  172. * 1: list size will be decremented by one ;tested
  173. * 2: element->previous->next will be element->next ;tested
  174. * 3: element->next->previous will be element->previous ;tested
  175. * 4: list->tail will be tail->previous
  176. */
  177. to_remove = Curl_llist_tail(&llist);
  178. element_prev = Curl_node_prev(to_remove);
  179. Curl_node_remove(to_remove);
  180. fail_unless(Curl_llist_tail(&llist) == element_prev,
  181. "llist tail is not being adjusted when removing tail");
  182. /**
  183. * case 4:
  184. * removing head with list having 1 element
  185. * @assumptions:
  186. * 1: list size will be decremented by one ;tested
  187. * 2: list head will be null
  188. * 3: list tail will be null
  189. */
  190. to_remove = Curl_llist_head(&llist);
  191. Curl_node_remove(to_remove);
  192. fail_unless(Curl_llist_head(&llist) == NULL,
  193. "llist head is not NULL while the llist is empty");
  194. fail_unless(Curl_llist_tail(&llist) == NULL,
  195. "llist tail is not NULL while the llist is empty");
  196. /**
  197. * testing Curl_llist_append
  198. * case 1:
  199. * list is empty
  200. * @assumptions:
  201. * 1: the element next to head should be our newly created element
  202. * 2: the list tail should different from newly created element
  203. */
  204. Curl_llist_append(&llist, &unusedData_case1, &case1_list);
  205. fail_unless(Curl_llist_count(&llist) == 1,
  206. "List size should be 1 after appending a new element");
  207. /* test that the list head data holds my unusedData */
  208. fail_unless(Curl_node_elem(Curl_llist_head(&llist)) == &unusedData_case1,
  209. "head ptr should be first entry");
  210. /* same goes for the list tail */
  211. fail_unless(Curl_llist_tail(&llist) == Curl_llist_head(&llist),
  212. "tail and head should be the same");
  213. /**
  214. * testing Curl_llist_append
  215. * case 2:
  216. * list is not empty
  217. * @assumptions:
  218. * 1: the list head-next should be the newly created element
  219. * 2: the list tail should be the newly created element
  220. */
  221. Curl_llist_append(&llist, &unusedData_case2, &case2_list);
  222. fail_unless(Curl_node_elem(Curl_node_next(Curl_llist_head(&llist))) ==
  223. &unusedData_case2,
  224. "the node next to head is not getting set correctly");
  225. fail_unless(Curl_node_elem(Curl_llist_tail(&llist)) == &unusedData_case2,
  226. "the list tail is not getting set correctly");
  227. /**
  228. * testing Curl_llist_append
  229. * case 3:
  230. * list is has 2 members
  231. * @assumptions:
  232. * 1: the list head-next should remain the same
  233. * 2: the list tail should be the newly created element
  234. */
  235. Curl_llist_append(&llist, &unusedData_case3, &case3_list);
  236. fail_unless(Curl_node_elem(Curl_node_next(Curl_llist_head(&llist))) ==
  237. &unusedData_case2,
  238. "the node next to head did not stay the same");
  239. fail_unless(Curl_node_elem(Curl_llist_tail(&llist)) == &unusedData_case3,
  240. "the list tail is not getting set correctly");
  241. Curl_llist_destroy(&llist, NULL);
  242. Curl_llist_destroy(&llist_destination, NULL);
  243. }
  244. UNITTEST_STOP