| 1 | #include <utility> | 
|---|
| 2 | #include <gtest/gtest.h> | 
|---|
| 3 | #include "core/object/StrongPtr.h" | 
|---|
| 4 |  | 
|---|
| 5 | namespace orxonox | 
|---|
| 6 | { | 
|---|
| 7 |     namespace | 
|---|
| 8 |     { | 
|---|
| 9 |         class DestroyableTest : public Destroyable | 
|---|
| 10 |         { | 
|---|
| 11 |             public: | 
|---|
| 12 |                 DestroyableTest(bool& destroyed) : destroyed_(destroyed) { destroyed_ = false; } | 
|---|
| 13 |                 virtual ~DestroyableTest() { destroyed_ = true; } | 
|---|
| 14 |  | 
|---|
| 15 |             private: | 
|---|
| 16 |                 bool& destroyed_; | 
|---|
| 17 |         }; | 
|---|
| 18 |     } | 
|---|
| 19 |  | 
|---|
| 20 |     TEST(StrongPtrTest, CanReferenceObject) | 
|---|
| 21 |     { | 
|---|
| 22 |         bool bla; | 
|---|
| 23 |         DestroyableTest* test = new DestroyableTest(bla); | 
|---|
| 24 |         StrongPtr<DestroyableTest> strongPtr = test; | 
|---|
| 25 |         EXPECT_EQ(test, strongPtr.get()); | 
|---|
| 26 |         EXPECT_EQ(test, &(*strongPtr)); | 
|---|
| 27 |         EXPECT_EQ(static_cast<Destroyable*>(test), strongPtr.getBase()); | 
|---|
| 28 |         test->destroy(); | 
|---|
| 29 |     } | 
|---|
| 30 |  | 
|---|
| 31 |     TEST(StrongPtrTest, CanHaveMultiplePointers) | 
|---|
| 32 |     { | 
|---|
| 33 |         bool bla; | 
|---|
| 34 |         DestroyableTest* test = new DestroyableTest(bla); | 
|---|
| 35 |         StrongPtr<DestroyableTest> strongPtr1 = test; | 
|---|
| 36 |         StrongPtr<DestroyableTest> strongPtr2 = test; | 
|---|
| 37 |         StrongPtr<DestroyableTest> strongPtr3 = test; | 
|---|
| 38 |         EXPECT_EQ(test, strongPtr1.get()); | 
|---|
| 39 |         EXPECT_EQ(test, strongPtr2.get()); | 
|---|
| 40 |         EXPECT_EQ(test, strongPtr3.get()); | 
|---|
| 41 |         EXPECT_EQ(3u, test->getReferenceCount()); | 
|---|
| 42 |         test->destroy(); | 
|---|
| 43 |     } | 
|---|
| 44 |  | 
|---|
| 45 |     TEST(StrongPtrTest, IncreasesReferenceCount) | 
|---|
| 46 |     { | 
|---|
| 47 |         bool bla; | 
|---|
| 48 |         DestroyableTest* test = new DestroyableTest(bla); | 
|---|
| 49 |         EXPECT_EQ(0u, test->getReferenceCount()); | 
|---|
| 50 |         { | 
|---|
| 51 |             StrongPtr<DestroyableTest> strongPtr = test; | 
|---|
| 52 |             EXPECT_EQ(1u, test->getReferenceCount()); | 
|---|
| 53 |         } | 
|---|
| 54 |         EXPECT_EQ(0u, test->getReferenceCount()); | 
|---|
| 55 |         test->destroy(); | 
|---|
| 56 |     } | 
|---|
| 57 |  | 
|---|
| 58 |     TEST(StrongPtrTest, DestroyDeletesInstance) | 
|---|
| 59 |     { | 
|---|
| 60 |         bool destroyed = false; | 
|---|
| 61 |         DestroyableTest* test = new DestroyableTest(destroyed); | 
|---|
| 62 |         EXPECT_FALSE(destroyed); | 
|---|
| 63 |         test->destroy(); | 
|---|
| 64 |         EXPECT_TRUE(destroyed); | 
|---|
| 65 |     } | 
|---|
| 66 |  | 
|---|
| 67 |     TEST(StrongPtrTest, PreventsDestruction) | 
|---|
| 68 |     { | 
|---|
| 69 |         bool destroyed = false; | 
|---|
| 70 |         DestroyableTest* test = new DestroyableTest(destroyed); | 
|---|
| 71 |         EXPECT_FALSE(destroyed); | 
|---|
| 72 |         StrongPtr<DestroyableTest> strongPtr = test; | 
|---|
| 73 |         test->destroy(); | 
|---|
| 74 |         EXPECT_FALSE(destroyed); | 
|---|
| 75 |     } | 
|---|
| 76 |  | 
|---|
| 77 |     TEST(StrongPtrTest, DestroysIfStrongPtrRemoved) | 
|---|
| 78 |     { | 
|---|
| 79 |         bool destroyed = false; | 
|---|
| 80 |         DestroyableTest* test = new DestroyableTest(destroyed); | 
|---|
| 81 |         EXPECT_FALSE(destroyed); | 
|---|
| 82 |         { | 
|---|
| 83 |             StrongPtr<DestroyableTest> strongPtr = test; | 
|---|
| 84 |             test->destroy(); | 
|---|
| 85 |             EXPECT_FALSE(destroyed); | 
|---|
| 86 |         } | 
|---|
| 87 |         EXPECT_TRUE(destroyed); | 
|---|
| 88 |     } | 
|---|
| 89 |  | 
|---|
| 90 |     TEST(StrongPtrTest, DestroysIfAllStrongPtrsRemoved) | 
|---|
| 91 |     { | 
|---|
| 92 |         bool destroyed = false; | 
|---|
| 93 |         DestroyableTest* test = new DestroyableTest(destroyed); | 
|---|
| 94 |         EXPECT_FALSE(destroyed); | 
|---|
| 95 |         { | 
|---|
| 96 |             StrongPtr<DestroyableTest> strongPtr1 = test; | 
|---|
| 97 |             { | 
|---|
| 98 |                 StrongPtr<DestroyableTest> strongPtr2 = test; | 
|---|
| 99 |                 { | 
|---|
| 100 |                     StrongPtr<DestroyableTest> strongPtr3 = test; | 
|---|
| 101 |                     test->destroy(); | 
|---|
| 102 |                     EXPECT_FALSE(destroyed); | 
|---|
| 103 |                 } | 
|---|
| 104 |                 EXPECT_FALSE(destroyed); | 
|---|
| 105 |             } | 
|---|
| 106 |             EXPECT_FALSE(destroyed); | 
|---|
| 107 |         } | 
|---|
| 108 |         EXPECT_TRUE(destroyed); | 
|---|
| 109 |     } | 
|---|
| 110 |  | 
|---|
| 111 |     void isNull(const StrongPtr<DestroyableTest> strongPtr) | 
|---|
| 112 |     { | 
|---|
| 113 |         EXPECT_TRUE(strongPtr == nullptr); | 
|---|
| 114 |         EXPECT_TRUE(strongPtr == nullptr); | 
|---|
| 115 |         EXPECT_TRUE(!strongPtr); | 
|---|
| 116 |         EXPECT_FALSE(strongPtr != nullptr); | 
|---|
| 117 |         EXPECT_FALSE(strongPtr != nullptr); | 
|---|
| 118 |         EXPECT_FALSE(strongPtr); | 
|---|
| 119 |     } | 
|---|
| 120 |  | 
|---|
| 121 |     TEST(StrongPtrTest, IsNull) | 
|---|
| 122 |     { | 
|---|
| 123 |         { | 
|---|
| 124 |             StrongPtr<DestroyableTest> strongPtr; | 
|---|
| 125 |             isNull(strongPtr); | 
|---|
| 126 |         } | 
|---|
| 127 |         { | 
|---|
| 128 |             StrongPtr<DestroyableTest> strongPtr = nullptr; | 
|---|
| 129 |             isNull(strongPtr); | 
|---|
| 130 |         } | 
|---|
| 131 |         { | 
|---|
| 132 |             StrongPtr<DestroyableTest> strongPtr; | 
|---|
| 133 |             strongPtr = nullptr; | 
|---|
| 134 |             isNull(strongPtr); | 
|---|
| 135 |         } | 
|---|
| 136 |         { | 
|---|
| 137 |             StrongPtr<DestroyableTest> strongPtr = nullptr; | 
|---|
| 138 |             isNull(strongPtr); | 
|---|
| 139 |         } | 
|---|
| 140 |         { | 
|---|
| 141 |             StrongPtr<DestroyableTest> strongPtr; | 
|---|
| 142 |             strongPtr = nullptr; | 
|---|
| 143 |             isNull(strongPtr); | 
|---|
| 144 |         } | 
|---|
| 145 |     } | 
|---|
| 146 |  | 
|---|
| 147 |     TEST(StrongPtrTest, IsNotNull) | 
|---|
| 148 |     { | 
|---|
| 149 |         bool destroyed = false; | 
|---|
| 150 |         DestroyableTest* test = new DestroyableTest(destroyed); | 
|---|
| 151 |         StrongPtr<DestroyableTest> strongPtr = test; | 
|---|
| 152 |         EXPECT_FALSE(strongPtr == nullptr); | 
|---|
| 153 |         EXPECT_FALSE(strongPtr == nullptr); | 
|---|
| 154 |         EXPECT_FALSE(!strongPtr); | 
|---|
| 155 |         EXPECT_TRUE(strongPtr != nullptr); | 
|---|
| 156 |         EXPECT_TRUE(strongPtr != nullptr); | 
|---|
| 157 |         EXPECT_TRUE(strongPtr); | 
|---|
| 158 |         test->destroy(); | 
|---|
| 159 |     } | 
|---|
| 160 |  | 
|---|
| 161 |     TEST(StrongPtrTest, TestConstructors) | 
|---|
| 162 |     { | 
|---|
| 163 |         bool bla; | 
|---|
| 164 |         DestroyableTest* test = new DestroyableTest(bla); | 
|---|
| 165 |  | 
|---|
| 166 |         // default | 
|---|
| 167 |         StrongPtr<DestroyableTest> strongPtr1; | 
|---|
| 168 |         EXPECT_EQ(nullptr, strongPtr1.get()); | 
|---|
| 169 |  | 
|---|
| 170 |         // pointer | 
|---|
| 171 |         StrongPtr<DestroyableTest> strongPtr2a = test; | 
|---|
| 172 |         StrongPtr<DestroyableTest> strongPtr2b(test); | 
|---|
| 173 |         EXPECT_EQ(test, strongPtr2a.get()); | 
|---|
| 174 |         EXPECT_EQ(test, strongPtr2b.get()); | 
|---|
| 175 |  | 
|---|
| 176 |         // copy | 
|---|
| 177 |         StrongPtr<DestroyableTest> strongPtr3a = strongPtr2a; | 
|---|
| 178 |         StrongPtr<DestroyableTest> strongPtr3b(strongPtr2b); | 
|---|
| 179 |         EXPECT_EQ(test, strongPtr3a.get()); | 
|---|
| 180 |         EXPECT_EQ(test, strongPtr3b.get()); | 
|---|
| 181 |  | 
|---|
| 182 |         // move | 
|---|
| 183 |         StrongPtr<DestroyableTest> strongPtr4a = std::move(strongPtr3a); | 
|---|
| 184 |         StrongPtr<DestroyableTest> strongPtr4b(std::move(strongPtr3b)); | 
|---|
| 185 |         EXPECT_EQ(test, strongPtr4a.get()); | 
|---|
| 186 |         EXPECT_EQ(test, strongPtr4b.get()); | 
|---|
| 187 |  | 
|---|
| 188 |         // other | 
|---|
| 189 |         StrongPtr<Destroyable> strongPtr5a = strongPtr4a; | 
|---|
| 190 |         StrongPtr<Destroyable> strongPtr5b(strongPtr4b); | 
|---|
| 191 |         EXPECT_EQ(test, strongPtr5a.get()); | 
|---|
| 192 |         EXPECT_EQ(test, strongPtr5b.get()); | 
|---|
| 193 |  | 
|---|
| 194 |         // weakPtr | 
|---|
| 195 |         WeakPtr<DestroyableTest> weakPtr = test; | 
|---|
| 196 |         StrongPtr<DestroyableTest> strongPtr6a = weakPtr; | 
|---|
| 197 |         StrongPtr<DestroyableTest> strongPtr6b(weakPtr); | 
|---|
| 198 |         EXPECT_EQ(test, strongPtr6a.get()); | 
|---|
| 199 |         EXPECT_EQ(test, strongPtr6b.get()); | 
|---|
| 200 |  | 
|---|
| 201 |         // weakPtr other | 
|---|
| 202 |         StrongPtr<Destroyable> strongPtr7a = weakPtr; | 
|---|
| 203 |         StrongPtr<Destroyable> strongPtr7b(weakPtr); | 
|---|
| 204 |         EXPECT_EQ(test, strongPtr7a.get()); | 
|---|
| 205 |         EXPECT_EQ(test, strongPtr7b.get()); | 
|---|
| 206 |  | 
|---|
| 207 |         test->destroy(); | 
|---|
| 208 |     } | 
|---|
| 209 |  | 
|---|
| 210 |     TEST(StrongPtrTest, TestAssignments) | 
|---|
| 211 |     { | 
|---|
| 212 |         bool bla; | 
|---|
| 213 |         DestroyableTest* test = new DestroyableTest(bla); | 
|---|
| 214 |  | 
|---|
| 215 |         // pointer | 
|---|
| 216 |         StrongPtr<DestroyableTest> strongPtr1; | 
|---|
| 217 |         strongPtr1 = test; | 
|---|
| 218 |         EXPECT_EQ(test, strongPtr1.get()); | 
|---|
| 219 |  | 
|---|
| 220 |         // copy | 
|---|
| 221 |         StrongPtr<DestroyableTest> strongPtr2; | 
|---|
| 222 |         strongPtr2 = strongPtr1; | 
|---|
| 223 |         EXPECT_EQ(test, strongPtr2.get()); | 
|---|
| 224 |  | 
|---|
| 225 |         // move | 
|---|
| 226 |         StrongPtr<DestroyableTest> strongPtr3; | 
|---|
| 227 |         strongPtr3 = std::move(strongPtr2); | 
|---|
| 228 |         EXPECT_EQ(test, strongPtr3.get()); | 
|---|
| 229 |  | 
|---|
| 230 |         // other | 
|---|
| 231 |         StrongPtr<Destroyable> strongPtr4; | 
|---|
| 232 |         strongPtr4 = strongPtr3; | 
|---|
| 233 |         EXPECT_EQ(test, strongPtr4.get()); | 
|---|
| 234 |  | 
|---|
| 235 |         // weakPtr | 
|---|
| 236 |         WeakPtr<DestroyableTest> weakPtr = test; | 
|---|
| 237 |         StrongPtr<DestroyableTest> strongPtr5; | 
|---|
| 238 |         strongPtr5 = weakPtr; | 
|---|
| 239 |         EXPECT_EQ(test, strongPtr5.get()); | 
|---|
| 240 |  | 
|---|
| 241 |         // weakPtr other | 
|---|
| 242 |         StrongPtr<Destroyable> strongPtr6; | 
|---|
| 243 |         strongPtr6 = weakPtr; | 
|---|
| 244 |         EXPECT_EQ(test, strongPtr6.get()); | 
|---|
| 245 |  | 
|---|
| 246 |         test->destroy(); | 
|---|
| 247 |     } | 
|---|
| 248 |  | 
|---|
| 249 |     TEST(StrongPtrTest, TestStrongPtrInVector) | 
|---|
| 250 |     { | 
|---|
| 251 |         bool bla; | 
|---|
| 252 |         DestroyableTest* test = new DestroyableTest(bla); | 
|---|
| 253 |  | 
|---|
| 254 |         std::vector<StrongPtr<DestroyableTest>> vector; | 
|---|
| 255 |         vector.push_back(test); | 
|---|
| 256 |         vector.push_back(test); | 
|---|
| 257 |         vector.push_back(test); | 
|---|
| 258 |  | 
|---|
| 259 |         ASSERT_EQ(3u, vector.size()); | 
|---|
| 260 |         EXPECT_EQ(test, vector[0].get()); | 
|---|
| 261 |         EXPECT_EQ(test, vector[1].get()); | 
|---|
| 262 |         EXPECT_EQ(test, vector[2].get()); | 
|---|
| 263 |         EXPECT_EQ(3u, test->getReferenceCount()); | 
|---|
| 264 |  | 
|---|
| 265 |         vector.clear(); | 
|---|
| 266 |         EXPECT_EQ(0u, test->getReferenceCount()); | 
|---|
| 267 |  | 
|---|
| 268 |         test->destroy(); | 
|---|
| 269 |     } | 
|---|
| 270 |  | 
|---|
| 271 |     TEST(StrongPtrTest, TestReset) | 
|---|
| 272 |     { | 
|---|
| 273 |         bool bla; | 
|---|
| 274 |         DestroyableTest* test = new DestroyableTest(bla); | 
|---|
| 275 |         StrongPtr<DestroyableTest> strongPtr(test); | 
|---|
| 276 |         EXPECT_EQ(test, strongPtr.get()); | 
|---|
| 277 |         EXPECT_EQ(1u, test->getReferenceCount()); | 
|---|
| 278 |         strongPtr.reset(); | 
|---|
| 279 |         EXPECT_EQ(nullptr, strongPtr.get()); | 
|---|
| 280 |         EXPECT_EQ(0u, test->getReferenceCount()); | 
|---|
| 281 |  | 
|---|
| 282 |         test->destroy(); | 
|---|
| 283 |     } | 
|---|
| 284 |  | 
|---|
| 285 |     TEST(StrongPtrTest, TestSwap) | 
|---|
| 286 |     { | 
|---|
| 287 |         bool bla; | 
|---|
| 288 |         DestroyableTest* test1 = new DestroyableTest(bla); | 
|---|
| 289 |         DestroyableTest* test2 = new DestroyableTest(bla); | 
|---|
| 290 |  | 
|---|
| 291 |         StrongPtr<DestroyableTest> strongPtr1(test1); | 
|---|
| 292 |         StrongPtr<DestroyableTest> strongPtr2(test2); | 
|---|
| 293 |         EXPECT_EQ(test1, strongPtr1.get()); | 
|---|
| 294 |         EXPECT_EQ(test2, strongPtr2.get()); | 
|---|
| 295 |         EXPECT_EQ(1u, test1->getReferenceCount()); | 
|---|
| 296 |         EXPECT_EQ(1u, test2->getReferenceCount()); | 
|---|
| 297 |  | 
|---|
| 298 |         strongPtr1.swap(strongPtr2); | 
|---|
| 299 |  | 
|---|
| 300 |         EXPECT_EQ(test2, strongPtr1.get()); | 
|---|
| 301 |         EXPECT_EQ(test1, strongPtr2.get()); | 
|---|
| 302 |         EXPECT_EQ(1u, test1->getReferenceCount()); | 
|---|
| 303 |         EXPECT_EQ(1u, test2->getReferenceCount()); | 
|---|
| 304 |  | 
|---|
| 305 |         test1->destroy(); | 
|---|
| 306 |         test2->destroy(); | 
|---|
| 307 |     } | 
|---|
| 308 | } | 
|---|