#include #include #include #include namespace NYT { namespace { //////////////////////////////////////////////////////////////////////////////// // Some compile-time sanity checks. static_assert(TFormatTraits::HasCustomFormatValue); static_assert(TFormatTraits::HasCustomFormatValue); static_assert(TFormatTraits::HasCustomFormatValue); static_assert(TFormatTraits::HasCustomFormatValue); static_assert(TFormatTraits::HasCustomFormatValue); static_assert(TFormatTraits::HasCustomFormatValue); static_assert(TFormatTraits>::HasCustomFormatValue); // N.B. TCompactVector is not buildable on Windows static_assert(TFormatTraits>::HasCustomFormatValue); static_assert(TFormatTraits>::HasCustomFormatValue); static_assert(TFormatTraits>::HasCustomFormatValue); static_assert(TFormatTraits>::HasCustomFormatValue); static_assert(TFormatTraits>::HasCustomFormatValue); static_assert(TFormatTraits>::HasCustomFormatValue); static_assert(TFormatTraits>::HasCustomFormatValue); static_assert(TFormatTraits>::HasCustomFormatValue); static_assert(TFormatTraits>::HasCustomFormatValue); static_assert(TFormatTraits::HasCustomFormatValue); static_assert(TFormatTraits::HasCustomFormatValue); struct TUnformattable { }; static_assert(!TFormatTraits::HasCustomFormatValue); //////////////////////////////////////////////////////////////////////////////// TEST(TFormatTest, Nothing) { EXPECT_EQ("abc", Format("a%nb%nc", 1, 2)); } TEST(TFormatTest, Verbatim) { EXPECT_EQ("", Format("")); EXPECT_EQ("test", Format("test")); EXPECT_EQ("%", Format("%%")); EXPECT_EQ("%hello%world%", Format("%%hello%%world%%")); } TEST(TFormatTest, MultipleArgs) { EXPECT_EQ("2+2=4", Format("%v+%v=%v", 2, 2, 4)); } TEST(TFormatTest, Strings) { EXPECT_EQ("test", Format("%s", "test")); EXPECT_EQ("test", Format("%s", TStringBuf("test"))); EXPECT_EQ("test", Format("%s", TString("test"))); EXPECT_EQ(" abc", Format("%6s", TString("abc"))); EXPECT_EQ("abc ", Format("%-6s", TString("abc"))); EXPECT_EQ(" abc", Format("%10v", TString("abc"))); EXPECT_EQ("abc ", Format("%-10v", TString("abc"))); EXPECT_EQ("abc", Format("%2s", TString("abc"))); EXPECT_EQ("abc", Format("%-2s", TString("abc"))); EXPECT_EQ("abc", Format("%0s", TString("abc"))); EXPECT_EQ("abc", Format("%-0s", TString("abc"))); EXPECT_EQ(100, std::ssize(Format("%100v", "abc"))); } TEST(TFormatTest, Integers) { EXPECT_EQ("123", Format("%d", 123)); EXPECT_EQ("123", Format("%v", 123)); EXPECT_EQ("042", Format("%03d", 42)); EXPECT_EQ("42", Format("%01d", 42)); EXPECT_EQ("2147483647", Format("%d", std::numeric_limits::max())); EXPECT_EQ("-2147483648", Format("%d", std::numeric_limits::min())); EXPECT_EQ("0", Format("%u", 0U)); EXPECT_EQ("0", Format("%v", 0U)); EXPECT_EQ("4294967295", Format("%u", std::numeric_limits::max())); EXPECT_EQ("4294967295", Format("%v", std::numeric_limits::max())); EXPECT_EQ("9223372036854775807", Format("%" PRId64, std::numeric_limits::max())); EXPECT_EQ("9223372036854775807", Format("%v", std::numeric_limits::max())); EXPECT_EQ("-9223372036854775808", Format("%" PRId64, std::numeric_limits::min())); EXPECT_EQ("-9223372036854775808", Format("%v", std::numeric_limits::min())); EXPECT_EQ("0", Format("%" PRIu64, 0ULL)); EXPECT_EQ("0", Format("%v", 0ULL)); EXPECT_EQ("18446744073709551615", Format("%" PRIu64, std::numeric_limits::max())); EXPECT_EQ("18446744073709551615", Format("%v", std::numeric_limits::max())); } TEST(TFormatTest, Floats) { EXPECT_EQ("3.14", Format("%.2f", 3.1415F)); EXPECT_EQ("3.14", Format("%.2v", 3.1415F)); EXPECT_EQ("3.14", Format("%.2lf", 3.1415)); EXPECT_EQ("3.14", Format("%.2v", 3.1415)); EXPECT_EQ(TString(std::to_string(std::numeric_limits::max())), Format("%lF", std::numeric_limits::max())); } TEST(TFormatTest, Bool) { EXPECT_EQ("True", Format("%v", true)); EXPECT_EQ("False", Format("%v", false)); EXPECT_EQ("true", Format("%lv", true)); EXPECT_EQ("false", Format("%lv", false)); } TEST(TFormatTest, Quotes) { EXPECT_EQ("\"True\"", Format("%Qv", true)); EXPECT_EQ("'False'", Format("%qv", false)); EXPECT_EQ("'\\\'\"'", Format("%qv", "\'\"")); EXPECT_EQ("\"\\x01\"", Format("%Qv", "\x1")); EXPECT_EQ("'\\x1b'", Format("%qv", '\x1b')); } TEST(TFormatTest, Nullable) { EXPECT_EQ("1", Format("%v", std::make_optional(1))); EXPECT_EQ("", Format("%v", std::nullopt)); EXPECT_EQ("", Format("%v", std::optional())); EXPECT_EQ("3.14", Format("%.2f", std::optional(3.1415))); } TEST(TFormatTest, Pointers) { // No idea if pointer format is standardized, check against Sprintf. auto p = reinterpret_cast(123); EXPECT_EQ(Sprintf("%p", reinterpret_cast(123)), Format("%p", p)); } //////////////////////////////////////////////////////////////////////////////// } // namespace } // namespace NYT