113481Sgiacomo.travaglini@arm.com// Copyright 2008 Google Inc.
213481Sgiacomo.travaglini@arm.com// All Rights Reserved.
313481Sgiacomo.travaglini@arm.com//
413481Sgiacomo.travaglini@arm.com// Redistribution and use in source and binary forms, with or without
513481Sgiacomo.travaglini@arm.com// modification, are permitted provided that the following conditions are
613481Sgiacomo.travaglini@arm.com// met:
713481Sgiacomo.travaglini@arm.com//
813481Sgiacomo.travaglini@arm.com//     * Redistributions of source code must retain the above copyright
913481Sgiacomo.travaglini@arm.com// notice, this list of conditions and the following disclaimer.
1013481Sgiacomo.travaglini@arm.com//     * Redistributions in binary form must reproduce the above
1113481Sgiacomo.travaglini@arm.com// copyright notice, this list of conditions and the following disclaimer
1213481Sgiacomo.travaglini@arm.com// in the documentation and/or other materials provided with the
1313481Sgiacomo.travaglini@arm.com// distribution.
1413481Sgiacomo.travaglini@arm.com//     * Neither the name of Google Inc. nor the names of its
1513481Sgiacomo.travaglini@arm.com// contributors may be used to endorse or promote products derived from
1613481Sgiacomo.travaglini@arm.com// this software without specific prior written permission.
1713481Sgiacomo.travaglini@arm.com//
1813481Sgiacomo.travaglini@arm.com// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
1913481Sgiacomo.travaglini@arm.com// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
2013481Sgiacomo.travaglini@arm.com// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
2113481Sgiacomo.travaglini@arm.com// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
2213481Sgiacomo.travaglini@arm.com// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
2313481Sgiacomo.travaglini@arm.com// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
2413481Sgiacomo.travaglini@arm.com// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2513481Sgiacomo.travaglini@arm.com// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
2613481Sgiacomo.travaglini@arm.com// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
2713481Sgiacomo.travaglini@arm.com// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
2813481Sgiacomo.travaglini@arm.com// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2913481Sgiacomo.travaglini@arm.com//
3013481Sgiacomo.travaglini@arm.com// Author: wan@google.com (Zhanyong Wan)
3113481Sgiacomo.travaglini@arm.com
3213481Sgiacomo.travaglini@arm.com#ifndef GTEST_INCLUDE_GTEST_GTEST_TYPED_TEST_H_
3313481Sgiacomo.travaglini@arm.com#define GTEST_INCLUDE_GTEST_GTEST_TYPED_TEST_H_
3413481Sgiacomo.travaglini@arm.com
3513481Sgiacomo.travaglini@arm.com// This header implements typed tests and type-parameterized tests.
3613481Sgiacomo.travaglini@arm.com
3713481Sgiacomo.travaglini@arm.com// Typed (aka type-driven) tests repeat the same test for types in a
3813481Sgiacomo.travaglini@arm.com// list.  You must know which types you want to test with when writing
3913481Sgiacomo.travaglini@arm.com// typed tests. Here's how you do it:
4013481Sgiacomo.travaglini@arm.com
4113481Sgiacomo.travaglini@arm.com#if 0
4213481Sgiacomo.travaglini@arm.com
4313481Sgiacomo.travaglini@arm.com// First, define a fixture class template.  It should be parameterized
4413481Sgiacomo.travaglini@arm.com// by a type.  Remember to derive it from testing::Test.
4513481Sgiacomo.travaglini@arm.comtemplate <typename T>
4613481Sgiacomo.travaglini@arm.comclass FooTest : public testing::Test {
4713481Sgiacomo.travaglini@arm.com public:
4813481Sgiacomo.travaglini@arm.com  ...
4913481Sgiacomo.travaglini@arm.com  typedef std::list<T> List;
5013481Sgiacomo.travaglini@arm.com  static T shared_;
5113481Sgiacomo.travaglini@arm.com  T value_;
5213481Sgiacomo.travaglini@arm.com};
5313481Sgiacomo.travaglini@arm.com
5413481Sgiacomo.travaglini@arm.com// Next, associate a list of types with the test case, which will be
5513481Sgiacomo.travaglini@arm.com// repeated for each type in the list.  The typedef is necessary for
5613481Sgiacomo.travaglini@arm.com// the macro to parse correctly.
5713481Sgiacomo.travaglini@arm.comtypedef testing::Types<char, int, unsigned int> MyTypes;
5813481Sgiacomo.travaglini@arm.comTYPED_TEST_CASE(FooTest, MyTypes);
5913481Sgiacomo.travaglini@arm.com
6013481Sgiacomo.travaglini@arm.com// If the type list contains only one type, you can write that type
6113481Sgiacomo.travaglini@arm.com// directly without Types<...>:
6213481Sgiacomo.travaglini@arm.com//   TYPED_TEST_CASE(FooTest, int);
6313481Sgiacomo.travaglini@arm.com
6413481Sgiacomo.travaglini@arm.com// Then, use TYPED_TEST() instead of TEST_F() to define as many typed
6513481Sgiacomo.travaglini@arm.com// tests for this test case as you want.
6613481Sgiacomo.travaglini@arm.comTYPED_TEST(FooTest, DoesBlah) {
6713481Sgiacomo.travaglini@arm.com  // Inside a test, refer to TypeParam to get the type parameter.
6813481Sgiacomo.travaglini@arm.com  // Since we are inside a derived class template, C++ requires use to
6913481Sgiacomo.travaglini@arm.com  // visit the members of FooTest via 'this'.
7013481Sgiacomo.travaglini@arm.com  TypeParam n = this->value_;
7113481Sgiacomo.travaglini@arm.com
7213481Sgiacomo.travaglini@arm.com  // To visit static members of the fixture, add the TestFixture::
7313481Sgiacomo.travaglini@arm.com  // prefix.
7413481Sgiacomo.travaglini@arm.com  n += TestFixture::shared_;
7513481Sgiacomo.travaglini@arm.com
7613481Sgiacomo.travaglini@arm.com  // To refer to typedefs in the fixture, add the "typename
7713481Sgiacomo.travaglini@arm.com  // TestFixture::" prefix.
7813481Sgiacomo.travaglini@arm.com  typename TestFixture::List values;
7913481Sgiacomo.travaglini@arm.com  values.push_back(n);
8013481Sgiacomo.travaglini@arm.com  ...
8113481Sgiacomo.travaglini@arm.com}
8213481Sgiacomo.travaglini@arm.com
8313481Sgiacomo.travaglini@arm.comTYPED_TEST(FooTest, HasPropertyA) { ... }
8413481Sgiacomo.travaglini@arm.com
8513481Sgiacomo.travaglini@arm.com#endif  // 0
8613481Sgiacomo.travaglini@arm.com
8713481Sgiacomo.travaglini@arm.com// Type-parameterized tests are abstract test patterns parameterized
8813481Sgiacomo.travaglini@arm.com// by a type.  Compared with typed tests, type-parameterized tests
8913481Sgiacomo.travaglini@arm.com// allow you to define the test pattern without knowing what the type
9013481Sgiacomo.travaglini@arm.com// parameters are.  The defined pattern can be instantiated with
9113481Sgiacomo.travaglini@arm.com// different types any number of times, in any number of translation
9213481Sgiacomo.travaglini@arm.com// units.
9313481Sgiacomo.travaglini@arm.com//
9413481Sgiacomo.travaglini@arm.com// If you are designing an interface or concept, you can define a
9513481Sgiacomo.travaglini@arm.com// suite of type-parameterized tests to verify properties that any
9613481Sgiacomo.travaglini@arm.com// valid implementation of the interface/concept should have.  Then,
9713481Sgiacomo.travaglini@arm.com// each implementation can easily instantiate the test suite to verify
9813481Sgiacomo.travaglini@arm.com// that it conforms to the requirements, without having to write
9913481Sgiacomo.travaglini@arm.com// similar tests repeatedly.  Here's an example:
10013481Sgiacomo.travaglini@arm.com
10113481Sgiacomo.travaglini@arm.com#if 0
10213481Sgiacomo.travaglini@arm.com
10313481Sgiacomo.travaglini@arm.com// First, define a fixture class template.  It should be parameterized
10413481Sgiacomo.travaglini@arm.com// by a type.  Remember to derive it from testing::Test.
10513481Sgiacomo.travaglini@arm.comtemplate <typename T>
10613481Sgiacomo.travaglini@arm.comclass FooTest : public testing::Test {
10713481Sgiacomo.travaglini@arm.com  ...
10813481Sgiacomo.travaglini@arm.com};
10913481Sgiacomo.travaglini@arm.com
11013481Sgiacomo.travaglini@arm.com// Next, declare that you will define a type-parameterized test case
11113481Sgiacomo.travaglini@arm.com// (the _P suffix is for "parameterized" or "pattern", whichever you
11213481Sgiacomo.travaglini@arm.com// prefer):
11313481Sgiacomo.travaglini@arm.comTYPED_TEST_CASE_P(FooTest);
11413481Sgiacomo.travaglini@arm.com
11513481Sgiacomo.travaglini@arm.com// Then, use TYPED_TEST_P() to define as many type-parameterized tests
11613481Sgiacomo.travaglini@arm.com// for this type-parameterized test case as you want.
11713481Sgiacomo.travaglini@arm.comTYPED_TEST_P(FooTest, DoesBlah) {
11813481Sgiacomo.travaglini@arm.com  // Inside a test, refer to TypeParam to get the type parameter.
11913481Sgiacomo.travaglini@arm.com  TypeParam n = 0;
12013481Sgiacomo.travaglini@arm.com  ...
12113481Sgiacomo.travaglini@arm.com}
12213481Sgiacomo.travaglini@arm.com
12313481Sgiacomo.travaglini@arm.comTYPED_TEST_P(FooTest, HasPropertyA) { ... }
12413481Sgiacomo.travaglini@arm.com
12513481Sgiacomo.travaglini@arm.com// Now the tricky part: you need to register all test patterns before
12613481Sgiacomo.travaglini@arm.com// you can instantiate them.  The first argument of the macro is the
12713481Sgiacomo.travaglini@arm.com// test case name; the rest are the names of the tests in this test
12813481Sgiacomo.travaglini@arm.com// case.
12913481Sgiacomo.travaglini@arm.comREGISTER_TYPED_TEST_CASE_P(FooTest,
13013481Sgiacomo.travaglini@arm.com                           DoesBlah, HasPropertyA);
13113481Sgiacomo.travaglini@arm.com
13213481Sgiacomo.travaglini@arm.com// Finally, you are free to instantiate the pattern with the types you
13313481Sgiacomo.travaglini@arm.com// want.  If you put the above code in a header file, you can #include
13413481Sgiacomo.travaglini@arm.com// it in multiple C++ source files and instantiate it multiple times.
13513481Sgiacomo.travaglini@arm.com//
13613481Sgiacomo.travaglini@arm.com// To distinguish different instances of the pattern, the first
13713481Sgiacomo.travaglini@arm.com// argument to the INSTANTIATE_* macro is a prefix that will be added
13813481Sgiacomo.travaglini@arm.com// to the actual test case name.  Remember to pick unique prefixes for
13913481Sgiacomo.travaglini@arm.com// different instances.
14013481Sgiacomo.travaglini@arm.comtypedef testing::Types<char, int, unsigned int> MyTypes;
14113481Sgiacomo.travaglini@arm.comINSTANTIATE_TYPED_TEST_CASE_P(My, FooTest, MyTypes);
14213481Sgiacomo.travaglini@arm.com
14313481Sgiacomo.travaglini@arm.com// If the type list contains only one type, you can write that type
14413481Sgiacomo.travaglini@arm.com// directly without Types<...>:
14513481Sgiacomo.travaglini@arm.com//   INSTANTIATE_TYPED_TEST_CASE_P(My, FooTest, int);
14613481Sgiacomo.travaglini@arm.com
14713481Sgiacomo.travaglini@arm.com#endif  // 0
14813481Sgiacomo.travaglini@arm.com
14913481Sgiacomo.travaglini@arm.com#include "gtest/internal/gtest-port.h"
15013481Sgiacomo.travaglini@arm.com#include "gtest/internal/gtest-type-util.h"
15113481Sgiacomo.travaglini@arm.com
15213481Sgiacomo.travaglini@arm.com// Implements typed tests.
15313481Sgiacomo.travaglini@arm.com
15413481Sgiacomo.travaglini@arm.com#if GTEST_HAS_TYPED_TEST
15513481Sgiacomo.travaglini@arm.com
15613481Sgiacomo.travaglini@arm.com// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
15713481Sgiacomo.travaglini@arm.com//
15813481Sgiacomo.travaglini@arm.com// Expands to the name of the typedef for the type parameters of the
15913481Sgiacomo.travaglini@arm.com// given test case.
16013481Sgiacomo.travaglini@arm.com# define GTEST_TYPE_PARAMS_(TestCaseName) gtest_type_params_##TestCaseName##_
16113481Sgiacomo.travaglini@arm.com
16213481Sgiacomo.travaglini@arm.com// The 'Types' template argument below must have spaces around it
16313481Sgiacomo.travaglini@arm.com// since some compilers may choke on '>>' when passing a template
16413481Sgiacomo.travaglini@arm.com// instance (e.g. Types<int>)
16513481Sgiacomo.travaglini@arm.com# define TYPED_TEST_CASE(CaseName, Types) \
16613481Sgiacomo.travaglini@arm.com  typedef ::testing::internal::TypeList< Types >::type \
16713481Sgiacomo.travaglini@arm.com      GTEST_TYPE_PARAMS_(CaseName)
16813481Sgiacomo.travaglini@arm.com
16913481Sgiacomo.travaglini@arm.com# define TYPED_TEST(CaseName, TestName) \
17013481Sgiacomo.travaglini@arm.com  template <typename gtest_TypeParam_> \
17113481Sgiacomo.travaglini@arm.com  class GTEST_TEST_CLASS_NAME_(CaseName, TestName) \
17213481Sgiacomo.travaglini@arm.com      : public CaseName<gtest_TypeParam_> { \
17313481Sgiacomo.travaglini@arm.com   private: \
17413481Sgiacomo.travaglini@arm.com    typedef CaseName<gtest_TypeParam_> TestFixture; \
17513481Sgiacomo.travaglini@arm.com    typedef gtest_TypeParam_ TypeParam; \
17613481Sgiacomo.travaglini@arm.com    virtual void TestBody(); \
17713481Sgiacomo.travaglini@arm.com  }; \
17813481Sgiacomo.travaglini@arm.com  bool gtest_##CaseName##_##TestName##_registered_ GTEST_ATTRIBUTE_UNUSED_ = \
17913481Sgiacomo.travaglini@arm.com      ::testing::internal::TypeParameterizedTest< \
18013481Sgiacomo.travaglini@arm.com          CaseName, \
18113481Sgiacomo.travaglini@arm.com          ::testing::internal::TemplateSel< \
18213481Sgiacomo.travaglini@arm.com              GTEST_TEST_CLASS_NAME_(CaseName, TestName)>, \
18313481Sgiacomo.travaglini@arm.com          GTEST_TYPE_PARAMS_(CaseName)>::Register(\
18413481Sgiacomo.travaglini@arm.com              "", ::testing::internal::CodeLocation(__FILE__, __LINE__), \
18513481Sgiacomo.travaglini@arm.com              #CaseName, #TestName, 0); \
18613481Sgiacomo.travaglini@arm.com  template <typename gtest_TypeParam_> \
18713481Sgiacomo.travaglini@arm.com  void GTEST_TEST_CLASS_NAME_(CaseName, TestName)<gtest_TypeParam_>::TestBody()
18813481Sgiacomo.travaglini@arm.com
18913481Sgiacomo.travaglini@arm.com#endif  // GTEST_HAS_TYPED_TEST
19013481Sgiacomo.travaglini@arm.com
19113481Sgiacomo.travaglini@arm.com// Implements type-parameterized tests.
19213481Sgiacomo.travaglini@arm.com
19313481Sgiacomo.travaglini@arm.com#if GTEST_HAS_TYPED_TEST_P
19413481Sgiacomo.travaglini@arm.com
19513481Sgiacomo.travaglini@arm.com// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
19613481Sgiacomo.travaglini@arm.com//
19713481Sgiacomo.travaglini@arm.com// Expands to the namespace name that the type-parameterized tests for
19813481Sgiacomo.travaglini@arm.com// the given type-parameterized test case are defined in.  The exact
19913481Sgiacomo.travaglini@arm.com// name of the namespace is subject to change without notice.
20013481Sgiacomo.travaglini@arm.com# define GTEST_CASE_NAMESPACE_(TestCaseName) \
20113481Sgiacomo.travaglini@arm.com  gtest_case_##TestCaseName##_
20213481Sgiacomo.travaglini@arm.com
20313481Sgiacomo.travaglini@arm.com// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
20413481Sgiacomo.travaglini@arm.com//
20513481Sgiacomo.travaglini@arm.com// Expands to the name of the variable used to remember the names of
20613481Sgiacomo.travaglini@arm.com// the defined tests in the given test case.
20713481Sgiacomo.travaglini@arm.com# define GTEST_TYPED_TEST_CASE_P_STATE_(TestCaseName) \
20813481Sgiacomo.travaglini@arm.com  gtest_typed_test_case_p_state_##TestCaseName##_
20913481Sgiacomo.travaglini@arm.com
21013481Sgiacomo.travaglini@arm.com// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE DIRECTLY.
21113481Sgiacomo.travaglini@arm.com//
21213481Sgiacomo.travaglini@arm.com// Expands to the name of the variable used to remember the names of
21313481Sgiacomo.travaglini@arm.com// the registered tests in the given test case.
21413481Sgiacomo.travaglini@arm.com# define GTEST_REGISTERED_TEST_NAMES_(TestCaseName) \
21513481Sgiacomo.travaglini@arm.com  gtest_registered_test_names_##TestCaseName##_
21613481Sgiacomo.travaglini@arm.com
21713481Sgiacomo.travaglini@arm.com// The variables defined in the type-parameterized test macros are
21813481Sgiacomo.travaglini@arm.com// static as typically these macros are used in a .h file that can be
21913481Sgiacomo.travaglini@arm.com// #included in multiple translation units linked together.
22013481Sgiacomo.travaglini@arm.com# define TYPED_TEST_CASE_P(CaseName) \
22113481Sgiacomo.travaglini@arm.com  static ::testing::internal::TypedTestCasePState \
22213481Sgiacomo.travaglini@arm.com      GTEST_TYPED_TEST_CASE_P_STATE_(CaseName)
22313481Sgiacomo.travaglini@arm.com
22413481Sgiacomo.travaglini@arm.com# define TYPED_TEST_P(CaseName, TestName) \
22513481Sgiacomo.travaglini@arm.com  namespace GTEST_CASE_NAMESPACE_(CaseName) { \
22613481Sgiacomo.travaglini@arm.com  template <typename gtest_TypeParam_> \
22713481Sgiacomo.travaglini@arm.com  class TestName : public CaseName<gtest_TypeParam_> { \
22813481Sgiacomo.travaglini@arm.com   private: \
22913481Sgiacomo.travaglini@arm.com    typedef CaseName<gtest_TypeParam_> TestFixture; \
23013481Sgiacomo.travaglini@arm.com    typedef gtest_TypeParam_ TypeParam; \
23113481Sgiacomo.travaglini@arm.com    virtual void TestBody(); \
23213481Sgiacomo.travaglini@arm.com  }; \
23313481Sgiacomo.travaglini@arm.com  static bool gtest_##TestName##_defined_ GTEST_ATTRIBUTE_UNUSED_ = \
23413481Sgiacomo.travaglini@arm.com      GTEST_TYPED_TEST_CASE_P_STATE_(CaseName).AddTestName(\
23513481Sgiacomo.travaglini@arm.com          __FILE__, __LINE__, #CaseName, #TestName); \
23613481Sgiacomo.travaglini@arm.com  } \
23713481Sgiacomo.travaglini@arm.com  template <typename gtest_TypeParam_> \
23813481Sgiacomo.travaglini@arm.com  void GTEST_CASE_NAMESPACE_(CaseName)::TestName<gtest_TypeParam_>::TestBody()
23913481Sgiacomo.travaglini@arm.com
24013481Sgiacomo.travaglini@arm.com# define REGISTER_TYPED_TEST_CASE_P(CaseName, ...) \
24113481Sgiacomo.travaglini@arm.com  namespace GTEST_CASE_NAMESPACE_(CaseName) { \
24213481Sgiacomo.travaglini@arm.com  typedef ::testing::internal::Templates<__VA_ARGS__>::type gtest_AllTests_; \
24313481Sgiacomo.travaglini@arm.com  } \
24413481Sgiacomo.travaglini@arm.com  static const char* const GTEST_REGISTERED_TEST_NAMES_(CaseName) = \
24513481Sgiacomo.travaglini@arm.com      GTEST_TYPED_TEST_CASE_P_STATE_(CaseName).VerifyRegisteredTestNames(\
24613481Sgiacomo.travaglini@arm.com          __FILE__, __LINE__, #__VA_ARGS__)
24713481Sgiacomo.travaglini@arm.com
24813481Sgiacomo.travaglini@arm.com// The 'Types' template argument below must have spaces around it
24913481Sgiacomo.travaglini@arm.com// since some compilers may choke on '>>' when passing a template
25013481Sgiacomo.travaglini@arm.com// instance (e.g. Types<int>)
25113481Sgiacomo.travaglini@arm.com# define INSTANTIATE_TYPED_TEST_CASE_P(Prefix, CaseName, Types) \
25213481Sgiacomo.travaglini@arm.com  bool gtest_##Prefix##_##CaseName GTEST_ATTRIBUTE_UNUSED_ = \
25313481Sgiacomo.travaglini@arm.com      ::testing::internal::TypeParameterizedTestCase<CaseName, \
25413481Sgiacomo.travaglini@arm.com          GTEST_CASE_NAMESPACE_(CaseName)::gtest_AllTests_, \
25513481Sgiacomo.travaglini@arm.com          ::testing::internal::TypeList< Types >::type>::Register(\
25613481Sgiacomo.travaglini@arm.com              #Prefix, \
25713481Sgiacomo.travaglini@arm.com              ::testing::internal::CodeLocation(__FILE__, __LINE__), \
25813481Sgiacomo.travaglini@arm.com              &GTEST_TYPED_TEST_CASE_P_STATE_(CaseName), \
25913481Sgiacomo.travaglini@arm.com              #CaseName, GTEST_REGISTERED_TEST_NAMES_(CaseName))
26013481Sgiacomo.travaglini@arm.com
26113481Sgiacomo.travaglini@arm.com#endif  // GTEST_HAS_TYPED_TEST_P
26213481Sgiacomo.travaglini@arm.com
26313481Sgiacomo.travaglini@arm.com#endif  // GTEST_INCLUDE_GTEST_GTEST_TYPED_TEST_H_
264