summaryrefslogtreecommitdiff
path: root/include/cppunit/extensions
diff options
context:
space:
mode:
Diffstat (limited to 'include/cppunit/extensions')
-rw-r--r--include/cppunit/extensions/AutoRegisterSuite.h103
-rw-r--r--include/cppunit/extensions/HelperMacros.h47
-rw-r--r--include/cppunit/extensions/TestFactoryRegistry.h84
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 &registry = 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 &copy );
void operator =( const TestFactoryRegistry &copy );
private:
- typedef std::map<std::string, TestFactory *> Factories;
+ typedef std::set<TestFactory *> Factories;
Factories m_factories;
std::string m_name;