diff options
-rw-r--r-- | llvm/include/llvm/Testing/Support/Error.h | 72 | ||||
-rw-r--r-- | llvm/include/llvm/Testing/Support/SupportHelpers.h | 3 | ||||
-rw-r--r-- | llvm/unittests/Support/ErrorTest.cpp | 21 |
3 files changed, 75 insertions, 21 deletions
diff --git a/llvm/include/llvm/Testing/Support/Error.h b/llvm/include/llvm/Testing/Support/Error.h index e7e8a007238..50889b9c66f 100644 --- a/llvm/include/llvm/Testing/Support/Error.h +++ b/llvm/include/llvm/Testing/Support/Error.h @@ -28,6 +28,60 @@ template <typename T> ExpectedHolder<T> TakeExpected(Expected<T> &Exp) { template <typename T> ExpectedHolder<T> TakeExpected(Expected<T> &&Exp) { return TakeExpected(Exp); } + +template <typename T> +class ValueMatchesMono + : public testing::MatcherInterface<const ExpectedHolder<T> &> { +public: + explicit ValueMatchesMono(const testing::Matcher<T> &Matcher) + : Matcher(Matcher) {} + + bool MatchAndExplain(const ExpectedHolder<T> &Holder, + testing::MatchResultListener *listener) const override { + if (!Holder.Success) + return false; + + bool result = Matcher.MatchAndExplain(*Holder.Exp, listener); + + if (result) + return result; + *listener << "("; + Matcher.DescribeNegationTo(listener->stream()); + *listener << ")"; + return result; + } + + void DescribeTo(std::ostream *OS) const override { + *OS << "succeeded with value ("; + Matcher.DescribeTo(OS); + *OS << ")"; + } + + void DescribeNegationTo(std::ostream *OS) const override { + *OS << "did not succeed or value ("; + Matcher.DescribeNegationTo(OS); + *OS << ")"; + } + +private: + testing::Matcher<T> Matcher; +}; + +template<typename M> +class ValueMatchesPoly { +public: + explicit ValueMatchesPoly(const M &Matcher) : Matcher(Matcher) {} + + template <typename T> + operator testing::Matcher<const ExpectedHolder<T> &>() const { + return MakeMatcher( + new ValueMatchesMono<T>(testing::SafeMatcherCast<T>(Matcher))); + } + +private: + M Matcher; +}; + } // namespace detail #define EXPECT_THAT_ERROR(Err, Matcher) \ @@ -43,21 +97,11 @@ template <typename T> ExpectedHolder<T> TakeExpected(Expected<T> &&Exp) { MATCHER(Succeeded, "") { return arg.Success; } MATCHER(Failed, "") { return !arg.Success; } -MATCHER_P(HasValue, value, - "succeeded with value \"" + testing::PrintToString(value) + '"') { - if (!arg.Success) { - *result_listener << "operation failed"; - return false; - } - - if (*arg.Exp != value) { - *result_listener << "but \"" + testing::PrintToString(*arg.Exp) + - "\" != \"" + testing::PrintToString(value) + '"'; - return false; - } - - return true; +template <typename M> +detail::ValueMatchesPoly<M> HasValue(M Matcher) { + return detail::ValueMatchesPoly<M>(Matcher); } + } // namespace llvm #endif diff --git a/llvm/include/llvm/Testing/Support/SupportHelpers.h b/llvm/include/llvm/Testing/Support/SupportHelpers.h index 8af3034767f..d7f0c7142b2 100644 --- a/llvm/include/llvm/Testing/Support/SupportHelpers.h +++ b/llvm/include/llvm/Testing/Support/SupportHelpers.h @@ -38,8 +38,7 @@ inline void PrintTo(const ErrorHolder &Err, std::ostream *Out) { template <typename T> void PrintTo(const ExpectedHolder<T> &Item, std::ostream *Out) { if (Item.Success) { - *Out << "succeeded with value \"" << ::testing::PrintToString(*Item.Exp) - << "\""; + *Out << "succeeded with value " << ::testing::PrintToString(*Item.Exp); } else { PrintTo(static_cast<const ErrorHolder &>(Item), Out); } diff --git a/llvm/unittests/Support/ErrorTest.cpp b/llvm/unittests/Support/ErrorTest.cpp index 213ed55c721..2629e640f79 100644 --- a/llvm/unittests/Support/ErrorTest.cpp +++ b/llvm/unittests/Support/ErrorTest.cpp @@ -735,23 +735,34 @@ TEST(Error, ErrorMatchers) { EXPECT_THAT_EXPECTED(Expected<int>(make_error<CustomError>(0)), Failed()); EXPECT_NONFATAL_FAILURE( EXPECT_THAT_EXPECTED(Expected<int>(0), Failed()), - "Expected: failed\n Actual: succeeded with value \"0\""); + "Expected: failed\n Actual: succeeded with value 0"); EXPECT_THAT_EXPECTED(Expected<int>(0), HasValue(0)); EXPECT_NONFATAL_FAILURE( EXPECT_THAT_EXPECTED(Expected<int>(make_error<CustomError>(0)), HasValue(0)), - "Expected: succeeded with value \"0\"\n" + "Expected: succeeded with value (is equal to 0)\n" " Actual: failed (CustomError { 0})"); EXPECT_NONFATAL_FAILURE( EXPECT_THAT_EXPECTED(Expected<int>(1), HasValue(0)), - "Expected: succeeded with value \"0\"\n" - " Actual: succeeded with value \"1\", but \"1\" != \"0\""); + "Expected: succeeded with value (is equal to 0)\n" + " Actual: succeeded with value 1, (isn't equal to 0)"); EXPECT_THAT_EXPECTED(Expected<int &>(make_error<CustomError>(0)), Failed()); int a = 1; EXPECT_THAT_EXPECTED(Expected<int &>(a), Succeeded()); - EXPECT_THAT_EXPECTED(Expected<int &>(a), HasValue(1)); + EXPECT_THAT_EXPECTED(Expected<int &>(a), HasValue(testing::Eq(1))); + + EXPECT_THAT_EXPECTED(Expected<int>(1), HasValue(testing::Gt(0))); + EXPECT_NONFATAL_FAILURE( + EXPECT_THAT_EXPECTED(Expected<int>(0), HasValue(testing::Gt(1))), + "Expected: succeeded with value (is > 1)\n" + " Actual: succeeded with value 0, (isn't > 1)"); + EXPECT_NONFATAL_FAILURE( + EXPECT_THAT_EXPECTED(Expected<int>(make_error<CustomError>(0)), + HasValue(testing::Gt(1))), + "Expected: succeeded with value (is > 1)\n" + " Actual: failed (CustomError { 0})"); } } // end anon namespace |