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