File indexing completed on 2026-05-10 08:44:37
0001
0002
0003
0004
0005
0006
0007
0008
0009 #ifndef LLVM_TESTING_SUPPORT_ERROR_H
0010 #define LLVM_TESTING_SUPPORT_ERROR_H
0011
0012 #include "llvm/Support/Error.h"
0013 #include "llvm/Testing/Support/SupportHelpers.h"
0014
0015 #include "gmock/gmock.h"
0016 #include <ostream>
0017
0018 namespace llvm {
0019 namespace detail {
0020 ErrorHolder TakeError(Error Err);
0021
0022 template <typename T> ExpectedHolder<T> TakeExpected(Expected<T> &Exp) {
0023 return {TakeError(Exp.takeError()), Exp};
0024 }
0025
0026 template <typename T> ExpectedHolder<T> TakeExpected(Expected<T> &&Exp) {
0027 return TakeExpected(Exp);
0028 }
0029
0030 template <typename T>
0031 class ValueMatchesMono
0032 : public testing::MatcherInterface<const ExpectedHolder<T> &> {
0033 public:
0034 explicit ValueMatchesMono(const testing::Matcher<T> &Matcher)
0035 : Matcher(Matcher) {}
0036
0037 bool MatchAndExplain(const ExpectedHolder<T> &Holder,
0038 testing::MatchResultListener *listener) const override {
0039 if (!Holder.Success())
0040 return false;
0041
0042 bool result = Matcher.MatchAndExplain(*Holder.Exp, listener);
0043
0044 if (result || !listener->IsInterested())
0045 return result;
0046 *listener << "(";
0047 Matcher.DescribeNegationTo(listener->stream());
0048 *listener << ")";
0049 return result;
0050 }
0051
0052 void DescribeTo(std::ostream *OS) const override {
0053 *OS << "succeeded with value (";
0054 Matcher.DescribeTo(OS);
0055 *OS << ")";
0056 }
0057
0058 void DescribeNegationTo(std::ostream *OS) const override {
0059 *OS << "did not succeed or value (";
0060 Matcher.DescribeNegationTo(OS);
0061 *OS << ")";
0062 }
0063
0064 private:
0065 testing::Matcher<T> Matcher;
0066 };
0067
0068 template<typename M>
0069 class ValueMatchesPoly {
0070 public:
0071 explicit ValueMatchesPoly(const M &Matcher) : Matcher(Matcher) {}
0072
0073 template <typename T>
0074 operator testing::Matcher<const ExpectedHolder<T> &>() const {
0075 return MakeMatcher(
0076 new ValueMatchesMono<T>(testing::SafeMatcherCast<T>(Matcher)));
0077 }
0078
0079 private:
0080 M Matcher;
0081 };
0082
0083 template <typename InfoT>
0084 class ErrorMatchesMono : public testing::MatcherInterface<const ErrorHolder &> {
0085 public:
0086 explicit ErrorMatchesMono(std::optional<testing::Matcher<InfoT &>> Matcher)
0087 : Matcher(std::move(Matcher)) {}
0088
0089 bool MatchAndExplain(const ErrorHolder &Holder,
0090 testing::MatchResultListener *listener) const override {
0091 if (Holder.Success())
0092 return false;
0093
0094 if (Holder.Infos.size() > 1) {
0095 *listener << "multiple errors";
0096 return false;
0097 }
0098
0099 auto &Info = *Holder.Infos[0];
0100 if (!Info.isA<InfoT>()) {
0101 *listener << "Error was not of given type";
0102 return false;
0103 }
0104
0105 if (!Matcher)
0106 return true;
0107
0108 return Matcher->MatchAndExplain(static_cast<InfoT &>(Info), listener);
0109 }
0110
0111 void DescribeTo(std::ostream *OS) const override {
0112 *OS << "failed with Error of given type";
0113 if (Matcher) {
0114 *OS << " and the error ";
0115 Matcher->DescribeTo(OS);
0116 }
0117 }
0118
0119 void DescribeNegationTo(std::ostream *OS) const override {
0120 *OS << "succeeded or did not fail with the error of given type";
0121 if (Matcher) {
0122 *OS << " or the error ";
0123 Matcher->DescribeNegationTo(OS);
0124 }
0125 }
0126
0127 private:
0128 std::optional<testing::Matcher<InfoT &>> Matcher;
0129 };
0130
0131 class ErrorMessageMatches
0132 : public testing::MatcherInterface<const ErrorHolder &> {
0133 public:
0134 explicit ErrorMessageMatches(
0135 testing::Matcher<std::vector<std::string>> Matcher)
0136 : Matcher(std::move(Matcher)) {}
0137
0138 bool MatchAndExplain(const ErrorHolder &Holder,
0139 testing::MatchResultListener *listener) const override {
0140 std::vector<std::string> Messages;
0141 Messages.reserve(Holder.Infos.size());
0142 for (const std::shared_ptr<ErrorInfoBase> &Info : Holder.Infos)
0143 Messages.push_back(Info->message());
0144
0145 return Matcher.MatchAndExplain(Messages, listener);
0146 }
0147
0148 void DescribeTo(std::ostream *OS) const override {
0149 *OS << "failed with Error whose message ";
0150 Matcher.DescribeTo(OS);
0151 }
0152
0153 void DescribeNegationTo(std::ostream *OS) const override {
0154 *OS << "failed with an Error whose message ";
0155 Matcher.DescribeNegationTo(OS);
0156 }
0157
0158 private:
0159 testing::Matcher<std::vector<std::string>> Matcher;
0160 };
0161 }
0162
0163 #define EXPECT_THAT_ERROR(Err, Matcher) \
0164 EXPECT_THAT(llvm::detail::TakeError(Err), Matcher)
0165 #define ASSERT_THAT_ERROR(Err, Matcher) \
0166 ASSERT_THAT(llvm::detail::TakeError(Err), Matcher)
0167
0168
0169
0170
0171
0172
0173
0174
0175
0176
0177
0178
0179
0180
0181
0182
0183
0184
0185
0186
0187
0188
0189 #define EXPECT_THAT_EXPECTED(Err, Matcher) \
0190 EXPECT_THAT(llvm::detail::TakeExpected(Err), Matcher)
0191 #define ASSERT_THAT_EXPECTED(Err, Matcher) \
0192 ASSERT_THAT(llvm::detail::TakeExpected(Err), Matcher)
0193
0194 MATCHER(Succeeded, "") { return arg.Success(); }
0195 MATCHER(Failed, "") { return !arg.Success(); }
0196
0197 template <typename InfoT>
0198 testing::Matcher<const detail::ErrorHolder &> Failed() {
0199 return MakeMatcher(new detail::ErrorMatchesMono<InfoT>(std::nullopt));
0200 }
0201
0202 template <typename InfoT, typename M>
0203 testing::Matcher<const detail::ErrorHolder &> Failed(M Matcher) {
0204 return MakeMatcher(new detail::ErrorMatchesMono<InfoT>(
0205 testing::SafeMatcherCast<InfoT &>(Matcher)));
0206 }
0207
0208 template <typename... M>
0209 testing::Matcher<const detail::ErrorHolder &> FailedWithMessage(M... Matcher) {
0210 static_assert(sizeof...(M) > 0);
0211 return MakeMatcher(
0212 new detail::ErrorMessageMatches(testing::ElementsAre(Matcher...)));
0213 }
0214
0215 template <typename M>
0216 testing::Matcher<const detail::ErrorHolder &> FailedWithMessageArray(M Matcher) {
0217 return MakeMatcher(new detail::ErrorMessageMatches(Matcher));
0218 }
0219
0220 template <typename M>
0221 detail::ValueMatchesPoly<M> HasValue(M Matcher) {
0222 return detail::ValueMatchesPoly<M>(Matcher);
0223 }
0224
0225 }
0226
0227 #endif