aboutsummaryrefslogtreecommitdiff
path: root/test/base/SelfResolvableTest.cpp
blob: c214bd775cd7a1e91fb688e57dd2b55846e892c3 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
#include "cru/base/Base.h"
#include "cru/base/SelfResolvable.h"

#include <catch2/catch_test_macros.hpp>

#include <memory>

namespace {
class SelfResolvableTestClassBase {
 public:
  SelfResolvableTestClassBase() = default;
  CRU_DELETE_COPY(SelfResolvableTestClassBase)
  CRU_DEFAULT_MOVE(SelfResolvableTestClassBase)
  virtual ~SelfResolvableTestClassBase() = default;
};

class SelfResolvableTestClass
    : public SelfResolvableTestClassBase,
      public cru::SelfResolvable<SelfResolvableTestClass> {
 public:
  SelfResolvableTestClass() : ptr_(new int(123)) {}
  CRU_DELETE_COPY(SelfResolvableTestClass)
  CRU_DEFAULT_MOVE(SelfResolvableTestClass)
  ~SelfResolvableTestClass() override = 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);
}

TEST_CASE("SelfResolvable should work for casted type.", "[self-resolvable]") {
  auto test_object = new SelfResolvableTestClass();

  cru::ObjectResolver<SelfResolvableTestClassBase> base_resolver =
      test_object->CreateResolver();

  REQUIRE(base_resolver.Resolve() == test_object);

  auto base_resolver2 = base_resolver;
  REQUIRE(base_resolver2.Resolve() == test_object);

  auto base_resolver3 = std::move(base_resolver2);
  REQUIRE(base_resolver3.Resolve() == test_object);

  auto moved_object = new SelfResolvableTestClass(std::move(*test_object));
  delete test_object;

  REQUIRE(base_resolver.Resolve() == moved_object);
  REQUIRE(base_resolver3.Resolve() == moved_object);

  delete moved_object;

  REQUIRE(base_resolver.Resolve() == nullptr);
  REQUIRE(base_resolver3.Resolve() == nullptr);
}