mirror of
https://github.com/abseil/abseil-cpp.git
synced 2026-06-04 12:07:05 +08:00
Add GoogleTest matchers for absl::Status
PiperOrigin-RevId: 630072639 Change-Id: Ibbb166cc3c0479617c8e48abe8134b59a67a578f
This commit is contained in:
committed by
Copybara-Service
parent
d94c7aefe7
commit
cba31a9562
@@ -609,6 +609,9 @@ set(ABSL_INTERNAL_TEST_DLL_FILES
|
||||
"random/internal/mock_overload_set.h"
|
||||
"random/mocking_bit_gen.h"
|
||||
"random/mock_distributions.h"
|
||||
"status/status_matchers.h"
|
||||
"status/internal/status_matchers.cc"
|
||||
"status/internal/status_matchers.h"
|
||||
"strings/cordz_test_helpers.h"
|
||||
"strings/cord_test_helpers.h"
|
||||
)
|
||||
@@ -621,6 +624,7 @@ set(ABSL_INTERNAL_TEST_DLL_TARGETS
|
||||
"random_internal_distribution_test_util"
|
||||
"random_internal_mock_overload_set"
|
||||
"scoped_mock_log"
|
||||
"status_matchers"
|
||||
)
|
||||
|
||||
include(CheckCXXSourceCompiles)
|
||||
|
||||
@@ -129,3 +129,38 @@ cc_test(
|
||||
"@com_google_googletest//:gtest_main",
|
||||
],
|
||||
)
|
||||
|
||||
cc_library(
|
||||
name = "status_matchers",
|
||||
testonly = 1,
|
||||
srcs = [
|
||||
"internal/status_matchers.cc",
|
||||
"internal/status_matchers.h",
|
||||
],
|
||||
hdrs = ["status_matchers.h"],
|
||||
copts = ABSL_DEFAULT_COPTS,
|
||||
linkopts = ABSL_DEFAULT_LINKOPTS,
|
||||
deps = [
|
||||
":status",
|
||||
":statusor",
|
||||
"//absl/base:config",
|
||||
"//absl/strings:string_view",
|
||||
"@com_google_googletest//:gtest",
|
||||
],
|
||||
)
|
||||
|
||||
cc_test(
|
||||
name = "status_matchers_test",
|
||||
size = "small",
|
||||
srcs = ["status_matchers_test.cc"],
|
||||
copts = ABSL_TEST_COPTS,
|
||||
linkopts = ABSL_DEFAULT_LINKOPTS,
|
||||
deps = [
|
||||
":status",
|
||||
":status_matchers",
|
||||
":statusor",
|
||||
"//absl/strings",
|
||||
"@com_google_googletest//:gtest",
|
||||
"@com_google_googletest//:gtest_main",
|
||||
],
|
||||
)
|
||||
|
||||
@@ -102,3 +102,40 @@ absl_cc_test(
|
||||
absl::strings
|
||||
GTest::gmock_main
|
||||
)
|
||||
|
||||
absl_cc_library(
|
||||
NAME
|
||||
status_matchers
|
||||
HDRS
|
||||
"status_matchers.h"
|
||||
SRCS
|
||||
"internal/status_matchers.h"
|
||||
"internal/status_matchers.cc"
|
||||
COPTS
|
||||
${ABSL_DEFAULT_COPTS}
|
||||
LINKOPTS
|
||||
${ABSL_DEFAULT_LINKOPTS}
|
||||
DEPS
|
||||
absl::base
|
||||
absl::status
|
||||
absl::statusor
|
||||
absl::strings
|
||||
GTest::gmock
|
||||
GTest::gtest
|
||||
PUBLIC
|
||||
TESTONLY
|
||||
)
|
||||
|
||||
absl_cc_test(
|
||||
NAME
|
||||
status_matchers_test
|
||||
SRCS
|
||||
"status_matchers_test.cc"
|
||||
COPTS
|
||||
${ABSL_TEST_COPTS}
|
||||
DEPS
|
||||
absl::status
|
||||
absl::statusor
|
||||
absl::status_matchers
|
||||
GTest::gmock_main
|
||||
)
|
||||
|
||||
68
absl/status/internal/status_matchers.cc
Normal file
68
absl/status/internal/status_matchers.cc
Normal file
@@ -0,0 +1,68 @@
|
||||
// Copyright 2024 The Abseil Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// https://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
// -----------------------------------------------------------------------------
|
||||
// File: status_matchers.cc
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
#include "absl/status/internal/status_matchers.h"
|
||||
|
||||
#include <ostream>
|
||||
#include <string>
|
||||
|
||||
#include "gmock/gmock.h"
|
||||
#include "absl/base/config.h"
|
||||
#include "absl/status/status.h"
|
||||
|
||||
namespace absl_testing {
|
||||
ABSL_NAMESPACE_BEGIN
|
||||
namespace status_internal {
|
||||
|
||||
void StatusIsMatcherCommonImpl::DescribeTo(std::ostream* os) const {
|
||||
*os << ", has a status code that ";
|
||||
code_matcher_.DescribeTo(os);
|
||||
*os << ", and has an error message that ";
|
||||
message_matcher_.DescribeTo(os);
|
||||
}
|
||||
|
||||
void StatusIsMatcherCommonImpl::DescribeNegationTo(std::ostream* os) const {
|
||||
*os << ", or has a status code that ";
|
||||
code_matcher_.DescribeNegationTo(os);
|
||||
*os << ", or has an error message that ";
|
||||
message_matcher_.DescribeNegationTo(os);
|
||||
}
|
||||
|
||||
bool StatusIsMatcherCommonImpl::MatchAndExplain(
|
||||
const ::absl::Status& status,
|
||||
::testing::MatchResultListener* result_listener) const {
|
||||
::testing::StringMatchResultListener inner_listener;
|
||||
if (!code_matcher_.MatchAndExplain(status.code(), &inner_listener)) {
|
||||
*result_listener << (inner_listener.str().empty()
|
||||
? "whose status code is wrong"
|
||||
: "which has a status code " +
|
||||
inner_listener.str());
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!message_matcher_.Matches(std::string(status.message()))) {
|
||||
*result_listener << "whose error message is wrong";
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace status_internal
|
||||
ABSL_NAMESPACE_END
|
||||
} // namespace absl_testing
|
||||
246
absl/status/internal/status_matchers.h
Normal file
246
absl/status/internal/status_matchers.h
Normal file
@@ -0,0 +1,246 @@
|
||||
// Copyright 2024 The Abseil Authors
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// https://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#ifndef ABSL_STATUS_INTERNAL_STATUS_MATCHERS_H_
|
||||
#define ABSL_STATUS_INTERNAL_STATUS_MATCHERS_H_
|
||||
|
||||
#include <ostream> // NOLINT
|
||||
#include <string>
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
|
||||
#include "gmock/gmock.h"
|
||||
#include "absl/base/config.h"
|
||||
#include "absl/status/status.h"
|
||||
#include "absl/status/statusor.h"
|
||||
#include "absl/strings/string_view.h"
|
||||
|
||||
namespace absl_testing {
|
||||
ABSL_NAMESPACE_BEGIN
|
||||
namespace status_internal {
|
||||
|
||||
inline const absl::Status& GetStatus(const absl::Status& status) {
|
||||
return status;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline const absl::Status& GetStatus(const absl::StatusOr<T>& status) {
|
||||
return status.status();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
// Implementation of IsOkAndHolds().
|
||||
|
||||
// Monomorphic implementation of matcher IsOkAndHolds(m). StatusOrType is a
|
||||
// reference to StatusOr<T>.
|
||||
template <typename StatusOrType>
|
||||
class IsOkAndHoldsMatcherImpl
|
||||
: public ::testing::MatcherInterface<StatusOrType> {
|
||||
public:
|
||||
typedef
|
||||
typename std::remove_reference<StatusOrType>::type::value_type value_type;
|
||||
|
||||
template <typename InnerMatcher>
|
||||
explicit IsOkAndHoldsMatcherImpl(InnerMatcher&& inner_matcher)
|
||||
: inner_matcher_(::testing::SafeMatcherCast<const value_type&>(
|
||||
std::forward<InnerMatcher>(inner_matcher))) {}
|
||||
|
||||
void DescribeTo(std::ostream* os) const override {
|
||||
*os << "is OK and has a value that ";
|
||||
inner_matcher_.DescribeTo(os);
|
||||
}
|
||||
|
||||
void DescribeNegationTo(std::ostream* os) const override {
|
||||
*os << "isn't OK or has a value that ";
|
||||
inner_matcher_.DescribeNegationTo(os);
|
||||
}
|
||||
|
||||
bool MatchAndExplain(
|
||||
StatusOrType actual_value,
|
||||
::testing::MatchResultListener* result_listener) const override {
|
||||
if (!actual_value.ok()) {
|
||||
*result_listener << "which has status " << actual_value.status();
|
||||
return false;
|
||||
}
|
||||
|
||||
// Call through to the inner matcher.
|
||||
return inner_matcher_.MatchAndExplain(*actual_value, result_listener);
|
||||
}
|
||||
|
||||
private:
|
||||
const ::testing::Matcher<const value_type&> inner_matcher_;
|
||||
};
|
||||
|
||||
// Implements IsOkAndHolds(m) as a polymorphic matcher.
|
||||
template <typename InnerMatcher>
|
||||
class IsOkAndHoldsMatcher {
|
||||
public:
|
||||
explicit IsOkAndHoldsMatcher(InnerMatcher inner_matcher)
|
||||
: inner_matcher_(std::forward<InnerMatcher>(inner_matcher)) {}
|
||||
|
||||
// Converts this polymorphic matcher to a monomorphic matcher of the
|
||||
// given type. StatusOrType can be either StatusOr<T> or a
|
||||
// reference to StatusOr<T>.
|
||||
template <typename StatusOrType>
|
||||
operator ::testing::Matcher<StatusOrType>() const { // NOLINT
|
||||
return ::testing::Matcher<StatusOrType>(
|
||||
new IsOkAndHoldsMatcherImpl<const StatusOrType&>(inner_matcher_));
|
||||
}
|
||||
|
||||
private:
|
||||
const InnerMatcher inner_matcher_;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
// Implementation of StatusIs().
|
||||
|
||||
// `StatusCode` is implicitly convertible from `int`, `absl::StatusCode`, and
|
||||
// is explicitly convertible to these types as well.
|
||||
//
|
||||
// We need this class because `absl::StatusCode` (as a scoped enum) is not
|
||||
// implicitly convertible to `int`. In order to handle use cases like
|
||||
// ```
|
||||
// StatusIs(Anyof(absl::StatusCode::kUnknown, absl::StatusCode::kCancelled))
|
||||
// ```
|
||||
// which uses polymorphic matchers, we need to unify the interfaces into
|
||||
// `Matcher<StatusCode>`.
|
||||
class StatusCode {
|
||||
public:
|
||||
/*implicit*/ StatusCode(int code) // NOLINT
|
||||
: code_(static_cast<::absl::StatusCode>(code)) {}
|
||||
/*implicit*/ StatusCode(::absl::StatusCode code) : code_(code) {} // NOLINT
|
||||
|
||||
explicit operator int() const { return static_cast<int>(code_); }
|
||||
|
||||
friend inline void PrintTo(const StatusCode& code, std::ostream* os) {
|
||||
// TODO(b/321095377): Change this to print the status code as a string.
|
||||
*os << static_cast<int>(code);
|
||||
}
|
||||
|
||||
private:
|
||||
::absl::StatusCode code_;
|
||||
};
|
||||
|
||||
// Relational operators to handle matchers like Eq, Lt, etc..
|
||||
inline bool operator==(const StatusCode& lhs, const StatusCode& rhs) {
|
||||
return static_cast<int>(lhs) == static_cast<int>(rhs);
|
||||
}
|
||||
inline bool operator!=(const StatusCode& lhs, const StatusCode& rhs) {
|
||||
return static_cast<int>(lhs) != static_cast<int>(rhs);
|
||||
}
|
||||
|
||||
// StatusIs() is a polymorphic matcher. This class is the common
|
||||
// implementation of it shared by all types T where StatusIs() can be
|
||||
// used as a Matcher<T>.
|
||||
class StatusIsMatcherCommonImpl {
|
||||
public:
|
||||
StatusIsMatcherCommonImpl(
|
||||
::testing::Matcher<StatusCode> code_matcher,
|
||||
::testing::Matcher<absl::string_view> message_matcher)
|
||||
: code_matcher_(std::move(code_matcher)),
|
||||
message_matcher_(std::move(message_matcher)) {}
|
||||
|
||||
void DescribeTo(std::ostream* os) const;
|
||||
|
||||
void DescribeNegationTo(std::ostream* os) const;
|
||||
|
||||
bool MatchAndExplain(const absl::Status& status,
|
||||
::testing::MatchResultListener* result_listener) const;
|
||||
|
||||
private:
|
||||
const ::testing::Matcher<StatusCode> code_matcher_;
|
||||
const ::testing::Matcher<absl::string_view> message_matcher_;
|
||||
};
|
||||
|
||||
// Monomorphic implementation of matcher StatusIs() for a given type
|
||||
// T. T can be Status, StatusOr<>, or a reference to either of them.
|
||||
template <typename T>
|
||||
class MonoStatusIsMatcherImpl : public ::testing::MatcherInterface<T> {
|
||||
public:
|
||||
explicit MonoStatusIsMatcherImpl(StatusIsMatcherCommonImpl common_impl)
|
||||
: common_impl_(std::move(common_impl)) {}
|
||||
|
||||
void DescribeTo(std::ostream* os) const override {
|
||||
common_impl_.DescribeTo(os);
|
||||
}
|
||||
|
||||
void DescribeNegationTo(std::ostream* os) const override {
|
||||
common_impl_.DescribeNegationTo(os);
|
||||
}
|
||||
|
||||
bool MatchAndExplain(
|
||||
T actual_value,
|
||||
::testing::MatchResultListener* result_listener) const override {
|
||||
return common_impl_.MatchAndExplain(GetStatus(actual_value),
|
||||
result_listener);
|
||||
}
|
||||
|
||||
private:
|
||||
StatusIsMatcherCommonImpl common_impl_;
|
||||
};
|
||||
|
||||
// Implements StatusIs() as a polymorphic matcher.
|
||||
class StatusIsMatcher {
|
||||
public:
|
||||
template <typename StatusCodeMatcher, typename StatusMessageMatcher>
|
||||
StatusIsMatcher(StatusCodeMatcher&& code_matcher,
|
||||
StatusMessageMatcher&& message_matcher)
|
||||
: common_impl_(::testing::MatcherCast<StatusCode>(
|
||||
std::forward<StatusCodeMatcher>(code_matcher)),
|
||||
::testing::MatcherCast<absl::string_view>(
|
||||
std::forward<StatusMessageMatcher>(message_matcher))) {
|
||||
}
|
||||
|
||||
// Converts this polymorphic matcher to a monomorphic matcher of the
|
||||
// given type. T can be StatusOr<>, Status, or a reference to
|
||||
// either of them.
|
||||
template <typename T>
|
||||
/*implicit*/ operator ::testing::Matcher<T>() const { // NOLINT
|
||||
return ::testing::Matcher<T>(
|
||||
new MonoStatusIsMatcherImpl<const T&>(common_impl_));
|
||||
}
|
||||
|
||||
private:
|
||||
const StatusIsMatcherCommonImpl common_impl_;
|
||||
};
|
||||
|
||||
// Monomorphic implementation of matcher IsOk() for a given type T.
|
||||
// T can be Status, StatusOr<>, or a reference to either of them.
|
||||
template <typename T>
|
||||
class MonoIsOkMatcherImpl : public ::testing::MatcherInterface<T> {
|
||||
public:
|
||||
void DescribeTo(std::ostream* os) const override { *os << "is OK"; }
|
||||
void DescribeNegationTo(std::ostream* os) const override {
|
||||
*os << "is not OK";
|
||||
}
|
||||
bool MatchAndExplain(T actual_value,
|
||||
::testing::MatchResultListener*) const override {
|
||||
return GetStatus(actual_value).ok();
|
||||
}
|
||||
};
|
||||
|
||||
// Implements IsOk() as a polymorphic matcher.
|
||||
class IsOkMatcher {
|
||||
public:
|
||||
template <typename T>
|
||||
/*implicit*/ operator ::testing::Matcher<T>() const { // NOLINT
|
||||
return ::testing::Matcher<T>(new MonoIsOkMatcherImpl<const T&>());
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace status_internal
|
||||
ABSL_NAMESPACE_END
|
||||
} // namespace absl_testing
|
||||
|
||||
#endif // ABSL_STATUS_INTERNAL_STATUS_MATCHERS_H_
|
||||
118
absl/status/status_matchers.h
Normal file
118
absl/status/status_matchers.h
Normal file
@@ -0,0 +1,118 @@
|
||||
// Copyright 2024 The Abseil Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// https://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
// -----------------------------------------------------------------------------
|
||||
// File: status_matchers.h
|
||||
// -----------------------------------------------------------------------------
|
||||
//
|
||||
// Testing utilities for working with `absl::Status` and `absl::StatusOr`.
|
||||
//
|
||||
// Defines the following utilities:
|
||||
//
|
||||
// ===============
|
||||
// `IsOkAndHolds(m)`
|
||||
// ===============
|
||||
//
|
||||
// This gMock matcher matches a StatusOr<T> value whose status is OK
|
||||
// and whose inner value matches matcher m. Example:
|
||||
//
|
||||
// ```
|
||||
// using ::testing::MatchesRegex;
|
||||
// using ::absl_testing::IsOkAndHolds;
|
||||
// ...
|
||||
// absl::StatusOr<string> maybe_name = ...;
|
||||
// EXPECT_THAT(maybe_name, IsOkAndHolds(MatchesRegex("John .*")));
|
||||
// ```
|
||||
//
|
||||
// ===============================
|
||||
// `StatusIs(status_code_matcher)`
|
||||
// ===============================
|
||||
//
|
||||
// This is a shorthand for
|
||||
// `StatusIs(status_code_matcher, ::testing::_)`
|
||||
// In other words, it's like the two-argument `StatusIs()`, except that it
|
||||
// ignores error message.
|
||||
//
|
||||
// ===============
|
||||
// `IsOk()`
|
||||
// ===============
|
||||
//
|
||||
// Matches an `absl::Status` or `absl::StatusOr<T>` value whose status value
|
||||
// is `absl::StatusCode::kOk.`
|
||||
//
|
||||
// Equivalent to 'StatusIs(absl::StatusCode::kOk)'.
|
||||
// Example:
|
||||
// ```
|
||||
// using ::absl_testing::IsOk;
|
||||
// ...
|
||||
// absl::StatusOr<string> maybe_name = ...;
|
||||
// EXPECT_THAT(maybe_name, IsOk());
|
||||
// Status s = ...;
|
||||
// EXPECT_THAT(s, IsOk());
|
||||
// ```
|
||||
|
||||
#ifndef ABSL_STATUS_STATUS_MATCHERS_H_
|
||||
#define ABSL_STATUS_STATUS_MATCHERS_H_
|
||||
|
||||
#include <ostream> // NOLINT
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
|
||||
#include "gmock/gmock.h"
|
||||
#include "absl/base/config.h"
|
||||
#include "absl/status/internal/status_matchers.h"
|
||||
|
||||
namespace absl_testing {
|
||||
ABSL_NAMESPACE_BEGIN
|
||||
|
||||
// Returns a gMock matcher that matches a StatusOr<> whose status is
|
||||
// OK and whose value matches the inner matcher.
|
||||
template <typename InnerMatcherT>
|
||||
status_internal::IsOkAndHoldsMatcher<typename std::decay<InnerMatcherT>::type>
|
||||
IsOkAndHolds(InnerMatcherT&& inner_matcher) {
|
||||
return status_internal::IsOkAndHoldsMatcher<
|
||||
typename std::decay<InnerMatcherT>::type>(
|
||||
std::forward<InnerMatcherT>(inner_matcher));
|
||||
}
|
||||
|
||||
// Returns a gMock matcher that matches a Status or StatusOr<> whose status code
|
||||
// matches code_matcher and whose error message matches message_matcher.
|
||||
// Typically, code_matcher will be an absl::StatusCode, e.g.
|
||||
//
|
||||
// StatusIs(absl::StatusCode::kInvalidArgument, "...")
|
||||
template <typename StatusCodeMatcherT, typename StatusMessageMatcherT>
|
||||
status_internal::StatusIsMatcher StatusIs(
|
||||
StatusCodeMatcherT&& code_matcher,
|
||||
StatusMessageMatcherT&& message_matcher) {
|
||||
return status_internal::StatusIsMatcher(
|
||||
std::forward<StatusCodeMatcherT>(code_matcher),
|
||||
std::forward<StatusMessageMatcherT>(message_matcher));
|
||||
}
|
||||
|
||||
// Returns a gMock matcher that matches a Status or StatusOr<> and whose status
|
||||
// code matches code_matcher. See above for details.
|
||||
template <typename StatusCodeMatcherT>
|
||||
status_internal::StatusIsMatcher StatusIs(StatusCodeMatcherT&& code_matcher) {
|
||||
return StatusIs(std::forward<StatusCodeMatcherT>(code_matcher), ::testing::_);
|
||||
}
|
||||
|
||||
// Returns a gMock matcher that matches a Status or StatusOr<> which is OK.
|
||||
inline status_internal::IsOkMatcher IsOk() {
|
||||
return status_internal::IsOkMatcher();
|
||||
}
|
||||
|
||||
ABSL_NAMESPACE_END
|
||||
} // namespace absl_testing
|
||||
|
||||
#endif // ABSL_STATUS_STATUS_MATCHERS_H_
|
||||
119
absl/status/status_matchers_test.cc
Normal file
119
absl/status/status_matchers_test.cc
Normal file
@@ -0,0 +1,119 @@
|
||||
// Copyright 2024 The Abseil Authors
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// https://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
// -----------------------------------------------------------------------------
|
||||
// File: status_matchers_test.cc
|
||||
// -----------------------------------------------------------------------------
|
||||
#include "absl/status/status_matchers.h"
|
||||
|
||||
#include "gmock/gmock.h"
|
||||
#include "gtest/gtest-spi.h"
|
||||
#include "gtest/gtest.h"
|
||||
#include "absl/status/status.h"
|
||||
#include "absl/status/statusor.h"
|
||||
#include "absl/strings/string_view.h"
|
||||
|
||||
namespace {
|
||||
|
||||
using ::absl_testing::IsOk;
|
||||
using ::absl_testing::IsOkAndHolds;
|
||||
using ::absl_testing::StatusIs;
|
||||
using ::testing::Gt;
|
||||
|
||||
TEST(StatusMatcherTest, StatusIsOk) { EXPECT_THAT(absl::OkStatus(), IsOk()); }
|
||||
|
||||
TEST(StatusMatcherTest, StatusOrIsOk) {
|
||||
absl::StatusOr<int> ok_int = {0};
|
||||
EXPECT_THAT(ok_int, IsOk());
|
||||
}
|
||||
|
||||
TEST(StatusMatcherTest, StatusIsNotOk) {
|
||||
absl::Status error = absl::UnknownError("Smigla");
|
||||
EXPECT_NONFATAL_FAILURE(EXPECT_THAT(error, IsOk()), "Smigla");
|
||||
}
|
||||
|
||||
TEST(StatusMatcherTest, StatusOrIsNotOk) {
|
||||
absl::StatusOr<int> error = absl::UnknownError("Smigla");
|
||||
EXPECT_NONFATAL_FAILURE(EXPECT_THAT(error, IsOk()), "Smigla");
|
||||
}
|
||||
|
||||
TEST(StatusMatcherTest, IsOkAndHolds) {
|
||||
absl::StatusOr<int> ok_int = {4};
|
||||
absl::StatusOr<absl::string_view> ok_str = {"text"};
|
||||
EXPECT_THAT(ok_int, IsOkAndHolds(4));
|
||||
EXPECT_THAT(ok_int, IsOkAndHolds(Gt(0)));
|
||||
EXPECT_THAT(ok_str, IsOkAndHolds("text"));
|
||||
}
|
||||
|
||||
TEST(StatusMatcherTest, IsOkAndHoldsFailure) {
|
||||
absl::StatusOr<int> ok_int = {502};
|
||||
absl::StatusOr<int> error = absl::UnknownError("Smigla");
|
||||
absl::StatusOr<absl::string_view> ok_str = {"actual"};
|
||||
EXPECT_NONFATAL_FAILURE(EXPECT_THAT(ok_int, IsOkAndHolds(0)), "502");
|
||||
EXPECT_NONFATAL_FAILURE(EXPECT_THAT(error, IsOkAndHolds(0)), "Smigla");
|
||||
EXPECT_NONFATAL_FAILURE(EXPECT_THAT(ok_str, IsOkAndHolds("expected")),
|
||||
"actual");
|
||||
}
|
||||
|
||||
TEST(StatusMatcherTest, StatusIs) {
|
||||
absl::Status unknown = absl::UnknownError("unbekannt");
|
||||
absl::Status invalid = absl::InvalidArgumentError("ungueltig");
|
||||
EXPECT_THAT(absl::OkStatus(), StatusIs(absl::StatusCode::kOk));
|
||||
EXPECT_THAT(absl::OkStatus(), StatusIs(0));
|
||||
EXPECT_THAT(unknown, StatusIs(absl::StatusCode::kUnknown));
|
||||
EXPECT_THAT(unknown, StatusIs(2));
|
||||
EXPECT_THAT(unknown, StatusIs(absl::StatusCode::kUnknown, "unbekannt"));
|
||||
EXPECT_THAT(invalid, StatusIs(absl::StatusCode::kInvalidArgument));
|
||||
EXPECT_THAT(invalid, StatusIs(3));
|
||||
EXPECT_THAT(invalid,
|
||||
StatusIs(absl::StatusCode::kInvalidArgument, "ungueltig"));
|
||||
}
|
||||
|
||||
TEST(StatusMatcherTest, StatusOrIs) {
|
||||
absl::StatusOr<int> ok = {42};
|
||||
absl::StatusOr<int> unknown = absl::UnknownError("unbekannt");
|
||||
absl::StatusOr<absl::string_view> invalid =
|
||||
absl::InvalidArgumentError("ungueltig");
|
||||
EXPECT_THAT(ok, StatusIs(absl::StatusCode::kOk));
|
||||
EXPECT_THAT(ok, StatusIs(0));
|
||||
EXPECT_THAT(unknown, StatusIs(absl::StatusCode::kUnknown));
|
||||
EXPECT_THAT(unknown, StatusIs(2));
|
||||
EXPECT_THAT(unknown, StatusIs(absl::StatusCode::kUnknown, "unbekannt"));
|
||||
EXPECT_THAT(invalid, StatusIs(absl::StatusCode::kInvalidArgument));
|
||||
EXPECT_THAT(invalid, StatusIs(3));
|
||||
EXPECT_THAT(invalid,
|
||||
StatusIs(absl::StatusCode::kInvalidArgument, "ungueltig"));
|
||||
}
|
||||
|
||||
TEST(StatusMatcherTest, StatusIsFailure) {
|
||||
absl::Status unknown = absl::UnknownError("unbekannt");
|
||||
absl::Status invalid = absl::InvalidArgumentError("ungueltig");
|
||||
EXPECT_NONFATAL_FAILURE(
|
||||
EXPECT_THAT(absl::OkStatus(),
|
||||
StatusIs(absl::StatusCode::kInvalidArgument)),
|
||||
"OK");
|
||||
EXPECT_NONFATAL_FAILURE(
|
||||
EXPECT_THAT(unknown, StatusIs(absl::StatusCode::kCancelled)), "UNKNOWN");
|
||||
EXPECT_NONFATAL_FAILURE(
|
||||
EXPECT_THAT(unknown, StatusIs(absl::StatusCode::kUnknown, "inconnu")),
|
||||
"unbekannt");
|
||||
EXPECT_NONFATAL_FAILURE(
|
||||
EXPECT_THAT(invalid, StatusIs(absl::StatusCode::kOutOfRange)), "INVALID");
|
||||
EXPECT_NONFATAL_FAILURE(
|
||||
EXPECT_THAT(invalid,
|
||||
StatusIs(absl::StatusCode::kInvalidArgument, "invalide")),
|
||||
"ungueltig");
|
||||
}
|
||||
|
||||
} // namespace
|
||||
Reference in New Issue
Block a user