Add matcher for std::variant.
This commit is contained in:
@@ -3623,6 +3623,66 @@ GTEST_API_ std::string FormatMatcherDescription(bool negation,
|
||||
const char* matcher_name,
|
||||
const Strings& param_values);
|
||||
|
||||
namespace variant_matcher {
|
||||
// Overloads to allow VariantMatcher to do proper ADL lookup.
|
||||
template <typename T>
|
||||
void holds_alternative() {}
|
||||
template <typename T>
|
||||
void get() {}
|
||||
|
||||
// Implements a matcher that checks the value of a variant<> type variable.
|
||||
template <typename T>
|
||||
class VariantMatcher {
|
||||
public:
|
||||
explicit VariantMatcher(::testing::Matcher<const T&> matcher)
|
||||
: matcher_(internal::move(matcher)) {}
|
||||
|
||||
template <typename Variant>
|
||||
bool MatchAndExplain(const Variant& value,
|
||||
::testing::MatchResultListener* listener) const {
|
||||
if (!listener->IsInterested()) {
|
||||
return holds_alternative<T>(value) && matcher_.Matches(get<T>(value));
|
||||
}
|
||||
|
||||
if (!holds_alternative<T>(value)) {
|
||||
*listener << "whose value is not of type '" << GetTypeName() << "'";
|
||||
return false;
|
||||
}
|
||||
|
||||
const T& elem = get<T>(value);
|
||||
StringMatchResultListener elem_listener;
|
||||
const bool match = matcher_.MatchAndExplain(elem, &elem_listener);
|
||||
*listener << "whose value " << PrintToString(elem)
|
||||
<< (match ? " matches" : " doesn't match");
|
||||
PrintIfNotEmpty(elem_listener.str(), listener->stream());
|
||||
return match;
|
||||
}
|
||||
|
||||
void DescribeTo(std::ostream* os) const {
|
||||
*os << "is a variant<> with value of type '" << GetTypeName()
|
||||
<< "' and the value ";
|
||||
matcher_.DescribeTo(os);
|
||||
}
|
||||
|
||||
void DescribeNegationTo(std::ostream* os) const {
|
||||
*os << "is a variant<> with value of type other than '" << GetTypeName()
|
||||
<< "' or the value ";
|
||||
matcher_.DescribeNegationTo(os);
|
||||
}
|
||||
|
||||
private:
|
||||
static string GetTypeName() {
|
||||
#if GTEST_HAS_RTTI
|
||||
return internal::GetTypeName<T>();
|
||||
#endif
|
||||
return "the element type";
|
||||
}
|
||||
|
||||
const ::testing::Matcher<const T&> matcher_;
|
||||
};
|
||||
|
||||
} // namespace variant_matcher
|
||||
|
||||
} // namespace internal
|
||||
|
||||
// ElementsAreArray(first, last)
|
||||
@@ -4397,6 +4457,17 @@ inline internal::AnyOfMatcher<Args...> AnyOf(const Args&... matchers) {
|
||||
template <typename InnerMatcher>
|
||||
inline InnerMatcher AllArgs(const InnerMatcher& matcher) { return matcher; }
|
||||
|
||||
// Returns a matcher that matches the value of a variant<> type variable.
|
||||
// The matcher implementation uses ADL to find the holds_alternative and get
|
||||
// functions.
|
||||
// It is compatible with std::variant.
|
||||
template <typename T>
|
||||
PolymorphicMatcher<internal::variant_matcher::VariantMatcher<T> > VariantWith(
|
||||
const Matcher<const T&>& matcher) {
|
||||
return MakePolymorphicMatcher(
|
||||
internal::variant_matcher::VariantMatcher<T>(matcher));
|
||||
}
|
||||
|
||||
// These macros allow using matchers to check values in Google Test
|
||||
// tests. ASSERT_THAT(value, matcher) and EXPECT_THAT(value, matcher)
|
||||
// succeed iff the value matches the matcher. If the assertion fails,
|
||||
|
||||
Reference in New Issue
Block a user