Refactored a lot of code from headers into impl headers only compiled into one TU
- also added noimpl option to single header script - which only generates the non impl code
diff --git a/include/catch.hpp b/include/catch.hpp
index 600815f..28e7f9b 100644
--- a/include/catch.hpp
+++ b/include/catch.hpp
@@ -21,7 +21,7 @@
#include "internal/catch_context.h"
#include "internal/catch_test_registry.hpp"
#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"
@@ -39,11 +39,11 @@
#if defined( CATCH_CONFIG_MAIN ) || defined( CATCH_CONFIG_RUNNER )
#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
//////
diff --git a/include/internal/catch_capture.hpp b/include/internal/catch_capture.hpp
index 849dee9..a352a62 100644
--- a/include/internal/catch_capture.hpp
+++ b/include/internal/catch_capture.hpp
@@ -12,11 +12,12 @@
#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_registry_hub.h"
+#include "catch_interfaces_config.h"
#include "internal/catch_compiler_capabilities.h"
#include <ostream>
@@ -66,7 +67,7 @@
///////////////////////////////////////////////////////////////////////////////
#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 ) throw Catch::TestFailureException(); \
if( !Catch::shouldContinueOnFailure( resultDisposition ) ) throw Catch::TestFailureException(); \
Catch::isTrue( false && originalExpr ); \
diff --git a/include/internal/catch_common.h b/include/internal/catch_common.h
index 7759987..650e1fb 100644
--- a/include/internal/catch_common.h
+++ b/include/internal/catch_common.h
@@ -67,36 +67,17 @@
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 @@
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( std::string 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__ ) )
diff --git a/include/internal/catch_common.hpp b/include/internal/catch_common.hpp
new file mode 100644
index 0000000..4fbf1ff
--- /dev/null
+++ b/include/internal/catch_common.hpp
@@ -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 {
+
+ bool startsWith( std::string const& s, std::string const& prefix ) {
+ return s.size() >= prefix.size() && s.substr( 0, prefix.size() ) == prefix;
+ }
+ bool endsWith( std::string const& s, std::string const& suffix ) {
+ return s.size() >= suffix.size() && s.substr( s.size()-suffix.size(), suffix.size() ) == suffix;
+ }
+ bool contains( std::string const& s, std::string const& infix ) {
+ return s.find( infix ) != std::string::npos;
+ }
+ void toLowerInPlace( std::string& s ) {
+ std::transform( s.begin(), s.end(), s.begin(), ::tolower );
+ }
+ std::string toLower( std::string const& s ) {
+ std::string lc = s;
+ toLowerInPlace( lc );
+ return lc;
+ }
+ 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 ) : "";
+ }
+
+ pluralise::pluralise( std::size_t count, std::string const& label )
+ : m_count( count ),
+ m_label( label )
+ {}
+
+ 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;
+ }
+
+ SourceLineInfo::SourceLineInfo() : line( 0 ){}
+ SourceLineInfo::SourceLineInfo( std::string const& _file, std::size_t _line )
+ : file( _file ),
+ line( _line )
+ {}
+ SourceLineInfo::SourceLineInfo( SourceLineInfo const& other )
+ : file( other.file ),
+ line( other.line )
+ {}
+ bool SourceLineInfo::empty() const {
+ return file.empty();
+ }
+ bool SourceLineInfo::operator == ( SourceLineInfo const& other ) const {
+ return line == other.line && file == other.file;
+ }
+
+ 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;
+ }
+
+ 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
+
diff --git a/include/internal/catch_config.hpp b/include/internal/catch_config.hpp
index 51b5913..30cd34b 100644
--- a/include/internal/catch_config.hpp
+++ b/include/internal/catch_config.hpp
@@ -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>
diff --git a/include/internal/catch_debugger.h b/include/internal/catch_debugger.h
new file mode 100644
index 0000000..0fb6621
--- /dev/null
+++ b/include/internal/catch_debugger.h
@@ -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
diff --git a/include/internal/catch_debugger.hpp b/include/internal/catch_debugger.hpp
index 9979dff..f3ad100 100644
--- a/include/internal/catch_debugger.hpp
+++ b/include/internal/catch_debugger.hpp
@@ -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(){
+ 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 {
+ 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 {
+ 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 {
+ 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 {
+ 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
diff --git a/include/internal/catch_impl.hpp b/include/internal/catch_impl.hpp
index 30ac219..0152235 100644
--- a/include/internal/catch_impl.hpp
+++ b/include/internal/catch_impl.hpp
@@ -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 @@
FreeFunctionTestCase::~FreeFunctionTestCase() {}
IGeneratorInfo::~IGeneratorInfo() {}
IGeneratorsForTest::~IGeneratorsForTest() {}
- TagParser::~TagParser() {}
- TagExtracter::~TagExtracter() {}
- TagExpressionParser::~TagExpressionParser() {}
Matchers::Impl::StdString::Equals::~Equals() {}
Matchers::Impl::StdString::Contains::~Contains() {}
diff --git a/include/internal/catch_interfaces_capture.h b/include/internal/catch_interfaces_capture.h
index 2601ab4..de779e0 100644
--- a/include/internal/catch_interfaces_capture.h
+++ b/include/internal/catch_interfaces_capture.h
@@ -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 @@
struct SectionInfo;
struct MessageInfo;
class ScopedMessageBuilder;
+ struct Counts;
struct IResultCapture {
diff --git a/include/internal/catch_interfaces_registry_hub.h b/include/internal/catch_interfaces_registry_hub.h
index 7fae3ab..b657183 100644
--- a/include/internal/catch_interfaces_registry_hub.h
+++ b/include/internal/catch_interfaces_registry_hub.h
@@ -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 @@
struct ITestCaseRegistry;
struct IExceptionTranslatorRegistry;
struct IExceptionTranslator;
+ struct IReporterRegistry;
+ struct IReporterFactory;
struct IRegistryHub {
virtual ~IRegistryHub();
diff --git a/include/internal/catch_interfaces_reporter.h b/include/internal/catch_interfaces_reporter.h
index 1de4778..eafaaa3 100644
--- a/include/internal/catch_interfaces_reporter.h
+++ b/include/internal/catch_interfaces_reporter.h
@@ -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 @@
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 @@
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 @@
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
diff --git a/include/internal/catch_interfaces_runner.h b/include/internal/catch_interfaces_runner.h
index ab127b9..6438f20 100644
--- a/include/internal/catch_interfaces_runner.h
+++ b/include/internal/catch_interfaces_runner.h
@@ -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;
diff --git a/include/internal/catch_legacy_reporter_adapter.h b/include/internal/catch_legacy_reporter_adapter.h
index 32d03f1..fb579c7 100644
--- a/include/internal/catch_legacy_reporter_adapter.h
+++ b/include/internal/catch_legacy_reporter_adapter.h
@@ -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:
diff --git a/include/internal/catch_list.hpp b/include/internal/catch_list.hpp
index 70d7668..1ee3d1f 100644
--- a/include/internal/catch_list.hpp
+++ b/include/internal/catch_list.hpp
@@ -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>
diff --git a/include/internal/catch_objc.hpp b/include/internal/catch_objc.hpp
index 45d64ba..85181f4 100644
--- a/include/internal/catch_objc.hpp
+++ b/include/internal/catch_objc.hpp
@@ -56,9 +56,6 @@
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 @@
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 );
diff --git a/include/internal/catch_section.h b/include/internal/catch_section.h
new file mode 100644
index 0000000..c1a81f6
--- /dev/null
+++ b/include/internal/catch_section.h
@@ -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
diff --git a/include/internal/catch_section.hpp b/include/internal/catch_section.hpp
index e58e72a..96fc832 100644
--- a/include/internal/catch_section.hpp
+++ b/include/internal/catch_section.hpp
@@ -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();
- }
+ 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() );
- }
+ 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
+ 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
diff --git a/include/internal/catch_section_info.h b/include/internal/catch_section_info.h
new file mode 100644
index 0000000..6bcc72a
--- /dev/null
+++ b/include/internal/catch_section_info.h
@@ -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
diff --git a/include/internal/catch_stream.h b/include/internal/catch_stream.h
new file mode 100644
index 0000000..70ddb58
--- /dev/null
+++ b/include/internal/catch_stream.h
@@ -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
diff --git a/include/internal/catch_stream.hpp b/include/internal/catch_stream.hpp
index eea576e..784ef86 100644
--- a/include/internal/catch_stream.hpp
+++ b/include/internal/catch_stream.hpp
@@ -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 @@
}
};
- class Stream {
- public:
- Stream()
- : streamBuf( NULL ), isOwned( false )
- {}
+ Stream::Stream()
+ : streamBuf( NULL ), isOwned( false )
+ {}
- Stream( std::streambuf* _streamBuf, bool _isOwned )
- : streamBuf( _streamBuf ), isOwned( _isOwned )
- {}
+ Stream::Stream( std::streambuf* _streamBuf, bool _isOwned )
+ : streamBuf( _streamBuf ), isOwned( _isOwned )
+ {}
- void release() {
- if( isOwned ) {
- delete streamBuf;
- streamBuf = NULL;
- isOwned = false;
- }
+ void Stream::release() {
+ if( isOwned ) {
+ delete streamBuf;
+ streamBuf = NULL;
+ isOwned = false;
}
-
- std::streambuf* streamBuf;
-
- private:
- bool isOwned;
- };
+ }
}
#endif // TWOBLUECUBES_CATCH_STREAM_HPP_INCLUDED
diff --git a/include/internal/catch_tags.h b/include/internal/catch_tags.h
new file mode 100644
index 0000000..8fd20b7
--- /dev/null
+++ b/include/internal/catch_tags.h
@@ -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
diff --git a/include/internal/catch_tags.hpp b/include/internal/catch_tags.hpp
index 36ecd1d..d02ed8d 100644
--- a/include/internal/catch_tags.hpp
+++ b/include/internal/catch_tags.hpp
@@ -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();
+ 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++;
- }
+ 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();
+ }
+
+ TagExtracter::TagExtracter( std::set<std::string>& tags )
+ : m_tags( tags )
+ {}
+
+ TagExtracter::~TagExtracter() {}
+
+ void TagExtracter::parse( std::string& description ) {
+ TagParser::parse( description );
+ description = m_remainder;
+ }
+
+ void TagExtracter::acceptTag( std::string const& tag ) {
+ m_tags.insert( toLower( tag ) );
+ }
+ void TagExtracter::acceptChar( char c ) {
+ m_remainder += c;
+ }
+
+ Tag::Tag() : m_isNegated( false ) {}
+ Tag::Tag( std::string const& name, bool isNegated )
+ : m_name( name ),
+ m_isNegated( isNegated )
+ {}
+
+ std::string Tag::getName() const {
+ return m_name;
+ }
+ bool Tag::isNegated() const {
+ return m_isNegated;
+ }
+
+ bool Tag::operator ! () const {
+ return m_name.empty();
+ }
+
+
+ void TagSet::add( Tag const& tag ) {
+ m_tags.insert( std::make_pair( toLower( tag.getName() ), tag ) );
+ }
+
+ bool TagSet::empty() const {
+ return m_tags.empty();
+ }
+
+ 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;
+ }
+
+
+ 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;
+ }
+
+ TagExpressionParser::TagExpressionParser( TagExpression& exp )
+ : m_isNegated( false ),
+ m_exp( exp )
+ {}
+
+ TagExpressionParser::~TagExpressionParser() {}
+
+ void TagExpressionParser::acceptTag( std::string const& tag ) {
+ m_currentTagSet.add( Tag( tag, m_isNegated ) );
+ m_isNegated = false;
+ }
+
+ 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;
- };
+ void TagExpressionParser::endParse() {
+ if( !m_currentTagSet.empty() )
+ m_exp.m_tagSets.push_back( m_currentTagSet );
+ }
} // end namespace Catch
diff --git a/include/internal/catch_test_case_info.hpp b/include/internal/catch_test_case_info.hpp
index 59fc39f..3d46320 100644
--- a/include/internal/catch_test_case_info.hpp
+++ b/include/internal/catch_test_case_info.hpp
@@ -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"
diff --git a/include/internal/catch_test_spec.h b/include/internal/catch_test_spec.h
index 05f877c..758f49e 100644
--- a/include/internal/catch_test_spec.h
+++ b/include/internal/catch_test_spec.h
@@ -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 @@
};
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 @@
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;
diff --git a/include/internal/catch_test_spec.hpp b/include/internal/catch_test_spec.hpp
new file mode 100644
index 0000000..6df01bc
--- /dev/null
+++ b/include/internal/catch_test_spec.hpp
@@ -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 {
+
+ 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 );
+ }
+ }
+
+ IfFilterMatches::DoWhat TestCaseFilter::getFilterType() const {
+ return m_filterType;
+ }
+
+ 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
+
+ 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
+
+ TestCaseFilters::TestCaseFilters( std::string const& name ) : m_name( name ) {}
+
+ std::string TestCaseFilters::getName() const {
+ return m_name;
+ }
+
+ void TestCaseFilters::addFilter( TestCaseFilter const& filter ) {
+ if( filter.getFilterType() == IfFilterMatches::ExcludeTests )
+ m_exclusionFilters.push_back( filter );
+ else
+ m_inclusionFilters.push_back( filter );
+ }
+
+ void TestCaseFilters::addTags( std::string const& tagPattern ) {
+ TagExpression exp;
+ TagExpressionParser( exp ).parse( tagPattern );
+
+ m_tagExpressions.push_back( exp );
+ }
+
+ 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
diff --git a/include/reporters/catch_reporter_bases.hpp b/include/reporters/catch_reporter_bases.hpp
new file mode 100644
index 0000000..a109d86
--- /dev/null
+++ b/include/reporters/catch_reporter_bases.hpp
@@ -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
diff --git a/include/reporters/catch_reporter_console.hpp b/include/reporters/catch_reporter_console.hpp
index 17b07a7..60ada64 100644
--- a/include/reporters/catch_reporter_console.hpp
+++ b/include/reporters/catch_reporter_console.hpp
@@ -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"
diff --git a/include/reporters/catch_reporter_junit.hpp b/include/reporters/catch_reporter_junit.hpp
index c9cf929..db12635 100644
--- a/include/reporters/catch_reporter_junit.hpp
+++ b/include/reporters/catch_reporter_junit.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"
diff --git a/include/reporters/catch_reporter_xml.hpp b/include/reporters/catch_reporter_xml.hpp
index 4c8095e..11ecd91 100644
--- a/include/reporters/catch_reporter_xml.hpp
+++ b/include/reporters/catch_reporter_xml.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"
diff --git a/projects/SelfTest/SurrogateCpps/catch_debugger.cpp b/projects/SelfTest/SurrogateCpps/catch_debugger.cpp
index f6b39f5..33f76ae 100644
--- a/projects/SelfTest/SurrogateCpps/catch_debugger.cpp
+++ b/projects/SelfTest/SurrogateCpps/catch_debugger.cpp
@@ -1,2 +1,2 @@
// This file is only here to verify (to the extent possible) the self sufficiency of the header
-#include "catch_debugger.hpp"
+#include "catch_debugger.h"
diff --git a/projects/SelfTest/SurrogateCpps/catch_stream.cpp b/projects/SelfTest/SurrogateCpps/catch_stream.cpp
index 43458de..9911aec 100644
--- a/projects/SelfTest/SurrogateCpps/catch_stream.cpp
+++ b/projects/SelfTest/SurrogateCpps/catch_stream.cpp
@@ -1,2 +1,2 @@
// This file is only here to verify (to the extent possible) the self sufficiency of the header
-#include "catch_stream.hpp"
+#include "catch_stream.h"
diff --git a/projects/SelfTest/SurrogateCpps/catch_tags.cpp b/projects/SelfTest/SurrogateCpps/catch_tags.cpp
index 63d1540..36e8789 100644
--- a/projects/SelfTest/SurrogateCpps/catch_tags.cpp
+++ b/projects/SelfTest/SurrogateCpps/catch_tags.cpp
@@ -1,2 +1,2 @@
// This file is only here to verify (to the extent possible) the self sufficiency of the header
-#include "catch_tags.hpp"
+#include "catch_tags.h"
diff --git a/projects/XCode4/CatchSelfTest/CatchSelfTest.xcodeproj/project.pbxproj b/projects/XCode4/CatchSelfTest/CatchSelfTest.xcodeproj/project.pbxproj
index 30b0b29..c6a13fb 100644
--- a/projects/XCode4/CatchSelfTest/CatchSelfTest.xcodeproj/project.pbxproj
+++ b/projects/XCode4/CatchSelfTest/CatchSelfTest.xcodeproj/project.pbxproj
@@ -56,6 +56,14 @@
/* End PBXCopyFilesBuildPhase section */
/* Begin PBXFileReference section */
+ 261488FA184C81130041FBEB /* catch_test_spec.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = catch_test_spec.hpp; sourceTree = "<group>"; };
+ 261488FB184C83EA0041FBEB /* catch_tags.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = catch_tags.h; sourceTree = "<group>"; };
+ 261488FC184D1DC10041FBEB /* catch_stream.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = catch_stream.h; sourceTree = "<group>"; };
+ 261488FD184D21290041FBEB /* catch_section_info.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = catch_section_info.h; sourceTree = "<group>"; };
+ 261488FE184DC32F0041FBEB /* catch_section.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = catch_section.h; sourceTree = "<group>"; };
+ 261488FF184DC4A20041FBEB /* catch_debugger.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = catch_debugger.h; sourceTree = "<group>"; };
+ 262E7399184673A800CAC268 /* catch_reporter_bases.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = catch_reporter_bases.hpp; sourceTree = "<group>"; };
+ 262E739A1846759000CAC268 /* catch_common.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = catch_common.hpp; sourceTree = "<group>"; };
263FD06017AF8DF200988A20 /* catch_timer.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = catch_timer.hpp; sourceTree = "<group>"; };
263FD06117AF8DF200988A20 /* catch_timer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = catch_timer.h; sourceTree = "<group>"; };
266B06B616F3A60A004ED264 /* VariadicMacrosTests.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = VariadicMacrosTests.cpp; path = ../../../SelfTest/VariadicMacrosTests.cpp; sourceTree = "<group>"; };
@@ -277,6 +285,7 @@
4A6D0C65149B3E3D00DB3EAA /* reporters */ = {
isa = PBXGroup;
children = (
+ 262E7399184673A800CAC268 /* catch_reporter_bases.hpp */,
4A6D0C67149B3E3D00DB3EAA /* catch_reporter_junit.hpp */,
4A6D0C68149B3E3D00DB3EAA /* catch_reporter_xml.hpp */,
4AB42F84166F3E1A0099F2C8 /* catch_reporter_console.hpp */,
@@ -314,6 +323,7 @@
4AC91CB4155B9EBF00DC5117 /* impl */ = {
isa = PBXGroup;
children = (
+ 261488FA184C81130041FBEB /* catch_test_spec.hpp */,
263FD06017AF8DF200988A20 /* catch_timer.hpp */,
266E9AD117230ACF0061DAB2 /* catch_text.hpp */,
4A4B0F9C15CEFA8300AE2392 /* catch_impl.hpp */,
@@ -341,6 +351,7 @@
4A6D0C5D149B3E3D00DB3EAA /* catch_assertionresult.h */,
4A9D84B315599AC900FBB209 /* catch_expressionresult_builder.h */,
4A6D0C5F149B3E3D00DB3EAA /* catch_section.hpp */,
+ 261488FE184DC32F0041FBEB /* catch_section.h */,
4A3D7DD01503869D005F9203 /* catch_matchers.hpp */,
4A9D84B11558FC0400FBB209 /* catch_tostring.hpp */,
4A6D0C46149B3E3D00DB3EAA /* catch_approx.hpp */,
@@ -349,6 +360,7 @@
4AC91CD0155D8DA600DC5117 /* catch_expression_decomposer.hpp */,
4A4B0F9A15CEF84800AE2392 /* catch_notimplemented_exception.h */,
26847E5B16BBAB790043B9C1 /* catch_message.h */,
+ 261488FD184D21290041FBEB /* catch_section_info.h */,
);
name = Assertions;
sourceTree = "<group>";
@@ -375,6 +387,7 @@
4A084F1D15DAD15F0027E631 /* catch_test_spec.h */,
4A8E4DCC160A344100194CBD /* catch_tags.hpp */,
26948287179EF7F900ED166E /* catch_test_case_tracker.hpp */,
+ 261488FB184C83EA0041FBEB /* catch_tags.h */,
);
name = "Test execution";
sourceTree = "<group>";
@@ -411,6 +424,7 @@
266ECD8D1713614B0030D735 /* catch_legacy_reporter_adapter.h */,
4A6D0C49149B3E3D00DB3EAA /* catch_common.h */,
4A6D0C4B149B3E3D00DB3EAA /* catch_debugger.hpp */,
+ 261488FF184DC4A20041FBEB /* catch_debugger.h */,
4A6D0C60149B3E3D00DB3EAA /* catch_stream.hpp */,
4A6D0C64149B3E3D00DB3EAA /* catch_xmlwriter.hpp */,
4AB1C73714F97C1300F31DF7 /* catch_console_colour.hpp */,
@@ -422,6 +436,8 @@
26DACF2F17206D3400A21326 /* catch_text.h */,
263FD06117AF8DF200988A20 /* catch_timer.h */,
26AEAF1617BEA18E009E32C9 /* catch_platform.h */,
+ 262E739A1846759000CAC268 /* catch_common.hpp */,
+ 261488FC184D1DC10041FBEB /* catch_stream.h */,
);
name = Infrastructure;
sourceTree = "<group>";
diff --git a/scripts/generateSingleHeader.py b/scripts/generateSingleHeader.py
index ba4c5cd..0f7aa9e 100644
--- a/scripts/generateSingleHeader.py
+++ b/scripts/generateSingleHeader.py
@@ -2,6 +2,7 @@
import sys
import re
import datetime
+import string
from scriptCommon import catchPath
@@ -9,6 +10,9 @@
includesParser = re.compile( r'\s*#include\s*"(.*)"' )
guardParser = re.compile( r'\s*#.*_INCLUDED')
defineParser = re.compile( r'\s*#define')
+ifParser = re.compile( r'\s*#if')
+endIfParser = re.compile( r'\s*#endif')
+ifImplParser = re.compile( r'\s*#if.*(CATCH_CONFIG_MAIN|CATCH_CONFIG_RUNNER)')
commentParser1 = re.compile( r'^\s*/\*')
commentParser2 = re.compile( r'^\s*\*')
blankParser = re.compile( r'^\s*$')
@@ -18,21 +22,48 @@
readmePath = os.path.join( catchPath, "README.md" )
outputPath = os.path.join( catchPath, 'single_include/catch.hpp' )
-bumpVersion = len(sys.argv) < 2 or sys.argv[1] <> "nobump"
+bumpVersion = True
+includeImpl = True
+
+for arg in sys.argv[1:]:
+ arg = string.lower(arg)
+ if arg == "nobump":
+ bumpVersion = False
+ print "Not bumping version number"
+ elif arg == "noimpl":
+ includeImpl = False
+ bumpVersion = False
+ print "Not including impl code (and not bumping version)"
+ else:
+ print "\n** Unrecognised argument: " + arg + " **\n"
+ exit(1)
out = open( outputPath, 'w' )
+ifdefs = 0
+implIfDefs = -1
+
+def write( line ):
+ if includeImpl or implIfDefs == -1:
+ out.write( line )
def parseFile( path, filename ):
+ global ifdefs
+ global implIfDefs
+
f = open( path + filename, 'r' )
blanks = 0
for line in f:
+ if ifParser.match( line ):
+ ifdefs = ifdefs + 1
+ elif endIfParser.match( line ):
+ ifdefs = ifdefs - 1
m = includesParser.match( line )
if m:
header = m.group(1)
headerPath, sep, headerFile = header.rpartition( "/" )
if not headerFile in seenHeaders:
seenHeaders.add( headerFile )
- out.write( "// #included from: {0}\n".format( header ) )
+ write( "// #included from: {0}\n".format( header ) )
if( headerPath == "internal" and path.endswith( "internal/" ) ):
headerPath = ""
sep = ""
@@ -40,13 +71,15 @@
parseFile( path + headerPath + sep, headerFile )
else:
parseFile( rootPath + headerPath + sep, headerFile )
+ elif ifImplParser.match(line):
+ implIfDefs = ifdefs
elif (not guardParser.match( line ) or defineParser.match( line ) ) and not commentParser1.match( line )and not commentParser2.match( line ):
if blankParser.match( line ):
blanks = blanks + 1
else:
blanks = 0
if blanks < 2:
- out.write( line.rstrip() + "\n" )
+ write( line.rstrip() + "\n" )
class Version:
def __init__(self):