writertest.cpp 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427
  1. // Tencent is pleased to support the open source community by making RapidJSON available.
  2. //
  3. // Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.
  4. //
  5. // Licensed under the MIT License (the "License"); you may not use this file except
  6. // in compliance with the License. You may obtain a copy of the License at
  7. //
  8. // http://opensource.org/licenses/MIT
  9. //
  10. // Unless required by applicable law or agreed to in writing, software distributed
  11. // under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
  12. // CONDITIONS OF ANY KIND, either express or implied. See the License for the
  13. // specific language governing permissions and limitations under the License.
  14. #include "unittest.h"
  15. #include "rapidjson/document.h"
  16. #include "rapidjson/reader.h"
  17. #include "rapidjson/writer.h"
  18. #include "rapidjson/stringbuffer.h"
  19. using namespace rapidjson;
  20. TEST(Writer, Compact) {
  21. StringStream s("{ \"hello\" : \"world\", \"t\" : true , \"f\" : false, \"n\": null, \"i\":123, \"pi\": 3.1416, \"a\":[1, 2, 3] } ");
  22. StringBuffer buffer;
  23. Writer<StringBuffer> writer(buffer);
  24. buffer.ShrinkToFit();
  25. Reader reader;
  26. reader.Parse<0>(s, writer);
  27. EXPECT_STREQ("{\"hello\":\"world\",\"t\":true,\"f\":false,\"n\":null,\"i\":123,\"pi\":3.1416,\"a\":[1,2,3]}", buffer.GetString());
  28. EXPECT_EQ(77u, buffer.GetSize());
  29. EXPECT_TRUE(writer.IsComplete());
  30. }
  31. // json -> parse -> writer -> json
  32. #define TEST_ROUNDTRIP(json) \
  33. { \
  34. StringStream s(json); \
  35. StringBuffer buffer; \
  36. Writer<StringBuffer> writer(buffer); \
  37. Reader reader; \
  38. reader.Parse<kParseFullPrecisionFlag>(s, writer); \
  39. EXPECT_STREQ(json, buffer.GetString()); \
  40. EXPECT_TRUE(writer.IsComplete()); \
  41. }
  42. TEST(Writer, Root) {
  43. TEST_ROUNDTRIP("null");
  44. TEST_ROUNDTRIP("true");
  45. TEST_ROUNDTRIP("false");
  46. TEST_ROUNDTRIP("0");
  47. TEST_ROUNDTRIP("\"foo\"");
  48. TEST_ROUNDTRIP("[]");
  49. TEST_ROUNDTRIP("{}");
  50. }
  51. TEST(Writer, Int) {
  52. TEST_ROUNDTRIP("[-1]");
  53. TEST_ROUNDTRIP("[-123]");
  54. TEST_ROUNDTRIP("[-2147483648]");
  55. }
  56. TEST(Writer, UInt) {
  57. TEST_ROUNDTRIP("[0]");
  58. TEST_ROUNDTRIP("[1]");
  59. TEST_ROUNDTRIP("[123]");
  60. TEST_ROUNDTRIP("[2147483647]");
  61. TEST_ROUNDTRIP("[4294967295]");
  62. }
  63. TEST(Writer, Int64) {
  64. TEST_ROUNDTRIP("[-1234567890123456789]");
  65. TEST_ROUNDTRIP("[-9223372036854775808]");
  66. }
  67. TEST(Writer, Uint64) {
  68. TEST_ROUNDTRIP("[1234567890123456789]");
  69. TEST_ROUNDTRIP("[9223372036854775807]");
  70. }
  71. TEST(Writer, String) {
  72. TEST_ROUNDTRIP("[\"Hello\"]");
  73. TEST_ROUNDTRIP("[\"Hello\\u0000World\"]");
  74. TEST_ROUNDTRIP("[\"\\\"\\\\/\\b\\f\\n\\r\\t\"]");
  75. #if RAPIDJSON_HAS_STDSTRING
  76. {
  77. StringBuffer buffer;
  78. Writer<StringBuffer> writer(buffer);
  79. writer.String(std::string("Hello\n"));
  80. EXPECT_STREQ("\"Hello\\n\"", buffer.GetString());
  81. }
  82. #endif
  83. }
  84. TEST(Writer, Double) {
  85. TEST_ROUNDTRIP("[1.2345,1.2345678,0.123456789012,1234567.8]");
  86. TEST_ROUNDTRIP("0.0");
  87. TEST_ROUNDTRIP("-0.0"); // Issue #289
  88. TEST_ROUNDTRIP("1e30");
  89. TEST_ROUNDTRIP("1.0");
  90. TEST_ROUNDTRIP("5e-324"); // Min subnormal positive double
  91. TEST_ROUNDTRIP("2.225073858507201e-308"); // Max subnormal positive double
  92. TEST_ROUNDTRIP("2.2250738585072014e-308"); // Min normal positive double
  93. TEST_ROUNDTRIP("1.7976931348623157e308"); // Max double
  94. }
  95. TEST(Writer, Transcode) {
  96. const char json[] = "{\"hello\":\"world\",\"t\":true,\"f\":false,\"n\":null,\"i\":123,\"pi\":3.1416,\"a\":[1,2,3],\"dollar\":\"\x24\",\"cents\":\"\xC2\xA2\",\"euro\":\"\xE2\x82\xAC\",\"gclef\":\"\xF0\x9D\x84\x9E\"}";
  97. // UTF8 -> UTF16 -> UTF8
  98. {
  99. StringStream s(json);
  100. StringBuffer buffer;
  101. Writer<StringBuffer, UTF16<>, UTF8<> > writer(buffer);
  102. GenericReader<UTF8<>, UTF16<> > reader;
  103. reader.Parse(s, writer);
  104. EXPECT_STREQ(json, buffer.GetString());
  105. }
  106. // UTF8 -> UTF8 -> ASCII -> UTF8 -> UTF8
  107. {
  108. StringStream s(json);
  109. StringBuffer buffer;
  110. Writer<StringBuffer, UTF8<>, ASCII<> > writer(buffer);
  111. Reader reader;
  112. reader.Parse(s, writer);
  113. StringBuffer buffer2;
  114. Writer<StringBuffer> writer2(buffer2);
  115. GenericReader<ASCII<>, UTF8<> > reader2;
  116. StringStream s2(buffer.GetString());
  117. reader2.Parse(s2, writer2);
  118. EXPECT_STREQ(json, buffer2.GetString());
  119. }
  120. }
  121. #include <sstream>
  122. class OStreamWrapper {
  123. public:
  124. typedef char Ch;
  125. OStreamWrapper(std::ostream& os) : os_(os) {}
  126. Ch Peek() const { assert(false); return '\0'; }
  127. Ch Take() { assert(false); return '\0'; }
  128. size_t Tell() const { return 0; }
  129. Ch* PutBegin() { assert(false); return 0; }
  130. void Put(Ch c) { os_.put(c); }
  131. void Flush() { os_.flush(); }
  132. size_t PutEnd(Ch*) { assert(false); return 0; }
  133. private:
  134. OStreamWrapper(const OStreamWrapper&);
  135. OStreamWrapper& operator=(const OStreamWrapper&);
  136. std::ostream& os_;
  137. };
  138. TEST(Writer, OStreamWrapper) {
  139. StringStream s("{ \"hello\" : \"world\", \"t\" : true , \"f\" : false, \"n\": null, \"i\":123, \"pi\": 3.1416, \"a\":[1, 2, 3], \"u64\": 1234567890123456789, \"i64\":-1234567890123456789 } ");
  140. std::stringstream ss;
  141. OStreamWrapper os(ss);
  142. Writer<OStreamWrapper> writer(os);
  143. Reader reader;
  144. reader.Parse<0>(s, writer);
  145. std::string actual = ss.str();
  146. EXPECT_STREQ("{\"hello\":\"world\",\"t\":true,\"f\":false,\"n\":null,\"i\":123,\"pi\":3.1416,\"a\":[1,2,3],\"u64\":1234567890123456789,\"i64\":-1234567890123456789}", actual.c_str());
  147. }
  148. TEST(Writer, AssertRootMayBeAnyValue) {
  149. #define T(x)\
  150. {\
  151. StringBuffer buffer;\
  152. Writer<StringBuffer> writer(buffer);\
  153. EXPECT_TRUE(x);\
  154. }
  155. T(writer.Bool(false));
  156. T(writer.Bool(true));
  157. T(writer.Null());
  158. T(writer.Int(0));
  159. T(writer.Uint(0));
  160. T(writer.Int64(0));
  161. T(writer.Uint64(0));
  162. T(writer.Double(0));
  163. T(writer.String("foo"));
  164. #undef T
  165. }
  166. TEST(Writer, AssertIncorrectObjectLevel) {
  167. StringBuffer buffer;
  168. Writer<StringBuffer> writer(buffer);
  169. writer.StartObject();
  170. writer.EndObject();
  171. ASSERT_THROW(writer.EndObject(), AssertException);
  172. }
  173. TEST(Writer, AssertIncorrectArrayLevel) {
  174. StringBuffer buffer;
  175. Writer<StringBuffer> writer(buffer);
  176. writer.StartArray();
  177. writer.EndArray();
  178. ASSERT_THROW(writer.EndArray(), AssertException);
  179. }
  180. TEST(Writer, AssertIncorrectEndObject) {
  181. StringBuffer buffer;
  182. Writer<StringBuffer> writer(buffer);
  183. writer.StartObject();
  184. ASSERT_THROW(writer.EndArray(), AssertException);
  185. }
  186. TEST(Writer, AssertIncorrectEndArray) {
  187. StringBuffer buffer;
  188. Writer<StringBuffer> writer(buffer);
  189. writer.StartObject();
  190. ASSERT_THROW(writer.EndArray(), AssertException);
  191. }
  192. TEST(Writer, AssertObjectKeyNotString) {
  193. #define T(x)\
  194. {\
  195. StringBuffer buffer;\
  196. Writer<StringBuffer> writer(buffer);\
  197. writer.StartObject();\
  198. ASSERT_THROW(x, AssertException); \
  199. }
  200. T(writer.Bool(false));
  201. T(writer.Bool(true));
  202. T(writer.Null());
  203. T(writer.Int(0));
  204. T(writer.Uint(0));
  205. T(writer.Int64(0));
  206. T(writer.Uint64(0));
  207. T(writer.Double(0));
  208. T(writer.StartObject());
  209. T(writer.StartArray());
  210. #undef T
  211. }
  212. TEST(Writer, AssertMultipleRoot) {
  213. StringBuffer buffer;
  214. Writer<StringBuffer> writer(buffer);
  215. writer.StartObject();
  216. writer.EndObject();
  217. ASSERT_THROW(writer.StartObject(), AssertException);
  218. writer.Reset(buffer);
  219. writer.Null();
  220. ASSERT_THROW(writer.Int(0), AssertException);
  221. writer.Reset(buffer);
  222. writer.String("foo");
  223. ASSERT_THROW(writer.StartArray(), AssertException);
  224. writer.Reset(buffer);
  225. writer.StartArray();
  226. writer.EndArray();
  227. //ASSERT_THROW(writer.Double(3.14), AssertException);
  228. }
  229. TEST(Writer, RootObjectIsComplete) {
  230. StringBuffer buffer;
  231. Writer<StringBuffer> writer(buffer);
  232. EXPECT_FALSE(writer.IsComplete());
  233. writer.StartObject();
  234. EXPECT_FALSE(writer.IsComplete());
  235. writer.String("foo");
  236. EXPECT_FALSE(writer.IsComplete());
  237. writer.Int(1);
  238. EXPECT_FALSE(writer.IsComplete());
  239. writer.EndObject();
  240. EXPECT_TRUE(writer.IsComplete());
  241. }
  242. TEST(Writer, RootArrayIsComplete) {
  243. StringBuffer buffer;
  244. Writer<StringBuffer> writer(buffer);
  245. EXPECT_FALSE(writer.IsComplete());
  246. writer.StartArray();
  247. EXPECT_FALSE(writer.IsComplete());
  248. writer.String("foo");
  249. EXPECT_FALSE(writer.IsComplete());
  250. writer.Int(1);
  251. EXPECT_FALSE(writer.IsComplete());
  252. writer.EndArray();
  253. EXPECT_TRUE(writer.IsComplete());
  254. }
  255. TEST(Writer, RootValueIsComplete) {
  256. #define T(x)\
  257. {\
  258. StringBuffer buffer;\
  259. Writer<StringBuffer> writer(buffer);\
  260. EXPECT_FALSE(writer.IsComplete()); \
  261. x; \
  262. EXPECT_TRUE(writer.IsComplete()); \
  263. }
  264. T(writer.Null());
  265. T(writer.Bool(true));
  266. T(writer.Bool(false));
  267. T(writer.Int(0));
  268. T(writer.Uint(0));
  269. T(writer.Int64(0));
  270. T(writer.Uint64(0));
  271. T(writer.Double(0));
  272. T(writer.String(""));
  273. #undef T
  274. }
  275. TEST(Writer, InvalidEncoding) {
  276. // Fail in decoding invalid UTF-8 sequence http://www.cl.cam.ac.uk/~mgk25/ucs/examples/UTF-8-test.txt
  277. {
  278. GenericStringBuffer<UTF16<> > buffer;
  279. Writer<GenericStringBuffer<UTF16<> >, UTF8<>, UTF16<> > writer(buffer);
  280. writer.StartArray();
  281. EXPECT_FALSE(writer.String("\xfe"));
  282. EXPECT_FALSE(writer.String("\xff"));
  283. EXPECT_FALSE(writer.String("\xfe\xfe\xff\xff"));
  284. writer.EndArray();
  285. }
  286. // Fail in encoding
  287. {
  288. StringBuffer buffer;
  289. Writer<StringBuffer, UTF32<> > writer(buffer);
  290. static const UTF32<>::Ch s[] = { 0x110000, 0 }; // Out of U+0000 to U+10FFFF
  291. EXPECT_FALSE(writer.String(s));
  292. }
  293. // Fail in unicode escaping in ASCII output
  294. {
  295. StringBuffer buffer;
  296. Writer<StringBuffer, UTF32<>, ASCII<> > writer(buffer);
  297. static const UTF32<>::Ch s[] = { 0x110000, 0 }; // Out of U+0000 to U+10FFFF
  298. EXPECT_FALSE(writer.String(s));
  299. }
  300. }
  301. TEST(Writer, ValidateEncoding) {
  302. {
  303. StringBuffer buffer;
  304. Writer<StringBuffer, UTF8<>, UTF8<>, CrtAllocator, kWriteValidateEncodingFlag> writer(buffer);
  305. writer.StartArray();
  306. EXPECT_TRUE(writer.String("\x24")); // Dollar sign U+0024
  307. EXPECT_TRUE(writer.String("\xC2\xA2")); // Cents sign U+00A2
  308. EXPECT_TRUE(writer.String("\xE2\x82\xAC")); // Euro sign U+20AC
  309. EXPECT_TRUE(writer.String("\xF0\x9D\x84\x9E")); // G clef sign U+1D11E
  310. writer.EndArray();
  311. EXPECT_STREQ("[\"\x24\",\"\xC2\xA2\",\"\xE2\x82\xAC\",\"\xF0\x9D\x84\x9E\"]", buffer.GetString());
  312. }
  313. // Fail in decoding invalid UTF-8 sequence http://www.cl.cam.ac.uk/~mgk25/ucs/examples/UTF-8-test.txt
  314. {
  315. StringBuffer buffer;
  316. Writer<StringBuffer, UTF8<>, UTF8<>, CrtAllocator, kWriteValidateEncodingFlag> writer(buffer);
  317. writer.StartArray();
  318. EXPECT_FALSE(writer.String("\xfe"));
  319. EXPECT_FALSE(writer.String("\xff"));
  320. EXPECT_FALSE(writer.String("\xfe\xfe\xff\xff"));
  321. writer.EndArray();
  322. }
  323. }
  324. TEST(Writer, InvalidEventSequence) {
  325. // {]
  326. {
  327. StringBuffer buffer;
  328. Writer<StringBuffer> writer(buffer);
  329. writer.StartObject();
  330. EXPECT_THROW(writer.EndArray(), AssertException);
  331. EXPECT_FALSE(writer.IsComplete());
  332. }
  333. // [}
  334. {
  335. StringBuffer buffer;
  336. Writer<StringBuffer> writer(buffer);
  337. writer.StartArray();
  338. EXPECT_THROW(writer.EndObject(), AssertException);
  339. EXPECT_FALSE(writer.IsComplete());
  340. }
  341. // { 1:
  342. {
  343. StringBuffer buffer;
  344. Writer<StringBuffer> writer(buffer);
  345. writer.StartObject();
  346. EXPECT_THROW(writer.Int(1), AssertException);
  347. EXPECT_FALSE(writer.IsComplete());
  348. }
  349. }
  350. extern double zero; // clang -Wmissing-variable-declarations
  351. double zero = 0.0; // Use global variable to prevent compiler warning
  352. TEST(Writer, NaN) {
  353. double nan = zero / zero;
  354. EXPECT_TRUE(internal::Double(nan).IsNan());
  355. StringBuffer buffer;
  356. Writer<StringBuffer> writer(buffer);
  357. EXPECT_FALSE(writer.Double(nan));
  358. }
  359. TEST(Writer, Inf) {
  360. double inf = 1.0 / zero;
  361. EXPECT_TRUE(internal::Double(inf).IsInf());
  362. StringBuffer buffer;
  363. {
  364. Writer<StringBuffer> writer(buffer);
  365. EXPECT_FALSE(writer.Double(inf));
  366. }
  367. {
  368. Writer<StringBuffer> writer(buffer);
  369. EXPECT_FALSE(writer.Double(-inf));
  370. }
  371. }