1 /**
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, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
17 */
18
19 #include <limits>
20
21 #include <boost/test/included/unit_test_framework.hpp>
22 #include <boost/test/unit_test.hpp>
23 #include <boost/test/parameterized_test.hpp>
24
25 #include "../impl/json/JsonDom.hh"
26
27 #define S(x) #x
28
29 namespace internal_avro {
30 namespace json {
31
32 template <typename T>
33 struct TestData {
34 const char* input;
35 EntityType type;
36 T value;
37 };
38
39 TestData<bool> boolData[] = {{"true", etBool, true},
40 {"false", etBool, false}, };
41
42 TestData<int64_t> longData[] = {
43 {"0", etLong, 0},
44 {"-1", etLong, -1},
45 {"1", etLong, 1},
46 {"9223372036854775807", etLong, 9223372036854775807LL},
47 {"-9223372036854775807", etLong, -9223372036854775807LL}, };
48
49 TestData<double> doubleData[] = {{"0.0", etDouble, 0.0},
50 {"-1.0", etDouble, -1.0},
51 {"1.0", etDouble, 1.0},
52 {"4.7e3", etDouble, 4700.0},
53 {"-7.2e-4", etDouble, -0.00072}, };
54
55 TestData<const char*> stringData[] = {{"\"\"", etString, ""},
56 {"\"a\"", etString, "a"},
57 {"\"\\U000a\"", etString, "\n"},
58 {"\"\\u000a\"", etString, "\n"},
59 {"\"\\\"\"", etString, "\""},
60 {"\"\\/\"", etString, "/"}, };
61
62 template <typename T>
testPrimitive(const TestData<T> & d)63 void testPrimitive(const TestData<T>& d) {
64 Entity n = loadEntity(d.input);
65 BOOST_CHECK_EQUAL(n.type(), d.type);
66 BOOST_CHECK_EQUAL(n.value<T>(), d.value);
67 }
68
testDouble(const TestData<double> & d)69 void testDouble(const TestData<double>& d) {
70 Entity n = loadEntity(d.input);
71 BOOST_CHECK_EQUAL(n.type(), d.type);
72 BOOST_CHECK_CLOSE(n.value<double>(), d.value, 1e-10);
73 }
74
testString(const TestData<const char * > & d)75 void testString(const TestData<const char*>& d) {
76 Entity n = loadEntity(d.input);
77 BOOST_CHECK_EQUAL(n.type(), d.type);
78 BOOST_CHECK_EQUAL(n.value<std::string>(), d.value);
79 }
80
testNull()81 static void testNull() {
82 Entity n = loadEntity("null");
83 BOOST_CHECK_EQUAL(n.type(), etNull);
84 }
85
testArray0()86 static void testArray0() {
87 Entity n = loadEntity("[]");
88 BOOST_CHECK_EQUAL(n.type(), etArray);
89 const std::vector<Entity>& a = n.value<std::vector<Entity> >();
90 BOOST_CHECK_EQUAL(a.size(), 0);
91 }
92
testArray1()93 static void testArray1() {
94 Entity n = loadEntity("[200]");
95 BOOST_CHECK_EQUAL(n.type(), etArray);
96 const std::vector<Entity>& a = n.value<std::vector<Entity> >();
97 BOOST_CHECK_EQUAL(a.size(), 1);
98 BOOST_CHECK_EQUAL(a[0].type(), etLong);
99 BOOST_CHECK_EQUAL(a[0].value<int64_t>(), 200ll);
100 }
101
testArray2()102 static void testArray2() {
103 Entity n = loadEntity("[200, \"v100\"]");
104 BOOST_CHECK_EQUAL(n.type(), etArray);
105 const std::vector<Entity>& a = n.value<std::vector<Entity> >();
106 BOOST_CHECK_EQUAL(a.size(), 2);
107 BOOST_CHECK_EQUAL(a[0].type(), etLong);
108 BOOST_CHECK_EQUAL(a[0].value<int64_t>(), 200ll);
109 BOOST_CHECK_EQUAL(a[1].type(), etString);
110 BOOST_CHECK_EQUAL(a[1].value<std::string>(), "v100");
111 }
112
testObject0()113 static void testObject0() {
114 Entity n = loadEntity("{}");
115 BOOST_CHECK_EQUAL(n.type(), etObject);
116 const std::map<std::string, Entity>& m =
117 n.value<std::map<std::string, Entity> >();
118 BOOST_CHECK_EQUAL(m.size(), 0);
119 }
120
testObject1()121 static void testObject1() {
122 Entity n = loadEntity("{\"k1\": 100}");
123 BOOST_CHECK_EQUAL(n.type(), etObject);
124 const std::map<std::string, Entity>& m =
125 n.value<std::map<std::string, Entity> >();
126 BOOST_CHECK_EQUAL(m.size(), 1);
127 BOOST_CHECK_EQUAL(m.begin()->first, "k1");
128 BOOST_CHECK_EQUAL(m.begin()->second.type(), etLong);
129 BOOST_CHECK_EQUAL(m.begin()->second.value<int64_t>(), 100ll);
130 }
131
testObject2()132 static void testObject2() {
133 Entity n = loadEntity("{\"k1\": 100, \"k2\": [400, \"v0\"]}");
134 BOOST_CHECK_EQUAL(n.type(), etObject);
135 const std::map<std::string, Entity>& m =
136 n.value<std::map<std::string, Entity> >();
137 BOOST_CHECK_EQUAL(m.size(), 2);
138
139 std::map<std::string, Entity>::const_iterator it = m.find("k1");
140 BOOST_CHECK(it != m.end());
141 BOOST_CHECK_EQUAL(it->second.type(), etLong);
142 BOOST_CHECK_EQUAL(m.begin()->second.value<int64_t>(), 100ll);
143
144 it = m.find("k2");
145 BOOST_CHECK(it != m.end());
146 BOOST_CHECK_EQUAL(it->second.type(), etArray);
147 const std::vector<Entity>& a = it->second.value<std::vector<Entity> >();
148 BOOST_CHECK_EQUAL(a.size(), 2);
149 BOOST_CHECK_EQUAL(a[0].type(), etLong);
150 BOOST_CHECK_EQUAL(a[0].value<int64_t>(), 400ll);
151 BOOST_CHECK_EQUAL(a[1].type(), etString);
152 BOOST_CHECK_EQUAL(a[1].value<std::string>(), "v0");
153 }
154 }
155 }
156
157 #define COUNTOF(x) (sizeof(x) / sizeof(x[0]))
158
init_unit_test_suite(int argc,char * argv[])159 boost::unit_test::test_suite* init_unit_test_suite(int argc, char* argv[]) {
160 using namespace boost::unit_test;
161
162 test_suite* ts = BOOST_TEST_SUITE("Avro C++ unit tests for json routines");
163
164 ts->add(BOOST_TEST_CASE(&internal_avro::json::testNull));
165 ts->add(BOOST_PARAM_TEST_CASE(
166 &internal_avro::json::testPrimitive<bool>, internal_avro::json::boolData,
167 internal_avro::json::boolData + COUNTOF(internal_avro::json::boolData)));
168 ts->add(BOOST_PARAM_TEST_CASE(
169 &internal_avro::json::testPrimitive<int64_t>,
170 internal_avro::json::longData,
171 internal_avro::json::longData + COUNTOF(internal_avro::json::longData)));
172 ts->add(BOOST_PARAM_TEST_CASE(&internal_avro::json::testDouble,
173 internal_avro::json::doubleData,
174 internal_avro::json::doubleData +
175 COUNTOF(internal_avro::json::doubleData)));
176 ts->add(BOOST_PARAM_TEST_CASE(&internal_avro::json::testString,
177 internal_avro::json::stringData,
178 internal_avro::json::stringData +
179 COUNTOF(internal_avro::json::stringData)));
180
181 ts->add(BOOST_TEST_CASE(&internal_avro::json::testArray0));
182 ts->add(BOOST_TEST_CASE(&internal_avro::json::testArray1));
183 ts->add(BOOST_TEST_CASE(&internal_avro::json::testArray2));
184
185 ts->add(BOOST_TEST_CASE(&internal_avro::json::testObject0));
186 ts->add(BOOST_TEST_CASE(&internal_avro::json::testObject1));
187 ts->add(BOOST_TEST_CASE(&internal_avro::json::testObject2));
188
189 return ts;
190 }
191