1 // //////////////////////////////////////////////////////////////////////////
2 // Header file HelperMacros.h
3 // (c)Copyright 2000, Baptiste Lepilleur.
4 // Created: 2001/04/15
5 // //////////////////////////////////////////////////////////////////////////
6 #ifndef CPPUNIT_EXTENSIONS_HELPERMACROS_H
7 #define CPPUNIT_EXTENSIONS_HELPERMACROS_H
8 
9 #include <cppunit/TestCaller.h>
10 #include <cppunit/TestSuite.h>
11 #include <cppunit/extensions/AutoRegisterSuite.h>
12 #include <cppunit/extensions/ExceptionTestCaseDecorator.h>
13 #include <cppunit/extensions/TestFixtureFactory.h>
14 #include <cppunit/extensions/TestNamer.h>
15 #include <cppunit/extensions/TestSuiteBuilderContext.h>
16 #include <memory>
17 
18 
19 /*! \addtogroup WritingTestFixture Writing test fixture
20  */
21 /** @{
22  */
23 
24 
25 /** \file
26  * Macros intended to ease the definition of test suites.
27  *
28  * The macros
29  * CPPUNIT_TEST_SUITE(), CPPUNIT_TEST(), and CPPUNIT_TEST_SUITE_END()
30  * are designed to facilitate easy creation of a test suite.
31  * For example,
32  *
33  * \code
34  * #include <cppunit/extensions/HelperMacros.h>
35  * class MyTest : public CppUnit::TestFixture {
36  *   CPPUNIT_TEST_SUITE( MyTest );
37  *   CPPUNIT_TEST( testEquality );
38  *   CPPUNIT_TEST( testSetName );
39  *   CPPUNIT_TEST_SUITE_END();
40  * public:
41  *   void testEquality();
42  *   void testSetName();
43  * };
44  * \endcode
45  *
46  * The effect of these macros is to define two methods in the
47  * class MyTest.  The first method is an auxiliary function
48  * named registerTests that you will not need to call directly.
49  * The second function
50  * \code static CppUnit::TestSuite *suite()\endcode
51  * returns a pointer to the suite of tests defined by the CPPUNIT_TEST()
52  * macros.
53  *
54  * Rather than invoking suite() directly,
55  * the macro CPPUNIT_TEST_SUITE_REGISTRATION() is
56  * used to create a static variable that automatically
57  * registers its test suite in a global registry.
58  * The registry yields a Test instance containing all the
59  * registered suites.
60  * \code
61  * CPPUNIT_TEST_SUITE_REGISTRATION( MyTest );
62  * CppUnit::Test* tp =
63  *   CppUnit::TestFactoryRegistry::getRegistry().makeTest();
64  * \endcode
65  *
66  * The test suite macros can even be used with templated test classes.
67  * For example:
68  *
69  * \code
70  * template<typename CharType>
71  * class StringTest : public CppUnit::TestFixture {
72  *   CPPUNIT_TEST_SUITE( StringTest );
73  *   CPPUNIT_TEST( testAppend );
74  *   CPPUNIT_TEST_SUITE_END();
75  * public:
76  *   ...
77  * };
78  * \endcode
79  *
80  * You need to add in an implementation file:
81  *
82  * \code
83  * CPPUNIT_TEST_SUITE_REGISTRATION( StringTest<char> );
84  * CPPUNIT_TEST_SUITE_REGISTRATION( StringTest<wchar_t> );
85  * \endcode
86  */
87 
88 
89 /*! \brief Begin test suite
90  *
91  * This macro starts the declaration of a new test suite.
92  * Use CPPUNIT_TEST_SUB_SUITE() instead, if you wish to include the
93  * test suite of the parent class.
94  *
95  * \param ATestFixtureType Type of the test case class. This type \b MUST
96  *                         be derived from TestFixture.
97  * \see CPPUNIT_TEST_SUB_SUITE, CPPUNIT_TEST, CPPUNIT_TEST_SUITE_END,
98  * \see CPPUNIT_TEST_SUITE_REGISTRATION, CPPUNIT_TEST_EXCEPTION, CPPUNIT_TEST_FAIL.
99  */
100 #define CPPUNIT_TEST_SUITE( ATestFixtureType )                              \
101   public:                                                                   \
102     typedef ATestFixtureType TestFixtureType;                               \
103                                                                             \
104   private:                                                                  \
105     static const CPPUNIT_NS::TestNamer &getTestNamer__()                    \
106     {                                                                       \
107       static CPPUNIT_TESTNAMER_DECL( testNamer, ATestFixtureType );         \
108       return testNamer;                                                     \
109     }                                                                       \
110                                                                             \
111   public:                                                                   \
112     typedef CPPUNIT_NS::TestSuiteBuilderContext<TestFixtureType>            \
113                 TestSuiteBuilderContextType;                                \
114                                                                             \
115     static void                                                             \
116     addTestsToSuite( CPPUNIT_NS::TestSuiteBuilderContextBase &baseContext ) \
117     {                                                                       \
118       TestSuiteBuilderContextType context( baseContext )
119 
120 
121 /*! \brief Begin test suite (includes parent suite)
122  *
123  * This macro may only be used in a class whose parent class
124  * defines a test suite using CPPUNIT_TEST_SUITE() or CPPUNIT_TEST_SUB_SUITE().
125  *
126  * This macro begins the declaration of a test suite, in the same
127  * manner as CPPUNIT_TEST_SUITE().  In addition, the test suite of the
128  * parent is automatically inserted in the test suite being
129  * defined.
130  *
131  * Here is an example:
132  *
133  * \code
134  * #include <cppunit/extensions/HelperMacros.h>
135  * class MySubTest : public MyTest {
136  *   CPPUNIT_TEST_SUB_SUITE( MySubTest, MyTest );
137  *   CPPUNIT_TEST( testAdd );
138  *   CPPUNIT_TEST( testSub );
139  *   CPPUNIT_TEST_SUITE_END();
140  * public:
141  *   void testAdd();
142  *   void testSub();
143  * };
144  * \endcode
145  *
146  * \param ATestFixtureType Type of the test case class. This type \b MUST
147  *                         be derived from TestFixture.
148  * \param ASuperClass   Type of the parent class.
149  * \see CPPUNIT_TEST_SUITE.
150  */
151 #define CPPUNIT_TEST_SUB_SUITE( ATestFixtureType, ASuperClass )  \
152   public:                                                        \
153     typedef ASuperClass ParentTestFixtureType;                   \
154   private:                                                       \
155     CPPUNIT_TEST_SUITE( ATestFixtureType );                      \
156       ParentTestFixtureType::addTestsToSuite( baseContext )
157 
158 
159 /*! \brief End declaration of the test suite.
160  *
161  * After this macro, member access is set to "private".
162  *
163  * \see  CPPUNIT_TEST_SUITE.
164  * \see  CPPUNIT_TEST_SUITE_REGISTRATION.
165  */
166 #define CPPUNIT_TEST_SUITE_END()                                               \
167     }                                                                          \
168                                                                                \
169 public:									       \
170     static CPPUNIT_NS::TestSuite *suite()                                      \
171     {                                                                          \
172       const CPPUNIT_NS::TestNamer &namer = getTestNamer__();                   \
173       std::unique_ptr<CPPUNIT_NS::TestSuite> guard(                            \
174               new CPPUNIT_NS::TestSuite( namer.getFixtureName() ));            \
175       CPPUNIT_NS::ConcretTestFixtureFactory<TestFixtureType> factory;          \
176       CPPUNIT_NS::TestSuiteBuilderContextBase context( *guard.get(),           \
177                                                        namer,                  \
178                                                        factory );              \
179       TestFixtureType::addTestsToSuite( context );                             \
180       return guard.release();                                                  \
181     }                                                                          \
182   private: /* dummy typedef so that the macro can still end with ';'*/         \
183     typedef int CppUnitDummyTypedefForSemiColonEnding__
184 
185 /*! \brief End declaration of an abstract test suite.
186  *
187  * Use this macro to indicate that the %TestFixture is abstract. No
188  * static suite() method will be declared.
189  *
190  * After this macro, member access is set to "private".
191  *
192  * Here is an example of usage:
193  *
194  * The abstract test fixture:
195  * \code
196  * #include <cppunit/extensions/HelperMacros.h>
197  * class AbstractDocument;
198  * class AbstractDocumentTest : public CppUnit::TestFixture {
199  *   CPPUNIT_TEST_SUITE( AbstractDocumentTest );
200  *   CPPUNIT_TEST( testInsertText );
201  *   CPPUNIT_TEST_SUITE_END_ABSTRACT();
202  * public:
203  *   void testInsertText();
204  *
205  *   void setUp()
206  *   {
207  *     m_document = makeDocument();
208  *   }
209  *
210  *   void tearDown()
211  *   {
212  *     delete m_document;
213  *   }
214  * protected:
215  *   virtual AbstractDocument *makeDocument() =0;
216  *
217  *   AbstractDocument *m_document;
218  * };\endcode
219  *
220  * The concret test fixture:
221  * \code
222  * class RichTextDocumentTest : public AbstractDocumentTest {
223  *   CPPUNIT_TEST_SUB_SUITE( RichTextDocumentTest, AbstractDocumentTest );
224  *   CPPUNIT_TEST( testInsertFormatedText );
225  *   CPPUNIT_TEST_SUITE_END();
226  * public:
227  *   void testInsertFormatedText();
228  * protected:
229  *   AbstractDocument *makeDocument()
230  *   {
231  *     return new RichTextDocument();
232  *   }
233  * };\endcode
234  *
235  * \see  CPPUNIT_TEST_SUB_SUITE.
236  * \see  CPPUNIT_TEST_SUITE_REGISTRATION.
237  */
238 #define CPPUNIT_TEST_SUITE_END_ABSTRACT()                                      \
239     }                                                                          \
240   private: /* dummy typedef so that the macro can still end with ';'*/         \
241     typedef int CppUnitDummyTypedefForSemiColonEnding__
242 
243 
244 /*! \brief Add a test to the suite (for custom test macro).
245  *
246  * The specified test will be added to the test suite being declared. This macro
247  * is intended for \e advanced usage, to extend %CppUnit by creating new macro such
248  * as CPPUNIT_TEST_EXCEPTION()...
249  *
250  * Between macro CPPUNIT_TEST_SUITE() and CPPUNIT_TEST_SUITE_END(), you can assume
251  * that the following variables can be used:
252  * \code
253  * typedef TestSuiteBuilder<TestFixtureType> TestSuiteBuilderType;
254  * TestSuiteBuilderType &context;
255  * \endcode
256  *
257  * \c context can be used to name test case, create new test fixture instance,
258  * or add test case to the test fixture suite.
259  *
260  * Below is an example that show how to use this macro to create new macro to add
261  * test to the fixture suite. The macro below show how you would add a new type
262  * of test case which fails if the execution last more than a given time limit.
263  * It relies on an imaginary TimeOutTestCaller class which has an interface similar
264  * to TestCaller.
265  *
266  * \code
267  * #define CPPUNITEX_TEST_TIMELIMIT( testMethod, timeLimit )            \
268  *      CPPUNIT_TEST_SUITE_ADD_TEST( (new TimeOutTestCaller<TestFixtureType>(  \
269  *                  namer.getTestNameFor( #testMethod ),                \
270  *                  &TestFixtureType::testMethod,                   \
271  *                  factory.makeFixture(),                              \
272  *                  timeLimit ) ) )
273  *
274  * class PerformanceTest : CppUnit::TestFixture
275  * {
276  * public:
277  *   CPPUNIT_TEST_SUITE( PerformanceTest );
278  *   CPPUNITEX_TEST_TIMELIMIT( testSortReverseOrder, 5.0 );
279  *   CPPUNIT_TEST_SUITE_END();
280  *
281  *   void testSortReverseOrder();
282  * };
283  * \endcode
284  *
285  * \param test Test to add to the suite. Must be a subclass of Test. The test name
286  *             should have been obtained using TestNamer::getTestNameFor().
287  */
288 #define CPPUNIT_TEST_SUITE_ADD_TEST( test ) \
289       context.addTest( test )
290 
291 /*! \brief Add a method to the suite.
292  * \param testMethod Name of the method of the test case to add to the
293  *                   suite. The signature of the method must be of
294  *                   type: void testMethod();
295  * \see  CPPUNIT_TEST_SUITE.
296  */
297 #define CPPUNIT_TEST( testMethod )                        \
298     CPPUNIT_TEST_SUITE_ADD_TEST(                           \
299         ( new CPPUNIT_NS::TestCaller<TestFixtureType>(    \
300                   context.getTestNameFor( #testMethod),   \
301                   &TestFixtureType::testMethod,           \
302                   context.makeFixture() ) ) )
303 
304 #define CPPUNIT_TEST_PARAMETERIZED( testMethod, ... )    \
305     for (auto& i : __VA_ARGS__)                                  \
306     {                                                           \
307         TestFixtureType* fixture = context.makeFixture();       \
308         CPPUNIT_TEST_SUITE_ADD_TEST(                            \
309         ( new CPPUNIT_NS::TestCaller<TestFixtureType>(          \
310                     context.getTestNameFor(#testMethod, i),     \
311                     std::bind(&TestFixtureType::testMethod, fixture, i),          \
312                     fixture)));                                  \
313     }
314 
315 /*! \brief Add a test which fail if the specified exception is not caught.
316  *
317  * Example:
318  * \code
319  * #include <cppunit/extensions/HelperMacros.h>
320  * #include <vector>
321  * class MyTest : public CppUnit::TestFixture {
322  *   CPPUNIT_TEST_SUITE( MyTest );
323  *   CPPUNIT_TEST_EXCEPTION( testVectorAtThrow, std::out_of_range );
324  *   CPPUNIT_TEST_SUITE_END();
325  * public:
326  *   void testVectorAtThrow()
327  *   {
328  *     std::vector<int> v;
329  *     v.at( 1 );     // must throw exception std::out_of_range
330  *   }
331  * };
332  * \endcode
333  *
334  * \param testMethod Name of the method of the test case to add to the suite.
335  * \param ExceptionType Type of the exception that must be thrown by the test
336  *                      method.
337  * \deprecated Use the assertion macro CPPUNIT_ASSERT_THROW instead.
338  */
339 #define CPPUNIT_TEST_EXCEPTION( testMethod, ExceptionType )          \
340   CPPUNIT_TEST_SUITE_ADD_TEST(                                        \
341       (new CPPUNIT_NS::ExceptionTestCaseDecorator< ExceptionType >(  \
342           new CPPUNIT_NS::TestCaller< TestFixtureType >(             \
343                                context.getTestNameFor( #testMethod ),  \
344                                &TestFixtureType::testMethod,         \
345                                context.makeFixture() ) ) ) )
346 
347 /*! \brief Adds a test case which is excepted to fail.
348  *
349  * The added test case expect an assertion to fail. You usually used that type
350  * of test case when testing custom assertion macros.
351  *
352  * \code
353  * CPPUNIT_TEST_FAIL( testAssertFalseFail );
354  *
355  * void testAssertFalseFail()
356  * {
357  *   CPPUNIT_ASSERT( false );
358  * }
359  * \endcode
360  * \see CreatingNewAssertions.
361  * \deprecated Use the assertion macro CPPUNIT_ASSERT_ASSERTION_FAIL instead.
362  */
363 #define CPPUNIT_TEST_FAIL( testMethod ) \
364               CPPUNIT_TEST_EXCEPTION( testMethod, CPPUNIT_NS::Exception )
365 
366 /*! \brief Adds some custom test cases.
367  *
368  * Use this to add one or more test cases to the fixture suite. The specified
369  * method is called with a context parameter that can be used to name,
370  * instantiate fixture, and add instantiated test case to the fixture suite.
371  * The specified method must have the following signature:
372  * \code
373  * static void aMethodName( TestSuiteBuilderContextType &context );
374  * \endcode
375  *
376  * \c TestSuiteBuilderContextType is typedef to
377  * TestSuiteBuilderContext<TestFixtureType> declared by CPPUNIT_TEST_SUITE().
378  *
379  * Here is an example that add two custom tests:
380  *
381  * \code
382  * #include <cppunit/extensions/HelperMacros.h>
383  *
384  * class MyTest : public CppUnit::TestFixture {
385  *   CPPUNIT_TEST_SUITE( MyTest );
386  *   CPPUNIT_TEST_SUITE_ADD_CUSTOM_TESTS( addTimeOutTests );
387  *   CPPUNIT_TEST_SUITE_END();
388  * public:
389  *   static void addTimeOutTests( TestSuiteBuilderContextType &context )
390  *   {
391  *     context.addTest( new TimeOutTestCaller( context.getTestNameFor( "test1" ) ),
392  *                                             &MyTest::test1,
393  *                                             context.makeFixture(),
394  *                                             5.0 );
395  *     context.addTest( new TimeOutTestCaller( context.getTestNameFor( "test2" ) ),
396  *                                             &MyTest::test2,
397  *                                             context.makeFixture(),
398  *                                             5.0 );
399  *   }
400  *
401  *   void test1()
402  *   {
403  *     // Do some test that may never end...
404  *   }
405  *
406  *   void test2()
407  *   {
408  *     // Do some test that may never end...
409  *   }
410  * };
411  * \endcode
412  * @param testAdderMethod Name of the method called to add the test cases.
413  */
414 #define CPPUNIT_TEST_SUITE_ADD_CUSTOM_TESTS( testAdderMethod ) \
415       testAdderMethod( context )
416 
417 /*! \brief Adds a property to the test suite builder context.
418  * \param APropertyKey   Key of the property to add.
419  * \param APropertyValue Value for the added property.
420  * Example:
421  * \code
422  * CPPUNIT_TEST_SUITE_PROPERTY("XmlFileName", "paraTest.xml"); \endcode
423  */
424 #define CPPUNIT_TEST_SUITE_PROPERTY( APropertyKey, APropertyValue ) \
425     context.addProperty( std::string(APropertyKey),                 \
426                          std::string(APropertyValue) )
427 
428 /** @}
429  */
430 
431 
432 /*! Adds the specified fixture suite to the unnamed registry.
433  * \ingroup CreatingTestSuite
434  *
435  * This macro declares a static variable whose construction
436  * causes a test suite factory to be inserted in a global registry
437  * of such factories.  The registry is available by calling
438  * the static function CppUnit::TestFactoryRegistry::getRegistry().
439  *
440  * \param ATestFixtureType Type of the test case class.
441  * \warning This macro should be used only once per line of code (the line
442  *          number is used to name a hidden static variable).
443  * \see CPPUNIT_TEST_SUITE_NAMED_REGISTRATION
444  * \see CPPUNIT_REGISTRY_ADD_TO_DEFAULT
445  * \see CPPUNIT_REGISTRY_ADD
446  * \see CPPUNIT_TEST_SUITE, CppUnit::AutoRegisterSuite,
447  *      CppUnit::TestFactoryRegistry.
448  */
449 #define CPPUNIT_TEST_SUITE_REGISTRATION( ATestFixtureType )      \
450   static CPPUNIT_NS::AutoRegisterSuite< ATestFixtureType >       \
451              CPPUNIT_MAKE_UNIQUE_NAME(autoRegisterRegistry__ )
452 
453 
454 /** Adds the specified fixture suite to the specified registry suite.
455  * \ingroup CreatingTestSuite
456  *
457  * This macro declares a static variable whose construction
458  * causes a test suite factory to be inserted in the global registry
459  * suite of the specified name. The registry is available by calling
460  * the static function CppUnit::TestFactoryRegistry::getRegistry().
461  *
462  * For the suite name, use a string returned by a static function rather
463  * than a hardcoded string. That way, you can know what are the name of
464  * named registry and you don't risk mistyping the registry name.
465  *
466  * \code
467  * // MySuites.h
468  * namespace MySuites {
469  *   std::string math() {
470  *     return "Math";
471  *   }
472  * }
473  *
474  * // ComplexNumberTest.cpp
475  * #include "MySuites.h"
476  *
477  * CPPUNIT_TEST_SUITE_NAMED_REGISTRATION( ComplexNumberTest, MySuites::math() );
478  * \endcode
479  *
480  * \param ATestFixtureType Type of the test case class.
481  * \param suiteName Name of the global registry suite the test suite is
482  *                  registered into.
483  * \warning This macro should be used only once per line of code (the line
484  *          number is used to name a hidden static variable).
485  * \see CPPUNIT_TEST_SUITE_REGISTRATION
486  * \see CPPUNIT_REGISTRY_ADD_TO_DEFAULT
487  * \see CPPUNIT_REGISTRY_ADD
488  * \see CPPUNIT_TEST_SUITE, CppUnit::AutoRegisterSuite,
489  *      CppUnit::TestFactoryRegistry..
490  */
491 #define CPPUNIT_TEST_SUITE_NAMED_REGISTRATION( ATestFixtureType, suiteName ) \
492   static CPPUNIT_NS::AutoRegisterSuite< ATestFixtureType >                   \
493              CPPUNIT_MAKE_UNIQUE_NAME(autoRegisterRegistry__ )(suiteName)
494 
495 /*! Adds that the specified registry suite to another registry suite.
496  * \ingroup CreatingTestSuite
497  *
498  * Use this macros to automatically create test registry suite hierarchy. For example,
499  * if you want to create the following hierarchy:
500  * - Math
501  *   - IntegerMath
502  *   - FloatMath
503  *     - FastFloat
504  *     - StandardFloat
505  *
506  * You can do this automatically with:
507  * \code
508  * CPPUNIT_REGISTRY_ADD( "FastFloat", "FloatMath" );
509  * CPPUNIT_REGISTRY_ADD( "IntegerMath", "Math" );
510  * CPPUNIT_REGISTRY_ADD( "FloatMath", "Math" );
511  * CPPUNIT_REGISTRY_ADD( "StandardFloat", "FloatMath" );
512  * \endcode
513  *
514  * There is no specific order of declaration. Think of it as declaring links.
515  *
516  * You register the test in each suite using CPPUNIT_TEST_SUITE_NAMED_REGISTRATION.
517  *
518  * \param which Name of the registry suite to add to the registry suite named \a to.
519  * \param to Name of the registry suite \a which is added to.
520  * \see CPPUNIT_REGISTRY_ADD_TO_DEFAULT, CPPUNIT_TEST_SUITE_NAMED_REGISTRATION.
521  */
522 #define CPPUNIT_REGISTRY_ADD( which, to )                                     \
523   static CPPUNIT_NS::AutoRegisterRegistry                                     \
524              CPPUNIT_MAKE_UNIQUE_NAME( autoRegisterRegistry__ )( which, to )
525 
526 /*! Adds that the specified registry suite to the default registry suite.
527  * \ingroup CreatingTestSuite
528  *
529  * This macro is just like CPPUNIT_REGISTRY_ADD except the specified registry
530  * suite is added to the default suite (root suite).
531  *
532  * \param which Name of the registry suite to add to the default registry suite.
533  * \see CPPUNIT_REGISTRY_ADD.
534  */
535 #define CPPUNIT_REGISTRY_ADD_TO_DEFAULT( which )                         \
536   static CPPUNIT_NS::AutoRegisterRegistry                                \
537              CPPUNIT_MAKE_UNIQUE_NAME( autoRegisterRegistry__ )( which )
538 
539 // Backwards compatibility
540 // (Not tested!)
541 
542 #if CPPUNIT_ENABLE_CU_TEST_MACROS
543 
544 #define CU_TEST_SUITE(tc) CPPUNIT_TEST_SUITE(tc)
545 #define CU_TEST_SUB_SUITE(tc,sc) CPPUNIT_TEST_SUB_SUITE(tc,sc)
546 #define CU_TEST(tm) CPPUNIT_TEST(tm)
547 #define CU_TEST_SUITE_END() CPPUNIT_TEST_SUITE_END()
548 #define CU_TEST_SUITE_REGISTRATION(tc) CPPUNIT_TEST_SUITE_REGISTRATION(tc)
549 
550 #endif
551 
552 
553 #endif  // CPPUNIT_EXTENSIONS_HELPERMACROS_H
554