From e3114cc5744393c5d8e514d9f3323ef194f3bcb5 Mon Sep 17 00:00:00 2001 From: Abseil Team Date: Tue, 26 Sep 2023 10:58:35 -0700 Subject: Adds `AbslStringify` to `absl::Status` for completeness. This also adds a test for `operator<<`. PiperOrigin-RevId: 568590367 Change-Id: Ia0ad39cb582e7d24e6c4131827818d8c4b10dfd9 --- absl/status/BUILD.bazel | 1 + absl/status/CMakeLists.txt | 1 + absl/status/status.h | 7 ++++- absl/status/status_test.cc | 67 +++++++++++++++++++++++++++++++++++++--------- 4 files changed, 62 insertions(+), 14 deletions(-) (limited to 'absl/status') diff --git a/absl/status/BUILD.bazel b/absl/status/BUILD.bazel index 5be5c218..8edf714f 100644 --- a/absl/status/BUILD.bazel +++ b/absl/status/BUILD.bazel @@ -70,6 +70,7 @@ cc_test( ":status", "//absl/strings", "//absl/strings:cord", + "//absl/strings:str_format", "@com_google_googletest//:gtest_main", ], ) diff --git a/absl/status/CMakeLists.txt b/absl/status/CMakeLists.txt index f369e341..fc4ae507 100644 --- a/absl/status/CMakeLists.txt +++ b/absl/status/CMakeLists.txt @@ -56,6 +56,7 @@ absl_cc_test( ${ABSL_TEST_COPTS} DEPS absl::status + absl::str_format absl::strings GTest::gmock_main ) diff --git a/absl/status/status.h b/absl/status/status.h index 2f03bb64..dc37493a 100644 --- a/absl/status/status.h +++ b/absl/status/status.h @@ -64,7 +64,6 @@ #include "absl/functional/function_ref.h" #include "absl/status/internal/status_internal.h" #include "absl/strings/cord.h" -#include "absl/strings/str_cat.h" #include "absl/strings/string_view.h" #include "absl/types/optional.h" @@ -523,6 +522,12 @@ class Status final { std::string ToString( StatusToStringMode mode = StatusToStringMode::kDefault) const; + // Support `absl::StrCat`, `absl::StrFormat`, etc. + template + friend void AbslStringify(Sink& sink, const Status& status) { + sink.Append(status.ToString(StatusToStringMode::kWithEverything)); + } + // Status::IgnoreError() // // Ignores any errors. This method does nothing except potentially suppress diff --git a/absl/status/status_test.cc b/absl/status/status_test.cc index 6d3cf6fa..585e7807 100644 --- a/absl/status/status_test.cc +++ b/absl/status/status_test.cc @@ -25,6 +25,7 @@ #include "gtest/gtest.h" #include "absl/strings/cord.h" #include "absl/strings/str_cat.h" +#include "absl/strings/str_format.h" namespace { @@ -305,37 +306,77 @@ TEST(Status, TestForEachPayload) { } TEST(Status, ToString) { - absl::Status s(absl::StatusCode::kInternal, "fail"); - EXPECT_EQ("INTERNAL: fail", s.ToString()); - s.SetPayload("foo", absl::Cord("bar")); - EXPECT_EQ("INTERNAL: fail [foo='bar']", s.ToString()); - s.SetPayload("bar", absl::Cord("\377")); - EXPECT_THAT(s.ToString(), + absl::Status status(absl::StatusCode::kInternal, "fail"); + EXPECT_EQ("INTERNAL: fail", status.ToString()); + status.SetPayload("foo", absl::Cord("bar")); + EXPECT_EQ("INTERNAL: fail [foo='bar']", status.ToString()); + status.SetPayload("bar", absl::Cord("\377")); + EXPECT_THAT(status.ToString(), AllOf(HasSubstr("INTERNAL: fail"), HasSubstr("[foo='bar']"), HasSubstr("[bar='\\xff']"))); } TEST(Status, ToStringMode) { - absl::Status s(absl::StatusCode::kInternal, "fail"); - s.SetPayload("foo", absl::Cord("bar")); - s.SetPayload("bar", absl::Cord("\377")); + absl::Status status(absl::StatusCode::kInternal, "fail"); + status.SetPayload("foo", absl::Cord("bar")); + status.SetPayload("bar", absl::Cord("\377")); EXPECT_EQ("INTERNAL: fail", - s.ToString(absl::StatusToStringMode::kWithNoExtraData)); + status.ToString(absl::StatusToStringMode::kWithNoExtraData)); - EXPECT_THAT(s.ToString(absl::StatusToStringMode::kWithPayload), + EXPECT_THAT(status.ToString(absl::StatusToStringMode::kWithPayload), AllOf(HasSubstr("INTERNAL: fail"), HasSubstr("[foo='bar']"), HasSubstr("[bar='\\xff']"))); - EXPECT_THAT(s.ToString(absl::StatusToStringMode::kWithEverything), + EXPECT_THAT(status.ToString(absl::StatusToStringMode::kWithEverything), AllOf(HasSubstr("INTERNAL: fail"), HasSubstr("[foo='bar']"), HasSubstr("[bar='\\xff']"))); - EXPECT_THAT(s.ToString(~absl::StatusToStringMode::kWithPayload), + EXPECT_THAT(status.ToString(~absl::StatusToStringMode::kWithPayload), AllOf(HasSubstr("INTERNAL: fail"), Not(HasSubstr("[foo='bar']")), Not(HasSubstr("[bar='\\xff']")))); } +TEST(Status, OstreamOperator) { + absl::Status status(absl::StatusCode::kInternal, "fail"); + { std::stringstream stream; + stream << status; + EXPECT_EQ("INTERNAL: fail", stream.str()); + } + status.SetPayload("foo", absl::Cord("bar")); + { std::stringstream stream; + stream << status; + EXPECT_EQ("INTERNAL: fail [foo='bar']", stream.str()); + } + status.SetPayload("bar", absl::Cord("\377")); + { std::stringstream stream; + stream << status; + EXPECT_THAT(stream.str(), + AllOf(HasSubstr("INTERNAL: fail"), HasSubstr("[foo='bar']"), + HasSubstr("[bar='\\xff']"))); + } +} + +TEST(Status, AbslStringify) { + absl::Status status(absl::StatusCode::kInternal, "fail"); + EXPECT_EQ("INTERNAL: fail", absl::StrCat(status)); + EXPECT_EQ("INTERNAL: fail", absl::StrFormat("%v", status)); + status.SetPayload("foo", absl::Cord("bar")); + EXPECT_EQ("INTERNAL: fail [foo='bar']", absl::StrCat(status)); + status.SetPayload("bar", absl::Cord("\377")); + EXPECT_THAT(absl::StrCat(status), + AllOf(HasSubstr("INTERNAL: fail"), HasSubstr("[foo='bar']"), + HasSubstr("[bar='\\xff']"))); +} + +TEST(Status, OstreamEqStringify) { + absl::Status status(absl::StatusCode::kUnknown, "fail"); + status.SetPayload("foo", absl::Cord("bar")); + std::stringstream stream; + stream << status; + EXPECT_EQ(stream.str(), absl::StrCat(status)); +} + absl::Status EraseAndReturn(const absl::Status& base) { absl::Status copy = base; EXPECT_TRUE(copy.ErasePayload(kUrl1)); -- cgit v1.2.3