1 //===- llvm/Testing/Support/Error.h ---------------------------------------===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 10 #ifndef LLVM_TESTING_SUPPORT_ERROR_H 11 #define LLVM_TESTING_SUPPORT_ERROR_H 12 13 #include "llvm/ADT/Optional.h" 14 #include "llvm/Support/Error.h" 15 #include "llvm/Testing/Support/SupportHelpers.h" 16 17 #include "gmock/gmock.h" 18 #include <ostream> 19 20 namespace llvm { 21 namespace detail { 22 ErrorHolder TakeError(Error Err); 23 24 template <typename T> ExpectedHolder<T> TakeExpected(Expected<T> &Exp) { 25 return {TakeError(Exp.takeError()), Exp}; 26 } 27 28 template <typename T> ExpectedHolder<T> TakeExpected(Expected<T> &&Exp) { 29 return TakeExpected(Exp); 30 } 31 32 template <typename T> 33 class ValueMatchesMono 34 : public testing::MatcherInterface<const ExpectedHolder<T> &> { 35 public: 36 explicit ValueMatchesMono(const testing::Matcher<T> &Matcher) 37 : Matcher(Matcher) {} 38 39 bool MatchAndExplain(const ExpectedHolder<T> &Holder, 40 testing::MatchResultListener *listener) const override { 41 if (!Holder.Success()) 42 return false; 43 44 bool result = Matcher.MatchAndExplain(*Holder.Exp, listener); 45 46 if (result) 47 return result; 48 *listener << "("; 49 Matcher.DescribeNegationTo(listener->stream()); 50 *listener << ")"; 51 return result; 52 } 53 54 void DescribeTo(std::ostream *OS) const override { 55 *OS << "succeeded with value ("; 56 Matcher.DescribeTo(OS); 57 *OS << ")"; 58 } 59 60 void DescribeNegationTo(std::ostream *OS) const override { 61 *OS << "did not succeed or value ("; 62 Matcher.DescribeNegationTo(OS); 63 *OS << ")"; 64 } 65 66 private: 67 testing::Matcher<T> Matcher; 68 }; 69 70 template<typename M> 71 class ValueMatchesPoly { 72 public: 73 explicit ValueMatchesPoly(const M &Matcher) : Matcher(Matcher) {} 74 75 template <typename T> 76 operator testing::Matcher<const ExpectedHolder<T> &>() const { 77 return MakeMatcher( 78 new ValueMatchesMono<T>(testing::SafeMatcherCast<T>(Matcher))); 79 } 80 81 private: 82 M Matcher; 83 }; 84 85 template <typename InfoT> 86 class ErrorMatchesMono : public testing::MatcherInterface<const ErrorHolder &> { 87 public: 88 explicit ErrorMatchesMono(Optional<testing::Matcher<InfoT &>> Matcher) 89 : Matcher(std::move(Matcher)) {} 90 91 bool MatchAndExplain(const ErrorHolder &Holder, 92 testing::MatchResultListener *listener) const override { 93 if (Holder.Success()) 94 return false; 95 96 if (Holder.Infos.size() > 1) { 97 *listener << "multiple errors"; 98 return false; 99 } 100 101 auto &Info = *Holder.Infos[0]; 102 if (!Info.isA<InfoT>()) { 103 *listener << "Error was not of given type"; 104 return false; 105 } 106 107 if (!Matcher) 108 return true; 109 110 return Matcher->MatchAndExplain(static_cast<InfoT &>(Info), listener); 111 } 112 113 void DescribeTo(std::ostream *OS) const override { 114 *OS << "failed with Error of given type"; 115 if (Matcher) { 116 *OS << " and the error "; 117 Matcher->DescribeTo(OS); 118 } 119 } 120 121 void DescribeNegationTo(std::ostream *OS) const override { 122 *OS << "succeeded or did not fail with the error of given type"; 123 if (Matcher) { 124 *OS << " or the error "; 125 Matcher->DescribeNegationTo(OS); 126 } 127 } 128 129 private: 130 Optional<testing::Matcher<InfoT &>> Matcher; 131 }; 132 } // namespace detail 133 134 #define EXPECT_THAT_ERROR(Err, Matcher) \ 135 EXPECT_THAT(llvm::detail::TakeError(Err), Matcher) 136 #define ASSERT_THAT_ERROR(Err, Matcher) \ 137 ASSERT_THAT(llvm::detail::TakeError(Err), Matcher) 138 139 #define EXPECT_THAT_EXPECTED(Err, Matcher) \ 140 EXPECT_THAT(llvm::detail::TakeExpected(Err), Matcher) 141 #define ASSERT_THAT_EXPECTED(Err, Matcher) \ 142 ASSERT_THAT(llvm::detail::TakeExpected(Err), Matcher) 143 144 MATCHER(Succeeded, "") { return arg.Success(); } 145 MATCHER(Failed, "") { return !arg.Success(); } 146 147 template <typename InfoT> 148 testing::Matcher<const detail::ErrorHolder &> Failed() { 149 return MakeMatcher(new detail::ErrorMatchesMono<InfoT>(None)); 150 } 151 152 template <typename InfoT, typename M> 153 testing::Matcher<const detail::ErrorHolder &> Failed(M Matcher) { 154 return MakeMatcher(new detail::ErrorMatchesMono<InfoT>( 155 testing::SafeMatcherCast<InfoT &>(Matcher))); 156 } 157 158 template <typename M> 159 detail::ValueMatchesPoly<M> HasValue(M Matcher) { 160 return detail::ValueMatchesPoly<M>(Matcher); 161 } 162 163 } // namespace llvm 164 165 #endif 166