7 #include "gmock/gmock.h" 8 #include "gtest/gtest.h" 14 using str_format_internal::FormatArgImpl;
16 using FormatEntryPointTest = ::testing::Test;
20 EXPECT_TRUE(
Format(&sink,
"A format %d", 123));
21 EXPECT_EQ(
"A format 123", sink);
24 ParsedFormat<'d'> pc(
"A format %d");
25 EXPECT_TRUE(
Format(&sink, pc, 123));
26 EXPECT_EQ(
"A format 123", sink);
28 TEST_F(FormatEntryPointTest, UntypedFormat) {
29 constexpr
const char* formats[] = {
33 #if !defined(_MSC_VER) && !defined(__ANDROID__) 35 "complicated multipart %% %1$d format %1$0999d",
38 for (
const char* fmt : formats) {
41 FormatArgImpl arg_123(i);
43 UntypedFormatSpec
format(fmt);
47 snprintf(
buf,
sizeof(
buf), fmt, 123);
52 EXPECT_EQ(actual,
buf);
55 ParsedFormat<'d'> pc(
"A format %d");
60 &out, str_format_internal::UntypedFormatSpecImpl(&pc), {&
arg, 1}));
61 EXPECT_EQ(
"A format 345", out);
64 TEST_F(FormatEntryPointTest, StringFormat) {
70 TEST_F(FormatEntryPointTest, AppendFormat) {
77 TEST_F(FormatEntryPointTest, AppendFormatFail) {
78 std::string s =
"orig";
80 UntypedFormatSpec
format(
" more %d");
81 FormatArgImpl
arg(
"not an int");
90 TEST_F(FormatEntryPointTest, ManyArgs) {
91 EXPECT_EQ(
"24",
StrFormat(
"%24$d", 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,
92 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24));
93 EXPECT_EQ(
"60",
StrFormat(
"%60$d", 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,
94 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26,
95 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39,
96 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52,
97 53, 54, 55, 56, 57, 58, 59, 60));
100 TEST_F(FormatEntryPointTest, Preparsed) {
101 ParsedFormat<'d'> pc(
"%d");
104 EXPECT_EQ(
"123",
StrFormat(ParsedFormat<'d'>(
"%d"), 123));
106 EXPECT_EQ(
"=123=",
StrFormat(ParsedFormat<'d'>(view), 123));
109 TEST_F(FormatEntryPointTest, FormatCountCapture) {
111 EXPECT_EQ(
"",
StrFormat(
"%n", FormatCountCapture(&n)));
113 EXPECT_EQ(
"123",
StrFormat(
"%d%n", 123, FormatCountCapture(&n)));
117 TEST_F(FormatEntryPointTest, FormatCountCaptureWrongType) {
120 UntypedFormatSpec
format(
"%d%n");
121 int i = 123, *ip = &
n;
122 FormatArgImpl args[2] = {FormatArgImpl(i), FormatArgImpl(ip)};
129 TEST_F(FormatEntryPointTest, FormatCountCaptureMultiple) {
133 StrFormat(
"%5d%n%10d%n", 1, FormatCountCapture(&n1), 2,
134 FormatCountCapture(&n2)));
139 TEST_F(FormatEntryPointTest, FormatCountCaptureExample) {
142 StrAppendFormat(&s,
"%s: %n%s\n",
"(1,1)", FormatCountCapture(&n),
"(1,2)");
151 TEST_F(FormatEntryPointTest, Stream) {
152 const std::string formats[] = {
156 #if !defined(_MSC_VER) && !defined(__ANDROID__) 158 "complicated multipart %% %1$d format %1$080d",
161 std::string
buf(4096,
'\0');
162 for (
const auto& fmt : formats) {
164 std::ostringstream oss;
166 int fmt_result = snprintf(&*
buf.begin(),
buf.size(), fmt.c_str(), 123);
167 ASSERT_TRUE(oss) << fmt;
168 ASSERT_TRUE(fmt_result >= 0 && static_cast<size_t>(fmt_result) <
buf.size())
170 EXPECT_EQ(
buf.c_str(), oss.str());
174 TEST_F(FormatEntryPointTest, StreamOk) {
175 std::ostringstream oss;
177 EXPECT_EQ(
"hello 123", oss.str());
178 EXPECT_TRUE(oss.good());
181 TEST_F(FormatEntryPointTest, StreamFail) {
182 std::ostringstream oss;
183 UntypedFormatSpec
format(
"hello %d");
184 FormatArgImpl
arg(
"non-numeric");
185 oss << str_format_internal::Streamable(
187 EXPECT_EQ(
"hello ", oss.str());
188 EXPECT_TRUE(oss.fail());
191 std::string WithSnprintf(
const char* fmt, ...) {
196 int r = vsnprintf(&*buf.begin(), buf.size(), fmt, va);
199 EXPECT_LT(r, buf.size());
204 TEST_F(FormatEntryPointTest, FloatPrecisionArg) {
208 EXPECT_EQ(
"0.1",
StrFormat(
"%.1f", 0.1));
209 EXPECT_EQ(
"0.1", WithSnprintf(
"%.1f", 0.1));
210 EXPECT_EQ(
" 0.1",
StrFormat(
"%*.1f", 5, 0.1));
211 EXPECT_EQ(
" 0.1", WithSnprintf(
"%*.1f", 5, 0.1));
212 EXPECT_EQ(
"0.1",
StrFormat(
"%.*f", 1, 0.1));
213 EXPECT_EQ(
"0.1", WithSnprintf(
"%.*f", 1, 0.1));
214 EXPECT_EQ(
" 0.1",
StrFormat(
"%*.*f", 5, 1, 0.1));
215 EXPECT_EQ(
" 0.1", WithSnprintf(
"%*.*f", 5, 1, 0.1));
217 namespace streamed_test {
219 std::ostream&
operator<<(std::ostream& os,
const X&) {
236 TempFile() :
file_(std::tmpfile()) {}
237 ~TempFile() { std::fclose(
file_); }
239 std::FILE* file()
const {
return file_; }
242 std::string ReadFile() {
243 std::fseek(
file_, 0, SEEK_END);
247 std::string str(2 * size,
' ');
248 int read_bytes = std::fread(&str[0], 1, str.size(),
file_);
249 EXPECT_EQ(read_bytes, size);
250 str.resize(read_bytes);
251 EXPECT_TRUE(std::feof(
file_));
262 FPrintF(tmp.file(),
"STRING: %s NUMBER: %010d", std::string(
"ABC"), -19);
263 EXPECT_EQ(result, 30);
264 EXPECT_EQ(tmp.ReadFile(),
"STRING: ABC NUMBER: -000000019");
267 TEST_F(FormatEntryPointTest, FPrintFError) {
269 int result =
FPrintF(stdin,
"ABC");
270 EXPECT_LT(result, 0);
271 EXPECT_EQ(errno, EBADF);
275 TEST_F(FormatEntryPointTest, FprintfTooLarge) {
276 std::FILE* f = std::fopen(
"/dev/null",
"w");
277 int width = 2000000000;
279 int result =
FPrintF(f,
"%*d %*d", width, 0, width, 0);
280 EXPECT_LT(result, 0);
281 EXPECT_EQ(errno, EFBIG);
286 int stdout_tmp = dup(STDOUT_FILENO);
290 dup2(fileno(tmp.file()), STDOUT_FILENO);
292 int result =
PrintF(
"STRING: %s NUMBER: %010d", std::string(
"ABC"), -19);
295 dup2(stdout_tmp, STDOUT_FILENO);
298 EXPECT_EQ(result, 30);
299 EXPECT_EQ(tmp.ReadFile(),
"STRING: ABC NUMBER: -000000019");
306 SNPrintF(buffer,
sizeof(buffer),
"STRING: %s", std::string(
"ABC"));
307 EXPECT_EQ(result, 11);
308 EXPECT_EQ(std::string(buffer),
"STRING: ABC");
310 result =
SNPrintF(buffer,
sizeof(buffer),
"NUMBER: %d", 123456);
311 EXPECT_EQ(result, 14);
312 EXPECT_EQ(std::string(buffer),
"NUMBER: 123456");
314 result =
SNPrintF(buffer,
sizeof(buffer),
"NUMBER: %d", 1234567);
315 EXPECT_EQ(result, 15);
316 EXPECT_EQ(std::string(buffer),
"NUMBER: 1234567");
318 result =
SNPrintF(buffer,
sizeof(buffer),
"NUMBER: %d", 12345678);
319 EXPECT_EQ(result, 16);
320 EXPECT_EQ(std::string(buffer),
"NUMBER: 1234567");
322 result =
SNPrintF(buffer,
sizeof(buffer),
"NUMBER: %d", 123456789);
323 EXPECT_EQ(result, 17);
324 EXPECT_EQ(std::string(buffer),
"NUMBER: 1234567");
326 result =
SNPrintF(
nullptr, 0,
"Just checking the %s of the output.",
"size");
327 EXPECT_EQ(result, 37);
332 EXPECT_EQ(
"Hello, 123!", s);
341 EXPECT_EQ(
StrFormat(
"%c",
int{
'a'}),
"a");
342 EXPECT_EQ(
StrFormat(
"%c",
long{
'a'}),
"a");
343 EXPECT_EQ(
StrFormat(
"%c", uint64_t{
'a'}),
"a");
347 EXPECT_EQ(
StrFormat(
"%s", std::string(
"C++")),
"C++");
348 EXPECT_EQ(
StrFormat(
"%s", string_view(
"view")),
"view");
351 EXPECT_EQ(
StrFormat(
"%d",
char{10}),
"10");
352 EXPECT_EQ(
StrFormat(
"%d",
int{10}),
"10");
353 EXPECT_EQ(
StrFormat(
"%d",
long{10}),
"10");
354 EXPECT_EQ(
StrFormat(
"%d", uint64_t{10}),
"10");
367 EXPECT_EQ(
StrFormat(
"%.1f",
float{1}),
"1.0");
368 EXPECT_EQ(
StrFormat(
"%.1f",
double{1}),
"1.0");
369 const long double long_double = 1.0;
370 EXPECT_EQ(
StrFormat(
"%.1f", long_double),
"1.0");
372 EXPECT_EQ(
StrFormat(
"%.1f",
char{1}),
"1.0");
373 EXPECT_EQ(
StrFormat(
"%.1f",
int{1}),
"1.0");
374 EXPECT_EQ(
StrFormat(
"%.1f",
long{1}),
"1.0");
375 EXPECT_EQ(
StrFormat(
"%.1f", uint64_t{1}),
"1.0");
377 EXPECT_EQ(
StrFormat(
"%f", 123456789),
"123456789.000000");
378 EXPECT_EQ(
StrFormat(
"%F", 123456789),
"123456789.000000");
380 EXPECT_EQ(
StrFormat(
"%e", .01),
"1.000000e-02");
381 EXPECT_EQ(
StrFormat(
"%E", .01),
"1.000000E-02");
384 EXPECT_EQ(
StrFormat(
"%g", 1e10),
"1e+10");
385 EXPECT_EQ(
StrFormat(
"%G", 1e10),
"1E+10");
389 #if !defined(__ANDROID_API__) || __ANDROID_API__ > 21 390 EXPECT_EQ(
StrFormat(
"%.1a", -3.0),
"-0x1.8p+1");
391 EXPECT_EQ(
StrFormat(
"%.1A", -3.0),
"-0X1.8P+1");
395 int64_t
value = 0x7ffdeb4;
396 auto ptr_value =
static_cast<uintptr_t
>(
value);
397 const int& something = *
reinterpret_cast<const int*
>(ptr_value);
402 EXPECT_EQ(
StrFormat(
"%3d", 123456),
"123456");
403 EXPECT_EQ(
StrFormat(
"%06.2f", 1.234),
"001.23");
411 EXPECT_EQ(
absl::StrFormat(
"%2$s, %3$s, %1$s!",
"vici",
"veni",
"vidi"),
412 "veni, vidi, vici!");
414 EXPECT_EQ(
StrFormat(
"%hhd",
int{1}),
"1");
415 EXPECT_EQ(
StrFormat(
"%hd",
int{1}),
"1");
416 EXPECT_EQ(
StrFormat(
"%ld",
int{1}),
"1");
417 EXPECT_EQ(
StrFormat(
"%lld",
int{1}),
"1");
418 EXPECT_EQ(
StrFormat(
"%Ld",
int{1}),
"1");
419 EXPECT_EQ(
StrFormat(
"%jd",
int{1}),
"1");
420 EXPECT_EQ(
StrFormat(
"%zd",
int{1}),
"1");
421 EXPECT_EQ(
StrFormat(
"%td",
int{1}),
"1");
422 EXPECT_EQ(
StrFormat(
"%qd",
int{1}),
"1");
425 using str_format_internal::ExtendedParsedFormat;
428 struct SummarizeConsumer {
430 explicit SummarizeConsumer(std::string* out) : out(out) {}
432 bool Append(string_view s) {
433 *out +=
"[" + std::string(s) +
"]";
437 bool ConvertOne(
const str_format_internal::UnboundConversion& conv,
440 *out += std::string(s);
442 *out += std::to_string(conv.arg_position) +
"$";
443 if (conv.width.is_from_arg()) {
444 *out += std::to_string(conv.width.get_from_arg()) +
"$*";
446 if (conv.precision.is_from_arg()) {
447 *out +=
"." + std::to_string(conv.precision.get_from_arg()) +
"$*";
449 *out += conv.conv.Char();
455 std::string SummarizeParsedFormat(
const ParsedFormatBase& pc) {
457 if (!pc.ProcessFormat(SummarizeConsumer(&out))) out +=
"!";
461 using ParsedFormatTest = ::testing::Test;
463 TEST_F(ParsedFormatTest, SimpleChecked) {
464 EXPECT_EQ(
"[ABC]{d:1$d}[DEF]",
465 SummarizeParsedFormat(ParsedFormat<'d'>(
"ABC%dDEF")));
466 EXPECT_EQ(
"{s:1$s}[FFF]{d:2$d}[ZZZ]{f:3$f}",
467 SummarizeParsedFormat(ParsedFormat<'s', 'd', 'f'>(
"%sFFF%dZZZ%f")));
468 EXPECT_EQ(
"{s:1$s}[ ]{.*d:3$.2$*d}",
469 SummarizeParsedFormat(ParsedFormat<'s', '*', 'd'>(
"%s %.*d")));
472 TEST_F(ParsedFormatTest, SimpleUncheckedCorrect) {
475 EXPECT_EQ(
"[ABC]{d:1$d}[DEF]", SummarizeParsedFormat(*f));
477 std::string
format =
"%sFFF%dZZZ%f";
481 EXPECT_EQ(
"{s:1$s}[FFF]{d:2$d}[ZZZ]{f:3$f}", SummarizeParsedFormat(*f2));
486 EXPECT_EQ(
"{s:1$s}[ ]{d:2$d}[ ]{f:3$f}", SummarizeParsedFormat(*f2));
490 EXPECT_EQ(
"{*d:2$1$*d}", SummarizeParsedFormat(*star));
494 EXPECT_EQ(
"{2$s:2$s}[ ]{1$d:1$d}", SummarizeParsedFormat(*dollar));
498 EXPECT_EQ(
"{2$s:2$s}[ ]{1$d:1$d}[ ]{1$d:1$d}",
499 SummarizeParsedFormat(*dollar));
502 TEST_F(ParsedFormatTest, SimpleUncheckedIgnoredArgs) {
508 EXPECT_EQ(
"[ABC]", SummarizeParsedFormat(*f));
511 EXPECT_EQ(
"{d:1$d}[ABC]", SummarizeParsedFormat(*f));
514 EXPECT_EQ(
"[ABC]{2$s:2$s}", SummarizeParsedFormat(*f));
517 TEST_F(ParsedFormatTest, SimpleUncheckedUnsupported) {
522 TEST_F(ParsedFormatTest, SimpleUncheckedIncorrect) {
527 std::string
format =
"%sFFF%dZZZ%f";
533 TEST_F(ParsedFormatTest, UncheckedCorrect) {
534 auto f = ExtendedParsedFormat<Conv::d>::New(
"ABC%dDEF");
536 EXPECT_EQ(
"[ABC]{d:1$d}[DEF]", SummarizeParsedFormat(*f));
538 std::string
format =
"%sFFF%dZZZ%f";
540 ExtendedParsedFormat<Conv::string, Conv::d, Conv::floating>::New(format);
543 EXPECT_EQ(
"{s:1$s}[FFF]{d:2$d}[ZZZ]{f:3$f}", SummarizeParsedFormat(*f2));
545 f2 = ExtendedParsedFormat<Conv::string, Conv::d, Conv::floating>::New(
549 EXPECT_EQ(
"{s:1$s}[ ]{d:2$d}[ ]{f:3$f}", SummarizeParsedFormat(*f2));
551 auto star = ExtendedParsedFormat<Conv::star, Conv::d>::New(
"%*d");
553 EXPECT_EQ(
"{*d:2$1$*d}", SummarizeParsedFormat(*star));
555 auto dollar = ExtendedParsedFormat<Conv::d, Conv::s>::New(
"%2$s %1$d");
557 EXPECT_EQ(
"{2$s:2$s}[ ]{1$d:1$d}", SummarizeParsedFormat(*dollar));
559 dollar = ExtendedParsedFormat<Conv::d, Conv::s>::New(
"%2$s %1$d %1$d");
561 EXPECT_EQ(
"{2$s:2$s}[ ]{1$d:1$d}[ ]{1$d:1$d}",
562 SummarizeParsedFormat(*dollar));
565 TEST_F(ParsedFormatTest, UncheckedIgnoredArgs) {
566 EXPECT_FALSE((ExtendedParsedFormat<Conv::d, Conv::s>::New(
"ABC")));
567 EXPECT_FALSE((ExtendedParsedFormat<Conv::d, Conv::s>::New(
"%dABC")));
568 EXPECT_FALSE((ExtendedParsedFormat<Conv::d, Conv::s>::New(
"ABC%2$s")));
569 auto f = ExtendedParsedFormat<Conv::d, Conv::s>::NewAllowIgnored(
"ABC");
571 EXPECT_EQ(
"[ABC]", SummarizeParsedFormat(*f));
572 f = ExtendedParsedFormat<Conv::d, Conv::s>::NewAllowIgnored(
"%dABC");
574 EXPECT_EQ(
"{d:1$d}[ABC]", SummarizeParsedFormat(*f));
575 f = ExtendedParsedFormat<Conv::d, Conv::s>::NewAllowIgnored(
"ABC%2$s");
577 EXPECT_EQ(
"[ABC]{2$s:2$s}", SummarizeParsedFormat(*f));
580 TEST_F(ParsedFormatTest, UncheckedMultipleTypes) {
581 auto dx = ExtendedParsedFormat<Conv::d | Conv::x>::New(
"%1$d %1$x");
583 EXPECT_EQ(
"{1$d:1$d}[ ]{1$x:1$x}", SummarizeParsedFormat(*dx));
585 dx = ExtendedParsedFormat<Conv::d | Conv::x>::New(
"%1$d");
587 EXPECT_EQ(
"{1$d:1$d}", SummarizeParsedFormat(*dx));
590 TEST_F(ParsedFormatTest, UncheckedIncorrect) {
591 EXPECT_FALSE(ExtendedParsedFormat<Conv::d>::New(
""));
593 EXPECT_FALSE(ExtendedParsedFormat<Conv::d>::New(
"ABC%dDEF%d"));
595 std::string
format =
"%sFFF%dZZZ%f";
596 EXPECT_FALSE((ExtendedParsedFormat<Conv::s, Conv::d, Conv::g>::New(format)));
599 TEST_F(ParsedFormatTest, RegressionMixPositional) {
600 EXPECT_FALSE((ExtendedParsedFormat<Conv::d, Conv::o>::New(
"%1$d %o")));
603 using FormatWrapperTest = ::testing::Test;
606 template <
typename... Args>
608 const Args&... args) {
612 TEST_F(FormatWrapperTest, ConstexprStringFormat) {
613 EXPECT_EQ(WrappedFormat(
"%s there",
"hello"),
"hello there");
617 ParsedFormat<'s'>
format(
"%s there");
618 EXPECT_EQ(WrappedFormat(format,
"hello"),
"hello there");
641 const std::string& s,
str_format_internal::StreamedWrapper< T > FormatStreamed(const T &v)
ABSL_MUST_USE_RESULT str_format_internal::Streamable StreamFormat(const FormatSpec< Args... > &format, const Args &...args)
TEST(NotificationTest, SanityTest)
std::string & StrAppendFormat(std::string *dst, const FormatSpec< Args... > &format, const Args &...args)
std::ostream & operator<<(std::ostream &os, absl::LogSeverity s)
ABSL_MUST_USE_RESULT bool FormatUntyped(FormatRawSink raw_sink, const UntypedFormatSpec &format, absl::Span< const FormatArg > args)
ABSL_MUST_USE_RESULT std::string StrFormat(const FormatSpec< Args... > &format, const Args &...args)
str_format_internal::FormatArgImpl FormatArg
str_format_internal::ExtendedParsedFormat< str_format_internal::ConversionCharToConv(Conv)... > ParsedFormat
TEST_F(GraphCyclesTest, NoCycle)
std::string format(const std::string &, const time_point< seconds > &, const femtoseconds &, const time_zone &)
int FPrintF(std::FILE *output, const FormatSpec< Args... > &format, const Args &...args)
int PrintF(const FormatSpec< Args... > &format, const Args &...args)
static char * Append(char *out, const AlphaNum &x)
typename str_format_internal::FormatSpecDeductionBarrier< Args... >::type FormatSpec
bool Format(FormatRawSink raw_sink, const FormatSpec< Args... > &format, const Args &...args)
constexpr Span< T > MakeSpan(T *ptr, size_t size) noexcept
int SNPrintF(char *output, std::size_t size, const FormatSpec< Args... > &format, const Args &...args)