testReplace.c 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487
  1. #include "testBase.h"
  2. static void testReplaceEdgeCases(void)
  3. {
  4. RyanJson_t obj = RyanJsonCreateObject();
  5. RyanJsonAddIntToObject(obj, "a", 1);
  6. // Replace NULL 参数
  7. RyanJson_t newItem = RyanJsonCreateInt("b", 2);
  8. TEST_ASSERT_FALSE_MESSAGE(RyanJsonReplaceByKey(NULL, "key", newItem), "ReplaceByKey(NULL, ...) 应返回 False");
  9. TEST_ASSERT_FALSE_MESSAGE(RyanJsonReplaceByKey(obj, NULL, newItem), "ReplaceByKey(..., key=NULL, ...) 应返回 False");
  10. // 注意:如果 Replace 失败,newItem 及其内存由谁负责?
  11. // 如果 Replace 函数返回 False 且没有接管 item,调用者需要释放 item。
  12. // RyanJsonReplaceByKey 检查参数失败时直接返回,不触碰 item。
  13. // 所以这里我们需要手动释放 newItem 以避免内存泄漏。
  14. RyanJsonDelete(newItem);
  15. newItem = RyanJsonCreateInt("b", 2);
  16. TEST_ASSERT_FALSE_MESSAGE(RyanJsonReplaceByKey(obj, "a", NULL), "ReplaceByKey(..., item=NULL) 应返回 False");
  17. // newItem 在这里没被传入成功,所以需要手动释放
  18. RyanJsonDelete(newItem);
  19. // Replace 不存在的 Key (应失败,而不是添加)
  20. newItem = RyanJsonCreateInt("b", 2);
  21. TEST_ASSERT_FALSE_MESSAGE(RyanJsonReplaceByKey(obj, "non_existent", newItem), "ReplaceByKey(不存在的Key) 应返回 False");
  22. // 同样,替换失败,需释放 newItem
  23. RyanJsonDelete(newItem);
  24. // Replace Index 越界
  25. newItem = RyanJsonCreateInt("b", 2);
  26. TEST_ASSERT_FALSE_MESSAGE(RyanJsonReplaceByIndex(obj, 99, newItem), "ReplaceByIndex(越界) 应返回 False");
  27. RyanJsonDelete(newItem);
  28. // ReplaceByIndex 在对象上的重复 key 行为由严格模式控制
  29. RyanJsonAddIntToObject(obj, "b", 2);
  30. newItem = RyanJsonCreateInt("a", 9);
  31. #if true == RyanJsonDefaultAddAtHead
  32. uint32_t replaceIndex = 0; // 头插模式下,后加的 "b" 位于索引 0
  33. #else
  34. uint32_t replaceIndex = 1; // 尾插模式下,后加的 "b" 位于索引 1
  35. #endif
  36. #if true == RyanJsonStrictObjectKeyCheck
  37. TEST_ASSERT_FALSE_MESSAGE(RyanJsonReplaceByIndex(obj, replaceIndex, newItem),
  38. "严格模式下 ReplaceByIndex(Object) 重复 key 应返回 False");
  39. RyanJsonDelete(newItem);
  40. TEST_ASSERT_EQUAL_INT(1, RyanJsonGetIntValue(RyanJsonGetObjectByKey(obj, "a")));
  41. TEST_ASSERT_EQUAL_INT(2, RyanJsonGetIntValue(RyanJsonGetObjectByKey(obj, "b")));
  42. #else
  43. TEST_ASSERT_TRUE_MESSAGE(RyanJsonReplaceByIndex(obj, replaceIndex, newItem),
  44. "非严格模式下 ReplaceByIndex(Object) 重复 key 应返回 True");
  45. #if true == RyanJsonDefaultAddAtHead
  46. TEST_ASSERT_EQUAL_INT(9, RyanJsonGetIntValue(RyanJsonGetObjectByKey(obj, "a")));
  47. #else
  48. TEST_ASSERT_EQUAL_INT(1, RyanJsonGetIntValue(RyanJsonGetObjectByKey(obj, "a")));
  49. #endif
  50. TEST_ASSERT_NULL_MESSAGE(RyanJsonGetObjectByKey(obj, "b"), "非严格模式替换后 b 应被替换掉");
  51. #endif
  52. // ReplaceByIndex 在对象上使用相同 key 替换应成功
  53. // 该用例覆盖冲突检查中的 item == skipItem 分支(应跳过被替换节点本身)
  54. newItem = RyanJsonCreateInt("b", 99);
  55. TEST_ASSERT_TRUE_MESSAGE(RyanJsonReplaceByIndex(obj, replaceIndex, newItem), "ReplaceByIndex(Object) 同 key 替换应成功");
  56. TEST_ASSERT_EQUAL_INT(1, RyanJsonGetIntValue(RyanJsonGetObjectByKey(obj, "a")));
  57. TEST_ASSERT_EQUAL_INT(99, RyanJsonGetIntValue(RyanJsonGetObjectByKey(obj, "b")));
  58. // 对非容器操作
  59. RyanJson_t num = RyanJsonCreateInt("num", 1);
  60. newItem = RyanJsonCreateInt("val", 2);
  61. TEST_ASSERT_FALSE_MESSAGE(RyanJsonReplaceByKey(num, "any", newItem), "对非容器 ReplaceByKey 应返回 False");
  62. RyanJsonDelete(newItem);
  63. RyanJsonDelete(obj);
  64. RyanJsonDelete(num);
  65. }
  66. static void testReplaceSelfCheck(void)
  67. {
  68. // 测试:尝试将节点替换为其自身(RyanJsonReplaceByKey/Index 至少应保持稳定,不发生崩溃)。
  69. // 但 API 语义通常要求 newItem 是新建节点,且不属于任何树(或来自其他位置的 Detach)。
  70. // 因此这里不直接传入“树内同一节点”,而是使用语义等价的替换场景做覆盖。
  71. // 测试:替换为“较重”的新节点(大数组)
  72. RyanJson_t obj = RyanJsonCreateObject();
  73. RyanJsonAddIntToObject(obj, "k", 1);
  74. RyanJson_t bigArr = RyanJsonCreateArray();
  75. for (int32_t i = 0; i < 100; i++)
  76. {
  77. RyanJsonAddIntToArray(bigArr, i);
  78. }
  79. TEST_ASSERT_TRUE(RyanJsonReplaceByKey(obj, "k", bigArr));
  80. TEST_ASSERT_EQUAL_INT(100, RyanJsonGetArraySize(RyanJsonGetObjectByKey(obj, "k")));
  81. RyanJsonDelete(obj);
  82. }
  83. static void testReplaceRejectAttachedItem(void)
  84. {
  85. RyanJson_t obj1 = RyanJsonCreateObject();
  86. RyanJson_t obj2 = RyanJsonCreateObject();
  87. RyanJsonAddIntToObject(obj1, "a", 1);
  88. RyanJsonAddIntToObject(obj2, "b", 2);
  89. RyanJson_t attachedObjItem = RyanJsonGetObjectByKey(obj1, "a");
  90. TEST_ASSERT_NOT_NULL(attachedObjItem);
  91. TEST_ASSERT_FALSE_MESSAGE(RyanJsonReplaceByKey(obj2, "b", attachedObjItem), "已挂树的 item 不应作为 ReplaceByKey 参数");
  92. TEST_ASSERT_EQUAL_INT(2, RyanJsonGetIntValue(RyanJsonGetObjectByKey(obj2, "b")));
  93. TEST_ASSERT_EQUAL_INT(1, RyanJsonGetIntValue(RyanJsonGetObjectByKey(obj1, "a")));
  94. RyanJson_t arr1 = RyanJsonCreateArray();
  95. RyanJson_t arr2 = RyanJsonCreateArray();
  96. RyanJsonAddIntToArray(arr1, 10);
  97. RyanJsonAddIntToArray(arr2, 20);
  98. RyanJson_t attachedArrItem = RyanJsonGetObjectByIndex(arr1, 0);
  99. TEST_ASSERT_NOT_NULL(attachedArrItem);
  100. TEST_ASSERT_FALSE_MESSAGE(RyanJsonReplaceByIndex(arr2, 0, attachedArrItem), "已挂树的 item 不应作为 ReplaceByIndex 参数");
  101. TEST_ASSERT_EQUAL_INT(20, RyanJsonGetIntValue(RyanJsonGetObjectByIndex(arr2, 0)));
  102. TEST_ASSERT_EQUAL_INT(10, RyanJsonGetIntValue(RyanJsonGetObjectByIndex(arr1, 0)));
  103. RyanJsonDelete(obj1);
  104. RyanJsonDelete(obj2);
  105. RyanJsonDelete(arr1);
  106. RyanJsonDelete(arr2);
  107. }
  108. static void testReplaceFailureKeepsItemOwnership(void)
  109. {
  110. // ReplaceByIndex 失败后,item 应仍由调用方持有
  111. RyanJson_t obj = RyanJsonCreateObject();
  112. TEST_ASSERT_NOT_NULL(obj);
  113. TEST_ASSERT_TRUE(RyanJsonAddIntToObject(obj, "a", 1));
  114. TEST_ASSERT_TRUE(RyanJsonAddIntToObject(obj, "b", 2));
  115. RyanJson_t conflictItem = RyanJsonCreateInt("a", 9);
  116. TEST_ASSERT_NOT_NULL(conflictItem);
  117. #if true == RyanJsonStrictObjectKeyCheck
  118. #if true == RyanJsonDefaultAddAtHead
  119. TEST_ASSERT_FALSE(RyanJsonReplaceByIndex(obj, 0, conflictItem));
  120. #else
  121. TEST_ASSERT_FALSE(RyanJsonReplaceByIndex(obj, 1, conflictItem));
  122. #endif
  123. #else
  124. TEST_ASSERT_FALSE(RyanJsonReplaceByIndex(obj, 99, conflictItem));
  125. #endif
  126. TEST_ASSERT_TRUE_MESSAGE(RyanJsonIsDetachedItem(conflictItem), "ReplaceByIndex 失败后 item 不应被消费");
  127. RyanJson_t arr = RyanJsonCreateArray();
  128. TEST_ASSERT_NOT_NULL(arr);
  129. TEST_ASSERT_TRUE(RyanJsonInsert(arr, 0, conflictItem));
  130. TEST_ASSERT_EQUAL_INT(9, RyanJsonGetIntValue(RyanJsonGetObjectByIndex(arr, 0)));
  131. // ReplaceByKey 失败(目标 key 不存在)后,item 也应可复用
  132. RyanJson_t notFoundItem = RyanJsonCreateString("tmp", "v");
  133. TEST_ASSERT_NOT_NULL(notFoundItem);
  134. TEST_ASSERT_FALSE(RyanJsonReplaceByKey(obj, "not_exist", notFoundItem));
  135. TEST_ASSERT_TRUE_MESSAGE(RyanJsonIsDetachedItem(notFoundItem), "ReplaceByKey 失败后 item 不应被消费");
  136. TEST_ASSERT_TRUE(RyanJsonInsert(arr, UINT32_MAX, notFoundItem));
  137. TEST_ASSERT_EQUAL_STRING("v", RyanJsonGetStringValue(RyanJsonGetObjectByIndex(arr, 1)));
  138. RyanJsonDelete(arr);
  139. RyanJsonDelete(obj);
  140. }
  141. static void testReplaceFailureCallerMustDeleteItem(void)
  142. {
  143. /*
  144. * 约定验证:
  145. * Replace 失败时库不会释放 item,调用方必须手动释放。
  146. */
  147. RyanJson_t obj = RyanJsonCreateObject();
  148. TEST_ASSERT_NOT_NULL(obj);
  149. TEST_ASSERT_TRUE(RyanJsonAddIntToObject(obj, "a", 1));
  150. // ReplaceByKey 失败:目标 key 不存在
  151. RyanJson_t replaceByKeyItem = RyanJsonCreateString("tmp", "v");
  152. TEST_ASSERT_NOT_NULL(replaceByKeyItem);
  153. TEST_ASSERT_FALSE(RyanJsonReplaceByKey(obj, "not_exist", replaceByKeyItem));
  154. TEST_ASSERT_TRUE_MESSAGE(RyanJsonIsDetachedItem(replaceByKeyItem), "ReplaceByKey 失败后 item 应保持游离");
  155. RyanJsonDelete(replaceByKeyItem); // 调用方主动释放
  156. // ReplaceByIndex 失败:索引越界
  157. RyanJson_t replaceByIndexItem = RyanJsonCreateInt("a", 9);
  158. TEST_ASSERT_NOT_NULL(replaceByIndexItem);
  159. TEST_ASSERT_FALSE(RyanJsonReplaceByIndex(obj, 99, replaceByIndexItem));
  160. TEST_ASSERT_TRUE_MESSAGE(RyanJsonIsDetachedItem(replaceByIndexItem), "ReplaceByIndex 失败后 item 应保持游离");
  161. RyanJsonDelete(replaceByIndexItem); // 调用方主动释放
  162. // 原树应保持不变
  163. TEST_ASSERT_EQUAL_INT(1, RyanJsonGetIntValue(RyanJsonGetObjectByKey(obj, "a")));
  164. RyanJsonDelete(obj);
  165. }
  166. static void testReplaceKeyRewriteAndWrapPaths(void)
  167. {
  168. RyanJson_t obj = RyanJsonCreateObject();
  169. TEST_ASSERT_NOT_NULL(obj);
  170. TEST_ASSERT_TRUE(RyanJsonAddIntToObject(obj, "a", 1));
  171. TEST_ASSERT_TRUE(RyanJsonAddIntToObject(obj, "b", 2));
  172. // 无 key 的容器替换对象字段:应自动包装成 key="a"
  173. RyanJson_t noKeyContainer = RyanJsonCreateObject();
  174. TEST_ASSERT_NOT_NULL(noKeyContainer);
  175. TEST_ASSERT_TRUE(RyanJsonAddIntToObject(noKeyContainer, "x", 7));
  176. TEST_ASSERT_TRUE_MESSAGE(RyanJsonReplaceByKey(obj, "a", noKeyContainer), "ReplaceByKey(无 key 容器) 应成功");
  177. RyanJson_t aNode = RyanJsonGetObjectByKey(obj, "a");
  178. TEST_ASSERT_NOT_NULL(aNode);
  179. TEST_ASSERT_TRUE(RyanJsonIsObject(aNode));
  180. TEST_ASSERT_EQUAL_INT(7, RyanJsonGetIntValue(RyanJsonGetObjectByKey(aNode, "x")));
  181. // 无 key 的标量替换对象字段:当前实现会包装为 key="a" 的 object,并把标量作为唯一子节点
  182. RyanJson_t noKeyScalar = RyanJsonCreateInt(NULL, 123);
  183. TEST_ASSERT_NOT_NULL(noKeyScalar);
  184. TEST_ASSERT_TRUE_MESSAGE(RyanJsonReplaceByKey(obj, "a", noKeyScalar), "ReplaceByKey(无 key 标量) 应成功");
  185. aNode = RyanJsonGetObjectByKey(obj, "a");
  186. TEST_ASSERT_NOT_NULL(aNode);
  187. TEST_ASSERT_TRUE_MESSAGE(RyanJsonIsObject(aNode), "无 key 标量替换后应包装为对象节点");
  188. TEST_ASSERT_EQUAL_UINT32(1, RyanJsonGetSize(aNode));
  189. TEST_ASSERT_EQUAL_INT(123, RyanJsonGetIntValue(RyanJsonGetObjectByIndex(aNode, 0)));
  190. // 不同 key 的节点替换:应重命名为目标 key="b"
  191. RyanJson_t diffKeyItem = RyanJsonCreateInt("temp", 88);
  192. TEST_ASSERT_NOT_NULL(diffKeyItem);
  193. TEST_ASSERT_TRUE_MESSAGE(RyanJsonReplaceByKey(obj, "b", diffKeyItem), "ReplaceByKey(不同 key) 应成功");
  194. TEST_ASSERT_EQUAL_INT(88, RyanJsonGetIntValue(RyanJsonGetObjectByKey(obj, "b")));
  195. TEST_ASSERT_NULL_MESSAGE(RyanJsonGetObjectByKey(obj, "temp"), "ReplaceByKey 后不应残留旧 key");
  196. RyanJsonDelete(obj);
  197. }
  198. static void testReplaceStandardOperations(void)
  199. {
  200. char jsonstr[] =
  201. "{\"inter\":16,\"double\":16.89,\"string\":\"hello\",\"boolTrue\":true,\"boolFalse\":false,\"null\":null,\"item\":"
  202. "{\"inter\":16,\"double\":16.89,\"string\":\"hello\",\"boolTrue\":true,\"boolFalse\":false,\"null\":null},"
  203. "\"arrayInt\":[16,16,16,16,16],\"arrayDouble\":[16.89,16.89,16.89,16.89,16.89],"
  204. "\"arrayString\":[\"hello\",\"hello\",\"hello\",\"hello\",\"hello\"],"
  205. "\"array\":[16,16.89,\"hello\",true,false,null],"
  206. "\"arrayItem\":[{\"inter\":16,\"double\":16.89,\"string\":\"hello\",\"boolTrue\":true,\"boolFalse\":false,\"null\":null},"
  207. "{\"inter\":16,\"double\":16.89,\"string\":\"hello\",\"boolTrue\":true,\"boolFalse\":false,\"null\":null}],"
  208. "\"string2222\":\"hello\"}";
  209. RyanJson_t json = RyanJsonParse(jsonstr);
  210. TEST_ASSERT_NOT_NULL_MESSAGE(json, "解析基础 Json 失败");
  211. // 数组替换测试:arrayInt 头部
  212. RyanJsonReplaceByIndex(RyanJsonGetObjectToKey(json, "arrayInt"), 0, RyanJsonCreateString(NULL, "arrayIntHead"));
  213. {
  214. RyanJson_t v = RyanJsonGetObjectToIndex(RyanJsonGetObjectToKey(json, "arrayInt"), 0);
  215. TEST_ASSERT_TRUE_MESSAGE(RyanJsonIsString(v), "替换后的 arrayInt[0] 不是字符串");
  216. TEST_ASSERT_EQUAL_STRING_MESSAGE("arrayIntHead", RyanJsonGetStringValue(v), "替换后的 arrayInt[0] 值错误");
  217. }
  218. // 数组替换测试:arrayInt 尾部
  219. {
  220. RyanJson_t arr = RyanJsonGetObjectToKey(json, "arrayInt");
  221. uint32_t last = RyanJsonGetSize(arr) - 1;
  222. RyanJsonReplaceByIndex(arr, last, RyanJsonCreateString(NULL, "arrayIntTail"));
  223. RyanJson_t v = RyanJsonGetObjectToIndex(arr, last);
  224. TEST_ASSERT_TRUE_MESSAGE(RyanJsonIsString(v), "替换后的 arrayInt 尾部不是字符串");
  225. TEST_ASSERT_EQUAL_STRING_MESSAGE("arrayIntTail", RyanJsonGetStringValue(v), "替换后的 arrayInt 尾部值错误");
  226. }
  227. // 数组对象替换测试:arrayItem[0]
  228. RyanJsonReplaceByIndex(RyanJsonGetObjectToKey(json, "arrayItem"), 0, RyanJsonCreateString(NULL, "arrayItem0"));
  229. {
  230. RyanJson_t v = RyanJsonGetObjectToIndex(RyanJsonGetObjectToKey(json, "arrayItem"), 0);
  231. TEST_ASSERT_TRUE_MESSAGE(RyanJsonIsString(v), "替换后的 arrayItem[0] 不是字符串");
  232. TEST_ASSERT_EQUAL_STRING_MESSAGE("arrayItem0", RyanJsonGetStringValue(v), "替换后的 arrayItem[0] 值错误");
  233. }
  234. // 对象字段替换:inter -> 999
  235. RyanJsonReplaceByKey(json, "inter", RyanJsonCreateInt("inter", 999));
  236. {
  237. RyanJson_t v = RyanJsonGetObjectToKey(json, "inter");
  238. TEST_ASSERT_TRUE_MESSAGE(RyanJsonIsInt(v), "替换后的 inter 不是整数");
  239. TEST_ASSERT_EQUAL_INT_MESSAGE(999, RyanJsonGetIntValue(v), "替换后的 inter 值错误");
  240. }
  241. // 对象字段替换:double -> 123.45
  242. RyanJsonReplaceByKey(json, "double", RyanJsonCreateDouble("double", 123.45));
  243. {
  244. RyanJson_t v = RyanJsonGetObjectToKey(json, "double");
  245. TEST_ASSERT_TRUE_MESSAGE(RyanJsonIsDouble(v), "替换后的 double 不是浮点数");
  246. TEST_ASSERT_TRUE_MESSAGE(RyanJsonCompareDouble(123.45, RyanJsonGetDoubleValue(v)), "替换后的 double 值错误");
  247. }
  248. // 对象字段替换:string -> "newString"
  249. RyanJsonReplaceByKey(json, "string", RyanJsonCreateString("string", "newString"));
  250. {
  251. RyanJson_t v = RyanJsonGetObjectToKey(json, "string");
  252. TEST_ASSERT_TRUE_MESSAGE(RyanJsonIsString(v), "替换后的 string 不是字符串");
  253. TEST_ASSERT_EQUAL_STRING_MESSAGE("newString", RyanJsonGetStringValue(v), "替换后的 string 值错误");
  254. }
  255. // 对象字段替换:boolFalse -> true
  256. RyanJsonReplaceByKey(json, "boolFalse", RyanJsonCreateBool("boolFalse", RyanJsonTrue));
  257. {
  258. RyanJson_t v = RyanJsonGetObjectToKey(json, "boolFalse");
  259. TEST_ASSERT_TRUE_MESSAGE(RyanJsonIsBool(v), "替换后的 boolFalse 不是布尔值");
  260. TEST_ASSERT_EQUAL_INT_MESSAGE(RyanJsonTrue, RyanJsonGetBoolValue(v), "替换后的 boolFalse 值错误");
  261. }
  262. // 数组替换:arrayString 中间元素 -> "headString"
  263. RyanJsonReplaceByIndex(RyanJsonGetObjectToKey(json, "arrayString"), 1, RyanJsonCreateString(NULL, "headString"));
  264. {
  265. RyanJson_t v = RyanJsonGetObjectToIndex(RyanJsonGetObjectToKey(json, "arrayString"), 1);
  266. TEST_ASSERT_TRUE_MESSAGE(RyanJsonIsString(v), "替换后的 arrayString[1] 不是字符串");
  267. TEST_ASSERT_EQUAL_STRING_MESSAGE("headString", RyanJsonGetStringValue(v), "替换后的 arrayString[1] 值错误");
  268. }
  269. // 数组项替换测试:arrayString 尾部
  270. {
  271. RyanJson_t arr = RyanJsonGetObjectToKey(json, "arrayString");
  272. uint32_t last = RyanJsonGetSize(arr) - 1;
  273. RyanJsonReplaceByIndex(arr, last, RyanJsonCreateString(NULL, "tailString"));
  274. RyanJson_t v = RyanJsonGetObjectToIndex(arr, last);
  275. TEST_ASSERT_TRUE_MESSAGE(RyanJsonIsString(v), "替换后的 arrayString 尾部不是字符串");
  276. TEST_ASSERT_EQUAL_STRING_MESSAGE("tailString", RyanJsonGetStringValue(v), "替换后的 arrayString 尾部值错误");
  277. }
  278. // 数组对象替换:arrayItem 尾部 -> "arrayItemTail"
  279. {
  280. RyanJson_t arr = RyanJsonGetObjectToKey(json, "arrayItem");
  281. uint32_t last = RyanJsonGetSize(arr) - 1;
  282. RyanJsonReplaceByIndex(arr, last, RyanJsonCreateString(NULL, "arrayItemTail"));
  283. RyanJson_t v = RyanJsonGetObjectToIndex(arr, last);
  284. TEST_ASSERT_TRUE_MESSAGE(RyanJsonIsString(v), "替换后的 arrayItem 尾部不是字符串");
  285. TEST_ASSERT_EQUAL_STRING_MESSAGE("arrayItemTail", RyanJsonGetStringValue(v), "替换后的 arrayItem 尾部值错误");
  286. }
  287. // 嵌套对象替换:item.inter -> 111
  288. RyanJsonReplaceByKey(RyanJsonGetObjectToKey(json, "item"), "inter", RyanJsonCreateInt("inter", 111));
  289. {
  290. RyanJson_t v = RyanJsonGetObjectToKey(RyanJsonGetObjectToKey(json, "item"), "inter");
  291. TEST_ASSERT_TRUE_MESSAGE(RyanJsonIsInt(v), "替换后的 item.inter 不是整数");
  292. TEST_ASSERT_EQUAL_INT_MESSAGE(111, RyanJsonGetIntValue(v), "替换后的 item.inter 值错误");
  293. }
  294. // 嵌套对象替换:item.string -> "nestedReplace"
  295. RyanJsonReplaceByKey(RyanJsonGetObjectToKey(json, "item"), "string", RyanJsonCreateString("string", "nestedReplace"));
  296. {
  297. RyanJson_t v = RyanJsonGetObjectToKey(RyanJsonGetObjectToKey(json, "item"), "string");
  298. TEST_ASSERT_TRUE_MESSAGE(RyanJsonIsString(v), "替换后的 item.string 不是字符串");
  299. TEST_ASSERT_EQUAL_STRING_MESSAGE("nestedReplace", RyanJsonGetStringValue(v), "替换后的 item.string 值错误");
  300. }
  301. // 混合数组替换测试
  302. RyanJson_t mixArr = RyanJsonGetObjectToKey(json, "array");
  303. // int32_t -> "intReplaced"
  304. RyanJsonReplaceByIndex(mixArr, 0, RyanJsonCreateString(NULL, "intReplaced"));
  305. {
  306. RyanJson_t v = RyanJsonGetObjectToIndex(mixArr, 0);
  307. TEST_ASSERT_TRUE_MESSAGE(RyanJsonIsString(v), "替换后的 array[0] 不是字符串");
  308. TEST_ASSERT_EQUAL_STRING_MESSAGE("intReplaced", RyanJsonGetStringValue(v), "替换后的 array[0] 值错误");
  309. }
  310. // double -> "doubleReplaced"
  311. RyanJsonReplaceByIndex(mixArr, 1, RyanJsonCreateString(NULL, "doubleReplaced"));
  312. {
  313. RyanJson_t v = RyanJsonGetObjectToIndex(mixArr, 1);
  314. TEST_ASSERT_TRUE_MESSAGE(RyanJsonIsString(v), "替换后的 array[1] 不是字符串");
  315. TEST_ASSERT_EQUAL_STRING_MESSAGE("doubleReplaced", RyanJsonGetStringValue(v), "替换后的 array[1] 值错误");
  316. }
  317. // string -> "stringReplaced"
  318. RyanJsonReplaceByIndex(mixArr, 2, RyanJsonCreateString(NULL, "stringReplaced"));
  319. {
  320. RyanJson_t v = RyanJsonGetObjectToIndex(mixArr, 2);
  321. TEST_ASSERT_TRUE_MESSAGE(RyanJsonIsString(v), "替换后的 array[2] 不是字符串");
  322. TEST_ASSERT_EQUAL_STRING_MESSAGE("stringReplaced", RyanJsonGetStringValue(v), "替换后的 array[2] 值错误");
  323. }
  324. // bool -> "boolReplaced"
  325. RyanJsonReplaceByIndex(mixArr, 3, RyanJsonCreateString(NULL, "boolReplaced"));
  326. {
  327. RyanJson_t v = RyanJsonGetObjectToIndex(mixArr, 3);
  328. TEST_ASSERT_TRUE_MESSAGE(RyanJsonIsString(v), "替换后的 array[3] 不是字符串");
  329. TEST_ASSERT_EQUAL_STRING_MESSAGE("boolReplaced", RyanJsonGetStringValue(v), "替换后的 array[3] 值错误");
  330. }
  331. // null -> "nullReplaced"
  332. RyanJsonReplaceByIndex(mixArr, 5, RyanJsonCreateString(NULL, "nullReplaced"));
  333. {
  334. RyanJson_t v = RyanJsonGetObjectToIndex(mixArr, 5);
  335. TEST_ASSERT_TRUE_MESSAGE(RyanJsonIsString(v), "替换后的 array[5] 不是字符串");
  336. TEST_ASSERT_EQUAL_STRING_MESSAGE("nullReplaced", RyanJsonGetStringValue(v), "替换后的 array[5] 值错误");
  337. }
  338. // 替换整个数组项:arrayString -> "arrayStringRenamed"
  339. RyanJsonReplaceByKey(json, "arrayString", RyanJsonCreateString("arrayString", "arrayStringRenamed"));
  340. {
  341. RyanJson_t v = RyanJsonGetObjectToKey(json, "arrayString");
  342. TEST_ASSERT_TRUE_MESSAGE(RyanJsonIsString(v), "替换后的 arrayString 不是字符串");
  343. TEST_ASSERT_EQUAL_STRING_MESSAGE("arrayStringRenamed", RyanJsonGetStringValue(v), "替换后的 arrayString 值错误");
  344. }
  345. // 修改数组节点为对象节点:arrayDouble -> duplicate(item)
  346. RyanJson_t duplicateJson = RyanJsonDuplicate(RyanJsonGetObjectToKey(json, "item"));
  347. RyanJsonReplaceByKey(json, "arrayDouble", duplicateJson);
  348. {
  349. RyanJson_t v = RyanJsonGetObjectToKey(json, "arrayDouble");
  350. TEST_ASSERT_TRUE_MESSAGE(RyanJsonIsObject(v), "替换后的 arrayDouble 不是对象类型");
  351. }
  352. // 替换字符串字段:string2222 -> "world"
  353. RyanJsonReplaceByKey(json, "string2222", RyanJsonCreateString("string2222", "world"));
  354. {
  355. RyanJson_t v = RyanJsonGetObjectToKey(json, "string2222");
  356. TEST_ASSERT_TRUE_MESSAGE(RyanJsonIsString(v), "替换后的 string2222 不是字符串");
  357. TEST_ASSERT_EQUAL_STRING_MESSAGE("world", RyanJsonGetStringValue(v), "替换后的 string2222 值错误");
  358. }
  359. // 替换 boolValue:boolTrue -> false
  360. RyanJsonReplaceByKey(json, "boolTrue", RyanJsonCreateBool("boolTrue", RyanJsonFalse));
  361. {
  362. RyanJson_t v = RyanJsonGetObjectToKey(json, "boolTrue");
  363. TEST_ASSERT_TRUE_MESSAGE(RyanJsonIsBool(v), "替换后的 boolTrue 不是布尔值");
  364. TEST_ASSERT_EQUAL_INT_MESSAGE(RyanJsonFalse, RyanJsonGetBoolValue(v), "替换后的 boolTrue 值错误");
  365. }
  366. // 替换 null 为字符串
  367. RyanJsonReplaceByKey(json, "null", RyanJsonCreateString("null", "notNull"));
  368. {
  369. RyanJson_t v = RyanJsonGetObjectToKey(json, "null");
  370. TEST_ASSERT_TRUE_MESSAGE(RyanJsonIsString(v), "替换后的 null 不是字符串");
  371. TEST_ASSERT_EQUAL_STRING_MESSAGE("notNull", RyanJsonGetStringValue(v), "替换后的 null 值错误");
  372. }
  373. char *str = RyanJsonPrint(json, 1024, RyanJsonTrue, NULL);
  374. RyanJsonFree(str);
  375. RyanJsonDelete(json);
  376. }
  377. static void testReplaceTypeSwitchingStress(void)
  378. {
  379. RyanJson_t root = RyanJsonCreateObject();
  380. RyanJsonAddIntToObject(root, "k", 1);
  381. // 疯狂类型切换
  382. // 高频类型切换
  383. // Int -> String
  384. TEST_ASSERT_TRUE(RyanJsonReplaceByKey(root, "k", RyanJsonCreateString("k", "s")));
  385. TEST_ASSERT_TRUE(RyanJsonIsString(RyanJsonGetObjectByKey(root, "k")));
  386. // String -> Array
  387. TEST_ASSERT_TRUE(RyanJsonReplaceByKey(root, "k", RyanJsonCreateArray()));
  388. TEST_ASSERT_TRUE(RyanJsonIsArray(RyanJsonGetObjectByKey(root, "k")));
  389. // 数组节点替换为对象节点
  390. TEST_ASSERT_TRUE(RyanJsonReplaceByKey(root, "k", RyanJsonCreateObject()));
  391. TEST_ASSERT_TRUE(RyanJsonIsObject(RyanJsonGetObjectByKey(root, "k")));
  392. // 对象节点替换为布尔节点
  393. TEST_ASSERT_TRUE(RyanJsonReplaceByKey(root, "k", RyanJsonCreateBool("k", RyanJsonTrue)));
  394. TEST_ASSERT_TRUE(RyanJsonIsBool(RyanJsonGetObjectByKey(root, "k")));
  395. // Bool -> Null
  396. TEST_ASSERT_TRUE(RyanJsonReplaceByKey(root, "k", RyanJsonCreateNull("k")));
  397. TEST_ASSERT_TRUE(RyanJsonIsNull(RyanJsonGetObjectByKey(root, "k")));
  398. // 自身替换(模拟):实际替换为副本节点
  399. RyanJson_t nullNode = RyanJsonGetObjectByKey(root, "k");
  400. RyanJson_t dupNull = RyanJsonDuplicate(nullNode);
  401. TEST_ASSERT_TRUE(RyanJsonReplaceByKey(root, "k", dupNull));
  402. TEST_ASSERT_TRUE(RyanJsonIsNull(RyanJsonGetObjectByKey(root, "k")));
  403. RyanJsonDelete(root);
  404. }
  405. void testReplaceRunner(void)
  406. {
  407. UnitySetTestFile(__FILE__);
  408. RUN_TEST(testReplaceEdgeCases);
  409. RUN_TEST(testReplaceSelfCheck);
  410. RUN_TEST(testReplaceRejectAttachedItem);
  411. RUN_TEST(testReplaceFailureKeepsItemOwnership);
  412. RUN_TEST(testReplaceFailureCallerMustDeleteItem);
  413. RUN_TEST(testReplaceKeyRewriteAndWrapPaths);
  414. RUN_TEST(testReplaceStandardOperations);
  415. RUN_TEST(testReplaceTypeSwitchingStress);
  416. }