@@ -48,43 +48,68 @@ class IsError {
48
48
::testing::Matcher<std::string> matcher_;
49
49
};
50
50
51
- // Matches the value for a non-error state of `ErrorOr<T>`. For example:
52
- // EXPECT_THAT(my_result, IsSuccess(Eq(3)));
53
- template <typename InnerMatcher>
54
- class IsSuccessMatcher {
51
+ // Implementation of a success matcher for a specific `T` and `ErrorT` in an
52
+ // `ErrorOr`. Supports a nested matcher for the `T` value.
53
+ template <typename T, typename ErrorT>
54
+ class IsSuccessMatcherImpl
55
+ : public ::testing::MatcherInterface<const ErrorOr<T, ErrorT>&> {
55
56
public:
56
- // NOLINTNEXTLINE(readability-identifier-naming)
57
- using is_gtest_matcher = void ;
58
-
59
- explicit IsSuccessMatcher (InnerMatcher matcher)
60
- : matcher_(std::move(matcher)) {}
57
+ explicit IsSuccessMatcherImpl (const ::testing::Matcher<T>& matcher)
58
+ : matcher_(matcher) {}
61
59
62
- template <typename T, typename ErrorT>
63
60
auto MatchAndExplain (const ErrorOr<T, ErrorT>& result,
64
- ::testing::MatchResultListener* listener) const -> bool {
61
+ ::testing::MatchResultListener* listener) const
62
+ -> bool override {
65
63
if (result.ok ()) {
66
- return ::testing::Matcher<T>( matcher_) .MatchAndExplain (*result, listener);
64
+ return matcher_.MatchAndExplain (*result, listener);
67
65
} else {
68
66
*listener << " is an error with `" << result.error () << " `" ;
69
67
return false ;
70
68
}
71
69
}
72
70
73
- auto DescribeTo (std::ostream* os) const -> void {
71
+ auto DescribeTo (std::ostream* os) const -> void override {
74
72
*os << " is a success and matches " ;
75
73
matcher_.DescribeTo (os);
76
74
}
77
75
78
- auto DescribeNegationTo (std::ostream* os) const -> void {
76
+ auto DescribeNegationTo (std::ostream* os) const -> void override {
79
77
*os << " is an error or does not match " ;
80
- matcher_.DescribeTo (os);
78
+ matcher_.DescribeNegationTo (os);
79
+ }
80
+
81
+ private:
82
+ ::testing::Matcher<T> matcher_;
83
+ };
84
+
85
+ // Polymorphic match implementation for GoogleTest.
86
+ //
87
+ // To support matching arbitrary types that `InnerMatcher` can also match, this
88
+ // itself must match arbitrary types. This is accomplished by not being a
89
+ // matcher itself, but by being convertible into matchers for any particular
90
+ // `ErrorOr`.
91
+ template <typename InnerMatcher>
92
+ class IsSuccessMatcher {
93
+ public:
94
+ explicit IsSuccessMatcher (InnerMatcher matcher)
95
+ : matcher_(std::move(matcher)) {}
96
+
97
+ template <typename T, typename ErrorT>
98
+ // NOLINTNEXTLINE(google-explicit-constructor): Required for matcher APIs.
99
+ operator ::testing::Matcher<const ErrorOr<T, ErrorT>&>() const {
100
+ return ::testing::Matcher<const ErrorOr<T, ErrorT>&>(
101
+ new IsSuccessMatcherImpl<T, ErrorT>(
102
+ ::testing::SafeMatcherCast<T>(matcher_)));
81
103
}
82
104
83
105
private:
84
106
InnerMatcher matcher_;
85
107
};
86
108
87
- // Wraps `IsSuccessMatcher` for the inner matcher deduction.
109
+ // Returns a matcher the value for a non-error state of `ErrorOr<T>`.
110
+ //
111
+ // For example:
112
+ // EXPECT_THAT(my_result, IsSuccess(Eq(3)));
88
113
template <typename InnerMatcher>
89
114
auto IsSuccess (InnerMatcher matcher) -> IsSuccessMatcher<InnerMatcher> {
90
115
return IsSuccessMatcher<InnerMatcher>(matcher);
0 commit comments