diff --git a/llvm/include/llvm/Testing/Support/SupportHelpers.h b/llvm/include/llvm/Testing/Support/SupportHelpers.h --- a/llvm/include/llvm/Testing/Support/SupportHelpers.h +++ b/llvm/include/llvm/Testing/Support/SupportHelpers.h @@ -9,9 +9,11 @@ #ifndef LLVM_TESTING_SUPPORT_SUPPORTHELPERS_H #define LLVM_TESTING_SUPPORT_SUPPORTHELPERS_H +#include "llvm/ADT/Optional.h" #include "llvm/ADT/SmallString.h" #include "llvm/Support/Error.h" #include "llvm/Support/raw_os_ostream.h" +#include "gmock/gmock-matchers.h" #include "gtest/gtest-printers.h" #include @@ -57,7 +59,57 @@ namespace unittest { SmallString<128> getInputFileDirectory(const char *Argv0); + +/// Matches an llvm::Optional with a value that conforms to an inner matcher. +/// To match llvm::None you could use Eq(llvm::None). +template class ValueIsMatcher { +public: + explicit ValueIsMatcher(InnerMatcher ValueMatcher) + : ValueMatcher(ValueMatcher) {} + + template + operator ::testing::Matcher &>() const { + return ::testing::MakeMatcher( + new Impl(::testing::SafeMatcherCast(ValueMatcher))); + } + + template + class Impl : public ::testing::MatcherInterface &> { + public: + explicit Impl(const ::testing::Matcher &ValueMatcher) + : ValueMatcher(ValueMatcher) {} + + bool MatchAndExplain(const llvm::Optional &Input, + testing::MatchResultListener *L) const override { + if (!Input) { + *L << "does not have a value"; + return false; + } + return ValueMatcher.MatchAndExplain(Input.getValue(), L); + } + + void DescribeTo(std::ostream *OS) const override { + *OS << "has a value that "; + ValueMatcher.DescribeTo(OS); + } + void DescribeNegationTo(std::ostream *OS) const override { + *OS << "does not have a value that "; + ValueMatcher.DescribeTo(OS); + } + + private: + testing::Matcher ValueMatcher; + }; + +private: + InnerMatcher ValueMatcher; +}; + +template +ValueIsMatcher ValueIs(const InnerMatcher &ValueMatcher) { + return ValueIsMatcher(ValueMatcher); } +} // namespace unittest } // namespace llvm #endif