diff options
Diffstat (limited to 'include/cppunit/extensions')
| -rw-r--r-- | include/cppunit/extensions/AutoRegisterSuite.h | 103 | ||||
| -rw-r--r-- | include/cppunit/extensions/HelperMacros.h | 47 | ||||
| -rw-r--r-- | include/cppunit/extensions/TestFactoryRegistry.h | 84 |
3 files changed, 173 insertions, 61 deletions
diff --git a/include/cppunit/extensions/AutoRegisterSuite.h b/include/cppunit/extensions/AutoRegisterSuite.h index 8af3489..ccf6997 100644 --- a/include/cppunit/extensions/AutoRegisterSuite.h +++ b/include/cppunit/extensions/AutoRegisterSuite.h @@ -1,49 +1,80 @@ #ifndef CPPUNIT_EXTENSIONS_AUTOREGISTERSUITE_H #define CPPUNIT_EXTENSIONS_AUTOREGISTERSUITE_H -#include <string> #include <cppunit/extensions/TestSuiteFactory.h> #include <cppunit/extensions/TestFactoryRegistry.h> +#include <string> namespace CppUnit { - /** Automatically register the test suite of the specified type. - * - * You should not use this class directly. Instead, use the following macros: - * - CPPUNIT_TEST_SUITE_REGISTRATION() - * - CPPUNIT_TEST_SUITE_NAMED_REGISTRATION() - * - * This object will register the test returned by TestCaseType::suite() - * when constructed to the test registry. - * - * This object is intented to be used as a static variable. - * - * - * \param TestCaseType Type of the test case which suite is registered. - * \see CPPUNIT_TEST_SUITE_REGISTRATION, CPPUNIT_TEST_SUITE_NAMED_REGISTRATION - * \see CppUnit::TestFactoryRegistry. +/** Automatically register the test suite of the specified type. (Implementation) + * + * You should not use this class directly. Instead, use the following macros: + * - CPPUNIT_TEST_SUITE_REGISTRATION() + * - CPPUNIT_TEST_SUITE_NAMED_REGISTRATION() + * + * This object will register the test returned by TestCaseType::suite() + * when constructed to the test registry. + * + * This object is intented to be used as a static variable. + * + * + * \param TestCaseType Type of the test case which suite is registered. + * \see CPPUNIT_TEST_SUITE_REGISTRATION, CPPUNIT_TEST_SUITE_NAMED_REGISTRATION + * \see CppUnit::TestFactoryRegistry. + */ +template<typename TestCaseType> +class AutoRegisterSuite +{ +public: + /** Auto-register the suite factory in the global registry. */ - template<typename TestCaseType> - class AutoRegisterSuite + AutoRegisterSuite() + : m_registry( &TestFactoryRegistry::getRegistry() ) + { + m_registry->registerFactory( &m_factory ); + } + + /** Auto-register the suite factory in the specified registry. + * \param name Name of the registry. + */ + AutoRegisterSuite( const std::string &name ) + : m_registry( &TestFactoryRegistry::getRegistry( name ) ) + { + m_registry->registerFactory( &m_factory ); + } + + ~AutoRegisterSuite() + { + if ( TestFactoryRegistry::isValid() ) + m_registry->unregisterFactory( &m_factory ); + } + +private: + TestFactoryRegistry *m_registry; + TestSuiteFactory<TestCaseType> m_factory; +}; + + +/*! Automatically adds a registry into another registry. (Implementation) + * + * Don't use this class. Use the macros CPPUNIT_REGISTRY_ADD() and + * CPPUNIT_REGISTRY_ADD_TO_DEFAULT() instead. + */ +class AutoRegisterRegistry +{ +public: + AutoRegisterRegistry( const std::string &which, + const std::string &to ) + { + TestFactoryRegistry::getRegistry( to ).addRegistry( which ); + } + + AutoRegisterRegistry( const std::string &which ) { - public: - /** Auto-register the suite factory in the global registry. - */ - AutoRegisterSuite() - { - TestFactory *factory = new TestSuiteFactory<TestCaseType>(); - TestFactoryRegistry::getRegistry().registerFactory( factory ); - } - - /** Auto-register the suite factory in the specified registry. - * \param name Name of the registry. - */ - AutoRegisterSuite( const std::string &name ) - { - TestFactory *factory = new TestSuiteFactory<TestCaseType>(); - TestFactoryRegistry::getRegistry( name ).registerFactory( factory ); - } - }; + TestFactoryRegistry::getRegistry().addRegistry( which ); + } +}; } // namespace CppUnit diff --git a/include/cppunit/extensions/HelperMacros.h b/include/cppunit/extensions/HelperMacros.h index c7be1aa..e8dfbef 100644 --- a/include/cppunit/extensions/HelperMacros.h +++ b/include/cppunit/extensions/HelperMacros.h @@ -272,6 +272,8 @@ namespace CppUnit * \warning This macro should be used only once per line of code (the line * number is used to name a hidden static variable). * \see CPPUNIT_TEST_SUITE_NAMED_REGISTRATION + * \see CPPUNIT_REGISTRY_ADD_TO_DEFAULT + * \see CPPUNIT_REGISTRY_ADD * \see CPPUNIT_TEST_SUITE, CppUnit::AutoRegisterSuite, * CppUnit::TestFactoryRegistry. */ @@ -312,6 +314,8 @@ namespace CppUnit * \warning This macro should be used only once per line of code (the line * number is used to name a hidden static variable). * \see CPPUNIT_TEST_SUITE_REGISTRATION + * \see CPPUNIT_REGISTRY_ADD_TO_DEFAULT + * \see CPPUNIT_REGISTRY_ADD * \see CPPUNIT_TEST_SUITE, CppUnit::AutoRegisterSuite, * CppUnit::TestFactoryRegistry.. */ @@ -319,6 +323,49 @@ namespace CppUnit static CppUnit::AutoRegisterSuite< ATestFixtureType > \ CPPUNIT_MAKE_UNIQUE_NAME(__autoRegisterSuite )(suiteName) +/*! Adds that the specified registry suite to another registry suite. + * \ingroup CreatingTestSuite + * + * Use this macros to automatically create test registry suite hierarchy. For example, + * if you want to create the following hierarchy: + * - Math + * - IntegerMath + * - FloatMath + * - FastFloat + * - StandardFloat + * + * You can do this automatically with: + * \code + * CPPUNIT_REGISTRY_ADD( "FastFloat", "FloatMath" ); + * CPPUNIT_REGISTRY_ADD( "IntegerMath", "Math" ); + * CPPUNIT_REGISTRY_ADD( "FloatMath", "Math" ); + * CPPUNIT_REGISTRY_ADD( "StandardFloat", "FloatMath" ); + * \endcode + * + * There is no specific order of declaration. Think of it as declaring links. + * + * You register the test in each suite using CPPUNIT_TEST_SUITE_NAMED_REGISTRATION. + * + * \param which Name of the registry suite to add to the registry suite named \a to. + * \param to Name of the registry suite \a which is added to. + * \see CPPUNIT_REGISTRY_ADD_TO_DEFAULT, CPPUNIT_TEST_SUITE_NAMED_REGISTRATION. + */ +#define CPPUNIT_REGISTRY_ADD( which, to ) \ + static CppUnit::AutoRegisterRegistry \ + CPPUNIT_MAKE_UNIQUE_NAME( __autoRegisterRegistry)( which, to ) + +/*! Adds that the specified registry suite to the default registry suite. + * \ingroup CreatingTestSuite + * + * This macro is just like CPPUNIT_REGISTRY_ADD except the specified registry + * suite is added to the default suite (root suite). + * + * \param which Name of the registry suite to add to the default registry suite. + * \see CPPUNIT_REGISTRY_ADD. + */ +#define CPPUNIT_REGISTRY_ADD_TO_DEFAULT( which ) \ + static CppUnit::AutoRegisterRegistry \ + CPPUNIT_MAKE_UNIQUE_NAME( __autoRegisterRegistry)( which ) // Backwards compatibility // (Not tested!) diff --git a/include/cppunit/extensions/TestFactoryRegistry.h b/include/cppunit/extensions/TestFactoryRegistry.h index 6553fe5..5020219 100644 --- a/include/cppunit/extensions/TestFactoryRegistry.h +++ b/include/cppunit/extensions/TestFactoryRegistry.h @@ -5,11 +5,11 @@ #if CPPUNIT_NEED_DLL_DECL #pragma warning( push ) -#pragma warning( disable: 4251 ) // X needs to have dll-interface to be used by clients of class Z +#pragma warning( disable: 4251) // X needs to have dll-interface to be used by clients of class Z #endif #include <cppunit/extensions/TestFactory.h> -#include <map> +#include <set> #include <string> namespace CppUnit { @@ -17,17 +17,21 @@ namespace CppUnit { class TestSuite; #if CPPUNIT_NEED_DLL_DECL - template class CPPUNIT_API std::map<std::string, TestFactory *>; + template class CPPUNIT_API std::set<TestFactory *>; #endif /*! \brief Registry for TestFactory. * \ingroup CreatingTestSuite * - * Notes that the registry assumes lifetime control for any registered test. + * Notes that the registry \b DON'T assumes lifetime control for any registered tests + * anymore. + * + * The <em>default</em> registry is the registry returned by getRegistry() with the + * default name parameter value. * * To register tests, use the macros: - * - CPPUNIT_TEST_SUITE_REGISTRATION(): to add tests in the unnamed registry. + * - CPPUNIT_TEST_SUITE_REGISTRATION(): to add tests in the default registry. * - CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(): to add tests in a named registry. * * Example 1: retreiving a suite that contains all the test registered with @@ -61,8 +65,8 @@ class TestSuite; * The same result can be obtained with: * \code * CppUnit::TestFactoryRegistry ®istry = CppUnit::TestFactoryRegistry::getRegistry(); - * registry.registerFactory( CppUnit::TestFactoryRegistry::getRegistry( "Graph" ) ); - * registry.registerFactory( CppUnit::TestFactoryRegistry::getRegistry( "Math" ) ); + * registry.addRegistry( "Graph" ); + * registry.addRegistry( "Math" ); * CppUnit::TestSuite *suite = registry.makeTest(); * \endcode * @@ -79,7 +83,7 @@ public: * \param name Name of the registry. It is the name of TestSuite returned by * makeTest(). */ - TestFactoryRegistry( std::string name = "All Tests" ); + TestFactoryRegistry( std::string name ); /// Destructor. virtual ~TestFactoryRegistry(); @@ -90,27 +94,63 @@ public: */ virtual Test *makeTest(); - /** Returns unnamed the registry. - * TestSuite registered using CPPUNIT_TEST_SUITE_REGISTRATION() are registered - * in this registry. - * \return Registry which name is "All Tests". - */ - static TestFactoryRegistry &getRegistry(); - /** Returns a named registry. - * TestSuite registered using CPPUNIT_TEST_SUITE_NAMED_REGISTRATION() are registered - * in the registry of the same name. + * + * If the \a name is left to its default value, then the registry that is returned is + * the one used by CPPUNIT_TEST_SUITE_REGISTRATION(): the 'top' level registry. + * * \param name Name of the registry to return. * \return Registry. If the registry does not exist, it is created with the * specified name. */ - static TestFactoryRegistry &getRegistry( const std::string &name ); + static TestFactoryRegistry &getRegistry( const std::string &name = "All Tests" ); /** Adds the registered tests to the specified suite. * \param suite Suite the tests are added to. */ void addTestToSuite( TestSuite *suite ); + /** Adds the specified TestFactory to the registry. + * + * \param factory Factory to register. + */ + void registerFactory( TestFactory *factory ); + + /*! Removes the specified TestFactory from the registry. + * + * The specified factory is not destroyed. + * \param factory Factory to remove from the registry. + * \todo Address case when trying to remove a TestRegistryFactory. + */ + void unregisterFactory( TestFactory *factory ); + + /*! Adds a registry to the registry. + * + * Convenience method to help create test hierarchy. See TestFactoryRegistry detail + * for examples of use. Calling this method is equivalent to: + * \code + * this->registerFactory( TestFactoryRegistry::getRegistry( name ) ); + * \endcode + * + * \param name Name of the registry to add. + */ + void addRegistry( const std::string &name ); + + /*! Tests if the registry is valid. + * + * This method should be used when unregistering test factory on static variable + * destruction to ensure that the registry has not been already destroyed (in + * that case there is no need to unregister the test factory). + * + * You should not concern yourself with this method unless you are writing a class + * like AutoRegisterSuite. + * + * \return \c true if the specified registry has not been destroyed, + * otherwise returns \c false. + * \see AutoRegisterSuite. + */ + static bool isValid(); + /** Adds the specified TestFactory with a specific name (DEPRECATED). * \param name Name associated to the factory. * \param factory Factory to register. @@ -119,18 +159,12 @@ public: void registerFactory( const std::string &name, TestFactory *factory ); - /** Adds the specified TestFactory to the registry. - * - * \param factory Factory to register. - */ - void registerFactory( TestFactory *factory ); - private: TestFactoryRegistry( const TestFactoryRegistry © ); void operator =( const TestFactoryRegistry © ); private: - typedef std::map<std::string, TestFactory *> Factories; + typedef std::set<TestFactory *> Factories; Factories m_factories; std::string m_name; |
