Thu, 30 Oct 2025 19:26:47 +0100
add tests for cxListDifference() - resolves #751
| tests/test_list.c | file | annotate | diff | comparison | revisions | |
| tests/ucxtest.c | file | annotate | diff | comparison | revisions |
--- a/tests/test_list.c Tue Oct 28 22:09:55 2025 +0100 +++ b/tests/test_list.c Thu Oct 30 19:26:47 2025 +0100 @@ -2526,15 +2526,23 @@ free(testdata); }) +static bool test_clone_func_max_enabled = false; static unsigned test_clone_func_max_clones; static void *test_clone_func(void *dest, const void *src, const CxAllocator *al, void *data) { - if (test_clone_func_max_clones == 0) return NULL; - test_clone_func_max_clones--; + if (test_clone_func_max_enabled) { + if (test_clone_func_max_clones == 0) return NULL; + test_clone_func_max_clones--; + } if (dest == NULL) { dest = cxMalloc(al, sizeof(int)); } + int z = 0; + if (data == NULL) { + data = &z; + } + *((int*) dest) = *(int*) src + *(int*) data; (*(int*) data)++; @@ -2573,7 +2581,6 @@ // perform the test int expected_data[12] = array_init(1, 2, 3, 4, 1, 3, 5, 7, 9, 11, 13, 15); int c = 0; - test_clone_func_max_clones = 100; // no limit CX_TEST_ASSERT(0 == cxListClone(target, source, test_clone_func, testing_alloc, &c)); CX_TEST_ASSERT(c == 8); CX_TEST_ASSERT(cxListSize(target) == 12); @@ -2621,8 +2628,10 @@ // perform the test int expected_data[9] = array_init(1, 2, 3, 4, 1, 3, 5, 7, 9); int c = 0; + test_clone_func_max_enabled = true; test_clone_func_max_clones = 5; CX_TEST_ASSERT(0 != cxListClone(target, source, test_clone_func, testing_alloc, &c)); + test_clone_func_max_enabled = false; CX_TEST_ASSERT(c == 5); CX_TEST_ASSERT(cxListSize(target) == 9); CX_TEST_ASSERT(cxListSize(source) == 8); @@ -2677,6 +2686,107 @@ CX_TEST_CALL_SUBROUTINE(verify_clone_alloc_fail, target, list, true); }) +static CX_TEST_SUBROUTINE(verify_difference, bool sorted, bool alloc_fail) { + CxTestingAllocator talloc; + cx_testing_allocator_init(&talloc); + + CxList *dst = cxLinkedListCreate(cxDefaultAllocator, cx_cmp_int, CX_STORE_POINTERS); + cxDefineAdvancedDestructor(dst, cxFree, &talloc); + CxList *minuend = cxLinkedListCreate(cxDefaultAllocator, cx_cmp_int, sizeof(int)); + CxList *subtrahend = cxLinkedListCreate(cxDefaultAllocator, cx_cmp_int, sizeof(int)); + + int dst_data[] = { + 47, 178, 176, 83, 109, 149, 192, 38, 101, 116, 121, 73, 94, 197, 91, 79, 158, 86, 190, 138, 100, 39, 30, 144, + 35, 182, 155, 84, 139, 186, 67, 123, 62, 37, 3, 64, 172, 56, 160, 1, 156, 132, 131, 49, 10, 126, 171, 145, 77, + 107 + }; + int minuend_data[] = { + 153, 106, 171, 130, 74, 173, 150, 94, 27, 92, 70, 175, 200, 20, 29, 161, 88, 116, 71, 53, 199, 124, 32, 9, 76, + 151, 33, 51, 37, 65, 176, 49, 12, 162, 28, 85, 4, 177, 198, 54, 109, 188, 44, 77, 194, 63, 41, 129, 97, 83 + }; + int subtrahend_data[] = { + 75, 137, 176, 111, 85, 27, 197, 141, 46, 103, 69, 146, 49, 79, 63, 130, 154, 45, 38, 139, 193, 90, 64, 142, 115, + 120, 78, 100, 101, 42, 21, 1, 161, 10, 114, 198, 181, 178, 136, 188, 59, 41, 73, 99, 151, 144, 118, 53, 199, 71 + }; + + { + CxList *tmp = cxArrayListCreateSimple(sizeof(int), 50); + cxListAddArray(tmp, dst_data, 50); + cxListClone(dst, tmp, test_clone_func, &talloc.base, NULL); + cxListFree(tmp); + } + cxListAddArray(minuend, minuend_data, 50); + cxListAddArray(subtrahend, subtrahend_data, 50); + if (sorted) { + cxListSort(dst); + cxListSort(minuend); + cxListSort(subtrahend); + } + + // expected 36 elements stay in dst, and 36 will be added from the difference + size_t expected_len = 72; + int expected_unsorted[] = { + 47, 83, 109, 149, 192, 116, 121, 94, 91, 158, 86, 190, 138, 39, 30, 35, 182, 155, 84, 186, 67, 123, 62, 37, + 3, 172, 56, 160, 156, 132, 131, 126, 171, 145, 77, 107, + 153, 106, 171, 74, 173, 150, 94, 92, 70, 175, 200, 20, 29, 88, 116, 124, 32, 9, 76, 33, 51, 37, 65, 12, 162, + 28, 4, 177, 54, 109, 44, 77, 194, 129, 97, 83 + }; + int expected_sorted[] = { + 3, 30, 35, 37, 39, 47, 56, 62, 67, 77, 83, 84, 86, 91, 94, 107, 109, 116, 121, 123, 126, 131, 132, 138, 145, + 149, 155, 156, 158, 160, 171, 172, 182, 186, 190, 192, + 4, 9, 12, 20, 28, 29, 32, 33, 37, 44, 51, 54, 65, 70, 74, 76, 77, 83, 88, 92, 94, 97, 106, 109, 116, 124, 129, + 150, 153, 162, 171, 173, 175, 177, 194, 200 + }; + + if (alloc_fail) { + test_clone_func_max_enabled = true; + test_clone_func_max_clones = 30; + expected_len = 66; + } + CxList *expected = cxArrayListCreate(cxDefaultAllocator, cx_cmp_int, sizeof(int), expected_len); + cxListAddArray(expected, sorted ? expected_sorted : expected_unsorted, expected_len); + + int result = cxListDifference(dst, minuend, subtrahend, test_clone_func, &talloc.base, NULL); + if (alloc_fail) { + CX_TEST_ASSERT(result != 0); + } else { + CX_TEST_ASSERT(result == 0); + } + test_clone_func_max_enabled = false; + CX_TEST_ASSERT(expected_len == cxListSize(dst)); + CX_TEST_ASSERT(0 == cxListCompare(dst, expected)); + + cxListFree(dst); + cxListFree(minuend); + cxListFree(subtrahend); + cxListFree(expected); + CX_TEST_ASSERT(cx_testing_allocator_verify(&talloc)); +} + +CX_TEST(test_list_difference_unsorted) { + CX_TEST_DO { + CX_TEST_CALL_SUBROUTINE(verify_difference, false, false); + } +} + +CX_TEST(test_list_difference_sorted) { + CX_TEST_DO { + CX_TEST_CALL_SUBROUTINE(verify_difference, true, false); + } +} + +CX_TEST(test_list_difference_unsorted_alloc_fail) { + CX_TEST_DO { + CX_TEST_CALL_SUBROUTINE(verify_difference, false, true); + } +} + +CX_TEST(test_list_difference_sorted_alloc_fail) { + CX_TEST_DO { + CX_TEST_CALL_SUBROUTINE(verify_difference, true, true); + } +} + CX_TEST(test_list_pointer_list_supports_null) { CxList *list = cxLinkedListCreate(cxDefaultAllocator, cx_cmp_int, CX_STORE_POINTERS); int x = 47; @@ -3128,6 +3238,18 @@ return suite; } +CxTestSuite *cx_test_suite_list_set_ops(void) { + CxTestSuite *suite = cx_test_suite_new("list collection operations"); + + // we do not perform the following tests with every combination of list types + cx_test_register(suite, test_list_difference_unsorted); + cx_test_register(suite, test_list_difference_sorted); + cx_test_register(suite, test_list_difference_unsorted_alloc_fail); + cx_test_register(suite, test_list_difference_sorted_alloc_fail); + + return suite; +} + CxTestSuite *cx_test_suite_list_corner_cases(void) { CxTestSuite *suite = cx_test_suite_new("list corner cases");
--- a/tests/ucxtest.c Tue Oct 28 22:09:55 2025 +0100 +++ b/tests/ucxtest.c Thu Oct 30 19:26:47 2025 +0100 @@ -48,6 +48,7 @@ CxTestSuite *cx_test_suite_linked_list_defaulted_funcs(void); CxTestSuite *cx_test_suite_kv_list(void); CxTestSuite *cx_test_suite_kv_list_specifics(void); +CxTestSuite *cx_test_suite_list_set_ops(void); CxTestSuite *cx_test_suite_list_corner_cases(void); CxTestSuite *cx_test_suite_tree_low_level(void); CxTestSuite *cx_test_suite_tree_high_level(void); @@ -102,6 +103,7 @@ cx_test_suite_linked_list_defaulted_funcs(), cx_test_suite_kv_list(), cx_test_suite_kv_list_specifics(), + cx_test_suite_list_set_ops(), cx_test_suite_list_corner_cases(), cx_test_suite_tree_low_level(), cx_test_suite_tree_high_level(),