1 // 2 // Copyright 2019 The Abseil Authors. 3 // 4 // Licensed under the Apache License, Version 2.0 (the "License"); 5 // you may not use this file except in compliance with the License. 6 // You may obtain a copy of the License at 7 // 8 // https://www.apache.org/licenses/LICENSE-2.0 9 // 10 // Unless required by applicable law or agreed to in writing, software 11 // distributed under the License is distributed on an "AS IS" BASIS, 12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 // See the License for the specific language governing permissions and 14 // limitations under the License. 15 16 #ifndef ABSL_RANDOM_INTERNAL_MOCK_OVERLOAD_SET_H_ 17 #define ABSL_RANDOM_INTERNAL_MOCK_OVERLOAD_SET_H_ 18 19 #include <type_traits> 20 21 #include "gmock/gmock.h" 22 #include "gtest/gtest.h" 23 #include "absl/random/internal/mock_helpers.h" 24 #include "absl/random/mocking_bit_gen.h" 25 26 namespace absl { 27 ABSL_NAMESPACE_BEGIN 28 namespace random_internal { 29 30 template <typename DistrT, typename Fn> 31 struct MockSingleOverload; 32 33 // MockSingleOverload 34 // 35 // MockSingleOverload hooks in to gMock's `ON_CALL` and `EXPECT_CALL` macros. 36 // EXPECT_CALL(mock_single_overload, Call(...))` will expand to a call to 37 // `mock_single_overload.gmock_Call(...)`. Because expectations are stored on 38 // the MockingBitGen (an argument passed inside `Call(...)`), this forwards to 39 // arguments to MockingBitGen::Register. 40 // 41 // The underlying KeyT must match the KeyT constructed by DistributionCaller. 42 template <typename DistrT, typename Ret, typename... Args> 43 struct MockSingleOverload<DistrT, Ret(MockingBitGen&, Args...)> { 44 static_assert(std::is_same<typename DistrT::result_type, Ret>::value, 45 "Overload signature must have return type matching the " 46 "distribution result_type."); 47 using KeyT = Ret(DistrT, std::tuple<Args...>); 48 auto gmock_Call( 49 absl::MockingBitGen& gen, // NOLINT(google-runtime-references) 50 const ::testing::Matcher<Args>&... matchers) 51 -> decltype(MockHelpers::MockFor<KeyT>(gen).gmock_Call(matchers...)) { 52 return MockHelpers::MockFor<KeyT>(gen).gmock_Call(matchers...); 53 } 54 }; 55 56 template <typename DistrT, typename Ret, typename Arg, typename... Args> 57 struct MockSingleOverload<DistrT, Ret(Arg, MockingBitGen&, Args...)> { 58 static_assert(std::is_same<typename DistrT::result_type, Ret>::value, 59 "Overload signature must have return type matching the " 60 "distribution result_type."); 61 using KeyT = Ret(DistrT, std::tuple<Arg, Args...>); 62 auto gmock_Call( 63 const ::testing::Matcher<Arg>& matcher, 64 absl::MockingBitGen& gen, // NOLINT(google-runtime-references) 65 const ::testing::Matcher<Args>&... matchers) 66 -> decltype(MockHelpers::MockFor<KeyT>(gen).gmock_Call(matcher, 67 matchers...)) { 68 return MockHelpers::MockFor<KeyT>(gen).gmock_Call(matcher, matchers...); 69 } 70 }; 71 72 // MockOverloadSet 73 // 74 // MockOverloadSet takes a distribution and a collection of signatures and 75 // performs overload resolution amongst all the overloads. This makes 76 // `EXPECT_CALL(mock_overload_set, Call(...))` expand and do overload resolution 77 // correctly. 78 template <typename DistrT, typename... Signatures> 79 struct MockOverloadSet; 80 81 template <typename DistrT, typename Sig> 82 struct MockOverloadSet<DistrT, Sig> : public MockSingleOverload<DistrT, Sig> { 83 using MockSingleOverload<DistrT, Sig>::gmock_Call; 84 }; 85 86 template <typename DistrT, typename FirstSig, typename... Rest> 87 struct MockOverloadSet<DistrT, FirstSig, Rest...> 88 : public MockSingleOverload<DistrT, FirstSig>, 89 public MockOverloadSet<DistrT, Rest...> { 90 using MockSingleOverload<DistrT, FirstSig>::gmock_Call; 91 using MockOverloadSet<DistrT, Rest...>::gmock_Call; 92 }; 93 94 } // namespace random_internal 95 ABSL_NAMESPACE_END 96 } // namespace absl 97 #endif // ABSL_RANDOM_INTERNAL_MOCK_OVERLOAD_SET_H_ 98