mirror of https://github.com/catchorg/Catch2.git
First cut of generators
This commit is contained in:
parent
455c2998a0
commit
c2b96d7ddb
|
@ -79,3 +79,16 @@ TEST_CASE( "./succeeding/Misc/stdout,stderr", "Sends stuff to stdout and stderr"
|
||||||
|
|
||||||
std::cerr << "An error";
|
std::cerr << "An error";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// An unnamed test case. A name, of the form, "unnamed/#" is generated, where
|
||||||
|
// # is an incrementing integer
|
||||||
|
ANON_TEST_CASE()
|
||||||
|
{
|
||||||
|
int i = 7;
|
||||||
|
REQUIRE( i == 7 );
|
||||||
|
}
|
||||||
|
ANON_TEST_CASE()
|
||||||
|
{
|
||||||
|
int i = 7;
|
||||||
|
REQUIRE( i == 8 );
|
||||||
|
}
|
||||||
|
|
|
@ -33,6 +33,27 @@ namespace Catch
|
||||||
// create a T for use in sizeof expressions
|
// create a T for use in sizeof expressions
|
||||||
template<typename T> T Synth();
|
template<typename T> T Synth();
|
||||||
|
|
||||||
|
template<typename ContainerT>
|
||||||
|
inline void deleteAll( ContainerT& container )
|
||||||
|
{
|
||||||
|
typename ContainerT::const_iterator it = container.begin();
|
||||||
|
typename ContainerT::const_iterator itEnd = container.end();
|
||||||
|
for(; it != itEnd; ++it )
|
||||||
|
{
|
||||||
|
delete *it;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
template<typename AssociativeContainerT>
|
||||||
|
inline void deleteAllValues( AssociativeContainerT& container )
|
||||||
|
{
|
||||||
|
typename AssociativeContainerT::const_iterator it = container.begin();
|
||||||
|
typename AssociativeContainerT::const_iterator itEnd = container.end();
|
||||||
|
for(; it != itEnd; ++it )
|
||||||
|
{
|
||||||
|
delete it->second;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // TWOBLUECUBES_CATCH_COMMON_H_INCLUDED
|
#endif // TWOBLUECUBES_CATCH_COMMON_H_INCLUDED
|
|
@ -23,6 +23,7 @@ namespace Catch
|
||||||
struct IResultCapture;
|
struct IResultCapture;
|
||||||
struct ITestCaseRegistry;
|
struct ITestCaseRegistry;
|
||||||
struct IRunner;
|
struct IRunner;
|
||||||
|
class GeneratorsForTest;
|
||||||
|
|
||||||
class StreamBufBase : public std::streambuf
|
class StreamBufBase : public std::streambuf
|
||||||
{
|
{
|
||||||
|
@ -60,11 +61,24 @@ namespace Catch
|
||||||
static IRunner& getRunner
|
static IRunner& getRunner
|
||||||
();
|
();
|
||||||
|
|
||||||
|
static size_t getGeneratorIndex
|
||||||
|
( const std::string& fileInfo,
|
||||||
|
size_t totalSize
|
||||||
|
);
|
||||||
|
static bool advanceGeneratorsForCurrentTest
|
||||||
|
();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
GeneratorsForTest* findGeneratorsForCurrentTest
|
||||||
|
();
|
||||||
|
GeneratorsForTest& getGeneratorsForCurrentTest
|
||||||
|
();
|
||||||
|
|
||||||
std::auto_ptr<IReporterRegistry> m_reporterRegistry;
|
std::auto_ptr<IReporterRegistry> m_reporterRegistry;
|
||||||
std::auto_ptr<ITestCaseRegistry> m_testCaseRegistry;
|
std::auto_ptr<ITestCaseRegistry> m_testCaseRegistry;
|
||||||
IRunner* m_runner;
|
IRunner* m_runner;
|
||||||
IResultCapture* m_resultCapture;
|
IResultCapture* m_resultCapture;
|
||||||
|
std::map<std::string, GeneratorsForTest*> m_generatorsByTestName;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -85,4 +85,152 @@ namespace Catch
|
||||||
throw std::domain_error( "Unknown stream: " + streamName );
|
throw std::domain_error( "Unknown stream: " + streamName );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct GeneratorInfo
|
||||||
|
{
|
||||||
|
GeneratorInfo
|
||||||
|
(
|
||||||
|
std::size_t size
|
||||||
|
)
|
||||||
|
: m_size( size ),
|
||||||
|
m_currentIndex( 0 )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void reset
|
||||||
|
()
|
||||||
|
{
|
||||||
|
m_currentIndex = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool moveNext
|
||||||
|
()
|
||||||
|
{
|
||||||
|
if( ++m_currentIndex == m_size )
|
||||||
|
{
|
||||||
|
reset();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::size_t getCurrentIndex
|
||||||
|
()
|
||||||
|
const
|
||||||
|
{
|
||||||
|
return m_currentIndex;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::size_t m_size;
|
||||||
|
std::size_t m_currentIndex;
|
||||||
|
};
|
||||||
|
|
||||||
|
class GeneratorsForTest
|
||||||
|
{
|
||||||
|
|
||||||
|
public:
|
||||||
|
GeneratorsForTest
|
||||||
|
()
|
||||||
|
: m_currentGenerator( 0 )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
~GeneratorsForTest
|
||||||
|
()
|
||||||
|
{
|
||||||
|
deleteAll( m_generatorsInOrder );
|
||||||
|
}
|
||||||
|
|
||||||
|
GeneratorInfo& getGeneratorInfo
|
||||||
|
(
|
||||||
|
const std::string& fileInfo,
|
||||||
|
std::size_t size
|
||||||
|
)
|
||||||
|
{
|
||||||
|
std::map<std::string, GeneratorInfo*>::const_iterator it = m_generatorsByName.find( fileInfo );
|
||||||
|
if( it == m_generatorsByName.end() )
|
||||||
|
{
|
||||||
|
GeneratorInfo* info = new GeneratorInfo( size );
|
||||||
|
m_generatorsByName.insert( std::make_pair( fileInfo, info ) );
|
||||||
|
m_generatorsInOrder.push_back( info );
|
||||||
|
return *info;
|
||||||
|
}
|
||||||
|
return *it->second;
|
||||||
|
}
|
||||||
|
|
||||||
|
void reset
|
||||||
|
()
|
||||||
|
{
|
||||||
|
std::vector<GeneratorInfo*>::const_iterator it = m_generatorsInOrder.begin();
|
||||||
|
std::vector<GeneratorInfo*>::const_iterator itEnd = m_generatorsInOrder.begin();
|
||||||
|
for(; it != itEnd; ++it )
|
||||||
|
{
|
||||||
|
(*it)->reset();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool moveNext
|
||||||
|
()
|
||||||
|
{
|
||||||
|
if( !m_generatorsInOrder[m_currentGenerator]->moveNext() )
|
||||||
|
{
|
||||||
|
if( ++m_currentGenerator == m_generatorsInOrder.size() )
|
||||||
|
{
|
||||||
|
m_currentGenerator = 0;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::map<std::string, GeneratorInfo*> m_generatorsByName;
|
||||||
|
std::vector<GeneratorInfo*> m_generatorsInOrder;
|
||||||
|
std::size_t m_currentGenerator;
|
||||||
|
};
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////
|
||||||
|
GeneratorsForTest* Hub::findGeneratorsForCurrentTest
|
||||||
|
()
|
||||||
|
{
|
||||||
|
std::string testName = getResultCapture().getCurrentTestName();
|
||||||
|
|
||||||
|
std::map<std::string, GeneratorsForTest*>::const_iterator it =
|
||||||
|
m_generatorsByTestName.find( testName );
|
||||||
|
return it != m_generatorsByTestName.end()
|
||||||
|
? it->second
|
||||||
|
: NULL;
|
||||||
|
}
|
||||||
|
///////////////////////////////////////////////////////////////////////////
|
||||||
|
GeneratorsForTest& Hub::getGeneratorsForCurrentTest
|
||||||
|
()
|
||||||
|
{
|
||||||
|
GeneratorsForTest* generators = findGeneratorsForCurrentTest();
|
||||||
|
if( !generators )
|
||||||
|
{
|
||||||
|
std::string testName = getResultCapture().getCurrentTestName();
|
||||||
|
generators = new GeneratorsForTest();
|
||||||
|
m_generatorsByTestName.insert( std::make_pair( testName, generators ) );
|
||||||
|
}
|
||||||
|
return *generators;
|
||||||
|
}
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////
|
||||||
|
size_t Hub::getGeneratorIndex
|
||||||
|
(
|
||||||
|
const std::string& fileInfo,
|
||||||
|
size_t totalSize
|
||||||
|
)
|
||||||
|
{
|
||||||
|
return me().getGeneratorsForCurrentTest()
|
||||||
|
.getGeneratorInfo( fileInfo, totalSize )
|
||||||
|
.getCurrentIndex();
|
||||||
|
}
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////
|
||||||
|
bool Hub::advanceGeneratorsForCurrentTest
|
||||||
|
()
|
||||||
|
{
|
||||||
|
GeneratorsForTest* generators = me().findGeneratorsForCurrentTest();
|
||||||
|
return generators && generators->moveNext();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,18 +23,49 @@ namespace Catch
|
||||||
|
|
||||||
struct IResultCapture
|
struct IResultCapture
|
||||||
{
|
{
|
||||||
virtual ~IResultCapture(){}
|
virtual ~IResultCapture
|
||||||
virtual void testEnded( const ResultInfo& result ) = 0;
|
()
|
||||||
virtual bool sectionStarted( const std::string& name, const std::string& description, std::size_t& successes, std::size_t& failures ) = 0;
|
{}
|
||||||
virtual void sectionEnded( const std::string& name, std::size_t successes, std::size_t failures ) = 0;
|
|
||||||
virtual void pushScopedInfo( ScopedInfo* scopedInfo ) = 0;
|
virtual void testEnded
|
||||||
virtual void popScopedInfo( ScopedInfo* scopedInfo ) = 0;
|
( const ResultInfo& result
|
||||||
virtual bool shouldDebugBreak() const = 0;
|
) = 0;
|
||||||
|
virtual bool sectionStarted
|
||||||
|
( const std::string& name,
|
||||||
|
const std::string& description,
|
||||||
|
std::size_t& successes,
|
||||||
|
std::size_t& failures
|
||||||
|
) = 0;
|
||||||
|
virtual void sectionEnded
|
||||||
|
( const std::string& name,
|
||||||
|
std::size_t successes,
|
||||||
|
std::size_t failures
|
||||||
|
) = 0;
|
||||||
|
virtual void pushScopedInfo
|
||||||
|
( ScopedInfo* scopedInfo
|
||||||
|
) = 0;
|
||||||
|
virtual void popScopedInfo
|
||||||
|
( ScopedInfo* scopedInfo
|
||||||
|
) = 0;
|
||||||
|
virtual bool shouldDebugBreak
|
||||||
|
() const = 0;
|
||||||
|
|
||||||
|
virtual ResultAction::Value acceptResult
|
||||||
|
( bool result
|
||||||
|
) = 0;
|
||||||
|
virtual ResultAction::Value acceptResult
|
||||||
|
( ResultWas::OfType result
|
||||||
|
) = 0;
|
||||||
|
virtual void acceptExpression
|
||||||
|
( const MutableResultInfo& resultInfo
|
||||||
|
) = 0;
|
||||||
|
virtual void acceptMessage
|
||||||
|
( const std::string& msg
|
||||||
|
) = 0;
|
||||||
|
|
||||||
|
virtual std::string getCurrentTestName
|
||||||
|
() const = 0;
|
||||||
|
|
||||||
virtual ResultAction::Value acceptResult( bool result ) = 0;
|
|
||||||
virtual ResultAction::Value acceptResult( ResultWas::OfType result ) = 0;
|
|
||||||
virtual void acceptExpression( const MutableResultInfo& resultInfo ) = 0;
|
|
||||||
virtual void acceptMessage( const std::string& msg ) = 0;
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -26,12 +26,7 @@ namespace Catch
|
||||||
~ReporterRegistry
|
~ReporterRegistry
|
||||||
()
|
()
|
||||||
{
|
{
|
||||||
FactoryMap::const_iterator it = m_factories.begin();
|
deleteAllValues( m_factories );
|
||||||
FactoryMap::const_iterator itEnd = m_factories.end();
|
|
||||||
for(; it != itEnd; ++it )
|
|
||||||
{
|
|
||||||
delete it->second;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////
|
||||||
|
|
|
@ -197,12 +197,16 @@ namespace Catch
|
||||||
|
|
||||||
m_runningTest = RunningTest( &testInfo );
|
m_runningTest = RunningTest( &testInfo );
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
m_runningTest.resetSectionSeen();
|
m_runningTest.resetSectionSeen();
|
||||||
runCurrentTest( redirectedCout, redirectedCerr );
|
runCurrentTest( redirectedCout, redirectedCerr );
|
||||||
}
|
}
|
||||||
while( m_runningTest.wasSectionSeen() );
|
while( m_runningTest.wasSectionSeen() );
|
||||||
|
}
|
||||||
|
while( Hub::advanceGeneratorsForCurrentTest() );
|
||||||
|
|
||||||
m_runningTest = RunningTest();
|
m_runningTest = RunningTest();
|
||||||
|
|
||||||
|
@ -358,6 +362,15 @@ namespace Catch
|
||||||
{
|
{
|
||||||
return m_config.shouldDebugBreak();
|
return m_config.shouldDebugBreak();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////
|
||||||
|
virtual std::string getCurrentTestName
|
||||||
|
()
|
||||||
|
const
|
||||||
|
{
|
||||||
|
return m_runningTest.getTestCaseInfo().getName();
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////
|
||||||
|
|
Loading…
Reference in New Issue