pull/496/merge
parent
a2b1a8556e
commit
29d8235540
8 changed files with 4706 additions and 0 deletions
@ -0,0 +1,253 @@ |
||||
// Copyright 2008 Google Inc.
|
||||
// All Rights Reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Author: wan@google.com (Zhanyong Wan)
|
||||
|
||||
#ifndef GTEST_INCLUDE_GTEST_GTEST_TYPED_TEST_H_ |
||||
#define GTEST_INCLUDE_GTEST_GTEST_TYPED_TEST_H_ |
||||
|
||||
// This header implements typed tests and type-parameterized tests.
|
||||
|
||||
// Typed (aka type-driven) tests repeat the same test for types in a
|
||||
// list. You must know which types you want to test with when writing
|
||||
// typed tests. Here's how you do it:
|
||||
|
||||
#if 0 |
||||
|
||||
// First, define a fixture class template. It should be parameterized
|
||||
// by a type. Remember to derive it from testing::Test.
|
||||
template <typename T> |
||||
class FooTest : public testing::Test { |
||||
public: |
||||
... |
||||
typedef std::list<T> List; |
||||
static T shared_; |
||||
T value_; |
||||
}; |
||||
|
||||
// Next, associate a list of types with the test case, which will be
|
||||
// repeated for each type in the list. The typedef is necessary for
|
||||
// the macro to parse correctly.
|
||||
typedef testing::Types<char, int, unsigned int> MyTypes; |
||||
TYPED_TEST_CASE(FooTest, MyTypes); |
||||
|
||||
// If the type list contains only one type, you can write that type
|
||||
// directly without Types<...>:
|
||||
// TYPED_TEST_CASE(FooTest, int);
|
||||
|
||||
// Then, use TYPED_TEST() instead of TEST_F() to define as many typed
|
||||
// tests for this test case as you want.
|
||||
TYPED_TEST(FooTest, DoesBlah) { |
||||
// Inside a test, refer to TypeParam to get the type parameter.
|
||||
// Since we are inside a derived class template, C++ requires use to
|
||||
// visit the members of FooTest via 'this'.
|
||||
TypeParam n = this->value_; |
||||
|
||||
// To visit static members of the fixture, add the TestFixture::
|
||||
// prefix.
|
||||
n += TestFixture::shared_; |
||||
|
||||
// To refer to typedefs in the fixture, add the "typename
|
||||
// TestFixture::" prefix.
|
||||
typename TestFixture::List values; |
||||
values.push_back(n); |
||||
... |
||||
} |
||||
|
||||
TYPED_TEST(FooTest, HasPropertyA) { ... } |
||||
|
||||
#endif // 0
|
||||
|
||||
// Type-parameterized tests are abstract test patterns parameterized
|
||||
// by a type. Compared with typed tests, type-parameterized tests
|
||||
// allow you to define the test pattern without knowing what the type
|
||||
// parameters are. The defined pattern can be instantiated with
|
||||
// different types any number of times, in any number of translation
|
||||
// units.
|
||||
//
|
||||
// If you are designing an interface or concept, you can define a
|
||||
// suite of type-parameterized tests to verify properties that any
|
||||
// valid implementation of the interface/concept should have. Then,
|
||||
// each implementation can easily instantiate the test suite to verify
|
||||
// that it conforms to the requirements, without having to write
|
||||
// similar tests repeatedly. Here's an example:
|
||||
|
||||
#if 0 |
||||
|
||||
// First, define a fixture class template. It should be parameterized
|
||||
// by a type. Remember to derive it from testing::Test.
|
||||
template <typename T> |
||||
class FooTest : public testing::Test { |
||||
... |
||||
}; |
||||
|
||||
// Next, declare that you will define a type-parameterized test case
|
||||
// (the _P suffix is for "parameterized" or "pattern", whichever you
|
||||
// prefer):
|
||||
TYPED_TEST_CASE_P(FooTest); |
||||
|
||||
// Then, use TYPED_TEST_P() to define as many type-parameterized tests
|
||||
// for this type-parameterized test case as you want.
|
||||
TYPED_TEST_P(FooTest, DoesBlah) { |
||||
// Inside a test, refer to TypeParam to get the type parameter.
|
||||
TypeParam n = 0; |
||||
... |
||||
} |
||||
|
||||
TYPED_TEST_P(FooTest, HasPropertyA) { ... } |
||||
|
||||
// Now the tricky part: you need to register all test patterns before
|
||||
// you can instantiate them. The first argument of the macro is the
|
||||
// test case name; the rest are the names of the tests in this test
|
||||
// case.
|
||||
REGISTER_TYPED_TEST_CASE_P(FooTest, |
||||
DoesBlah, HasPropertyA); |
||||
|
||||
// Finally, you are free to instantiate the pattern with the types you
|
||||
// want. If you put the above code in a header file, you can #include
|
||||
// it in multiple C++ source files and instantiate it multiple times.
|
||||
//
|
||||
// To distinguish different instances of the pattern, the first
|
||||
// argument to the INSTANTIATE_* macro is a prefix that will be added
|
||||
// to the actual test case name. Remember to pick unique prefixes for
|
||||
// different instances.
|
||||
typedef testing::Types<char, int, unsigned int> MyTypes; |
||||
INSTANTIATE_TYPED_TEST_CASE_P(My, FooTest, MyTypes); |
||||
|
||||
// If the type list contains only one type, you can write that type
|
||||
// directly without Types<...>:
|
||||
// INSTANTIATE_TYPED_TEST_CASE_P(My, FooTest, int);
|
||||
|
||||
#endif // 0
|
||||
|
||||
#include <gtest/internal/gtest-port.h> |
||||
#include <gtest/internal/gtest-type-util.h> |
||||
|
||||
// Implements typed tests.
|
||||
|
||||
#ifdef GTEST_HAS_TYPED_TEST |
||||
|
||||
// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
|
||||
//
|
||||
// Expands to the name of the typedef for the type parameters of the
|
||||
// given test case.
|
||||
#define GTEST_TYPE_PARAMS_(TestCaseName) gtest_type_params_##TestCaseName##_ |
||||
|
||||
#define TYPED_TEST_CASE(CaseName, Types) \ |
||||
typedef ::testing::internal::TypeList<Types>::type \
|
||||
GTEST_TYPE_PARAMS_(CaseName) |
||||
|
||||
#define TYPED_TEST(CaseName, TestName) \ |
||||
template <typename gtest_TypeParam_> \
|
||||
class GTEST_TEST_CLASS_NAME_(CaseName, TestName) \
|
||||
: public CaseName<gtest_TypeParam_> { \
|
||||
private: \
|
||||
typedef CaseName<gtest_TypeParam_> TestFixture; \
|
||||
typedef gtest_TypeParam_ TypeParam; \
|
||||
virtual void TestBody(); \
|
||||
}; \
|
||||
bool gtest_##CaseName##_##TestName##_registered_ = \
|
||||
::testing::internal::TypeParameterizedTest< \
|
||||
CaseName, \
|
||||
::testing::internal::TemplateSel< \
|
||||
GTEST_TEST_CLASS_NAME_(CaseName, TestName)>, \
|
||||
GTEST_TYPE_PARAMS_(CaseName)>::Register(\
|
||||
"", #CaseName, #TestName, 0); \
|
||||
template <typename gtest_TypeParam_> \
|
||||
void GTEST_TEST_CLASS_NAME_(CaseName, TestName)<gtest_TypeParam_>::TestBody() |
||||
|
||||
#endif // GTEST_HAS_TYPED_TEST
|
||||
|
||||
// Implements type-parameterized tests.
|
||||
|
||||
#ifdef GTEST_HAS_TYPED_TEST_P |
||||
|
||||
// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
|
||||
//
|
||||
// Expands to the namespace name that the type-parameterized tests for
|
||||
// the given type-parameterized test case are defined in. The exact
|
||||
// name of the namespace is subject to change without notice.
|
||||
#define GTEST_CASE_NAMESPACE_(TestCaseName) \ |
||||
gtest_case_##TestCaseName##_ |
||||
|
||||
// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
|
||||
//
|
||||
// Expands to the name of the variable used to remember the names of
|
||||
// the defined tests in the given test case.
|
||||
#define GTEST_TYPED_TEST_CASE_P_STATE_(TestCaseName) \ |
||||
gtest_typed_test_case_p_state_##TestCaseName##_ |
||||
|
||||
// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE DIRECTLY.
|
||||
//
|
||||
// Expands to the name of the variable used to remember the names of
|
||||
// the registered tests in the given test case.
|
||||
#define GTEST_REGISTERED_TEST_NAMES_(TestCaseName) \ |
||||
gtest_registered_test_names_##TestCaseName##_ |
||||
|
||||
// The variables defined in the type-parameterized test macros are
|
||||
// static as typically these macros are used in a .h file that can be
|
||||
// #included in multiple translation units linked together.
|
||||
#define TYPED_TEST_CASE_P(CaseName) \ |
||||
static ::testing::internal::TypedTestCasePState \
|
||||
GTEST_TYPED_TEST_CASE_P_STATE_(CaseName) |
||||
|
||||
#define TYPED_TEST_P(CaseName, TestName) \ |
||||
namespace GTEST_CASE_NAMESPACE_(CaseName) { \
|
||||
template <typename gtest_TypeParam_> \
|
||||
class TestName : public CaseName<gtest_TypeParam_> { \
|
||||
private: \
|
||||
typedef CaseName<gtest_TypeParam_> TestFixture; \
|
||||
typedef gtest_TypeParam_ TypeParam; \
|
||||
virtual void TestBody(); \
|
||||
}; \
|
||||
static bool gtest_##TestName##_defined_ = \
|
||||
GTEST_TYPED_TEST_CASE_P_STATE_(CaseName).AddTestName(\
|
||||
__FILE__, __LINE__, #CaseName, #TestName); \
|
||||
} \
|
||||
template <typename gtest_TypeParam_> \
|
||||
void GTEST_CASE_NAMESPACE_(CaseName)::TestName<gtest_TypeParam_>::TestBody() |
||||
|
||||
#define REGISTER_TYPED_TEST_CASE_P(CaseName, ...) \ |
||||
namespace GTEST_CASE_NAMESPACE_(CaseName) { \
|
||||
typedef ::testing::internal::Templates<__VA_ARGS__>::type gtest_AllTests_; \
|
||||
} \
|
||||
static const char* const GTEST_REGISTERED_TEST_NAMES_(CaseName) = \
|
||||
GTEST_TYPED_TEST_CASE_P_STATE_(CaseName).VerifyRegisteredTestNames(\
|
||||
__FILE__, __LINE__, #__VA_ARGS__) |
||||
|
||||
#define INSTANTIATE_TYPED_TEST_CASE_P(Prefix, CaseName, Types) \ |
||||
bool gtest_##Prefix##_##CaseName = \
|
||||
::testing::internal::TypeParameterizedTestCase<CaseName, \
|
||||
GTEST_CASE_NAMESPACE_(CaseName)::gtest_AllTests_, \
|
||||
::testing::internal::TypeList<Types>::type>::Register(\
|
||||
#Prefix, #CaseName, GTEST_REGISTERED_TEST_NAMES_(CaseName)) |
||||
|
||||
#endif // GTEST_HAS_TYPED_TEST_P
|
||||
|
||||
#endif // GTEST_INCLUDE_GTEST_GTEST_TYPED_TEST_H_
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,281 @@ |
||||
$$ -*- mode: c++; -*- |
||||
$var n = 50 $$ Maximum length of type lists we want to support. |
||||
// Copyright 2008 Google Inc. |
||||
// All Rights Reserved. |
||||
// |
||||
// Redistribution and use in source and binary forms, with or without |
||||
// modification, are permitted provided that the following conditions are |
||||
// met: |
||||
// |
||||
// * Redistributions of source code must retain the above copyright |
||||
// notice, this list of conditions and the following disclaimer. |
||||
// * Redistributions in binary form must reproduce the above |
||||
// copyright notice, this list of conditions and the following disclaimer |
||||
// in the documentation and/or other materials provided with the |
||||
// distribution. |
||||
// * Neither the name of Google Inc. nor the names of its |
||||
// contributors may be used to endorse or promote products derived from |
||||
// this software without specific prior written permission. |
||||
// |
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
||||
// |
||||
// Author: wan@google.com (Zhanyong Wan) |
||||
|
||||
// Type utilities needed for implementing typed and type-parameterized |
||||
// tests. This file is generated by a SCRIPT. DO NOT EDIT BY HAND! |
||||
// |
||||
// Currently we support at most $n types in a list, and at most $n |
||||
// type-parameterized tests in one type-parameterized test case. |
||||
// Please contact googletestframework@googlegroups.com if you need |
||||
// more. |
||||
|
||||
#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_TYPE_UTIL_H_ |
||||
#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_TYPE_UTIL_H_ |
||||
|
||||
#include <gtest/internal/gtest-port.h> |
||||
#include <gtest/internal/gtest-string.h> |
||||
|
||||
#if defined(GTEST_HAS_TYPED_TEST) || defined(GTEST_HAS_TYPED_TEST_P) |
||||
|
||||
#ifdef __GNUC__ |
||||
#include <cxxabi.h> |
||||
#endif // __GNUC__ |
||||
|
||||
#include <typeinfo> |
||||
|
||||
namespace testing { |
||||
namespace internal { |
||||
|
||||
// AssertyTypeEq<T1, T2>::type is defined iff T1 and T2 are the same |
||||
// type. This can be used as a compile-time assertion to ensure that |
||||
// two types are equal. |
||||
|
||||
template <typename T1, typename T2> |
||||
struct AssertTypeEq; |
||||
|
||||
template <typename T> |
||||
struct AssertTypeEq<T, T> { |
||||
typedef bool type; |
||||
}; |
||||
|
||||
// GetTypeName<T>() returns a human-readable name of type T. |
||||
template <typename T> |
||||
String GetTypeName() { |
||||
const char* const name = typeid(T).name(); |
||||
#ifdef __GNUC__ |
||||
int status = 0; |
||||
// gcc's implementation of typeid(T).name() mangles the type name, |
||||
// so we have to demangle it. |
||||
char* const readable_name = abi::__cxa_demangle(name, 0, 0, &status); |
||||
const String name_str(status == 0 ? readable_name : name); |
||||
free(readable_name); |
||||
return name_str; |
||||
#else |
||||
return name; |
||||
#endif // __GNUC__ |
||||
} |
||||
|
||||
// A unique type used as the default value for the arguments of class |
||||
// template Types. This allows us to simulate variadic templates |
||||
// (e.g. Types<int>, Type<int, double>, and etc), which C++ doesn't |
||||
// support directly. |
||||
struct None {}; |
||||
|
||||
// The following family of struct and struct templates are used to |
||||
// represent type lists. In particular, TypesN<T1, T2, ..., TN> |
||||
// represents a type list with N types (T1, T2, ..., and TN) in it. |
||||
// Except for Types0, every struct in the family has two member types: |
||||
// Head for the first type in the list, and Tail for the rest of the |
||||
// list. |
||||
|
||||
// The empty type list. |
||||
struct Types0 {}; |
||||
|
||||
// Type lists of length 1, 2, 3, and so on. |
||||
|
||||
template <typename T1> |
||||
struct Types1 { |
||||
typedef T1 Head; |
||||
typedef Types0 Tail; |
||||
}; |
||||
|
||||
$range i 2..n |
||||
|
||||
$for i [[ |
||||
$range j 1..i |
||||
$range k 2..i |
||||
template <$for j, [[typename T$j]]> |
||||
struct Types$i { |
||||
typedef T1 Head; |
||||
typedef Types$(i-1)<$for k, [[T$k]]> Tail; |
||||
}; |
||||
|
||||
|
||||
]] |
||||
|
||||
} // namespace internal |
||||
|
||||
// We don't want to require the users to write TypesN<...> directly, |
||||
// as that would require them to count the length. Types<...> is much |
||||
// easier to write, but generates horrible messages when there is a |
||||
// compiler error, as gcc insists on printing out each template |
||||
// argument, even if it has the default value (this means Types<int> |
||||
// will appear as Types<int, None, None, ..., None> in the compiler |
||||
// errors). |
||||
// |
||||
// Our solution is to combine the best part of the two approaches: a |
||||
// user would write Types<T1, ..., TN>, and Google Test will translate |
||||
// that to TypesN<T1, ..., TN> internally to make error messages |
||||
// readable. The translation is done by the 'type' member of the |
||||
// Types template. |
||||
|
||||
$range i 1..n |
||||
template <$for i, [[typename T$i = internal::None]]> |
||||
struct Types { |
||||
typedef internal::Types$n<$for i, [[T$i]]> type; |
||||
}; |
||||
|
||||
template <> |
||||
struct Types<$for i, [[internal::None]]> { |
||||
typedef internal::Types0 type; |
||||
}; |
||||
|
||||
$range i 1..n-1 |
||||
$for i [[ |
||||
$range j 1..i |
||||
$range k i+1..n |
||||
template <$for j, [[typename T$j]]> |
||||
struct Types<$for j, [[T$j]]$for k[[, internal::None]]> { |
||||
typedef internal::Types$i<$for j, [[T$j]]> type; |
||||
}; |
||||
|
||||
]] |
||||
|
||||
namespace internal { |
||||
|
||||
#define GTEST_TEMPLATE_ template <typename T> class |
||||
|
||||
// The template "selector" struct TemplateSel<Tmpl> is used to |
||||
// represent Tmpl, which must be a class template with one type |
||||
// parameter, as a type. TemplateSel<Tmpl>::Bind<T>::type is defined |
||||
// as the type Tmpl<T>. This allows us to actually instantiate the |
||||
// template "selected" by TemplateSel<Tmpl>. |
||||
// |
||||
// This trick is necessary for simulating typedef for class templates, |
||||
// which C++ doesn't support directly. |
||||
template <GTEST_TEMPLATE_ Tmpl> |
||||
struct TemplateSel { |
||||
template <typename T> |
||||
struct Bind { |
||||
typedef Tmpl<T> type; |
||||
}; |
||||
}; |
||||
|
||||
#define GTEST_BIND_(TmplSel, T) \ |
||||
TmplSel::template Bind<T>::type |
||||
|
||||
// A unique struct template used as the default value for the |
||||
// arguments of class template Templates. This allows us to simulate |
||||
// variadic templates (e.g. Templates<int>, Templates<int, double>, |
||||
// and etc), which C++ doesn't support directly. |
||||
template <typename T> |
||||
struct NoneT {}; |
||||
|
||||
// The following family of struct and struct templates are used to |
||||
// represent template lists. In particular, TemplatesN<T1, T2, ..., |
||||
// TN> represents a list of N templates (T1, T2, ..., and TN). Except |
||||
// for Templates0, every struct in the family has two member types: |
||||
// Head for the selector of the first template in the list, and Tail |
||||
// for the rest of the list. |
||||
|
||||
// The empty template list. |
||||
struct Templates0 {}; |
||||
|
||||
// Template lists of length 1, 2, 3, and so on. |
||||
|
||||
template <GTEST_TEMPLATE_ T1> |
||||
struct Templates1 { |
||||
typedef TemplateSel<T1> Head; |
||||
typedef Templates0 Tail; |
||||
}; |
||||
|
||||
$range i 2..n |
||||
|
||||
$for i [[ |
||||
$range j 1..i |
||||
$range k 2..i |
||||
template <$for j, [[GTEST_TEMPLATE_ T$j]]> |
||||
struct Templates$i { |
||||
typedef TemplateSel<T1> Head; |
||||
typedef Templates$(i-1)<$for k, [[T$k]]> Tail; |
||||
}; |
||||
|
||||
|
||||
]] |
||||
|
||||
// We don't want to require the users to write TemplatesN<...> directly, |
||||
// as that would require them to count the length. Templates<...> is much |
||||
// easier to write, but generates horrible messages when there is a |
||||
// compiler error, as gcc insists on printing out each template |
||||
// argument, even if it has the default value (this means Templates<list> |
||||
// will appear as Templates<list, NoneT, NoneT, ..., NoneT> in the compiler |
||||
// errors). |
||||
// |
||||
// Our solution is to combine the best part of the two approaches: a |
||||
// user would write Templates<T1, ..., TN>, and Google Test will translate |
||||
// that to TemplatesN<T1, ..., TN> internally to make error messages |
||||
// readable. The translation is done by the 'type' member of the |
||||
// Templates template. |
||||
|
||||
$range i 1..n |
||||
template <$for i, [[GTEST_TEMPLATE_ T$i = NoneT]]> |
||||
struct Templates { |
||||
typedef Templates$n<$for i, [[T$i]]> type; |
||||
}; |
||||
|
||||
template <> |
||||
struct Templates<$for i, [[NoneT]]> { |
||||
typedef Templates0 type; |
||||
}; |
||||
|
||||
$range i 1..n-1 |
||||
$for i [[ |
||||
$range j 1..i |
||||
$range k i+1..n |
||||
template <$for j, [[GTEST_TEMPLATE_ T$j]]> |
||||
struct Templates<$for j, [[T$j]]$for k[[, NoneT]]> { |
||||
typedef Templates$i<$for j, [[T$j]]> type; |
||||
}; |
||||
|
||||
]] |
||||
|
||||
// The TypeList template makes it possible to use either a single type |
||||
// or a Types<...> list in TYPED_TEST_CASE() and |
||||
// INSTANTIATE_TYPED_TEST_CASE_P(). |
||||
|
||||
template <typename T> |
||||
struct TypeList { typedef Types1<T> type; }; |
||||
|
||||
|
||||
$range i 1..n |
||||
template <$for i, [[typename T$i]]> |
||||
struct TypeList<Types<$for i, [[T$i]]> > { |
||||
typedef typename Types<$for i, [[T$i]]>::type type; |
||||
}; |
||||
|
||||
} // namespace internal |
||||
} // namespace testing |
||||
|
||||
#endif // GTEST_HAS_TYPED_TEST || GTEST_HAS_TYPED_TEST_P |
||||
|
||||
#endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_TYPE_UTIL_H_ |
@ -0,0 +1,301 @@ |
||||
// Copyright 2008 Google Inc.
|
||||
// All Rights Reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Author: wan@google.com (Zhanyong Wan)
|
||||
|
||||
// This sample shows how to test common properties of multiple
|
||||
// implementations of the same interface (aka interface tests). We
|
||||
// put the code to be tested and the tests in the same file for
|
||||
// simplicity.
|
||||
|
||||
#include <vector> |
||||
#include <gtest/gtest.h> |
||||
|
||||
// Section 1. the interface and its implementations.
|
||||
|
||||
// The prime table interface.
|
||||
class PrimeTable { |
||||
public: |
||||
virtual ~PrimeTable() {} |
||||
|
||||
// Returns true iff n is a prime number.
|
||||
virtual bool IsPrime(int n) const = 0; |
||||
|
||||
// Returns the smallest prime number greater than p; or returns -1
|
||||
// if the next prime is beyond the capacity of the table.
|
||||
virtual int GetNextPrime(int p) const = 0; |
||||
}; |
||||
|
||||
// Implementation #1 calculates the primes on-the-fly.
|
||||
class OnTheFlyPrimeTable : public PrimeTable { |
||||
public: |
||||
virtual bool IsPrime(int n) const { |
||||
if (n <= 1) return false; |
||||
|
||||
for (int i = 2; i*i <= n; i++) { |
||||
// n is divisible by an integer other than 1 and itself.
|
||||
if ((n % i) == 0) return false; |
||||
} |
||||
|
||||
return true; |
||||
} |
||||
|
||||
virtual int GetNextPrime(int p) const { |
||||
for (int n = p + 1; n > 0; n++) { |
||||
if (IsPrime(n)) return n; |
||||
} |
||||
|
||||
return -1; |
||||
} |
||||
}; |
||||
|
||||
// Implementation #2 pre-calculates the primes and stores the result
|
||||
// in a vector.
|
||||
class PreCalculatedPrimeTable : public PrimeTable { |
||||
public: |
||||
// 'max' specifies the maximum number the prime table holds.
|
||||
explicit PreCalculatedPrimeTable(int max) : is_prime_(max + 1) { |
||||
CalculatePrimesUpTo(max); |
||||
} |
||||
|
||||
virtual bool IsPrime(int n) const { |
||||
return 0 <= n && n < is_prime_.size() && is_prime_[n]; |
||||
} |
||||
|
||||
virtual int GetNextPrime(int p) const { |
||||
for (int n = p + 1; n < is_prime_.size(); n++) { |
||||
if (is_prime_[n]) return n; |
||||
} |
||||
|
||||
return -1; |
||||
} |
||||
|
||||
private: |
||||
void CalculatePrimesUpTo(int max) { |
||||
fill(is_prime_.begin(), is_prime_.end(), true); |
||||
is_prime_[0] = is_prime_[1] = false; |
||||
|
||||
for (int i = 2; i <= max; i++) { |
||||
if (!is_prime_[i]) continue; |
||||
|
||||
// Marks all multiples of i (except i itself) as non-prime.
|
||||
for (int j = 2*i; j <= max; j += i) { |
||||
is_prime_[j] = false; |
||||
} |
||||
} |
||||
} |
||||
|
||||
std::vector<bool> is_prime_; |
||||
}; |
||||
|
||||
// Sections 2. the tests.
|
||||
|
||||
// First, we define some factory functions for creating instances of
|
||||
// the implementations. You may be able to skip this step if all your
|
||||
// implementations can be constructed the same way.
|
||||
|
||||
template <class T> |
||||
PrimeTable* CreatePrimeTable(); |
||||
|
||||
template <> |
||||
PrimeTable* CreatePrimeTable<OnTheFlyPrimeTable>() { |
||||
return new OnTheFlyPrimeTable; |
||||
} |
||||
|
||||
template <> |
||||
PrimeTable* CreatePrimeTable<PreCalculatedPrimeTable>() { |
||||
return new PreCalculatedPrimeTable(10000); |
||||
} |
||||
|
||||
// Then we define a test fixture class template.
|
||||
template <class T> |
||||
class PrimeTableTest : public testing::Test { |
||||
protected: |
||||
// The ctor calls the factory function to create a prime table
|
||||
// implemented by T.
|
||||
PrimeTableTest() : table_(CreatePrimeTable<T>()) {} |
||||
|
||||
virtual ~PrimeTableTest() { delete table_; } |
||||
|
||||
// Note that we test an implementation via the base interface
|
||||
// instead of the actual implementation class. This is important
|
||||
// for keeping the tests close to the real world scenario, where the
|
||||
// implementation is invoked via the base interface. It avoids
|
||||
// got-yas where the implementation class has a method that shadows
|
||||
// a method with the same name (but slightly different argument
|
||||
// types) in the base interface, for example.
|
||||
PrimeTable* const table_; |
||||
}; |
||||
|
||||
using testing::Types; |
||||
|
||||
#ifdef GTEST_HAS_TYPED_TEST |
||||
|
||||
// Google Test offers two ways for reusing tests for different types.
|
||||
// The first is called "typed tests". You should use it if you
|
||||
// already know *all* the types you are gonna exercise when you write
|
||||
// the tests.
|
||||
|
||||
// To write a typed test case, first use
|
||||
//
|
||||
// TYPED_TEST_CASE(TestCaseName, TypeList);
|
||||
//
|
||||
// to declare it and specify the type parameters. As with TEST_F,
|
||||
// TestCaseName must match the test fixture name.
|
||||
|
||||
// The list of types we want to test.
|
||||
typedef Types<OnTheFlyPrimeTable, PreCalculatedPrimeTable> Implementations; |
||||
|
||||
TYPED_TEST_CASE(PrimeTableTest, Implementations); |
||||
|
||||
// Then use TYPED_TEST(TestCaseName, TestName) to define a typed test,
|
||||
// similar to TEST_F.
|
||||
TYPED_TEST(PrimeTableTest, ReturnsFalseForNonPrimes) { |
||||
// Inside the test body, you can refer to the type parameter by
|
||||
// TypeParam, and refer to the fixture class by TestFixture. We
|
||||
// don't need them in this example.
|
||||
|
||||
// Since we are in the template world, C++ requires explicitly
|
||||
// writing 'this->' when referring to members of the fixture class.
|
||||
// This is something you have to learn to live with.
|
||||
EXPECT_FALSE(this->table_->IsPrime(-5)); |
||||
EXPECT_FALSE(this->table_->IsPrime(0)); |
||||
EXPECT_FALSE(this->table_->IsPrime(1)); |
||||
EXPECT_FALSE(this->table_->IsPrime(4)); |
||||
EXPECT_FALSE(this->table_->IsPrime(6)); |
||||
EXPECT_FALSE(this->table_->IsPrime(100)); |
||||
} |
||||
|
||||
TYPED_TEST(PrimeTableTest, ReturnsTrueForPrimes) { |
||||
EXPECT_TRUE(this->table_->IsPrime(2)); |
||||
EXPECT_TRUE(this->table_->IsPrime(3)); |
||||
EXPECT_TRUE(this->table_->IsPrime(5)); |
||||
EXPECT_TRUE(this->table_->IsPrime(7)); |
||||
EXPECT_TRUE(this->table_->IsPrime(11)); |
||||
EXPECT_TRUE(this->table_->IsPrime(131)); |
||||
} |
||||
|
||||
TYPED_TEST(PrimeTableTest, CanGetNextPrime) { |
||||
EXPECT_EQ(2, this->table_->GetNextPrime(0)); |
||||
EXPECT_EQ(3, this->table_->GetNextPrime(2)); |
||||
EXPECT_EQ(5, this->table_->GetNextPrime(3)); |
||||
EXPECT_EQ(7, this->table_->GetNextPrime(5)); |
||||
EXPECT_EQ(11, this->table_->GetNextPrime(7)); |
||||
EXPECT_EQ(131, this->table_->GetNextPrime(128)); |
||||
} |
||||
|
||||
// That's it! Google Test will repeat each TYPED_TEST for each type
|
||||
// in the type list specified in TYPED_TEST_CASE. Sit back and be
|
||||
// happy that you don't have to define them multiple times.
|
||||
|
||||
#endif // GTEST_HAS_TYPED_TEST
|
||||
|
||||
#ifdef GTEST_HAS_TYPED_TEST_P |
||||
|
||||
// Sometimes, however, you don't yet know all the types that you want
|
||||
// to test when you write the tests. For example, if you are the
|
||||
// author of an interface and expect other people to implement it, you
|
||||
// might want to write a set of tests to make sure each implementation
|
||||
// conforms to some basic requirements, but you don't know what
|
||||
// implementations will be written in the future.
|
||||
//
|
||||
// How can you write the tests without committing to the type
|
||||
// parameters? That's what "type-parameterized tests" can do for you.
|
||||
// It is a bit more involved than typed tests, but in return you get a
|
||||
// test pattern that can be reused in many contexts, which is a big
|
||||
// win. Here's how you do it:
|
||||
|
||||
// First, define a test fixture class template. Here we just reuse
|
||||
// the PrimeTableTest fixture defined earlier:
|
||||
|
||||
template <class T> |
||||
class PrimeTableTest2 : public PrimeTableTest<T> { |
||||
}; |
||||
|
||||
// Then, declare the test case. The argument is the name of the test
|
||||
// fixture, and also the name of the test case (as usual). The _P
|
||||
// suffix is for "parameterized" or "pattern".
|
||||
TYPED_TEST_CASE_P(PrimeTableTest2); |
||||
|
||||
// Next, use TYPED_TEST_P(TestCaseName, TestName) to define a test,
|
||||
// similar to what you do with TEST_F.
|
||||
TYPED_TEST_P(PrimeTableTest2, ReturnsFalseForNonPrimes) { |
||||
EXPECT_FALSE(this->table_->IsPrime(-5)); |
||||
EXPECT_FALSE(this->table_->IsPrime(0)); |
||||
EXPECT_FALSE(this->table_->IsPrime(1)); |
||||
EXPECT_FALSE(this->table_->IsPrime(4)); |
||||
EXPECT_FALSE(this->table_->IsPrime(6)); |
||||
EXPECT_FALSE(this->table_->IsPrime(100)); |
||||
} |
||||
|
||||
TYPED_TEST_P(PrimeTableTest2, ReturnsTrueForPrimes) { |
||||
EXPECT_TRUE(this->table_->IsPrime(2)); |
||||
EXPECT_TRUE(this->table_->IsPrime(3)); |
||||
EXPECT_TRUE(this->table_->IsPrime(5)); |
||||
EXPECT_TRUE(this->table_->IsPrime(7)); |
||||
EXPECT_TRUE(this->table_->IsPrime(11)); |
||||
EXPECT_TRUE(this->table_->IsPrime(131)); |
||||
} |
||||
|
||||
TYPED_TEST_P(PrimeTableTest2, CanGetNextPrime) { |
||||
EXPECT_EQ(2, this->table_->GetNextPrime(0)); |
||||
EXPECT_EQ(3, this->table_->GetNextPrime(2)); |
||||
EXPECT_EQ(5, this->table_->GetNextPrime(3)); |
||||
EXPECT_EQ(7, this->table_->GetNextPrime(5)); |
||||
EXPECT_EQ(11, this->table_->GetNextPrime(7)); |
||||
EXPECT_EQ(131, this->table_->GetNextPrime(128)); |
||||
} |
||||
|
||||
// Type-parameterized tests involve one extra step: you have to
|
||||
// enumerate the tests you defined:
|
||||
REGISTER_TYPED_TEST_CASE_P( |
||||
PrimeTableTest2, // The first argument is the test case name.
|
||||
// The rest of the arguments are the test names.
|
||||
ReturnsFalseForNonPrimes, ReturnsTrueForPrimes, CanGetNextPrime); |
||||
|
||||
// At this point the test pattern is done. However, you don't have
|
||||
// any real test yet as you haven't said which types you want to run
|
||||
// the tests with.
|
||||
|
||||
// To turn the abstract test pattern into real tests, you instantiate
|
||||
// it with a list of types. Usually the test pattern will be defined
|
||||
// in a .h file, and anyone can #include and instantiate it. You can
|
||||
// even instantiate it more than once in the same program. To tell
|
||||
// different instances apart, you give each of them a name, which will
|
||||
// become part of the test case name and can be used in test filters.
|
||||
|
||||
// The list of types we want to test. Note that it doesn't have to be
|
||||
// defined at the time we write the TYPED_TEST_P()s.
|
||||
typedef Types<OnTheFlyPrimeTable, PreCalculatedPrimeTable> |
||||
PrimeTableImplementations; |
||||
INSTANTIATE_TYPED_TEST_CASE_P(OnTheFlyAndPreCalculated, // Instance name
|
||||
PrimeTableTest2, // Test case name
|
||||
PrimeTableImplementations); // Type list
|
||||
|
||||
#endif // GTEST_HAS_TYPED_TEST_P
|
@ -0,0 +1,97 @@ |
||||
// Copyright 2008 Google Inc.
|
||||
// All Rights Reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Author: wan@google.com (Zhanyong Wan)
|
||||
|
||||
#include <gtest/gtest-typed-test.h> |
||||
#include <gtest/gtest.h> |
||||
|
||||
namespace testing { |
||||
namespace internal { |
||||
|
||||
#ifdef GTEST_HAS_TYPED_TEST_P |
||||
|
||||
// Verifies that registered_tests match the test names in
|
||||
// defined_test_names_; returns registered_tests if successful, or
|
||||
// aborts the program otherwise.
|
||||
const char* TypedTestCasePState::VerifyRegisteredTestNames( |
||||
const char* file, int line, const char* registered_tests) { |
||||
typedef ::std::set<const char*>::const_iterator DefinedTestIter; |
||||
registered_ = true; |
||||
|
||||
Message errors; |
||||
::std::set<String> tests; |
||||
for (const char* names = registered_tests; names != NULL; |
||||
names = SkipComma(names)) { |
||||
const String name = GetPrefixUntilComma(names); |
||||
if (tests.count(name) != 0) { |
||||
errors << "Test " << name << " is listed more than once.\n"; |
||||
continue; |
||||
} |
||||
|
||||
bool found = false; |
||||
for (DefinedTestIter it = defined_test_names_.begin(); |
||||
it != defined_test_names_.end(); |
||||
++it) { |
||||
if (name == *it) { |
||||
found = true; |
||||
break; |
||||
} |
||||
} |
||||
|
||||
if (found) { |
||||
tests.insert(name); |
||||
} else { |
||||
errors << "No test named " << name |
||||
<< " can be found in this test case.\n"; |
||||
} |
||||
} |
||||
|
||||
for (DefinedTestIter it = defined_test_names_.begin(); |
||||
it != defined_test_names_.end(); |
||||
++it) { |
||||
if (tests.count(*it) == 0) { |
||||
errors << "You forgot to list test " << *it << ".\n"; |
||||
} |
||||
} |
||||
|
||||
const String& errors_str = errors.GetString(); |
||||
if (errors_str != "") { |
||||
fprintf(stderr, "%s %s", FormatFileLocation(file, line).c_str(), |
||||
errors_str.c_str()); |
||||
abort(); |
||||
} |
||||
|
||||
return registered_tests; |
||||
} |
||||
|
||||
#endif // GTEST_HAS_TYPED_TEST_P
|
||||
|
||||
} // namespace internal
|
||||
} // namespace testing
|
@ -0,0 +1,45 @@ |
||||
// Copyright 2008 Google Inc.
|
||||
// All Rights Reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Author: wan@google.com (Zhanyong Wan)
|
||||
|
||||
#include <vector> |
||||
|
||||
#include "test/gtest-typed-test_test.h" |
||||
#include <gtest/gtest.h> |
||||
|
||||
#ifdef GTEST_HAS_TYPED_TEST_P |
||||
|
||||
// Tests that the same type-parameterized test case can be
|
||||
// instantiated in different translation units linked together.
|
||||
// (ContainerTest is also instantiated in gtest-typed-test_test.cc.)
|
||||
INSTANTIATE_TYPED_TEST_CASE_P(Vector, ContainerTest, |
||||
testing::Types<std::vector<int> >); |
||||
|
||||
#endif // GTEST_HAS_TYPED_TEST_P
|
@ -0,0 +1,350 @@ |
||||
// Copyright 2008 Google Inc.
|
||||
// All Rights Reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Author: wan@google.com (Zhanyong Wan)
|
||||
|
||||
#include <list> |
||||
#include <set> |
||||
|
||||
#include "test/gtest-typed-test_test.h" |
||||
#include <gtest/gtest.h> |
||||
|
||||
using testing::Test; |
||||
|
||||
// Used for testing that SetUpTestCase()/TearDownTestCase(), fixture
|
||||
// ctor/dtor, and SetUp()/TearDown() work correctly in typed tests and
|
||||
// type-parameterized test.
|
||||
template <typename T> |
||||
class CommonTest : public Test { |
||||
// For some technical reason, SetUpTestCase() and TearDownTestCase()
|
||||
// must be public.
|
||||
public: |
||||
static void SetUpTestCase() { |
||||
shared_ = new T(5); |
||||
} |
||||
|
||||
static void TearDownTestCase() { |
||||
delete shared_; |
||||
shared_ = NULL; |
||||
} |
||||
|
||||
// This 'protected:' is optional. There's no harm in making all
|
||||
// members of this fixture class template public.
|
||||
protected: |
||||
typedef std::list<T> List; |
||||
typedef std::set<int> IntSet; |
||||
|
||||
CommonTest() : value_(1) {} |
||||
|
||||
virtual ~CommonTest() { EXPECT_EQ(3, value_); } |
||||
|
||||
virtual void SetUp() { |
||||
EXPECT_EQ(1, value_); |
||||
value_++; |
||||
} |
||||
|
||||
virtual void TearDown() { |
||||
EXPECT_EQ(2, value_); |
||||
value_++; |
||||
} |
||||
|
||||
T value_; |
||||
static T* shared_; |
||||
}; |
||||
|
||||
template <typename T> |
||||
T* CommonTest<T>::shared_ = NULL; |
||||
|
||||
// This #ifdef block tests typed tests.
|
||||
#ifdef GTEST_HAS_TYPED_TEST |
||||
|
||||
using testing::Types; |
||||
|
||||
// Tests that SetUpTestCase()/TearDownTestCase(), fixture ctor/dtor,
|
||||
// and SetUp()/TearDown() work correctly in typed tests
|
||||
|
||||
typedef Types<char, int> TwoTypes; |
||||
TYPED_TEST_CASE(CommonTest, TwoTypes); |
||||
|
||||
TYPED_TEST(CommonTest, ValuesAreCorrect) { |
||||
// Static members of the fixture class template can be visited via
|
||||
// the TestFixture:: prefix.
|
||||
EXPECT_EQ(5, *TestFixture::shared_); |
||||
|
||||
// Typedefs in the fixture class template can be visited via the
|
||||
// "typename TestFixture::" prefix.
|
||||
typename TestFixture::List empty; |
||||
EXPECT_EQ(0, empty.size()); |
||||
|
||||
typename TestFixture::IntSet empty2; |
||||
EXPECT_EQ(0, empty2.size()); |
||||
|
||||
// Non-static members of the fixture class must be visited via
|
||||
// 'this', as required by C++ for class templates.
|
||||
EXPECT_EQ(2, this->value_); |
||||
} |
||||
|
||||
// The second test makes sure shared_ is not deleted after the first
|
||||
// test.
|
||||
TYPED_TEST(CommonTest, ValuesAreStillCorrect) { |
||||
// Static members of the fixture class template can also be visited
|
||||
// via 'this'.
|
||||
ASSERT_TRUE(this->shared_ != NULL); |
||||
EXPECT_EQ(5, *this->shared_); |
||||
|
||||
// TypeParam can be used to refer to the type parameter.
|
||||
EXPECT_EQ(static_cast<TypeParam>(2), this->value_); |
||||
} |
||||
|
||||
// Tests that multiple TYPED_TEST_CASE's can be defined in the same
|
||||
// translation unit.
|
||||
|
||||
template <typename T> |
||||
class TypedTest1 : public Test { |
||||
}; |
||||
|
||||
// Verifies that the second argument of TYPED_TEST_CASE can be a
|
||||
// single type.
|
||||
TYPED_TEST_CASE(TypedTest1, int); |
||||
TYPED_TEST(TypedTest1, A) {} |
||||
|
||||
template <typename T> |
||||
class TypedTest2 : public Test { |
||||
}; |
||||
|
||||
// Verifies that the second argument of TYPED_TEST_CASE can be a
|
||||
// Types<...> type list.
|
||||
TYPED_TEST_CASE(TypedTest2, Types<int>); |
||||
|
||||
// This also verifies that tests from different typed test cases can
|
||||
// share the same name.
|
||||
TYPED_TEST(TypedTest2, A) {} |
||||
|
||||
// Tests that a typed test case can be defined in a namespace.
|
||||
|
||||
namespace library1 { |
||||
|
||||
template <typename T> |
||||
class NumericTest : public Test { |
||||
}; |
||||
|
||||
typedef Types<int, long> NumericTypes; |
||||
TYPED_TEST_CASE(NumericTest, NumericTypes); |
||||
|
||||
TYPED_TEST(NumericTest, DefaultIsZero) { |
||||
EXPECT_EQ(0, TypeParam()); |
||||
} |
||||
|
||||
} // namespace library1
|
||||
|
||||
#endif // GTEST_HAS_TYPED_TEST
|
||||
|
||||
// This #ifdef block tests type-parameterized tests.
|
||||
#ifdef GTEST_HAS_TYPED_TEST_P |
||||
|
||||
using testing::Types; |
||||
using testing::internal::TypedTestCasePState; |
||||
|
||||
// Tests TypedTestCasePState.
|
||||
|
||||
class TypedTestCasePStateTest : public Test { |
||||
protected: |
||||
virtual void SetUp() { |
||||
state_.AddTestName("foo.cc", 0, "FooTest", "A"); |
||||
state_.AddTestName("foo.cc", 0, "FooTest", "B"); |
||||
state_.AddTestName("foo.cc", 0, "FooTest", "C"); |
||||
} |
||||
|
||||
TypedTestCasePState state_; |
||||
}; |
||||
|
||||
TEST_F(TypedTestCasePStateTest, SucceedsForMatchingList) { |
||||
const char* tests = "A, B, C"; |
||||
EXPECT_EQ(tests, |
||||
state_.VerifyRegisteredTestNames("foo.cc", 1, tests)); |
||||
} |
||||
|
||||
// Makes sure that the order of the tests and spaces around the names
|
||||
// don't matter.
|
||||
TEST_F(TypedTestCasePStateTest, IgnoresOrderAndSpaces) { |
||||
const char* tests = "A,C, B"; |
||||
EXPECT_EQ(tests, |
||||
state_.VerifyRegisteredTestNames("foo.cc", 1, tests)); |
||||
} |
||||
|
||||
#ifdef GTEST_HAS_DEATH_TEST |
||||
|
||||
typedef TypedTestCasePStateTest TypedTestCasePStateDeathTest; |
||||
|
||||
TEST_F(TypedTestCasePStateDeathTest, DetectsDuplicates) { |
||||
EXPECT_DEATH( |
||||
state_.VerifyRegisteredTestNames("foo.cc", 1, "A, B, A, C"), |
||||
"foo\\.cc:1: Test A is listed more than once\\."); |
||||
} |
||||
|
||||
TEST_F(TypedTestCasePStateDeathTest, DetectsExtraTest) { |
||||
EXPECT_DEATH( |
||||
state_.VerifyRegisteredTestNames("foo.cc", 1, "A, B, C, D"), |
||||
"foo\\.cc:1: No test named D can be found in this test case\\."); |
||||
} |
||||
|
||||
TEST_F(TypedTestCasePStateDeathTest, DetectsMissedTest) { |
||||
EXPECT_DEATH( |
||||
state_.VerifyRegisteredTestNames("foo.cc", 1, "A, C"), |
||||
"foo\\.cc:1: You forgot to list test B\\."); |
||||
} |
||||
|
||||
// Tests that defining a test for a parameterized test case generates
|
||||
// a run-time error if the test case has been registered.
|
||||
TEST_F(TypedTestCasePStateDeathTest, DetectsTestAfterRegistration) { |
||||
state_.VerifyRegisteredTestNames("foo.cc", 1, "A, B, C"); |
||||
EXPECT_DEATH( |
||||
state_.AddTestName("foo.cc", 2, "FooTest", "D"), |
||||
"foo\\.cc:2: Test D must be defined before REGISTER_TYPED_TEST_CASE_P" |
||||
"\\(FooTest, \\.\\.\\.\\)\\."); |
||||
} |
||||
|
||||
#endif // GTEST_HAS_DEATH_TEST
|
||||
|
||||
// Tests that SetUpTestCase()/TearDownTestCase(), fixture ctor/dtor,
|
||||
// and SetUp()/TearDown() work correctly in type-parameterized tests.
|
||||
|
||||
template <typename T> |
||||
class DerivedTest : public CommonTest<T> { |
||||
}; |
||||
|
||||
TYPED_TEST_CASE_P(DerivedTest); |
||||
|
||||
TYPED_TEST_P(DerivedTest, ValuesAreCorrect) { |
||||
// Static members of the fixture class template can be visited via
|
||||
// the TestFixture:: prefix.
|
||||
EXPECT_EQ(5, *TestFixture::shared_); |
||||
|
||||
// Non-static members of the fixture class must be visited via
|
||||
// 'this', as required by C++ for class templates.
|
||||
EXPECT_EQ(2, this->value_); |
||||
} |
||||
|
||||
// The second test makes sure shared_ is not deleted after the first
|
||||
// test.
|
||||
TYPED_TEST_P(DerivedTest, ValuesAreStillCorrect) { |
||||
// Static members of the fixture class template can also be visited
|
||||
// via 'this'.
|
||||
ASSERT_TRUE(this->shared_ != NULL); |
||||
EXPECT_EQ(5, *this->shared_); |
||||
EXPECT_EQ(2, this->value_); |
||||
} |
||||
|
||||
REGISTER_TYPED_TEST_CASE_P(DerivedTest, |
||||
ValuesAreCorrect, ValuesAreStillCorrect); |
||||
|
||||
typedef Types<short, long> MyTwoTypes; |
||||
INSTANTIATE_TYPED_TEST_CASE_P(My, DerivedTest, MyTwoTypes); |
||||
|
||||
// Tests that multiple TYPED_TEST_CASE_P's can be defined in the same
|
||||
// translation unit.
|
||||
|
||||
template <typename T> |
||||
class TypedTestP1 : public Test { |
||||
}; |
||||
|
||||
TYPED_TEST_CASE_P(TypedTestP1); |
||||
|
||||
// For testing that the code between TYPED_TEST_CASE_P() and
|
||||
// TYPED_TEST_P() is not enclosed in a namespace.
|
||||
typedef int IntAfterTypedTestCaseP; |
||||
|
||||
TYPED_TEST_P(TypedTestP1, A) {} |
||||
TYPED_TEST_P(TypedTestP1, B) {} |
||||
|
||||
// For testing that the code between TYPED_TEST_P() and
|
||||
// REGISTER_TYPED_TEST_CASE_P() is not enclosed in a namespace.
|
||||
typedef int IntBeforeRegisterTypedTestCaseP; |
||||
|
||||
REGISTER_TYPED_TEST_CASE_P(TypedTestP1, A, B); |
||||
|
||||
template <typename T> |
||||
class TypedTestP2 : public Test { |
||||
}; |
||||
|
||||
TYPED_TEST_CASE_P(TypedTestP2); |
||||
|
||||
// This also verifies that tests from different type-parameterized
|
||||
// test cases can share the same name.
|
||||
TYPED_TEST_P(TypedTestP2, A) {} |
||||
|
||||
REGISTER_TYPED_TEST_CASE_P(TypedTestP2, A); |
||||
|
||||
// Verifies that the code between TYPED_TEST_CASE_P() and
|
||||
// REGISTER_TYPED_TEST_CASE_P() is not enclosed in a namespace.
|
||||
IntAfterTypedTestCaseP after = 0; |
||||
IntBeforeRegisterTypedTestCaseP before = 0; |
||||
|
||||
// Verifies that the last argument of INSTANTIATE_TYPED_TEST_CASE_P()
|
||||
// can be either a single type or a Types<...> type list.
|
||||
INSTANTIATE_TYPED_TEST_CASE_P(Int, TypedTestP1, int); |
||||
INSTANTIATE_TYPED_TEST_CASE_P(Int, TypedTestP2, Types<int>); |
||||
|
||||
// Tests that the same type-parameterized test case can be
|
||||
// instantiated more than once in the same translation unit.
|
||||
INSTANTIATE_TYPED_TEST_CASE_P(Double, TypedTestP2, Types<double>); |
||||
|
||||
// Tests that the same type-parameterized test case can be
|
||||
// instantiated in different translation units linked together.
|
||||
// (ContainerTest is also instantiated in gtest-typed-test_test.cc.)
|
||||
typedef Types<std::list<double>, std::set<char> > MyContainers; |
||||
INSTANTIATE_TYPED_TEST_CASE_P(My, ContainerTest, MyContainers); |
||||
|
||||
// Tests that a type-parameterized test case can be defined and
|
||||
// instantiated in a namespace.
|
||||
|
||||
namespace library2 { |
||||
|
||||
template <typename T> |
||||
class NumericTest : public Test { |
||||
}; |
||||
|
||||
TYPED_TEST_CASE_P(NumericTest); |
||||
|
||||
TYPED_TEST_P(NumericTest, DefaultIsZero) { |
||||
EXPECT_EQ(0, TypeParam()); |
||||
} |
||||
|
||||
TYPED_TEST_P(NumericTest, ZeroIsLessThanOne) { |
||||
EXPECT_LT(TypeParam(0), TypeParam(1)); |
||||
} |
||||
|
||||
REGISTER_TYPED_TEST_CASE_P(NumericTest, |
||||
DefaultIsZero, ZeroIsLessThanOne); |
||||
typedef Types<int, double> NumericTypes; |
||||
INSTANTIATE_TYPED_TEST_CASE_P(My, NumericTest, NumericTypes); |
||||
|
||||
} // namespace library2
|
||||
|
||||
#endif // GTEST_HAS_TYPED_TEST_P
|
@ -0,0 +1,66 @@ |
||||
// Copyright 2008 Google Inc.
|
||||
// All Rights Reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Author: wan@google.com (Zhanyong Wan)
|
||||
|
||||
#ifndef GTEST_TEST_GTEST_TYPED_TEST_TEST_H_ |
||||
#define GTEST_TEST_GTEST_TYPED_TEST_TEST_H_ |
||||
|
||||
#include <gtest/gtest.h> |
||||
|
||||
#ifdef GTEST_HAS_TYPED_TEST_P |
||||
|
||||
using testing::Test; |
||||
|
||||
// For testing that the same type-parameterized test case can be
|
||||
// instantiated in different translation units linked together.
|
||||
// ContainerTest will be instantiated in both gtest-typed-test_test.cc
|
||||
// and gtest-typed-test2_test.cc.
|
||||
|
||||
template <typename T> |
||||
class ContainerTest : public Test { |
||||
}; |
||||
|
||||
TYPED_TEST_CASE_P(ContainerTest); |
||||
|
||||
TYPED_TEST_P(ContainerTest, CanBeDefaultConstructed) { |
||||
TypeParam container; |
||||
} |
||||
|
||||
TYPED_TEST_P(ContainerTest, InitialSizeIsZero) { |
||||
TypeParam container; |
||||
EXPECT_EQ(0, container.size()); |
||||
} |
||||
|
||||
REGISTER_TYPED_TEST_CASE_P(ContainerTest, |
||||
CanBeDefaultConstructed, InitialSizeIsZero); |
||||
|
||||
#endif // GTEST_HAS_TYPED_TEST_P
|
||||
|
||||
#endif // GTEST_TEST_GTEST_TYPED_TEST_TEST_H_
|
Loading…
Reference in new issue