RyanJsonBaseTestEqualityString.c 9.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171
  1. #include "RyanJsonBaseTest.h"
  2. // ========== 简单字符串(使用X-macro) ==========
  3. #define SimpleStringList \
  4. X("") \
  5. X("hello") \
  6. X("world") \
  7. X("test") \
  8. X("RyanJson") \
  9. X("123") \
  10. X("0") \
  11. X("-1") \
  12. X("3.14") \
  13. X("1e10") \
  14. X("hello world") \
  15. X("path/to/file") \
  16. X("abcdefghijklmnopqrstuvwxyz") \
  17. X("ABCDEFGHIJKLMNOPQRSTUVWXYZ") \
  18. X("0123456789") \
  19. X("The quick brown fox jumps over the lazy dog") \
  20. X(" ") \
  21. X(" ") \
  22. X(" leading") \
  23. X("trailing ") \
  24. X(" both ") \
  25. X("true") \
  26. X("false") \
  27. X("null") \
  28. X("@#$%^&*()") \
  29. X("!@#$%") \
  30. X("a=b&c=d") \
  31. X("user@example.com") \
  32. X("中文测试") \
  33. X("日本語テスト") \
  34. X("한국어테스트") \
  35. X("混合Mixed混合") \
  36. X("Привет мир") \
  37. X("مرحبا بالعالم") \
  38. X("שלום עולם")
  39. static const char *SimpleStringValueTable[] = {
  40. #define X(a) a,
  41. SimpleStringList
  42. #undef X
  43. };
  44. static const char *SimpleStringJsonTable[] = {
  45. #define X(a) "{\"str\":\"" a "\"}",
  46. SimpleStringList
  47. #undef X
  48. };
  49. // ========== 转义字符(需分离JSON和值) ==========
  50. typedef struct
  51. {
  52. const char *json; // JSON字符串(带转义)
  53. const char *expected; // 期望的C字符串值
  54. } EscapeTestCase;
  55. static const EscapeTestCase EscapeTestCases[] = {
  56. // 制表符
  57. {"{\"str\":\"hello\\tworld\"}", "hello\tworld"},
  58. {"{\"str\":\"tab\\there\"}", "tab\there"},
  59. // 换行符
  60. {"{\"str\":\"hello\\nworld\"}", "hello\nworld"},
  61. {"{\"str\":\"line1\\nline2\\nline3\"}", "line1\nline2\nline3"},
  62. // 回车符
  63. {"{\"str\":\"hello\\rworld\"}", "hello\rworld"},
  64. // 引号转义
  65. {"{\"str\":\"quote\\\"inside\"}", "quote\"inside"},
  66. {"{\"str\":\"say \\\"hello\\\"\"}", "say \"hello\""},
  67. // 反斜杠转义
  68. {"{\"str\":\"backslash\\\\here\"}", "backslash\\here"},
  69. {"{\"str\":\"C:\\\\Windows\\\\System32\"}", "C:\\Windows\\System32"},
  70. {"{\"str\":\"path\\\\to\\\\file\"}", "path\\to\\file"},
  71. // 斜杠(可选转义)
  72. {"{\"str\":\"a\\/b\"}", "a/b"},
  73. // 退格符
  74. {"{\"str\":\"back\\bspace\"}", "back\bspace"},
  75. // 换页符
  76. {"{\"str\":\"form\\ffeed\"}", "form\ffeed"},
  77. // 组合转义
  78. {"{\"str\":\"line1\\nline2\\ttab\"}", "line1\nline2\ttab"},
  79. {"{\"str\":\"\\\"quoted\\\" and \\\\escaped\\\\\"}", "\"quoted\" and \\escaped\\"},
  80. // Unicode转义
  81. {"{\"str\":\"\\u0048\\u0065\\u006C\\u006C\\u006F\"}", "Hello"},
  82. {"{\"str\":\"\\u4E2D\\u6587\"}", "中文"},
  83. {"{\"str\":\"euro: \\u20AC\"}", "euro: €"},
  84. {"{\"str\":\"smile: \\u263A\"}", "smile: ☺"},
  85. };
  86. // 字符串一致性测试
  87. RyanJsonBool_e RyanJsonBaseTestEqualityString(void)
  88. {
  89. // ========== 测试简单字符串 ==========
  90. for (uint32_t i = 0; i < sizeof(SimpleStringValueTable) / sizeof(SimpleStringValueTable[0]); i++)
  91. {
  92. const char *jsonStrInput = SimpleStringJsonTable[i];
  93. RyanJson_t jsonRoot = RyanJsonParse(jsonStrInput);
  94. RyanJsonCheckReturnFalse(NULL != jsonRoot);
  95. RyanJsonCheckReturnFalse(RyanJsonIsString(RyanJsonGetObjectToKey(jsonRoot, "str")));
  96. const char *strValue = RyanJsonGetStringValue(RyanJsonGetObjectToKey(jsonRoot, "str"));
  97. RyanJsonCheckCode(0 == strcmp(strValue, SimpleStringValueTable[i]), {
  98. jsonLog("simple str failed: expected: %s, got: %s\n", SimpleStringValueTable[i], strValue);
  99. RyanJsonDelete(jsonRoot);
  100. goto err;
  101. });
  102. // 往返测试
  103. char *serializedStr = RyanJsonPrint(jsonRoot, 128, RyanJsonFalse, NULL);
  104. RyanJsonDelete(jsonRoot);
  105. RyanJson_t roundtripJson = RyanJsonParse(serializedStr);
  106. RyanJsonFree(serializedStr);
  107. RyanJsonCheckReturnFalse(NULL != roundtripJson);
  108. const char *roundtripValue = RyanJsonGetStringValue(RyanJsonGetObjectToKey(roundtripJson, "str"));
  109. RyanJsonCheckCode(0 == strcmp(roundtripValue, SimpleStringValueTable[i]), {
  110. jsonLog("simple roundtrip failed: expected: %s, got: %s\n", SimpleStringValueTable[i], roundtripValue);
  111. RyanJsonDelete(roundtripJson);
  112. goto err;
  113. });
  114. RyanJsonDelete(roundtripJson);
  115. }
  116. // ========== 测试转义字符 ==========
  117. for (uint32_t i = 0; i < sizeof(EscapeTestCases) / sizeof(EscapeTestCases[0]); i++)
  118. {
  119. const EscapeTestCase *tc = &EscapeTestCases[i];
  120. RyanJson_t jsonRoot = RyanJsonParse(tc->json);
  121. RyanJsonCheckCode(NULL != jsonRoot, {
  122. jsonLog("escape parse failed: %s\n", tc->json);
  123. goto err;
  124. });
  125. RyanJsonCheckReturnFalse(RyanJsonIsString(RyanJsonGetObjectToKey(jsonRoot, "str")));
  126. const char *strValue = RyanJsonGetStringValue(RyanJsonGetObjectToKey(jsonRoot, "str"));
  127. RyanJsonCheckCode(0 == strcmp(strValue, tc->expected), {
  128. jsonLog("escape str failed: json=%s, expected=%s, got=%s\n", tc->json, tc->expected, strValue);
  129. RyanJsonDelete(jsonRoot);
  130. goto err;
  131. });
  132. // 往返测试
  133. char *serializedStr = RyanJsonPrint(jsonRoot, 128, RyanJsonFalse, NULL);
  134. RyanJsonDelete(jsonRoot);
  135. RyanJson_t roundtripJson = RyanJsonParse(serializedStr);
  136. RyanJsonFree(serializedStr);
  137. RyanJsonCheckCode(NULL != roundtripJson, {
  138. jsonLog("escape roundtrip parse failed\n");
  139. goto err;
  140. });
  141. const char *roundtripValue = RyanJsonGetStringValue(RyanJsonGetObjectToKey(roundtripJson, "str"));
  142. RyanJsonCheckCode(0 == strcmp(roundtripValue, tc->expected), {
  143. jsonLog("escape roundtrip failed: expected=%s, got=%s\n", tc->expected, roundtripValue);
  144. RyanJsonDelete(roundtripJson);
  145. goto err;
  146. });
  147. RyanJsonDelete(roundtripJson);
  148. }
  149. return RyanJsonTrue;
  150. err:
  151. return RyanJsonFalse;
  152. }