Merge branch 'master' of github.com:philsquared/Catch

This commit is contained in:
Phil Nash 2011-06-23 08:25:07 +01:00
commit f5c057ead2
1 changed files with 106 additions and 14 deletions

View File

@ -436,6 +436,61 @@ namespace Catch
// #included from: catch_descriptor.hpp
/*
* catch_descriptor.hpp
* Catch
*
* Created by Phil on 16/06/2011.
* Copyright 2011 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)
*
*/
#define TWOBLUECUBES_CATCH_DESCRIPTOR_HPP_INCLUDED
namespace Catch
{
class Descriptor
{
public:
Descriptor()
: Anon( *this )
{
}
Descriptor& Name( const char* name )
{
m_name = name;
return *this;
}
Descriptor& Desc( const char* desc )
{
m_desc = desc;
return *this;
}
Descriptor& Tag( const char* tag )
{
m_tags.push_back( tag );
return *this;
}
Descriptor& Anon;
private:
const char* m_name;
const char* m_desc;
std::vector<const char*> m_tags;
};
}
namespace Catch namespace Catch
{ {
@ -506,6 +561,13 @@ struct AutoReg
std::size_t line std::size_t line
); );
AutoReg
( TestFunction function,
const Descriptor& descriptor,
const char* filename,
std::size_t line
);
/////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////
template<typename C> template<typename C>
AutoReg AutoReg
@ -1821,16 +1883,16 @@ inline bool isTrue
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
#define INTERNAL_CATCH_ACCEPT_EXPR( expr, stopOnFailure ) \ #define INTERNAL_CATCH_ACCEPT_EXPR( expr, stopOnFailure ) \
if( Catch::ResultAction::Value action = Catch::Hub::getResultCapture().acceptExpression( expr ) ) \ if( Catch::ResultAction::Value internal_catch_action = Catch::Hub::getResultCapture().acceptExpression( expr ) ) \
{ \ { \
if( action == Catch::ResultAction::DebugFailed ) BreakIntoDebugger(); \ if( internal_catch_action == Catch::ResultAction::DebugFailed ) BreakIntoDebugger(); \
if( Catch::isTrue( stopOnFailure ) ) throw Catch::TestFailureException(); \ if( Catch::isTrue( stopOnFailure ) ) throw Catch::TestFailureException(); \
} }
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
#define INTERNAL_CATCH_TEST( expr, isNot, stopOnFailure, macroName ) \ #define INTERNAL_CATCH_TEST( expr, isNot, stopOnFailure, macroName ) \
INTERNAL_CATCH_ACCEPT_EXPR( ( Catch::ResultBuilder( __FILE__, __LINE__, macroName, #expr, isNot )->*expr ), stopOnFailure ); \ INTERNAL_CATCH_ACCEPT_EXPR( ( Catch::ResultBuilder( __FILE__, __LINE__, macroName, #expr, isNot )->*expr ), stopOnFailure ); \
if( Catch::isTrue( false ) ){ bool dummyResult = ( expr ); Catch::isTrue( dummyResult ); } if( Catch::isTrue( false ) ){ bool internal_catch_dummyResult = ( expr ); Catch::isTrue( internal_catch_dummyResult ); }
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
#define INTERNAL_CATCH_NO_THROW( expr, stopOnFailure, macroName ) \ #define INTERNAL_CATCH_NO_THROW( expr, stopOnFailure, macroName ) \
@ -1839,9 +1901,9 @@ inline bool isTrue
expr; \ expr; \
INTERNAL_CATCH_ACCEPT_EXPR( Catch::ResultBuilder( __FILE__, __LINE__, macroName, #expr ).setResultType( Catch::ResultWas::Ok ), stopOnFailure ); \ INTERNAL_CATCH_ACCEPT_EXPR( Catch::ResultBuilder( __FILE__, __LINE__, macroName, #expr ).setResultType( Catch::ResultWas::Ok ), stopOnFailure ); \
} \ } \
catch( std::exception& ex ) \ catch( std::exception& internal_catch_exception ) \
{ \ { \
INTERNAL_CATCH_ACCEPT_EXPR( ( Catch::ResultBuilder( __FILE__, __LINE__, macroName, #expr ) << ex.what() ).setResultType( Catch::ResultWas::ThrewException ), stopOnFailure ); \ INTERNAL_CATCH_ACCEPT_EXPR( ( Catch::ResultBuilder( __FILE__, __LINE__, macroName, #expr ) << internal_catch_exception.what() ).setResultType( Catch::ResultWas::ThrewException ), stopOnFailure ); \
} \ } \
catch( ... ) \ catch( ... ) \
{ \ { \
@ -2989,6 +3051,18 @@ namespace Catch
registerTestCase( new FreeFunctionTestCase( function ), name, description, filename, line ); registerTestCase( new FreeFunctionTestCase( function ), name, description, filename, line );
} }
///////////////////////////////////////////////////////////////////////////
AutoReg::AutoReg
(
TestFunction function,
const Descriptor& descriptor,
const char* filename,
std::size_t line
)
{
registerTestCase( new FreeFunctionTestCase( function ), "tbd", "tbd", filename, line );
}
/////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////
AutoReg::~AutoReg AutoReg::~AutoReg
() ()
@ -3427,7 +3501,6 @@ namespace Catch
Root, Root,
Unknown, Unknown,
NonLeaf, NonLeaf,
UntestedLeaf,
TestedLeaf TestedLeaf
}; };
@ -3477,15 +3550,23 @@ namespace Catch
} }
/////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////
SectionInfo* getSubSection SectionInfo* findSubSection
( (
const std::string& name const std::string& name
) )
{ {
std::map<std::string, SectionInfo*>::const_iterator it = m_subSections.find( name ); std::map<std::string, SectionInfo*>::const_iterator it = m_subSections.find( name );
if( it != m_subSections.end() ) return it != m_subSections.end()
return it->second; ? it->second
: NULL;
}
///////////////////////////////////////////////////////////////////////
SectionInfo* addSubSection
(
const std::string& name
)
{
SectionInfo* subSection = new SectionInfo( this ); SectionInfo* subSection = new SectionInfo( this );
m_subSections.insert( std::make_pair( name, subSection ) ); m_subSections.insert( std::make_pair( name, subSection ) );
m_status = NonLeaf; m_status = NonLeaf;
@ -3504,7 +3585,7 @@ namespace Catch
() ()
const const
{ {
if( m_status == Unknown || m_status == UntestedLeaf ) if( m_status == Unknown )
return true; return true;
std::map<std::string, SectionInfo*>::const_iterator it = m_subSections.begin(); std::map<std::string, SectionInfo*>::const_iterator it = m_subSections.begin();
@ -3545,7 +3626,8 @@ namespace Catch
) )
: m_info( info ), : m_info( info ),
m_runStatus( RanAtLeastOneSection ), m_runStatus( RanAtLeastOneSection ),
m_currentSection( &m_rootSection ) m_currentSection( &m_rootSection ),
m_changed( false )
{ {
} }
@ -3563,6 +3645,7 @@ namespace Catch
() ()
{ {
m_runStatus = NothingRun; m_runStatus = NothingRun;
m_changed = false;
} }
/////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////
@ -3584,7 +3667,12 @@ namespace Catch
if( m_runStatus == NothingRun ) if( m_runStatus == NothingRun )
m_runStatus = EncounteredASection; m_runStatus = EncounteredASection;
SectionInfo* thisSection = m_currentSection->getSubSection( name ); SectionInfo* thisSection = m_currentSection->findSubSection( name );
if( !thisSection )
{
thisSection = m_currentSection->addSubSection( name );
m_changed = true;
}
if( !wasSectionSeen() && thisSection->shouldRun() ) if( !wasSectionSeen() && thisSection->shouldRun() )
{ {
@ -3601,7 +3689,10 @@ namespace Catch
) )
{ {
if( m_currentSection->ran() ) if( m_currentSection->ran() )
{
m_runStatus = RanAtLeastOneSection; m_runStatus = RanAtLeastOneSection;
m_changed = true;
}
m_currentSection = m_currentSection->getParent(); m_currentSection = m_currentSection->getParent();
} }
@ -3618,8 +3709,8 @@ namespace Catch
() ()
const const
{ {
return m_rootSection.hasUntestedSections() || return m_runStatus == RanAtLeastOneSection ||
m_runStatus == RanAtLeastOneSection; ( m_rootSection.hasUntestedSections() && m_changed );
} }
private: private:
@ -3627,6 +3718,7 @@ namespace Catch
RunStatus m_runStatus; RunStatus m_runStatus;
SectionInfo m_rootSection; SectionInfo m_rootSection;
SectionInfo* m_currentSection; SectionInfo* m_currentSection;
bool m_changed;
}; };
/////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////