• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 <limits>
18 #include <string>
19 #include "gtest/gtest.h"
20 #include "absl/base/config.h"
21 #include "absl/strings/str_format.h"
22 
23 namespace absl {
24 ABSL_NAMESPACE_BEGIN
25 namespace str_format_internal {
26 namespace {
27 
28 class FormatArgImplTest : public ::testing::Test {
29  public:
30   enum Color { kRed, kGreen, kBlue };
31 
hi()32   static const char *hi() { return "hi"; }
33 
34   struct X {};
35 
36   X x_;
37 };
38 
AbslFormatConvert(const FormatArgImplTest::X &,const FormatConversionSpec &,FormatSink *)39 inline FormatConvertResult<FormatConversionCharSet{}> AbslFormatConvert(
40     const FormatArgImplTest::X &, const FormatConversionSpec &, FormatSink *) {
41   return {false};
42 }
43 
TEST_F(FormatArgImplTest,ToInt)44 TEST_F(FormatArgImplTest, ToInt) {
45   int out = 0;
46   EXPECT_TRUE(FormatArgImplFriend::ToInt(FormatArgImpl(1), &out));
47   EXPECT_EQ(1, out);
48   EXPECT_TRUE(FormatArgImplFriend::ToInt(FormatArgImpl(-1), &out));
49   EXPECT_EQ(-1, out);
50   EXPECT_TRUE(
51       FormatArgImplFriend::ToInt(FormatArgImpl(static_cast<char>(64)), &out));
52   EXPECT_EQ(64, out);
53   EXPECT_TRUE(FormatArgImplFriend::ToInt(
54       FormatArgImpl(static_cast<unsigned long long>(123456)), &out));  // NOLINT
55   EXPECT_EQ(123456, out);
56   EXPECT_TRUE(FormatArgImplFriend::ToInt(
57       FormatArgImpl(static_cast<unsigned long long>(  // NOLINT
58                         std::numeric_limits<int>::max()) +
59                     1),
60       &out));
61   EXPECT_EQ(std::numeric_limits<int>::max(), out);
62   EXPECT_TRUE(FormatArgImplFriend::ToInt(
63       FormatArgImpl(static_cast<long long>(  // NOLINT
64                         std::numeric_limits<int>::min()) -
65                     10),
66       &out));
67   EXPECT_EQ(std::numeric_limits<int>::min(), out);
68   EXPECT_TRUE(FormatArgImplFriend::ToInt(FormatArgImpl(false), &out));
69   EXPECT_EQ(0, out);
70   EXPECT_TRUE(FormatArgImplFriend::ToInt(FormatArgImpl(true), &out));
71   EXPECT_EQ(1, out);
72   EXPECT_FALSE(FormatArgImplFriend::ToInt(FormatArgImpl(2.2), &out));
73   EXPECT_FALSE(FormatArgImplFriend::ToInt(FormatArgImpl(3.2f), &out));
74   EXPECT_FALSE(FormatArgImplFriend::ToInt(
75       FormatArgImpl(static_cast<int *>(nullptr)), &out));
76   EXPECT_FALSE(FormatArgImplFriend::ToInt(FormatArgImpl(hi()), &out));
77   EXPECT_FALSE(FormatArgImplFriend::ToInt(FormatArgImpl("hi"), &out));
78   EXPECT_FALSE(FormatArgImplFriend::ToInt(FormatArgImpl(x_), &out));
79   EXPECT_TRUE(FormatArgImplFriend::ToInt(FormatArgImpl(kBlue), &out));
80   EXPECT_EQ(2, out);
81 }
82 
83 extern const char kMyArray[];
84 
TEST_F(FormatArgImplTest,CharArraysDecayToCharPtr)85 TEST_F(FormatArgImplTest, CharArraysDecayToCharPtr) {
86   const char* a = "";
87   EXPECT_EQ(FormatArgImplFriend::GetVTablePtrForTest(FormatArgImpl(a)),
88             FormatArgImplFriend::GetVTablePtrForTest(FormatArgImpl("")));
89   EXPECT_EQ(FormatArgImplFriend::GetVTablePtrForTest(FormatArgImpl(a)),
90             FormatArgImplFriend::GetVTablePtrForTest(FormatArgImpl("A")));
91   EXPECT_EQ(FormatArgImplFriend::GetVTablePtrForTest(FormatArgImpl(a)),
92             FormatArgImplFriend::GetVTablePtrForTest(FormatArgImpl("ABC")));
93   EXPECT_EQ(FormatArgImplFriend::GetVTablePtrForTest(FormatArgImpl(a)),
94             FormatArgImplFriend::GetVTablePtrForTest(FormatArgImpl(kMyArray)));
95 }
96 
97 extern const wchar_t kMyWCharTArray[];
98 
TEST_F(FormatArgImplTest,WCharTArraysDecayToWCharTPtr)99 TEST_F(FormatArgImplTest, WCharTArraysDecayToWCharTPtr) {
100   const wchar_t* a = L"";
101   EXPECT_EQ(FormatArgImplFriend::GetVTablePtrForTest(FormatArgImpl(a)),
102             FormatArgImplFriend::GetVTablePtrForTest(FormatArgImpl(L"")));
103   EXPECT_EQ(FormatArgImplFriend::GetVTablePtrForTest(FormatArgImpl(a)),
104             FormatArgImplFriend::GetVTablePtrForTest(FormatArgImpl(L"A")));
105   EXPECT_EQ(FormatArgImplFriend::GetVTablePtrForTest(FormatArgImpl(a)),
106             FormatArgImplFriend::GetVTablePtrForTest(FormatArgImpl(L"ABC")));
107   EXPECT_EQ(
108       FormatArgImplFriend::GetVTablePtrForTest(FormatArgImpl(a)),
109       FormatArgImplFriend::GetVTablePtrForTest(FormatArgImpl(kMyWCharTArray)));
110 }
111 
TEST_F(FormatArgImplTest,OtherPtrDecayToVoidPtr)112 TEST_F(FormatArgImplTest, OtherPtrDecayToVoidPtr) {
113   auto expected = FormatArgImplFriend::GetVTablePtrForTest(
114       FormatArgImpl(static_cast<void *>(nullptr)));
115   EXPECT_EQ(FormatArgImplFriend::GetVTablePtrForTest(
116                 FormatArgImpl(static_cast<int *>(nullptr))),
117             expected);
118   EXPECT_EQ(FormatArgImplFriend::GetVTablePtrForTest(
119                 FormatArgImpl(static_cast<volatile int *>(nullptr))),
120             expected);
121 
122   auto p = static_cast<void (*)()>([] {});
123   EXPECT_EQ(FormatArgImplFriend::GetVTablePtrForTest(FormatArgImpl(p)),
124             expected);
125 }
126 
TEST_F(FormatArgImplTest,WorksWithCharArraysOfUnknownSize)127 TEST_F(FormatArgImplTest, WorksWithCharArraysOfUnknownSize) {
128   std::string s;
129   FormatSinkImpl sink(&s);
130   FormatConversionSpecImpl conv;
131   FormatConversionSpecImplFriend::SetConversionChar(
132       FormatConversionCharInternal::s, &conv);
133   FormatConversionSpecImplFriend::SetFlags(Flags(), &conv);
134   FormatConversionSpecImplFriend::SetWidth(-1, &conv);
135   FormatConversionSpecImplFriend::SetPrecision(-1, &conv);
136   EXPECT_TRUE(
137       FormatArgImplFriend::Convert(FormatArgImpl(kMyArray), conv, &sink));
138   sink.Flush();
139   EXPECT_EQ("ABCDE", s);
140 }
141 const char kMyArray[] = "ABCDE";
142 
TEST_F(FormatArgImplTest,WorksWithWCharTArraysOfUnknownSize)143 TEST_F(FormatArgImplTest, WorksWithWCharTArraysOfUnknownSize) {
144   std::string s;
145   FormatSinkImpl sink(&s);
146   FormatConversionSpecImpl conv;
147   FormatConversionSpecImplFriend::SetConversionChar(
148       FormatConversionCharInternal::s, &conv);
149   FormatConversionSpecImplFriend::SetFlags(Flags(), &conv);
150   FormatConversionSpecImplFriend::SetWidth(-1, &conv);
151   FormatConversionSpecImplFriend::SetPrecision(-1, &conv);
152   EXPECT_TRUE(
153       FormatArgImplFriend::Convert(FormatArgImpl(kMyWCharTArray), conv, &sink));
154   sink.Flush();
155   EXPECT_EQ("ABCDE", s);
156 }
157 const wchar_t kMyWCharTArray[] = L"ABCDE";
158 
159 }  // namespace
160 }  // namespace str_format_internal
161 ABSL_NAMESPACE_END
162 }  // namespace absl
163