mirror of
https://gitee.com/zyjblog/oatpp.git
synced 2025-01-05 17:42:23 +08:00
Merge pull request #241 from oatpp/dto_hashcode_equals
Dto hashcode equals
This commit is contained in:
commit
b209cc2684
@ -11,6 +11,7 @@ Contents:
|
||||
- [Object-Mapping std Collections](#object-mapping-std-collections)
|
||||
- [Type oatpp::Any](#type-oatppany)
|
||||
- [Type oatpp::Enum](#object-mapping-enum)
|
||||
- [DTO - Hashcode & Equals](#dto-hashcode-and-equals)
|
||||
|
||||
## No more explicit ObjectWrapper
|
||||
|
||||
@ -272,3 +273,27 @@ class MyDto : public oatpp::Object {
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## DTO Hashcode and Equals
|
||||
|
||||
Now DTOs can be used as a Key in `unordered_map` and `unordered_set`.
|
||||
The convenience `DTO_HC_EQ` (DTO_HASHCODE_AND_EQUALS) macro has been added.
|
||||
|
||||
```cpp
|
||||
class User : public oatpp::Object {
|
||||
|
||||
DTO_INIT(User, Object)
|
||||
|
||||
DTO_FIELD(String, firstName);
|
||||
DTO_FIELD(String, lastName);
|
||||
|
||||
DTO_HC_EQ(firstName, lastName) // List key fields that count in std::hash and "==","!=" operators.
|
||||
|
||||
};
|
||||
```
|
||||
|
||||
The `DTO_HC_EQ` macro works taking into account the `DTO_HC_EQ` declared in the parent DTO class.
|
||||
|
||||
If no `DTO_HC_EQ` is declared in none of the DTO's parent classes the default behavior is:
|
||||
- `std::hash` - is `v_uint64` representation of object address.
|
||||
- operators `==` and `!=` - is comparison of object addresses.
|
||||
|
@ -34,7 +34,7 @@
|
||||
public: \
|
||||
typedef TYPE_NAME Z__CLASS; \
|
||||
typedef TYPE_EXTEND Z__CLASS_EXTENDED; \
|
||||
typedef oatpp::data::mapping::type::ObjectWrapper<Z__CLASS, oatpp::data::mapping::type::__class::Object<Z__CLASS>> ObjectWrapper; \
|
||||
typedef oatpp::data::mapping::type::DTOWrapper<Z__CLASS> ObjectWrapper; \
|
||||
typedef ObjectWrapper __Wrapper; \
|
||||
public: \
|
||||
OBJECT_POOL(DTO_OBJECT_POOL_##TYPE_NAME, TYPE_NAME, 32) \
|
||||
@ -121,3 +121,43 @@ TYPE::__Wrapper NAME
|
||||
*/
|
||||
#define DTO_FIELD(TYPE, ...) \
|
||||
OATPP_MACRO_EXPAND(OATPP_MACRO_MACRO_SELECTOR(OATPP_MACRO_DTO_FIELD_, (__VA_ARGS__)) (TYPE, __VA_ARGS__))
|
||||
|
||||
// FOR EACH
|
||||
|
||||
#define OATPP_MACRO_DTO_HC_EQ_PARAM_HC(INDEX, COUNT, X) \
|
||||
result = ((result << 5) - result) + std::hash<decltype(X)>{}(X);
|
||||
|
||||
#define OATPP_MACRO_DTO_HC_EQ_PARAM_EQ(INDEX, COUNT, X) \
|
||||
&& X == other.X
|
||||
|
||||
#define DTO_HASHCODE_AND_EQUALS(...) \
|
||||
v_uint64 defaultHashCode() const override { \
|
||||
return 1; \
|
||||
} \
|
||||
\
|
||||
bool defaultEquals(const Object& other) const override { \
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
v_uint64 hashCode() const { \
|
||||
v_uint64 result = 1; \
|
||||
result = ((result << 5) - result) + static_cast<const Z__CLASS_EXTENDED&>(*this).hashCode(); \
|
||||
OATPP_MACRO_FOREACH(OATPP_MACRO_DTO_HC_EQ_PARAM_HC, __VA_ARGS__) \
|
||||
return result; \
|
||||
} \
|
||||
\
|
||||
bool operator==(const Z__CLASS& other) const { \
|
||||
return static_cast<const Z__CLASS_EXTENDED&>(*this) == static_cast<const Z__CLASS_EXTENDED&>(other) \
|
||||
OATPP_MACRO_FOREACH(OATPP_MACRO_DTO_HC_EQ_PARAM_EQ, __VA_ARGS__) \
|
||||
; \
|
||||
} \
|
||||
\
|
||||
bool operator!=(const Z__CLASS& other) const { \
|
||||
return !this->operator==(other); \
|
||||
}
|
||||
|
||||
/**
|
||||
* Hashcode and Equals macro. <br>
|
||||
* List DTO-fields which should count in hashcode and equals operators.
|
||||
*/
|
||||
#define DTO_HC_EQ(...) DTO_HASHCODE_AND_EQUALS(__VA_ARGS__)
|
||||
|
@ -31,3 +31,10 @@
|
||||
#undef OATPP_MACRO_DTO_FIELD_1
|
||||
#undef OATPP_MACRO_DTO_FIELD_2
|
||||
#undef DTO_FIELD
|
||||
|
||||
// Hashcode & Equals
|
||||
|
||||
#undef OATPP_MACRO_DTO_HC_EQ_PARAM_HC
|
||||
#undef OATPP_MACRO_DTO_HC_EQ_PARAM_EQ
|
||||
#undef DTO_HASHCODE_AND_EQUALS
|
||||
#undef DTO_HC_EQ
|
||||
|
@ -39,6 +39,8 @@
|
||||
#include "oatpp/core/base/memory/ObjectPool.hpp"
|
||||
#include "oatpp/core/base/Countable.hpp"
|
||||
|
||||
#include <type_traits>
|
||||
|
||||
namespace oatpp { namespace data { namespace mapping { namespace type {
|
||||
|
||||
namespace __class {
|
||||
@ -121,9 +123,89 @@ public:
|
||||
static oatpp::data::mapping::type::Type::Properties map;
|
||||
return ↦
|
||||
}
|
||||
|
||||
|
||||
virtual v_uint64 defaultHashCode() const {
|
||||
return (v_uint64) reinterpret_cast<v_buff_usize>(this);
|
||||
}
|
||||
|
||||
virtual bool defaultEquals(const Object& other) const {
|
||||
return this == &other;
|
||||
}
|
||||
|
||||
v_uint64 hashCode() const {
|
||||
return defaultHashCode();
|
||||
}
|
||||
|
||||
bool operator==(const Object& other) const {
|
||||
return defaultEquals(other);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
template<class ObjT>
|
||||
class DTOWrapper : public ObjectWrapper<ObjT, __class::Object<ObjT>> {
|
||||
public:
|
||||
typedef ObjT TemplateObjectType;
|
||||
typedef __class::Object<ObjT> TemplateObjectClass;
|
||||
public:
|
||||
|
||||
OATPP_DEFINE_OBJECT_WRAPPER_DEFAULTS(DTOWrapper, TemplateObjectType, TemplateObjectClass)
|
||||
|
||||
static DTOWrapper createShared() {
|
||||
return std::make_shared<TemplateObjectType>();
|
||||
}
|
||||
|
||||
template<typename T,
|
||||
typename enabled = typename std::enable_if<std::is_same<T, std::nullptr_t>::value, void>::type
|
||||
>
|
||||
inline bool operator == (T){
|
||||
return this->m_ptr.get() == nullptr;
|
||||
}
|
||||
|
||||
template<typename T,
|
||||
typename enabled = typename std::enable_if<std::is_same<T, std::nullptr_t>::value, void>::type
|
||||
>
|
||||
inline bool operator != (T){
|
||||
return this->m_ptr.get() != nullptr;
|
||||
}
|
||||
|
||||
template<typename T,
|
||||
typename enabled = typename std::enable_if<std::is_same<T, DTOWrapper>::value, void>::type
|
||||
>
|
||||
inline bool operator == (const T &other) const {
|
||||
if(this->m_ptr.get() == other.m_ptr.get()) return true;
|
||||
if(!this->m_ptr || !other.m_ptr) return false;
|
||||
return *this->m_ptr == *other.m_ptr;
|
||||
}
|
||||
|
||||
template<typename T,
|
||||
typename enabled = typename std::enable_if<std::is_same<T, DTOWrapper>::value, void>::type
|
||||
>
|
||||
inline bool operator != (const T &other) const {
|
||||
return !operator == (other);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
}}}}
|
||||
|
||||
namespace std {
|
||||
|
||||
template<class T>
|
||||
struct hash<oatpp::data::mapping::type::DTOWrapper<T>> {
|
||||
|
||||
typedef oatpp::data::mapping::type::DTOWrapper<T> argument_type;
|
||||
typedef v_uint64 result_type;
|
||||
|
||||
result_type operator()(argument_type const &ow) const noexcept {
|
||||
if(ow) {
|
||||
return ow->hashCode();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif /* oatpp_data_type_Object_hpp */
|
||||
|
@ -549,9 +549,10 @@ namespace std {
|
||||
struct hash<oatpp::data::mapping::type::String> {
|
||||
|
||||
typedef oatpp::data::mapping::type::String argument_type;
|
||||
typedef v_uint32 result_type;
|
||||
typedef v_uint64 result_type;
|
||||
|
||||
result_type operator()(argument_type const& s) const noexcept {
|
||||
if(s.get() == nullptr) return 0;
|
||||
|
||||
p_char8 data = s->getData();
|
||||
result_type result = 0;
|
||||
@ -570,7 +571,7 @@ namespace std {
|
||||
struct hash<oatpp::data::mapping::type::Boolean> {
|
||||
|
||||
typedef oatpp::data::mapping::type::Boolean argument_type;
|
||||
typedef v_uint8 result_type;
|
||||
typedef v_uint64 result_type;
|
||||
|
||||
result_type operator()(argument_type const& v) const noexcept {
|
||||
if(v.get() == nullptr) return 2;
|
||||
@ -583,7 +584,7 @@ namespace std {
|
||||
struct hash<oatpp::data::mapping::type::Int8> {
|
||||
|
||||
typedef oatpp::data::mapping::type::Int8 argument_type;
|
||||
typedef v_uint8 result_type;
|
||||
typedef v_uint64 result_type;
|
||||
|
||||
result_type operator()(argument_type const& v) const noexcept {
|
||||
if(v.get() == nullptr) return 0;
|
||||
@ -596,7 +597,7 @@ namespace std {
|
||||
struct hash<oatpp::data::mapping::type::UInt8> {
|
||||
|
||||
typedef oatpp::data::mapping::type::UInt8 argument_type;
|
||||
typedef v_uint8 result_type;
|
||||
typedef v_uint64 result_type;
|
||||
|
||||
result_type operator()(argument_type const& v) const noexcept {
|
||||
if(v.get() == nullptr) return 0;
|
||||
@ -609,7 +610,7 @@ namespace std {
|
||||
struct hash<oatpp::data::mapping::type::Int16> {
|
||||
|
||||
typedef oatpp::data::mapping::type::Int16 argument_type;
|
||||
typedef v_uint16 result_type;
|
||||
typedef v_uint64 result_type;
|
||||
|
||||
result_type operator()(argument_type const& v) const noexcept {
|
||||
if(v.get() == nullptr) return 0;
|
||||
@ -622,7 +623,7 @@ namespace std {
|
||||
struct hash<oatpp::data::mapping::type::UInt16> {
|
||||
|
||||
typedef oatpp::data::mapping::type::UInt16 argument_type;
|
||||
typedef v_uint16 result_type;
|
||||
typedef v_uint64 result_type;
|
||||
|
||||
result_type operator()(argument_type const& v) const noexcept {
|
||||
if(v.get() == nullptr) return 0;
|
||||
@ -635,7 +636,7 @@ namespace std {
|
||||
struct hash<oatpp::data::mapping::type::Int32> {
|
||||
|
||||
typedef oatpp::data::mapping::type::Int32 argument_type;
|
||||
typedef v_uint32 result_type;
|
||||
typedef v_uint64 result_type;
|
||||
|
||||
result_type operator()(argument_type const& v) const noexcept {
|
||||
if(v.get() == nullptr) return 0;
|
||||
@ -648,7 +649,7 @@ namespace std {
|
||||
struct hash<oatpp::data::mapping::type::UInt32> {
|
||||
|
||||
typedef oatpp::data::mapping::type::UInt32 argument_type;
|
||||
typedef v_uint32 result_type;
|
||||
typedef v_uint64 result_type;
|
||||
|
||||
result_type operator()(argument_type const& v) const noexcept {
|
||||
if(v.get() == nullptr) return 0;
|
||||
@ -687,11 +688,11 @@ namespace std {
|
||||
struct hash<oatpp::data::mapping::type::Float32> {
|
||||
|
||||
typedef oatpp::data::mapping::type::Float32 argument_type;
|
||||
typedef v_uint32 result_type;
|
||||
typedef v_uint64 result_type;
|
||||
|
||||
result_type operator()(argument_type const& v) const noexcept {
|
||||
if(v.get() == nullptr) return 0;
|
||||
return *((result_type*) v.get());
|
||||
return *((v_uint32*) v.get());
|
||||
}
|
||||
|
||||
};
|
||||
|
@ -423,7 +423,7 @@ template<>
|
||||
struct hash<oatpp::data::mapping::type::Void> {
|
||||
|
||||
typedef oatpp::data::mapping::type::Void argument_type;
|
||||
typedef v_buff_usize result_type;
|
||||
typedef v_uint64 result_type;
|
||||
|
||||
result_type operator()(argument_type const& v) const noexcept {
|
||||
return (result_type) v.get();
|
||||
|
@ -334,7 +334,7 @@ namespace std {
|
||||
struct hash<oatpp::data::share::StringKeyLabel> {
|
||||
|
||||
typedef oatpp::data::share::StringKeyLabel argument_type;
|
||||
typedef v_uint32 result_type;
|
||||
typedef v_uint64 result_type;
|
||||
|
||||
result_type operator()(oatpp::data::share::StringKeyLabel const& s) const noexcept {
|
||||
|
||||
@ -354,7 +354,7 @@ namespace std {
|
||||
struct hash<oatpp::data::share::StringKeyLabelCI> {
|
||||
|
||||
typedef oatpp::data::share::StringKeyLabelCI argument_type;
|
||||
typedef v_uint32 result_type;
|
||||
typedef v_uint64 result_type;
|
||||
|
||||
result_type operator()(oatpp::data::share::StringKeyLabelCI const& s) const noexcept {
|
||||
|
||||
@ -374,7 +374,7 @@ namespace std {
|
||||
struct hash<oatpp::data::share::StringKeyLabelCI_FAST> {
|
||||
|
||||
typedef oatpp::data::share::StringKeyLabelCI_FAST argument_type;
|
||||
typedef v_uint32 result_type;
|
||||
typedef v_uint64 result_type;
|
||||
|
||||
result_type operator()(oatpp::data::share::StringKeyLabelCI_FAST const& s) const noexcept {
|
||||
|
||||
|
@ -735,7 +735,7 @@ namespace std {
|
||||
struct hash<oatpp::web::protocol::http::Status> {
|
||||
|
||||
typedef oatpp::web::protocol::http::Status argument_type;
|
||||
typedef v_uint32 result_type;
|
||||
typedef v_uint64 result_type;
|
||||
|
||||
result_type operator()(oatpp::web::protocol::http::Status const& s) const noexcept {
|
||||
return s.code;
|
||||
|
@ -19,6 +19,8 @@ add_executable(oatppAllTests
|
||||
oatpp/core/data/mapping/type/EnumTest.hpp
|
||||
oatpp/core/data/mapping/type/ListTest.cpp
|
||||
oatpp/core/data/mapping/type/ListTest.hpp
|
||||
oatpp/core/data/mapping/type/ObjectTest.cpp
|
||||
oatpp/core/data/mapping/type/ObjectTest.hpp
|
||||
oatpp/core/data/mapping/type/ObjectWrapperTest.cpp
|
||||
oatpp/core/data/mapping/type/ObjectWrapperTest.hpp
|
||||
oatpp/core/data/mapping/type/PairListTest.cpp
|
||||
|
@ -45,6 +45,7 @@
|
||||
#include "oatpp/core/data/mapping/type/VectorTest.hpp"
|
||||
#include "oatpp/core/data/mapping/type/UnorderedSetTest.hpp"
|
||||
#include "oatpp/core/data/mapping/type/ListTest.hpp"
|
||||
#include "oatpp/core/data/mapping/type/ObjectTest.hpp"
|
||||
#include "oatpp/core/data/mapping/type/StringTest.hpp"
|
||||
#include "oatpp/core/data/mapping/type/PrimitiveTest.hpp"
|
||||
#include "oatpp/core/data/mapping/type/ObjectWrapperTest.hpp"
|
||||
@ -75,7 +76,7 @@ void runTests() {
|
||||
|
||||
OATPP_LOGD("aaa", "coroutine size=%d", sizeof(oatpp::async::AbstractCoroutine));
|
||||
OATPP_LOGD("aaa", "action size=%d", sizeof(oatpp::async::Action));
|
||||
/*
|
||||
|
||||
OATPP_RUN_TEST(oatpp::test::base::CommandLineArgumentsTest);
|
||||
|
||||
OATPP_RUN_TEST(oatpp::test::memory::MemoryPoolTest);
|
||||
@ -98,23 +99,22 @@ void runTests() {
|
||||
OATPP_RUN_TEST(oatpp::test::core::data::mapping::type::PrimitiveTest);
|
||||
OATPP_RUN_TEST(oatpp::test::core::data::mapping::type::ListTest);
|
||||
OATPP_RUN_TEST(oatpp::test::core::data::mapping::type::VectorTest);
|
||||
*/
|
||||
OATPP_RUN_TEST(oatpp::test::core::data::mapping::type::UnorderedSetTest);
|
||||
/*
|
||||
OATPP_RUN_TEST(oatpp::test::core::data::mapping::type::PairListTest);
|
||||
OATPP_RUN_TEST(oatpp::test::core::data::mapping::type::UnorderedMapTest);
|
||||
OATPP_RUN_TEST(oatpp::test::core::data::mapping::type::AnyTest);
|
||||
|
||||
OATPP_RUN_TEST(oatpp::test::core::data::mapping::type::EnumTest);
|
||||
|
||||
OATPP_RUN_TEST(oatpp::test::core::data::mapping::type::ObjectTest);
|
||||
|
||||
OATPP_RUN_TEST(oatpp::test::async::LockTest);
|
||||
|
||||
OATPP_RUN_TEST(oatpp::test::parser::CaretTest);
|
||||
|
||||
OATPP_RUN_TEST(oatpp::test::parser::json::mapping::EnumTest);
|
||||
*/
|
||||
|
||||
OATPP_RUN_TEST(oatpp::test::parser::json::mapping::UnorderedSetTest);
|
||||
/*
|
||||
|
||||
OATPP_RUN_TEST(oatpp::test::parser::json::mapping::DeserializerTest);
|
||||
OATPP_RUN_TEST(oatpp::test::parser::json::mapping::DTOMapperPerfTest);
|
||||
OATPP_RUN_TEST(oatpp::test::parser::json::mapping::DTOMapperTest);
|
||||
@ -196,7 +196,7 @@ void runTests() {
|
||||
test_port.run();
|
||||
|
||||
}
|
||||
*/
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
215
test/oatpp/core/data/mapping/type/ObjectTest.cpp
Normal file
215
test/oatpp/core/data/mapping/type/ObjectTest.cpp
Normal file
@ -0,0 +1,215 @@
|
||||
/***************************************************************************
|
||||
*
|
||||
* Project _____ __ ____ _ _
|
||||
* ( _ ) /__\ (_ _)_| |_ _| |_
|
||||
* )(_)( /(__)\ )( (_ _)(_ _)
|
||||
* (_____)(__)(__)(__) |_| |_|
|
||||
*
|
||||
*
|
||||
* Copyright 2018-present, Leonid Stryzhevskyi <lganzzzo@gmail.com>
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
#include "ObjectTest.hpp"
|
||||
|
||||
#include "oatpp/core/macro/codegen.hpp"
|
||||
#include "oatpp/core/Types.hpp"
|
||||
|
||||
namespace oatpp { namespace test { namespace core { namespace data { namespace mapping { namespace type {
|
||||
|
||||
namespace {
|
||||
|
||||
#include OATPP_CODEGEN_BEGIN(DTO)
|
||||
|
||||
class Dto0 : public oatpp::Object {
|
||||
DTO_INIT(Dto0, Object)
|
||||
};
|
||||
|
||||
class DtoA : public oatpp::Object {
|
||||
|
||||
DTO_INIT(DtoA, Object)
|
||||
|
||||
DTO_FIELD(String, id);
|
||||
|
||||
DTO_HC_EQ(id)
|
||||
|
||||
};
|
||||
|
||||
class DtoB : public DtoA {
|
||||
|
||||
DTO_INIT(DtoB, DtoA)
|
||||
|
||||
DTO_FIELD(String, a);
|
||||
|
||||
};
|
||||
|
||||
class DtoC : public DtoA {
|
||||
|
||||
DTO_INIT(DtoC, DtoA)
|
||||
|
||||
DTO_FIELD(String, a);
|
||||
DTO_FIELD(String, b);
|
||||
DTO_FIELD(String, c);
|
||||
|
||||
DTO_HC_EQ(a, b, c);
|
||||
|
||||
};
|
||||
|
||||
#include OATPP_CODEGEN_END(DTO)
|
||||
|
||||
}
|
||||
|
||||
void ObjectTest::onRun() {
|
||||
|
||||
{
|
||||
OATPP_LOGI(TAG, "Test 1...");
|
||||
DtoA::ObjectWrapper a;
|
||||
OATPP_ASSERT(!a);
|
||||
OATPP_ASSERT(a == nullptr);
|
||||
OATPP_ASSERT(a.valueType->classId.id == oatpp::data::mapping::type::__class::AbstractObject::CLASS_ID.id);
|
||||
OATPP_LOGI(TAG, "OK");
|
||||
}
|
||||
|
||||
{
|
||||
OATPP_LOGI(TAG, "Test 2...");
|
||||
DtoA::ObjectWrapper a;
|
||||
DtoA::ObjectWrapper b;
|
||||
OATPP_ASSERT(a == b);
|
||||
OATPP_LOGI(TAG, "OK");
|
||||
}
|
||||
|
||||
{
|
||||
OATPP_LOGI(TAG, "Test 3...");
|
||||
auto a = DtoA::createShared();
|
||||
DtoA::ObjectWrapper b;
|
||||
OATPP_ASSERT(a != b);
|
||||
OATPP_ASSERT(b != a);
|
||||
auto ohc = a->hashCode();
|
||||
auto whc = std::hash<DtoA::ObjectWrapper>{}(a);
|
||||
OATPP_ASSERT(ohc == whc);
|
||||
OATPP_LOGI(TAG, "OK");
|
||||
}
|
||||
|
||||
{
|
||||
OATPP_LOGI(TAG, "Test 4...");
|
||||
auto a = Dto0::createShared();
|
||||
auto b = Dto0::createShared();
|
||||
OATPP_ASSERT(a != b);
|
||||
OATPP_ASSERT(a->hashCode() != b->hashCode());
|
||||
OATPP_LOGI(TAG, "OK");
|
||||
}
|
||||
|
||||
{
|
||||
OATPP_LOGI(TAG, "Test 5...");
|
||||
auto a = DtoA::createShared();
|
||||
auto b = DtoA::createShared();
|
||||
|
||||
OATPP_ASSERT(a == b);
|
||||
OATPP_ASSERT(a->hashCode() == b->hashCode());
|
||||
|
||||
a->id = "hello";
|
||||
|
||||
OATPP_ASSERT(a != b);
|
||||
OATPP_ASSERT(a->hashCode() != b->hashCode());
|
||||
|
||||
b->id = "hello";
|
||||
|
||||
OATPP_ASSERT(a == b);
|
||||
OATPP_ASSERT(a->hashCode() == b->hashCode());
|
||||
OATPP_LOGI(TAG, "OK");
|
||||
}
|
||||
|
||||
{
|
||||
OATPP_LOGI(TAG, "Test 6...");
|
||||
auto a = DtoB::createShared();
|
||||
auto b = DtoB::createShared();
|
||||
|
||||
a->a = "value1"; // value that is ignored in HC & EQ
|
||||
a->a = "value2"; // value that is ignored in HC & EQ
|
||||
|
||||
OATPP_ASSERT(a == b);
|
||||
OATPP_ASSERT(a->hashCode() == b->hashCode());
|
||||
|
||||
a->id = "hello";
|
||||
|
||||
OATPP_ASSERT(a != b);
|
||||
OATPP_ASSERT(a->hashCode() != b->hashCode());
|
||||
|
||||
b->id = "hello";
|
||||
|
||||
OATPP_ASSERT(a == b);
|
||||
OATPP_ASSERT(a->hashCode() == b->hashCode());
|
||||
OATPP_LOGI(TAG, "OK");
|
||||
}
|
||||
|
||||
{
|
||||
OATPP_LOGI(TAG, "Test 7...");
|
||||
auto a = DtoC::createShared();
|
||||
auto b = DtoC::createShared();
|
||||
|
||||
a->id = "1";
|
||||
b->id = "2";
|
||||
|
||||
OATPP_ASSERT(a != b);
|
||||
OATPP_ASSERT(a->hashCode() != b->hashCode());
|
||||
|
||||
a->id = "2";
|
||||
|
||||
OATPP_ASSERT(a == b);
|
||||
OATPP_ASSERT(a->hashCode() == b->hashCode());
|
||||
|
||||
a->c = "a";
|
||||
|
||||
OATPP_ASSERT(a != b);
|
||||
OATPP_ASSERT(a->hashCode() != b->hashCode());
|
||||
|
||||
b->c = "a";
|
||||
|
||||
OATPP_ASSERT(a == b);
|
||||
OATPP_ASSERT(a->hashCode() == b->hashCode());
|
||||
OATPP_LOGI(TAG, "OK");
|
||||
}
|
||||
|
||||
{
|
||||
OATPP_LOGI(TAG, "Test 8...");
|
||||
auto a = DtoB::createShared();
|
||||
auto b = DtoB::createShared();
|
||||
auto c = DtoB::createShared();
|
||||
auto d = DtoB::createShared();
|
||||
auto e = DtoB::createShared();
|
||||
|
||||
a->a = "1";
|
||||
b->a = "2";
|
||||
c->a = "3";
|
||||
d->a = "4";
|
||||
e->a = "5";
|
||||
|
||||
a->id = "1";
|
||||
e->id = "1";
|
||||
|
||||
oatpp::UnorderedSet<DtoB> set = {a, b, c, d, e};
|
||||
|
||||
OATPP_ASSERT(set->size() == 2);
|
||||
OATPP_ASSERT(set[a] == true);
|
||||
OATPP_ASSERT(set[b] == true);
|
||||
OATPP_ASSERT(set[c] == true);
|
||||
OATPP_ASSERT(set[d] == true);
|
||||
OATPP_ASSERT(set[e] == true);
|
||||
OATPP_LOGI(TAG, "OK");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}}}}}}
|
42
test/oatpp/core/data/mapping/type/ObjectTest.hpp
Normal file
42
test/oatpp/core/data/mapping/type/ObjectTest.hpp
Normal file
@ -0,0 +1,42 @@
|
||||
/***************************************************************************
|
||||
*
|
||||
* Project _____ __ ____ _ _
|
||||
* ( _ ) /__\ (_ _)_| |_ _| |_
|
||||
* )(_)( /(__)\ )( (_ _)(_ _)
|
||||
* (_____)(__)(__)(__) |_| |_|
|
||||
*
|
||||
*
|
||||
* Copyright 2018-present, Leonid Stryzhevskyi <lganzzzo@gmail.com>
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef oatpp_test_core_data_mapping_type_ObjectTest_hpp
|
||||
#define oatpp_test_core_data_mapping_type_ObjectTest_hpp
|
||||
|
||||
#include "oatpp-test/UnitTest.hpp"
|
||||
|
||||
namespace oatpp { namespace test { namespace core { namespace data { namespace mapping { namespace type {
|
||||
|
||||
class ObjectTest : public UnitTest{
|
||||
public:
|
||||
|
||||
ObjectTest():UnitTest("TEST[core::data::mapping::type::ObjectTest]"){}
|
||||
void onRun() override;
|
||||
|
||||
};
|
||||
|
||||
}}}}}}
|
||||
|
||||
#endif /* oatpp_test_core_data_mapping_type_ObjectTest_hpp */
|
Loading…
Reference in New Issue
Block a user