#include "c_KnuthShuffle.h" #include "c_Test.h" #include #include #include TEST_CASE(test_c_KnuthShuffle_IntArray) { // 显式播种确保单次测试序列可重现,或调用您的 c_Random_Init() srand(54321); int original[] = { 10, 20, 30, 40, 50, 60, 70, 80, 90, 100 }; int arr[] = { 10, 20, 30, 40, 50, 60, 70, 80, 90, 100 }; c_size_t num = sizeof(arr) / sizeof(arr[0]); // 执行洗牌 c_KnuthShuffle(arr, num, sizeof(int)); // 1. 验证乱序生效性:洗牌后的数组大概率不再与原数组完全相同 int match_count = 0; for (size_t i = 0; i < num; i++) { if (arr[i] == original[i]) { match_count++; } } // 10个元素洗牌后,依然完全对齐原数组的概率极低 ASSERT_TRUE(match_count < (int)num); // 2. 验证元素守恒性:利用计数桶确保数据没有在交换中丢失或损坏 for (size_t i = 0; i < num; i++) { int target = original[i]; bool found = false; for (size_t j = 0; j < num; j++) { if (arr[j] == target) { found = true; break; } } ASSERT_TRUE(found); // 每一个原数组的元素都必须在洗牌后的数组中存在 } } TEST_CASE(test_c_KnuthShuffle_StringViewArray) { c_StringView_t original_sv[] = { c_StringView_FromCStr("A"), c_StringView_FromCStr("B"), c_StringView_FromCStr("C"), c_StringView_FromCStr("D") }; c_StringView_t sv_arr[] = { c_StringView_FromCStr("A"), c_StringView_FromCStr("B"), c_StringView_FromCStr("C"), c_StringView_FromCStr("D") }; c_size_t num = sizeof(sv_arr) / sizeof(sv_arr[0]); // 对 StringView 结构体数组执行泛型洗牌 c_KnuthShuffle(sv_arr, num, sizeof(c_StringView_t)); // 验证洗牌后所有的 StringView 依然完好、大小未被破坏 for (size_t i = 0; i < num; i++) { c_StringView_t* cur = &sv_arr[i]; ASSERT_PTR_NOT_NULL(cur->str); ASSERT_INT_EQ(1, (int)cur->size); // 每个视图长度原本都为 1 // 确保属于原集合 A, B, C, D 之一 char c = cur->str[0]; ASSERT_TRUE(c == 'A' || c == 'B' || c == 'C' || c == 'D'); } } TEST_CASE(test_c_KnuthShuffle_EdgeCases) { int single_arr[] = { 42 }; // 1. 测试单元素或空元素数组的防御能力(应当安全返回,不崩溃) c_KnuthShuffle(single_arr, 1, sizeof(int)); ASSERT_INT_EQ(42, single_arr[0]); c_KnuthShuffle(NULL, 0, sizeof(int)); ASSERT_TRUE(true); // 代表通过了 NULL 校验 } TEST_CASE(test_c_KnuthShuffle_UnderflowDefense) { int small_arr[] = { 1, 2 }; // 压测 2 个元素的无符号边界切换,确保能在一瞬间安全退出 c_KnuthShuffle(small_arr, 2, sizeof(int)); // 修正:分别验证下标 0 和 下标 1 的元素有效性 ASSERT_TRUE(small_arr[0] == 1 || small_arr[0] == 2); ASSERT_TRUE(small_arr[1] == 1 || small_arr[1] == 2); // 附加校验:洗牌不会凭空克隆元素,两个位置的值必须保持不相等 ASSERT_TRUE(small_arr[0] != small_arr[1]); } int main(int argc, char** argv){ TEST_START(Unit Tests); // 运行普通无环境要求的用例 RUN_TEST(test_c_KnuthShuffle_IntArray); RUN_TEST(test_c_KnuthShuffle_StringViewArray); RUN_TEST(test_c_KnuthShuffle_EdgeCases); RUN_TEST(test_c_KnuthShuffle_UnderflowDefense); // 打印最终统计报告 TEST_REPORT(); RETURN_TEST_STATUS; return 0; }