mirror of
https://github.com/catchorg/Catch2.git
synced 2024-11-26 15:26:11 +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 */
|
/* 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; };
|
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; };
|
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; };
|
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; };
|
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 */,
|
4A6D514B12C8A547008F0415 /* catch_debugger.hpp */,
|
||||||
4AFC341612809A36003A0C29 /* catch_common.h */,
|
4AFC341612809A36003A0C29 /* catch_common.h */,
|
||||||
4A992A6512B2156C002B7B66 /* catch_xmlwriter.hpp */,
|
4A992A6512B2156C002B7B66 /* catch_xmlwriter.hpp */,
|
||||||
|
4A15D4A812E4DF0D0005EB03 /* catch_stream.hpp */,
|
||||||
);
|
);
|
||||||
name = support;
|
name = support;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
|
@ -24,7 +24,6 @@ TEST_CASE( "selftest/main", "Runs all Catch self tests and checks their results"
|
|||||||
CHECK( runner.getReporter().getFailed() == 0 );
|
CHECK( runner.getReporter().getFailed() == 0 );
|
||||||
|
|
||||||
runner.runMatching( "./failing/*" );
|
runner.runMatching( "./failing/*" );
|
||||||
|
|
||||||
CHECK( runner.getReporter().getSucceeded() == 0 );
|
CHECK( runner.getReporter().getSucceeded() == 0 );
|
||||||
CHECK( runner.getReporter().getFailed() == 53 );
|
CHECK( runner.getReporter().getFailed() == 53 );
|
||||||
}
|
}
|
||||||
|
@ -23,13 +23,17 @@ namespace Catch
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
///////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////
|
||||||
XmlReporter( const IReporterConfig& config )
|
XmlReporter
|
||||||
: m_config( config )
|
(
|
||||||
|
const IReporterConfig& config
|
||||||
|
)
|
||||||
|
: m_config( config )
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////
|
||||||
static std::string getDescription()
|
static std::string getDescription
|
||||||
|
()
|
||||||
{
|
{
|
||||||
return "Reports test results as an XML document";
|
return "Reports test results as an XML document";
|
||||||
}
|
}
|
||||||
@ -37,14 +41,19 @@ namespace Catch
|
|||||||
private: // IReporter
|
private: // IReporter
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////
|
||||||
virtual void StartTesting()
|
virtual void StartTesting
|
||||||
|
()
|
||||||
{
|
{
|
||||||
m_xml = XmlWriter( m_config.stream() );
|
m_xml = XmlWriter( m_config.stream() );
|
||||||
m_xml.startElement( "AllTests" );
|
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" )
|
m_xml.scopedElement( "OverallResults" )
|
||||||
.writeAttribute( "successes", succeeded )
|
.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" )
|
m_xml.startElement( "Group" )
|
||||||
.writeAttribute( "name", groupName );
|
.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" )
|
m_xml.scopedElement( "OverallResults" )
|
||||||
.writeAttribute( "successes", succeeded )
|
.writeAttribute( "successes", succeeded )
|
||||||
|
@ -50,7 +50,7 @@ namespace Catch
|
|||||||
<< "\t-l, --list <tests | reporters> [xml]\n"
|
<< "\t-l, --list <tests | reporters> [xml]\n"
|
||||||
<< "\t-t, --test <testspec> [<testspec>...]\n"
|
<< "\t-t, --test <testspec> [<testspec>...]\n"
|
||||||
<< "\t-r, --reporter <reporter name>\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-s, --success\n"
|
||||||
<< "\t-b, --break\n\n"
|
<< "\t-b, --break\n\n"
|
||||||
<< "For more detail usage please see: https://github.com/philsquared/Catch/wiki/Command-line" << std::endl;
|
<< "For more detail usage please see: https://github.com/philsquared/Catch/wiki/Command-line" << std::endl;
|
||||||
|
@ -152,7 +152,10 @@ namespace Catch
|
|||||||
case modeOutput:
|
case modeOutput:
|
||||||
if( m_args.size() == 0 )
|
if( m_args.size() == 0 )
|
||||||
return setErrorMode( m_command + " expected filename" );
|
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;
|
break;
|
||||||
case modeSuccess:
|
case modeSuccess:
|
||||||
if( m_args.size() != 0 )
|
if( m_args.size() != 0 )
|
||||||
|
@ -23,6 +23,7 @@
|
|||||||
|
|
||||||
namespace Catch
|
namespace Catch
|
||||||
{
|
{
|
||||||
|
|
||||||
class Config : public IReporterConfig
|
class Config : public IReporterConfig
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
@ -59,10 +60,17 @@ namespace Catch
|
|||||||
m_listSpec( List::None ),
|
m_listSpec( List::None ),
|
||||||
m_shouldDebugBreak( false ),
|
m_shouldDebugBreak( false ),
|
||||||
m_showHelp( false ),
|
m_showHelp( false ),
|
||||||
m_os( std::cout.rdbuf() ),
|
m_streambuf( std::cout.rdbuf() ),
|
||||||
|
m_os( m_streambuf ),
|
||||||
m_includeWhat( Include::FailedOnly )
|
m_includeWhat( Include::FailedOnly )
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////
|
||||||
|
~Config()
|
||||||
|
{
|
||||||
|
setStreamBuf( NULL );
|
||||||
|
}
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////
|
||||||
void setReporter( const std::string& reporterName )
|
void setReporter( const std::string& reporterName )
|
||||||
{
|
{
|
||||||
@ -172,7 +180,18 @@ namespace Catch
|
|||||||
///////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////
|
||||||
void setStreamBuf( std::streambuf* buf )
|
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 ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////
|
||||||
@ -189,6 +208,7 @@ namespace Catch
|
|||||||
std::vector<std::string> m_testSpecs;
|
std::vector<std::string> m_testSpecs;
|
||||||
bool m_shouldDebugBreak;
|
bool m_shouldDebugBreak;
|
||||||
bool m_showHelp;
|
bool m_showHelp;
|
||||||
|
std::streambuf* m_streambuf;
|
||||||
mutable std::ostream m_os;
|
mutable std::ostream m_os;
|
||||||
Include::What m_includeWhat;
|
Include::What m_includeWhat;
|
||||||
};
|
};
|
||||||
|
@ -15,6 +15,8 @@
|
|||||||
#ifndef TWOBLUECUBES_CATCH_DEBUGGER_HPP_INCLUDED
|
#ifndef TWOBLUECUBES_CATCH_DEBUGGER_HPP_INCLUDED
|
||||||
#define TWOBLUECUBES_CATCH_DEBUGGER_HPP_INCLUDED
|
#define TWOBLUECUBES_CATCH_DEBUGGER_HPP_INCLUDED
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
#if defined(macintosh) || defined(__APPLE__) || defined(__APPLE_CC__)
|
#if defined(macintosh) || defined(__APPLE__) || defined(__APPLE_CC__)
|
||||||
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
@ -83,5 +85,14 @@
|
|||||||
inline void DebugBreak(){}
|
inline void DebugBreak(){}
|
||||||
#endif
|
#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
|
#endif // TWOBLUECUBES_CATCH_DEBUGGER_HPP_INCLUDED
|
@ -24,6 +24,10 @@ namespace Catch
|
|||||||
struct ITestCaseRegistry;
|
struct ITestCaseRegistry;
|
||||||
struct IRunner;
|
struct IRunner;
|
||||||
|
|
||||||
|
class StreamBufBase : public std::streambuf
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
class Hub
|
class Hub
|
||||||
{
|
{
|
||||||
Hub();
|
Hub();
|
||||||
@ -49,6 +53,10 @@ namespace Catch
|
|||||||
static ITestCaseRegistry& getTestCaseRegistry
|
static ITestCaseRegistry& getTestCaseRegistry
|
||||||
();
|
();
|
||||||
|
|
||||||
|
static std::streambuf* createStreamBuf
|
||||||
|
( const std::string& streamName
|
||||||
|
);
|
||||||
|
|
||||||
static IRunner& getRunner
|
static IRunner& getRunner
|
||||||
();
|
();
|
||||||
|
|
||||||
|
@ -13,6 +13,7 @@
|
|||||||
#include "catch_reporter_registry.hpp"
|
#include "catch_reporter_registry.hpp"
|
||||||
#include "catch_test_case_registry_impl.hpp"
|
#include "catch_test_case_registry_impl.hpp"
|
||||||
#include "catch_runner_impl.hpp"
|
#include "catch_runner_impl.hpp"
|
||||||
|
#include "catch_stream.hpp"
|
||||||
|
|
||||||
namespace Catch
|
namespace Catch
|
||||||
{
|
{
|
||||||
@ -70,4 +71,18 @@ namespace Catch
|
|||||||
{
|
{
|
||||||
return *me().m_testCaseRegistry.get();
|
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