[10922] | 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 | |
---|
[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 | } |
---|