1#include <cppunit/extensions/TestFactoryRegistry.h> 2#include <cppunit/TestSuite.h> 3#include <set> 4#include <string> 5 6 7#if CPPUNIT_USE_TYPEINFO_NAME 8# include "cppunit/extensions/TypeInfoHelper.h" 9#endif 10 11 12using std::map; 13using std::set; 14using std::string; 15 16namespace CppUnit { 17 18/** (Implementation) This class manages all the TestFactoryRegistry. 19 * 20 * Responsible for the life-cycle of the TestFactoryRegistry. 21 * 22 * TestFactory registry must call wasDestroyed() to indicate that 23 * a given TestRegistry was destroyed, and needDestroy() to 24 * know if a given TestFactory need to be destroyed (was not already 25 * destroyed by another TestFactoryRegistry). 26 */ 27class NamedRegistries 28{ 29public: 30 ~NamedRegistries(); 31 32 static NamedRegistries &getInstance(); 33 34 TestFactoryRegistry &getRegistry( string name ); 35 36 void wasDestroyed( TestFactory *factory ); 37 38 bool needDestroy( TestFactory *factory ); 39 40private: 41 typedef map<string, TestFactoryRegistry *> Registries; 42 Registries m_registries; 43 44 typedef set<TestFactory *> Factories; 45 Factories m_factoriesToDestroy; 46 Factories m_destroyedFactories; 47}; 48 49 50NamedRegistries::~NamedRegistries() 51{ 52 Registries::iterator it = m_registries.begin(); 53 while ( it != m_registries.end() ) 54 { 55 TestFactoryRegistry *registry = (it++)->second; 56 if ( needDestroy( registry ) ) 57 delete registry; 58 } 59} 60 61 62NamedRegistries & 63NamedRegistries::getInstance() 64{ 65 static NamedRegistries namedRegistries; 66 return namedRegistries; 67} 68 69 70TestFactoryRegistry & 71NamedRegistries::getRegistry( string name ) 72{ 73 Registries::const_iterator foundIt = m_registries.find( name ); 74 if ( foundIt == m_registries.end() ) 75 { 76 TestFactoryRegistry *factory = new TestFactoryRegistry( name ); 77#if defined(__POWERPC__) && (defined(__BEOS__) || defined(__HAIKU__)) 78 m_registries.insert( 79 pair< 80 const basic_string< char, char_traits< char>, allocator<char> >, 81 CppUnit::TestFactoryRegistry* 82 >( 83 name, factory 84 ) 85 ); 86#else 87 m_registries.insert( std::make_pair( name, factory ) ); 88#endif 89 m_factoriesToDestroy.insert( factory ); 90 return *factory; 91 } 92 return *foundIt->second; 93} 94 95 96void 97NamedRegistries::wasDestroyed( TestFactory *factory ) 98{ 99 m_factoriesToDestroy.erase( factory ); 100 m_destroyedFactories.insert( factory ); 101} 102 103 104bool 105NamedRegistries::needDestroy( TestFactory *factory ) 106{ 107 return m_destroyedFactories.count( factory ) == 0; 108} 109 110 111 112TestFactoryRegistry::TestFactoryRegistry( string name ) : 113 m_name( name ) 114{ 115} 116 117 118TestFactoryRegistry::~TestFactoryRegistry() 119{ 120 // The wasDestroyed() and needDestroy() is used to prevent 121 // a double destruction of a factory registry. 122 // registerFactory( "All Tests", getRegistry( "Unit Tests" ) ); 123 // => the TestFactoryRegistry "Unit Tests" is owned by both 124 // the "All Tests" registry and the NamedRegistries... 125 NamedRegistries::getInstance().wasDestroyed( this ); 126 127 for ( Factories::iterator it = m_factories.begin(); it != m_factories.end(); ++it ) 128 { 129 TestFactory *factory = it->second; 130 if ( NamedRegistries::getInstance().needDestroy( factory ) ) 131 delete factory; 132 } 133} 134 135 136TestFactoryRegistry & 137TestFactoryRegistry::getRegistry() 138{ 139 return getRegistry( "All Tests" ); 140} 141 142 143TestFactoryRegistry & 144TestFactoryRegistry::getRegistry( const string &name ) 145{ 146 return NamedRegistries::getInstance().getRegistry( name ); 147} 148 149 150void 151TestFactoryRegistry::registerFactory( const string &name, 152 TestFactory *factory ) 153{ 154 m_factories[name] = factory; 155} 156 157 158void 159TestFactoryRegistry::registerFactory( TestFactory *factory ) 160{ 161 static int serialNumber = 1; 162 163 OStringStream ost; 164 ost << "@Dummy@" << serialNumber++; 165 166 registerFactory( ost.str(), factory ); 167} 168 169 170Test * 171TestFactoryRegistry::makeTest() 172{ 173 TestSuite *suite = new TestSuite( m_name ); 174 addTestToSuite( suite ); 175 return suite; 176} 177 178 179void 180TestFactoryRegistry::addTestToSuite( TestSuite *suite ) 181{ 182 for ( Factories::iterator it = m_factories.begin(); 183 it != m_factories.end(); 184 ++it ) 185 { 186 TestFactory *factory = (*it).second; 187 suite->addTest( factory->makeTest() ); 188 } 189} 190 191 192} // namespace CppUnit 193