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> 25 using namespace CPPUNIT_NS;
26 using namespace RAPIDJSON_NAMESPACE;
27 using namespace IoUtilities;
28 using namespace ConversionUtilities;
29 using namespace TestUtilities;
30 using namespace TestUtilities::Literals;
43 enum class SomeEnumClass {
55 map<string, int> someMap;
56 unordered_map<string, bool> someHash;
58 multiset<string> someMultiset;
59 unordered_set<string> someUnorderedSet;
60 unordered_multiset<string> someUnorderedMultiset;
70 vector<TestObject> testObjects;
75 namespace JsonReflector {
77 template <>
inline void push<TestObject>(
const TestObject &reflectable, Value::Object &value, Document::AllocatorType &allocator)
79 push(reflectable.number,
"number", value, allocator);
80 push(reflectable.number2,
"number2", value, allocator);
81 push(reflectable.numbers,
"numbers", value, allocator);
82 push(reflectable.text,
"text", value, allocator);
83 push(reflectable.boolean,
"boolean", value, allocator);
84 push(reflectable.someMap,
"someMap", value, allocator);
85 push(reflectable.someHash,
"someHash", value, allocator);
86 push(reflectable.someSet,
"someSet", value, allocator);
87 push(reflectable.someMultiset,
"someMultiset", value, allocator);
88 push(reflectable.someUnorderedSet,
"someUnorderedSet", value, allocator);
89 push(reflectable.someUnorderedMultiset,
"someUnorderedMultiset", value, allocator);
92 template <>
inline void push<NestingObject>(
const NestingObject &reflectable, Value::Object &value, Document::AllocatorType &allocator)
94 push(reflectable.name,
"name", value, allocator);
95 push(reflectable.testObj,
"testObj", value, allocator);
98 template <>
inline void push<NestingArray>(
const NestingArray &reflectable, Value::Object &value, Document::AllocatorType &allocator)
100 push(reflectable.name,
"name", value, allocator);
101 push(reflectable.testObjects,
"testObjects", value, allocator);
105 inline void pull<TestObject>(TestObject &reflectable,
const GenericValue<UTF8<char>>::ConstObject &value,
JsonDeserializationErrors *errors)
107 const char *previousRecord;
112 pull(reflectable.number,
"number", value, errors);
113 pull(reflectable.number2,
"number2", value, errors);
114 pull(reflectable.numbers,
"numbers", value, errors);
115 pull(reflectable.text,
"text", value, errors);
116 pull(reflectable.boolean,
"boolean", value, errors);
117 pull(reflectable.someMap,
"someMap", value, errors);
118 pull(reflectable.someHash,
"someHash", value, errors);
119 pull(reflectable.someSet,
"someSet", value, errors);
120 pull(reflectable.someMultiset,
"someMultiset", value, errors);
121 pull(reflectable.someUnorderedSet,
"someUnorderedSet", value, errors);
122 pull(reflectable.someUnorderedMultiset,
"someUnorderedMultiset", value, errors);
129 inline void pull<NestingObject>(NestingObject &reflectable,
const GenericValue<UTF8<char>>::ConstObject &value,
JsonDeserializationErrors *errors)
131 const char *previousRecord;
136 pull(reflectable.name,
"name", value, errors);
137 pull(reflectable.testObj,
"testObj", value, errors);
144 inline void pull<NestingArray>(NestingArray &reflectable,
const GenericValue<UTF8<char>>::ConstObject &value,
JsonDeserializationErrors *errors)
146 const char *previousRecord;
151 pull(reflectable.name,
"name", value, errors);
152 pull(reflectable.testObjects,
"testObjects", value, errors);
171 CPPUNIT_TEST(testSerializePrimitives);
172 CPPUNIT_TEST(testSerializeSimpleObjects);
173 CPPUNIT_TEST(testSerializeNestedObjects);
174 CPPUNIT_TEST(testSerializeUniquePtr);
175 CPPUNIT_TEST(testSerializeSharedPtr);
176 CPPUNIT_TEST(testDeserializePrimitives);
177 CPPUNIT_TEST(testDeserializeSimpleObjects);
178 CPPUNIT_TEST(testDeserializeNestedObjects);
179 CPPUNIT_TEST(testDeserializeUniquePtr);
180 CPPUNIT_TEST(testDeserializeSharedPtr);
181 CPPUNIT_TEST(testHandlingParseError);
182 CPPUNIT_TEST(testHandlingTypeMismatch);
183 CPPUNIT_TEST_SUITE_END();
190 void testSerializePrimitives();
191 void testSerializeSimpleObjects();
192 void testSerializeNestedObjects();
193 void testSerializeUniquePtr();
194 void testSerializeSharedPtr();
195 void testDeserializePrimitives();
196 void testDeserializeSimpleObjects();
197 void testDeserializeNestedObjects();
198 void testDeserializeUniquePtr();
199 void testDeserializeSharedPtr();
200 void testHandlingParseError();
201 void testHandlingTypeMismatch();
221 Document doc(kArrayType);
222 Document::AllocatorType &alloc = doc.GetAllocator();
224 Document::Array array(doc.GetArray());
227 const string foo(
"foo");
228 JsonReflector::push<string>(foo, array, alloc);
229 JsonReflector::push<const char *>(
"bar", array, alloc);
231 JsonReflector::push<int>(25, array, alloc);
232 JsonReflector::push<double>(12.5, array, alloc);
234 JsonReflector::push<SomeEnum>(SomeEnumItem2, array, alloc);
235 JsonReflector::push<SomeEnumClass>(SomeEnumClass::Item2, array, alloc);
236 JsonReflector::push<SomeEnumClass>(SomeEnumClass::Item3, array, alloc);
238 JsonReflector::push<vector<const char *>>({
"foo1",
"bar1" }, array, alloc);
239 JsonReflector::push<list<const char *>>({
"foo2",
"bar2" }, array, alloc);
240 JsonReflector::push<initializer_list<const char *>>({
"foo3",
"bar3" }, array, alloc);
241 JsonReflector::push<tuple<int, double>>(make_tuple(2, 413.0), array, alloc);
243 JsonReflector::push<bool>(
true, array, alloc);
244 JsonReflector::push<bool>(
false, array, alloc);
247 Writer<StringBuffer> jsonWriter(strbuf);
248 doc.Accept(jsonWriter);
249 CPPUNIT_ASSERT_EQUAL(
"[\"foo\",\"bar\",25,12.5,1,1,2,[\"foo1\",\"bar1\"],[\"foo2\",\"bar2\"],[\"foo3\",\"bar3\"],[2,413.0],true,false]"s,
250 string(strbuf.GetString()));
260 testObj.number2 = 3.141592653589793;
261 testObj.numbers = { 1, 2, 3, 4 };
262 testObj.text =
"test";
263 testObj.boolean =
false;
264 testObj.someMap = { {
"a", 1 }, {
"b", 2 } };
265 testObj.someHash = { {
"c",
true }, {
"d",
false } };
266 testObj.someSet = {
"a",
"b",
"c" };
267 testObj.someMultiset = {
"a",
"b",
"b" };
268 testObj.someUnorderedSet = {
"a" };
269 testObj.someUnorderedMultiset = {
"b",
"b",
"b" };
270 CPPUNIT_ASSERT_EQUAL(
271 "{\"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,
272 string(testObj.toJson().GetString()));
280 NestingObject nestingObj;
281 nestingObj.name =
"nesting";
282 TestObject &testObj = nestingObj.testObj;
284 testObj.number2 = 3.141592653589793;
285 testObj.numbers = { 1, 2, 3, 4 };
286 testObj.text =
"test";
287 testObj.boolean =
false;
288 CPPUNIT_ASSERT_EQUAL(
289 "{\"name\":\"nesting\",\"testObj\":{\"number\":42,\"number2\":3.141592653589793,\"numbers\":[1,2,3,4],\"text\":\"test\",\"boolean\":false,\"someMap\":{},\"someHash\":{},\"someSet\":[],\"someMultiset\":[],\"someUnorderedSet\":[],\"someUnorderedMultiset\":[]}}"s,
290 string(nestingObj.toJson().GetString()));
292 NestingArray nestingArray;
293 nestingArray.name =
"nesting2";
294 nestingArray.testObjects.emplace_back(testObj);
295 nestingArray.testObjects.emplace_back(testObj);
296 nestingArray.testObjects.back().number = 43;
297 CPPUNIT_ASSERT_EQUAL(
298 "{\"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,
299 string(nestingArray.toJson().GetString()));
301 vector<TestObject> nestedInVector;
302 nestedInVector.emplace_back(testObj);
303 CPPUNIT_ASSERT_EQUAL(
304 "[{\"number\":42,\"number2\":3.141592653589793,\"numbers\":[1,2,3,4],\"text\":\"test\",\"boolean\":false,\"someMap\":{},\"someHash\":{},\"someSet\":[],\"someMultiset\":[],\"someUnorderedSet\":[],\"someUnorderedMultiset\":[]}]"s,
310 Document doc(kArrayType);
311 Document::AllocatorType &alloc = doc.GetAllocator();
313 Document::Array array(doc.GetArray());
315 const auto str = make_unique<string>(
"foo");
316 std::unique_ptr<string> nullStr;
317 const auto obj = make_unique<TestObject>();
319 obj->number2 = 3.141592653589793;
320 obj->numbers = { 1, 2, 3, 4 };
322 obj->boolean =
false;
329 Writer<StringBuffer> jsonWriter(strbuf);
330 doc.Accept(jsonWriter);
331 CPPUNIT_ASSERT_EQUAL(
332 "[\"foo\",null,{\"number\":42,\"number2\":3.141592653589793,\"numbers\":[1,2,3,4],\"text\":\"bar\",\"boolean\":false,\"someMap\":{},\"someHash\":{},\"someSet\":[],\"someMultiset\":[],\"someUnorderedSet\":[],\"someUnorderedMultiset\":[]}]"s,
333 string(strbuf.GetString()));
338 Document doc(kArrayType);
339 Document::AllocatorType &alloc = doc.GetAllocator();
341 Document::Array array(doc.GetArray());
343 const auto str = make_shared<string>(
"foo");
344 std::unique_ptr<string> nullStr;
345 const auto obj = make_shared<TestObject>();
347 obj->number2 = 3.141592653589793;
348 obj->numbers = { 1, 2, 3, 4 };
350 obj->boolean =
false;
357 Writer<StringBuffer> jsonWriter(strbuf);
358 doc.Accept(jsonWriter);
359 CPPUNIT_ASSERT_EQUAL(
360 "[\"foo\",null,{\"number\":42,\"number2\":3.141592653589793,\"numbers\":[1,2,3,4],\"text\":\"bar\",\"boolean\":false,\"someMap\":{},\"someHash\":{},\"someSet\":[],\"someMultiset\":[],\"someUnorderedSet\":[],\"someUnorderedMultiset\":[]}]"s,
361 string(strbuf.GetString()));
369 Document doc(kArrayType);
371 doc.Parse(
"[\"a\", 5, 5.0, 5e6, 4, \"test\", true, 4.125, false]");
372 auto array = doc.GetArray().begin();
375 int int1 = 0, int2 = 0;
376 bool bool1 =
false, bool2 =
true;
377 float float1 = 0.0f, float2 = 0.0f;
378 double double1 = 0.0;
390 CPPUNIT_ASSERT_EQUAL(0_st, errors.size());
391 CPPUNIT_ASSERT_EQUAL(
"a"s, str1);
392 CPPUNIT_ASSERT_EQUAL(5, int1);
393 CPPUNIT_ASSERT_EQUAL(5, int2);
394 CPPUNIT_ASSERT_EQUAL(5e6f, float1);
395 CPPUNIT_ASSERT_EQUAL(4.f, float2);
396 CPPUNIT_ASSERT_EQUAL(
"test"s, str2);
397 CPPUNIT_ASSERT_EQUAL(
true, bool1);
398 CPPUNIT_ASSERT_EQUAL(4.125, double1);
399 CPPUNIT_ASSERT_EQUAL(
false, bool2);
402 tuple<string, int, int, float, float, string, bool, double, bool> arrayAsTuple;
404 CPPUNIT_ASSERT_EQUAL(0_st, errors.size());
405 CPPUNIT_ASSERT_EQUAL(
"a"s, get<0>(arrayAsTuple));
406 CPPUNIT_ASSERT_EQUAL(5, get<1>(arrayAsTuple));
407 CPPUNIT_ASSERT_EQUAL(5, get<2>(arrayAsTuple));
408 CPPUNIT_ASSERT_EQUAL(5e6f, get<3>(arrayAsTuple));
409 CPPUNIT_ASSERT_EQUAL(4.f, get<4>(arrayAsTuple));
410 CPPUNIT_ASSERT_EQUAL(
"test"s, get<5>(arrayAsTuple));
411 CPPUNIT_ASSERT_EQUAL(
true, get<6>(arrayAsTuple));
412 CPPUNIT_ASSERT_EQUAL(4.125, get<7>(arrayAsTuple));
413 CPPUNIT_ASSERT_EQUAL(
false, get<8>(arrayAsTuple));
414 tuple<string, int> anotherTuple;
416 CPPUNIT_ASSERT_EQUAL(1_st, errors.size());
417 CPPUNIT_ASSERT_EQUAL(JsonDeserializationErrorKind::ArraySizeMismatch, errors.front().kind);
425 const TestObject testObj(
426 TestObject::fromJson(
"{\"number\":42,\"number2\":3.141592653589793,\"numbers\":[1,2,3,4],\"text\":\"test\",\"boolean\":" 427 "false,\"someMap\":{\"a\":1,\"b\":2},\"someHash\":{\"c\":true,\"d\":false},\"someSet\":[\"a\",\"b\"],\"someMultiset\":[" 428 "\"a\",\"a\"],\"someUnorderedSet\":[\"a\",\"b\"],\"someUnorderedMultiset\":[\"a\",\"a\"]}"));
430 CPPUNIT_ASSERT_EQUAL(42, testObj.number);
431 CPPUNIT_ASSERT_EQUAL(3.141592653589793, testObj.number2);
432 CPPUNIT_ASSERT_EQUAL(vector<int>({ 1, 2, 3, 4 }), testObj.numbers);
433 CPPUNIT_ASSERT_EQUAL(
"test"s, testObj.text);
434 CPPUNIT_ASSERT_EQUAL(
false, testObj.boolean);
435 const map<string, int> expectedMap{ {
"a", 1 }, {
"b", 2 } };
436 CPPUNIT_ASSERT_EQUAL(expectedMap, testObj.someMap);
437 const unordered_map<string, bool> expectedHash{ {
"c",
true }, {
"d",
false } };
438 CPPUNIT_ASSERT_EQUAL(expectedHash, testObj.someHash);
439 CPPUNIT_ASSERT_EQUAL(set<string>({
"a",
"b" }), testObj.someSet);
440 CPPUNIT_ASSERT_EQUAL(multiset<string>({
"a",
"a" }), testObj.someMultiset);
441 CPPUNIT_ASSERT_EQUAL(unordered_set<string>({
"a",
"b" }), testObj.someUnorderedSet);
442 CPPUNIT_ASSERT_EQUAL(unordered_multiset<string>({
"a",
"a" }), testObj.someUnorderedMultiset);
451 const NestingObject nestingObj(
NestingObject::fromJson(
"{\"name\":\"nesting\",\"testObj\":{\"number\":42,\"number2\":3.141592653589793," 452 "\"numbers\":[1,2,3,4],\"text\":\"test\",\"boolean\":false}}",
454 const TestObject &testObj = nestingObj.testObj;
455 CPPUNIT_ASSERT_EQUAL(0_st, errors.size());
456 CPPUNIT_ASSERT_EQUAL(
"nesting"s, nestingObj.name);
457 CPPUNIT_ASSERT_EQUAL(42, testObj.number);
458 CPPUNIT_ASSERT_EQUAL(3.141592653589793, testObj.number2);
459 CPPUNIT_ASSERT_EQUAL(vector<int>({ 1, 2, 3, 4 }), testObj.numbers);
460 CPPUNIT_ASSERT_EQUAL(
"test"s, testObj.text);
461 CPPUNIT_ASSERT_EQUAL(
false, testObj.boolean);
463 const NestingArray nestingArray(
NestingArray::fromJson(
"{\"name\":\"nesting2\",\"testObjects\":[{\"number\":42,\"number2\":3.141592653589793," 464 "\"numbers\":[1,2,3,4],\"text\":\"test\",\"boolean\":false},{\"number\":43,\"number2\":3." 465 "141592653589793,\"numbers\":[1,2,3,4],\"text\":\"test\",\"boolean\":false}]}",
467 const vector<TestObject> &testObjects = nestingArray.testObjects;
468 CPPUNIT_ASSERT_EQUAL(0_st, errors.size());
469 CPPUNIT_ASSERT_EQUAL(
"nesting2"s, nestingArray.name);
470 CPPUNIT_ASSERT_EQUAL(2_st, testObjects.size());
471 CPPUNIT_ASSERT_EQUAL(42, testObjects[0].number);
472 CPPUNIT_ASSERT_EQUAL(43, testObjects[1].number);
473 for (
const TestObject &testObj : testObjects) {
474 CPPUNIT_ASSERT_EQUAL(3.141592653589793, testObj.number2);
475 CPPUNIT_ASSERT_EQUAL(vector<int>({ 1, 2, 3, 4 }), testObj.numbers);
476 CPPUNIT_ASSERT_EQUAL(
"test"s, testObj.text);
477 CPPUNIT_ASSERT_EQUAL(
false, testObj.boolean);
481 "[{\"number\":42,\"number2\":3.141592653589793,\"numbers\":[1,2,3,4],\"text\":\"test\",\"boolean\":false,\"someMap\":{},\"someHash\":{}}]",
483 CPPUNIT_ASSERT_EQUAL(0_st, errors.size());
484 CPPUNIT_ASSERT_EQUAL(1_st, nestedInVector.size());
485 CPPUNIT_ASSERT_EQUAL(42, nestedInVector[0].number);
486 CPPUNIT_ASSERT_EQUAL(4_st, nestedInVector[0].numbers.size());
487 CPPUNIT_ASSERT_EQUAL(
"test"s, nestedInVector[0].text);
492 Document doc(kArrayType);
493 doc.Parse(
"[\"foo\",null,{\"text\":\"bar\"}]");
494 auto array = doc.GetArray().begin();
496 unique_ptr<string> str;
497 unique_ptr<string> nullStr;
498 unique_ptr<TestObject> obj;
504 CPPUNIT_ASSERT_EQUAL(0_st, errors.size());
506 CPPUNIT_ASSERT_EQUAL(
"foo"s, *str);
507 CPPUNIT_ASSERT(!nullStr);
509 CPPUNIT_ASSERT_EQUAL(
"bar"s, obj->text);
514 Document doc(kArrayType);
515 doc.Parse(
"[\"foo\",null,{\"text\":\"bar\"}]");
516 auto array = doc.GetArray().begin();
518 shared_ptr<string> str;
519 shared_ptr<string> nullStr;
520 shared_ptr<TestObject> obj;
526 CPPUNIT_ASSERT_EQUAL(0_st, errors.size());
528 CPPUNIT_ASSERT_EQUAL(
"foo"s, *str);
529 CPPUNIT_ASSERT(!nullStr);
531 CPPUNIT_ASSERT_EQUAL(
"bar"s, obj->text);
540 NestingObject::fromJson(
"{\"name\":nesting\",\"testObj\":{\"number\":42,\"number2\":3.141592653589793,\"numbers\":[1,2,3,4],\"text\":" 541 "\"test\",\"boolean\":false}}");
542 CPPUNIT_FAIL(
"expected ParseResult thrown");
543 }
catch (
const RAPIDJSON_NAMESPACE::ParseResult &res) {
544 CPPUNIT_ASSERT_EQUAL(RAPIDJSON_NAMESPACE::kParseErrorValueInvalid, res.Code());
545 CPPUNIT_ASSERT_EQUAL(9_st, res.Offset());
555 NestingArray::fromJson(
"{\"name\":\"nesting2\",\"testObjects\":[{\"number\":42,\"number2\":3.141592653589793," 556 "\"numbers\":[1,2,3,4],\"text\":\"test\",\"boolean\":false},{\"number\":43,\"number2\":3." 557 "141592653589793,\"numbers\":[1,2,3,4],\"text\":\"test\",\"boolean\":false}]}",
559 CPPUNIT_ASSERT_EQUAL(0_st, errors.size());
561 NestingObject::fromJson(
"{\"name\":\"nesting\",\"testObj\":{\"number\":\"42\",\"number2\":3.141592653589793,\"numbers\":[1,2,3,4],\"text\":" 562 "\"test\",\"boolean\":false,\"someSet\":[\"a\",\"a\"],\"someMultiset\":[\"a\",\"a\"],\"someUnorderedSet\":[\"a\",\"a\"]," 563 "\"someUnorderedMultiset\":[\"a\",\"a\"]}}",
565 CPPUNIT_ASSERT_EQUAL(3_st, errors.size());
566 CPPUNIT_ASSERT_EQUAL(JsonDeserializationErrorKind::TypeMismatch, errors.front().kind);
567 CPPUNIT_ASSERT_EQUAL(JsonType::Number, errors.front().expectedType);
568 CPPUNIT_ASSERT_EQUAL(JsonType::String, errors.front().actualType);
569 CPPUNIT_ASSERT_EQUAL(
"number"s,
string(errors.front().member));
570 CPPUNIT_ASSERT_EQUAL(
"TestObject"s,
string(errors.front().record));
571 CPPUNIT_ASSERT_EQUAL(JsonDeserializationErrorKind::UnexpectedDuplicate, errors[1].kind);
572 CPPUNIT_ASSERT_EQUAL(JsonType::Array, errors[1].expectedType);
573 CPPUNIT_ASSERT_EQUAL(JsonType::Array, errors[1].actualType);
574 CPPUNIT_ASSERT_EQUAL(
"someSet"s,
string(errors[1].member));
575 CPPUNIT_ASSERT_EQUAL(
"TestObject"s,
string(errors[1].record));
576 CPPUNIT_ASSERT_EQUAL(JsonDeserializationErrorKind::UnexpectedDuplicate, errors[2].kind);
577 CPPUNIT_ASSERT_EQUAL(JsonType::Array, errors[2].expectedType);
578 CPPUNIT_ASSERT_EQUAL(JsonType::Array, errors[2].actualType);
579 CPPUNIT_ASSERT_EQUAL(
"someUnorderedSet"s,
string(errors[2].member));
580 CPPUNIT_ASSERT_EQUAL(
"TestObject"s,
string(errors[2].record));
583 NestingObject::fromJson(
"{\"name\":\"nesting\",\"testObj\":{\"number\":42,\"number2\":3.141592653589793,\"numbers\":1,\"text\":" 584 "\"test\",\"boolean\":false}}",
586 CPPUNIT_ASSERT_EQUAL(1_st, errors.size());
587 CPPUNIT_ASSERT_EQUAL(JsonDeserializationErrorKind::TypeMismatch, errors.front().kind);
588 CPPUNIT_ASSERT_EQUAL(JsonType::Array, errors.front().expectedType);
589 CPPUNIT_ASSERT_EQUAL(JsonType::Number, errors.front().actualType);
590 CPPUNIT_ASSERT_EQUAL(
"numbers"s,
string(errors.front().member));
591 CPPUNIT_ASSERT_EQUAL(
"TestObject"s,
string(errors.front().record));
595 CPPUNIT_ASSERT_EQUAL(2_st, errors.size());
596 CPPUNIT_ASSERT_EQUAL(JsonDeserializationErrorKind::TypeMismatch, errors.front().kind);
597 CPPUNIT_ASSERT_EQUAL(JsonType::String, errors.front().expectedType);
598 CPPUNIT_ASSERT_EQUAL(JsonType::Array, errors.front().actualType);
599 CPPUNIT_ASSERT_EQUAL(
"name"s,
string(errors.front().member));
600 CPPUNIT_ASSERT_EQUAL(
"NestingObject"s,
string(errors.front().record));
601 CPPUNIT_ASSERT_EQUAL(JsonDeserializationErrorKind::TypeMismatch, errors.back().kind);
602 CPPUNIT_ASSERT_EQUAL(JsonType::Object, errors.back().expectedType);
603 CPPUNIT_ASSERT_EQUAL(JsonType::String, errors.back().actualType);
604 CPPUNIT_ASSERT_EQUAL(
"testObj"s,
string(errors.back().member));
605 CPPUNIT_ASSERT_EQUAL(
"NestingObject"s,
string(errors.back().record));
608 const NestingArray nestingArray(
609 NestingArray::fromJson(
"{\"name\":\"nesting2\",\"testObjects\":[25,{\"number\":42,\"number2\":3.141592653589793," 610 "\"numbers\":[1,2,3,4],\"text\":\"test\",\"boolean\":false},\"foo\",{\"number\":43,\"number2\":3." 611 "141592653589793,\"numbers\":[1,2,3,4,\"bar\"],\"text\":\"test\",\"boolean\":false}]}",
613 CPPUNIT_ASSERT_EQUAL(3_st, errors.size());
614 CPPUNIT_ASSERT_EQUAL(JsonDeserializationErrorKind::TypeMismatch, errors[0].kind);
615 CPPUNIT_ASSERT_EQUAL(JsonType::Object, errors[0].expectedType);
616 CPPUNIT_ASSERT_EQUAL(JsonType::Number, errors[0].actualType);
617 CPPUNIT_ASSERT_EQUAL(
"testObjects"s,
string(errors[0].member));
618 CPPUNIT_ASSERT_EQUAL(
"NestingArray"s,
string(errors[0].record));
619 CPPUNIT_ASSERT_EQUAL(0_st, errors[0].index);
620 CPPUNIT_ASSERT_EQUAL(JsonDeserializationErrorKind::TypeMismatch, errors[1].kind);
621 CPPUNIT_ASSERT_EQUAL(JsonType::Object, errors[1].expectedType);
622 CPPUNIT_ASSERT_EQUAL(JsonType::String, errors[1].actualType);
623 CPPUNIT_ASSERT_EQUAL(2_st, errors[1].index);
624 CPPUNIT_ASSERT_EQUAL(
"testObjects"s,
string(errors[1].member));
625 CPPUNIT_ASSERT_EQUAL(
"NestingArray"s,
string(errors[1].record));
626 CPPUNIT_ASSERT_EQUAL(JsonDeserializationErrorKind::TypeMismatch, errors[2].kind);
627 CPPUNIT_ASSERT_EQUAL(JsonType::Number, errors[2].expectedType);
628 CPPUNIT_ASSERT_EQUAL(JsonType::String, errors[2].actualType);
629 CPPUNIT_ASSERT_EQUAL(
"numbers"s,
string(errors[2].member));
630 CPPUNIT_ASSERT_EQUAL(
"TestObject"s,
string(errors[2].record));
631 CPPUNIT_ASSERT_EQUAL(4_st, errors[2].index);
634 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.
void testDeserializeSimpleObjects()
Tests deserializing simple objects.
RAPIDJSON_NAMESPACE::StringBuffer toJson(const Type &reflectable)
Serializes the specified reflectable.
void testSerializeNestedObjects()
Tests serializing nested object and arrays.
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.
const char * currentRecord
The name of the class or struct which is currently being processed.
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()