--- a/tests/test_list.c Thu Dec 18 18:07:29 2025 +0100 +++ b/tests/test_list.c Fri Dec 19 12:40:58 2025 +0100 @@ -74,6 +74,166 @@ cx_array_free(arr); } +CX_TEST(test_array_remove) { + CX_ARRAY(int, arr); + cx_array_init(arr, 5); + arr.data[0] = 2; + arr.data[1] = 3; + arr.data[2] = 5; + arr.data[3] = 7; + arr.data[4] = 11; + arr.size = 5; + int expected[5]; + const size_t len = 5*sizeof(int); + memcpy(expected, arr.data, len); + CX_TEST_DO { + // out-of-bounds + cx_array_remove(arr, 7); + CX_TEST_ASSERT(arr.capacity == 5); + CX_TEST_ASSERT(arr.size == 5); + CX_TEST_ASSERT(0 == memcmp(arr.data, expected, len)); + + // remove mid + cx_array_remove(arr, 2); + CX_TEST_ASSERT(arr.capacity == 5); + CX_TEST_ASSERT(arr.size == 4); + expected[2] = 7; + expected[3] = 11; + expected[4] = 11; // not cleared + CX_TEST_ASSERT(0 == memcmp(arr.data, expected, len)); + + // remove end + cx_array_remove(arr, 3); + CX_TEST_ASSERT(arr.capacity == 5); + CX_TEST_ASSERT(arr.size == 3); + CX_TEST_ASSERT(0 == memcmp(arr.data, expected, len)); + } + cx_array_free(arr); +} + +CX_TEST(test_array_remove_fast) { + CX_ARRAY(int, arr); + cx_array_init(arr, 5); + arr.data[0] = 2; + arr.data[1] = 3; + arr.data[2] = 5; + arr.data[3] = 7; + arr.data[4] = 11; + arr.size = 5; + int expected[5]; + const size_t len = 5*sizeof(int); + memcpy(expected, arr.data, len); + CX_TEST_DO { + // out-of-bounds + cx_array_remove_fast(arr, 7); + CX_TEST_ASSERT(arr.capacity == 5); + CX_TEST_ASSERT(arr.size == 5); + CX_TEST_ASSERT(0 == memcmp(arr.data, expected, len)); + + // remove mid + cx_array_remove_fast(arr, 2); + CX_TEST_ASSERT(arr.capacity == 5); + CX_TEST_ASSERT(arr.size == 4); + expected[2] = 11; + expected[3] = 7; + expected[4] = 11; // not cleared + CX_TEST_ASSERT(0 == memcmp(arr.data, expected, len)); + + // remove end + cx_array_remove_fast(arr, 3); + CX_TEST_ASSERT(arr.capacity == 5); + CX_TEST_ASSERT(arr.size == 3); + CX_TEST_ASSERT(0 == memcmp(arr.data, expected, len)); + } + cx_array_free(arr); +} + +CX_TEST(test_array_remove_array) { + CX_ARRAY(int, arr); + cx_array_init(arr, 10); + arr.data[0] = 2; + arr.data[1] = 3; + arr.data[2] = 5; + arr.data[3] = 7; + arr.data[4] = 11; + arr.data[5] = 47; + arr.data[6] = 80; + arr.data[7] = 104; + arr.data[8] = 250; + arr.data[9] = 999; + arr.size = 10; + int expected[10]; + const size_t len = 5*sizeof(int); + memcpy(expected, arr.data, len); + CX_TEST_DO { + // completely out-of-bounds + cx_array_remove_array(arr, 10, 3); + CX_TEST_ASSERT(arr.capacity == 10); + CX_TEST_ASSERT(arr.size == 10); + CX_TEST_ASSERT(0 == memcmp(arr.data, expected, len)); + + // somewhere in the middle + cx_array_remove_array(arr, 2, 3); + CX_TEST_ASSERT(arr.capacity == 10); + CX_TEST_ASSERT(arr.size == 7); + expected[2] = 47; + expected[3] = 80; + expected[4] = 104; + expected[5] = 250; + expected[6] = 999; + CX_TEST_ASSERT(0 == memcmp(arr.data, expected, len)); + + // partially out-of-bounds + cx_array_remove_array(arr, 5, 4); + CX_TEST_ASSERT(arr.capacity == 10); + CX_TEST_ASSERT(arr.size == 5); + CX_TEST_ASSERT(0 == memcmp(arr.data, expected, len)); + } + cx_array_free(arr); +} + +CX_TEST(test_array_remove_array_fast) { + CX_ARRAY(int, arr); + cx_array_init(arr, 10); + arr.data[0] = 2; + arr.data[1] = 3; + arr.data[2] = 5; + arr.data[3] = 7; + arr.data[4] = 11; + arr.data[5] = 47; + arr.data[6] = 80; + arr.data[7] = 104; + arr.data[8] = 250; + arr.data[9] = 999; + arr.size = 10; + int expected[10]; + const size_t len = 5*sizeof(int); + memcpy(expected, arr.data, len); + CX_TEST_DO { + // completely out-of-bounds + cx_array_remove_array_fast(arr, 10, 3); + CX_TEST_ASSERT(arr.capacity == 10); + CX_TEST_ASSERT(arr.size == 10); + CX_TEST_ASSERT(0 == memcmp(arr.data, expected, len)); + + // somewhere in the middle + cx_array_remove_array_fast(arr, 2, 3); + CX_TEST_ASSERT(arr.capacity == 10); + CX_TEST_ASSERT(arr.size == 7); + expected[2] = 104; + expected[3] = 250; + expected[4] = 999; + CX_TEST_ASSERT(0 == memcmp(arr.data, expected, len)); + + // partially out-of-bounds + cx_array_remove_array_fast(arr, 5, 4); + CX_TEST_ASSERT(arr.capacity == 10); + CX_TEST_ASSERT(arr.size == 5); + CX_TEST_ASSERT(0 == memcmp(arr.data, expected, len)); + } + cx_array_free(arr); +} + CX_TEST(test_array_reserve) { CX_ARRAY(int, arr); cx_array_init(arr, 5); @@ -3277,10 +3437,14 @@ cxListFree(array_list); } -CxTestSuite *cx_test_suite_array_list(void) { - CxTestSuite *suite = cx_test_suite_new("array_list"); +CxTestSuite *cx_test_suite_array(void) { + CxTestSuite *suite = cx_test_suite_new("array (low-level)"); cx_test_register(suite, test_array_add); + cx_test_register(suite, test_array_remove); + cx_test_register(suite, test_array_remove_fast); + cx_test_register(suite, test_array_remove_array); + cx_test_register(suite, test_array_remove_array_fast); cx_test_register(suite, test_array_reserve); cx_test_register(suite, test_array_copy_to_new); cx_test_register(suite, test_array_insert_sorted); @@ -3288,6 +3452,12 @@ cx_test_register(suite, test_array_binary_search); cx_test_register(suite, test_array_binary_search_with_duplicates); + return suite; +} + +CxTestSuite *cx_test_suite_array_list(void) { + CxTestSuite *suite = cx_test_suite_new("array_list"); + cx_test_register(suite, test_list_arl_create); cx_test_register(suite, test_list_arl_create_simple); cx_test_register(suite, test_list_arl_create_simple_for_pointers);