// 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 // // http://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