1 /*
2 printf tests.
3
4 Copyright (c) 2012-2014, Victor Zverovich
5 All rights reserved.
6
7 Redistribution and use in source and binary forms, with or without
8 modification, are permitted provided that the following conditions are met:
9
10 1. Redistributions of source code must retain the above copyright notice, this
11 list of conditions and the following disclaimer.
12 2. Redistributions in binary form must reproduce the above copyright notice,
13 this list of conditions and the following disclaimer in the documentation
14 and/or other materials provided with the distribution.
15
16 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
17 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
20 ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28 #include <cctype>
29 #include <climits>
30 #include <cstring>
31
32 #include "fmt/printf.h"
33 #include "fmt/format.h"
34 #include "gtest-extra.h"
35 #include "util.h"
36
37 using fmt::format;
38 using fmt::FormatError;
39
40 const unsigned BIG_NUM = INT_MAX + 1u;
41
42 // Makes format string argument positional.
make_positional(fmt::StringRef format)43 std::string make_positional(fmt::StringRef format) {
44 std::string s(format.to_string());
45 s.replace(s.find('%'), 1, "%1$");
46 return s;
47 }
48
49 #define EXPECT_PRINTF(expected_output, format, arg) \
50 EXPECT_EQ(expected_output, fmt::sprintf(format, arg)) \
51 << "format: " << format; \
52 EXPECT_EQ(expected_output, fmt::sprintf(make_positional(format), arg))
53
TEST(PrintfTest,NoArgs)54 TEST(PrintfTest, NoArgs) {
55 EXPECT_EQ("test", fmt::sprintf("test"));
56 }
57
TEST(PrintfTest,Escape)58 TEST(PrintfTest, Escape) {
59 EXPECT_EQ("%", fmt::sprintf("%%"));
60 EXPECT_EQ("before %", fmt::sprintf("before %%"));
61 EXPECT_EQ("% after", fmt::sprintf("%% after"));
62 EXPECT_EQ("before % after", fmt::sprintf("before %% after"));
63 EXPECT_EQ("%s", fmt::sprintf("%%s"));
64 }
65
TEST(PrintfTest,PositionalArgs)66 TEST(PrintfTest, PositionalArgs) {
67 EXPECT_EQ("42", fmt::sprintf("%1$d", 42));
68 EXPECT_EQ("before 42", fmt::sprintf("before %1$d", 42));
69 EXPECT_EQ("42 after", fmt::sprintf("%1$d after",42));
70 EXPECT_EQ("before 42 after", fmt::sprintf("before %1$d after", 42));
71 EXPECT_EQ("answer = 42", fmt::sprintf("%1$s = %2$d", "answer", 42));
72 EXPECT_EQ("42 is the answer",
73 fmt::sprintf("%2$d is the %1$s", "answer", 42));
74 EXPECT_EQ("abracadabra", fmt::sprintf("%1$s%2$s%1$s", "abra", "cad"));
75 }
76
TEST(PrintfTest,AutomaticArgIndexing)77 TEST(PrintfTest, AutomaticArgIndexing) {
78 EXPECT_EQ("abc", fmt::sprintf("%c%c%c", 'a', 'b', 'c'));
79 }
80
TEST(PrintfTest,NumberIsTooBigInArgIndex)81 TEST(PrintfTest, NumberIsTooBigInArgIndex) {
82 EXPECT_THROW_MSG(fmt::sprintf(format("%{}$", BIG_NUM)),
83 FormatError, "number is too big");
84 EXPECT_THROW_MSG(fmt::sprintf(format("%{}$d", BIG_NUM)),
85 FormatError, "number is too big");
86 }
87
TEST(PrintfTest,SwitchArgIndexing)88 TEST(PrintfTest, SwitchArgIndexing) {
89 EXPECT_THROW_MSG(fmt::sprintf("%1$d%", 1, 2),
90 FormatError, "invalid format string");
91 EXPECT_THROW_MSG(fmt::sprintf(format("%1$d%{}d", BIG_NUM), 1, 2),
92 FormatError, "number is too big");
93 EXPECT_THROW_MSG(fmt::sprintf("%1$d%d", 1, 2),
94 FormatError, "cannot switch from manual to automatic argument indexing");
95
96 EXPECT_THROW_MSG(fmt::sprintf("%d%1$", 1, 2),
97 FormatError, "invalid format string");
98 EXPECT_THROW_MSG(fmt::sprintf(format("%d%{}$d", BIG_NUM), 1, 2),
99 FormatError, "number is too big");
100 EXPECT_THROW_MSG(fmt::sprintf("%d%1$d", 1, 2),
101 FormatError, "cannot switch from automatic to manual argument indexing");
102
103 // Indexing errors override width errors.
104 EXPECT_THROW_MSG(fmt::sprintf(format("%d%1${}d", BIG_NUM), 1, 2),
105 FormatError, "number is too big");
106 EXPECT_THROW_MSG(fmt::sprintf(format("%1$d%{}d", BIG_NUM), 1, 2),
107 FormatError, "number is too big");
108 }
109
TEST(PrintfTest,InvalidArgIndex)110 TEST(PrintfTest, InvalidArgIndex) {
111 EXPECT_THROW_MSG(fmt::sprintf("%0$d", 42), FormatError,
112 "argument index out of range");
113 EXPECT_THROW_MSG(fmt::sprintf("%2$d", 42), FormatError,
114 "argument index out of range");
115 EXPECT_THROW_MSG(fmt::sprintf(format("%{}$d", INT_MAX), 42),
116 FormatError, "argument index out of range");
117
118 EXPECT_THROW_MSG(fmt::sprintf("%2$", 42),
119 FormatError, "invalid format string");
120 EXPECT_THROW_MSG(fmt::sprintf(format("%{}$d", BIG_NUM), 42),
121 FormatError, "number is too big");
122 }
123
TEST(PrintfTest,DefaultAlignRight)124 TEST(PrintfTest, DefaultAlignRight) {
125 EXPECT_PRINTF(" 42", "%5d", 42);
126 EXPECT_PRINTF(" abc", "%5s", "abc");
127 }
128
TEST(PrintfTest,ZeroFlag)129 TEST(PrintfTest, ZeroFlag) {
130 EXPECT_PRINTF("00042", "%05d", 42);
131 EXPECT_PRINTF("-0042", "%05d", -42);
132
133 EXPECT_PRINTF("00042", "%05d", 42);
134 EXPECT_PRINTF("-0042", "%05d", -42);
135 EXPECT_PRINTF("-004.2", "%06g", -4.2);
136
137 EXPECT_PRINTF("+00042", "%00+6d", 42);
138
139 // '0' flag is ignored for non-numeric types.
140 EXPECT_PRINTF(" x", "%05c", 'x');
141 }
142
TEST(PrintfTest,PlusFlag)143 TEST(PrintfTest, PlusFlag) {
144 EXPECT_PRINTF("+42", "%+d", 42);
145 EXPECT_PRINTF("-42", "%+d", -42);
146 EXPECT_PRINTF("+0042", "%+05d", 42);
147 EXPECT_PRINTF("+0042", "%0++5d", 42);
148
149 // '+' flag is ignored for non-numeric types.
150 EXPECT_PRINTF("x", "%+c", 'x');
151 }
152
TEST(PrintfTest,MinusFlag)153 TEST(PrintfTest, MinusFlag) {
154 EXPECT_PRINTF("abc ", "%-5s", "abc");
155 EXPECT_PRINTF("abc ", "%0--5s", "abc");
156 }
157
TEST(PrintfTest,SpaceFlag)158 TEST(PrintfTest, SpaceFlag) {
159 EXPECT_PRINTF(" 42", "% d", 42);
160 EXPECT_PRINTF("-42", "% d", -42);
161 EXPECT_PRINTF(" 0042", "% 05d", 42);
162 EXPECT_PRINTF(" 0042", "%0 5d", 42);
163
164 // ' ' flag is ignored for non-numeric types.
165 EXPECT_PRINTF("x", "% c", 'x');
166 }
167
TEST(PrintfTest,HashFlag)168 TEST(PrintfTest, HashFlag) {
169 EXPECT_PRINTF("042", "%#o", 042);
170 EXPECT_PRINTF(fmt::format("0{:o}", static_cast<unsigned>(-042)), "%#o", -042);
171 EXPECT_PRINTF("0", "%#o", 0);
172
173 EXPECT_PRINTF("0x42", "%#x", 0x42);
174 EXPECT_PRINTF("0X42", "%#X", 0x42);
175 EXPECT_PRINTF(
176 fmt::format("0x{:x}", static_cast<unsigned>(-0x42)), "%#x", -0x42);
177 EXPECT_PRINTF("0", "%#x", 0);
178
179 EXPECT_PRINTF("0x0042", "%#06x", 0x42);
180 EXPECT_PRINTF("0x0042", "%0##6x", 0x42);
181
182 EXPECT_PRINTF("-42.000000", "%#f", -42.0);
183 EXPECT_PRINTF("-42.000000", "%#F", -42.0);
184
185 char buffer[BUFFER_SIZE];
186 safe_sprintf(buffer, "%#e", -42.0);
187 EXPECT_PRINTF(buffer, "%#e", -42.0);
188 safe_sprintf(buffer, "%#E", -42.0);
189 EXPECT_PRINTF(buffer, "%#E", -42.0);
190
191 EXPECT_PRINTF("-42.0000", "%#g", -42.0);
192 EXPECT_PRINTF("-42.0000", "%#G", -42.0);
193
194 safe_sprintf(buffer, "%#a", 16.0);
195 EXPECT_PRINTF(buffer, "%#a", 16.0);
196 safe_sprintf(buffer, "%#A", 16.0);
197 EXPECT_PRINTF(buffer, "%#A", 16.0);
198
199 // '#' flag is ignored for non-numeric types.
200 EXPECT_PRINTF("x", "%#c", 'x');
201 }
202
TEST(PrintfTest,Width)203 TEST(PrintfTest, Width) {
204 EXPECT_PRINTF(" abc", "%5s", "abc");
205
206 // Width cannot be specified twice.
207 EXPECT_THROW_MSG(fmt::sprintf("%5-5d", 42), FormatError,
208 "unknown format code '-' for integer");
209
210 EXPECT_THROW_MSG(fmt::sprintf(format("%{}d", BIG_NUM), 42),
211 FormatError, "number is too big");
212 EXPECT_THROW_MSG(fmt::sprintf(format("%1${}d", BIG_NUM), 42),
213 FormatError, "number is too big");
214 }
215
TEST(PrintfTest,DynamicWidth)216 TEST(PrintfTest, DynamicWidth) {
217 EXPECT_EQ(" 42", fmt::sprintf("%*d", 5, 42));
218 EXPECT_EQ("42 ", fmt::sprintf("%*d", -5, 42));
219 EXPECT_THROW_MSG(fmt::sprintf("%*d", 5.0, 42), FormatError,
220 "width is not integer");
221 EXPECT_THROW_MSG(fmt::sprintf("%*d"), FormatError,
222 "argument index out of range");
223 EXPECT_THROW_MSG(fmt::sprintf("%*d", BIG_NUM, 42), FormatError,
224 "number is too big");
225 }
226
TEST(PrintfTest,IntPrecision)227 TEST(PrintfTest, IntPrecision) {
228 EXPECT_PRINTF("00042", "%.5d", 42);
229 EXPECT_PRINTF("-00042", "%.5d", -42);
230 EXPECT_PRINTF("00042", "%.5x", 0x42);
231 EXPECT_PRINTF("0x00042", "%#.5x", 0x42);
232 EXPECT_PRINTF("00042", "%.5o", 042);
233 EXPECT_PRINTF("00042", "%#.5o", 042);
234
235 EXPECT_PRINTF(" 00042", "%7.5d", 42);
236 EXPECT_PRINTF(" 00042", "%7.5x", 0x42);
237 EXPECT_PRINTF(" 0x00042", "%#10.5x", 0x42);
238 EXPECT_PRINTF(" 00042", "%7.5o", 042);
239 EXPECT_PRINTF(" 00042", "%#10.5o", 042);
240
241 EXPECT_PRINTF("00042 ", "%-7.5d", 42);
242 EXPECT_PRINTF("00042 ", "%-7.5x", 0x42);
243 EXPECT_PRINTF("0x00042 ", "%-#10.5x", 0x42);
244 EXPECT_PRINTF("00042 ", "%-7.5o", 042);
245 EXPECT_PRINTF("00042 ", "%-#10.5o", 042);
246 }
247
TEST(PrintfTest,FloatPrecision)248 TEST(PrintfTest, FloatPrecision) {
249 char buffer[BUFFER_SIZE];
250 safe_sprintf(buffer, "%.3e", 1234.5678);
251 EXPECT_PRINTF(buffer, "%.3e", 1234.5678);
252 EXPECT_PRINTF("1234.568", "%.3f", 1234.5678);
253 safe_sprintf(buffer, "%.3g", 1234.5678);
254 EXPECT_PRINTF(buffer, "%.3g", 1234.5678);
255 safe_sprintf(buffer, "%.3a", 1234.5678);
256 EXPECT_PRINTF(buffer, "%.3a", 1234.5678);
257 }
258
TEST(PrintfTest,IgnorePrecisionForNonNumericArg)259 TEST(PrintfTest, IgnorePrecisionForNonNumericArg) {
260 EXPECT_PRINTF("abc", "%.5s", "abc");
261 }
262
TEST(PrintfTest,DynamicPrecision)263 TEST(PrintfTest, DynamicPrecision) {
264 EXPECT_EQ("00042", fmt::sprintf("%.*d", 5, 42));
265 EXPECT_EQ("42", fmt::sprintf("%.*d", -5, 42));
266 EXPECT_THROW_MSG(fmt::sprintf("%.*d", 5.0, 42), FormatError,
267 "precision is not integer");
268 EXPECT_THROW_MSG(fmt::sprintf("%.*d"), FormatError,
269 "argument index out of range");
270 EXPECT_THROW_MSG(fmt::sprintf("%.*d", BIG_NUM, 42), FormatError,
271 "number is too big");
272 if (sizeof(fmt::LongLong) != sizeof(int)) {
273 fmt::LongLong prec = static_cast<fmt::LongLong>(INT_MIN) - 1;
274 EXPECT_THROW_MSG(fmt::sprintf("%.*d", prec, 42), FormatError,
275 "number is too big");
276 }
277 }
278
279 template <typename T>
280 struct MakeSigned { typedef T Type; };
281
282 #define SPECIALIZE_MAKE_SIGNED(T, S) \
283 template <> \
284 struct MakeSigned<T> { typedef S Type; }
285
286 SPECIALIZE_MAKE_SIGNED(char, signed char);
287 SPECIALIZE_MAKE_SIGNED(unsigned char, signed char);
288 SPECIALIZE_MAKE_SIGNED(unsigned short, short);
289 SPECIALIZE_MAKE_SIGNED(unsigned, int);
290 SPECIALIZE_MAKE_SIGNED(unsigned long, long);
291 SPECIALIZE_MAKE_SIGNED(fmt::ULongLong, fmt::LongLong);
292
293 // Test length format specifier ``length_spec``.
294 template <typename T, typename U>
TestLength(const char * length_spec,U value)295 void TestLength(const char *length_spec, U value) {
296 fmt::LongLong signed_value = 0;
297 fmt::ULongLong unsigned_value = 0;
298 // Apply integer promotion to the argument.
299 using std::numeric_limits;
300 fmt::ULongLong max = numeric_limits<U>::max();
301 using fmt::internal::const_check;
302 if (const_check(max <= static_cast<unsigned>(numeric_limits<int>::max()))) {
303 signed_value = static_cast<int>(value);
304 unsigned_value = static_cast<unsigned>(value);
305 } else if (const_check(max <= numeric_limits<unsigned>::max())) {
306 signed_value = static_cast<unsigned>(value);
307 unsigned_value = static_cast<unsigned>(value);
308 }
309 using fmt::internal::MakeUnsigned;
310 if (sizeof(U) <= sizeof(int) && sizeof(int) < sizeof(T)) {
311 signed_value = static_cast<fmt::LongLong>(value);
312 unsigned_value = static_cast<typename MakeUnsigned<unsigned>::Type>(value);
313 } else {
314 signed_value = static_cast<typename MakeSigned<T>::Type>(value);
315 unsigned_value = static_cast<typename MakeUnsigned<T>::Type>(value);
316 }
317 std::ostringstream os;
318 os << signed_value;
319 EXPECT_PRINTF(os.str(), fmt::format("%{}d", length_spec), value);
320 EXPECT_PRINTF(os.str(), fmt::format("%{}i", length_spec), value);
321 os.str("");
322 os << unsigned_value;
323 EXPECT_PRINTF(os.str(), fmt::format("%{}u", length_spec), value);
324 os.str("");
325 os << std::oct << unsigned_value;
326 EXPECT_PRINTF(os.str(), fmt::format("%{}o", length_spec), value);
327 os.str("");
328 os << std::hex << unsigned_value;
329 EXPECT_PRINTF(os.str(), fmt::format("%{}x", length_spec), value);
330 os.str("");
331 os << std::hex << std::uppercase << unsigned_value;
332 EXPECT_PRINTF(os.str(), fmt::format("%{}X", length_spec), value);
333 }
334
335 template <typename T>
TestLength(const char * length_spec)336 void TestLength(const char *length_spec) {
337 T min = std::numeric_limits<T>::min(), max = std::numeric_limits<T>::max();
338 TestLength<T>(length_spec, 42);
339 TestLength<T>(length_spec, -42);
340 TestLength<T>(length_spec, min);
341 TestLength<T>(length_spec, max);
342 TestLength<T>(length_spec, fmt::LongLong(min) - 1);
343 fmt::ULongLong long_long_max = std::numeric_limits<fmt::LongLong>::max();
344 if (static_cast<fmt::ULongLong>(max) < long_long_max)
345 TestLength<T>(length_spec, fmt::LongLong(max) + 1);
346 TestLength<T>(length_spec, std::numeric_limits<short>::min());
347 TestLength<T>(length_spec, std::numeric_limits<unsigned short>::max());
348 TestLength<T>(length_spec, std::numeric_limits<int>::min());
349 TestLength<T>(length_spec, std::numeric_limits<int>::max());
350 TestLength<T>(length_spec, std::numeric_limits<unsigned>::min());
351 TestLength<T>(length_spec, std::numeric_limits<unsigned>::max());
352 TestLength<T>(length_spec, std::numeric_limits<fmt::LongLong>::min());
353 TestLength<T>(length_spec, std::numeric_limits<fmt::LongLong>::max());
354 TestLength<T>(length_spec, std::numeric_limits<fmt::ULongLong>::min());
355 TestLength<T>(length_spec, std::numeric_limits<fmt::ULongLong>::max());
356 }
357
TEST(PrintfTest,Length)358 TEST(PrintfTest, Length) {
359 TestLength<char>("hh");
360 TestLength<signed char>("hh");
361 TestLength<unsigned char>("hh");
362 TestLength<short>("h");
363 TestLength<unsigned short>("h");
364 TestLength<long>("l");
365 TestLength<unsigned long>("l");
366 TestLength<fmt::LongLong>("ll");
367 TestLength<fmt::ULongLong>("ll");
368 TestLength<intmax_t>("j");
369 TestLength<std::size_t>("z");
370 TestLength<std::ptrdiff_t>("t");
371 long double max = std::numeric_limits<long double>::max();
372 EXPECT_PRINTF(fmt::format("{}", max), "%g", max);
373 EXPECT_PRINTF(fmt::format("{}", max), "%Lg", max);
374 }
375
TEST(PrintfTest,Bool)376 TEST(PrintfTest, Bool) {
377 EXPECT_PRINTF("1", "%d", true);
378 EXPECT_PRINTF("true", "%s", true);
379 }
380
TEST(PrintfTest,Int)381 TEST(PrintfTest, Int) {
382 EXPECT_PRINTF("-42", "%d", -42);
383 EXPECT_PRINTF("-42", "%i", -42);
384 unsigned u = 0 - 42u;
385 EXPECT_PRINTF(fmt::format("{}", u), "%u", -42);
386 EXPECT_PRINTF(fmt::format("{:o}", u), "%o", -42);
387 EXPECT_PRINTF(fmt::format("{:x}", u), "%x", -42);
388 EXPECT_PRINTF(fmt::format("{:X}", u), "%X", -42);
389 }
390
TEST(PrintfTest,LongLong)391 TEST(PrintfTest, LongLong) {
392 // fmt::printf allows passing long long arguments to %d without length
393 // specifiers.
394 fmt::LongLong max = std::numeric_limits<fmt::LongLong>::max();
395 EXPECT_PRINTF(fmt::format("{}", max), "%d", max);
396 }
397
TEST(PrintfTest,Float)398 TEST(PrintfTest, Float) {
399 EXPECT_PRINTF("392.650000", "%f", 392.65);
400 EXPECT_PRINTF("392.650000", "%F", 392.65);
401 char buffer[BUFFER_SIZE];
402 safe_sprintf(buffer, "%e", 392.65);
403 EXPECT_PRINTF(buffer, "%e", 392.65);
404 safe_sprintf(buffer, "%E", 392.65);
405 EXPECT_PRINTF(buffer, "%E", 392.65);
406 EXPECT_PRINTF("392.65", "%g", 392.65);
407 EXPECT_PRINTF("392.65", "%G", 392.65);
408 safe_sprintf(buffer, "%a", -392.65);
409 EXPECT_EQ(buffer, format("{:a}", -392.65));
410 safe_sprintf(buffer, "%A", -392.65);
411 EXPECT_EQ(buffer, format("{:A}", -392.65));
412 }
413
TEST(PrintfTest,Inf)414 TEST(PrintfTest, Inf) {
415 double inf = std::numeric_limits<double>::infinity();
416 for (const char* type = "fega"; *type; ++type) {
417 EXPECT_PRINTF("inf", fmt::format("%{}", *type), inf);
418 char upper = std::toupper(*type);
419 EXPECT_PRINTF("INF", fmt::format("%{}", upper), inf);
420 }
421 }
422
TEST(PrintfTest,Char)423 TEST(PrintfTest, Char) {
424 EXPECT_PRINTF("x", "%c", 'x');
425 int max = std::numeric_limits<int>::max();
426 EXPECT_PRINTF(fmt::format("{}", static_cast<char>(max)), "%c", max);
427 //EXPECT_PRINTF("x", "%lc", L'x');
428 // TODO: test wchar_t
429 }
430
TEST(PrintfTest,String)431 TEST(PrintfTest, String) {
432 EXPECT_PRINTF("abc", "%s", "abc");
433 const char *null_str = 0;
434 EXPECT_PRINTF("(null)", "%s", null_str);
435 EXPECT_PRINTF(" (null)", "%10s", null_str);
436 // TODO: wide string
437 }
438
TEST(PrintfTest,Pointer)439 TEST(PrintfTest, Pointer) {
440 int n;
441 void *p = &n;
442 EXPECT_PRINTF(fmt::format("{}", p), "%p", p);
443 p = 0;
444 EXPECT_PRINTF("(nil)", "%p", p);
445 EXPECT_PRINTF(" (nil)", "%10p", p);
446 const char *s = "test";
447 EXPECT_PRINTF(fmt::format("{:p}", s), "%p", s);
448 const char *null_str = 0;
449 EXPECT_PRINTF("(nil)", "%p", null_str);
450 }
451
TEST(PrintfTest,Location)452 TEST(PrintfTest, Location) {
453 // TODO: test %n
454 }
455
456 enum E { A = 42 };
457
TEST(PrintfTest,Enum)458 TEST(PrintfTest, Enum) {
459 EXPECT_PRINTF("42", "%d", A);
460 }
461
462 #if FMT_USE_FILE_DESCRIPTORS
TEST(PrintfTest,Examples)463 TEST(PrintfTest, Examples) {
464 const char *weekday = "Thursday";
465 const char *month = "August";
466 int day = 21;
467 EXPECT_WRITE(stdout, fmt::printf("%1$s, %3$d %2$s", weekday, month, day),
468 "Thursday, 21 August");
469 }
470
TEST(PrintfTest,PrintfError)471 TEST(PrintfTest, PrintfError) {
472 fmt::File read_end, write_end;
473 fmt::File::pipe(read_end, write_end);
474 int result = fmt::fprintf(read_end.fdopen("r").get(), "test");
475 EXPECT_LT(result, 0);
476 }
477 #endif
478
TEST(PrintfTest,WideString)479 TEST(PrintfTest, WideString) {
480 EXPECT_EQ(L"abc", fmt::sprintf(L"%s", L"abc"));
481 }
482
TEST(PrintfTest,PrintfCustom)483 TEST(PrintfTest, PrintfCustom) {
484 EXPECT_EQ("abc", fmt::sprintf("%s", TestString("abc")));
485 }
486
TEST(PrintfTest,OStream)487 TEST(PrintfTest, OStream) {
488 std::ostringstream os;
489 int ret = fmt::fprintf(os, "Don't %s!", "panic");
490 EXPECT_EQ("Don't panic!", os.str());
491 EXPECT_EQ(12, ret);
492 }
493