1 | #include <gtest/gtest.h> |
---|
2 | #include "core/command/Functor.h" |
---|
3 | |
---|
4 | namespace 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 | } |
---|