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, 8 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
Line 
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
21        class DestroyableClass : public Destroyable
22        {
23                public:
24                    void method() {};
25        };
26
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        }
39
40        struct CallableStruct
41        {
42                public:
43                    int operator()()
44                    {
45                        return 1;
46                    }
47        };
48    }
49
50    TEST_F(FunctorTest, canCompareHeaderIdentifiers)
51    {
52        FunctorPtr fp1 = createFunctor(&f1);
53        FunctorPtr fp2 = createFunctor(&f2);
54        FunctorPtr fp3 = createFunctor(&f3);
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());
62    }
63
64    TEST_F(FunctorTest, canCompareTypenames)
65    {
66        FunctorPtr fp1 = createFunctor(&f1);
67        FunctorPtr fp2 = createFunctor(&f2);
68        FunctorPtr fp3 = createFunctor(&f3);
69        ASSERT_EQ(fp1->getTypenameReturnvalue(), fp2->getTypenameReturnvalue());
70        ASSERT_EQ(fp1->getTypenameParam(0), fp3->getTypenameParam(0));
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());
84        ASSERT_NE(fp1->getParamCount(), fp3->getParamCount());
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    }
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    }
145}
Note: See TracBrowser for help on using the repository browser.