mock_overload_set.h 5.1 KB

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