]>
Commit | Line | Data |
---|---|---|
31f18b77 FG |
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@google.com (Zhanyong Wan) | |
31 | ||
1e59de90 | 32 | #include "gtest-typed-test_test.h" |
31f18b77 FG |
33 | |
34 | #include <set> | |
35 | #include <vector> | |
36 | ||
37 | #include "gtest/gtest.h" | |
38 | ||
39 | using testing::Test; | |
40 | ||
41 | // Used for testing that SetUpTestCase()/TearDownTestCase(), fixture | |
42 | // ctor/dtor, and SetUp()/TearDown() work correctly in typed tests and | |
43 | // type-parameterized test. | |
44 | template <typename T> | |
45 | class CommonTest : public Test { | |
46 | // For some technical reason, SetUpTestCase() and TearDownTestCase() | |
47 | // must be public. | |
48 | public: | |
49 | static void SetUpTestCase() { | |
50 | shared_ = new T(5); | |
51 | } | |
52 | ||
53 | static void TearDownTestCase() { | |
54 | delete shared_; | |
55 | shared_ = NULL; | |
56 | } | |
57 | ||
58 | // This 'protected:' is optional. There's no harm in making all | |
59 | // members of this fixture class template public. | |
60 | protected: | |
61 | // We used to use std::list here, but switched to std::vector since | |
62 | // MSVC's <list> doesn't compile cleanly with /W4. | |
63 | typedef std::vector<T> Vector; | |
64 | typedef std::set<int> IntSet; | |
65 | ||
66 | CommonTest() : value_(1) {} | |
67 | ||
68 | virtual ~CommonTest() { EXPECT_EQ(3, value_); } | |
69 | ||
70 | virtual void SetUp() { | |
71 | EXPECT_EQ(1, value_); | |
72 | value_++; | |
73 | } | |
74 | ||
75 | virtual void TearDown() { | |
76 | EXPECT_EQ(2, value_); | |
77 | value_++; | |
78 | } | |
79 | ||
80 | T value_; | |
81 | static T* shared_; | |
82 | }; | |
83 | ||
84 | template <typename T> | |
85 | T* CommonTest<T>::shared_ = NULL; | |
86 | ||
87 | // This #ifdef block tests typed tests. | |
88 | #if GTEST_HAS_TYPED_TEST | |
89 | ||
90 | using testing::Types; | |
91 | ||
92 | // Tests that SetUpTestCase()/TearDownTestCase(), fixture ctor/dtor, | |
93 | // and SetUp()/TearDown() work correctly in typed tests | |
94 | ||
95 | typedef Types<char, int> TwoTypes; | |
96 | TYPED_TEST_CASE(CommonTest, TwoTypes); | |
97 | ||
98 | TYPED_TEST(CommonTest, ValuesAreCorrect) { | |
99 | // Static members of the fixture class template can be visited via | |
100 | // the TestFixture:: prefix. | |
101 | EXPECT_EQ(5, *TestFixture::shared_); | |
102 | ||
103 | // Typedefs in the fixture class template can be visited via the | |
104 | // "typename TestFixture::" prefix. | |
105 | typename TestFixture::Vector empty; | |
106 | EXPECT_EQ(0U, empty.size()); | |
107 | ||
108 | typename TestFixture::IntSet empty2; | |
109 | EXPECT_EQ(0U, empty2.size()); | |
110 | ||
111 | // Non-static members of the fixture class must be visited via | |
112 | // 'this', as required by C++ for class templates. | |
113 | EXPECT_EQ(2, this->value_); | |
114 | } | |
115 | ||
116 | // The second test makes sure shared_ is not deleted after the first | |
117 | // test. | |
118 | TYPED_TEST(CommonTest, ValuesAreStillCorrect) { | |
119 | // Static members of the fixture class template can also be visited | |
120 | // via 'this'. | |
121 | ASSERT_TRUE(this->shared_ != NULL); | |
122 | EXPECT_EQ(5, *this->shared_); | |
123 | ||
124 | // TypeParam can be used to refer to the type parameter. | |
125 | EXPECT_EQ(static_cast<TypeParam>(2), this->value_); | |
126 | } | |
127 | ||
128 | // Tests that multiple TYPED_TEST_CASE's can be defined in the same | |
129 | // translation unit. | |
130 | ||
131 | template <typename T> | |
132 | class TypedTest1 : public Test { | |
133 | }; | |
134 | ||
135 | // Verifies that the second argument of TYPED_TEST_CASE can be a | |
136 | // single type. | |
137 | TYPED_TEST_CASE(TypedTest1, int); | |
138 | TYPED_TEST(TypedTest1, A) {} | |
139 | ||
140 | template <typename T> | |
141 | class TypedTest2 : public Test { | |
142 | }; | |
143 | ||
144 | // Verifies that the second argument of TYPED_TEST_CASE can be a | |
145 | // Types<...> type list. | |
146 | TYPED_TEST_CASE(TypedTest2, Types<int>); | |
147 | ||
148 | // This also verifies that tests from different typed test cases can | |
149 | // share the same name. | |
150 | TYPED_TEST(TypedTest2, A) {} | |
151 | ||
152 | // Tests that a typed test case can be defined in a namespace. | |
153 | ||
154 | namespace library1 { | |
155 | ||
156 | template <typename T> | |
157 | class NumericTest : public Test { | |
158 | }; | |
159 | ||
160 | typedef Types<int, long> NumericTypes; | |
161 | TYPED_TEST_CASE(NumericTest, NumericTypes); | |
162 | ||
163 | TYPED_TEST(NumericTest, DefaultIsZero) { | |
164 | EXPECT_EQ(0, TypeParam()); | |
165 | } | |
166 | ||
167 | } // namespace library1 | |
168 | ||
169 | #endif // GTEST_HAS_TYPED_TEST | |
170 | ||
171 | // This #ifdef block tests type-parameterized tests. | |
172 | #if GTEST_HAS_TYPED_TEST_P | |
173 | ||
174 | using testing::Types; | |
175 | using testing::internal::TypedTestCasePState; | |
176 | ||
177 | // Tests TypedTestCasePState. | |
178 | ||
179 | class TypedTestCasePStateTest : public Test { | |
180 | protected: | |
181 | virtual void SetUp() { | |
182 | state_.AddTestName("foo.cc", 0, "FooTest", "A"); | |
183 | state_.AddTestName("foo.cc", 0, "FooTest", "B"); | |
184 | state_.AddTestName("foo.cc", 0, "FooTest", "C"); | |
185 | } | |
186 | ||
187 | TypedTestCasePState state_; | |
188 | }; | |
189 | ||
190 | TEST_F(TypedTestCasePStateTest, SucceedsForMatchingList) { | |
191 | const char* tests = "A, B, C"; | |
192 | EXPECT_EQ(tests, | |
193 | state_.VerifyRegisteredTestNames("foo.cc", 1, tests)); | |
194 | } | |
195 | ||
196 | // Makes sure that the order of the tests and spaces around the names | |
197 | // don't matter. | |
198 | TEST_F(TypedTestCasePStateTest, IgnoresOrderAndSpaces) { | |
199 | const char* tests = "A,C, B"; | |
200 | EXPECT_EQ(tests, | |
201 | state_.VerifyRegisteredTestNames("foo.cc", 1, tests)); | |
202 | } | |
203 | ||
204 | typedef TypedTestCasePStateTest TypedTestCasePStateDeathTest; | |
205 | ||
206 | TEST_F(TypedTestCasePStateDeathTest, DetectsDuplicates) { | |
207 | EXPECT_DEATH_IF_SUPPORTED( | |
208 | state_.VerifyRegisteredTestNames("foo.cc", 1, "A, B, A, C"), | |
209 | "foo\\.cc.1.?: Test A is listed more than once\\."); | |
210 | } | |
211 | ||
212 | TEST_F(TypedTestCasePStateDeathTest, DetectsExtraTest) { | |
213 | EXPECT_DEATH_IF_SUPPORTED( | |
214 | state_.VerifyRegisteredTestNames("foo.cc", 1, "A, B, C, D"), | |
215 | "foo\\.cc.1.?: No test named D can be found in this test case\\."); | |
216 | } | |
217 | ||
218 | TEST_F(TypedTestCasePStateDeathTest, DetectsMissedTest) { | |
219 | EXPECT_DEATH_IF_SUPPORTED( | |
220 | state_.VerifyRegisteredTestNames("foo.cc", 1, "A, C"), | |
221 | "foo\\.cc.1.?: You forgot to list test B\\."); | |
222 | } | |
223 | ||
224 | // Tests that defining a test for a parameterized test case generates | |
225 | // a run-time error if the test case has been registered. | |
226 | TEST_F(TypedTestCasePStateDeathTest, DetectsTestAfterRegistration) { | |
227 | state_.VerifyRegisteredTestNames("foo.cc", 1, "A, B, C"); | |
228 | EXPECT_DEATH_IF_SUPPORTED( | |
229 | state_.AddTestName("foo.cc", 2, "FooTest", "D"), | |
230 | "foo\\.cc.2.?: Test D must be defined before REGISTER_TYPED_TEST_CASE_P" | |
231 | "\\(FooTest, \\.\\.\\.\\)\\."); | |
232 | } | |
233 | ||
234 | // Tests that SetUpTestCase()/TearDownTestCase(), fixture ctor/dtor, | |
235 | // and SetUp()/TearDown() work correctly in type-parameterized tests. | |
236 | ||
237 | template <typename T> | |
238 | class DerivedTest : public CommonTest<T> { | |
239 | }; | |
240 | ||
241 | TYPED_TEST_CASE_P(DerivedTest); | |
242 | ||
243 | TYPED_TEST_P(DerivedTest, ValuesAreCorrect) { | |
244 | // Static members of the fixture class template can be visited via | |
245 | // the TestFixture:: prefix. | |
246 | EXPECT_EQ(5, *TestFixture::shared_); | |
247 | ||
248 | // Non-static members of the fixture class must be visited via | |
249 | // 'this', as required by C++ for class templates. | |
250 | EXPECT_EQ(2, this->value_); | |
251 | } | |
252 | ||
253 | // The second test makes sure shared_ is not deleted after the first | |
254 | // test. | |
255 | TYPED_TEST_P(DerivedTest, ValuesAreStillCorrect) { | |
256 | // Static members of the fixture class template can also be visited | |
257 | // via 'this'. | |
258 | ASSERT_TRUE(this->shared_ != NULL); | |
259 | EXPECT_EQ(5, *this->shared_); | |
260 | EXPECT_EQ(2, this->value_); | |
261 | } | |
262 | ||
263 | REGISTER_TYPED_TEST_CASE_P(DerivedTest, | |
264 | ValuesAreCorrect, ValuesAreStillCorrect); | |
265 | ||
266 | typedef Types<short, long> MyTwoTypes; | |
267 | INSTANTIATE_TYPED_TEST_CASE_P(My, DerivedTest, MyTwoTypes); | |
268 | ||
269 | // Tests that multiple TYPED_TEST_CASE_P's can be defined in the same | |
270 | // translation unit. | |
271 | ||
272 | template <typename T> | |
273 | class TypedTestP1 : public Test { | |
274 | }; | |
275 | ||
276 | TYPED_TEST_CASE_P(TypedTestP1); | |
277 | ||
278 | // For testing that the code between TYPED_TEST_CASE_P() and | |
279 | // TYPED_TEST_P() is not enclosed in a namespace. | |
280 | typedef int IntAfterTypedTestCaseP; | |
281 | ||
282 | TYPED_TEST_P(TypedTestP1, A) {} | |
283 | TYPED_TEST_P(TypedTestP1, B) {} | |
284 | ||
285 | // For testing that the code between TYPED_TEST_P() and | |
286 | // REGISTER_TYPED_TEST_CASE_P() is not enclosed in a namespace. | |
287 | typedef int IntBeforeRegisterTypedTestCaseP; | |
288 | ||
289 | REGISTER_TYPED_TEST_CASE_P(TypedTestP1, A, B); | |
290 | ||
291 | template <typename T> | |
292 | class TypedTestP2 : public Test { | |
293 | }; | |
294 | ||
295 | TYPED_TEST_CASE_P(TypedTestP2); | |
296 | ||
297 | // This also verifies that tests from different type-parameterized | |
298 | // test cases can share the same name. | |
299 | TYPED_TEST_P(TypedTestP2, A) {} | |
300 | ||
301 | REGISTER_TYPED_TEST_CASE_P(TypedTestP2, A); | |
302 | ||
303 | // Verifies that the code between TYPED_TEST_CASE_P() and | |
304 | // REGISTER_TYPED_TEST_CASE_P() is not enclosed in a namespace. | |
305 | IntAfterTypedTestCaseP after = 0; | |
306 | IntBeforeRegisterTypedTestCaseP before = 0; | |
307 | ||
308 | // Verifies that the last argument of INSTANTIATE_TYPED_TEST_CASE_P() | |
309 | // can be either a single type or a Types<...> type list. | |
310 | INSTANTIATE_TYPED_TEST_CASE_P(Int, TypedTestP1, int); | |
311 | INSTANTIATE_TYPED_TEST_CASE_P(Int, TypedTestP2, Types<int>); | |
312 | ||
313 | // Tests that the same type-parameterized test case can be | |
314 | // instantiated more than once in the same translation unit. | |
315 | INSTANTIATE_TYPED_TEST_CASE_P(Double, TypedTestP2, Types<double>); | |
316 | ||
317 | // Tests that the same type-parameterized test case can be | |
318 | // instantiated in different translation units linked together. | |
319 | // (ContainerTest is also instantiated in gtest-typed-test_test.cc.) | |
320 | typedef Types<std::vector<double>, std::set<char> > MyContainers; | |
321 | INSTANTIATE_TYPED_TEST_CASE_P(My, ContainerTest, MyContainers); | |
322 | ||
323 | // Tests that a type-parameterized test case can be defined and | |
324 | // instantiated in a namespace. | |
325 | ||
326 | namespace library2 { | |
327 | ||
328 | template <typename T> | |
329 | class NumericTest : public Test { | |
330 | }; | |
331 | ||
332 | TYPED_TEST_CASE_P(NumericTest); | |
333 | ||
334 | TYPED_TEST_P(NumericTest, DefaultIsZero) { | |
335 | EXPECT_EQ(0, TypeParam()); | |
336 | } | |
337 | ||
338 | TYPED_TEST_P(NumericTest, ZeroIsLessThanOne) { | |
339 | EXPECT_LT(TypeParam(0), TypeParam(1)); | |
340 | } | |
341 | ||
342 | REGISTER_TYPED_TEST_CASE_P(NumericTest, | |
343 | DefaultIsZero, ZeroIsLessThanOne); | |
344 | typedef Types<int, double> NumericTypes; | |
345 | INSTANTIATE_TYPED_TEST_CASE_P(My, NumericTest, NumericTypes); | |
346 | ||
347 | static const char* GetTestName() { | |
348 | return testing::UnitTest::GetInstance()->current_test_info()->name(); | |
349 | } | |
350 | // Test the stripping of space from test names | |
351 | template <typename T> class TrimmedTest : public Test { }; | |
352 | TYPED_TEST_CASE_P(TrimmedTest); | |
353 | TYPED_TEST_P(TrimmedTest, Test1) { EXPECT_STREQ("Test1", GetTestName()); } | |
354 | TYPED_TEST_P(TrimmedTest, Test2) { EXPECT_STREQ("Test2", GetTestName()); } | |
355 | TYPED_TEST_P(TrimmedTest, Test3) { EXPECT_STREQ("Test3", GetTestName()); } | |
356 | TYPED_TEST_P(TrimmedTest, Test4) { EXPECT_STREQ("Test4", GetTestName()); } | |
357 | TYPED_TEST_P(TrimmedTest, Test5) { EXPECT_STREQ("Test5", GetTestName()); } | |
358 | REGISTER_TYPED_TEST_CASE_P( | |
359 | TrimmedTest, | |
360 | Test1, Test2,Test3 , Test4 ,Test5 ); // NOLINT | |
361 | template <typename T1, typename T2> struct MyPair {}; | |
362 | // Be sure to try a type with a comma in its name just in case it matters. | |
363 | typedef Types<int, double, MyPair<int, int> > TrimTypes; | |
364 | INSTANTIATE_TYPED_TEST_CASE_P(My, TrimmedTest, TrimTypes); | |
365 | ||
366 | } // namespace library2 | |
367 | ||
368 | #endif // GTEST_HAS_TYPED_TEST_P | |
369 | ||
370 | #if !defined(GTEST_HAS_TYPED_TEST) && !defined(GTEST_HAS_TYPED_TEST_P) | |
371 | ||
372 | // Google Test may not support type-parameterized tests with some | |
373 | // compilers. If we use conditional compilation to compile out all | |
374 | // code referring to the gtest_main library, MSVC linker will not link | |
375 | // that library at all and consequently complain about missing entry | |
376 | // point defined in that library (fatal error LNK1561: entry point | |
377 | // must be defined). This dummy test keeps gtest_main linked in. | |
378 | TEST(DummyTest, TypedTestsAreNotSupportedOnThisPlatform) {} | |
379 | ||
380 | #endif // #if !defined(GTEST_HAS_TYPED_TEST) && !defined(GTEST_HAS_TYPED_TEST_P) |