Browse Source

Add SerializableJSONEvent class

- add SerializableJSONEvent class to serialize an
instance of Event class
- add tests for SerializableJSONEvent class
- extend Event class by adding missing setter and
parameter list clear functionality
Patrick-Laptop 3 years ago
parent
commit
0e6cc3a694

+ 4 - 2
CMakeLists.txt

@@ -92,7 +92,8 @@ set(SOURCE_FILES
         ${CMAKE_CURRENT_SOURCE_DIR}/source/ls_std/event/Event.cpp
         ${CMAKE_CURRENT_SOURCE_DIR}/source/ls_std/event/EventHandler.cpp
         ${CMAKE_CURRENT_SOURCE_DIR}/source/ls_std/event/EventManager.cpp
-        ${CMAKE_CURRENT_SOURCE_DIR}/source/ls_std/network/Socket.cpp)
+        ${CMAKE_CURRENT_SOURCE_DIR}/source/ls_std/network/Socket.cpp
+        ${CMAKE_CURRENT_SOURCE_DIR}/source/ls_std/serialization/json/event/SerializableJSONEvent.cpp)
 
 if (${LS_STD_BUILD_WITH_TESTS})
     set(TEST_FILES
@@ -147,7 +148,8 @@ if (${LS_STD_BUILD_WITH_TESTS})
             ${CMAKE_CURRENT_SOURCE_DIR}/test/classes/event/GossipNewsAgency.cpp
             ${CMAKE_CURRENT_SOURCE_DIR}/test/cases/event/EventHandlerTest.cpp
             ${CMAKE_CURRENT_SOURCE_DIR}/test/cases/event/EventManagerTest.cpp
-            ${CMAKE_CURRENT_SOURCE_DIR}/test/cases/network/SocketTest.cpp)
+            ${CMAKE_CURRENT_SOURCE_DIR}/test/cases/network/SocketTest.cpp
+            ${CMAKE_CURRENT_SOURCE_DIR}/test/cases/serialization/json/event/SerializableJSONEventTest.cpp)
 endif ()
 
 ##########################################################

+ 4 - 1
include/ls_std/event/Event.hpp

@@ -3,7 +3,7 @@
  * Company:         Lynar Studios
  * E-Mail:          webmaster@lynarstudios.com
  * Created:         2020-11-26
- * Changed:         2020-11-29
+ * Changed:         2020-12-20
  *
  * */
 
@@ -21,15 +21,18 @@ namespace ls_std {
       ~Event() override = default;
 
       void addParameter(const ls_std::event_parameter& _eventParameter);
+      void clearParameterList();
       ls_std::event_id getId();
       ls_std::event_parameter_list getParameterList();
       void removeParameter(const ls_std::event_parameter_id& _id);
+      void setId(ls_std::event_id  _id);
 
     private:
 
       ls_std::event_id id {};
       ls_std::event_parameter_list parameterList {};
 
+      void _assignId(ls_std::event_id _id);
       bool _hasParameter(const ls_std::event_id&  _id);
   };
 }

+ 2 - 1
include/ls_std/ls_std.hpp

@@ -3,7 +3,7 @@
  * Company:         Lynar Studios
  * E-Mail:          webmaster@lynarstudios.com
  * Created:         2020-10-29
- * Changed:         2020-12-06
+ * Changed:         2020-12-20
  *
  * */
 
@@ -68,6 +68,7 @@
 #include "serialization/logic/SerializableJSONState.hpp"
 #include "serialization/logic/SerializableJSONStateConnection.hpp"
 #include "serialization/logic/SerializableJSONStateMachine.hpp"
+#include "serialization/event/SerializableJSONEvent.hpp"
 #include "serialization/ISerializable.hpp"
 
 #include "time/Date.hpp"

+ 48 - 0
include/ls_std/serialization/event/SerializableJSONEvent.hpp

@@ -0,0 +1,48 @@
+/*
+ * Author:          Patrick-Christopher Mattulat
+ * Company:         Lynar Studios
+ * E-Mail:          webmaster@lynarstudios.com
+ * Created:         2020-12-07
+ * Changed:         2020-12-20
+ *
+ * */
+
+#ifndef LS_STD_SERIALIZABLE_JSON_EVENT_HPP
+#define LS_STD_SERIALIZABLE_JSON_EVENT_HPP
+
+#include <ls_std/serialization/ISerializable.hpp>
+#include <ls_std/base/Class.hpp>
+#include <ls_std/event/Event.hpp>
+#include <memory>
+#include <ls_std/lib/nlohmann_json/include/nlohmann/json.hpp>
+
+namespace ls_std {
+  class SerializableJSONEvent : public ls_std::Class, public ls_std::ISerializable {
+    public:
+
+      explicit SerializableJSONEvent(const std::shared_ptr<ls_std::Event>& _value);
+      ~SerializableJSONEvent() override = default;
+
+      // implementation
+
+      ls_std::byte_field marshal() override;
+      void unmarshal(const ls_std::byte_field& _data) override;
+
+      // additional functionality
+
+      std::shared_ptr<ls_std::Event> getValue();
+      void setValue(const std::shared_ptr<ls_std::Event>& _value);
+
+    private:
+
+      nlohmann::json jsonObject {};
+      std::shared_ptr<ls_std::Event> value {};
+
+      void _assignValue(const std::shared_ptr<ls_std::Event>& _value);
+      void _unmarshalParameterList();
+      void _update();
+      void _updateEventParameterList();
+  };
+}
+
+#endif

+ 25 - 4
source/ls_std/event/Event.cpp

@@ -3,15 +3,17 @@
  * Company:         Lynar Studios
  * E-Mail:          webmaster@lynarstudios.com
  * Created:         2020-11-26
- * Changed:         2020-11-29
+ * Changed:         2020-12-20
  *
  * */
 
 #include <ls_std/event/Event.hpp>
+#include <ls_std/exception/IllegalArgumentException.hpp>
 
-ls_std::Event::Event(ls_std::event_id _id) : ls_std::Class("Event"),
-id(std::move(_id))
-{}
+ls_std::Event::Event(ls_std::event_id _id) : ls_std::Class("Event")
+{
+  this->_assignId(std::move(_id));
+}
 
 void ls_std::Event::addParameter(const ls_std::event_parameter &_eventParameter)
 {
@@ -20,6 +22,11 @@ void ls_std::Event::addParameter(const ls_std::event_parameter &_eventParameter)
   }
 }
 
+void ls_std::Event::clearParameterList()
+{
+  this->parameterList.clear();
+}
+
 ls_std::event_id ls_std::Event::getId()
 {
   return this->id;
@@ -37,6 +44,20 @@ void ls_std::Event::removeParameter(const ls_std::event_parameter_id &_id)
   }
 }
 
+void ls_std::Event::setId(ls_std::event_id  _id)
+{
+  this->_assignId(std::move(_id));
+}
+
+void ls_std::Event::_assignId(ls_std::event_id _id)
+{
+  if(_id.empty()) {
+    throw ls_std::IllegalArgumentException {};
+  }
+
+  this->id = _id;
+}
+
 bool ls_std::Event::_hasParameter(const ls_std::event_id &_id)
 {
   return this->parameterList.find(_id) != this->parameterList.end();

+ 79 - 0
source/ls_std/serialization/json/event/SerializableJSONEvent.cpp

@@ -0,0 +1,79 @@
+/*
+ * Author:          Patrick-Christopher Mattulat
+ * Company:         Lynar Studios
+ * E-Mail:          webmaster@lynarstudios.com
+ * Created:         2020-12-07
+ * Changed:         2020-12-20
+ *
+ * */
+
+#include <ls_std/serialization/event/SerializableJSONEvent.hpp>
+#include <ls_std/exception/NullPointerException.hpp>
+
+ls_std::SerializableJSONEvent::SerializableJSONEvent(const std::shared_ptr<ls_std::Event>& _value) :
+ls_std::Class("SerializableJSONEvent")
+{
+  this->_assignValue(_value);
+}
+
+ls_std::byte_field ls_std::SerializableJSONEvent::marshal()
+{
+  this->_update();
+  return this->jsonObject.dump();
+}
+
+void ls_std::SerializableJSONEvent::unmarshal(const ls_std::byte_field &_data)
+{
+  this->jsonObject = nlohmann::json::parse(_data);
+
+  this->value->setId(this->jsonObject["id"]);
+  this->_unmarshalParameterList();
+}
+
+std::shared_ptr<ls_std::Event> ls_std::SerializableJSONEvent::getValue()
+{
+  return this->value;
+}
+
+void ls_std::SerializableJSONEvent::setValue(const std::shared_ptr<ls_std::Event>& _value)
+{
+  this->_assignValue(_value);
+}
+
+void ls_std::SerializableJSONEvent::_assignValue(const std::shared_ptr<ls_std::Event> &_value)
+{
+  if(_value == nullptr) {
+    throw ls_std::NullPointerException {};
+  }
+
+  this->value = _value;
+}
+
+void ls_std::SerializableJSONEvent::_unmarshalParameterList()
+{
+  this->value->clearParameterList();
+
+  for(const auto& parameterJSON : this->jsonObject["parameterList"]) {
+    ls_std::event_parameter parameter = {parameterJSON.at(0), parameterJSON.at(1)};
+    this->value->addParameter(parameter);
+  }
+}
+
+void ls_std::SerializableJSONEvent::_update()
+{
+  this->jsonObject = {
+      {"id", this->value->getId()}
+  };
+
+  this->_updateEventParameterList();
+}
+
+void ls_std::SerializableJSONEvent::_updateEventParameterList()
+{
+  std::string jsonString {};
+
+  for(const auto& eventParameter : this->value->getParameterList()) {
+    nlohmann::json parameterJson = {eventParameter.first, eventParameter.second};
+    this->jsonObject["parameterList"][eventParameter.first] = parameterJson;
+  }
+}

+ 22 - 1
test/cases/event/EventTest.cpp

@@ -3,7 +3,7 @@
  * Company:         Lynar Studios
  * E-Mail:          webmaster@lynarstudios.com
  * Created:         2020-11-26
- * Changed:         2020-11-26
+ * Changed:         2020-12-20
  *
  * */
 
@@ -45,6 +45,18 @@ namespace {
     ASSERT_STREQ("yes", parameterList.at("facing_door").c_str());
   }
 
+  TEST_F(EventTest, clearParameterList)
+  {
+    ls_std::Event event {"OPEN_DOOR_EVENT"};
+    event.addParameter(ls_std::event_parameter("key", "yes"));
+    event.addParameter(ls_std::event_parameter("facing_door", "yes"));
+    ASSERT_EQ(2, event.getParameterList().size());
+
+    event.clearParameterList();
+    ASSERT_TRUE(event.getParameterList().empty());
+    ASSERT_EQ(0, event.getParameterList().size());
+  }
+
   TEST_F(EventTest, getId)
   {
     ls_std::Event event {"OPEN_DOOR_EVENT"};
@@ -73,4 +85,13 @@ namespace {
     ASSERT_EQ(0, event.getParameterList().size());
     ASSERT_TRUE(event.getParameterList().empty());
   }
+
+  TEST_F(EventTest, setId)
+  {
+    ls_std::Event event {"OPEN_DOOR_EVENT"};
+    ASSERT_STREQ("OPEN_DOOR_EVENT", event.getId().c_str());
+
+    event.setId("ANOTHER_EVENT");
+    ASSERT_STREQ("ANOTHER_EVENT", event.getId().c_str());
+  }
 }

+ 55 - 0
test/cases/serialization/json/event/SerializableJSONEventTest.cpp

@@ -0,0 +1,55 @@
+/*
+ * Author:          Patrick-Christopher Mattulat
+ * Company:         Lynar Studios
+ * E-Mail:          webmaster@lynarstudios.com
+ * Created:         2020-12-20
+ * Changed:         2020-12-20
+ *
+ * */
+
+#include <gtest/gtest.h>
+#include <ls_std/ls_std.hpp>
+
+namespace
+{
+  class SerializableJSONEventTest : public ::testing::Test
+  {
+    protected:
+
+      SerializableJSONEventTest() = default;
+      ~SerializableJSONEventTest() override = default;
+
+      void SetUp() override {}
+      void TearDown() override {}
+  };
+
+  TEST_F(SerializableJSONEventTest, marshal)
+  {
+    ls_std::Event event {"OPEN_DOOR_EVENT"};
+    event.addParameter(ls_std::event_parameter{"key_available", "true"});
+    event.addParameter(ls_std::event_parameter{"door_id", "16675"});
+
+    ls_std::SerializableJSONEvent serializable {std::make_shared<ls_std::Event>(event)};
+
+    ls_std::byte_field data = serializable.marshal();
+    ASSERT_FALSE(data.empty());
+    std::string expectedString = R"({"id":"OPEN_DOOR_EVENT","parameterList":{"door_id":["door_id","16675"],"key_available":["key_available","true"]}})";
+    ASSERT_STREQ(expectedString.c_str(), data.c_str());
+  }
+
+  TEST_F(SerializableJSONEventTest, unmarshal)
+  {
+    ls_std::Event event {"TMP_EVENT"};
+    ls_std::SerializableJSONEvent serializable {std::make_shared<ls_std::Event>(event)};
+    std::string jsonString = R"({"id":"OPEN_DOOR_EVENT","parameterList":{"door_id":["door_id","16675"],"key_available":["key_available","true"]}})";
+
+    serializable.unmarshal(jsonString);
+    ASSERT_STREQ("OPEN_DOOR_EVENT", serializable.getValue()->getId().c_str());
+    ls_std::event_parameter_list parameterList = serializable.getValue()->getParameterList();
+
+    ASSERT_FALSE(parameterList.empty());
+    ASSERT_EQ(2, parameterList.size());
+    ASSERT_STREQ("16675", parameterList.at("door_id").c_str());
+    ASSERT_STREQ("true", parameterList.at("key_available").c_str());
+  }
+}