Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

Changeset 10983 for code


Ignore:
Timestamp:
Dec 27, 2015, 11:17:12 PM (9 years ago)
Author:
landauf
Message:

added a bunch of unit tests for Functor

File:
1 edited

Legend:

Unmodified
Added
Removed
  • code/branches/cpp11_v2/test/core/command/FunctorTest.cc

    r10975 r10983  
    11#include <gtest/gtest.h>
     2#include <gmock/gmock.h>
     3#include <functional>
    24#include "core/command/Functor.h"
    35
     
    2123        class DestroyableClass : public Destroyable
    2224        {
    23                 public:
    24                     void method() {};
     25            public:
     26                virtual void        method0() { return; }
     27                virtual int         method1(int arg1) { return arg1; }
     28                virtual float       method2(int arg1, float arg2) { return arg2; }
     29                virtual bool        method3(int arg1, float arg2, bool arg3) { return arg3; }
     30                virtual std::string method4(int arg1, float arg2, bool arg3, const std::string& arg4) { return arg4; }
     31                virtual Vector3     method5(int arg1, float arg2, bool arg3, const std::string& arg4, const Vector3& arg5) { return arg5; }
     32
     33                static void        staticmethod0()
     34                    { return staticinstance->method0(); }
     35                static int         staticmethod1(int arg1)
     36                    { return staticinstance->method1(arg1); }
     37                static float       staticmethod2(int arg1, float arg2)
     38                    { return staticinstance->method2(arg1, arg2); }
     39                static bool        staticmethod3(int arg1, float arg2, bool arg3)
     40                    { return staticinstance->method3(arg1, arg2, arg3); }
     41                static std::string staticmethod4(int arg1, float arg2, bool arg3, const std::string& arg4)
     42                    { return staticinstance->method4(arg1, arg2, arg3, arg4); }
     43                static Vector3     staticmethod5(int arg1, float arg2, bool arg3, const std::string& arg4, const Vector3& arg5)
     44                    { return staticinstance->method5(arg1, arg2, arg3, arg4, arg5); }
     45
     46                static DestroyableClass* staticinstance;
    2547        };
    2648
    27         void f1(int, double)
    28         {
    29         }
    30 
    31         void f2(int, double, double)
    32         {
    33         }
    34 
    35         int f3(int, double, double)
    36         {
    37             return 0;
    38         }
     49        DestroyableClass* DestroyableClass::staticinstance = nullptr;
     50
     51        class MockDestroyableClass : public DestroyableClass
     52        {
     53            public:
     54                MOCK_METHOD0(method0, void());
     55                MOCK_METHOD1(method1, int(int));
     56                MOCK_METHOD2(method2, float(int, float));
     57                MOCK_METHOD3(method3, bool(int, float, bool));
     58                MOCK_METHOD4(method4, std::string(int, float, bool, const std::string&));
     59                MOCK_METHOD5(method5, Vector3(int, float, bool, const std::string&, const Vector3&));
     60        };
     61
     62        class NonDestroyableClass
     63        {
     64            public:
     65                void method() {}
     66        };
     67
     68        void f1(int, double) {}
     69        void f2(int, double, double) {}
     70        int f3(int, double, double) { return 0; }
     71        int f4a(int arg) { return arg*2; }
     72        int f4b(int arg) { return arg*3; }
    3973
    4074        struct CallableStruct
    4175        {
    42                 public:
    43                     int operator()()
    44                     {
    45                         return 1;
    46                     }
     76            public:
     77                int operator()()
     78                {
     79                    return 1;
     80                }
    4781        };
    4882    }
     83
     84
     85    ///////////////////////////////////////////////////////////////
     86    ////////////////////// Functor (general) //////////////////////
     87    ///////////////////////////////////////////////////////////////
     88
     89    TEST_F(FunctorTest, HasCorrectType)
     90    {
     91        FunctorMemberPtr<DestroyableClass> functor1 = createFunctor(&DestroyableClass::method0);
     92        FunctorStaticPtr functor2 = createFunctor(&DestroyableClass::staticmethod0);
     93        EXPECT_EQ(Functor::Type::Member, functor1->getType());
     94        EXPECT_EQ(Functor::Type::Static, functor2->getType());
     95    }
     96
     97    TEST_F(FunctorTest, ReturnsCorrectParamCount)
     98    {
     99        EXPECT_EQ(0, createFunctor(&DestroyableClass::method0)->getParamCount());
     100        EXPECT_EQ(1, createFunctor(&DestroyableClass::method1)->getParamCount());
     101        EXPECT_EQ(2, createFunctor(&DestroyableClass::method2)->getParamCount());
     102        EXPECT_EQ(3, createFunctor(&DestroyableClass::method3)->getParamCount());
     103        EXPECT_EQ(4, createFunctor(&DestroyableClass::method4)->getParamCount());
     104        EXPECT_EQ(5, createFunctor(&DestroyableClass::method5)->getParamCount());
     105    }
     106
     107    TEST_F(FunctorTest, HasReturnValue)
     108    {
     109        EXPECT_FALSE(createFunctor(&DestroyableClass::method0)->hasReturnvalue());
     110        EXPECT_TRUE(createFunctor(&DestroyableClass::method1)->hasReturnvalue());
     111        EXPECT_TRUE(createFunctor(&DestroyableClass::method2)->hasReturnvalue());
     112        EXPECT_TRUE(createFunctor(&DestroyableClass::method3)->hasReturnvalue());
     113        EXPECT_TRUE(createFunctor(&DestroyableClass::method4)->hasReturnvalue());
     114        EXPECT_TRUE(createFunctor(&DestroyableClass::method5)->hasReturnvalue());
     115    }
     116
     117    TEST_F(FunctorTest, GetTypenameParam)
     118    {
     119        FunctorPtr functor = createFunctor(&DestroyableClass::method5);
     120        EXPECT_EQ("int",     functor->getTypenameParam(0));
     121        EXPECT_EQ("float",   functor->getTypenameParam(1));
     122        EXPECT_EQ("bool",    functor->getTypenameParam(2));
     123        EXPECT_EQ("string",  functor->getTypenameParam(3));
     124        EXPECT_EQ("Vector3", functor->getTypenameParam(4));
     125        EXPECT_EQ("",        functor->getTypenameParam(5)); // max 5 arguments supported (index 0-4) -> this returns empty string
     126    }
     127
     128    TEST_F(FunctorTest, TypenameParamIsAlwaysVoidForFunctionWithoutParams)
     129    {
     130        FunctorPtr functor = createFunctor(&DestroyableClass::method0);
     131        EXPECT_EQ("void", functor->getTypenameParam(0));
     132        EXPECT_EQ("void", functor->getTypenameParam(1));
     133        EXPECT_EQ("void", functor->getTypenameParam(2));
     134        EXPECT_EQ("void", functor->getTypenameParam(3));
     135        EXPECT_EQ("void", functor->getTypenameParam(4));
     136        EXPECT_EQ("",     functor->getTypenameParam(5)); // max 5 arguments supported (index 0-4) -> this returns empty string
     137    }
     138
     139    TEST_F(FunctorTest, GetTypenameReturnvalue)
     140    {
     141        EXPECT_EQ("void",    createFunctor(&DestroyableClass::method0)->getTypenameReturnvalue());
     142        EXPECT_EQ("int",     createFunctor(&DestroyableClass::method1)->getTypenameReturnvalue());
     143        EXPECT_EQ("float",   createFunctor(&DestroyableClass::method2)->getTypenameReturnvalue());
     144        EXPECT_EQ("bool",    createFunctor(&DestroyableClass::method3)->getTypenameReturnvalue());
     145        EXPECT_EQ("string",  createFunctor(&DestroyableClass::method4)->getTypenameReturnvalue());
     146        EXPECT_EQ("Vector3", createFunctor(&DestroyableClass::method5)->getTypenameReturnvalue());
     147    }
     148
     149    TEST_F(FunctorTest, GetFullIdentifier)
     150    {
     151        // static
     152        EXPECT_EQ(typeid(       void(*)()),                                                     createFunctor(&DestroyableClass::staticmethod0)->getFullIdentifier());
     153        EXPECT_EQ(typeid(        int(*)(int)),                                                  createFunctor(&DestroyableClass::staticmethod1)->getFullIdentifier());
     154        EXPECT_EQ(typeid(      float(*)(int, float)),                                           createFunctor(&DestroyableClass::staticmethod2)->getFullIdentifier());
     155        EXPECT_EQ(typeid(       bool(*)(int, float, bool)),                                     createFunctor(&DestroyableClass::staticmethod3)->getFullIdentifier());
     156        EXPECT_EQ(typeid(std::string(*)(int, float, bool, const std::string&)),                 createFunctor(&DestroyableClass::staticmethod4)->getFullIdentifier());
     157        EXPECT_EQ(typeid(    Vector3(*)(int, float, bool, const std::string&, const Vector3&)), createFunctor(&DestroyableClass::staticmethod5)->getFullIdentifier());
     158
     159        // member
     160        EXPECT_EQ(typeid(       void(DestroyableClass::*)()),                                                     createFunctor(&DestroyableClass::method0)->getFullIdentifier());
     161        EXPECT_EQ(typeid(        int(DestroyableClass::*)(int)),                                                  createFunctor(&DestroyableClass::method1)->getFullIdentifier());
     162        EXPECT_EQ(typeid(      float(DestroyableClass::*)(int, float)),                                           createFunctor(&DestroyableClass::method2)->getFullIdentifier());
     163        EXPECT_EQ(typeid(       bool(DestroyableClass::*)(int, float, bool)),                                     createFunctor(&DestroyableClass::method3)->getFullIdentifier());
     164        EXPECT_EQ(typeid(std::string(DestroyableClass::*)(int, float, bool, const std::string&)),                 createFunctor(&DestroyableClass::method4)->getFullIdentifier());
     165        EXPECT_EQ(typeid(    Vector3(DestroyableClass::*)(int, float, bool, const std::string&, const Vector3&)), createFunctor(&DestroyableClass::method5)->getFullIdentifier());
     166    }
     167
     168    TEST_F(FunctorTest, GetHeaderIdentifier)
     169    {
     170        // static
     171        EXPECT_EQ(typeid(       void(*)()),                                                     createFunctor(&DestroyableClass::staticmethod0)->getHeaderIdentifier());
     172        EXPECT_EQ(typeid(        int(*)(int)),                                                  createFunctor(&DestroyableClass::staticmethod1)->getHeaderIdentifier());
     173        EXPECT_EQ(typeid(      float(*)(int, float)),                                           createFunctor(&DestroyableClass::staticmethod2)->getHeaderIdentifier());
     174        EXPECT_EQ(typeid(       bool(*)(int, float, bool)),                                     createFunctor(&DestroyableClass::staticmethod3)->getHeaderIdentifier());
     175        EXPECT_EQ(typeid(std::string(*)(int, float, bool, const std::string&)),                 createFunctor(&DestroyableClass::staticmethod4)->getHeaderIdentifier());
     176        EXPECT_EQ(typeid(    Vector3(*)(int, float, bool, const std::string&, const Vector3&)), createFunctor(&DestroyableClass::staticmethod5)->getHeaderIdentifier());
     177
     178        // member
     179        EXPECT_EQ(typeid(       void(*)()),                                                     createFunctor(&DestroyableClass::method0)->getHeaderIdentifier());
     180        EXPECT_EQ(typeid(        int(*)(int)),                                                  createFunctor(&DestroyableClass::method1)->getHeaderIdentifier());
     181        EXPECT_EQ(typeid(      float(*)(int, float)),                                           createFunctor(&DestroyableClass::method2)->getHeaderIdentifier());
     182        EXPECT_EQ(typeid(       bool(*)(int, float, bool)),                                     createFunctor(&DestroyableClass::method3)->getHeaderIdentifier());
     183        EXPECT_EQ(typeid(std::string(*)(int, float, bool, const std::string&)),                 createFunctor(&DestroyableClass::method4)->getHeaderIdentifier());
     184        EXPECT_EQ(typeid(    Vector3(*)(int, float, bool, const std::string&, const Vector3&)), createFunctor(&DestroyableClass::method5)->getHeaderIdentifier());
     185    }
     186
     187    TEST_F(FunctorTest, GetHeaderIdentifierFor2Params)
     188    {
     189        // static
     190        EXPECT_EQ(typeid(       void(*)()),           createFunctor(&DestroyableClass::staticmethod0)->getHeaderIdentifier(2));
     191        EXPECT_EQ(typeid(        int(*)(int)),        createFunctor(&DestroyableClass::staticmethod1)->getHeaderIdentifier(2));
     192        EXPECT_EQ(typeid(      float(*)(int, float)), createFunctor(&DestroyableClass::staticmethod2)->getHeaderIdentifier(2));
     193        EXPECT_EQ(typeid(       bool(*)(int, float)), createFunctor(&DestroyableClass::staticmethod3)->getHeaderIdentifier(2));
     194        EXPECT_EQ(typeid(std::string(*)(int, float)), createFunctor(&DestroyableClass::staticmethod4)->getHeaderIdentifier(2));
     195        EXPECT_EQ(typeid(    Vector3(*)(int, float)), createFunctor(&DestroyableClass::staticmethod5)->getHeaderIdentifier(2));
     196
     197        // member
     198        EXPECT_EQ(typeid(       void(*)()),           createFunctor(&DestroyableClass::method0)->getHeaderIdentifier(2));
     199        EXPECT_EQ(typeid(        int(*)(int)),        createFunctor(&DestroyableClass::method1)->getHeaderIdentifier(2));
     200        EXPECT_EQ(typeid(      float(*)(int, float)), createFunctor(&DestroyableClass::method2)->getHeaderIdentifier(2));
     201        EXPECT_EQ(typeid(       bool(*)(int, float)), createFunctor(&DestroyableClass::method3)->getHeaderIdentifier(2));
     202        EXPECT_EQ(typeid(std::string(*)(int, float)), createFunctor(&DestroyableClass::method4)->getHeaderIdentifier(2));
     203        EXPECT_EQ(typeid(    Vector3(*)(int, float)), createFunctor(&DestroyableClass::method5)->getHeaderIdentifier(2));
     204    }
     205
     206    TEST_F(FunctorTest, GetHeaderIdentifierForNParams)
     207    {
     208        // static
     209        FunctorStaticPtr functorStatic = createFunctor(&DestroyableClass::staticmethod5);
     210        EXPECT_EQ(typeid(Vector3(*)()),                                                     functorStatic->getHeaderIdentifier(0));
     211        EXPECT_EQ(typeid(Vector3(*)(int)),                                                  functorStatic->getHeaderIdentifier(1));
     212        EXPECT_EQ(typeid(Vector3(*)(int, float)),                                           functorStatic->getHeaderIdentifier(2));
     213        EXPECT_EQ(typeid(Vector3(*)(int, float, bool)),                                     functorStatic->getHeaderIdentifier(3));
     214        EXPECT_EQ(typeid(Vector3(*)(int, float, bool, const std::string&)),                 functorStatic->getHeaderIdentifier(4));
     215        EXPECT_EQ(typeid(Vector3(*)(int, float, bool, const std::string&, const Vector3&)), functorStatic->getHeaderIdentifier(5));
     216        EXPECT_EQ(typeid(Vector3(*)(int, float, bool, const std::string&, const Vector3&)), functorStatic->getHeaderIdentifier(6));
     217
     218        // member
     219        FunctorMemberPtr<DestroyableClass> functorMember = createFunctor(&DestroyableClass::method5);
     220        EXPECT_EQ(typeid(Vector3(*)()),                                                     functorMember->getHeaderIdentifier(0));
     221        EXPECT_EQ(typeid(Vector3(*)(int)),                                                  functorMember->getHeaderIdentifier(1));
     222        EXPECT_EQ(typeid(Vector3(*)(int, float)),                                           functorMember->getHeaderIdentifier(2));
     223        EXPECT_EQ(typeid(Vector3(*)(int, float, bool)),                                     functorMember->getHeaderIdentifier(3));
     224        EXPECT_EQ(typeid(Vector3(*)(int, float, bool, const std::string&)),                 functorMember->getHeaderIdentifier(4));
     225        EXPECT_EQ(typeid(Vector3(*)(int, float, bool, const std::string&, const Vector3&)), functorMember->getHeaderIdentifier(5));
     226        EXPECT_EQ(typeid(Vector3(*)(int, float, bool, const std::string&, const Vector3&)), functorMember->getHeaderIdentifier(6));
     227    }
     228
     229    TEST_F(FunctorTest, CanClone)
     230    {
     231        FunctorPtr functor = createFunctor(&f4a);
     232        FunctorPtr clone = functor->clone();
     233        EXPECT_NE(nullptr, clone.get());
     234    }
     235
     236    TEST_F(FunctorTest, ClonedFunctorCanBeCalled)
     237    {
     238        FunctorPtr functor = createFunctor(&f4a);
     239        FunctorPtr clone = functor->clone();
     240
     241        EXPECT_EQ(8, (*functor)(4).get<int>());
     242        EXPECT_EQ(8, (*clone)(4).get<int>());
     243    }
     244
     245    TEST_F(FunctorTest, ClonedFunctorKeepsFunction)
     246    {
     247        FunctorPtr functor = createFunctor(&f4a);
     248        FunctorPointer<int(*)(int)>* pointer = static_cast<FunctorPointer<int(*)(int)>*>(functor.get());
     249
     250        FunctorPtr clone = functor->clone();
     251        FunctorPointer<int(*)(int)>* clonePointer = static_cast<FunctorPointer<int(*)(int)>*>(clone.get());
     252
     253        EXPECT_EQ(&f4a, pointer->getFunction());
     254        EXPECT_EQ(&f4a, clonePointer->getFunction());
     255    }
     256
     257    TEST_F(FunctorTest, ClonedFunctorKeepsObject)
     258    {
     259        DestroyableClass object;
     260        FunctorPtr functor = createFunctor(&DestroyableClass::method0, &object);
     261        FunctorPtr clone = functor->clone();
     262
     263        EXPECT_EQ(&object, functor->getRawObjectPointer());
     264        EXPECT_EQ(&object, clone->getRawObjectPointer());
     265    }
     266
     267    // TODO: test fails... fix or delete clone()
     268//    TEST_F(FunctorTest, ClonedFunctorKeepsSafeMode)
     269//    {
     270//        DestroyableClass* object = new DestroyableClass();
     271//        FunctorPtr functor = createFunctor(&DestroyableClass::method0, object);
     272//        functor->setSafeMode(true);
     273//        FunctorPtr clone = functor->clone();
     274//
     275//        EXPECT_EQ(object, functor->getRawObjectPointer());
     276//        EXPECT_EQ(object, clone->getRawObjectPointer());
     277//        object->destroy();
     278//        EXPECT_EQ(nullptr, functor->getRawObjectPointer());
     279//        EXPECT_EQ(nullptr, clone->getRawObjectPointer());
     280//
     281//    }
     282
     283    TEST_F(FunctorTest, CanEvaluateArgument)
     284    {
     285        FunctorPtr functor = createFunctor(&f4a);
     286        MultiType value("5");
     287        EXPECT_FALSE(value.isType<int>());
     288        EXPECT_TRUE(value.isType<std::string>());
     289        functor->evaluateArgument(0, value);
     290        EXPECT_TRUE(value.isType<int>());
     291        EXPECT_FALSE(value.isType<std::string>());
     292    }
     293
     294    TEST_F(FunctorTest, CanGetAndSetFunctionPointer)
     295    {
     296        FunctorPtr functor = createFunctor(&f4a);
     297        FunctorPointer<int(*)(int)>* pointer = static_cast<FunctorPointer<int(*)(int)>*>(functor.get());
     298
     299        EXPECT_EQ(6, (*functor)(3).get<int>()); // 3*2 = 6
     300        EXPECT_EQ(&f4a, pointer->getFunction());
     301
     302        pointer->setFunction(&f4b);
     303
     304        EXPECT_EQ(9, (*functor)(3).get<int>()); // 3*3 = 9
     305        EXPECT_EQ(&f4b, pointer->getFunction());
     306    }
     307
     308    TEST_F(FunctorTest, ReturnsValue)
     309    {
     310        DestroyableClass object;
     311        {
     312            FunctorMemberPtr<DestroyableClass> functor = createFunctor(&DestroyableClass::method1);
     313            int result = (*functor)(&object, 13);
     314            EXPECT_EQ(13, result);
     315        }
     316        {
     317            FunctorMemberPtr<DestroyableClass> functor = createFunctor(&DestroyableClass::method2);
     318            float result = (*functor)(&object, 0, 111.11);
     319            EXPECT_FLOAT_EQ(111.11, result);
     320        }
     321        {
     322            FunctorMemberPtr<DestroyableClass> functor = createFunctor(&DestroyableClass::method3);
     323            bool result = (*functor)(&object, 0, 0, true);
     324            EXPECT_EQ(true, result);
     325        }
     326        {
     327            FunctorMemberPtr<DestroyableClass> functor = createFunctor(&DestroyableClass::method4);
     328            std::string result = (*functor)(&object, 0, 0, false, "test");
     329            EXPECT_EQ("test", result);
     330        }
     331        {
     332            FunctorMemberPtr<DestroyableClass> functor = createFunctor(&DestroyableClass::method5);
     333            Vector3 result = (*functor)(&object, 0, 0, false, "", Vector3(3, 2, 1));
     334            EXPECT_EQ(Vector3(3, 2, 1), result);
     335        }
     336    }
     337
     338
     339    ///////////////////////////////////////////////////////////
     340    ////////////////////// FunctorMember //////////////////////
     341    ///////////////////////////////////////////////////////////
     342
     343    TEST_F(FunctorTest, FunctorMember_CanSetObject)
     344    {
     345        DestroyableClass object;
     346
     347        FunctorMemberPtr<DestroyableClass> functor = createFunctor(&DestroyableClass::method0);
     348        EXPECT_EQ(nullptr, functor->getObject());
     349        functor->setObject(&object);
     350        EXPECT_EQ(&object, functor->getObject());
     351        functor->setObject(nullptr);
     352        EXPECT_EQ(nullptr, functor->getObject());
     353    }
     354
     355    TEST_F(FunctorTest, FunctorMember_CanSetObjectInConstructor)
     356    {
     357        DestroyableClass object;
     358
     359        FunctorMemberPtr<DestroyableClass> functor = createFunctor(&DestroyableClass::method0, &object);
     360        EXPECT_EQ(&object, functor->getObject());
     361        functor->setObject(nullptr);
     362        EXPECT_EQ(nullptr, functor->getObject());
     363    }
     364
     365    TEST_F(FunctorTest, FunctorMember_CanSetRawObjectPointer)
     366    {
     367        DestroyableClass object;
     368
     369        FunctorMemberPtr<DestroyableClass> functor = createFunctor(&DestroyableClass::method0);
     370        EXPECT_EQ(nullptr, functor->getRawObjectPointer());
     371        functor->setRawObjectPointer(&object);
     372        EXPECT_EQ(&object, functor->getRawObjectPointer());
     373        functor->setRawObjectPointer(nullptr);
     374        EXPECT_EQ(nullptr, functor->getRawObjectPointer());
     375    }
     376
     377    TEST_F(FunctorTest, FunctorMember_RawObjectPointerAndObjectAreEqual)
     378    {
     379        DestroyableClass object1;
     380        DestroyableClass object2;
     381
     382        FunctorMemberPtr<DestroyableClass> functor = createFunctor(&DestroyableClass::method0);
     383        EXPECT_EQ(nullptr, functor->getRawObjectPointer());
     384        EXPECT_EQ(nullptr, functor->getObject());
     385        functor->setObject(&object1);
     386        EXPECT_EQ(&object1, functor->getRawObjectPointer());
     387        EXPECT_EQ(&object1, functor->getObject());
     388        functor->setObject(&object2);
     389        EXPECT_EQ(&object2, functor->getRawObjectPointer());
     390        EXPECT_EQ(&object2, functor->getObject());
     391    }
     392
     393    TEST_F(FunctorTest, FunctorMember_SafeModeWorks_SetObjectThenActivateSafeMode)
     394    {
     395        FunctorMemberPtr<DestroyableClass> functor = createFunctor(&DestroyableClass::method0);
     396        {
     397            DestroyableClass object;
     398            functor->setObject(&object);
     399            functor->setSafeMode(true);
     400            EXPECT_EQ(&object, functor->getObject());
     401        }
     402        EXPECT_EQ(nullptr, functor->getObject());
     403    }
     404
     405    TEST_F(FunctorTest, FunctorMember_SafeModeWorks_ActivateSafeModeThenSetObject)
     406    {
     407        FunctorMemberPtr<DestroyableClass> functor = createFunctor(&DestroyableClass::method0);
     408        {
     409            DestroyableClass object;
     410            functor->setSafeMode(true);
     411            functor->setObject(&object);
     412            EXPECT_EQ(&object, functor->getObject());
     413        }
     414        EXPECT_EQ(nullptr, functor->getObject());
     415    }
     416
     417    TEST_F(FunctorTest, FunctorMember_SafeModeCanBeDisabledAfterObjectWasSet)
     418    {
     419        DestroyableClass* ptr;
     420        FunctorMemberPtr<DestroyableClass> functor = createFunctor(&DestroyableClass::method0);
     421        {
     422            DestroyableClass object;
     423            functor->setSafeMode(true);
     424            functor->setObject(&object);
     425            functor->setSafeMode(false);
     426            ptr = &object; // remember the pointer
     427            EXPECT_EQ(ptr, functor->getObject());
     428        }
     429        EXPECT_EQ(ptr, functor->getObject());
     430    }
     431
     432    TEST_F(FunctorTest, FunctorMember_SafeModeWorks_CanChangeObject)
     433    {
     434        FunctorMemberPtr<DestroyableClass> functor = createFunctor(&DestroyableClass::method0);
     435        DestroyableClass* object1 = new DestroyableClass();
     436        DestroyableClass* object2 = new DestroyableClass();
     437        functor->setSafeMode(true);
     438
     439        functor->setObject(object1);
     440        EXPECT_EQ(object1, functor->getObject());
     441        functor->setObject(object2);
     442        EXPECT_EQ(object2, functor->getObject());
     443        object1->destroy();
     444        EXPECT_EQ(object2, functor->getObject());
     445        object2->destroy();
     446        EXPECT_EQ(nullptr, functor->getObject());
     447    }
     448
     449    TEST_F(FunctorTest, FunctorMember_CanDestroyFunctorWhenObjectInSafeModeStillExists)
     450    {
     451        DestroyableClass object;
     452        {
     453            FunctorMemberPtr<DestroyableClass> functor = createFunctor(&DestroyableClass::method0);
     454            functor->setSafeMode(true);
     455            functor->setObject(&object);
     456            EXPECT_EQ(&object, functor->getObject());
     457        } // functor is destroyed here
     458    }
     459
     460    TEST_F(FunctorTest, FunctorMember_SafeModeDoesntDoAnythingWithObjectsNotInheritedFromDestroyable)
     461    {
     462        NonDestroyableClass* ptr;
     463        FunctorMemberPtr<NonDestroyableClass> functor = createFunctor(&NonDestroyableClass::method);
     464        {
     465            NonDestroyableClass object;
     466            functor->setSafeMode(true);
     467            functor->setObject(&object);
     468            ptr = &object; // remember the pointer
     469            EXPECT_EQ(ptr, functor->getObject());
     470        }
     471        EXPECT_EQ(ptr, functor->getObject()); // pointer is still set because safe mode doesn't work on NonDestroyableClass
     472    }
     473
     474    TEST_F(FunctorTest, FunctorMember_CanCall_WithObjectInCall)
     475    {
     476        MockDestroyableClass mock;
     477        {
     478            EXPECT_CALL(mock, method0());
     479            FunctorMemberPtr<DestroyableClass> functor = createFunctor(&DestroyableClass::method0);
     480            (*functor)(&mock);
     481        }
     482        {
     483            EXPECT_CALL(mock, method1(13)).WillOnce(::testing::Return(0));
     484            FunctorMemberPtr<DestroyableClass> functor = createFunctor(&DestroyableClass::method1);
     485            (*functor)(&mock, 13);
     486        }
     487        {
     488            EXPECT_CALL(mock, method2(13, 111.11)).WillOnce(::testing::Return(0.0));
     489            FunctorMemberPtr<DestroyableClass> functor = createFunctor(&DestroyableClass::method2);
     490            (*functor)(&mock, 13, 111.11);
     491        }
     492        {
     493            EXPECT_CALL(mock, method3(13, 111.11, true)).WillOnce(::testing::Return(false));
     494            FunctorMemberPtr<DestroyableClass> functor = createFunctor(&DestroyableClass::method3);
     495            (*functor)(&mock, 13, 111.11, true);
     496        }
     497        {
     498            EXPECT_CALL(mock, method4(13, 111.11, true, "test")).WillOnce(::testing::Return(""));
     499            FunctorMemberPtr<DestroyableClass> functor = createFunctor(&DestroyableClass::method4);
     500            (*functor)(&mock, 13, 111.11, true, "test");
     501        }
     502        {
     503            EXPECT_CALL(mock, method5(13, 111.11, true, "test", Vector3(3, 2, 1))).WillOnce(::testing::Return(Vector3()));
     504            FunctorMemberPtr<DestroyableClass> functor = createFunctor(&DestroyableClass::method5);
     505            (*functor)(&mock, 13, 111.11, true, "test", Vector3(3, 2, 1));
     506        }
     507    }
     508
     509    TEST_F(FunctorTest, FunctorMember_CanCall_WithObjectInConstructor)
     510    {
     511        MockDestroyableClass mock;
     512        {
     513            EXPECT_CALL(mock, method0());
     514            FunctorMemberPtr<DestroyableClass> functor = createFunctor(&DestroyableClass::method0, &mock);
     515            (*functor)();
     516        }
     517        {
     518            EXPECT_CALL(mock, method1(13)).WillOnce(::testing::Return(0));
     519            FunctorMemberPtr<DestroyableClass> functor = createFunctor(&DestroyableClass::method1, &mock);
     520            (*functor)(13);
     521        }
     522        {
     523            EXPECT_CALL(mock, method2(13, 111.11)).WillOnce(::testing::Return(0.0));
     524            FunctorMemberPtr<DestroyableClass> functor = createFunctor(&DestroyableClass::method2, &mock);
     525            (*functor)(13, 111.11);
     526        }
     527        {
     528            EXPECT_CALL(mock, method3(13, 111.11, true)).WillOnce(::testing::Return(false));
     529            FunctorMemberPtr<DestroyableClass> functor = createFunctor(&DestroyableClass::method3, &mock);
     530            (*functor)(13, 111.11, true);
     531        }
     532        {
     533            EXPECT_CALL(mock, method4(13, 111.11, true, "test")).WillOnce(::testing::Return(""));
     534            FunctorMemberPtr<DestroyableClass> functor = createFunctor(&DestroyableClass::method4, &mock);
     535            (*functor)(13, 111.11, true, "test");
     536        }
     537        {
     538            EXPECT_CALL(mock, method5(13, 111.11, true, "test", Vector3(3, 2, 1))).WillOnce(::testing::Return(Vector3()));
     539            FunctorMemberPtr<DestroyableClass> functor = createFunctor(&DestroyableClass::method5, &mock);
     540            (*functor)(13, 111.11, true, "test", Vector3(3, 2, 1));
     541        }
     542    }
     543
     544    TEST_F(FunctorTest, FunctorMember_ReturnsZeroIfCalledWithoutObject)
     545    {
     546        DestroyableClass object;
     547        {
     548            FunctorMemberPtr<DestroyableClass> functor = createFunctor(&DestroyableClass::method1);
     549            int resultWithObject = (*functor)(&object, 13);
     550            int resultWithoutObject = (*functor)(13);
     551            EXPECT_EQ(13, resultWithObject);
     552            EXPECT_EQ(0, resultWithoutObject);
     553        }
     554    }
     555
     556
     557    ///////////////////////////////////////////////////////////
     558    ////////////////////// FunctorStatic //////////////////////
     559    ///////////////////////////////////////////////////////////
     560
     561    TEST_F(FunctorTest, FunctorStatic_CanCall)
     562    {
     563        MockDestroyableClass mock;
     564        DestroyableClass::staticinstance = &mock;
     565
     566        {
     567            EXPECT_CALL(mock, method0());
     568            FunctorStaticPtr functor = createFunctor(&DestroyableClass::staticmethod0);
     569            (*functor)();
     570        }
     571        {
     572            EXPECT_CALL(mock, method1(13)).WillOnce(::testing::Return(0));
     573            FunctorStaticPtr functor = createFunctor(&DestroyableClass::staticmethod1);
     574            (*functor)(13);
     575        }
     576        {
     577            EXPECT_CALL(mock, method2(13, 111.11)).WillOnce(::testing::Return(0.0));
     578            FunctorStaticPtr functor = createFunctor(&DestroyableClass::staticmethod2);
     579            (*functor)(13, 111.11);
     580        }
     581        {
     582            EXPECT_CALL(mock, method3(13, 111.11, true)).WillOnce(::testing::Return(false));
     583            FunctorStaticPtr functor = createFunctor(&DestroyableClass::staticmethod3);
     584            (*functor)(13, 111.11, true);
     585        }
     586        {
     587            EXPECT_CALL(mock, method4(13, 111.11, true, "test")).WillOnce(::testing::Return(""));
     588            FunctorStaticPtr functor = createFunctor(&DestroyableClass::staticmethod4);
     589            (*functor)(13, 111.11, true, "test");
     590        }
     591        {
     592            EXPECT_CALL(mock, method5(13, 111.11, true, "test", Vector3(3, 2, 1))).WillOnce(::testing::Return(Vector3()));
     593            FunctorStaticPtr functor = createFunctor(&DestroyableClass::staticmethod5);
     594            (*functor)(13, 111.11, true, "test", Vector3(3, 2, 1));
     595        }
     596    }
     597
     598    TEST_F(FunctorTest, FunctorStatic_CanCallWithObject)
     599    {
     600        MockDestroyableClass mock;
     601        DestroyableClass::staticinstance = &mock;
     602
     603        {
     604            EXPECT_CALL(mock, method0());
     605            FunctorStaticPtr functor = createFunctor(&DestroyableClass::staticmethod0);
     606            (*functor)(&mock); // object is ignored
     607        }
     608    }
     609
     610    TEST_F(FunctorTest, FunctorStatic_CanCallWithNull)
     611    {
     612        MockDestroyableClass mock;
     613        DestroyableClass::staticinstance = &mock;
     614
     615        {
     616            EXPECT_CALL(mock, method0());
     617            FunctorStaticPtr functor = createFunctor(&DestroyableClass::staticmethod0);
     618            (*functor)(nullptr); // pointer is ignored
     619        }
     620    }
     621
     622    TEST_F(FunctorTest, FunctorStatic_RawObjectPointerIsAlwaysNull)
     623    {
     624        DestroyableClass object;
     625
     626        FunctorStaticPtr functor = createFunctor(&DestroyableClass::staticmethod0);
     627        EXPECT_EQ(nullptr, functor->getRawObjectPointer());
     628        functor->setRawObjectPointer(&object);
     629        EXPECT_EQ(nullptr, functor->getRawObjectPointer());
     630        functor->setRawObjectPointer(nullptr);
     631        EXPECT_EQ(nullptr, functor->getRawObjectPointer());
     632    }
     633
     634    ////////////////////////////// Various tests //////////////////////////////
    49635
    50636    TEST_F(FunctorTest, canCompareHeaderIdentifiers)
     
    121707        DestroyableClass* testclass = new DestroyableClass();
    122708        DestroyableClass* testclass2 = new DestroyableClass();
    123         FunctorPtr fp1 = createFunctor(&DestroyableClass::method, testclass);
     709        FunctorPtr fp1 = createFunctor(&DestroyableClass::method0, testclass);
    124710        fp1->setSafeMode(true);
    125         FunctorPtr fp2 = createFunctor(&DestroyableClass::method, testclass);
     711        FunctorPtr fp2 = createFunctor(&DestroyableClass::method0, testclass);
    126712        fp2->setSafeMode(true);
    127         FunctorPtr fp3 = createFunctor(&DestroyableClass::method, testclass);
     713        FunctorPtr fp3 = createFunctor(&DestroyableClass::method0, testclass);
    128714        fp2->setRawObjectPointer(testclass2);
    129715
Note: See TracChangeset for help on using the changeset viewer.