xref: /aosp_15_r20/external/cronet/base/strings/to_string_unittest.cc (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1*6777b538SAndroid Build Coastguard Worker // Copyright 2023 The Chromium Authors
2*6777b538SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
3*6777b538SAndroid Build Coastguard Worker // found in the LICENSE file.
4*6777b538SAndroid Build Coastguard Worker 
5*6777b538SAndroid Build Coastguard Worker #include "base/strings/to_string.h"
6*6777b538SAndroid Build Coastguard Worker 
7*6777b538SAndroid Build Coastguard Worker #include <ios>
8*6777b538SAndroid Build Coastguard Worker #include <ostream>
9*6777b538SAndroid Build Coastguard Worker #include <string>
10*6777b538SAndroid Build Coastguard Worker 
11*6777b538SAndroid Build Coastguard Worker #include "testing/gtest/include/gtest/gtest.h"
12*6777b538SAndroid Build Coastguard Worker 
13*6777b538SAndroid Build Coastguard Worker namespace base {
14*6777b538SAndroid Build Coastguard Worker namespace {
15*6777b538SAndroid Build Coastguard Worker 
16*6777b538SAndroid Build Coastguard Worker class NotStringifiable {};
17*6777b538SAndroid Build Coastguard Worker class HasToString {
18*6777b538SAndroid Build Coastguard Worker  public:
ToString() const19*6777b538SAndroid Build Coastguard Worker   std::string ToString() const { return "yay!"; }
20*6777b538SAndroid Build Coastguard Worker };
21*6777b538SAndroid Build Coastguard Worker 
22*6777b538SAndroid Build Coastguard Worker // .ToString() support on structs.
23*6777b538SAndroid Build Coastguard Worker static_assert(!internal::SupportsToString<NotStringifiable>,
24*6777b538SAndroid Build Coastguard Worker               "value without ToString() shouldn't be marked SupportsToString");
25*6777b538SAndroid Build Coastguard Worker static_assert(!internal::SupportsToString<NotStringifiable&>,
26*6777b538SAndroid Build Coastguard Worker               "& without ToString() shouldn't be marked SupportsToString");
27*6777b538SAndroid Build Coastguard Worker static_assert(!internal::SupportsToString<const NotStringifiable&>,
28*6777b538SAndroid Build Coastguard Worker               "const& without ToString() shouldn't be marked SupportsToString");
29*6777b538SAndroid Build Coastguard Worker static_assert(!internal::SupportsToString<NotStringifiable&&>,
30*6777b538SAndroid Build Coastguard Worker               "&& without ToString() shouldn't be marked SupportsToString");
31*6777b538SAndroid Build Coastguard Worker static_assert(internal::SupportsToString<HasToString>,
32*6777b538SAndroid Build Coastguard Worker               "value with ToString() should be marked SupportsToString");
33*6777b538SAndroid Build Coastguard Worker static_assert(internal::SupportsToString<HasToString&>,
34*6777b538SAndroid Build Coastguard Worker               "& with ToString() should be marked SupportsToString");
35*6777b538SAndroid Build Coastguard Worker static_assert(internal::SupportsToString<const HasToString&>,
36*6777b538SAndroid Build Coastguard Worker               "const& with ToString() should be marked SupportsToString");
37*6777b538SAndroid Build Coastguard Worker static_assert(internal::SupportsToString<HasToString&&>,
38*6777b538SAndroid Build Coastguard Worker               "&& with ToString() should be marked SupportsToString");
39*6777b538SAndroid Build Coastguard Worker 
TEST(ToStringTest,Streamable)40*6777b538SAndroid Build Coastguard Worker TEST(ToStringTest, Streamable) {
41*6777b538SAndroid Build Coastguard Worker   // Types with built-in <<.
42*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(ToString("foo"), "foo");
43*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(ToString(123), "123");
44*6777b538SAndroid Build Coastguard Worker }
45*6777b538SAndroid Build Coastguard Worker 
46*6777b538SAndroid Build Coastguard Worker enum class StreamableTestEnum { kGreeting, kLocation };
47*6777b538SAndroid Build Coastguard Worker 
operator <<(std::ostream & os,const StreamableTestEnum & value)48*6777b538SAndroid Build Coastguard Worker std::ostream& operator<<(std::ostream& os, const StreamableTestEnum& value) {
49*6777b538SAndroid Build Coastguard Worker   switch (value) {
50*6777b538SAndroid Build Coastguard Worker     case StreamableTestEnum::kGreeting:
51*6777b538SAndroid Build Coastguard Worker       return os << "hello";
52*6777b538SAndroid Build Coastguard Worker     case StreamableTestEnum::kLocation:
53*6777b538SAndroid Build Coastguard Worker       return os << "world";
54*6777b538SAndroid Build Coastguard Worker   }
55*6777b538SAndroid Build Coastguard Worker }
56*6777b538SAndroid Build Coastguard Worker 
TEST(ToStringTest,UserDefinedStreamable)57*6777b538SAndroid Build Coastguard Worker TEST(ToStringTest, UserDefinedStreamable) {
58*6777b538SAndroid Build Coastguard Worker   // Type with user-defined <<.
59*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(ToString(StreamableTestEnum::kGreeting), "hello");
60*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(ToString(StreamableTestEnum::kGreeting, " ",
61*6777b538SAndroid Build Coastguard Worker                      StreamableTestEnum::kLocation),
62*6777b538SAndroid Build Coastguard Worker             "hello world");
63*6777b538SAndroid Build Coastguard Worker }
64*6777b538SAndroid Build Coastguard Worker 
TEST(ToStringTest,UserDefinedToString)65*6777b538SAndroid Build Coastguard Worker TEST(ToStringTest, UserDefinedToString) {
66*6777b538SAndroid Build Coastguard Worker   // Type with user-defined ToString().
67*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(ToString(HasToString()), "yay!");
68*6777b538SAndroid Build Coastguard Worker }
69*6777b538SAndroid Build Coastguard Worker 
70*6777b538SAndroid Build Coastguard Worker class UnusualToString {
71*6777b538SAndroid Build Coastguard Worker  public:
ToString() const72*6777b538SAndroid Build Coastguard Worker   HasToString ToString() const { return HasToString(); }
73*6777b538SAndroid Build Coastguard Worker };
74*6777b538SAndroid Build Coastguard Worker 
TEST(ToStringTest,ToStringReturnsNonStdString)75*6777b538SAndroid Build Coastguard Worker TEST(ToStringTest, ToStringReturnsNonStdString) {
76*6777b538SAndroid Build Coastguard Worker   // Types with a ToString() that does not directly return a std::string should
77*6777b538SAndroid Build Coastguard Worker   // still work.
78*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(ToString(UnusualToString()), "yay!");
79*6777b538SAndroid Build Coastguard Worker }
80*6777b538SAndroid Build Coastguard Worker 
81*6777b538SAndroid Build Coastguard Worker enum class NonStreamableTestEnum { kGreeting = 0, kLocation };
82*6777b538SAndroid Build Coastguard Worker 
TEST(ToStringTest,ScopedEnum)83*6777b538SAndroid Build Coastguard Worker TEST(ToStringTest, ScopedEnum) {
84*6777b538SAndroid Build Coastguard Worker   // Scoped enums without a defined << should print as their underlying type.
85*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(ToString(NonStreamableTestEnum::kLocation), "1");
86*6777b538SAndroid Build Coastguard Worker }
87*6777b538SAndroid Build Coastguard Worker 
TEST(ToStringTest,IoManip)88*6777b538SAndroid Build Coastguard Worker TEST(ToStringTest, IoManip) {
89*6777b538SAndroid Build Coastguard Worker   // I/O manipulators should have their expected effect, not be printed as
90*6777b538SAndroid Build Coastguard Worker   // function pointers.
91*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(ToString("42 in hex is ", std::hex, 42), "42 in hex is 2a");
92*6777b538SAndroid Build Coastguard Worker }
93*6777b538SAndroid Build Coastguard Worker 
TEST(ToStringTest,Tuple)94*6777b538SAndroid Build Coastguard Worker TEST(ToStringTest, Tuple) {
95*6777b538SAndroid Build Coastguard Worker   // Tuples should correctly format the contained types.
96*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(ToString(std::make_tuple(StreamableTestEnum::kGreeting,
97*6777b538SAndroid Build Coastguard Worker                                      HasToString(), "a string")),
98*6777b538SAndroid Build Coastguard Worker             "<hello, yay!, a string>");
99*6777b538SAndroid Build Coastguard Worker }
100*6777b538SAndroid Build Coastguard Worker 
Func()101*6777b538SAndroid Build Coastguard Worker void Func() {}
102*6777b538SAndroid Build Coastguard Worker 
TEST(ToStringTest,FunctionPointer)103*6777b538SAndroid Build Coastguard Worker TEST(ToStringTest, FunctionPointer) {
104*6777b538SAndroid Build Coastguard Worker   // We don't care about the actual address, but a function pointer should not
105*6777b538SAndroid Build Coastguard Worker   // be implicitly converted to bool.
106*6777b538SAndroid Build Coastguard Worker   EXPECT_NE(ToString(&Func), ToString(true));
107*6777b538SAndroid Build Coastguard Worker 
108*6777b538SAndroid Build Coastguard Worker   // Functions should be treated like function pointers.
109*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(ToString(Func), ToString(&Func));
110*6777b538SAndroid Build Coastguard Worker }
111*6777b538SAndroid Build Coastguard Worker 
112*6777b538SAndroid Build Coastguard Worker class OverloadsAddressOp {
113*6777b538SAndroid Build Coastguard Worker  public:
operator &()114*6777b538SAndroid Build Coastguard Worker   OverloadsAddressOp* operator&() { return nullptr; }
operator &() const115*6777b538SAndroid Build Coastguard Worker   const OverloadsAddressOp* operator&() const { return nullptr; }
116*6777b538SAndroid Build Coastguard Worker };
117*6777b538SAndroid Build Coastguard Worker 
TEST(ToStringTest,NonStringifiable)118*6777b538SAndroid Build Coastguard Worker TEST(ToStringTest, NonStringifiable) {
119*6777b538SAndroid Build Coastguard Worker   // Non-stringifiable types should be printed using a fallback.
120*6777b538SAndroid Build Coastguard Worker   EXPECT_NE(ToString(NotStringifiable()).find("-byte object at 0x"),
121*6777b538SAndroid Build Coastguard Worker             std::string::npos);
122*6777b538SAndroid Build Coastguard Worker 
123*6777b538SAndroid Build Coastguard Worker   // Non-stringifiable types which overload operator& should print their real
124*6777b538SAndroid Build Coastguard Worker   // address.
125*6777b538SAndroid Build Coastguard Worker   EXPECT_NE(ToString(OverloadsAddressOp()),
126*6777b538SAndroid Build Coastguard Worker             ToString(static_cast<OverloadsAddressOp*>(nullptr)));
127*6777b538SAndroid Build Coastguard Worker }
128*6777b538SAndroid Build Coastguard Worker 
129*6777b538SAndroid Build Coastguard Worker }  // namespace
130*6777b538SAndroid Build Coastguard Worker }  // namespace base
131