diff --git a/test/enforce-compiletime-test.cc b/test/enforce-compiletime-test.cc index 286e3d0e..a335806e 100644 --- a/test/enforce-compiletime-test.cc +++ b/test/enforce-compiletime-test.cc @@ -25,77 +25,41 @@ #include "fmt/ostream.h" #include "fmt/ranges.h" -#undef index +// Exercise the API to verify that everything we expect to can compile. +void TestFormatApi() { + (void)fmt::format(FMT_STRING("noop")); + (void)fmt::format(FMT_STRING("{}"), 42); + (void)fmt::format(FMT_STRING(L"{}"), 42); -#include "gmock.h" -#include "gtest-extra.h" - -TEST(CompileTimeTest, FormatApi) { - EXPECT_EQ("42", fmt::format(FMT_STRING("{}"), 42)); - EXPECT_EQ(L"42", fmt::format(FMT_STRING(L"{}"), 42)); - EXPECT_EQ("42", fmt::to_string(42)); - EXPECT_EQ(L"42", fmt::to_wstring(42)); + (void)fmt::to_string(42); + (void)fmt::to_wstring(42); std::list out; fmt::format_to(std::back_inserter(out), FMT_STRING("{}"), 42); - EXPECT_EQ("42", std::string(out.begin(), out.end())); std::stringstream s; fmt::format_to(std::ostream_iterator(s), FMT_STRING("{}"), 42); - EXPECT_EQ("42", s.str()); -} -#if FMT_USE_UDL_TEMPLATE -// 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(CompileTimeTest, Literals) { - auto udl_format = "{}c{}"_format("ab", 1); - EXPECT_EQ("abc1", udl_format); - auto udl_format_w = L"{}c{}"_format(L"ab", 1); - EXPECT_EQ(L"abc1", udl_format_w); -} -#endif - -TEST(CompileTimeTest, FormattedSize) { - EXPECT_EQ(2u, fmt::formatted_size(FMT_STRING("{}"), 42)); -} - -TEST(CompileTimeTest, FormatTo) { - std::vector v; - fmt::format_to(std::back_inserter(v), FMT_STRING("{}"), "foo"); - EXPECT_EQ(fmt::string_view(v.data(), v.size()), "foo"); -} - -TEST(CompileTimeTest, FormatToN) { char buffer[4]; - buffer[3] = 'x'; - auto result = fmt::format_to_n(buffer, 3, FMT_STRING("{}"), 12345); - EXPECT_EQ(5u, result.size); - EXPECT_EQ(buffer + 3, result.out); - EXPECT_EQ("123x", fmt::string_view(buffer, 4)); -} + (void)fmt::format_to_n(buffer, 3, FMT_STRING("{}"), 12345); -TEST(CompileTimeTest, WideFormatToN) { - wchar_t buffer[4]; - buffer[3] = L'x'; - auto result = fmt::format_to_n(buffer, 3, FMT_STRING(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, FMT_STRING(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, FMT_STRING(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)); + wchar_t wbuffer[4]; + (void)fmt::format_to_n(wbuffer, 3, FMT_STRING(L"{}"), 12345); + + (void)fmt::formatted_size(FMT_STRING("{}"), 42); +} +void TestLiteralsApi() { +#if FMT_USE_UDL_TEMPLATE + // 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; + + auto udl_format = "{}c{}"_format("ab", 1); + auto udl_format_w = L"{}c{}"_format(L"ab", 1); + (void)udl_format; + (void)udl_format_w; +#endif } struct test_output_iterator { @@ -119,53 +83,29 @@ struct test_output_iterator { char& operator*() { return *data; } }; -TEST(CompileTimeTest, FormatToNOutputIterator) { +void FormatToNOutputIteratorTest() { char buf[10] = {}; fmt::format_to_n(test_output_iterator{buf}, 10, FMT_STRING("{}"), 42); - EXPECT_STREQ(buf, "42"); } +void TestChrono() { #ifndef FMT_STATIC_THOUSANDS_SEPARATOR - -TEST(CompileTimeTest, Chrono) { - EXPECT_EQ("42s", fmt::format(FMT_STRING("{}"), std::chrono::seconds(42))); -} - -TEST(CompileTimeTest, ChronoWide) { - EXPECT_EQ(L"42s", fmt::format(FMT_STRING(L"{}"), std::chrono::seconds(42))); -} - + (void)fmt::format(FMT_STRING("{}"), std::chrono::seconds(42)); + (void)fmt::format(FMT_STRING(L"{}"), std::chrono::seconds(42)); #endif // FMT_STATIC_THOUSANDS_SEPARATOR - -TEST(CompileTimeTest, PrintTextStyle) { - EXPECT_WRITE( - stdout, - fmt::print(fg(fmt::rgb(255, 20, 30)), FMT_STRING("{}"), "rgb(255,20,30)"), - "\x1b[38;2;255;020;030mrgb(255,20,30)\x1b[0m"); } -TEST(CompileTimeTest, FormatTextStyle) { - EXPECT_EQ("\x1b[38;2;255;020;030mrgb(255,20,30)\x1b[0m", - fmt::format(fg(fmt::rgb(255, 20, 30)), FMT_STRING("{}"), - "rgb(255,20,30)")); -} +void TestTextStyle() { + fmt::print(fg(fmt::rgb(255, 20, 30)), FMT_STRING("{}"), "rgb(255,20,30)"); + (void)fmt::format(fg(fmt::rgb(255, 20, 30)), FMT_STRING("{}"), + "rgb(255,20,30)"); -TEST(CompileTimeTest, FormatToOutAcceptsTextStyle) { fmt::text_style ts = fg(fmt::rgb(255, 20, 30)); std::string out; fmt::format_to(std::back_inserter(out), ts, FMT_STRING("rgb(255,20,30){}{}{}"), 1, 2, 3); - - EXPECT_EQ(fmt::to_string(out), - "\x1b[38;2;255;020;030mrgb(255,20,30)123\x1b[0m"); } -struct test {}; - -// Check if 'if constexpr' is supported. -#if (__cplusplus > 201402L) || \ - (defined(_MSVC_LANG) && _MSVC_LANG > 201402L && _MSC_VER >= 1910) - struct zstring_sentinel {}; bool operator==(const char* p, zstring_sentinel) { return *p == '\0'; } @@ -177,8 +117,19 @@ struct zstring { zstring_sentinel end() const { return {}; } }; -TEST(CompileTimeTest, JoinSentinel) { +void TestZString() { zstring hello{"hello"}; - EXPECT_EQ("{'h', 'e', 'l', 'l', 'o'}", fmt::format(FMT_STRING("{}"), hello)); - EXPECT_EQ("h_e_l_l_o", fmt::format(FMT_STRING("{}"), fmt::join(hello, "_"))); + (void)fmt::format(FMT_STRING("{}"), hello); + (void)fmt::format(FMT_STRING("{}"), fmt::join(hello, "_")); +} + +int main(int argc, char** argv) { + TestFormatApi(); + TestLiteralsApi(); + FormatToNOutputIteratorTest(); + TestChrono(); + TestTextStyle(); + TestZString(); + + return 0; }