mirror of
				https://github.com/catchorg/Catch2.git
				synced 2025-10-31 04:07: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_context.h" | ||||||
| #include "internal/catch_test_registry.hpp" | #include "internal/catch_test_registry.hpp" | ||||||
| #include "internal/catch_capture.hpp" | #include "internal/catch_capture.hpp" | ||||||
| #include "internal/catch_section.hpp" | #include "internal/catch_section.h" | ||||||
| #include "internal/catch_generators.hpp" | #include "internal/catch_generators.hpp" | ||||||
| #include "internal/catch_interfaces_exception.h" | #include "internal/catch_interfaces_exception.h" | ||||||
| #include "internal/catch_approx.hpp" | #include "internal/catch_approx.hpp" | ||||||
| @@ -39,11 +39,11 @@ | |||||||
|  |  | ||||||
| #if defined( CATCH_CONFIG_MAIN ) || defined( CATCH_CONFIG_RUNNER ) | #if defined( CATCH_CONFIG_MAIN ) || defined( CATCH_CONFIG_RUNNER ) | ||||||
| #include "internal/catch_impl.hpp" | #include "internal/catch_impl.hpp" | ||||||
| #endif | #endif // CATCH_CONFIG_MAIN || CATCH_CONFIG_RUNNER | ||||||
|  |  | ||||||
| #ifdef CATCH_CONFIG_MAIN | #ifdef CATCH_CONFIG_MAIN | ||||||
| #include "internal/catch_default_main.hpp" | #include "internal/catch_default_main.hpp" | ||||||
| #endif | #endif // CATCH_CONFIG_MAIN | ||||||
|  |  | ||||||
| ////// | ////// | ||||||
|  |  | ||||||
|   | |||||||
| @@ -12,11 +12,12 @@ | |||||||
| #include "catch_expressionresult_builder.h" | #include "catch_expressionresult_builder.h" | ||||||
| #include "catch_message.h" | #include "catch_message.h" | ||||||
| #include "catch_interfaces_capture.h" | #include "catch_interfaces_capture.h" | ||||||
| #include "catch_debugger.hpp" | #include "catch_debugger.h" | ||||||
| #include "catch_context.h" | #include "catch_context.h" | ||||||
| #include "catch_common.h" | #include "catch_common.h" | ||||||
| #include "catch_tostring.hpp" | #include "catch_tostring.hpp" | ||||||
| #include "catch_interfaces_registry_hub.h" | #include "catch_interfaces_registry_hub.h" | ||||||
|  | #include "catch_interfaces_config.h" | ||||||
| #include "internal/catch_compiler_capabilities.h" | #include "internal/catch_compiler_capabilities.h" | ||||||
|  |  | ||||||
| #include <ostream> | #include <ostream> | ||||||
| @@ -66,7 +67,7 @@ struct TestFailureException{}; | |||||||
| /////////////////////////////////////////////////////////////////////////////// | /////////////////////////////////////////////////////////////////////////////// | ||||||
| #define INTERNAL_CATCH_ACCEPT_EXPR( evaluatedExpr, resultDisposition, originalExpr ) \ | #define INTERNAL_CATCH_ACCEPT_EXPR( evaluatedExpr, resultDisposition, originalExpr ) \ | ||||||
|     if( Catch::ResultAction::Value internal_catch_action = Catch::getResultCapture().acceptExpression( evaluatedExpr, INTERNAL_CATCH_ASSERTIONINFO_NAME )  ) { \ |     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( internal_catch_action & Catch::ResultAction::Abort ) throw Catch::TestFailureException(); \ | ||||||
|         if( !Catch::shouldContinueOnFailure( resultDisposition ) ) throw Catch::TestFailureException(); \ |         if( !Catch::shouldContinueOnFailure( resultDisposition ) ) throw Catch::TestFailureException(); \ | ||||||
|         Catch::isTrue( false && originalExpr ); \ |         Catch::isTrue( false && originalExpr ); \ | ||||||
|   | |||||||
| @@ -67,36 +67,17 @@ namespace Catch { | |||||||
|         std::for_each( container.begin(), container.end(), function ); |         std::for_each( container.begin(), container.end(), function ); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     inline bool startsWith( std::string const& s, std::string const& prefix ) { |     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 ); | ||||||
|     } |     bool contains( std::string const& s, std::string const& infix ); | ||||||
|     inline bool endsWith( std::string const& s, std::string const& suffix ) { |     void toLowerInPlace( std::string& s ); | ||||||
|         return s.size() >= suffix.size() && s.substr( s.size()-suffix.size(), suffix.size() ) == suffix; |     std::string toLower( std::string const& s ); | ||||||
|     } |     std::string trim( std::string const& str ); | ||||||
|     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; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     struct pluralise { |     struct pluralise { | ||||||
|         pluralise( std::size_t count, std::string const& label ) |         pluralise( std::size_t count, std::string const& label ); | ||||||
|         :   m_count( count ), |  | ||||||
|             m_label( label ) |  | ||||||
|         {} |  | ||||||
|  |  | ||||||
|         friend std::ostream& operator << ( std::ostream& os, pluralise const& pluraliser ) { |         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; |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         std::size_t m_count; |         std::size_t m_count; | ||||||
|         std::string m_label; |         std::string m_label; | ||||||
| @@ -104,43 +85,22 @@ namespace Catch { | |||||||
|  |  | ||||||
|     struct SourceLineInfo { |     struct SourceLineInfo { | ||||||
|  |  | ||||||
|         SourceLineInfo() : line( 0 ){} |         SourceLineInfo(); | ||||||
|         SourceLineInfo( std::string const& _file, std::size_t _line ) |         SourceLineInfo( std::string const& _file, std::size_t _line ); | ||||||
|         :   file( _file ), |         SourceLineInfo( SourceLineInfo const& other ); | ||||||
|             line( _line ) |         bool empty() const; | ||||||
|         {} |         bool operator == ( SourceLineInfo const& other ) const; | ||||||
|         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; |  | ||||||
|         } |  | ||||||
|         std::string file; |         std::string file; | ||||||
|         std::size_t line; |         std::size_t line; | ||||||
|     }; |     }; | ||||||
|  |  | ||||||
|     inline std::ostream& operator << ( std::ostream& os, SourceLineInfo const& info ) { |     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; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     // This is just here to avoid compiler warnings with macro constants and boolean literals |     // This is just here to avoid compiler warnings with macro constants and boolean literals | ||||||
|     inline bool isTrue( bool value ){ return value; } |     inline bool isTrue( bool value ){ return value; } | ||||||
|  |  | ||||||
|     inline void throwLogicError( std::string const& message, SourceLineInfo const& locationInfo ) { |     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() ); |  | ||||||
|     } |  | ||||||
| } | } | ||||||
|  |  | ||||||
| #define CATCH_INTERNAL_LINEINFO ::Catch::SourceLineInfo( __FILE__, static_cast<std::size_t>( __LINE__ ) ) | #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_test_spec.h" | ||||||
| #include "catch_context.h" | #include "catch_context.h" | ||||||
| #include "catch_interfaces_config.h" | #include "catch_interfaces_config.h" | ||||||
| #include "catch_stream.hpp" | #include "catch_stream.h" | ||||||
|  |  | ||||||
| #include <memory> | #include <memory> | ||||||
| #include <vector> | #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 |  *  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) |  *  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 | #ifndef TWOBLUECUBES_CATCH_DEBUGGER_HPP_INCLUDED | ||||||
| #define 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 | #ifdef CATCH_PLATFORM_MAC | ||||||
|  |  | ||||||
| @@ -29,7 +28,7 @@ | |||||||
|  |  | ||||||
|         // Returns true if the current process is being debugged (either |         // Returns true if the current process is being debugged (either | ||||||
|         // running under the debugger or has a debugger attached post facto). |         // running under the debugger or has a debugger attached post facto). | ||||||
|         inline bool isDebuggerActive(){ |         bool isDebuggerActive(){ | ||||||
|  |  | ||||||
|             int                 junk; |             int                 junk; | ||||||
|             int                 mib[4]; |             int                 mib[4]; | ||||||
| @@ -59,52 +58,42 @@ | |||||||
|  |  | ||||||
|             return ( (info.kp_proc.p_flag & P_TRACED) != 0 ); |             return ( (info.kp_proc.p_flag & P_TRACED) != 0 ); | ||||||
|         } |         } | ||||||
|     } |     } // namespace Catch | ||||||
|  |  | ||||||
|     // 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 |  | ||||||
|  |  | ||||||
| #elif defined(_MSC_VER) | #elif defined(_MSC_VER) | ||||||
|     extern "C" __declspec(dllimport) int __stdcall IsDebuggerPresent(); |     extern "C" __declspec(dllimport) int __stdcall IsDebuggerPresent(); | ||||||
|     #define BreakIntoDebugger() if (IsDebuggerPresent() ) { __debugbreak(); } |     namespace Catch { | ||||||
|     inline bool isDebuggerActive() { |         bool isDebuggerActive() { | ||||||
|         return IsDebuggerPresent() != 0; |             return IsDebuggerPresent() != 0; | ||||||
|  |         } | ||||||
|     } |     } | ||||||
| #elif defined(__MINGW32__) | #elif defined(__MINGW32__) | ||||||
|     extern "C" __declspec(dllimport) int __stdcall IsDebuggerPresent(); |     extern "C" __declspec(dllimport) int __stdcall IsDebuggerPresent(); | ||||||
|     extern "C" __declspec(dllimport) void __stdcall DebugBreak(); |     namespace Catch { | ||||||
|     #define BreakIntoDebugger() if (IsDebuggerPresent() ) { DebugBreak(); } |         bool isDebuggerActive() { | ||||||
|     inline bool isDebuggerActive() { |             return IsDebuggerPresent() != 0; | ||||||
|         return IsDebuggerPresent() != 0; |         } | ||||||
|     } |     } | ||||||
| #else | #else | ||||||
|        inline void BreakIntoDebugger(){} |     namespace Catch { | ||||||
|        inline bool isDebuggerActive() { return false; } |        inline bool isDebuggerActive() { return false; } | ||||||
| #endif |     } | ||||||
|  | #endif // Platform | ||||||
|  |  | ||||||
| #ifdef CATCH_PLATFORM_WINDOWS | #ifdef CATCH_PLATFORM_WINDOWS | ||||||
| extern "C" __declspec(dllimport) void __stdcall OutputDebugStringA( const char* ); |     extern "C" __declspec(dllimport) void __stdcall OutputDebugStringA( const char* ); | ||||||
| inline void writeToDebugConsole( std::string const& text ) { |     namespace Catch { | ||||||
|     ::OutputDebugStringA( text.c_str() ); |         void writeToDebugConsole( std::string const& text ) { | ||||||
| } |             ::OutputDebugStringA( text.c_str() ); | ||||||
|  |         } | ||||||
|  |     } | ||||||
| #else | #else | ||||||
| inline void writeToDebugConsole( std::string const& text ) { |     namespace Catch { | ||||||
|     // !TBD: Need a version for Mac/ XCode and other IDEs |         void writeToDebugConsole( std::string const& text ) { | ||||||
|     std::cout << text; |             // !TBD: Need a version for Mac/ XCode and other IDEs | ||||||
| } |             std::cout << text; | ||||||
| #endif // CATCH_PLATFORM_WINDOWS |         } | ||||||
|  |     } | ||||||
|  | #endif // Platform | ||||||
|  |  | ||||||
| #endif // TWOBLUECUBES_CATCH_DEBUGGER_HPP_INCLUDED | #endif // TWOBLUECUBES_CATCH_DEBUGGER_HPP_INCLUDED | ||||||
|   | |||||||
| @@ -26,11 +26,15 @@ | |||||||
| #include "catch_expressionresult_builder.hpp" | #include "catch_expressionresult_builder.hpp" | ||||||
| #include "catch_test_case_info.hpp" | #include "catch_test_case_info.hpp" | ||||||
| #include "catch_tags.hpp" | #include "catch_tags.hpp" | ||||||
|  | #include "catch_test_spec.hpp" | ||||||
| #include "catch_version.hpp" | #include "catch_version.hpp" | ||||||
| #include "catch_text.hpp" | #include "catch_text.hpp" | ||||||
| #include "catch_message.hpp" | #include "catch_message.hpp" | ||||||
| #include "catch_legacy_reporter_adapter.hpp" | #include "catch_legacy_reporter_adapter.hpp" | ||||||
| #include "catch_timer.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_xml.hpp" | ||||||
| #include "../reporters/catch_reporter_junit.hpp" | #include "../reporters/catch_reporter_junit.hpp" | ||||||
| @@ -71,9 +75,6 @@ namespace Catch { | |||||||
|     FreeFunctionTestCase::~FreeFunctionTestCase() {} |     FreeFunctionTestCase::~FreeFunctionTestCase() {} | ||||||
|     IGeneratorInfo::~IGeneratorInfo() {} |     IGeneratorInfo::~IGeneratorInfo() {} | ||||||
|     IGeneratorsForTest::~IGeneratorsForTest() {} |     IGeneratorsForTest::~IGeneratorsForTest() {} | ||||||
|     TagParser::~TagParser() {} |  | ||||||
|     TagExtracter::~TagExtracter() {} |  | ||||||
|     TagExpressionParser::~TagExpressionParser() {} |  | ||||||
|  |  | ||||||
|     Matchers::Impl::StdString::Equals::~Equals() {} |     Matchers::Impl::StdString::Equals::~Equals() {} | ||||||
|     Matchers::Impl::StdString::Contains::~Contains() {} |     Matchers::Impl::StdString::Contains::~Contains() {} | ||||||
|   | |||||||
| @@ -10,7 +10,6 @@ | |||||||
|  |  | ||||||
| #include <string> | #include <string> | ||||||
| #include "catch_result_type.h" | #include "catch_result_type.h" | ||||||
| #include "catch_totals.hpp" |  | ||||||
| #include "catch_common.h" | #include "catch_common.h" | ||||||
|  |  | ||||||
| namespace Catch { | namespace Catch { | ||||||
| @@ -22,6 +21,7 @@ namespace Catch { | |||||||
|     struct SectionInfo; |     struct SectionInfo; | ||||||
|     struct MessageInfo; |     struct MessageInfo; | ||||||
|     class ScopedMessageBuilder; |     class ScopedMessageBuilder; | ||||||
|  |     struct Counts; | ||||||
|  |  | ||||||
|     struct IResultCapture { |     struct IResultCapture { | ||||||
|  |  | ||||||
|   | |||||||
| @@ -8,10 +8,7 @@ | |||||||
| #ifndef TWOBLUECUBES_CATCH_INTERFACES_REGISTRY_HUB_H_INCLUDED | #ifndef TWOBLUECUBES_CATCH_INTERFACES_REGISTRY_HUB_H_INCLUDED | ||||||
| #define TWOBLUECUBES_CATCH_INTERFACES_REGISTRY_HUB_H_INCLUDED | #define TWOBLUECUBES_CATCH_INTERFACES_REGISTRY_HUB_H_INCLUDED | ||||||
|  |  | ||||||
| #include "catch_interfaces_reporter.h" | #include <string> | ||||||
| #include "catch_interfaces_config.h" |  | ||||||
|  |  | ||||||
| #include <vector> |  | ||||||
|  |  | ||||||
| namespace Catch { | namespace Catch { | ||||||
|  |  | ||||||
| @@ -19,6 +16,8 @@ namespace Catch { | |||||||
|     struct ITestCaseRegistry; |     struct ITestCaseRegistry; | ||||||
|     struct IExceptionTranslatorRegistry; |     struct IExceptionTranslatorRegistry; | ||||||
|     struct IExceptionTranslator; |     struct IExceptionTranslator; | ||||||
|  |     struct IReporterRegistry; | ||||||
|  |     struct IReporterFactory; | ||||||
|  |  | ||||||
|     struct IRegistryHub { |     struct IRegistryHub { | ||||||
|         virtual ~IRegistryHub(); |         virtual ~IRegistryHub(); | ||||||
|   | |||||||
| @@ -8,6 +8,7 @@ | |||||||
| #ifndef TWOBLUECUBES_CATCH_INTERFACES_REPORTER_H_INCLUDED | #ifndef TWOBLUECUBES_CATCH_INTERFACES_REPORTER_H_INCLUDED | ||||||
| #define TWOBLUECUBES_CATCH_INTERFACES_REPORTER_H_INCLUDED | #define TWOBLUECUBES_CATCH_INTERFACES_REPORTER_H_INCLUDED | ||||||
|  |  | ||||||
|  | #include "catch_section_info.h" | ||||||
| #include "catch_common.h" | #include "catch_common.h" | ||||||
| #include "catch_totals.hpp" | #include "catch_totals.hpp" | ||||||
| #include "catch_ptr.hpp" | #include "catch_ptr.hpp" | ||||||
| @@ -80,20 +81,6 @@ namespace Catch | |||||||
|         std::size_t groupsCounts; |         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 { |     struct AssertionStats { | ||||||
|         AssertionStats( AssertionResult const& _assertionResult, |         AssertionStats( AssertionResult const& _assertionResult, | ||||||
|                         std::vector<MessageInfo> const& _infoMessages, |                         std::vector<MessageInfo> const& _infoMessages, | ||||||
| @@ -223,201 +210,6 @@ namespace Catch | |||||||
|         virtual void testRunEnded( TestRunStats const& testRunStats ) = 0; |         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 { |     struct IReporterFactory { | ||||||
|         virtual ~IReporterFactory(); |         virtual ~IReporterFactory(); | ||||||
| @@ -433,13 +225,6 @@ namespace Catch | |||||||
|         virtual FactoryMap const& getFactories() const = 0; |         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 | #endif // TWOBLUECUBES_CATCH_INTERFACES_REPORTER_H_INCLUDED | ||||||
|   | |||||||
| @@ -8,10 +8,6 @@ | |||||||
| #ifndef TWOBLUECUBES_CATCH_INTERFACES_RUNNER_H_INCLUDED | #ifndef TWOBLUECUBES_CATCH_INTERFACES_RUNNER_H_INCLUDED | ||||||
| #define TWOBLUECUBES_CATCH_INTERFACES_RUNNER_H_INCLUDED | #define TWOBLUECUBES_CATCH_INTERFACES_RUNNER_H_INCLUDED | ||||||
|  |  | ||||||
| #include "catch_totals.hpp" |  | ||||||
|  |  | ||||||
| #include <string> |  | ||||||
|  |  | ||||||
| namespace Catch { | namespace Catch { | ||||||
|     class TestCase; |     class TestCase; | ||||||
|  |  | ||||||
|   | |||||||
| @@ -12,6 +12,26 @@ | |||||||
|  |  | ||||||
| namespace Catch | 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> |     class LegacyReporterAdapter : public SharedImpl<IStreamingReporter> | ||||||
|     { |     { | ||||||
|     public: |     public: | ||||||
|   | |||||||
| @@ -11,6 +11,7 @@ | |||||||
| #include "catch_commandline.hpp" | #include "catch_commandline.hpp" | ||||||
| #include "catch_text.h" | #include "catch_text.h" | ||||||
| #include "catch_console_colour.hpp" | #include "catch_console_colour.hpp" | ||||||
|  | #include "catch_interfaces_reporter.h" | ||||||
|  |  | ||||||
| #include <limits> | #include <limits> | ||||||
| #include <algorithm> | #include <algorithm> | ||||||
|   | |||||||
| @@ -56,9 +56,6 @@ namespace Catch { | |||||||
|  |  | ||||||
|     namespace Detail{ |     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, |         inline std::string getAnnotation(   Class cls, | ||||||
|                                             std::string const& annotationName, |                                             std::string const& annotationName, | ||||||
| @@ -88,7 +85,7 @@ namespace Catch { | |||||||
|                 for( u_int m = 0; m < count ; m++ ) { |                 for( u_int m = 0; m < count ; m++ ) { | ||||||
|                     SEL selector = method_getName(methods[m]); |                     SEL selector = method_getName(methods[m]); | ||||||
|                     std::string methodName = sel_getName(selector); |                     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 testCaseName = methodName.substr( 15 ); | ||||||
|                         std::string name = Detail::getAnnotation( cls, "Name", testCaseName ); |                         std::string name = Detail::getAnnotation( cls, "Name", testCaseName ); | ||||||
|                         std::string desc = Detail::getAnnotation( cls, "Description", 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 | #ifndef TWOBLUECUBES_CATCH_SECTION_HPP_INCLUDED | ||||||
| #define TWOBLUECUBES_CATCH_SECTION_HPP_INCLUDED | #define TWOBLUECUBES_CATCH_SECTION_HPP_INCLUDED | ||||||
|  |  | ||||||
|  | #include "catch_section.h" | ||||||
| #include "catch_capture.hpp" | #include "catch_capture.hpp" | ||||||
| #include "catch_totals.hpp" |  | ||||||
| #include "catch_compiler_capabilities.h" | #include "catch_compiler_capabilities.h" | ||||||
| #include "catch_timer.h" | #include "catch_timer.h" | ||||||
|  |  | ||||||
| #include <string> |  | ||||||
|  |  | ||||||
| namespace Catch { | namespace Catch { | ||||||
|  |  | ||||||
|     class Section { |     Section::Section(   SourceLineInfo const& lineInfo, | ||||||
|     public: |                         std::string const& name, | ||||||
|         Section(    SourceLineInfo const& lineInfo, |                         std::string const& description ) | ||||||
|                     std::string const& name, |     :   m_info( name, description, lineInfo ), | ||||||
|                     std::string const& description = "" ) |         m_sectionIncluded( getCurrentContext().getResultCapture().sectionStarted( m_info, m_assertions ) ) | ||||||
|         :   m_info( name, description, lineInfo ), |     { | ||||||
|             m_sectionIncluded( getCurrentContext().getResultCapture().sectionStarted( m_info, m_assertions ) ) |         m_timer.start(); | ||||||
|         { |     } | ||||||
|             m_timer.start(); |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         ~Section() { |     Section::~Section() { | ||||||
|             if( m_sectionIncluded ) |         if( m_sectionIncluded ) | ||||||
|                 getCurrentContext().getResultCapture().sectionEnded( m_info, m_assertions, m_timer.getElapsedSeconds() ); |             getCurrentContext().getResultCapture().sectionEnded( m_info, m_assertions, m_timer.getElapsedSeconds() ); | ||||||
|         } |     } | ||||||
|  |  | ||||||
|         // This indicates whether the section should be executed or not |     // This indicates whether the section should be executed or not | ||||||
|         operator bool() { |     Section::operator bool() { | ||||||
|             return m_sectionIncluded; |         return m_sectionIncluded; | ||||||
|         } |     } | ||||||
|  |  | ||||||
|     private: |  | ||||||
|         SectionInfo m_info; |  | ||||||
|  |  | ||||||
|         std::string m_name; |  | ||||||
|         Counts m_assertions; |  | ||||||
|         bool m_sectionIncluded; |  | ||||||
|         Timer m_timer; |  | ||||||
|     }; |  | ||||||
|  |  | ||||||
| } // end namespace Catch | } // 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 | #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 | #ifndef TWOBLUECUBES_CATCH_STREAM_HPP_INCLUDED | ||||||
| #define TWOBLUECUBES_CATCH_STREAM_HPP_INCLUDED | #define TWOBLUECUBES_CATCH_STREAM_HPP_INCLUDED | ||||||
|  |  | ||||||
|  | #include "catch_stream.h" | ||||||
| #include "catch_streambuf.h" | #include "catch_streambuf.h" | ||||||
| #include "catch_debugger.hpp" | #include "catch_debugger.h" | ||||||
|  |  | ||||||
| #include <stdexcept> | #include <stdexcept> | ||||||
| #include <cstdio> | #include <cstdio> | ||||||
| @@ -62,29 +63,21 @@ namespace Catch { | |||||||
|         } |         } | ||||||
|     }; |     }; | ||||||
|  |  | ||||||
|     class Stream { |     Stream::Stream() | ||||||
|     public: |     : streamBuf( NULL ), isOwned( false ) | ||||||
|         Stream() |     {} | ||||||
|         : streamBuf( NULL ), isOwned( false ) |  | ||||||
|         {} |  | ||||||
|  |  | ||||||
|         Stream( std::streambuf* _streamBuf, bool _isOwned ) |     Stream::Stream( std::streambuf* _streamBuf, bool _isOwned ) | ||||||
|         : streamBuf( _streamBuf ), isOwned( _isOwned ) |     : streamBuf( _streamBuf ), isOwned( _isOwned ) | ||||||
|         {} |     {} | ||||||
|  |  | ||||||
|         void release() { |     void Stream::release() { | ||||||
|             if( isOwned ) { |         if( isOwned ) { | ||||||
|                 delete streamBuf; |             delete streamBuf; | ||||||
|                 streamBuf = NULL; |             streamBuf = NULL; | ||||||
|                 isOwned = false; |             isOwned = false; | ||||||
|             } |  | ||||||
|         } |         } | ||||||
|  |     } | ||||||
|         std::streambuf* streamBuf; |  | ||||||
|  |  | ||||||
|     private: |  | ||||||
|         bool isOwned; |  | ||||||
|     }; |  | ||||||
| } | } | ||||||
|  |  | ||||||
| #endif // TWOBLUECUBES_CATCH_STREAM_HPP_INCLUDED | #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 | #ifndef TWOBLUECUBES_CATCH_TAGS_HPP_INCLUDED | ||||||
| #define TWOBLUECUBES_CATCH_TAGS_HPP_INCLUDED | #define TWOBLUECUBES_CATCH_TAGS_HPP_INCLUDED | ||||||
|  |  | ||||||
| #include "catch_common.h" | #include "catch_tags.h" | ||||||
|  |  | ||||||
| #include <string> |  | ||||||
| #include <set> |  | ||||||
| #include <map> |  | ||||||
| #include <vector> |  | ||||||
|  |  | ||||||
| #ifdef __clang__ |  | ||||||
| #pragma clang diagnostic ignored "-Wpadded" |  | ||||||
| #endif |  | ||||||
|  |  | ||||||
| namespace Catch { | namespace Catch { | ||||||
|     class TagParser { |     TagParser::~TagParser() {} | ||||||
|     public: |  | ||||||
|         virtual ~TagParser(); |  | ||||||
|  |  | ||||||
|         void parse( std::string const& str ) { |     void TagParser::parse( std::string const& str ) { | ||||||
|             std::size_t pos = 0; |         std::size_t pos = 0; | ||||||
|             while( pos < str.size() ) { |         while( pos < str.size() ) { | ||||||
|                 char c = str[pos]; |             char c = str[pos]; | ||||||
|                 if( c == '[' ) { |             if( c == '[' ) { | ||||||
|                     std::size_t end = str.find_first_of( ']', pos ); |                 std::size_t end = str.find_first_of( ']', pos ); | ||||||
|                     if( end != std::string::npos ) { |                 if( end != std::string::npos ) { | ||||||
|                         acceptTag( str.substr( pos+1, end-pos-1 ) ); |                     acceptTag( str.substr( pos+1, end-pos-1 ) ); | ||||||
|                         pos = end+1; |                     pos = end+1; | ||||||
|                     } |  | ||||||
|                     else { |  | ||||||
|                         acceptChar( c ); |  | ||||||
|                         pos++; |  | ||||||
|                     } |  | ||||||
|                 } |                 } | ||||||
|                 else { |                 else { | ||||||
|                     acceptChar( c ); |                     acceptChar( c ); | ||||||
|                     pos++; |                     pos++; | ||||||
|                 } |                 } | ||||||
|             } |             } | ||||||
|             endParse(); |             else { | ||||||
|         } |                 acceptChar( c ); | ||||||
|  |                 pos++; | ||||||
|     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; |  | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|         virtual void endParse() { |         endParse(); | ||||||
|             if( !m_currentTagSet.empty() ) |     } | ||||||
|  |  | ||||||
|  |     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_exp.m_tagSets.push_back( m_currentTagSet ); | ||||||
|  |                 m_currentTagSet = TagSet(); | ||||||
|  |                 break; | ||||||
|         } |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|         TagExpressionParser& operator=(TagExpressionParser const&); |     void TagExpressionParser::endParse() { | ||||||
|  |         if( !m_currentTagSet.empty() ) | ||||||
|         bool m_isNegated; |             m_exp.m_tagSets.push_back( m_currentTagSet ); | ||||||
|         TagSet m_currentTagSet; |     } | ||||||
|         TagExpression& m_exp; |  | ||||||
|     }; |  | ||||||
|  |  | ||||||
| } // end namespace Catch | } // end namespace Catch | ||||||
|  |  | ||||||
|   | |||||||
| @@ -8,7 +8,7 @@ | |||||||
| #ifndef TWOBLUECUBES_CATCH_TEST_CASE_INFO_HPP_INCLUDED | #ifndef TWOBLUECUBES_CATCH_TEST_CASE_INFO_HPP_INCLUDED | ||||||
| #define 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_test_case_info.h" | ||||||
| #include "catch_interfaces_testcase.h" | #include "catch_interfaces_testcase.h" | ||||||
| #include "catch_common.h" | #include "catch_common.h" | ||||||
|   | |||||||
| @@ -8,15 +8,15 @@ | |||||||
| #ifndef TWOBLUECUBES_CATCH_TEST_SPEC_H_INCLUDED | #ifndef TWOBLUECUBES_CATCH_TEST_SPEC_H_INCLUDED | ||||||
| #define TWOBLUECUBES_CATCH_TEST_SPEC_H_INCLUDED | #define TWOBLUECUBES_CATCH_TEST_SPEC_H_INCLUDED | ||||||
|  |  | ||||||
| #include "catch_test_case_info.h" | #include "catch_tags.h" | ||||||
| #include "catch_tags.hpp" |  | ||||||
| #include "catch_common.h" |  | ||||||
|  |  | ||||||
| #include <string> | #include <string> | ||||||
| #include <vector> | #include <vector> | ||||||
|  |  | ||||||
| namespace Catch { | namespace Catch { | ||||||
|  |  | ||||||
|  |     class TestCase; | ||||||
|  |  | ||||||
|     struct IfFilterMatches{ enum DoWhat { |     struct IfFilterMatches{ enum DoWhat { | ||||||
|         AutoDetectBehaviour, |         AutoDetectBehaviour, | ||||||
|         IncludeTests, |         IncludeTests, | ||||||
| @@ -32,69 +32,13 @@ namespace Catch { | |||||||
|         }; |         }; | ||||||
|  |  | ||||||
|     public: |     public: | ||||||
|         TestCaseFilter( std::string const& testSpec, IfFilterMatches::DoWhat matchBehaviour = IfFilterMatches::AutoDetectBehaviour ) |         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; |  | ||||||
|                 } |  | ||||||
|             } |  | ||||||
|  |  | ||||||
|             if( startsWith( m_stringToMatch, "*" ) ) { |         IfFilterMatches::DoWhat getFilterType() const; | ||||||
|                 m_stringToMatch = m_stringToMatch.substr( 1 ); |         bool shouldInclude( TestCase const& testCase ) const; | ||||||
|                 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 { |  | ||||||
|             return m_filterType; |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         bool shouldInclude( TestCase const& testCase ) const { |  | ||||||
|             return isMatch( testCase ) == (m_filterType == IfFilterMatches::IncludeTests); |  | ||||||
|         } |  | ||||||
|     private: |     private: | ||||||
|  |         bool isMatch( TestCase const& testCase ) const; | ||||||
| #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 |  | ||||||
|  |  | ||||||
|         std::string m_stringToMatch; |         std::string m_stringToMatch; | ||||||
|         IfFilterMatches::DoWhat m_filterType; |         IfFilterMatches::DoWhat m_filterType; | ||||||
| @@ -103,57 +47,12 @@ namespace Catch { | |||||||
|  |  | ||||||
|     class TestCaseFilters { |     class TestCaseFilters { | ||||||
|     public: |     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: |     private: | ||||||
|         std::vector<TagExpression> m_tagExpressions; |         std::vector<TagExpression> m_tagExpressions; | ||||||
|         std::vector<TestCaseFilter> m_inclusionFilters; |         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 | #ifndef TWOBLUECUBES_CATCH_REPORTER_CONSOLE_HPP_INCLUDED | ||||||
| #define 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_reporter_registrars.hpp" | ||||||
| #include "../internal/catch_console_colour.hpp" | #include "../internal/catch_console_colour.hpp" | ||||||
|  |  | ||||||
|   | |||||||
| @@ -8,8 +8,9 @@ | |||||||
| #ifndef TWOBLUECUBES_CATCH_REPORTER_JUNIT_HPP_INCLUDED | #ifndef TWOBLUECUBES_CATCH_REPORTER_JUNIT_HPP_INCLUDED | ||||||
| #define 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_tostring.hpp" | ||||||
| #include "../internal/catch_interfaces_reporter.h" |  | ||||||
| #include "../internal/catch_reporter_registrars.hpp" | #include "../internal/catch_reporter_registrars.hpp" | ||||||
| #include "../internal/catch_xmlwriter.hpp" | #include "../internal/catch_xmlwriter.hpp" | ||||||
|  |  | ||||||
|   | |||||||
| @@ -8,8 +8,9 @@ | |||||||
| #ifndef TWOBLUECUBES_CATCH_REPORTER_XML_HPP_INCLUDED | #ifndef TWOBLUECUBES_CATCH_REPORTER_XML_HPP_INCLUDED | ||||||
| #define 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_capture.hpp" | ||||||
| #include "../internal/catch_interfaces_reporter.h" |  | ||||||
| #include "../internal/catch_reporter_registrars.hpp" | #include "../internal/catch_reporter_registrars.hpp" | ||||||
| #include "../internal/catch_xmlwriter.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 | // 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 | // 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 | // 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 */ | /* End PBXCopyFilesBuildPhase section */ | ||||||
|  |  | ||||||
| /* Begin PBXFileReference 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>"; }; | 		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>"; }; | 		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>"; }; | 		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 */ = { | 		4A6D0C65149B3E3D00DB3EAA /* reporters */ = { | ||||||
| 			isa = PBXGroup; | 			isa = PBXGroup; | ||||||
| 			children = ( | 			children = ( | ||||||
|  | 				262E7399184673A800CAC268 /* catch_reporter_bases.hpp */, | ||||||
| 				4A6D0C67149B3E3D00DB3EAA /* catch_reporter_junit.hpp */, | 				4A6D0C67149B3E3D00DB3EAA /* catch_reporter_junit.hpp */, | ||||||
| 				4A6D0C68149B3E3D00DB3EAA /* catch_reporter_xml.hpp */, | 				4A6D0C68149B3E3D00DB3EAA /* catch_reporter_xml.hpp */, | ||||||
| 				4AB42F84166F3E1A0099F2C8 /* catch_reporter_console.hpp */, | 				4AB42F84166F3E1A0099F2C8 /* catch_reporter_console.hpp */, | ||||||
| @@ -314,6 +323,7 @@ | |||||||
| 		4AC91CB4155B9EBF00DC5117 /* impl */ = { | 		4AC91CB4155B9EBF00DC5117 /* impl */ = { | ||||||
| 			isa = PBXGroup; | 			isa = PBXGroup; | ||||||
| 			children = ( | 			children = ( | ||||||
|  | 				261488FA184C81130041FBEB /* catch_test_spec.hpp */, | ||||||
| 				263FD06017AF8DF200988A20 /* catch_timer.hpp */, | 				263FD06017AF8DF200988A20 /* catch_timer.hpp */, | ||||||
| 				266E9AD117230ACF0061DAB2 /* catch_text.hpp */, | 				266E9AD117230ACF0061DAB2 /* catch_text.hpp */, | ||||||
| 				4A4B0F9C15CEFA8300AE2392 /* catch_impl.hpp */, | 				4A4B0F9C15CEFA8300AE2392 /* catch_impl.hpp */, | ||||||
| @@ -341,6 +351,7 @@ | |||||||
| 				4A6D0C5D149B3E3D00DB3EAA /* catch_assertionresult.h */, | 				4A6D0C5D149B3E3D00DB3EAA /* catch_assertionresult.h */, | ||||||
| 				4A9D84B315599AC900FBB209 /* catch_expressionresult_builder.h */, | 				4A9D84B315599AC900FBB209 /* catch_expressionresult_builder.h */, | ||||||
| 				4A6D0C5F149B3E3D00DB3EAA /* catch_section.hpp */, | 				4A6D0C5F149B3E3D00DB3EAA /* catch_section.hpp */, | ||||||
|  | 				261488FE184DC32F0041FBEB /* catch_section.h */, | ||||||
| 				4A3D7DD01503869D005F9203 /* catch_matchers.hpp */, | 				4A3D7DD01503869D005F9203 /* catch_matchers.hpp */, | ||||||
| 				4A9D84B11558FC0400FBB209 /* catch_tostring.hpp */, | 				4A9D84B11558FC0400FBB209 /* catch_tostring.hpp */, | ||||||
| 				4A6D0C46149B3E3D00DB3EAA /* catch_approx.hpp */, | 				4A6D0C46149B3E3D00DB3EAA /* catch_approx.hpp */, | ||||||
| @@ -349,6 +360,7 @@ | |||||||
| 				4AC91CD0155D8DA600DC5117 /* catch_expression_decomposer.hpp */, | 				4AC91CD0155D8DA600DC5117 /* catch_expression_decomposer.hpp */, | ||||||
| 				4A4B0F9A15CEF84800AE2392 /* catch_notimplemented_exception.h */, | 				4A4B0F9A15CEF84800AE2392 /* catch_notimplemented_exception.h */, | ||||||
| 				26847E5B16BBAB790043B9C1 /* catch_message.h */, | 				26847E5B16BBAB790043B9C1 /* catch_message.h */, | ||||||
|  | 				261488FD184D21290041FBEB /* catch_section_info.h */, | ||||||
| 			); | 			); | ||||||
| 			name = Assertions; | 			name = Assertions; | ||||||
| 			sourceTree = "<group>"; | 			sourceTree = "<group>"; | ||||||
| @@ -375,6 +387,7 @@ | |||||||
| 				4A084F1D15DAD15F0027E631 /* catch_test_spec.h */, | 				4A084F1D15DAD15F0027E631 /* catch_test_spec.h */, | ||||||
| 				4A8E4DCC160A344100194CBD /* catch_tags.hpp */, | 				4A8E4DCC160A344100194CBD /* catch_tags.hpp */, | ||||||
| 				26948287179EF7F900ED166E /* catch_test_case_tracker.hpp */, | 				26948287179EF7F900ED166E /* catch_test_case_tracker.hpp */, | ||||||
|  | 				261488FB184C83EA0041FBEB /* catch_tags.h */, | ||||||
| 			); | 			); | ||||||
| 			name = "Test execution"; | 			name = "Test execution"; | ||||||
| 			sourceTree = "<group>"; | 			sourceTree = "<group>"; | ||||||
| @@ -411,6 +424,7 @@ | |||||||
| 				266ECD8D1713614B0030D735 /* catch_legacy_reporter_adapter.h */, | 				266ECD8D1713614B0030D735 /* catch_legacy_reporter_adapter.h */, | ||||||
| 				4A6D0C49149B3E3D00DB3EAA /* catch_common.h */, | 				4A6D0C49149B3E3D00DB3EAA /* catch_common.h */, | ||||||
| 				4A6D0C4B149B3E3D00DB3EAA /* catch_debugger.hpp */, | 				4A6D0C4B149B3E3D00DB3EAA /* catch_debugger.hpp */, | ||||||
|  | 				261488FF184DC4A20041FBEB /* catch_debugger.h */, | ||||||
| 				4A6D0C60149B3E3D00DB3EAA /* catch_stream.hpp */, | 				4A6D0C60149B3E3D00DB3EAA /* catch_stream.hpp */, | ||||||
| 				4A6D0C64149B3E3D00DB3EAA /* catch_xmlwriter.hpp */, | 				4A6D0C64149B3E3D00DB3EAA /* catch_xmlwriter.hpp */, | ||||||
| 				4AB1C73714F97C1300F31DF7 /* catch_console_colour.hpp */, | 				4AB1C73714F97C1300F31DF7 /* catch_console_colour.hpp */, | ||||||
| @@ -422,6 +436,8 @@ | |||||||
| 				26DACF2F17206D3400A21326 /* catch_text.h */, | 				26DACF2F17206D3400A21326 /* catch_text.h */, | ||||||
| 				263FD06117AF8DF200988A20 /* catch_timer.h */, | 				263FD06117AF8DF200988A20 /* catch_timer.h */, | ||||||
| 				26AEAF1617BEA18E009E32C9 /* catch_platform.h */, | 				26AEAF1617BEA18E009E32C9 /* catch_platform.h */, | ||||||
|  | 				262E739A1846759000CAC268 /* catch_common.hpp */, | ||||||
|  | 				261488FC184D1DC10041FBEB /* catch_stream.h */, | ||||||
| 			); | 			); | ||||||
| 			name = Infrastructure; | 			name = Infrastructure; | ||||||
| 			sourceTree = "<group>"; | 			sourceTree = "<group>"; | ||||||
|   | |||||||
| @@ -2,6 +2,7 @@ import os | |||||||
| import sys | import sys | ||||||
| import re | import re | ||||||
| import datetime | import datetime | ||||||
|  | import string | ||||||
|  |  | ||||||
| from scriptCommon import catchPath | 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*"(.*)"' ) | includesParser = re.compile( r'\s*#include\s*"(.*)"' ) | ||||||
| guardParser = re.compile( r'\s*#.*_INCLUDED') | guardParser = re.compile( r'\s*#.*_INCLUDED') | ||||||
| defineParser = re.compile( r'\s*#define') | 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*/\*') | commentParser1 = re.compile( r'^\s*/\*') | ||||||
| commentParser2 = re.compile( r'^\s*\*') | commentParser2 = re.compile( r'^\s*\*') | ||||||
| blankParser = 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" ) | readmePath = os.path.join( catchPath, "README.md" ) | ||||||
| outputPath = os.path.join( catchPath, 'single_include/catch.hpp' ) | 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' ) | out = open( outputPath, 'w' ) | ||||||
|  | ifdefs = 0 | ||||||
|  | implIfDefs = -1 | ||||||
|  |  | ||||||
|  | def write( line ): | ||||||
|  | 	if includeImpl or implIfDefs == -1: | ||||||
|  | 		out.write( line ) | ||||||
|  |  | ||||||
| def parseFile( path, filename ): | def parseFile( path, filename ): | ||||||
|  | 	global ifdefs | ||||||
|  | 	global implIfDefs | ||||||
|  |  | ||||||
| 	f = open( path + filename, 'r' ) | 	f = open( path + filename, 'r' ) | ||||||
| 	blanks = 0 | 	blanks = 0 | ||||||
| 	for line in f: | 	for line in f: | ||||||
|  | 		if ifParser.match( line ): | ||||||
|  | 			ifdefs = ifdefs + 1 | ||||||
|  | 		elif endIfParser.match( line ): | ||||||
|  | 			ifdefs = ifdefs - 1 | ||||||
| 		m = includesParser.match( line ) | 		m = includesParser.match( line ) | ||||||
| 		if m: | 		if m: | ||||||
| 			header = m.group(1) | 			header = m.group(1) | ||||||
| 			headerPath, sep, headerFile = header.rpartition( "/" ) | 			headerPath, sep, headerFile = header.rpartition( "/" ) | ||||||
| 			if not headerFile in seenHeaders: | 			if not headerFile in seenHeaders: | ||||||
| 				seenHeaders.add( headerFile ) | 				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/" ) ): | 				if( headerPath == "internal" and path.endswith( "internal/" ) ): | ||||||
| 					headerPath = "" | 					headerPath = "" | ||||||
| 					sep = "" | 					sep = "" | ||||||
| @@ -40,13 +71,15 @@ def parseFile( path, filename ): | |||||||
| 					parseFile( path + headerPath + sep, headerFile ) | 					parseFile( path + headerPath + sep, headerFile ) | ||||||
| 				else: | 				else: | ||||||
| 					parseFile( rootPath + headerPath + sep, headerFile ) | 					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 ): | 		elif (not guardParser.match( line ) or defineParser.match( line ) ) and not commentParser1.match( line )and not commentParser2.match( line ): | ||||||
| 			if blankParser.match( line ): | 			if blankParser.match( line ): | ||||||
| 				blanks = blanks + 1 | 				blanks = blanks + 1 | ||||||
| 			else: | 			else: | ||||||
| 				blanks = 0 | 				blanks = 0 | ||||||
| 			if blanks < 2: | 			if blanks < 2: | ||||||
| 				out.write( line.rstrip() + "\n" ) | 				write( line.rstrip() + "\n" ) | ||||||
|  |  | ||||||
| class Version: | class Version: | ||||||
| 	def __init__(self): | 	def __init__(self): | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 Phil Nash
					Phil Nash