mirror of
				https://github.com/catchorg/Catch2.git
				synced 2025-10-31 12:17:11 +01:00 
			
		
		
		
	Added StringMaker (for partially specialising string conversions), extended BDD macros and moved file/line info to top of message.
Re-enable ANSI colour by default - hopefully properly excluding Windows this time
This commit is contained in:
		| @@ -10,6 +10,10 @@ | ||||
|  | ||||
| #include "catch_console_colour.hpp" | ||||
|  | ||||
| #if !defined(CATCH_CONFIG_USE_ANSI_COLOUR_CODES) && !defined(CATCH_PLATFORM_WINDOWS) | ||||
| #define CATCH_CONFIG_USE_ANSI_COLOUR_CODES 1 | ||||
| #endif | ||||
|  | ||||
| #if defined( CATCH_CONFIG_USE_ANSI_COLOUR_CODES ) | ||||
|  | ||||
| #include <unistd.h> | ||||
| @@ -31,8 +35,15 @@ namespace Catch { | ||||
|  | ||||
|     namespace { const char colourEscape = '\033'; } | ||||
|  | ||||
|     inline bool shouldUseColour() { | ||||
|         static bool s_shouldUseColour | ||||
|             =   CATCH_CONFIG_USE_ANSI_COLOUR_CODES != 0 && | ||||
|                 isatty( fileno(stdout) ) && | ||||
|                 !isDebuggerActive(); | ||||
|         return s_shouldUseColour; | ||||
|     } | ||||
|     void TextColour::set( Colours colour ) { | ||||
|         if( isatty( fileno(stdout) ) && !isDebuggerActive() ) { | ||||
|         if( shouldUseColour() ) { | ||||
|             switch( colour ) { | ||||
|                 case TextColour::FileName: | ||||
|                     std::cout << colourEscape << "[0m";    // white/ normal | ||||
|   | ||||
| @@ -82,12 +82,10 @@ namespace Catch { | ||||
|         else if( m_exprComponents.op == "matches" ) | ||||
|             return m_exprComponents.lhs + " " + m_exprComponents.rhs; | ||||
|         else if( m_exprComponents.op != "!" ) { | ||||
|             if( m_exprComponents.lhs.size() + m_exprComponents.rhs.size() < 30 ) | ||||
|             if( m_exprComponents.lhs.size() + m_exprComponents.rhs.size() < 40 ) | ||||
|                 return m_exprComponents.lhs + " " + m_exprComponents.op + " " + m_exprComponents.rhs; | ||||
|             else if( m_exprComponents.lhs.size() < 70 && m_exprComponents.rhs.size() < 70 ) | ||||
|                 return "\n\t" + m_exprComponents.lhs + "\n\t" + m_exprComponents.op + "\n\t" + m_exprComponents.rhs; | ||||
|             else | ||||
|                 return "\n" + m_exprComponents.lhs + "\n" + m_exprComponents.op + "\n" + m_exprComponents.rhs + "\n\n"; | ||||
|                 return m_exprComponents.lhs + "\n" + m_exprComponents.op + "\n" + m_exprComponents.rhs; | ||||
|         } | ||||
|         else | ||||
|             return "{can't expand - use " + info.macroName + "_FALSE( " + info.capturedExpression.substr(1) + " ) instead of " + info.macroName + "( " + info.capturedExpression + " ) for better diagnostics}"; | ||||
|   | ||||
| @@ -216,7 +216,7 @@ namespace Catch { | ||||
|                 missingAssertions = true; | ||||
|  | ||||
|             } | ||||
|             m_runningTest->endSection( info.name ); | ||||
|             m_runningTest->endSection( info.name, false ); | ||||
|  | ||||
|             m_reporter->sectionEnded( SectionStats( info, assertions, missingAssertions ) ); | ||||
|             m_messages.clear(); | ||||
|   | ||||
| @@ -78,13 +78,15 @@ namespace Catch { | ||||
|             return false; | ||||
|         } | ||||
|          | ||||
|         void endSection( const std::string& ) { | ||||
|         void endSection( const std::string&, bool stealth ) { | ||||
|             if( m_currentSection->ran() ) { | ||||
|                 m_runStatus = RanAtLeastOneSection; | ||||
|                 if( !stealth ) | ||||
|                     m_runStatus = RanAtLeastOneSection; | ||||
|                 m_changed = true; | ||||
|             } | ||||
|             else if( m_runStatus == EncounteredASection ) { | ||||
|                 m_runStatus = RanAtLeastOneSection; | ||||
|                 if( !stealth ) | ||||
|                     m_runStatus = RanAtLeastOneSection; | ||||
|                 m_lastSectionToRun = m_currentSection; | ||||
|             } | ||||
|             m_currentSection = m_currentSection->getParent(); | ||||
|   | ||||
| @@ -10,6 +10,8 @@ | ||||
|  | ||||
| #include "catch_common.h" | ||||
| #include <sstream> | ||||
| #include <iomanip> | ||||
| #include <limits> | ||||
|  | ||||
| #ifdef __OBJC__ | ||||
| #include "catch_objc_arc.hpp" | ||||
| @@ -22,37 +24,53 @@ namespace Detail { | ||||
|         template<typename T> NonStreamable( const T& ){} | ||||
|     }; | ||||
|      | ||||
|     // If the type does not have its own << overload for ostream then | ||||
|     // this one will be used instead | ||||
|     inline std::ostream& operator << ( std::ostream& ss, NonStreamable ){ | ||||
|         return ss << "{?}"; | ||||
|     } | ||||
|      | ||||
|     template<typename T> | ||||
|     inline std::string makeString( const T& value ) { | ||||
| } // end namespace Detail | ||||
|  | ||||
| // If the type does not have its own << overload for ostream then | ||||
| // this one will be used instead | ||||
| inline std::ostream& operator << ( std::ostream& ss, Detail::NonStreamable ){ | ||||
|     return ss << "{?}"; | ||||
| } | ||||
|  | ||||
| template<typename T> | ||||
| struct StringMaker { | ||||
|     static std::string convert( T const& value ) { | ||||
|         std::ostringstream oss; | ||||
|         oss << value; | ||||
|         return oss.str(); | ||||
|     }     | ||||
|  | ||||
|     template<typename T> | ||||
|     inline std::string makeString( T* p ) { | ||||
|     } | ||||
| }; | ||||
| template<typename T> | ||||
| struct StringMaker<T*> { | ||||
|     static std::string convert( T const* p ) { | ||||
|         if( !p ) | ||||
|             return INTERNAL_CATCH_STRINGIFY( NULL ); | ||||
|         std::ostringstream oss; | ||||
|         oss << p; | ||||
|         return oss.str(); | ||||
|     }     | ||||
|     } | ||||
| }; | ||||
|  | ||||
|     template<typename T> | ||||
|     inline std::string makeString( const T* p ) { | ||||
|         if( !p ) | ||||
|             return INTERNAL_CATCH_STRINGIFY( NULL ); | ||||
| template<typename T> | ||||
| struct StringMaker<std::vector<T> > { | ||||
|     static std::string convert( std::vector<T> const& v ) { | ||||
|         std::ostringstream oss; | ||||
|         oss << p; | ||||
|         oss << "{ "; | ||||
|         for( std::size_t i = 0; i < v.size(); ++ i ) { | ||||
|             oss << v[i]; | ||||
|             if( i < v.size() - 1 ) | ||||
|                 oss << ", "; | ||||
|         } | ||||
|         oss << " }"; | ||||
|         return oss.str(); | ||||
|     }     | ||||
|     } | ||||
| }; | ||||
|  | ||||
| namespace Detail { | ||||
|     template<typename T> | ||||
|     inline std::string makeString( const T& value ) { | ||||
|         return StringMaker<T>::convert( value ); | ||||
|     }    | ||||
| } // end namespace Detail | ||||
|  | ||||
| /// \brief converts any type to a string | ||||
| @@ -64,7 +82,8 @@ namespace Detail { | ||||
| /// to provide an ostream overload for. | ||||
| template<typename T> | ||||
| std::string toString( const T& value ) { | ||||
|     return Detail::makeString( value ); | ||||
|     return StringMaker<T>::convert( value ); | ||||
| //    return Detail::makeString( value ); | ||||
| } | ||||
|      | ||||
| // Built in overloads | ||||
| @@ -111,7 +130,8 @@ inline std::string toString( unsigned int value ) { | ||||
|      | ||||
| inline std::string toString( const double value ) { | ||||
|     std::ostringstream oss; | ||||
|     oss << value; | ||||
|     oss << std::setprecision (std::numeric_limits<double>::digits10 + 1) | ||||
|         << value; | ||||
|     return oss.str(); | ||||
| }     | ||||
|  | ||||
|   | ||||
| @@ -13,7 +13,7 @@ | ||||
| namespace Catch { | ||||
|  | ||||
|     // These numbers are maintained by a script | ||||
|     Version libraryVersion( 0, 9, 20, "integration" ); | ||||
|     Version libraryVersion( 0, 9, 21, "integration" ); | ||||
| } | ||||
|  | ||||
| #endif // TWOBLUECUBES_CATCH_VERSION_HPP_INCLUDED | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Phil Nash
					Phil Nash