From 2dbd45c607b0ee60a9ad754b5092a2e6a1adee5c Mon Sep 17 00:00:00 2001
From: Daniel Hornung <d.hornung@indiscale.com>
Date: Wed, 25 Aug 2021 19:20:28 +0200
Subject: [PATCH] ENH: Testing numeric entity values.

---
 test/test_transaction.cpp | 112 +++++++++++++++++++++++++++++++++-----
 1 file changed, 97 insertions(+), 15 deletions(-)

diff --git a/test/test_transaction.cpp b/test/test_transaction.cpp
index 7acdd76..9bc7e82 100644
--- a/test/test_transaction.cpp
+++ b/test/test_transaction.cpp
@@ -30,6 +30,7 @@
 #include <boost/filesystem/operations.hpp>  // for remove
 #include <boost/filesystem/path.hpp>        // for path
 #include <boost/filesystem/path_traits.hpp> // for filesystem
+#include <boost/lexical_cast.hpp>
 #include <gtest/gtest-message.h>            // for Message
 #include <gtest/gtest-test-part.h> // for TestPartResult, SuiteApiResolver
 #include <gtest/gtest_pred_impl.h> // for Test, EXPECT_EQ, AssertionResult
@@ -49,10 +50,48 @@ using caosdb::entity::Property;
 using caosdb::entity::Role;
 
 class test_transaction : public ::testing::Test {
+public:
+
+  // public utility functions ////////////////////////////////////////////////////////
+
+  /**
+   * Generate a vector with useful values for testing.
+   */
+  template <typename T> static auto generateValues() -> std::vector<T> {
+    std::vector<T> values = {
+      0,
+      1,
+      std::numeric_limits<T>::max(),
+      std::numeric_limits<T>::min(),
+      std::numeric_limits<T>::lowest(),
+      std::numeric_limits<T>::epsilon() // 0 for integers, but who cares?
+    };
+    return values;
+  }
+
+  static void DeleteEntities() {
+    // delete all entities
+    const auto &connection =
+        caosdb::connection::ConnectionManager::GetDefaultConnection();
+    auto query_transaction(connection->CreateTransaction());
+    query_transaction->Query("FIND ENTITY WITH id > 99");
+    query_transaction->Execute();
+    if (query_transaction->GetResultSet().size() > 0) {
+      auto delete_transaction(connection->CreateTransaction());
+      for (const Entity &entity : query_transaction->GetResultSet()) {
+        delete_transaction->DeleteById(entity.GetId());
+      }
+      delete_transaction->Execute();
+    }
+  }
+
+
 protected:
   fs::path test_upload_file_1;
   fs::path test_download_file_1;
 
+  // Fixture methods //////////////////////////////////////////////////////////
+
   void SetUp() override {
     DeleteEntities();
 
@@ -74,21 +113,6 @@ protected:
     DeleteEntities();
   }
 
-  static void DeleteEntities() {
-    // delete all entities
-    const auto &connection =
-        caosdb::connection::ConnectionManager::GetDefaultConnection();
-    auto query_transaction(connection->CreateTransaction());
-    query_transaction->Query("FIND ENTITY WITH id > 99");
-    query_transaction->Execute();
-    if (query_transaction->GetResultSet().size() > 0) {
-      auto delete_transaction(connection->CreateTransaction());
-      for (const Entity &entity : query_transaction->GetResultSet()) {
-        delete_transaction->DeleteById(entity.GetId());
-      }
-      delete_transaction->Execute();
-    }
-  }
 };
 
 /*
@@ -640,6 +664,64 @@ TEST_F(test_transaction, test_query) {
   EXPECT_EQ(count_query_trans->GetCountResult(), 1);
 }
 
+/**
+ * Test numeric values (template).
+ */
+template<typename T>
+auto test_numeric_values_impl(AtomicDataType a_type) -> void {
+  const auto &connection =
+    caosdb::connection::ConnectionManager::GetDefaultConnection();
+
+  // Insert entities
+  auto insert_transaction(connection->CreateTransaction());
+  auto values_orig = test_transaction::generateValues<T>();
+  auto props_orig = std::vector<Entity>();
+  size_t i = 0;
+  --i;
+  for (auto value : values_orig) {
+    ++i;
+    Entity prop;
+    prop.SetRole(Role::PROPERTY);
+    prop.SetName(std::string("Prop ") + boost::lexical_cast<std::string>(i));
+    prop.SetDataType(a_type);
+    prop.SetValue(value);
+    props_orig.push_back(prop);
+    insert_transaction->InsertEntity(&prop);
+    insert_transaction->ExecuteAsynchronously();
+    auto t_stat = insert_transaction->WaitForIt();
+    ASSERT_TRUE(t_stat.IsTerminated());
+    ASSERT_FALSE(t_stat.IsError());
+  }
+
+  // Retrieve and verify
+  auto retrieve_transaction(connection->CreateTransaction());
+  i = 0;
+  --i;
+  for (auto value : values_orig) {
+    ++i;
+    auto prop = props_orig[i];
+    auto name = std::string("Prop ") + boost::lexical_cast<std::string>(i);
+    auto query = std::string("FIND ENTITY \"Prop ") + boost::lexical_cast<std::string>(i) + "\"";
+    retrieve_transaction->Query(query);
+    retrieve_transaction->ExecuteAsynchronously();
+    auto t_stat = retrieve_transaction->WaitForIt();
+    ASSERT_TRUE(t_stat.IsTerminated());
+    ASSERT_FALSE(t_stat.IsError());
+
+    auto result = retrieve_transaction->GetResultSet().at(0);
+    ASSERT_EQ(result.GetDataType(), a_type);
+  }
+}
+
+/**
+ * Test numeric values (wrapper for types).
+ */
+TEST_F(test_transaction, test_numeric_values) {
+  test_numeric_values_impl<double>(AtomicDataType::DOUBLE);
+  DeleteEntities();
+  test_numeric_values_impl<int64_t>(AtomicDataType::INTEGER);
+}
+
 /*
  * test miscellaneous queries
  */
-- 
GitLab