Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/cpp11_v2/test/core/command/FunctorTest.cc @ 10975

Last change on this file since 10975 was 10975, checked in by muemart, 10 years ago

Extend Functor to handle any callable objects (lambdas!). Had to modify (un)registerObject, because apparently you can't dynamic_cast lambdas. Also wanted to perfect forward the object from createFunctor until obj_, but MSVC didn't like that.
Including new and improved Functor tests.

  • Property svn:eol-style set to native
File size: 4.9 KB
RevLine 
[10922]1#include <gtest/gtest.h>
2#include "core/command/Functor.h"
3
4namespace orxonox
5{
6    namespace
7    {
8        // Fixture
9        class FunctorTest : public ::testing::Test
10        {
11            public:
12                virtual void SetUp() override
13                {
14                }
15
16                virtual void TearDown() override
17                {
18                }
19        };
20
[10975]21        class DestroyableClass : public Destroyable
22        {
23                public:
24                    void method() {};
25        };
26
[10922]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        }
[10975]39
40        struct CallableStruct
41        {
42                public:
43                    int operator()()
44                    {
45                        return 1;
46                    }
47        };
[10922]48    }
49
50    TEST_F(FunctorTest, canCompareHeaderIdentifiers)
51    {
52        FunctorPtr fp1 = createFunctor(&f1);
53        FunctorPtr fp2 = createFunctor(&f2);
54        FunctorPtr fp3 = createFunctor(&f3);
[10975]55        ASSERT_STREQ(fp1->getHeaderIdentifier(1).name(), fp2->getHeaderIdentifier(1).name());
56        ASSERT_STREQ(fp1->getHeaderIdentifier(2).name(), fp2->getHeaderIdentifier(2).name());
57        ASSERT_STRNE(fp1->getHeaderIdentifier(1).name(), fp2->getHeaderIdentifier(2).name());
58        ASSERT_STRNE(fp1->getHeaderIdentifier(10).name(), fp2->getHeaderIdentifier(10).name());
59        ASSERT_STRNE(fp2->getHeaderIdentifier(2).name(), fp3->getHeaderIdentifier(2).name());
60        ASSERT_STRNE(fp1->getHeaderIdentifier().name(), fp2->getHeaderIdentifier().name());
61        ASSERT_STRNE(fp2->getHeaderIdentifier().name(), fp3->getHeaderIdentifier().name());
[10922]62    }
63
64    TEST_F(FunctorTest, canCompareTypenames)
65    {
66        FunctorPtr fp1 = createFunctor(&f1);
67        FunctorPtr fp2 = createFunctor(&f2);
68        FunctorPtr fp3 = createFunctor(&f3);
[10975]69        ASSERT_EQ(fp1->getTypenameReturnvalue(), fp2->getTypenameReturnvalue());
70        ASSERT_EQ(fp1->getTypenameParam(0), fp3->getTypenameParam(0));
[10922]71        ASSERT_EQ("void", fp1->getTypenameReturnvalue());
72        ASSERT_EQ("int", fp3->getTypenameReturnvalue());
73        ASSERT_EQ("int", fp2->getTypenameParam(0));
74        ASSERT_EQ("double", fp3->getTypenameParam(2));
75        ASSERT_EQ("", fp3->getTypenameParam(6));
76    }
77
78    TEST_F(FunctorTest, testGetParamCountAndHasReturnValue)
79    {
80        FunctorPtr fp1 = createFunctor(&f1);
81        FunctorPtr fp2 = createFunctor(&f2);
82        FunctorPtr fp3 = createFunctor(&f3);
83        ASSERT_EQ(3, fp2->getParamCount());
[10975]84        ASSERT_NE(fp1->getParamCount(), fp3->getParamCount());
[10922]85        ASSERT_FALSE(fp2->hasReturnvalue());
86        ASSERT_TRUE(fp3->hasReturnvalue());
87    }
88
89    TEST_F(FunctorTest, canEvaluateArgument)
90    {
91        FunctorPtr fp1 = createFunctor(&f1);
92        MultiType mttype = "2";
93        fp1->evaluateArgument(0, mttype);
94        ASSERT_TRUE(mttype.isType<int>());
95        ASSERT_EQ(2, mttype.get<int>());
96        fp1->evaluateArgument(1, mttype);
97        ASSERT_TRUE(mttype.isType<double>());
98        ASSERT_EQ(2.0, mttype.get<double>());
99        mttype.reset();
100        fp1->evaluateArgument(5, mttype);
101        ASSERT_TRUE(mttype.null());
102    }
[10975]103
104    TEST_F(FunctorTest, canUseCallables)
105    {
106        int a = 0;
107        FunctorPtr fp1 = createFunctor(CallableStruct{});
108        FunctorPtr fp2 = createFunctor([](bool val) { return val; });
109        FunctorPtr fp3 = createFunctor([&a]() {return a++; });
110        FunctorPtr fp4 = createFunctor([a]() {return a; });
111        ASSERT_EQ(1, (*fp1)().get<int>());
112        ASSERT_EQ(true, (*fp2)(true).get<bool>());
113        ASSERT_EQ(0, (*fp3)().get<int>());
114        ASSERT_EQ(1, a);
115        ASSERT_EQ(0, (*fp4)().get<int>());
116        ASSERT_STREQ(fp1->getHeaderIdentifier().name(), fp3->getHeaderIdentifier().name());
117    }
118
119    TEST_F(FunctorTest, SafeModeWorks)
120    {
121        DestroyableClass* testclass = new DestroyableClass();
122        DestroyableClass* testclass2 = new DestroyableClass();
123        FunctorPtr fp1 = createFunctor(&DestroyableClass::method, testclass);
124        fp1->setSafeMode(true);
125        FunctorPtr fp2 = createFunctor(&DestroyableClass::method, testclass);
126        fp2->setSafeMode(true);
127        FunctorPtr fp3 = createFunctor(&DestroyableClass::method, testclass);
128        fp2->setRawObjectPointer(testclass2);
129
130        ASSERT_NE(nullptr, fp1->getRawObjectPointer());
131        ASSERT_NE(nullptr, fp2->getRawObjectPointer());
132        ASSERT_NE(nullptr, fp3->getRawObjectPointer());
133        testclass->destroy();
134        ASSERT_EQ(nullptr, fp1->getRawObjectPointer());
135        ASSERT_NE(nullptr, fp2->getRawObjectPointer());
136        ASSERT_NE(nullptr, fp3->getRawObjectPointer());
137
138        fp3->setRawObjectPointer(testclass2);
139        fp3->setSafeMode(true);
140        fp2->setSafeMode(false);
141        testclass2->destroy();
142        ASSERT_NE(nullptr, fp2->getRawObjectPointer());
143        ASSERT_EQ(nullptr, fp3->getRawObjectPointer());
144    }
[10922]145}
Note: See TracBrowser for help on using the repository browser.