testEdgeKeyBoundary.c 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245
  1. #include "testBase.h"
  2. static char *allocPatternString(uint32_t len, char ch)
  3. {
  4. char *buf = (char *)malloc(len + 1U);
  5. if (NULL == buf) { return NULL; }
  6. for (uint32_t i = 0; i < len; i++)
  7. {
  8. buf[i] = ch;
  9. }
  10. buf[len] = '\0';
  11. return buf;
  12. }
  13. static void testEdgeKeyBoundaryChangeKeyShortToLong(void)
  14. {
  15. // 复杂链路:
  16. // Create(Object) -> AddIntToObject(短 key) -> ChangeKey(长 key) -> Compare。
  17. // 目标:验证短 key 切换到长 key 后结构正确。
  18. uint32_t shortLen = (RyanJsonInlineStringSize > 8U) ? (RyanJsonInlineStringSize - 2U) : 8U;
  19. uint32_t longLen = RyanJsonInlineStringSize + 8U;
  20. char *shortKey = allocPatternString(shortLen, 's');
  21. char *longKey = allocPatternString(longLen, 'l');
  22. TEST_ASSERT_NOT_NULL(shortKey);
  23. TEST_ASSERT_NOT_NULL(longKey);
  24. RyanJson_t root = RyanJsonCreateObject();
  25. TEST_ASSERT_NOT_NULL(root);
  26. TEST_ASSERT_TRUE(RyanJsonAddIntToObject(root, shortKey, 1));
  27. RyanJson_t node = RyanJsonGetObjectByKey(root, shortKey);
  28. TEST_ASSERT_NOT_NULL(node);
  29. TEST_ASSERT_TRUE(RyanJsonChangeKey(node, longKey));
  30. TEST_ASSERT_TRUE(RyanJsonHasObjectByKey(root, longKey));
  31. RyanJson_t expect = RyanJsonCreateObject();
  32. TEST_ASSERT_NOT_NULL(expect);
  33. TEST_ASSERT_TRUE(RyanJsonAddIntToObject(expect, longKey, 1));
  34. TEST_ASSERT_TRUE(RyanJsonCompare(root, expect));
  35. RyanJsonDelete(expect);
  36. RyanJsonDelete(root);
  37. free(shortKey);
  38. free(longKey);
  39. }
  40. static void testEdgeKeyBoundaryChangeKeyLongToShort(void)
  41. {
  42. // 复杂链路:
  43. // Create(Object) -> AddIntToObject(长 key) -> ChangeKey(短 key) -> Compare。
  44. // 目标:验证长 key 切换到短 key 后结构正确。
  45. uint32_t shortLen = (RyanJsonInlineStringSize > 8U) ? (RyanJsonInlineStringSize - 2U) : 8U;
  46. uint32_t longLen = RyanJsonInlineStringSize + 8U;
  47. char *shortKey = allocPatternString(shortLen, 's');
  48. char *longKey = allocPatternString(longLen, 'l');
  49. TEST_ASSERT_NOT_NULL(shortKey);
  50. TEST_ASSERT_NOT_NULL(longKey);
  51. RyanJson_t root = RyanJsonCreateObject();
  52. TEST_ASSERT_NOT_NULL(root);
  53. TEST_ASSERT_TRUE(RyanJsonAddIntToObject(root, longKey, 2));
  54. RyanJson_t node = RyanJsonGetObjectByKey(root, longKey);
  55. TEST_ASSERT_NOT_NULL(node);
  56. TEST_ASSERT_TRUE(RyanJsonChangeKey(node, shortKey));
  57. TEST_ASSERT_TRUE(RyanJsonHasObjectByKey(root, shortKey));
  58. RyanJson_t expect = RyanJsonCreateObject();
  59. TEST_ASSERT_NOT_NULL(expect);
  60. TEST_ASSERT_TRUE(RyanJsonAddIntToObject(expect, shortKey, 2));
  61. TEST_ASSERT_TRUE(RyanJsonCompare(root, expect));
  62. RyanJsonDelete(expect);
  63. RyanJsonDelete(root);
  64. free(shortKey);
  65. free(longKey);
  66. }
  67. static void testEdgeKeyBoundaryChangeKeyLongToLongDifferent(void)
  68. {
  69. // 复杂链路:
  70. // Create(Object) -> AddIntToObject(长 key) -> ChangeKey(另一个长 key)。
  71. // 目标:验证长 key 切换到另一长 key 后结构正确。
  72. uint32_t longLen = RyanJsonInlineStringSize + 8U;
  73. char *longKeyA = allocPatternString(longLen, 'a');
  74. char *longKeyB = allocPatternString(longLen, 'b');
  75. TEST_ASSERT_NOT_NULL(longKeyA);
  76. TEST_ASSERT_NOT_NULL(longKeyB);
  77. RyanJson_t root = RyanJsonCreateObject();
  78. TEST_ASSERT_NOT_NULL(root);
  79. TEST_ASSERT_TRUE(RyanJsonAddIntToObject(root, longKeyA, 3));
  80. RyanJson_t node = RyanJsonGetObjectByKey(root, longKeyA);
  81. TEST_ASSERT_NOT_NULL(node);
  82. TEST_ASSERT_TRUE(RyanJsonChangeKey(node, longKeyB));
  83. TEST_ASSERT_TRUE(RyanJsonHasObjectByKey(root, longKeyB));
  84. RyanJson_t expect = RyanJsonCreateObject();
  85. TEST_ASSERT_NOT_NULL(expect);
  86. TEST_ASSERT_TRUE(RyanJsonAddIntToObject(expect, longKeyB, 3));
  87. TEST_ASSERT_TRUE(RyanJsonCompare(root, expect));
  88. RyanJsonDelete(expect);
  89. RyanJsonDelete(root);
  90. free(longKeyA);
  91. free(longKeyB);
  92. }
  93. static void testEdgeKeyBoundaryChangeKeyKeepsValue(void)
  94. {
  95. // 复杂链路:
  96. // Create(Object) -> AddIntToObject -> ChangeKey -> GetIntValue。
  97. // 目标:验证改 key 不影响原值。
  98. uint32_t longLen = RyanJsonInlineStringSize + 8U;
  99. char *longKey = allocPatternString(longLen, 'k');
  100. TEST_ASSERT_NOT_NULL(longKey);
  101. RyanJson_t root = RyanJsonParse("{\"a\":7}");
  102. TEST_ASSERT_NOT_NULL(root);
  103. RyanJson_t node = RyanJsonGetObjectByKey(root, "a");
  104. TEST_ASSERT_NOT_NULL(node);
  105. TEST_ASSERT_TRUE(RyanJsonChangeKey(node, longKey));
  106. TEST_ASSERT_EQUAL_INT(7, RyanJsonGetIntValue(RyanJsonGetObjectByKey(root, longKey)));
  107. RyanJsonDelete(root);
  108. free(longKey);
  109. }
  110. static void testEdgeKeyRoundtripLongKey(void)
  111. {
  112. // 复杂链路:
  113. // Create(Object 长 key) -> Print -> Parse -> Compare。
  114. // 目标:验证长 key 往返一致。
  115. uint32_t longLen = RyanJsonInlineStringSize + 8U;
  116. char *longKey = allocPatternString(longLen, 'k');
  117. TEST_ASSERT_NOT_NULL(longKey);
  118. RyanJson_t obj = RyanJsonCreateObject();
  119. TEST_ASSERT_NOT_NULL(obj);
  120. TEST_ASSERT_TRUE(RyanJsonAddIntToObject(obj, longKey, 1));
  121. char *printed = RyanJsonPrint(obj, 32, RyanJsonFalse, NULL);
  122. TEST_ASSERT_NOT_NULL(printed);
  123. RyanJson_t reparsed = RyanJsonParse(printed);
  124. TEST_ASSERT_NOT_NULL(reparsed);
  125. TEST_ASSERT_TRUE(RyanJsonCompare(obj, reparsed));
  126. RyanJsonDelete(reparsed);
  127. RyanJsonFree(printed);
  128. RyanJsonDelete(obj);
  129. free(longKey);
  130. }
  131. static void testEdgeKeyRoundtripNestedLongKey(void)
  132. {
  133. // 复杂链路:
  134. // Create(嵌套 Object 长 key) -> Print -> Parse -> Compare。
  135. // 目标:验证长 key 在嵌套 Object 中的往返一致性。
  136. uint32_t longLen = RyanJsonInlineStringSize + 8U;
  137. char *longKey = allocPatternString(longLen, 'k');
  138. TEST_ASSERT_NOT_NULL(longKey);
  139. RyanJson_t root = RyanJsonCreateObject();
  140. RyanJson_t child = RyanJsonCreateObject();
  141. TEST_ASSERT_NOT_NULL(root);
  142. TEST_ASSERT_NOT_NULL(child);
  143. TEST_ASSERT_TRUE(RyanJsonAddStringToObject(child, longKey, "v"));
  144. TEST_ASSERT_TRUE(RyanJsonAddItemToObject(root, "child", child));
  145. char *printed = RyanJsonPrint(root, 64, RyanJsonFalse, NULL);
  146. TEST_ASSERT_NOT_NULL(printed);
  147. RyanJson_t reparsed = RyanJsonParse(printed);
  148. TEST_ASSERT_NOT_NULL(reparsed);
  149. TEST_ASSERT_TRUE(RyanJsonCompare(root, reparsed));
  150. RyanJsonDelete(reparsed);
  151. RyanJsonFree(printed);
  152. RyanJsonDelete(root);
  153. free(longKey);
  154. }
  155. static void testEdgeKeyBoundaryExactInlineLenKey(void)
  156. {
  157. // 复杂链路:
  158. // Create(Object) -> AddIntToObject(key 长度=InlineSize) -> Print/Parse -> Compare。
  159. // 目标:验证边界长度 key 往返一致。
  160. uint32_t keyLen = RyanJsonInlineStringSize;
  161. char *key = allocPatternString(keyLen, 'k');
  162. TEST_ASSERT_NOT_NULL(key);
  163. RyanJson_t obj = RyanJsonCreateObject();
  164. TEST_ASSERT_NOT_NULL(obj);
  165. TEST_ASSERT_TRUE(RyanJsonAddIntToObject(obj, key, 1));
  166. char *printed = RyanJsonPrint(obj, 32, RyanJsonFalse, NULL);
  167. TEST_ASSERT_NOT_NULL(printed);
  168. RyanJson_t reparsed = RyanJsonParse(printed);
  169. TEST_ASSERT_NOT_NULL(reparsed);
  170. TEST_ASSERT_TRUE(RyanJsonCompare(obj, reparsed));
  171. RyanJsonDelete(reparsed);
  172. RyanJsonFree(printed);
  173. RyanJsonDelete(obj);
  174. free(key);
  175. }
  176. static void testEdgeKeyBoundaryInlinePlusOneKey(void)
  177. {
  178. // 复杂链路:
  179. // Create(Object) -> AddIntToObject(key 长度=InlineSize+1) -> Print/Parse -> Compare。
  180. // 目标:验证边界+1 长度 key 往返一致。
  181. uint32_t keyLen = RyanJsonInlineStringSize + 1U;
  182. char *key = allocPatternString(keyLen, 'k');
  183. TEST_ASSERT_NOT_NULL(key);
  184. RyanJson_t obj = RyanJsonCreateObject();
  185. TEST_ASSERT_NOT_NULL(obj);
  186. TEST_ASSERT_TRUE(RyanJsonAddIntToObject(obj, key, 1));
  187. char *printed = RyanJsonPrint(obj, 32, RyanJsonFalse, NULL);
  188. TEST_ASSERT_NOT_NULL(printed);
  189. RyanJson_t reparsed = RyanJsonParse(printed);
  190. TEST_ASSERT_NOT_NULL(reparsed);
  191. TEST_ASSERT_TRUE(RyanJsonCompare(obj, reparsed));
  192. RyanJsonDelete(reparsed);
  193. RyanJsonFree(printed);
  194. RyanJsonDelete(obj);
  195. free(key);
  196. }
  197. void testEdgeKeyBoundaryRunner(void)
  198. {
  199. UnitySetTestFile(__FILE__);
  200. RUN_TEST(testEdgeKeyBoundaryChangeKeyShortToLong);
  201. RUN_TEST(testEdgeKeyBoundaryChangeKeyLongToShort);
  202. RUN_TEST(testEdgeKeyBoundaryChangeKeyLongToLongDifferent);
  203. RUN_TEST(testEdgeKeyBoundaryChangeKeyKeepsValue);
  204. RUN_TEST(testEdgeKeyRoundtripLongKey);
  205. RUN_TEST(testEdgeKeyRoundtripNestedLongKey);
  206. RUN_TEST(testEdgeKeyBoundaryExactInlineLenKey);
  207. RUN_TEST(testEdgeKeyBoundaryInlinePlusOneKey);
  208. }