6#ifndef MIMICPP_MATCHER_HPP
7#define MIMICPP_MATCHER_HPP
24 template <
typename T,
typename Target>
26 && std::is_move_constructible_v<T>
27 && std::destructible<T>
28 &&
requires(
const T& matcher, Target& target)
30 { matcher.matches(target) } -> std::convertible_to<bool>;
31 { matcher.describe() } -> std::convertible_to<std::optional<StringT>>;
41 template <
typename Predicate,
typename... AdditionalArgs>
42 requires std::is_move_constructible_v<Predicate>
43 && (... && std::is_move_constructible_v<AdditionalArgs>)
52 std::tuple<AdditionalArgs...> additionalArgs = std::tuple{}
53 )
noexcept(std::is_nothrow_move_constructible_v<Predicate>
54 && (... && std::is_nothrow_move_constructible_v<AdditionalArgs>))
55 : m_Predicate{std::move(predicate)},
56 m_FormatString{std::move(fmt)},
57 m_InvertedFormatString{std::move(invertedFmt)},
58 m_AdditionalArgs{std::move(additionalArgs)}
63 requires std::predicate<
const Predicate&, T&,
const AdditionalArgs&...>
67 )
const noexcept(std::is_nothrow_invocable_v<
const Predicate&, T&,
const AdditionalArgs&...>)
70 [&,
this](
auto&... additionalArgs)
84 [&,
this](
auto&... additionalArgs)
87 constexpr auto makeLvalue = [](
auto&& val)
noexcept ->
const auto& {
return val; };
88 return format::vformat(
90 format::make_format_args(
97 constexpr auto operator !() const &
98 requires std::is_copy_constructible_v<Predicate>
99 && (... && std::is_copy_constructible_v<AdditionalArgs>)
101 return make_inverted(
103 m_InvertedFormatString,
105 std::move(m_AdditionalArgs));
109 constexpr auto operator !() &&
111 return make_inverted(
112 std::move(m_Predicate),
113 std::move(m_InvertedFormatString),
114 std::move(m_FormatString),
115 std::move(m_AdditionalArgs));
119 [[no_unique_address]] Predicate m_Predicate;
121 StringT m_InvertedFormatString;
122 mutable std::tuple<AdditionalArgs...> m_AdditionalArgs{};
124 template <
typename Fn>
126 static constexpr auto make_inverted(
130 std::tuple<AdditionalArgs...> tuple
133 using NotFnT =
decltype(std::not_fn(std::forward<Fn>(fn)));
134 return PredicateMatcher<NotFnT, AdditionalArgs...>{
135 std::not_fn(std::forward<Fn>(fn)),
137 std::move(invertedFmt),
152 static constexpr bool matches(
auto&& target)
noexcept
157 static constexpr std::nullopt_t
describe() noexcept
210 template <
typename T>
212 constexpr auto eq(T&& value)
215 std::ranges::equal_to{},
218 std::tuple{std::forward<T>(value)}
227 template <
typename T>
229 constexpr auto ne(T&& value)
232 std::ranges::not_equal_to{},
235 std::tuple{std::forward<T>(value)}
244 template <
typename T>
246 constexpr auto lt(T&& value)
252 std::tuple{std::forward<T>(value)}
261 template <
typename T>
263 constexpr auto le(T&& value)
266 std::ranges::less_equal{},
269 std::tuple{std::forward<T>(value)}
278 template <
typename T>
280 constexpr auto gt(T&& value)
283 std::ranges::greater{},
286 std::tuple{std::forward<T>(value)}
295 template <
typename T>
297 constexpr auto ge(T&& value)
300 std::ranges::greater_equal{},
303 std::tuple{std::forward<T>(value)}
315 template <
typename UnaryPredicate>
319 StringT description =
"passes predicate",
320 StringT invertedDescription =
"fails predicate"
325 std::move(description),
326 std::move(invertedDescription),
353 template <
typename Char,
typename Traits,
typename Allocator>
355 constexpr auto eq(std::basic_string<Char, Traits, Allocator> expected)
357 using ViewT = std::basic_string_view<Char>;
359 [](
const ViewT target,
const ViewT exp)
361 return target == exp;
364 "is not equal to {}",
365 std::tuple{std::move(expected)}
374 template <
typename Char>
376 constexpr auto eq(
const Char* expected)
379 std::basic_string<Char>{expected});
405 template <std::ranges::forward_range Range,
typename Comparator = std::equal_to<>>
407 constexpr auto eq(Range&& expected, Comparator comparator = Comparator{})
410 [comp = std::move(comparator)]
411 <
typename Target>(Target&& target,
auto& range)
412 requires std::predicate<
414 std::ranges::range_reference_t<Target>,
415 std::ranges::range_reference_t<Range>>
417 return std::ranges::equal(
423 "elements are not {}",
424 std::tuple{std::views::all(std::forward<Range>(expected))}
435 template <std::ranges::forward_range Range,
typename Comparator = std::equal_to<>>
437 constexpr auto unordered_eq(Range&& expected, Comparator comparator = Comparator{})
440 [comp = std::move(comparator)]<
typename Target
441 >(Target&& target,
auto& range)
442 requires std::predicate<
444 std::ranges::range_reference_t<Target>,
445 std::ranges::range_reference_t<Range>>
447 return std::ranges::is_permutation(
452 "is a permutation of {}",
453 "is not a permutation of {}",
454 std::tuple{std::views::all(std::forward<Range>(expected))}
463 template <
typename Relation = std::ranges::less>
465 constexpr auto is_sorted(Relation relation = Relation{})
468 [rel = std::move(relation)]<
typename Target>(Target&& target)
469 requires std::equivalence_relation<
471 std::ranges::range_reference_t<Target>,
472 std::ranges::range_reference_t<Target>>
474 return std::ranges::is_sorted(
479 "is an unsorted range"
490 [](std::ranges::range
auto&& target)
492 return std::ranges::empty(target);
495 "is not an empty range"
504 constexpr auto has_size(
const std::integral
auto expected)
507 [](std::ranges::range
auto&& target,
const std::integral
auto size)
509 return std::cmp_equal(
511 std::ranges::size(target));
514 "has different size than {}",
Generic matcher and the basic building block of most of the built-in matchers.
Definition Matcher.hpp:45
constexpr bool matches(T &target) const noexcept(std::is_nothrow_invocable_v< const Predicate &, T &, const AdditionalArgs &... >)
Definition Matcher.hpp:65
constexpr StringT describe() const
Definition Matcher.hpp:81
constexpr PredicateMatcher(Predicate predicate, StringT fmt, StringT invertedFmt, std::tuple< AdditionalArgs... > additionalArgs=std::tuple{}) noexcept(std::is_nothrow_move_constructible_v< Predicate > &&(... &&std::is_nothrow_move_constructible_v< AdditionalArgs >))
Definition Matcher.hpp:48
Matcher, which never fails.
Definition Matcher.hpp:150
static constexpr bool matches(auto &&target) noexcept
Definition Matcher.hpp:152
static constexpr std::nullopt_t describe() noexcept
Definition Matcher.hpp:157
Definition Matcher.hpp:25
constexpr auto eq(Range &&expected, Comparator comparator=Comparator{})
Tests, whether the target range compares equal to the expected range, by comparing them element-wise.
Definition Matcher.hpp:407
constexpr auto unordered_eq(Range &&expected, Comparator comparator=Comparator{})
Tests, whether the target range is a permutation of the expected range, by comparing them element-wis...
Definition Matcher.hpp:437
constexpr auto has_size(const std::integral auto expected)
Tests, whether the target range has the expected size.
Definition Matcher.hpp:504
constexpr auto is_sorted(Relation relation=Relation{})
Tests, whether the target range is sorted, by applying the relation on each adjacent elements.
Definition Matcher.hpp:465
constexpr auto is_empty()
Tests, whether the target range is empty.
Definition Matcher.hpp:487
constexpr auto lt(T &&value)
Tests, whether the target is less than the expected value.
Definition Matcher.hpp:246
constexpr auto le(T &&value)
Tests, whether the target is less than or equal to the expected value.
Definition Matcher.hpp:263
constexpr auto predicate(UnaryPredicate &&predicate, StringT description="passes predicate", StringT invertedDescription="fails predicate")
Tests, whether the target fulfills the given predicate.
Definition Matcher.hpp:317
constexpr WildcardMatcher _
The wildcard matcher, always matching.
Definition Matcher.hpp:203
constexpr auto eq(T &&value)
Tests, whether the target compares equal to the expected value.
Definition Matcher.hpp:212
constexpr auto gt(T &&value)
Tests, whether the target is greater than the expected value.
Definition Matcher.hpp:280
constexpr auto ge(T &&value)
Tests, whether the target is greater than or equal to the expected value.
Definition Matcher.hpp:297
constexpr auto ne(T &&value)
Tests, whether the target compares not equal to the expected value.
Definition Matcher.hpp:229
constexpr auto eq(std::basic_string< Char, Traits, Allocator > expected)
Tests, whether the target string compares equal to the expected string.
Definition Matcher.hpp:355
Definition Matcher.hpp:388
Definition Matcher.hpp:336
Definition Matcher.hpp:165
constexpr detail::PrintFn print
Definition Printer.hpp:266
std::basic_string< CharT, CharTraitsT > StringT
Definition Fwd.hpp:37