1 /*
2 * Copyright (C) 2011 Emweb bv, Herent, Belgium.
3 *
4 * See the LICENSE file for terms of use.
5 */
6 #include <boost/test/unit_test.hpp>
7 #include <boost/version.hpp>
8
9 #include <Wt/Json/Parser.h>
10 #include <Wt/Json/Object.h>
11 #include <Wt/Json/Array.h>
12
13 #include <fstream>
14 #include <streambuf>
15
16 #if !defined(WT_NO_SPIRIT) && BOOST_VERSION >= 104100
17 # define JSON_PARSER
18 #endif
19
20 #ifdef JSON_PARSER
21
22 #define JS(...) #__VA_ARGS__
23
24 using namespace Wt;
25
BOOST_AUTO_TEST_CASE(json_parse_empty_test)26 BOOST_AUTO_TEST_CASE( json_parse_empty_test )
27 {
28 Json::Value result;
29 Json::parse("{}", result);
30
31 BOOST_REQUIRE(result.type() == Json::Type::Object);
32 BOOST_REQUIRE(((const Json::Object&) result).empty());
33 }
34
BOOST_AUTO_TEST_CASE(json_parse_object1_test)35 BOOST_AUTO_TEST_CASE( json_parse_object1_test )
36 {
37 Json::Object result;
38 Json::parse("{ "
39 " \"a\": \"That's great\", "
40 " \"b\": true "
41 "}",
42 result);
43 BOOST_REQUIRE(result.size() == 2);
44
45 WString a = result.get("a");
46 bool b = result.get("b");
47
48 BOOST_REQUIRE(a == "That's great");
49 BOOST_REQUIRE(b == true);
50 }
51
BOOST_AUTO_TEST_CASE(json_parse_object2_test)52 BOOST_AUTO_TEST_CASE( json_parse_object2_test )
53 {
54 Json::Object result;
55 Json::parse("{ \"a\": 5 }", result);
56
57 BOOST_REQUIRE(result.size() == 1);
58
59 int i = result.get("a");
60
61 BOOST_REQUIRE(i == 5);
62 }
63
BOOST_AUTO_TEST_CASE(json_parse_strings_test)64 BOOST_AUTO_TEST_CASE( json_parse_strings_test )
65 {
66 Json::Object result;
67 Json::parse(JS({
68 "s1": "simple",
69 "s2": "escaped: \\ \t \n \b \r",
70 "s3": "unicode: \u0194"
71 }), result);
72
73 BOOST_REQUIRE(result.size() == 3);
74
75 const WString& s1 = result.get("s1");
76 BOOST_REQUIRE(s1 == "simple");
77 const WString& s2 = result.get("s2");
78 BOOST_REQUIRE(s2 == "escaped: \\ \t \n \b \r");
79 const WString& s3 = result.get("s3");
80 BOOST_REQUIRE(s3 == L"unicode: \x0194");
81 }
82
BOOST_AUTO_TEST_CASE(json_structure_test)83 BOOST_AUTO_TEST_CASE( json_structure_test )
84 {
85 Json::Object result;
86 Json::parse(JS({
87 "firstName": "John",
88 "lastName": "Smith",
89 "age": 25,
90 "address":
91 {
92 "streetAddress": "21 2nd Street",
93 "city": "New York",
94 "state": "NY",
95 "postalCode": "10021"
96 },
97 "phoneNumber":
98 [
99 {
100 "type": "home",
101 "number": "212 555-1234"
102 },
103 {
104 "type": "fax",
105 "number": "646 555-4567"
106 }
107 ]
108 }), result);
109
110 BOOST_REQUIRE(result.size() == 5);
111
112 const Json::Array& phoneNumbers = result.get("phoneNumber");
113 BOOST_REQUIRE(phoneNumbers.size() == 2);
114
115 const Json::Object& p1 = phoneNumbers[0];
116 WString t1 = p1.get("type");
117 WString n1 = p1.get("number");
118 BOOST_REQUIRE(t1 == "home");
119 BOOST_REQUIRE(n1 == "212 555-1234");
120 }
121
BOOST_AUTO_TEST_CASE(json_bad_test)122 BOOST_AUTO_TEST_CASE( json_bad_test )
123 {
124 bool caught = false;
125
126 try {
127 Json::Object result;
128 Json::parse("{ \"Field1\": \"one\" \n \"Field2\" : \"two\" }", result);
129 } catch (std::exception& e) {
130 caught = true;
131 }
132
133 BOOST_REQUIRE(caught);
134 }
135
BOOST_AUTO_TEST_CASE(json_utf8_test)136 BOOST_AUTO_TEST_CASE( json_utf8_test )
137 {
138 std::ifstream t("json/UTF-8-test.json", std::ios::in | std::ios::binary);
139 BOOST_REQUIRE(t.good());
140 std::string str((std::istreambuf_iterator<char>(t)),
141 std::istreambuf_iterator<char>());
142
143 Json::Object result;
144 Json::parse(str, result);
145 WString s1 = result.get("kosme");
146 WString s2 = result.get("2 bytes (U-00000080)");
147 WString s3 = result.get("3 bytes (U-00000800)");
148 WString s4 = result.get("4 bytes (U-00010000)");
149 WString s5 = result.get("1 byte (U-0000007F)");
150 WString s6 = result.get("2 bytes (U-000007FF)");
151 WString s7 = result.get("3 bytes (U-0000FFFF)");
152 WString s8 = result.get("U-0000D7FF = ed 9f bf");
153 WString s9 = result.get("U-0000E000 = ee 80 80");
154 WString s10 = result.get("U-0000FFFD = ef bf bd");
155 WString s11 = result.get("U-0010FFFF = f4 8f bf bf");
156
157 std::u32string u32s1 = s1.toUTF32();
158 std::u32string u32s2 = s2.toUTF32();
159 std::u32string u32s3 = s3.toUTF32();
160 std::u32string u32s4 = s4.toUTF32();
161 std::u32string u32s5 = s5.toUTF32();
162 std::u32string u32s6 = s6.toUTF32();
163 std::u32string u32s7 = s7.toUTF32();
164 std::u32string u32s8 = s8.toUTF32();
165 std::u32string u32s9 = s9.toUTF32();
166 std::u32string u32s10 = s10.toUTF32();
167 std::u32string u32s11 = s11.toUTF32();
168
169 BOOST_REQUIRE(u32s1[0] == 954);
170 BOOST_REQUIRE(u32s1[1] == 8057);
171 BOOST_REQUIRE(u32s1[2] == 963);
172 BOOST_REQUIRE(u32s1[3] == 956);
173 BOOST_REQUIRE(u32s1[4] == 949);
174 BOOST_REQUIRE(u32s2[0] == 128);
175 BOOST_REQUIRE(u32s3[0] == 2048);
176 BOOST_REQUIRE(u32s4[0] == 65533 || u32s4[0] == 65536);
177 BOOST_REQUIRE(u32s5[0] == 127);
178 BOOST_REQUIRE(u32s6[0] == 2047);
179 BOOST_REQUIRE(u32s7[0] == 65535);
180 BOOST_REQUIRE(u32s8[0] == 55295);
181 BOOST_REQUIRE(u32s9[0] == 57344);
182 BOOST_REQUIRE(u32s10[0] == 65533);
183 BOOST_REQUIRE(u32s11[0] == '?'); // should this really be rejected?
184
185 BOOST_REQUIRE(result.size() == 11);
186 }
187
188
189 #endif // JSON_PARSER
190