diff --git a/CMakeLists.txt b/CMakeLists.txt index d25af07..aced62d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -16,8 +16,11 @@ set(META_APP_VERSION ${META_VERSION_MAJOR}.${META_VERSION_MINOR}.${META_VERSION_ # set project name for IDEs like Qt Creator project(${META_PROJECT_NAME}) +# ensure testing is enabled at this level (and not only for particular sub directories) +enable_testing() + # allow bundling c++utilities -set(BUNDLED_CPP_UTILITIES_PATH OFF CACHE FILEPATH "specifies the (relative) path to the c++utilities sources for building it together with ${META_PROJECT_NAME}") +set(BUNDLED_CPP_UTILITIES_PATH OFF CACHE PATH "specifies the (relative) path to the c++utilities sources for building it together with ${META_PROJECT_NAME}") if(NOT BUNDLED_CPP_UTILITIES_PATH) message(STATUS "Using system c++utilities") elseif(IS_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/${BUNDLED_CPP_UTILITIES_PATH}" OR IS_DIRECTORY "${BUNDLED_CPP_UTILITIES_PATH}") diff --git a/README.md b/README.md index 375273c..47787ea 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# reflective-rapidjson +# Reflective RapidJSON The main goal of this project is to provide a code generator for serializing/deserializing C++ objects to/from JSON using Clang and RapidJSON. @@ -131,9 +131,34 @@ makes use of the `reflective-rapidjson`. ### How to build Install all required dependencies and ensure the CMake script finds them. It is possible to build `c++utilities` -together `reflective-rapidjson` to ease the build process. The following build script makes use of this. To use -system `c++utilities`, just skip any lines with `c++utilities` in it. +together with `reflective-rapidjson` to simplify the build process. The following build script makes use of this. +To use system `c++utilities`, just skip any lines with "`c++utilities`" in the following examples. +Get sources, eg. using Git: ``` -TODO +cd $SOURCES +git clone https://github.com/Martchus/cpp-utilities.git c++utilities +git clone https://github.com/Martchus/reflective-rapidjson.git ``` + +If you don't want to build the development version, just checkout the desired version tag. + +Here is an example for building with CMake and GNU Make: +``` +cd $BUILD_DIR +# generate Makefile +cmake \ + -DCMAKE_BUILD_TYPE:STRING=Release \ + -DCMAKE_INSTALL_PREFIX:PATH="/final/install/prefix" \ + -DBUNDLED_CPP_UTILITIES_PATH:PATH="$SOURCES/c++utilities" \ + "$SOURCES/reflective-rapidjson" +# build library and generators +make +# run test (optional, requires CppUnit) +make check +# generates API documentation (optional, reqquires Doxygen) +make apidoc +# install header files, libraries and generator +make install DESTDIR="/temporary/install/location" +``` +Add eg. `-j$(nproc)` to `make` arguments for using all cores. diff --git a/generator/CMakeLists.txt b/generator/CMakeLists.txt index 29ee26a..5f91671 100644 --- a/generator/CMakeLists.txt +++ b/generator/CMakeLists.txt @@ -34,23 +34,27 @@ set(TEST_SRC_FILES tests/jsongenerator.cpp ) -# find c++utilities +# find c++utilities and link against the library find_package(c++utilities 4.11.0 REQUIRED) use_cpp_utilities() -# find libclang +# find Clang for LibTooling; adding clangTooling should be sufficient as it pulls all transitive dependencies find_package(Clang REQUIRED) list(APPEND PRIVATE_LIBRARIES clangTooling) -# also add reflective_rapidjson +# also add reflective_rapidjson which is header-only but might pull additional include dirs for RapidJSON list(APPEND PRIVATE_LIBRARIES reflective_rapidjson) -# trigger code generator for tests +# trigger code generator because the tests already contain structs to be (de)serialized include(ReflectionGenerator) add_reflection_generator_invocation( - INPUT_FILES tests/structs.h tests/cppunit.cpp - GENERATORS json - OUTPUT_LISTS TEST_HEADER_FILES + INPUT_FILES + tests/structs.h # used by test cases + tests/cppunit.cpp # just for testing multiple input files and the "empty file" case + GENERATORS + json + OUTPUT_LISTS + TEST_HEADER_FILES ) # include modules to apply configuration diff --git a/lib/CMakeLists.txt b/lib/CMakeLists.txt index 3d92426..2e79921 100644 --- a/lib/CMakeLists.txt +++ b/lib/CMakeLists.txt @@ -26,9 +26,20 @@ set(DOC_FILES README.md ) -# find c++utilities +# find c++utilities, but only add the include dirs because we're not depending on the actual library find_package(c++utilities 4.11.0 REQUIRED) -use_cpp_utilities() +list(APPEND PUBLIC_SHARED_INCLUDE_DIRS ${CPP_UTILITIES_INCLUDE_DIRS}) +list(APPEND PUBLIC_STATIC_INCLUDE_DIRS ${CPP_UTILITIES_INCLUDE_DIRS}) +list(APPEND CMAKE_MODULE_PATH ${CPP_UTILITIES_MODULE_DIRS}) + +# find RapidJSON, also add only the include dirs because RapidJSON is a header-only library +find_package(RapidJSON) +if(RapidJSON_FOUND) + list(APPEND PUBLIC_SHARED_INCLUDE_DIRS ${RAPIDJSON_INCLUDE_DIRS}) + list(APPEND PUBLIC_STATIC_INCLUDE_DIRS ${RAPIDJSON_INCLUDE_DIRS}) +else() + message(FATAL_ERROR "Unable to find RapidJSON. Since this is the only reflection application supported at this time it makes no sense to continue.") +endif() # include modules to apply configuration include(BasicConfig) diff --git a/lib/json/errorhandling.h b/lib/json/errorhandling.h index 620ab8b..23ed0fc 100644 --- a/lib/json/errorhandling.h +++ b/lib/json/errorhandling.h @@ -11,6 +11,7 @@ #include +#include #include #include #include diff --git a/lib/json/reflector.h b/lib/json/reflector.h index dad5305..4cbbb0b 100644 --- a/lib/json/reflector.h +++ b/lib/json/reflector.h @@ -23,7 +23,10 @@ namespace ReflectiveRapidJSON { template struct JsonSerializable; -inline RAPIDJSON_NAMESPACE::StringBuffer documentToString(RAPIDJSON_NAMESPACE::Document &document) +/*! + * \brief Serializes the specified JSON \a document. + */ +inline RAPIDJSON_NAMESPACE::StringBuffer serializeJsonDocToString(RAPIDJSON_NAMESPACE::Document &document) { RAPIDJSON_NAMESPACE::StringBuffer buffer; RAPIDJSON_NAMESPACE::Writer writer(buffer); @@ -31,7 +34,10 @@ inline RAPIDJSON_NAMESPACE::StringBuffer documentToString(RAPIDJSON_NAMESPACE::D return buffer; } -inline RAPIDJSON_NAMESPACE::Document parseDocumentFromString(const char *json, std::size_t jsonSize) +/*! + * \brief Parses the specified JSON string. + */ +inline RAPIDJSON_NAMESPACE::Document parseJsonDocFromString(const char *json, std::size_t jsonSize) { RAPIDJSON_NAMESPACE::Document document(RAPIDJSON_NAMESPACE::kObjectType); const RAPIDJSON_NAMESPACE::ParseResult parseRes = document.Parse(json, jsonSize); @@ -45,22 +51,35 @@ namespace Reflector { // define functions to "push" values to a RapidJSON array or object +/*! + * \brief Pushes the \a reflectable which has a custom type to the specified array. + */ template , std::is_floating_point, std::is_pointer, Traits::All, Traits::Not>>>...> void push(const Type &reflectable, RAPIDJSON_NAMESPACE::Value::Array &value, RAPIDJSON_NAMESPACE::Document::AllocatorType &allocator); +/*! + * \brief Pushes the \a reflectable which has a custom type to the specified object. + * \remarks The definition of this function must be provided by the code generator or Boost.Hana. + */ template , std::is_floating_point, std::is_pointer, Traits::All, Traits::Not>>>...> void push(const Type &reflectable, RAPIDJSON_NAMESPACE::Value::Object &value, RAPIDJSON_NAMESPACE::Document::AllocatorType &allocator); +/*! + * \brief Pushes the specified integer/float/boolean to the specified array. + */ template , std::is_floating_point, std::is_pointer>...> inline void push(Type reflectable, RAPIDJSON_NAMESPACE::Value::Array &value, RAPIDJSON_NAMESPACE::Document::AllocatorType &allocator) { value.PushBack(reflectable, allocator); } +/*! + * \brief Pushes the specified C-string to the specified array. + */ template <> inline void push( const char *reflectable, RAPIDJSON_NAMESPACE::Value::Array &value, RAPIDJSON_NAMESPACE::Document::AllocatorType &allocator) @@ -68,13 +87,9 @@ inline void push( value.PushBack(RAPIDJSON_NAMESPACE::StringRef(reflectable), allocator); } -template <> -inline void push( - const std::string &reflectable, RAPIDJSON_NAMESPACE::Value::Array &value, RAPIDJSON_NAMESPACE::Document::AllocatorType &allocator) -{ - value.PushBack(RAPIDJSON_NAMESPACE::StringRef(reflectable.data(), reflectable.size()), allocator); -} - +/*! + * \brief Pushes the specified constant C-string to the specified array. + */ template <> inline void push( const char *const &reflectable, RAPIDJSON_NAMESPACE::Value::Array &value, RAPIDJSON_NAMESPACE::Document::AllocatorType &allocator) @@ -82,6 +97,19 @@ inline void push( value.PushBack(RAPIDJSON_NAMESPACE::StringRef(reflectable), allocator); } +/*! + * \brief Pushes the specified std::string to the specified array. + */ +template <> +inline void push( + const std::string &reflectable, RAPIDJSON_NAMESPACE::Value::Array &value, RAPIDJSON_NAMESPACE::Document::AllocatorType &allocator) +{ + value.PushBack(RAPIDJSON_NAMESPACE::StringRef(reflectable.data(), reflectable.size()), allocator); +} + +/*! + * \brief Pushes the specified iteratable (eg. std::vector, std::list) to the specified array. + */ template , Traits::Not>>...> void push(const Type &reflectable, RAPIDJSON_NAMESPACE::Value::Array &value, RAPIDJSON_NAMESPACE::Document::AllocatorType &allocator) { @@ -94,6 +122,9 @@ void push(const Type &reflectable, RAPIDJSON_NAMESPACE::Value::Array &value, RAP value.PushBack(array, allocator); } +/*! + * \brief Pushes the specified \a reflectable which has a custom type as member to the specified object. + */ template , std::is_floating_point, std::is_pointer, Traits::All, Traits::Not>>>...> @@ -106,6 +137,9 @@ inline void push( value.AddMember(RAPIDJSON_NAMESPACE::StringRef(name), object, allocator); } +/*! + * \brief Pushes the specified integer/float/boolean as member to the specified object. + */ template , std::is_floating_point, std::is_pointer>...> inline void push( Type reflectable, const char *name, RAPIDJSON_NAMESPACE::Value::Object &value, RAPIDJSON_NAMESPACE::Document::AllocatorType &allocator) @@ -113,13 +147,9 @@ inline void push( value.AddMember(RAPIDJSON_NAMESPACE::StringRef(name), reflectable, allocator); } -template <> -inline void push(const std::string &reflectable, const char *name, RAPIDJSON_NAMESPACE::Value::Object &value, - RAPIDJSON_NAMESPACE::Document::AllocatorType &allocator) -{ - value.AddMember(RAPIDJSON_NAMESPACE::StringRef(name), RAPIDJSON_NAMESPACE::StringRef(reflectable.data(), reflectable.size()), allocator); -} - +/*! + * \brief Pushes the specified C-string as member to the specified object. + */ template <> inline void push( const char *reflectable, const char *name, RAPIDJSON_NAMESPACE::Value::Object &value, RAPIDJSON_NAMESPACE::Document::AllocatorType &allocator) @@ -127,6 +157,9 @@ inline void push( value.AddMember(RAPIDJSON_NAMESPACE::StringRef(name), RAPIDJSON_NAMESPACE::StringRef(reflectable), allocator); } +/*! + * \brief Pushes the specified constant C-string as member to the specified object. + */ template <> inline void push(const char *const &reflectable, const char *name, RAPIDJSON_NAMESPACE::Value::Object &value, RAPIDJSON_NAMESPACE::Document::AllocatorType &allocator) @@ -134,6 +167,19 @@ inline void push(const char *const &reflectable, const char value.AddMember(RAPIDJSON_NAMESPACE::StringRef(name), RAPIDJSON_NAMESPACE::StringRef(reflectable), allocator); } +/*! + * \brief Pushes the specified std::string as member to the specified object. + */ +template <> +inline void push(const std::string &reflectable, const char *name, RAPIDJSON_NAMESPACE::Value::Object &value, + RAPIDJSON_NAMESPACE::Document::AllocatorType &allocator) +{ + value.AddMember(RAPIDJSON_NAMESPACE::StringRef(name), RAPIDJSON_NAMESPACE::StringRef(reflectable.data(), reflectable.size()), allocator); +} + +/*! + * \brief Pushes the specified iteratable without size() method as member to the specified object. + */ template , Traits::Not>, Traits::Not>>...> @@ -148,6 +194,9 @@ void push( value.AddMember(RAPIDJSON_NAMESPACE::StringRef(name), array, allocator); } +/*! + * \brief Pushes the specified iteratable with size() method (eg. std::vector, std::list) as member to the specified object. + */ template , Traits::HasSize, Traits::Not>>...> void push( @@ -162,6 +211,9 @@ void push( value.AddMember(RAPIDJSON_NAMESPACE::StringRef(name), array, allocator); } +/*! + * \brief Pushes the \a reflectable which has a custom type to the specified array. + */ template , std::is_floating_point, std::is_pointer, Traits::All, Traits::Not>>>...> @@ -175,18 +227,28 @@ void push(const Type &reflectable, RAPIDJSON_NAMESPACE::Value::Array &value, RAP // define functions to "pull" values from a RapidJSON array or object +/*! + * \brief Pulls the \a reflectable which has a custom type from the specified value. + */ template , std::is_floating_point, std::is_pointer, Traits::All, Traits::Not>>>...> void pull( Type &reflectable, RAPIDJSON_NAMESPACE::GenericValue>::ValueIterator &value, JsonDeserializationErrors *errors); +/*! + * \brief Pulls the \a reflectable which has a custom type from the specified object. + * \remarks The definition of this function must be provided by the code generator or Boost.Hana. + */ template , std::is_floating_point, std::is_pointer, Traits::All, Traits::Not>>>...> void pull(Type &reflectable, const RAPIDJSON_NAMESPACE::GenericValue>::ConstObject &value, JsonDeserializationErrors *errors); +/*! + * \brief Pulls the \a reflectable which has a custom type from the specified value which is supposed and checked to contain an object. + */ template , std::is_floating_point, std::is_pointer, Traits::All, Traits::Not>>>...> @@ -201,6 +263,9 @@ void pull(Type &reflectable, const RAPIDJSON_NAMESPACE::GenericValue(reflectable, value.GetObject(), errors); } +/*! + * \brief Pulls the integer/float/boolean from the specified value iterator which is supposed and checked to contain the right type. + */ template , std::is_floating_point, std::is_pointer>...> inline void pull( Type &reflectable, RAPIDJSON_NAMESPACE::GenericValue>::ValueIterator &value, JsonDeserializationErrors *errors) @@ -215,6 +280,9 @@ inline void pull( ++value; } +/*! + * \brief Pulls the integer/float/boolean from the specified value which is supposed and checked to contain the right type. + */ template , std::is_floating_point, std::is_pointer>...> inline void pull( Type &reflectable, const RAPIDJSON_NAMESPACE::GenericValue> &value, JsonDeserializationErrors *errors) @@ -228,6 +296,9 @@ inline void pull( reflectable = value.Get(); } +/*! + * \brief Pulls the std::string from the specified value iterator which is supposed and checked to contain a string. + */ template <> inline void pull(std::string &reflectable, RAPIDJSON_NAMESPACE::GenericValue>::ValueIterator &value, JsonDeserializationErrors *errors) @@ -242,6 +313,9 @@ inline void pull(std::string &reflectable, RAPIDJSON_NAMESPACE::Gen ++value; } +/*! + * \brief Pulls the std::string from the specified value which is supposed and checked to contain a string. + */ template <> inline void pull( std::string &reflectable, const RAPIDJSON_NAMESPACE::GenericValue> &value, JsonDeserializationErrors *errors) @@ -255,9 +329,15 @@ inline void pull( reflectable = value.GetString(); } +/*! + * \brief Pulls the speciified \a reflectable which is an iteratable from the specified array. The \a reflectable is cleared before. + */ template , Traits::Not>>...> void pull(Type &reflectable, rapidjson::GenericValue>::ConstArray array, JsonDeserializationErrors *errors); +/*! + * \brief Pulls the speciified \a reflectable which is an iteratable without reserve() method from the specified value iterator which is checked to contain an array. + */ template , Traits::Not>, Traits::Not>>...> @@ -273,6 +353,9 @@ void pull(Type &reflectable, rapidjson::GenericValue, Traits::IsReservable, Traits::Not>>...> void pull(Type &reflectable, rapidjson::GenericValue>::ValueIterator &value, JsonDeserializationErrors *errors) @@ -289,6 +372,9 @@ void pull(Type &reflectable, rapidjson::GenericValue, Traits::Not>, Traits::Not>>...> @@ -303,6 +389,9 @@ void pull(Type &reflectable, const rapidjson::GenericValue, Traits::IsReservable, Traits::Not>>...> void pull(Type &reflectable, const rapidjson::GenericValue> &value, JsonDeserializationErrors *errors) @@ -318,6 +407,9 @@ void pull(Type &reflectable, const rapidjson::GenericValue, Traits::Not>>...> void pull(Type &reflectable, rapidjson::GenericValue>::ConstArray array, JsonDeserializationErrors *errors) { @@ -342,6 +434,11 @@ void pull(Type &reflectable, rapidjson::GenericValue inline void pull(Type &reflectable, const char *name, const rapidjson::GenericValue>::ConstObject &value, JsonDeserializationErrors *errors) @@ -370,44 +467,59 @@ inline void pull(Type &reflectable, const char *name, const rapidjson::GenericVa // define functions providing high-level JSON serialization +/*! + * \brief Serializes the specified \a reflectable which has a custom type. + */ template , Type>>...> RAPIDJSON_NAMESPACE::StringBuffer toJson(const Type &reflectable) { RAPIDJSON_NAMESPACE::Document document(RAPIDJSON_NAMESPACE::kObjectType); RAPIDJSON_NAMESPACE::Document::Object object(document.GetObject()); push(reflectable, object, document.GetAllocator()); - return documentToString(document); + return serializeJsonDocToString(document); } +/*! + * \brief Serializes the specified \a reflectable which is an integer, float or boolean. + */ template , std::is_floating_point>...> RAPIDJSON_NAMESPACE::StringBuffer toJson(Type reflectable) { RAPIDJSON_NAMESPACE::Document document(RAPIDJSON_NAMESPACE::kNumberType); document.Set(reflectable, document.GetAllocator()); - return documentToString(document); + return serializeJsonDocToString(document); } +/*! + * \brief Serializes the specified \a reflectable which is an std::string. + */ template >...> RAPIDJSON_NAMESPACE::StringBuffer toJson(const std::string &reflectable) { RAPIDJSON_NAMESPACE::Document document(RAPIDJSON_NAMESPACE::kStringType); document.SetString(RAPIDJSON_NAMESPACE::StringRef(reflectable.data(), reflectable.size()), document.GetAllocator()); - return documentToString(document); + return serializeJsonDocToString(document); } +/*! + * \brief Serializes the specified \a reflectable which is a C-string. + */ template >...> RAPIDJSON_NAMESPACE::StringBuffer toJson(const char *reflectable) { RAPIDJSON_NAMESPACE::Document document(RAPIDJSON_NAMESPACE::kStringType); document.SetString(RAPIDJSON_NAMESPACE::StringRef(reflectable), document.GetAllocator()); - return documentToString(document); + return serializeJsonDocToString(document); } // define functions providing high-level JSON deserialization +/*! + * \brief Deserializes the specified JSON to \tparam Type which is a custom type. + */ template , Type>>...> Type fromJson(const char *json, std::size_t jsonSize, JsonDeserializationErrors *errors = nullptr) { - RAPIDJSON_NAMESPACE::Document doc(parseDocumentFromString(json, jsonSize)); + RAPIDJSON_NAMESPACE::Document doc(parseJsonDocFromString(json, jsonSize)); if (!doc.IsObject()) { if (errors) { errors->reportTypeMismatch(doc.GetType()); @@ -420,10 +532,13 @@ Type fromJson(const char *json, std::size_t jsonSize, JsonDeserializationErrors return res; } +/*! + * \brief Deserializes the specified JSON to \tparam Type which is an integer, float or boolean. + */ template , std::is_floating_point>...> Type fromJson(const char *json, std::size_t jsonSize, JsonDeserializationErrors *errors) { - RAPIDJSON_NAMESPACE::Document doc(parseDocumentFromString(json, jsonSize)); + RAPIDJSON_NAMESPACE::Document doc(parseJsonDocFromString(json, jsonSize)); if (!doc.Is()) { if (errors) { errors->reportTypeMismatch(doc.GetType()); @@ -434,10 +549,13 @@ Type fromJson(const char *json, std::size_t jsonSize, JsonDeserializationErrors return doc.Get(); } +/*! + * \brief Deserializes the specified JSON to \tparam Type which is a std::string. + */ template >...> Type fromJson(const char *json, std::size_t jsonSize, JsonDeserializationErrors *errors) { - RAPIDJSON_NAMESPACE::Document doc(parseDocumentFromString(json, jsonSize)); + RAPIDJSON_NAMESPACE::Document doc(parseJsonDocFromString(json, jsonSize)); if (!doc.IsString()) { if (errors) { errors->reportTypeMismatch(doc.GetType()); @@ -448,6 +566,9 @@ Type fromJson(const char *json, std::size_t jsonSize, JsonDeserializationErrors return doc.GetString(); } +/*! + * \brief Deserializes the specified JSON from an std::string to \tparam Type. + */ template Type fromJson(const std::string &json) { return fromJson(json.data(), json.size()); diff --git a/lib/tests/jsonreflector-boosthana.cpp b/lib/tests/jsonreflector-boosthana.cpp index 75bfaf9..fe8d994 100644 --- a/lib/tests/jsonreflector-boosthana.cpp +++ b/lib/tests/jsonreflector-boosthana.cpp @@ -31,11 +31,6 @@ using namespace ReflectiveRapidJSON; // define some structs for testing serialization struct TestObjectHana : public JsonSerializable { - //TestObjectHana(){}; - //TestObjectHana(const TestObjectHana &) - //{ - // std::cout << "copied!!" << std::endl; - //}; BOOST_HANA_DEFINE_STRUCT(TestObjectHana, (int, number), (double, number2), (vector, numbers), (string, text), (bool, boolean)); }; @@ -50,15 +45,13 @@ struct NestingArrayHana : public JsonSerializable { /// \endcond /*! - * \brief The ReflectorTests class tests RapidJSON wrapper which is used to ease code generation. - * \remarks In this tests, no reflection or code generation is involved yet. + * \brief The JsonReflectorBoostHanaTests class tests the integration of Boost.Hana with the RapidJSON wrapper. + * \remarks In these tests, the reflection is provided through Boost.Hana so the code generator is not involved. */ -class JSONReflectorBoostHanaTests : public TestFixture { - CPPUNIT_TEST_SUITE(JSONReflectorBoostHanaTests); - CPPUNIT_TEST(testSerializePrimitives); +class JsonReflectorBoostHanaTests : public TestFixture { + CPPUNIT_TEST_SUITE(JsonReflectorBoostHanaTests); CPPUNIT_TEST(testSerializeSimpleObjects); CPPUNIT_TEST(testSerializeNestedObjects); - CPPUNIT_TEST(testDeserializePrimitives); CPPUNIT_TEST(testDeserializeSimpleObjects); CPPUNIT_TEST(testDeserializeNestedObjects); CPPUNIT_TEST(testHandlingTypeMismatch); @@ -79,51 +72,20 @@ public: private: }; -CPPUNIT_TEST_SUITE_REGISTRATION(JSONReflectorBoostHanaTests); +CPPUNIT_TEST_SUITE_REGISTRATION(JsonReflectorBoostHanaTests); -void JSONReflectorBoostHanaTests::setUp() +void JsonReflectorBoostHanaTests::setUp() { } -void JSONReflectorBoostHanaTests::tearDown() +void JsonReflectorBoostHanaTests::tearDown() { } -/*! - * \brief Tests serializing strings, numbers, arrays and boolean. - */ -void JSONReflectorBoostHanaTests::testSerializePrimitives() -{ - Document doc(kArrayType); - Document::AllocatorType &alloc = doc.GetAllocator(); - doc.SetArray(); - Document::Array array(doc.GetArray()); - - // string - Reflector::push("foo"s, array, alloc); - Reflector::push("bar", array, alloc); - // number - Reflector::push(25, array, alloc); - Reflector::push(12.5, array, alloc); - // array - Reflector::push>({ "foo1", "bar1" }, array, alloc); - Reflector::push>({ "foo2", "bar2" }, array, alloc); - Reflector::push>({ "foo3", "bar3" }, array, alloc); - // boolean - Reflector::push(true, array, alloc); - Reflector::push(false, array, alloc); - - StringBuffer strbuf; - Writer jsonWriter(strbuf); - doc.Accept(jsonWriter); - CPPUNIT_ASSERT_EQUAL( - "[\"foo\",\"bar\",25,12.5,[\"foo1\",\"bar1\"],[\"foo2\",\"bar2\"],[\"foo3\",\"bar3\"],true,false]"s, string(strbuf.GetString())); -} - /*! * \brief Tests serializing objects. */ -void JSONReflectorBoostHanaTests::testSerializeSimpleObjects() +void JsonReflectorBoostHanaTests::testSerializeSimpleObjects() { TestObjectHana testObj; testObj.number = 42; @@ -138,7 +100,7 @@ void JSONReflectorBoostHanaTests::testSerializeSimpleObjects() /*! * \brief Tests serializing nested object and arrays. */ -void JSONReflectorBoostHanaTests::testSerializeNestedObjects() +void JsonReflectorBoostHanaTests::testSerializeNestedObjects() { NestingObjectHana nestingObj; nestingObj.name = "nesting"; @@ -161,43 +123,10 @@ void JSONReflectorBoostHanaTests::testSerializeNestedObjects() string(nestingArray.toJson().GetString())); } -/*! - * \brief Tests deserializing strings, numbers (int, float, double) and boolean. - */ -void JSONReflectorBoostHanaTests::testDeserializePrimitives() -{ - Document doc(kArrayType); - - doc.Parse("[\"a\", 5, 5e6, \"test\", true, 4.125, false]"); - auto array = doc.GetArray().begin(); - - string str1, str2; - int int1 = 0; - bool bool1 = false, bool2 = true; - float float1 = 0.0; - double double1 = 0.0; - JsonDeserializationErrors errors; - Reflector::pull(str1, array, &errors); - Reflector::pull(int1, array, &errors); - Reflector::pull(float1, array, &errors); - Reflector::pull(str2, array, &errors); - Reflector::pull(bool1, array, &errors); - Reflector::pull(double1, array, &errors); - Reflector::pull(bool2, array, &errors); - - CPPUNIT_ASSERT_EQUAL("a"s, str1); - CPPUNIT_ASSERT_EQUAL(5, int1); - CPPUNIT_ASSERT_EQUAL(5e6f, float1); - CPPUNIT_ASSERT_EQUAL("test"s, str2); - CPPUNIT_ASSERT_EQUAL(true, bool1); - CPPUNIT_ASSERT_EQUAL(4.125, double1); - CPPUNIT_ASSERT_EQUAL(false, bool2); -} - /*! * \brief Tests deserializing simple objects. */ -void JSONReflectorBoostHanaTests::testDeserializeSimpleObjects() +void JsonReflectorBoostHanaTests::testDeserializeSimpleObjects() { const TestObjectHana testObj( TestObjectHana::fromJson("{\"number\":42,\"number2\":3.141592653589793,\"numbers\":[1,2,3,4],\"text\":\"test\",\"boolean\":false}")); @@ -212,7 +141,7 @@ void JSONReflectorBoostHanaTests::testDeserializeSimpleObjects() /*! * \brief Tests deserializing nested objects and arrays. */ -void JSONReflectorBoostHanaTests::testDeserializeNestedObjects() +void JsonReflectorBoostHanaTests::testDeserializeNestedObjects() { const NestingObjectHana nestingObj(NestingObjectHana::fromJson("{\"name\":\"nesting\",\"testObj\":{\"number\":42,\"number2\":3.141592653589793," "\"numbers\":[1,2,3,4],\"text\":\"test\",\"boolean\":false}}")); @@ -244,7 +173,7 @@ void JSONReflectorBoostHanaTests::testDeserializeNestedObjects() /*! * \brief Tests whether JsonDeserializationError is thrown on type mismatch. */ -void JSONReflectorBoostHanaTests::testHandlingTypeMismatch() +void JsonReflectorBoostHanaTests::testHandlingTypeMismatch() { JsonDeserializationErrors errors; NestingArrayHana::fromJson("{\"name\":\"nesting2\",\"testObjects\":[{\"number\":42,\"number2\":3.141592653589793," diff --git a/lib/tests/jsonreflector.cpp b/lib/tests/jsonreflector.cpp index 472d1c9..2671de6 100644 --- a/lib/tests/jsonreflector.cpp +++ b/lib/tests/jsonreflector.cpp @@ -129,11 +129,11 @@ inline void pull(NestingArray &reflectable, const GenericValue