CppUnit project page CppUnit home page

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 } // namespace Impl
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 // Plain C function tests
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 } // namespace CppUT
00286 
00287 
00288 #endif // CPPUT_REGISTRY_H_INCLUDED

SourceForge Logo hosts this site. Send comments to:
CppUnit Developers