mimic++ v2
Loading...
Searching...
No Matches
Mock.hpp
Go to the documentation of this file.
1// // Copyright Dominic (DNKpp) Koepke 2024 - 2024.
2// // Distributed under the Boost Software License, Version 1.0.
3// // (See accompanying file LICENSE_1_0.txt or copy at
4// // https://www.boost.org/LICENSE_1_0.txt)
5
6#ifndef MIMICPP_MOCK_HPP
7#define MIMICPP_MOCK_HPP
8
9#pragma once
10
14#include "mimic++/Utility.hpp"
15
16namespace mimicpp::detail
17{
18 template <typename T, typename Target>
19 concept requirement_for = std::equality_comparable_with<T, Target>
20 || matcher_for<std::remove_cvref_t<T>, Target>;
21
22 template <ValueCategory category, Constness constness, typename Return, typename... Params>
23 class BasicMockFrontend
24 {
25 protected:
26 using ExpectationCollectionT = ExpectationCollection<Return(Params...)>;
27
28 [[nodiscard]]
29 explicit BasicMockFrontend(
30 std::shared_ptr<ExpectationCollectionT> collection
31 ) noexcept
32 : m_Expectations{std::move(collection)}
33 {
34 }
35
36 [[nodiscard]]
37 constexpr Return handle_call(
38 std::tuple<std::reference_wrapper<std::remove_reference_t<Params>>...> params,
39 const std::source_location& from
40 ) const
41 {
42 using CallInfoT = call::Info<Return, Params...>;
43
44 return m_Expectations->handle_call(
45 CallInfoT{
46 .args = std::move(params),
47 .fromCategory = category,
48 .fromConstness = constness,
49 .fromSourceLocation = from
50 });
51 }
52
53 template <typename... Args>
54 requires (... && requirement_for<Args, Params>)
55 [[nodiscard]]
56 constexpr auto make_expectation_builder(Args&&... args) const
57 {
58 return detail::make_expectation_builder(
59 m_Expectations,
60 std::forward<Args>(args)...)
61 && expectation_policies::Category<category>{}
62 && expectation_policies::Constness<constness>{};
63 }
64
65 private:
66 std::shared_ptr<ExpectationCollectionT> m_Expectations;
67 };
68
69 template <typename Signature>
70 class MockFrontend;
71
72 template <typename Return, typename... Params>
73 class MockFrontend<Return(Params...)>
74 : protected BasicMockFrontend<
75 ValueCategory::any,
76 Constness::non_const,
77 Return,
78 Params...>
79 {
80 using SuperT = BasicMockFrontend<
83 Return,
84 Params...>;
85
86 public:
87 using SignatureT = Return(Params...);
88
89 constexpr Return operator ()(Params... params, const std::source_location& from = std::source_location::current())
90 {
91 return SuperT::handle_call(
92 std::tuple{std::ref(params)...},
93 from);
94 }
95
96 template <typename... Args>
97 requires (... && requirement_for<Args, Params>)
98 [[nodiscard]]
99 constexpr auto expect_call(Args&&... args)
100 {
101 return SuperT::make_expectation_builder(
102 std::forward<Args>(args)...);
103 }
104
105 protected:
106 using SuperT::SuperT;
107 };
108
109 template <typename Return, typename... Params>
110 class MockFrontend<Return(Params...) const>
111 : protected BasicMockFrontend<
112 ValueCategory::any,
113 Constness::as_const,
114 Return,
115 Params...>
116 {
117 using SuperT = BasicMockFrontend<
120 Return,
121 Params...>;
122
123 public:
124 using SignatureT = Return(Params...) const;
125
126 constexpr Return operator ()(Params... params, const std::source_location& from = std::source_location::current()) const
127 {
128 return SuperT::handle_call(
129 std::tuple{std::ref(params)...},
130 from);
131 }
132
133 template <typename... Args>
134 requires (... && requirement_for<Args, Params>)
135 [[nodiscard]]
136 constexpr auto expect_call(Args&&... args) const
137 {
138 return SuperT::make_expectation_builder(
139 std::forward<Args>(args)...);
140 }
141
142 protected:
143 using SuperT::SuperT;
144 };
145
146 template <typename Return, typename... Params>
147 class MockFrontend<Return(Params...) &>
148 : protected BasicMockFrontend<
151 Return,
152 Params...>
153 {
154 using SuperT = BasicMockFrontend<
157 Return,
158 Params...>;
159
160 public:
161 using SignatureT = Return(Params...) &;
162
163 constexpr Return operator ()(Params... params, const std::source_location& from = std::source_location::current()) &
164 {
165 return SuperT::handle_call(
166 std::tuple{std::ref(params)...},
167 from);
168 }
169
170 template <typename... Args>
171 requires (... && requirement_for<Args, Params>)
172 [[nodiscard]]
173 constexpr auto expect_call(Args&&... args) &
174 {
175 return SuperT::make_expectation_builder(
176 std::forward<Args>(args)...);
177 }
178
179 protected:
180 using SuperT::SuperT;
181 };
182
183 template <typename Return, typename... Params>
184 class MockFrontend<Return(Params...) const &>
185 : protected BasicMockFrontend<
188 Return,
189 Params...>
190 {
191 using SuperT = BasicMockFrontend<
194 Return,
195 Params...>;
196
197 public:
198 using SignatureT = Return(Params...) const &;
199
200 constexpr Return operator ()(Params... params, const std::source_location& from = std::source_location::current()) const &
201 {
202 return SuperT::handle_call(
203 std::tuple{std::ref(params)...},
204 from);
205 }
206
207 template <typename... Args>
208 requires (... && requirement_for<Args, Params>)
209 [[nodiscard]]
210 constexpr auto expect_call(Args&&... args) const &
211 {
212 return SuperT::make_expectation_builder(
213 std::forward<Args>(args)...);
214 }
215
216 protected:
217 using SuperT::SuperT;
218 };
219
220 template <typename Return, typename... Params>
221 class MockFrontend<Return(Params...) &&>
222 : protected BasicMockFrontend<
225 Return,
226 Params...>
227 {
228 using SuperT = BasicMockFrontend<
231 Return,
232 Params...>;
233
234 public:
235 using SignatureT = Return(Params...) &&;
236
237 constexpr Return operator ()(Params... params, const std::source_location& from = std::source_location::current()) &&
238 {
239 return SuperT::handle_call(
240 std::tuple{std::ref(params)...},
241 from);
242 }
243
244 template <typename... Args>
245 requires (... && requirement_for<Args, Params>)
246 [[nodiscard]]
247 constexpr auto expect_call(Args&&... args) &&
248 {
249 return SuperT::make_expectation_builder(
250 std::forward<Args>(args)...);
251 }
252
253 protected:
254 using SuperT::SuperT;
255 };
256
257 template <typename Return, typename... Params>
258 class MockFrontend<Return(Params...) const &&>
259 : protected BasicMockFrontend<
262 Return,
263 Params...>
264 {
265 using SuperT = BasicMockFrontend<
268 Return,
269 Params...>;
270
271 public:
272 using SignatureT = Return(Params...) const &&;
273
274 constexpr Return operator ()(Params... params, const std::source_location& from = std::source_location::current()) const &&
275 {
276 return SuperT::handle_call(
277 std::tuple{std::ref(params)...},
278 from);
279 }
280
281 template <typename... Args>
282 requires (... && requirement_for<Args, Params>)
283 [[nodiscard]]
284 constexpr auto expect_call(Args&&... args) const &&
285 {
286 return SuperT::make_expectation_builder(
287 std::forward<Args>(args)...);
288 }
289
290 protected:
291 using SuperT::SuperT;
292 };
293
294 template <typename Return, typename... Params>
295 class MockFrontend<Return(Params...) noexcept>
296 : protected BasicMockFrontend<
297 ValueCategory::any,
298 Constness::non_const,
299 Return,
300 Params...>
301 {
302 using SuperT = BasicMockFrontend<
305 Return,
306 Params...>;
307
308 public:
309 using SignatureT = Return(Params...) noexcept;
310
311 constexpr Return operator ()(Params... params, const std::source_location& from = std::source_location::current()) noexcept
312 {
313 return SuperT::handle_call(
314 std::tuple{std::ref(params)...},
315 from);
316 }
317
318 template <typename... Args>
319 requires (... && requirement_for<Args, Params>)
320 [[nodiscard]]
321 constexpr auto expect_call(Args&&... args)
322 {
323 return SuperT::make_expectation_builder(
324 std::forward<Args>(args)...);
325 }
326
327 protected:
328 using SuperT::SuperT;
329 };
330
331 template <typename Return, typename... Params>
332 class MockFrontend<Return(Params...) const noexcept>
333 : protected BasicMockFrontend<
334 ValueCategory::any,
335 Constness::as_const,
336 Return,
337 Params...>
338 {
339 using SuperT = BasicMockFrontend<
342 Return,
343 Params...>;
344
345 public:
346 using SignatureT = Return(Params...) const noexcept;
347
348 constexpr Return operator ()(
349 Params... params,
350 const std::source_location& from = std::source_location::current()
351 ) const noexcept
352 {
353 return SuperT::handle_call(
354 std::tuple{std::ref(params)...},
355 from);
356 }
357
358 template <typename... Args>
359 requires (... && requirement_for<Args, Params>)
360 [[nodiscard]]
361 constexpr auto expect_call(Args&&... args) const
362 {
363 return SuperT::make_expectation_builder(
364 std::forward<Args>(args)...);
365 }
366
367 protected:
368 using SuperT::SuperT;
369 };
370
371 template <typename Return, typename... Params>
372 class MockFrontend<Return(Params...) & noexcept>
373 : protected BasicMockFrontend<
376 Return,
377 Params...>
378 {
379 using SuperT = BasicMockFrontend<
382 Return,
383 Params...>;
384
385 public:
386 using SignatureT = Return(Params...) & noexcept;
387
388 constexpr Return operator ()(Params... params, const std::source_location& from = std::source_location::current()) & noexcept
389 {
390 return SuperT::handle_call(
391 std::tuple{std::ref(params)...},
392 from);
393 }
394
395 template <typename... Args>
396 requires (... && requirement_for<Args, Params>)
397 [[nodiscard]]
398 constexpr auto expect_call(Args&&... args) &
399 {
400 return SuperT::make_expectation_builder(
401 std::forward<Args>(args)...);
402 }
403
404 protected:
405 using SuperT::SuperT;
406 };
407
408 template <typename Return, typename... Params>
409 class MockFrontend<Return(Params...) const & noexcept>
410 : protected BasicMockFrontend<
413 Return,
414 Params...>
415 {
416 using SuperT = BasicMockFrontend<
419 Return,
420 Params...>;
421
422 public:
423 using SignatureT = Return(Params...) const & noexcept;
424
425 constexpr Return operator ()(
426 Params... params,
427 const std::source_location& from = std::source_location::current()
428 ) const & noexcept
429 {
430 return SuperT::handle_call(
431 std::tuple{std::ref(params)...},
432 from);
433 }
434
435 template <typename... Args>
436 requires (... && requirement_for<Args, Params>)
437 [[nodiscard]]
438 constexpr auto expect_call(Args&&... args) const &
439 {
440 return SuperT::make_expectation_builder(
441 std::forward<Args>(args)...);
442 }
443
444 protected:
445 using SuperT::SuperT;
446 };
447
448 template <typename Return, typename... Params>
449 class MockFrontend<Return(Params...) && noexcept>
450 : protected BasicMockFrontend<
453 Return,
454 Params...>
455 {
456 using SuperT = BasicMockFrontend<
459 Return,
460 Params...>;
461
462 public:
463 using SignatureT = Return(Params...) && noexcept;
464
465 constexpr Return operator ()(Params... params, const std::source_location& from = std::source_location::current()) && noexcept
466 {
467 return SuperT::handle_call(
468 std::tuple{std::ref(params)...},
469 from);
470 }
471
472 template <typename... Args>
473 requires (... && requirement_for<Args, Params>)
474 [[nodiscard]]
475 constexpr auto expect_call(Args&&... args) &&
476 {
477 return SuperT::make_expectation_builder(
478 std::forward<Args>(args)...);
479 }
480
481 protected:
482 using SuperT::SuperT;
483 };
484
485 template <typename Return, typename... Params>
486 class MockFrontend<Return(Params...) const && noexcept>
487 : protected BasicMockFrontend<
490 Return,
491 Params...>
492 {
493 using SuperT = BasicMockFrontend<
496 Return,
497 Params...>;
498
499 public:
500 using SignatureT = Return(Params...) const && noexcept;
501
502 constexpr Return operator ()(
503 Params... params,
504 const std::source_location& from = std::source_location::current()
505 ) const && noexcept
506 {
507 return SuperT::handle_call(
508 std::tuple{std::ref(params)...},
509 from);
510 }
511
512 template <typename... Args>
513 requires (... && requirement_for<Args, Params>)
514 [[nodiscard]]
515 constexpr auto expect_call(Args&&... args) const &&
516 {
517 return SuperT::make_expectation_builder(
518 std::forward<Args>(args)...);
519 }
520
521 protected:
522 using SuperT::SuperT;
523 };
524
525 template <typename List>
526 struct expectation_collection_factory;
527
528 template <typename... UniqueSignatures>
529 struct expectation_collection_factory<std::tuple<UniqueSignatures...>>
530 {
531 [[nodiscard]]
532 static auto make()
533 {
534 return std::tuple{
535 std::make_shared<ExpectationCollection<UniqueSignatures>>()...
536 };
537 }
538 };
539}
540
541namespace mimicpp
542{
599 template <typename FirstSignature, typename... OtherSignatures>
600 requires is_overload_set_v<FirstSignature, OtherSignatures...>
601 class Mock
602 : public detail::MockFrontend<FirstSignature>,
603 public detail::MockFrontend<OtherSignatures>...
604 {
605 public:
606 using detail::MockFrontend<FirstSignature>::operator();
607 using detail::MockFrontend<FirstSignature>::expect_call;
608 using detail::MockFrontend<OtherSignatures>::operator()...;
609 using detail::MockFrontend<OtherSignatures>::expect_call...;
610
614 ~Mock() = default;
615
619 [[nodiscard]]
621 : Mock{
622 detail::expectation_collection_factory<
623 detail::unique_list_t<
624 signature_decay_t<FirstSignature>,
625 signature_decay_t<OtherSignatures>...>>::make()
626 }
627 {
628 }
629
633 Mock(const Mock&) = delete;
634
638 Mock& operator =(const Mock&) = delete;
639
643 [[nodiscard]]
644 Mock(Mock&&) = default;
645
649 Mock& operator =(Mock&&) = default;
650
651 private:
652 template <typename... Collections>
653 explicit Mock(std::tuple<Collections...> collections)
654 : detail::MockFrontend<FirstSignature>{
655 std::get<std::shared_ptr<ExpectationCollection<signature_decay_t<FirstSignature>>>>(collections)
656 },
657 detail::MockFrontend<OtherSignatures>{
658 std::get<std::shared_ptr<ExpectationCollection<signature_decay_t<OtherSignatures>>>>(collections)
659 }...
660 {
661 }
662 };
663
667}
668
669#endif
A Mock type, which fully supports overload sets.
Definition Mock.hpp:604
~Mock()=default
Defaulted destructor.
Mock(Mock &&)=default
Defaulted move constructor.
Mock(const Mock &)=delete
Deleted copy constructor.
Mock & operator=(const Mock &)=delete
Deleted copy assignment operator.
Mock()
Default constructor.
Definition Mock.hpp:620
Definition BoostTest.hpp:20
constexpr bool is_overload_set_v
Definition Fwd.hpp:67
ValueCategory
Definition Fwd.hpp:100
Constness
Definition Fwd.hpp:93
typename signature_decay< Signature >::type signature_decay_t
Definition Fwd.hpp:37