summaryrefslogtreecommitdiffstats
blob: 9d10c94d7c20a1d3f4338708a855e51f89b65a2d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
#ifndef CPPUNIT_EXTENSIONS_TESTFACTORYREGISTRY_H
#define CPPUNIT_EXTENSIONS_TESTFACTORYREGISTRY_H

#include <cppunit/Portability.h>

#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
#endif

#include <set>
#include <cppunit/extensions/TestFactory.h>
#include <string>

CPPUNIT_NS_BEGIN


class TestSuite;

/*! \brief Registry for TestFactory.
 * \ingroup CreatingTestSuite
 *
 * 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 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
 * CPPUNIT_TEST_SUITE_REGISTRATION().
 * \code
 * CppUnit::TestFactoryRegistry &registry = CppUnit::TestFactoryRegistry::getRegistry();
 * CppUnit::TestSuite *suite = registry.makeTest();
 * \endcode
 *
 * Example 2: retreiving a suite that contains all the test registered with
 * \link CPPUNIT_TEST_SUITE_NAMED_REGISTRATION() CPPUNIT_TEST_SUITE_NAMED_REGISTRATION( ..., "Math" )\endlink.
 * \code
 * CppUnit::TestFactoryRegistry &mathRegistry = CppUnit::TestFactoryRegistry::getRegistry( "Math" );
 * CppUnit::TestSuite *mathSuite = mathRegistry.makeTest();
 * \endcode
 *
 * Example 3: creating a test suite hierarchy composed of unnamed registration and
 * named registration:
 * - All Tests
 *   - tests registered with CPPUNIT_TEST_SUITE_NAMED_REGISTRATION( ..., "Graph" )
 *   - tests registered with CPPUNIT_TEST_SUITE_NAMED_REGISTRATION( ..., "Math" )
 *   - tests registered with CPPUNIT_TEST_SUITE_REGISTRATION
 *
 * \code
 * CppUnit::TestSuite *rootSuite = new CppUnit::TestSuite( "All tests" );
 * rootSuite->addTest( CppUnit::TestFactoryRegistry::getRegistry( "Graph" ).makeTest() );
 * rootSuite->addTest( CppUnit::TestFactoryRegistry::getRegistry( "Math" ).makeTest() );
 * CppUnit::TestFactoryRegistry::getRegistry().addTestToSuite( rootSuite );
 * \endcode
 *
 * The same result can be obtained with:
 * \code
 * CppUnit::TestFactoryRegistry &registry = CppUnit::TestFactoryRegistry::getRegistry();
 * registry.addRegistry( "Graph" );
 * registry.addRegistry( "Math" );
 * CppUnit::TestSuite *suite = registry.makeTest();
 * \endcode
 *
 * Since a TestFactoryRegistry is a TestFactory, the named registries can be 
 * registered in the unnamed registry, creating the hierarchy links.
 *
 * \see TestSuiteFactory, AutoRegisterSuite
 * \see CPPUNIT_TEST_SUITE_REGISTRATION, CPPUNIT_TEST_SUITE_NAMED_REGISTRATION
 */
class CPPUNIT_API TestFactoryRegistry : public TestFactory
{
public:
  /** Constructs the registry with the specified name.
   * \param name Name of the registry. It is the name of TestSuite returned by
   *             makeTest().
   */
  TestFactoryRegistry( std::string name );

  /// Destructor.
  virtual ~TestFactoryRegistry();

  /** Returns a new TestSuite that contains the registered test.
   * \return A new TestSuite which contains all the test added using 
   * registerFactory(TestFactory *).
   */
  virtual Test *makeTest();

  /** Returns a named registry.
   *
   * 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 = "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. 
   * \deprecated Use registerFactory( TestFactory *) instead.
   */
  void registerFactory( const std::string &name,
                        TestFactory *factory );

private:
  TestFactoryRegistry( const TestFactoryRegistry &copy );
  void operator =( const TestFactoryRegistry &copy );

private:
  typedef std::set<TestFactory *, std::less<TestFactory*> > Factories;
  Factories m_factories;

  std::string m_name;
};


CPPUNIT_NS_END

#if CPPUNIT_NEED_DLL_DECL
#pragma warning( pop )
#endif


#endif  // CPPUNIT_EXTENSIONS_TESTFACTORYREGISTRY_H