mimic++ v4
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 <ValueCategory category, Constness constness, typename Return, typename... Params>
19 class BasicMockFrontend
20 {
21 protected:
22 using ExpectationCollectionT = ExpectationCollection<Return(Params...)>;
23
24 [[nodiscard]]
25 explicit BasicMockFrontend(
26 std::shared_ptr<ExpectationCollectionT> collection
27 ) noexcept
28 : m_Expectations{std::move(collection)}
29 {
30 }
31
32 [[nodiscard]]
33 constexpr Return handle_call(
34 std::tuple<std::reference_wrapper<std::remove_reference_t<Params>>...> params,
35 const std::source_location& from
36 ) const
37 {
38 using CallInfoT = call::Info<Return, Params...>;
39
40 return m_Expectations->handle_call(
41 CallInfoT{
42 .args = std::move(params),
43 .fromCategory = category,
44 .fromConstness = constness,
45 .fromSourceLocation = from
46 });
47 }
48
49 template <typename... Args>
50 requires (... && requirement_for<Args, Params>)
51 [[nodiscard]]
52 constexpr auto make_expectation_builder(Args&&... args) const
53 {
54 return detail::make_expectation_builder(
55 m_Expectations,
56 std::forward<Args>(args)...)
57 && expectation_policies::Category<category>{}
58 && expectation_policies::Constness<constness>{};
59 }
60
61 private:
62 std::shared_ptr<ExpectationCollectionT> m_Expectations;
63 };
64
65 template <typename Signature>
66 class MockFrontend;
67
68 template <typename Return, typename... Params>
69 class MockFrontend<Return(Params...)>
70 : protected BasicMockFrontend<
71 ValueCategory::any,
72 Constness::non_const,
73 Return,
74 Params...>
75 {
76 using SuperT = BasicMockFrontend<
79 Return,
80 Params...>;
81
82 public:
83 using SignatureT = Return(Params...);
84
85 constexpr Return operator ()(Params... params, const std::source_location& from = std::source_location::current())
86 {
87 return SuperT::handle_call(
88 std::tuple{std::ref(params)...},
89 from);
90 }
91
92 template <typename... Args>
93 requires (... && requirement_for<Args, Params>)
94 [[nodiscard]]
95 constexpr auto expect_call(Args&&... args)
96 {
97 return SuperT::make_expectation_builder(
98 std::forward<Args>(args)...);
99 }
100
101 protected:
102 using SuperT::SuperT;
103 };
104
105 template <typename Return, typename... Params>
106 class MockFrontend<Return(Params...) const>
107 : protected BasicMockFrontend<
108 ValueCategory::any,
109 Constness::as_const,
110 Return,
111 Params...>
112 {
113 using SuperT = BasicMockFrontend<
116 Return,
117 Params...>;
118
119 public:
120 using SignatureT = Return(Params...) const;
121
122 constexpr Return operator ()(Params... params, const std::source_location& from = std::source_location::current()) const
123 {
124 return SuperT::handle_call(
125 std::tuple{std::ref(params)...},
126 from);
127 }
128
129 template <typename... Args>
130 requires (... && requirement_for<Args, Params>)
131 [[nodiscard]]
132 constexpr auto expect_call(Args&&... args) const
133 {
134 return SuperT::make_expectation_builder(
135 std::forward<Args>(args)...);
136 }
137
138 protected:
139 using SuperT::SuperT;
140 };
141
142 template <typename Return, typename... Params>
143 class MockFrontend<Return(Params...) &>
144 : protected BasicMockFrontend<
147 Return,
148 Params...>
149 {
150 using SuperT = BasicMockFrontend<
153 Return,
154 Params...>;
155
156 public:
157 using SignatureT = Return(Params...) &;
158
159 constexpr Return operator ()(Params... params, const std::source_location& from = std::source_location::current()) &
160 {
161 return SuperT::handle_call(
162 std::tuple{std::ref(params)...},
163 from);
164 }
165
166 template <typename... Args>
167 requires (... && requirement_for<Args, Params>)
168 [[nodiscard]]
169 constexpr auto expect_call(Args&&... args) &
170 {
171 return SuperT::make_expectation_builder(
172 std::forward<Args>(args)...);
173 }
174
175 protected:
176 using SuperT::SuperT;
177 };
178
179 template <typename Return, typename... Params>
180 class MockFrontend<Return(Params...) const &>
181 : protected BasicMockFrontend<
184 Return,
185 Params...>
186 {
187 using SuperT = BasicMockFrontend<
190 Return,
191 Params...>;
192
193 public:
194 using SignatureT = Return(Params...) const &;
195
196 constexpr Return operator ()(Params... params, const std::source_location& from = std::source_location::current()) const &
197 {
198 return SuperT::handle_call(
199 std::tuple{std::ref(params)...},
200 from);
201 }
202
203 template <typename... Args>
204 requires (... && requirement_for<Args, Params>)
205 [[nodiscard]]
206 constexpr auto expect_call(Args&&... args) const &
207 {
208 return SuperT::make_expectation_builder(
209 std::forward<Args>(args)...);
210 }
211
212 protected:
213 using SuperT::SuperT;
214 };
215
216 template <typename Return, typename... Params>
217 class MockFrontend<Return(Params...) &&>
218 : protected BasicMockFrontend<
221 Return,
222 Params...>
223 {
224 using SuperT = BasicMockFrontend<
227 Return,
228 Params...>;
229
230 public:
231 using SignatureT = Return(Params...) &&;
232
233 constexpr Return operator ()(Params... params, const std::source_location& from = std::source_location::current()) &&
234 {
235 return SuperT::handle_call(
236 std::tuple{std::ref(params)...},
237 from);
238 }
239
240 template <typename... Args>
241 requires (... && requirement_for<Args, Params>)
242 [[nodiscard]]
243 constexpr auto expect_call(Args&&... args) &&
244 {
245 return SuperT::make_expectation_builder(
246 std::forward<Args>(args)...);
247 }
248
249 protected:
250 using SuperT::SuperT;
251 };
252
253 template <typename Return, typename... Params>
254 class MockFrontend<Return(Params...) const &&>
255 : protected BasicMockFrontend<
258 Return,
259 Params...>
260 {
261 using SuperT = BasicMockFrontend<
264 Return,
265 Params...>;
266
267 public:
268 using SignatureT = Return(Params...) const &&;
269
270 constexpr Return operator ()(Params... params, const std::source_location& from = std::source_location::current()) const &&
271 {
272 return SuperT::handle_call(
273 std::tuple{std::ref(params)...},
274 from);
275 }
276
277 template <typename... Args>
278 requires (... && requirement_for<Args, Params>)
279 [[nodiscard]]
280 constexpr auto expect_call(Args&&... args) const &&
281 {
282 return SuperT::make_expectation_builder(
283 std::forward<Args>(args)...);
284 }
285
286 protected:
287 using SuperT::SuperT;
288 };
289
290 template <typename Return, typename... Params>
291 class MockFrontend<Return(Params...) noexcept>
292 : protected BasicMockFrontend<
293 ValueCategory::any,
294 Constness::non_const,
295 Return,
296 Params...>
297 {
298 using SuperT = BasicMockFrontend<
301 Return,
302 Params...>;
303
304 public:
305 using SignatureT = Return(Params...) noexcept;
306
307 constexpr Return operator ()(Params... params, const std::source_location& from = std::source_location::current()) noexcept
308 {
309 return SuperT::handle_call(
310 std::tuple{std::ref(params)...},
311 from);
312 }
313
314 template <typename... Args>
315 requires (... && requirement_for<Args, Params>)
316 [[nodiscard]]
317 constexpr auto expect_call(Args&&... args)
318 {
319 return SuperT::make_expectation_builder(
320 std::forward<Args>(args)...);
321 }
322
323 protected:
324 using SuperT::SuperT;
325 };
326
327 template <typename Return, typename... Params>
328 class MockFrontend<Return(Params...) const noexcept>
329 : protected BasicMockFrontend<
330 ValueCategory::any,
331 Constness::as_const,
332 Return,
333 Params...>
334 {
335 using SuperT = BasicMockFrontend<
338 Return,
339 Params...>;
340
341 public:
342 using SignatureT = Return(Params...) const noexcept;
343
344 constexpr Return operator ()(
345 Params... params,
346 const std::source_location& from = std::source_location::current()
347 ) const noexcept
348 {
349 return SuperT::handle_call(
350 std::tuple{std::ref(params)...},
351 from);
352 }
353
354 template <typename... Args>
355 requires (... && requirement_for<Args, Params>)
356 [[nodiscard]]
357 constexpr auto expect_call(Args&&... args) const
358 {
359 return SuperT::make_expectation_builder(
360 std::forward<Args>(args)...);
361 }
362
363 protected:
364 using SuperT::SuperT;
365 };
366
367 template <typename Return, typename... Params>
368 class MockFrontend<Return(Params...) & noexcept>
369 : protected BasicMockFrontend<
372 Return,
373 Params...>
374 {
375 using SuperT = BasicMockFrontend<
378 Return,
379 Params...>;
380
381 public:
382 using SignatureT = Return(Params...) & noexcept;
383
384 constexpr Return operator ()(Params... params, const std::source_location& from = std::source_location::current()) & noexcept
385 {
386 return SuperT::handle_call(
387 std::tuple{std::ref(params)...},
388 from);
389 }
390
391 template <typename... Args>
392 requires (... && requirement_for<Args, Params>)
393 [[nodiscard]]
394 constexpr auto expect_call(Args&&... args) &
395 {
396 return SuperT::make_expectation_builder(
397 std::forward<Args>(args)...);
398 }
399
400 protected:
401 using SuperT::SuperT;
402 };
403
404 template <typename Return, typename... Params>
405 class MockFrontend<Return(Params...) const & noexcept>
406 : protected BasicMockFrontend<
409 Return,
410 Params...>
411 {
412 using SuperT = BasicMockFrontend<
415 Return,
416 Params...>;
417
418 public:
419 using SignatureT = Return(Params...) const & noexcept;
420
421 constexpr Return operator ()(
422 Params... params,
423 const std::source_location& from = std::source_location::current()
424 ) const & noexcept
425 {
426 return SuperT::handle_call(
427 std::tuple{std::ref(params)...},
428 from);
429 }
430
431 template <typename... Args>
432 requires (... && requirement_for<Args, Params>)
433 [[nodiscard]]
434 constexpr auto expect_call(Args&&... args) const &
435 {
436 return SuperT::make_expectation_builder(
437 std::forward<Args>(args)...);
438 }
439
440 protected:
441 using SuperT::SuperT;
442 };
443
444 template <typename Return, typename... Params>
445 class MockFrontend<Return(Params...) && noexcept>
446 : protected BasicMockFrontend<
449 Return,
450 Params...>
451 {
452 using SuperT = BasicMockFrontend<
455 Return,
456 Params...>;
457
458 public:
459 using SignatureT = Return(Params...) && noexcept;
460
461 constexpr Return operator ()(Params... params, const std::source_location& from = std::source_location::current()) && noexcept
462 {
463 return SuperT::handle_call(
464 std::tuple{std::ref(params)...},
465 from);
466 }
467
468 template <typename... Args>
469 requires (... && requirement_for<Args, Params>)
470 [[nodiscard]]
471 constexpr auto expect_call(Args&&... args) &&
472 {
473 return SuperT::make_expectation_builder(
474 std::forward<Args>(args)...);
475 }
476
477 protected:
478 using SuperT::SuperT;
479 };
480
481 template <typename Return, typename... Params>
482 class MockFrontend<Return(Params...) const && noexcept>
483 : protected BasicMockFrontend<
486 Return,
487 Params...>
488 {
489 using SuperT = BasicMockFrontend<
492 Return,
493 Params...>;
494
495 public:
496 using SignatureT = Return(Params...) const && noexcept;
497
498 constexpr Return operator ()(
499 Params... params,
500 const std::source_location& from = std::source_location::current()
501 ) const && noexcept
502 {
503 return SuperT::handle_call(
504 std::tuple{std::ref(params)...},
505 from);
506 }
507
508 template <typename... Args>
509 requires (... && requirement_for<Args, Params>)
510 [[nodiscard]]
511 constexpr auto expect_call(Args&&... args) const &&
512 {
513 return SuperT::make_expectation_builder(
514 std::forward<Args>(args)...);
515 }
516
517 protected:
518 using SuperT::SuperT;
519 };
520
521 template <typename List>
522 struct expectation_collection_factory;
523
524 template <typename... UniqueSignatures>
525 struct expectation_collection_factory<std::tuple<UniqueSignatures...>>
526 {
527 [[nodiscard]]
528 static auto make()
529 {
530 return std::tuple{
531 std::make_shared<ExpectationCollection<UniqueSignatures>>()...
532 };
533 }
534 };
535}
536
537namespace mimicpp
538{
595 template <typename FirstSignature, typename... OtherSignatures>
596 requires is_overload_set_v<FirstSignature, OtherSignatures...>
597 class Mock
598 : public detail::MockFrontend<FirstSignature>,
599 public detail::MockFrontend<OtherSignatures>...
600 {
601 public:
602 using detail::MockFrontend<FirstSignature>::operator();
603 using detail::MockFrontend<FirstSignature>::expect_call;
604 using detail::MockFrontend<OtherSignatures>::operator()...;
605 using detail::MockFrontend<OtherSignatures>::expect_call...;
606
610 ~Mock() = default;
611
615 [[nodiscard]]
617 : Mock{
618 detail::expectation_collection_factory<
619 detail::unique_list_t<
620 signature_decay_t<FirstSignature>,
621 signature_decay_t<OtherSignatures>...>>::make()
622 }
623 {
624 }
625
629 Mock(const Mock&) = delete;
630
634 Mock& operator =(const Mock&) = delete;
635
639 [[nodiscard]]
640 Mock(Mock&&) = default;
641
645 Mock& operator =(Mock&&) = default;
646
647 private:
648 template <typename... Collections>
649 explicit Mock(std::tuple<Collections...> collections)
650 : detail::MockFrontend<FirstSignature>{
651 std::get<std::shared_ptr<ExpectationCollection<signature_decay_t<FirstSignature>>>>(collections)
652 },
653 detail::MockFrontend<OtherSignatures>{
654 std::get<std::shared_ptr<ExpectationCollection<signature_decay_t<OtherSignatures>>>>(collections)
655 }...
656 {
657 }
658 };
659
663}
664
665#endif
A Mock type, which fully supports overload sets.
Definition Mock.hpp:600
~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:616
constexpr bool is_overload_set_v
Convenience constant, exposing the value member of the actual type-trait.
Definition Fwd.hpp:146
typename signature_decay< Signature >::type signature_decay_t
Convenience alias, exposing the type member alias of the actual type-trait.
Definition Fwd.hpp:68
Definition BoostTest.hpp:20
ValueCategory
Definition Fwd.hpp:195
Constness
Definition Fwd.hpp:188