Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
4358 Serge 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 
38
#include 
39
#include 
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  class ParamGeneratorInterface;
64
template  class ParamGenerator;
65
 
66
// Interface for iterating over elements provided by an implementation
67
// of ParamGeneratorInterface.
68
template 
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* 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.
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::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::operator==().
92
  virtual bool Equals(const ParamIteratorInterface& other) const = 0;
93
};
94
 
95
// Class iterating over elements provided by an implementation of
96
// ParamGeneratorInterface. It wraps ParamIteratorInterface
97
// and implements the const forward iterator concept.
98
template 
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* 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;
135
  explicit ParamIterator(ParamIteratorInterface* impl) : impl_(impl) {}
136
  scoped_ptr > impl_;
137
};
138
 
139
// ParamGeneratorInterface is the binary interface to access generators
140
// defined in other translation units.
141
template 
142
class ParamGeneratorInterface {
143
 public:
144
  typedef T ParamType;
145
 
146
  virtual ~ParamGeneratorInterface() {}
147
 
148
  // Generator interface definition
149
  virtual ParamIteratorInterface* Begin() const = 0;
150
  virtual ParamIteratorInterface* End() const = 0;
151
};
152
 
153
// Wraps ParamGeneratorInterface and provides general generator syntax
154
// compatible with the STL Container concept.
155
// This class implements copy initialization semantics and the contained
156
// ParamGeneratorInterface instance is shared among all copies
157
// of the original object. This is possible because that instance is immutable.
158
template
159
class ParamGenerator {
160
 public:
161
  typedef ParamIterator iterator;
162
 
163
  explicit ParamGenerator(ParamGeneratorInterface* 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 > 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 
183
class RangeGenerator : public ParamGeneratorInterface {
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* Begin() const {
191
    return new Iterator(this, begin_, 0, step_);
192
  }
193
  virtual ParamIteratorInterface* End() const {
194
    return new Iterator(this, end_, end_index_, step_);
195
  }
196
 
197
 private:
198
  class Iterator : public ParamIteratorInterface {
199
   public:
200
    Iterator(const ParamGeneratorInterface* 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* BaseGenerator() const {
206
      return base_;
207
    }
208
    virtual void Advance() {
209
      value_ = value_ + step_;
210
      index_++;
211
    }
212
    virtual ParamIteratorInterface* Clone() const {
213
      return new Iterator(*this);
214
    }
215
    virtual const T* Current() const { return &value_; }
216
    virtual bool Equals(const ParamIteratorInterface& 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(&other)->index_;
224
      return index_ == other_index;
225
    }
226
 
227
   private:
228
    Iterator(const Iterator& other)
229
        : ParamIteratorInterface(),
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* 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 
268
class ValuesInIteratorRangeGenerator : public ParamGeneratorInterface {
269
 public:
270
  template 
271
  ValuesInIteratorRangeGenerator(ForwardIterator begin, ForwardIterator end)
272
      : container_(begin, end) {}
273
  virtual ~ValuesInIteratorRangeGenerator() {}
274
 
275
  virtual ParamIteratorInterface* Begin() const {
276
    return new Iterator(this, container_.begin());
277
  }
278
  virtual ParamIteratorInterface* End() const {
279
    return new Iterator(this, container_.end());
280
  }
281
 
282
 private:
283
  typedef typename ::std::vector ContainerType;
284
 
285
  class Iterator : public ParamIteratorInterface {
286
   public:
287
    Iterator(const ParamGeneratorInterface* base,
288
             typename ContainerType::const_iterator iterator)
289
        : base_(base), iterator_(iterator) {}
290
    virtual ~Iterator() {}
291
 
292
    virtual const ParamGeneratorInterface* BaseGenerator() const {
293
      return base_;
294
    }
295
    virtual void Advance() {
296
      ++iterator_;
297
      value_.reset();
298
    }
299
    virtual ParamIteratorInterface* 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& 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(&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(),
329
          base_(other.base_),
330
          iterator_(other.iterator_) {}
331
 
332
    const ParamGeneratorInterface* 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 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 
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 
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 
390
class TestMetaFactory
391
    : public TestMetaFactoryBase {
392
 public:
393
  typedef typename TestCase::ParamType ParamType;
394
 
395
  TestMetaFactory() {}
396
 
397
  virtual TestFactoryBase* CreateTestFactory(ParamType parameter) {
398
    return new ParameterizedTestFactory(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 
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(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(); }
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* meta_factory) {
469
    tests_.push_back(linked_ptr(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 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 generator((*gen_it->second)());
496
 
497
        Message test_case_name_stream;
498
        if ( !instantiation_name.empty() )
499
          test_case_name_stream << instantiation_name << "/";
500
        test_case_name_stream << test_info->test_case_base_name;
501
 
502
        int i = 0;
503
        for (typename ParamGenerator::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_stream.GetString().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* 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 > test_meta_factory;
536
  };
537
  typedef ::std::vector > TestInfoContainer;
538
  // Keeps pairs of 
539
  // received from INSTANTIATE_TEST_CASE_P macros.
540
  typedef ::std::vector >
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 
569
  ParameterizedTestCaseInfo* GetTestCasePatternHolder(
570
      const char* test_case_name,
571
      const char* file,
572
      int line) {
573
    ParameterizedTestCaseInfo* 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()) {
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 >(*it);
589
        }
590
        break;
591
      }
592
    }
593
    if (typed_test_info == NULL) {
594
      typed_test_info = new ParameterizedTestCaseInfo(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 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_