registry.h
Go to the documentation of this file.00001 #ifndef CPPUT_REGISTRY_H_INCLUDED
00002 # define CPPUT_REGISTRY_H_INCLUDED
00003
00004 # include <cpput/forwards.h>
00005 # include <cpptl/conststring.h>
00006 # include <cpptl/functor.h>
00007 # include <deque>
00008 # include <map>
00009
00010
00011 namespace CppUT {
00012
00015 typedef CppTL::Functor0R<TestPtr> TestFactory;
00016
00019 typedef int TestFactoryId;
00020
00021
00027 class CPPUT_API Registry
00028 {
00029 public:
00030 static std::string defaultParentSuiteName();
00031
00032 static Registry &instance();
00033
00034 Registry();
00035
00036 void addChild( const std::string &parentSuiteName,
00037 const std::string &childSuiteName );
00038 void addChildToDefault( const std::string &childSuiteName );
00039
00040 bool removeChild( const std::string &parentSuiteName,
00041 const std::string &childSuiteName );
00042
00043 TestFactoryId add( const std::string &parentSuiteName,
00044 const TestFactory &testFactory );
00045 TestFactoryId add( const std::string &parentSuiteName,
00046 TestPtr (*factory)() );
00047 TestFactoryId add( const std::string &parentSuiteName,
00048 TestPtr (*factory)( const std::string &suiteName ),
00049 const std::string &suiteName = std::string("") );
00050
00051 TestFactoryId addToDefault( const TestFactory &testFactory );
00052 TestFactoryId addToDefault( TestPtr (*factory)() );
00053 TestFactoryId addToDefault( TestPtr (*factory)( const std::string &suiteName ),
00054 const std::string &suiteName = std::string("") );
00055
00056 bool remove( TestFactoryId testFactoryId );
00057
00058 TestSuitePtr createTests( const std::string &suiteName ) const;
00059
00060 TestSuitePtr createDefaultTests() const;
00061
00062 void addCreatedTests( const std::string &suiteName,
00063 const TestSuitePtr &suite ) const;
00064
00065 private:
00066 void addChildSuite( const std::string &suiteName,
00067 const TestSuitePtr &suite ) const;
00068
00069 void addSuiteRegisteredTests( const std::string &suiteName,
00070 const TestSuitePtr &suite ) const;
00071
00072 TestFactoryId nextFactoryId();
00073
00074 typedef std::pair<TestFactory, TestFactoryId> TestFactoryWithId;
00075
00076 typedef std::deque<TestFactoryWithId> TestFactories;
00077 typedef std::map<CppTL::ConstString,TestFactories> TestFactoryRegistry;
00078 TestFactoryRegistry registry_;
00079
00080 typedef std::multimap<CppTL::ConstString,CppTL::ConstString> ParentChildRelationShips;
00081 ParentChildRelationShips relations_;
00082
00083 typedef std::map<TestFactoryId,CppTL::ConstString> TestFactoryParentSuiteById;
00084 TestFactoryParentSuiteById parentSuiteById_;
00085
00086 TestFactoryId nextId_;
00087 };
00088
00089
00090 namespace Impl {
00091
00092 enum RegisterToNamedSuiteTag {
00093 registerToNamedSuite
00094 };
00095
00096 }
00097
00098
00101 template<class SuiteType>
00102 class SuiteRegisterer
00103 {
00104 public:
00105 SuiteRegisterer()
00106 {
00107 testFactoryId_ = Registry::instance().addToDefault( &SuiteType::suite );
00108 }
00109
00110 SuiteRegisterer( const std::string &suiteName )
00111 {
00112 testFactoryId_ = Registry::instance().addToDefault( &SuiteType::suite,
00113 suiteName );
00114 }
00115
00116 SuiteRegisterer( Impl::RegisterToNamedSuiteTag,
00117 const std::string &parentSuiteName )
00118 {
00119 testFactoryId_ = Registry::instance().add( parentSuiteName,
00120 &SuiteType::suite );
00121 }
00122
00123 SuiteRegisterer( Impl::RegisterToNamedSuiteTag,
00124 const std::string &parentSuiteName,
00125 const std::string &suiteName )
00126 {
00127 testFactoryId_ = Registry::instance().add( parentSuiteName,
00128 &SuiteType::suite,
00129 suiteName );
00130 }
00131
00132 ~SuiteRegisterer()
00133 {
00134 Registry::instance().remove( testFactoryId_ );
00135 }
00136
00137 protected:
00138 SuiteRegisterer( TestFactoryId testFactoryId ):
00139 testFactoryId_( testFactoryId )
00140 {
00141 }
00142
00143 private:
00144 TestFactoryId testFactoryId_;
00145 };
00146
00147
00148
00151 #define CPPUT_REGISTER_NAMED_SUITE_TO_DEFAULT( TestFixtureType, suiteName ) \
00152 static CppUT::SuiteRegisterer< TestFixtureType > \
00153 CPPTL_MAKE_UNIQUE_NAME(cpputSuiteRegisterer )(suiteName);
00154
00155
00158 #define CPPUT_REGISTER_SUITE_TO_DEFAULT( TestFixtureType ) \
00159 static CppUT::SuiteRegisterer< TestFixtureType > \
00160 CPPTL_MAKE_UNIQUE_NAME(cpputSuiteRegisterer );
00161
00162
00165 #define CPPUT_REGISTER_SUITE_IN( TestFixtureType, parentSuiteName ) \
00166 static CppUT::SuiteRegisterer< TestFixtureType > \
00167 CPPTL_MAKE_UNIQUE_NAME(cpputSuiteRegisterer)( \
00168 CppUT::Impl::registerToNamedSuite, \
00169 parentSuiteName );
00170
00171
00174 #define CPPUT_REGISTER_NAMED_SUITE_IN( TestFixtureType, \
00175 parentSuiteName, \
00176 suiteName ) \
00177 static CppUT::SuiteRegisterer< TestFixtureType > \
00178 CPPTL_MAKE_UNIQUE_NAME(cpputSuiteRegisterer )( \
00179 CppUT::Impl::registerToNamedSuite, \
00180 parentSuiteName, \
00181 suiteName );
00182
00185 class SuiteRelationshipRegisterer
00186 {
00187 public:
00188 explicit SuiteRelationshipRegisterer( const std::string &childSuiteName )
00189 : childSuiteName_( childSuiteName )
00190 , parentSuiteName_( Registry::defaultParentSuiteName() )
00191 {
00192 Registry::instance().addChildToDefault( childSuiteName );
00193 }
00194
00195 SuiteRelationshipRegisterer( const std::string &parentSuiteName,
00196 const std::string &childSuiteName )
00197 : parentSuiteName_( parentSuiteName )
00198 , childSuiteName_( childSuiteName )
00199 {
00200 Registry::instance().addChild( parentSuiteName, childSuiteName );
00201 }
00202
00203 ~SuiteRelationshipRegisterer()
00204 {
00205 Registry::instance().removeChild( parentSuiteName_.str(),
00206 childSuiteName_.str() );
00207 }
00208
00209 private:
00210 CppTL::ConstString parentSuiteName_;
00211 CppTL::ConstString childSuiteName_;
00212 };
00213
00214
00217 #define CPPUT_REGISTER_SUITE_RELATIONSHIP( parentSuiteName, childSuiteName ) \
00218 static ::CppUT::SuiteRelationshipRegisterer \
00219 CPPTL_MAKE_UNIQUE_NAME(cpputSuiteRelationShipRegisterer )( \
00220 parentSuiteName, \
00221 childSuiteName )
00222
00223
00226 #define CPPUT_REGISTER_SUITE_RELATIONSHIP_TO_DEFAULT( childSuiteName ) \
00227 static ::CppUT::SuiteRelationshipRegisterer \
00228 CPPTL_MAKE_UNIQUE_NAME(cpputSuiteRelationShipRegisterer )( \
00229 childSuiteName )
00230
00231
00232
00233
00237 class TestFactoryRegisterer
00238 {
00239 public:
00240 typedef TestPtr (*FactoryFn)();
00241
00242 TestFactoryRegisterer( FactoryFn testFactory )
00243 {
00244 testFactoryId_ = Registry::instance().addToDefault( CppTL::cfn0r<TestPtr>(testFactory) );
00245 }
00246
00247 TestFactoryRegisterer( TestFactory testFactory )
00248 {
00249 testFactoryId_ = Registry::instance().addToDefault( testFactory );
00250 }
00251
00252 TestFactoryRegisterer( TestFactory testFactory, const std::string &parentSuiteName )
00253 {
00254 testFactoryId_ = Registry::instance().add( parentSuiteName, testFactory );
00255 }
00256
00257 TestFactoryRegisterer( FactoryFn testFactory, const std::string &parentSuiteName )
00258 {
00259 testFactoryId_ = Registry::instance().add( parentSuiteName, CppTL::cfn0r<TestPtr>(testFactory) );
00260 }
00261
00262 ~TestFactoryRegisterer()
00263 {
00264 Registry::instance().remove( testFactoryId_ );
00265 }
00266
00267 private:
00268 TestFactoryId testFactoryId_;
00269 };
00270
00274 #define CPPUT_REGISTER_TESTFACTORY_TO_DEFAULT( testFactory ) \
00275 static ::CppUT::TestFactoryRegisterer \
00276 CPPTL_MAKE_UNIQUE_NAME(cpputTestFactoryRegisterer)( testFactory )
00277
00281 #define CPPUT_REGISTER_TESTFACTORY_IN( testFactory, parentSuiteName ) \
00282 static ::CppUT::TestFactoryRegisterer \
00283 CPPTL_MAKE_UNIQUE_NAME(cpputTestFactoryRegisterer)( testFactory, parentSuiteName )
00284
00285 }
00286
00287
00288 #endif // CPPUT_REGISTRY_H_INCLUDED