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