blob: da7680283e77f9517688dd5a8b305f2fc74f5e23 [file] [log] [blame]
David Reissea2cba82009-03-30 21:35:00 +00001/*
2 * Licensed to the Apache Software Foundation (ASF) under one
3 * or more contributor license agreements. See the NOTICE file
4 * distributed with this work for additional information
5 * regarding copyright ownership. The ASF licenses this file
6 * to you under the Apache License, Version 2.0 (the
7 * "License"); you may not use this file except in compliance
8 * with the License. You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing,
13 * software distributed under the License is distributed on an
14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 * KIND, either express or implied. See the License for the
16 * specific language governing permissions and limitations
17 * under the License.
18 */
19
Jake Farrell5d02b802014-01-07 21:42:01 -050020#define _USE_MATH_DEFINES
David Reissdb0ea152008-02-18 01:49:37 +000021#include <cmath>
Roger Meier49ff8b12012-04-13 09:12:31 +000022#include <thrift/transport/TBufferTransports.h>
23#include <thrift/protocol/TJSONProtocol.h>
David Reissdb0ea152008-02-18 01:49:37 +000024#include "gen-cpp/DebugProtoTest_types.h"
25
Claudius Heine5ef662b2015-06-24 10:03:50 +020026#define BOOST_TEST_MODULE JSONProtoTest
27#include <boost/test/unit_test.hpp>
David Reissdb0ea152008-02-18 01:49:37 +000028
Claudius Heine5ef662b2015-06-24 10:03:50 +020029using namespace thrift::test::debug;
30using apache::thrift::transport::TMemoryBuffer;
31using apache::thrift::protocol::TJSONProtocol;
David Reissdb0ea152008-02-18 01:49:37 +000032
Claudius Heine5ef662b2015-06-24 10:03:50 +020033static std::auto_ptr<OneOfEach> ooe;
David Reissdb0ea152008-02-18 01:49:37 +000034
Claudius Heine5ef662b2015-06-24 10:03:50 +020035void testCaseSetup_1() {
36 ooe.reset(new OneOfEach);
37 ooe->im_true = true;
38 ooe->im_false = false;
39 ooe->a_bite = 0x7f;
40 ooe->integer16 = 27000;
41 ooe->integer32 = 1 << 24;
42 ooe->integer64 = (uint64_t)6000 * 1000 * 1000;
43 ooe->double_precision = M_PI;
44 ooe->some_characters = "JSON THIS! \"\1";
45 ooe->zomg_unicode = "\xd7\n\a\t";
46 ooe->base64 = "\1\2\3\255";
47}
David Reissdb0ea152008-02-18 01:49:37 +000048
Claudius Heine5ef662b2015-06-24 10:03:50 +020049BOOST_AUTO_TEST_CASE(test_json_proto_1) {
50 testCaseSetup_1();
David Reissdb0ea152008-02-18 01:49:37 +000051
Claudius Heine5ef662b2015-06-24 10:03:50 +020052 const std::string expected_result(
53 "{\"1\":{\"tf\":1},\"2\":{\"tf\":0},\"3\":{\"i8\":127},\"4\":{\"i16\":27000},"
54 "\"5\":{\"i32\":16777216},\"6\":{\"i64\":6000000000},\"7\":{\"dbl\":3.1415926"
55 "53589793},\"8\":{\"str\":\"JSON THIS! \\\"\\u0001\"},\"9\":{\"str\":\"\xd7\\"
56 "n\\u0007\\t\"},\"10\":{\"tf\":0},\"11\":{\"str\":\"AQIDrQ\"},\"12\":{\"lst\""
57 ":[\"i8\",3,1,2,3]},\"13\":{\"lst\":[\"i16\",3,1,2,3]},\"14\":{\"lst\":[\"i64"
58 "\",3,1,2,3]}}");
59
60 const std::string result(apache::thrift::ThriftJSONString(*ooe));
61
62 BOOST_CHECK_MESSAGE(!expected_result.compare(result),
63 "Expected:\n" << expected_result << "\nGotten:\n" << result);
64}
65
66static std::auto_ptr<Nesting> n;
67
68void testCaseSetup_2() {
69 testCaseSetup_1();
70
71 n.reset(new Nesting);
72 n->my_ooe = *ooe;
73 n->my_ooe.integer16 = 16;
74 n->my_ooe.integer32 = 32;
75 n->my_ooe.integer64 = 64;
76 n->my_ooe.double_precision = (std::sqrt(5.0) + 1) / 2;
77 n->my_ooe.some_characters = ":R (me going \"rrrr\")";
78 n->my_ooe.zomg_unicode = "\xd3\x80\xe2\x85\xae\xce\x9d\x20\xd0\x9d\xce"
79 "\xbf\xe2\x85\xbf\xd0\xbe\xc9\xa1\xd0\xb3\xd0"
80 "\xb0\xcf\x81\xe2\x84\x8e\x20\xce\x91\x74\x74"
81 "\xce\xb1\xe2\x85\xbd\xce\xba\xc7\x83\xe2\x80"
82 "\xbc";
83 n->my_bonk.type = 31337;
84 n->my_bonk.message = "I am a bonk... xor!";
85}
86
87BOOST_AUTO_TEST_CASE(test_json_proto_2) {
88 testCaseSetup_2();
89
90 const std::string expected_result(
91 "{\"1\":{\"rec\":{\"1\":{\"i32\":31337},\"2\":{\"str\":\"I am a bonk... xor"
92 "!\"}}},\"2\":{\"rec\":{\"1\":{\"tf\":1},\"2\":{\"tf\":0},\"3\":{\"i8\":127"
93 "},\"4\":{\"i16\":16},\"5\":{\"i32\":32},\"6\":{\"i64\":64},\"7\":{\"dbl\":"
94 "1.618033988749895},\"8\":{\"str\":\":R (me going \\\"rrrr\\\")\"},\"9\":{"
95 "\"str\":\"ӀⅮΝ Нοⅿоɡгаρℎ Αttαⅽκǃ‼\"},\"10\":{\"tf\":0},\"11\":{\"str\":\""
96 "AQIDrQ\"},\"12\":{\"lst\":[\"i8\",3,1,2,3]},\"13\":{\"lst\":[\"i16\",3,1,2"
97 ",3]},\"14\":{\"lst\":[\"i64\",3,1,2,3]}}}}"
98 );
99
100 const std::string result(apache::thrift::ThriftJSONString(*n));
101
102 BOOST_CHECK_MESSAGE(!expected_result.compare(result),
103 "Expected:\n" << expected_result << "\nGotten:\n" << result);
104}
105
106static std::auto_ptr<HolyMoley> hm;
107
108void testCaseSetup_3() {
109 testCaseSetup_2();
110
111 hm.reset(new HolyMoley);
112
113 hm->big.push_back(*ooe);
114 hm->big.push_back(n->my_ooe);
115 hm->big[0].a_bite = 0x22;
116 hm->big[1].a_bite = 0x33;
David Reissdb0ea152008-02-18 01:49:37 +0000117
118 std::vector<std::string> stage1;
119 stage1.push_back("and a one");
120 stage1.push_back("and a two");
Claudius Heine5ef662b2015-06-24 10:03:50 +0200121 hm->contain.insert(stage1);
David Reissdb0ea152008-02-18 01:49:37 +0000122 stage1.clear();
123 stage1.push_back("then a one, two");
124 stage1.push_back("three!");
125 stage1.push_back("FOUR!!");
Claudius Heine5ef662b2015-06-24 10:03:50 +0200126 hm->contain.insert(stage1);
David Reissdb0ea152008-02-18 01:49:37 +0000127 stage1.clear();
Claudius Heine5ef662b2015-06-24 10:03:50 +0200128 hm->contain.insert(stage1);
David Reissdb0ea152008-02-18 01:49:37 +0000129
130 std::vector<Bonk> stage2;
Claudius Heine5ef662b2015-06-24 10:03:50 +0200131 hm->bonks["nothing"] = stage2;
Konrad Grochowski16a23a62014-11-13 15:33:38 +0100132 stage2.resize(stage2.size() + 1);
David Reissdb0ea152008-02-18 01:49:37 +0000133 stage2.back().type = 1;
134 stage2.back().message = "Wait.";
Konrad Grochowski16a23a62014-11-13 15:33:38 +0100135 stage2.resize(stage2.size() + 1);
David Reissdb0ea152008-02-18 01:49:37 +0000136 stage2.back().type = 2;
137 stage2.back().message = "What?";
Claudius Heine5ef662b2015-06-24 10:03:50 +0200138 hm->bonks["something"] = stage2;
David Reissdb0ea152008-02-18 01:49:37 +0000139 stage2.clear();
Konrad Grochowski16a23a62014-11-13 15:33:38 +0100140 stage2.resize(stage2.size() + 1);
David Reissdb0ea152008-02-18 01:49:37 +0000141 stage2.back().type = 3;
142 stage2.back().message = "quoth";
Konrad Grochowski16a23a62014-11-13 15:33:38 +0100143 stage2.resize(stage2.size() + 1);
David Reissdb0ea152008-02-18 01:49:37 +0000144 stage2.back().type = 4;
145 stage2.back().message = "the raven";
Konrad Grochowski16a23a62014-11-13 15:33:38 +0100146 stage2.resize(stage2.size() + 1);
David Reissdb0ea152008-02-18 01:49:37 +0000147 stage2.back().type = 5;
148 stage2.back().message = "nevermore";
Claudius Heine5ef662b2015-06-24 10:03:50 +0200149 hm->bonks["poe"] = stage2;
150}
David Reissdb0ea152008-02-18 01:49:37 +0000151
Claudius Heine5ef662b2015-06-24 10:03:50 +0200152BOOST_AUTO_TEST_CASE(test_json_proto_3) {
153 testCaseSetup_3();
154
155 const std::string expected_result(
156 "{\"1\":{\"lst\":[\"rec\",2,{\"1\":{\"tf\":1},\"2\":{\"tf\":0},\"3\":{\"i8\":"
157 "34},\"4\":{\"i16\":27000},\"5\":{\"i32\":16777216},\"6\":{\"i64\":6000000000"
158 "},\"7\":{\"dbl\":3.141592653589793},\"8\":{\"str\":\"JSON THIS! \\\"\\u0001"
159 "\"},\"9\":{\"str\":\"\xd7\\n\\u0007\\t\"},\"10\":{\"tf\":0},\"11\":{\"str\":"
160 "\"AQIDrQ\"},\"12\":{\"lst\":[\"i8\",3,1,2,3]},\"13\":{\"lst\":[\"i16\",3,1,2"
161 ",3]},\"14\":{\"lst\":[\"i64\",3,1,2,3]}},{\"1\":{\"tf\":1},\"2\":{\"tf\":0},"
162 "\"3\":{\"i8\":51},\"4\":{\"i16\":16},\"5\":{\"i32\":32},\"6\":{\"i64\":64},"
163 "\"7\":{\"dbl\":1.618033988749895},\"8\":{\"str\":\":R (me going \\\"rrrr\\\""
164 ")\"},\"9\":{\"str\":\"ӀⅮΝ Нοⅿоɡгаρℎ Αttαⅽκǃ‼\"},\"10\":{\"tf\":0},\"11\":{"
165 "\"str\":\"AQIDrQ\"},\"12\":{\"lst\":[\"i8\",3,1,2,3]},\"13\":{\"lst\":[\"i16"
166 "\",3,1,2,3]},\"14\":{\"lst\":[\"i64\",3,1,2,3]}}]},\"2\":{\"set\":[\"lst\",3"
167 ",[\"str\",0],[\"str\",2,\"and a one\",\"and a two\"],[\"str\",3,\"then a one"
168 ", two\",\"three!\",\"FOUR!!\"]]},\"3\":{\"map\":[\"str\",\"lst\",3,{\"nothin"
169 "g\":[\"rec\",0],\"poe\":[\"rec\",3,{\"1\":{\"i32\":3},\"2\":{\"str\":\"quoth"
170 "\"}},{\"1\":{\"i32\":4},\"2\":{\"str\":\"the raven\"}},{\"1\":{\"i32\":5},\""
171 "2\":{\"str\":\"nevermore\"}}],\"something\":[\"rec\",2,{\"1\":{\"i32\":1},\""
172 "2\":{\"str\":\"Wait.\"}},{\"1\":{\"i32\":2},\"2\":{\"str\":\"What?\"}}]}]}}"
173 );
174
175 const std::string result(apache::thrift::ThriftJSONString(*hm));
176
177 BOOST_CHECK_MESSAGE(!expected_result.compare(result),
178 "Expected:\n" << expected_result << "\nGotten:\n" << result);
179}
180
181BOOST_AUTO_TEST_CASE(test_json_proto_4) {
182 testCaseSetup_1();
David Reissdb0ea152008-02-18 01:49:37 +0000183
184 boost::shared_ptr<TMemoryBuffer> buffer(new TMemoryBuffer());
185 boost::shared_ptr<TJSONProtocol> proto(new TJSONProtocol(buffer));
186
Claudius Heine5ef662b2015-06-24 10:03:50 +0200187 ooe->write(proto.get());
David Reissdb0ea152008-02-18 01:49:37 +0000188 OneOfEach ooe2;
189 ooe2.read(proto.get());
190
Claudius Heine5ef662b2015-06-24 10:03:50 +0200191 BOOST_CHECK(*ooe == ooe2);
192}
David Reissdb0ea152008-02-18 01:49:37 +0000193
Claudius Heine5ef662b2015-06-24 10:03:50 +0200194BOOST_AUTO_TEST_CASE(test_json_proto_5) {
195 testCaseSetup_3();
David Reissdb0ea152008-02-18 01:49:37 +0000196
Claudius Heine5ef662b2015-06-24 10:03:50 +0200197 boost::shared_ptr<TMemoryBuffer> buffer(new TMemoryBuffer());
198 boost::shared_ptr<TJSONProtocol> proto(new TJSONProtocol(buffer));
199
200 hm->write(proto.get());
David Reissdb0ea152008-02-18 01:49:37 +0000201 HolyMoley hm2;
202 hm2.read(proto.get());
203
Claudius Heine5ef662b2015-06-24 10:03:50 +0200204 BOOST_CHECK(*hm == hm2);
David Reissdb0ea152008-02-18 01:49:37 +0000205
Christian Lavoiecbf87cb2010-11-28 14:34:26 +0000206 hm2.big[0].a_bite = 0x00;
David Reiss4a8f46c2008-03-07 20:12:07 +0000207
Claudius Heine5ef662b2015-06-24 10:03:50 +0200208 BOOST_CHECK(*hm != hm2);
209}
David Reiss4a8f46c2008-03-07 20:12:07 +0000210
Claudius Heine5ef662b2015-06-24 10:03:50 +0200211BOOST_AUTO_TEST_CASE(test_json_proto_6) {
David Reissdb0ea152008-02-18 01:49:37 +0000212 Doubles dub;
Konrad Grochowski16a23a62014-11-13 15:33:38 +0100213 dub.nan = HUGE_VAL / HUGE_VAL;
David Reissdb0ea152008-02-18 01:49:37 +0000214 dub.inf = HUGE_VAL;
215 dub.neginf = -HUGE_VAL;
Konrad Grochowski16a23a62014-11-13 15:33:38 +0100216 dub.repeating = 10.0 / 3.0;
David Reissdb0ea152008-02-18 01:49:37 +0000217 dub.big = 1E+305;
Roger Meier22888ce2014-02-09 11:31:02 +0100218 dub.tiny = 1E-305;
David Reissdb0ea152008-02-18 01:49:37 +0000219 dub.zero = 0.0;
220 dub.negzero = -0.0;
David Reissdb0ea152008-02-18 01:49:37 +0000221
Claudius Heine5ef662b2015-06-24 10:03:50 +0200222 const std::string expected_result(
223 "{\"1\":{\"dbl\":\"NaN\"},\"2\":{\"dbl\":\"Infinity\"},\"3\":{\"dbl\":\"-Infi"
224 "nity\"},\"4\":{\"dbl\":3.333333333333333},\"5\":{\"dbl\":9.999999999999999e+"
225 "304},\"6\":{\"dbl\":1e-305},\"7\":{\"dbl\":0},\"8\":{\"dbl\":-0}}"
226 );
227
228 const std::string result(apache::thrift::ThriftJSONString(dub));
229
230 BOOST_CHECK_MESSAGE(!expected_result.compare(result),
231 "Expected:\n" << expected_result << "\nGotten:\n" << result);
232}
233
234BOOST_AUTO_TEST_CASE(test_json_proto_7) {
235 boost::shared_ptr<TMemoryBuffer> buffer(new TMemoryBuffer());
236 boost::shared_ptr<TJSONProtocol> proto(new TJSONProtocol(buffer));
David Reiss4a8f46c2008-03-07 20:12:07 +0000237
238 Base64 base;
239 base.a = 123;
240 base.b1 = "1";
241 base.b2 = "12";
242 base.b3 = "123";
243 base.b4 = "1234";
244 base.b5 = "12345";
245 base.b6 = "123456";
246
247 base.write(proto.get());
248 Base64 base2;
249 base2.read(proto.get());
250
Claudius Heine5ef662b2015-06-24 10:03:50 +0200251 BOOST_CHECK(base == base2);
David Reissdb0ea152008-02-18 01:49:37 +0000252}