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 @@ -53,11 +55,56 @@ PrintTo(static_cast(Item), Out); } } + +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 { + return Input && 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; +}; } // namespace detail +/// Matches an llvm::Optional with a value that conforms to an inner matcher. +/// To match llvm::None you could use Eq(llvm::None). +template +detail::ValueIsMatcher ValueIs(const InnerMatcher &ValueMatcher) { + return detail::ValueIsMatcher(ValueMatcher); +} namespace unittest { SmallString<128> getInputFileDirectory(const char *Argv0); -} +} // namespace unittest } // namespace llvm #endif diff --git a/llvm/unittests/Support/CMakeLists.txt b/llvm/unittests/Support/CMakeLists.txt --- a/llvm/unittests/Support/CMakeLists.txt +++ b/llvm/unittests/Support/CMakeLists.txt @@ -39,6 +39,7 @@ LEB128Test.cpp LineIteratorTest.cpp LockFileManagerTest.cpp + MatchersTest.cpp MD5Test.cpp ManagedStatic.cpp MathExtrasTest.cpp diff --git a/llvm/unittests/Support/MatchersTest.cpp b/llvm/unittests/Support/MatchersTest.cpp new file mode 100644 --- /dev/null +++ b/llvm/unittests/Support/MatchersTest.cpp @@ -0,0 +1,25 @@ +//===----- unittests/MatchersTest.cpp -------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "llvm/ADT/Optional.h" +#include "llvm/Testing/Support/SupportHelpers.h" +#include "gmock/gmock-matchers.h" + +using ::testing::_; +using ::testing::AllOf; +using ::testing::Gt; +using ::testing::Lt; +using ::testing::Not; + +namespace { +TEST(MatchersTest, Optional) { + EXPECT_THAT(llvm::Optional(llvm::None), Not(llvm::ValueIs(_))); + EXPECT_THAT(llvm::Optional(10), llvm::ValueIs(10)); + EXPECT_THAT(llvm::Optional(10), llvm::ValueIs(AllOf(Lt(11), Gt(9)))); +} +} // namespace