mirror of
https://github.com/catchorg/Catch2.git
synced 2025-08-01 21:05:39 +02:00
Merge from mainline
This commit is contained in:
@@ -34,7 +34,7 @@
|
||||
#include "internal/catch_notimplemented_exception.h"
|
||||
#include "internal/catch_context.h"
|
||||
#include "internal/catch_capture.hpp"
|
||||
#include "internal/catch_section.hpp"
|
||||
#include "internal/catch_section.h"
|
||||
#include "internal/catch_generators.hpp"
|
||||
#include "internal/catch_interfaces_exception.h"
|
||||
#include "internal/catch_approx.hpp"
|
||||
@@ -67,11 +67,11 @@
|
||||
#if defined( CATCH_CONFIG_MAIN ) || defined( CATCH_CONFIG_RUNNER )
|
||||
#define INTERNAL_CATCH_INLINE
|
||||
#include "internal/catch_impl.hpp"
|
||||
#endif
|
||||
#endif // CATCH_CONFIG_MAIN || CATCH_CONFIG_RUNNER
|
||||
|
||||
#ifdef CATCH_CONFIG_MAIN
|
||||
#include "internal/catch_default_main.hpp"
|
||||
#endif
|
||||
#endif // CATCH_CONFIG_MAIN
|
||||
|
||||
#endif // INTERNAL_CATCH_VS_MANAGED or INTERNAL_CATCH_VS_NATIVE defined
|
||||
|
||||
|
@@ -12,11 +12,13 @@
|
||||
#include "catch_expressionresult_builder.h"
|
||||
#include "catch_message.h"
|
||||
#include "catch_interfaces_capture.h"
|
||||
#include "catch_debugger.hpp"
|
||||
#include "catch_debugger.h"
|
||||
#include "catch_context.h"
|
||||
#include "catch_common.h"
|
||||
#include "catch_tostring.hpp"
|
||||
#include "catch_interfaces_reporter.h"
|
||||
//#include "catch_interfaces_registry_hub.h"
|
||||
//#include "catch_interfaces_config.h"
|
||||
#include "internal/catch_compiler_capabilities.h"
|
||||
|
||||
#include <ostream>
|
||||
@@ -117,7 +119,7 @@ struct TestFailureException{};
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
#define INTERNAL_CATCH_ACCEPT_EXPR( evaluatedExpr, resultDisposition, originalExpr ) \
|
||||
if( Catch::ResultAction::Value internal_catch_action = Catch::getResultCapture().acceptExpression( evaluatedExpr, INTERNAL_CATCH_ASSERTIONINFO_NAME ) ) { \
|
||||
if( internal_catch_action & Catch::ResultAction::Debug ) BreakIntoDebugger(); \
|
||||
if( internal_catch_action & Catch::ResultAction::Debug ) CATCH_BREAK_INTO_DEBUGGER(); \
|
||||
if( internal_catch_action & Catch::ResultAction::Abort ) { INTERNAL_CATCH_TEST_THROW_FAILURE } \
|
||||
if( !Catch::shouldContinueOnFailure( resultDisposition ) ) { INTERNAL_CATCH_TEST_THROW_FAILURE } \
|
||||
Catch::isTrue( false && originalExpr ); \
|
||||
|
@@ -12,6 +12,8 @@
|
||||
#include "catch_common.h"
|
||||
#include "clara.h"
|
||||
|
||||
#include <fstream>
|
||||
|
||||
namespace Catch {
|
||||
|
||||
inline void abortAfterFirst( ConfigData& config ) { config.abortAfter = 1; }
|
||||
@@ -38,7 +40,18 @@ namespace Catch {
|
||||
? ShowDurations::Always
|
||||
: ShowDurations::Never;
|
||||
}
|
||||
|
||||
inline void loadTestNamesFromFile( ConfigData& config, std::string const& _filename ) {
|
||||
std::ifstream f( _filename.c_str() );
|
||||
if( !f.is_open() )
|
||||
throw std::domain_error( "Unable to load input file: " + _filename );
|
||||
|
||||
std::string line;
|
||||
while( std::getline( f, line ) ) {
|
||||
line = trim(line);
|
||||
if( !line.empty() && !startsWith( line, "#" ) )
|
||||
addTestOrTags( config, line );
|
||||
}
|
||||
}
|
||||
|
||||
inline Clara::CommandLine<ConfigData> makeCommandLineParser() {
|
||||
|
||||
@@ -53,19 +66,15 @@ namespace Catch {
|
||||
.longOpt( "help" );
|
||||
|
||||
cli.bind( &ConfigData::listTests )
|
||||
.describe( "list all (or matching) test cases" )
|
||||
.describe( "list all/matching test cases" )
|
||||
.shortOpt( "l")
|
||||
.longOpt( "list-tests" );
|
||||
|
||||
cli.bind( &ConfigData::listTags )
|
||||
.describe( "list all (or matching) tags" )
|
||||
.describe( "list all/matching tags" )
|
||||
.shortOpt( "t")
|
||||
.longOpt( "list-tags" );
|
||||
|
||||
cli.bind( &ConfigData::listReporters )
|
||||
.describe( "list all reporters" )
|
||||
.longOpt( "list-reporters" );
|
||||
|
||||
cli.bind( &ConfigData::showSuccessfulTests )
|
||||
.describe( "include successful tests in output" )
|
||||
.shortOpt( "s")
|
||||
@@ -88,7 +97,7 @@ namespace Catch {
|
||||
.hint( "filename" );
|
||||
|
||||
cli.bind( &ConfigData::reporterName )
|
||||
.describe( "reporter to use - defaults to console" )
|
||||
.describe( "reporter to use (defaults to console)" )
|
||||
.shortOpt( "r")
|
||||
.longOpt( "reporter" )
|
||||
// .hint( "name[:filename]" );
|
||||
@@ -133,6 +142,22 @@ namespace Catch {
|
||||
.longOpt( "durations" )
|
||||
.hint( "yes/no" );
|
||||
|
||||
cli.bind( &loadTestNamesFromFile )
|
||||
.describe( "load test names to run from a file" )
|
||||
.shortOpt( "f")
|
||||
.longOpt( "input-file" )
|
||||
.hint( "filename" );
|
||||
|
||||
// Less common commands which don't have a short form
|
||||
cli.bind( &ConfigData::listTestNamesOnly )
|
||||
.describe( "list all/matching test cases names only" )
|
||||
.longOpt( "list-test-names-only" );
|
||||
|
||||
cli.bind( &ConfigData::listReporters )
|
||||
.describe( "list all reporters" )
|
||||
.longOpt( "list-reporters" );
|
||||
|
||||
|
||||
return cli;
|
||||
}
|
||||
|
||||
|
@@ -67,36 +67,17 @@ namespace Catch {
|
||||
std::for_each( container.begin(), container.end(), function );
|
||||
}
|
||||
|
||||
inline bool startsWith( std::string const& s, std::string const& prefix ) {
|
||||
return s.size() >= prefix.size() && s.substr( 0, prefix.size() ) == prefix;
|
||||
}
|
||||
inline bool endsWith( std::string const& s, std::string const& suffix ) {
|
||||
return s.size() >= suffix.size() && s.substr( s.size()-suffix.size(), suffix.size() ) == suffix;
|
||||
}
|
||||
inline bool contains( std::string const& s, std::string const& infix ) {
|
||||
return s.find( infix ) != std::string::npos;
|
||||
}
|
||||
inline void toLowerInPlace( std::string& s ) {
|
||||
std::transform( s.begin(), s.end(), s.begin(), ::tolower );
|
||||
}
|
||||
inline std::string toLower( std::string const& s ) {
|
||||
std::string lc = s;
|
||||
toLowerInPlace( lc );
|
||||
return lc;
|
||||
}
|
||||
bool startsWith( std::string const& s, std::string const& prefix );
|
||||
bool endsWith( std::string const& s, std::string const& suffix );
|
||||
bool contains( std::string const& s, std::string const& infix );
|
||||
void toLowerInPlace( std::string& s );
|
||||
std::string toLower( std::string const& s );
|
||||
std::string trim( std::string const& str );
|
||||
|
||||
struct pluralise {
|
||||
pluralise( std::size_t count, std::string const& label )
|
||||
: m_count( count ),
|
||||
m_label( label )
|
||||
{}
|
||||
pluralise( std::size_t count, std::string const& label );
|
||||
|
||||
friend std::ostream& operator << ( std::ostream& os, pluralise const& pluraliser ) {
|
||||
os << pluraliser.m_count << " " << pluraliser.m_label;
|
||||
if( pluraliser.m_count != 1 )
|
||||
os << "s";
|
||||
return os;
|
||||
}
|
||||
friend std::ostream& operator << ( std::ostream& os, pluralise const& pluraliser );
|
||||
|
||||
std::size_t m_count;
|
||||
std::string m_label;
|
||||
@@ -104,43 +85,22 @@ namespace Catch {
|
||||
|
||||
struct SourceLineInfo {
|
||||
|
||||
SourceLineInfo() : line( 0 ){}
|
||||
SourceLineInfo( std::string const& _file, std::size_t _line )
|
||||
: file( _file ),
|
||||
line( _line )
|
||||
{}
|
||||
SourceLineInfo( SourceLineInfo const& other )
|
||||
: file( other.file ),
|
||||
line( other.line )
|
||||
{}
|
||||
bool empty() const {
|
||||
return file.empty();
|
||||
}
|
||||
bool operator == ( SourceLineInfo const& other ) const {
|
||||
return line == other.line && file == other.file;
|
||||
}
|
||||
SourceLineInfo();
|
||||
SourceLineInfo( char const* _file, std::size_t _line );
|
||||
SourceLineInfo( SourceLineInfo const& other );
|
||||
bool empty() const;
|
||||
bool operator == ( SourceLineInfo const& other ) const;
|
||||
|
||||
std::string file;
|
||||
std::size_t line;
|
||||
};
|
||||
|
||||
inline std::ostream& operator << ( std::ostream& os, SourceLineInfo const& info ) {
|
||||
#ifndef __GNUG__
|
||||
os << info.file << "(" << info.line << ")";
|
||||
#else
|
||||
os << info.file << ":" << info.line;
|
||||
#endif
|
||||
return os;
|
||||
}
|
||||
std::ostream& operator << ( std::ostream& os, SourceLineInfo const& info );
|
||||
|
||||
// This is just here to avoid compiler warnings with macro constants and boolean literals
|
||||
inline bool isTrue( bool value ){ return value; }
|
||||
|
||||
inline void throwLogicError( std::string const& message, SourceLineInfo const& locationInfo ) {
|
||||
std::ostringstream oss;
|
||||
oss << locationInfo << ": Internal Catch error: '" << message << "'";
|
||||
if( isTrue( true ))
|
||||
throw std::logic_error( oss.str() );
|
||||
}
|
||||
void throwLogicError( std::string const& message, SourceLineInfo const& locationInfo );
|
||||
}
|
||||
|
||||
#define CATCH_INTERNAL_LINEINFO ::Catch::SourceLineInfo( __FILE__, static_cast<std::size_t>( __LINE__ ) )
|
||||
|
86
include/internal/catch_common.hpp
Normal file
86
include/internal/catch_common.hpp
Normal file
@@ -0,0 +1,86 @@
|
||||
/*
|
||||
* Created by Phil on 27/11/2013.
|
||||
* Copyright 2013 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_COMMON_HPP_INCLUDED
|
||||
#define TWOBLUECUBES_CATCH_COMMON_HPP_INCLUDED
|
||||
|
||||
#include "catch_common.h"
|
||||
|
||||
namespace Catch {
|
||||
|
||||
INTERNAL_CATCH_INLINE bool startsWith( std::string const& s, std::string const& prefix ) {
|
||||
return s.size() >= prefix.size() && s.substr( 0, prefix.size() ) == prefix;
|
||||
}
|
||||
INTERNAL_CATCH_INLINE bool endsWith( std::string const& s, std::string const& suffix ) {
|
||||
return s.size() >= suffix.size() && s.substr( s.size()-suffix.size(), suffix.size() ) == suffix;
|
||||
}
|
||||
INTERNAL_CATCH_INLINE bool contains( std::string const& s, std::string const& infix ) {
|
||||
return s.find( infix ) != std::string::npos;
|
||||
}
|
||||
INTERNAL_CATCH_INLINE void toLowerInPlace( std::string& s ) {
|
||||
std::transform( s.begin(), s.end(), s.begin(), ::tolower );
|
||||
}
|
||||
INTERNAL_CATCH_INLINE std::string toLower( std::string const& s ) {
|
||||
std::string lc = s;
|
||||
toLowerInPlace( lc );
|
||||
return lc;
|
||||
}
|
||||
INTERNAL_CATCH_INLINE std::string trim( std::string const& str ) {
|
||||
static char const* whitespaceChars = "\n\r\t ";
|
||||
std::string::size_type start = str.find_first_not_of( whitespaceChars );
|
||||
std::string::size_type end = str.find_last_not_of( whitespaceChars );
|
||||
|
||||
return start != std::string::npos ? str.substr( start, 1+end-start ) : "";
|
||||
}
|
||||
|
||||
INTERNAL_CATCH_INLINE pluralise::pluralise( std::size_t count, std::string const& label )
|
||||
: m_count( count ),
|
||||
m_label( label )
|
||||
{}
|
||||
|
||||
INTERNAL_CATCH_INLINE std::ostream& operator << ( std::ostream& os, pluralise const& pluraliser ) {
|
||||
os << pluraliser.m_count << " " << pluraliser.m_label;
|
||||
if( pluraliser.m_count != 1 )
|
||||
os << "s";
|
||||
return os;
|
||||
}
|
||||
|
||||
INTERNAL_CATCH_INLINE SourceLineInfo::SourceLineInfo() : line( 0 ){}
|
||||
INTERNAL_CATCH_INLINE SourceLineInfo::SourceLineInfo( char const* _file, std::size_t _line )
|
||||
: file( _file ),
|
||||
line( _line )
|
||||
{}
|
||||
INTERNAL_CATCH_INLINE SourceLineInfo::SourceLineInfo( SourceLineInfo const& other )
|
||||
: file( other.file ),
|
||||
line( other.line )
|
||||
{}
|
||||
INTERNAL_CATCH_INLINE bool SourceLineInfo::empty() const {
|
||||
return file.empty();
|
||||
}
|
||||
INTERNAL_CATCH_INLINE bool SourceLineInfo::operator == ( SourceLineInfo const& other ) const {
|
||||
return line == other.line && file == other.file;
|
||||
}
|
||||
|
||||
INTERNAL_CATCH_INLINE std::ostream& operator << ( std::ostream& os, SourceLineInfo const& info ) {
|
||||
#ifndef __GNUG__
|
||||
os << info.file << "(" << info.line << ")";
|
||||
#else
|
||||
os << info.file << ":" << info.line;
|
||||
#endif
|
||||
return os;
|
||||
}
|
||||
|
||||
INTERNAL_CATCH_INLINE void throwLogicError( std::string const& message, SourceLineInfo const& locationInfo ) {
|
||||
std::ostringstream oss;
|
||||
oss << locationInfo << ": Internal Catch error: '" << message << "'";
|
||||
if( isTrue( true ))
|
||||
throw std::logic_error( oss.str() );
|
||||
}
|
||||
}
|
||||
|
||||
#endif // TWOBLUECUBES_CATCH_COMMON_HPP_INCLUDED
|
||||
|
@@ -11,7 +11,7 @@
|
||||
#include "catch_test_spec.h"
|
||||
#include "catch_context.h"
|
||||
#include "catch_interfaces_config.h"
|
||||
#include "catch_stream.hpp"
|
||||
#include "catch_stream.h"
|
||||
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
@@ -30,6 +30,7 @@ namespace Catch {
|
||||
: listTests( false ),
|
||||
listTags( false ),
|
||||
listReporters( false ),
|
||||
listTestNamesOnly( false ),
|
||||
showSuccessfulTests( false ),
|
||||
shouldDebugBreak( false ),
|
||||
noThrow( false ),
|
||||
@@ -43,6 +44,7 @@ namespace Catch {
|
||||
bool listTests;
|
||||
bool listTags;
|
||||
bool listReporters;
|
||||
bool listTestNamesOnly;
|
||||
|
||||
bool showSuccessfulTests;
|
||||
bool shouldDebugBreak;
|
||||
@@ -112,6 +114,7 @@ namespace Catch {
|
||||
}
|
||||
|
||||
bool listTests() const { return m_data.listTests; }
|
||||
bool listTestNamesOnly() const { return m_data.listTestNamesOnly; }
|
||||
bool listTags() const { return m_data.listTags; }
|
||||
bool listReporters() const { return m_data.listReporters; }
|
||||
|
||||
|
@@ -117,7 +117,7 @@ namespace {
|
||||
};
|
||||
|
||||
inline bool shouldUseColourForPlatform() {
|
||||
return isatty( fileno(stdout) );
|
||||
return isatty(STDOUT_FILENO);
|
||||
}
|
||||
|
||||
PosixColourImpl platformColourImpl;
|
||||
|
49
include/internal/catch_debugger.h
Normal file
49
include/internal/catch_debugger.h
Normal file
@@ -0,0 +1,49 @@
|
||||
/*
|
||||
* Created by Phil on 3/12/2013.
|
||||
* Copyright 2013 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_DEBUGGER_H_INCLUDED
|
||||
#define TWOBLUECUBES_CATCH_DEBUGGER_H_INCLUDED
|
||||
|
||||
#include "catch_platform.h"
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace Catch{
|
||||
|
||||
bool isDebuggerActive();
|
||||
void writeToDebugConsole( std::string const& text );
|
||||
}
|
||||
|
||||
#ifdef CATCH_PLATFORM_MAC
|
||||
|
||||
// The following code snippet based on:
|
||||
// http://cocoawithlove.com/2008/03/break-into-debugger.html
|
||||
#ifdef DEBUG
|
||||
#if defined(__ppc64__) || defined(__ppc__)
|
||||
#define CATCH_BREAK_INTO_DEBUGGER() \
|
||||
if( Catch::isDebuggerActive() ) { \
|
||||
__asm__("li r0, 20\nsc\nnop\nli r0, 37\nli r4, 2\nsc\nnop\n" \
|
||||
: : : "memory","r0","r3","r4" ); \
|
||||
}
|
||||
#else
|
||||
#define CATCH_BREAK_INTO_DEBUGGER() if( Catch::isDebuggerActive() ) {__asm__("int $3\n" : : );}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#elif defined(_MSC_VER)
|
||||
#define CATCH_BREAK_INTO_DEBUGGER() if( Catch::isDebuggerActive() ) { __debugbreak(); }
|
||||
#elif defined(__MINGW32__)
|
||||
extern "C" __declspec(dllimport) void __stdcall DebugBreak();
|
||||
#define CATCH_BREAK_INTO_DEBUGGER() if( Catch::isDebuggerActive() ) { DebugBreak(); }
|
||||
#endif
|
||||
|
||||
#ifndef CATCH_BREAK_INTO_DEBUGGER
|
||||
#define CATCH_BREAK_INTO_DEBUGGER()
|
||||
#endif
|
||||
|
||||
#endif // TWOBLUECUBES_CATCH_DEBUGGER_H_INCLUDED
|
@@ -5,14 +5,13 @@
|
||||
* 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)
|
||||
*
|
||||
* Provides a BreakIntoDebugger() macro for Windows and Mac (so far)
|
||||
*/
|
||||
#ifndef TWOBLUECUBES_CATCH_DEBUGGER_HPP_INCLUDED
|
||||
#define TWOBLUECUBES_CATCH_DEBUGGER_HPP_INCLUDED
|
||||
|
||||
#include <iostream>
|
||||
#include "catch_debugger.h"
|
||||
|
||||
#include "catch_platform.h"
|
||||
#include <iostream>
|
||||
|
||||
#ifdef CATCH_PLATFORM_MAC
|
||||
|
||||
@@ -29,7 +28,7 @@
|
||||
|
||||
// Returns true if the current process is being debugged (either
|
||||
// running under the debugger or has a debugger attached post facto).
|
||||
inline bool isDebuggerActive(){
|
||||
INTERNAL_CATCH_INLINE bool isDebuggerActive(){
|
||||
|
||||
int junk;
|
||||
int mib[4];
|
||||
@@ -59,52 +58,42 @@
|
||||
|
||||
return ( (info.kp_proc.p_flag & P_TRACED) != 0 );
|
||||
}
|
||||
}
|
||||
|
||||
// The following code snippet taken from:
|
||||
// http://cocoawithlove.com/2008/03/break-into-debugger.html
|
||||
#ifdef DEBUG
|
||||
#if defined(__ppc64__) || defined(__ppc__)
|
||||
#define BreakIntoDebugger() \
|
||||
if( Catch::isDebuggerActive() ) { \
|
||||
__asm__("li r0, 20\nsc\nnop\nli r0, 37\nli r4, 2\nsc\nnop\n" \
|
||||
: : : "memory","r0","r3","r4" ); \
|
||||
}
|
||||
#else
|
||||
#define BreakIntoDebugger() if( Catch::isDebuggerActive() ) {__asm__("int $3\n" : : );}
|
||||
#endif
|
||||
#else
|
||||
inline void BreakIntoDebugger(){}
|
||||
#endif
|
||||
} // namespace Catch
|
||||
|
||||
#elif defined(_MSC_VER)
|
||||
extern "C" __declspec(dllimport) int __stdcall IsDebuggerPresent();
|
||||
#define BreakIntoDebugger() if (IsDebuggerPresent() ) { __debugbreak(); }
|
||||
inline bool isDebuggerActive() {
|
||||
return IsDebuggerPresent() != 0;
|
||||
namespace Catch {
|
||||
INTERNAL_CATCH_INLINE bool isDebuggerActive() {
|
||||
return IsDebuggerPresent() != 0;
|
||||
}
|
||||
}
|
||||
#elif defined(__MINGW32__)
|
||||
extern "C" __declspec(dllimport) int __stdcall IsDebuggerPresent();
|
||||
extern "C" __declspec(dllimport) void __stdcall DebugBreak();
|
||||
#define BreakIntoDebugger() if (IsDebuggerPresent() ) { DebugBreak(); }
|
||||
inline bool isDebuggerActive() {
|
||||
return IsDebuggerPresent() != 0;
|
||||
namespace Catch {
|
||||
INTERNAL_CATCH_INLINE bool isDebuggerActive() {
|
||||
return IsDebuggerPresent() != 0;
|
||||
}
|
||||
}
|
||||
#else
|
||||
inline void BreakIntoDebugger(){}
|
||||
namespace Catch {
|
||||
inline bool isDebuggerActive() { return false; }
|
||||
#endif
|
||||
}
|
||||
#endif // Platform
|
||||
|
||||
#ifdef CATCH_PLATFORM_WINDOWS
|
||||
extern "C" __declspec(dllimport) void __stdcall OutputDebugStringA( const char* );
|
||||
inline void writeToDebugConsole( std::string const& text ) {
|
||||
::OutputDebugStringA( text.c_str() );
|
||||
}
|
||||
extern "C" __declspec(dllimport) void __stdcall OutputDebugStringA( const char* );
|
||||
namespace Catch {
|
||||
INTERNAL_CATCH_INLINE void writeToDebugConsole( std::string const& text ) {
|
||||
::OutputDebugStringA( text.c_str() );
|
||||
}
|
||||
}
|
||||
#else
|
||||
inline void writeToDebugConsole( std::string const& text ) {
|
||||
// !TBD: Need a version for Mac/ XCode and other IDEs
|
||||
std::cout << text;
|
||||
}
|
||||
#endif // CATCH_PLATFORM_WINDOWS
|
||||
namespace Catch {
|
||||
INTERNAL_CATCH_INLINE void writeToDebugConsole( std::string const& text ) {
|
||||
// !TBD: Need a version for Mac/ XCode and other IDEs
|
||||
std::cout << text;
|
||||
}
|
||||
}
|
||||
#endif // Platform
|
||||
|
||||
#endif // TWOBLUECUBES_CATCH_DEBUGGER_HPP_INCLUDED
|
||||
|
@@ -26,11 +26,15 @@
|
||||
#include "catch_expressionresult_builder.hpp"
|
||||
#include "catch_test_case_info.hpp"
|
||||
#include "catch_tags.hpp"
|
||||
#include "catch_test_spec.hpp"
|
||||
#include "catch_version.hpp"
|
||||
#include "catch_text.hpp"
|
||||
#include "catch_message.hpp"
|
||||
#include "catch_legacy_reporter_adapter.hpp"
|
||||
#include "catch_timer.hpp"
|
||||
#include "catch_common.hpp"
|
||||
#include "catch_section.hpp"
|
||||
#include "catch_debugger.hpp"
|
||||
|
||||
#include "../reporters/catch_reporter_xml.hpp"
|
||||
#include "../reporters/catch_reporter_junit.hpp"
|
||||
@@ -71,9 +75,6 @@ namespace Catch {
|
||||
FreeFunctionTestCase::~FreeFunctionTestCase() {}
|
||||
IGeneratorInfo::~IGeneratorInfo() {}
|
||||
IGeneratorsForTest::~IGeneratorsForTest() {}
|
||||
TagParser::~TagParser() {}
|
||||
TagExtracter::~TagExtracter() {}
|
||||
TagExpressionParser::~TagExpressionParser() {}
|
||||
|
||||
Matchers::Impl::StdString::Equals::~Equals() {}
|
||||
Matchers::Impl::StdString::Contains::~Contains() {}
|
||||
|
@@ -10,7 +10,6 @@
|
||||
|
||||
#include <string>
|
||||
#include "catch_result_type.h"
|
||||
#include "catch_totals.hpp"
|
||||
#include "catch_common.h"
|
||||
|
||||
namespace Catch {
|
||||
@@ -22,6 +21,7 @@ namespace Catch {
|
||||
struct SectionInfo;
|
||||
struct MessageInfo;
|
||||
class ScopedMessageBuilder;
|
||||
struct Counts;
|
||||
|
||||
struct IResultCapture {
|
||||
|
||||
|
@@ -8,10 +8,7 @@
|
||||
#ifndef TWOBLUECUBES_CATCH_INTERFACES_REGISTRY_HUB_H_INCLUDED
|
||||
#define TWOBLUECUBES_CATCH_INTERFACES_REGISTRY_HUB_H_INCLUDED
|
||||
|
||||
#include "catch_interfaces_reporter.h"
|
||||
#include "catch_interfaces_config.h"
|
||||
|
||||
#include <vector>
|
||||
#include <string>
|
||||
|
||||
namespace Catch {
|
||||
|
||||
@@ -19,6 +16,8 @@ namespace Catch {
|
||||
struct ITestCaseRegistry;
|
||||
struct IExceptionTranslatorRegistry;
|
||||
struct IExceptionTranslator;
|
||||
struct IReporterRegistry;
|
||||
struct IReporterFactory;
|
||||
|
||||
struct IRegistryHub {
|
||||
virtual ~IRegistryHub();
|
||||
|
@@ -8,6 +8,7 @@
|
||||
#ifndef TWOBLUECUBES_CATCH_INTERFACES_REPORTER_H_INCLUDED
|
||||
#define TWOBLUECUBES_CATCH_INTERFACES_REPORTER_H_INCLUDED
|
||||
|
||||
#include "catch_section_info.h"
|
||||
#include "catch_common.h"
|
||||
#include "catch_totals.hpp"
|
||||
#include "catch_ptr.hpp"
|
||||
@@ -80,20 +81,6 @@ namespace Catch
|
||||
std::size_t groupsCounts;
|
||||
};
|
||||
|
||||
struct SectionInfo {
|
||||
SectionInfo( std::string const& _name,
|
||||
std::string const& _description,
|
||||
SourceLineInfo const& _lineInfo )
|
||||
: name( _name ),
|
||||
description( _description ),
|
||||
lineInfo( _lineInfo )
|
||||
{}
|
||||
|
||||
std::string name;
|
||||
std::string description;
|
||||
SourceLineInfo lineInfo;
|
||||
};
|
||||
|
||||
struct AssertionStats {
|
||||
AssertionStats( AssertionResult const& _assertionResult,
|
||||
std::vector<MessageInfo> const& _infoMessages,
|
||||
@@ -223,201 +210,6 @@ namespace Catch
|
||||
virtual void testRunEnded( TestRunStats const& testRunStats ) = 0;
|
||||
};
|
||||
|
||||
struct StreamingReporterBase : SharedImpl<IStreamingReporter> {
|
||||
|
||||
StreamingReporterBase( ReporterConfig const& _config )
|
||||
: m_config( _config.fullConfig() ),
|
||||
stream( _config.stream() )
|
||||
{}
|
||||
|
||||
virtual ~StreamingReporterBase();
|
||||
|
||||
virtual void noMatchingTestCases( std::string const& ) {}
|
||||
|
||||
virtual void testRunStarting( TestRunInfo const& _testRunInfo ) {
|
||||
currentTestRunInfo = _testRunInfo;
|
||||
}
|
||||
virtual void testGroupStarting( GroupInfo const& _groupInfo ) {
|
||||
currentGroupInfo = _groupInfo;
|
||||
}
|
||||
|
||||
virtual void testCaseStarting( TestCaseInfo const& _testInfo ) {
|
||||
currentTestCaseInfo = _testInfo;
|
||||
}
|
||||
virtual void sectionStarting( SectionInfo const& _sectionInfo ) {
|
||||
m_sectionStack.push_back( _sectionInfo );
|
||||
}
|
||||
|
||||
virtual void sectionEnded( SectionStats const& /* _sectionStats */ ) {
|
||||
m_sectionStack.pop_back();
|
||||
}
|
||||
virtual void testCaseEnded( TestCaseStats const& /* _testCaseStats */ ) {
|
||||
currentTestCaseInfo.reset();
|
||||
assert( m_sectionStack.empty() );
|
||||
}
|
||||
virtual void testGroupEnded( TestGroupStats const& /* _testGroupStats */ ) {
|
||||
currentGroupInfo.reset();
|
||||
}
|
||||
virtual void testRunEnded( TestRunStats const& /* _testRunStats */ ) {
|
||||
currentTestCaseInfo.reset();
|
||||
currentGroupInfo.reset();
|
||||
currentTestRunInfo.reset();
|
||||
}
|
||||
|
||||
Ptr<IConfig> m_config;
|
||||
std::ostream& stream;
|
||||
|
||||
LazyStat<TestRunInfo> currentTestRunInfo;
|
||||
LazyStat<GroupInfo> currentGroupInfo;
|
||||
LazyStat<TestCaseInfo> currentTestCaseInfo;
|
||||
|
||||
std::vector<SectionInfo> m_sectionStack;
|
||||
};
|
||||
|
||||
struct CumulativeReporterBase : SharedImpl<IStreamingReporter> {
|
||||
template<typename T, typename ChildNodeT>
|
||||
struct Node : SharedImpl<> {
|
||||
explicit Node( T const& _value ) : value( _value ) {}
|
||||
virtual ~Node() {}
|
||||
|
||||
typedef std::vector<Ptr<ChildNodeT> > ChildNodes;
|
||||
T value;
|
||||
ChildNodes children;
|
||||
};
|
||||
struct SectionNode : SharedImpl<> {
|
||||
explicit SectionNode( SectionStats const& _stats ) : stats( _stats ) {}
|
||||
virtual ~SectionNode();
|
||||
|
||||
bool operator == ( SectionNode const& other ) const {
|
||||
return stats.sectionInfo.lineInfo == other.stats.sectionInfo.lineInfo;
|
||||
}
|
||||
bool operator == ( Ptr<SectionNode> const& other ) const {
|
||||
return operator==( *other );
|
||||
}
|
||||
|
||||
SectionStats stats;
|
||||
typedef std::vector<Ptr<SectionNode> > ChildSections;
|
||||
typedef std::vector<AssertionStats> Assertions;
|
||||
ChildSections childSections;
|
||||
Assertions assertions;
|
||||
std::string stdOut;
|
||||
std::string stdErr;
|
||||
};
|
||||
friend bool operator == ( Ptr<SectionNode> const& node, SectionInfo const& other ) {
|
||||
return node->stats.sectionInfo.lineInfo == other.lineInfo;
|
||||
}
|
||||
|
||||
typedef Node<TestCaseStats, SectionNode> TestCaseNode;
|
||||
typedef Node<TestGroupStats, TestCaseNode> TestGroupNode;
|
||||
typedef Node<TestRunStats, TestGroupNode> TestRunNode;
|
||||
|
||||
CumulativeReporterBase( ReporterConfig const& _config )
|
||||
: m_config( _config.fullConfig() ),
|
||||
stream( _config.stream() )
|
||||
{}
|
||||
~CumulativeReporterBase();
|
||||
|
||||
virtual void testRunStarting( TestRunInfo const& ) {}
|
||||
virtual void testGroupStarting( GroupInfo const& ) {}
|
||||
|
||||
virtual void testCaseStarting( TestCaseInfo const& ) {}
|
||||
|
||||
virtual void sectionStarting( SectionInfo const& sectionInfo ) {
|
||||
SectionStats incompleteStats( sectionInfo, Counts(), 0, false );
|
||||
Ptr<SectionNode> node;
|
||||
if( m_sectionStack.empty() ) {
|
||||
if( !m_rootSection )
|
||||
m_rootSection = new SectionNode( incompleteStats );
|
||||
node = m_rootSection;
|
||||
}
|
||||
else {
|
||||
SectionNode& parentNode = *m_sectionStack.back();
|
||||
SectionNode::ChildSections::const_iterator it =
|
||||
std::find( parentNode.childSections.begin(), parentNode.childSections.end(), sectionInfo );
|
||||
if( it == parentNode.childSections.end() ) {
|
||||
node = new SectionNode( incompleteStats );
|
||||
parentNode.childSections.push_back( node );
|
||||
}
|
||||
else
|
||||
node = *it;
|
||||
}
|
||||
m_sectionStack.push_back( node );
|
||||
m_deepestSection = node;
|
||||
}
|
||||
|
||||
virtual void assertionStarting( AssertionInfo const& ) {}
|
||||
|
||||
virtual bool assertionEnded( AssertionStats const& assertionStats ) {
|
||||
assert( !m_sectionStack.empty() );
|
||||
SectionNode& sectionNode = *m_sectionStack.back();
|
||||
sectionNode.assertions.push_back( assertionStats );
|
||||
return true;
|
||||
}
|
||||
virtual void sectionEnded( SectionStats const& sectionStats ) {
|
||||
assert( !m_sectionStack.empty() );
|
||||
SectionNode& node = *m_sectionStack.back();
|
||||
node.stats = sectionStats;
|
||||
m_sectionStack.pop_back();
|
||||
}
|
||||
virtual void testCaseEnded( TestCaseStats const& testCaseStats ) {
|
||||
Ptr<TestCaseNode> node = new TestCaseNode( testCaseStats );
|
||||
assert( m_sectionStack.size() == 0 );
|
||||
node->children.push_back( m_rootSection );
|
||||
m_testCases.push_back( node );
|
||||
m_rootSection.reset();
|
||||
|
||||
assert( m_deepestSection );
|
||||
m_deepestSection->stdOut = testCaseStats.stdOut;
|
||||
m_deepestSection->stdErr = testCaseStats.stdErr;
|
||||
}
|
||||
virtual void testGroupEnded( TestGroupStats const& testGroupStats ) {
|
||||
Ptr<TestGroupNode> node = new TestGroupNode( testGroupStats );
|
||||
node->children.swap( m_testCases );
|
||||
m_testGroups.push_back( node );
|
||||
}
|
||||
virtual void testRunEnded( TestRunStats const& testRunStats ) {
|
||||
Ptr<TestRunNode> node = new TestRunNode( testRunStats );
|
||||
node->children.swap( m_testGroups );
|
||||
m_testRuns.push_back( node );
|
||||
testRunEnded();
|
||||
}
|
||||
virtual void testRunEnded() = 0;
|
||||
|
||||
Ptr<IConfig> m_config;
|
||||
std::ostream& stream;
|
||||
std::vector<AssertionStats> m_assertions;
|
||||
std::vector<std::vector<Ptr<SectionNode> > > m_sections;
|
||||
std::vector<Ptr<TestCaseNode> > m_testCases;
|
||||
std::vector<Ptr<TestGroupNode> > m_testGroups;
|
||||
|
||||
std::vector<Ptr<TestRunNode> > m_testRuns;
|
||||
|
||||
Ptr<SectionNode> m_rootSection;
|
||||
Ptr<SectionNode> m_deepestSection;
|
||||
std::vector<Ptr<SectionNode> > m_sectionStack;
|
||||
|
||||
};
|
||||
|
||||
// Deprecated
|
||||
struct IReporter : IShared {
|
||||
virtual ~IReporter();
|
||||
|
||||
virtual bool shouldRedirectStdout() const = 0;
|
||||
|
||||
virtual void StartTesting() = 0;
|
||||
virtual void EndTesting( Totals const& totals ) = 0;
|
||||
virtual void StartGroup( std::string const& groupName ) = 0;
|
||||
virtual void EndGroup( std::string const& groupName, Totals const& totals ) = 0;
|
||||
virtual void StartTestCase( TestCaseInfo const& testInfo ) = 0;
|
||||
virtual void EndTestCase( TestCaseInfo const& testInfo, Totals const& totals, std::string const& stdOut, std::string const& stdErr ) = 0;
|
||||
virtual void StartSection( std::string const& sectionName, std::string const& description ) = 0;
|
||||
virtual void EndSection( std::string const& sectionName, Counts const& assertions ) = 0;
|
||||
virtual void NoAssertionsInSection( std::string const& sectionName ) = 0;
|
||||
virtual void NoAssertionsInTestCase( std::string const& testName ) = 0;
|
||||
virtual void Aborted() = 0;
|
||||
virtual void Result( AssertionResult const& result ) = 0;
|
||||
};
|
||||
|
||||
|
||||
struct IReporterFactory {
|
||||
virtual ~IReporterFactory();
|
||||
@@ -433,13 +225,6 @@ namespace Catch
|
||||
virtual FactoryMap const& getFactories() const = 0;
|
||||
};
|
||||
|
||||
inline std::string trim( std::string const& str ) {
|
||||
static char const* whitespaceChars = "\n\r\t ";
|
||||
std::string::size_type start = str.find_first_not_of( whitespaceChars );
|
||||
std::string::size_type end = str.find_last_not_of( whitespaceChars );
|
||||
|
||||
return start != std::string::npos ? str.substr( start, 1+end-start ) : "";
|
||||
}
|
||||
}
|
||||
|
||||
#endif // TWOBLUECUBES_CATCH_INTERFACES_REPORTER_H_INCLUDED
|
||||
|
@@ -8,10 +8,6 @@
|
||||
#ifndef TWOBLUECUBES_CATCH_INTERFACES_RUNNER_H_INCLUDED
|
||||
#define TWOBLUECUBES_CATCH_INTERFACES_RUNNER_H_INCLUDED
|
||||
|
||||
#include "catch_totals.hpp"
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace Catch {
|
||||
class TestCase;
|
||||
|
||||
|
@@ -12,6 +12,26 @@
|
||||
|
||||
namespace Catch
|
||||
{
|
||||
// Deprecated
|
||||
struct IReporter : IShared {
|
||||
virtual ~IReporter();
|
||||
|
||||
virtual bool shouldRedirectStdout() const = 0;
|
||||
|
||||
virtual void StartTesting() = 0;
|
||||
virtual void EndTesting( Totals const& totals ) = 0;
|
||||
virtual void StartGroup( std::string const& groupName ) = 0;
|
||||
virtual void EndGroup( std::string const& groupName, Totals const& totals ) = 0;
|
||||
virtual void StartTestCase( TestCaseInfo const& testInfo ) = 0;
|
||||
virtual void EndTestCase( TestCaseInfo const& testInfo, Totals const& totals, std::string const& stdOut, std::string const& stdErr ) = 0;
|
||||
virtual void StartSection( std::string const& sectionName, std::string const& description ) = 0;
|
||||
virtual void EndSection( std::string const& sectionName, Counts const& assertions ) = 0;
|
||||
virtual void NoAssertionsInSection( std::string const& sectionName ) = 0;
|
||||
virtual void NoAssertionsInTestCase( std::string const& testName ) = 0;
|
||||
virtual void Aborted() = 0;
|
||||
virtual void Result( AssertionResult const& result ) = 0;
|
||||
};
|
||||
|
||||
class LegacyReporterAdapter : public SharedImpl<IStreamingReporter>
|
||||
{
|
||||
public:
|
||||
|
@@ -11,6 +11,7 @@
|
||||
#include "catch_commandline.hpp"
|
||||
#include "catch_text.h"
|
||||
#include "catch_console_colour.hpp"
|
||||
#include "catch_interfaces_reporter.h"
|
||||
|
||||
#include <limits>
|
||||
#include <algorithm>
|
||||
@@ -60,6 +61,20 @@ namespace Catch {
|
||||
return matchedTests;
|
||||
}
|
||||
|
||||
inline std::size_t listTestsNamesOnly( Config const& config ) {
|
||||
std::size_t matchedTests = 0;
|
||||
std::vector<TestCase> const& allTests = getRegistryHub().getTestCaseRegistry().getAllTests();
|
||||
for( std::vector<TestCase>::const_iterator it = allTests.begin(), itEnd = allTests.end();
|
||||
it != itEnd;
|
||||
++it )
|
||||
if( matchesFilters( config.filters(), *it ) ) {
|
||||
matchedTests++;
|
||||
TestCaseInfo const& testCaseInfo = it->getTestCaseInfo();
|
||||
std::cout << testCaseInfo.name << std::endl;
|
||||
}
|
||||
return matchedTests;
|
||||
}
|
||||
|
||||
inline std::size_t listTags( Config const& config ) {
|
||||
if( config.filters().empty() )
|
||||
std::cout << "All available tags:\n";
|
||||
@@ -131,6 +146,8 @@ namespace Catch {
|
||||
Option<std::size_t> listedCount;
|
||||
if( config.listTests() )
|
||||
listedCount = listedCount.valueOr(0) + listTests( config );
|
||||
if( config.listTestNamesOnly() )
|
||||
listedCount = listedCount.valueOr(0) + listTestsNamesOnly( config );
|
||||
if( config.listTags() )
|
||||
listedCount = listedCount.valueOr(0) + listTags( config );
|
||||
if( config.listReporters() )
|
||||
|
@@ -56,9 +56,6 @@ namespace Catch {
|
||||
|
||||
namespace Detail{
|
||||
|
||||
inline bool startsWith( std::string const& str, std::string const& sub ) {
|
||||
return str.length() > sub.length() && str.substr( 0, sub.length() ) == sub;
|
||||
}
|
||||
|
||||
inline std::string getAnnotation( Class cls,
|
||||
std::string const& annotationName,
|
||||
@@ -88,7 +85,7 @@ namespace Catch {
|
||||
for( u_int m = 0; m < count ; m++ ) {
|
||||
SEL selector = method_getName(methods[m]);
|
||||
std::string methodName = sel_getName(selector);
|
||||
if( Detail::startsWith( methodName, "Catch_TestCase_" ) ) {
|
||||
if( startsWith( methodName, "Catch_TestCase_" ) ) {
|
||||
std::string testCaseName = methodName.substr( 15 );
|
||||
std::string name = Detail::getAnnotation( cls, "Name", testCaseName );
|
||||
std::string desc = Detail::getAnnotation( cls, "Description", testCaseName );
|
||||
|
49
include/internal/catch_section.h
Normal file
49
include/internal/catch_section.h
Normal file
@@ -0,0 +1,49 @@
|
||||
/*
|
||||
* Created by Phil on 03/12/2013.
|
||||
* Copyright 2013 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_SECTION_H_INCLUDED
|
||||
#define TWOBLUECUBES_CATCH_SECTION_H_INCLUDED
|
||||
|
||||
#include "catch_section_info.h"
|
||||
#include "catch_totals.hpp"
|
||||
#include "catch_timer.h"
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace Catch {
|
||||
|
||||
class Section {
|
||||
public:
|
||||
Section( SourceLineInfo const& lineInfo,
|
||||
std::string const& name,
|
||||
std::string const& description = "" );
|
||||
~Section();
|
||||
|
||||
// This indicates whether the section should be executed or not
|
||||
operator bool();
|
||||
|
||||
private:
|
||||
|
||||
SectionInfo m_info;
|
||||
|
||||
std::string m_name;
|
||||
Counts m_assertions;
|
||||
bool m_sectionIncluded;
|
||||
Timer m_timer;
|
||||
};
|
||||
|
||||
} // end namespace Catch
|
||||
|
||||
#ifdef CATCH_CONFIG_VARIADIC_MACROS
|
||||
#define INTERNAL_CATCH_SECTION( ... ) \
|
||||
if( Catch::Section INTERNAL_CATCH_UNIQUE_NAME( catch_internal_Section ) = Catch::Section( CATCH_INTERNAL_LINEINFO, __VA_ARGS__ ) )
|
||||
#else
|
||||
#define INTERNAL_CATCH_SECTION( name, desc ) \
|
||||
if( Catch::Section INTERNAL_CATCH_UNIQUE_NAME( catch_internal_Section ) = Catch::Section( CATCH_INTERNAL_LINEINFO, name, desc ) )
|
||||
#endif
|
||||
|
||||
#endif // TWOBLUECUBES_CATCH_SECTION_H_INCLUDED
|
@@ -8,53 +8,33 @@
|
||||
#ifndef TWOBLUECUBES_CATCH_SECTION_HPP_INCLUDED
|
||||
#define TWOBLUECUBES_CATCH_SECTION_HPP_INCLUDED
|
||||
|
||||
#include "catch_section.h"
|
||||
#include "catch_capture.hpp"
|
||||
#include "catch_totals.hpp"
|
||||
#include "catch_compiler_capabilities.h"
|
||||
#include "catch_timer.h"
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace Catch {
|
||||
|
||||
class Section {
|
||||
public:
|
||||
Section( SourceLineInfo const& lineInfo,
|
||||
std::string const& name,
|
||||
std::string const& description = "" )
|
||||
: m_info( name, description, lineInfo ),
|
||||
m_sectionIncluded( getCurrentContext().getResultCapture().sectionStarted( m_info, m_assertions ) )
|
||||
{
|
||||
m_timer.start();
|
||||
}
|
||||
INTERNAL_CATCH_INLINE Section::Section( SourceLineInfo const& lineInfo,
|
||||
std::string const& name,
|
||||
std::string const& description )
|
||||
: m_info( name, description, lineInfo ),
|
||||
m_sectionIncluded( getCurrentContext().getResultCapture().sectionStarted( m_info, m_assertions ) )
|
||||
{
|
||||
m_timer.start();
|
||||
}
|
||||
|
||||
~Section() {
|
||||
if( m_sectionIncluded )
|
||||
getCurrentContext().getResultCapture().sectionEnded( m_info, m_assertions, m_timer.getElapsedSeconds() );
|
||||
}
|
||||
INTERNAL_CATCH_INLINE Section::~Section() {
|
||||
if( m_sectionIncluded )
|
||||
getCurrentContext().getResultCapture().sectionEnded( m_info, m_assertions, m_timer.getElapsedSeconds() );
|
||||
}
|
||||
|
||||
// This indicates whether the section should be executed or not
|
||||
operator bool() {
|
||||
return m_sectionIncluded;
|
||||
}
|
||||
// This indicates whether the section should be executed or not
|
||||
INTERNAL_CATCH_INLINE Section::operator bool() {
|
||||
return m_sectionIncluded;
|
||||
}
|
||||
|
||||
private:
|
||||
SectionInfo m_info;
|
||||
|
||||
std::string m_name;
|
||||
Counts m_assertions;
|
||||
bool m_sectionIncluded;
|
||||
Timer m_timer;
|
||||
};
|
||||
|
||||
} // end namespace Catch
|
||||
|
||||
#ifdef CATCH_CONFIG_VARIADIC_MACROS
|
||||
#define INTERNAL_CATCH_SECTION( ... ) \
|
||||
if( Catch::Section INTERNAL_CATCH_UNIQUE_NAME( catch_internal_Section ) = Catch::Section( CATCH_INTERNAL_LINEINFO, __VA_ARGS__ ) )
|
||||
#else
|
||||
#define INTERNAL_CATCH_SECTION( name, desc ) \
|
||||
if( Catch::Section INTERNAL_CATCH_UNIQUE_NAME( catch_internal_Section ) = Catch::Section( CATCH_INTERNAL_LINEINFO, name, desc ) )
|
||||
#endif
|
||||
|
||||
#endif // TWOBLUECUBES_CATCH_SECTION_HPP_INCLUDED
|
||||
|
31
include/internal/catch_section_info.h
Normal file
31
include/internal/catch_section_info.h
Normal file
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
* Created by Phil on 03/11/2010.
|
||||
* Copyright 2010 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_SECTION_INFO_H_INCLUDED
|
||||
#define TWOBLUECUBES_CATCH_SECTION_INFO_H_INCLUDED
|
||||
|
||||
#include "catch_common.h"
|
||||
|
||||
namespace Catch {
|
||||
|
||||
struct SectionInfo {
|
||||
SectionInfo( std::string const& _name,
|
||||
std::string const& _description,
|
||||
SourceLineInfo const& _lineInfo )
|
||||
: name( _name ),
|
||||
description( _description ),
|
||||
lineInfo( _lineInfo )
|
||||
{}
|
||||
|
||||
std::string name;
|
||||
std::string description;
|
||||
SourceLineInfo lineInfo;
|
||||
};
|
||||
|
||||
} // end namespace Catch
|
||||
|
||||
#endif // TWOBLUECUBES_CATCH_SECTION_INFO_H_INCLUDED
|
33
include/internal/catch_stream.h
Normal file
33
include/internal/catch_stream.h
Normal file
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
* Created by Phil on 2/12/2013.
|
||||
* Copyright 2013 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_H_INCLUDED
|
||||
#define TWOBLUECUBES_CATCH_STREAM_H_INCLUDED
|
||||
|
||||
#include <streambuf>
|
||||
|
||||
#ifdef __clang__
|
||||
#pragma clang diagnostic ignored "-Wpadded"
|
||||
#endif
|
||||
|
||||
namespace Catch {
|
||||
|
||||
class Stream {
|
||||
public:
|
||||
Stream();
|
||||
Stream( std::streambuf* _streamBuf, bool _isOwned );
|
||||
void release();
|
||||
|
||||
std::streambuf* streamBuf;
|
||||
|
||||
private:
|
||||
bool isOwned;
|
||||
};
|
||||
}
|
||||
|
||||
#endif // TWOBLUECUBES_CATCH_STREAM_H_INCLUDED
|
@@ -9,8 +9,9 @@
|
||||
#ifndef TWOBLUECUBES_CATCH_STREAM_HPP_INCLUDED
|
||||
#define TWOBLUECUBES_CATCH_STREAM_HPP_INCLUDED
|
||||
|
||||
#include "catch_stream.h"
|
||||
#include "catch_streambuf.h"
|
||||
#include "catch_debugger.hpp"
|
||||
#include "catch_debugger.h"
|
||||
|
||||
#include <stdexcept>
|
||||
#include <cstdio>
|
||||
@@ -62,29 +63,21 @@ namespace Catch {
|
||||
}
|
||||
};
|
||||
|
||||
class Stream {
|
||||
public:
|
||||
Stream()
|
||||
: streamBuf( NULL ), isOwned( false )
|
||||
{}
|
||||
INTERNAL_CATCH_INLINE Stream::Stream()
|
||||
: streamBuf( NULL ), isOwned( false )
|
||||
{}
|
||||
|
||||
Stream( std::streambuf* _streamBuf, bool _isOwned )
|
||||
: streamBuf( _streamBuf ), isOwned( _isOwned )
|
||||
{}
|
||||
INTERNAL_CATCH_INLINE Stream::Stream( std::streambuf* _streamBuf, bool _isOwned )
|
||||
: streamBuf( _streamBuf ), isOwned( _isOwned )
|
||||
{}
|
||||
|
||||
void release() {
|
||||
if( isOwned ) {
|
||||
delete streamBuf;
|
||||
streamBuf = NULL;
|
||||
isOwned = false;
|
||||
}
|
||||
INTERNAL_CATCH_INLINE void Stream::release() {
|
||||
if( isOwned ) {
|
||||
delete streamBuf;
|
||||
streamBuf = NULL;
|
||||
isOwned = false;
|
||||
}
|
||||
|
||||
std::streambuf* streamBuf;
|
||||
|
||||
private:
|
||||
bool isOwned;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
#endif // TWOBLUECUBES_CATCH_STREAM_HPP_INCLUDED
|
||||
|
109
include/internal/catch_tags.h
Normal file
109
include/internal/catch_tags.h
Normal file
@@ -0,0 +1,109 @@
|
||||
/*
|
||||
* Created by Phil on 2/12/2013.
|
||||
* Copyright 2013 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_TAGS_H_INCLUDED
|
||||
#define TWOBLUECUBES_CATCH_TAGS_H_INCLUDED
|
||||
|
||||
#include "catch_common.h"
|
||||
|
||||
#include <string>
|
||||
#include <set>
|
||||
#include <map>
|
||||
#include <vector>
|
||||
|
||||
#ifdef __clang__
|
||||
#pragma clang diagnostic ignored "-Wpadded"
|
||||
#endif
|
||||
|
||||
namespace Catch {
|
||||
class TagParser {
|
||||
public:
|
||||
virtual ~TagParser();
|
||||
|
||||
void parse( std::string const& str );
|
||||
|
||||
protected:
|
||||
virtual void acceptTag( std::string const& tag ) = 0;
|
||||
virtual void acceptChar( char c ) = 0;
|
||||
virtual void endParse() {}
|
||||
|
||||
private:
|
||||
};
|
||||
|
||||
class TagExtracter : public TagParser {
|
||||
public:
|
||||
|
||||
TagExtracter( std::set<std::string>& tags );
|
||||
virtual ~TagExtracter();
|
||||
|
||||
void parse( std::string& description );
|
||||
|
||||
private:
|
||||
virtual void acceptTag( std::string const& tag );
|
||||
virtual void acceptChar( char c );
|
||||
|
||||
TagExtracter& operator=(TagExtracter const&);
|
||||
|
||||
std::set<std::string>& m_tags;
|
||||
std::string m_remainder;
|
||||
};
|
||||
|
||||
class Tag {
|
||||
public:
|
||||
Tag();
|
||||
Tag( std::string const& name, bool isNegated );
|
||||
std::string getName() const;
|
||||
bool isNegated() const;
|
||||
bool operator ! () const;
|
||||
|
||||
private:
|
||||
std::string m_name;
|
||||
bool m_isNegated;
|
||||
};
|
||||
|
||||
class TagSet {
|
||||
typedef std::map<std::string, Tag> TagMap;
|
||||
public:
|
||||
void add( Tag const& tag );
|
||||
bool empty() const;
|
||||
bool matches( std::set<std::string> const& tags ) const;
|
||||
|
||||
private:
|
||||
TagMap m_tags;
|
||||
};
|
||||
|
||||
|
||||
class TagExpression {
|
||||
public:
|
||||
bool matches( std::set<std::string> const& tags ) const;
|
||||
|
||||
private:
|
||||
friend class TagExpressionParser;
|
||||
|
||||
std::vector<TagSet> m_tagSets;
|
||||
};
|
||||
|
||||
class TagExpressionParser : public TagParser {
|
||||
public:
|
||||
TagExpressionParser( TagExpression& exp );
|
||||
~TagExpressionParser();
|
||||
|
||||
private:
|
||||
virtual void acceptTag( std::string const& tag );
|
||||
virtual void acceptChar( char c );
|
||||
virtual void endParse();
|
||||
|
||||
TagExpressionParser& operator=(TagExpressionParser const&);
|
||||
|
||||
bool m_isNegated;
|
||||
TagSet m_currentTagSet;
|
||||
TagExpression& m_exp;
|
||||
};
|
||||
|
||||
} // end namespace Catch
|
||||
|
||||
#endif // TWOBLUECUBES_CATCH_TAGS_HPP_INCLUDED
|
@@ -8,188 +8,129 @@
|
||||
#ifndef TWOBLUECUBES_CATCH_TAGS_HPP_INCLUDED
|
||||
#define TWOBLUECUBES_CATCH_TAGS_HPP_INCLUDED
|
||||
|
||||
#include "catch_common.h"
|
||||
|
||||
#include <string>
|
||||
#include <set>
|
||||
#include <map>
|
||||
#include <vector>
|
||||
|
||||
#ifdef __clang__
|
||||
#pragma clang diagnostic ignored "-Wpadded"
|
||||
#endif
|
||||
#include "catch_tags.h"
|
||||
|
||||
namespace Catch {
|
||||
class TagParser {
|
||||
public:
|
||||
virtual ~TagParser();
|
||||
INTERNAL_CATCH_INLINE TagParser::~TagParser() {}
|
||||
|
||||
void parse( std::string const& str ) {
|
||||
std::size_t pos = 0;
|
||||
while( pos < str.size() ) {
|
||||
char c = str[pos];
|
||||
if( c == '[' ) {
|
||||
std::size_t end = str.find_first_of( ']', pos );
|
||||
if( end != std::string::npos ) {
|
||||
acceptTag( str.substr( pos+1, end-pos-1 ) );
|
||||
pos = end+1;
|
||||
}
|
||||
else {
|
||||
acceptChar( c );
|
||||
pos++;
|
||||
}
|
||||
INTERNAL_CATCH_INLINE void TagParser::parse( std::string const& str ) {
|
||||
std::size_t pos = 0;
|
||||
while( pos < str.size() ) {
|
||||
char c = str[pos];
|
||||
if( c == '[' ) {
|
||||
std::size_t end = str.find_first_of( ']', pos );
|
||||
if( end != std::string::npos ) {
|
||||
acceptTag( str.substr( pos+1, end-pos-1 ) );
|
||||
pos = end+1;
|
||||
}
|
||||
else {
|
||||
acceptChar( c );
|
||||
pos++;
|
||||
}
|
||||
}
|
||||
endParse();
|
||||
}
|
||||
|
||||
protected:
|
||||
virtual void acceptTag( std::string const& tag ) = 0;
|
||||
virtual void acceptChar( char c ) = 0;
|
||||
virtual void endParse() {}
|
||||
|
||||
private:
|
||||
};
|
||||
|
||||
class TagExtracter : public TagParser {
|
||||
public:
|
||||
|
||||
TagExtracter( std::set<std::string>& tags )
|
||||
: m_tags( tags )
|
||||
{}
|
||||
virtual ~TagExtracter();
|
||||
|
||||
void parse( std::string& description ) {
|
||||
TagParser::parse( description );
|
||||
description = m_remainder;
|
||||
}
|
||||
|
||||
private:
|
||||
virtual void acceptTag( std::string const& tag ) {
|
||||
m_tags.insert( toLower( tag ) );
|
||||
}
|
||||
virtual void acceptChar( char c ) {
|
||||
m_remainder += c;
|
||||
}
|
||||
|
||||
TagExtracter& operator=(TagExtracter const&);
|
||||
|
||||
std::set<std::string>& m_tags;
|
||||
std::string m_remainder;
|
||||
};
|
||||
|
||||
class Tag {
|
||||
public:
|
||||
Tag()
|
||||
: m_isNegated( false )
|
||||
{}
|
||||
|
||||
Tag( std::string const& name, bool isNegated )
|
||||
: m_name( name ),
|
||||
m_isNegated( isNegated )
|
||||
{}
|
||||
|
||||
std::string getName() const {
|
||||
return m_name;
|
||||
}
|
||||
bool isNegated() const {
|
||||
return m_isNegated;
|
||||
}
|
||||
|
||||
bool operator ! () const {
|
||||
return m_name.empty();
|
||||
}
|
||||
|
||||
private:
|
||||
std::string m_name;
|
||||
bool m_isNegated;
|
||||
};
|
||||
|
||||
class TagSet {
|
||||
typedef std::map<std::string, Tag> TagMap;
|
||||
public:
|
||||
void add( Tag const& tag ) {
|
||||
m_tags.insert( std::make_pair( toLower( tag.getName() ), tag ) );
|
||||
}
|
||||
|
||||
bool empty() const {
|
||||
return m_tags.empty();
|
||||
}
|
||||
|
||||
bool matches( std::set<std::string> const& tags ) const {
|
||||
for( TagMap::const_iterator
|
||||
it = m_tags.begin(), itEnd = m_tags.end();
|
||||
it != itEnd;
|
||||
++it ) {
|
||||
bool found = tags.find( it->first ) != tags.end();
|
||||
if( found == it->second.isNegated() )
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private:
|
||||
TagMap m_tags;
|
||||
};
|
||||
|
||||
class TagExpression {
|
||||
public:
|
||||
bool matches( std::set<std::string> const& tags ) const {
|
||||
for( std::vector<TagSet>::const_iterator
|
||||
it = m_tagSets.begin(), itEnd = m_tagSets.end();
|
||||
it != itEnd;
|
||||
++it )
|
||||
if( it->matches( tags ) )
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
private:
|
||||
friend class TagExpressionParser;
|
||||
|
||||
std::vector<TagSet> m_tagSets;
|
||||
};
|
||||
|
||||
class TagExpressionParser : public TagParser {
|
||||
public:
|
||||
TagExpressionParser( TagExpression& exp )
|
||||
: m_isNegated( false ),
|
||||
m_exp( exp )
|
||||
{}
|
||||
|
||||
~TagExpressionParser();
|
||||
|
||||
private:
|
||||
virtual void acceptTag( std::string const& tag ) {
|
||||
m_currentTagSet.add( Tag( tag, m_isNegated ) );
|
||||
m_isNegated = false;
|
||||
}
|
||||
virtual void acceptChar( char c ) {
|
||||
switch( c ) {
|
||||
case '~':
|
||||
m_isNegated = true;
|
||||
break;
|
||||
case ',':
|
||||
m_exp.m_tagSets.push_back( m_currentTagSet );
|
||||
m_currentTagSet = TagSet();
|
||||
break;
|
||||
else {
|
||||
acceptChar( c );
|
||||
pos++;
|
||||
}
|
||||
}
|
||||
virtual void endParse() {
|
||||
if( !m_currentTagSet.empty() )
|
||||
endParse();
|
||||
}
|
||||
|
||||
INTERNAL_CATCH_INLINE TagExtracter::TagExtracter( std::set<std::string>& tags )
|
||||
: m_tags( tags )
|
||||
{}
|
||||
|
||||
INTERNAL_CATCH_INLINE TagExtracter::~TagExtracter() {}
|
||||
|
||||
INTERNAL_CATCH_INLINE void TagExtracter::parse( std::string& description ) {
|
||||
TagParser::parse( description );
|
||||
description = m_remainder;
|
||||
}
|
||||
|
||||
INTERNAL_CATCH_INLINE void TagExtracter::acceptTag( std::string const& tag ) {
|
||||
m_tags.insert( toLower( tag ) );
|
||||
}
|
||||
INTERNAL_CATCH_INLINE void TagExtracter::acceptChar( char c ) {
|
||||
m_remainder += c;
|
||||
}
|
||||
|
||||
INTERNAL_CATCH_INLINE Tag::Tag() : m_isNegated( false ) {}
|
||||
INTERNAL_CATCH_INLINE Tag::Tag( std::string const& name, bool isNegated )
|
||||
: m_name( name ),
|
||||
m_isNegated( isNegated )
|
||||
{}
|
||||
|
||||
INTERNAL_CATCH_INLINE std::string Tag::getName() const {
|
||||
return m_name;
|
||||
}
|
||||
INTERNAL_CATCH_INLINE bool Tag::isNegated() const {
|
||||
return m_isNegated;
|
||||
}
|
||||
|
||||
INTERNAL_CATCH_INLINE bool Tag::operator ! () const {
|
||||
return m_name.empty();
|
||||
}
|
||||
|
||||
|
||||
INTERNAL_CATCH_INLINE void TagSet::add( Tag const& tag ) {
|
||||
m_tags.insert( std::make_pair( toLower( tag.getName() ), tag ) );
|
||||
}
|
||||
|
||||
INTERNAL_CATCH_INLINE bool TagSet::empty() const {
|
||||
return m_tags.empty();
|
||||
}
|
||||
|
||||
INTERNAL_CATCH_INLINE bool TagSet::matches( std::set<std::string> const& tags ) const {
|
||||
for( TagMap::const_iterator
|
||||
it = m_tags.begin(), itEnd = m_tags.end();
|
||||
it != itEnd;
|
||||
++it ) {
|
||||
bool found = tags.find( it->first ) != tags.end();
|
||||
if( found == it->second.isNegated() )
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
INTERNAL_CATCH_INLINE bool TagExpression::matches( std::set<std::string> const& tags ) const {
|
||||
for( std::vector<TagSet>::const_iterator
|
||||
it = m_tagSets.begin(), itEnd = m_tagSets.end();
|
||||
it != itEnd;
|
||||
++it )
|
||||
if( it->matches( tags ) )
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
INTERNAL_CATCH_INLINE TagExpressionParser::TagExpressionParser( TagExpression& exp )
|
||||
: m_isNegated( false ),
|
||||
m_exp( exp )
|
||||
{}
|
||||
|
||||
INTERNAL_CATCH_INLINE TagExpressionParser::~TagExpressionParser() {}
|
||||
|
||||
INTERNAL_CATCH_INLINE void TagExpressionParser::acceptTag( std::string const& tag ) {
|
||||
m_currentTagSet.add( Tag( tag, m_isNegated ) );
|
||||
m_isNegated = false;
|
||||
}
|
||||
|
||||
INTERNAL_CATCH_INLINE void TagExpressionParser::acceptChar( char c ) {
|
||||
switch( c ) {
|
||||
case '~':
|
||||
m_isNegated = true;
|
||||
break;
|
||||
case ',':
|
||||
m_exp.m_tagSets.push_back( m_currentTagSet );
|
||||
m_currentTagSet = TagSet();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
TagExpressionParser& operator=(TagExpressionParser const&);
|
||||
|
||||
bool m_isNegated;
|
||||
TagSet m_currentTagSet;
|
||||
TagExpression& m_exp;
|
||||
};
|
||||
INTERNAL_CATCH_INLINE void TagExpressionParser::endParse() {
|
||||
if( !m_currentTagSet.empty() )
|
||||
m_exp.m_tagSets.push_back( m_currentTagSet );
|
||||
}
|
||||
|
||||
} // end namespace Catch
|
||||
|
||||
|
@@ -8,7 +8,7 @@
|
||||
#ifndef TWOBLUECUBES_CATCH_TEST_CASE_INFO_HPP_INCLUDED
|
||||
#define TWOBLUECUBES_CATCH_TEST_CASE_INFO_HPP_INCLUDED
|
||||
|
||||
#include "catch_tags.hpp"
|
||||
#include "catch_tags.h"
|
||||
#include "catch_test_case_info.h"
|
||||
#include "catch_interfaces_testcase.h"
|
||||
#include "catch_common.h"
|
||||
@@ -22,12 +22,16 @@ namespace Catch {
|
||||
SourceLineInfo const& _lineInfo )
|
||||
{
|
||||
std::string desc = _descOrTags;
|
||||
bool isHidden( startsWith( _name, "./" ) );
|
||||
bool isHidden( startsWith( _name, "./" ) ); // Legacy support
|
||||
std::set<std::string> tags;
|
||||
TagExtracter( tags ).parse( desc );
|
||||
if( tags.find( "hide" ) != tags.end() || tags.find( "." ) != tags.end() )
|
||||
isHidden = true;
|
||||
|
||||
if( isHidden ) {
|
||||
tags.insert( "hide" );
|
||||
tags.insert( "." );
|
||||
}
|
||||
TestCaseInfo info( _name, _className, desc, tags, isHidden, _lineInfo );
|
||||
return TestCase( _testCase, info );
|
||||
}
|
||||
|
@@ -42,8 +42,8 @@ namespace Catch {
|
||||
else {
|
||||
TestCase const& prev = *m_functions.find( testCase );
|
||||
std::cerr << "error: TEST_CASE( \"" << name << "\" ) already defined.\n"
|
||||
<< "\tFirst seen at " << SourceLineInfo( prev.getTestCaseInfo().lineInfo ) << "\n"
|
||||
<< "\tRedefined at " << SourceLineInfo( testCase.getTestCaseInfo().lineInfo ) << std::endl;
|
||||
<< "\tFirst seen at " << prev.getTestCaseInfo().lineInfo << "\n"
|
||||
<< "\tRedefined at " << testCase.getTestCaseInfo().lineInfo << std::endl;
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
@@ -8,15 +8,15 @@
|
||||
#ifndef TWOBLUECUBES_CATCH_TEST_SPEC_H_INCLUDED
|
||||
#define TWOBLUECUBES_CATCH_TEST_SPEC_H_INCLUDED
|
||||
|
||||
#include "catch_test_case_info.h"
|
||||
#include "catch_tags.hpp"
|
||||
#include "catch_common.h"
|
||||
#include "catch_tags.h"
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace Catch {
|
||||
|
||||
class TestCase;
|
||||
|
||||
struct IfFilterMatches{ enum DoWhat {
|
||||
AutoDetectBehaviour,
|
||||
IncludeTests,
|
||||
@@ -32,69 +32,13 @@ namespace Catch {
|
||||
};
|
||||
|
||||
public:
|
||||
TestCaseFilter( std::string const& testSpec, IfFilterMatches::DoWhat matchBehaviour = IfFilterMatches::AutoDetectBehaviour )
|
||||
: m_stringToMatch( toLower( testSpec ) ),
|
||||
m_filterType( matchBehaviour ),
|
||||
m_wildcardPosition( NoWildcard )
|
||||
{
|
||||
if( m_filterType == IfFilterMatches::AutoDetectBehaviour ) {
|
||||
if( startsWith( m_stringToMatch, "exclude:" ) ) {
|
||||
m_stringToMatch = m_stringToMatch.substr( 8 );
|
||||
m_filterType = IfFilterMatches::ExcludeTests;
|
||||
}
|
||||
else if( startsWith( m_stringToMatch, "~" ) ) {
|
||||
m_stringToMatch = m_stringToMatch.substr( 1 );
|
||||
m_filterType = IfFilterMatches::ExcludeTests;
|
||||
}
|
||||
else {
|
||||
m_filterType = IfFilterMatches::IncludeTests;
|
||||
}
|
||||
}
|
||||
TestCaseFilter( std::string const& testSpec, IfFilterMatches::DoWhat matchBehaviour = IfFilterMatches::AutoDetectBehaviour );
|
||||
|
||||
if( startsWith( m_stringToMatch, "*" ) ) {
|
||||
m_stringToMatch = m_stringToMatch.substr( 1 );
|
||||
m_wildcardPosition = (WildcardPosition)( m_wildcardPosition | WildcardAtStart );
|
||||
}
|
||||
if( endsWith( m_stringToMatch, "*" ) ) {
|
||||
m_stringToMatch = m_stringToMatch.substr( 0, m_stringToMatch.size()-1 );
|
||||
m_wildcardPosition = (WildcardPosition)( m_wildcardPosition | WildcardAtEnd );
|
||||
}
|
||||
}
|
||||
IfFilterMatches::DoWhat getFilterType() const;
|
||||
bool shouldInclude( TestCase const& testCase ) const;
|
||||
|
||||
IfFilterMatches::DoWhat getFilterType() const {
|
||||
return m_filterType;
|
||||
}
|
||||
|
||||
bool shouldInclude( TestCase const& testCase ) const {
|
||||
return isMatch( testCase ) == (m_filterType == IfFilterMatches::IncludeTests);
|
||||
}
|
||||
private:
|
||||
|
||||
#ifdef __clang__
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wunreachable-code"
|
||||
#endif
|
||||
|
||||
bool isMatch( TestCase const& testCase ) const {
|
||||
std::string name = testCase.getTestCaseInfo().name;
|
||||
toLowerInPlace( name );
|
||||
|
||||
switch( m_wildcardPosition ) {
|
||||
case NoWildcard:
|
||||
return m_stringToMatch == name;
|
||||
case WildcardAtStart:
|
||||
return endsWith( name, m_stringToMatch );
|
||||
case WildcardAtEnd:
|
||||
return startsWith( name, m_stringToMatch );
|
||||
case WildcardAtBothEnds:
|
||||
return contains( name, m_stringToMatch );
|
||||
}
|
||||
throw std::logic_error( "Unhandled wildcard type" );
|
||||
}
|
||||
|
||||
#ifdef __clang__
|
||||
#pragma clang diagnostic pop
|
||||
#endif
|
||||
bool isMatch( TestCase const& testCase ) const;
|
||||
|
||||
std::string m_stringToMatch;
|
||||
IfFilterMatches::DoWhat m_filterType;
|
||||
@@ -103,57 +47,12 @@ namespace Catch {
|
||||
|
||||
class TestCaseFilters {
|
||||
public:
|
||||
TestCaseFilters( std::string const& name ) : m_name( name ) {}
|
||||
TestCaseFilters( std::string const& name );
|
||||
std::string getName() const;
|
||||
void addFilter( TestCaseFilter const& filter );
|
||||
void addTags( std::string const& tagPattern );
|
||||
bool shouldInclude( TestCase const& testCase ) const;
|
||||
|
||||
std::string getName() const {
|
||||
return m_name;
|
||||
}
|
||||
|
||||
void addFilter( TestCaseFilter const& filter ) {
|
||||
if( filter.getFilterType() == IfFilterMatches::ExcludeTests )
|
||||
m_exclusionFilters.push_back( filter );
|
||||
else
|
||||
m_inclusionFilters.push_back( filter );
|
||||
}
|
||||
|
||||
void addTags( std::string const& tagPattern ) {
|
||||
TagExpression exp;
|
||||
TagExpressionParser( exp ).parse( tagPattern );
|
||||
|
||||
m_tagExpressions.push_back( exp );
|
||||
}
|
||||
|
||||
bool shouldInclude( TestCase const& testCase ) const {
|
||||
if( !m_tagExpressions.empty() ) {
|
||||
std::vector<TagExpression>::const_iterator it = m_tagExpressions.begin();
|
||||
std::vector<TagExpression>::const_iterator itEnd = m_tagExpressions.end();
|
||||
for(; it != itEnd; ++it )
|
||||
if( it->matches( testCase.getTags() ) )
|
||||
break;
|
||||
if( it == itEnd )
|
||||
return false;
|
||||
}
|
||||
|
||||
if( !m_inclusionFilters.empty() ) {
|
||||
std::vector<TestCaseFilter>::const_iterator it = m_inclusionFilters.begin();
|
||||
std::vector<TestCaseFilter>::const_iterator itEnd = m_inclusionFilters.end();
|
||||
for(; it != itEnd; ++it )
|
||||
if( it->shouldInclude( testCase ) )
|
||||
break;
|
||||
if( it == itEnd )
|
||||
return false;
|
||||
}
|
||||
else if( m_exclusionFilters.empty() && m_tagExpressions.empty() ) {
|
||||
return !testCase.isHidden();
|
||||
}
|
||||
|
||||
std::vector<TestCaseFilter>::const_iterator it = m_exclusionFilters.begin();
|
||||
std::vector<TestCaseFilter>::const_iterator itEnd = m_exclusionFilters.end();
|
||||
for(; it != itEnd; ++it )
|
||||
if( !it->shouldInclude( testCase ) )
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
private:
|
||||
std::vector<TagExpression> m_tagExpressions;
|
||||
std::vector<TestCaseFilter> m_inclusionFilters;
|
||||
|
133
include/internal/catch_test_spec.hpp
Normal file
133
include/internal/catch_test_spec.hpp
Normal file
@@ -0,0 +1,133 @@
|
||||
/*
|
||||
* Created by Phil on 2/12/2013.
|
||||
* Copyright 2013 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_TEST_SPEC_HPP_INCLUDED
|
||||
#define TWOBLUECUBES_CATCH_TEST_SPEC_HPP_INCLUDED
|
||||
|
||||
#include "catch_test_spec.hpp"
|
||||
#include "catch_test_case_info.h"
|
||||
#include "catch_common.h"
|
||||
|
||||
namespace Catch {
|
||||
|
||||
INTERNAL_CATCH_INLINE TestCaseFilter::TestCaseFilter( std::string const& testSpec, IfFilterMatches::DoWhat matchBehaviour )
|
||||
: m_stringToMatch( toLower( testSpec ) ),
|
||||
m_filterType( matchBehaviour ),
|
||||
m_wildcardPosition( NoWildcard )
|
||||
{
|
||||
if( m_filterType == IfFilterMatches::AutoDetectBehaviour ) {
|
||||
if( startsWith( m_stringToMatch, "exclude:" ) ) {
|
||||
m_stringToMatch = m_stringToMatch.substr( 8 );
|
||||
m_filterType = IfFilterMatches::ExcludeTests;
|
||||
}
|
||||
else if( startsWith( m_stringToMatch, "~" ) ) {
|
||||
m_stringToMatch = m_stringToMatch.substr( 1 );
|
||||
m_filterType = IfFilterMatches::ExcludeTests;
|
||||
}
|
||||
else {
|
||||
m_filterType = IfFilterMatches::IncludeTests;
|
||||
}
|
||||
}
|
||||
|
||||
if( startsWith( m_stringToMatch, "*" ) ) {
|
||||
m_stringToMatch = m_stringToMatch.substr( 1 );
|
||||
m_wildcardPosition = (WildcardPosition)( m_wildcardPosition | WildcardAtStart );
|
||||
}
|
||||
if( endsWith( m_stringToMatch, "*" ) ) {
|
||||
m_stringToMatch = m_stringToMatch.substr( 0, m_stringToMatch.size()-1 );
|
||||
m_wildcardPosition = (WildcardPosition)( m_wildcardPosition | WildcardAtEnd );
|
||||
}
|
||||
}
|
||||
|
||||
INTERNAL_CATCH_INLINE IfFilterMatches::DoWhat TestCaseFilter::getFilterType() const {
|
||||
return m_filterType;
|
||||
}
|
||||
|
||||
INTERNAL_CATCH_INLINE bool TestCaseFilter::shouldInclude( TestCase const& testCase ) const {
|
||||
return isMatch( testCase ) == (m_filterType == IfFilterMatches::IncludeTests);
|
||||
}
|
||||
|
||||
#ifdef __clang__
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wunreachable-code"
|
||||
#endif
|
||||
|
||||
INTERNAL_CATCH_INLINE bool TestCaseFilter::isMatch( TestCase const& testCase ) const {
|
||||
std::string name = testCase.getTestCaseInfo().name;
|
||||
toLowerInPlace( name );
|
||||
|
||||
switch( m_wildcardPosition ) {
|
||||
case NoWildcard:
|
||||
return m_stringToMatch == name;
|
||||
case WildcardAtStart:
|
||||
return endsWith( name, m_stringToMatch );
|
||||
case WildcardAtEnd:
|
||||
return startsWith( name, m_stringToMatch );
|
||||
case WildcardAtBothEnds:
|
||||
return contains( name, m_stringToMatch );
|
||||
}
|
||||
throw std::logic_error( "Unhandled wildcard type" );
|
||||
}
|
||||
|
||||
#ifdef __clang__
|
||||
#pragma clang diagnostic pop
|
||||
#endif
|
||||
|
||||
INTERNAL_CATCH_INLINE TestCaseFilters::TestCaseFilters( std::string const& name ) : m_name( name ) {}
|
||||
|
||||
INTERNAL_CATCH_INLINE std::string TestCaseFilters::getName() const {
|
||||
return m_name;
|
||||
}
|
||||
|
||||
INTERNAL_CATCH_INLINE void TestCaseFilters::addFilter( TestCaseFilter const& filter ) {
|
||||
if( filter.getFilterType() == IfFilterMatches::ExcludeTests )
|
||||
m_exclusionFilters.push_back( filter );
|
||||
else
|
||||
m_inclusionFilters.push_back( filter );
|
||||
}
|
||||
|
||||
INTERNAL_CATCH_INLINE void TestCaseFilters::addTags( std::string const& tagPattern ) {
|
||||
TagExpression exp;
|
||||
TagExpressionParser( exp ).parse( tagPattern );
|
||||
|
||||
m_tagExpressions.push_back( exp );
|
||||
}
|
||||
|
||||
INTERNAL_CATCH_INLINE bool TestCaseFilters::shouldInclude( TestCase const& testCase ) const {
|
||||
if( !m_tagExpressions.empty() ) {
|
||||
std::vector<TagExpression>::const_iterator it = m_tagExpressions.begin();
|
||||
std::vector<TagExpression>::const_iterator itEnd = m_tagExpressions.end();
|
||||
for(; it != itEnd; ++it )
|
||||
if( it->matches( testCase.getTags() ) )
|
||||
break;
|
||||
if( it == itEnd )
|
||||
return false;
|
||||
}
|
||||
|
||||
if( !m_inclusionFilters.empty() ) {
|
||||
std::vector<TestCaseFilter>::const_iterator it = m_inclusionFilters.begin();
|
||||
std::vector<TestCaseFilter>::const_iterator itEnd = m_inclusionFilters.end();
|
||||
for(; it != itEnd; ++it )
|
||||
if( it->shouldInclude( testCase ) )
|
||||
break;
|
||||
if( it == itEnd )
|
||||
return false;
|
||||
}
|
||||
else if( m_exclusionFilters.empty() && m_tagExpressions.empty() ) {
|
||||
return !testCase.isHidden();
|
||||
}
|
||||
|
||||
std::vector<TestCaseFilter>::const_iterator it = m_exclusionFilters.begin();
|
||||
std::vector<TestCaseFilter>::const_iterator itEnd = m_exclusionFilters.end();
|
||||
for(; it != itEnd; ++it )
|
||||
if( !it->shouldInclude( testCase ) )
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
#endif // TWOBLUECUBES_CATCH_TEST_SPEC_HPP_INCLUDED
|
@@ -14,7 +14,7 @@ namespace Catch {
|
||||
|
||||
// These numbers are maintained by a script
|
||||
template <typename T>
|
||||
const T LibraryVersionInfo<T>::value( 1, 0, 13, "master" );
|
||||
const T LibraryVersionInfo<T>::value( 1, 0, 16, "master" );
|
||||
}
|
||||
|
||||
#endif // TWOBLUECUBES_CATCH_VERSION_HPP_INCLUDED
|
||||
|
@@ -26,6 +26,11 @@ namespace Catch {
|
||||
|
||||
}
|
||||
|
||||
#include "catch_common.hpp"
|
||||
#include "catch_debugger.hpp"
|
||||
#include "catch_tags.hpp"
|
||||
#include "catch_test_spec.hpp"
|
||||
#include "catch_section.hpp"
|
||||
#include "internal/catch_timer.hpp"
|
||||
#include "internal/catch_vs_test_registry.hpp"
|
||||
#include "reporters/catch_vs_reporter.hpp"
|
||||
|
@@ -21,6 +21,11 @@ using Microsoft::VisualStudio::CppUnitTestFramework::__LineInfo;
|
||||
#include <cvt/wstring>
|
||||
#include <codecvt>
|
||||
|
||||
#include "catch_common.hpp"
|
||||
#include "catch_debugger.hpp"
|
||||
#include "catch_tags.hpp"
|
||||
#include "catch_test_spec.hpp"
|
||||
#include "catch_section.hpp"
|
||||
#include "internal/catch_timer.hpp"
|
||||
#include "internal/catch_vs_test_registry.hpp"
|
||||
#include "reporters/catch_vs_reporter.hpp"
|
||||
|
@@ -332,7 +332,6 @@ namespace Catch {
|
||||
inline IMutableRegistryHub::~IMutableRegistryHub() {}
|
||||
inline IExceptionTranslator::~IExceptionTranslator() {}
|
||||
inline IExceptionTranslatorRegistry::~IExceptionTranslatorRegistry() {}
|
||||
inline IReporter::~IReporter() {}
|
||||
inline IReporterFactory::~IReporterFactory() {}
|
||||
inline IReporterRegistry::~IReporterRegistry() {}
|
||||
inline IStreamingReporter::~IStreamingReporter() {}
|
||||
@@ -355,9 +354,6 @@ namespace Catch {
|
||||
inline FreeFunctionTestCase::~FreeFunctionTestCase() {}
|
||||
inline IGeneratorInfo::~IGeneratorInfo() {}
|
||||
inline IGeneratorsForTest::~IGeneratorsForTest() {}
|
||||
inline TagParser::~TagParser() {}
|
||||
inline TagExtracter::~TagExtracter() {}
|
||||
inline TagExpressionParser::~TagExpressionParser() {}
|
||||
|
||||
inline Matchers::Impl::StdString::Equals::~Equals() {}
|
||||
inline Matchers::Impl::StdString::Contains::~Contains() {}
|
||||
|
192
include/reporters/catch_reporter_bases.hpp
Normal file
192
include/reporters/catch_reporter_bases.hpp
Normal file
@@ -0,0 +1,192 @@
|
||||
/*
|
||||
* Created by Phil on 27/11/2013.
|
||||
* Copyright 2013 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_REPORTER_BASES_HPP_INCLUDED
|
||||
#define TWOBLUECUBES_CATCH_REPORTER_BASES_HPP_INCLUDED
|
||||
|
||||
#include "../internal/catch_interfaces_reporter.h"
|
||||
|
||||
namespace Catch {
|
||||
|
||||
struct StreamingReporterBase : SharedImpl<IStreamingReporter> {
|
||||
|
||||
StreamingReporterBase( ReporterConfig const& _config )
|
||||
: m_config( _config.fullConfig() ),
|
||||
stream( _config.stream() )
|
||||
{}
|
||||
|
||||
virtual ~StreamingReporterBase();
|
||||
|
||||
virtual void noMatchingTestCases( std::string const& ) {}
|
||||
|
||||
virtual void testRunStarting( TestRunInfo const& _testRunInfo ) {
|
||||
currentTestRunInfo = _testRunInfo;
|
||||
}
|
||||
virtual void testGroupStarting( GroupInfo const& _groupInfo ) {
|
||||
currentGroupInfo = _groupInfo;
|
||||
}
|
||||
|
||||
virtual void testCaseStarting( TestCaseInfo const& _testInfo ) {
|
||||
currentTestCaseInfo = _testInfo;
|
||||
}
|
||||
virtual void sectionStarting( SectionInfo const& _sectionInfo ) {
|
||||
m_sectionStack.push_back( _sectionInfo );
|
||||
}
|
||||
|
||||
virtual void sectionEnded( SectionStats const& /* _sectionStats */ ) {
|
||||
m_sectionStack.pop_back();
|
||||
}
|
||||
virtual void testCaseEnded( TestCaseStats const& /* _testCaseStats */ ) {
|
||||
currentTestCaseInfo.reset();
|
||||
assert( m_sectionStack.empty() );
|
||||
}
|
||||
virtual void testGroupEnded( TestGroupStats const& /* _testGroupStats */ ) {
|
||||
currentGroupInfo.reset();
|
||||
}
|
||||
virtual void testRunEnded( TestRunStats const& /* _testRunStats */ ) {
|
||||
currentTestCaseInfo.reset();
|
||||
currentGroupInfo.reset();
|
||||
currentTestRunInfo.reset();
|
||||
}
|
||||
|
||||
Ptr<IConfig> m_config;
|
||||
std::ostream& stream;
|
||||
|
||||
LazyStat<TestRunInfo> currentTestRunInfo;
|
||||
LazyStat<GroupInfo> currentGroupInfo;
|
||||
LazyStat<TestCaseInfo> currentTestCaseInfo;
|
||||
|
||||
std::vector<SectionInfo> m_sectionStack;
|
||||
};
|
||||
|
||||
struct CumulativeReporterBase : SharedImpl<IStreamingReporter> {
|
||||
template<typename T, typename ChildNodeT>
|
||||
struct Node : SharedImpl<> {
|
||||
explicit Node( T const& _value ) : value( _value ) {}
|
||||
virtual ~Node() {}
|
||||
|
||||
typedef std::vector<Ptr<ChildNodeT> > ChildNodes;
|
||||
T value;
|
||||
ChildNodes children;
|
||||
};
|
||||
struct SectionNode : SharedImpl<> {
|
||||
explicit SectionNode( SectionStats const& _stats ) : stats( _stats ) {}
|
||||
virtual ~SectionNode();
|
||||
|
||||
bool operator == ( SectionNode const& other ) const {
|
||||
return stats.sectionInfo.lineInfo == other.stats.sectionInfo.lineInfo;
|
||||
}
|
||||
bool operator == ( Ptr<SectionNode> const& other ) const {
|
||||
return operator==( *other );
|
||||
}
|
||||
|
||||
SectionStats stats;
|
||||
typedef std::vector<Ptr<SectionNode> > ChildSections;
|
||||
typedef std::vector<AssertionStats> Assertions;
|
||||
ChildSections childSections;
|
||||
Assertions assertions;
|
||||
std::string stdOut;
|
||||
std::string stdErr;
|
||||
};
|
||||
friend bool operator == ( Ptr<SectionNode> const& node, SectionInfo const& other ) {
|
||||
return node->stats.sectionInfo.lineInfo == other.lineInfo;
|
||||
}
|
||||
|
||||
typedef Node<TestCaseStats, SectionNode> TestCaseNode;
|
||||
typedef Node<TestGroupStats, TestCaseNode> TestGroupNode;
|
||||
typedef Node<TestRunStats, TestGroupNode> TestRunNode;
|
||||
|
||||
CumulativeReporterBase( ReporterConfig const& _config )
|
||||
: m_config( _config.fullConfig() ),
|
||||
stream( _config.stream() )
|
||||
{}
|
||||
~CumulativeReporterBase();
|
||||
|
||||
virtual void testRunStarting( TestRunInfo const& ) {}
|
||||
virtual void testGroupStarting( GroupInfo const& ) {}
|
||||
|
||||
virtual void testCaseStarting( TestCaseInfo const& ) {}
|
||||
|
||||
virtual void sectionStarting( SectionInfo const& sectionInfo ) {
|
||||
SectionStats incompleteStats( sectionInfo, Counts(), 0, false );
|
||||
Ptr<SectionNode> node;
|
||||
if( m_sectionStack.empty() ) {
|
||||
if( !m_rootSection )
|
||||
m_rootSection = new SectionNode( incompleteStats );
|
||||
node = m_rootSection;
|
||||
}
|
||||
else {
|
||||
SectionNode& parentNode = *m_sectionStack.back();
|
||||
SectionNode::ChildSections::const_iterator it =
|
||||
std::find( parentNode.childSections.begin(), parentNode.childSections.end(), sectionInfo );
|
||||
if( it == parentNode.childSections.end() ) {
|
||||
node = new SectionNode( incompleteStats );
|
||||
parentNode.childSections.push_back( node );
|
||||
}
|
||||
else
|
||||
node = *it;
|
||||
}
|
||||
m_sectionStack.push_back( node );
|
||||
m_deepestSection = node;
|
||||
}
|
||||
|
||||
virtual void assertionStarting( AssertionInfo const& ) {}
|
||||
|
||||
virtual bool assertionEnded( AssertionStats const& assertionStats ) {
|
||||
assert( !m_sectionStack.empty() );
|
||||
SectionNode& sectionNode = *m_sectionStack.back();
|
||||
sectionNode.assertions.push_back( assertionStats );
|
||||
return true;
|
||||
}
|
||||
virtual void sectionEnded( SectionStats const& sectionStats ) {
|
||||
assert( !m_sectionStack.empty() );
|
||||
SectionNode& node = *m_sectionStack.back();
|
||||
node.stats = sectionStats;
|
||||
m_sectionStack.pop_back();
|
||||
}
|
||||
virtual void testCaseEnded( TestCaseStats const& testCaseStats ) {
|
||||
Ptr<TestCaseNode> node = new TestCaseNode( testCaseStats );
|
||||
assert( m_sectionStack.size() == 0 );
|
||||
node->children.push_back( m_rootSection );
|
||||
m_testCases.push_back( node );
|
||||
m_rootSection.reset();
|
||||
|
||||
assert( m_deepestSection );
|
||||
m_deepestSection->stdOut = testCaseStats.stdOut;
|
||||
m_deepestSection->stdErr = testCaseStats.stdErr;
|
||||
}
|
||||
virtual void testGroupEnded( TestGroupStats const& testGroupStats ) {
|
||||
Ptr<TestGroupNode> node = new TestGroupNode( testGroupStats );
|
||||
node->children.swap( m_testCases );
|
||||
m_testGroups.push_back( node );
|
||||
}
|
||||
virtual void testRunEnded( TestRunStats const& testRunStats ) {
|
||||
Ptr<TestRunNode> node = new TestRunNode( testRunStats );
|
||||
node->children.swap( m_testGroups );
|
||||
m_testRuns.push_back( node );
|
||||
testRunEnded();
|
||||
}
|
||||
virtual void testRunEnded() = 0;
|
||||
|
||||
Ptr<IConfig> m_config;
|
||||
std::ostream& stream;
|
||||
std::vector<AssertionStats> m_assertions;
|
||||
std::vector<std::vector<Ptr<SectionNode> > > m_sections;
|
||||
std::vector<Ptr<TestCaseNode> > m_testCases;
|
||||
std::vector<Ptr<TestGroupNode> > m_testGroups;
|
||||
|
||||
std::vector<Ptr<TestRunNode> > m_testRuns;
|
||||
|
||||
Ptr<SectionNode> m_rootSection;
|
||||
Ptr<SectionNode> m_deepestSection;
|
||||
std::vector<Ptr<SectionNode> > m_sectionStack;
|
||||
|
||||
};
|
||||
|
||||
} // end namespace Catch
|
||||
|
||||
#endif // TWOBLUECUBES_CATCH_REPORTER_BASES_HPP_INCLUDED
|
@@ -8,7 +8,8 @@
|
||||
#ifndef TWOBLUECUBES_CATCH_REPORTER_CONSOLE_HPP_INCLUDED
|
||||
#define TWOBLUECUBES_CATCH_REPORTER_CONSOLE_HPP_INCLUDED
|
||||
|
||||
#include "../internal/catch_interfaces_reporter.h"
|
||||
#include "catch_reporter_bases.hpp"
|
||||
|
||||
#include "../internal/catch_reporter_registrars.hpp"
|
||||
#include "../internal/catch_console_colour.hpp"
|
||||
|
||||
|
@@ -8,8 +8,9 @@
|
||||
#ifndef TWOBLUECUBES_CATCH_REPORTER_JUNIT_HPP_INCLUDED
|
||||
#define TWOBLUECUBES_CATCH_REPORTER_JUNIT_HPP_INCLUDED
|
||||
|
||||
#include "catch_reporter_bases.hpp"
|
||||
|
||||
#include "../internal/catch_tostring.hpp"
|
||||
#include "../internal/catch_interfaces_reporter.h"
|
||||
#include "../internal/catch_reporter_registrars.hpp"
|
||||
#include "../internal/catch_xmlwriter.hpp"
|
||||
|
||||
|
@@ -8,8 +8,9 @@
|
||||
#ifndef TWOBLUECUBES_CATCH_REPORTER_XML_HPP_INCLUDED
|
||||
#define TWOBLUECUBES_CATCH_REPORTER_XML_HPP_INCLUDED
|
||||
|
||||
#include "catch_reporter_bases.hpp"
|
||||
|
||||
#include "../internal/catch_capture.hpp"
|
||||
#include "../internal/catch_interfaces_reporter.h"
|
||||
#include "../internal/catch_reporter_registrars.hpp"
|
||||
#include "../internal/catch_xmlwriter.hpp"
|
||||
|
||||
|
Reference in New Issue
Block a user