#include #include #include "core/object/StrongPtr.h" namespace orxonox { namespace { class DestroyableTest : public Destroyable { public: DestroyableTest(bool& destroyed) : destroyed_(destroyed) { destroyed_ = false; } virtual ~DestroyableTest() { destroyed_ = true; } private: bool& destroyed_; }; } TEST(StrongPtrTest, CanReferenceObject) { bool bla; DestroyableTest* test = new DestroyableTest(bla); StrongPtr strongPtr = test; EXPECT_EQ(test, strongPtr.get()); EXPECT_EQ(test, &(*strongPtr)); EXPECT_EQ(static_cast(test), strongPtr.getBase()); test->destroy(); } TEST(StrongPtrTest, CanHaveMultiplePointers) { bool bla; DestroyableTest* test = new DestroyableTest(bla); StrongPtr strongPtr1 = test; StrongPtr strongPtr2 = test; StrongPtr strongPtr3 = test; EXPECT_EQ(test, strongPtr1.get()); EXPECT_EQ(test, strongPtr2.get()); EXPECT_EQ(test, strongPtr3.get()); EXPECT_EQ(3u, test->getReferenceCount()); test->destroy(); } TEST(StrongPtrTest, IncreasesReferenceCount) { bool bla; DestroyableTest* test = new DestroyableTest(bla); EXPECT_EQ(0u, test->getReferenceCount()); { StrongPtr strongPtr = test; EXPECT_EQ(1u, test->getReferenceCount()); } EXPECT_EQ(0u, test->getReferenceCount()); test->destroy(); } TEST(StrongPtrTest, DestroyDeletesInstance) { bool destroyed = false; DestroyableTest* test = new DestroyableTest(destroyed); EXPECT_FALSE(destroyed); test->destroy(); EXPECT_TRUE(destroyed); } TEST(StrongPtrTest, PreventsDestruction) { bool destroyed = false; DestroyableTest* test = new DestroyableTest(destroyed); EXPECT_FALSE(destroyed); StrongPtr strongPtr = test; test->destroy(); EXPECT_FALSE(destroyed); } TEST(StrongPtrTest, DestroysIfStrongPtrRemoved) { bool destroyed = false; DestroyableTest* test = new DestroyableTest(destroyed); EXPECT_FALSE(destroyed); { StrongPtr strongPtr = test; test->destroy(); EXPECT_FALSE(destroyed); } EXPECT_TRUE(destroyed); } TEST(StrongPtrTest, DestroysIfAllStrongPtrsRemoved) { bool destroyed = false; DestroyableTest* test = new DestroyableTest(destroyed); EXPECT_FALSE(destroyed); { StrongPtr strongPtr1 = test; { StrongPtr strongPtr2 = test; { StrongPtr strongPtr3 = test; test->destroy(); EXPECT_FALSE(destroyed); } EXPECT_FALSE(destroyed); } EXPECT_FALSE(destroyed); } EXPECT_TRUE(destroyed); } void isNull(const StrongPtr strongPtr) { EXPECT_TRUE(strongPtr == nullptr); EXPECT_TRUE(strongPtr == 0); EXPECT_TRUE(!strongPtr); EXPECT_FALSE(strongPtr != nullptr); EXPECT_FALSE(strongPtr != 0); EXPECT_FALSE(strongPtr); } TEST(StrongPtrTest, IsNull) { { StrongPtr strongPtr; isNull(strongPtr); } { StrongPtr strongPtr = nullptr; isNull(strongPtr); } { StrongPtr strongPtr; strongPtr = nullptr; isNull(strongPtr); } { StrongPtr strongPtr = 0; isNull(strongPtr); } { StrongPtr strongPtr; strongPtr = 0; isNull(strongPtr); } } TEST(StrongPtrTest, IsNotNull) { bool destroyed = false; DestroyableTest* test = new DestroyableTest(destroyed); StrongPtr strongPtr = test; EXPECT_FALSE(strongPtr == nullptr); EXPECT_FALSE(strongPtr == 0); EXPECT_FALSE(!strongPtr); EXPECT_TRUE(strongPtr != nullptr); EXPECT_TRUE(strongPtr != 0); EXPECT_TRUE(strongPtr); test->destroy(); } TEST(StrongPtrTest, TestConstructors) { bool bla; DestroyableTest* test = new DestroyableTest(bla); // default StrongPtr strongPtr1; EXPECT_EQ(nullptr, strongPtr1.get()); // pointer StrongPtr strongPtr2a = test; StrongPtr strongPtr2b(test); EXPECT_EQ(test, strongPtr2a.get()); EXPECT_EQ(test, strongPtr2b.get()); // copy StrongPtr strongPtr3a = strongPtr2a; StrongPtr strongPtr3b(strongPtr2b); EXPECT_EQ(test, strongPtr3a.get()); EXPECT_EQ(test, strongPtr3b.get()); // move StrongPtr strongPtr4a = std::move(strongPtr3a); StrongPtr strongPtr4b(std::move(strongPtr3b)); EXPECT_EQ(test, strongPtr4a.get()); EXPECT_EQ(test, strongPtr4b.get()); // other StrongPtr strongPtr5a = strongPtr4a; StrongPtr strongPtr5b(strongPtr4b); EXPECT_EQ(test, strongPtr5a.get()); EXPECT_EQ(test, strongPtr5b.get()); // weakPtr WeakPtr weakPtr = test; StrongPtr strongPtr6a = weakPtr; StrongPtr strongPtr6b(weakPtr); EXPECT_EQ(test, strongPtr6a.get()); EXPECT_EQ(test, strongPtr6b.get()); // weakPtr other StrongPtr strongPtr7a = weakPtr; StrongPtr strongPtr7b(weakPtr); EXPECT_EQ(test, strongPtr7a.get()); EXPECT_EQ(test, strongPtr7b.get()); test->destroy(); } TEST(StrongPtrTest, TestAssignments) { bool bla; DestroyableTest* test = new DestroyableTest(bla); // pointer StrongPtr strongPtr1; strongPtr1 = test; EXPECT_EQ(test, strongPtr1.get()); // copy StrongPtr strongPtr2; strongPtr2 = strongPtr1; EXPECT_EQ(test, strongPtr2.get()); // move StrongPtr strongPtr3; strongPtr3 = std::move(strongPtr2); EXPECT_EQ(test, strongPtr3.get()); // other StrongPtr strongPtr4; strongPtr4 = strongPtr3; EXPECT_EQ(test, strongPtr4.get()); // weakPtr WeakPtr weakPtr = test; StrongPtr strongPtr5; strongPtr5 = weakPtr; EXPECT_EQ(test, strongPtr5.get()); // weakPtr other StrongPtr strongPtr6; strongPtr6 = weakPtr; EXPECT_EQ(test, strongPtr6.get()); test->destroy(); } TEST(StrongPtrTest, TestStrongPtrInVector) { bool bla; DestroyableTest* test = new DestroyableTest(bla); std::vector> vector; vector.push_back(test); vector.push_back(test); vector.push_back(test); ASSERT_EQ(3, vector.size()); EXPECT_EQ(test, vector[0].get()); EXPECT_EQ(test, vector[1].get()); EXPECT_EQ(test, vector[2].get()); EXPECT_EQ(3u, test->getReferenceCount()); vector.clear(); EXPECT_EQ(0u, test->getReferenceCount()); test->destroy(); } TEST(StrongPtrTest, TestReset) { bool bla; DestroyableTest* test = new DestroyableTest(bla); StrongPtr strongPtr(test); EXPECT_EQ(test, strongPtr.get()); EXPECT_EQ(1u, test->getReferenceCount()); strongPtr.reset(); EXPECT_EQ(nullptr, strongPtr.get()); EXPECT_EQ(0u, test->getReferenceCount()); test->destroy(); } TEST(StrongPtrTest, TestSwap) { bool bla; DestroyableTest* test1 = new DestroyableTest(bla); DestroyableTest* test2 = new DestroyableTest(bla); StrongPtr strongPtr1(test1); StrongPtr strongPtr2(test2); EXPECT_EQ(test1, strongPtr1.get()); EXPECT_EQ(test2, strongPtr2.get()); EXPECT_EQ(1u, test1->getReferenceCount()); EXPECT_EQ(1u, test2->getReferenceCount()); strongPtr1.swap(strongPtr2); EXPECT_EQ(test2, strongPtr1.get()); EXPECT_EQ(test1, strongPtr2.get()); EXPECT_EQ(1u, test1->getReferenceCount()); EXPECT_EQ(1u, test2->getReferenceCount()); test1->destroy(); test2->destroy(); } }