Implement PropertyValue
for storage v2
Reviewers: teon.banek, mtomic Reviewed By: mtomic Subscribers: pullbot Differential Revision: https://phabricator.memgraph.io/D2149
This commit is contained in:
parent
fabfa77bd9
commit
f2b23828ab
398
src/storage/v2/property_value.hpp
Normal file
398
src/storage/v2/property_value.hpp
Normal file
@ -0,0 +1,398 @@
|
||||
#pragma once
|
||||
|
||||
#include <iostream>
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "utils/algorithm.hpp"
|
||||
#include "utils/exceptions.hpp"
|
||||
|
||||
namespace storage {
|
||||
|
||||
/// An exception raised by the PropertyValue. Typically when trying to perform
|
||||
/// operations (such as addition) on PropertyValues of incompatible Types.
|
||||
class PropertyValueException : public utils::BasicException {
|
||||
public:
|
||||
using utils::BasicException::BasicException;
|
||||
};
|
||||
|
||||
/// Encapsulation of a value and its type in a class that has no compile-time
|
||||
/// info about the type.
|
||||
///
|
||||
/// Values can be of a number of predefined types that are enumerated in
|
||||
/// PropertyValue::Type. Each such type corresponds to exactly one C++ type.
|
||||
class PropertyValue {
|
||||
public:
|
||||
enum class Type : uint8_t { Null, Bool, Int, Double, String, List, Map };
|
||||
|
||||
// default constructor, makes Null
|
||||
PropertyValue() : type_(Type::Null) {}
|
||||
|
||||
// constructors for primitive types
|
||||
explicit PropertyValue(bool value) : type_(Type::Bool) { bool_v = value; }
|
||||
explicit PropertyValue(int value) : type_(Type::Int) { int_v = value; }
|
||||
explicit PropertyValue(int64_t value) : type_(Type::Int) { int_v = value; }
|
||||
explicit PropertyValue(double value) : type_(Type::Double) {
|
||||
double_v = value;
|
||||
}
|
||||
|
||||
// copy constructors for non-primitive types
|
||||
explicit PropertyValue(const std::string &value) : type_(Type::String) {
|
||||
new (&string_v) std::string(value);
|
||||
}
|
||||
explicit PropertyValue(const char *value) : type_(Type::String) {
|
||||
new (&string_v) std::string(value);
|
||||
}
|
||||
explicit PropertyValue(const std::vector<PropertyValue> &value)
|
||||
: type_(Type::List) {
|
||||
new (&list_v) std::vector<PropertyValue>(value);
|
||||
}
|
||||
explicit PropertyValue(const std::map<std::string, PropertyValue> &value)
|
||||
: type_(Type::Map) {
|
||||
new (&map_v) std::map<std::string, PropertyValue>(value);
|
||||
}
|
||||
|
||||
// move constructors for non-primitive types
|
||||
explicit PropertyValue(std::string &&value) noexcept : type_(Type::String) {
|
||||
new (&string_v) std::string(std::move(value));
|
||||
}
|
||||
explicit PropertyValue(std::vector<PropertyValue> &&value) noexcept
|
||||
: type_(Type::List) {
|
||||
new (&list_v) std::vector<PropertyValue>(std::move(value));
|
||||
}
|
||||
explicit PropertyValue(std::map<std::string, PropertyValue> &&value) noexcept
|
||||
: type_(Type::Map) {
|
||||
new (&map_v) std::map<std::string, PropertyValue>(std::move(value));
|
||||
}
|
||||
|
||||
// copy constructor
|
||||
PropertyValue(const PropertyValue &other) : type_(other.type_) {
|
||||
switch (other.type_) {
|
||||
case Type::Null:
|
||||
return;
|
||||
case Type::Bool:
|
||||
this->bool_v = other.bool_v;
|
||||
return;
|
||||
case Type::Int:
|
||||
this->int_v = other.int_v;
|
||||
return;
|
||||
case Type::Double:
|
||||
this->double_v = other.double_v;
|
||||
return;
|
||||
case Type::String:
|
||||
new (&string_v) std::string(other.string_v);
|
||||
return;
|
||||
case Type::List:
|
||||
new (&list_v) std::vector<PropertyValue>(other.list_v);
|
||||
return;
|
||||
case Type::Map:
|
||||
new (&map_v) std::map<std::string, PropertyValue>(other.map_v);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// move constructor
|
||||
PropertyValue(PropertyValue &&other) noexcept : type_(other.type_) {
|
||||
switch (other.type_) {
|
||||
case Type::Null:
|
||||
break;
|
||||
case Type::Bool:
|
||||
this->bool_v = other.bool_v;
|
||||
break;
|
||||
case Type::Int:
|
||||
this->int_v = other.int_v;
|
||||
break;
|
||||
case Type::Double:
|
||||
this->double_v = other.double_v;
|
||||
break;
|
||||
case Type::String:
|
||||
new (&string_v) std::string(std::move(other.string_v));
|
||||
break;
|
||||
case Type::List:
|
||||
new (&list_v) std::vector<PropertyValue>(std::move(other.list_v));
|
||||
break;
|
||||
case Type::Map:
|
||||
new (&map_v)
|
||||
std::map<std::string, PropertyValue>(std::move(other.map_v));
|
||||
break;
|
||||
}
|
||||
|
||||
// reset the type of other
|
||||
other.DestroyValue();
|
||||
other.type_ = Type::Null;
|
||||
}
|
||||
|
||||
// copy assignment
|
||||
PropertyValue &operator=(const PropertyValue &other) {
|
||||
if (this == &other) return *this;
|
||||
|
||||
DestroyValue();
|
||||
type_ = other.type_;
|
||||
|
||||
switch (other.type_) {
|
||||
case Type::Null:
|
||||
break;
|
||||
case Type::Bool:
|
||||
this->bool_v = other.bool_v;
|
||||
break;
|
||||
case Type::Int:
|
||||
this->int_v = other.int_v;
|
||||
break;
|
||||
case Type::Double:
|
||||
this->double_v = other.double_v;
|
||||
break;
|
||||
case Type::String:
|
||||
new (&string_v) std::string(other.string_v);
|
||||
break;
|
||||
case Type::List:
|
||||
new (&list_v) std::vector<PropertyValue>(other.list_v);
|
||||
break;
|
||||
case Type::Map:
|
||||
new (&map_v) std::map<std::string, PropertyValue>(other.map_v);
|
||||
break;
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
// move assignment
|
||||
PropertyValue &operator=(PropertyValue &&other) noexcept {
|
||||
if (this == &other) return *this;
|
||||
|
||||
DestroyValue();
|
||||
type_ = other.type_;
|
||||
|
||||
switch (other.type_) {
|
||||
case Type::Null:
|
||||
break;
|
||||
case Type::Bool:
|
||||
this->bool_v = other.bool_v;
|
||||
break;
|
||||
case Type::Int:
|
||||
this->int_v = other.int_v;
|
||||
break;
|
||||
case Type::Double:
|
||||
this->double_v = other.double_v;
|
||||
break;
|
||||
case Type::String:
|
||||
new (&string_v) std::string(std::move(other.string_v));
|
||||
break;
|
||||
case Type::List:
|
||||
new (&list_v) std::vector<PropertyValue>(std::move(other.list_v));
|
||||
break;
|
||||
case Type::Map:
|
||||
new (&map_v)
|
||||
std::map<std::string, PropertyValue>(std::move(other.map_v));
|
||||
break;
|
||||
}
|
||||
|
||||
// reset the type of other
|
||||
other.DestroyValue();
|
||||
other.type_ = Type::Null;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
// TODO: Implement copy assignment operators for primitive types.
|
||||
// TODO: Implement copy and move assignment operators for non-primitive types.
|
||||
|
||||
~PropertyValue() { DestroyValue(); }
|
||||
|
||||
Type type() const { return type_; }
|
||||
|
||||
// type checkers
|
||||
bool IsNull() const { return type_ == Type::Null; }
|
||||
bool IsBool() const { return type_ == Type::Bool; }
|
||||
bool IsInt() const { return type_ == Type::Int; }
|
||||
bool IsDouble() const { return type_ == Type::Double; }
|
||||
bool IsString() const { return type_ == Type::String; }
|
||||
bool IsList() const { return type_ == Type::List; }
|
||||
bool IsMap() const { return type_ == Type::Map; }
|
||||
|
||||
// value getters for primitive types
|
||||
bool ValueBool() const {
|
||||
if (type_ != Type::Bool) {
|
||||
throw PropertyValueException("The value isn't a bool!");
|
||||
}
|
||||
return bool_v;
|
||||
}
|
||||
int64_t ValueInt() const {
|
||||
if (type_ != Type::Int) {
|
||||
throw PropertyValueException("The value isn't an int!");
|
||||
}
|
||||
return int_v;
|
||||
}
|
||||
double ValueDouble() const {
|
||||
if (type_ != Type::Double) {
|
||||
throw PropertyValueException("The value isn't a double!");
|
||||
}
|
||||
return double_v;
|
||||
}
|
||||
|
||||
// const value getters for non-primitive types
|
||||
const std::string &ValueString() const {
|
||||
if (type_ != Type::String) {
|
||||
throw PropertyValueException("The value isn't a string!");
|
||||
}
|
||||
return string_v;
|
||||
}
|
||||
const std::vector<PropertyValue> &ValueList() const {
|
||||
if (type_ != Type::List) {
|
||||
throw PropertyValueException("The value isn't a list!");
|
||||
}
|
||||
return list_v;
|
||||
}
|
||||
const std::map<std::string, PropertyValue> &ValueMap() const {
|
||||
if (type_ != Type::Map) {
|
||||
throw PropertyValueException("The value isn't a map!");
|
||||
}
|
||||
return map_v;
|
||||
}
|
||||
|
||||
// reference value getters for non-primitive types
|
||||
std::string &ValueString() {
|
||||
if (type_ != Type::String) {
|
||||
throw PropertyValueException("The value isn't a string!");
|
||||
}
|
||||
return string_v;
|
||||
}
|
||||
std::vector<PropertyValue> &ValueList() {
|
||||
if (type_ != Type::List) {
|
||||
throw PropertyValueException("The value isn't a list!");
|
||||
}
|
||||
return list_v;
|
||||
}
|
||||
std::map<std::string, PropertyValue> &ValueMap() {
|
||||
if (type_ != Type::Map) {
|
||||
throw PropertyValueException("The value isn't a map!");
|
||||
}
|
||||
return map_v;
|
||||
}
|
||||
|
||||
private:
|
||||
void DestroyValue() {
|
||||
switch (type_) {
|
||||
// destructor for primitive types does nothing
|
||||
case Type::Null:
|
||||
case Type::Bool:
|
||||
case Type::Int:
|
||||
case Type::Double:
|
||||
return;
|
||||
|
||||
// destructor for non primitive types since we used placement new
|
||||
case Type::String:
|
||||
// Clang fails to compile ~std::string. It seems it is a bug in some
|
||||
// versions of clang. Using namespace std statement solves the issue.
|
||||
using namespace std;
|
||||
string_v.~string();
|
||||
return;
|
||||
case Type::List:
|
||||
list_v.~vector();
|
||||
return;
|
||||
case Type::Map:
|
||||
map_v.~map();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
union {
|
||||
bool bool_v;
|
||||
int64_t int_v;
|
||||
double double_v;
|
||||
std::string string_v;
|
||||
std::vector<PropertyValue> list_v;
|
||||
std::map<std::string, PropertyValue> map_v;
|
||||
};
|
||||
|
||||
Type type_;
|
||||
};
|
||||
|
||||
// stream output
|
||||
inline std::ostream &operator<<(std::ostream &os,
|
||||
const PropertyValue::Type type) {
|
||||
switch (type) {
|
||||
case PropertyValue::Type::Null:
|
||||
return os << "null";
|
||||
case PropertyValue::Type::Bool:
|
||||
return os << "bool";
|
||||
case PropertyValue::Type::Int:
|
||||
return os << "int";
|
||||
case PropertyValue::Type::Double:
|
||||
return os << "double";
|
||||
case PropertyValue::Type::String:
|
||||
return os << "string";
|
||||
case PropertyValue::Type::List:
|
||||
return os << "list";
|
||||
case PropertyValue::Type::Map:
|
||||
return os << "map";
|
||||
}
|
||||
}
|
||||
inline std::ostream &operator<<(std::ostream &os, const PropertyValue &value) {
|
||||
switch (value.type()) {
|
||||
case PropertyValue::Type::Null:
|
||||
return os << "null";
|
||||
case PropertyValue::Type::Bool:
|
||||
return os << (value.ValueBool() ? "true" : "false");
|
||||
case PropertyValue::Type::Int:
|
||||
return os << value.ValueInt();
|
||||
case PropertyValue::Type::Double:
|
||||
return os << value.ValueDouble();
|
||||
case PropertyValue::Type::String:
|
||||
return os << value.ValueString();
|
||||
case PropertyValue::Type::List:
|
||||
os << "[";
|
||||
utils::PrintIterable(os, value.ValueList());
|
||||
return os << "]";
|
||||
case PropertyValue::Type::Map:
|
||||
os << "{";
|
||||
utils::PrintIterable(os, value.ValueMap(), ", ",
|
||||
[](auto &stream, const auto &pair) {
|
||||
stream << pair.first << ": " << pair.second;
|
||||
});
|
||||
return os << "}";
|
||||
}
|
||||
}
|
||||
|
||||
// comparison
|
||||
inline bool operator==(const PropertyValue &first,
|
||||
const PropertyValue &second) {
|
||||
if (first.type() != second.type()) return false;
|
||||
switch (first.type()) {
|
||||
case PropertyValue::Type::Null:
|
||||
return true;
|
||||
case PropertyValue::Type::Bool:
|
||||
return first.ValueBool() == second.ValueBool();
|
||||
case PropertyValue::Type::Int:
|
||||
return first.ValueInt() == second.ValueInt();
|
||||
case PropertyValue::Type::Double:
|
||||
return first.ValueDouble() == second.ValueDouble();
|
||||
case PropertyValue::Type::String:
|
||||
return first.ValueString() == second.ValueString();
|
||||
case PropertyValue::Type::List:
|
||||
return first.ValueList() == second.ValueList();
|
||||
case PropertyValue::Type::Map:
|
||||
return first.ValueMap() == second.ValueMap();
|
||||
}
|
||||
}
|
||||
inline bool operator<(const PropertyValue &first, const PropertyValue &second) {
|
||||
if (first.type() != second.type()) return first.type() < second.type();
|
||||
switch (first.type()) {
|
||||
case PropertyValue::Type::Null:
|
||||
return false;
|
||||
case PropertyValue::Type::Bool:
|
||||
return first.ValueBool() < second.ValueBool();
|
||||
case PropertyValue::Type::Int:
|
||||
return first.ValueInt() < second.ValueInt();
|
||||
case PropertyValue::Type::Double:
|
||||
return first.ValueDouble() < second.ValueDouble();
|
||||
case PropertyValue::Type::String:
|
||||
return first.ValueString() < second.ValueString();
|
||||
case PropertyValue::Type::List:
|
||||
return first.ValueList() < second.ValueList();
|
||||
case PropertyValue::Type::Map:
|
||||
return first.ValueMap() < second.ValueMap();
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace storage
|
@ -379,6 +379,9 @@ target_link_libraries(${test_prefix}auth mg-auth kvstore_lib)
|
||||
|
||||
# Test storage v2
|
||||
|
||||
add_unit_test(property_value_v2.cpp)
|
||||
target_link_libraries(${test_prefix}property_value_v2 mg-utils)
|
||||
|
||||
add_unit_test(storage_v2.cpp)
|
||||
target_link_libraries(${test_prefix}storage_v2 mg-utils)
|
||||
|
||||
|
731
tests/unit/property_value_v2.cpp
Normal file
731
tests/unit/property_value_v2.cpp
Normal file
@ -0,0 +1,731 @@
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include <sstream>
|
||||
|
||||
#include "storage/v2/property_value.hpp"
|
||||
|
||||
// NOLINTNEXTLINE(hicpp-special-member-functions)
|
||||
TEST(PropertyValue, Null) {
|
||||
storage::PropertyValue pv;
|
||||
|
||||
ASSERT_EQ(pv.type(), storage::PropertyValue::Type::Null);
|
||||
|
||||
ASSERT_TRUE(pv.IsNull());
|
||||
ASSERT_FALSE(pv.IsBool());
|
||||
ASSERT_FALSE(pv.IsInt());
|
||||
ASSERT_FALSE(pv.IsDouble());
|
||||
ASSERT_FALSE(pv.IsString());
|
||||
ASSERT_FALSE(pv.IsList());
|
||||
ASSERT_FALSE(pv.IsMap());
|
||||
|
||||
ASSERT_THROW(pv.ValueBool(), storage::PropertyValueException);
|
||||
ASSERT_THROW(pv.ValueInt(), storage::PropertyValueException);
|
||||
ASSERT_THROW(pv.ValueDouble(), storage::PropertyValueException);
|
||||
ASSERT_THROW(pv.ValueString(), storage::PropertyValueException);
|
||||
ASSERT_THROW(pv.ValueList(), storage::PropertyValueException);
|
||||
ASSERT_THROW(pv.ValueMap(), storage::PropertyValueException);
|
||||
|
||||
const auto &cpv = pv;
|
||||
|
||||
ASSERT_THROW(cpv.ValueBool(), storage::PropertyValueException);
|
||||
ASSERT_THROW(cpv.ValueInt(), storage::PropertyValueException);
|
||||
ASSERT_THROW(cpv.ValueDouble(), storage::PropertyValueException);
|
||||
ASSERT_THROW(cpv.ValueString(), storage::PropertyValueException);
|
||||
ASSERT_THROW(cpv.ValueList(), storage::PropertyValueException);
|
||||
ASSERT_THROW(cpv.ValueMap(), storage::PropertyValueException);
|
||||
|
||||
{
|
||||
std::stringstream ss;
|
||||
ss << pv.type();
|
||||
ASSERT_EQ(ss.str(), "null");
|
||||
}
|
||||
{
|
||||
std::stringstream ss;
|
||||
ss << pv;
|
||||
ASSERT_EQ(ss.str(), "null");
|
||||
}
|
||||
}
|
||||
|
||||
// NOLINTNEXTLINE(hicpp-special-member-functions)
|
||||
TEST(PropertyValue, Bool) {
|
||||
storage::PropertyValue pv(false);
|
||||
|
||||
ASSERT_EQ(pv.type(), storage::PropertyValue::Type::Bool);
|
||||
|
||||
ASSERT_FALSE(pv.IsNull());
|
||||
ASSERT_TRUE(pv.IsBool());
|
||||
ASSERT_FALSE(pv.IsInt());
|
||||
ASSERT_FALSE(pv.IsDouble());
|
||||
ASSERT_FALSE(pv.IsString());
|
||||
ASSERT_FALSE(pv.IsList());
|
||||
ASSERT_FALSE(pv.IsMap());
|
||||
|
||||
ASSERT_EQ(pv.ValueBool(), false);
|
||||
ASSERT_THROW(pv.ValueInt(), storage::PropertyValueException);
|
||||
ASSERT_THROW(pv.ValueDouble(), storage::PropertyValueException);
|
||||
ASSERT_THROW(pv.ValueString(), storage::PropertyValueException);
|
||||
ASSERT_THROW(pv.ValueList(), storage::PropertyValueException);
|
||||
ASSERT_THROW(pv.ValueMap(), storage::PropertyValueException);
|
||||
|
||||
const auto &cpv = pv;
|
||||
|
||||
ASSERT_EQ(cpv.ValueBool(), false);
|
||||
ASSERT_THROW(cpv.ValueInt(), storage::PropertyValueException);
|
||||
ASSERT_THROW(cpv.ValueDouble(), storage::PropertyValueException);
|
||||
ASSERT_THROW(cpv.ValueString(), storage::PropertyValueException);
|
||||
ASSERT_THROW(cpv.ValueList(), storage::PropertyValueException);
|
||||
ASSERT_THROW(cpv.ValueMap(), storage::PropertyValueException);
|
||||
|
||||
{
|
||||
std::stringstream ss;
|
||||
ss << pv.type();
|
||||
ASSERT_EQ(ss.str(), "bool");
|
||||
}
|
||||
{
|
||||
std::stringstream ss;
|
||||
ss << pv;
|
||||
ASSERT_EQ(ss.str(), "false");
|
||||
}
|
||||
{
|
||||
storage::PropertyValue pvtrue(true);
|
||||
std::stringstream ss;
|
||||
ss << pvtrue;
|
||||
ASSERT_EQ(ss.str(), "true");
|
||||
}
|
||||
}
|
||||
|
||||
// NOLINTNEXTLINE(hicpp-special-member-functions)
|
||||
TEST(PropertyValue, Int) {
|
||||
storage::PropertyValue pv(123L);
|
||||
|
||||
ASSERT_EQ(pv.type(), storage::PropertyValue::Type::Int);
|
||||
|
||||
ASSERT_FALSE(pv.IsNull());
|
||||
ASSERT_FALSE(pv.IsBool());
|
||||
ASSERT_TRUE(pv.IsInt());
|
||||
ASSERT_FALSE(pv.IsDouble());
|
||||
ASSERT_FALSE(pv.IsString());
|
||||
ASSERT_FALSE(pv.IsList());
|
||||
ASSERT_FALSE(pv.IsMap());
|
||||
|
||||
ASSERT_THROW(pv.ValueBool(), storage::PropertyValueException);
|
||||
ASSERT_EQ(pv.ValueInt(), 123L);
|
||||
ASSERT_THROW(pv.ValueDouble(), storage::PropertyValueException);
|
||||
ASSERT_THROW(pv.ValueString(), storage::PropertyValueException);
|
||||
ASSERT_THROW(pv.ValueList(), storage::PropertyValueException);
|
||||
ASSERT_THROW(pv.ValueMap(), storage::PropertyValueException);
|
||||
|
||||
const auto &cpv = pv;
|
||||
|
||||
ASSERT_THROW(cpv.ValueBool(), storage::PropertyValueException);
|
||||
ASSERT_EQ(cpv.ValueInt(), 123L);
|
||||
ASSERT_THROW(cpv.ValueDouble(), storage::PropertyValueException);
|
||||
ASSERT_THROW(cpv.ValueString(), storage::PropertyValueException);
|
||||
ASSERT_THROW(cpv.ValueList(), storage::PropertyValueException);
|
||||
ASSERT_THROW(cpv.ValueMap(), storage::PropertyValueException);
|
||||
|
||||
{
|
||||
std::stringstream ss;
|
||||
ss << pv.type();
|
||||
ASSERT_EQ(ss.str(), "int");
|
||||
}
|
||||
{
|
||||
std::stringstream ss;
|
||||
ss << pv;
|
||||
ASSERT_EQ(ss.str(), "123");
|
||||
}
|
||||
|
||||
{
|
||||
storage::PropertyValue pvint(123);
|
||||
ASSERT_EQ(pvint.type(), storage::PropertyValue::Type::Int);
|
||||
}
|
||||
}
|
||||
|
||||
// NOLINTNEXTLINE(hicpp-special-member-functions)
|
||||
TEST(PropertyValue, Double) {
|
||||
storage::PropertyValue pv(123.5);
|
||||
|
||||
ASSERT_EQ(pv.type(), storage::PropertyValue::Type::Double);
|
||||
|
||||
ASSERT_FALSE(pv.IsNull());
|
||||
ASSERT_FALSE(pv.IsBool());
|
||||
ASSERT_FALSE(pv.IsInt());
|
||||
ASSERT_TRUE(pv.IsDouble());
|
||||
ASSERT_FALSE(pv.IsString());
|
||||
ASSERT_FALSE(pv.IsList());
|
||||
ASSERT_FALSE(pv.IsMap());
|
||||
|
||||
ASSERT_THROW(pv.ValueBool(), storage::PropertyValueException);
|
||||
ASSERT_THROW(pv.ValueInt(), storage::PropertyValueException);
|
||||
ASSERT_EQ(pv.ValueDouble(), 123.5);
|
||||
ASSERT_THROW(pv.ValueString(), storage::PropertyValueException);
|
||||
ASSERT_THROW(pv.ValueList(), storage::PropertyValueException);
|
||||
ASSERT_THROW(pv.ValueMap(), storage::PropertyValueException);
|
||||
|
||||
const auto &cpv = pv;
|
||||
|
||||
ASSERT_THROW(cpv.ValueBool(), storage::PropertyValueException);
|
||||
ASSERT_THROW(cpv.ValueInt(), storage::PropertyValueException);
|
||||
ASSERT_EQ(cpv.ValueDouble(), 123.5);
|
||||
ASSERT_THROW(cpv.ValueString(), storage::PropertyValueException);
|
||||
ASSERT_THROW(cpv.ValueList(), storage::PropertyValueException);
|
||||
ASSERT_THROW(cpv.ValueMap(), storage::PropertyValueException);
|
||||
|
||||
{
|
||||
std::stringstream ss;
|
||||
ss << pv.type();
|
||||
ASSERT_EQ(ss.str(), "double");
|
||||
}
|
||||
{
|
||||
std::stringstream ss;
|
||||
ss << pv;
|
||||
ASSERT_EQ(ss.str(), "123.5");
|
||||
}
|
||||
}
|
||||
|
||||
// NOLINTNEXTLINE(hicpp-special-member-functions)
|
||||
TEST(PropertyValue, StringCopy) {
|
||||
std::string str("nandare");
|
||||
storage::PropertyValue pv(str);
|
||||
|
||||
ASSERT_EQ(str, "nandare");
|
||||
|
||||
ASSERT_EQ(pv.type(), storage::PropertyValue::Type::String);
|
||||
|
||||
ASSERT_FALSE(pv.IsNull());
|
||||
ASSERT_FALSE(pv.IsBool());
|
||||
ASSERT_FALSE(pv.IsInt());
|
||||
ASSERT_FALSE(pv.IsDouble());
|
||||
ASSERT_TRUE(pv.IsString());
|
||||
ASSERT_FALSE(pv.IsList());
|
||||
ASSERT_FALSE(pv.IsMap());
|
||||
|
||||
ASSERT_THROW(pv.ValueBool(), storage::PropertyValueException);
|
||||
ASSERT_THROW(pv.ValueInt(), storage::PropertyValueException);
|
||||
ASSERT_THROW(pv.ValueDouble(), storage::PropertyValueException);
|
||||
ASSERT_EQ(pv.ValueString(), "nandare");
|
||||
ASSERT_THROW(pv.ValueList(), storage::PropertyValueException);
|
||||
ASSERT_THROW(pv.ValueMap(), storage::PropertyValueException);
|
||||
|
||||
const auto &cpv = pv;
|
||||
|
||||
ASSERT_THROW(cpv.ValueBool(), storage::PropertyValueException);
|
||||
ASSERT_THROW(cpv.ValueInt(), storage::PropertyValueException);
|
||||
ASSERT_THROW(cpv.ValueDouble(), storage::PropertyValueException);
|
||||
ASSERT_EQ(cpv.ValueString(), "nandare");
|
||||
ASSERT_THROW(cpv.ValueList(), storage::PropertyValueException);
|
||||
ASSERT_THROW(cpv.ValueMap(), storage::PropertyValueException);
|
||||
|
||||
{
|
||||
std::stringstream ss;
|
||||
ss << pv.type();
|
||||
ASSERT_EQ(ss.str(), "string");
|
||||
}
|
||||
{
|
||||
std::stringstream ss;
|
||||
ss << pv;
|
||||
ASSERT_EQ(ss.str(), "nandare");
|
||||
}
|
||||
}
|
||||
|
||||
// NOLINTNEXTLINE(hicpp-special-member-functions)
|
||||
TEST(PropertyValue, StringMove) {
|
||||
std::string str("nandare");
|
||||
storage::PropertyValue pv(std::move(str));
|
||||
|
||||
ASSERT_EQ(str, "");
|
||||
|
||||
ASSERT_EQ(pv.type(), storage::PropertyValue::Type::String);
|
||||
|
||||
ASSERT_FALSE(pv.IsNull());
|
||||
ASSERT_FALSE(pv.IsBool());
|
||||
ASSERT_FALSE(pv.IsInt());
|
||||
ASSERT_FALSE(pv.IsDouble());
|
||||
ASSERT_TRUE(pv.IsString());
|
||||
ASSERT_FALSE(pv.IsList());
|
||||
ASSERT_FALSE(pv.IsMap());
|
||||
|
||||
ASSERT_THROW(pv.ValueBool(), storage::PropertyValueException);
|
||||
ASSERT_THROW(pv.ValueInt(), storage::PropertyValueException);
|
||||
ASSERT_THROW(pv.ValueDouble(), storage::PropertyValueException);
|
||||
ASSERT_EQ(pv.ValueString(), "nandare");
|
||||
ASSERT_THROW(pv.ValueList(), storage::PropertyValueException);
|
||||
ASSERT_THROW(pv.ValueMap(), storage::PropertyValueException);
|
||||
|
||||
const auto &cpv = pv;
|
||||
|
||||
ASSERT_THROW(cpv.ValueBool(), storage::PropertyValueException);
|
||||
ASSERT_THROW(cpv.ValueInt(), storage::PropertyValueException);
|
||||
ASSERT_THROW(cpv.ValueDouble(), storage::PropertyValueException);
|
||||
ASSERT_EQ(cpv.ValueString(), "nandare");
|
||||
ASSERT_THROW(cpv.ValueList(), storage::PropertyValueException);
|
||||
ASSERT_THROW(cpv.ValueMap(), storage::PropertyValueException);
|
||||
|
||||
{
|
||||
std::stringstream ss;
|
||||
ss << pv.type();
|
||||
ASSERT_EQ(ss.str(), "string");
|
||||
}
|
||||
{
|
||||
std::stringstream ss;
|
||||
ss << pv;
|
||||
ASSERT_EQ(ss.str(), "nandare");
|
||||
}
|
||||
}
|
||||
|
||||
// NOLINTNEXTLINE(hicpp-special-member-functions)
|
||||
TEST(PropertyValue, ListCopy) {
|
||||
std::vector<storage::PropertyValue> vec{storage::PropertyValue("nandare"),
|
||||
storage::PropertyValue(123)};
|
||||
storage::PropertyValue pv(vec);
|
||||
|
||||
ASSERT_EQ(vec.size(), 2);
|
||||
ASSERT_EQ(vec[0].ValueString(), "nandare");
|
||||
ASSERT_EQ(vec[1].ValueInt(), 123);
|
||||
|
||||
ASSERT_EQ(pv.type(), storage::PropertyValue::Type::List);
|
||||
|
||||
ASSERT_FALSE(pv.IsNull());
|
||||
ASSERT_FALSE(pv.IsBool());
|
||||
ASSERT_FALSE(pv.IsInt());
|
||||
ASSERT_FALSE(pv.IsDouble());
|
||||
ASSERT_FALSE(pv.IsString());
|
||||
ASSERT_TRUE(pv.IsList());
|
||||
ASSERT_FALSE(pv.IsMap());
|
||||
|
||||
ASSERT_THROW(pv.ValueBool(), storage::PropertyValueException);
|
||||
ASSERT_THROW(pv.ValueInt(), storage::PropertyValueException);
|
||||
ASSERT_THROW(pv.ValueDouble(), storage::PropertyValueException);
|
||||
ASSERT_THROW(pv.ValueString(), storage::PropertyValueException);
|
||||
{
|
||||
const auto &ret = pv.ValueList();
|
||||
ASSERT_EQ(ret.size(), 2);
|
||||
ASSERT_EQ(ret[0].ValueString(), "nandare");
|
||||
ASSERT_EQ(ret[1].ValueInt(), 123);
|
||||
}
|
||||
ASSERT_THROW(pv.ValueMap(), storage::PropertyValueException);
|
||||
|
||||
const auto &cpv = pv;
|
||||
|
||||
ASSERT_THROW(cpv.ValueBool(), storage::PropertyValueException);
|
||||
ASSERT_THROW(cpv.ValueInt(), storage::PropertyValueException);
|
||||
ASSERT_THROW(cpv.ValueDouble(), storage::PropertyValueException);
|
||||
ASSERT_THROW(cpv.ValueString(), storage::PropertyValueException);
|
||||
{
|
||||
const auto &ret = cpv.ValueList();
|
||||
ASSERT_EQ(ret.size(), 2);
|
||||
ASSERT_EQ(ret[0].ValueString(), "nandare");
|
||||
ASSERT_EQ(ret[1].ValueInt(), 123);
|
||||
}
|
||||
ASSERT_THROW(cpv.ValueMap(), storage::PropertyValueException);
|
||||
|
||||
{
|
||||
std::stringstream ss;
|
||||
ss << pv.type();
|
||||
ASSERT_EQ(ss.str(), "list");
|
||||
}
|
||||
{
|
||||
std::stringstream ss;
|
||||
ss << pv;
|
||||
ASSERT_EQ(ss.str(), "[nandare, 123]");
|
||||
}
|
||||
}
|
||||
|
||||
// NOLINTNEXTLINE(hicpp-special-member-functions)
|
||||
TEST(PropertyValue, ListMove) {
|
||||
std::vector<storage::PropertyValue> vec{storage::PropertyValue("nandare"),
|
||||
storage::PropertyValue(123)};
|
||||
storage::PropertyValue pv(std::move(vec));
|
||||
|
||||
ASSERT_EQ(vec.size(), 0);
|
||||
|
||||
ASSERT_EQ(pv.type(), storage::PropertyValue::Type::List);
|
||||
|
||||
ASSERT_FALSE(pv.IsNull());
|
||||
ASSERT_FALSE(pv.IsBool());
|
||||
ASSERT_FALSE(pv.IsInt());
|
||||
ASSERT_FALSE(pv.IsDouble());
|
||||
ASSERT_FALSE(pv.IsString());
|
||||
ASSERT_TRUE(pv.IsList());
|
||||
ASSERT_FALSE(pv.IsMap());
|
||||
|
||||
ASSERT_THROW(pv.ValueBool(), storage::PropertyValueException);
|
||||
ASSERT_THROW(pv.ValueInt(), storage::PropertyValueException);
|
||||
ASSERT_THROW(pv.ValueDouble(), storage::PropertyValueException);
|
||||
ASSERT_THROW(pv.ValueString(), storage::PropertyValueException);
|
||||
{
|
||||
const auto &ret = pv.ValueList();
|
||||
ASSERT_EQ(ret.size(), 2);
|
||||
ASSERT_EQ(ret[0].ValueString(), "nandare");
|
||||
ASSERT_EQ(ret[1].ValueInt(), 123);
|
||||
}
|
||||
ASSERT_THROW(pv.ValueMap(), storage::PropertyValueException);
|
||||
|
||||
const auto &cpv = pv;
|
||||
|
||||
ASSERT_THROW(cpv.ValueBool(), storage::PropertyValueException);
|
||||
ASSERT_THROW(cpv.ValueInt(), storage::PropertyValueException);
|
||||
ASSERT_THROW(cpv.ValueDouble(), storage::PropertyValueException);
|
||||
ASSERT_THROW(cpv.ValueString(), storage::PropertyValueException);
|
||||
{
|
||||
const auto &ret = cpv.ValueList();
|
||||
ASSERT_EQ(ret.size(), 2);
|
||||
ASSERT_EQ(ret[0].ValueString(), "nandare");
|
||||
ASSERT_EQ(ret[1].ValueInt(), 123);
|
||||
}
|
||||
ASSERT_THROW(cpv.ValueMap(), storage::PropertyValueException);
|
||||
|
||||
{
|
||||
std::stringstream ss;
|
||||
ss << pv.type();
|
||||
ASSERT_EQ(ss.str(), "list");
|
||||
}
|
||||
{
|
||||
std::stringstream ss;
|
||||
ss << pv;
|
||||
ASSERT_EQ(ss.str(), "[nandare, 123]");
|
||||
}
|
||||
}
|
||||
|
||||
// NOLINTNEXTLINE(hicpp-special-member-functions)
|
||||
TEST(PropertyValue, MapCopy) {
|
||||
std::map<std::string, storage::PropertyValue> map{
|
||||
{"nandare", storage::PropertyValue(123)}};
|
||||
storage::PropertyValue pv(map);
|
||||
|
||||
ASSERT_EQ(map.size(), 1);
|
||||
ASSERT_EQ(map.at("nandare").ValueInt(), 123);
|
||||
|
||||
ASSERT_EQ(pv.type(), storage::PropertyValue::Type::Map);
|
||||
|
||||
ASSERT_FALSE(pv.IsNull());
|
||||
ASSERT_FALSE(pv.IsBool());
|
||||
ASSERT_FALSE(pv.IsInt());
|
||||
ASSERT_FALSE(pv.IsDouble());
|
||||
ASSERT_FALSE(pv.IsString());
|
||||
ASSERT_FALSE(pv.IsList());
|
||||
ASSERT_TRUE(pv.IsMap());
|
||||
|
||||
ASSERT_THROW(pv.ValueBool(), storage::PropertyValueException);
|
||||
ASSERT_THROW(pv.ValueInt(), storage::PropertyValueException);
|
||||
ASSERT_THROW(pv.ValueDouble(), storage::PropertyValueException);
|
||||
ASSERT_THROW(pv.ValueString(), storage::PropertyValueException);
|
||||
ASSERT_THROW(pv.ValueList(), storage::PropertyValueException);
|
||||
{
|
||||
const auto &ret = pv.ValueMap();
|
||||
ASSERT_EQ(ret.size(), 1);
|
||||
ASSERT_EQ(ret.at("nandare").ValueInt(), 123);
|
||||
}
|
||||
|
||||
const auto &cpv = pv;
|
||||
|
||||
ASSERT_THROW(cpv.ValueBool(), storage::PropertyValueException);
|
||||
ASSERT_THROW(cpv.ValueInt(), storage::PropertyValueException);
|
||||
ASSERT_THROW(cpv.ValueDouble(), storage::PropertyValueException);
|
||||
ASSERT_THROW(cpv.ValueString(), storage::PropertyValueException);
|
||||
ASSERT_THROW(cpv.ValueList(), storage::PropertyValueException);
|
||||
{
|
||||
const auto &ret = cpv.ValueMap();
|
||||
ASSERT_EQ(ret.size(), 1);
|
||||
ASSERT_EQ(ret.at("nandare").ValueInt(), 123);
|
||||
}
|
||||
|
||||
{
|
||||
std::stringstream ss;
|
||||
ss << pv.type();
|
||||
ASSERT_EQ(ss.str(), "map");
|
||||
}
|
||||
{
|
||||
std::stringstream ss;
|
||||
ss << pv;
|
||||
ASSERT_EQ(ss.str(), "{nandare: 123}");
|
||||
}
|
||||
}
|
||||
|
||||
// NOLINTNEXTLINE(hicpp-special-member-functions)
|
||||
TEST(PropertyValue, MapMove) {
|
||||
std::map<std::string, storage::PropertyValue> map{
|
||||
{"nandare", storage::PropertyValue(123)}};
|
||||
storage::PropertyValue pv(std::move(map));
|
||||
|
||||
ASSERT_EQ(map.size(), 0);
|
||||
|
||||
ASSERT_EQ(pv.type(), storage::PropertyValue::Type::Map);
|
||||
|
||||
ASSERT_FALSE(pv.IsNull());
|
||||
ASSERT_FALSE(pv.IsBool());
|
||||
ASSERT_FALSE(pv.IsInt());
|
||||
ASSERT_FALSE(pv.IsDouble());
|
||||
ASSERT_FALSE(pv.IsString());
|
||||
ASSERT_FALSE(pv.IsList());
|
||||
ASSERT_TRUE(pv.IsMap());
|
||||
|
||||
ASSERT_THROW(pv.ValueBool(), storage::PropertyValueException);
|
||||
ASSERT_THROW(pv.ValueInt(), storage::PropertyValueException);
|
||||
ASSERT_THROW(pv.ValueDouble(), storage::PropertyValueException);
|
||||
ASSERT_THROW(pv.ValueString(), storage::PropertyValueException);
|
||||
ASSERT_THROW(pv.ValueList(), storage::PropertyValueException);
|
||||
{
|
||||
const auto &ret = pv.ValueMap();
|
||||
ASSERT_EQ(ret.size(), 1);
|
||||
ASSERT_EQ(ret.at("nandare").ValueInt(), 123);
|
||||
}
|
||||
|
||||
const auto &cpv = pv;
|
||||
|
||||
ASSERT_THROW(cpv.ValueBool(), storage::PropertyValueException);
|
||||
ASSERT_THROW(cpv.ValueInt(), storage::PropertyValueException);
|
||||
ASSERT_THROW(cpv.ValueDouble(), storage::PropertyValueException);
|
||||
ASSERT_THROW(cpv.ValueString(), storage::PropertyValueException);
|
||||
ASSERT_THROW(cpv.ValueList(), storage::PropertyValueException);
|
||||
{
|
||||
const auto &ret = cpv.ValueMap();
|
||||
ASSERT_EQ(ret.size(), 1);
|
||||
ASSERT_EQ(ret.at("nandare").ValueInt(), 123);
|
||||
}
|
||||
|
||||
{
|
||||
std::stringstream ss;
|
||||
ss << pv.type();
|
||||
ASSERT_EQ(ss.str(), "map");
|
||||
}
|
||||
{
|
||||
std::stringstream ss;
|
||||
ss << pv;
|
||||
ASSERT_EQ(ss.str(), "{nandare: 123}");
|
||||
}
|
||||
}
|
||||
|
||||
// NOLINTNEXTLINE(hicpp-special-member-functions)
|
||||
TEST(PropertyValue, CopyConstructor) {
|
||||
std::vector<storage::PropertyValue> vec{storage::PropertyValue(true),
|
||||
storage::PropertyValue(123)};
|
||||
std::map<std::string, storage::PropertyValue> map{
|
||||
{"nandare", storage::PropertyValue(false)}};
|
||||
std::vector<storage::PropertyValue> data{
|
||||
storage::PropertyValue(), storage::PropertyValue(true),
|
||||
storage::PropertyValue(123), storage::PropertyValue(123.5),
|
||||
storage::PropertyValue("nandare"), storage::PropertyValue(vec),
|
||||
storage::PropertyValue(map)};
|
||||
for (const auto &item : data) {
|
||||
storage::PropertyValue pv(item);
|
||||
ASSERT_EQ(pv.type(), item.type());
|
||||
switch (item.type()) {
|
||||
case storage::PropertyValue::Type::Null:
|
||||
ASSERT_TRUE(pv.IsNull());
|
||||
break;
|
||||
case storage::PropertyValue::Type::Bool:
|
||||
ASSERT_EQ(pv.ValueBool(), item.ValueBool());
|
||||
break;
|
||||
case storage::PropertyValue::Type::Int:
|
||||
ASSERT_EQ(pv.ValueInt(), item.ValueInt());
|
||||
break;
|
||||
case storage::PropertyValue::Type::Double:
|
||||
ASSERT_EQ(pv.ValueDouble(), item.ValueDouble());
|
||||
break;
|
||||
case storage::PropertyValue::Type::String:
|
||||
ASSERT_EQ(pv.ValueString(), item.ValueString());
|
||||
break;
|
||||
case storage::PropertyValue::Type::List:
|
||||
ASSERT_EQ(pv.ValueList(), item.ValueList());
|
||||
break;
|
||||
case storage::PropertyValue::Type::Map:
|
||||
ASSERT_EQ(pv.ValueMap(), item.ValueMap());
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// NOLINTNEXTLINE(hicpp-special-member-functions)
|
||||
TEST(PropertyValue, MoveConstructor) {
|
||||
std::vector<storage::PropertyValue> vec{storage::PropertyValue(true),
|
||||
storage::PropertyValue(123)};
|
||||
std::map<std::string, storage::PropertyValue> map{
|
||||
{"nandare", storage::PropertyValue(false)}};
|
||||
std::vector<storage::PropertyValue> data{
|
||||
storage::PropertyValue(), storage::PropertyValue(true),
|
||||
storage::PropertyValue(123), storage::PropertyValue(123.5),
|
||||
storage::PropertyValue("nandare"), storage::PropertyValue(vec),
|
||||
storage::PropertyValue(map)};
|
||||
for (auto &item : data) {
|
||||
storage::PropertyValue copy(item);
|
||||
storage::PropertyValue pv(std::move(item));
|
||||
ASSERT_EQ(item.type(), storage::PropertyValue::Type::Null);
|
||||
ASSERT_EQ(pv.type(), copy.type());
|
||||
switch (copy.type()) {
|
||||
case storage::PropertyValue::Type::Null:
|
||||
ASSERT_TRUE(pv.IsNull());
|
||||
break;
|
||||
case storage::PropertyValue::Type::Bool:
|
||||
ASSERT_EQ(pv.ValueBool(), copy.ValueBool());
|
||||
break;
|
||||
case storage::PropertyValue::Type::Int:
|
||||
ASSERT_EQ(pv.ValueInt(), copy.ValueInt());
|
||||
break;
|
||||
case storage::PropertyValue::Type::Double:
|
||||
ASSERT_EQ(pv.ValueDouble(), copy.ValueDouble());
|
||||
break;
|
||||
case storage::PropertyValue::Type::String:
|
||||
ASSERT_EQ(pv.ValueString(), copy.ValueString());
|
||||
break;
|
||||
case storage::PropertyValue::Type::List:
|
||||
ASSERT_EQ(pv.ValueList(), copy.ValueList());
|
||||
break;
|
||||
case storage::PropertyValue::Type::Map:
|
||||
ASSERT_EQ(pv.ValueMap(), copy.ValueMap());
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// NOLINTNEXTLINE(hicpp-special-member-functions)
|
||||
TEST(PropertyValue, CopyAssignment) {
|
||||
std::vector<storage::PropertyValue> vec{storage::PropertyValue(true),
|
||||
storage::PropertyValue(123)};
|
||||
std::map<std::string, storage::PropertyValue> map{
|
||||
{"nandare", storage::PropertyValue(false)}};
|
||||
std::vector<storage::PropertyValue> data{
|
||||
storage::PropertyValue(), storage::PropertyValue(true),
|
||||
storage::PropertyValue(123), storage::PropertyValue(123.5),
|
||||
storage::PropertyValue("nandare"), storage::PropertyValue(vec),
|
||||
storage::PropertyValue(map)};
|
||||
for (const auto &item : data) {
|
||||
storage::PropertyValue pv(123);
|
||||
pv = item;
|
||||
ASSERT_EQ(pv.type(), item.type());
|
||||
switch (item.type()) {
|
||||
case storage::PropertyValue::Type::Null:
|
||||
ASSERT_TRUE(pv.IsNull());
|
||||
break;
|
||||
case storage::PropertyValue::Type::Bool:
|
||||
ASSERT_EQ(pv.ValueBool(), item.ValueBool());
|
||||
break;
|
||||
case storage::PropertyValue::Type::Int:
|
||||
ASSERT_EQ(pv.ValueInt(), item.ValueInt());
|
||||
break;
|
||||
case storage::PropertyValue::Type::Double:
|
||||
ASSERT_EQ(pv.ValueDouble(), item.ValueDouble());
|
||||
break;
|
||||
case storage::PropertyValue::Type::String:
|
||||
ASSERT_EQ(pv.ValueString(), item.ValueString());
|
||||
break;
|
||||
case storage::PropertyValue::Type::List:
|
||||
ASSERT_EQ(pv.ValueList(), item.ValueList());
|
||||
break;
|
||||
case storage::PropertyValue::Type::Map:
|
||||
ASSERT_EQ(pv.ValueMap(), item.ValueMap());
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// NOLINTNEXTLINE(hicpp-special-member-functions)
|
||||
TEST(PropertyValue, MoveAssignment) {
|
||||
std::vector<storage::PropertyValue> vec{storage::PropertyValue(true),
|
||||
storage::PropertyValue(123)};
|
||||
std::map<std::string, storage::PropertyValue> map{
|
||||
{"nandare", storage::PropertyValue(false)}};
|
||||
std::vector<storage::PropertyValue> data{
|
||||
storage::PropertyValue(), storage::PropertyValue(true),
|
||||
storage::PropertyValue(123), storage::PropertyValue(123.5),
|
||||
storage::PropertyValue("nandare"), storage::PropertyValue(vec),
|
||||
storage::PropertyValue(map)};
|
||||
for (auto &item : data) {
|
||||
storage::PropertyValue copy(item);
|
||||
storage::PropertyValue pv(123);
|
||||
pv = std::move(item);
|
||||
ASSERT_EQ(item.type(), storage::PropertyValue::Type::Null);
|
||||
ASSERT_EQ(pv.type(), copy.type());
|
||||
switch (copy.type()) {
|
||||
case storage::PropertyValue::Type::Null:
|
||||
ASSERT_TRUE(pv.IsNull());
|
||||
break;
|
||||
case storage::PropertyValue::Type::Bool:
|
||||
ASSERT_EQ(pv.ValueBool(), copy.ValueBool());
|
||||
break;
|
||||
case storage::PropertyValue::Type::Int:
|
||||
ASSERT_EQ(pv.ValueInt(), copy.ValueInt());
|
||||
break;
|
||||
case storage::PropertyValue::Type::Double:
|
||||
ASSERT_EQ(pv.ValueDouble(), copy.ValueDouble());
|
||||
break;
|
||||
case storage::PropertyValue::Type::String:
|
||||
ASSERT_EQ(pv.ValueString(), copy.ValueString());
|
||||
break;
|
||||
case storage::PropertyValue::Type::List:
|
||||
ASSERT_EQ(pv.ValueList(), copy.ValueList());
|
||||
break;
|
||||
case storage::PropertyValue::Type::Map:
|
||||
ASSERT_EQ(pv.ValueMap(), copy.ValueMap());
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// NOLINTNEXTLINE(hicpp-special-member-functions)
|
||||
TEST(PropertyValue, CopyAssignmentSelf) {
|
||||
storage::PropertyValue pv("nandare");
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wself-assign-overloaded"
|
||||
pv = pv;
|
||||
#pragma clang diagnostic pop
|
||||
ASSERT_EQ(pv.type(), storage::PropertyValue::Type::String);
|
||||
ASSERT_EQ(pv.ValueString(), "nandare");
|
||||
}
|
||||
|
||||
// NOLINTNEXTLINE(hicpp-special-member-functions)
|
||||
TEST(PropertyValue, MoveAssignmentSelf) {
|
||||
storage::PropertyValue pv("nandare");
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wself-move"
|
||||
pv = std::move(pv);
|
||||
#pragma clang diagnostic pop
|
||||
ASSERT_EQ(pv.type(), storage::PropertyValue::Type::String);
|
||||
ASSERT_EQ(pv.ValueString(), "nandare");
|
||||
}
|
||||
|
||||
// NOLINTNEXTLINE(hicpp-special-member-functions)
|
||||
TEST(PropertyValue, Equal) {
|
||||
std::vector<storage::PropertyValue> vec{storage::PropertyValue(true),
|
||||
storage::PropertyValue(123)};
|
||||
std::map<std::string, storage::PropertyValue> map{
|
||||
{"nandare", storage::PropertyValue(false)}};
|
||||
std::vector<storage::PropertyValue> data{
|
||||
storage::PropertyValue(), storage::PropertyValue(true),
|
||||
storage::PropertyValue(123), storage::PropertyValue(123.5),
|
||||
storage::PropertyValue("nandare"), storage::PropertyValue(vec),
|
||||
storage::PropertyValue(map)};
|
||||
for (const auto item1 : data) {
|
||||
for (const auto item2 : data) {
|
||||
if (item1.type() == item2.type()) {
|
||||
ASSERT_TRUE(item1 == item2);
|
||||
} else {
|
||||
ASSERT_FALSE(item1 == item2);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// NOLINTNEXTLINE(hicpp-special-member-functions)
|
||||
TEST(PropertyValue, Less) {
|
||||
std::vector<storage::PropertyValue> vec{storage::PropertyValue(true),
|
||||
storage::PropertyValue(123)};
|
||||
std::map<std::string, storage::PropertyValue> map{
|
||||
{"nandare", storage::PropertyValue(false)}};
|
||||
std::vector<storage::PropertyValue> data{
|
||||
storage::PropertyValue(), storage::PropertyValue(true),
|
||||
storage::PropertyValue(123), storage::PropertyValue(123.5),
|
||||
storage::PropertyValue("nandare"), storage::PropertyValue(vec),
|
||||
storage::PropertyValue(map)};
|
||||
for (size_t i = 0; i < data.size(); ++i) {
|
||||
for (size_t j = 0; j < data.size(); ++j) {
|
||||
auto item1 = data[i];
|
||||
auto item2 = data[j];
|
||||
if (i < j) {
|
||||
ASSERT_TRUE(item1 < item2);
|
||||
} else {
|
||||
ASSERT_FALSE(item1 < item2);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user