Value-parameterized tests and many bugfixes

This commit is contained in:
vladlosev 2008-11-20 01:40:35 +00:00
parent b6a296d0f7
commit 3d70421763
36 changed files with 10345 additions and 194 deletions

View File

@ -9,6 +9,7 @@ Bharat Mediratta <bharat@menalto.com>
Chandler Carruth <chandlerc@google.com> Chandler Carruth <chandlerc@google.com>
Chris Prince <cprince@google.com> Chris Prince <cprince@google.com>
Chris Taylor <taylorc@google.com> Chris Taylor <taylorc@google.com>
Dan Egnor <egnor@google.com>
Jeffrey Yasskin <jyasskin@google.com> Jeffrey Yasskin <jyasskin@google.com>
Jói Sigurðsson <joi@google.com> Jói Sigurðsson <joi@google.com>
Keir Mierle <mierle@gmail.com> Keir Mierle <mierle@gmail.com>
@ -26,5 +27,6 @@ Russ Rufer <russ@pentad.com>
Sean Mcafee <eefacm@gmail.com> Sean Mcafee <eefacm@gmail.com>
Sigurður Ásgeirsson <siggi@google.com> Sigurður Ásgeirsson <siggi@google.com>
Tracy Bialik <tracy@pentad.com> Tracy Bialik <tracy@pentad.com>
Vadim Berman <vadimb@google.com>
Vlad Losev <vladl@google.com> Vlad Losev <vladl@google.com>
Zhanyong Wan <wan@google.com> Zhanyong Wan <wan@google.com>

View File

@ -6,7 +6,9 @@
EXTRA_DIST = \ EXTRA_DIST = \
CHANGES \ CHANGES \
CONTRIBUTORS \ CONTRIBUTORS \
include/gtest/gtest-param-test.h.pump \
include/gtest/internal/gtest-type-util.h.pump \ include/gtest/internal/gtest-type-util.h.pump \
include/gtest/internal/gtest-param-util-generated.h.pump \
scons/SConscript \ scons/SConscript \
scripts/gen_gtest_pred_impl.py \ scripts/gen_gtest_pred_impl.py \
src/gtest-all.cc src/gtest-all.cc
@ -77,9 +79,10 @@ lib_libgtest_la_SOURCES = src/gtest.cc \
pkginclude_HEADERS = include/gtest/gtest.h \ pkginclude_HEADERS = include/gtest/gtest.h \
include/gtest/gtest-death-test.h \ include/gtest/gtest-death-test.h \
include/gtest/gtest-message.h \ include/gtest/gtest-message.h \
include/gtest/gtest-spi.h \ include/gtest/gtest-param-test.h \
include/gtest/gtest_pred_impl.h \ include/gtest/gtest_pred_impl.h \
include/gtest/gtest_prod.h \ include/gtest/gtest_prod.h \
include/gtest/gtest-spi.h \
include/gtest/gtest-test-part.h \ include/gtest/gtest-test-part.h \
include/gtest/gtest-typed-test.h include/gtest/gtest-typed-test.h
@ -88,6 +91,9 @@ pkginclude_internal_HEADERS = \
include/gtest/internal/gtest-death-test-internal.h \ include/gtest/internal/gtest-death-test-internal.h \
include/gtest/internal/gtest-filepath.h \ include/gtest/internal/gtest-filepath.h \
include/gtest/internal/gtest-internal.h \ include/gtest/internal/gtest-internal.h \
include/gtest/internal/gtest-linked_ptr.h \
include/gtest/internal/gtest-param-util-generated.h \
include/gtest/internal/gtest-param-util.h \
include/gtest/internal/gtest-port.h \ include/gtest/internal/gtest-port.h \
include/gtest/internal/gtest-string.h \ include/gtest/internal/gtest-string.h \
include/gtest/internal/gtest-type-util.h include/gtest/internal/gtest-type-util.h
@ -149,10 +155,25 @@ samples_sample5_unittest_LDADD = lib/libgtest_main.la \
TESTS += samples/sample6_unittest TESTS += samples/sample6_unittest
check_PROGRAMS += samples/sample6_unittest check_PROGRAMS += samples/sample6_unittest
samples_sample6_unittest_SOURCES = samples/sample6_unittest.cc samples_sample6_unittest_SOURCES = samples/prime_tables.h \
samples/sample6_unittest.cc
samples_sample6_unittest_LDADD = lib/libgtest_main.la \ samples_sample6_unittest_LDADD = lib/libgtest_main.la \
samples/libsamples.la samples/libsamples.la
TESTS += samples/sample7_unittest
check_PROGRAMS += samples/sample7_unittest
samples_sample7_unittest_SOURCES = samples/prime_tables.h \
samples/sample7_unittest.cc
samples_sample7_unittest_LDADD = lib/libgtest_main.la \
samples/libsamples.la
TESTS += samples/sample8_unittest
check_PROGRAMS += samples/sample8_unittest
samples_sample8_unittest_SOURCES = samples/prime_tables.h \
samples/sample8_unittest.cc
samples_sample8_unittest_LDADD = lib/libgtest_main.la \
samples/libsamples.la
TESTS += test/gtest_unittest TESTS += test/gtest_unittest
check_PROGRAMS += test/gtest_unittest check_PROGRAMS += test/gtest_unittest
test_gtest_unittest_SOURCES = test/gtest_unittest.cc test_gtest_unittest_SOURCES = test/gtest_unittest.cc
@ -189,6 +210,11 @@ check_PROGRAMS += test/gtest_environment_test
test_gtest_environment_test_SOURCES = test/gtest_environment_test.cc test_gtest_environment_test_SOURCES = test/gtest_environment_test.cc
test_gtest_environment_test_LDADD = lib/libgtest.la test_gtest_environment_test_LDADD = lib/libgtest.la
TESTS += test/gtest-linked_ptr_test
check_PROGRAMS += test/gtest-linked_ptr_test
test_gtest_linked_ptr_test_SOURCES = test/gtest-linked_ptr_test.cc
test_gtest_linked_ptr_test_LDADD = lib/libgtest_main.la
TESTS += test/gtest_no_test_unittest TESTS += test/gtest_no_test_unittest
check_PROGRAMS += test/gtest_no_test_unittest check_PROGRAMS += test/gtest_no_test_unittest
test_gtest_no_test_unittest_SOURCES = test/gtest_no_test_unittest.cc test_gtest_no_test_unittest_SOURCES = test/gtest_no_test_unittest.cc
@ -199,6 +225,18 @@ check_PROGRAMS += test/gtest_main_unittest
test_gtest_main_unittest_SOURCES = test/gtest_main_unittest.cc test_gtest_main_unittest_SOURCES = test/gtest_main_unittest.cc
test_gtest_main_unittest_LDADD = lib/libgtest_main.la test_gtest_main_unittest_LDADD = lib/libgtest_main.la
TESTS += test/gtest-param-test_test
check_PROGRAMS += test/gtest-param-test_test
test_gtest_param_test_test_SOURCES = test/gtest-param-test_test.cc \
test/gtest-param-test2_test.cc \
test/gtest-param-test_test.h
test_gtest_param_test_test_LDADD = lib/libgtest.la
TESTS += test/gtest-port_test
check_PROGRAMS += test/gtest-port_test
test_gtest_port_test_SOURCES = test/gtest-port_test.cc
test_gtest_port_test_LDADD = lib/libgtest_main.la
TESTS += test/gtest_prod_test TESTS += test/gtest_prod_test
check_PROGRAMS += test/gtest_prod_test check_PROGRAMS += test/gtest_prod_test
test_gtest_prod_test_SOURCES = test/gtest_prod_test.cc \ test_gtest_prod_test_SOURCES = test/gtest_prod_test.cc \

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,456 @@
$$ -*- mode: c++; -*-
$var n = 50 $$ Maximum length of Values arguments we want to support.
$var maxtuple = 10 $$ Maximum number of Combine arguments 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.
//
// Authors: vladl@google.com (Vlad Losev)
//
// Macros and functions for implementing parameterized tests
// in Google C++ Testing Framework (Google Test)
//
// This file is generated by a SCRIPT. DO NOT EDIT BY HAND!
//
#ifndef GTEST_INCLUDE_GTEST_GTEST_PARAM_TEST_H_
#define GTEST_INCLUDE_GTEST_GTEST_PARAM_TEST_H_
// Value-parameterized tests allow you to test your code with different
// parameters without writing multiple copies of the same test.
//
// Here is how you use value-parameterized tests:
#if 0
// To write value-parameterized tests, first you should define a fixture
// class. It must be derived from testing::TestWithParam<T>, where T is
// the type of your parameter values. TestWithParam<T> is itself derived
// from testing::Test. T can be any copyable type. If it's a raw pointer,
// you are responsible for managing the lifespan of the pointed values.
class FooTest : public ::testing::TestWithParam<const char*> {
// You can implement all the usual class fixture members here.
};
// Then, use the TEST_P macro to define as many parameterized tests
// for this fixture as you want. The _P suffix is for "parameterized"
// or "pattern", whichever you prefer to think.
TEST_P(FooTest, DoesBlah) {
// Inside a test, access the test parameter with the GetParam() method
// of the TestWithParam<T> class:
EXPECT_TRUE(foo.Blah(GetParam()));
...
}
TEST_P(FooTest, HasBlahBlah) {
...
}
// Finally, you can use INSTANTIATE_TEST_CASE_P to instantiate the test
// case with any set of parameters you want. Google Test defines a number
// of functions for generating test parameters. They return what we call
// (surprise!) parameter generators. Here is a summary of them, which
// are all in the testing namespace:
//
//
// Range(begin, end [, step]) - Yields values {begin, begin+step,
// begin+step+step, ...}. The values do not
// include end. step defaults to 1.
// Values(v1, v2, ..., vN) - Yields values {v1, v2, ..., vN}.
// ValuesIn(container) - Yields values from a C-style array, an STL
// ValuesIn(begin,end) container, or an iterator range [begin, end).
// Bool() - Yields sequence {false, true}.
// Combine(g1, g2, ..., gN) - Yields all combinations (the Cartesian product
// for the math savvy) of the values generated
// by the N generators.
//
// For more details, see comments at the definitions of these functions below
// in this file.
//
// The following statement will instantiate tests from the FooTest test case
// each with parameter values "meeny", "miny", and "moe".
INSTANTIATE_TEST_CASE_P(InstantiationName,
FooTest,
Values("meeny", "miny", "moe"));
// To distinguish different instances of the pattern, (yes, you
// can instantiate it more then once) the first argument to the
// INSTANTIATE_TEST_CASE_P macro is a prefix that will be added to the
// actual test case name. Remember to pick unique prefixes for different
// instantiations. The tests from the instantiation above will have
// these names:
//
// * InstantiationName/FooTest.DoesBlah/0 for "meeny"
// * InstantiationName/FooTest.DoesBlah/1 for "miny"
// * InstantiationName/FooTest.DoesBlah/2 for "moe"
// * InstantiationName/FooTest.HasBlahBlah/0 for "meeny"
// * InstantiationName/FooTest.HasBlahBlah/1 for "miny"
// * InstantiationName/FooTest.HasBlahBlah/2 for "moe"
//
// You can use these names in --gtest_filter.
//
// This statement will instantiate all tests from FooTest again, each
// with parameter values "cat" and "dog":
const char* pets[] = {"cat", "dog"};
INSTANTIATE_TEST_CASE_P(AnotherInstantiationName, FooTest, ValuesIn(pets));
// The tests from the instantiation above will have these names:
//
// * AnotherInstantiationName/FooTest.DoesBlah/0 for "cat"
// * AnotherInstantiationName/FooTest.DoesBlah/1 for "dog"
// * AnotherInstantiationName/FooTest.HasBlahBlah/0 for "cat"
// * AnotherInstantiationName/FooTest.HasBlahBlah/1 for "dog"
//
// Please note that INSTANTIATE_TEST_CASE_P will instantiate all tests
// in the given test case, whether their definitions come before or
// AFTER the INSTANTIATE_TEST_CASE_P statement.
//
// Please also note that generator expressions are evaluated in
// RUN_ALL_TESTS(), after main() has started. This allows evaluation of
// parameter list based on command line parameters.
//
// You can see samples/sample7_unittest.cc and samples/sample8_unittest.cc
// for more examples.
//
// In the future, we plan to publish the API for defining new parameter
// generators. But for now this interface remains part of the internal
// implementation and is subject to change.
#endif // 0
#include <utility>
#include <gtest/internal/gtest-port.h>
#ifdef GTEST_HAS_PARAM_TEST
#include <gtest/internal/gtest-internal.h>
#include <gtest/internal/gtest-param-util.h>
#include <gtest/internal/gtest-param-util-generated.h>
#ifdef GTEST_HAS_COMBINE
#include <tr1/tuple>
#endif // GTEST_HAS_COMBINE
namespace testing {
// Functions producing parameter generators.
//
// Google Test uses these generators to produce parameters for value-
// parameterized tests. When a parameterized test case is instantiated
// with a particular generator, Google Test creates and runs tests
// for each element in the sequence produced by the generator.
//
// In the following sample, tests from test case FooTest are instantiated
// each three times with parameter values 3, 5, and 8:
//
// class FooTest : public TestWithParam<int> { ... };
//
// TEST_P(FooTest, TestThis) {
// }
// TEST_P(FooTest, TestThat) {
// }
// INSTANTIATE_TEST_CASE_P(TestSequence, FooTest, Values(3, 5, 8));
//
// Range() returns generators providing sequences of values in a range.
//
// Synopsis:
// Range(start, end)
// - returns a generator producing a sequence of values {start, start+1,
// start+2, ..., }.
// Range(start, end, step)
// - returns a generator producing a sequence of values {start, start+step,
// start+step+step, ..., }.
// Notes:
// * The generated sequences never include end. For example, Range(1, 5)
// returns a generator producing a sequence {1, 2, 3, 4}. Range(1, 9, 2)
// returns a generator producing {1, 3, 5, 7}.
// * start and end must have the same type. That type may be any integral or
// floating-point type or a user defined type satisfying these conditions:
// * It must be assignable (have operator=() defined).
// * It must have operator+() (operator+(int-compatible type) for
// two-operand version).
// * It must have operator<() defined.
// Elements in the resulting sequences will also have that type.
// * Condition start < end must be satisfied in order for resulting sequences
// to contain any elements.
//
template <typename T, typename IncrementT>
internal::ParamGenerator<T> Range(T start, T end, IncrementT step) {
return internal::ParamGenerator<T>(
new internal::RangeGenerator<T, IncrementT>(start, end, step));
}
template <typename T>
internal::ParamGenerator<T> Range(T start, T end) {
return Range(start, end, 1);
}
// ValuesIn() function allows generation of tests with parameters coming from
// a container.
//
// Synopsis:
// ValuesIn(const T (&array)[N])
// - returns a generator producing sequences with elements from
// a C-style array.
// ValuesIn(const Container& container)
// - returns a generator producing sequences with elements from
// an STL-style container.
// ValuesIn(Iterator begin, Iterator end)
// - returns a generator producing sequences with elements from
// a range [begin, end) defined by a pair of STL-style iterators. These
// iterators can also be plain C pointers.
//
// Please note that ValuesIn copies the values from the containers
// passed in and keeps them to generate tests in RUN_ALL_TESTS().
//
// Examples:
//
// This instantiates tests from test case StringTest
// each with C-string values of "foo", "bar", and "baz":
//
// const char* strings[] = {"foo", "bar", "baz"};
// INSTANTIATE_TEST_CASE_P(StringSequence, SrtingTest, ValuesIn(strings));
//
// This instantiates tests from test case StlStringTest
// each with STL strings with values "a" and "b":
//
// ::std::vector< ::std::string> GetParameterStrings() {
// ::std::vector< ::std::string> v;
// v.push_back("a");
// v.push_back("b");
// return v;
// }
//
// INSTANTIATE_TEST_CASE_P(CharSequence,
// StlStringTest,
// ValuesIn(GetParameterStrings()));
//
//
// This will also instantiate tests from CharTest
// each with parameter values 'a' and 'b':
//
// ::std::list<char> GetParameterChars() {
// ::std::list<char> list;
// list.push_back('a');
// list.push_back('b');
// return list;
// }
// ::std::list<char> l = GetParameterChars();
// INSTANTIATE_TEST_CASE_P(CharSequence2,
// CharTest,
// ValuesIn(l.begin(), l.end()));
//
template <typename ForwardIterator>
internal::ParamGenerator<
typename ::std::iterator_traits<ForwardIterator>::value_type> ValuesIn(
ForwardIterator begin,
ForwardIterator end) {
typedef typename ::std::iterator_traits<ForwardIterator>::value_type
ParamType;
return internal::ParamGenerator<ParamType>(
new internal::ValuesInIteratorRangeGenerator<ParamType>(begin, end));
}
template <typename T, size_t N>
internal::ParamGenerator<T> ValuesIn(const T (&array)[N]) {
return ValuesIn(array, array + N);
}
template <class Container>
internal::ParamGenerator<typename Container::value_type> ValuesIn(
const Container& container) {
return ValuesIn(container.begin(), container.end());
}
// Values() allows generating tests from explicitly specified list of
// parameters.
//
// Synopsis:
// Values(T v1, T v2, ..., T vN)
// - returns a generator producing sequences with elements v1, v2, ..., vN.
//
// For example, this instantiates tests from test case BarTest each
// with values "one", "two", and "three":
//
// INSTANTIATE_TEST_CASE_P(NumSequence, BarTest, Values("one", "two", "three"));
//
// This instantiates tests from test case BazTest each with values 1, 2, 3.5.
// The exact type of values will depend on the type of parameter in BazTest.
//
// INSTANTIATE_TEST_CASE_P(FloatingNumbers, BazTest, Values(1, 2, 3.5));
//
// Currently, Values() supports from 1 to $n parameters.
//
$range i 1..n
$for i [[
$range j 1..i
template <$for j, [[typename T$j]]>
internal::ValueArray$i<$for j, [[T$j]]> Values($for j, [[T$j v$j]]) {
return internal::ValueArray$i<$for j, [[T$j]]>($for j, [[v$j]]);
}
]]
// Bool() allows generating tests with parameters in a set of (false, true).
//
// Synopsis:
// Bool()
// - returns a generator producing sequences with elements {false, true}.
//
// It is useful when testing code that depends on Boolean flags. Combinations
// of multiple flags can be tested when several Bool()'s are combined using
// Combine() function.
//
// In the following example all tests in the test case FlagDependentTest
// will be instantiated twice with parameters false and true.
//
// class FlagDependentTest : public testing::TestWithParam<bool> {
// virtual void SetUp() {
// external_flag = GetParam();
// }
// }
// INSTANTIATE_TEST_CASE_P(BoolSequence, FlagDependentTest, Bool());
//
inline internal::ParamGenerator<bool> Bool() {
return Values(false, true);
}
#ifdef GTEST_HAS_COMBINE
// Combine() allows the user to combine two or more sequences to produce
// values of a Cartesian product of those sequences' elements.
//
// Synopsis:
// Combine(gen1, gen2, ..., genN)
// - returns a generator producing sequences with elements coming from
// the Cartesian product of elements from the sequences generated by
// gen1, gen2, ..., genN. The sequence elements will have a type of
// tuple<T1, T2, ..., TN> where T1, T2, ..., TN are the types
// of elements from sequences produces by gen1, gen2, ..., genN.
//
// Combine can have up to $maxtuple arguments. This number is currently limited
// by the maximum number of elements in the tuple implementation used by Google
// Test.
//
// Example:
//
// This will instantiate tests in test case AnimalTest each one with
// the parameter values tuple("cat", BLACK), tuple("cat", WHITE),
// tuple("dog", BLACK), and tuple("dog", WHITE):
//
// enum Color { BLACK, GRAY, WHITE };
// class AnimalTest
// : public testing::TestWithParam<tuple<const char*, Color> > {...};
//
// TEST_P(AnimalTest, AnimalLooksNice) {...}
//
// INSTANTIATE_TEST_CASE_P(AnimalVariations, AnimalTest,
// Combine(Values("cat", "dog"),
// Values(BLACK, WHITE)));
//
// This will instantiate tests in FlagDependentTest with all variations of two
// Boolean flags:
//
// class FlagDependentTest
// : public testing::TestWithParam<tuple(bool, bool)> > {
// virtual void SetUp() {
// // Assigns external_flag_1 and external_flag_2 values from the tuple.
// tie(external_flag_1, external_flag_2) = GetParam();
// }
// };
//
// TEST_P(FlagDependentTest, TestFeature1) {
// // Test your code using external_flag_1 and external_flag_2 here.
// }
// INSTANTIATE_TEST_CASE_P(TwoBoolSequence, FlagDependentTest,
// Combine(Bool(), Bool()));
//
$range i 2..maxtuple
$for i [[
$range j 1..i
template <$for j, [[typename Generator$j]]>
internal::CartesianProductHolder$i<$for j, [[Generator$j]]> Combine(
$for j, [[const Generator$j& g$j]]) {
return internal::CartesianProductHolder$i<$for j, [[Generator$j]]>(
$for j, [[g$j]]);
}
]]
#endif // GTEST_HAS_COMBINE
#define TEST_P(test_case_name, test_name) \
class GTEST_TEST_CLASS_NAME_(test_case_name, test_name) \
: public test_case_name { \
public: \
GTEST_TEST_CLASS_NAME_(test_case_name, test_name)() {} \
virtual void TestBody(); \
private: \
static int AddToRegistry() { \
::testing::UnitTest::GetInstance()->parameterized_test_registry(). \
GetTestCasePatternHolder<test_case_name>(\
#test_case_name, __FILE__, __LINE__)->AddTestPattern(\
#test_case_name, \
#test_name, \
new ::testing::internal::TestMetaFactory< \
GTEST_TEST_CLASS_NAME_(test_case_name, test_name)>()); \
return 0; \
} \
static int gtest_registering_dummy_; \
GTEST_DISALLOW_COPY_AND_ASSIGN_(\
GTEST_TEST_CLASS_NAME_(test_case_name, test_name)); \
}; \
int GTEST_TEST_CLASS_NAME_(test_case_name, \
test_name)::gtest_registering_dummy_ = \
GTEST_TEST_CLASS_NAME_(test_case_name, test_name)::AddToRegistry(); \
void GTEST_TEST_CLASS_NAME_(test_case_name, test_name)::TestBody()
#define INSTANTIATE_TEST_CASE_P(prefix, test_case_name, generator) \
::testing::internal::ParamGenerator<test_case_name::ParamType> \
gtest_##prefix##test_case_name##_EvalGenerator_() { return generator; } \
int gtest_##prefix##test_case_name##_dummy_ = \
::testing::UnitTest::GetInstance()->parameterized_test_registry(). \
GetTestCasePatternHolder<test_case_name>(\
#test_case_name, __FILE__, __LINE__)->AddTestCaseInstantiation(\
#prefix, \
&gtest_##prefix##test_case_name##_EvalGenerator_, \
__FILE__, __LINE__)
} // namespace testing
#endif // GTEST_HAS_PARAM_TEST
#endif // GTEST_INCLUDE_GTEST_GTEST_PARAM_TEST_H_

View File

@ -108,21 +108,6 @@ class SingleFailureChecker {
GTEST_DISALLOW_COPY_AND_ASSIGN_(SingleFailureChecker); GTEST_DISALLOW_COPY_AND_ASSIGN_(SingleFailureChecker);
}; };
// Helper macro to test that statement generates exactly one fatal failure,
// which contains the substring 'substr' in its failure message, when a scoped
// test result reporter of the given interception mode is used.
#define GTEST_EXPECT_NONFATAL_FAILURE_(statement, substr, intercept_mode)\
do {\
::testing::TestPartResultArray gtest_failures;\
::testing::internal::SingleFailureChecker gtest_checker(\
&gtest_failures, ::testing::TPRT_NONFATAL_FAILURE, (substr));\
{\
::testing::ScopedFakeTestPartResultReporter gtest_reporter(\
intercept_mode, &gtest_failures);\
statement;\
}\
} while (false)
} // namespace internal } // namespace internal
} // namespace testing } // namespace testing

View File

@ -66,6 +66,7 @@
#include <gtest/internal/gtest-string.h> #include <gtest/internal/gtest-string.h>
#include <gtest/gtest-death-test.h> #include <gtest/gtest-death-test.h>
#include <gtest/gtest-message.h> #include <gtest/gtest-message.h>
#include <gtest/gtest-param-test.h>
#include <gtest/gtest_prod.h> #include <gtest/gtest_prod.h>
#include <gtest/gtest-test-part.h> #include <gtest/gtest-test-part.h>
#include <gtest/gtest-typed-test.h> #include <gtest/gtest-typed-test.h>
@ -483,6 +484,12 @@ class UnitTest {
// or NULL if no test is running. // or NULL if no test is running.
const TestInfo* current_test_info() const; const TestInfo* current_test_info() const;
#ifdef GTEST_HAS_PARAM_TEST
// Returns the ParameterizedTestCaseRegistry object used to keep track of
// value-parameterized tests and instantiate and register them.
internal::ParameterizedTestCaseRegistry& parameterized_test_registry();
#endif // GTEST_HAS_PARAM_TEST
// Accessors for the implementation object. // Accessors for the implementation object.
internal::UnitTestImpl* impl() { return impl_; } internal::UnitTestImpl* impl() { return impl_; }
const internal::UnitTestImpl* impl() const { return impl_; } const internal::UnitTestImpl* impl() const { return impl_; }
@ -886,6 +893,65 @@ class AssertHelper {
} // namespace internal } // namespace internal
#ifdef GTEST_HAS_PARAM_TEST
// The abstract base class that all value-parameterized tests inherit from.
//
// This class adds support for accessing the test parameter value via
// the GetParam() method.
//
// Use it with one of the parameter generator defining functions, like Range(),
// Values(), ValuesIn(), Bool(), and Combine().
//
// class FooTest : public ::testing::TestWithParam<int> {
// protected:
// FooTest() {
// // Can use GetParam() here.
// }
// virtual ~FooTest() {
// // Can use GetParam() here.
// }
// virtual void SetUp() {
// // Can use GetParam() here.
// }
// virtual void TearDown {
// // Can use GetParam() here.
// }
// };
// TEST_P(FooTest, DoesBar) {
// // Can use GetParam() method here.
// Foo foo;
// ASSERT_TRUE(foo.DoesBar(GetParam()));
// }
// INSTANTIATE_TEST_CASE_P(OneToTenRange, FooTest, ::testing::Range(1, 10));
template <typename T>
class TestWithParam : public Test {
public:
typedef T ParamType;
// The current parameter value. Is also available in the test fixture's
// constructor.
const ParamType& GetParam() const { return *parameter_; }
private:
// Sets parameter value. The caller is responsible for making sure the value
// remains alive and unchanged throughout the current test.
static void SetParam(const ParamType* parameter) {
parameter_ = parameter;
}
// Static value used for accessing parameter during a test lifetime.
static const ParamType* parameter_;
// TestClass must be a subclass of TestWithParam<T>.
template <class TestClass> friend class internal::ParameterizedTestFactory;
};
template <typename T>
const T* TestWithParam<T>::parameter_ = NULL;
#endif // GTEST_HAS_PARAM_TEST
// Macros for indicating success/failure in test code. // Macros for indicating success/failure in test code.
// ADD_FAILURE unconditionally adds a failure to the current test. // ADD_FAILURE unconditionally adds a failure to the current test.

View File

@ -711,6 +711,21 @@ class TypeParameterizedTestCase<Fixture, Templates0, Types> {
#endif // GTEST_HAS_TYPED_TEST || GTEST_HAS_TYPED_TEST_P #endif // GTEST_HAS_TYPED_TEST || GTEST_HAS_TYPED_TEST_P
// Returns the current OS stack trace as a String.
//
// The maximum number of stack frames to be included is specified by
// the gtest_stack_trace_depth flag. The skip_count parameter
// specifies the number of top frames to be skipped, which doesn't
// count against the number of frames to be included.
//
// For example, if Foo() calls Bar(), which in turn calls
// GetCurrentOsStackTraceExceptTop(..., 1), Foo() will be included in
// the trace but Bar() and GetCurrentOsStackTraceExceptTop() won't.
String GetCurrentOsStackTraceExceptTop(UnitTest* unit_test, int skip_count);
// Returns the number of failed test parts in the given test result object.
int GetFailedPartCount(const TestResult* result);
} // namespace internal } // namespace internal
} // namespace testing } // namespace testing
@ -727,7 +742,6 @@ class TypeParameterizedTestCase<Fixture, Templates0, Types> {
#define GTEST_SUCCESS_(message) \ #define GTEST_SUCCESS_(message) \
GTEST_MESSAGE_(message, ::testing::TPRT_SUCCESS) GTEST_MESSAGE_(message, ::testing::TPRT_SUCCESS)
#define GTEST_TEST_THROW_(statement, expected_exception, fail) \ #define GTEST_TEST_THROW_(statement, expected_exception, fail) \
GTEST_AMBIGUOUS_ELSE_BLOCKER_ \ GTEST_AMBIGUOUS_ELSE_BLOCKER_ \
if (const char* gtest_msg = "") { \ if (const char* gtest_msg = "") { \
@ -837,5 +851,4 @@ class GTEST_TEST_CLASS_NAME_(test_case_name, test_name) : public parent_class {\
GTEST_TEST_CLASS_NAME_(test_case_name, test_name)>);\ GTEST_TEST_CLASS_NAME_(test_case_name, test_name)>);\
void GTEST_TEST_CLASS_NAME_(test_case_name, test_name)::TestBody() void GTEST_TEST_CLASS_NAME_(test_case_name, test_name)::TestBody()
#endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_INTERNAL_H_ #endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_INTERNAL_H_

View File

@ -0,0 +1,242 @@
// Copyright 2003 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.
//
// Authors: Dan Egnor (egnor@google.com)
//
// A "smart" pointer type with reference tracking. Every pointer to a
// particular object is kept on a circular linked list. When the last pointer
// to an object is destroyed or reassigned, the object is deleted.
//
// Used properly, this deletes the object when the last reference goes away.
// There are several caveats:
// - Like all reference counting schemes, cycles lead to leaks.
// - Each smart pointer is actually two pointers (8 bytes instead of 4).
// - Every time a pointer is assigned, the entire list of pointers to that
// object is traversed. This class is therefore NOT SUITABLE when there
// will often be more than two or three pointers to a particular object.
// - References are only tracked as long as linked_ptr<> objects are copied.
// If a linked_ptr<> is converted to a raw pointer and back, BAD THINGS
// will happen (double deletion).
//
// A good use of this class is storing object references in STL containers.
// You can safely put linked_ptr<> in a vector<>.
// Other uses may not be as good.
//
// Note: If you use an incomplete type with linked_ptr<>, the class
// *containing* linked_ptr<> must have a constructor and destructor (even
// if they do nothing!).
//
// Bill Gibbons suggested we use something like this.
//
// Thread Safety:
// Unlike other linked_ptr implementations, in this implementation
// a linked_ptr object is thread-safe in the sense that:
// - it's safe to copy linked_ptr objects concurrently,
// - it's safe to copy *from* a linked_ptr and read its underlying
// raw pointer (e.g. via get()) concurrently, and
// - it's safe to write to two linked_ptrs that point to the same
// shared object concurrently.
// TODO(wan@google.com): rename this to safe_linked_ptr to avoid
// confusion with normal linked_ptr.
#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_LINKED_PTR_H_
#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_LINKED_PTR_H_
#include <stdlib.h>
#include <assert.h>
#include <gtest/internal/gtest-port.h>
namespace testing {
namespace internal {
// Protects copying of all linked_ptr objects.
extern Mutex g_linked_ptr_mutex;
// This is used internally by all instances of linked_ptr<>. It needs to be
// a non-template class because different types of linked_ptr<> can refer to
// the same object (linked_ptr<Superclass>(obj) vs linked_ptr<Subclass>(obj)).
// So, it needs to be possible for different types of linked_ptr to participate
// in the same circular linked list, so we need a single class type here.
//
// DO NOT USE THIS CLASS DIRECTLY YOURSELF. Use linked_ptr<T>.
class linked_ptr_internal {
public:
// Create a new circle that includes only this instance.
void join_new() {
next_ = this;
}
// Many linked_ptr operations may change p.link_ for some linked_ptr
// variable p in the same circle as this object. Therefore we need
// to prevent two such operations from occurring concurrently.
//
// Note that different types of linked_ptr objects can coexist in a
// circle (e.g. linked_ptr<Base>, linked_ptr<Derived1>, and
// linked_ptr<Derived2>). Therefore we must use a single mutex to
// protect all linked_ptr objects. This can create serious
// contention in production code, but is acceptable in a testing
// framework.
// Join an existing circle.
// L < g_linked_ptr_mutex
void join(linked_ptr_internal const* ptr) {
MutexLock lock(&g_linked_ptr_mutex);
linked_ptr_internal const* p = ptr;
while (p->next_ != ptr) p = p->next_;
p->next_ = this;
next_ = ptr;
}
// Leave whatever circle we're part of. Returns true if we were the
// last member of the circle. Once this is done, you can join() another.
// L < g_linked_ptr_mutex
bool depart() {
MutexLock lock(&g_linked_ptr_mutex);
if (next_ == this) return true;
linked_ptr_internal const* p = next_;
while (p->next_ != this) p = p->next_;
p->next_ = next_;
return false;
}
private:
mutable linked_ptr_internal const* next_;
};
template <typename T>
class linked_ptr {
public:
typedef T element_type;
// Take over ownership of a raw pointer. This should happen as soon as
// possible after the object is created.
explicit linked_ptr(T* ptr = NULL) { capture(ptr); }
~linked_ptr() { depart(); }
// Copy an existing linked_ptr<>, adding ourselves to the list of references.
template <typename U> linked_ptr(linked_ptr<U> const& ptr) { copy(&ptr); }
linked_ptr(linked_ptr const& ptr) { // NOLINT
assert(&ptr != this);
copy(&ptr);
}
// Assignment releases the old value and acquires the new.
template <typename U> linked_ptr& operator=(linked_ptr<U> const& ptr) {
depart();
copy(&ptr);
return *this;
}
linked_ptr& operator=(linked_ptr const& ptr) {
if (&ptr != this) {
depart();
copy(&ptr);
}
return *this;
}
// Smart pointer members.
void reset(T* ptr = NULL) {
depart();
capture(ptr);
}
T* get() const { return value_; }
T* operator->() const { return value_; }
T& operator*() const { return *value_; }
// Release ownership of the pointed object and returns it.
// Sole ownership by this linked_ptr object is required.
T* release() {
bool last = link_.depart();
assert(last);
T* v = value_;
value_ = NULL;
return v;
}
bool operator==(T* p) const { return value_ == p; }
bool operator!=(T* p) const { return value_ != p; }
template <typename U>
bool operator==(linked_ptr<U> const& ptr) const {
return value_ == ptr.get();
}
template <typename U>
bool operator!=(linked_ptr<U> const& ptr) const {
return value_ != ptr.get();
}
private:
template <typename U>
friend class linked_ptr;
T* value_;
linked_ptr_internal link_;
void depart() {
if (link_.depart()) delete value_;
}
void capture(T* ptr) {
value_ = ptr;
link_.join_new();
}
template <typename U> void copy(linked_ptr<U> const* ptr) {
value_ = ptr->get();
if (value_)
link_.join(&ptr->link_);
else
link_.join_new();
}
};
template<typename T> inline
bool operator==(T* ptr, const linked_ptr<T>& x) {
return ptr == x.get();
}
template<typename T> inline
bool operator!=(T* ptr, const linked_ptr<T>& x) {
return ptr != x.get();
}
// A function to convert T* into linked_ptr<T>
// Doing e.g. make_linked_ptr(new FooBarBaz<type>(arg)) is a shorter notation
// for linked_ptr<FooBarBaz<type> >(new FooBarBaz<type>(arg))
template <typename T>
linked_ptr<T> make_linked_ptr(T* ptr) {
return linked_ptr<T>(ptr);
}
} // namespace internal
} // namespace testing
#endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_LINKED_PTR_H_

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,273 @@
$$ -*- mode: c++; -*-
$var n = 50 $$ Maximum length of Values arguments we want to support.
$var maxtuple = 10 $$ Maximum number of Combine arguments 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: vladl@google.com (Vlad Losev)
// Type and function utilities for implementing parameterized tests.
// This file is generated by a SCRIPT. DO NOT EDIT BY HAND!
//
// Currently Google Test supports at most $n arguments in Values,
// and at most $maxtuple arguments in Combine. Please contact
// googletestframework@googlegroups.com if you need more.
// Please note that the number of arguments to Combine is limited
// by the maximum arity of the implementation of tr1::tuple which is
// currently set at $maxtuple.
#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_GENERATED_H_
#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_GENERATED_H_
#include <gtest/internal/gtest-port.h>
#ifdef GTEST_HAS_PARAM_TEST
#ifdef GTEST_HAS_COMBINE
#include <tr1/tuple>
#endif // GTEST_HAS_COMBINE
#include <gtest/internal/gtest-param-util.h>
namespace testing {
namespace internal {
// Used in the Values() function to provide polymorphic capabilities.
template <typename T1>
class ValueArray1 {
public:
explicit ValueArray1(T1 v1) : v1_(v1) {}
template <typename T>
operator ParamGenerator<T>() const { return ValuesIn(&v1_, &v1_ + 1); }
private:
const T1 v1_;
};
$range i 2..n
$for i [[
$range j 1..i
template <$for j, [[typename T$j]]>
class ValueArray$i {
public:
ValueArray$i($for j, [[T$j v$j]]) : $for j, [[v$(j)_(v$j)]] {}
template <typename T>
operator ParamGenerator<T>() const {
const T array[] = {$for j, [[v$(j)_]]};
return ValuesIn(array);
}
private:
$for j [[
const T$j v$(j)_;
]]
};
]]
#ifdef GTEST_HAS_COMBINE
// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
//
// Generates values from the Cartesian product of values produced
// by the argument generators.
//
$range i 2..maxtuple
$for i [[
$range j 1..i
$range k 2..i
template <$for j, [[typename T$j]]>
class CartesianProductGenerator$i
: public ParamGeneratorInterface< ::std::tr1::tuple<$for j, [[T$j]]> > {
public:
typedef ::std::tr1::tuple<$for j, [[T$j]]> ParamType;
CartesianProductGenerator$i($for j, [[const ParamGenerator<T$j>& g$j]])
: $for j, [[g$(j)_(g$j)]] {}
virtual ~CartesianProductGenerator$i() {}
virtual ParamIteratorInterface<ParamType>* Begin() const {
return new Iterator(this, $for j, [[g$(j)_, g$(j)_.begin()]]);
}
virtual ParamIteratorInterface<ParamType>* End() const {
return new Iterator(this, $for j, [[g$(j)_, g$(j)_.end()]]);
}
private:
class Iterator : public ParamIteratorInterface<ParamType> {
public:
Iterator(const ParamGeneratorInterface<ParamType>* base, $for j, [[
const ParamGenerator<T$j>& g$j,
const typename ParamGenerator<T$j>::iterator& current$(j)]])
: base_(base),
$for j, [[
begin$(j)_(g$j.begin()), end$(j)_(g$j.end()), current$(j)_(current$j)
]] {
ComputeCurrentValue();
}
virtual ~Iterator() {}
virtual const ParamGeneratorInterface<ParamType>* BaseGenerator() const {
return base_;
}
// Advance should not be called on beyond-of-range iterators
// so no component iterators must be beyond end of range, either.
virtual void Advance() {
assert(!AtEnd());
++current$(i)_;
$for k [[
if (current$(i+2-k)_ == end$(i+2-k)_) {
current$(i+2-k)_ = begin$(i+2-k)_;
++current$(i+2-k-1)_;
}
]]
ComputeCurrentValue();
}
virtual ParamIteratorInterface<ParamType>* Clone() const {
return new Iterator(*this);
}
virtual const ParamType* Current() const { return &current_value_; }
virtual bool Equals(const ParamIteratorInterface<ParamType>& other) const {
// Having the same base generator guarantees that the other
// iterator is of the same type and we can downcast.
GTEST_CHECK_(BaseGenerator() == other.BaseGenerator())
<< "The program attempted to compare iterators "
<< "from different generators." << std::endl;
const Iterator* typed_other =
CheckedDowncastToActualType<const Iterator>(&other);
// We must report iterators equal if they both point beyond their
// respective ranges. That can happen in a variety of fashions,
// so we have to consult AtEnd().
return (AtEnd() && typed_other->AtEnd()) ||
($for j && [[
current$(j)_ == typed_other->current$(j)_
]]);
}
private:
Iterator(const Iterator& other)
: base_(other.base_), $for j, [[
begin$(j)_(other.begin$(j)_),
end$(j)_(other.end$(j)_),
current$(j)_(other.current$(j)_)
]] {
ComputeCurrentValue();
}
void ComputeCurrentValue() {
if (!AtEnd())
current_value_ = ParamType($for j, [[*current$(j)_]]);
}
bool AtEnd() const {
// We must report iterator past the end of the range when either of the
// component iterators has reached the end of its range.
return
$for j || [[
current$(j)_ == end$(j)_
]];
}
const ParamGeneratorInterface<ParamType>* const base_;
// begin[i]_ and end[i]_ define the i-th range that Iterator traverses.
// current[i]_ is the actual traversing iterator.
$for j [[
const typename ParamGenerator<T$j>::iterator begin$(j)_;
const typename ParamGenerator<T$j>::iterator end$(j)_;
typename ParamGenerator<T$j>::iterator current$(j)_;
]]
ParamType current_value_;
};
$for j [[
const ParamGenerator<T$j> g$(j)_;
]]
};
]]
// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
//
// Helper classes providing Combine() with polymorphic features. They allow
// casting CartesianProductGeneratorN<T> to ParamGenerator<U> if T is
// convertible to U.
//
$range i 2..maxtuple
$for i [[
$range j 1..i
template <$for j, [[class Generator$j]]>
class CartesianProductHolder$i {
public:
CartesianProductHolder$i($for j, [[const Generator$j& g$j]])
: $for j, [[g$(j)_(g$j)]] {}
template <$for j, [[typename T$j]]>
operator ParamGenerator< ::std::tr1::tuple<$for j, [[T$j]]> >() const {
return ParamGenerator< ::std::tr1::tuple<$for j, [[T$j]]> >(
new CartesianProductGenerator$i<$for j, [[T$j]]>(
$for j,[[
static_cast<ParamGenerator<T$j> >(g$(j)_)
]]));
}
private:
$for j [[
const Generator$j g$(j)_;
]]
};
]]
#endif // GTEST_HAS_COMBINE
} // namespace internal
} // namespace testing
#endif // GTEST_HAS_PARAM_TEST
#endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_GENERATED_H_

View File

@ -0,0 +1,629 @@
// 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: vladl@google.com (Vlad Losev)
// Type and function utilities for implementing parameterized tests.
#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_H_
#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_H_
#include <iterator>
#include <utility>
#include <vector>
#include <gtest/internal/gtest-port.h>
#ifdef GTEST_HAS_PARAM_TEST
#if GTEST_HAS_RTTI
#include <typeinfo>
#endif // GTEST_HAS_RTTI
#include <gtest/internal/gtest-linked_ptr.h>
#include <gtest/internal/gtest-internal.h>
namespace testing {
namespace internal {
// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
//
// Outputs a message explaining invalid registration of different
// fixture class for the same test case. This may happen when
// TEST_P macro is used to define two tests with the same name
// but in different namespaces.
void ReportInvalidTestCaseType(const char* test_case_name,
const char* file, int line);
// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
//
// Downcasts the pointer of type Base to Derived.
// Derived must be a subclass of Base. The parameter MUST
// point to a class of type Derived, not any subclass of it.
// When RTTI is available, the function performs a runtime
// check to enforce this.
template <class Derived, class Base>
Derived* CheckedDowncastToActualType(Base* base) {
#if GTEST_HAS_RTTI
GTEST_CHECK_(typeid(*base) == typeid(Derived));
Derived* derived = dynamic_cast<Derived*>(base); // NOLINT
#else
Derived* derived = static_cast<Derived*>(base); // Poor man's downcast.
#endif // GTEST_HAS_RTTI
return derived;
}
template <typename> class ParamGeneratorInterface;
template <typename> class ParamGenerator;
// Interface for iterating over elements provided by an implementation
// of ParamGeneratorInterface<T>.
template <typename T>
class ParamIteratorInterface {
public:
virtual ~ParamIteratorInterface() {}
// A pointer to the base generator instance.
// Used only for the purposes of iterator comparison
// to make sure that two iterators belong to the same generator.
virtual const ParamGeneratorInterface<T>* BaseGenerator() const = 0;
// Advances iterator to point to the next element
// provided by the generator. The caller is responsible
// for not calling Advance() on an iterator equal to
// BaseGenerator()->End().
virtual void Advance() = 0;
// Clones the iterator object. Used for implementing copy semantics
// of ParamIterator<T>.
virtual ParamIteratorInterface* Clone() const = 0;
// Dereferences the current iterator and provides (read-only) access
// to the pointed value. It is the caller's responsibility not to call
// Current() on an iterator equal to BaseGenerator()->End().
// Used for implementing ParamGenerator<T>::operator*().
virtual const T* Current() const = 0;
// Determines whether the given iterator and other point to the same
// element in the sequence generated by the generator.
// Used for implementing ParamGenerator<T>::operator==().
virtual bool Equals(const ParamIteratorInterface& other) const = 0;
};
// Class iterating over elements provided by an implementation of
// ParamGeneratorInterface<T>. It wraps ParamIteratorInterface<T>
// and implements the const forward iterator concept.
template <typename T>
class ParamIterator {
public:
typedef T value_type;
typedef const T& reference;
typedef ptrdiff_t difference_type;
// ParamIterator assumes ownership of the impl_ pointer.
ParamIterator(const ParamIterator& other) : impl_(other.impl_->Clone()) {}
ParamIterator& operator=(const ParamIterator& other) {
if (this != &other)
impl_.reset(other.impl_->Clone());
return *this;
}
const T& operator*() const { return *impl_->Current(); }
const T* operator->() const { return impl_->Current(); }
// Prefix version of operator++.
ParamIterator& operator++() {
impl_->Advance();
return *this;
}
// Postfix version of operator++.
ParamIterator operator++(int /*unused*/) {
ParamIteratorInterface<T>* clone = impl_->Clone();
impl_->Advance();
return ParamIterator(clone);
}
bool operator==(const ParamIterator& other) const {
return impl_.get() == other.impl_.get() || impl_->Equals(*other.impl_);
}
bool operator!=(const ParamIterator& other) const {
return !(*this == other);
}
private:
friend class ParamGenerator<T>;
explicit ParamIterator(ParamIteratorInterface<T>* impl) : impl_(impl) {}
scoped_ptr<ParamIteratorInterface<T> > impl_;
};
// ParamGeneratorInterface<T> is the binary interface to access generators
// defined in other translation units.
template <typename T>
class ParamGeneratorInterface {
public:
typedef T ParamType;
virtual ~ParamGeneratorInterface() {}
// Generator interface definition
virtual ParamIteratorInterface<T>* Begin() const = 0;
virtual ParamIteratorInterface<T>* End() const = 0;
};
// Wraps ParamGeneratorInetrface<T> and provides general generator syntax
// compatible with the STL Container concept.
// This class implements copy initialization semantics and the contained
// ParamGeneratorInterface<T> instance is shared among all copies
// of the original object. This is possible because that instance is immutable.
template<typename T>
class ParamGenerator {
public:
typedef ParamIterator<T> iterator;
explicit ParamGenerator(ParamGeneratorInterface<T>* impl) : impl_(impl) {}
ParamGenerator(const ParamGenerator& other) : impl_(other.impl_) {}
ParamGenerator& operator=(const ParamGenerator& other) {
impl_ = other.impl_;
return *this;
}
iterator begin() const { return iterator(impl_->Begin()); }
iterator end() const { return iterator(impl_->End()); }
private:
::testing::internal::linked_ptr<const ParamGeneratorInterface<T> > impl_;
};
// Generates values from a range of two comparable values. Can be used to
// generate sequences of user-defined types that implement operator+() and
// operator<().
// This class is used in the Range() function.
template <typename T, typename IncrementT>
class RangeGenerator : public ParamGeneratorInterface<T> {
public:
RangeGenerator(T begin, T end, IncrementT step)
: begin_(begin), end_(end),
step_(step), end_index_(CalculateEndIndex(begin, end, step)) {}
virtual ~RangeGenerator() {}
virtual ParamIteratorInterface<T>* Begin() const {
return new Iterator(this, begin_, 0, step_);
}
virtual ParamIteratorInterface<T>* End() const {
return new Iterator(this, end_, end_index_, step_);
}
private:
class Iterator : public ParamIteratorInterface<T> {
public:
Iterator(const ParamGeneratorInterface<T>* base, T value, int index,
IncrementT step)
: base_(base), value_(value), index_(index), step_(step) {}
virtual ~Iterator() {}
virtual const ParamGeneratorInterface<T>* BaseGenerator() const {
return base_;
}
virtual void Advance() {
value_ = value_ + step_;
index_++;
}
virtual ParamIteratorInterface<T>* Clone() const {
return new Iterator(*this);
}
virtual const T* Current() const { return &value_; }
virtual bool Equals(const ParamIteratorInterface<T>& other) const {
// Having the same base generator guarantees that the other
// iterator is of the same type and we can downcast.
GTEST_CHECK_(BaseGenerator() == other.BaseGenerator())
<< "The program attempted to compare iterators "
<< "from different generators." << std::endl;
const int other_index =
CheckedDowncastToActualType<const Iterator>(&other)->index_;
return index_ == other_index;
}
private:
Iterator(const Iterator& other)
: base_(other.base_), value_(other.value_), index_(other.index_),
step_(other.step_) {}
const ParamGeneratorInterface<T>* const base_;
T value_;
int index_;
const IncrementT step_;
}; // class RangeGenerator::Iterator
static int CalculateEndIndex(const T& begin,
const T& end,
const IncrementT& step) {
int end_index = 0;
for (T i = begin; i < end; i = i + step)
end_index++;
return end_index;
}
const T begin_;
const T end_;
const IncrementT step_;
// The index for the end() iterator. All the elements in the generated
// sequence are indexed (0-based) to aid iterator comparison.
const int end_index_;
}; // class RangeGenerator
// Generates values from a pair of STL-style iterators. Used in the
// ValuesIn() function. The elements are copied from the source range
// since the source can be located on the stack, and the generator
// is likely to persist beyond that stack frame.
template <typename T>
class ValuesInIteratorRangeGenerator : public ParamGeneratorInterface<T> {
public:
template <typename ForwardIterator>
ValuesInIteratorRangeGenerator(ForwardIterator begin, ForwardIterator end)
: container_(begin, end) {}
virtual ~ValuesInIteratorRangeGenerator() {}
virtual ParamIteratorInterface<T>* Begin() const {
return new Iterator(this, container_.begin());
}
virtual ParamIteratorInterface<T>* End() const {
return new Iterator(this, container_.end());
}
private:
typedef typename ::std::vector<T> ContainerType;
class Iterator : public ParamIteratorInterface<T> {
public:
Iterator(const ParamGeneratorInterface<T>* base,
typename ContainerType::const_iterator iterator)
: base_(base), iterator_(iterator) {}
virtual ~Iterator() {}
virtual const ParamGeneratorInterface<T>* BaseGenerator() const {
return base_;
}
virtual void Advance() {
++iterator_;
value_.reset();
}
virtual ParamIteratorInterface<T>* Clone() const {
return new Iterator(*this);
}
// We need to use cached value referenced by iterator_ because *iterator_
// can return a temporary object (and of type other then T), so just
// having "return &*iterator_;" doesn't work.
// value_ is updated here and not in Advance() because Advance()
// can advance iterator_ beyond the end of the range, and we cannot
// detect that fact. The client code, on the other hand, is
// responsible for not calling Current() on an out-of-range iterator.
virtual const T* Current() const {
if (value_.get() == NULL)
value_.reset(new T(*iterator_));
return value_.get();
}
virtual bool Equals(const ParamIteratorInterface<T>& other) const {
// Having the same base generator guarantees that the other
// iterator is of the same type and we can downcast.
GTEST_CHECK_(BaseGenerator() == other.BaseGenerator())
<< "The program attempted to compare iterators "
<< "from different generators." << std::endl;
return iterator_ ==
CheckedDowncastToActualType<const Iterator>(&other)->iterator_;
}
private:
Iterator(const Iterator& other)
// The explicit constructor call suppresses a false warning
// emitted by gcc when supplied with the -Wextra option.
: ParamIteratorInterface<T>(),
base_(other.base_),
iterator_(other.iterator_) {}
const ParamGeneratorInterface<T>* const base_;
typename ContainerType::const_iterator iterator_;
// A cached value of *iterator_. We keep it here to allow access by
// pointer in the wrapping iterator's operator->().
// value_ needs to be mutable to be accessed in Current().
// Use of scoped_ptr helps manage cached value's lifetime,
// which is bound by the lifespan of the iterator itself.
mutable scoped_ptr<const T> value_;
};
const ContainerType container_;
}; // class ValuesInIteratorRangeGenerator
// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
//
// Stores a parameter value and later creates tests parameterized with that
// value.
template <class TestClass>
class ParameterizedTestFactory : public TestFactoryBase {
public:
typedef typename TestClass::ParamType ParamType;
explicit ParameterizedTestFactory(ParamType parameter) :
parameter_(parameter) {}
virtual Test* CreateTest() {
TestClass::SetParam(&parameter_);
return new TestClass();
}
private:
const ParamType parameter_;
GTEST_DISALLOW_COPY_AND_ASSIGN_(ParameterizedTestFactory);
};
// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
//
// TestMetaFactoryBase is a base class for meta-factories that create
// test factories for passing into MakeAndRegisterTestInfo function.
template <class ParamType>
class TestMetaFactoryBase {
public:
virtual ~TestMetaFactoryBase() {}
virtual TestFactoryBase* CreateTestFactory(ParamType parameter) = 0;
};
// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
//
// TestMetaFactory creates test factories for passing into
// MakeAndRegisterTestInfo function. Since MakeAndRegisterTestInfo receives
// ownership of test factory pointer, same factory object cannot be passed
// into that method twice. But ParameterizedTestCaseInfo is going to call
// it for each Test/Parameter value combination. Thus it needs meta factory
// creator class.
template <class TestCase>
class TestMetaFactory
: public TestMetaFactoryBase<typename TestCase::ParamType> {
public:
typedef typename TestCase::ParamType ParamType;
TestMetaFactory() {}
virtual TestFactoryBase* CreateTestFactory(ParamType parameter) {
return new ParameterizedTestFactory<TestCase>(parameter);
}
private:
GTEST_DISALLOW_COPY_AND_ASSIGN_(TestMetaFactory);
};
// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
//
// ParameterizedTestCaseInfoBase is a generic interface
// to ParameterizedTestCaseInfo classes. ParameterizedTestCaseInfoBase
// accumulates test information provided by TEST_P macro invocations
// and generators provided by INSTANTIATE_TEST_CASE_P macro invocations
// and uses that information to register all resulting test instances
// in RegisterTests method. The ParameterizeTestCaseRegistry class holds
// a collection of pointers to the ParameterizedTestCaseInfo objects
// and calls RegisterTests() on each of them when asked.
class ParameterizedTestCaseInfoBase {
public:
virtual ~ParameterizedTestCaseInfoBase() {}
// Base part of test case name for display purposes.
virtual const String& GetTestCaseName() const = 0;
// Test case id to verify identity.
virtual TypeId GetTestCaseTypeId() const = 0;
// UnitTest class invokes this method to register tests in this
// test case right before running them in RUN_ALL_TESTS macro.
// This method should not be called more then once on any single
// instance of a ParameterizedTestCaseInfoBase derived class.
virtual void RegisterTests() = 0;
protected:
ParameterizedTestCaseInfoBase() {}
private:
GTEST_DISALLOW_COPY_AND_ASSIGN_(ParameterizedTestCaseInfoBase);
};
// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
//
// ParameterizedTestCaseInfo accumulates tests obtained from TEST_P
// macro invocations for a particular test case and generators
// obtained from INSTANTIATE_TEST_CASE_P macro invocations for that
// test case. It registers tests with all values generated by all
// generators when asked.
template <class TestCase>
class ParameterizedTestCaseInfo : public ParameterizedTestCaseInfoBase {
public:
// ParamType and GeneratorCreationFunc are private types but are required
// for declarations of public methods AddTestPattern() and
// AddTestCaseInstantiation().
typedef typename TestCase::ParamType ParamType;
// A function that returns an instance of appropriate generator type.
typedef ParamGenerator<ParamType>(GeneratorCreationFunc)();
explicit ParameterizedTestCaseInfo(const char* name)
: test_case_name_(name) {}
// Test case base name for display purposes.
virtual const String& GetTestCaseName() const { return test_case_name_; }
// Test case id to verify identity.
virtual TypeId GetTestCaseTypeId() const { return GetTypeId<TestCase>(); }
// TEST_P macro uses AddTestPattern() to record information
// about a single test in a LocalTestInfo structure.
// test_case_name is the base name of the test case (without invocation
// prefix). test_base_name is the name of an individual test without
// parameter index. For the test SequenceA/FooTest.DoBar/1 FooTest is
// test case base name and DoBar is test base name.
void AddTestPattern(const char* test_case_name,
const char* test_base_name,
TestMetaFactoryBase<ParamType>* meta_factory) {
tests_.push_back(linked_ptr<TestInfo>(new TestInfo(test_case_name,
test_base_name,
meta_factory)));
}
// INSTANTIATE_TEST_CASE_P macro uses AddGenerator() to record information
// about a generator.
int AddTestCaseInstantiation(const char* instantiation_name,
GeneratorCreationFunc* func,
const char* file,
int line) {
instantiations_.push_back(::std::make_pair(instantiation_name, func));
return 0; // Return value used only to run this method in namespace scope.
}
// UnitTest class invokes this method to register tests in this test case
// test cases right before running tests in RUN_ALL_TESTS macro.
// This method should not be called more then once on any single
// instance of a ParameterizedTestCaseInfoBase derived class.
// UnitTest has a guard to prevent from calling this method more then once.
virtual void RegisterTests() {
for (typename TestInfoContainer::iterator test_it = tests_.begin();
test_it != tests_.end(); ++test_it) {
linked_ptr<TestInfo> test_info = *test_it;
for (typename InstantiationContainer::iterator gen_it =
instantiations_.begin(); gen_it != instantiations_.end();
++gen_it) {
const String& instantiation_name = gen_it->first;
ParamGenerator<ParamType> generator((*gen_it->second)());
Message test_case_name_stream;
if ( !instantiation_name.empty() )
test_case_name_stream << instantiation_name.c_str() << "/";
test_case_name_stream << test_info->test_case_base_name.c_str();
int i = 0;
for (typename ParamGenerator<ParamType>::iterator param_it =
generator.begin();
param_it != generator.end(); ++param_it, ++i) {
Message test_name_stream;
test_name_stream << test_info->test_base_name.c_str() << "/" << i;
::testing::internal::MakeAndRegisterTestInfo(
test_case_name_stream.GetString().c_str(),
test_name_stream.GetString().c_str(),
"", // test_case_comment
"", // comment; TODO(vladl@google.com): provide parameter value
// representation.
GetTestCaseTypeId(),
TestCase::SetUpTestCase,
TestCase::TearDownTestCase,
test_info->test_meta_factory->CreateTestFactory(*param_it));
} // for param_it
} // for gen_it
} // for test_it
} // RegisterTests
private:
// LocalTestInfo structure keeps information about a single test registered
// with TEST_P macro.
struct TestInfo {
TestInfo(const char* test_case_base_name,
const char* test_base_name,
TestMetaFactoryBase<ParamType>* test_meta_factory) :
test_case_base_name(test_case_base_name),
test_base_name(test_base_name),
test_meta_factory(test_meta_factory) {}
const String test_case_base_name;
const String test_base_name;
const scoped_ptr<TestMetaFactoryBase<ParamType> > test_meta_factory;
};
typedef ::std::vector<linked_ptr<TestInfo> > TestInfoContainer;
// Keeps pairs of <Instantiation name, Sequence generator creation function>
// received from INSTANTIATE_TEST_CASE_P macros.
typedef ::std::vector<std::pair<String, GeneratorCreationFunc*> >
InstantiationContainer;
const String test_case_name_;
TestInfoContainer tests_;
InstantiationContainer instantiations_;
GTEST_DISALLOW_COPY_AND_ASSIGN_(ParameterizedTestCaseInfo);
}; // class ParameterizedTestCaseInfo
// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
//
// ParameterizedTestCaseRegistry contains a map of ParameterizedTestCaseInfoBase
// classes accessed by test case names. TEST_P and INSTANTIATE_TEST_CASE_P
// macros use it to locate their corresponding ParameterizedTestCaseInfo
// descriptors.
class ParameterizedTestCaseRegistry {
public:
ParameterizedTestCaseRegistry() {}
~ParameterizedTestCaseRegistry() {
for (TestCaseInfoContainer::iterator it = test_case_infos_.begin();
it != test_case_infos_.end(); ++it) {
delete *it;
}
}
// Looks up or creates and returns a structure containing information about
// tests and instantiations of a particular test case.
template <class TestCase>
ParameterizedTestCaseInfo<TestCase>* GetTestCasePatternHolder(
const char* test_case_name,
const char* file,
int line) {
ParameterizedTestCaseInfo<TestCase>* typed_test_info = NULL;
for (TestCaseInfoContainer::iterator it = test_case_infos_.begin();
it != test_case_infos_.end(); ++it) {
if ((*it)->GetTestCaseName() == test_case_name) {
if ((*it)->GetTestCaseTypeId() != GetTypeId<TestCase>()) {
// Complain about incorrect usage of Google Test facilities
// and terminate the program since we cannot guaranty correct
// test case setup and tear-down in this case.
ReportInvalidTestCaseType(test_case_name, file, line);
abort();
} else {
// At this point we are sure that the object we found is of the same
// type we are looking for, so we downcast it to that type
// without further checks.
typed_test_info = CheckedDowncastToActualType<
ParameterizedTestCaseInfo<TestCase> >(*it);
}
break;
}
}
if (typed_test_info == NULL) {
typed_test_info = new ParameterizedTestCaseInfo<TestCase>(test_case_name);
test_case_infos_.push_back(typed_test_info);
}
return typed_test_info;
}
void RegisterTests() {
for (TestCaseInfoContainer::iterator it = test_case_infos_.begin();
it != test_case_infos_.end(); ++it) {
(*it)->RegisterTests();
}
}
private:
typedef ::std::vector<ParameterizedTestCaseInfoBase*> TestCaseInfoContainer;
TestCaseInfoContainer test_case_infos_;
GTEST_DISALLOW_COPY_AND_ASSIGN_(ParameterizedTestCaseRegistry);
};
} // namespace internal
} // namespace testing
#endif // GTEST_HAS_PARAM_TEST
#endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_H_

View File

@ -56,6 +56,8 @@
// enabled. // enabled.
// GTEST_HAS_PTHREAD - Define it to 1/0 to indicate that <pthread.h> // GTEST_HAS_PTHREAD - Define it to 1/0 to indicate that <pthread.h>
// is/isn't available. // is/isn't available.
// GTEST_HAS_TR1_TUPLE 1 - Define it to 1/0 to indicate tr1::tuple
// is/isn't available.
// This header defines the following utilities: // This header defines the following utilities:
// //
@ -85,7 +87,11 @@
// Note that it is possible that none of the GTEST_OS_ macros are defined. // Note that it is possible that none of the GTEST_OS_ macros are defined.
// //
// Macros indicating available Google Test features: // Macros indicating available Google Test features:
// GTEST_HAS_COMBINE - defined iff Combine construct is supported
// in value-parameterized tests.
// GTEST_HAS_DEATH_TEST - defined iff death tests are supported. // GTEST_HAS_DEATH_TEST - defined iff death tests are supported.
// GTEST_HAS_PARAM_TEST - defined iff value-parameterized tests are
// supported.
// GTEST_HAS_TYPED_TEST - defined iff typed tests are supported. // GTEST_HAS_TYPED_TEST - defined iff typed tests are supported.
// GTEST_HAS_TYPED_TEST_P - defined iff type-parameterized tests are // GTEST_HAS_TYPED_TEST_P - defined iff type-parameterized tests are
// supported. // supported.
@ -145,6 +151,7 @@
#include <stdlib.h> #include <stdlib.h>
#include <stdio.h> #include <stdio.h>
#include <iostream> // Used for GTEST_CHECK_
#define GTEST_NAME "Google Test" #define GTEST_NAME "Google Test"
#define GTEST_FLAG_PREFIX "gtest_" #define GTEST_FLAG_PREFIX "gtest_"
@ -292,6 +299,22 @@
#endif // GTEST_HAS_PTHREAD #endif // GTEST_HAS_PTHREAD
// Determines whether <tr1/tuple> is available. If you have <tr1/tuple>
// on your platform, define GTEST_HAS_TR1_TUPLE=1 for both the Google
// Test project and your tests. If you would like Google Test to detect
// <tr1/tuple> on your platform automatically, please open an issue
// ticket at http://code.google.com/p/googletest.
#ifndef GTEST_HAS_TR1_TUPLE
// The user didn't tell us, so we need to figure it out.
// GCC provides <tr1/tuple> since 4.0.0.
#if defined(__GNUC__) && (GTEST_GCC_VER_ >= 40000)
#define GTEST_HAS_TR1_TUPLE 1
#else
#define GTEST_HAS_TR1_TUPLE 0
#endif // __GNUC__
#endif // GTEST_HAS_TR1_TUPLE
// Determines whether to support death tests. // Determines whether to support death tests.
#if GTEST_HAS_STD_STRING && defined(GTEST_OS_LINUX) #if GTEST_HAS_STD_STRING && defined(GTEST_OS_LINUX)
#define GTEST_HAS_DEATH_TEST #define GTEST_HAS_DEATH_TEST
@ -305,6 +328,14 @@
#include <sys/mman.h> #include <sys/mman.h>
#endif // GTEST_HAS_STD_STRING && defined(GTEST_OS_LINUX) #endif // GTEST_HAS_STD_STRING && defined(GTEST_OS_LINUX)
// Determines whether to support value-parameterized tests.
#if defined(__GNUC__) || (_MSC_VER >= 1400)
// TODO(vladl@google.com): get the implementation rid of vector and list
// to compile on MSVC 7.1.
#define GTEST_HAS_PARAM_TEST
#endif // defined(__GNUC__) || (_MSC_VER >= 1400)
// Determines whether to support type-driven tests. // Determines whether to support type-driven tests.
// Typed tests need <typeinfo> and variadic macros, which gcc and VC // Typed tests need <typeinfo> and variadic macros, which gcc and VC
@ -314,6 +345,12 @@
#define GTEST_HAS_TYPED_TEST_P #define GTEST_HAS_TYPED_TEST_P
#endif // defined(__GNUC__) || (_MSC_VER >= 1400) #endif // defined(__GNUC__) || (_MSC_VER >= 1400)
// Determines whether to support Combine(). This only makes sense when
// value-parameterized tests are enabled.
#if defined(GTEST_HAS_PARAM_TEST) && GTEST_HAS_TR1_TUPLE
#define GTEST_HAS_COMBINE
#endif // defined(GTEST_HAS_PARAM_TEST) && GTEST_HAS_TR1_TUPLE
// Determines whether the system compiler uses UTF-16 for encoding wide strings. // Determines whether the system compiler uses UTF-16 for encoding wide strings.
#if defined(GTEST_OS_WINDOWS) || defined(GTEST_OS_CYGWIN) || \ #if defined(GTEST_OS_WINDOWS) || defined(GTEST_OS_CYGWIN) || \
defined(GTEST_OS_SYMBIAN) defined(GTEST_OS_SYMBIAN)
@ -421,7 +458,7 @@ class scoped_ptr {
#ifdef GTEST_HAS_DEATH_TEST #ifdef GTEST_HAS_DEATH_TEST
// Defines RE. Currently only needed for death tests. // Defines RE.
// A simple C++ wrapper for <regex.h>. It uses the POSIX Enxtended // A simple C++ wrapper for <regex.h>. It uses the POSIX Enxtended
// Regular Expression syntax. // Regular Expression syntax.
@ -442,22 +479,32 @@ class RE {
// Returns the string representation of the regex. // Returns the string representation of the regex.
const char* pattern() const { return pattern_; } const char* pattern() const { return pattern_; }
// Returns true iff str contains regular expression re. // FullMatch(str, re) returns true iff regular expression re matches
// the entire str.
// TODO(wan): make PartialMatch() work when str contains NUL // PartialMatch(str, re) returns true iff regular expression re
// characters. // matches a substring of str (including str itself).
//
// TODO(wan@google.com): make FullMatch() and PartialMatch() work
// when str contains NUL characters.
#if GTEST_HAS_STD_STRING #if GTEST_HAS_STD_STRING
static bool FullMatch(const ::std::string& str, const RE& re) {
return FullMatch(str.c_str(), re);
}
static bool PartialMatch(const ::std::string& str, const RE& re) { static bool PartialMatch(const ::std::string& str, const RE& re) {
return PartialMatch(str.c_str(), re); return PartialMatch(str.c_str(), re);
} }
#endif // GTEST_HAS_STD_STRING #endif // GTEST_HAS_STD_STRING
#if GTEST_HAS_GLOBAL_STRING #if GTEST_HAS_GLOBAL_STRING
static bool FullMatch(const ::string& str, const RE& re) {
return FullMatch(str.c_str(), re);
}
static bool PartialMatch(const ::string& str, const RE& re) { static bool PartialMatch(const ::string& str, const RE& re) {
return PartialMatch(str.c_str(), re); return PartialMatch(str.c_str(), re);
} }
#endif // GTEST_HAS_GLOBAL_STRING #endif // GTEST_HAS_GLOBAL_STRING
static bool FullMatch(const char* str, const RE& re);
static bool PartialMatch(const char* str, const RE& re); static bool PartialMatch(const char* str, const RE& re);
private: private:
@ -468,7 +515,8 @@ class RE {
// String type here, in order to simplify dependencies between the // String type here, in order to simplify dependencies between the
// files. // files.
const char* pattern_; const char* pattern_;
regex_t regex_; regex_t full_regex_; // For FullMatch().
regex_t partial_regex_; // For PartialMatch().
bool is_valid_; bool is_valid_;
}; };
@ -697,6 +745,53 @@ void abort();
inline void abort() { ::abort(); } inline void abort() { ::abort(); }
#endif // _WIN32_WCE #endif // _WIN32_WCE
// INTERNAL IMPLEMENTATION - DO NOT USE.
//
// GTEST_CHECK_ is an all-mode assert. It aborts the program if the condition
// is not satisfied.
// Synopsys:
// GTEST_CHECK_(boolean_condition);
// or
// GTEST_CHECK_(boolean_condition) << "Additional message";
//
// This checks the condition and if the condition is not satisfied
// it prints message about the condition violation, including the
// condition itself, plus additional message streamed into it, if any,
// and then it aborts the program. It aborts the program irrespective of
// whether it is built in the debug mode or not.
class GTestCheckProvider {
public:
GTestCheckProvider(const char* condition, const char* file, int line) {
FormatFileLocation(file, line);
::std::cerr << " ERROR: Condition " << condition << " failed. ";
}
~GTestCheckProvider() {
::std::cerr << ::std::endl;
abort();
}
void FormatFileLocation(const char* file, int line) {
if (file == NULL)
file = "unknown file";
if (line < 0) {
::std::cerr << file << ":";
} else {
#if _MSC_VER
::std::cerr << file << "(" << line << "):";
#else
::std::cerr << file << ":" << line << ":";
#endif
}
}
::std::ostream& GetStream() { return ::std::cerr; }
};
#define GTEST_CHECK_(condition) \
GTEST_AMBIGUOUS_ELSE_BLOCKER_ \
if (condition) \
; \
else \
::testing::internal::GTestCheckProvider(\
#condition, __FILE__, __LINE__).GetStream()
// Macro for referencing flags. // Macro for referencing flags.
#define GTEST_FLAG(name) FLAGS_gtest_##name #define GTEST_FLAG(name) FLAGS_gtest_##name

120
samples/prime_tables.h Normal file
View File

@ -0,0 +1,120 @@
// 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)
// Author: vladl@google.com (Vlad Losev)
// This provides interface PrimeTable that determines whether a number is a
// prime and determines a next prime number. This interface is used
// in Google Test samples demonstrating use of parameterized tests.
#ifndef GTEST_SAMPLES_PRIME_TABLES_H_
#define GTEST_SAMPLES_PRIME_TABLES_H_
#include <algorithm>
// 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 an array.
class PreCalculatedPrimeTable : public PrimeTable {
public:
// 'max' specifies the maximum number the prime table holds.
explicit PreCalculatedPrimeTable(int max)
: is_prime_size_(max + 1), is_prime_(new bool[max + 1]) {
CalculatePrimesUpTo(max);
}
virtual ~PreCalculatedPrimeTable() { delete[] is_prime_; }
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) {
::std::fill(is_prime_, is_prime_ + is_prime_size_, 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;
}
}
}
const int is_prime_size_;
bool* const is_prime_;
};
#endif // GTEST_SAMPLES_PRIME_TABLES_H_

View File

@ -33,13 +33,15 @@
#include "sample2.h" #include "sample2.h"
#include <string.h>
// Clones a 0-terminated C string, allocating memory using new. // Clones a 0-terminated C string, allocating memory using new.
const char * MyString::CloneCString(const char * c_string) { const char * MyString::CloneCString(const char * c_string) {
if (c_string == NULL) return NULL; if (c_string == NULL) return NULL;
const size_t len = strlen(c_string); const size_t len = strlen(c_string);
char * const clone = new char[ len + 1 ]; char * const clone = new char[ len + 1 ];
strcpy(clone, c_string); memcpy(clone, c_string, len + 1);
return clone; return clone;
} }

View File

@ -30,92 +30,13 @@
// Author: wan@google.com (Zhanyong Wan) // Author: wan@google.com (Zhanyong Wan)
// This sample shows how to test common properties of multiple // This sample shows how to test common properties of multiple
// implementations of the same interface (aka interface tests). We // implementations of the same interface (aka interface tests).
// put the code to be tested and the tests in the same file for
// simplicity. // The interface and its implementations are in this header.
#include "prime_tables.h"
#include <vector>
#include <gtest/gtest.h> #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 // First, we define some factory functions for creating instances of
// the implementations. You may be able to skip this step if all your // the implementations. You may be able to skip this step if all your
// implementations can be constructed the same way. // implementations can be constructed the same way.
@ -153,10 +74,10 @@ class PrimeTableTest : public testing::Test {
PrimeTable* const table_; PrimeTable* const table_;
}; };
using testing::Types;
#ifdef GTEST_HAS_TYPED_TEST #ifdef GTEST_HAS_TYPED_TEST
using testing::Types;
// Google Test offers two ways for reusing tests for different types. // Google Test offers two ways for reusing tests for different types.
// The first is called "typed tests". You should use it if you // The first is called "typed tests". You should use it if you
// already know *all* the types you are gonna exercise when you write // already know *all* the types you are gonna exercise when you write
@ -218,6 +139,8 @@ TYPED_TEST(PrimeTableTest, CanGetNextPrime) {
#ifdef GTEST_HAS_TYPED_TEST_P #ifdef GTEST_HAS_TYPED_TEST_P
using testing::Types;
// Sometimes, however, you don't yet know all the types that you want // 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 // 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 // author of an interface and expect other people to implement it, you

132
samples/sample7_unittest.cc Normal file
View File

@ -0,0 +1,132 @@
// 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: vladl@google.com (Vlad Losev)
// This sample shows how to test common properties of multiple
// implementations of an interface (aka interface tests) using
// value-parameterized tests. Each test in the test case has
// a parameter that is an interface pointer to an implementation
// tested.
// The interface and its implementations are in this header.
#include "prime_tables.h"
#include <gtest/gtest.h>
#ifdef GTEST_HAS_PARAM_TEST
using ::testing::TestWithParam;
using ::testing::Values;
// As a general rule, tested objects should not be reused between tests.
// Also, their constructors and destructors of tested objects can have
// side effects. Thus you should create and destroy them for each test.
// In this sample we will define a simple factory function for PrimeTable
// objects. We will instantiate objects in test's SetUp() method and
// delete them in TearDown() method.
typedef PrimeTable* CreatePrimeTableFunc();
PrimeTable* CreateOnTheFlyPrimeTable() {
return new OnTheFlyPrimeTable();
}
template <size_t max_precalculated>
PrimeTable* CreatePreCalculatedPrimeTable() {
return new PreCalculatedPrimeTable(max_precalculated);
}
// Inside the test body, fixture constructor, SetUp(), and TearDown()
// you can refer to the test parameter by GetParam().
// In this case, the test parameter is a PrimeTableFactory interface pointer
// which we use in fixture's SetUp() to create and store an instance of
// PrimeTable.
class PrimeTableTest : public TestWithParam<CreatePrimeTableFunc*> {
public:
virtual ~PrimeTableTest() { delete table_; }
virtual void SetUp() { table_ = (*GetParam())(); }
virtual void TearDown() {
delete table_;
table_ = NULL;
}
protected:
PrimeTable* table_;
};
TEST_P(PrimeTableTest, ReturnsFalseForNonPrimes) {
EXPECT_FALSE(table_->IsPrime(-5));
EXPECT_FALSE(table_->IsPrime(0));
EXPECT_FALSE(table_->IsPrime(1));
EXPECT_FALSE(table_->IsPrime(4));
EXPECT_FALSE(table_->IsPrime(6));
EXPECT_FALSE(table_->IsPrime(100));
}
TEST_P(PrimeTableTest, ReturnsTrueForPrimes) {
EXPECT_TRUE(table_->IsPrime(2));
EXPECT_TRUE(table_->IsPrime(3));
EXPECT_TRUE(table_->IsPrime(5));
EXPECT_TRUE(table_->IsPrime(7));
EXPECT_TRUE(table_->IsPrime(11));
EXPECT_TRUE(table_->IsPrime(131));
}
TEST_P(PrimeTableTest, CanGetNextPrime) {
EXPECT_EQ(2, table_->GetNextPrime(0));
EXPECT_EQ(3, table_->GetNextPrime(2));
EXPECT_EQ(5, table_->GetNextPrime(3));
EXPECT_EQ(7, table_->GetNextPrime(5));
EXPECT_EQ(11, table_->GetNextPrime(7));
EXPECT_EQ(131, table_->GetNextPrime(128));
}
// In order to run value-parameterized tests, you need to instantiate them,
// or bind them to a list of values which will be used as test parameters.
// You can instantiate them in a different translation module, or even
// instantiate them several times.
//
// Here, we instantiate our tests with a list of two PrimeTable object
// factory functions:
INSTANTIATE_TEST_CASE_P(
OnTheFlyAndPreCalculated,
PrimeTableTest,
Values(&CreateOnTheFlyPrimeTable, &CreatePreCalculatedPrimeTable<1000>));
#else
// Google Test doesn't support value-parameterized tests on some platforms
// and compilers, such as MSVC 7.1. If we use conditional compilation to
// compile out all code referring to the gtest_main library, MSVC linker
// will not link that library at all and consequently complain about
// missing entry point defined in that library (fatal error LNK1561:
// entry point must be defined). This dummy test keeps gtest_main linked in.
TEST(DummyTest, ValueParameterizedTestsAreNotSupportedOnThisPlatform) {}
#endif // GTEST_HAS_PARAM_TEST

173
samples/sample8_unittest.cc Normal file
View File

@ -0,0 +1,173 @@
// 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: vladl@google.com (Vlad Losev)
// This sample shows how to test code relying on some global flag variables.
// Combine() helps with generating all possible combinations of such flags,
// and each test is given one combination as a parameter.
// Use class definitions to test from this header.
#include "prime_tables.h"
#include <gtest/gtest.h>
#ifdef GTEST_HAS_COMBINE
// Suppose we want to introduce a new, improved implementation of PrimeTable
// which combines speed of PrecalcPrimeTable and versatility of
// OnTheFlyPrimeTable (see prime_tables.h). Inside it instantiates both
// PrecalcPrimeTable and OnTheFlyPrimeTable and uses the one that is more
// appropriate under the circumstances. But in low memory conditions, it can be
// told to instantiate without PrecalcPrimeTable instance at all and use only
// OnTheFlyPrimeTable.
class HybridPrimeTable : public PrimeTable {
public:
HybridPrimeTable(bool force_on_the_fly, int max_precalculated)
: on_the_fly_impl_(new OnTheFlyPrimeTable),
precalc_impl_(force_on_the_fly ? NULL :
new PreCalculatedPrimeTable(max_precalculated)),
max_precalculated_(max_precalculated) {}
virtual ~HybridPrimeTable() {
delete on_the_fly_impl_;
delete precalc_impl_;
}
virtual bool IsPrime(int n) const {
if (precalc_impl_ != NULL && n < max_precalculated_)
return precalc_impl_->IsPrime(n);
else
return on_the_fly_impl_->IsPrime(n);
}
virtual int GetNextPrime(int p) const {
int next_prime = -1;
if (precalc_impl_ != NULL && p < max_precalculated_)
next_prime = precalc_impl_->GetNextPrime(p);
return next_prime != -1 ? next_prime : on_the_fly_impl_->GetNextPrime(p);
}
private:
OnTheFlyPrimeTable* on_the_fly_impl_;
PreCalculatedPrimeTable* precalc_impl_;
int max_precalculated_;
};
using ::testing::TestWithParam;
using ::testing::Bool;
using ::testing::Values;
using ::testing::Combine;
// To test all code paths for HybridPrimeTable we must test it with numbers
// both within and outside PreCalculatedPrimeTable's capacity and also with
// PreCalculatedPrimeTable disabled. We do this by defining fixture which will
// accept different combinations of parameters for instantiating a
// HybridPrimeTable instance.
class PrimeTableTest : public TestWithParam< ::std::tr1::tuple<bool, int> > {
protected:
virtual void SetUp() {
// This can be written as
//
// bool force_on_the_fly;
// int max_precalculated;
// tie(force_on_the_fly, max_precalculated) = GetParam();
//
// once the Google C++ Style Guide allows use of ::std::tr1::tie.
//
bool force_on_the_fly = ::std::tr1::get<0>(GetParam());
int max_precalculated = ::std::tr1::get<1>(GetParam());
table_ = new HybridPrimeTable(force_on_the_fly, max_precalculated);
}
virtual void TearDown() {
delete table_;
table_ = NULL;
}
HybridPrimeTable* table_;
};
TEST_P(PrimeTableTest, ReturnsFalseForNonPrimes) {
// Inside the test body, you can refer to the test parameter by GetParam().
// In this case, the test parameter is a PrimeTable interface pointer which
// we can use directly.
// Please note that you can also save it in the fixture's SetUp() method
// or constructor and use saved copy in the tests.
EXPECT_FALSE(table_->IsPrime(-5));
EXPECT_FALSE(table_->IsPrime(0));
EXPECT_FALSE(table_->IsPrime(1));
EXPECT_FALSE(table_->IsPrime(4));
EXPECT_FALSE(table_->IsPrime(6));
EXPECT_FALSE(table_->IsPrime(100));
}
TEST_P(PrimeTableTest, ReturnsTrueForPrimes) {
EXPECT_TRUE(table_->IsPrime(2));
EXPECT_TRUE(table_->IsPrime(3));
EXPECT_TRUE(table_->IsPrime(5));
EXPECT_TRUE(table_->IsPrime(7));
EXPECT_TRUE(table_->IsPrime(11));
EXPECT_TRUE(table_->IsPrime(131));
}
TEST_P(PrimeTableTest, CanGetNextPrime) {
EXPECT_EQ(2, table_->GetNextPrime(0));
EXPECT_EQ(3, table_->GetNextPrime(2));
EXPECT_EQ(5, table_->GetNextPrime(3));
EXPECT_EQ(7, table_->GetNextPrime(5));
EXPECT_EQ(11, table_->GetNextPrime(7));
EXPECT_EQ(131, table_->GetNextPrime(128));
}
// In order to run value-parameterized tests, you need to instantiate them,
// or bind them to a list of values which will be used as test parameters.
// You can instantiate them in a different translation module, or even
// instantiate them several times.
//
// Here, we instantiate our tests with a list of parameters. We must combine
// all variations of the boolean flag suppressing PrecalcPrimeTable and some
// meaningful values for tests. We choose a small value (1), and a value that
// will put some of the tested numbers beyond the capability of the
// PrecalcPrimeTable instance and some inside it (10). Combine will produce all
// possible combinations.
INSTANTIATE_TEST_CASE_P(MeaningfulTestParameters,
PrimeTableTest,
Combine(Bool(), Values(1, 10)));
#else
// Google Test doesn't support Combine() on some platforms and compilers,
// such as MSVC 7.1. If we use conditional compilation to compile out
// all code referring to the gtest_main library, MSVC linker will not
// link that library at all and consequently complain about missing entry
// point defined in that library (fatal error LNK1561: entry point must
// be defined). This dummy test keeps gtest_main linked in.
TEST(DummyTest, CombineIsNotSupportedOnThisPlatform) {}
#endif // GTEST_HAS_COMBINE

View File

@ -67,7 +67,7 @@ to the following:
# Build gtest library; as it is outside of our source root, we need to # Build gtest library; as it is outside of our source root, we need to
# tell SCons that the directory it will refer to as # tell SCons that the directory it will refer to as
# e.g. $BUIlD_DIR/gtest is actually on disk in original form as # e.g. $BUILD_DIR/gtest is actually on disk in original form as
# ../../gtest (relative to your project root directory). Recall that # ../../gtest (relative to your project root directory). Recall that
# SCons by default copies all source files into the build directory # SCons by default copies all source files into the build directory
# before building. # before building.
@ -102,11 +102,6 @@ env = env.Clone()
env.Prepend(CPPPATH = ['..', env.Prepend(CPPPATH = ['..',
'../include']) '../include'])
# TODO(joi@google.com) Fix the code that causes this warning so that
# we see all warnings from the compiler about possible 64-bit porting
# issues.
env.Append(CCFLAGS=['-wd4267'])
# Sources shared by base library and library that includes main. # Sources shared by base library and library that includes main.
gtest_sources = ['../src/gtest-all.cc'] gtest_sources = ['../src/gtest-all.cc']
@ -125,6 +120,23 @@ if 'LIB_OUTPUT' in env.Dictionary():
env.Install('$LIB_OUTPUT', source=[gtest, gtest_main]) env.Install('$LIB_OUTPUT', source=[gtest, gtest_main])
def GtestBinary(env, target, dir_prefix, gtest_lib, additional_sources=None):
"""Helper to create gtest binaries: tests, samples, etc.
Args:
env: The SCons construction environment to use to build.
target: The basename of the target's main source file, also used as target
name.
dir_prefix: The path to prefix the main source file.
gtest_lib: The gtest lib to use.
"""
source = [env.File('%s.cc' % target, env.Dir(dir_prefix))]
if additional_sources:
source += additional_sources
unit_test = env.Program(target=target, source=source, LIBS=[gtest_lib])
if 'EXE_OUTPUT' in env.Dictionary():
env.Install('$EXE_OUTPUT', source=[unit_test])
def GtestUnitTest(env, target, gtest_lib, additional_sources=None): def GtestUnitTest(env, target, gtest_lib, additional_sources=None):
"""Helper to create gtest unit tests. """Helper to create gtest unit tests.
@ -133,15 +145,7 @@ def GtestUnitTest(env, target, gtest_lib, additional_sources=None):
target: The basename of the target unit test .cc file. target: The basename of the target unit test .cc file.
gtest_lib: The gtest lib to use. gtest_lib: The gtest lib to use.
""" """
source = [env.File('%s.cc' % target, env.Dir('../test'))] GtestBinary(env, target, "../test", gtest_lib, additional_sources)
if additional_sources:
source += additional_sources
unit_test = env.Program(target=target,
source=source,
LIBS=[gtest_lib, 'kernel32.lib', 'user32.lib'])
if 'EXE_OUTPUT' in env.Dictionary():
env.Install('$EXE_OUTPUT', source=[unit_test])
GtestUnitTest(env, 'gtest-filepath_test', gtest_main) GtestUnitTest(env, 'gtest-filepath_test', gtest_main)
GtestUnitTest(env, 'gtest-message_test', gtest_main) GtestUnitTest(env, 'gtest-message_test', gtest_main)
@ -157,9 +161,13 @@ GtestUnitTest(env, 'gtest_sole_header_test', gtest_main)
GtestUnitTest(env, 'gtest-test-part_test', gtest_main) GtestUnitTest(env, 'gtest-test-part_test', gtest_main)
GtestUnitTest(env, 'gtest-typed-test_test', gtest_main, GtestUnitTest(env, 'gtest-typed-test_test', gtest_main,
additional_sources=['../test/gtest-typed-test2_test.cc']) additional_sources=['../test/gtest-typed-test2_test.cc'])
GtestUnitTest(env, 'gtest-param-test_test', gtest,
additional_sources=['../test/gtest-param-test2_test.cc'])
GtestUnitTest(env, 'gtest_unittest', gtest) GtestUnitTest(env, 'gtest_unittest', gtest)
GtestUnitTest(env, 'gtest_output_test_', gtest) GtestUnitTest(env, 'gtest_output_test_', gtest)
GtestUnitTest(env, 'gtest_color_test_', gtest) GtestUnitTest(env, 'gtest_color_test_', gtest)
GtestUnitTest(env, 'gtest-linked_ptr_test', gtest_main)
GtestUnitTest(env, 'gtest-port_test', gtest_main)
# TODO(wan@google.com) Add these unit tests: # TODO(wan@google.com) Add these unit tests:
# - gtest_break_on_failure_unittest_ # - gtest_break_on_failure_unittest_
@ -179,3 +187,33 @@ for flag in ["/O1", "/Os", "/Og", "/Oy"]:
linker_flags.remove(flag) linker_flags.remove(flag)
GtestUnitTest(special_env, 'gtest_env_var_test_', gtest) GtestUnitTest(special_env, 'gtest_env_var_test_', gtest)
GtestUnitTest(special_env, 'gtest_uninitialized_test_', gtest) GtestUnitTest(special_env, 'gtest_uninitialized_test_', gtest)
def GtestSample(env, target, gtest_lib, additional_sources=None):
"""Helper to create gtest samples.
Args:
env: The SCons construction environment to use to build.
target: The basename of the target unit test .cc file.
gtest_lib: The gtest lib to use.
"""
GtestBinary(env, target, "../samples", gtest_lib, additional_sources)
# Use the GTEST_BUILD_SAMPLES build variable to control building of samples.
# In your SConstruct file, add
# vars = Variables()
# vars.Add(BoolVariable('GTEST_BUILD_SAMPLES', 'Build samples', True))
# my_environment = Environment(variables = vars, ...)
# Then, in the command line use GTEST_BUILD_SAMPLES=true to enable them.
#
if env.get('GTEST_BUILD_SAMPLES', False):
sample1_obj = env.Object('../samples/sample1.cc')
GtestSample(env, 'sample1_unittest', gtest_main,
additional_sources=[sample1_obj])
GtestSample(env, 'sample2_unittest', gtest_main,
additional_sources=['../samples/sample2.cc'])
GtestSample(env, 'sample3_unittest', gtest_main)
GtestSample(env, 'sample5_unittest', gtest_main,
additional_sources=[sample1_obj])
GtestSample(env, 'sample6_unittest', gtest_main)
GtestSample(env, 'sample7_unittest', gtest_main)
GtestSample(env, 'sample8_unittest', gtest_main)

View File

@ -53,7 +53,6 @@
#include <windows.h> // NOLINT #include <windows.h> // NOLINT
#endif // GTEST_OS_WINDOWS #endif // GTEST_OS_WINDOWS
#include <ostream> // NOLINT
#include <gtest/gtest.h> #include <gtest/gtest.h>
#include <gtest/gtest-spi.h> #include <gtest/gtest-spi.h>
@ -846,7 +845,7 @@ class OsStackTraceGetterInterface {
GTEST_DISALLOW_COPY_AND_ASSIGN_(OsStackTraceGetterInterface); GTEST_DISALLOW_COPY_AND_ASSIGN_(OsStackTraceGetterInterface);
}; };
// A working implemenation of the OsStackTraceGetterInterface interface. // A working implementation of the OsStackTraceGetterInterface interface.
class OsStackTraceGetter : public OsStackTraceGetterInterface { class OsStackTraceGetter : public OsStackTraceGetterInterface {
public: public:
OsStackTraceGetter() {} OsStackTraceGetter() {}
@ -1063,6 +1062,14 @@ class UnitTestImpl {
tear_down_tc)->AddTestInfo(test_info); tear_down_tc)->AddTestInfo(test_info);
} }
#ifdef GTEST_HAS_PARAM_TEST
// Returns ParameterizedTestCaseRegistry object used to keep track of
// value-parameterized tests and instantiate and register them.
internal::ParameterizedTestCaseRegistry& parameterized_test_registry() {
return parameterized_test_registry_;
}
#endif // GTEST_HAS_PARAM_TEST
// Sets the TestCase object for the test that's currently running. // Sets the TestCase object for the test that's currently running.
void set_current_test_case(TestCase* current_test_case) { void set_current_test_case(TestCase* current_test_case) {
current_test_case_ = current_test_case; current_test_case_ = current_test_case;
@ -1075,6 +1082,14 @@ class UnitTestImpl {
current_test_info_ = current_test_info; current_test_info_ = current_test_info;
} }
// Registers all parameterized tests defined using TEST_P and
// INSTANTIATE_TEST_P, creating regular tests for each test/parameter
// combination. This method can be called more then once; it has
// guards protecting from registering the tests more then once.
// If value-parameterized tests are disabled, RegisterParameterizedTests
// is present but does nothing.
void RegisterParameterizedTests();
// Runs all tests in this UnitTest object, prints the result, and // Runs all tests in this UnitTest object, prints the result, and
// returns 0 if all tests are successful, or 1 otherwise. If any // returns 0 if all tests are successful, or 1 otherwise. If any
// exception is thrown during a test on Windows, this test is // exception is thrown during a test on Windows, this test is
@ -1169,6 +1184,15 @@ class UnitTestImpl {
internal::List<TestCase*> test_cases_; // The list of TestCases. internal::List<TestCase*> test_cases_; // The list of TestCases.
#ifdef GTEST_HAS_PARAM_TEST
// ParameterizedTestRegistry object used to register value-parameterized
// tests.
internal::ParameterizedTestCaseRegistry parameterized_test_registry_;
// Indicates whether RegisterParameterizedTests() has been called already.
bool parameterized_tests_registered_;
#endif // GTEST_HAS_PARAM_TEST
// Points to the last death test case registered. Initially NULL. // Points to the last death test case registered. Initially NULL.
internal::ListNode<TestCase*>* last_death_test_case_; internal::ListNode<TestCase*>* last_death_test_case_;

View File

@ -56,25 +56,49 @@ namespace internal {
// Implements RE. Currently only needed for death tests. // Implements RE. Currently only needed for death tests.
RE::~RE() { RE::~RE() {
regfree(&regex_); regfree(&partial_regex_);
regfree(&full_regex_);
free(const_cast<char*>(pattern_)); free(const_cast<char*>(pattern_));
} }
// Returns true iff str contains regular expression re. // Returns true iff regular expression re matches the entire str.
bool RE::FullMatch(const char* str, const RE& re) {
if (!re.is_valid_) return false;
regmatch_t match;
return regexec(&re.full_regex_, str, 1, &match, 0) == 0;
}
// Returns true iff regular expression re matches a substring of str
// (including str itself).
bool RE::PartialMatch(const char* str, const RE& re) { bool RE::PartialMatch(const char* str, const RE& re) {
if (!re.is_valid_) return false; if (!re.is_valid_) return false;
regmatch_t match; regmatch_t match;
return regexec(&re.regex_, str, 1, &match, 0) == 0; return regexec(&re.partial_regex_, str, 1, &match, 0) == 0;
} }
// Initializes an RE from its string representation. // Initializes an RE from its string representation.
void RE::Init(const char* regex) { void RE::Init(const char* regex) {
pattern_ = strdup(regex); pattern_ = strdup(regex);
is_valid_ = regcomp(&regex_, regex, REG_EXTENDED) == 0;
// Reserves enough bytes to hold the regular expression used for a
// full match.
const size_t full_regex_len = strlen(regex) + 10;
char* const full_pattern = new char[full_regex_len];
snprintf(full_pattern, full_regex_len, "^(%s)$", regex);
is_valid_ = regcomp(&full_regex_, full_pattern, REG_EXTENDED) == 0;
// We want to call regcomp(&partial_regex_, ...) even if the
// previous expression returns false. Otherwise partial_regex_ may
// not be properly initialized can may cause trouble when it's
// freed.
is_valid_ = (regcomp(&partial_regex_, regex, REG_EXTENDED) == 0) && is_valid_;
EXPECT_TRUE(is_valid_) EXPECT_TRUE(is_valid_)
<< "Regular expression \"" << regex << "Regular expression \"" << regex
<< "\" is not a valid POSIX Extended regular expression."; << "\" is not a valid POSIX Extended regular expression.";
delete[] full_pattern;
} }
#endif // GTEST_HAS_DEATH_TEST #endif // GTEST_HAS_DEATH_TEST

View File

@ -277,6 +277,9 @@ void AssertHelper::operator=(const Message& message) const {
); // NOLINT ); // NOLINT
} }
// Mutex for linked pointers.
Mutex g_linked_ptr_mutex(Mutex::NO_CONSTRUCTOR_NEEDED_FOR_STATIC_MUTEX);
// Application pathname gotten in InitGoogleTest. // Application pathname gotten in InitGoogleTest.
String g_executable_path; String g_executable_path;
@ -830,7 +833,7 @@ static void StreamWideCharsToMessage(const wchar_t* wstr, size_t len,
// several other places). // several other places).
for (size_t i = 0; i != len; ) { // NOLINT for (size_t i = 0; i != len; ) { // NOLINT
if (wstr[i] != L'\0') { if (wstr[i] != L'\0') {
*msg << WideStringToUtf8(wstr + i, len - i); *msg << WideStringToUtf8(wstr + i, static_cast<int>(len - i));
while (i != len && wstr[i] != L'\0') while (i != len && wstr[i] != L'\0')
i++; i++;
} else { } else {
@ -1453,7 +1456,7 @@ inline UInt32 CreateCodePointFromUtf16SurrogatePair(wchar_t first,
// will be encoded as individual Unicode characters from Basic Normal Plane. // will be encoded as individual Unicode characters from Basic Normal Plane.
String WideStringToUtf8(const wchar_t* str, int num_chars) { String WideStringToUtf8(const wchar_t* str, int num_chars) {
if (num_chars == -1) if (num_chars == -1)
num_chars = wcslen(str); num_chars = static_cast<int>(wcslen(str));
StrStream stream; StrStream stream;
for (int i = 0; i < num_chars; ++i) { for (int i = 0; i < num_chars; ++i) {
@ -2080,6 +2083,25 @@ TestInfo* MakeAndRegisterTestInfo(
return test_info; return test_info;
} }
#ifdef GTEST_HAS_PARAM_TEST
void ReportInvalidTestCaseType(const char* test_case_name,
const char* file, int line) {
Message errors;
errors
<< "Attempted redefinition of test case " << test_case_name << ".\n"
<< "All tests in the same test case must use the same test fixture\n"
<< "class. However, in test case " << test_case_name << ", you tried\n"
<< "to define a test using a fixture class different from the one\n"
<< "used earlier. This can happen if the two fixture classes are\n"
<< "from different namespaces and have the same name. You should\n"
<< "probably rename one of the classes to put the tests into different\n"
<< "test cases.";
fprintf(stderr, "%s %s", FormatFileLocation(file, line).c_str(),
errors.GetString().c_str());
}
#endif // GTEST_HAS_PARAM_TEST
} // namespace internal } // namespace internal
// Returns the test case name. // Returns the test case name.
@ -2156,6 +2178,18 @@ TestInfo * TestCase::GetTestInfo(const char* test_name) {
namespace internal { namespace internal {
// This method expands all parameterized tests registered with macros TEST_P
// and INSTANTIATE_TEST_CASE_P into regular tests and registers those.
// This will be done just once during the program runtime.
void UnitTestImpl::RegisterParameterizedTests() {
#ifdef GTEST_HAS_PARAM_TEST
if (!parameterized_tests_registered_) {
parameterized_test_registry_.RegisterTests();
parameterized_tests_registered_ = true;
}
#endif
}
// Creates the test object, runs it, records its result, and then // Creates the test object, runs it, records its result, and then
// deletes it. // deletes it.
void TestInfoImpl::Run() { void TestInfoImpl::Run() {
@ -3269,6 +3303,16 @@ const TestInfo* UnitTest::current_test_info() const {
return impl_->current_test_info(); return impl_->current_test_info();
} }
#ifdef GTEST_HAS_PARAM_TEST
// Returns ParameterizedTestCaseRegistry object used to keep track of
// value-parameterized tests and instantiate and register them.
// L < mutex_
internal::ParameterizedTestCaseRegistry&
UnitTest::parameterized_test_registry() {
return impl_->parameterized_test_registry();
}
#endif // GTEST_HAS_PARAM_TEST
// Creates an empty UnitTest. // Creates an empty UnitTest.
UnitTest::UnitTest() { UnitTest::UnitTest() {
impl_ = new internal::UnitTestImpl(this); impl_ = new internal::UnitTestImpl(this);
@ -3314,6 +3358,10 @@ UnitTestImpl::UnitTestImpl(UnitTest* parent)
per_thread_test_part_result_reporter_( per_thread_test_part_result_reporter_(
&default_per_thread_test_part_result_reporter_), &default_per_thread_test_part_result_reporter_),
test_cases_(), test_cases_(),
#ifdef GTEST_HAS_PARAM_TEST
parameterized_test_registry_(),
parameterized_tests_registered_(false),
#endif // GTEST_HAS_PARAM_TEST
last_death_test_case_(NULL), last_death_test_case_(NULL),
current_test_case_(NULL), current_test_case_(NULL),
current_test_info_(NULL), current_test_info_(NULL),
@ -3415,6 +3463,10 @@ static void TearDownEnvironment(Environment* env) { env->TearDown(); }
// considered to be failed, but the rest of the tests will still be // considered to be failed, but the rest of the tests will still be
// run. (We disable exceptions on Linux and Mac OS X, so the issue // run. (We disable exceptions on Linux and Mac OS X, so the issue
// doesn't apply there.) // doesn't apply there.)
// When parameterized tests are enabled, it explands and registers
// parameterized tests first in RegisterParameterizedTests().
// All other functions called from RunAllTests() may safely assume that
// parameterized tests are ready to be counted and run.
int UnitTestImpl::RunAllTests() { int UnitTestImpl::RunAllTests() {
// Makes sure InitGoogleTest() was called. // Makes sure InitGoogleTest() was called.
if (!GTestIsInitialized()) { if (!GTestIsInitialized()) {
@ -3424,6 +3476,8 @@ int UnitTestImpl::RunAllTests() {
return 1; return 1;
} }
RegisterParameterizedTests();
// Lists all the tests and exits if the --gtest_list_tests // Lists all the tests and exits if the --gtest_list_tests
// flag was specified. // flag was specified.
if (GTEST_FLAG(list_tests)) { if (GTEST_FLAG(list_tests)) {
@ -3639,7 +3693,7 @@ internal::TestResult* UnitTestImpl::current_test_result() {
} }
// TestInfoImpl constructor. The new instance assumes ownership of the test // TestInfoImpl constructor. The new instance assumes ownership of the test
// factory opbject. // factory object.
TestInfoImpl::TestInfoImpl(TestInfo* parent, TestInfoImpl::TestInfoImpl(TestInfo* parent,
const char* test_case_name, const char* test_case_name,
const char* name, const char* name,
@ -3663,10 +3717,6 @@ TestInfoImpl::~TestInfoImpl() {
delete factory_; delete factory_;
} }
} // namespace internal
namespace internal {
// Parses a string as a command line flag. The string should have // Parses a string as a command line flag. The string should have
// the format "--flag=value". When def_optional is true, the "=value" // the format "--flag=value". When def_optional is true, the "=value"
// part can be omitted. // part can be omitted.
@ -3814,6 +3864,27 @@ void InitGoogleTestImpl(int* argc, CharType** argv) {
} }
} }
// Returns the current OS stack trace as a String.
//
// The maximum number of stack frames to be included is specified by
// the gtest_stack_trace_depth flag. The skip_count parameter
// specifies the number of top frames to be skipped, which doesn't
// count against the number of frames to be included.
//
// For example, if Foo() calls Bar(), which in turn calls
// GetCurrentOsStackTraceExceptTop(..., 1), Foo() will be included in
// the trace but Bar() and GetCurrentOsStackTraceExceptTop() won't.
String GetCurrentOsStackTraceExceptTop(UnitTest* unit_test, int skip_count) {
// We pass skip_count + 1 to skip this wrapper function in addition
// to what the user really wants to skip.
return unit_test->impl()->CurrentOsStackTraceExceptTop(skip_count + 1);
}
// Returns the number of failed test parts in the given test result object.
int GetFailedPartCount(const TestResult* result) {
return result->failed_part_count();
}
} // namespace internal } // namespace internal
// Initializes Google Test. This must be called before calling // Initializes Google Test. This must be called before calling

View File

@ -83,12 +83,6 @@ int _rmdir(const char* path) {
return ret; return ret;
} }
#elif defined(GTEST_LINUX_GOOGLE3_MODE)
// Creates a temporary directory and returns its path.
const char* MakeTempDir() {
static char dir_name[] = "gtest-filepath_test_tmpXXXXXX";
return mkdtemp(dir_name);
}
#endif // _WIN32_WCE #endif // _WIN32_WCE
#ifndef _WIN32_WCE #ifndef _WIN32_WCE

View File

@ -0,0 +1,154 @@
// Copyright 2003, 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.
//
// Authors: Dan Egnor (egnor@google.com)
// Ported to Windows: Vadim Berman (vadimb@google.com)
#include <gtest/internal/gtest-linked_ptr.h>
#include <stdlib.h>
#include <gtest/gtest.h>
namespace {
using testing::Message;
using testing::internal::linked_ptr;
int num;
Message* history = NULL;
// Class which tracks allocation/deallocation
class A {
public:
A(): mynum(num++) { *history << "A" << mynum << " ctor\n"; }
virtual ~A() { *history << "A" << mynum << " dtor\n"; }
virtual void Use() { *history << "A" << mynum << " use\n"; }
protected:
int mynum;
};
// Subclass
class B : public A {
public:
B() { *history << "B" << mynum << " ctor\n"; }
~B() { *history << "B" << mynum << " dtor\n"; }
virtual void Use() { *history << "B" << mynum << " use\n"; }
};
class LinkedPtrTest : public testing::Test {
public:
LinkedPtrTest() {
num = 0;
history = new Message;
}
virtual ~LinkedPtrTest() {
delete history;
history = NULL;
}
};
TEST_F(LinkedPtrTest, GeneralTest) {
{
linked_ptr<A> a0, a1, a2;
a0 = a0;
a1 = a2;
ASSERT_EQ(a0.get(), static_cast<A*>(NULL));
ASSERT_EQ(a1.get(), static_cast<A*>(NULL));
ASSERT_EQ(a2.get(), static_cast<A*>(NULL));
ASSERT_TRUE(a0 == NULL);
ASSERT_TRUE(a1 == NULL);
ASSERT_TRUE(a2 == NULL);
{
linked_ptr<A> a3(new A);
a0 = a3;
ASSERT_TRUE(a0 == a3);
ASSERT_TRUE(a0 != NULL);
ASSERT_TRUE(a0.get() == a3);
ASSERT_TRUE(a0 == a3.get());
linked_ptr<A> a4(a0);
a1 = a4;
linked_ptr<A> a5(new A);
ASSERT_TRUE(a5.get() != a3);
ASSERT_TRUE(a5 != a3.get());
a2 = a5;
linked_ptr<B> b0(new B);
linked_ptr<A> a6(b0);
ASSERT_TRUE(b0 == a6);
ASSERT_TRUE(a6 == b0);
ASSERT_TRUE(b0 != NULL);
a5 = b0;
a5 = b0;
a3->Use();
a4->Use();
a5->Use();
a6->Use();
b0->Use();
(*b0).Use();
b0.get()->Use();
}
a0->Use();
a1->Use();
a2->Use();
a1 = a2;
a2.reset(new A);
a0.reset();
linked_ptr<A> a7;
}
ASSERT_STREQ(
"A0 ctor\n"
"A1 ctor\n"
"A2 ctor\n"
"B2 ctor\n"
"A0 use\n"
"A0 use\n"
"B2 use\n"
"B2 use\n"
"B2 use\n"
"B2 use\n"
"B2 use\n"
"B2 dtor\n"
"A2 dtor\n"
"A0 use\n"
"A0 use\n"
"A1 use\n"
"A3 ctor\n"
"A0 dtor\n"
"A3 dtor\n"
"A1 dtor\n",
history->GetString().c_str()
);
}
} // Unnamed namespace

View File

@ -0,0 +1,65 @@
// 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: vladl@google.com (Vlad Losev)
//
// Tests for Google Test itself. This verifies that the basic constructs of
// Google Test work.
#include <gtest/gtest.h>
#include "test/gtest-param-test_test.h"
#ifdef GTEST_HAS_PARAM_TEST
using ::testing::Values;
using ::testing::internal::ParamGenerator;
// Tests that generators defined in a different translation unit
// are functional. The test using extern_gen is defined
// in gtest-param-test_test.cc.
ParamGenerator<int> extern_gen = Values(33);
// Tests that a parameterized test case can be defined in one translation unit
// and instantiated in another. The test is defined in gtest-param-test_test.cc
// and ExternalInstantiationTest fixture class is defined in
// gtest-param-test_test.h.
INSTANTIATE_TEST_CASE_P(MultiplesOf33,
ExternalInstantiationTest,
Values(33, 66));
// Tests that a parameterized test case can be instantiated
// in multiple translation units. Another instantiation is defined
// in gtest-param-test_test.cc and InstantiationInMultipleTranslaionUnitsTest
// fixture is defined in gtest-param-test_test.h
INSTANTIATE_TEST_CASE_P(Sequence2,
InstantiationInMultipleTranslaionUnitsTest,
Values(42*3, 42*4, 42*5));
#endif // GTEST_HAS_PARAM_TEST

View File

@ -0,0 +1,796 @@
// 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: vladl@google.com (Vlad Losev)
//
// Tests for Google Test itself. This file verifies that the parameter
// generators objects produce correct parameter sequences and that
// Google Test runtime instantiates correct tests from those sequences.
#include <gtest/gtest.h>
#ifdef GTEST_HAS_PARAM_TEST
#include <algorithm>
#include <iostream>
#include <list>
#include <vector>
#ifdef GTEST_HAS_COMBINE
#include <tr1/tuple>
#endif // GTEST_HAS_COMBINE
// To include gtest-internal-inl.h.
#define GTEST_IMPLEMENTATION
#include "src/gtest-internal-inl.h" // for UnitTestOptions
#undef GTEST_IMPLEMENTATION
#include "test/gtest-param-test_test.h"
using ::std::vector;
using ::std::sort;
using ::testing::AddGlobalTestEnvironment;
using ::testing::Bool;
using ::testing::Message;
using ::testing::Range;
using ::testing::TestWithParam;
using ::testing::Values;
using ::testing::ValuesIn;
#ifdef GTEST_HAS_COMBINE
using ::testing::Combine;
using ::std::tr1::get;
using ::std::tr1::make_tuple;
using ::std::tr1::tuple;
#endif // GTEST_HAS_COMBINE
using ::testing::internal::ParamGenerator;
using ::testing::internal::UnitTestOptions;
// Verifies that a sequence generated by the generator and accessed
// via the iterator object matches the expected one using Google Test
// assertions.
template <typename T, size_t N>
void VerifyGenerator(const ParamGenerator<T>& generator,
const T (&expected_values)[N]) {
typename ParamGenerator<T>::iterator it = generator.begin();
for (size_t i = 0; i < N; ++i) {
ASSERT_FALSE(it == generator.end())
<< "At element " << i << " when accessing via an iterator "
<< "created with the copy constructor." << std::endl;
EXPECT_EQ(expected_values[i], *it)
<< "At element " << i << " when accessing via an iterator "
<< "created with the copy constructor." << std::endl;
it++;
}
EXPECT_TRUE(it == generator.end())
<< "At the presumed end of sequence when accessing via an iterator "
<< "created with the copy constructor." << std::endl;
// Test the iterator assignment. The following lines verify that
// the sequence accessed via an iterator initialized via the
// assignment operator (as opposed to a copy constructor) matches
// just the same.
it = generator.begin();
for (size_t i = 0; i < N; ++i) {
ASSERT_FALSE(it == generator.end())
<< "At element " << i << " when accessing via an iterator "
<< "created with the assignment operator." << std::endl;
EXPECT_EQ(expected_values[i], *it)
<< "At element " << i << " when accessing via an iterator "
<< "created with the assignment operator." << std::endl;
it++;
}
EXPECT_TRUE(it == generator.end())
<< "At the presumed end of sequence when accessing via an iterator "
<< "created with the assignment operator." << std::endl;
}
template <typename T>
void VerifyGeneratorIsEmpty(const ParamGenerator<T>& generator) {
typename ParamGenerator<T>::iterator it = generator.begin();
EXPECT_TRUE(it == generator.end());
it = generator.begin();
EXPECT_TRUE(it == generator.end());
}
// Generator tests. They test that each of the provided generator functions
// generates an expected sequence of values. The general test pattern
// instantiates a generator using one of the generator functions,
// checks the sequence produced by the generator using its iterator API,
// and then resets the iterator back to the beginning of the sequence
// and checks the sequence again.
// Tests that iterators produced by generator functions conform to the
// ForwardIterator concept.
TEST(IteratorTest, ParamIteratorConformsToForwardIteratorConcept) {
const ParamGenerator<int> gen = Range(0, 10);
ParamGenerator<int>::iterator it = gen.begin();
// Verifies that iterator initialization works as expected.
ParamGenerator<int>::iterator it2 = it;
EXPECT_TRUE(*it == *it2) << "Initialized iterators must point to the "
<< "element same as its source points to";
// Verifies that iterator assignment works as expected.
it++;
EXPECT_FALSE(*it == *it2);
it2 = it;
EXPECT_TRUE(*it == *it2) << "Assigned iterators must point to the "
<< "element same as its source points to";
// Verifies that prefix operator++() returns *this.
EXPECT_EQ(&it, &(++it)) << "Result of the prefix operator++ must be "
<< "refer to the original object";
// Verifies that the result of the postfix operator++ points to the value
// pointed to by the original iterator.
int original_value = *it; // Have to compute it outside of macro call to be
// unaffected by the parameter evaluation order.
EXPECT_EQ(original_value, *(it++));
// Verifies that prefix and postfix operator++() advance an iterator
// all the same.
it2 = it;
it++;
++it2;
EXPECT_TRUE(*it == *it2);
}
// Tests that Range() generates the expected sequence.
TEST(RangeTest, IntRangeWithDefaultStep) {
const ParamGenerator<int> gen = Range(0, 3);
const int expected_values[] = {0, 1, 2};
VerifyGenerator(gen, expected_values);
}
// Edge case. Tests that Range() generates the single element sequence
// as expected when provided with range limits that are equal.
TEST(RangeTest, IntRangeSingleValue) {
const ParamGenerator<int> gen = Range(0, 1);
const int expected_values[] = {0};
VerifyGenerator(gen, expected_values);
}
// Edge case. Tests that Range() with generates empty sequence when
// supplied with an empty range.
TEST(RangeTest, IntRangeEmpty) {
const ParamGenerator<int> gen = Range(0, 0);
VerifyGeneratorIsEmpty(gen);
}
// Tests that Range() with custom step (greater then one) generates
// the expected sequence.
TEST(RangeTest, IntRangeWithCustomStep) {
const ParamGenerator<int> gen = Range(0, 9, 3);
const int expected_values[] = {0, 3, 6};
VerifyGenerator(gen, expected_values);
}
// Tests that Range() with custom step (greater then one) generates
// the expected sequence when the last element does not fall on the
// upper range limit. Sequences generated by Range() must not have
// elements beyond the range limits.
TEST(RangeTest, IntRangeWithCustomStepOverUpperBound) {
const ParamGenerator<int> gen = Range(0, 4, 3);
const int expected_values[] = {0, 3};
VerifyGenerator(gen, expected_values);
}
// Verifies that Range works with user-defined types that define
// copy constructor, operator=(), operator+(), and operator<().
class DogAdder {
public:
explicit DogAdder(const char* value) : value_(value) {}
DogAdder(const DogAdder& other) : value_(other.value_.c_str()) {}
DogAdder operator=(const DogAdder& other) {
if (this != &other)
value_ = other.value_;
return *this;
}
DogAdder operator+(const DogAdder& other) const {
Message msg;
msg << value_.c_str() << other.value_.c_str();
return DogAdder(msg.GetString().c_str());
}
bool operator<(const DogAdder& other) const {
return value_ < other.value_;
}
const ::testing::internal::String& value() const { return value_; }
private:
::testing::internal::String value_;
};
TEST(RangeTest, WorksWithACustomType) {
const ParamGenerator<DogAdder> gen =
Range(DogAdder("cat"), DogAdder("catdogdog"), DogAdder("dog"));
ParamGenerator<DogAdder>::iterator it = gen.begin();
ASSERT_FALSE(it == gen.end());
EXPECT_STREQ("cat", it->value().c_str());
ASSERT_FALSE(++it == gen.end());
EXPECT_STREQ("catdog", it->value().c_str());
EXPECT_TRUE(++it == gen.end());
}
class IntWrapper {
public:
explicit IntWrapper(int value) : value_(value) {}
IntWrapper(const IntWrapper& other) : value_(other.value_) {}
IntWrapper operator=(const IntWrapper& other) {
value_ = other.value_;
return *this;
}
// operator+() adds a different type.
IntWrapper operator+(int other) const { return IntWrapper(value_ + other); }
bool operator<(const IntWrapper& other) const {
return value_ < other.value_;
}
int value() const { return value_; }
private:
int value_;
};
TEST(RangeTest, WorksWithACustomTypeWithDifferentIncrementType) {
const ParamGenerator<IntWrapper> gen = Range(IntWrapper(0), IntWrapper(2));
ParamGenerator<IntWrapper>::iterator it = gen.begin();
ASSERT_FALSE(it == gen.end());
EXPECT_EQ(0, it->value());
ASSERT_FALSE(++it == gen.end());
EXPECT_EQ(1, it->value());
EXPECT_TRUE(++it == gen.end());
}
// Tests that ValuesIn() with an array parameter generates
// the expected sequence.
TEST(ValuesInTest, ValuesInArray) {
int array[] = {3, 5, 8};
const ParamGenerator<int> gen = ValuesIn(array);
VerifyGenerator(gen, array);
}
// Tests that ValuesIn() with a const array parameter generates
// the expected sequence.
TEST(ValuesInTest, ValuesInConstArray) {
const int array[] = {3, 5, 8};
const ParamGenerator<int> gen = ValuesIn(array);
VerifyGenerator(gen, array);
}
// Edge case. Tests that ValuesIn() with an array parameter containing a
// single element generates the single element sequence.
TEST(ValuesInTest, ValuesInSingleElementArray) {
int array[] = {42};
const ParamGenerator<int> gen = ValuesIn(array);
VerifyGenerator(gen, array);
}
// Tests that ValuesIn() generates the expected sequence for an STL
// container (vector).
TEST(ValuesInTest, ValuesInVector) {
typedef ::std::vector<int> ContainerType;
ContainerType values;
values.push_back(3);
values.push_back(5);
values.push_back(8);
const ParamGenerator<int> gen = ValuesIn(values);
const int expected_values[] = {3, 5, 8};
VerifyGenerator(gen, expected_values);
}
// Tests that ValuesIn() generates the expected sequence.
TEST(ValuesInTest, ValuesInIteratorRange) {
typedef ::std::vector<int> ContainerType;
ContainerType values;
values.push_back(3);
values.push_back(5);
values.push_back(8);
const ParamGenerator<int> gen = ValuesIn(values.begin(), values.end());
const int expected_values[] = {3, 5, 8};
VerifyGenerator(gen, expected_values);
}
// Edge case. Tests that ValuesIn() provided with an iterator range specifying a
// single value generates a single-element sequence.
TEST(ValuesInTest, ValuesInSingleElementIteratorRange) {
typedef ::std::vector<int> ContainerType;
ContainerType values;
values.push_back(42);
const ParamGenerator<int> gen = ValuesIn(values.begin(), values.end());
const int expected_values[] = {42};
VerifyGenerator(gen, expected_values);
}
// Edge case. Tests that ValuesIn() provided with an empty iterator range
// generates an empty sequence.
TEST(ValuesInTest, ValuesInEmptyIteratorRange) {
typedef ::std::vector<int> ContainerType;
ContainerType values;
const ParamGenerator<int> gen = ValuesIn(values.begin(), values.end());
VerifyGeneratorIsEmpty(gen);
}
// Tests that the Values() generates the expected sequence.
TEST(ValuesTest, ValuesWorks) {
const ParamGenerator<int> gen = Values(3, 5, 8);
const int expected_values[] = {3, 5, 8};
VerifyGenerator(gen, expected_values);
}
// Tests that Values() generates the expected sequences from elements of
// different types convertible to ParamGenerator's parameter type.
TEST(ValuesTest, ValuesWorksForValuesOfCompatibleTypes) {
const ParamGenerator<double> gen = Values(3, 5.0f, 8.0);
const double expected_values[] = {3.0, 5.0, 8.0};
VerifyGenerator(gen, expected_values);
}
TEST(ValuesTest, ValuesWorksForMaxLengthList) {
const ParamGenerator<int> gen = Values(
10, 20, 30, 40, 50, 60, 70, 80, 90, 100,
110, 120, 130, 140, 150, 160, 170, 180, 190, 200,
210, 220, 230, 240, 250, 260, 270, 280, 290, 300,
310, 320, 330, 340, 350, 360, 370, 380, 390, 400,
410, 420, 430, 440, 450, 460, 470, 480, 490, 500);
const int expected_values[] = {
10, 20, 30, 40, 50, 60, 70, 80, 90, 100,
110, 120, 130, 140, 150, 160, 170, 180, 190, 200,
210, 220, 230, 240, 250, 260, 270, 280, 290, 300,
310, 320, 330, 340, 350, 360, 370, 380, 390, 400,
410, 420, 430, 440, 450, 460, 470, 480, 490, 500};
VerifyGenerator(gen, expected_values);
}
// Edge case test. Tests that single-parameter Values() generates the sequence
// with the single value.
TEST(ValuesTest, ValuesWithSingleParameter) {
const ParamGenerator<int> gen = Values(42);
const int expected_values[] = {42};
VerifyGenerator(gen, expected_values);
}
// Tests that Bool() generates sequence (false, true).
TEST(BoolTest, BoolWorks) {
const ParamGenerator<bool> gen = Bool();
const bool expected_values[] = {false, true};
VerifyGenerator(gen, expected_values);
}
#ifdef GTEST_HAS_COMBINE
template <typename T1, typename T2>
::std::ostream& operator<<(::std::ostream& stream, const tuple<T1, T2>& value) {
stream << "(" << get<0>(value) << ", " << get<1>(value) << ")";
return stream;
}
template <typename T1, typename T2, typename T3>
::std::ostream& operator<<(::std::ostream& stream,
const tuple<T1, T2, T3>& value) {
stream << "(" << get<0>(value) << ", " << get<1>(value)
<< ", "<< get<2>(value) << ")";
return stream;
}
template <typename T1, typename T2, typename T3, typename T4, typename T5,
typename T6, typename T7, typename T8, typename T9, typename T10>
::std::ostream& operator<<(
::std::ostream& stream,
const tuple<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10>& value) {
stream << "(" << get<0>(value) << ", " << get<1>(value)
<< ", "<< get<2>(value) << ", " << get<3>(value)
<< ", "<< get<4>(value) << ", " << get<5>(value)
<< ", "<< get<6>(value) << ", " << get<7>(value)
<< ", "<< get<8>(value) << ", " << get<9>(value) << ")";
return stream;
}
// Tests that Combine() with two parameters generates the expected sequence.
TEST(CombineTest, CombineWithTwoParameters) {
const char* foo = "foo";
const char* bar = "bar";
const ParamGenerator<tuple<const char*, int> > gen =
Combine(Values(foo, bar), Values(3, 4));
tuple<const char*, int> expected_values[] = {
make_tuple(foo, 3), make_tuple(foo, 4),
make_tuple(bar, 3), make_tuple(bar, 4)};
VerifyGenerator(gen, expected_values);
}
// Tests that Combine() with three parameters generates the expected sequence.
TEST(CombineTest, CombineWithThreeParameters) {
const ParamGenerator<tuple<int, int, int> > gen = Combine(Values(0, 1),
Values(3, 4),
Values(5, 6));
tuple<int, int, int> expected_values[] = {
make_tuple(0, 3, 5), make_tuple(0, 3, 6),
make_tuple(0, 4, 5), make_tuple(0, 4, 6),
make_tuple(1, 3, 5), make_tuple(1, 3, 6),
make_tuple(1, 4, 5), make_tuple(1, 4, 6)};
VerifyGenerator(gen, expected_values);
}
// Tests that the Combine() with the first parameter generating a single value
// sequence generates a sequence with the number of elements equal to the
// number of elements in the sequence generated by the second parameter.
TEST(CombineTest, CombineWithFirstParameterSingleValue) {
const ParamGenerator<tuple<int, int> > gen = Combine(Values(42),
Values(0, 1));
tuple<int, int> expected_values[] = {make_tuple(42, 0), make_tuple(42, 1)};
VerifyGenerator(gen, expected_values);
}
// Tests that the Combine() with the second parameter generating a single value
// sequence generates a sequence with the number of elements equal to the
// number of elements in the sequence generated by the first parameter.
TEST(CombineTest, CombineWithSecondParameterSingleValue) {
const ParamGenerator<tuple<int, int> > gen = Combine(Values(0, 1),
Values(42));
tuple<int, int> expected_values[] = {make_tuple(0, 42), make_tuple(1, 42)};
VerifyGenerator(gen, expected_values);
}
// Tests that when the first parameter produces an empty sequence,
// Combine() produces an empty sequence, too.
TEST(CombineTest, CombineWithFirstParameterEmptyRange) {
const ParamGenerator<tuple<int, int> > gen = Combine(Range(0, 0),
Values(0, 1));
VerifyGeneratorIsEmpty(gen);
}
// Tests that when the second parameter produces an empty sequence,
// Combine() produces an empty sequence, too.
TEST(CombineTest, CombineWithSecondParameterEmptyRange) {
const ParamGenerator<tuple<int, int> > gen = Combine(Values(0, 1),
Range(1, 1));
VerifyGeneratorIsEmpty(gen);
}
// Edge case. Tests that combine works with the maximum number
// of parameters supported by Google Test (currently 10).
TEST(CombineTest, CombineWithMaxNumberOfParameters) {
const char* foo = "foo";
const char* bar = "bar";
const ParamGenerator<tuple<const char*, int, int, int, int, int, int, int,
int, int> > gen = Combine(Values(foo, bar),
Values(1), Values(2),
Values(3), Values(4),
Values(5), Values(6),
Values(7), Values(8),
Values(9));
tuple<const char*, int, int, int, int, int, int, int, int, int>
expected_values[] = {make_tuple(foo, 1, 2, 3, 4, 5, 6, 7, 8, 9),
make_tuple(bar, 1, 2, 3, 4, 5, 6, 7, 8, 9)};
VerifyGenerator(gen, expected_values);
}
#endif // GTEST_HAS_COMBINE
// Tests that an generator produces correct sequence after being
// assigned from another generator.
TEST(ParamGeneratorTest, AssignmentWorks) {
ParamGenerator<int> gen = Values(1, 2);
const ParamGenerator<int> gen2 = Values(3, 4);
gen = gen2;
const int expected_values[] = {3, 4};
VerifyGenerator(gen, expected_values);
}
// This test verifies that the tests are expanded and run as specified:
// one test per element from the sequence produced by the generator
// specified in INSTANTIATE_TEST_CASE_P. It also verifies that the test's
// fixture constructor, SetUp(), and TearDown() have run and have been
// supplied with the correct parameters.
// The use of environment object allows detection of the case where no test
// case functionality is run at all. In this case TestCaseTearDown will not
// be able to detect missing tests, naturally.
template <int kExpectedCalls>
class TestGenerationEnvironment : public ::testing::Environment {
public:
static TestGenerationEnvironment* Instance() {
static TestGenerationEnvironment* instance = new TestGenerationEnvironment;
return instance;
}
void FixtureConstructorExecuted() { fixture_constructor_count_++; }
void SetUpExecuted() { set_up_count_++; }
void TearDownExecuted() { tear_down_count_++; }
void TestBodyExecuted() { test_body_count_++; }
virtual void TearDown() {
// If all MultipleTestGenerationTest tests have been de-selected
// by the filter flag, the following checks make no sense.
bool perform_check = false;
for (int i = 0; i < kExpectedCalls; ++i) {
Message msg;
msg << "TestsExpandedAndRun/" << i;
if (UnitTestOptions::FilterMatchesTest(
"TestExpansionModule/MultipleTestGenerationTest",
msg.GetString().c_str())) {
perform_check = true;
}
}
if (perform_check) {
EXPECT_EQ(kExpectedCalls, fixture_constructor_count_)
<< "Fixture constructor of ParamTestGenerationTest test case "
<< "has not been run as expected.";
EXPECT_EQ(kExpectedCalls, set_up_count_)
<< "Fixture SetUp method of ParamTestGenerationTest test case "
<< "has not been run as expected.";
EXPECT_EQ(kExpectedCalls, tear_down_count_)
<< "Fixture TearDown method of ParamTestGenerationTest test case "
<< "has not been run as expected.";
EXPECT_EQ(kExpectedCalls, test_body_count_)
<< "Test in ParamTestGenerationTest test case "
<< "has not been run as expected.";
}
}
private:
TestGenerationEnvironment() : fixture_constructor_count_(0), set_up_count_(0),
tear_down_count_(0), test_body_count_(0) {}
int fixture_constructor_count_;
int set_up_count_;
int tear_down_count_;
int test_body_count_;
GTEST_DISALLOW_COPY_AND_ASSIGN_(TestGenerationEnvironment);
};
const int test_generation_params[] = {36, 42, 72};
class TestGenerationTest : public TestWithParam<int> {
public:
enum {
PARAMETER_COUNT =
sizeof(test_generation_params)/sizeof(test_generation_params[0])
};
typedef TestGenerationEnvironment<PARAMETER_COUNT> Environment;
TestGenerationTest() {
Environment::Instance()->FixtureConstructorExecuted();
current_parameter_ = GetParam();
}
virtual void SetUp() {
Environment::Instance()->SetUpExecuted();
EXPECT_EQ(current_parameter_, GetParam());
}
virtual void TearDown() {
Environment::Instance()->TearDownExecuted();
EXPECT_EQ(current_parameter_, GetParam());
}
static void SetUpTestCase() {
bool all_tests_in_test_case_selected = true;
for (int i = 0; i < PARAMETER_COUNT; ++i) {
Message test_name;
test_name << "TestsExpandedAndRun/" << i;
if ( !UnitTestOptions::FilterMatchesTest(
"TestExpansionModule/MultipleTestGenerationTest",
test_name.GetString())) {
all_tests_in_test_case_selected = false;
}
}
EXPECT_TRUE(all_tests_in_test_case_selected)
<< "When running the TestGenerationTest test case all of its tests\n"
<< "must be selected by the filter flag for the test case to pass.\n"
<< "If not all of them are enabled, we can't reliably conclude\n"
<< "that the correct number of tests have been generated.";
collected_parameters_.clear();
}
static void TearDownTestCase() {
vector<int> expected_values(test_generation_params,
test_generation_params + PARAMETER_COUNT);
// Test execution order is not guaranteed by Google Test,
// so the order of values in collected_parameters_ can be
// different and we have to sort to compare.
sort(expected_values.begin(), expected_values.end());
sort(collected_parameters_.begin(), collected_parameters_.end());
EXPECT_TRUE(collected_parameters_ == expected_values);
}
protected:
int current_parameter_;
static vector<int> collected_parameters_;
private:
GTEST_DISALLOW_COPY_AND_ASSIGN_(TestGenerationTest);
};
vector<int> TestGenerationTest::collected_parameters_;
TEST_P(TestGenerationTest, TestsExpandedAndRun) {
Environment::Instance()->TestBodyExecuted();
EXPECT_EQ(current_parameter_, GetParam());
collected_parameters_.push_back(GetParam());
}
INSTANTIATE_TEST_CASE_P(TestExpansionModule, TestGenerationTest,
ValuesIn(test_generation_params));
// This test verifies that the element sequence (third parameter of
// INSTANTIATE_TEST_CASE_P) is evaluated in RUN_ALL_TESTS and not at the call
// site of INSTANTIATE_TEST_CASE_P.
// For that, we declare param_value_ to be a static member of
// GeneratorEvaluationTest and initialize it to 0. We set it to 1 in main(),
// just before invocation of RUN_ALL_TESTS. If the sequence is evaluated
// before that moment, INSTANTIATE_TEST_CASE_P will create a test with
// parameter 0, and the test body will fail the assertion.
class GeneratorEvaluationTest : public TestWithParam<int> {
public:
static int param_value() { return param_value_; }
static void set_param_value(int param_value) { param_value_ = param_value; }
private:
static int param_value_;
};
int GeneratorEvaluationTest::param_value_ = 0;
TEST_P(GeneratorEvaluationTest, GeneratorsEvaluatedInMain) {
EXPECT_EQ(1, GetParam());
}
INSTANTIATE_TEST_CASE_P(GenEvalModule,
GeneratorEvaluationTest,
Values(GeneratorEvaluationTest::param_value()));
// Tests that generators defined in a different translation unit are
// functional. Generator extern_gen is defined in gtest-param-test_test2.cc.
extern ParamGenerator<int> extern_gen;
class ExternalGeneratorTest : public TestWithParam<int> {};
TEST_P(ExternalGeneratorTest, ExternalGenerator) {
// Sequence produced by extern_gen contains only a single value
// which we verify here.
EXPECT_EQ(GetParam(), 33);
}
INSTANTIATE_TEST_CASE_P(ExternalGeneratorModule,
ExternalGeneratorTest,
extern_gen);
// Tests that a parameterized test case can be defined in one translation
// unit and instantiated in another. This test will be instantiated in
// gtest-param-test_test2.cc. ExternalInstantiationTest fixture class is
// defined in gtest-param-test_test.h.
TEST_P(ExternalInstantiationTest, IsMultipleOf33) {
EXPECT_EQ(0, GetParam() % 33);
}
// Tests that a parameterized test case can be instantiated with multiple
// generators.
class MultipleInstantiationTest : public TestWithParam<int> {};
TEST_P(MultipleInstantiationTest, AllowsMultipleInstances) {
}
INSTANTIATE_TEST_CASE_P(Sequence1, MultipleInstantiationTest, Values(1, 2));
INSTANTIATE_TEST_CASE_P(Sequence2, MultipleInstantiationTest, Range(3, 5));
// Tests that a parameterized test case can be instantiated
// in multiple translation units. This test will be instantiated
// here and in gtest-param-test_test2.cc.
// InstantiationInMultipleTranslationUnitsTest fixture class
// is defined in gtest-param-test_test.h.
TEST_P(InstantiationInMultipleTranslaionUnitsTest, IsMultipleOf42) {
EXPECT_EQ(0, GetParam() % 42);
}
INSTANTIATE_TEST_CASE_P(Sequence1,
InstantiationInMultipleTranslaionUnitsTest,
Values(42, 42*2));
// Tests that each iteration of parameterized test runs in a separate test
// object.
class SeparateInstanceTest : public TestWithParam<int> {
public:
SeparateInstanceTest() : count_(0) {}
static void TearDownTestCase() {
EXPECT_GE(global_count_, 2)
<< "If some (but not all) SeparateInstanceTest tests have been "
<< "filtered out this test will fail. Make sure that all "
<< "GeneratorEvaluationTest are selected or de-selected together "
<< "by the test filter.";
}
protected:
int count_;
static int global_count_;
};
int SeparateInstanceTest::global_count_ = 0;
TEST_P(SeparateInstanceTest, TestsRunInSeparateInstances) {
EXPECT_EQ(0, count_++);
global_count_++;
}
INSTANTIATE_TEST_CASE_P(FourElemSequence, SeparateInstanceTest, Range(1, 4));
// Tests that all instantiations of a test have named appropriately. Test
// defined with TEST_P(TestCaseName, TestName) and instantiated with
// INSTANTIATE_TEST_CASE_P(SequenceName, TestCaseName, generator) must be named
// SequenceName/TestCaseName.TestName/i, where i is the 0-based index of the
// sequence element used to instantiate the test.
class NamingTest : public TestWithParam<int> {};
TEST_P(NamingTest, TestsAreNamedAppropriately) {
const ::testing::TestInfo* const test_info =
::testing::UnitTest::GetInstance()->current_test_info();
EXPECT_STREQ("ZeroToFiveSequence/NamingTest", test_info->test_case_name());
Message msg;
msg << "TestsAreNamedAppropriately/" << GetParam();
EXPECT_STREQ(msg.GetString().c_str(), test_info->name());
}
INSTANTIATE_TEST_CASE_P(ZeroToFiveSequence, NamingTest, Range(0, 5));
#endif // GTEST_HAS_PARAM_TEST
TEST(CompileTest, CombineIsDefinedOnlyWhenGtestHasParamTestIsDefined) {
#if defined(GTEST_HAS_COMBINE) && !defined(GTEST_HAS_PARAM_TEST)
FAIL() << "GTEST_HAS_COMBINE is defined while GTEST_HAS_PARAM_TEST is not\n"
#endif
}
int main(int argc, char **argv) {
#ifdef GTEST_HAS_PARAM_TEST
// Used in TestGenerationTest test case.
AddGlobalTestEnvironment(TestGenerationTest::Environment::Instance());
// Used in GeneratorEvaluationTest test case.
GeneratorEvaluationTest::set_param_value(1);
#endif // GTEST_HAS_PARAM_TEST
testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}

View File

@ -0,0 +1,55 @@
// 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.
//
// Authors: vladl@google.com (Vlad Losev)
//
// The Google C++ Testing Framework (Google Test)
//
// This header file provides classes and functions used internally
// for testing Google Test itself.
#ifndef GTEST_TEST_GTEST_PARAM_TEST_TEST_H_
#define GTEST_TEST_GTEST_PARAM_TEST_TEST_H_
#include <gtest/gtest.h>
#ifdef GTEST_HAS_PARAM_TEST
// Test fixture for testing definition and instantiation of a test
// in separate translation units.
class ExternalInstantiationTest : public ::testing::TestWithParam<int> {};
// Test fixture for testing instantiation of a test in multiple
// translation units.
class InstantiationInMultipleTranslaionUnitsTest
: public ::testing::TestWithParam<int> {};
#endif // GTEST_HAS_PARAM_TEST
#endif // GTEST_TEST_GTEST_PARAM_TEST_TEST_H_

156
test/gtest-port_test.cc Normal file
View File

@ -0,0 +1,156 @@
// 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: vladl@google.com (Vlad Losev)
//
// This file tests the internal cross-platform support utilities.
#include <gtest/internal/gtest-port.h>
#include <gtest/gtest.h>
#include <gtest/gtest-spi.h>
TEST(GtestCheckSyntaxTest, BehavesLikeASingleStatement) {
if (false)
GTEST_CHECK_(false) << "This should never be executed; "
"It's a compilation test only.";
if (true)
GTEST_CHECK_(true);
else
; // NOLINT
if (false)
; // NOLINT
else
GTEST_CHECK_(true) << "";
}
TEST(GtestCheckSyntaxTest, WorksWithSwitch) {
switch (0) {
case 1:
break;
default:
GTEST_CHECK_(true);
}
switch(0)
case 0:
GTEST_CHECK_(true) << "Check failed in switch case";
}
#ifdef GTEST_HAS_DEATH_TEST
TEST(GtestCheckDeathTest, DiesWithCorrectOutputOnFailure) {
const bool a_false_condition = false;
EXPECT_DEATH(GTEST_CHECK_(a_false_condition) << "Extra info",
#ifdef _MSC_VER
"gtest-port_test\\.cc\\([0-9]+\\):"
#else
"gtest-port_test\\.cc:[0-9]+"
#endif // _MSC_VER
".*a_false_condition.*Extra info.*");
}
TEST(GtestCheckDeathTest, LivesSilentlyOnSuccess) {
EXPECT_EXIT({
GTEST_CHECK_(true) << "Extra info";
::std::cerr << "Success\n";
exit(0); },
::testing::ExitedWithCode(0), "Success");
}
#endif // GTEST_HAS_DEATH_TEST
#ifdef GTEST_USES_POSIX_RE
using ::testing::internal::RE;
template <typename Str>
class RETest : public ::testing::Test {};
// Defines StringTypes as the list of all string types that class RE
// supports.
typedef testing::Types<
#if GTEST_HAS_STD_STRING
::std::string,
#endif // GTEST_HAS_STD_STRING
#if GTEST_HAS_GLOBAL_STRING
::string,
#endif // GTEST_HAS_GLOBAL_STRING
const char*> StringTypes;
TYPED_TEST_CASE(RETest, StringTypes);
// Tests RE's implicit constructors.
TYPED_TEST(RETest, ImplicitConstructorWorks) {
const RE empty = TypeParam("");
EXPECT_STREQ("", empty.pattern());
const RE simple = TypeParam("hello");
EXPECT_STREQ("hello", simple.pattern());
const RE normal = TypeParam(".*(\\w+)");
EXPECT_STREQ(".*(\\w+)", normal.pattern());
}
// Tests that RE's constructors reject invalid regular expressions.
TYPED_TEST(RETest, RejectsInvalidRegex) {
EXPECT_NONFATAL_FAILURE({
const RE invalid = TypeParam("?");
}, "\"?\" is not a valid POSIX Extended regular expression.");
}
// Tests RE::FullMatch().
TYPED_TEST(RETest, FullMatchWorks) {
const RE empty = TypeParam("");
EXPECT_TRUE(RE::FullMatch(TypeParam(""), empty));
EXPECT_FALSE(RE::FullMatch(TypeParam("a"), empty));
const RE re = TypeParam("a.*z");
EXPECT_TRUE(RE::FullMatch(TypeParam("az"), re));
EXPECT_TRUE(RE::FullMatch(TypeParam("axyz"), re));
EXPECT_FALSE(RE::FullMatch(TypeParam("baz"), re));
EXPECT_FALSE(RE::FullMatch(TypeParam("azy"), re));
}
// Tests RE::PartialMatch().
TYPED_TEST(RETest, PartialMatchWorks) {
const RE empty = TypeParam("");
EXPECT_TRUE(RE::PartialMatch(TypeParam(""), empty));
EXPECT_TRUE(RE::PartialMatch(TypeParam("a"), empty));
const RE re = TypeParam("a.*z");
EXPECT_TRUE(RE::PartialMatch(TypeParam("az"), re));
EXPECT_TRUE(RE::PartialMatch(TypeParam("axyz"), re));
EXPECT_TRUE(RE::PartialMatch(TypeParam("baz"), re));
EXPECT_TRUE(RE::PartialMatch(TypeParam("azy"), re));
EXPECT_FALSE(RE::PartialMatch(TypeParam("zza"), re));
}
#endif // GTEST_USES_POSIX_RE

View File

@ -348,3 +348,15 @@ INSTANTIATE_TYPED_TEST_CASE_P(My, NumericTest, NumericTypes);
} // namespace library2 } // namespace library2
#endif // GTEST_HAS_TYPED_TEST_P #endif // GTEST_HAS_TYPED_TEST_P
#if !defined(GTEST_HAS_TYPED_TEST) && !defined(GTEST_HAS_TYPED_TEST_P)
// Google Test doesn't support type-parameterized tests on some platforms
// and compilers, such as MSVC 7.1. If we use conditional compilation to
// compile out all code referring to the gtest_main library, MSVC linker
// will not link that library at all and consequently complain about
// missing entry point defined in that library (fatal error LNK1561:
// entry point must be defined). This dummy test keeps gtest_main linked in.
TEST(DummyTest, TypedTestsAreNotSupportedOnThisPlatform) {}
#endif // #if !defined(GTEST_HAS_TYPED_TEST) && !defined(GTEST_HAS_TYPED_TEST_P)

View File

@ -43,6 +43,7 @@ __author__ = 'wan@google.com (Zhanyong Wan)'
import gtest_test_utils import gtest_test_utils
import os import os
import re import re
import sets
import sys import sys
import unittest import unittest
@ -58,26 +59,41 @@ FILTER_FLAG = 'gtest_filter'
COMMAND = os.path.join(gtest_test_utils.GetBuildDir(), COMMAND = os.path.join(gtest_test_utils.GetBuildDir(),
'gtest_filter_unittest_') 'gtest_filter_unittest_')
# Regex for determining whether parameterized tests are enabled in the binary.
PARAM_TEST_REGEX = re.compile(r'/ParamTest')
# Regex for parsing test case names from Google Test's output. # Regex for parsing test case names from Google Test's output.
TEST_CASE_REGEX = re.compile(r'^\[\-+\] \d+ test.* from (\w+)') TEST_CASE_REGEX = re.compile(r'^\[\-+\] \d+ tests? from (\w+(/\w+)?)')
# Regex for parsing test names from Google Test's output. # Regex for parsing test names from Google Test's output.
TEST_REGEX = re.compile(r'^\[\s*RUN\s*\].*\.(\w+)') TEST_REGEX = re.compile(r'^\[\s*RUN\s*\].*\.(\w+(/\w+)?)')
# Full names of all tests in gtest_filter_unittests_. # Full names of all tests in gtest_filter_unittests_.
PARAM_TESTS = [
'SeqP/ParamTest.TestX/0',
'SeqP/ParamTest.TestX/1',
'SeqP/ParamTest.TestY/0',
'SeqP/ParamTest.TestY/1',
'SeqQ/ParamTest.TestX/0',
'SeqQ/ParamTest.TestX/1',
'SeqQ/ParamTest.TestY/0',
'SeqQ/ParamTest.TestY/1',
]
ALL_TESTS = [ ALL_TESTS = [
'FooTest.Abc', 'FooTest.Abc',
'FooTest.Xyz', 'FooTest.Xyz',
'BarTest.Test1', 'BarTest.TestOne',
'BarTest.Test2', 'BarTest.TestTwo',
'BarTest.Test3', 'BarTest.TestThree',
'BazTest.Test1', 'BazTest.TestOne',
'BazTest.TestA', 'BazTest.TestA',
'BazTest.TestB', 'BazTest.TestB',
] ] + PARAM_TESTS
param_tests_present = None
# Utilities. # Utilities.
@ -136,6 +152,11 @@ class GTestFilterUnitTest(unittest.TestCase):
"""Runs gtest_flag_unittest_ with the given filter, and verifies """Runs gtest_flag_unittest_ with the given filter, and verifies
that the right set of tests were run. that the right set of tests were run.
""" """
# Adjust tests_to_run in case value parameterized tests are disabled
# in the binary.
global param_tests_present
if not param_tests_present:
tests_to_run = list(sets.Set(tests_to_run) - sets.Set(PARAM_TESTS))
# First, tests using GTEST_FILTER. # First, tests using GTEST_FILTER.
@ -155,6 +176,15 @@ class GTestFilterUnitTest(unittest.TestCase):
tests_run = Run(command) tests_run = Run(command)
self.AssertSetEqual(tests_run, tests_to_run) self.AssertSetEqual(tests_run, tests_to_run)
def setUp(self):
"""Sets up test case. Determines whether value-parameterized tests are
enabled in the binary and sets flags accordingly.
"""
global param_tests_present
if param_tests_present is None:
param_tests_present = PARAM_TEST_REGEX.search(
'\n'.join(os.popen(COMMAND, 'r').readlines())) is not None
def testDefaultBehavior(self): def testDefaultBehavior(self):
"""Tests the behavior of not specifying the filter.""" """Tests the behavior of not specifying the filter."""
@ -189,20 +219,19 @@ class GTestFilterUnitTest(unittest.TestCase):
def testFilterByTest(self): def testFilterByTest(self):
"""Tests filtering by test name.""" """Tests filtering by test name."""
self.RunAndVerify('*.Test1', ['BarTest.Test1', 'BazTest.Test1']) self.RunAndVerify('*.TestOne', ['BarTest.TestOne', 'BazTest.TestOne'])
def testWildcardInTestCaseName(self): def testWildcardInTestCaseName(self):
"""Tests using wildcard in the test case name.""" """Tests using wildcard in the test case name."""
self.RunAndVerify('*a*.*', [ self.RunAndVerify('*a*.*', [
'BarTest.Test1', 'BarTest.TestOne',
'BarTest.Test2', 'BarTest.TestTwo',
'BarTest.Test3', 'BarTest.TestThree',
'BazTest.Test1', 'BazTest.TestOne',
'BazTest.TestA', 'BazTest.TestA',
'BazTest.TestB', 'BazTest.TestB',] + PARAM_TESTS)
])
def testWildcardInTestName(self): def testWildcardInTestName(self):
"""Tests using wildcard in the test name.""" """Tests using wildcard in the test name."""
@ -215,7 +244,7 @@ class GTestFilterUnitTest(unittest.TestCase):
self.RunAndVerify('*z*', [ self.RunAndVerify('*z*', [
'FooTest.Xyz', 'FooTest.Xyz',
'BazTest.Test1', 'BazTest.TestOne',
'BazTest.TestA', 'BazTest.TestA',
'BazTest.TestB', 'BazTest.TestB',
]) ])
@ -236,24 +265,24 @@ class GTestFilterUnitTest(unittest.TestCase):
def testThreePatterns(self): def testThreePatterns(self):
"""Tests filters that consist of three patterns.""" """Tests filters that consist of three patterns."""
self.RunAndVerify('*oo*:*A*:*1', [ self.RunAndVerify('*oo*:*A*:*One', [
'FooTest.Abc', 'FooTest.Abc',
'FooTest.Xyz', 'FooTest.Xyz',
'BarTest.Test1', 'BarTest.TestOne',
'BazTest.Test1', 'BazTest.TestOne',
'BazTest.TestA', 'BazTest.TestA',
]) ])
# The 2nd pattern is empty. # The 2nd pattern is empty.
self.RunAndVerify('*oo*::*1', [ self.RunAndVerify('*oo*::*One', [
'FooTest.Abc', 'FooTest.Abc',
'FooTest.Xyz', 'FooTest.Xyz',
'BarTest.Test1', 'BarTest.TestOne',
'BazTest.Test1', 'BazTest.TestOne',
]) ])
# The last 2 patterns are empty. # The last 2 patterns are empty.
@ -266,49 +295,69 @@ class GTestFilterUnitTest(unittest.TestCase):
self.RunAndVerify('*-FooTest.Abc', [ self.RunAndVerify('*-FooTest.Abc', [
'FooTest.Xyz', 'FooTest.Xyz',
'BarTest.Test1', 'BarTest.TestOne',
'BarTest.Test2', 'BarTest.TestTwo',
'BarTest.Test3', 'BarTest.TestThree',
'BazTest.Test1', 'BazTest.TestOne',
'BazTest.TestA', 'BazTest.TestA',
'BazTest.TestB', 'BazTest.TestB',
]) ] + PARAM_TESTS)
self.RunAndVerify('*-FooTest.Abc:BazTest.*', [ self.RunAndVerify('*-FooTest.Abc:BazTest.*', [
'FooTest.Xyz', 'FooTest.Xyz',
'BarTest.Test1', 'BarTest.TestOne',
'BarTest.Test2', 'BarTest.TestTwo',
'BarTest.Test3', 'BarTest.TestThree',
]) ] + PARAM_TESTS)
self.RunAndVerify('BarTest.*-BarTest.Test1', [ self.RunAndVerify('BarTest.*-BarTest.TestOne', [
'BarTest.Test2', 'BarTest.TestTwo',
'BarTest.Test3', 'BarTest.TestThree',
]) ])
# Tests without leading '*'. # Tests without leading '*'.
self.RunAndVerify('-FooTest.Abc:FooTest.Xyz', [ self.RunAndVerify('-FooTest.Abc:FooTest.Xyz', [
'BarTest.Test1', 'BarTest.TestOne',
'BarTest.Test2', 'BarTest.TestTwo',
'BarTest.Test3', 'BarTest.TestThree',
'BazTest.Test1', 'BazTest.TestOne',
'BazTest.TestA', 'BazTest.TestA',
'BazTest.TestB', 'BazTest.TestB',
] + PARAM_TESTS)
# Value parameterized tests.
self.RunAndVerify('*/*', PARAM_TESTS)
# Value parameterized tests filtering by the sequence name.
self.RunAndVerify('SeqP/*', [
'SeqP/ParamTest.TestX/0',
'SeqP/ParamTest.TestX/1',
'SeqP/ParamTest.TestY/0',
'SeqP/ParamTest.TestY/1',
])
# Value parameterized tests filtering by the test name.
self.RunAndVerify('*/0', [
'SeqP/ParamTest.TestX/0',
'SeqP/ParamTest.TestY/0',
'SeqQ/ParamTest.TestX/0',
'SeqQ/ParamTest.TestY/0',
]) ])
def testFlagOverridesEnvVar(self): def testFlagOverridesEnvVar(self):
"""Tests that the --gtest_filter flag overrides the GTEST_FILTER """Tests that the --gtest_filter flag overrides the GTEST_FILTER
environment variable.""" environment variable.
"""
SetEnvVar(FILTER_ENV_VAR, 'Foo*') SetEnvVar(FILTER_ENV_VAR, 'Foo*')
command = '%s --%s=%s' % (COMMAND, FILTER_FLAG, '*1') command = '%s --%s=%s' % (COMMAND, FILTER_FLAG, '*One')
tests_run = Run(command) tests_run = Run(command)
SetEnvVar(FILTER_ENV_VAR, None) SetEnvVar(FILTER_ENV_VAR, None)
self.AssertSetEqual(tests_run, ['BarTest.Test1', 'BazTest.Test1']) self.AssertSetEqual(tests_run, ['BarTest.TestOne', 'BazTest.TestOne'])
if __name__ == '__main__': if __name__ == '__main__':

View File

@ -58,19 +58,19 @@ TEST_F(FooTest, Xyz) {
// Test case BarTest. // Test case BarTest.
TEST(BarTest, Test1) { TEST(BarTest, TestOne) {
} }
TEST(BarTest, Test2) { TEST(BarTest, TestTwo) {
} }
TEST(BarTest, Test3) { TEST(BarTest, TestThree) {
} }
// Test case BazTest. // Test case BazTest.
TEST(BazTest, Test1) { TEST(BazTest, TestOne) {
FAIL() << "Expected failure."; FAIL() << "Expected failure.";
} }
@ -80,6 +80,20 @@ TEST(BazTest, TestA) {
TEST(BazTest, TestB) { TEST(BazTest, TestB) {
} }
#ifdef GTEST_HAS_PARAM_TEST
class ParamTest : public testing::TestWithParam<int> {
};
TEST_P(ParamTest, TestX) {
}
TEST_P(ParamTest, TestY) {
}
INSTANTIATE_TEST_CASE_P(SeqP, ParamTest, testing::Values(1, 2));
INSTANTIATE_TEST_CASE_P(SeqQ, ParamTest, testing::Values(5, 6));
#endif // GTEST_HAS_PARAM_TEST
} // namespace } // namespace

View File

@ -121,6 +121,24 @@ TEST(BarDeathTest, ThreadSafeAndFast) {
#endif // GTEST_HAS_DEATH_TEST #endif // GTEST_HAS_DEATH_TEST
} }
#ifdef GTEST_HAS_PARAM_TEST
int g_param_test_count = 0;
const int kNumberOfParamTests = 10;
class MyParamTest : public testing::TestWithParam<int> {};
TEST_P(MyParamTest, ShouldPass) {
// TODO(vladl@google.com): Make parameter value checking robust
// WRT order of tests.
GTEST_CHECK_INT_EQ_(g_param_test_count % kNumberOfParamTests, GetParam());
g_param_test_count++;
}
INSTANTIATE_TEST_CASE_P(MyParamSequence,
MyParamTest,
testing::Range(0, kNumberOfParamTests));
#endif // GTEST_HAS_PARAM_TEST
// Resets the count for each test. // Resets the count for each test.
void ResetCounts() { void ResetCounts() {
g_environment_set_up_count = 0; g_environment_set_up_count = 0;
@ -128,6 +146,9 @@ void ResetCounts() {
g_should_fail_count = 0; g_should_fail_count = 0;
g_should_pass_count = 0; g_should_pass_count = 0;
g_death_test_count = 0; g_death_test_count = 0;
#ifdef GTEST_HAS_PARAM_TEST
g_param_test_count = 0;
#endif // GTEST_HAS_PARAM_TEST
} }
// Checks that the count for each test is expected. // Checks that the count for each test is expected.
@ -137,6 +158,9 @@ void CheckCounts(int expected) {
GTEST_CHECK_INT_EQ_(expected, g_should_fail_count); GTEST_CHECK_INT_EQ_(expected, g_should_fail_count);
GTEST_CHECK_INT_EQ_(expected, g_should_pass_count); GTEST_CHECK_INT_EQ_(expected, g_should_pass_count);
GTEST_CHECK_INT_EQ_(expected, g_death_test_count); GTEST_CHECK_INT_EQ_(expected, g_death_test_count);
#ifdef GTEST_HAS_PARAM_TEST
GTEST_CHECK_INT_EQ_(expected * kNumberOfParamTests, g_param_test_count);
#endif // GTEST_HAS_PARAM_TEST
} }
// Tests the behavior of Google Test when --gtest_repeat is not specified. // Tests the behavior of Google Test when --gtest_repeat is not specified.
@ -179,6 +203,9 @@ void TestRepeatWithFilterForSuccessfulTests(int repeat) {
GTEST_CHECK_INT_EQ_(0, g_should_fail_count); GTEST_CHECK_INT_EQ_(0, g_should_fail_count);
GTEST_CHECK_INT_EQ_(repeat, g_should_pass_count); GTEST_CHECK_INT_EQ_(repeat, g_should_pass_count);
GTEST_CHECK_INT_EQ_(repeat, g_death_test_count); GTEST_CHECK_INT_EQ_(repeat, g_death_test_count);
#ifdef GTEST_HAS_PARAM_TEST
GTEST_CHECK_INT_EQ_(repeat * kNumberOfParamTests, g_param_test_count);
#endif // GTEST_HAS_PARAM_TEST
} }
// Tests using --gtest_repeat when --gtest_filter specifies a set of // Tests using --gtest_repeat when --gtest_filter specifies a set of
@ -194,6 +221,9 @@ void TestRepeatWithFilterForFailedTests(int repeat) {
GTEST_CHECK_INT_EQ_(repeat, g_should_fail_count); GTEST_CHECK_INT_EQ_(repeat, g_should_fail_count);
GTEST_CHECK_INT_EQ_(0, g_should_pass_count); GTEST_CHECK_INT_EQ_(0, g_should_pass_count);
GTEST_CHECK_INT_EQ_(0, g_death_test_count); GTEST_CHECK_INT_EQ_(0, g_death_test_count);
#ifdef GTEST_HAS_PARAM_TEST
GTEST_CHECK_INT_EQ_(0, g_param_test_count);
#endif // GTEST_HAS_PARAM_TEST
} }
} // namespace } // namespace

View File

@ -109,6 +109,8 @@ using testing::internal::AppendUserMessage;
using testing::internal::CodePointToUtf8; using testing::internal::CodePointToUtf8;
using testing::internal::EqFailure; using testing::internal::EqFailure;
using testing::internal::FloatingPoint; using testing::internal::FloatingPoint;
using testing::internal::GetCurrentOsStackTraceExceptTop;
using testing::internal::GetFailedPartCount;
using testing::internal::GTestFlagSaver; using testing::internal::GTestFlagSaver;
using testing::internal::Int32; using testing::internal::Int32;
using testing::internal::List; using testing::internal::List;
@ -899,6 +901,13 @@ TEST_F(TestResultTest, failed_part_count) {
ASSERT_EQ(1u, r2->failed_part_count()); ASSERT_EQ(1u, r2->failed_part_count());
} }
// Tests testing::internal::GetFailedPartCount().
TEST_F(TestResultTest, GetFailedPartCount) {
ASSERT_EQ(0u, GetFailedPartCount(r0));
ASSERT_EQ(0u, GetFailedPartCount(r1));
ASSERT_EQ(1u, GetFailedPartCount(r2));
}
// Tests TestResult::total_part_count() // Tests TestResult::total_part_count()
TEST_F(TestResultTest, total_part_count) { TEST_F(TestResultTest, total_part_count) {
ASSERT_EQ(0u, r0->total_part_count()); ASSERT_EQ(0u, r0->total_part_count());
@ -4914,6 +4923,14 @@ TEST(ThreadLocalTest, Init) {
EXPECT_EQ(&i, t2.get()); EXPECT_EQ(&i, t2.get());
} }
TEST(GetCurrentOsStackTraceExceptTopTest, ReturnsTheStackTrace) {
testing::UnitTest* const unit_test = testing::UnitTest::GetInstance();
// We don't have a stack walker in Google Test yet.
EXPECT_STREQ("", GetCurrentOsStackTraceExceptTop(unit_test, 0).c_str());
EXPECT_STREQ("", GetCurrentOsStackTraceExceptTop(unit_test, 1).c_str());
}
#ifndef GTEST_OS_SYMBIAN #ifndef GTEST_OS_SYMBIAN
// We will want to integrate running the unittests to a different // We will want to integrate running the unittests to a different
// main application on Symbian. // main application on Symbian.

View File

@ -5,4 +5,4 @@
// is set in the "Based On:" dropdown in the "Target" info dialog. // is set in the "Based On:" dropdown in the "Target" info dialog.
PRODUCT_NAME = $(TARGET_NAME) PRODUCT_NAME = $(TARGET_NAME)
HEADER_SEARCH_PATHS = "../" HEADER_SEARCH_PATHS = ../ ../include

View File

@ -5,3 +5,4 @@
// is set in the "Based On:" dropdown in the "Target" info dialog. // is set in the "Based On:" dropdown in the "Target" info dialog.
PRODUCT_NAME = $(TARGET_NAME) PRODUCT_NAME = $(TARGET_NAME)
HEADER_SEARCH_PATHS = ../include

View File

@ -12,6 +12,8 @@ test_executables=("$BUILT_PRODUCTS_DIR/sample1_unittest"
"$BUILT_PRODUCTS_DIR/sample4_unittest" "$BUILT_PRODUCTS_DIR/sample4_unittest"
"$BUILT_PRODUCTS_DIR/sample5_unittest" "$BUILT_PRODUCTS_DIR/sample5_unittest"
"$BUILT_PRODUCTS_DIR/sample6_unittest" "$BUILT_PRODUCTS_DIR/sample6_unittest"
"$BUILT_PRODUCTS_DIR/sample7_unittest"
"$BUILT_PRODUCTS_DIR/sample8_unittest"
"$BUILT_PRODUCTS_DIR/gtest_unittest" "$BUILT_PRODUCTS_DIR/gtest_unittest"
"$BUILT_PRODUCTS_DIR/gtest-death-test_test" "$BUILT_PRODUCTS_DIR/gtest-death-test_test"
@ -28,6 +30,9 @@ test_executables=("$BUILT_PRODUCTS_DIR/sample1_unittest"
"$BUILT_PRODUCTS_DIR/gtest_stress_test" "$BUILT_PRODUCTS_DIR/gtest_stress_test"
"$BUILT_PRODUCTS_DIR/gtest_test_part_test" "$BUILT_PRODUCTS_DIR/gtest_test_part_test"
"$BUILT_PRODUCTS_DIR/gtest-typed-test_test" "$BUILT_PRODUCTS_DIR/gtest-typed-test_test"
"$BUILT_PRODUCTS_DIR/gtest-param-test_test"
"$BUILT_PRODUCTS_DIR/gtest-linked_ptr_test"
"$BUILT_PRODUCTS_DIR/gtest-port_test"
"$BUILT_PRODUCTS_DIR/gtest_output_test.py" "$BUILT_PRODUCTS_DIR/gtest_output_test.py"
"$BUILT_PRODUCTS_DIR/gtest_color_test.py" "$BUILT_PRODUCTS_DIR/gtest_color_test.py"

View File

@ -20,11 +20,14 @@
3B238F690E828B6100846E11 /* PBXTargetDependency */, 3B238F690E828B6100846E11 /* PBXTargetDependency */,
3B238F6B0E828B6100846E11 /* PBXTargetDependency */, 3B238F6B0E828B6100846E11 /* PBXTargetDependency */,
3B238F6D0E828B6100846E11 /* PBXTargetDependency */, 3B238F6D0E828B6100846E11 /* PBXTargetDependency */,
4539C94C0EC2823500A70F4C /* PBXTargetDependency */,
4539C94A0EC2823500A70F4C /* PBXTargetDependency */,
3B238F6F0E828B7100846E11 /* PBXTargetDependency */, 3B238F6F0E828B7100846E11 /* PBXTargetDependency */,
3B238F710E828B7100846E11 /* PBXTargetDependency */, 3B238F710E828B7100846E11 /* PBXTargetDependency */,
3B238F730E828B7100846E11 /* PBXTargetDependency */, 3B238F730E828B7100846E11 /* PBXTargetDependency */,
3B238F750E828B7100846E11 /* PBXTargetDependency */, 3B238F750E828B7100846E11 /* PBXTargetDependency */,
3B238F790E828B7100846E11 /* PBXTargetDependency */, 3B238F790E828B7100846E11 /* PBXTargetDependency */,
4539C95F0EC2833100A70F4C /* PBXTargetDependency */,
3B238F7B0E828B7100846E11 /* PBXTargetDependency */, 3B238F7B0E828B7100846E11 /* PBXTargetDependency */,
3B238F7D0E828B7100846E11 /* PBXTargetDependency */, 3B238F7D0E828B7100846E11 /* PBXTargetDependency */,
3B238F7F0E828B7100846E11 /* PBXTargetDependency */, 3B238F7F0E828B7100846E11 /* PBXTargetDependency */,
@ -46,6 +49,8 @@
3B238F9B0E828B7100846E11 /* PBXTargetDependency */, 3B238F9B0E828B7100846E11 /* PBXTargetDependency */,
3B238F9D0E828B7100846E11 /* PBXTargetDependency */, 3B238F9D0E828B7100846E11 /* PBXTargetDependency */,
3B238F9F0E828B7100846E11 /* PBXTargetDependency */, 3B238F9F0E828B7100846E11 /* PBXTargetDependency */,
4539C9B30EC284C300A70F4C /* PBXTargetDependency */,
4539C9B10EC284C300A70F4C /* PBXTargetDependency */,
); );
name = Check; name = Check;
productName = Check; productName = Check;
@ -184,6 +189,21 @@
408454BC0E97098200AC66C2 /* gtest-typed-test2_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = 3B238BF50E7FE13B00846E11 /* gtest-typed-test2_test.cc */; }; 408454BC0E97098200AC66C2 /* gtest-typed-test2_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = 3B238BF50E7FE13B00846E11 /* gtest-typed-test2_test.cc */; };
40D2095B0E9FFBE500191629 /* gtest_sole_header_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = 40D209590E9FFBAA00191629 /* gtest_sole_header_test.cc */; }; 40D2095B0E9FFBE500191629 /* gtest_sole_header_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = 40D209590E9FFBAA00191629 /* gtest_sole_header_test.cc */; };
40D2095C0E9FFC0700191629 /* gtest_stress_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = 40D2095A0E9FFBAA00191629 /* gtest_stress_test.cc */; }; 40D2095C0E9FFC0700191629 /* gtest_stress_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = 40D2095A0E9FFBAA00191629 /* gtest_stress_test.cc */; };
4539C90B0EC27FBC00A70F4C /* gtest.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3B87D22D0E96C038000D1852 /* gtest.framework */; };
4539C9170EC27FC000A70F4C /* gtest.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3B87D22D0E96C038000D1852 /* gtest.framework */; };
4539C91E0EC2800600A70F4C /* sample7_unittest.cc in Sources */ = {isa = PBXBuildFile; fileRef = 4539C91D0EC2800600A70F4C /* sample7_unittest.cc */; };
4539C9200EC2801E00A70F4C /* sample8_unittest.cc in Sources */ = {isa = PBXBuildFile; fileRef = 4539C91F0EC2801E00A70F4C /* sample8_unittest.cc */; };
4539C9340EC280AE00A70F4C /* gtest-param-test.h in Headers */ = {isa = PBXBuildFile; fileRef = 4539C9330EC280AE00A70F4C /* gtest-param-test.h */; settings = {ATTRIBUTES = (Public, ); }; };
4539C9380EC280E200A70F4C /* gtest-linked_ptr.h in Copy Headers Internal */ = {isa = PBXBuildFile; fileRef = 4539C9350EC280E200A70F4C /* gtest-linked_ptr.h */; };
4539C9390EC280E200A70F4C /* gtest-param-util-generated.h in Copy Headers Internal */ = {isa = PBXBuildFile; fileRef = 4539C9360EC280E200A70F4C /* gtest-param-util-generated.h */; };
4539C93A0EC280E200A70F4C /* gtest-param-util.h in Copy Headers Internal */ = {isa = PBXBuildFile; fileRef = 4539C9370EC280E200A70F4C /* gtest-param-util.h */; };
4539C9540EC282D400A70F4C /* gtest.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3B87D22D0E96C038000D1852 /* gtest.framework */; };
4539C95C0EC2830E00A70F4C /* gtest-param-test2_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = 4539C95A0EC2830E00A70F4C /* gtest-param-test2_test.cc */; };
4539C95D0EC2830E00A70F4C /* gtest-param-test_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = 4539C95B0EC2830E00A70F4C /* gtest-param-test_test.cc */; };
4539C99A0EC283A800A70F4C /* gtest.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3B87D22D0E96C038000D1852 /* gtest.framework */; };
4539C9A10EC283E400A70F4C /* gtest-port_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = 4539C9A00EC283E400A70F4C /* gtest-port_test.cc */; };
4539C9A80EC2840700A70F4C /* gtest.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3B87D22D0E96C038000D1852 /* gtest.framework */; };
4539C9AF0EC2843000A70F4C /* gtest-linked_ptr_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = 4539C9AE0EC2843000A70F4C /* gtest-linked_ptr_test.cc */; };
/* End PBXBuildFile section */ /* End PBXBuildFile section */
/* Begin PBXContainerItemProxy section */ /* Begin PBXContainerItemProxy section */
@ -733,6 +753,76 @@
remoteGlobalIDString = 40C44ADC0E3798F4008FCC51; remoteGlobalIDString = 40C44ADC0E3798F4008FCC51;
remoteInfo = Version.h; remoteInfo = Version.h;
}; };
4539C9070EC27FBC00A70F4C /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 0867D690FE84028FC02AAC07 /* Project object */;
proxyType = 1;
remoteGlobalIDString = 8D07F2BC0486CC7A007CD1D0;
remoteInfo = gtest;
};
4539C9130EC27FC000A70F4C /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 0867D690FE84028FC02AAC07 /* Project object */;
proxyType = 1;
remoteGlobalIDString = 8D07F2BC0486CC7A007CD1D0;
remoteInfo = gtest;
};
4539C9490EC2823500A70F4C /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 0867D690FE84028FC02AAC07 /* Project object */;
proxyType = 1;
remoteGlobalIDString = 4539C9110EC27FC000A70F4C;
remoteInfo = sample8_unittest;
};
4539C94B0EC2823500A70F4C /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 0867D690FE84028FC02AAC07 /* Project object */;
proxyType = 1;
remoteGlobalIDString = 4539C9050EC27FBC00A70F4C;
remoteInfo = sample7_unittest;
};
4539C94F0EC282D400A70F4C /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 0867D690FE84028FC02AAC07 /* Project object */;
proxyType = 1;
remoteGlobalIDString = 8D07F2BC0486CC7A007CD1D0;
remoteInfo = gtest;
};
4539C95E0EC2833100A70F4C /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 0867D690FE84028FC02AAC07 /* Project object */;
proxyType = 1;
remoteGlobalIDString = 4539C94D0EC282D400A70F4C;
remoteInfo = "gtest-param-test_test";
};
4539C9950EC283A800A70F4C /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 0867D690FE84028FC02AAC07 /* Project object */;
proxyType = 1;
remoteGlobalIDString = 8D07F2BC0486CC7A007CD1D0;
remoteInfo = gtest;
};
4539C9A40EC2840700A70F4C /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 0867D690FE84028FC02AAC07 /* Project object */;
proxyType = 1;
remoteGlobalIDString = 8D07F2BC0486CC7A007CD1D0;
remoteInfo = gtest;
};
4539C9B00EC284C300A70F4C /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 0867D690FE84028FC02AAC07 /* Project object */;
proxyType = 1;
remoteGlobalIDString = 4539C9A20EC2840700A70F4C;
remoteInfo = "gtest-linked_ptr_test";
};
4539C9B20EC284C300A70F4C /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 0867D690FE84028FC02AAC07 /* Project object */;
proxyType = 1;
remoteGlobalIDString = 4539C9930EC283A800A70F4C;
remoteInfo = "gtest-port_test";
};
/* End PBXContainerItemProxy section */ /* End PBXContainerItemProxy section */
/* Begin PBXCopyFilesBuildPhase section */ /* Begin PBXCopyFilesBuildPhase section */
@ -745,6 +835,9 @@
404884A00E2F7BE600CF7658 /* gtest-death-test-internal.h in Copy Headers Internal */, 404884A00E2F7BE600CF7658 /* gtest-death-test-internal.h in Copy Headers Internal */,
404884A10E2F7BE600CF7658 /* gtest-filepath.h in Copy Headers Internal */, 404884A10E2F7BE600CF7658 /* gtest-filepath.h in Copy Headers Internal */,
404884A20E2F7BE600CF7658 /* gtest-internal.h in Copy Headers Internal */, 404884A20E2F7BE600CF7658 /* gtest-internal.h in Copy Headers Internal */,
4539C9380EC280E200A70F4C /* gtest-linked_ptr.h in Copy Headers Internal */,
4539C9390EC280E200A70F4C /* gtest-param-util-generated.h in Copy Headers Internal */,
4539C93A0EC280E200A70F4C /* gtest-param-util.h in Copy Headers Internal */,
404884A30E2F7BE600CF7658 /* gtest-port.h in Copy Headers Internal */, 404884A30E2F7BE600CF7658 /* gtest-port.h in Copy Headers Internal */,
404884A40E2F7BE600CF7658 /* gtest-string.h in Copy Headers Internal */, 404884A40E2F7BE600CF7658 /* gtest-string.h in Copy Headers Internal */,
3BF6F2A00E79B5AD000F2EEE /* gtest-type-util.h in Copy Headers Internal */, 3BF6F2A00E79B5AD000F2EEE /* gtest-type-util.h in Copy Headers Internal */,
@ -986,7 +1079,6 @@
404884A90E2F7CD900CF7658 /* CHANGES */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = CHANGES; path = ../CHANGES; sourceTree = SOURCE_ROOT; }; 404884A90E2F7CD900CF7658 /* CHANGES */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = CHANGES; path = ../CHANGES; sourceTree = SOURCE_ROOT; };
404884AA0E2F7CD900CF7658 /* CONTRIBUTORS */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = CONTRIBUTORS; path = ../CONTRIBUTORS; sourceTree = SOURCE_ROOT; }; 404884AA0E2F7CD900CF7658 /* CONTRIBUTORS */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = CONTRIBUTORS; path = ../CONTRIBUTORS; sourceTree = SOURCE_ROOT; };
404884AB0E2F7CD900CF7658 /* COPYING */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = COPYING; path = ../COPYING; sourceTree = SOURCE_ROOT; }; 404884AB0E2F7CD900CF7658 /* COPYING */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = COPYING; path = ../COPYING; sourceTree = SOURCE_ROOT; };
408453CD0E96CE0700AC66C2 /* gtest.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; name = gtest.framework; path = /Volumes/Work/Repository/perforce/gtest/src/depot/branches/open_gtest_branch/google3/third_party/gtest/xcode/build/Debug/gtest.framework; sourceTree = "<absolute>"; };
40D209590E9FFBAA00191629 /* gtest_sole_header_test.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = gtest_sole_header_test.cc; sourceTree = "<group>"; }; 40D209590E9FFBAA00191629 /* gtest_sole_header_test.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = gtest_sole_header_test.cc; sourceTree = "<group>"; };
40D2095A0E9FFBAA00191629 /* gtest_stress_test.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = gtest_stress_test.cc; sourceTree = "<group>"; }; 40D2095A0E9FFBAA00191629 /* gtest_stress_test.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = gtest_stress_test.cc; sourceTree = "<group>"; };
40D4CDF10E30E07400294801 /* DebugProject.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = DebugProject.xcconfig; sourceTree = "<group>"; }; 40D4CDF10E30E07400294801 /* DebugProject.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = DebugProject.xcconfig; sourceTree = "<group>"; };
@ -994,6 +1086,23 @@
40D4CDF30E30E07400294801 /* General.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = General.xcconfig; sourceTree = "<group>"; }; 40D4CDF30E30E07400294801 /* General.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = General.xcconfig; sourceTree = "<group>"; };
40D4CDF40E30E07400294801 /* ReleaseProject.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = ReleaseProject.xcconfig; sourceTree = "<group>"; }; 40D4CDF40E30E07400294801 /* ReleaseProject.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = ReleaseProject.xcconfig; sourceTree = "<group>"; };
40D4CF510E30F5E200294801 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; }; 40D4CF510E30F5E200294801 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
4539C8FF0EC27F6400A70F4C /* gtest.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = gtest.framework; sourceTree = BUILT_PRODUCTS_DIR; };
4539C90F0EC27FBC00A70F4C /* sample7_unittest */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = sample7_unittest; sourceTree = BUILT_PRODUCTS_DIR; };
4539C91B0EC27FC000A70F4C /* sample8_unittest */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = sample8_unittest; sourceTree = BUILT_PRODUCTS_DIR; };
4539C91D0EC2800600A70F4C /* sample7_unittest.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = sample7_unittest.cc; sourceTree = "<group>"; };
4539C91F0EC2801E00A70F4C /* sample8_unittest.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = sample8_unittest.cc; sourceTree = "<group>"; };
4539C9210EC2805500A70F4C /* prime_tables.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = prime_tables.h; sourceTree = "<group>"; };
4539C9330EC280AE00A70F4C /* gtest-param-test.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "gtest-param-test.h"; sourceTree = "<group>"; };
4539C9350EC280E200A70F4C /* gtest-linked_ptr.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "gtest-linked_ptr.h"; sourceTree = "<group>"; };
4539C9360EC280E200A70F4C /* gtest-param-util-generated.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "gtest-param-util-generated.h"; sourceTree = "<group>"; };
4539C9370EC280E200A70F4C /* gtest-param-util.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "gtest-param-util.h"; sourceTree = "<group>"; };
4539C9580EC282D400A70F4C /* gtest-param-test_test */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = "gtest-param-test_test"; sourceTree = BUILT_PRODUCTS_DIR; };
4539C95A0EC2830E00A70F4C /* gtest-param-test2_test.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = "gtest-param-test2_test.cc"; sourceTree = "<group>"; };
4539C95B0EC2830E00A70F4C /* gtest-param-test_test.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = "gtest-param-test_test.cc"; sourceTree = "<group>"; };
4539C99E0EC283A800A70F4C /* gtest-port_test */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = "gtest-port_test"; sourceTree = BUILT_PRODUCTS_DIR; };
4539C9A00EC283E400A70F4C /* gtest-port_test.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = "gtest-port_test.cc"; sourceTree = "<group>"; };
4539C9AC0EC2840700A70F4C /* gtest-linked_ptr_test */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = "gtest-linked_ptr_test"; sourceTree = BUILT_PRODUCTS_DIR; };
4539C9AE0EC2843000A70F4C /* gtest-linked_ptr_test.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = "gtest-linked_ptr_test.cc"; sourceTree = "<group>"; };
/* End PBXFileReference section */ /* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */ /* Begin PBXFrameworksBuildPhase section */
@ -1253,6 +1362,46 @@
); );
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
}; };
4539C90A0EC27FBC00A70F4C /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
4539C90B0EC27FBC00A70F4C /* gtest.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
4539C9160EC27FC000A70F4C /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
4539C9170EC27FC000A70F4C /* gtest.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
4539C9530EC282D400A70F4C /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
4539C9540EC282D400A70F4C /* gtest.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
4539C9990EC283A800A70F4C /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
4539C99A0EC283A800A70F4C /* gtest.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
4539C9A70EC2840700A70F4C /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
4539C9A80EC2840700A70F4C /* gtest.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXFrameworksBuildPhase section */ /* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */ /* Begin PBXGroup section */
@ -1261,11 +1410,13 @@
children = ( children = (
3B87D22D0E96C038000D1852 /* gtest.framework */, 3B87D22D0E96C038000D1852 /* gtest.framework */,
3B87D22F0E96C038000D1852 /* sample1_unittest */, 3B87D22F0E96C038000D1852 /* sample1_unittest */,
3B87D2320E96C038000D1852 /* sample3_unittest */,
3B87D2350E96C038000D1852 /* sample2_unittest */, 3B87D2350E96C038000D1852 /* sample2_unittest */,
3B87D2320E96C038000D1852 /* sample3_unittest */,
3B87D2380E96C038000D1852 /* sample4_unittest */, 3B87D2380E96C038000D1852 /* sample4_unittest */,
3B87D2800E96C039000D1852 /* sample5_unittest */, 3B87D2800E96C039000D1852 /* sample5_unittest */,
3B87D2830E96C039000D1852 /* sample6_unittest */, 3B87D2830E96C039000D1852 /* sample6_unittest */,
4539C90F0EC27FBC00A70F4C /* sample7_unittest */,
4539C91B0EC27FC000A70F4C /* sample8_unittest */,
3B87D23B0E96C038000D1852 /* gtest_xml_output_unittest_ */, 3B87D23B0E96C038000D1852 /* gtest_xml_output_unittest_ */,
3B87D23E0E96C038000D1852 /* gtest_xml_outfile2_test_ */, 3B87D23E0E96C038000D1852 /* gtest_xml_outfile2_test_ */,
3B87D2410E96C038000D1852 /* gtest_xml_outfile1_test_ */, 3B87D2410E96C038000D1852 /* gtest_xml_outfile1_test_ */,
@ -1292,6 +1443,10 @@
3B87D27D0E96C039000D1852 /* gtest-message_test */, 3B87D27D0E96C039000D1852 /* gtest-message_test */,
3B87D2860E96C039000D1852 /* gtest-death-test_test */, 3B87D2860E96C039000D1852 /* gtest-death-test_test */,
3B87D2890E96C039000D1852 /* gtest-filepath_test */, 3B87D2890E96C039000D1852 /* gtest-filepath_test */,
4539C9580EC282D400A70F4C /* gtest-param-test_test */,
4539C99E0EC283A800A70F4C /* gtest-port_test */,
4539C9AC0EC2840700A70F4C /* gtest-linked_ptr_test */,
4539C8FF0EC27F6400A70F4C /* gtest.framework */,
); );
name = Products; name = Products;
sourceTree = "<group>"; sourceTree = "<group>";
@ -1328,8 +1483,12 @@
children = ( children = (
3B238BF10E7FE13B00846E11 /* gtest-death-test_test.cc */, 3B238BF10E7FE13B00846E11 /* gtest-death-test_test.cc */,
3B238BF20E7FE13B00846E11 /* gtest-filepath_test.cc */, 3B238BF20E7FE13B00846E11 /* gtest-filepath_test.cc */,
4539C9AE0EC2843000A70F4C /* gtest-linked_ptr_test.cc */,
3B238BF30E7FE13B00846E11 /* gtest-message_test.cc */, 3B238BF30E7FE13B00846E11 /* gtest-message_test.cc */,
3B238BF40E7FE13B00846E11 /* gtest-options_test.cc */, 3B238BF40E7FE13B00846E11 /* gtest-options_test.cc */,
4539C95A0EC2830E00A70F4C /* gtest-param-test2_test.cc */,
4539C95B0EC2830E00A70F4C /* gtest-param-test_test.cc */,
4539C9A00EC283E400A70F4C /* gtest-port_test.cc */,
3B238BF50E7FE13B00846E11 /* gtest-typed-test2_test.cc */, 3B238BF50E7FE13B00846E11 /* gtest-typed-test2_test.cc */,
3B238BF60E7FE13B00846E11 /* gtest-typed-test_test.cc */, 3B238BF60E7FE13B00846E11 /* gtest-typed-test_test.cc */,
3B238BF70E7FE13B00846E11 /* gtest-typed-test_test.h */, 3B238BF70E7FE13B00846E11 /* gtest-typed-test_test.h */,
@ -1396,14 +1555,15 @@
404883DA0E2F799B00CF7658 /* gtest */ = { 404883DA0E2F799B00CF7658 /* gtest */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
404883E10E2F799B00CF7658 /* internal */,
224A12A20E9EADCC00BD17FD /* gtest-test-part.h */, 224A12A20E9EADCC00BD17FD /* gtest-test-part.h */,
404883DB0E2F799B00CF7658 /* gtest-death-test.h */, 404883DB0E2F799B00CF7658 /* gtest-death-test.h */,
404883DC0E2F799B00CF7658 /* gtest-message.h */, 404883DC0E2F799B00CF7658 /* gtest-message.h */,
4539C9330EC280AE00A70F4C /* gtest-param-test.h */,
404883DD0E2F799B00CF7658 /* gtest-spi.h */, 404883DD0E2F799B00CF7658 /* gtest-spi.h */,
404883DE0E2F799B00CF7658 /* gtest.h */, 404883DE0E2F799B00CF7658 /* gtest.h */,
404883DF0E2F799B00CF7658 /* gtest_pred_impl.h */, 404883DF0E2F799B00CF7658 /* gtest_pred_impl.h */,
404883E00E2F799B00CF7658 /* gtest_prod.h */, 404883E00E2F799B00CF7658 /* gtest_prod.h */,
404883E10E2F799B00CF7658 /* internal */,
3BF6F2A40E79B616000F2EEE /* gtest-typed-test.h */, 3BF6F2A40E79B616000F2EEE /* gtest-typed-test.h */,
); );
path = gtest; path = gtest;
@ -1415,6 +1575,9 @@
404883E20E2F799B00CF7658 /* gtest-death-test-internal.h */, 404883E20E2F799B00CF7658 /* gtest-death-test-internal.h */,
404883E30E2F799B00CF7658 /* gtest-filepath.h */, 404883E30E2F799B00CF7658 /* gtest-filepath.h */,
404883E40E2F799B00CF7658 /* gtest-internal.h */, 404883E40E2F799B00CF7658 /* gtest-internal.h */,
4539C9350EC280E200A70F4C /* gtest-linked_ptr.h */,
4539C9360EC280E200A70F4C /* gtest-param-util-generated.h */,
4539C9370EC280E200A70F4C /* gtest-param-util.h */,
404883E50E2F799B00CF7658 /* gtest-port.h */, 404883E50E2F799B00CF7658 /* gtest-port.h */,
404883E60E2F799B00CF7658 /* gtest-string.h */, 404883E60E2F799B00CF7658 /* gtest-string.h */,
3BF6F29F0E79B5AD000F2EEE /* gtest-type-util.h */, 3BF6F29F0E79B5AD000F2EEE /* gtest-type-util.h */,
@ -1425,6 +1588,7 @@
404883F70E2F799B00CF7658 /* samples */ = { 404883F70E2F799B00CF7658 /* samples */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
4539C9210EC2805500A70F4C /* prime_tables.h */,
404883F80E2F799B00CF7658 /* sample1.cc */, 404883F80E2F799B00CF7658 /* sample1.cc */,
404883F90E2F799B00CF7658 /* sample1.h */, 404883F90E2F799B00CF7658 /* sample1.h */,
404883FA0E2F799B00CF7658 /* sample1_unittest.cc */, 404883FA0E2F799B00CF7658 /* sample1_unittest.cc */,
@ -1438,6 +1602,8 @@
404884020E2F799B00CF7658 /* sample4_unittest.cc */, 404884020E2F799B00CF7658 /* sample4_unittest.cc */,
404884030E2F799B00CF7658 /* sample5_unittest.cc */, 404884030E2F799B00CF7658 /* sample5_unittest.cc */,
22A866180E70A41000F7AE6E /* sample6_unittest.cc */, 22A866180E70A41000F7AE6E /* sample6_unittest.cc */,
4539C91F0EC2801E00A70F4C /* sample8_unittest.cc */,
4539C91D0EC2800600A70F4C /* sample7_unittest.cc */,
); );
name = samples; name = samples;
path = ../samples; path = ../samples;
@ -1490,6 +1656,7 @@
files = ( files = (
404884380E2F799B00CF7658 /* gtest-death-test.h in Headers */, 404884380E2F799B00CF7658 /* gtest-death-test.h in Headers */,
404884390E2F799B00CF7658 /* gtest-message.h in Headers */, 404884390E2F799B00CF7658 /* gtest-message.h in Headers */,
4539C9340EC280AE00A70F4C /* gtest-param-test.h in Headers */,
3BF6F2A50E79B616000F2EEE /* gtest-typed-test.h in Headers */, 3BF6F2A50E79B616000F2EEE /* gtest-typed-test.h in Headers */,
4048843A0E2F799B00CF7658 /* gtest-spi.h in Headers */, 4048843A0E2F799B00CF7658 /* gtest-spi.h in Headers */,
4048843B0E2F799B00CF7658 /* gtest.h in Headers */, 4048843B0E2F799B00CF7658 /* gtest.h in Headers */,
@ -2069,6 +2236,91 @@
productReference = 3B87D2800E96C039000D1852 /* sample5_unittest */; productReference = 3B87D2800E96C039000D1852 /* sample5_unittest */;
productType = "com.apple.product-type.tool"; productType = "com.apple.product-type.tool";
}; };
4539C9050EC27FBC00A70F4C /* sample7_unittest */ = {
isa = PBXNativeTarget;
buildConfigurationList = 4539C90C0EC27FBC00A70F4C /* Build configuration list for PBXNativeTarget "sample7_unittest" */;
buildPhases = (
4539C9080EC27FBC00A70F4C /* Sources */,
4539C90A0EC27FBC00A70F4C /* Frameworks */,
);
buildRules = (
);
dependencies = (
4539C9060EC27FBC00A70F4C /* PBXTargetDependency */,
);
name = sample7_unittest;
productName = sample6;
productReference = 4539C90F0EC27FBC00A70F4C /* sample7_unittest */;
productType = "com.apple.product-type.tool";
};
4539C9110EC27FC000A70F4C /* sample8_unittest */ = {
isa = PBXNativeTarget;
buildConfigurationList = 4539C9180EC27FC000A70F4C /* Build configuration list for PBXNativeTarget "sample8_unittest" */;
buildPhases = (
4539C9140EC27FC000A70F4C /* Sources */,
4539C9160EC27FC000A70F4C /* Frameworks */,
);
buildRules = (
);
dependencies = (
4539C9120EC27FC000A70F4C /* PBXTargetDependency */,
);
name = sample8_unittest;
productName = sample6;
productReference = 4539C91B0EC27FC000A70F4C /* sample8_unittest */;
productType = "com.apple.product-type.tool";
};
4539C94D0EC282D400A70F4C /* gtest-param-test_test */ = {
isa = PBXNativeTarget;
buildConfigurationList = 4539C9550EC282D400A70F4C /* Build configuration list for PBXNativeTarget "gtest-param-test_test" */;
buildPhases = (
4539C9500EC282D400A70F4C /* Sources */,
4539C9530EC282D400A70F4C /* Frameworks */,
);
buildRules = (
);
dependencies = (
4539C94E0EC282D400A70F4C /* PBXTargetDependency */,
);
name = "gtest-param-test_test";
productName = TypedTest2;
productReference = 4539C9580EC282D400A70F4C /* gtest-param-test_test */;
productType = "com.apple.product-type.tool";
};
4539C9930EC283A800A70F4C /* gtest-port_test */ = {
isa = PBXNativeTarget;
buildConfigurationList = 4539C99B0EC283A800A70F4C /* Build configuration list for PBXNativeTarget "gtest-port_test" */;
buildPhases = (
4539C9960EC283A800A70F4C /* Sources */,
4539C9990EC283A800A70F4C /* Frameworks */,
);
buildRules = (
);
dependencies = (
4539C9940EC283A800A70F4C /* PBXTargetDependency */,
);
name = "gtest-port_test";
productName = TypedTest2;
productReference = 4539C99E0EC283A800A70F4C /* gtest-port_test */;
productType = "com.apple.product-type.tool";
};
4539C9A20EC2840700A70F4C /* gtest-linked_ptr_test */ = {
isa = PBXNativeTarget;
buildConfigurationList = 4539C9A90EC2840700A70F4C /* Build configuration list for PBXNativeTarget "gtest-linked_ptr_test" */;
buildPhases = (
4539C9A50EC2840700A70F4C /* Sources */,
4539C9A70EC2840700A70F4C /* Frameworks */,
);
buildRules = (
);
dependencies = (
4539C9A30EC2840700A70F4C /* PBXTargetDependency */,
);
name = "gtest-linked_ptr_test";
productName = TypedTest2;
productReference = 4539C9AC0EC2840700A70F4C /* gtest-linked_ptr_test */;
productType = "com.apple.product-type.tool";
};
8D07F2BC0486CC7A007CD1D0 /* gtest */ = { 8D07F2BC0486CC7A007CD1D0 /* gtest */ = {
isa = PBXNativeTarget; isa = PBXNativeTarget;
buildConfigurationList = 4FADC24208B4156D00ABE55E /* Build configuration list for PBXNativeTarget "gtest" */; buildConfigurationList = 4FADC24208B4156D00ABE55E /* Build configuration list for PBXNativeTarget "gtest" */;
@ -2087,7 +2339,7 @@
name = gtest; name = gtest;
productInstallPath = "$(HOME)/Library/Frameworks"; productInstallPath = "$(HOME)/Library/Frameworks";
productName = gtest; productName = gtest;
productReference = 408453CD0E96CE0700AC66C2 /* gtest.framework */; productReference = 4539C8FF0EC27F6400A70F4C /* gtest.framework */;
productType = "com.apple.product-type.framework"; productType = "com.apple.product-type.framework";
}; };
/* End PBXNativeTarget section */ /* End PBXNativeTarget section */
@ -2118,6 +2370,8 @@
404885E10E2F833000CF7658 /* sample4_unittest */, 404885E10E2F833000CF7658 /* sample4_unittest */,
404885EE0E2F833400CF7658 /* sample5_unittest */, 404885EE0E2F833400CF7658 /* sample5_unittest */,
22A866010E70A39900F7AE6E /* sample6_unittest */, 22A866010E70A39900F7AE6E /* sample6_unittest */,
4539C9050EC27FBC00A70F4C /* sample7_unittest */,
4539C9110EC27FC000A70F4C /* sample8_unittest */,
3B238EF30E8289CE00846E11 /* gtest_unittest */, 3B238EF30E8289CE00846E11 /* gtest_unittest */,
3B238C660E81B8B500846E11 /* gtest-death-test_test */, 3B238C660E81B8B500846E11 /* gtest-death-test_test */,
3B238D520E82855F00846E11 /* gtest-filepath_test */, 3B238D520E82855F00846E11 /* gtest-filepath_test */,
@ -2144,6 +2398,9 @@
3B238F150E828A3B00846E11 /* gtest_xml_outfile2_test_ */, 3B238F150E828A3B00846E11 /* gtest_xml_outfile2_test_ */,
3B238EE60E8289C900846E11 /* gtest_uninitialized_test_ */, 3B238EE60E8289C900846E11 /* gtest_uninitialized_test_ */,
3B238E850E82894800846E11 /* gtest_nc */, 3B238E850E82894800846E11 /* gtest_nc */,
4539C94D0EC282D400A70F4C /* gtest-param-test_test */,
4539C9930EC283A800A70F4C /* gtest-port_test */,
4539C9A20EC2840700A70F4C /* gtest-linked_ptr_test */,
40C44ADC0E3798F4008FCC51 /* Version Info */, 40C44ADC0E3798F4008FCC51 /* Version Info */,
408454310E96D39000AC66C2 /* Setup Python */, 408454310E96D39000AC66C2 /* Setup Python */,
); );
@ -2470,6 +2727,47 @@
); );
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
}; };
4539C9080EC27FBC00A70F4C /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
4539C91E0EC2800600A70F4C /* sample7_unittest.cc in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
4539C9140EC27FC000A70F4C /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
4539C9200EC2801E00A70F4C /* sample8_unittest.cc in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
4539C9500EC282D400A70F4C /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
4539C95C0EC2830E00A70F4C /* gtest-param-test2_test.cc in Sources */,
4539C95D0EC2830E00A70F4C /* gtest-param-test_test.cc in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
4539C9960EC283A800A70F4C /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
4539C9A10EC283E400A70F4C /* gtest-port_test.cc in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
4539C9A50EC2840700A70F4C /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
4539C9AF0EC2843000A70F4C /* gtest-linked_ptr_test.cc in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
8D07F2C10486CC7A007CD1D0 /* Sources */ = { 8D07F2C10486CC7A007CD1D0 /* Sources */ = {
isa = PBXSourcesBuildPhase; isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647; buildActionMask = 2147483647;
@ -2877,6 +3175,56 @@
target = 40C44ADC0E3798F4008FCC51 /* Version Info */; target = 40C44ADC0E3798F4008FCC51 /* Version Info */;
targetProxy = 40C44AE50E379922008FCC51 /* PBXContainerItemProxy */; targetProxy = 40C44AE50E379922008FCC51 /* PBXContainerItemProxy */;
}; };
4539C9060EC27FBC00A70F4C /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
target = 8D07F2BC0486CC7A007CD1D0 /* gtest */;
targetProxy = 4539C9070EC27FBC00A70F4C /* PBXContainerItemProxy */;
};
4539C9120EC27FC000A70F4C /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
target = 8D07F2BC0486CC7A007CD1D0 /* gtest */;
targetProxy = 4539C9130EC27FC000A70F4C /* PBXContainerItemProxy */;
};
4539C94A0EC2823500A70F4C /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
target = 4539C9110EC27FC000A70F4C /* sample8_unittest */;
targetProxy = 4539C9490EC2823500A70F4C /* PBXContainerItemProxy */;
};
4539C94C0EC2823500A70F4C /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
target = 4539C9050EC27FBC00A70F4C /* sample7_unittest */;
targetProxy = 4539C94B0EC2823500A70F4C /* PBXContainerItemProxy */;
};
4539C94E0EC282D400A70F4C /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
target = 8D07F2BC0486CC7A007CD1D0 /* gtest */;
targetProxy = 4539C94F0EC282D400A70F4C /* PBXContainerItemProxy */;
};
4539C95F0EC2833100A70F4C /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
target = 4539C94D0EC282D400A70F4C /* gtest-param-test_test */;
targetProxy = 4539C95E0EC2833100A70F4C /* PBXContainerItemProxy */;
};
4539C9940EC283A800A70F4C /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
target = 8D07F2BC0486CC7A007CD1D0 /* gtest */;
targetProxy = 4539C9950EC283A800A70F4C /* PBXContainerItemProxy */;
};
4539C9A30EC2840700A70F4C /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
target = 8D07F2BC0486CC7A007CD1D0 /* gtest */;
targetProxy = 4539C9A40EC2840700A70F4C /* PBXContainerItemProxy */;
};
4539C9B10EC284C300A70F4C /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
target = 4539C9A20EC2840700A70F4C /* gtest-linked_ptr_test */;
targetProxy = 4539C9B00EC284C300A70F4C /* PBXContainerItemProxy */;
};
4539C9B30EC284C300A70F4C /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
target = 4539C9930EC283A800A70F4C /* gtest-port_test */;
targetProxy = 4539C9B20EC284C300A70F4C /* PBXContainerItemProxy */;
};
/* End PBXTargetDependency section */ /* End PBXTargetDependency section */
/* Begin XCBuildConfiguration section */ /* Begin XCBuildConfiguration section */
@ -3827,6 +4175,146 @@
}; };
name = Release; name = Release;
}; };
4539C90D0EC27FBC00A70F4C /* Debug */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 3B23903C0E830EA800846E11 /* TestTarget.xcconfig */;
buildSettings = {
FRAMEWORK_SEARCH_PATHS = (
"$(inherited)",
"$(FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1)",
"$(FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_2)",
);
FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1 = "\"$(SRCROOT)/build/Debug\"";
FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_2 = "\"$(SRCROOT)/build/Debug\"";
};
name = Debug;
};
4539C90E0EC27FBC00A70F4C /* Release */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 3B23903C0E830EA800846E11 /* TestTarget.xcconfig */;
buildSettings = {
FRAMEWORK_SEARCH_PATHS = (
"$(inherited)",
"$(FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1)",
"$(FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_2)",
);
FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1 = "\"$(SRCROOT)/build/Debug\"";
FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_2 = "\"$(SRCROOT)/build/Debug\"";
};
name = Release;
};
4539C9190EC27FC000A70F4C /* Debug */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 3B23903C0E830EA800846E11 /* TestTarget.xcconfig */;
buildSettings = {
FRAMEWORK_SEARCH_PATHS = (
"$(inherited)",
"$(FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1)",
"$(FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_2)",
);
FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1 = "\"$(SRCROOT)/build/Debug\"";
FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_2 = "\"$(SRCROOT)/build/Debug\"";
};
name = Debug;
};
4539C91A0EC27FC000A70F4C /* Release */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 3B23903C0E830EA800846E11 /* TestTarget.xcconfig */;
buildSettings = {
FRAMEWORK_SEARCH_PATHS = (
"$(inherited)",
"$(FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1)",
"$(FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_2)",
);
FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1 = "\"$(SRCROOT)/build/Debug\"";
FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_2 = "\"$(SRCROOT)/build/Debug\"";
};
name = Release;
};
4539C9560EC282D400A70F4C /* Debug */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 3B238D190E82837D00846E11 /* InternalTestTarget.xcconfig */;
buildSettings = {
FRAMEWORK_SEARCH_PATHS = (
"$(inherited)",
"$(FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1)",
"$(FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_2)",
);
FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1 = "\"$(SRCROOT)/build/Debug\"";
FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_2 = "\"$(SRCROOT)/build/Debug\"";
};
name = Debug;
};
4539C9570EC282D400A70F4C /* Release */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 3B238D190E82837D00846E11 /* InternalTestTarget.xcconfig */;
buildSettings = {
FRAMEWORK_SEARCH_PATHS = (
"$(inherited)",
"$(FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1)",
"$(FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_2)",
);
FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1 = "\"$(SRCROOT)/build/Debug\"";
FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_2 = "\"$(SRCROOT)/build/Debug\"";
};
name = Release;
};
4539C99C0EC283A800A70F4C /* Debug */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 3B238D190E82837D00846E11 /* InternalTestTarget.xcconfig */;
buildSettings = {
FRAMEWORK_SEARCH_PATHS = (
"$(inherited)",
"$(FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1)",
"$(FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_2)",
);
FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1 = "\"$(SRCROOT)/build/Debug\"";
FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_2 = "\"$(SRCROOT)/build/Debug\"";
};
name = Debug;
};
4539C99D0EC283A800A70F4C /* Release */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 3B238D190E82837D00846E11 /* InternalTestTarget.xcconfig */;
buildSettings = {
FRAMEWORK_SEARCH_PATHS = (
"$(inherited)",
"$(FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1)",
"$(FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_2)",
);
FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1 = "\"$(SRCROOT)/build/Debug\"";
FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_2 = "\"$(SRCROOT)/build/Debug\"";
};
name = Release;
};
4539C9AA0EC2840700A70F4C /* Debug */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 3B238D190E82837D00846E11 /* InternalTestTarget.xcconfig */;
buildSettings = {
FRAMEWORK_SEARCH_PATHS = (
"$(inherited)",
"$(FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1)",
"$(FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_2)",
);
FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1 = "\"$(SRCROOT)/build/Debug\"";
FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_2 = "\"$(SRCROOT)/build/Debug\"";
};
name = Debug;
};
4539C9AB0EC2840700A70F4C /* Release */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 3B238D190E82837D00846E11 /* InternalTestTarget.xcconfig */;
buildSettings = {
FRAMEWORK_SEARCH_PATHS = (
"$(inherited)",
"$(FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1)",
"$(FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_2)",
);
FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1 = "\"$(SRCROOT)/build/Debug\"";
FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_2 = "\"$(SRCROOT)/build/Debug\"";
};
name = Release;
};
4FADC24308B4156D00ABE55E /* Debug */ = { 4FADC24308B4156D00ABE55E /* Debug */ = {
isa = XCBuildConfiguration; isa = XCBuildConfiguration;
baseConfigurationReference = 40D4CDF20E30E07400294801 /* FrameworkTarget.xcconfig */; baseConfigurationReference = 40D4CDF20E30E07400294801 /* FrameworkTarget.xcconfig */;
@ -4195,6 +4683,51 @@
defaultConfigurationIsVisible = 0; defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release; defaultConfigurationName = Release;
}; };
4539C90C0EC27FBC00A70F4C /* Build configuration list for PBXNativeTarget "sample7_unittest" */ = {
isa = XCConfigurationList;
buildConfigurations = (
4539C90D0EC27FBC00A70F4C /* Debug */,
4539C90E0EC27FBC00A70F4C /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
4539C9180EC27FC000A70F4C /* Build configuration list for PBXNativeTarget "sample8_unittest" */ = {
isa = XCConfigurationList;
buildConfigurations = (
4539C9190EC27FC000A70F4C /* Debug */,
4539C91A0EC27FC000A70F4C /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
4539C9550EC282D400A70F4C /* Build configuration list for PBXNativeTarget "gtest-param-test_test" */ = {
isa = XCConfigurationList;
buildConfigurations = (
4539C9560EC282D400A70F4C /* Debug */,
4539C9570EC282D400A70F4C /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
4539C99B0EC283A800A70F4C /* Build configuration list for PBXNativeTarget "gtest-port_test" */ = {
isa = XCConfigurationList;
buildConfigurations = (
4539C99C0EC283A800A70F4C /* Debug */,
4539C99D0EC283A800A70F4C /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
4539C9A90EC2840700A70F4C /* Build configuration list for PBXNativeTarget "gtest-linked_ptr_test" */ = {
isa = XCConfigurationList;
buildConfigurations = (
4539C9AA0EC2840700A70F4C /* Debug */,
4539C9AB0EC2840700A70F4C /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
4FADC24208B4156D00ABE55E /* Build configuration list for PBXNativeTarget "gtest" */ = { 4FADC24208B4156D00ABE55E /* Build configuration list for PBXNativeTarget "gtest" */ = {
isa = XCConfigurationList; isa = XCConfigurationList;
buildConfigurations = ( buildConfigurations = (