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 
  31 // GOOGLETEST_CM0001 DO NOT DELETE
  32 
  33 #ifndef GTEST_INCLUDE_GTEST_GTEST_TYPED_TEST_H_
  34 #define GTEST_INCLUDE_GTEST_GTEST_TYPED_TEST_H_
  35 
  36 // This header implements typed tests and type-parameterized tests.
  37 
  38 // Typed (aka type-driven) tests repeat the same test for types in a
  39 // list.  You must know which types you want to test with when writing
  40 // typed tests. Here's how you do it:
  41 
  42 #if 0
  43 
  44 // First, define a fixture class template.  It should be parameterized
  45 // by a type.  Remember to derive it from testing::Test.
  46 template <typename T>
  47 class FooTest : public testing::Test {
  48  public:
  49   ...
  50   typedef std::list<T> List;
  51   static T shared_;
  52   T value_;
  53 };
  54 
  55 // Next, associate a list of types with the test case, which will be
  56 // repeated for each type in the list.  The typedef is necessary for
  57 // the macro to parse correctly.
  58 typedef testing::Types<char, int, unsigned int> MyTypes;
  59 TYPED_TEST_CASE(FooTest, MyTypes);
  60 
  61 // If the type list contains only one type, you can write that type
  62 // directly without Types<...>:
  63 //   TYPED_TEST_CASE(FooTest, int);
  64 
  65 // Then, use TYPED_TEST() instead of TEST_F() to define as many typed
  66 // tests for this test case as you want.
  67 TYPED_TEST(FooTest, DoesBlah) {
  68   // Inside a test, refer to TypeParam to get the type parameter.
  69   // Since we are inside a derived class template, C++ requires use to
  70   // visit the members of FooTest via 'this'.
  71   TypeParam n = this->value_;
  72 
  73   // To visit static members of the fixture, add the TestFixture::
  74   // prefix.
  75   n += TestFixture::shared_;
  76 
  77   // To refer to typedefs in the fixture, add the "typename
  78   // TestFixture::" prefix.
  79   typename TestFixture::List values;
  80   values.push_back(n);
  81   ...
  82 }
  83 
  84 TYPED_TEST(FooTest, HasPropertyA) { ... }
  85 
  86 // TYPED_TEST_CASE takes an optional third argument which allows to specify a
  87 // class that generates custom test name suffixes based on the type. This should
  88 // be a class which has a static template function GetName(int index) returning
  89 // a string for each type. The provided integer index equals the index of the
  90 // type in the provided type list. In many cases the index can be ignored.
  91 //
  92 // For example:
  93 //   class MyTypeNames {
  94 //    public:
  95 //     template <typename T>
  96 //     static std::string GetName(int) {
  97 //       if (std::is_same<T, char>()) return "char";
  98 //       if (std::is_same<T, int>()) return "int";
  99 //       if (std::is_same<T, unsigned int>()) return "unsignedInt";
 100 //     }
 101 //   };
 102 //   TYPED_TEST_CASE(FooTest, MyTypes, MyTypeNames);
 103 
 104 #endif  // 0
 105 
 106 // Type-parameterized tests are abstract test patterns parameterized
 107 // by a type.  Compared with typed tests, type-parameterized tests
 108 // allow you to define the test pattern without knowing what the type
 109 // parameters are.  The defined pattern can be instantiated with
 110 // different types any number of times, in any number of translation
 111 // units.
 112 //
 113 // If you are designing an interface or concept, you can define a
 114 // suite of type-parameterized tests to verify properties that any
 115 // valid implementation of the interface/concept should have.  Then,
 116 // each implementation can easily instantiate the test suite to verify
 117 // that it conforms to the requirements, without having to write
 118 // similar tests repeatedly.  Here's an example:
 119 
 120 #if 0
 121 
 122 // First, define a fixture class template.  It should be parameterized
 123 // by a type.  Remember to derive it from testing::Test.
 124 template <typename T>
 125 class FooTest : public testing::Test {
 126   ...
 127 };
 128 
 129 // Next, declare that you will define a type-parameterized test case
 130 // (the _P suffix is for "parameterized" or "pattern", whichever you
 131 // prefer):
 132 TYPED_TEST_CASE_P(FooTest);
 133 
 134 // Then, use TYPED_TEST_P() to define as many type-parameterized tests
 135 // for this type-parameterized test case as you want.
 136 TYPED_TEST_P(FooTest, DoesBlah) {
 137   // Inside a test, refer to TypeParam to get the type parameter.
 138   TypeParam n = 0;
 139   ...
 140 }
 141 
 142 TYPED_TEST_P(FooTest, HasPropertyA) { ... }
 143 
 144 // Now the tricky part: you need to register all test patterns before
 145 // you can instantiate them.  The first argument of the macro is the
 146 // test case name; the rest are the names of the tests in this test
 147 // case.
 148 REGISTER_TYPED_TEST_CASE_P(FooTest,
 149                            DoesBlah, HasPropertyA);
 150 
 151 // Finally, you are free to instantiate the pattern with the types you
 152 // want.  If you put the above code in a header file, you can #include
 153 // it in multiple C++ source files and instantiate it multiple times.
 154 //
 155 // To distinguish different instances of the pattern, the first
 156 // argument to the INSTANTIATE_* macro is a prefix that will be added
 157 // to the actual test case name.  Remember to pick unique prefixes for
 158 // different instances.
 159 typedef testing::Types<char, int, unsigned int> MyTypes;
 160 INSTANTIATE_TYPED_TEST_CASE_P(My, FooTest, MyTypes);
 161 
 162 // If the type list contains only one type, you can write that type
 163 // directly without Types<...>:
 164 //   INSTANTIATE_TYPED_TEST_CASE_P(My, FooTest, int);
 165 //
 166 // Similar to the optional argument of TYPED_TEST_CASE above,
 167 // INSTANTIATE_TEST_CASE_P takes an optional fourth argument which allows to
 168 // generate custom names.
 169 //   INSTANTIATE_TYPED_TEST_CASE_P(My, FooTest, MyTypes, MyTypeNames);
 170 
 171 #endif  // 0
 172 
 173 #include "gtest/internal/gtest-port.h"
 174 #include "gtest/internal/gtest-type-util.h"
 175 
 176 // Implements typed tests.
 177 
 178 #if GTEST_HAS_TYPED_TEST
 179 
 180 // INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
 181 //
 182 // Expands to the name of the typedef for the type parameters of the
 183 // given test case.
 184 # define GTEST_TYPE_PARAMS_(TestCaseName) gtest_type_params_##TestCaseName##_
 185 
 186 // Expands to the name of the typedef for the NameGenerator, responsible for
 187 // creating the suffixes of the name.
 188 #define GTEST_NAME_GENERATOR_(TestCaseName) \
 189   gtest_type_params_##TestCaseName##_NameGenerator
 190 
 191 // The 'Types' template argument below must have spaces around it
 192 // since some compilers may choke on '>>' when passing a template
 193 // instance (e.g. Types<int>)
 194 # define TYPED_TEST_CASE(CaseName, Types, ...)                             \
 195   typedef ::testing::internal::TypeList< Types >::type GTEST_TYPE_PARAMS_( \
 196       CaseName);                                                           \
 197   typedef ::testing::internal::NameGeneratorSelector<__VA_ARGS__>::type    \
 198       GTEST_NAME_GENERATOR_(CaseName)
 199 
 200 # define TYPED_TEST(CaseName, TestName)                                       \
 201   template <typename gtest_TypeParam_>                                        \
 202   class GTEST_TEST_CLASS_NAME_(CaseName, TestName)                            \
 203       : public CaseName<gtest_TypeParam_> {                                   \
 204    private:                                                                   \
 205     typedef CaseName<gtest_TypeParam_> TestFixture;                           \
 206     typedef gtest_TypeParam_ TypeParam;                                       \
 207     virtual void TestBody();                                                  \
 208   };                                                                          \
 209   static bool gtest_##CaseName##_##TestName##_registered_                     \
 210         GTEST_ATTRIBUTE_UNUSED_ =                                             \
 211       ::testing::internal::TypeParameterizedTest<                             \
 212           CaseName,                                                           \
 213           ::testing::internal::TemplateSel<GTEST_TEST_CLASS_NAME_(CaseName,   \
 214                                                                   TestName)>, \
 215           GTEST_TYPE_PARAMS_(                                                 \
 216               CaseName)>::Register("",                                        \
 217                                    ::testing::internal::CodeLocation(         \
 218                                        __FILE__, __LINE__),                   \
 219                                    #CaseName, #TestName, 0,                   \
 220                                    ::testing::internal::GenerateNames<        \
 221                                        GTEST_NAME_GENERATOR_(CaseName),       \
 222                                        GTEST_TYPE_PARAMS_(CaseName)>());      \
 223   template <typename gtest_TypeParam_>                                        \
 224   void GTEST_TEST_CLASS_NAME_(CaseName,                                       \
 225                               TestName)<gtest_TypeParam_>::TestBody()
 226 
 227 #endif  // GTEST_HAS_TYPED_TEST
 228 
 229 // Implements type-parameterized tests.
 230 
 231 #if GTEST_HAS_TYPED_TEST_P
 232 
 233 // INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
 234 //
 235 // Expands to the namespace name that the type-parameterized tests for
 236 // the given type-parameterized test case are defined in.  The exact
 237 // name of the namespace is subject to change without notice.
 238 # define GTEST_CASE_NAMESPACE_(TestCaseName) \
 239   gtest_case_##TestCaseName##_
 240 
 241 // INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
 242 //
 243 // Expands to the name of the variable used to remember the names of
 244 // the defined tests in the given test case.
 245 # define GTEST_TYPED_TEST_CASE_P_STATE_(TestCaseName) \
 246   gtest_typed_test_case_p_state_##TestCaseName##_
 247 
 248 // INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE DIRECTLY.
 249 //
 250 // Expands to the name of the variable used to remember the names of
 251 // the registered tests in the given test case.
 252 # define GTEST_REGISTERED_TEST_NAMES_(TestCaseName) \
 253   gtest_registered_test_names_##TestCaseName##_
 254 
 255 // The variables defined in the type-parameterized test macros are
 256 // static as typically these macros are used in a .h file that can be
 257 // #included in multiple translation units linked together.
 258 # define TYPED_TEST_CASE_P(CaseName) \
 259   static ::testing::internal::TypedTestCasePState \
 260       GTEST_TYPED_TEST_CASE_P_STATE_(CaseName)
 261 
 262 # define TYPED_TEST_P(CaseName, TestName) \
 263   namespace GTEST_CASE_NAMESPACE_(CaseName) { \
 264   template <typename gtest_TypeParam_> \
 265   class TestName : public CaseName<gtest_TypeParam_> { \
 266    private: \
 267     typedef CaseName<gtest_TypeParam_> TestFixture; \
 268     typedef gtest_TypeParam_ TypeParam; \
 269     virtual void TestBody(); \
 270   }; \
 271   static bool gtest_##TestName##_defined_ GTEST_ATTRIBUTE_UNUSED_ = \
 272       GTEST_TYPED_TEST_CASE_P_STATE_(CaseName).AddTestName(\
 273           __FILE__, __LINE__, #CaseName, #TestName); \
 274   } \
 275   template <typename gtest_TypeParam_> \
 276   void GTEST_CASE_NAMESPACE_(CaseName)::TestName<gtest_TypeParam_>::TestBody()
 277 
 278 # define REGISTER_TYPED_TEST_CASE_P(CaseName, ...) \
 279   namespace GTEST_CASE_NAMESPACE_(CaseName) { \
 280   typedef ::testing::internal::Templates<__VA_ARGS__>::type gtest_AllTests_; \
 281   } \
 282   static const char* const GTEST_REGISTERED_TEST_NAMES_(CaseName) \
 283       GTEST_ATTRIBUTE_UNUSED_ = \
 284           GTEST_TYPED_TEST_CASE_P_STATE_(CaseName).VerifyRegisteredTestNames( \
 285               __FILE__, __LINE__, #__VA_ARGS__)
 286 
 287 // The 'Types' template argument below must have spaces around it
 288 // since some compilers may choke on '>>' when passing a template
 289 // instance (e.g. Types<int>)
 290 # define INSTANTIATE_TYPED_TEST_CASE_P(Prefix, CaseName, Types, ...)      \
 291   static bool gtest_##Prefix##_##CaseName GTEST_ATTRIBUTE_UNUSED_ =       \
 292       ::testing::internal::TypeParameterizedTestCase<                     \
 293           CaseName, GTEST_CASE_NAMESPACE_(CaseName)::gtest_AllTests_,     \
 294           ::testing::internal::TypeList< Types >::type>::                 \
 295           Register(#Prefix,                                               \
 296                    ::testing::internal::CodeLocation(__FILE__, __LINE__), \
 297                    &GTEST_TYPED_TEST_CASE_P_STATE_(CaseName), #CaseName,  \
 298                    GTEST_REGISTERED_TEST_NAMES_(CaseName),                \
 299                    ::testing::internal::GenerateNames<                    \
 300                        ::testing::internal::NameGeneratorSelector<        \
 301                            __VA_ARGS__>::type,                            \
 302                        ::testing::internal::TypeList< Types >::type>())
 303 
 304 #endif  // GTEST_HAS_TYPED_TEST_P
 305 
 306 #endif  // GTEST_INCLUDE_GTEST_GTEST_TYPED_TEST_H_