Files
cKit/Foundation/c_KnuthShuffle.t.c
T
2026-08-30 22:24:45 +08:00

113 lines
3.5 KiB
C

#include "c_KnuthShuffle.h"
#include "c_Test.h"
#include <stdlib.h>
#include <stdio.h>
#include <c_StringView.h>
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;
}