mirror of
https://github.com/fmtlib/fmt.git
synced 2025-11-02 07:01:58 +01:00
Move ostream support to ostream.{h,cc}
This commit is contained in:
@@ -75,6 +75,7 @@ add_fmt_test(assert-test)
|
||||
add_fmt_test(gtest-extra-test)
|
||||
add_fmt_test(format-test)
|
||||
add_fmt_test(format-impl-test)
|
||||
add_fmt_test(ostream-test)
|
||||
add_fmt_test(printf-test)
|
||||
add_fmt_test(util-test mock-allocator.h)
|
||||
add_fmt_test(macro-test)
|
||||
|
||||
@@ -123,55 +123,3 @@ TEST(FormatTest, FormatErrorCode) {
|
||||
EXPECT_EQ(msg, w.str());
|
||||
}
|
||||
}
|
||||
|
||||
TEST(FormatTest, WriteToOStream) {
|
||||
std::ostringstream os;
|
||||
fmt::MemoryWriter w;
|
||||
w << "foo";
|
||||
fmt::write(os, w);
|
||||
EXPECT_EQ("foo", os.str());
|
||||
}
|
||||
|
||||
TEST(FormatTest, 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;
|
||||
|
||||
class TestWriter : public fmt::BasicWriter<char> {
|
||||
private:
|
||||
struct TestBuffer : fmt::Buffer<char> {
|
||||
explicit TestBuffer(std::size_t size) { size_ = size; }
|
||||
void grow(std::size_t) {}
|
||||
} buffer_;
|
||||
public:
|
||||
explicit TestWriter(std::size_t size)
|
||||
: fmt::BasicWriter<char>(buffer_), buffer_(size) {}
|
||||
} w(max_size);
|
||||
|
||||
struct MockStreamBuf : 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;
|
||||
return xsputn(v, n);
|
||||
}
|
||||
} buffer;
|
||||
|
||||
struct TestOStream : std::ostream {
|
||||
explicit TestOStream(MockStreamBuf &buffer) : std::ostream(&buffer) {}
|
||||
} os(buffer);
|
||||
|
||||
testing::InSequence sequence;
|
||||
const char *data = 0;
|
||||
std::size_t size = max_size;
|
||||
do {
|
||||
typedef fmt::internal::MakeUnsigned<std::streamsize>::Type UStreamSize;
|
||||
UStreamSize n = std::min<UStreamSize>(
|
||||
size, fmt::internal::to_unsigned(max_streamsize));
|
||||
EXPECT_CALL(buffer, xsputn(data, static_cast<std::streamsize>(n)))
|
||||
.WillOnce(testing::Return(max_streamsize));
|
||||
data += n;
|
||||
size -= static_cast<std::size_t>(n);
|
||||
} while (size != 0);
|
||||
fmt::write(os, w);
|
||||
}
|
||||
|
||||
@@ -31,10 +31,7 @@
|
||||
#include <clocale>
|
||||
#include <cmath>
|
||||
#include <cstring>
|
||||
#include <fstream>
|
||||
#include <iomanip>
|
||||
#include <memory>
|
||||
#include <sstream>
|
||||
#include <stdint.h>
|
||||
|
||||
#if FMT_USE_TYPE_TRAITS
|
||||
@@ -386,30 +383,10 @@ TEST(WriterTest, hexu) {
|
||||
EXPECT_EQ("DEADBEEF", (MemoryWriter() << hexu(0xdeadbeefull)).str());
|
||||
}
|
||||
|
||||
class Date {
|
||||
int year_, month_, day_;
|
||||
public:
|
||||
Date(int year, int month, int day) : year_(year), month_(month), day_(day) {}
|
||||
|
||||
int year() const { return year_; }
|
||||
int month() const { return month_; }
|
||||
int day() const { return day_; }
|
||||
|
||||
friend std::ostream &operator<<(std::ostream &os, const Date &d) {
|
||||
os << d.year_ << '-' << d.month_ << '-' << d.day_;
|
||||
return os;
|
||||
}
|
||||
|
||||
friend std::wostream &operator<<(std::wostream &os, const Date &d) {
|
||||
os << d.year_ << L'-' << d.month_ << L'-' << d.day_;
|
||||
return os;
|
||||
}
|
||||
|
||||
template <typename Char>
|
||||
friend BasicWriter<Char> &operator<<(BasicWriter<Char> &f, const Date &d) {
|
||||
return f << d.year_ << '-' << d.month_ << '-' << d.day_;
|
||||
}
|
||||
};
|
||||
template <typename Char>
|
||||
BasicWriter<Char> &operator<<(BasicWriter<Char> &f, const Date &d) {
|
||||
return f << d.year() << '-' << d.month() << '-' << d.day();
|
||||
}
|
||||
|
||||
class ISO8601DateFormatter {
|
||||
const Date *date_;
|
||||
@@ -665,7 +642,6 @@ TEST(FormatterTest, LeftAlign) {
|
||||
EXPECT_EQ("c ", format("{0:<5}", 'c'));
|
||||
EXPECT_EQ("abc ", format("{0:<5}", "abc"));
|
||||
EXPECT_EQ("0xface ", format("{0:<8}", reinterpret_cast<void*>(0xface)));
|
||||
EXPECT_EQ("def ", format("{0:<5}", TestString("def")));
|
||||
}
|
||||
|
||||
TEST(FormatterTest, RightAlign) {
|
||||
@@ -683,7 +659,6 @@ TEST(FormatterTest, RightAlign) {
|
||||
EXPECT_EQ(" c", format("{0:>5}", 'c'));
|
||||
EXPECT_EQ(" abc", format("{0:>5}", "abc"));
|
||||
EXPECT_EQ(" 0xface", format("{0:>8}", reinterpret_cast<void*>(0xface)));
|
||||
EXPECT_EQ(" def", format("{0:>5}", TestString("def")));
|
||||
}
|
||||
|
||||
TEST(FormatterTest, NumericAlign) {
|
||||
@@ -709,8 +684,6 @@ TEST(FormatterTest, NumericAlign) {
|
||||
FormatError, "format specifier '=' requires numeric argument");
|
||||
EXPECT_THROW_MSG(format("{0:=8}", reinterpret_cast<void*>(0xface)),
|
||||
FormatError, "format specifier '=' requires numeric argument");
|
||||
EXPECT_THROW_MSG(format("{0:=5}", TestString("def")),
|
||||
FormatError, "format specifier '=' requires numeric argument");
|
||||
}
|
||||
|
||||
TEST(FormatterTest, CenterAlign) {
|
||||
@@ -728,7 +701,6 @@ TEST(FormatterTest, CenterAlign) {
|
||||
EXPECT_EQ(" c ", format("{0:^5}", 'c'));
|
||||
EXPECT_EQ(" abc ", format("{0:^6}", "abc"));
|
||||
EXPECT_EQ(" 0xface ", format("{0:^8}", reinterpret_cast<void*>(0xface)));
|
||||
EXPECT_EQ(" def ", format("{0:^5}", TestString("def")));
|
||||
}
|
||||
|
||||
TEST(FormatterTest, Fill) {
|
||||
@@ -748,7 +720,6 @@ TEST(FormatterTest, Fill) {
|
||||
EXPECT_EQ("c****", format("{0:*<5}", 'c'));
|
||||
EXPECT_EQ("abc**", format("{0:*<5}", "abc"));
|
||||
EXPECT_EQ("**0xface", format("{0:*>8}", reinterpret_cast<void*>(0xface)));
|
||||
EXPECT_EQ("def**", format("{0:*<5}", TestString("def")));
|
||||
}
|
||||
|
||||
TEST(FormatterTest, PlusSign) {
|
||||
@@ -773,8 +744,6 @@ TEST(FormatterTest, PlusSign) {
|
||||
FormatError, "format specifier '+' requires numeric argument");
|
||||
EXPECT_THROW_MSG(format("{0:+}", reinterpret_cast<void*>(0x42)),
|
||||
FormatError, "format specifier '+' requires numeric argument");
|
||||
EXPECT_THROW_MSG(format("{0:+}", TestString()),
|
||||
FormatError, "format specifier '+' requires numeric argument");
|
||||
}
|
||||
|
||||
TEST(FormatterTest, MinusSign) {
|
||||
@@ -799,8 +768,6 @@ TEST(FormatterTest, MinusSign) {
|
||||
FormatError, "format specifier '-' requires numeric argument");
|
||||
EXPECT_THROW_MSG(format("{0:-}", reinterpret_cast<void*>(0x42)),
|
||||
FormatError, "format specifier '-' requires numeric argument");
|
||||
EXPECT_THROW_MSG(format("{0:-}", TestString()),
|
||||
FormatError, "format specifier '-' requires numeric argument");
|
||||
}
|
||||
|
||||
TEST(FormatterTest, SpaceSign) {
|
||||
@@ -825,8 +792,6 @@ TEST(FormatterTest, SpaceSign) {
|
||||
FormatError, "format specifier ' ' requires numeric argument");
|
||||
EXPECT_THROW_MSG(format("{0: }", reinterpret_cast<void*>(0x42)),
|
||||
FormatError, "format specifier ' ' requires numeric argument");
|
||||
EXPECT_THROW_MSG(format("{0: }", TestString()),
|
||||
FormatError, "format specifier ' ' requires numeric argument");
|
||||
}
|
||||
|
||||
TEST(FormatterTest, HashFlag) {
|
||||
@@ -872,8 +837,6 @@ TEST(FormatterTest, HashFlag) {
|
||||
FormatError, "format specifier '#' requires numeric argument");
|
||||
EXPECT_THROW_MSG(format("{0:#}", reinterpret_cast<void*>(0x42)),
|
||||
FormatError, "format specifier '#' requires numeric argument");
|
||||
EXPECT_THROW_MSG(format("{0:#}", TestString()),
|
||||
FormatError, "format specifier '#' requires numeric argument");
|
||||
}
|
||||
|
||||
TEST(FormatterTest, ZeroFlag) {
|
||||
@@ -894,8 +857,6 @@ TEST(FormatterTest, ZeroFlag) {
|
||||
FormatError, "format specifier '0' requires numeric argument");
|
||||
EXPECT_THROW_MSG(format("{0:05}", reinterpret_cast<void*>(0x42)),
|
||||
FormatError, "format specifier '0' requires numeric argument");
|
||||
EXPECT_THROW_MSG(format("{0:05}", TestString()),
|
||||
FormatError, "format specifier '0' requires numeric argument");
|
||||
}
|
||||
|
||||
TEST(FormatterTest, Width) {
|
||||
@@ -923,7 +884,6 @@ TEST(FormatterTest, Width) {
|
||||
EXPECT_EQ(" 0xcafe", format("{0:10}", reinterpret_cast<void*>(0xcafe)));
|
||||
EXPECT_EQ("x ", format("{0:11}", 'x'));
|
||||
EXPECT_EQ("str ", format("{0:12}", "str"));
|
||||
EXPECT_EQ("test ", format("{0:13}", TestString("test")));
|
||||
}
|
||||
|
||||
TEST(FormatterTest, RuntimeWidth) {
|
||||
@@ -982,7 +942,6 @@ TEST(FormatterTest, RuntimeWidth) {
|
||||
format("{0:{1}}", reinterpret_cast<void*>(0xcafe), 10));
|
||||
EXPECT_EQ("x ", format("{0:{1}}", 'x', 11));
|
||||
EXPECT_EQ("str ", format("{0:{1}}", "str", 12));
|
||||
EXPECT_EQ("test ", format("{0:{1}}", TestString("test"), 13));
|
||||
}
|
||||
|
||||
TEST(FormatterTest, Precision) {
|
||||
@@ -1042,7 +1001,6 @@ TEST(FormatterTest, Precision) {
|
||||
FormatError, "precision not allowed in pointer format specifier");
|
||||
|
||||
EXPECT_EQ("st", format("{0:.2}", "str"));
|
||||
EXPECT_EQ("te", format("{0:.2}", TestString("test")));
|
||||
}
|
||||
|
||||
TEST(FormatterTest, RuntimePrecision) {
|
||||
@@ -1126,7 +1084,6 @@ TEST(FormatterTest, RuntimePrecision) {
|
||||
FormatError, "precision not allowed in pointer format specifier");
|
||||
|
||||
EXPECT_EQ("st", format("{0:.{1}}", "str", 2));
|
||||
EXPECT_EQ("te", format("{0:.{1}}", TestString("test"), 2));
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
@@ -1393,14 +1350,14 @@ TEST(FormatterTest, FormatCStringRef) {
|
||||
EXPECT_EQ("test", format("{0}", CStringRef("test")));
|
||||
}
|
||||
|
||||
TEST(FormatterTest, FormatUsingIOStreams) {
|
||||
EXPECT_EQ("a string", format("{0}", TestString("a string")));
|
||||
std::string s = format("The date is {0}", Date(2012, 12, 9));
|
||||
EXPECT_EQ("The date is 2012-12-9", s);
|
||||
void format(fmt::BasicFormatter<char> &f, const char *, const Date &d) {
|
||||
f.writer() << d.year() << '-' << d.month() << '-' << d.day();
|
||||
}
|
||||
|
||||
TEST(FormatterTest, FormatCustom) {
|
||||
Date date(2012, 12, 9);
|
||||
check_unknown_types(date, "s", "string");
|
||||
EXPECT_EQ(L"The date is 2012-12-9",
|
||||
format(L"The date is {0}", Date(2012, 12, 9)));
|
||||
EXPECT_THROW_MSG(fmt::format("{:s}", date), FormatError,
|
||||
"unmatched '}' in format string");
|
||||
}
|
||||
|
||||
class Answer {};
|
||||
@@ -1563,9 +1520,6 @@ TEST(FormatTest, Print) {
|
||||
EXPECT_WRITE(stderr,
|
||||
fmt::print(stderr, "Don't {}!", "panic"), "Don't panic!");
|
||||
#endif
|
||||
std::ostringstream os;
|
||||
fmt::print(os, "Don't {}!", "panic");
|
||||
EXPECT_EQ("Don't panic!", os.str());
|
||||
}
|
||||
|
||||
#if FMT_USE_FILE_DESCRIPTORS
|
||||
@@ -1660,27 +1614,12 @@ TEST(LiteralsTest, NamedArg) {
|
||||
}
|
||||
#endif // FMT_USE_USER_DEFINED_LITERALS
|
||||
|
||||
enum TestEnum {};
|
||||
std::ostream &operator<<(std::ostream &os, TestEnum) {
|
||||
return os << "TestEnum";
|
||||
}
|
||||
|
||||
enum TestEnum2 { A };
|
||||
enum TestEnum { A };
|
||||
|
||||
TEST(FormatTest, Enum) {
|
||||
EXPECT_EQ("TestEnum", fmt::format("{}", TestEnum()));
|
||||
EXPECT_EQ("0", fmt::format("{}", A));
|
||||
}
|
||||
|
||||
struct EmptyTest {};
|
||||
std::ostream &operator<<(std::ostream &os, EmptyTest) {
|
||||
return os << "";
|
||||
}
|
||||
|
||||
TEST(FormatTest, EmptyCustomOutput) {
|
||||
EXPECT_EQ("", fmt::format("{}", EmptyTest()));
|
||||
}
|
||||
|
||||
class MockArgFormatter :
|
||||
public fmt::internal::ArgFormatterBase<MockArgFormatter, char> {
|
||||
public:
|
||||
@@ -1705,19 +1644,3 @@ FMT_VARIADIC(void, custom_format, const char *)
|
||||
TEST(FormatTest, CustomArgFormatter) {
|
||||
custom_format("{}", 42);
|
||||
}
|
||||
|
||||
struct TestArgFormatter : fmt::BasicArgFormatter<TestArgFormatter, char> {
|
||||
TestArgFormatter(fmt::BasicFormatter<char, TestArgFormatter> &f,
|
||||
fmt::FormatSpec &s, const char *fmt)
|
||||
: fmt::BasicArgFormatter<TestArgFormatter, char>(f, s, fmt) {}
|
||||
};
|
||||
|
||||
TEST(ArgFormatterTest, CustomArg) {
|
||||
fmt::MemoryWriter writer;
|
||||
typedef fmt::BasicFormatter<char, TestArgFormatter> Formatter;
|
||||
Formatter formatter(fmt::ArgList(), writer);
|
||||
fmt::FormatSpec spec;
|
||||
TestArgFormatter af(formatter, spec, "}");
|
||||
af.visit(fmt::internal::MakeArg<Formatter>(TestEnum()));
|
||||
EXPECT_EQ("TestEnum", writer.str());
|
||||
}
|
||||
|
||||
192
test/ostream-test.cc
Normal file
192
test/ostream-test.cc
Normal file
@@ -0,0 +1,192 @@
|
||||
/*
|
||||
std::ostream support tests
|
||||
|
||||
Copyright (c) 2012-2016, Victor Zverovich
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "fmt/ostream.cc"
|
||||
|
||||
#include <sstream>
|
||||
#include "gmock/gmock.h"
|
||||
#include "gtest-extra.h"
|
||||
#include "util.h"
|
||||
|
||||
using fmt::format;
|
||||
using fmt::FormatError;
|
||||
|
||||
template <typename Char>
|
||||
std::basic_ostream<Char> &operator<<(
|
||||
std::basic_ostream<Char> &os, const BasicTestString<Char> &s) {
|
||||
os << s.value();
|
||||
return os;
|
||||
}
|
||||
|
||||
std::ostream &operator<<(std::ostream &os, const Date &d) {
|
||||
os << d.year() << '-' << d.month() << '-' << d.day();
|
||||
return os;
|
||||
}
|
||||
|
||||
std::wostream &operator<<(std::wostream &os, const Date &d) {
|
||||
os << d.year() << L'-' << d.month() << L'-' << d.day();
|
||||
return os;
|
||||
}
|
||||
|
||||
enum TestEnum {};
|
||||
std::ostream &operator<<(std::ostream &os, TestEnum) {
|
||||
return os << "TestEnum";
|
||||
}
|
||||
|
||||
enum TestEnum2 {A};
|
||||
|
||||
TEST(OStreamTest, Enum) {
|
||||
EXPECT_FALSE(fmt::internal::ConvertToInt<TestEnum>::value);
|
||||
EXPECT_EQ("TestEnum", fmt::format("{}", TestEnum()));
|
||||
EXPECT_EQ("0", fmt::format("{}", A));
|
||||
}
|
||||
|
||||
struct TestArgFormatter : fmt::BasicArgFormatter<TestArgFormatter, char> {
|
||||
TestArgFormatter(fmt::BasicFormatter<char, TestArgFormatter> &f,
|
||||
fmt::FormatSpec &s, const char *fmt)
|
||||
: fmt::BasicArgFormatter<TestArgFormatter, char>(f, s, fmt) {}
|
||||
};
|
||||
|
||||
TEST(OStreamTest, CustomArg) {
|
||||
fmt::MemoryWriter writer;
|
||||
typedef fmt::BasicFormatter<char, TestArgFormatter> Formatter;
|
||||
Formatter formatter(fmt::ArgList(), writer);
|
||||
fmt::FormatSpec spec;
|
||||
TestArgFormatter af(formatter, spec, "}");
|
||||
af.visit(fmt::internal::MakeArg<Formatter>(TestEnum()));
|
||||
EXPECT_EQ("TestEnum", writer.str());
|
||||
}
|
||||
|
||||
TEST(OStreamTest, Format) {
|
||||
EXPECT_EQ("a string", format("{0}", TestString("a string")));
|
||||
std::string s = format("The date is {0}", Date(2012, 12, 9));
|
||||
EXPECT_EQ("The date is 2012-12-9", s);
|
||||
Date date(2012, 12, 9);
|
||||
EXPECT_EQ(L"The date is 2012-12-9",
|
||||
format(L"The date is {0}", Date(2012, 12, 9)));
|
||||
}
|
||||
|
||||
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")),
|
||||
FormatError, "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()),
|
||||
FormatError, "format specifier '+' requires numeric argument");
|
||||
EXPECT_THROW_MSG(format("{0:-}", TestString()),
|
||||
FormatError, "format specifier '-' requires numeric argument");
|
||||
EXPECT_THROW_MSG(format("{0: }", TestString()),
|
||||
FormatError, "format specifier ' ' requires numeric argument");
|
||||
EXPECT_THROW_MSG(format("{0:#}", TestString()),
|
||||
FormatError, "format specifier '#' requires numeric argument");
|
||||
EXPECT_THROW_MSG(format("{0:05}", TestString()),
|
||||
FormatError, "format specifier '0' 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")));
|
||||
EXPECT_EQ("te", format("{0:.{1}}", TestString("test"), 2));
|
||||
}
|
||||
|
||||
struct EmptyTest {};
|
||||
std::ostream &operator<<(std::ostream &os, EmptyTest) {
|
||||
return os << "";
|
||||
}
|
||||
|
||||
TEST(OStreamTest, EmptyCustomOutput) {
|
||||
EXPECT_EQ("", fmt::format("{}", EmptyTest()));
|
||||
}
|
||||
|
||||
TEST(OStreamTest, Print) {
|
||||
std::ostringstream os;
|
||||
fmt::print(os, "Don't {}!", "panic");
|
||||
EXPECT_EQ("Don't panic!", os.str());
|
||||
}
|
||||
|
||||
TEST(OStreamTest, PrintfCustom) {
|
||||
EXPECT_EQ("abc", fmt::sprintf("%s", TestString("abc")));
|
||||
}
|
||||
|
||||
TEST(OStreamTest, FPrintf) {
|
||||
std::ostringstream os;
|
||||
int ret = fmt::fprintf(os, "Don't %s!", "panic");
|
||||
EXPECT_EQ("Don't panic!", os.str());
|
||||
EXPECT_EQ(12, ret);
|
||||
}
|
||||
|
||||
TEST(OStreamTest, WriteToOStream) {
|
||||
std::ostringstream os;
|
||||
fmt::MemoryWriter w;
|
||||
w << "foo";
|
||||
fmt::write(os, w);
|
||||
EXPECT_EQ("foo", os.str());
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
class TestWriter : public fmt::BasicWriter<char> {
|
||||
private:
|
||||
struct TestBuffer : fmt::Buffer<char> {
|
||||
explicit TestBuffer(std::size_t size) { size_ = size; }
|
||||
void grow(std::size_t) {}
|
||||
} buffer_;
|
||||
public:
|
||||
explicit TestWriter(std::size_t size)
|
||||
: fmt::BasicWriter<char>(buffer_), buffer_(size) {}
|
||||
} w(max_size);
|
||||
|
||||
struct MockStreamBuf : 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;
|
||||
return xsputn(v, n);
|
||||
}
|
||||
} buffer;
|
||||
|
||||
struct TestOStream : std::ostream {
|
||||
explicit TestOStream(MockStreamBuf &buffer) : std::ostream(&buffer) {}
|
||||
} os(buffer);
|
||||
|
||||
testing::InSequence sequence;
|
||||
const char *data = 0;
|
||||
std::size_t size = max_size;
|
||||
do {
|
||||
typedef fmt::internal::MakeUnsigned<std::streamsize>::Type UStreamSize;
|
||||
UStreamSize n = std::min<UStreamSize>(
|
||||
size, fmt::internal::to_unsigned(max_streamsize));
|
||||
EXPECT_CALL(buffer, xsputn(data, static_cast<std::streamsize>(n)))
|
||||
.WillOnce(testing::Return(max_streamsize));
|
||||
data += n;
|
||||
size -= static_cast<std::size_t>(n);
|
||||
} while (size != 0);
|
||||
fmt::write(os, w);
|
||||
}
|
||||
@@ -447,10 +447,6 @@ TEST(PrintfTest, Pointer) {
|
||||
EXPECT_PRINTF("(nil)", "%p", null_str);
|
||||
}
|
||||
|
||||
TEST(PrintfTest, Custom) {
|
||||
EXPECT_PRINTF("abc", "%s", TestString("abc"));
|
||||
}
|
||||
|
||||
TEST(PrintfTest, Location) {
|
||||
// TODO: test %n
|
||||
}
|
||||
@@ -479,12 +475,5 @@ TEST(PrintfTest, PrintfError) {
|
||||
#endif
|
||||
|
||||
TEST(PrintfTest, WideString) {
|
||||
EXPECT_EQ(L"abc", fmt::sprintf(L"%s", TestWString(L"abc")));
|
||||
}
|
||||
|
||||
TEST(PrintfTest, Iostream) {
|
||||
std::ostringstream os;
|
||||
int ret = fmt::fprintf(os, "Don't %s!", "panic");
|
||||
EXPECT_EQ("Don't panic!", os.str());
|
||||
EXPECT_EQ(12, ret);
|
||||
EXPECT_EQ(L"abc", fmt::sprintf(L"%s", L"abc"));
|
||||
}
|
||||
|
||||
@@ -62,9 +62,10 @@ using testing::StrictMock;
|
||||
namespace {
|
||||
|
||||
struct Test {};
|
||||
|
||||
template <typename Char>
|
||||
std::basic_ostream<Char> &operator<<(std::basic_ostream<Char> &os, Test) {
|
||||
return os << "test";
|
||||
void format(fmt::BasicFormatter<Char> &f, const Char *, Test) {
|
||||
f.writer() << "test";
|
||||
}
|
||||
|
||||
template <typename Char, typename T>
|
||||
@@ -914,14 +915,11 @@ TEST(UtilTest, ReportWindowsError) {
|
||||
#endif // _WIN32
|
||||
|
||||
enum TestEnum2 {};
|
||||
enum TestEnum3 {};
|
||||
std::ostream &operator<<(std::ostream &, TestEnum3);
|
||||
|
||||
TEST(UtilTest, ConvertToInt) {
|
||||
EXPECT_TRUE(fmt::internal::ConvertToInt<char>::enable_conversion);
|
||||
EXPECT_FALSE(fmt::internal::ConvertToInt<const char *>::enable_conversion);
|
||||
EXPECT_TRUE(fmt::internal::ConvertToInt<TestEnum2>::value);
|
||||
EXPECT_FALSE(fmt::internal::ConvertToInt<TestEnum3>::value);
|
||||
}
|
||||
|
||||
#if FMT_USE_ENUM_BASE
|
||||
|
||||
16
test/util.h
16
test/util.h
@@ -78,11 +78,7 @@ class BasicTestString {
|
||||
public:
|
||||
explicit BasicTestString(const Char *value = EMPTY) : value_(value) {}
|
||||
|
||||
friend std::basic_ostream<Char> &operator<<(
|
||||
std::basic_ostream<Char> &os, const BasicTestString &s) {
|
||||
os << s.value_;
|
||||
return os;
|
||||
}
|
||||
const std::basic_string<Char> &value() const { return value_; }
|
||||
};
|
||||
|
||||
template <typename Char>
|
||||
@@ -90,3 +86,13 @@ const Char BasicTestString<Char>::EMPTY[] = {0};
|
||||
|
||||
typedef BasicTestString<char> TestString;
|
||||
typedef BasicTestString<wchar_t> TestWString;
|
||||
|
||||
class Date {
|
||||
int year_, month_, day_;
|
||||
public:
|
||||
Date(int year, int month, int day) : year_(year), month_(month), day_(day) {}
|
||||
|
||||
int year() const { return year_; }
|
||||
int month() const { return month_; }
|
||||
int day() const { return day_; }
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user