1 #include "../json/reflector.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 TestUtilities::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> 21 #include <unordered_map> 56 map<string, int> someMap;
57 unordered_map<string, bool> someHash;
59 multiset<string> someMultiset;
60 unordered_set<string> someUnorderedSet;
61 unordered_multiset<string> someUnorderedMultiset;
71 vector<TestObject> testObjects;
80 enum class SomeEnumClass {
88 namespace JsonReflector {
90 template <>
inline void push<TestObject>(
const TestObject &reflectable, Value::Object &value, Document::AllocatorType &allocator)
92 push(reflectable.number,
"number", value, allocator);
93 push(reflectable.number2,
"number2", value, allocator);
94 push(reflectable.numbers,
"numbers", value, allocator);
95 push(reflectable.text,
"text", value, allocator);
96 push(reflectable.boolean,
"boolean", value, allocator);
97 push(reflectable.someMap,
"someMap", value, allocator);
98 push(reflectable.someHash,
"someHash", value, allocator);
99 push(reflectable.someSet,
"someSet", value, allocator);
100 push(reflectable.someMultiset,
"someMultiset", value, allocator);
101 push(reflectable.someUnorderedSet,
"someUnorderedSet", value, allocator);
102 push(reflectable.someUnorderedMultiset,
"someUnorderedMultiset", value, allocator);
105 template <>
inline void push<NestingObject>(
const NestingObject &reflectable, Value::Object &value, Document::AllocatorType &allocator)
107 push(reflectable.name,
"name", value, allocator);
108 push(reflectable.testObj,
"testObj", value, allocator);
111 template <>
inline void push<NestingArray>(
const NestingArray &reflectable, Value::Object &value, Document::AllocatorType &allocator)
113 push(reflectable.name,
"name", value, allocator);
114 push(reflectable.testObjects,
"testObjects", value, allocator);
118 inline void pull<TestObject>(TestObject &reflectable,
const GenericValue<UTF8<char>>::ConstObject &value,
JsonDeserializationErrors *errors)
120 const char *previousRecord;
122 previousRecord = errors->currentRecord;
123 errors->currentRecord =
"TestObject";
125 pull(reflectable.number,
"number", value, errors);
126 pull(reflectable.number2,
"number2", value, errors);
127 pull(reflectable.numbers,
"numbers", value, errors);
128 pull(reflectable.text,
"text", value, errors);
129 pull(reflectable.boolean,
"boolean", value, errors);
130 pull(reflectable.someMap,
"someMap", value, errors);
131 pull(reflectable.someHash,
"someHash", value, errors);
132 pull(reflectable.someSet,
"someSet", value, errors);
133 pull(reflectable.someMultiset,
"someMultiset", value, errors);
134 pull(reflectable.someUnorderedSet,
"someUnorderedSet", value, errors);
135 pull(reflectable.someUnorderedMultiset,
"someUnorderedMultiset", value, errors);
137 errors->currentRecord = previousRecord;
142 inline void pull<NestingObject>(NestingObject &reflectable,
const GenericValue<UTF8<char>>::ConstObject &value,
JsonDeserializationErrors *errors)
144 const char *previousRecord;
146 previousRecord = errors->currentRecord;
147 errors->currentRecord =
"NestingObject";
149 pull(reflectable.name,
"name", value, errors);
150 pull(reflectable.testObj,
"testObj", value, errors);
152 errors->currentRecord = previousRecord;
157 inline void pull<NestingArray>(NestingArray &reflectable,
const GenericValue<UTF8<char>>::ConstObject &value,
JsonDeserializationErrors *errors)
159 const char *previousRecord;
161 previousRecord = errors->currentRecord;
162 errors->currentRecord =
"NestingArray";
164 pull(reflectable.name,
"name", value, errors);
165 pull(reflectable.testObjects,
"testObjects", value, errors);
167 errors->currentRecord = previousRecord;
184 CPPUNIT_TEST(testSerializePrimitives);
185 CPPUNIT_TEST(testSerializeSimpleObjects);
186 CPPUNIT_TEST(testSerializeNestedObjects);
187 CPPUNIT_TEST(testSerializeUniquePtr);
188 CPPUNIT_TEST(testSerializeSharedPtr);
189 CPPUNIT_TEST(testDeserializePrimitives);
190 CPPUNIT_TEST(testDeserializeSimpleObjects);
191 CPPUNIT_TEST(testDeserializeNestedObjects);
192 CPPUNIT_TEST(testDeserializeUniquePtr);
193 CPPUNIT_TEST(testDeserializeSharedPtr);
194 CPPUNIT_TEST(testHandlingParseError);
195 CPPUNIT_TEST(testHandlingTypeMismatch);
196 CPPUNIT_TEST_SUITE_END();
203 void testSerializePrimitives();
204 void testSerializeSimpleObjects();
205 void testSerializeNestedObjects();
206 void testSerializeUniquePtr();
207 void testSerializeSharedPtr();
208 void testDeserializePrimitives();
209 void testDeserializeSimpleObjects();
210 void testDeserializeNestedObjects();
211 void testDeserializeUniquePtr();
212 void testDeserializeSharedPtr();
213 void testHandlingParseError();
214 void testHandlingTypeMismatch();
234 Document doc(kArrayType);
235 Document::AllocatorType &alloc = doc.GetAllocator();
237 Document::Array array(doc.GetArray());
240 const string foo(
"foo");
241 JsonReflector::push<string>(foo, array, alloc);
242 JsonReflector::push<const char *>(
"bar", array, alloc);
244 JsonReflector::push<int>(25, array, alloc);
245 JsonReflector::push<double>(12.5, array, alloc);
247 JsonReflector::push<SomeEnum>(SomeEnumItem2, array, alloc);
248 JsonReflector::push<SomeEnumClass>(SomeEnumClass::Item2, array, alloc);
249 JsonReflector::push<SomeEnumClass>(SomeEnumClass::Item3, array, alloc);
251 JsonReflector::push<vector<const char *>>({
"foo1",
"bar1" }, array, alloc);
252 JsonReflector::push<list<const char *>>({
"foo2",
"bar2" }, array, alloc);
253 JsonReflector::push<initializer_list<const char *>>({
"foo3",
"bar3" }, array, alloc);
254 JsonReflector::push<tuple<int, double>>(make_tuple(2, 413.0), array, alloc);
256 JsonReflector::push<bool>(
true, array, alloc);
257 JsonReflector::push<bool>(
false, array, alloc);
260 Writer<StringBuffer> jsonWriter(strbuf);
261 doc.Accept(jsonWriter);
262 CPPUNIT_ASSERT_EQUAL(
"[\"foo\",\"bar\",25,12.5,1,1,2,[\"foo1\",\"bar1\"],[\"foo2\",\"bar2\"],[\"foo3\",\"bar3\"],[2,413.0],true,false]"s,
263 string(strbuf.GetString()));
273 testObj.number2 = 3.141592653589793;
274 testObj.numbers = { 1, 2, 3, 4 };
275 testObj.text =
"test";
276 testObj.boolean =
false;
277 testObj.someMap = { {
"a", 1 }, {
"b", 2 } };
278 testObj.someHash = { {
"c",
true }, {
"d",
false } };
279 testObj.someSet = {
"a",
"b",
"c" };
280 testObj.someMultiset = {
"a",
"b",
"b" };
281 testObj.someUnorderedSet = {
"a" };
282 testObj.someUnorderedMultiset = {
"b",
"b",
"b" };
283 CPPUNIT_ASSERT_EQUAL(
284 "{\"number\":42,\"number2\":3.141592653589793,\"numbers\":[1,2,3,4],\"text\":\"test\",\"boolean\":false,\"someMap\":{\"a\":1,\"b\":2},\"someHash\":{\"d\":false,\"c\":true},\"someSet\":[\"a\",\"b\",\"c\"],\"someMultiset\":[\"a\",\"b\",\"b\"],\"someUnorderedSet\":[\"a\"],\"someUnorderedMultiset\":[\"b\",\"b\",\"b\"]}"s,
285 string(testObj.toJson().GetString()));
293 NestingObject nestingObj;
294 nestingObj.name =
"nesting";
295 TestObject &testObj = nestingObj.testObj;
297 testObj.number2 = 3.141592653589793;
298 testObj.numbers = { 1, 2, 3, 4 };
299 testObj.text =
"test";
300 testObj.boolean =
false;
301 CPPUNIT_ASSERT_EQUAL(
302 "{\"name\":\"nesting\",\"testObj\":{\"number\":42,\"number2\":3.141592653589793,\"numbers\":[1,2,3,4],\"text\":\"test\",\"boolean\":false,\"someMap\":{},\"someHash\":{},\"someSet\":[],\"someMultiset\":[],\"someUnorderedSet\":[],\"someUnorderedMultiset\":[]}}"s,
303 string(nestingObj.toJson().GetString()));
305 NestingArray nestingArray;
306 nestingArray.name =
"nesting2";
307 nestingArray.testObjects.emplace_back(testObj);
308 nestingArray.testObjects.emplace_back(testObj);
309 nestingArray.testObjects.back().number = 43;
310 CPPUNIT_ASSERT_EQUAL(
311 "{\"name\":\"nesting2\",\"testObjects\":[{\"number\":42,\"number2\":3.141592653589793,\"numbers\":[1,2,3,4],\"text\":\"test\",\"boolean\":false,\"someMap\":{},\"someHash\":{},\"someSet\":[],\"someMultiset\":[],\"someUnorderedSet\":[],\"someUnorderedMultiset\":[]},{\"number\":43,\"number2\":3.141592653589793,\"numbers\":[1,2,3,4],\"text\":\"test\",\"boolean\":false,\"someMap\":{},\"someHash\":{},\"someSet\":[],\"someMultiset\":[],\"someUnorderedSet\":[],\"someUnorderedMultiset\":[]}]}"s,
312 string(nestingArray.toJson().GetString()));
314 vector<TestObject> nestedInVector;
315 nestedInVector.emplace_back(testObj);
316 CPPUNIT_ASSERT_EQUAL(
317 "[{\"number\":42,\"number2\":3.141592653589793,\"numbers\":[1,2,3,4],\"text\":\"test\",\"boolean\":false,\"someMap\":{},\"someHash\":{},\"someSet\":[],\"someMultiset\":[],\"someUnorderedSet\":[],\"someUnorderedMultiset\":[]}]"s,
323 Document doc(kArrayType);
324 Document::AllocatorType &alloc = doc.GetAllocator();
326 Document::Array array(doc.GetArray());
328 const auto str = make_unique<string>(
"foo");
329 std::unique_ptr<string> nullStr;
330 const auto obj = make_unique<TestObject>();
332 obj->number2 = 3.141592653589793;
333 obj->numbers = { 1, 2, 3, 4 };
335 obj->boolean =
false;
342 Writer<StringBuffer> jsonWriter(strbuf);
343 doc.Accept(jsonWriter);
344 CPPUNIT_ASSERT_EQUAL(
345 "[\"foo\",null,{\"number\":42,\"number2\":3.141592653589793,\"numbers\":[1,2,3,4],\"text\":\"bar\",\"boolean\":false,\"someMap\":{},\"someHash\":{},\"someSet\":[],\"someMultiset\":[],\"someUnorderedSet\":[],\"someUnorderedMultiset\":[]}]"s,
346 string(strbuf.GetString()));
351 Document doc(kArrayType);
352 Document::AllocatorType &alloc = doc.GetAllocator();
354 Document::Array array(doc.GetArray());
356 const auto str = make_shared<string>(
"foo");
357 std::unique_ptr<string> nullStr;
358 const auto obj = make_shared<TestObject>();
360 obj->number2 = 3.141592653589793;
361 obj->numbers = { 1, 2, 3, 4 };
363 obj->boolean =
false;
370 Writer<StringBuffer> jsonWriter(strbuf);
371 doc.Accept(jsonWriter);
372 CPPUNIT_ASSERT_EQUAL(
373 "[\"foo\",null,{\"number\":42,\"number2\":3.141592653589793,\"numbers\":[1,2,3,4],\"text\":\"bar\",\"boolean\":false,\"someMap\":{},\"someHash\":{},\"someSet\":[],\"someMultiset\":[],\"someUnorderedSet\":[],\"someUnorderedMultiset\":[]}]"s,
374 string(strbuf.GetString()));
382 Document doc(kArrayType);
384 doc.Parse(
"[\"a\", 5, 5.0, 5e6, 4, \"test\", true, 4.125, false]");
385 auto array = doc.GetArray().begin();
388 int int1 = 0, int2 = 0;
389 bool bool1 =
false, bool2 =
true;
390 float float1 = 0.0f, float2 = 0.0f;
391 double double1 = 0.0;
403 CPPUNIT_ASSERT_EQUAL(0_st, errors.size());
404 CPPUNIT_ASSERT_EQUAL(
"a"s, str1);
405 CPPUNIT_ASSERT_EQUAL(5, int1);
406 CPPUNIT_ASSERT_EQUAL(5, int2);
407 CPPUNIT_ASSERT_EQUAL(5e6f, float1);
408 CPPUNIT_ASSERT_EQUAL(4.f, float2);
409 CPPUNIT_ASSERT_EQUAL(
"test"s, str2);
410 CPPUNIT_ASSERT_EQUAL(
true, bool1);
411 CPPUNIT_ASSERT_EQUAL(4.125, double1);
412 CPPUNIT_ASSERT_EQUAL(
false, bool2);
415 tuple<string, int, int, float, float, string, bool, double, bool> arrayAsTuple;
417 CPPUNIT_ASSERT_EQUAL(0_st, errors.size());
418 CPPUNIT_ASSERT_EQUAL(
"a"s, get<0>(arrayAsTuple));
419 CPPUNIT_ASSERT_EQUAL(5, get<1>(arrayAsTuple));
420 CPPUNIT_ASSERT_EQUAL(5, get<2>(arrayAsTuple));
421 CPPUNIT_ASSERT_EQUAL(5e6f, get<3>(arrayAsTuple));
422 CPPUNIT_ASSERT_EQUAL(4.f, get<4>(arrayAsTuple));
423 CPPUNIT_ASSERT_EQUAL(
"test"s, get<5>(arrayAsTuple));
424 CPPUNIT_ASSERT_EQUAL(
true, get<6>(arrayAsTuple));
425 CPPUNIT_ASSERT_EQUAL(4.125, get<7>(arrayAsTuple));
426 CPPUNIT_ASSERT_EQUAL(
false, get<8>(arrayAsTuple));
427 tuple<string, int> anotherTuple;
429 CPPUNIT_ASSERT_EQUAL(1_st, errors.size());
430 CPPUNIT_ASSERT_EQUAL(JsonDeserializationErrorKind::ArraySizeMismatch, errors.front().kind);
438 const TestObject testObj(
439 TestObject::fromJson(
"{\"number\":42,\"number2\":3.141592653589793,\"numbers\":[1,2,3,4],\"text\":\"test\",\"boolean\":" 440 "false,\"someMap\":{\"a\":1,\"b\":2},\"someHash\":{\"c\":true,\"d\":false},\"someSet\":[\"a\",\"b\"],\"someMultiset\":[" 441 "\"a\",\"a\"],\"someUnorderedSet\":[\"a\",\"b\"],\"someUnorderedMultiset\":[\"a\",\"a\"]}"));
443 CPPUNIT_ASSERT_EQUAL(42, testObj.number);
444 CPPUNIT_ASSERT_EQUAL(3.141592653589793, testObj.number2);
445 CPPUNIT_ASSERT_EQUAL(vector<int>({ 1, 2, 3, 4 }), testObj.numbers);
446 CPPUNIT_ASSERT_EQUAL(
"test"s, testObj.text);
447 CPPUNIT_ASSERT_EQUAL(
false, testObj.boolean);
448 const map<string, int> expectedMap{ {
"a", 1 }, {
"b", 2 } };
449 CPPUNIT_ASSERT_EQUAL(expectedMap, testObj.someMap);
450 const unordered_map<string, bool> expectedHash{ {
"c",
true }, {
"d",
false } };
451 CPPUNIT_ASSERT_EQUAL(expectedHash, testObj.someHash);
452 CPPUNIT_ASSERT_EQUAL(set<string>({
"a",
"b" }), testObj.someSet);
453 CPPUNIT_ASSERT_EQUAL(multiset<string>({
"a",
"a" }), testObj.someMultiset);
454 CPPUNIT_ASSERT_EQUAL(unordered_set<string>({
"a",
"b" }), testObj.someUnorderedSet);
455 CPPUNIT_ASSERT_EQUAL(unordered_multiset<string>({
"a",
"a" }), testObj.someUnorderedMultiset);
464 const NestingObject nestingObj(
NestingObject::fromJson(
"{\"name\":\"nesting\",\"testObj\":{\"number\":42,\"number2\":3.141592653589793," 465 "\"numbers\":[1,2,3,4],\"text\":\"test\",\"boolean\":false}}",
467 const TestObject &testObj = nestingObj.testObj;
468 CPPUNIT_ASSERT_EQUAL(0_st, errors.size());
469 CPPUNIT_ASSERT_EQUAL(
"nesting"s, nestingObj.name);
470 CPPUNIT_ASSERT_EQUAL(42, testObj.number);
471 CPPUNIT_ASSERT_EQUAL(3.141592653589793, testObj.number2);
472 CPPUNIT_ASSERT_EQUAL(vector<int>({ 1, 2, 3, 4 }), testObj.numbers);
473 CPPUNIT_ASSERT_EQUAL(
"test"s, testObj.text);
474 CPPUNIT_ASSERT_EQUAL(
false, testObj.boolean);
476 const NestingArray nestingArray(
NestingArray::fromJson(
"{\"name\":\"nesting2\",\"testObjects\":[{\"number\":42,\"number2\":3.141592653589793," 477 "\"numbers\":[1,2,3,4],\"text\":\"test\",\"boolean\":false},{\"number\":43,\"number2\":3." 478 "141592653589793,\"numbers\":[1,2,3,4],\"text\":\"test\",\"boolean\":false}]}",
480 const vector<TestObject> &testObjects = nestingArray.testObjects;
481 CPPUNIT_ASSERT_EQUAL(0_st, errors.size());
482 CPPUNIT_ASSERT_EQUAL(
"nesting2"s, nestingArray.name);
483 CPPUNIT_ASSERT_EQUAL(2_st, testObjects.size());
484 CPPUNIT_ASSERT_EQUAL(42, testObjects[0].number);
485 CPPUNIT_ASSERT_EQUAL(43, testObjects[1].number);
486 for (
const TestObject &testObj : testObjects) {
487 CPPUNIT_ASSERT_EQUAL(3.141592653589793, testObj.number2);
488 CPPUNIT_ASSERT_EQUAL(vector<int>({ 1, 2, 3, 4 }), testObj.numbers);
489 CPPUNIT_ASSERT_EQUAL(
"test"s, testObj.text);
490 CPPUNIT_ASSERT_EQUAL(
false, testObj.boolean);
494 "[{\"number\":42,\"number2\":3.141592653589793,\"numbers\":[1,2,3,4],\"text\":\"test\",\"boolean\":false,\"someMap\":{},\"someHash\":{}}]",
496 CPPUNIT_ASSERT_EQUAL(0_st, errors.size());
497 CPPUNIT_ASSERT_EQUAL(1_st, nestedInVector.size());
498 CPPUNIT_ASSERT_EQUAL(42, nestedInVector[0].number);
499 CPPUNIT_ASSERT_EQUAL(4_st, nestedInVector[0].numbers.size());
500 CPPUNIT_ASSERT_EQUAL(
"test"s, nestedInVector[0].text);
505 Document doc(kArrayType);
506 doc.Parse(
"[\"foo\",null,{\"text\":\"bar\"}]");
507 auto array = doc.GetArray().begin();
509 unique_ptr<string> str;
510 unique_ptr<string> nullStr;
511 unique_ptr<TestObject> obj;
517 CPPUNIT_ASSERT_EQUAL(0_st, errors.size());
519 CPPUNIT_ASSERT_EQUAL(
"foo"s, *str);
520 CPPUNIT_ASSERT(!nullStr);
522 CPPUNIT_ASSERT_EQUAL(
"bar"s, obj->text);
527 Document doc(kArrayType);
528 doc.Parse(
"[\"foo\",null,{\"text\":\"bar\"}]");
529 auto array = doc.GetArray().begin();
531 shared_ptr<string> str;
532 shared_ptr<string> nullStr;
533 shared_ptr<TestObject> obj;
539 CPPUNIT_ASSERT_EQUAL(0_st, errors.size());
541 CPPUNIT_ASSERT_EQUAL(
"foo"s, *str);
542 CPPUNIT_ASSERT(!nullStr);
544 CPPUNIT_ASSERT_EQUAL(
"bar"s, obj->text);
553 NestingObject::fromJson(
"{\"name\":nesting\",\"testObj\":{\"number\":42,\"number2\":3.141592653589793,\"numbers\":[1,2,3,4],\"text\":" 554 "\"test\",\"boolean\":false}}");
555 CPPUNIT_FAIL(
"expected ParseResult thrown");
556 }
catch (
const RAPIDJSON_NAMESPACE::ParseResult &res) {
557 CPPUNIT_ASSERT_EQUAL(RAPIDJSON_NAMESPACE::kParseErrorValueInvalid, res.Code());
558 CPPUNIT_ASSERT_EQUAL(9_st, res.Offset());
568 NestingArray::fromJson(
"{\"name\":\"nesting2\",\"testObjects\":[{\"number\":42,\"number2\":3.141592653589793," 569 "\"numbers\":[1,2,3,4],\"text\":\"test\",\"boolean\":false},{\"number\":43,\"number2\":3." 570 "141592653589793,\"numbers\":[1,2,3,4],\"text\":\"test\",\"boolean\":false}]}",
572 CPPUNIT_ASSERT_EQUAL(0_st, errors.size());
574 NestingObject::fromJson(
"{\"name\":\"nesting\",\"testObj\":{\"number\":\"42\",\"number2\":3.141592653589793,\"numbers\":[1,2,3,4],\"text\":" 575 "\"test\",\"boolean\":false,\"someSet\":[\"a\",\"a\"],\"someMultiset\":[\"a\",\"a\"],\"someUnorderedSet\":[\"a\",\"a\"]," 576 "\"someUnorderedMultiset\":[\"a\",\"a\"]}}",
578 CPPUNIT_ASSERT_EQUAL(3_st, errors.size());
579 CPPUNIT_ASSERT_EQUAL(JsonDeserializationErrorKind::TypeMismatch, errors.front().kind);
580 CPPUNIT_ASSERT_EQUAL(JsonType::Number, errors.front().expectedType);
581 CPPUNIT_ASSERT_EQUAL(JsonType::String, errors.front().actualType);
582 CPPUNIT_ASSERT_EQUAL(
"number"s,
string(errors.front().member));
583 CPPUNIT_ASSERT_EQUAL(
"TestObject"s,
string(errors.front().record));
584 CPPUNIT_ASSERT_EQUAL(JsonDeserializationErrorKind::UnexpectedDuplicate, errors[1].kind);
585 CPPUNIT_ASSERT_EQUAL(JsonType::Array, errors[1].expectedType);
586 CPPUNIT_ASSERT_EQUAL(JsonType::Array, errors[1].actualType);
587 CPPUNIT_ASSERT_EQUAL(
"someSet"s,
string(errors[1].member));
588 CPPUNIT_ASSERT_EQUAL(
"TestObject"s,
string(errors[1].record));
589 CPPUNIT_ASSERT_EQUAL(JsonDeserializationErrorKind::UnexpectedDuplicate, errors[2].kind);
590 CPPUNIT_ASSERT_EQUAL(JsonType::Array, errors[2].expectedType);
591 CPPUNIT_ASSERT_EQUAL(JsonType::Array, errors[2].actualType);
592 CPPUNIT_ASSERT_EQUAL(
"someUnorderedSet"s,
string(errors[2].member));
593 CPPUNIT_ASSERT_EQUAL(
"TestObject"s,
string(errors[2].record));
596 NestingObject::fromJson(
"{\"name\":\"nesting\",\"testObj\":{\"number\":42,\"number2\":3.141592653589793,\"numbers\":1,\"text\":" 597 "\"test\",\"boolean\":false}}",
599 CPPUNIT_ASSERT_EQUAL(1_st, errors.size());
600 CPPUNIT_ASSERT_EQUAL(JsonDeserializationErrorKind::TypeMismatch, errors.front().kind);
601 CPPUNIT_ASSERT_EQUAL(JsonType::Array, errors.front().expectedType);
602 CPPUNIT_ASSERT_EQUAL(JsonType::Number, errors.front().actualType);
603 CPPUNIT_ASSERT_EQUAL(
"numbers"s,
string(errors.front().member));
604 CPPUNIT_ASSERT_EQUAL(
"TestObject"s,
string(errors.front().record));
608 CPPUNIT_ASSERT_EQUAL(2_st, errors.size());
609 CPPUNIT_ASSERT_EQUAL(JsonDeserializationErrorKind::TypeMismatch, errors.front().kind);
610 CPPUNIT_ASSERT_EQUAL(JsonType::String, errors.front().expectedType);
611 CPPUNIT_ASSERT_EQUAL(JsonType::Array, errors.front().actualType);
612 CPPUNIT_ASSERT_EQUAL(
"name"s,
string(errors.front().member));
613 CPPUNIT_ASSERT_EQUAL(
"NestingObject"s,
string(errors.front().record));
614 CPPUNIT_ASSERT_EQUAL(JsonDeserializationErrorKind::TypeMismatch, errors.back().kind);
615 CPPUNIT_ASSERT_EQUAL(JsonType::Object, errors.back().expectedType);
616 CPPUNIT_ASSERT_EQUAL(JsonType::String, errors.back().actualType);
617 CPPUNIT_ASSERT_EQUAL(
"testObj"s,
string(errors.back().member));
618 CPPUNIT_ASSERT_EQUAL(
"NestingObject"s,
string(errors.back().record));
621 const NestingArray nestingArray(
622 NestingArray::fromJson(
"{\"name\":\"nesting2\",\"testObjects\":[25,{\"number\":42,\"number2\":3.141592653589793," 623 "\"numbers\":[1,2,3,4],\"text\":\"test\",\"boolean\":false},\"foo\",{\"number\":43,\"number2\":3." 624 "141592653589793,\"numbers\":[1,2,3,4,\"bar\"],\"text\":\"test\",\"boolean\":false}]}",
626 CPPUNIT_ASSERT_EQUAL(3_st, errors.size());
627 CPPUNIT_ASSERT_EQUAL(JsonDeserializationErrorKind::TypeMismatch, errors[0].kind);
628 CPPUNIT_ASSERT_EQUAL(JsonType::Object, errors[0].expectedType);
629 CPPUNIT_ASSERT_EQUAL(JsonType::Number, errors[0].actualType);
630 CPPUNIT_ASSERT_EQUAL(
"testObjects"s,
string(errors[0].member));
631 CPPUNIT_ASSERT_EQUAL(
"NestingArray"s,
string(errors[0].record));
632 CPPUNIT_ASSERT_EQUAL(0_st, errors[0].index);
633 CPPUNIT_ASSERT_EQUAL(JsonDeserializationErrorKind::TypeMismatch, errors[1].kind);
634 CPPUNIT_ASSERT_EQUAL(JsonType::Object, errors[1].expectedType);
635 CPPUNIT_ASSERT_EQUAL(JsonType::String, errors[1].actualType);
636 CPPUNIT_ASSERT_EQUAL(2_st, errors[1].index);
637 CPPUNIT_ASSERT_EQUAL(
"testObjects"s,
string(errors[1].member));
638 CPPUNIT_ASSERT_EQUAL(
"NestingArray"s,
string(errors[1].record));
639 CPPUNIT_ASSERT_EQUAL(JsonDeserializationErrorKind::TypeMismatch, errors[2].kind);
640 CPPUNIT_ASSERT_EQUAL(JsonType::Number, errors[2].expectedType);
641 CPPUNIT_ASSERT_EQUAL(JsonType::String, errors[2].actualType);
642 CPPUNIT_ASSERT_EQUAL(
"numbers"s,
string(errors[2].member));
643 CPPUNIT_ASSERT_EQUAL(
"TestObject"s,
string(errors[2].record));
644 CPPUNIT_ASSERT_EQUAL(4_st, errors[2].index);
647 errors.
throwOn = JsonDeserializationErrors::ThrowOn::TypeMismatch;
void testSerializeUniquePtr()
The JsonReflectorTests class tests RapidJSON wrapper which is used to ease code generation.
void testDeserializePrimitives()
Tests deserializing strings, numbers (int, float, double) and boolean.
void testDeserializeNestedObjects()
Tests deserializing nested objects and arrays.
Traits::Any< Traits::IsSpecializationOf< Type, std::set >, Traits::IsSpecializationOf< Type, std::unordered_set > > IsSet
Traits::Any< Traits::IsSpecializationOf< Type, std::multiset >, Traits::IsSpecializationOf< Type, std::unordered_multiset > > IsMultiSet
void testDeserializeSimpleObjects()
Tests deserializing simple objects.
Traits::Any< Traits::IsSpecializationOf< Type, std::map >, Traits::IsSpecializationOf< Type, std::unordered_map > > IsMapOrHash
RAPIDJSON_NAMESPACE::StringBuffer toJson(const Type &reflectable)
Serializes the specified reflectable which has a custom type or can be mapped to and object...
void testSerializeNestedObjects()
Tests serializing nested object and arrays.
Traits::All< Traits::IsIteratable< Type >, Traits::Not< Traits::IsSpecializationOf< Type, std::basic_string > >, Traits::Not< IsMapOrHash< Type > >, Traits::Not< IsSet< Type > >, Traits::Not< IsMultiSet< Type > >> IsArray
void testSerializeSharedPtr()
enum ReflectiveRapidJSON::JsonDeserializationErrors::ThrowOn throwOn
void testDeserializeSharedPtr()
void testSerializeSimpleObjects()
Tests serializing objects.
The JsonDeserializationErrors struct can be passed to fromJson() for error handling.
Type fromJson(const char *json, std::size_t jsonSize, JsonDeserializationErrors *errors=nullptr)
Deserializes the specified JSON to.
Traits::All< Traits::IsIteratable< Type >, Traits::Not< Traits::IsSpecializationOf< Type, std::basic_string > >, Traits::Not< IsMapOrHash< Type > >> IsArrayOrSet
void pull(Type &reflectable, const RAPIDJSON_NAMESPACE::GenericValue< RAPIDJSON_NAMESPACE::UTF8< char >>::ConstObject &value, JsonDeserializationErrors *errors)
Pulls the reflectable which has a custom type from the specified object.
CPPUNIT_TEST_SUITE_REGISTRATION(JsonReflectorTests)
The JsonDeserializationError struct describes any errors of fromJson() except such caused by invalid ...
void testHandlingTypeMismatch()
Tests whether errors are added on type mismatch and in other cases.
void testHandlingParseError()
Tests whether RAPIDJSON_NAMESPACE::ParseResult is thrown correctly when passing invalid JSON to fromJ...
void testSerializePrimitives()
Tests serializing strings, numbers, arrays and boolean.
void push(const Type &reflectable, RAPIDJSON_NAMESPACE::Value &value, RAPIDJSON_NAMESPACE::Document::AllocatorType &allocator)
Pushes the specified reflectable to the specified value.
The JsonSerializable class provides the CRTP-base for (de)serializable objects.
void testDeserializeUniquePtr()