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 <tuple> 20 #include <type_traits> 21 22 #include "gmock/gmock.h" 23 #include "absl/base/config.h" 24 #include "absl/random/internal/mock_helpers.h" 25 #include "absl/random/mocking_bit_gen.h" 26 27 namespace absl { 28 ABSL_NAMESPACE_BEGIN 29 namespace random_internal { 30 31 template <typename DistrT, typename ValidatorT, typename Fn> 32 struct MockSingleOverload; 33 34 // MockSingleOverload 35 // 36 // MockSingleOverload hooks in to gMock's `ON_CALL` and `EXPECT_CALL` macros. 37 // EXPECT_CALL(mock_single_overload, Call(...))` will expand to a call to 38 // `mock_single_overload.gmock_Call(...)`. Because expectations are stored on 39 // the MockingBitGen (an argument passed inside `Call(...)`), this forwards to 40 // arguments to MockingBitGen::Register. 41 // 42 // The underlying KeyT must match the KeyT constructed by DistributionCaller. 43 template <typename DistrT, typename ValidatorT, typename Ret, typename... Args> 44 struct MockSingleOverload<DistrT, ValidatorT, Ret(MockingBitGen&, Args...)> { 45 static_assert(std::is_same<typename DistrT::result_type, Ret>::value, 46 "Overload signature must have return type matching the " 47 "distribution result_type."); 48 using KeyT = Ret(DistrT, std::tuple<Args...>); 49 50 template <typename MockURBG> 51 auto gmock_Call(MockURBG& gen, const ::testing::Matcher<Args>&... matchers) 52 -> decltype(MockHelpers::MockFor<KeyT>(gen, ValidatorT()) 53 .gmock_Call(matchers...)) { 54 static_assert( 55 std::is_base_of<MockingBitGenImpl<true>, MockURBG>::value || 56 std::is_base_of<MockingBitGenImpl<false>, MockURBG>::value, 57 "Mocking requires an absl::MockingBitGen"); 58 return MockHelpers::MockFor<KeyT>(gen, ValidatorT()) 59 .gmock_Call(matchers...); 60 } 61 }; 62 63 template <typename DistrT, typename ValidatorT, typename Ret, typename Arg, 64 typename... Args> 65 struct MockSingleOverload<DistrT, ValidatorT, 66 Ret(Arg, MockingBitGen&, Args...)> { 67 static_assert(std::is_same<typename DistrT::result_type, Ret>::value, 68 "Overload signature must have return type matching the " 69 "distribution result_type."); 70 using KeyT = Ret(DistrT, std::tuple<Arg, Args...>); 71 72 template <typename MockURBG> 73 auto gmock_Call(const ::testing::Matcher<Arg>& matcher, MockURBG& gen, 74 const ::testing::Matcher<Args>&... matchers) 75 -> decltype(MockHelpers::MockFor<KeyT>(gen, ValidatorT()) 76 .gmock_Call(matcher, matchers...)) { 77 static_assert( 78 std::is_base_of<MockingBitGenImpl<true>, MockURBG>::value || 79 std::is_base_of<MockingBitGenImpl<false>, MockURBG>::value, 80 "Mocking requires an absl::MockingBitGen"); 81 return MockHelpers::MockFor<KeyT>(gen, ValidatorT()) 82 .gmock_Call(matcher, matchers...); 83 } 84 }; 85 86 // MockOverloadSetWithValidator 87 // 88 // MockOverloadSetWithValidator is a wrapper around MockOverloadSet which takes 89 // an additional Validator parameter, allowing for customization of the mock 90 // behavior. 91 // 92 // `ValidatorT::Validate(result, args...)` will be called after the mock 93 // distribution returns a value in `result`, allowing for validation against the 94 // args. 95 template <typename DistrT, typename ValidatorT, typename... Fns> 96 struct MockOverloadSetWithValidator; 97 98 template <typename DistrT, typename ValidatorT, typename Sig> 99 struct MockOverloadSetWithValidator<DistrT, ValidatorT, Sig> 100 : public MockSingleOverload<DistrT, ValidatorT, Sig> { 101 using MockSingleOverload<DistrT, ValidatorT, Sig>::gmock_Call; 102 }; 103 104 template <typename DistrT, typename ValidatorT, typename FirstSig, 105 typename... Rest> 106 struct MockOverloadSetWithValidator<DistrT, ValidatorT, FirstSig, Rest...> 107 : public MockSingleOverload<DistrT, ValidatorT, FirstSig>, 108 public MockOverloadSetWithValidator<DistrT, ValidatorT, Rest...> { 109 using MockSingleOverload<DistrT, ValidatorT, FirstSig>::gmock_Call; 110 using MockOverloadSetWithValidator<DistrT, ValidatorT, Rest...>::gmock_Call; 111 }; 112 113 // MockOverloadSet 114 // 115 // MockOverloadSet takes a distribution and a collection of signatures and 116 // performs overload resolution amongst all the overloads. This makes 117 // `EXPECT_CALL(mock_overload_set, Call(...))` expand and do overload resolution 118 // correctly. 119 template <typename DistrT, typename... Signatures> 120 using MockOverloadSet = 121 MockOverloadSetWithValidator<DistrT, NoOpValidator, Signatures...>; 122 123 } // namespace random_internal 124 ABSL_NAMESPACE_END 125 } // namespace absl 126 #endif // ABSL_RANDOM_INTERNAL_MOCK_OVERLOAD_SET_H_ 127