/* * * This file is a part of the CaosDB Project. * * Copyright (C) 2021 Timm Fitschen <t.fitschen@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/value.h" // for Value #include "caosdb/entity/v1alpha1/main.pb.h" // for AtomicDataType, DataType #include "caosdb/protobuf_helper.h" // for ProtoMessageWrapper #include <algorithm> // for max #include <cmath> // for isnan #include <gtest/gtest-message.h> // for Message #include <gtest/gtest-test-part.h> // for TestPartResult, SuiteApi... #include <gtest/gtest_pred_impl.h> // for AssertionResult, Test #include <initializer_list> // for initializer_list #include <string> // for string, basic_string #include <vector> // for vector namespace caosdb::entity { using ProtoValue = caosdb::entity::v1alpha1::Value; using ProtoEntity = caosdb::entity::v1alpha1::Entity; using ProtoParent = caosdb::entity::v1alpha1::Parent; using ProtoDataType = caosdb::entity::v1alpha1::DataType; using ProtoAtomicDataType = caosdb::entity::v1alpha1::AtomicDataType; TEST(test_value, test_null) { Value value; EXPECT_TRUE(value.IsNull()); EXPECT_FALSE(value.IsDouble()); EXPECT_FALSE(value.IsBool()); EXPECT_FALSE(value.IsInt64()); EXPECT_FALSE(value.IsString()); EXPECT_FALSE(value.IsVector()); } TEST(test_value, test_string) { Value value(std::string("test")); EXPECT_FALSE(value.IsNull()); EXPECT_TRUE(value.IsString()); EXPECT_FALSE(value.IsDouble()); EXPECT_FALSE(value.IsBool()); EXPECT_FALSE(value.IsInt64()); EXPECT_EQ(value.GetAsString(), "test"); Value empty_string(std::string("")); EXPECT_FALSE(empty_string.IsNull()); EXPECT_TRUE(empty_string.IsString()); EXPECT_FALSE(empty_string.IsDouble()); EXPECT_FALSE(empty_string.IsBool()); EXPECT_FALSE(empty_string.IsInt64()); EXPECT_EQ(empty_string.GetAsString(), ""); // Test inequality Value string1("1"); Value int1(1); EXPECT_FALSE(string1 == int1); } TEST(test_value, test_double) { Value value(2.26); EXPECT_FALSE(value.IsNull()); EXPECT_FALSE(value.IsString()); EXPECT_TRUE(value.IsDouble()); EXPECT_FALSE(value.IsBool()); EXPECT_FALSE(value.IsInt64()); EXPECT_EQ(value.GetAsDouble(), 2.26); Value nan(std::sqrt(-1.0)); EXPECT_FALSE(nan.IsNull()); EXPECT_FALSE(nan.IsString()); EXPECT_TRUE(nan.IsDouble()); EXPECT_FALSE(nan.IsBool()); EXPECT_FALSE(nan.IsInt64()); EXPECT_TRUE(std::isnan(nan.GetAsDouble())); } TEST(test_value, test_integer) { Value value(1337); EXPECT_FALSE(value.IsNull()); EXPECT_FALSE(value.IsString()); EXPECT_FALSE(value.IsDouble()); EXPECT_FALSE(value.IsBool()); EXPECT_TRUE(value.IsInt64()); EXPECT_EQ(value.GetAsInt64(), 1337); } TEST(test_value, test_boolean) { Value value(true); EXPECT_FALSE(value.IsNull()); EXPECT_FALSE(value.IsString()); EXPECT_FALSE(value.IsDouble()); EXPECT_TRUE(value.IsBool()); EXPECT_FALSE(value.IsInt64()); EXPECT_EQ(value.GetAsBool(), true); } TEST(test_value, test_list) { std::vector<std::string> ids; for (std::string id : {"id0", "id1", "id2"}) { ids.push_back(id); } Value value(ids); EXPECT_FALSE(value.IsNull()); EXPECT_TRUE(value.IsVector()); EXPECT_FALSE(value.IsString()); EXPECT_FALSE(value.IsDouble()); EXPECT_FALSE(value.IsBool()); EXPECT_FALSE(value.IsInt64()); auto list_value = value.GetAsVector(); int counter = 0; for (const auto &item : list_value) { EXPECT_EQ(item.IsString(), true); EXPECT_EQ(item.GetAsString(), "id" + std::to_string(counter++)); } } TEST(test_value, test_scalar_value_to_value) { ProtoScalarValue proto_scalar_value; proto_scalar_value.set_integer_value(5); ScalarValue scalar_value(&proto_scalar_value); Value value(scalar_value); EXPECT_TRUE(scalar_value.IsInt64()); EXPECT_TRUE(value.IsInt64()); EXPECT_EQ(scalar_value.GetAsInt64(), value.GetAsInt64()); } TEST(test_value, test_abstract_value) { std::vector<double> vals; for (double num : {0.0, 5.6, 27.5}) { vals.push_back(num); } Value value(vals); EXPECT_TRUE(value.IsVector()); AbstractValue *abstract_value = &value; EXPECT_TRUE(abstract_value->IsVector()); Value value2(*abstract_value); EXPECT_TRUE(value2.IsVector()); ScalarValue scalar_value = value.GetAsVector().at(2); EXPECT_TRUE(scalar_value.IsDouble()); EXPECT_EQ(scalar_value.GetAsDouble(), 27.5); AbstractValue *abstract_scalar_value = &scalar_value; EXPECT_TRUE(abstract_scalar_value->IsDouble()); EXPECT_EQ(abstract_scalar_value->GetAsDouble(), 27.5); Value scalar_value2(*abstract_scalar_value); EXPECT_TRUE(scalar_value2.IsDouble()); EXPECT_EQ(scalar_value2.GetAsDouble(), 27.5); } TEST(test_value, test_value_to_string) { Value value1; EXPECT_EQ(value1.ToString(), "{}\n"); ProtoValue proto_value; Value value2(&proto_value); EXPECT_EQ(value2.ToString(), "{}\n"); Value value3(2.6); EXPECT_EQ(value3.ToString(), "{\n \"scalarValue\": {\n \"doubleValue\": 2.6\n }\n}\n"); Value value4(std::vector<bool>{true, false}); EXPECT_EQ(value4.ToString(), "{\n \"listValues\": {\n \"values\": [\n {\n " "\"booleanValue\": true\n },\n " "{\n \"booleanValue\": false\n }\n ]\n }\n}\n"); } } // namespace caosdb::entity