// GNU Lesser General Public License v3.0 // Copyright (c) 2023 Bart Beumer // // This program is free software; you can redistribute it and/or modify it // under the terms of the GNU Lesser General Public License v3.0 as published by // the Free Software Foundation. // #include "bmrshared/invoke.hpp" #include "MockDataSource.hpp" #include #include #include using ::testing::An; using ::testing::ElementsAre; using ::testing::Return; using ::testing::SetArgReferee; using ::testing::TypedEq; using bmrshared::flexible_value; using bmrshared::MockDataSource; namespace { // Compile-time test of some helper templates. static_assert(std::is_same, 0>::tuple, std::tuple<>>::value); static_assert(std::is_same, 1>::tuple, std::tuple>::value); static_assert(std::is_same, 2>::tuple, std::tuple>::value); static_assert(std::is_same, 0>::tuple, std::tuple>::value); static_assert(std::is_same, 1>::tuple, std::tuple>::value); static_assert( std::is_same, 2>::tuple, std::tuple<>>::value); class TestAddition { public: uint64_t AddNumbers(uint64_t left, uint64_t right) { return left + (right * 2); } uint64_t AddNumbersConst(uint64_t left, uint64_t right) const { return left + (right * 2); } }; } // namespace TEST(InvokeTest, Ok_Callable) { auto fn = [](int64_t a, int64_t b) { return (a + (b * 2)); }; std::array names = {"a", "b"}; MockDataSource mockSrc; EXPECT_CALL(mockSrc, GetKeys()).WillRepeatedly(Return(std::vector{"a", "b"})); EXPECT_CALL(mockSrc, Get("a", An())).WillRepeatedly(SetArgReferee<1>(42)); EXPECT_CALL(mockSrc, Get("b", An())).WillRepeatedly(SetArgReferee<1>(21)); flexible_value returnValue = bmrshared::invoke(fn, names, mockSrc); EXPECT_EQ(returnValue.as(), 84); } TEST(InvokeTest, Ok_Callable_LastArg) { auto fn = [](int64_t a, int64_t b, int64_t lastArg) { return ((lastArg * 4) + a + (b * 2)); }; std::array names = {"a", "b"}; MockDataSource mockSrc; EXPECT_CALL(mockSrc, GetKeys()).WillRepeatedly(Return(std::vector{"a", "b"})); EXPECT_CALL(mockSrc, Get("a", An())).WillRepeatedly(SetArgReferee<1>(42)); EXPECT_CALL(mockSrc, Get("b", An())).WillRepeatedly(SetArgReferee<1>(21)); flexible_value returnValue = bmrshared::invoke(fn, names, mockSrc, 1000); EXPECT_EQ(returnValue.as(), 4084); } TEST(InvokeTest, Ok_Ptr_Member) { std::array names = {"left", "right"}; MockDataSource mockSrc; EXPECT_CALL(mockSrc, GetKeys()).WillRepeatedly(Return(std::vector{"left", "right"})); EXPECT_CALL(mockSrc, Get("left", An())).WillRepeatedly(SetArgReferee<1>(100)); EXPECT_CALL(mockSrc, Get("right", An())).WillRepeatedly(SetArgReferee<1>(20)); TestAddition functor; flexible_value returnValue = bmrshared::invoke(functor, &TestAddition::AddNumbers, names, mockSrc); EXPECT_EQ(returnValue.as(), 140); } TEST(InvokeTest, Ok_Ptr_Const_Member_Const) { std::array names = {"left", "right"}; MockDataSource mockSrc; EXPECT_CALL(mockSrc, GetKeys()).WillRepeatedly(Return(std::vector{"left", "right"})); EXPECT_CALL(mockSrc, Get("left", An())).WillRepeatedly(SetArgReferee<1>(100)); EXPECT_CALL(mockSrc, Get("right", An())).WillRepeatedly(SetArgReferee<1>(20)); const TestAddition functor; flexible_value returnValue = bmrshared::invoke(functor, &TestAddition::AddNumbersConst, names, mockSrc); EXPECT_EQ(returnValue.as(), 140); } TEST(InvokeTest, Ok_Ptr_Member_Const) { std::array names = {"left", "right"}; MockDataSource mockSrc; EXPECT_CALL(mockSrc, GetKeys()).WillRepeatedly(Return(std::vector{"left", "right"})); EXPECT_CALL(mockSrc, Get("left", An())).WillRepeatedly(SetArgReferee<1>(100)); EXPECT_CALL(mockSrc, Get("right", An())).WillRepeatedly(SetArgReferee<1>(20)); TestAddition functor; flexible_value returnValue = bmrshared::invoke(functor, &TestAddition::AddNumbersConst, names, mockSrc); EXPECT_EQ(returnValue.as(), 140); } TEST(InvokeTest, Ok_ExtraArgumentByRefChanged) { auto fn = [](int64_t a, int64_t& lastArg) { lastArg = a; return true; }; std::array names = {"a"}; MockDataSource mockSrc; EXPECT_CALL(mockSrc, GetKeys()).WillRepeatedly(Return(std::vector{"a"})); EXPECT_CALL(mockSrc, Get("a", An())).WillRepeatedly(SetArgReferee<1>(42)); int64_t lastArg = 0; flexible_value returnValue = bmrshared::invoke(fn, names, mockSrc, lastArg); EXPECT_EQ(returnValue.as(), true); EXPECT_EQ(lastArg, 42); }