mock_overload_set.h 4.9 KB

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