diff options
Diffstat (limited to 'src/cppunit/TestFactoryRegistry.cpp')
| -rw-r--r-- | src/cppunit/TestFactoryRegistry.cpp | 171 |
1 files changed, 79 insertions, 92 deletions
diff --git a/src/cppunit/TestFactoryRegistry.cpp b/src/cppunit/TestFactoryRegistry.cpp index d46ff29..ec10c5f 100644 --- a/src/cppunit/TestFactoryRegistry.cpp +++ b/src/cppunit/TestFactoryRegistry.cpp @@ -1,7 +1,7 @@ #include <cppunit/extensions/TestFactoryRegistry.h> #include <cppunit/TestSuite.h> -#include <set> - +#include <map> +#include <assert.h> #if CPPUNIT_USE_TYPEINFO_NAME # include "cppunit/extensions/TypeInfoHelper.h" @@ -10,86 +10,77 @@ namespace CppUnit { -/** (Implementation) This class manages all the TestFactoryRegistry. - * - * Responsible for the life-cycle of the TestFactoryRegistry. - * - * TestFactory registry must call wasDestroyed() to indicate that - * a given TestRegistry was destroyed, and needDestroy() to - * know if a given TestFactory need to be destroyed (was not already - * destroyed by another TestFactoryRegistry). - */ -class NamedRegistries -{ -public: - ~NamedRegistries(); - - static NamedRegistries &getInstance(); - - TestFactoryRegistry &getRegistry( std::string name ); - - void wasDestroyed( TestFactory *factory ); - - bool needDestroy( TestFactory *factory ); +class TestFactoryRegistryList +{ private: typedef std::map<std::string, TestFactoryRegistry *> Registries; Registries m_registries; - typedef std::set<TestFactory *> Factories; - Factories m_factoriesToDestroy; - Factories m_destroyedFactories; -}; - + enum State { + doNotChange =0, + notCreated, + exist, + destroyed + }; -NamedRegistries::~NamedRegistries() -{ - Registries::iterator it = m_registries.begin(); - while ( it != m_registries.end() ) + static State stateFlag( State newState = doNotChange ) { - TestFactoryRegistry *registry = (it++)->second; - if ( needDestroy( registry ) ) - delete registry; + static State state = notCreated; + if ( newState != doNotChange ) + state = newState; + return state; } -} - -NamedRegistries & -NamedRegistries::getInstance() -{ - static NamedRegistries namedRegistries; - return namedRegistries; -} + 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::make_pair( name, factory ) ); + return factory; + } + return foundIt->second; + } -TestFactoryRegistry & -NamedRegistries::getRegistry( std::string name ) -{ - Registries::const_iterator foundIt = m_registries.find( name ); - if ( foundIt == m_registries.end() ) +public: + TestFactoryRegistryList() { - TestFactoryRegistry *factory = new TestFactoryRegistry( name ); - m_registries.insert( std::make_pair( name, factory ) ); - m_factoriesToDestroy.insert( factory ); - return *factory; + stateFlag( exist ); } - return *foundIt->second; -} + ~TestFactoryRegistryList() + { + for ( Registries::iterator it = m_registries.begin(); it != m_registries.end(); ++it ) + delete it->second; -void -NamedRegistries::wasDestroyed( TestFactory *factory ) -{ - m_factoriesToDestroy.erase( factory ); - m_destroyedFactories.insert( factory ); -} + 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 ); + } -bool -NamedRegistries::needDestroy( TestFactory *factory ) -{ - return m_destroyedFactories.count( factory ) == 0; -} + static bool isValid() + { + return stateFlag() != destroyed; + } +}; @@ -101,33 +92,13 @@ TestFactoryRegistry::TestFactoryRegistry( std::string name ) : TestFactoryRegistry::~TestFactoryRegistry() { - // The wasDestroyed() and needDestroy() is used to prevent - // a double destruction of a factory registry. - // registerFactory( "All Tests", getRegistry( "Unit Tests" ) ); - // => the TestFactoryRegistry "Unit Tests" is owned by both - // the "All Tests" registry and the NamedRegistries... - NamedRegistries::getInstance().wasDestroyed( this ); - - for ( Factories::iterator it = m_factories.begin(); it != m_factories.end(); ++it ) - { - TestFactory *factory = it->second; - if ( NamedRegistries::getInstance().needDestroy( factory ) ) - delete factory; - } -} - - -TestFactoryRegistry & -TestFactoryRegistry::getRegistry() -{ - return getRegistry( "All Tests" ); } TestFactoryRegistry & TestFactoryRegistry::getRegistry( const std::string &name ) { - return NamedRegistries::getInstance().getRegistry( name ); + return *TestFactoryRegistryList::getRegistry( name ); } @@ -135,19 +106,28 @@ void TestFactoryRegistry::registerFactory( const std::string &name, TestFactory *factory ) { - m_factories[name] = factory; + registerFactory( factory ); } void TestFactoryRegistry::registerFactory( TestFactory *factory ) { - static int serialNumber = 1; + m_factories.insert( factory ); +} + + +void +TestFactoryRegistry::unregisterFactory( TestFactory *factory ) +{ + m_factories.erase( factory ); +} - OStringStream ost; - ost << "@Dummy@" << serialNumber++; - registerFactory( ost.str(), factory ); +void +TestFactoryRegistry::addRegistry( const std::string &name ) +{ + registerFactory( &getRegistry( name ) ); } @@ -167,10 +147,17 @@ TestFactoryRegistry::addTestToSuite( TestSuite *suite ) it != m_factories.end(); ++it ) { - TestFactory *factory = (*it).second; + TestFactory *factory = *it; suite->addTest( factory->makeTest() ); } } +bool +TestFactoryRegistry::isValid() +{ + return TestFactoryRegistryList::isValid(); +} + + } // namespace CppUnit |
