Skip to content
Snippets Groups Projects
Code owners
Assign users and groups as approvers for specific file changes. Learn more.
test_value.cpp 6.00 KiB
/*
 *
 * 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