diff options
author | orivej <orivej@yandex-team.ru> | 2022-02-10 16:45:01 +0300 |
---|---|---|
committer | Daniil Cherednik <dcherednik@yandex-team.ru> | 2022-02-10 16:45:01 +0300 |
commit | 2d37894b1b037cf24231090eda8589bbb44fb6fc (patch) | |
tree | be835aa92c6248212e705f25388ebafcf84bc7a1 /contrib/libs/fmt/test | |
parent | 718c552901d703c502ccbefdfc3c9028d608b947 (diff) | |
download | ydb-2d37894b1b037cf24231090eda8589bbb44fb6fc.tar.gz |
Restoring authorship annotation for <orivej@yandex-team.ru>. Commit 2 of 2.
Diffstat (limited to 'contrib/libs/fmt/test')
42 files changed, 7620 insertions, 7620 deletions
diff --git a/contrib/libs/fmt/test/assert-test.cc b/contrib/libs/fmt/test/assert-test.cc index 41fb29a92f..73f622e56b 100644 --- a/contrib/libs/fmt/test/assert-test.cc +++ b/contrib/libs/fmt/test/assert-test.cc @@ -1,32 +1,32 @@ // Formatting library for C++ - FMT_ASSERT test -// +// // It is a separate test to minimize the number of EXPECT_DEBUG_DEATH checks // which are slow on some platforms. In other tests FMT_ASSERT is made to throw // an exception which is much faster and easier to check. // -// Copyright (c) 2012 - present, Victor Zverovich -// All rights reserved. -// -// For the license information refer to format.h. - -#include "fmt/core.h" -#include <gtest/gtest.h> - -TEST(AssertTest, Fail) { -#if GTEST_HAS_DEATH_TEST - EXPECT_DEBUG_DEATH(FMT_ASSERT(false, "don't panic!"), "don't panic!"); -#else - fmt::print("warning: death tests are not supported\n"); -#endif -} - -bool test_condition = false; - -TEST(AssertTest, DanglingElse) { - bool executed_else = false; - if (test_condition) - FMT_ASSERT(true, ""); - else - executed_else = true; - EXPECT_TRUE(executed_else); -} +// Copyright (c) 2012 - present, Victor Zverovich +// All rights reserved. +// +// For the license information refer to format.h. + +#include "fmt/core.h" +#include <gtest/gtest.h> + +TEST(AssertTest, Fail) { +#if GTEST_HAS_DEATH_TEST + EXPECT_DEBUG_DEATH(FMT_ASSERT(false, "don't panic!"), "don't panic!"); +#else + fmt::print("warning: death tests are not supported\n"); +#endif +} + +bool test_condition = false; + +TEST(AssertTest, DanglingElse) { + bool executed_else = false; + if (test_condition) + FMT_ASSERT(true, ""); + else + executed_else = true; + EXPECT_TRUE(executed_else); +} diff --git a/contrib/libs/fmt/test/assert-test/ya.make b/contrib/libs/fmt/test/assert-test/ya.make index e861be6557..22d19ae00a 100644 --- a/contrib/libs/fmt/test/assert-test/ya.make +++ b/contrib/libs/fmt/test/assert-test/ya.make @@ -1,37 +1,37 @@ -# Generated by devtools/yamaker. - +# Generated by devtools/yamaker. + GTEST() - + WITHOUT_LICENSE_TEXTS() - + OWNER( orivej g:cpp-contrib ) -LICENSE(MIT) - -PEERDIR( - contrib/libs/fmt - contrib/libs/fmt/test -) - -NO_COMPILER_WARNINGS() - -NO_UTIL() - -CFLAGS( - -DFMT_LOCALE - -DFMT_SHARED - -DGTEST_HAS_STD_WSTRING=1 - -DGTEST_LANG_CXX11=0 - -D_SILENCE_TR1_NAMESPACE_DEPRECATION_WARNING=1 -) - -SRCDIR(contrib/libs/fmt/test) - -SRCS( - assert-test.cc -) - -END() +LICENSE(MIT) + +PEERDIR( + contrib/libs/fmt + contrib/libs/fmt/test +) + +NO_COMPILER_WARNINGS() + +NO_UTIL() + +CFLAGS( + -DFMT_LOCALE + -DFMT_SHARED + -DGTEST_HAS_STD_WSTRING=1 + -DGTEST_LANG_CXX11=0 + -D_SILENCE_TR1_NAMESPACE_DEPRECATION_WARNING=1 +) + +SRCDIR(contrib/libs/fmt/test) + +SRCS( + assert-test.cc +) + +END() diff --git a/contrib/libs/fmt/test/chrono-test.cc b/contrib/libs/fmt/test/chrono-test.cc index eb132ef95e..fa383c1446 100644 --- a/contrib/libs/fmt/test/chrono-test.cc +++ b/contrib/libs/fmt/test/chrono-test.cc @@ -1,100 +1,100 @@ -// Formatting library for C++ - time formatting tests -// -// Copyright (c) 2012 - present, Victor Zverovich -// All rights reserved. -// -// For the license information refer to format.h. - -#ifdef WIN32 -# define _CRT_SECURE_NO_WARNINGS -#endif - -#include "fmt/chrono.h" - -#include <iomanip> - +// Formatting library for C++ - time formatting tests +// +// Copyright (c) 2012 - present, Victor Zverovich +// All rights reserved. +// +// For the license information refer to format.h. + +#ifdef WIN32 +# define _CRT_SECURE_NO_WARNINGS +#endif + +#include "fmt/chrono.h" + +#include <iomanip> + #include "gtest-extra.h" -std::tm make_tm() { - auto time = std::tm(); - time.tm_mday = 1; - return time; -} - -std::tm make_hour(int h) { - auto time = make_tm(); - time.tm_hour = h; - return time; -} - -std::tm make_minute(int m) { - auto time = make_tm(); - time.tm_min = m; - return time; -} - -std::tm make_second(int s) { - auto time = make_tm(); - time.tm_sec = s; - return time; -} - -std::string format_tm(const std::tm& time, const char* spec, - const std::locale& loc) { - auto& facet = std::use_facet<std::time_put<char>>(loc); - std::ostringstream os; - os.imbue(loc); - facet.put(os, os, ' ', &time, spec, spec + std::strlen(spec)); - return os.str(); -} - -TEST(TimeTest, Format) { - std::tm tm = std::tm(); - tm.tm_year = 116; - tm.tm_mon = 3; - tm.tm_mday = 25; - EXPECT_EQ("The date is 2016-04-25.", - fmt::format("The date is {:%Y-%m-%d}.", tm)); -} - -TEST(TimeTest, GrowBuffer) { - std::string s = "{:"; - for (int i = 0; i < 30; ++i) s += "%c"; - s += "}\n"; - std::time_t t = std::time(nullptr); - fmt::format(s, *std::localtime(&t)); -} - -TEST(TimeTest, FormatToEmptyContainer) { - std::string s; - auto time = std::tm(); - time.tm_sec = 42; - fmt::format_to(std::back_inserter(s), "{:%S}", time); - EXPECT_EQ(s, "42"); -} - -TEST(TimeTest, EmptyResult) { EXPECT_EQ("", fmt::format("{}", std::tm())); } - -static bool EqualTime(const std::tm& lhs, const std::tm& rhs) { - return lhs.tm_sec == rhs.tm_sec && lhs.tm_min == rhs.tm_min && - lhs.tm_hour == rhs.tm_hour && lhs.tm_mday == rhs.tm_mday && - lhs.tm_mon == rhs.tm_mon && lhs.tm_year == rhs.tm_year && - lhs.tm_wday == rhs.tm_wday && lhs.tm_yday == rhs.tm_yday && - lhs.tm_isdst == rhs.tm_isdst; -} - -TEST(TimeTest, LocalTime) { - std::time_t t = std::time(nullptr); - std::tm tm = *std::localtime(&t); - EXPECT_TRUE(EqualTime(tm, fmt::localtime(t))); -} - -TEST(TimeTest, GMTime) { - std::time_t t = std::time(nullptr); - std::tm tm = *std::gmtime(&t); - EXPECT_TRUE(EqualTime(tm, fmt::gmtime(t))); -} - +std::tm make_tm() { + auto time = std::tm(); + time.tm_mday = 1; + return time; +} + +std::tm make_hour(int h) { + auto time = make_tm(); + time.tm_hour = h; + return time; +} + +std::tm make_minute(int m) { + auto time = make_tm(); + time.tm_min = m; + return time; +} + +std::tm make_second(int s) { + auto time = make_tm(); + time.tm_sec = s; + return time; +} + +std::string format_tm(const std::tm& time, const char* spec, + const std::locale& loc) { + auto& facet = std::use_facet<std::time_put<char>>(loc); + std::ostringstream os; + os.imbue(loc); + facet.put(os, os, ' ', &time, spec, spec + std::strlen(spec)); + return os.str(); +} + +TEST(TimeTest, Format) { + std::tm tm = std::tm(); + tm.tm_year = 116; + tm.tm_mon = 3; + tm.tm_mday = 25; + EXPECT_EQ("The date is 2016-04-25.", + fmt::format("The date is {:%Y-%m-%d}.", tm)); +} + +TEST(TimeTest, GrowBuffer) { + std::string s = "{:"; + for (int i = 0; i < 30; ++i) s += "%c"; + s += "}\n"; + std::time_t t = std::time(nullptr); + fmt::format(s, *std::localtime(&t)); +} + +TEST(TimeTest, FormatToEmptyContainer) { + std::string s; + auto time = std::tm(); + time.tm_sec = 42; + fmt::format_to(std::back_inserter(s), "{:%S}", time); + EXPECT_EQ(s, "42"); +} + +TEST(TimeTest, EmptyResult) { EXPECT_EQ("", fmt::format("{}", std::tm())); } + +static bool EqualTime(const std::tm& lhs, const std::tm& rhs) { + return lhs.tm_sec == rhs.tm_sec && lhs.tm_min == rhs.tm_min && + lhs.tm_hour == rhs.tm_hour && lhs.tm_mday == rhs.tm_mday && + lhs.tm_mon == rhs.tm_mon && lhs.tm_year == rhs.tm_year && + lhs.tm_wday == rhs.tm_wday && lhs.tm_yday == rhs.tm_yday && + lhs.tm_isdst == rhs.tm_isdst; +} + +TEST(TimeTest, LocalTime) { + std::time_t t = std::time(nullptr); + std::tm tm = *std::localtime(&t); + EXPECT_TRUE(EqualTime(tm, fmt::localtime(t))); +} + +TEST(TimeTest, GMTime) { + std::time_t t = std::time(nullptr); + std::tm tm = *std::gmtime(&t); + EXPECT_TRUE(EqualTime(tm, fmt::gmtime(t))); +} + TEST(TimeTest, TimePoint) { std::chrono::system_clock::time_point point = std::chrono::system_clock::now(); @@ -106,293 +106,293 @@ TEST(TimeTest, TimePoint) { EXPECT_EQ(strftime_output, fmt::format("It is {:%Y-%m-%d %H:%M:%S}", point)); } -#define EXPECT_TIME(spec, time, duration) \ - { \ - std::locale loc("ja_JP.utf8"); \ - EXPECT_EQ(format_tm(time, spec, loc), \ - fmt::format(loc, "{:" spec "}", duration)); \ - } - -#ifndef FMT_STATIC_THOUSANDS_SEPARATOR - -TEST(ChronoTest, FormatDefault) { - EXPECT_EQ("42s", fmt::format("{}", std::chrono::seconds(42))); - EXPECT_EQ("42as", - fmt::format("{}", std::chrono::duration<int, std::atto>(42))); - EXPECT_EQ("42fs", - fmt::format("{}", std::chrono::duration<int, std::femto>(42))); - EXPECT_EQ("42ps", - fmt::format("{}", std::chrono::duration<int, std::pico>(42))); - EXPECT_EQ("42ns", fmt::format("{}", std::chrono::nanoseconds(42))); - EXPECT_EQ("42µs", fmt::format("{}", std::chrono::microseconds(42))); - EXPECT_EQ("42ms", fmt::format("{}", std::chrono::milliseconds(42))); - EXPECT_EQ("42cs", - fmt::format("{}", std::chrono::duration<int, std::centi>(42))); - EXPECT_EQ("42ds", - fmt::format("{}", std::chrono::duration<int, std::deci>(42))); - EXPECT_EQ("42s", fmt::format("{}", std::chrono::seconds(42))); - EXPECT_EQ("42das", - fmt::format("{}", std::chrono::duration<int, std::deca>(42))); - EXPECT_EQ("42hs", - fmt::format("{}", std::chrono::duration<int, std::hecto>(42))); - EXPECT_EQ("42ks", - fmt::format("{}", std::chrono::duration<int, std::kilo>(42))); - EXPECT_EQ("42Ms", - fmt::format("{}", std::chrono::duration<int, std::mega>(42))); - EXPECT_EQ("42Gs", - fmt::format("{}", std::chrono::duration<int, std::giga>(42))); - EXPECT_EQ("42Ts", - fmt::format("{}", std::chrono::duration<int, std::tera>(42))); - EXPECT_EQ("42Ps", - fmt::format("{}", std::chrono::duration<int, std::peta>(42))); - EXPECT_EQ("42Es", - fmt::format("{}", std::chrono::duration<int, std::exa>(42))); - EXPECT_EQ("42m", fmt::format("{}", std::chrono::minutes(42))); - EXPECT_EQ("42h", fmt::format("{}", std::chrono::hours(42))); - EXPECT_EQ( - "42[15]s", - fmt::format("{}", std::chrono::duration<int, std::ratio<15, 1>>(42))); - EXPECT_EQ( - "42[15/4]s", - fmt::format("{}", std::chrono::duration<int, std::ratio<15, 4>>(42))); -} - -TEST(ChronoTest, FormatWide) { - EXPECT_EQ(L"42s", fmt::format(L"{}", std::chrono::seconds(42))); - EXPECT_EQ(L"42as", - fmt::format(L"{}", std::chrono::duration<int, std::atto>(42))); - EXPECT_EQ(L"42fs", - fmt::format(L"{}", std::chrono::duration<int, std::femto>(42))); - EXPECT_EQ(L"42ps", - fmt::format(L"{}", std::chrono::duration<int, std::pico>(42))); - EXPECT_EQ(L"42ns", fmt::format(L"{}", std::chrono::nanoseconds(42))); - EXPECT_EQ(L"42\u00B5s", fmt::format(L"{}", std::chrono::microseconds(42))); - EXPECT_EQ(L"42ms", fmt::format(L"{}", std::chrono::milliseconds(42))); - EXPECT_EQ(L"42cs", - fmt::format(L"{}", std::chrono::duration<int, std::centi>(42))); - EXPECT_EQ(L"42ds", - fmt::format(L"{}", std::chrono::duration<int, std::deci>(42))); - EXPECT_EQ(L"42s", fmt::format(L"{}", std::chrono::seconds(42))); - EXPECT_EQ(L"42das", - fmt::format(L"{}", std::chrono::duration<int, std::deca>(42))); - EXPECT_EQ(L"42hs", - fmt::format(L"{}", std::chrono::duration<int, std::hecto>(42))); - EXPECT_EQ(L"42ks", - fmt::format(L"{}", std::chrono::duration<int, std::kilo>(42))); - EXPECT_EQ(L"42Ms", - fmt::format(L"{}", std::chrono::duration<int, std::mega>(42))); - EXPECT_EQ(L"42Gs", - fmt::format(L"{}", std::chrono::duration<int, std::giga>(42))); - EXPECT_EQ(L"42Ts", - fmt::format(L"{}", std::chrono::duration<int, std::tera>(42))); - EXPECT_EQ(L"42Ps", - fmt::format(L"{}", std::chrono::duration<int, std::peta>(42))); - EXPECT_EQ(L"42Es", - fmt::format(L"{}", std::chrono::duration<int, std::exa>(42))); - EXPECT_EQ(L"42m", fmt::format(L"{}", std::chrono::minutes(42))); - EXPECT_EQ(L"42h", fmt::format(L"{}", std::chrono::hours(42))); - EXPECT_EQ( - L"42[15]s", - fmt::format(L"{}", std::chrono::duration<int, std::ratio<15, 1>>(42))); - EXPECT_EQ( - L"42[15/4]s", - fmt::format(L"{}", std::chrono::duration<int, std::ratio<15, 4>>(42))); -} - -TEST(ChronoTest, Align) { - auto s = std::chrono::seconds(42); - EXPECT_EQ("42s ", fmt::format("{:5}", s)); - EXPECT_EQ("42s ", fmt::format("{:{}}", s, 5)); - EXPECT_EQ(" 42s", fmt::format("{:>5}", s)); - EXPECT_EQ("**42s**", fmt::format("{:*^7}", s)); - EXPECT_EQ("03:25:45 ", - fmt::format("{:12%H:%M:%S}", std::chrono::seconds(12345))); - EXPECT_EQ(" 03:25:45", - fmt::format("{:>12%H:%M:%S}", std::chrono::seconds(12345))); - EXPECT_EQ("~~03:25:45~~", - fmt::format("{:~^12%H:%M:%S}", std::chrono::seconds(12345))); - EXPECT_EQ("03:25:45 ", - fmt::format("{:{}%H:%M:%S}", std::chrono::seconds(12345), 12)); -} - -TEST(ChronoTest, FormatSpecs) { - EXPECT_EQ("%", fmt::format("{:%%}", std::chrono::seconds(0))); - EXPECT_EQ("\n", fmt::format("{:%n}", std::chrono::seconds(0))); - EXPECT_EQ("\t", fmt::format("{:%t}", std::chrono::seconds(0))); - EXPECT_EQ("00", fmt::format("{:%S}", std::chrono::seconds(0))); - EXPECT_EQ("00", fmt::format("{:%S}", std::chrono::seconds(60))); - EXPECT_EQ("42", fmt::format("{:%S}", std::chrono::seconds(42))); - EXPECT_EQ("01.234", fmt::format("{:%S}", std::chrono::milliseconds(1234))); - EXPECT_EQ("00", fmt::format("{:%M}", std::chrono::minutes(0))); - EXPECT_EQ("00", fmt::format("{:%M}", std::chrono::minutes(60))); - EXPECT_EQ("42", fmt::format("{:%M}", std::chrono::minutes(42))); - EXPECT_EQ("01", fmt::format("{:%M}", std::chrono::seconds(61))); - EXPECT_EQ("00", fmt::format("{:%H}", std::chrono::hours(0))); - EXPECT_EQ("00", fmt::format("{:%H}", std::chrono::hours(24))); - EXPECT_EQ("14", fmt::format("{:%H}", std::chrono::hours(14))); - EXPECT_EQ("01", fmt::format("{:%H}", std::chrono::minutes(61))); - EXPECT_EQ("12", fmt::format("{:%I}", std::chrono::hours(0))); - EXPECT_EQ("12", fmt::format("{:%I}", std::chrono::hours(12))); - EXPECT_EQ("12", fmt::format("{:%I}", std::chrono::hours(24))); - EXPECT_EQ("04", fmt::format("{:%I}", std::chrono::hours(4))); - EXPECT_EQ("02", fmt::format("{:%I}", std::chrono::hours(14))); - EXPECT_EQ("03:25:45", - fmt::format("{:%H:%M:%S}", std::chrono::seconds(12345))); - EXPECT_EQ("03:25", fmt::format("{:%R}", std::chrono::seconds(12345))); - EXPECT_EQ("03:25:45", fmt::format("{:%T}", std::chrono::seconds(12345))); - EXPECT_EQ("12345", fmt::format("{:%Q}", std::chrono::seconds(12345))); - EXPECT_EQ("s", fmt::format("{:%q}", std::chrono::seconds(12345))); -} - -TEST(ChronoTest, InvalidSpecs) { - auto sec = std::chrono::seconds(0); - EXPECT_THROW_MSG(fmt::format("{:%a}", sec), fmt::format_error, "no date"); - EXPECT_THROW_MSG(fmt::format("{:%A}", sec), fmt::format_error, "no date"); - EXPECT_THROW_MSG(fmt::format("{:%c}", sec), fmt::format_error, "no date"); - EXPECT_THROW_MSG(fmt::format("{:%x}", sec), fmt::format_error, "no date"); - EXPECT_THROW_MSG(fmt::format("{:%Ex}", sec), fmt::format_error, "no date"); - EXPECT_THROW_MSG(fmt::format("{:%X}", sec), fmt::format_error, "no date"); - EXPECT_THROW_MSG(fmt::format("{:%EX}", sec), fmt::format_error, "no date"); - EXPECT_THROW_MSG(fmt::format("{:%D}", sec), fmt::format_error, "no date"); - EXPECT_THROW_MSG(fmt::format("{:%F}", sec), fmt::format_error, "no date"); - EXPECT_THROW_MSG(fmt::format("{:%Ec}", sec), fmt::format_error, "no date"); - EXPECT_THROW_MSG(fmt::format("{:%w}", sec), fmt::format_error, "no date"); - EXPECT_THROW_MSG(fmt::format("{:%u}", sec), fmt::format_error, "no date"); - EXPECT_THROW_MSG(fmt::format("{:%b}", sec), fmt::format_error, "no date"); - EXPECT_THROW_MSG(fmt::format("{:%B}", sec), fmt::format_error, "no date"); - EXPECT_THROW_MSG(fmt::format("{:%z}", sec), fmt::format_error, "no date"); - EXPECT_THROW_MSG(fmt::format("{:%Z}", sec), fmt::format_error, "no date"); - EXPECT_THROW_MSG(fmt::format("{:%Eq}", sec), fmt::format_error, - "invalid format"); - EXPECT_THROW_MSG(fmt::format("{:%Oq}", sec), fmt::format_error, - "invalid format"); -} - -TEST(ChronoTest, Locale) { - const char* loc_name = "ja_JP.utf8"; - bool has_locale = false; - std::locale loc; - try { - loc = std::locale(loc_name); - has_locale = true; - } catch (const std::runtime_error&) { - } - if (!has_locale) { - fmt::print("{} locale is missing.\n", loc_name); - return; - } - EXPECT_TIME("%OH", make_hour(14), std::chrono::hours(14)); - EXPECT_TIME("%OI", make_hour(14), std::chrono::hours(14)); - EXPECT_TIME("%OM", make_minute(42), std::chrono::minutes(42)); - EXPECT_TIME("%OS", make_second(42), std::chrono::seconds(42)); - auto time = make_tm(); - time.tm_hour = 3; - time.tm_min = 25; - time.tm_sec = 45; - auto sec = std::chrono::seconds(12345); - EXPECT_TIME("%r", time, sec); - EXPECT_TIME("%p", time, sec); -} - -typedef std::chrono::duration<double, std::milli> dms; - -TEST(ChronoTest, FormatDefaultFP) { - typedef std::chrono::duration<float> fs; - EXPECT_EQ("1.234s", fmt::format("{}", fs(1.234))); - typedef std::chrono::duration<float, std::milli> fms; - EXPECT_EQ("1.234ms", fmt::format("{}", fms(1.234))); - typedef std::chrono::duration<double> ds; - EXPECT_EQ("1.234s", fmt::format("{}", ds(1.234))); - EXPECT_EQ("1.234ms", fmt::format("{}", dms(1.234))); -} - -TEST(ChronoTest, FormatPrecision) { - EXPECT_THROW_MSG(fmt::format("{:.2}", std::chrono::seconds(42)), - fmt::format_error, - "precision not allowed for this argument type"); - EXPECT_EQ("1.2ms", fmt::format("{:.1}", dms(1.234))); - EXPECT_EQ("1.23ms", fmt::format("{:.{}}", dms(1.234), 2)); -} - -TEST(ChronoTest, FormatFullSpecs) { - EXPECT_EQ("1.2ms ", fmt::format("{:6.1}", dms(1.234))); - EXPECT_EQ(" 1.23ms", fmt::format("{:>8.{}}", dms(1.234), 2)); - EXPECT_EQ(" 1.2ms ", fmt::format("{:^{}.{}}", dms(1.234), 7, 1)); - EXPECT_EQ(" 1.23ms ", fmt::format("{0:^{2}.{1}}", dms(1.234), 2, 8)); - EXPECT_EQ("=1.234ms=", fmt::format("{:=^{}.{}}", dms(1.234), 9, 3)); - EXPECT_EQ("*1.2340ms*", fmt::format("{:*^10.4}", dms(1.234))); -} - -TEST(ChronoTest, FormatSimpleQq) { - typedef std::chrono::duration<float> fs; - EXPECT_EQ("1.234 s", fmt::format("{:%Q %q}", fs(1.234))); - typedef std::chrono::duration<float, std::milli> fms; - EXPECT_EQ("1.234 ms", fmt::format("{:%Q %q}", fms(1.234))); - typedef std::chrono::duration<double> ds; - EXPECT_EQ("1.234 s", fmt::format("{:%Q %q}", ds(1.234))); - EXPECT_EQ("1.234 ms", fmt::format("{:%Q %q}", dms(1.234))); -} - -TEST(ChronoTest, FormatPrecisionQq) { - EXPECT_THROW_MSG(fmt::format("{:.2%Q %q}", std::chrono::seconds(42)), - fmt::format_error, - "precision not allowed for this argument type"); - EXPECT_EQ("1.2 ms", fmt::format("{:.1%Q %q}", dms(1.234))); - EXPECT_EQ("1.23 ms", fmt::format("{:.{}%Q %q}", dms(1.234), 2)); -} - -TEST(ChronoTest, FormatFullSpecsQq) { - EXPECT_EQ("1.2 ms ", fmt::format("{:7.1%Q %q}", dms(1.234))); - EXPECT_EQ(" 1.23 ms", fmt::format("{:>8.{}%Q %q}", dms(1.234), 2)); - EXPECT_EQ(" 1.2 ms ", fmt::format("{:^{}.{}%Q %q}", dms(1.234), 8, 1)); - EXPECT_EQ(" 1.23 ms ", fmt::format("{0:^{2}.{1}%Q %q}", dms(1.234), 2, 9)); - EXPECT_EQ("=1.234 ms=", fmt::format("{:=^{}.{}%Q %q}", dms(1.234), 10, 3)); - EXPECT_EQ("*1.2340 ms*", fmt::format("{:*^11.4%Q %q}", dms(1.234))); -} - -TEST(ChronoTest, InvalidWidthId) { - EXPECT_THROW(fmt::format("{:{o}", std::chrono::seconds(0)), - fmt::format_error); -} - -TEST(ChronoTest, InvalidColons) { - EXPECT_THROW(fmt::format("{0}=:{0::", std::chrono::seconds(0)), - fmt::format_error); -} - -TEST(ChronoTest, NegativeDurations) { - EXPECT_EQ("-12345", fmt::format("{:%Q}", std::chrono::seconds(-12345))); - EXPECT_EQ("-03:25:45", - fmt::format("{:%H:%M:%S}", std::chrono::seconds(-12345))); - EXPECT_EQ("-00:01", - fmt::format("{:%M:%S}", std::chrono::duration<double>(-1))); - EXPECT_EQ("s", fmt::format("{:%q}", std::chrono::seconds(-12345))); - EXPECT_EQ("-00.127", - fmt::format("{:%S}", - std::chrono::duration<signed char, std::milli>{-127})); - auto min = std::numeric_limits<int>::min(); - EXPECT_EQ(fmt::format("{}", min), - fmt::format("{:%Q}", std::chrono::duration<int>(min))); -} - -TEST(ChronoTest, SpecialDurations) { - EXPECT_EQ( - "40.", - fmt::format("{:%S}", std::chrono::duration<double>(1e20)).substr(0, 3)); - auto nan = std::numeric_limits<double>::quiet_NaN(); - EXPECT_EQ( - "nan nan nan nan nan:nan nan", - fmt::format("{:%I %H %M %S %R %r}", std::chrono::duration<double>(nan))); - fmt::format("{:%S}", - std::chrono::duration<float, std::atto>(1.79400457e+31f)); - EXPECT_EQ(fmt::format("{}", std::chrono::duration<float, std::exa>(1)), - "1Es"); - EXPECT_EQ(fmt::format("{}", std::chrono::duration<float, std::atto>(1)), - "1as"); - EXPECT_EQ(fmt::format("{:%R}", std::chrono::duration<char, std::mega>{2}), - "03:33"); - EXPECT_EQ(fmt::format("{:%T}", std::chrono::duration<char, std::mega>{2}), - "03:33:20"); -} - -#endif // FMT_STATIC_THOUSANDS_SEPARATOR +#define EXPECT_TIME(spec, time, duration) \ + { \ + std::locale loc("ja_JP.utf8"); \ + EXPECT_EQ(format_tm(time, spec, loc), \ + fmt::format(loc, "{:" spec "}", duration)); \ + } + +#ifndef FMT_STATIC_THOUSANDS_SEPARATOR + +TEST(ChronoTest, FormatDefault) { + EXPECT_EQ("42s", fmt::format("{}", std::chrono::seconds(42))); + EXPECT_EQ("42as", + fmt::format("{}", std::chrono::duration<int, std::atto>(42))); + EXPECT_EQ("42fs", + fmt::format("{}", std::chrono::duration<int, std::femto>(42))); + EXPECT_EQ("42ps", + fmt::format("{}", std::chrono::duration<int, std::pico>(42))); + EXPECT_EQ("42ns", fmt::format("{}", std::chrono::nanoseconds(42))); + EXPECT_EQ("42µs", fmt::format("{}", std::chrono::microseconds(42))); + EXPECT_EQ("42ms", fmt::format("{}", std::chrono::milliseconds(42))); + EXPECT_EQ("42cs", + fmt::format("{}", std::chrono::duration<int, std::centi>(42))); + EXPECT_EQ("42ds", + fmt::format("{}", std::chrono::duration<int, std::deci>(42))); + EXPECT_EQ("42s", fmt::format("{}", std::chrono::seconds(42))); + EXPECT_EQ("42das", + fmt::format("{}", std::chrono::duration<int, std::deca>(42))); + EXPECT_EQ("42hs", + fmt::format("{}", std::chrono::duration<int, std::hecto>(42))); + EXPECT_EQ("42ks", + fmt::format("{}", std::chrono::duration<int, std::kilo>(42))); + EXPECT_EQ("42Ms", + fmt::format("{}", std::chrono::duration<int, std::mega>(42))); + EXPECT_EQ("42Gs", + fmt::format("{}", std::chrono::duration<int, std::giga>(42))); + EXPECT_EQ("42Ts", + fmt::format("{}", std::chrono::duration<int, std::tera>(42))); + EXPECT_EQ("42Ps", + fmt::format("{}", std::chrono::duration<int, std::peta>(42))); + EXPECT_EQ("42Es", + fmt::format("{}", std::chrono::duration<int, std::exa>(42))); + EXPECT_EQ("42m", fmt::format("{}", std::chrono::minutes(42))); + EXPECT_EQ("42h", fmt::format("{}", std::chrono::hours(42))); + EXPECT_EQ( + "42[15]s", + fmt::format("{}", std::chrono::duration<int, std::ratio<15, 1>>(42))); + EXPECT_EQ( + "42[15/4]s", + fmt::format("{}", std::chrono::duration<int, std::ratio<15, 4>>(42))); +} + +TEST(ChronoTest, FormatWide) { + EXPECT_EQ(L"42s", fmt::format(L"{}", std::chrono::seconds(42))); + EXPECT_EQ(L"42as", + fmt::format(L"{}", std::chrono::duration<int, std::atto>(42))); + EXPECT_EQ(L"42fs", + fmt::format(L"{}", std::chrono::duration<int, std::femto>(42))); + EXPECT_EQ(L"42ps", + fmt::format(L"{}", std::chrono::duration<int, std::pico>(42))); + EXPECT_EQ(L"42ns", fmt::format(L"{}", std::chrono::nanoseconds(42))); + EXPECT_EQ(L"42\u00B5s", fmt::format(L"{}", std::chrono::microseconds(42))); + EXPECT_EQ(L"42ms", fmt::format(L"{}", std::chrono::milliseconds(42))); + EXPECT_EQ(L"42cs", + fmt::format(L"{}", std::chrono::duration<int, std::centi>(42))); + EXPECT_EQ(L"42ds", + fmt::format(L"{}", std::chrono::duration<int, std::deci>(42))); + EXPECT_EQ(L"42s", fmt::format(L"{}", std::chrono::seconds(42))); + EXPECT_EQ(L"42das", + fmt::format(L"{}", std::chrono::duration<int, std::deca>(42))); + EXPECT_EQ(L"42hs", + fmt::format(L"{}", std::chrono::duration<int, std::hecto>(42))); + EXPECT_EQ(L"42ks", + fmt::format(L"{}", std::chrono::duration<int, std::kilo>(42))); + EXPECT_EQ(L"42Ms", + fmt::format(L"{}", std::chrono::duration<int, std::mega>(42))); + EXPECT_EQ(L"42Gs", + fmt::format(L"{}", std::chrono::duration<int, std::giga>(42))); + EXPECT_EQ(L"42Ts", + fmt::format(L"{}", std::chrono::duration<int, std::tera>(42))); + EXPECT_EQ(L"42Ps", + fmt::format(L"{}", std::chrono::duration<int, std::peta>(42))); + EXPECT_EQ(L"42Es", + fmt::format(L"{}", std::chrono::duration<int, std::exa>(42))); + EXPECT_EQ(L"42m", fmt::format(L"{}", std::chrono::minutes(42))); + EXPECT_EQ(L"42h", fmt::format(L"{}", std::chrono::hours(42))); + EXPECT_EQ( + L"42[15]s", + fmt::format(L"{}", std::chrono::duration<int, std::ratio<15, 1>>(42))); + EXPECT_EQ( + L"42[15/4]s", + fmt::format(L"{}", std::chrono::duration<int, std::ratio<15, 4>>(42))); +} + +TEST(ChronoTest, Align) { + auto s = std::chrono::seconds(42); + EXPECT_EQ("42s ", fmt::format("{:5}", s)); + EXPECT_EQ("42s ", fmt::format("{:{}}", s, 5)); + EXPECT_EQ(" 42s", fmt::format("{:>5}", s)); + EXPECT_EQ("**42s**", fmt::format("{:*^7}", s)); + EXPECT_EQ("03:25:45 ", + fmt::format("{:12%H:%M:%S}", std::chrono::seconds(12345))); + EXPECT_EQ(" 03:25:45", + fmt::format("{:>12%H:%M:%S}", std::chrono::seconds(12345))); + EXPECT_EQ("~~03:25:45~~", + fmt::format("{:~^12%H:%M:%S}", std::chrono::seconds(12345))); + EXPECT_EQ("03:25:45 ", + fmt::format("{:{}%H:%M:%S}", std::chrono::seconds(12345), 12)); +} + +TEST(ChronoTest, FormatSpecs) { + EXPECT_EQ("%", fmt::format("{:%%}", std::chrono::seconds(0))); + EXPECT_EQ("\n", fmt::format("{:%n}", std::chrono::seconds(0))); + EXPECT_EQ("\t", fmt::format("{:%t}", std::chrono::seconds(0))); + EXPECT_EQ("00", fmt::format("{:%S}", std::chrono::seconds(0))); + EXPECT_EQ("00", fmt::format("{:%S}", std::chrono::seconds(60))); + EXPECT_EQ("42", fmt::format("{:%S}", std::chrono::seconds(42))); + EXPECT_EQ("01.234", fmt::format("{:%S}", std::chrono::milliseconds(1234))); + EXPECT_EQ("00", fmt::format("{:%M}", std::chrono::minutes(0))); + EXPECT_EQ("00", fmt::format("{:%M}", std::chrono::minutes(60))); + EXPECT_EQ("42", fmt::format("{:%M}", std::chrono::minutes(42))); + EXPECT_EQ("01", fmt::format("{:%M}", std::chrono::seconds(61))); + EXPECT_EQ("00", fmt::format("{:%H}", std::chrono::hours(0))); + EXPECT_EQ("00", fmt::format("{:%H}", std::chrono::hours(24))); + EXPECT_EQ("14", fmt::format("{:%H}", std::chrono::hours(14))); + EXPECT_EQ("01", fmt::format("{:%H}", std::chrono::minutes(61))); + EXPECT_EQ("12", fmt::format("{:%I}", std::chrono::hours(0))); + EXPECT_EQ("12", fmt::format("{:%I}", std::chrono::hours(12))); + EXPECT_EQ("12", fmt::format("{:%I}", std::chrono::hours(24))); + EXPECT_EQ("04", fmt::format("{:%I}", std::chrono::hours(4))); + EXPECT_EQ("02", fmt::format("{:%I}", std::chrono::hours(14))); + EXPECT_EQ("03:25:45", + fmt::format("{:%H:%M:%S}", std::chrono::seconds(12345))); + EXPECT_EQ("03:25", fmt::format("{:%R}", std::chrono::seconds(12345))); + EXPECT_EQ("03:25:45", fmt::format("{:%T}", std::chrono::seconds(12345))); + EXPECT_EQ("12345", fmt::format("{:%Q}", std::chrono::seconds(12345))); + EXPECT_EQ("s", fmt::format("{:%q}", std::chrono::seconds(12345))); +} + +TEST(ChronoTest, InvalidSpecs) { + auto sec = std::chrono::seconds(0); + EXPECT_THROW_MSG(fmt::format("{:%a}", sec), fmt::format_error, "no date"); + EXPECT_THROW_MSG(fmt::format("{:%A}", sec), fmt::format_error, "no date"); + EXPECT_THROW_MSG(fmt::format("{:%c}", sec), fmt::format_error, "no date"); + EXPECT_THROW_MSG(fmt::format("{:%x}", sec), fmt::format_error, "no date"); + EXPECT_THROW_MSG(fmt::format("{:%Ex}", sec), fmt::format_error, "no date"); + EXPECT_THROW_MSG(fmt::format("{:%X}", sec), fmt::format_error, "no date"); + EXPECT_THROW_MSG(fmt::format("{:%EX}", sec), fmt::format_error, "no date"); + EXPECT_THROW_MSG(fmt::format("{:%D}", sec), fmt::format_error, "no date"); + EXPECT_THROW_MSG(fmt::format("{:%F}", sec), fmt::format_error, "no date"); + EXPECT_THROW_MSG(fmt::format("{:%Ec}", sec), fmt::format_error, "no date"); + EXPECT_THROW_MSG(fmt::format("{:%w}", sec), fmt::format_error, "no date"); + EXPECT_THROW_MSG(fmt::format("{:%u}", sec), fmt::format_error, "no date"); + EXPECT_THROW_MSG(fmt::format("{:%b}", sec), fmt::format_error, "no date"); + EXPECT_THROW_MSG(fmt::format("{:%B}", sec), fmt::format_error, "no date"); + EXPECT_THROW_MSG(fmt::format("{:%z}", sec), fmt::format_error, "no date"); + EXPECT_THROW_MSG(fmt::format("{:%Z}", sec), fmt::format_error, "no date"); + EXPECT_THROW_MSG(fmt::format("{:%Eq}", sec), fmt::format_error, + "invalid format"); + EXPECT_THROW_MSG(fmt::format("{:%Oq}", sec), fmt::format_error, + "invalid format"); +} + +TEST(ChronoTest, Locale) { + const char* loc_name = "ja_JP.utf8"; + bool has_locale = false; + std::locale loc; + try { + loc = std::locale(loc_name); + has_locale = true; + } catch (const std::runtime_error&) { + } + if (!has_locale) { + fmt::print("{} locale is missing.\n", loc_name); + return; + } + EXPECT_TIME("%OH", make_hour(14), std::chrono::hours(14)); + EXPECT_TIME("%OI", make_hour(14), std::chrono::hours(14)); + EXPECT_TIME("%OM", make_minute(42), std::chrono::minutes(42)); + EXPECT_TIME("%OS", make_second(42), std::chrono::seconds(42)); + auto time = make_tm(); + time.tm_hour = 3; + time.tm_min = 25; + time.tm_sec = 45; + auto sec = std::chrono::seconds(12345); + EXPECT_TIME("%r", time, sec); + EXPECT_TIME("%p", time, sec); +} + +typedef std::chrono::duration<double, std::milli> dms; + +TEST(ChronoTest, FormatDefaultFP) { + typedef std::chrono::duration<float> fs; + EXPECT_EQ("1.234s", fmt::format("{}", fs(1.234))); + typedef std::chrono::duration<float, std::milli> fms; + EXPECT_EQ("1.234ms", fmt::format("{}", fms(1.234))); + typedef std::chrono::duration<double> ds; + EXPECT_EQ("1.234s", fmt::format("{}", ds(1.234))); + EXPECT_EQ("1.234ms", fmt::format("{}", dms(1.234))); +} + +TEST(ChronoTest, FormatPrecision) { + EXPECT_THROW_MSG(fmt::format("{:.2}", std::chrono::seconds(42)), + fmt::format_error, + "precision not allowed for this argument type"); + EXPECT_EQ("1.2ms", fmt::format("{:.1}", dms(1.234))); + EXPECT_EQ("1.23ms", fmt::format("{:.{}}", dms(1.234), 2)); +} + +TEST(ChronoTest, FormatFullSpecs) { + EXPECT_EQ("1.2ms ", fmt::format("{:6.1}", dms(1.234))); + EXPECT_EQ(" 1.23ms", fmt::format("{:>8.{}}", dms(1.234), 2)); + EXPECT_EQ(" 1.2ms ", fmt::format("{:^{}.{}}", dms(1.234), 7, 1)); + EXPECT_EQ(" 1.23ms ", fmt::format("{0:^{2}.{1}}", dms(1.234), 2, 8)); + EXPECT_EQ("=1.234ms=", fmt::format("{:=^{}.{}}", dms(1.234), 9, 3)); + EXPECT_EQ("*1.2340ms*", fmt::format("{:*^10.4}", dms(1.234))); +} + +TEST(ChronoTest, FormatSimpleQq) { + typedef std::chrono::duration<float> fs; + EXPECT_EQ("1.234 s", fmt::format("{:%Q %q}", fs(1.234))); + typedef std::chrono::duration<float, std::milli> fms; + EXPECT_EQ("1.234 ms", fmt::format("{:%Q %q}", fms(1.234))); + typedef std::chrono::duration<double> ds; + EXPECT_EQ("1.234 s", fmt::format("{:%Q %q}", ds(1.234))); + EXPECT_EQ("1.234 ms", fmt::format("{:%Q %q}", dms(1.234))); +} + +TEST(ChronoTest, FormatPrecisionQq) { + EXPECT_THROW_MSG(fmt::format("{:.2%Q %q}", std::chrono::seconds(42)), + fmt::format_error, + "precision not allowed for this argument type"); + EXPECT_EQ("1.2 ms", fmt::format("{:.1%Q %q}", dms(1.234))); + EXPECT_EQ("1.23 ms", fmt::format("{:.{}%Q %q}", dms(1.234), 2)); +} + +TEST(ChronoTest, FormatFullSpecsQq) { + EXPECT_EQ("1.2 ms ", fmt::format("{:7.1%Q %q}", dms(1.234))); + EXPECT_EQ(" 1.23 ms", fmt::format("{:>8.{}%Q %q}", dms(1.234), 2)); + EXPECT_EQ(" 1.2 ms ", fmt::format("{:^{}.{}%Q %q}", dms(1.234), 8, 1)); + EXPECT_EQ(" 1.23 ms ", fmt::format("{0:^{2}.{1}%Q %q}", dms(1.234), 2, 9)); + EXPECT_EQ("=1.234 ms=", fmt::format("{:=^{}.{}%Q %q}", dms(1.234), 10, 3)); + EXPECT_EQ("*1.2340 ms*", fmt::format("{:*^11.4%Q %q}", dms(1.234))); +} + +TEST(ChronoTest, InvalidWidthId) { + EXPECT_THROW(fmt::format("{:{o}", std::chrono::seconds(0)), + fmt::format_error); +} + +TEST(ChronoTest, InvalidColons) { + EXPECT_THROW(fmt::format("{0}=:{0::", std::chrono::seconds(0)), + fmt::format_error); +} + +TEST(ChronoTest, NegativeDurations) { + EXPECT_EQ("-12345", fmt::format("{:%Q}", std::chrono::seconds(-12345))); + EXPECT_EQ("-03:25:45", + fmt::format("{:%H:%M:%S}", std::chrono::seconds(-12345))); + EXPECT_EQ("-00:01", + fmt::format("{:%M:%S}", std::chrono::duration<double>(-1))); + EXPECT_EQ("s", fmt::format("{:%q}", std::chrono::seconds(-12345))); + EXPECT_EQ("-00.127", + fmt::format("{:%S}", + std::chrono::duration<signed char, std::milli>{-127})); + auto min = std::numeric_limits<int>::min(); + EXPECT_EQ(fmt::format("{}", min), + fmt::format("{:%Q}", std::chrono::duration<int>(min))); +} + +TEST(ChronoTest, SpecialDurations) { + EXPECT_EQ( + "40.", + fmt::format("{:%S}", std::chrono::duration<double>(1e20)).substr(0, 3)); + auto nan = std::numeric_limits<double>::quiet_NaN(); + EXPECT_EQ( + "nan nan nan nan nan:nan nan", + fmt::format("{:%I %H %M %S %R %r}", std::chrono::duration<double>(nan))); + fmt::format("{:%S}", + std::chrono::duration<float, std::atto>(1.79400457e+31f)); + EXPECT_EQ(fmt::format("{}", std::chrono::duration<float, std::exa>(1)), + "1Es"); + EXPECT_EQ(fmt::format("{}", std::chrono::duration<float, std::atto>(1)), + "1as"); + EXPECT_EQ(fmt::format("{:%R}", std::chrono::duration<char, std::mega>{2}), + "03:33"); + EXPECT_EQ(fmt::format("{:%T}", std::chrono::duration<char, std::mega>{2}), + "03:33:20"); +} + +#endif // FMT_STATIC_THOUSANDS_SEPARATOR diff --git a/contrib/libs/fmt/test/chrono-test/ya.make b/contrib/libs/fmt/test/chrono-test/ya.make index 1e1c0d91e1..7982d65069 100644 --- a/contrib/libs/fmt/test/chrono-test/ya.make +++ b/contrib/libs/fmt/test/chrono-test/ya.make @@ -1,37 +1,37 @@ -# Generated by devtools/yamaker. - +# Generated by devtools/yamaker. + GTEST() - + WITHOUT_LICENSE_TEXTS() - + OWNER( orivej g:cpp-contrib ) -LICENSE(MIT) - -PEERDIR( - contrib/libs/fmt - contrib/libs/fmt/test -) - -NO_COMPILER_WARNINGS() - -NO_UTIL() - -CFLAGS( - -DFMT_LOCALE - -DFMT_SHARED - -DGTEST_HAS_STD_WSTRING=1 - -DGTEST_LANG_CXX11=0 - -D_SILENCE_TR1_NAMESPACE_DEPRECATION_WARNING=1 -) - -SRCDIR(contrib/libs/fmt/test) - -SRCS( - chrono-test.cc -) - -END() +LICENSE(MIT) + +PEERDIR( + contrib/libs/fmt + contrib/libs/fmt/test +) + +NO_COMPILER_WARNINGS() + +NO_UTIL() + +CFLAGS( + -DFMT_LOCALE + -DFMT_SHARED + -DGTEST_HAS_STD_WSTRING=1 + -DGTEST_LANG_CXX11=0 + -D_SILENCE_TR1_NAMESPACE_DEPRECATION_WARNING=1 +) + +SRCDIR(contrib/libs/fmt/test) + +SRCS( + chrono-test.cc +) + +END() diff --git a/contrib/libs/fmt/test/color-test.cc b/contrib/libs/fmt/test/color-test.cc index b229aa1abf..3073808541 100644 --- a/contrib/libs/fmt/test/color-test.cc +++ b/contrib/libs/fmt/test/color-test.cc @@ -1,93 +1,93 @@ -// Formatting library for C++ - color tests -// -// Copyright (c) 2012 - present, Victor Zverovich -// All rights reserved. -// -// For the license information refer to format.h. - -#include "fmt/color.h" +// Formatting library for C++ - color tests +// +// Copyright (c) 2012 - present, Victor Zverovich +// All rights reserved. +// +// For the license information refer to format.h. + +#include "fmt/color.h" #include <iterator> #include <string> #include <utility> -#include "gtest-extra.h" - -TEST(ColorsTest, ColorsPrint) { - EXPECT_WRITE(stdout, fmt::print(fg(fmt::rgb(255, 20, 30)), "rgb(255,20,30)"), - "\x1b[38;2;255;020;030mrgb(255,20,30)\x1b[0m"); - EXPECT_WRITE(stdout, fmt::print(fg(fmt::color::blue), "blue"), - "\x1b[38;2;000;000;255mblue\x1b[0m"); - EXPECT_WRITE( - stdout, - fmt::print(fg(fmt::color::blue) | bg(fmt::color::red), "two color"), - "\x1b[38;2;000;000;255m\x1b[48;2;255;000;000mtwo color\x1b[0m"); - EXPECT_WRITE(stdout, fmt::print(fmt::emphasis::bold, "bold"), - "\x1b[1mbold\x1b[0m"); - EXPECT_WRITE(stdout, fmt::print(fmt::emphasis::italic, "italic"), - "\x1b[3mitalic\x1b[0m"); - EXPECT_WRITE(stdout, fmt::print(fmt::emphasis::underline, "underline"), - "\x1b[4munderline\x1b[0m"); - EXPECT_WRITE(stdout, - fmt::print(fmt::emphasis::strikethrough, "strikethrough"), - "\x1b[9mstrikethrough\x1b[0m"); - EXPECT_WRITE( - stdout, - fmt::print(fg(fmt::color::blue) | fmt::emphasis::bold, "blue/bold"), - "\x1b[1m\x1b[38;2;000;000;255mblue/bold\x1b[0m"); - EXPECT_WRITE(stderr, fmt::print(stderr, fmt::emphasis::bold, "bold error"), - "\x1b[1mbold error\x1b[0m"); - EXPECT_WRITE(stderr, fmt::print(stderr, fg(fmt::color::blue), "blue log"), - "\x1b[38;2;000;000;255mblue log\x1b[0m"); - EXPECT_WRITE(stdout, fmt::print(fmt::text_style(), "hi"), "hi"); - EXPECT_WRITE(stdout, fmt::print(fg(fmt::terminal_color::red), "tred"), - "\x1b[31mtred\x1b[0m"); - EXPECT_WRITE(stdout, fmt::print(bg(fmt::terminal_color::cyan), "tcyan"), - "\x1b[46mtcyan\x1b[0m"); - EXPECT_WRITE(stdout, - fmt::print(fg(fmt::terminal_color::bright_green), "tbgreen"), - "\x1b[92mtbgreen\x1b[0m"); - EXPECT_WRITE(stdout, - fmt::print(bg(fmt::terminal_color::bright_magenta), "tbmagenta"), - "\x1b[105mtbmagenta\x1b[0m"); -} - -TEST(ColorsTest, Format) { - EXPECT_EQ(fmt::format(fg(fmt::rgb(255, 20, 30)), "rgb(255,20,30)"), - "\x1b[38;2;255;020;030mrgb(255,20,30)\x1b[0m"); - EXPECT_EQ(fmt::format(fg(fmt::rgb(255, 20, 30)), L"rgb(255,20,30) wide"), - L"\x1b[38;2;255;020;030mrgb(255,20,30) wide\x1b[0m"); - EXPECT_EQ(fmt::format(fg(fmt::color::blue), "blue"), - "\x1b[38;2;000;000;255mblue\x1b[0m"); - EXPECT_EQ( - fmt::format(fg(fmt::color::blue) | bg(fmt::color::red), "two color"), - "\x1b[38;2;000;000;255m\x1b[48;2;255;000;000mtwo color\x1b[0m"); - EXPECT_EQ(fmt::format(fmt::emphasis::bold, "bold"), "\x1b[1mbold\x1b[0m"); - EXPECT_EQ(fmt::format(fmt::emphasis::italic, "italic"), - "\x1b[3mitalic\x1b[0m"); - EXPECT_EQ(fmt::format(fmt::emphasis::underline, "underline"), - "\x1b[4munderline\x1b[0m"); - EXPECT_EQ(fmt::format(fmt::emphasis::strikethrough, "strikethrough"), - "\x1b[9mstrikethrough\x1b[0m"); - EXPECT_EQ( - fmt::format(fg(fmt::color::blue) | fmt::emphasis::bold, "blue/bold"), - "\x1b[1m\x1b[38;2;000;000;255mblue/bold\x1b[0m"); - EXPECT_EQ(fmt::format(fmt::emphasis::bold, "bold error"), - "\x1b[1mbold error\x1b[0m"); - EXPECT_EQ(fmt::format(fg(fmt::color::blue), "blue log"), - "\x1b[38;2;000;000;255mblue log\x1b[0m"); - EXPECT_EQ(fmt::format(fmt::text_style(), "hi"), "hi"); - EXPECT_EQ(fmt::format(fg(fmt::terminal_color::red), "tred"), - "\x1b[31mtred\x1b[0m"); - EXPECT_EQ(fmt::format(bg(fmt::terminal_color::cyan), "tcyan"), - "\x1b[46mtcyan\x1b[0m"); - EXPECT_EQ(fmt::format(fg(fmt::terminal_color::bright_green), "tbgreen"), - "\x1b[92mtbgreen\x1b[0m"); - EXPECT_EQ(fmt::format(bg(fmt::terminal_color::bright_magenta), "tbmagenta"), - "\x1b[105mtbmagenta\x1b[0m"); - EXPECT_EQ(fmt::format(fg(fmt::terminal_color::red), "{}", "foo"), - "\x1b[31mfoo\x1b[0m"); -} +#include "gtest-extra.h" + +TEST(ColorsTest, ColorsPrint) { + EXPECT_WRITE(stdout, fmt::print(fg(fmt::rgb(255, 20, 30)), "rgb(255,20,30)"), + "\x1b[38;2;255;020;030mrgb(255,20,30)\x1b[0m"); + EXPECT_WRITE(stdout, fmt::print(fg(fmt::color::blue), "blue"), + "\x1b[38;2;000;000;255mblue\x1b[0m"); + EXPECT_WRITE( + stdout, + fmt::print(fg(fmt::color::blue) | bg(fmt::color::red), "two color"), + "\x1b[38;2;000;000;255m\x1b[48;2;255;000;000mtwo color\x1b[0m"); + EXPECT_WRITE(stdout, fmt::print(fmt::emphasis::bold, "bold"), + "\x1b[1mbold\x1b[0m"); + EXPECT_WRITE(stdout, fmt::print(fmt::emphasis::italic, "italic"), + "\x1b[3mitalic\x1b[0m"); + EXPECT_WRITE(stdout, fmt::print(fmt::emphasis::underline, "underline"), + "\x1b[4munderline\x1b[0m"); + EXPECT_WRITE(stdout, + fmt::print(fmt::emphasis::strikethrough, "strikethrough"), + "\x1b[9mstrikethrough\x1b[0m"); + EXPECT_WRITE( + stdout, + fmt::print(fg(fmt::color::blue) | fmt::emphasis::bold, "blue/bold"), + "\x1b[1m\x1b[38;2;000;000;255mblue/bold\x1b[0m"); + EXPECT_WRITE(stderr, fmt::print(stderr, fmt::emphasis::bold, "bold error"), + "\x1b[1mbold error\x1b[0m"); + EXPECT_WRITE(stderr, fmt::print(stderr, fg(fmt::color::blue), "blue log"), + "\x1b[38;2;000;000;255mblue log\x1b[0m"); + EXPECT_WRITE(stdout, fmt::print(fmt::text_style(), "hi"), "hi"); + EXPECT_WRITE(stdout, fmt::print(fg(fmt::terminal_color::red), "tred"), + "\x1b[31mtred\x1b[0m"); + EXPECT_WRITE(stdout, fmt::print(bg(fmt::terminal_color::cyan), "tcyan"), + "\x1b[46mtcyan\x1b[0m"); + EXPECT_WRITE(stdout, + fmt::print(fg(fmt::terminal_color::bright_green), "tbgreen"), + "\x1b[92mtbgreen\x1b[0m"); + EXPECT_WRITE(stdout, + fmt::print(bg(fmt::terminal_color::bright_magenta), "tbmagenta"), + "\x1b[105mtbmagenta\x1b[0m"); +} + +TEST(ColorsTest, Format) { + EXPECT_EQ(fmt::format(fg(fmt::rgb(255, 20, 30)), "rgb(255,20,30)"), + "\x1b[38;2;255;020;030mrgb(255,20,30)\x1b[0m"); + EXPECT_EQ(fmt::format(fg(fmt::rgb(255, 20, 30)), L"rgb(255,20,30) wide"), + L"\x1b[38;2;255;020;030mrgb(255,20,30) wide\x1b[0m"); + EXPECT_EQ(fmt::format(fg(fmt::color::blue), "blue"), + "\x1b[38;2;000;000;255mblue\x1b[0m"); + EXPECT_EQ( + fmt::format(fg(fmt::color::blue) | bg(fmt::color::red), "two color"), + "\x1b[38;2;000;000;255m\x1b[48;2;255;000;000mtwo color\x1b[0m"); + EXPECT_EQ(fmt::format(fmt::emphasis::bold, "bold"), "\x1b[1mbold\x1b[0m"); + EXPECT_EQ(fmt::format(fmt::emphasis::italic, "italic"), + "\x1b[3mitalic\x1b[0m"); + EXPECT_EQ(fmt::format(fmt::emphasis::underline, "underline"), + "\x1b[4munderline\x1b[0m"); + EXPECT_EQ(fmt::format(fmt::emphasis::strikethrough, "strikethrough"), + "\x1b[9mstrikethrough\x1b[0m"); + EXPECT_EQ( + fmt::format(fg(fmt::color::blue) | fmt::emphasis::bold, "blue/bold"), + "\x1b[1m\x1b[38;2;000;000;255mblue/bold\x1b[0m"); + EXPECT_EQ(fmt::format(fmt::emphasis::bold, "bold error"), + "\x1b[1mbold error\x1b[0m"); + EXPECT_EQ(fmt::format(fg(fmt::color::blue), "blue log"), + "\x1b[38;2;000;000;255mblue log\x1b[0m"); + EXPECT_EQ(fmt::format(fmt::text_style(), "hi"), "hi"); + EXPECT_EQ(fmt::format(fg(fmt::terminal_color::red), "tred"), + "\x1b[31mtred\x1b[0m"); + EXPECT_EQ(fmt::format(bg(fmt::terminal_color::cyan), "tcyan"), + "\x1b[46mtcyan\x1b[0m"); + EXPECT_EQ(fmt::format(fg(fmt::terminal_color::bright_green), "tbgreen"), + "\x1b[92mtbgreen\x1b[0m"); + EXPECT_EQ(fmt::format(bg(fmt::terminal_color::bright_magenta), "tbmagenta"), + "\x1b[105mtbmagenta\x1b[0m"); + EXPECT_EQ(fmt::format(fg(fmt::terminal_color::red), "{}", "foo"), + "\x1b[31mfoo\x1b[0m"); +} TEST(ColorsTest, FormatToOutAcceptsTextStyle) { fmt::text_style ts = fg(fmt::rgb(255, 20, 30)); diff --git a/contrib/libs/fmt/test/color-test/ya.make b/contrib/libs/fmt/test/color-test/ya.make index 1c224fe251..22e6654b0f 100644 --- a/contrib/libs/fmt/test/color-test/ya.make +++ b/contrib/libs/fmt/test/color-test/ya.make @@ -1,37 +1,37 @@ -# Generated by devtools/yamaker. - +# Generated by devtools/yamaker. + GTEST() - + WITHOUT_LICENSE_TEXTS() - + OWNER( orivej g:cpp-contrib ) -LICENSE(MIT) - -PEERDIR( - contrib/libs/fmt - contrib/libs/fmt/test -) - -NO_COMPILER_WARNINGS() - -NO_UTIL() - -CFLAGS( - -DFMT_LOCALE - -DFMT_SHARED - -DGTEST_HAS_STD_WSTRING=1 - -DGTEST_LANG_CXX11=0 - -D_SILENCE_TR1_NAMESPACE_DEPRECATION_WARNING=1 -) - -SRCDIR(contrib/libs/fmt/test) - -SRCS( - color-test.cc -) - -END() +LICENSE(MIT) + +PEERDIR( + contrib/libs/fmt + contrib/libs/fmt/test +) + +NO_COMPILER_WARNINGS() + +NO_UTIL() + +CFLAGS( + -DFMT_LOCALE + -DFMT_SHARED + -DGTEST_HAS_STD_WSTRING=1 + -DGTEST_LANG_CXX11=0 + -D_SILENCE_TR1_NAMESPACE_DEPRECATION_WARNING=1 +) + +SRCDIR(contrib/libs/fmt/test) + +SRCS( + color-test.cc +) + +END() diff --git a/contrib/libs/fmt/test/compile-test.cc b/contrib/libs/fmt/test/compile-test.cc index ad23980e62..9bb9bb7d9e 100644 --- a/contrib/libs/fmt/test/compile-test.cc +++ b/contrib/libs/fmt/test/compile-test.cc @@ -1,122 +1,122 @@ -// Formatting library for C++ - formatting library tests -// -// Copyright (c) 2012 - present, Victor Zverovich -// All rights reserved. -// -// For the license information refer to format.h. - -#include <string> +// Formatting library for C++ - formatting library tests +// +// Copyright (c) 2012 - present, Victor Zverovich +// All rights reserved. +// +// For the license information refer to format.h. + +#include <string> #include <type_traits> - + // Check that fmt/compile.h compiles with windows.h included before it. -#ifdef _WIN32 -# include <windows.h> -#endif - -#include "fmt/compile.h" -#include <gmock/gmock.h> -#include "gtest-extra.h" -#include "util.h" - -// compiletime_prepared_parts_type_provider is useful only with relaxed -// constexpr. -#if FMT_USE_CONSTEXPR -template <unsigned EXPECTED_PARTS_COUNT, typename Format> -void check_prepared_parts_type(Format format) { +#ifdef _WIN32 +# include <windows.h> +#endif + +#include "fmt/compile.h" +#include <gmock/gmock.h> +#include "gtest-extra.h" +#include "util.h" + +// compiletime_prepared_parts_type_provider is useful only with relaxed +// constexpr. +#if FMT_USE_CONSTEXPR +template <unsigned EXPECTED_PARTS_COUNT, typename Format> +void check_prepared_parts_type(Format format) { typedef fmt::detail::compiled_format_base<decltype(format)> provider; typedef fmt::detail::format_part<char> - expected_parts_type[EXPECTED_PARTS_COUNT]; - static_assert(std::is_same<typename provider::parts_container, - expected_parts_type>::value, - "CompileTimePreparedPartsTypeProvider test failed"); -} - -TEST(CompileTest, CompileTimePreparedPartsTypeProvider) { - check_prepared_parts_type<1u>(FMT_STRING("text")); - check_prepared_parts_type<1u>(FMT_STRING("{}")); - check_prepared_parts_type<2u>(FMT_STRING("text{}")); - check_prepared_parts_type<2u>(FMT_STRING("{}text")); - check_prepared_parts_type<3u>(FMT_STRING("text{}text")); - check_prepared_parts_type<3u>(FMT_STRING("{:{}.{}} {:{}}")); - - check_prepared_parts_type<3u>(FMT_STRING("{{{}}}")); // '{', 'argument', '}' - check_prepared_parts_type<2u>(FMT_STRING("text{{")); // 'text', '{' - check_prepared_parts_type<3u>(FMT_STRING("text{{ ")); // 'text', '{', ' ' - check_prepared_parts_type<2u>(FMT_STRING("}}text")); // '}', text - check_prepared_parts_type<2u>(FMT_STRING("text}}text")); // 'text}', 'text' - check_prepared_parts_type<4u>( - FMT_STRING("text{{}}text")); // 'text', '{', '}', 'text' -} -#endif - -TEST(CompileTest, PassStringLiteralFormat) { + expected_parts_type[EXPECTED_PARTS_COUNT]; + static_assert(std::is_same<typename provider::parts_container, + expected_parts_type>::value, + "CompileTimePreparedPartsTypeProvider test failed"); +} + +TEST(CompileTest, CompileTimePreparedPartsTypeProvider) { + check_prepared_parts_type<1u>(FMT_STRING("text")); + check_prepared_parts_type<1u>(FMT_STRING("{}")); + check_prepared_parts_type<2u>(FMT_STRING("text{}")); + check_prepared_parts_type<2u>(FMT_STRING("{}text")); + check_prepared_parts_type<3u>(FMT_STRING("text{}text")); + check_prepared_parts_type<3u>(FMT_STRING("{:{}.{}} {:{}}")); + + check_prepared_parts_type<3u>(FMT_STRING("{{{}}}")); // '{', 'argument', '}' + check_prepared_parts_type<2u>(FMT_STRING("text{{")); // 'text', '{' + check_prepared_parts_type<3u>(FMT_STRING("text{{ ")); // 'text', '{', ' ' + check_prepared_parts_type<2u>(FMT_STRING("}}text")); // '}', text + check_prepared_parts_type<2u>(FMT_STRING("text}}text")); // 'text}', 'text' + check_prepared_parts_type<4u>( + FMT_STRING("text{{}}text")); // 'text', '{', '}', 'text' +} +#endif + +TEST(CompileTest, PassStringLiteralFormat) { const auto prepared = fmt::detail::compile<int>("test {}"); - EXPECT_EQ("test 42", fmt::format(prepared, 42)); + EXPECT_EQ("test 42", fmt::format(prepared, 42)); const auto wprepared = fmt::detail::compile<int>(L"test {}"); - EXPECT_EQ(L"test 42", fmt::format(wprepared, 42)); -} - -TEST(CompileTest, FormatToArrayOfChars) { - char buffer[32] = {0}; + EXPECT_EQ(L"test 42", fmt::format(wprepared, 42)); +} + +TEST(CompileTest, FormatToArrayOfChars) { + char buffer[32] = {0}; const auto prepared = fmt::detail::compile<int>("4{}"); fmt::format_to(fmt::detail::make_checked(buffer, 32), prepared, 2); - EXPECT_EQ(std::string("42"), buffer); - wchar_t wbuffer[32] = {0}; + EXPECT_EQ(std::string("42"), buffer); + wchar_t wbuffer[32] = {0}; const auto wprepared = fmt::detail::compile<int>(L"4{}"); fmt::format_to(fmt::detail::make_checked(wbuffer, 32), wprepared, 2); - EXPECT_EQ(std::wstring(L"42"), wbuffer); -} - -TEST(CompileTest, FormatToIterator) { - std::string s(2, ' '); + EXPECT_EQ(std::wstring(L"42"), wbuffer); +} + +TEST(CompileTest, FormatToIterator) { + std::string s(2, ' '); const auto prepared = fmt::detail::compile<int>("4{}"); - fmt::format_to(s.begin(), prepared, 2); - EXPECT_EQ("42", s); - std::wstring ws(2, L' '); + fmt::format_to(s.begin(), prepared, 2); + EXPECT_EQ("42", s); + std::wstring ws(2, L' '); const auto wprepared = fmt::detail::compile<int>(L"4{}"); - fmt::format_to(ws.begin(), wprepared, 2); - EXPECT_EQ(L"42", ws); -} - -TEST(CompileTest, FormatToN) { - char buf[5]; + fmt::format_to(ws.begin(), wprepared, 2); + EXPECT_EQ(L"42", ws); +} + +TEST(CompileTest, FormatToN) { + char buf[5]; auto f = fmt::detail::compile<int>("{:10}"); - auto result = fmt::format_to_n(buf, 5, f, 42); - EXPECT_EQ(result.size, 10); - EXPECT_EQ(result.out, buf + 5); - EXPECT_EQ(fmt::string_view(buf, 5), " "); -} - -TEST(CompileTest, FormattedSize) { + auto result = fmt::format_to_n(buf, 5, f, 42); + EXPECT_EQ(result.size, 10); + EXPECT_EQ(result.out, buf + 5); + EXPECT_EQ(fmt::string_view(buf, 5), " "); +} + +TEST(CompileTest, FormattedSize) { auto f = fmt::detail::compile<int>("{:10}"); - EXPECT_EQ(fmt::formatted_size(f, 42), 10); -} - -TEST(CompileTest, MultipleTypes) { + EXPECT_EQ(fmt::formatted_size(f, 42), 10); +} + +TEST(CompileTest, MultipleTypes) { auto f = fmt::detail::compile<int, int>("{} {}"); - EXPECT_EQ(fmt::format(f, 42, 42), "42 42"); -} - + EXPECT_EQ(fmt::format(f, 42, 42), "42 42"); +} + struct test_formattable {}; - -FMT_BEGIN_NAMESPACE + +FMT_BEGIN_NAMESPACE template <> struct formatter<test_formattable> : formatter<const char*> { template <typename FormatContext> auto format(test_formattable, FormatContext& ctx) -> decltype(ctx.out()) { - return formatter<const char*>::format("foo", ctx); - } -}; -FMT_END_NAMESPACE - -TEST(CompileTest, FormatUserDefinedType) { + return formatter<const char*>::format("foo", ctx); + } +}; +FMT_END_NAMESPACE + +TEST(CompileTest, FormatUserDefinedType) { auto f = fmt::detail::compile<test_formattable>("{}"); EXPECT_EQ(fmt::format(f, test_formattable()), "foo"); -} - -TEST(CompileTest, EmptyFormatString) { +} + +TEST(CompileTest, EmptyFormatString) { auto f = fmt::detail::compile<>(""); - EXPECT_EQ(fmt::format(f), ""); -} + EXPECT_EQ(fmt::format(f), ""); +} #ifdef __cpp_if_constexpr TEST(CompileTest, FormatDefault) { diff --git a/contrib/libs/fmt/test/compile-test/ya.make b/contrib/libs/fmt/test/compile-test/ya.make index e5bb486acd..0173e7e70f 100644 --- a/contrib/libs/fmt/test/compile-test/ya.make +++ b/contrib/libs/fmt/test/compile-test/ya.make @@ -1,37 +1,37 @@ -# Generated by devtools/yamaker. - +# Generated by devtools/yamaker. + GTEST() - + WITHOUT_LICENSE_TEXTS() - + OWNER( orivej g:cpp-contrib ) -LICENSE(MIT) - -PEERDIR( - contrib/libs/fmt - contrib/libs/fmt/test -) - -NO_COMPILER_WARNINGS() - -NO_UTIL() - -CFLAGS( - -DFMT_LOCALE - -DFMT_SHARED - -DGTEST_HAS_STD_WSTRING=1 - -DGTEST_LANG_CXX11=0 - -D_SILENCE_TR1_NAMESPACE_DEPRECATION_WARNING=1 -) - -SRCDIR(contrib/libs/fmt/test) - -SRCS( - compile-test.cc -) - -END() +LICENSE(MIT) + +PEERDIR( + contrib/libs/fmt + contrib/libs/fmt/test +) + +NO_COMPILER_WARNINGS() + +NO_UTIL() + +CFLAGS( + -DFMT_LOCALE + -DFMT_SHARED + -DGTEST_HAS_STD_WSTRING=1 + -DGTEST_LANG_CXX11=0 + -D_SILENCE_TR1_NAMESPACE_DEPRECATION_WARNING=1 +) + +SRCDIR(contrib/libs/fmt/test) + +SRCS( + compile-test.cc +) + +END() diff --git a/contrib/libs/fmt/test/core-test.cc b/contrib/libs/fmt/test/core-test.cc index ae0824762a..a5fd01fa4d 100644 --- a/contrib/libs/fmt/test/core-test.cc +++ b/contrib/libs/fmt/test/core-test.cc @@ -1,86 +1,86 @@ -// Formatting library for C++ - core tests -// -// Copyright (c) 2012 - present, Victor Zverovich -// All rights reserved. -// -// For the license information refer to format.h. - -#include <algorithm> -#include <climits> -#include <cstring> -#include <functional> -#include <iterator> -#include <limits> -#include <memory> -#include <string> -#include <type_traits> - -#include <gmock/gmock.h> -#include "test-assert.h" - -// Check if fmt/core.h compiles with windows.h included before it. -#ifdef _WIN32 -# include <windows.h> -#endif - -#include "fmt/core.h" - -#undef min -#undef max - -using fmt::basic_format_arg; -using fmt::string_view; +// Formatting library for C++ - core tests +// +// Copyright (c) 2012 - present, Victor Zverovich +// All rights reserved. +// +// For the license information refer to format.h. + +#include <algorithm> +#include <climits> +#include <cstring> +#include <functional> +#include <iterator> +#include <limits> +#include <memory> +#include <string> +#include <type_traits> + +#include <gmock/gmock.h> +#include "test-assert.h" + +// Check if fmt/core.h compiles with windows.h included before it. +#ifdef _WIN32 +# include <windows.h> +#endif + +#include "fmt/core.h" + +#undef min +#undef max + +using fmt::basic_format_arg; +using fmt::string_view; using fmt::detail::buffer; using fmt::detail::make_arg; using fmt::detail::value; - -using testing::_; + +using testing::_; using testing::Invoke; using testing::Return; -using testing::StrictMock; - -struct test_struct {}; - -FMT_BEGIN_NAMESPACE -template <typename Char> struct formatter<test_struct, Char> { - template <typename ParseContext> - auto parse(ParseContext& ctx) -> decltype(ctx.begin()) { - return ctx.begin(); - } - +using testing::StrictMock; + +struct test_struct {}; + +FMT_BEGIN_NAMESPACE +template <typename Char> struct formatter<test_struct, Char> { + template <typename ParseContext> + auto parse(ParseContext& ctx) -> decltype(ctx.begin()) { + return ctx.begin(); + } + auto format(test_struct, format_context& ctx) -> decltype(ctx.out()) { - const Char* test = "test"; - return std::copy_n(test, std::strlen(test), ctx.out()); - } -}; -FMT_END_NAMESPACE - -#if !FMT_GCC_VERSION || FMT_GCC_VERSION >= 470 -TEST(BufferTest, Noncopyable) { - EXPECT_FALSE(std::is_copy_constructible<buffer<char>>::value); -# if !FMT_MSC_VER - // std::is_copy_assignable is broken in MSVC2013. - EXPECT_FALSE(std::is_copy_assignable<buffer<char>>::value); -# endif -} - -TEST(BufferTest, Nonmoveable) { - EXPECT_FALSE(std::is_move_constructible<buffer<char>>::value); -# if !FMT_MSC_VER - // std::is_move_assignable is broken in MSVC2013. - EXPECT_FALSE(std::is_move_assignable<buffer<char>>::value); -# endif -} -#endif - + const Char* test = "test"; + return std::copy_n(test, std::strlen(test), ctx.out()); + } +}; +FMT_END_NAMESPACE + +#if !FMT_GCC_VERSION || FMT_GCC_VERSION >= 470 +TEST(BufferTest, Noncopyable) { + EXPECT_FALSE(std::is_copy_constructible<buffer<char>>::value); +# if !FMT_MSC_VER + // std::is_copy_assignable is broken in MSVC2013. + EXPECT_FALSE(std::is_copy_assignable<buffer<char>>::value); +# endif +} + +TEST(BufferTest, Nonmoveable) { + EXPECT_FALSE(std::is_move_constructible<buffer<char>>::value); +# if !FMT_MSC_VER + // std::is_move_assignable is broken in MSVC2013. + EXPECT_FALSE(std::is_move_assignable<buffer<char>>::value); +# endif +} +#endif + TEST(BufferTest, Indestructible) { static_assert(!std::is_destructible<fmt::detail::buffer<int>>(), "buffer's destructor is protected"); } - + template <typename T> struct mock_buffer final : buffer<T> { MOCK_METHOD1(do_grow, size_t(size_t capacity)); - + void grow(size_t capacity) { this->set(this->data(), do_grow(capacity)); } mock_buffer(T* data = nullptr, size_t capacity = 0) { @@ -88,64 +88,64 @@ template <typename T> struct mock_buffer final : buffer<T> { ON_CALL(*this, do_grow(_)).WillByDefault(Invoke([](size_t capacity) { return capacity; })); - } -}; - -TEST(BufferTest, Ctor) { - { - mock_buffer<int> buffer; - EXPECT_EQ(nullptr, buffer.data()); - EXPECT_EQ(static_cast<size_t>(0), buffer.size()); - EXPECT_EQ(static_cast<size_t>(0), buffer.capacity()); - } - { - int dummy; - mock_buffer<int> buffer(&dummy); - EXPECT_EQ(&dummy, &buffer[0]); - EXPECT_EQ(static_cast<size_t>(0), buffer.size()); - EXPECT_EQ(static_cast<size_t>(0), buffer.capacity()); - } - { - int dummy; + } +}; + +TEST(BufferTest, Ctor) { + { + mock_buffer<int> buffer; + EXPECT_EQ(nullptr, buffer.data()); + EXPECT_EQ(static_cast<size_t>(0), buffer.size()); + EXPECT_EQ(static_cast<size_t>(0), buffer.capacity()); + } + { + int dummy; + mock_buffer<int> buffer(&dummy); + EXPECT_EQ(&dummy, &buffer[0]); + EXPECT_EQ(static_cast<size_t>(0), buffer.size()); + EXPECT_EQ(static_cast<size_t>(0), buffer.capacity()); + } + { + int dummy; size_t capacity = std::numeric_limits<size_t>::max(); - mock_buffer<int> buffer(&dummy, capacity); - EXPECT_EQ(&dummy, &buffer[0]); - EXPECT_EQ(static_cast<size_t>(0), buffer.size()); - EXPECT_EQ(capacity, buffer.capacity()); - } -} - -TEST(BufferTest, Access) { - char data[10]; - mock_buffer<char> buffer(data, sizeof(data)); - buffer[0] = 11; - EXPECT_EQ(11, buffer[0]); - buffer[3] = 42; - EXPECT_EQ(42, *(&buffer[0] + 3)); + mock_buffer<int> buffer(&dummy, capacity); + EXPECT_EQ(&dummy, &buffer[0]); + EXPECT_EQ(static_cast<size_t>(0), buffer.size()); + EXPECT_EQ(capacity, buffer.capacity()); + } +} + +TEST(BufferTest, Access) { + char data[10]; + mock_buffer<char> buffer(data, sizeof(data)); + buffer[0] = 11; + EXPECT_EQ(11, buffer[0]); + buffer[3] = 42; + EXPECT_EQ(42, *(&buffer[0] + 3)); const fmt::detail::buffer<char>& const_buffer = buffer; - EXPECT_EQ(42, const_buffer[3]); -} - + EXPECT_EQ(42, const_buffer[3]); +} + TEST(BufferTest, TryResize) { - char data[123]; - mock_buffer<char> buffer(data, sizeof(data)); - buffer[10] = 42; - EXPECT_EQ(42, buffer[10]); + char data[123]; + mock_buffer<char> buffer(data, sizeof(data)); + buffer[10] = 42; + EXPECT_EQ(42, buffer[10]); buffer.try_resize(20); - EXPECT_EQ(20u, buffer.size()); - EXPECT_EQ(123u, buffer.capacity()); - EXPECT_EQ(42, buffer[10]); + EXPECT_EQ(20u, buffer.size()); + EXPECT_EQ(123u, buffer.capacity()); + EXPECT_EQ(42, buffer[10]); buffer.try_resize(5); - EXPECT_EQ(5u, buffer.size()); - EXPECT_EQ(123u, buffer.capacity()); - EXPECT_EQ(42, buffer[10]); + EXPECT_EQ(5u, buffer.size()); + EXPECT_EQ(123u, buffer.capacity()); + EXPECT_EQ(42, buffer[10]); // Check if try_resize calls grow. - EXPECT_CALL(buffer, do_grow(124)); + EXPECT_CALL(buffer, do_grow(124)); buffer.try_resize(124); - EXPECT_CALL(buffer, do_grow(200)); + EXPECT_CALL(buffer, do_grow(200)); buffer.try_resize(200); -} - +} + TEST(BufferTest, TryResizePartial) { char data[10]; mock_buffer<char> buffer(data, sizeof(data)); @@ -155,30 +155,30 @@ TEST(BufferTest, TryResizePartial) { EXPECT_EQ(buffer.size(), 15); } -TEST(BufferTest, Clear) { +TEST(BufferTest, Clear) { mock_buffer<char> buffer; EXPECT_CALL(buffer, do_grow(20)); buffer.try_resize(20); buffer.try_resize(0); - EXPECT_EQ(static_cast<size_t>(0), buffer.size()); - EXPECT_EQ(20u, buffer.capacity()); -} - -TEST(BufferTest, Append) { - char data[15]; - mock_buffer<char> buffer(data, 10); + EXPECT_EQ(static_cast<size_t>(0), buffer.size()); + EXPECT_EQ(20u, buffer.capacity()); +} + +TEST(BufferTest, Append) { + char data[15]; + mock_buffer<char> buffer(data, 10); auto test = "test"; - buffer.append(test, test + 5); - EXPECT_STREQ(test, &buffer[0]); - EXPECT_EQ(5u, buffer.size()); + buffer.append(test, test + 5); + EXPECT_STREQ(test, &buffer[0]); + EXPECT_EQ(5u, buffer.size()); buffer.try_resize(10); - EXPECT_CALL(buffer, do_grow(12)); - buffer.append(test, test + 2); - EXPECT_EQ('t', buffer[10]); - EXPECT_EQ('e', buffer[11]); - EXPECT_EQ(12u, buffer.size()); -} - + EXPECT_CALL(buffer, do_grow(12)); + buffer.append(test, test + 2); + EXPECT_EQ('t', buffer[10]); + EXPECT_EQ('e', buffer[11]); + EXPECT_EQ(12u, buffer.size()); +} + TEST(BufferTest, AppendPartial) { char data[10]; mock_buffer<char> buffer(data, sizeof(data)); @@ -193,262 +193,262 @@ TEST(BufferTest, AppendPartial) { buffer.append(test, test + 15); } -TEST(BufferTest, AppendAllocatesEnoughStorage) { - char data[19]; - mock_buffer<char> buffer(data, 10); +TEST(BufferTest, AppendAllocatesEnoughStorage) { + char data[19]; + mock_buffer<char> buffer(data, 10); auto test = "abcdefgh"; buffer.try_resize(10); - EXPECT_CALL(buffer, do_grow(19)); - buffer.append(test, test + 9); -} - -TEST(ArgTest, FormatArgs) { + EXPECT_CALL(buffer, do_grow(19)); + buffer.append(test, test + 9); +} + +TEST(ArgTest, FormatArgs) { auto args = fmt::format_args(); - EXPECT_FALSE(args.get(1)); -} - -struct custom_context { - using char_type = char; - using parse_context_type = fmt::format_parse_context; - - template <typename T> struct formatter_type { - template <typename ParseContext> - auto parse(ParseContext& ctx) -> decltype(ctx.begin()) { - return ctx.begin(); - } - - const char* format(const T&, custom_context& ctx) { - ctx.called = true; - return nullptr; - } - }; - - bool called; - fmt::format_parse_context ctx; - - fmt::format_parse_context& parse_context() { return ctx; } - void advance_to(const char*) {} -}; - -TEST(ArgTest, MakeValueWithCustomContext) { + EXPECT_FALSE(args.get(1)); +} + +struct custom_context { + using char_type = char; + using parse_context_type = fmt::format_parse_context; + + template <typename T> struct formatter_type { + template <typename ParseContext> + auto parse(ParseContext& ctx) -> decltype(ctx.begin()) { + return ctx.begin(); + } + + const char* format(const T&, custom_context& ctx) { + ctx.called = true; + return nullptr; + } + }; + + bool called; + fmt::format_parse_context ctx; + + fmt::format_parse_context& parse_context() { return ctx; } + void advance_to(const char*) {} +}; + +TEST(ArgTest, MakeValueWithCustomContext) { auto t = test_struct(); fmt::detail::value<custom_context> arg( fmt::detail::arg_mapper<custom_context>().map(t)); - custom_context ctx = {false, fmt::format_parse_context("")}; - arg.custom.format(&t, ctx.parse_context(), ctx); - EXPECT_TRUE(ctx.called); -} - -FMT_BEGIN_NAMESPACE + custom_context ctx = {false, fmt::format_parse_context("")}; + arg.custom.format(&t, ctx.parse_context(), ctx); + EXPECT_TRUE(ctx.called); +} + +FMT_BEGIN_NAMESPACE namespace detail { -template <typename Char> -bool operator==(custom_value<Char> lhs, custom_value<Char> rhs) { - return lhs.value == rhs.value; -} +template <typename Char> +bool operator==(custom_value<Char> lhs, custom_value<Char> rhs) { + return lhs.value == rhs.value; +} } // namespace detail -FMT_END_NAMESPACE - -// Use a unique result type to make sure that there are no undesirable -// conversions. -struct test_result {}; - -template <typename T> struct mock_visitor { +FMT_END_NAMESPACE + +// Use a unique result type to make sure that there are no undesirable +// conversions. +struct test_result {}; + +template <typename T> struct mock_visitor { template <typename U> struct result { using type = test_result; }; - - mock_visitor() { + + mock_visitor() { ON_CALL(*this, visit(_)).WillByDefault(Return(test_result())); - } - - MOCK_METHOD1_T(visit, test_result(T value)); - MOCK_METHOD0_T(unexpected, void()); - - test_result operator()(T value) { return visit(value); } - - template <typename U> test_result operator()(U) { - unexpected(); - return test_result(); - } -}; - + } + + MOCK_METHOD1_T(visit, test_result(T value)); + MOCK_METHOD0_T(unexpected, void()); + + test_result operator()(T value) { return visit(value); } + + template <typename U> test_result operator()(U) { + unexpected(); + return test_result(); + } +}; + template <typename T> struct visit_type { using type = T; }; - + #define VISIT_TYPE(type_, visit_type_) \ template <> struct visit_type<type_> { using type = visit_type_; } - -VISIT_TYPE(signed char, int); -VISIT_TYPE(unsigned char, unsigned); -VISIT_TYPE(short, int); -VISIT_TYPE(unsigned short, unsigned); - -#if LONG_MAX == INT_MAX -VISIT_TYPE(long, int); -VISIT_TYPE(unsigned long, unsigned); -#else -VISIT_TYPE(long, long long); -VISIT_TYPE(unsigned long, unsigned long long); -#endif - -#define CHECK_ARG_(Char, expected, value) \ - { \ - testing::StrictMock<mock_visitor<decltype(expected)>> visitor; \ - EXPECT_CALL(visitor, visit(expected)); \ + +VISIT_TYPE(signed char, int); +VISIT_TYPE(unsigned char, unsigned); +VISIT_TYPE(short, int); +VISIT_TYPE(unsigned short, unsigned); + +#if LONG_MAX == INT_MAX +VISIT_TYPE(long, int); +VISIT_TYPE(unsigned long, unsigned); +#else +VISIT_TYPE(long, long long); +VISIT_TYPE(unsigned long, unsigned long long); +#endif + +#define CHECK_ARG_(Char, expected, value) \ + { \ + testing::StrictMock<mock_visitor<decltype(expected)>> visitor; \ + EXPECT_CALL(visitor, visit(expected)); \ using iterator = std::back_insert_iterator<buffer<Char>>; \ - fmt::visit_format_arg( \ - visitor, make_arg<fmt::basic_format_context<iterator, Char>>(value)); \ - } - -#define CHECK_ARG(value, typename_) \ - { \ + fmt::visit_format_arg( \ + visitor, make_arg<fmt::basic_format_context<iterator, Char>>(value)); \ + } + +#define CHECK_ARG(value, typename_) \ + { \ using value_type = decltype(value); \ typename_ visit_type<value_type>::type expected = value; \ - CHECK_ARG_(char, expected, value) \ - CHECK_ARG_(wchar_t, expected, value) \ - } - -template <typename T> class NumericArgTest : public testing::Test {}; - + CHECK_ARG_(char, expected, value) \ + CHECK_ARG_(wchar_t, expected, value) \ + } + +template <typename T> class NumericArgTest : public testing::Test {}; + using types = ::testing::Types<bool, signed char, unsigned char, signed, unsigned short, int, unsigned, long, unsigned long, long long, unsigned long long, float, double, long double>; TYPED_TEST_CASE(NumericArgTest, types); - -template <typename T> + +template <typename T> fmt::enable_if_t<std::is_integral<T>::value, T> test_value() { - return static_cast<T>(42); -} - -template <typename T> + return static_cast<T>(42); +} + +template <typename T> fmt::enable_if_t<std::is_floating_point<T>::value, T> test_value() { - return static_cast<T>(4.2); -} - -TYPED_TEST(NumericArgTest, MakeAndVisit) { - CHECK_ARG(test_value<TypeParam>(), typename); - CHECK_ARG(std::numeric_limits<TypeParam>::min(), typename); - CHECK_ARG(std::numeric_limits<TypeParam>::max(), typename); -} - -TEST(ArgTest, CharArg) { - CHECK_ARG_(char, 'a', 'a'); - CHECK_ARG_(wchar_t, L'a', 'a'); - CHECK_ARG_(wchar_t, L'a', L'a'); -} - -TEST(ArgTest, StringArg) { - char str_data[] = "test"; - char* str = str_data; - const char* cstr = str; - CHECK_ARG_(char, cstr, str); - + return static_cast<T>(4.2); +} + +TYPED_TEST(NumericArgTest, MakeAndVisit) { + CHECK_ARG(test_value<TypeParam>(), typename); + CHECK_ARG(std::numeric_limits<TypeParam>::min(), typename); + CHECK_ARG(std::numeric_limits<TypeParam>::max(), typename); +} + +TEST(ArgTest, CharArg) { + CHECK_ARG_(char, 'a', 'a'); + CHECK_ARG_(wchar_t, L'a', 'a'); + CHECK_ARG_(wchar_t, L'a', L'a'); +} + +TEST(ArgTest, StringArg) { + char str_data[] = "test"; + char* str = str_data; + const char* cstr = str; + CHECK_ARG_(char, cstr, str); + auto sref = string_view(str); - CHECK_ARG_(char, sref, std::string(str)); -} - -TEST(ArgTest, WStringArg) { - wchar_t str_data[] = L"test"; - wchar_t* str = str_data; - const wchar_t* cstr = str; - - fmt::wstring_view sref(str); - CHECK_ARG_(wchar_t, cstr, str); - CHECK_ARG_(wchar_t, cstr, cstr); - CHECK_ARG_(wchar_t, sref, std::wstring(str)); - CHECK_ARG_(wchar_t, sref, fmt::wstring_view(str)); -} - -TEST(ArgTest, PointerArg) { - void* p = nullptr; - const void* cp = nullptr; - CHECK_ARG_(char, cp, p); - CHECK_ARG_(wchar_t, cp, p); - CHECK_ARG(cp, ); -} - -struct check_custom { - test_result operator()( - fmt::basic_format_arg<fmt::format_context>::handle h) const { + CHECK_ARG_(char, sref, std::string(str)); +} + +TEST(ArgTest, WStringArg) { + wchar_t str_data[] = L"test"; + wchar_t* str = str_data; + const wchar_t* cstr = str; + + fmt::wstring_view sref(str); + CHECK_ARG_(wchar_t, cstr, str); + CHECK_ARG_(wchar_t, cstr, cstr); + CHECK_ARG_(wchar_t, sref, std::wstring(str)); + CHECK_ARG_(wchar_t, sref, fmt::wstring_view(str)); +} + +TEST(ArgTest, PointerArg) { + void* p = nullptr; + const void* cp = nullptr; + CHECK_ARG_(char, cp, p); + CHECK_ARG_(wchar_t, cp, p); + CHECK_ARG(cp, ); +} + +struct check_custom { + test_result operator()( + fmt::basic_format_arg<fmt::format_context>::handle h) const { struct test_buffer final : fmt::detail::buffer<char> { - char data[10]; + char data[10]; test_buffer() : fmt::detail::buffer<char>(data, 0, 10) {} void grow(size_t) {} - } buffer; - fmt::format_parse_context parse_ctx(""); + } buffer; + fmt::format_parse_context parse_ctx(""); fmt::format_context ctx{fmt::detail::buffer_appender<char>(buffer), fmt::format_args()}; - h.format(parse_ctx, ctx); - EXPECT_EQ("test", std::string(buffer.data, buffer.size())); - return test_result(); - } -}; - -TEST(ArgTest, CustomArg) { - test_struct test; + h.format(parse_ctx, ctx); + EXPECT_EQ("test", std::string(buffer.data, buffer.size())); + return test_result(); + } +}; + +TEST(ArgTest, CustomArg) { + test_struct test; using visitor = mock_visitor<fmt::basic_format_arg<fmt::format_context>::handle>; - testing::StrictMock<visitor> v; + testing::StrictMock<visitor> v; EXPECT_CALL(v, visit(_)).WillOnce(Invoke(check_custom())); - fmt::visit_format_arg(v, make_arg<fmt::format_context>(test)); -} - -TEST(ArgTest, VisitInvalidArg) { - testing::StrictMock<mock_visitor<fmt::monostate>> visitor; - EXPECT_CALL(visitor, visit(_)); - fmt::basic_format_arg<fmt::format_context> arg; - fmt::visit_format_arg(visitor, arg); -} - -TEST(FormatDynArgsTest, Basic) { - fmt::dynamic_format_arg_store<fmt::format_context> store; - store.push_back(42); - store.push_back("abc1"); - store.push_back(1.5f); + fmt::visit_format_arg(v, make_arg<fmt::format_context>(test)); +} + +TEST(ArgTest, VisitInvalidArg) { + testing::StrictMock<mock_visitor<fmt::monostate>> visitor; + EXPECT_CALL(visitor, visit(_)); + fmt::basic_format_arg<fmt::format_context> arg; + fmt::visit_format_arg(visitor, arg); +} + +TEST(FormatDynArgsTest, Basic) { + fmt::dynamic_format_arg_store<fmt::format_context> store; + store.push_back(42); + store.push_back("abc1"); + store.push_back(1.5f); EXPECT_EQ("42 and abc1 and 1.5", fmt::vformat("{} and {} and {}", store)); -} - -TEST(FormatDynArgsTest, StringsAndRefs) { - // Unfortunately the tests are compiled with old ABI so strings use COW. - fmt::dynamic_format_arg_store<fmt::format_context> store; - char str[] = "1234567890"; - store.push_back(str); - store.push_back(std::cref(str)); - store.push_back(fmt::string_view{str}); - str[0] = 'X'; - - std::string result = fmt::vformat("{} and {} and {}", store); - EXPECT_EQ("1234567890 and X234567890 and X234567890", result); -} - -struct custom_type { - int i = 0; -}; - -FMT_BEGIN_NAMESPACE -template <> struct formatter<custom_type> { - auto parse(format_parse_context& ctx) const -> decltype(ctx.begin()) { - return ctx.begin(); - } - - template <typename FormatContext> - auto format(const custom_type& p, FormatContext& ctx) -> decltype(ctx.out()) { - return format_to(ctx.out(), "cust={}", p.i); - } -}; -FMT_END_NAMESPACE - -TEST(FormatDynArgsTest, CustomFormat) { - fmt::dynamic_format_arg_store<fmt::format_context> store; - custom_type c{}; - store.push_back(c); - ++c.i; - store.push_back(c); - ++c.i; - store.push_back(std::cref(c)); - ++c.i; - std::string result = fmt::vformat("{} and {} and {}", store); - EXPECT_EQ("cust=0 and cust=1 and cust=3", result); -} - +} + +TEST(FormatDynArgsTest, StringsAndRefs) { + // Unfortunately the tests are compiled with old ABI so strings use COW. + fmt::dynamic_format_arg_store<fmt::format_context> store; + char str[] = "1234567890"; + store.push_back(str); + store.push_back(std::cref(str)); + store.push_back(fmt::string_view{str}); + str[0] = 'X'; + + std::string result = fmt::vformat("{} and {} and {}", store); + EXPECT_EQ("1234567890 and X234567890 and X234567890", result); +} + +struct custom_type { + int i = 0; +}; + +FMT_BEGIN_NAMESPACE +template <> struct formatter<custom_type> { + auto parse(format_parse_context& ctx) const -> decltype(ctx.begin()) { + return ctx.begin(); + } + + template <typename FormatContext> + auto format(const custom_type& p, FormatContext& ctx) -> decltype(ctx.out()) { + return format_to(ctx.out(), "cust={}", p.i); + } +}; +FMT_END_NAMESPACE + +TEST(FormatDynArgsTest, CustomFormat) { + fmt::dynamic_format_arg_store<fmt::format_context> store; + custom_type c{}; + store.push_back(c); + ++c.i; + store.push_back(c); + ++c.i; + store.push_back(std::cref(c)); + ++c.i; + std::string result = fmt::vformat("{} and {} and {}", store); + EXPECT_EQ("cust=0 and cust=1 and cust=3", result); +} + TEST(FormatDynArgsTest, NamedInt) { fmt::dynamic_format_arg_store<fmt::format_context> store; store.push_back(fmt::arg("a1", 42)); @@ -464,28 +464,28 @@ TEST(FormatDynArgsTest, NamedStrings) { EXPECT_EQ("1234567890 and X234567890", fmt::vformat("{a1} and {a2}", store)); } -TEST(FormatDynArgsTest, NamedArgByRef) { - fmt::dynamic_format_arg_store<fmt::format_context> store; - - // Note: fmt::arg() constructs an object which holds a reference - // to its value. It's not an aggregate, so it doesn't extend the - // reference lifetime. As a result, it's a very bad idea passing temporary - // as a named argument value. Only GCC with optimization level >0 - // complains about this. - // - // A real life usecase is when you have both name and value alive - // guarantee their lifetime and thus don't want them to be copied into - // storages. - int a1_val{42}; - auto a1 = fmt::arg("a1_", a1_val); +TEST(FormatDynArgsTest, NamedArgByRef) { + fmt::dynamic_format_arg_store<fmt::format_context> store; + + // Note: fmt::arg() constructs an object which holds a reference + // to its value. It's not an aggregate, so it doesn't extend the + // reference lifetime. As a result, it's a very bad idea passing temporary + // as a named argument value. Only GCC with optimization level >0 + // complains about this. + // + // A real life usecase is when you have both name and value alive + // guarantee their lifetime and thus don't want them to be copied into + // storages. + int a1_val{42}; + auto a1 = fmt::arg("a1_", a1_val); store.push_back("abc"); store.push_back(1.5f); - store.push_back(std::cref(a1)); - + store.push_back(std::cref(a1)); + std::string result = fmt::vformat("{a1_} and {} and {} and {}", store); EXPECT_EQ("42 and abc and 1.5 and 42", result); } - + TEST(FormatDynArgsTest, NamedCustomFormat) { fmt::dynamic_format_arg_store<fmt::format_context> store; custom_type c{}; @@ -504,7 +504,7 @@ TEST(FormatDynArgsTest, Clear) { store.push_back(42); std::string result = fmt::vformat("{}", store); - EXPECT_EQ("42", result); + EXPECT_EQ("42", result); store.push_back(43); result = fmt::vformat("{} and {}", store); @@ -514,8 +514,8 @@ TEST(FormatDynArgsTest, Clear) { store.push_back(44); result = fmt::vformat("{}", store); EXPECT_EQ("44", result); -} - +} + TEST(FormatDynArgsTest, Reserve) { fmt::dynamic_format_arg_store<fmt::format_context> store; store.reserve(2, 1); @@ -525,249 +525,249 @@ TEST(FormatDynArgsTest, Reserve) { EXPECT_EQ("42 and 1.5", result); } -struct copy_throwable { - copy_throwable() {} - copy_throwable(const copy_throwable&) { throw "deal with it"; } -}; - -FMT_BEGIN_NAMESPACE -template <> struct formatter<copy_throwable> { - auto parse(format_parse_context& ctx) const -> decltype(ctx.begin()) { - return ctx.begin(); - } - auto format(copy_throwable, format_context& ctx) -> decltype(ctx.out()) { - return ctx.out(); - } -}; -FMT_END_NAMESPACE - -TEST(FormatDynArgsTest, ThrowOnCopy) { - fmt::dynamic_format_arg_store<fmt::format_context> store; - store.push_back(std::string("foo")); - try { - store.push_back(copy_throwable()); - } catch (...) { - } - EXPECT_EQ(fmt::vformat("{}", store), "foo"); -} - -TEST(StringViewTest, ValueType) { - static_assert(std::is_same<string_view::value_type, char>::value, ""); -} - -TEST(StringViewTest, Length) { - // Test that string_view::size() returns string length, not buffer size. - char str[100] = "some string"; - EXPECT_EQ(std::strlen(str), string_view(str).size()); - EXPECT_LT(std::strlen(str), sizeof(str)); -} - -// Check string_view's comparison operator. -template <template <typename> class Op> void check_op() { - const char* inputs[] = {"foo", "fop", "fo"}; +struct copy_throwable { + copy_throwable() {} + copy_throwable(const copy_throwable&) { throw "deal with it"; } +}; + +FMT_BEGIN_NAMESPACE +template <> struct formatter<copy_throwable> { + auto parse(format_parse_context& ctx) const -> decltype(ctx.begin()) { + return ctx.begin(); + } + auto format(copy_throwable, format_context& ctx) -> decltype(ctx.out()) { + return ctx.out(); + } +}; +FMT_END_NAMESPACE + +TEST(FormatDynArgsTest, ThrowOnCopy) { + fmt::dynamic_format_arg_store<fmt::format_context> store; + store.push_back(std::string("foo")); + try { + store.push_back(copy_throwable()); + } catch (...) { + } + EXPECT_EQ(fmt::vformat("{}", store), "foo"); +} + +TEST(StringViewTest, ValueType) { + static_assert(std::is_same<string_view::value_type, char>::value, ""); +} + +TEST(StringViewTest, Length) { + // Test that string_view::size() returns string length, not buffer size. + char str[100] = "some string"; + EXPECT_EQ(std::strlen(str), string_view(str).size()); + EXPECT_LT(std::strlen(str), sizeof(str)); +} + +// Check string_view's comparison operator. +template <template <typename> class Op> void check_op() { + const char* inputs[] = {"foo", "fop", "fo"}; size_t num_inputs = sizeof(inputs) / sizeof(*inputs); for (size_t i = 0; i < num_inputs; ++i) { for (size_t j = 0; j < num_inputs; ++j) { - string_view lhs(inputs[i]), rhs(inputs[j]); - EXPECT_EQ(Op<int>()(lhs.compare(rhs), 0), Op<string_view>()(lhs, rhs)); - } - } -} - -TEST(StringViewTest, Compare) { - EXPECT_EQ(string_view("foo").compare(string_view("foo")), 0); - EXPECT_GT(string_view("fop").compare(string_view("foo")), 0); - EXPECT_LT(string_view("foo").compare(string_view("fop")), 0); - EXPECT_GT(string_view("foo").compare(string_view("fo")), 0); - EXPECT_LT(string_view("fo").compare(string_view("foo")), 0); - check_op<std::equal_to>(); - check_op<std::not_equal_to>(); - check_op<std::less>(); - check_op<std::less_equal>(); - check_op<std::greater>(); - check_op<std::greater_equal>(); -} - -struct enabled_formatter {}; -struct disabled_formatter {}; -struct disabled_formatter_convertible { - operator int() const { return 42; } -}; - -FMT_BEGIN_NAMESPACE -template <> struct formatter<enabled_formatter> { - auto parse(format_parse_context& ctx) -> decltype(ctx.begin()) { - return ctx.begin(); - } - auto format(enabled_formatter, format_context& ctx) -> decltype(ctx.out()) { - return ctx.out(); - } -}; -FMT_END_NAMESPACE - -TEST(CoreTest, HasFormatter) { - using fmt::has_formatter; - using context = fmt::format_context; - static_assert(has_formatter<enabled_formatter, context>::value, ""); - static_assert(!has_formatter<disabled_formatter, context>::value, ""); - static_assert(!has_formatter<disabled_formatter_convertible, context>::value, - ""); -} - -struct convertible_to_int { - operator int() const { return 42; } -}; - -struct convertible_to_c_string { - operator const char*() const { return "foo"; } -}; - -FMT_BEGIN_NAMESPACE -template <> struct formatter<convertible_to_int> { - auto parse(format_parse_context& ctx) -> decltype(ctx.begin()) { - return ctx.begin(); - } - auto format(convertible_to_int, format_context& ctx) -> decltype(ctx.out()) { - return std::copy_n("foo", 3, ctx.out()); - } -}; - -template <> struct formatter<convertible_to_c_string> { - auto parse(format_parse_context& ctx) -> decltype(ctx.begin()) { - return ctx.begin(); - } - auto format(convertible_to_c_string, format_context& ctx) - -> decltype(ctx.out()) { - return std::copy_n("bar", 3, ctx.out()); - } -}; -FMT_END_NAMESPACE - -TEST(CoreTest, FormatterOverridesImplicitConversion) { - EXPECT_EQ(fmt::format("{}", convertible_to_int()), "foo"); - EXPECT_EQ(fmt::format("{}", convertible_to_c_string()), "bar"); -} - -namespace my_ns { -template <typename Char> class my_string { + string_view lhs(inputs[i]), rhs(inputs[j]); + EXPECT_EQ(Op<int>()(lhs.compare(rhs), 0), Op<string_view>()(lhs, rhs)); + } + } +} + +TEST(StringViewTest, Compare) { + EXPECT_EQ(string_view("foo").compare(string_view("foo")), 0); + EXPECT_GT(string_view("fop").compare(string_view("foo")), 0); + EXPECT_LT(string_view("foo").compare(string_view("fop")), 0); + EXPECT_GT(string_view("foo").compare(string_view("fo")), 0); + EXPECT_LT(string_view("fo").compare(string_view("foo")), 0); + check_op<std::equal_to>(); + check_op<std::not_equal_to>(); + check_op<std::less>(); + check_op<std::less_equal>(); + check_op<std::greater>(); + check_op<std::greater_equal>(); +} + +struct enabled_formatter {}; +struct disabled_formatter {}; +struct disabled_formatter_convertible { + operator int() const { return 42; } +}; + +FMT_BEGIN_NAMESPACE +template <> struct formatter<enabled_formatter> { + auto parse(format_parse_context& ctx) -> decltype(ctx.begin()) { + return ctx.begin(); + } + auto format(enabled_formatter, format_context& ctx) -> decltype(ctx.out()) { + return ctx.out(); + } +}; +FMT_END_NAMESPACE + +TEST(CoreTest, HasFormatter) { + using fmt::has_formatter; + using context = fmt::format_context; + static_assert(has_formatter<enabled_formatter, context>::value, ""); + static_assert(!has_formatter<disabled_formatter, context>::value, ""); + static_assert(!has_formatter<disabled_formatter_convertible, context>::value, + ""); +} + +struct convertible_to_int { + operator int() const { return 42; } +}; + +struct convertible_to_c_string { + operator const char*() const { return "foo"; } +}; + +FMT_BEGIN_NAMESPACE +template <> struct formatter<convertible_to_int> { + auto parse(format_parse_context& ctx) -> decltype(ctx.begin()) { + return ctx.begin(); + } + auto format(convertible_to_int, format_context& ctx) -> decltype(ctx.out()) { + return std::copy_n("foo", 3, ctx.out()); + } +}; + +template <> struct formatter<convertible_to_c_string> { + auto parse(format_parse_context& ctx) -> decltype(ctx.begin()) { + return ctx.begin(); + } + auto format(convertible_to_c_string, format_context& ctx) + -> decltype(ctx.out()) { + return std::copy_n("bar", 3, ctx.out()); + } +}; +FMT_END_NAMESPACE + +TEST(CoreTest, FormatterOverridesImplicitConversion) { + EXPECT_EQ(fmt::format("{}", convertible_to_int()), "foo"); + EXPECT_EQ(fmt::format("{}", convertible_to_c_string()), "bar"); +} + +namespace my_ns { +template <typename Char> class my_string { private: std::basic_string<Char> s_; - public: - my_string(const Char* s) : s_(s) {} - const Char* data() const FMT_NOEXCEPT { return s_.data(); } + public: + my_string(const Char* s) : s_(s) {} + const Char* data() const FMT_NOEXCEPT { return s_.data(); } size_t length() const FMT_NOEXCEPT { return s_.size(); } - operator const Char*() const { return s_.c_str(); } -}; - -template <typename Char> -inline fmt::basic_string_view<Char> to_string_view(const my_string<Char>& s) - FMT_NOEXCEPT { - return {s.data(), s.length()}; -} - -struct non_string {}; -} // namespace my_ns - -template <typename T> class IsStringTest : public testing::Test {}; - -typedef ::testing::Types<char, wchar_t, char16_t, char32_t> StringCharTypes; -TYPED_TEST_CASE(IsStringTest, StringCharTypes); - -namespace { -template <typename Char> -struct derived_from_string_view : fmt::basic_string_view<Char> {}; -} // namespace - -TYPED_TEST(IsStringTest, IsString) { + operator const Char*() const { return s_.c_str(); } +}; + +template <typename Char> +inline fmt::basic_string_view<Char> to_string_view(const my_string<Char>& s) + FMT_NOEXCEPT { + return {s.data(), s.length()}; +} + +struct non_string {}; +} // namespace my_ns + +template <typename T> class IsStringTest : public testing::Test {}; + +typedef ::testing::Types<char, wchar_t, char16_t, char32_t> StringCharTypes; +TYPED_TEST_CASE(IsStringTest, StringCharTypes); + +namespace { +template <typename Char> +struct derived_from_string_view : fmt::basic_string_view<Char> {}; +} // namespace + +TYPED_TEST(IsStringTest, IsString) { EXPECT_TRUE(fmt::detail::is_string<TypeParam*>::value); EXPECT_TRUE(fmt::detail::is_string<const TypeParam*>::value); EXPECT_TRUE(fmt::detail::is_string<TypeParam[2]>::value); EXPECT_TRUE(fmt::detail::is_string<const TypeParam[2]>::value); EXPECT_TRUE(fmt::detail::is_string<std::basic_string<TypeParam>>::value); EXPECT_TRUE(fmt::detail::is_string<fmt::basic_string_view<TypeParam>>::value); - EXPECT_TRUE( + EXPECT_TRUE( fmt::detail::is_string<derived_from_string_view<TypeParam>>::value); using string_view = fmt::detail::std_string_view<TypeParam>; - EXPECT_TRUE(std::is_empty<string_view>::value != + EXPECT_TRUE(std::is_empty<string_view>::value != fmt::detail::is_string<string_view>::value); EXPECT_TRUE(fmt::detail::is_string<my_ns::my_string<TypeParam>>::value); EXPECT_FALSE(fmt::detail::is_string<my_ns::non_string>::value); -} - -TEST(CoreTest, Format) { - // This should work without including fmt/format.h. -#ifdef FMT_FORMAT_H_ -# error fmt/format.h must not be included in the core test -#endif - EXPECT_EQ(fmt::format("{}", 42), "42"); -} - -TEST(CoreTest, FormatTo) { - // This should work without including fmt/format.h. -#ifdef FMT_FORMAT_H_ -# error fmt/format.h must not be included in the core test -#endif - std::string s; - fmt::format_to(std::back_inserter(s), "{}", 42); - EXPECT_EQ(s, "42"); -} - -TEST(CoreTest, ToStringViewForeignStrings) { - using namespace my_ns; - EXPECT_EQ(to_string_view(my_string<char>("42")), "42"); +} + +TEST(CoreTest, Format) { + // This should work without including fmt/format.h. +#ifdef FMT_FORMAT_H_ +# error fmt/format.h must not be included in the core test +#endif + EXPECT_EQ(fmt::format("{}", 42), "42"); +} + +TEST(CoreTest, FormatTo) { + // This should work without including fmt/format.h. +#ifdef FMT_FORMAT_H_ +# error fmt/format.h must not be included in the core test +#endif + std::string s; + fmt::format_to(std::back_inserter(s), "{}", 42); + EXPECT_EQ(s, "42"); +} + +TEST(CoreTest, ToStringViewForeignStrings) { + using namespace my_ns; + EXPECT_EQ(to_string_view(my_string<char>("42")), "42"); fmt::detail::type type = fmt::detail::mapped_type_constant<my_string<char>, fmt::format_context>::value; EXPECT_EQ(type, fmt::detail::type::string_type); -} - -TEST(CoreTest, FormatForeignStrings) { - using namespace my_ns; - EXPECT_EQ(fmt::format(my_string<char>("{}"), 42), "42"); -} - -struct implicitly_convertible_to_string { - operator std::string() const { return "foo"; } -}; - -struct implicitly_convertible_to_string_view { - operator fmt::string_view() const { return "foo"; } -}; - +} + +TEST(CoreTest, FormatForeignStrings) { + using namespace my_ns; + EXPECT_EQ(fmt::format(my_string<char>("{}"), 42), "42"); +} + +struct implicitly_convertible_to_string { + operator std::string() const { return "foo"; } +}; + +struct implicitly_convertible_to_string_view { + operator fmt::string_view() const { return "foo"; } +}; + TEST(CoreTest, FormatImplicitlyConvertibleToStringView) { - EXPECT_EQ("foo", fmt::format("{}", implicitly_convertible_to_string_view())); -} - -// std::is_constructible is broken in MSVC until version 2015. -#if !FMT_MSC_VER || FMT_MSC_VER >= 1900 -struct explicitly_convertible_to_string_view { - explicit operator fmt::string_view() const { return "foo"; } -}; - + EXPECT_EQ("foo", fmt::format("{}", implicitly_convertible_to_string_view())); +} + +// std::is_constructible is broken in MSVC until version 2015. +#if !FMT_MSC_VER || FMT_MSC_VER >= 1900 +struct explicitly_convertible_to_string_view { + explicit operator fmt::string_view() const { return "foo"; } +}; + TEST(CoreTest, FormatExplicitlyConvertibleToStringView) { - EXPECT_EQ("foo", fmt::format("{}", explicitly_convertible_to_string_view())); -} - -# ifdef FMT_USE_STRING_VIEW -struct explicitly_convertible_to_std_string_view { - explicit operator std::string_view() const { return "foo"; } -}; - + EXPECT_EQ("foo", fmt::format("{}", explicitly_convertible_to_string_view())); +} + +# ifdef FMT_USE_STRING_VIEW +struct explicitly_convertible_to_std_string_view { + explicit operator std::string_view() const { return "foo"; } +}; + TEST(CoreTest, FormatExplicitlyConvertibleToStdStringView) { - EXPECT_EQ("foo", - fmt::format("{}", explicitly_convertible_to_std_string_view())); -} -# endif -#endif - -struct disabled_rvalue_conversion { - operator const char*() const& { return "foo"; } - operator const char*() & { return "foo"; } - operator const char*() const&& = delete; - operator const char*() && = delete; -}; - + EXPECT_EQ("foo", + fmt::format("{}", explicitly_convertible_to_std_string_view())); +} +# endif +#endif + +struct disabled_rvalue_conversion { + operator const char*() const& { return "foo"; } + operator const char*() & { return "foo"; } + operator const char*() const&& = delete; + operator const char*() && = delete; +}; + TEST(CoreTest, DisabledRValueConversion) { - EXPECT_EQ("foo", fmt::format("{}", disabled_rvalue_conversion())); -} + EXPECT_EQ("foo", fmt::format("{}", disabled_rvalue_conversion())); +} diff --git a/contrib/libs/fmt/test/core-test/ya.make b/contrib/libs/fmt/test/core-test/ya.make index 650db81964..8c320f4810 100644 --- a/contrib/libs/fmt/test/core-test/ya.make +++ b/contrib/libs/fmt/test/core-test/ya.make @@ -1,37 +1,37 @@ -# Generated by devtools/yamaker. - +# Generated by devtools/yamaker. + GTEST() - + WITHOUT_LICENSE_TEXTS() - + OWNER( orivej g:cpp-contrib ) -LICENSE(MIT) - -PEERDIR( - contrib/libs/fmt - contrib/libs/fmt/test -) - -NO_COMPILER_WARNINGS() - -NO_UTIL() - -CFLAGS( - -DFMT_LOCALE - -DFMT_SHARED - -DGTEST_HAS_STD_WSTRING=1 - -DGTEST_LANG_CXX11=0 - -D_SILENCE_TR1_NAMESPACE_DEPRECATION_WARNING=1 -) - -SRCDIR(contrib/libs/fmt/test) - -SRCS( - core-test.cc -) - -END() +LICENSE(MIT) + +PEERDIR( + contrib/libs/fmt + contrib/libs/fmt/test +) + +NO_COMPILER_WARNINGS() + +NO_UTIL() + +CFLAGS( + -DFMT_LOCALE + -DFMT_SHARED + -DGTEST_HAS_STD_WSTRING=1 + -DGTEST_LANG_CXX11=0 + -D_SILENCE_TR1_NAMESPACE_DEPRECATION_WARNING=1 +) + +SRCDIR(contrib/libs/fmt/test) + +SRCS( + core-test.cc +) + +END() diff --git a/contrib/libs/fmt/test/format-impl-test.cc b/contrib/libs/fmt/test/format-impl-test.cc index afe182e02c..66b55b5381 100644 --- a/contrib/libs/fmt/test/format-impl-test.cc +++ b/contrib/libs/fmt/test/format-impl-test.cc @@ -1,220 +1,220 @@ -// Formatting library for C++ - formatting library implementation tests -// -// Copyright (c) 2012 - present, Victor Zverovich -// All rights reserved. -// -// For the license information refer to format.h. - -#define FMT_NOEXCEPT -#undef FMT_SHARED -#include "test-assert.h" - -// Include format.cc instead of format.h to test implementation. -#include <algorithm> -#include <cstring> - -#include "../src/format.cc" -#include "fmt/printf.h" -#include <gmock/gmock.h> -#include "gtest-extra.h" -#include "util.h" - +// Formatting library for C++ - formatting library implementation tests +// +// Copyright (c) 2012 - present, Victor Zverovich +// All rights reserved. +// +// For the license information refer to format.h. + +#define FMT_NOEXCEPT +#undef FMT_SHARED +#include "test-assert.h" + +// Include format.cc instead of format.h to test implementation. +#include <algorithm> +#include <cstring> + +#include "../src/format.cc" +#include "fmt/printf.h" +#include <gmock/gmock.h> +#include "gtest-extra.h" +#include "util.h" + #ifdef _WIN32 # include <windows.h> # undef max #endif - + using fmt::detail::bigint; using fmt::detail::fp; using fmt::detail::max_value; - -static_assert(!std::is_copy_constructible<bigint>::value, ""); -static_assert(!std::is_copy_assignable<bigint>::value, ""); - -TEST(BigIntTest, Construct) { - EXPECT_EQ("", fmt::format("{}", bigint())); - EXPECT_EQ("42", fmt::format("{}", bigint(0x42))); - EXPECT_EQ("123456789abcedf0", fmt::format("{}", bigint(0x123456789abcedf0))); -} - -TEST(BigIntTest, Compare) { - bigint n1(42); - bigint n2(42); - EXPECT_EQ(compare(n1, n2), 0); - n2 <<= 32; - EXPECT_LT(compare(n1, n2), 0); - bigint n3(43); - EXPECT_LT(compare(n1, n3), 0); - EXPECT_GT(compare(n3, n1), 0); - bigint n4(42 * 0x100000001); - EXPECT_LT(compare(n2, n4), 0); - EXPECT_GT(compare(n4, n2), 0); -} - -TEST(BigIntTest, AddCompare) { - EXPECT_LT( - add_compare(bigint(0xffffffff), bigint(0xffffffff), bigint(1) <<= 64), 0); - EXPECT_LT(add_compare(bigint(1) <<= 32, bigint(1), bigint(1) <<= 96), 0); - EXPECT_GT(add_compare(bigint(1) <<= 32, bigint(0), bigint(0xffffffff)), 0); - EXPECT_GT(add_compare(bigint(0), bigint(1) <<= 32, bigint(0xffffffff)), 0); - EXPECT_GT(add_compare(bigint(42), bigint(1), bigint(42)), 0); - EXPECT_GT(add_compare(bigint(0xffffffff), bigint(1), bigint(0xffffffff)), 0); - EXPECT_LT(add_compare(bigint(10), bigint(10), bigint(22)), 0); - EXPECT_LT(add_compare(bigint(0x100000010), bigint(0x100000010), - bigint(0x300000010)), - 0); - EXPECT_GT(add_compare(bigint(0x1ffffffff), bigint(0x100000002), - bigint(0x300000000)), - 0); - EXPECT_EQ(add_compare(bigint(0x1ffffffff), bigint(0x100000002), - bigint(0x300000001)), - 0); - EXPECT_LT(add_compare(bigint(0x1ffffffff), bigint(0x100000002), - bigint(0x300000002)), - 0); - EXPECT_LT(add_compare(bigint(0x1ffffffff), bigint(0x100000002), - bigint(0x300000003)), - 0); -} - -TEST(BigIntTest, ShiftLeft) { - bigint n(0x42); - n <<= 0; - EXPECT_EQ("42", fmt::format("{}", n)); - n <<= 1; - EXPECT_EQ("84", fmt::format("{}", n)); - n <<= 25; - EXPECT_EQ("108000000", fmt::format("{}", n)); -} - -TEST(BigIntTest, Multiply) { - bigint n(0x42); - EXPECT_THROW(n *= 0, assertion_failure); - n *= 1; - EXPECT_EQ("42", fmt::format("{}", n)); - n *= 2; - EXPECT_EQ("84", fmt::format("{}", n)); - n *= 0x12345678; - EXPECT_EQ("962fc95e0", fmt::format("{}", n)); - bigint bigmax(max_value<uint32_t>()); - bigmax *= max_value<uint32_t>(); - EXPECT_EQ("fffffffe00000001", fmt::format("{}", bigmax)); - bigmax.assign(max_value<uint64_t>()); - bigmax *= max_value<uint64_t>(); - EXPECT_EQ("fffffffffffffffe0000000000000001", fmt::format("{}", bigmax)); -} - -TEST(BigIntTest, Accumulator) { + +static_assert(!std::is_copy_constructible<bigint>::value, ""); +static_assert(!std::is_copy_assignable<bigint>::value, ""); + +TEST(BigIntTest, Construct) { + EXPECT_EQ("", fmt::format("{}", bigint())); + EXPECT_EQ("42", fmt::format("{}", bigint(0x42))); + EXPECT_EQ("123456789abcedf0", fmt::format("{}", bigint(0x123456789abcedf0))); +} + +TEST(BigIntTest, Compare) { + bigint n1(42); + bigint n2(42); + EXPECT_EQ(compare(n1, n2), 0); + n2 <<= 32; + EXPECT_LT(compare(n1, n2), 0); + bigint n3(43); + EXPECT_LT(compare(n1, n3), 0); + EXPECT_GT(compare(n3, n1), 0); + bigint n4(42 * 0x100000001); + EXPECT_LT(compare(n2, n4), 0); + EXPECT_GT(compare(n4, n2), 0); +} + +TEST(BigIntTest, AddCompare) { + EXPECT_LT( + add_compare(bigint(0xffffffff), bigint(0xffffffff), bigint(1) <<= 64), 0); + EXPECT_LT(add_compare(bigint(1) <<= 32, bigint(1), bigint(1) <<= 96), 0); + EXPECT_GT(add_compare(bigint(1) <<= 32, bigint(0), bigint(0xffffffff)), 0); + EXPECT_GT(add_compare(bigint(0), bigint(1) <<= 32, bigint(0xffffffff)), 0); + EXPECT_GT(add_compare(bigint(42), bigint(1), bigint(42)), 0); + EXPECT_GT(add_compare(bigint(0xffffffff), bigint(1), bigint(0xffffffff)), 0); + EXPECT_LT(add_compare(bigint(10), bigint(10), bigint(22)), 0); + EXPECT_LT(add_compare(bigint(0x100000010), bigint(0x100000010), + bigint(0x300000010)), + 0); + EXPECT_GT(add_compare(bigint(0x1ffffffff), bigint(0x100000002), + bigint(0x300000000)), + 0); + EXPECT_EQ(add_compare(bigint(0x1ffffffff), bigint(0x100000002), + bigint(0x300000001)), + 0); + EXPECT_LT(add_compare(bigint(0x1ffffffff), bigint(0x100000002), + bigint(0x300000002)), + 0); + EXPECT_LT(add_compare(bigint(0x1ffffffff), bigint(0x100000002), + bigint(0x300000003)), + 0); +} + +TEST(BigIntTest, ShiftLeft) { + bigint n(0x42); + n <<= 0; + EXPECT_EQ("42", fmt::format("{}", n)); + n <<= 1; + EXPECT_EQ("84", fmt::format("{}", n)); + n <<= 25; + EXPECT_EQ("108000000", fmt::format("{}", n)); +} + +TEST(BigIntTest, Multiply) { + bigint n(0x42); + EXPECT_THROW(n *= 0, assertion_failure); + n *= 1; + EXPECT_EQ("42", fmt::format("{}", n)); + n *= 2; + EXPECT_EQ("84", fmt::format("{}", n)); + n *= 0x12345678; + EXPECT_EQ("962fc95e0", fmt::format("{}", n)); + bigint bigmax(max_value<uint32_t>()); + bigmax *= max_value<uint32_t>(); + EXPECT_EQ("fffffffe00000001", fmt::format("{}", bigmax)); + bigmax.assign(max_value<uint64_t>()); + bigmax *= max_value<uint64_t>(); + EXPECT_EQ("fffffffffffffffe0000000000000001", fmt::format("{}", bigmax)); +} + +TEST(BigIntTest, Accumulator) { fmt::detail::accumulator acc; - EXPECT_EQ(acc.lower, 0); - EXPECT_EQ(acc.upper, 0); - acc.upper = 12; - acc.lower = 34; - EXPECT_EQ(static_cast<uint32_t>(acc), 34); - acc += 56; - EXPECT_EQ(acc.lower, 90); + EXPECT_EQ(acc.lower, 0); + EXPECT_EQ(acc.upper, 0); + acc.upper = 12; + acc.lower = 34; + EXPECT_EQ(static_cast<uint32_t>(acc), 34); + acc += 56; + EXPECT_EQ(acc.lower, 90); acc += fmt::detail::max_value<uint64_t>(); - EXPECT_EQ(acc.upper, 13); - EXPECT_EQ(acc.lower, 89); - acc >>= 32; - EXPECT_EQ(acc.upper, 0); - EXPECT_EQ(acc.lower, 13 * 0x100000000); -} - -TEST(BigIntTest, Square) { - bigint n0(0); - n0.square(); - EXPECT_EQ("0", fmt::format("{}", n0)); - bigint n1(0x100); - n1.square(); - EXPECT_EQ("10000", fmt::format("{}", n1)); - bigint n2(0xfffffffff); - n2.square(); - EXPECT_EQ("ffffffffe000000001", fmt::format("{}", n2)); - bigint n3(max_value<uint64_t>()); - n3.square(); - EXPECT_EQ("fffffffffffffffe0000000000000001", fmt::format("{}", n3)); - bigint n4; - n4.assign_pow10(10); - EXPECT_EQ("2540be400", fmt::format("{}", n4)); -} - -TEST(BigIntTest, DivModAssignZeroDivisor) { - bigint zero(0); - EXPECT_THROW(bigint(0).divmod_assign(zero), assertion_failure); - EXPECT_THROW(bigint(42).divmod_assign(zero), assertion_failure); -} - -TEST(BigIntTest, DivModAssignSelf) { - bigint n(100); - EXPECT_THROW(n.divmod_assign(n), assertion_failure); -} - -TEST(BigIntTest, DivModAssignUnaligned) { - // (42 << 340) / pow(10, 100): - bigint n1(42); - n1 <<= 340; - bigint n2; - n2.assign_pow10(100); - int result = n1.divmod_assign(n2); - EXPECT_EQ(result, 9406); - EXPECT_EQ("10f8353019583bfc29ffc8f564e1b9f9d819dbb4cf783e4507eca1539220p96", - fmt::format("{}", n1)); -} - -TEST(BigIntTest, DivModAssign) { - // 100 / 10: - bigint n1(100); - int result = n1.divmod_assign(bigint(10)); - EXPECT_EQ(result, 10); - EXPECT_EQ("0", fmt::format("{}", n1)); - // pow(10, 100) / (42 << 320): - n1.assign_pow10(100); - result = n1.divmod_assign(bigint(42) <<= 320); - EXPECT_EQ(result, 111); - EXPECT_EQ("13ad2594c37ceb0b2784c4ce0bf38ace408e211a7caab24308a82e8f10p96", - fmt::format("{}", n1)); - // 42 / 100: - bigint n2(42); - n1.assign_pow10(2); - result = n2.divmod_assign(n1); - EXPECT_EQ(result, 0); - EXPECT_EQ("2a", fmt::format("{}", n2)); -} - -template <bool is_iec559> void run_double_tests() { - fmt::print("warning: double is not IEC559, skipping FP tests\n"); -} - -template <> void run_double_tests<true>() { - // Construct from double. - EXPECT_EQ(fp(1.23), fp(0x13ae147ae147aeu, -52)); -} - -TEST(FPTest, DoubleTests) { - run_double_tests<std::numeric_limits<double>::is_iec559>(); -} - -TEST(FPTest, Normalize) { - const auto v = fp(0xbeef, 42); - auto normalized = normalize(v); - EXPECT_EQ(0xbeef000000000000, normalized.f); - EXPECT_EQ(-6, normalized.e); -} - -TEST(FPTest, Multiply) { - auto v = fp(123ULL << 32, 4) * fp(56ULL << 32, 7); - EXPECT_EQ(v.f, 123u * 56u); - EXPECT_EQ(v.e, 4 + 7 + 64); - v = fp(123ULL << 32, 4) * fp(567ULL << 31, 8); - EXPECT_EQ(v.f, (123 * 567 + 1u) / 2); - EXPECT_EQ(v.e, 4 + 8 + 64); -} - -TEST(FPTest, GetCachedPower) { + EXPECT_EQ(acc.upper, 13); + EXPECT_EQ(acc.lower, 89); + acc >>= 32; + EXPECT_EQ(acc.upper, 0); + EXPECT_EQ(acc.lower, 13 * 0x100000000); +} + +TEST(BigIntTest, Square) { + bigint n0(0); + n0.square(); + EXPECT_EQ("0", fmt::format("{}", n0)); + bigint n1(0x100); + n1.square(); + EXPECT_EQ("10000", fmt::format("{}", n1)); + bigint n2(0xfffffffff); + n2.square(); + EXPECT_EQ("ffffffffe000000001", fmt::format("{}", n2)); + bigint n3(max_value<uint64_t>()); + n3.square(); + EXPECT_EQ("fffffffffffffffe0000000000000001", fmt::format("{}", n3)); + bigint n4; + n4.assign_pow10(10); + EXPECT_EQ("2540be400", fmt::format("{}", n4)); +} + +TEST(BigIntTest, DivModAssignZeroDivisor) { + bigint zero(0); + EXPECT_THROW(bigint(0).divmod_assign(zero), assertion_failure); + EXPECT_THROW(bigint(42).divmod_assign(zero), assertion_failure); +} + +TEST(BigIntTest, DivModAssignSelf) { + bigint n(100); + EXPECT_THROW(n.divmod_assign(n), assertion_failure); +} + +TEST(BigIntTest, DivModAssignUnaligned) { + // (42 << 340) / pow(10, 100): + bigint n1(42); + n1 <<= 340; + bigint n2; + n2.assign_pow10(100); + int result = n1.divmod_assign(n2); + EXPECT_EQ(result, 9406); + EXPECT_EQ("10f8353019583bfc29ffc8f564e1b9f9d819dbb4cf783e4507eca1539220p96", + fmt::format("{}", n1)); +} + +TEST(BigIntTest, DivModAssign) { + // 100 / 10: + bigint n1(100); + int result = n1.divmod_assign(bigint(10)); + EXPECT_EQ(result, 10); + EXPECT_EQ("0", fmt::format("{}", n1)); + // pow(10, 100) / (42 << 320): + n1.assign_pow10(100); + result = n1.divmod_assign(bigint(42) <<= 320); + EXPECT_EQ(result, 111); + EXPECT_EQ("13ad2594c37ceb0b2784c4ce0bf38ace408e211a7caab24308a82e8f10p96", + fmt::format("{}", n1)); + // 42 / 100: + bigint n2(42); + n1.assign_pow10(2); + result = n2.divmod_assign(n1); + EXPECT_EQ(result, 0); + EXPECT_EQ("2a", fmt::format("{}", n2)); +} + +template <bool is_iec559> void run_double_tests() { + fmt::print("warning: double is not IEC559, skipping FP tests\n"); +} + +template <> void run_double_tests<true>() { + // Construct from double. + EXPECT_EQ(fp(1.23), fp(0x13ae147ae147aeu, -52)); +} + +TEST(FPTest, DoubleTests) { + run_double_tests<std::numeric_limits<double>::is_iec559>(); +} + +TEST(FPTest, Normalize) { + const auto v = fp(0xbeef, 42); + auto normalized = normalize(v); + EXPECT_EQ(0xbeef000000000000, normalized.f); + EXPECT_EQ(-6, normalized.e); +} + +TEST(FPTest, Multiply) { + auto v = fp(123ULL << 32, 4) * fp(56ULL << 32, 7); + EXPECT_EQ(v.f, 123u * 56u); + EXPECT_EQ(v.e, 4 + 7 + 64); + v = fp(123ULL << 32, 4) * fp(567ULL << 31, 8); + EXPECT_EQ(v.f, (123 * 567 + 1u) / 2); + EXPECT_EQ(v.e, 4 + 8 + 64); +} + +TEST(FPTest, GetCachedPower) { using limits = std::numeric_limits<double>; - for (auto exp = limits::min_exponent; exp <= limits::max_exponent; ++exp) { - int dec_exp = 0; + for (auto exp = limits::min_exponent; exp <= limits::max_exponent; ++exp) { + int dec_exp = 0; auto fp = fmt::detail::get_cached_power(exp, dec_exp); bigint exact, cache(fp.f); if (dec_exp >= 0) { @@ -245,9 +245,9 @@ TEST(FPTest, GetCachedPower) { EXPECT_EQ(exact_str.size(), cache_str.size()); EXPECT_EQ(exact_str.substr(0, 16), cache_str.substr(0, 16)); } - } -} - + } +} + TEST(FPTest, DragonboxMaxK) { using fmt::detail::dragonbox::floor_log10_pow2; using float_info = fmt::detail::dragonbox::float_info<float>; @@ -261,182 +261,182 @@ TEST(FPTest, DragonboxMaxK) { double_info::significand_bits)); } -TEST(FPTest, GetRoundDirection) { +TEST(FPTest, GetRoundDirection) { using fmt::detail::get_round_direction; using fmt::detail::round_direction; - EXPECT_EQ(round_direction::down, get_round_direction(100, 50, 0)); - EXPECT_EQ(round_direction::up, get_round_direction(100, 51, 0)); - EXPECT_EQ(round_direction::down, get_round_direction(100, 40, 10)); - EXPECT_EQ(round_direction::up, get_round_direction(100, 60, 10)); - for (size_t i = 41; i < 60; ++i) - EXPECT_EQ(round_direction::unknown, get_round_direction(100, i, 10)); - uint64_t max = max_value<uint64_t>(); - EXPECT_THROW(get_round_direction(100, 100, 0), assertion_failure); - EXPECT_THROW(get_round_direction(100, 0, 100), assertion_failure); - EXPECT_THROW(get_round_direction(100, 0, 50), assertion_failure); - // Check that remainder + error doesn't overflow. - EXPECT_EQ(round_direction::up, get_round_direction(max, max - 1, 2)); - // Check that 2 * (remainder + error) doesn't overflow. - EXPECT_EQ(round_direction::unknown, - get_round_direction(max, max / 2 + 1, max / 2)); - // Check that remainder - error doesn't overflow. - EXPECT_EQ(round_direction::unknown, get_round_direction(100, 40, 41)); - // Check that 2 * (remainder - error) doesn't overflow. - EXPECT_EQ(round_direction::up, get_round_direction(max, max - 1, 1)); -} - -TEST(FPTest, FixedHandler) { + EXPECT_EQ(round_direction::down, get_round_direction(100, 50, 0)); + EXPECT_EQ(round_direction::up, get_round_direction(100, 51, 0)); + EXPECT_EQ(round_direction::down, get_round_direction(100, 40, 10)); + EXPECT_EQ(round_direction::up, get_round_direction(100, 60, 10)); + for (size_t i = 41; i < 60; ++i) + EXPECT_EQ(round_direction::unknown, get_round_direction(100, i, 10)); + uint64_t max = max_value<uint64_t>(); + EXPECT_THROW(get_round_direction(100, 100, 0), assertion_failure); + EXPECT_THROW(get_round_direction(100, 0, 100), assertion_failure); + EXPECT_THROW(get_round_direction(100, 0, 50), assertion_failure); + // Check that remainder + error doesn't overflow. + EXPECT_EQ(round_direction::up, get_round_direction(max, max - 1, 2)); + // Check that 2 * (remainder + error) doesn't overflow. + EXPECT_EQ(round_direction::unknown, + get_round_direction(max, max / 2 + 1, max / 2)); + // Check that remainder - error doesn't overflow. + EXPECT_EQ(round_direction::unknown, get_round_direction(100, 40, 41)); + // Check that 2 * (remainder - error) doesn't overflow. + EXPECT_EQ(round_direction::up, get_round_direction(max, max - 1, 1)); +} + +TEST(FPTest, FixedHandler) { struct handler : fmt::detail::fixed_handler { - char buffer[10]; + char buffer[10]; handler(int prec = 0) : fmt::detail::fixed_handler() { - buf = buffer; - precision = prec; - } - }; - int exp = 0; - handler().on_digit('0', 100, 99, 0, exp, false); - EXPECT_THROW(handler().on_digit('0', 100, 100, 0, exp, false), - assertion_failure); + buf = buffer; + precision = prec; + } + }; + int exp = 0; + handler().on_digit('0', 100, 99, 0, exp, false); + EXPECT_THROW(handler().on_digit('0', 100, 100, 0, exp, false), + assertion_failure); namespace digits = fmt::detail::digits; EXPECT_EQ(handler(1).on_digit('0', 100, 10, 10, exp, false), digits::error); - // Check that divisor - error doesn't overflow. - EXPECT_EQ(handler(1).on_digit('0', 100, 10, 101, exp, false), digits::error); - // Check that 2 * error doesn't overflow. - uint64_t max = max_value<uint64_t>(); - EXPECT_EQ(handler(1).on_digit('0', max, 10, max - 1, exp, false), - digits::error); -} - -TEST(FPTest, GrisuFormatCompilesWithNonIEEEDouble) { - fmt::memory_buffer buf; + // Check that divisor - error doesn't overflow. + EXPECT_EQ(handler(1).on_digit('0', 100, 10, 101, exp, false), digits::error); + // Check that 2 * error doesn't overflow. + uint64_t max = max_value<uint64_t>(); + EXPECT_EQ(handler(1).on_digit('0', max, 10, max - 1, exp, false), + digits::error); +} + +TEST(FPTest, GrisuFormatCompilesWithNonIEEEDouble) { + fmt::memory_buffer buf; format_float(0.42, -1, fmt::detail::float_specs(), buf); -} - -template <typename T> struct value_extractor { - T operator()(T value) { return value; } - - template <typename U> FMT_NORETURN T operator()(U) { - throw std::runtime_error(fmt::format("invalid type {}", typeid(U).name())); - } - -#if FMT_USE_INT128 - // Apple Clang does not define typeid for __int128_t and __uint128_t. +} + +template <typename T> struct value_extractor { + T operator()(T value) { return value; } + + template <typename U> FMT_NORETURN T operator()(U) { + throw std::runtime_error(fmt::format("invalid type {}", typeid(U).name())); + } + +#if FMT_USE_INT128 + // Apple Clang does not define typeid for __int128_t and __uint128_t. FMT_NORETURN T operator()(fmt::detail::int128_t) { - throw std::runtime_error("invalid type __int128_t"); - } - + throw std::runtime_error("invalid type __int128_t"); + } + FMT_NORETURN T operator()(fmt::detail::uint128_t) { - throw std::runtime_error("invalid type __uint128_t"); - } -#endif -}; - -TEST(FormatTest, ArgConverter) { - long long value = max_value<long long>(); + throw std::runtime_error("invalid type __uint128_t"); + } +#endif +}; + +TEST(FormatTest, ArgConverter) { + long long value = max_value<long long>(); auto arg = fmt::detail::make_arg<fmt::format_context>(value); - fmt::visit_format_arg( + fmt::visit_format_arg( fmt::detail::arg_converter<long long, fmt::format_context>(arg, 'd'), - arg); - EXPECT_EQ(value, fmt::visit_format_arg(value_extractor<long long>(), arg)); -} - -TEST(FormatTest, StrError) { - char* message = nullptr; - char buffer[BUFFER_SIZE]; + arg); + EXPECT_EQ(value, fmt::visit_format_arg(value_extractor<long long>(), arg)); +} + +TEST(FormatTest, StrError) { + char* message = nullptr; + char buffer[BUFFER_SIZE]; EXPECT_ASSERT(fmt::detail::safe_strerror(EDOM, message = nullptr, 0), - "invalid buffer"); + "invalid buffer"); EXPECT_ASSERT(fmt::detail::safe_strerror(EDOM, message = buffer, 0), - "invalid buffer"); - buffer[0] = 'x'; -#if defined(_GNU_SOURCE) && !defined(__COVERITY__) - // Use invalid error code to make sure that safe_strerror returns an error - // message in the buffer rather than a pointer to a static string. - int error_code = -1; -#else - int error_code = EDOM; -#endif - - int result = + "invalid buffer"); + buffer[0] = 'x'; +#if defined(_GNU_SOURCE) && !defined(__COVERITY__) + // Use invalid error code to make sure that safe_strerror returns an error + // message in the buffer rather than a pointer to a static string. + int error_code = -1; +#else + int error_code = EDOM; +#endif + + int result = fmt::detail::safe_strerror(error_code, message = buffer, BUFFER_SIZE); - EXPECT_EQ(result, 0); + EXPECT_EQ(result, 0); size_t message_size = std::strlen(message); - EXPECT_GE(BUFFER_SIZE - 1u, message_size); - EXPECT_EQ(get_system_error(error_code), message); - - // safe_strerror never uses buffer on MinGW. -#if !defined(__MINGW32__) && !defined(__sun) - result = + EXPECT_GE(BUFFER_SIZE - 1u, message_size); + EXPECT_EQ(get_system_error(error_code), message); + + // safe_strerror never uses buffer on MinGW. +#if !defined(__MINGW32__) && !defined(__sun) + result = fmt::detail::safe_strerror(error_code, message = buffer, message_size); - EXPECT_EQ(ERANGE, result); + EXPECT_EQ(ERANGE, result); result = fmt::detail::safe_strerror(error_code, message = buffer, 1); - EXPECT_EQ(buffer, message); // Message should point to buffer. - EXPECT_EQ(ERANGE, result); - EXPECT_STREQ("", message); -#endif -} - -TEST(FormatTest, FormatErrorCode) { - std::string msg = "error 42", sep = ": "; - { - fmt::memory_buffer buffer; - format_to(buffer, "garbage"); + EXPECT_EQ(buffer, message); // Message should point to buffer. + EXPECT_EQ(ERANGE, result); + EXPECT_STREQ("", message); +#endif +} + +TEST(FormatTest, FormatErrorCode) { + std::string msg = "error 42", sep = ": "; + { + fmt::memory_buffer buffer; + format_to(buffer, "garbage"); fmt::detail::format_error_code(buffer, 42, "test"); - EXPECT_EQ("test: " + msg, to_string(buffer)); - } - { - fmt::memory_buffer buffer; - std::string prefix(fmt::inline_buffer_size - msg.size() - sep.size() + 1, - 'x'); + EXPECT_EQ("test: " + msg, to_string(buffer)); + } + { + fmt::memory_buffer buffer; + std::string prefix(fmt::inline_buffer_size - msg.size() - sep.size() + 1, + 'x'); fmt::detail::format_error_code(buffer, 42, prefix); - EXPECT_EQ(msg, to_string(buffer)); - } - int codes[] = {42, -1}; + EXPECT_EQ(msg, to_string(buffer)); + } + int codes[] = {42, -1}; for (size_t i = 0, n = sizeof(codes) / sizeof(*codes); i < n; ++i) { - // Test maximum buffer size. - msg = fmt::format("error {}", codes[i]); - fmt::memory_buffer buffer; - std::string prefix(fmt::inline_buffer_size - msg.size() - sep.size(), 'x'); + // Test maximum buffer size. + msg = fmt::format("error {}", codes[i]); + fmt::memory_buffer buffer; + std::string prefix(fmt::inline_buffer_size - msg.size() - sep.size(), 'x'); fmt::detail::format_error_code(buffer, codes[i], prefix); - EXPECT_EQ(prefix + sep + msg, to_string(buffer)); + EXPECT_EQ(prefix + sep + msg, to_string(buffer)); size_t size = fmt::inline_buffer_size; - EXPECT_EQ(size, buffer.size()); - buffer.resize(0); - // Test with a message that doesn't fit into the buffer. - prefix += 'x'; + EXPECT_EQ(size, buffer.size()); + buffer.resize(0); + // Test with a message that doesn't fit into the buffer. + prefix += 'x'; fmt::detail::format_error_code(buffer, codes[i], prefix); - EXPECT_EQ(msg, to_string(buffer)); - } -} - -TEST(FormatTest, CountCodePoints) { + EXPECT_EQ(msg, to_string(buffer)); + } +} + +TEST(FormatTest, CountCodePoints) { EXPECT_EQ(4, fmt::detail::count_code_points( fmt::basic_string_view<fmt::detail::char8_type>( reinterpret_cast<const fmt::detail::char8_type*>("ёжик")))); -} - +} + // Tests fmt::detail::count_digits for integer type Int. -template <typename Int> void test_count_digits() { +template <typename Int> void test_count_digits() { for (Int i = 0; i < 10; ++i) EXPECT_EQ(1u, fmt::detail::count_digits(i)); - for (Int i = 1, n = 1, end = max_value<Int>() / 10; n <= end; ++i) { - n *= 10; + for (Int i = 1, n = 1, end = max_value<Int>() / 10; n <= end; ++i) { + n *= 10; EXPECT_EQ(i, fmt::detail::count_digits(n - 1)); EXPECT_EQ(i + 1, fmt::detail::count_digits(n)); - } -} - -TEST(UtilTest, CountDigits) { - test_count_digits<uint32_t>(); - test_count_digits<uint64_t>(); -} - + } +} + +TEST(UtilTest, CountDigits) { + test_count_digits<uint32_t>(); + test_count_digits<uint64_t>(); +} + TEST(UtilTest, WriteFallbackUIntPtr) { std::string s; fmt::detail::write_ptr<char>( std::back_inserter(s), fmt::detail::fallback_uintptr(reinterpret_cast<void*>(0xface)), nullptr); EXPECT_EQ(s, "0xface"); -} +} #ifdef _WIN32 TEST(UtilTest, WriteConsoleSignature) { diff --git a/contrib/libs/fmt/test/format-impl-test/ya.make b/contrib/libs/fmt/test/format-impl-test/ya.make index 74364407b5..f8612f4120 100644 --- a/contrib/libs/fmt/test/format-impl-test/ya.make +++ b/contrib/libs/fmt/test/format-impl-test/ya.make @@ -1,37 +1,37 @@ -# Generated by devtools/yamaker. - +# Generated by devtools/yamaker. + GTEST() - + WITHOUT_LICENSE_TEXTS() - + OWNER( orivej g:cpp-contrib ) -LICENSE(MIT) - -PEERDIR( - contrib/libs/fmt - contrib/libs/fmt/test -) - -NO_COMPILER_WARNINGS() - -NO_UTIL() - -CFLAGS( - -DFMT_LOCALE - -DFMT_SHARED - -DGTEST_HAS_STD_WSTRING=1 - -DGTEST_LANG_CXX11=0 - -D_SILENCE_TR1_NAMESPACE_DEPRECATION_WARNING=1 -) - -SRCDIR(contrib/libs/fmt/test) - -SRCS( - format-impl-test.cc -) - -END() +LICENSE(MIT) + +PEERDIR( + contrib/libs/fmt + contrib/libs/fmt/test +) + +NO_COMPILER_WARNINGS() + +NO_UTIL() + +CFLAGS( + -DFMT_LOCALE + -DFMT_SHARED + -DGTEST_HAS_STD_WSTRING=1 + -DGTEST_LANG_CXX11=0 + -D_SILENCE_TR1_NAMESPACE_DEPRECATION_WARNING=1 +) + +SRCDIR(contrib/libs/fmt/test) + +SRCS( + format-impl-test.cc +) + +END() diff --git a/contrib/libs/fmt/test/format-test.cc b/contrib/libs/fmt/test/format-test.cc index 9acae430c3..6164ad60d6 100644 --- a/contrib/libs/fmt/test/format-test.cc +++ b/contrib/libs/fmt/test/format-test.cc @@ -1,178 +1,178 @@ -// Formatting library for C++ - formatting library tests -// -// Copyright (c) 2012 - present, Victor Zverovich -// All rights reserved. -// -// For the license information refer to format.h. - -#include <stdint.h> - -#include <cctype> -#include <cfloat> -#include <climits> -#include <cmath> -#include <cstring> -#include <list> -#include <memory> -#include <string> - -// Check if fmt/format.h compiles with windows.h included before it. -#ifdef _WIN32 -# include <windows.h> -#endif - -// Check if fmt/format.h compiles with the X11 index macro defined. -#define index(x, y) no nice things - -#include "fmt/format.h" - -#undef index - -#include <gmock/gmock.h> -#include "gtest-extra.h" -#include "mock-allocator.h" -#include "util.h" - -#undef ERROR - -using fmt::basic_memory_buffer; -using fmt::format; -using fmt::format_error; -using fmt::memory_buffer; -using fmt::string_view; -using fmt::wmemory_buffer; -using fmt::wstring_view; +// Formatting library for C++ - formatting library tests +// +// Copyright (c) 2012 - present, Victor Zverovich +// All rights reserved. +// +// For the license information refer to format.h. + +#include <stdint.h> + +#include <cctype> +#include <cfloat> +#include <climits> +#include <cmath> +#include <cstring> +#include <list> +#include <memory> +#include <string> + +// Check if fmt/format.h compiles with windows.h included before it. +#ifdef _WIN32 +# include <windows.h> +#endif + +// Check if fmt/format.h compiles with the X11 index macro defined. +#define index(x, y) no nice things + +#include "fmt/format.h" + +#undef index + +#include <gmock/gmock.h> +#include "gtest-extra.h" +#include "mock-allocator.h" +#include "util.h" + +#undef ERROR + +using fmt::basic_memory_buffer; +using fmt::format; +using fmt::format_error; +using fmt::memory_buffer; +using fmt::string_view; +using fmt::wmemory_buffer; +using fmt::wstring_view; using fmt::detail::max_value; - -using testing::Return; -using testing::StrictMock; - -namespace { - -#if !FMT_GCC_VERSION || FMT_GCC_VERSION >= 408 -template <typename Char, typename T> bool check_enabled_formatter() { - static_assert(std::is_default_constructible<fmt::formatter<T, Char>>::value, - ""); - return true; -} - -template <typename Char, typename... T> void check_enabled_formatters() { - auto dummy = {check_enabled_formatter<Char, T>()...}; - (void)dummy; -} - -TEST(FormatterTest, TestFormattersEnabled) { - check_enabled_formatters<char, bool, char, signed char, unsigned char, short, - unsigned short, int, unsigned, long, unsigned long, - long long, unsigned long long, float, double, - long double, void*, const void*, char*, const char*, - std::string, std::nullptr_t>(); - check_enabled_formatters<wchar_t, bool, wchar_t, signed char, unsigned char, - short, unsigned short, int, unsigned, long, - unsigned long, long long, unsigned long long, float, - double, long double, void*, const void*, wchar_t*, - const wchar_t*, std::wstring, std::nullptr_t>(); -} -#endif - -// Format value using the standard library. -template <typename Char, typename T> -void std_format(const T& value, std::basic_string<Char>& result) { - std::basic_ostringstream<Char> os; - os << value; - result = os.str(); -} - -#ifdef __MINGW32__ -// Workaround a bug in formatting long double in MinGW. -void std_format(long double value, std::string& result) { - char buffer[100]; - safe_sprintf(buffer, "%Lg", value); - result = buffer; -} -void std_format(long double value, std::wstring& result) { - wchar_t buffer[100]; - swprintf(buffer, L"%Lg", value); - result = buffer; -} -#endif -} // namespace - -struct uint32_pair { - uint32_t u[2]; -}; - -TEST(UtilTest, BitCast) { + +using testing::Return; +using testing::StrictMock; + +namespace { + +#if !FMT_GCC_VERSION || FMT_GCC_VERSION >= 408 +template <typename Char, typename T> bool check_enabled_formatter() { + static_assert(std::is_default_constructible<fmt::formatter<T, Char>>::value, + ""); + return true; +} + +template <typename Char, typename... T> void check_enabled_formatters() { + auto dummy = {check_enabled_formatter<Char, T>()...}; + (void)dummy; +} + +TEST(FormatterTest, TestFormattersEnabled) { + check_enabled_formatters<char, bool, char, signed char, unsigned char, short, + unsigned short, int, unsigned, long, unsigned long, + long long, unsigned long long, float, double, + long double, void*, const void*, char*, const char*, + std::string, std::nullptr_t>(); + check_enabled_formatters<wchar_t, bool, wchar_t, signed char, unsigned char, + short, unsigned short, int, unsigned, long, + unsigned long, long long, unsigned long long, float, + double, long double, void*, const void*, wchar_t*, + const wchar_t*, std::wstring, std::nullptr_t>(); +} +#endif + +// Format value using the standard library. +template <typename Char, typename T> +void std_format(const T& value, std::basic_string<Char>& result) { + std::basic_ostringstream<Char> os; + os << value; + result = os.str(); +} + +#ifdef __MINGW32__ +// Workaround a bug in formatting long double in MinGW. +void std_format(long double value, std::string& result) { + char buffer[100]; + safe_sprintf(buffer, "%Lg", value); + result = buffer; +} +void std_format(long double value, std::wstring& result) { + wchar_t buffer[100]; + swprintf(buffer, L"%Lg", value); + result = buffer; +} +#endif +} // namespace + +struct uint32_pair { + uint32_t u[2]; +}; + +TEST(UtilTest, BitCast) { auto s = fmt::detail::bit_cast<uint32_pair>(uint64_t{42}); EXPECT_EQ(fmt::detail::bit_cast<uint64_t>(s), 42ull); s = fmt::detail::bit_cast<uint32_pair>(uint64_t(~0ull)); EXPECT_EQ(fmt::detail::bit_cast<uint64_t>(s), ~0ull); -} - -TEST(UtilTest, Increment) { - char s[10] = "123"; - increment(s); - EXPECT_STREQ("124", s); - s[2] = '8'; - increment(s); - EXPECT_STREQ("129", s); - increment(s); - EXPECT_STREQ("130", s); - s[1] = s[2] = '9'; - increment(s); - EXPECT_STREQ("200", s); -} - -TEST(UtilTest, ParseNonnegativeInt) { - if (max_value<int>() != static_cast<int>(static_cast<unsigned>(1) << 31)) { - fmt::print("Skipping parse_nonnegative_int test\n"); - return; - } - fmt::string_view s = "10000000000"; - auto begin = s.begin(), end = s.end(); - EXPECT_THROW_MSG( +} + +TEST(UtilTest, Increment) { + char s[10] = "123"; + increment(s); + EXPECT_STREQ("124", s); + s[2] = '8'; + increment(s); + EXPECT_STREQ("129", s); + increment(s); + EXPECT_STREQ("130", s); + s[1] = s[2] = '9'; + increment(s); + EXPECT_STREQ("200", s); +} + +TEST(UtilTest, ParseNonnegativeInt) { + if (max_value<int>() != static_cast<int>(static_cast<unsigned>(1) << 31)) { + fmt::print("Skipping parse_nonnegative_int test\n"); + return; + } + fmt::string_view s = "10000000000"; + auto begin = s.begin(), end = s.end(); + EXPECT_THROW_MSG( parse_nonnegative_int(begin, end, fmt::detail::error_handler()), - fmt::format_error, "number is too big"); - s = "2147483649"; - begin = s.begin(); - end = s.end(); - EXPECT_THROW_MSG( + fmt::format_error, "number is too big"); + s = "2147483649"; + begin = s.begin(); + end = s.end(); + EXPECT_THROW_MSG( parse_nonnegative_int(begin, end, fmt::detail::error_handler()), - fmt::format_error, "number is too big"); -} - -TEST(IteratorTest, CountingIterator) { + fmt::format_error, "number is too big"); +} + +TEST(IteratorTest, CountingIterator) { fmt::detail::counting_iterator it; - auto prev = it++; - EXPECT_EQ(prev.count(), 0); - EXPECT_EQ(it.count(), 1); + auto prev = it++; + EXPECT_EQ(prev.count(), 0); + EXPECT_EQ(it.count(), 1); EXPECT_EQ((it + 41).count(), 42); -} - -TEST(IteratorTest, TruncatingIterator) { - char* p = nullptr; +} + +TEST(IteratorTest, TruncatingIterator) { + char* p = nullptr; fmt::detail::truncating_iterator<char*> it(p, 3); - auto prev = it++; - EXPECT_EQ(prev.base(), p); - EXPECT_EQ(it.base(), p + 1); -} - -TEST(IteratorTest, TruncatingBackInserter) { - std::string buffer; - auto bi = std::back_inserter(buffer); + auto prev = it++; + EXPECT_EQ(prev.base(), p); + EXPECT_EQ(it.base(), p + 1); +} + +TEST(IteratorTest, TruncatingBackInserter) { + std::string buffer; + auto bi = std::back_inserter(buffer); fmt::detail::truncating_iterator<decltype(bi)> it(bi, 2); - *it++ = '4'; - *it++ = '2'; - *it++ = '1'; - EXPECT_EQ(buffer.size(), 2); - EXPECT_EQ(buffer, "42"); -} - -TEST(IteratorTest, IsOutputIterator) { + *it++ = '4'; + *it++ = '2'; + *it++ = '1'; + EXPECT_EQ(buffer.size(), 2); + EXPECT_EQ(buffer, "42"); +} + +TEST(IteratorTest, IsOutputIterator) { EXPECT_TRUE((fmt::detail::is_output_iterator<char*, char>::value)); EXPECT_FALSE((fmt::detail::is_output_iterator<const char*, char>::value)); EXPECT_FALSE((fmt::detail::is_output_iterator<std::string, char>::value)); - EXPECT_TRUE( + EXPECT_TRUE( (fmt::detail::is_output_iterator<std::back_insert_iterator<std::string>, char>::value)); EXPECT_TRUE( @@ -185,1106 +185,1106 @@ TEST(IteratorTest, IsOutputIterator) { EXPECT_FALSE((fmt::detail::is_output_iterator<std::list<char>::const_iterator, char>::value)); EXPECT_FALSE((fmt::detail::is_output_iterator<uint32_pair, char>::value)); -} - -TEST(MemoryBufferTest, Ctor) { - basic_memory_buffer<char, 123> buffer; - EXPECT_EQ(static_cast<size_t>(0), buffer.size()); - EXPECT_EQ(123u, buffer.capacity()); -} - -static void check_forwarding(mock_allocator<int>& alloc, - allocator_ref<mock_allocator<int>>& ref) { - int mem; - // Check if value_type is properly defined. - allocator_ref<mock_allocator<int>>::value_type* ptr = &mem; - // Check forwarding. - EXPECT_CALL(alloc, allocate(42)).WillOnce(testing::Return(ptr)); - ref.allocate(42); - EXPECT_CALL(alloc, deallocate(ptr, 42)); - ref.deallocate(ptr, 42); -} - -TEST(AllocatorTest, allocator_ref) { - StrictMock<mock_allocator<int>> alloc; - typedef allocator_ref<mock_allocator<int>> test_allocator_ref; - test_allocator_ref ref(&alloc); - // Check if allocator_ref forwards to the underlying allocator. - check_forwarding(alloc, ref); - test_allocator_ref ref2(ref); - check_forwarding(alloc, ref2); - test_allocator_ref ref3; - EXPECT_EQ(nullptr, ref3.get()); - ref3 = ref; - check_forwarding(alloc, ref3); -} - -typedef allocator_ref<std::allocator<char>> TestAllocator; - -static void check_move_buffer( - const char* str, basic_memory_buffer<char, 5, TestAllocator>& buffer) { - std::allocator<char>* alloc = buffer.get_allocator().get(); - basic_memory_buffer<char, 5, TestAllocator> buffer2(std::move(buffer)); - // Move shouldn't destroy the inline content of the first buffer. - EXPECT_EQ(str, std::string(&buffer[0], buffer.size())); - EXPECT_EQ(str, std::string(&buffer2[0], buffer2.size())); - EXPECT_EQ(5u, buffer2.capacity()); - // Move should transfer allocator. - EXPECT_EQ(nullptr, buffer.get_allocator().get()); - EXPECT_EQ(alloc, buffer2.get_allocator().get()); -} - -TEST(MemoryBufferTest, MoveCtorInlineBuffer) { - std::allocator<char> alloc; - basic_memory_buffer<char, 5, TestAllocator> buffer((TestAllocator(&alloc))); - const char test[] = "test"; +} + +TEST(MemoryBufferTest, Ctor) { + basic_memory_buffer<char, 123> buffer; + EXPECT_EQ(static_cast<size_t>(0), buffer.size()); + EXPECT_EQ(123u, buffer.capacity()); +} + +static void check_forwarding(mock_allocator<int>& alloc, + allocator_ref<mock_allocator<int>>& ref) { + int mem; + // Check if value_type is properly defined. + allocator_ref<mock_allocator<int>>::value_type* ptr = &mem; + // Check forwarding. + EXPECT_CALL(alloc, allocate(42)).WillOnce(testing::Return(ptr)); + ref.allocate(42); + EXPECT_CALL(alloc, deallocate(ptr, 42)); + ref.deallocate(ptr, 42); +} + +TEST(AllocatorTest, allocator_ref) { + StrictMock<mock_allocator<int>> alloc; + typedef allocator_ref<mock_allocator<int>> test_allocator_ref; + test_allocator_ref ref(&alloc); + // Check if allocator_ref forwards to the underlying allocator. + check_forwarding(alloc, ref); + test_allocator_ref ref2(ref); + check_forwarding(alloc, ref2); + test_allocator_ref ref3; + EXPECT_EQ(nullptr, ref3.get()); + ref3 = ref; + check_forwarding(alloc, ref3); +} + +typedef allocator_ref<std::allocator<char>> TestAllocator; + +static void check_move_buffer( + const char* str, basic_memory_buffer<char, 5, TestAllocator>& buffer) { + std::allocator<char>* alloc = buffer.get_allocator().get(); + basic_memory_buffer<char, 5, TestAllocator> buffer2(std::move(buffer)); + // Move shouldn't destroy the inline content of the first buffer. + EXPECT_EQ(str, std::string(&buffer[0], buffer.size())); + EXPECT_EQ(str, std::string(&buffer2[0], buffer2.size())); + EXPECT_EQ(5u, buffer2.capacity()); + // Move should transfer allocator. + EXPECT_EQ(nullptr, buffer.get_allocator().get()); + EXPECT_EQ(alloc, buffer2.get_allocator().get()); +} + +TEST(MemoryBufferTest, MoveCtorInlineBuffer) { + std::allocator<char> alloc; + basic_memory_buffer<char, 5, TestAllocator> buffer((TestAllocator(&alloc))); + const char test[] = "test"; buffer.append(string_view(test, 4)); - check_move_buffer("test", buffer); - // Adding one more character fills the inline buffer, but doesn't cause - // dynamic allocation. - buffer.push_back('a'); - check_move_buffer("testa", buffer); -} - -TEST(MemoryBufferTest, MoveCtorDynamicBuffer) { - std::allocator<char> alloc; - basic_memory_buffer<char, 4, TestAllocator> buffer((TestAllocator(&alloc))); - const char test[] = "test"; - buffer.append(test, test + 4); - const char* inline_buffer_ptr = &buffer[0]; - // Adding one more character causes the content to move from the inline to - // a dynamically allocated buffer. - buffer.push_back('a'); - basic_memory_buffer<char, 4, TestAllocator> buffer2(std::move(buffer)); - // Move should rip the guts of the first buffer. - EXPECT_EQ(inline_buffer_ptr, &buffer[0]); - EXPECT_EQ("testa", std::string(&buffer2[0], buffer2.size())); - EXPECT_GT(buffer2.capacity(), 4u); -} - -static void check_move_assign_buffer(const char* str, - basic_memory_buffer<char, 5>& buffer) { - basic_memory_buffer<char, 5> buffer2; - buffer2 = std::move(buffer); - // Move shouldn't destroy the inline content of the first buffer. - EXPECT_EQ(str, std::string(&buffer[0], buffer.size())); - EXPECT_EQ(str, std::string(&buffer2[0], buffer2.size())); - EXPECT_EQ(5u, buffer2.capacity()); -} - -TEST(MemoryBufferTest, MoveAssignment) { - basic_memory_buffer<char, 5> buffer; - const char test[] = "test"; - buffer.append(test, test + 4); - check_move_assign_buffer("test", buffer); - // Adding one more character fills the inline buffer, but doesn't cause - // dynamic allocation. - buffer.push_back('a'); - check_move_assign_buffer("testa", buffer); - const char* inline_buffer_ptr = &buffer[0]; - // Adding one more character causes the content to move from the inline to - // a dynamically allocated buffer. - buffer.push_back('b'); - basic_memory_buffer<char, 5> buffer2; - buffer2 = std::move(buffer); - // Move should rip the guts of the first buffer. - EXPECT_EQ(inline_buffer_ptr, &buffer[0]); - EXPECT_EQ("testab", std::string(&buffer2[0], buffer2.size())); - EXPECT_GT(buffer2.capacity(), 5u); -} - -TEST(MemoryBufferTest, Grow) { - typedef allocator_ref<mock_allocator<int>> Allocator; - mock_allocator<int> alloc; + check_move_buffer("test", buffer); + // Adding one more character fills the inline buffer, but doesn't cause + // dynamic allocation. + buffer.push_back('a'); + check_move_buffer("testa", buffer); +} + +TEST(MemoryBufferTest, MoveCtorDynamicBuffer) { + std::allocator<char> alloc; + basic_memory_buffer<char, 4, TestAllocator> buffer((TestAllocator(&alloc))); + const char test[] = "test"; + buffer.append(test, test + 4); + const char* inline_buffer_ptr = &buffer[0]; + // Adding one more character causes the content to move from the inline to + // a dynamically allocated buffer. + buffer.push_back('a'); + basic_memory_buffer<char, 4, TestAllocator> buffer2(std::move(buffer)); + // Move should rip the guts of the first buffer. + EXPECT_EQ(inline_buffer_ptr, &buffer[0]); + EXPECT_EQ("testa", std::string(&buffer2[0], buffer2.size())); + EXPECT_GT(buffer2.capacity(), 4u); +} + +static void check_move_assign_buffer(const char* str, + basic_memory_buffer<char, 5>& buffer) { + basic_memory_buffer<char, 5> buffer2; + buffer2 = std::move(buffer); + // Move shouldn't destroy the inline content of the first buffer. + EXPECT_EQ(str, std::string(&buffer[0], buffer.size())); + EXPECT_EQ(str, std::string(&buffer2[0], buffer2.size())); + EXPECT_EQ(5u, buffer2.capacity()); +} + +TEST(MemoryBufferTest, MoveAssignment) { + basic_memory_buffer<char, 5> buffer; + const char test[] = "test"; + buffer.append(test, test + 4); + check_move_assign_buffer("test", buffer); + // Adding one more character fills the inline buffer, but doesn't cause + // dynamic allocation. + buffer.push_back('a'); + check_move_assign_buffer("testa", buffer); + const char* inline_buffer_ptr = &buffer[0]; + // Adding one more character causes the content to move from the inline to + // a dynamically allocated buffer. + buffer.push_back('b'); + basic_memory_buffer<char, 5> buffer2; + buffer2 = std::move(buffer); + // Move should rip the guts of the first buffer. + EXPECT_EQ(inline_buffer_ptr, &buffer[0]); + EXPECT_EQ("testab", std::string(&buffer2[0], buffer2.size())); + EXPECT_GT(buffer2.capacity(), 5u); +} + +TEST(MemoryBufferTest, Grow) { + typedef allocator_ref<mock_allocator<int>> Allocator; + mock_allocator<int> alloc; basic_memory_buffer<int, 10, Allocator> buffer((Allocator(&alloc))); - buffer.resize(7); + buffer.resize(7); using fmt::detail::to_unsigned; - for (int i = 0; i < 7; ++i) buffer[to_unsigned(i)] = i * i; - EXPECT_EQ(10u, buffer.capacity()); - int mem[20]; - mem[7] = 0xdead; - EXPECT_CALL(alloc, allocate(20)).WillOnce(Return(mem)); + for (int i = 0; i < 7; ++i) buffer[to_unsigned(i)] = i * i; + EXPECT_EQ(10u, buffer.capacity()); + int mem[20]; + mem[7] = 0xdead; + EXPECT_CALL(alloc, allocate(20)).WillOnce(Return(mem)); buffer.try_reserve(20); - EXPECT_EQ(20u, buffer.capacity()); - // Check if size elements have been copied - for (int i = 0; i < 7; ++i) EXPECT_EQ(i * i, buffer[to_unsigned(i)]); - // and no more than that. - EXPECT_EQ(0xdead, buffer[7]); - EXPECT_CALL(alloc, deallocate(mem, 20)); -} - -TEST(MemoryBufferTest, Allocator) { - typedef allocator_ref<mock_allocator<char>> TestAllocator; - basic_memory_buffer<char, 10, TestAllocator> buffer; - EXPECT_EQ(nullptr, buffer.get_allocator().get()); - StrictMock<mock_allocator<char>> alloc; - char mem; - { - basic_memory_buffer<char, 10, TestAllocator> buffer2( - (TestAllocator(&alloc))); - EXPECT_EQ(&alloc, buffer2.get_allocator().get()); + EXPECT_EQ(20u, buffer.capacity()); + // Check if size elements have been copied + for (int i = 0; i < 7; ++i) EXPECT_EQ(i * i, buffer[to_unsigned(i)]); + // and no more than that. + EXPECT_EQ(0xdead, buffer[7]); + EXPECT_CALL(alloc, deallocate(mem, 20)); +} + +TEST(MemoryBufferTest, Allocator) { + typedef allocator_ref<mock_allocator<char>> TestAllocator; + basic_memory_buffer<char, 10, TestAllocator> buffer; + EXPECT_EQ(nullptr, buffer.get_allocator().get()); + StrictMock<mock_allocator<char>> alloc; + char mem; + { + basic_memory_buffer<char, 10, TestAllocator> buffer2( + (TestAllocator(&alloc))); + EXPECT_EQ(&alloc, buffer2.get_allocator().get()); size_t size = 2 * fmt::inline_buffer_size; - EXPECT_CALL(alloc, allocate(size)).WillOnce(Return(&mem)); - buffer2.reserve(size); - EXPECT_CALL(alloc, deallocate(&mem, size)); - } -} - -TEST(MemoryBufferTest, ExceptionInDeallocate) { - typedef allocator_ref<mock_allocator<char>> TestAllocator; - StrictMock<mock_allocator<char>> alloc; - basic_memory_buffer<char, 10, TestAllocator> buffer((TestAllocator(&alloc))); + EXPECT_CALL(alloc, allocate(size)).WillOnce(Return(&mem)); + buffer2.reserve(size); + EXPECT_CALL(alloc, deallocate(&mem, size)); + } +} + +TEST(MemoryBufferTest, ExceptionInDeallocate) { + typedef allocator_ref<mock_allocator<char>> TestAllocator; + StrictMock<mock_allocator<char>> alloc; + basic_memory_buffer<char, 10, TestAllocator> buffer((TestAllocator(&alloc))); size_t size = 2 * fmt::inline_buffer_size; - std::vector<char> mem(size); - { - EXPECT_CALL(alloc, allocate(size)).WillOnce(Return(&mem[0])); - buffer.resize(size); - std::fill(&buffer[0], &buffer[0] + size, 'x'); - } - std::vector<char> mem2(2 * size); - { - EXPECT_CALL(alloc, allocate(2 * size)).WillOnce(Return(&mem2[0])); - std::exception e; - EXPECT_CALL(alloc, deallocate(&mem[0], size)).WillOnce(testing::Throw(e)); - EXPECT_THROW(buffer.reserve(2 * size), std::exception); - EXPECT_EQ(&mem2[0], &buffer[0]); - // Check that the data has been copied. + std::vector<char> mem(size); + { + EXPECT_CALL(alloc, allocate(size)).WillOnce(Return(&mem[0])); + buffer.resize(size); + std::fill(&buffer[0], &buffer[0] + size, 'x'); + } + std::vector<char> mem2(2 * size); + { + EXPECT_CALL(alloc, allocate(2 * size)).WillOnce(Return(&mem2[0])); + std::exception e; + EXPECT_CALL(alloc, deallocate(&mem[0], size)).WillOnce(testing::Throw(e)); + EXPECT_THROW(buffer.reserve(2 * size), std::exception); + EXPECT_EQ(&mem2[0], &buffer[0]); + // Check that the data has been copied. for (size_t i = 0; i < size; ++i) EXPECT_EQ('x', buffer[i]); - } - EXPECT_CALL(alloc, deallocate(&mem2[0], 2 * size)); -} - -TEST(UtilTest, UTF8ToUTF16) { + } + EXPECT_CALL(alloc, deallocate(&mem2[0], 2 * size)); +} + +TEST(UtilTest, UTF8ToUTF16) { fmt::detail::utf8_to_utf16 u("лошадка"); - EXPECT_EQ(L"\x043B\x043E\x0448\x0430\x0434\x043A\x0430", u.str()); - EXPECT_EQ(7, u.size()); - // U+10437 { DESERET SMALL LETTER YEE } + EXPECT_EQ(L"\x043B\x043E\x0448\x0430\x0434\x043A\x0430", u.str()); + EXPECT_EQ(7, u.size()); + // U+10437 { DESERET SMALL LETTER YEE } EXPECT_EQ(L"\xD801\xDC37", fmt::detail::utf8_to_utf16("𐐷").str()); EXPECT_THROW_MSG(fmt::detail::utf8_to_utf16("\xc3\x28"), std::runtime_error, - "invalid utf8"); + "invalid utf8"); EXPECT_THROW_MSG(fmt::detail::utf8_to_utf16(fmt::string_view("л", 1)), - std::runtime_error, "invalid utf8"); + std::runtime_error, "invalid utf8"); EXPECT_EQ(L"123456", fmt::detail::utf8_to_utf16("123456").str()); -} - -TEST(UtilTest, UTF8ToUTF16EmptyString) { - std::string s = ""; +} + +TEST(UtilTest, UTF8ToUTF16EmptyString) { + std::string s = ""; fmt::detail::utf8_to_utf16 u(s.c_str()); - EXPECT_EQ(L"", u.str()); - EXPECT_EQ(s.size(), u.size()); -} - -TEST(UtilTest, FormatSystemError) { - fmt::memory_buffer message; - fmt::format_system_error(message, EDOM, "test"); - EXPECT_EQ(fmt::format("test: {}", get_system_error(EDOM)), - to_string(message)); - message = fmt::memory_buffer(); - - // Check if std::allocator throws on allocating max size_t / 2 chars. - size_t max_size = max_value<size_t>() / 2; - bool throws_on_alloc = false; - try { - std::allocator<char> alloc; - alloc.deallocate(alloc.allocate(max_size), max_size); - } catch (const std::bad_alloc&) { - throws_on_alloc = true; - } - if (!throws_on_alloc) { - fmt::print("warning: std::allocator allocates {} chars", max_size); - return; - } - fmt::format_system_error(message, EDOM, fmt::string_view(nullptr, max_size)); - EXPECT_EQ(fmt::format("error {}", EDOM), to_string(message)); -} - -TEST(UtilTest, SystemError) { - fmt::system_error e(EDOM, "test"); - EXPECT_EQ(fmt::format("test: {}", get_system_error(EDOM)), e.what()); - EXPECT_EQ(EDOM, e.error_code()); - - fmt::system_error error(0, ""); - try { - throw fmt::system_error(EDOM, "test {}", "error"); - } catch (const fmt::system_error& e) { - error = e; - } - fmt::memory_buffer message; - fmt::format_system_error(message, EDOM, "test error"); - EXPECT_EQ(to_string(message), error.what()); - EXPECT_EQ(EDOM, error.error_code()); -} - -TEST(UtilTest, ReportSystemError) { - fmt::memory_buffer out; - fmt::format_system_error(out, EDOM, "test error"); - out.push_back('\n'); - EXPECT_WRITE(stderr, fmt::report_system_error(EDOM, "test error"), - to_string(out)); -} - -TEST(StringViewTest, Ctor) { - EXPECT_STREQ("abc", string_view("abc").data()); - EXPECT_EQ(3u, string_view("abc").size()); - - EXPECT_STREQ("defg", string_view(std::string("defg")).data()); - EXPECT_EQ(4u, string_view(std::string("defg")).size()); -} - -TEST(FormatToTest, FormatWithoutArgs) { - std::string s; - fmt::format_to(std::back_inserter(s), "test"); - EXPECT_EQ("test", s); -} - -TEST(FormatToTest, Format) { - std::string s; - fmt::format_to(std::back_inserter(s), "part{0}", 1); - EXPECT_EQ("part1", s); - fmt::format_to(std::back_inserter(s), "part{0}", 2); - EXPECT_EQ("part1part2", s); -} - -TEST(FormatToTest, WideString) { - std::vector<wchar_t> buf; - fmt::format_to(std::back_inserter(buf), L"{}{}", 42, L'\0'); - EXPECT_STREQ(buf.data(), L"42"); -} - -TEST(FormatToTest, FormatToMemoryBuffer) { - fmt::basic_memory_buffer<char, 100> buffer; - fmt::format_to(buffer, "{}", "foo"); - EXPECT_EQ("foo", to_string(buffer)); - fmt::wmemory_buffer wbuffer; - fmt::format_to(wbuffer, L"{}", L"foo"); - EXPECT_EQ(L"foo", to_string(wbuffer)); -} - -TEST(FormatterTest, Escape) { - EXPECT_EQ("{", format("{{")); - EXPECT_EQ("before {", format("before {{")); - EXPECT_EQ("{ after", format("{{ after")); - EXPECT_EQ("before { after", format("before {{ after")); - - EXPECT_EQ("}", format("}}")); - EXPECT_EQ("before }", format("before }}")); - EXPECT_EQ("} after", format("}} after")); - EXPECT_EQ("before } after", format("before }} after")); - - EXPECT_EQ("{}", format("{{}}")); - EXPECT_EQ("{42}", format("{{{0}}}", 42)); -} - -TEST(FormatterTest, UnmatchedBraces) { - EXPECT_THROW_MSG(format("{"), format_error, "invalid format string"); - EXPECT_THROW_MSG(format("}"), format_error, "unmatched '}' in format string"); - EXPECT_THROW_MSG(format("{0{}"), format_error, "invalid format string"); -} - -TEST(FormatterTest, NoArgs) { EXPECT_EQ("test", format("test")); } - -TEST(FormatterTest, ArgsInDifferentPositions) { - EXPECT_EQ("42", format("{0}", 42)); - EXPECT_EQ("before 42", format("before {0}", 42)); - EXPECT_EQ("42 after", format("{0} after", 42)); - EXPECT_EQ("before 42 after", format("before {0} after", 42)); - EXPECT_EQ("answer = 42", format("{0} = {1}", "answer", 42)); - EXPECT_EQ("42 is the answer", format("{1} is the {0}", "answer", 42)); - EXPECT_EQ("abracadabra", format("{0}{1}{0}", "abra", "cad")); -} - -TEST(FormatterTest, ArgErrors) { - EXPECT_THROW_MSG(format("{"), format_error, "invalid format string"); - EXPECT_THROW_MSG(format("{?}"), format_error, "invalid format string"); - EXPECT_THROW_MSG(format("{0"), format_error, "invalid format string"); + EXPECT_EQ(L"", u.str()); + EXPECT_EQ(s.size(), u.size()); +} + +TEST(UtilTest, FormatSystemError) { + fmt::memory_buffer message; + fmt::format_system_error(message, EDOM, "test"); + EXPECT_EQ(fmt::format("test: {}", get_system_error(EDOM)), + to_string(message)); + message = fmt::memory_buffer(); + + // Check if std::allocator throws on allocating max size_t / 2 chars. + size_t max_size = max_value<size_t>() / 2; + bool throws_on_alloc = false; + try { + std::allocator<char> alloc; + alloc.deallocate(alloc.allocate(max_size), max_size); + } catch (const std::bad_alloc&) { + throws_on_alloc = true; + } + if (!throws_on_alloc) { + fmt::print("warning: std::allocator allocates {} chars", max_size); + return; + } + fmt::format_system_error(message, EDOM, fmt::string_view(nullptr, max_size)); + EXPECT_EQ(fmt::format("error {}", EDOM), to_string(message)); +} + +TEST(UtilTest, SystemError) { + fmt::system_error e(EDOM, "test"); + EXPECT_EQ(fmt::format("test: {}", get_system_error(EDOM)), e.what()); + EXPECT_EQ(EDOM, e.error_code()); + + fmt::system_error error(0, ""); + try { + throw fmt::system_error(EDOM, "test {}", "error"); + } catch (const fmt::system_error& e) { + error = e; + } + fmt::memory_buffer message; + fmt::format_system_error(message, EDOM, "test error"); + EXPECT_EQ(to_string(message), error.what()); + EXPECT_EQ(EDOM, error.error_code()); +} + +TEST(UtilTest, ReportSystemError) { + fmt::memory_buffer out; + fmt::format_system_error(out, EDOM, "test error"); + out.push_back('\n'); + EXPECT_WRITE(stderr, fmt::report_system_error(EDOM, "test error"), + to_string(out)); +} + +TEST(StringViewTest, Ctor) { + EXPECT_STREQ("abc", string_view("abc").data()); + EXPECT_EQ(3u, string_view("abc").size()); + + EXPECT_STREQ("defg", string_view(std::string("defg")).data()); + EXPECT_EQ(4u, string_view(std::string("defg")).size()); +} + +TEST(FormatToTest, FormatWithoutArgs) { + std::string s; + fmt::format_to(std::back_inserter(s), "test"); + EXPECT_EQ("test", s); +} + +TEST(FormatToTest, Format) { + std::string s; + fmt::format_to(std::back_inserter(s), "part{0}", 1); + EXPECT_EQ("part1", s); + fmt::format_to(std::back_inserter(s), "part{0}", 2); + EXPECT_EQ("part1part2", s); +} + +TEST(FormatToTest, WideString) { + std::vector<wchar_t> buf; + fmt::format_to(std::back_inserter(buf), L"{}{}", 42, L'\0'); + EXPECT_STREQ(buf.data(), L"42"); +} + +TEST(FormatToTest, FormatToMemoryBuffer) { + fmt::basic_memory_buffer<char, 100> buffer; + fmt::format_to(buffer, "{}", "foo"); + EXPECT_EQ("foo", to_string(buffer)); + fmt::wmemory_buffer wbuffer; + fmt::format_to(wbuffer, L"{}", L"foo"); + EXPECT_EQ(L"foo", to_string(wbuffer)); +} + +TEST(FormatterTest, Escape) { + EXPECT_EQ("{", format("{{")); + EXPECT_EQ("before {", format("before {{")); + EXPECT_EQ("{ after", format("{{ after")); + EXPECT_EQ("before { after", format("before {{ after")); + + EXPECT_EQ("}", format("}}")); + EXPECT_EQ("before }", format("before }}")); + EXPECT_EQ("} after", format("}} after")); + EXPECT_EQ("before } after", format("before }} after")); + + EXPECT_EQ("{}", format("{{}}")); + EXPECT_EQ("{42}", format("{{{0}}}", 42)); +} + +TEST(FormatterTest, UnmatchedBraces) { + EXPECT_THROW_MSG(format("{"), format_error, "invalid format string"); + EXPECT_THROW_MSG(format("}"), format_error, "unmatched '}' in format string"); + EXPECT_THROW_MSG(format("{0{}"), format_error, "invalid format string"); +} + +TEST(FormatterTest, NoArgs) { EXPECT_EQ("test", format("test")); } + +TEST(FormatterTest, ArgsInDifferentPositions) { + EXPECT_EQ("42", format("{0}", 42)); + EXPECT_EQ("before 42", format("before {0}", 42)); + EXPECT_EQ("42 after", format("{0} after", 42)); + EXPECT_EQ("before 42 after", format("before {0} after", 42)); + EXPECT_EQ("answer = 42", format("{0} = {1}", "answer", 42)); + EXPECT_EQ("42 is the answer", format("{1} is the {0}", "answer", 42)); + EXPECT_EQ("abracadabra", format("{0}{1}{0}", "abra", "cad")); +} + +TEST(FormatterTest, ArgErrors) { + EXPECT_THROW_MSG(format("{"), format_error, "invalid format string"); + EXPECT_THROW_MSG(format("{?}"), format_error, "invalid format string"); + EXPECT_THROW_MSG(format("{0"), format_error, "invalid format string"); EXPECT_THROW_MSG(format("{0}"), format_error, "argument not found"); - EXPECT_THROW_MSG(format("{00}", 42), format_error, "invalid format string"); - - char format_str[BUFFER_SIZE]; - safe_sprintf(format_str, "{%u", INT_MAX); - EXPECT_THROW_MSG(format(format_str), format_error, "invalid format string"); - safe_sprintf(format_str, "{%u}", INT_MAX); + EXPECT_THROW_MSG(format("{00}", 42), format_error, "invalid format string"); + + char format_str[BUFFER_SIZE]; + safe_sprintf(format_str, "{%u", INT_MAX); + EXPECT_THROW_MSG(format(format_str), format_error, "invalid format string"); + safe_sprintf(format_str, "{%u}", INT_MAX); EXPECT_THROW_MSG(format(format_str), format_error, "argument not found"); - - safe_sprintf(format_str, "{%u", INT_MAX + 1u); - EXPECT_THROW_MSG(format(format_str), format_error, "number is too big"); - safe_sprintf(format_str, "{%u}", INT_MAX + 1u); - EXPECT_THROW_MSG(format(format_str), format_error, "number is too big"); -} - -template <int N> struct TestFormat { - template <typename... Args> - static std::string format(fmt::string_view format_str, const Args&... args) { - return TestFormat<N - 1>::format(format_str, N - 1, args...); - } -}; - -template <> struct TestFormat<0> { - template <typename... Args> - static std::string format(fmt::string_view format_str, const Args&... args) { - return fmt::format(format_str, args...); - } -}; - -TEST(FormatterTest, ManyArgs) { - EXPECT_EQ("19", TestFormat<20>::format("{19}")); - EXPECT_THROW_MSG(TestFormat<20>::format("{20}"), format_error, + + safe_sprintf(format_str, "{%u", INT_MAX + 1u); + EXPECT_THROW_MSG(format(format_str), format_error, "number is too big"); + safe_sprintf(format_str, "{%u}", INT_MAX + 1u); + EXPECT_THROW_MSG(format(format_str), format_error, "number is too big"); +} + +template <int N> struct TestFormat { + template <typename... Args> + static std::string format(fmt::string_view format_str, const Args&... args) { + return TestFormat<N - 1>::format(format_str, N - 1, args...); + } +}; + +template <> struct TestFormat<0> { + template <typename... Args> + static std::string format(fmt::string_view format_str, const Args&... args) { + return fmt::format(format_str, args...); + } +}; + +TEST(FormatterTest, ManyArgs) { + EXPECT_EQ("19", TestFormat<20>::format("{19}")); + EXPECT_THROW_MSG(TestFormat<20>::format("{20}"), format_error, "argument not found"); - EXPECT_THROW_MSG(TestFormat<21>::format("{21}"), format_error, + EXPECT_THROW_MSG(TestFormat<21>::format("{21}"), format_error, "argument not found"); enum { max_packed_args = fmt::detail::max_packed_args }; - std::string format_str = fmt::format("{{{}}}", max_packed_args + 1); - EXPECT_THROW_MSG(TestFormat<max_packed_args>::format(format_str), + std::string format_str = fmt::format("{{{}}}", max_packed_args + 1); + EXPECT_THROW_MSG(TestFormat<max_packed_args>::format(format_str), format_error, "argument not found"); -} - -TEST(FormatterTest, NamedArg) { - EXPECT_EQ("1/a/A", format("{_1}/{a_}/{A_}", fmt::arg("a_", 'a'), - fmt::arg("A_", "A"), fmt::arg("_1", 1))); - EXPECT_EQ(" -42", format("{0:{width}}", -42, fmt::arg("width", 4))); - EXPECT_EQ("st", format("{0:.{precision}}", "str", fmt::arg("precision", 2))); - EXPECT_EQ("1 2", format("{} {two}", 1, fmt::arg("two", 2))); - EXPECT_EQ("42", format("{c}", fmt::arg("a", 0), fmt::arg("b", 0), - fmt::arg("c", 42), fmt::arg("d", 0), fmt::arg("e", 0), - fmt::arg("f", 0), fmt::arg("g", 0), fmt::arg("h", 0), - fmt::arg("i", 0), fmt::arg("j", 0), fmt::arg("k", 0), - fmt::arg("l", 0), fmt::arg("m", 0), fmt::arg("n", 0), - fmt::arg("o", 0), fmt::arg("p", 0))); +} + +TEST(FormatterTest, NamedArg) { + EXPECT_EQ("1/a/A", format("{_1}/{a_}/{A_}", fmt::arg("a_", 'a'), + fmt::arg("A_", "A"), fmt::arg("_1", 1))); + EXPECT_EQ(" -42", format("{0:{width}}", -42, fmt::arg("width", 4))); + EXPECT_EQ("st", format("{0:.{precision}}", "str", fmt::arg("precision", 2))); + EXPECT_EQ("1 2", format("{} {two}", 1, fmt::arg("two", 2))); + EXPECT_EQ("42", format("{c}", fmt::arg("a", 0), fmt::arg("b", 0), + fmt::arg("c", 42), fmt::arg("d", 0), fmt::arg("e", 0), + fmt::arg("f", 0), fmt::arg("g", 0), fmt::arg("h", 0), + fmt::arg("i", 0), fmt::arg("j", 0), fmt::arg("k", 0), + fmt::arg("l", 0), fmt::arg("m", 0), fmt::arg("n", 0), + fmt::arg("o", 0), fmt::arg("p", 0))); EXPECT_THROW_MSG(format("{a}"), format_error, "argument not found"); EXPECT_THROW_MSG(format("{a}", 42), format_error, "argument not found"); -} - -TEST(FormatterTest, AutoArgIndex) { - EXPECT_EQ("abc", format("{}{}{}", 'a', 'b', 'c')); - EXPECT_THROW_MSG(format("{0}{}", 'a', 'b'), format_error, - "cannot switch from manual to automatic argument indexing"); - EXPECT_THROW_MSG(format("{}{0}", 'a', 'b'), format_error, - "cannot switch from automatic to manual argument indexing"); - EXPECT_EQ("1.2", format("{:.{}}", 1.2345, 2)); - EXPECT_THROW_MSG(format("{0}:.{}", 1.2345, 2), format_error, - "cannot switch from manual to automatic argument indexing"); - EXPECT_THROW_MSG(format("{:.{0}}", 1.2345, 2), format_error, - "cannot switch from automatic to manual argument indexing"); +} + +TEST(FormatterTest, AutoArgIndex) { + EXPECT_EQ("abc", format("{}{}{}", 'a', 'b', 'c')); + EXPECT_THROW_MSG(format("{0}{}", 'a', 'b'), format_error, + "cannot switch from manual to automatic argument indexing"); + EXPECT_THROW_MSG(format("{}{0}", 'a', 'b'), format_error, + "cannot switch from automatic to manual argument indexing"); + EXPECT_EQ("1.2", format("{:.{}}", 1.2345, 2)); + EXPECT_THROW_MSG(format("{0}:.{}", 1.2345, 2), format_error, + "cannot switch from manual to automatic argument indexing"); + EXPECT_THROW_MSG(format("{:.{0}}", 1.2345, 2), format_error, + "cannot switch from automatic to manual argument indexing"); EXPECT_THROW_MSG(format("{}"), format_error, "argument not found"); -} - -TEST(FormatterTest, EmptySpecs) { EXPECT_EQ("42", format("{0:}", 42)); } - -TEST(FormatterTest, LeftAlign) { - EXPECT_EQ("42 ", format("{0:<4}", 42)); - EXPECT_EQ("42 ", format("{0:<4o}", 042)); - EXPECT_EQ("42 ", format("{0:<4x}", 0x42)); - EXPECT_EQ("-42 ", format("{0:<5}", -42)); - EXPECT_EQ("42 ", format("{0:<5}", 42u)); - EXPECT_EQ("-42 ", format("{0:<5}", -42l)); - EXPECT_EQ("42 ", format("{0:<5}", 42ul)); - EXPECT_EQ("-42 ", format("{0:<5}", -42ll)); - EXPECT_EQ("42 ", format("{0:<5}", 42ull)); +} + +TEST(FormatterTest, EmptySpecs) { EXPECT_EQ("42", format("{0:}", 42)); } + +TEST(FormatterTest, LeftAlign) { + EXPECT_EQ("42 ", format("{0:<4}", 42)); + EXPECT_EQ("42 ", format("{0:<4o}", 042)); + EXPECT_EQ("42 ", format("{0:<4x}", 0x42)); + EXPECT_EQ("-42 ", format("{0:<5}", -42)); + EXPECT_EQ("42 ", format("{0:<5}", 42u)); + EXPECT_EQ("-42 ", format("{0:<5}", -42l)); + EXPECT_EQ("42 ", format("{0:<5}", 42ul)); + EXPECT_EQ("-42 ", format("{0:<5}", -42ll)); + EXPECT_EQ("42 ", format("{0:<5}", 42ull)); EXPECT_EQ("-42 ", format("{0:<5}", -42.0)); EXPECT_EQ("-42 ", format("{0:<5}", -42.0l)); - EXPECT_EQ("c ", format("{0:<5}", 'c')); - EXPECT_EQ("abc ", format("{0:<5}", "abc")); - EXPECT_EQ("0xface ", format("{0:<8}", reinterpret_cast<void*>(0xface))); -} - -TEST(FormatterTest, RightAlign) { - EXPECT_EQ(" 42", format("{0:>4}", 42)); - EXPECT_EQ(" 42", format("{0:>4o}", 042)); - EXPECT_EQ(" 42", format("{0:>4x}", 0x42)); - EXPECT_EQ(" -42", format("{0:>5}", -42)); - EXPECT_EQ(" 42", format("{0:>5}", 42u)); - EXPECT_EQ(" -42", format("{0:>5}", -42l)); - EXPECT_EQ(" 42", format("{0:>5}", 42ul)); - EXPECT_EQ(" -42", format("{0:>5}", -42ll)); - EXPECT_EQ(" 42", format("{0:>5}", 42ull)); + EXPECT_EQ("c ", format("{0:<5}", 'c')); + EXPECT_EQ("abc ", format("{0:<5}", "abc")); + EXPECT_EQ("0xface ", format("{0:<8}", reinterpret_cast<void*>(0xface))); +} + +TEST(FormatterTest, RightAlign) { + EXPECT_EQ(" 42", format("{0:>4}", 42)); + EXPECT_EQ(" 42", format("{0:>4o}", 042)); + EXPECT_EQ(" 42", format("{0:>4x}", 0x42)); + EXPECT_EQ(" -42", format("{0:>5}", -42)); + EXPECT_EQ(" 42", format("{0:>5}", 42u)); + EXPECT_EQ(" -42", format("{0:>5}", -42l)); + EXPECT_EQ(" 42", format("{0:>5}", 42ul)); + EXPECT_EQ(" -42", format("{0:>5}", -42ll)); + EXPECT_EQ(" 42", format("{0:>5}", 42ull)); EXPECT_EQ(" -42", format("{0:>5}", -42.0)); EXPECT_EQ(" -42", format("{0:>5}", -42.0l)); - EXPECT_EQ(" c", format("{0:>5}", 'c')); - EXPECT_EQ(" abc", format("{0:>5}", "abc")); - EXPECT_EQ(" 0xface", format("{0:>8}", reinterpret_cast<void*>(0xface))); -} - + EXPECT_EQ(" c", format("{0:>5}", 'c')); + EXPECT_EQ(" abc", format("{0:>5}", "abc")); + EXPECT_EQ(" 0xface", format("{0:>8}", reinterpret_cast<void*>(0xface))); +} + #if FMT_DEPRECATED_NUMERIC_ALIGN TEST(FormatterTest, NumericAlign) { EXPECT_EQ("0042", format("{0:=4}", 42)); } -#endif - -TEST(FormatterTest, CenterAlign) { - EXPECT_EQ(" 42 ", format("{0:^5}", 42)); - EXPECT_EQ(" 42 ", format("{0:^5o}", 042)); - EXPECT_EQ(" 42 ", format("{0:^5x}", 0x42)); - EXPECT_EQ(" -42 ", format("{0:^5}", -42)); - EXPECT_EQ(" 42 ", format("{0:^5}", 42u)); - EXPECT_EQ(" -42 ", format("{0:^5}", -42l)); - EXPECT_EQ(" 42 ", format("{0:^5}", 42ul)); - EXPECT_EQ(" -42 ", format("{0:^5}", -42ll)); - EXPECT_EQ(" 42 ", format("{0:^5}", 42ull)); +#endif + +TEST(FormatterTest, CenterAlign) { + EXPECT_EQ(" 42 ", format("{0:^5}", 42)); + EXPECT_EQ(" 42 ", format("{0:^5o}", 042)); + EXPECT_EQ(" 42 ", format("{0:^5x}", 0x42)); + EXPECT_EQ(" -42 ", format("{0:^5}", -42)); + EXPECT_EQ(" 42 ", format("{0:^5}", 42u)); + EXPECT_EQ(" -42 ", format("{0:^5}", -42l)); + EXPECT_EQ(" 42 ", format("{0:^5}", 42ul)); + EXPECT_EQ(" -42 ", format("{0:^5}", -42ll)); + EXPECT_EQ(" 42 ", format("{0:^5}", 42ull)); EXPECT_EQ(" -42 ", format("{0:^5}", -42.0)); EXPECT_EQ(" -42 ", format("{0:^5}", -42.0l)); - EXPECT_EQ(" c ", format("{0:^5}", 'c')); - EXPECT_EQ(" abc ", format("{0:^6}", "abc")); - EXPECT_EQ(" 0xface ", format("{0:^8}", reinterpret_cast<void*>(0xface))); -} - -TEST(FormatterTest, Fill) { - EXPECT_THROW_MSG(format("{0:{<5}", 'c'), format_error, - "invalid fill character '{'"); - EXPECT_THROW_MSG(format("{0:{<5}}", 'c'), format_error, - "invalid fill character '{'"); - EXPECT_EQ("**42", format("{0:*>4}", 42)); - EXPECT_EQ("**-42", format("{0:*>5}", -42)); - EXPECT_EQ("***42", format("{0:*>5}", 42u)); - EXPECT_EQ("**-42", format("{0:*>5}", -42l)); - EXPECT_EQ("***42", format("{0:*>5}", 42ul)); - EXPECT_EQ("**-42", format("{0:*>5}", -42ll)); - EXPECT_EQ("***42", format("{0:*>5}", 42ull)); + EXPECT_EQ(" c ", format("{0:^5}", 'c')); + EXPECT_EQ(" abc ", format("{0:^6}", "abc")); + EXPECT_EQ(" 0xface ", format("{0:^8}", reinterpret_cast<void*>(0xface))); +} + +TEST(FormatterTest, Fill) { + EXPECT_THROW_MSG(format("{0:{<5}", 'c'), format_error, + "invalid fill character '{'"); + EXPECT_THROW_MSG(format("{0:{<5}}", 'c'), format_error, + "invalid fill character '{'"); + EXPECT_EQ("**42", format("{0:*>4}", 42)); + EXPECT_EQ("**-42", format("{0:*>5}", -42)); + EXPECT_EQ("***42", format("{0:*>5}", 42u)); + EXPECT_EQ("**-42", format("{0:*>5}", -42l)); + EXPECT_EQ("***42", format("{0:*>5}", 42ul)); + EXPECT_EQ("**-42", format("{0:*>5}", -42ll)); + EXPECT_EQ("***42", format("{0:*>5}", 42ull)); EXPECT_EQ("**-42", format("{0:*>5}", -42.0)); EXPECT_EQ("**-42", format("{0:*>5}", -42.0l)); - EXPECT_EQ("c****", format("{0:*<5}", 'c')); - EXPECT_EQ("abc**", format("{0:*<5}", "abc")); - EXPECT_EQ("**0xface", format("{0:*>8}", reinterpret_cast<void*>(0xface))); - EXPECT_EQ("foo=", format("{:}=", "foo")); - EXPECT_EQ(std::string("\0\0\0*", 4), format(string_view("{:\0>4}", 6), '*')); - EXPECT_EQ("жж42", format("{0:ж>4}", 42)); - EXPECT_THROW_MSG(format("{:\x80\x80\x80\x80\x80>}", 0), format_error, + EXPECT_EQ("c****", format("{0:*<5}", 'c')); + EXPECT_EQ("abc**", format("{0:*<5}", "abc")); + EXPECT_EQ("**0xface", format("{0:*>8}", reinterpret_cast<void*>(0xface))); + EXPECT_EQ("foo=", format("{:}=", "foo")); + EXPECT_EQ(std::string("\0\0\0*", 4), format(string_view("{:\0>4}", 6), '*')); + EXPECT_EQ("жж42", format("{0:ж>4}", 42)); + EXPECT_THROW_MSG(format("{:\x80\x80\x80\x80\x80>}", 0), format_error, "missing '}' in format string"); -} - -TEST(FormatterTest, PlusSign) { - EXPECT_EQ("+42", format("{0:+}", 42)); - EXPECT_EQ("-42", format("{0:+}", -42)); - EXPECT_EQ("+42", format("{0:+}", 42)); - EXPECT_THROW_MSG(format("{0:+}", 42u), format_error, - "format specifier requires signed argument"); - EXPECT_EQ("+42", format("{0:+}", 42l)); - EXPECT_THROW_MSG(format("{0:+}", 42ul), format_error, - "format specifier requires signed argument"); - EXPECT_EQ("+42", format("{0:+}", 42ll)); - EXPECT_THROW_MSG(format("{0:+}", 42ull), format_error, - "format specifier requires signed argument"); +} + +TEST(FormatterTest, PlusSign) { + EXPECT_EQ("+42", format("{0:+}", 42)); + EXPECT_EQ("-42", format("{0:+}", -42)); + EXPECT_EQ("+42", format("{0:+}", 42)); + EXPECT_THROW_MSG(format("{0:+}", 42u), format_error, + "format specifier requires signed argument"); + EXPECT_EQ("+42", format("{0:+}", 42l)); + EXPECT_THROW_MSG(format("{0:+}", 42ul), format_error, + "format specifier requires signed argument"); + EXPECT_EQ("+42", format("{0:+}", 42ll)); + EXPECT_THROW_MSG(format("{0:+}", 42ull), format_error, + "format specifier requires signed argument"); EXPECT_EQ("+42", format("{0:+}", 42.0)); EXPECT_EQ("+42", format("{0:+}", 42.0l)); - EXPECT_THROW_MSG(format("{0:+", 'c'), format_error, - "missing '}' in format string"); - EXPECT_THROW_MSG(format("{0:+}", 'c'), format_error, - "invalid format specifier for char"); - EXPECT_THROW_MSG(format("{0:+}", "abc"), format_error, - "format specifier requires numeric argument"); - EXPECT_THROW_MSG(format("{0:+}", reinterpret_cast<void*>(0x42)), format_error, - "format specifier requires numeric argument"); -} - -TEST(FormatterTest, MinusSign) { - EXPECT_EQ("42", format("{0:-}", 42)); - EXPECT_EQ("-42", format("{0:-}", -42)); - EXPECT_EQ("42", format("{0:-}", 42)); - EXPECT_THROW_MSG(format("{0:-}", 42u), format_error, - "format specifier requires signed argument"); - EXPECT_EQ("42", format("{0:-}", 42l)); - EXPECT_THROW_MSG(format("{0:-}", 42ul), format_error, - "format specifier requires signed argument"); - EXPECT_EQ("42", format("{0:-}", 42ll)); - EXPECT_THROW_MSG(format("{0:-}", 42ull), format_error, - "format specifier requires signed argument"); + EXPECT_THROW_MSG(format("{0:+", 'c'), format_error, + "missing '}' in format string"); + EXPECT_THROW_MSG(format("{0:+}", 'c'), format_error, + "invalid format specifier for char"); + EXPECT_THROW_MSG(format("{0:+}", "abc"), format_error, + "format specifier requires numeric argument"); + EXPECT_THROW_MSG(format("{0:+}", reinterpret_cast<void*>(0x42)), format_error, + "format specifier requires numeric argument"); +} + +TEST(FormatterTest, MinusSign) { + EXPECT_EQ("42", format("{0:-}", 42)); + EXPECT_EQ("-42", format("{0:-}", -42)); + EXPECT_EQ("42", format("{0:-}", 42)); + EXPECT_THROW_MSG(format("{0:-}", 42u), format_error, + "format specifier requires signed argument"); + EXPECT_EQ("42", format("{0:-}", 42l)); + EXPECT_THROW_MSG(format("{0:-}", 42ul), format_error, + "format specifier requires signed argument"); + EXPECT_EQ("42", format("{0:-}", 42ll)); + EXPECT_THROW_MSG(format("{0:-}", 42ull), format_error, + "format specifier requires signed argument"); EXPECT_EQ("42", format("{0:-}", 42.0)); EXPECT_EQ("42", format("{0:-}", 42.0l)); - EXPECT_THROW_MSG(format("{0:-", 'c'), format_error, - "missing '}' in format string"); - EXPECT_THROW_MSG(format("{0:-}", 'c'), format_error, - "invalid format specifier for char"); - EXPECT_THROW_MSG(format("{0:-}", "abc"), format_error, - "format specifier requires numeric argument"); - EXPECT_THROW_MSG(format("{0:-}", reinterpret_cast<void*>(0x42)), format_error, - "format specifier requires numeric argument"); -} - -TEST(FormatterTest, SpaceSign) { - EXPECT_EQ(" 42", format("{0: }", 42)); - EXPECT_EQ("-42", format("{0: }", -42)); - EXPECT_EQ(" 42", format("{0: }", 42)); - EXPECT_THROW_MSG(format("{0: }", 42u), format_error, - "format specifier requires signed argument"); - EXPECT_EQ(" 42", format("{0: }", 42l)); - EXPECT_THROW_MSG(format("{0: }", 42ul), format_error, - "format specifier requires signed argument"); - EXPECT_EQ(" 42", format("{0: }", 42ll)); - EXPECT_THROW_MSG(format("{0: }", 42ull), format_error, - "format specifier requires signed argument"); + EXPECT_THROW_MSG(format("{0:-", 'c'), format_error, + "missing '}' in format string"); + EXPECT_THROW_MSG(format("{0:-}", 'c'), format_error, + "invalid format specifier for char"); + EXPECT_THROW_MSG(format("{0:-}", "abc"), format_error, + "format specifier requires numeric argument"); + EXPECT_THROW_MSG(format("{0:-}", reinterpret_cast<void*>(0x42)), format_error, + "format specifier requires numeric argument"); +} + +TEST(FormatterTest, SpaceSign) { + EXPECT_EQ(" 42", format("{0: }", 42)); + EXPECT_EQ("-42", format("{0: }", -42)); + EXPECT_EQ(" 42", format("{0: }", 42)); + EXPECT_THROW_MSG(format("{0: }", 42u), format_error, + "format specifier requires signed argument"); + EXPECT_EQ(" 42", format("{0: }", 42l)); + EXPECT_THROW_MSG(format("{0: }", 42ul), format_error, + "format specifier requires signed argument"); + EXPECT_EQ(" 42", format("{0: }", 42ll)); + EXPECT_THROW_MSG(format("{0: }", 42ull), format_error, + "format specifier requires signed argument"); EXPECT_EQ(" 42", format("{0: }", 42.0)); EXPECT_EQ(" 42", format("{0: }", 42.0l)); - EXPECT_THROW_MSG(format("{0: ", 'c'), format_error, - "missing '}' in format string"); - EXPECT_THROW_MSG(format("{0: }", 'c'), format_error, - "invalid format specifier for char"); - EXPECT_THROW_MSG(format("{0: }", "abc"), format_error, - "format specifier requires numeric argument"); - EXPECT_THROW_MSG(format("{0: }", reinterpret_cast<void*>(0x42)), format_error, - "format specifier requires numeric argument"); -} - + EXPECT_THROW_MSG(format("{0: ", 'c'), format_error, + "missing '}' in format string"); + EXPECT_THROW_MSG(format("{0: }", 'c'), format_error, + "invalid format specifier for char"); + EXPECT_THROW_MSG(format("{0: }", "abc"), format_error, + "format specifier requires numeric argument"); + EXPECT_THROW_MSG(format("{0: }", reinterpret_cast<void*>(0x42)), format_error, + "format specifier requires numeric argument"); +} + TEST(FormatterTest, SignNotTruncated) { wchar_t format_str[] = {L'{', L':', '+' | (1 << fmt::detail::num_bits<char>()), L'}', 0}; EXPECT_THROW(format(format_str, 42), format_error); } -TEST(FormatterTest, HashFlag) { - EXPECT_EQ("42", format("{0:#}", 42)); - EXPECT_EQ("-42", format("{0:#}", -42)); - EXPECT_EQ("0b101010", format("{0:#b}", 42)); - EXPECT_EQ("0B101010", format("{0:#B}", 42)); - EXPECT_EQ("-0b101010", format("{0:#b}", -42)); - EXPECT_EQ("0x42", format("{0:#x}", 0x42)); - EXPECT_EQ("0X42", format("{0:#X}", 0x42)); - EXPECT_EQ("-0x42", format("{0:#x}", -0x42)); - EXPECT_EQ("0", format("{0:#o}", 0)); - EXPECT_EQ("042", format("{0:#o}", 042)); - EXPECT_EQ("-042", format("{0:#o}", -042)); - EXPECT_EQ("42", format("{0:#}", 42u)); - EXPECT_EQ("0x42", format("{0:#x}", 0x42u)); - EXPECT_EQ("042", format("{0:#o}", 042u)); - - EXPECT_EQ("-42", format("{0:#}", -42l)); - EXPECT_EQ("0x42", format("{0:#x}", 0x42l)); - EXPECT_EQ("-0x42", format("{0:#x}", -0x42l)); - EXPECT_EQ("042", format("{0:#o}", 042l)); - EXPECT_EQ("-042", format("{0:#o}", -042l)); - EXPECT_EQ("42", format("{0:#}", 42ul)); - EXPECT_EQ("0x42", format("{0:#x}", 0x42ul)); - EXPECT_EQ("042", format("{0:#o}", 042ul)); - - EXPECT_EQ("-42", format("{0:#}", -42ll)); - EXPECT_EQ("0x42", format("{0:#x}", 0x42ll)); - EXPECT_EQ("-0x42", format("{0:#x}", -0x42ll)); - EXPECT_EQ("042", format("{0:#o}", 042ll)); - EXPECT_EQ("-042", format("{0:#o}", -042ll)); - EXPECT_EQ("42", format("{0:#}", 42ull)); - EXPECT_EQ("0x42", format("{0:#x}", 0x42ull)); - EXPECT_EQ("042", format("{0:#o}", 042ull)); - - EXPECT_EQ("-42.0", format("{0:#}", -42.0)); - EXPECT_EQ("-42.0", format("{0:#}", -42.0l)); - EXPECT_EQ("4.e+01", format("{:#.0e}", 42.0)); - EXPECT_EQ("0.", format("{:#.0f}", 0.01)); +TEST(FormatterTest, HashFlag) { + EXPECT_EQ("42", format("{0:#}", 42)); + EXPECT_EQ("-42", format("{0:#}", -42)); + EXPECT_EQ("0b101010", format("{0:#b}", 42)); + EXPECT_EQ("0B101010", format("{0:#B}", 42)); + EXPECT_EQ("-0b101010", format("{0:#b}", -42)); + EXPECT_EQ("0x42", format("{0:#x}", 0x42)); + EXPECT_EQ("0X42", format("{0:#X}", 0x42)); + EXPECT_EQ("-0x42", format("{0:#x}", -0x42)); + EXPECT_EQ("0", format("{0:#o}", 0)); + EXPECT_EQ("042", format("{0:#o}", 042)); + EXPECT_EQ("-042", format("{0:#o}", -042)); + EXPECT_EQ("42", format("{0:#}", 42u)); + EXPECT_EQ("0x42", format("{0:#x}", 0x42u)); + EXPECT_EQ("042", format("{0:#o}", 042u)); + + EXPECT_EQ("-42", format("{0:#}", -42l)); + EXPECT_EQ("0x42", format("{0:#x}", 0x42l)); + EXPECT_EQ("-0x42", format("{0:#x}", -0x42l)); + EXPECT_EQ("042", format("{0:#o}", 042l)); + EXPECT_EQ("-042", format("{0:#o}", -042l)); + EXPECT_EQ("42", format("{0:#}", 42ul)); + EXPECT_EQ("0x42", format("{0:#x}", 0x42ul)); + EXPECT_EQ("042", format("{0:#o}", 042ul)); + + EXPECT_EQ("-42", format("{0:#}", -42ll)); + EXPECT_EQ("0x42", format("{0:#x}", 0x42ll)); + EXPECT_EQ("-0x42", format("{0:#x}", -0x42ll)); + EXPECT_EQ("042", format("{0:#o}", 042ll)); + EXPECT_EQ("-042", format("{0:#o}", -042ll)); + EXPECT_EQ("42", format("{0:#}", 42ull)); + EXPECT_EQ("0x42", format("{0:#x}", 0x42ull)); + EXPECT_EQ("042", format("{0:#o}", 042ull)); + + EXPECT_EQ("-42.0", format("{0:#}", -42.0)); + EXPECT_EQ("-42.0", format("{0:#}", -42.0l)); + EXPECT_EQ("4.e+01", format("{:#.0e}", 42.0)); + EXPECT_EQ("0.", format("{:#.0f}", 0.01)); EXPECT_EQ("0.50", format("{:#.2g}", 0.5)); EXPECT_EQ("0.", format("{:#.0f}", 0.5)); - EXPECT_THROW_MSG(format("{0:#", 'c'), format_error, - "missing '}' in format string"); - EXPECT_THROW_MSG(format("{0:#}", 'c'), format_error, - "invalid format specifier for char"); - EXPECT_THROW_MSG(format("{0:#}", "abc"), format_error, - "format specifier requires numeric argument"); - EXPECT_THROW_MSG(format("{0:#}", reinterpret_cast<void*>(0x42)), format_error, - "format specifier requires numeric argument"); -} - -TEST(FormatterTest, ZeroFlag) { - EXPECT_EQ("42", format("{0:0}", 42)); - EXPECT_EQ("-0042", format("{0:05}", -42)); - EXPECT_EQ("00042", format("{0:05}", 42u)); - EXPECT_EQ("-0042", format("{0:05}", -42l)); - EXPECT_EQ("00042", format("{0:05}", 42ul)); - EXPECT_EQ("-0042", format("{0:05}", -42ll)); - EXPECT_EQ("00042", format("{0:05}", 42ull)); + EXPECT_THROW_MSG(format("{0:#", 'c'), format_error, + "missing '}' in format string"); + EXPECT_THROW_MSG(format("{0:#}", 'c'), format_error, + "invalid format specifier for char"); + EXPECT_THROW_MSG(format("{0:#}", "abc"), format_error, + "format specifier requires numeric argument"); + EXPECT_THROW_MSG(format("{0:#}", reinterpret_cast<void*>(0x42)), format_error, + "format specifier requires numeric argument"); +} + +TEST(FormatterTest, ZeroFlag) { + EXPECT_EQ("42", format("{0:0}", 42)); + EXPECT_EQ("-0042", format("{0:05}", -42)); + EXPECT_EQ("00042", format("{0:05}", 42u)); + EXPECT_EQ("-0042", format("{0:05}", -42l)); + EXPECT_EQ("00042", format("{0:05}", 42ul)); + EXPECT_EQ("-0042", format("{0:05}", -42ll)); + EXPECT_EQ("00042", format("{0:05}", 42ull)); EXPECT_EQ("-000042", format("{0:07}", -42.0)); EXPECT_EQ("-000042", format("{0:07}", -42.0l)); - EXPECT_THROW_MSG(format("{0:0", 'c'), format_error, - "missing '}' in format string"); - EXPECT_THROW_MSG(format("{0:05}", 'c'), format_error, - "invalid format specifier for char"); - EXPECT_THROW_MSG(format("{0:05}", "abc"), format_error, - "format specifier requires numeric argument"); - EXPECT_THROW_MSG(format("{0:05}", reinterpret_cast<void*>(0x42)), - format_error, "format specifier requires numeric argument"); -} - -TEST(FormatterTest, Width) { - char format_str[BUFFER_SIZE]; - safe_sprintf(format_str, "{0:%u", UINT_MAX); - increment(format_str + 3); - EXPECT_THROW_MSG(format(format_str, 0), format_error, "number is too big"); + EXPECT_THROW_MSG(format("{0:0", 'c'), format_error, + "missing '}' in format string"); + EXPECT_THROW_MSG(format("{0:05}", 'c'), format_error, + "invalid format specifier for char"); + EXPECT_THROW_MSG(format("{0:05}", "abc"), format_error, + "format specifier requires numeric argument"); + EXPECT_THROW_MSG(format("{0:05}", reinterpret_cast<void*>(0x42)), + format_error, "format specifier requires numeric argument"); +} + +TEST(FormatterTest, Width) { + char format_str[BUFFER_SIZE]; + safe_sprintf(format_str, "{0:%u", UINT_MAX); + increment(format_str + 3); + EXPECT_THROW_MSG(format(format_str, 0), format_error, "number is too big"); size_t size = std::strlen(format_str); - format_str[size] = '}'; - format_str[size + 1] = 0; - EXPECT_THROW_MSG(format(format_str, 0), format_error, "number is too big"); - - safe_sprintf(format_str, "{0:%u", INT_MAX + 1u); - EXPECT_THROW_MSG(format(format_str, 0), format_error, "number is too big"); - safe_sprintf(format_str, "{0:%u}", INT_MAX + 1u); - EXPECT_THROW_MSG(format(format_str, 0), format_error, "number is too big"); - EXPECT_EQ(" -42", format("{0:4}", -42)); - EXPECT_EQ(" 42", format("{0:5}", 42u)); - EXPECT_EQ(" -42", format("{0:6}", -42l)); - EXPECT_EQ(" 42", format("{0:7}", 42ul)); - EXPECT_EQ(" -42", format("{0:6}", -42ll)); - EXPECT_EQ(" 42", format("{0:7}", 42ull)); - EXPECT_EQ(" -1.23", format("{0:8}", -1.23)); - EXPECT_EQ(" -1.23", format("{0:9}", -1.23l)); - EXPECT_EQ(" 0xcafe", format("{0:10}", reinterpret_cast<void*>(0xcafe))); - EXPECT_EQ("x ", format("{0:11}", 'x')); - EXPECT_EQ("str ", format("{0:12}", "str")); - EXPECT_EQ(fmt::format("{:*^5}", "🤡"), "**🤡**"); -} - -template <typename T> inline T const_check(T value) { return value; } - -TEST(FormatterTest, RuntimeWidth) { - char format_str[BUFFER_SIZE]; - safe_sprintf(format_str, "{0:{%u", UINT_MAX); - increment(format_str + 4); - EXPECT_THROW_MSG(format(format_str, 0), format_error, "number is too big"); + format_str[size] = '}'; + format_str[size + 1] = 0; + EXPECT_THROW_MSG(format(format_str, 0), format_error, "number is too big"); + + safe_sprintf(format_str, "{0:%u", INT_MAX + 1u); + EXPECT_THROW_MSG(format(format_str, 0), format_error, "number is too big"); + safe_sprintf(format_str, "{0:%u}", INT_MAX + 1u); + EXPECT_THROW_MSG(format(format_str, 0), format_error, "number is too big"); + EXPECT_EQ(" -42", format("{0:4}", -42)); + EXPECT_EQ(" 42", format("{0:5}", 42u)); + EXPECT_EQ(" -42", format("{0:6}", -42l)); + EXPECT_EQ(" 42", format("{0:7}", 42ul)); + EXPECT_EQ(" -42", format("{0:6}", -42ll)); + EXPECT_EQ(" 42", format("{0:7}", 42ull)); + EXPECT_EQ(" -1.23", format("{0:8}", -1.23)); + EXPECT_EQ(" -1.23", format("{0:9}", -1.23l)); + EXPECT_EQ(" 0xcafe", format("{0:10}", reinterpret_cast<void*>(0xcafe))); + EXPECT_EQ("x ", format("{0:11}", 'x')); + EXPECT_EQ("str ", format("{0:12}", "str")); + EXPECT_EQ(fmt::format("{:*^5}", "🤡"), "**🤡**"); +} + +template <typename T> inline T const_check(T value) { return value; } + +TEST(FormatterTest, RuntimeWidth) { + char format_str[BUFFER_SIZE]; + safe_sprintf(format_str, "{0:{%u", UINT_MAX); + increment(format_str + 4); + EXPECT_THROW_MSG(format(format_str, 0), format_error, "number is too big"); size_t size = std::strlen(format_str); - format_str[size] = '}'; - format_str[size + 1] = 0; - EXPECT_THROW_MSG(format(format_str, 0), format_error, "number is too big"); - format_str[size + 1] = '}'; - format_str[size + 2] = 0; - EXPECT_THROW_MSG(format(format_str, 0), format_error, "number is too big"); - - EXPECT_THROW_MSG(format("{0:{", 0), format_error, "invalid format string"); - EXPECT_THROW_MSG(format("{0:{}", 0), format_error, - "cannot switch from manual to automatic argument indexing"); - EXPECT_THROW_MSG(format("{0:{?}}", 0), format_error, "invalid format string"); + format_str[size] = '}'; + format_str[size + 1] = 0; + EXPECT_THROW_MSG(format(format_str, 0), format_error, "number is too big"); + format_str[size + 1] = '}'; + format_str[size + 2] = 0; + EXPECT_THROW_MSG(format(format_str, 0), format_error, "number is too big"); + + EXPECT_THROW_MSG(format("{0:{", 0), format_error, "invalid format string"); + EXPECT_THROW_MSG(format("{0:{}", 0), format_error, + "cannot switch from manual to automatic argument indexing"); + EXPECT_THROW_MSG(format("{0:{?}}", 0), format_error, "invalid format string"); EXPECT_THROW_MSG(format("{0:{1}}", 0), format_error, "argument not found"); - - EXPECT_THROW_MSG(format("{0:{0:}}", 0), format_error, - "invalid format string"); - - EXPECT_THROW_MSG(format("{0:{1}}", 0, -1), format_error, "negative width"); - EXPECT_THROW_MSG(format("{0:{1}}", 0, (INT_MAX + 1u)), format_error, - "number is too big"); - EXPECT_THROW_MSG(format("{0:{1}}", 0, -1l), format_error, "negative width"); - if (const_check(sizeof(long) > sizeof(int))) { - long value = INT_MAX; - EXPECT_THROW_MSG(format("{0:{1}}", 0, (value + 1)), format_error, - "number is too big"); - } - EXPECT_THROW_MSG(format("{0:{1}}", 0, (INT_MAX + 1ul)), format_error, - "number is too big"); - - EXPECT_THROW_MSG(format("{0:{1}}", 0, '0'), format_error, - "width is not integer"); - EXPECT_THROW_MSG(format("{0:{1}}", 0, 0.0), format_error, - "width is not integer"); - - EXPECT_EQ(" -42", format("{0:{1}}", -42, 4)); - EXPECT_EQ(" 42", format("{0:{1}}", 42u, 5)); - EXPECT_EQ(" -42", format("{0:{1}}", -42l, 6)); - EXPECT_EQ(" 42", format("{0:{1}}", 42ul, 7)); - EXPECT_EQ(" -42", format("{0:{1}}", -42ll, 6)); - EXPECT_EQ(" 42", format("{0:{1}}", 42ull, 7)); - EXPECT_EQ(" -1.23", format("{0:{1}}", -1.23, 8)); - EXPECT_EQ(" -1.23", format("{0:{1}}", -1.23l, 9)); - EXPECT_EQ(" 0xcafe", - format("{0:{1}}", reinterpret_cast<void*>(0xcafe), 10)); - EXPECT_EQ("x ", format("{0:{1}}", 'x', 11)); - EXPECT_EQ("str ", format("{0:{1}}", "str", 12)); -} - -TEST(FormatterTest, Precision) { - char format_str[BUFFER_SIZE]; - safe_sprintf(format_str, "{0:.%u", UINT_MAX); - increment(format_str + 4); - EXPECT_THROW_MSG(format(format_str, 0), format_error, "number is too big"); + + EXPECT_THROW_MSG(format("{0:{0:}}", 0), format_error, + "invalid format string"); + + EXPECT_THROW_MSG(format("{0:{1}}", 0, -1), format_error, "negative width"); + EXPECT_THROW_MSG(format("{0:{1}}", 0, (INT_MAX + 1u)), format_error, + "number is too big"); + EXPECT_THROW_MSG(format("{0:{1}}", 0, -1l), format_error, "negative width"); + if (const_check(sizeof(long) > sizeof(int))) { + long value = INT_MAX; + EXPECT_THROW_MSG(format("{0:{1}}", 0, (value + 1)), format_error, + "number is too big"); + } + EXPECT_THROW_MSG(format("{0:{1}}", 0, (INT_MAX + 1ul)), format_error, + "number is too big"); + + EXPECT_THROW_MSG(format("{0:{1}}", 0, '0'), format_error, + "width is not integer"); + EXPECT_THROW_MSG(format("{0:{1}}", 0, 0.0), format_error, + "width is not integer"); + + EXPECT_EQ(" -42", format("{0:{1}}", -42, 4)); + EXPECT_EQ(" 42", format("{0:{1}}", 42u, 5)); + EXPECT_EQ(" -42", format("{0:{1}}", -42l, 6)); + EXPECT_EQ(" 42", format("{0:{1}}", 42ul, 7)); + EXPECT_EQ(" -42", format("{0:{1}}", -42ll, 6)); + EXPECT_EQ(" 42", format("{0:{1}}", 42ull, 7)); + EXPECT_EQ(" -1.23", format("{0:{1}}", -1.23, 8)); + EXPECT_EQ(" -1.23", format("{0:{1}}", -1.23l, 9)); + EXPECT_EQ(" 0xcafe", + format("{0:{1}}", reinterpret_cast<void*>(0xcafe), 10)); + EXPECT_EQ("x ", format("{0:{1}}", 'x', 11)); + EXPECT_EQ("str ", format("{0:{1}}", "str", 12)); +} + +TEST(FormatterTest, Precision) { + char format_str[BUFFER_SIZE]; + safe_sprintf(format_str, "{0:.%u", UINT_MAX); + increment(format_str + 4); + EXPECT_THROW_MSG(format(format_str, 0), format_error, "number is too big"); size_t size = std::strlen(format_str); - format_str[size] = '}'; - format_str[size + 1] = 0; - EXPECT_THROW_MSG(format(format_str, 0), format_error, "number is too big"); - - safe_sprintf(format_str, "{0:.%u", INT_MAX + 1u); - EXPECT_THROW_MSG(format(format_str, 0), format_error, "number is too big"); - safe_sprintf(format_str, "{0:.%u}", INT_MAX + 1u); - EXPECT_THROW_MSG(format(format_str, 0), format_error, "number is too big"); - - EXPECT_THROW_MSG(format("{0:.", 0), format_error, - "missing precision specifier"); - EXPECT_THROW_MSG(format("{0:.}", 0), format_error, - "missing precision specifier"); - - EXPECT_THROW_MSG(format("{0:.2", 0), format_error, - "precision not allowed for this argument type"); - EXPECT_THROW_MSG(format("{0:.2}", 42), format_error, - "precision not allowed for this argument type"); - EXPECT_THROW_MSG(format("{0:.2f}", 42), format_error, - "precision not allowed for this argument type"); - EXPECT_THROW_MSG(format("{0:.2}", 42u), format_error, - "precision not allowed for this argument type"); - EXPECT_THROW_MSG(format("{0:.2f}", 42u), format_error, - "precision not allowed for this argument type"); - EXPECT_THROW_MSG(format("{0:.2}", 42l), format_error, - "precision not allowed for this argument type"); - EXPECT_THROW_MSG(format("{0:.2f}", 42l), format_error, - "precision not allowed for this argument type"); - EXPECT_THROW_MSG(format("{0:.2}", 42ul), format_error, - "precision not allowed for this argument type"); - EXPECT_THROW_MSG(format("{0:.2f}", 42ul), format_error, - "precision not allowed for this argument type"); - EXPECT_THROW_MSG(format("{0:.2}", 42ll), format_error, - "precision not allowed for this argument type"); - EXPECT_THROW_MSG(format("{0:.2f}", 42ll), format_error, - "precision not allowed for this argument type"); - EXPECT_THROW_MSG(format("{0:.2}", 42ull), format_error, - "precision not allowed for this argument type"); - EXPECT_THROW_MSG(format("{0:.2f}", 42ull), format_error, - "precision not allowed for this argument type"); - EXPECT_THROW_MSG(format("{0:3.0}", 'x'), format_error, - "precision not allowed for this argument type"); - EXPECT_EQ("1.2", format("{0:.2}", 1.2345)); - EXPECT_EQ("1.2", format("{0:.2}", 1.2345l)); - EXPECT_EQ("1.2e+56", format("{:.2}", 1.234e56)); - EXPECT_EQ("1e+00", format("{:.0e}", 1.0L)); - EXPECT_EQ(" 0.0e+00", format("{:9.1e}", 0.0)); - EXPECT_EQ( - "4.9406564584124654417656879286822137236505980261432476442558568250067550" - "727020875186529983636163599237979656469544571773092665671035593979639877" - "479601078187812630071319031140452784581716784898210368871863605699873072" - "305000638740915356498438731247339727316961514003171538539807412623856559" - "117102665855668676818703956031062493194527159149245532930545654440112748" - "012970999954193198940908041656332452475714786901472678015935523861155013" - "480352649347201937902681071074917033322268447533357208324319361e-324", - format("{:.494}", 4.9406564584124654E-324)); - EXPECT_EQ( - "-0X1.41FE3FFE71C9E000000000000000000000000000000000000000000000000000000" - "000000000000000000000000000000000000000000000000000000000000000000000000" - "000000000000000000000000000000000000000000000000000000000000000000000000" - "000000000000000000000000000000000000000000000000000000000000000000000000" - "000000000000000000000000000000000000000000000000000000000000000000000000" - "000000000000000000000000000000000000000000000000000000000000000000000000" - "000000000000000000000000000000000000000000000000000000000000000000000000" - "000000000000000000000000000000000000000000000000000000000000000000000000" - "000000000000000000000000000000000000000000000000000000000000000000000000" - "000000000000000000000000000000000000000000000000000000000000000000000000" - "000000000000000000000000000000000000000000000000000000000000000000000000" - "000000000000000000000000000000000000000000000000000P+127", - format("{:.838A}", -2.14001164E+38)); - EXPECT_EQ("123.", format("{:#.0f}", 123.0)); - EXPECT_EQ("1.23", format("{:.02f}", 1.234)); - EXPECT_EQ("0.001", format("{:.1g}", 0.001)); + format_str[size] = '}'; + format_str[size + 1] = 0; + EXPECT_THROW_MSG(format(format_str, 0), format_error, "number is too big"); + + safe_sprintf(format_str, "{0:.%u", INT_MAX + 1u); + EXPECT_THROW_MSG(format(format_str, 0), format_error, "number is too big"); + safe_sprintf(format_str, "{0:.%u}", INT_MAX + 1u); + EXPECT_THROW_MSG(format(format_str, 0), format_error, "number is too big"); + + EXPECT_THROW_MSG(format("{0:.", 0), format_error, + "missing precision specifier"); + EXPECT_THROW_MSG(format("{0:.}", 0), format_error, + "missing precision specifier"); + + EXPECT_THROW_MSG(format("{0:.2", 0), format_error, + "precision not allowed for this argument type"); + EXPECT_THROW_MSG(format("{0:.2}", 42), format_error, + "precision not allowed for this argument type"); + EXPECT_THROW_MSG(format("{0:.2f}", 42), format_error, + "precision not allowed for this argument type"); + EXPECT_THROW_MSG(format("{0:.2}", 42u), format_error, + "precision not allowed for this argument type"); + EXPECT_THROW_MSG(format("{0:.2f}", 42u), format_error, + "precision not allowed for this argument type"); + EXPECT_THROW_MSG(format("{0:.2}", 42l), format_error, + "precision not allowed for this argument type"); + EXPECT_THROW_MSG(format("{0:.2f}", 42l), format_error, + "precision not allowed for this argument type"); + EXPECT_THROW_MSG(format("{0:.2}", 42ul), format_error, + "precision not allowed for this argument type"); + EXPECT_THROW_MSG(format("{0:.2f}", 42ul), format_error, + "precision not allowed for this argument type"); + EXPECT_THROW_MSG(format("{0:.2}", 42ll), format_error, + "precision not allowed for this argument type"); + EXPECT_THROW_MSG(format("{0:.2f}", 42ll), format_error, + "precision not allowed for this argument type"); + EXPECT_THROW_MSG(format("{0:.2}", 42ull), format_error, + "precision not allowed for this argument type"); + EXPECT_THROW_MSG(format("{0:.2f}", 42ull), format_error, + "precision not allowed for this argument type"); + EXPECT_THROW_MSG(format("{0:3.0}", 'x'), format_error, + "precision not allowed for this argument type"); + EXPECT_EQ("1.2", format("{0:.2}", 1.2345)); + EXPECT_EQ("1.2", format("{0:.2}", 1.2345l)); + EXPECT_EQ("1.2e+56", format("{:.2}", 1.234e56)); + EXPECT_EQ("1e+00", format("{:.0e}", 1.0L)); + EXPECT_EQ(" 0.0e+00", format("{:9.1e}", 0.0)); + EXPECT_EQ( + "4.9406564584124654417656879286822137236505980261432476442558568250067550" + "727020875186529983636163599237979656469544571773092665671035593979639877" + "479601078187812630071319031140452784581716784898210368871863605699873072" + "305000638740915356498438731247339727316961514003171538539807412623856559" + "117102665855668676818703956031062493194527159149245532930545654440112748" + "012970999954193198940908041656332452475714786901472678015935523861155013" + "480352649347201937902681071074917033322268447533357208324319361e-324", + format("{:.494}", 4.9406564584124654E-324)); + EXPECT_EQ( + "-0X1.41FE3FFE71C9E000000000000000000000000000000000000000000000000000000" + "000000000000000000000000000000000000000000000000000000000000000000000000" + "000000000000000000000000000000000000000000000000000000000000000000000000" + "000000000000000000000000000000000000000000000000000000000000000000000000" + "000000000000000000000000000000000000000000000000000000000000000000000000" + "000000000000000000000000000000000000000000000000000000000000000000000000" + "000000000000000000000000000000000000000000000000000000000000000000000000" + "000000000000000000000000000000000000000000000000000000000000000000000000" + "000000000000000000000000000000000000000000000000000000000000000000000000" + "000000000000000000000000000000000000000000000000000000000000000000000000" + "000000000000000000000000000000000000000000000000000000000000000000000000" + "000000000000000000000000000000000000000000000000000P+127", + format("{:.838A}", -2.14001164E+38)); + EXPECT_EQ("123.", format("{:#.0f}", 123.0)); + EXPECT_EQ("1.23", format("{:.02f}", 1.234)); + EXPECT_EQ("0.001", format("{:.1g}", 0.001)); EXPECT_EQ("1019666400", format("{}", 1019666432.0f)); EXPECT_EQ("1e+01", format("{:.0e}", 9.5)); EXPECT_EQ("1.0e-34", fmt::format("{:.1e}", 1e-34)); - - EXPECT_THROW_MSG(format("{0:.2}", reinterpret_cast<void*>(0xcafe)), - format_error, - "precision not allowed for this argument type"); - EXPECT_THROW_MSG(format("{0:.2f}", reinterpret_cast<void*>(0xcafe)), - format_error, - "precision not allowed for this argument type"); + + EXPECT_THROW_MSG(format("{0:.2}", reinterpret_cast<void*>(0xcafe)), + format_error, + "precision not allowed for this argument type"); + EXPECT_THROW_MSG(format("{0:.2f}", reinterpret_cast<void*>(0xcafe)), + format_error, + "precision not allowed for this argument type"); EXPECT_THROW_MSG(format("{:.{}e}", 42.0, fmt::detail::max_value<int>()), - format_error, "number is too big"); - - EXPECT_EQ("st", format("{0:.2}", "str")); -} - -TEST(FormatterTest, RuntimePrecision) { - char format_str[BUFFER_SIZE]; - safe_sprintf(format_str, "{0:.{%u", UINT_MAX); - increment(format_str + 5); - EXPECT_THROW_MSG(format(format_str, 0), format_error, "number is too big"); + format_error, "number is too big"); + + EXPECT_EQ("st", format("{0:.2}", "str")); +} + +TEST(FormatterTest, RuntimePrecision) { + char format_str[BUFFER_SIZE]; + safe_sprintf(format_str, "{0:.{%u", UINT_MAX); + increment(format_str + 5); + EXPECT_THROW_MSG(format(format_str, 0), format_error, "number is too big"); size_t size = std::strlen(format_str); - format_str[size] = '}'; - format_str[size + 1] = 0; - EXPECT_THROW_MSG(format(format_str, 0), format_error, "number is too big"); - format_str[size + 1] = '}'; - format_str[size + 2] = 0; - EXPECT_THROW_MSG(format(format_str, 0), format_error, "number is too big"); - - EXPECT_THROW_MSG(format("{0:.{", 0), format_error, "invalid format string"); - EXPECT_THROW_MSG(format("{0:.{}", 0), format_error, - "cannot switch from manual to automatic argument indexing"); - EXPECT_THROW_MSG(format("{0:.{?}}", 0), format_error, - "invalid format string"); - EXPECT_THROW_MSG(format("{0:.{1}", 0, 0), format_error, - "precision not allowed for this argument type"); + format_str[size] = '}'; + format_str[size + 1] = 0; + EXPECT_THROW_MSG(format(format_str, 0), format_error, "number is too big"); + format_str[size + 1] = '}'; + format_str[size + 2] = 0; + EXPECT_THROW_MSG(format(format_str, 0), format_error, "number is too big"); + + EXPECT_THROW_MSG(format("{0:.{", 0), format_error, "invalid format string"); + EXPECT_THROW_MSG(format("{0:.{}", 0), format_error, + "cannot switch from manual to automatic argument indexing"); + EXPECT_THROW_MSG(format("{0:.{?}}", 0), format_error, + "invalid format string"); + EXPECT_THROW_MSG(format("{0:.{1}", 0, 0), format_error, + "precision not allowed for this argument type"); EXPECT_THROW_MSG(format("{0:.{1}}", 0), format_error, "argument not found"); - - EXPECT_THROW_MSG(format("{0:.{0:}}", 0), format_error, - "invalid format string"); - - EXPECT_THROW_MSG(format("{0:.{1}}", 0, -1), format_error, - "negative precision"); - EXPECT_THROW_MSG(format("{0:.{1}}", 0, (INT_MAX + 1u)), format_error, - "number is too big"); - EXPECT_THROW_MSG(format("{0:.{1}}", 0, -1l), format_error, - "negative precision"); - if (const_check(sizeof(long) > sizeof(int))) { - long value = INT_MAX; - EXPECT_THROW_MSG(format("{0:.{1}}", 0, (value + 1)), format_error, - "number is too big"); - } - EXPECT_THROW_MSG(format("{0:.{1}}", 0, (INT_MAX + 1ul)), format_error, - "number is too big"); - - EXPECT_THROW_MSG(format("{0:.{1}}", 0, '0'), format_error, - "precision is not integer"); - EXPECT_THROW_MSG(format("{0:.{1}}", 0, 0.0), format_error, - "precision is not integer"); - - EXPECT_THROW_MSG(format("{0:.{1}}", 42, 2), format_error, - "precision not allowed for this argument type"); - EXPECT_THROW_MSG(format("{0:.{1}f}", 42, 2), format_error, - "precision not allowed for this argument type"); - EXPECT_THROW_MSG(format("{0:.{1}}", 42u, 2), format_error, - "precision not allowed for this argument type"); - EXPECT_THROW_MSG(format("{0:.{1}f}", 42u, 2), format_error, - "precision not allowed for this argument type"); - EXPECT_THROW_MSG(format("{0:.{1}}", 42l, 2), format_error, - "precision not allowed for this argument type"); - EXPECT_THROW_MSG(format("{0:.{1}f}", 42l, 2), format_error, - "precision not allowed for this argument type"); - EXPECT_THROW_MSG(format("{0:.{1}}", 42ul, 2), format_error, - "precision not allowed for this argument type"); - EXPECT_THROW_MSG(format("{0:.{1}f}", 42ul, 2), format_error, - "precision not allowed for this argument type"); - EXPECT_THROW_MSG(format("{0:.{1}}", 42ll, 2), format_error, - "precision not allowed for this argument type"); - EXPECT_THROW_MSG(format("{0:.{1}f}", 42ll, 2), format_error, - "precision not allowed for this argument type"); - EXPECT_THROW_MSG(format("{0:.{1}}", 42ull, 2), format_error, - "precision not allowed for this argument type"); - EXPECT_THROW_MSG(format("{0:.{1}f}", 42ull, 2), format_error, - "precision not allowed for this argument type"); - EXPECT_THROW_MSG(format("{0:3.{1}}", 'x', 0), format_error, - "precision not allowed for this argument type"); - EXPECT_EQ("1.2", format("{0:.{1}}", 1.2345, 2)); - EXPECT_EQ("1.2", format("{1:.{0}}", 2, 1.2345l)); - - EXPECT_THROW_MSG(format("{0:.{1}}", reinterpret_cast<void*>(0xcafe), 2), - format_error, - "precision not allowed for this argument type"); - EXPECT_THROW_MSG(format("{0:.{1}f}", reinterpret_cast<void*>(0xcafe), 2), - format_error, - "precision not allowed for this argument type"); - - EXPECT_EQ("st", format("{0:.{1}}", "str", 2)); -} - -template <typename T> -void check_unknown_types(const T& value, const char* types, const char*) { - char format_str[BUFFER_SIZE]; - const char* special = ".0123456789}"; - for (int i = CHAR_MIN; i <= CHAR_MAX; ++i) { - char c = static_cast<char>(i); - if (std::strchr(types, c) || std::strchr(special, c) || !c) continue; - safe_sprintf(format_str, "{0:10%c}", c); - const char* message = "invalid type specifier"; - EXPECT_THROW_MSG(format(format_str, value), format_error, message) - << format_str << " " << message; - } -} - -TEST(BoolTest, FormatBool) { - EXPECT_EQ("true", format("{}", true)); - EXPECT_EQ("false", format("{}", false)); - EXPECT_EQ("1", format("{:d}", true)); - EXPECT_EQ("true ", format("{:5}", true)); - EXPECT_EQ(L"true", format(L"{}", true)); -} - -TEST(FormatterTest, FormatShort) { - short s = 42; - EXPECT_EQ("42", format("{0:d}", s)); - unsigned short us = 42; - EXPECT_EQ("42", format("{0:d}", us)); -} - -TEST(FormatterTest, FormatInt) { - EXPECT_THROW_MSG(format("{0:v", 42), format_error, - "missing '}' in format string"); + + EXPECT_THROW_MSG(format("{0:.{0:}}", 0), format_error, + "invalid format string"); + + EXPECT_THROW_MSG(format("{0:.{1}}", 0, -1), format_error, + "negative precision"); + EXPECT_THROW_MSG(format("{0:.{1}}", 0, (INT_MAX + 1u)), format_error, + "number is too big"); + EXPECT_THROW_MSG(format("{0:.{1}}", 0, -1l), format_error, + "negative precision"); + if (const_check(sizeof(long) > sizeof(int))) { + long value = INT_MAX; + EXPECT_THROW_MSG(format("{0:.{1}}", 0, (value + 1)), format_error, + "number is too big"); + } + EXPECT_THROW_MSG(format("{0:.{1}}", 0, (INT_MAX + 1ul)), format_error, + "number is too big"); + + EXPECT_THROW_MSG(format("{0:.{1}}", 0, '0'), format_error, + "precision is not integer"); + EXPECT_THROW_MSG(format("{0:.{1}}", 0, 0.0), format_error, + "precision is not integer"); + + EXPECT_THROW_MSG(format("{0:.{1}}", 42, 2), format_error, + "precision not allowed for this argument type"); + EXPECT_THROW_MSG(format("{0:.{1}f}", 42, 2), format_error, + "precision not allowed for this argument type"); + EXPECT_THROW_MSG(format("{0:.{1}}", 42u, 2), format_error, + "precision not allowed for this argument type"); + EXPECT_THROW_MSG(format("{0:.{1}f}", 42u, 2), format_error, + "precision not allowed for this argument type"); + EXPECT_THROW_MSG(format("{0:.{1}}", 42l, 2), format_error, + "precision not allowed for this argument type"); + EXPECT_THROW_MSG(format("{0:.{1}f}", 42l, 2), format_error, + "precision not allowed for this argument type"); + EXPECT_THROW_MSG(format("{0:.{1}}", 42ul, 2), format_error, + "precision not allowed for this argument type"); + EXPECT_THROW_MSG(format("{0:.{1}f}", 42ul, 2), format_error, + "precision not allowed for this argument type"); + EXPECT_THROW_MSG(format("{0:.{1}}", 42ll, 2), format_error, + "precision not allowed for this argument type"); + EXPECT_THROW_MSG(format("{0:.{1}f}", 42ll, 2), format_error, + "precision not allowed for this argument type"); + EXPECT_THROW_MSG(format("{0:.{1}}", 42ull, 2), format_error, + "precision not allowed for this argument type"); + EXPECT_THROW_MSG(format("{0:.{1}f}", 42ull, 2), format_error, + "precision not allowed for this argument type"); + EXPECT_THROW_MSG(format("{0:3.{1}}", 'x', 0), format_error, + "precision not allowed for this argument type"); + EXPECT_EQ("1.2", format("{0:.{1}}", 1.2345, 2)); + EXPECT_EQ("1.2", format("{1:.{0}}", 2, 1.2345l)); + + EXPECT_THROW_MSG(format("{0:.{1}}", reinterpret_cast<void*>(0xcafe), 2), + format_error, + "precision not allowed for this argument type"); + EXPECT_THROW_MSG(format("{0:.{1}f}", reinterpret_cast<void*>(0xcafe), 2), + format_error, + "precision not allowed for this argument type"); + + EXPECT_EQ("st", format("{0:.{1}}", "str", 2)); +} + +template <typename T> +void check_unknown_types(const T& value, const char* types, const char*) { + char format_str[BUFFER_SIZE]; + const char* special = ".0123456789}"; + for (int i = CHAR_MIN; i <= CHAR_MAX; ++i) { + char c = static_cast<char>(i); + if (std::strchr(types, c) || std::strchr(special, c) || !c) continue; + safe_sprintf(format_str, "{0:10%c}", c); + const char* message = "invalid type specifier"; + EXPECT_THROW_MSG(format(format_str, value), format_error, message) + << format_str << " " << message; + } +} + +TEST(BoolTest, FormatBool) { + EXPECT_EQ("true", format("{}", true)); + EXPECT_EQ("false", format("{}", false)); + EXPECT_EQ("1", format("{:d}", true)); + EXPECT_EQ("true ", format("{:5}", true)); + EXPECT_EQ(L"true", format(L"{}", true)); +} + +TEST(FormatterTest, FormatShort) { + short s = 42; + EXPECT_EQ("42", format("{0:d}", s)); + unsigned short us = 42; + EXPECT_EQ("42", format("{0:d}", us)); +} + +TEST(FormatterTest, FormatInt) { + EXPECT_THROW_MSG(format("{0:v", 42), format_error, + "missing '}' in format string"); check_unknown_types(42, "bBdoxXnLc", "integer"); EXPECT_EQ("x", format("{:c}", static_cast<int>('x'))); -} - -TEST(FormatterTest, FormatBin) { - EXPECT_EQ("0", format("{0:b}", 0)); - EXPECT_EQ("101010", format("{0:b}", 42)); - EXPECT_EQ("101010", format("{0:b}", 42u)); - EXPECT_EQ("-101010", format("{0:b}", -42)); - EXPECT_EQ("11000000111001", format("{0:b}", 12345)); - EXPECT_EQ("10010001101000101011001111000", format("{0:b}", 0x12345678)); - EXPECT_EQ("10010000101010111100110111101111", format("{0:b}", 0x90ABCDEF)); - EXPECT_EQ("11111111111111111111111111111111", - format("{0:b}", max_value<uint32_t>())); -} - -#if FMT_USE_INT128 -constexpr auto int128_max = static_cast<__int128_t>( - (static_cast<__uint128_t>(1) << ((__SIZEOF_INT128__ * CHAR_BIT) - 1)) - 1); -constexpr auto int128_min = -int128_max - 1; - -constexpr auto uint128_max = ~static_cast<__uint128_t>(0); -#endif - -TEST(FormatterTest, FormatDec) { - EXPECT_EQ("0", format("{0}", 0)); - EXPECT_EQ("42", format("{0}", 42)); - EXPECT_EQ("42", format("{0:d}", 42)); - EXPECT_EQ("42", format("{0}", 42u)); - EXPECT_EQ("-42", format("{0}", -42)); - EXPECT_EQ("12345", format("{0}", 12345)); - EXPECT_EQ("67890", format("{0}", 67890)); -#if FMT_USE_INT128 - EXPECT_EQ("0", format("{0}", static_cast<__int128_t>(0))); - EXPECT_EQ("0", format("{0}", static_cast<__uint128_t>(0))); - EXPECT_EQ("9223372036854775808", - format("{0}", static_cast<__int128_t>(INT64_MAX) + 1)); - EXPECT_EQ("-9223372036854775809", - format("{0}", static_cast<__int128_t>(INT64_MIN) - 1)); - EXPECT_EQ("18446744073709551616", - format("{0}", static_cast<__int128_t>(UINT64_MAX) + 1)); - EXPECT_EQ("170141183460469231731687303715884105727", - format("{0}", int128_max)); - EXPECT_EQ("-170141183460469231731687303715884105728", - format("{0}", int128_min)); - EXPECT_EQ("340282366920938463463374607431768211455", - format("{0}", uint128_max)); -#endif - - char buffer[BUFFER_SIZE]; - safe_sprintf(buffer, "%d", INT_MIN); - EXPECT_EQ(buffer, format("{0}", INT_MIN)); - safe_sprintf(buffer, "%d", INT_MAX); - EXPECT_EQ(buffer, format("{0}", INT_MAX)); - safe_sprintf(buffer, "%u", UINT_MAX); - EXPECT_EQ(buffer, format("{0}", UINT_MAX)); - safe_sprintf(buffer, "%ld", 0 - static_cast<unsigned long>(LONG_MIN)); - EXPECT_EQ(buffer, format("{0}", LONG_MIN)); - safe_sprintf(buffer, "%ld", LONG_MAX); - EXPECT_EQ(buffer, format("{0}", LONG_MAX)); - safe_sprintf(buffer, "%lu", ULONG_MAX); - EXPECT_EQ(buffer, format("{0}", ULONG_MAX)); -} - -TEST(FormatterTest, FormatHex) { - EXPECT_EQ("0", format("{0:x}", 0)); - EXPECT_EQ("42", format("{0:x}", 0x42)); - EXPECT_EQ("42", format("{0:x}", 0x42u)); - EXPECT_EQ("-42", format("{0:x}", -0x42)); - EXPECT_EQ("12345678", format("{0:x}", 0x12345678)); - EXPECT_EQ("90abcdef", format("{0:x}", 0x90abcdef)); - EXPECT_EQ("12345678", format("{0:X}", 0x12345678)); - EXPECT_EQ("90ABCDEF", format("{0:X}", 0x90ABCDEF)); -#if FMT_USE_INT128 - EXPECT_EQ("0", format("{0:x}", static_cast<__int128_t>(0))); - EXPECT_EQ("0", format("{0:x}", static_cast<__uint128_t>(0))); - EXPECT_EQ("8000000000000000", - format("{0:x}", static_cast<__int128_t>(INT64_MAX) + 1)); - EXPECT_EQ("-8000000000000001", - format("{0:x}", static_cast<__int128_t>(INT64_MIN) - 1)); - EXPECT_EQ("10000000000000000", - format("{0:x}", static_cast<__int128_t>(UINT64_MAX) + 1)); - EXPECT_EQ("7fffffffffffffffffffffffffffffff", format("{0:x}", int128_max)); - EXPECT_EQ("-80000000000000000000000000000000", format("{0:x}", int128_min)); - EXPECT_EQ("ffffffffffffffffffffffffffffffff", format("{0:x}", uint128_max)); -#endif - - char buffer[BUFFER_SIZE]; - safe_sprintf(buffer, "-%x", 0 - static_cast<unsigned>(INT_MIN)); - EXPECT_EQ(buffer, format("{0:x}", INT_MIN)); - safe_sprintf(buffer, "%x", INT_MAX); - EXPECT_EQ(buffer, format("{0:x}", INT_MAX)); - safe_sprintf(buffer, "%x", UINT_MAX); - EXPECT_EQ(buffer, format("{0:x}", UINT_MAX)); - safe_sprintf(buffer, "-%lx", 0 - static_cast<unsigned long>(LONG_MIN)); - EXPECT_EQ(buffer, format("{0:x}", LONG_MIN)); - safe_sprintf(buffer, "%lx", LONG_MAX); - EXPECT_EQ(buffer, format("{0:x}", LONG_MAX)); - safe_sprintf(buffer, "%lx", ULONG_MAX); - EXPECT_EQ(buffer, format("{0:x}", ULONG_MAX)); -} - -TEST(FormatterTest, FormatOct) { - EXPECT_EQ("0", format("{0:o}", 0)); - EXPECT_EQ("42", format("{0:o}", 042)); - EXPECT_EQ("42", format("{0:o}", 042u)); - EXPECT_EQ("-42", format("{0:o}", -042)); - EXPECT_EQ("12345670", format("{0:o}", 012345670)); -#if FMT_USE_INT128 - EXPECT_EQ("0", format("{0:o}", static_cast<__int128_t>(0))); - EXPECT_EQ("0", format("{0:o}", static_cast<__uint128_t>(0))); - EXPECT_EQ("1000000000000000000000", - format("{0:o}", static_cast<__int128_t>(INT64_MAX) + 1)); - EXPECT_EQ("-1000000000000000000001", - format("{0:o}", static_cast<__int128_t>(INT64_MIN) - 1)); - EXPECT_EQ("2000000000000000000000", - format("{0:o}", static_cast<__int128_t>(UINT64_MAX) + 1)); - EXPECT_EQ("1777777777777777777777777777777777777777777", - format("{0:o}", int128_max)); - EXPECT_EQ("-2000000000000000000000000000000000000000000", - format("{0:o}", int128_min)); - EXPECT_EQ("3777777777777777777777777777777777777777777", - format("{0:o}", uint128_max)); -#endif - - char buffer[BUFFER_SIZE]; - safe_sprintf(buffer, "-%o", 0 - static_cast<unsigned>(INT_MIN)); - EXPECT_EQ(buffer, format("{0:o}", INT_MIN)); - safe_sprintf(buffer, "%o", INT_MAX); - EXPECT_EQ(buffer, format("{0:o}", INT_MAX)); - safe_sprintf(buffer, "%o", UINT_MAX); - EXPECT_EQ(buffer, format("{0:o}", UINT_MAX)); - safe_sprintf(buffer, "-%lo", 0 - static_cast<unsigned long>(LONG_MIN)); - EXPECT_EQ(buffer, format("{0:o}", LONG_MIN)); - safe_sprintf(buffer, "%lo", LONG_MAX); - EXPECT_EQ(buffer, format("{0:o}", LONG_MAX)); - safe_sprintf(buffer, "%lo", ULONG_MAX); - EXPECT_EQ(buffer, format("{0:o}", ULONG_MAX)); -} - -TEST(FormatterTest, FormatIntLocale) { - EXPECT_EQ("1234", format("{:L}", 1234)); -} - -struct ConvertibleToLongLong { - operator long long() const { return 1LL << 32; } -}; - -TEST(FormatterTest, FormatConvertibleToLongLong) { - EXPECT_EQ("100000000", format("{:x}", ConvertibleToLongLong())); -} - -TEST(FormatterTest, FormatFloat) { +} + +TEST(FormatterTest, FormatBin) { + EXPECT_EQ("0", format("{0:b}", 0)); + EXPECT_EQ("101010", format("{0:b}", 42)); + EXPECT_EQ("101010", format("{0:b}", 42u)); + EXPECT_EQ("-101010", format("{0:b}", -42)); + EXPECT_EQ("11000000111001", format("{0:b}", 12345)); + EXPECT_EQ("10010001101000101011001111000", format("{0:b}", 0x12345678)); + EXPECT_EQ("10010000101010111100110111101111", format("{0:b}", 0x90ABCDEF)); + EXPECT_EQ("11111111111111111111111111111111", + format("{0:b}", max_value<uint32_t>())); +} + +#if FMT_USE_INT128 +constexpr auto int128_max = static_cast<__int128_t>( + (static_cast<__uint128_t>(1) << ((__SIZEOF_INT128__ * CHAR_BIT) - 1)) - 1); +constexpr auto int128_min = -int128_max - 1; + +constexpr auto uint128_max = ~static_cast<__uint128_t>(0); +#endif + +TEST(FormatterTest, FormatDec) { + EXPECT_EQ("0", format("{0}", 0)); + EXPECT_EQ("42", format("{0}", 42)); + EXPECT_EQ("42", format("{0:d}", 42)); + EXPECT_EQ("42", format("{0}", 42u)); + EXPECT_EQ("-42", format("{0}", -42)); + EXPECT_EQ("12345", format("{0}", 12345)); + EXPECT_EQ("67890", format("{0}", 67890)); +#if FMT_USE_INT128 + EXPECT_EQ("0", format("{0}", static_cast<__int128_t>(0))); + EXPECT_EQ("0", format("{0}", static_cast<__uint128_t>(0))); + EXPECT_EQ("9223372036854775808", + format("{0}", static_cast<__int128_t>(INT64_MAX) + 1)); + EXPECT_EQ("-9223372036854775809", + format("{0}", static_cast<__int128_t>(INT64_MIN) - 1)); + EXPECT_EQ("18446744073709551616", + format("{0}", static_cast<__int128_t>(UINT64_MAX) + 1)); + EXPECT_EQ("170141183460469231731687303715884105727", + format("{0}", int128_max)); + EXPECT_EQ("-170141183460469231731687303715884105728", + format("{0}", int128_min)); + EXPECT_EQ("340282366920938463463374607431768211455", + format("{0}", uint128_max)); +#endif + + char buffer[BUFFER_SIZE]; + safe_sprintf(buffer, "%d", INT_MIN); + EXPECT_EQ(buffer, format("{0}", INT_MIN)); + safe_sprintf(buffer, "%d", INT_MAX); + EXPECT_EQ(buffer, format("{0}", INT_MAX)); + safe_sprintf(buffer, "%u", UINT_MAX); + EXPECT_EQ(buffer, format("{0}", UINT_MAX)); + safe_sprintf(buffer, "%ld", 0 - static_cast<unsigned long>(LONG_MIN)); + EXPECT_EQ(buffer, format("{0}", LONG_MIN)); + safe_sprintf(buffer, "%ld", LONG_MAX); + EXPECT_EQ(buffer, format("{0}", LONG_MAX)); + safe_sprintf(buffer, "%lu", ULONG_MAX); + EXPECT_EQ(buffer, format("{0}", ULONG_MAX)); +} + +TEST(FormatterTest, FormatHex) { + EXPECT_EQ("0", format("{0:x}", 0)); + EXPECT_EQ("42", format("{0:x}", 0x42)); + EXPECT_EQ("42", format("{0:x}", 0x42u)); + EXPECT_EQ("-42", format("{0:x}", -0x42)); + EXPECT_EQ("12345678", format("{0:x}", 0x12345678)); + EXPECT_EQ("90abcdef", format("{0:x}", 0x90abcdef)); + EXPECT_EQ("12345678", format("{0:X}", 0x12345678)); + EXPECT_EQ("90ABCDEF", format("{0:X}", 0x90ABCDEF)); +#if FMT_USE_INT128 + EXPECT_EQ("0", format("{0:x}", static_cast<__int128_t>(0))); + EXPECT_EQ("0", format("{0:x}", static_cast<__uint128_t>(0))); + EXPECT_EQ("8000000000000000", + format("{0:x}", static_cast<__int128_t>(INT64_MAX) + 1)); + EXPECT_EQ("-8000000000000001", + format("{0:x}", static_cast<__int128_t>(INT64_MIN) - 1)); + EXPECT_EQ("10000000000000000", + format("{0:x}", static_cast<__int128_t>(UINT64_MAX) + 1)); + EXPECT_EQ("7fffffffffffffffffffffffffffffff", format("{0:x}", int128_max)); + EXPECT_EQ("-80000000000000000000000000000000", format("{0:x}", int128_min)); + EXPECT_EQ("ffffffffffffffffffffffffffffffff", format("{0:x}", uint128_max)); +#endif + + char buffer[BUFFER_SIZE]; + safe_sprintf(buffer, "-%x", 0 - static_cast<unsigned>(INT_MIN)); + EXPECT_EQ(buffer, format("{0:x}", INT_MIN)); + safe_sprintf(buffer, "%x", INT_MAX); + EXPECT_EQ(buffer, format("{0:x}", INT_MAX)); + safe_sprintf(buffer, "%x", UINT_MAX); + EXPECT_EQ(buffer, format("{0:x}", UINT_MAX)); + safe_sprintf(buffer, "-%lx", 0 - static_cast<unsigned long>(LONG_MIN)); + EXPECT_EQ(buffer, format("{0:x}", LONG_MIN)); + safe_sprintf(buffer, "%lx", LONG_MAX); + EXPECT_EQ(buffer, format("{0:x}", LONG_MAX)); + safe_sprintf(buffer, "%lx", ULONG_MAX); + EXPECT_EQ(buffer, format("{0:x}", ULONG_MAX)); +} + +TEST(FormatterTest, FormatOct) { + EXPECT_EQ("0", format("{0:o}", 0)); + EXPECT_EQ("42", format("{0:o}", 042)); + EXPECT_EQ("42", format("{0:o}", 042u)); + EXPECT_EQ("-42", format("{0:o}", -042)); + EXPECT_EQ("12345670", format("{0:o}", 012345670)); +#if FMT_USE_INT128 + EXPECT_EQ("0", format("{0:o}", static_cast<__int128_t>(0))); + EXPECT_EQ("0", format("{0:o}", static_cast<__uint128_t>(0))); + EXPECT_EQ("1000000000000000000000", + format("{0:o}", static_cast<__int128_t>(INT64_MAX) + 1)); + EXPECT_EQ("-1000000000000000000001", + format("{0:o}", static_cast<__int128_t>(INT64_MIN) - 1)); + EXPECT_EQ("2000000000000000000000", + format("{0:o}", static_cast<__int128_t>(UINT64_MAX) + 1)); + EXPECT_EQ("1777777777777777777777777777777777777777777", + format("{0:o}", int128_max)); + EXPECT_EQ("-2000000000000000000000000000000000000000000", + format("{0:o}", int128_min)); + EXPECT_EQ("3777777777777777777777777777777777777777777", + format("{0:o}", uint128_max)); +#endif + + char buffer[BUFFER_SIZE]; + safe_sprintf(buffer, "-%o", 0 - static_cast<unsigned>(INT_MIN)); + EXPECT_EQ(buffer, format("{0:o}", INT_MIN)); + safe_sprintf(buffer, "%o", INT_MAX); + EXPECT_EQ(buffer, format("{0:o}", INT_MAX)); + safe_sprintf(buffer, "%o", UINT_MAX); + EXPECT_EQ(buffer, format("{0:o}", UINT_MAX)); + safe_sprintf(buffer, "-%lo", 0 - static_cast<unsigned long>(LONG_MIN)); + EXPECT_EQ(buffer, format("{0:o}", LONG_MIN)); + safe_sprintf(buffer, "%lo", LONG_MAX); + EXPECT_EQ(buffer, format("{0:o}", LONG_MAX)); + safe_sprintf(buffer, "%lo", ULONG_MAX); + EXPECT_EQ(buffer, format("{0:o}", ULONG_MAX)); +} + +TEST(FormatterTest, FormatIntLocale) { + EXPECT_EQ("1234", format("{:L}", 1234)); +} + +struct ConvertibleToLongLong { + operator long long() const { return 1LL << 32; } +}; + +TEST(FormatterTest, FormatConvertibleToLongLong) { + EXPECT_EQ("100000000", format("{:x}", ConvertibleToLongLong())); +} + +TEST(FormatterTest, FormatFloat) { EXPECT_EQ("0", format("{}", 0.0f)); - EXPECT_EQ("392.500000", format("{0:f}", 392.5f)); -} - -TEST(FormatterTest, FormatDouble) { + EXPECT_EQ("392.500000", format("{0:f}", 392.5f)); +} + +TEST(FormatterTest, FormatDouble) { EXPECT_EQ("0", format("{}", 0.0)); check_unknown_types(1.2, "eEfFgGaAnL%", "double"); EXPECT_EQ("0", format("{:}", 0.0)); - EXPECT_EQ("0.000000", format("{:f}", 0.0)); - EXPECT_EQ("0", format("{:g}", 0.0)); - EXPECT_EQ("392.65", format("{:}", 392.65)); - EXPECT_EQ("392.65", format("{:g}", 392.65)); - EXPECT_EQ("392.65", format("{:G}", 392.65)); + EXPECT_EQ("0.000000", format("{:f}", 0.0)); + EXPECT_EQ("0", format("{:g}", 0.0)); + EXPECT_EQ("392.65", format("{:}", 392.65)); + EXPECT_EQ("392.65", format("{:g}", 392.65)); + EXPECT_EQ("392.65", format("{:G}", 392.65)); EXPECT_EQ("4.9014e+06", format("{:g}", 4.9014e6)); - EXPECT_EQ("392.650000", format("{:f}", 392.65)); - EXPECT_EQ("392.650000", format("{:F}", 392.65)); + EXPECT_EQ("392.650000", format("{:f}", 392.65)); + EXPECT_EQ("392.650000", format("{:F}", 392.65)); EXPECT_EQ("42", format("{:L}", 42.0)); - char buffer[BUFFER_SIZE]; - safe_sprintf(buffer, "%e", 392.65); - EXPECT_EQ(buffer, format("{0:e}", 392.65)); - safe_sprintf(buffer, "%E", 392.65); - EXPECT_EQ(buffer, format("{0:E}", 392.65)); - EXPECT_EQ("+0000392.6", format("{0:+010.4g}", 392.65)); - safe_sprintf(buffer, "%a", -42.0); - EXPECT_EQ(buffer, format("{:a}", -42.0)); - safe_sprintf(buffer, "%A", -42.0); - EXPECT_EQ(buffer, format("{:A}", -42.0)); + char buffer[BUFFER_SIZE]; + safe_sprintf(buffer, "%e", 392.65); + EXPECT_EQ(buffer, format("{0:e}", 392.65)); + safe_sprintf(buffer, "%E", 392.65); + EXPECT_EQ(buffer, format("{0:E}", 392.65)); + EXPECT_EQ("+0000392.6", format("{0:+010.4g}", 392.65)); + safe_sprintf(buffer, "%a", -42.0); + EXPECT_EQ(buffer, format("{:a}", -42.0)); + safe_sprintf(buffer, "%A", -42.0); + EXPECT_EQ(buffer, format("{:A}", -42.0)); EXPECT_EQ("9223372036854775808.000000", format("{:f}", 9223372036854775807.0)); -} - -TEST(FormatterTest, PrecisionRounding) { - EXPECT_EQ("0", format("{:.0f}", 0.0)); - EXPECT_EQ("0", format("{:.0f}", 0.01)); - EXPECT_EQ("0", format("{:.0f}", 0.1)); - EXPECT_EQ("0.000", format("{:.3f}", 0.00049)); - EXPECT_EQ("0.001", format("{:.3f}", 0.0005)); - EXPECT_EQ("0.001", format("{:.3f}", 0.00149)); - EXPECT_EQ("0.002", format("{:.3f}", 0.0015)); - EXPECT_EQ("1.000", format("{:.3f}", 0.9999)); - EXPECT_EQ("0.00123", format("{:.3}", 0.00123)); - EXPECT_EQ("0.1", format("{:.16g}", 0.1)); +} + +TEST(FormatterTest, PrecisionRounding) { + EXPECT_EQ("0", format("{:.0f}", 0.0)); + EXPECT_EQ("0", format("{:.0f}", 0.01)); + EXPECT_EQ("0", format("{:.0f}", 0.1)); + EXPECT_EQ("0.000", format("{:.3f}", 0.00049)); + EXPECT_EQ("0.001", format("{:.3f}", 0.0005)); + EXPECT_EQ("0.001", format("{:.3f}", 0.00149)); + EXPECT_EQ("0.002", format("{:.3f}", 0.0015)); + EXPECT_EQ("1.000", format("{:.3f}", 0.9999)); + EXPECT_EQ("0.00123", format("{:.3}", 0.00123)); + EXPECT_EQ("0.1", format("{:.16g}", 0.1)); EXPECT_EQ("1", fmt::format("{:.0}", 1.0)); EXPECT_EQ("225.51575035152063720", fmt::format("{:.17f}", 225.51575035152064)); @@ -1295,8 +1295,8 @@ TEST(FormatterTest, PrecisionRounding) { // Trigger a rounding error in Grisu by a specially chosen number. EXPECT_EQ("3788512123356.985352", format("{:f}", 3788512123356.985352)); -} - +} + TEST(FormatterTest, PrettifyFloat) { EXPECT_EQ("0.0001", fmt::format("{}", 1e-4)); EXPECT_EQ("1e-05", fmt::format("{}", 1e-5)); @@ -1313,166 +1313,166 @@ TEST(FormatterTest, PrettifyFloat) { EXPECT_EQ("1.3563156e-19", fmt::format("{}", 1.35631564e-19f)); } -TEST(FormatterTest, FormatNaN) { - double nan = std::numeric_limits<double>::quiet_NaN(); - EXPECT_EQ("nan", format("{}", nan)); - EXPECT_EQ("+nan", format("{:+}", nan)); +TEST(FormatterTest, FormatNaN) { + double nan = std::numeric_limits<double>::quiet_NaN(); + EXPECT_EQ("nan", format("{}", nan)); + EXPECT_EQ("+nan", format("{:+}", nan)); if (std::signbit(-nan)) EXPECT_EQ("-nan", format("{}", -nan)); else fmt::print("Warning: compiler doesn't handle negative NaN correctly"); - EXPECT_EQ(" nan", format("{: }", nan)); - EXPECT_EQ("NAN", format("{:F}", nan)); - EXPECT_EQ("nan ", format("{:<7}", nan)); - EXPECT_EQ(" nan ", format("{:^7}", nan)); - EXPECT_EQ(" nan", format("{:>7}", nan)); -} - -TEST(FormatterTest, FormatInfinity) { - double inf = std::numeric_limits<double>::infinity(); - EXPECT_EQ("inf", format("{}", inf)); - EXPECT_EQ("+inf", format("{:+}", inf)); - EXPECT_EQ("-inf", format("{}", -inf)); - EXPECT_EQ(" inf", format("{: }", inf)); - EXPECT_EQ("INF", format("{:F}", inf)); - EXPECT_EQ("inf ", format("{:<7}", inf)); - EXPECT_EQ(" inf ", format("{:^7}", inf)); - EXPECT_EQ(" inf", format("{:>7}", inf)); -} - -TEST(FormatterTest, FormatLongDouble) { + EXPECT_EQ(" nan", format("{: }", nan)); + EXPECT_EQ("NAN", format("{:F}", nan)); + EXPECT_EQ("nan ", format("{:<7}", nan)); + EXPECT_EQ(" nan ", format("{:^7}", nan)); + EXPECT_EQ(" nan", format("{:>7}", nan)); +} + +TEST(FormatterTest, FormatInfinity) { + double inf = std::numeric_limits<double>::infinity(); + EXPECT_EQ("inf", format("{}", inf)); + EXPECT_EQ("+inf", format("{:+}", inf)); + EXPECT_EQ("-inf", format("{}", -inf)); + EXPECT_EQ(" inf", format("{: }", inf)); + EXPECT_EQ("INF", format("{:F}", inf)); + EXPECT_EQ("inf ", format("{:<7}", inf)); + EXPECT_EQ(" inf ", format("{:^7}", inf)); + EXPECT_EQ(" inf", format("{:>7}", inf)); +} + +TEST(FormatterTest, FormatLongDouble) { EXPECT_EQ("0", format("{0:}", 0.0l)); - EXPECT_EQ("0.000000", format("{0:f}", 0.0l)); - EXPECT_EQ("392.65", format("{0:}", 392.65l)); - EXPECT_EQ("392.65", format("{0:g}", 392.65l)); - EXPECT_EQ("392.65", format("{0:G}", 392.65l)); - EXPECT_EQ("392.650000", format("{0:f}", 392.65l)); - EXPECT_EQ("392.650000", format("{0:F}", 392.65l)); - char buffer[BUFFER_SIZE]; - safe_sprintf(buffer, "%Le", 392.65l); - EXPECT_EQ(buffer, format("{0:e}", 392.65l)); - EXPECT_EQ("+0000392.6", format("{0:+010.4g}", 392.64l)); - safe_sprintf(buffer, "%La", 3.31l); - EXPECT_EQ(buffer, format("{:a}", 3.31l)); -} - -TEST(FormatterTest, FormatChar) { + EXPECT_EQ("0.000000", format("{0:f}", 0.0l)); + EXPECT_EQ("392.65", format("{0:}", 392.65l)); + EXPECT_EQ("392.65", format("{0:g}", 392.65l)); + EXPECT_EQ("392.65", format("{0:G}", 392.65l)); + EXPECT_EQ("392.650000", format("{0:f}", 392.65l)); + EXPECT_EQ("392.650000", format("{0:F}", 392.65l)); + char buffer[BUFFER_SIZE]; + safe_sprintf(buffer, "%Le", 392.65l); + EXPECT_EQ(buffer, format("{0:e}", 392.65l)); + EXPECT_EQ("+0000392.6", format("{0:+010.4g}", 392.64l)); + safe_sprintf(buffer, "%La", 3.31l); + EXPECT_EQ(buffer, format("{:a}", 3.31l)); +} + +TEST(FormatterTest, FormatChar) { const char types[] = "cbBdoxXL"; - check_unknown_types('a', types, "char"); - EXPECT_EQ("a", format("{0}", 'a')); - EXPECT_EQ("z", format("{0:c}", 'z')); - EXPECT_EQ(L"a", format(L"{0}", 'a')); - int n = 'x'; - for (const char* type = types + 1; *type; ++type) { - std::string format_str = fmt::format("{{:{}}}", *type); - EXPECT_EQ(fmt::format(format_str, n), fmt::format(format_str, 'x')); - } - EXPECT_EQ(fmt::format("{:02X}", n), fmt::format("{:02X}", 'x')); -} - -TEST(FormatterTest, FormatVolatileChar) { - volatile char c = 'x'; - EXPECT_EQ("x", format("{}", c)); -} - -TEST(FormatterTest, FormatUnsignedChar) { - EXPECT_EQ("42", format("{}", static_cast<unsigned char>(42))); - EXPECT_EQ("42", format("{}", static_cast<uint8_t>(42))); -} - -TEST(FormatterTest, FormatWChar) { - EXPECT_EQ(L"a", format(L"{0}", L'a')); - // This shouldn't compile: - // format("{}", L'a'); -} - -TEST(FormatterTest, FormatCString) { - check_unknown_types("test", "sp", "string"); - EXPECT_EQ("test", format("{0}", "test")); - EXPECT_EQ("test", format("{0:s}", "test")); - char nonconst[] = "nonconst"; - EXPECT_EQ("nonconst", format("{0}", nonconst)); - EXPECT_THROW_MSG(format("{0}", static_cast<const char*>(nullptr)), - format_error, "string pointer is null"); -} - -TEST(FormatterTest, FormatSCharString) { - signed char str[] = "test"; - EXPECT_EQ("test", format("{0:s}", str)); - const signed char* const_str = str; - EXPECT_EQ("test", format("{0:s}", const_str)); -} - -TEST(FormatterTest, FormatUCharString) { - unsigned char str[] = "test"; - EXPECT_EQ("test", format("{0:s}", str)); - const unsigned char* const_str = str; - EXPECT_EQ("test", format("{0:s}", const_str)); - unsigned char* ptr = str; - EXPECT_EQ("test", format("{0:s}", ptr)); -} - -TEST(FormatterTest, FormatPointer) { - check_unknown_types(reinterpret_cast<void*>(0x1234), "p", "pointer"); - EXPECT_EQ("0x0", format("{0}", static_cast<void*>(nullptr))); - EXPECT_EQ("0x1234", format("{0}", reinterpret_cast<void*>(0x1234))); - EXPECT_EQ("0x1234", format("{0:p}", reinterpret_cast<void*>(0x1234))); - EXPECT_EQ("0x" + std::string(sizeof(void*) * CHAR_BIT / 4, 'f'), - format("{0}", reinterpret_cast<void*>(~uintptr_t()))); - EXPECT_EQ("0x1234", format("{}", fmt::ptr(reinterpret_cast<int*>(0x1234)))); - std::unique_ptr<int> up(new int(1)); - EXPECT_EQ(format("{}", fmt::ptr(up.get())), format("{}", fmt::ptr(up))); - std::shared_ptr<int> sp(new int(1)); - EXPECT_EQ(format("{}", fmt::ptr(sp.get())), format("{}", fmt::ptr(sp))); - EXPECT_EQ("0x0", format("{}", nullptr)); -} - -TEST(FormatterTest, FormatString) { - EXPECT_EQ("test", format("{0}", std::string("test"))); -} - -TEST(FormatterTest, FormatStringView) { - EXPECT_EQ("test", format("{}", string_view("test"))); - EXPECT_EQ("", format("{}", string_view())); -} - -#ifdef FMT_USE_STRING_VIEW -struct string_viewable {}; - -FMT_BEGIN_NAMESPACE -template <> struct formatter<string_viewable> : formatter<std::string_view> { - auto format(string_viewable, format_context& ctx) -> decltype(ctx.out()) { - return formatter<std::string_view>::format("foo", ctx); - } -}; -FMT_END_NAMESPACE - -TEST(FormatterTest, FormatStdStringView) { - EXPECT_EQ("test", format("{}", std::string_view("test"))); - EXPECT_EQ("foo", format("{}", string_viewable())); -} - -struct explicitly_convertible_to_std_string_view { - explicit operator std::string_view() const { return "foo"; } -}; - -namespace fmt { -template <> -struct formatter<explicitly_convertible_to_std_string_view> - : formatter<std::string_view> { - auto format(const explicitly_convertible_to_std_string_view& v, - format_context& ctx) -> decltype(ctx.out()) { - return format_to(ctx.out(), "'{}'", std::string_view(v)); - } -}; -} // namespace fmt - -TEST(FormatterTest, FormatExplicitlyConvertibleToStdStringView) { - EXPECT_EQ("'foo'", - fmt::format("{}", explicitly_convertible_to_std_string_view())); -} -#endif - + check_unknown_types('a', types, "char"); + EXPECT_EQ("a", format("{0}", 'a')); + EXPECT_EQ("z", format("{0:c}", 'z')); + EXPECT_EQ(L"a", format(L"{0}", 'a')); + int n = 'x'; + for (const char* type = types + 1; *type; ++type) { + std::string format_str = fmt::format("{{:{}}}", *type); + EXPECT_EQ(fmt::format(format_str, n), fmt::format(format_str, 'x')); + } + EXPECT_EQ(fmt::format("{:02X}", n), fmt::format("{:02X}", 'x')); +} + +TEST(FormatterTest, FormatVolatileChar) { + volatile char c = 'x'; + EXPECT_EQ("x", format("{}", c)); +} + +TEST(FormatterTest, FormatUnsignedChar) { + EXPECT_EQ("42", format("{}", static_cast<unsigned char>(42))); + EXPECT_EQ("42", format("{}", static_cast<uint8_t>(42))); +} + +TEST(FormatterTest, FormatWChar) { + EXPECT_EQ(L"a", format(L"{0}", L'a')); + // This shouldn't compile: + // format("{}", L'a'); +} + +TEST(FormatterTest, FormatCString) { + check_unknown_types("test", "sp", "string"); + EXPECT_EQ("test", format("{0}", "test")); + EXPECT_EQ("test", format("{0:s}", "test")); + char nonconst[] = "nonconst"; + EXPECT_EQ("nonconst", format("{0}", nonconst)); + EXPECT_THROW_MSG(format("{0}", static_cast<const char*>(nullptr)), + format_error, "string pointer is null"); +} + +TEST(FormatterTest, FormatSCharString) { + signed char str[] = "test"; + EXPECT_EQ("test", format("{0:s}", str)); + const signed char* const_str = str; + EXPECT_EQ("test", format("{0:s}", const_str)); +} + +TEST(FormatterTest, FormatUCharString) { + unsigned char str[] = "test"; + EXPECT_EQ("test", format("{0:s}", str)); + const unsigned char* const_str = str; + EXPECT_EQ("test", format("{0:s}", const_str)); + unsigned char* ptr = str; + EXPECT_EQ("test", format("{0:s}", ptr)); +} + +TEST(FormatterTest, FormatPointer) { + check_unknown_types(reinterpret_cast<void*>(0x1234), "p", "pointer"); + EXPECT_EQ("0x0", format("{0}", static_cast<void*>(nullptr))); + EXPECT_EQ("0x1234", format("{0}", reinterpret_cast<void*>(0x1234))); + EXPECT_EQ("0x1234", format("{0:p}", reinterpret_cast<void*>(0x1234))); + EXPECT_EQ("0x" + std::string(sizeof(void*) * CHAR_BIT / 4, 'f'), + format("{0}", reinterpret_cast<void*>(~uintptr_t()))); + EXPECT_EQ("0x1234", format("{}", fmt::ptr(reinterpret_cast<int*>(0x1234)))); + std::unique_ptr<int> up(new int(1)); + EXPECT_EQ(format("{}", fmt::ptr(up.get())), format("{}", fmt::ptr(up))); + std::shared_ptr<int> sp(new int(1)); + EXPECT_EQ(format("{}", fmt::ptr(sp.get())), format("{}", fmt::ptr(sp))); + EXPECT_EQ("0x0", format("{}", nullptr)); +} + +TEST(FormatterTest, FormatString) { + EXPECT_EQ("test", format("{0}", std::string("test"))); +} + +TEST(FormatterTest, FormatStringView) { + EXPECT_EQ("test", format("{}", string_view("test"))); + EXPECT_EQ("", format("{}", string_view())); +} + +#ifdef FMT_USE_STRING_VIEW +struct string_viewable {}; + +FMT_BEGIN_NAMESPACE +template <> struct formatter<string_viewable> : formatter<std::string_view> { + auto format(string_viewable, format_context& ctx) -> decltype(ctx.out()) { + return formatter<std::string_view>::format("foo", ctx); + } +}; +FMT_END_NAMESPACE + +TEST(FormatterTest, FormatStdStringView) { + EXPECT_EQ("test", format("{}", std::string_view("test"))); + EXPECT_EQ("foo", format("{}", string_viewable())); +} + +struct explicitly_convertible_to_std_string_view { + explicit operator std::string_view() const { return "foo"; } +}; + +namespace fmt { +template <> +struct formatter<explicitly_convertible_to_std_string_view> + : formatter<std::string_view> { + auto format(const explicitly_convertible_to_std_string_view& v, + format_context& ctx) -> decltype(ctx.out()) { + return format_to(ctx.out(), "'{}'", std::string_view(v)); + } +}; +} // namespace fmt + +TEST(FormatterTest, FormatExplicitlyConvertibleToStdStringView) { + EXPECT_EQ("'foo'", + fmt::format("{}", explicitly_convertible_to_std_string_view())); +} +#endif + // std::is_constructible is broken in MSVC until version 2015. #if !FMT_MSC_VER || FMT_MSC_VER >= 1900 struct explicitly_convertible_to_wstring_view { @@ -1507,390 +1507,390 @@ TEST(FormatTest, FormatForeignStrings) { EXPECT_EQ(fmt::format(QString(L"{}"), QString(L"42")), L"42"); } -FMT_BEGIN_NAMESPACE -template <> struct formatter<Date> { - template <typename ParseContext> - FMT_CONSTEXPR auto parse(ParseContext& ctx) -> decltype(ctx.begin()) { - auto it = ctx.begin(); +FMT_BEGIN_NAMESPACE +template <> struct formatter<Date> { + template <typename ParseContext> + FMT_CONSTEXPR auto parse(ParseContext& ctx) -> decltype(ctx.begin()) { + auto it = ctx.begin(); if (it != ctx.end() && *it == 'd') ++it; - return it; - } - - auto format(const Date& d, format_context& ctx) -> decltype(ctx.out()) { - format_to(ctx.out(), "{}-{}-{}", d.year(), d.month(), d.day()); - return ctx.out(); - } -}; -FMT_END_NAMESPACE - -TEST(FormatterTest, FormatCustom) { - Date date(2012, 12, 9); - EXPECT_THROW_MSG(fmt::format("{:s}", date), format_error, - "unknown format specifier"); -} - -class Answer {}; - -FMT_BEGIN_NAMESPACE -template <> struct formatter<Answer> : formatter<int> { - template <typename FormatContext> - auto format(Answer, FormatContext& ctx) -> decltype(ctx.out()) { - return formatter<int>::format(42, ctx); - } -}; -FMT_END_NAMESPACE - -TEST(FormatterTest, CustomFormat) { - EXPECT_EQ("42", format("{0}", Answer())); - EXPECT_EQ("0042", format("{:04}", Answer())); -} - -TEST(FormatterTest, CustomFormatTo) { - char buf[10] = {}; - auto end = + return it; + } + + auto format(const Date& d, format_context& ctx) -> decltype(ctx.out()) { + format_to(ctx.out(), "{}-{}-{}", d.year(), d.month(), d.day()); + return ctx.out(); + } +}; +FMT_END_NAMESPACE + +TEST(FormatterTest, FormatCustom) { + Date date(2012, 12, 9); + EXPECT_THROW_MSG(fmt::format("{:s}", date), format_error, + "unknown format specifier"); +} + +class Answer {}; + +FMT_BEGIN_NAMESPACE +template <> struct formatter<Answer> : formatter<int> { + template <typename FormatContext> + auto format(Answer, FormatContext& ctx) -> decltype(ctx.out()) { + return formatter<int>::format(42, ctx); + } +}; +FMT_END_NAMESPACE + +TEST(FormatterTest, CustomFormat) { + EXPECT_EQ("42", format("{0}", Answer())); + EXPECT_EQ("0042", format("{:04}", Answer())); +} + +TEST(FormatterTest, CustomFormatTo) { + char buf[10] = {}; + auto end = &*fmt::format_to(fmt::detail::make_checked(buf, 10), "{}", Answer()); - EXPECT_EQ(end, buf + 2); - EXPECT_STREQ(buf, "42"); -} - -TEST(FormatterTest, WideFormatString) { - EXPECT_EQ(L"42", format(L"{}", 42)); - EXPECT_EQ(L"4.2", format(L"{}", 4.2)); - EXPECT_EQ(L"abc", format(L"{}", L"abc")); - EXPECT_EQ(L"z", format(L"{}", L'z')); + EXPECT_EQ(end, buf + 2); + EXPECT_STREQ(buf, "42"); +} + +TEST(FormatterTest, WideFormatString) { + EXPECT_EQ(L"42", format(L"{}", 42)); + EXPECT_EQ(L"4.2", format(L"{}", 4.2)); + EXPECT_EQ(L"abc", format(L"{}", L"abc")); + EXPECT_EQ(L"z", format(L"{}", L'z')); EXPECT_THROW(fmt::format(L"{:*\x343E}", 42), fmt::format_error); -} - -TEST(FormatterTest, FormatStringFromSpeedTest) { - EXPECT_EQ("1.2340000000:0042:+3.13:str:0x3e8:X:%", - format("{0:0.10f}:{1:04}:{2:+g}:{3}:{4}:{5}:%", 1.234, 42, 3.13, - "str", reinterpret_cast<void*>(1000), 'X')); -} - -TEST(FormatterTest, FormatExamples) { - std::string message = format("The answer is {}", 42); - EXPECT_EQ("The answer is 42", message); - - EXPECT_EQ("42", format("{}", 42)); - EXPECT_EQ("42", format(std::string("{}"), 42)); - - memory_buffer out; - format_to(out, "The answer is {}.", 42); - EXPECT_EQ("The answer is 42.", to_string(out)); - - const char* filename = "nonexistent"; - FILE* ftest = safe_fopen(filename, "r"); - if (ftest) fclose(ftest); - int error_code = errno; - EXPECT_TRUE(ftest == nullptr); - EXPECT_SYSTEM_ERROR( - { - FILE* f = safe_fopen(filename, "r"); - if (!f) - throw fmt::system_error(errno, "Cannot open file '{}'", filename); - fclose(f); - }, - error_code, "Cannot open file 'nonexistent'"); -} - -TEST(FormatterTest, Examples) { - EXPECT_EQ("First, thou shalt count to three", - format("First, thou shalt count to {0}", "three")); - EXPECT_EQ("Bring me a shrubbery", format("Bring me a {}", "shrubbery")); - EXPECT_EQ("From 1 to 3", format("From {} to {}", 1, 3)); - - char buffer[BUFFER_SIZE]; - safe_sprintf(buffer, "%03.2f", -1.2); - EXPECT_EQ(buffer, format("{:03.2f}", -1.2)); - - EXPECT_EQ("a, b, c", format("{0}, {1}, {2}", 'a', 'b', 'c')); - EXPECT_EQ("a, b, c", format("{}, {}, {}", 'a', 'b', 'c')); - EXPECT_EQ("c, b, a", format("{2}, {1}, {0}", 'a', 'b', 'c')); - EXPECT_EQ("abracadabra", format("{0}{1}{0}", "abra", "cad")); - - EXPECT_EQ("left aligned ", format("{:<30}", "left aligned")); - EXPECT_EQ(" right aligned", - format("{:>30}", "right aligned")); - EXPECT_EQ(" centered ", format("{:^30}", "centered")); - EXPECT_EQ("***********centered***********", format("{:*^30}", "centered")); - - EXPECT_EQ("+3.140000; -3.140000", format("{:+f}; {:+f}", 3.14, -3.14)); - EXPECT_EQ(" 3.140000; -3.140000", format("{: f}; {: f}", 3.14, -3.14)); - EXPECT_EQ("3.140000; -3.140000", format("{:-f}; {:-f}", 3.14, -3.14)); - - EXPECT_EQ("int: 42; hex: 2a; oct: 52", - format("int: {0:d}; hex: {0:x}; oct: {0:o}", 42)); - EXPECT_EQ("int: 42; hex: 0x2a; oct: 052", - format("int: {0:d}; hex: {0:#x}; oct: {0:#o}", 42)); - - EXPECT_EQ("The answer is 42", format("The answer is {}", 42)); - EXPECT_THROW_MSG(format("The answer is {:d}", "forty-two"), format_error, - "invalid type specifier"); - - EXPECT_EQ(L"Cyrillic letter \x42e", format(L"Cyrillic letter {}", L'\x42e')); - - EXPECT_WRITE( - stdout, fmt::print("{}", std::numeric_limits<double>::infinity()), "inf"); -} - -TEST(FormatIntTest, Data) { - fmt::format_int format_int(42); - EXPECT_EQ("42", std::string(format_int.data(), format_int.size())); -} - -TEST(FormatIntTest, FormatInt) { - EXPECT_EQ("42", fmt::format_int(42).str()); - EXPECT_EQ(2u, fmt::format_int(42).size()); - EXPECT_EQ("-42", fmt::format_int(-42).str()); - EXPECT_EQ(3u, fmt::format_int(-42).size()); - EXPECT_EQ("42", fmt::format_int(42ul).str()); - EXPECT_EQ("-42", fmt::format_int(-42l).str()); - EXPECT_EQ("42", fmt::format_int(42ull).str()); - EXPECT_EQ("-42", fmt::format_int(-42ll).str()); - std::ostringstream os; - os << max_value<int64_t>(); - EXPECT_EQ(os.str(), fmt::format_int(max_value<int64_t>()).str()); -} - -TEST(FormatTest, Print) { -#if FMT_USE_FCNTL - EXPECT_WRITE(stdout, fmt::print("Don't {}!", "panic"), "Don't panic!"); - EXPECT_WRITE(stderr, fmt::print(stderr, "Don't {}!", "panic"), - "Don't panic!"); -#endif - // Check that the wide print overload compiles. +} + +TEST(FormatterTest, FormatStringFromSpeedTest) { + EXPECT_EQ("1.2340000000:0042:+3.13:str:0x3e8:X:%", + format("{0:0.10f}:{1:04}:{2:+g}:{3}:{4}:{5}:%", 1.234, 42, 3.13, + "str", reinterpret_cast<void*>(1000), 'X')); +} + +TEST(FormatterTest, FormatExamples) { + std::string message = format("The answer is {}", 42); + EXPECT_EQ("The answer is 42", message); + + EXPECT_EQ("42", format("{}", 42)); + EXPECT_EQ("42", format(std::string("{}"), 42)); + + memory_buffer out; + format_to(out, "The answer is {}.", 42); + EXPECT_EQ("The answer is 42.", to_string(out)); + + const char* filename = "nonexistent"; + FILE* ftest = safe_fopen(filename, "r"); + if (ftest) fclose(ftest); + int error_code = errno; + EXPECT_TRUE(ftest == nullptr); + EXPECT_SYSTEM_ERROR( + { + FILE* f = safe_fopen(filename, "r"); + if (!f) + throw fmt::system_error(errno, "Cannot open file '{}'", filename); + fclose(f); + }, + error_code, "Cannot open file 'nonexistent'"); +} + +TEST(FormatterTest, Examples) { + EXPECT_EQ("First, thou shalt count to three", + format("First, thou shalt count to {0}", "three")); + EXPECT_EQ("Bring me a shrubbery", format("Bring me a {}", "shrubbery")); + EXPECT_EQ("From 1 to 3", format("From {} to {}", 1, 3)); + + char buffer[BUFFER_SIZE]; + safe_sprintf(buffer, "%03.2f", -1.2); + EXPECT_EQ(buffer, format("{:03.2f}", -1.2)); + + EXPECT_EQ("a, b, c", format("{0}, {1}, {2}", 'a', 'b', 'c')); + EXPECT_EQ("a, b, c", format("{}, {}, {}", 'a', 'b', 'c')); + EXPECT_EQ("c, b, a", format("{2}, {1}, {0}", 'a', 'b', 'c')); + EXPECT_EQ("abracadabra", format("{0}{1}{0}", "abra", "cad")); + + EXPECT_EQ("left aligned ", format("{:<30}", "left aligned")); + EXPECT_EQ(" right aligned", + format("{:>30}", "right aligned")); + EXPECT_EQ(" centered ", format("{:^30}", "centered")); + EXPECT_EQ("***********centered***********", format("{:*^30}", "centered")); + + EXPECT_EQ("+3.140000; -3.140000", format("{:+f}; {:+f}", 3.14, -3.14)); + EXPECT_EQ(" 3.140000; -3.140000", format("{: f}; {: f}", 3.14, -3.14)); + EXPECT_EQ("3.140000; -3.140000", format("{:-f}; {:-f}", 3.14, -3.14)); + + EXPECT_EQ("int: 42; hex: 2a; oct: 52", + format("int: {0:d}; hex: {0:x}; oct: {0:o}", 42)); + EXPECT_EQ("int: 42; hex: 0x2a; oct: 052", + format("int: {0:d}; hex: {0:#x}; oct: {0:#o}", 42)); + + EXPECT_EQ("The answer is 42", format("The answer is {}", 42)); + EXPECT_THROW_MSG(format("The answer is {:d}", "forty-two"), format_error, + "invalid type specifier"); + + EXPECT_EQ(L"Cyrillic letter \x42e", format(L"Cyrillic letter {}", L'\x42e')); + + EXPECT_WRITE( + stdout, fmt::print("{}", std::numeric_limits<double>::infinity()), "inf"); +} + +TEST(FormatIntTest, Data) { + fmt::format_int format_int(42); + EXPECT_EQ("42", std::string(format_int.data(), format_int.size())); +} + +TEST(FormatIntTest, FormatInt) { + EXPECT_EQ("42", fmt::format_int(42).str()); + EXPECT_EQ(2u, fmt::format_int(42).size()); + EXPECT_EQ("-42", fmt::format_int(-42).str()); + EXPECT_EQ(3u, fmt::format_int(-42).size()); + EXPECT_EQ("42", fmt::format_int(42ul).str()); + EXPECT_EQ("-42", fmt::format_int(-42l).str()); + EXPECT_EQ("42", fmt::format_int(42ull).str()); + EXPECT_EQ("-42", fmt::format_int(-42ll).str()); + std::ostringstream os; + os << max_value<int64_t>(); + EXPECT_EQ(os.str(), fmt::format_int(max_value<int64_t>()).str()); +} + +TEST(FormatTest, Print) { +#if FMT_USE_FCNTL + EXPECT_WRITE(stdout, fmt::print("Don't {}!", "panic"), "Don't panic!"); + EXPECT_WRITE(stderr, fmt::print(stderr, "Don't {}!", "panic"), + "Don't panic!"); +#endif + // Check that the wide print overload compiles. if (fmt::detail::const_check(false)) fmt::print(L"test"); -} - -TEST(FormatTest, Variadic) { - EXPECT_EQ("abc1", format("{}c{}", "ab", 1)); - EXPECT_EQ(L"abc1", format(L"{}c{}", L"ab", 1)); -} - -TEST(FormatTest, Dynamic) { - typedef fmt::format_context ctx; - std::vector<fmt::basic_format_arg<ctx>> args; +} + +TEST(FormatTest, Variadic) { + EXPECT_EQ("abc1", format("{}c{}", "ab", 1)); + EXPECT_EQ(L"abc1", format(L"{}c{}", L"ab", 1)); +} + +TEST(FormatTest, Dynamic) { + typedef fmt::format_context ctx; + std::vector<fmt::basic_format_arg<ctx>> args; args.emplace_back(fmt::detail::make_arg<ctx>(42)); args.emplace_back(fmt::detail::make_arg<ctx>("abc1")); args.emplace_back(fmt::detail::make_arg<ctx>(1.5f)); - - std::string result = fmt::vformat( - "{} and {} and {}", - fmt::basic_format_args<ctx>(args.data(), static_cast<int>(args.size()))); - - EXPECT_EQ("42 and abc1 and 1.5", result); -} - -TEST(FormatTest, Bytes) { - auto s = fmt::format("{:10}", fmt::bytes("ёжик")); - EXPECT_EQ("ёжик ", s); - EXPECT_EQ(10, s.size()); -} - -TEST(FormatTest, JoinArg) { - using fmt::join; - int v1[3] = {1, 2, 3}; - std::vector<float> v2; - v2.push_back(1.2f); - v2.push_back(3.4f); - void* v3[2] = {&v1[0], &v1[1]}; - - EXPECT_EQ("(1, 2, 3)", format("({})", join(v1, v1 + 3, ", "))); - EXPECT_EQ("(1)", format("({})", join(v1, v1 + 1, ", "))); - EXPECT_EQ("()", format("({})", join(v1, v1, ", "))); - EXPECT_EQ("(001, 002, 003)", format("({:03})", join(v1, v1 + 3, ", "))); - EXPECT_EQ("(+01.20, +03.40)", - format("({:+06.2f})", join(v2.begin(), v2.end(), ", "))); - - EXPECT_EQ(L"(1, 2, 3)", format(L"({})", join(v1, v1 + 3, L", "))); - EXPECT_EQ("1, 2, 3", format("{0:{1}}", join(v1, v1 + 3, ", "), 1)); - - EXPECT_EQ(format("{}, {}", v3[0], v3[1]), - format("{}", join(v3, v3 + 2, ", "))); - -#if !FMT_GCC_VERSION || FMT_GCC_VERSION >= 405 - EXPECT_EQ("(1, 2, 3)", format("({})", join(v1, ", "))); - EXPECT_EQ("(+01.20, +03.40)", format("({:+06.2f})", join(v2, ", "))); -#endif -} - -template <typename T> std::string str(const T& value) { - return fmt::format("{}", value); -} - -TEST(StrTest, Convert) { - EXPECT_EQ("42", str(42)); - std::string s = str(Date(2012, 12, 9)); - EXPECT_EQ("2012-12-9", s); -} - -std::string vformat_message(int id, const char* format, fmt::format_args args) { - fmt::memory_buffer buffer; - format_to(buffer, "[{}] ", id); - vformat_to(buffer, format, args); - return to_string(buffer); -} - -template <typename... Args> -std::string format_message(int id, const char* format, const Args&... args) { - auto va = fmt::make_format_args(args...); - return vformat_message(id, format, va); -} - -TEST(FormatTest, FormatMessageExample) { - EXPECT_EQ("[42] something happened", - format_message(42, "{} happened", "something")); -} - -template <typename... Args> -void print_error(const char* file, int line, const char* format, - const Args&... args) { - fmt::print("{}: {}: ", file, line); - fmt::print(format, args...); -} - -TEST(FormatTest, UnpackedArgs) { - EXPECT_EQ("0123456789abcdefg", - fmt::format("{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}", 0, 1, 2, 3, 4, 5, - 6, 7, 8, 9, 'a', 'b', 'c', 'd', 'e', 'f', 'g')); -} - -struct string_like {}; -fmt::string_view to_string_view(string_like) { return "foo"; } - -constexpr char with_null[3] = {'{', '}', '\0'}; -constexpr char no_null[2] = {'{', '}'}; - -TEST(FormatTest, CompileTimeString) { - EXPECT_EQ("42", fmt::format(FMT_STRING("{}"), 42)); - EXPECT_EQ(L"42", fmt::format(FMT_STRING(L"{}"), 42)); - EXPECT_EQ("foo", fmt::format(FMT_STRING("{}"), string_like())); - (void)with_null; - (void)no_null; -#if __cplusplus >= 201703L - EXPECT_EQ("42", fmt::format(FMT_STRING(with_null), 42)); - EXPECT_EQ("42", fmt::format(FMT_STRING(no_null), 42)); -#endif -#if defined(FMT_USE_STRING_VIEW) && __cplusplus >= 201703L - EXPECT_EQ("42", fmt::format(FMT_STRING(std::string_view("{}")), 42)); - EXPECT_EQ(L"42", fmt::format(FMT_STRING(std::wstring_view(L"{}")), 42)); -#endif -} - -TEST(FormatTest, CustomFormatCompileTimeString) { - EXPECT_EQ("42", fmt::format(FMT_STRING("{}"), Answer())); - Answer answer; - EXPECT_EQ("42", fmt::format(FMT_STRING("{}"), answer)); - char buf[10] = {}; - fmt::format_to(buf, FMT_STRING("{}"), answer); - const Answer const_answer = Answer(); - EXPECT_EQ("42", fmt::format(FMT_STRING("{}"), const_answer)); -} - -#if FMT_USE_USER_DEFINED_LITERALS -// Passing user-defined literals directly to EXPECT_EQ causes problems -// with macro argument stringification (#) on some versions of GCC. -// Workaround: Assing the UDL result to a variable before the macro. - -using namespace fmt::literals; - -TEST(LiteralsTest, Format) { - auto udl_format = "{}c{}"_format("ab", 1); - EXPECT_EQ(format("{}c{}", "ab", 1), udl_format); - auto udl_format_w = L"{}c{}"_format(L"ab", 1); - EXPECT_EQ(format(L"{}c{}", L"ab", 1), udl_format_w); -} - -TEST(LiteralsTest, NamedArg) { - auto udl_a = format("{first}{second}{first}{third}", "first"_a = "abra", - "second"_a = "cad", "third"_a = 99); - EXPECT_EQ(format("{first}{second}{first}{third}", fmt::arg("first", "abra"), - fmt::arg("second", "cad"), fmt::arg("third", 99)), - udl_a); - auto udl_a_w = format(L"{first}{second}{first}{third}", L"first"_a = L"abra", - L"second"_a = L"cad", L"third"_a = 99); - EXPECT_EQ( - format(L"{first}{second}{first}{third}", fmt::arg(L"first", L"abra"), - fmt::arg(L"second", L"cad"), fmt::arg(L"third", 99)), - udl_a_w); -} - -TEST(FormatTest, UdlTemplate) { - EXPECT_EQ("foo", "foo"_format()); - EXPECT_EQ(" 42", "{0:10}"_format(42)); -} - -TEST(FormatTest, UdlPassUserDefinedObjectAsLvalue) { - Date date(2015, 10, 21); - EXPECT_EQ("2015-10-21", "{}"_format(date)); -} -#endif // FMT_USE_USER_DEFINED_LITERALS - -enum TestEnum { A }; - -TEST(FormatTest, Enum) { EXPECT_EQ("0", fmt::format("{}", A)); } - -TEST(FormatTest, FormatterNotSpecialized) { - static_assert( - !fmt::has_formatter<fmt::formatter<TestEnum>, fmt::format_context>::value, - ""); -} - -#if FMT_HAS_FEATURE(cxx_strong_enums) -enum big_enum : unsigned long long { big_enum_value = 5000000000ULL }; - -TEST(FormatTest, StrongEnum) { - EXPECT_EQ("5000000000", fmt::format("{}", big_enum_value)); -} -#endif - -TEST(FormatTest, NonNullTerminatedFormatString) { - EXPECT_EQ("42", format(string_view("{}foo", 2), 42)); -} - -struct variant { - enum { INT, STRING } type; - explicit variant(int) : type(INT) {} - explicit variant(const char*) : type(STRING) {} -}; - -FMT_BEGIN_NAMESPACE -template <> struct formatter<variant> : dynamic_formatter<> { - auto format(variant value, format_context& ctx) -> decltype(ctx.out()) { - if (value.type == variant::INT) return dynamic_formatter<>::format(42, ctx); - return dynamic_formatter<>::format("foo", ctx); - } -}; -FMT_END_NAMESPACE - -TEST(FormatTest, DynamicFormatter) { - auto num = variant(42); - auto str = variant("foo"); - EXPECT_EQ("42", format("{:d}", num)); - EXPECT_EQ("foo", format("{:s}", str)); - EXPECT_EQ(" 42 foo ", format("{:{}} {:{}}", num, 3, str, 4)); - EXPECT_THROW_MSG(format("{0:{}}", num), format_error, - "cannot switch from manual to automatic argument indexing"); - EXPECT_THROW_MSG(format("{:{0}}", num), format_error, - "cannot switch from automatic to manual argument indexing"); + + std::string result = fmt::vformat( + "{} and {} and {}", + fmt::basic_format_args<ctx>(args.data(), static_cast<int>(args.size()))); + + EXPECT_EQ("42 and abc1 and 1.5", result); +} + +TEST(FormatTest, Bytes) { + auto s = fmt::format("{:10}", fmt::bytes("ёжик")); + EXPECT_EQ("ёжик ", s); + EXPECT_EQ(10, s.size()); +} + +TEST(FormatTest, JoinArg) { + using fmt::join; + int v1[3] = {1, 2, 3}; + std::vector<float> v2; + v2.push_back(1.2f); + v2.push_back(3.4f); + void* v3[2] = {&v1[0], &v1[1]}; + + EXPECT_EQ("(1, 2, 3)", format("({})", join(v1, v1 + 3, ", "))); + EXPECT_EQ("(1)", format("({})", join(v1, v1 + 1, ", "))); + EXPECT_EQ("()", format("({})", join(v1, v1, ", "))); + EXPECT_EQ("(001, 002, 003)", format("({:03})", join(v1, v1 + 3, ", "))); + EXPECT_EQ("(+01.20, +03.40)", + format("({:+06.2f})", join(v2.begin(), v2.end(), ", "))); + + EXPECT_EQ(L"(1, 2, 3)", format(L"({})", join(v1, v1 + 3, L", "))); + EXPECT_EQ("1, 2, 3", format("{0:{1}}", join(v1, v1 + 3, ", "), 1)); + + EXPECT_EQ(format("{}, {}", v3[0], v3[1]), + format("{}", join(v3, v3 + 2, ", "))); + +#if !FMT_GCC_VERSION || FMT_GCC_VERSION >= 405 + EXPECT_EQ("(1, 2, 3)", format("({})", join(v1, ", "))); + EXPECT_EQ("(+01.20, +03.40)", format("({:+06.2f})", join(v2, ", "))); +#endif +} + +template <typename T> std::string str(const T& value) { + return fmt::format("{}", value); +} + +TEST(StrTest, Convert) { + EXPECT_EQ("42", str(42)); + std::string s = str(Date(2012, 12, 9)); + EXPECT_EQ("2012-12-9", s); +} + +std::string vformat_message(int id, const char* format, fmt::format_args args) { + fmt::memory_buffer buffer; + format_to(buffer, "[{}] ", id); + vformat_to(buffer, format, args); + return to_string(buffer); +} + +template <typename... Args> +std::string format_message(int id, const char* format, const Args&... args) { + auto va = fmt::make_format_args(args...); + return vformat_message(id, format, va); +} + +TEST(FormatTest, FormatMessageExample) { + EXPECT_EQ("[42] something happened", + format_message(42, "{} happened", "something")); +} + +template <typename... Args> +void print_error(const char* file, int line, const char* format, + const Args&... args) { + fmt::print("{}: {}: ", file, line); + fmt::print(format, args...); +} + +TEST(FormatTest, UnpackedArgs) { + EXPECT_EQ("0123456789abcdefg", + fmt::format("{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}", 0, 1, 2, 3, 4, 5, + 6, 7, 8, 9, 'a', 'b', 'c', 'd', 'e', 'f', 'g')); +} + +struct string_like {}; +fmt::string_view to_string_view(string_like) { return "foo"; } + +constexpr char with_null[3] = {'{', '}', '\0'}; +constexpr char no_null[2] = {'{', '}'}; + +TEST(FormatTest, CompileTimeString) { + EXPECT_EQ("42", fmt::format(FMT_STRING("{}"), 42)); + EXPECT_EQ(L"42", fmt::format(FMT_STRING(L"{}"), 42)); + EXPECT_EQ("foo", fmt::format(FMT_STRING("{}"), string_like())); + (void)with_null; + (void)no_null; +#if __cplusplus >= 201703L + EXPECT_EQ("42", fmt::format(FMT_STRING(with_null), 42)); + EXPECT_EQ("42", fmt::format(FMT_STRING(no_null), 42)); +#endif +#if defined(FMT_USE_STRING_VIEW) && __cplusplus >= 201703L + EXPECT_EQ("42", fmt::format(FMT_STRING(std::string_view("{}")), 42)); + EXPECT_EQ(L"42", fmt::format(FMT_STRING(std::wstring_view(L"{}")), 42)); +#endif +} + +TEST(FormatTest, CustomFormatCompileTimeString) { + EXPECT_EQ("42", fmt::format(FMT_STRING("{}"), Answer())); + Answer answer; + EXPECT_EQ("42", fmt::format(FMT_STRING("{}"), answer)); + char buf[10] = {}; + fmt::format_to(buf, FMT_STRING("{}"), answer); + const Answer const_answer = Answer(); + EXPECT_EQ("42", fmt::format(FMT_STRING("{}"), const_answer)); +} + +#if FMT_USE_USER_DEFINED_LITERALS +// Passing user-defined literals directly to EXPECT_EQ causes problems +// with macro argument stringification (#) on some versions of GCC. +// Workaround: Assing the UDL result to a variable before the macro. + +using namespace fmt::literals; + +TEST(LiteralsTest, Format) { + auto udl_format = "{}c{}"_format("ab", 1); + EXPECT_EQ(format("{}c{}", "ab", 1), udl_format); + auto udl_format_w = L"{}c{}"_format(L"ab", 1); + EXPECT_EQ(format(L"{}c{}", L"ab", 1), udl_format_w); +} + +TEST(LiteralsTest, NamedArg) { + auto udl_a = format("{first}{second}{first}{third}", "first"_a = "abra", + "second"_a = "cad", "third"_a = 99); + EXPECT_EQ(format("{first}{second}{first}{third}", fmt::arg("first", "abra"), + fmt::arg("second", "cad"), fmt::arg("third", 99)), + udl_a); + auto udl_a_w = format(L"{first}{second}{first}{third}", L"first"_a = L"abra", + L"second"_a = L"cad", L"third"_a = 99); + EXPECT_EQ( + format(L"{first}{second}{first}{third}", fmt::arg(L"first", L"abra"), + fmt::arg(L"second", L"cad"), fmt::arg(L"third", 99)), + udl_a_w); +} + +TEST(FormatTest, UdlTemplate) { + EXPECT_EQ("foo", "foo"_format()); + EXPECT_EQ(" 42", "{0:10}"_format(42)); +} + +TEST(FormatTest, UdlPassUserDefinedObjectAsLvalue) { + Date date(2015, 10, 21); + EXPECT_EQ("2015-10-21", "{}"_format(date)); +} +#endif // FMT_USE_USER_DEFINED_LITERALS + +enum TestEnum { A }; + +TEST(FormatTest, Enum) { EXPECT_EQ("0", fmt::format("{}", A)); } + +TEST(FormatTest, FormatterNotSpecialized) { + static_assert( + !fmt::has_formatter<fmt::formatter<TestEnum>, fmt::format_context>::value, + ""); +} + +#if FMT_HAS_FEATURE(cxx_strong_enums) +enum big_enum : unsigned long long { big_enum_value = 5000000000ULL }; + +TEST(FormatTest, StrongEnum) { + EXPECT_EQ("5000000000", fmt::format("{}", big_enum_value)); +} +#endif + +TEST(FormatTest, NonNullTerminatedFormatString) { + EXPECT_EQ("42", format(string_view("{}foo", 2), 42)); +} + +struct variant { + enum { INT, STRING } type; + explicit variant(int) : type(INT) {} + explicit variant(const char*) : type(STRING) {} +}; + +FMT_BEGIN_NAMESPACE +template <> struct formatter<variant> : dynamic_formatter<> { + auto format(variant value, format_context& ctx) -> decltype(ctx.out()) { + if (value.type == variant::INT) return dynamic_formatter<>::format(42, ctx); + return dynamic_formatter<>::format("foo", ctx); + } +}; +FMT_END_NAMESPACE + +TEST(FormatTest, DynamicFormatter) { + auto num = variant(42); + auto str = variant("foo"); + EXPECT_EQ("42", format("{:d}", num)); + EXPECT_EQ("foo", format("{:s}", str)); + EXPECT_EQ(" 42 foo ", format("{:{}} {:{}}", num, 3, str, 4)); + EXPECT_THROW_MSG(format("{0:{}}", num), format_error, + "cannot switch from manual to automatic argument indexing"); + EXPECT_THROW_MSG(format("{:{0}}", num), format_error, + "cannot switch from automatic to manual argument indexing"); #if FMT_DEPRECATED_NUMERIC_ALIGN - EXPECT_THROW_MSG(format("{:=}", str), format_error, - "format specifier requires numeric argument"); -#endif - EXPECT_THROW_MSG(format("{:+}", str), format_error, - "format specifier requires numeric argument"); - EXPECT_THROW_MSG(format("{:-}", str), format_error, - "format specifier requires numeric argument"); - EXPECT_THROW_MSG(format("{: }", str), format_error, - "format specifier requires numeric argument"); - EXPECT_THROW_MSG(format("{:#}", str), format_error, - "format specifier requires numeric argument"); - EXPECT_THROW_MSG(format("{:0}", str), format_error, - "format specifier requires numeric argument"); - EXPECT_THROW_MSG(format("{:.2}", num), format_error, - "precision not allowed for this argument type"); -} - + EXPECT_THROW_MSG(format("{:=}", str), format_error, + "format specifier requires numeric argument"); +#endif + EXPECT_THROW_MSG(format("{:+}", str), format_error, + "format specifier requires numeric argument"); + EXPECT_THROW_MSG(format("{:-}", str), format_error, + "format specifier requires numeric argument"); + EXPECT_THROW_MSG(format("{: }", str), format_error, + "format specifier requires numeric argument"); + EXPECT_THROW_MSG(format("{:#}", str), format_error, + "format specifier requires numeric argument"); + EXPECT_THROW_MSG(format("{:0}", str), format_error, + "format specifier requires numeric argument"); + EXPECT_THROW_MSG(format("{:.2}", num), format_error, + "precision not allowed for this argument type"); +} + namespace adl_test { namespace fmt { namespace detail { @@ -1911,58 +1911,58 @@ struct formatter<adl_test::fmt::detail::foo> : formatter<std::string> { }; FMT_END_NAMESPACE -TEST(FormatTest, ToString) { - EXPECT_EQ("42", fmt::to_string(42)); - EXPECT_EQ("0x1234", fmt::to_string(reinterpret_cast<void*>(0x1234))); +TEST(FormatTest, ToString) { + EXPECT_EQ("42", fmt::to_string(42)); + EXPECT_EQ("0x1234", fmt::to_string(reinterpret_cast<void*>(0x1234))); EXPECT_EQ("foo", fmt::to_string(adl_test::fmt::detail::foo())); -} - -TEST(FormatTest, ToWString) { EXPECT_EQ(L"42", fmt::to_wstring(42)); } - -TEST(FormatTest, OutputIterators) { - std::list<char> out; - fmt::format_to(std::back_inserter(out), "{}", 42); - EXPECT_EQ("42", std::string(out.begin(), out.end())); - std::stringstream s; - fmt::format_to(std::ostream_iterator<char>(s), "{}", 42); - EXPECT_EQ("42", s.str()); -} - -TEST(FormatTest, FormattedSize) { - EXPECT_EQ(2u, fmt::formatted_size("{}", 42)); -} - +} + +TEST(FormatTest, ToWString) { EXPECT_EQ(L"42", fmt::to_wstring(42)); } + +TEST(FormatTest, OutputIterators) { + std::list<char> out; + fmt::format_to(std::back_inserter(out), "{}", 42); + EXPECT_EQ("42", std::string(out.begin(), out.end())); + std::stringstream s; + fmt::format_to(std::ostream_iterator<char>(s), "{}", 42); + EXPECT_EQ("42", s.str()); +} + +TEST(FormatTest, FormattedSize) { + EXPECT_EQ(2u, fmt::formatted_size("{}", 42)); +} + TEST(FormatTest, FormatTo) { std::vector<char> v; fmt::format_to(std::back_inserter(v), "{}", "foo"); EXPECT_EQ(string_view(v.data(), v.size()), "foo"); } -TEST(FormatTest, FormatToN) { - char buffer[4]; - buffer[3] = 'x'; - auto result = fmt::format_to_n(buffer, 3, "{}", 12345); - EXPECT_EQ(5u, result.size); - EXPECT_EQ(buffer + 3, result.out); - EXPECT_EQ("123x", fmt::string_view(buffer, 4)); - - result = fmt::format_to_n(buffer, 3, "{:s}", "foobar"); - EXPECT_EQ(6u, result.size); - EXPECT_EQ(buffer + 3, result.out); - EXPECT_EQ("foox", fmt::string_view(buffer, 4)); - - buffer[0] = 'x'; - buffer[1] = 'x'; - buffer[2] = 'x'; - result = fmt::format_to_n(buffer, 3, "{}", 'A'); - EXPECT_EQ(1u, result.size); - EXPECT_EQ(buffer + 1, result.out); - EXPECT_EQ("Axxx", fmt::string_view(buffer, 4)); - - result = fmt::format_to_n(buffer, 3, "{}{} ", 'B', 'C'); - EXPECT_EQ(3u, result.size); - EXPECT_EQ(buffer + 3, result.out); - EXPECT_EQ("BC x", fmt::string_view(buffer, 4)); +TEST(FormatTest, FormatToN) { + char buffer[4]; + buffer[3] = 'x'; + auto result = fmt::format_to_n(buffer, 3, "{}", 12345); + EXPECT_EQ(5u, result.size); + EXPECT_EQ(buffer + 3, result.out); + EXPECT_EQ("123x", fmt::string_view(buffer, 4)); + + result = fmt::format_to_n(buffer, 3, "{:s}", "foobar"); + EXPECT_EQ(6u, result.size); + EXPECT_EQ(buffer + 3, result.out); + EXPECT_EQ("foox", fmt::string_view(buffer, 4)); + + buffer[0] = 'x'; + buffer[1] = 'x'; + buffer[2] = 'x'; + result = fmt::format_to_n(buffer, 3, "{}", 'A'); + EXPECT_EQ(1u, result.size); + EXPECT_EQ(buffer + 1, result.out); + EXPECT_EQ("Axxx", fmt::string_view(buffer, 4)); + + result = fmt::format_to_n(buffer, 3, "{}{} ", 'B', 'C'); + EXPECT_EQ(3u, result.size); + EXPECT_EQ(buffer + 3, result.out); + EXPECT_EQ("BC x", fmt::string_view(buffer, 4)); result = fmt::format_to_n(buffer, 4, "{}", "ABCDE"); EXPECT_EQ(5u, result.size); @@ -1972,503 +1972,503 @@ TEST(FormatTest, FormatToN) { result = fmt::format_to_n(buffer, 3, "{}", std::string(1000, '*')); EXPECT_EQ(1000u, result.size); EXPECT_EQ("***x", fmt::string_view(buffer, 4)); -} - -TEST(FormatTest, WideFormatToN) { - wchar_t buffer[4]; - buffer[3] = L'x'; - auto result = fmt::format_to_n(buffer, 3, L"{}", 12345); - EXPECT_EQ(5u, result.size); - EXPECT_EQ(buffer + 3, result.out); - EXPECT_EQ(L"123x", fmt::wstring_view(buffer, 4)); - buffer[0] = L'x'; - buffer[1] = L'x'; - buffer[2] = L'x'; - result = fmt::format_to_n(buffer, 3, L"{}", L'A'); - EXPECT_EQ(1u, result.size); - EXPECT_EQ(buffer + 1, result.out); - EXPECT_EQ(L"Axxx", fmt::wstring_view(buffer, 4)); - result = fmt::format_to_n(buffer, 3, L"{}{} ", L'B', L'C'); - EXPECT_EQ(3u, result.size); - EXPECT_EQ(buffer + 3, result.out); - EXPECT_EQ(L"BC x", fmt::wstring_view(buffer, 4)); -} - -struct test_output_iterator { - char* data; - - using iterator_category = std::output_iterator_tag; - using value_type = void; - using difference_type = void; - using pointer = void; - using reference = void; - - test_output_iterator& operator++() { - ++data; - return *this; - } - test_output_iterator operator++(int) { - auto tmp = *this; - ++data; - return tmp; - } - char& operator*() { return *data; } -}; - -TEST(FormatTest, FormatToNOutputIterator) { - char buf[10] = {}; - fmt::format_to_n(test_output_iterator{buf}, 10, "{}", 42); - EXPECT_STREQ(buf, "42"); -} - -#if FMT_USE_CONSTEXPR -struct test_arg_id_handler { - enum result { NONE, EMPTY, INDEX, NAME, ERROR }; - result res = NONE; - int index = 0; - string_view name; - - FMT_CONSTEXPR void operator()() { res = EMPTY; } - - FMT_CONSTEXPR void operator()(int i) { - res = INDEX; - index = i; - } - - FMT_CONSTEXPR void operator()(string_view n) { - res = NAME; - name = n; - } - - FMT_CONSTEXPR void on_error(const char*) { res = ERROR; } -}; - -template <size_t N> -FMT_CONSTEXPR test_arg_id_handler parse_arg_id(const char (&s)[N]) { - test_arg_id_handler h; +} + +TEST(FormatTest, WideFormatToN) { + wchar_t buffer[4]; + buffer[3] = L'x'; + auto result = fmt::format_to_n(buffer, 3, L"{}", 12345); + EXPECT_EQ(5u, result.size); + EXPECT_EQ(buffer + 3, result.out); + EXPECT_EQ(L"123x", fmt::wstring_view(buffer, 4)); + buffer[0] = L'x'; + buffer[1] = L'x'; + buffer[2] = L'x'; + result = fmt::format_to_n(buffer, 3, L"{}", L'A'); + EXPECT_EQ(1u, result.size); + EXPECT_EQ(buffer + 1, result.out); + EXPECT_EQ(L"Axxx", fmt::wstring_view(buffer, 4)); + result = fmt::format_to_n(buffer, 3, L"{}{} ", L'B', L'C'); + EXPECT_EQ(3u, result.size); + EXPECT_EQ(buffer + 3, result.out); + EXPECT_EQ(L"BC x", fmt::wstring_view(buffer, 4)); +} + +struct test_output_iterator { + char* data; + + using iterator_category = std::output_iterator_tag; + using value_type = void; + using difference_type = void; + using pointer = void; + using reference = void; + + test_output_iterator& operator++() { + ++data; + return *this; + } + test_output_iterator operator++(int) { + auto tmp = *this; + ++data; + return tmp; + } + char& operator*() { return *data; } +}; + +TEST(FormatTest, FormatToNOutputIterator) { + char buf[10] = {}; + fmt::format_to_n(test_output_iterator{buf}, 10, "{}", 42); + EXPECT_STREQ(buf, "42"); +} + +#if FMT_USE_CONSTEXPR +struct test_arg_id_handler { + enum result { NONE, EMPTY, INDEX, NAME, ERROR }; + result res = NONE; + int index = 0; + string_view name; + + FMT_CONSTEXPR void operator()() { res = EMPTY; } + + FMT_CONSTEXPR void operator()(int i) { + res = INDEX; + index = i; + } + + FMT_CONSTEXPR void operator()(string_view n) { + res = NAME; + name = n; + } + + FMT_CONSTEXPR void on_error(const char*) { res = ERROR; } +}; + +template <size_t N> +FMT_CONSTEXPR test_arg_id_handler parse_arg_id(const char (&s)[N]) { + test_arg_id_handler h; fmt::detail::parse_arg_id(s, s + N, h); - return h; -} - -TEST(FormatTest, ConstexprParseArgID) { - static_assert(parse_arg_id(":").res == test_arg_id_handler::EMPTY, ""); - static_assert(parse_arg_id("}").res == test_arg_id_handler::EMPTY, ""); - static_assert(parse_arg_id("42:").res == test_arg_id_handler::INDEX, ""); - static_assert(parse_arg_id("42:").index == 42, ""); - static_assert(parse_arg_id("foo:").res == test_arg_id_handler::NAME, ""); - static_assert(parse_arg_id("foo:").name.size() == 3, ""); - static_assert(parse_arg_id("!").res == test_arg_id_handler::ERROR, ""); -} - -struct test_format_specs_handler { - enum Result { NONE, PLUS, MINUS, SPACE, HASH, ZERO, ERROR }; - Result res = NONE; - - fmt::align_t align = fmt::align::none; - char fill = 0; - int width = 0; + return h; +} + +TEST(FormatTest, ConstexprParseArgID) { + static_assert(parse_arg_id(":").res == test_arg_id_handler::EMPTY, ""); + static_assert(parse_arg_id("}").res == test_arg_id_handler::EMPTY, ""); + static_assert(parse_arg_id("42:").res == test_arg_id_handler::INDEX, ""); + static_assert(parse_arg_id("42:").index == 42, ""); + static_assert(parse_arg_id("foo:").res == test_arg_id_handler::NAME, ""); + static_assert(parse_arg_id("foo:").name.size() == 3, ""); + static_assert(parse_arg_id("!").res == test_arg_id_handler::ERROR, ""); +} + +struct test_format_specs_handler { + enum Result { NONE, PLUS, MINUS, SPACE, HASH, ZERO, ERROR }; + Result res = NONE; + + fmt::align_t align = fmt::align::none; + char fill = 0; + int width = 0; fmt::detail::arg_ref<char> width_ref; - int precision = 0; + int precision = 0; fmt::detail::arg_ref<char> precision_ref; - char type = 0; - - // Workaround for MSVC2017 bug that results in "expression did not evaluate - // to a constant" with compiler-generated copy ctor. - FMT_CONSTEXPR test_format_specs_handler() {} - FMT_CONSTEXPR test_format_specs_handler( - const test_format_specs_handler& other) - : res(other.res), - align(other.align), - fill(other.fill), - width(other.width), - width_ref(other.width_ref), - precision(other.precision), - precision_ref(other.precision_ref), - type(other.type) {} - - FMT_CONSTEXPR void on_align(fmt::align_t a) { align = a; } - FMT_CONSTEXPR void on_fill(fmt::string_view f) { fill = f[0]; } - FMT_CONSTEXPR void on_plus() { res = PLUS; } - FMT_CONSTEXPR void on_minus() { res = MINUS; } - FMT_CONSTEXPR void on_space() { res = SPACE; } - FMT_CONSTEXPR void on_hash() { res = HASH; } - FMT_CONSTEXPR void on_zero() { res = ZERO; } - - FMT_CONSTEXPR void on_width(int w) { width = w; } + char type = 0; + + // Workaround for MSVC2017 bug that results in "expression did not evaluate + // to a constant" with compiler-generated copy ctor. + FMT_CONSTEXPR test_format_specs_handler() {} + FMT_CONSTEXPR test_format_specs_handler( + const test_format_specs_handler& other) + : res(other.res), + align(other.align), + fill(other.fill), + width(other.width), + width_ref(other.width_ref), + precision(other.precision), + precision_ref(other.precision_ref), + type(other.type) {} + + FMT_CONSTEXPR void on_align(fmt::align_t a) { align = a; } + FMT_CONSTEXPR void on_fill(fmt::string_view f) { fill = f[0]; } + FMT_CONSTEXPR void on_plus() { res = PLUS; } + FMT_CONSTEXPR void on_minus() { res = MINUS; } + FMT_CONSTEXPR void on_space() { res = SPACE; } + FMT_CONSTEXPR void on_hash() { res = HASH; } + FMT_CONSTEXPR void on_zero() { res = ZERO; } + + FMT_CONSTEXPR void on_width(int w) { width = w; } FMT_CONSTEXPR void on_dynamic_width(fmt::detail::auto_id) {} - FMT_CONSTEXPR void on_dynamic_width(int index) { width_ref = index; } - FMT_CONSTEXPR void on_dynamic_width(string_view) {} - - FMT_CONSTEXPR void on_precision(int p) { precision = p; } + FMT_CONSTEXPR void on_dynamic_width(int index) { width_ref = index; } + FMT_CONSTEXPR void on_dynamic_width(string_view) {} + + FMT_CONSTEXPR void on_precision(int p) { precision = p; } FMT_CONSTEXPR void on_dynamic_precision(fmt::detail::auto_id) {} - FMT_CONSTEXPR void on_dynamic_precision(int index) { precision_ref = index; } - FMT_CONSTEXPR void on_dynamic_precision(string_view) {} - - FMT_CONSTEXPR void end_precision() {} - FMT_CONSTEXPR void on_type(char t) { type = t; } - FMT_CONSTEXPR void on_error(const char*) { res = ERROR; } -}; - -template <size_t N> -FMT_CONSTEXPR test_format_specs_handler parse_test_specs(const char (&s)[N]) { - test_format_specs_handler h; + FMT_CONSTEXPR void on_dynamic_precision(int index) { precision_ref = index; } + FMT_CONSTEXPR void on_dynamic_precision(string_view) {} + + FMT_CONSTEXPR void end_precision() {} + FMT_CONSTEXPR void on_type(char t) { type = t; } + FMT_CONSTEXPR void on_error(const char*) { res = ERROR; } +}; + +template <size_t N> +FMT_CONSTEXPR test_format_specs_handler parse_test_specs(const char (&s)[N]) { + test_format_specs_handler h; fmt::detail::parse_format_specs(s, s + N, h); - return h; -} - -TEST(FormatTest, ConstexprParseFormatSpecs) { - typedef test_format_specs_handler handler; - static_assert(parse_test_specs("<").align == fmt::align::left, ""); - static_assert(parse_test_specs("*^").fill == '*', ""); - static_assert(parse_test_specs("+").res == handler::PLUS, ""); - static_assert(parse_test_specs("-").res == handler::MINUS, ""); - static_assert(parse_test_specs(" ").res == handler::SPACE, ""); - static_assert(parse_test_specs("#").res == handler::HASH, ""); - static_assert(parse_test_specs("0").res == handler::ZERO, ""); - static_assert(parse_test_specs("42").width == 42, ""); - static_assert(parse_test_specs("{42}").width_ref.val.index == 42, ""); - static_assert(parse_test_specs(".42").precision == 42, ""); - static_assert(parse_test_specs(".{42}").precision_ref.val.index == 42, ""); - static_assert(parse_test_specs("d").type == 'd', ""); - static_assert(parse_test_specs("{<").res == handler::ERROR, ""); -} - -struct test_parse_context { - typedef char char_type; - - FMT_CONSTEXPR int next_arg_id() { return 11; } - template <typename Id> FMT_CONSTEXPR void check_arg_id(Id) {} - - FMT_CONSTEXPR const char* begin() { return nullptr; } - FMT_CONSTEXPR const char* end() { return nullptr; } - - void on_error(const char*) {} -}; - -struct test_context { - using char_type = char; - using format_arg = fmt::basic_format_arg<test_context>; - using parse_context_type = fmt::format_parse_context; - - template <typename T> struct formatter_type { - typedef fmt::formatter<T, char_type> type; - }; - - template <typename Id> - FMT_CONSTEXPR fmt::basic_format_arg<test_context> arg(Id id) { + return h; +} + +TEST(FormatTest, ConstexprParseFormatSpecs) { + typedef test_format_specs_handler handler; + static_assert(parse_test_specs("<").align == fmt::align::left, ""); + static_assert(parse_test_specs("*^").fill == '*', ""); + static_assert(parse_test_specs("+").res == handler::PLUS, ""); + static_assert(parse_test_specs("-").res == handler::MINUS, ""); + static_assert(parse_test_specs(" ").res == handler::SPACE, ""); + static_assert(parse_test_specs("#").res == handler::HASH, ""); + static_assert(parse_test_specs("0").res == handler::ZERO, ""); + static_assert(parse_test_specs("42").width == 42, ""); + static_assert(parse_test_specs("{42}").width_ref.val.index == 42, ""); + static_assert(parse_test_specs(".42").precision == 42, ""); + static_assert(parse_test_specs(".{42}").precision_ref.val.index == 42, ""); + static_assert(parse_test_specs("d").type == 'd', ""); + static_assert(parse_test_specs("{<").res == handler::ERROR, ""); +} + +struct test_parse_context { + typedef char char_type; + + FMT_CONSTEXPR int next_arg_id() { return 11; } + template <typename Id> FMT_CONSTEXPR void check_arg_id(Id) {} + + FMT_CONSTEXPR const char* begin() { return nullptr; } + FMT_CONSTEXPR const char* end() { return nullptr; } + + void on_error(const char*) {} +}; + +struct test_context { + using char_type = char; + using format_arg = fmt::basic_format_arg<test_context>; + using parse_context_type = fmt::format_parse_context; + + template <typename T> struct formatter_type { + typedef fmt::formatter<T, char_type> type; + }; + + template <typename Id> + FMT_CONSTEXPR fmt::basic_format_arg<test_context> arg(Id id) { return fmt::detail::make_arg<test_context>(id); - } - - void on_error(const char*) {} - - FMT_CONSTEXPR test_context error_handler() { return *this; } -}; - -template <size_t N> -FMT_CONSTEXPR fmt::format_specs parse_specs(const char (&s)[N]) { - auto specs = fmt::format_specs(); - auto parse_ctx = test_parse_context(); - auto ctx = test_context(); + } + + void on_error(const char*) {} + + FMT_CONSTEXPR test_context error_handler() { return *this; } +}; + +template <size_t N> +FMT_CONSTEXPR fmt::format_specs parse_specs(const char (&s)[N]) { + auto specs = fmt::format_specs(); + auto parse_ctx = test_parse_context(); + auto ctx = test_context(); fmt::detail::specs_handler<test_parse_context, test_context> h( - specs, parse_ctx, ctx); - parse_format_specs(s, s + N, h); - return specs; -} - -TEST(FormatTest, ConstexprSpecsHandler) { - static_assert(parse_specs("<").align == fmt::align::left, ""); - static_assert(parse_specs("*^").fill[0] == '*', ""); - static_assert(parse_specs("+").sign == fmt::sign::plus, ""); - static_assert(parse_specs("-").sign == fmt::sign::minus, ""); - static_assert(parse_specs(" ").sign == fmt::sign::space, ""); - static_assert(parse_specs("#").alt, ""); - static_assert(parse_specs("0").align == fmt::align::numeric, ""); - static_assert(parse_specs("42").width == 42, ""); - static_assert(parse_specs("{}").width == 11, ""); - static_assert(parse_specs("{22}").width == 22, ""); - static_assert(parse_specs(".42").precision == 42, ""); - static_assert(parse_specs(".{}").precision == 11, ""); - static_assert(parse_specs(".{22}").precision == 22, ""); - static_assert(parse_specs("d").type == 'd', ""); -} - -template <size_t N> + specs, parse_ctx, ctx); + parse_format_specs(s, s + N, h); + return specs; +} + +TEST(FormatTest, ConstexprSpecsHandler) { + static_assert(parse_specs("<").align == fmt::align::left, ""); + static_assert(parse_specs("*^").fill[0] == '*', ""); + static_assert(parse_specs("+").sign == fmt::sign::plus, ""); + static_assert(parse_specs("-").sign == fmt::sign::minus, ""); + static_assert(parse_specs(" ").sign == fmt::sign::space, ""); + static_assert(parse_specs("#").alt, ""); + static_assert(parse_specs("0").align == fmt::align::numeric, ""); + static_assert(parse_specs("42").width == 42, ""); + static_assert(parse_specs("{}").width == 11, ""); + static_assert(parse_specs("{22}").width == 22, ""); + static_assert(parse_specs(".42").precision == 42, ""); + static_assert(parse_specs(".{}").precision == 11, ""); + static_assert(parse_specs(".{22}").precision == 22, ""); + static_assert(parse_specs("d").type == 'd', ""); +} + +template <size_t N> FMT_CONSTEXPR fmt::detail::dynamic_format_specs<char> parse_dynamic_specs( - const char (&s)[N]) { + const char (&s)[N]) { fmt::detail::dynamic_format_specs<char> specs; - test_parse_context ctx{}; + test_parse_context ctx{}; fmt::detail::dynamic_specs_handler<test_parse_context> h(specs, ctx); - parse_format_specs(s, s + N, h); - return specs; -} - -TEST(FormatTest, ConstexprDynamicSpecsHandler) { - static_assert(parse_dynamic_specs("<").align == fmt::align::left, ""); - static_assert(parse_dynamic_specs("*^").fill[0] == '*', ""); - static_assert(parse_dynamic_specs("+").sign == fmt::sign::plus, ""); - static_assert(parse_dynamic_specs("-").sign == fmt::sign::minus, ""); - static_assert(parse_dynamic_specs(" ").sign == fmt::sign::space, ""); - static_assert(parse_dynamic_specs("#").alt, ""); - static_assert(parse_dynamic_specs("0").align == fmt::align::numeric, ""); - static_assert(parse_dynamic_specs("42").width == 42, ""); - static_assert(parse_dynamic_specs("{}").width_ref.val.index == 11, ""); - static_assert(parse_dynamic_specs("{42}").width_ref.val.index == 42, ""); - static_assert(parse_dynamic_specs(".42").precision == 42, ""); - static_assert(parse_dynamic_specs(".{}").precision_ref.val.index == 11, ""); - static_assert(parse_dynamic_specs(".{42}").precision_ref.val.index == 42, ""); - static_assert(parse_dynamic_specs("d").type == 'd', ""); -} - -template <size_t N> -FMT_CONSTEXPR test_format_specs_handler check_specs(const char (&s)[N]) { + parse_format_specs(s, s + N, h); + return specs; +} + +TEST(FormatTest, ConstexprDynamicSpecsHandler) { + static_assert(parse_dynamic_specs("<").align == fmt::align::left, ""); + static_assert(parse_dynamic_specs("*^").fill[0] == '*', ""); + static_assert(parse_dynamic_specs("+").sign == fmt::sign::plus, ""); + static_assert(parse_dynamic_specs("-").sign == fmt::sign::minus, ""); + static_assert(parse_dynamic_specs(" ").sign == fmt::sign::space, ""); + static_assert(parse_dynamic_specs("#").alt, ""); + static_assert(parse_dynamic_specs("0").align == fmt::align::numeric, ""); + static_assert(parse_dynamic_specs("42").width == 42, ""); + static_assert(parse_dynamic_specs("{}").width_ref.val.index == 11, ""); + static_assert(parse_dynamic_specs("{42}").width_ref.val.index == 42, ""); + static_assert(parse_dynamic_specs(".42").precision == 42, ""); + static_assert(parse_dynamic_specs(".{}").precision_ref.val.index == 11, ""); + static_assert(parse_dynamic_specs(".{42}").precision_ref.val.index == 42, ""); + static_assert(parse_dynamic_specs("d").type == 'd', ""); +} + +template <size_t N> +FMT_CONSTEXPR test_format_specs_handler check_specs(const char (&s)[N]) { fmt::detail::specs_checker<test_format_specs_handler> checker( test_format_specs_handler(), fmt::detail::type::double_type); - parse_format_specs(s, s + N, checker); - return checker; -} - -TEST(FormatTest, ConstexprSpecsChecker) { - typedef test_format_specs_handler handler; - static_assert(check_specs("<").align == fmt::align::left, ""); - static_assert(check_specs("*^").fill == '*', ""); - static_assert(check_specs("+").res == handler::PLUS, ""); - static_assert(check_specs("-").res == handler::MINUS, ""); - static_assert(check_specs(" ").res == handler::SPACE, ""); - static_assert(check_specs("#").res == handler::HASH, ""); - static_assert(check_specs("0").res == handler::ZERO, ""); - static_assert(check_specs("42").width == 42, ""); - static_assert(check_specs("{42}").width_ref.val.index == 42, ""); - static_assert(check_specs(".42").precision == 42, ""); - static_assert(check_specs(".{42}").precision_ref.val.index == 42, ""); - static_assert(check_specs("d").type == 'd', ""); - static_assert(check_specs("{<").res == handler::ERROR, ""); -} - -struct test_format_string_handler { - FMT_CONSTEXPR void on_text(const char*, const char*) {} - + parse_format_specs(s, s + N, checker); + return checker; +} + +TEST(FormatTest, ConstexprSpecsChecker) { + typedef test_format_specs_handler handler; + static_assert(check_specs("<").align == fmt::align::left, ""); + static_assert(check_specs("*^").fill == '*', ""); + static_assert(check_specs("+").res == handler::PLUS, ""); + static_assert(check_specs("-").res == handler::MINUS, ""); + static_assert(check_specs(" ").res == handler::SPACE, ""); + static_assert(check_specs("#").res == handler::HASH, ""); + static_assert(check_specs("0").res == handler::ZERO, ""); + static_assert(check_specs("42").width == 42, ""); + static_assert(check_specs("{42}").width_ref.val.index == 42, ""); + static_assert(check_specs(".42").precision == 42, ""); + static_assert(check_specs(".{42}").precision_ref.val.index == 42, ""); + static_assert(check_specs("d").type == 'd', ""); + static_assert(check_specs("{<").res == handler::ERROR, ""); +} + +struct test_format_string_handler { + FMT_CONSTEXPR void on_text(const char*, const char*) {} + FMT_CONSTEXPR int on_arg_id() { return 0; } - + template <typename T> FMT_CONSTEXPR int on_arg_id(T) { return 0; } - + FMT_CONSTEXPR void on_replacement_field(int, const char*) {} - + FMT_CONSTEXPR const char* on_format_specs(int, const char* begin, const char*) { - return begin; - } - - FMT_CONSTEXPR void on_error(const char*) { error = true; } - - bool error = false; -}; - -template <size_t N> FMT_CONSTEXPR bool parse_string(const char (&s)[N]) { - test_format_string_handler h; + return begin; + } + + FMT_CONSTEXPR void on_error(const char*) { error = true; } + + bool error = false; +}; + +template <size_t N> FMT_CONSTEXPR bool parse_string(const char (&s)[N]) { + test_format_string_handler h; fmt::detail::parse_format_string<true>(fmt::string_view(s, N - 1), h); - return !h.error; -} - -TEST(FormatTest, ConstexprParseFormatString) { - static_assert(parse_string("foo"), ""); - static_assert(!parse_string("}"), ""); - static_assert(parse_string("{}"), ""); - static_assert(parse_string("{42}"), ""); - static_assert(parse_string("{foo}"), ""); - static_assert(parse_string("{:}"), ""); -} - -struct test_error_handler { - const char*& error; - - FMT_CONSTEXPR test_error_handler(const char*& err) : error(err) {} - - FMT_CONSTEXPR test_error_handler(const test_error_handler& other) - : error(other.error) {} - - FMT_CONSTEXPR void on_error(const char* message) { - if (!error) error = message; - } -}; - -FMT_CONSTEXPR size_t len(const char* s) { - size_t len = 0; - while (*s++) ++len; - return len; -} - -FMT_CONSTEXPR bool equal(const char* s1, const char* s2) { - if (!s1 || !s2) return s1 == s2; - while (*s1 && *s1 == *s2) { - ++s1; - ++s2; - } - return *s1 == *s2; -} - -template <typename... Args> -FMT_CONSTEXPR bool test_error(const char* fmt, const char* expected_error) { - const char* actual_error = nullptr; + return !h.error; +} + +TEST(FormatTest, ConstexprParseFormatString) { + static_assert(parse_string("foo"), ""); + static_assert(!parse_string("}"), ""); + static_assert(parse_string("{}"), ""); + static_assert(parse_string("{42}"), ""); + static_assert(parse_string("{foo}"), ""); + static_assert(parse_string("{:}"), ""); +} + +struct test_error_handler { + const char*& error; + + FMT_CONSTEXPR test_error_handler(const char*& err) : error(err) {} + + FMT_CONSTEXPR test_error_handler(const test_error_handler& other) + : error(other.error) {} + + FMT_CONSTEXPR void on_error(const char* message) { + if (!error) error = message; + } +}; + +FMT_CONSTEXPR size_t len(const char* s) { + size_t len = 0; + while (*s++) ++len; + return len; +} + +FMT_CONSTEXPR bool equal(const char* s1, const char* s2) { + if (!s1 || !s2) return s1 == s2; + while (*s1 && *s1 == *s2) { + ++s1; + ++s2; + } + return *s1 == *s2; +} + +template <typename... Args> +FMT_CONSTEXPR bool test_error(const char* fmt, const char* expected_error) { + const char* actual_error = nullptr; string_view s(fmt, len(fmt)); fmt::detail::format_string_checker<char, test_error_handler, Args...> checker( s, test_error_handler(actual_error)); fmt::detail::parse_format_string<true>(s, checker); - return equal(actual_error, expected_error); -} - -# define EXPECT_ERROR_NOARGS(fmt, error) \ - static_assert(test_error(fmt, error), "") -# define EXPECT_ERROR(fmt, error, ...) \ - static_assert(test_error<__VA_ARGS__>(fmt, error), "") - -TEST(FormatTest, FormatStringErrors) { - EXPECT_ERROR_NOARGS("foo", nullptr); - EXPECT_ERROR_NOARGS("}", "unmatched '}' in format string"); - EXPECT_ERROR("{0:s", "unknown format specifier", Date); + return equal(actual_error, expected_error); +} + +# define EXPECT_ERROR_NOARGS(fmt, error) \ + static_assert(test_error(fmt, error), "") +# define EXPECT_ERROR(fmt, error, ...) \ + static_assert(test_error<__VA_ARGS__>(fmt, error), "") + +TEST(FormatTest, FormatStringErrors) { + EXPECT_ERROR_NOARGS("foo", nullptr); + EXPECT_ERROR_NOARGS("}", "unmatched '}' in format string"); + EXPECT_ERROR("{0:s", "unknown format specifier", Date); # if !FMT_MSC_VER || FMT_MSC_VER >= 1916 // This causes an detail compiler error in MSVC2017. - EXPECT_ERROR("{:{<}", "invalid fill character '{'", int); - EXPECT_ERROR("{:10000000000}", "number is too big", int); - EXPECT_ERROR("{:.10000000000}", "number is too big", int); + EXPECT_ERROR("{:{<}", "invalid fill character '{'", int); + EXPECT_ERROR("{:10000000000}", "number is too big", int); + EXPECT_ERROR("{:.10000000000}", "number is too big", int); EXPECT_ERROR_NOARGS("{:x}", "argument not found"); # if FMT_DEPRECATED_NUMERIC_ALIGN - EXPECT_ERROR("{0:=5", "unknown format specifier", int); - EXPECT_ERROR("{:=}", "format specifier requires numeric argument", - const char*); -# endif - EXPECT_ERROR("{:+}", "format specifier requires numeric argument", - const char*); - EXPECT_ERROR("{:-}", "format specifier requires numeric argument", - const char*); - EXPECT_ERROR("{:#}", "format specifier requires numeric argument", - const char*); - EXPECT_ERROR("{: }", "format specifier requires numeric argument", - const char*); - EXPECT_ERROR("{:0}", "format specifier requires numeric argument", - const char*); - EXPECT_ERROR("{:+}", "format specifier requires signed argument", unsigned); - EXPECT_ERROR("{:-}", "format specifier requires signed argument", unsigned); - EXPECT_ERROR("{: }", "format specifier requires signed argument", unsigned); + EXPECT_ERROR("{0:=5", "unknown format specifier", int); + EXPECT_ERROR("{:=}", "format specifier requires numeric argument", + const char*); +# endif + EXPECT_ERROR("{:+}", "format specifier requires numeric argument", + const char*); + EXPECT_ERROR("{:-}", "format specifier requires numeric argument", + const char*); + EXPECT_ERROR("{:#}", "format specifier requires numeric argument", + const char*); + EXPECT_ERROR("{: }", "format specifier requires numeric argument", + const char*); + EXPECT_ERROR("{:0}", "format specifier requires numeric argument", + const char*); + EXPECT_ERROR("{:+}", "format specifier requires signed argument", unsigned); + EXPECT_ERROR("{:-}", "format specifier requires signed argument", unsigned); + EXPECT_ERROR("{: }", "format specifier requires signed argument", unsigned); EXPECT_ERROR("{:{}}", "argument not found", int); EXPECT_ERROR("{:.{}}", "argument not found", double); - EXPECT_ERROR("{:.2}", "precision not allowed for this argument type", int); - EXPECT_ERROR("{:s}", "invalid type specifier", int); - EXPECT_ERROR("{:s}", "invalid type specifier", bool); - EXPECT_ERROR("{:s}", "invalid type specifier", char); - EXPECT_ERROR("{:+}", "invalid format specifier for char", char); - EXPECT_ERROR("{:s}", "invalid type specifier", double); - EXPECT_ERROR("{:d}", "invalid type specifier", const char*); - EXPECT_ERROR("{:d}", "invalid type specifier", std::string); - EXPECT_ERROR("{:s}", "invalid type specifier", void*); -# else - fmt::print("warning: constexpr is broken in this version of MSVC\n"); -# endif - EXPECT_ERROR("{foo", "compile-time checks don't support named arguments", - int); - EXPECT_ERROR_NOARGS("{10000000000}", "number is too big"); - EXPECT_ERROR_NOARGS("{0x}", "invalid format string"); - EXPECT_ERROR_NOARGS("{-}", "invalid format string"); - EXPECT_ERROR("{:{0x}}", "invalid format string", int); - EXPECT_ERROR("{:{-}}", "invalid format string", int); - EXPECT_ERROR("{:.{0x}}", "invalid format string", int); - EXPECT_ERROR("{:.{-}}", "invalid format string", int); - EXPECT_ERROR("{:.x}", "missing precision specifier", int); + EXPECT_ERROR("{:.2}", "precision not allowed for this argument type", int); + EXPECT_ERROR("{:s}", "invalid type specifier", int); + EXPECT_ERROR("{:s}", "invalid type specifier", bool); + EXPECT_ERROR("{:s}", "invalid type specifier", char); + EXPECT_ERROR("{:+}", "invalid format specifier for char", char); + EXPECT_ERROR("{:s}", "invalid type specifier", double); + EXPECT_ERROR("{:d}", "invalid type specifier", const char*); + EXPECT_ERROR("{:d}", "invalid type specifier", std::string); + EXPECT_ERROR("{:s}", "invalid type specifier", void*); +# else + fmt::print("warning: constexpr is broken in this version of MSVC\n"); +# endif + EXPECT_ERROR("{foo", "compile-time checks don't support named arguments", + int); + EXPECT_ERROR_NOARGS("{10000000000}", "number is too big"); + EXPECT_ERROR_NOARGS("{0x}", "invalid format string"); + EXPECT_ERROR_NOARGS("{-}", "invalid format string"); + EXPECT_ERROR("{:{0x}}", "invalid format string", int); + EXPECT_ERROR("{:{-}}", "invalid format string", int); + EXPECT_ERROR("{:.{0x}}", "invalid format string", int); + EXPECT_ERROR("{:.{-}}", "invalid format string", int); + EXPECT_ERROR("{:.x}", "missing precision specifier", int); EXPECT_ERROR_NOARGS("{}", "argument not found"); EXPECT_ERROR("{1}", "argument not found", int); - EXPECT_ERROR("{1}{}", - "cannot switch from manual to automatic argument indexing", int, - int); - EXPECT_ERROR("{}{1}", - "cannot switch from automatic to manual argument indexing", int, - int); -} - -TEST(FormatTest, VFormatTo) { - typedef fmt::format_context context; + EXPECT_ERROR("{1}{}", + "cannot switch from manual to automatic argument indexing", int, + int); + EXPECT_ERROR("{}{1}", + "cannot switch from automatic to manual argument indexing", int, + int); +} + +TEST(FormatTest, VFormatTo) { + typedef fmt::format_context context; fmt::basic_format_arg<context> arg = fmt::detail::make_arg<context>(42); - fmt::basic_format_args<context> args(&arg, 1); - std::string s; - fmt::vformat_to(std::back_inserter(s), "{}", args); - EXPECT_EQ("42", s); - s.clear(); - fmt::vformat_to(std::back_inserter(s), FMT_STRING("{}"), args); - EXPECT_EQ("42", s); - - typedef fmt::wformat_context wcontext; + fmt::basic_format_args<context> args(&arg, 1); + std::string s; + fmt::vformat_to(std::back_inserter(s), "{}", args); + EXPECT_EQ("42", s); + s.clear(); + fmt::vformat_to(std::back_inserter(s), FMT_STRING("{}"), args); + EXPECT_EQ("42", s); + + typedef fmt::wformat_context wcontext; fmt::basic_format_arg<wcontext> warg = fmt::detail::make_arg<wcontext>(42); - fmt::basic_format_args<wcontext> wargs(&warg, 1); - std::wstring w; - fmt::vformat_to(std::back_inserter(w), L"{}", wargs); - EXPECT_EQ(L"42", w); - w.clear(); - fmt::vformat_to(std::back_inserter(w), FMT_STRING(L"{}"), wargs); - EXPECT_EQ(L"42", w); -} - -template <typename T> static std::string FmtToString(const T& t) { - return fmt::format(FMT_STRING("{}"), t); -} - -TEST(FormatTest, FmtStringInTemplate) { - EXPECT_EQ(FmtToString(1), "1"); - EXPECT_EQ(FmtToString(0), "0"); -} - -#endif // FMT_USE_CONSTEXPR - -TEST(FormatTest, CharTraitsIsNotAmbiguous) { + fmt::basic_format_args<wcontext> wargs(&warg, 1); + std::wstring w; + fmt::vformat_to(std::back_inserter(w), L"{}", wargs); + EXPECT_EQ(L"42", w); + w.clear(); + fmt::vformat_to(std::back_inserter(w), FMT_STRING(L"{}"), wargs); + EXPECT_EQ(L"42", w); +} + +template <typename T> static std::string FmtToString(const T& t) { + return fmt::format(FMT_STRING("{}"), t); +} + +TEST(FormatTest, FmtStringInTemplate) { + EXPECT_EQ(FmtToString(1), "1"); + EXPECT_EQ(FmtToString(0), "0"); +} + +#endif // FMT_USE_CONSTEXPR + +TEST(FormatTest, CharTraitsIsNotAmbiguous) { // Test that we don't inject detail names into the std namespace. - using namespace std; - char_traits<char>::char_type c; - (void)c; -#if __cplusplus >= 201103L - std::string s; - auto lval = begin(s); - (void)lval; -#endif -} - + using namespace std; + char_traits<char>::char_type c; + (void)c; +#if __cplusplus >= 201103L + std::string s; + auto lval = begin(s); + (void)lval; +#endif +} + #if __cplusplus > 201103L struct custom_char { - int value; + int value; custom_char() = default; - + template <typename T> constexpr custom_char(T val) : value(static_cast<int>(val)) {} - - operator int() const { return value; } -}; - + + operator int() const { return value; } +}; + int to_ascii(custom_char c) { return c; } -FMT_BEGIN_NAMESPACE +FMT_BEGIN_NAMESPACE template <> struct is_char<custom_char> : std::true_type {}; -FMT_END_NAMESPACE - -TEST(FormatTest, FormatCustomChar) { +FMT_END_NAMESPACE + +TEST(FormatTest, FormatCustomChar) { const custom_char format[] = {'{', '}', 0}; auto result = fmt::format(format, custom_char('x')); - EXPECT_EQ(result.size(), 1); + EXPECT_EQ(result.size(), 1); EXPECT_EQ(result[0], custom_char('x')); -} +} #endif - -// Convert a char8_t string to std::string. Otherwise GTest will insist on -// inserting `char8_t` NTBS into a `char` stream which is disabled by P1423. -template <typename S> std::string from_u8str(const S& str) { - return std::string(str.begin(), str.end()); -} - -TEST(FormatTest, FormatUTF8Precision) { + +// Convert a char8_t string to std::string. Otherwise GTest will insist on +// inserting `char8_t` NTBS into a `char` stream which is disabled by P1423. +template <typename S> std::string from_u8str(const S& str) { + return std::string(str.begin(), str.end()); +} + +TEST(FormatTest, FormatUTF8Precision) { using str_type = std::basic_string<fmt::detail::char8_type>; str_type format(reinterpret_cast<const fmt::detail::char8_type*>(u8"{:.4}")); str_type str(reinterpret_cast<const fmt::detail::char8_type*>( - u8"caf\u00e9s")); // cafés - auto result = fmt::format(format, str); + u8"caf\u00e9s")); // cafés + auto result = fmt::format(format, str); EXPECT_EQ(fmt::detail::count_code_points(result), 4); - EXPECT_EQ(result.size(), 5); - EXPECT_EQ(from_u8str(result), from_u8str(str.substr(0, 5))); -} + EXPECT_EQ(result.size(), 5); + EXPECT_EQ(from_u8str(result), from_u8str(str.substr(0, 5))); +} struct check_back_appender {}; diff --git a/contrib/libs/fmt/test/format-test/ya.make b/contrib/libs/fmt/test/format-test/ya.make index 053554fddf..bc3d7c85c8 100644 --- a/contrib/libs/fmt/test/format-test/ya.make +++ b/contrib/libs/fmt/test/format-test/ya.make @@ -1,39 +1,39 @@ -# Generated by devtools/yamaker. - +# Generated by devtools/yamaker. + GTEST() - + WITHOUT_LICENSE_TEXTS() - + OWNER( orivej g:cpp-contrib ) -LICENSE(MIT) - -ALLOCATOR(J) - -PEERDIR( - contrib/libs/fmt - contrib/libs/fmt/test -) - -NO_COMPILER_WARNINGS() - -NO_UTIL() - -CFLAGS( - -DFMT_LOCALE - -DFMT_SHARED - -DGTEST_HAS_STD_WSTRING=1 - -DGTEST_LANG_CXX11=0 - -D_SILENCE_TR1_NAMESPACE_DEPRECATION_WARNING=1 -) - -SRCDIR(contrib/libs/fmt/test) - -SRCS( - format-test.cc -) - -END() +LICENSE(MIT) + +ALLOCATOR(J) + +PEERDIR( + contrib/libs/fmt + contrib/libs/fmt/test +) + +NO_COMPILER_WARNINGS() + +NO_UTIL() + +CFLAGS( + -DFMT_LOCALE + -DFMT_SHARED + -DGTEST_HAS_STD_WSTRING=1 + -DGTEST_LANG_CXX11=0 + -D_SILENCE_TR1_NAMESPACE_DEPRECATION_WARNING=1 +) + +SRCDIR(contrib/libs/fmt/test) + +SRCS( + format-test.cc +) + +END() diff --git a/contrib/libs/fmt/test/gtest-extra-test.cc b/contrib/libs/fmt/test/gtest-extra-test.cc index 80b3007748..ea728607e8 100644 --- a/contrib/libs/fmt/test/gtest-extra-test.cc +++ b/contrib/libs/fmt/test/gtest-extra-test.cc @@ -1,173 +1,173 @@ -// Formatting library for C++ - tests of custom Google Test assertions -// -// Copyright (c) 2012 - present, Victor Zverovich -// All rights reserved. -// -// For the license information refer to format.h. - -#include "gtest-extra.h" - -#include <gtest/gtest-spi.h> - -#include <algorithm> -#include <cstring> -#include <memory> -#include <stdexcept> - -#if defined(_WIN32) && !defined(__MINGW32__) -# include <crtdbg.h> // for _CrtSetReportMode -#endif // _WIN32 - -#include "util.h" - -namespace { - -// This is used to suppress coverity warnings about untrusted values. -std::string sanitize(const std::string& s) { - std::string result; - for (std::string::const_iterator i = s.begin(), end = s.end(); i != end; ++i) - result.push_back(static_cast<char>(*i & 0xff)); - return result; -} - -// Tests that assertion macros evaluate their arguments exactly once. -class SingleEvaluationTest : public ::testing::Test { - protected: - SingleEvaluationTest() { - p_ = s_; - a_ = 0; - b_ = 0; - } - - static const char* const s_; - static const char* p_; - - static int a_; - static int b_; -}; - -const char* const SingleEvaluationTest::s_ = "01234"; -const char* SingleEvaluationTest::p_; -int SingleEvaluationTest::a_; -int SingleEvaluationTest::b_; - -void do_nothing() {} - -FMT_NORETURN void throw_exception() { throw std::runtime_error("test"); } - -FMT_NORETURN void throw_system_error() { - throw fmt::system_error(EDOM, "test"); -} - -// Tests that when EXPECT_THROW_MSG fails, it evaluates its message argument -// exactly once. -TEST_F(SingleEvaluationTest, FailedEXPECT_THROW_MSG) { - EXPECT_NONFATAL_FAILURE( - EXPECT_THROW_MSG(throw_exception(), std::exception, p_++), "01234"); - EXPECT_EQ(s_ + 1, p_); -} - -// Tests that when EXPECT_SYSTEM_ERROR fails, it evaluates its message argument -// exactly once. -TEST_F(SingleEvaluationTest, FailedEXPECT_SYSTEM_ERROR) { - EXPECT_NONFATAL_FAILURE(EXPECT_SYSTEM_ERROR(throw_system_error(), EDOM, p_++), - "01234"); - EXPECT_EQ(s_ + 1, p_); -} - -// Tests that assertion arguments are evaluated exactly once. -TEST_F(SingleEvaluationTest, ExceptionTests) { - // successful EXPECT_THROW_MSG - EXPECT_THROW_MSG( - { // NOLINT - a_++; - throw_exception(); - }, - std::exception, (b_++, "test")); - EXPECT_EQ(1, a_); - EXPECT_EQ(1, b_); - - // failed EXPECT_THROW_MSG, throws different type - EXPECT_NONFATAL_FAILURE(EXPECT_THROW_MSG( - { // NOLINT - a_++; - throw_exception(); - }, - std::logic_error, (b_++, "test")), - "throws a different type"); - EXPECT_EQ(2, a_); - EXPECT_EQ(2, b_); - - // failed EXPECT_THROW_MSG, throws an exception with different message - EXPECT_NONFATAL_FAILURE(EXPECT_THROW_MSG( - { // NOLINT - a_++; - throw_exception(); - }, - std::exception, (b_++, "other")), - "throws an exception with a different message"); - EXPECT_EQ(3, a_); - EXPECT_EQ(3, b_); - - // failed EXPECT_THROW_MSG, throws nothing - EXPECT_NONFATAL_FAILURE( - EXPECT_THROW_MSG(a_++, std::exception, (b_++, "test")), "throws nothing"); - EXPECT_EQ(4, a_); - EXPECT_EQ(4, b_); -} - -TEST_F(SingleEvaluationTest, SystemErrorTests) { - // successful EXPECT_SYSTEM_ERROR - EXPECT_SYSTEM_ERROR( - { // NOLINT - a_++; - throw_system_error(); - }, - EDOM, (b_++, "test")); - EXPECT_EQ(1, a_); - EXPECT_EQ(1, b_); - - // failed EXPECT_SYSTEM_ERROR, throws different type - EXPECT_NONFATAL_FAILURE(EXPECT_SYSTEM_ERROR( - { // NOLINT - a_++; - throw_exception(); - }, - EDOM, (b_++, "test")), - "throws a different type"); - EXPECT_EQ(2, a_); - EXPECT_EQ(2, b_); - - // failed EXPECT_SYSTEM_ERROR, throws an exception with different message - EXPECT_NONFATAL_FAILURE(EXPECT_SYSTEM_ERROR( - { // NOLINT - a_++; - throw_system_error(); - }, - EDOM, (b_++, "other")), - "throws an exception with a different message"); - EXPECT_EQ(3, a_); - EXPECT_EQ(3, b_); - - // failed EXPECT_SYSTEM_ERROR, throws nothing - EXPECT_NONFATAL_FAILURE(EXPECT_SYSTEM_ERROR(a_++, EDOM, (b_++, "test")), - "throws nothing"); - EXPECT_EQ(4, a_); - EXPECT_EQ(4, b_); -} - -#if FMT_USE_FCNTL -// Tests that when EXPECT_WRITE fails, it evaluates its message argument -// exactly once. -TEST_F(SingleEvaluationTest, FailedEXPECT_WRITE) { - EXPECT_NONFATAL_FAILURE(EXPECT_WRITE(stdout, std::printf("test"), p_++), - "01234"); - EXPECT_EQ(s_ + 1, p_); -} - -// Tests that assertion arguments are evaluated exactly once. -TEST_F(SingleEvaluationTest, WriteTests) { - // successful EXPECT_WRITE +// Formatting library for C++ - tests of custom Google Test assertions +// +// Copyright (c) 2012 - present, Victor Zverovich +// All rights reserved. +// +// For the license information refer to format.h. + +#include "gtest-extra.h" + +#include <gtest/gtest-spi.h> + +#include <algorithm> +#include <cstring> +#include <memory> +#include <stdexcept> + +#if defined(_WIN32) && !defined(__MINGW32__) +# include <crtdbg.h> // for _CrtSetReportMode +#endif // _WIN32 + +#include "util.h" + +namespace { + +// This is used to suppress coverity warnings about untrusted values. +std::string sanitize(const std::string& s) { + std::string result; + for (std::string::const_iterator i = s.begin(), end = s.end(); i != end; ++i) + result.push_back(static_cast<char>(*i & 0xff)); + return result; +} + +// Tests that assertion macros evaluate their arguments exactly once. +class SingleEvaluationTest : public ::testing::Test { + protected: + SingleEvaluationTest() { + p_ = s_; + a_ = 0; + b_ = 0; + } + + static const char* const s_; + static const char* p_; + + static int a_; + static int b_; +}; + +const char* const SingleEvaluationTest::s_ = "01234"; +const char* SingleEvaluationTest::p_; +int SingleEvaluationTest::a_; +int SingleEvaluationTest::b_; + +void do_nothing() {} + +FMT_NORETURN void throw_exception() { throw std::runtime_error("test"); } + +FMT_NORETURN void throw_system_error() { + throw fmt::system_error(EDOM, "test"); +} + +// Tests that when EXPECT_THROW_MSG fails, it evaluates its message argument +// exactly once. +TEST_F(SingleEvaluationTest, FailedEXPECT_THROW_MSG) { + EXPECT_NONFATAL_FAILURE( + EXPECT_THROW_MSG(throw_exception(), std::exception, p_++), "01234"); + EXPECT_EQ(s_ + 1, p_); +} + +// Tests that when EXPECT_SYSTEM_ERROR fails, it evaluates its message argument +// exactly once. +TEST_F(SingleEvaluationTest, FailedEXPECT_SYSTEM_ERROR) { + EXPECT_NONFATAL_FAILURE(EXPECT_SYSTEM_ERROR(throw_system_error(), EDOM, p_++), + "01234"); + EXPECT_EQ(s_ + 1, p_); +} + +// Tests that assertion arguments are evaluated exactly once. +TEST_F(SingleEvaluationTest, ExceptionTests) { + // successful EXPECT_THROW_MSG + EXPECT_THROW_MSG( + { // NOLINT + a_++; + throw_exception(); + }, + std::exception, (b_++, "test")); + EXPECT_EQ(1, a_); + EXPECT_EQ(1, b_); + + // failed EXPECT_THROW_MSG, throws different type + EXPECT_NONFATAL_FAILURE(EXPECT_THROW_MSG( + { // NOLINT + a_++; + throw_exception(); + }, + std::logic_error, (b_++, "test")), + "throws a different type"); + EXPECT_EQ(2, a_); + EXPECT_EQ(2, b_); + + // failed EXPECT_THROW_MSG, throws an exception with different message + EXPECT_NONFATAL_FAILURE(EXPECT_THROW_MSG( + { // NOLINT + a_++; + throw_exception(); + }, + std::exception, (b_++, "other")), + "throws an exception with a different message"); + EXPECT_EQ(3, a_); + EXPECT_EQ(3, b_); + + // failed EXPECT_THROW_MSG, throws nothing + EXPECT_NONFATAL_FAILURE( + EXPECT_THROW_MSG(a_++, std::exception, (b_++, "test")), "throws nothing"); + EXPECT_EQ(4, a_); + EXPECT_EQ(4, b_); +} + +TEST_F(SingleEvaluationTest, SystemErrorTests) { + // successful EXPECT_SYSTEM_ERROR + EXPECT_SYSTEM_ERROR( + { // NOLINT + a_++; + throw_system_error(); + }, + EDOM, (b_++, "test")); + EXPECT_EQ(1, a_); + EXPECT_EQ(1, b_); + + // failed EXPECT_SYSTEM_ERROR, throws different type + EXPECT_NONFATAL_FAILURE(EXPECT_SYSTEM_ERROR( + { // NOLINT + a_++; + throw_exception(); + }, + EDOM, (b_++, "test")), + "throws a different type"); + EXPECT_EQ(2, a_); + EXPECT_EQ(2, b_); + + // failed EXPECT_SYSTEM_ERROR, throws an exception with different message + EXPECT_NONFATAL_FAILURE(EXPECT_SYSTEM_ERROR( + { // NOLINT + a_++; + throw_system_error(); + }, + EDOM, (b_++, "other")), + "throws an exception with a different message"); + EXPECT_EQ(3, a_); + EXPECT_EQ(3, b_); + + // failed EXPECT_SYSTEM_ERROR, throws nothing + EXPECT_NONFATAL_FAILURE(EXPECT_SYSTEM_ERROR(a_++, EDOM, (b_++, "test")), + "throws nothing"); + EXPECT_EQ(4, a_); + EXPECT_EQ(4, b_); +} + +#if FMT_USE_FCNTL +// Tests that when EXPECT_WRITE fails, it evaluates its message argument +// exactly once. +TEST_F(SingleEvaluationTest, FailedEXPECT_WRITE) { + EXPECT_NONFATAL_FAILURE(EXPECT_WRITE(stdout, std::printf("test"), p_++), + "01234"); + EXPECT_EQ(s_ + 1, p_); +} + +// Tests that assertion arguments are evaluated exactly once. +TEST_F(SingleEvaluationTest, WriteTests) { + // successful EXPECT_WRITE EXPECT_WRITE( stdout, { // NOLINT @@ -175,10 +175,10 @@ TEST_F(SingleEvaluationTest, WriteTests) { std::printf("test"); }, (b_++, "test")); - EXPECT_EQ(1, a_); - EXPECT_EQ(1, b_); - - // failed EXPECT_WRITE + EXPECT_EQ(1, a_); + EXPECT_EQ(1, b_); + + // failed EXPECT_WRITE EXPECT_NONFATAL_FAILURE(EXPECT_WRITE( stdout, { // NOLINT @@ -186,240 +186,240 @@ TEST_F(SingleEvaluationTest, WriteTests) { std::printf("test"); }, (b_++, "other")), - "Actual: test"); - EXPECT_EQ(2, a_); - EXPECT_EQ(2, b_); -} - -// Tests EXPECT_WRITE. -TEST(ExpectTest, EXPECT_WRITE) { - EXPECT_WRITE(stdout, do_nothing(), ""); - EXPECT_WRITE(stdout, std::printf("test"), "test"); - EXPECT_WRITE(stderr, std::fprintf(stderr, "test"), "test"); - EXPECT_NONFATAL_FAILURE(EXPECT_WRITE(stdout, std::printf("that"), "this"), - "Expected: this\n" - " Actual: that"); -} - -TEST(StreamingAssertionsTest, EXPECT_WRITE) { - EXPECT_WRITE(stdout, std::printf("test"), "test") << "unexpected failure"; - EXPECT_NONFATAL_FAILURE(EXPECT_WRITE(stdout, std::printf("test"), "other") - << "expected failure", - "expected failure"); -} -#endif // FMT_USE_FCNTL - -// Tests that the compiler will not complain about unreachable code in the -// EXPECT_THROW_MSG macro. -TEST(ExpectThrowTest, DoesNotGenerateUnreachableCodeWarning) { - int n = 0; - using std::runtime_error; - EXPECT_THROW_MSG(throw runtime_error(""), runtime_error, ""); - EXPECT_NONFATAL_FAILURE(EXPECT_THROW_MSG(n++, runtime_error, ""), ""); - EXPECT_NONFATAL_FAILURE(EXPECT_THROW_MSG(throw 1, runtime_error, ""), ""); - EXPECT_NONFATAL_FAILURE( - EXPECT_THROW_MSG(throw runtime_error("a"), runtime_error, "b"), ""); -} - -// Tests that the compiler will not complain about unreachable code in the -// EXPECT_SYSTEM_ERROR macro. -TEST(ExpectSystemErrorTest, DoesNotGenerateUnreachableCodeWarning) { - int n = 0; - EXPECT_SYSTEM_ERROR(throw fmt::system_error(EDOM, "test"), EDOM, "test"); - EXPECT_NONFATAL_FAILURE(EXPECT_SYSTEM_ERROR(n++, EDOM, ""), ""); - EXPECT_NONFATAL_FAILURE(EXPECT_SYSTEM_ERROR(throw 1, EDOM, ""), ""); - EXPECT_NONFATAL_FAILURE( - EXPECT_SYSTEM_ERROR(throw fmt::system_error(EDOM, "aaa"), EDOM, "bbb"), - ""); -} - -TEST(AssertionSyntaxTest, ExceptionAssertionBehavesLikeSingleStatement) { - if (::testing::internal::AlwaysFalse()) - EXPECT_THROW_MSG(do_nothing(), std::exception, ""); - - if (::testing::internal::AlwaysTrue()) - EXPECT_THROW_MSG(throw_exception(), std::exception, "test"); - else - do_nothing(); -} - -TEST(AssertionSyntaxTest, SystemErrorAssertionBehavesLikeSingleStatement) { - if (::testing::internal::AlwaysFalse()) - EXPECT_SYSTEM_ERROR(do_nothing(), EDOM, ""); - - if (::testing::internal::AlwaysTrue()) - EXPECT_SYSTEM_ERROR(throw_system_error(), EDOM, "test"); - else - do_nothing(); -} - -TEST(AssertionSyntaxTest, WriteAssertionBehavesLikeSingleStatement) { - if (::testing::internal::AlwaysFalse()) - EXPECT_WRITE(stdout, std::printf("x"), "x"); - - if (::testing::internal::AlwaysTrue()) - EXPECT_WRITE(stdout, std::printf("x"), "x"); - else - do_nothing(); -} - -// Tests EXPECT_THROW_MSG. -TEST(ExpectTest, EXPECT_THROW_MSG) { - EXPECT_THROW_MSG(throw_exception(), std::exception, "test"); - EXPECT_NONFATAL_FAILURE( - EXPECT_THROW_MSG(throw_exception(), std::logic_error, "test"), - "Expected: throw_exception() throws an exception of " - "type std::logic_error.\n Actual: it throws a different type."); - EXPECT_NONFATAL_FAILURE( - EXPECT_THROW_MSG(do_nothing(), std::exception, "test"), - "Expected: do_nothing() throws an exception of type std::exception.\n" - " Actual: it throws nothing."); - EXPECT_NONFATAL_FAILURE( - EXPECT_THROW_MSG(throw_exception(), std::exception, "other"), - "throw_exception() throws an exception with a different message.\n" - "Expected: other\n" - " Actual: test"); -} - -// Tests EXPECT_SYSTEM_ERROR. -TEST(ExpectTest, EXPECT_SYSTEM_ERROR) { - EXPECT_SYSTEM_ERROR(throw_system_error(), EDOM, "test"); - EXPECT_NONFATAL_FAILURE( - EXPECT_SYSTEM_ERROR(throw_exception(), EDOM, "test"), - "Expected: throw_exception() throws an exception of " - "type fmt::system_error.\n Actual: it throws a different type."); - EXPECT_NONFATAL_FAILURE( - EXPECT_SYSTEM_ERROR(do_nothing(), EDOM, "test"), - "Expected: do_nothing() throws an exception of type fmt::system_error.\n" - " Actual: it throws nothing."); - EXPECT_NONFATAL_FAILURE( - EXPECT_SYSTEM_ERROR(throw_system_error(), EDOM, "other"), - fmt::format( - "throw_system_error() throws an exception with a different message.\n" - "Expected: {}\n" - " Actual: {}", - format_system_error(EDOM, "other"), - format_system_error(EDOM, "test"))); -} - -TEST(StreamingAssertionsTest, EXPECT_THROW_MSG) { - EXPECT_THROW_MSG(throw_exception(), std::exception, "test") - << "unexpected failure"; - EXPECT_NONFATAL_FAILURE( - EXPECT_THROW_MSG(throw_exception(), std::exception, "other") - << "expected failure", - "expected failure"); -} - -TEST(StreamingAssertionsTest, EXPECT_SYSTEM_ERROR) { - EXPECT_SYSTEM_ERROR(throw_system_error(), EDOM, "test") - << "unexpected failure"; - EXPECT_NONFATAL_FAILURE( - EXPECT_SYSTEM_ERROR(throw_system_error(), EDOM, "other") - << "expected failure", - "expected failure"); -} - -TEST(UtilTest, FormatSystemError) { - fmt::memory_buffer out; - fmt::format_system_error(out, EDOM, "test message"); - EXPECT_EQ(to_string(out), format_system_error(EDOM, "test message")); -} - -#if FMT_USE_FCNTL - -using fmt::buffered_file; -using fmt::error_code; -using fmt::file; - -TEST(ErrorCodeTest, Ctor) { - EXPECT_EQ(error_code().get(), 0); - EXPECT_EQ(error_code(42).get(), 42); -} - -TEST(OutputRedirectTest, ScopedRedirect) { - file read_end, write_end; - file::pipe(read_end, write_end); - { - buffered_file file(write_end.fdopen("w")); - std::fprintf(file.get(), "[[["); - { - OutputRedirect redir(file.get()); - std::fprintf(file.get(), "censored"); - } - std::fprintf(file.get(), "]]]"); - } - EXPECT_READ(read_end, "[[[]]]"); -} - -// Test that OutputRedirect handles errors in flush correctly. -TEST(OutputRedirectTest, FlushErrorInCtor) { - file read_end, write_end; - file::pipe(read_end, write_end); - int write_fd = write_end.descriptor(); - file write_copy = write_end.dup(write_fd); - buffered_file f = write_end.fdopen("w"); - // Put a character in a file buffer. - EXPECT_EQ('x', fputc('x', f.get())); - FMT_POSIX(close(write_fd)); - std::unique_ptr<OutputRedirect> redir{nullptr}; - EXPECT_SYSTEM_ERROR_NOASSERT(redir.reset(new OutputRedirect(f.get())), EBADF, - "cannot flush stream"); - redir.reset(nullptr); - write_copy.dup2(write_fd); // "undo" close or dtor will fail -} - -TEST(OutputRedirectTest, DupErrorInCtor) { - buffered_file f = open_buffered_file(); - int fd = (f.fileno)(); - file copy = file::dup(fd); - FMT_POSIX(close(fd)); - std::unique_ptr<OutputRedirect> redir{nullptr}; - EXPECT_SYSTEM_ERROR_NOASSERT( - redir.reset(new OutputRedirect(f.get())), EBADF, - fmt::format("cannot duplicate file descriptor {}", fd)); - copy.dup2(fd); // "undo" close or dtor will fail -} - -TEST(OutputRedirectTest, RestoreAndRead) { - file read_end, write_end; - file::pipe(read_end, write_end); - buffered_file file(write_end.fdopen("w")); - std::fprintf(file.get(), "[[["); - OutputRedirect redir(file.get()); - std::fprintf(file.get(), "censored"); - EXPECT_EQ("censored", sanitize(redir.restore_and_read())); - EXPECT_EQ("", sanitize(redir.restore_and_read())); - std::fprintf(file.get(), "]]]"); - file = buffered_file(); - EXPECT_READ(read_end, "[[[]]]"); -} - -// Test that OutputRedirect handles errors in flush correctly. -TEST(OutputRedirectTest, FlushErrorInRestoreAndRead) { - file read_end, write_end; - file::pipe(read_end, write_end); - int write_fd = write_end.descriptor(); - file write_copy = write_end.dup(write_fd); - buffered_file f = write_end.fdopen("w"); - OutputRedirect redir(f.get()); - // Put a character in a file buffer. - EXPECT_EQ('x', fputc('x', f.get())); - FMT_POSIX(close(write_fd)); - EXPECT_SYSTEM_ERROR_NOASSERT(redir.restore_and_read(), EBADF, - "cannot flush stream"); - write_copy.dup2(write_fd); // "undo" close or dtor will fail -} - -TEST(OutputRedirectTest, ErrorInDtor) { - file read_end, write_end; - file::pipe(read_end, write_end); - int write_fd = write_end.descriptor(); - file write_copy = write_end.dup(write_fd); - buffered_file f = write_end.fdopen("w"); - std::unique_ptr<OutputRedirect> redir(new OutputRedirect(f.get())); - // Put a character in a file buffer. - EXPECT_EQ('x', fputc('x', f.get())); + "Actual: test"); + EXPECT_EQ(2, a_); + EXPECT_EQ(2, b_); +} + +// Tests EXPECT_WRITE. +TEST(ExpectTest, EXPECT_WRITE) { + EXPECT_WRITE(stdout, do_nothing(), ""); + EXPECT_WRITE(stdout, std::printf("test"), "test"); + EXPECT_WRITE(stderr, std::fprintf(stderr, "test"), "test"); + EXPECT_NONFATAL_FAILURE(EXPECT_WRITE(stdout, std::printf("that"), "this"), + "Expected: this\n" + " Actual: that"); +} + +TEST(StreamingAssertionsTest, EXPECT_WRITE) { + EXPECT_WRITE(stdout, std::printf("test"), "test") << "unexpected failure"; + EXPECT_NONFATAL_FAILURE(EXPECT_WRITE(stdout, std::printf("test"), "other") + << "expected failure", + "expected failure"); +} +#endif // FMT_USE_FCNTL + +// Tests that the compiler will not complain about unreachable code in the +// EXPECT_THROW_MSG macro. +TEST(ExpectThrowTest, DoesNotGenerateUnreachableCodeWarning) { + int n = 0; + using std::runtime_error; + EXPECT_THROW_MSG(throw runtime_error(""), runtime_error, ""); + EXPECT_NONFATAL_FAILURE(EXPECT_THROW_MSG(n++, runtime_error, ""), ""); + EXPECT_NONFATAL_FAILURE(EXPECT_THROW_MSG(throw 1, runtime_error, ""), ""); + EXPECT_NONFATAL_FAILURE( + EXPECT_THROW_MSG(throw runtime_error("a"), runtime_error, "b"), ""); +} + +// Tests that the compiler will not complain about unreachable code in the +// EXPECT_SYSTEM_ERROR macro. +TEST(ExpectSystemErrorTest, DoesNotGenerateUnreachableCodeWarning) { + int n = 0; + EXPECT_SYSTEM_ERROR(throw fmt::system_error(EDOM, "test"), EDOM, "test"); + EXPECT_NONFATAL_FAILURE(EXPECT_SYSTEM_ERROR(n++, EDOM, ""), ""); + EXPECT_NONFATAL_FAILURE(EXPECT_SYSTEM_ERROR(throw 1, EDOM, ""), ""); + EXPECT_NONFATAL_FAILURE( + EXPECT_SYSTEM_ERROR(throw fmt::system_error(EDOM, "aaa"), EDOM, "bbb"), + ""); +} + +TEST(AssertionSyntaxTest, ExceptionAssertionBehavesLikeSingleStatement) { + if (::testing::internal::AlwaysFalse()) + EXPECT_THROW_MSG(do_nothing(), std::exception, ""); + + if (::testing::internal::AlwaysTrue()) + EXPECT_THROW_MSG(throw_exception(), std::exception, "test"); + else + do_nothing(); +} + +TEST(AssertionSyntaxTest, SystemErrorAssertionBehavesLikeSingleStatement) { + if (::testing::internal::AlwaysFalse()) + EXPECT_SYSTEM_ERROR(do_nothing(), EDOM, ""); + + if (::testing::internal::AlwaysTrue()) + EXPECT_SYSTEM_ERROR(throw_system_error(), EDOM, "test"); + else + do_nothing(); +} + +TEST(AssertionSyntaxTest, WriteAssertionBehavesLikeSingleStatement) { + if (::testing::internal::AlwaysFalse()) + EXPECT_WRITE(stdout, std::printf("x"), "x"); + + if (::testing::internal::AlwaysTrue()) + EXPECT_WRITE(stdout, std::printf("x"), "x"); + else + do_nothing(); +} + +// Tests EXPECT_THROW_MSG. +TEST(ExpectTest, EXPECT_THROW_MSG) { + EXPECT_THROW_MSG(throw_exception(), std::exception, "test"); + EXPECT_NONFATAL_FAILURE( + EXPECT_THROW_MSG(throw_exception(), std::logic_error, "test"), + "Expected: throw_exception() throws an exception of " + "type std::logic_error.\n Actual: it throws a different type."); + EXPECT_NONFATAL_FAILURE( + EXPECT_THROW_MSG(do_nothing(), std::exception, "test"), + "Expected: do_nothing() throws an exception of type std::exception.\n" + " Actual: it throws nothing."); + EXPECT_NONFATAL_FAILURE( + EXPECT_THROW_MSG(throw_exception(), std::exception, "other"), + "throw_exception() throws an exception with a different message.\n" + "Expected: other\n" + " Actual: test"); +} + +// Tests EXPECT_SYSTEM_ERROR. +TEST(ExpectTest, EXPECT_SYSTEM_ERROR) { + EXPECT_SYSTEM_ERROR(throw_system_error(), EDOM, "test"); + EXPECT_NONFATAL_FAILURE( + EXPECT_SYSTEM_ERROR(throw_exception(), EDOM, "test"), + "Expected: throw_exception() throws an exception of " + "type fmt::system_error.\n Actual: it throws a different type."); + EXPECT_NONFATAL_FAILURE( + EXPECT_SYSTEM_ERROR(do_nothing(), EDOM, "test"), + "Expected: do_nothing() throws an exception of type fmt::system_error.\n" + " Actual: it throws nothing."); + EXPECT_NONFATAL_FAILURE( + EXPECT_SYSTEM_ERROR(throw_system_error(), EDOM, "other"), + fmt::format( + "throw_system_error() throws an exception with a different message.\n" + "Expected: {}\n" + " Actual: {}", + format_system_error(EDOM, "other"), + format_system_error(EDOM, "test"))); +} + +TEST(StreamingAssertionsTest, EXPECT_THROW_MSG) { + EXPECT_THROW_MSG(throw_exception(), std::exception, "test") + << "unexpected failure"; + EXPECT_NONFATAL_FAILURE( + EXPECT_THROW_MSG(throw_exception(), std::exception, "other") + << "expected failure", + "expected failure"); +} + +TEST(StreamingAssertionsTest, EXPECT_SYSTEM_ERROR) { + EXPECT_SYSTEM_ERROR(throw_system_error(), EDOM, "test") + << "unexpected failure"; + EXPECT_NONFATAL_FAILURE( + EXPECT_SYSTEM_ERROR(throw_system_error(), EDOM, "other") + << "expected failure", + "expected failure"); +} + +TEST(UtilTest, FormatSystemError) { + fmt::memory_buffer out; + fmt::format_system_error(out, EDOM, "test message"); + EXPECT_EQ(to_string(out), format_system_error(EDOM, "test message")); +} + +#if FMT_USE_FCNTL + +using fmt::buffered_file; +using fmt::error_code; +using fmt::file; + +TEST(ErrorCodeTest, Ctor) { + EXPECT_EQ(error_code().get(), 0); + EXPECT_EQ(error_code(42).get(), 42); +} + +TEST(OutputRedirectTest, ScopedRedirect) { + file read_end, write_end; + file::pipe(read_end, write_end); + { + buffered_file file(write_end.fdopen("w")); + std::fprintf(file.get(), "[[["); + { + OutputRedirect redir(file.get()); + std::fprintf(file.get(), "censored"); + } + std::fprintf(file.get(), "]]]"); + } + EXPECT_READ(read_end, "[[[]]]"); +} + +// Test that OutputRedirect handles errors in flush correctly. +TEST(OutputRedirectTest, FlushErrorInCtor) { + file read_end, write_end; + file::pipe(read_end, write_end); + int write_fd = write_end.descriptor(); + file write_copy = write_end.dup(write_fd); + buffered_file f = write_end.fdopen("w"); + // Put a character in a file buffer. + EXPECT_EQ('x', fputc('x', f.get())); + FMT_POSIX(close(write_fd)); + std::unique_ptr<OutputRedirect> redir{nullptr}; + EXPECT_SYSTEM_ERROR_NOASSERT(redir.reset(new OutputRedirect(f.get())), EBADF, + "cannot flush stream"); + redir.reset(nullptr); + write_copy.dup2(write_fd); // "undo" close or dtor will fail +} + +TEST(OutputRedirectTest, DupErrorInCtor) { + buffered_file f = open_buffered_file(); + int fd = (f.fileno)(); + file copy = file::dup(fd); + FMT_POSIX(close(fd)); + std::unique_ptr<OutputRedirect> redir{nullptr}; + EXPECT_SYSTEM_ERROR_NOASSERT( + redir.reset(new OutputRedirect(f.get())), EBADF, + fmt::format("cannot duplicate file descriptor {}", fd)); + copy.dup2(fd); // "undo" close or dtor will fail +} + +TEST(OutputRedirectTest, RestoreAndRead) { + file read_end, write_end; + file::pipe(read_end, write_end); + buffered_file file(write_end.fdopen("w")); + std::fprintf(file.get(), "[[["); + OutputRedirect redir(file.get()); + std::fprintf(file.get(), "censored"); + EXPECT_EQ("censored", sanitize(redir.restore_and_read())); + EXPECT_EQ("", sanitize(redir.restore_and_read())); + std::fprintf(file.get(), "]]]"); + file = buffered_file(); + EXPECT_READ(read_end, "[[[]]]"); +} + +// Test that OutputRedirect handles errors in flush correctly. +TEST(OutputRedirectTest, FlushErrorInRestoreAndRead) { + file read_end, write_end; + file::pipe(read_end, write_end); + int write_fd = write_end.descriptor(); + file write_copy = write_end.dup(write_fd); + buffered_file f = write_end.fdopen("w"); + OutputRedirect redir(f.get()); + // Put a character in a file buffer. + EXPECT_EQ('x', fputc('x', f.get())); + FMT_POSIX(close(write_fd)); + EXPECT_SYSTEM_ERROR_NOASSERT(redir.restore_and_read(), EBADF, + "cannot flush stream"); + write_copy.dup2(write_fd); // "undo" close or dtor will fail +} + +TEST(OutputRedirectTest, ErrorInDtor) { + file read_end, write_end; + file::pipe(read_end, write_end); + int write_fd = write_end.descriptor(); + file write_copy = write_end.dup(write_fd); + buffered_file f = write_end.fdopen("w"); + std::unique_ptr<OutputRedirect> redir(new OutputRedirect(f.get())); + // Put a character in a file buffer. + EXPECT_EQ('x', fputc('x', f.get())); EXPECT_WRITE( stderr, { @@ -431,9 +431,9 @@ TEST(OutputRedirectTest, ErrorInDtor) { SUPPRESS_ASSERT(redir.reset(nullptr)); }, format_system_error(EBADF, "cannot flush stream")); - write_copy.dup2(write_fd); // "undo" close or dtor of buffered_file will fail -} - -#endif // FMT_USE_FILE_DESCRIPTORS - -} // namespace + write_copy.dup2(write_fd); // "undo" close or dtor of buffered_file will fail +} + +#endif // FMT_USE_FILE_DESCRIPTORS + +} // namespace diff --git a/contrib/libs/fmt/test/gtest-extra-test/ya.make b/contrib/libs/fmt/test/gtest-extra-test/ya.make index e6953ec539..b8d6cf8316 100644 --- a/contrib/libs/fmt/test/gtest-extra-test/ya.make +++ b/contrib/libs/fmt/test/gtest-extra-test/ya.make @@ -1,37 +1,37 @@ -# Generated by devtools/yamaker. - +# Generated by devtools/yamaker. + GTEST() - + WITHOUT_LICENSE_TEXTS() - + OWNER( orivej g:cpp-contrib ) -LICENSE(MIT) - -PEERDIR( - contrib/libs/fmt - contrib/libs/fmt/test -) - -NO_COMPILER_WARNINGS() - -NO_UTIL() - -CFLAGS( - -DFMT_LOCALE - -DFMT_SHARED - -DGTEST_HAS_STD_WSTRING=1 - -DGTEST_LANG_CXX11=0 - -D_SILENCE_TR1_NAMESPACE_DEPRECATION_WARNING=1 -) - -SRCDIR(contrib/libs/fmt/test) - -SRCS( - gtest-extra-test.cc -) - -END() +LICENSE(MIT) + +PEERDIR( + contrib/libs/fmt + contrib/libs/fmt/test +) + +NO_COMPILER_WARNINGS() + +NO_UTIL() + +CFLAGS( + -DFMT_LOCALE + -DFMT_SHARED + -DGTEST_HAS_STD_WSTRING=1 + -DGTEST_LANG_CXX11=0 + -D_SILENCE_TR1_NAMESPACE_DEPRECATION_WARNING=1 +) + +SRCDIR(contrib/libs/fmt/test) + +SRCS( + gtest-extra-test.cc +) + +END() diff --git a/contrib/libs/fmt/test/gtest-extra.cc b/contrib/libs/fmt/test/gtest-extra.cc index 3f38cbd1e6..58628a8a98 100644 --- a/contrib/libs/fmt/test/gtest-extra.cc +++ b/contrib/libs/fmt/test/gtest-extra.cc @@ -1,87 +1,87 @@ -// Formatting library for C++ - custom Google Test assertions -// -// Copyright (c) 2012 - present, Victor Zverovich -// All rights reserved. -// -// For the license information refer to format.h. - -#include "gtest-extra.h" - -#if FMT_USE_FCNTL - -using fmt::file; - -void OutputRedirect::flush() { -# if EOF != -1 -# error "FMT_RETRY assumes return value of -1 indicating failure" -# endif - int result = 0; - FMT_RETRY(result, fflush(file_)); - if (result != 0) throw fmt::system_error(errno, "cannot flush stream"); -} - -void OutputRedirect::restore() { - if (original_.descriptor() == -1) return; // Already restored. - flush(); - // Restore the original file. - original_.dup2(FMT_POSIX(fileno(file_))); - original_.close(); -} - -OutputRedirect::OutputRedirect(FILE* f) : file_(f) { - flush(); - int fd = FMT_POSIX(fileno(f)); - // Create a file object referring to the original file. - original_ = file::dup(fd); - // Create a pipe. - file write_end; - file::pipe(read_end_, write_end); - // Connect the passed FILE object to the write end of the pipe. - write_end.dup2(fd); -} - -OutputRedirect::~OutputRedirect() FMT_NOEXCEPT { - try { - restore(); - } catch (const std::exception& e) { - std::fputs(e.what(), stderr); - } -} - -std::string OutputRedirect::restore_and_read() { - // Restore output. - restore(); - - // Read everything from the pipe. - std::string content; - if (read_end_.descriptor() == -1) return content; // Already read. - enum { BUFFER_SIZE = 4096 }; - char buffer[BUFFER_SIZE]; +// Formatting library for C++ - custom Google Test assertions +// +// Copyright (c) 2012 - present, Victor Zverovich +// All rights reserved. +// +// For the license information refer to format.h. + +#include "gtest-extra.h" + +#if FMT_USE_FCNTL + +using fmt::file; + +void OutputRedirect::flush() { +# if EOF != -1 +# error "FMT_RETRY assumes return value of -1 indicating failure" +# endif + int result = 0; + FMT_RETRY(result, fflush(file_)); + if (result != 0) throw fmt::system_error(errno, "cannot flush stream"); +} + +void OutputRedirect::restore() { + if (original_.descriptor() == -1) return; // Already restored. + flush(); + // Restore the original file. + original_.dup2(FMT_POSIX(fileno(file_))); + original_.close(); +} + +OutputRedirect::OutputRedirect(FILE* f) : file_(f) { + flush(); + int fd = FMT_POSIX(fileno(f)); + // Create a file object referring to the original file. + original_ = file::dup(fd); + // Create a pipe. + file write_end; + file::pipe(read_end_, write_end); + // Connect the passed FILE object to the write end of the pipe. + write_end.dup2(fd); +} + +OutputRedirect::~OutputRedirect() FMT_NOEXCEPT { + try { + restore(); + } catch (const std::exception& e) { + std::fputs(e.what(), stderr); + } +} + +std::string OutputRedirect::restore_and_read() { + // Restore output. + restore(); + + // Read everything from the pipe. + std::string content; + if (read_end_.descriptor() == -1) return content; // Already read. + enum { BUFFER_SIZE = 4096 }; + char buffer[BUFFER_SIZE]; size_t count = 0; - do { - count = read_end_.read(buffer, BUFFER_SIZE); - content.append(buffer, count); - } while (count != 0); - read_end_.close(); - return content; -} - + do { + count = read_end_.read(buffer, BUFFER_SIZE); + content.append(buffer, count); + } while (count != 0); + read_end_.close(); + return content; +} + std::string read(file& f, size_t count) { - std::string buffer(count, '\0'); + std::string buffer(count, '\0'); size_t n = 0, offset = 0; - do { - n = f.read(&buffer[offset], count - offset); - // We can't read more than size_t bytes since count has type size_t. - offset += n; - } while (offset < count && n != 0); - buffer.resize(offset); - return buffer; -} - -#endif // FMT_USE_FCNTL - -std::string format_system_error(int error_code, fmt::string_view message) { - fmt::memory_buffer out; - format_system_error(out, error_code, message); - return to_string(out); -} + do { + n = f.read(&buffer[offset], count - offset); + // We can't read more than size_t bytes since count has type size_t. + offset += n; + } while (offset < count && n != 0); + buffer.resize(offset); + return buffer; +} + +#endif // FMT_USE_FCNTL + +std::string format_system_error(int error_code, fmt::string_view message) { + fmt::memory_buffer out; + format_system_error(out, error_code, message); + return to_string(out); +} diff --git a/contrib/libs/fmt/test/gtest-extra.h b/contrib/libs/fmt/test/gtest-extra.h index 2b602e65fa..36be158bbb 100644 --- a/contrib/libs/fmt/test/gtest-extra.h +++ b/contrib/libs/fmt/test/gtest-extra.h @@ -1,151 +1,151 @@ -// Formatting library for C++ - custom Google Test assertions -// -// Copyright (c) 2012 - present, Victor Zverovich -// All rights reserved. -// -// For the license information refer to format.h. - -#ifndef FMT_GTEST_EXTRA_H_ -#define FMT_GTEST_EXTRA_H_ - -#include <string> +// Formatting library for C++ - custom Google Test assertions +// +// Copyright (c) 2012 - present, Victor Zverovich +// All rights reserved. +// +// For the license information refer to format.h. + +#ifndef FMT_GTEST_EXTRA_H_ +#define FMT_GTEST_EXTRA_H_ + +#include <string> #include "fmt/os.h" -#include <gmock/gmock.h> - -#define FMT_TEST_THROW_(statement, expected_exception, expected_message, fail) \ - GTEST_AMBIGUOUS_ELSE_BLOCKER_ \ - if (::testing::AssertionResult gtest_ar = ::testing::AssertionSuccess()) { \ - std::string gtest_expected_message = expected_message; \ - bool gtest_caught_expected = false; \ - try { \ - GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \ - } catch (expected_exception const& e) { \ - if (gtest_expected_message != e.what()) { \ - gtest_ar << #statement \ - " throws an exception with a different message.\n" \ - << "Expected: " << gtest_expected_message << "\n" \ - << " Actual: " << e.what(); \ - goto GTEST_CONCAT_TOKEN_(gtest_label_testthrow_, __LINE__); \ - } \ - gtest_caught_expected = true; \ - } catch (...) { \ - gtest_ar << "Expected: " #statement \ - " throws an exception of type " #expected_exception \ - ".\n Actual: it throws a different type."; \ - goto GTEST_CONCAT_TOKEN_(gtest_label_testthrow_, __LINE__); \ - } \ - if (!gtest_caught_expected) { \ - gtest_ar << "Expected: " #statement \ - " throws an exception of type " #expected_exception \ - ".\n Actual: it throws nothing."; \ - goto GTEST_CONCAT_TOKEN_(gtest_label_testthrow_, __LINE__); \ - } \ - } else \ - GTEST_CONCAT_TOKEN_(gtest_label_testthrow_, __LINE__) \ - : fail(gtest_ar.failure_message()) - -// Tests that the statement throws the expected exception and the exception's -// what() method returns expected message. -#define EXPECT_THROW_MSG(statement, expected_exception, expected_message) \ - FMT_TEST_THROW_(statement, expected_exception, expected_message, \ - GTEST_NONFATAL_FAILURE_) - -std::string format_system_error(int error_code, fmt::string_view message); - -#define EXPECT_SYSTEM_ERROR(statement, error_code, message) \ - EXPECT_THROW_MSG(statement, fmt::system_error, \ - format_system_error(error_code, message)) - -#if FMT_USE_FCNTL - -// Captures file output by redirecting it to a pipe. -// The output it can handle is limited by the pipe capacity. -class OutputRedirect { - private: - FILE* file_; - fmt::file original_; // Original file passed to redirector. - fmt::file read_end_; // Read end of the pipe where the output is redirected. - - GTEST_DISALLOW_COPY_AND_ASSIGN_(OutputRedirect); - - void flush(); - void restore(); - - public: - explicit OutputRedirect(FILE* file); - ~OutputRedirect() FMT_NOEXCEPT; - - // Restores the original file, reads output from the pipe into a string - // and returns it. - std::string restore_and_read(); -}; - -# define FMT_TEST_WRITE_(statement, expected_output, file, fail) \ - GTEST_AMBIGUOUS_ELSE_BLOCKER_ \ - if (::testing::AssertionResult gtest_ar = ::testing::AssertionSuccess()) { \ - std::string gtest_expected_output = expected_output; \ - OutputRedirect gtest_redir(file); \ - GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \ - std::string gtest_output = gtest_redir.restore_and_read(); \ - if (gtest_output != gtest_expected_output) { \ - gtest_ar << #statement " produces different output.\n" \ - << "Expected: " << gtest_expected_output << "\n" \ - << " Actual: " << gtest_output; \ - goto GTEST_CONCAT_TOKEN_(gtest_label_testthrow_, __LINE__); \ - } \ - } else \ - GTEST_CONCAT_TOKEN_(gtest_label_testthrow_, __LINE__) \ - : fail(gtest_ar.failure_message()) - -// Tests that the statement writes the expected output to file. -# define EXPECT_WRITE(file, statement, expected_output) \ - FMT_TEST_WRITE_(statement, expected_output, file, GTEST_NONFATAL_FAILURE_) - -# ifdef _MSC_VER +#include <gmock/gmock.h> + +#define FMT_TEST_THROW_(statement, expected_exception, expected_message, fail) \ + GTEST_AMBIGUOUS_ELSE_BLOCKER_ \ + if (::testing::AssertionResult gtest_ar = ::testing::AssertionSuccess()) { \ + std::string gtest_expected_message = expected_message; \ + bool gtest_caught_expected = false; \ + try { \ + GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \ + } catch (expected_exception const& e) { \ + if (gtest_expected_message != e.what()) { \ + gtest_ar << #statement \ + " throws an exception with a different message.\n" \ + << "Expected: " << gtest_expected_message << "\n" \ + << " Actual: " << e.what(); \ + goto GTEST_CONCAT_TOKEN_(gtest_label_testthrow_, __LINE__); \ + } \ + gtest_caught_expected = true; \ + } catch (...) { \ + gtest_ar << "Expected: " #statement \ + " throws an exception of type " #expected_exception \ + ".\n Actual: it throws a different type."; \ + goto GTEST_CONCAT_TOKEN_(gtest_label_testthrow_, __LINE__); \ + } \ + if (!gtest_caught_expected) { \ + gtest_ar << "Expected: " #statement \ + " throws an exception of type " #expected_exception \ + ".\n Actual: it throws nothing."; \ + goto GTEST_CONCAT_TOKEN_(gtest_label_testthrow_, __LINE__); \ + } \ + } else \ + GTEST_CONCAT_TOKEN_(gtest_label_testthrow_, __LINE__) \ + : fail(gtest_ar.failure_message()) + +// Tests that the statement throws the expected exception and the exception's +// what() method returns expected message. +#define EXPECT_THROW_MSG(statement, expected_exception, expected_message) \ + FMT_TEST_THROW_(statement, expected_exception, expected_message, \ + GTEST_NONFATAL_FAILURE_) + +std::string format_system_error(int error_code, fmt::string_view message); + +#define EXPECT_SYSTEM_ERROR(statement, error_code, message) \ + EXPECT_THROW_MSG(statement, fmt::system_error, \ + format_system_error(error_code, message)) + +#if FMT_USE_FCNTL + +// Captures file output by redirecting it to a pipe. +// The output it can handle is limited by the pipe capacity. +class OutputRedirect { + private: + FILE* file_; + fmt::file original_; // Original file passed to redirector. + fmt::file read_end_; // Read end of the pipe where the output is redirected. + + GTEST_DISALLOW_COPY_AND_ASSIGN_(OutputRedirect); + + void flush(); + void restore(); + + public: + explicit OutputRedirect(FILE* file); + ~OutputRedirect() FMT_NOEXCEPT; + + // Restores the original file, reads output from the pipe into a string + // and returns it. + std::string restore_and_read(); +}; + +# define FMT_TEST_WRITE_(statement, expected_output, file, fail) \ + GTEST_AMBIGUOUS_ELSE_BLOCKER_ \ + if (::testing::AssertionResult gtest_ar = ::testing::AssertionSuccess()) { \ + std::string gtest_expected_output = expected_output; \ + OutputRedirect gtest_redir(file); \ + GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \ + std::string gtest_output = gtest_redir.restore_and_read(); \ + if (gtest_output != gtest_expected_output) { \ + gtest_ar << #statement " produces different output.\n" \ + << "Expected: " << gtest_expected_output << "\n" \ + << " Actual: " << gtest_output; \ + goto GTEST_CONCAT_TOKEN_(gtest_label_testthrow_, __LINE__); \ + } \ + } else \ + GTEST_CONCAT_TOKEN_(gtest_label_testthrow_, __LINE__) \ + : fail(gtest_ar.failure_message()) + +// Tests that the statement writes the expected output to file. +# define EXPECT_WRITE(file, statement, expected_output) \ + FMT_TEST_WRITE_(statement, expected_output, file, GTEST_NONFATAL_FAILURE_) + +# ifdef _MSC_VER #include <crtdbg.h> - -// Suppresses Windows assertions on invalid file descriptors, making -// POSIX functions return proper error codes instead of crashing on Windows. -class SuppressAssert { - private: - _invalid_parameter_handler original_handler_; - int original_report_mode_; - - static void handle_invalid_parameter(const wchar_t*, const wchar_t*, - const wchar_t*, unsigned, uintptr_t) {} - - public: - SuppressAssert() - : original_handler_( - _set_invalid_parameter_handler(handle_invalid_parameter)), - original_report_mode_(_CrtSetReportMode(_CRT_ASSERT, 0)) {} - ~SuppressAssert() { - _set_invalid_parameter_handler(original_handler_); - _CrtSetReportMode(_CRT_ASSERT, original_report_mode_); - } -}; - -# define SUPPRESS_ASSERT(statement) \ - { \ - SuppressAssert sa; \ - statement; \ - } -# else -# define SUPPRESS_ASSERT(statement) statement -# endif // _MSC_VER - -# define EXPECT_SYSTEM_ERROR_NOASSERT(statement, error_code, message) \ - EXPECT_SYSTEM_ERROR(SUPPRESS_ASSERT(statement), error_code, message) - -// Attempts to read count characters from a file. + +// Suppresses Windows assertions on invalid file descriptors, making +// POSIX functions return proper error codes instead of crashing on Windows. +class SuppressAssert { + private: + _invalid_parameter_handler original_handler_; + int original_report_mode_; + + static void handle_invalid_parameter(const wchar_t*, const wchar_t*, + const wchar_t*, unsigned, uintptr_t) {} + + public: + SuppressAssert() + : original_handler_( + _set_invalid_parameter_handler(handle_invalid_parameter)), + original_report_mode_(_CrtSetReportMode(_CRT_ASSERT, 0)) {} + ~SuppressAssert() { + _set_invalid_parameter_handler(original_handler_); + _CrtSetReportMode(_CRT_ASSERT, original_report_mode_); + } +}; + +# define SUPPRESS_ASSERT(statement) \ + { \ + SuppressAssert sa; \ + statement; \ + } +# else +# define SUPPRESS_ASSERT(statement) statement +# endif // _MSC_VER + +# define EXPECT_SYSTEM_ERROR_NOASSERT(statement, error_code, message) \ + EXPECT_SYSTEM_ERROR(SUPPRESS_ASSERT(statement), error_code, message) + +// Attempts to read count characters from a file. std::string read(fmt::file& f, size_t count); - -# define EXPECT_READ(file, expected_content) \ + +# define EXPECT_READ(file, expected_content) \ EXPECT_EQ(expected_content, \ read(file, fmt::string_view(expected_content).size())) - -#else + +#else # define EXPECT_WRITE(file, statement, expected_output) \ do { \ (void)(file); \ @@ -153,11 +153,11 @@ std::string read(fmt::file& f, size_t count); (void)(expected_output); \ SUCCEED(); \ } while (false) -#endif // FMT_USE_FCNTL - -template <typename Mock> struct ScopedMock : testing::StrictMock<Mock> { - ScopedMock() { Mock::instance = this; } - ~ScopedMock() { Mock::instance = nullptr; } -}; - -#endif // FMT_GTEST_EXTRA_H_ +#endif // FMT_USE_FCNTL + +template <typename Mock> struct ScopedMock : testing::StrictMock<Mock> { + ScopedMock() { Mock::instance = this; } + ~ScopedMock() { Mock::instance = nullptr; } +}; + +#endif // FMT_GTEST_EXTRA_H_ diff --git a/contrib/libs/fmt/test/header-only-test.cc b/contrib/libs/fmt/test/header-only-test.cc index e38159c83c..674dab993d 100644 --- a/contrib/libs/fmt/test/header-only-test.cc +++ b/contrib/libs/fmt/test/header-only-test.cc @@ -1,3 +1,3 @@ -// Header-only configuration test - -#include "fmt/core.h" +// Header-only configuration test + +#include "fmt/core.h" diff --git a/contrib/libs/fmt/test/header-only-test/ya.make b/contrib/libs/fmt/test/header-only-test/ya.make index de4aa9fa85..cfbc290203 100644 --- a/contrib/libs/fmt/test/header-only-test/ya.make +++ b/contrib/libs/fmt/test/header-only-test/ya.make @@ -1,37 +1,37 @@ -# Generated by devtools/yamaker. - +# Generated by devtools/yamaker. + GTEST() - + WITHOUT_LICENSE_TEXTS() - + OWNER( orivej g:cpp-contrib ) -LICENSE(MIT) - -PEERDIR( +LICENSE(MIT) + +PEERDIR( contrib/libs/fmt - contrib/libs/fmt/test -) - -NO_COMPILER_WARNINGS() - -NO_UTIL() - -CFLAGS( - -DFMT_HEADER_ONLY=1 - -DGTEST_HAS_STD_WSTRING=1 - -DGTEST_LANG_CXX11=0 - -D_SILENCE_TR1_NAMESPACE_DEPRECATION_WARNING=1 -) - -SRCDIR(contrib/libs/fmt/test) - -SRCS( - header-only-test.cc - header-only-test2.cc -) - -END() + contrib/libs/fmt/test +) + +NO_COMPILER_WARNINGS() + +NO_UTIL() + +CFLAGS( + -DFMT_HEADER_ONLY=1 + -DGTEST_HAS_STD_WSTRING=1 + -DGTEST_LANG_CXX11=0 + -D_SILENCE_TR1_NAMESPACE_DEPRECATION_WARNING=1 +) + +SRCDIR(contrib/libs/fmt/test) + +SRCS( + header-only-test.cc + header-only-test2.cc +) + +END() diff --git a/contrib/libs/fmt/test/header-only-test2.cc b/contrib/libs/fmt/test/header-only-test2.cc index 9fbbc9a5b1..ea90b604e4 100644 --- a/contrib/libs/fmt/test/header-only-test2.cc +++ b/contrib/libs/fmt/test/header-only-test2.cc @@ -1,3 +1,3 @@ -// Additional translation unit for the header-only configuration test - -#include "fmt/core.h" +// Additional translation unit for the header-only configuration test + +#include "fmt/core.h" diff --git a/contrib/libs/fmt/test/locale-test.cc b/contrib/libs/fmt/test/locale-test.cc index ef346ab6be..7d776b4290 100644 --- a/contrib/libs/fmt/test/locale-test.cc +++ b/contrib/libs/fmt/test/locale-test.cc @@ -1,102 +1,102 @@ -// Formatting library for C++ - locale tests -// -// Copyright (c) 2012 - present, Victor Zverovich -// All rights reserved. -// -// For the license information refer to format.h. - -#include "fmt/locale.h" +// Formatting library for C++ - locale tests +// +// Copyright (c) 2012 - present, Victor Zverovich +// All rights reserved. +// +// For the license information refer to format.h. + +#include "fmt/locale.h" #include <complex> -#include <gmock/gmock.h> - +#include <gmock/gmock.h> + using fmt::detail::max_value; - -#ifndef FMT_STATIC_THOUSANDS_SEPARATOR -template <typename Char> struct numpunct : std::numpunct<Char> { - protected: - Char do_decimal_point() const FMT_OVERRIDE { return '?'; } - std::string do_grouping() const FMT_OVERRIDE { return "\03"; } - Char do_thousands_sep() const FMT_OVERRIDE { return '~'; } -}; - -template <typename Char> struct no_grouping : std::numpunct<Char> { - protected: - Char do_decimal_point() const FMT_OVERRIDE { return '.'; } - std::string do_grouping() const FMT_OVERRIDE { return ""; } - Char do_thousands_sep() const FMT_OVERRIDE { return ','; } -}; - -template <typename Char> struct special_grouping : std::numpunct<Char> { - protected: - Char do_decimal_point() const FMT_OVERRIDE { return '.'; } - std::string do_grouping() const FMT_OVERRIDE { return "\03\02"; } - Char do_thousands_sep() const FMT_OVERRIDE { return ','; } -}; - -template <typename Char> struct small_grouping : std::numpunct<Char> { - protected: - Char do_decimal_point() const FMT_OVERRIDE { return '.'; } - std::string do_grouping() const FMT_OVERRIDE { return "\01"; } - Char do_thousands_sep() const FMT_OVERRIDE { return ','; } -}; - -TEST(LocaleTest, DoubleDecimalPoint) { - std::locale loc(std::locale(), new numpunct<char>()); + +#ifndef FMT_STATIC_THOUSANDS_SEPARATOR +template <typename Char> struct numpunct : std::numpunct<Char> { + protected: + Char do_decimal_point() const FMT_OVERRIDE { return '?'; } + std::string do_grouping() const FMT_OVERRIDE { return "\03"; } + Char do_thousands_sep() const FMT_OVERRIDE { return '~'; } +}; + +template <typename Char> struct no_grouping : std::numpunct<Char> { + protected: + Char do_decimal_point() const FMT_OVERRIDE { return '.'; } + std::string do_grouping() const FMT_OVERRIDE { return ""; } + Char do_thousands_sep() const FMT_OVERRIDE { return ','; } +}; + +template <typename Char> struct special_grouping : std::numpunct<Char> { + protected: + Char do_decimal_point() const FMT_OVERRIDE { return '.'; } + std::string do_grouping() const FMT_OVERRIDE { return "\03\02"; } + Char do_thousands_sep() const FMT_OVERRIDE { return ','; } +}; + +template <typename Char> struct small_grouping : std::numpunct<Char> { + protected: + Char do_decimal_point() const FMT_OVERRIDE { return '.'; } + std::string do_grouping() const FMT_OVERRIDE { return "\01"; } + Char do_thousands_sep() const FMT_OVERRIDE { return ','; } +}; + +TEST(LocaleTest, DoubleDecimalPoint) { + std::locale loc(std::locale(), new numpunct<char>()); EXPECT_EQ("1?23", fmt::format(loc, "{:L}", 1.23)); -} - -TEST(LocaleTest, Format) { - std::locale loc(std::locale(), new numpunct<char>()); +} + +TEST(LocaleTest, Format) { + std::locale loc(std::locale(), new numpunct<char>()); EXPECT_EQ("1234567", fmt::format(std::locale(), "{:L}", 1234567)); EXPECT_EQ("1~234~567", fmt::format(loc, "{:L}", 1234567)); EXPECT_EQ("-1~234~567", fmt::format(loc, "{:L}", -1234567)); EXPECT_EQ("-256", fmt::format(loc, "{:L}", -256)); - fmt::format_arg_store<fmt::format_context, int> as{1234567}; + fmt::format_arg_store<fmt::format_context, int> as{1234567}; EXPECT_EQ("1~234~567", fmt::vformat(loc, "{:L}", fmt::format_args(as))); - std::string s; + std::string s; fmt::format_to(std::back_inserter(s), loc, "{:L}", 1234567); - EXPECT_EQ("1~234~567", s); - - std::locale no_grouping_loc(std::locale(), new no_grouping<char>()); + EXPECT_EQ("1~234~567", s); + + std::locale no_grouping_loc(std::locale(), new no_grouping<char>()); EXPECT_EQ("1234567", fmt::format(no_grouping_loc, "{:L}", 1234567)); - - std::locale special_grouping_loc(std::locale(), new special_grouping<char>()); + + std::locale special_grouping_loc(std::locale(), new special_grouping<char>()); EXPECT_EQ("1,23,45,678", fmt::format(special_grouping_loc, "{:L}", 12345678)); EXPECT_EQ("12,345", fmt::format(special_grouping_loc, "{:L}", 12345)); - - std::locale small_grouping_loc(std::locale(), new small_grouping<char>()); - EXPECT_EQ("4,2,9,4,9,6,7,2,9,5", + + std::locale small_grouping_loc(std::locale(), new small_grouping<char>()); + EXPECT_EQ("4,2,9,4,9,6,7,2,9,5", fmt::format(small_grouping_loc, "{:L}", max_value<uint32_t>())); -} - +} + TEST(LocaleTest, FormatDetaultAlign) { std::locale special_grouping_loc(std::locale(), new special_grouping<char>()); EXPECT_EQ(" 12,345", fmt::format(special_grouping_loc, "{:8L}", 12345)); } -TEST(LocaleTest, WFormat) { - std::locale loc(std::locale(), new numpunct<wchar_t>()); +TEST(LocaleTest, WFormat) { + std::locale loc(std::locale(), new numpunct<wchar_t>()); EXPECT_EQ(L"1234567", fmt::format(std::locale(), L"{:L}", 1234567)); EXPECT_EQ(L"1~234~567", fmt::format(loc, L"{:L}", 1234567)); - fmt::format_arg_store<fmt::wformat_context, int> as{1234567}; + fmt::format_arg_store<fmt::wformat_context, int> as{1234567}; EXPECT_EQ(L"1~234~567", fmt::vformat(loc, L"{:L}", fmt::wformat_args(as))); EXPECT_EQ(L"1234567", fmt::format(std::locale("C"), L"{:L}", 1234567)); - - std::locale no_grouping_loc(std::locale(), new no_grouping<wchar_t>()); + + std::locale no_grouping_loc(std::locale(), new no_grouping<wchar_t>()); EXPECT_EQ(L"1234567", fmt::format(no_grouping_loc, L"{:L}", 1234567)); - - std::locale special_grouping_loc(std::locale(), - new special_grouping<wchar_t>()); - EXPECT_EQ(L"1,23,45,678", + + std::locale special_grouping_loc(std::locale(), + new special_grouping<wchar_t>()); + EXPECT_EQ(L"1,23,45,678", fmt::format(special_grouping_loc, L"{:L}", 12345678)); - - std::locale small_grouping_loc(std::locale(), new small_grouping<wchar_t>()); - EXPECT_EQ(L"4,2,9,4,9,6,7,2,9,5", + + std::locale small_grouping_loc(std::locale(), new small_grouping<wchar_t>()); + EXPECT_EQ(L"4,2,9,4,9,6,7,2,9,5", fmt::format(small_grouping_loc, L"{:L}", max_value<uint32_t>())); -} - +} + TEST(LocaleTest, DoubleFormatter) { auto loc = std::locale(std::locale(), new special_grouping<char>()); auto f = fmt::formatter<int>(); @@ -157,4 +157,4 @@ TEST(FormatTest, Complex) { EXPECT_EQ(fmt::format("{:8}", std::complex<double>(1, 2)), " (1+2i)"); } -#endif // FMT_STATIC_THOUSANDS_SEPARATOR +#endif // FMT_STATIC_THOUSANDS_SEPARATOR diff --git a/contrib/libs/fmt/test/locale-test/ya.make b/contrib/libs/fmt/test/locale-test/ya.make index 9619d8632c..06a53a939c 100644 --- a/contrib/libs/fmt/test/locale-test/ya.make +++ b/contrib/libs/fmt/test/locale-test/ya.make @@ -1,37 +1,37 @@ -# Generated by devtools/yamaker. - +# Generated by devtools/yamaker. + GTEST() - + WITHOUT_LICENSE_TEXTS() - + OWNER( orivej g:cpp-contrib ) -LICENSE(MIT) - -PEERDIR( - contrib/libs/fmt - contrib/libs/fmt/test -) - -NO_COMPILER_WARNINGS() - -NO_UTIL() - -CFLAGS( - -DFMT_LOCALE - -DFMT_SHARED - -DGTEST_HAS_STD_WSTRING=1 - -DGTEST_LANG_CXX11=0 - -D_SILENCE_TR1_NAMESPACE_DEPRECATION_WARNING=1 -) - -SRCDIR(contrib/libs/fmt/test) - -SRCS( - locale-test.cc -) - -END() +LICENSE(MIT) + +PEERDIR( + contrib/libs/fmt + contrib/libs/fmt/test +) + +NO_COMPILER_WARNINGS() + +NO_UTIL() + +CFLAGS( + -DFMT_LOCALE + -DFMT_SHARED + -DGTEST_HAS_STD_WSTRING=1 + -DGTEST_LANG_CXX11=0 + -D_SILENCE_TR1_NAMESPACE_DEPRECATION_WARNING=1 +) + +SRCDIR(contrib/libs/fmt/test) + +SRCS( + locale-test.cc +) + +END() diff --git a/contrib/libs/fmt/test/mock-allocator.h b/contrib/libs/fmt/test/mock-allocator.h index c946009aa1..dfc13feee7 100644 --- a/contrib/libs/fmt/test/mock-allocator.h +++ b/contrib/libs/fmt/test/mock-allocator.h @@ -1,60 +1,60 @@ -// Formatting library for C++ - mock allocator -// -// Copyright (c) 2012 - present, Victor Zverovich -// All rights reserved. -// -// For the license information refer to format.h. - -#ifndef FMT_MOCK_ALLOCATOR_H_ -#define FMT_MOCK_ALLOCATOR_H_ - -#include "fmt/format.h" -#include <gmock/gmock.h> - -template <typename T> class mock_allocator { - public: - mock_allocator() {} - mock_allocator(const mock_allocator&) {} - typedef T value_type; +// Formatting library for C++ - mock allocator +// +// Copyright (c) 2012 - present, Victor Zverovich +// All rights reserved. +// +// For the license information refer to format.h. + +#ifndef FMT_MOCK_ALLOCATOR_H_ +#define FMT_MOCK_ALLOCATOR_H_ + +#include "fmt/format.h" +#include <gmock/gmock.h> + +template <typename T> class mock_allocator { + public: + mock_allocator() {} + mock_allocator(const mock_allocator&) {} + typedef T value_type; MOCK_METHOD1_T(allocate, T*(size_t n)); MOCK_METHOD2_T(deallocate, void(T* p, size_t n)); -}; - -template <typename Allocator> class allocator_ref { - private: - Allocator* alloc_; - - void move(allocator_ref& other) { - alloc_ = other.alloc_; - other.alloc_ = nullptr; - } - - public: - typedef typename Allocator::value_type value_type; - - explicit allocator_ref(Allocator* alloc = nullptr) : alloc_(alloc) {} - - allocator_ref(const allocator_ref& other) : alloc_(other.alloc_) {} - allocator_ref(allocator_ref&& other) { move(other); } - - allocator_ref& operator=(allocator_ref&& other) { - assert(this != &other); - move(other); - return *this; - } - - allocator_ref& operator=(const allocator_ref& other) { - alloc_ = other.alloc_; - return *this; - } - - public: - Allocator* get() const { return alloc_; } - +}; + +template <typename Allocator> class allocator_ref { + private: + Allocator* alloc_; + + void move(allocator_ref& other) { + alloc_ = other.alloc_; + other.alloc_ = nullptr; + } + + public: + typedef typename Allocator::value_type value_type; + + explicit allocator_ref(Allocator* alloc = nullptr) : alloc_(alloc) {} + + allocator_ref(const allocator_ref& other) : alloc_(other.alloc_) {} + allocator_ref(allocator_ref&& other) { move(other); } + + allocator_ref& operator=(allocator_ref&& other) { + assert(this != &other); + move(other); + return *this; + } + + allocator_ref& operator=(const allocator_ref& other) { + alloc_ = other.alloc_; + return *this; + } + + public: + Allocator* get() const { return alloc_; } + value_type* allocate(size_t n) { - return std::allocator_traits<Allocator>::allocate(*alloc_, n); - } + return std::allocator_traits<Allocator>::allocate(*alloc_, n); + } void deallocate(value_type* p, size_t n) { alloc_->deallocate(p, n); } -}; - -#endif // FMT_MOCK_ALLOCATOR_H_ +}; + +#endif // FMT_MOCK_ALLOCATOR_H_ diff --git a/contrib/libs/fmt/test/os-test.cc b/contrib/libs/fmt/test/os-test.cc index 4e17c5d522..359b5ff8ce 100644 --- a/contrib/libs/fmt/test/os-test.cc +++ b/contrib/libs/fmt/test/os-test.cc @@ -1,243 +1,243 @@ -// Formatting library for C++ - tests of the OS-specific functionality -// -// Copyright (c) 2012 - present, Victor Zverovich -// All rights reserved. -// -// For the license information refer to format.h. - +// Formatting library for C++ - tests of the OS-specific functionality +// +// Copyright (c) 2012 - present, Victor Zverovich +// All rights reserved. +// +// For the license information refer to format.h. + #include "fmt/os.h" -#include <cstdlib> // std::exit -#include <cstring> -#include <memory> - -#include "gtest-extra.h" -#include "util.h" - -#ifdef fileno -# undef fileno -#endif - -using fmt::buffered_file; -using fmt::error_code; - -#ifdef _WIN32 - -# include <windows.h> - -TEST(UtilTest, UTF16ToUTF8) { - std::string s = "ёжик"; +#include <cstdlib> // std::exit +#include <cstring> +#include <memory> + +#include "gtest-extra.h" +#include "util.h" + +#ifdef fileno +# undef fileno +#endif + +using fmt::buffered_file; +using fmt::error_code; + +#ifdef _WIN32 + +# include <windows.h> + +TEST(UtilTest, UTF16ToUTF8) { + std::string s = "ёжик"; fmt::detail::utf16_to_utf8 u(L"\x0451\x0436\x0438\x043A"); - EXPECT_EQ(s, u.str()); - EXPECT_EQ(s.size(), u.size()); -} - -TEST(UtilTest, UTF16ToUTF8EmptyString) { - std::string s = ""; + EXPECT_EQ(s, u.str()); + EXPECT_EQ(s.size(), u.size()); +} + +TEST(UtilTest, UTF16ToUTF8EmptyString) { + std::string s = ""; fmt::detail::utf16_to_utf8 u(L""); - EXPECT_EQ(s, u.str()); - EXPECT_EQ(s.size(), u.size()); -} - -template <typename Converter, typename Char> -void check_utf_conversion_error( - const char* message, - fmt::basic_string_view<Char> str = fmt::basic_string_view<Char>(0, 1)) { - fmt::memory_buffer out; + EXPECT_EQ(s, u.str()); + EXPECT_EQ(s.size(), u.size()); +} + +template <typename Converter, typename Char> +void check_utf_conversion_error( + const char* message, + fmt::basic_string_view<Char> str = fmt::basic_string_view<Char>(0, 1)) { + fmt::memory_buffer out; fmt::detail::format_windows_error(out, ERROR_INVALID_PARAMETER, message); - fmt::system_error error(0, ""); - try { - (Converter)(str); - } catch (const fmt::system_error& e) { - error = e; - } - EXPECT_EQ(ERROR_INVALID_PARAMETER, error.error_code()); - EXPECT_EQ(fmt::to_string(out), error.what()); -} - -TEST(UtilTest, UTF16ToUTF8Error) { + fmt::system_error error(0, ""); + try { + (Converter)(str); + } catch (const fmt::system_error& e) { + error = e; + } + EXPECT_EQ(ERROR_INVALID_PARAMETER, error.error_code()); + EXPECT_EQ(fmt::to_string(out), error.what()); +} + +TEST(UtilTest, UTF16ToUTF8Error) { check_utf_conversion_error<fmt::detail::utf16_to_utf8, wchar_t>( - "cannot convert string from UTF-16 to UTF-8"); -} - -TEST(UtilTest, UTF16ToUTF8Convert) { + "cannot convert string from UTF-16 to UTF-8"); +} + +TEST(UtilTest, UTF16ToUTF8Convert) { fmt::detail::utf16_to_utf8 u; - EXPECT_EQ(ERROR_INVALID_PARAMETER, u.convert(fmt::wstring_view(0, 1))); - EXPECT_EQ(ERROR_INVALID_PARAMETER, - u.convert(fmt::wstring_view(L"foo", INT_MAX + 1u))); -} - -TEST(UtilTest, FormatWindowsError) { - LPWSTR message = 0; - FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | - FORMAT_MESSAGE_IGNORE_INSERTS, - 0, ERROR_FILE_EXISTS, - MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), - reinterpret_cast<LPWSTR>(&message), 0, 0); + EXPECT_EQ(ERROR_INVALID_PARAMETER, u.convert(fmt::wstring_view(0, 1))); + EXPECT_EQ(ERROR_INVALID_PARAMETER, + u.convert(fmt::wstring_view(L"foo", INT_MAX + 1u))); +} + +TEST(UtilTest, FormatWindowsError) { + LPWSTR message = 0; + FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | + FORMAT_MESSAGE_IGNORE_INSERTS, + 0, ERROR_FILE_EXISTS, + MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), + reinterpret_cast<LPWSTR>(&message), 0, 0); fmt::detail::utf16_to_utf8 utf8_message(message); - LocalFree(message); - fmt::memory_buffer actual_message; + LocalFree(message); + fmt::memory_buffer actual_message; fmt::detail::format_windows_error(actual_message, ERROR_FILE_EXISTS, "test"); - EXPECT_EQ(fmt::format("test: {}", utf8_message.str()), - fmt::to_string(actual_message)); - actual_message.resize(0); + EXPECT_EQ(fmt::format("test: {}", utf8_message.str()), + fmt::to_string(actual_message)); + actual_message.resize(0); auto max_size = fmt::detail::max_value<size_t>() / 2; fmt::detail::format_windows_error(actual_message, ERROR_FILE_EXISTS, fmt::string_view(nullptr, max_size)); - EXPECT_EQ(fmt::format("error {}", ERROR_FILE_EXISTS), - fmt::to_string(actual_message)); -} - -TEST(UtilTest, FormatLongWindowsError) { - LPWSTR message = 0; - // this error code is not available on all Windows platforms and - // Windows SDKs, so do not fail the test if the error string cannot - // be retrieved. - const int provisioning_not_allowed = - 0x80284013L /*TBS_E_PROVISIONING_NOT_ALLOWED*/; - if (FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER | - FORMAT_MESSAGE_FROM_SYSTEM | - FORMAT_MESSAGE_IGNORE_INSERTS, - 0, static_cast<DWORD>(provisioning_not_allowed), - MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), - reinterpret_cast<LPWSTR>(&message), 0, 0) == 0) { - return; - } + EXPECT_EQ(fmt::format("error {}", ERROR_FILE_EXISTS), + fmt::to_string(actual_message)); +} + +TEST(UtilTest, FormatLongWindowsError) { + LPWSTR message = 0; + // this error code is not available on all Windows platforms and + // Windows SDKs, so do not fail the test if the error string cannot + // be retrieved. + const int provisioning_not_allowed = + 0x80284013L /*TBS_E_PROVISIONING_NOT_ALLOWED*/; + if (FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER | + FORMAT_MESSAGE_FROM_SYSTEM | + FORMAT_MESSAGE_IGNORE_INSERTS, + 0, static_cast<DWORD>(provisioning_not_allowed), + MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), + reinterpret_cast<LPWSTR>(&message), 0, 0) == 0) { + return; + } fmt::detail::utf16_to_utf8 utf8_message(message); - LocalFree(message); - fmt::memory_buffer actual_message; + LocalFree(message); + fmt::memory_buffer actual_message; fmt::detail::format_windows_error(actual_message, provisioning_not_allowed, "test"); - EXPECT_EQ(fmt::format("test: {}", utf8_message.str()), - fmt::to_string(actual_message)); -} - -TEST(UtilTest, WindowsError) { - fmt::system_error error(0, ""); - try { - throw fmt::windows_error(ERROR_FILE_EXISTS, "test {}", "error"); - } catch (const fmt::system_error& e) { - error = e; - } - fmt::memory_buffer message; + EXPECT_EQ(fmt::format("test: {}", utf8_message.str()), + fmt::to_string(actual_message)); +} + +TEST(UtilTest, WindowsError) { + fmt::system_error error(0, ""); + try { + throw fmt::windows_error(ERROR_FILE_EXISTS, "test {}", "error"); + } catch (const fmt::system_error& e) { + error = e; + } + fmt::memory_buffer message; fmt::detail::format_windows_error(message, ERROR_FILE_EXISTS, "test error"); - EXPECT_EQ(to_string(message), error.what()); - EXPECT_EQ(ERROR_FILE_EXISTS, error.error_code()); -} - -TEST(UtilTest, ReportWindowsError) { - fmt::memory_buffer out; + EXPECT_EQ(to_string(message), error.what()); + EXPECT_EQ(ERROR_FILE_EXISTS, error.error_code()); +} + +TEST(UtilTest, ReportWindowsError) { + fmt::memory_buffer out; fmt::detail::format_windows_error(out, ERROR_FILE_EXISTS, "test error"); - out.push_back('\n'); - EXPECT_WRITE(stderr, - fmt::report_windows_error(ERROR_FILE_EXISTS, "test error"), - fmt::to_string(out)); -} - -#endif // _WIN32 - -#if FMT_USE_FCNTL - -using fmt::file; - -// Checks if the file is open by reading one character from it. -static bool isopen(int fd) { - char buffer; - return FMT_POSIX(read(fd, &buffer, 1)) == 1; -} - -static bool isclosed(int fd) { - char buffer; - std::streamsize result = 0; - SUPPRESS_ASSERT(result = FMT_POSIX(read(fd, &buffer, 1))); - return result == -1 && errno == EBADF; -} - -// Opens a file for reading. -static file open_file() { - file read_end, write_end; - file::pipe(read_end, write_end); - write_end.write(FILE_CONTENT, std::strlen(FILE_CONTENT)); - write_end.close(); - return read_end; -} - -// Attempts to write a string to a file. -static void write(file& f, fmt::string_view s) { + out.push_back('\n'); + EXPECT_WRITE(stderr, + fmt::report_windows_error(ERROR_FILE_EXISTS, "test error"), + fmt::to_string(out)); +} + +#endif // _WIN32 + +#if FMT_USE_FCNTL + +using fmt::file; + +// Checks if the file is open by reading one character from it. +static bool isopen(int fd) { + char buffer; + return FMT_POSIX(read(fd, &buffer, 1)) == 1; +} + +static bool isclosed(int fd) { + char buffer; + std::streamsize result = 0; + SUPPRESS_ASSERT(result = FMT_POSIX(read(fd, &buffer, 1))); + return result == -1 && errno == EBADF; +} + +// Opens a file for reading. +static file open_file() { + file read_end, write_end; + file::pipe(read_end, write_end); + write_end.write(FILE_CONTENT, std::strlen(FILE_CONTENT)); + write_end.close(); + return read_end; +} + +// Attempts to write a string to a file. +static void write(file& f, fmt::string_view s) { size_t num_chars_left = s.size(); - const char* ptr = s.data(); - do { + const char* ptr = s.data(); + do { size_t count = f.write(ptr, num_chars_left); - ptr += count; - // We can't write more than size_t bytes since num_chars_left - // has type size_t. - num_chars_left -= count; - } while (num_chars_left != 0); -} - -TEST(BufferedFileTest, DefaultCtor) { - buffered_file f; - EXPECT_TRUE(f.get() == nullptr); -} - -TEST(BufferedFileTest, MoveCtor) { - buffered_file bf = open_buffered_file(); - FILE* fp = bf.get(); - EXPECT_TRUE(fp != nullptr); - buffered_file bf2(std::move(bf)); - EXPECT_EQ(fp, bf2.get()); - EXPECT_TRUE(bf.get() == nullptr); -} - -TEST(BufferedFileTest, MoveAssignment) { - buffered_file bf = open_buffered_file(); - FILE* fp = bf.get(); - EXPECT_TRUE(fp != nullptr); - buffered_file bf2; - bf2 = std::move(bf); - EXPECT_EQ(fp, bf2.get()); - EXPECT_TRUE(bf.get() == nullptr); -} - -TEST(BufferedFileTest, MoveAssignmentClosesFile) { - buffered_file bf = open_buffered_file(); - buffered_file bf2 = open_buffered_file(); - int old_fd = bf2.fileno(); - bf2 = std::move(bf); - EXPECT_TRUE(isclosed(old_fd)); -} - -TEST(BufferedFileTest, MoveFromTemporaryInCtor) { - FILE* fp = nullptr; - buffered_file f(open_buffered_file(&fp)); - EXPECT_EQ(fp, f.get()); -} - -TEST(BufferedFileTest, MoveFromTemporaryInAssignment) { - FILE* fp = nullptr; - buffered_file f; - f = open_buffered_file(&fp); - EXPECT_EQ(fp, f.get()); -} - -TEST(BufferedFileTest, MoveFromTemporaryInAssignmentClosesFile) { - buffered_file f = open_buffered_file(); - int old_fd = f.fileno(); - f = open_buffered_file(); - EXPECT_TRUE(isclosed(old_fd)); -} - -TEST(BufferedFileTest, CloseFileInDtor) { - int fd = 0; - { - buffered_file f = open_buffered_file(); - fd = f.fileno(); - } - EXPECT_TRUE(isclosed(fd)); -} - -TEST(BufferedFileTest, CloseErrorInDtor) { - std::unique_ptr<buffered_file> f(new buffered_file(open_buffered_file())); + ptr += count; + // We can't write more than size_t bytes since num_chars_left + // has type size_t. + num_chars_left -= count; + } while (num_chars_left != 0); +} + +TEST(BufferedFileTest, DefaultCtor) { + buffered_file f; + EXPECT_TRUE(f.get() == nullptr); +} + +TEST(BufferedFileTest, MoveCtor) { + buffered_file bf = open_buffered_file(); + FILE* fp = bf.get(); + EXPECT_TRUE(fp != nullptr); + buffered_file bf2(std::move(bf)); + EXPECT_EQ(fp, bf2.get()); + EXPECT_TRUE(bf.get() == nullptr); +} + +TEST(BufferedFileTest, MoveAssignment) { + buffered_file bf = open_buffered_file(); + FILE* fp = bf.get(); + EXPECT_TRUE(fp != nullptr); + buffered_file bf2; + bf2 = std::move(bf); + EXPECT_EQ(fp, bf2.get()); + EXPECT_TRUE(bf.get() == nullptr); +} + +TEST(BufferedFileTest, MoveAssignmentClosesFile) { + buffered_file bf = open_buffered_file(); + buffered_file bf2 = open_buffered_file(); + int old_fd = bf2.fileno(); + bf2 = std::move(bf); + EXPECT_TRUE(isclosed(old_fd)); +} + +TEST(BufferedFileTest, MoveFromTemporaryInCtor) { + FILE* fp = nullptr; + buffered_file f(open_buffered_file(&fp)); + EXPECT_EQ(fp, f.get()); +} + +TEST(BufferedFileTest, MoveFromTemporaryInAssignment) { + FILE* fp = nullptr; + buffered_file f; + f = open_buffered_file(&fp); + EXPECT_EQ(fp, f.get()); +} + +TEST(BufferedFileTest, MoveFromTemporaryInAssignmentClosesFile) { + buffered_file f = open_buffered_file(); + int old_fd = f.fileno(); + f = open_buffered_file(); + EXPECT_TRUE(isclosed(old_fd)); +} + +TEST(BufferedFileTest, CloseFileInDtor) { + int fd = 0; + { + buffered_file f = open_buffered_file(); + fd = f.fileno(); + } + EXPECT_TRUE(isclosed(fd)); +} + +TEST(BufferedFileTest, CloseErrorInDtor) { + std::unique_ptr<buffered_file> f(new buffered_file(open_buffered_file())); EXPECT_WRITE( stderr, { @@ -249,44 +249,44 @@ TEST(BufferedFileTest, CloseErrorInDtor) { SUPPRESS_ASSERT(f.reset(nullptr)); }, format_system_error(EBADF, "cannot close file") + "\n"); -} - -TEST(BufferedFileTest, Close) { - buffered_file f = open_buffered_file(); - int fd = f.fileno(); - f.close(); - EXPECT_TRUE(f.get() == nullptr); - EXPECT_TRUE(isclosed(fd)); -} - -TEST(BufferedFileTest, CloseError) { - buffered_file f = open_buffered_file(); - FMT_POSIX(close(f.fileno())); - EXPECT_SYSTEM_ERROR_NOASSERT(f.close(), EBADF, "cannot close file"); - EXPECT_TRUE(f.get() == nullptr); -} - -TEST(BufferedFileTest, Fileno) { - buffered_file f; -# ifndef __COVERITY__ - // fileno on a null FILE pointer either crashes or returns an error. - // Disable Coverity because this is intentional. - EXPECT_DEATH_IF_SUPPORTED( - { - try { - f.fileno(); - } catch (const fmt::system_error&) { - std::exit(1); - } - }, - ""); -# endif - f = open_buffered_file(); - EXPECT_TRUE(f.fileno() != -1); - file copy = file::dup(f.fileno()); - EXPECT_READ(copy, FILE_CONTENT); -} - +} + +TEST(BufferedFileTest, Close) { + buffered_file f = open_buffered_file(); + int fd = f.fileno(); + f.close(); + EXPECT_TRUE(f.get() == nullptr); + EXPECT_TRUE(isclosed(fd)); +} + +TEST(BufferedFileTest, CloseError) { + buffered_file f = open_buffered_file(); + FMT_POSIX(close(f.fileno())); + EXPECT_SYSTEM_ERROR_NOASSERT(f.close(), EBADF, "cannot close file"); + EXPECT_TRUE(f.get() == nullptr); +} + +TEST(BufferedFileTest, Fileno) { + buffered_file f; +# ifndef __COVERITY__ + // fileno on a null FILE pointer either crashes or returns an error. + // Disable Coverity because this is intentional. + EXPECT_DEATH_IF_SUPPORTED( + { + try { + f.fileno(); + } catch (const fmt::system_error&) { + std::exit(1); + } + }, + ""); +# endif + f = open_buffered_file(); + EXPECT_TRUE(f.fileno() != -1); + file copy = file::dup(f.fileno()); + EXPECT_READ(copy, FILE_CONTENT); +} + TEST(OStreamTest, Move) { fmt::ostream out = fmt::output_file("test-file"); fmt::ostream moved(std::move(out)); @@ -319,89 +319,89 @@ TEST(OStreamTest, BufferSize) { EXPECT_READ(in, "foo"); } -TEST(FileTest, DefaultCtor) { - file f; - EXPECT_EQ(-1, f.descriptor()); -} - -TEST(FileTest, OpenBufferedFileInCtor) { - FILE* fp = safe_fopen("test-file", "w"); - std::fputs(FILE_CONTENT, fp); - std::fclose(fp); - file f("test-file", file::RDONLY); - ASSERT_TRUE(isopen(f.descriptor())); -} - -TEST(FileTest, OpenBufferedFileError) { - EXPECT_SYSTEM_ERROR(file("nonexistent", file::RDONLY), ENOENT, - "cannot open file nonexistent"); -} - -TEST(FileTest, MoveCtor) { - file f = open_file(); - int fd = f.descriptor(); - EXPECT_NE(-1, fd); - file f2(std::move(f)); - EXPECT_EQ(fd, f2.descriptor()); - EXPECT_EQ(-1, f.descriptor()); -} - -TEST(FileTest, MoveAssignment) { - file f = open_file(); - int fd = f.descriptor(); - EXPECT_NE(-1, fd); - file f2; - f2 = std::move(f); - EXPECT_EQ(fd, f2.descriptor()); - EXPECT_EQ(-1, f.descriptor()); -} - -TEST(FileTest, MoveAssignmentClosesFile) { - file f = open_file(); - file f2 = open_file(); - int old_fd = f2.descriptor(); - f2 = std::move(f); - EXPECT_TRUE(isclosed(old_fd)); -} - -static file OpenBufferedFile(int& fd) { - file f = open_file(); - fd = f.descriptor(); - return f; -} - -TEST(FileTest, MoveFromTemporaryInCtor) { - int fd = 0xdead; - file f(OpenBufferedFile(fd)); - EXPECT_EQ(fd, f.descriptor()); -} - -TEST(FileTest, MoveFromTemporaryInAssignment) { - int fd = 0xdead; - file f; - f = OpenBufferedFile(fd); - EXPECT_EQ(fd, f.descriptor()); -} - -TEST(FileTest, MoveFromTemporaryInAssignmentClosesFile) { - int fd = 0xdead; - file f = open_file(); - int old_fd = f.descriptor(); - f = OpenBufferedFile(fd); - EXPECT_TRUE(isclosed(old_fd)); -} - -TEST(FileTest, CloseFileInDtor) { - int fd = 0; - { - file f = open_file(); - fd = f.descriptor(); - } - EXPECT_TRUE(isclosed(fd)); -} - -TEST(FileTest, CloseErrorInDtor) { - std::unique_ptr<file> f(new file(open_file())); +TEST(FileTest, DefaultCtor) { + file f; + EXPECT_EQ(-1, f.descriptor()); +} + +TEST(FileTest, OpenBufferedFileInCtor) { + FILE* fp = safe_fopen("test-file", "w"); + std::fputs(FILE_CONTENT, fp); + std::fclose(fp); + file f("test-file", file::RDONLY); + ASSERT_TRUE(isopen(f.descriptor())); +} + +TEST(FileTest, OpenBufferedFileError) { + EXPECT_SYSTEM_ERROR(file("nonexistent", file::RDONLY), ENOENT, + "cannot open file nonexistent"); +} + +TEST(FileTest, MoveCtor) { + file f = open_file(); + int fd = f.descriptor(); + EXPECT_NE(-1, fd); + file f2(std::move(f)); + EXPECT_EQ(fd, f2.descriptor()); + EXPECT_EQ(-1, f.descriptor()); +} + +TEST(FileTest, MoveAssignment) { + file f = open_file(); + int fd = f.descriptor(); + EXPECT_NE(-1, fd); + file f2; + f2 = std::move(f); + EXPECT_EQ(fd, f2.descriptor()); + EXPECT_EQ(-1, f.descriptor()); +} + +TEST(FileTest, MoveAssignmentClosesFile) { + file f = open_file(); + file f2 = open_file(); + int old_fd = f2.descriptor(); + f2 = std::move(f); + EXPECT_TRUE(isclosed(old_fd)); +} + +static file OpenBufferedFile(int& fd) { + file f = open_file(); + fd = f.descriptor(); + return f; +} + +TEST(FileTest, MoveFromTemporaryInCtor) { + int fd = 0xdead; + file f(OpenBufferedFile(fd)); + EXPECT_EQ(fd, f.descriptor()); +} + +TEST(FileTest, MoveFromTemporaryInAssignment) { + int fd = 0xdead; + file f; + f = OpenBufferedFile(fd); + EXPECT_EQ(fd, f.descriptor()); +} + +TEST(FileTest, MoveFromTemporaryInAssignmentClosesFile) { + int fd = 0xdead; + file f = open_file(); + int old_fd = f.descriptor(); + f = OpenBufferedFile(fd); + EXPECT_TRUE(isclosed(old_fd)); +} + +TEST(FileTest, CloseFileInDtor) { + int fd = 0; + { + file f = open_file(); + fd = f.descriptor(); + } + EXPECT_TRUE(isclosed(fd)); +} + +TEST(FileTest, CloseErrorInDtor) { + std::unique_ptr<file> f(new file(open_file())); EXPECT_WRITE( stderr, { @@ -413,120 +413,120 @@ TEST(FileTest, CloseErrorInDtor) { SUPPRESS_ASSERT(f.reset(nullptr)); }, format_system_error(EBADF, "cannot close file") + "\n"); -} - -TEST(FileTest, Close) { - file f = open_file(); - int fd = f.descriptor(); - f.close(); - EXPECT_EQ(-1, f.descriptor()); - EXPECT_TRUE(isclosed(fd)); -} - -TEST(FileTest, CloseError) { - file f = open_file(); - FMT_POSIX(close(f.descriptor())); - EXPECT_SYSTEM_ERROR_NOASSERT(f.close(), EBADF, "cannot close file"); - EXPECT_EQ(-1, f.descriptor()); -} - -TEST(FileTest, Read) { - file f = open_file(); - EXPECT_READ(f, FILE_CONTENT); -} - -TEST(FileTest, ReadError) { - file f("test-file", file::WRONLY); - char buf; - // We intentionally read from a file opened in the write-only mode to - // cause error. - EXPECT_SYSTEM_ERROR(f.read(&buf, 1), EBADF, "cannot read from file"); -} - -TEST(FileTest, Write) { - file read_end, write_end; - file::pipe(read_end, write_end); - write(write_end, "test"); - write_end.close(); - EXPECT_READ(read_end, "test"); -} - -TEST(FileTest, WriteError) { - file f("test-file", file::RDONLY); - // We intentionally write to a file opened in the read-only mode to - // cause error. - EXPECT_SYSTEM_ERROR(f.write(" ", 1), EBADF, "cannot write to file"); -} - -TEST(FileTest, Dup) { - file f = open_file(); - file copy = file::dup(f.descriptor()); - EXPECT_NE(f.descriptor(), copy.descriptor()); - EXPECT_EQ(FILE_CONTENT, read(copy, std::strlen(FILE_CONTENT))); -} - -# ifndef __COVERITY__ -TEST(FileTest, DupError) { - int value = -1; - EXPECT_SYSTEM_ERROR_NOASSERT(file::dup(value), EBADF, - "cannot duplicate file descriptor -1"); -} -# endif - -TEST(FileTest, Dup2) { - file f = open_file(); - file copy = open_file(); - f.dup2(copy.descriptor()); - EXPECT_NE(f.descriptor(), copy.descriptor()); - EXPECT_READ(copy, FILE_CONTENT); -} - -TEST(FileTest, Dup2Error) { - file f = open_file(); - EXPECT_SYSTEM_ERROR_NOASSERT( - f.dup2(-1), EBADF, - fmt::format("cannot duplicate file descriptor {} to -1", f.descriptor())); -} - -TEST(FileTest, Dup2NoExcept) { - file f = open_file(); - file copy = open_file(); - error_code ec; - f.dup2(copy.descriptor(), ec); - EXPECT_EQ(ec.get(), 0); - EXPECT_NE(f.descriptor(), copy.descriptor()); - EXPECT_READ(copy, FILE_CONTENT); -} - -TEST(FileTest, Dup2NoExceptError) { - file f = open_file(); - error_code ec; - SUPPRESS_ASSERT(f.dup2(-1, ec)); - EXPECT_EQ(EBADF, ec.get()); -} - -TEST(FileTest, Pipe) { - file read_end, write_end; - file::pipe(read_end, write_end); - EXPECT_NE(-1, read_end.descriptor()); - EXPECT_NE(-1, write_end.descriptor()); - write(write_end, "test"); - EXPECT_READ(read_end, "test"); -} - -TEST(FileTest, Fdopen) { - file read_end, write_end; - file::pipe(read_end, write_end); - int read_fd = read_end.descriptor(); - EXPECT_EQ(read_fd, FMT_POSIX(fileno(read_end.fdopen("r").get()))); -} - -# ifdef FMT_LOCALE -TEST(LocaleTest, Strtod) { - fmt::locale loc; - const char *start = "4.2", *ptr = start; - EXPECT_EQ(4.2, loc.strtod(ptr)); - EXPECT_EQ(start + 3, ptr); -} -# endif +} + +TEST(FileTest, Close) { + file f = open_file(); + int fd = f.descriptor(); + f.close(); + EXPECT_EQ(-1, f.descriptor()); + EXPECT_TRUE(isclosed(fd)); +} + +TEST(FileTest, CloseError) { + file f = open_file(); + FMT_POSIX(close(f.descriptor())); + EXPECT_SYSTEM_ERROR_NOASSERT(f.close(), EBADF, "cannot close file"); + EXPECT_EQ(-1, f.descriptor()); +} + +TEST(FileTest, Read) { + file f = open_file(); + EXPECT_READ(f, FILE_CONTENT); +} + +TEST(FileTest, ReadError) { + file f("test-file", file::WRONLY); + char buf; + // We intentionally read from a file opened in the write-only mode to + // cause error. + EXPECT_SYSTEM_ERROR(f.read(&buf, 1), EBADF, "cannot read from file"); +} + +TEST(FileTest, Write) { + file read_end, write_end; + file::pipe(read_end, write_end); + write(write_end, "test"); + write_end.close(); + EXPECT_READ(read_end, "test"); +} + +TEST(FileTest, WriteError) { + file f("test-file", file::RDONLY); + // We intentionally write to a file opened in the read-only mode to + // cause error. + EXPECT_SYSTEM_ERROR(f.write(" ", 1), EBADF, "cannot write to file"); +} + +TEST(FileTest, Dup) { + file f = open_file(); + file copy = file::dup(f.descriptor()); + EXPECT_NE(f.descriptor(), copy.descriptor()); + EXPECT_EQ(FILE_CONTENT, read(copy, std::strlen(FILE_CONTENT))); +} + +# ifndef __COVERITY__ +TEST(FileTest, DupError) { + int value = -1; + EXPECT_SYSTEM_ERROR_NOASSERT(file::dup(value), EBADF, + "cannot duplicate file descriptor -1"); +} +# endif + +TEST(FileTest, Dup2) { + file f = open_file(); + file copy = open_file(); + f.dup2(copy.descriptor()); + EXPECT_NE(f.descriptor(), copy.descriptor()); + EXPECT_READ(copy, FILE_CONTENT); +} + +TEST(FileTest, Dup2Error) { + file f = open_file(); + EXPECT_SYSTEM_ERROR_NOASSERT( + f.dup2(-1), EBADF, + fmt::format("cannot duplicate file descriptor {} to -1", f.descriptor())); +} + +TEST(FileTest, Dup2NoExcept) { + file f = open_file(); + file copy = open_file(); + error_code ec; + f.dup2(copy.descriptor(), ec); + EXPECT_EQ(ec.get(), 0); + EXPECT_NE(f.descriptor(), copy.descriptor()); + EXPECT_READ(copy, FILE_CONTENT); +} + +TEST(FileTest, Dup2NoExceptError) { + file f = open_file(); + error_code ec; + SUPPRESS_ASSERT(f.dup2(-1, ec)); + EXPECT_EQ(EBADF, ec.get()); +} + +TEST(FileTest, Pipe) { + file read_end, write_end; + file::pipe(read_end, write_end); + EXPECT_NE(-1, read_end.descriptor()); + EXPECT_NE(-1, write_end.descriptor()); + write(write_end, "test"); + EXPECT_READ(read_end, "test"); +} + +TEST(FileTest, Fdopen) { + file read_end, write_end; + file::pipe(read_end, write_end); + int read_fd = read_end.descriptor(); + EXPECT_EQ(read_fd, FMT_POSIX(fileno(read_end.fdopen("r").get()))); +} + +# ifdef FMT_LOCALE +TEST(LocaleTest, Strtod) { + fmt::locale loc; + const char *start = "4.2", *ptr = start; + EXPECT_EQ(4.2, loc.strtod(ptr)); + EXPECT_EQ(start + 3, ptr); +} +# endif #endif // FMT_USE_FCNTL diff --git a/contrib/libs/fmt/test/os-test/ya.make b/contrib/libs/fmt/test/os-test/ya.make index c0d5749207..34228bb26b 100644 --- a/contrib/libs/fmt/test/os-test/ya.make +++ b/contrib/libs/fmt/test/os-test/ya.make @@ -1,37 +1,37 @@ -# Generated by devtools/yamaker. - +# Generated by devtools/yamaker. + GTEST() - + WITHOUT_LICENSE_TEXTS() - + OWNER( orivej g:cpp-contrib ) -LICENSE(MIT) - -PEERDIR( - contrib/libs/fmt - contrib/libs/fmt/test -) - -NO_COMPILER_WARNINGS() - -NO_UTIL() - -CFLAGS( - -DFMT_LOCALE - -DFMT_SHARED - -DGTEST_HAS_STD_WSTRING=1 - -DGTEST_LANG_CXX11=0 - -D_SILENCE_TR1_NAMESPACE_DEPRECATION_WARNING=1 -) - -SRCDIR(contrib/libs/fmt/test) - -SRCS( - os-test.cc -) - -END() +LICENSE(MIT) + +PEERDIR( + contrib/libs/fmt + contrib/libs/fmt/test +) + +NO_COMPILER_WARNINGS() + +NO_UTIL() + +CFLAGS( + -DFMT_LOCALE + -DFMT_SHARED + -DGTEST_HAS_STD_WSTRING=1 + -DGTEST_LANG_CXX11=0 + -D_SILENCE_TR1_NAMESPACE_DEPRECATION_WARNING=1 +) + +SRCDIR(contrib/libs/fmt/test) + +SRCS( + os-test.cc +) + +END() diff --git a/contrib/libs/fmt/test/ostream-test.cc b/contrib/libs/fmt/test/ostream-test.cc index 7ec8515baf..4cef5a78c4 100644 --- a/contrib/libs/fmt/test/ostream-test.cc +++ b/contrib/libs/fmt/test/ostream-test.cc @@ -1,297 +1,297 @@ -// Formatting library for C++ - std::ostream support tests -// -// Copyright (c) 2012 - present, Victor Zverovich -// All rights reserved. -// -// For the license information refer to format.h. - -#include "fmt/format.h" - -struct test {}; - -// Test that there is no issues with specializations when fmt/ostream.h is -// included after fmt/format.h. -namespace fmt { -template <> struct formatter<test> : formatter<int> { - template <typename FormatContext> - typename FormatContext::iterator format(const test&, FormatContext& ctx) { - return formatter<int>::format(42, ctx); - } -}; -} // namespace fmt - +// Formatting library for C++ - std::ostream support tests +// +// Copyright (c) 2012 - present, Victor Zverovich +// All rights reserved. +// +// For the license information refer to format.h. + +#include "fmt/format.h" + +struct test {}; + +// Test that there is no issues with specializations when fmt/ostream.h is +// included after fmt/format.h. +namespace fmt { +template <> struct formatter<test> : formatter<int> { + template <typename FormatContext> + typename FormatContext::iterator format(const test&, FormatContext& ctx) { + return formatter<int>::format(42, ctx); + } +}; +} // namespace fmt + #include <sstream> -#include "fmt/ostream.h" +#include "fmt/ostream.h" #include "fmt/ranges.h" -#include <gmock/gmock.h> -#include "gtest-extra.h" -#include "util.h" - -using fmt::format; -using fmt::format_error; - -static std::ostream& operator<<(std::ostream& os, const Date& d) { - os << d.year() << '-' << d.month() << '-' << d.day(); - return os; -} - -static std::wostream& operator<<(std::wostream& os, const Date& d) { - os << d.year() << L'-' << d.month() << L'-' << d.day(); - return os; -} - -// Make sure that overloaded comma operators do no harm to is_streamable. -struct type_with_comma_op {}; -template <typename T> void operator,(type_with_comma_op, const T&); -template <typename T> type_with_comma_op operator<<(T&, const Date&); - -enum streamable_enum {}; -static std::ostream& operator<<(std::ostream& os, streamable_enum) { - return os << "streamable_enum"; -} - -static std::wostream& operator<<(std::wostream& os, streamable_enum) { - return os << L"streamable_enum"; -} - -enum unstreamable_enum {}; - -TEST(OStreamTest, Enum) { - EXPECT_EQ("streamable_enum", fmt::format("{}", streamable_enum())); - EXPECT_EQ("0", fmt::format("{}", unstreamable_enum())); - EXPECT_EQ(L"streamable_enum", fmt::format(L"{}", streamable_enum())); - EXPECT_EQ(L"0", fmt::format(L"{}", unstreamable_enum())); -} - +#include <gmock/gmock.h> +#include "gtest-extra.h" +#include "util.h" + +using fmt::format; +using fmt::format_error; + +static std::ostream& operator<<(std::ostream& os, const Date& d) { + os << d.year() << '-' << d.month() << '-' << d.day(); + return os; +} + +static std::wostream& operator<<(std::wostream& os, const Date& d) { + os << d.year() << L'-' << d.month() << L'-' << d.day(); + return os; +} + +// Make sure that overloaded comma operators do no harm to is_streamable. +struct type_with_comma_op {}; +template <typename T> void operator,(type_with_comma_op, const T&); +template <typename T> type_with_comma_op operator<<(T&, const Date&); + +enum streamable_enum {}; +static std::ostream& operator<<(std::ostream& os, streamable_enum) { + return os << "streamable_enum"; +} + +static std::wostream& operator<<(std::wostream& os, streamable_enum) { + return os << L"streamable_enum"; +} + +enum unstreamable_enum {}; + +TEST(OStreamTest, Enum) { + EXPECT_EQ("streamable_enum", fmt::format("{}", streamable_enum())); + EXPECT_EQ("0", fmt::format("{}", unstreamable_enum())); + EXPECT_EQ(L"streamable_enum", fmt::format(L"{}", streamable_enum())); + EXPECT_EQ(L"0", fmt::format(L"{}", unstreamable_enum())); +} + struct test_arg_formatter : fmt::detail::arg_formatter<fmt::format_context::iterator, char> { - fmt::format_parse_context parse_ctx; - test_arg_formatter(fmt::format_context& ctx, fmt::format_specs& s) + fmt::format_parse_context parse_ctx; + test_arg_formatter(fmt::format_context& ctx, fmt::format_specs& s) : fmt::detail::arg_formatter<fmt::format_context::iterator, char>( ctx, &parse_ctx, &s), parse_ctx("") {} -}; - -TEST(OStreamTest, CustomArg) { - fmt::memory_buffer buffer; +}; + +TEST(OStreamTest, CustomArg) { + fmt::memory_buffer buffer; fmt::format_context ctx(fmt::detail::buffer_appender<char>{buffer}, fmt::format_args()); - fmt::format_specs spec; - test_arg_formatter af(ctx, spec); - fmt::visit_format_arg( + fmt::format_specs spec; + test_arg_formatter af(ctx, spec); + fmt::visit_format_arg( af, fmt::detail::make_arg<fmt::format_context>(streamable_enum())); - EXPECT_EQ("streamable_enum", std::string(buffer.data(), buffer.size())); -} - -TEST(OStreamTest, Format) { - EXPECT_EQ("a string", format("{0}", TestString("a string"))); - std::string s = format("The date is {0}", Date(2012, 12, 9)); - EXPECT_EQ("The date is 2012-12-9", s); - Date date(2012, 12, 9); - EXPECT_EQ(L"The date is 2012-12-9", - format(L"The date is {0}", Date(2012, 12, 9))); -} - -TEST(OStreamTest, FormatSpecs) { - EXPECT_EQ("def ", format("{0:<5}", TestString("def"))); - EXPECT_EQ(" def", format("{0:>5}", TestString("def"))); + EXPECT_EQ("streamable_enum", std::string(buffer.data(), buffer.size())); +} + +TEST(OStreamTest, Format) { + EXPECT_EQ("a string", format("{0}", TestString("a string"))); + std::string s = format("The date is {0}", Date(2012, 12, 9)); + EXPECT_EQ("The date is 2012-12-9", s); + Date date(2012, 12, 9); + EXPECT_EQ(L"The date is 2012-12-9", + format(L"The date is {0}", Date(2012, 12, 9))); +} + +TEST(OStreamTest, FormatSpecs) { + EXPECT_EQ("def ", format("{0:<5}", TestString("def"))); + EXPECT_EQ(" def", format("{0:>5}", TestString("def"))); #if FMT_DEPRECATED_NUMERIC_ALIGN - EXPECT_THROW_MSG(format("{0:=5}", TestString("def")), format_error, - "format specifier requires numeric argument"); -#endif - EXPECT_EQ(" def ", format("{0:^5}", TestString("def"))); - EXPECT_EQ("def**", format("{0:*<5}", TestString("def"))); - EXPECT_THROW_MSG(format("{0:+}", TestString()), format_error, - "format specifier requires numeric argument"); - EXPECT_THROW_MSG(format("{0:-}", TestString()), format_error, - "format specifier requires numeric argument"); - EXPECT_THROW_MSG(format("{0: }", TestString()), format_error, - "format specifier requires numeric argument"); - EXPECT_THROW_MSG(format("{0:#}", TestString()), format_error, - "format specifier requires numeric argument"); - EXPECT_THROW_MSG(format("{0:05}", TestString()), format_error, - "format specifier requires numeric argument"); - EXPECT_EQ("test ", format("{0:13}", TestString("test"))); - EXPECT_EQ("test ", format("{0:{1}}", TestString("test"), 13)); - EXPECT_EQ("te", format("{0:.2}", TestString("test"))); - EXPECT_EQ("te", format("{0:.{1}}", TestString("test"), 2)); -} - -struct EmptyTest {}; -static std::ostream& operator<<(std::ostream& os, EmptyTest) { - return os << ""; -} - -TEST(OStreamTest, EmptyCustomOutput) { - EXPECT_EQ("", fmt::format("{}", EmptyTest())); -} - -TEST(OStreamTest, Print) { - std::ostringstream os; - fmt::print(os, "Don't {}!", "panic"); - EXPECT_EQ("Don't panic!", os.str()); - std::wostringstream wos; - fmt::print(wos, L"Don't {}!", L"panic"); - EXPECT_EQ(L"Don't panic!", wos.str()); -} - -TEST(OStreamTest, WriteToOStream) { - std::ostringstream os; - fmt::memory_buffer buffer; - const char* foo = "foo"; - buffer.append(foo, foo + std::strlen(foo)); + EXPECT_THROW_MSG(format("{0:=5}", TestString("def")), format_error, + "format specifier requires numeric argument"); +#endif + EXPECT_EQ(" def ", format("{0:^5}", TestString("def"))); + EXPECT_EQ("def**", format("{0:*<5}", TestString("def"))); + EXPECT_THROW_MSG(format("{0:+}", TestString()), format_error, + "format specifier requires numeric argument"); + EXPECT_THROW_MSG(format("{0:-}", TestString()), format_error, + "format specifier requires numeric argument"); + EXPECT_THROW_MSG(format("{0: }", TestString()), format_error, + "format specifier requires numeric argument"); + EXPECT_THROW_MSG(format("{0:#}", TestString()), format_error, + "format specifier requires numeric argument"); + EXPECT_THROW_MSG(format("{0:05}", TestString()), format_error, + "format specifier requires numeric argument"); + EXPECT_EQ("test ", format("{0:13}", TestString("test"))); + EXPECT_EQ("test ", format("{0:{1}}", TestString("test"), 13)); + EXPECT_EQ("te", format("{0:.2}", TestString("test"))); + EXPECT_EQ("te", format("{0:.{1}}", TestString("test"), 2)); +} + +struct EmptyTest {}; +static std::ostream& operator<<(std::ostream& os, EmptyTest) { + return os << ""; +} + +TEST(OStreamTest, EmptyCustomOutput) { + EXPECT_EQ("", fmt::format("{}", EmptyTest())); +} + +TEST(OStreamTest, Print) { + std::ostringstream os; + fmt::print(os, "Don't {}!", "panic"); + EXPECT_EQ("Don't panic!", os.str()); + std::wostringstream wos; + fmt::print(wos, L"Don't {}!", L"panic"); + EXPECT_EQ(L"Don't panic!", wos.str()); +} + +TEST(OStreamTest, WriteToOStream) { + std::ostringstream os; + fmt::memory_buffer buffer; + const char* foo = "foo"; + buffer.append(foo, foo + std::strlen(foo)); fmt::detail::write_buffer(os, buffer); - EXPECT_EQ("foo", os.str()); -} - -TEST(OStreamTest, WriteToOStreamMaxSize) { + EXPECT_EQ("foo", os.str()); +} + +TEST(OStreamTest, WriteToOStreamMaxSize) { size_t max_size = fmt::detail::max_value<size_t>(); std::streamsize max_streamsize = fmt::detail::max_value<std::streamsize>(); if (max_size <= fmt::detail::to_unsigned(max_streamsize)) return; - + struct test_buffer final : fmt::detail::buffer<char> { explicit test_buffer(size_t size) : fmt::detail::buffer<char>(nullptr, size, size) {} void grow(size_t) {} - } buffer(max_size); - - struct mock_streambuf : std::streambuf { - MOCK_METHOD2(xsputn, std::streamsize(const void* s, std::streamsize n)); - std::streamsize xsputn(const char* s, std::streamsize n) { - const void* v = s; - return xsputn(v, n); - } - } streambuf; - - struct test_ostream : std::ostream { - explicit test_ostream(mock_streambuf& buffer) : std::ostream(&buffer) {} - } os(streambuf); - - testing::InSequence sequence; - const char* data = nullptr; - typedef std::make_unsigned<std::streamsize>::type ustreamsize; - ustreamsize size = max_size; - do { + } buffer(max_size); + + struct mock_streambuf : std::streambuf { + MOCK_METHOD2(xsputn, std::streamsize(const void* s, std::streamsize n)); + std::streamsize xsputn(const char* s, std::streamsize n) { + const void* v = s; + return xsputn(v, n); + } + } streambuf; + + struct test_ostream : std::ostream { + explicit test_ostream(mock_streambuf& buffer) : std::ostream(&buffer) {} + } os(streambuf); + + testing::InSequence sequence; + const char* data = nullptr; + typedef std::make_unsigned<std::streamsize>::type ustreamsize; + ustreamsize size = max_size; + do { auto n = std::min(size, fmt::detail::to_unsigned(max_streamsize)); - EXPECT_CALL(streambuf, xsputn(data, static_cast<std::streamsize>(n))) - .WillOnce(testing::Return(max_streamsize)); - data += n; - size -= n; - } while (size != 0); + EXPECT_CALL(streambuf, xsputn(data, static_cast<std::streamsize>(n))) + .WillOnce(testing::Return(max_streamsize)); + data += n; + size -= n; + } while (size != 0); fmt::detail::write_buffer(os, buffer); -} - -TEST(OStreamTest, Join) { - int v[3] = {1, 2, 3}; - EXPECT_EQ("1, 2, 3", fmt::format("{}", fmt::join(v, v + 3, ", "))); -} - -#if FMT_USE_CONSTEXPR -TEST(OStreamTest, ConstexprString) { - EXPECT_EQ("42", format(FMT_STRING("{}"), std::string("42"))); - EXPECT_EQ("a string", format(FMT_STRING("{0}"), TestString("a string"))); -} -#endif - -namespace fmt_test { -struct ABC {}; - -template <typename Output> Output& operator<<(Output& out, ABC) { - out << "ABC"; - return out; -} -} // namespace fmt_test - -template <typename T> struct TestTemplate {}; - -template <typename T> -std::ostream& operator<<(std::ostream& os, TestTemplate<T>) { - return os << 1; -} - -namespace fmt { -template <typename T> struct formatter<TestTemplate<T>> : formatter<int> { - template <typename FormatContext> - typename FormatContext::iterator format(TestTemplate<T>, FormatContext& ctx) { - return formatter<int>::format(2, ctx); - } -}; -} // namespace fmt - -#if !FMT_GCC_VERSION || FMT_GCC_VERSION >= 407 -TEST(OStreamTest, Template) { - EXPECT_EQ("2", fmt::format("{}", TestTemplate<int>())); -} - -TEST(FormatTest, FormatToN) { - char buffer[4]; - buffer[3] = 'x'; - auto result = fmt::format_to_n(buffer, 3, "{}", fmt_test::ABC()); - EXPECT_EQ(3u, result.size); - EXPECT_EQ(buffer + 3, result.out); - EXPECT_EQ("ABCx", fmt::string_view(buffer, 4)); - result = fmt::format_to_n(buffer, 3, "x{}y", fmt_test::ABC()); - EXPECT_EQ(5u, result.size); - EXPECT_EQ(buffer + 3, result.out); - EXPECT_EQ("xABx", fmt::string_view(buffer, 4)); -} -#endif - -#if FMT_USE_USER_DEFINED_LITERALS -TEST(FormatTest, UDL) { - using namespace fmt::literals; - EXPECT_EQ("{}"_format("test"), "test"); -} -#endif - -template <typename T> struct convertible { - T value; - explicit convertible(const T& val) : value(val) {} - operator T() const { return value; } -}; - -TEST(OStreamTest, DisableBuiltinOStreamOperators) { - EXPECT_EQ("42", fmt::format("{:d}", convertible<unsigned short>(42))); - EXPECT_EQ(L"42", fmt::format(L"{:d}", convertible<unsigned short>(42))); - EXPECT_EQ("foo", fmt::format("{}", convertible<const char*>("foo"))); -} - -struct explicitly_convertible_to_string_like { - template <typename String, - typename = typename std::enable_if<std::is_constructible< +} + +TEST(OStreamTest, Join) { + int v[3] = {1, 2, 3}; + EXPECT_EQ("1, 2, 3", fmt::format("{}", fmt::join(v, v + 3, ", "))); +} + +#if FMT_USE_CONSTEXPR +TEST(OStreamTest, ConstexprString) { + EXPECT_EQ("42", format(FMT_STRING("{}"), std::string("42"))); + EXPECT_EQ("a string", format(FMT_STRING("{0}"), TestString("a string"))); +} +#endif + +namespace fmt_test { +struct ABC {}; + +template <typename Output> Output& operator<<(Output& out, ABC) { + out << "ABC"; + return out; +} +} // namespace fmt_test + +template <typename T> struct TestTemplate {}; + +template <typename T> +std::ostream& operator<<(std::ostream& os, TestTemplate<T>) { + return os << 1; +} + +namespace fmt { +template <typename T> struct formatter<TestTemplate<T>> : formatter<int> { + template <typename FormatContext> + typename FormatContext::iterator format(TestTemplate<T>, FormatContext& ctx) { + return formatter<int>::format(2, ctx); + } +}; +} // namespace fmt + +#if !FMT_GCC_VERSION || FMT_GCC_VERSION >= 407 +TEST(OStreamTest, Template) { + EXPECT_EQ("2", fmt::format("{}", TestTemplate<int>())); +} + +TEST(FormatTest, FormatToN) { + char buffer[4]; + buffer[3] = 'x'; + auto result = fmt::format_to_n(buffer, 3, "{}", fmt_test::ABC()); + EXPECT_EQ(3u, result.size); + EXPECT_EQ(buffer + 3, result.out); + EXPECT_EQ("ABCx", fmt::string_view(buffer, 4)); + result = fmt::format_to_n(buffer, 3, "x{}y", fmt_test::ABC()); + EXPECT_EQ(5u, result.size); + EXPECT_EQ(buffer + 3, result.out); + EXPECT_EQ("xABx", fmt::string_view(buffer, 4)); +} +#endif + +#if FMT_USE_USER_DEFINED_LITERALS +TEST(FormatTest, UDL) { + using namespace fmt::literals; + EXPECT_EQ("{}"_format("test"), "test"); +} +#endif + +template <typename T> struct convertible { + T value; + explicit convertible(const T& val) : value(val) {} + operator T() const { return value; } +}; + +TEST(OStreamTest, DisableBuiltinOStreamOperators) { + EXPECT_EQ("42", fmt::format("{:d}", convertible<unsigned short>(42))); + EXPECT_EQ(L"42", fmt::format(L"{:d}", convertible<unsigned short>(42))); + EXPECT_EQ("foo", fmt::format("{}", convertible<const char*>("foo"))); +} + +struct explicitly_convertible_to_string_like { + template <typename String, + typename = typename std::enable_if<std::is_constructible< String, const char*, size_t>::value>::type> - explicit operator String() const { - return String("foo", 3u); - } -}; - -std::ostream& operator<<(std::ostream& os, - explicitly_convertible_to_string_like) { - return os << "bar"; -} - + explicit operator String() const { + return String("foo", 3u); + } +}; + +std::ostream& operator<<(std::ostream& os, + explicitly_convertible_to_string_like) { + return os << "bar"; +} + TEST(OStreamTest, FormatExplicitlyConvertibleToStringLike) { - EXPECT_EQ("bar", fmt::format("{}", explicitly_convertible_to_string_like())); -} - -#ifdef FMT_USE_STRING_VIEW -struct explicitly_convertible_to_std_string_view { + EXPECT_EQ("bar", fmt::format("{}", explicitly_convertible_to_string_like())); +} + +#ifdef FMT_USE_STRING_VIEW +struct explicitly_convertible_to_std_string_view { explicit operator fmt::detail::std_string_view<char>() const { - return {"foo", 3u}; - } -}; - -std::ostream& operator<<(std::ostream& os, - explicitly_convertible_to_std_string_view) { - return os << "bar"; -} - + return {"foo", 3u}; + } +}; + +std::ostream& operator<<(std::ostream& os, + explicitly_convertible_to_std_string_view) { + return os << "bar"; +} + TEST(OStreamTest, FormatExplicitlyConvertibleToStdStringView) { - EXPECT_EQ("bar", fmt::format("{}", explicitly_convertible_to_string_like())); -} + EXPECT_EQ("bar", fmt::format("{}", explicitly_convertible_to_string_like())); +} #endif // FMT_USE_STRING_VIEW - + struct streamable_and_convertible_to_bool { operator bool() const { return true; } }; diff --git a/contrib/libs/fmt/test/ostream-test/ya.make b/contrib/libs/fmt/test/ostream-test/ya.make index 2356199159..10921b40d1 100644 --- a/contrib/libs/fmt/test/ostream-test/ya.make +++ b/contrib/libs/fmt/test/ostream-test/ya.make @@ -1,37 +1,37 @@ -# Generated by devtools/yamaker. - +# Generated by devtools/yamaker. + GTEST() - + WITHOUT_LICENSE_TEXTS() - + OWNER( orivej g:cpp-contrib ) -LICENSE(MIT) - -PEERDIR( - contrib/libs/fmt - contrib/libs/fmt/test -) - -NO_COMPILER_WARNINGS() - -NO_UTIL() - -CFLAGS( - -DFMT_LOCALE - -DFMT_SHARED - -DGTEST_HAS_STD_WSTRING=1 - -DGTEST_LANG_CXX11=0 - -D_SILENCE_TR1_NAMESPACE_DEPRECATION_WARNING=1 -) - -SRCDIR(contrib/libs/fmt/test) - -SRCS( - ostream-test.cc -) - -END() +LICENSE(MIT) + +PEERDIR( + contrib/libs/fmt + contrib/libs/fmt/test +) + +NO_COMPILER_WARNINGS() + +NO_UTIL() + +CFLAGS( + -DFMT_LOCALE + -DFMT_SHARED + -DGTEST_HAS_STD_WSTRING=1 + -DGTEST_LANG_CXX11=0 + -D_SILENCE_TR1_NAMESPACE_DEPRECATION_WARNING=1 +) + +SRCDIR(contrib/libs/fmt/test) + +SRCS( + ostream-test.cc +) + +END() diff --git a/contrib/libs/fmt/test/posix-mock-test.cc b/contrib/libs/fmt/test/posix-mock-test.cc index 54f6ab7971..0ea1b9c6d5 100644 --- a/contrib/libs/fmt/test/posix-mock-test.cc +++ b/contrib/libs/fmt/test/posix-mock-test.cc @@ -1,558 +1,558 @@ -// Tests of the C++ interface to POSIX functions that require mocks -// -// Copyright (c) 2012 - present, Victor Zverovich -// All rights reserved. -// -// For the license information refer to format.h. - -// Disable bogus MSVC warnings. -#ifndef _CRT_SECURE_NO_WARNINGS -# define _CRT_SECURE_NO_WARNINGS -#endif - -#include "posix-mock.h" - -#include <errno.h> -#include <fcntl.h> - -#include <climits> -#include <memory> - -#include "../src/os.cc" - -#ifdef _WIN32 -# include <io.h> -# undef max -# undef ERROR -#endif - -#include <gmock/gmock.h> -#include "gtest-extra.h" -#include "util.h" - -using fmt::buffered_file; -using fmt::error_code; - -using testing::_; -using testing::Return; -using testing::StrEq; - -namespace { -int open_count; -int close_count; -int dup_count; -int dup2_count; -int fdopen_count; -int read_count; -int write_count; -int pipe_count; -int fopen_count; -int fclose_count; -int fileno_count; +// Tests of the C++ interface to POSIX functions that require mocks +// +// Copyright (c) 2012 - present, Victor Zverovich +// All rights reserved. +// +// For the license information refer to format.h. + +// Disable bogus MSVC warnings. +#ifndef _CRT_SECURE_NO_WARNINGS +# define _CRT_SECURE_NO_WARNINGS +#endif + +#include "posix-mock.h" + +#include <errno.h> +#include <fcntl.h> + +#include <climits> +#include <memory> + +#include "../src/os.cc" + +#ifdef _WIN32 +# include <io.h> +# undef max +# undef ERROR +#endif + +#include <gmock/gmock.h> +#include "gtest-extra.h" +#include "util.h" + +using fmt::buffered_file; +using fmt::error_code; + +using testing::_; +using testing::Return; +using testing::StrEq; + +namespace { +int open_count; +int close_count; +int dup_count; +int dup2_count; +int fdopen_count; +int read_count; +int write_count; +int pipe_count; +int fopen_count; +int fclose_count; +int fileno_count; size_t read_nbyte; size_t write_nbyte; -bool sysconf_error; - -enum { NONE, MAX_SIZE, ERROR } fstat_sim; -} // namespace - -#define EMULATE_EINTR(func, error_result) \ - if (func##_count != 0) { \ - if (func##_count++ != 3) { \ - errno = EINTR; \ - return error_result; \ - } \ - } - -#ifndef _MSC_VER -int test::open(const char* path, int oflag, int mode) { - EMULATE_EINTR(open, -1); - return ::open(path, oflag, mode); -} -#else -errno_t test::sopen_s(int* pfh, const char* filename, int oflag, int shflag, - int pmode) { - EMULATE_EINTR(open, EINTR); - return _sopen_s(pfh, filename, oflag, shflag, pmode); -} -#endif - -#ifndef _WIN32 - -long test::sysconf(int name) { - long result = ::sysconf(name); - if (!sysconf_error) return result; - // Simulate an error. - errno = EINVAL; - return -1; -} - -static off_t max_file_size() { return std::numeric_limits<off_t>::max(); } - -int test::fstat(int fd, struct stat* buf) { - int result = ::fstat(fd, buf); - if (fstat_sim == MAX_SIZE) buf->st_size = max_file_size(); - return result; -} - -#else - -static LONGLONG max_file_size() { return std::numeric_limits<LONGLONG>::max(); } - -DWORD test::GetFileSize(HANDLE hFile, LPDWORD lpFileSizeHigh) { - if (fstat_sim == ERROR) { - SetLastError(ERROR_ACCESS_DENIED); - return INVALID_FILE_SIZE; - } - if (fstat_sim == MAX_SIZE) { - DWORD max = std::numeric_limits<DWORD>::max(); - *lpFileSizeHigh = max >> 1; - return max; - } - return ::GetFileSize(hFile, lpFileSizeHigh); -} - -#endif - -int test::close(int fildes) { - // Close the file first because close shouldn't be retried. - int result = ::FMT_POSIX(close(fildes)); - EMULATE_EINTR(close, -1); - return result; -} - -int test::dup(int fildes) { - EMULATE_EINTR(dup, -1); - return ::FMT_POSIX(dup(fildes)); -} - -int test::dup2(int fildes, int fildes2) { - EMULATE_EINTR(dup2, -1); - return ::FMT_POSIX(dup2(fildes, fildes2)); -} - -FILE* test::fdopen(int fildes, const char* mode) { - EMULATE_EINTR(fdopen, nullptr); - return ::FMT_POSIX(fdopen(fildes, mode)); -} - -test::ssize_t test::read(int fildes, void* buf, test::size_t nbyte) { - read_nbyte = nbyte; - EMULATE_EINTR(read, -1); - return ::FMT_POSIX(read(fildes, buf, nbyte)); -} - -test::ssize_t test::write(int fildes, const void* buf, test::size_t nbyte) { - write_nbyte = nbyte; - EMULATE_EINTR(write, -1); - return ::FMT_POSIX(write(fildes, buf, nbyte)); -} - -#ifndef _WIN32 -int test::pipe(int fildes[2]) { - EMULATE_EINTR(pipe, -1); - return ::pipe(fildes); -} -#else -int test::pipe(int* pfds, unsigned psize, int textmode) { - EMULATE_EINTR(pipe, -1); - return _pipe(pfds, psize, textmode); -} -#endif - -FILE* test::fopen(const char* filename, const char* mode) { - EMULATE_EINTR(fopen, nullptr); - return ::fopen(filename, mode); -} - -int test::fclose(FILE* stream) { - EMULATE_EINTR(fclose, EOF); - return ::fclose(stream); -} - -int(test::fileno)(FILE* stream) { - EMULATE_EINTR(fileno, -1); -#ifdef fileno - return FMT_POSIX(fileno(stream)); -#else - return ::FMT_POSIX(fileno(stream)); -#endif -} - -#ifndef _WIN32 -# define EXPECT_RETRY(statement, func, message) \ - func##_count = 1; \ - statement; \ - EXPECT_EQ(4, func##_count); \ - func##_count = 0; -# define EXPECT_EQ_POSIX(expected, actual) EXPECT_EQ(expected, actual) -#else -# define EXPECT_RETRY(statement, func, message) \ - func##_count = 1; \ - EXPECT_SYSTEM_ERROR(statement, EINTR, message); \ - func##_count = 0; -# define EXPECT_EQ_POSIX(expected, actual) -#endif - -static void write_file(fmt::cstring_view filename, fmt::string_view content) { - fmt::buffered_file f(filename, "w"); - f.print("{}", content); -} - -#if FMT_USE_FCNTL -using fmt::file; - -TEST(UtilTest, GetPageSize) { -# ifdef _WIN32 - SYSTEM_INFO si = {}; - GetSystemInfo(&si); - EXPECT_EQ(si.dwPageSize, fmt::getpagesize()); -# else - EXPECT_EQ(sysconf(_SC_PAGESIZE), fmt::getpagesize()); - sysconf_error = true; - EXPECT_SYSTEM_ERROR(fmt::getpagesize(), EINVAL, - "cannot get memory page size"); - sysconf_error = false; -# endif -} - -TEST(FileTest, OpenRetry) { - write_file("temp", "there must be something here"); - std::unique_ptr<file> f{nullptr}; - EXPECT_RETRY(f.reset(new file("temp", file::RDONLY)), open, - "cannot open file temp"); -# ifndef _WIN32 - char c = 0; - f->read(&c, 1); -# endif -} - -TEST(FileTest, CloseNoRetryInDtor) { - file read_end, write_end; - file::pipe(read_end, write_end); - std::unique_ptr<file> f(new file(std::move(read_end))); - int saved_close_count = 0; - EXPECT_WRITE( - stderr, - { - close_count = 1; - f.reset(nullptr); - saved_close_count = close_count; - close_count = 0; - }, - format_system_error(EINTR, "cannot close file") + "\n"); - EXPECT_EQ(2, saved_close_count); -} - -TEST(FileTest, CloseNoRetry) { - file read_end, write_end; - file::pipe(read_end, write_end); - close_count = 1; - EXPECT_SYSTEM_ERROR(read_end.close(), EINTR, "cannot close file"); - EXPECT_EQ(2, close_count); - close_count = 0; -} - -TEST(FileTest, Size) { - std::string content = "top secret, destroy before reading"; - write_file("temp", content); - file f("temp", file::RDONLY); - EXPECT_GE(f.size(), 0); - EXPECT_EQ(content.size(), static_cast<unsigned long long>(f.size())); -# ifdef _WIN32 - fmt::memory_buffer message; +bool sysconf_error; + +enum { NONE, MAX_SIZE, ERROR } fstat_sim; +} // namespace + +#define EMULATE_EINTR(func, error_result) \ + if (func##_count != 0) { \ + if (func##_count++ != 3) { \ + errno = EINTR; \ + return error_result; \ + } \ + } + +#ifndef _MSC_VER +int test::open(const char* path, int oflag, int mode) { + EMULATE_EINTR(open, -1); + return ::open(path, oflag, mode); +} +#else +errno_t test::sopen_s(int* pfh, const char* filename, int oflag, int shflag, + int pmode) { + EMULATE_EINTR(open, EINTR); + return _sopen_s(pfh, filename, oflag, shflag, pmode); +} +#endif + +#ifndef _WIN32 + +long test::sysconf(int name) { + long result = ::sysconf(name); + if (!sysconf_error) return result; + // Simulate an error. + errno = EINVAL; + return -1; +} + +static off_t max_file_size() { return std::numeric_limits<off_t>::max(); } + +int test::fstat(int fd, struct stat* buf) { + int result = ::fstat(fd, buf); + if (fstat_sim == MAX_SIZE) buf->st_size = max_file_size(); + return result; +} + +#else + +static LONGLONG max_file_size() { return std::numeric_limits<LONGLONG>::max(); } + +DWORD test::GetFileSize(HANDLE hFile, LPDWORD lpFileSizeHigh) { + if (fstat_sim == ERROR) { + SetLastError(ERROR_ACCESS_DENIED); + return INVALID_FILE_SIZE; + } + if (fstat_sim == MAX_SIZE) { + DWORD max = std::numeric_limits<DWORD>::max(); + *lpFileSizeHigh = max >> 1; + return max; + } + return ::GetFileSize(hFile, lpFileSizeHigh); +} + +#endif + +int test::close(int fildes) { + // Close the file first because close shouldn't be retried. + int result = ::FMT_POSIX(close(fildes)); + EMULATE_EINTR(close, -1); + return result; +} + +int test::dup(int fildes) { + EMULATE_EINTR(dup, -1); + return ::FMT_POSIX(dup(fildes)); +} + +int test::dup2(int fildes, int fildes2) { + EMULATE_EINTR(dup2, -1); + return ::FMT_POSIX(dup2(fildes, fildes2)); +} + +FILE* test::fdopen(int fildes, const char* mode) { + EMULATE_EINTR(fdopen, nullptr); + return ::FMT_POSIX(fdopen(fildes, mode)); +} + +test::ssize_t test::read(int fildes, void* buf, test::size_t nbyte) { + read_nbyte = nbyte; + EMULATE_EINTR(read, -1); + return ::FMT_POSIX(read(fildes, buf, nbyte)); +} + +test::ssize_t test::write(int fildes, const void* buf, test::size_t nbyte) { + write_nbyte = nbyte; + EMULATE_EINTR(write, -1); + return ::FMT_POSIX(write(fildes, buf, nbyte)); +} + +#ifndef _WIN32 +int test::pipe(int fildes[2]) { + EMULATE_EINTR(pipe, -1); + return ::pipe(fildes); +} +#else +int test::pipe(int* pfds, unsigned psize, int textmode) { + EMULATE_EINTR(pipe, -1); + return _pipe(pfds, psize, textmode); +} +#endif + +FILE* test::fopen(const char* filename, const char* mode) { + EMULATE_EINTR(fopen, nullptr); + return ::fopen(filename, mode); +} + +int test::fclose(FILE* stream) { + EMULATE_EINTR(fclose, EOF); + return ::fclose(stream); +} + +int(test::fileno)(FILE* stream) { + EMULATE_EINTR(fileno, -1); +#ifdef fileno + return FMT_POSIX(fileno(stream)); +#else + return ::FMT_POSIX(fileno(stream)); +#endif +} + +#ifndef _WIN32 +# define EXPECT_RETRY(statement, func, message) \ + func##_count = 1; \ + statement; \ + EXPECT_EQ(4, func##_count); \ + func##_count = 0; +# define EXPECT_EQ_POSIX(expected, actual) EXPECT_EQ(expected, actual) +#else +# define EXPECT_RETRY(statement, func, message) \ + func##_count = 1; \ + EXPECT_SYSTEM_ERROR(statement, EINTR, message); \ + func##_count = 0; +# define EXPECT_EQ_POSIX(expected, actual) +#endif + +static void write_file(fmt::cstring_view filename, fmt::string_view content) { + fmt::buffered_file f(filename, "w"); + f.print("{}", content); +} + +#if FMT_USE_FCNTL +using fmt::file; + +TEST(UtilTest, GetPageSize) { +# ifdef _WIN32 + SYSTEM_INFO si = {}; + GetSystemInfo(&si); + EXPECT_EQ(si.dwPageSize, fmt::getpagesize()); +# else + EXPECT_EQ(sysconf(_SC_PAGESIZE), fmt::getpagesize()); + sysconf_error = true; + EXPECT_SYSTEM_ERROR(fmt::getpagesize(), EINVAL, + "cannot get memory page size"); + sysconf_error = false; +# endif +} + +TEST(FileTest, OpenRetry) { + write_file("temp", "there must be something here"); + std::unique_ptr<file> f{nullptr}; + EXPECT_RETRY(f.reset(new file("temp", file::RDONLY)), open, + "cannot open file temp"); +# ifndef _WIN32 + char c = 0; + f->read(&c, 1); +# endif +} + +TEST(FileTest, CloseNoRetryInDtor) { + file read_end, write_end; + file::pipe(read_end, write_end); + std::unique_ptr<file> f(new file(std::move(read_end))); + int saved_close_count = 0; + EXPECT_WRITE( + stderr, + { + close_count = 1; + f.reset(nullptr); + saved_close_count = close_count; + close_count = 0; + }, + format_system_error(EINTR, "cannot close file") + "\n"); + EXPECT_EQ(2, saved_close_count); +} + +TEST(FileTest, CloseNoRetry) { + file read_end, write_end; + file::pipe(read_end, write_end); + close_count = 1; + EXPECT_SYSTEM_ERROR(read_end.close(), EINTR, "cannot close file"); + EXPECT_EQ(2, close_count); + close_count = 0; +} + +TEST(FileTest, Size) { + std::string content = "top secret, destroy before reading"; + write_file("temp", content); + file f("temp", file::RDONLY); + EXPECT_GE(f.size(), 0); + EXPECT_EQ(content.size(), static_cast<unsigned long long>(f.size())); +# ifdef _WIN32 + fmt::memory_buffer message; fmt::detail::format_windows_error(message, ERROR_ACCESS_DENIED, "cannot get file size"); - fstat_sim = ERROR; - EXPECT_THROW_MSG(f.size(), fmt::windows_error, fmt::to_string(message)); - fstat_sim = NONE; -# else - f.close(); - EXPECT_SYSTEM_ERROR(f.size(), EBADF, "cannot get file attributes"); -# endif -} - -TEST(FileTest, MaxSize) { - write_file("temp", ""); - file f("temp", file::RDONLY); - fstat_sim = MAX_SIZE; - EXPECT_GE(f.size(), 0); - EXPECT_EQ(max_file_size(), f.size()); - fstat_sim = NONE; -} - -TEST(FileTest, ReadRetry) { - file read_end, write_end; - file::pipe(read_end, write_end); - enum { SIZE = 4 }; - write_end.write("test", SIZE); - write_end.close(); - char buffer[SIZE]; + fstat_sim = ERROR; + EXPECT_THROW_MSG(f.size(), fmt::windows_error, fmt::to_string(message)); + fstat_sim = NONE; +# else + f.close(); + EXPECT_SYSTEM_ERROR(f.size(), EBADF, "cannot get file attributes"); +# endif +} + +TEST(FileTest, MaxSize) { + write_file("temp", ""); + file f("temp", file::RDONLY); + fstat_sim = MAX_SIZE; + EXPECT_GE(f.size(), 0); + EXPECT_EQ(max_file_size(), f.size()); + fstat_sim = NONE; +} + +TEST(FileTest, ReadRetry) { + file read_end, write_end; + file::pipe(read_end, write_end); + enum { SIZE = 4 }; + write_end.write("test", SIZE); + write_end.close(); + char buffer[SIZE]; size_t count = 0; - EXPECT_RETRY(count = read_end.read(buffer, SIZE), read, - "cannot read from file"); - EXPECT_EQ_POSIX(static_cast<std::streamsize>(SIZE), count); -} - -TEST(FileTest, WriteRetry) { - file read_end, write_end; - file::pipe(read_end, write_end); - enum { SIZE = 4 }; + EXPECT_RETRY(count = read_end.read(buffer, SIZE), read, + "cannot read from file"); + EXPECT_EQ_POSIX(static_cast<std::streamsize>(SIZE), count); +} + +TEST(FileTest, WriteRetry) { + file read_end, write_end; + file::pipe(read_end, write_end); + enum { SIZE = 4 }; size_t count = 0; - EXPECT_RETRY(count = write_end.write("test", SIZE), write, - "cannot write to file"); - write_end.close(); -# ifndef _WIN32 - EXPECT_EQ(static_cast<std::streamsize>(SIZE), count); - char buffer[SIZE + 1]; - read_end.read(buffer, SIZE); - buffer[SIZE] = '\0'; - EXPECT_STREQ("test", buffer); -# endif -} - -# ifdef _WIN32 -TEST(FileTest, ConvertReadCount) { - file read_end, write_end; - file::pipe(read_end, write_end); - char c; + EXPECT_RETRY(count = write_end.write("test", SIZE), write, + "cannot write to file"); + write_end.close(); +# ifndef _WIN32 + EXPECT_EQ(static_cast<std::streamsize>(SIZE), count); + char buffer[SIZE + 1]; + read_end.read(buffer, SIZE); + buffer[SIZE] = '\0'; + EXPECT_STREQ("test", buffer); +# endif +} + +# ifdef _WIN32 +TEST(FileTest, ConvertReadCount) { + file read_end, write_end; + file::pipe(read_end, write_end); + char c; size_t size = UINT_MAX; if (sizeof(unsigned) != sizeof(size_t)) ++size; - read_count = 1; - read_nbyte = 0; - EXPECT_THROW(read_end.read(&c, size), fmt::system_error); - read_count = 0; - EXPECT_EQ(UINT_MAX, read_nbyte); -} - -TEST(FileTest, ConvertWriteCount) { - file read_end, write_end; - file::pipe(read_end, write_end); - char c; + read_count = 1; + read_nbyte = 0; + EXPECT_THROW(read_end.read(&c, size), fmt::system_error); + read_count = 0; + EXPECT_EQ(UINT_MAX, read_nbyte); +} + +TEST(FileTest, ConvertWriteCount) { + file read_end, write_end; + file::pipe(read_end, write_end); + char c; size_t size = UINT_MAX; if (sizeof(unsigned) != sizeof(size_t)) ++size; - write_count = 1; - write_nbyte = 0; - EXPECT_THROW(write_end.write(&c, size), fmt::system_error); - write_count = 0; - EXPECT_EQ(UINT_MAX, write_nbyte); -} -# endif - -TEST(FileTest, DupNoRetry) { - int stdout_fd = FMT_POSIX(fileno(stdout)); - dup_count = 1; - EXPECT_SYSTEM_ERROR( - file::dup(stdout_fd), EINTR, - fmt::format("cannot duplicate file descriptor {}", stdout_fd)); - dup_count = 0; -} - -TEST(FileTest, Dup2Retry) { - int stdout_fd = FMT_POSIX(fileno(stdout)); - file f1 = file::dup(stdout_fd), f2 = file::dup(stdout_fd); - EXPECT_RETRY(f1.dup2(f2.descriptor()), dup2, - fmt::format("cannot duplicate file descriptor {} to {}", - f1.descriptor(), f2.descriptor())); -} - -TEST(FileTest, Dup2NoExceptRetry) { - int stdout_fd = FMT_POSIX(fileno(stdout)); - file f1 = file::dup(stdout_fd), f2 = file::dup(stdout_fd); - error_code ec; - dup2_count = 1; - f1.dup2(f2.descriptor(), ec); -# ifndef _WIN32 - EXPECT_EQ(4, dup2_count); -# else - EXPECT_EQ(EINTR, ec.get()); -# endif - dup2_count = 0; -} - -TEST(FileTest, PipeNoRetry) { - file read_end, write_end; - pipe_count = 1; - EXPECT_SYSTEM_ERROR(file::pipe(read_end, write_end), EINTR, - "cannot create pipe"); - pipe_count = 0; -} - -TEST(FileTest, FdopenNoRetry) { - file read_end, write_end; - file::pipe(read_end, write_end); - fdopen_count = 1; - EXPECT_SYSTEM_ERROR(read_end.fdopen("r"), EINTR, - "cannot associate stream with file descriptor"); - fdopen_count = 0; -} - -TEST(BufferedFileTest, OpenRetry) { - write_file("temp", "there must be something here"); - std::unique_ptr<buffered_file> f{nullptr}; - EXPECT_RETRY(f.reset(new buffered_file("temp", "r")), fopen, - "cannot open file temp"); -# ifndef _WIN32 - char c = 0; - if (fread(&c, 1, 1, f->get()) < 1) - throw fmt::system_error(errno, "fread failed"); -# endif -} - -TEST(BufferedFileTest, CloseNoRetryInDtor) { - file read_end, write_end; - file::pipe(read_end, write_end); - std::unique_ptr<buffered_file> f(new buffered_file(read_end.fdopen("r"))); - int saved_fclose_count = 0; - EXPECT_WRITE( - stderr, - { - fclose_count = 1; - f.reset(nullptr); - saved_fclose_count = fclose_count; - fclose_count = 0; - }, - format_system_error(EINTR, "cannot close file") + "\n"); - EXPECT_EQ(2, saved_fclose_count); -} - -TEST(BufferedFileTest, CloseNoRetry) { - file read_end, write_end; - file::pipe(read_end, write_end); - buffered_file f = read_end.fdopen("r"); - fclose_count = 1; - EXPECT_SYSTEM_ERROR(f.close(), EINTR, "cannot close file"); - EXPECT_EQ(2, fclose_count); - fclose_count = 0; -} - -TEST(BufferedFileTest, FilenoNoRetry) { - file read_end, write_end; - file::pipe(read_end, write_end); - buffered_file f = read_end.fdopen("r"); - fileno_count = 1; - EXPECT_SYSTEM_ERROR((f.fileno)(), EINTR, "cannot get file descriptor"); - EXPECT_EQ(2, fileno_count); - fileno_count = 0; -} -#endif // FMT_USE_FCNTL - -struct test_mock { - static test_mock* instance; -} * test_mock::instance; - -TEST(ScopedMock, Scope) { - { - ScopedMock<test_mock> mock; - EXPECT_EQ(&mock, test_mock::instance); - test_mock& copy = mock; - static_cast<void>(copy); - } - EXPECT_EQ(nullptr, test_mock::instance); -} - -#if defined(FMT_LOCALE) && !defined(_LIBCPP_VERSION) - -typedef fmt::locale::type locale_type; - -struct locale_mock { - static locale_mock* instance; - MOCK_METHOD3(newlocale, locale_type(int category_mask, const char* locale, - locale_type base)); - MOCK_METHOD1(freelocale, void(locale_type locale)); - - MOCK_METHOD3(strtod_l, - double(const char* nptr, char** endptr, locale_type locale)); -} * locale_mock::instance; - -# ifdef _MSC_VER -# pragma warning(push) -# pragma warning(disable : 4273) -# ifdef __clang__ -# pragma clang diagnostic push -# pragma clang diagnostic ignored "-Winconsistent-dllimport" -# endif - -_locale_t _create_locale(int category, const char* locale) { - return locale_mock::instance->newlocale(category, locale, 0); -} - -void _free_locale(_locale_t locale) { - locale_mock::instance->freelocale(locale); -} - -double _strtod_l(const char* nptr, char** endptr, _locale_t locale) { - return locale_mock::instance->strtod_l(nptr, endptr, locale); -} -# ifdef __clang__ -# pragma clang diagnostic pop -# endif -# pragma warning(pop) -# endif - -# if defined(__THROW) && FMT_GCC_VERSION > 0 && FMT_GCC_VERSION <= 408 -# define FMT_LOCALE_THROW __THROW -# else -# define FMT_LOCALE_THROW -# endif - -# if defined(__APPLE__) || \ - (defined(__FreeBSD__) && __FreeBSD_version < 1200002) -typedef int FreeLocaleResult; -# else -typedef void FreeLocaleResult; -# endif - -FreeLocaleResult freelocale(locale_type locale) FMT_LOCALE_THROW { - locale_mock::instance->freelocale(locale); - return FreeLocaleResult(); -} - -double strtod_l(const char* nptr, char** endptr, - locale_type locale) FMT_LOCALE_THROW { - return locale_mock::instance->strtod_l(nptr, endptr, locale); -} - -# undef FMT_LOCALE_THROW - -# if !defined(_WIN32) || defined(_LIBCPP_VERSION) -locale_t test::newlocale(int category_mask, const char* locale, locale_t base) { - return locale_mock::instance->newlocale(category_mask, locale, base); -} - -TEST(LocaleTest, LocaleMock) { - ScopedMock<locale_mock> mock; - locale_type locale = reinterpret_cast<locale_type>(11); - EXPECT_CALL(mock, newlocale(222, StrEq("foo"), locale)); - FMT_SYSTEM(newlocale(222, "foo", locale)); -} -# endif - -TEST(LocaleTest, Locale) { -# ifndef LC_NUMERIC_MASK - enum { LC_NUMERIC_MASK = LC_NUMERIC }; -# endif - ScopedMock<locale_mock> mock; - locale_type impl = reinterpret_cast<locale_type>(42); - EXPECT_CALL(mock, newlocale(LC_NUMERIC_MASK, StrEq("C"), nullptr)) - .WillOnce(Return(impl)); - EXPECT_CALL(mock, freelocale(impl)); - fmt::locale loc; - EXPECT_EQ(impl, loc.get()); -} - -TEST(LocaleTest, Strtod) { - ScopedMock<locale_mock> mock; - EXPECT_CALL(mock, newlocale(_, _, _)) - .WillOnce(Return(reinterpret_cast<locale_type>(42))); - EXPECT_CALL(mock, freelocale(_)); - fmt::locale loc; - const char* str = "4.2"; - char end = 'x'; - EXPECT_CALL(mock, strtod_l(str, _, loc.get())) - .WillOnce(testing::DoAll(testing::SetArgPointee<1>(&end), Return(777))); - EXPECT_EQ(777, loc.strtod(str)); - EXPECT_EQ(&end, str); -} - -#endif // FMT_LOCALE + write_count = 1; + write_nbyte = 0; + EXPECT_THROW(write_end.write(&c, size), fmt::system_error); + write_count = 0; + EXPECT_EQ(UINT_MAX, write_nbyte); +} +# endif + +TEST(FileTest, DupNoRetry) { + int stdout_fd = FMT_POSIX(fileno(stdout)); + dup_count = 1; + EXPECT_SYSTEM_ERROR( + file::dup(stdout_fd), EINTR, + fmt::format("cannot duplicate file descriptor {}", stdout_fd)); + dup_count = 0; +} + +TEST(FileTest, Dup2Retry) { + int stdout_fd = FMT_POSIX(fileno(stdout)); + file f1 = file::dup(stdout_fd), f2 = file::dup(stdout_fd); + EXPECT_RETRY(f1.dup2(f2.descriptor()), dup2, + fmt::format("cannot duplicate file descriptor {} to {}", + f1.descriptor(), f2.descriptor())); +} + +TEST(FileTest, Dup2NoExceptRetry) { + int stdout_fd = FMT_POSIX(fileno(stdout)); + file f1 = file::dup(stdout_fd), f2 = file::dup(stdout_fd); + error_code ec; + dup2_count = 1; + f1.dup2(f2.descriptor(), ec); +# ifndef _WIN32 + EXPECT_EQ(4, dup2_count); +# else + EXPECT_EQ(EINTR, ec.get()); +# endif + dup2_count = 0; +} + +TEST(FileTest, PipeNoRetry) { + file read_end, write_end; + pipe_count = 1; + EXPECT_SYSTEM_ERROR(file::pipe(read_end, write_end), EINTR, + "cannot create pipe"); + pipe_count = 0; +} + +TEST(FileTest, FdopenNoRetry) { + file read_end, write_end; + file::pipe(read_end, write_end); + fdopen_count = 1; + EXPECT_SYSTEM_ERROR(read_end.fdopen("r"), EINTR, + "cannot associate stream with file descriptor"); + fdopen_count = 0; +} + +TEST(BufferedFileTest, OpenRetry) { + write_file("temp", "there must be something here"); + std::unique_ptr<buffered_file> f{nullptr}; + EXPECT_RETRY(f.reset(new buffered_file("temp", "r")), fopen, + "cannot open file temp"); +# ifndef _WIN32 + char c = 0; + if (fread(&c, 1, 1, f->get()) < 1) + throw fmt::system_error(errno, "fread failed"); +# endif +} + +TEST(BufferedFileTest, CloseNoRetryInDtor) { + file read_end, write_end; + file::pipe(read_end, write_end); + std::unique_ptr<buffered_file> f(new buffered_file(read_end.fdopen("r"))); + int saved_fclose_count = 0; + EXPECT_WRITE( + stderr, + { + fclose_count = 1; + f.reset(nullptr); + saved_fclose_count = fclose_count; + fclose_count = 0; + }, + format_system_error(EINTR, "cannot close file") + "\n"); + EXPECT_EQ(2, saved_fclose_count); +} + +TEST(BufferedFileTest, CloseNoRetry) { + file read_end, write_end; + file::pipe(read_end, write_end); + buffered_file f = read_end.fdopen("r"); + fclose_count = 1; + EXPECT_SYSTEM_ERROR(f.close(), EINTR, "cannot close file"); + EXPECT_EQ(2, fclose_count); + fclose_count = 0; +} + +TEST(BufferedFileTest, FilenoNoRetry) { + file read_end, write_end; + file::pipe(read_end, write_end); + buffered_file f = read_end.fdopen("r"); + fileno_count = 1; + EXPECT_SYSTEM_ERROR((f.fileno)(), EINTR, "cannot get file descriptor"); + EXPECT_EQ(2, fileno_count); + fileno_count = 0; +} +#endif // FMT_USE_FCNTL + +struct test_mock { + static test_mock* instance; +} * test_mock::instance; + +TEST(ScopedMock, Scope) { + { + ScopedMock<test_mock> mock; + EXPECT_EQ(&mock, test_mock::instance); + test_mock& copy = mock; + static_cast<void>(copy); + } + EXPECT_EQ(nullptr, test_mock::instance); +} + +#if defined(FMT_LOCALE) && !defined(_LIBCPP_VERSION) + +typedef fmt::locale::type locale_type; + +struct locale_mock { + static locale_mock* instance; + MOCK_METHOD3(newlocale, locale_type(int category_mask, const char* locale, + locale_type base)); + MOCK_METHOD1(freelocale, void(locale_type locale)); + + MOCK_METHOD3(strtod_l, + double(const char* nptr, char** endptr, locale_type locale)); +} * locale_mock::instance; + +# ifdef _MSC_VER +# pragma warning(push) +# pragma warning(disable : 4273) +# ifdef __clang__ +# pragma clang diagnostic push +# pragma clang diagnostic ignored "-Winconsistent-dllimport" +# endif + +_locale_t _create_locale(int category, const char* locale) { + return locale_mock::instance->newlocale(category, locale, 0); +} + +void _free_locale(_locale_t locale) { + locale_mock::instance->freelocale(locale); +} + +double _strtod_l(const char* nptr, char** endptr, _locale_t locale) { + return locale_mock::instance->strtod_l(nptr, endptr, locale); +} +# ifdef __clang__ +# pragma clang diagnostic pop +# endif +# pragma warning(pop) +# endif + +# if defined(__THROW) && FMT_GCC_VERSION > 0 && FMT_GCC_VERSION <= 408 +# define FMT_LOCALE_THROW __THROW +# else +# define FMT_LOCALE_THROW +# endif + +# if defined(__APPLE__) || \ + (defined(__FreeBSD__) && __FreeBSD_version < 1200002) +typedef int FreeLocaleResult; +# else +typedef void FreeLocaleResult; +# endif + +FreeLocaleResult freelocale(locale_type locale) FMT_LOCALE_THROW { + locale_mock::instance->freelocale(locale); + return FreeLocaleResult(); +} + +double strtod_l(const char* nptr, char** endptr, + locale_type locale) FMT_LOCALE_THROW { + return locale_mock::instance->strtod_l(nptr, endptr, locale); +} + +# undef FMT_LOCALE_THROW + +# if !defined(_WIN32) || defined(_LIBCPP_VERSION) +locale_t test::newlocale(int category_mask, const char* locale, locale_t base) { + return locale_mock::instance->newlocale(category_mask, locale, base); +} + +TEST(LocaleTest, LocaleMock) { + ScopedMock<locale_mock> mock; + locale_type locale = reinterpret_cast<locale_type>(11); + EXPECT_CALL(mock, newlocale(222, StrEq("foo"), locale)); + FMT_SYSTEM(newlocale(222, "foo", locale)); +} +# endif + +TEST(LocaleTest, Locale) { +# ifndef LC_NUMERIC_MASK + enum { LC_NUMERIC_MASK = LC_NUMERIC }; +# endif + ScopedMock<locale_mock> mock; + locale_type impl = reinterpret_cast<locale_type>(42); + EXPECT_CALL(mock, newlocale(LC_NUMERIC_MASK, StrEq("C"), nullptr)) + .WillOnce(Return(impl)); + EXPECT_CALL(mock, freelocale(impl)); + fmt::locale loc; + EXPECT_EQ(impl, loc.get()); +} + +TEST(LocaleTest, Strtod) { + ScopedMock<locale_mock> mock; + EXPECT_CALL(mock, newlocale(_, _, _)) + .WillOnce(Return(reinterpret_cast<locale_type>(42))); + EXPECT_CALL(mock, freelocale(_)); + fmt::locale loc; + const char* str = "4.2"; + char end = 'x'; + EXPECT_CALL(mock, strtod_l(str, _, loc.get())) + .WillOnce(testing::DoAll(testing::SetArgPointee<1>(&end), Return(777))); + EXPECT_EQ(777, loc.strtod(str)); + EXPECT_EQ(&end, str); +} + +#endif // FMT_LOCALE diff --git a/contrib/libs/fmt/test/posix-mock-test/ya.make b/contrib/libs/fmt/test/posix-mock-test/ya.make index 1da082bd78..d1a55e5200 100644 --- a/contrib/libs/fmt/test/posix-mock-test/ya.make +++ b/contrib/libs/fmt/test/posix-mock-test/ya.make @@ -1,38 +1,38 @@ -# Generated by devtools/yamaker. - +# Generated by devtools/yamaker. + GTEST() - + WITHOUT_LICENSE_TEXTS() - + OWNER( orivej g:cpp-contrib ) -LICENSE(MIT) - +LICENSE(MIT) + ADDINCL( contrib/libs/fmt/include ) - -NO_COMPILER_WARNINGS() - -NO_UTIL() - -CFLAGS( - -DFMT_LOCALE - -DGTEST_HAS_STD_WSTRING=1 - -DGTEST_LANG_CXX11=0 - -D_SILENCE_TR1_NAMESPACE_DEPRECATION_WARNING=1 -) - -SRCDIR(contrib/libs/fmt) - -SRCS( - src/format.cc - test/gtest-extra.cc - test/posix-mock-test.cc - test/util.cc -) - -END() + +NO_COMPILER_WARNINGS() + +NO_UTIL() + +CFLAGS( + -DFMT_LOCALE + -DGTEST_HAS_STD_WSTRING=1 + -DGTEST_LANG_CXX11=0 + -D_SILENCE_TR1_NAMESPACE_DEPRECATION_WARNING=1 +) + +SRCDIR(contrib/libs/fmt) + +SRCS( + src/format.cc + test/gtest-extra.cc + test/posix-mock-test.cc + test/util.cc +) + +END() diff --git a/contrib/libs/fmt/test/posix-mock.h b/contrib/libs/fmt/test/posix-mock.h index 22f305cbf7..1f204263c6 100644 --- a/contrib/libs/fmt/test/posix-mock.h +++ b/contrib/libs/fmt/test/posix-mock.h @@ -1,78 +1,78 @@ -// Formatting library for C++ - mocks of POSIX functions -// -// Copyright (c) 2012 - present, Victor Zverovich -// All rights reserved. -// -// For the license information refer to format.h. - -#ifndef FMT_POSIX_TEST_H -#define FMT_POSIX_TEST_H - -#include <errno.h> -#include <locale.h> -#include <stdio.h> -#ifdef __APPLE__ -# include <xlocale.h> -#endif - -#ifdef _WIN32 -# include <windows.h> -# include <locale> // for libc++ locale_win32.h -#else -# include <sys/param.h> // for FreeBSD version -# include <sys/types.h> // for ssize_t -#endif - -#ifndef _MSC_VER -struct stat; -#endif - -namespace test { - -#ifndef _MSC_VER -// Size type for read and write. -typedef size_t size_t; -typedef ssize_t ssize_t; -int open(const char* path, int oflag, int mode); -int fstat(int fd, struct stat* buf); -#else -typedef unsigned size_t; -typedef int ssize_t; -errno_t sopen_s(int* pfh, const char* filename, int oflag, int shflag, - int pmode); -#endif - -#ifndef _WIN32 -long sysconf(int name); -#else -DWORD GetFileSize(HANDLE hFile, LPDWORD lpFileSizeHigh); -#endif - -int close(int fildes); - -int dup(int fildes); -int dup2(int fildes, int fildes2); - -FILE* fdopen(int fildes, const char* mode); - -ssize_t read(int fildes, void* buf, size_t nbyte); -ssize_t write(int fildes, const void* buf, size_t nbyte); - -#ifndef _WIN32 -int pipe(int fildes[2]); -#else -int pipe(int* pfds, unsigned psize, int textmode); -#endif - -FILE* fopen(const char* filename, const char* mode); -int fclose(FILE* stream); -int(fileno)(FILE* stream); - -#if defined(FMT_LOCALE) && (!defined(_WIN32) || defined(_LIBCPP_VERSION)) -locale_t newlocale(int category_mask, const char* locale, locale_t base); -#endif -} // namespace test - -#define FMT_SYSTEM(call) test::call - -#endif // FMT_POSIX_TEST_H +// Formatting library for C++ - mocks of POSIX functions +// +// Copyright (c) 2012 - present, Victor Zverovich +// All rights reserved. +// +// For the license information refer to format.h. + +#ifndef FMT_POSIX_TEST_H +#define FMT_POSIX_TEST_H + +#include <errno.h> +#include <locale.h> +#include <stdio.h> +#ifdef __APPLE__ +# include <xlocale.h> +#endif + +#ifdef _WIN32 +# include <windows.h> +# include <locale> // for libc++ locale_win32.h +#else +# include <sys/param.h> // for FreeBSD version +# include <sys/types.h> // for ssize_t +#endif + +#ifndef _MSC_VER +struct stat; +#endif + +namespace test { + +#ifndef _MSC_VER +// Size type for read and write. +typedef size_t size_t; +typedef ssize_t ssize_t; +int open(const char* path, int oflag, int mode); +int fstat(int fd, struct stat* buf); +#else +typedef unsigned size_t; +typedef int ssize_t; +errno_t sopen_s(int* pfh, const char* filename, int oflag, int shflag, + int pmode); +#endif + +#ifndef _WIN32 +long sysconf(int name); +#else +DWORD GetFileSize(HANDLE hFile, LPDWORD lpFileSizeHigh); +#endif + +int close(int fildes); + +int dup(int fildes); +int dup2(int fildes, int fildes2); + +FILE* fdopen(int fildes, const char* mode); + +ssize_t read(int fildes, void* buf, size_t nbyte); +ssize_t write(int fildes, const void* buf, size_t nbyte); + +#ifndef _WIN32 +int pipe(int fildes[2]); +#else +int pipe(int* pfds, unsigned psize, int textmode); +#endif + +FILE* fopen(const char* filename, const char* mode); +int fclose(FILE* stream); +int(fileno)(FILE* stream); + +#if defined(FMT_LOCALE) && (!defined(_WIN32) || defined(_LIBCPP_VERSION)) +locale_t newlocale(int category_mask, const char* locale, locale_t base); +#endif +} // namespace test + +#define FMT_SYSTEM(call) test::call + +#endif // FMT_POSIX_TEST_H diff --git a/contrib/libs/fmt/test/printf-test.cc b/contrib/libs/fmt/test/printf-test.cc index c9e1dfa6a2..ccd72dcd75 100644 --- a/contrib/libs/fmt/test/printf-test.cc +++ b/contrib/libs/fmt/test/printf-test.cc @@ -1,159 +1,159 @@ -// Formatting library for C++ - printf tests -// -// Copyright (c) 2012 - present, Victor Zverovich -// All rights reserved. -// -// For the license information refer to format.h. - -#include "fmt/printf.h" - -#include <cctype> -#include <climits> -#include <cstring> - -#include "fmt/core.h" -#include "gtest-extra.h" -#include "util.h" - -using fmt::format; -using fmt::format_error; +// Formatting library for C++ - printf tests +// +// Copyright (c) 2012 - present, Victor Zverovich +// All rights reserved. +// +// For the license information refer to format.h. + +#include "fmt/printf.h" + +#include <cctype> +#include <climits> +#include <cstring> + +#include "fmt/core.h" +#include "gtest-extra.h" +#include "util.h" + +using fmt::format; +using fmt::format_error; using fmt::detail::max_value; - -const unsigned BIG_NUM = INT_MAX + 1u; - -// Makes format string argument positional. -static std::string make_positional(fmt::string_view format) { - std::string s(format.data(), format.size()); - s.replace(s.find('%'), 1, "%1$"); - return s; -} - -static std::wstring make_positional(fmt::wstring_view format) { - std::wstring s(format.data(), format.size()); - s.replace(s.find(L'%'), 1, L"%1$"); - return s; -} - -// A wrapper around fmt::sprintf to workaround bogus warnings about invalid -// format strings in MSVC. -template <typename... Args> -std::string test_sprintf(fmt::string_view format, const Args&... args) { - return fmt::sprintf(format, args...); -} -template <typename... Args> -std::wstring test_sprintf(fmt::wstring_view format, const Args&... args) { - return fmt::sprintf(format, args...); -} - -#define EXPECT_PRINTF(expected_output, format, arg) \ - EXPECT_EQ(expected_output, test_sprintf(format, arg)) \ - << "format: " << format; \ - EXPECT_EQ(expected_output, fmt::sprintf(make_positional(format), arg)) - -TEST(PrintfTest, NoArgs) { - EXPECT_EQ("test", test_sprintf("test")); - EXPECT_EQ(L"test", fmt::sprintf(L"test")); -} - -TEST(PrintfTest, Escape) { - EXPECT_EQ("%", test_sprintf("%%")); - EXPECT_EQ("before %", test_sprintf("before %%")); - EXPECT_EQ("% after", test_sprintf("%% after")); - EXPECT_EQ("before % after", test_sprintf("before %% after")); - EXPECT_EQ("%s", test_sprintf("%%s")); - EXPECT_EQ(L"%", fmt::sprintf(L"%%")); - EXPECT_EQ(L"before %", fmt::sprintf(L"before %%")); - EXPECT_EQ(L"% after", fmt::sprintf(L"%% after")); - EXPECT_EQ(L"before % after", fmt::sprintf(L"before %% after")); - EXPECT_EQ(L"%s", fmt::sprintf(L"%%s")); -} - -TEST(PrintfTest, PositionalArgs) { - EXPECT_EQ("42", test_sprintf("%1$d", 42)); - EXPECT_EQ("before 42", test_sprintf("before %1$d", 42)); - EXPECT_EQ("42 after", test_sprintf("%1$d after", 42)); - EXPECT_EQ("before 42 after", test_sprintf("before %1$d after", 42)); - EXPECT_EQ("answer = 42", test_sprintf("%1$s = %2$d", "answer", 42)); - EXPECT_EQ("42 is the answer", test_sprintf("%2$d is the %1$s", "answer", 42)); - EXPECT_EQ("abracadabra", test_sprintf("%1$s%2$s%1$s", "abra", "cad")); -} - -TEST(PrintfTest, AutomaticArgIndexing) { - EXPECT_EQ("abc", test_sprintf("%c%c%c", 'a', 'b', 'c')); -} - -TEST(PrintfTest, NumberIsTooBigInArgIndex) { - EXPECT_THROW_MSG(test_sprintf(format("%{}$", BIG_NUM)), format_error, - "number is too big"); - EXPECT_THROW_MSG(test_sprintf(format("%{}$d", BIG_NUM)), format_error, - "number is too big"); -} - -TEST(PrintfTest, SwitchArgIndexing) { - EXPECT_THROW_MSG(test_sprintf("%1$d%", 1, 2), format_error, - "cannot switch from manual to automatic argument indexing"); - EXPECT_THROW_MSG(test_sprintf(format("%1$d%{}d", BIG_NUM), 1, 2), - format_error, "number is too big"); - EXPECT_THROW_MSG(test_sprintf("%1$d%d", 1, 2), format_error, - "cannot switch from manual to automatic argument indexing"); - - EXPECT_THROW_MSG(test_sprintf("%d%1$", 1, 2), format_error, - "cannot switch from automatic to manual argument indexing"); - EXPECT_THROW_MSG(test_sprintf(format("%d%{}$d", BIG_NUM), 1, 2), format_error, - "number is too big"); - EXPECT_THROW_MSG(test_sprintf("%d%1$d", 1, 2), format_error, - "cannot switch from automatic to manual argument indexing"); - - // Indexing errors override width errors. - EXPECT_THROW_MSG(test_sprintf(format("%d%1${}d", BIG_NUM), 1, 2), - format_error, "number is too big"); - EXPECT_THROW_MSG(test_sprintf(format("%1$d%{}d", BIG_NUM), 1, 2), - format_error, "number is too big"); -} - -TEST(PrintfTest, InvalidArgIndex) { - EXPECT_THROW_MSG(test_sprintf("%0$d", 42), format_error, + +const unsigned BIG_NUM = INT_MAX + 1u; + +// Makes format string argument positional. +static std::string make_positional(fmt::string_view format) { + std::string s(format.data(), format.size()); + s.replace(s.find('%'), 1, "%1$"); + return s; +} + +static std::wstring make_positional(fmt::wstring_view format) { + std::wstring s(format.data(), format.size()); + s.replace(s.find(L'%'), 1, L"%1$"); + return s; +} + +// A wrapper around fmt::sprintf to workaround bogus warnings about invalid +// format strings in MSVC. +template <typename... Args> +std::string test_sprintf(fmt::string_view format, const Args&... args) { + return fmt::sprintf(format, args...); +} +template <typename... Args> +std::wstring test_sprintf(fmt::wstring_view format, const Args&... args) { + return fmt::sprintf(format, args...); +} + +#define EXPECT_PRINTF(expected_output, format, arg) \ + EXPECT_EQ(expected_output, test_sprintf(format, arg)) \ + << "format: " << format; \ + EXPECT_EQ(expected_output, fmt::sprintf(make_positional(format), arg)) + +TEST(PrintfTest, NoArgs) { + EXPECT_EQ("test", test_sprintf("test")); + EXPECT_EQ(L"test", fmt::sprintf(L"test")); +} + +TEST(PrintfTest, Escape) { + EXPECT_EQ("%", test_sprintf("%%")); + EXPECT_EQ("before %", test_sprintf("before %%")); + EXPECT_EQ("% after", test_sprintf("%% after")); + EXPECT_EQ("before % after", test_sprintf("before %% after")); + EXPECT_EQ("%s", test_sprintf("%%s")); + EXPECT_EQ(L"%", fmt::sprintf(L"%%")); + EXPECT_EQ(L"before %", fmt::sprintf(L"before %%")); + EXPECT_EQ(L"% after", fmt::sprintf(L"%% after")); + EXPECT_EQ(L"before % after", fmt::sprintf(L"before %% after")); + EXPECT_EQ(L"%s", fmt::sprintf(L"%%s")); +} + +TEST(PrintfTest, PositionalArgs) { + EXPECT_EQ("42", test_sprintf("%1$d", 42)); + EXPECT_EQ("before 42", test_sprintf("before %1$d", 42)); + EXPECT_EQ("42 after", test_sprintf("%1$d after", 42)); + EXPECT_EQ("before 42 after", test_sprintf("before %1$d after", 42)); + EXPECT_EQ("answer = 42", test_sprintf("%1$s = %2$d", "answer", 42)); + EXPECT_EQ("42 is the answer", test_sprintf("%2$d is the %1$s", "answer", 42)); + EXPECT_EQ("abracadabra", test_sprintf("%1$s%2$s%1$s", "abra", "cad")); +} + +TEST(PrintfTest, AutomaticArgIndexing) { + EXPECT_EQ("abc", test_sprintf("%c%c%c", 'a', 'b', 'c')); +} + +TEST(PrintfTest, NumberIsTooBigInArgIndex) { + EXPECT_THROW_MSG(test_sprintf(format("%{}$", BIG_NUM)), format_error, + "number is too big"); + EXPECT_THROW_MSG(test_sprintf(format("%{}$d", BIG_NUM)), format_error, + "number is too big"); +} + +TEST(PrintfTest, SwitchArgIndexing) { + EXPECT_THROW_MSG(test_sprintf("%1$d%", 1, 2), format_error, + "cannot switch from manual to automatic argument indexing"); + EXPECT_THROW_MSG(test_sprintf(format("%1$d%{}d", BIG_NUM), 1, 2), + format_error, "number is too big"); + EXPECT_THROW_MSG(test_sprintf("%1$d%d", 1, 2), format_error, + "cannot switch from manual to automatic argument indexing"); + + EXPECT_THROW_MSG(test_sprintf("%d%1$", 1, 2), format_error, + "cannot switch from automatic to manual argument indexing"); + EXPECT_THROW_MSG(test_sprintf(format("%d%{}$d", BIG_NUM), 1, 2), format_error, + "number is too big"); + EXPECT_THROW_MSG(test_sprintf("%d%1$d", 1, 2), format_error, + "cannot switch from automatic to manual argument indexing"); + + // Indexing errors override width errors. + EXPECT_THROW_MSG(test_sprintf(format("%d%1${}d", BIG_NUM), 1, 2), + format_error, "number is too big"); + EXPECT_THROW_MSG(test_sprintf(format("%1$d%{}d", BIG_NUM), 1, 2), + format_error, "number is too big"); +} + +TEST(PrintfTest, InvalidArgIndex) { + EXPECT_THROW_MSG(test_sprintf("%0$d", 42), format_error, "argument not found"); - EXPECT_THROW_MSG(test_sprintf("%2$d", 42), format_error, + EXPECT_THROW_MSG(test_sprintf("%2$d", 42), format_error, "argument not found"); - EXPECT_THROW_MSG(test_sprintf(format("%{}$d", INT_MAX), 42), format_error, + EXPECT_THROW_MSG(test_sprintf(format("%{}$d", INT_MAX), 42), format_error, "argument not found"); - + EXPECT_THROW_MSG(test_sprintf("%2$", 42), format_error, "argument not found"); - EXPECT_THROW_MSG(test_sprintf(format("%{}$d", BIG_NUM), 42), format_error, - "number is too big"); -} - -TEST(PrintfTest, DefaultAlignRight) { - EXPECT_PRINTF(" 42", "%5d", 42); - EXPECT_PRINTF(" abc", "%5s", "abc"); -} - -TEST(PrintfTest, ZeroFlag) { - EXPECT_PRINTF("00042", "%05d", 42); - EXPECT_PRINTF("-0042", "%05d", -42); - - EXPECT_PRINTF("00042", "%05d", 42); - EXPECT_PRINTF("-0042", "%05d", -42); - EXPECT_PRINTF("-004.2", "%06g", -4.2); - - EXPECT_PRINTF("+00042", "%00+6d", 42); - + EXPECT_THROW_MSG(test_sprintf(format("%{}$d", BIG_NUM), 42), format_error, + "number is too big"); +} + +TEST(PrintfTest, DefaultAlignRight) { + EXPECT_PRINTF(" 42", "%5d", 42); + EXPECT_PRINTF(" abc", "%5s", "abc"); +} + +TEST(PrintfTest, ZeroFlag) { + EXPECT_PRINTF("00042", "%05d", 42); + EXPECT_PRINTF("-0042", "%05d", -42); + + EXPECT_PRINTF("00042", "%05d", 42); + EXPECT_PRINTF("-0042", "%05d", -42); + EXPECT_PRINTF("-004.2", "%06g", -4.2); + + EXPECT_PRINTF("+00042", "%00+6d", 42); + EXPECT_PRINTF(" 42", "%05.d", 42); EXPECT_PRINTF(" 0042", "%05.4d", 42); - // '0' flag is ignored for non-numeric types. + // '0' flag is ignored for non-numeric types. EXPECT_PRINTF(" x", "%05c", 'x'); -} - -TEST(PrintfTest, PlusFlag) { - EXPECT_PRINTF("+42", "%+d", 42); - EXPECT_PRINTF("-42", "%+d", -42); - EXPECT_PRINTF("+0042", "%+05d", 42); - EXPECT_PRINTF("+0042", "%0++5d", 42); - - // '+' flag is ignored for non-numeric types. - EXPECT_PRINTF("x", "%+c", 'x'); +} + +TEST(PrintfTest, PlusFlag) { + EXPECT_PRINTF("+42", "%+d", 42); + EXPECT_PRINTF("-42", "%+d", -42); + EXPECT_PRINTF("+0042", "%+05d", 42); + EXPECT_PRINTF("+0042", "%0++5d", 42); + + // '+' flag is ignored for non-numeric types. + EXPECT_PRINTF("x", "%+c", 'x'); // '+' flag wins over space flag EXPECT_PRINTF("+42", "%+ d", 42); @@ -166,11 +166,11 @@ TEST(PrintfTest, PlusFlag) { // '+' flag and space flag are both ignored for non-numeric types. EXPECT_PRINTF("x", "%+ c", 'x'); EXPECT_PRINTF("x", "% +c", 'x'); -} - -TEST(PrintfTest, MinusFlag) { - EXPECT_PRINTF("abc ", "%-5s", "abc"); - EXPECT_PRINTF("abc ", "%0--5s", "abc"); +} + +TEST(PrintfTest, MinusFlag) { + EXPECT_PRINTF("abc ", "%-5s", "abc"); + EXPECT_PRINTF("abc ", "%0--5s", "abc"); EXPECT_PRINTF("7 ", "%-5d", 7); EXPECT_PRINTF("97 ", "%-5hhi", 'a'); @@ -186,443 +186,443 @@ TEST(PrintfTest, MinusFlag) { // '-' and space flag don't interfere EXPECT_PRINTF(" 42", "%- d", 42); -} - -TEST(PrintfTest, SpaceFlag) { - EXPECT_PRINTF(" 42", "% d", 42); - EXPECT_PRINTF("-42", "% d", -42); - EXPECT_PRINTF(" 0042", "% 05d", 42); - EXPECT_PRINTF(" 0042", "%0 5d", 42); - - // ' ' flag is ignored for non-numeric types. - EXPECT_PRINTF("x", "% c", 'x'); -} - -TEST(PrintfTest, HashFlag) { - EXPECT_PRINTF("042", "%#o", 042); - EXPECT_PRINTF(fmt::format("0{:o}", static_cast<unsigned>(-042)), "%#o", -042); - EXPECT_PRINTF("0", "%#o", 0); - - EXPECT_PRINTF("0x42", "%#x", 0x42); - EXPECT_PRINTF("0X42", "%#X", 0x42); - EXPECT_PRINTF(fmt::format("0x{:x}", static_cast<unsigned>(-0x42)), "%#x", - -0x42); - EXPECT_PRINTF("0", "%#x", 0); - - EXPECT_PRINTF("0x0042", "%#06x", 0x42); - EXPECT_PRINTF("0x0042", "%0##6x", 0x42); - - EXPECT_PRINTF("-42.000000", "%#f", -42.0); - EXPECT_PRINTF("-42.000000", "%#F", -42.0); - - char buffer[BUFFER_SIZE]; - safe_sprintf(buffer, "%#e", -42.0); - EXPECT_PRINTF(buffer, "%#e", -42.0); - safe_sprintf(buffer, "%#E", -42.0); - EXPECT_PRINTF(buffer, "%#E", -42.0); - - EXPECT_PRINTF("-42.0000", "%#g", -42.0); - EXPECT_PRINTF("-42.0000", "%#G", -42.0); - - safe_sprintf(buffer, "%#a", 16.0); - EXPECT_PRINTF(buffer, "%#a", 16.0); - safe_sprintf(buffer, "%#A", 16.0); - EXPECT_PRINTF(buffer, "%#A", 16.0); - - // '#' flag is ignored for non-numeric types. - EXPECT_PRINTF("x", "%#c", 'x'); -} - -TEST(PrintfTest, Width) { - EXPECT_PRINTF(" abc", "%5s", "abc"); - - // Width cannot be specified twice. - EXPECT_THROW_MSG(test_sprintf("%5-5d", 42), format_error, - "invalid type specifier"); - - EXPECT_THROW_MSG(test_sprintf(format("%{}d", BIG_NUM), 42), format_error, - "number is too big"); - EXPECT_THROW_MSG(test_sprintf(format("%1${}d", BIG_NUM), 42), format_error, - "number is too big"); -} - -TEST(PrintfTest, DynamicWidth) { - EXPECT_EQ(" 42", test_sprintf("%*d", 5, 42)); - EXPECT_EQ("42 ", test_sprintf("%*d", -5, 42)); - EXPECT_THROW_MSG(test_sprintf("%*d", 5.0, 42), format_error, - "width is not integer"); +} + +TEST(PrintfTest, SpaceFlag) { + EXPECT_PRINTF(" 42", "% d", 42); + EXPECT_PRINTF("-42", "% d", -42); + EXPECT_PRINTF(" 0042", "% 05d", 42); + EXPECT_PRINTF(" 0042", "%0 5d", 42); + + // ' ' flag is ignored for non-numeric types. + EXPECT_PRINTF("x", "% c", 'x'); +} + +TEST(PrintfTest, HashFlag) { + EXPECT_PRINTF("042", "%#o", 042); + EXPECT_PRINTF(fmt::format("0{:o}", static_cast<unsigned>(-042)), "%#o", -042); + EXPECT_PRINTF("0", "%#o", 0); + + EXPECT_PRINTF("0x42", "%#x", 0x42); + EXPECT_PRINTF("0X42", "%#X", 0x42); + EXPECT_PRINTF(fmt::format("0x{:x}", static_cast<unsigned>(-0x42)), "%#x", + -0x42); + EXPECT_PRINTF("0", "%#x", 0); + + EXPECT_PRINTF("0x0042", "%#06x", 0x42); + EXPECT_PRINTF("0x0042", "%0##6x", 0x42); + + EXPECT_PRINTF("-42.000000", "%#f", -42.0); + EXPECT_PRINTF("-42.000000", "%#F", -42.0); + + char buffer[BUFFER_SIZE]; + safe_sprintf(buffer, "%#e", -42.0); + EXPECT_PRINTF(buffer, "%#e", -42.0); + safe_sprintf(buffer, "%#E", -42.0); + EXPECT_PRINTF(buffer, "%#E", -42.0); + + EXPECT_PRINTF("-42.0000", "%#g", -42.0); + EXPECT_PRINTF("-42.0000", "%#G", -42.0); + + safe_sprintf(buffer, "%#a", 16.0); + EXPECT_PRINTF(buffer, "%#a", 16.0); + safe_sprintf(buffer, "%#A", 16.0); + EXPECT_PRINTF(buffer, "%#A", 16.0); + + // '#' flag is ignored for non-numeric types. + EXPECT_PRINTF("x", "%#c", 'x'); +} + +TEST(PrintfTest, Width) { + EXPECT_PRINTF(" abc", "%5s", "abc"); + + // Width cannot be specified twice. + EXPECT_THROW_MSG(test_sprintf("%5-5d", 42), format_error, + "invalid type specifier"); + + EXPECT_THROW_MSG(test_sprintf(format("%{}d", BIG_NUM), 42), format_error, + "number is too big"); + EXPECT_THROW_MSG(test_sprintf(format("%1${}d", BIG_NUM), 42), format_error, + "number is too big"); +} + +TEST(PrintfTest, DynamicWidth) { + EXPECT_EQ(" 42", test_sprintf("%*d", 5, 42)); + EXPECT_EQ("42 ", test_sprintf("%*d", -5, 42)); + EXPECT_THROW_MSG(test_sprintf("%*d", 5.0, 42), format_error, + "width is not integer"); EXPECT_THROW_MSG(test_sprintf("%*d"), format_error, "argument not found"); - EXPECT_THROW_MSG(test_sprintf("%*d", BIG_NUM, 42), format_error, - "number is too big"); -} - -TEST(PrintfTest, IntPrecision) { - EXPECT_PRINTF("00042", "%.5d", 42); - EXPECT_PRINTF("-00042", "%.5d", -42); - EXPECT_PRINTF("00042", "%.5x", 0x42); - EXPECT_PRINTF("0x00042", "%#.5x", 0x42); - EXPECT_PRINTF("00042", "%.5o", 042); - EXPECT_PRINTF("00042", "%#.5o", 042); - - EXPECT_PRINTF(" 00042", "%7.5d", 42); - EXPECT_PRINTF(" 00042", "%7.5x", 0x42); - EXPECT_PRINTF(" 0x00042", "%#10.5x", 0x42); - EXPECT_PRINTF(" 00042", "%7.5o", 042); - EXPECT_PRINTF(" 00042", "%#10.5o", 042); - - EXPECT_PRINTF("00042 ", "%-7.5d", 42); - EXPECT_PRINTF("00042 ", "%-7.5x", 0x42); - EXPECT_PRINTF("0x00042 ", "%-#10.5x", 0x42); - EXPECT_PRINTF("00042 ", "%-7.5o", 042); - EXPECT_PRINTF("00042 ", "%-#10.5o", 042); -} - -TEST(PrintfTest, FloatPrecision) { - char buffer[BUFFER_SIZE]; - safe_sprintf(buffer, "%.3e", 1234.5678); - EXPECT_PRINTF(buffer, "%.3e", 1234.5678); - EXPECT_PRINTF("1234.568", "%.3f", 1234.5678); - EXPECT_PRINTF("1.23e+03", "%.3g", 1234.5678); - safe_sprintf(buffer, "%.3a", 1234.5678); - EXPECT_PRINTF(buffer, "%.3a", 1234.5678); -} - + EXPECT_THROW_MSG(test_sprintf("%*d", BIG_NUM, 42), format_error, + "number is too big"); +} + +TEST(PrintfTest, IntPrecision) { + EXPECT_PRINTF("00042", "%.5d", 42); + EXPECT_PRINTF("-00042", "%.5d", -42); + EXPECT_PRINTF("00042", "%.5x", 0x42); + EXPECT_PRINTF("0x00042", "%#.5x", 0x42); + EXPECT_PRINTF("00042", "%.5o", 042); + EXPECT_PRINTF("00042", "%#.5o", 042); + + EXPECT_PRINTF(" 00042", "%7.5d", 42); + EXPECT_PRINTF(" 00042", "%7.5x", 0x42); + EXPECT_PRINTF(" 0x00042", "%#10.5x", 0x42); + EXPECT_PRINTF(" 00042", "%7.5o", 042); + EXPECT_PRINTF(" 00042", "%#10.5o", 042); + + EXPECT_PRINTF("00042 ", "%-7.5d", 42); + EXPECT_PRINTF("00042 ", "%-7.5x", 0x42); + EXPECT_PRINTF("0x00042 ", "%-#10.5x", 0x42); + EXPECT_PRINTF("00042 ", "%-7.5o", 042); + EXPECT_PRINTF("00042 ", "%-#10.5o", 042); +} + +TEST(PrintfTest, FloatPrecision) { + char buffer[BUFFER_SIZE]; + safe_sprintf(buffer, "%.3e", 1234.5678); + EXPECT_PRINTF(buffer, "%.3e", 1234.5678); + EXPECT_PRINTF("1234.568", "%.3f", 1234.5678); + EXPECT_PRINTF("1.23e+03", "%.3g", 1234.5678); + safe_sprintf(buffer, "%.3a", 1234.5678); + EXPECT_PRINTF(buffer, "%.3a", 1234.5678); +} + TEST(PrintfTest, StringPrecision) { char test[] = {'H', 'e', 'l', 'l', 'o'}; EXPECT_EQ(fmt::sprintf("%.4s", test), "Hell"); } -TEST(PrintfTest, IgnorePrecisionForNonNumericArg) { - EXPECT_PRINTF("abc", "%.5s", "abc"); -} - -TEST(PrintfTest, DynamicPrecision) { - EXPECT_EQ("00042", test_sprintf("%.*d", 5, 42)); - EXPECT_EQ("42", test_sprintf("%.*d", -5, 42)); - EXPECT_THROW_MSG(test_sprintf("%.*d", 5.0, 42), format_error, - "precision is not integer"); +TEST(PrintfTest, IgnorePrecisionForNonNumericArg) { + EXPECT_PRINTF("abc", "%.5s", "abc"); +} + +TEST(PrintfTest, DynamicPrecision) { + EXPECT_EQ("00042", test_sprintf("%.*d", 5, 42)); + EXPECT_EQ("42", test_sprintf("%.*d", -5, 42)); + EXPECT_THROW_MSG(test_sprintf("%.*d", 5.0, 42), format_error, + "precision is not integer"); EXPECT_THROW_MSG(test_sprintf("%.*d"), format_error, "argument not found"); - EXPECT_THROW_MSG(test_sprintf("%.*d", BIG_NUM, 42), format_error, - "number is too big"); - if (sizeof(long long) != sizeof(int)) { - long long prec = static_cast<long long>(INT_MIN) - 1; - EXPECT_THROW_MSG(test_sprintf("%.*d", prec, 42), format_error, - "number is too big"); - } -} - -template <typename T> struct make_signed { typedef T type; }; - -#define SPECIALIZE_MAKE_SIGNED(T, S) \ - template <> struct make_signed<T> { typedef S type; } - -SPECIALIZE_MAKE_SIGNED(char, signed char); -SPECIALIZE_MAKE_SIGNED(unsigned char, signed char); -SPECIALIZE_MAKE_SIGNED(unsigned short, short); -SPECIALIZE_MAKE_SIGNED(unsigned, int); -SPECIALIZE_MAKE_SIGNED(unsigned long, long); -SPECIALIZE_MAKE_SIGNED(unsigned long long, long long); - -// Test length format specifier ``length_spec``. -template <typename T, typename U> -void TestLength(const char* length_spec, U value) { - long long signed_value = 0; - unsigned long long unsigned_value = 0; - // Apply integer promotion to the argument. - unsigned long long max = max_value<U>(); + EXPECT_THROW_MSG(test_sprintf("%.*d", BIG_NUM, 42), format_error, + "number is too big"); + if (sizeof(long long) != sizeof(int)) { + long long prec = static_cast<long long>(INT_MIN) - 1; + EXPECT_THROW_MSG(test_sprintf("%.*d", prec, 42), format_error, + "number is too big"); + } +} + +template <typename T> struct make_signed { typedef T type; }; + +#define SPECIALIZE_MAKE_SIGNED(T, S) \ + template <> struct make_signed<T> { typedef S type; } + +SPECIALIZE_MAKE_SIGNED(char, signed char); +SPECIALIZE_MAKE_SIGNED(unsigned char, signed char); +SPECIALIZE_MAKE_SIGNED(unsigned short, short); +SPECIALIZE_MAKE_SIGNED(unsigned, int); +SPECIALIZE_MAKE_SIGNED(unsigned long, long); +SPECIALIZE_MAKE_SIGNED(unsigned long long, long long); + +// Test length format specifier ``length_spec``. +template <typename T, typename U> +void TestLength(const char* length_spec, U value) { + long long signed_value = 0; + unsigned long long unsigned_value = 0; + // Apply integer promotion to the argument. + unsigned long long max = max_value<U>(); using fmt::detail::const_check; - if (const_check(max <= static_cast<unsigned>(max_value<int>()))) { - signed_value = static_cast<int>(value); - unsigned_value = static_cast<unsigned long long>(value); - } else if (const_check(max <= max_value<unsigned>())) { - signed_value = static_cast<unsigned>(value); - unsigned_value = static_cast<unsigned long long>(value); - } - if (sizeof(U) <= sizeof(int) && sizeof(int) < sizeof(T)) { - signed_value = static_cast<long long>(value); - unsigned_value = static_cast<unsigned long long>( - static_cast<typename std::make_unsigned<unsigned>::type>(value)); - } else { - signed_value = static_cast<typename make_signed<T>::type>(value); - unsigned_value = static_cast<typename std::make_unsigned<T>::type>(value); - } - std::ostringstream os; - os << signed_value; - EXPECT_PRINTF(os.str(), fmt::format("%{}d", length_spec), value); - EXPECT_PRINTF(os.str(), fmt::format("%{}i", length_spec), value); - os.str(""); - os << unsigned_value; - EXPECT_PRINTF(os.str(), fmt::format("%{}u", length_spec), value); - os.str(""); - os << std::oct << unsigned_value; - EXPECT_PRINTF(os.str(), fmt::format("%{}o", length_spec), value); - os.str(""); - os << std::hex << unsigned_value; - EXPECT_PRINTF(os.str(), fmt::format("%{}x", length_spec), value); - os.str(""); - os << std::hex << std::uppercase << unsigned_value; - EXPECT_PRINTF(os.str(), fmt::format("%{}X", length_spec), value); -} - -template <typename T> void TestLength(const char* length_spec) { - T min = std::numeric_limits<T>::min(), max = max_value<T>(); - TestLength<T>(length_spec, 42); - TestLength<T>(length_spec, -42); - TestLength<T>(length_spec, min); - TestLength<T>(length_spec, max); - long long long_long_min = std::numeric_limits<long long>::min(); - if (static_cast<long long>(min) > long_long_min) - TestLength<T>(length_spec, static_cast<long long>(min) - 1); - unsigned long long long_long_max = max_value<long long>(); - if (static_cast<unsigned long long>(max) < long_long_max) - TestLength<T>(length_spec, static_cast<long long>(max) + 1); - TestLength<T>(length_spec, std::numeric_limits<short>::min()); - TestLength<T>(length_spec, max_value<unsigned short>()); - TestLength<T>(length_spec, std::numeric_limits<int>::min()); - TestLength<T>(length_spec, max_value<int>()); - TestLength<T>(length_spec, std::numeric_limits<unsigned>::min()); - TestLength<T>(length_spec, max_value<unsigned>()); - TestLength<T>(length_spec, std::numeric_limits<long long>::min()); - TestLength<T>(length_spec, max_value<long long>()); - TestLength<T>(length_spec, std::numeric_limits<unsigned long long>::min()); - TestLength<T>(length_spec, max_value<unsigned long long>()); -} - -TEST(PrintfTest, Length) { - TestLength<char>("hh"); - TestLength<signed char>("hh"); - TestLength<unsigned char>("hh"); - TestLength<short>("h"); - TestLength<unsigned short>("h"); - TestLength<long>("l"); - TestLength<unsigned long>("l"); - TestLength<long long>("ll"); - TestLength<unsigned long long>("ll"); - TestLength<intmax_t>("j"); + if (const_check(max <= static_cast<unsigned>(max_value<int>()))) { + signed_value = static_cast<int>(value); + unsigned_value = static_cast<unsigned long long>(value); + } else if (const_check(max <= max_value<unsigned>())) { + signed_value = static_cast<unsigned>(value); + unsigned_value = static_cast<unsigned long long>(value); + } + if (sizeof(U) <= sizeof(int) && sizeof(int) < sizeof(T)) { + signed_value = static_cast<long long>(value); + unsigned_value = static_cast<unsigned long long>( + static_cast<typename std::make_unsigned<unsigned>::type>(value)); + } else { + signed_value = static_cast<typename make_signed<T>::type>(value); + unsigned_value = static_cast<typename std::make_unsigned<T>::type>(value); + } + std::ostringstream os; + os << signed_value; + EXPECT_PRINTF(os.str(), fmt::format("%{}d", length_spec), value); + EXPECT_PRINTF(os.str(), fmt::format("%{}i", length_spec), value); + os.str(""); + os << unsigned_value; + EXPECT_PRINTF(os.str(), fmt::format("%{}u", length_spec), value); + os.str(""); + os << std::oct << unsigned_value; + EXPECT_PRINTF(os.str(), fmt::format("%{}o", length_spec), value); + os.str(""); + os << std::hex << unsigned_value; + EXPECT_PRINTF(os.str(), fmt::format("%{}x", length_spec), value); + os.str(""); + os << std::hex << std::uppercase << unsigned_value; + EXPECT_PRINTF(os.str(), fmt::format("%{}X", length_spec), value); +} + +template <typename T> void TestLength(const char* length_spec) { + T min = std::numeric_limits<T>::min(), max = max_value<T>(); + TestLength<T>(length_spec, 42); + TestLength<T>(length_spec, -42); + TestLength<T>(length_spec, min); + TestLength<T>(length_spec, max); + long long long_long_min = std::numeric_limits<long long>::min(); + if (static_cast<long long>(min) > long_long_min) + TestLength<T>(length_spec, static_cast<long long>(min) - 1); + unsigned long long long_long_max = max_value<long long>(); + if (static_cast<unsigned long long>(max) < long_long_max) + TestLength<T>(length_spec, static_cast<long long>(max) + 1); + TestLength<T>(length_spec, std::numeric_limits<short>::min()); + TestLength<T>(length_spec, max_value<unsigned short>()); + TestLength<T>(length_spec, std::numeric_limits<int>::min()); + TestLength<T>(length_spec, max_value<int>()); + TestLength<T>(length_spec, std::numeric_limits<unsigned>::min()); + TestLength<T>(length_spec, max_value<unsigned>()); + TestLength<T>(length_spec, std::numeric_limits<long long>::min()); + TestLength<T>(length_spec, max_value<long long>()); + TestLength<T>(length_spec, std::numeric_limits<unsigned long long>::min()); + TestLength<T>(length_spec, max_value<unsigned long long>()); +} + +TEST(PrintfTest, Length) { + TestLength<char>("hh"); + TestLength<signed char>("hh"); + TestLength<unsigned char>("hh"); + TestLength<short>("h"); + TestLength<unsigned short>("h"); + TestLength<long>("l"); + TestLength<unsigned long>("l"); + TestLength<long long>("ll"); + TestLength<unsigned long long>("ll"); + TestLength<intmax_t>("j"); TestLength<size_t>("z"); - TestLength<std::ptrdiff_t>("t"); - long double max = max_value<long double>(); - EXPECT_PRINTF(fmt::format("{:.6}", max), "%g", max); - EXPECT_PRINTF(fmt::format("{:.6}", max), "%Lg", max); -} - -TEST(PrintfTest, Bool) { - EXPECT_PRINTF("1", "%d", true); - EXPECT_PRINTF("true", "%s", true); -} - -TEST(PrintfTest, Int) { - EXPECT_PRINTF("-42", "%d", -42); - EXPECT_PRINTF("-42", "%i", -42); - unsigned u = 0 - 42u; - EXPECT_PRINTF(fmt::format("{}", u), "%u", -42); - EXPECT_PRINTF(fmt::format("{:o}", u), "%o", -42); - EXPECT_PRINTF(fmt::format("{:x}", u), "%x", -42); - EXPECT_PRINTF(fmt::format("{:X}", u), "%X", -42); -} - -TEST(PrintfTest, long_long) { - // fmt::printf allows passing long long arguments to %d without length - // specifiers. - long long max = max_value<long long>(); - EXPECT_PRINTF(fmt::format("{}", max), "%d", max); -} - -TEST(PrintfTest, Float) { - EXPECT_PRINTF("392.650000", "%f", 392.65); - EXPECT_PRINTF("392.65", "%.2f", 392.65); - EXPECT_PRINTF("392.6", "%.1f", 392.65); - EXPECT_PRINTF("393", "%.f", 392.65); - EXPECT_PRINTF("392.650000", "%F", 392.65); - char buffer[BUFFER_SIZE]; - safe_sprintf(buffer, "%e", 392.65); - EXPECT_PRINTF(buffer, "%e", 392.65); - safe_sprintf(buffer, "%E", 392.65); - EXPECT_PRINTF(buffer, "%E", 392.65); - EXPECT_PRINTF("392.65", "%g", 392.65); - EXPECT_PRINTF("392.65", "%G", 392.65); - EXPECT_PRINTF("392", "%g", 392.0); - EXPECT_PRINTF("392", "%G", 392.0); - EXPECT_PRINTF("4.56e-07", "%g", 0.000000456); - safe_sprintf(buffer, "%a", -392.65); - EXPECT_EQ(buffer, format("{:a}", -392.65)); - safe_sprintf(buffer, "%A", -392.65); - EXPECT_EQ(buffer, format("{:A}", -392.65)); -} - -TEST(PrintfTest, Inf) { - double inf = std::numeric_limits<double>::infinity(); - for (const char* type = "fega"; *type; ++type) { - EXPECT_PRINTF("inf", fmt::format("%{}", *type), inf); - char upper = static_cast<char>(std::toupper(*type)); - EXPECT_PRINTF("INF", fmt::format("%{}", upper), inf); - } -} - -TEST(PrintfTest, Char) { - EXPECT_PRINTF("x", "%c", 'x'); - int max = max_value<int>(); - EXPECT_PRINTF(fmt::format("{}", static_cast<char>(max)), "%c", max); - // EXPECT_PRINTF("x", "%lc", L'x'); - EXPECT_PRINTF(L"x", L"%c", L'x'); - EXPECT_PRINTF(fmt::format(L"{}", static_cast<wchar_t>(max)), L"%c", max); -} - -TEST(PrintfTest, String) { - EXPECT_PRINTF("abc", "%s", "abc"); - const char* null_str = nullptr; - EXPECT_PRINTF("(null)", "%s", null_str); - EXPECT_PRINTF(" (null)", "%10s", null_str); - EXPECT_PRINTF(L"abc", L"%s", L"abc"); - const wchar_t* null_wstr = nullptr; - EXPECT_PRINTF(L"(null)", L"%s", null_wstr); - EXPECT_PRINTF(L" (null)", L"%10s", null_wstr); -} - -TEST(PrintfTest, UCharString) { - unsigned char str[] = "test"; - unsigned char* pstr = str; - EXPECT_EQ("test", fmt::sprintf("%s", pstr)); -} - -TEST(PrintfTest, Pointer) { - int n; - void* p = &n; - EXPECT_PRINTF(fmt::format("{}", p), "%p", p); - p = nullptr; - EXPECT_PRINTF("(nil)", "%p", p); - EXPECT_PRINTF(" (nil)", "%10p", p); - const char* s = "test"; - EXPECT_PRINTF(fmt::format("{:p}", s), "%p", s); - const char* null_str = nullptr; - EXPECT_PRINTF("(nil)", "%p", null_str); - - p = &n; - EXPECT_PRINTF(fmt::format(L"{}", p), L"%p", p); - p = nullptr; - EXPECT_PRINTF(L"(nil)", L"%p", p); - EXPECT_PRINTF(L" (nil)", L"%10p", p); - const wchar_t* w = L"test"; - EXPECT_PRINTF(fmt::format(L"{:p}", w), L"%p", w); - const wchar_t* null_wstr = nullptr; - EXPECT_PRINTF(L"(nil)", L"%p", null_wstr); -} - -TEST(PrintfTest, Location) { - // TODO: test %n -} - -enum test_enum { answer = 42 }; - -TEST(PrintfTest, Enum) { - EXPECT_PRINTF("42", "%d", answer); - volatile test_enum volatile_enum = answer; - EXPECT_PRINTF("42", "%d", volatile_enum); -} - -#if FMT_USE_FCNTL -TEST(PrintfTest, Examples) { - const char* weekday = "Thursday"; - const char* month = "August"; - int day = 21; - EXPECT_WRITE(stdout, fmt::printf("%1$s, %3$d %2$s", weekday, month, day), - "Thursday, 21 August"); -} - -TEST(PrintfTest, PrintfError) { - fmt::file read_end, write_end; - fmt::file::pipe(read_end, write_end); - int result = fmt::fprintf(read_end.fdopen("r").get(), "test"); - EXPECT_LT(result, 0); -} -#endif - -TEST(PrintfTest, WideString) { EXPECT_EQ(L"abc", fmt::sprintf(L"%s", L"abc")); } - -TEST(PrintfTest, PrintfCustom) { - EXPECT_EQ("abc", test_sprintf("%s", TestString("abc"))); -} - -TEST(PrintfTest, OStream) { - std::ostringstream os; - int ret = fmt::fprintf(os, "Don't %s!", "panic"); - EXPECT_EQ("Don't panic!", os.str()); - EXPECT_EQ(12, ret); -} - -TEST(PrintfTest, VPrintf) { - fmt::format_arg_store<fmt::printf_context, int> as{42}; - fmt::basic_format_args<fmt::printf_context> args(as); - EXPECT_EQ(fmt::vsprintf("%d", args), "42"); - EXPECT_WRITE(stdout, fmt::vprintf("%d", args), "42"); - EXPECT_WRITE(stdout, fmt::vfprintf(stdout, "%d", args), "42"); - EXPECT_WRITE(stdout, fmt::vfprintf(std::cout, "%d", args), "42"); -} - -template <typename... Args> -void check_format_string_regression(fmt::string_view s, const Args&... args) { - fmt::sprintf(s, args...); -} - -TEST(PrintfTest, CheckFormatStringRegression) { - check_format_string_regression("%c%s", 'x', ""); -} - -TEST(PrintfTest, FixedLargeExponent) { - EXPECT_EQ("1000000000000000000000", fmt::sprintf("%.*f", -13, 1e21)); -} - -TEST(PrintfTest, VSPrintfMakeArgsExample) { - fmt::format_arg_store<fmt::printf_context, int, const char*> as{42, - "something"}; - fmt::basic_format_args<fmt::printf_context> args(as); - EXPECT_EQ("[42] something happened", fmt::vsprintf("[%d] %s happened", args)); - auto as2 = fmt::make_printf_args(42, "something"); - fmt::basic_format_args<fmt::printf_context> args2(as2); - EXPECT_EQ("[42] something happened", - fmt::vsprintf("[%d] %s happened", args2)); - // The older gcc versions can't cast the return value. -#if !defined(__GNUC__) || (__GNUC__ > 4) - EXPECT_EQ("[42] something happened", - fmt::vsprintf("[%d] %s happened", - {fmt::make_printf_args(42, "something")})); -#endif -} - -TEST(PrintfTest, VSPrintfMakeWArgsExample) { - fmt::format_arg_store<fmt::wprintf_context, int, const wchar_t*> as{ - 42, L"something"}; - fmt::basic_format_args<fmt::wprintf_context> args(as); - EXPECT_EQ(L"[42] something happened", - fmt::vsprintf(L"[%d] %s happened", args)); - auto as2 = fmt::make_wprintf_args(42, L"something"); - fmt::basic_format_args<fmt::wprintf_context> args2(as2); - EXPECT_EQ(L"[42] something happened", - fmt::vsprintf(L"[%d] %s happened", args2)); - // the older gcc versions can't cast the return value -#if !defined(__GNUC__) || (__GNUC__ > 4) - EXPECT_EQ(L"[42] something happened", - fmt::vsprintf(L"[%d] %s happened", - {fmt::make_wprintf_args(42, L"something")})); -#endif -} - + TestLength<std::ptrdiff_t>("t"); + long double max = max_value<long double>(); + EXPECT_PRINTF(fmt::format("{:.6}", max), "%g", max); + EXPECT_PRINTF(fmt::format("{:.6}", max), "%Lg", max); +} + +TEST(PrintfTest, Bool) { + EXPECT_PRINTF("1", "%d", true); + EXPECT_PRINTF("true", "%s", true); +} + +TEST(PrintfTest, Int) { + EXPECT_PRINTF("-42", "%d", -42); + EXPECT_PRINTF("-42", "%i", -42); + unsigned u = 0 - 42u; + EXPECT_PRINTF(fmt::format("{}", u), "%u", -42); + EXPECT_PRINTF(fmt::format("{:o}", u), "%o", -42); + EXPECT_PRINTF(fmt::format("{:x}", u), "%x", -42); + EXPECT_PRINTF(fmt::format("{:X}", u), "%X", -42); +} + +TEST(PrintfTest, long_long) { + // fmt::printf allows passing long long arguments to %d without length + // specifiers. + long long max = max_value<long long>(); + EXPECT_PRINTF(fmt::format("{}", max), "%d", max); +} + +TEST(PrintfTest, Float) { + EXPECT_PRINTF("392.650000", "%f", 392.65); + EXPECT_PRINTF("392.65", "%.2f", 392.65); + EXPECT_PRINTF("392.6", "%.1f", 392.65); + EXPECT_PRINTF("393", "%.f", 392.65); + EXPECT_PRINTF("392.650000", "%F", 392.65); + char buffer[BUFFER_SIZE]; + safe_sprintf(buffer, "%e", 392.65); + EXPECT_PRINTF(buffer, "%e", 392.65); + safe_sprintf(buffer, "%E", 392.65); + EXPECT_PRINTF(buffer, "%E", 392.65); + EXPECT_PRINTF("392.65", "%g", 392.65); + EXPECT_PRINTF("392.65", "%G", 392.65); + EXPECT_PRINTF("392", "%g", 392.0); + EXPECT_PRINTF("392", "%G", 392.0); + EXPECT_PRINTF("4.56e-07", "%g", 0.000000456); + safe_sprintf(buffer, "%a", -392.65); + EXPECT_EQ(buffer, format("{:a}", -392.65)); + safe_sprintf(buffer, "%A", -392.65); + EXPECT_EQ(buffer, format("{:A}", -392.65)); +} + +TEST(PrintfTest, Inf) { + double inf = std::numeric_limits<double>::infinity(); + for (const char* type = "fega"; *type; ++type) { + EXPECT_PRINTF("inf", fmt::format("%{}", *type), inf); + char upper = static_cast<char>(std::toupper(*type)); + EXPECT_PRINTF("INF", fmt::format("%{}", upper), inf); + } +} + +TEST(PrintfTest, Char) { + EXPECT_PRINTF("x", "%c", 'x'); + int max = max_value<int>(); + EXPECT_PRINTF(fmt::format("{}", static_cast<char>(max)), "%c", max); + // EXPECT_PRINTF("x", "%lc", L'x'); + EXPECT_PRINTF(L"x", L"%c", L'x'); + EXPECT_PRINTF(fmt::format(L"{}", static_cast<wchar_t>(max)), L"%c", max); +} + +TEST(PrintfTest, String) { + EXPECT_PRINTF("abc", "%s", "abc"); + const char* null_str = nullptr; + EXPECT_PRINTF("(null)", "%s", null_str); + EXPECT_PRINTF(" (null)", "%10s", null_str); + EXPECT_PRINTF(L"abc", L"%s", L"abc"); + const wchar_t* null_wstr = nullptr; + EXPECT_PRINTF(L"(null)", L"%s", null_wstr); + EXPECT_PRINTF(L" (null)", L"%10s", null_wstr); +} + +TEST(PrintfTest, UCharString) { + unsigned char str[] = "test"; + unsigned char* pstr = str; + EXPECT_EQ("test", fmt::sprintf("%s", pstr)); +} + +TEST(PrintfTest, Pointer) { + int n; + void* p = &n; + EXPECT_PRINTF(fmt::format("{}", p), "%p", p); + p = nullptr; + EXPECT_PRINTF("(nil)", "%p", p); + EXPECT_PRINTF(" (nil)", "%10p", p); + const char* s = "test"; + EXPECT_PRINTF(fmt::format("{:p}", s), "%p", s); + const char* null_str = nullptr; + EXPECT_PRINTF("(nil)", "%p", null_str); + + p = &n; + EXPECT_PRINTF(fmt::format(L"{}", p), L"%p", p); + p = nullptr; + EXPECT_PRINTF(L"(nil)", L"%p", p); + EXPECT_PRINTF(L" (nil)", L"%10p", p); + const wchar_t* w = L"test"; + EXPECT_PRINTF(fmt::format(L"{:p}", w), L"%p", w); + const wchar_t* null_wstr = nullptr; + EXPECT_PRINTF(L"(nil)", L"%p", null_wstr); +} + +TEST(PrintfTest, Location) { + // TODO: test %n +} + +enum test_enum { answer = 42 }; + +TEST(PrintfTest, Enum) { + EXPECT_PRINTF("42", "%d", answer); + volatile test_enum volatile_enum = answer; + EXPECT_PRINTF("42", "%d", volatile_enum); +} + +#if FMT_USE_FCNTL +TEST(PrintfTest, Examples) { + const char* weekday = "Thursday"; + const char* month = "August"; + int day = 21; + EXPECT_WRITE(stdout, fmt::printf("%1$s, %3$d %2$s", weekday, month, day), + "Thursday, 21 August"); +} + +TEST(PrintfTest, PrintfError) { + fmt::file read_end, write_end; + fmt::file::pipe(read_end, write_end); + int result = fmt::fprintf(read_end.fdopen("r").get(), "test"); + EXPECT_LT(result, 0); +} +#endif + +TEST(PrintfTest, WideString) { EXPECT_EQ(L"abc", fmt::sprintf(L"%s", L"abc")); } + +TEST(PrintfTest, PrintfCustom) { + EXPECT_EQ("abc", test_sprintf("%s", TestString("abc"))); +} + +TEST(PrintfTest, OStream) { + std::ostringstream os; + int ret = fmt::fprintf(os, "Don't %s!", "panic"); + EXPECT_EQ("Don't panic!", os.str()); + EXPECT_EQ(12, ret); +} + +TEST(PrintfTest, VPrintf) { + fmt::format_arg_store<fmt::printf_context, int> as{42}; + fmt::basic_format_args<fmt::printf_context> args(as); + EXPECT_EQ(fmt::vsprintf("%d", args), "42"); + EXPECT_WRITE(stdout, fmt::vprintf("%d", args), "42"); + EXPECT_WRITE(stdout, fmt::vfprintf(stdout, "%d", args), "42"); + EXPECT_WRITE(stdout, fmt::vfprintf(std::cout, "%d", args), "42"); +} + +template <typename... Args> +void check_format_string_regression(fmt::string_view s, const Args&... args) { + fmt::sprintf(s, args...); +} + +TEST(PrintfTest, CheckFormatStringRegression) { + check_format_string_regression("%c%s", 'x', ""); +} + +TEST(PrintfTest, FixedLargeExponent) { + EXPECT_EQ("1000000000000000000000", fmt::sprintf("%.*f", -13, 1e21)); +} + +TEST(PrintfTest, VSPrintfMakeArgsExample) { + fmt::format_arg_store<fmt::printf_context, int, const char*> as{42, + "something"}; + fmt::basic_format_args<fmt::printf_context> args(as); + EXPECT_EQ("[42] something happened", fmt::vsprintf("[%d] %s happened", args)); + auto as2 = fmt::make_printf_args(42, "something"); + fmt::basic_format_args<fmt::printf_context> args2(as2); + EXPECT_EQ("[42] something happened", + fmt::vsprintf("[%d] %s happened", args2)); + // The older gcc versions can't cast the return value. +#if !defined(__GNUC__) || (__GNUC__ > 4) + EXPECT_EQ("[42] something happened", + fmt::vsprintf("[%d] %s happened", + {fmt::make_printf_args(42, "something")})); +#endif +} + +TEST(PrintfTest, VSPrintfMakeWArgsExample) { + fmt::format_arg_store<fmt::wprintf_context, int, const wchar_t*> as{ + 42, L"something"}; + fmt::basic_format_args<fmt::wprintf_context> args(as); + EXPECT_EQ(L"[42] something happened", + fmt::vsprintf(L"[%d] %s happened", args)); + auto as2 = fmt::make_wprintf_args(42, L"something"); + fmt::basic_format_args<fmt::wprintf_context> args2(as2); + EXPECT_EQ(L"[42] something happened", + fmt::vsprintf(L"[%d] %s happened", args2)); + // the older gcc versions can't cast the return value +#if !defined(__GNUC__) || (__GNUC__ > 4) + EXPECT_EQ(L"[42] something happened", + fmt::vsprintf(L"[%d] %s happened", + {fmt::make_wprintf_args(42, L"something")})); +#endif +} + TEST(PrintfTest, PrintfDetermineOutputSize) { using backit = std::back_insert_iterator<std::vector<char>>; using truncated_printf_context = fmt::basic_printf_context<fmt::detail::truncating_iterator<backit>, char>; - + auto v = std::vector<char>{}; auto it = std::back_inserter(v); - + const auto format_string = "%s"; const auto format_arg = "Hello"; const auto expected_size = fmt::sprintf(format_string, format_arg).size(); - + EXPECT_EQ((truncated_printf_context( fmt::detail::truncating_iterator<backit>(it, 0), format_string, fmt::make_format_args<truncated_printf_context>(format_arg)) .format() .count()), expected_size); -} +} diff --git a/contrib/libs/fmt/test/printf-test/ya.make b/contrib/libs/fmt/test/printf-test/ya.make index 4c27379ea4..ec264a6c81 100644 --- a/contrib/libs/fmt/test/printf-test/ya.make +++ b/contrib/libs/fmt/test/printf-test/ya.make @@ -1,37 +1,37 @@ -# Generated by devtools/yamaker. - +# Generated by devtools/yamaker. + GTEST() - + WITHOUT_LICENSE_TEXTS() - + OWNER( orivej g:cpp-contrib ) -LICENSE(MIT) - -PEERDIR( - contrib/libs/fmt - contrib/libs/fmt/test -) - -NO_COMPILER_WARNINGS() - -NO_UTIL() - -CFLAGS( - -DFMT_LOCALE - -DFMT_SHARED - -DGTEST_HAS_STD_WSTRING=1 - -DGTEST_LANG_CXX11=0 - -D_SILENCE_TR1_NAMESPACE_DEPRECATION_WARNING=1 -) - -SRCDIR(contrib/libs/fmt/test) - -SRCS( - printf-test.cc -) - -END() +LICENSE(MIT) + +PEERDIR( + contrib/libs/fmt + contrib/libs/fmt/test +) + +NO_COMPILER_WARNINGS() + +NO_UTIL() + +CFLAGS( + -DFMT_LOCALE + -DFMT_SHARED + -DGTEST_HAS_STD_WSTRING=1 + -DGTEST_LANG_CXX11=0 + -D_SILENCE_TR1_NAMESPACE_DEPRECATION_WARNING=1 +) + +SRCDIR(contrib/libs/fmt/test) + +SRCS( + printf-test.cc +) + +END() diff --git a/contrib/libs/fmt/test/ranges-test.cc b/contrib/libs/fmt/test/ranges-test.cc index a45ea55f25..394f7b81be 100644 --- a/contrib/libs/fmt/test/ranges-test.cc +++ b/contrib/libs/fmt/test/ranges-test.cc @@ -1,144 +1,144 @@ -// Formatting library for C++ - the core API -// -// Copyright (c) 2012 - present, Victor Zverovich -// All rights reserved. -// -// For the license information refer to format.h. -// -// Copyright (c) 2018 - present, Remotion (Igor Schulz) -// All Rights Reserved -// {fmt} support for ranges, containers and types tuple interface. - -#include "fmt/ranges.h" - -#include <gtest/gtest.h> - -// Check if 'if constexpr' is supported. -#if (__cplusplus > 201402L) || \ - (defined(_MSVC_LANG) && _MSVC_LANG > 201402L && _MSC_VER >= 1910) - -# include <array> -# include <map> -# include <string> -# include <vector> - -TEST(RangesTest, FormatVector) { - std::vector<int32_t> iv{1, 2, 3, 5, 7, 11}; - auto ivf = fmt::format("{}", iv); - EXPECT_EQ("{1, 2, 3, 5, 7, 11}", ivf); -} - -TEST(RangesTest, FormatVector2) { - std::vector<std::vector<int32_t>> ivv{{1, 2}, {3, 5}, {7, 11}}; - auto ivf = fmt::format("{}", ivv); - EXPECT_EQ("{{1, 2}, {3, 5}, {7, 11}}", ivf); -} - -TEST(RangesTest, FormatMap) { - std::map<std::string, int32_t> simap{{"one", 1}, {"two", 2}}; - EXPECT_EQ("{(\"one\", 1), (\"two\", 2)}", fmt::format("{}", simap)); -} - -TEST(RangesTest, FormatPair) { - std::pair<int64_t, float> pa1{42, 1.5f}; - EXPECT_EQ("(42, 1.5)", fmt::format("{}", pa1)); -} - -TEST(RangesTest, FormatTuple) { - std::tuple<int64_t, float, std::string, char> t{42, 1.5f, "this is tuple", - 'i'}; - EXPECT_EQ("(42, 1.5, \"this is tuple\", 'i')", fmt::format("{}", t)); - EXPECT_EQ("()", fmt::format("{}", std::tuple<>())); -} - -TEST(RangesTest, JoinTuple) { - // Value tuple args - std::tuple<char, int, float> t1 = std::make_tuple('a', 1, 2.0f); +// Formatting library for C++ - the core API +// +// Copyright (c) 2012 - present, Victor Zverovich +// All rights reserved. +// +// For the license information refer to format.h. +// +// Copyright (c) 2018 - present, Remotion (Igor Schulz) +// All Rights Reserved +// {fmt} support for ranges, containers and types tuple interface. + +#include "fmt/ranges.h" + +#include <gtest/gtest.h> + +// Check if 'if constexpr' is supported. +#if (__cplusplus > 201402L) || \ + (defined(_MSVC_LANG) && _MSVC_LANG > 201402L && _MSC_VER >= 1910) + +# include <array> +# include <map> +# include <string> +# include <vector> + +TEST(RangesTest, FormatVector) { + std::vector<int32_t> iv{1, 2, 3, 5, 7, 11}; + auto ivf = fmt::format("{}", iv); + EXPECT_EQ("{1, 2, 3, 5, 7, 11}", ivf); +} + +TEST(RangesTest, FormatVector2) { + std::vector<std::vector<int32_t>> ivv{{1, 2}, {3, 5}, {7, 11}}; + auto ivf = fmt::format("{}", ivv); + EXPECT_EQ("{{1, 2}, {3, 5}, {7, 11}}", ivf); +} + +TEST(RangesTest, FormatMap) { + std::map<std::string, int32_t> simap{{"one", 1}, {"two", 2}}; + EXPECT_EQ("{(\"one\", 1), (\"two\", 2)}", fmt::format("{}", simap)); +} + +TEST(RangesTest, FormatPair) { + std::pair<int64_t, float> pa1{42, 1.5f}; + EXPECT_EQ("(42, 1.5)", fmt::format("{}", pa1)); +} + +TEST(RangesTest, FormatTuple) { + std::tuple<int64_t, float, std::string, char> t{42, 1.5f, "this is tuple", + 'i'}; + EXPECT_EQ("(42, 1.5, \"this is tuple\", 'i')", fmt::format("{}", t)); + EXPECT_EQ("()", fmt::format("{}", std::tuple<>())); +} + +TEST(RangesTest, JoinTuple) { + // Value tuple args + std::tuple<char, int, float> t1 = std::make_tuple('a', 1, 2.0f); EXPECT_EQ("(a, 1, 2)", fmt::format("({})", fmt::join(t1, ", "))); - - // Testing lvalue tuple args - int x = 4; - std::tuple<char, int&> t2{'b', x}; - EXPECT_EQ("b + 4", fmt::format("{}", fmt::join(t2, " + "))); - - // Empty tuple - std::tuple<> t3; - EXPECT_EQ("", fmt::format("{}", fmt::join(t3, "|"))); - - // Single element tuple - std::tuple<float> t4{4.0f}; + + // Testing lvalue tuple args + int x = 4; + std::tuple<char, int&> t2{'b', x}; + EXPECT_EQ("b + 4", fmt::format("{}", fmt::join(t2, " + "))); + + // Empty tuple + std::tuple<> t3; + EXPECT_EQ("", fmt::format("{}", fmt::join(t3, "|"))); + + // Single element tuple + std::tuple<float> t4{4.0f}; EXPECT_EQ("4", fmt::format("{}", fmt::join(t4, "/"))); -} - -TEST(RangesTest, JoinInitializerList) { - EXPECT_EQ("1, 2, 3", fmt::format("{}", fmt::join({1, 2, 3}, ", "))); - EXPECT_EQ("fmt rocks !", - fmt::format("{}", fmt::join({"fmt", "rocks", "!"}, " "))); -} - -struct my_struct { - int32_t i; - std::string str; // can throw +} + +TEST(RangesTest, JoinInitializerList) { + EXPECT_EQ("1, 2, 3", fmt::format("{}", fmt::join({1, 2, 3}, ", "))); + EXPECT_EQ("fmt rocks !", + fmt::format("{}", fmt::join({"fmt", "rocks", "!"}, " "))); +} + +struct my_struct { + int32_t i; + std::string str; // can throw template <size_t N> decltype(auto) get() const noexcept { - if constexpr (N == 0) - return i; - else if constexpr (N == 1) - return fmt::string_view{str}; - } -}; - + if constexpr (N == 0) + return i; + else if constexpr (N == 1) + return fmt::string_view{str}; + } +}; + template <size_t N> decltype(auto) get(const my_struct& s) noexcept { - return s.get<N>(); -} - -namespace std { - + return s.get<N>(); +} + +namespace std { + template <> struct tuple_size<my_struct> : std::integral_constant<size_t, 2> {}; - + template <size_t N> struct tuple_element<N, my_struct> { - using type = decltype(std::declval<my_struct>().get<N>()); -}; - -} // namespace std - -TEST(RangesTest, FormatStruct) { - my_struct mst{13, "my struct"}; - EXPECT_EQ("(13, \"my struct\")", fmt::format("{}", mst)); -} - -TEST(RangesTest, FormatTo) { - char buf[10]; - auto end = fmt::format_to(buf, "{}", std::vector{1, 2, 3}); - *end = '\0'; - EXPECT_STREQ(buf, "{1, 2, 3}"); -} - -struct path_like { - const path_like* begin() const; - const path_like* end() const; - - operator std::string() const; -}; - -TEST(RangesTest, PathLike) { - EXPECT_FALSE((fmt::is_range<path_like, char>::value)); -} - -#endif // (__cplusplus > 201402L) || (defined(_MSVC_LANG) && _MSVC_LANG > - // 201402L && _MSC_VER >= 1910) - -#ifdef FMT_USE_STRING_VIEW -struct string_like { - const char* begin(); - const char* end(); - explicit operator fmt::string_view() const { return "foo"; } - explicit operator std::string_view() const { return "foo"; } -}; - -TEST(RangesTest, FormatStringLike) { - EXPECT_EQ("foo", fmt::format("{}", string_like())); -} -#endif // FMT_USE_STRING_VIEW + using type = decltype(std::declval<my_struct>().get<N>()); +}; + +} // namespace std + +TEST(RangesTest, FormatStruct) { + my_struct mst{13, "my struct"}; + EXPECT_EQ("(13, \"my struct\")", fmt::format("{}", mst)); +} + +TEST(RangesTest, FormatTo) { + char buf[10]; + auto end = fmt::format_to(buf, "{}", std::vector{1, 2, 3}); + *end = '\0'; + EXPECT_STREQ(buf, "{1, 2, 3}"); +} + +struct path_like { + const path_like* begin() const; + const path_like* end() const; + + operator std::string() const; +}; + +TEST(RangesTest, PathLike) { + EXPECT_FALSE((fmt::is_range<path_like, char>::value)); +} + +#endif // (__cplusplus > 201402L) || (defined(_MSVC_LANG) && _MSVC_LANG > + // 201402L && _MSC_VER >= 1910) + +#ifdef FMT_USE_STRING_VIEW +struct string_like { + const char* begin(); + const char* end(); + explicit operator fmt::string_view() const { return "foo"; } + explicit operator std::string_view() const { return "foo"; } +}; + +TEST(RangesTest, FormatStringLike) { + EXPECT_EQ("foo", fmt::format("{}", string_like())); +} +#endif // FMT_USE_STRING_VIEW struct zstring_sentinel {}; diff --git a/contrib/libs/fmt/test/ranges-test/ya.make b/contrib/libs/fmt/test/ranges-test/ya.make index 194968c38b..6856e12893 100644 --- a/contrib/libs/fmt/test/ranges-test/ya.make +++ b/contrib/libs/fmt/test/ranges-test/ya.make @@ -1,37 +1,37 @@ -# Generated by devtools/yamaker. - +# Generated by devtools/yamaker. + GTEST() - + WITHOUT_LICENSE_TEXTS() - + OWNER( orivej g:cpp-contrib ) -LICENSE(MIT) - -PEERDIR( - contrib/libs/fmt - contrib/libs/fmt/test -) - -NO_COMPILER_WARNINGS() - -NO_UTIL() - -CFLAGS( - -DFMT_LOCALE - -DFMT_SHARED - -DGTEST_HAS_STD_WSTRING=1 - -DGTEST_LANG_CXX11=0 - -D_SILENCE_TR1_NAMESPACE_DEPRECATION_WARNING=1 -) - -SRCDIR(contrib/libs/fmt/test) - -SRCS( - ranges-test.cc -) - -END() +LICENSE(MIT) + +PEERDIR( + contrib/libs/fmt + contrib/libs/fmt/test +) + +NO_COMPILER_WARNINGS() + +NO_UTIL() + +CFLAGS( + -DFMT_LOCALE + -DFMT_SHARED + -DGTEST_HAS_STD_WSTRING=1 + -DGTEST_LANG_CXX11=0 + -D_SILENCE_TR1_NAMESPACE_DEPRECATION_WARNING=1 +) + +SRCDIR(contrib/libs/fmt/test) + +SRCS( + ranges-test.cc +) + +END() diff --git a/contrib/libs/fmt/test/scan-test.cc b/contrib/libs/fmt/test/scan-test.cc index 3542cdc2cb..90c0edef9b 100644 --- a/contrib/libs/fmt/test/scan-test.cc +++ b/contrib/libs/fmt/test/scan-test.cc @@ -1,116 +1,116 @@ -// Formatting library for C++ - scanning API test -// -// Copyright (c) 2019 - present, Victor Zverovich -// All rights reserved. -// -// For the license information refer to format.h. - +// Formatting library for C++ - scanning API test +// +// Copyright (c) 2019 - present, Victor Zverovich +// All rights reserved. +// +// For the license information refer to format.h. + #include "scan.h" -#include <time.h> - -#include <climits> - -#include <gmock/gmock.h> -#include "gtest-extra.h" - -TEST(ScanTest, ReadText) { - fmt::string_view s = "foo"; - auto end = fmt::scan(s, "foo"); - EXPECT_EQ(end, s.end()); - EXPECT_THROW_MSG(fmt::scan("fob", "foo"), fmt::format_error, "invalid input"); -} - -TEST(ScanTest, ReadInt) { - int n = 0; - fmt::scan("42", "{}", n); - EXPECT_EQ(n, 42); - fmt::scan("-42", "{}", n); - EXPECT_EQ(n, -42); -} - -TEST(ScanTest, ReadLongLong) { - long long n = 0; - fmt::scan("42", "{}", n); - EXPECT_EQ(n, 42); - fmt::scan("-42", "{}", n); - EXPECT_EQ(n, -42); -} - -TEST(ScanTest, ReadUInt) { - unsigned n = 0; - fmt::scan("42", "{}", n); - EXPECT_EQ(n, 42); - EXPECT_THROW_MSG(fmt::scan("-42", "{}", n), fmt::format_error, - "invalid input"); -} - -TEST(ScanTest, ReadULongLong) { - unsigned long long n = 0; - fmt::scan("42", "{}", n); - EXPECT_EQ(n, 42); - EXPECT_THROW_MSG(fmt::scan("-42", "{}", n), fmt::format_error, - "invalid input"); -} - -TEST(ScanTest, ReadString) { - std::string s; - fmt::scan("foo", "{}", s); - EXPECT_EQ(s, "foo"); -} - -TEST(ScanTest, ReadStringView) { - fmt::string_view s; - fmt::scan("foo", "{}", s); - EXPECT_EQ(s, "foo"); -} - -#ifndef _WIN32 -namespace fmt { -template <> struct scanner<tm> { - std::string format; - - scan_parse_context::iterator parse(scan_parse_context& ctx) { - auto it = ctx.begin(); - if (it != ctx.end() && *it == ':') ++it; - auto end = it; - while (end != ctx.end() && *end != '}') ++end; +#include <time.h> + +#include <climits> + +#include <gmock/gmock.h> +#include "gtest-extra.h" + +TEST(ScanTest, ReadText) { + fmt::string_view s = "foo"; + auto end = fmt::scan(s, "foo"); + EXPECT_EQ(end, s.end()); + EXPECT_THROW_MSG(fmt::scan("fob", "foo"), fmt::format_error, "invalid input"); +} + +TEST(ScanTest, ReadInt) { + int n = 0; + fmt::scan("42", "{}", n); + EXPECT_EQ(n, 42); + fmt::scan("-42", "{}", n); + EXPECT_EQ(n, -42); +} + +TEST(ScanTest, ReadLongLong) { + long long n = 0; + fmt::scan("42", "{}", n); + EXPECT_EQ(n, 42); + fmt::scan("-42", "{}", n); + EXPECT_EQ(n, -42); +} + +TEST(ScanTest, ReadUInt) { + unsigned n = 0; + fmt::scan("42", "{}", n); + EXPECT_EQ(n, 42); + EXPECT_THROW_MSG(fmt::scan("-42", "{}", n), fmt::format_error, + "invalid input"); +} + +TEST(ScanTest, ReadULongLong) { + unsigned long long n = 0; + fmt::scan("42", "{}", n); + EXPECT_EQ(n, 42); + EXPECT_THROW_MSG(fmt::scan("-42", "{}", n), fmt::format_error, + "invalid input"); +} + +TEST(ScanTest, ReadString) { + std::string s; + fmt::scan("foo", "{}", s); + EXPECT_EQ(s, "foo"); +} + +TEST(ScanTest, ReadStringView) { + fmt::string_view s; + fmt::scan("foo", "{}", s); + EXPECT_EQ(s, "foo"); +} + +#ifndef _WIN32 +namespace fmt { +template <> struct scanner<tm> { + std::string format; + + scan_parse_context::iterator parse(scan_parse_context& ctx) { + auto it = ctx.begin(); + if (it != ctx.end() && *it == ':') ++it; + auto end = it; + while (end != ctx.end() && *end != '}') ++end; format.reserve(detail::to_unsigned(end - it + 1)); - format.append(it, end); - format.push_back('\0'); - return end; - } - - template <class ScanContext> - typename ScanContext::iterator scan(tm& t, ScanContext& ctx) { - auto result = strptime(ctx.begin(), format.c_str(), &t); - if (!result) throw format_error("failed to parse time"); - return result; - } -}; -} // namespace fmt - -TEST(ScanTest, ReadCustom) { - const char* input = "Date: 1985-10-25"; - auto t = tm(); - fmt::scan(input, "Date: {0:%Y-%m-%d}", t); - EXPECT_EQ(t.tm_year, 85); - EXPECT_EQ(t.tm_mon, 9); - EXPECT_EQ(t.tm_mday, 25); -} -#endif - -TEST(ScanTest, InvalidFormat) { - EXPECT_THROW_MSG(fmt::scan("", "{}"), fmt::format_error, - "argument index out of range"); - EXPECT_THROW_MSG(fmt::scan("", "{"), fmt::format_error, - "invalid format string"); -} - -TEST(ScanTest, Example) { - std::string key; - int value; - fmt::scan("answer = 42", "{} = {}", key, value); - EXPECT_EQ(key, "answer"); - EXPECT_EQ(value, 42); -} + format.append(it, end); + format.push_back('\0'); + return end; + } + + template <class ScanContext> + typename ScanContext::iterator scan(tm& t, ScanContext& ctx) { + auto result = strptime(ctx.begin(), format.c_str(), &t); + if (!result) throw format_error("failed to parse time"); + return result; + } +}; +} // namespace fmt + +TEST(ScanTest, ReadCustom) { + const char* input = "Date: 1985-10-25"; + auto t = tm(); + fmt::scan(input, "Date: {0:%Y-%m-%d}", t); + EXPECT_EQ(t.tm_year, 85); + EXPECT_EQ(t.tm_mon, 9); + EXPECT_EQ(t.tm_mday, 25); +} +#endif + +TEST(ScanTest, InvalidFormat) { + EXPECT_THROW_MSG(fmt::scan("", "{}"), fmt::format_error, + "argument index out of range"); + EXPECT_THROW_MSG(fmt::scan("", "{"), fmt::format_error, + "invalid format string"); +} + +TEST(ScanTest, Example) { + std::string key; + int value; + fmt::scan("answer = 42", "{} = {}", key, value); + EXPECT_EQ(key, "answer"); + EXPECT_EQ(value, 42); +} diff --git a/contrib/libs/fmt/test/scan-test/ya.make b/contrib/libs/fmt/test/scan-test/ya.make index d8219e04b9..2a3a49bd9a 100644 --- a/contrib/libs/fmt/test/scan-test/ya.make +++ b/contrib/libs/fmt/test/scan-test/ya.make @@ -1,37 +1,37 @@ -# Generated by devtools/yamaker. - +# Generated by devtools/yamaker. + GTEST() - + WITHOUT_LICENSE_TEXTS() - + OWNER( orivej g:cpp-contrib ) -LICENSE(MIT) - -PEERDIR( - contrib/libs/fmt - contrib/libs/fmt/test -) - -NO_COMPILER_WARNINGS() - -NO_UTIL() - -CFLAGS( - -DFMT_LOCALE - -DFMT_SHARED - -DGTEST_HAS_STD_WSTRING=1 - -DGTEST_LANG_CXX11=0 - -D_SILENCE_TR1_NAMESPACE_DEPRECATION_WARNING=1 -) - -SRCDIR(contrib/libs/fmt/test) - -SRCS( - scan-test.cc -) - -END() +LICENSE(MIT) + +PEERDIR( + contrib/libs/fmt + contrib/libs/fmt/test +) + +NO_COMPILER_WARNINGS() + +NO_UTIL() + +CFLAGS( + -DFMT_LOCALE + -DFMT_SHARED + -DGTEST_HAS_STD_WSTRING=1 + -DGTEST_LANG_CXX11=0 + -D_SILENCE_TR1_NAMESPACE_DEPRECATION_WARNING=1 +) + +SRCDIR(contrib/libs/fmt/test) + +SRCS( + scan-test.cc +) + +END() diff --git a/contrib/libs/fmt/test/scan.h b/contrib/libs/fmt/test/scan.h index c4faf54863..de82067a49 100644 --- a/contrib/libs/fmt/test/scan.h +++ b/contrib/libs/fmt/test/scan.h @@ -1,238 +1,238 @@ -// Formatting library for C++ - scanning API proof of concept -// -// Copyright (c) 2019 - present, Victor Zverovich -// All rights reserved. -// -// For the license information refer to format.h. - -#include <array> -#include <cassert> -#include <climits> - -#include "fmt/format.h" - -FMT_BEGIN_NAMESPACE -template <typename T, typename Char = char> struct scanner { - // A deleted default constructor indicates a disabled scanner. - scanner() = delete; -}; - -class scan_parse_context { - private: - string_view format_; - - public: - using iterator = string_view::iterator; - - explicit FMT_CONSTEXPR scan_parse_context(string_view format) - : format_(format) {} - - FMT_CONSTEXPR iterator begin() const { return format_.begin(); } - FMT_CONSTEXPR iterator end() const { return format_.end(); } - - void advance_to(iterator it) { +// Formatting library for C++ - scanning API proof of concept +// +// Copyright (c) 2019 - present, Victor Zverovich +// All rights reserved. +// +// For the license information refer to format.h. + +#include <array> +#include <cassert> +#include <climits> + +#include "fmt/format.h" + +FMT_BEGIN_NAMESPACE +template <typename T, typename Char = char> struct scanner { + // A deleted default constructor indicates a disabled scanner. + scanner() = delete; +}; + +class scan_parse_context { + private: + string_view format_; + + public: + using iterator = string_view::iterator; + + explicit FMT_CONSTEXPR scan_parse_context(string_view format) + : format_(format) {} + + FMT_CONSTEXPR iterator begin() const { return format_.begin(); } + FMT_CONSTEXPR iterator end() const { return format_.end(); } + + void advance_to(iterator it) { format_.remove_prefix(detail::to_unsigned(it - begin())); - } -}; - -struct scan_context { - private: - string_view input_; - - public: - using iterator = const char*; - - explicit scan_context(string_view input) : input_(input) {} - - iterator begin() const { return input_.data(); } - iterator end() const { return begin() + input_.size(); } - - void advance_to(iterator it) { + } +}; + +struct scan_context { + private: + string_view input_; + + public: + using iterator = const char*; + + explicit scan_context(string_view input) : input_(input) {} + + iterator begin() const { return input_.data(); } + iterator end() const { return begin() + input_.size(); } + + void advance_to(iterator it) { input_.remove_prefix(detail::to_unsigned(it - begin())); - } -}; - + } +}; + namespace detail { -enum class scan_type { - none_type, - int_type, - uint_type, - long_long_type, - ulong_long_type, - string_type, - string_view_type, - custom_type -}; - -struct custom_scan_arg { - void* value; - void (*scan)(void* arg, scan_parse_context& parse_ctx, scan_context& ctx); -}; - -class scan_arg { - public: - scan_type type; - union { - int* int_value; - unsigned* uint_value; - long long* long_long_value; - unsigned long long* ulong_long_value; - std::string* string; - fmt::string_view* string_view; - custom_scan_arg custom; - // TODO: more types - }; - - scan_arg() : type(scan_type::none_type) {} - scan_arg(int& value) : type(scan_type::int_type), int_value(&value) {} - scan_arg(unsigned& value) : type(scan_type::uint_type), uint_value(&value) {} - scan_arg(long long& value) - : type(scan_type::long_long_type), long_long_value(&value) {} - scan_arg(unsigned long long& value) - : type(scan_type::ulong_long_type), ulong_long_value(&value) {} - scan_arg(std::string& value) : type(scan_type::string_type), string(&value) {} - scan_arg(fmt::string_view& value) - : type(scan_type::string_view_type), string_view(&value) {} - template <typename T> scan_arg(T& value) : type(scan_type::custom_type) { - custom.value = &value; - custom.scan = scan_custom_arg<T>; - } - - private: - template <typename T> - static void scan_custom_arg(void* arg, scan_parse_context& parse_ctx, - scan_context& ctx) { - scanner<T> s; - parse_ctx.advance_to(s.parse(parse_ctx)); - ctx.advance_to(s.scan(*static_cast<T*>(arg), ctx)); - } -}; +enum class scan_type { + none_type, + int_type, + uint_type, + long_long_type, + ulong_long_type, + string_type, + string_view_type, + custom_type +}; + +struct custom_scan_arg { + void* value; + void (*scan)(void* arg, scan_parse_context& parse_ctx, scan_context& ctx); +}; + +class scan_arg { + public: + scan_type type; + union { + int* int_value; + unsigned* uint_value; + long long* long_long_value; + unsigned long long* ulong_long_value; + std::string* string; + fmt::string_view* string_view; + custom_scan_arg custom; + // TODO: more types + }; + + scan_arg() : type(scan_type::none_type) {} + scan_arg(int& value) : type(scan_type::int_type), int_value(&value) {} + scan_arg(unsigned& value) : type(scan_type::uint_type), uint_value(&value) {} + scan_arg(long long& value) + : type(scan_type::long_long_type), long_long_value(&value) {} + scan_arg(unsigned long long& value) + : type(scan_type::ulong_long_type), ulong_long_value(&value) {} + scan_arg(std::string& value) : type(scan_type::string_type), string(&value) {} + scan_arg(fmt::string_view& value) + : type(scan_type::string_view_type), string_view(&value) {} + template <typename T> scan_arg(T& value) : type(scan_type::custom_type) { + custom.value = &value; + custom.scan = scan_custom_arg<T>; + } + + private: + template <typename T> + static void scan_custom_arg(void* arg, scan_parse_context& parse_ctx, + scan_context& ctx) { + scanner<T> s; + parse_ctx.advance_to(s.parse(parse_ctx)); + ctx.advance_to(s.scan(*static_cast<T*>(arg), ctx)); + } +}; } // namespace detail - -struct scan_args { - int size; + +struct scan_args { + int size; const detail::scan_arg* data; - - template <size_t N> + + template <size_t N> scan_args(const std::array<detail::scan_arg, N>& store) - : size(N), data(store.data()) { - static_assert(N < INT_MAX, "too many arguments"); - } -}; - + : size(N), data(store.data()) { + static_assert(N < INT_MAX, "too many arguments"); + } +}; + namespace detail { - -struct scan_handler : error_handler { - private: - scan_parse_context parse_ctx_; - scan_context scan_ctx_; - scan_args args_; - int next_arg_id_; - scan_arg arg_; - - template <typename T = unsigned> T read_uint() { - T value = 0; - auto it = scan_ctx_.begin(), end = scan_ctx_.end(); - while (it != end) { - char c = *it++; - if (c < '0' || c > '9') on_error("invalid input"); - // TODO: check overflow - value = value * 10 + static_cast<unsigned>(c - '0'); - } - scan_ctx_.advance_to(it); - return value; - } - - template <typename T = int> T read_int() { - auto it = scan_ctx_.begin(), end = scan_ctx_.end(); - bool negative = it != end && *it == '-'; - if (negative) ++it; - scan_ctx_.advance_to(it); - const auto value = read_uint<typename std::make_unsigned<T>::type>(); - if (negative) return -static_cast<T>(value); - return static_cast<T>(value); - } - - public: - scan_handler(string_view format, string_view input, scan_args args) - : parse_ctx_(format), scan_ctx_(input), args_(args), next_arg_id_(0) {} - - const char* pos() const { return scan_ctx_.begin(); } - - void on_text(const char* begin, const char* end) { - auto size = to_unsigned(end - begin); - auto it = scan_ctx_.begin(); - if (it + size > scan_ctx_.end() || - !std::equal(begin, end, make_checked(it, size))) { - on_error("invalid input"); - } - scan_ctx_.advance_to(it + size); - } - + +struct scan_handler : error_handler { + private: + scan_parse_context parse_ctx_; + scan_context scan_ctx_; + scan_args args_; + int next_arg_id_; + scan_arg arg_; + + template <typename T = unsigned> T read_uint() { + T value = 0; + auto it = scan_ctx_.begin(), end = scan_ctx_.end(); + while (it != end) { + char c = *it++; + if (c < '0' || c > '9') on_error("invalid input"); + // TODO: check overflow + value = value * 10 + static_cast<unsigned>(c - '0'); + } + scan_ctx_.advance_to(it); + return value; + } + + template <typename T = int> T read_int() { + auto it = scan_ctx_.begin(), end = scan_ctx_.end(); + bool negative = it != end && *it == '-'; + if (negative) ++it; + scan_ctx_.advance_to(it); + const auto value = read_uint<typename std::make_unsigned<T>::type>(); + if (negative) return -static_cast<T>(value); + return static_cast<T>(value); + } + + public: + scan_handler(string_view format, string_view input, scan_args args) + : parse_ctx_(format), scan_ctx_(input), args_(args), next_arg_id_(0) {} + + const char* pos() const { return scan_ctx_.begin(); } + + void on_text(const char* begin, const char* end) { + auto size = to_unsigned(end - begin); + auto it = scan_ctx_.begin(); + if (it + size > scan_ctx_.end() || + !std::equal(begin, end, make_checked(it, size))) { + on_error("invalid input"); + } + scan_ctx_.advance_to(it + size); + } + int on_arg_id() { return on_arg_id(next_arg_id_++); } int on_arg_id(int id) { - if (id >= args_.size) on_error("argument index out of range"); - arg_ = args_.data[id]; + if (id >= args_.size) on_error("argument index out of range"); + arg_ = args_.data[id]; return id; - } + } int on_arg_id(string_view) { return on_error("invalid format"), 0; } - + void on_replacement_field(int, const char*) { - auto it = scan_ctx_.begin(), end = scan_ctx_.end(); - switch (arg_.type) { - case scan_type::int_type: - *arg_.int_value = read_int(); - break; - case scan_type::uint_type: - *arg_.uint_value = read_uint(); - break; - case scan_type::long_long_type: - *arg_.long_long_value = read_int<long long>(); - break; - case scan_type::ulong_long_type: - *arg_.ulong_long_value = read_uint<unsigned long long>(); - break; - case scan_type::string_type: - while (it != end && *it != ' ') arg_.string->push_back(*it++); - scan_ctx_.advance_to(it); - break; - case scan_type::string_view_type: { - auto s = it; - while (it != end && *it != ' ') ++it; - *arg_.string_view = fmt::string_view(s, to_unsigned(it - s)); - scan_ctx_.advance_to(it); - break; - } - case scan_type::none_type: - case scan_type::custom_type: - assert(false); - } - } - + auto it = scan_ctx_.begin(), end = scan_ctx_.end(); + switch (arg_.type) { + case scan_type::int_type: + *arg_.int_value = read_int(); + break; + case scan_type::uint_type: + *arg_.uint_value = read_uint(); + break; + case scan_type::long_long_type: + *arg_.long_long_value = read_int<long long>(); + break; + case scan_type::ulong_long_type: + *arg_.ulong_long_value = read_uint<unsigned long long>(); + break; + case scan_type::string_type: + while (it != end && *it != ' ') arg_.string->push_back(*it++); + scan_ctx_.advance_to(it); + break; + case scan_type::string_view_type: { + auto s = it; + while (it != end && *it != ' ') ++it; + *arg_.string_view = fmt::string_view(s, to_unsigned(it - s)); + scan_ctx_.advance_to(it); + break; + } + case scan_type::none_type: + case scan_type::custom_type: + assert(false); + } + } + const char* on_format_specs(int, const char* begin, const char*) { - if (arg_.type != scan_type::custom_type) return begin; - parse_ctx_.advance_to(begin); - arg_.custom.scan(arg_.custom.value, parse_ctx_, scan_ctx_); - return parse_ctx_.begin(); - } -}; + if (arg_.type != scan_type::custom_type) return begin; + parse_ctx_.advance_to(begin); + arg_.custom.scan(arg_.custom.value, parse_ctx_, scan_ctx_); + return parse_ctx_.begin(); + } +}; } // namespace detail - -template <typename... Args> + +template <typename... Args> std::array<detail::scan_arg, sizeof...(Args)> make_scan_args(Args&... args) { - return {{args...}}; -} - -string_view::iterator vscan(string_view input, string_view format_str, - scan_args args) { + return {{args...}}; +} + +string_view::iterator vscan(string_view input, string_view format_str, + scan_args args) { detail::scan_handler h(format_str, input, args); detail::parse_format_string<false>(format_str, h); - return input.begin() + (h.pos() - &*input.begin()); -} - -template <typename... Args> -string_view::iterator scan(string_view input, string_view format_str, - Args&... args) { - return vscan(input, format_str, make_scan_args(args...)); -} -FMT_END_NAMESPACE + return input.begin() + (h.pos() - &*input.begin()); +} + +template <typename... Args> +string_view::iterator scan(string_view input, string_view format_str, + Args&... args) { + return vscan(input, format_str, make_scan_args(args...)); +} +FMT_END_NAMESPACE diff --git a/contrib/libs/fmt/test/test-assert.h b/contrib/libs/fmt/test/test-assert.h index 0eb7215ee4..f9df580539 100644 --- a/contrib/libs/fmt/test/test-assert.h +++ b/contrib/libs/fmt/test/test-assert.h @@ -1,32 +1,32 @@ -// Formatting library for C++ - test version of FMT_ASSERT -// -// Copyright (c) 2012 - present, Victor Zverovich -// All rights reserved. -// -// For the license information refer to format.h. - -#ifndef FMT_TEST_ASSERT_H_ -#define FMT_TEST_ASSERT_H_ - -#include <stdexcept> - -#include <gtest/gtest.h> - -class assertion_failure : public std::logic_error { - public: - explicit assertion_failure(const char* message) : std::logic_error(message) {} - - private: - virtual void avoid_weak_vtable(); -}; - -void assertion_failure::avoid_weak_vtable() {} - -#define FMT_ASSERT(condition, message) \ - if (!(condition)) throw assertion_failure(message); - -// Expects an assertion failure. -#define EXPECT_ASSERT(stmt, message) \ - FMT_TEST_THROW_(stmt, assertion_failure, message, GTEST_NONFATAL_FAILURE_) - -#endif // FMT_TEST_ASSERT_H_ +// Formatting library for C++ - test version of FMT_ASSERT +// +// Copyright (c) 2012 - present, Victor Zverovich +// All rights reserved. +// +// For the license information refer to format.h. + +#ifndef FMT_TEST_ASSERT_H_ +#define FMT_TEST_ASSERT_H_ + +#include <stdexcept> + +#include <gtest/gtest.h> + +class assertion_failure : public std::logic_error { + public: + explicit assertion_failure(const char* message) : std::logic_error(message) {} + + private: + virtual void avoid_weak_vtable(); +}; + +void assertion_failure::avoid_weak_vtable() {} + +#define FMT_ASSERT(condition, message) \ + if (!(condition)) throw assertion_failure(message); + +// Expects an assertion failure. +#define EXPECT_ASSERT(stmt, message) \ + FMT_TEST_THROW_(stmt, assertion_failure, message, GTEST_NONFATAL_FAILURE_) + +#endif // FMT_TEST_ASSERT_H_ diff --git a/contrib/libs/fmt/test/util.cc b/contrib/libs/fmt/test/util.cc index 116e8a3a0a..d08dcbdcbf 100644 --- a/contrib/libs/fmt/test/util.cc +++ b/contrib/libs/fmt/test/util.cc @@ -1,50 +1,50 @@ -// Formatting library for C++ - test utilities -// -// Copyright (c) 2012 - present, Victor Zverovich -// All rights reserved. -// -// For the license information refer to format.h. - -#include "util.h" +// Formatting library for C++ - test utilities +// +// Copyright (c) 2012 - present, Victor Zverovich +// All rights reserved. +// +// For the license information refer to format.h. -#include <cstring> - -void increment(char* s) { - for (int i = static_cast<int>(std::strlen(s)) - 1; i >= 0; --i) { - if (s[i] != '9') { - ++s[i]; - break; - } - s[i] = '0'; - } -} - -std::string get_system_error(int error_code) { -#if defined(__MINGW32__) || !defined(_WIN32) - return strerror(error_code); -#else - enum { BUFFER_SIZE = 200 }; - char buffer[BUFFER_SIZE]; - if (strerror_s(buffer, BUFFER_SIZE, error_code)) - throw std::exception("strerror_s failed"); - return buffer; -#endif -} - -const char* const FILE_CONTENT = "Don't panic!"; - -fmt::buffered_file open_buffered_file(FILE** fp) { -#if FMT_USE_FCNTL - fmt::file read_end, write_end; - fmt::file::pipe(read_end, write_end); - write_end.write(FILE_CONTENT, std::strlen(FILE_CONTENT)); - write_end.close(); - fmt::buffered_file f = read_end.fdopen("r"); - if (fp) *fp = f.get(); -#else - fmt::buffered_file f("test-file", "w"); - fputs(FILE_CONTENT, f.get()); - if (fp) *fp = f.get(); -#endif - return f; -} +#include "util.h" + +#include <cstring> + +void increment(char* s) { + for (int i = static_cast<int>(std::strlen(s)) - 1; i >= 0; --i) { + if (s[i] != '9') { + ++s[i]; + break; + } + s[i] = '0'; + } +} + +std::string get_system_error(int error_code) { +#if defined(__MINGW32__) || !defined(_WIN32) + return strerror(error_code); +#else + enum { BUFFER_SIZE = 200 }; + char buffer[BUFFER_SIZE]; + if (strerror_s(buffer, BUFFER_SIZE, error_code)) + throw std::exception("strerror_s failed"); + return buffer; +#endif +} + +const char* const FILE_CONTENT = "Don't panic!"; + +fmt::buffered_file open_buffered_file(FILE** fp) { +#if FMT_USE_FCNTL + fmt::file read_end, write_end; + fmt::file::pipe(read_end, write_end); + write_end.write(FILE_CONTENT, std::strlen(FILE_CONTENT)); + write_end.close(); + fmt::buffered_file f = read_end.fdopen("r"); + if (fp) *fp = f.get(); +#else + fmt::buffered_file f("test-file", "w"); + fputs(FILE_CONTENT, f.get()); + if (fp) *fp = f.get(); +#endif + return f; +} diff --git a/contrib/libs/fmt/test/util.h b/contrib/libs/fmt/test/util.h index ad3b999d38..24a5f4e34b 100644 --- a/contrib/libs/fmt/test/util.h +++ b/contrib/libs/fmt/test/util.h @@ -1,84 +1,84 @@ -// Formatting library for C++ - test utilities -// -// Copyright (c) 2012 - present, Victor Zverovich -// All rights reserved. -// -// For the license information refer to format.h. - -#include <cstdarg> -#include <cstdio> -#include <string> - -#include "fmt/os.h" - -enum { BUFFER_SIZE = 256 }; - -#ifdef _MSC_VER -# define FMT_VSNPRINTF vsprintf_s -#else -# define FMT_VSNPRINTF vsnprintf -#endif - +// Formatting library for C++ - test utilities +// +// Copyright (c) 2012 - present, Victor Zverovich +// All rights reserved. +// +// For the license information refer to format.h. + +#include <cstdarg> +#include <cstdio> +#include <string> + +#include "fmt/os.h" + +enum { BUFFER_SIZE = 256 }; + +#ifdef _MSC_VER +# define FMT_VSNPRINTF vsprintf_s +#else +# define FMT_VSNPRINTF vsnprintf +#endif + template <size_t SIZE> -void safe_sprintf(char (&buffer)[SIZE], const char* format, ...) { - std::va_list args; - va_start(args, format); - FMT_VSNPRINTF(buffer, SIZE, format, args); - va_end(args); -} - -// Increment a number in a string. -void increment(char* s); - -std::string get_system_error(int error_code); - -extern const char* const FILE_CONTENT; - -// Opens a buffered file for reading. -fmt::buffered_file open_buffered_file(FILE** fp = nullptr); - -inline FILE* safe_fopen(const char* filename, const char* mode) { -#if defined(_WIN32) && !defined(__MINGW32__) - // Fix MSVC warning about "unsafe" fopen. - FILE* f = 0; - errno = fopen_s(&f, filename, mode); - return f; -#else - return std::fopen(filename, mode); -#endif -} - -template <typename Char> class BasicTestString { - private: - std::basic_string<Char> value_; - - static const Char EMPTY[]; - - public: - explicit BasicTestString(const Char* value = EMPTY) : value_(value) {} - - const std::basic_string<Char>& value() const { return value_; } -}; - -template <typename Char> const Char BasicTestString<Char>::EMPTY[] = {0}; - -typedef BasicTestString<char> TestString; -typedef BasicTestString<wchar_t> TestWString; - -template <typename Char> -std::basic_ostream<Char>& operator<<(std::basic_ostream<Char>& os, - const BasicTestString<Char>& s) { - os << s.value(); - return os; -} - -class Date { - int year_, month_, day_; - - public: - Date(int year, int month, int day) : year_(year), month_(month), day_(day) {} - - int year() const { return year_; } - int month() const { return month_; } - int day() const { return day_; } -}; +void safe_sprintf(char (&buffer)[SIZE], const char* format, ...) { + std::va_list args; + va_start(args, format); + FMT_VSNPRINTF(buffer, SIZE, format, args); + va_end(args); +} + +// Increment a number in a string. +void increment(char* s); + +std::string get_system_error(int error_code); + +extern const char* const FILE_CONTENT; + +// Opens a buffered file for reading. +fmt::buffered_file open_buffered_file(FILE** fp = nullptr); + +inline FILE* safe_fopen(const char* filename, const char* mode) { +#if defined(_WIN32) && !defined(__MINGW32__) + // Fix MSVC warning about "unsafe" fopen. + FILE* f = 0; + errno = fopen_s(&f, filename, mode); + return f; +#else + return std::fopen(filename, mode); +#endif +} + +template <typename Char> class BasicTestString { + private: + std::basic_string<Char> value_; + + static const Char EMPTY[]; + + public: + explicit BasicTestString(const Char* value = EMPTY) : value_(value) {} + + const std::basic_string<Char>& value() const { return value_; } +}; + +template <typename Char> const Char BasicTestString<Char>::EMPTY[] = {0}; + +typedef BasicTestString<char> TestString; +typedef BasicTestString<wchar_t> TestWString; + +template <typename Char> +std::basic_ostream<Char>& operator<<(std::basic_ostream<Char>& os, + const BasicTestString<Char>& s) { + os << s.value(); + return os; +} + +class Date { + int year_, month_, day_; + + public: + Date(int year, int month, int day) : year_(year), month_(month), day_(day) {} + + int year() const { return year_; } + int month() const { return month_; } + int day() const { return day_; } +}; diff --git a/contrib/libs/fmt/test/ya.make b/contrib/libs/fmt/test/ya.make index afba712c09..8db82d6c1e 100644 --- a/contrib/libs/fmt/test/ya.make +++ b/contrib/libs/fmt/test/ya.make @@ -1,9 +1,9 @@ -# Generated by devtools/yamaker. - -LIBRARY() - +# Generated by devtools/yamaker. + +LIBRARY() + WITHOUT_LICENSE_TEXTS() - + OWNER( orivej g:cpp-contrib @@ -11,45 +11,45 @@ OWNER( LICENSE(MIT) -PEERDIR( +PEERDIR( contrib/libs/fmt contrib/restricted/googletest/googlemock -) - -NO_COMPILER_WARNINGS() - -NO_UTIL() - -CFLAGS( - -DFMT_LOCALE - -DFMT_SHARED - -DGTEST_HAS_STD_WSTRING=1 - -DGTEST_LANG_CXX11=0 - -D_SILENCE_TR1_NAMESPACE_DEPRECATION_WARNING=1 -) - -SRCS( - gtest-extra.cc - util.cc -) - -END() - -RECURSE( - assert-test - chrono-test - color-test - compile-test - core-test - format-impl-test - format-test - gtest-extra-test - header-only-test - locale-test - os-test - ostream-test - posix-mock-test - printf-test - ranges-test - scan-test -) +) + +NO_COMPILER_WARNINGS() + +NO_UTIL() + +CFLAGS( + -DFMT_LOCALE + -DFMT_SHARED + -DGTEST_HAS_STD_WSTRING=1 + -DGTEST_LANG_CXX11=0 + -D_SILENCE_TR1_NAMESPACE_DEPRECATION_WARNING=1 +) + +SRCS( + gtest-extra.cc + util.cc +) + +END() + +RECURSE( + assert-test + chrono-test + color-test + compile-test + core-test + format-impl-test + format-test + gtest-extra-test + header-only-test + locale-test + os-test + ostream-test + posix-mock-test + printf-test + ranges-test + scan-test +) |