1 /*
2  * Copyright (c) 2019 LK Trusty Authors. All Rights Reserved.
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining
5  * a copy of this software and associated documentation files
6  * (the "Software"), to deal in the Software without restriction,
7  * including without limitation the rights to use, copy, modify, merge,
8  * publish, distribute, sublicense, and/or sell copies of the Software,
9  * and to permit persons to whom the Software is furnished to do so,
10  * subject to the following conditions:
11  *
12  * The above copyright notice and this permission notice shall be
13  * included in all copies or substantial portions of the Software.
14  *
15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
18  * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
19  * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
20  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
21  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22  */
23 
24 #include <lk/list.h>
25 
26 #include "gtest/gtest.h"
27 
28 /**
29  * CheckListArray - check that a list contains specific items.
30  * @list:   The list to check.
31  * @items:  Array with expected items.
32  * @count:  Number if entries in @items, and expected number of entries in
33  *          @list.
34  *
35  * Check that @list contains the all the entries in @items, in the same order,
36  * and no other entries. Also check that head, tail, next and prev functions
37  * return the expected entries in @items.
38  */
CheckListArray(struct list_node * list,struct list_node * items[],int count)39 static void CheckListArray(struct list_node *list, struct list_node *items[],
40                            int count) {
41     struct list_node *node;
42     int i = 0;
43 
44     struct list_node *head_item = count ? items[0] : NULL;
45     EXPECT_EQ(list_peek_head(list), head_item) << "List has wrong head";
46 
47     struct list_node *tail_item = count ? items[count - 1] : NULL;
48     EXPECT_EQ(list_peek_tail(list), tail_item) << "List has wrong tail";
49 
50     list_for_every(list, node) {
51         ASSERT_GT(count, i) << "List has more items than expected";
52         EXPECT_EQ(node, items[i]) << "Wrong entry as index " << i;
53 
54         struct list_node *prev_item = i > 0 ? items[i - 1] : NULL;
55         EXPECT_EQ(list_prev(list, node), prev_item) <<
56             "List has wrong back pointer at index " << i;
57 
58         struct list_node *next_item = i < count - 1 ? items[i + 1] : NULL;
59         EXPECT_EQ(list_next(list, node), next_item) <<
60             "List has wrong next pointer at index " << i;
61         i++;
62     }
63     EXPECT_EQ(i, count) << "List has fewer items than expected";
64 }
65 
66 #define ArraySize(a) (sizeof(a) / sizeof((a)[0]))
67 
68 /**
69  * CheckList - Helper macro to call CheckListArray.
70  */
71 #define CheckList(list, items...) { \
72     SCOPED_TRACE("CheckList"); \
73     struct list_node *itemarray[] = {items}; \
74     CheckListArray(list, itemarray, ArraySize(itemarray)); \
75 }
76 
77 /**
78  * DefineEmptyList - Helper macro to define and initialize a list.
79  */
80 #define DefineEmptyList(list) \
81     struct list_node list = LIST_INITIAL_VALUE(list);
82 
83 /**
84  * DefineAndAddListItem - Helper macro to define and initialize a list entry and
85  *                        add it to a list.
86  */
87 #define DefineAndAddListItem(list, item) \
88     struct list_node item = LIST_INITIAL_CLEARED_VALUE; \
89     list_add_tail(&list, &item);
90 
91 /**
92  * DefineListWith1Item - Helper macro to define and initialize a list with 1
93  *                       item.
94  */
95 #define DefineListWith1Item(list, item1) \
96     DefineEmptyList(list) \
97     DefineAndAddListItem(list, item1) \
98     CheckList(&list, &item1)
99 
100 /**
101  * DefineListWith2Items - Helper macro to define and initialize a list with 2
102  *                        items.
103  */
104 #define DefineListWith2Items(list, item1, item2) \
105     DefineListWith1Item(list, item1) \
106     DefineAndAddListItem(list, item2) \
107     CheckList(&list, &item1, &item2)
108 
109 /**
110  * DefineListWith3Items - Helper macro to define and initialize a list with 3
111  *                        items.
112  */
113 #define DefineListWith3Items(list, item1, item2, item3) \
114     DefineListWith2Items(list, item1, item2) \
115     DefineAndAddListItem(list, item3) \
116     CheckList(&list, &item1, &item2, &item3)
117 
118 /* Smoke test 3 list init methods */
TEST(ListTest,ListInitialValue)119 TEST(ListTest, ListInitialValue) {
120     struct list_node list = LIST_INITIAL_VALUE(list);
121     EXPECT_TRUE(list_in_list(&list));
122     EXPECT_TRUE(list_is_empty(&list));
123     CheckList(&list);
124 }
125 
TEST(ListTest,ListInitialClearedValue)126 TEST(ListTest, ListInitialClearedValue) {
127     struct list_node list = LIST_INITIAL_CLEARED_VALUE;
128     EXPECT_FALSE(list_in_list(&list));
129 }
130 
TEST(ListTest,ListInitialize)131 TEST(ListTest, ListInitialize) {
132     struct list_node list;
133     list_initialize(&list);
134     EXPECT_TRUE(list_in_list(&list));
135     EXPECT_TRUE(list_is_empty(&list));
136 }
137 
138 /* Test 4 list add methods */
TEST(ListTest,ListAddHead)139 TEST(ListTest, ListAddHead) {
140     struct list_node list = LIST_INITIAL_VALUE(list);
141     struct list_node item1 = LIST_INITIAL_CLEARED_VALUE;
142     struct list_node item2 = LIST_INITIAL_CLEARED_VALUE;
143 
144     list_add_head(&list, &item1);
145     CheckList(&list, &item1);
146 
147     list_add_head(&list, &item2);
148     CheckList(&list, &item2, &item1);
149 }
150 
TEST(ListTest,ListAddAfterLast)151 TEST(ListTest, ListAddAfterLast) {
152     DefineListWith1Item(list, item1);
153     struct list_node item2 = LIST_INITIAL_CLEARED_VALUE;
154 
155     list_add_after(&item1, &item2);
156     CheckList(&list, &item1, &item2);
157 }
158 
TEST(ListTest,ListAddAfterNotLast)159 TEST(ListTest, ListAddAfterNotLast) {
160     DefineListWith2Items(list, item1, item2);
161     struct list_node item3 = LIST_INITIAL_CLEARED_VALUE;
162 
163     list_add_after(&item1, &item3);
164     CheckList(&list, &item1, &item3, &item2);
165 }
166 
TEST(ListTest,ListAddTail)167 TEST(ListTest, ListAddTail) {
168     struct list_node list = LIST_INITIAL_VALUE(list);
169     struct list_node item1 = LIST_INITIAL_CLEARED_VALUE;
170     struct list_node item2 = LIST_INITIAL_CLEARED_VALUE;
171 
172     list_add_tail(&list, &item1);
173     CheckList(&list, &item1);
174 
175     list_add_tail(&list, &item2);
176     CheckList(&list, &item1, &item2);
177 }
178 
TEST(ListTest,ListAddBeforeHead)179 TEST(ListTest, ListAddBeforeHead) {
180     DefineListWith1Item(list, item1);
181     struct list_node item2 = LIST_INITIAL_CLEARED_VALUE;
182 
183     list_add_before(&item1, &item2);
184     CheckList(&list, &item2, &item1);
185 }
186 
TEST(ListTest,ListAddBeforeNotHead)187 TEST(ListTest, ListAddBeforeNotHead) {
188     DefineListWith2Items(list, item1, item2);
189     struct list_node item3 = LIST_INITIAL_CLEARED_VALUE;
190 
191     list_add_before(&item2, &item3);
192     CheckList(&list, &item1, &item3, &item2);
193 }
194 
195 /* Test list delete 4 possible configurations of prev and next entries */
TEST(ListTest,ListDeleteOnly)196 TEST(ListTest, ListDeleteOnly) {
197     DefineListWith1Item(list, item);
198     list_delete(&item);
199     EXPECT_FALSE(list_in_list(&item));
200     CheckList(&list);
201 }
202 
TEST(ListTest,ListDeleteFirst)203 TEST(ListTest, ListDeleteFirst) {
204     DefineListWith2Items(list, item1, item2);
205     list_delete(&item1);
206     EXPECT_FALSE(list_in_list(&item1));
207     CheckList(&list, &item2);
208 }
209 
TEST(ListTest,ListDeleteLast)210 TEST(ListTest, ListDeleteLast) {
211     DefineListWith2Items(list, item1, item2);
212     list_delete(&item2);
213     EXPECT_FALSE(list_in_list(&item2));
214     CheckList(&list, &item1);
215 }
216 
TEST(ListTest,ListDeleteMiddle)217 TEST(ListTest, ListDeleteMiddle) {
218     DefineListWith3Items(list, item1, item2, item3);
219     list_delete(&item2);
220     EXPECT_FALSE(list_in_list(&item2));
221     CheckList(&list, &item1, &item3);
222 }
223 
224 /*
225  * Test list_remove_head with 3 possible configurations of empty list, head is
226  * last entry, and head is not the last entry.
227  */
TEST(ListTest,ListRemoveHead)228 TEST(ListTest, ListRemoveHead) {
229     DefineListWith2Items(list, item1, item2);
230     struct list_node *node = list_remove_head(&list);
231     EXPECT_EQ(node, &item1);
232     CheckList(&list, &item2);
233     node = list_remove_head(&list);
234     EXPECT_EQ(node, &item2);
235     CheckList(&list);
236     node = list_remove_head(&list);
237     EXPECT_EQ(node, nullptr);
238     CheckList(&list);
239 }
240 
241 /*
242  * Test list_remove_tail with 3 possible configurations of empty list, tail is
243  * first entry, and tail is not the first entry.
244  */
TEST(ListTest,ListRemoveTail)245 TEST(ListTest, ListRemoveTail) {
246     DefineListWith2Items(list, item1, item2);
247     struct list_node *node = list_remove_tail(&list);
248     EXPECT_EQ(node, &item2);
249     CheckList(&list, &item1);
250     node = list_remove_tail(&list);
251     EXPECT_EQ(node, &item1);
252     CheckList(&list);
253     node = list_remove_tail(&list);
254     EXPECT_EQ(node, nullptr);
255     CheckList(&list);
256 }
257 
258 /*
259  * Test list_peek_head with and without entries in the list.
260  * Use 2 entries to separate tail and head in non-empty test.
261  */
TEST(ListTest,ListPeekHeadEmpty)262 TEST(ListTest, ListPeekHeadEmpty) {
263     struct list_node list = LIST_INITIAL_VALUE(list);
264     struct list_node *node = list_peek_head(&list);
265     EXPECT_EQ(node, nullptr);
266 }
267 
TEST(ListTest,ListPeekHeadNotEmpty)268 TEST(ListTest, ListPeekHeadNotEmpty) {
269     DefineListWith2Items(list, item1, item2);
270     struct list_node *node = list_peek_head(&list);
271     EXPECT_EQ(node, &item1);
272 }
273 
274 /*
275  * Test list_peek_tail with and without entries in the list.
276  * Use 2 entries to separate tail and head in non-empty test.
277  */
TEST(ListTest,ListPeekTailEmpty)278 TEST(ListTest, ListPeekTailEmpty) {
279     struct list_node list = LIST_INITIAL_VALUE(list);
280     struct list_node *node = list_peek_tail(&list);
281     EXPECT_EQ(node, nullptr);
282 }
283 
TEST(ListTest,ListPeekTailNotEmpty)284 TEST(ListTest, ListPeekTailNotEmpty) {
285     DefineListWith2Items(list, item1, item2);
286     struct list_node *node = list_peek_tail(&list);
287     EXPECT_EQ(node, &item2);
288 }
289 
290 /* Test list navigation functions. */
TEST(ListTest,ListPrevHead)291 TEST(ListTest, ListPrevHead) {
292     /*
293      * Calling list_prev on the head should return NULL.
294      */
295     DefineListWith2Items(list, item1, item2);
296     struct list_node *node = list_prev(&list, &item1);
297     EXPECT_EQ(node, nullptr);
298 }
299 
TEST(ListTest,ListPrevNotHead)300 TEST(ListTest, ListPrevNotHead) {
301     /*
302      * Calling list_prev on entries other than the head should return the
303      * previous entry.
304      */
305     DefineListWith2Items(list, item1, item2);
306     struct list_node *node = list_prev(&list, &item2);
307     EXPECT_EQ(node, &item1);
308 }
309 
TEST(ListTest,ListPrevWrapHead)310 TEST(ListTest, ListPrevWrapHead) {
311     /*
312      * Calling list_prev_wrap on the head should return the tail.
313      */
314     DefineListWith2Items(list, item1, item2);
315     struct list_node *node = list_prev_wrap(&list, &item1);
316     EXPECT_EQ(node, &item2);
317 }
318 
TEST(ListTest,ListPrevWrapNotHead)319 TEST(ListTest, ListPrevWrapNotHead) {
320     /*
321      * Calling list_prev_wrap on entries other than the head should return the
322      * previous entry (same as list_prev).
323      */
324     DefineListWith2Items(list, item1, item2);
325     struct list_node *node = list_prev_wrap(&list, &item2);
326     EXPECT_EQ(node, &item1);
327 }
328 
TEST(ListTest,ListPrevWrapEmpty)329 TEST(ListTest, ListPrevWrapEmpty) {
330     /*
331      * Calling list_prev_wrap on the list itself, instead of an entry does not
332      * appear to be a useful operation, but the implemention allows it and
333      * returns NULL in that case.
334      */
335     DefineEmptyList(list);
336     struct list_node *node = list_prev_wrap(&list, &list);
337     EXPECT_EQ(node, nullptr);
338 }
339 
TEST(ListTest,ListNextHead)340 TEST(ListTest, ListNextHead) {
341     /*
342      * Calling list_next on the tail should return NULL.
343      */
344     DefineListWith2Items(list, item1, item2);
345     struct list_node *node = list_next(&list, &item2);
346     EXPECT_EQ(node, nullptr);
347 }
348 
TEST(ListTest,ListNextNotTail)349 TEST(ListTest, ListNextNotTail) {
350     /*
351      * Calling list_next on entries other than the tail should return the next
352      * entry.
353      */
354     DefineListWith2Items(list, item1, item2);
355     struct list_node *node = list_next(&list, &item1);
356     EXPECT_EQ(node, &item2);
357 }
358 
TEST(ListTest,ListNextWrapTail)359 TEST(ListTest, ListNextWrapTail) {
360     /*
361      * Calling list_next_wrap on the tail should return the head.
362      */
363     DefineListWith2Items(list, item1, item2);
364     struct list_node *node = list_next_wrap(&list, &item2);
365     EXPECT_EQ(node, &item1);
366 }
367 
TEST(ListTest,ListNextWrapNotTail)368 TEST(ListTest, ListNextWrapNotTail) {
369     /*
370      * Calling list_next_wrap on entries other than the tail should return the
371      * next entry (same as list_next).
372      */
373     DefineListWith2Items(list, item1, item2);
374     struct list_node *node = list_next_wrap(&list, &item1);
375     EXPECT_EQ(node, &item2);
376 }
377 
TEST(ListTest,ListNextWrapEmpty)378 TEST(ListTest, ListNextWrapEmpty) {
379     /*
380      * Calling list_next_wrap on the list itself, instead of an entry does not
381      * appear to be a useful operation, but the implemention allows it and
382      * returns NULL in that case.
383      */
384     DefineEmptyList(list);
385     struct list_node *node = list_next_wrap(&list, &list);
386     EXPECT_EQ(node, nullptr);
387 }
388 
389 /* Test list iterators */
TEST(ListTest,ListForEvery)390 TEST(ListTest, ListForEvery) {
391     /*
392      * list_for_every should return every entry one by one.
393      */
394     DefineListWith2Items(list, item1, item2);
395     struct list_node *itemarray[] = {&item1, &item2};
396     size_t i = 0;
397     struct list_node *node;
398     list_for_every(&list, node) {
399         ASSERT_LT(i, countof(itemarray));
400         EXPECT_EQ(node, itemarray[i]);
401         i++;
402     }
403     EXPECT_EQ(i, countof(itemarray));
404 }
405 
TEST(ListTest,ListForEverySafe)406 TEST(ListTest, ListForEverySafe) {
407     /*
408      * list_for_every_safe should return every entry one by one even if the
409      * current entry is removed (not tested here).
410      */
411     DefineListWith2Items(list, item1, item2);
412     struct list_node *itemarray[] = {&item1, &item2};
413     size_t i = 0;
414     struct list_node *node;
415     struct list_node *tmp_node;
416     list_for_every_safe(&list, node, tmp_node) {
417         ASSERT_LT(i, countof(itemarray));
418         EXPECT_EQ(node, itemarray[i]);
419         i++;
420     }
421     EXPECT_EQ(i, countof(itemarray));
422 }
423 
TEST(ListTest,ListForEverySafeDeleteAll)424 TEST(ListTest, ListForEverySafeDeleteAll) {
425     /*
426      * list_for_every_safe should return every entry one by one even if the
427      * current entry is removed (tested here).
428      */
429     DefineListWith2Items(list, item1, item2);
430     struct list_node *itemarray[] = {&item1, &item2};
431     size_t i = 0;
432     struct list_node *node;
433     struct list_node *tmp_node;
434     list_for_every_safe(&list, node, tmp_node) {
435         ASSERT_LT(i, countof(itemarray));
436         EXPECT_EQ(node, itemarray[i]);
437         list_delete(node);
438         i++;
439     }
440     EXPECT_EQ(i, countof(itemarray));
441     CheckList(&list);
442 }
443 
TEST(ListTest,ListForEverySafeDeleteSome)444 TEST(ListTest, ListForEverySafeDeleteSome) {
445     /*
446      * list_for_every_safe should return every entry one by one even if the
447      * current entry is removed (tested here).
448      */
449     DefineListWith3Items(list, item1, item2, item3);
450     struct list_node *itemarray[] = {&item1, &item2, &item3};
451     size_t i = 0;
452     struct list_node *node;
453     struct list_node *tmp_node;
454     list_for_every_safe(&list, node, tmp_node) {
455         ASSERT_LT(i, countof(itemarray));
456         EXPECT_EQ(node, itemarray[i]);
457         if (i != 1) {
458             list_delete(node);
459         }
460         i++;
461     }
462     EXPECT_EQ(i, countof(itemarray));
463     CheckList(&list, &item2);
464 }
465 
466 /* Test list empty and count functions */
TEST(ListTest,ListIsEmptyEmpty)467 TEST(ListTest, ListIsEmptyEmpty) {
468     DefineEmptyList(list);
469     EXPECT_TRUE(list_is_empty(&list));
470 }
471 
TEST(ListTest,ListIsEmptyNotEmpty)472 TEST(ListTest, ListIsEmptyNotEmpty) {
473     DefineListWith1Item(list, item);
474     EXPECT_FALSE(list_is_empty(&list));
475 }
476 
TEST(ListTest,ListLengthEmpty)477 TEST(ListTest, ListLengthEmpty) {
478     DefineEmptyList(list);
479     EXPECT_EQ(list_length(&list), 0U);
480 }
481 
TEST(ListTest,ListLength1)482 TEST(ListTest, ListLength1) {
483     DefineListWith1Item(list, item);
484     EXPECT_EQ(list_length(&list), 1U);
485 }
486 
TEST(ListTest,ListLength2)487 TEST(ListTest, ListLength2) {
488     DefineListWith2Items(list, item1, item2);
489     EXPECT_EQ(list_length(&list), 2U);
490 }
491 
492 /* Test list splice operations */
TEST(ListTest,ListSpliceTailBothEmpty)493 TEST(ListTest, ListSpliceTailBothEmpty) {
494     DefineEmptyList(list1);
495     DefineEmptyList(list2);
496     list_splice_tail(&list1, &list2);
497     CheckList(&list1);
498     CheckList(&list2);
499 }
500 
TEST(ListTest,ListSpliceTailSrcEmpty)501 TEST(ListTest, ListSpliceTailSrcEmpty) {
502     DefineListWith2Items(list1, item1, item2);
503     DefineEmptyList(list2);
504     list_splice_tail(&list1, &list2);
505     CheckList(&list1, &item1, &item2);
506     CheckList(&list2);
507 }
508 
TEST(ListTest,ListSpliceTailSrc1Item)509 TEST(ListTest, ListSpliceTailSrc1Item) {
510     DefineListWith2Items(list1, item1, item2);
511     DefineListWith1Item(list2, item3);
512     list_splice_tail(&list1, &list2);
513     CheckList(&list1, &item1, &item2, &item3);
514     CheckList(&list2);
515 }
516 
TEST(ListTest,ListSpliceTailDestEmpty)517 TEST(ListTest, ListSpliceTailDestEmpty) {
518     DefineEmptyList(list1);
519     DefineListWith2Items(list2, item1, item2);
520     list_splice_tail(&list1, &list2);
521     CheckList(&list1, &item1, &item2);
522     CheckList(&list2);
523 }
524 
TEST(ListTest,ListSpliceTailDest1Item)525 TEST(ListTest, ListSpliceTailDest1Item) {
526     DefineListWith1Item(list1, item1);
527     DefineListWith2Items(list2, item2, item3);
528     list_splice_tail(&list1, &list2);
529     CheckList(&list1, &item1, &item2, &item3);
530     CheckList(&list2);
531 }
532 
TEST(ListTest,ListSpliceTail)533 TEST(ListTest, ListSpliceTail) {
534     DefineListWith2Items(list1, item1, item2);
535     DefineListWith2Items(list2, item3, item4);
536     list_splice_tail(&list1, &list2);
537     CheckList(&list1, &item1, &item2, &item3, &item4);
538     CheckList(&list2);
539 }
540 
TEST(ListTest,ListSpliceHeadBothEmpty)541 TEST(ListTest, ListSpliceHeadBothEmpty) {
542     DefineEmptyList(list1);
543     DefineEmptyList(list2);
544     list_splice_head(&list1, &list2);
545     CheckList(&list1);
546     CheckList(&list2);
547 }
548 
TEST(ListTest,ListSpliceHeadSrcEmpty)549 TEST(ListTest, ListSpliceHeadSrcEmpty) {
550     DefineListWith2Items(list1, item1, item2);
551     DefineEmptyList(list2);
552     list_splice_head(&list1, &list2);
553     CheckList(&list1, &item1, &item2);
554     CheckList(&list2);
555 }
556 
TEST(ListTest,ListSpliceHeadSrc1Item)557 TEST(ListTest, ListSpliceHeadSrc1Item) {
558     DefineListWith2Items(list1, item2, item3);
559     DefineListWith1Item(list2, item1);
560     list_splice_head(&list1, &list2);
561     CheckList(&list1, &item1, &item2, &item3);
562     CheckList(&list2);
563 }
564 
TEST(ListTest,ListSpliceHeadDestEmpty)565 TEST(ListTest, ListSpliceHeadDestEmpty) {
566     DefineEmptyList(list1);
567     DefineListWith2Items(list2, item1, item2);
568     list_splice_head(&list1, &list2);
569     CheckList(&list1, &item1, &item2);
570     CheckList(&list2);
571 }
572 
TEST(ListTest,ListSpliceHeadDest1Item)573 TEST(ListTest, ListSpliceHeadDest1Item) {
574     DefineListWith1Item(list1, item3);
575     DefineListWith2Items(list2, item1, item2);
576     list_splice_head(&list1, &list2);
577     CheckList(&list1, &item1, &item2, &item3);
578     CheckList(&list2);
579 }
580 
TEST(ListTest,ListSpliceHead)581 TEST(ListTest, ListSpliceHead) {
582     DefineListWith2Items(list1, item3, item4);
583     DefineListWith2Items(list2, item1, item2);
584     list_splice_head(&list1, &list2);
585     CheckList(&list1, &item1, &item2, &item3, &item4);
586     CheckList(&list2);
587 }
588 
TEST(ListTest,ListSpliceAfter)589 TEST(ListTest, ListSpliceAfter) {
590     DefineListWith2Items(list1, item1, item4);
591     DefineListWith2Items(list2, item2, item3);
592     list_splice_after(&item1, &list2);
593     CheckList(&list1, &item1, &item2, &item3, &item4);
594     CheckList(&list2);
595 }
596 
TEST(ListTest,ListSpliceBefore)597 TEST(ListTest, ListSpliceBefore) {
598     DefineListWith2Items(list1, item1, item4);
599     DefineListWith2Items(list2, item2, item3);
600     list_splice_before(&item4, &list2);
601     CheckList(&list1, &item1, &item2, &item3, &item4);
602     CheckList(&list2);
603 }
604