From 66406fdf1553de6ad672576167e7cc7ca2d764cb Mon Sep 17 00:00:00 2001 From: Greg Falcon Date: Mon, 5 Jun 2023 14:27:37 -0700 Subject: Add a unit test that captures the current behavior of formatting of char types and char-backed enum types through StrCat(), StrFormat("%v"), and Substitute(). This test allows us to modify the behavior in this space without introducing undesired changes elsewhere. PiperOrigin-RevId: 537981963 Change-Id: Icda91b66efcc0dc8c263011b137e130a3db2dc19 --- absl/strings/char_formatting_test.cc | 189 +++++++++++++++++++++++++++++++++++ 1 file changed, 189 insertions(+) create mode 100644 absl/strings/char_formatting_test.cc (limited to 'absl/strings/char_formatting_test.cc') diff --git a/absl/strings/char_formatting_test.cc b/absl/strings/char_formatting_test.cc new file mode 100644 index 00000000..60416af3 --- /dev/null +++ b/absl/strings/char_formatting_test.cc @@ -0,0 +1,189 @@ +// Copyright 2023 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. + +#include + +#include "gtest/gtest.h" +#include "absl/strings/str_cat.h" +#include "absl/strings/str_format.h" +#include "absl/strings/substitute.h" + +namespace { + +TEST(CharFormatting, Char) { + const char v = 'A'; + + // Desired behavior: does not compile: + // EXPECT_EQ(absl::StrCat(v, "B"), "AB"); + // EXPECT_EQ(absl::StrFormat("%vB", v), "AB"); + + // Legacy behavior: format as char: + EXPECT_EQ(absl::Substitute("$0B", v), "AB"); +} + +enum CharEnum : char {}; +TEST(CharFormatting, CharEnum) { + auto v = static_cast('A'); + + // Desired behavior: format as decimal + // (No APIs do this today.) + + // BUG: internally fails + EXPECT_EQ(absl::StrFormat("%vB", v), ""); + + // Legacy behavior: does not compile: + // EXPECT_EQ(absl::StrCat(ch, "B"), "AB"); + + // Legacy behavior: format as character: + + // Some older versions of gcc behave differently in this one case. +#if !defined(__GNUC__) || defined(__clang__) + EXPECT_EQ(absl::Substitute("$0B", v), "AB"); +#endif +} + +enum class CharEnumClass: char {}; +TEST(CharFormatting, CharEnumClass) { + auto v = static_cast('A'); + + // Desired behavior: format as decimal + // (No APIs do this today.) + + // BUG: internally fails + EXPECT_EQ(absl::StrFormat("%vB", v), ""); + + // Legacy behavior: does not compile: + // EXPECT_EQ(absl::StrCat(ch, "B"), "AB"); + + // Legacy behavior: format as character: + EXPECT_EQ(absl::Substitute("$0B", v), "AB"); +} + +TEST(CharFormatting, UnsignedChar) { + const unsigned char v = 'A'; + + // Desired behavior: format as decimal: + EXPECT_EQ(absl::StrCat(v, "B"), "65B"); + EXPECT_EQ(absl::Substitute("$0B", v), "65B"); + + // Legacy behavior: does not compile: + // EXPECT_EQ(absl::StrFormat("%vB", v), "65B"); + + // Signedness check + const unsigned char w = 255; + EXPECT_EQ(absl::StrCat(w, "B"), "255B"); + EXPECT_EQ(absl::Substitute("$0B", w), "255B"); + // EXPECT_EQ(absl::StrFormat("%vB", v), "255B"); +} + +TEST(CharFormatting, SignedChar) { + const signed char v = 'A'; + + // Desired behavior: format as decimal: + EXPECT_EQ(absl::StrCat(v, "B"), "65B"); + EXPECT_EQ(absl::Substitute("$0B", v), "65B"); + + // Legacy behavior: does not compile: + // EXPECT_EQ(absl::StrFormat("%vB", v), "AB"); + + // Signedness check + const signed char w = -128; + EXPECT_EQ(absl::StrCat(w, "B"), "-128B"); + EXPECT_EQ(absl::Substitute("$0B", w), "-128B"); +} + +enum UnsignedCharEnum : unsigned char {}; +TEST(CharFormatting, UnsignedCharEnum) { + auto v = static_cast('A'); + + // Desired behavior: format as decimal: + EXPECT_EQ(absl::StrCat(v, "B"), "65B"); + EXPECT_EQ(absl::Substitute("$0B", v), "65B"); + + // BUG: internally fails + EXPECT_EQ(absl::StrFormat("%vB", v), ""); + + // Signedness check + auto w = static_cast(255); + EXPECT_EQ(absl::StrCat(w, "B"), "255B"); + EXPECT_EQ(absl::Substitute("$0B", w), "255B"); +} + +enum SignedCharEnum : signed char {}; +TEST(CharFormatting, SignedCharEnum) { + auto v = static_cast('A'); + + // Desired behavior: format as decimal: + EXPECT_EQ(absl::StrCat(v, "B"), "65B"); + EXPECT_EQ(absl::Substitute("$0B", v), "65B"); + + // BUG: internally fails + EXPECT_EQ(absl::StrFormat("%vB", v), ""); + + // Signedness check + auto w = static_cast(-128); + EXPECT_EQ(absl::StrCat(w, "B"), "-128B"); + EXPECT_EQ(absl::Substitute("$0B", w), "-128B"); +} + +enum class UnsignedCharEnumClass : unsigned char {}; +TEST(CharFormatting, UnsignedCharEnumClass) { + auto v = static_cast('A'); + + // Desired behavior: format as decimal: + EXPECT_EQ(absl::StrCat(v, "B"), "65B"); + EXPECT_EQ(absl::Substitute("$0B", v), "65B"); + + // BUG: internally fails + EXPECT_EQ(absl::StrFormat("%vB", v), ""); + + // Signedness check + auto w = static_cast(255); + EXPECT_EQ(absl::StrCat(w, "B"), "255B"); + EXPECT_EQ(absl::Substitute("$0B", w), "255B"); +} + +enum SignedCharEnumClass : signed char {}; +TEST(CharFormatting, SignedCharEnumClass) { + auto v = static_cast('A'); + + // Desired behavior: format as decimal: + EXPECT_EQ(absl::StrCat(v, "B"), "65B"); + EXPECT_EQ(absl::Substitute("$0B", v), "65B"); + + // BUG: internally fails + EXPECT_EQ(absl::StrFormat("%vB", v), ""); + + // Signedness check + auto w = static_cast(-128); + EXPECT_EQ(absl::StrCat(w, "B"), "-128B"); + EXPECT_EQ(absl::Substitute("$0B", w), "-128B"); +} + +#ifdef __cpp_lib_byte +TEST(CharFormatting, StdByte) { + auto v = static_cast('A'); + // Desired behavior: format as 0xff + // (No APIs do this today.) + + // BUG: internally fails + EXPECT_EQ(absl::StrFormat("%vB", v), ""); + + // Legacy behavior: format as decimal: + EXPECT_EQ(absl::StrCat(v, "B"), "65B"); + EXPECT_EQ(absl::Substitute("$0B", v), "65B"); +} +#endif // _cpp_lib_byte + +} // namespace -- cgit v1.2.3