mirror of
https://github.com/catchorg/Catch2.git
synced 2024-12-23 03:43:28 +01:00
Allow output stream to be specified on the command line
This commit is contained in:
parent
925409d7e9
commit
2885339287
@ -32,6 +32,7 @@
|
||||
|
||||
/* Begin PBXFileReference section */
|
||||
4A15D2B712E0418F0005EB03 /* catch_self_test.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = catch_self_test.hpp; path = ../internal/catch_self_test.hpp; sourceTree = SOURCE_ROOT; };
|
||||
4A15D4A812E4DF0D0005EB03 /* catch_stream.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = catch_stream.hpp; path = ../internal/catch_stream.hpp; sourceTree = SOURCE_ROOT; };
|
||||
4A302DE312D5114900C84B67 /* catch.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = catch.hpp; path = ../catch.hpp; sourceTree = SOURCE_ROOT; };
|
||||
4A33BCE512CE7F500052A211 /* catch_hub.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = catch_hub.h; path = ../internal/catch_hub.h; sourceTree = SOURCE_ROOT; };
|
||||
4A33BCF912CE80EC0052A211 /* catch_interfaces_reporter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = catch_interfaces_reporter.h; path = ../internal/catch_interfaces_reporter.h; sourceTree = SOURCE_ROOT; };
|
||||
@ -163,6 +164,7 @@
|
||||
4A6D514B12C8A547008F0415 /* catch_debugger.hpp */,
|
||||
4AFC341612809A36003A0C29 /* catch_common.h */,
|
||||
4A992A6512B2156C002B7B66 /* catch_xmlwriter.hpp */,
|
||||
4A15D4A812E4DF0D0005EB03 /* catch_stream.hpp */,
|
||||
);
|
||||
name = support;
|
||||
sourceTree = "<group>";
|
||||
|
@ -23,8 +23,7 @@ TEST_CASE( "selftest/main", "Runs all Catch self tests and checks their results"
|
||||
CHECK( runner.getReporter().getSucceeded() == 53 );
|
||||
CHECK( runner.getReporter().getFailed() == 0 );
|
||||
|
||||
runner.runMatching( "./failing/*" );
|
||||
|
||||
runner.runMatching( "./failing/*" );
|
||||
CHECK( runner.getReporter().getSucceeded() == 0 );
|
||||
CHECK( runner.getReporter().getFailed() == 53 );
|
||||
}
|
||||
|
@ -23,13 +23,17 @@ namespace Catch
|
||||
{
|
||||
public:
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
XmlReporter( const IReporterConfig& config )
|
||||
: m_config( config )
|
||||
XmlReporter
|
||||
(
|
||||
const IReporterConfig& config
|
||||
)
|
||||
: m_config( config )
|
||||
{
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
static std::string getDescription()
|
||||
static std::string getDescription
|
||||
()
|
||||
{
|
||||
return "Reports test results as an XML document";
|
||||
}
|
||||
@ -37,14 +41,19 @@ namespace Catch
|
||||
private: // IReporter
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
virtual void StartTesting()
|
||||
virtual void StartTesting
|
||||
()
|
||||
{
|
||||
m_xml = XmlWriter( m_config.stream() );
|
||||
m_xml.startElement( "AllTests" );
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
virtual void EndTesting( std::size_t succeeded, std::size_t failed )
|
||||
virtual void EndTesting
|
||||
(
|
||||
std::size_t succeeded,
|
||||
std::size_t failed
|
||||
)
|
||||
{
|
||||
m_xml.scopedElement( "OverallResults" )
|
||||
.writeAttribute( "successes", succeeded )
|
||||
@ -52,14 +61,22 @@ namespace Catch
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
virtual void StartGroup( const std::string& groupName )
|
||||
virtual void StartGroup
|
||||
(
|
||||
const std::string& groupName
|
||||
)
|
||||
{
|
||||
m_xml.startElement( "Group" )
|
||||
.writeAttribute( "name", groupName );
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
virtual void EndGroup( const std::string& /*groupName*/, std::size_t succeeded, std::size_t failed )
|
||||
virtual void EndGroup
|
||||
(
|
||||
const std::string& /*groupName*/,
|
||||
std::size_t succeeded,
|
||||
std::size_t failed
|
||||
)
|
||||
{
|
||||
m_xml.scopedElement( "OverallResults" )
|
||||
.writeAttribute( "successes", succeeded )
|
||||
|
@ -50,7 +50,7 @@ namespace Catch
|
||||
<< "\t-l, --list <tests | reporters> [xml]\n"
|
||||
<< "\t-t, --test <testspec> [<testspec>...]\n"
|
||||
<< "\t-r, --reporter <reporter name>\n"
|
||||
<< "\t-o, --out <file name>\n"
|
||||
<< "\t-o, --out <file name>|<%stream name>\n"
|
||||
<< "\t-s, --success\n"
|
||||
<< "\t-b, --break\n\n"
|
||||
<< "For more detail usage please see: https://github.com/philsquared/Catch/wiki/Command-line" << std::endl;
|
||||
|
@ -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 )
|
||||
|
@ -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;
|
||||
};
|
||||
|
@ -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
|
@ -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
|
||||
();
|
||||
|
||||
|
@ -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
71
internal/catch_stream.hpp
Normal 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
|
Loading…
Reference in New Issue
Block a user