• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2023 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "base/strings/to_string.h"
6 
7 #include <ios>
8 #include <ostream>
9 #include <string>
10 
11 #include "testing/gtest/include/gtest/gtest.h"
12 
13 namespace base {
14 namespace {
15 
TEST(ToStringTest,Streamable)16 TEST(ToStringTest, Streamable) {
17   // Types with built-in <<.
18   EXPECT_EQ(ToString("foo"), "foo");
19   EXPECT_EQ(ToString(123), "123");
20 }
21 
22 enum class StreamableTestEnum { kGreeting, kLocation };
23 
operator <<(std::ostream & os,const StreamableTestEnum & value)24 std::ostream& operator<<(std::ostream& os, const StreamableTestEnum& value) {
25   switch (value) {
26     case StreamableTestEnum::kGreeting:
27       return os << "hello";
28     case StreamableTestEnum::kLocation:
29       return os << "world";
30   }
31 }
32 
TEST(ToStringTest,UserDefinedStreamable)33 TEST(ToStringTest, UserDefinedStreamable) {
34   // Type with user-defined <<.
35   EXPECT_EQ(ToString(StreamableTestEnum::kGreeting), "hello");
36   EXPECT_EQ(ToString(StreamableTestEnum::kGreeting, " ",
37                      StreamableTestEnum::kLocation),
38             "hello world");
39 }
40 
41 class HasToString {
42  public:
ToString() const43   std::string ToString() const { return "yay!"; }
44 };
45 
TEST(ToStringTest,UserDefinedToString)46 TEST(ToStringTest, UserDefinedToString) {
47   // Type with user-defined ToString().
48   EXPECT_EQ(ToString(HasToString()), "yay!");
49 }
50 
51 class UnusualToString {
52  public:
ToString() const53   HasToString ToString() const { return HasToString(); }
54 };
55 
TEST(ToStringTest,ToStringReturnsNonStdString)56 TEST(ToStringTest, ToStringReturnsNonStdString) {
57   // Types with a ToString() that does not directly return a std::string should
58   // still work.
59   EXPECT_EQ(ToString(UnusualToString()), "yay!");
60 }
61 
62 enum class NonStreamableTestEnum { kGreeting = 0, kLocation };
63 
TEST(ToStringTest,ScopedEnum)64 TEST(ToStringTest, ScopedEnum) {
65   // Scoped enums without a defined << should print as their underlying type.
66   EXPECT_EQ(ToString(NonStreamableTestEnum::kLocation), "1");
67 }
68 
TEST(ToStringTest,IoManip)69 TEST(ToStringTest, IoManip) {
70   // I/O manipulators should have their expected effect, not be printed as
71   // function pointers.
72   EXPECT_EQ(ToString("42 in hex is ", std::hex, 42), "42 in hex is 2a");
73 }
74 
Func()75 void Func() {}
76 
TEST(ToStringTest,FunctionPointer)77 TEST(ToStringTest, FunctionPointer) {
78   // We don't care about the actual address, but a function pointer should not
79   // be implicitly converted to bool.
80   EXPECT_NE(ToString(&Func), ToString(true));
81 
82   // Functions should be treated like function pointers.
83   EXPECT_EQ(ToString(Func), ToString(&Func));
84 }
85 
86 class NotStringifiable {};
87 
88 class OverloadsAddressOp {
89  public:
operator &()90   OverloadsAddressOp* operator&() { return nullptr; }
operator &() const91   const OverloadsAddressOp* operator&() const { return nullptr; }
92 };
93 
TEST(ToStringTest,NonStringifiable)94 TEST(ToStringTest, NonStringifiable) {
95   // Non-stringifiable types should be printed using a fallback.
96   EXPECT_NE(ToString(NotStringifiable()).find("-byte object at 0x"),
97             std::string::npos);
98 
99   // Non-stringifiable types which overload operator& should print their real
100   // address.
101   EXPECT_NE(ToString(OverloadsAddressOp()),
102             ToString(static_cast<OverloadsAddressOp*>(nullptr)));
103 }
104 
105 }  // namespace
106 }  // namespace base
107