testUtils.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277
  1. #include "testBase.h"
  2. /**
  3. * @brief Json 公共校验辅助函数
  4. */
  5. void printJsonDebug(RyanJson_t json)
  6. {
  7. char *str = RyanJsonPrint(json, 1024, RyanJsonTrue, NULL);
  8. testLog("aa %s\r\n", str);
  9. RyanJsonFree(str);
  10. }
  11. void rootNodeCheckTest(RyanJson_t json)
  12. {
  13. TEST_ASSERT_NOT_NULL_MESSAGE(json, "根节点检查:输入 Json 为空");
  14. // 校验 Int 字段
  15. RyanJson_t inter = RyanJsonGetObjectToKey(json, "inter");
  16. TEST_ASSERT_TRUE_MESSAGE(RyanJsonIsInt(inter), "字段 'inter' 不是 Int 类型");
  17. TEST_ASSERT_EQUAL_INT_MESSAGE(16, RyanJsonGetIntValue(inter), "字段 'inter' 值不正确");
  18. // 校验 Double 字段
  19. RyanJson_t dbl = RyanJsonGetObjectToKey(json, "double");
  20. TEST_ASSERT_TRUE_MESSAGE(RyanJsonIsDouble(dbl), "字段 'double' 不是 Double 类型");
  21. TEST_ASSERT_TRUE_MESSAGE(RyanJsonCompareDouble(RyanJsonGetDoubleValue(dbl), 16.89), "字段 'double' 值不正确");
  22. // 校验 String 字段
  23. RyanJson_t str = RyanJsonGetObjectToKey(json, "string");
  24. TEST_ASSERT_TRUE_MESSAGE(RyanJsonIsString(str), "字段 'string' 不是 String 类型");
  25. TEST_ASSERT_EQUAL_STRING_MESSAGE("hello", RyanJsonGetStringValue(str), "字段 'string' 值不正确");
  26. // 校验 Bool 字段(true)
  27. RyanJson_t bTrue = RyanJsonGetObjectToKey(json, "boolTrue");
  28. TEST_ASSERT_TRUE_MESSAGE(RyanJsonIsBool(bTrue), "字段 'boolTrue' 不是 Bool 类型");
  29. TEST_ASSERT_EQUAL_INT_MESSAGE(RyanJsonTrue, RyanJsonGetBoolValue(bTrue), "字段 'boolTrue' 值不正确");
  30. // 校验 Bool 字段(false)
  31. RyanJson_t bFalse = RyanJsonGetObjectToKey(json, "boolFalse");
  32. TEST_ASSERT_TRUE_MESSAGE(RyanJsonIsBool(bFalse), "字段 'boolFalse' 不是 Bool 类型");
  33. TEST_ASSERT_EQUAL_INT_MESSAGE(RyanJsonFalse, RyanJsonGetBoolValue(bFalse), "字段 'boolFalse' 值不正确");
  34. // 校验 Null 字段
  35. TEST_ASSERT_TRUE_MESSAGE(RyanJsonIsNull(RyanJsonGetObjectToKey(json, "null")), "字段 'null' 不是 Null 类型");
  36. }
  37. void itemNodeCheckTest(RyanJson_t json)
  38. {
  39. RyanJson_t item = RyanJsonGetObjectToKey(json, "item");
  40. TEST_ASSERT_NOT_NULL_MESSAGE(item, "字段 'item' 不存在");
  41. rootNodeCheckTest(item);
  42. }
  43. void arrayNodeCheckTest(RyanJson_t json, RyanJsonBool_e isReversed)
  44. {
  45. TEST_ASSERT_TRUE_MESSAGE(RyanJsonIsArray(RyanJsonGetObjectToKey(json, "arrayInt")), "arrayInt 不是 Array");
  46. TEST_ASSERT_TRUE_MESSAGE(RyanJsonIsArray(RyanJsonGetObjectToKey(json, "arrayDouble")), "arrayDouble 不是 Array");
  47. TEST_ASSERT_TRUE_MESSAGE(RyanJsonIsArray(RyanJsonGetObjectToKey(json, "arrayString")), "arrayString 不是 Array");
  48. TEST_ASSERT_TRUE_MESSAGE(RyanJsonIsArray(RyanJsonGetObjectToKey(json, "array")), "array 不是 Array");
  49. // 校验混合 Array(含 Int/Double/String/Bool/Null):[16, 16.89, "hello", true, false, Null]
  50. RyanJson_t array = RyanJsonGetObjectToKey(json, "array");
  51. TEST_ASSERT_EQUAL_INT_MESSAGE(6, RyanJsonGetSize(array), "混合 Array 长度不正确");
  52. if (isReversed)
  53. {
  54. TEST_ASSERT_TRUE_MESSAGE(RyanJsonIsNull(RyanJsonGetObjectByIndex(array, 0)), "混合 Array[0]不是 Null");
  55. TEST_ASSERT_TRUE_MESSAGE(RyanJsonIsBool(RyanJsonGetObjectByIndex(array, 1)), "混合 Array[1]不是 Bool 值");
  56. TEST_ASSERT_EQUAL_INT_MESSAGE(RyanJsonFalse, RyanJsonGetBoolValue(RyanJsonGetObjectByIndex(array, 1)), "混合 Array[1]值错误");
  57. TEST_ASSERT_TRUE_MESSAGE(RyanJsonIsBool(RyanJsonGetObjectByIndex(array, 2)), "混合 Array[2]不是 Bool 值");
  58. TEST_ASSERT_EQUAL_INT_MESSAGE(RyanJsonTrue, RyanJsonGetBoolValue(RyanJsonGetObjectByIndex(array, 2)), "混合 Array[2]值错误");
  59. TEST_ASSERT_TRUE_MESSAGE(RyanJsonIsString(RyanJsonGetObjectByIndex(array, 3)), "混合 Array[3]不是 String");
  60. TEST_ASSERT_EQUAL_STRING_MESSAGE("hello", RyanJsonGetStringValue(RyanJsonGetObjectByIndex(array, 3)), "混合 Array[3]值错误");
  61. TEST_ASSERT_TRUE_MESSAGE(RyanJsonIsDouble(RyanJsonGetObjectByIndex(array, 4)), "混合 Array[4]不是 Double");
  62. TEST_ASSERT_TRUE_MESSAGE(RyanJsonCompareDouble(RyanJsonGetDoubleValue(RyanJsonGetObjectByIndex(array, 4)), 16.89),
  63. "混合 Array[4]值错误");
  64. TEST_ASSERT_TRUE_MESSAGE(RyanJsonIsInt(RyanJsonGetObjectByIndex(array, 5)), "混合 Array[5]不是 Int");
  65. TEST_ASSERT_EQUAL_INT_MESSAGE(16, RyanJsonGetIntValue(RyanJsonGetObjectByIndex(array, 5)), "混合 Array[5]值错误");
  66. }
  67. else
  68. {
  69. TEST_ASSERT_TRUE_MESSAGE(RyanJsonIsInt(RyanJsonGetObjectByIndex(array, 0)), "混合 Array[0]不是 Int");
  70. TEST_ASSERT_EQUAL_INT_MESSAGE(16, RyanJsonGetIntValue(RyanJsonGetObjectByIndex(array, 0)), "混合 Array[0]值错误");
  71. TEST_ASSERT_TRUE_MESSAGE(RyanJsonIsDouble(RyanJsonGetObjectByIndex(array, 1)), "混合 Array[1]不是 Double");
  72. TEST_ASSERT_TRUE_MESSAGE(RyanJsonCompareDouble(RyanJsonGetDoubleValue(RyanJsonGetObjectByIndex(array, 1)), 16.89),
  73. "混合 Array[1]值错误");
  74. TEST_ASSERT_TRUE_MESSAGE(RyanJsonIsString(RyanJsonGetObjectByIndex(array, 2)), "混合 Array[2]不是 String");
  75. TEST_ASSERT_EQUAL_STRING_MESSAGE("hello", RyanJsonGetStringValue(RyanJsonGetObjectByIndex(array, 2)), "混合 Array[2]值错误");
  76. TEST_ASSERT_TRUE_MESSAGE(RyanJsonIsBool(RyanJsonGetObjectByIndex(array, 3)), "混合 Array[3]不是 Bool 值");
  77. TEST_ASSERT_EQUAL_INT_MESSAGE(RyanJsonTrue, RyanJsonGetBoolValue(RyanJsonGetObjectByIndex(array, 3)), "混合 Array[3]值错误");
  78. TEST_ASSERT_TRUE_MESSAGE(RyanJsonIsBool(RyanJsonGetObjectByIndex(array, 4)), "混合 Array[4]不是 Bool 值");
  79. TEST_ASSERT_EQUAL_INT_MESSAGE(RyanJsonFalse, RyanJsonGetBoolValue(RyanJsonGetObjectByIndex(array, 4)), "混合 Array[4]值错误");
  80. TEST_ASSERT_TRUE_MESSAGE(RyanJsonIsNull(RyanJsonGetObjectByIndex(array, 5)), "混合 Array[5]不是 Null");
  81. }
  82. // 校验强类型 Array
  83. RyanJson_t arrayInt = RyanJsonGetObjectToKey(json, "arrayInt");
  84. for (int32_t i = 0; i < RyanJsonGetSize(arrayInt); i++)
  85. {
  86. RyanJson_t item = RyanJsonGetObjectByIndex(arrayInt, i);
  87. TEST_ASSERT_TRUE_MESSAGE(RyanJsonIsInt(item), "arrayInt 元素不是 Int");
  88. TEST_ASSERT_EQUAL_INT_MESSAGE(16, RyanJsonGetIntValue(item), "arrayInt 元素值错误");
  89. }
  90. RyanJson_t arrayDouble = RyanJsonGetObjectToKey(json, "arrayDouble");
  91. for (int32_t i = 0; i < RyanJsonGetSize(arrayDouble); i++)
  92. {
  93. RyanJson_t item = RyanJsonGetObjectByIndex(arrayDouble, i);
  94. TEST_ASSERT_TRUE_MESSAGE(RyanJsonIsDouble(item), "arrayDouble 元素不是 Double");
  95. TEST_ASSERT_TRUE_MESSAGE(RyanJsonCompareDouble(RyanJsonGetDoubleValue(item), 16.89), "arrayDouble 元素值错误");
  96. }
  97. RyanJson_t arrayString = RyanJsonGetObjectToKey(json, "arrayString");
  98. for (int32_t i = 0; i < RyanJsonGetSize(arrayString); i++)
  99. {
  100. RyanJson_t item = RyanJsonGetObjectByIndex(arrayString, i);
  101. TEST_ASSERT_TRUE_MESSAGE(RyanJsonIsString(item), "arrayString 元素不是 String");
  102. TEST_ASSERT_EQUAL_STRING_MESSAGE("hello", RyanJsonGetStringValue(item), "arrayString 元素值错误");
  103. }
  104. }
  105. void arrayItemNodeCheckTest(RyanJson_t json)
  106. {
  107. RyanJson_t arrayItem = RyanJsonGetObjectToKey(json, "arrayItem");
  108. TEST_ASSERT_TRUE_MESSAGE(RyanJsonIsArray(arrayItem), "arrayItem 不是 Array");
  109. TEST_ASSERT_EQUAL_INT_MESSAGE(2, RyanJsonGetSize(arrayItem), "arrayItem 长度错误");
  110. rootNodeCheckTest(RyanJsonGetObjectToIndex(arrayItem, 0));
  111. rootNodeCheckTest(RyanJsonGetObjectToIndex(arrayItem, 1));
  112. }
  113. void testCheckRootEx(RyanJson_t pJson, RyanJsonBool_e isReversed)
  114. {
  115. rootNodeCheckTest(pJson);
  116. itemNodeCheckTest(pJson);
  117. arrayNodeCheckTest(pJson, isReversed);
  118. arrayItemNodeCheckTest(pJson);
  119. }
  120. void testCheckRoot(RyanJson_t pJson)
  121. {
  122. testCheckRootEx(pJson, RyanJsonFalse);
  123. }
  124. static void testUtilsMinifyNoExtraSpace(void)
  125. {
  126. char buf[4];
  127. buf[0] = 'a';
  128. buf[1] = 'b';
  129. buf[2] = 'c';
  130. buf[3] = 'X'; // 哨兵:不应被覆盖
  131. uint32_t count = RyanJsonMinify(buf, 3);
  132. TEST_ASSERT_EQUAL_UINT32(3, count);
  133. TEST_ASSERT_EQUAL_UINT8('a', (uint8_t)buf[0]);
  134. TEST_ASSERT_EQUAL_UINT8('b', (uint8_t)buf[1]);
  135. TEST_ASSERT_EQUAL_UINT8('c', (uint8_t)buf[2]);
  136. TEST_ASSERT_EQUAL_UINT8('X', (uint8_t)buf[3]);
  137. }
  138. static void testUtilsMinifyZeroLengthNoWrite(void)
  139. {
  140. char buf[] = "{}";
  141. uint32_t count = RyanJsonMinify(buf, 0);
  142. TEST_ASSERT_EQUAL_UINT32(0U, count);
  143. TEST_ASSERT_EQUAL_STRING("{}", buf);
  144. }
  145. static void testUtilsMinifyWriteTerminatorWhenSpaceRemain(void)
  146. {
  147. /*
  148. * textLen=4 时,压缩后 "abc" 长度为 3:
  149. * - 返回值应为 3
  150. * - 因为 3 < 4,函数应在 buf[3] 写入 '\0'
  151. * - buf[4] 是哨兵,必须保持不变
  152. */
  153. char buf[5];
  154. buf[0] = 'a';
  155. buf[1] = ' ';
  156. buf[2] = 'b';
  157. buf[3] = 'c';
  158. buf[4] = '#';
  159. uint32_t count = RyanJsonMinify(buf, 4);
  160. TEST_ASSERT_EQUAL_UINT32(3, count);
  161. TEST_ASSERT_EQUAL_UINT8('a', (uint8_t)buf[0]);
  162. TEST_ASSERT_EQUAL_UINT8('b', (uint8_t)buf[1]);
  163. TEST_ASSERT_EQUAL_UINT8('c', (uint8_t)buf[2]);
  164. TEST_ASSERT_EQUAL_UINT8('\0', (uint8_t)buf[3]);
  165. TEST_ASSERT_EQUAL_UINT8('#', (uint8_t)buf[4]);
  166. }
  167. static void testUtilsMinifyNoTerminatorOverflow(void)
  168. {
  169. uint8_t rawBuf[8] = {'{', '\"', 'a', '\"', ':', '1', '}', '#'};
  170. uint32_t count = RyanJsonMinify((char *)rawBuf, 7);
  171. TEST_ASSERT_EQUAL_UINT32(7U, count);
  172. TEST_ASSERT_EQUAL_UINT8((uint8_t)'#', rawBuf[7]);
  173. TEST_ASSERT_EQUAL_UINT8((uint8_t)'{', rawBuf[0]);
  174. TEST_ASSERT_EQUAL_UINT8((uint8_t)'\"', rawBuf[1]);
  175. TEST_ASSERT_EQUAL_UINT8((uint8_t)'a', rawBuf[2]);
  176. TEST_ASSERT_EQUAL_UINT8((uint8_t)'\"', rawBuf[3]);
  177. TEST_ASSERT_EQUAL_UINT8((uint8_t)':', rawBuf[4]);
  178. TEST_ASSERT_EQUAL_UINT8((uint8_t)'1', rawBuf[5]);
  179. TEST_ASSERT_EQUAL_UINT8((uint8_t)'}', rawBuf[6]);
  180. }
  181. static void testUtilsMinifyCommentOnlyToEmpty(void)
  182. {
  183. char buf[] = "/*comment*/";
  184. uint32_t count = RyanJsonMinify(buf, (int32_t)strlen(buf));
  185. TEST_ASSERT_EQUAL_UINT32(0U, count);
  186. TEST_ASSERT_EQUAL_STRING("", buf);
  187. }
  188. static void testUtilsMinifyWhitespaceOnlyWritesTerminator(void)
  189. {
  190. char buf[4] = {' ', '\t', '\n', '#'};
  191. uint32_t count = RyanJsonMinify(buf, 3);
  192. TEST_ASSERT_EQUAL_UINT32(0U, count);
  193. TEST_ASSERT_EQUAL_UINT8((uint8_t)'\0', (uint8_t)buf[0]);
  194. TEST_ASSERT_EQUAL_UINT8((uint8_t)'#', (uint8_t)buf[3]);
  195. }
  196. static void testUtilsMinifyTruncatedEscapeDoesNotOverread(void)
  197. {
  198. char rawTruncated[3] = {'\"', 'a', '\\'};
  199. uint32_t count = RyanJsonMinify(rawTruncated, 3);
  200. TEST_ASSERT_EQUAL_UINT32(3U, count);
  201. TEST_ASSERT_EQUAL_UINT8((uint8_t)'\"', (uint8_t)rawTruncated[0]);
  202. TEST_ASSERT_EQUAL_UINT8((uint8_t)'a', (uint8_t)rawTruncated[1]);
  203. TEST_ASSERT_EQUAL_UINT8((uint8_t)'\\', (uint8_t)rawTruncated[2]);
  204. }
  205. static void testUtilsMinifyInvalidArgsNoWrite(void)
  206. {
  207. // 参数守护分支:无论是 NULL 指针还是负长度,都只能返回 0,
  208. // 且不得写坏调用方传入的缓冲区内容。
  209. char buf[5] = {'{', '}', '!', '#', '@'};
  210. TEST_ASSERT_EQUAL_UINT32(0U, RyanJsonMinify(NULL, 4));
  211. TEST_ASSERT_EQUAL_UINT32(0U, RyanJsonMinify(buf, -1));
  212. TEST_ASSERT_EQUAL_UINT8((uint8_t)'{', (uint8_t)buf[0]);
  213. TEST_ASSERT_EQUAL_UINT8((uint8_t)'}', (uint8_t)buf[1]);
  214. TEST_ASSERT_EQUAL_UINT8((uint8_t)'!', (uint8_t)buf[2]);
  215. TEST_ASSERT_EQUAL_UINT8((uint8_t)'#', (uint8_t)buf[3]);
  216. TEST_ASSERT_EQUAL_UINT8((uint8_t)'@', (uint8_t)buf[4]);
  217. }
  218. void testUtilsRunner(void)
  219. {
  220. UnitySetTestFile(__FILE__);
  221. RUN_TEST(testUtilsMinifyNoExtraSpace);
  222. RUN_TEST(testUtilsMinifyZeroLengthNoWrite);
  223. RUN_TEST(testUtilsMinifyWriteTerminatorWhenSpaceRemain);
  224. RUN_TEST(testUtilsMinifyNoTerminatorOverflow);
  225. RUN_TEST(testUtilsMinifyCommentOnlyToEmpty);
  226. RUN_TEST(testUtilsMinifyWhitespaceOnlyWritesTerminator);
  227. RUN_TEST(testUtilsMinifyTruncatedEscapeDoesNotOverread);
  228. RUN_TEST(testUtilsMinifyInvalidArgsNoWrite);
  229. }