Mercurial > libbase64
comparison gtest/include/gtest/internal/gtest-param-util.h @ 13:a837dfb51eea
Switch to Boost.Test
author | David Demelier <markand@malikania.fr> |
---|---|
date | Mon, 27 Nov 2017 14:51:55 +0100 |
parents | f8a106ba04f8 |
children | 23cf89f2570a |
comparison
equal
deleted
inserted
replaced
12:f8a106ba04f8 | 13:a837dfb51eea |
---|---|
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: vladl@google.com (Vlad Losev) | |
31 | |
32 // Type and function utilities for implementing parameterized tests. | |
33 | |
34 #ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_H_ | |
35 #define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_H_ | |
36 | |
37 #include <iterator> | |
38 #include <utility> | |
39 #include <vector> | |
40 | |
41 // scripts/fuse_gtest.py depends on gtest's own header being #included | |
42 // *unconditionally*. Therefore these #includes cannot be moved | |
43 // inside #if GTEST_HAS_PARAM_TEST. | |
44 #include "gtest/internal/gtest-internal.h" | |
45 #include "gtest/internal/gtest-linked_ptr.h" | |
46 #include "gtest/internal/gtest-port.h" | |
47 #include "gtest/gtest-printers.h" | |
48 | |
49 #if GTEST_HAS_PARAM_TEST | |
50 | |
51 namespace testing { | |
52 namespace internal { | |
53 | |
54 // INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. | |
55 // | |
56 // Outputs a message explaining invalid registration of different | |
57 // fixture class for the same test case. This may happen when | |
58 // TEST_P macro is used to define two tests with the same name | |
59 // but in different namespaces. | |
60 GTEST_API_ void ReportInvalidTestCaseType(const char* test_case_name, | |
61 const char* file, int line); | |
62 | |
63 template <typename> class ParamGeneratorInterface; | |
64 template <typename> class ParamGenerator; | |
65 | |
66 // Interface for iterating over elements provided by an implementation | |
67 // of ParamGeneratorInterface<T>. | |
68 template <typename T> | |
69 class ParamIteratorInterface { | |
70 public: | |
71 virtual ~ParamIteratorInterface() {} | |
72 // A pointer to the base generator instance. | |
73 // Used only for the purposes of iterator comparison | |
74 // to make sure that two iterators belong to the same generator. | |
75 virtual const ParamGeneratorInterface<T>* BaseGenerator() const = 0; | |
76 // Advances iterator to point to the next element | |
77 // provided by the generator. The caller is responsible | |
78 // for not calling Advance() on an iterator equal to | |
79 // BaseGenerator()->End(). | |
80 virtual void Advance() = 0; | |
81 // Clones the iterator object. Used for implementing copy semantics | |
82 // of ParamIterator<T>. | |
83 virtual ParamIteratorInterface* Clone() const = 0; | |
84 // Dereferences the current iterator and provides (read-only) access | |
85 // to the pointed value. It is the caller's responsibility not to call | |
86 // Current() on an iterator equal to BaseGenerator()->End(). | |
87 // Used for implementing ParamGenerator<T>::operator*(). | |
88 virtual const T* Current() const = 0; | |
89 // Determines whether the given iterator and other point to the same | |
90 // element in the sequence generated by the generator. | |
91 // Used for implementing ParamGenerator<T>::operator==(). | |
92 virtual bool Equals(const ParamIteratorInterface& other) const = 0; | |
93 }; | |
94 | |
95 // Class iterating over elements provided by an implementation of | |
96 // ParamGeneratorInterface<T>. It wraps ParamIteratorInterface<T> | |
97 // and implements the const forward iterator concept. | |
98 template <typename T> | |
99 class ParamIterator { | |
100 public: | |
101 typedef T value_type; | |
102 typedef const T& reference; | |
103 typedef ptrdiff_t difference_type; | |
104 | |
105 // ParamIterator assumes ownership of the impl_ pointer. | |
106 ParamIterator(const ParamIterator& other) : impl_(other.impl_->Clone()) {} | |
107 ParamIterator& operator=(const ParamIterator& other) { | |
108 if (this != &other) | |
109 impl_.reset(other.impl_->Clone()); | |
110 return *this; | |
111 } | |
112 | |
113 const T& operator*() const { return *impl_->Current(); } | |
114 const T* operator->() const { return impl_->Current(); } | |
115 // Prefix version of operator++. | |
116 ParamIterator& operator++() { | |
117 impl_->Advance(); | |
118 return *this; | |
119 } | |
120 // Postfix version of operator++. | |
121 ParamIterator operator++(int /*unused*/) { | |
122 ParamIteratorInterface<T>* clone = impl_->Clone(); | |
123 impl_->Advance(); | |
124 return ParamIterator(clone); | |
125 } | |
126 bool operator==(const ParamIterator& other) const { | |
127 return impl_.get() == other.impl_.get() || impl_->Equals(*other.impl_); | |
128 } | |
129 bool operator!=(const ParamIterator& other) const { | |
130 return !(*this == other); | |
131 } | |
132 | |
133 private: | |
134 friend class ParamGenerator<T>; | |
135 explicit ParamIterator(ParamIteratorInterface<T>* impl) : impl_(impl) {} | |
136 scoped_ptr<ParamIteratorInterface<T> > impl_; | |
137 }; | |
138 | |
139 // ParamGeneratorInterface<T> is the binary interface to access generators | |
140 // defined in other translation units. | |
141 template <typename T> | |
142 class ParamGeneratorInterface { | |
143 public: | |
144 typedef T ParamType; | |
145 | |
146 virtual ~ParamGeneratorInterface() {} | |
147 | |
148 // Generator interface definition | |
149 virtual ParamIteratorInterface<T>* Begin() const = 0; | |
150 virtual ParamIteratorInterface<T>* End() const = 0; | |
151 }; | |
152 | |
153 // Wraps ParamGeneratorInterface<T> and provides general generator syntax | |
154 // compatible with the STL Container concept. | |
155 // This class implements copy initialization semantics and the contained | |
156 // ParamGeneratorInterface<T> instance is shared among all copies | |
157 // of the original object. This is possible because that instance is immutable. | |
158 template<typename T> | |
159 class ParamGenerator { | |
160 public: | |
161 typedef ParamIterator<T> iterator; | |
162 | |
163 explicit ParamGenerator(ParamGeneratorInterface<T>* impl) : impl_(impl) {} | |
164 ParamGenerator(const ParamGenerator& other) : impl_(other.impl_) {} | |
165 | |
166 ParamGenerator& operator=(const ParamGenerator& other) { | |
167 impl_ = other.impl_; | |
168 return *this; | |
169 } | |
170 | |
171 iterator begin() const { return iterator(impl_->Begin()); } | |
172 iterator end() const { return iterator(impl_->End()); } | |
173 | |
174 private: | |
175 linked_ptr<const ParamGeneratorInterface<T> > impl_; | |
176 }; | |
177 | |
178 // Generates values from a range of two comparable values. Can be used to | |
179 // generate sequences of user-defined types that implement operator+() and | |
180 // operator<(). | |
181 // This class is used in the Range() function. | |
182 template <typename T, typename IncrementT> | |
183 class RangeGenerator : public ParamGeneratorInterface<T> { | |
184 public: | |
185 RangeGenerator(T begin, T end, IncrementT step) | |
186 : begin_(begin), end_(end), | |
187 step_(step), end_index_(CalculateEndIndex(begin, end, step)) {} | |
188 virtual ~RangeGenerator() {} | |
189 | |
190 virtual ParamIteratorInterface<T>* Begin() const { | |
191 return new Iterator(this, begin_, 0, step_); | |
192 } | |
193 virtual ParamIteratorInterface<T>* End() const { | |
194 return new Iterator(this, end_, end_index_, step_); | |
195 } | |
196 | |
197 private: | |
198 class Iterator : public ParamIteratorInterface<T> { | |
199 public: | |
200 Iterator(const ParamGeneratorInterface<T>* base, T value, int index, | |
201 IncrementT step) | |
202 : base_(base), value_(value), index_(index), step_(step) {} | |
203 virtual ~Iterator() {} | |
204 | |
205 virtual const ParamGeneratorInterface<T>* BaseGenerator() const { | |
206 return base_; | |
207 } | |
208 virtual void Advance() { | |
209 value_ = value_ + step_; | |
210 index_++; | |
211 } | |
212 virtual ParamIteratorInterface<T>* Clone() const { | |
213 return new Iterator(*this); | |
214 } | |
215 virtual const T* Current() const { return &value_; } | |
216 virtual bool Equals(const ParamIteratorInterface<T>& other) const { | |
217 // Having the same base generator guarantees that the other | |
218 // iterator is of the same type and we can downcast. | |
219 GTEST_CHECK_(BaseGenerator() == other.BaseGenerator()) | |
220 << "The program attempted to compare iterators " | |
221 << "from different generators." << std::endl; | |
222 const int other_index = | |
223 CheckedDowncastToActualType<const Iterator>(&other)->index_; | |
224 return index_ == other_index; | |
225 } | |
226 | |
227 private: | |
228 Iterator(const Iterator& other) | |
229 : ParamIteratorInterface<T>(), | |
230 base_(other.base_), value_(other.value_), index_(other.index_), | |
231 step_(other.step_) {} | |
232 | |
233 // No implementation - assignment is unsupported. | |
234 void operator=(const Iterator& other); | |
235 | |
236 const ParamGeneratorInterface<T>* const base_; | |
237 T value_; | |
238 int index_; | |
239 const IncrementT step_; | |
240 }; // class RangeGenerator::Iterator | |
241 | |
242 static int CalculateEndIndex(const T& begin, | |
243 const T& end, | |
244 const IncrementT& step) { | |
245 int end_index = 0; | |
246 for (T i = begin; i < end; i = i + step) | |
247 end_index++; | |
248 return end_index; | |
249 } | |
250 | |
251 // No implementation - assignment is unsupported. | |
252 void operator=(const RangeGenerator& other); | |
253 | |
254 const T begin_; | |
255 const T end_; | |
256 const IncrementT step_; | |
257 // The index for the end() iterator. All the elements in the generated | |
258 // sequence are indexed (0-based) to aid iterator comparison. | |
259 const int end_index_; | |
260 }; // class RangeGenerator | |
261 | |
262 | |
263 // Generates values from a pair of STL-style iterators. Used in the | |
264 // ValuesIn() function. The elements are copied from the source range | |
265 // since the source can be located on the stack, and the generator | |
266 // is likely to persist beyond that stack frame. | |
267 template <typename T> | |
268 class ValuesInIteratorRangeGenerator : public ParamGeneratorInterface<T> { | |
269 public: | |
270 template <typename ForwardIterator> | |
271 ValuesInIteratorRangeGenerator(ForwardIterator begin, ForwardIterator end) | |
272 : container_(begin, end) {} | |
273 virtual ~ValuesInIteratorRangeGenerator() {} | |
274 | |
275 virtual ParamIteratorInterface<T>* Begin() const { | |
276 return new Iterator(this, container_.begin()); | |
277 } | |
278 virtual ParamIteratorInterface<T>* End() const { | |
279 return new Iterator(this, container_.end()); | |
280 } | |
281 | |
282 private: | |
283 typedef typename ::std::vector<T> ContainerType; | |
284 | |
285 class Iterator : public ParamIteratorInterface<T> { | |
286 public: | |
287 Iterator(const ParamGeneratorInterface<T>* base, | |
288 typename ContainerType::const_iterator iterator) | |
289 : base_(base), iterator_(iterator) {} | |
290 virtual ~Iterator() {} | |
291 | |
292 virtual const ParamGeneratorInterface<T>* BaseGenerator() const { | |
293 return base_; | |
294 } | |
295 virtual void Advance() { | |
296 ++iterator_; | |
297 value_.reset(); | |
298 } | |
299 virtual ParamIteratorInterface<T>* Clone() const { | |
300 return new Iterator(*this); | |
301 } | |
302 // We need to use cached value referenced by iterator_ because *iterator_ | |
303 // can return a temporary object (and of type other then T), so just | |
304 // having "return &*iterator_;" doesn't work. | |
305 // value_ is updated here and not in Advance() because Advance() | |
306 // can advance iterator_ beyond the end of the range, and we cannot | |
307 // detect that fact. The client code, on the other hand, is | |
308 // responsible for not calling Current() on an out-of-range iterator. | |
309 virtual const T* Current() const { | |
310 if (value_.get() == NULL) | |
311 value_.reset(new T(*iterator_)); | |
312 return value_.get(); | |
313 } | |
314 virtual bool Equals(const ParamIteratorInterface<T>& other) const { | |
315 // Having the same base generator guarantees that the other | |
316 // iterator is of the same type and we can downcast. | |
317 GTEST_CHECK_(BaseGenerator() == other.BaseGenerator()) | |
318 << "The program attempted to compare iterators " | |
319 << "from different generators." << std::endl; | |
320 return iterator_ == | |
321 CheckedDowncastToActualType<const Iterator>(&other)->iterator_; | |
322 } | |
323 | |
324 private: | |
325 Iterator(const Iterator& other) | |
326 // The explicit constructor call suppresses a false warning | |
327 // emitted by gcc when supplied with the -Wextra option. | |
328 : ParamIteratorInterface<T>(), | |
329 base_(other.base_), | |
330 iterator_(other.iterator_) {} | |
331 | |
332 const ParamGeneratorInterface<T>* const base_; | |
333 typename ContainerType::const_iterator iterator_; | |
334 // A cached value of *iterator_. We keep it here to allow access by | |
335 // pointer in the wrapping iterator's operator->(). | |
336 // value_ needs to be mutable to be accessed in Current(). | |
337 // Use of scoped_ptr helps manage cached value's lifetime, | |
338 // which is bound by the lifespan of the iterator itself. | |
339 mutable scoped_ptr<const T> value_; | |
340 }; // class ValuesInIteratorRangeGenerator::Iterator | |
341 | |
342 // No implementation - assignment is unsupported. | |
343 void operator=(const ValuesInIteratorRangeGenerator& other); | |
344 | |
345 const ContainerType container_; | |
346 }; // class ValuesInIteratorRangeGenerator | |
347 | |
348 // INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. | |
349 // | |
350 // Stores a parameter value and later creates tests parameterized with that | |
351 // value. | |
352 template <class TestClass> | |
353 class ParameterizedTestFactory : public TestFactoryBase { | |
354 public: | |
355 typedef typename TestClass::ParamType ParamType; | |
356 explicit ParameterizedTestFactory(ParamType parameter) : | |
357 parameter_(parameter) {} | |
358 virtual Test* CreateTest() { | |
359 TestClass::SetParam(¶meter_); | |
360 return new TestClass(); | |
361 } | |
362 | |
363 private: | |
364 const ParamType parameter_; | |
365 | |
366 GTEST_DISALLOW_COPY_AND_ASSIGN_(ParameterizedTestFactory); | |
367 }; | |
368 | |
369 // INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. | |
370 // | |
371 // TestMetaFactoryBase is a base class for meta-factories that create | |
372 // test factories for passing into MakeAndRegisterTestInfo function. | |
373 template <class ParamType> | |
374 class TestMetaFactoryBase { | |
375 public: | |
376 virtual ~TestMetaFactoryBase() {} | |
377 | |
378 virtual TestFactoryBase* CreateTestFactory(ParamType parameter) = 0; | |
379 }; | |
380 | |
381 // INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. | |
382 // | |
383 // TestMetaFactory creates test factories for passing into | |
384 // MakeAndRegisterTestInfo function. Since MakeAndRegisterTestInfo receives | |
385 // ownership of test factory pointer, same factory object cannot be passed | |
386 // into that method twice. But ParameterizedTestCaseInfo is going to call | |
387 // it for each Test/Parameter value combination. Thus it needs meta factory | |
388 // creator class. | |
389 template <class TestCase> | |
390 class TestMetaFactory | |
391 : public TestMetaFactoryBase<typename TestCase::ParamType> { | |
392 public: | |
393 typedef typename TestCase::ParamType ParamType; | |
394 | |
395 TestMetaFactory() {} | |
396 | |
397 virtual TestFactoryBase* CreateTestFactory(ParamType parameter) { | |
398 return new ParameterizedTestFactory<TestCase>(parameter); | |
399 } | |
400 | |
401 private: | |
402 GTEST_DISALLOW_COPY_AND_ASSIGN_(TestMetaFactory); | |
403 }; | |
404 | |
405 // INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. | |
406 // | |
407 // ParameterizedTestCaseInfoBase is a generic interface | |
408 // to ParameterizedTestCaseInfo classes. ParameterizedTestCaseInfoBase | |
409 // accumulates test information provided by TEST_P macro invocations | |
410 // and generators provided by INSTANTIATE_TEST_CASE_P macro invocations | |
411 // and uses that information to register all resulting test instances | |
412 // in RegisterTests method. The ParameterizeTestCaseRegistry class holds | |
413 // a collection of pointers to the ParameterizedTestCaseInfo objects | |
414 // and calls RegisterTests() on each of them when asked. | |
415 class ParameterizedTestCaseInfoBase { | |
416 public: | |
417 virtual ~ParameterizedTestCaseInfoBase() {} | |
418 | |
419 // Base part of test case name for display purposes. | |
420 virtual const string& GetTestCaseName() const = 0; | |
421 // Test case id to verify identity. | |
422 virtual TypeId GetTestCaseTypeId() const = 0; | |
423 // UnitTest class invokes this method to register tests in this | |
424 // test case right before running them in RUN_ALL_TESTS macro. | |
425 // This method should not be called more then once on any single | |
426 // instance of a ParameterizedTestCaseInfoBase derived class. | |
427 virtual void RegisterTests() = 0; | |
428 | |
429 protected: | |
430 ParameterizedTestCaseInfoBase() {} | |
431 | |
432 private: | |
433 GTEST_DISALLOW_COPY_AND_ASSIGN_(ParameterizedTestCaseInfoBase); | |
434 }; | |
435 | |
436 // INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. | |
437 // | |
438 // ParameterizedTestCaseInfo accumulates tests obtained from TEST_P | |
439 // macro invocations for a particular test case and generators | |
440 // obtained from INSTANTIATE_TEST_CASE_P macro invocations for that | |
441 // test case. It registers tests with all values generated by all | |
442 // generators when asked. | |
443 template <class TestCase> | |
444 class ParameterizedTestCaseInfo : public ParameterizedTestCaseInfoBase { | |
445 public: | |
446 // ParamType and GeneratorCreationFunc are private types but are required | |
447 // for declarations of public methods AddTestPattern() and | |
448 // AddTestCaseInstantiation(). | |
449 typedef typename TestCase::ParamType ParamType; | |
450 // A function that returns an instance of appropriate generator type. | |
451 typedef ParamGenerator<ParamType>(GeneratorCreationFunc)(); | |
452 | |
453 explicit ParameterizedTestCaseInfo(const char* name) | |
454 : test_case_name_(name) {} | |
455 | |
456 // Test case base name for display purposes. | |
457 virtual const string& GetTestCaseName() const { return test_case_name_; } | |
458 // Test case id to verify identity. | |
459 virtual TypeId GetTestCaseTypeId() const { return GetTypeId<TestCase>(); } | |
460 // TEST_P macro uses AddTestPattern() to record information | |
461 // about a single test in a LocalTestInfo structure. | |
462 // test_case_name is the base name of the test case (without invocation | |
463 // prefix). test_base_name is the name of an individual test without | |
464 // parameter index. For the test SequenceA/FooTest.DoBar/1 FooTest is | |
465 // test case base name and DoBar is test base name. | |
466 void AddTestPattern(const char* test_case_name, | |
467 const char* test_base_name, | |
468 TestMetaFactoryBase<ParamType>* meta_factory) { | |
469 tests_.push_back(linked_ptr<TestInfo>(new TestInfo(test_case_name, | |
470 test_base_name, | |
471 meta_factory))); | |
472 } | |
473 // INSTANTIATE_TEST_CASE_P macro uses AddGenerator() to record information | |
474 // about a generator. | |
475 int AddTestCaseInstantiation(const string& instantiation_name, | |
476 GeneratorCreationFunc* func, | |
477 const char* /* file */, | |
478 int /* line */) { | |
479 instantiations_.push_back(::std::make_pair(instantiation_name, func)); | |
480 return 0; // Return value used only to run this method in namespace scope. | |
481 } | |
482 // UnitTest class invokes this method to register tests in this test case | |
483 // test cases right before running tests in RUN_ALL_TESTS macro. | |
484 // This method should not be called more then once on any single | |
485 // instance of a ParameterizedTestCaseInfoBase derived class. | |
486 // UnitTest has a guard to prevent from calling this method more then once. | |
487 virtual void RegisterTests() { | |
488 for (typename TestInfoContainer::iterator test_it = tests_.begin(); | |
489 test_it != tests_.end(); ++test_it) { | |
490 linked_ptr<TestInfo> test_info = *test_it; | |
491 for (typename InstantiationContainer::iterator gen_it = | |
492 instantiations_.begin(); gen_it != instantiations_.end(); | |
493 ++gen_it) { | |
494 const string& instantiation_name = gen_it->first; | |
495 ParamGenerator<ParamType> generator((*gen_it->second)()); | |
496 | |
497 string test_case_name; | |
498 if ( !instantiation_name.empty() ) | |
499 test_case_name = instantiation_name + "/"; | |
500 test_case_name += test_info->test_case_base_name; | |
501 | |
502 int i = 0; | |
503 for (typename ParamGenerator<ParamType>::iterator param_it = | |
504 generator.begin(); | |
505 param_it != generator.end(); ++param_it, ++i) { | |
506 Message test_name_stream; | |
507 test_name_stream << test_info->test_base_name << "/" << i; | |
508 MakeAndRegisterTestInfo( | |
509 test_case_name.c_str(), | |
510 test_name_stream.GetString().c_str(), | |
511 NULL, // No type parameter. | |
512 PrintToString(*param_it).c_str(), | |
513 GetTestCaseTypeId(), | |
514 TestCase::SetUpTestCase, | |
515 TestCase::TearDownTestCase, | |
516 test_info->test_meta_factory->CreateTestFactory(*param_it)); | |
517 } // for param_it | |
518 } // for gen_it | |
519 } // for test_it | |
520 } // RegisterTests | |
521 | |
522 private: | |
523 // LocalTestInfo structure keeps information about a single test registered | |
524 // with TEST_P macro. | |
525 struct TestInfo { | |
526 TestInfo(const char* a_test_case_base_name, | |
527 const char* a_test_base_name, | |
528 TestMetaFactoryBase<ParamType>* a_test_meta_factory) : | |
529 test_case_base_name(a_test_case_base_name), | |
530 test_base_name(a_test_base_name), | |
531 test_meta_factory(a_test_meta_factory) {} | |
532 | |
533 const string test_case_base_name; | |
534 const string test_base_name; | |
535 const scoped_ptr<TestMetaFactoryBase<ParamType> > test_meta_factory; | |
536 }; | |
537 typedef ::std::vector<linked_ptr<TestInfo> > TestInfoContainer; | |
538 // Keeps pairs of <Instantiation name, Sequence generator creation function> | |
539 // received from INSTANTIATE_TEST_CASE_P macros. | |
540 typedef ::std::vector<std::pair<string, GeneratorCreationFunc*> > | |
541 InstantiationContainer; | |
542 | |
543 const string test_case_name_; | |
544 TestInfoContainer tests_; | |
545 InstantiationContainer instantiations_; | |
546 | |
547 GTEST_DISALLOW_COPY_AND_ASSIGN_(ParameterizedTestCaseInfo); | |
548 }; // class ParameterizedTestCaseInfo | |
549 | |
550 // INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. | |
551 // | |
552 // ParameterizedTestCaseRegistry contains a map of ParameterizedTestCaseInfoBase | |
553 // classes accessed by test case names. TEST_P and INSTANTIATE_TEST_CASE_P | |
554 // macros use it to locate their corresponding ParameterizedTestCaseInfo | |
555 // descriptors. | |
556 class ParameterizedTestCaseRegistry { | |
557 public: | |
558 ParameterizedTestCaseRegistry() {} | |
559 ~ParameterizedTestCaseRegistry() { | |
560 for (TestCaseInfoContainer::iterator it = test_case_infos_.begin(); | |
561 it != test_case_infos_.end(); ++it) { | |
562 delete *it; | |
563 } | |
564 } | |
565 | |
566 // Looks up or creates and returns a structure containing information about | |
567 // tests and instantiations of a particular test case. | |
568 template <class TestCase> | |
569 ParameterizedTestCaseInfo<TestCase>* GetTestCasePatternHolder( | |
570 const char* test_case_name, | |
571 const char* file, | |
572 int line) { | |
573 ParameterizedTestCaseInfo<TestCase>* typed_test_info = NULL; | |
574 for (TestCaseInfoContainer::iterator it = test_case_infos_.begin(); | |
575 it != test_case_infos_.end(); ++it) { | |
576 if ((*it)->GetTestCaseName() == test_case_name) { | |
577 if ((*it)->GetTestCaseTypeId() != GetTypeId<TestCase>()) { | |
578 // Complain about incorrect usage of Google Test facilities | |
579 // and terminate the program since we cannot guaranty correct | |
580 // test case setup and tear-down in this case. | |
581 ReportInvalidTestCaseType(test_case_name, file, line); | |
582 posix::Abort(); | |
583 } else { | |
584 // At this point we are sure that the object we found is of the same | |
585 // type we are looking for, so we downcast it to that type | |
586 // without further checks. | |
587 typed_test_info = CheckedDowncastToActualType< | |
588 ParameterizedTestCaseInfo<TestCase> >(*it); | |
589 } | |
590 break; | |
591 } | |
592 } | |
593 if (typed_test_info == NULL) { | |
594 typed_test_info = new ParameterizedTestCaseInfo<TestCase>(test_case_name); | |
595 test_case_infos_.push_back(typed_test_info); | |
596 } | |
597 return typed_test_info; | |
598 } | |
599 void RegisterTests() { | |
600 for (TestCaseInfoContainer::iterator it = test_case_infos_.begin(); | |
601 it != test_case_infos_.end(); ++it) { | |
602 (*it)->RegisterTests(); | |
603 } | |
604 } | |
605 | |
606 private: | |
607 typedef ::std::vector<ParameterizedTestCaseInfoBase*> TestCaseInfoContainer; | |
608 | |
609 TestCaseInfoContainer test_case_infos_; | |
610 | |
611 GTEST_DISALLOW_COPY_AND_ASSIGN_(ParameterizedTestCaseRegistry); | |
612 }; | |
613 | |
614 } // namespace internal | |
615 } // namespace testing | |
616 | |
617 #endif // GTEST_HAS_PARAM_TEST | |
618 | |
619 #endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_H_ |