#include "c_BinarySearch.h" #include "c_Test.h" #include #include #include "c_StringView.h" /* ------------------------------------------------------------------------------------------------------------------ */ /* */ // ========================================== // 1. 测试用例伴生:基础数据类型比对器 // ========================================== static int compare_ints(const void* a, const void* b) { int arg1 = *(const int*)a; int arg2 = *(const int*)b; if (arg1 < arg2) return -1; if (arg1 > arg2) return 1; return 0; } // 自定义结构体与对应的比对器 typedef struct { uint32_t id; uint32_t value; } TestItem_t; static int compare_items_by_id(const void* key, const void* elem) { uint32_t key_id = *(const uint32_t*)key; // 查找时通常可以直接传入 ID 变量的地址作为 key uint32_t elem_id = ((const TestItem_t*)elem)->id; if (key_id < elem_id) return -1; if (key_id > elem_id) return 1; return 0; } // 适配 c_StringView_t 的比对器(对之前 Cmp 函数的外壳包裹) static int compare_string_views(const void* key, const void* elem) { return c_StringView_Cmp((c_StringView_t*)key, (c_StringView_t*)elem); } // ========================================== // 2. 核心测试用例 // ========================================== TEST_CASE(test_c_BinarySearch_IntArray) { int sorted_ints[] = { 2, 5, 8, 12, 16, 23, 38, 56, 72, 91 }; c_size_t array_len = sizeof(sorted_ints) / sizeof(sorted_ints[0]); // 1. 查找存在的元素 int target_exist = 23; const int* result1 = (const int*)c_BinarySearch(&target_exist, sorted_ints, array_len, sizeof(int), compare_ints); ASSERT_PTR_NOT_NULL(result1); ASSERT_INT_EQ(23, *result1); ASSERT_LL_EQ(5, result1 - sorted_ints); // 校验指针偏移,确定下标为 5 // 2. 查找不存在的元素 int target_missing = 40; const int* result2 = (const int*)c_BinarySearch(&target_missing, sorted_ints, array_len, sizeof(int), compare_ints); ASSERT_TRUE(result2 == NULL); } TEST_CASE(test_c_BinarySearch_StructArray) { // 模拟数据库索引项或符号表,已按 ID 升序排好 TestItem_t items[] = { { 1001, 55 }, { 1005, 99 }, { 1012, 12 }, { 1045, 78 } }; c_size_t array_len = sizeof(items) / sizeof(items[0]); // 查找 ID 为 1012 的结构体数据 uint32_t search_id = 1012; const TestItem_t* match = (const TestItem_t*)c_BinarySearch(&search_id, items, array_len, sizeof(TestItem_t), compare_items_by_id); ASSERT_PTR_NOT_NULL(match); ASSERT_INT_EQ(1012, (int)match->id); ASSERT_INT_EQ(12, (int)match->value); // 成功提取对应的值 ASSERT_LL_EQ(2, match - items); // 下标确认 } TEST_CASE(test_c_BinarySearch_StringViewArray) { // 复用之前的有序 StringView 数组进行查找 c_StringView_t sv_array[] = { c_StringView_FromCStr("apple"), c_StringView_FromCStr("banana"), c_StringView_FromCStr("cherry"), c_StringView_FromCStr("date") }; c_size_t array_len = sizeof(sv_array) / sizeof(sv_array[0]); c_StringView_t target = c_StringView_FromCStr("banana"); const c_StringView_t* match = (const c_StringView_t*)c_BinarySearch(&target, sv_array, array_len, sizeof(c_StringView_t), compare_string_views); ASSERT_PTR_NOT_NULL(match); ASSERT_INT_EQ(6, (int)match->size); ASSERT_TRUE(memcmp(match->str, "banana", 6) == 0); ASSERT_LL_EQ(1, match - sv_array); // 确认位于数组第 1 项 } TEST_CASE(test_c_BinarySearch_EdgeAndNull) { int single_elem[] = { 42 }; int target = 42; // 1. 空参数安全防御 ASSERT_TRUE(c_BinarySearch(NULL, single_elem, 1, sizeof(int), compare_ints) == NULL); ASSERT_TRUE(c_BinarySearch(&target, NULL, 1, sizeof(int), compare_ints) == NULL); ASSERT_TRUE(c_BinarySearch(&target, single_elem, 1, sizeof(int), NULL) == NULL); ASSERT_TRUE(c_BinarySearch(&target, single_elem, 0, sizeof(int), compare_ints) == NULL); // 2. 单元素数组边界查找 const int* match = (const int*)c_BinarySearch(&target, single_elem, 1, sizeof(int), compare_ints); ASSERT_PTR_NOT_NULL(match); ASSERT_INT_EQ(42, *match); } /* ------------------------------------------------------------------------------------------------------------------ */ /* */ int main(int argc, char** argv){ TEST_START(Unit Tests); // 运行普通无环境要求的用例 RUN_TEST(test_c_BinarySearch_IntArray); RUN_TEST(test_c_BinarySearch_StructArray); RUN_TEST(test_c_BinarySearch_StringViewArray); RUN_TEST(test_c_BinarySearch_EdgeAndNull); // 打印最终统计报告 TEST_REPORT(); RETURN_TEST_STATUS; }