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 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> 22 using namespace CPPUNIT_NS;
23 using namespace RAPIDJSON_NAMESPACE;
24 using namespace IoUtilities;
25 using namespace ConversionUtilities;
26 using namespace TestUtilities;
27 using namespace TestUtilities::Literals;
34 BOOST_HANA_DEFINE_STRUCT(TestObjectHana, (
int, number), (
double, number2), (vector<int>, numbers), (
string, text), (
bool,
boolean));
38 BOOST_HANA_DEFINE_STRUCT(NestingObjectHana, (
string, name), (TestObjectHana, testObj));
42 BOOST_HANA_DEFINE_STRUCT(NestingArrayHana, (
string, name), (vector<TestObjectHana>, testObjects));
53 CPPUNIT_TEST(testSerializeSimpleObjects);
54 CPPUNIT_TEST(testSerializeNestedObjects);
55 CPPUNIT_TEST(testDeserializeSimpleObjects);
56 CPPUNIT_TEST(testDeserializeNestedObjects);
57 CPPUNIT_TEST(testHandlingTypeMismatch);
58 CPPUNIT_TEST_SUITE_END();
64 void testSerializePrimitives();
65 void testSerializeSimpleObjects();
66 void testSerializeNestedObjects();
67 void testDeserializePrimitives();
68 void testDeserializeSimpleObjects();
69 void testDeserializeNestedObjects();
70 void testHandlingTypeMismatch();
90 TestObjectHana testObj;
92 testObj.number2 = 3.141592653589793;
93 testObj.numbers = { 1, 2, 3, 4 };
94 testObj.text =
"test";
95 testObj.boolean =
false;
96 CPPUNIT_ASSERT_EQUAL(
"{\"number\":42,\"number2\":3.141592653589793,\"numbers\":[1,2,3,4],\"text\":\"test\",\"boolean\":false}"s,
97 string(testObj.toJson().GetString()));
105 NestingObjectHana nestingObj;
106 nestingObj.name =
"nesting";
107 TestObjectHana &testObj = nestingObj.testObj;
109 testObj.number2 = 3.141592653589793;
110 testObj.numbers = { 1, 2, 3, 4 };
111 testObj.text =
"test";
112 testObj.boolean =
false;
113 CPPUNIT_ASSERT_EQUAL(
114 "{\"name\":\"nesting\",\"testObj\":{\"number\":42,\"number2\":3.141592653589793,\"numbers\":[1,2,3,4],\"text\":\"test\",\"boolean\":false}}"s,
115 string(nestingObj.toJson().GetString()));
116 NestingArrayHana nestingArray;
117 nestingArray.name =
"nesting2";
118 nestingArray.testObjects.emplace_back(testObj);
119 nestingArray.testObjects.emplace_back(testObj);
120 nestingArray.testObjects.back().number = 43;
121 CPPUNIT_ASSERT_EQUAL(
122 "{\"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,
123 string(nestingArray.toJson().GetString()));
131 const TestObjectHana testObj(
132 TestObjectHana::fromJson(
"{\"number\":42,\"number2\":3.141592653589793,\"numbers\":[1,2,3,4],\"text\":\"test\",\"boolean\":false}"));
134 CPPUNIT_ASSERT_EQUAL(42, testObj.number);
135 CPPUNIT_ASSERT_EQUAL(3.141592653589793, testObj.number2);
136 CPPUNIT_ASSERT_EQUAL(vector<int>({ 1, 2, 3, 4 }), testObj.numbers);
137 CPPUNIT_ASSERT_EQUAL(
"test"s, testObj.text);
138 CPPUNIT_ASSERT_EQUAL(
false, testObj.boolean);
146 const NestingObjectHana nestingObj(
NestingObjectHana::fromJson(
"{\"name\":\"nesting\",\"testObj\":{\"number\":42,\"number2\":3.141592653589793," 147 "\"numbers\":[1,2,3,4],\"text\":\"test\",\"boolean\":false}}"));
148 const TestObjectHana &testObj = nestingObj.testObj;
149 CPPUNIT_ASSERT_EQUAL(
"nesting"s, nestingObj.name);
150 CPPUNIT_ASSERT_EQUAL(42, testObj.number);
151 CPPUNIT_ASSERT_EQUAL(3.141592653589793, testObj.number2);
152 CPPUNIT_ASSERT_EQUAL(vector<int>({ 1, 2, 3, 4 }), testObj.numbers);
153 CPPUNIT_ASSERT_EQUAL(
"test"s, testObj.text);
154 CPPUNIT_ASSERT_EQUAL(
false, testObj.boolean);
156 const NestingArrayHana nestingArray(
158 "\"numbers\":[1,2,3,4],\"text\":\"test\",\"boolean\":false},{\"number\":43,\"number2\":3." 159 "141592653589793,\"numbers\":[1,2,3,4],\"text\":\"test\",\"boolean\":false}]}"));
160 const vector<TestObjectHana> &testObjects = nestingArray.testObjects;
161 CPPUNIT_ASSERT_EQUAL(
"nesting2"s, nestingArray.name);
162 CPPUNIT_ASSERT_EQUAL(2_st, testObjects.size());
163 CPPUNIT_ASSERT_EQUAL(42, testObjects[0].number);
164 CPPUNIT_ASSERT_EQUAL(43, testObjects[1].number);
165 for (
const TestObjectHana &testObj : testObjects) {
166 CPPUNIT_ASSERT_EQUAL(3.141592653589793, testObj.number2);
167 CPPUNIT_ASSERT_EQUAL(vector<int>({ 1, 2, 3, 4 }), testObj.numbers);
168 CPPUNIT_ASSERT_EQUAL(
"test"s, testObj.text);
169 CPPUNIT_ASSERT_EQUAL(
false, testObj.boolean);
180 "\"numbers\":[1,2,3,4],\"text\":\"test\",\"boolean\":false},{\"number\":43,\"number2\":3." 181 "141592653589793,\"numbers\":[1,2,3,4],\"text\":\"test\",\"boolean\":false}]}",
183 CPPUNIT_ASSERT_EQUAL(0_st, errors.size());
185 NestingObjectHana::fromJson(
"{\"name\":\"nesting\",\"testObj\":{\"number\":\"42\",\"number2\":3.141592653589793,\"numbers\":[1,2,3,4],\"text\":" 186 "\"test\",\"boolean\":false}}",
188 CPPUNIT_ASSERT_EQUAL(1_st, errors.size());
189 CPPUNIT_ASSERT_EQUAL(JsonDeserializationErrorKind::TypeMismatch, errors.front().kind);
190 CPPUNIT_ASSERT_EQUAL(JsonType::Number, errors.front().expectedType);
191 CPPUNIT_ASSERT_EQUAL(JsonType::String, errors.front().actualType);
192 CPPUNIT_ASSERT_EQUAL(
"number"s,
string(errors.front().member));
193 CPPUNIT_ASSERT_EQUAL(
"[document]"s,
string(errors.front().record));
196 NestingObjectHana::fromJson(
"{\"name\":\"nesting\",\"testObj\":{\"number\":42,\"number2\":3.141592653589793,\"numbers\":1,\"text\":" 197 "\"test\",\"boolean\":false}}",
199 CPPUNIT_ASSERT_EQUAL(1_st, errors.size());
200 CPPUNIT_ASSERT_EQUAL(JsonDeserializationErrorKind::TypeMismatch, errors.front().kind);
201 CPPUNIT_ASSERT_EQUAL(JsonType::Array, errors.front().expectedType);
202 CPPUNIT_ASSERT_EQUAL(JsonType::Number, errors.front().actualType);
203 CPPUNIT_ASSERT_EQUAL(
"numbers"s,
string(errors.front().member));
204 CPPUNIT_ASSERT_EQUAL(
"[document]"s,
string(errors.front().record));
208 CPPUNIT_ASSERT_EQUAL(2_st, errors.size());
209 CPPUNIT_ASSERT_EQUAL(JsonDeserializationErrorKind::TypeMismatch, errors.front().kind);
210 CPPUNIT_ASSERT_EQUAL(JsonType::String, errors.front().expectedType);
211 CPPUNIT_ASSERT_EQUAL(JsonType::Array, errors.front().actualType);
212 CPPUNIT_ASSERT_EQUAL(
"name"s,
string(errors.front().member));
213 CPPUNIT_ASSERT_EQUAL(
"[document]"s,
string(errors.front().record));
214 CPPUNIT_ASSERT_EQUAL(JsonDeserializationErrorKind::TypeMismatch, errors.back().kind);
215 CPPUNIT_ASSERT_EQUAL(JsonType::Object, errors.back().expectedType);
216 CPPUNIT_ASSERT_EQUAL(JsonType::String, errors.back().actualType);
217 CPPUNIT_ASSERT_EQUAL(
"testObj"s,
string(errors.back().member));
218 CPPUNIT_ASSERT_EQUAL(
"[document]"s,
string(errors.back().record));
221 const NestingArrayHana nestingArray(
223 "\"numbers\":[1,2,3,4],\"text\":\"test\",\"boolean\":false},\"foo\",{\"number\":43,\"number2\":3." 224 "141592653589793,\"numbers\":[1,2,3,4,\"bar\"],\"text\":\"test\",\"boolean\":false}]}",
226 CPPUNIT_ASSERT_EQUAL(3_st, errors.size());
227 CPPUNIT_ASSERT_EQUAL(JsonDeserializationErrorKind::TypeMismatch, errors[0].kind);
228 CPPUNIT_ASSERT_EQUAL(JsonType::Object, errors[0].expectedType);
229 CPPUNIT_ASSERT_EQUAL(JsonType::Number, errors[0].actualType);
230 CPPUNIT_ASSERT_EQUAL(
"testObjects"s,
string(errors[0].member));
231 CPPUNIT_ASSERT_EQUAL(
"[document]"s,
string(errors[0].record));
232 CPPUNIT_ASSERT_EQUAL(0_st, errors[0].index);
233 CPPUNIT_ASSERT_EQUAL(JsonDeserializationErrorKind::TypeMismatch, errors[1].kind);
234 CPPUNIT_ASSERT_EQUAL(JsonType::Object, errors[1].expectedType);
235 CPPUNIT_ASSERT_EQUAL(JsonType::String, errors[1].actualType);
236 CPPUNIT_ASSERT_EQUAL(2_st, errors[1].index);
237 CPPUNIT_ASSERT_EQUAL(
"testObjects"s,
string(errors[1].member));
238 CPPUNIT_ASSERT_EQUAL(
"[document]"s,
string(errors[1].record));
239 CPPUNIT_ASSERT_EQUAL(JsonDeserializationErrorKind::TypeMismatch, errors[2].kind);
240 CPPUNIT_ASSERT_EQUAL(JsonType::Number, errors[2].expectedType);
241 CPPUNIT_ASSERT_EQUAL(JsonType::String, errors[2].actualType);
242 CPPUNIT_ASSERT_EQUAL(
"numbers"s,
string(errors[2].member));
243 CPPUNIT_ASSERT_EQUAL(
"[document]"s,
string(errors[2].record));
244 CPPUNIT_ASSERT_EQUAL(4_st, errors[2].index);
247 errors.
throwOn = JsonDeserializationErrors::ThrowOn::TypeMismatch;
void testHandlingTypeMismatch()
Tests whether JsonDeserializationError is thrown on type mismatch.
CPPUNIT_TEST_SUITE_REGISTRATION(JsonReflectorBoostHanaTests)
enum ReflectiveRapidJSON::JsonDeserializationErrors::ThrowOn throwOn
The JsonReflectorBoostHanaTests class tests the integration of Boost.Hana with the RapidJSON wrapper.
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.
The JsonDeserializationError struct describes any errors of fromJson() except such caused by invalid ...
void testDeserializeSimpleObjects()
Tests deserializing simple objects.
The JsonSerializable class provides the CRTP-base for (de)serializable objects.
void testDeserializeNestedObjects()
Tests deserializing nested objects and arrays.
void testSerializeSimpleObjects()
Tests serializing objects.
void testSerializeNestedObjects()
Tests serializing nested object and arrays.