14#ifndef OR_TOOLS_BASE_STATUS_MATCHERS_H_
15#define OR_TOOLS_BASE_STATUS_MATCHERS_H_
21#include "absl/status/status.h"
22#include "absl/status/statusor.h"
23#include "absl/strings/str_cat.h"
24#include "gmock/gmock-matchers.h"
28inline const ::absl::Status&
GetStatus(const ::absl::Status& status) {
33inline const ::absl::Status&
GetStatus(const ::absl::StatusOr<T>& status) {
41template <
typename StatusOrType>
43 :
public ::testing::MatcherInterface<StatusOrType> {
46 typename std::remove_reference<StatusOrType>::type::value_type;
48 template <
typename InnerMatcher>
51 std::forward<InnerMatcher>(inner_matcher))) {}
54 *os <<
"is OK and has a value that ";
55 inner_matcher_.DescribeTo(os);
59 *os <<
"is not OK or has a value that ";
60 inner_matcher_.DescribeNegationTo(os);
64 StatusOrType actual_value,
65 ::testing::MatchResultListener* result_listener)
const override {
66 if (!actual_value.ok()) {
67 *result_listener <<
"which has status " << actual_value.status();
71 ::testing::StringMatchResultListener inner_listener;
73 inner_matcher_.MatchAndExplain(*actual_value, &inner_listener);
74 const std::string inner_explanation = inner_listener.str();
75 if (!inner_explanation.empty()) {
76 *result_listener <<
"which contains value "
77 << ::testing::PrintToString(*actual_value) <<
", "
84 const ::testing::Matcher<const value_type&> inner_matcher_;
88template <
typename InnerMatcher>
92 : inner_matcher_(
std::move(inner_matcher)) {}
97 template <
typename StatusOrType>
98 operator ::testing::Matcher<StatusOrType>()
const {
99 return ::testing::Matcher<StatusOrType>(
104 const InnerMatcher inner_matcher_;
111template <
typename InnerMatcher>
112internal::IsOkAndHoldsMatcher<typename std::decay<InnerMatcher>::type>
115 std::forward<InnerMatcher>(inner_matcher));
125class MonoIsOkMatcherImpl :
public ::testing::MatcherInterface<T> {
127 void DescribeTo(std::ostream* os)
const override { *os <<
"is OK"; }
132 ::testing::MatchResultListener*)
const override {
140 template <
typename T>
141 operator ::testing::Matcher<T>()
const {
148inline internal::IsOkMatcher
IsOk() {
return internal::IsOkMatcher(); }
158class StatusIsMatcherCommonImpl {
161 ::testing::Matcher<const absl::StatusCode> code_matcher,
162 ::testing::Matcher<const std::string&> message_matcher)
163 : code_matcher_(
std::move(code_matcher)),
164 message_matcher_(
std::move(message_matcher)) {}
167 *os <<
"has a status code that ";
168 code_matcher_.DescribeTo(os);
169 *os <<
", and has an error message that ";
170 message_matcher_.DescribeTo(os);
174 *os <<
"has a status code that ";
175 code_matcher_.DescribeNegationTo(os);
176 *os <<
", or has an error message that ";
177 message_matcher_.DescribeNegationTo(os);
181 ::testing::MatchResultListener* result_listener)
const {
182 ::testing::StringMatchResultListener inner_listener;
184 inner_listener.Clear();
185 if (!code_matcher_.MatchAndExplain(
status.code(), &inner_listener)) {
186 *result_listener << (inner_listener.str().empty()
187 ?
"whose status code is wrong"
188 :
"which has a status code " +
189 inner_listener.str());
193 if (!message_matcher_.Matches(std::string(
status.message()))) {
194 *result_listener <<
"whose error message is wrong";
202 const ::testing::Matcher<const absl::StatusCode> code_matcher_;
203 const ::testing::Matcher<const std::string&> message_matcher_;
209class MonoStatusIsMatcherImpl :
public ::testing::MatcherInterface<T> {
212 : common_impl_(
std::move(common_impl)) {}
214 void DescribeTo(std::ostream* os)
const override {
224 ::testing::MatchResultListener* result_listener)
const override {
234class StatusIsMatcher {
237 ::testing::Matcher<const std::string&> message_matcher)
239 ::
testing::MatcherCast<const
absl::StatusCode>(code_matcher),
240 ::
testing::MatcherCast<const
std::string&>(message_matcher)) {}
244 template <
typename T>
245 operator ::testing::Matcher<T>()
const {
250 const StatusIsMatcherCommonImpl common_impl_;
256template <
typename CodeMatcher,
typename MessageMatcher>
257internal::StatusIsMatcher
StatusIs(CodeMatcher code_matcher,
258 MessageMatcher message_matcher) {
260 std::move(message_matcher));
265template <
typename CodeMatcher>
266internal::StatusIsMatcher
StatusIs(CodeMatcher code_matcher) {
267 return StatusIs(std::move(code_matcher), ::testing::_);
274#define EXPECT_OK(expression) EXPECT_THAT(expression, ::testing::status::IsOk())
275#define ASSERT_OK(expression) ASSERT_THAT(expression, ::testing::status::IsOk())
277#define STATUS_MATCHERS_IMPL_CONCAT_INNER_(x, y) x##y
278#define STATUS_MATCHERS_IMPL_CONCAT_(x, y) \
279 STATUS_MATCHERS_IMPL_CONCAT_INNER_(x, y)
281#undef ASSERT_OK_AND_ASSIGN
282#define ASSERT_OK_AND_ASSIGN(lhs, rexpr) \
283 ASSERT_OK_AND_ASSIGN_IMPL_( \
284 STATUS_MATCHERS_IMPL_CONCAT_(_status_or_value, __COUNTER__), lhs, rexpr)
286#define ASSERT_OK_AND_ASSIGN_IMPL_(statusor, lhs, rexpr) \
287 auto statusor = (rexpr); \
288 ASSERT_TRUE(statusor.ok()) << statusor.status(); \
289 lhs = std::move(statusor.value())
IsOkAndHoldsMatcherImpl(InnerMatcher &&inner_matcher)
typename std::remove_reference< StatusOrType >::type::value_type value_type
void DescribeNegationTo(std::ostream *os) const override
void DescribeTo(std::ostream *os) const override
bool MatchAndExplain(StatusOrType actual_value, ::testing::MatchResultListener *result_listener) const override
Implements IsOkAndHolds(m) as a polymorphic matcher.
IsOkAndHoldsMatcher(InnerMatcher inner_matcher)
void DescribeNegationTo(std::ostream *os) const override
void DescribeTo(std::ostream *os) const override
bool MatchAndExplain(T actual_value, ::testing::MatchResultListener *) const override
void DescribeNegationTo(std::ostream *os) const override
bool MatchAndExplain(T actual_value, ::testing::MatchResultListener *result_listener) const override
MonoStatusIsMatcherImpl(StatusIsMatcherCommonImpl common_impl)
void DescribeTo(std::ostream *os) const override
void DescribeNegationTo(std::ostream *os) const
void DescribeTo(std::ostream *os) const
bool MatchAndExplain(const absl::Status &status, ::testing::MatchResultListener *result_listener) const
StatusIsMatcherCommonImpl(::testing::Matcher< const absl::StatusCode > code_matcher, ::testing::Matcher< const std::string & > message_matcher)
Implements StatusIs() as a polymorphic matcher.
StatusIsMatcher(::testing::Matcher< const absl::StatusCode > code_matcher, ::testing::Matcher< const std::string & > message_matcher)
internal::IsOkMatcher IsOk()
Returns a gMock matcher that matches a Status or StatusOr<> which is OK.
const ::absl::Status & GetStatus(const ::absl::Status &status)
internal::StatusIsMatcher StatusIs(CodeMatcher code_matcher, MessageMatcher message_matcher)
internal::IsOkAndHoldsMatcher< typename std::decay< InnerMatcher >::type > IsOkAndHolds(InnerMatcher &&inner_matcher)