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 #include "absl/strings/internal/str_format/arg.h"
10 
11 #include <ostream>
12 #include <string>
13 #include "gtest/gtest.h"
14 #include "absl/strings/str_format.h"
15 
16 namespace absl {
17 ABSL_NAMESPACE_BEGIN
18 namespace str_format_internal {
19 namespace {
20 
21 class FormatArgImplTest : public ::testing::Test {
22  public:
23   enum Color { kRed, kGreen, kBlue };
24 
hi()25   static const char *hi() { return "hi"; }
26 };
27 
TEST_F(FormatArgImplTest,ToInt)28 TEST_F(FormatArgImplTest, ToInt) {
29   int out = 0;
30   EXPECT_TRUE(FormatArgImplFriend::ToInt(FormatArgImpl(1), &out));
31   EXPECT_EQ(1, out);
32   EXPECT_TRUE(FormatArgImplFriend::ToInt(FormatArgImpl(-1), &out));
33   EXPECT_EQ(-1, out);
34   EXPECT_TRUE(
35       FormatArgImplFriend::ToInt(FormatArgImpl(static_cast<char>(64)), &out));
36   EXPECT_EQ(64, out);
37   EXPECT_TRUE(FormatArgImplFriend::ToInt(
38       FormatArgImpl(static_cast<unsigned long long>(123456)), &out));  // NOLINT
39   EXPECT_EQ(123456, out);
40   EXPECT_TRUE(FormatArgImplFriend::ToInt(
41       FormatArgImpl(static_cast<unsigned long long>(  // NOLINT
42                         std::numeric_limits<int>::max()) +
43                     1),
44       &out));
45   EXPECT_EQ(std::numeric_limits<int>::max(), out);
46   EXPECT_TRUE(FormatArgImplFriend::ToInt(
47       FormatArgImpl(static_cast<long long>(  // NOLINT
48                         std::numeric_limits<int>::min()) -
49                     10),
50       &out));
51   EXPECT_EQ(std::numeric_limits<int>::min(), out);
52   EXPECT_TRUE(FormatArgImplFriend::ToInt(FormatArgImpl(false), &out));
53   EXPECT_EQ(0, out);
54   EXPECT_TRUE(FormatArgImplFriend::ToInt(FormatArgImpl(true), &out));
55   EXPECT_EQ(1, out);
56   EXPECT_FALSE(FormatArgImplFriend::ToInt(FormatArgImpl(2.2), &out));
57   EXPECT_FALSE(FormatArgImplFriend::ToInt(FormatArgImpl(3.2f), &out));
58   EXPECT_FALSE(FormatArgImplFriend::ToInt(
59       FormatArgImpl(static_cast<int *>(nullptr)), &out));
60   EXPECT_FALSE(FormatArgImplFriend::ToInt(FormatArgImpl(hi()), &out));
61   EXPECT_FALSE(FormatArgImplFriend::ToInt(FormatArgImpl("hi"), &out));
62   EXPECT_TRUE(FormatArgImplFriend::ToInt(FormatArgImpl(kBlue), &out));
63   EXPECT_EQ(2, out);
64 }
65 
66 extern const char kMyArray[];
67 
TEST_F(FormatArgImplTest,CharArraysDecayToCharPtr)68 TEST_F(FormatArgImplTest, CharArraysDecayToCharPtr) {
69   const char* a = "";
70   EXPECT_EQ(FormatArgImplFriend::GetVTablePtrForTest(FormatArgImpl(a)),
71             FormatArgImplFriend::GetVTablePtrForTest(FormatArgImpl("")));
72   EXPECT_EQ(FormatArgImplFriend::GetVTablePtrForTest(FormatArgImpl(a)),
73             FormatArgImplFriend::GetVTablePtrForTest(FormatArgImpl("A")));
74   EXPECT_EQ(FormatArgImplFriend::GetVTablePtrForTest(FormatArgImpl(a)),
75             FormatArgImplFriend::GetVTablePtrForTest(FormatArgImpl("ABC")));
76   EXPECT_EQ(FormatArgImplFriend::GetVTablePtrForTest(FormatArgImpl(a)),
77             FormatArgImplFriend::GetVTablePtrForTest(FormatArgImpl(kMyArray)));
78 }
79 
TEST_F(FormatArgImplTest,OtherPtrDecayToVoidPtr)80 TEST_F(FormatArgImplTest, OtherPtrDecayToVoidPtr) {
81   auto expected = FormatArgImplFriend::GetVTablePtrForTest(
82       FormatArgImpl(static_cast<void *>(nullptr)));
83   EXPECT_EQ(FormatArgImplFriend::GetVTablePtrForTest(
84                 FormatArgImpl(static_cast<int *>(nullptr))),
85             expected);
86   EXPECT_EQ(FormatArgImplFriend::GetVTablePtrForTest(
87                 FormatArgImpl(static_cast<volatile int *>(nullptr))),
88             expected);
89 
90   auto p = static_cast<void (*)()>([] {});
91   EXPECT_EQ(FormatArgImplFriend::GetVTablePtrForTest(FormatArgImpl(p)),
92             expected);
93 }
94 
TEST_F(FormatArgImplTest,WorksWithCharArraysOfUnknownSize)95 TEST_F(FormatArgImplTest, WorksWithCharArraysOfUnknownSize) {
96   std::string s;
97   FormatSinkImpl sink(&s);
98   ConversionSpec conv;
99   FormatConversionSpecImplFriend::SetConversionChar(ConversionChar::s, &conv);
100   FormatConversionSpecImplFriend::SetFlags(Flags(), &conv);
101   FormatConversionSpecImplFriend::SetWidth(-1, &conv);
102   FormatConversionSpecImplFriend::SetPrecision(-1, &conv);
103   EXPECT_TRUE(
104       FormatArgImplFriend::Convert(FormatArgImpl(kMyArray), conv, &sink));
105   sink.Flush();
106   EXPECT_EQ("ABCDE", s);
107 }
108 const char kMyArray[] = "ABCDE";
109 
110 }  // namespace
111 }  // namespace str_format_internal
112 ABSL_NAMESPACE_END
113 }  // namespace absl
114