Read-only mirrors. Development, issues and pull requests are on GitHub.

summaryrefslogtreecommitdiffhomepage
path: root/include
diff options
context:
space:
mode:
authorPhil Nash2014-12-23 18:54:08 +0000
committerPhil Nash2014-12-23 18:54:08 +0000
commit1cbc4f2c9c4e8bb0bb5a34ccaa43217963efdd3e (patch)
treefa7fe74463f1177b730695a808c4400f76885c09 /include
parent92f0836fd3d683d4237068d6dd602805ad888aee (diff)
parent6e996956103a390046525a88487cbfe739625c45 (diff)
downloadcatch3-1cbc4f2c9c4e8bb0bb5a34ccaa43217963efdd3e.tar.gz
Merge branch 'develop' of https://github.com/SeanCline/Catch into develop
Diffstat (limited to 'include')
-rw-r--r--include/internal/catch_impl.hpp2
-rw-r--r--include/reporters/catch_reporter_xml.hpp170
2 files changed, 106 insertions, 66 deletions
diff --git a/include/internal/catch_impl.hpp b/include/internal/catch_impl.hpp
index cc03ae08..820b4975 100644
--- a/include/internal/catch_impl.hpp
+++ b/include/internal/catch_impl.hpp
@@ -88,8 +88,6 @@ namespace Catch {
Matchers::Impl::StdString::EndsWith::~EndsWith() {}
void Config::dummy() {}
-
- INTERNAL_CATCH_REGISTER_LEGACY_REPORTER( "xml", XmlReporter )
}
#ifdef __clang__
diff --git a/include/reporters/catch_reporter_xml.hpp b/include/reporters/catch_reporter_xml.hpp
index 4687471a..1b7c0199 100644
--- a/include/reporters/catch_reporter_xml.hpp
+++ b/include/reporters/catch_reporter_xml.hpp
@@ -13,83 +13,93 @@
#include "../internal/catch_capture.hpp"
#include "../internal/catch_reporter_registrars.hpp"
#include "../internal/catch_xmlwriter.hpp"
+#include "../internal/catch_timer.h"
namespace Catch {
- class XmlReporter : public SharedImpl<IReporter> {
+ class XmlReporter : public StreamingReporterBase {
public:
- XmlReporter( ReporterConfig const& config ) : m_config( config ), m_sectionDepth( 0 ) {}
+ XmlReporter( ReporterConfig const& _config )
+ : StreamingReporterBase( _config ),
+ m_sectionDepth( 0 )
+ {}
+ virtual ~XmlReporter();
+
static std::string getDescription() {
return "Reports test results as an XML document";
}
- virtual ~XmlReporter();
-
- private: // IReporter
- virtual bool shouldRedirectStdout() const {
- return true;
+ public: // StreamingReporterBase
+ virtual ReporterPreferences getPreferences() const {
+ ReporterPreferences prefs;
+ prefs.shouldRedirectStdOut = true;
+ return prefs;
}
- virtual void StartTesting() {
- m_xml.setStream( m_config.stream() );
- m_xml.startElement( "Catch" );
- if( !m_config.fullConfig()->name().empty() )
- m_xml.writeAttribute( "name", m_config.fullConfig()->name() );
+ virtual void noMatchingTestCases( std::string const& s ) {
+ StreamingReporterBase::noMatchingTestCases( s );
}
- virtual void EndTesting( const Totals& totals ) {
- m_xml.scopedElement( "OverallResults" )
- .writeAttribute( "successes", totals.assertions.passed )
- .writeAttribute( "failures", totals.assertions.failed )
- .writeAttribute( "expectedFailures", totals.assertions.failedButOk );
- m_xml.endElement();
+ virtual void testRunStarting( TestRunInfo const& testInfo ) {
+ StreamingReporterBase::testRunStarting( testInfo );
+ m_xml.setStream( stream );
+ m_xml.startElement( "Catch" );
+ if( !m_config->name().empty() )
+ m_xml.writeAttribute( "name", m_config->name() );
}
- virtual void StartGroup( const std::string& groupName ) {
+ virtual void testGroupStarting( GroupInfo const& groupInfo ) {
+ StreamingReporterBase::testGroupStarting( groupInfo );
m_xml.startElement( "Group" )
- .writeAttribute( "name", groupName );
+ .writeAttribute( "name", groupInfo.name );
}
- virtual void EndGroup( const std::string&, const Totals& totals ) {
- m_xml.scopedElement( "OverallResults" )
- .writeAttribute( "successes", totals.assertions.passed )
- .writeAttribute( "failures", totals.assertions.failed )
- .writeAttribute( "expectedFailures", totals.assertions.failedButOk );
- m_xml.endElement();
+ virtual void testCaseStarting( TestCaseInfo const& testInfo ) {
+ StreamingReporterBase::testCaseStarting(testInfo);
+ m_xml.startElement( "TestCase" ).writeAttribute( "name", trim( testInfo.name ) );
+
+ if ( m_config->showDurations() == ShowDurations::Always )
+ m_testCaseTimer.start();
}
- virtual void StartSection( const std::string& sectionName, const std::string& description ) {
+ virtual void sectionStarting( SectionInfo const& sectionInfo ) {
+ StreamingReporterBase::sectionStarting( sectionInfo );
if( m_sectionDepth++ > 0 ) {
m_xml.startElement( "Section" )
- .writeAttribute( "name", trim( sectionName ) )
- .writeAttribute( "description", description );
+ .writeAttribute( "name", trim( sectionInfo.name ) )
+ .writeAttribute( "description", sectionInfo.description );
}
}
- virtual void NoAssertionsInSection( const std::string& ) {}
- virtual void NoAssertionsInTestCase( const std::string& ) {}
- virtual void EndSection( const std::string& /*sectionName*/, const Counts& assertions ) {
- if( --m_sectionDepth > 0 ) {
- m_xml.scopedElement( "OverallResults" )
- .writeAttribute( "successes", assertions.passed )
- .writeAttribute( "failures", assertions.failed )
- .writeAttribute( "expectedFailures", assertions.failedButOk );
- m_xml.endElement();
+ virtual void assertionStarting( AssertionInfo const& ) { }
+
+ virtual bool assertionEnded( AssertionStats const& assertionStats ) {
+ const AssertionResult& assertionResult = assertionStats.assertionResult;
+
+ // Print any info messages in <Info> tags.
+ if( assertionStats.assertionResult.getResultType() != ResultWas::Ok ) {
+ for( std::vector<MessageInfo>::const_iterator it = assertionStats.infoMessages.begin(), itEnd = assertionStats.infoMessages.end();
+ it != itEnd;
+ ++it ) {
+ if( it->type == ResultWas::Info ) {
+ m_xml.scopedElement( "Info" )
+ .writeText( it->message );
+ } else if ( it->type == ResultWas::Warning ) {
+ m_xml.scopedElement( "Warning" )
+ .writeText( it->message );
+ }
+ }
}
- }
-
- virtual void StartTestCase( const Catch::TestCaseInfo& testInfo ) {
- m_xml.startElement( "TestCase" ).writeAttribute( "name", trim( testInfo.name ) );
- m_currentTestSuccess = true;
- }
- virtual void Result( const Catch::AssertionResult& assertionResult ) {
- if( !m_config.fullConfig()->includeSuccessfulResults() && assertionResult.getResultType() == ResultWas::Ok )
- return;
+ // Drop out if result was successful but we're not printing them.
+ if( !m_config->includeSuccessfulResults() && isOk(assertionResult.getResultType()) )
+ return true;
+ // Print the expression if there is one.
if( assertionResult.hasExpression() ) {
m_xml.startElement( "Expression" )
.writeAttribute( "success", assertionResult.succeeded() )
+ .writeAttribute( "type", assertionResult.getTestMacroName() )
.writeAttribute( "filename", assertionResult.getSourceInfo().file )
.writeAttribute( "line", assertionResult.getSourceInfo().line );
@@ -97,23 +107,23 @@ namespace Catch {
.writeText( assertionResult.getExpression() );
m_xml.scopedElement( "Expanded" )
.writeText( assertionResult.getExpandedExpression() );
- m_currentTestSuccess &= assertionResult.succeeded();
}
+ // And... Print a result applicable to each result type.
switch( assertionResult.getResultType() ) {
+ default:
+ break;
case ResultWas::ThrewException:
m_xml.scopedElement( "Exception" )
.writeAttribute( "filename", assertionResult.getSourceInfo().file )
.writeAttribute( "line", assertionResult.getSourceInfo().line )
.writeText( assertionResult.getMessage() );
- m_currentTestSuccess = false;
break;
case ResultWas::FatalErrorCondition:
m_xml.scopedElement( "Fatal Error Condition" )
.writeAttribute( "filename", assertionResult.getSourceInfo().file )
.writeAttribute( "line", assertionResult.getSourceInfo().line )
.writeText( assertionResult.getMessage() );
- m_currentTestSuccess = false;
break;
case ResultWas::Info:
m_xml.scopedElement( "Info" )
@@ -126,36 +136,68 @@ namespace Catch {
case ResultWas::ExplicitFailure:
m_xml.scopedElement( "Failure" )
.writeText( assertionResult.getMessage() );
- m_currentTestSuccess = false;
- break;
- case ResultWas::Unknown:
- case ResultWas::Ok:
- case ResultWas::FailureBit:
- case ResultWas::ExpressionFailed:
- case ResultWas::Exception:
- case ResultWas::DidntThrowException:
break;
}
+
if( assertionResult.hasExpression() )
m_xml.endElement();
+
+ return true;
+ }
+
+ virtual void sectionEnded( SectionStats const& sectionStats ) {
+ StreamingReporterBase::sectionEnded( sectionStats );
+ if( --m_sectionDepth > 0 ) {
+ XmlWriter::ScopedElement e = m_xml.scopedElement( "OverallResults" );
+ e.writeAttribute( "successes", sectionStats.assertions.passed );
+ e.writeAttribute( "failures", sectionStats.assertions.failed );
+ e.writeAttribute( "expectedFailures", sectionStats.assertions.failedButOk );
+
+ if ( m_config->showDurations() == ShowDurations::Always )
+ e.writeAttribute( "durationInSeconds", sectionStats.durationInSeconds );
+
+ m_xml.endElement();
+ }
}
- virtual void Aborted() {
- // !TBD
+ virtual void testCaseEnded( TestCaseStats const& testCaseStats ) {
+ StreamingReporterBase::testCaseEnded( testCaseStats );
+ XmlWriter::ScopedElement e = m_xml.scopedElement( "OverallResult" );
+ e.writeAttribute( "success", testCaseStats.totals.assertions.allPassed() );
+
+ if ( m_config->showDurations() == ShowDurations::Always )
+ e.writeAttribute( "durationInSeconds", m_testCaseTimer.getElapsedSeconds() );
+
+ m_xml.endElement();
}
- virtual void EndTestCase( const Catch::TestCaseInfo&, const Totals&, const std::string&, const std::string& ) {
- m_xml.scopedElement( "OverallResult" ).writeAttribute( "success", m_currentTestSuccess );
+ virtual void testGroupEnded( TestGroupStats const& testGroupStats ) {
+ StreamingReporterBase::testGroupEnded( testGroupStats );
+ // TODO: Check testGroupStats.aborting and act accordingly.
+ m_xml.scopedElement( "OverallResults" )
+ .writeAttribute( "successes", testGroupStats.totals.assertions.passed )
+ .writeAttribute( "failures", testGroupStats.totals.assertions.failed )
+ .writeAttribute( "expectedFailures", testGroupStats.totals.assertions.failedButOk );
+ m_xml.endElement();
+ }
+
+ virtual void testRunEnded( TestRunStats const& testRunStats ) {
+ StreamingReporterBase::testRunEnded( testRunStats );
+ m_xml.scopedElement( "OverallResults" )
+ .writeAttribute( "successes", testRunStats.totals.assertions.passed )
+ .writeAttribute( "failures", testRunStats.totals.assertions.failed )
+ .writeAttribute( "expectedFailures", testRunStats.totals.assertions.failedButOk );
m_xml.endElement();
}
private:
- ReporterConfig m_config;
- bool m_currentTestSuccess;
+ Timer m_testCaseTimer;
XmlWriter m_xml;
int m_sectionDepth;
};
+ INTERNAL_CATCH_REGISTER_REPORTER( "xml", XmlReporter )
+
} // end namespace Catch
#endif // TWOBLUECUBES_CATCH_REPORTER_XML_HPP_INCLUDED