File indexing completed on 2025-01-31 09:33:36
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015 #ifndef ABSL_STATUS_INTERNAL_STATUS_MATCHERS_H_
0016 #define ABSL_STATUS_INTERNAL_STATUS_MATCHERS_H_
0017
0018 #include <ostream> // NOLINT
0019 #include <string>
0020 #include <type_traits>
0021 #include <utility>
0022
0023 #include "gmock/gmock.h" // gmock_for_status_matchers.h
0024 #include "absl/base/config.h"
0025 #include "absl/status/status.h"
0026 #include "absl/status/statusor.h"
0027 #include "absl/strings/string_view.h"
0028
0029 namespace absl_testing {
0030 ABSL_NAMESPACE_BEGIN
0031 namespace status_internal {
0032
0033 inline const absl::Status& GetStatus(const absl::Status& status) {
0034 return status;
0035 }
0036
0037 template <typename T>
0038 inline const absl::Status& GetStatus(const absl::StatusOr<T>& status) {
0039 return status.status();
0040 }
0041
0042
0043
0044
0045
0046
0047 template <typename StatusOrType>
0048 class IsOkAndHoldsMatcherImpl
0049 : public ::testing::MatcherInterface<StatusOrType> {
0050 public:
0051 typedef
0052 typename std::remove_reference<StatusOrType>::type::value_type value_type;
0053
0054 template <typename InnerMatcher>
0055 explicit IsOkAndHoldsMatcherImpl(InnerMatcher&& inner_matcher)
0056 : inner_matcher_(::testing::SafeMatcherCast<const value_type&>(
0057 std::forward<InnerMatcher>(inner_matcher))) {}
0058
0059 void DescribeTo(std::ostream* os) const override {
0060 *os << "is OK and has a value that ";
0061 inner_matcher_.DescribeTo(os);
0062 }
0063
0064 void DescribeNegationTo(std::ostream* os) const override {
0065 *os << "isn't OK or has a value that ";
0066 inner_matcher_.DescribeNegationTo(os);
0067 }
0068
0069 bool MatchAndExplain(
0070 StatusOrType actual_value,
0071 ::testing::MatchResultListener* result_listener) const override {
0072 if (!GetStatus(actual_value).ok()) {
0073 *result_listener << "which has status " << GetStatus(actual_value);
0074 return false;
0075 }
0076
0077
0078 return inner_matcher_.MatchAndExplain(*actual_value, result_listener);
0079 }
0080
0081 private:
0082 const ::testing::Matcher<const value_type&> inner_matcher_;
0083 };
0084
0085
0086 template <typename InnerMatcher>
0087 class IsOkAndHoldsMatcher {
0088 public:
0089 explicit IsOkAndHoldsMatcher(InnerMatcher inner_matcher)
0090 : inner_matcher_(std::forward<InnerMatcher>(inner_matcher)) {}
0091
0092
0093
0094
0095 template <typename StatusOrType>
0096 operator ::testing::Matcher<StatusOrType>() const {
0097 return ::testing::Matcher<StatusOrType>(
0098 new IsOkAndHoldsMatcherImpl<const StatusOrType&>(inner_matcher_));
0099 }
0100
0101 private:
0102 const InnerMatcher inner_matcher_;
0103 };
0104
0105
0106
0107
0108
0109
0110
0111
0112
0113
0114
0115
0116
0117
0118 class StatusCode {
0119 public:
0120 StatusCode(int code)
0121 : code_(static_cast<::absl::StatusCode>(code)) {}
0122 StatusCode(::absl::StatusCode code) : code_(code) {}
0123
0124 explicit operator int() const { return static_cast<int>(code_); }
0125
0126 friend inline void PrintTo(const StatusCode& code, std::ostream* os) {
0127
0128 *os << static_cast<int>(code);
0129 }
0130
0131 private:
0132 ::absl::StatusCode code_;
0133 };
0134
0135
0136 inline bool operator==(const StatusCode& lhs, const StatusCode& rhs) {
0137 return static_cast<int>(lhs) == static_cast<int>(rhs);
0138 }
0139 inline bool operator!=(const StatusCode& lhs, const StatusCode& rhs) {
0140 return static_cast<int>(lhs) != static_cast<int>(rhs);
0141 }
0142
0143
0144
0145
0146 class StatusIsMatcherCommonImpl {
0147 public:
0148 StatusIsMatcherCommonImpl(
0149 ::testing::Matcher<StatusCode> code_matcher,
0150 ::testing::Matcher<absl::string_view> message_matcher)
0151 : code_matcher_(std::move(code_matcher)),
0152 message_matcher_(std::move(message_matcher)) {}
0153
0154 void DescribeTo(std::ostream* os) const;
0155
0156 void DescribeNegationTo(std::ostream* os) const;
0157
0158 bool MatchAndExplain(const absl::Status& status,
0159 ::testing::MatchResultListener* result_listener) const;
0160
0161 private:
0162 const ::testing::Matcher<StatusCode> code_matcher_;
0163 const ::testing::Matcher<absl::string_view> message_matcher_;
0164 };
0165
0166
0167
0168 template <typename T>
0169 class MonoStatusIsMatcherImpl : public ::testing::MatcherInterface<T> {
0170 public:
0171 explicit MonoStatusIsMatcherImpl(StatusIsMatcherCommonImpl common_impl)
0172 : common_impl_(std::move(common_impl)) {}
0173
0174 void DescribeTo(std::ostream* os) const override {
0175 common_impl_.DescribeTo(os);
0176 }
0177
0178 void DescribeNegationTo(std::ostream* os) const override {
0179 common_impl_.DescribeNegationTo(os);
0180 }
0181
0182 bool MatchAndExplain(
0183 T actual_value,
0184 ::testing::MatchResultListener* result_listener) const override {
0185 return common_impl_.MatchAndExplain(GetStatus(actual_value),
0186 result_listener);
0187 }
0188
0189 private:
0190 StatusIsMatcherCommonImpl common_impl_;
0191 };
0192
0193
0194 class StatusIsMatcher {
0195 public:
0196 template <typename StatusCodeMatcher, typename StatusMessageMatcher>
0197 StatusIsMatcher(StatusCodeMatcher&& code_matcher,
0198 StatusMessageMatcher&& message_matcher)
0199 : common_impl_(::testing::MatcherCast<StatusCode>(
0200 std::forward<StatusCodeMatcher>(code_matcher)),
0201 ::testing::MatcherCast<absl::string_view>(
0202 std::forward<StatusMessageMatcher>(message_matcher))) {
0203 }
0204
0205
0206
0207
0208 template <typename T>
0209 operator ::testing::Matcher<T>() const {
0210 return ::testing::Matcher<T>(
0211 new MonoStatusIsMatcherImpl<const T&>(common_impl_));
0212 }
0213
0214 private:
0215 const StatusIsMatcherCommonImpl common_impl_;
0216 };
0217
0218
0219
0220 template <typename T>
0221 class MonoIsOkMatcherImpl : public ::testing::MatcherInterface<T> {
0222 public:
0223 void DescribeTo(std::ostream* os) const override { *os << "is OK"; }
0224 void DescribeNegationTo(std::ostream* os) const override {
0225 *os << "is not OK";
0226 }
0227 bool MatchAndExplain(T actual_value,
0228 ::testing::MatchResultListener*) const override {
0229 return GetStatus(actual_value).ok();
0230 }
0231 };
0232
0233
0234 class IsOkMatcher {
0235 public:
0236 template <typename T>
0237 operator ::testing::Matcher<T>() const {
0238 return ::testing::Matcher<T>(new MonoIsOkMatcherImpl<const T&>());
0239 }
0240 };
0241
0242 }
0243 ABSL_NAMESPACE_END
0244 }
0245
0246 #endif