Home | History | Annotate | Download | only in gtest
      1 // Copyright 2008 Google Inc.
      2 // All Rights Reserved.
      3 //
      4 // Redistribution and use in source and binary forms, with or without
      5 // modification, are permitted provided that the following conditions are
      6 // met:
      7 //
      8 //     * Redistributions of source code must retain the above copyright
      9 // notice, this list of conditions and the following disclaimer.
     10 //     * Redistributions in binary form must reproduce the above
     11 // copyright notice, this list of conditions and the following disclaimer
     12 // in the documentation and/or other materials provided with the
     13 // distribution.
     14 //     * Neither the name of Google Inc. nor the names of its
     15 // contributors may be used to endorse or promote products derived from
     16 // this software without specific prior written permission.
     17 //
     18 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     19 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     20 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
     21 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
     22 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
     23 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
     24 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     25 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     26 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     27 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
     28 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     29 //
     30 // Author: wan (at) google.com (Zhanyong Wan)
     31 
     32 #ifndef GTEST_INCLUDE_GTEST_GTEST_TYPED_TEST_H_
     33 #define GTEST_INCLUDE_GTEST_GTEST_TYPED_TEST_H_
     34 
     35 // This header implements typed tests and type-parameterized tests.
     36 
     37 // Typed (aka type-driven) tests repeat the same test for types in a
     38 // list.  You must know which types you want to test with when writing
     39 // typed tests. Here's how you do it:
     40 
     41 #if 0
     42 
     43 // First, define a fixture class template.  It should be parameterized
     44 // by a type.  Remember to derive it from testing::Test.
     45 template <typename T>
     46 class FooTest : public testing::Test {
     47  public:
     48   ...
     49   typedef std::list<T> List;
     50   static T shared_;
     51   T value_;
     52 };
     53 
     54 // Next, associate a list of types with the test case, which will be
     55 // repeated for each type in the list.  The typedef is necessary for
     56 // the macro to parse correctly.
     57 typedef testing::Types<char, int, unsigned int> MyTypes;
     58 TYPED_TEST_CASE(FooTest, MyTypes);
     59 
     60 // If the type list contains only one type, you can write that type
     61 // directly without Types<...>:
     62 //   TYPED_TEST_CASE(FooTest, int);
     63 
     64 // Then, use TYPED_TEST() instead of TEST_F() to define as many typed
     65 // tests for this test case as you want.
     66 TYPED_TEST(FooTest, DoesBlah) {
     67   // Inside a test, refer to TypeParam to get the type parameter.
     68   // Since we are inside a derived class template, C++ requires use to
     69   // visit the members of FooTest via 'this'.
     70   TypeParam n = this->value_;
     71 
     72   // To visit static members of the fixture, add the TestFixture::
     73   // prefix.
     74   n += TestFixture::shared_;
     75 
     76   // To refer to typedefs in the fixture, add the "typename
     77   // TestFixture::" prefix.
     78   typename TestFixture::List values;
     79   values.push_back(n);
     80   ...
     81 }
     82 
     83 TYPED_TEST(FooTest, HasPropertyA) { ... }
     84 
     85 #endif  // 0
     86 
     87 // Type-parameterized tests are abstract test patterns parameterized
     88 // by a type.  Compared with typed tests, type-parameterized tests
     89 // allow you to define the test pattern without knowing what the type
     90 // parameters are.  The defined pattern can be instantiated with
     91 // different types any number of times, in any number of translation
     92 // units.
     93 //
     94 // If you are designing an interface or concept, you can define a
     95 // suite of type-parameterized tests to verify properties that any
     96 // valid implementation of the interface/concept should have.  Then,
     97 // each implementation can easily instantiate the test suite to verify
     98 // that it conforms to the requirements, without having to write
     99 // similar tests repeatedly.  Here's an example:
    100 
    101 #if 0
    102 
    103 // First, define a fixture class template.  It should be parameterized
    104 // by a type.  Remember to derive it from testing::Test.
    105 template <typename T>
    106 class FooTest : public testing::Test {
    107   ...
    108 };
    109 
    110 // Next, declare that you will define a type-parameterized test case
    111 // (the _P suffix is for "parameterized" or "pattern", whichever you
    112 // prefer):
    113 TYPED_TEST_CASE_P(FooTest);
    114 
    115 // Then, use TYPED_TEST_P() to define as many type-parameterized tests
    116 // for this type-parameterized test case as you want.
    117 TYPED_TEST_P(FooTest, DoesBlah) {
    118   // Inside a test, refer to TypeParam to get the type parameter.
    119   TypeParam n = 0;
    120   ...
    121 }
    122 
    123 TYPED_TEST_P(FooTest, HasPropertyA) { ... }
    124 
    125 // Now the tricky part: you need to register all test patterns before
    126 // you can instantiate them.  The first argument of the macro is the
    127 // test case name; the rest are the names of the tests in this test
    128 // case.
    129 REGISTER_TYPED_TEST_CASE_P(FooTest,
    130                            DoesBlah, HasPropertyA);
    131 
    132 // Finally, you are free to instantiate the pattern with the types you
    133 // want.  If you put the above code in a header file, you can #include
    134 // it in multiple C++ source files and instantiate it multiple times.
    135 //
    136 // To distinguish different instances of the pattern, the first
    137 // argument to the INSTANTIATE_* macro is a prefix that will be added
    138 // to the actual test case name.  Remember to pick unique prefixes for
    139 // different instances.
    140 typedef testing::Types<char, int, unsigned int> MyTypes;
    141 INSTANTIATE_TYPED_TEST_CASE_P(My, FooTest, MyTypes);
    142 
    143 // If the type list contains only one type, you can write that type
    144 // directly without Types<...>:
    145 //   INSTANTIATE_TYPED_TEST_CASE_P(My, FooTest, int);
    146 
    147 #endif  // 0
    148 
    149 #include "gtest/internal/gtest-port.h"
    150 #include "gtest/internal/gtest-type-util.h"
    151 
    152 // Implements typed tests.
    153 
    154 #if GTEST_HAS_TYPED_TEST
    155 
    156 // INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
    157 //
    158 // Expands to the name of the typedef for the type parameters of the
    159 // given test case.
    160 # define GTEST_TYPE_PARAMS_(TestCaseName) gtest_type_params_##TestCaseName##_
    161 
    162 // The 'Types' template argument below must have spaces around it
    163 // since some compilers may choke on '>>' when passing a template
    164 // instance (e.g. Types<int>)
    165 # define TYPED_TEST_CASE(CaseName, Types) \
    166   typedef ::testing::internal::TypeList< Types >::type \
    167       GTEST_TYPE_PARAMS_(CaseName)
    168 
    169 # define TYPED_TEST(CaseName, TestName) \
    170   template <typename gtest_TypeParam_> \
    171   class GTEST_TEST_CLASS_NAME_(CaseName, TestName) \
    172       : public CaseName<gtest_TypeParam_> { \
    173    private: \
    174     typedef CaseName<gtest_TypeParam_> TestFixture; \
    175     typedef gtest_TypeParam_ TypeParam; \
    176     virtual void TestBody(); \
    177   }; \
    178   bool gtest_##CaseName##_##TestName##_registered_ GTEST_ATTRIBUTE_UNUSED_ = \
    179       ::testing::internal::TypeParameterizedTest< \
    180           CaseName, \
    181           ::testing::internal::TemplateSel< \
    182               GTEST_TEST_CLASS_NAME_(CaseName, TestName)>, \
    183           GTEST_TYPE_PARAMS_(CaseName)>::Register(\
    184               "", #CaseName, #TestName, 0); \
    185   template <typename gtest_TypeParam_> \
    186   void GTEST_TEST_CLASS_NAME_(CaseName, TestName)<gtest_TypeParam_>::TestBody()
    187 
    188 #endif  // GTEST_HAS_TYPED_TEST
    189 
    190 // Implements type-parameterized tests.
    191 
    192 #if GTEST_HAS_TYPED_TEST_P
    193 
    194 // INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
    195 //
    196 // Expands to the namespace name that the type-parameterized tests for
    197 // the given type-parameterized test case are defined in.  The exact
    198 // name of the namespace is subject to change without notice.
    199 # define GTEST_CASE_NAMESPACE_(TestCaseName) \
    200   gtest_case_##TestCaseName##_
    201 
    202 // INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
    203 //
    204 // Expands to the name of the variable used to remember the names of
    205 // the defined tests in the given test case.
    206 # define GTEST_TYPED_TEST_CASE_P_STATE_(TestCaseName) \
    207   gtest_typed_test_case_p_state_##TestCaseName##_
    208 
    209 // INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE DIRECTLY.
    210 //
    211 // Expands to the name of the variable used to remember the names of
    212 // the registered tests in the given test case.
    213 # define GTEST_REGISTERED_TEST_NAMES_(TestCaseName) \
    214   gtest_registered_test_names_##TestCaseName##_
    215 
    216 // The variables defined in the type-parameterized test macros are
    217 // static as typically these macros are used in a .h file that can be
    218 // #included in multiple translation units linked together.
    219 # define TYPED_TEST_CASE_P(CaseName) \
    220   static ::testing::internal::TypedTestCasePState \
    221       GTEST_TYPED_TEST_CASE_P_STATE_(CaseName)
    222 
    223 # define TYPED_TEST_P(CaseName, TestName) \
    224   namespace GTEST_CASE_NAMESPACE_(CaseName) { \
    225   template <typename gtest_TypeParam_> \
    226   class TestName : public CaseName<gtest_TypeParam_> { \
    227    private: \
    228     typedef CaseName<gtest_TypeParam_> TestFixture; \
    229     typedef gtest_TypeParam_ TypeParam; \
    230     virtual void TestBody(); \
    231   }; \
    232   static bool gtest_##TestName##_defined_ GTEST_ATTRIBUTE_UNUSED_ = \
    233       GTEST_TYPED_TEST_CASE_P_STATE_(CaseName).AddTestName(\
    234           __FILE__, __LINE__, #CaseName, #TestName); \
    235   } \
    236   template <typename gtest_TypeParam_> \
    237   void GTEST_CASE_NAMESPACE_(CaseName)::TestName<gtest_TypeParam_>::TestBody()
    238 
    239 # define REGISTER_TYPED_TEST_CASE_P(CaseName, ...) \
    240   namespace GTEST_CASE_NAMESPACE_(CaseName) { \
    241   typedef ::testing::internal::Templates<__VA_ARGS__>::type gtest_AllTests_; \
    242   } \
    243   static const char* const GTEST_REGISTERED_TEST_NAMES_(CaseName) = \
    244       GTEST_TYPED_TEST_CASE_P_STATE_(CaseName).VerifyRegisteredTestNames(\
    245           __FILE__, __LINE__, #__VA_ARGS__)
    246 
    247 // The 'Types' template argument below must have spaces around it
    248 // since some compilers may choke on '>>' when passing a template
    249 // instance (e.g. Types<int>)
    250 # define INSTANTIATE_TYPED_TEST_CASE_P(Prefix, CaseName, Types) \
    251   bool gtest_##Prefix##_##CaseName GTEST_ATTRIBUTE_UNUSED_ = \
    252       ::testing::internal::TypeParameterizedTestCase<CaseName, \
    253           GTEST_CASE_NAMESPACE_(CaseName)::gtest_AllTests_, \
    254           ::testing::internal::TypeList< Types >::type>::Register(\
    255               #Prefix, #CaseName, GTEST_REGISTERED_TEST_NAMES_(CaseName))
    256 
    257 #endif  // GTEST_HAS_TYPED_TEST_P
    258 
    259 #endif  // GTEST_INCLUDE_GTEST_GTEST_TYPED_TEST_H_
    260