Compare commits

..
Author SHA1 Message Date
Phil Nash e73583d556 dev build 12 2015-08-07 17:30:34 +01:00
Phil Nash afcc38efc5 Fixes for single include 2015-08-07 17:28:48 +01:00
Phil Nash 368714e7aa Added Listeners (programatically provided extra reporters) 2015-08-07 08:20:56 +01:00
Phil Nash 4cb74761d9 Support for multiple reporters
- can't (yet) specify different targets for each reporter (e.g. different files)
2015-08-05 19:02:17 +01:00
Phil Nash c06e1909ae Refactored test filtering and sorting 2015-08-04 23:11:56 +01:00
Phil Nash 8b1b7cd66e dev build 11 2015-08-03 07:40:52 +01:00
Phil Nash 34fa25ed2f Removed Runner class
- it served no purpose - split into functions instead
2015-07-28 18:55:11 +01:00
Phil Nash 85c8074784 Set group name to -n parameter (or exe name)
- As discussed in #469
2015-07-28 18:26:09 +01:00
Phil Nash 0edebf41b0 approvals rebase
- I *think* this fixes an earlier regression, but I'm not 100% sure where that came from!
2015-07-28 18:24:20 +01:00
Phil Nash f3308ed7c4 Let gcc use __cplusplus identifier to decide if nullptr supported
- or, for 4.6, continue to check __GX_EXPERIMENTAL_CXX0X__
See GitHb issue #445 and PR #471
2015-07-27 18:42:36 +01:00
Phil Nash 74eef52644 dev build 10 2015-07-24 08:13:52 +01:00
Phil Nash e085d4811a Qualified path to xmlwriter to fix travis error 2015-07-24 08:13:07 +01:00
Phil Nash 2f6371f2ec dev build 9 2015-07-23 23:06:26 +01:00
Phil Nash 70975517b3 rebased approvals for long long test 2015-07-23 23:05:52 +01:00
Phil Nash 733ebb6024 Added CATCH_CONFIG_CPP11_LONG_LONG support 2015-07-23 23:05:05 +01:00
Phil Nash d6e59cd56f Fixed Xml encoding
- don't encode apostrophes
- only encode quotes in attributes
- encode control characters (as in PR #465)
2015-07-23 18:45:31 +01:00
Phil Nash 6de135c63a Given, When, Then prefixes are now std::strings
(and so can be prepended to std::strings themselves)
see #455
2015-07-22 18:07:28 +01:00
41 changed files with 2117 additions and 1090 deletions
+1 -1
View File
@@ -1,6 +1,6 @@
![catch logo](catch-logo-small.png)
*v1.2.1-develop.8*
*v1.2.1-develop.12*
Build status (on Travis CI) [![Build Status](https://travis-ci.org/philsquared/Catch.png)](https://travis-ci.org/philsquared/Catch)
+10 -10
View File
@@ -125,11 +125,11 @@
#define CATCH_SCENARIO( name, tags ) CATCH_TEST_CASE( "Scenario: " name, tags )
#define CATCH_SCENARIO_METHOD( className, name, tags ) INTERNAL_CATCH_TEST_CASE_METHOD( className, "Scenario: " name, tags )
#endif
#define CATCH_GIVEN( desc ) CATCH_SECTION( "Given: " desc, "" )
#define CATCH_WHEN( desc ) CATCH_SECTION( " When: " desc, "" )
#define CATCH_AND_WHEN( desc ) CATCH_SECTION( " And: " desc, "" )
#define CATCH_THEN( desc ) CATCH_SECTION( " Then: " desc, "" )
#define CATCH_AND_THEN( desc ) CATCH_SECTION( " And: " desc, "" )
#define CATCH_GIVEN( desc ) CATCH_SECTION( std::string( "Given: ") + desc, "" )
#define CATCH_WHEN( desc ) CATCH_SECTION( std::string( " When: ") + desc, "" )
#define CATCH_AND_WHEN( desc ) CATCH_SECTION( std::string( " And: ") + desc, "" )
#define CATCH_THEN( desc ) CATCH_SECTION( std::string( " Then: ") + desc, "" )
#define CATCH_AND_THEN( desc ) CATCH_SECTION( std::string( " And: ") + desc, "" )
// If CATCH_CONFIG_PREFIX_ALL is not defined then the CATCH_ prefix is not required
#else
@@ -196,11 +196,11 @@
#define SCENARIO( name, tags ) TEST_CASE( "Scenario: " name, tags )
#define SCENARIO_METHOD( className, name, tags ) INTERNAL_CATCH_TEST_CASE_METHOD( className, "Scenario: " name, tags )
#endif
#define GIVEN( desc ) SECTION( " Given: " desc, "" )
#define WHEN( desc ) SECTION( " When: " desc, "" )
#define AND_WHEN( desc ) SECTION( "And when: " desc, "" )
#define THEN( desc ) SECTION( " Then: " desc, "" )
#define AND_THEN( desc ) SECTION( " And: " desc, "" )
#define GIVEN( desc ) SECTION( std::string(" Given: ") + desc, "" )
#define WHEN( desc ) SECTION( std::string(" When: ") + desc, "" )
#define AND_WHEN( desc ) SECTION( std::string("And when: ") + desc, "" )
#define THEN( desc ) SECTION( std::string(" Then: ") + desc, "" )
#define AND_THEN( desc ) SECTION( std::string(" And: ") + desc, "" )
using Catch::Detail::Approx;
@@ -10,7 +10,7 @@
#include "internal/catch_commandline.hpp"
#include "internal/catch_list.hpp"
#include "internal/catch_runner_impl.hpp"
#include "internal/catch_run_context.hpp"
#include "internal/catch_test_spec.hpp"
#include "internal/catch_version.h"
#include "internal/catch_text.h"
@@ -21,92 +21,83 @@
namespace Catch {
class Runner {
public:
Runner( Ptr<Config> const& config )
: m_config( config )
{
openStream();
makeReporter();
Ptr<IStreamingReporter> createReporter( std::string const& reporterName, Ptr<Config> const& config ) {
Ptr<IStreamingReporter> reporter = getRegistryHub().getReporterRegistry().create( reporterName, config.get() );
if( !reporter ) {
std::ostringstream oss;
oss << "No reporter registered with name: '" << reporterName << "'";
throw std::domain_error( oss.str() );
}
return reporter;
}
Ptr<IStreamingReporter> makeReporter( Ptr<Config> const& config ) {
std::vector<std::string> reporters = config->getReporterNames();
if( reporters.empty() )
reporters.push_back( "console" );
Totals runTests() {
RunContext context( m_config.get(), m_reporter );
Totals totals;
context.testGroupStarting( "all tests", 1, 1 ); // deprecated?
TestSpec testSpec = m_config->testSpec();
if( !testSpec.hasFilters() )
testSpec = TestSpecParser( ITagAliasRegistry::get() ).parse( "~[.]" ).testSpec(); // All not hidden tests
std::vector<TestCase> testCases;
getRegistryHub().getTestCaseRegistry().getFilteredTests( testSpec, *m_config, testCases );
int testsRunForGroup = 0;
for( std::vector<TestCase>::const_iterator it = testCases.begin(), itEnd = testCases.end();
it != itEnd;
++it ) {
testsRunForGroup++;
if( m_testsAlreadyRun.find( *it ) == m_testsAlreadyRun.end() ) {
if( context.aborting() )
break;
totals += context.runTest( *it );
m_testsAlreadyRun.insert( *it );
}
}
std::vector<TestCase> skippedTestCases;
getRegistryHub().getTestCaseRegistry().getFilteredTests( testSpec, *m_config, skippedTestCases, true );
for( std::vector<TestCase>::const_iterator it = skippedTestCases.begin(), itEnd = skippedTestCases.end();
it != itEnd;
++it )
m_reporter->skipTest( *it );
context.testGroupEnded( "all tests", totals, 1, 1 );
return totals;
}
private:
void openStream() {
// Open output file, if specified
if( !m_config->getFilename().empty() ) {
m_ofs.open( m_config->getFilename().c_str() );
if( m_ofs.fail() ) {
std::ostringstream oss;
oss << "Unable to open file: '" << m_config->getFilename() << "'";
throw std::domain_error( oss.str() );
}
m_config->setStreamBuf( m_ofs.rdbuf() );
}
}
void makeReporter() {
std::string reporterName = m_config->getReporterName().empty()
? "console"
: m_config->getReporterName();
m_reporter = getRegistryHub().getReporterRegistry().create( reporterName, m_config.get() );
if( !m_reporter ) {
Ptr<IStreamingReporter> reporter;
for( std::vector<std::string>::const_iterator it = reporters.begin(), itEnd = reporters.end();
it != itEnd;
++it )
reporter = addReporter( reporter, createReporter( *it, config ) );
return reporter;
}
Ptr<IStreamingReporter> addListeners( Ptr<IConfig> const& config, Ptr<IStreamingReporter> reporters ) {
IReporterRegistry::Listeners listeners = getRegistryHub().getReporterRegistry().getListeners();
for( IReporterRegistry::Listeners::const_iterator it = listeners.begin(), itEnd = listeners.end();
it != itEnd;
++it )
reporters = addReporter(reporters, (*it)->create( ReporterConfig( config ) ) );
return reporters;
}
void openStreamInto( Ptr<Config> const& config, std::ofstream& ofs ) {
// Open output file, if specified
if( !config->getFilename().empty() ) {
ofs.open( config->getFilename().c_str() );
if( ofs.fail() ) {
std::ostringstream oss;
oss << "No reporter registered with name: '" << reporterName << "'";
oss << "Unable to open file: '" << config->getFilename() << "'";
throw std::domain_error( oss.str() );
}
config->setStreamBuf( ofs.rdbuf() );
}
}
Totals runTests( Ptr<Config> const& config ) {
std::ofstream ofs;
openStreamInto( config, ofs );
Ptr<IStreamingReporter> reporter = makeReporter( config );
reporter = addListeners( config.get(), reporter );
RunContext context( config.get(), reporter );
Totals totals;
context.testGroupStarting( config->name(), 1, 1 );
TestSpec testSpec = config->testSpec();
if( !testSpec.hasFilters() )
testSpec = TestSpecParser( ITagAliasRegistry::get() ).parse( "~[.]" ).testSpec(); // All not hidden tests
std::vector<TestCase> const& allTestCases = getAllTestCasesSorted( *config );
for( std::vector<TestCase>::const_iterator it = allTestCases.begin(), itEnd = allTestCases.end();
it != itEnd;
++it ) {
if( !context.aborting() && matchTest( *it, testSpec, *config ) )
totals += context.runTest( *it );
else
reporter->skipTest( *it );
}
private:
Ptr<Config> m_config;
std::ofstream m_ofs;
Ptr<IStreamingReporter> m_reporter;
std::set<TestCase> m_testsAlreadyRun;
};
context.testGroupEnded( config->name(), totals, 1, 1 );
return totals;
}
void applyFilenamesAsTags() {
std::vector<TestCase> const& tests = getRegistryHub().getTestCaseRegistry().getAllTests();
void applyFilenamesAsTags( IConfig const& config ) {
std::vector<TestCase> const& tests = getAllTestCasesSorted( config );
for(std::size_t i = 0; i < tests.size(); ++i ) {
TestCase& test = const_cast<TestCase&>( tests[i] );
std::set<std::string> tags = test.tags;
@@ -194,19 +185,17 @@ namespace Catch {
try
{
config(); // Force config to be constructed
if( m_configData.filenamesAsTags )
applyFilenamesAsTags();
seedRng( *m_config );
Runner runner( m_config );
if( m_configData.filenamesAsTags )
applyFilenamesAsTags( *m_config );
// Handle list request
if( Option<std::size_t> listed = list( config() ) )
return static_cast<int>( *listed );
return static_cast<int>( runner.runTests().assertions.failed );
return static_cast<int>( runTests( m_config ).assertions.failed );
}
catch( std::exception& ex ) {
Catch::cerr() << ex.what() << std::endl;
@@ -228,7 +217,6 @@ namespace Catch {
m_config = new Config( m_configData );
return *m_config;
}
private:
Clara::CommandLine<ConfigData> m_cli;
std::vector<Clara::Parser::Token> m_unusedTokens;
+2 -1
View File
@@ -23,6 +23,7 @@ namespace Catch {
config.abortAfter = x;
}
inline void addTestOrTags( ConfigData& config, std::string const& _testSpec ) { config.testsOrTags.push_back( _testSpec ); }
inline void addReporterName( ConfigData& config, std::string const& _reporterName ) { config.reporterNames.push_back( _reporterName ); }
inline void addWarning( ConfigData& config, std::string const& _warning ) {
if( _warning == "NoAssertions" )
@@ -116,7 +117,7 @@ namespace Catch {
cli["-r"]["--reporter"]
// .placeholder( "name[:filename]" )
.describe( "reporter to use (defaults to console)" )
.bind( &ConfigData::reporterName, "name" );
.bind( &addReporterName, "name" );
cli["-n"]["--name"]
.describe( "suite name" )
+29 -2
View File
@@ -16,6 +16,8 @@
// CATCH_CONFIG_CPP11_GENERATED_METHODS : The delete and default keywords for compiler generated methods
// CATCH_CONFIG_CPP11_IS_ENUM : std::is_enum is supported?
// CATCH_CONFIG_CPP11_TUPLE : std::tuple is supported
// CATCH_CONFIG_CPP11_LONG_LONG : is long long supported?
// CATCH_CONFIG_CPP11_OVERRIDE : is override supported?
// CATCH_CONFIG_CPP11_OR_GREATER : Is C++11 supported?
@@ -66,10 +68,13 @@
// GCC
#ifdef __GNUC__
#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6 && defined(__GXX_EXPERIMENTAL_CXX0X__) )
#if __GNUC__ == 4 && __GNUC_MINOR__ >= 6 && defined(__GXX_EXPERIMENTAL_CXX0X__)
# define CATCH_INTERNAL_CONFIG_CPP11_NULLPTR
#endif
// - otherwise more recent versions define __cplusplus >= 201103L
// and will get picked up below
#endif // __GNUC__
@@ -130,6 +135,15 @@
# define CATCH_INTERNAL_CONFIG_VARIADIC_MACROS
# endif
# if !defined(CATCH_INTERNAL_CONFIG_CPP11_LONG_LONG)
# define CATCH_INTERNAL_CONFIG_CPP11_LONG_LONG
# endif
# if !defined(CATCH_INTERNAL_CONFIG_CPP11_OVERRIDE)
# define CATCH_INTERNAL_CONFIG_CPP11_OVERRIDE
# endif
#endif // __cplusplus >= 201103L
// Now set the actual defines based on the above + anything the user has configured
@@ -149,7 +163,13 @@
# define CATCH_CONFIG_CPP11_TUPLE
#endif
#if defined(CATCH_INTERNAL_CONFIG_VARIADIC_MACROS) && !defined(CATCH_CONFIG_NO_VARIADIC_MACROS) && !defined(CATCH_CONFIG_VARIADIC_MACROS)
#define CATCH_CONFIG_VARIADIC_MACROS
# define CATCH_CONFIG_VARIADIC_MACROS
#endif
#if defined(CATCH_INTERNAL_CONFIG_CPP11_LONG_LONG) && !defined(CATCH_CONFIG_NO_LONG_LONG) && !defined(CATCH_CONFIG_CPP11_LONG_LONG)
# define CATCH_CONFIG_CPP11_LONG_LONG
#endif
#if defined(CATCH_INTERNAL_CONFIG_CPP11_OVERRIDE) && !defined(CATCH_CONFIG_NO_OVERRIDE) && !defined(CATCH_CONFIG_CPP11_OVERRIDE)
# define CATCH_CONFIG_CPP11_OVERRIDE
#endif
@@ -169,5 +189,12 @@
# define CATCH_NULL NULL
#endif
// override support
#ifdef CATCH_CONFIG_CPP11_OVERRIDE
# define CATCH_OVERRIDE override
#else
# define CATCH_OVERRIDE
#endif
#endif // TWOBLUECUBES_CATCH_COMPILER_CAPABILITIES_HPP_INCLUDED
+2 -2
View File
@@ -68,11 +68,11 @@ namespace Catch {
ShowDurations::OrNot showDurations;
RunTests::InWhatOrder runOrder;
std::string reporterName;
std::string outputFilename;
std::string name;
std::string processName;
std::vector<std::string> reporterNames;
std::vector<std::string> testsOrTags;
};
@@ -133,7 +133,7 @@ namespace Catch {
m_stream = stream;
}
std::string getReporterName() const { return m_data.reporterName; }
std::vector<std::string> getReporterNames() const { return m_data.reporterNames; }
int abortAfter() const { return m_data.abortAfter; }
+1 -1
View File
@@ -8,7 +8,7 @@
#ifndef TWOBLUECUBES_CATCH_CONTEXT_IMPL_HPP_INCLUDED
#define TWOBLUECUBES_CATCH_CONTEXT_IMPL_HPP_INCLUDED
#include "catch_runner_impl.hpp"
#include "catch_run_context.hpp"
#include "catch_context.h"
#include "catch_stream.hpp"
+40 -2
View File
@@ -160,13 +160,51 @@ namespace Internal {
return Evaluator<T*, T*, Op>::evaluate( lhs, reinterpret_cast<T*>( rhs ) );
}
#ifdef CATCH_CONFIG_CPP11_LONG_LONG
// long long to unsigned X
template<Operator Op> bool compare( long long lhs, unsigned int rhs ) {
return applyEvaluator<Op>( static_cast<unsigned long>( lhs ), rhs );
}
template<Operator Op> bool compare( long long lhs, unsigned long rhs ) {
return applyEvaluator<Op>( static_cast<unsigned long>( lhs ), rhs );
}
template<Operator Op> bool compare( long long lhs, unsigned long long rhs ) {
return applyEvaluator<Op>( static_cast<unsigned long>( lhs ), rhs );
}
template<Operator Op> bool compare( long long lhs, unsigned char rhs ) {
return applyEvaluator<Op>( static_cast<unsigned long>( lhs ), rhs );
}
// unsigned long long to X
template<Operator Op> bool compare( unsigned long long lhs, int rhs ) {
return applyEvaluator<Op>( static_cast<long>( lhs ), rhs );
}
template<Operator Op> bool compare( unsigned long long lhs, long rhs ) {
return applyEvaluator<Op>( static_cast<long>( lhs ), rhs );
}
template<Operator Op> bool compare( unsigned long long lhs, long long rhs ) {
return applyEvaluator<Op>( static_cast<long>( lhs ), rhs );
}
template<Operator Op> bool compare( unsigned long long lhs, char rhs ) {
return applyEvaluator<Op>( static_cast<long>( lhs ), rhs );
}
// pointer to long long (when comparing against NULL)
template<Operator Op, typename T> bool compare( long long lhs, T* rhs ) {
return Evaluator<T*, T*, Op>::evaluate( reinterpret_cast<T*>( lhs ), rhs );
}
template<Operator Op, typename T> bool compare( T* lhs, long long rhs ) {
return Evaluator<T*, T*, Op>::evaluate( lhs, reinterpret_cast<T*>( rhs ) );
}
#endif // CATCH_CONFIG_CPP11_LONG_LONG
#ifdef CATCH_CONFIG_CPP11_NULLPTR
// pointer to nullptr_t (when comparing against nullptr)
template<Operator Op, typename T> bool compare( std::nullptr_t, T* rhs ) {
return Evaluator<T*, T*, Op>::evaluate( CATCH_NULL, rhs );
return Evaluator<T*, T*, Op>::evaluate( nullptr, rhs );
}
template<Operator Op, typename T> bool compare( T* lhs, std::nullptr_t ) {
return Evaluator<T*, T*, Op>::evaluate( lhs, CATCH_NULL );
return Evaluator<T*, T*, Op>::evaluate( lhs, nullptr );
}
#endif // CATCH_CONFIG_CPP11_NULLPTR
+2 -1
View File
@@ -16,7 +16,7 @@
#pragma clang diagnostic ignored "-Wweak-vtables"
#endif
#include "../catch_runner.hpp"
#include "../catch_session.hpp"
#include "catch_registry_hub.hpp"
#include "catch_notimplemented_exception.hpp"
#include "catch_context_impl.hpp"
@@ -36,6 +36,7 @@
#include "catch_result_builder.hpp"
#include "catch_tag_alias_registry.hpp"
#include "../reporters/catch_reporter_multi.hpp"
#include "../reporters/catch_reporter_xml.hpp"
#include "../reporters/catch_reporter_junit.hpp"
#include "../reporters/catch_reporter_console.hpp"
@@ -8,6 +8,8 @@
#ifndef TWOBLUECUBES_CATCH_INTERFACES_REGISTRY_HUB_H_INCLUDED
#define TWOBLUECUBES_CATCH_INTERFACES_REGISTRY_HUB_H_INCLUDED
#include "catch_ptr.hpp"
#include <string>
namespace Catch {
@@ -29,7 +31,8 @@ namespace Catch {
struct IMutableRegistryHub {
virtual ~IMutableRegistryHub();
virtual void registerReporter( std::string const& name, IReporterFactory* factory ) = 0;
virtual void registerReporter( std::string const& name, Ptr<IReporterFactory> const& factory ) = 0;
virtual void registerListener( Ptr<IReporterFactory> const& factory ) = 0;
virtual void registerTest( TestCase const& testInfo ) = 0;
virtual void registerTranslator( const IExceptionTranslator* translator ) = 0;
};
+7 -2
View File
@@ -240,6 +240,7 @@ namespace Catch
// The return value indicates if the messages buffer should be cleared:
virtual bool assertionEnded( AssertionStats const& assertionStats ) = 0;
virtual void sectionEnded( SectionStats const& sectionStats ) = 0;
virtual void testCaseEnded( TestCaseStats const& testCaseStats ) = 0;
virtual void testGroupEnded( TestGroupStats const& testGroupStats ) = 0;
@@ -249,20 +250,24 @@ namespace Catch
};
struct IReporterFactory {
struct IReporterFactory : IShared {
virtual ~IReporterFactory();
virtual IStreamingReporter* create( ReporterConfig const& config ) const = 0;
virtual std::string getDescription() const = 0;
};
struct IReporterRegistry {
typedef std::map<std::string, IReporterFactory*> FactoryMap;
typedef std::map<std::string, Ptr<IReporterFactory> > FactoryMap;
typedef std::vector<Ptr<IReporterFactory> > Listeners;
virtual ~IReporterRegistry();
virtual IStreamingReporter* create( std::string const& name, Ptr<IConfig> const& config ) const = 0;
virtual FactoryMap const& getFactories() const = 0;
virtual Listeners const& getListeners() const = 0;
};
Ptr<IStreamingReporter> addReporter( Ptr<IStreamingReporter> const& existingReporter, Ptr<IStreamingReporter> const& additionalReporter );
}
#endif // TWOBLUECUBES_CATCH_INTERFACES_REPORTER_H_INCLUDED
+6 -2
View File
@@ -28,9 +28,13 @@ namespace Catch {
struct ITestCaseRegistry {
virtual ~ITestCaseRegistry();
virtual std::vector<TestCase> const& getAllTests() const = 0;
virtual void getFilteredTests( TestSpec const& testSpec, IConfig const& config, std::vector<TestCase>& matchingTestCases, bool negated = false ) const = 0;
virtual std::vector<TestCase> const& getAllTestsSorted( IConfig const& config ) const = 0;
};
bool matchTest( TestCase const& testCase, TestSpec const& testSpec, IConfig const& config );
std::vector<TestCase> filterTests( std::vector<TestCase> const& testCases, TestSpec const& testSpec, IConfig const& config );
std::vector<TestCase> const& getAllTestCasesSorted( IConfig const& config );
}
#endif // TWOBLUECUBES_CATCH_INTERFACES_TESTCASE_H_INCLUDED
+3 -6
View File
@@ -34,8 +34,7 @@ namespace Catch {
nameAttr.setInitialIndent( 2 ).setIndent( 4 );
tagsAttr.setIndent( 6 );
std::vector<TestCase> matchedTestCases;
getRegistryHub().getTestCaseRegistry().getFilteredTests( testSpec, config, matchedTestCases );
std::vector<TestCase> matchedTestCases = filterTests( getAllTestCasesSorted( config ), testSpec, config );
for( std::vector<TestCase>::const_iterator it = matchedTestCases.begin(), itEnd = matchedTestCases.end();
it != itEnd;
++it ) {
@@ -63,8 +62,7 @@ namespace Catch {
if( !config.testSpec().hasFilters() )
testSpec = TestSpecParser( ITagAliasRegistry::get() ).parse( "*" ).testSpec();
std::size_t matchedTests = 0;
std::vector<TestCase> matchedTestCases;
getRegistryHub().getTestCaseRegistry().getFilteredTests( testSpec, config, matchedTestCases );
std::vector<TestCase> matchedTestCases = filterTests( getAllTestCasesSorted( config ), testSpec, config );
for( std::vector<TestCase>::const_iterator it = matchedTestCases.begin(), itEnd = matchedTestCases.end();
it != itEnd;
++it ) {
@@ -104,8 +102,7 @@ namespace Catch {
std::map<std::string, TagInfo> tagCounts;
std::vector<TestCase> matchedTestCases;
getRegistryHub().getTestCaseRegistry().getFilteredTests( testSpec, config, matchedTestCases );
std::vector<TestCase> matchedTestCases = filterTests( getAllTestCasesSorted( config ), testSpec, config );
for( std::vector<TestCase>::const_iterator it = matchedTestCases.begin(), itEnd = matchedTestCases.end();
it != itEnd;
++it ) {
+1 -2
View File
@@ -52,8 +52,7 @@ namespace Catch {
return *this;
}
void swap( Ptr& other ) { std::swap( m_p, other.m_p ); }
T* get() { return m_p; }
const T* get() const{ return m_p; }
T* get() const{ return m_p; }
T& operator*() const { return *m_p; }
T* operator->() const { return m_p; }
bool operator !() const { return m_p == CATCH_NULL; }
+9 -6
View File
@@ -26,24 +26,27 @@ namespace Catch {
public: // IRegistryHub
RegistryHub() {
}
virtual IReporterRegistry const& getReporterRegistry() const {
virtual IReporterRegistry const& getReporterRegistry() const override {
return m_reporterRegistry;
}
virtual ITestCaseRegistry const& getTestCaseRegistry() const {
virtual ITestCaseRegistry const& getTestCaseRegistry() const override {
return m_testCaseRegistry;
}
virtual IExceptionTranslatorRegistry& getExceptionTranslatorRegistry() {
virtual IExceptionTranslatorRegistry& getExceptionTranslatorRegistry() override {
return m_exceptionTranslatorRegistry;
}
public: // IMutableRegistryHub
virtual void registerReporter( std::string const& name, IReporterFactory* factory ) {
virtual void registerReporter( std::string const& name, Ptr<IReporterFactory> const& factory ) override {
m_reporterRegistry.registerReporter( name, factory );
}
virtual void registerTest( TestCase const& testInfo ) {
virtual void registerListener( Ptr<IReporterFactory> const& factory ) override {
m_reporterRegistry.registerListener( factory );
}
virtual void registerTest( TestCase const& testInfo ) override {
m_testCaseRegistry.registerTest( testInfo );
}
virtual void registerTranslator( const IExceptionTranslator* translator ) {
virtual void registerTranslator( const IExceptionTranslator* translator ) override {
m_exceptionTranslatorRegistry.registerTranslator( translator );
}
+25 -1
View File
@@ -36,7 +36,7 @@ namespace Catch {
template<typename T>
class ReporterRegistrar {
class ReporterFactory : public IReporterFactory {
class ReporterFactory : public SharedImpl<IReporterFactory> {
// *** Please Note ***:
// - If you end up here looking at a compiler error because it's trying to register
@@ -64,11 +64,35 @@ namespace Catch {
getMutableRegistryHub().registerReporter( name, new ReporterFactory() );
}
};
template<typename T>
class ListenerRegistrar {
class ListenerFactory : public SharedImpl<IReporterFactory> {
virtual IStreamingReporter* create( ReporterConfig const& config ) const {
return new T( config );
}
virtual std::string getDescription() const {
return "";
}
};
public:
ListenerRegistrar() {
getMutableRegistryHub().registerListener( new ListenerFactory() );
}
};
}
#define INTERNAL_CATCH_REGISTER_LEGACY_REPORTER( name, reporterType ) \
namespace{ Catch::LegacyReporterRegistrar<reporterType> catch_internal_RegistrarFor##reporterType( name ); }
#define INTERNAL_CATCH_REGISTER_REPORTER( name, reporterType ) \
namespace{ Catch::ReporterRegistrar<reporterType> catch_internal_RegistrarFor##reporterType( name ); }
#define INTERNAL_CATCH_REGISTER_LISTENER( listenerType ) \
namespace{ Catch::ListenerRegistrar<listenerType> catch_internal_RegistrarFor##listenerType; }
#endif // TWOBLUECUBES_CATCH_REPORTER_REGISTRARS_HPP_INCLUDED
+11 -6
View File
@@ -18,27 +18,32 @@ namespace Catch {
public:
virtual ~ReporterRegistry() {
deleteAllValues( m_factories );
}
virtual ~ReporterRegistry() override {}
virtual IStreamingReporter* create( std::string const& name, Ptr<IConfig> const& config ) const {
virtual IStreamingReporter* create( std::string const& name, Ptr<IConfig> const& config ) const override {
FactoryMap::const_iterator it = m_factories.find( name );
if( it == m_factories.end() )
return CATCH_NULL;
return it->second->create( ReporterConfig( config ) );
}
void registerReporter( std::string const& name, IReporterFactory* factory ) {
void registerReporter( std::string const& name, Ptr<IReporterFactory> const& factory ) {
m_factories.insert( std::make_pair( name, factory ) );
}
void registerListener( Ptr<IReporterFactory> const& factory ) {
m_listeners.push_back( factory );
}
FactoryMap const& getFactories() const {
virtual FactoryMap const& getFactories() const override {
return m_factories;
}
virtual Listeners const& getListeners() const override {
return m_listeners;
}
private:
FactoryMap m_factories;
Listeners m_listeners;
};
}
@@ -5,9 +5,6 @@
* file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
*/
#ifndef TWOBLUECUBES_CATCH_SUPPRESS_WARNINGS_H_INCLUDED
#define TWOBLUECUBES_CATCH_SUPPRESS_WARNINGS_H_INCLUDED
#ifdef __clang__
# ifdef __ICC // icpc defines the __clang__ macro
# pragma warning(push)
@@ -29,5 +26,3 @@
# pragma GCC diagnostic push
# pragma GCC diagnostic ignored "-Wpadded"
#endif
#endif // TWOBLUECUBES_CATCH_SUPPRESS_WARNINGS_H_INCLUDED
@@ -21,14 +21,75 @@
namespace Catch {
class TestRegistry : public ITestCaseRegistry {
struct LexSort {
bool operator() (TestCase i,TestCase j) const { return (i<j);}
};
struct RandomNumberGenerator {
int operator()( int n ) const { return std::rand() % n; }
};
struct LexSort {
bool operator() (TestCase i,TestCase j) const { return (i<j);}
};
struct RandomNumberGenerator {
int operator()( int n ) const { return std::rand() % n; }
};
inline std::vector<TestCase> sortTests( IConfig const& config, std::vector<TestCase> const& unsortedTestCases ) {
std::vector<TestCase> sorted = unsortedTestCases;
switch( config.runOrder() ) {
case RunTests::InLexicographicalOrder:
std::sort( sorted.begin(), sorted.end(), LexSort() );
break;
case RunTests::InRandomOrder:
{
seedRng( config );
RandomNumberGenerator rng;
std::random_shuffle( sorted.begin(), sorted.end(), rng );
}
break;
case RunTests::InDeclarationOrder:
// already in declaration order
break;
}
return sorted;
}
bool matchTest( TestCase const& testCase, TestSpec const& testSpec, IConfig const& config ) {
return testSpec.matches( testCase ) && ( config.allowThrows() || !testCase.throws() );
}
struct TestMatcher {
TestMatcher( TestSpec const& testSpec, bool allowThrows ) : m_testSpec( testSpec ), m_allowThrows( allowThrows ) {}
bool operator()( TestCase const& testCase ) const {
return m_testSpec.matches( testCase ) && ( m_allowThrows || !testCase.throws() );
}
TestSpec m_testSpec;
bool m_allowThrows;
};
void enforceNoDuplicateTestCases( std::vector<TestCase> const& functions ) {
std::set<TestCase> seenFunctions;
for( std::vector<TestCase>::const_iterator it = functions.begin(), itEnd = functions.end();
it != itEnd;
++it ) {
std::pair<std::set<TestCase>::const_iterator, bool> prev = seenFunctions.insert( *it );
if( !prev.second ){
Catch::cerr()
<< Colour( Colour::Red )
<< "error: TEST_CASE( \"" << it->name << "\" ) already defined.\n"
<< "\tFirst seen at " << prev.first->getTestCaseInfo().lineInfo << "\n"
<< "\tRedefined at " << it->getTestCaseInfo().lineInfo << std::endl;
exit(1);
}
}
}
std::vector<TestCase> filterTests( std::vector<TestCase> const& testCases, TestSpec const& testSpec, IConfig const& config ) {
std::vector<TestCase> filtered;
std::copy_if( testCases.begin(), testCases.end(), std::back_inserter( filtered ), TestMatcher( testSpec, config.allowThrows() ) );
return filtered;
}
std::vector<TestCase> const& getAllTestCasesSorted( IConfig const& config ) {
return getRegistryHub().getTestCaseRegistry().getAllTestsSorted( config );
}
class TestRegistry : public ITestCaseRegistry {
public:
TestRegistry() : m_unnamedCount( 0 ) {}
virtual ~TestRegistry();
@@ -40,70 +101,27 @@ namespace Catch {
oss << "Anonymous test case " << ++m_unnamedCount;
return registerTest( testCase.withName( oss.str() ) );
}
if( m_functions.find( testCase ) == m_functions.end() ) {
m_functions.insert( testCase );
m_functionsInOrder.push_back( testCase );
if( !testCase.isHidden() )
m_nonHiddenFunctions.push_back( testCase );
}
else {
TestCase const& prev = *m_functions.find( testCase );
{
Colour colourGuard( Colour::Red );
Catch::cerr() << "error: TEST_CASE( \"" << name << "\" ) already defined.\n"
<< "\tFirst seen at " << prev.getTestCaseInfo().lineInfo << "\n"
<< "\tRedefined at " << testCase.getTestCaseInfo().lineInfo << std::endl;
}
exit(1);
}
m_functions.push_back( testCase );
}
virtual std::vector<TestCase> const& getAllTests() const {
return m_functionsInOrder;
return m_functions;
}
virtual std::vector<TestCase> const& getAllTestsSorted( IConfig const& config ) const {
if( m_sortedFunctions.empty() )
enforceNoDuplicateTestCases( m_functions );
virtual std::vector<TestCase> const& getAllNonHiddenTests() const {
return m_nonHiddenFunctions;
}
virtual void getFilteredTests( TestSpec const& testSpec, IConfig const& config, std::vector<TestCase>& matchingTestCases, bool negated = false ) const {
for( std::vector<TestCase>::const_iterator it = m_functionsInOrder.begin(),
itEnd = m_functionsInOrder.end();
it != itEnd;
++it ) {
bool includeTest = testSpec.matches( *it ) && ( config.allowThrows() || !it->throws() );
if( includeTest != negated )
matchingTestCases.push_back( *it );
if( m_currentSortOrder != config.runOrder() || m_sortedFunctions.empty() ) {
m_sortedFunctions = sortTests( config, m_functions );
m_currentSortOrder = config.runOrder();
}
sortTests( config, matchingTestCases );
return m_sortedFunctions;
}
private:
static void sortTests( IConfig const& config, std::vector<TestCase>& matchingTestCases ) {
switch( config.runOrder() ) {
case RunTests::InLexicographicalOrder:
std::sort( matchingTestCases.begin(), matchingTestCases.end(), LexSort() );
break;
case RunTests::InRandomOrder:
{
seedRng( config );
RandomNumberGenerator rng;
std::random_shuffle( matchingTestCases.begin(), matchingTestCases.end(), rng );
}
break;
case RunTests::InDeclarationOrder:
// already in declaration order
break;
}
}
std::set<TestCase> m_functions;
std::vector<TestCase> m_functionsInOrder;
std::vector<TestCase> m_nonHiddenFunctions;
std::vector<TestCase> m_functions;
mutable RunTests::InWhatOrder m_currentSortOrder;
mutable std::vector<TestCase> m_sortedFunctions;
size_t m_unnamedCount;
std::ios_base::Init m_ostreamInit; // Forces cout/ cerr to be initialised
};
+6 -1
View File
@@ -52,6 +52,11 @@ std::string toString( char value );
std::string toString( signed char value );
std::string toString( unsigned char value );
#ifdef CATCH_CONFIG_CPP11_LONG_LONG
std::string toString( long long value );
std::string toString( unsigned long long value );
#endif
#ifdef CATCH_CONFIG_CPP11_NULLPTR
std::string toString( std::nullptr_t );
#endif
@@ -65,7 +70,7 @@ std::string toString( std::nullptr_t );
namespace Detail {
extern std::string unprintableString;
extern const std::string unprintableString;
struct BorgType {
template<typename T> BorgType( T const& );
+23 -4
View File
@@ -15,9 +15,11 @@ namespace Catch {
namespace Detail {
std::string unprintableString = "{?}";
const std::string unprintableString = "{?}";
namespace {
const int hexThreshold = 255;
struct Endianness {
enum Arch { Big, Little };
@@ -99,7 +101,7 @@ std::string toString( wchar_t* const value )
std::string toString( int value ) {
std::ostringstream oss;
oss << value;
if( value >= 255 )
if( value > Detail::hexThreshold )
oss << " (0x" << std::hex << value << ")";
return oss.str();
}
@@ -107,7 +109,7 @@ std::string toString( int value ) {
std::string toString( unsigned long value ) {
std::ostringstream oss;
oss << value;
if( value >= 255 )
if( value > Detail::hexThreshold )
oss << " (0x" << std::hex << value << ")";
return oss.str();
}
@@ -157,6 +159,23 @@ std::string toString( unsigned char value ) {
return toString( static_cast<char>( value ) );
}
#ifdef CATCH_CONFIG_CPP11_LONG_LONG
std::string toString( long long value ) {
std::ostringstream oss;
oss << value;
if( value > Detail::hexThreshold )
oss << " (0x" << std::hex << value << ")";
return oss.str();
}
std::string toString( unsigned long long value ) {
std::ostringstream oss;
oss << value;
if( value > Detail::hexThreshold )
oss << " (0x" << std::hex << value << ")";
return oss.str();
}
#endif
#ifdef CATCH_CONFIG_CPP11_NULLPTR
std::string toString( std::nullptr_t ) {
return "nullptr";
+1 -1
View File
@@ -37,7 +37,7 @@ namespace Catch {
return os;
}
Version libraryVersion( 1, 2, 1, "develop", 8 );
Version libraryVersion( 1, 2, 1, "develop", 12 );
}
+65 -33
View File
@@ -10,13 +10,70 @@
#include "catch_stream.h"
#include "catch_compiler_capabilities.h"
#include "catch_suppress_warnings.h"
#include <sstream>
#include <string>
#include <vector>
#include <iomanip>
namespace Catch {
class XmlEncode {
public:
enum ForWhat { ForTextNodes, ForAttributes };
XmlEncode( std::string const& str, ForWhat forWhat = ForTextNodes )
: m_str( str ),
m_forWhat( forWhat )
{}
void encodeTo( std::ostream& os ) const {
// Apostrophe escaping not necessary if we always use " to write attributes
// (see: http://www.w3.org/TR/xml/#syntax)
for( std::size_t i = 0; i < m_str.size(); ++ i ) {
char c = m_str[i];
switch( c ) {
case '<': os << "&lt;"; break;
case '&': os << "&amp;"; break;
case '>':
// See: http://www.w3.org/TR/xml/#syntax
if( i > 2 && m_str[i-1] == ']' && m_str[i-2] == ']' )
os << "&gt;";
else
os << c;
break;
case '\"':
if( m_forWhat == ForAttributes )
os << "&quot;";
else
os << c;
break;
default:
// Escape control chars - based on contribution by @espenalb in PR #465
if ( ( c < '\x09' ) || ( c > '\x0D' && c < '\x20') || c=='\x7F' )
os << "&#x" << std::uppercase << std::hex << static_cast<int>( c );
else
os << c;
}
}
}
friend std::ostream& operator << ( std::ostream& os, XmlEncode const& xmlEncode ) {
xmlEncode.encodeTo( os );
return os;
}
private:
std::string m_str;
ForWhat m_forWhat;
};
class XmlWriter {
public:
@@ -99,11 +156,8 @@ namespace Catch {
}
XmlWriter& writeAttribute( std::string const& name, std::string const& attribute ) {
if( !name.empty() && !attribute.empty() ) {
stream() << " " << name << "=\"";
writeEncodedText( attribute );
stream() << "\"";
}
if( !name.empty() && !attribute.empty() )
stream() << " " << name << "=\"" << XmlEncode( attribute, XmlEncode::ForAttributes ) << "\"";
return *this;
}
@@ -114,9 +168,9 @@ namespace Catch {
template<typename T>
XmlWriter& writeAttribute( std::string const& name, T const& attribute ) {
if( !name.empty() )
stream() << " " << name << "=\"" << attribute << "\"";
return *this;
std::ostringstream oss;
oss << attribute;
return writeAttribute( name, oss.str() );
}
XmlWriter& writeText( std::string const& text, bool indent = true ) {
@@ -125,7 +179,7 @@ namespace Catch {
ensureTagClosed();
if( tagWasOpen && indent )
stream() << m_indent;
writeEncodedText( text );
stream() << XmlEncode( text );
m_needsNewline = true;
}
return *this;
@@ -170,30 +224,6 @@ namespace Catch {
}
}
void writeEncodedText( std::string const& text ) {
static const char* charsToEncode = "<&\"";
std::string mtext = text;
std::string::size_type pos = mtext.find_first_of( charsToEncode );
while( pos != std::string::npos ) {
stream() << mtext.substr( 0, pos );
switch( mtext[pos] ) {
case '<':
stream() << "&lt;";
break;
case '&':
stream() << "&amp;";
break;
case '\"':
stream() << "&quot;";
break;
}
mtext = mtext.substr( pos+1 );
pos = mtext.find_first_of( charsToEncode );
}
stream() << mtext;
}
bool m_tagIsOpen;
bool m_needsNewline;
std::vector<std::string> m_tags;
@@ -202,4 +232,6 @@ namespace Catch {
};
}
#include "catch_reenable_warnings.h"
#endif // TWOBLUECUBES_CATCH_XMLWRITER_HPP_INCLUDED
+49 -23
View File
@@ -19,42 +19,48 @@ namespace Catch {
StreamingReporterBase( ReporterConfig const& _config )
: m_config( _config.fullConfig() ),
stream( _config.stream() )
{}
{
m_reporterPrefs.shouldRedirectStdOut = false;
}
virtual ~StreamingReporterBase();
virtual ReporterPreferences getPreferences() const CATCH_OVERRIDE {
return m_reporterPrefs;
}
virtual void noMatchingTestCases( std::string const& ) {}
virtual ~StreamingReporterBase() CATCH_OVERRIDE;
virtual void testRunStarting( TestRunInfo const& _testRunInfo ) {
virtual void noMatchingTestCases( std::string const& ) CATCH_OVERRIDE {}
virtual void testRunStarting( TestRunInfo const& _testRunInfo ) CATCH_OVERRIDE {
currentTestRunInfo = _testRunInfo;
}
virtual void testGroupStarting( GroupInfo const& _groupInfo ) {
virtual void testGroupStarting( GroupInfo const& _groupInfo ) CATCH_OVERRIDE {
currentGroupInfo = _groupInfo;
}
virtual void testCaseStarting( TestCaseInfo const& _testInfo ) {
virtual void testCaseStarting( TestCaseInfo const& _testInfo ) CATCH_OVERRIDE {
currentTestCaseInfo = _testInfo;
}
virtual void sectionStarting( SectionInfo const& _sectionInfo ) {
virtual void sectionStarting( SectionInfo const& _sectionInfo ) CATCH_OVERRIDE {
m_sectionStack.push_back( _sectionInfo );
}
virtual void sectionEnded( SectionStats const& /* _sectionStats */ ) {
virtual void sectionEnded( SectionStats const& /* _sectionStats */ ) CATCH_OVERRIDE {
m_sectionStack.pop_back();
}
virtual void testCaseEnded( TestCaseStats const& /* _testCaseStats */ ) {
virtual void testCaseEnded( TestCaseStats const& /* _testCaseStats */ ) CATCH_OVERRIDE {
currentTestCaseInfo.reset();
}
virtual void testGroupEnded( TestGroupStats const& /* _testGroupStats */ ) {
virtual void testGroupEnded( TestGroupStats const& /* _testGroupStats */ ) CATCH_OVERRIDE {
currentGroupInfo.reset();
}
virtual void testRunEnded( TestRunStats const& /* _testRunStats */ ) {
virtual void testRunEnded( TestRunStats const& /* _testRunStats */ ) CATCH_OVERRIDE {
currentTestCaseInfo.reset();
currentGroupInfo.reset();
currentTestRunInfo.reset();
}
virtual void skipTest( TestCaseInfo const& ) {
virtual void skipTest( TestCaseInfo const& ) CATCH_OVERRIDE {
// Don't do anything with this by default.
// It can optionally be overridden in the derived class.
}
@@ -67,6 +73,7 @@ namespace Catch {
LazyStat<TestCaseInfo> currentTestCaseInfo;
std::vector<SectionInfo> m_sectionStack;
ReporterPreferences m_reporterPrefs;
};
struct CumulativeReporterBase : SharedImpl<IStreamingReporter> {
@@ -118,15 +125,21 @@ namespace Catch {
CumulativeReporterBase( ReporterConfig const& _config )
: m_config( _config.fullConfig() ),
stream( _config.stream() )
{}
{
m_reporterPrefs.shouldRedirectStdOut = false;
}
~CumulativeReporterBase();
virtual void testRunStarting( TestRunInfo const& ) {}
virtual void testGroupStarting( GroupInfo const& ) {}
virtual ReporterPreferences getPreferences() const CATCH_OVERRIDE {
return m_reporterPrefs;
}
virtual void testCaseStarting( TestCaseInfo const& ) {}
virtual void testRunStarting( TestRunInfo const& ) CATCH_OVERRIDE {}
virtual void testGroupStarting( GroupInfo const& ) CATCH_OVERRIDE {}
virtual void sectionStarting( SectionInfo const& sectionInfo ) {
virtual void testCaseStarting( TestCaseInfo const& ) CATCH_OVERRIDE {}
virtual void sectionStarting( SectionInfo const& sectionInfo ) CATCH_OVERRIDE {
SectionStats incompleteStats( sectionInfo, Counts(), 0, false );
Ptr<SectionNode> node;
if( m_sectionStack.empty() ) {
@@ -151,7 +164,7 @@ namespace Catch {
m_deepestSection = node;
}
virtual void assertionStarting( AssertionInfo const& ) {}
virtual void assertionStarting( AssertionInfo const& ) CATCH_OVERRIDE {}
virtual bool assertionEnded( AssertionStats const& assertionStats ) {
assert( !m_sectionStack.empty() );
@@ -159,13 +172,13 @@ namespace Catch {
sectionNode.assertions.push_back( assertionStats );
return true;
}
virtual void sectionEnded( SectionStats const& sectionStats ) {
virtual void sectionEnded( SectionStats const& sectionStats ) CATCH_OVERRIDE {
assert( !m_sectionStack.empty() );
SectionNode& node = *m_sectionStack.back();
node.stats = sectionStats;
m_sectionStack.pop_back();
}
virtual void testCaseEnded( TestCaseStats const& testCaseStats ) {
virtual void testCaseEnded( TestCaseStats const& testCaseStats ) CATCH_OVERRIDE {
Ptr<TestCaseNode> node = new TestCaseNode( testCaseStats );
assert( m_sectionStack.size() == 0 );
node->children.push_back( m_rootSection );
@@ -176,12 +189,12 @@ namespace Catch {
m_deepestSection->stdOut = testCaseStats.stdOut;
m_deepestSection->stdErr = testCaseStats.stdErr;
}
virtual void testGroupEnded( TestGroupStats const& testGroupStats ) {
virtual void testGroupEnded( TestGroupStats const& testGroupStats ) CATCH_OVERRIDE {
Ptr<TestGroupNode> node = new TestGroupNode( testGroupStats );
node->children.swap( m_testCases );
m_testGroups.push_back( node );
}
virtual void testRunEnded( TestRunStats const& testRunStats ) {
virtual void testRunEnded( TestRunStats const& testRunStats ) CATCH_OVERRIDE {
Ptr<TestRunNode> node = new TestRunNode( testRunStats );
node->children.swap( m_testGroups );
m_testRuns.push_back( node );
@@ -189,7 +202,7 @@ namespace Catch {
}
virtual void testRunEndedCumulative() = 0;
virtual void skipTest( TestCaseInfo const& ) {}
virtual void skipTest( TestCaseInfo const& ) CATCH_OVERRIDE {}
Ptr<IConfig> m_config;
std::ostream& stream;
@@ -203,6 +216,7 @@ namespace Catch {
Ptr<SectionNode> m_rootSection;
Ptr<SectionNode> m_deepestSection;
std::vector<Ptr<SectionNode> > m_sectionStack;
ReporterPreferences m_reporterPrefs;
};
@@ -216,6 +230,18 @@ namespace Catch {
return line;
}
struct TestEventListenerBase : StreamingReporterBase {
TestEventListenerBase( ReporterConfig const& _config )
: StreamingReporterBase( _config )
{}
virtual void assertionStarting( AssertionInfo const& ) CATCH_OVERRIDE {}
virtual bool assertionEnded( AssertionStats const& _assertionStats ) CATCH_OVERRIDE {
return false;
}
};
} // end namespace Catch
#endif // TWOBLUECUBES_CATCH_REPORTER_BASES_HPP_INCLUDED
+9 -14
View File
@@ -21,24 +21,19 @@ namespace Catch {
m_headerPrinted( false )
{}
virtual ~ConsoleReporter();
virtual ~ConsoleReporter() CATCH_OVERRIDE;
static std::string getDescription() {
return "Reports test results as plain lines of text";
}
virtual ReporterPreferences getPreferences() const {
ReporterPreferences prefs;
prefs.shouldRedirectStdOut = false;
return prefs;
}
virtual void noMatchingTestCases( std::string const& spec ) {
virtual void noMatchingTestCases( std::string const& spec ) CATCH_OVERRIDE {
stream << "No test cases matched '" << spec << "'" << std::endl;
}
virtual void assertionStarting( AssertionInfo const& ) {
virtual void assertionStarting( AssertionInfo const& ) CATCH_OVERRIDE {
}
virtual bool assertionEnded( AssertionStats const& _assertionStats ) {
virtual bool assertionEnded( AssertionStats const& _assertionStats ) CATCH_OVERRIDE {
AssertionResult const& result = _assertionStats.assertionResult;
bool printInfoMessages = true;
@@ -58,11 +53,11 @@ namespace Catch {
return true;
}
virtual void sectionStarting( SectionInfo const& _sectionInfo ) {
virtual void sectionStarting( SectionInfo const& _sectionInfo ) CATCH_OVERRIDE {
m_headerPrinted = false;
StreamingReporterBase::sectionStarting( _sectionInfo );
}
virtual void sectionEnded( SectionStats const& _sectionStats ) {
virtual void sectionEnded( SectionStats const& _sectionStats ) CATCH_OVERRIDE {
if( _sectionStats.missingAssertions ) {
lazyPrint();
Colour colour( Colour::ResultError );
@@ -84,11 +79,11 @@ namespace Catch {
StreamingReporterBase::sectionEnded( _sectionStats );
}
virtual void testCaseEnded( TestCaseStats const& _testCaseStats ) {
virtual void testCaseEnded( TestCaseStats const& _testCaseStats ) CATCH_OVERRIDE {
StreamingReporterBase::testCaseEnded( _testCaseStats );
m_headerPrinted = false;
}
virtual void testGroupEnded( TestGroupStats const& _testGroupStats ) {
virtual void testGroupEnded( TestGroupStats const& _testGroupStats ) CATCH_OVERRIDE {
if( currentGroupInfo.used ) {
printSummaryDivider();
stream << "Summary for group '" << _testGroupStats.groupInfo.name << "':\n";
@@ -97,7 +92,7 @@ namespace Catch {
}
StreamingReporterBase::testGroupEnded( _testGroupStats );
}
virtual void testRunEnded( TestRunStats const& _testRunStats ) {
virtual void testRunEnded( TestRunStats const& _testRunStats ) CATCH_OVERRIDE {
printTotalsDivider( _testRunStats.totals );
printTotals( _testRunStats.totals );
stream << std::endl;
+11 -15
View File
@@ -23,28 +23,24 @@ namespace Catch {
JunitReporter( ReporterConfig const& _config )
: CumulativeReporterBase( _config ),
xml( _config.stream() )
{}
{
m_reporterPrefs.shouldRedirectStdOut = true;
}
~JunitReporter();
virtual ~JunitReporter() CATCH_OVERRIDE;
static std::string getDescription() {
return "Reports test results in an XML format that looks like Ant's junitreport target";
}
virtual void noMatchingTestCases( std::string const& /*spec*/ ) {}
virtual void noMatchingTestCases( std::string const& /*spec*/ ) CATCH_OVERRIDE {}
virtual ReporterPreferences getPreferences() const {
ReporterPreferences prefs;
prefs.shouldRedirectStdOut = true;
return prefs;
}
virtual void testRunStarting( TestRunInfo const& runInfo ) {
virtual void testRunStarting( TestRunInfo const& runInfo ) CATCH_OVERRIDE {
CumulativeReporterBase::testRunStarting( runInfo );
xml.startElement( "testsuites" );
}
virtual void testGroupStarting( GroupInfo const& groupInfo ) {
virtual void testGroupStarting( GroupInfo const& groupInfo ) CATCH_OVERRIDE {
suiteTimer.start();
stdOutForSuite.str("");
stdErrForSuite.str("");
@@ -52,25 +48,25 @@ namespace Catch {
CumulativeReporterBase::testGroupStarting( groupInfo );
}
virtual bool assertionEnded( AssertionStats const& assertionStats ) {
virtual bool assertionEnded( AssertionStats const& assertionStats ) CATCH_OVERRIDE {
if( assertionStats.assertionResult.getResultType() == ResultWas::ThrewException )
unexpectedExceptions++;
return CumulativeReporterBase::assertionEnded( assertionStats );
}
virtual void testCaseEnded( TestCaseStats const& testCaseStats ) {
virtual void testCaseEnded( TestCaseStats const& testCaseStats ) CATCH_OVERRIDE {
stdOutForSuite << testCaseStats.stdOut;
stdErrForSuite << testCaseStats.stdErr;
CumulativeReporterBase::testCaseEnded( testCaseStats );
}
virtual void testGroupEnded( TestGroupStats const& testGroupStats ) {
virtual void testGroupEnded( TestGroupStats const& testGroupStats ) CATCH_OVERRIDE {
double suiteTime = suiteTimer.getElapsedSeconds();
CumulativeReporterBase::testGroupEnded( testGroupStats );
writeGroup( *m_testGroups.back(), suiteTime );
}
virtual void testRunEndedCumulative() {
virtual void testRunEndedCumulative() CATCH_OVERRIDE {
xml.endElement();
}
+147
View File
@@ -0,0 +1,147 @@
/*
* Created by Phil on 5/08/2015.
* Copyright 2015 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_MULTI_HPP_INCLUDED
#define TWOBLUECUBES_CATCH_REPORTER_MULTI_HPP_INCLUDED
#include "../internal/catch_interfaces_reporter.h"
namespace Catch {
class MultipleReporters : public SharedImpl<IStreamingReporter> {
typedef std::vector<Ptr<IStreamingReporter> > Reporters;
Reporters m_reporters;
public:
void add( Ptr<IStreamingReporter> const& reporter ) {
m_reporters.push_back( reporter );
}
public: // IStreamingReporter
virtual ReporterPreferences getPreferences() const CATCH_OVERRIDE {
return m_reporters[0]->getPreferences();
}
virtual void noMatchingTestCases( std::string const& spec ) CATCH_OVERRIDE {
for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end();
it != itEnd;
++it )
(*it)->noMatchingTestCases( spec );
}
virtual void testRunStarting( TestRunInfo const& testRunInfo ) CATCH_OVERRIDE {
for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end();
it != itEnd;
++it )
(*it)->testRunStarting( testRunInfo );
}
virtual void testGroupStarting( GroupInfo const& groupInfo ) CATCH_OVERRIDE {
for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end();
it != itEnd;
++it )
(*it)->testGroupStarting( groupInfo );
}
virtual void testCaseStarting( TestCaseInfo const& testInfo ) CATCH_OVERRIDE {
for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end();
it != itEnd;
++it )
(*it)->testCaseStarting( testInfo );
}
virtual void sectionStarting( SectionInfo const& sectionInfo ) CATCH_OVERRIDE {
for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end();
it != itEnd;
++it )
(*it)->sectionStarting( sectionInfo );
}
virtual void assertionStarting( AssertionInfo const& assertionInfo ) CATCH_OVERRIDE {
for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end();
it != itEnd;
++it )
(*it)->assertionStarting( assertionInfo );
}
// The return value indicates if the messages buffer should be cleared:
virtual bool assertionEnded( AssertionStats const& assertionStats ) CATCH_OVERRIDE {
bool clearBuffer = false;
for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end();
it != itEnd;
++it )
clearBuffer |= (*it)->assertionEnded( assertionStats );
return clearBuffer;
}
virtual void sectionEnded( SectionStats const& sectionStats ) CATCH_OVERRIDE {
for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end();
it != itEnd;
++it )
(*it)->sectionEnded( sectionStats );
}
virtual void testCaseEnded( TestCaseStats const& testCaseStats ) CATCH_OVERRIDE {
for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end();
it != itEnd;
++it )
(*it)->testCaseEnded( testCaseStats );
}
virtual void testGroupEnded( TestGroupStats const& testGroupStats ) CATCH_OVERRIDE {
for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end();
it != itEnd;
++it )
(*it)->testGroupEnded( testGroupStats );
}
virtual void testRunEnded( TestRunStats const& testRunStats ) CATCH_OVERRIDE {
for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end();
it != itEnd;
++it )
(*it)->testRunEnded( testRunStats );
}
virtual void skipTest( TestCaseInfo const& testInfo ) CATCH_OVERRIDE {
for( Reporters::const_iterator it = m_reporters.begin(), itEnd = m_reporters.end();
it != itEnd;
++it )
(*it)->skipTest( testInfo );
}
};
Ptr<IStreamingReporter> addReporter( Ptr<IStreamingReporter> const& existingReporter, Ptr<IStreamingReporter> const& additionalReporter ) {
Ptr<IStreamingReporter> resultingReporter;
if( existingReporter ) {
MultipleReporters* multi = dynamic_cast<MultipleReporters*>( existingReporter.get() );
if( !multi ) {
multi = new MultipleReporters;
resultingReporter = Ptr<IStreamingReporter>( multi );
if( existingReporter )
multi->add( existingReporter );
}
else
resultingReporter = existingReporter;
multi->add( additionalReporter );
}
else
resultingReporter = additionalReporter;
return resultingReporter;
}
} // end namespace Catch
#endif // TWOBLUECUBES_CATCH_REPORTER_MULTI_HPP_INCLUDED
+18 -19
View File
@@ -17,8 +17,10 @@
#include <cstring>
#ifdef __clang__
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wpadded"
# pragma clang diagnostic push
# pragma clang diagnostic ignored "-Wpadded"
# pragma clang diagnostic ignored "-Wc++98-compat"
# pragma clang diagnostic ignored "-Wc++98-compat-pedantic"
#endif
namespace Catch {
@@ -27,7 +29,9 @@ namespace Catch {
TeamCityReporter( ReporterConfig const& _config )
: StreamingReporterBase( _config ),
m_headerPrintedForThisSection( false )
{}
{
m_reporterPrefs.shouldRedirectStdOut = true;
}
static std::string escape( std::string const& str ) {
std::string escaped = str;
@@ -39,18 +43,13 @@ namespace Catch {
replaceInPlace( escaped, "]", "|]" );
return escaped;
}
virtual ~TeamCityReporter();
virtual ~TeamCityReporter() CATCH_OVERRIDE;
static std::string getDescription() {
return "Reports test results as TeamCity service messages";
}
virtual ReporterPreferences getPreferences() const {
ReporterPreferences prefs;
prefs.shouldRedirectStdOut = true;
return prefs;
}
virtual void skipTest( TestCaseInfo const& testInfo ) {
virtual void skipTest( TestCaseInfo const& testInfo ) CATCH_OVERRIDE {
stream << "##teamcity[testIgnored name='"
<< escape( testInfo.name ) << "'";
if( testInfo.isHidden() )
@@ -60,24 +59,24 @@ namespace Catch {
stream << "]\n";
}
virtual void noMatchingTestCases( std::string const& /* spec */ ) {}
virtual void noMatchingTestCases( std::string const& /* spec */ ) CATCH_OVERRIDE {}
virtual void testGroupStarting( GroupInfo const& groupInfo ) {
virtual void testGroupStarting( GroupInfo const& groupInfo ) CATCH_OVERRIDE {
StreamingReporterBase::testGroupStarting( groupInfo );
stream << "##teamcity[testSuiteStarted name='"
<< escape( groupInfo.name ) << "']\n";
}
virtual void testGroupEnded( TestGroupStats const& testGroupStats ) {
virtual void testGroupEnded( TestGroupStats const& testGroupStats ) CATCH_OVERRIDE {
StreamingReporterBase::testGroupEnded( testGroupStats );
stream << "##teamcity[testSuiteFinished name='"
<< escape( testGroupStats.groupInfo.name ) << "']\n";
}
virtual void assertionStarting( AssertionInfo const& ) {
virtual void assertionStarting( AssertionInfo const& ) CATCH_OVERRIDE {
}
virtual bool assertionEnded( AssertionStats const& assertionStats ) {
virtual bool assertionEnded( AssertionStats const& assertionStats ) CATCH_OVERRIDE {
AssertionResult const& result = assertionStats.assertionResult;
if( !result.isOk() ) {
@@ -143,18 +142,18 @@ namespace Catch {
return true;
}
virtual void sectionStarting( SectionInfo const& sectionInfo ) {
virtual void sectionStarting( SectionInfo const& sectionInfo ) CATCH_OVERRIDE {
m_headerPrintedForThisSection = false;
StreamingReporterBase::sectionStarting( sectionInfo );
}
virtual void testCaseStarting( TestCaseInfo const& testInfo ) {
virtual void testCaseStarting( TestCaseInfo const& testInfo ) CATCH_OVERRIDE {
StreamingReporterBase::testCaseStarting( testInfo );
stream << "##teamcity[testStarted name='"
<< escape( testInfo.name ) << "']\n";
}
virtual void testCaseEnded( TestCaseStats const& testCaseStats ) {
virtual void testCaseEnded( TestCaseStats const& testCaseStats ) CATCH_OVERRIDE {
StreamingReporterBase::testCaseEnded( testCaseStats );
if( !testCaseStats.stdOut.empty() )
stream << "##teamcity[testStdOut name='"
@@ -216,7 +215,7 @@ namespace Catch {
} // end namespace Catch
#ifdef __clang__
#pragma clang diagnostic pop
# pragma clang diagnostic pop
#endif
#endif // TWOBLUECUBES_CATCH_REPORTER_TEAMCITY_HPP_INCLUDED
+15 -18
View File
@@ -21,26 +21,23 @@ namespace Catch {
XmlReporter( ReporterConfig const& _config )
: StreamingReporterBase( _config ),
m_sectionDepth( 0 )
{}
{
m_reporterPrefs.shouldRedirectStdOut = true;
}
virtual ~XmlReporter();
virtual ~XmlReporter() CATCH_OVERRIDE;
static std::string getDescription() {
return "Reports test results as an XML document";
}
public: // StreamingReporterBase
virtual ReporterPreferences getPreferences() const {
ReporterPreferences prefs;
prefs.shouldRedirectStdOut = true;
return prefs;
}
virtual void noMatchingTestCases( std::string const& s ) {
virtual void noMatchingTestCases( std::string const& s ) CATCH_OVERRIDE {
StreamingReporterBase::noMatchingTestCases( s );
}
virtual void testRunStarting( TestRunInfo const& testInfo ) {
virtual void testRunStarting( TestRunInfo const& testInfo ) CATCH_OVERRIDE {
StreamingReporterBase::testRunStarting( testInfo );
m_xml.setStream( stream );
m_xml.startElement( "Catch" );
@@ -48,13 +45,13 @@ namespace Catch {
m_xml.writeAttribute( "name", m_config->name() );
}
virtual void testGroupStarting( GroupInfo const& groupInfo ) {
virtual void testGroupStarting( GroupInfo const& groupInfo ) CATCH_OVERRIDE {
StreamingReporterBase::testGroupStarting( groupInfo );
m_xml.startElement( "Group" )
.writeAttribute( "name", groupInfo.name );
}
virtual void testCaseStarting( TestCaseInfo const& testInfo ) {
virtual void testCaseStarting( TestCaseInfo const& testInfo ) CATCH_OVERRIDE {
StreamingReporterBase::testCaseStarting(testInfo);
m_xml.startElement( "TestCase" ).writeAttribute( "name", trim( testInfo.name ) );
@@ -62,7 +59,7 @@ namespace Catch {
m_testCaseTimer.start();
}
virtual void sectionStarting( SectionInfo const& sectionInfo ) {
virtual void sectionStarting( SectionInfo const& sectionInfo ) CATCH_OVERRIDE {
StreamingReporterBase::sectionStarting( sectionInfo );
if( m_sectionDepth++ > 0 ) {
m_xml.startElement( "Section" )
@@ -71,9 +68,9 @@ namespace Catch {
}
}
virtual void assertionStarting( AssertionInfo const& ) { }
virtual void assertionStarting( AssertionInfo const& ) CATCH_OVERRIDE { }
virtual bool assertionEnded( AssertionStats const& assertionStats ) {
virtual bool assertionEnded( AssertionStats const& assertionStats ) CATCH_OVERRIDE {
const AssertionResult& assertionResult = assertionStats.assertionResult;
// Print any info messages in <Info> tags.
@@ -144,7 +141,7 @@ namespace Catch {
return true;
}
virtual void sectionEnded( SectionStats const& sectionStats ) {
virtual void sectionEnded( SectionStats const& sectionStats ) CATCH_OVERRIDE {
StreamingReporterBase::sectionEnded( sectionStats );
if( --m_sectionDepth > 0 ) {
XmlWriter::ScopedElement e = m_xml.scopedElement( "OverallResults" );
@@ -159,7 +156,7 @@ namespace Catch {
}
}
virtual void testCaseEnded( TestCaseStats const& testCaseStats ) {
virtual void testCaseEnded( TestCaseStats const& testCaseStats ) CATCH_OVERRIDE {
StreamingReporterBase::testCaseEnded( testCaseStats );
XmlWriter::ScopedElement e = m_xml.scopedElement( "OverallResult" );
e.writeAttribute( "success", testCaseStats.totals.assertions.allOk() );
@@ -170,7 +167,7 @@ namespace Catch {
m_xml.endElement();
}
virtual void testGroupEnded( TestGroupStats const& testGroupStats ) {
virtual void testGroupEnded( TestGroupStats const& testGroupStats ) CATCH_OVERRIDE {
StreamingReporterBase::testGroupEnded( testGroupStats );
// TODO: Check testGroupStats.aborting and act accordingly.
m_xml.scopedElement( "OverallResults" )
@@ -180,7 +177,7 @@ namespace Catch {
m_xml.endElement();
}
virtual void testRunEnded( TestRunStats const& testRunStats ) {
virtual void testRunEnded( TestRunStats const& testRunStats ) CATCH_OVERRIDE {
StreamingReporterBase::testRunEnded( testRunStats );
m_xml.scopedElement( "OverallResults" )
.writeAttribute( "successes", testRunStats.totals.assertions.passed )
@@ -797,6 +797,6 @@ with expansion:
"first" == "second"
===============================================================================
test cases: 157 | 117 passed | 39 failed | 1 failed as expected
assertions: 773 | 680 passed | 80 failed | 13 failed as expected
test cases: 159 | 119 passed | 39 failed | 1 failed as expected
assertions: 788 | 695 passed | 80 failed | 13 failed as expected
@@ -3762,6 +3762,142 @@ PASSED:
with expansion:
""wide load"" == ""wide load""
-------------------------------------------------------------------------------
XmlEncode
normal string
-------------------------------------------------------------------------------
MiscTests.cpp:<line number>
...............................................................................
MiscTests.cpp:<line number>:
PASSED:
REQUIRE( encode( "normal string" ) == "normal string" )
with expansion:
"normal string" == "normal string"
-------------------------------------------------------------------------------
XmlEncode
empty string
-------------------------------------------------------------------------------
MiscTests.cpp:<line number>
...............................................................................
MiscTests.cpp:<line number>:
PASSED:
REQUIRE( encode( "" ) == "" )
with expansion:
"" == ""
-------------------------------------------------------------------------------
XmlEncode
string with ampersand
-------------------------------------------------------------------------------
MiscTests.cpp:<line number>
...............................................................................
MiscTests.cpp:<line number>:
PASSED:
REQUIRE( encode( "smith & jones" ) == "smith &amp; jones" )
with expansion:
"smith &amp; jones" == "smith &amp; jones"
-------------------------------------------------------------------------------
XmlEncode
string with less-than
-------------------------------------------------------------------------------
MiscTests.cpp:<line number>
...............................................................................
MiscTests.cpp:<line number>:
PASSED:
REQUIRE( encode( "smith < jones" ) == "smith &lt; jones" )
with expansion:
"smith &lt; jones" == "smith &lt; jones"
-------------------------------------------------------------------------------
XmlEncode
string with greater-than
-------------------------------------------------------------------------------
MiscTests.cpp:<line number>
...............................................................................
MiscTests.cpp:<line number>:
PASSED:
REQUIRE( encode( "smith > jones" ) == "smith > jones" )
with expansion:
"smith > jones" == "smith > jones"
MiscTests.cpp:<line number>:
PASSED:
REQUIRE( encode( "smith ]]> jones" ) == "smith ]]&gt; jones" )
with expansion:
"smith ]]&gt; jones"
==
"smith ]]&gt; jones"
-------------------------------------------------------------------------------
XmlEncode
string with quotes
-------------------------------------------------------------------------------
MiscTests.cpp:<line number>
...............................................................................
MiscTests.cpp:<line number>:
PASSED:
REQUIRE( encode( stringWithQuotes ) == stringWithQuotes )
with expansion:
"don't "quote" me on that"
==
"don't "quote" me on that"
MiscTests.cpp:<line number>:
PASSED:
REQUIRE( encode( stringWithQuotes, Catch::XmlEncode::ForAttributes ) == "don't &quot;quote&quot; me on that" )
with expansion:
"don't &quot;quote&quot; me on that"
==
"don't &quot;quote&quot; me on that"
-------------------------------------------------------------------------------
XmlEncode
string with control char (1)
-------------------------------------------------------------------------------
MiscTests.cpp:<line number>
...............................................................................
MiscTests.cpp:<line number>:
PASSED:
REQUIRE( encode( "[\x01]" ) == "[&#x1]" )
with expansion:
"[&#x1]" == "[&#x1]"
-------------------------------------------------------------------------------
XmlEncode
string with control char (x7F)
-------------------------------------------------------------------------------
MiscTests.cpp:<line number>
...............................................................................
MiscTests.cpp:<line number>:
PASSED:
REQUIRE( encode( "[\x7F]" ) == "[&#x7F]" )
with expansion:
"[&#x7F]" == "[&#x7F]"
-------------------------------------------------------------------------------
long long
-------------------------------------------------------------------------------
MiscTests.cpp:<line number>
...............................................................................
MiscTests.cpp:<line number>:
PASSED:
REQUIRE( l == std::numeric_limits<long long>::max() )
with expansion:
9223372036854775807 (0x<hex digits>)
==
9223372036854775807 (0x<hex digits>)
-------------------------------------------------------------------------------
Process can be configured on command line
default - no arguments
@@ -3793,7 +3929,7 @@ with expansion:
TestMain.cpp:<line number>:
PASSED:
CHECK( config.reporterName.empty() )
CHECK( config.reporterNames.empty() )
with expansion:
true
@@ -3883,7 +4019,7 @@ PASSED:
TestMain.cpp:<line number>:
PASSED:
REQUIRE( config.reporterName == "console" )
REQUIRE( config.reporterNames[0] == "console" )
with expansion:
"console" == "console"
@@ -3901,10 +4037,40 @@ PASSED:
TestMain.cpp:<line number>:
PASSED:
REQUIRE( config.reporterName == "xml" )
REQUIRE( config.reporterNames[0] == "xml" )
with expansion:
"xml" == "xml"
-------------------------------------------------------------------------------
Process can be configured on command line
reporter
-r xml and junit
-------------------------------------------------------------------------------
TestMain.cpp:<line number>
...............................................................................
TestMain.cpp:<line number>:
PASSED:
CHECK_NOTHROW( parseIntoConfig( argv, config ) )
TestMain.cpp:<line number>:
PASSED:
REQUIRE( config.reporterNames.size() == 2 )
with expansion:
2 == 2
TestMain.cpp:<line number>:
PASSED:
REQUIRE( config.reporterNames[0] == "xml" )
with expansion:
"xml" == "xml"
TestMain.cpp:<line number>:
PASSED:
REQUIRE( config.reporterNames[1] == "junit" )
with expansion:
"junit" == "junit"
-------------------------------------------------------------------------------
Process can be configured on command line
reporter
@@ -3919,7 +4085,7 @@ PASSED:
TestMain.cpp:<line number>:
PASSED:
REQUIRE( config.reporterName == "junit" )
REQUIRE( config.reporterNames[0] == "junit" )
with expansion:
"junit" == "junit"
@@ -8004,6 +8170,6 @@ with expansion:
true
===============================================================================
test cases: 157 | 101 passed | 55 failed | 1 failed as expected
assertions: 793 | 680 passed | 100 failed | 13 failed as expected
test cases: 159 | 103 passed | 55 failed | 1 failed as expected
assertions: 808 | 695 passed | 100 failed | 13 failed as expected
@@ -1,5 +1,5 @@
<testsuites>
<testsuite name="all tests" errors="12" failures="88" tests="793" hostname="tbd" time="{duration}" timestamp="tbd">
<testsuite name="CatchSelfTest" errors="12" failures="88" tests="808" hostname="tbd" time="{duration}" timestamp="tbd">
<testcase classname="global" name="toString(enum)" time="{duration}"/>
<testcase classname="global" name="toString(enum w/operator&lt;&lt;)" time="{duration}"/>
<testcase classname="global" name="toString(enum class)" time="{duration}"/>
@@ -463,12 +463,22 @@ MiscTests.cpp:<line number>
<testcase classname="global" name="toString on const wchar_t pointer returns the string contents" time="{duration}"/>
<testcase classname="global" name="toString on wchar_t const pointer returns the string contents" time="{duration}"/>
<testcase classname="global" name="toString on wchar_t returns the string contents" time="{duration}"/>
<testcase classname="XmlEncode" name="normal string" time="{duration}"/>
<testcase classname="XmlEncode" name="empty string" time="{duration}"/>
<testcase classname="XmlEncode" name="string with ampersand" time="{duration}"/>
<testcase classname="XmlEncode" name="string with less-than" time="{duration}"/>
<testcase classname="XmlEncode" name="string with greater-than" time="{duration}"/>
<testcase classname="XmlEncode" name="string with quotes" time="{duration}"/>
<testcase classname="XmlEncode" name="string with control char (1)" time="{duration}"/>
<testcase classname="XmlEncode" name="string with control char (x7F)" time="{duration}"/>
<testcase classname="global" name="long long" time="{duration}"/>
<testcase classname="Process can be configured on command line" name="default - no arguments" time="{duration}"/>
<testcase classname="Process can be configured on command line" name="test lists/1 test" time="{duration}"/>
<testcase classname="Process can be configured on command line" name="test lists/Specify one test case exclusion using exclude:" time="{duration}"/>
<testcase classname="Process can be configured on command line" name="test lists/Specify one test case exclusion using ~" time="{duration}"/>
<testcase classname="Process can be configured on command line" name="reporter/-r/console" time="{duration}"/>
<testcase classname="Process can be configured on command line" name="reporter/-r/xml" time="{duration}"/>
<testcase classname="Process can be configured on command line" name="reporter/-r xml and junit" time="{duration}"/>
<testcase classname="Process can be configured on command line" name="reporter/--reporter/junit" time="{duration}"/>
<testcase classname="Process can be configured on command line" name="debugger/-b" time="{duration}"/>
<testcase classname="Process can be configured on command line" name="debugger/--break" time="{duration}"/>
File diff suppressed because it is too large Load Diff
+50 -3
View File
@@ -8,12 +8,15 @@
#include "catch.hpp"
#include <iostream>
#ifdef __clang__
#pragma clang diagnostic ignored "-Wc++98-compat-pedantic"
# pragma clang diagnostic ignored "-Wc++98-compat"
# pragma clang diagnostic ignored "-Wc++98-compat-pedantic"
#endif
#include "../include/internal/catch_xmlwriter.hpp"
#include <iostream>
TEST_CASE( "random SECTION tests", "[.][sections][failing]" )
{
int a = 1;
@@ -381,6 +384,50 @@ TEST_CASE( "toString on wchar_t returns the string contents", "[toString]" ) {
CHECK( result == "\"wide load\"" );
}
inline std::string encode( std::string const& str, Catch::XmlEncode::ForWhat forWhat = Catch::XmlEncode::ForTextNodes ) {
std::ostringstream oss;
oss << Catch::XmlEncode( str, forWhat );
return oss.str();
}
TEST_CASE( "XmlEncode" ) {
SECTION( "normal string" ) {
REQUIRE( encode( "normal string" ) == "normal string" );
}
SECTION( "empty string" ) {
REQUIRE( encode( "" ) == "" );
}
SECTION( "string with ampersand" ) {
REQUIRE( encode( "smith & jones" ) == "smith &amp; jones" );
}
SECTION( "string with less-than" ) {
REQUIRE( encode( "smith < jones" ) == "smith &lt; jones" );
}
SECTION( "string with greater-than" ) {
REQUIRE( encode( "smith > jones" ) == "smith > jones" );
REQUIRE( encode( "smith ]]> jones" ) == "smith ]]&gt; jones" );
}
SECTION( "string with quotes" ) {
std::string stringWithQuotes = "don't \"quote\" me on that";
REQUIRE( encode( stringWithQuotes ) == stringWithQuotes );
REQUIRE( encode( stringWithQuotes, Catch::XmlEncode::ForAttributes ) == "don't &quot;quote&quot; me on that" );
}
SECTION( "string with control char (1)" ) {
REQUIRE( encode( "[\x01]" ) == "[&#x1]" );
}
SECTION( "string with control char (x7F)" ) {
REQUIRE( encode( "[\x7F]" ) == "[&#x7F]" );
}
}
#ifdef CATCH_CONFIG_CPP11_LONG_LONG
TEST_CASE( "long long" ) {
long long l = std::numeric_limits<long long>::max();
REQUIRE( l == std::numeric_limits<long long>::max() );
}
#endif
//TEST_CASE( "Divide by Zero signal handler", "[.][sig]" ) {
// int i = 0;
// int x = 10/i; // This should cause the signal to fire
@@ -1 +1,2 @@
#include "catch_suppress_warnings.h"
#include "catch_interfaces_exception.h"
@@ -1,2 +1,3 @@
// This file is only here to verify (to the extent possible) the self sufficiency of the header
#include "catch_suppress_warnings.h"
#include "catch_interfaces_registry_hub.h"
+13 -5
View File
@@ -8,7 +8,7 @@
#define CATCH_CONFIG_MAIN
#include "catch.hpp"
#include "reporters/catch_reporter_teamcity.hpp"
#include "../include/reporters/catch_reporter_teamcity.hpp"
// Some example tag aliases
CATCH_REGISTER_TAG_ALIAS( "[@nhf]", "[failing]~[.]" )
@@ -53,7 +53,7 @@ TEST_CASE( "Process can be configured on command line", "[config][command-line]"
CHECK( config.shouldDebugBreak == false );
CHECK( config.abortAfter == -1 );
CHECK( config.noThrow == false );
CHECK( config.reporterName.empty() );
CHECK( config.reporterNames.empty() );
}
SECTION( "test lists", "" ) {
@@ -90,19 +90,27 @@ TEST_CASE( "Process can be configured on command line", "[config][command-line]"
const char* argv[] = { "test", "-r", "console" };
CHECK_NOTHROW( parseIntoConfig( argv, config ) );
REQUIRE( config.reporterName == "console" );
REQUIRE( config.reporterNames[0] == "console" );
}
SECTION( "-r/xml", "" ) {
const char* argv[] = { "test", "-r", "xml" };
CHECK_NOTHROW( parseIntoConfig( argv, config ) );
REQUIRE( config.reporterName == "xml" );
REQUIRE( config.reporterNames[0] == "xml" );
}
SECTION( "-r xml and junit", "" ) {
const char* argv[] = { "test", "-r", "xml", "-r", "junit" };
CHECK_NOTHROW( parseIntoConfig( argv, config ) );
REQUIRE( config.reporterNames.size() == 2 );
REQUIRE( config.reporterNames[0] == "xml" );
REQUIRE( config.reporterNames[1] == "junit" );
}
SECTION( "--reporter/junit", "" ) {
const char* argv[] = { "test", "--reporter", "junit" };
CHECK_NOTHROW( parseIntoConfig( argv, config ) );
REQUIRE( config.reporterName == "junit" );
REQUIRE( config.reporterNames[0] == "junit" );
}
}
@@ -110,6 +110,7 @@
26DACF2F17206D3400A21326 /* catch_text.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = catch_text.h; sourceTree = "<group>"; };
26DFD3B11B53F84700FD6F16 /* catch_wildcard_pattern.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = catch_wildcard_pattern.hpp; sourceTree = "<group>"; };
26E1B7D119213BC900812682 /* CmdLineTests.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CmdLineTests.cpp; path = ../../../SelfTest/CmdLineTests.cpp; sourceTree = "<group>"; };
26EDFBD91B72011F00B1873C /* catch_reporter_multi.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = catch_reporter_multi.hpp; sourceTree = "<group>"; };
4A084F1C15DACEEA0027E631 /* catch_test_case_info.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = catch_test_case_info.hpp; sourceTree = "<group>"; };
4A3D7DD01503869D005F9203 /* catch_matchers.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = catch_matchers.hpp; sourceTree = "<group>"; };
4A45DA2316161EF9004F8D6B /* catch_console_colour.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = catch_console_colour.cpp; path = ../../../SelfTest/SurrogateCpps/catch_console_colour.cpp; sourceTree = "<group>"; };
@@ -136,7 +137,7 @@
4A6D0C34149B3D9E00DB3EAA /* MiscTests.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = MiscTests.cpp; path = ../../../SelfTest/MiscTests.cpp; sourceTree = "<group>"; };
4A6D0C35149B3D9E00DB3EAA /* TestMain.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = TestMain.cpp; path = ../../../SelfTest/TestMain.cpp; sourceTree = "<group>"; };
4A6D0C36149B3D9E00DB3EAA /* TrickyTests.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = TrickyTests.cpp; path = ../../../SelfTest/TrickyTests.cpp; sourceTree = "<group>"; };
4A6D0C42149B3E1500DB3EAA /* catch_runner.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; lineEnding = 0; name = catch_runner.hpp; path = ../../../../include/catch_runner.hpp; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.cpp; };
4A6D0C42149B3E1500DB3EAA /* catch_session.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; lineEnding = 0; name = catch_session.hpp; path = ../../../../include/catch_session.hpp; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.cpp; };
4A6D0C43149B3E1500DB3EAA /* catch_with_main.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = catch_with_main.hpp; path = ../../../../include/catch_with_main.hpp; sourceTree = "<group>"; };
4A6D0C44149B3E1500DB3EAA /* catch.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = catch.hpp; path = ../../../../include/catch.hpp; sourceTree = "<group>"; };
4A6D0C46149B3E3D00DB3EAA /* catch_approx.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = catch_approx.hpp; sourceTree = "<group>"; };
@@ -163,7 +164,7 @@
4A6D0C5B149B3E3D00DB3EAA /* catch_reporter_registry.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = catch_reporter_registry.hpp; sourceTree = "<group>"; };
4A6D0C5C149B3E3D00DB3EAA /* catch_result_type.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = catch_result_type.h; sourceTree = "<group>"; };
4A6D0C5D149B3E3D00DB3EAA /* catch_assertionresult.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; lineEnding = 0; path = catch_assertionresult.h; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; };
4A6D0C5E149B3E3D00DB3EAA /* catch_runner_impl.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; lineEnding = 0; path = catch_runner_impl.hpp; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.cpp; };
4A6D0C5E149B3E3D00DB3EAA /* catch_run_context.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; lineEnding = 0; path = catch_run_context.hpp; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.cpp; };
4A6D0C5F149B3E3D00DB3EAA /* catch_section.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = catch_section.hpp; sourceTree = "<group>"; };
4A6D0C60149B3E3D00DB3EAA /* catch_stream.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = catch_stream.hpp; sourceTree = "<group>"; };
4A6D0C61149B3E3D00DB3EAA /* catch_test_case_info.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = catch_test_case_info.h; sourceTree = "<group>"; };
@@ -285,7 +286,7 @@
4AA7B8B4165428BA003155F6 /* catch_version.hpp */,
4A8E4DCF160A34E200194CBD /* SurrogateCpps */,
4A6D0C44149B3E1500DB3EAA /* catch.hpp */,
4A6D0C42149B3E1500DB3EAA /* catch_runner.hpp */,
4A6D0C42149B3E1500DB3EAA /* catch_session.hpp */,
4A6D0C43149B3E1500DB3EAA /* catch_with_main.hpp */,
4A6D0C45149B3E3D00DB3EAA /* internal */,
4A6D0C65149B3E3D00DB3EAA /* reporters */,
@@ -318,6 +319,7 @@
4A6D0C68149B3E3D00DB3EAA /* catch_reporter_xml.hpp */,
4AB42F84166F3E1A0099F2C8 /* catch_reporter_console.hpp */,
2691574A1A4480C50054F1ED /* catch_reporter_teamcity.hpp */,
26EDFBD91B72011F00B1873C /* catch_reporter_multi.hpp */,
);
name = reporters;
path = ../../../../include/reporters;
@@ -358,7 +360,7 @@
4A4B0F9715CE6CFB00AE2392 /* catch_registry_hub.hpp */,
4A6D0C50149B3E3D00DB3EAA /* catch_generators_impl.hpp */,
4A6D0C52149B3E3D00DB3EAA /* catch_context_impl.hpp */,
4A6D0C5E149B3E3D00DB3EAA /* catch_runner_impl.hpp */,
4A6D0C5E149B3E3D00DB3EAA /* catch_run_context.hpp */,
4A6D0C62149B3E3D00DB3EAA /* catch_test_case_registry_impl.hpp */,
4AB1C73514F97BDA00F31DF7 /* catch_console_colour_impl.hpp */,
4A4B0F9B15CEF8C400AE2392 /* catch_notimplemented_exception.hpp */,
@@ -10,31 +10,31 @@
<string>CatchSelfTestSingle</string>
<key>IDESourceControlProjectOriginsDictionary</key>
<dict>
<key>01DD8CA9-7DC3-46BC-B998-EFF40EA3485F</key>
<string>ssh://github.com/philsquared/Catch.git</string>
<key>90C00904F36E6ADB57A7313E998815D255B0DEAF</key>
<string>https://github.com/philsquared/Catch.git</string>
</dict>
<key>IDESourceControlProjectPath</key>
<string>projects/XCode4/CatchSelfTest/CatchSelfTestSingle.xcodeproj/project.xcworkspace</string>
<string>projects/XCode/CatchSelfTest/CatchSelfTestSingle.xcodeproj</string>
<key>IDESourceControlProjectRelativeInstallPathDictionary</key>
<dict>
<key>01DD8CA9-7DC3-46BC-B998-EFF40EA3485F</key>
<key>90C00904F36E6ADB57A7313E998815D255B0DEAF</key>
<string>../../../../..</string>
</dict>
<key>IDESourceControlProjectURL</key>
<string>ssh://github.com/philsquared/Catch.git</string>
<string>https://github.com/philsquared/Catch.git</string>
<key>IDESourceControlProjectVersion</key>
<integer>110</integer>
<integer>111</integer>
<key>IDESourceControlProjectWCCIdentifier</key>
<string>01DD8CA9-7DC3-46BC-B998-EFF40EA3485F</string>
<string>90C00904F36E6ADB57A7313E998815D255B0DEAF</string>
<key>IDESourceControlProjectWCConfigurations</key>
<array>
<dict>
<key>IDESourceControlRepositoryExtensionIdentifierKey</key>
<string>public.vcs.git</string>
<key>IDESourceControlWCCIdentifierKey</key>
<string>01DD8CA9-7DC3-46BC-B998-EFF40EA3485F</string>
<string>90C00904F36E6ADB57A7313E998815D255B0DEAF</string>
<key>IDESourceControlWCCName</key>
<string>Catch</string>
<string>Catch-Develop</string>
</dict>
</array>
</dict>
+620 -316
View File
File diff suppressed because it is too large Load Diff