unit1300.c (9707B)
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 "unitcheck.h" 25 26 #include "llist.h" 27 #include "unitprotos.h" 28 29 static void test_Curl_llist_dtor(void *key, void *value) 30 { 31 /* used by the llist API, does nothing here */ 32 (void)key; 33 (void)value; 34 } 35 36 static CURLcode test_unit1300(char *arg) 37 { 38 UNITTEST_BEGIN_SIMPLE 39 40 struct Curl_llist llist; 41 struct Curl_llist llist_destination; 42 43 int unusedData_case1 = 1; 44 int unusedData_case2 = 2; 45 int unusedData_case3 = 3; 46 struct Curl_llist_node case1_list; 47 struct Curl_llist_node case2_list; 48 struct Curl_llist_node case3_list; 49 struct Curl_llist_node case4_list; 50 struct Curl_llist_node *head; 51 struct Curl_llist_node *element_next; 52 struct Curl_llist_node *element_prev; 53 struct Curl_llist_node *to_remove; 54 size_t llist_size; 55 56 Curl_llist_init(&llist, test_Curl_llist_dtor); 57 Curl_llist_init(&llist_destination, test_Curl_llist_dtor); 58 59 /** 60 * testing llist_init 61 * case 1: 62 * list initiation 63 * @assumptions: 64 * 1: list size will be 0 65 * 2: list head will be NULL 66 * 3: list tail will be NULL 67 * 4: list dtor will be NULL 68 */ 69 70 fail_unless(Curl_llist_count(&llist) == 0, 71 "list initial size should be zero"); 72 fail_unless(Curl_llist_head(&llist) == NULL, 73 "list head should initiate to NULL"); 74 fail_unless(Curl_llist_tail(&llist) == NULL, 75 "list tail should initiate to NULL"); 76 77 /** 78 * testing Curl_llist_insert_next 79 * case 1: 80 * list is empty 81 * @assumptions: 82 * 1: list size will be 1 83 * 2: list head will hold the data "unusedData_case1" 84 * 3: list tail will be the same as list head 85 */ 86 87 Curl_llist_insert_next(&llist, Curl_llist_head(&llist), &unusedData_case1, 88 &case1_list); 89 90 fail_unless(Curl_llist_count(&llist) == 1, 91 "List size should be 1 after adding a new element"); 92 /* test that the list head data holds my unusedData */ 93 fail_unless(Curl_node_elem(Curl_llist_head(&llist)) == &unusedData_case1, 94 "head ptr should be first entry"); 95 /* same goes for the list tail */ 96 fail_unless(Curl_llist_tail(&llist) == Curl_llist_head(&llist), 97 "tail and head should be the same"); 98 99 /** 100 * testing Curl_llist_insert_next 101 * case 2: 102 * list has 1 element, adding one element after the head 103 * @assumptions: 104 * 1: the element next to head should be our newly created element 105 * 2: the list tail should be our newly created element 106 */ 107 108 Curl_llist_insert_next(&llist, Curl_llist_head(&llist), 109 &unusedData_case3, &case3_list); 110 fail_unless(Curl_node_elem(Curl_node_next(Curl_llist_head(&llist))) == 111 &unusedData_case3, 112 "the node next to head is not getting set correctly"); 113 fail_unless(Curl_node_elem(Curl_llist_tail(&llist)) == &unusedData_case3, 114 "the list tail is not getting set correctly"); 115 116 /** 117 * testing Curl_llist_insert_next 118 * case 3: 119 * list has >1 element, adding one element after "NULL" 120 * @assumptions: 121 * 1: the element next to head should be our newly created element 122 * 2: the list tail should different from newly created element 123 */ 124 125 Curl_llist_insert_next(&llist, Curl_llist_head(&llist), 126 &unusedData_case2, &case2_list); 127 fail_unless(Curl_node_elem(Curl_node_next(Curl_llist_head(&llist))) == 128 &unusedData_case2, 129 "the node next to head is not getting set correctly"); 130 /* better safe than sorry, check that the tail isn't corrupted */ 131 fail_unless(Curl_node_elem(Curl_llist_tail(&llist)) != &unusedData_case2, 132 "the list tail is not getting set correctly"); 133 134 /* unit tests for Curl_node_remove */ 135 136 /** 137 * case 1: 138 * list has >1 element, removing head 139 * @assumptions: 140 * 1: list size will be decremented by one 141 * 2: head will be the head->next 142 * 3: "new" head's previous will be NULL 143 */ 144 145 head = Curl_llist_head(&llist); 146 abort_unless(head, "llist.head is NULL"); 147 element_next = Curl_node_next(head); 148 llist_size = Curl_llist_count(&llist); 149 150 Curl_node_remove(Curl_llist_head(&llist)); 151 152 fail_unless(Curl_llist_count(&llist) == (llist_size-1), 153 "llist size not decremented as expected"); 154 fail_unless(Curl_llist_head(&llist) == element_next, 155 "llist new head not modified properly"); 156 abort_unless(Curl_llist_head(&llist), "llist.head is NULL"); 157 fail_unless(Curl_node_prev(Curl_llist_head(&llist)) == NULL, 158 "new head previous not set to null"); 159 160 /** 161 * case 2: 162 * removing non head element, with list having >=2 elements 163 * @setup: 164 * 1: insert another element to the list to make element >=2 165 * @assumptions: 166 * 1: list size will be decremented by one ; tested 167 * 2: element->previous->next will be element->next 168 * 3: element->next->previous will be element->previous 169 */ 170 Curl_llist_insert_next(&llist, Curl_llist_head(&llist), &unusedData_case3, 171 &case4_list); 172 llist_size = Curl_llist_count(&llist); 173 fail_unless(llist_size == 3, "should be 3 list members"); 174 175 to_remove = Curl_node_next(Curl_llist_head(&llist)); 176 abort_unless(to_remove, "to_remove is NULL"); 177 element_next = Curl_node_next(to_remove); 178 element_prev = Curl_node_prev(to_remove); 179 Curl_node_uremove(to_remove, NULL); 180 fail_unless(Curl_node_next(element_prev) == element_next, 181 "element previous->next is not being adjusted"); 182 abort_unless(element_next, "element_next is NULL"); 183 fail_unless(Curl_node_prev(element_next) == element_prev, 184 "element next->previous is not being adjusted"); 185 186 /** 187 * case 3: 188 * removing the tail with list having >=1 element 189 * @assumptions 190 * 1: list size will be decremented by one ;tested 191 * 2: element->previous->next will be element->next ;tested 192 * 3: element->next->previous will be element->previous ;tested 193 * 4: list->tail will be tail->previous 194 */ 195 196 to_remove = Curl_llist_tail(&llist); 197 element_prev = Curl_node_prev(to_remove); 198 Curl_node_remove(to_remove); 199 fail_unless(Curl_llist_tail(&llist) == element_prev, 200 "llist tail is not being adjusted when removing tail"); 201 202 /** 203 * case 4: 204 * removing head with list having 1 element 205 * @assumptions: 206 * 1: list size will be decremented by one ;tested 207 * 2: list head will be null 208 * 3: list tail will be null 209 */ 210 211 to_remove = Curl_llist_head(&llist); 212 Curl_node_remove(to_remove); 213 fail_unless(Curl_llist_head(&llist) == NULL, 214 "llist head is not NULL while the llist is empty"); 215 fail_unless(Curl_llist_tail(&llist) == NULL, 216 "llist tail is not NULL while the llist is empty"); 217 218 /** 219 * testing Curl_llist_append 220 * case 1: 221 * list is empty 222 * @assumptions: 223 * 1: the element next to head should be our newly created element 224 * 2: the list tail should different from newly created element 225 */ 226 Curl_llist_append(&llist, &unusedData_case1, &case1_list); 227 fail_unless(Curl_llist_count(&llist) == 1, 228 "List size should be 1 after appending a new element"); 229 /* test that the list head data holds my unusedData */ 230 fail_unless(Curl_node_elem(Curl_llist_head(&llist)) == &unusedData_case1, 231 "head ptr should be first entry"); 232 /* same goes for the list tail */ 233 fail_unless(Curl_llist_tail(&llist) == Curl_llist_head(&llist), 234 "tail and head should be the same"); 235 236 /** 237 * testing Curl_llist_append 238 * case 2: 239 * list is not empty 240 * @assumptions: 241 * 1: the list head-next should be the newly created element 242 * 2: the list tail should be the newly created element 243 */ 244 Curl_llist_append(&llist, &unusedData_case2, &case2_list); 245 fail_unless(Curl_node_elem(Curl_node_next(Curl_llist_head(&llist))) == 246 &unusedData_case2, 247 "the node next to head is not getting set correctly"); 248 fail_unless(Curl_node_elem(Curl_llist_tail(&llist)) == &unusedData_case2, 249 "the list tail is not getting set correctly"); 250 251 /** 252 * testing Curl_llist_append 253 * case 3: 254 * list is has 2 members 255 * @assumptions: 256 * 1: the list head-next should remain the same 257 * 2: the list tail should be the newly created element 258 */ 259 Curl_llist_append(&llist, &unusedData_case3, &case3_list); 260 fail_unless(Curl_node_elem(Curl_node_next(Curl_llist_head(&llist))) == 261 &unusedData_case2, 262 "the node next to head did not stay the same"); 263 fail_unless(Curl_node_elem(Curl_llist_tail(&llist)) == &unusedData_case3, 264 "the list tail is not getting set correctly"); 265 266 Curl_llist_destroy(&llist, NULL); 267 Curl_llist_destroy(&llist_destination, NULL); 268 269 UNITTEST_END_SIMPLE 270 }