mimic++ v6
Loading...
Searching...
No Matches
ExpectationBuilder.hpp
Go to the documentation of this file.
1// Copyright Dominic (DNKpp) Koepke 2024 - 2025.
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_EXPECTATION_BUILDER_HPP
7#define MIMICPP_EXPECTATION_BUILDER_HPP
8
9#pragma once
10
12#include "mimic++/Sequence.hpp"
19
20namespace mimicpp
21{
22 template <
23 bool timesConfigured,
24 typename SequenceConfig,
25 typename Signature,
26 typename FinalizePolicy,
29 {
30 public:
32 using PolicyListT = std::tuple<Policies...>;
34
36
37 template <typename FinalizePolicyArg, typename PolicyListArg>
38 requires std::constructible_from<FinalizePolicy, FinalizePolicyArg>
39 && std::constructible_from<PolicyListT, PolicyListArg>
40 [[nodiscard]]
41 explicit constexpr BasicExpectationBuilder(
42 std::shared_ptr<StorageT> storage,
43 detail::TimesConfig timesConfig,
44 SequenceConfig sequenceConfig,
45 FinalizePolicyArg&& finalizePolicyArg,
46 PolicyListArg&& policyListArg) noexcept
47 : m_Storage{std::move(storage)},
48 m_TimesConfig{std::move(timesConfig)},
49 m_SequenceConfig{std::move(sequenceConfig)},
50 m_FinalizePolicy{std::forward<FinalizePolicyArg>(finalizePolicyArg)},
51 m_ExpectationPolicies{std::forward<PolicyListArg>(policyListArg)}
52 {
53 assert(m_Storage && "Storage is nullptr.");
54 }
55
58
59 [[nodiscard]]
62
63 template <typename Policy>
64 requires std::same_as<expectation_policies::InitFinalize, FinalizePolicy>
65 && (!std::same_as<expectation_policies::InitFinalize, std::remove_cvref_t<Policy>>)
66 && finalize_policy_for<std::remove_cvref_t<Policy>, Signature>
67 [[nodiscard]]
68 friend constexpr auto operator&&(BasicExpectationBuilder&& builder, Policy&& policy)
69 {
70 using ExtendedExpectationBuilderT = BasicExpectationBuilder<
71 timesConfigured,
72 SequenceConfig,
73 Signature,
74 std::remove_cvref_t<Policy>,
75 Policies...>;
76
77 return ExtendedExpectationBuilderT{
78 std::move(builder.m_Storage),
79 std::move(builder.m_TimesConfig),
80 std::move(builder.m_SequenceConfig),
81 std::forward<Policy>(policy),
82 std::move(builder.m_ExpectationPolicies)};
83 }
84
85 template <typename Policy>
87 [[nodiscard]]
88 friend constexpr auto operator&&(BasicExpectationBuilder&& builder, Policy&& policy)
89 {
90 using ExtendedExpectationBuilderT = BasicExpectationBuilder<
91 timesConfigured,
92 SequenceConfig,
93 Signature,
94 FinalizePolicy,
95 Policies...,
96 std::remove_cvref_t<Policy>>;
97
98 return ExtendedExpectationBuilderT{
99 std::move(builder.m_Storage),
100 std::move(builder.m_TimesConfig),
101 std::move(builder.m_SequenceConfig),
102 std::move(builder.m_FinalizePolicy),
103 std::tuple_cat(
104 std::move(builder.m_ExpectationPolicies),
105 std::forward_as_tuple(std::forward<Policy>(policy)))};
106 }
107
108 [[nodiscard]]
109 friend constexpr auto operator&&(BasicExpectationBuilder&& builder, detail::TimesConfig&& config)
110 requires(!timesConfigured)
111 {
112 using NewBuilderT = BasicExpectationBuilder<
113 true,
114 SequenceConfig,
115 Signature,
116 FinalizePolicy,
117 Policies...>;
118
119 return NewBuilderT{
120 std::move(builder.m_Storage),
121 std::move(config),
122 std::move(builder.m_SequenceConfig),
123 std::move(builder.m_FinalizePolicy),
124 std::move(builder.m_ExpectationPolicies)};
125 }
126
127 template <typename... Sequences>
128 [[nodiscard]]
129 friend constexpr auto operator&&(BasicExpectationBuilder&& builder, sequence::detail::Config<Sequences...>&& config)
130 {
131 sequence::detail::Config newConfig = builder.m_SequenceConfig.concat(std::move(config));
132
133 using ExtendedExpectationBuilderT = BasicExpectationBuilder<
134 timesConfigured,
135 decltype(newConfig),
136 Signature,
137 FinalizePolicy,
138 Policies...>;
139
140 return ExtendedExpectationBuilderT{
141 std::move(builder.m_Storage),
142 std::move(builder.m_TimesConfig),
143 std::move(newConfig),
144 std::move(builder.m_FinalizePolicy),
145 std::move(builder.m_ExpectationPolicies)};
146 }
147
148 [[nodiscard]]
149 ScopedExpectation finalize(const std::source_location& sourceLocation) &&
150 {
151 static_assert(
153 "For non-void return types, a finalize policy must be set.");
154
155 return ScopedExpectation{
156 std::move(m_Storage),
157 std::apply(
158 [&](auto&... policies) {
159 ControlPolicy controlPolicy{
160 std::move(m_TimesConfig),
161 std::move(m_SequenceConfig)};
162
163 using ExpectationT = BasicExpectation<
164 Signature,
165 decltype(controlPolicy),
166 FinalizePolicy,
167 Policies...>;
168
169 return std::make_unique<ExpectationT>(
170 sourceLocation,
171 std::move(controlPolicy),
172 std::move(m_FinalizePolicy),
173 std::move(policies)...);
174 },
175 m_ExpectationPolicies)};
176 }
177
178 private:
179 std::shared_ptr<StorageT> m_Storage;
180 detail::TimesConfig m_TimesConfig{};
181 SequenceConfig m_SequenceConfig{};
182 FinalizePolicy m_FinalizePolicy{};
183 PolicyListT m_ExpectationPolicies{};
184 };
185}
186
187namespace mimicpp::detail
188{
189 template <typename Param, typename Arg>
190 requires matcher_for<
191 std::remove_cvref_t<Arg>,
192 Param>
193 [[nodiscard]]
194 constexpr auto make_arg_matcher(Arg&& arg, [[maybe_unused]] const priority_tag<2>)
195 {
196 return std::forward<Arg>(arg);
197 }
198
199 template <string Param, string Arg>
200 [[nodiscard]]
201 constexpr auto make_arg_matcher(Arg&& arg, [[maybe_unused]] const priority_tag<1>)
202 {
203 return matches::str::eq(std::forward<Arg>(arg));
204 }
205
206 template <typename Param, std::equality_comparable_with<Param> Arg>
207 [[nodiscard]]
208 constexpr auto make_arg_matcher(Arg&& arg, [[maybe_unused]] const priority_tag<0>)
209 {
210 return matches::eq(std::forward<Arg>(arg));
211 }
212
213 constexpr priority_tag<2> max_make_arg_matcher_tag{};
214
215 template <typename Arg, typename Target>
216 concept requirement_for = requires {
217 {
218 detail::make_arg_matcher<Target, Arg>(
219 std::declval<Arg>(),
220 max_make_arg_matcher_tag)
221 } -> matcher_for<Target>;
222 };
223
224 template <
225 typename Signature,
226 std::size_t index,
227 typename Arg,
228 typename... Canary,
230 requires requirement_for<Arg, Param>
231 constexpr auto make_arg_policy(Arg&& arg)
232 {
233 return expect::arg<index>(
234 detail::make_arg_matcher<Param, Arg>(
235 std::forward<Arg>(arg),
236 max_make_arg_matcher_tag));
237 }
238
239 template <typename Signature, typename Builder, std::size_t... indices, typename... Args>
240 [[nodiscard]]
241 constexpr auto extend_builder_with_arg_policies(
242 Builder&& builder,
243 const std::index_sequence<indices...>,
244 Args&&... args)
245 {
246 return (
247 std::forward<Builder>(builder)
248 && ...
249 && detail::make_arg_policy<Signature, indices>(
250 std::forward<Args>(args)));
251 }
252
253 template <typename Signature, typename... Args>
254 constexpr auto make_expectation_builder(
255 std::shared_ptr<ExpectationCollection<Signature>> expectations,
256 Args&&... args)
257 {
258 using BaseBuilderT = BasicExpectationBuilder<
259 false,
260 sequence::detail::Config<>,
261 Signature,
262 expectation_policies::InitFinalize>;
263
264 return detail::extend_builder_with_arg_policies<Signature>(
265 BaseBuilderT{
266 std::move(expectations),
267 TimesConfig{},
268 sequence::detail::Config<>{},
269 expectation_policies::InitFinalize{},
270 std::tuple{}},
271 std::index_sequence_for<Args...>{},
272 std::forward<Args>(args)...);
273 }
274}
275
276#define MIMICPP_DETAIL_UNIQUE_NAME(prefix, counter) prefix##counter
277#define MIMICPP_DETAIL_SCOPED_EXPECTATION_IMPL(counter) \
278 [[maybe_unused]] \
279 const ::mimicpp::ScopedExpectation MIMICPP_DETAIL_UNIQUE_NAME(_mimicpp_expectation_, counter) =
280
285#define MIMICPP_SCOPED_EXPECTATION MIMICPP_DETAIL_SCOPED_EXPECTATION_IMPL(__COUNTER__)
286
287#ifndef MIMICPP_CONFIG_ONLY_PREFIXED_MACROS
288
293 #define SCOPED_EXP MIMICPP_SCOPED_EXPECTATION
294
295#endif
296
297#endif
ScopedExpectation finalize(const std::source_location &sourceLocation) &&
Definition ExpectationBuilder.hpp:149
BasicExpectationBuilder(BasicExpectationBuilder &&)=default
friend constexpr auto operator&&(BasicExpectationBuilder &&builder, Policy &&policy)
Definition ExpectationBuilder.hpp:88
BasicExpectationBuilder & operator=(BasicExpectationBuilder &&)=default
ExpectationCollection< Signature > StorageT
Definition ExpectationBuilder.hpp:31
friend constexpr auto operator&&(BasicExpectationBuilder &&builder, sequence::detail::Config< Sequences... > &&config)
Definition ExpectationBuilder.hpp:129
std::tuple< Policies... > PolicyListT
Definition ExpectationBuilder.hpp:32
BasicExpectationBuilder & operator=(const BasicExpectationBuilder &)=delete
typename Expectation< Signature >::ReturnT ReturnT
Definition ExpectationBuilder.hpp:33
BasicExpectationBuilder(const BasicExpectationBuilder &)=delete
friend constexpr auto operator&&(BasicExpectationBuilder &&builder, detail::TimesConfig &&config)
Definition ExpectationBuilder.hpp:109
constexpr BasicExpectationBuilder(std::shared_ptr< StorageT > storage, detail::TimesConfig timesConfig, SequenceConfig sequenceConfig, FinalizePolicyArg &&finalizePolicyArg, PolicyListArg &&policyListArg) noexcept
Definition ExpectationBuilder.hpp:41
The actual expectation template.
Definition Expectation.hpp:417
Definition ControlPolicies.hpp:156
Collects all expectations for a specific (decayed) signature.
Definition Fwd.hpp:327
signature_return_type_t< Signature > ReturnT
The return type.
Definition Expectation.hpp:118
Takes the ownership of an expectation and check whether it's satisfied during destruction.
Definition Expectation.hpp:561
Determines, whether the given type satisfies the requirements of an expectation-policy for the given ...
Definition Expectation.hpp:369
Determines, whether the given type satisfies the requirements of a finalize-policy for the given sign...
Definition Expectation.hpp:383
constexpr auto arg(Matcher &&matcher, Projection &&projection={}) noexcept(std::is_nothrow_constructible_v< std::remove_cvref_t< Matcher >, Matcher > &&std::is_nothrow_constructible_v< std::remove_cvref_t< Projection >, Projection >)
Checks whether the selected argument satisfies the given matcher.
Definition ArgRequirementPolicies.hpp:188
constexpr auto eq(Pattern &&pattern)
Tests, whether the target string compares equal to the expected string.
Definition StringMatchers.hpp:118
constexpr auto eq(T &&value)
Tests, whether the target compares equal to the expected value.
Definition GeneralMatchers.hpp:247
typename signature_param_type< index, Signature >::type signature_param_type_t
Convenience alias, exposing the type member alias of the actual type-trait.
Definition Fwd.hpp:237
Definition BoostTest.hpp:20