Browse Source

Added SerializableXMLStateConnection class

- added SerializableXMLStateConnection class to
provide functionality to serialize StateConnection
class by using XML
- added tests for SerializableXMLStateConnection
class
Patrick-Laptop 4 năm trước cách đây
mục cha
commit
ef5e23cdc1

+ 4 - 1
CMakeLists.txt

@@ -107,6 +107,8 @@ set(SOURCE_FILES
         ${CMAKE_CURRENT_SOURCE_DIR}/source/serialization/json/logic/SerializableJSONState.cpp
         ${CMAKE_CURRENT_SOURCE_DIR}/source/serialization/json/logic/SerializableJSONStateMachine.hpp
         ${CMAKE_CURRENT_SOURCE_DIR}/source/serialization/json/logic/SerializableJSONStateMachine.cpp
+        ${CMAKE_CURRENT_SOURCE_DIR}/source/serialization/xml/logic/SerializableXMLStateConnection.hpp
+        ${CMAKE_CURRENT_SOURCE_DIR}/source/serialization/xml/logic/SerializableXMLStateConnection.cpp
         )
 
 set(LIBRARY_SOURCE_FILES
@@ -148,7 +150,8 @@ set(TEST_FILES
         ${CMAKE_CURRENT_SOURCE_DIR}/test/TestDataFactory.hpp
         ${CMAKE_CURRENT_SOURCE_DIR}/test/TestDataFactory.cpp
         ${CMAKE_CURRENT_SOURCE_DIR}/test/cases/serialization/xml/RapidXMLTest.cpp
-        ${CMAKE_CURRENT_SOURCE_DIR}/test/cases/serialization/xml/TinyXMLTest.cpp)
+        ${CMAKE_CURRENT_SOURCE_DIR}/test/cases/serialization/xml/TinyXMLTest.cpp
+        ${CMAKE_CURRENT_SOURCE_DIR}/test/cases/serialization/xml/logic/SerializableXMLStateConnectionTest.cpp)
 
 ##########################################################
 # Build

+ 90 - 0
source/serialization/xml/logic/SerializableXMLStateConnection.cpp

@@ -0,0 +1,90 @@
+/*
+ * Author:          Patrick-Christopher Mattulat
+ * Company:         Lynar Studios
+ * E-Mail:          webmaster@lynarstudios.com
+ * Created:         2020-09-20
+ * Changed:         2020-09-20
+ *
+ * */
+
+#include "SerializableXMLStateConnection.hpp"
+#include "../../../boxing/String.hpp"
+#include "../../../boxing/Boolean.hpp"
+
+ls_std::SerializableXMLStateConnection::SerializableXMLStateConnection(std::shared_ptr<StateConnection> _value) :
+Class("SerializableXMLStateConnection"),
+value(std::move(_value))
+{}
+
+ls_std::byte_field ls_std::SerializableXMLStateConnection::marshal()
+{
+  this->_update();
+  tinyxml2::XMLPrinter printer {};
+  this->document.Print(&printer);
+  return ls_std::byte_field(printer.CStr());
+}
+
+void ls_std::SerializableXMLStateConnection::unmarshal(const ls_std::byte_field &_data)
+{
+  ls_std::String data {_data};
+  this->document.Parse(data.getByteData().data());
+  this->_unmarshalConnectionId();
+  this->_unmarshalCondition();
+  this->_unmarshalId();
+}
+
+std::shared_ptr<ls_std::StateConnection> ls_std::SerializableXMLStateConnection::getValue()
+{
+  return this->value;
+}
+
+void ls_std::SerializableXMLStateConnection::setValue(std::shared_ptr<StateConnection> _value)
+{
+  this->value = std::move(_value);
+  this->_clear();
+}
+
+void ls_std::SerializableXMLStateConnection::_clear()
+{
+  this->document.Clear();
+}
+
+void ls_std::SerializableXMLStateConnection::_unmarshalCondition()
+{
+  ls_std::Boolean condition {};
+  const tinyxml2::XMLAttribute *attribute = this->document.RootElement()->FindAttribute("condition");
+
+  if(attribute != nullptr) {
+    condition.parse(attribute->Value());
+    this->value->updatePassCondition(condition.getValue());
+  }
+}
+
+void ls_std::SerializableXMLStateConnection::_unmarshalConnectionId()
+{
+  const tinyxml2::XMLAttribute *attribute = this->document.RootElement()->FindAttribute("connectionId");
+
+  if(attribute != nullptr) {
+    this->value->setConnectionId(attribute->Value());
+  }
+}
+
+void ls_std::SerializableXMLStateConnection::_unmarshalId()
+{
+  const tinyxml2::XMLAttribute *attribute = this->document.RootElement()->FindAttribute("id");
+
+  if(attribute != nullptr) {
+    this->value->setStateId(attribute->Value());
+  }
+}
+
+void ls_std::SerializableXMLStateConnection::_update()
+{
+  this->_clear();
+  tinyxml2::XMLNode* root = this->document.NewElement("connection");
+  this->document.InsertFirstChild(root);
+
+  root->ToElement()->SetAttribute("connectionId", this->value->getConnectionId().c_str());
+  root->ToElement()->SetAttribute("id", this->value->getStateId().c_str());
+  root->ToElement()->SetAttribute("condition", this->value->isPassable());
+}

+ 49 - 0
source/serialization/xml/logic/SerializableXMLStateConnection.hpp

@@ -0,0 +1,49 @@
+/*
+ * Author:          Patrick-Christopher Mattulat
+ * Company:         Lynar Studios
+ * E-Mail:          webmaster@lynarstudios.com
+ * Created:         2020-09-20
+ * Changed:         2020-09-20
+ *
+ * */
+
+#ifndef LS_STD_SERIALIZABLE_XML_STATE_CONNECTION_HPP
+#define LS_STD_SERIALIZABLE_XML_STATE_CONNECTION_HPP
+
+#include "../../../base/Class.hpp"
+#include "../../ISerializable.hpp"
+#include "../../../logic/StateConnection.hpp"
+#include <memory>
+#include <tinyxml2.h>
+
+namespace ls_std {
+  class SerializableXMLStateConnection : public Class, public ISerializable {
+    public:
+
+      explicit SerializableXMLStateConnection(std::shared_ptr<StateConnection> _value);
+      ~SerializableXMLStateConnection() = default;
+
+      // implementation
+
+      ls_std::byte_field marshal() override;
+      void unmarshal(const ls_std::byte_field& _data) override;
+
+      // additional functionality
+
+      std::shared_ptr<StateConnection> getValue();
+      void setValue(std::shared_ptr<StateConnection> _value);
+
+    private:
+
+      tinyxml2::XMLDocument document {};
+      std::shared_ptr<StateConnection> value {};
+
+      void _clear();
+      void _unmarshalCondition();
+      void _unmarshalConnectionId();
+      void _unmarshalId();
+      void _update();
+  };
+}
+
+#endif

+ 72 - 0
test/cases/serialization/xml/logic/SerializableXMLStateConnectionTest.cpp

@@ -0,0 +1,72 @@
+/*
+ * Author:          Patrick-Christopher Mattulat
+ * Company:         Lynar Studios
+ * E-Mail:          webmaster@lynarstudios.com
+ * Created:         2020-09-20
+ * Changed:         2020-09-20
+ *
+ * */
+
+#include <gtest/gtest.h>
+#include "../../../../../source/serialization/xml/logic/SerializableXMLStateConnection.hpp"
+#include "../../../../../source/boxing/String.hpp"
+
+namespace {
+  class SerializableXMLStateConnectionTest : public ::testing::Test {
+    protected:
+
+      SerializableXMLStateConnectionTest() = default;
+      ~SerializableXMLStateConnectionTest() override = default;
+
+      void SetUp() override {}
+      void TearDown() override {}
+  };
+
+  TEST_F(SerializableXMLStateConnectionTest, marshal)
+  {
+    ls_std::SerializableXMLStateConnection serializable {std::make_shared<ls_std::StateConnection>("AB", "B")};
+    ls_std::String data {serializable.marshal()};
+
+    ASSERT_TRUE(!data.toString().empty());
+    ls_std::String expected {R"(<connection connectionId="AB" id="B" condition="false"/>)"};
+    ASSERT_TRUE(data.contains(expected));
+  }
+
+  TEST_F(SerializableXMLStateConnectionTest, unmarshal)
+  {
+    ls_std::SerializableXMLStateConnection serializable {std::make_shared<ls_std::StateConnection>("AB", "B")};
+    std::string xmlString = R"(<connection connectionId="DE" id="E" condition="true"></connection>)";
+
+    serializable.unmarshal(xmlString);
+    ASSERT_STREQ("DE", serializable.getValue()->getConnectionId().c_str());
+    ASSERT_STREQ("E", serializable.getValue()->getStateId().c_str());
+    ASSERT_TRUE(serializable.getValue()->isPassable());
+  }
+
+  // additional functionality
+
+  TEST_F(SerializableXMLStateConnectionTest, getValue)
+  {
+    std::shared_ptr<ls_std::StateConnection> x = std::make_shared<ls_std::StateConnection>("AB", "B");
+    ls_std::SerializableXMLStateConnection serializable {x};
+
+    ASSERT_STREQ("AB", serializable.getValue()->getConnectionId().c_str());
+    ASSERT_STREQ("B", serializable.getValue()->getStateId().c_str());
+    ASSERT_FALSE(serializable.getValue()->isPassable());
+  }
+
+  TEST_F(SerializableXMLStateConnectionTest, setValue)
+  {
+    ls_std::SerializableXMLStateConnection serializable {std::make_shared<ls_std::StateConnection>("AB", "B")};
+
+    ASSERT_STREQ("AB", serializable.getValue()->getConnectionId().c_str());
+    ASSERT_STREQ("B", serializable.getValue()->getStateId().c_str());
+    ASSERT_FALSE(serializable.getValue()->isPassable());
+
+    serializable.setValue(std::make_shared<ls_std::StateConnection>("BC", "C"));
+
+    ASSERT_STREQ("BC", serializable.getValue()->getConnectionId().c_str());
+    ASSERT_STREQ("C", serializable.getValue()->getStateId().c_str());
+    ASSERT_FALSE(serializable.getValue()->isPassable());
+  }
+}