1 //===- llvm/Testing/Support/Error.h ---------------------------------------===//
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
7 //===----------------------------------------------------------------------===//
9 #ifndef LLVM_TESTING_SUPPORT_ERROR_H
10 #define LLVM_TESTING_SUPPORT_ERROR_H
12 #include "llvm/ADT/Optional.h"
13 #include "llvm/Support/Error.h"
14 #include "llvm/Testing/Support/SupportHelpers.h"
16 #include "gmock/gmock.h"
21 ErrorHolder
TakeError(Error Err
);
23 template <typename T
> ExpectedHolder
<T
> TakeExpected(Expected
<T
> &Exp
) {
24 return {TakeError(Exp
.takeError()), Exp
};
27 template <typename T
> ExpectedHolder
<T
> TakeExpected(Expected
<T
> &&Exp
) {
28 return TakeExpected(Exp
);
32 class ValueMatchesMono
33 : public testing::MatcherInterface
<const ExpectedHolder
<T
> &> {
35 explicit ValueMatchesMono(const testing::Matcher
<T
> &Matcher
)
38 bool MatchAndExplain(const ExpectedHolder
<T
> &Holder
,
39 testing::MatchResultListener
*listener
) const override
{
40 if (!Holder
.Success())
43 bool result
= Matcher
.MatchAndExplain(*Holder
.Exp
, listener
);
48 Matcher
.DescribeNegationTo(listener
->stream());
53 void DescribeTo(std::ostream
*OS
) const override
{
54 *OS
<< "succeeded with value (";
55 Matcher
.DescribeTo(OS
);
59 void DescribeNegationTo(std::ostream
*OS
) const override
{
60 *OS
<< "did not succeed or value (";
61 Matcher
.DescribeNegationTo(OS
);
66 testing::Matcher
<T
> Matcher
;
70 class ValueMatchesPoly
{
72 explicit ValueMatchesPoly(const M
&Matcher
) : Matcher(Matcher
) {}
75 operator testing::Matcher
<const ExpectedHolder
<T
> &>() const {
77 new ValueMatchesMono
<T
>(testing::SafeMatcherCast
<T
>(Matcher
)));
84 template <typename InfoT
>
85 class ErrorMatchesMono
: public testing::MatcherInterface
<const ErrorHolder
&> {
87 explicit ErrorMatchesMono(Optional
<testing::Matcher
<InfoT
&>> Matcher
)
88 : Matcher(std::move(Matcher
)) {}
90 bool MatchAndExplain(const ErrorHolder
&Holder
,
91 testing::MatchResultListener
*listener
) const override
{
95 if (Holder
.Infos
.size() > 1) {
96 *listener
<< "multiple errors";
100 auto &Info
= *Holder
.Infos
[0];
101 if (!Info
.isA
<InfoT
>()) {
102 *listener
<< "Error was not of given type";
109 return Matcher
->MatchAndExplain(static_cast<InfoT
&>(Info
), listener
);
112 void DescribeTo(std::ostream
*OS
) const override
{
113 *OS
<< "failed with Error of given type";
115 *OS
<< " and the error ";
116 Matcher
->DescribeTo(OS
);
120 void DescribeNegationTo(std::ostream
*OS
) const override
{
121 *OS
<< "succeeded or did not fail with the error of given type";
123 *OS
<< " or the error ";
124 Matcher
->DescribeNegationTo(OS
);
129 Optional
<testing::Matcher
<InfoT
&>> Matcher
;
131 } // namespace detail
133 #define EXPECT_THAT_ERROR(Err, Matcher) \
134 EXPECT_THAT(llvm::detail::TakeError(Err), Matcher)
135 #define ASSERT_THAT_ERROR(Err, Matcher) \
136 ASSERT_THAT(llvm::detail::TakeError(Err), Matcher)
138 #define EXPECT_THAT_EXPECTED(Err, Matcher) \
139 EXPECT_THAT(llvm::detail::TakeExpected(Err), Matcher)
140 #define ASSERT_THAT_EXPECTED(Err, Matcher) \
141 ASSERT_THAT(llvm::detail::TakeExpected(Err), Matcher)
143 MATCHER(Succeeded
, "") { return arg
.Success(); }
144 MATCHER(Failed
, "") { return !arg
.Success(); }
146 template <typename InfoT
>
147 testing::Matcher
<const detail::ErrorHolder
&> Failed() {
148 return MakeMatcher(new detail::ErrorMatchesMono
<InfoT
>(None
));
151 template <typename InfoT
, typename M
>
152 testing::Matcher
<const detail::ErrorHolder
&> Failed(M Matcher
) {
153 return MakeMatcher(new detail::ErrorMatchesMono
<InfoT
>(
154 testing::SafeMatcherCast
<InfoT
&>(Matcher
)));
157 template <typename M
>
158 detail::ValueMatchesPoly
<M
> HasValue(M Matcher
) {
159 return detail::ValueMatchesPoly
<M
>(Matcher
);