mirror of
				https://github.com/catchorg/Catch2.git
				synced 2025-11-04 05:59:32 +01:00 
			
		
		
		
	Provide JunitReporter declaration with EXTERNAL_INTERFACES
Related to #991
This commit is contained in:
		@@ -248,6 +248,7 @@ set(REPORTER_HEADERS
 | 
				
			|||||||
        ${HEADER_DIR}/reporters/catch_reporter_automake.hpp
 | 
					        ${HEADER_DIR}/reporters/catch_reporter_automake.hpp
 | 
				
			||||||
        ${HEADER_DIR}/reporters/catch_reporter_bases.hpp
 | 
					        ${HEADER_DIR}/reporters/catch_reporter_bases.hpp
 | 
				
			||||||
        ${HEADER_DIR}/reporters/catch_reporter_compact.h
 | 
					        ${HEADER_DIR}/reporters/catch_reporter_compact.h
 | 
				
			||||||
 | 
					        ${HEADER_DIR}/reporters/catch_reporter_junit.h
 | 
				
			||||||
        ${HEADER_DIR}/reporters/catch_reporter_multi.h
 | 
					        ${HEADER_DIR}/reporters/catch_reporter_multi.h
 | 
				
			||||||
        ${HEADER_DIR}/reporters/catch_reporter_tap.hpp
 | 
					        ${HEADER_DIR}/reporters/catch_reporter_tap.hpp
 | 
				
			||||||
        ${HEADER_DIR}/reporters/catch_reporter_teamcity.hpp
 | 
					        ${HEADER_DIR}/reporters/catch_reporter_teamcity.hpp
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -13,5 +13,6 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
// Allow users to base their work off existing reporters
 | 
					// Allow users to base their work off existing reporters
 | 
				
			||||||
#include "../reporters/catch_reporter_compact.h"
 | 
					#include "../reporters/catch_reporter_compact.h"
 | 
				
			||||||
 | 
					#include "../reporters/catch_reporter_junit.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#endif // TWOBLUECUBES_CATCH_EXTERNAL_INTERFACES_H_INCLUDED
 | 
					#endif // TWOBLUECUBES_CATCH_EXTERNAL_INTERFACES_H_INCLUDED
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -8,10 +8,10 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#include "catch_reporter_bases.hpp"
 | 
					#include "catch_reporter_bases.hpp"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "catch_reporter_junit.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "../internal/catch_tostring.h"
 | 
					#include "../internal/catch_tostring.h"
 | 
				
			||||||
#include "../internal/catch_reporter_registrars.hpp"
 | 
					#include "../internal/catch_reporter_registrars.hpp"
 | 
				
			||||||
#include "internal/catch_xmlwriter.h"
 | 
					 | 
				
			||||||
#include "../internal/catch_timer.h"
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <assert.h>
 | 
					#include <assert.h>
 | 
				
			||||||
#include <sstream>
 | 
					#include <sstream>
 | 
				
			||||||
@@ -55,64 +55,63 @@ namespace Catch {
 | 
				
			|||||||
                return it->substr(1);
 | 
					                return it->substr(1);
 | 
				
			||||||
            return std::string();
 | 
					            return std::string();
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    } // anonymous namespace
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    class JunitReporter : public CumulativeReporterBase<JunitReporter> {
 | 
					    JunitReporter::JunitReporter( ReporterConfig const& _config )
 | 
				
			||||||
    public:
 | 
					 | 
				
			||||||
        JunitReporter( ReporterConfig const& _config )
 | 
					 | 
				
			||||||
        :   CumulativeReporterBase( _config ),
 | 
					        :   CumulativeReporterBase( _config ),
 | 
				
			||||||
            xml( _config.stream() )
 | 
					            xml( _config.stream() )
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            m_reporterPrefs.shouldRedirectStdOut = true;
 | 
					            m_reporterPrefs.shouldRedirectStdOut = true;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        ~JunitReporter() override;
 | 
					    JunitReporter::~JunitReporter() {};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        static std::string getDescription() {
 | 
					    std::string JunitReporter::getDescription() {
 | 
				
			||||||
        return "Reports test results in an XML format that looks like Ant's junitreport target";
 | 
					        return "Reports test results in an XML format that looks like Ant's junitreport target";
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        void noMatchingTestCases( std::string const& /*spec*/ ) override {}
 | 
					    void JunitReporter::noMatchingTestCases( std::string const& /*spec*/ ) {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        void testRunStarting( TestRunInfo const& runInfo ) override {
 | 
					    void JunitReporter::testRunStarting( TestRunInfo const& runInfo )  {
 | 
				
			||||||
        CumulativeReporterBase::testRunStarting( runInfo );
 | 
					        CumulativeReporterBase::testRunStarting( runInfo );
 | 
				
			||||||
        xml.startElement( "testsuites" );
 | 
					        xml.startElement( "testsuites" );
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        void testGroupStarting( GroupInfo const& groupInfo ) override {
 | 
					    void JunitReporter::testGroupStarting( GroupInfo const& groupInfo ) {
 | 
				
			||||||
        suiteTimer.start();
 | 
					        suiteTimer.start();
 | 
				
			||||||
            stdOutForSuite.str("");
 | 
					        stdOutForSuite.clear();
 | 
				
			||||||
            stdErrForSuite.str("");
 | 
					        stdErrForSuite.clear();
 | 
				
			||||||
        unexpectedExceptions = 0;
 | 
					        unexpectedExceptions = 0;
 | 
				
			||||||
        CumulativeReporterBase::testGroupStarting( groupInfo );
 | 
					        CumulativeReporterBase::testGroupStarting( groupInfo );
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        void testCaseStarting( TestCaseInfo const& testCaseInfo ) override {
 | 
					    void JunitReporter::testCaseStarting( TestCaseInfo const& testCaseInfo ) {
 | 
				
			||||||
        m_okToFail = testCaseInfo.okToFail();
 | 
					        m_okToFail = testCaseInfo.okToFail();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
        bool assertionEnded( AssertionStats const& assertionStats ) override {
 | 
					
 | 
				
			||||||
 | 
					    bool JunitReporter::assertionEnded( AssertionStats const& assertionStats ) {
 | 
				
			||||||
        if( assertionStats.assertionResult.getResultType() == ResultWas::ThrewException && !m_okToFail )
 | 
					        if( assertionStats.assertionResult.getResultType() == ResultWas::ThrewException && !m_okToFail )
 | 
				
			||||||
            unexpectedExceptions++;
 | 
					            unexpectedExceptions++;
 | 
				
			||||||
        return CumulativeReporterBase::assertionEnded( assertionStats );
 | 
					        return CumulativeReporterBase::assertionEnded( assertionStats );
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        void testCaseEnded( TestCaseStats const& testCaseStats ) override {
 | 
					    void JunitReporter::testCaseEnded( TestCaseStats const& testCaseStats ) {
 | 
				
			||||||
            stdOutForSuite << testCaseStats.stdOut;
 | 
					        stdOutForSuite += testCaseStats.stdOut;
 | 
				
			||||||
            stdErrForSuite << testCaseStats.stdErr;
 | 
					        stdErrForSuite += testCaseStats.stdErr;
 | 
				
			||||||
        CumulativeReporterBase::testCaseEnded( testCaseStats );
 | 
					        CumulativeReporterBase::testCaseEnded( testCaseStats );
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        void testGroupEnded( TestGroupStats const& testGroupStats ) override {
 | 
					    void JunitReporter::testGroupEnded( TestGroupStats const& testGroupStats ) {
 | 
				
			||||||
        double suiteTime = suiteTimer.getElapsedSeconds();
 | 
					        double suiteTime = suiteTimer.getElapsedSeconds();
 | 
				
			||||||
        CumulativeReporterBase::testGroupEnded( testGroupStats );
 | 
					        CumulativeReporterBase::testGroupEnded( testGroupStats );
 | 
				
			||||||
        writeGroup( *m_testGroups.back(), suiteTime );
 | 
					        writeGroup( *m_testGroups.back(), suiteTime );
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        void testRunEndedCumulative() override {
 | 
					    void JunitReporter::testRunEndedCumulative() {
 | 
				
			||||||
        xml.endElement();
 | 
					        xml.endElement();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        void writeGroup( TestGroupNode const& groupNode, double suiteTime ) {
 | 
					    void JunitReporter::writeGroup( TestGroupNode const& groupNode, double suiteTime ) {
 | 
				
			||||||
        XmlWriter::ScopedElement e = xml.scopedElement( "testsuite" );
 | 
					        XmlWriter::ScopedElement e = xml.scopedElement( "testsuite" );
 | 
				
			||||||
        TestGroupStats const& stats = groupNode.value;
 | 
					        TestGroupStats const& stats = groupNode.value;
 | 
				
			||||||
        xml.writeAttribute( "name", stats.groupInfo.name );
 | 
					        xml.writeAttribute( "name", stats.groupInfo.name );
 | 
				
			||||||
@@ -130,11 +129,11 @@ namespace Catch {
 | 
				
			|||||||
        for( auto const& child : groupNode.children )
 | 
					        for( auto const& child : groupNode.children )
 | 
				
			||||||
            writeTestCase( *child );
 | 
					            writeTestCase( *child );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            xml.scopedElement( "system-out" ).writeText( trim( stdOutForSuite.str() ), false );
 | 
					        xml.scopedElement( "system-out" ).writeText( trim( stdOutForSuite ), false );
 | 
				
			||||||
            xml.scopedElement( "system-err" ).writeText( trim( stdErrForSuite.str() ), false );
 | 
					        xml.scopedElement( "system-err" ).writeText( trim( stdErrForSuite ), false );
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        void writeTestCase( TestCaseNode const& testCaseNode ) {
 | 
					    void JunitReporter::writeTestCase( TestCaseNode const& testCaseNode ) {
 | 
				
			||||||
        TestCaseStats const& stats = testCaseNode.value;
 | 
					        TestCaseStats const& stats = testCaseNode.value;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // All test cases have exactly one section - which represents the
 | 
					        // All test cases have exactly one section - which represents the
 | 
				
			||||||
@@ -156,7 +155,7 @@ namespace Catch {
 | 
				
			|||||||
        writeSection( className, "", rootSection );
 | 
					        writeSection( className, "", rootSection );
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        void writeSection(  std::string const& className,
 | 
					    void JunitReporter::writeSection(  std::string const& className,
 | 
				
			||||||
                        std::string const& rootName,
 | 
					                        std::string const& rootName,
 | 
				
			||||||
                        SectionNode const& sectionNode ) {
 | 
					                        SectionNode const& sectionNode ) {
 | 
				
			||||||
        std::string name = trim( sectionNode.stats.sectionInfo.name );
 | 
					        std::string name = trim( sectionNode.stats.sectionInfo.name );
 | 
				
			||||||
@@ -191,11 +190,12 @@ namespace Catch {
 | 
				
			|||||||
                writeSection( className, name, *childNode );
 | 
					                writeSection( className, name, *childNode );
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        void writeAssertions( SectionNode const& sectionNode ) {
 | 
					    void JunitReporter::writeAssertions( SectionNode const& sectionNode ) {
 | 
				
			||||||
        for( auto const& assertion : sectionNode.assertions )
 | 
					        for( auto const& assertion : sectionNode.assertions )
 | 
				
			||||||
            writeAssertion( assertion );
 | 
					            writeAssertion( assertion );
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
        void writeAssertion( AssertionStats const& stats ) {
 | 
					
 | 
				
			||||||
 | 
					    void JunitReporter::writeAssertion( AssertionStats const& stats ) {
 | 
				
			||||||
        AssertionResult const& result = stats.assertionResult;
 | 
					        AssertionResult const& result = stats.assertionResult;
 | 
				
			||||||
        if( !result.isOk() ) {
 | 
					        if( !result.isOk() ) {
 | 
				
			||||||
            std::string elementName;
 | 
					            std::string elementName;
 | 
				
			||||||
@@ -242,15 +242,6 @@ namespace Catch {
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        XmlWriter xml;
 | 
					 | 
				
			||||||
        Timer suiteTimer;
 | 
					 | 
				
			||||||
        std::ostringstream stdOutForSuite;
 | 
					 | 
				
			||||||
        std::ostringstream stdErrForSuite;
 | 
					 | 
				
			||||||
        unsigned int unexpectedExceptions = 0;
 | 
					 | 
				
			||||||
        bool m_okToFail = false;
 | 
					 | 
				
			||||||
    };
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    JunitReporter::~JunitReporter() {}
 | 
					 | 
				
			||||||
    CATCH_REGISTER_REPORTER( "junit", JunitReporter )
 | 
					    CATCH_REGISTER_REPORTER( "junit", JunitReporter )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
} // end namespace Catch
 | 
					} // end namespace Catch
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										61
									
								
								include/reporters/catch_reporter_junit.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										61
									
								
								include/reporters/catch_reporter_junit.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,61 @@
 | 
				
			|||||||
 | 
					/*
 | 
				
			||||||
 | 
					 *  Created by Martin on 14/11/2017.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 *  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_JUNIT_H_INCLUDED
 | 
				
			||||||
 | 
					#define TWOBLUECUBES_CATCH_REPORTER_JUNIT_H_INCLUDED
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "catch_reporter_bases.hpp"
 | 
				
			||||||
 | 
					#include "../internal/catch_xmlwriter.h"
 | 
				
			||||||
 | 
					#include "../internal/catch_timer.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace Catch {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    class JunitReporter : public CumulativeReporterBase<JunitReporter> {
 | 
				
			||||||
 | 
					    public:
 | 
				
			||||||
 | 
					        JunitReporter(ReporterConfig const& _config);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        ~JunitReporter() override;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        static std::string getDescription();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        void noMatchingTestCases(std::string const& /*spec*/) override;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        void testRunStarting(TestRunInfo const& runInfo) override;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        void testGroupStarting(GroupInfo const& groupInfo) override;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        void testCaseStarting(TestCaseInfo const& testCaseInfo) override;
 | 
				
			||||||
 | 
					        bool assertionEnded(AssertionStats const& assertionStats) override;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        void testCaseEnded(TestCaseStats const& testCaseStats) override;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        void testGroupEnded(TestGroupStats const& testGroupStats) override;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        void testRunEndedCumulative() override;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        void writeGroup(TestGroupNode const& groupNode, double suiteTime);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        void writeTestCase(TestCaseNode const& testCaseNode);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        void writeSection(std::string const& className,
 | 
				
			||||||
 | 
					                          std::string const& rootName,
 | 
				
			||||||
 | 
					                          SectionNode const& sectionNode);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        void writeAssertions(SectionNode const& sectionNode);
 | 
				
			||||||
 | 
					        void writeAssertion(AssertionStats const& stats);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        XmlWriter xml;
 | 
				
			||||||
 | 
					        Timer suiteTimer;
 | 
				
			||||||
 | 
					        std::string stdOutForSuite;
 | 
				
			||||||
 | 
					        std::string stdErrForSuite;
 | 
				
			||||||
 | 
					        unsigned int unexpectedExceptions = 0;
 | 
				
			||||||
 | 
					        bool m_okToFail = false;
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					} // end namespace Catch
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif // TWOBLUECUBES_CATCH_REPORTER_JUNIT_H_INCLUDED
 | 
				
			||||||
		Reference in New Issue
	
	Block a user