mock_overload_set.h (5055B)
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(std::is_base_of<MockingBitGen, MockURBG>::value, 55 "Mocking requires an absl::MockingBitGen"); 56 return MockHelpers::MockFor<KeyT>(gen, ValidatorT()) 57 .gmock_Call(matchers...); 58 } 59 }; 60 61 template <typename DistrT, typename ValidatorT, typename Ret, typename Arg, 62 typename... Args> 63 struct MockSingleOverload<DistrT, ValidatorT, 64 Ret(Arg, MockingBitGen&, Args...)> { 65 static_assert(std::is_same<typename DistrT::result_type, Ret>::value, 66 "Overload signature must have return type matching the " 67 "distribution result_type."); 68 using KeyT = Ret(DistrT, std::tuple<Arg, Args...>); 69 70 template <typename MockURBG> 71 auto gmock_Call(const ::testing::Matcher<Arg>& matcher, MockURBG& gen, 72 const ::testing::Matcher<Args>&... matchers) 73 -> decltype(MockHelpers::MockFor<KeyT>(gen, ValidatorT()) 74 .gmock_Call(matcher, matchers...)) { 75 static_assert(std::is_base_of<MockingBitGen, MockURBG>::value, 76 "Mocking requires an absl::MockingBitGen"); 77 return MockHelpers::MockFor<KeyT>(gen, ValidatorT()) 78 .gmock_Call(matcher, matchers...); 79 } 80 }; 81 82 // MockOverloadSetWithValidator 83 // 84 // MockOverloadSetWithValidator is a wrapper around MockOverloadSet which takes 85 // an additional Validator parameter, allowing for customization of the mock 86 // behavior. 87 // 88 // `ValidatorT::Validate(result, args...)` will be called after the mock 89 // distribution returns a value in `result`, allowing for validation against the 90 // args. 91 template <typename DistrT, typename ValidatorT, typename... Fns> 92 struct MockOverloadSetWithValidator; 93 94 template <typename DistrT, typename ValidatorT, typename Sig> 95 struct MockOverloadSetWithValidator<DistrT, ValidatorT, Sig> 96 : public MockSingleOverload<DistrT, ValidatorT, Sig> { 97 using MockSingleOverload<DistrT, ValidatorT, Sig>::gmock_Call; 98 }; 99 100 template <typename DistrT, typename ValidatorT, typename FirstSig, 101 typename... Rest> 102 struct MockOverloadSetWithValidator<DistrT, ValidatorT, FirstSig, Rest...> 103 : public MockSingleOverload<DistrT, ValidatorT, FirstSig>, 104 public MockOverloadSetWithValidator<DistrT, ValidatorT, Rest...> { 105 using MockSingleOverload<DistrT, ValidatorT, FirstSig>::gmock_Call; 106 using MockOverloadSetWithValidator<DistrT, ValidatorT, Rest...>::gmock_Call; 107 }; 108 109 // MockOverloadSet 110 // 111 // MockOverloadSet takes a distribution and a collection of signatures and 112 // performs overload resolution amongst all the overloads. This makes 113 // `EXPECT_CALL(mock_overload_set, Call(...))` expand and do overload resolution 114 // correctly. 115 template <typename DistrT, typename... Signatures> 116 using MockOverloadSet = 117 MockOverloadSetWithValidator<DistrT, NoOpValidator, Signatures...>; 118 119 } // namespace random_internal 120 ABSL_NAMESPACE_END 121 } // namespace absl 122 #endif // ABSL_RANDOM_INTERNAL_MOCK_OVERLOAD_SET_H_