testEdgeContainerReplaceGuard.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385
  1. #include "testBase.h"
  2. static void testEdgeContainerOpsReplaceByIndexObjectWithNewKey(void)
  3. {
  4. // 复杂链路:
  5. // Parse(Object) -> ReplaceByIndex -> Key 校验。
  6. // 目标:验证索引替换可更换 key。
  7. RyanJson_t obj = RyanJsonParse("{\"a\":1,\"b\":2}");
  8. TEST_ASSERT_NOT_NULL(obj);
  9. TEST_ASSERT_TRUE(RyanJsonReplaceByIndex(obj, 1, RyanJsonCreateInt("c", 3)));
  10. TEST_ASSERT_TRUE(RyanJsonHasObjectByKey(obj, "a"));
  11. TEST_ASSERT_TRUE(RyanJsonHasObjectByKey(obj, "c"));
  12. TEST_ASSERT_FALSE(RyanJsonHasObjectByKey(obj, "b"));
  13. RyanJsonDelete(obj);
  14. }
  15. static void testEdgeContainerOpsReplaceByIndexArrayWithObject(void)
  16. {
  17. // 复杂链路:
  18. // Parse(Array) -> ReplaceByIndex(Object) -> 结构校验。
  19. // 目标:验证 Array 索引可替换为 Object。
  20. RyanJson_t arr = RyanJsonParse("[1,2]");
  21. TEST_ASSERT_NOT_NULL(arr);
  22. RyanJson_t obj = RyanJsonCreateObject();
  23. TEST_ASSERT_NOT_NULL(obj);
  24. TEST_ASSERT_TRUE(RyanJsonAddIntToObject(obj, "x", 1));
  25. TEST_ASSERT_TRUE(RyanJsonReplaceByIndex(arr, 0, obj));
  26. RyanJson_t item = RyanJsonGetObjectByIndex(arr, 0);
  27. TEST_ASSERT_TRUE(RyanJsonIsObject(item));
  28. TEST_ASSERT_EQUAL_INT(1, RyanJsonGetIntValue(RyanJsonGetObjectToKey(item, "x")));
  29. RyanJsonDelete(arr);
  30. }
  31. static void testEdgeContainerOpsReplaceByKeyWithDetachedFromOther(void)
  32. {
  33. // 复杂链路:
  34. // Parse -> DetachByKey -> ReplaceByKey -> Key 校验。
  35. // 目标:验证 ReplaceByKey 会重命名 key。
  36. RyanJson_t obj1 = RyanJsonParse("{\"a\":1}");
  37. RyanJson_t obj2 = RyanJsonParse("{\"b\":2}");
  38. TEST_ASSERT_NOT_NULL(obj1);
  39. TEST_ASSERT_NOT_NULL(obj2);
  40. RyanJson_t detached = RyanJsonDetachByKey(obj2, "b");
  41. TEST_ASSERT_NOT_NULL(detached);
  42. TEST_ASSERT_TRUE(RyanJsonReplaceByKey(obj1, "a", detached));
  43. TEST_ASSERT_TRUE(RyanJsonHasObjectByKey(obj1, "a"));
  44. TEST_ASSERT_EQUAL_INT(2, RyanJsonGetIntValue(RyanJsonGetObjectByKey(obj1, "a")));
  45. TEST_ASSERT_EQUAL_UINT32(0U, RyanJsonGetSize(obj2));
  46. RyanJsonDelete(obj2);
  47. RyanJsonDelete(obj1);
  48. }
  49. static void testEdgeContainerOpsReplaceByKeyWithArrayContainer(void)
  50. {
  51. // 复杂链路:
  52. // Parse -> Create(Array) -> ReplaceByKey -> 类型校验。
  53. // 目标:验证 ReplaceByKey 可替换为 Array 容器。
  54. RyanJson_t obj = RyanJsonParse("{\"a\":1}");
  55. TEST_ASSERT_NOT_NULL(obj);
  56. RyanJson_t arr = RyanJsonCreateArray();
  57. TEST_ASSERT_NOT_NULL(arr);
  58. TEST_ASSERT_TRUE(RyanJsonAddIntToArray(arr, 1));
  59. TEST_ASSERT_TRUE(RyanJsonAddIntToArray(arr, 2));
  60. TEST_ASSERT_TRUE(RyanJsonReplaceByKey(obj, "a", arr));
  61. RyanJson_t node = RyanJsonGetObjectByKey(obj, "a");
  62. TEST_ASSERT_TRUE(RyanJsonIsArray(node));
  63. TEST_ASSERT_EQUAL_UINT32(2U, RyanJsonGetArraySize(node));
  64. RyanJsonDelete(obj);
  65. }
  66. static void testEdgeContainerOpsAddItemToArrayThenReplaceByIndex(void)
  67. {
  68. // 复杂链路:
  69. // Create(Array) -> AddItemToArray -> ReplaceByIndex -> 类型校验。
  70. // 目标:验证替换后 Array 元素类型更新。
  71. RyanJson_t arr = RyanJsonCreateArray();
  72. TEST_ASSERT_NOT_NULL(arr);
  73. RyanJson_t obj = RyanJsonCreateObject();
  74. TEST_ASSERT_NOT_NULL(obj);
  75. TEST_ASSERT_TRUE(RyanJsonAddIntToObject(obj, "x", 1));
  76. TEST_ASSERT_TRUE(RyanJsonAddItemToArray(arr, obj));
  77. TEST_ASSERT_TRUE(RyanJsonReplaceByIndex(arr, 0, RyanJsonCreateInt(NULL, 9)));
  78. TEST_ASSERT_TRUE(RyanJsonIsInt(RyanJsonGetObjectByIndex(arr, 0)));
  79. TEST_ASSERT_EQUAL_INT(9, RyanJsonGetIntValue(RyanJsonGetObjectByIndex(arr, 0)));
  80. RyanJsonDelete(arr);
  81. }
  82. static void testEdgeContainerOpsAddItemToObjectThenReplaceByKey(void)
  83. {
  84. // 复杂链路:
  85. // Create(Object) -> AddItemToObject -> ReplaceByKey -> 类型校验。
  86. // 目标:验证替换后 Object 字段类型更新。
  87. RyanJson_t obj = RyanJsonCreateObject();
  88. TEST_ASSERT_NOT_NULL(obj);
  89. RyanJson_t arr = RyanJsonCreateArray();
  90. TEST_ASSERT_NOT_NULL(arr);
  91. TEST_ASSERT_TRUE(RyanJsonAddIntToArray(arr, 1));
  92. TEST_ASSERT_TRUE(RyanJsonAddItemToObject(obj, "arr", arr));
  93. TEST_ASSERT_TRUE(RyanJsonReplaceByKey(obj, "arr", RyanJsonCreateObject()));
  94. TEST_ASSERT_TRUE(RyanJsonIsObject(RyanJsonGetObjectByKey(obj, "arr")));
  95. RyanJsonDelete(obj);
  96. }
  97. static void testEdgeContainerOpsDetachThenReplaceByIndexSameObject(void)
  98. {
  99. // 复杂链路:
  100. // Parse(Object) -> DetachByKey -> ReplaceByIndex -> Size 校验。
  101. // 目标:验证分离后再替换可正确更新结构。
  102. RyanJson_t obj = RyanJsonParse("{\"a\":1,\"b\":2}");
  103. TEST_ASSERT_NOT_NULL(obj);
  104. RyanJson_t moved = RyanJsonDetachByKey(obj, "a");
  105. TEST_ASSERT_NOT_NULL(moved);
  106. TEST_ASSERT_TRUE(RyanJsonReplaceByIndex(obj, 0, moved));
  107. TEST_ASSERT_EQUAL_UINT32(1U, RyanJsonGetSize(obj));
  108. TEST_ASSERT_TRUE(RyanJsonHasObjectByKey(obj, "a"));
  109. RyanJsonDelete(obj);
  110. }
  111. static void testEdgeContainerOpsReplaceByIndexArrayOutOfRange(void)
  112. {
  113. // 复杂链路:
  114. // Parse(Array) -> ReplaceByIndex(越界) -> item 保持游离。
  115. // 目标:验证越界替换失败路径。
  116. RyanJson_t arr = RyanJsonParse("[1]");
  117. TEST_ASSERT_NOT_NULL(arr);
  118. RyanJson_t item = RyanJsonCreateInt(NULL, 9);
  119. TEST_ASSERT_NOT_NULL(item);
  120. TEST_ASSERT_FALSE(RyanJsonReplaceByIndex(arr, 2, item));
  121. TEST_ASSERT_TRUE(RyanJsonIsDetachedItem(item));
  122. RyanJsonDelete(item);
  123. RyanJsonDelete(arr);
  124. }
  125. static void testEdgeContainerOpsReplaceByKeyMissing(void)
  126. {
  127. // 复杂链路:
  128. // Parse(Object) -> ReplaceByKey(缺失) -> item 保持游离。
  129. // 目标:验证缺失 key 替换失败路径。
  130. RyanJson_t obj = RyanJsonParse("{\"a\":1}");
  131. TEST_ASSERT_NOT_NULL(obj);
  132. RyanJson_t item = RyanJsonCreateInt("x", 9);
  133. TEST_ASSERT_NOT_NULL(item);
  134. TEST_ASSERT_FALSE(RyanJsonReplaceByKey(obj, "missing", item));
  135. TEST_ASSERT_TRUE(RyanJsonIsDetachedItem(item));
  136. RyanJsonDelete(item);
  137. RyanJsonDelete(obj);
  138. }
  139. static void testEdgeContainerOpsReplaceByIndexEmptyContainerKeepsDetachedItem(void)
  140. {
  141. // 复杂链路:
  142. // Create(空容器) -> ReplaceByIndex(失败) -> item 保持游离。
  143. // 目标:验证空容器替换失败不会消费 item。
  144. RyanJson_t arr = RyanJsonCreateArray();
  145. RyanJson_t obj = RyanJsonCreateObject();
  146. TEST_ASSERT_NOT_NULL(arr);
  147. TEST_ASSERT_NOT_NULL(obj);
  148. RyanJson_t arrItem = RyanJsonCreateInt(NULL, 1);
  149. TEST_ASSERT_NOT_NULL(arrItem);
  150. TEST_ASSERT_FALSE_MESSAGE(RyanJsonReplaceByIndex(arr, 0, arrItem), "空 Array ReplaceByIndex 应失败");
  151. TEST_ASSERT_TRUE_MESSAGE(RyanJsonIsDetachedItem(arrItem), "ReplaceByIndex 失败后 item 应保持游离");
  152. RyanJsonDelete(arrItem);
  153. RyanJson_t objItem = RyanJsonCreateInt("a", 1);
  154. TEST_ASSERT_NOT_NULL(objItem);
  155. TEST_ASSERT_FALSE_MESSAGE(RyanJsonReplaceByIndex(obj, 0, objItem), "空 Object ReplaceByIndex 应失败");
  156. TEST_ASSERT_TRUE_MESSAGE(RyanJsonIsDetachedItem(objItem), "ReplaceByIndex 失败后 item 应保持游离");
  157. RyanJsonDelete(objItem);
  158. RyanJsonDelete(obj);
  159. RyanJsonDelete(arr);
  160. }
  161. static void testEdgeContainerOpsGetObjectByIndexOnScalarReturnsNull(void)
  162. {
  163. // 复杂链路:
  164. // Parse(标量) -> GetObjectByIndex -> NULL。
  165. // 目标:验证标量场景下索引获取失败。
  166. RyanJson_t root = RyanJsonParse("1");
  167. TEST_ASSERT_NOT_NULL(root);
  168. TEST_ASSERT_NULL(RyanJsonGetObjectByIndex(root, 0));
  169. RyanJsonDelete(root);
  170. }
  171. static void testEdgeContainerOpsGetObjectByKeyOnArrayReturnsNull(void)
  172. {
  173. // 复杂链路:
  174. // Parse(Array) -> GetObjectByKey -> NULL。
  175. // 目标:验证 Array 场景下 key 获取失败。
  176. RyanJson_t arr = RyanJsonParse("[1]");
  177. TEST_ASSERT_NOT_NULL(arr);
  178. TEST_ASSERT_NULL(RyanJsonGetObjectByKey(arr, "a"));
  179. RyanJsonDelete(arr);
  180. }
  181. static void testEdgeContainerOpsInsertKeylessIntoObjectFailsRecover(void)
  182. {
  183. // 复杂链路:
  184. // Parse(Object) -> Insert(keyless, 失败) -> Insert(合法)。
  185. // 目标:验证失败后 Object 可继续使用。
  186. RyanJson_t obj = RyanJsonParse("{\"a\":1}");
  187. TEST_ASSERT_NOT_NULL(obj);
  188. RyanJson_t bad = RyanJsonCreateInt(NULL, 9);
  189. TEST_ASSERT_NOT_NULL(bad);
  190. TEST_ASSERT_FALSE(RyanJsonInsert(obj, 0, bad));
  191. TEST_ASSERT_TRUE(RyanJsonInsert(obj, 0, RyanJsonCreateInt("b", 2)));
  192. TEST_ASSERT_TRUE(RyanJsonHasObjectByKey(obj, "a"));
  193. TEST_ASSERT_TRUE(RyanJsonHasObjectByKey(obj, "b"));
  194. RyanJsonDelete(obj);
  195. }
  196. static void testEdgeContainerOpsInsertIntoNonContainerFails(void)
  197. {
  198. // 复杂链路:
  199. // Create(String) -> Insert(失败) -> 值不变。
  200. // 目标:验证非容器插入失败不会破坏自身。
  201. RyanJson_t str = RyanJsonCreateString("s", "v");
  202. TEST_ASSERT_NOT_NULL(str);
  203. RyanJson_t item = RyanJsonCreateInt(NULL, 1);
  204. TEST_ASSERT_NOT_NULL(item);
  205. TEST_ASSERT_FALSE(RyanJsonInsert(str, 0, item));
  206. TEST_ASSERT_EQUAL_STRING("v", RyanJsonGetStringValue(str));
  207. RyanJsonDelete(str);
  208. }
  209. static void testEdgeContainerOpsReplaceByIndexObjectOutOfRange(void)
  210. {
  211. // 复杂链路:
  212. // Parse(Object) -> ReplaceByIndex(越界) -> item 保持游离。
  213. // 目标:验证 Object 越界替换失败路径。
  214. RyanJson_t obj = RyanJsonParse("{\"a\":1}");
  215. TEST_ASSERT_NOT_NULL(obj);
  216. RyanJson_t item = RyanJsonCreateInt("b", 2);
  217. TEST_ASSERT_NOT_NULL(item);
  218. TEST_ASSERT_FALSE(RyanJsonReplaceByIndex(obj, 2, item));
  219. TEST_ASSERT_TRUE(RyanJsonIsDetachedItem(item));
  220. RyanJsonDelete(item);
  221. RyanJsonDelete(obj);
  222. }
  223. static void testEdgeContainerOpsReplaceByIndexObjectWithKeylessItemFails(void)
  224. {
  225. // 复杂链路:
  226. // Parse(Object) -> ReplaceByIndex(无 key 节点) -> 失败且 item 仍游离。
  227. // 目标:验证 Object 替换必须提供带 key 的节点。
  228. RyanJson_t obj = RyanJsonParse("{\"a\":1,\"b\":2}");
  229. TEST_ASSERT_NOT_NULL(obj);
  230. RyanJson_t item = RyanJsonCreateObject();
  231. TEST_ASSERT_NOT_NULL(item);
  232. TEST_ASSERT_FALSE(RyanJsonReplaceByIndex(obj, 0, item));
  233. TEST_ASSERT_TRUE(RyanJsonIsDetachedItem(item));
  234. RyanJsonDelete(item);
  235. RyanJsonDelete(obj);
  236. }
  237. static void testEdgeContainerOpsReplaceByIndexUpdatesArrayHead(void)
  238. {
  239. // 复杂链路:
  240. // Parse(Array) -> ReplaceByIndex(head) -> GetArrayValue 校验。
  241. // 目标:验证替换头元素后 Array 入口指针更新。
  242. RyanJson_t arr = RyanJsonParse("[1,2]");
  243. TEST_ASSERT_NOT_NULL(arr);
  244. TEST_ASSERT_TRUE(RyanJsonReplaceByIndex(arr, 0, RyanJsonCreateInt(NULL, 9)));
  245. TEST_ASSERT_EQUAL_UINT32(2U, RyanJsonGetArraySize(arr));
  246. TEST_ASSERT_EQUAL_INT(9, RyanJsonGetIntValue(RyanJsonGetArrayValue(arr)));
  247. TEST_ASSERT_EQUAL_INT(9, RyanJsonGetIntValue(RyanJsonGetObjectByIndex(arr, 0)));
  248. RyanJsonDelete(arr);
  249. }
  250. static void testEdgeContainerOpsReplaceByIndexUpdatesObjectHead(void)
  251. {
  252. // 复杂链路:
  253. // Parse(Object) -> ReplaceByIndex(head) -> GetObjectValue 校验。
  254. // 目标:验证替换头节点后 Object 入口指针更新。
  255. RyanJson_t obj = RyanJsonParse("{\"a\":1,\"b\":2}");
  256. TEST_ASSERT_NOT_NULL(obj);
  257. TEST_ASSERT_TRUE(RyanJsonReplaceByIndex(obj, 0, RyanJsonCreateInt("h", 9)));
  258. RyanJson_t head = RyanJsonGetObjectValue(obj);
  259. TEST_ASSERT_NOT_NULL(head);
  260. TEST_ASSERT_EQUAL_STRING("h", RyanJsonGetKey(head));
  261. TEST_ASSERT_EQUAL_INT(9, RyanJsonGetIntValue(head));
  262. RyanJsonDelete(obj);
  263. }
  264. static void testEdgeContainerOpsReplaceByKeyOnArrayFails(void)
  265. {
  266. // 复杂链路:
  267. // Parse(Array) -> ReplaceByKey(失败) -> item 保持游离。
  268. // 目标:验证 Array 不可使用 ReplaceByKey。
  269. RyanJson_t arr = RyanJsonParse("[1]");
  270. TEST_ASSERT_NOT_NULL(arr);
  271. RyanJson_t item = RyanJsonCreateInt("a", 9);
  272. TEST_ASSERT_NOT_NULL(item);
  273. TEST_ASSERT_FALSE(RyanJsonReplaceByKey(arr, "a", item));
  274. TEST_ASSERT_TRUE(RyanJsonIsDetachedItem(item));
  275. RyanJsonDelete(item);
  276. RyanJsonDelete(arr);
  277. }
  278. static void testEdgeContainerOpsGetObjectByIndexEmptyObject(void)
  279. {
  280. // 复杂链路:
  281. // Create(Object) -> GetObjectByIndex -> NULL。
  282. // 目标:验证空 Object 索引获取失败。
  283. RyanJson_t obj = RyanJsonCreateObject();
  284. TEST_ASSERT_NOT_NULL(obj);
  285. TEST_ASSERT_NULL(RyanJsonGetObjectByIndex(obj, 0));
  286. RyanJsonDelete(obj);
  287. }
  288. static void testEdgeContainerOpsGetObjectByIndexEmptyArray(void)
  289. {
  290. // 复杂链路:
  291. // Create(Array) -> GetObjectByIndex -> NULL。
  292. // 目标:验证空 Array 索引获取失败。
  293. RyanJson_t arr = RyanJsonCreateArray();
  294. TEST_ASSERT_NOT_NULL(arr);
  295. TEST_ASSERT_NULL(RyanJsonGetObjectByIndex(arr, 0));
  296. RyanJsonDelete(arr);
  297. }
  298. void testEdgeContainerReplaceGuardRunner(void)
  299. {
  300. UnitySetTestFile(__FILE__);
  301. RUN_TEST(testEdgeContainerOpsReplaceByIndexObjectWithNewKey);
  302. RUN_TEST(testEdgeContainerOpsReplaceByIndexArrayWithObject);
  303. RUN_TEST(testEdgeContainerOpsReplaceByKeyWithDetachedFromOther);
  304. RUN_TEST(testEdgeContainerOpsReplaceByKeyWithArrayContainer);
  305. RUN_TEST(testEdgeContainerOpsAddItemToArrayThenReplaceByIndex);
  306. RUN_TEST(testEdgeContainerOpsAddItemToObjectThenReplaceByKey);
  307. RUN_TEST(testEdgeContainerOpsDetachThenReplaceByIndexSameObject);
  308. RUN_TEST(testEdgeContainerOpsReplaceByIndexArrayOutOfRange);
  309. RUN_TEST(testEdgeContainerOpsReplaceByKeyMissing);
  310. RUN_TEST(testEdgeContainerOpsReplaceByIndexEmptyContainerKeepsDetachedItem);
  311. RUN_TEST(testEdgeContainerOpsGetObjectByIndexOnScalarReturnsNull);
  312. RUN_TEST(testEdgeContainerOpsGetObjectByKeyOnArrayReturnsNull);
  313. RUN_TEST(testEdgeContainerOpsInsertKeylessIntoObjectFailsRecover);
  314. RUN_TEST(testEdgeContainerOpsInsertIntoNonContainerFails);
  315. RUN_TEST(testEdgeContainerOpsReplaceByIndexObjectOutOfRange);
  316. RUN_TEST(testEdgeContainerOpsReplaceByIndexObjectWithKeylessItemFails);
  317. RUN_TEST(testEdgeContainerOpsReplaceByIndexUpdatesArrayHead);
  318. RUN_TEST(testEdgeContainerOpsReplaceByIndexUpdatesObjectHead);
  319. RUN_TEST(testEdgeContainerOpsReplaceByKeyOnArrayFails);
  320. RUN_TEST(testEdgeContainerOpsGetObjectByIndexEmptyObject);
  321. RUN_TEST(testEdgeContainerOpsGetObjectByIndexEmptyArray);
  322. }