From 0867c1b4479aa9e21bb35701c28c1a6eec168e18 Mon Sep 17 00:00:00 2001 From: vitaut Date: Fri, 4 Mar 2016 09:04:28 -0800 Subject: [PATCH] Test writing to ostream --- cppformat/format.cc | 2 +- test/format-impl-test.cc | 55 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 56 insertions(+), 1 deletion(-) diff --git a/cppformat/format.cc b/cppformat/format.cc index 96597dab..daccd68f 100644 --- a/cppformat/format.cc +++ b/cppformat/format.cc @@ -364,7 +364,7 @@ class CharConverter : public fmt::internal::ArgVisitor { }; // Write the content of w to os. -void write(std::ostream &os, fmt::MemoryWriter &w) { +void write(std::ostream &os, fmt::Writer &w) { const char *data = w.data(); typedef internal::MakeUnsigned::Type UnsignedStreamSize; UnsignedStreamSize size = w.size(); diff --git a/test/format-impl-test.cc b/test/format-impl-test.cc index 9f9cc5dd..b5d92227 100644 --- a/test/format-impl-test.cc +++ b/test/format-impl-test.cc @@ -31,11 +31,14 @@ // Include format.cc instead of format.h to test implementation-specific stuff. #include "cppformat/format.cc" +#include #include +#include "gmock/gmock.h" #include "gtest-extra.h" #include "util.h" +#undef min #undef max TEST(FormatTest, ArgConverter) { @@ -119,3 +122,55 @@ 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::max(); + std::streamsize max_streamsize = std::numeric_limits::max(); + if (max_size <= fmt::internal::to_unsigned(max_streamsize)) + return; + + class TestWriter : public fmt::BasicWriter { + private: + struct TestBuffer : fmt::Buffer { + explicit TestBuffer(std::size_t size) { size_ = size; } + void grow(std::size_t) {} + } buffer_; + public: + explicit TestWriter(std::size_t size) + : fmt::BasicWriter(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::Type UStreamSize; + UStreamSize n = std::min( + size, fmt::internal::to_unsigned(max_streamsize)); + EXPECT_CALL(buffer, xsputn(data, static_cast(n))) + .WillOnce(testing::Return(max_streamsize)); + data += n; + size -= n; + } while (size != 0); + fmt::write(os, w); +}