mirror of
				https://github.com/SoftFever/OrcaSlicer.git
				synced 2025-10-30 04:02:52 -06:00 
			
		
		
		
	
		
			
				
	
	
		
			220 lines
		
	
	
	
		
			8.5 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			220 lines
		
	
	
	
		
			8.5 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| /*
 | |
|  *  Created by Phil Nash on 19th December 2014
 | |
|  *  Copyright 2014 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_TEAMCITY_HPP_INCLUDED
 | |
| #define TWOBLUECUBES_CATCH_REPORTER_TEAMCITY_HPP_INCLUDED
 | |
| 
 | |
| // Don't #include any Catch headers here - we can assume they are already
 | |
| // included before this header.
 | |
| // This is not good practice in general but is necessary in this case so this
 | |
| // file can be distributed as a single header that works with the main
 | |
| // Catch single header.
 | |
| 
 | |
| #include <cstring>
 | |
| 
 | |
| #ifdef __clang__
 | |
| #   pragma clang diagnostic push
 | |
| #   pragma clang diagnostic ignored "-Wpadded"
 | |
| #endif
 | |
| 
 | |
| namespace Catch {
 | |
| 
 | |
|     struct TeamCityReporter : StreamingReporterBase<TeamCityReporter> {
 | |
|         TeamCityReporter( ReporterConfig const& _config )
 | |
|         :   StreamingReporterBase( _config )
 | |
|         {
 | |
|             m_reporterPrefs.shouldRedirectStdOut = true;
 | |
|         }
 | |
| 
 | |
|         static std::string escape( std::string const& str ) {
 | |
|             std::string escaped = str;
 | |
|             replaceInPlace( escaped, "|", "||" );
 | |
|             replaceInPlace( escaped, "'", "|'" );
 | |
|             replaceInPlace( escaped, "\n", "|n" );
 | |
|             replaceInPlace( escaped, "\r", "|r" );
 | |
|             replaceInPlace( escaped, "[", "|[" );
 | |
|             replaceInPlace( escaped, "]", "|]" );
 | |
|             return escaped;
 | |
|         }
 | |
|         ~TeamCityReporter() override;
 | |
| 
 | |
|         static std::string getDescription() {
 | |
|             return "Reports test results as TeamCity service messages";
 | |
|         }
 | |
| 
 | |
|         void skipTest( TestCaseInfo const& /* testInfo */ ) override {
 | |
|         }
 | |
| 
 | |
|         void noMatchingTestCases( std::string const& /* spec */ ) override {}
 | |
| 
 | |
|         void testGroupStarting( GroupInfo const& groupInfo ) override {
 | |
|             StreamingReporterBase::testGroupStarting( groupInfo );
 | |
|             stream << "##teamcity[testSuiteStarted name='"
 | |
|                 << escape( groupInfo.name ) << "']\n";
 | |
|         }
 | |
|         void testGroupEnded( TestGroupStats const& testGroupStats ) override {
 | |
|             StreamingReporterBase::testGroupEnded( testGroupStats );
 | |
|             stream << "##teamcity[testSuiteFinished name='"
 | |
|                 << escape( testGroupStats.groupInfo.name ) << "']\n";
 | |
|         }
 | |
| 
 | |
| 
 | |
|         void assertionStarting( AssertionInfo const& ) override {}
 | |
| 
 | |
|         bool assertionEnded( AssertionStats const& assertionStats ) override {
 | |
|             AssertionResult const& result = assertionStats.assertionResult;
 | |
|             if( !result.isOk() ) {
 | |
| 
 | |
|                 ReusableStringStream msg;
 | |
|                 if( !m_headerPrintedForThisSection )
 | |
|                     printSectionHeader( msg.get() );
 | |
|                 m_headerPrintedForThisSection = true;
 | |
| 
 | |
|                 msg << result.getSourceInfo() << "\n";
 | |
| 
 | |
|                 switch( result.getResultType() ) {
 | |
|                     case ResultWas::ExpressionFailed:
 | |
|                         msg << "expression failed";
 | |
|                         break;
 | |
|                     case ResultWas::ThrewException:
 | |
|                         msg << "unexpected exception";
 | |
|                         break;
 | |
|                     case ResultWas::FatalErrorCondition:
 | |
|                         msg << "fatal error condition";
 | |
|                         break;
 | |
|                     case ResultWas::DidntThrowException:
 | |
|                         msg << "no exception was thrown where one was expected";
 | |
|                         break;
 | |
|                     case ResultWas::ExplicitFailure:
 | |
|                         msg << "explicit failure";
 | |
|                         break;
 | |
| 
 | |
|                     // We shouldn't get here because of the isOk() test
 | |
|                     case ResultWas::Ok:
 | |
|                     case ResultWas::Info:
 | |
|                     case ResultWas::Warning:
 | |
|                         CATCH_ERROR( "Internal error in TeamCity reporter" );
 | |
|                     // These cases are here to prevent compiler warnings
 | |
|                     case ResultWas::Unknown:
 | |
|                     case ResultWas::FailureBit:
 | |
|                     case ResultWas::Exception:
 | |
|                         CATCH_ERROR( "Not implemented" );
 | |
|                 }
 | |
|                 if( assertionStats.infoMessages.size() == 1 )
 | |
|                     msg << " with message:";
 | |
|                 if( assertionStats.infoMessages.size() > 1 )
 | |
|                     msg << " with messages:";
 | |
|                 for( auto const& messageInfo : assertionStats.infoMessages )
 | |
|                     msg << "\n  \"" << messageInfo.message << "\"";
 | |
| 
 | |
| 
 | |
|                 if( result.hasExpression() ) {
 | |
|                     msg <<
 | |
|                         "\n  " << result.getExpressionInMacro() << "\n"
 | |
|                         "with expansion:\n" <<
 | |
|                         "  " << result.getExpandedExpression() << "\n";
 | |
|                 }
 | |
| 
 | |
|                 if( currentTestCaseInfo->okToFail() ) {
 | |
|                     msg << "- failure ignore as test marked as 'ok to fail'\n";
 | |
|                     stream << "##teamcity[testIgnored"
 | |
|                            << " name='" << escape( currentTestCaseInfo->name )<< "'"
 | |
|                            << " message='" << escape( msg.str() ) << "'"
 | |
|                            << "]\n";
 | |
|                 }
 | |
|                 else {
 | |
|                     stream << "##teamcity[testFailed"
 | |
|                            << " name='" << escape( currentTestCaseInfo->name )<< "'"
 | |
|                            << " message='" << escape( msg.str() ) << "'"
 | |
|                            << "]\n";
 | |
|                 }
 | |
|             }
 | |
|             stream.flush();
 | |
|             return true;
 | |
|         }
 | |
| 
 | |
|         void sectionStarting( SectionInfo const& sectionInfo ) override {
 | |
|             m_headerPrintedForThisSection = false;
 | |
|             StreamingReporterBase::sectionStarting( sectionInfo );
 | |
|         }
 | |
| 
 | |
|         void testCaseStarting( TestCaseInfo const& testInfo ) override {
 | |
|             m_testTimer.start();
 | |
|             StreamingReporterBase::testCaseStarting( testInfo );
 | |
|             stream << "##teamcity[testStarted name='"
 | |
|                 << escape( testInfo.name ) << "']\n";
 | |
|             stream.flush();
 | |
|         }
 | |
| 
 | |
|         void testCaseEnded( TestCaseStats const& testCaseStats ) override {
 | |
|             StreamingReporterBase::testCaseEnded( testCaseStats );
 | |
|             if( !testCaseStats.stdOut.empty() )
 | |
|                 stream << "##teamcity[testStdOut name='"
 | |
|                     << escape( testCaseStats.testInfo.name )
 | |
|                     << "' out='" << escape( testCaseStats.stdOut ) << "']\n";
 | |
|             if( !testCaseStats.stdErr.empty() )
 | |
|                 stream << "##teamcity[testStdErr name='"
 | |
|                     << escape( testCaseStats.testInfo.name )
 | |
|                     << "' out='" << escape( testCaseStats.stdErr ) << "']\n";
 | |
|             stream << "##teamcity[testFinished name='"
 | |
|                     << escape( testCaseStats.testInfo.name ) << "' duration='"
 | |
|                     << m_testTimer.getElapsedMilliseconds() << "']\n";
 | |
|             stream.flush();
 | |
|         }
 | |
| 
 | |
|     private:
 | |
|         void printSectionHeader( std::ostream& os ) {
 | |
|             assert( !m_sectionStack.empty() );
 | |
| 
 | |
|             if( m_sectionStack.size() > 1 ) {
 | |
|                 os << getLineOfChars<'-'>() << "\n";
 | |
| 
 | |
|                 std::vector<SectionInfo>::const_iterator
 | |
|                 it = m_sectionStack.begin()+1, // Skip first section (test case)
 | |
|                 itEnd = m_sectionStack.end();
 | |
|                 for( ; it != itEnd; ++it )
 | |
|                     printHeaderString( os, it->name );
 | |
|                 os << getLineOfChars<'-'>() << "\n";
 | |
|             }
 | |
| 
 | |
|             SourceLineInfo lineInfo = m_sectionStack.front().lineInfo;
 | |
| 
 | |
|             if( !lineInfo.empty() )
 | |
|                 os << lineInfo << "\n";
 | |
|             os << getLineOfChars<'.'>() << "\n\n";
 | |
|         }
 | |
| 
 | |
|         // if string has a : in first line will set indent to follow it on
 | |
|         // subsequent lines
 | |
|         static void printHeaderString( std::ostream& os, std::string const& _string, std::size_t indent = 0 ) {
 | |
|             std::size_t i = _string.find( ": " );
 | |
|             if( i != std::string::npos )
 | |
|                 i+=2;
 | |
|             else
 | |
|                 i = 0;
 | |
|             os << Column( _string )
 | |
|                            .indent( indent+i)
 | |
|                            .initialIndent( indent ) << "\n";
 | |
|         }
 | |
|     private:
 | |
|         bool m_headerPrintedForThisSection = false;
 | |
|         Timer m_testTimer;
 | |
|     };
 | |
| 
 | |
| #ifdef CATCH_IMPL
 | |
|     TeamCityReporter::~TeamCityReporter() {}
 | |
| #endif
 | |
| 
 | |
|     CATCH_REGISTER_REPORTER( "teamcity", TeamCityReporter )
 | |
| 
 | |
| } // end namespace Catch
 | |
| 
 | |
| #ifdef __clang__
 | |
| #   pragma clang diagnostic pop
 | |
| #endif
 | |
| 
 | |
| #endif // TWOBLUECUBES_CATCH_REPORTER_TEAMCITY_HPP_INCLUDED
 | 
