Cleanup tests

This commit is contained in:
Victor Zverovich 2021-04-30 17:02:14 -07:00
parent 38127d9ec0
commit 9155e2de4c
8 changed files with 491 additions and 538 deletions

View File

@ -16,6 +16,51 @@
FMT_BEGIN_NAMESPACE FMT_BEGIN_NAMESPACE
namespace detail { namespace detail {
// An output iterator that counts the number of objects written to it and
// discards them.
class counting_iterator {
private:
size_t count_;
public:
using iterator_category = std::output_iterator_tag;
using difference_type = std::ptrdiff_t;
using pointer = void;
using reference = void;
using _Unchecked_type = counting_iterator; // Mark iterator as checked.
struct value_type {
template <typename T> void operator=(const T&) {}
};
counting_iterator() : count_(0) {}
size_t count() const { return count_; }
counting_iterator& operator++() {
++count_;
return *this;
}
counting_iterator operator++(int) {
auto it = *this;
++*this;
return it;
}
friend counting_iterator operator+(counting_iterator it, difference_type n) {
it.count_ += static_cast<size_t>(n);
return it;
}
value_type operator*() const { return {}; }
};
template <typename Char, typename InputIt>
inline counting_iterator copy_str(InputIt begin, InputIt end,
counting_iterator it) {
return it + (end - begin);
}
template <typename OutputIt> class truncating_iterator_base { template <typename OutputIt> class truncating_iterator_base {
protected: protected:
OutputIt out_; OutputIt out_;

View File

@ -33,15 +33,15 @@
#ifndef FMT_FORMAT_H_ #ifndef FMT_FORMAT_H_
#define FMT_FORMAT_H_ #define FMT_FORMAT_H_
#include <cerrno> #include <cerrno> // errno
#include <cmath> #include <cmath> // std::signbit
#include <cstddef> // std::byte #include <cstddef> // std::byte
#include <cstdint> #include <cstdint>
#include <cwchar> #include <cwchar>
#include <limits> #include <limits> // std::numeric_limits
#include <memory> #include <memory> // std::uninitialized_copy
#include <stdexcept> #include <stdexcept> // std::runtime_error
#include <utility> // std::swap #include <utility> // std::swap
#include "core.h" #include "core.h"
@ -430,45 +430,6 @@ constexpr Iterator base_iterator(Iterator, Iterator it) {
return it; return it;
} }
// An output iterator that counts the number of objects written to it and
// discards them.
class counting_iterator {
private:
size_t count_;
public:
using iterator_category = std::output_iterator_tag;
using difference_type = std::ptrdiff_t;
using pointer = void;
using reference = void;
using _Unchecked_type = counting_iterator; // Mark iterator as checked.
struct value_type {
template <typename T> void operator=(const T&) {}
};
counting_iterator() : count_(0) {}
size_t count() const { return count_; }
counting_iterator& operator++() {
++count_;
return *this;
}
counting_iterator operator++(int) {
auto it = *this;
++*this;
return it;
}
friend counting_iterator operator+(counting_iterator it, difference_type n) {
it.count_ += static_cast<size_t>(n);
return it;
}
value_type operator*() const { return {}; }
};
// <algorithm> is spectacularly slow to compile in C++20 so use a simple fill_n // <algorithm> is spectacularly slow to compile in C++20 so use a simple fill_n
// instead (#1998). // instead (#1998).
template <typename OutputIt, typename Size, typename T> template <typename OutputIt, typename Size, typename T>
@ -524,12 +485,6 @@ buffer_appender<OutChar> copy_str(InputIt begin, InputIt end,
return out; return out;
} }
template <typename Char, typename InputIt>
inline counting_iterator copy_str(InputIt begin, InputIt end,
counting_iterator it) {
return it + (end - begin);
}
template <typename Char> template <typename Char>
FMT_CONSTEXPR int code_point_length(const Char* begin) { FMT_CONSTEXPR int code_point_length(const Char* begin) {
if (const_check(sizeof(Char) != 1)) return 1; if (const_check(sizeof(Char) != 1)) return 1;

View File

@ -75,8 +75,8 @@ add_fmt_test(scan-test)
if (NOT MSVC) if (NOT MSVC)
# FMT_ENFORCE_COMPILE_STRING is not supported under MSVC due to compiler bugs. # FMT_ENFORCE_COMPILE_STRING is not supported under MSVC due to compiler bugs.
add_fmt_test(enforce-compile-string-test) add_fmt_test(enforce-checks-test)
target_compile_definitions(enforce-compile-string-test PRIVATE target_compile_definitions(enforce-checks-test PRIVATE
-DFMT_ENFORCE_COMPILE_STRING) -DFMT_ENFORCE_COMPILE_STRING)
endif () endif ()

View File

@ -12,6 +12,14 @@
#include "fmt/chrono.h" #include "fmt/chrono.h"
#include "gmock/gmock.h" #include "gmock/gmock.h"
TEST(iterator_test, counting_iterator) {
auto it = fmt::detail::counting_iterator();
auto prev = it++;
EXPECT_EQ(prev.count(), 0);
EXPECT_EQ(it.count(), 1);
EXPECT_EQ((it + 41).count(), 42);
}
TEST(iterator_test, truncating_iterator) { TEST(iterator_test, truncating_iterator) {
char* p = nullptr; char* p = nullptr;
auto it = fmt::detail::truncating_iterator<char*>(p, 3); auto it = fmt::detail::truncating_iterator<char*>(p, 3);

View File

@ -37,6 +37,14 @@ TEST(string_view_test, value_type) {
static_assert(std::is_same<string_view::value_type, char>::value, ""); static_assert(std::is_same<string_view::value_type, char>::value, "");
} }
TEST(string_view_test, ctor) {
EXPECT_STREQ("abc", fmt::string_view("abc").data());
EXPECT_EQ(3u, fmt::string_view("abc").size());
EXPECT_STREQ("defg", fmt::string_view(std::string("defg")).data());
EXPECT_EQ(4u, fmt::string_view(std::string("defg")).size());
}
TEST(string_view_test, length) { TEST(string_view_test, length) {
// Test that string_view::size() returns string length, not buffer size. // Test that string_view::size() returns string length, not buffer size.
char str[100] = "some string"; char str[100] = "some string";
@ -114,6 +122,35 @@ TYPED_TEST(is_string_test, is_string) {
EXPECT_FALSE(fmt::detail::is_string<test_ns::non_string>::value); EXPECT_FALSE(fmt::detail::is_string<test_ns::non_string>::value);
} }
TEST(core_test, is_output_iterator) {
EXPECT_TRUE((fmt::detail::is_output_iterator<char*, char>::value));
EXPECT_FALSE((fmt::detail::is_output_iterator<const char*, char>::value));
EXPECT_FALSE((fmt::detail::is_output_iterator<std::string, char>::value));
EXPECT_TRUE(
(fmt::detail::is_output_iterator<std::back_insert_iterator<std::string>,
char>::value));
EXPECT_TRUE(
(fmt::detail::is_output_iterator<std::string::iterator, char>::value));
EXPECT_FALSE((fmt::detail::is_output_iterator<std::string::const_iterator,
char>::value));
}
TEST(core_test, buffer_appender) {
// back_insert_iterator is not default-constructible before C++20, so
// buffer_appender can only be default-constructible when back_insert_iterator
// is.
static_assert(
std::is_default_constructible<
std::back_insert_iterator<fmt::detail::buffer<char>>>::value ==
std::is_default_constructible<
fmt::detail::buffer_appender<char>>::value,
"");
#ifdef __cpp_lib_ranges
static_assert(std::output_iterator<fmt::detail::buffer_appender<char>, char>);
#endif
}
#if !FMT_GCC_VERSION || FMT_GCC_VERSION >= 470 #if !FMT_GCC_VERSION || FMT_GCC_VERSION >= 470
TEST(buffer_test, noncopyable) { TEST(buffer_test, noncopyable) {
EXPECT_FALSE(std::is_copy_constructible<buffer<char>>::value); EXPECT_FALSE(std::is_copy_constructible<buffer<char>>::value);
@ -592,6 +629,14 @@ TEST(core_test, format_explicitly_convertible_to_std_string_view) {
# endif # endif
#endif #endif
struct convertible_to_long_long {
operator long long() const { return 1LL << 32; }
};
TEST(format_test, format_convertible_to_long_long) {
EXPECT_EQ("100000000", fmt::format("{:x}", convertible_to_long_long()));
}
struct disabled_rvalue_conversion { struct disabled_rvalue_conversion {
operator const char*() const& { return "foo"; } operator const char*() const& { return "foo"; }
operator const char*() & { return "foo"; } operator const char*() & { return "foo"; }

File diff suppressed because it is too large Load Diff

View File

@ -8,14 +8,18 @@
#ifndef FMT_MOCK_ALLOCATOR_H_ #ifndef FMT_MOCK_ALLOCATOR_H_
#define FMT_MOCK_ALLOCATOR_H_ #define FMT_MOCK_ALLOCATOR_H_
#include "fmt/format.h" #include <assert.h> // assert
#include <stddef.h> // size_t
#include <memory> // std::allocator_traits
#include "gmock/gmock.h" #include "gmock/gmock.h"
template <typename T> class mock_allocator { template <typename T> class mock_allocator {
public: public:
mock_allocator() {} mock_allocator() {}
mock_allocator(const mock_allocator&) {} mock_allocator(const mock_allocator&) {}
typedef T value_type; using value_type = T;
MOCK_METHOD1_T(allocate, T*(size_t n)); MOCK_METHOD1_T(allocate, T*(size_t n));
MOCK_METHOD2_T(deallocate, void(T* p, size_t n)); MOCK_METHOD2_T(deallocate, void(T* p, size_t n));
}; };
@ -30,7 +34,7 @@ template <typename Allocator> class allocator_ref {
} }
public: public:
typedef typename Allocator::value_type value_type; using value_type = typename Allocator::value_type;
explicit allocator_ref(Allocator* alloc = nullptr) : alloc_(alloc) {} explicit allocator_ref(Allocator* alloc = nullptr) : alloc_(alloc) {}