Line data Source code
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 210 : class ParamIteratorInterface {
70 : public:
71 210 : 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 210 : 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 220 : const T& operator*() const { return *impl_->Current(); }
114 : const T* operator->() const { return impl_->Current(); }
115 : // Prefix version of operator++.
116 110 : ParamIterator& operator++() {
117 110 : impl_->Advance();
118 110 : 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 160 : bool operator==(const ParamIterator& other) const {
127 160 : return impl_.get() == other.impl_.get() || impl_->Equals(*other.impl_);
128 : }
129 160 : bool operator!=(const ParamIterator& other) const {
130 160 : return !(*this == other);
131 : }
132 :
133 : private:
134 : friend class ParamGenerator<T>;
135 210 : 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 50 : class ParamGeneratorInterface {
143 : public:
144 : typedef T ParamType;
145 :
146 50 : 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 50 : class ParamGenerator {
160 : public:
161 : typedef ParamIterator<T> iterator;
162 :
163 50 : 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 50 : iterator begin() const { return iterator(impl_->Begin()); }
172 160 : 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 50 : ValuesInIteratorRangeGenerator(ForwardIterator begin, ForwardIterator end)
272 50 : : container_(begin, end) {}
273 100 : virtual ~ValuesInIteratorRangeGenerator() {}
274 :
275 50 : virtual ParamIteratorInterface<T>* Begin() const {
276 50 : return new Iterator(this, container_.begin());
277 : }
278 160 : virtual ParamIteratorInterface<T>* End() const {
279 160 : 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 210 : Iterator(const ParamGeneratorInterface<T>* base,
288 : typename ContainerType::const_iterator iterator)
289 210 : : base_(base), iterator_(iterator) {}
290 420 : virtual ~Iterator() {}
291 :
292 320 : virtual const ParamGeneratorInterface<T>* BaseGenerator() const {
293 320 : return base_;
294 : }
295 110 : virtual void Advance() {
296 110 : ++iterator_;
297 110 : value_.reset();
298 110 : }
299 0 : virtual ParamIteratorInterface<T>* Clone() const {
300 0 : 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 220 : virtual const T* Current() const {
310 220 : if (value_.get() == NULL)
311 110 : value_.reset(new T(*iterator_));
312 220 : return value_.get();
313 : }
314 160 : 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 160 : GTEST_CHECK_(BaseGenerator() == other.BaseGenerator())
318 0 : << "The program attempted to compare iterators "
319 0 : << "from different generators." << std::endl;
320 160 : return iterator_ ==
321 320 : CheckedDowncastToActualType<const Iterator>(&other)->iterator_;
322 : }
323 :
324 : private:
325 0 : 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 0 : 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 0 : class ParameterizedTestFactory : public TestFactoryBase {
354 : public:
355 : typedef typename TestClass::ParamType ParamType;
356 110 : explicit ParameterizedTestFactory(ParamType parameter) :
357 110 : parameter_(parameter) {}
358 110 : virtual Test* CreateTest() {
359 110 : TestClass::SetParam(¶meter_);
360 110 : 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 50 : class TestMetaFactoryBase {
375 : public:
376 0 : 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 0 : class TestMetaFactory
391 : : public TestMetaFactoryBase<typename TestCase::ParamType> {
392 : public:
393 : typedef typename TestCase::ParamType ParamType;
394 :
395 50 : TestMetaFactory() {}
396 :
397 110 : virtual TestFactoryBase* CreateTestFactory(ParamType parameter) {
398 110 : 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 0 : 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 4 : 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 0 : 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 4 : explicit ParameterizedTestCaseInfo(const char* name)
454 4 : : test_case_name_(name) {}
455 :
456 : // Test case base name for display purposes.
457 88 : virtual const string& GetTestCaseName() const { return test_case_name_; }
458 : // Test case id to verify identity.
459 160 : 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 50 : void AddTestPattern(const char* test_case_name,
467 : const char* test_base_name,
468 : TestMetaFactoryBase<ParamType>* meta_factory) {
469 50 : tests_.push_back(linked_ptr<TestInfo>(new TestInfo(test_case_name,
470 : test_base_name,
471 : meta_factory)));
472 50 : }
473 : // INSTANTIATE_TEST_CASE_P macro uses AddGenerator() to record information
474 : // about a generator.
475 4 : int AddTestCaseInstantiation(const string& instantiation_name,
476 : GeneratorCreationFunc* func,
477 : const char* /* file */,
478 : int /* line */) {
479 4 : instantiations_.push_back(::std::make_pair(instantiation_name, func));
480 4 : 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 4 : virtual void RegisterTests() {
488 162 : for (typename TestInfoContainer::iterator test_it = tests_.begin();
489 108 : test_it != tests_.end(); ++test_it) {
490 50 : linked_ptr<TestInfo> test_info = *test_it;
491 300 : for (typename InstantiationContainer::iterator gen_it =
492 250 : instantiations_.begin(); gen_it != instantiations_.end();
493 : ++gen_it) {
494 50 : const string& instantiation_name = gen_it->first;
495 50 : ParamGenerator<ParamType> generator((*gen_it->second)());
496 :
497 100 : string test_case_name;
498 50 : if ( !instantiation_name.empty() )
499 50 : test_case_name = instantiation_name + "/";
500 50 : test_case_name += test_info->test_case_base_name;
501 :
502 50 : int i = 0;
503 480 : for (typename ParamGenerator<ParamType>::iterator param_it =
504 50 : generator.begin();
505 320 : param_it != generator.end(); ++param_it, ++i) {
506 110 : Message test_name_stream;
507 110 : test_name_stream << test_info->test_base_name << "/" << i;
508 110 : MakeAndRegisterTestInfo(
509 : test_case_name.c_str(),
510 : test_name_stream.GetString().c_str(),
511 : NULL, // No type parameter.
512 110 : PrintToString(*param_it).c_str(),
513 110 : GetTestCaseTypeId(),
514 : TestCase::SetUpTestCase,
515 : TestCase::TearDownTestCase,
516 440 : test_info->test_meta_factory->CreateTestFactory(*param_it));
517 : } // for param_it
518 : } // for gen_it
519 : } // for test_it
520 4 : } // RegisterTests
521 :
522 : private:
523 : // LocalTestInfo structure keeps information about a single test registered
524 : // with TEST_P macro.
525 0 : struct TestInfo {
526 50 : 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 50 : 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 54 : ParameterizedTestCaseInfo<TestCase>* GetTestCasePatternHolder(
570 : const char* test_case_name,
571 : const char* file,
572 : int line) {
573 54 : ParameterizedTestCaseInfo<TestCase>* typed_test_info = NULL;
574 276 : for (TestCaseInfoContainer::iterator it = test_case_infos_.begin();
575 184 : it != test_case_infos_.end(); ++it) {
576 88 : if ((*it)->GetTestCaseName() == test_case_name) {
577 50 : 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 0 : ReportInvalidTestCaseType(test_case_name, file, line);
582 0 : 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 50 : typed_test_info = CheckedDowncastToActualType<
588 50 : ParameterizedTestCaseInfo<TestCase> >(*it);
589 : }
590 50 : break;
591 : }
592 : }
593 54 : if (typed_test_info == NULL) {
594 4 : typed_test_info = new ParameterizedTestCaseInfo<TestCase>(test_case_name);
595 4 : test_case_infos_.push_back(typed_test_info);
596 : }
597 54 : 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_
|