| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487 |
- #include "testBase.h"
- static void testReplaceEdgeCases(void)
- {
- RyanJson_t obj = RyanJsonCreateObject();
- RyanJsonAddIntToObject(obj, "a", 1);
- // Replace NULL 参数
- RyanJson_t newItem = RyanJsonCreateInt("b", 2);
- TEST_ASSERT_FALSE_MESSAGE(RyanJsonReplaceByKey(NULL, "key", newItem), "ReplaceByKey(NULL, ...) 应返回 False");
- TEST_ASSERT_FALSE_MESSAGE(RyanJsonReplaceByKey(obj, NULL, newItem), "ReplaceByKey(..., key=NULL, ...) 应返回 False");
- // 注意:如果 Replace 失败,newItem 及其内存由谁负责?
- // 如果 Replace 函数返回 False 且没有接管 item,调用者需要释放 item。
- // RyanJsonReplaceByKey 检查参数失败时直接返回,不触碰 item。
- // 所以这里我们需要手动释放 newItem 以避免内存泄漏。
- RyanJsonDelete(newItem);
- newItem = RyanJsonCreateInt("b", 2);
- TEST_ASSERT_FALSE_MESSAGE(RyanJsonReplaceByKey(obj, "a", NULL), "ReplaceByKey(..., item=NULL) 应返回 False");
- // newItem 在这里没被传入成功,所以需要手动释放
- RyanJsonDelete(newItem);
- // Replace 不存在的 Key (应失败,而不是添加)
- newItem = RyanJsonCreateInt("b", 2);
- TEST_ASSERT_FALSE_MESSAGE(RyanJsonReplaceByKey(obj, "non_existent", newItem), "ReplaceByKey(不存在的Key) 应返回 False");
- // 同样,替换失败,需释放 newItem
- RyanJsonDelete(newItem);
- // Replace Index 越界
- newItem = RyanJsonCreateInt("b", 2);
- TEST_ASSERT_FALSE_MESSAGE(RyanJsonReplaceByIndex(obj, 99, newItem), "ReplaceByIndex(越界) 应返回 False");
- RyanJsonDelete(newItem);
- // ReplaceByIndex 在对象上的重复 key 行为由严格模式控制
- RyanJsonAddIntToObject(obj, "b", 2);
- newItem = RyanJsonCreateInt("a", 9);
- #if true == RyanJsonDefaultAddAtHead
- uint32_t replaceIndex = 0; // 头插模式下,后加的 "b" 位于索引 0
- #else
- uint32_t replaceIndex = 1; // 尾插模式下,后加的 "b" 位于索引 1
- #endif
- #if true == RyanJsonStrictObjectKeyCheck
- TEST_ASSERT_FALSE_MESSAGE(RyanJsonReplaceByIndex(obj, replaceIndex, newItem),
- "严格模式下 ReplaceByIndex(Object) 重复 key 应返回 False");
- RyanJsonDelete(newItem);
- TEST_ASSERT_EQUAL_INT(1, RyanJsonGetIntValue(RyanJsonGetObjectByKey(obj, "a")));
- TEST_ASSERT_EQUAL_INT(2, RyanJsonGetIntValue(RyanJsonGetObjectByKey(obj, "b")));
- #else
- TEST_ASSERT_TRUE_MESSAGE(RyanJsonReplaceByIndex(obj, replaceIndex, newItem),
- "非严格模式下 ReplaceByIndex(Object) 重复 key 应返回 True");
- #if true == RyanJsonDefaultAddAtHead
- TEST_ASSERT_EQUAL_INT(9, RyanJsonGetIntValue(RyanJsonGetObjectByKey(obj, "a")));
- #else
- TEST_ASSERT_EQUAL_INT(1, RyanJsonGetIntValue(RyanJsonGetObjectByKey(obj, "a")));
- #endif
- TEST_ASSERT_NULL_MESSAGE(RyanJsonGetObjectByKey(obj, "b"), "非严格模式替换后 b 应被替换掉");
- #endif
- // ReplaceByIndex 在对象上使用相同 key 替换应成功
- // 该用例覆盖冲突检查中的 item == skipItem 分支(应跳过被替换节点本身)
- newItem = RyanJsonCreateInt("b", 99);
- TEST_ASSERT_TRUE_MESSAGE(RyanJsonReplaceByIndex(obj, replaceIndex, newItem), "ReplaceByIndex(Object) 同 key 替换应成功");
- TEST_ASSERT_EQUAL_INT(1, RyanJsonGetIntValue(RyanJsonGetObjectByKey(obj, "a")));
- TEST_ASSERT_EQUAL_INT(99, RyanJsonGetIntValue(RyanJsonGetObjectByKey(obj, "b")));
- // 对非容器操作
- RyanJson_t num = RyanJsonCreateInt("num", 1);
- newItem = RyanJsonCreateInt("val", 2);
- TEST_ASSERT_FALSE_MESSAGE(RyanJsonReplaceByKey(num, "any", newItem), "对非容器 ReplaceByKey 应返回 False");
- RyanJsonDelete(newItem);
- RyanJsonDelete(obj);
- RyanJsonDelete(num);
- }
- static void testReplaceSelfCheck(void)
- {
- // 测试:尝试将节点替换为其自身(RyanJsonReplaceByKey/Index 至少应保持稳定,不发生崩溃)。
- // 但 API 语义通常要求 newItem 是新建节点,且不属于任何树(或来自其他位置的 Detach)。
- // 因此这里不直接传入“树内同一节点”,而是使用语义等价的替换场景做覆盖。
- // 测试:替换为“较重”的新节点(大数组)
- RyanJson_t obj = RyanJsonCreateObject();
- RyanJsonAddIntToObject(obj, "k", 1);
- RyanJson_t bigArr = RyanJsonCreateArray();
- for (int32_t i = 0; i < 100; i++)
- {
- RyanJsonAddIntToArray(bigArr, i);
- }
- TEST_ASSERT_TRUE(RyanJsonReplaceByKey(obj, "k", bigArr));
- TEST_ASSERT_EQUAL_INT(100, RyanJsonGetArraySize(RyanJsonGetObjectByKey(obj, "k")));
- RyanJsonDelete(obj);
- }
- static void testReplaceRejectAttachedItem(void)
- {
- RyanJson_t obj1 = RyanJsonCreateObject();
- RyanJson_t obj2 = RyanJsonCreateObject();
- RyanJsonAddIntToObject(obj1, "a", 1);
- RyanJsonAddIntToObject(obj2, "b", 2);
- RyanJson_t attachedObjItem = RyanJsonGetObjectByKey(obj1, "a");
- TEST_ASSERT_NOT_NULL(attachedObjItem);
- TEST_ASSERT_FALSE_MESSAGE(RyanJsonReplaceByKey(obj2, "b", attachedObjItem), "已挂树的 item 不应作为 ReplaceByKey 参数");
- TEST_ASSERT_EQUAL_INT(2, RyanJsonGetIntValue(RyanJsonGetObjectByKey(obj2, "b")));
- TEST_ASSERT_EQUAL_INT(1, RyanJsonGetIntValue(RyanJsonGetObjectByKey(obj1, "a")));
- RyanJson_t arr1 = RyanJsonCreateArray();
- RyanJson_t arr2 = RyanJsonCreateArray();
- RyanJsonAddIntToArray(arr1, 10);
- RyanJsonAddIntToArray(arr2, 20);
- RyanJson_t attachedArrItem = RyanJsonGetObjectByIndex(arr1, 0);
- TEST_ASSERT_NOT_NULL(attachedArrItem);
- TEST_ASSERT_FALSE_MESSAGE(RyanJsonReplaceByIndex(arr2, 0, attachedArrItem), "已挂树的 item 不应作为 ReplaceByIndex 参数");
- TEST_ASSERT_EQUAL_INT(20, RyanJsonGetIntValue(RyanJsonGetObjectByIndex(arr2, 0)));
- TEST_ASSERT_EQUAL_INT(10, RyanJsonGetIntValue(RyanJsonGetObjectByIndex(arr1, 0)));
- RyanJsonDelete(obj1);
- RyanJsonDelete(obj2);
- RyanJsonDelete(arr1);
- RyanJsonDelete(arr2);
- }
- static void testReplaceFailureKeepsItemOwnership(void)
- {
- // ReplaceByIndex 失败后,item 应仍由调用方持有
- RyanJson_t obj = RyanJsonCreateObject();
- TEST_ASSERT_NOT_NULL(obj);
- TEST_ASSERT_TRUE(RyanJsonAddIntToObject(obj, "a", 1));
- TEST_ASSERT_TRUE(RyanJsonAddIntToObject(obj, "b", 2));
- RyanJson_t conflictItem = RyanJsonCreateInt("a", 9);
- TEST_ASSERT_NOT_NULL(conflictItem);
- #if true == RyanJsonStrictObjectKeyCheck
- #if true == RyanJsonDefaultAddAtHead
- TEST_ASSERT_FALSE(RyanJsonReplaceByIndex(obj, 0, conflictItem));
- #else
- TEST_ASSERT_FALSE(RyanJsonReplaceByIndex(obj, 1, conflictItem));
- #endif
- #else
- TEST_ASSERT_FALSE(RyanJsonReplaceByIndex(obj, 99, conflictItem));
- #endif
- TEST_ASSERT_TRUE_MESSAGE(RyanJsonIsDetachedItem(conflictItem), "ReplaceByIndex 失败后 item 不应被消费");
- RyanJson_t arr = RyanJsonCreateArray();
- TEST_ASSERT_NOT_NULL(arr);
- TEST_ASSERT_TRUE(RyanJsonInsert(arr, 0, conflictItem));
- TEST_ASSERT_EQUAL_INT(9, RyanJsonGetIntValue(RyanJsonGetObjectByIndex(arr, 0)));
- // ReplaceByKey 失败(目标 key 不存在)后,item 也应可复用
- RyanJson_t notFoundItem = RyanJsonCreateString("tmp", "v");
- TEST_ASSERT_NOT_NULL(notFoundItem);
- TEST_ASSERT_FALSE(RyanJsonReplaceByKey(obj, "not_exist", notFoundItem));
- TEST_ASSERT_TRUE_MESSAGE(RyanJsonIsDetachedItem(notFoundItem), "ReplaceByKey 失败后 item 不应被消费");
- TEST_ASSERT_TRUE(RyanJsonInsert(arr, UINT32_MAX, notFoundItem));
- TEST_ASSERT_EQUAL_STRING("v", RyanJsonGetStringValue(RyanJsonGetObjectByIndex(arr, 1)));
- RyanJsonDelete(arr);
- RyanJsonDelete(obj);
- }
- static void testReplaceFailureCallerMustDeleteItem(void)
- {
- /*
- * 约定验证:
- * Replace 失败时库不会释放 item,调用方必须手动释放。
- */
- RyanJson_t obj = RyanJsonCreateObject();
- TEST_ASSERT_NOT_NULL(obj);
- TEST_ASSERT_TRUE(RyanJsonAddIntToObject(obj, "a", 1));
- // ReplaceByKey 失败:目标 key 不存在
- RyanJson_t replaceByKeyItem = RyanJsonCreateString("tmp", "v");
- TEST_ASSERT_NOT_NULL(replaceByKeyItem);
- TEST_ASSERT_FALSE(RyanJsonReplaceByKey(obj, "not_exist", replaceByKeyItem));
- TEST_ASSERT_TRUE_MESSAGE(RyanJsonIsDetachedItem(replaceByKeyItem), "ReplaceByKey 失败后 item 应保持游离");
- RyanJsonDelete(replaceByKeyItem); // 调用方主动释放
- // ReplaceByIndex 失败:索引越界
- RyanJson_t replaceByIndexItem = RyanJsonCreateInt("a", 9);
- TEST_ASSERT_NOT_NULL(replaceByIndexItem);
- TEST_ASSERT_FALSE(RyanJsonReplaceByIndex(obj, 99, replaceByIndexItem));
- TEST_ASSERT_TRUE_MESSAGE(RyanJsonIsDetachedItem(replaceByIndexItem), "ReplaceByIndex 失败后 item 应保持游离");
- RyanJsonDelete(replaceByIndexItem); // 调用方主动释放
- // 原树应保持不变
- TEST_ASSERT_EQUAL_INT(1, RyanJsonGetIntValue(RyanJsonGetObjectByKey(obj, "a")));
- RyanJsonDelete(obj);
- }
- static void testReplaceKeyRewriteAndWrapPaths(void)
- {
- RyanJson_t obj = RyanJsonCreateObject();
- TEST_ASSERT_NOT_NULL(obj);
- TEST_ASSERT_TRUE(RyanJsonAddIntToObject(obj, "a", 1));
- TEST_ASSERT_TRUE(RyanJsonAddIntToObject(obj, "b", 2));
- // 无 key 的容器替换对象字段:应自动包装成 key="a"
- RyanJson_t noKeyContainer = RyanJsonCreateObject();
- TEST_ASSERT_NOT_NULL(noKeyContainer);
- TEST_ASSERT_TRUE(RyanJsonAddIntToObject(noKeyContainer, "x", 7));
- TEST_ASSERT_TRUE_MESSAGE(RyanJsonReplaceByKey(obj, "a", noKeyContainer), "ReplaceByKey(无 key 容器) 应成功");
- RyanJson_t aNode = RyanJsonGetObjectByKey(obj, "a");
- TEST_ASSERT_NOT_NULL(aNode);
- TEST_ASSERT_TRUE(RyanJsonIsObject(aNode));
- TEST_ASSERT_EQUAL_INT(7, RyanJsonGetIntValue(RyanJsonGetObjectByKey(aNode, "x")));
- // 无 key 的标量替换对象字段:当前实现会包装为 key="a" 的 object,并把标量作为唯一子节点
- RyanJson_t noKeyScalar = RyanJsonCreateInt(NULL, 123);
- TEST_ASSERT_NOT_NULL(noKeyScalar);
- TEST_ASSERT_TRUE_MESSAGE(RyanJsonReplaceByKey(obj, "a", noKeyScalar), "ReplaceByKey(无 key 标量) 应成功");
- aNode = RyanJsonGetObjectByKey(obj, "a");
- TEST_ASSERT_NOT_NULL(aNode);
- TEST_ASSERT_TRUE_MESSAGE(RyanJsonIsObject(aNode), "无 key 标量替换后应包装为对象节点");
- TEST_ASSERT_EQUAL_UINT32(1, RyanJsonGetSize(aNode));
- TEST_ASSERT_EQUAL_INT(123, RyanJsonGetIntValue(RyanJsonGetObjectByIndex(aNode, 0)));
- // 不同 key 的节点替换:应重命名为目标 key="b"
- RyanJson_t diffKeyItem = RyanJsonCreateInt("temp", 88);
- TEST_ASSERT_NOT_NULL(diffKeyItem);
- TEST_ASSERT_TRUE_MESSAGE(RyanJsonReplaceByKey(obj, "b", diffKeyItem), "ReplaceByKey(不同 key) 应成功");
- TEST_ASSERT_EQUAL_INT(88, RyanJsonGetIntValue(RyanJsonGetObjectByKey(obj, "b")));
- TEST_ASSERT_NULL_MESSAGE(RyanJsonGetObjectByKey(obj, "temp"), "ReplaceByKey 后不应残留旧 key");
- RyanJsonDelete(obj);
- }
- static void testReplaceStandardOperations(void)
- {
- 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}],"
- "\"string2222\":\"hello\"}";
- RyanJson_t json = RyanJsonParse(jsonstr);
- TEST_ASSERT_NOT_NULL_MESSAGE(json, "解析基础 Json 失败");
- // 数组替换测试:arrayInt 头部
- RyanJsonReplaceByIndex(RyanJsonGetObjectToKey(json, "arrayInt"), 0, RyanJsonCreateString(NULL, "arrayIntHead"));
- {
- RyanJson_t v = RyanJsonGetObjectToIndex(RyanJsonGetObjectToKey(json, "arrayInt"), 0);
- TEST_ASSERT_TRUE_MESSAGE(RyanJsonIsString(v), "替换后的 arrayInt[0] 不是字符串");
- TEST_ASSERT_EQUAL_STRING_MESSAGE("arrayIntHead", RyanJsonGetStringValue(v), "替换后的 arrayInt[0] 值错误");
- }
- // 数组替换测试:arrayInt 尾部
- {
- RyanJson_t arr = RyanJsonGetObjectToKey(json, "arrayInt");
- uint32_t last = RyanJsonGetSize(arr) - 1;
- RyanJsonReplaceByIndex(arr, last, RyanJsonCreateString(NULL, "arrayIntTail"));
- RyanJson_t v = RyanJsonGetObjectToIndex(arr, last);
- TEST_ASSERT_TRUE_MESSAGE(RyanJsonIsString(v), "替换后的 arrayInt 尾部不是字符串");
- TEST_ASSERT_EQUAL_STRING_MESSAGE("arrayIntTail", RyanJsonGetStringValue(v), "替换后的 arrayInt 尾部值错误");
- }
- // 数组对象替换测试:arrayItem[0]
- RyanJsonReplaceByIndex(RyanJsonGetObjectToKey(json, "arrayItem"), 0, RyanJsonCreateString(NULL, "arrayItem0"));
- {
- RyanJson_t v = RyanJsonGetObjectToIndex(RyanJsonGetObjectToKey(json, "arrayItem"), 0);
- TEST_ASSERT_TRUE_MESSAGE(RyanJsonIsString(v), "替换后的 arrayItem[0] 不是字符串");
- TEST_ASSERT_EQUAL_STRING_MESSAGE("arrayItem0", RyanJsonGetStringValue(v), "替换后的 arrayItem[0] 值错误");
- }
- // 对象字段替换:inter -> 999
- RyanJsonReplaceByKey(json, "inter", RyanJsonCreateInt("inter", 999));
- {
- RyanJson_t v = RyanJsonGetObjectToKey(json, "inter");
- TEST_ASSERT_TRUE_MESSAGE(RyanJsonIsInt(v), "替换后的 inter 不是整数");
- TEST_ASSERT_EQUAL_INT_MESSAGE(999, RyanJsonGetIntValue(v), "替换后的 inter 值错误");
- }
- // 对象字段替换:double -> 123.45
- RyanJsonReplaceByKey(json, "double", RyanJsonCreateDouble("double", 123.45));
- {
- RyanJson_t v = RyanJsonGetObjectToKey(json, "double");
- TEST_ASSERT_TRUE_MESSAGE(RyanJsonIsDouble(v), "替换后的 double 不是浮点数");
- TEST_ASSERT_TRUE_MESSAGE(RyanJsonCompareDouble(123.45, RyanJsonGetDoubleValue(v)), "替换后的 double 值错误");
- }
- // 对象字段替换:string -> "newString"
- RyanJsonReplaceByKey(json, "string", RyanJsonCreateString("string", "newString"));
- {
- RyanJson_t v = RyanJsonGetObjectToKey(json, "string");
- TEST_ASSERT_TRUE_MESSAGE(RyanJsonIsString(v), "替换后的 string 不是字符串");
- TEST_ASSERT_EQUAL_STRING_MESSAGE("newString", RyanJsonGetStringValue(v), "替换后的 string 值错误");
- }
- // 对象字段替换:boolFalse -> true
- RyanJsonReplaceByKey(json, "boolFalse", RyanJsonCreateBool("boolFalse", RyanJsonTrue));
- {
- RyanJson_t v = RyanJsonGetObjectToKey(json, "boolFalse");
- TEST_ASSERT_TRUE_MESSAGE(RyanJsonIsBool(v), "替换后的 boolFalse 不是布尔值");
- TEST_ASSERT_EQUAL_INT_MESSAGE(RyanJsonTrue, RyanJsonGetBoolValue(v), "替换后的 boolFalse 值错误");
- }
- // 数组替换:arrayString 中间元素 -> "headString"
- RyanJsonReplaceByIndex(RyanJsonGetObjectToKey(json, "arrayString"), 1, RyanJsonCreateString(NULL, "headString"));
- {
- RyanJson_t v = RyanJsonGetObjectToIndex(RyanJsonGetObjectToKey(json, "arrayString"), 1);
- TEST_ASSERT_TRUE_MESSAGE(RyanJsonIsString(v), "替换后的 arrayString[1] 不是字符串");
- TEST_ASSERT_EQUAL_STRING_MESSAGE("headString", RyanJsonGetStringValue(v), "替换后的 arrayString[1] 值错误");
- }
- // 数组项替换测试:arrayString 尾部
- {
- RyanJson_t arr = RyanJsonGetObjectToKey(json, "arrayString");
- uint32_t last = RyanJsonGetSize(arr) - 1;
- RyanJsonReplaceByIndex(arr, last, RyanJsonCreateString(NULL, "tailString"));
- RyanJson_t v = RyanJsonGetObjectToIndex(arr, last);
- TEST_ASSERT_TRUE_MESSAGE(RyanJsonIsString(v), "替换后的 arrayString 尾部不是字符串");
- TEST_ASSERT_EQUAL_STRING_MESSAGE("tailString", RyanJsonGetStringValue(v), "替换后的 arrayString 尾部值错误");
- }
- // 数组对象替换:arrayItem 尾部 -> "arrayItemTail"
- {
- RyanJson_t arr = RyanJsonGetObjectToKey(json, "arrayItem");
- uint32_t last = RyanJsonGetSize(arr) - 1;
- RyanJsonReplaceByIndex(arr, last, RyanJsonCreateString(NULL, "arrayItemTail"));
- RyanJson_t v = RyanJsonGetObjectToIndex(arr, last);
- TEST_ASSERT_TRUE_MESSAGE(RyanJsonIsString(v), "替换后的 arrayItem 尾部不是字符串");
- TEST_ASSERT_EQUAL_STRING_MESSAGE("arrayItemTail", RyanJsonGetStringValue(v), "替换后的 arrayItem 尾部值错误");
- }
- // 嵌套对象替换:item.inter -> 111
- RyanJsonReplaceByKey(RyanJsonGetObjectToKey(json, "item"), "inter", RyanJsonCreateInt("inter", 111));
- {
- RyanJson_t v = RyanJsonGetObjectToKey(RyanJsonGetObjectToKey(json, "item"), "inter");
- TEST_ASSERT_TRUE_MESSAGE(RyanJsonIsInt(v), "替换后的 item.inter 不是整数");
- TEST_ASSERT_EQUAL_INT_MESSAGE(111, RyanJsonGetIntValue(v), "替换后的 item.inter 值错误");
- }
- // 嵌套对象替换:item.string -> "nestedReplace"
- RyanJsonReplaceByKey(RyanJsonGetObjectToKey(json, "item"), "string", RyanJsonCreateString("string", "nestedReplace"));
- {
- RyanJson_t v = RyanJsonGetObjectToKey(RyanJsonGetObjectToKey(json, "item"), "string");
- TEST_ASSERT_TRUE_MESSAGE(RyanJsonIsString(v), "替换后的 item.string 不是字符串");
- TEST_ASSERT_EQUAL_STRING_MESSAGE("nestedReplace", RyanJsonGetStringValue(v), "替换后的 item.string 值错误");
- }
- // 混合数组替换测试
- RyanJson_t mixArr = RyanJsonGetObjectToKey(json, "array");
- // int32_t -> "intReplaced"
- RyanJsonReplaceByIndex(mixArr, 0, RyanJsonCreateString(NULL, "intReplaced"));
- {
- RyanJson_t v = RyanJsonGetObjectToIndex(mixArr, 0);
- TEST_ASSERT_TRUE_MESSAGE(RyanJsonIsString(v), "替换后的 array[0] 不是字符串");
- TEST_ASSERT_EQUAL_STRING_MESSAGE("intReplaced", RyanJsonGetStringValue(v), "替换后的 array[0] 值错误");
- }
- // double -> "doubleReplaced"
- RyanJsonReplaceByIndex(mixArr, 1, RyanJsonCreateString(NULL, "doubleReplaced"));
- {
- RyanJson_t v = RyanJsonGetObjectToIndex(mixArr, 1);
- TEST_ASSERT_TRUE_MESSAGE(RyanJsonIsString(v), "替换后的 array[1] 不是字符串");
- TEST_ASSERT_EQUAL_STRING_MESSAGE("doubleReplaced", RyanJsonGetStringValue(v), "替换后的 array[1] 值错误");
- }
- // string -> "stringReplaced"
- RyanJsonReplaceByIndex(mixArr, 2, RyanJsonCreateString(NULL, "stringReplaced"));
- {
- RyanJson_t v = RyanJsonGetObjectToIndex(mixArr, 2);
- TEST_ASSERT_TRUE_MESSAGE(RyanJsonIsString(v), "替换后的 array[2] 不是字符串");
- TEST_ASSERT_EQUAL_STRING_MESSAGE("stringReplaced", RyanJsonGetStringValue(v), "替换后的 array[2] 值错误");
- }
- // bool -> "boolReplaced"
- RyanJsonReplaceByIndex(mixArr, 3, RyanJsonCreateString(NULL, "boolReplaced"));
- {
- RyanJson_t v = RyanJsonGetObjectToIndex(mixArr, 3);
- TEST_ASSERT_TRUE_MESSAGE(RyanJsonIsString(v), "替换后的 array[3] 不是字符串");
- TEST_ASSERT_EQUAL_STRING_MESSAGE("boolReplaced", RyanJsonGetStringValue(v), "替换后的 array[3] 值错误");
- }
- // null -> "nullReplaced"
- RyanJsonReplaceByIndex(mixArr, 5, RyanJsonCreateString(NULL, "nullReplaced"));
- {
- RyanJson_t v = RyanJsonGetObjectToIndex(mixArr, 5);
- TEST_ASSERT_TRUE_MESSAGE(RyanJsonIsString(v), "替换后的 array[5] 不是字符串");
- TEST_ASSERT_EQUAL_STRING_MESSAGE("nullReplaced", RyanJsonGetStringValue(v), "替换后的 array[5] 值错误");
- }
- // 替换整个数组项:arrayString -> "arrayStringRenamed"
- RyanJsonReplaceByKey(json, "arrayString", RyanJsonCreateString("arrayString", "arrayStringRenamed"));
- {
- RyanJson_t v = RyanJsonGetObjectToKey(json, "arrayString");
- TEST_ASSERT_TRUE_MESSAGE(RyanJsonIsString(v), "替换后的 arrayString 不是字符串");
- TEST_ASSERT_EQUAL_STRING_MESSAGE("arrayStringRenamed", RyanJsonGetStringValue(v), "替换后的 arrayString 值错误");
- }
- // 修改数组节点为对象节点:arrayDouble -> duplicate(item)
- RyanJson_t duplicateJson = RyanJsonDuplicate(RyanJsonGetObjectToKey(json, "item"));
- RyanJsonReplaceByKey(json, "arrayDouble", duplicateJson);
- {
- RyanJson_t v = RyanJsonGetObjectToKey(json, "arrayDouble");
- TEST_ASSERT_TRUE_MESSAGE(RyanJsonIsObject(v), "替换后的 arrayDouble 不是对象类型");
- }
- // 替换字符串字段:string2222 -> "world"
- RyanJsonReplaceByKey(json, "string2222", RyanJsonCreateString("string2222", "world"));
- {
- RyanJson_t v = RyanJsonGetObjectToKey(json, "string2222");
- TEST_ASSERT_TRUE_MESSAGE(RyanJsonIsString(v), "替换后的 string2222 不是字符串");
- TEST_ASSERT_EQUAL_STRING_MESSAGE("world", RyanJsonGetStringValue(v), "替换后的 string2222 值错误");
- }
- // 替换 boolValue:boolTrue -> false
- RyanJsonReplaceByKey(json, "boolTrue", RyanJsonCreateBool("boolTrue", RyanJsonFalse));
- {
- RyanJson_t v = RyanJsonGetObjectToKey(json, "boolTrue");
- TEST_ASSERT_TRUE_MESSAGE(RyanJsonIsBool(v), "替换后的 boolTrue 不是布尔值");
- TEST_ASSERT_EQUAL_INT_MESSAGE(RyanJsonFalse, RyanJsonGetBoolValue(v), "替换后的 boolTrue 值错误");
- }
- // 替换 null 为字符串
- RyanJsonReplaceByKey(json, "null", RyanJsonCreateString("null", "notNull"));
- {
- RyanJson_t v = RyanJsonGetObjectToKey(json, "null");
- TEST_ASSERT_TRUE_MESSAGE(RyanJsonIsString(v), "替换后的 null 不是字符串");
- TEST_ASSERT_EQUAL_STRING_MESSAGE("notNull", RyanJsonGetStringValue(v), "替换后的 null 值错误");
- }
- char *str = RyanJsonPrint(json, 1024, RyanJsonTrue, NULL);
- RyanJsonFree(str);
- RyanJsonDelete(json);
- }
- static void testReplaceTypeSwitchingStress(void)
- {
- RyanJson_t root = RyanJsonCreateObject();
- RyanJsonAddIntToObject(root, "k", 1);
- // 疯狂类型切换
- // 高频类型切换
- // Int -> String
- TEST_ASSERT_TRUE(RyanJsonReplaceByKey(root, "k", RyanJsonCreateString("k", "s")));
- TEST_ASSERT_TRUE(RyanJsonIsString(RyanJsonGetObjectByKey(root, "k")));
- // String -> Array
- TEST_ASSERT_TRUE(RyanJsonReplaceByKey(root, "k", RyanJsonCreateArray()));
- TEST_ASSERT_TRUE(RyanJsonIsArray(RyanJsonGetObjectByKey(root, "k")));
- // 数组节点替换为对象节点
- TEST_ASSERT_TRUE(RyanJsonReplaceByKey(root, "k", RyanJsonCreateObject()));
- TEST_ASSERT_TRUE(RyanJsonIsObject(RyanJsonGetObjectByKey(root, "k")));
- // 对象节点替换为布尔节点
- TEST_ASSERT_TRUE(RyanJsonReplaceByKey(root, "k", RyanJsonCreateBool("k", RyanJsonTrue)));
- TEST_ASSERT_TRUE(RyanJsonIsBool(RyanJsonGetObjectByKey(root, "k")));
- // Bool -> Null
- TEST_ASSERT_TRUE(RyanJsonReplaceByKey(root, "k", RyanJsonCreateNull("k")));
- TEST_ASSERT_TRUE(RyanJsonIsNull(RyanJsonGetObjectByKey(root, "k")));
- // 自身替换(模拟):实际替换为副本节点
- RyanJson_t nullNode = RyanJsonGetObjectByKey(root, "k");
- RyanJson_t dupNull = RyanJsonDuplicate(nullNode);
- TEST_ASSERT_TRUE(RyanJsonReplaceByKey(root, "k", dupNull));
- TEST_ASSERT_TRUE(RyanJsonIsNull(RyanJsonGetObjectByKey(root, "k")));
- RyanJsonDelete(root);
- }
- void testReplaceRunner(void)
- {
- UnitySetTestFile(__FILE__);
- RUN_TEST(testReplaceEdgeCases);
- RUN_TEST(testReplaceSelfCheck);
- RUN_TEST(testReplaceRejectAttachedItem);
- RUN_TEST(testReplaceFailureKeepsItemOwnership);
- RUN_TEST(testReplaceFailureCallerMustDeleteItem);
- RUN_TEST(testReplaceKeyRewriteAndWrapPaths);
- RUN_TEST(testReplaceStandardOperations);
- RUN_TEST(testReplaceTypeSwitchingStress);
- }
|