| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198 |
- #include "testBase.h"
- static void testDuplicateEdgeCases(void)
- {
- // 复制 NULL
- TEST_ASSERT_NULL_MESSAGE(RyanJsonDuplicate(NULL), "Duplicate(NULL) 应返回 NULL");
- // 深拷贝验证
- // 创建一个嵌套对象: root -> child -> val
- RyanJson_t root = RyanJsonCreateObject();
- RyanJson_t child = RyanJsonCreateObject();
- RyanJsonAddIntToObject(child, "val", 100);
- RyanJsonAddItemToObject(root, "child", child);
- // 复制整个树
- RyanJson_t rootCopy = RyanJsonDuplicate(root);
- TEST_ASSERT_NOT_NULL(rootCopy);
- TEST_ASSERT_TRUE_MESSAGE(RyanJsonCompare(root, rootCopy), "复制后内容应一致");
- // 修改副本的深层值
- RyanJson_t childCopy = RyanJsonGetObjectToKey(rootCopy, "child");
- RyanJsonChangeIntValue(RyanJsonGetObjectToKey(childCopy, "val"), 200);
- // 验证:原件应保持 100,副本为 200
- TEST_ASSERT_EQUAL_INT_MESSAGE(100, RyanJsonGetIntValue(RyanJsonGetObjectToKey(root, "child", "val")), "修改副本不应影响原件");
- TEST_ASSERT_EQUAL_INT_MESSAGE(200, RyanJsonGetIntValue(RyanJsonGetObjectToKey(rootCopy, "child", "val")), "副本修改失效");
- RyanJsonDelete(root);
- RyanJsonDelete(rootCopy);
- }
- static void testDuplicateEmptyAndSpecial(void)
- {
- // 复制空对象和空数组
- RyanJson_t emptyObj = RyanJsonCreateObject();
- RyanJson_t dupEmptyObj = RyanJsonDuplicate(emptyObj);
- TEST_ASSERT_NOT_NULL(dupEmptyObj);
- TEST_ASSERT_TRUE(RyanJsonIsObject(dupEmptyObj));
- TEST_ASSERT_EQUAL_INT(0, RyanJsonGetSize(dupEmptyObj));
- RyanJsonDelete(emptyObj);
- RyanJsonDelete(dupEmptyObj);
- RyanJson_t emptyArr = RyanJsonCreateArray();
- RyanJson_t dupEmptyArr = RyanJsonDuplicate(emptyArr);
- TEST_ASSERT_NOT_NULL(dupEmptyArr);
- TEST_ASSERT_TRUE(RyanJsonIsArray(dupEmptyArr));
- TEST_ASSERT_EQUAL_INT(0, RyanJsonGetSize(dupEmptyArr));
- RyanJsonDelete(emptyArr);
- RyanJsonDelete(dupEmptyArr);
- // 复制包含特殊值的对象
- RyanJson_t specialObj = RyanJsonCreateObject();
- RyanJsonAddNullToObject(specialObj, "null");
- RyanJsonAddBoolToObject(specialObj, "true", RyanJsonTrue);
- RyanJsonAddBoolToObject(specialObj, "false", RyanJsonFalse);
- RyanJsonAddStringToObject(specialObj, "emptyStr", "");
- RyanJson_t dupSpecial = RyanJsonDuplicate(specialObj);
- TEST_ASSERT_TRUE(RyanJsonCompare(specialObj, dupSpecial));
- RyanJsonDelete(specialObj);
- RyanJsonDelete(dupSpecial);
- }
- static void testDuplicateFullScenarios(void)
- {
- RyanJson_t json, dupItem, jsonRoot = NULL;
- char jsonstr[] = "{\"inter\":16,\"double\":16.89,\"string\":\"hello\",\"boolTrue\":true,\"boolFalse\":false,\"null\":null,\"item\":"
- "{\"inter\":16,\"double\":16."
- "89,\"string\":\"hello\","
- "\"boolTrue\":true,\"boolFalse\":false,\"null\":null},\"arrayInt\":[16,16,16,16,16],\"arrayDouble\":[16.89,16.89,"
- "16.89,16.89,16.89],"
- "\"arrayString\":[\"hello\",\"hello\","
- "\"hello\",\"hello\",\"hello\"],\"array\":[16,16.89,\"hello\",true,false,null],\"arrayItem\":[{\"inter\":16,"
- "\"double\":16.89,\"string\":"
- "\"hello\",\"boolTrue\":true,"
- "\"boolFalse\":false,\"null\":null},{\"inter\":16,\"double\":16.89,\"string\":\"hello\",\"boolTrue\":true,"
- "\"boolFalse\":false,\"null\":null}]}";
- /**
- * @brief 普通类型复制测试
- */
- json = RyanJsonParse(jsonstr);
- TEST_ASSERT_NOT_NULL_MESSAGE(json, "解析 Json 失败");
- dupItem = RyanJsonDuplicate(RyanJsonGetObjectToKey(json, "inter"));
- TEST_ASSERT_TRUE_MESSAGE(RyanJsonCompare(dupItem, RyanJsonGetObjectToKey(json, "inter")), "普通类型复制后比较失败");
- RyanJsonDelete(dupItem);
- dupItem = RyanJsonDuplicate(RyanJsonGetObjectToKey(json, "inter"));
- TEST_ASSERT_FALSE_MESSAGE(RyanJsonAddItemToObject(json, "test", dupItem), "AddItemToObject 不应接受标量 item");
- dupItem = RyanJsonDuplicate(RyanJsonGetObjectToKey(json, "inter"));
- TEST_ASSERT_FALSE_MESSAGE(RyanJsonAddItemToObject(json, "test", dupItem), "AddItemToObject 不应接受标量 item");
- RyanJsonDelete(json);
- /**
- * @brief 对象类型复制测试
- */
- json = RyanJsonParse(jsonstr);
- TEST_ASSERT_NOT_NULL_MESSAGE(json, "重新解析 Json 失败");
- dupItem = RyanJsonDuplicate(RyanJsonGetObjectToKey(json, "item"));
- TEST_ASSERT_TRUE_MESSAGE(RyanJsonCompare(dupItem, RyanJsonGetObjectToKey(json, "item")), "对象类型复制后比较失败");
- RyanJsonDelete(dupItem);
- dupItem = RyanJsonDuplicate(RyanJsonGetObjectToKey(json, "item"));
- RyanJsonAddItemToObject(json, "test", dupItem);
- TEST_ASSERT_TRUE_MESSAGE(RyanJsonCompare(RyanJsonGetObjectToKey(json, "test"), RyanJsonGetObjectToKey(json, "item")),
- "对象类型复制并添加后比较失败");
- RyanJsonDelete(RyanJsonDetachByKey(json, "test"));
- dupItem = RyanJsonDuplicate(RyanJsonGetObjectToKey(json, "item"));
- RyanJsonAddItemToObject(json, "test", dupItem);
- TEST_ASSERT_TRUE_MESSAGE(RyanJsonCompare(RyanJsonGetObjectToKey(json, "test"), RyanJsonGetObjectToKey(json, "item")),
- "对象类型复制并添加后删除再添加比较失败");
- RyanJsonDelete(json);
- /**
- * @brief 数组类型复制测试
- */
- json = RyanJsonParse(jsonstr);
- TEST_ASSERT_NOT_NULL_MESSAGE(json, "重新解析 Json 失败 (数组测试)");
- dupItem = RyanJsonDuplicate(RyanJsonGetObjectToKey(json, "arrayItem"));
- TEST_ASSERT_TRUE_MESSAGE(RyanJsonCompare(dupItem, RyanJsonGetObjectToKey(json, "arrayItem")), "数组类型复制后比较失败");
- RyanJsonDelete(dupItem);
- dupItem = RyanJsonDuplicate(RyanJsonGetObjectToKey(json, "arrayItem"));
- RyanJsonAddItemToObject(json, "test", dupItem);
- TEST_ASSERT_TRUE_MESSAGE(RyanJsonCompare(RyanJsonGetObjectToKey(json, "test"), RyanJsonGetObjectToKey(json, "arrayItem")),
- "数组类型复制并添加后比较失败");
- RyanJsonDelete(RyanJsonDetachByKey(json, "test"));
- dupItem = RyanJsonDuplicate(RyanJsonGetObjectToKey(json, "arrayItem"));
- RyanJsonAddItemToObject(json, "test", dupItem);
- TEST_ASSERT_TRUE_MESSAGE(RyanJsonCompare(RyanJsonGetObjectToKey(json, "test"), RyanJsonGetObjectToKey(json, "arrayItem")),
- "数组类型复制并添加后删除再添加比较失败");
- RyanJsonDelete(json);
- /**
- * @brief 循环压力与内存泄漏测试
- */
- json = RyanJsonParse(jsonstr);
- jsonRoot = RyanJsonCreateObject();
- RyanJsonAddBoolToObject(jsonRoot, "arrayItem", RyanJsonTrue);
- int32_t initialUse = vallocGetUse();
- for (uint8_t i = 0; i < 10; i++)
- {
- dupItem = RyanJsonParse(jsonstr);
- TEST_ASSERT_NOT_NULL_MESSAGE(dupItem, "循环中解析失败");
- RyanJsonReplaceByKey(jsonRoot, "arrayItem", RyanJsonDuplicate(dupItem));
- TEST_ASSERT_TRUE_MESSAGE(RyanJsonCompare(RyanJsonGetObjectToKey(jsonRoot, "arrayItem"), dupItem), "循环中替换并比较失败");
- RyanJsonReplaceByKey(json, "arrayItem", RyanJsonDuplicate(RyanJsonGetObjectByKey(dupItem, "item")));
- TEST_ASSERT_TRUE_MESSAGE(
- RyanJsonCompare(RyanJsonGetObjectToKey(json, "arrayItem"), RyanJsonGetObjectByKey(dupItem, "item")),
- "循环中嵌套替换并比较失败");
- RyanJsonDelete(dupItem);
- if (i > 0) { TEST_ASSERT_EQUAL_INT_MESSAGE(initialUse, vallocGetUse(), "内存泄漏检测失败"); }
- initialUse = vallocGetUse();
- }
- RyanJsonDelete(json);
- RyanJsonDelete(jsonRoot);
- }
- static void testDuplicateMassiveStress(void)
- {
- // 压力测试:大数组复制
- int32_t bigSize = 2000;
- RyanJson_t bigArr = RyanJsonCreateArray();
- for (int32_t i = 0; i < bigSize; i++)
- {
- RyanJsonAddIntToArray(bigArr, i);
- }
- RyanJson_t dupBigArr = RyanJsonDuplicate(bigArr);
- TEST_ASSERT_EQUAL_INT(bigSize, RyanJsonGetArraySize(dupBigArr));
- #if true == RyanJsonDefaultAddAtHead
- TEST_ASSERT_EQUAL_INT(0, RyanJsonGetIntValue(RyanJsonGetObjectByIndex(dupBigArr, bigSize - 1)));
- #else
- TEST_ASSERT_EQUAL_INT(bigSize - 1, RyanJsonGetIntValue(RyanJsonGetObjectByIndex(dupBigArr, bigSize - 1)));
- #endif
- RyanJsonDelete(bigArr);
- RyanJsonDelete(dupBigArr);
- }
- void testDuplicateRunner(void)
- {
- UnitySetTestFile(__FILE__);
- RUN_TEST(testDuplicateEdgeCases);
- RUN_TEST(testDuplicateEmptyAndSpecial);
- RUN_TEST(testDuplicateFullScenarios);
- RUN_TEST(testDuplicateMassiveStress);
- }
|