Allow output stream to be specified on the command line

This commit is contained in:
Phil Nash
2011-01-18 09:20:06 +00:00
parent 925409d7e9
commit 2885339287
10 changed files with 161 additions and 15 deletions

View File

@@ -152,7 +152,10 @@ namespace Catch
case modeOutput:
if( m_args.size() == 0 )
return setErrorMode( m_command + " expected filename" );
m_config.setFilename( m_args[0] );
if( m_args[0][0] == '%' )
m_config.useStream( m_args[0].substr( 1 ) );
else
m_config.setFilename( m_args[0] );
break;
case modeSuccess:
if( m_args.size() != 0 )

View File

@@ -23,6 +23,7 @@
namespace Catch
{
class Config : public IReporterConfig
{
private:
@@ -59,10 +60,17 @@ namespace Catch
m_listSpec( List::None ),
m_shouldDebugBreak( false ),
m_showHelp( false ),
m_os( std::cout.rdbuf() ),
m_streambuf( std::cout.rdbuf() ),
m_os( m_streambuf ),
m_includeWhat( Include::FailedOnly )
{}
///////////////////////////////////////////////////////////////////////////
~Config()
{
setStreamBuf( NULL );
}
///////////////////////////////////////////////////////////////////////////
void setReporter( const std::string& reporterName )
{
@@ -167,14 +175,25 @@ namespace Catch
virtual std::ostream& stream() const
{
return m_os;
}
}
///////////////////////////////////////////////////////////////////////////
void setStreamBuf( std::streambuf* buf )
{
m_os.rdbuf( buf );
// Delete previous stream buf if we own it
if( m_streambuf && dynamic_cast<StreamBufBase*>( m_streambuf ) )
delete m_streambuf;
m_streambuf = buf;
m_os.rdbuf( buf ? buf : std::cout.rdbuf() );
}
///////////////////////////////////////////////////////////////////////////
void useStream( const std::string& streamName )
{
setStreamBuf( Hub::createStreamBuf( streamName ) );
}
///////////////////////////////////////////////////////////////////////////
virtual bool includeSuccessfulResults() const
{
@@ -189,6 +208,7 @@ namespace Catch
std::vector<std::string> m_testSpecs;
bool m_shouldDebugBreak;
bool m_showHelp;
std::streambuf* m_streambuf;
mutable std::ostream m_os;
Include::What m_includeWhat;
};

View File

@@ -15,6 +15,8 @@
#ifndef TWOBLUECUBES_CATCH_DEBUGGER_HPP_INCLUDED
#define TWOBLUECUBES_CATCH_DEBUGGER_HPP_INCLUDED
#include <iostream>
#if defined(macintosh) || defined(__APPLE__) || defined(__APPLE_CC__)
#include <assert.h>
@@ -83,5 +85,14 @@
inline void DebugBreak(){}
#endif
inline void writeToDebugConsole( const std::string& text )
{
#ifdef _WIN32
::OutputDebugStringA( text.get() );
#else
// !TBD: Need a version for Mac/ XCode and other IDEs
std::cout << text;
#endif
}
#endif // TWOBLUECUBES_CATCH_DEBUGGER_HPP_INCLUDED

View File

@@ -23,6 +23,10 @@ namespace Catch
struct IResultCapture;
struct ITestCaseRegistry;
struct IRunner;
class StreamBufBase : public std::streambuf
{
};
class Hub
{
@@ -49,6 +53,10 @@ namespace Catch
static ITestCaseRegistry& getTestCaseRegistry
();
static std::streambuf* createStreamBuf
( const std::string& streamName
);
static IRunner& getRunner
();

View File

@@ -13,9 +13,10 @@
#include "catch_reporter_registry.hpp"
#include "catch_test_case_registry_impl.hpp"
#include "catch_runner_impl.hpp"
#include "catch_stream.hpp"
namespace Catch
{
{
///////////////////////////////////////////////////////////////////////////
Hub::Hub
()
@@ -70,4 +71,18 @@ namespace Catch
{
return *me().m_testCaseRegistry.get();
}
///////////////////////////////////////////////////////////////////////////
std::streambuf* Hub::createStreamBuf
(
const std::string& streamName
)
{
if( streamName == "stdout" ) return std::cout.rdbuf();
if( streamName == "stderr" ) return std::cerr.rdbuf();
if( streamName == "debug" ) return new StreamBufImpl<OutputDebugWriter>;
throw std::domain_error( "Unknown stream: " + streamName );
}
}

71
internal/catch_stream.hpp Normal file
View File

@@ -0,0 +1,71 @@
/*
* catch_stream.hpp
* Catch
*
* Created by Phil on 17/01/2011.
* Copyright 2011 Two Blue Cubes Ltd. All rights reserved.
*
* Distributed under the Boost Software License, Version 1.0. (See accompanying
* file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
*
*/
#ifndef TWOBLUECUBES_CATCH_STREAM_HPP_INCLUDED
#define TWOBLUECUBES_CATCH_STREAM_HPP_INCLUDED
#include <stdexcept>
namespace Catch
{
template<typename WriterF, size_t bufferSize=256>
class StreamBufImpl : public StreamBufBase
{
char data[bufferSize];
WriterF m_writer;
public:
StreamBufImpl()
{
setp( data, data + sizeof(data) );
}
~StreamBufImpl()
{
sync();
}
private:
int overflow( int c )
{
sync();
if( c != EOF )
{
if( pbase() == epptr() )
m_writer( std::string( 1, (char)c ) );
else
sputc( c );
}
return 0;
}
int sync()
{
if( pbase() != pptr() )
{
m_writer( std::string( pbase(), pptr() - pbase() ) );
setp( pbase(), epptr() );
}
return 0;
}
};
struct OutputDebugWriter
{
void operator()( const std::string &str )
{
writeToDebugConsole( str );
}
};
}
#endif // TWOBLUECUBES_CATCH_STREAM_HPP_INCLUDED