/* * * This file is a part of the CaosDB Project. * * Copyright (C) 2021 Timm Fitschen <t.fitschen@indiscale.com> * Copyright (C) 2021 Florian Spreckelsen <f.spreckelsen@indiscale.com> * Copyright (C) 2021 IndiScale GmbH <info@indiscale.com> * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <https://www.gnu.org/licenses/>. * */ #include "caosdb/entity.h" // for Entity, Parent, Par... #include "caosdb/entity/v1alpha1/main.grpc.pb.h" // for EntityTransactionSe... #include "caosdb/entity/v1alpha1/main.pb.h" // for IdResponse, Message #include "caosdb/message_code.h" // for MessageCode #include "caosdb/protobuf_helper.h" // for get_arena #include "caosdb/transaction.h" // for Transaction #include "google/protobuf/arena.h" // for Arena #include "gtest/gtest-message.h" // for Message #include "gtest/gtest-test-part.h" // for TestPartResult, Sui... #include "gtest/gtest_pred_impl.h" // for Test, EXPECT_EQ #include <iostream> #include <memory> // for allocator, shared_ptr #include <string> namespace caosdb::entity { using caosdb::entity::v1alpha1::IdResponse; using ProtoEntity = caosdb::entity::v1alpha1::Entity; using caosdb::utility::get_arena; TEST(test_entity, test_parent_setters) { auto parent = Parent(); parent.SetName("RT1"); parent.SetId("some-id"); EXPECT_EQ(parent.GetName(), "RT1"); EXPECT_EQ(parent.GetId(), "some-id"); } TEST(test_entity, test_append_parent) { auto parent = Parent(); parent.SetId("some-id"); auto entity = Entity(); EXPECT_EQ(entity.GetParents().Size(), 0); entity.AppendParent(parent); EXPECT_EQ(entity.GetParents().Size(), 1); auto same_parent = entity.GetParents().At(0); EXPECT_EQ(same_parent.GetId(), "some-id"); } TEST(test_entity, test_property_setters) { auto prop = Property(); prop.SetName("prop_name"); prop.SetId("prop_id"); prop.SetImportance("prop_importance"); prop.SetValue("prop_value"); prop.SetUnit("prop_unit"); prop.SetDatatype("prop_dtype"); EXPECT_EQ(prop.GetName(), "prop_name"); EXPECT_EQ(prop.GetId(), "prop_id"); EXPECT_EQ(prop.GetImportance(), "prop_importance"); EXPECT_EQ(prop.GetValue(), "prop_value"); EXPECT_EQ(prop.GetUnit(), "prop_unit"); EXPECT_EQ(prop.GetDatatype(), "prop_dtype"); } TEST(test_entity, test_append_property) { auto entity = Entity(); auto prop = Property(); prop.SetName("prop_name"); prop.SetId("prop_id"); prop.SetImportance("prop_importance"); prop.SetValue("prop_value"); prop.SetUnit("prop_unit"); prop.SetDatatype("prop_dtype"); EXPECT_EQ(entity.GetProperties().Size(), 0); entity.AppendProperty(prop); EXPECT_EQ(entity.GetProperties().Size(), 1); auto same_prop = entity.GetProperties().At(0); EXPECT_EQ(prop.GetName(), same_prop.GetName()); EXPECT_EQ(prop.GetId(), same_prop.GetId()); EXPECT_EQ(prop.GetImportance(), same_prop.GetImportance()); EXPECT_EQ(prop.GetValue(), same_prop.GetValue()); EXPECT_EQ(prop.GetUnit(), same_prop.GetUnit()); EXPECT_EQ(prop.GetDatatype(), same_prop.GetDatatype()); } TEST(test_entity, test_copy_to) { auto entity = Entity(); entity.SetRole("original_role"); entity.SetName("orignial_name"); auto parent = Parent(); parent.SetId("parent_id"); parent.SetName("parent_name"); entity.AppendParent(parent); auto prop = Property(); prop.SetId("prop_id"); prop.SetName("prop_name"); entity.AppendProperty(prop); // create protobuf entity to which all fields ae copied and then a // CaoosDB entity from that protobuf entity. auto *proto_copy = google::protobuf::Arena::CreateMessage<ProtoEntity>(get_arena()); entity.CopyTo(proto_copy); auto copied = Entity(proto_copy); EXPECT_EQ(entity.GetRole(), copied.GetRole()); EXPECT_EQ(entity.GetName(), copied.GetName()); EXPECT_EQ(copied.GetParents().At(0).GetId(), parent.GetId()); EXPECT_EQ(copied.GetParents().At(0).GetName(), parent.GetName()); EXPECT_EQ(copied.GetProperties().At(0).GetId(), prop.GetId()); EXPECT_EQ(copied.GetProperties().At(0).GetName(), prop.GetName()); } TEST(test_entity, test_insert_entity) { auto transaction = caosdb::transaction::Transaction( std::shared_ptr<transaction::EntityTransactionService::Stub>(nullptr)); auto entity = Entity(); entity.SetRole("entity_role"); entity.SetName("entity_name"); EXPECT_EQ(entity.GetRole(), "entity_role"); EXPECT_EQ(entity.GetName(), "entity_name"); transaction.InsertEntity(&entity); EXPECT_EQ(entity.GetRole(), "entity_role"); EXPECT_EQ(entity.GetName(), "entity_name"); } TEST(test_entity, test_insert_with_role) { auto transaction = caosdb::transaction::Transaction( std::shared_ptr<transaction::EntityTransactionService::Stub>(nullptr)); auto entity = Entity(); entity.SetRole("Property"); entity.SetDatatype("DOUBLE"); entity.SetName("Length"); entity.SetUnit("m"); entity.SetValue("5.5"); transaction.InsertEntity(&entity); EXPECT_EQ(entity.GetRole(), "Property"); EXPECT_EQ(entity.GetDatatype(), "DOUBLE"); EXPECT_EQ(entity.GetName(), "Length"); EXPECT_EQ(entity.GetUnit(), "m"); EXPECT_EQ(entity.GetValue(), "5.5"); } TEST(test_entity, test_insert_with_parent) { auto transaction = caosdb::transaction::Transaction( std::shared_ptr<transaction::EntityTransactionService::Stub>(nullptr)); auto entity = Entity(); entity.SetName("entity_name"); auto parent = Parent(); parent.SetId("parent_id"); parent.SetName("parent_name"); EXPECT_EQ(parent.GetId(), "parent_id"); EXPECT_EQ(parent.GetName(), "parent_name"); entity.AppendParent(parent); transaction.InsertEntity(&entity); EXPECT_EQ(entity.GetName(), "entity_name"); EXPECT_EQ(entity.GetParents().Size(), 1); auto inserted_parent = entity.GetParents().At(0); EXPECT_EQ(inserted_parent.GetId(), parent.GetId()); EXPECT_EQ(inserted_parent.GetName(), parent.GetName()); } TEST(test_entity, test_insert_with_property) { auto transaction = caosdb::transaction::Transaction( std::shared_ptr<transaction::EntityTransactionService::Stub>(nullptr)); auto entity = Entity(); entity.SetName("entity_name"); auto prop = Property(); prop.SetName("prop_name"); prop.SetId("prop_id"); prop.SetImportance("prop_importance"); prop.SetValue("prop_value"); prop.SetUnit("prop_unit"); prop.SetDatatype("prop_dtype"); entity.AppendProperty(prop); transaction.InsertEntity(&entity); EXPECT_EQ(entity.GetProperties().Size(), 1); auto inserted_prop = entity.GetProperties().At(0); EXPECT_EQ(prop.GetName(), inserted_prop.GetName()); EXPECT_EQ(prop.GetId(), inserted_prop.GetId()); EXPECT_EQ(prop.GetImportance(), inserted_prop.GetImportance()); EXPECT_EQ(prop.GetValue(), inserted_prop.GetValue()); EXPECT_EQ(prop.GetUnit(), inserted_prop.GetUnit()); EXPECT_EQ(prop.GetDatatype(), inserted_prop.GetDatatype()); } TEST(test_entity, test_from_id_response) { IdResponse idResponse; idResponse.set_id("entity_id"); auto *error = idResponse.add_entity_errors(); error->set_code(MessageCode::ENTITY_DOES_NOT_EXIST); error->set_description("error_desc"); Entity entity(&idResponse); EXPECT_EQ(entity.GetId(), "entity_id"); EXPECT_TRUE(entity.HasErrors()); EXPECT_EQ(entity.GetErrors().Size(), 1); EXPECT_EQ(entity.GetErrors().At(0).GetDescription(), "error_desc"); EXPECT_EQ(entity.GetErrors().At(0).GetCode(), MessageCode::ENTITY_DOES_NOT_EXIST); IdResponse idr_warnings_and_infos; idr_warnings_and_infos.set_id("other_entity_id"); auto *warning = idr_warnings_and_infos.add_entity_warnings(); warning->set_description("warning_desc"); warning->set_code(MessageCode::ENTITY_HAS_NO_PROPERTIES); auto *info = idr_warnings_and_infos.add_entity_infos(); info->set_description("info_desc"); info->set_code(MessageCode::UNSPECIFIED); Entity other_ent(&idr_warnings_and_infos); EXPECT_EQ(other_ent.GetId(), "other_entity_id"); EXPECT_EQ(other_ent.GetWarnings().Size(), 1); EXPECT_TRUE(other_ent.HasWarnings()); EXPECT_EQ(other_ent.GetWarnings().At(0).GetDescription(), "warning_desc"); EXPECT_EQ(other_ent.GetWarnings().At(0).GetCode(), MessageCode::ENTITY_HAS_NO_PROPERTIES); EXPECT_EQ(other_ent.GetInfos().Size(), 1); EXPECT_EQ(other_ent.GetInfos().At(0).GetDescription(), "info_desc"); EXPECT_EQ(other_ent.GetInfos().At(0).GetCode(), MessageCode::UNSPECIFIED); } TEST(test_entity, test_remove_property) { Entity entity; for (int i = 0; i < 5; i++) { auto name = "PROPERTY-" + std::to_string(i); Property property; property.SetName(name); EXPECT_EQ(property.GetName(), name); entity.AppendProperty(property); EXPECT_EQ(property.GetName(), name); // not initializing the cache } ASSERT_EQ(entity.GetProperties().Size(), 5); for (int i = 5; i < 10; i++) { auto name = "PROPERTY-" + std::to_string(i); Property property; property.SetName(name); EXPECT_EQ(property.GetName(), name); entity.AppendProperty(property); EXPECT_EQ(property.GetName(), name); // initializing the cache const auto &property_2 = entity.GetProperties().At(i); EXPECT_EQ(property_2.GetName(), name); } ASSERT_EQ(entity.GetProperties().Size(), 10); for (int i = 5; i < 10; i++) { // double checking the cache auto name = "PROPERTY-" + std::to_string(i); const auto &property = entity.GetProperties().At(i); EXPECT_EQ(property.GetName(), name); } // Remove at index 3 // P0,P1,P2,P3,P4,P5,P6,P7,P8,P9 // ^ // P0,P1,P2, P4,P5,P6,P7,P8,P9 entity.RemoveProperty(3); // Remove at index 6 // P0,P1,P2, P4,P5,P6,P7,P8,P9 // ^ // P0,P1,P2, P4,P5,P6, P8,P9 entity.RemoveProperty(6); ASSERT_EQ(entity.GetProperties().Size(), 8); // AppendProperty another property // P0,P1,P2, P4,P5,P6, P8,P9 // ^ // P0,P1,P2, P4,P5,P6, P8,P9,P10 Property property10; property10.SetName("PROPERTY-10"); entity.AppendProperty(property10); ASSERT_EQ(entity.GetProperties().Size(), 9); std::cout << "[" << std::endl; for (int i = 0; i < 9; i++) { std::cout << " " << entity.GetProperties().At(i).GetName() << ",\n"; } std::cout << "]" << std::endl; for (int i = 0; i < 3; i++) { auto name = "PROPERTY-" + std::to_string(i); const auto &property = entity.GetProperties().At(i); EXPECT_EQ(property.GetName(), name); } for (int i = 3; i < 6; i++) { auto name = "PROPERTY-" + std::to_string(i + 1); const auto &property = entity.GetProperties().At(i); EXPECT_EQ(property.GetName(), name); } for (int i = 6; i < 9; i++) { auto name = "PROPERTY-" + std::to_string(i + 2); const auto &property = entity.GetProperties().At(i); EXPECT_EQ(property.GetName(), name); } } TEST(test_entity, test_property_iterator) { Entity entity; for (int i = 0; i < 5; i++) { auto name = "PROPERTY-" + std::to_string(i); Property property; property.SetName(name); EXPECT_EQ(property.GetName(), name); entity.AppendProperty(property); } ASSERT_EQ(entity.GetProperties().Size(), 5); int counter = 0; for (auto &property : entity.GetProperties()) { auto name = "PROPERTY-" + std::to_string(counter); EXPECT_EQ(property.GetName(), name); counter++; } EXPECT_EQ(counter, 5); } } // namespace caosdb::entity