Procházet zdrojové kódy

Improve Double class

- add missing error checks
- add missing tests
Patrick-Christopher Mattulat před 3 roky
rodič
revize
77ae8807fb

+ 7 - 3
include/ls_std/boxing/Double.hpp

@@ -3,7 +3,7 @@
  * Company:         Lynar Studios
  * E-Mail:          webmaster@lynarstudios.com
  * Created:         2020-08-14
- * Changed:         2021-05-01
+ * Changed:         2021-07-01
  *
  * */
 
@@ -91,8 +91,8 @@ namespace ls_std
       double getEpsilon();
       double getValue();
       void setEpsilon(double _epsilon);
-      void setSerializable(std::shared_ptr<ls_std::ISerializable> _serializable);
-      void setStorable(std::shared_ptr<ls_std::IStorable> _storable);
+      void setSerializable(const std::shared_ptr<ls_std::ISerializable>& _serializable);
+      void setStorable(const std::shared_ptr<ls_std::IStorable>& _storable);
 
     private:
 
@@ -100,6 +100,10 @@ namespace ls_std
       std::shared_ptr<ls_std::ISerializable> serializable{};
       std::shared_ptr<ls_std::IStorable> storable{};
       double value{};
+
+      void _assignEpsilon(double _epsilon);
+      void _assignSerializable(const std::shared_ptr<ls_std::ISerializable>& _serializable);
+      void _assignStorable(const std::shared_ptr<ls_std::IStorable>& _storable);
   };
 }
 

+ 43 - 11
source/ls_std/boxing/Double.cpp

@@ -3,23 +3,25 @@
  * Company:         Lynar Studios
  * E-Mail:          webmaster@lynarstudios.com
  * Created:         2020-08-14
- * Changed:         2021-05-01
+ * Changed:         2021-07-01
  *
  * */
 
 #include <cmath>
 #include <ls_std/boxing/Double.hpp>
+#include <ls_std/exception/IllegalArgumentException.hpp>
 
-ls_std::Double::Double()
-    : ls_std::Class("Double"),
-      epsilon(0.00000001)
-{}
+ls_std::Double::Double() : ls_std::Class("Double")
+{
+  this->_assignEpsilon(0.00000001);
+}
 
 ls_std::Double::Double(double _value)
     : ls_std::Class("Double"),
-      epsilon(0.00000001),
       value(_value)
-{}
+{
+  this->_assignEpsilon(0.00000001);
+}
 
 ls_std::Double::operator double() const
 {
@@ -265,15 +267,45 @@ double ls_std::Double::getValue()
 
 void ls_std::Double::setEpsilon(double _epsilon)
 {
+  this->_assignEpsilon(_epsilon);
+}
+
+void ls_std::Double::setSerializable(const std::shared_ptr<ls_std::ISerializable>& _serializable)
+{
+  this->_assignSerializable(_serializable);
+}
+
+void ls_std::Double::setStorable(const std::shared_ptr<ls_std::IStorable>& _storable)
+{
+  this->_assignStorable(_storable);
+}
+
+void ls_std::Double::_assignEpsilon(double _epsilon)
+{
+  if (_epsilon <= 0.0)
+  {
+    throw ls_std::IllegalArgumentException{};
+  }
+
   this->epsilon = _epsilon;
 }
 
-void ls_std::Double::setSerializable(std::shared_ptr<ls_std::ISerializable> _serializable)
+void ls_std::Double::_assignSerializable(const std::shared_ptr<ls_std::ISerializable>& _serializable)
 {
-  this->serializable = std::move(_serializable);
+  if (_serializable == nullptr)
+  {
+    throw ls_std::IllegalArgumentException{};
+  }
+
+  this->serializable = _serializable;
 }
 
-void ls_std::Double::setStorable(std::shared_ptr<ls_std::IStorable> _storable)
+void ls_std::Double::_assignStorable(const std::shared_ptr<ls_std::IStorable>& _storable)
 {
-  this->storable = std::move(_storable);
+  if (_storable == nullptr)
+  {
+    throw ls_std::IllegalArgumentException{};
+  }
+
+  this->storable = _storable;
 }

+ 188 - 111
test/cases/boxing/DoubleTest.cpp

@@ -3,7 +3,7 @@
  * Company:         Lynar Studios
  * E-Mail:          webmaster@lynarstudios.com
  * Created:         2020-08-14
- * Changed:         2021-05-02
+ * Changed:         2021-07-01
  *
  * */
 
@@ -18,6 +18,7 @@ namespace
     protected:
 
       DoubleTest() = default;
+
       ~DoubleTest() override = default;
 
       void SetUp() override
@@ -25,168 +26,227 @@ namespace
 
       void TearDown() override
       {}
+
+      static std::pair<std::shared_ptr<ls_std::File>, std::shared_ptr<ls_std::Double>> createPersistentTestDouble()
+      {
+        std::shared_ptr<ls_std::Double> number = std::make_shared<ls_std::Double>();
+        std::string path = TestHelper::getResourcesFolderLocation() + "tmp_storable_double.json";
+        std::shared_ptr<ls_std::File> file = std::make_shared<ls_std::File>(path);
+        file->createNewFile();
+        ls_std::FileWriter writer{*file};
+        writer.write(R"({"value":3.14159})");
+
+        auto serializable = std::make_shared<ls_std::SerializableJsonDouble>(number);
+        number->setSerializable(std::dynamic_pointer_cast<ls_std::ISerializable>(serializable));
+
+        auto storable = std::make_shared<ls_std::StorableFile>(path);
+        number->setStorable(std::dynamic_pointer_cast<ls_std::IStorable>(storable));
+
+        return std::pair<std::shared_ptr<ls_std::File>, std::shared_ptr<ls_std::Double>>(file, number);
+      }
   };
 
   // assignment operators
 
-  TEST_F(DoubleTest, operatorAssignment)
+  TEST_F(DoubleTest, operator_assignment)
   {
-    ls_std::Double x{13.023};
-    ASSERT_EQ(13.023, x);
-
+    ls_std::Double x{};
     x = 44.22;
-    ASSERT_EQ(44.22, x);
 
-    ls_std::Double y{3.0};
-    x = y;
-    ASSERT_EQ(3.0, x);
+    ASSERT_EQ(44.22, x);
   }
 
   // arithmetic operators
 
-  TEST_F(DoubleTest, operatorHyphen)
+  TEST_F(DoubleTest, operator_negative)
   {
     ls_std::Double x{3.25};
     ASSERT_DOUBLE_EQ(-3.25, -x);
   }
 
-  TEST_F(DoubleTest, operatorAddition)
+  TEST_F(DoubleTest, operator_addition_with_reference)
   {
     ls_std::Double x{3.1415};
     ls_std::Double y{2.223};
     ls_std::Double z{x + y};
 
     ASSERT_DOUBLE_EQ(5.3645, z);
+  }
+
+  TEST_F(DoubleTest, operator_addition_with_value)
+  {
+    ls_std::Double x{3.1415};
     ASSERT_DOUBLE_EQ(5.3645, x + 2.223);
   }
 
-  TEST_F(DoubleTest, operatorMultiplication)
+  TEST_F(DoubleTest, operator_multiplication_with_reference)
   {
     ls_std::Double x{3.14};
     ls_std::Double y{2.22};
     ls_std::Double z{x * y};
 
     ASSERT_DOUBLE_EQ(6.9708, z);
+  }
+
+  TEST_F(DoubleTest, operator_multiplication_with_value)
+  {
+    ls_std::Double x{3.14};
     ASSERT_DOUBLE_EQ(6.9708, x * 2.22);
   }
 
-  TEST_F(DoubleTest, operatorSubstraction)
+  TEST_F(DoubleTest, operator_substraction_with_reference)
   {
     ls_std::Double x{3.1415};
     ls_std::Double y{2.225};
     ls_std::Double z{x - y};
 
     ASSERT_DOUBLE_EQ(0.9165, z);
+  }
+
+  TEST_F(DoubleTest, operator_substraction_with_value)
+  {
+    ls_std::Double x{3.1415};
     ASSERT_DOUBLE_EQ(0.9165, x - 2.225);
   }
 
-  TEST_F(DoubleTest, operatorDivision)
+  TEST_F(DoubleTest, operator_division_with_reference)
   {
     ls_std::Double x{2.25};
     ls_std::Double y{0.5};
     ls_std::Double z{x / y};
 
     ASSERT_DOUBLE_EQ(4.5, z);
+  }
+
+  TEST_F(DoubleTest, operator_division_with_value)
+  {
+    ls_std::Double x{2.25};
     ASSERT_DOUBLE_EQ(4.5, x / 0.5);
   }
 
   // compound operators
 
-  TEST_F(DoubleTest, operatorAddEqual)
+  TEST_F(DoubleTest, operator_add_assign_with_reference)
   {
     ls_std::Double x{2.25000000};
-    ls_std::Double y{-0.39000000};
-    ASSERT_DOUBLE_EQ(2.25000000, x);
+    ls_std::Double y{3.14000000};
 
-    x += 3.14000000;
+    x += y;
     ASSERT_DOUBLE_EQ(5.39000000, x);
+  }
 
-    x += y;
-    ASSERT_DOUBLE_EQ(5.0000000, x);
+  TEST_F(DoubleTest, operator_add_assign_with_value)
+  {
+    ls_std::Double x{2.25000000};
+
+    x += 3.14000000;
+    ASSERT_DOUBLE_EQ(5.39000000, x);
   }
 
-  TEST_F(DoubleTest, operatorSubEqual)
+  TEST_F(DoubleTest, operator_sub_assign_with_reference)
   {
     ls_std::Double x{2.25};
-    ls_std::Double y{-0.04};
-    ASSERT_DOUBLE_EQ(2.25, x);
-
-    x -= 1.14;
-    ASSERT_DOUBLE_EQ(1.11, x);
+    ls_std::Double y{0.04};
 
     x -= y;
-    ASSERT_DOUBLE_EQ(1.15, x);
+    ASSERT_DOUBLE_EQ(2.21, x);
   }
 
-  TEST_F(DoubleTest, operatorMulEqual)
+  TEST_F(DoubleTest, operator_sub_assign_with_value)
+  {
+    ls_std::Double x{2.25};
+
+    x -= 0.04;
+    ASSERT_DOUBLE_EQ(2.21, x);
+  }
+
+  TEST_F(DoubleTest, operator_mul_assign_with_reference)
   {
     ls_std::Double x{2.25000000};
     ls_std::Double y{0.04000000};
-    ASSERT_DOUBLE_EQ(2.25000000, x);
-
-    x *= 1.14000000;
-    ASSERT_DOUBLE_EQ(2.56500000, x);
 
     x *= y;
-    ASSERT_DOUBLE_EQ(0.102600000, x);
+    ASSERT_DOUBLE_EQ(0.09000000, x);
+  }
+
+  TEST_F(DoubleTest, operator_mul_assign_with_value)
+  {
+    ls_std::Double x{2.25000000};
+
+    x *= 0.04000000;
+    ASSERT_DOUBLE_EQ(0.09000000, x);
   }
 
-  TEST_F(DoubleTest, operatorDivEqual)
+  TEST_F(DoubleTest, operator_division_assign_with_reference)
   {
     ls_std::Double x{2.25};
-    ls_std::Double y{1.5};
-    ASSERT_DOUBLE_EQ(2.25, x);
+    ls_std::Double y{0.05};
 
-    x /= 0.05;
+    x /= y;
     ASSERT_DOUBLE_EQ(45.0, x);
+  }
 
-    x /= y;
-    ASSERT_DOUBLE_EQ(30.0, x);
+  TEST_F(DoubleTest, operator_division_assign_with_value)
+  {
+    ls_std::Double x{2.25};
+
+    x /= 0.05;
+    ASSERT_DOUBLE_EQ(45.0, x);
   }
 
   // comparison operators
 
-  TEST_F(DoubleTest, operatorEqual)
+  TEST_F(DoubleTest, operator_equals_with_reference)
   {
     ls_std::Double x{3.14159};
     ls_std::Double y{3.14159};
 
     ASSERT_TRUE(x == y);
     ASSERT_TRUE(y == x);
+  }
+
+  TEST_F(DoubleTest, operator_equals_with_value)
+  {
+    ls_std::Double x{3.14159};
+
     ASSERT_TRUE(x == 3.14159);
     ASSERT_TRUE(3.14159 == x);
   }
 
-  TEST_F(DoubleTest, operatorNotEqual)
+  TEST_F(DoubleTest, operator_not_equal_with_reference)
   {
     ls_std::Double x{3.1415};
     ls_std::Double y{3.1414};
 
     ASSERT_TRUE(x != y);
     ASSERT_TRUE(y != x);
+  }
+
+  TEST_F(DoubleTest, operator_not_equal_with_value)
+  {
+    ls_std::Double x{3.1415};
+
     ASSERT_TRUE(x != 3.1414);
     ASSERT_TRUE(3.1414 != x);
   }
 
-  TEST_F(DoubleTest, operatorGreaterThan)
+  TEST_F(DoubleTest, operator_greater_than_with_reference)
   {
     ls_std::Double x{3.1415};
     ls_std::Double y{3.1414};
 
     ASSERT_TRUE(x > y);
-    ASSERT_TRUE(x > 3.1414);
   }
 
-  TEST_F(DoubleTest, operatorGreaterThanNegative)
+  TEST_F(DoubleTest, operator_greater_than_with_value)
   {
-    ls_std::Double x{3.1414};
+    ls_std::Double x{3.1415};
     ls_std::Double y{3.1414};
 
-    ASSERT_FALSE(x > y);
-    ASSERT_FALSE(x > 3.1414);
+    ASSERT_TRUE(x > 3.1414);
   }
 
-  TEST_F(DoubleTest, operatorGreaterThanEqual)
+  TEST_F(DoubleTest, operator_greater_than_equals_with_reference)
   {
     ls_std::Double x{3.1414};
     ls_std::Double y{3.1414};
@@ -194,38 +254,31 @@ namespace
 
     ASSERT_TRUE(x >= y);
     ASSERT_TRUE(z >= y);
-    ASSERT_TRUE(x >= 3.1414);
-    ASSERT_TRUE(z >= 3.1414);
   }
 
-  TEST_F(DoubleTest, operatorGreaterThanEqualNegative)
+  TEST_F(DoubleTest, operator_greater_than_equals_with_value)
   {
     ls_std::Double x{3.1414};
-    ls_std::Double y{3.1415};
-
-    ASSERT_FALSE(x >= y);
-    ASSERT_FALSE(x >= 3.1415);
+    ASSERT_TRUE(x >= 3.1414);
   }
 
-  TEST_F(DoubleTest, operatorLessThan)
+  TEST_F(DoubleTest, operator_less_than_with_reference)
   {
     ls_std::Double x{3.1413};
     ls_std::Double y{3.1414};
 
     ASSERT_TRUE(x < y);
-    ASSERT_TRUE(x < 3.1414);
   }
 
-  TEST_F(DoubleTest, operatorLessThanNegative)
+  TEST_F(DoubleTest, operator_less_than_with_value)
   {
-    ls_std::Double x{3.1414};
+    ls_std::Double x{3.1413};
     ls_std::Double y{3.1414};
 
-    ASSERT_FALSE(x < y);
-    ASSERT_FALSE(x < 3.1414);
+    ASSERT_TRUE(x < 3.1414);
   }
 
-  TEST_F(DoubleTest, operatorLessThanEqual)
+  TEST_F(DoubleTest, operator_less_than_equals_with_reference)
   {
     ls_std::Double x{3.1414};
     ls_std::Double y{3.1414};
@@ -233,43 +286,30 @@ namespace
 
     ASSERT_TRUE(x <= y);
     ASSERT_TRUE(x <= z);
-    ASSERT_TRUE(x <= 3.1414);
-    ASSERT_TRUE(x <= 3.1415);
   }
 
-  TEST_F(DoubleTest, operatorLessThanEqualNegative)
+  TEST_F(DoubleTest, operator_less_than_equals_with_value)
   {
-    ls_std::Double x{3.1415};
-    ls_std::Double y{3.1414};
-
-    ASSERT_FALSE(x <= y);
-    ASSERT_FALSE(x <= 3.1414);
+    ls_std::Double x{3.1414};
+    ASSERT_TRUE(x <= 3.1414);
   }
 
   // increment / decrement operator
 
-  TEST_F(DoubleTest, operatorIncrement)
+  TEST_F(DoubleTest, operator_increment)
   {
     ls_std::Double x{3.1415};
-    ASSERT_DOUBLE_EQ(3.1415, x);
 
     ++x;
     ASSERT_DOUBLE_EQ(4.1415, x);
-
-    ++x;
-    ASSERT_DOUBLE_EQ(5.1415, x);
   }
 
-  TEST_F(DoubleTest, operatorDecrement)
+  TEST_F(DoubleTest, operator_decrement)
   {
     ls_std::Double x{3.1415};
-    ASSERT_DOUBLE_EQ(3.1415, x);
 
     --x;
     ASSERT_DOUBLE_EQ(2.1415, x);
-
-    --x;
-    ASSERT_DOUBLE_EQ(1.1415, x);
   }
 
   // implementation
@@ -278,48 +318,38 @@ namespace
   {
     // preparation
 
-    std::shared_ptr<ls_std::Double> x = std::make_shared<ls_std::Double>();
-    std::string path = TestHelper::getResourcesFolderLocation() + "tmp_storable_double.json";
-    ls_std::File file{path};
-    file.createNewFile();
-    ls_std::FileWriter writer{file};
-    writer.write(R"({"value":3.14159})");
-
-    auto serializable = std::make_shared<ls_std::SerializableJsonDouble>(x);
-    x->setSerializable(std::dynamic_pointer_cast<ls_std::ISerializable>(serializable));
-
-    auto storable = std::make_shared<ls_std::StorableFile>(path);
-    x->setStorable(std::dynamic_pointer_cast<ls_std::IStorable>(storable));
+    auto storableDouble = createPersistentTestDouble();
 
     // check
 
-    x->load();
-    ASSERT_DOUBLE_EQ(3.14159, *x);
+    storableDouble.second->load();
+    ASSERT_DOUBLE_EQ(3.14159, *storableDouble.second);
 
-    file.remove();
+    storableDouble.first->remove();
   }
 
   TEST_F(DoubleTest, marshal)
   {
-    std::shared_ptr<ls_std::Double> x = std::make_shared<ls_std::Double>(3.14159);
+    std::shared_ptr<ls_std::Double> number = std::make_shared<ls_std::Double>(3.14159);
 
-    auto serializable = std::make_shared<ls_std::SerializableJsonDouble>(x);
-    x->setSerializable(std::dynamic_pointer_cast<ls_std::ISerializable>(serializable));
-    ls_std::String jsonString{x->marshal()};
+    auto serializable = std::make_shared<ls_std::SerializableJsonDouble>(number);
+    number->setSerializable(std::dynamic_pointer_cast<ls_std::ISerializable>(serializable));
+    ls_std::String jsonString{number->marshal()};
 
     ASSERT_TRUE(jsonString.contains(R"({"value":3.14159)"));
-
-    *x = 17.13149;
-    jsonString = x->marshal();
-    ASSERT_TRUE(jsonString.contains(R"({"value":17.1314)"));
   }
 
-  TEST_F(DoubleTest, parse)
+  TEST_F(DoubleTest, parse_with_positive_value)
   {
     ls_std::Double x{};
 
     x.parse("3.1415");
     ASSERT_DOUBLE_EQ(3.1415, x);
+  }
+
+  TEST_F(DoubleTest, parse_with_negative_value)
+  {
+    ls_std::Double x{};
 
     x.parse("-2.1415");
     ASSERT_DOUBLE_EQ(-2.1415, x);
@@ -333,15 +363,13 @@ namespace
 
   TEST_F(DoubleTest, unmarshal)
   {
-    std::shared_ptr<ls_std::Double> x = std::make_shared<ls_std::Double>(3.14159);
+    std::shared_ptr<ls_std::Double> number = std::make_shared<ls_std::Double>(3.14159);
 
-    ASSERT_DOUBLE_EQ(3.14159, *x);
+    auto serializable = std::make_shared<ls_std::SerializableJsonDouble>(number);
+    number->setSerializable(std::dynamic_pointer_cast<ls_std::ISerializable>(serializable));
+    number->unmarshal(R"({"value":17.4132})");
 
-    auto serializable = std::make_shared<ls_std::SerializableJsonDouble>(x);
-    x->setSerializable(std::dynamic_pointer_cast<ls_std::ISerializable>(serializable));
-    x->unmarshal(R"({"value":17.4132})");
-
-    ASSERT_DOUBLE_EQ(17.4132, *x);
+    ASSERT_DOUBLE_EQ(17.4132, *number);
   }
 
   // additional functionality
@@ -362,6 +390,55 @@ namespace
   {
     ls_std::Double x{};
     x.setEpsilon(0.01);
+
     ASSERT_DOUBLE_EQ(0.01, x.getEpsilon());
   }
+
+  TEST_F(DoubleTest, setEpsilon_invalid_value)
+  {
+    ls_std::Double x{};
+
+    EXPECT_THROW({
+                   try
+                   {
+                     x.setEpsilon(0.0);
+                   }
+                   catch (const ls_std::IllegalArgumentException &_exception)
+                   {
+                     throw;
+                   }
+                 }, ls_std::IllegalArgumentException);
+  }
+
+  TEST_F(DoubleTest, setSerializable_no_reference)
+  {
+    ls_std::Double x{};
+
+    EXPECT_THROW({
+                   try
+                   {
+                     x.setSerializable(nullptr);
+                   }
+                   catch (const ls_std::IllegalArgumentException &_exception)
+                   {
+                     throw;
+                   }
+                 }, ls_std::IllegalArgumentException);
+  }
+
+  TEST_F(DoubleTest, setStorable_no_reference)
+  {
+    ls_std::Double x{};
+
+    EXPECT_THROW({
+                   try
+                   {
+                     x.setStorable(nullptr);
+                   }
+                   catch (const ls_std::IllegalArgumentException &_exception)
+                   {
+                     throw;
+                   }
+                 }, ls_std::IllegalArgumentException);
+  }
 }