27 #define BOOST_OPTIONAL_CONFIG_ALLOW_BINDING_TO_RVALUES
31 #include <ableton/build_system/Warnings.hpp>
33 #include <boost/variant/static_visitor.hpp>
34 #include <boost/variant/apply_visitor.hpp>
35 #include <boost/optional.hpp>
37 #include <unordered_set>
58 void operator()(
const T&)
60 calls_.insert(
typeid(T));
64 template <
typename T = all_variants>
65 std::size_t count()
const
67 return calls_.count(
typeid(T));
70 template<
typename VariantT>
74 static_cast<void (*) (variant_spy&,
const VariantT&)
>(
75 &boost::apply_visitor<variant_spy, const VariantT>),
77 std::placeholders::_1))
80 std::unordered_multiset<
std::type_index> calls_;
88 template <
typename... Args>
89 T operator() (Args&&...) {
return T(); }
102 template <
typename... Args>
103 T operator() (Args&& ...) {
108 std::function<T()> mock_;
118 std::size_t count()
const
129 std::shared_ptr<std::size_t> count_ = std::make_shared<std::size_t>(0);
141 template<
typename MockT = mocks::defaulting<
void> >
149 template<
typename MockT2>
151 : mock_(std::move(mock))
154 template<
typename MockT2>
157 , mock_(std::move(mock))
160 template <
typename... Args>
161 auto operator() (Args&& ...args)
164 this->mock_(std::forward<Args>(args)...)))
170 template <
typename Fn>
171 inline auto spy(
const Fn& fn)
188 template <
typename MockT>
189 class scoped_intruder
191 boost::optional<MockT&> mock_;
195 scoped_intruder& operator=(
const scoped_intruder&) =
delete;
196 scoped_intruder(
const scoped_intruder&) =
delete;
198 scoped_intruder(scoped_intruder&& other)
203 scoped_intruder& operator=(scoped_intruder&& other)
211 scoped_intruder(MockT& mock, MockT replacement)
215 *mock_ = replacement;
226 template <
typename ...Args>
227 auto operator() (Args&& ...args)
228 -> decltype((*mock_)(std::forward<Args>(args)...))
230 assert(mock_ &&
"must not call intruder after having moved from it");
231 return (*mock_)(std::forward<Args>(args)...);
234 friend void swap(scoped_intruder& a, scoped_intruder& b)
237 swap(a.mock_, b.mock_);
238 swap(a.original_, b.original_);
249 template <
typename MockT>
254 return { detail::scoped_intruder<MockT>(mock, s), s };
262 template <
typename MockT,
typename FnT>
263 inline auto spy_on(MockT& mock,
const FnT& replacement)
266 auto s =
spy(replacement);
267 return { detail::scoped_intruder<MockT>(mock, s), s };
271 struct default_copy_spy_base_t {};
277 template <
typename BaseT = detail::default_copy_spy_base_t>
280 using base_t = BaseT;
297 base_t::operator=(x);
auto spy_on(MockT &mock) -> spy_fn< detail::scoped_intruder< MockT > >
Given a functor object mock of a general functor with type erasure (e.g.
#define ABL_DECLTYPE_RETURN(body_expr)
Utility for defining generic functions with a deduced return type, that are composed of a single expr...
Class for spying on functions that take a variant as a parameter.
Utility for testing how many times an object is copied.
Functor that counts the number of times it was called.
C++ amazing templates and reusable implementations awesomeness.
auto spy(const Fn &fn) -> spy_fn< Fn >
Returns a spy object that uses fn as mock implementation.