#include <cppunit/config/SourcePrefix.h>
#include <cppunit/extensions/TestFactoryRegistry.h>
#include <map>
#include <cppunit/TestSuite.h>
#include <assert.h>
CPPUNIT_NS_BEGIN
/*! \brief (INTERNAL) List of all TestFactoryRegistry.
*/
class TestFactoryRegistryList
{
private:
typedef std::map<std::string, TestFactoryRegistry *, std::less<std::string> > Registries;
Registries m_registries;
enum State {
doNotChange =0,
notCreated,
exist,
destroyed
};
static State stateFlag( State newState = doNotChange )
{
static State state = notCreated;
if ( newState != doNotChange )
state = newState;
return state;
}
static TestFactoryRegistryList *getInstance()
{
static TestFactoryRegistryList list;
return &list;
}
TestFactoryRegistry *getInternalRegistry( const std::string &name )
{
Registries::const_iterator foundIt = m_registries.find( name );
if ( foundIt == m_registries.end() )
{
TestFactoryRegistry *factory = new TestFactoryRegistry( name );
m_registries.insert( std::pair<const std::string, TestFactoryRegistry*>( name, factory ) );
return factory;
}
return (*foundIt).second;
}
public:
TestFactoryRegistryList()
: m_registries()
{
stateFlag( exist );
}
~TestFactoryRegistryList()
{
for ( Registries::iterator it = m_registries.begin(); it != m_registries.end(); ++it )
delete (*it).second;
stateFlag( destroyed );
}
static TestFactoryRegistry *getRegistry( const std::string &name )
{
// If the following assertion failed, then TestFactoryRegistry::getRegistry()
// was called during static variable destruction without checking the registry
// validity beforehand using TestFactoryRegistry::isValid() beforehand.
assert( isValid() );
if ( !isValid() ) // release mode
return NULL; // => force CRASH
return getInstance()->getInternalRegistry( name );
}
static bool isValid()
{
return stateFlag() != destroyed;
}
};
TestFactoryRegistry::TestFactoryRegistry( std::string name ) :
m_factories(),
m_name( name )
{
}
TestFactoryRegistry::~TestFactoryRegistry()
{
}
TestFactoryRegistry &
TestFactoryRegistry::getRegistry( const std::string &name )
{
return *TestFactoryRegistryList::getRegistry( name );
}
void
TestFactoryRegistry::registerFactory( const std::string &,
TestFactory *factory )
{
registerFactory( factory );
}
void
TestFactoryRegistry::registerFactory( TestFactory *factory )
{
m_factories.insert( factory );
}
void
TestFactoryRegistry::unregisterFactory( TestFactory *factory )
{
m_factories.erase( factory );
}
void
TestFactoryRegistry::addRegistry( const std::string &name )
{
registerFactory( &getRegistry( name ) );
}
Test *
TestFactoryRegistry::makeTest()
{
TestSuite *suite = new TestSuite( m_name );
addTestToSuite( suite );
return suite;
}
void
TestFactoryRegistry::addTestToSuite( TestSuite *suite )
{
for ( Factories::iterator it = m_factories.begin();
it != m_factories.end();
++it )
{
TestFactory *factory = *it;
suite->addTest( factory->makeTest() );
}
}
bool
TestFactoryRegistry::isValid()
{
return TestFactoryRegistryList::isValid();
}
CPPUNIT_NS_END