Read-only mirrors. Development, issues and pull requests are on GitHub.

summaryrefslogtreecommitdiffhomepage
path: root/include
diff options
context:
space:
mode:
authorPhil Nash2015-09-29 19:21:08 +0100
committerPhil Nash2015-09-29 19:23:06 +0100
commitd43a47efca81129eb079b924e61d8cbcd12d8f3c (patch)
tree6e5f78a628384dd2dd324bb0670b08fb2638d522 /include
parenta0de07d45bf84ed1c77652f097fd7c55c6cf1888 (diff)
downloadcatch3-d43a47efca81129eb079b924e61d8cbcd12d8f3c.tar.gz
Refactored stream related stuff
- simpler, polymorphic hierarchy-based, approach - less bitty conditionals spread across the code - all resolved up-front so now config class is immutable (it had evolved the way it was and in need of a clean-up sweep for a long time)
Diffstat (limited to 'include')
-rw-r--r--include/catch_session.hpp14
-rw-r--r--include/internal/catch_config.hpp38
-rw-r--r--include/internal/catch_context_impl.hpp8
-rw-r--r--include/internal/catch_impl.hpp1
-rw-r--r--include/internal/catch_stream.h50
-rw-r--r--include/internal/catch_stream.hpp47
6 files changed, 86 insertions, 72 deletions
diff --git a/include/catch_session.hpp b/include/catch_session.hpp
index 1f37b5a5..c63f517b 100644
--- a/include/catch_session.hpp
+++ b/include/catch_session.hpp
@@ -52,25 +52,11 @@ namespace Catch {
return reporters;
}
- void openStreamInto( Ptr<Config> const& config, std::ofstream& ofs ) {
- // Open output file, if specified
- if( !config->getFilename().empty() ) {
- ofs.open( config->getFilename().c_str() );
- if( ofs.fail() ) {
- std::ostringstream oss;
- oss << "Unable to open file: '" << config->getFilename() << "'";
- throw std::domain_error( oss.str() );
- }
- config->setStreamBuf( ofs.rdbuf() );
- }
- }
Totals runTests( Ptr<Config> const& config ) {
Ptr<IConfig const> iconfig = config.get();
- std::ofstream ofs;
- openStreamInto( config, ofs );
Ptr<IStreamingReporter> reporter = makeReporter( config );
reporter = addListeners( iconfig, reporter );
diff --git a/include/internal/catch_config.hpp b/include/internal/catch_config.hpp
index 6b2b04a3..eca10363 100644
--- a/include/internal/catch_config.hpp
+++ b/include/internal/catch_config.hpp
@@ -85,12 +85,11 @@ namespace Catch {
public:
Config()
- : m_os( Catch::cout().rdbuf() )
{}
Config( ConfigData const& data )
: m_data( data ),
- m_os( Catch::cout().rdbuf() )
+ m_stream( openStream() )
{
if( !data.testsOrTags.empty() ) {
TestSpecParser parser( ITagAliasRegistry::get() );
@@ -101,12 +100,6 @@ namespace Catch {
}
virtual ~Config() {
- m_os.rdbuf( Catch::cout().rdbuf() );
- m_stream.release();
- }
-
- void setFilename( std::string const& filename ) {
- m_data.outputFilename = filename;
}
std::string const& getFilename() const {
@@ -122,17 +115,6 @@ namespace Catch {
bool shouldDebugBreak() const { return m_data.shouldDebugBreak; }
- void setStreamBuf( std::streambuf* buf ) {
- m_os.rdbuf( buf ? buf : Catch::cout().rdbuf() );
- }
-
- void useStream( std::string const& streamName ) {
- Stream stream = createStream( streamName );
- setStreamBuf( stream.streamBuf );
- m_stream.release();
- m_stream = stream;
- }
-
std::vector<std::string> getReporterNames() const { return m_data.reporterNames; }
int abortAfter() const { return m_data.abortAfter; }
@@ -144,7 +126,7 @@ namespace Catch {
// IConfig interface
virtual bool allowThrows() const { return !m_data.noThrow; }
- virtual std::ostream& stream() const { return m_os; }
+ virtual std::ostream& stream() const { return m_stream->stream(); }
virtual std::string name() const { return m_data.name.empty() ? m_data.processName : m_data.name; }
virtual bool includeSuccessfulResults() const { return m_data.showSuccessfulTests; }
virtual bool warnAboutMissingAssertions() const { return m_data.warnings & WarnAbout::NoAssertions; }
@@ -154,10 +136,22 @@ namespace Catch {
virtual bool forceColour() const { return m_data.forceColour; }
private:
+
+ IStream const* openStream() {
+ if( m_data.outputFilename.empty() )
+ return new CoutStream();
+ else if( m_data.outputFilename[0] == '%' ) {
+ if( m_data.outputFilename == "%debug" )
+ return new DebugOutStream();
+ else
+ throw std::domain_error( "Unrecognised stream: " + m_data.outputFilename );
+ }
+ else
+ return new FileStream( m_data.outputFilename );
+ }
ConfigData m_data;
- Stream m_stream;
- mutable std::ostream m_os;
+ std::auto_ptr<IStream const> m_stream;
TestSpec m_testSpec;
};
diff --git a/include/internal/catch_context_impl.hpp b/include/internal/catch_context_impl.hpp
index a3ac2ae5..030f29e2 100644
--- a/include/internal/catch_context_impl.hpp
+++ b/include/internal/catch_context_impl.hpp
@@ -95,14 +95,6 @@ namespace Catch {
return getCurrentMutableContext();
}
- Stream createStream( std::string const& streamName ) {
- if( streamName == "stdout" ) return Stream( Catch::cout().rdbuf(), false );
- if( streamName == "stderr" ) return Stream( Catch::cerr().rdbuf(), false );
- if( streamName == "debug" ) return Stream( new StreamBufImpl<OutputDebugWriter>, true );
-
- throw std::domain_error( "Unknown stream: " + streamName );
- }
-
void cleanUpContext() {
delete currentContext;
currentContext = CATCH_NULL;
diff --git a/include/internal/catch_impl.hpp b/include/internal/catch_impl.hpp
index 3ff5ac00..170b4807 100644
--- a/include/internal/catch_impl.hpp
+++ b/include/internal/catch_impl.hpp
@@ -45,6 +45,7 @@
namespace Catch {
NonCopyable::~NonCopyable() {}
IShared::~IShared() {}
+ IStream::~IStream() CATCH_NOEXCEPT {}
StreamBufBase::~StreamBufBase() CATCH_NOEXCEPT {}
IContext::~IContext() {}
IResultCapture::~IResultCapture() {}
diff --git a/include/internal/catch_stream.h b/include/internal/catch_stream.h
index 402a6617..a69c841e 100644
--- a/include/internal/catch_stream.h
+++ b/include/internal/catch_stream.h
@@ -9,28 +9,52 @@
#ifndef TWOBLUECUBES_CATCH_STREAM_H_INCLUDED
#define TWOBLUECUBES_CATCH_STREAM_H_INCLUDED
-#include <streambuf>
+#include "catch_compiler_capabilities.h"
+#include "catch_streambuf.h"
-#ifdef __clang__
-#pragma clang diagnostic ignored "-Wpadded"
-#endif
+#include <streambuf>
+#include <ostream>
+#include <fstream>
namespace Catch {
- class Stream {
+ std::ostream& cout();
+ std::ostream& cerr();
+
+
+ struct IStream {
+ virtual ~IStream() CATCH_NOEXCEPT;
+ virtual std::ostream& stream() const = 0;
+ };
+
+ class FileStream : public IStream {
+ mutable std::ofstream m_ofs;
public:
- Stream();
- Stream( std::streambuf* _streamBuf, bool _isOwned );
- void release();
+ FileStream( std::string const& filename );
+ public: // IStream
+ virtual std::ostream& stream() const CATCH_OVERRIDE;
+ };
+
- std::streambuf* streamBuf;
+ class CoutStream : public IStream {
+ mutable std::ostream m_os;
+ public:
+ CoutStream();
- private:
- bool isOwned;
+ public: // IStream
+ virtual std::ostream& stream() const CATCH_OVERRIDE;
};
- std::ostream& cout();
- std::ostream& cerr();
+
+ class DebugOutStream : public IStream {
+ std::auto_ptr<StreamBufBase> m_streamBuf;
+ mutable std::ostream m_os;
+ public:
+ DebugOutStream();
+
+ public: // IStream
+ virtual std::ostream& stream() const CATCH_OVERRIDE;
+ };
}
#endif // TWOBLUECUBES_CATCH_STREAM_H_INCLUDED
diff --git a/include/internal/catch_stream.hpp b/include/internal/catch_stream.hpp
index 42933487..e6bf7b0c 100644
--- a/include/internal/catch_stream.hpp
+++ b/include/internal/catch_stream.hpp
@@ -10,7 +10,6 @@
#define TWOBLUECUBES_CATCH_STREAM_HPP_INCLUDED
#include "catch_stream.h"
-#include "catch_streambuf.h"
#include "catch_debugger.h"
#include <stdexcept>
@@ -57,29 +56,47 @@ namespace Catch {
///////////////////////////////////////////////////////////////////////////
- struct OutputDebugWriter {
+ FileStream::FileStream( std::string const& filename ) {
+ m_ofs.open( filename.c_str() );
+ if( m_ofs.fail() ) {
+ std::ostringstream oss;
+ oss << "Unable to open file: '" << filename << "'";
+ throw std::domain_error( oss.str() );
+ }
+ }
+
+ std::ostream& FileStream::stream() const {
+ return m_ofs;
+ }
+
+ struct OutputDebugWriter {
+
void operator()( std::string const&str ) {
writeToDebugConsole( str );
}
};
-
- Stream::Stream()
- : streamBuf( CATCH_NULL ), isOwned( false )
+
+ DebugOutStream::DebugOutStream()
+ : m_streamBuf( new StreamBufImpl<OutputDebugWriter>() ),
+ m_os( m_streamBuf.get() )
{}
-
- Stream::Stream( std::streambuf* _streamBuf, bool _isOwned )
- : streamBuf( _streamBuf ), isOwned( _isOwned )
+
+ std::ostream& DebugOutStream::stream() const {
+ return m_os;
+ }
+
+ // Store the streambuf from cout up-front because
+ // cout may get redirected when running tests
+ CoutStream::CoutStream()
+ : m_os( Catch::cout().rdbuf() )
{}
- void Stream::release() {
- if( isOwned ) {
- delete streamBuf;
- streamBuf = CATCH_NULL;
- isOwned = false;
- }
+ std::ostream& CoutStream::stream() const {
+ return m_os;
}
-
+
+
#ifndef CATCH_CONFIG_NOSTDOUT // If you #define this you must implement this functions
std::ostream& cout() {
return std::cout;