Subversion Repositories QNX 8.QNX8 LLVM/Clang compiler suite

Rev

Blame | Last modification | View Log | Download | RSS feed

  1. //===- llvm/Testing/Support/Error.h ---------------------------------------===//
  2. //
  3. // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  4. // See https://llvm.org/LICENSE.txt for license information.
  5. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  6. //
  7. //===----------------------------------------------------------------------===//
  8.  
  9. #ifndef LLVM_TESTING_SUPPORT_ERROR_H
  10. #define LLVM_TESTING_SUPPORT_ERROR_H
  11.  
  12. #include "llvm/Support/Error.h"
  13. #include "llvm/Testing/Support/SupportHelpers.h"
  14.  
  15. #include "gmock/gmock.h"
  16. #include <ostream>
  17.  
  18. namespace llvm {
  19. namespace detail {
  20. ErrorHolder TakeError(Error Err);
  21.  
  22. template <typename T> ExpectedHolder<T> TakeExpected(Expected<T> &Exp) {
  23.   return {TakeError(Exp.takeError()), Exp};
  24. }
  25.  
  26. template <typename T> ExpectedHolder<T> TakeExpected(Expected<T> &&Exp) {
  27.   return TakeExpected(Exp);
  28. }
  29.  
  30. template <typename T>
  31. class ValueMatchesMono
  32.     : public testing::MatcherInterface<const ExpectedHolder<T> &> {
  33. public:
  34.   explicit ValueMatchesMono(const testing::Matcher<T> &Matcher)
  35.       : Matcher(Matcher) {}
  36.  
  37.   bool MatchAndExplain(const ExpectedHolder<T> &Holder,
  38.                        testing::MatchResultListener *listener) const override {
  39.     if (!Holder.Success())
  40.       return false;
  41.  
  42.     bool result = Matcher.MatchAndExplain(*Holder.Exp, listener);
  43.  
  44.     if (result || !listener->IsInterested())
  45.       return result;
  46.     *listener << "(";
  47.     Matcher.DescribeNegationTo(listener->stream());
  48.     *listener << ")";
  49.     return result;
  50.   }
  51.  
  52.   void DescribeTo(std::ostream *OS) const override {
  53.     *OS << "succeeded with value (";
  54.     Matcher.DescribeTo(OS);
  55.     *OS << ")";
  56.   }
  57.  
  58.   void DescribeNegationTo(std::ostream *OS) const override {
  59.     *OS << "did not succeed or value (";
  60.     Matcher.DescribeNegationTo(OS);
  61.     *OS << ")";
  62.   }
  63.  
  64. private:
  65.   testing::Matcher<T> Matcher;
  66. };
  67.  
  68. template<typename M>
  69. class ValueMatchesPoly {
  70. public:
  71.   explicit ValueMatchesPoly(const M &Matcher) : Matcher(Matcher) {}
  72.  
  73.   template <typename T>
  74.   operator testing::Matcher<const ExpectedHolder<T> &>() const {
  75.     return MakeMatcher(
  76.         new ValueMatchesMono<T>(testing::SafeMatcherCast<T>(Matcher)));
  77.   }
  78.  
  79. private:
  80.   M Matcher;
  81. };
  82.  
  83. template <typename InfoT>
  84. class ErrorMatchesMono : public testing::MatcherInterface<const ErrorHolder &> {
  85. public:
  86.   explicit ErrorMatchesMono(std::optional<testing::Matcher<InfoT &>> Matcher)
  87.       : Matcher(std::move(Matcher)) {}
  88.  
  89.   bool MatchAndExplain(const ErrorHolder &Holder,
  90.                        testing::MatchResultListener *listener) const override {
  91.     if (Holder.Success())
  92.       return false;
  93.  
  94.     if (Holder.Infos.size() > 1) {
  95.       *listener << "multiple errors";
  96.       return false;
  97.     }
  98.  
  99.     auto &Info = *Holder.Infos[0];
  100.     if (!Info.isA<InfoT>()) {
  101.       *listener << "Error was not of given type";
  102.       return false;
  103.     }
  104.  
  105.     if (!Matcher)
  106.       return true;
  107.  
  108.     return Matcher->MatchAndExplain(static_cast<InfoT &>(Info), listener);
  109.   }
  110.  
  111.   void DescribeTo(std::ostream *OS) const override {
  112.     *OS << "failed with Error of given type";
  113.     if (Matcher) {
  114.       *OS << " and the error ";
  115.       Matcher->DescribeTo(OS);
  116.     }
  117.   }
  118.  
  119.   void DescribeNegationTo(std::ostream *OS) const override {
  120.     *OS << "succeeded or did not fail with the error of given type";
  121.     if (Matcher) {
  122.       *OS << " or the error ";
  123.       Matcher->DescribeNegationTo(OS);
  124.     }
  125.   }
  126.  
  127. private:
  128.   std::optional<testing::Matcher<InfoT &>> Matcher;
  129. };
  130.  
  131. class ErrorMessageMatches
  132.     : public testing::MatcherInterface<const ErrorHolder &> {
  133. public:
  134.   explicit ErrorMessageMatches(
  135.       testing::Matcher<std::vector<std::string>> Matcher)
  136.       : Matcher(std::move(Matcher)) {}
  137.  
  138.   bool MatchAndExplain(const ErrorHolder &Holder,
  139.                        testing::MatchResultListener *listener) const override {
  140.     std::vector<std::string> Messages;
  141.     Messages.reserve(Holder.Infos.size());
  142.     for (const std::shared_ptr<ErrorInfoBase> &Info : Holder.Infos)
  143.       Messages.push_back(Info->message());
  144.  
  145.     return Matcher.MatchAndExplain(Messages, listener);
  146.   }
  147.  
  148.   void DescribeTo(std::ostream *OS) const override {
  149.     *OS << "failed with Error whose message ";
  150.     Matcher.DescribeTo(OS);
  151.   }
  152.  
  153.   void DescribeNegationTo(std::ostream *OS) const override {
  154.     *OS << "failed with an Error whose message ";
  155.     Matcher.DescribeNegationTo(OS);
  156.   }
  157.  
  158. private:
  159.   testing::Matcher<std::vector<std::string>> Matcher;
  160. };
  161. } // namespace detail
  162.  
  163. #define EXPECT_THAT_ERROR(Err, Matcher)                                        \
  164.   EXPECT_THAT(llvm::detail::TakeError(Err), Matcher)
  165. #define ASSERT_THAT_ERROR(Err, Matcher)                                        \
  166.   ASSERT_THAT(llvm::detail::TakeError(Err), Matcher)
  167.  
  168. /// Helper macro for checking the result of an 'Expected<T>'
  169. ///
  170. ///   @code{.cpp}
  171. ///     // function to be tested
  172. ///     Expected<int> myDivide(int A, int B);
  173. ///
  174. ///     TEST(myDivideTests, GoodAndBad) {
  175. ///       // test good case
  176. ///       // if you only care about success or failure:
  177. ///       EXPECT_THAT_EXPECTED(myDivide(10, 5), Succeeded());
  178. ///       // if you also care about the value:
  179. ///       EXPECT_THAT_EXPECTED(myDivide(10, 5), HasValue(2));
  180. ///
  181. ///       // test the error case
  182. ///       EXPECT_THAT_EXPECTED(myDivide(10, 0), Failed());
  183. ///       // also check the error message
  184. ///       EXPECT_THAT_EXPECTED(myDivide(10, 0),
  185. ///           FailedWithMessage("B must not be zero!"));
  186. ///     }
  187. ///   @endcode
  188.  
  189. #define EXPECT_THAT_EXPECTED(Err, Matcher)                                     \
  190.   EXPECT_THAT(llvm::detail::TakeExpected(Err), Matcher)
  191. #define ASSERT_THAT_EXPECTED(Err, Matcher)                                     \
  192.   ASSERT_THAT(llvm::detail::TakeExpected(Err), Matcher)
  193.  
  194. MATCHER(Succeeded, "") { return arg.Success(); }
  195. MATCHER(Failed, "") { return !arg.Success(); }
  196.  
  197. template <typename InfoT>
  198. testing::Matcher<const detail::ErrorHolder &> Failed() {
  199.   return MakeMatcher(new detail::ErrorMatchesMono<InfoT>(std::nullopt));
  200. }
  201.  
  202. template <typename InfoT, typename M>
  203. testing::Matcher<const detail::ErrorHolder &> Failed(M Matcher) {
  204.   return MakeMatcher(new detail::ErrorMatchesMono<InfoT>(
  205.       testing::SafeMatcherCast<InfoT &>(Matcher)));
  206. }
  207.  
  208. template <typename... M>
  209. testing::Matcher<const detail::ErrorHolder &> FailedWithMessage(M... Matcher) {
  210.   static_assert(sizeof...(M) > 0);
  211.   return MakeMatcher(
  212.       new detail::ErrorMessageMatches(testing::ElementsAre(Matcher...)));
  213. }
  214.  
  215. template <typename M>
  216. testing::Matcher<const detail::ErrorHolder &> FailedWithMessageArray(M Matcher) {
  217.   return MakeMatcher(new detail::ErrorMessageMatches(Matcher));
  218. }
  219.  
  220. template <typename M>
  221. detail::ValueMatchesPoly<M> HasValue(M Matcher) {
  222.   return detail::ValueMatchesPoly<M>(Matcher);
  223. }
  224.  
  225. } // namespace llvm
  226.  
  227. #endif
  228.