mirror of
https://github.com/fmtlib/fmt.git
synced 2025-07-29 18:27:40 +02:00
Cleanup tests and format string compilation
This commit is contained in:
@ -5,49 +5,38 @@
|
||||
//
|
||||
// For the license information refer to format.h.
|
||||
|
||||
#include <string>
|
||||
#include "fmt/compile.h"
|
||||
|
||||
#include <type_traits>
|
||||
|
||||
// Check that fmt/compile.h compiles with windows.h included before it.
|
||||
#ifdef _WIN32
|
||||
# include <windows.h>
|
||||
#endif
|
||||
|
||||
#include "fmt/chrono.h"
|
||||
#include "fmt/compile.h"
|
||||
#include "gmock/gmock.h"
|
||||
#include "gtest-extra.h"
|
||||
#include "util.h"
|
||||
|
||||
TEST(IteratorTest, TruncatingIterator) {
|
||||
TEST(iterator_test, truncating_iterator) {
|
||||
char* p = nullptr;
|
||||
fmt::detail::truncating_iterator<char*> it(p, 3);
|
||||
auto it = fmt::detail::truncating_iterator<char*>(p, 3);
|
||||
auto prev = it++;
|
||||
EXPECT_EQ(prev.base(), p);
|
||||
EXPECT_EQ(it.base(), p + 1);
|
||||
}
|
||||
|
||||
TEST(IteratorTest, TruncatingIteratorDefaultConstruct) {
|
||||
static_assert(std::is_default_constructible<
|
||||
fmt::detail::truncating_iterator<char*>>::value,
|
||||
"");
|
||||
|
||||
fmt::detail::truncating_iterator<char*> it;
|
||||
TEST(iterator_test, truncating_iterator_default_construct) {
|
||||
auto it = fmt::detail::truncating_iterator<char*>();
|
||||
EXPECT_EQ(nullptr, it.base());
|
||||
EXPECT_EQ(std::size_t{0}, it.count());
|
||||
}
|
||||
|
||||
#ifdef __cpp_lib_ranges
|
||||
TEST(IteratorTest, TruncatingIteratorOutputIterator) {
|
||||
TEST(iterator_test, truncating_iterator_is_output_iterator) {
|
||||
static_assert(
|
||||
std::output_iterator<fmt::detail::truncating_iterator<char*>, char>);
|
||||
}
|
||||
#endif
|
||||
|
||||
TEST(IteratorTest, TruncatingBackInserter) {
|
||||
std::string buffer;
|
||||
TEST(iterator_test, truncating_back_inserter) {
|
||||
auto buffer = std::string();
|
||||
auto bi = std::back_inserter(buffer);
|
||||
fmt::detail::truncating_iterator<decltype(bi)> it(bi, 2);
|
||||
auto it = fmt::detail::truncating_iterator<decltype(bi)>(bi, 2);
|
||||
*it++ = '4';
|
||||
*it++ = '2';
|
||||
*it++ = '1';
|
||||
@ -55,37 +44,6 @@ TEST(IteratorTest, TruncatingBackInserter) {
|
||||
EXPECT_EQ(buffer, "42");
|
||||
}
|
||||
|
||||
// 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
|
||||
|
||||
struct test_formattable {};
|
||||
|
||||
FMT_BEGIN_NAMESPACE
|
||||
@ -97,14 +55,14 @@ template <> struct formatter<test_formattable> : formatter<const char*> {
|
||||
};
|
||||
FMT_END_NAMESPACE
|
||||
|
||||
TEST(CompileTest, CompileFallback) {
|
||||
TEST(compile_test, compile_fallback) {
|
||||
// FMT_COMPILE should fallback on runtime formatting when `if constexpr` is
|
||||
// not available.
|
||||
EXPECT_EQ("42", fmt::format(FMT_COMPILE("{}"), 42));
|
||||
}
|
||||
|
||||
#ifdef __cpp_if_constexpr
|
||||
TEST(CompileTest, FormatDefault) {
|
||||
TEST(compile_test, format_default) {
|
||||
EXPECT_EQ("42", fmt::format(FMT_COMPILE("{}"), 42));
|
||||
EXPECT_EQ("42", fmt::format(FMT_COMPILE("{}"), 42u));
|
||||
EXPECT_EQ("42", fmt::format(FMT_COMPILE("{}"), 42ll));
|
||||
@ -120,18 +78,18 @@ TEST(CompileTest, FormatDefault) {
|
||||
# endif
|
||||
}
|
||||
|
||||
TEST(CompileTest, FormatWideString) {
|
||||
TEST(compile_test, format_wide_string) {
|
||||
EXPECT_EQ(L"42", fmt::format(FMT_COMPILE(L"{}"), 42));
|
||||
}
|
||||
|
||||
TEST(CompileTest, FormatSpecs) {
|
||||
TEST(compile_test, format_specs) {
|
||||
EXPECT_EQ("42", fmt::format(FMT_COMPILE("{:x}"), 0x42));
|
||||
EXPECT_EQ("1.2 ms ",
|
||||
fmt::format(FMT_COMPILE("{:7.1%Q %q}"),
|
||||
std::chrono::duration<double, std::milli>(1.234)));
|
||||
}
|
||||
|
||||
TEST(CompileTest, DynamicFormatSpecs) {
|
||||
TEST(compile_test, dynamic_format_specs) {
|
||||
EXPECT_EQ("foo ", fmt::format(FMT_COMPILE("{:{}}"), "foo", 5));
|
||||
EXPECT_EQ(" 3.14", fmt::format(FMT_COMPILE("{:{}.{}f}"), 3.141592, 6, 2));
|
||||
EXPECT_EQ(
|
||||
@ -140,7 +98,7 @@ TEST(CompileTest, DynamicFormatSpecs) {
|
||||
std::chrono::duration<double, std::milli>(1.234), 9, 3));
|
||||
}
|
||||
|
||||
TEST(CompileTest, ManualOrdering) {
|
||||
TEST(compile_test, manual_ordering) {
|
||||
EXPECT_EQ("42", fmt::format(FMT_COMPILE("{0}"), 42));
|
||||
EXPECT_EQ(" -42", fmt::format(FMT_COMPILE("{0:4}"), -42));
|
||||
EXPECT_EQ("41 43", fmt::format(FMT_COMPILE("{0} {1}"), 41, 43));
|
||||
@ -157,7 +115,7 @@ TEST(CompileTest, ManualOrdering) {
|
||||
EXPECT_EQ(L"42", fmt::format(FMT_COMPILE(L"{0}"), 42));
|
||||
}
|
||||
|
||||
TEST(CompileTest, Named) {
|
||||
TEST(compile_test, named) {
|
||||
auto runtime_named_field_compiled =
|
||||
fmt::detail::compile<decltype(fmt::arg("arg", 42))>(FMT_COMPILE("{arg}"));
|
||||
static_assert(std::is_same_v<decltype(runtime_named_field_compiled),
|
||||
@ -205,7 +163,7 @@ TEST(CompileTest, Named) {
|
||||
# endif
|
||||
}
|
||||
|
||||
TEST(CompileTest, FormatTo) {
|
||||
TEST(compile_test, format_to) {
|
||||
char buf[8];
|
||||
auto end = fmt::format_to(buf, FMT_COMPILE("{}"), 42);
|
||||
*end = '\0';
|
||||
@ -215,7 +173,7 @@ TEST(CompileTest, FormatTo) {
|
||||
EXPECT_STREQ("2a", buf);
|
||||
}
|
||||
|
||||
TEST(CompileTest, FormatToNWithCompileMacro) {
|
||||
TEST(compile_test, format_to_n) {
|
||||
constexpr auto buffer_size = 8;
|
||||
char buffer[buffer_size];
|
||||
auto res = fmt::format_to_n(buffer, buffer_size, FMT_COMPILE("{}"), 42);
|
||||
@ -226,17 +184,17 @@ TEST(CompileTest, FormatToNWithCompileMacro) {
|
||||
EXPECT_STREQ("2a", buffer);
|
||||
}
|
||||
|
||||
TEST(CompileTest, FormattedSizeWithCompileMacro) {
|
||||
TEST(compile_test, formatted_size) {
|
||||
EXPECT_EQ(2, fmt::formatted_size(FMT_COMPILE("{0}"), 42));
|
||||
EXPECT_EQ(5, fmt::formatted_size(FMT_COMPILE("{0:<4.2f}"), 42.0));
|
||||
}
|
||||
|
||||
TEST(CompileTest, TextAndArg) {
|
||||
TEST(compile_test, text_and_arg) {
|
||||
EXPECT_EQ(">>>42<<<", fmt::format(FMT_COMPILE(">>>{}<<<"), 42));
|
||||
EXPECT_EQ("42!", fmt::format(FMT_COMPILE("{}!"), 42));
|
||||
}
|
||||
|
||||
TEST(CompileTest, UnknownFormatFallback) {
|
||||
TEST(compile_test, unknown_format_fallback) {
|
||||
EXPECT_EQ(" 42 ",
|
||||
fmt::format(FMT_COMPILE("{name:^4}"), fmt::arg("name", 42)));
|
||||
|
||||
@ -253,7 +211,7 @@ TEST(CompileTest, UnknownFormatFallback) {
|
||||
EXPECT_EQ(" 42 ", fmt::string_view(buffer, 4));
|
||||
}
|
||||
|
||||
TEST(CompileTest, Empty) { EXPECT_EQ("", fmt::format(FMT_COMPILE(""))); }
|
||||
TEST(compile_test, empty) { EXPECT_EQ("", fmt::format(FMT_COMPILE(""))); }
|
||||
|
||||
struct to_stringable {
|
||||
friend fmt::string_view to_string_view(to_stringable) { return {}; }
|
||||
@ -272,13 +230,13 @@ template <> struct formatter<to_stringable> {
|
||||
};
|
||||
FMT_END_NAMESPACE
|
||||
|
||||
TEST(CompileTest, ToStringAndFormatter) {
|
||||
TEST(compile_test, to_string_and_formatter) {
|
||||
fmt::format(FMT_COMPILE("{}"), to_stringable());
|
||||
}
|
||||
#endif
|
||||
|
||||
#if FMT_USE_NONTYPE_TEMPLATE_PARAMETERS
|
||||
TEST(CompileTest, CompileFormatStringLiteral) {
|
||||
TEST(compile_test, compile_format_string_literal) {
|
||||
using namespace fmt::literals;
|
||||
EXPECT_EQ("", fmt::format(""_cf));
|
||||
EXPECT_EQ("42", fmt::format("{}"_cf, 42));
|
||||
@ -302,14 +260,14 @@ consteval auto test_format(auto format, const Args&... args) {
|
||||
return string;
|
||||
}
|
||||
|
||||
TEST(CompileTimeFormattingTest, Bool) {
|
||||
TEST(compile_time_formatting_test, bool) {
|
||||
EXPECT_EQ("true", test_format<5>(FMT_COMPILE("{}"), true));
|
||||
EXPECT_EQ("false", test_format<6>(FMT_COMPILE("{}"), false));
|
||||
EXPECT_EQ("true ", test_format<6>(FMT_COMPILE("{:5}"), true));
|
||||
EXPECT_EQ("1", test_format<2>(FMT_COMPILE("{:d}"), true));
|
||||
}
|
||||
|
||||
TEST(CompileTimeFormattingTest, Integer) {
|
||||
TEST(compile_time_formatting_test, integer) {
|
||||
EXPECT_EQ("42", test_format<3>(FMT_COMPILE("{}"), 42));
|
||||
EXPECT_EQ("420", test_format<4>(FMT_COMPILE("{}"), 420));
|
||||
EXPECT_EQ("42 42", test_format<6>(FMT_COMPILE("{} {}"), 42, 42));
|
||||
@ -339,14 +297,14 @@ TEST(CompileTimeFormattingTest, Integer) {
|
||||
EXPECT_EQ("**-42", test_format<6>(FMT_COMPILE("{:*>5}"), -42));
|
||||
}
|
||||
|
||||
TEST(CompileTimeFormattingTest, Char) {
|
||||
TEST(compile_time_formatting_test, char) {
|
||||
EXPECT_EQ("c", test_format<2>(FMT_COMPILE("{}"), 'c'));
|
||||
|
||||
EXPECT_EQ("c ", test_format<4>(FMT_COMPILE("{:3}"), 'c'));
|
||||
EXPECT_EQ("99", test_format<3>(FMT_COMPILE("{:d}"), 'c'));
|
||||
}
|
||||
|
||||
TEST(CompileTimeFormattingTest, String) {
|
||||
TEST(compile_time_formatting_test, string) {
|
||||
EXPECT_EQ("42", test_format<3>(FMT_COMPILE("{}"), "42"));
|
||||
EXPECT_EQ("The answer is 42",
|
||||
test_format<17>(FMT_COMPILE("{} is {}"), "The answer", "42"));
|
||||
@ -355,14 +313,14 @@ TEST(CompileTimeFormattingTest, String) {
|
||||
EXPECT_EQ("**🤡**", test_format<9>(FMT_COMPILE("{:*^6}"), "🤡"));
|
||||
}
|
||||
|
||||
TEST(CompileTimeFormattingTest, Combination) {
|
||||
TEST(compile_time_formatting_test, combination) {
|
||||
EXPECT_EQ("420, true, answer",
|
||||
test_format<18>(FMT_COMPILE("{}, {}, {}"), 420, true, "answer"));
|
||||
|
||||
EXPECT_EQ(" -42", test_format<5>(FMT_COMPILE("{:{}}"), -42, 4));
|
||||
}
|
||||
|
||||
TEST(CompileTimeFormattingTest, MultiByteFill) {
|
||||
TEST(compile_time_formatting_test, multibyte_fill) {
|
||||
EXPECT_EQ("жж42", test_format<8>(FMT_COMPILE("{:ж>4}"), 42));
|
||||
}
|
||||
#endif
|
||||
|
Reference in New Issue
Block a user