1 #include "../json/reflector-boosthana.h"
2 #include "../json/serializable.h"
4 #include <c++utilities/conversion/stringbuilder.h>
5 #include <c++utilities/conversion/stringconversion.h>
6 #include <c++utilities/io/misc.h>
7 #include <c++utilities/tests/testutils.h>
9 using CppUtilities::operator<<;
10 #include <cppunit/TestFixture.h>
11 #include <cppunit/extensions/HelperMacros.h>
13 #include <rapidjson/document.h>
14 #include <rapidjson/stringbuffer.h>
15 #include <rapidjson/writer.h>
22 using namespace CPPUNIT_NS;
23 using namespace RAPIDJSON_NAMESPACE;
24 using namespace CppUtilities;
25 using namespace CppUtilities::Literals;
32 BOOST_HANA_DEFINE_STRUCT(TestObjectHana, (
int, number), (
double, number2), (vector<int>, numbers), (
string, text), (
bool,
boolean));
36 BOOST_HANA_DEFINE_STRUCT(NestingObjectHana, (
string, name), (TestObjectHana, testObj));
40 BOOST_HANA_DEFINE_STRUCT(NestingArrayHana, (
string, name), (vector<TestObjectHana>, testObjects));
51 CPPUNIT_TEST(testSerializeSimpleObjects);
52 CPPUNIT_TEST(testSerializeNestedObjects);
53 CPPUNIT_TEST(testDeserializeSimpleObjects);
54 CPPUNIT_TEST(testDeserializeNestedObjects);
55 CPPUNIT_TEST(testHandlingTypeMismatch);
56 CPPUNIT_TEST_SUITE_END();
59 void setUp()
override;
60 void tearDown()
override;
63 void testSerializeSimpleObjects();
64 void testSerializeNestedObjects();
66 void testDeserializeSimpleObjects();
67 void testDeserializeNestedObjects();
68 void testHandlingTypeMismatch();
88 TestObjectHana testObj;
90 testObj.number2 = 3.141592653589793;
91 testObj.numbers = { 1, 2, 3, 4 };
92 testObj.text =
"test";
93 testObj.boolean =
false;
94 CPPUNIT_ASSERT_EQUAL(
"{\"number\":42,\"number2\":3.141592653589793,\"numbers\":[1,2,3,4],\"text\":\"test\",\"boolean\":false}"s,
95 string(testObj.toJson().GetString()));
103 NestingObjectHana nestingObj;
104 nestingObj.name =
"nesting";
105 TestObjectHana &testObj = nestingObj.testObj;
107 testObj.number2 = 3.141592653589793;
108 testObj.numbers = { 1, 2, 3, 4 };
109 testObj.text =
"test";
110 testObj.boolean =
false;
111 CPPUNIT_ASSERT_EQUAL(
112 "{\"name\":\"nesting\",\"testObj\":{\"number\":42,\"number2\":3.141592653589793,\"numbers\":[1,2,3,4],\"text\":\"test\",\"boolean\":false}}"s,
113 string(nestingObj.toJson().GetString()));
114 NestingArrayHana nestingArray;
115 nestingArray.name =
"nesting2";
116 nestingArray.testObjects.emplace_back(testObj);
117 nestingArray.testObjects.emplace_back(testObj);
118 nestingArray.testObjects.back().number = 43;
119 CPPUNIT_ASSERT_EQUAL(
120 "{\"name\":\"nesting2\",\"testObjects\":[{\"number\":42,\"number2\":3.141592653589793,\"numbers\":[1,2,3,4],\"text\":\"test\",\"boolean\":false},{\"number\":43,\"number2\":3.141592653589793,\"numbers\":[1,2,3,4],\"text\":\"test\",\"boolean\":false}]}"s,
121 string(nestingArray.toJson().GetString()));
129 const TestObjectHana testObj(
130 TestObjectHana::fromJson(
"{\"number\":42,\"number2\":3.141592653589793,\"numbers\":[1,2,3,4],\"text\":\"test\",\"boolean\":false}"));
132 CPPUNIT_ASSERT_EQUAL(42, testObj.number);
133 CPPUNIT_ASSERT_EQUAL(3.141592653589793, testObj.number2);
134 CPPUNIT_ASSERT_EQUAL(vector<int>({ 1, 2, 3, 4 }), testObj.numbers);
135 CPPUNIT_ASSERT_EQUAL(
"test"s, testObj.text);
136 CPPUNIT_ASSERT_EQUAL(
false, testObj.boolean);
144 const NestingObjectHana nestingObj(
NestingObjectHana::fromJson(
"{\"name\":\"nesting\",\"testObj\":{\"number\":42,\"number2\":3.141592653589793,"
145 "\"numbers\":[1,2,3,4],\"text\":\"test\",\"boolean\":false}}"));
146 const TestObjectHana &testObj = nestingObj.testObj;
147 CPPUNIT_ASSERT_EQUAL(
"nesting"s, nestingObj.name);
148 CPPUNIT_ASSERT_EQUAL(42, testObj.number);
149 CPPUNIT_ASSERT_EQUAL(3.141592653589793, testObj.number2);
150 CPPUNIT_ASSERT_EQUAL(vector<int>({ 1, 2, 3, 4 }), testObj.numbers);
151 CPPUNIT_ASSERT_EQUAL(
"test"s, testObj.text);
152 CPPUNIT_ASSERT_EQUAL(
false, testObj.boolean);
154 const NestingArrayHana nestingArray(
156 "\"numbers\":[1,2,3,4],\"text\":\"test\",\"boolean\":false},{\"number\":43,\"number2\":3."
157 "141592653589793,\"numbers\":[1,2,3,4],\"text\":\"test\",\"boolean\":false}]}"));
158 const vector<TestObjectHana> &testObjects = nestingArray.testObjects;
159 CPPUNIT_ASSERT_EQUAL(
"nesting2"s, nestingArray.name);
160 CPPUNIT_ASSERT_EQUAL(2_st, testObjects.size());
161 CPPUNIT_ASSERT_EQUAL(42, testObjects[0].number);
162 CPPUNIT_ASSERT_EQUAL(43, testObjects[1].number);
163 for (
const TestObjectHana &testObj : testObjects) {
164 CPPUNIT_ASSERT_EQUAL(3.141592653589793, testObj.number2);
165 CPPUNIT_ASSERT_EQUAL(vector<int>({ 1, 2, 3, 4 }), testObj.numbers);
166 CPPUNIT_ASSERT_EQUAL(
"test"s, testObj.text);
167 CPPUNIT_ASSERT_EQUAL(
false, testObj.boolean);
178 "\"numbers\":[1,2,3,4],\"text\":\"test\",\"boolean\":false},{\"number\":43,\"number2\":3."
179 "141592653589793,\"numbers\":[1,2,3,4],\"text\":\"test\",\"boolean\":false}]}",
181 CPPUNIT_ASSERT_EQUAL(0_st, errors.size());
183 NestingObjectHana::fromJson(
"{\"name\":\"nesting\",\"testObj\":{\"number\":\"42\",\"number2\":3.141592653589793,\"numbers\":[1,2,3,4],\"text\":"
184 "\"test\",\"boolean\":false}}",
186 CPPUNIT_ASSERT_EQUAL(1_st, errors.size());
187 CPPUNIT_ASSERT_EQUAL(JsonDeserializationErrorKind::TypeMismatch, errors.front().kind);
188 CPPUNIT_ASSERT_EQUAL(JsonType::Number, errors.front().expectedType);
189 CPPUNIT_ASSERT_EQUAL(JsonType::String, errors.front().actualType);
190 CPPUNIT_ASSERT_EQUAL(
"number"s,
string(errors.front().member));
191 CPPUNIT_ASSERT_EQUAL(
"[document]"s,
string(errors.front().record));
194 NestingObjectHana::fromJson(
"{\"name\":\"nesting\",\"testObj\":{\"number\":42,\"number2\":3.141592653589793,\"numbers\":1,\"text\":"
195 "\"test\",\"boolean\":false}}",
197 CPPUNIT_ASSERT_EQUAL(1_st, errors.size());
198 CPPUNIT_ASSERT_EQUAL(JsonDeserializationErrorKind::TypeMismatch, errors.front().kind);
199 CPPUNIT_ASSERT_EQUAL(JsonType::Array, errors.front().expectedType);
200 CPPUNIT_ASSERT_EQUAL(JsonType::Number, errors.front().actualType);
201 CPPUNIT_ASSERT_EQUAL(
"numbers"s,
string(errors.front().member));
202 CPPUNIT_ASSERT_EQUAL(
"[document]"s,
string(errors.front().record));
206 CPPUNIT_ASSERT_EQUAL(2_st, errors.size());
207 CPPUNIT_ASSERT_EQUAL(JsonDeserializationErrorKind::TypeMismatch, errors.front().kind);
208 CPPUNIT_ASSERT_EQUAL(JsonType::String, errors.front().expectedType);
209 CPPUNIT_ASSERT_EQUAL(JsonType::Array, errors.front().actualType);
210 CPPUNIT_ASSERT_EQUAL(
"name"s,
string(errors.front().member));
211 CPPUNIT_ASSERT_EQUAL(
"[document]"s,
string(errors.front().record));
212 CPPUNIT_ASSERT_EQUAL(JsonDeserializationErrorKind::TypeMismatch, errors.back().kind);
213 CPPUNIT_ASSERT_EQUAL(JsonType::Object, errors.back().expectedType);
214 CPPUNIT_ASSERT_EQUAL(JsonType::String, errors.back().actualType);
215 CPPUNIT_ASSERT_EQUAL(
"testObj"s,
string(errors.back().member));
216 CPPUNIT_ASSERT_EQUAL(
"[document]"s,
string(errors.back().record));
219 const NestingArrayHana nestingArray(
221 "\"numbers\":[1,2,3,4],\"text\":\"test\",\"boolean\":false},\"foo\",{\"number\":43,\"number2\":3."
222 "141592653589793,\"numbers\":[1,2,3,4,\"bar\"],\"text\":\"test\",\"boolean\":false}]}",
224 CPPUNIT_ASSERT_EQUAL(3_st, errors.size());
225 CPPUNIT_ASSERT_EQUAL(JsonDeserializationErrorKind::TypeMismatch, errors[0].kind);
226 CPPUNIT_ASSERT_EQUAL(JsonType::Object, errors[0].expectedType);
227 CPPUNIT_ASSERT_EQUAL(JsonType::Number, errors[0].actualType);
228 CPPUNIT_ASSERT_EQUAL(
"testObjects"s,
string(errors[0].member));
229 CPPUNIT_ASSERT_EQUAL(
"[document]"s,
string(errors[0].record));
230 CPPUNIT_ASSERT_EQUAL(0_st, errors[0].index);
231 CPPUNIT_ASSERT_EQUAL(JsonDeserializationErrorKind::TypeMismatch, errors[1].kind);
232 CPPUNIT_ASSERT_EQUAL(JsonType::Object, errors[1].expectedType);
233 CPPUNIT_ASSERT_EQUAL(JsonType::String, errors[1].actualType);
234 CPPUNIT_ASSERT_EQUAL(2_st, errors[1].index);
235 CPPUNIT_ASSERT_EQUAL(
"testObjects"s,
string(errors[1].member));
236 CPPUNIT_ASSERT_EQUAL(
"[document]"s,
string(errors[1].record));
237 CPPUNIT_ASSERT_EQUAL(JsonDeserializationErrorKind::TypeMismatch, errors[2].kind);
238 CPPUNIT_ASSERT_EQUAL(JsonType::Number, errors[2].expectedType);
239 CPPUNIT_ASSERT_EQUAL(JsonType::String, errors[2].actualType);
240 CPPUNIT_ASSERT_EQUAL(
"numbers"s,
string(errors[2].member));
241 CPPUNIT_ASSERT_EQUAL(
"[document]"s,
string(errors[2].record));
242 CPPUNIT_ASSERT_EQUAL(4_st, errors[2].index);
245 errors.
throwOn = JsonDeserializationErrors::ThrowOn::TypeMismatch;