38 using Ptr = std::shared_ptr<Registry>;
76 template <
typename... Args>
77 requires std::constructible_from<
Expectation, Args...>
81 std::scoped_lock
const lock{m_ExpectationsMx};
82 return m_Expectations.emplace_back(std::forward<Args>(args)...);
94 std::scoped_lock
const lock{m_ExpectationsMx};
96 auto const iter = std::ranges::find(m_Expectations,
expectation);
97 MIMICPP_ASSERT(iter != m_Expectations.cend(),
"Expectation does not belong to this registry.");
98 m_Expectations.erase(iter);
102 reporting::detail::report_unfulfilled_expectation(
expectation.report());
116 template <
typename Signature>
120 std::scoped_lock
const lock{m_ExpectationsMx};
121 auto&& [
matches, inapplicableMatches, noMatches] = evaluate_expectations(target,
call);
123 std::size_t
const stacktraceSkip{1u +
call.baseStacktraceSkip};
124 if (!std::ranges::empty(
matches))
126 return handle_matched_call<Signature>(
130 stacktraceSkip + 1u);
133 if (!std::ranges::empty(inapplicableMatches))
135 reporting::detail::report_inapplicable_matches(
137 make_match_reports(std::move(inapplicableMatches)));
140 reporting::detail::report_no_matches(
142 make_match_reports(std::move(noMatches)));
146 std::vector<Expectation> m_Expectations{};
147 std::mutex m_ExpectationsMx{};
150 static std::optional<MatchResults> try_match_call(
151 reporting::TargetReport
const& target,
152 auto const& callInfo,
153 Expectation
const& expectation)
noexcept
157 return expectation.matches(callInfo);
161 reporting::detail::report_unhandled_exception(
166 expectation.report(),
167 std::current_exception());
173 struct evaluation_results
185 .matchResults = std::move(
results),
191 std::vector<entry> inapplicableMatches{};
192 std::vector<entry> noMatches{};
196 auto evaluate_expectations(reporting::TargetReport
const& target,
auto const& callInfo)
198 evaluation_results results{};
200 for (
auto& exp : std::views::reverse(m_Expectations))
202 if (std::optional result = try_match_call(target, callInfo, exp))
204 if (std::ranges::any_of(*result, [](
auto const& el) {
return std::holds_alternative<MatchFailure>(el); }))
206 results.noMatches.emplace_back(exp, *std::move(result));
208 else if (!exp.is_applicable())
210 results.inapplicableMatches.emplace_back(exp, *std::move(result));
214 results.matches.emplace_back(exp, *std::move(result));
222 template <
typename Signature>
225 reporting::TargetReport&& target,
227 std::vector<evaluation_results::entry>&& matches,
228 std::size_t
const stacktraceSkip)
230 std::vector reports = std::invoke([&] {
231 auto view = std::views::transform(
233 [](
auto const& entry) {
return entry.expectation.get().report(); });
234 return std::vector(view.begin(), view.end());
236 MIMICPP_ASSERT(matches.size() == reports.size(),
"Size mismatch.");
237 auto const bestIter = std::ranges::max_element(
239 std::not_fn(&sequence::detail::has_better_rating),
240 [](reporting::ExpectationReport
const& el)
noexcept ->
const auto& {
241 return std::get<reporting::state_applicable>(el.controlReport).sequenceRatings;
243 auto& bestMatch = matches[std::ranges::distance(reports.cbegin(), bestIter)];
251 reporting::detail::report_full_match(
253 {.expectationReport = std::move(*bestIter), .matchResults = std::move(bestMatch.results)});
256 return bestMatch.expectation.get().consume(callInfo);
260 static std::vector<reporting::MatchReport> make_match_reports(std::vector<evaluation_results::entry>&& outcomes)
262 std::vector<reporting::MatchReport> reports{};
263 reports.reserve(outcomes.size());
264 std::ranges::transform(
266 std::back_inserter(reports),
signature_return_type_t< Signature > handle_call(reporting::TargetReport target, call::info_for_signature_t< Signature > call)
Handles the incoming call.
Definition Registry.hpp:118
CallReport make_call_report(TargetReport target, call::Info< Return, Params... > callInfo, util::Stacktrace stacktrace)
Generates the call report for a given call info.
Definition CallReport.hpp:79
reporting::MatchReport to_match_report() &&
Definition Registry.hpp:181
MatchResults results
Definition Registry.hpp:178
std::reference_wrapper< Expectation > expectation
Definition Registry.hpp:177