| // Copyright 2017 The Abseil Authors. |
| // |
| // Licensed under the Apache License, Version 2.0 (the "License"); |
| // you may not use this file except in compliance with the License. |
| // You may obtain a copy of the License at |
| // |
| // https://www.apache.org/licenses/LICENSE-2.0 |
| // |
| #include "absl/strings/internal/str_format/arg.h" |
| |
| #include <ostream> |
| #include <string> |
| #include "gtest/gtest.h" |
| #include "absl/strings/str_format.h" |
| |
| namespace absl { |
| namespace str_format_internal { |
| namespace { |
| |
| class FormatArgImplTest : public ::testing::Test { |
| public: |
| enum Color { kRed, kGreen, kBlue }; |
| |
| static const char *hi() { return "hi"; } |
| }; |
| |
| TEST_F(FormatArgImplTest, ToInt) { |
| int out = 0; |
| EXPECT_TRUE(FormatArgImplFriend::ToInt(FormatArgImpl(1), &out)); |
| EXPECT_EQ(1, out); |
| EXPECT_TRUE(FormatArgImplFriend::ToInt(FormatArgImpl(-1), &out)); |
| EXPECT_EQ(-1, out); |
| EXPECT_TRUE( |
| FormatArgImplFriend::ToInt(FormatArgImpl(static_cast<char>(64)), &out)); |
| EXPECT_EQ(64, out); |
| EXPECT_TRUE(FormatArgImplFriend::ToInt( |
| FormatArgImpl(static_cast<unsigned long long>(123456)), &out)); // NOLINT |
| EXPECT_EQ(123456, out); |
| EXPECT_TRUE(FormatArgImplFriend::ToInt( |
| FormatArgImpl(static_cast<unsigned long long>( // NOLINT |
| std::numeric_limits<int>::max()) + |
| 1), |
| &out)); |
| EXPECT_EQ(std::numeric_limits<int>::max(), out); |
| EXPECT_TRUE(FormatArgImplFriend::ToInt( |
| FormatArgImpl(static_cast<long long>( // NOLINT |
| std::numeric_limits<int>::min()) - |
| 10), |
| &out)); |
| EXPECT_EQ(std::numeric_limits<int>::min(), out); |
| EXPECT_TRUE(FormatArgImplFriend::ToInt(FormatArgImpl(false), &out)); |
| EXPECT_EQ(0, out); |
| EXPECT_TRUE(FormatArgImplFriend::ToInt(FormatArgImpl(true), &out)); |
| EXPECT_EQ(1, out); |
| EXPECT_FALSE(FormatArgImplFriend::ToInt(FormatArgImpl(2.2), &out)); |
| EXPECT_FALSE(FormatArgImplFriend::ToInt(FormatArgImpl(3.2f), &out)); |
| EXPECT_FALSE(FormatArgImplFriend::ToInt( |
| FormatArgImpl(static_cast<int *>(nullptr)), &out)); |
| EXPECT_FALSE(FormatArgImplFriend::ToInt(FormatArgImpl(hi()), &out)); |
| EXPECT_FALSE(FormatArgImplFriend::ToInt(FormatArgImpl("hi"), &out)); |
| EXPECT_TRUE(FormatArgImplFriend::ToInt(FormatArgImpl(kBlue), &out)); |
| EXPECT_EQ(2, out); |
| } |
| |
| extern const char kMyArray[]; |
| |
| TEST_F(FormatArgImplTest, CharArraysDecayToCharPtr) { |
| const char* a = ""; |
| EXPECT_EQ(FormatArgImplFriend::GetVTablePtrForTest(FormatArgImpl(a)), |
| FormatArgImplFriend::GetVTablePtrForTest(FormatArgImpl(""))); |
| EXPECT_EQ(FormatArgImplFriend::GetVTablePtrForTest(FormatArgImpl(a)), |
| FormatArgImplFriend::GetVTablePtrForTest(FormatArgImpl("A"))); |
| EXPECT_EQ(FormatArgImplFriend::GetVTablePtrForTest(FormatArgImpl(a)), |
| FormatArgImplFriend::GetVTablePtrForTest(FormatArgImpl("ABC"))); |
| EXPECT_EQ(FormatArgImplFriend::GetVTablePtrForTest(FormatArgImpl(a)), |
| FormatArgImplFriend::GetVTablePtrForTest(FormatArgImpl(kMyArray))); |
| } |
| |
| TEST_F(FormatArgImplTest, OtherPtrDecayToVoidPtr) { |
| auto expected = FormatArgImplFriend::GetVTablePtrForTest( |
| FormatArgImpl(static_cast<void *>(nullptr))); |
| EXPECT_EQ(FormatArgImplFriend::GetVTablePtrForTest( |
| FormatArgImpl(static_cast<int *>(nullptr))), |
| expected); |
| EXPECT_EQ(FormatArgImplFriend::GetVTablePtrForTest( |
| FormatArgImpl(static_cast<volatile int *>(nullptr))), |
| expected); |
| |
| auto p = static_cast<void (*)()>([] {}); |
| EXPECT_EQ(FormatArgImplFriend::GetVTablePtrForTest(FormatArgImpl(p)), |
| expected); |
| } |
| |
| TEST_F(FormatArgImplTest, WorksWithCharArraysOfUnknownSize) { |
| std::string s; |
| FormatSinkImpl sink(&s); |
| ConversionSpec conv; |
| conv.set_conv(ConversionChar::FromChar('s')); |
| conv.set_flags(Flags()); |
| conv.set_width(-1); |
| conv.set_precision(-1); |
| EXPECT_TRUE( |
| FormatArgImplFriend::Convert(FormatArgImpl(kMyArray), conv, &sink)); |
| sink.Flush(); |
| EXPECT_EQ("ABCDE", s); |
| } |
| const char kMyArray[] = "ABCDE"; |
| |
| } // namespace |
| } // namespace str_format_internal |
| } // namespace absl |