Jelajahi Sumber

Improve Narrator class

- add additional error checks to Narrator class
- increase test coverage for Narrator class
Patrick-Christopher Mattulat 3 tahun lalu
induk
melakukan
d0e666fed3

+ 3 - 3
include/ls_std/logic/Narrator.hpp

@@ -3,7 +3,7 @@
  * Company:         Lynar Studios
  * E-Mail:          webmaster@lynarstudios.com
  * Created:         2020-11-14
- * Changed:         2021-05-01
+ * Changed:         2021-05-27
  *
  * */
 
@@ -24,10 +24,10 @@ namespace ls_std
       Narrator();
       ~Narrator() override = default;
 
-      void addListener(const std::shared_ptr<ls_std::IListener> &_listener);
+      bool addListener(const std::shared_ptr<ls_std::IListener> &_listener);
       void clear();
       std::list<std::shared_ptr<ls_std::IListener>> getListeners();
-      void removeListener(const std::shared_ptr<ls_std::IListener> &_listener);
+      bool removeListener(const std::shared_ptr<ls_std::IListener> &_listener);
       void tell(const ls_std::Class &_info);
 
     private:

+ 32 - 7
source/ls_std/logic/Narrator.cpp

@@ -3,22 +3,35 @@
  * Company:         Lynar Studios
  * E-Mail:          webmaster@lynarstudios.com
  * Created:         2020-11-14
- * Changed:         2021-05-02
+ * Changed:         2021-05-27
  *
  * */
 
 #include <ls_std/utils/STLUtils.hpp>
 #include <ls_std/logic/Narrator.hpp>
+#include <ls_std/exception/IllegalArgumentException.hpp>
 
 ls_std::Narrator::Narrator() : ls_std::Class("Narrator")
 {}
 
-void ls_std::Narrator::addListener(const std::shared_ptr<ls_std::IListener> &_listener)
+bool ls_std::Narrator::addListener(const std::shared_ptr<ls_std::IListener> &_listener)
 {
-  if (!ls_std::STLUtils::contains(this->listeners, _listener))
+  bool wasAdded{};
+
+  if (_listener == nullptr)
+  {
+    throw ls_std::IllegalArgumentException{};
+  }
+  else
   {
-    this->listeners.push_back(_listener);
+    if (!ls_std::STLUtils::contains(this->listeners, _listener))
+    {
+      this->listeners.push_back(_listener);
+      wasAdded = true;
+    }
   }
+
+  return wasAdded;
 }
 
 void ls_std::Narrator::clear()
@@ -31,12 +44,24 @@ std::list<std::shared_ptr<ls_std::IListener>> ls_std::Narrator::getListeners()
   return this->listeners;
 }
 
-void ls_std::Narrator::removeListener(const std::shared_ptr<ls_std::IListener> &_listener)
+bool ls_std::Narrator::removeListener(const std::shared_ptr<ls_std::IListener> &_listener)
 {
-  if (ls_std::STLUtils::contains(this->listeners, _listener))
+  bool wasRemoved{};
+
+  if (_listener == nullptr)
+  {
+    throw ls_std::IllegalArgumentException{};
+  }
+  else
   {
-    this->listeners.remove(_listener);
+    if (ls_std::STLUtils::contains(this->listeners, _listener))
+    {
+      this->listeners.remove(_listener);
+      wasRemoved = true;
+    }
   }
+
+  return wasRemoved;
 }
 
 void ls_std::Narrator::tell(const ls_std::Class &_info)

+ 54 - 19
test/cases/logic/NarratorTest.cpp

@@ -3,7 +3,7 @@
  * Company:         Lynar Studios
  * E-Mail:          webmaster@lynarstudios.com
  * Created:         2020-11-14
- * Changed:         2021-04-23
+ * Changed:         2021-05-27
  *
  * */
 
@@ -45,13 +45,34 @@ namespace
   {
     this->createCars();
     ls_std::Narrator paintingMachine{};
-    ASSERT_TRUE(paintingMachine.getListeners().empty());
-    paintingMachine.addListener(std::dynamic_pointer_cast<ls_std::IListener>(this->mercedes1));
-    ASSERT_EQ(1, paintingMachine.getListeners().size());
-    paintingMachine.addListener(std::dynamic_pointer_cast<ls_std::IListener>(this->mercedes2));
-    ASSERT_EQ(2, paintingMachine.getListeners().size());
-    paintingMachine.addListener(std::dynamic_pointer_cast<ls_std::IListener>(this->mercedes3));
-    ASSERT_EQ(3, paintingMachine.getListeners().size());
+
+    ASSERT_TRUE(paintingMachine.addListener(std::dynamic_pointer_cast<ls_std::IListener>(this->mercedes1)));
+    ASSERT_TRUE(paintingMachine.addListener(std::dynamic_pointer_cast<ls_std::IListener>(this->mercedes2)));
+    ASSERT_TRUE(paintingMachine.addListener(std::dynamic_pointer_cast<ls_std::IListener>(this->mercedes3)));
+  }
+
+  TEST_F(NarratorTest, addListener_listener_already_exists)
+  {
+    this->createCars();
+    ls_std::Narrator paintingMachine{};
+
+    ASSERT_TRUE(paintingMachine.addListener(std::dynamic_pointer_cast<ls_std::IListener>(this->mercedes1)));
+    ASSERT_FALSE(paintingMachine.addListener(std::dynamic_pointer_cast<ls_std::IListener>(this->mercedes1)));
+  }
+
+  TEST_F(NarratorTest, addListener_no_reference)
+  {
+    EXPECT_THROW({
+                   try
+                   {
+                     ls_std::Narrator paintingMachine{};
+                     paintingMachine.addListener(nullptr);
+                   }
+                   catch (const ls_std::IllegalArgumentException &_exception)
+                   {
+                     throw;
+                   }
+                 }, ls_std::IllegalArgumentException);
   }
 
   TEST_F(NarratorTest, clear)
@@ -80,21 +101,35 @@ namespace
     paintingMachine.addListener(std::dynamic_pointer_cast<ls_std::IListener>(this->mercedes1));
     paintingMachine.addListener(std::dynamic_pointer_cast<ls_std::IListener>(this->mercedes2));
     paintingMachine.addListener(std::dynamic_pointer_cast<ls_std::IListener>(this->mercedes3));
-    ASSERT_EQ(3, paintingMachine.getListeners().size());
-
-    paintingMachine.removeListener(this->mercedes2);
-    ASSERT_EQ(2, paintingMachine.getListeners().size());
-    paintingMachine.removeListener(this->mercedes1);
-    ASSERT_EQ(1, paintingMachine.getListeners().size());
-    paintingMachine.removeListener(this->mercedes3);
-    ASSERT_EQ(0, paintingMachine.getListeners().size());
-    ASSERT_TRUE(paintingMachine.getListeners().empty());
 
-    paintingMachine.removeListener(nullptr);
-    ASSERT_EQ(0, paintingMachine.getListeners().size());
+    ASSERT_TRUE(paintingMachine.removeListener(this->mercedes2));
+    ASSERT_TRUE(paintingMachine.removeListener(this->mercedes1));
+    ASSERT_TRUE(paintingMachine.removeListener(this->mercedes3));
     ASSERT_TRUE(paintingMachine.getListeners().empty());
   }
 
+  TEST_F(NarratorTest, removeListener_no_listener_available)
+  {
+    this->createCars();
+    ls_std::Narrator paintingMachine{};
+    ASSERT_FALSE(paintingMachine.removeListener(this->mercedes2));
+  }
+
+  TEST_F(NarratorTest, removeListener_no_reference)
+  {
+    EXPECT_THROW({
+                   try
+                   {
+                     ls_std::Narrator paintingMachine{};
+                     paintingMachine.removeListener(nullptr);
+                   }
+                   catch (const ls_std::IllegalArgumentException &_exception)
+                   {
+                     throw;
+                   }
+                 }, ls_std::IllegalArgumentException);
+  }
+
   TEST_F(NarratorTest, tell)
   {
     this->createCars();