Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-05-10 08:44:37

0001 //===- llvm/Testing/Support/Error.h ---------------------------------------===//
0002 //
0003 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
0004 // See https://llvm.org/LICENSE.txt for license information.
0005 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
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 } // namespace detail
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 /// Helper macro for checking the result of an 'Expected<T>'
0169 ///
0170 ///   @code{.cpp}
0171 ///     // function to be tested
0172 ///     Expected<int> myDivide(int A, int B);
0173 ///
0174 ///     TEST(myDivideTests, GoodAndBad) {
0175 ///       // test good case
0176 ///       // if you only care about success or failure:
0177 ///       EXPECT_THAT_EXPECTED(myDivide(10, 5), Succeeded());
0178 ///       // if you also care about the value:
0179 ///       EXPECT_THAT_EXPECTED(myDivide(10, 5), HasValue(2));
0180 ///
0181 ///       // test the error case
0182 ///       EXPECT_THAT_EXPECTED(myDivide(10, 0), Failed());
0183 ///       // also check the error message
0184 ///       EXPECT_THAT_EXPECTED(myDivide(10, 0),
0185 ///           FailedWithMessage("B must not be zero!"));
0186 ///     }
0187 ///   @endcode
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 } // namespace llvm
0226 
0227 #endif