From aa9d635014c3ab321fe65bd59c50fa71d6a86583 Mon Sep 17 00:00:00 2001 From: Phil Nash Date: Tue, 5 Dec 2017 23:19:28 +0000 Subject: [PATCH] Refactored StreamRedirect classes --- include/internal/catch_run_context.cpp | 66 +++++++++++++++++--------- include/internal/catch_run_context.h | 27 ----------- 2 files changed, 43 insertions(+), 50 deletions(-) diff --git a/include/internal/catch_run_context.cpp b/include/internal/catch_run_context.cpp index 44e3fb37..2f07a6a0 100644 --- a/include/internal/catch_run_context.cpp +++ b/include/internal/catch_run_context.cpp @@ -10,30 +10,47 @@ namespace Catch { - StreamRedirect::StreamRedirect(std::ostream& stream, std::string& targetString) - : m_stream(stream), - m_prevBuf(stream.rdbuf()), - m_targetString(targetString) { - stream.rdbuf(m_oss.get().rdbuf()); - } + class RedirectedStream { + std::ostream& m_originalStream; + std::ostream& m_redirectionStream; + std::streambuf* m_prevBuf; - StreamRedirect::~StreamRedirect() { - m_targetString += m_oss.str(); - m_stream.rdbuf(m_prevBuf); - } + public: + RedirectedStream( std::ostream& originalStream, std::ostream& redirectionStream ) + : m_originalStream( originalStream ), + m_redirectionStream( redirectionStream ), + m_prevBuf( m_originalStream.rdbuf() ) + { + m_originalStream.rdbuf( m_redirectionStream.rdbuf() ); + } + ~RedirectedStream() { + m_originalStream.rdbuf( m_prevBuf ); + } + }; - StdErrRedirect::StdErrRedirect(std::string & targetString) - :m_cerrBuf(cerr().rdbuf()), m_clogBuf(clog().rdbuf()), - m_targetString(targetString) { - cerr().rdbuf(m_oss.get().rdbuf()); - clog().rdbuf(m_oss.get().rdbuf()); - } + class RedirectedStdOut { + ReusableStringStream m_rss; + RedirectedStream m_cout; + public: + RedirectedStdOut() : m_cout( Catch::cout(), m_rss.get() ) {} + auto str() const -> std::string { return m_rss.str(); } + }; + + // StdErr has two constituent streams in C++, std::cerr and std::clog + // This means that we need to redirect 2 streams into 1 to keep proper + // order of writes + class RedirectedStdErr { + ReusableStringStream m_rss; + RedirectedStream m_cerr; + RedirectedStream m_clog; + public: + RedirectedStdErr() + : m_cerr( Catch::cerr(), m_rss.get() ), + m_clog( Catch::clog(), m_rss.get() ) + {} + auto str() const -> std::string { return m_rss.str(); } + }; - StdErrRedirect::~StdErrRedirect() { - m_targetString += m_oss.str(); - cerr().rdbuf(m_cerrBuf); - clog().rdbuf(m_clogBuf); - } RunContext::RunContext(IConfigPtr const& _config, IStreamingReporterPtr&& reporter) : m_runInfo(_config->name()), @@ -282,10 +299,13 @@ namespace Catch { Timer timer; try { if (m_reporter->getPreferences().shouldRedirectStdOut) { - StreamRedirect coutRedir(cout(), redirectedCout); - StdErrRedirect errRedir(redirectedCerr); + RedirectedStdOut redirectedStdOut; + RedirectedStdErr redirectedStdErr; timer.start(); invokeActiveTestCase(); + redirectedCout += redirectedStdOut.str(); + redirectedCerr += redirectedStdErr.str(); + } else { timer.start(); invokeActiveTestCase(); diff --git a/include/internal/catch_run_context.h b/include/internal/catch_run_context.h index 732caa47..d0007a36 100644 --- a/include/internal/catch_run_context.h +++ b/include/internal/catch_run_context.h @@ -28,33 +28,6 @@ namespace Catch { struct IMutableContext; - class StreamRedirect { - - public: - StreamRedirect(std::ostream& stream, std::string& targetString); - ~StreamRedirect(); - - private: - std::ostream& m_stream; - std::streambuf* m_prevBuf; - ReusableStringStream m_oss; - std::string& m_targetString; - }; - - // StdErr has two constituent streams in C++, std::cerr and std::clog - // This means that we need to redirect 2 streams into 1 to keep proper - // order of writes and cannot use StreamRedirect on its own - class StdErrRedirect { - public: - explicit StdErrRedirect( std::string& targetString ); - ~StdErrRedirect(); - private: - std::streambuf* m_cerrBuf; - std::streambuf* m_clogBuf; - ReusableStringStream m_oss; - std::string& m_targetString; - }; - /////////////////////////////////////////////////////////////////////////// class RunContext : public IResultCapture, public IRunner {