axmol/tests/cpp-tests/Classes/UnitTest/RefPtrTest.cpp

328 lines
11 KiB
C++

#include "RefPtrTest.h"
USING_NS_CC;
void RefPtrTest::onEnter()
{
UnitTestDemo::onEnter();
#if (defined(COCOS2D_DEBUG) && COCOS2D_DEBUG > 0)
// TEST(constructors)
{
// Default constructor
RefPtr<Ref> ref1;
CC_ASSERT(nullptr == ref1.get());
// Parameter constructor
RefPtr<__String> ref2(cocos2d::String::create("Hello"));
CC_ASSERT(strcmp("Hello", ref2->getCString()) == 0);
CC_ASSERT(2 == ref2->getReferenceCount());
// Parameter constructor with nullptr
RefPtr<__String> ref3(nullptr);
CC_ASSERT((__String*) nullptr == ref3.get());
// Copy constructor
RefPtr<__String> ref4(ref2);
CC_ASSERT(strcmp("Hello", ref4->getCString()) == 0);
CC_ASSERT(3 == ref2->getReferenceCount());
CC_ASSERT(3 == ref4->getReferenceCount());
// Copy constructor with nullptr reference
RefPtr<Ref> ref5(ref1);
CC_ASSERT((Ref*) nullptr == ref5.get());
}
// TEST(destructor)
{
__String * hello = __String::create("Hello");
CC_ASSERT(1 == hello->getReferenceCount());
{
RefPtr<Ref> ref(hello);
CC_ASSERT(2 == hello->getReferenceCount());
}
CC_ASSERT(1 == hello->getReferenceCount());
}
// TEST(assignmentOperator)
{
// Test basic assignment with pointer
RefPtr<__String> ref1;
CC_ASSERT((Ref*) nullptr == ref1.get());
ref1 = __String::create("World");
CC_ASSERT(strcmp("World", ref1->getCString()) == 0);
CC_ASSERT(2 == ref1->getReferenceCount());
// Assigment back to nullptr
__String * world = ref1;
CC_ASSERT(2 == world->getReferenceCount());
ref1 = nullptr;
CC_ASSERT(1 == world->getReferenceCount());
// Assignment swapping
ref1 = __String::create("Hello");
CC_ASSERT(strcmp("Hello", ref1->getCString()) == 0);
CC_ASSERT(2 == ref1->getReferenceCount());
__String * hello = (__String*) ref1;
CC_ASSERT(2 == hello->getReferenceCount());
ref1 = world;
CC_ASSERT(1 == hello->getReferenceCount());
CC_ASSERT(2 == world->getReferenceCount());
// Test assignment with another reference
RefPtr<__String> ref2 = __String::create("blah");
__String * blah = ref2;
CC_ASSERT(2 == blah->getReferenceCount());
ref2 = ref1;
CC_ASSERT(1 == blah->getReferenceCount());
CC_ASSERT(3 == world->getReferenceCount());
}
// TEST(castBackToPointerOperator)
{
RefPtr<__String> ref1 = __String::create("Hello");
__String * helloPtr = ref1;
Ref * objectPtr = ref1;
CC_ASSERT(helloPtr == objectPtr);
}
// TEST(dereferenceOperators)
{
RefPtr<__String> ref1 = __String::create("Hello");
CC_ASSERT(strcmp("Hello", ref1->getCString()) == 0);
CC_ASSERT(strcmp("Hello", (*ref1).getCString()) == 0);
}
// TEST(convertToBooleanOperator)
{
RefPtr<__String> ref1 = __String::create("Hello");
CC_ASSERT(true == (bool) ref1);
ref1 = nullptr;
CC_ASSERT(false == (bool) ref1);
}
// TEST(get)
{
RefPtr<__String> ref1 = __String::create("Hello");
CC_ASSERT(strcmp("Hello", ref1.get()->getCString()) == 0);
ref1.reset();
CC_ASSERT((__String*) nullptr == ref1.get());
}
// TEST(reset)
{
RefPtr<__String> ref1;
CC_ASSERT((__String*) nullptr == ref1.get());
ref1.reset();
CC_ASSERT((__String*) nullptr == ref1.get());
ref1 = __String::create("Hello");
CC_ASSERT(strcmp("Hello", ref1.get()->getCString()) == 0);
__String * hello = ref1.get();
CC_ASSERT(2 == hello->getReferenceCount());
ref1.reset();
CC_ASSERT((__String*) nullptr == ref1.get());
CC_ASSERT(1 == hello->getReferenceCount());
}
// TEST(swap)
{
RefPtr<__String> ref1;
RefPtr<__String> ref2;
CC_ASSERT((__String*) nullptr == ref1.get());
CC_ASSERT((__String*) nullptr == ref2.get());
ref1.swap(ref2);
CC_ASSERT((__String*) nullptr == ref1.get());
CC_ASSERT((__String*) nullptr == ref2.get());
__String * hello = __String::create("Hello");
CC_ASSERT(1 == hello->getReferenceCount());
ref1 = hello;
CC_ASSERT(2 == hello->getReferenceCount());
ref1.swap(ref2);
CC_ASSERT(2 == hello->getReferenceCount());
CC_ASSERT((__String*) nullptr == ref1.get());
CC_ASSERT(strcmp("Hello", ref2->getCString()) == 0);
ref1.swap(ref2);
CC_ASSERT(2 == hello->getReferenceCount());
CC_ASSERT(strcmp("Hello", ref1->getCString()) == 0);
CC_ASSERT((__String*) nullptr == ref2.get());
__String * world = __String::create("World");
CC_ASSERT(1 == world->getReferenceCount());
ref2 = world;
CC_ASSERT(2 == world->getReferenceCount());
ref2.swap(ref1);
CC_ASSERT(strcmp("World", ref1->getCString()) == 0);
CC_ASSERT(strcmp("Hello", ref2->getCString()) == 0);
CC_ASSERT(2 == hello->getReferenceCount());
CC_ASSERT(2 == world->getReferenceCount());
ref1.swap(ref2);
CC_ASSERT(strcmp("Hello", ref1->getCString()) == 0);
CC_ASSERT(strcmp("World", ref2->getCString()) == 0);
CC_ASSERT(2 == hello->getReferenceCount());
CC_ASSERT(2 == world->getReferenceCount());
}
// TEST(staticPointerCast)
{
RefPtr<__String> ref1 = __String::create("Hello");
CC_ASSERT(2 == ref1->getReferenceCount());
RefPtr<Ref> ref2 = static_pointer_cast<Ref>(ref1);
CC_ASSERT(strcmp("Hello", ((__String*) ref2.get())->getCString()) == 0);
CC_ASSERT(3 == ref1->getReferenceCount());
}
// TEST(dynamicPointerCast)
{
RefPtr<__String> ref1 = cocos2d::String::create("Hello");
CC_ASSERT(2 == ref1->getReferenceCount());
RefPtr<Ref> ref2 = dynamic_pointer_cast<Ref>(ref1);
CC_ASSERT(strcmp("Hello", ((__String*) ref2.get())->getCString()) == 0);
CC_ASSERT(3 == ref1->getReferenceCount());
RefPtr<__String> ref3 = dynamic_pointer_cast<__String>(ref2);
CC_ASSERT(strcmp("Hello", ref3->getCString()) == 0);
CC_ASSERT(4 == ref1->getReferenceCount());
RefPtr<cocos2d::Node> ref4 = dynamic_pointer_cast<cocos2d::Node>(ref2);
CC_ASSERT((Ref*) nullptr == ref4.get());
}
// TEST(weakAssign)
{
RefPtr<__String> ref1;
__String * string1 = new __String("Hello");
ref1.weakAssign(string1);
CC_ASSERT(1 == string1->getReferenceCount());
RefPtr<__String> ref2 = ref1;
CC_ASSERT(2 == string1->getReferenceCount());
__String * string2 = new __String("World");
ref1.weakAssign(string2);
CC_ASSERT(1 == string1->getReferenceCount());
CC_ASSERT(1 == ref2->getReferenceCount());
__String * string3 = new __String("Blah");
RefPtr<__String> ref3;
ref3.weakAssign(string3);
CC_ASSERT(1 == string3->getReferenceCount());
string3->retain();
CC_ASSERT(2 == string3->getReferenceCount());
ref3.weakAssign(nullptr);
CC_ASSERT(1 == string3->getReferenceCount());
CC_SAFE_RELEASE_NULL(string3);
}
// TEST(comparisonOperators)
{
RefPtr<Ref> ref1;
RefPtr<Ref> ref2;
CC_ASSERT(true == (ref1 == ref2));
CC_ASSERT(false == (ref1 != ref2));
CC_ASSERT(false == (ref1 < ref2));
CC_ASSERT(false == (ref1 > ref2));
CC_ASSERT(true == (ref1 <= ref2));
CC_ASSERT(true == (ref1 >= ref2));
CC_ASSERT(true == (ref1 == nullptr));
CC_ASSERT(false == (ref1 != nullptr));
CC_ASSERT(false == (ref1 < nullptr));
CC_ASSERT(false == (ref1 > nullptr));
CC_ASSERT(true == (ref1 <= nullptr));
CC_ASSERT(true == (ref1 >= nullptr));
CC_ASSERT(false == (ref1 == __String::create("Hello")));
CC_ASSERT(true == (ref1 != __String::create("Hello")));
CC_ASSERT(true == (ref1 < __String::create("Hello")));
CC_ASSERT(false == (ref1 > __String::create("Hello")));
CC_ASSERT(true == (ref1 <= __String::create("Hello")));
CC_ASSERT(false == (ref1 >= __String::create("Hello")));
ref1 = __String::create("Hello");
CC_ASSERT(false == (ref1 == ref2));
CC_ASSERT(true == (ref1 != ref2));
CC_ASSERT(false == (ref1 < ref2));
CC_ASSERT(true == (ref1 > ref2));
CC_ASSERT(false == (ref1 <= ref2));
CC_ASSERT(true == (ref1 >= ref2));
}
// TEST(moveConstructor)
{
auto someFunc = []() -> RefPtr<__String>
{
return __String::create("Hello world!");
};
// Note: std::move will turn the rvalue into an rvalue reference and thus cause the move constructor to be invoked.
// Have to use this because the compiler will try and optimize how we handle the return value otherwise and skip the move constructor.
RefPtr<__String> theString(std::move(someFunc()));
CC_ASSERT(theString->getReferenceCount() == 2);
CC_ASSERT(theString->compare("Hello world!") == 0);
__String * theStringPtr = theString;
theString.reset();
CC_ASSERT(theStringPtr->getReferenceCount() == 1);
CC_ASSERT(theStringPtr->compare("Hello world!") == 0);
}
// TEST(moveAssignmentOperator)
{
auto someFunc = []() -> RefPtr<__String>
{
return __String::create("Hello world!");
};
RefPtr<__String> theString(someFunc());
CC_ASSERT(theString->getReferenceCount() == 2);
CC_ASSERT(theString->compare("Hello world!") == 0);
theString = someFunc(); // No need to use std::move here, compiler should figure out that move semantics are appropriate for this statement.
CC_ASSERT(theString->getReferenceCount() == 2);
CC_ASSERT(theString->compare("Hello world!") == 0);
}
#else
log("RefPtr tests are not executed in release mode");
#endif
}
std::string RefPtrTest::subtitle() const
{
return "RefPtrTest, should not crash!";
}