mirror of
				https://github.com/catchorg/Catch2.git
				synced 2025-10-30 19:57:10 +01:00 
			
		
		
		
	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
This commit is contained in:
		| @@ -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 | ||||
|  | ||||
| ////// | ||||
|  | ||||
|   | ||||
| @@ -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 @@ 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 ) throw Catch::TestFailureException(); \ | ||||
|         if( !Catch::shouldContinueOnFailure( resultDisposition ) ) throw Catch::TestFailureException(); \ | ||||
|         Catch::isTrue( false && originalExpr ); \ | ||||
|   | ||||
| @@ -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( 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__ ) ) | ||||
|   | ||||
							
								
								
									
										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 { | ||||
|  | ||||
|     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 | ||||
|  | ||||
| @@ -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> | ||||
|   | ||||
							
								
								
									
										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(){ | ||||
|         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 | ||||
|   | ||||
| @@ -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> | ||||
|   | ||||
| @@ -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(); | ||||
|         } | ||||
|     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 | ||||
|   | ||||
							
								
								
									
										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 ) | ||||
|         {} | ||||
|     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 | ||||
|   | ||||
							
								
								
									
										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(); | ||||
|     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 | ||||
|  | ||||
|   | ||||
| @@ -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" | ||||
|   | ||||
| @@ -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 { | ||||
|  | ||||
|     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 | ||||
							
								
								
									
										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" | ||||
|  | ||||
|   | ||||
| @@ -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" | ||||
|   | ||||
| @@ -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" | ||||
|   | ||||
| @@ -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" | ||||
|   | ||||
| @@ -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>"; | ||||
|   | ||||
| @@ -2,6 +2,7 @@ import os | ||||
| import sys | ||||
| import re | ||||
| import datetime | ||||
| import string | ||||
|  | ||||
| from scriptCommon import catchPath | ||||
|  | ||||
| @@ -9,6 +10,9 @@ versionParser = re.compile( r'(\s*Version\slibraryVersion)\s*\(\s*(.*)\s*,\s*(.* | ||||
| 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 @@ versionPath = os.path.join( rootPath, "internal/catch_version.hpp" ) | ||||
| 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 @@ def parseFile( path, filename ): | ||||
| 					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): | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Phil Nash
					Phil Nash