Browse Source

Add SectionPairSection class

This class represents a section within a section pair file.
Patrick-Christopher Mattulat 1 year ago
parent
commit
56f809c461

+ 2 - 0
CMakeLists.txt

@@ -181,6 +181,7 @@ set(SOURCE_FILES_IO
         ${CMAKE_CURRENT_SOURCE_DIR}/source/ls-std/io/section-pair/model/SectionPairRowListValue.cpp
         ${CMAKE_CURRENT_SOURCE_DIR}/source/ls-std/io/section-pair/model/SectionPairRowSingleValue.cpp
         ${CMAKE_CURRENT_SOURCE_DIR}/source/ls-std/io/section-pair/model/SectionPairRowValue.cpp
+        ${CMAKE_CURRENT_SOURCE_DIR}/source/ls-std/io/section-pair/model/SectionPairSection.cpp
         ${CMAKE_CURRENT_SOURCE_DIR}/source/ls-std/io/section-pair/validator/SectionPairIdentifierValidator.cpp
         ${CMAKE_CURRENT_SOURCE_DIR}/source/ls-std/io/section-pair/validator/SectionPairRowValueValidator.cpp
         ${CMAKE_CURRENT_SOURCE_DIR}/source/ls-std/io/section-pair/serialization/SerializableSectionPairRow.cpp
@@ -279,6 +280,7 @@ if (${LS_STD_BUILD_WITH_TESTS})
             ${CMAKE_CURRENT_SOURCE_DIR}/test/cases/io/section-pair/model/SectionPairRowListValueTest.cpp
             ${CMAKE_CURRENT_SOURCE_DIR}/test/cases/io/section-pair/model/SectionPairRowSingleValueTest.cpp
             ${CMAKE_CURRENT_SOURCE_DIR}/test/cases/io/section-pair/model/SectionPairRowTest.cpp
+            ${CMAKE_CURRENT_SOURCE_DIR}/test/cases/io/section-pair/model/SectionPairSectionTest.cpp
             ${CMAKE_CURRENT_SOURCE_DIR}/test/cases/io/section-pair/serialization/SerializableSectionPairRowListValueTest.cpp
             ${CMAKE_CURRENT_SOURCE_DIR}/test/cases/io/section-pair/serialization/SerializableSectionPairRowSingleValueTest.cpp
             ${CMAKE_CURRENT_SOURCE_DIR}/test/cases/io/section-pair/serialization/SerializableSectionPairRowTest.cpp

+ 45 - 0
include/ls-std/io/section-pair/model/SectionPairSection.hpp

@@ -0,0 +1,45 @@
+/*
+* Author:          Patrick-Christopher Mattulat
+* Company:         Lynar Studios
+* E-Mail:          webmaster@lynarstudios.com
+* Created:         2023-02-13
+* Changed:         2023-02-14
+*
+* */
+
+#ifndef LS_STD_SECTION_PAIR_SECTION_HPP
+#define LS_STD_SECTION_PAIR_SECTION_HPP
+
+#include <list>
+#include <ls-std/core/Class.hpp>
+#include <ls-std/io/section-pair/SectionPairTypes.hpp>
+#include <ls-std/io/section-pair/type/SectionPairSectionTypes.hpp>
+#include <ls-std/os/dynamic-goal.hpp>
+
+namespace ls::std::io
+{
+  class LS_STD_DYNAMIC_GOAL SectionPairSection : public ls::std::core::Class
+  {
+    public:
+
+      explicit SectionPairSection(const ls::std::io::section_pair_identifier &_sectionId);
+      ~SectionPairSection() override;
+
+      void add(const section_pair_row_list_element &_row);
+      [[nodiscard]] section_pair_row_list_element get(size_t _index);
+      [[nodiscard]] size_t getRowAmount();
+      [[nodiscard]] ls::std::io::section_pair_identifier getSectionId();
+      void setSectionId(const ls::std::io::section_pair_identifier &_sectionId);
+
+    private:
+
+      ls::std::io::section_pair_row_list rows{};
+      ls::std::io::section_pair_identifier sectionId{};
+
+      [[nodiscard]] bool _hasRow(const ls::std::io::section_pair_identifier &_key);
+      void _rowExistenceCheck(const ls::std::io::section_pair_identifier &_key);
+      void _setSectionId(const ls::std::io::section_pair_identifier &_sectionId);
+  };
+}
+
+#endif

+ 23 - 0
include/ls-std/io/section-pair/type/SectionPairSectionTypes.hpp

@@ -0,0 +1,23 @@
+/*
+* Author:          Patrick-Christopher Mattulat
+* Company:         Lynar Studios
+* E-Mail:          webmaster@lynarstudios.com
+* Created:         2023-02-13
+* Changed:         2023-02-13
+*
+* */
+
+#ifndef LS_STD_SECTION_PAIR_SECTION_TYPES_HPP
+#define LS_STD_SECTION_PAIR_SECTION_TYPES_HPP
+
+#include <list>
+#include <ls-std/io/section-pair/model/SectionPairRow.hpp>
+#include <memory>
+
+namespace ls::std::io
+{
+  using section_pair_row_list_element = ::std::shared_ptr<ls::std::io::SectionPairRow>;
+  using section_pair_row_list = ::std::list<ls::std::io::section_pair_row_list_element>;
+}
+
+#endif

+ 3 - 1
include/ls-std/ls-std-io.hpp

@@ -3,7 +3,7 @@
  * Company:         Lynar Studios
  * E-Mail:          webmaster@lynarstudios.com
  * Created:         2023-02-11
- * Changed:         2023-02-12
+ * Changed:         2023-02-13
  *
  * */
 
@@ -28,9 +28,11 @@
 #include <ls-std/io/section-pair/model/SectionPairRowListValue.hpp>
 #include <ls-std/io/section-pair/model/SectionPairRowSingleValue.hpp>
 #include <ls-std/io/section-pair/model/SectionPairRowValue.hpp>
+#include <ls-std/io/section-pair/model/SectionPairSection.hpp>
 #include <ls-std/io/section-pair/serialization/SerializableSectionPairRow.hpp>
 #include <ls-std/io/section-pair/serialization/SerializableSectionPairRowListValue.hpp>
 #include <ls-std/io/section-pair/serialization/SerializableSectionPairRowSingleValue.hpp>
+#include <ls-std/io/section-pair/type/SectionPairSectionTypes.hpp>
 #include <ls-std/io/section-pair/validator/SectionPairIdentifierValidator.hpp>
 #include <ls-std/io/section-pair/validator/SectionPairRowValueValidator.hpp>
 

+ 95 - 0
source/ls-std/io/section-pair/model/SectionPairSection.cpp

@@ -0,0 +1,95 @@
+/*
+* Author:          Patrick-Christopher Mattulat
+* Company:         Lynar Studios
+* E-Mail:          webmaster@lynarstudios.com
+* Created:         2023-02-13
+* Changed:         2023-02-14
+*
+* */
+
+#include <ls-std/core/evaluator/EmptyStringArgumentEvaluator.hpp>
+#include <ls-std/core/evaluator/IndexOutOfBoundsEvaluator.hpp>
+#include <ls-std/core/evaluator/NullPointerArgumentEvaluator.hpp>
+#include <ls-std/core/exception/IllegalArgumentException.hpp>
+#include <ls-std/io/section-pair/evaluator/SectionPairIdentifierArgumentEvaluator.hpp>
+#include <ls-std/io/section-pair/model/SectionPairSection.hpp>
+
+ls::std::io::SectionPairSection::SectionPairSection(const ls::std::io::section_pair_identifier &_sectionId) : ls::std::core::Class("SectionPairSection")
+{
+  this->_setSectionId(_sectionId);
+}
+
+ls::std::io::SectionPairSection::~SectionPairSection() = default;
+
+void ls::std::io::SectionPairSection::add(const section_pair_row_list_element &_row)
+{
+  ls::std::core::NullPointerArgumentEvaluator{::std::reinterpret_pointer_cast<void>(_row)}.evaluate();
+  this->_rowExistenceCheck(_row->getKey());
+  this->rows.push_back(_row);
+}
+
+ls::std::io::section_pair_row_list_element ls::std::io::SectionPairSection::get(size_t _index)
+{
+  ls::std::core::IndexOutOfBoundsEvaluator{_index, this->rows.size()}.evaluate();
+  ls::std::io::section_pair_row_list_element element{};
+  size_t index{};
+
+  for (const auto &_element : this->rows)
+  {
+    if (index == _index)
+    {
+      element = _element;
+      break;
+    }
+
+    ++index;
+  }
+
+  return element;
+}
+
+size_t ls::std::io::SectionPairSection::getRowAmount()
+{
+  return this->rows.size();
+}
+
+ls::std::io::section_pair_identifier ls::std::io::SectionPairSection::getSectionId()
+{
+  return this->sectionId;
+}
+
+void ls::std::io::SectionPairSection::setSectionId(const ls::std::io::section_pair_identifier &_sectionId)
+{
+  this->_setSectionId(_sectionId);
+}
+
+bool ls::std::io::SectionPairSection::_hasRow(const ls::std::io::section_pair_identifier &_key)
+{
+  bool rowExists{};
+
+  for (const auto &_row : this->rows)
+  {
+    if (_row->getKey() == _key)
+    {
+      rowExists = true;
+      break;
+    }
+  }
+
+  return rowExists;
+}
+
+void ls::std::io::SectionPairSection::_rowExistenceCheck(const ls::std::io::section_pair_identifier &_key)
+{
+  if (this->_hasRow(_key))
+  {
+    ::std::string message = this->getClassName() + ": row key \"" + _key + "\" already exists in section \"" + this->sectionId + "\"!";
+    throw ls::std::core::IllegalArgumentException{message};
+  }
+}
+void ls::std::io::SectionPairSection::_setSectionId(const ls::std::io::section_pair_identifier &_sectionId)
+{
+  ls::std::core::EmptyStringArgumentEvaluator{_sectionId}.evaluate();
+  ls::std::io::SectionPairIdentifierArgumentEvaluator(_sectionId, this->getClassName() + "argument \"_sectionId\" contains invalid characters!").evaluate();
+  this->sectionId = _sectionId;
+}

+ 179 - 0
test/cases/io/section-pair/model/SectionPairSectionTest.cpp

@@ -0,0 +1,179 @@
+/*
+* Author:          Patrick-Christopher Mattulat
+* Company:         Lynar Studios
+* E-Mail:          webmaster@lynarstudios.com
+* Created:         2023-02-13
+* Changed:         2023-02-14
+*
+* */
+
+#include <gtest/gtest.h>
+#include <ls-std/ls-std-core.hpp>
+#include <ls-std/ls-std-io.hpp>
+
+using namespace ls::std::core;
+using namespace ls::std::io;
+using namespace ::std;
+
+namespace
+{
+  class SectionPairSectionTest : public ::testing::Test
+  {
+    protected:
+
+      SectionPairSectionTest() = default;
+      ~SectionPairSectionTest() override = default;
+
+      void SetUp() override
+      {}
+
+      void TearDown() override
+      {}
+  };
+
+  TEST_F(SectionPairSectionTest, constructor_empty_id)
+  {
+    EXPECT_THROW(
+        {
+          try
+          {
+            SectionPairSection section{""};
+          }
+          catch (const IllegalArgumentException &_exception)
+          {
+            throw;
+          }
+        },
+        IllegalArgumentException);
+  }
+
+  TEST_F(SectionPairSectionTest, constructor_invalid_id)
+  {
+    EXPECT_THROW(
+        {
+          try
+          {
+            SectionPairSection section = SectionPairSection{"SERVER"};
+          }
+          catch (const IllegalArgumentException &_exception)
+          {
+            throw;
+          }
+        },
+        IllegalArgumentException);
+  }
+
+  TEST_F(SectionPairSectionTest, getClassName)
+  {
+    ASSERT_STREQ("SectionPairSection", SectionPairSection{"general"}.getClassName().c_str());
+  }
+
+  TEST_F(SectionPairSectionTest, add)
+  {
+    shared_ptr<SectionPairSection> section = make_shared<SectionPairSection>("general");
+    section->add(make_shared<SectionPairRow>("color", SectionPairRowEnumType::SECTION_PAIR_ROW_SINGLE_VALUE));
+
+    ASSERT_EQ(1, section->getRowAmount());
+  }
+
+  TEST_F(SectionPairSectionTest, add_row_already_exists)
+  {
+    shared_ptr<SectionPairSection> section = make_shared<SectionPairSection>("general");
+    section->add(make_shared<SectionPairRow>("color", SectionPairRowEnumType::SECTION_PAIR_ROW_SINGLE_VALUE));
+
+    EXPECT_THROW(
+        {
+          try
+          {
+            section->add(make_shared<SectionPairRow>("color", SectionPairRowEnumType::SECTION_PAIR_ROW_SINGLE_VALUE));
+          }
+          catch (const IllegalArgumentException &_exception)
+          {
+            throw;
+          }
+        },
+        IllegalArgumentException);
+  }
+
+  TEST_F(SectionPairSectionTest, get)
+  {
+    shared_ptr<SectionPairSection> section = make_shared<SectionPairSection>("general");
+    section->add(make_shared<SectionPairRow>("color", SectionPairRowEnumType::SECTION_PAIR_ROW_SINGLE_VALUE));
+
+    ASSERT_TRUE(section->get(0) != nullptr);
+  }
+
+  TEST_F(SectionPairSectionTest, get_out_of_bounds)
+  {
+    shared_ptr<SectionPairSection> section = make_shared<SectionPairSection>("general");
+
+    EXPECT_THROW(
+        {
+          try
+          {
+            section_pair_row_list_element element = section->get(1);
+          }
+          catch (const IndexOutOfBoundsException &_exception)
+          {
+            throw;
+          }
+        },
+        IndexOutOfBoundsException);
+  }
+
+  TEST_F(SectionPairSectionTest, getAmount)
+  {
+    shared_ptr<SectionPairSection> section = make_shared<SectionPairSection>("general");
+    ASSERT_EQ(0, section->getRowAmount());
+  }
+
+  TEST_F(SectionPairSectionTest, getSectionId)
+  {
+    shared_ptr<SectionPairSection> section = make_shared<SectionPairSection>("general");
+    ASSERT_STREQ("general", section->getSectionId().c_str());
+  }
+
+  TEST_F(SectionPairSectionTest, setSectionId)
+  {
+    shared_ptr<SectionPairSection> section = make_shared<SectionPairSection>("general");
+
+    section->setSectionId("personal");
+    ASSERT_STREQ("personal", section->getSectionId().c_str());
+  }
+
+  TEST_F(SectionPairSectionTest, setSectionId_empty_id)
+  {
+    shared_ptr<SectionPairSection> section = make_shared<SectionPairSection>("general");
+
+    EXPECT_THROW(
+        {
+          try
+          {
+            section->setSectionId("");
+          }
+          catch (const IllegalArgumentException &_exception)
+          {
+            throw;
+          }
+        },
+        IllegalArgumentException);
+  }
+
+  TEST_F(SectionPairSectionTest, setSectionId_invalid_id)
+  {
+    shared_ptr<SectionPairSection> section = make_shared<SectionPairSection>("general");
+
+    EXPECT_THROW(
+        {
+          try
+          {
+            section->setSectionId("PERSONAL");
+          }
+          catch (const IllegalArgumentException &_exception)
+          {
+            throw;
+          }
+        },
+        IllegalArgumentException);
+  }
+}