Format the code using clang-format
This commit is contained in:
+4
-4
@@ -9,14 +9,14 @@
|
||||
#include "gtest.h"
|
||||
|
||||
#if GTEST_HAS_DEATH_TEST
|
||||
# define EXPECT_DEBUG_DEATH_IF_SUPPORTED(statement, regex) \
|
||||
# define EXPECT_DEBUG_DEATH_IF_SUPPORTED(statement, regex) \
|
||||
EXPECT_DEBUG_DEATH(statement, regex)
|
||||
#else
|
||||
# define EXPECT_DEBUG_DEATH_IF_SUPPORTED(statement, regex) \
|
||||
# define EXPECT_DEBUG_DEATH_IF_SUPPORTED(statement, regex) \
|
||||
GTEST_UNSUPPORTED_DEATH_TEST_(statement, regex, )
|
||||
#endif
|
||||
|
||||
TEST(AssertTest, Fail) {
|
||||
EXPECT_DEBUG_DEATH_IF_SUPPORTED(
|
||||
FMT_ASSERT(false, "don't panic!"), "don't panic!");
|
||||
EXPECT_DEBUG_DEATH_IF_SUPPORTED(FMT_ASSERT(false, "don't panic!"),
|
||||
"don't panic!");
|
||||
}
|
||||
|
||||
+16
-15
@@ -34,18 +34,19 @@ std::tm make_second(int 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::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();
|
||||
}
|
||||
|
||||
#define EXPECT_TIME(spec, time, duration) { \
|
||||
std::locale loc("ja_JP.utf8"); \
|
||||
EXPECT_EQ(format_tm(time, spec, loc), \
|
||||
#define EXPECT_TIME(spec, time, duration) \
|
||||
{ \
|
||||
std::locale loc("ja_JP.utf8"); \
|
||||
EXPECT_EQ(format_tm(time, spec, loc), \
|
||||
fmt::format(loc, "{:" spec "}", duration)); \
|
||||
}
|
||||
|
||||
@@ -83,12 +84,12 @@ TEST(ChronoTest, FormatDefault) {
|
||||
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)));
|
||||
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, Align) {
|
||||
@@ -105,7 +106,6 @@ TEST(ChronoTest, Align) {
|
||||
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) {
|
||||
@@ -162,13 +162,14 @@ TEST(ChronoTest, InvalidSpecs) {
|
||||
}
|
||||
|
||||
TEST(ChronoTest, Locale) {
|
||||
const char *loc_name = "ja_JP.utf8";
|
||||
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 &) {}
|
||||
} catch (const std::runtime_error&) {
|
||||
}
|
||||
if (!has_locale) {
|
||||
fmt::print("{} locale is missing.\n", loc_name);
|
||||
return;
|
||||
|
||||
+100
-109
@@ -11,9 +11,9 @@
|
||||
#include <functional>
|
||||
#include <iterator>
|
||||
#include <limits>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <type_traits>
|
||||
#include <memory>
|
||||
|
||||
#include "test-assert.h"
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
|
||||
// Check if fmt/core.h compiles with windows.h included before it.
|
||||
#ifdef _WIN32
|
||||
# include <windows.h>
|
||||
# include <windows.h>
|
||||
#endif
|
||||
|
||||
#include "fmt/core.h"
|
||||
@@ -30,9 +30,9 @@
|
||||
#undef max
|
||||
|
||||
using fmt::basic_format_arg;
|
||||
using fmt::string_view;
|
||||
using fmt::internal::basic_buffer;
|
||||
using fmt::internal::value;
|
||||
using fmt::string_view;
|
||||
|
||||
using testing::_;
|
||||
using testing::StrictMock;
|
||||
@@ -42,24 +42,23 @@ namespace {
|
||||
struct test_struct {};
|
||||
|
||||
template <typename Context, typename T>
|
||||
basic_format_arg<Context> make_arg(const T &value) {
|
||||
basic_format_arg<Context> make_arg(const T& value) {
|
||||
return fmt::internal::make_arg<Context>(value);
|
||||
}
|
||||
} // namespace
|
||||
|
||||
FMT_BEGIN_NAMESPACE
|
||||
template <typename Char>
|
||||
struct formatter<test_struct, Char> {
|
||||
template <typename Char> struct formatter<test_struct, Char> {
|
||||
template <typename ParseContext>
|
||||
auto parse(ParseContext &ctx) -> decltype(ctx.begin()) {
|
||||
auto parse(ParseContext& ctx) -> decltype(ctx.begin()) {
|
||||
return ctx.begin();
|
||||
}
|
||||
|
||||
typedef std::back_insert_iterator<basic_buffer<Char>> iterator;
|
||||
|
||||
auto format(test_struct, basic_format_context<iterator, char> &ctx)
|
||||
auto format(test_struct, basic_format_context<iterator, char>& ctx)
|
||||
-> decltype(ctx.out()) {
|
||||
const Char *test = "test";
|
||||
const Char* test = "test";
|
||||
return std::copy_n(test, std::strlen(test), ctx.out());
|
||||
}
|
||||
};
|
||||
@@ -67,31 +66,29 @@ FMT_END_NAMESPACE
|
||||
|
||||
#if !FMT_GCC_VERSION || FMT_GCC_VERSION >= 470
|
||||
TEST(BufferTest, Noncopyable) {
|
||||
EXPECT_FALSE(std::is_copy_constructible<basic_buffer<char> >::value);
|
||||
#if !FMT_MSC_VER
|
||||
EXPECT_FALSE(std::is_copy_constructible<basic_buffer<char>>::value);
|
||||
# if !FMT_MSC_VER
|
||||
// std::is_copy_assignable is broken in MSVC2013.
|
||||
EXPECT_FALSE(std::is_copy_assignable<basic_buffer<char> >::value);
|
||||
#endif
|
||||
EXPECT_FALSE(std::is_copy_assignable<basic_buffer<char>>::value);
|
||||
# endif
|
||||
}
|
||||
|
||||
TEST(BufferTest, Nonmoveable) {
|
||||
EXPECT_FALSE(std::is_move_constructible<basic_buffer<char> >::value);
|
||||
#if !FMT_MSC_VER
|
||||
EXPECT_FALSE(std::is_move_constructible<basic_buffer<char>>::value);
|
||||
# if !FMT_MSC_VER
|
||||
// std::is_move_assignable is broken in MSVC2013.
|
||||
EXPECT_FALSE(std::is_move_assignable<basic_buffer<char> >::value);
|
||||
#endif
|
||||
EXPECT_FALSE(std::is_move_assignable<basic_buffer<char>>::value);
|
||||
# endif
|
||||
}
|
||||
#endif
|
||||
|
||||
// A test buffer with a dummy grow method.
|
||||
template <typename T>
|
||||
struct test_buffer : basic_buffer<T> {
|
||||
template <typename T> struct test_buffer : basic_buffer<T> {
|
||||
void grow(std::size_t capacity) { this->set(FMT_NULL, capacity); }
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct mock_buffer : basic_buffer<T> {
|
||||
MOCK_METHOD1(do_grow, void (std::size_t capacity));
|
||||
template <typename T> struct mock_buffer : basic_buffer<T> {
|
||||
MOCK_METHOD1(do_grow, void(std::size_t capacity));
|
||||
|
||||
void grow(std::size_t capacity) {
|
||||
this->set(this->data(), capacity);
|
||||
@@ -99,8 +96,8 @@ struct mock_buffer : basic_buffer<T> {
|
||||
}
|
||||
|
||||
mock_buffer() {}
|
||||
mock_buffer(T *data) { this->set(data, 0); }
|
||||
mock_buffer(T *data, std::size_t capacity) { this->set(data, capacity); }
|
||||
mock_buffer(T* data) { this->set(data, 0); }
|
||||
mock_buffer(T* data, std::size_t capacity) { this->set(data, capacity); }
|
||||
};
|
||||
|
||||
TEST(BufferTest, Ctor) {
|
||||
@@ -134,9 +131,9 @@ struct dying_buffer : test_buffer<int> {
|
||||
|
||||
TEST(BufferTest, VirtualDtor) {
|
||||
typedef StrictMock<dying_buffer> stict_mock_buffer;
|
||||
stict_mock_buffer *mock_buffer = new stict_mock_buffer();
|
||||
stict_mock_buffer* mock_buffer = new stict_mock_buffer();
|
||||
EXPECT_CALL(*mock_buffer, die());
|
||||
basic_buffer<int> *buffer = mock_buffer;
|
||||
basic_buffer<int>* buffer = mock_buffer;
|
||||
delete buffer;
|
||||
}
|
||||
|
||||
@@ -147,7 +144,7 @@ TEST(BufferTest, Access) {
|
||||
EXPECT_EQ(11, buffer[0]);
|
||||
buffer[3] = 42;
|
||||
EXPECT_EQ(42, *(&buffer[0] + 3));
|
||||
const basic_buffer<char> &const_buffer = buffer;
|
||||
const basic_buffer<char>& const_buffer = buffer;
|
||||
EXPECT_EQ(42, const_buffer[3]);
|
||||
}
|
||||
|
||||
@@ -182,7 +179,7 @@ TEST(BufferTest, Clear) {
|
||||
TEST(BufferTest, Append) {
|
||||
char data[15];
|
||||
mock_buffer<char> buffer(data, 10);
|
||||
const char *test = "test";
|
||||
const char* test = "test";
|
||||
buffer.append(test, test + 5);
|
||||
EXPECT_STREQ(test, &buffer[0]);
|
||||
EXPECT_EQ(5u, buffer.size());
|
||||
@@ -197,7 +194,7 @@ TEST(BufferTest, Append) {
|
||||
TEST(BufferTest, AppendAllocatesEnoughStorage) {
|
||||
char data[19];
|
||||
mock_buffer<char> buffer(data, 10);
|
||||
const char *test = "abcdefgh";
|
||||
const char* test = "abcdefgh";
|
||||
buffer.resize(10);
|
||||
EXPECT_CALL(buffer, do_grow(19));
|
||||
buffer.append(test, test + 9);
|
||||
@@ -211,15 +208,14 @@ TEST(ArgTest, FormatArgs) {
|
||||
struct custom_context {
|
||||
typedef char char_type;
|
||||
|
||||
template <typename T>
|
||||
struct formatter_type {
|
||||
template <typename T> struct formatter_type {
|
||||
struct type {
|
||||
template <typename ParseContext>
|
||||
auto parse(ParseContext &ctx) -> decltype(ctx.begin()) {
|
||||
auto parse(ParseContext& ctx) -> decltype(ctx.begin()) {
|
||||
return ctx.begin();
|
||||
}
|
||||
|
||||
const char *format(const T &, custom_context& ctx) {
|
||||
const char* format(const T&, custom_context& ctx) {
|
||||
ctx.called = true;
|
||||
return FMT_NULL;
|
||||
}
|
||||
@@ -231,7 +227,7 @@ struct custom_context {
|
||||
fmt::format_parse_context parse_context() {
|
||||
return fmt::format_parse_context("");
|
||||
}
|
||||
void advance_to(const char *) {}
|
||||
void advance_to(const char*) {}
|
||||
};
|
||||
|
||||
TEST(ArgTest, MakeValueWithCustomContext) {
|
||||
@@ -249,40 +245,35 @@ template <typename Char>
|
||||
bool operator==(custom_value<Char> lhs, custom_value<Char> rhs) {
|
||||
return lhs.value == rhs.value;
|
||||
}
|
||||
}
|
||||
} // namespace internal
|
||||
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 { typedef test_result type; };
|
||||
template <typename T> struct mock_visitor {
|
||||
template <typename U> struct result { typedef test_result type; };
|
||||
|
||||
mock_visitor() {
|
||||
ON_CALL(*this, visit(_)).WillByDefault(testing::Return(test_result()));
|
||||
}
|
||||
|
||||
MOCK_METHOD1_T(visit, test_result (T value));
|
||||
MOCK_METHOD0_T(unexpected, void ());
|
||||
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) {
|
||||
template <typename U> test_result operator()(U) {
|
||||
unexpected();
|
||||
return test_result();
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct visit_type { typedef T Type; };
|
||||
template <typename T> struct visit_type { typedef T Type; };
|
||||
|
||||
#define VISIT_TYPE(Type_, visit_type_) \
|
||||
template <> \
|
||||
struct visit_type<Type_> { typedef visit_type_ Type; }
|
||||
template <> struct visit_type<Type_> { typedef visit_type_ Type; }
|
||||
|
||||
VISIT_TYPE(signed char, int);
|
||||
VISIT_TYPE(unsigned char, unsigned);
|
||||
@@ -299,28 +290,30 @@ VISIT_TYPE(unsigned long, unsigned long long);
|
||||
|
||||
VISIT_TYPE(float, double);
|
||||
|
||||
#define CHECK_ARG_(Char, expected, value) { \
|
||||
testing::StrictMock<mock_visitor<decltype(expected)>> visitor; \
|
||||
EXPECT_CALL(visitor, visit(expected)); \
|
||||
typedef std::back_insert_iterator<basic_buffer<Char>> iterator; \
|
||||
fmt::visit(visitor, \
|
||||
make_arg<fmt::basic_format_context<iterator, Char>>(value)); \
|
||||
}
|
||||
#define CHECK_ARG_(Char, expected, value) \
|
||||
{ \
|
||||
testing::StrictMock<mock_visitor<decltype(expected)>> visitor; \
|
||||
EXPECT_CALL(visitor, visit(expected)); \
|
||||
typedef std::back_insert_iterator<basic_buffer<Char>> iterator; \
|
||||
fmt::visit(visitor, \
|
||||
make_arg<fmt::basic_format_context<iterator, Char>>(value)); \
|
||||
}
|
||||
|
||||
#define CHECK_ARG(value, typename_) { \
|
||||
typedef decltype(value) value_type; \
|
||||
typename_ visit_type<value_type>::Type expected = value; \
|
||||
CHECK_ARG_(char, expected, value) \
|
||||
CHECK_ARG_(wchar_t, expected, value) \
|
||||
}
|
||||
#define CHECK_ARG(value, typename_) \
|
||||
{ \
|
||||
typedef decltype(value) value_type; \
|
||||
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 {};
|
||||
template <typename T> class NumericArgTest : public testing::Test {};
|
||||
|
||||
typedef ::testing::Types<
|
||||
bool, signed char, unsigned char, signed, unsigned short,
|
||||
int, unsigned, long, unsigned long, long long, unsigned long long,
|
||||
float, double, long double> Types;
|
||||
typedef ::testing::Types<bool, signed char, unsigned char, signed,
|
||||
unsigned short, int, unsigned, long, unsigned long,
|
||||
long long, unsigned long long, float, double,
|
||||
long double>
|
||||
Types;
|
||||
TYPED_TEST_CASE(NumericArgTest, Types);
|
||||
|
||||
template <typename T>
|
||||
@@ -330,7 +323,7 @@ typename std::enable_if<std::is_integral<T>::value, T>::type test_value() {
|
||||
|
||||
template <typename T>
|
||||
typename std::enable_if<std::is_floating_point<T>::value, T>::type
|
||||
test_value() {
|
||||
test_value() {
|
||||
return static_cast<T>(4.2);
|
||||
}
|
||||
|
||||
@@ -348,8 +341,8 @@ TEST(ArgTest, CharArg) {
|
||||
|
||||
TEST(ArgTest, StringArg) {
|
||||
char str_data[] = "test";
|
||||
char *str = str_data;
|
||||
const char *cstr = str;
|
||||
char* str = str_data;
|
||||
const char* cstr = str;
|
||||
CHECK_ARG_(char, cstr, str);
|
||||
|
||||
string_view sref(str);
|
||||
@@ -358,8 +351,8 @@ TEST(ArgTest, StringArg) {
|
||||
|
||||
TEST(ArgTest, WStringArg) {
|
||||
wchar_t str_data[] = L"test";
|
||||
wchar_t *str = str_data;
|
||||
const wchar_t *cstr = str;
|
||||
wchar_t* str = str_data;
|
||||
const wchar_t* cstr = str;
|
||||
|
||||
fmt::wstring_view sref(str);
|
||||
CHECK_ARG_(wchar_t, cstr, str);
|
||||
@@ -369,8 +362,8 @@ TEST(ArgTest, WStringArg) {
|
||||
}
|
||||
|
||||
TEST(ArgTest, PointerArg) {
|
||||
void *p = FMT_NULL;
|
||||
const void *cp = FMT_NULL;
|
||||
void* p = FMT_NULL;
|
||||
const void* cp = FMT_NULL;
|
||||
CHECK_ARG_(char, cp, p);
|
||||
CHECK_ARG_(wchar_t, cp, p);
|
||||
CHECK_ARG(cp, );
|
||||
@@ -384,7 +377,7 @@ struct check_custom {
|
||||
test_buffer() : fmt::internal::basic_buffer<char>(data, 0, 10) {}
|
||||
void grow(std::size_t) {}
|
||||
} buffer;
|
||||
fmt::internal::basic_buffer<char> &base = buffer;
|
||||
fmt::internal::basic_buffer<char>& base = buffer;
|
||||
fmt::format_context ctx(std::back_inserter(base), "", fmt::format_args());
|
||||
h.format(ctx);
|
||||
EXPECT_EQ("test", std::string(buffer.data, buffer.size()));
|
||||
@@ -395,14 +388,14 @@ struct check_custom {
|
||||
TEST(ArgTest, CustomArg) {
|
||||
test_struct test;
|
||||
typedef mock_visitor<fmt::basic_format_arg<fmt::format_context>::handle>
|
||||
visitor;
|
||||
visitor;
|
||||
testing::StrictMock<visitor> v;
|
||||
EXPECT_CALL(v, visit(_)).WillOnce(testing::Invoke(check_custom()));
|
||||
fmt::visit(v, make_arg<fmt::format_context>(test));
|
||||
}
|
||||
|
||||
TEST(ArgTest, VisitInvalidArg) {
|
||||
testing::StrictMock< mock_visitor<fmt::monostate> > visitor;
|
||||
testing::StrictMock<mock_visitor<fmt::monostate>> visitor;
|
||||
EXPECT_CALL(visitor, visit(_));
|
||||
fmt::basic_format_arg<fmt::format_context> arg;
|
||||
visit(visitor, arg);
|
||||
@@ -416,9 +409,8 @@ TEST(StringViewTest, Length) {
|
||||
}
|
||||
|
||||
// Check string_view's comparison operator.
|
||||
template <template <typename> class Op>
|
||||
void check_op() {
|
||||
const char *inputs[] = {"foo", "fop", "fo"};
|
||||
template <template <typename> class Op> void check_op() {
|
||||
const char* inputs[] = {"foo", "fop", "fo"};
|
||||
std::size_t num_inputs = sizeof(inputs) / sizeof(*inputs);
|
||||
for (std::size_t i = 0; i < num_inputs; ++i) {
|
||||
for (std::size_t j = 0; j < num_inputs; ++j) {
|
||||
@@ -446,7 +438,7 @@ enum basic_enum {};
|
||||
|
||||
TEST(CoreTest, ConvertToInt) {
|
||||
EXPECT_FALSE((fmt::convert_to_int<char, char>::value));
|
||||
EXPECT_FALSE((fmt::convert_to_int<const char *, char>::value));
|
||||
EXPECT_FALSE((fmt::convert_to_int<const char*, char>::value));
|
||||
EXPECT_TRUE((fmt::convert_to_int<basic_enum, char>::value));
|
||||
}
|
||||
|
||||
@@ -457,31 +449,31 @@ TEST(CoreTest, IsEnumConvertibleToInt) {
|
||||
}
|
||||
|
||||
namespace my_ns {
|
||||
template <typename Char>
|
||||
class my_string {
|
||||
template <typename Char> class my_string {
|
||||
public:
|
||||
my_string(const Char *s) : s_(s) {}
|
||||
const Char * data() const FMT_NOEXCEPT { return s_.data(); }
|
||||
my_string(const Char* s) : s_(s) {}
|
||||
const Char* data() const FMT_NOEXCEPT { return s_.data(); }
|
||||
std::size_t length() const FMT_NOEXCEPT { return s_.size(); }
|
||||
operator const Char*() const { return s_.c_str(); }
|
||||
|
||||
private:
|
||||
std::basic_string<Char> s_;
|
||||
};
|
||||
|
||||
template <typename Char>
|
||||
inline fmt::basic_string_view<Char>
|
||||
to_string_view(const my_string<Char> &s) FMT_NOEXCEPT {
|
||||
return { s.data(), s.length() };
|
||||
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
|
||||
|
||||
namespace FakeQt {
|
||||
class QString {
|
||||
public:
|
||||
QString(const wchar_t *s) : s_(std::make_shared<std::wstring>(s)) {}
|
||||
const wchar_t *utf16() const FMT_NOEXCEPT { return s_->data(); }
|
||||
QString(const wchar_t* s) : s_(std::make_shared<std::wstring>(s)) {}
|
||||
const wchar_t* utf16() const FMT_NOEXCEPT { return s_->data(); }
|
||||
int size() const FMT_NOEXCEPT { return static_cast<int>(s_->size()); }
|
||||
#ifdef FMT_STRING_VIEW
|
||||
operator FMT_STRING_VIEW<wchar_t>() const FMT_NOEXCEPT { return *s_; }
|
||||
@@ -490,15 +482,13 @@ class QString {
|
||||
std::shared_ptr<std::wstring> s_;
|
||||
};
|
||||
|
||||
inline fmt::basic_string_view<wchar_t> to_string_view(
|
||||
const QString &s) FMT_NOEXCEPT {
|
||||
return {s.utf16(),
|
||||
static_cast<std::size_t>(s.size())};
|
||||
}
|
||||
inline fmt::basic_string_view<wchar_t> to_string_view(const QString& s)
|
||||
FMT_NOEXCEPT {
|
||||
return {s.utf16(), static_cast<std::size_t>(s.size())};
|
||||
}
|
||||
} // namespace FakeQt
|
||||
|
||||
template <typename T>
|
||||
class IsStringTest : public testing::Test {};
|
||||
template <typename T> class IsStringTest : public testing::Test {};
|
||||
|
||||
typedef ::testing::Types<char, wchar_t, char16_t, char32_t> StringCharTypes;
|
||||
TYPED_TEST_CASE(IsStringTest, StringCharTypes);
|
||||
@@ -506,18 +496,18 @@ 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::internal::is_string<TypeParam *>::value));
|
||||
EXPECT_TRUE((fmt::internal::is_string<const TypeParam *>::value));
|
||||
EXPECT_TRUE((fmt::internal::is_string<TypeParam*>::value));
|
||||
EXPECT_TRUE((fmt::internal::is_string<const TypeParam*>::value));
|
||||
EXPECT_TRUE((fmt::internal::is_string<TypeParam[2]>::value));
|
||||
EXPECT_TRUE((fmt::internal::is_string<const TypeParam[2]>::value));
|
||||
EXPECT_TRUE((fmt::internal::is_string<std::basic_string<TypeParam>>::value));
|
||||
EXPECT_TRUE(
|
||||
(fmt::internal::is_string<fmt::basic_string_view<TypeParam>>::value));
|
||||
(fmt::internal::is_string<fmt::basic_string_view<TypeParam>>::value));
|
||||
EXPECT_TRUE(
|
||||
(fmt::internal::is_string<derived_from_string_view<TypeParam>>::value));
|
||||
(fmt::internal::is_string<derived_from_string_view<TypeParam>>::value));
|
||||
#ifdef FMT_STRING_VIEW
|
||||
EXPECT_TRUE((fmt::internal::is_string<FMT_STRING_VIEW<TypeParam>>::value));
|
||||
#endif
|
||||
@@ -529,7 +519,7 @@ TYPED_TEST(IsStringTest, IsString) {
|
||||
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
|
||||
# error fmt/format.h must not be included in the core test
|
||||
#endif
|
||||
EXPECT_EQ(fmt::format("{}", 42), "42");
|
||||
}
|
||||
@@ -537,7 +527,7 @@ TEST(CoreTest, Format) {
|
||||
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
|
||||
# error fmt/format.h must not be included in the core test
|
||||
#endif
|
||||
std::string s;
|
||||
fmt::format_to(std::back_inserter(s), "{}", 42);
|
||||
@@ -600,11 +590,12 @@ TEST(FormatterTest, FormatExplicitlyConvertibleToWStringView) {
|
||||
}
|
||||
|
||||
struct explicitly_convertible_to_string_like {
|
||||
template <
|
||||
typename String,
|
||||
typename = typename std::enable_if<
|
||||
std::is_constructible<String, const char*, std::size_t>::value>::type>
|
||||
FMT_EXPLICIT operator String() const { return String("foo", 3u); }
|
||||
template <typename String,
|
||||
typename = typename std::enable_if<std::is_constructible<
|
||||
String, const char*, std::size_t>::value>::type>
|
||||
FMT_EXPLICIT operator String() const {
|
||||
return String("foo", 3u);
|
||||
}
|
||||
};
|
||||
|
||||
TEST(FormatterTest, FormatExplicitlyConvertibleToStringLike) {
|
||||
|
||||
@@ -13,22 +13,21 @@
|
||||
|
||||
// A custom argument formatter that doesn't print `-` for floating-point values
|
||||
// rounded to 0.
|
||||
class custom_arg_formatter :
|
||||
public fmt::arg_formatter<fmt::back_insert_range<fmt::internal::buffer>> {
|
||||
class custom_arg_formatter
|
||||
: public fmt::arg_formatter<fmt::back_insert_range<fmt::internal::buffer>> {
|
||||
public:
|
||||
typedef fmt::back_insert_range<fmt::internal::buffer> range;
|
||||
typedef fmt::arg_formatter<range> base;
|
||||
|
||||
custom_arg_formatter(
|
||||
fmt::format_context &ctx, fmt::format_specs *s = FMT_NULL)
|
||||
: base(ctx, s) {}
|
||||
custom_arg_formatter(fmt::format_context& ctx,
|
||||
fmt::format_specs* s = FMT_NULL)
|
||||
: base(ctx, s) {}
|
||||
|
||||
using base::operator();
|
||||
|
||||
iterator operator()(double value) {
|
||||
// Comparing a float to 0.0 is safe.
|
||||
if (round(value * pow(10, spec()->precision)) == 0.0)
|
||||
value = 0;
|
||||
if (round(value * pow(10, spec()->precision)) == 0.0) value = 0;
|
||||
return base::operator()(value);
|
||||
}
|
||||
};
|
||||
@@ -41,7 +40,7 @@ std::string custom_vformat(fmt::string_view format_str, fmt::format_args args) {
|
||||
}
|
||||
|
||||
template <typename... Args>
|
||||
std::string custom_format(const char *format_str, const Args & ... args) {
|
||||
std::string custom_format(const char* format_str, const Args&... args) {
|
||||
auto va = fmt::make_format_args(args...);
|
||||
return custom_vformat(format_str, va);
|
||||
}
|
||||
|
||||
+19
-25
@@ -25,20 +25,18 @@
|
||||
#undef max
|
||||
|
||||
#if FMT_HAS_CPP_ATTRIBUTE(noreturn)
|
||||
# define FMT_NORETURN [[noreturn]]
|
||||
# define FMT_NORETURN [[noreturn]]
|
||||
#else
|
||||
# define FMT_NORETURN
|
||||
# define FMT_NORETURN
|
||||
#endif
|
||||
|
||||
using fmt::internal::fp;
|
||||
|
||||
template <bool is_iec559>
|
||||
void test_construct_from_double() {
|
||||
template <bool is_iec559> void test_construct_from_double() {
|
||||
fmt::print("warning: double is not IEC559, skipping FP tests\n");
|
||||
}
|
||||
|
||||
template <>
|
||||
void test_construct_from_double<true>() {
|
||||
template <> void test_construct_from_double<true>() {
|
||||
auto v = fp(1.23);
|
||||
EXPECT_EQ(v.f, 0x13ae147ae147aeu);
|
||||
EXPECT_EQ(v.e, -52);
|
||||
@@ -107,14 +105,10 @@ TEST(FPTest, Grisu2FormatCompilesWithNonIEEEDouble) {
|
||||
grisu2_format(4.2f, buf, fmt::core_format_specs());
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
struct ValueExtractor: fmt::internal::function<T> {
|
||||
T operator()(T value) {
|
||||
return value;
|
||||
}
|
||||
template <typename T> struct ValueExtractor : fmt::internal::function<T> {
|
||||
T operator()(T value) { return value; }
|
||||
|
||||
template <typename U>
|
||||
FMT_NORETURN T operator()(U) {
|
||||
template <typename U> FMT_NORETURN T operator()(U) {
|
||||
throw std::runtime_error(fmt::format("invalid type {}", typeid(U).name()));
|
||||
}
|
||||
};
|
||||
@@ -136,7 +130,7 @@ TEST(FormatTest, FormatNegativeNaN) {
|
||||
}
|
||||
|
||||
TEST(FormatTest, StrError) {
|
||||
char *message = FMT_NULL;
|
||||
char* message = FMT_NULL;
|
||||
char buffer[BUFFER_SIZE];
|
||||
EXPECT_ASSERT(fmt::safe_strerror(EDOM, message = FMT_NULL, 0),
|
||||
"invalid buffer");
|
||||
@@ -178,8 +172,8 @@ TEST(FormatTest, FormatErrorCode) {
|
||||
}
|
||||
{
|
||||
fmt::memory_buffer buffer;
|
||||
std::string prefix(
|
||||
fmt::inline_buffer_size - msg.size() - sep.size() + 1, 'x');
|
||||
std::string prefix(fmt::inline_buffer_size - msg.size() - sep.size() + 1,
|
||||
'x');
|
||||
fmt::format_error_code(buffer, 42, prefix);
|
||||
EXPECT_EQ(msg, to_string(buffer));
|
||||
}
|
||||
@@ -188,8 +182,7 @@ TEST(FormatTest, FormatErrorCode) {
|
||||
// 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');
|
||||
std::string prefix(fmt::inline_buffer_size - msg.size() - sep.size(), 'x');
|
||||
fmt::format_error_code(buffer, codes[i], prefix);
|
||||
EXPECT_EQ(prefix + sep + msg, to_string(buffer));
|
||||
std::size_t size = fmt::inline_buffer_size;
|
||||
@@ -231,7 +224,7 @@ TEST(ColorsTest, ColorsPrint) {
|
||||
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");
|
||||
"\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");
|
||||
@@ -250,18 +243,19 @@ TEST(ColorsTest, ColorsFormat) {
|
||||
"\x1b[38;2;255;020;030mrgb(255,20,30)\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(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(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"),
|
||||
|
||||
+485
-530
File diff suppressed because it is too large
Load Diff
+1352
-1558
File diff suppressed because it is too large
Load Diff
+99
-80
@@ -7,22 +7,22 @@
|
||||
|
||||
#include "gtest-extra.h"
|
||||
|
||||
#include <gtest/gtest-spi.h>
|
||||
#include <algorithm>
|
||||
#include <cstring>
|
||||
#include <memory>
|
||||
#include <stdexcept>
|
||||
#include <gtest/gtest-spi.h>
|
||||
|
||||
#if defined(_WIN32) && !defined(__MINGW32__)
|
||||
# include <crtdbg.h> // for _CrtSetReportMode
|
||||
#endif // _WIN32
|
||||
# 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 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));
|
||||
@@ -52,13 +52,9 @@ int SingleEvaluationTest::b_;
|
||||
|
||||
void do_nothing() {}
|
||||
|
||||
void throw_exception() {
|
||||
throw std::runtime_error("test");
|
||||
}
|
||||
void throw_exception() { throw std::runtime_error("test"); }
|
||||
|
||||
void throw_system_error() {
|
||||
throw fmt::system_error(EDOM, "test");
|
||||
}
|
||||
void throw_system_error() { throw fmt::system_error(EDOM, "test"); }
|
||||
|
||||
// Tests that when EXPECT_THROW_MSG fails, it evaluates its message argument
|
||||
// exactly once.
|
||||
@@ -71,43 +67,50 @@ TEST_F(SingleEvaluationTest, FailedEXPECT_THROW_MSG) {
|
||||
// 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_NONFATAL_FAILURE(EXPECT_SYSTEM_ERROR(throw_system_error(), EDOM, p_++),
|
||||
"01234");
|
||||
EXPECT_EQ(s_ + 1, p_);
|
||||
}
|
||||
|
||||
// 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_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, ExceptionTests) {
|
||||
// successful EXPECT_THROW_MSG
|
||||
EXPECT_THROW_MSG({ // NOLINT
|
||||
a_++;
|
||||
throw_exception();
|
||||
}, std::exception, (b_++, "test"));
|
||||
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_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_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_);
|
||||
|
||||
@@ -120,33 +123,40 @@ TEST_F(SingleEvaluationTest, ExceptionTests) {
|
||||
|
||||
TEST_F(SingleEvaluationTest, SystemErrorTests) {
|
||||
// successful EXPECT_SYSTEM_ERROR
|
||||
EXPECT_SYSTEM_ERROR({ // NOLINT
|
||||
a_++;
|
||||
throw_system_error();
|
||||
}, EDOM, (b_++, "test"));
|
||||
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_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_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_NONFATAL_FAILURE(EXPECT_SYSTEM_ERROR(a_++, EDOM, (b_++, "test")),
|
||||
"throws nothing");
|
||||
EXPECT_EQ(4, a_);
|
||||
EXPECT_EQ(4, b_);
|
||||
}
|
||||
@@ -154,18 +164,23 @@ TEST_F(SingleEvaluationTest, SystemErrorTests) {
|
||||
// Tests that assertion arguments are evaluated exactly once.
|
||||
TEST_F(SingleEvaluationTest, WriteTests) {
|
||||
// successful EXPECT_WRITE
|
||||
EXPECT_WRITE(stdout, { // NOLINT
|
||||
a_++;
|
||||
std::printf("test");
|
||||
}, (b_++, "test"));
|
||||
EXPECT_WRITE(stdout,
|
||||
{ // NOLINT
|
||||
a_++;
|
||||
std::printf("test");
|
||||
},
|
||||
(b_++, "test"));
|
||||
EXPECT_EQ(1, a_);
|
||||
EXPECT_EQ(1, b_);
|
||||
|
||||
// failed EXPECT_WRITE
|
||||
EXPECT_NONFATAL_FAILURE(EXPECT_WRITE(stdout, { // NOLINT
|
||||
a_++;
|
||||
std::printf("test");
|
||||
}, (b_++, "other")), "Actual: test");
|
||||
EXPECT_NONFATAL_FAILURE(EXPECT_WRITE(stdout,
|
||||
{ // NOLINT
|
||||
a_++;
|
||||
std::printf("test");
|
||||
},
|
||||
(b_++, "other")),
|
||||
"Actual: test");
|
||||
EXPECT_EQ(2, a_);
|
||||
EXPECT_EQ(2, b_);
|
||||
}
|
||||
@@ -178,8 +193,8 @@ TEST(ExpectThrowTest, DoesNotGenerateUnreachableCodeWarning) {
|
||||
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"), "");
|
||||
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
|
||||
@@ -189,8 +204,9 @@ TEST(ExpectSystemErrorTest, DoesNotGenerateUnreachableCodeWarning) {
|
||||
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"), "");
|
||||
EXPECT_NONFATAL_FAILURE(
|
||||
EXPECT_SYSTEM_ERROR(throw fmt::system_error(EDOM, "aaa"), EDOM, "bbb"),
|
||||
"");
|
||||
}
|
||||
|
||||
TEST(AssertionSyntaxTest, ExceptionAssertionBehavesLikeSingleStatement) {
|
||||
@@ -267,10 +283,9 @@ 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");
|
||||
EXPECT_NONFATAL_FAILURE(EXPECT_WRITE(stdout, std::printf("that"), "this"),
|
||||
"Expected: this\n"
|
||||
" Actual: that");
|
||||
}
|
||||
|
||||
TEST(StreamingAssertionsTest, EXPECT_THROW_MSG) {
|
||||
@@ -278,7 +293,8 @@ TEST(StreamingAssertionsTest, EXPECT_THROW_MSG) {
|
||||
<< "unexpected failure";
|
||||
EXPECT_NONFATAL_FAILURE(
|
||||
EXPECT_THROW_MSG(throw_exception(), std::exception, "other")
|
||||
<< "expected failure", "expected failure");
|
||||
<< "expected failure",
|
||||
"expected failure");
|
||||
}
|
||||
|
||||
TEST(StreamingAssertionsTest, EXPECT_SYSTEM_ERROR) {
|
||||
@@ -286,15 +302,15 @@ TEST(StreamingAssertionsTest, EXPECT_SYSTEM_ERROR) {
|
||||
<< "unexpected failure";
|
||||
EXPECT_NONFATAL_FAILURE(
|
||||
EXPECT_SYSTEM_ERROR(throw_system_error(), EDOM, "other")
|
||||
<< "expected failure", "expected failure");
|
||||
<< "expected failure",
|
||||
"expected failure");
|
||||
}
|
||||
|
||||
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");
|
||||
EXPECT_WRITE(stdout, std::printf("test"), "test") << "unexpected failure";
|
||||
EXPECT_NONFATAL_FAILURE(EXPECT_WRITE(stdout, std::printf("test"), "other")
|
||||
<< "expected failure",
|
||||
"expected failure");
|
||||
}
|
||||
|
||||
TEST(UtilTest, FormatSystemError) {
|
||||
@@ -340,8 +356,8 @@ TEST(OutputRedirectTest, FlushErrorInCtor) {
|
||||
EXPECT_EQ('x', fputc('x', f.get()));
|
||||
FMT_POSIX(close(write_fd));
|
||||
std::unique_ptr<OutputRedirect> redir{FMT_NULL};
|
||||
EXPECT_SYSTEM_ERROR_NOASSERT(redir.reset(new OutputRedirect(f.get())),
|
||||
EBADF, "cannot flush stream");
|
||||
EXPECT_SYSTEM_ERROR_NOASSERT(redir.reset(new OutputRedirect(f.get())), EBADF,
|
||||
"cannot flush stream");
|
||||
redir.reset(FMT_NULL);
|
||||
write_copy.dup2(write_fd); // "undo" close or dtor will fail
|
||||
}
|
||||
@@ -352,8 +368,9 @@ TEST(OutputRedirectTest, DupErrorInCtor) {
|
||||
file copy = file::dup(fd);
|
||||
FMT_POSIX(close(fd));
|
||||
std::unique_ptr<OutputRedirect> redir{FMT_NULL};
|
||||
EXPECT_SYSTEM_ERROR_NOASSERT(redir.reset(new OutputRedirect(f.get())),
|
||||
EBADF, fmt::format("cannot duplicate file descriptor {}", fd));
|
||||
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
|
||||
}
|
||||
|
||||
@@ -382,8 +399,8 @@ TEST(OutputRedirectTest, FlushErrorInRestoreAndRead) {
|
||||
// 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");
|
||||
EXPECT_SYSTEM_ERROR_NOASSERT(redir.restore_and_read(), EBADF,
|
||||
"cannot flush stream");
|
||||
write_copy.dup2(write_fd); // "undo" close or dtor will fail
|
||||
}
|
||||
|
||||
@@ -396,15 +413,17 @@ TEST(OutputRedirectTest, ErrorInDtor) {
|
||||
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, {
|
||||
// The close function must be called inside EXPECT_WRITE, otherwise
|
||||
// the system may recycle closed file descriptor when redirecting the
|
||||
// output in EXPECT_STDERR and the second close will break output
|
||||
// redirection.
|
||||
FMT_POSIX(close(write_fd));
|
||||
SUPPRESS_ASSERT(redir.reset(FMT_NULL));
|
||||
}, format_system_error(EBADF, "cannot flush stream"));
|
||||
write_copy.dup2(write_fd); // "undo" close or dtor of buffered_file will fail
|
||||
EXPECT_WRITE(stderr,
|
||||
{
|
||||
// The close function must be called inside EXPECT_WRITE,
|
||||
// otherwise the system may recycle closed file descriptor when
|
||||
// redirecting the output in EXPECT_STDERR and the second close
|
||||
// will break output redirection.
|
||||
FMT_POSIX(close(write_fd));
|
||||
SUPPRESS_ASSERT(redir.reset(FMT_NULL));
|
||||
},
|
||||
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
|
||||
|
||||
+9
-12
@@ -12,25 +12,23 @@
|
||||
using fmt::file;
|
||||
|
||||
void OutputRedirect::flush() {
|
||||
#if EOF != -1
|
||||
# error "FMT_RETRY assumes return value of -1 indicating failure"
|
||||
#endif
|
||||
# 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");
|
||||
if (result != 0) throw fmt::system_error(errno, "cannot flush stream");
|
||||
}
|
||||
|
||||
void OutputRedirect::restore() {
|
||||
if (original_.descriptor() == -1)
|
||||
return; // Already restored.
|
||||
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) {
|
||||
OutputRedirect::OutputRedirect(FILE* f) : file_(f) {
|
||||
flush();
|
||||
int fd = FMT_POSIX(fileno(f));
|
||||
// Create a file object referring to the original file.
|
||||
@@ -45,7 +43,7 @@ OutputRedirect::OutputRedirect(FILE *f) : file_(f) {
|
||||
OutputRedirect::~OutputRedirect() FMT_NOEXCEPT {
|
||||
try {
|
||||
restore();
|
||||
} catch (const std::exception &e) {
|
||||
} catch (const std::exception& e) {
|
||||
std::fputs(e.what(), stderr);
|
||||
}
|
||||
}
|
||||
@@ -56,8 +54,7 @@ std::string OutputRedirect::restore_and_read() {
|
||||
|
||||
// Read everything from the pipe.
|
||||
std::string content;
|
||||
if (read_end_.descriptor() == -1)
|
||||
return content; // Already read.
|
||||
if (read_end_.descriptor() == -1) return content; // Already read.
|
||||
enum { BUFFER_SIZE = 4096 };
|
||||
char buffer[BUFFER_SIZE];
|
||||
std::size_t count = 0;
|
||||
@@ -69,7 +66,7 @@ std::string OutputRedirect::restore_and_read() {
|
||||
return content;
|
||||
}
|
||||
|
||||
std::string read(file &f, std::size_t count) {
|
||||
std::string read(file& f, std::size_t count) {
|
||||
std::string buffer(count, '\0');
|
||||
std::size_t n = 0, offset = 0;
|
||||
do {
|
||||
|
||||
+75
-75
@@ -14,58 +14,56 @@
|
||||
#include "fmt/core.h"
|
||||
|
||||
#ifndef FMT_USE_FILE_DESCRIPTORS
|
||||
# define FMT_USE_FILE_DESCRIPTORS 0
|
||||
# define FMT_USE_FILE_DESCRIPTORS 0
|
||||
#endif
|
||||
|
||||
#if FMT_USE_FILE_DESCRIPTORS
|
||||
# include "fmt/posix.h"
|
||||
# include "fmt/posix.h"
|
||||
#endif
|
||||
|
||||
#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())
|
||||
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_)
|
||||
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))
|
||||
EXPECT_THROW_MSG(statement, fmt::system_error, \
|
||||
format_system_error(error_code, message))
|
||||
|
||||
#if FMT_USE_FILE_DESCRIPTORS
|
||||
|
||||
@@ -73,7 +71,7 @@ std::string format_system_error(int error_code, fmt::string_view message);
|
||||
// The output it can handle is limited by the pipe capacity.
|
||||
class OutputRedirect {
|
||||
private:
|
||||
FILE *file_;
|
||||
FILE* file_;
|
||||
fmt::file original_; // Original file passed to redirector.
|
||||
fmt::file read_end_; // Read end of the pipe where the output is redirected.
|
||||
|
||||
@@ -83,7 +81,7 @@ class OutputRedirect {
|
||||
void restore();
|
||||
|
||||
public:
|
||||
explicit OutputRedirect(FILE *file);
|
||||
explicit OutputRedirect(FILE* file);
|
||||
~OutputRedirect() FMT_NOEXCEPT;
|
||||
|
||||
// Restores the original file, reads output from the pipe into a string
|
||||
@@ -91,29 +89,28 @@ class OutputRedirect {
|
||||
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())
|
||||
# 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) \
|
||||
# define EXPECT_WRITE(file, statement, expected_output) \
|
||||
FMT_TEST_WRITE_(statement, expected_output, file, GTEST_NONFATAL_FAILURE_)
|
||||
|
||||
#ifdef _MSC_VER
|
||||
# ifdef _MSC_VER
|
||||
|
||||
// Suppresses Windows assertions on invalid file descriptors, making
|
||||
// POSIX functions return proper error codes instead of crashing on Windows.
|
||||
@@ -122,38 +119,41 @@ class SuppressAssert {
|
||||
_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) {}
|
||||
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)) {
|
||||
}
|
||||
: 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 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)
|
||||
# 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, std::size_t count);
|
||||
std::string read(fmt::file& f, std::size_t count);
|
||||
|
||||
#define EXPECT_READ(file, expected_content) \
|
||||
EXPECT_EQ(expected_content, read(file, std::strlen(expected_content)))
|
||||
# define EXPECT_READ(file, expected_content) \
|
||||
EXPECT_EQ(expected_content, read(file, std::strlen(expected_content)))
|
||||
|
||||
#endif // FMT_USE_FILE_DESCRIPTORS
|
||||
|
||||
template <typename Mock>
|
||||
struct ScopedMock : testing::StrictMock<Mock> {
|
||||
template <typename Mock> struct ScopedMock : testing::StrictMock<Mock> {
|
||||
ScopedMock() { Mock::instance = this; }
|
||||
~ScopedMock() { Mock::instance = FMT_NULL; }
|
||||
};
|
||||
|
||||
+1
-2
@@ -8,8 +8,7 @@
|
||||
#include "fmt/locale.h"
|
||||
#include "gmock.h"
|
||||
|
||||
template <typename Char>
|
||||
struct numpunct : std::numpunct<Char> {
|
||||
template <typename Char> struct numpunct : std::numpunct<Char> {
|
||||
protected:
|
||||
Char do_thousands_sep() const FMT_OVERRIDE { return '~'; }
|
||||
};
|
||||
|
||||
+14
-16
@@ -8,25 +8,23 @@
|
||||
#ifndef FMT_MOCK_ALLOCATOR_H_
|
||||
#define FMT_MOCK_ALLOCATOR_H_
|
||||
|
||||
#include "gmock.h"
|
||||
#include "fmt/format.h"
|
||||
#include "gmock.h"
|
||||
|
||||
template <typename T>
|
||||
class mock_allocator {
|
||||
template <typename T> class mock_allocator {
|
||||
public:
|
||||
mock_allocator() {}
|
||||
mock_allocator(const mock_allocator &) {}
|
||||
mock_allocator(const mock_allocator&) {}
|
||||
typedef T value_type;
|
||||
MOCK_METHOD1_T(allocate, T* (std::size_t n));
|
||||
MOCK_METHOD2_T(deallocate, void (T* p, std::size_t n));
|
||||
MOCK_METHOD1_T(allocate, T*(std::size_t n));
|
||||
MOCK_METHOD2_T(deallocate, void(T* p, std::size_t n));
|
||||
};
|
||||
|
||||
template <typename Allocator>
|
||||
class allocator_ref {
|
||||
template <typename Allocator> class allocator_ref {
|
||||
private:
|
||||
Allocator *alloc_;
|
||||
Allocator* alloc_;
|
||||
|
||||
void move(allocator_ref &other) {
|
||||
void move(allocator_ref& other) {
|
||||
alloc_ = other.alloc_;
|
||||
other.alloc_ = FMT_NULL;
|
||||
}
|
||||
@@ -34,24 +32,24 @@ class allocator_ref {
|
||||
public:
|
||||
typedef typename Allocator::value_type value_type;
|
||||
|
||||
explicit allocator_ref(Allocator *alloc = FMT_NULL) : alloc_(alloc) {}
|
||||
explicit allocator_ref(Allocator* alloc = FMT_NULL) : alloc_(alloc) {}
|
||||
|
||||
allocator_ref(const allocator_ref &other) : alloc_(other.alloc_) {}
|
||||
allocator_ref(allocator_ref &&other) { move(other); }
|
||||
allocator_ref(const allocator_ref& other) : alloc_(other.alloc_) {}
|
||||
allocator_ref(allocator_ref&& other) { move(other); }
|
||||
|
||||
allocator_ref& operator=(allocator_ref &&other) {
|
||||
allocator_ref& operator=(allocator_ref&& other) {
|
||||
assert(this != &other);
|
||||
move(other);
|
||||
return *this;
|
||||
}
|
||||
|
||||
allocator_ref& operator=(const allocator_ref &other) {
|
||||
allocator_ref& operator=(const allocator_ref& other) {
|
||||
alloc_ = other.alloc_;
|
||||
return *this;
|
||||
}
|
||||
|
||||
public:
|
||||
Allocator *get() const { return alloc_; }
|
||||
Allocator* get() const { return alloc_; }
|
||||
|
||||
value_type* allocate(std::size_t n) {
|
||||
return fmt::internal::allocate(*alloc_, n);
|
||||
|
||||
+31
-32
@@ -16,26 +16,26 @@
|
||||
using fmt::format;
|
||||
using fmt::format_error;
|
||||
|
||||
static std::ostream &operator<<(std::ostream &os, const Date &d) {
|
||||
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) {
|
||||
static std::wostream& operator<<(std::wostream& os, const Date& d) {
|
||||
os << d.year() << L'-' << d.month() << L'-' << d.day();
|
||||
return os;
|
||||
}
|
||||
|
||||
enum TestEnum {};
|
||||
static std::ostream &operator<<(std::ostream &os, TestEnum) {
|
||||
static std::ostream& operator<<(std::ostream& os, TestEnum) {
|
||||
return os << "TestEnum";
|
||||
}
|
||||
|
||||
static std::wostream &operator<<(std::wostream &os, TestEnum) {
|
||||
static std::wostream& operator<<(std::wostream& os, TestEnum) {
|
||||
return os << L"TestEnum";
|
||||
}
|
||||
|
||||
enum TestEnum2 {A};
|
||||
enum TestEnum2 { A };
|
||||
|
||||
TEST(OStreamTest, Enum) {
|
||||
EXPECT_FALSE((fmt::convert_to_int<TestEnum, char>::value));
|
||||
@@ -48,14 +48,14 @@ TEST(OStreamTest, Enum) {
|
||||
|
||||
typedef fmt::back_insert_range<fmt::internal::buffer> range;
|
||||
|
||||
struct test_arg_formatter: fmt::arg_formatter<range> {
|
||||
test_arg_formatter(fmt::format_context &ctx, fmt::format_specs &s)
|
||||
: fmt::arg_formatter<range>(ctx, &s) {}
|
||||
struct test_arg_formatter : fmt::arg_formatter<range> {
|
||||
test_arg_formatter(fmt::format_context& ctx, fmt::format_specs& s)
|
||||
: fmt::arg_formatter<range>(ctx, &s) {}
|
||||
};
|
||||
|
||||
TEST(OStreamTest, CustomArg) {
|
||||
fmt::memory_buffer buffer;
|
||||
fmt::internal::buffer &base = buffer;
|
||||
fmt::internal::buffer& base = buffer;
|
||||
fmt::format_context ctx(std::back_inserter(base), "", fmt::format_args());
|
||||
fmt::format_specs spec;
|
||||
test_arg_formatter af(ctx, spec);
|
||||
@@ -75,20 +75,20 @@ TEST(OStreamTest, Format) {
|
||||
TEST(OStreamTest, FormatSpecs) {
|
||||
EXPECT_EQ("def ", format("{0:<5}", TestString("def")));
|
||||
EXPECT_EQ(" def", format("{0:>5}", TestString("def")));
|
||||
EXPECT_THROW_MSG(format("{0:=5}", TestString("def")),
|
||||
format_error, "format specifier requires numeric argument");
|
||||
EXPECT_THROW_MSG(format("{0:=5}", TestString("def")), format_error,
|
||||
"format specifier requires numeric argument");
|
||||
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_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")));
|
||||
@@ -96,7 +96,7 @@ TEST(OStreamTest, FormatSpecs) {
|
||||
}
|
||||
|
||||
struct EmptyTest {};
|
||||
static std::ostream &operator<<(std::ostream &os, EmptyTest) {
|
||||
static std::ostream& operator<<(std::ostream& os, EmptyTest) {
|
||||
return os << "";
|
||||
}
|
||||
|
||||
@@ -116,7 +116,7 @@ TEST(OStreamTest, Print) {
|
||||
TEST(OStreamTest, WriteToOStream) {
|
||||
std::ostringstream os;
|
||||
fmt::memory_buffer buffer;
|
||||
const char *foo = "foo";
|
||||
const char* foo = "foo";
|
||||
buffer.append(foo, foo + std::strlen(foo));
|
||||
fmt::internal::write(os, buffer);
|
||||
EXPECT_EQ("foo", os.str());
|
||||
@@ -125,8 +125,7 @@ TEST(OStreamTest, WriteToOStream) {
|
||||
TEST(OStreamTest, WriteToOStreamMaxSize) {
|
||||
std::size_t max_size = std::numeric_limits<std::size_t>::max();
|
||||
std::streamsize max_streamsize = std::numeric_limits<std::streamsize>::max();
|
||||
if (max_size <= fmt::internal::to_unsigned(max_streamsize))
|
||||
return;
|
||||
if (max_size <= fmt::internal::to_unsigned(max_streamsize)) return;
|
||||
|
||||
struct test_buffer : fmt::internal::buffer {
|
||||
explicit test_buffer(std::size_t size) { resize(size); }
|
||||
@@ -134,19 +133,19 @@ TEST(OStreamTest, WriteToOStreamMaxSize) {
|
||||
} 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;
|
||||
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) {}
|
||||
explicit test_ostream(mock_streambuf& buffer) : std::ostream(&buffer) {}
|
||||
} os(streambuf);
|
||||
|
||||
testing::InSequence sequence;
|
||||
const char *data = FMT_NULL;
|
||||
const char* data = FMT_NULL;
|
||||
typedef std::make_unsigned<std::streamsize>::type ustreamsize;
|
||||
ustreamsize size = max_size;
|
||||
do {
|
||||
@@ -173,11 +172,11 @@ TEST(OStreamTest, ConstexprString) {
|
||||
namespace fmt_test {
|
||||
struct ABC {};
|
||||
|
||||
template <typename Output> Output &operator<<(Output &out, ABC) {
|
||||
template <typename Output> Output& operator<<(Output& out, ABC) {
|
||||
out << "ABC";
|
||||
return out;
|
||||
}
|
||||
} // namespace fmt_test
|
||||
} // namespace fmt_test
|
||||
|
||||
TEST(FormatTest, FormatToN) {
|
||||
char buffer[4];
|
||||
|
||||
+105
-101
@@ -7,21 +7,21 @@
|
||||
|
||||
// Disable bogus MSVC warnings.
|
||||
#ifdef _MSC_VER
|
||||
# define _CRT_SECURE_NO_WARNINGS
|
||||
# define _CRT_SECURE_NO_WARNINGS
|
||||
#endif
|
||||
|
||||
#include "posix-mock.h"
|
||||
#include "../src/posix.cc"
|
||||
|
||||
#include <climits>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <climits>
|
||||
#include <memory>
|
||||
|
||||
#ifdef _WIN32
|
||||
# include <io.h>
|
||||
# undef max
|
||||
# undef ERROR
|
||||
# include <io.h>
|
||||
# undef max
|
||||
# undef ERROR
|
||||
#endif
|
||||
|
||||
#include "gmock.h"
|
||||
@@ -33,8 +33,8 @@ using fmt::error_code;
|
||||
using fmt::file;
|
||||
|
||||
using testing::_;
|
||||
using testing::StrEq;
|
||||
using testing::Return;
|
||||
using testing::StrEq;
|
||||
|
||||
namespace {
|
||||
int open_count;
|
||||
@@ -53,24 +53,24 @@ std::size_t write_nbyte;
|
||||
bool sysconf_error;
|
||||
|
||||
enum FStatSimulation { 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; \
|
||||
} \
|
||||
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) {
|
||||
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) {
|
||||
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);
|
||||
}
|
||||
@@ -80,8 +80,7 @@ errno_t test::sopen_s(
|
||||
|
||||
long test::sysconf(int name) {
|
||||
long result = ::sysconf(name);
|
||||
if (!sysconf_error)
|
||||
return result;
|
||||
if (!sysconf_error) return result;
|
||||
// Simulate an error.
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
@@ -89,10 +88,9 @@ long test::sysconf(int name) {
|
||||
|
||||
static off_t max_file_size() { return std::numeric_limits<off_t>::max(); }
|
||||
|
||||
int test::fstat(int fd, struct stat *buf) {
|
||||
int test::fstat(int fd, struct stat* buf) {
|
||||
int result = ::fstat(fd, buf);
|
||||
if (fstat_sim == MAX_SIZE)
|
||||
buf->st_size = max_file_size();
|
||||
if (fstat_sim == MAX_SIZE) buf->st_size = max_file_size();
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -132,18 +130,18 @@ int test::dup2(int fildes, int fildes2) {
|
||||
return ::FMT_POSIX(dup2(fildes, fildes2));
|
||||
}
|
||||
|
||||
FILE *test::fdopen(int fildes, const char *mode) {
|
||||
FILE* test::fdopen(int fildes, const char* mode) {
|
||||
EMULATE_EINTR(fdopen, FMT_NULL);
|
||||
return ::FMT_POSIX(fdopen(fildes, mode));
|
||||
}
|
||||
|
||||
test::ssize_t test::read(int fildes, void *buf, test::size_t nbyte) {
|
||||
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) {
|
||||
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));
|
||||
@@ -155,23 +153,23 @@ int test::pipe(int fildes[2]) {
|
||||
return ::pipe(fildes);
|
||||
}
|
||||
#else
|
||||
int test::pipe(int *pfds, unsigned psize, int textmode) {
|
||||
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) {
|
||||
FILE* test::fopen(const char* filename, const char* mode) {
|
||||
EMULATE_EINTR(fopen, FMT_NULL);
|
||||
return ::fopen(filename, mode);
|
||||
}
|
||||
|
||||
int test::fclose(FILE *stream) {
|
||||
int test::fclose(FILE* stream) {
|
||||
EMULATE_EINTR(fclose, EOF);
|
||||
return ::fclose(stream);
|
||||
}
|
||||
|
||||
int (test::fileno)(FILE *stream) {
|
||||
int(test::fileno)(FILE* stream) {
|
||||
EMULATE_EINTR(fileno, -1);
|
||||
#ifdef fileno
|
||||
return FMT_POSIX(fileno(stream));
|
||||
@@ -181,18 +179,18 @@ int (test::fileno)(FILE *stream) {
|
||||
}
|
||||
|
||||
#ifndef _WIN32
|
||||
# define EXPECT_RETRY(statement, func, message) \
|
||||
func##_count = 1; \
|
||||
statement; \
|
||||
EXPECT_EQ(4, func##_count); \
|
||||
# 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)
|
||||
# define EXPECT_EQ_POSIX(expected, actual) EXPECT_EQ(expected, actual)
|
||||
#else
|
||||
# define EXPECT_RETRY(statement, func, message) \
|
||||
func##_count = 1; \
|
||||
# define EXPECT_RETRY(statement, func, message) \
|
||||
func##_count = 1; \
|
||||
EXPECT_SYSTEM_ERROR(statement, EINTR, message); \
|
||||
func##_count = 0;
|
||||
# define EXPECT_EQ_POSIX(expected, actual)
|
||||
# define EXPECT_EQ_POSIX(expected, actual)
|
||||
#endif
|
||||
|
||||
static void write_file(fmt::cstring_view filename, fmt::string_view content) {
|
||||
@@ -208,8 +206,8 @@ TEST(UtilTest, GetPageSize) {
|
||||
#else
|
||||
EXPECT_EQ(sysconf(_SC_PAGESIZE), fmt::getpagesize());
|
||||
sysconf_error = true;
|
||||
EXPECT_SYSTEM_ERROR(
|
||||
fmt::getpagesize(), EINVAL, "cannot get memory page size");
|
||||
EXPECT_SYSTEM_ERROR(fmt::getpagesize(), EINVAL,
|
||||
"cannot get memory page size");
|
||||
sysconf_error = false;
|
||||
#endif
|
||||
}
|
||||
@@ -217,8 +215,8 @@ TEST(UtilTest, GetPageSize) {
|
||||
TEST(FileTest, OpenRetry) {
|
||||
write_file("test", "there must be something here");
|
||||
std::unique_ptr<file> f{FMT_NULL};
|
||||
EXPECT_RETRY(f.reset(new file("test", file::RDONLY)),
|
||||
open, "cannot open file test");
|
||||
EXPECT_RETRY(f.reset(new file("test", file::RDONLY)), open,
|
||||
"cannot open file test");
|
||||
#ifndef _WIN32
|
||||
char c = 0;
|
||||
f->read(&c, 1);
|
||||
@@ -230,12 +228,14 @@ TEST(FileTest, CloseNoRetryInDtor) {
|
||||
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(FMT_NULL);
|
||||
saved_close_count = close_count;
|
||||
close_count = 0;
|
||||
}, format_system_error(EINTR, "cannot close file") + "\n");
|
||||
EXPECT_WRITE(stderr,
|
||||
{
|
||||
close_count = 1;
|
||||
f.reset(FMT_NULL);
|
||||
saved_close_count = close_count;
|
||||
close_count = 0;
|
||||
},
|
||||
format_system_error(EINTR, "cannot close file") + "\n");
|
||||
EXPECT_EQ(2, saved_close_count);
|
||||
}
|
||||
|
||||
@@ -256,8 +256,8 @@ TEST(FileTest, Size) {
|
||||
EXPECT_EQ(content.size(), static_cast<unsigned long long>(f.size()));
|
||||
#ifdef _WIN32
|
||||
fmt::memory_buffer message;
|
||||
fmt::internal::format_windows_error(
|
||||
message, ERROR_ACCESS_DENIED, "cannot get file size");
|
||||
fmt::internal::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;
|
||||
@@ -284,8 +284,8 @@ TEST(FileTest, ReadRetry) {
|
||||
write_end.close();
|
||||
char buffer[SIZE];
|
||||
std::size_t count = 0;
|
||||
EXPECT_RETRY(count = read_end.read(buffer, SIZE),
|
||||
read, "cannot read from file");
|
||||
EXPECT_RETRY(count = read_end.read(buffer, SIZE), read,
|
||||
"cannot read from file");
|
||||
EXPECT_EQ_POSIX(static_cast<std::streamsize>(SIZE), count);
|
||||
}
|
||||
|
||||
@@ -294,8 +294,8 @@ TEST(FileTest, WriteRetry) {
|
||||
file::pipe(read_end, write_end);
|
||||
enum { SIZE = 4 };
|
||||
std::size_t count = 0;
|
||||
EXPECT_RETRY(count = write_end.write("test", SIZE),
|
||||
write, "cannot write to file");
|
||||
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);
|
||||
@@ -312,8 +312,7 @@ TEST(FileTest, ConvertReadCount) {
|
||||
file::pipe(read_end, write_end);
|
||||
char c;
|
||||
std::size_t size = UINT_MAX;
|
||||
if (sizeof(unsigned) != sizeof(std::size_t))
|
||||
++size;
|
||||
if (sizeof(unsigned) != sizeof(std::size_t)) ++size;
|
||||
read_count = 1;
|
||||
read_nbyte = 0;
|
||||
EXPECT_THROW(read_end.read(&c, size), fmt::system_error);
|
||||
@@ -326,8 +325,7 @@ TEST(FileTest, ConvertWriteCount) {
|
||||
file::pipe(read_end, write_end);
|
||||
char c;
|
||||
std::size_t size = UINT_MAX;
|
||||
if (sizeof(unsigned) != sizeof(std::size_t))
|
||||
++size;
|
||||
if (sizeof(unsigned) != sizeof(std::size_t)) ++size;
|
||||
write_count = 1;
|
||||
write_nbyte = 0;
|
||||
EXPECT_THROW(write_end.write(&c, size), fmt::system_error);
|
||||
@@ -339,7 +337,8 @@ TEST(FileTest, ConvertWriteCount) {
|
||||
TEST(FileTest, DupNoRetry) {
|
||||
int stdout_fd = FMT_POSIX(fileno(stdout));
|
||||
dup_count = 1;
|
||||
EXPECT_SYSTEM_ERROR(file::dup(stdout_fd), EINTR,
|
||||
EXPECT_SYSTEM_ERROR(
|
||||
file::dup(stdout_fd), EINTR,
|
||||
fmt::format("cannot duplicate file descriptor {}", stdout_fd));
|
||||
dup_count = 0;
|
||||
}
|
||||
@@ -348,8 +347,8 @@ 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()));
|
||||
fmt::format("cannot duplicate file descriptor {} to {}",
|
||||
f1.descriptor(), f2.descriptor()));
|
||||
}
|
||||
|
||||
TEST(FileTest, Dup2NoExceptRetry) {
|
||||
@@ -369,8 +368,8 @@ TEST(FileTest, Dup2NoExceptRetry) {
|
||||
TEST(FileTest, PipeNoRetry) {
|
||||
file read_end, write_end;
|
||||
pipe_count = 1;
|
||||
EXPECT_SYSTEM_ERROR(
|
||||
file::pipe(read_end, write_end), EINTR, "cannot create pipe");
|
||||
EXPECT_SYSTEM_ERROR(file::pipe(read_end, write_end), EINTR,
|
||||
"cannot create pipe");
|
||||
pipe_count = 0;
|
||||
}
|
||||
|
||||
@@ -378,16 +377,16 @@ 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");
|
||||
EXPECT_SYSTEM_ERROR(read_end.fdopen("r"), EINTR,
|
||||
"cannot associate stream with file descriptor");
|
||||
fdopen_count = 0;
|
||||
}
|
||||
|
||||
TEST(BufferedFileTest, OpenRetry) {
|
||||
write_file("test", "there must be something here");
|
||||
std::unique_ptr<buffered_file> f{FMT_NULL};
|
||||
EXPECT_RETRY(f.reset(new buffered_file("test", "r")),
|
||||
fopen, "cannot open file test");
|
||||
EXPECT_RETRY(f.reset(new buffered_file("test", "r")), fopen,
|
||||
"cannot open file test");
|
||||
#ifndef _WIN32
|
||||
char c = 0;
|
||||
if (fread(&c, 1, 1, f->get()) < 1)
|
||||
@@ -400,12 +399,14 @@ TEST(BufferedFileTest, CloseNoRetryInDtor) {
|
||||
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(FMT_NULL);
|
||||
saved_fclose_count = fclose_count;
|
||||
fclose_count = 0;
|
||||
}, format_system_error(EINTR, "cannot close file") + "\n");
|
||||
EXPECT_WRITE(stderr,
|
||||
{
|
||||
fclose_count = 1;
|
||||
f.reset(FMT_NULL);
|
||||
saved_fclose_count = fclose_count;
|
||||
fclose_count = 0;
|
||||
},
|
||||
format_system_error(EINTR, "cannot close file") + "\n");
|
||||
EXPECT_EQ(2, saved_fclose_count);
|
||||
}
|
||||
|
||||
@@ -430,14 +431,14 @@ TEST(BufferedFileTest, FilenoNoRetry) {
|
||||
}
|
||||
|
||||
struct TestMock {
|
||||
static TestMock *instance;
|
||||
} *TestMock::instance;
|
||||
static TestMock* instance;
|
||||
} * TestMock::instance;
|
||||
|
||||
TEST(ScopedMock, Scope) {
|
||||
{
|
||||
ScopedMock<TestMock> mock;
|
||||
EXPECT_EQ(&mock, TestMock::instance);
|
||||
TestMock © = mock;
|
||||
TestMock& copy = mock;
|
||||
static_cast<void>(copy);
|
||||
}
|
||||
EXPECT_EQ(FMT_NULL, TestMock::instance);
|
||||
@@ -448,20 +449,20 @@ TEST(ScopedMock, Scope) {
|
||||
typedef fmt::Locale::Type LocaleType;
|
||||
|
||||
struct LocaleMock {
|
||||
static LocaleMock *instance;
|
||||
MOCK_METHOD3(newlocale, LocaleType (int category_mask, const char *locale,
|
||||
LocaleType base));
|
||||
MOCK_METHOD1(freelocale, void (LocaleType locale));
|
||||
static LocaleMock* instance;
|
||||
MOCK_METHOD3(newlocale, LocaleType(int category_mask, const char* locale,
|
||||
LocaleType base));
|
||||
MOCK_METHOD1(freelocale, void(LocaleType locale));
|
||||
|
||||
MOCK_METHOD3(strtod_l, double (const char *nptr, char **endptr,
|
||||
LocaleType locale));
|
||||
} *LocaleMock::instance;
|
||||
MOCK_METHOD3(strtod_l,
|
||||
double(const char* nptr, char** endptr, LocaleType locale));
|
||||
} * LocaleMock::instance;
|
||||
|
||||
#ifdef _MSC_VER
|
||||
# pragma warning(push)
|
||||
# pragma warning(disable: 4273)
|
||||
# ifdef _MSC_VER
|
||||
# pragma warning(push)
|
||||
# pragma warning(disable : 4273)
|
||||
|
||||
_locale_t _create_locale(int category, const char *locale) {
|
||||
_locale_t _create_locale(int category, const char* locale) {
|
||||
return LocaleMock::instance->newlocale(category, locale, 0);
|
||||
}
|
||||
|
||||
@@ -469,38 +470,41 @@ void _free_locale(_locale_t locale) {
|
||||
LocaleMock::instance->freelocale(locale);
|
||||
}
|
||||
|
||||
double _strtod_l(const char *nptr, char **endptr, _locale_t locale) {
|
||||
double _strtod_l(const char* nptr, char** endptr, _locale_t locale) {
|
||||
return LocaleMock::instance->strtod_l(nptr, endptr, locale);
|
||||
}
|
||||
# pragma warning(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(__THROW) && FMT_GCC_VERSION > 0 && FMT_GCC_VERSION <= 408
|
||||
# define FMT_LOCALE_THROW __THROW
|
||||
# else
|
||||
# define FMT_LOCALE_THROW
|
||||
# endif
|
||||
|
||||
LocaleType newlocale(int category_mask, const char *locale, LocaleType base) FMT_LOCALE_THROW {
|
||||
LocaleType newlocale(int category_mask, const char* locale,
|
||||
LocaleType base) FMT_LOCALE_THROW {
|
||||
return LocaleMock::instance->newlocale(category_mask, locale, base);
|
||||
}
|
||||
|
||||
#if defined(__APPLE__) || (defined(__FreeBSD__) && __FreeBSD_version < 1200002)
|
||||
# if defined(__APPLE__) || \
|
||||
(defined(__FreeBSD__) && __FreeBSD_version < 1200002)
|
||||
typedef int FreeLocaleResult;
|
||||
#else
|
||||
# else
|
||||
typedef void FreeLocaleResult;
|
||||
#endif
|
||||
# endif
|
||||
|
||||
FreeLocaleResult freelocale(LocaleType locale) FMT_LOCALE_THROW {
|
||||
LocaleMock::instance->freelocale(locale);
|
||||
return FreeLocaleResult();
|
||||
}
|
||||
|
||||
double strtod_l(const char *nptr, char **endptr, LocaleType locale) FMT_LOCALE_THROW {
|
||||
double strtod_l(const char* nptr, char** endptr,
|
||||
LocaleType locale) FMT_LOCALE_THROW {
|
||||
return LocaleMock::instance->strtod_l(nptr, endptr, locale);
|
||||
}
|
||||
|
||||
#undef FMT_LOCALE_THROW
|
||||
# undef FMT_LOCALE_THROW
|
||||
|
||||
TEST(LocaleTest, LocaleMock) {
|
||||
ScopedMock<LocaleMock> mock;
|
||||
@@ -510,9 +514,9 @@ TEST(LocaleTest, LocaleMock) {
|
||||
}
|
||||
|
||||
TEST(LocaleTest, Locale) {
|
||||
#ifndef LC_NUMERIC_MASK
|
||||
# ifndef LC_NUMERIC_MASK
|
||||
enum { LC_NUMERIC_MASK = LC_NUMERIC };
|
||||
#endif
|
||||
# endif
|
||||
ScopedMock<LocaleMock> mock;
|
||||
LocaleType impl = reinterpret_cast<LocaleType>(42);
|
||||
EXPECT_CALL(mock, newlocale(LC_NUMERIC_MASK, StrEq("C"), FMT_NULL))
|
||||
@@ -528,7 +532,7 @@ TEST(LocaleTest, Strtod) {
|
||||
.WillOnce(Return(reinterpret_cast<LocaleType>(42)));
|
||||
EXPECT_CALL(mock, freelocale(_));
|
||||
fmt::Locale locale;
|
||||
const char *str = "4.2";
|
||||
const char* str = "4.2";
|
||||
char end = 'x';
|
||||
EXPECT_CALL(mock, strtod_l(str, _, locale.get()))
|
||||
.WillOnce(testing::DoAll(testing::SetArgPointee<1>(&end), Return(777)));
|
||||
|
||||
+14
-14
@@ -12,10 +12,10 @@
|
||||
#include <stdio.h>
|
||||
|
||||
#ifdef _WIN32
|
||||
# include <windows.h>
|
||||
# include <windows.h>
|
||||
#else
|
||||
# include <sys/param.h> // for FreeBSD version
|
||||
# include <sys/types.h> // for ssize_t
|
||||
# include <sys/param.h> // for FreeBSD version
|
||||
# include <sys/types.h> // for ssize_t
|
||||
#endif
|
||||
|
||||
#ifndef _MSC_VER
|
||||
@@ -28,13 +28,13 @@ namespace test {
|
||||
// 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);
|
||||
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);
|
||||
errno_t sopen_s(int* pfh, const char* filename, int oflag, int shflag,
|
||||
int pmode);
|
||||
#endif
|
||||
|
||||
#ifndef _WIN32
|
||||
@@ -48,20 +48,20 @@ int close(int fildes);
|
||||
int dup(int fildes);
|
||||
int dup2(int fildes, int fildes2);
|
||||
|
||||
FILE *fdopen(int fildes, const char *mode);
|
||||
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);
|
||||
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);
|
||||
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);
|
||||
FILE* fopen(const char* filename, const char* mode);
|
||||
int fclose(FILE* stream);
|
||||
int(fileno)(FILE* stream);
|
||||
} // namespace test
|
||||
|
||||
#define FMT_SYSTEM(call) test::call
|
||||
|
||||
+47
-40
@@ -14,7 +14,7 @@
|
||||
#include "util.h"
|
||||
|
||||
#ifdef fileno
|
||||
# undef fileno
|
||||
# undef fileno
|
||||
#endif
|
||||
|
||||
using fmt::buffered_file;
|
||||
@@ -44,9 +44,9 @@ static file open_file() {
|
||||
}
|
||||
|
||||
// Attempts to write a string to a file.
|
||||
static void write(file &f, fmt::string_view s) {
|
||||
static void write(file& f, fmt::string_view s) {
|
||||
std::size_t num_chars_left = s.size();
|
||||
const char *ptr = s.data();
|
||||
const char* ptr = s.data();
|
||||
do {
|
||||
std::size_t count = f.write(ptr, num_chars_left);
|
||||
ptr += count;
|
||||
@@ -63,7 +63,7 @@ TEST(BufferedFileTest, DefaultCtor) {
|
||||
|
||||
TEST(BufferedFileTest, MoveCtor) {
|
||||
buffered_file bf = open_buffered_file();
|
||||
FILE *fp = bf.get();
|
||||
FILE* fp = bf.get();
|
||||
EXPECT_TRUE(fp != FMT_NULL);
|
||||
buffered_file bf2(std::move(bf));
|
||||
EXPECT_EQ(fp, bf2.get());
|
||||
@@ -72,7 +72,7 @@ TEST(BufferedFileTest, MoveCtor) {
|
||||
|
||||
TEST(BufferedFileTest, MoveAssignment) {
|
||||
buffered_file bf = open_buffered_file();
|
||||
FILE *fp = bf.get();
|
||||
FILE* fp = bf.get();
|
||||
EXPECT_TRUE(fp != FMT_NULL);
|
||||
buffered_file bf2;
|
||||
bf2 = std::move(bf);
|
||||
@@ -89,13 +89,13 @@ TEST(BufferedFileTest, MoveAssignmentClosesFile) {
|
||||
}
|
||||
|
||||
TEST(BufferedFileTest, MoveFromTemporaryInCtor) {
|
||||
FILE *fp = FMT_NULL;
|
||||
FILE* fp = FMT_NULL;
|
||||
buffered_file f(open_buffered_file(&fp));
|
||||
EXPECT_EQ(fp, f.get());
|
||||
}
|
||||
|
||||
TEST(BufferedFileTest, MoveFromTemporaryInAssignment) {
|
||||
FILE *fp = FMT_NULL;
|
||||
FILE* fp = FMT_NULL;
|
||||
buffered_file f;
|
||||
f = open_buffered_file(&fp);
|
||||
EXPECT_EQ(fp, f.get());
|
||||
@@ -119,14 +119,16 @@ TEST(BufferedFileTest, CloseFileInDtor) {
|
||||
|
||||
TEST(BufferedFileTest, CloseErrorInDtor) {
|
||||
std::unique_ptr<buffered_file> f(new buffered_file(open_buffered_file()));
|
||||
EXPECT_WRITE(stderr, {
|
||||
// The close function must be called inside EXPECT_WRITE, otherwise
|
||||
// the system may recycle closed file descriptor when redirecting the
|
||||
// output in EXPECT_STDERR and the second close will break output
|
||||
// redirection.
|
||||
FMT_POSIX(close(f->fileno()));
|
||||
SUPPRESS_ASSERT(f.reset(FMT_NULL));
|
||||
}, format_system_error(EBADF, "cannot close file") + "\n");
|
||||
EXPECT_WRITE(stderr,
|
||||
{
|
||||
// The close function must be called inside EXPECT_WRITE,
|
||||
// otherwise the system may recycle closed file descriptor when
|
||||
// redirecting the output in EXPECT_STDERR and the second close
|
||||
// will break output redirection.
|
||||
FMT_POSIX(close(f->fileno()));
|
||||
SUPPRESS_ASSERT(f.reset(FMT_NULL));
|
||||
},
|
||||
format_system_error(EBADF, "cannot close file") + "\n");
|
||||
}
|
||||
|
||||
TEST(BufferedFileTest, Close) {
|
||||
@@ -149,13 +151,15 @@ TEST(BufferedFileTest, Fileno) {
|
||||
#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);
|
||||
}
|
||||
}, "");
|
||||
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);
|
||||
@@ -169,7 +173,7 @@ TEST(FileTest, DefaultCtor) {
|
||||
}
|
||||
|
||||
TEST(FileTest, OpenBufferedFileInCtor) {
|
||||
FILE *fp = safe_fopen("test-file", "w");
|
||||
FILE* fp = safe_fopen("test-file", "w");
|
||||
std::fputs(FILE_CONTENT, fp);
|
||||
std::fclose(fp);
|
||||
file f("test-file", file::RDONLY);
|
||||
@@ -177,8 +181,8 @@ TEST(FileTest, OpenBufferedFileInCtor) {
|
||||
}
|
||||
|
||||
TEST(FileTest, OpenBufferedFileError) {
|
||||
EXPECT_SYSTEM_ERROR(file("nonexistent", file::RDONLY),
|
||||
ENOENT, "cannot open file nonexistent");
|
||||
EXPECT_SYSTEM_ERROR(file("nonexistent", file::RDONLY), ENOENT,
|
||||
"cannot open file nonexistent");
|
||||
}
|
||||
|
||||
TEST(FileTest, MoveCtor) {
|
||||
@@ -208,7 +212,7 @@ TEST(FileTest, MoveAssignmentClosesFile) {
|
||||
EXPECT_TRUE(isclosed(old_fd));
|
||||
}
|
||||
|
||||
static file OpenBufferedFile(int &fd) {
|
||||
static file OpenBufferedFile(int& fd) {
|
||||
file f = open_file();
|
||||
fd = f.descriptor();
|
||||
return f;
|
||||
@@ -246,14 +250,16 @@ TEST(FileTest, CloseFileInDtor) {
|
||||
|
||||
TEST(FileTest, CloseErrorInDtor) {
|
||||
std::unique_ptr<file> f(new file(open_file()));
|
||||
EXPECT_WRITE(stderr, {
|
||||
// The close function must be called inside EXPECT_WRITE, otherwise
|
||||
// the system may recycle closed file descriptor when redirecting the
|
||||
// output in EXPECT_STDERR and the second close will break output
|
||||
// redirection.
|
||||
FMT_POSIX(close(f->descriptor()));
|
||||
SUPPRESS_ASSERT(f.reset(FMT_NULL));
|
||||
}, format_system_error(EBADF, "cannot close file") + "\n");
|
||||
EXPECT_WRITE(stderr,
|
||||
{
|
||||
// The close function must be called inside EXPECT_WRITE,
|
||||
// otherwise the system may recycle closed file descriptor when
|
||||
// redirecting the output in EXPECT_STDERR and the second close
|
||||
// will break output redirection.
|
||||
FMT_POSIX(close(f->descriptor()));
|
||||
SUPPRESS_ASSERT(f.reset(FMT_NULL));
|
||||
},
|
||||
format_system_error(EBADF, "cannot close file") + "\n");
|
||||
}
|
||||
|
||||
TEST(FileTest, Close) {
|
||||
@@ -309,8 +315,8 @@ TEST(FileTest, Dup) {
|
||||
#ifndef __COVERITY__
|
||||
TEST(FileTest, DupError) {
|
||||
int value = -1;
|
||||
EXPECT_SYSTEM_ERROR_NOASSERT(file::dup(value),
|
||||
EBADF, "cannot duplicate file descriptor -1");
|
||||
EXPECT_SYSTEM_ERROR_NOASSERT(file::dup(value), EBADF,
|
||||
"cannot duplicate file descriptor -1");
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -324,8 +330,9 @@ TEST(FileTest, Dup2) {
|
||||
|
||||
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()));
|
||||
EXPECT_SYSTEM_ERROR_NOASSERT(
|
||||
f.dup2(-1), EBADF,
|
||||
fmt::format("cannot duplicate file descriptor {} to -1", f.descriptor()));
|
||||
}
|
||||
|
||||
TEST(FileTest, Dup2NoExcept) {
|
||||
@@ -363,8 +370,8 @@ TEST(FileTest, Fdopen) {
|
||||
|
||||
TEST(FileTest, FdopenError) {
|
||||
file f;
|
||||
EXPECT_SYSTEM_ERROR_NOASSERT(
|
||||
f.fdopen("r"), EBADF, "cannot associate stream with file descriptor");
|
||||
EXPECT_SYSTEM_ERROR_NOASSERT(f.fdopen("r"), EBADF,
|
||||
"cannot associate stream with file descriptor");
|
||||
}
|
||||
|
||||
#ifdef FMT_LOCALE
|
||||
|
||||
+41
-39
@@ -5,6 +5,7 @@
|
||||
//
|
||||
// For the license information refer to prepare.h.
|
||||
|
||||
#include <stdint.h>
|
||||
#include <cctype>
|
||||
#include <cfloat>
|
||||
#include <climits>
|
||||
@@ -13,12 +14,11 @@
|
||||
#include <deque>
|
||||
#include <list>
|
||||
#include <memory>
|
||||
#include <stdint.h>
|
||||
#include <string>
|
||||
|
||||
// Check if fmt/prepare.h compiles with windows.h included before it.
|
||||
#ifdef _WIN32
|
||||
#include <windows.h>
|
||||
# include <windows.h>
|
||||
#endif
|
||||
|
||||
#include "fmt/prepare.h"
|
||||
@@ -35,24 +35,24 @@ using testing::Return;
|
||||
using testing::StrictMock;
|
||||
|
||||
class mock_parts_collector {
|
||||
public:
|
||||
public:
|
||||
MOCK_METHOD1(add, void(fmt::format_part<char>));
|
||||
MOCK_METHOD1(substitute_last, void(fmt::format_part<char>));
|
||||
MOCK_METHOD0(last, fmt::format_part<char>());
|
||||
};
|
||||
|
||||
FMT_BEGIN_NAMESPACE
|
||||
bool operator==(const internal::string_view_metadata &lhs,
|
||||
const internal::string_view_metadata &rhs) {
|
||||
bool operator==(const internal::string_view_metadata& lhs,
|
||||
const internal::string_view_metadata& rhs) {
|
||||
return std::tie(lhs.offset_, lhs.size_) == std::tie(rhs.offset_, rhs.size_);
|
||||
}
|
||||
bool operator!=(const internal::string_view_metadata &lhs,
|
||||
const internal::string_view_metadata &rhs) {
|
||||
bool operator!=(const internal::string_view_metadata& lhs,
|
||||
const internal::string_view_metadata& rhs) {
|
||||
return !(lhs == rhs);
|
||||
}
|
||||
|
||||
bool operator==(const format_part<char>::specification &lhs,
|
||||
const format_part<char>::specification &rhs) {
|
||||
bool operator==(const format_part<char>::specification& lhs,
|
||||
const format_part<char>::specification& rhs) {
|
||||
if (lhs.arg_id.which != rhs.arg_id.which) {
|
||||
return false;
|
||||
}
|
||||
@@ -79,13 +79,13 @@ bool operator==(const format_part<char>::specification &lhs,
|
||||
rhs.parsed_specs.flags, rhs.parsed_specs.type);
|
||||
}
|
||||
|
||||
bool operator!=(const format_part<char>::specification &lhs,
|
||||
const format_part<char>::specification &rhs) {
|
||||
bool operator!=(const format_part<char>::specification& lhs,
|
||||
const format_part<char>::specification& rhs) {
|
||||
return !(lhs == rhs);
|
||||
}
|
||||
|
||||
bool operator==(const format_part<char> &lhs,
|
||||
const fmt::format_part<char> &rhs) {
|
||||
bool operator==(const format_part<char>& lhs,
|
||||
const fmt::format_part<char>& rhs) {
|
||||
typedef format_part<char>::which_value which_value;
|
||||
|
||||
if (lhs.which != rhs.which ||
|
||||
@@ -114,8 +114,8 @@ bool operator==(const format_part<char> &lhs,
|
||||
return false;
|
||||
}
|
||||
|
||||
bool operator!=(const fmt::format_part<char> &lhs,
|
||||
const fmt::format_part<char> &rhs) {
|
||||
bool operator!=(const fmt::format_part<char>& lhs,
|
||||
const fmt::format_part<char>& rhs) {
|
||||
return !(lhs == rhs);
|
||||
}
|
||||
FMT_END_NAMESPACE
|
||||
@@ -303,13 +303,15 @@ TEST(PrepareTest, FormatPreparationHandler_OnArgId_AddsPartWithPassedNamedId) {
|
||||
const auto expected_third_arg_id = fmt::string_view(format.data() + 6, 3);
|
||||
const auto expected_third_arg_view_metadata =
|
||||
fmt::internal::string_view_metadata(6, 3);
|
||||
EXPECT_CALL(parts, add(format_part(
|
||||
named_argument_id(expected_first_arg_view_metadata))));
|
||||
EXPECT_CALL(
|
||||
parts,
|
||||
add(format_part(named_argument_id(expected_first_arg_view_metadata))));
|
||||
EXPECT_CALL(
|
||||
parts,
|
||||
add(format_part(named_argument_id(expected_second_arg_view_metadata))));
|
||||
EXPECT_CALL(parts, add(format_part(
|
||||
named_argument_id(expected_third_arg_view_metadata))));
|
||||
EXPECT_CALL(
|
||||
parts,
|
||||
add(format_part(named_argument_id(expected_third_arg_view_metadata))));
|
||||
|
||||
handler.on_arg_id(expected_first_arg_id);
|
||||
handler.on_arg_id(expected_second_arg_id);
|
||||
@@ -423,13 +425,13 @@ TEST(PrepareTest, CompileTimePreparedPartsTypeProvider) {
|
||||
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<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'
|
||||
FMT_STRING("text{{}}text")); // 'text', '{', '}', 'text'
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -500,13 +502,13 @@ TEST(PrepareTest, UserProvidedPartsContainerUnderlyingContainer) {
|
||||
}
|
||||
|
||||
class custom_parts_container {
|
||||
public:
|
||||
public:
|
||||
typedef fmt::format_part<char> format_part_type;
|
||||
|
||||
private:
|
||||
private:
|
||||
typedef std::deque<format_part_type> parts;
|
||||
|
||||
public:
|
||||
public:
|
||||
void add(format_part_type part) { parts_.push_back(std::move(part)); }
|
||||
|
||||
void substitute_last(format_part_type part) {
|
||||
@@ -532,7 +534,7 @@ public:
|
||||
return parts_.end();
|
||||
}
|
||||
|
||||
private:
|
||||
private:
|
||||
parts parts_;
|
||||
};
|
||||
|
||||
@@ -547,10 +549,10 @@ TEST(PrepareTest, UserProvidedPartsContainer) {
|
||||
}
|
||||
|
||||
TEST(PrepareTest, PassConstCharPointerFormat) {
|
||||
const char *c_format = "test {}";
|
||||
const char* c_format = "test {}";
|
||||
const auto prepared = fmt::prepare<int>(c_format);
|
||||
EXPECT_EQ("test 42", prepared.format(42));
|
||||
const wchar_t *wc_format = L"test {}";
|
||||
const wchar_t* wc_format = L"test {}";
|
||||
const auto wprepared = fmt::prepare<int>(wc_format);
|
||||
EXPECT_EQ(L"test 42", wprepared.format(42));
|
||||
}
|
||||
@@ -607,10 +609,10 @@ TEST(PrepareTest, PassCompileString) {
|
||||
|
||||
template <typename T> struct user_allocator {
|
||||
typedef T value_type;
|
||||
typedef value_type *pointer;
|
||||
typedef const value_type *const_pointer;
|
||||
typedef value_type &reference;
|
||||
typedef const value_type &const_reference;
|
||||
typedef value_type* pointer;
|
||||
typedef const value_type* const_pointer;
|
||||
typedef value_type& reference;
|
||||
typedef const value_type& const_reference;
|
||||
typedef std::size_t size_type;
|
||||
typedef std::ptrdiff_t difference_type;
|
||||
|
||||
@@ -618,7 +620,7 @@ template <typename T> struct user_allocator {
|
||||
|
||||
user_allocator() = default;
|
||||
~user_allocator() = default;
|
||||
template <typename U> user_allocator(const user_allocator<U> &) {}
|
||||
template <typename U> user_allocator(const user_allocator<U>&) {}
|
||||
|
||||
pointer allocate(size_type cnt,
|
||||
typename std::allocator<void>::const_pointer = 0) {
|
||||
@@ -627,12 +629,12 @@ template <typename T> struct user_allocator {
|
||||
|
||||
void deallocate(pointer p, size_type cnt) { delete[] p; }
|
||||
|
||||
void construct(pointer p, const value_type &val) { new (p) value_type(val); }
|
||||
void construct(pointer p, const value_type& val) { new (p) value_type(val); }
|
||||
|
||||
void destroy(pointer p) { (*p).~value_type(); }
|
||||
|
||||
bool operator==(const user_allocator &other) const { return true; }
|
||||
bool operator!=(const user_allocator &other) const { return false; }
|
||||
bool operator==(const user_allocator& other) const { return true; }
|
||||
bool operator!=(const user_allocator& other) const { return false; }
|
||||
};
|
||||
|
||||
TEST(PrepareTest, PassUserTypeFormat) {
|
||||
|
||||
+83
-95
@@ -35,17 +35,17 @@ static std::wstring make_positional(fmt::wstring_view format) {
|
||||
// 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) {
|
||||
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) {
|
||||
std::wstring test_sprintf(fmt::wstring_view format, const Args&... args) {
|
||||
return fmt::sprintf(format, args...);
|
||||
}
|
||||
|
||||
#define EXPECT_PRINTF(expected_output, format, arg) \
|
||||
#define EXPECT_PRINTF(expected_output, format, arg) \
|
||||
EXPECT_EQ(expected_output, test_sprintf(format, arg)) \
|
||||
<< "format: " << format; \
|
||||
<< "format: " << format; \
|
||||
EXPECT_EQ(expected_output, fmt::sprintf(make_positional(format), arg))
|
||||
|
||||
TEST(PrintfTest, NoArgs) {
|
||||
@@ -69,11 +69,10 @@ TEST(PrintfTest, Escape) {
|
||||
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("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("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"));
|
||||
}
|
||||
|
||||
@@ -82,46 +81,46 @@ TEST(PrintfTest, AutomaticArgIndexing) {
|
||||
}
|
||||
|
||||
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");
|
||||
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("%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");
|
||||
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");
|
||||
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");
|
||||
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");
|
||||
format_error, "number is too big");
|
||||
}
|
||||
|
||||
TEST(PrintfTest, InvalidArgIndex) {
|
||||
EXPECT_THROW_MSG(test_sprintf("%0$d", 42), format_error,
|
||||
"argument index out of range");
|
||||
"argument index out of range");
|
||||
EXPECT_THROW_MSG(test_sprintf("%2$d", 42), format_error,
|
||||
"argument index out of range");
|
||||
EXPECT_THROW_MSG(test_sprintf(format("%{}$d", INT_MAX), 42),
|
||||
format_error, "argument index out of range");
|
||||
"argument index out of range");
|
||||
EXPECT_THROW_MSG(test_sprintf(format("%{}$d", INT_MAX), 42), format_error,
|
||||
"argument index out of range");
|
||||
|
||||
EXPECT_THROW_MSG(test_sprintf("%2$", 42),
|
||||
format_error, "argument index out of range");
|
||||
EXPECT_THROW_MSG(test_sprintf(format("%{}$d", BIG_NUM), 42),
|
||||
format_error, "number is too big");
|
||||
EXPECT_THROW_MSG(test_sprintf("%2$", 42), format_error,
|
||||
"argument index out of range");
|
||||
EXPECT_THROW_MSG(test_sprintf(format("%{}$d", BIG_NUM), 42), format_error,
|
||||
"number is too big");
|
||||
}
|
||||
|
||||
TEST(PrintfTest, DefaultAlignRight) {
|
||||
@@ -175,8 +174,8 @@ TEST(PrintfTest, HashFlag) {
|
||||
|
||||
EXPECT_PRINTF("0x42", "%#x", 0x42);
|
||||
EXPECT_PRINTF("0X42", "%#X", 0x42);
|
||||
EXPECT_PRINTF(
|
||||
fmt::format("0x{:x}", static_cast<unsigned>(-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);
|
||||
@@ -208,23 +207,23 @@ TEST(PrintfTest, Width) {
|
||||
|
||||
// Width cannot be specified twice.
|
||||
EXPECT_THROW_MSG(test_sprintf("%5-5d", 42), format_error,
|
||||
"invalid type specifier");
|
||||
"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");
|
||||
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");
|
||||
"width is not integer");
|
||||
EXPECT_THROW_MSG(test_sprintf("%*d"), format_error,
|
||||
"argument index out of range");
|
||||
"argument index out of range");
|
||||
EXPECT_THROW_MSG(test_sprintf("%*d", BIG_NUM, 42), format_error,
|
||||
"number is too big");
|
||||
"number is too big");
|
||||
}
|
||||
|
||||
TEST(PrintfTest, IntPrecision) {
|
||||
@@ -267,24 +266,22 @@ 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");
|
||||
"precision is not integer");
|
||||
EXPECT_THROW_MSG(test_sprintf("%.*d"), format_error,
|
||||
"argument index out of range");
|
||||
"argument index out of range");
|
||||
EXPECT_THROW_MSG(test_sprintf("%.*d", BIG_NUM, 42), format_error,
|
||||
"number is too big");
|
||||
"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");
|
||||
}
|
||||
"number is too big");
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
struct make_signed { typedef T type; };
|
||||
template <typename T> struct make_signed { typedef T type; };
|
||||
|
||||
#define SPECIALIZE_MAKE_SIGNED(T, S) \
|
||||
template <> \
|
||||
struct make_signed<T> { typedef S type; }
|
||||
template <> struct make_signed<T> { typedef S type; }
|
||||
|
||||
SPECIALIZE_MAKE_SIGNED(char, signed char);
|
||||
SPECIALIZE_MAKE_SIGNED(unsigned char, signed char);
|
||||
@@ -295,7 +292,7 @@ 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) {
|
||||
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.
|
||||
@@ -335,8 +332,7 @@ void TestLength(const char *length_spec, U value) {
|
||||
EXPECT_PRINTF(os.str(), fmt::format("%{}X", length_spec), value);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void TestLength(const char *length_spec) {
|
||||
template <typename T> void TestLength(const char* length_spec) {
|
||||
T min = std::numeric_limits<T>::min(), max = std::numeric_limits<T>::max();
|
||||
TestLength<T>(length_spec, 42);
|
||||
TestLength<T>(length_spec, -42);
|
||||
@@ -430,32 +426,32 @@ TEST(PrintfTest, Char) {
|
||||
EXPECT_PRINTF("x", "%c", 'x');
|
||||
int max = std::numeric_limits<int>::max();
|
||||
EXPECT_PRINTF(fmt::format("{}", static_cast<char>(max)), "%c", max);
|
||||
//EXPECT_PRINTF("x", "%lc", L'x');
|
||||
// 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 = FMT_NULL;
|
||||
const char* null_str = FMT_NULL;
|
||||
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 = FMT_NULL;
|
||||
const wchar_t* null_wstr = FMT_NULL;
|
||||
EXPECT_PRINTF(L"(null)", L"%s", null_wstr);
|
||||
EXPECT_PRINTF(L" (null)", L"%10s", null_wstr);
|
||||
}
|
||||
|
||||
TEST(PrintfTest, Pointer) {
|
||||
int n;
|
||||
void *p = &n;
|
||||
void* p = &n;
|
||||
EXPECT_PRINTF(fmt::format("{}", p), "%p", p);
|
||||
p = FMT_NULL;
|
||||
EXPECT_PRINTF("(nil)", "%p", p);
|
||||
EXPECT_PRINTF(" (nil)", "%10p", p);
|
||||
const char *s = "test";
|
||||
const char* s = "test";
|
||||
EXPECT_PRINTF(fmt::format("{:p}", s), "%p", s);
|
||||
const char *null_str = FMT_NULL;
|
||||
const char* null_str = FMT_NULL;
|
||||
EXPECT_PRINTF("(nil)", "%p", null_str);
|
||||
|
||||
p = &n;
|
||||
@@ -463,9 +459,9 @@ TEST(PrintfTest, Pointer) {
|
||||
p = FMT_NULL;
|
||||
EXPECT_PRINTF(L"(nil)", L"%p", p);
|
||||
EXPECT_PRINTF(L" (nil)", L"%10p", p);
|
||||
const wchar_t *w = L"test";
|
||||
const wchar_t* w = L"test";
|
||||
EXPECT_PRINTF(fmt::format(L"{:p}", w), L"%p", w);
|
||||
const wchar_t *null_wstr = FMT_NULL;
|
||||
const wchar_t* null_wstr = FMT_NULL;
|
||||
EXPECT_PRINTF(L"(nil)", L"%p", null_wstr);
|
||||
}
|
||||
|
||||
@@ -475,14 +471,12 @@ TEST(PrintfTest, Location) {
|
||||
|
||||
enum E { A = 42 };
|
||||
|
||||
TEST(PrintfTest, Enum) {
|
||||
EXPECT_PRINTF("42", "%d", A);
|
||||
}
|
||||
TEST(PrintfTest, Enum) { EXPECT_PRINTF("42", "%d", A); }
|
||||
|
||||
#if FMT_USE_FILE_DESCRIPTORS
|
||||
TEST(PrintfTest, Examples) {
|
||||
const char *weekday = "Thursday";
|
||||
const char *month = "August";
|
||||
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");
|
||||
@@ -496,9 +490,7 @@ TEST(PrintfTest, PrintfError) {
|
||||
}
|
||||
#endif
|
||||
|
||||
TEST(PrintfTest, WideString) {
|
||||
EXPECT_EQ(L"abc", fmt::sprintf(L"%s", L"abc"));
|
||||
}
|
||||
TEST(PrintfTest, WideString) { EXPECT_EQ(L"abc", fmt::sprintf(L"%s", L"abc")); }
|
||||
|
||||
TEST(PrintfTest, PrintfCustom) {
|
||||
EXPECT_EQ("abc", test_sprintf("%s", TestString("abc")));
|
||||
@@ -520,7 +512,7 @@ TEST(PrintfTest, VPrintf) {
|
||||
EXPECT_WRITE(stdout, fmt::vfprintf(std::cout, "%d", args), "42");
|
||||
}
|
||||
|
||||
template<typename... Args>
|
||||
template <typename... Args>
|
||||
void check_format_string_regression(fmt::string_view s, const Args&... args) {
|
||||
fmt::sprintf(s, args...);
|
||||
}
|
||||
@@ -530,40 +522,36 @@ TEST(PrintfTest, CheckFormatStringRegression) {
|
||||
}
|
||||
|
||||
TEST(PrintfTest, VSPrintfMakeArgsExample) {
|
||||
fmt::format_arg_store<fmt::printf_context, int, const char *> as{
|
||||
42, "something"};
|
||||
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));
|
||||
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")));
|
||||
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::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");
|
||||
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));
|
||||
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")));
|
||||
EXPECT_EQ(L"[42] something happened",
|
||||
fmt::vsprintf(L"[%d] %s happened",
|
||||
fmt::make_wprintf_args(42, L"something")));
|
||||
#endif
|
||||
}
|
||||
|
||||
+10
-13
@@ -13,13 +13,13 @@
|
||||
#if (__cplusplus > 201402L) || \
|
||||
(defined(_MSVC_LANG) && _MSVC_LANG > 201402L && _MSC_VER >= 1910)
|
||||
|
||||
#include "fmt/ranges.h"
|
||||
#include "gtest.h"
|
||||
# include "fmt/ranges.h"
|
||||
# include "gtest.h"
|
||||
|
||||
#include <vector>
|
||||
#include <array>
|
||||
#include <map>
|
||||
#include <string>
|
||||
# include <array>
|
||||
# include <map>
|
||||
# include <string>
|
||||
# include <vector>
|
||||
|
||||
TEST(RangesTest, FormatVector) {
|
||||
std::vector<int32_t> iv{1, 2, 3, 5, 7, 11};
|
||||
@@ -45,15 +45,14 @@ TEST(RangesTest, FormatPair) {
|
||||
|
||||
TEST(RangesTest, FormatTuple) {
|
||||
std::tuple<int64_t, float, std::string, char> tu1{42, 3.14159265358979f,
|
||||
"this is tuple", 'i'};
|
||||
"this is tuple", 'i'};
|
||||
EXPECT_EQ("(42, 3.14159, \"this is tuple\", 'i')", fmt::format("{}", tu1));
|
||||
}
|
||||
|
||||
struct my_struct {
|
||||
int32_t i;
|
||||
std::string str; // can throw
|
||||
template <std::size_t N>
|
||||
decltype(auto) get() const noexcept {
|
||||
template <std::size_t N> decltype(auto) get() const noexcept {
|
||||
if constexpr (N == 0)
|
||||
return i;
|
||||
else if constexpr (N == 1)
|
||||
@@ -61,8 +60,7 @@ struct my_struct {
|
||||
}
|
||||
};
|
||||
|
||||
template <std::size_t N>
|
||||
decltype(auto) get(const my_struct& s) noexcept {
|
||||
template <std::size_t N> decltype(auto) get(const my_struct& s) noexcept {
|
||||
return s.get<N>();
|
||||
}
|
||||
|
||||
@@ -71,8 +69,7 @@ namespace std {
|
||||
template <>
|
||||
struct tuple_size<my_struct> : std::integral_constant<std::size_t, 2> {};
|
||||
|
||||
template <std::size_t N>
|
||||
struct tuple_element<N, my_struct> {
|
||||
template <std::size_t N> struct tuple_element<N, my_struct> {
|
||||
using type = decltype(std::declval<my_struct>().get<N>());
|
||||
};
|
||||
|
||||
|
||||
+1
-1
@@ -13,7 +13,7 @@
|
||||
|
||||
class assertion_failure : public std::logic_error {
|
||||
public:
|
||||
explicit assertion_failure(const char *message) : std::logic_error(message) {}
|
||||
explicit assertion_failure(const char* message) : std::logic_error(message) {}
|
||||
};
|
||||
|
||||
#define FMT_ASSERT(condition, message) \
|
||||
|
||||
+6
-6
@@ -9,23 +9,23 @@
|
||||
#include "gtest.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
# include <windows.h>
|
||||
# include <windows.h>
|
||||
#endif
|
||||
|
||||
#ifdef _MSC_VER
|
||||
# include <crtdbg.h>
|
||||
# include <crtdbg.h>
|
||||
#else
|
||||
# define _CrtSetReportFile(a, b)
|
||||
# define _CrtSetReportMode(a, b)
|
||||
# define _CrtSetReportFile(a, b)
|
||||
# define _CrtSetReportMode(a, b)
|
||||
#endif
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
int main(int argc, char** argv) {
|
||||
#ifdef _WIN32
|
||||
// Don't display any error dialogs. This also suppresses message boxes
|
||||
// on assertion failures in MinGW where _set_error_mode/CrtSetReportMode
|
||||
// doesn't help.
|
||||
SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOGPFAULTERRORBOX |
|
||||
SEM_NOOPENFILEERRORBOX);
|
||||
SEM_NOOPENFILEERRORBOX);
|
||||
#endif
|
||||
// Disable message boxes on assertion failures.
|
||||
_CrtSetReportMode(_CRT_ERROR, _CRTDBG_MODE_FILE | _CRTDBG_MODE_DEBUG);
|
||||
|
||||
+11
-18
@@ -6,17 +6,17 @@
|
||||
// For the license information refer to format.h.
|
||||
|
||||
#ifdef WIN32
|
||||
#define _CRT_SECURE_NO_WARNINGS
|
||||
# define _CRT_SECURE_NO_WARNINGS
|
||||
#endif
|
||||
|
||||
#include "gmock.h"
|
||||
#include "fmt/locale.h"
|
||||
#include "fmt/time.h"
|
||||
#include "fmt/locale.h"
|
||||
#include "gmock.h"
|
||||
|
||||
TEST(TimeTest, Format) {
|
||||
std::tm tm = std::tm();
|
||||
tm.tm_year = 116;
|
||||
tm.tm_mon = 3;
|
||||
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));
|
||||
@@ -24,8 +24,7 @@ TEST(TimeTest, Format) {
|
||||
|
||||
TEST(TimeTest, GrowBuffer) {
|
||||
std::string s = "{:";
|
||||
for (int i = 0; i < 30; ++i)
|
||||
s += "%c";
|
||||
for (int i = 0; i < 30; ++i) s += "%c";
|
||||
s += "}\n";
|
||||
std::time_t t = std::time(FMT_NULL);
|
||||
fmt::format(s, *std::localtime(&t));
|
||||
@@ -39,19 +38,13 @@ TEST(TimeTest, FormatToEmptyContainer) {
|
||||
EXPECT_EQ(s, "42");
|
||||
}
|
||||
|
||||
TEST(TimeTest, EmptyResult) {
|
||||
EXPECT_EQ("", fmt::format("{}", std::tm()));
|
||||
}
|
||||
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 &&
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
+4
-5
@@ -8,7 +8,7 @@
|
||||
#include "util.h"
|
||||
#include <cstring>
|
||||
|
||||
void increment(char *s) {
|
||||
void increment(char* s) {
|
||||
for (int i = static_cast<int>(std::strlen(s)) - 1; i >= 0; --i) {
|
||||
if (s[i] != '9') {
|
||||
++s[i];
|
||||
@@ -30,15 +30,14 @@ std::string get_system_error(int error_code) {
|
||||
#endif
|
||||
}
|
||||
|
||||
const char *const FILE_CONTENT = "Don't panic!";
|
||||
const char* const FILE_CONTENT = "Don't panic!";
|
||||
|
||||
fmt::buffered_file open_buffered_file(FILE **fp) {
|
||||
fmt::buffered_file open_buffered_file(FILE** fp) {
|
||||
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();
|
||||
if (fp) *fp = f.get();
|
||||
return f;
|
||||
}
|
||||
|
||||
+16
-17
@@ -11,16 +11,16 @@
|
||||
|
||||
#include "fmt/posix.h"
|
||||
|
||||
enum {BUFFER_SIZE = 256};
|
||||
enum { BUFFER_SIZE = 256 };
|
||||
|
||||
#ifdef _MSC_VER
|
||||
# define FMT_VSNPRINTF vsprintf_s
|
||||
# define FMT_VSNPRINTF vsprintf_s
|
||||
#else
|
||||
# define FMT_VSNPRINTF vsnprintf
|
||||
# define FMT_VSNPRINTF vsnprintf
|
||||
#endif
|
||||
|
||||
template <std::size_t SIZE>
|
||||
void safe_sprintf(char (&buffer)[SIZE], const char *format, ...) {
|
||||
void safe_sprintf(char (&buffer)[SIZE], const char* format, ...) {
|
||||
std::va_list args;
|
||||
va_start(args, format);
|
||||
FMT_VSNPRINTF(buffer, SIZE, format, args);
|
||||
@@ -28,19 +28,19 @@ void safe_sprintf(char (&buffer)[SIZE], const char *format, ...) {
|
||||
}
|
||||
|
||||
// Increment a number in a string.
|
||||
void increment(char *s);
|
||||
void increment(char* s);
|
||||
|
||||
std::string get_system_error(int error_code);
|
||||
|
||||
extern const char *const FILE_CONTENT;
|
||||
extern const char* const FILE_CONTENT;
|
||||
|
||||
// Opens a buffered file for reading.
|
||||
fmt::buffered_file open_buffered_file(FILE **fp = FMT_NULL);
|
||||
fmt::buffered_file open_buffered_file(FILE** fp = FMT_NULL);
|
||||
|
||||
inline FILE *safe_fopen(const char *filename, const char *mode) {
|
||||
inline FILE* safe_fopen(const char* filename, const char* mode) {
|
||||
#if defined(_WIN32) && !defined(__MINGW32__)
|
||||
// Fix MSVC warning about "unsafe" fopen.
|
||||
FILE *f = 0;
|
||||
FILE* f = 0;
|
||||
errno = fopen_s(&f, filename, mode);
|
||||
return f;
|
||||
#else
|
||||
@@ -48,34 +48,33 @@ inline FILE *safe_fopen(const char *filename, const char *mode) {
|
||||
#endif
|
||||
}
|
||||
|
||||
template <typename Char>
|
||||
class BasicTestString {
|
||||
template <typename Char> class BasicTestString {
|
||||
private:
|
||||
std::basic_string<Char> value_;
|
||||
|
||||
static const Char EMPTY[];
|
||||
|
||||
public:
|
||||
explicit BasicTestString(const Char *value = EMPTY) : value_(value) {}
|
||||
explicit BasicTestString(const Char* value = EMPTY) : value_(value) {}
|
||||
|
||||
const std::basic_string<Char> &value() const { return value_; }
|
||||
const std::basic_string<Char>& value() const { return value_; }
|
||||
};
|
||||
|
||||
template <typename Char>
|
||||
const Char BasicTestString<Char>::EMPTY[] = {0};
|
||||
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) {
|
||||
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) {}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user