1 // Copyright 2017 The Abseil Authors.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //      https://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #include "absl/strings/internal/str_format/arg.h"
16 
17 #include <ostream>
18 #include <string>
19 #include "gtest/gtest.h"
20 #include "absl/strings/str_format.h"
21 
22 namespace absl {
23 ABSL_NAMESPACE_BEGIN
24 namespace str_format_internal {
25 namespace {
26 
27 class FormatArgImplTest : public ::testing::Test {
28  public:
29   enum Color { kRed, kGreen, kBlue };
30 
hi()31   static const char *hi() { return "hi"; }
32 
33   struct X {};
34 
35   X x_;
36 };
37 
AbslFormatConvert(const FormatArgImplTest::X &,const FormatConversionSpec &,FormatSink *)38 inline FormatConvertResult<FormatConversionCharSet{}> AbslFormatConvert(
39     const FormatArgImplTest::X &, const FormatConversionSpec &, FormatSink *) {
40   return {false};
41 }
42 
TEST_F(FormatArgImplTest,ToInt)43 TEST_F(FormatArgImplTest, ToInt) {
44   int out = 0;
45   EXPECT_TRUE(FormatArgImplFriend::ToInt(FormatArgImpl(1), &out));
46   EXPECT_EQ(1, out);
47   EXPECT_TRUE(FormatArgImplFriend::ToInt(FormatArgImpl(-1), &out));
48   EXPECT_EQ(-1, out);
49   EXPECT_TRUE(
50       FormatArgImplFriend::ToInt(FormatArgImpl(static_cast<char>(64)), &out));
51   EXPECT_EQ(64, out);
52   EXPECT_TRUE(FormatArgImplFriend::ToInt(
53       FormatArgImpl(static_cast<unsigned long long>(123456)), &out));  // NOLINT
54   EXPECT_EQ(123456, out);
55   EXPECT_TRUE(FormatArgImplFriend::ToInt(
56       FormatArgImpl(static_cast<unsigned long long>(  // NOLINT
57                         std::numeric_limits<int>::max()) +
58                     1),
59       &out));
60   EXPECT_EQ(std::numeric_limits<int>::max(), out);
61   EXPECT_TRUE(FormatArgImplFriend::ToInt(
62       FormatArgImpl(static_cast<long long>(  // NOLINT
63                         std::numeric_limits<int>::min()) -
64                     10),
65       &out));
66   EXPECT_EQ(std::numeric_limits<int>::min(), out);
67   EXPECT_TRUE(FormatArgImplFriend::ToInt(FormatArgImpl(false), &out));
68   EXPECT_EQ(0, out);
69   EXPECT_TRUE(FormatArgImplFriend::ToInt(FormatArgImpl(true), &out));
70   EXPECT_EQ(1, out);
71   EXPECT_FALSE(FormatArgImplFriend::ToInt(FormatArgImpl(2.2), &out));
72   EXPECT_FALSE(FormatArgImplFriend::ToInt(FormatArgImpl(3.2f), &out));
73   EXPECT_FALSE(FormatArgImplFriend::ToInt(
74       FormatArgImpl(static_cast<int *>(nullptr)), &out));
75   EXPECT_FALSE(FormatArgImplFriend::ToInt(FormatArgImpl(hi()), &out));
76   EXPECT_FALSE(FormatArgImplFriend::ToInt(FormatArgImpl("hi"), &out));
77   EXPECT_FALSE(FormatArgImplFriend::ToInt(FormatArgImpl(x_), &out));
78   EXPECT_TRUE(FormatArgImplFriend::ToInt(FormatArgImpl(kBlue), &out));
79   EXPECT_EQ(2, out);
80 }
81 
82 extern const char kMyArray[];
83 
TEST_F(FormatArgImplTest,CharArraysDecayToCharPtr)84 TEST_F(FormatArgImplTest, CharArraysDecayToCharPtr) {
85   const char* a = "";
86   EXPECT_EQ(FormatArgImplFriend::GetVTablePtrForTest(FormatArgImpl(a)),
87             FormatArgImplFriend::GetVTablePtrForTest(FormatArgImpl("")));
88   EXPECT_EQ(FormatArgImplFriend::GetVTablePtrForTest(FormatArgImpl(a)),
89             FormatArgImplFriend::GetVTablePtrForTest(FormatArgImpl("A")));
90   EXPECT_EQ(FormatArgImplFriend::GetVTablePtrForTest(FormatArgImpl(a)),
91             FormatArgImplFriend::GetVTablePtrForTest(FormatArgImpl("ABC")));
92   EXPECT_EQ(FormatArgImplFriend::GetVTablePtrForTest(FormatArgImpl(a)),
93             FormatArgImplFriend::GetVTablePtrForTest(FormatArgImpl(kMyArray)));
94 }
95 
TEST_F(FormatArgImplTest,OtherPtrDecayToVoidPtr)96 TEST_F(FormatArgImplTest, OtherPtrDecayToVoidPtr) {
97   auto expected = FormatArgImplFriend::GetVTablePtrForTest(
98       FormatArgImpl(static_cast<void *>(nullptr)));
99   EXPECT_EQ(FormatArgImplFriend::GetVTablePtrForTest(
100                 FormatArgImpl(static_cast<int *>(nullptr))),
101             expected);
102   EXPECT_EQ(FormatArgImplFriend::GetVTablePtrForTest(
103                 FormatArgImpl(static_cast<volatile int *>(nullptr))),
104             expected);
105 
106   auto p = static_cast<void (*)()>([] {});
107   EXPECT_EQ(FormatArgImplFriend::GetVTablePtrForTest(FormatArgImpl(p)),
108             expected);
109 }
110 
TEST_F(FormatArgImplTest,WorksWithCharArraysOfUnknownSize)111 TEST_F(FormatArgImplTest, WorksWithCharArraysOfUnknownSize) {
112   std::string s;
113   FormatSinkImpl sink(&s);
114   FormatConversionSpecImpl conv;
115   FormatConversionSpecImplFriend::SetConversionChar(
116       FormatConversionCharInternal::s, &conv);
117   FormatConversionSpecImplFriend::SetFlags(Flags(), &conv);
118   FormatConversionSpecImplFriend::SetWidth(-1, &conv);
119   FormatConversionSpecImplFriend::SetPrecision(-1, &conv);
120   EXPECT_TRUE(
121       FormatArgImplFriend::Convert(FormatArgImpl(kMyArray), conv, &sink));
122   sink.Flush();
123   EXPECT_EQ("ABCDE", s);
124 }
125 const char kMyArray[] = "ABCDE";
126 
127 }  // namespace
128 }  // namespace str_format_internal
129 ABSL_NAMESPACE_END
130 }  // namespace absl
131