Skip to content

Commit

Permalink
Fix bugs and write unit tests for SelfResolvable.
Browse files Browse the repository at this point in the history
  • Loading branch information
crupest committed Dec 30, 2023
1 parent f7a4000 commit c4641ca
Show file tree
Hide file tree
Showing 3 changed files with 83 additions and 5 deletions.
11 changes: 6 additions & 5 deletions include/cru/common/SelfResolvable.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,6 @@ class ObjectResolver {
return *this->shared_object_ptr_;
}

explicit operator bool() const { return this->IsValid(); }

private:
void SetResolvedObject(T* o) {
assert(IsValid());
Expand All @@ -43,22 +41,22 @@ class ObjectResolver {
template <typename T>
class SelfResolvable {
public:
SelfResolvable() : resolver_(static_cast<T*>(this)) {}
SelfResolvable() : resolver_(CastToSubClass()) {}
SelfResolvable(const SelfResolvable&) = delete;
SelfResolvable& operator=(const SelfResolvable&) = delete;

// Resolvers to old object will resolve to new object.
SelfResolvable(SelfResolvable&& other)
: resolver_(std::move(other.resolver_)) {
this->resolver_.SetResolvedObject(this);
this->resolver_.SetResolvedObject(CastToSubClass());
}

// Old resolvers for this object will resolve to nullptr.
// Other's resolvers will now resolve to this.
SelfResolvable& operator=(SelfResolvable&& other) {
if (this != &other) {
this->resolver_ = std::move(other.resolver_);
this->resolver_.SetResolvedObject(this);
this->resolver_.SetResolvedObject(CastToSubClass());
}
return *this;
}
Expand All @@ -71,6 +69,9 @@ class SelfResolvable {

ObjectResolver<T> CreateResolver() { return resolver_; }

private:
T* CastToSubClass() { return static_cast<T*>(this); }

private:
ObjectResolver<T> resolver_;
};
Expand Down
1 change: 1 addition & 0 deletions test/common/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
add_executable(CruBaseTest
HandlerRegistryTest.cpp
PropertyTreeTest.cpp
SelfResolvableTest.cpp
StringTest.cpp
StringToNumberConverterTest.cpp
StringUtilTest.cpp
Expand Down
76 changes: 76 additions & 0 deletions test/common/SelfResolvableTest.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
#include "cru/common/Base.h"
#include "cru/common/SelfResolvable.h"

#include <catch2/catch_test_macros.hpp>

#include <memory>

namespace {
class SelfResolvableTestClass
: public cru::SelfResolvable<SelfResolvableTestClass> {
public:
SelfResolvableTestClass() : ptr_(new int(123)) {}
CRU_DELETE_COPY(SelfResolvableTestClass)
CRU_DEFAULT_MOVE(SelfResolvableTestClass)
~SelfResolvableTestClass() = default;

private:
std::shared_ptr<int> ptr_;
};
} // namespace

TEST_CASE("SelfResolvable resolver should work.", "[self-resolvable]") {
SelfResolvableTestClass test_object;

auto resolver = test_object.CreateResolver();
REQUIRE(resolver.Resolve() == &test_object);

auto resolver_copy = resolver;
REQUIRE(resolver.Resolve() == &test_object);
REQUIRE(resolver.Resolve() == &test_object);

auto resolver_move = std::move(resolver_copy);
REQUIRE(resolver.Resolve() == &test_object);
REQUIRE(resolver_copy.IsValid() == false);
REQUIRE(resolver_move.Resolve() == &test_object);
}

TEST_CASE("SelfResolvable object destructed should work.",
"[self-resolvable]") {
SelfResolvableTestClass* test_object = new SelfResolvableTestClass();

auto resolver = test_object->CreateResolver();
auto resolver_copy = resolver;

delete test_object;

REQUIRE(resolver.Resolve() == nullptr);
REQUIRE(resolver_copy.Resolve() == nullptr);

auto resolver_copy2 = resolver_copy;
REQUIRE(resolver_copy2.Resolve() == nullptr);

auto resolver_move = std::move(resolver_copy);
REQUIRE(resolver_copy.IsValid() == false);
REQUIRE(resolver_move.Resolve() == nullptr);
}

TEST_CASE("SelfResolvable object moved should work.", "[self-resolvable]") {
SelfResolvableTestClass test_object;

auto resolver = test_object.CreateResolver();
auto resolver_copy = resolver;

SelfResolvableTestClass moved_object = std::move(test_object);

REQUIRE(resolver.Resolve() == &moved_object);
REQUIRE(resolver_copy.Resolve() == &moved_object);

auto resolver_copy2 = resolver_copy;
REQUIRE(resolver_copy2.Resolve() == &moved_object);

auto resolver_move = std::move(resolver_copy);
REQUIRE(resolver_copy.IsValid() == false);
REQUIRE(resolver_move.Resolve() == &moved_object);
}

0 comments on commit c4641ca

Please sign in to comment.