summaryrefslogtreecommitdiff
path: root/src/cppunit/TestFactoryRegistry.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/cppunit/TestFactoryRegistry.cpp')
-rw-r--r--src/cppunit/TestFactoryRegistry.cpp171
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