testEdgePrintOptions.c 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427
  1. #include "testBase.h"
  2. static void testEdgeParsePrintPrintFormatFlag(void)
  3. {
  4. // 复杂链路:
  5. // Parse -> Print(format=true/false) -> 输出差异校验。
  6. // 目标:验证格式化开关影响输出形态。
  7. RyanJson_t root = RyanJsonParse("{\"a\":1,\"b\":{\"c\":2,\"d\":3}}");
  8. TEST_ASSERT_NOT_NULL(root);
  9. char *pretty = RyanJsonPrint(root, 64, RyanJsonTrue, NULL);
  10. char *minified = RyanJsonPrint(root, 64, RyanJsonFalse, NULL);
  11. TEST_ASSERT_NOT_NULL(pretty);
  12. TEST_ASSERT_NOT_NULL(minified);
  13. TEST_ASSERT_NOT_NULL(strchr(pretty, '\n'));
  14. TEST_ASSERT_NULL(strchr(minified, '\n'));
  15. RyanJsonFree(minified);
  16. RyanJsonFree(pretty);
  17. RyanJsonDelete(root);
  18. }
  19. static void testEdgeParsePrintPrintPresetSmall(void)
  20. {
  21. // 复杂链路:
  22. // Parse -> Print(preset=1) -> Parse -> Compare。
  23. // 目标:验证小预设缓冲也可正常扩容。
  24. RyanJson_t root = RyanJsonParse("{\"a\":1,\"b\":[1,2,3]}");
  25. TEST_ASSERT_NOT_NULL(root);
  26. char *printed = RyanJsonPrint(root, 1, RyanJsonFalse, NULL);
  27. TEST_ASSERT_NOT_NULL(printed);
  28. RyanJson_t reparsed = RyanJsonParse(printed);
  29. TEST_ASSERT_NOT_NULL(reparsed);
  30. TEST_ASSERT_TRUE(RyanJsonCompare(root, reparsed));
  31. RyanJsonDelete(reparsed);
  32. RyanJsonFree(printed);
  33. RyanJsonDelete(root);
  34. }
  35. static void testEdgeParsePrintPrintPreallocatedExactFitFromPrint(void)
  36. {
  37. // 复杂链路:
  38. // Print -> 获取长度 -> PrintPreallocated(足够容量) -> 输出一致性。
  39. // 目标:验证预分配打印在安全容量下输出一致。
  40. RyanJson_t root = RyanJsonParse("{\"k\":\"v\",\"arr\":[1,2]}");
  41. TEST_ASSERT_NOT_NULL(root);
  42. uint32_t len = 0;
  43. char *printed = RyanJsonPrint(root, 0, RyanJsonFalse, &len);
  44. TEST_ASSERT_NOT_NULL(printed);
  45. char buf[512];
  46. TEST_ASSERT_TRUE(len + 1U <= sizeof(buf));
  47. char *out = RyanJsonPrintPreallocated(root, buf, (uint32_t)sizeof(buf), RyanJsonFalse, NULL);
  48. TEST_ASSERT_NOT_NULL(out);
  49. TEST_ASSERT_EQUAL_STRING(printed, out);
  50. RyanJsonFree(printed);
  51. RyanJsonDelete(root);
  52. }
  53. static void testEdgeParsePrintPrintPreallocatedTooSmallThenSuccess(void)
  54. {
  55. // 复杂链路:
  56. // Print(获取长度) -> PrintPreallocated(失败) -> PrintPreallocated(成功)。
  57. // 目标:验证不足容量失败路径可恢复。
  58. RyanJson_t root = RyanJsonParse("{\"a\":1,\"b\":{\"c\":2}}");
  59. TEST_ASSERT_NOT_NULL(root);
  60. uint32_t len = 0;
  61. char *printed = RyanJsonPrint(root, 0, RyanJsonFalse, &len);
  62. TEST_ASSERT_NOT_NULL(printed);
  63. char tiny[8];
  64. TEST_ASSERT_TRUE(len + 1U > sizeof(tiny));
  65. TEST_ASSERT_NULL(RyanJsonPrintPreallocated(root, tiny, (uint32_t)sizeof(tiny), RyanJsonFalse, NULL));
  66. char buf[512];
  67. TEST_ASSERT_TRUE(len + 1U <= sizeof(buf));
  68. TEST_ASSERT_NOT_NULL(RyanJsonPrintPreallocated(root, buf, (uint32_t)sizeof(buf), RyanJsonFalse, NULL));
  69. RyanJsonFree(printed);
  70. RyanJsonDelete(root);
  71. }
  72. static void testEdgeParsePrintPrintWithStyleCustomIndent(void)
  73. {
  74. // 复杂链路:
  75. // Parse -> PrintWithStyle(自定义缩进) -> Parse -> Compare。
  76. // 目标:验证自定义缩进风格可往返。
  77. RyanJson_t root = RyanJsonParse("{\"a\":1,\"b\":{\"c\":2}}");
  78. TEST_ASSERT_NOT_NULL(root);
  79. RyanJsonPrintStyle style = {
  80. .indent = " \t", .newline = "\n", .indentLen = 2, .newlineLen = 1, .spaceAfterColon = 1, .format = RyanJsonTrue};
  81. char *printed = RyanJsonPrintWithStyle(root, 256, &style, NULL);
  82. TEST_ASSERT_NOT_NULL(printed);
  83. RyanJson_t reparsed = RyanJsonParse(printed);
  84. TEST_ASSERT_NOT_NULL(reparsed);
  85. TEST_ASSERT_TRUE(RyanJsonCompare(root, reparsed));
  86. RyanJsonDelete(reparsed);
  87. RyanJsonFree(printed);
  88. RyanJsonDelete(root);
  89. }
  90. static void testEdgeParsePrintPrintWithStyleCrlf(void)
  91. {
  92. // 复杂链路:
  93. // Parse -> PrintWithStyle(\r\n) -> Parse -> Compare。
  94. // 目标:验证 CRLF 换行风格可往返。
  95. RyanJson_t root = RyanJsonParse("{\"a\":1,\"b\":2}");
  96. TEST_ASSERT_NOT_NULL(root);
  97. RyanJsonPrintStyle style = {
  98. .indent = " ", .newline = "\r\n", .indentLen = 2, .newlineLen = 2, .spaceAfterColon = 1, .format = RyanJsonTrue};
  99. char *printed = RyanJsonPrintWithStyle(root, 256, &style, NULL);
  100. TEST_ASSERT_NOT_NULL(printed);
  101. RyanJson_t reparsed = RyanJsonParse(printed);
  102. TEST_ASSERT_NOT_NULL(reparsed);
  103. TEST_ASSERT_TRUE(RyanJsonCompare(root, reparsed));
  104. RyanJsonDelete(reparsed);
  105. RyanJsonFree(printed);
  106. RyanJsonDelete(root);
  107. }
  108. static void testEdgeParsePrintPrintWithStyleLongIndent(void)
  109. {
  110. // 复杂链路:
  111. // Parse -> PrintWithStyle(长缩进) -> Parse -> Compare。
  112. // 目标:验证长缩进 String 可往返。
  113. RyanJson_t root = RyanJsonParse("{\"a\":1,\"b\":{\"c\":2}}");
  114. TEST_ASSERT_NOT_NULL(root);
  115. RyanJsonPrintStyle style = {
  116. .indent = " ", .newline = "\n", .indentLen = 4, .newlineLen = 1, .spaceAfterColon = 1, .format = RyanJsonTrue};
  117. char *printed = RyanJsonPrintWithStyle(root, 64, &style, NULL);
  118. TEST_ASSERT_NOT_NULL(printed);
  119. RyanJson_t reparsed = RyanJsonParse(printed);
  120. TEST_ASSERT_NOT_NULL(reparsed);
  121. TEST_ASSERT_TRUE(RyanJsonCompare(root, reparsed));
  122. RyanJsonDelete(reparsed);
  123. RyanJsonFree(printed);
  124. RyanJsonDelete(root);
  125. }
  126. static void testEdgeParsePrintPrintWithStyleFormatFalse(void)
  127. {
  128. // 复杂链路:
  129. // Parse -> PrintWithStyle(format=false) -> Parse -> Compare。
  130. // 目标:验证 style.format=false 输出仍可解析。
  131. RyanJson_t root = RyanJsonParse("{\"a\":1,\"b\":2}");
  132. TEST_ASSERT_NOT_NULL(root);
  133. RyanJsonPrintStyle style = {
  134. .indent = " ", .newline = "\n", .indentLen = 2, .newlineLen = 1, .spaceAfterColon = 1, .format = RyanJsonFalse};
  135. char *printed = RyanJsonPrintWithStyle(root, 64, &style, NULL);
  136. TEST_ASSERT_NOT_NULL(printed);
  137. RyanJson_t reparsed = RyanJsonParse(printed);
  138. TEST_ASSERT_NOT_NULL(reparsed);
  139. TEST_ASSERT_TRUE(RyanJsonCompare(root, reparsed));
  140. RyanJsonDelete(reparsed);
  141. RyanJsonFree(printed);
  142. RyanJsonDelete(root);
  143. }
  144. static void testEdgeParsePrintPrintNullRootRoundtrip(void)
  145. {
  146. // 复杂链路:
  147. // Parse(Null) -> Print -> Parse -> Compare。
  148. // 目标:验证根 Null 往返一致。
  149. RyanJson_t root = RyanJsonParse("null");
  150. TEST_ASSERT_NOT_NULL(root);
  151. char *printed = RyanJsonPrint(root, 8, RyanJsonFalse, NULL);
  152. TEST_ASSERT_NOT_NULL(printed);
  153. RyanJson_t reparsed = RyanJsonParse(printed);
  154. TEST_ASSERT_NOT_NULL(reparsed);
  155. TEST_ASSERT_TRUE(RyanJsonCompare(root, reparsed));
  156. RyanJsonDelete(reparsed);
  157. RyanJsonFree(printed);
  158. RyanJsonDelete(root);
  159. }
  160. static void testEdgeParsePrintPrintBoolRootRoundtrip(void)
  161. {
  162. // 复杂链路:
  163. // Parse(Bool) -> Print -> Parse -> Compare。
  164. // 目标:验证根 Bool 往返一致。
  165. RyanJson_t root = RyanJsonParse("false");
  166. TEST_ASSERT_NOT_NULL(root);
  167. char *printed = RyanJsonPrint(root, 8, RyanJsonFalse, NULL);
  168. TEST_ASSERT_NOT_NULL(printed);
  169. RyanJson_t reparsed = RyanJsonParse(printed);
  170. TEST_ASSERT_NOT_NULL(reparsed);
  171. TEST_ASSERT_TRUE(RyanJsonCompare(root, reparsed));
  172. RyanJsonDelete(reparsed);
  173. RyanJsonFree(printed);
  174. RyanJsonDelete(root);
  175. }
  176. static void testEdgeParsePrintPrintNumberRootRoundtrip(void)
  177. {
  178. // 复杂链路:
  179. // Parse(Number) -> Print -> Parse -> Compare。
  180. // 目标:验证根数值往返一致。
  181. RyanJson_t root = RyanJsonParse("123.5");
  182. TEST_ASSERT_NOT_NULL(root);
  183. char *printed = RyanJsonPrint(root, 8, RyanJsonFalse, NULL);
  184. TEST_ASSERT_NOT_NULL(printed);
  185. RyanJson_t reparsed = RyanJsonParse(printed);
  186. TEST_ASSERT_NOT_NULL(reparsed);
  187. TEST_ASSERT_TRUE(RyanJsonCompare(root, reparsed));
  188. RyanJsonDelete(reparsed);
  189. RyanJsonFree(printed);
  190. RyanJsonDelete(root);
  191. }
  192. static void testEdgeParsePrintPrintPreallocatedWithStyleExact(void)
  193. {
  194. // 复杂链路:
  195. // PrintWithStyle -> 获取长度 -> PrintPreallocatedWithStyle(精确) -> 输出一致性。
  196. // 目标:验证预分配风格打印边界。
  197. RyanJson_t root = RyanJsonParse("{\"a\":1,\"b\":2}");
  198. TEST_ASSERT_NOT_NULL(root);
  199. RyanJsonPrintStyle style = {
  200. .indent = " ", .newline = "\n", .indentLen = 2, .newlineLen = 1, .spaceAfterColon = 1, .format = RyanJsonTrue};
  201. uint32_t len = 0;
  202. char *printed = RyanJsonPrintWithStyle(root, 32, &style, &len);
  203. TEST_ASSERT_NOT_NULL(printed);
  204. char buf[512];
  205. TEST_ASSERT_TRUE(len + 1U <= sizeof(buf));
  206. char *out = RyanJsonPrintPreallocatedWithStyle(root, buf, (uint32_t)sizeof(buf), &style, NULL);
  207. TEST_ASSERT_NOT_NULL(out);
  208. TEST_ASSERT_EQUAL_STRING(printed, out);
  209. RyanJsonFree(printed);
  210. RyanJsonDelete(root);
  211. }
  212. static void testEdgeParsePrintPrintPreallocatedFormatTrue(void)
  213. {
  214. // 复杂链路:
  215. // Parse -> PrintPreallocated(format=true) -> Parse -> Compare。
  216. // 目标:验证预分配格式化打印可往返。
  217. RyanJson_t root = RyanJsonParse("{\"a\":1,\"b\":{\"c\":2}}");
  218. TEST_ASSERT_NOT_NULL(root);
  219. char buf[256];
  220. char *out = RyanJsonPrintPreallocated(root, buf, sizeof(buf), RyanJsonTrue, NULL);
  221. TEST_ASSERT_NOT_NULL(out);
  222. RyanJson_t reparsed = RyanJsonParse(out);
  223. TEST_ASSERT_NOT_NULL(reparsed);
  224. TEST_ASSERT_TRUE(RyanJsonCompare(root, reparsed));
  225. RyanJsonDelete(reparsed);
  226. RyanJsonDelete(root);
  227. }
  228. static void testEdgeParsePrintPrintWithStyleNoSpaceAfterColon(void)
  229. {
  230. // 复杂链路:
  231. // Parse -> PrintWithStyle(spaceAfterColon=0) -> Parse -> Compare。
  232. // 目标:验证冒号后无空格风格可往返。
  233. RyanJson_t root = RyanJsonParse("{\"a\":1,\"b\":2}");
  234. TEST_ASSERT_NOT_NULL(root);
  235. RyanJsonPrintStyle style = {
  236. .indent = " ", .newline = "\n", .indentLen = 2, .newlineLen = 1, .spaceAfterColon = 0, .format = RyanJsonTrue};
  237. char *printed = RyanJsonPrintWithStyle(root, 32, &style, NULL);
  238. TEST_ASSERT_NOT_NULL(printed);
  239. RyanJson_t reparsed = RyanJsonParse(printed);
  240. TEST_ASSERT_NOT_NULL(reparsed);
  241. TEST_ASSERT_TRUE(RyanJsonCompare(root, reparsed));
  242. RyanJsonDelete(reparsed);
  243. RyanJsonFree(printed);
  244. RyanJsonDelete(root);
  245. }
  246. static void testEdgeParsePrintPrintWithStyleIndentLenMismatch(void)
  247. {
  248. // 复杂链路:
  249. // Parse -> PrintWithStyle(indentLen 不匹配) -> Parse -> Compare。
  250. // 目标:验证 indentLen 较短时仍可输出可解析结果。
  251. RyanJson_t root = RyanJsonParse("{\"a\":1,\"b\":{\"c\":2}}");
  252. TEST_ASSERT_NOT_NULL(root);
  253. RyanJsonPrintStyle style = {
  254. .indent = " ", .newline = "\n", .indentLen = 1, .newlineLen = 1, .spaceAfterColon = 1, .format = RyanJsonTrue};
  255. char *printed = RyanJsonPrintWithStyle(root, 64, &style, NULL);
  256. TEST_ASSERT_NOT_NULL(printed);
  257. RyanJson_t reparsed = RyanJsonParse(printed);
  258. TEST_ASSERT_NOT_NULL(reparsed);
  259. TEST_ASSERT_TRUE(RyanJsonCompare(root, reparsed));
  260. RyanJsonDelete(reparsed);
  261. RyanJsonFree(printed);
  262. RyanJsonDelete(root);
  263. }
  264. static void testEdgeParsePrintPrintWithStyleNewlineLenMismatch(void)
  265. {
  266. // 复杂链路:
  267. // Parse -> PrintWithStyle(newlineLen 不匹配) -> Parse -> Compare。
  268. // 目标:验证 newlineLen 较短时仍可输出可解析结果。
  269. RyanJson_t root = RyanJsonParse("{\"a\":1,\"b\":{\"c\":2}}");
  270. TEST_ASSERT_NOT_NULL(root);
  271. RyanJsonPrintStyle style = {
  272. .indent = " ", .newline = "\r\n", .indentLen = 2, .newlineLen = 1, .spaceAfterColon = 1, .format = RyanJsonTrue};
  273. char *printed = RyanJsonPrintWithStyle(root, 64, &style, NULL);
  274. TEST_ASSERT_NOT_NULL(printed);
  275. RyanJson_t reparsed = RyanJsonParse(printed);
  276. TEST_ASSERT_NOT_NULL(reparsed);
  277. TEST_ASSERT_TRUE(RyanJsonCompare(root, reparsed));
  278. RyanJsonDelete(reparsed);
  279. RyanJsonFree(printed);
  280. RyanJsonDelete(root);
  281. }
  282. static void testEdgeParsePrintPrintPreallocatedFormatTrueExact(void)
  283. {
  284. // 复杂链路:
  285. // Print(format=true) -> 获取长度 -> PrintPreallocated(format=true) -> Compare。
  286. // 目标:验证格式化预分配输出边界。
  287. RyanJson_t root = RyanJsonParse("{\"a\":1,\"b\":{\"c\":2}}");
  288. TEST_ASSERT_NOT_NULL(root);
  289. uint32_t len = 0;
  290. char *printed = RyanJsonPrint(root, 16, RyanJsonTrue, &len);
  291. TEST_ASSERT_NOT_NULL(printed);
  292. char buf[512];
  293. TEST_ASSERT_TRUE(len + 1U <= sizeof(buf));
  294. char *out = RyanJsonPrintPreallocated(root, buf, (uint32_t)sizeof(buf), RyanJsonTrue, NULL);
  295. TEST_ASSERT_NOT_NULL(out);
  296. TEST_ASSERT_EQUAL_STRING(printed, out);
  297. RyanJsonFree(printed);
  298. RyanJsonDelete(root);
  299. }
  300. static void testEdgeParsePrintPrintPreallocatedFormatTrueTooSmall(void)
  301. {
  302. // 复杂链路:
  303. // Print(format=true) -> PrintPreallocated(不足) -> PrintPreallocated(足够)。
  304. // 目标:验证格式化预分配失败可恢复。
  305. RyanJson_t root = RyanJsonParse("{\"a\":1,\"b\":{\"c\":2}}");
  306. TEST_ASSERT_NOT_NULL(root);
  307. uint32_t len = 0;
  308. char *printed = RyanJsonPrint(root, 16, RyanJsonTrue, &len);
  309. TEST_ASSERT_NOT_NULL(printed);
  310. char tiny[8];
  311. TEST_ASSERT_TRUE(len + 1U > sizeof(tiny));
  312. TEST_ASSERT_NULL(RyanJsonPrintPreallocated(root, tiny, (uint32_t)sizeof(tiny), RyanJsonTrue, NULL));
  313. char buf[512];
  314. TEST_ASSERT_TRUE(len + 1U <= sizeof(buf));
  315. TEST_ASSERT_NOT_NULL(RyanJsonPrintPreallocated(root, buf, (uint32_t)sizeof(buf), RyanJsonTrue, NULL));
  316. RyanJsonFree(printed);
  317. RyanJsonDelete(root);
  318. }
  319. static void testEdgeParsePrintPrintPreallocatedWithStyleFormatFalse(void)
  320. {
  321. // 复杂链路:
  322. // PrintWithStyle(format=false) -> PrintPreallocatedWithStyle -> Parse -> Compare。
  323. // 目标:验证 style.format=false 的预分配输出可回环。
  324. RyanJson_t root = RyanJsonParse("{\"a\":1,\"b\":2}");
  325. TEST_ASSERT_NOT_NULL(root);
  326. RyanJsonPrintStyle style = {
  327. .indent = " ", .newline = "\n", .indentLen = 2, .newlineLen = 1, .spaceAfterColon = 1, .format = RyanJsonFalse};
  328. uint32_t len = 0;
  329. char *printed = RyanJsonPrintWithStyle(root, 16, &style, &len);
  330. TEST_ASSERT_NOT_NULL(printed);
  331. char buf[512];
  332. TEST_ASSERT_TRUE(len + 1U <= sizeof(buf));
  333. char *out = RyanJsonPrintPreallocatedWithStyle(root, buf, (uint32_t)sizeof(buf), &style, NULL);
  334. TEST_ASSERT_NOT_NULL(out);
  335. RyanJson_t reparsed = RyanJsonParse(out);
  336. TEST_ASSERT_NOT_NULL(reparsed);
  337. TEST_ASSERT_TRUE(RyanJsonCompare(root, reparsed));
  338. RyanJsonDelete(reparsed);
  339. RyanJsonFree(printed);
  340. RyanJsonDelete(root);
  341. }
  342. void testEdgePrintOptionsRunner(void)
  343. {
  344. UnitySetTestFile(__FILE__);
  345. RUN_TEST(testEdgeParsePrintPrintFormatFlag);
  346. RUN_TEST(testEdgeParsePrintPrintPresetSmall);
  347. RUN_TEST(testEdgeParsePrintPrintPreallocatedExactFitFromPrint);
  348. RUN_TEST(testEdgeParsePrintPrintPreallocatedTooSmallThenSuccess);
  349. RUN_TEST(testEdgeParsePrintPrintWithStyleCustomIndent);
  350. RUN_TEST(testEdgeParsePrintPrintWithStyleCrlf);
  351. RUN_TEST(testEdgeParsePrintPrintWithStyleLongIndent);
  352. RUN_TEST(testEdgeParsePrintPrintWithStyleFormatFalse);
  353. RUN_TEST(testEdgeParsePrintPrintNullRootRoundtrip);
  354. RUN_TEST(testEdgeParsePrintPrintBoolRootRoundtrip);
  355. RUN_TEST(testEdgeParsePrintPrintNumberRootRoundtrip);
  356. RUN_TEST(testEdgeParsePrintPrintPreallocatedWithStyleExact);
  357. RUN_TEST(testEdgeParsePrintPrintPreallocatedFormatTrue);
  358. RUN_TEST(testEdgeParsePrintPrintWithStyleNoSpaceAfterColon);
  359. RUN_TEST(testEdgeParsePrintPrintWithStyleIndentLenMismatch);
  360. RUN_TEST(testEdgeParsePrintPrintWithStyleNewlineLenMismatch);
  361. RUN_TEST(testEdgeParsePrintPrintPreallocatedFormatTrueExact);
  362. RUN_TEST(testEdgeParsePrintPrintPreallocatedFormatTrueTooSmall);
  363. RUN_TEST(testEdgeParsePrintPrintPreallocatedWithStyleFormatFalse);
  364. }