Error.h 6.8 KB

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