testDelete.c 9.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268
  1. #include "testBase.h"
  2. static void testDeleteEdgeCases(void)
  3. {
  4. // 删除 NULL(应安全返回)
  5. RyanJsonDelete(NULL);
  6. // RyanJsonDeleteByKey 参数校验
  7. RyanJson_t obj = RyanJsonCreateObject();
  8. RyanJsonAddIntToObject(obj, "a", 1);
  9. TEST_ASSERT_FALSE_MESSAGE(RyanJsonDeleteByKey(NULL, "a"), "DeleteByKey(NULL, key) 应返回 False");
  10. TEST_ASSERT_FALSE_MESSAGE(RyanJsonDeleteByKey(obj, NULL), "DeleteByKey(obj, NULL) 应返回 False");
  11. TEST_ASSERT_FALSE_MESSAGE(RyanJsonDeleteByKey(obj, "non_existent"), "DeleteByKey(不存在的key) 应返回 False");
  12. // RyanJsonDeleteByIndex 参数校验
  13. TEST_ASSERT_FALSE_MESSAGE(RyanJsonDeleteByIndex(NULL, 0), "DeleteByIndex(NULL, 0) 应返回 False");
  14. TEST_ASSERT_FALSE_MESSAGE(RyanJsonDeleteByIndex(obj, 999), "DeleteByIndex(越界) 应返回 False");
  15. // 从非容器类型删除
  16. RyanJson_t num = RyanJsonCreateInt("num", 123);
  17. TEST_ASSERT_FALSE_MESSAGE(RyanJsonDeleteByKey(num, "a"), "从非容器 DeleteByKey 应返回 False"); // 内部 Detach 会做类型与存在性检查
  18. TEST_ASSERT_FALSE_MESSAGE(RyanJsonDeleteByIndex(num, 0), "从非容器 DeleteByIndex 应返回 False");
  19. RyanJsonDelete(obj);
  20. RyanJsonDelete(num);
  21. }
  22. static void testDeleteMassiveItemsStress(void)
  23. {
  24. // 连续删除直到空(Array)
  25. RyanJson_t arr = RyanJsonCreateArray();
  26. for (int32_t i = 0; i < 100; i++)
  27. {
  28. RyanJsonAddIntToArray(arr, i);
  29. }
  30. TEST_ASSERT_EQUAL_INT(100, RyanJsonGetSize(arr));
  31. // 从头部连续删除
  32. while (RyanJsonGetSize(arr) > 0)
  33. {
  34. TEST_ASSERT_TRUE(RyanJsonDeleteByIndex(arr, 0));
  35. }
  36. TEST_ASSERT_EQUAL_INT(0, RyanJsonGetSize(arr));
  37. // 空数组删除
  38. TEST_ASSERT_FALSE(RyanJsonDeleteByIndex(arr, 0));
  39. RyanJsonDelete(arr);
  40. // 连续删除直到空(Object)
  41. RyanJson_t obj = RyanJsonCreateObject();
  42. char key[16];
  43. for (int32_t i = 0; i < 100; i++)
  44. {
  45. snprintf(key, sizeof(key), "%d", i);
  46. RyanJsonAddIntToObject(obj, key, i);
  47. }
  48. TEST_ASSERT_EQUAL_INT(100, RyanJsonGetSize(obj));
  49. // 从头部连续删除(Object 也是链表,ByIndex=0 有效)
  50. while (RyanJsonGetSize(obj) > 0)
  51. {
  52. TEST_ASSERT_TRUE(RyanJsonDeleteByIndex(obj, 0));
  53. }
  54. TEST_ASSERT_EQUAL_INT(0, RyanJsonGetSize(obj));
  55. // 对象按 key 全量删除
  56. for (int32_t i = 0; i < 100; i++)
  57. {
  58. snprintf(key, sizeof(key), "%d", i);
  59. RyanJsonAddIntToObject(obj, key, i);
  60. }
  61. for (int32_t i = 0; i < 100; i++)
  62. {
  63. snprintf(key, sizeof(key), "%d", i);
  64. TEST_ASSERT_TRUE(RyanJsonDeleteByKey(obj, key));
  65. }
  66. TEST_ASSERT_EQUAL_INT(0, RyanJsonGetSize(obj));
  67. // 空 Object 删除不存在的 key
  68. TEST_ASSERT_FALSE(RyanJsonDeleteByKey(obj, "any"));
  69. RyanJsonDelete(obj);
  70. }
  71. static void testDeleteSingleNodeAndReuse(void)
  72. {
  73. // Object:删除唯一节点后应保持可复用
  74. RyanJson_t obj = RyanJsonCreateObject();
  75. TEST_ASSERT_NOT_NULL(obj);
  76. TEST_ASSERT_TRUE(RyanJsonAddIntToObject(obj, "a", 1));
  77. TEST_ASSERT_TRUE(RyanJsonDeleteByKey(obj, "a"));
  78. TEST_ASSERT_EQUAL_INT(0, RyanJsonGetSize(obj));
  79. TEST_ASSERT_NULL(RyanJsonGetObjectValue(obj));
  80. TEST_ASSERT_FALSE(RyanJsonDeleteByKey(obj, "a"));
  81. TEST_ASSERT_TRUE(RyanJsonAddStringToObject(obj, "b", "ok"));
  82. TEST_ASSERT_EQUAL_INT(1, RyanJsonGetSize(obj));
  83. TEST_ASSERT_EQUAL_STRING("ok", RyanJsonGetStringValue(RyanJsonGetObjectByKey(obj, "b")));
  84. // Array:删除唯一节点后应保持可复用
  85. RyanJson_t arr = RyanJsonCreateArray();
  86. TEST_ASSERT_NOT_NULL(arr);
  87. TEST_ASSERT_TRUE(RyanJsonAddIntToArray(arr, 9));
  88. TEST_ASSERT_TRUE(RyanJsonDeleteByIndex(arr, 0));
  89. TEST_ASSERT_EQUAL_INT(0, RyanJsonGetSize(arr));
  90. TEST_ASSERT_NULL(RyanJsonGetObjectValue(arr));
  91. TEST_ASSERT_FALSE(RyanJsonDeleteByIndex(arr, 0));
  92. TEST_ASSERT_TRUE(RyanJsonAddIntToArray(arr, 10));
  93. TEST_ASSERT_EQUAL_INT(1, RyanJsonGetSize(arr));
  94. TEST_ASSERT_EQUAL_INT(10, RyanJsonGetIntValue(RyanJsonGetObjectByIndex(arr, 0)));
  95. RyanJsonDelete(arr);
  96. RyanJsonDelete(obj);
  97. }
  98. static void testDeleteTailAndMiddleThenAppend(void)
  99. {
  100. // Object:删除尾和中间节点后再次追加,验证链表仍可正常维护
  101. RyanJson_t obj = RyanJsonCreateObject();
  102. TEST_ASSERT_NOT_NULL(obj);
  103. TEST_ASSERT_TRUE(RyanJsonAddIntToObject(obj, "a", 1));
  104. TEST_ASSERT_TRUE(RyanJsonAddIntToObject(obj, "b", 2));
  105. TEST_ASSERT_TRUE(RyanJsonAddIntToObject(obj, "c", 3));
  106. TEST_ASSERT_TRUE(RyanJsonDeleteByKey(obj, "c"));
  107. TEST_ASSERT_EQUAL_INT(2, RyanJsonGetSize(obj));
  108. TEST_ASSERT_TRUE(RyanJsonDeleteByKey(obj, "b"));
  109. TEST_ASSERT_EQUAL_INT(1, RyanJsonGetSize(obj));
  110. TEST_ASSERT_TRUE(RyanJsonAddIntToObject(obj, "d", 4));
  111. TEST_ASSERT_EQUAL_INT(2, RyanJsonGetSize(obj));
  112. #if true == RyanJsonDefaultAddAtHead
  113. TEST_ASSERT_EQUAL_INT(4, RyanJsonGetIntValue(RyanJsonGetObjectByIndex(obj, 0)));
  114. TEST_ASSERT_EQUAL_INT(1, RyanJsonGetIntValue(RyanJsonGetObjectByIndex(obj, 1)));
  115. #else
  116. TEST_ASSERT_EQUAL_INT(1, RyanJsonGetIntValue(RyanJsonGetObjectByIndex(obj, 0)));
  117. TEST_ASSERT_EQUAL_INT(4, RyanJsonGetIntValue(RyanJsonGetObjectByIndex(obj, 1)));
  118. #endif
  119. // Array:同样覆盖“删尾/删中后再追加”路径
  120. RyanJson_t arr = RyanJsonCreateArray();
  121. TEST_ASSERT_NOT_NULL(arr);
  122. TEST_ASSERT_TRUE(RyanJsonAddIntToArray(arr, 10));
  123. TEST_ASSERT_TRUE(RyanJsonAddIntToArray(arr, 20));
  124. TEST_ASSERT_TRUE(RyanJsonAddIntToArray(arr, 30));
  125. TEST_ASSERT_TRUE(RyanJsonDeleteByIndex(arr, 2));
  126. TEST_ASSERT_EQUAL_INT(2, RyanJsonGetSize(arr));
  127. TEST_ASSERT_TRUE(RyanJsonDeleteByIndex(arr, 1));
  128. TEST_ASSERT_EQUAL_INT(1, RyanJsonGetSize(arr));
  129. TEST_ASSERT_TRUE(RyanJsonAddIntToArray(arr, 40));
  130. TEST_ASSERT_EQUAL_INT(2, RyanJsonGetSize(arr));
  131. #if true == RyanJsonDefaultAddAtHead
  132. TEST_ASSERT_EQUAL_INT(40, RyanJsonGetIntValue(RyanJsonGetObjectByIndex(arr, 0)));
  133. TEST_ASSERT_EQUAL_INT(30, RyanJsonGetIntValue(RyanJsonGetObjectByIndex(arr, 1)));
  134. #else
  135. TEST_ASSERT_EQUAL_INT(10, RyanJsonGetIntValue(RyanJsonGetObjectByIndex(arr, 0)));
  136. TEST_ASSERT_EQUAL_INT(40, RyanJsonGetIntValue(RyanJsonGetObjectByIndex(arr, 1)));
  137. #endif
  138. RyanJsonDelete(arr);
  139. RyanJsonDelete(obj);
  140. }
  141. static void testDeleteStandardOperations(void)
  142. {
  143. // 保持原始 jsonStr,不做修改
  144. char jsonstr[] =
  145. "{\"inter\":16,\"double\":16.89,\"string\":\"hello\",\"boolTrue\":true,\"boolFalse\":false,\"null\":null,\"item\":"
  146. "{\"inter\":16,\"double\":16.89,\"string\":\"hello\",\"boolTrue\":true,\"boolFalse\":false,\"null\":null},"
  147. "\"arrayInt\":[16,16,16,16,16],\"arrayDouble\":[16.89,16.89,16.89,16.89,16.89],"
  148. "\"arrayString\":[\"hello\",\"hello\",\"hello\",\"hello\",\"hello\"],"
  149. "\"array\":[16,16.89,\"hello\",true,false,null],"
  150. "\"arrayItem\":[{\"inter\":16,\"double\":16.89,\"string\":\"hello\",\"boolTrue\":true,\"boolFalse\":false,\"null\":null},"
  151. "{\"inter\":16,\"double\":16.89,\"string\":\"hello\",\"boolTrue\":true,\"boolFalse\":false,\"null\":null}],"
  152. "\"string2222\":\"hello\"}";
  153. RyanJson_t json = RyanJsonParse(jsonstr);
  154. TEST_ASSERT_NOT_NULL_MESSAGE(json, "解析 Json 失败");
  155. /**
  156. * @brief 删除对象中的节点(头、中、尾)
  157. */
  158. // 删除中间节点(double)
  159. RyanJsonDeleteByKey(json, "double");
  160. TEST_ASSERT_NULL_MESSAGE(RyanJsonGetObjectToKey(json, "double"), "删除中间节点 double 失败");
  161. // 删除头部节点(inter)
  162. RyanJsonDeleteByIndex(json, 0);
  163. TEST_ASSERT_NULL_MESSAGE(RyanJsonGetObjectToKey(json, "inter"), "删除头部节点 inter 失败");
  164. // 删除尾部节点(string2222)
  165. uint32_t lastIndex = RyanJsonGetSize(json) - 1;
  166. RyanJsonDeleteByIndex(json, lastIndex);
  167. TEST_ASSERT_NULL_MESSAGE(RyanJsonGetObjectToKey(json, "string2222"), "删除尾部节点 string2222 失败");
  168. /**
  169. * @brief 删除数组中的元素(arrayInt)
  170. */
  171. RyanJson_t array = RyanJsonGetObjectToKey(json, "arrayInt");
  172. TEST_ASSERT_NOT_NULL_MESSAGE(array, "获取 arrayInt 失败");
  173. // 删除数组首位
  174. RyanJsonDeleteByIndex(array, 0);
  175. TEST_ASSERT_EQUAL_INT_MESSAGE(4, RyanJsonGetSize(array), "删除数组首位后长度错误");
  176. // 删除数组中间元素
  177. RyanJsonDeleteByIndex(array, 1);
  178. TEST_ASSERT_EQUAL_INT_MESSAGE(3, RyanJsonGetSize(array), "删除数组中间元素后长度错误");
  179. // 删除数组尾部元素
  180. lastIndex = RyanJsonGetSize(array) - 1;
  181. RyanJsonDeleteByIndex(array, lastIndex);
  182. TEST_ASSERT_EQUAL_INT_MESSAGE(2, RyanJsonGetSize(array), "删除数组尾部元素后长度错误");
  183. /**
  184. * @brief 深层嵌套删除(item)
  185. */
  186. RyanJsonDeleteByKey(json, "item");
  187. TEST_ASSERT_NULL_MESSAGE(RyanJsonGetObjectToKey(json, "item"), "删除嵌套对象 item 失败");
  188. /**
  189. * @brief 数组对象元素删除(arrayItem)
  190. */
  191. RyanJson_t arrObj = RyanJsonGetObjectToKey(json, "arrayItem");
  192. TEST_ASSERT_NOT_NULL_MESSAGE(arrObj, "获取 arrayItem 失败");
  193. // 删除第一个对象
  194. RyanJsonDeleteByIndex(arrObj, 0);
  195. TEST_ASSERT_EQUAL_INT_MESSAGE(1, RyanJsonGetSize(arrObj), "删除数组首个对象后长度错误");
  196. // 删除最后一个对象
  197. RyanJsonDeleteByIndex(arrObj, 0);
  198. TEST_ASSERT_EQUAL_INT_MESSAGE(0, RyanJsonGetSize(arrObj), "删除数组最后一个对象后长度错误");
  199. /**
  200. * @brief 特殊类型删除(null / bool)
  201. */
  202. RyanJsonDeleteByKey(json, "null");
  203. TEST_ASSERT_NULL_MESSAGE(RyanJsonGetObjectToKey(json, "null"), "删除 null 节点失败");
  204. RyanJsonDeleteByKey(json, "boolTrue");
  205. TEST_ASSERT_NULL_MESSAGE(RyanJsonGetObjectToKey(json, "boolTrue"), "删除 boolTrue 节点失败");
  206. RyanJsonDeleteByKey(json, "boolFalse");
  207. TEST_ASSERT_NULL_MESSAGE(RyanJsonGetObjectToKey(json, "boolFalse"), "删除 boolFalse 节点失败");
  208. /**
  209. * @brief 异常路径覆盖(健壮性)
  210. */
  211. RyanJsonDeleteByKey(json, "non_exist"); // 删除不存在的 key
  212. RyanJsonDeleteByIndex(NULL, 0); // 在 NULL 上操作
  213. RyanJsonDelete(json);
  214. }
  215. void testDeleteRunner(void)
  216. {
  217. UnitySetTestFile(__FILE__);
  218. RUN_TEST(testDeleteEdgeCases);
  219. RUN_TEST(testDeleteSingleNodeAndReuse);
  220. RUN_TEST(testDeleteTailAndMiddleThenAppend);
  221. RUN_TEST(testDeleteStandardOperations);
  222. RUN_TEST(testDeleteMassiveItemsStress);
  223. }