register all tests, begin work on running all tests for 'tag'

This commit is contained in:
Malcolm Noyes 2013-11-22 11:47:21 +00:00
parent 2a14dffe97
commit c88413dd58
7 changed files with 167 additions and 126 deletions

1
.gitignore vendored
View File

@ -10,6 +10,7 @@ Debug
Release Release
ipch ipch
TestResults TestResults
projects/VS2010/TestCatch/Visual Lint
*.user *.user
*.xcuserstate *.xcuserstate
*.o *.o

View File

@ -16,64 +16,68 @@
namespace Catch { namespace Catch {
namespace { class RegistryHub : public IRegistryHub, public IMutableRegistryHub {
class RegistryHub : public IRegistryHub, public IMutableRegistryHub { RegistryHub( RegistryHub const& );
void operator=( RegistryHub const& );
RegistryHub( RegistryHub const& ); public: // IRegistryHub
void operator=( RegistryHub const& ); RegistryHub() {
}
virtual IReporterRegistry const& getReporterRegistry() const {
return m_reporterRegistry;
}
virtual ITestCaseRegistry const& getTestCaseRegistry() const {
return m_testCaseRegistry;
}
virtual IExceptionTranslatorRegistry& getExceptionTranslatorRegistry() {
return m_exceptionTranslatorRegistry;
}
public: // IRegistryHub public: // IMutableRegistryHub
RegistryHub() { virtual void registerReporter( std::string const& name, IReporterFactory* factory ) {
} m_reporterRegistry.registerReporter( name, factory );
virtual IReporterRegistry const& getReporterRegistry() const { }
return m_reporterRegistry; virtual void registerTest( TestCase const& testInfo ) {
} m_testCaseRegistry.registerTest( testInfo );
virtual ITestCaseRegistry const& getTestCaseRegistry() const { }
return m_testCaseRegistry; virtual void registerTranslator( const IExceptionTranslator* translator ) {
} m_exceptionTranslatorRegistry.registerTranslator( translator );
virtual IExceptionTranslatorRegistry& getExceptionTranslatorRegistry() { }
return m_exceptionTranslatorRegistry;
}
public: // IMutableRegistryHub private:
virtual void registerReporter( std::string const& name, IReporterFactory* factory ) { TestRegistry m_testCaseRegistry;
m_reporterRegistry.registerReporter( name, factory ); ReporterRegistry m_reporterRegistry;
} ExceptionTranslatorRegistry m_exceptionTranslatorRegistry;
virtual void registerTest( TestCase const& testInfo ) { };
m_testCaseRegistry.registerTest( testInfo );
}
virtual void registerTranslator( const IExceptionTranslator* translator ) {
m_exceptionTranslatorRegistry.registerTranslator( translator );
}
private: // Single, global, instance
TestRegistry m_testCaseRegistry; template <typename T>
ReporterRegistry m_reporterRegistry; struct GlobalRegistryHub
ExceptionTranslatorRegistry m_exceptionTranslatorRegistry; {
}; static T*& instance()
{
// Single, global, instance
inline RegistryHub*& getTheRegistryHub() {
static RegistryHub* theRegistryHub = NULL;
if( !theRegistryHub ) if( !theRegistryHub )
theRegistryHub = new RegistryHub(); theRegistryHub = new T();
return theRegistryHub; return theRegistryHub;
} }
} static T* theRegistryHub;
};
template <typename T>
T* GlobalRegistryHub<T>::theRegistryHub = NULL;
IRegistryHub& getRegistryHub() { INTERNAL_CATCH_INLINE IRegistryHub& getRegistryHub() {
return *getTheRegistryHub(); return *GlobalRegistryHub<RegistryHub>::instance();
} }
IMutableRegistryHub& getMutableRegistryHub() { INTERNAL_CATCH_INLINE IMutableRegistryHub& getMutableRegistryHub() {
return *getTheRegistryHub(); return *GlobalRegistryHub<RegistryHub>::instance();
} }
void cleanUp() { INTERNAL_CATCH_INLINE void cleanUp() {
delete getTheRegistryHub(); delete GlobalRegistryHub<RegistryHub>::instance();
getTheRegistryHub() = NULL; GlobalRegistryHub<RegistryHub>::instance() = NULL;
cleanUpContext(); cleanUpContext();
} }
std::string translateActiveException() { INTERNAL_CATCH_INLINE std::string translateActiveException() {
return getRegistryHub().getExceptionTranslatorRegistry().translateActiveException(); return getRegistryHub().getExceptionTranslatorRegistry().translateActiveException();
} }

View File

@ -279,7 +279,8 @@ namespace Catch {
} }
#ifdef INTERNAL_CATCH_VS_MANAGED // detect CLR #ifdef INTERNAL_CATCH_VS_MANAGED // detect CLR
catch(AssertFailedException^) { catch(AssertFailedException^) {
throw; // CLR always rethrows - stop on first assert if( aborting() )
throw; // CLR always rethrows - stop on first assert
} }
#else #else
catch( INTERNAL_CATCH_TEST_FAILURE_EXCEPTION ) { catch( INTERNAL_CATCH_TEST_FAILURE_EXCEPTION ) {

View File

@ -8,7 +8,11 @@
#ifndef TWOBLUECUBES_CATCH_TEST_CASE_REGISTRY_IMPL_HPP_INCLUDED #ifndef TWOBLUECUBES_CATCH_TEST_CASE_REGISTRY_IMPL_HPP_INCLUDED
#define TWOBLUECUBES_CATCH_TEST_CASE_REGISTRY_IMPL_HPP_INCLUDED #define TWOBLUECUBES_CATCH_TEST_CASE_REGISTRY_IMPL_HPP_INCLUDED
#if defined(INTERNAL_CATCH_VS_MANAGED) || defined(INTERNAL_CATCH_VS_NATIVE)
#include "internal/catch_vs_test_registry.hpp"
#else
#include "catch_test_registry.hpp" #include "catch_test_registry.hpp"
#endif
#include "catch_test_case_info.h" #include "catch_test_case_info.h"
#include "catch_test_spec.h" #include "catch_test_spec.h"
#include "catch_context.h" #include "catch_context.h"
@ -124,15 +128,15 @@ namespace Catch {
/////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////
AutoReg::AutoReg( TestFunction function, INTERNAL_CATCH_INLINE AutoReg::AutoReg( TestFunction function,
SourceLineInfo const& lineInfo, SourceLineInfo const& lineInfo,
NameAndDesc const& nameAndDesc ) { NameAndDesc const& nameAndDesc ) {
registerTestCase( new FreeFunctionTestCase( function ), "", nameAndDesc, lineInfo ); registerTestCase( new FreeFunctionTestCase( function ), "", nameAndDesc, lineInfo );
} }
AutoReg::~AutoReg() {} INTERNAL_CATCH_INLINE AutoReg::~AutoReg() {}
void AutoReg::registerTestCase( ITestCase* testCase, INTERNAL_CATCH_INLINE void AutoReg::registerTestCase( ITestCase* testCase,
char const* classOrQualifiedMethodName, char const* classOrQualifiedMethodName,
NameAndDesc const& nameAndDesc, NameAndDesc const& nameAndDesc,
SourceLineInfo const& lineInfo ) { SourceLineInfo const& lineInfo ) {

View File

@ -27,11 +27,12 @@ namespace Catch {
} }
#include "internal/catch_timer.hpp" #include "internal/catch_timer.hpp"
#include "internal/catch_vs_test_registry.hpp" #include "internal/catch_reporter_registrars.hpp"
#include "reporters/catch_vs_reporter.hpp" #include "reporters/catch_vs_reporter.hpp"
#include "catch_registry_hub.hpp"
#include "internal/catch_exception_translator_registry.hpp" //#define OLD (1)
#ifdef OLD
namespace Catch { namespace Catch {
class ExceptionRegistryHub : public IRegistryHub, public IMutableRegistryHub { class ExceptionRegistryHub : public IRegistryHub, public IMutableRegistryHub {
@ -70,11 +71,11 @@ namespace Catch {
template <typename T> template <typename T>
struct GlobalRegistryHub struct GlobalRegistryHub
{ {
static T& instance() static T*& instance()
{ {
if( !theRegistryHub ) if( !theRegistryHub )
theRegistryHub = new T(); theRegistryHub = new T();
return *theRegistryHub; return theRegistryHub;
} }
static T* theRegistryHub; static T* theRegistryHub;
}; };
@ -82,13 +83,64 @@ namespace Catch {
T* GlobalRegistryHub<T>::theRegistryHub = NULL; T* GlobalRegistryHub<T>::theRegistryHub = NULL;
INTERNAL_CATCH_INLINE IMutableRegistryHub& getMutableRegistryHub() { INTERNAL_CATCH_INLINE IMutableRegistryHub& getMutableRegistryHub() {
return GlobalRegistryHub<ExceptionRegistryHub>::instance(); return *GlobalRegistryHub<ExceptionRegistryHub>::instance();
} }
INTERNAL_CATCH_INLINE std::string translateActiveException() { INTERNAL_CATCH_INLINE std::string translateActiveException() {
return GlobalRegistryHub<ExceptionRegistryHub>::instance().getExceptionTranslatorRegistry().translateActiveException(); return GlobalRegistryHub<ExceptionRegistryHub>::instance()->getExceptionTranslatorRegistry().translateActiveException();
} }
} }
#endif // OLD
namespace Catch {
inline NonCopyable::~NonCopyable() {}
inline IShared::~IShared() {}
inline StreamBufBase::~StreamBufBase() throw() {}
inline IContext::~IContext() {}
inline IResultCapture::~IResultCapture() {}
inline ITestCase::~ITestCase() {}
inline ITestCaseRegistry::~ITestCaseRegistry() {}
inline IRegistryHub::~IRegistryHub() {}
inline IMutableRegistryHub::~IMutableRegistryHub() {}
inline IExceptionTranslator::~IExceptionTranslator() {}
inline IExceptionTranslatorRegistry::~IExceptionTranslatorRegistry() {}
inline IReporter::~IReporter() {}
inline IReporterFactory::~IReporterFactory() {}
inline IReporterRegistry::~IReporterRegistry() {}
inline IStreamingReporter::~IStreamingReporter() {}
inline AssertionStats::~AssertionStats() {}
inline SectionStats::~SectionStats() {}
inline TestCaseStats::~TestCaseStats() {}
inline TestGroupStats::~TestGroupStats() {}
inline TestRunStats::~TestRunStats() {}
//CumulativeReporterBase::SectionNode::~SectionNode() {}
//CumulativeReporterBase::~CumulativeReporterBase() {}
//StreamingReporterBase::~StreamingReporterBase() {}
//ConsoleReporter::~ConsoleReporter() {}
inline IRunner::~IRunner() {}
inline IMutableContext::~IMutableContext() {}
inline IConfig::~IConfig() {}
//XmlReporter::~XmlReporter() {}
//JunitReporter::~JunitReporter() {}
inline TestRegistry::~TestRegistry() {}
inline FreeFunctionTestCase::~FreeFunctionTestCase() {}
inline IGeneratorInfo::~IGeneratorInfo() {}
inline IGeneratorsForTest::~IGeneratorsForTest() {}
inline TagParser::~TagParser() {}
inline TagExtracter::~TagExtracter() {}
inline TagExpressionParser::~TagExpressionParser() {}
inline Matchers::Impl::StdString::Equals::~Equals() {}
inline Matchers::Impl::StdString::Contains::~Contains() {}
inline Matchers::Impl::StdString::StartsWith::~StartsWith() {}
inline Matchers::Impl::StdString::EndsWith::~EndsWith() {}
inline void Config::dummy() {}
//INTERNAL_CATCH_REGISTER_LEGACY_REPORTER( "xml", XmlReporter )
}
#endif #endif
#endif // TWOBLUECUBES_CATCH_VS_MANAGED_HPP_INCLUDED #endif // TWOBLUECUBES_CATCH_VS_MANAGED_HPP_INCLUDED

View File

@ -16,27 +16,11 @@
#include "catch_common.h" #include "catch_common.h"
#include "catch_interfaces_testcase.h" #include "catch_interfaces_testcase.h"
#include "internal/catch_compiler_capabilities.h" #include "internal/catch_compiler_capabilities.h"
#include "internal/clara.h"
#include <tchar.h> #include <tchar.h>
namespace Catch { namespace Catch {
typedef void(*TestFunction)();
class FreeFunctionTestCase : public SharedImpl<ITestCase> {
public:
FreeFunctionTestCase( TestFunction fun ) : m_fun( fun ) {}
virtual void invoke() const {
m_fun();
}
private:
virtual ~FreeFunctionTestCase();
TestFunction m_fun;
};
class MethodTestCase : public SharedImpl<ITestCase> { class MethodTestCase : public SharedImpl<ITestCase> {
struct placeholder struct placeholder
@ -105,6 +89,35 @@ struct NameAndDesc {
std::string description; std::string description;
}; };
struct AutoReg {
AutoReg( TestFunction function,
SourceLineInfo const& lineInfo,
NameAndDesc const& nameAndDesc );
template<typename C>
AutoReg( void (C::*method)(),
char const* className,
NameAndDesc const& nameAndDesc,
SourceLineInfo const& lineInfo ) {
registerTestCase( new MethodTestCase( method ),
className,
nameAndDesc,
lineInfo );
}
void registerTestCase( ITestCase* testCase,
char const* className,
NameAndDesc const& nameAndDesc,
SourceLineInfo const& lineInfo );
~AutoReg();
private:
AutoReg( AutoReg const& );
void operator= ( AutoReg const& );
};
} // end namespace Catch } // end namespace Catch
#if (_MANAGED == 1) || (_M_CEE == 1) // detect CLR #if (_MANAGED == 1) || (_M_CEE == 1) // detect CLR
@ -213,27 +226,34 @@ struct NameAndDesc {
#define CATCH_INTERNAL_RUN_SINGLE_TEST( Method ) \ #define CATCH_INTERNAL_RUN_SINGLE_TEST( Method ) \
{ Catch::ConfigData cd; \ { Catch::ConfigData cd; \
cd.name = name_desc.name; \ cd.name = name_desc.name; \
cd.abortAfter = 1; \
Catch::Ptr<Catch::Config> config(new Catch::Config(cd)); \ Catch::Ptr<Catch::Config> config(new Catch::Config(cd)); \
Catch::MSTestReporter* rep = new Catch::MSTestReporter(config.get()); \ Catch::MSTestReporter* rep = new Catch::MSTestReporter(config.get()); \
Catch::RunContext tr(config.get(), rep); \ Catch::RunContext tr(config.get(), rep); \
Catch::TestCase tc = Catch::makeTestCase( new Catch::FreeFunctionTestCase( & Method ), "", name_desc.name, name_desc.description, CATCH_INTERNAL_LINEINFO ); \ std::vector<Catch::TestCase> testCase = Catch::getRegistryHub().getTestCaseRegistry().getMatchingTestCases(name_desc.name); \
tr.runTest(tc); \ if( testCase.empty() ) Assert::Fail("No tests match"); \
if( testCase.size() > 1 ) Assert::Fail("More than one test with the same name"); \
tr.runTest(*testCase.begin()); \
} }
#define CATCH_INTERNAL_RUN_SINGLE_CLASS_TEST( ClassMethod ) \ #define CATCH_INTERNAL_RUN_SINGLE_CLASS_TEST( ClassMethod ) \
{ Catch::ConfigData cd; \ { Catch::ConfigData cd; \
cd.name = name_desc.name; \ cd.name = name_desc.name; \
cd.abortAfter = 1; \
Catch::Ptr<Catch::Config> config(new Catch::Config(cd)); \ Catch::Ptr<Catch::Config> config(new Catch::Config(cd)); \
Catch::MSTestReporter* rep = new Catch::MSTestReporter(config.get()); \ Catch::MSTestReporter* rep = new Catch::MSTestReporter(config.get()); \
Catch::RunContext tr(config.get(), rep); \ Catch::RunContext tr(config.get(), rep); \
Catch::TestCase tc = Catch::makeTestCase( new Catch::MethodTestCase( & ClassMethod ), # ClassMethod, name_desc.name, name_desc.description, CATCH_INTERNAL_LINEINFO ); \ std::vector<Catch::TestCase> testCase = Catch::getRegistryHub().getTestCaseRegistry().getMatchingTestCases(name_desc.name); \
tr.runTest(tc); \ if( testCase.empty() ) Assert::Fail("No tests match"); \
if( testCase.size() > 1 ) Assert::Fail("More than one test with the same name"); \
tr.runTest(*testCase.begin()); \
} }
#define INTERNAL_CATCH_TESTCASE2( UniqueExt, Name, Desc ) \ #define INTERNAL_CATCH_TESTCASE2( UniqueExt, Name, Desc ) \
CHECK_FOR_TEST_CASE_CLASH \ CHECK_FOR_TEST_CASE_CLASH \
static void INTERNAL_CATCH_UNIQUE_NAME_LINE( C_A_T_C_H____T_E_S_T____, UniqueExt )(); \ static void INTERNAL_CATCH_UNIQUE_NAME_LINE( C_A_T_C_H____T_E_S_T____, UniqueExt )(); \
namespace CATCH_INTERNAL_NAMESPACE( UniqueExt ) { \ namespace CATCH_INTERNAL_NAMESPACE( UniqueExt ) { \
Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( & INTERNAL_CATCH_UNIQUE_NAME_LINE( C_A_T_C_H____T_E_S_T____, UniqueExt ), CATCH_INTERNAL_LINEINFO, Catch::NameAndDesc(Name, Desc) ); \
INTERNAL_CATCH_CLASS_DEFINITION( INTERNAL_CATCH_UNIQUE_NAME_LINE( C_A_T_C_H____T_E_S_T____C_L_A_S_S___, UniqueExt ) ) \ INTERNAL_CATCH_CLASS_DEFINITION( INTERNAL_CATCH_UNIQUE_NAME_LINE( C_A_T_C_H____T_E_S_T____C_L_A_S_S___, UniqueExt ) ) \
{ \ { \
INTERNAL_CATCH_CLASS_CONTEXT \ INTERNAL_CATCH_CLASS_CONTEXT \
@ -245,6 +265,7 @@ struct NameAndDesc {
#define INTERNAL_CATCH_METHOD_AS_TEST_CASE2( QualifiedMethod, UniqueExt, Name, Desc ) \ #define INTERNAL_CATCH_METHOD_AS_TEST_CASE2( QualifiedMethod, UniqueExt, Name, Desc ) \
CHECK_FOR_TEST_CASE_CLASH \ CHECK_FOR_TEST_CASE_CLASH \
namespace CATCH_INTERNAL_NAMESPACE( UniqueExt ) { \ namespace CATCH_INTERNAL_NAMESPACE( UniqueExt ) { \
Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( & QualifiedMethod, "&" # QualifiedMethod, Catch::NameAndDesc(Name, Desc), CATCH_INTERNAL_LINEINFO ); \
INTERNAL_CATCH_CLASS_DEFINITION( INTERNAL_CATCH_UNIQUE_NAME_LINE( C_A_T_C_H____T_E_S_T____C_L_A_S_S___, UniqueExt ) ) \ INTERNAL_CATCH_CLASS_DEFINITION( INTERNAL_CATCH_UNIQUE_NAME_LINE( C_A_T_C_H____T_E_S_T____C_L_A_S_S___, UniqueExt ) ) \
{ \ { \
INTERNAL_CATCH_CLASS_CONTEXT \ INTERNAL_CATCH_CLASS_CONTEXT \
@ -259,6 +280,7 @@ struct NameAndDesc {
static void invoke() { INTERNAL_CATCH_UNIQUE_NAME_LINE( C_A_T_C_H____T_E_S_T____, UniqueExt ) tmp; tmp.test(); } \ static void invoke() { INTERNAL_CATCH_UNIQUE_NAME_LINE( C_A_T_C_H____T_E_S_T____, UniqueExt ) tmp; tmp.test(); } \
}; \ }; \
namespace CATCH_INTERNAL_NAMESPACE( UniqueExt ) { \ namespace CATCH_INTERNAL_NAMESPACE( UniqueExt ) { \
Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( & INTERNAL_CATCH_UNIQUE_NAME_LINE( C_A_T_C_H____T_E_S_T____, UniqueExt )::invoke, CATCH_INTERNAL_LINEINFO, Catch::NameAndDesc(TestName, Desc) ); \
INTERNAL_CATCH_CLASS_DEFINITION( INTERNAL_CATCH_UNIQUE_NAME_LINE( C_A_T_C_H____T_E_S_T____C_L_A_S_S___, UniqueExt ) ) \ INTERNAL_CATCH_CLASS_DEFINITION( INTERNAL_CATCH_UNIQUE_NAME_LINE( C_A_T_C_H____T_E_S_T____C_L_A_S_S___, UniqueExt ) ) \
{ \ { \
INTERNAL_CATCH_CLASS_CONTEXT \ INTERNAL_CATCH_CLASS_CONTEXT \
@ -320,55 +342,6 @@ struct NameAndDesc {
#include "catch_exception_translator_registry.hpp" #include "catch_exception_translator_registry.hpp"
namespace Catch {
inline NonCopyable::~NonCopyable() {}
inline IShared::~IShared() {}
inline StreamBufBase::~StreamBufBase() throw() {}
inline IContext::~IContext() {}
inline IResultCapture::~IResultCapture() {}
inline ITestCase::~ITestCase() {}
inline ITestCaseRegistry::~ITestCaseRegistry() {}
inline IRegistryHub::~IRegistryHub() {}
inline IMutableRegistryHub::~IMutableRegistryHub() {}
inline IExceptionTranslator::~IExceptionTranslator() {}
inline IExceptionTranslatorRegistry::~IExceptionTranslatorRegistry() {}
inline IReporter::~IReporter() {}
inline IReporterFactory::~IReporterFactory() {}
inline IReporterRegistry::~IReporterRegistry() {}
inline IStreamingReporter::~IStreamingReporter() {}
inline AssertionStats::~AssertionStats() {}
inline SectionStats::~SectionStats() {}
inline TestCaseStats::~TestCaseStats() {}
inline TestGroupStats::~TestGroupStats() {}
inline TestRunStats::~TestRunStats() {}
//CumulativeReporterBase::SectionNode::~SectionNode() {}
//CumulativeReporterBase::~CumulativeReporterBase() {}
//StreamingReporterBase::~StreamingReporterBase() {}
//ConsoleReporter::~ConsoleReporter() {}
inline IRunner::~IRunner() {}
inline IMutableContext::~IMutableContext() {}
inline IConfig::~IConfig() {}
//XmlReporter::~XmlReporter() {}
//JunitReporter::~JunitReporter() {}
//TestRegistry::~TestRegistry() {}
inline FreeFunctionTestCase::~FreeFunctionTestCase() {}
inline IGeneratorInfo::~IGeneratorInfo() {}
inline IGeneratorsForTest::~IGeneratorsForTest() {}
inline TagParser::~TagParser() {}
inline TagExtracter::~TagExtracter() {}
inline TagExpressionParser::~TagExpressionParser() {}
inline Matchers::Impl::StdString::Equals::~Equals() {}
inline Matchers::Impl::StdString::Contains::~Contains() {}
inline Matchers::Impl::StdString::StartsWith::~StartsWith() {}
inline Matchers::Impl::StdString::EndsWith::~EndsWith() {}
inline void Config::dummy() {}
//INTERNAL_CATCH_REGISTER_LEGACY_REPORTER( "xml", XmlReporter )
}
#ifdef __clang__ #ifdef __clang__
#pragma clang diagnostic pop #pragma clang diagnostic pop
#endif #endif

View File

@ -46,6 +46,12 @@ namespace Catch {
#endif // detect CLR #endif // detect CLR
struct MSTestReporter : SharedImpl<IStreamingReporter> { struct MSTestReporter : SharedImpl<IStreamingReporter> {
MSTestReporter( ReporterConfig const& _config )
: m_config( _config.fullConfig() ),
m_headerPrinted( false ),
m_atLeastOneTestCasePrinted( false )
{}
MSTestReporter( Ptr<IConfig> const& _fullConfig ) MSTestReporter( Ptr<IConfig> const& _fullConfig )
: m_config( _fullConfig ), : m_config( _fullConfig ),
m_headerPrinted( false ), m_headerPrinted( false ),