[Orxonox-commit 6326] r10983 - code/branches/cpp11_v2/test/core/command
landauf at orxonox.net
landauf at orxonox.net
Sun Dec 27 23:17:13 CET 2015
Author: landauf
Date: 2015-12-27 23:17:12 +0100 (Sun, 27 Dec 2015)
New Revision: 10983
Modified:
code/branches/cpp11_v2/test/core/command/FunctorTest.cc
Log:
added a bunch of unit tests for Functor
Modified: code/branches/cpp11_v2/test/core/command/FunctorTest.cc
===================================================================
--- code/branches/cpp11_v2/test/core/command/FunctorTest.cc 2015-12-27 22:07:37 UTC (rev 10982)
+++ code/branches/cpp11_v2/test/core/command/FunctorTest.cc 2015-12-27 22:17:12 UTC (rev 10983)
@@ -1,4 +1,6 @@
#include <gtest/gtest.h>
+#include <gmock/gmock.h>
+#include <functional>
#include "core/command/Functor.h"
namespace orxonox
@@ -20,33 +22,617 @@
class DestroyableClass : public Destroyable
{
- public:
- void method() {};
+ public:
+ virtual void method0() { return; }
+ virtual int method1(int arg1) { return arg1; }
+ virtual float method2(int arg1, float arg2) { return arg2; }
+ virtual bool method3(int arg1, float arg2, bool arg3) { return arg3; }
+ virtual std::string method4(int arg1, float arg2, bool arg3, const std::string& arg4) { return arg4; }
+ virtual Vector3 method5(int arg1, float arg2, bool arg3, const std::string& arg4, const Vector3& arg5) { return arg5; }
+
+ static void staticmethod0()
+ { return staticinstance->method0(); }
+ static int staticmethod1(int arg1)
+ { return staticinstance->method1(arg1); }
+ static float staticmethod2(int arg1, float arg2)
+ { return staticinstance->method2(arg1, arg2); }
+ static bool staticmethod3(int arg1, float arg2, bool arg3)
+ { return staticinstance->method3(arg1, arg2, arg3); }
+ static std::string staticmethod4(int arg1, float arg2, bool arg3, const std::string& arg4)
+ { return staticinstance->method4(arg1, arg2, arg3, arg4); }
+ static Vector3 staticmethod5(int arg1, float arg2, bool arg3, const std::string& arg4, const Vector3& arg5)
+ { return staticinstance->method5(arg1, arg2, arg3, arg4, arg5); }
+
+ static DestroyableClass* staticinstance;
};
- void f1(int, double)
+ DestroyableClass* DestroyableClass::staticinstance = nullptr;
+
+ class MockDestroyableClass : public DestroyableClass
{
+ public:
+ MOCK_METHOD0(method0, void());
+ MOCK_METHOD1(method1, int(int));
+ MOCK_METHOD2(method2, float(int, float));
+ MOCK_METHOD3(method3, bool(int, float, bool));
+ MOCK_METHOD4(method4, std::string(int, float, bool, const std::string&));
+ MOCK_METHOD5(method5, Vector3(int, float, bool, const std::string&, const Vector3&));
+ };
+
+ class NonDestroyableClass
+ {
+ public:
+ void method() {}
+ };
+
+ void f1(int, double) {}
+ void f2(int, double, double) {}
+ int f3(int, double, double) { return 0; }
+ int f4a(int arg) { return arg*2; }
+ int f4b(int arg) { return arg*3; }
+
+ struct CallableStruct
+ {
+ public:
+ int operator()()
+ {
+ return 1;
+ }
+ };
+ }
+
+
+ ///////////////////////////////////////////////////////////////
+ ////////////////////// Functor (general) //////////////////////
+ ///////////////////////////////////////////////////////////////
+
+ TEST_F(FunctorTest, HasCorrectType)
+ {
+ FunctorMemberPtr<DestroyableClass> functor1 = createFunctor(&DestroyableClass::method0);
+ FunctorStaticPtr functor2 = createFunctor(&DestroyableClass::staticmethod0);
+ EXPECT_EQ(Functor::Type::Member, functor1->getType());
+ EXPECT_EQ(Functor::Type::Static, functor2->getType());
+ }
+
+ TEST_F(FunctorTest, ReturnsCorrectParamCount)
+ {
+ EXPECT_EQ(0, createFunctor(&DestroyableClass::method0)->getParamCount());
+ EXPECT_EQ(1, createFunctor(&DestroyableClass::method1)->getParamCount());
+ EXPECT_EQ(2, createFunctor(&DestroyableClass::method2)->getParamCount());
+ EXPECT_EQ(3, createFunctor(&DestroyableClass::method3)->getParamCount());
+ EXPECT_EQ(4, createFunctor(&DestroyableClass::method4)->getParamCount());
+ EXPECT_EQ(5, createFunctor(&DestroyableClass::method5)->getParamCount());
+ }
+
+ TEST_F(FunctorTest, HasReturnValue)
+ {
+ EXPECT_FALSE(createFunctor(&DestroyableClass::method0)->hasReturnvalue());
+ EXPECT_TRUE(createFunctor(&DestroyableClass::method1)->hasReturnvalue());
+ EXPECT_TRUE(createFunctor(&DestroyableClass::method2)->hasReturnvalue());
+ EXPECT_TRUE(createFunctor(&DestroyableClass::method3)->hasReturnvalue());
+ EXPECT_TRUE(createFunctor(&DestroyableClass::method4)->hasReturnvalue());
+ EXPECT_TRUE(createFunctor(&DestroyableClass::method5)->hasReturnvalue());
+ }
+
+ TEST_F(FunctorTest, GetTypenameParam)
+ {
+ FunctorPtr functor = createFunctor(&DestroyableClass::method5);
+ EXPECT_EQ("int", functor->getTypenameParam(0));
+ EXPECT_EQ("float", functor->getTypenameParam(1));
+ EXPECT_EQ("bool", functor->getTypenameParam(2));
+ EXPECT_EQ("string", functor->getTypenameParam(3));
+ EXPECT_EQ("Vector3", functor->getTypenameParam(4));
+ EXPECT_EQ("", functor->getTypenameParam(5)); // max 5 arguments supported (index 0-4) -> this returns empty string
+ }
+
+ TEST_F(FunctorTest, TypenameParamIsAlwaysVoidForFunctionWithoutParams)
+ {
+ FunctorPtr functor = createFunctor(&DestroyableClass::method0);
+ EXPECT_EQ("void", functor->getTypenameParam(0));
+ EXPECT_EQ("void", functor->getTypenameParam(1));
+ EXPECT_EQ("void", functor->getTypenameParam(2));
+ EXPECT_EQ("void", functor->getTypenameParam(3));
+ EXPECT_EQ("void", functor->getTypenameParam(4));
+ EXPECT_EQ("", functor->getTypenameParam(5)); // max 5 arguments supported (index 0-4) -> this returns empty string
+ }
+
+ TEST_F(FunctorTest, GetTypenameReturnvalue)
+ {
+ EXPECT_EQ("void", createFunctor(&DestroyableClass::method0)->getTypenameReturnvalue());
+ EXPECT_EQ("int", createFunctor(&DestroyableClass::method1)->getTypenameReturnvalue());
+ EXPECT_EQ("float", createFunctor(&DestroyableClass::method2)->getTypenameReturnvalue());
+ EXPECT_EQ("bool", createFunctor(&DestroyableClass::method3)->getTypenameReturnvalue());
+ EXPECT_EQ("string", createFunctor(&DestroyableClass::method4)->getTypenameReturnvalue());
+ EXPECT_EQ("Vector3", createFunctor(&DestroyableClass::method5)->getTypenameReturnvalue());
+ }
+
+ TEST_F(FunctorTest, GetFullIdentifier)
+ {
+ // static
+ EXPECT_EQ(typeid( void(*)()), createFunctor(&DestroyableClass::staticmethod0)->getFullIdentifier());
+ EXPECT_EQ(typeid( int(*)(int)), createFunctor(&DestroyableClass::staticmethod1)->getFullIdentifier());
+ EXPECT_EQ(typeid( float(*)(int, float)), createFunctor(&DestroyableClass::staticmethod2)->getFullIdentifier());
+ EXPECT_EQ(typeid( bool(*)(int, float, bool)), createFunctor(&DestroyableClass::staticmethod3)->getFullIdentifier());
+ EXPECT_EQ(typeid(std::string(*)(int, float, bool, const std::string&)), createFunctor(&DestroyableClass::staticmethod4)->getFullIdentifier());
+ EXPECT_EQ(typeid( Vector3(*)(int, float, bool, const std::string&, const Vector3&)), createFunctor(&DestroyableClass::staticmethod5)->getFullIdentifier());
+
+ // member
+ EXPECT_EQ(typeid( void(DestroyableClass::*)()), createFunctor(&DestroyableClass::method0)->getFullIdentifier());
+ EXPECT_EQ(typeid( int(DestroyableClass::*)(int)), createFunctor(&DestroyableClass::method1)->getFullIdentifier());
+ EXPECT_EQ(typeid( float(DestroyableClass::*)(int, float)), createFunctor(&DestroyableClass::method2)->getFullIdentifier());
+ EXPECT_EQ(typeid( bool(DestroyableClass::*)(int, float, bool)), createFunctor(&DestroyableClass::method3)->getFullIdentifier());
+ EXPECT_EQ(typeid(std::string(DestroyableClass::*)(int, float, bool, const std::string&)), createFunctor(&DestroyableClass::method4)->getFullIdentifier());
+ EXPECT_EQ(typeid( Vector3(DestroyableClass::*)(int, float, bool, const std::string&, const Vector3&)), createFunctor(&DestroyableClass::method5)->getFullIdentifier());
+ }
+
+ TEST_F(FunctorTest, GetHeaderIdentifier)
+ {
+ // static
+ EXPECT_EQ(typeid( void(*)()), createFunctor(&DestroyableClass::staticmethod0)->getHeaderIdentifier());
+ EXPECT_EQ(typeid( int(*)(int)), createFunctor(&DestroyableClass::staticmethod1)->getHeaderIdentifier());
+ EXPECT_EQ(typeid( float(*)(int, float)), createFunctor(&DestroyableClass::staticmethod2)->getHeaderIdentifier());
+ EXPECT_EQ(typeid( bool(*)(int, float, bool)), createFunctor(&DestroyableClass::staticmethod3)->getHeaderIdentifier());
+ EXPECT_EQ(typeid(std::string(*)(int, float, bool, const std::string&)), createFunctor(&DestroyableClass::staticmethod4)->getHeaderIdentifier());
+ EXPECT_EQ(typeid( Vector3(*)(int, float, bool, const std::string&, const Vector3&)), createFunctor(&DestroyableClass::staticmethod5)->getHeaderIdentifier());
+
+ // member
+ EXPECT_EQ(typeid( void(*)()), createFunctor(&DestroyableClass::method0)->getHeaderIdentifier());
+ EXPECT_EQ(typeid( int(*)(int)), createFunctor(&DestroyableClass::method1)->getHeaderIdentifier());
+ EXPECT_EQ(typeid( float(*)(int, float)), createFunctor(&DestroyableClass::method2)->getHeaderIdentifier());
+ EXPECT_EQ(typeid( bool(*)(int, float, bool)), createFunctor(&DestroyableClass::method3)->getHeaderIdentifier());
+ EXPECT_EQ(typeid(std::string(*)(int, float, bool, const std::string&)), createFunctor(&DestroyableClass::method4)->getHeaderIdentifier());
+ EXPECT_EQ(typeid( Vector3(*)(int, float, bool, const std::string&, const Vector3&)), createFunctor(&DestroyableClass::method5)->getHeaderIdentifier());
+ }
+
+ TEST_F(FunctorTest, GetHeaderIdentifierFor2Params)
+ {
+ // static
+ EXPECT_EQ(typeid( void(*)()), createFunctor(&DestroyableClass::staticmethod0)->getHeaderIdentifier(2));
+ EXPECT_EQ(typeid( int(*)(int)), createFunctor(&DestroyableClass::staticmethod1)->getHeaderIdentifier(2));
+ EXPECT_EQ(typeid( float(*)(int, float)), createFunctor(&DestroyableClass::staticmethod2)->getHeaderIdentifier(2));
+ EXPECT_EQ(typeid( bool(*)(int, float)), createFunctor(&DestroyableClass::staticmethod3)->getHeaderIdentifier(2));
+ EXPECT_EQ(typeid(std::string(*)(int, float)), createFunctor(&DestroyableClass::staticmethod4)->getHeaderIdentifier(2));
+ EXPECT_EQ(typeid( Vector3(*)(int, float)), createFunctor(&DestroyableClass::staticmethod5)->getHeaderIdentifier(2));
+
+ // member
+ EXPECT_EQ(typeid( void(*)()), createFunctor(&DestroyableClass::method0)->getHeaderIdentifier(2));
+ EXPECT_EQ(typeid( int(*)(int)), createFunctor(&DestroyableClass::method1)->getHeaderIdentifier(2));
+ EXPECT_EQ(typeid( float(*)(int, float)), createFunctor(&DestroyableClass::method2)->getHeaderIdentifier(2));
+ EXPECT_EQ(typeid( bool(*)(int, float)), createFunctor(&DestroyableClass::method3)->getHeaderIdentifier(2));
+ EXPECT_EQ(typeid(std::string(*)(int, float)), createFunctor(&DestroyableClass::method4)->getHeaderIdentifier(2));
+ EXPECT_EQ(typeid( Vector3(*)(int, float)), createFunctor(&DestroyableClass::method5)->getHeaderIdentifier(2));
+ }
+
+ TEST_F(FunctorTest, GetHeaderIdentifierForNParams)
+ {
+ // static
+ FunctorStaticPtr functorStatic = createFunctor(&DestroyableClass::staticmethod5);
+ EXPECT_EQ(typeid(Vector3(*)()), functorStatic->getHeaderIdentifier(0));
+ EXPECT_EQ(typeid(Vector3(*)(int)), functorStatic->getHeaderIdentifier(1));
+ EXPECT_EQ(typeid(Vector3(*)(int, float)), functorStatic->getHeaderIdentifier(2));
+ EXPECT_EQ(typeid(Vector3(*)(int, float, bool)), functorStatic->getHeaderIdentifier(3));
+ EXPECT_EQ(typeid(Vector3(*)(int, float, bool, const std::string&)), functorStatic->getHeaderIdentifier(4));
+ EXPECT_EQ(typeid(Vector3(*)(int, float, bool, const std::string&, const Vector3&)), functorStatic->getHeaderIdentifier(5));
+ EXPECT_EQ(typeid(Vector3(*)(int, float, bool, const std::string&, const Vector3&)), functorStatic->getHeaderIdentifier(6));
+
+ // member
+ FunctorMemberPtr<DestroyableClass> functorMember = createFunctor(&DestroyableClass::method5);
+ EXPECT_EQ(typeid(Vector3(*)()), functorMember->getHeaderIdentifier(0));
+ EXPECT_EQ(typeid(Vector3(*)(int)), functorMember->getHeaderIdentifier(1));
+ EXPECT_EQ(typeid(Vector3(*)(int, float)), functorMember->getHeaderIdentifier(2));
+ EXPECT_EQ(typeid(Vector3(*)(int, float, bool)), functorMember->getHeaderIdentifier(3));
+ EXPECT_EQ(typeid(Vector3(*)(int, float, bool, const std::string&)), functorMember->getHeaderIdentifier(4));
+ EXPECT_EQ(typeid(Vector3(*)(int, float, bool, const std::string&, const Vector3&)), functorMember->getHeaderIdentifier(5));
+ EXPECT_EQ(typeid(Vector3(*)(int, float, bool, const std::string&, const Vector3&)), functorMember->getHeaderIdentifier(6));
+ }
+
+ TEST_F(FunctorTest, CanClone)
+ {
+ FunctorPtr functor = createFunctor(&f4a);
+ FunctorPtr clone = functor->clone();
+ EXPECT_NE(nullptr, clone.get());
+ }
+
+ TEST_F(FunctorTest, ClonedFunctorCanBeCalled)
+ {
+ FunctorPtr functor = createFunctor(&f4a);
+ FunctorPtr clone = functor->clone();
+
+ EXPECT_EQ(8, (*functor)(4).get<int>());
+ EXPECT_EQ(8, (*clone)(4).get<int>());
+ }
+
+ TEST_F(FunctorTest, ClonedFunctorKeepsFunction)
+ {
+ FunctorPtr functor = createFunctor(&f4a);
+ FunctorPointer<int(*)(int)>* pointer = static_cast<FunctorPointer<int(*)(int)>*>(functor.get());
+
+ FunctorPtr clone = functor->clone();
+ FunctorPointer<int(*)(int)>* clonePointer = static_cast<FunctorPointer<int(*)(int)>*>(clone.get());
+
+ EXPECT_EQ(&f4a, pointer->getFunction());
+ EXPECT_EQ(&f4a, clonePointer->getFunction());
+ }
+
+ TEST_F(FunctorTest, ClonedFunctorKeepsObject)
+ {
+ DestroyableClass object;
+ FunctorPtr functor = createFunctor(&DestroyableClass::method0, &object);
+ FunctorPtr clone = functor->clone();
+
+ EXPECT_EQ(&object, functor->getRawObjectPointer());
+ EXPECT_EQ(&object, clone->getRawObjectPointer());
+ }
+
+ // TODO: test fails... fix or delete clone()
+// TEST_F(FunctorTest, ClonedFunctorKeepsSafeMode)
+// {
+// DestroyableClass* object = new DestroyableClass();
+// FunctorPtr functor = createFunctor(&DestroyableClass::method0, object);
+// functor->setSafeMode(true);
+// FunctorPtr clone = functor->clone();
+//
+// EXPECT_EQ(object, functor->getRawObjectPointer());
+// EXPECT_EQ(object, clone->getRawObjectPointer());
+// object->destroy();
+// EXPECT_EQ(nullptr, functor->getRawObjectPointer());
+// EXPECT_EQ(nullptr, clone->getRawObjectPointer());
+//
+// }
+
+ TEST_F(FunctorTest, CanEvaluateArgument)
+ {
+ FunctorPtr functor = createFunctor(&f4a);
+ MultiType value("5");
+ EXPECT_FALSE(value.isType<int>());
+ EXPECT_TRUE(value.isType<std::string>());
+ functor->evaluateArgument(0, value);
+ EXPECT_TRUE(value.isType<int>());
+ EXPECT_FALSE(value.isType<std::string>());
+ }
+
+ TEST_F(FunctorTest, CanGetAndSetFunctionPointer)
+ {
+ FunctorPtr functor = createFunctor(&f4a);
+ FunctorPointer<int(*)(int)>* pointer = static_cast<FunctorPointer<int(*)(int)>*>(functor.get());
+
+ EXPECT_EQ(6, (*functor)(3).get<int>()); // 3*2 = 6
+ EXPECT_EQ(&f4a, pointer->getFunction());
+
+ pointer->setFunction(&f4b);
+
+ EXPECT_EQ(9, (*functor)(3).get<int>()); // 3*3 = 9
+ EXPECT_EQ(&f4b, pointer->getFunction());
+ }
+
+ TEST_F(FunctorTest, ReturnsValue)
+ {
+ DestroyableClass object;
+ {
+ FunctorMemberPtr<DestroyableClass> functor = createFunctor(&DestroyableClass::method1);
+ int result = (*functor)(&object, 13);
+ EXPECT_EQ(13, result);
}
+ {
+ FunctorMemberPtr<DestroyableClass> functor = createFunctor(&DestroyableClass::method2);
+ float result = (*functor)(&object, 0, 111.11);
+ EXPECT_FLOAT_EQ(111.11, result);
+ }
+ {
+ FunctorMemberPtr<DestroyableClass> functor = createFunctor(&DestroyableClass::method3);
+ bool result = (*functor)(&object, 0, 0, true);
+ EXPECT_EQ(true, result);
+ }
+ {
+ FunctorMemberPtr<DestroyableClass> functor = createFunctor(&DestroyableClass::method4);
+ std::string result = (*functor)(&object, 0, 0, false, "test");
+ EXPECT_EQ("test", result);
+ }
+ {
+ FunctorMemberPtr<DestroyableClass> functor = createFunctor(&DestroyableClass::method5);
+ Vector3 result = (*functor)(&object, 0, 0, false, "", Vector3(3, 2, 1));
+ EXPECT_EQ(Vector3(3, 2, 1), result);
+ }
+ }
- void f2(int, double, double)
+
+ ///////////////////////////////////////////////////////////
+ ////////////////////// FunctorMember //////////////////////
+ ///////////////////////////////////////////////////////////
+
+ TEST_F(FunctorTest, FunctorMember_CanSetObject)
+ {
+ DestroyableClass object;
+
+ FunctorMemberPtr<DestroyableClass> functor = createFunctor(&DestroyableClass::method0);
+ EXPECT_EQ(nullptr, functor->getObject());
+ functor->setObject(&object);
+ EXPECT_EQ(&object, functor->getObject());
+ functor->setObject(nullptr);
+ EXPECT_EQ(nullptr, functor->getObject());
+ }
+
+ TEST_F(FunctorTest, FunctorMember_CanSetObjectInConstructor)
+ {
+ DestroyableClass object;
+
+ FunctorMemberPtr<DestroyableClass> functor = createFunctor(&DestroyableClass::method0, &object);
+ EXPECT_EQ(&object, functor->getObject());
+ functor->setObject(nullptr);
+ EXPECT_EQ(nullptr, functor->getObject());
+ }
+
+ TEST_F(FunctorTest, FunctorMember_CanSetRawObjectPointer)
+ {
+ DestroyableClass object;
+
+ FunctorMemberPtr<DestroyableClass> functor = createFunctor(&DestroyableClass::method0);
+ EXPECT_EQ(nullptr, functor->getRawObjectPointer());
+ functor->setRawObjectPointer(&object);
+ EXPECT_EQ(&object, functor->getRawObjectPointer());
+ functor->setRawObjectPointer(nullptr);
+ EXPECT_EQ(nullptr, functor->getRawObjectPointer());
+ }
+
+ TEST_F(FunctorTest, FunctorMember_RawObjectPointerAndObjectAreEqual)
+ {
+ DestroyableClass object1;
+ DestroyableClass object2;
+
+ FunctorMemberPtr<DestroyableClass> functor = createFunctor(&DestroyableClass::method0);
+ EXPECT_EQ(nullptr, functor->getRawObjectPointer());
+ EXPECT_EQ(nullptr, functor->getObject());
+ functor->setObject(&object1);
+ EXPECT_EQ(&object1, functor->getRawObjectPointer());
+ EXPECT_EQ(&object1, functor->getObject());
+ functor->setObject(&object2);
+ EXPECT_EQ(&object2, functor->getRawObjectPointer());
+ EXPECT_EQ(&object2, functor->getObject());
+ }
+
+ TEST_F(FunctorTest, FunctorMember_SafeModeWorks_SetObjectThenActivateSafeMode)
+ {
+ FunctorMemberPtr<DestroyableClass> functor = createFunctor(&DestroyableClass::method0);
{
+ DestroyableClass object;
+ functor->setObject(&object);
+ functor->setSafeMode(true);
+ EXPECT_EQ(&object, functor->getObject());
}
+ EXPECT_EQ(nullptr, functor->getObject());
+ }
- int f3(int, double, double)
+ TEST_F(FunctorTest, FunctorMember_SafeModeWorks_ActivateSafeModeThenSetObject)
+ {
+ FunctorMemberPtr<DestroyableClass> functor = createFunctor(&DestroyableClass::method0);
{
- return 0;
+ DestroyableClass object;
+ functor->setSafeMode(true);
+ functor->setObject(&object);
+ EXPECT_EQ(&object, functor->getObject());
}
+ EXPECT_EQ(nullptr, functor->getObject());
+ }
- struct CallableStruct
+ TEST_F(FunctorTest, FunctorMember_SafeModeCanBeDisabledAfterObjectWasSet)
+ {
+ DestroyableClass* ptr;
+ FunctorMemberPtr<DestroyableClass> functor = createFunctor(&DestroyableClass::method0);
{
- public:
- int operator()()
- {
- return 1;
- }
- };
+ DestroyableClass object;
+ functor->setSafeMode(true);
+ functor->setObject(&object);
+ functor->setSafeMode(false);
+ ptr = &object; // remember the pointer
+ EXPECT_EQ(ptr, functor->getObject());
+ }
+ EXPECT_EQ(ptr, functor->getObject());
}
+ TEST_F(FunctorTest, FunctorMember_SafeModeWorks_CanChangeObject)
+ {
+ FunctorMemberPtr<DestroyableClass> functor = createFunctor(&DestroyableClass::method0);
+ DestroyableClass* object1 = new DestroyableClass();
+ DestroyableClass* object2 = new DestroyableClass();
+ functor->setSafeMode(true);
+
+ functor->setObject(object1);
+ EXPECT_EQ(object1, functor->getObject());
+ functor->setObject(object2);
+ EXPECT_EQ(object2, functor->getObject());
+ object1->destroy();
+ EXPECT_EQ(object2, functor->getObject());
+ object2->destroy();
+ EXPECT_EQ(nullptr, functor->getObject());
+ }
+
+ TEST_F(FunctorTest, FunctorMember_CanDestroyFunctorWhenObjectInSafeModeStillExists)
+ {
+ DestroyableClass object;
+ {
+ FunctorMemberPtr<DestroyableClass> functor = createFunctor(&DestroyableClass::method0);
+ functor->setSafeMode(true);
+ functor->setObject(&object);
+ EXPECT_EQ(&object, functor->getObject());
+ } // functor is destroyed here
+ }
+
+ TEST_F(FunctorTest, FunctorMember_SafeModeDoesntDoAnythingWithObjectsNotInheritedFromDestroyable)
+ {
+ NonDestroyableClass* ptr;
+ FunctorMemberPtr<NonDestroyableClass> functor = createFunctor(&NonDestroyableClass::method);
+ {
+ NonDestroyableClass object;
+ functor->setSafeMode(true);
+ functor->setObject(&object);
+ ptr = &object; // remember the pointer
+ EXPECT_EQ(ptr, functor->getObject());
+ }
+ EXPECT_EQ(ptr, functor->getObject()); // pointer is still set because safe mode doesn't work on NonDestroyableClass
+ }
+
+ TEST_F(FunctorTest, FunctorMember_CanCall_WithObjectInCall)
+ {
+ MockDestroyableClass mock;
+ {
+ EXPECT_CALL(mock, method0());
+ FunctorMemberPtr<DestroyableClass> functor = createFunctor(&DestroyableClass::method0);
+ (*functor)(&mock);
+ }
+ {
+ EXPECT_CALL(mock, method1(13)).WillOnce(::testing::Return(0));
+ FunctorMemberPtr<DestroyableClass> functor = createFunctor(&DestroyableClass::method1);
+ (*functor)(&mock, 13);
+ }
+ {
+ EXPECT_CALL(mock, method2(13, 111.11)).WillOnce(::testing::Return(0.0));
+ FunctorMemberPtr<DestroyableClass> functor = createFunctor(&DestroyableClass::method2);
+ (*functor)(&mock, 13, 111.11);
+ }
+ {
+ EXPECT_CALL(mock, method3(13, 111.11, true)).WillOnce(::testing::Return(false));
+ FunctorMemberPtr<DestroyableClass> functor = createFunctor(&DestroyableClass::method3);
+ (*functor)(&mock, 13, 111.11, true);
+ }
+ {
+ EXPECT_CALL(mock, method4(13, 111.11, true, "test")).WillOnce(::testing::Return(""));
+ FunctorMemberPtr<DestroyableClass> functor = createFunctor(&DestroyableClass::method4);
+ (*functor)(&mock, 13, 111.11, true, "test");
+ }
+ {
+ EXPECT_CALL(mock, method5(13, 111.11, true, "test", Vector3(3, 2, 1))).WillOnce(::testing::Return(Vector3()));
+ FunctorMemberPtr<DestroyableClass> functor = createFunctor(&DestroyableClass::method5);
+ (*functor)(&mock, 13, 111.11, true, "test", Vector3(3, 2, 1));
+ }
+ }
+
+ TEST_F(FunctorTest, FunctorMember_CanCall_WithObjectInConstructor)
+ {
+ MockDestroyableClass mock;
+ {
+ EXPECT_CALL(mock, method0());
+ FunctorMemberPtr<DestroyableClass> functor = createFunctor(&DestroyableClass::method0, &mock);
+ (*functor)();
+ }
+ {
+ EXPECT_CALL(mock, method1(13)).WillOnce(::testing::Return(0));
+ FunctorMemberPtr<DestroyableClass> functor = createFunctor(&DestroyableClass::method1, &mock);
+ (*functor)(13);
+ }
+ {
+ EXPECT_CALL(mock, method2(13, 111.11)).WillOnce(::testing::Return(0.0));
+ FunctorMemberPtr<DestroyableClass> functor = createFunctor(&DestroyableClass::method2, &mock);
+ (*functor)(13, 111.11);
+ }
+ {
+ EXPECT_CALL(mock, method3(13, 111.11, true)).WillOnce(::testing::Return(false));
+ FunctorMemberPtr<DestroyableClass> functor = createFunctor(&DestroyableClass::method3, &mock);
+ (*functor)(13, 111.11, true);
+ }
+ {
+ EXPECT_CALL(mock, method4(13, 111.11, true, "test")).WillOnce(::testing::Return(""));
+ FunctorMemberPtr<DestroyableClass> functor = createFunctor(&DestroyableClass::method4, &mock);
+ (*functor)(13, 111.11, true, "test");
+ }
+ {
+ EXPECT_CALL(mock, method5(13, 111.11, true, "test", Vector3(3, 2, 1))).WillOnce(::testing::Return(Vector3()));
+ FunctorMemberPtr<DestroyableClass> functor = createFunctor(&DestroyableClass::method5, &mock);
+ (*functor)(13, 111.11, true, "test", Vector3(3, 2, 1));
+ }
+ }
+
+ TEST_F(FunctorTest, FunctorMember_ReturnsZeroIfCalledWithoutObject)
+ {
+ DestroyableClass object;
+ {
+ FunctorMemberPtr<DestroyableClass> functor = createFunctor(&DestroyableClass::method1);
+ int resultWithObject = (*functor)(&object, 13);
+ int resultWithoutObject = (*functor)(13);
+ EXPECT_EQ(13, resultWithObject);
+ EXPECT_EQ(0, resultWithoutObject);
+ }
+ }
+
+
+ ///////////////////////////////////////////////////////////
+ ////////////////////// FunctorStatic //////////////////////
+ ///////////////////////////////////////////////////////////
+
+ TEST_F(FunctorTest, FunctorStatic_CanCall)
+ {
+ MockDestroyableClass mock;
+ DestroyableClass::staticinstance = &mock;
+
+ {
+ EXPECT_CALL(mock, method0());
+ FunctorStaticPtr functor = createFunctor(&DestroyableClass::staticmethod0);
+ (*functor)();
+ }
+ {
+ EXPECT_CALL(mock, method1(13)).WillOnce(::testing::Return(0));
+ FunctorStaticPtr functor = createFunctor(&DestroyableClass::staticmethod1);
+ (*functor)(13);
+ }
+ {
+ EXPECT_CALL(mock, method2(13, 111.11)).WillOnce(::testing::Return(0.0));
+ FunctorStaticPtr functor = createFunctor(&DestroyableClass::staticmethod2);
+ (*functor)(13, 111.11);
+ }
+ {
+ EXPECT_CALL(mock, method3(13, 111.11, true)).WillOnce(::testing::Return(false));
+ FunctorStaticPtr functor = createFunctor(&DestroyableClass::staticmethod3);
+ (*functor)(13, 111.11, true);
+ }
+ {
+ EXPECT_CALL(mock, method4(13, 111.11, true, "test")).WillOnce(::testing::Return(""));
+ FunctorStaticPtr functor = createFunctor(&DestroyableClass::staticmethod4);
+ (*functor)(13, 111.11, true, "test");
+ }
+ {
+ EXPECT_CALL(mock, method5(13, 111.11, true, "test", Vector3(3, 2, 1))).WillOnce(::testing::Return(Vector3()));
+ FunctorStaticPtr functor = createFunctor(&DestroyableClass::staticmethod5);
+ (*functor)(13, 111.11, true, "test", Vector3(3, 2, 1));
+ }
+ }
+
+ TEST_F(FunctorTest, FunctorStatic_CanCallWithObject)
+ {
+ MockDestroyableClass mock;
+ DestroyableClass::staticinstance = &mock;
+
+ {
+ EXPECT_CALL(mock, method0());
+ FunctorStaticPtr functor = createFunctor(&DestroyableClass::staticmethod0);
+ (*functor)(&mock); // object is ignored
+ }
+ }
+
+ TEST_F(FunctorTest, FunctorStatic_CanCallWithNull)
+ {
+ MockDestroyableClass mock;
+ DestroyableClass::staticinstance = &mock;
+
+ {
+ EXPECT_CALL(mock, method0());
+ FunctorStaticPtr functor = createFunctor(&DestroyableClass::staticmethod0);
+ (*functor)(nullptr); // pointer is ignored
+ }
+ }
+
+ TEST_F(FunctorTest, FunctorStatic_RawObjectPointerIsAlwaysNull)
+ {
+ DestroyableClass object;
+
+ FunctorStaticPtr functor = createFunctor(&DestroyableClass::staticmethod0);
+ EXPECT_EQ(nullptr, functor->getRawObjectPointer());
+ functor->setRawObjectPointer(&object);
+ EXPECT_EQ(nullptr, functor->getRawObjectPointer());
+ functor->setRawObjectPointer(nullptr);
+ EXPECT_EQ(nullptr, functor->getRawObjectPointer());
+ }
+
+ ////////////////////////////// Various tests //////////////////////////////
+
TEST_F(FunctorTest, canCompareHeaderIdentifiers)
{
FunctorPtr fp1 = createFunctor(&f1);
@@ -120,11 +706,11 @@
{
DestroyableClass* testclass = new DestroyableClass();
DestroyableClass* testclass2 = new DestroyableClass();
- FunctorPtr fp1 = createFunctor(&DestroyableClass::method, testclass);
+ FunctorPtr fp1 = createFunctor(&DestroyableClass::method0, testclass);
fp1->setSafeMode(true);
- FunctorPtr fp2 = createFunctor(&DestroyableClass::method, testclass);
+ FunctorPtr fp2 = createFunctor(&DestroyableClass::method0, testclass);
fp2->setSafeMode(true);
- FunctorPtr fp3 = createFunctor(&DestroyableClass::method, testclass);
+ FunctorPtr fp3 = createFunctor(&DestroyableClass::method0, testclass);
fp2->setRawObjectPointer(testclass2);
ASSERT_NE(nullptr, fp1->getRawObjectPointer());
More information about the Orxonox-commit
mailing list