text: #include <check.h>
  #include <stdlib.h>
  
  #include "list.h"
  
  START_TEST(test_list_new) {
    struct list *lst = list_new();
  
    ck_assert_ptr_eq(lst->head, NULL);
    ck_assert_ptr_eq(lst->tail, NULL);
  
    list_free(lst);
  }
  END_TEST
  
  START_TEST(test_list_add_head) {
    // setup
    int arr[] = {1, 2};
    struct list *lst = list_new();
    struct list_iter iter;
  
    // action
    list_add_head(lst, &arr[0]);
  
    // expectations
    ck_assert_ptr_ne(lst->head, NULL);
    ck_assert_ptr_ne(lst->tail, NULL);
    ck_assert_ptr_eq(lst->head, lst->tail);
  
    iter = list_iter_new(lst, HEAD_TO_TAIL);
    ck_assert_ptr_eq(list_iter_next(&iter), &arr[0]);
    ck_assert_ptr_eq(list_iter_next(&iter), NULL);
  
    // action
    list_add_head(lst, &arr[1]);
  
    // expectations
    ck_assert_ptr_ne(lst->head, NULL);
    ck_assert_ptr_ne(lst->tail, NULL);
    ck_assert_ptr_ne(lst->head, lst->tail);
  
    iter = list_iter_new(lst, HEAD_TO_TAIL);
    ck_assert_ptr_eq(list_iter_next(&iter), &arr[1]);
    ck_assert_ptr_eq(list_iter_next(&iter), &arr[0]);
    ck_assert_ptr_eq(list_iter_next(&iter), NULL);
  
    // teardown
    list_free(lst);
  }
  END_TEST
  
  START_TEST(test_list_add_tail) {
    // setup
    int arr[] = {1, 2};
    struct list *lst = list_new();
    struct list_iter iter;
  
    // action
    list_add_tail(lst, &arr[0]);
  
    // expectations
    ck_assert_ptr_ne(lst->head, NULL);
    ck_assert_ptr_ne(lst->tail, NULL);
    ck_assert_ptr_eq(lst->head, lst->tail);
  
    iter = list_iter_new(lst, TAIL_TO_HEAD);
    ck_assert_ptr_eq(list_iter_next(&iter), &arr[0]);
    ck_assert_ptr_eq(list_iter_next(&iter), NULL);
  
    // action
    list_add_tail(lst, &arr[1]);
  
    // expectations
    ck_assert_ptr_ne(lst->head, NULL);
    ck_assert_ptr_ne(lst->tail, NULL);
    ck_assert_ptr_ne(lst->head, lst->tail);
  
    iter = list_iter_new(lst, TAIL_TO_HEAD);
    ck_assert_ptr_eq(list_iter_next(&iter), &arr[1]);
    ck_assert_ptr_eq(list_iter_next(&iter), &arr[0]);
    ck_assert_ptr_eq(list_iter_next(&iter), NULL);
  
    // teardown
    list_free(lst);
  }
  END_TEST
  
  START_TEST(test_list_get_pos) {
    // setup
    int arr[] = {1, 2};
    struct list *lst = list_new();
  
    // action
    list_add_head(lst, &arr[0]);
    list_add_tail(lst, &arr[1]);
  
    // expectations
    ck_assert_ptr_eq(list_get_pos(lst, 0), &arr[0]);
    ck_assert_ptr_eq(list_get_pos(lst, 1), &arr[1]);
  }
  
  START_TEST(test_list_size) {
    // setup
    int arr[] = {1, 2};
    struct list *lst = list_new();
  
    // expectations
    ck_assert(list_size(lst) == 0);
  
    // action
    list_add_head(lst, &arr[0]);
    list_add_tail(lst, &arr[1]);
  
    // expectations
    ck_assert(list_size(lst) == 2);
  
    // action
    list_remove_pos(lst, 0);
  
    // expectations
    ck_assert(list_size(lst) == 1);
  
    // action
    list_remove_pos(lst, 0);
  
    // expectations
    ck_assert(list_size(lst) == 0);
  }
  
  START_TEST(test_list_remove) {
    // setup
    int arr[] = {1, 2};
    struct list *lst = list_new();
    list_handle h[2];
  
    h[0] = list_add_head(lst, &arr[0]);
    h[1] = list_add_tail(lst, &arr[1]);
  
    // action
    list_remove(lst, h[0]);
  
    // expectations
    ck_assert_ptr_ne(lst->head, NULL);
    ck_assert_ptr_ne(lst->tail, NULL);
    ck_assert_ptr_eq(lst->head, lst->tail);
  
    // action
    list_remove(lst, h[1]);
  
    // expectations
    ck_assert_ptr_eq(lst->head, NULL);
    ck_assert_ptr_eq(lst->tail, NULL);
  
    // teardown
    list_free(lst);
  }
  END_TEST
  
  START_TEST(test_list_remove_pos) {
    // setup
    int arr[] = {1, 2};
    struct list *lst = list_new();
  
    list_add_head(lst, &arr[0]);
    list_add_tail(lst, &arr[1]);
  
    // action
    list_remove_pos(lst, 1);
  
    // expectations
    ck_assert_ptr_ne(lst->head, NULL);
    ck_assert_ptr_ne(lst->tail, NULL);
    ck_assert_ptr_eq(lst->head, lst->tail);
  
    // action
    list_remove_pos(lst, 0);
  
    // expectations
    ck_assert_ptr_eq(lst->head, NULL);
    ck_assert_ptr_eq(lst->tail, NULL);
  
    // teardown
    list_free(lst);
  }
  END_TEST
  
  START_TEST(test_list_iter_remove_1) {
    // setup
    int arr[] = {1, 2};
    struct list *lst = list_new();
  
    list_add_tail(lst, &arr[0]);
    list_add_tail(lst, &arr[1]);
    ck_assert(list_size(lst) == 2);
  
    // action
    void const *item;
    struct list_iter iter = list_iter_new(lst, HEAD_TO_TAIL);
    item = list_iter_next(&iter);
    list_iter_remove(&iter);
  
    // expectations
    ck_assert_ptr_eq(item, &arr[0]);
    ck_assert(list_size(lst) == 1);
  
    // action
    item = list_iter_next(&iter);
    list_iter_remove(&iter);
  
    // expectations
    ck_assert_ptr_eq(item, &arr[1]);
    ck_assert(list_size(lst) == 0);
  
    ck_assert_ptr_eq(lst->head, NULL);
    ck_assert_ptr_eq(lst->tail, NULL);
  
    // teardown
    list_free(lst);
  }
  
  START_TEST(test_list_iter_remove_2) {
    // setup
    int arr[] = {1, 2};
    struct list *lst = list_new();
  
    list_add_tail(lst, &arr[0]);
    list_add_tail(lst, &arr[1]);
    ck_assert(list_size(lst) == 2);
  
    // action
    void const *item;
    struct list_iter iter = list_iter_new(lst, TAIL_TO_HEAD);
    item = list_iter_next(&iter);
    list_iter_remove(&iter);
  
    // expectations
    ck_assert_ptr_eq(item, &arr[1]);
    ck_assert(list_size(lst) == 1);
  
    // action
    item = list_iter_next(&iter);
    list_iter_remove(&iter);
  
    // expectations
    ck_assert_ptr_eq(item, &arr[0]);
    ck_assert(list_size(lst) == 0);
  
    ck_assert_ptr_eq(lst->head, NULL);
    ck_assert_ptr_eq(lst->tail, NULL);
  
    // teardown
    list_free(lst);
  }
  
  START_TEST(test_list_clear) {
    // // setup
    int arr[] = {1, 2};
    struct list *lst = list_new();
  
    list_add_head(lst, &arr[0]);
    list_add_tail(lst, &arr[1]);
  
    // action
    list_clear(lst);
  
    // expectations
    ck_assert_ptr_eq(lst->head, NULL);
    ck_assert_ptr_eq(lst->tail, NULL);
  
    // teardown
    list_free(lst);
  }
  END_TEST
  
  Suite *list_suite(void) {
    TCase *tc_core = tcase_create("Core");
    tcase_add_test(tc_core, test_list_new);
    tcase_add_test(tc_core, test_list_add_head);
    tcase_add_test(tc_core, test_list_add_tail);
    tcase_add_test(tc_core, test_list_get_pos);
    tcase_add_test(tc_core, test_list_size);
    tcase_add_test(tc_core, test_list_remove);
    tcase_add_test(tc_core, test_list_remove_pos);
    tcase_add_test(tc_core, test_list_iter_remove_1);
    tcase_add_test(tc_core, test_list_iter_remove_2);
    tcase_add_test(tc_core, test_list_clear);
  
    Suite *s = suite_create("List");
    suite_add_tcase(s, tc_core);
  
    return s;
  }
  
  int main(void) {
    int number_failed;
    Suite *s;
    SRunner *sr;
  
    s = list_suite();
    sr = srunner_create(s);
  
    srunner_run_all(sr, CK_NORMAL);
    number_failed = srunner_ntests_failed(sr);
    srunner_free(sr);
  
    return (number_failed == 0) ? EXIT_SUCCESS : EXIT_FAILURE;
  }
  