#pragma once #include #include #include #include #include namespace testing { /* * This file contains gtest matchers for absl::Status. * * Example usage: * * EXPECT_OK(status); -- fails the test if 'status' is an error * ASSERT_OK(status); -- instantly fails the test if error * * using ::testing::IsStatusCode; * EXPECT_THAT(status, IsStatusCode(absl::StatusCode::kInternal)); */ namespace nix_internal { using ::testing::MakeMatcher; using ::testing::Matcher; using ::testing::MatcherInterface; using ::testing::MatchResultListener; MATCHER_P(IsStatusCode, code, "") { return arg.code() == code; } class StatusCodeMatcher { public: StatusCodeMatcher(absl::StatusCode code) : code_(code) {} // Match on absl::Status. template ::value, int>::type int_ = 0> bool MatchAndExplain(const T& status, MatchResultListener* /* listener */) const { return status.code() == code_; } // Match on absl::StatusOr. // // note: I check for the return value of ConsumeValueOrDie because it's the // only non-overloaded member I could figure out how to select. Checking for // the presence of .status() didn't work because it's overloaded, so // std::invoke_result can't pick which overload to use. template ::type, typename T::value_type>::value, int>::type int_ = 0> bool MatchAndExplain(const T& statusor, MatchResultListener* /* listener */) const { return statusor.status().code() == code_; } void DescribeTo(std::ostream* os) const { *os << "is " << code_; } void DescribeNegationTo(std::ostream* os) const { *os << "isn't " << code_; } private: absl::StatusCode code_; }; } // namespace nix_internal PolymorphicMatcher IsStatusCode( absl::StatusCode code) { return MakePolymorphicMatcher(nix_internal::StatusCodeMatcher(code)); } #define EXPECT_OK(status) \ EXPECT_THAT((status), testing::IsStatusCode(absl::StatusCode::kOk)) #define ASSERT_OK(status) \ ASSERT_THAT((status), testing::IsStatusCode(absl::StatusCode::kOk)) } // namespace testing