Implements a subset of TR1 tuple needed by gtest and gmock (by Zhanyong Wan); cleaned up the Python tests (by Vlad Losev); made run_tests.py invokable from any directory (by Vlad Losev).

This commit is contained in:
zhanyong.wan 2009-06-17 21:06:27 +00:00
parent 210ea10e7a
commit 532dc2de35
23 changed files with 1941 additions and 161 deletions

View File

@ -300,6 +300,23 @@ test_gtest_no_rtti_test_SOURCES = test/gtest_unittest.cc \
src/gtest_main.cc
test_gtest_no_rtti_test_CXXFLAGS = $(AM_CXXFLAGS) -fno-rtti -DGTEST_HAS_RTTI=0
# Verifies that Google Test's own TR1 tuple implementation works.
TESTS += test/gtest-tuple_test
check_PROGRAMS += test/gtest-tuple_test
test_gtest_tuple_test_SOURCES = test/gtest-tuple_test.cc \
src/gtest-all.cc \
src/gtest_main.cc
test_gtest_tuple_test_CXXFLAGS = $(AM_CXXFLAGS) -DGTEST_USE_OWN_TR1_TUPLE=1
# Verifies that Google Test's features that use its own TR1 tuple work.
TESTS += test/gtest_use_own_tuple_test
check_PROGRAMS += test/gtest_use_own_tuple_test
test_gtest_use_own_tuple_test_SOURCES = test/gtest-param-test_test.cc \
test/gtest-param-test2_test.cc \
src/gtest-all.cc
test_gtest_use_own_tuple_test_CXXFLAGS = \
$(AM_CXXFLAGS) -DGTEST_USE_OWN_TR1_TUPLE=1
# The following tests depend on the presence of a Python installation and are
# keyed off of it. TODO(chandlerc@google.com): While we currently only attempt
# to build and execute these tests if Autoconf has found Python v2.4 on the

26
README
View File

@ -112,6 +112,32 @@ which contains all of the source code. Here are some examples in Linux:
tar -xvjf gtest-X.Y.Z.tar.bz2
unzip gtest-X.Y.Z.zip
Choosing a TR1 Tuple Library
----------------------------
Some Google Test features require the C++ Technical Report 1 (TR1)
tuple library, which is not yet widely available with all compilers.
The good news is that Google Test implements a subset of TR1 tuple
that's enough for its own need, and will automatically use this when
the compiler doesn't provide TR1 tuple.
Usually you don't need to care about which tuple library Google Test
uses. However, if your project already uses TR1 tuple, you need to
tell Google Test to use the same TR1 tuple library the rest of your
project uses (this requirement is new in Google Test 1.4.0, so you may
need to take care of it when upgrading from an earlier version), or
the two tuple implementations will clash. To do that, add
-DGTEST_USE_OWN_TR1_TUPLE=0
to the compiler flags while compiling Google Test and your tests.
If you don't want Google Test to use tuple at all, add
-DGTEST_HAS_TR1_TUPLE=0
to the compiler flags. All features using tuple will be disabled in
this mode.
Building the Source
-------------------
### Linux, Mac OS X (without Xcode), and Cygwin ###

View File

@ -58,11 +58,15 @@
// GTEST_HAS_STD_WSTRING - Define it to 1/0 to indicate that
// std::wstring does/doesn't work (Google Test can
// be used where std::wstring is unavailable).
// GTEST_HAS_TR1_TUPLE 1 - Define it to 1/0 to indicate tr1::tuple
// GTEST_HAS_TR1_TUPLE - Define it to 1/0 to indicate tr1::tuple
// is/isn't available.
// GTEST_HAS_SEH - Define it to 1/0 to indicate whether the
// compiler supports Microsoft's "Structured
// Exception Handling".
// GTEST_USE_OWN_TR1_TUPLE - Define it to 1/0 to indicate whether Google
// Test's own tr1 tuple implementation should be
// used. Unused when the user sets
// GTEST_HAS_TR1_TUPLE to 0.
// This header defines the following utilities:
//
@ -339,28 +343,41 @@
#define GTEST_HAS_PTHREAD (GTEST_OS_LINUX || GTEST_OS_MAC)
#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.
// Determines whether Google Test can use tr1/tuple. You can define
// this macro to 0 to prevent Google Test from using tuple (any
// feature depending on tuple with be disabled in this mode).
#ifndef GTEST_HAS_TR1_TUPLE
// The user didn't tell us not to do it, so we assume it's OK.
#define GTEST_HAS_TR1_TUPLE 1
#endif // GTEST_HAS_TR1_TUPLE
// Determines whether Google Test's own tr1 tuple implementation
// should be used.
#ifndef GTEST_USE_OWN_TR1_TUPLE
// The user didn't tell us, so we need to figure it out.
// GCC provides <tr1/tuple> since 4.0.0.
// We use our own tr1 tuple if we aren't sure the user has an
// implementation of it already. At this time, GCC 4.0.0+ is the only
// mainstream compiler that comes with a TR1 tuple implementation.
// MSVC 2008 (9.0) provides TR1 tuple in a 323 MB Feature Pack
// download, which we cannot assume the user has. MSVC 2010 isn't
// released yet.
#if defined(__GNUC__) && (GTEST_GCC_VER_ >= 40000)
#define GTEST_HAS_TR1_TUPLE 1
#define GTEST_USE_OWN_TR1_TUPLE 0
#else
#define GTEST_HAS_TR1_TUPLE 0
#endif // __GNUC__
#endif // GTEST_HAS_TR1_TUPLE
#define GTEST_USE_OWN_TR1_TUPLE 1
#endif // defined(__GNUC__) && (GTEST_GCC_VER_ >= 40000)
#endif // GTEST_USE_OWN_TR1_TUPLE
// To avoid conditional compilation everywhere, we make it
// gtest-port.h's responsibility to #include the header implementing
// tr1/tuple.
#if GTEST_HAS_TR1_TUPLE
#if GTEST_OS_SYMBIAN
#if GTEST_USE_OWN_TR1_TUPLE
#include <gtest/internal/gtest-tuple.h>
#elif GTEST_OS_SYMBIAN
// On Symbian, BOOST_HAS_TR1_TUPLE causes Boost's TR1 tuple library to
// use STLport's tuple implementation, which unfortunately doesn't
@ -398,7 +415,7 @@
// If the compiler is not GCC 4.0+, we assume the user is using a
// spec-conforming TR1 implementation.
#include <tuple>
#endif // GTEST_OS_SYMBIAN
#endif // GTEST_USE_OWN_TR1_TUPLE
#endif // GTEST_HAS_TR1_TUPLE

View File

@ -0,0 +1,945 @@
// This file was GENERATED by a script. DO NOT EDIT BY HAND!!!
// Copyright 2009 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)
// Implements a subset of TR1 tuple needed by Google Test and Google Mock.
#ifndef GTEST_INCLUDE_GTEST_INTERAL_GTEST_TUPLE_H_
#define GTEST_INCLUDE_GTEST_INTERAL_GTEST_TUPLE_H_
#include <utility> // For ::std::pair.
// GTEST_n_TUPLE_(T) is the type of an n-tuple.
#define GTEST_0_TUPLE_(T) tuple<>
#define GTEST_1_TUPLE_(T) tuple<T##0>
#define GTEST_2_TUPLE_(T) tuple<T##0, T##1>
#define GTEST_3_TUPLE_(T) tuple<T##0, T##1, T##2>
#define GTEST_4_TUPLE_(T) tuple<T##0, T##1, T##2, T##3>
#define GTEST_5_TUPLE_(T) tuple<T##0, T##1, T##2, T##3, T##4>
#define GTEST_6_TUPLE_(T) tuple<T##0, T##1, T##2, T##3, T##4, T##5>
#define GTEST_7_TUPLE_(T) tuple<T##0, T##1, T##2, T##3, T##4, T##5, T##6>
#define GTEST_8_TUPLE_(T) tuple<T##0, T##1, T##2, T##3, T##4, T##5, T##6, T##7>
#define GTEST_9_TUPLE_(T) tuple<T##0, T##1, T##2, T##3, T##4, T##5, T##6, \
T##7, T##8>
#define GTEST_10_TUPLE_(T) tuple<T##0, T##1, T##2, T##3, T##4, T##5, T##6, \
T##7, T##8, T##9>
// GTEST_n_TYPENAMES_(T) declares a list of n typenames.
#define GTEST_0_TYPENAMES_(T)
#define GTEST_1_TYPENAMES_(T) typename T##0
#define GTEST_2_TYPENAMES_(T) typename T##0, typename T##1
#define GTEST_3_TYPENAMES_(T) typename T##0, typename T##1, typename T##2
#define GTEST_4_TYPENAMES_(T) typename T##0, typename T##1, typename T##2, \
typename T##3
#define GTEST_5_TYPENAMES_(T) typename T##0, typename T##1, typename T##2, \
typename T##3, typename T##4
#define GTEST_6_TYPENAMES_(T) typename T##0, typename T##1, typename T##2, \
typename T##3, typename T##4, typename T##5
#define GTEST_7_TYPENAMES_(T) typename T##0, typename T##1, typename T##2, \
typename T##3, typename T##4, typename T##5, typename T##6
#define GTEST_8_TYPENAMES_(T) typename T##0, typename T##1, typename T##2, \
typename T##3, typename T##4, typename T##5, typename T##6, typename T##7
#define GTEST_9_TYPENAMES_(T) typename T##0, typename T##1, typename T##2, \
typename T##3, typename T##4, typename T##5, typename T##6, \
typename T##7, typename T##8
#define GTEST_10_TYPENAMES_(T) typename T##0, typename T##1, typename T##2, \
typename T##3, typename T##4, typename T##5, typename T##6, \
typename T##7, typename T##8, typename T##9
// In theory, defining stuff in the ::std namespace is undefined
// behavior. We can do this as we are playing the role of a standard
// library vendor.
namespace std {
namespace tr1 {
template <typename T0 = void, typename T1 = void, typename T2 = void,
typename T3 = void, typename T4 = void, typename T5 = void,
typename T6 = void, typename T7 = void, typename T8 = void,
typename T9 = void>
class tuple;
// Anything in namespace gtest_internal is Google Test's INTERNAL
// IMPLEMENTATION DETAIL and MUST NOT BE USED DIRECTLY in user code.
namespace gtest_internal {
// ByRef<T>::type is T if T is a reference; otherwise it's const T&.
template <typename T>
struct ByRef { typedef const T& type; }; // NOLINT
template <typename T>
struct ByRef<T&> { typedef T& type; }; // NOLINT
// A handy wrapper for ByRef.
#define GTEST_BY_REF_(T) typename ::std::tr1::gtest_internal::ByRef<T>::type
// AddRef<T>::type is T if T is a reference; otherwise it's T&. This
// is the same as tr1::add_reference<T>::type.
template <typename T>
struct AddRef { typedef T& type; }; // NOLINT
template <typename T>
struct AddRef<T&> { typedef T& type; }; // NOLINT
// A handy wrapper for AddRef.
#define GTEST_ADD_REF_(T) typename ::std::tr1::gtest_internal::AddRef<T>::type
// A helper for implementing get<k>().
template <int k> class Get;
// A helper for implementing tuple_element<k, T>. kIndexValid is true
// iff k < the number of fields in tuple type T.
template <bool kIndexValid, int kIndex, class Tuple>
struct TupleElement;
template <GTEST_10_TYPENAMES_(T)>
struct TupleElement<true, 0, GTEST_10_TUPLE_(T)> { typedef T0 type; };
template <GTEST_10_TYPENAMES_(T)>
struct TupleElement<true, 1, GTEST_10_TUPLE_(T)> { typedef T1 type; };
template <GTEST_10_TYPENAMES_(T)>
struct TupleElement<true, 2, GTEST_10_TUPLE_(T)> { typedef T2 type; };
template <GTEST_10_TYPENAMES_(T)>
struct TupleElement<true, 3, GTEST_10_TUPLE_(T)> { typedef T3 type; };
template <GTEST_10_TYPENAMES_(T)>
struct TupleElement<true, 4, GTEST_10_TUPLE_(T)> { typedef T4 type; };
template <GTEST_10_TYPENAMES_(T)>
struct TupleElement<true, 5, GTEST_10_TUPLE_(T)> { typedef T5 type; };
template <GTEST_10_TYPENAMES_(T)>
struct TupleElement<true, 6, GTEST_10_TUPLE_(T)> { typedef T6 type; };
template <GTEST_10_TYPENAMES_(T)>
struct TupleElement<true, 7, GTEST_10_TUPLE_(T)> { typedef T7 type; };
template <GTEST_10_TYPENAMES_(T)>
struct TupleElement<true, 8, GTEST_10_TUPLE_(T)> { typedef T8 type; };
template <GTEST_10_TYPENAMES_(T)>
struct TupleElement<true, 9, GTEST_10_TUPLE_(T)> { typedef T9 type; };
} // namespace gtest_internal
template <>
class tuple<> {
public:
tuple() {}
tuple(const tuple& /* t */) {}
tuple& operator=(const tuple& /* t */) { return *this; }
};
template <GTEST_1_TYPENAMES_(T)>
class GTEST_1_TUPLE_(T) {
public:
template <int k> friend class gtest_internal::Get;
template <GTEST_10_TYPENAMES_(U)> friend class tuple;
tuple() {}
explicit tuple(GTEST_BY_REF_(T0) f0) : f0_(f0) {}
tuple(const tuple& t) : f0_(t.f0_) {}
template <GTEST_1_TYPENAMES_(U)>
tuple(const GTEST_1_TUPLE_(U)& t) : f0_(t.f0_) {}
tuple& operator=(const tuple& t) { return CopyFrom(t); }
template <GTEST_1_TYPENAMES_(U)>
tuple& operator=(const GTEST_1_TUPLE_(U)& t) {
return CopyFrom(t);
}
private:
template <GTEST_1_TYPENAMES_(U)>
tuple& CopyFrom(const GTEST_1_TUPLE_(U)& t) {
f0_ = t.f0_;
return *this;
}
T0 f0_;
};
template <GTEST_2_TYPENAMES_(T)>
class GTEST_2_TUPLE_(T) {
public:
template <int k> friend class gtest_internal::Get;
template <GTEST_10_TYPENAMES_(U)> friend class tuple;
tuple() {}
explicit tuple(GTEST_BY_REF_(T0) f0, GTEST_BY_REF_(T1) f1) : f0_(f0),
f1_(f1) {}
tuple(const tuple& t) : f0_(t.f0_), f1_(t.f1_) {}
template <GTEST_2_TYPENAMES_(U)>
tuple(const GTEST_2_TUPLE_(U)& t) : f0_(t.f0_), f1_(t.f1_) {}
template <typename U0, typename U1>
tuple(const ::std::pair<U0, U1>& p) : f0_(p.first), f1_(p.second) {}
tuple& operator=(const tuple& t) { return CopyFrom(t); }
template <GTEST_2_TYPENAMES_(U)>
tuple& operator=(const GTEST_2_TUPLE_(U)& t) {
return CopyFrom(t);
}
template <typename U0, typename U1>
tuple& operator=(const ::std::pair<U0, U1>& p) {
f0_ = p.first;
f1_ = p.second;
return *this;
}
private:
template <GTEST_2_TYPENAMES_(U)>
tuple& CopyFrom(const GTEST_2_TUPLE_(U)& t) {
f0_ = t.f0_;
f1_ = t.f1_;
return *this;
}
T0 f0_;
T1 f1_;
};
template <GTEST_3_TYPENAMES_(T)>
class GTEST_3_TUPLE_(T) {
public:
template <int k> friend class gtest_internal::Get;
template <GTEST_10_TYPENAMES_(U)> friend class tuple;
tuple() {}
explicit tuple(GTEST_BY_REF_(T0) f0, GTEST_BY_REF_(T1) f1,
GTEST_BY_REF_(T2) f2) : f0_(f0), f1_(f1), f2_(f2) {}
tuple(const tuple& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_) {}
template <GTEST_3_TYPENAMES_(U)>
tuple(const GTEST_3_TUPLE_(U)& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_) {}
tuple& operator=(const tuple& t) { return CopyFrom(t); }
template <GTEST_3_TYPENAMES_(U)>
tuple& operator=(const GTEST_3_TUPLE_(U)& t) {
return CopyFrom(t);
}
private:
template <GTEST_3_TYPENAMES_(U)>
tuple& CopyFrom(const GTEST_3_TUPLE_(U)& t) {
f0_ = t.f0_;
f1_ = t.f1_;
f2_ = t.f2_;
return *this;
}
T0 f0_;
T1 f1_;
T2 f2_;
};
template <GTEST_4_TYPENAMES_(T)>
class GTEST_4_TUPLE_(T) {
public:
template <int k> friend class gtest_internal::Get;
template <GTEST_10_TYPENAMES_(U)> friend class tuple;
tuple() {}
explicit tuple(GTEST_BY_REF_(T0) f0, GTEST_BY_REF_(T1) f1,
GTEST_BY_REF_(T2) f2, GTEST_BY_REF_(T3) f3) : f0_(f0), f1_(f1), f2_(f2),
f3_(f3) {}
tuple(const tuple& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), f3_(t.f3_) {}
template <GTEST_4_TYPENAMES_(U)>
tuple(const GTEST_4_TUPLE_(U)& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_),
f3_(t.f3_) {}
tuple& operator=(const tuple& t) { return CopyFrom(t); }
template <GTEST_4_TYPENAMES_(U)>
tuple& operator=(const GTEST_4_TUPLE_(U)& t) {
return CopyFrom(t);
}
private:
template <GTEST_4_TYPENAMES_(U)>
tuple& CopyFrom(const GTEST_4_TUPLE_(U)& t) {
f0_ = t.f0_;
f1_ = t.f1_;
f2_ = t.f2_;
f3_ = t.f3_;
return *this;
}
T0 f0_;
T1 f1_;
T2 f2_;
T3 f3_;
};
template <GTEST_5_TYPENAMES_(T)>
class GTEST_5_TUPLE_(T) {
public:
template <int k> friend class gtest_internal::Get;
template <GTEST_10_TYPENAMES_(U)> friend class tuple;
tuple() {}
explicit tuple(GTEST_BY_REF_(T0) f0, GTEST_BY_REF_(T1) f1,
GTEST_BY_REF_(T2) f2, GTEST_BY_REF_(T3) f3,
GTEST_BY_REF_(T4) f4) : f0_(f0), f1_(f1), f2_(f2), f3_(f3), f4_(f4) {}
tuple(const tuple& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), f3_(t.f3_),
f4_(t.f4_) {}
template <GTEST_5_TYPENAMES_(U)>
tuple(const GTEST_5_TUPLE_(U)& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_),
f3_(t.f3_), f4_(t.f4_) {}
tuple& operator=(const tuple& t) { return CopyFrom(t); }
template <GTEST_5_TYPENAMES_(U)>
tuple& operator=(const GTEST_5_TUPLE_(U)& t) {
return CopyFrom(t);
}
private:
template <GTEST_5_TYPENAMES_(U)>
tuple& CopyFrom(const GTEST_5_TUPLE_(U)& t) {
f0_ = t.f0_;
f1_ = t.f1_;
f2_ = t.f2_;
f3_ = t.f3_;
f4_ = t.f4_;
return *this;
}
T0 f0_;
T1 f1_;
T2 f2_;
T3 f3_;
T4 f4_;
};
template <GTEST_6_TYPENAMES_(T)>
class GTEST_6_TUPLE_(T) {
public:
template <int k> friend class gtest_internal::Get;
template <GTEST_10_TYPENAMES_(U)> friend class tuple;
tuple() {}
explicit tuple(GTEST_BY_REF_(T0) f0, GTEST_BY_REF_(T1) f1,
GTEST_BY_REF_(T2) f2, GTEST_BY_REF_(T3) f3, GTEST_BY_REF_(T4) f4,
GTEST_BY_REF_(T5) f5) : f0_(f0), f1_(f1), f2_(f2), f3_(f3), f4_(f4),
f5_(f5) {}
tuple(const tuple& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), f3_(t.f3_),
f4_(t.f4_), f5_(t.f5_) {}
template <GTEST_6_TYPENAMES_(U)>
tuple(const GTEST_6_TUPLE_(U)& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_),
f3_(t.f3_), f4_(t.f4_), f5_(t.f5_) {}
tuple& operator=(const tuple& t) { return CopyFrom(t); }
template <GTEST_6_TYPENAMES_(U)>
tuple& operator=(const GTEST_6_TUPLE_(U)& t) {
return CopyFrom(t);
}
private:
template <GTEST_6_TYPENAMES_(U)>
tuple& CopyFrom(const GTEST_6_TUPLE_(U)& t) {
f0_ = t.f0_;
f1_ = t.f1_;
f2_ = t.f2_;
f3_ = t.f3_;
f4_ = t.f4_;
f5_ = t.f5_;
return *this;
}
T0 f0_;
T1 f1_;
T2 f2_;
T3 f3_;
T4 f4_;
T5 f5_;
};
template <GTEST_7_TYPENAMES_(T)>
class GTEST_7_TUPLE_(T) {
public:
template <int k> friend class gtest_internal::Get;
template <GTEST_10_TYPENAMES_(U)> friend class tuple;
tuple() {}
explicit tuple(GTEST_BY_REF_(T0) f0, GTEST_BY_REF_(T1) f1,
GTEST_BY_REF_(T2) f2, GTEST_BY_REF_(T3) f3, GTEST_BY_REF_(T4) f4,
GTEST_BY_REF_(T5) f5, GTEST_BY_REF_(T6) f6) : f0_(f0), f1_(f1), f2_(f2),
f3_(f3), f4_(f4), f5_(f5), f6_(f6) {}
tuple(const tuple& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), f3_(t.f3_),
f4_(t.f4_), f5_(t.f5_), f6_(t.f6_) {}
template <GTEST_7_TYPENAMES_(U)>
tuple(const GTEST_7_TUPLE_(U)& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_),
f3_(t.f3_), f4_(t.f4_), f5_(t.f5_), f6_(t.f6_) {}
tuple& operator=(const tuple& t) { return CopyFrom(t); }
template <GTEST_7_TYPENAMES_(U)>
tuple& operator=(const GTEST_7_TUPLE_(U)& t) {
return CopyFrom(t);
}
private:
template <GTEST_7_TYPENAMES_(U)>
tuple& CopyFrom(const GTEST_7_TUPLE_(U)& t) {
f0_ = t.f0_;
f1_ = t.f1_;
f2_ = t.f2_;
f3_ = t.f3_;
f4_ = t.f4_;
f5_ = t.f5_;
f6_ = t.f6_;
return *this;
}
T0 f0_;
T1 f1_;
T2 f2_;
T3 f3_;
T4 f4_;
T5 f5_;
T6 f6_;
};
template <GTEST_8_TYPENAMES_(T)>
class GTEST_8_TUPLE_(T) {
public:
template <int k> friend class gtest_internal::Get;
template <GTEST_10_TYPENAMES_(U)> friend class tuple;
tuple() {}
explicit tuple(GTEST_BY_REF_(T0) f0, GTEST_BY_REF_(T1) f1,
GTEST_BY_REF_(T2) f2, GTEST_BY_REF_(T3) f3, GTEST_BY_REF_(T4) f4,
GTEST_BY_REF_(T5) f5, GTEST_BY_REF_(T6) f6,
GTEST_BY_REF_(T7) f7) : f0_(f0), f1_(f1), f2_(f2), f3_(f3), f4_(f4),
f5_(f5), f6_(f6), f7_(f7) {}
tuple(const tuple& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), f3_(t.f3_),
f4_(t.f4_), f5_(t.f5_), f6_(t.f6_), f7_(t.f7_) {}
template <GTEST_8_TYPENAMES_(U)>
tuple(const GTEST_8_TUPLE_(U)& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_),
f3_(t.f3_), f4_(t.f4_), f5_(t.f5_), f6_(t.f6_), f7_(t.f7_) {}
tuple& operator=(const tuple& t) { return CopyFrom(t); }
template <GTEST_8_TYPENAMES_(U)>
tuple& operator=(const GTEST_8_TUPLE_(U)& t) {
return CopyFrom(t);
}
private:
template <GTEST_8_TYPENAMES_(U)>
tuple& CopyFrom(const GTEST_8_TUPLE_(U)& t) {
f0_ = t.f0_;
f1_ = t.f1_;
f2_ = t.f2_;
f3_ = t.f3_;
f4_ = t.f4_;
f5_ = t.f5_;
f6_ = t.f6_;
f7_ = t.f7_;
return *this;
}
T0 f0_;
T1 f1_;
T2 f2_;
T3 f3_;
T4 f4_;
T5 f5_;
T6 f6_;
T7 f7_;
};
template <GTEST_9_TYPENAMES_(T)>
class GTEST_9_TUPLE_(T) {
public:
template <int k> friend class gtest_internal::Get;
template <GTEST_10_TYPENAMES_(U)> friend class tuple;
tuple() {}
explicit tuple(GTEST_BY_REF_(T0) f0, GTEST_BY_REF_(T1) f1,
GTEST_BY_REF_(T2) f2, GTEST_BY_REF_(T3) f3, GTEST_BY_REF_(T4) f4,
GTEST_BY_REF_(T5) f5, GTEST_BY_REF_(T6) f6, GTEST_BY_REF_(T7) f7,
GTEST_BY_REF_(T8) f8) : f0_(f0), f1_(f1), f2_(f2), f3_(f3), f4_(f4),
f5_(f5), f6_(f6), f7_(f7), f8_(f8) {}
tuple(const tuple& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), f3_(t.f3_),
f4_(t.f4_), f5_(t.f5_), f6_(t.f6_), f7_(t.f7_), f8_(t.f8_) {}
template <GTEST_9_TYPENAMES_(U)>
tuple(const GTEST_9_TUPLE_(U)& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_),
f3_(t.f3_), f4_(t.f4_), f5_(t.f5_), f6_(t.f6_), f7_(t.f7_), f8_(t.f8_) {}
tuple& operator=(const tuple& t) { return CopyFrom(t); }
template <GTEST_9_TYPENAMES_(U)>
tuple& operator=(const GTEST_9_TUPLE_(U)& t) {
return CopyFrom(t);
}
private:
template <GTEST_9_TYPENAMES_(U)>
tuple& CopyFrom(const GTEST_9_TUPLE_(U)& t) {
f0_ = t.f0_;
f1_ = t.f1_;
f2_ = t.f2_;
f3_ = t.f3_;
f4_ = t.f4_;
f5_ = t.f5_;
f6_ = t.f6_;
f7_ = t.f7_;
f8_ = t.f8_;
return *this;
}
T0 f0_;
T1 f1_;
T2 f2_;
T3 f3_;
T4 f4_;
T5 f5_;
T6 f6_;
T7 f7_;
T8 f8_;
};
template <GTEST_10_TYPENAMES_(T)>
class tuple {
public:
template <int k> friend class gtest_internal::Get;
template <GTEST_10_TYPENAMES_(U)> friend class tuple;
tuple() {}
explicit tuple(GTEST_BY_REF_(T0) f0, GTEST_BY_REF_(T1) f1,
GTEST_BY_REF_(T2) f2, GTEST_BY_REF_(T3) f3, GTEST_BY_REF_(T4) f4,
GTEST_BY_REF_(T5) f5, GTEST_BY_REF_(T6) f6, GTEST_BY_REF_(T7) f7,
GTEST_BY_REF_(T8) f8, GTEST_BY_REF_(T9) f9) : f0_(f0), f1_(f1), f2_(f2),
f3_(f3), f4_(f4), f5_(f5), f6_(f6), f7_(f7), f8_(f8), f9_(f9) {}
tuple(const tuple& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), f3_(t.f3_),
f4_(t.f4_), f5_(t.f5_), f6_(t.f6_), f7_(t.f7_), f8_(t.f8_), f9_(t.f9_) {}
template <GTEST_10_TYPENAMES_(U)>
tuple(const GTEST_10_TUPLE_(U)& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_),
f3_(t.f3_), f4_(t.f4_), f5_(t.f5_), f6_(t.f6_), f7_(t.f7_), f8_(t.f8_),
f9_(t.f9_) {}
tuple& operator=(const tuple& t) { return CopyFrom(t); }
template <GTEST_10_TYPENAMES_(U)>
tuple& operator=(const GTEST_10_TUPLE_(U)& t) {
return CopyFrom(t);
}
private:
template <GTEST_10_TYPENAMES_(U)>
tuple& CopyFrom(const GTEST_10_TUPLE_(U)& t) {
f0_ = t.f0_;
f1_ = t.f1_;
f2_ = t.f2_;
f3_ = t.f3_;
f4_ = t.f4_;
f5_ = t.f5_;
f6_ = t.f6_;
f7_ = t.f7_;
f8_ = t.f8_;
f9_ = t.f9_;
return *this;
}
T0 f0_;
T1 f1_;
T2 f2_;
T3 f3_;
T4 f4_;
T5 f5_;
T6 f6_;
T7 f7_;
T8 f8_;
T9 f9_;
};
// 6.1.3.2 Tuple creation functions.
// Known limitations: we don't support passing an
// std::tr1::reference_wrapper<T> to make_tuple(). And we don't
// implement tie().
inline tuple<> make_tuple() { return tuple<>(); }
template <GTEST_1_TYPENAMES_(T)>
inline GTEST_1_TUPLE_(T) make_tuple(const T0& f0) {
return GTEST_1_TUPLE_(T)(f0);
}
template <GTEST_2_TYPENAMES_(T)>
inline GTEST_2_TUPLE_(T) make_tuple(const T0& f0, const T1& f1) {
return GTEST_2_TUPLE_(T)(f0, f1);
}
template <GTEST_3_TYPENAMES_(T)>
inline GTEST_3_TUPLE_(T) make_tuple(const T0& f0, const T1& f1, const T2& f2) {
return GTEST_3_TUPLE_(T)(f0, f1, f2);
}
template <GTEST_4_TYPENAMES_(T)>
inline GTEST_4_TUPLE_(T) make_tuple(const T0& f0, const T1& f1, const T2& f2,
const T3& f3) {
return GTEST_4_TUPLE_(T)(f0, f1, f2, f3);
}
template <GTEST_5_TYPENAMES_(T)>
inline GTEST_5_TUPLE_(T) make_tuple(const T0& f0, const T1& f1, const T2& f2,
const T3& f3, const T4& f4) {
return GTEST_5_TUPLE_(T)(f0, f1, f2, f3, f4);
}
template <GTEST_6_TYPENAMES_(T)>
inline GTEST_6_TUPLE_(T) make_tuple(const T0& f0, const T1& f1, const T2& f2,
const T3& f3, const T4& f4, const T5& f5) {
return GTEST_6_TUPLE_(T)(f0, f1, f2, f3, f4, f5);
}
template <GTEST_7_TYPENAMES_(T)>
inline GTEST_7_TUPLE_(T) make_tuple(const T0& f0, const T1& f1, const T2& f2,
const T3& f3, const T4& f4, const T5& f5, const T6& f6) {
return GTEST_7_TUPLE_(T)(f0, f1, f2, f3, f4, f5, f6);
}
template <GTEST_8_TYPENAMES_(T)>
inline GTEST_8_TUPLE_(T) make_tuple(const T0& f0, const T1& f1, const T2& f2,
const T3& f3, const T4& f4, const T5& f5, const T6& f6, const T7& f7) {
return GTEST_8_TUPLE_(T)(f0, f1, f2, f3, f4, f5, f6, f7);
}
template <GTEST_9_TYPENAMES_(T)>
inline GTEST_9_TUPLE_(T) make_tuple(const T0& f0, const T1& f1, const T2& f2,
const T3& f3, const T4& f4, const T5& f5, const T6& f6, const T7& f7,
const T8& f8) {
return GTEST_9_TUPLE_(T)(f0, f1, f2, f3, f4, f5, f6, f7, f8);
}
template <GTEST_10_TYPENAMES_(T)>
inline GTEST_10_TUPLE_(T) make_tuple(const T0& f0, const T1& f1, const T2& f2,
const T3& f3, const T4& f4, const T5& f5, const T6& f6, const T7& f7,
const T8& f8, const T9& f9) {
return GTEST_10_TUPLE_(T)(f0, f1, f2, f3, f4, f5, f6, f7, f8, f9);
}
// 6.1.3.3 Tuple helper classes.
template <typename Tuple> struct tuple_size;
template <GTEST_0_TYPENAMES_(T)>
struct tuple_size<GTEST_0_TUPLE_(T)> { static const int value = 0; };
template <GTEST_1_TYPENAMES_(T)>
struct tuple_size<GTEST_1_TUPLE_(T)> { static const int value = 1; };
template <GTEST_2_TYPENAMES_(T)>
struct tuple_size<GTEST_2_TUPLE_(T)> { static const int value = 2; };
template <GTEST_3_TYPENAMES_(T)>
struct tuple_size<GTEST_3_TUPLE_(T)> { static const int value = 3; };
template <GTEST_4_TYPENAMES_(T)>
struct tuple_size<GTEST_4_TUPLE_(T)> { static const int value = 4; };
template <GTEST_5_TYPENAMES_(T)>
struct tuple_size<GTEST_5_TUPLE_(T)> { static const int value = 5; };
template <GTEST_6_TYPENAMES_(T)>
struct tuple_size<GTEST_6_TUPLE_(T)> { static const int value = 6; };
template <GTEST_7_TYPENAMES_(T)>
struct tuple_size<GTEST_7_TUPLE_(T)> { static const int value = 7; };
template <GTEST_8_TYPENAMES_(T)>
struct tuple_size<GTEST_8_TUPLE_(T)> { static const int value = 8; };
template <GTEST_9_TYPENAMES_(T)>
struct tuple_size<GTEST_9_TUPLE_(T)> { static const int value = 9; };
template <GTEST_10_TYPENAMES_(T)>
struct tuple_size<GTEST_10_TUPLE_(T)> { static const int value = 10; };
template <int k, class Tuple>
struct tuple_element {
typedef typename gtest_internal::TupleElement<
k < (tuple_size<Tuple>::value), k, Tuple>::type type;
};
#define GTEST_TUPLE_ELEMENT_(k, Tuple) typename tuple_element<k, Tuple >::type
// 6.1.3.4 Element access.
namespace gtest_internal {
template <>
class Get<0> {
public:
template <class Tuple>
static GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(0, Tuple))
Field(Tuple& t) { return t.f0_; } // NOLINT
template <class Tuple>
static GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(0, Tuple))
ConstField(const Tuple& t) { return t.f0_; }
};
template <>
class Get<1> {
public:
template <class Tuple>
static GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(1, Tuple))
Field(Tuple& t) { return t.f1_; } // NOLINT
template <class Tuple>
static GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(1, Tuple))
ConstField(const Tuple& t) { return t.f1_; }
};
template <>
class Get<2> {
public:
template <class Tuple>
static GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(2, Tuple))
Field(Tuple& t) { return t.f2_; } // NOLINT
template <class Tuple>
static GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(2, Tuple))
ConstField(const Tuple& t) { return t.f2_; }
};
template <>
class Get<3> {
public:
template <class Tuple>
static GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(3, Tuple))
Field(Tuple& t) { return t.f3_; } // NOLINT
template <class Tuple>
static GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(3, Tuple))
ConstField(const Tuple& t) { return t.f3_; }
};
template <>
class Get<4> {
public:
template <class Tuple>
static GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(4, Tuple))
Field(Tuple& t) { return t.f4_; } // NOLINT
template <class Tuple>
static GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(4, Tuple))
ConstField(const Tuple& t) { return t.f4_; }
};
template <>
class Get<5> {
public:
template <class Tuple>
static GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(5, Tuple))
Field(Tuple& t) { return t.f5_; } // NOLINT
template <class Tuple>
static GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(5, Tuple))
ConstField(const Tuple& t) { return t.f5_; }
};
template <>
class Get<6> {
public:
template <class Tuple>
static GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(6, Tuple))
Field(Tuple& t) { return t.f6_; } // NOLINT
template <class Tuple>
static GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(6, Tuple))
ConstField(const Tuple& t) { return t.f6_; }
};
template <>
class Get<7> {
public:
template <class Tuple>
static GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(7, Tuple))
Field(Tuple& t) { return t.f7_; } // NOLINT
template <class Tuple>
static GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(7, Tuple))
ConstField(const Tuple& t) { return t.f7_; }
};
template <>
class Get<8> {
public:
template <class Tuple>
static GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(8, Tuple))
Field(Tuple& t) { return t.f8_; } // NOLINT
template <class Tuple>
static GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(8, Tuple))
ConstField(const Tuple& t) { return t.f8_; }
};
template <>
class Get<9> {
public:
template <class Tuple>
static GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(9, Tuple))
Field(Tuple& t) { return t.f9_; } // NOLINT
template <class Tuple>
static GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(9, Tuple))
ConstField(const Tuple& t) { return t.f9_; }
};
} // namespace gtest_internal
template <int k, GTEST_10_TYPENAMES_(T)>
GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(k, GTEST_10_TUPLE_(T)))
get(GTEST_10_TUPLE_(T)& t) {
return gtest_internal::Get<k>::Field(t);
}
template <int k, GTEST_10_TYPENAMES_(T)>
GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(k, GTEST_10_TUPLE_(T)))
get(const GTEST_10_TUPLE_(T)& t) {
return gtest_internal::Get<k>::ConstField(t);
}
// 6.1.3.5 Relational operators
// We only implement == and !=, as we don't have a need for the rest yet.
namespace gtest_internal {
// SameSizeTuplePrefixComparator<k, k>::Eq(t1, t2) returns true if the
// first k fields of t1 equals the first k fields of t2.
// SameSizeTuplePrefixComparator(k1, k2) would be a compiler error if
// k1 != k2.
template <int kSize1, int kSize2>
struct SameSizeTuplePrefixComparator;
template <>
struct SameSizeTuplePrefixComparator<0, 0> {
template <class Tuple1, class Tuple2>
static bool Eq(const Tuple1& /* t1 */, const Tuple2& /* t2 */) {
return true;
}
};
template <int k>
struct SameSizeTuplePrefixComparator<k, k> {
template <class Tuple1, class Tuple2>
static bool Eq(const Tuple1& t1, const Tuple2& t2) {
return SameSizeTuplePrefixComparator<k - 1, k - 1>::Eq(t1, t2) &&
::std::tr1::get<k - 1>(t1) == ::std::tr1::get<k - 1>(t2);
}
};
} // namespace gtest_internal
template <GTEST_10_TYPENAMES_(T), GTEST_10_TYPENAMES_(U)>
inline bool operator==(const GTEST_10_TUPLE_(T)& t,
const GTEST_10_TUPLE_(U)& u) {
return gtest_internal::SameSizeTuplePrefixComparator<
tuple_size<GTEST_10_TUPLE_(T)>::value,
tuple_size<GTEST_10_TUPLE_(U)>::value>::Eq(t, u);
}
template <GTEST_10_TYPENAMES_(T), GTEST_10_TYPENAMES_(U)>
inline bool operator!=(const GTEST_10_TUPLE_(T)& t,
const GTEST_10_TUPLE_(U)& u) { return !(t == u); }
// 6.1.4 Pairs.
// Unimplemented.
} // namespace tr1
} // namespace std
#undef GTEST_0_TUPLE_
#undef GTEST_1_TUPLE_
#undef GTEST_2_TUPLE_
#undef GTEST_3_TUPLE_
#undef GTEST_4_TUPLE_
#undef GTEST_5_TUPLE_
#undef GTEST_6_TUPLE_
#undef GTEST_7_TUPLE_
#undef GTEST_8_TUPLE_
#undef GTEST_9_TUPLE_
#undef GTEST_10_TUPLE_
#undef GTEST_0_TYPENAMES_
#undef GTEST_1_TYPENAMES_
#undef GTEST_2_TYPENAMES_
#undef GTEST_3_TYPENAMES_
#undef GTEST_4_TYPENAMES_
#undef GTEST_5_TYPENAMES_
#undef GTEST_6_TYPENAMES_
#undef GTEST_7_TYPENAMES_
#undef GTEST_8_TYPENAMES_
#undef GTEST_9_TYPENAMES_
#undef GTEST_10_TYPENAMES_
#undef GTEST_BY_REF_
#undef GTEST_ADD_REF_
#undef GTEST_TUPLE_ELEMENT_
#endif // GTEST_INCLUDE_GTEST_INTERAL_GTEST_TUPLE_H_

View File

@ -0,0 +1,320 @@
$$ -*- mode: c++; -*-
$var n = 10 $$ Maximum number of tuple fields we want to support.
$$ This meta comment fixes auto-indentation in Emacs. }}
// Copyright 2009 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)
// Implements a subset of TR1 tuple needed by Google Test and Google Mock.
#ifndef GTEST_INCLUDE_GTEST_INTERAL_GTEST_TUPLE_H_
#define GTEST_INCLUDE_GTEST_INTERAL_GTEST_TUPLE_H_
#include <utility> // For ::std::pair.
$range i 0..n-1
$range j 0..n
$range k 1..n
// GTEST_n_TUPLE_(T) is the type of an n-tuple.
$for j [[
$range m 0..j-1
#define GTEST_$(j)_TUPLE_(T) tuple<$for m, [[T##$m]]>
]]
// GTEST_n_TYPENAMES_(T) declares a list of n typenames.
$for j [[
$range m 0..j-1
#define GTEST_$(j)_TYPENAMES_(T) $for m, [[typename T##$m]]
]]
// In theory, defining stuff in the ::std namespace is undefined
// behavior. We can do this as we are playing the role of a standard
// library vendor.
namespace std {
namespace tr1 {
template <$for i, [[typename T$i = void]]>
class tuple;
// Anything in namespace gtest_internal is Google Test's INTERNAL
// IMPLEMENTATION DETAIL and MUST NOT BE USED DIRECTLY in user code.
namespace gtest_internal {
// ByRef<T>::type is T if T is a reference; otherwise it's const T&.
template <typename T>
struct ByRef { typedef const T& type; }; // NOLINT
template <typename T>
struct ByRef<T&> { typedef T& type; }; // NOLINT
// A handy wrapper for ByRef.
#define GTEST_BY_REF_(T) typename ::std::tr1::gtest_internal::ByRef<T>::type
// AddRef<T>::type is T if T is a reference; otherwise it's T&. This
// is the same as tr1::add_reference<T>::type.
template <typename T>
struct AddRef { typedef T& type; }; // NOLINT
template <typename T>
struct AddRef<T&> { typedef T& type; }; // NOLINT
// A handy wrapper for AddRef.
#define GTEST_ADD_REF_(T) typename ::std::tr1::gtest_internal::AddRef<T>::type
// A helper for implementing get<k>().
template <int k> class Get;
// A helper for implementing tuple_element<k, T>. kIndexValid is true
// iff k < the number of fields in tuple type T.
template <bool kIndexValid, int kIndex, class Tuple>
struct TupleElement;
$for i [[
template <GTEST_$(n)_TYPENAMES_(T)>
struct TupleElement<true, $i, GTEST_$(n)_TUPLE_(T)> [[]]
{ typedef T$i type; };
]]
} // namespace gtest_internal
template <>
class tuple<> {
public:
tuple() {}
tuple(const tuple& /* t */) {}
tuple& operator=(const tuple& /* t */) { return *this; }
};
$for k [[
$range m 0..k-1
template <GTEST_$(k)_TYPENAMES_(T)>
class $if k < n [[GTEST_$(k)_TUPLE_(T)]] $else [[tuple]] {
public:
template <int k> friend class gtest_internal::Get;
template <GTEST_$(n)_TYPENAMES_(U)> friend class tuple;
tuple() {}
explicit tuple($for m, [[GTEST_BY_REF_(T$m) f$m]]) : [[]]
$for m, [[f$(m)_(f$m)]] {}
tuple(const tuple& t) : $for m, [[f$(m)_(t.f$(m)_)]] {}
template <GTEST_$(k)_TYPENAMES_(U)>
tuple(const GTEST_$(k)_TUPLE_(U)& t) : $for m, [[f$(m)_(t.f$(m)_)]] {}
$if k == 2 [[
template <typename U0, typename U1>
tuple(const ::std::pair<U0, U1>& p) : f0_(p.first), f1_(p.second) {}
]]
tuple& operator=(const tuple& t) { return CopyFrom(t); }
template <GTEST_$(k)_TYPENAMES_(U)>
tuple& operator=(const GTEST_$(k)_TUPLE_(U)& t) {
return CopyFrom(t);
}
$if k == 2 [[
template <typename U0, typename U1>
tuple& operator=(const ::std::pair<U0, U1>& p) {
f0_ = p.first;
f1_ = p.second;
return *this;
}
]]
private:
template <GTEST_$(k)_TYPENAMES_(U)>
tuple& CopyFrom(const GTEST_$(k)_TUPLE_(U)& t) {
$for m [[
f$(m)_ = t.f$(m)_;
]]
return *this;
}
$for m [[
T$m f$(m)_;
]]
};
]]
// 6.1.3.2 Tuple creation functions.
// Known limitations: we don't support passing an
// std::tr1::reference_wrapper<T> to make_tuple(). And we don't
// implement tie().
inline tuple<> make_tuple() { return tuple<>(); }
$for k [[
$range m 0..k-1
template <GTEST_$(k)_TYPENAMES_(T)>
inline GTEST_$(k)_TUPLE_(T) make_tuple($for m, [[const T$m& f$m]]) {
return GTEST_$(k)_TUPLE_(T)($for m, [[f$m]]);
}
]]
// 6.1.3.3 Tuple helper classes.
template <typename Tuple> struct tuple_size;
$for j [[
template <GTEST_$(j)_TYPENAMES_(T)>
struct tuple_size<GTEST_$(j)_TUPLE_(T)> { static const int value = $j; };
]]
template <int k, class Tuple>
struct tuple_element {
typedef typename gtest_internal::TupleElement<
k < (tuple_size<Tuple>::value), k, Tuple>::type type;
};
#define GTEST_TUPLE_ELEMENT_(k, Tuple) typename tuple_element<k, Tuple >::type
// 6.1.3.4 Element access.
namespace gtest_internal {
$for i [[
template <>
class Get<$i> {
public:
template <class Tuple>
static GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_($i, Tuple))
Field(Tuple& t) { return t.f$(i)_; } // NOLINT
template <class Tuple>
static GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_($i, Tuple))
ConstField(const Tuple& t) { return t.f$(i)_; }
};
]]
} // namespace gtest_internal
template <int k, GTEST_$(n)_TYPENAMES_(T)>
GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(k, GTEST_$(n)_TUPLE_(T)))
get(GTEST_$(n)_TUPLE_(T)& t) {
return gtest_internal::Get<k>::Field(t);
}
template <int k, GTEST_$(n)_TYPENAMES_(T)>
GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(k, GTEST_$(n)_TUPLE_(T)))
get(const GTEST_$(n)_TUPLE_(T)& t) {
return gtest_internal::Get<k>::ConstField(t);
}
// 6.1.3.5 Relational operators
// We only implement == and !=, as we don't have a need for the rest yet.
namespace gtest_internal {
// SameSizeTuplePrefixComparator<k, k>::Eq(t1, t2) returns true if the
// first k fields of t1 equals the first k fields of t2.
// SameSizeTuplePrefixComparator(k1, k2) would be a compiler error if
// k1 != k2.
template <int kSize1, int kSize2>
struct SameSizeTuplePrefixComparator;
template <>
struct SameSizeTuplePrefixComparator<0, 0> {
template <class Tuple1, class Tuple2>
static bool Eq(const Tuple1& /* t1 */, const Tuple2& /* t2 */) {
return true;
}
};
template <int k>
struct SameSizeTuplePrefixComparator<k, k> {
template <class Tuple1, class Tuple2>
static bool Eq(const Tuple1& t1, const Tuple2& t2) {
return SameSizeTuplePrefixComparator<k - 1, k - 1>::Eq(t1, t2) &&
::std::tr1::get<k - 1>(t1) == ::std::tr1::get<k - 1>(t2);
}
};
} // namespace gtest_internal
template <GTEST_$(n)_TYPENAMES_(T), GTEST_$(n)_TYPENAMES_(U)>
inline bool operator==(const GTEST_$(n)_TUPLE_(T)& t,
const GTEST_$(n)_TUPLE_(U)& u) {
return gtest_internal::SameSizeTuplePrefixComparator<
tuple_size<GTEST_$(n)_TUPLE_(T)>::value,
tuple_size<GTEST_$(n)_TUPLE_(U)>::value>::Eq(t, u);
}
template <GTEST_$(n)_TYPENAMES_(T), GTEST_$(n)_TYPENAMES_(U)>
inline bool operator!=(const GTEST_$(n)_TUPLE_(T)& t,
const GTEST_$(n)_TUPLE_(U)& u) { return !(t == u); }
// 6.1.4 Pairs.
// Unimplemented.
} // namespace tr1
} // namespace std
$for j [[
#undef GTEST_$(j)_TUPLE_
]]
$for j [[
#undef GTEST_$(j)_TYPENAMES_
]]
#undef GTEST_BY_REF_
#undef GTEST_ADD_REF_
#undef GTEST_TUPLE_ELEMENT_
#endif // GTEST_INCLUDE_GTEST_INTERAL_GTEST_TUPLE_H_

View File

@ -151,31 +151,30 @@ else:
GTEST_BUILD_DIR = 'GTEST_BUILD_DIR'
def ScriptDir():
"""Returns the directory containing this script file."""
my_path = sys.argv[0]
my_dir = os.path.dirname(my_path)
if not my_dir or __name__ != '__main__':
my_dir = '.'
return my_dir
MY_DIR = ScriptDir()
def GetBuildDirForConfig(config):
"""Returns the build directory for a given configuration."""
return 'scons/build/%s/scons' % config
# All paths in this script are either absolute or relative to the current
# working directory, unless otherwise specified.
class TestRunner(object):
"""Provides facilities for running Python and binary tests for Google Test."""
def __init__(self, injected_os=os, injected_subprocess=subprocess):
def __init__(self,
injected_os=os,
injected_subprocess=subprocess,
injected_script_dir=os.path.dirname(__file__)):
self.os = injected_os
self.subprocess = injected_subprocess
# If a program using this file is invoked via a relative path, the
# script directory will be relative to the path of the main program
# file. It may be '.' when this script is invoked directly or '..' when
# it is imported for testing. To simplify testing we inject the script
# directory into TestRunner.
self.script_dir = injected_script_dir
def GetBuildDirForConfig(self, config):
"""Returns the build directory for a given configuration."""
return self.os.path.normpath(
self.os.path.join(self.script_dir, 'scons/build/%s/scons' % config))
def Run(self, args):
"""Runs the executable with given args (args[0] is the executable name).
@ -194,23 +193,23 @@ class TestRunner(object):
return self.os.spawnv(self.os.P_WAIT, args[0], args)
def RunBinaryTest(self, test):
"""Runs the binary test script given its path relative to the gtest root.
"""Runs the binary test given its path.
Args:
test: Path to the test binary relative to the location of this script.
test: Path to the test binary.
Returns:
Process's exit code if it exits normally, or -signal if the process is
killed by a signal.
"""
return self.Run([self.os.path.abspath(self.os.path.join(MY_DIR, test))])
return self.Run([test])
def RunPythonTest(self, test, build_dir):
"""Runs the Python test script with the specified build directory.
Args:
test: Name of the test's Python script.
test: Path to the test's Python script.
build_dir: Path to the directory where the test binary is to be found.
Returns:
@ -226,9 +225,8 @@ class TestRunner(object):
# If this script is run on a Windows machine that has no association
# between the .py extension and a python interpreter, simply passing
# the script name into subprocess.Popen/os.spawn will not work.
script = self.os.path.join(MY_DIR, test)
print 'Running %s . . .' % (script,)
return self.Run([sys.executable, script])
print 'Running %s . . .' % (test,)
return self.Run([sys.executable, test])
finally:
if old_build_dir is None:
@ -277,28 +275,29 @@ class TestRunner(object):
if named_configurations == 'all':
named_configurations = ','.join(available_configurations)
normalized_args = [self.os.path.normpath(arg) for arg in args]
# A final list of build directories which will be searched for the test
# binaries. First, add directories specified directly on the command
# line.
build_dirs = [arg for arg in args if self.os.path.isdir(arg)]
build_dirs = filter(self.os.path.isdir, normalized_args)
# Adds build directories specified via their build configurations using
# the -c or -a options.
if named_configurations:
build_dirs += [GetBuildDirForConfig(config)
build_dirs += [self.GetBuildDirForConfig(config)
for config in named_configurations.split(',')]
# Adds KNOWN BUILD DIRECTORIES if -b is specified.
if built_configurations:
build_dirs += [GetBuildDirForConfig(config)
build_dirs += [self.GetBuildDirForConfig(config)
for config in available_configurations
if self.os.path.isdir(GetBuildDirForConfig(config))]
if self.os.path.isdir(self.GetBuildDirForConfig(config))]
# If no directories were specified either via -a, -b, -c, or directly, use
# the default configuration.
elif not build_dirs:
build_dirs = [GetBuildDirForConfig(config)
for config in available_configurations[0:1]]
build_dirs = [self.GetBuildDirForConfig(available_configurations[0])]
# Makes sure there are no duplications.
build_dirs = sets.Set(build_dirs)
@ -309,10 +308,12 @@ class TestRunner(object):
# Sifts through non-directory arguments fishing for any Python or binary
# tests and detecting errors.
for argument in sets.Set(args) - build_dirs:
for argument in sets.Set(normalized_args) - build_dirs:
if re.search(PYTHON_TEST_REGEX, argument):
python_path = self.os.path.join('test', self.os.path.basename(argument))
if self.os.path.isfile(self.os.path.join(MY_DIR, python_path)):
python_path = self.os.path.join(self.script_dir,
'test',
self.os.path.basename(argument))
if self.os.path.isfile(python_path):
listed_python_tests.append(python_path)
else:
sys.stderr.write('Unable to find Python test %s' % argument)
@ -334,7 +335,9 @@ class TestRunner(object):
if user_has_listed_tests:
selected_python_tests = listed_python_tests
else:
selected_python_tests = self.FindFilesByRegex('test', PYTHON_TEST_REGEX)
selected_python_tests = self.FindFilesByRegex(
self.os.path.join(self.script_dir, 'test'),
PYTHON_TEST_REGEX)
# TODO(vladl@google.com): skip unbuilt Python tests when -b is specified.
python_test_pairs = []
@ -355,7 +358,7 @@ class TestRunner(object):
return (python_test_pairs, binary_test_pairs)
def RunTests(self, python_tests, binary_tests):
"""Runs Python and binary tests represented as pairs (work_dir, binary).
"""Runs Python and binary tests and reports results to the standard output.
Args:
python_tests: List of Python tests to run in the form of tuples

View File

@ -125,6 +125,11 @@ if env_with_exceptions['PLATFORM'] == 'win32':
cppdefines = env_with_exceptions['CPPDEFINES']
if '_TYPEINFO_' in cppdefines:
cppdefines.remove('_TYPEINFO_')
else:
env_with_exceptions.Append(CCFLAGS='-fexceptions')
ccflags = env_with_exceptions['CCFLAGS']
if '-fno-exceptions' in ccflags:
ccflags.remove('-fno-exceptions')
env_without_rtti = env.Clone()
if env_without_rtti['PLATFORM'] == 'win32':
@ -133,6 +138,9 @@ else:
env_without_rtti.Append(CCFLAGS = ['-fno-rtti'])
env_without_rtti.Append(CPPDEFINES = 'GTEST_HAS_RTTI=0')
env_use_own_tuple = env.Clone()
env_use_own_tuple.Append(CPPDEFINES = 'GTEST_USE_OWN_TR1_TUPLE=1')
gtest_ex_obj = env_with_exceptions.Object(target='gtest_ex',
source=gtest_source)
gtest_main_ex_obj = env_with_exceptions.Object(target='gtest_main_ex',
@ -258,6 +266,37 @@ GtestBinary(env_without_rtti,
gtest_all_no_rtti_obj +
gtest_main_no_rtti_obj)
# Builds a test for gtest's own TR1 tuple implementation.
gtest_all_use_own_tuple_obj = env_use_own_tuple.Object(
target='gtest_all_use_own_tuple',
source='../src/gtest-all.cc')
gtest_main_use_own_tuple_obj = env_use_own_tuple.Object(
target='gtest_main_use_own_tuple',
source='../src/gtest_main.cc')
GtestBinary(env_use_own_tuple,
'gtest-tuple_test',
[],
['../test/gtest-tuple_test.cc',
gtest_all_use_own_tuple_obj,
gtest_main_use_own_tuple_obj])
# Builds a test for gtest features that use tuple.
gtest_param_test_test_use_own_tuple_obj = env_use_own_tuple.Object(
target='gtest_param_test_test_use_own_tuple',
source='../test/gtest-param-test_test.cc')
gtest_param_test2_test_use_own_tuple_obj = env_use_own_tuple.Object(
target='gtest_param_test2_test_use_own_tuple',
source='../test/gtest-param-test2_test.cc')
GtestBinary(env_use_own_tuple,
'gtest_use_own_tuple_test',
[],
gtest_param_test_test_use_own_tuple_obj +
gtest_param_test2_test_use_own_tuple_obj +
gtest_all_use_own_tuple_obj)
# TODO(wan@google.com): simplify the definition of build targets that
# use alternative environments.
# We need to disable some optimization flags for some tests on
# Windows; otherwise the redirection of stdout does not work
# (apparently because of a compiler bug).

288
test/gtest-tuple_test.cc Normal file
View File

@ -0,0 +1,288 @@
// Copyright 2007, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// Author: wan@google.com (Zhanyong Wan)
#include <gtest/internal/gtest-tuple.h>
#include <utility>
#include <gtest/gtest.h>
namespace {
using ::std::tr1::get;
using ::std::tr1::make_tuple;
using ::std::tr1::tuple;
using ::std::tr1::tuple_element;
using ::std::tr1::tuple_size;
using ::testing::StaticAssertTypeEq;
// Tests that tuple_element<K, tuple<T0, T1, ..., TN> >::type returns TK.
TEST(tuple_element_Test, ReturnsElementType) {
StaticAssertTypeEq<int, tuple_element<0, tuple<int, char> >::type>();
StaticAssertTypeEq<int&, tuple_element<1, tuple<double, int&> >::type>();
StaticAssertTypeEq<bool, tuple_element<2, tuple<double, int, bool> >::type>();
}
// Tests that tuple_size<T>::value gives the number of fields in tuple
// type T.
TEST(tuple_size_Test, ReturnsNumberOfFields) {
EXPECT_EQ(0, +tuple_size<tuple<> >::value);
EXPECT_EQ(1, +tuple_size<tuple<void*> >::value);
EXPECT_EQ(1, +tuple_size<tuple<char> >::value);
EXPECT_EQ(1, +(tuple_size<tuple<tuple<int, double> > >::value));
EXPECT_EQ(2, +(tuple_size<tuple<int&, const char> >::value));
EXPECT_EQ(3, +(tuple_size<tuple<char*, void, const bool&> >::value));
}
// Tests comparing a tuple with itself.
TEST(ComparisonTest, ComparesWithSelf) {
const tuple<int, char, bool> a(5, 'a', false);
EXPECT_TRUE(a == a);
EXPECT_FALSE(a != a);
}
// Tests comparing two tuples with the same value.
TEST(ComparisonTest, ComparesEqualTuples) {
const tuple<int, bool> a(5, true), b(5, true);
EXPECT_TRUE(a == b);
EXPECT_FALSE(a != b);
}
// Tests comparing two different tuples that have no reference fields.
TEST(ComparisonTest, ComparesUnequalTuplesWithoutReferenceFields) {
typedef tuple<const int, char> FooTuple;
const FooTuple a(0, 'x');
const FooTuple b(1, 'a');
EXPECT_TRUE(a != b);
EXPECT_FALSE(a == b);
const FooTuple c(1, 'b');
EXPECT_TRUE(b != c);
EXPECT_FALSE(b == c);
}
// Tests comparing two different tuples that have reference fields.
TEST(ComparisonTest, ComparesUnequalTuplesWithReferenceFields) {
typedef tuple<int&, const char&> FooTuple;
int i = 5;
const char ch = 'a';
const FooTuple a(i, ch);
int j = 6;
const FooTuple b(j, ch);
EXPECT_TRUE(a != b);
EXPECT_FALSE(a == b);
j = 5;
const char ch2 = 'b';
const FooTuple c(j, ch2);
EXPECT_TRUE(b != c);
EXPECT_FALSE(b == c);
}
// Tests that a tuple field with a reference type is an alias of the
// variable it's supposed to reference.
TEST(ReferenceFieldTest, IsAliasOfReferencedVariable) {
int n = 0;
tuple<bool, int&> t(true, n);
n = 1;
EXPECT_EQ(n, get<1>(t))
<< "Changing a underlying variable should update the reference field.";
// Makes sure that the implementation doesn't do anything funny with
// the & operator for the return type of get<>().
EXPECT_EQ(&n, &(get<1>(t)))
<< "The address of a reference field should equal the address of "
<< "the underlying variable.";
get<1>(t) = 2;
EXPECT_EQ(2, n)
<< "Changing a reference field should update the underlying variable.";
}
// Tests tuple's default constructor.
TEST(TupleConstructorTest, DefaultConstructor) {
// We are just testing that the following compiles.
tuple<> empty;
tuple<int> one_field;
tuple<double, char, bool*> three_fields;
}
// Tests constructing a tuple from its fields.
TEST(TupleConstructorTest, ConstructsFromFields) {
int n = 1;
// Reference field.
tuple<int&> a(n);
EXPECT_EQ(&n, &(get<0>(a)));
// Non-reference fields.
tuple<int, char> b(5, 'a');
EXPECT_EQ(5, get<0>(b));
EXPECT_EQ('a', get<1>(b));
// Const reference field.
const int m = 2;
tuple<bool, const int&> c(true, m);
EXPECT_TRUE(get<0>(c));
EXPECT_EQ(&m, &(get<1>(c)));
}
// Tests tuple's copy constructor.
TEST(TupleConstructorTest, CopyConstructor) {
tuple<double, bool> a(0.0, true);
tuple<double, bool> b(a);
EXPECT_DOUBLE_EQ(0.0, get<0>(b));
EXPECT_TRUE(get<1>(b));
}
// Tests constructing a tuple from another tuple that has a compatible
// but different type.
TEST(TupleConstructorTest, ConstructsFromDifferentTupleType) {
tuple<int, int, char> a(0, 1, 'a');
tuple<double, long, int> b(a);
EXPECT_DOUBLE_EQ(0.0, get<0>(b));
EXPECT_EQ(1, get<1>(b));
EXPECT_EQ('a', get<2>(b));
}
// Tests constructing a 2-tuple from an std::pair.
TEST(TupleConstructorTest, ConstructsFromPair) {
::std::pair<int, char> a(1, 'a');
tuple<int, char> b(a);
tuple<int, const char&> c(a);
}
// Tests assigning a tuple to another tuple with the same type.
TEST(TupleAssignmentTest, AssignsToSameTupleType) {
const tuple<int, long> a(5, 7L);
tuple<int, long> b;
b = a;
EXPECT_EQ(5, get<0>(b));
EXPECT_EQ(7L, get<1>(b));
}
// Tests assigning a tuple to another tuple with a different but
// compatible type.
TEST(TupleAssignmentTest, AssignsToDifferentTupleType) {
const tuple<int, long, bool> a(1, 7L, true);
tuple<long, int, bool> b;
b = a;
EXPECT_EQ(1L, get<0>(b));
EXPECT_EQ(7, get<1>(b));
EXPECT_TRUE(get<2>(b));
}
// Tests assigning an std::pair to a 2-tuple.
TEST(TupleAssignmentTest, AssignsFromPair) {
const ::std::pair<int, bool> a(5, true);
tuple<int, bool> b;
b = a;
EXPECT_EQ(5, get<0>(b));
EXPECT_TRUE(get<1>(b));
tuple<long, bool> c;
c = a;
EXPECT_EQ(5L, get<0>(c));
EXPECT_TRUE(get<1>(c));
}
// A fixture for testing big tuples.
class BigTupleTest : public testing::Test {
protected:
typedef tuple<int, int, int, int, int, int, int, int, int, int> BigTuple;
BigTupleTest() :
a_(1, 0, 0, 0, 0, 0, 0, 0, 0, 2),
b_(1, 0, 0, 0, 0, 0, 0, 0, 0, 3) {}
BigTuple a_, b_;
};
// Tests constructing big tuples.
TEST_F(BigTupleTest, Construction) {
BigTuple a;
BigTuple b(b_);
}
// Tests that get<N>(t) returns the N-th (0-based) field of tuple t.
TEST_F(BigTupleTest, get) {
EXPECT_EQ(1, get<0>(a_));
EXPECT_EQ(2, get<9>(a_));
// Tests that get() works on a const tuple too.
const BigTuple a(a_);
EXPECT_EQ(1, get<0>(a));
EXPECT_EQ(2, get<9>(a));
}
// Tests comparing big tuples.
TEST_F(BigTupleTest, Comparisons) {
EXPECT_TRUE(a_ == a_);
EXPECT_FALSE(a_ != a_);
EXPECT_TRUE(a_ != b_);
EXPECT_FALSE(a_ == b_);
}
TEST(MakeTupleTest, WorksForScalarTypes) {
tuple<bool, int> a;
a = make_tuple(true, 5);
EXPECT_TRUE(get<0>(a));
EXPECT_EQ(5, get<1>(a));
tuple<char, int, long> b;
b = make_tuple('a', 'b', 5);
EXPECT_EQ('a', get<0>(b));
EXPECT_EQ('b', get<1>(b));
EXPECT_EQ(5, get<2>(b));
}
TEST(MakeTupleTest, WorksForPointers) {
int a[] = { 1, 2, 3, 4 };
const char* const str = "hi";
int* const p = a;
tuple<const char*, int*> t;
t = make_tuple(str, p);
EXPECT_EQ(str, get<0>(t));
EXPECT_EQ(p, get<1>(t));
}
} // namespace

View File

@ -43,7 +43,6 @@ __author__ = 'wan@google.com (Zhanyong Wan)'
import gtest_test_utils
import os
import sys
import unittest
# Constants.
@ -94,7 +93,7 @@ def Run(command):
# The tests.
class GTestBreakOnFailureUnitTest(unittest.TestCase):
class GTestBreakOnFailureUnitTest(gtest_test_utils.TestCase):
"""Tests using the GTEST_BREAK_ON_FAILURE environment variable or
the --gtest_break_on_failure flag to turn assertion failures into
segmentation faults.

View File

@ -33,10 +33,9 @@
__author__ = 'wan@google.com (Zhanyong Wan)'
import gtest_test_utils
import os
import sys
import unittest
import gtest_test_utils
IS_WINDOWS = os.name = 'nt'
@ -65,7 +64,7 @@ def UsesColor(term, color_env_var, color_flag):
return gtest_test_utils.GetExitStatus(os.system(cmd))
class GTestColorTest(unittest.TestCase):
class GTestColorTest(gtest_test_utils.TestCase):
def testNoEnvVarNoFlag(self):
"""Tests the case when there's neither GTEST_COLOR nor --gtest_color."""

View File

@ -33,13 +33,12 @@
__author__ = 'wan@google.com (Zhanyong Wan)'
import gtest_test_utils
import os
import sys
import unittest
import gtest_test_utils
IS_WINDOWS = os.name == 'nt'
IS_LINUX = os.name == 'posix'
IS_LINUX = os.name == 'posix' and os.uname()[0] == 'Linux'
COMMAND = gtest_test_utils.GetTestExecutablePath('gtest_env_var_test_')
@ -97,12 +96,13 @@ def TestEnvVarAffectsFlag(command):
if IS_WINDOWS:
TestFlag(command, 'catch_exceptions', '1', '0')
if IS_LINUX:
TestFlag(command, 'stack_trace_depth', '0', '100')
TestFlag(command, 'death_test_use_fork', '1', '0')
TestFlag(command, 'stack_trace_depth', '0', '100')
class GTestEnvVarTest(unittest.TestCase):
class GTestEnvVarTest(gtest_test_utils.TestCase):
def testEnvVarAffectsFlag(self):
TestEnvVarAffectsFlag(COMMAND)

View File

@ -1,7 +1,6 @@
#!/usr/bin/env python
#
# Copyright 2005, Google Inc.
# All rights reserved.
# Copyright 2005 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
@ -46,8 +45,6 @@ __author__ = 'wan@google.com (Zhanyong Wan)'
import os
import re
import sets
import tempfile
import unittest
import gtest_test_utils
# Constants.
@ -133,9 +130,7 @@ def SetEnvVar(env_var, value):
def Run(command):
"""Runs a Google Test program and returns a list of full names of the
tests that were run along with the test exit code.
"""
"""Runs a test program and returns its exit code and a list of tests run."""
stdout_file = os.popen(command, 'r')
tests_run = []
@ -169,9 +164,7 @@ def InvokeWithModifiedEnv(extra_env, function, *args, **kwargs):
def RunWithSharding(total_shards, shard_index, command):
"""Runs the Google Test program shard and returns a list of full names of the
tests that were run along with the exit code.
"""
"""Runs a test program shard and returns exit code and a list of tests run."""
extra_env = {SHARD_INDEX_ENV_VAR: str(shard_index),
TOTAL_SHARDS_ENV_VAR: str(total_shards)}
@ -180,10 +173,8 @@ def RunWithSharding(total_shards, shard_index, command):
# The unit test.
class GTestFilterUnitTest(unittest.TestCase):
"""Tests using the GTEST_FILTER environment variable or the
--gtest_filter flag to filter tests.
"""
class GTestFilterUnitTest(gtest_test_utils.TestCase):
"""Tests GTEST_FILTER env variable or --gtest_filter flag to filter tests."""
# Utilities.
@ -206,9 +197,8 @@ class GTestFilterUnitTest(unittest.TestCase):
self.assertEqual(sets.Set(set_var), sets.Set(full_partition))
def AdjustForParameterizedTests(self, tests_to_run):
"""Adjust tests_to_run in case value parameterized tests are disabled
in the binary.
"""
"""Adjust tests_to_run in case value parameterized tests are disabled."""
global param_tests_present
if not param_tests_present:
return list(sets.Set(tests_to_run) - sets.Set(PARAM_TESTS))
@ -216,9 +206,8 @@ class GTestFilterUnitTest(unittest.TestCase):
return tests_to_run
def RunAndVerify(self, gtest_filter, tests_to_run):
"""Runs gtest_flag_unittest_ with the given filter, and verifies
that the right set of tests were run.
"""
"""Checks that the binary runs correct set of tests for the given filter."""
tests_to_run = self.AdjustForParameterizedTests(tests_to_run)
# First, tests using GTEST_FILTER.
@ -248,11 +237,21 @@ class GTestFilterUnitTest(unittest.TestCase):
def RunAndVerifyWithSharding(self, gtest_filter, total_shards, tests_to_run,
command=COMMAND, check_exit_0=False):
"""Runs all shards of gtest_flag_unittest_ with the given filter, and
"""Checks that binary runs correct tests for the given filter and shard.
Runs all shards of gtest_filter_unittest_ with the given filter, and
verifies that the right set of tests were run. The union of tests run
on each shard should be identical to tests_to_run, without duplicates.
If check_exit_0, make sure that all shards returned 0.
Args:
gtest_filter: A filter to apply to the tests.
total_shards: A total number of shards to split test run into.
tests_to_run: A set of tests expected to run.
command: A command to invoke the test binary.
check_exit_0: When set to a true value, make sure that all shards
return 0.
"""
tests_to_run = self.AdjustForParameterizedTests(tests_to_run)
# Windows removes empty variables from the environment when passing it
@ -275,9 +274,16 @@ class GTestFilterUnitTest(unittest.TestCase):
# pylint: enable-msg=C6403
def RunAndVerifyAllowingDisabled(self, gtest_filter, tests_to_run):
"""Runs gtest_flag_unittest_ with the given filter, and enables
"""Checks that the binary runs correct set of tests for the given filter.
Runs gtest_filter_unittest_ with the given filter, and enables
disabled tests. Verifies that the right set of tests were run.
Args:
gtest_filter: A filter to apply to the tests.
tests_to_run: A set of tests expected to run.
"""
tests_to_run = self.AdjustForParameterizedTests(tests_to_run)
# Construct the command line.
@ -294,6 +300,7 @@ class GTestFilterUnitTest(unittest.TestCase):
Determines whether value-parameterized tests are enabled in the binary and
sets the flags accordingly.
"""
global param_tests_present
if param_tests_present is None:
param_tests_present = PARAM_TEST_REGEX.search(
@ -305,9 +312,8 @@ class GTestFilterUnitTest(unittest.TestCase):
self.RunAndVerify(None, ACTIVE_TESTS)
def testDefaultBehaviorWithShards(self):
"""Tests the behavior of not specifying the filter, with sharding
enabled.
"""
"""Tests the behavior without the filter, with sharding enabled."""
self.RunAndVerifyWithSharding(None, 1, ACTIVE_TESTS)
self.RunAndVerifyWithSharding(None, 2, ACTIVE_TESTS)
self.RunAndVerifyWithSharding(None, len(ACTIVE_TESTS) - 1, ACTIVE_TESTS)
@ -520,9 +526,7 @@ class GTestFilterUnitTest(unittest.TestCase):
])
def testFlagOverridesEnvVar(self):
"""Tests that the --gtest_filter flag overrides the GTEST_FILTER
environment variable.
"""
"""Tests that the filter flag overrides the filtering env. variable."""
SetEnvVar(FILTER_ENV_VAR, 'Foo*')
command = '%s --%s=%s' % (COMMAND, FILTER_FLAG, '*One')
@ -534,8 +538,8 @@ class GTestFilterUnitTest(unittest.TestCase):
def testShardStatusFileIsCreated(self):
"""Tests that the shard file is created if specified in the environment."""
test_tmpdir = tempfile.mkdtemp()
shard_status_file = os.path.join(test_tmpdir, 'shard_status_file')
shard_status_file = os.path.join(gtest_test_utils.GetTempDir(),
'shard_status_file')
self.assert_(not os.path.exists(shard_status_file))
extra_env = {SHARD_STATUS_FILE_ENV_VAR: shard_status_file}
@ -546,13 +550,12 @@ class GTestFilterUnitTest(unittest.TestCase):
stdout_file.close()
self.assert_(os.path.exists(shard_status_file))
os.remove(shard_status_file)
os.removedirs(test_tmpdir)
def testShardStatusFileIsCreatedWithListTests(self):
"""Tests that the shard file is created with --gtest_list_tests."""
test_tmpdir = tempfile.mkdtemp()
shard_status_file = os.path.join(test_tmpdir, 'shard_status_file2')
shard_status_file = os.path.join(gtest_test_utils.GetTempDir(),
'shard_status_file2')
self.assert_(not os.path.exists(shard_status_file))
extra_env = {SHARD_STATUS_FILE_ENV_VAR: shard_status_file}
@ -564,7 +567,6 @@ class GTestFilterUnitTest(unittest.TestCase):
stdout_file.close()
self.assert_(os.path.exists(shard_status_file))
os.remove(shard_status_file)
os.removedirs(test_tmpdir)
def testShardingWorksWithDeathTests(self):
"""Tests integration with death tests and sharding."""

View File

@ -39,10 +39,9 @@ SYNOPSIS
__author__ = 'wan@google.com (Zhanyong Wan)'
import gtest_test_utils
import os
import re
import unittest
import gtest_test_utils
IS_WINDOWS = os.name == 'nt'
@ -83,7 +82,7 @@ def RunWithFlag(flag):
return child.exit_code, child.output
class GTestHelpTest(unittest.TestCase):
class GTestHelpTest(gtest_test_utils.TestCase):
"""Tests the --help flag and its equivalent forms."""
def TestHelpFlag(self, flag):

View File

@ -39,11 +39,8 @@ Google Test) the command line flags.
__author__ = 'phanna@google.com (Patrick Hanna)'
import gtest_test_utils
import os
import re
import sys
import unittest
import gtest_test_utils
# Constants.
@ -105,7 +102,7 @@ def Run(command):
# The unit test.
class GTestListTestsUnitTest(unittest.TestCase):
class GTestListTestsUnitTest(gtest_test_utils.TestCase):
"""Tests using the --gtest_list_tests flag to list all tests."""
def RunAndVerify(self, flag_value, expected_output, other_flag):

View File

@ -38,6 +38,11 @@ import sys
import unittest
IS_LINUX = os.name == 'posix' and os.uname()[0] == 'Linux'
if not IS_LINUX:
sys.exit(0) # Negative compilation tests are not supported on Windows & Mac.
class GTestNCTest(unittest.TestCase):
"""Negative compilation test for Google Test."""

View File

@ -44,7 +44,6 @@ import os
import re
import string
import sys
import unittest
import gtest_test_utils
@ -84,11 +83,11 @@ def ToUnixLineEnding(s):
return s.replace('\r\n', '\n').replace('\r', '\n')
def RemoveLocations(output):
def RemoveLocations(test_output):
"""Removes all file location info from a Google Test program's output.
Args:
output: the output of a Google Test program.
test_output: the output of a Google Test program.
Returns:
output with all file location info (in the form of
@ -97,10 +96,10 @@ def RemoveLocations(output):
'FILE_NAME:#: '.
"""
return re.sub(r'.*[/\\](.+)(\:\d+|\(\d+\))\: ', r'\1:#: ', output)
return re.sub(r'.*[/\\](.+)(\:\d+|\(\d+\))\: ', r'\1:#: ', test_output)
def RemoveStackTraces(output):
def RemoveStackTraceDetails(output):
"""Removes all stack traces from a Google Test program's output."""
# *? means "find the shortest string that matches".
@ -108,6 +107,13 @@ def RemoveStackTraces(output):
'Stack trace: (omitted)\n\n', output)
def RemoveStackTraces(output):
"""Removes all traces of stack traces from a Google Test program's output."""
# *? means "find the shortest string that matches".
return re.sub(r'Stack trace:(.|\n)*?\n\n', '', output)
def RemoveTime(output):
"""Removes all time information from a Google Test program's output."""
@ -123,25 +129,28 @@ def RemoveTestCounts(output):
'? FAILED TESTS', output)
output = re.sub(r'\d+ tests from \d+ test cases',
'? tests from ? test cases', output)
output = re.sub(r'\d+ tests from ([a-zA-Z_])',
r'? tests from \1', output)
return re.sub(r'\d+ tests\.', '? tests.', output)
def RemoveMatchingTests(test_output, pattern):
"""Removes typed test information from a Google Test program's output.
"""Removes output of specified tests from a Google Test program's output.
This function strips not only the beginning and the end of a test but also all
output in between.
This function strips not only the beginning and the end of a test but also
all output in between.
Args:
test_output: A string containing the test output.
pattern: A string that matches names of test cases to remove.
pattern: A regex string that matches names of test cases or
tests to remove.
Returns:
Contents of test_output with removed test case whose names match pattern.
Contents of test_output with tests whose names match pattern removed.
"""
test_output = re.sub(
r'\[ RUN \] .*%s(.|\n)*?\[( FAILED | OK )\] .*%s.*\n' % (
r'.*\[ RUN \] .*%s(.|\n)*?\[( FAILED | OK )\] .*%s.*\n' % (
pattern, pattern),
'',
test_output)
@ -153,7 +162,7 @@ def NormalizeOutput(output):
output = ToUnixLineEnding(output)
output = RemoveLocations(output)
output = RemoveStackTraces(output)
output = RemoveStackTraceDetails(output)
output = RemoveTime(output)
return output
@ -241,14 +250,28 @@ def GetOutputOfAllCommands():
test_list = GetShellCommandOutput(COMMAND_LIST_TESTS, '')
SUPPORTS_DEATH_TESTS = 'DeathTest' in test_list
SUPPORTS_TYPED_TESTS = 'TypedTest' in test_list
SUPPORTS_THREADS = 'ExpectFailureWithThreadsTest' in test_list
SUPPORTS_STACK_TRACES = False
CAN_GENERATE_GOLDEN_FILE = SUPPORTS_DEATH_TESTS and SUPPORTS_TYPED_TESTS
class GTestOutputTest(unittest.TestCase):
class GTestOutputTest(gtest_test_utils.TestCase):
def RemoveUnsupportedTests(self, test_output):
if not SUPPORTS_DEATH_TESTS:
test_output = RemoveMatchingTests(test_output, 'DeathTest')
if not SUPPORTS_TYPED_TESTS:
test_output = RemoveMatchingTests(test_output, 'TypedTest')
if not SUPPORTS_THREADS:
test_output = RemoveMatchingTests(test_output,
'ExpectFailureWithThreadsTest')
test_output = RemoveMatchingTests(test_output,
'ScopedFakeTestPartResultReporterTest')
test_output = RemoveMatchingTests(test_output,
'WorksConcurrently')
if not SUPPORTS_STACK_TRACES:
test_output = RemoveStackTraces(test_output)
return test_output
def testOutput(self):
@ -262,26 +285,48 @@ class GTestOutputTest(unittest.TestCase):
golden = ToUnixLineEnding(golden_file.read())
golden_file.close()
# We want the test to pass regardless of death tests being
# We want the test to pass regardless of certain features being
# supported or not.
if SUPPORTS_DEATH_TESTS and SUPPORTS_TYPED_TESTS:
if CAN_GENERATE_GOLDEN_FILE:
self.assert_(golden == output)
else:
self.assert_(RemoveTestCounts(self.RemoveUnsupportedTests(golden)) ==
RemoveTestCounts(output))
normalized_actual = RemoveTestCounts(output)
normalized_golden = RemoveTestCounts(self.RemoveUnsupportedTests(golden))
# This code is very handy when debugging test differences so I left it
# here, commented.
# open(os.path.join(
# gtest_test_utils.GetSourceDir(),
# '_gtest_output_test_normalized_actual.txt'), 'wb').write(
# normalized_actual)
# open(os.path.join(
# gtest_test_utils.GetSourceDir(),
# '_gtest_output_test_normalized_golden.txt'), 'wb').write(
# normalized_golden)
self.assert_(normalized_golden == normalized_actual)
if __name__ == '__main__':
if sys.argv[1:] == [GENGOLDEN_FLAG]:
if SUPPORTS_DEATH_TESTS and SUPPORTS_TYPED_TESTS:
if CAN_GENERATE_GOLDEN_FILE:
output = GetOutputOfAllCommands()
golden_file = open(GOLDEN_PATH, 'wb')
golden_file.write(output)
golden_file.close()
else:
print >> sys.stderr, ('Unable to write a golden file when compiled in an '
'environment that does not support death tests and '
'typed tests. Are you using VC 7.1?')
message = (
"""Unable to write a golden file when compiled in an environment
that does not support all the required features (death tests""")
if IS_WINDOWS:
message += (
"""\nand typed tests). Please check that you are using VC++ 8.0 SP1
or higher as your compiler.""")
else:
message += """\nand typed tests). Please generate the golden file
using a binary built with those features enabled."""
sys.stderr.write(message)
sys.exit(1)
else:
gtest_test_utils.Main()

View File

@ -33,19 +33,32 @@
__author__ = 'wan@google.com (Zhanyong Wan)'
import atexit
import os
import shutil
import sys
import tempfile
import unittest
_test_module = unittest
# Suppresses the 'Import not at the top of the file' lint complaint.
# pylint: disable-msg=C6204
try:
import subprocess
_SUBPROCESS_MODULE_AVAILABLE = True
except:
import popen2
_SUBPROCESS_MODULE_AVAILABLE = False
# pylint: enable-msg=C6204
IS_WINDOWS = os.name == 'nt'
# Here we expose a class from a particular module, depending on the
# environment. The comment suppresses the 'Invalid variable name' lint
# complaint.
TestCase = _test_module.TestCase # pylint: disable-msg=C6409
# Initially maps a flag to its default value. After
# _ParseAndStripGTestFlags() is called, maps a flag to its actual value.
_flag_map = {'gtest_source_dir': os.path.dirname(sys.argv[0]),
@ -56,7 +69,9 @@ _gtest_flags_are_parsed = False
def _ParseAndStripGTestFlags(argv):
"""Parses and strips Google Test flags from argv. This is idempotent."""
global _gtest_flags_are_parsed
# Suppresses the lint complaint about a global variable since we need it
# here to maintain module-wide state.
global _gtest_flags_are_parsed # pylint: disable-msg=W0603
if _gtest_flags_are_parsed:
return
@ -103,6 +118,24 @@ def GetBuildDir():
return os.path.abspath(GetFlag('gtest_build_dir'))
_temp_dir = None
def _RemoveTempDir():
if _temp_dir:
shutil.rmtree(_temp_dir, ignore_errors=True)
atexit.register(_RemoveTempDir)
def GetTempDir():
"""Returns a directory for temporary files."""
global _temp_dir
if not _temp_dir:
_temp_dir = tempfile.mkdtemp()
return _temp_dir
def GetTestExecutablePath(executable_name):
"""Returns the absolute path of the test binary given its name.
@ -223,4 +256,4 @@ def Main():
# unittest.main(). Otherwise the latter will be confused by the
# --gtest_* flags.
_ParseAndStripGTestFlags(sys.argv)
unittest.main()
_test_module.main()

View File

@ -37,9 +37,8 @@ Google Test) with different environments and command line flags.
__author__ = 'wan@google.com (Zhanyong Wan)'
import gtest_test_utils
import os
import unittest
import gtest_test_utils
# Constants.
@ -78,7 +77,7 @@ def Run(command):
# The tests. TODO(wan@google.com): refactor the class to share common
# logic with code in gtest_break_on_failure_unittest.py.
class ThrowOnFailureTest(unittest.TestCase):
class ThrowOnFailureTest(gtest_test_utils.TestCase):
"""Tests the throw-on-failure mode."""
def RunAndVerify(self, env_var_value, flag_value, should_fail):

View File

@ -34,8 +34,6 @@
__author__ = 'wan@google.com (Zhanyong Wan)'
import gtest_test_utils
import sys
import unittest
COMMAND = gtest_test_utils.GetTestExecutablePath('gtest_uninitialized_test_')
@ -63,7 +61,7 @@ def TestExitCodeAndOutput(command):
Assert('InitGoogleTest' in p.output)
class GTestUninitializedTest(unittest.TestCase):
class GTestUninitializedTest(gtest_test_utils.TestCase):
def testExitCodeAndOutput(self):
TestExitCodeAndOutput(COMMAND)

View File

@ -33,17 +33,14 @@
__author__ = "keith.ray@gmail.com (Keith Ray)"
import gtest_test_utils
import os
import sys
import tempfile
import unittest
from xml.dom import minidom, Node
import gtest_test_utils
import gtest_xml_test_utils
GTEST_OUTPUT_SUBDIR = "xml_outfiles"
GTEST_OUTPUT_1_TEST = "gtest_xml_outfile1_test_"
GTEST_OUTPUT_2_TEST = "gtest_xml_outfile2_test_"
@ -71,7 +68,8 @@ class GTestXMLOutFilesTest(gtest_xml_test_utils.GTestXMLTestCase):
# We want the trailing '/' that the last "" provides in os.path.join, for
# telling Google Test to create an output directory instead of a single file
# for xml output.
self.output_dir_ = os.path.join(tempfile.mkdtemp(), "")
self.output_dir_ = os.path.join(gtest_test_utils.GetTempDir(),
GTEST_OUTPUT_SUBDIR, "")
self.DeleteFilesAndDir()
def tearDown(self):
@ -87,7 +85,7 @@ class GTestXMLOutFilesTest(gtest_xml_test_utils.GTestXMLTestCase):
except os.error:
pass
try:
os.removedirs(self.output_dir_)
os.rmdir(self.output_dir_)
except os.error:
pass
@ -100,7 +98,8 @@ class GTestXMLOutFilesTest(gtest_xml_test_utils.GTestXMLTestCase):
def _TestOutFile(self, test_name, expected_xml):
gtest_prog_path = gtest_test_utils.GetTestExecutablePath(test_name)
command = [gtest_prog_path, "--gtest_output=xml:%s" % self.output_dir_]
p = gtest_test_utils.Subprocess(command, working_dir=tempfile.mkdtemp())
p = gtest_test_utils.Subprocess(command,
working_dir=gtest_test_utils.GetTempDir())
self.assert_(p.exited)
self.assertEquals(0, p.exit_code)

View File

@ -34,19 +34,24 @@
__author__ = 'eefacm@gmail.com (Sean Mcafee)'
import errno
import gtest_test_utils
import os
import sys
import tempfile
import unittest
from xml.dom import minidom, Node
import gtest_test_utils
import gtest_xml_test_utils
GTEST_OUTPUT_FLAG = "--gtest_output"
GTEST_DEFAULT_OUTPUT_FILE = "test_detail.xml"
SUPPORTS_STACK_TRACES = False
if SUPPORTS_STACK_TRACES:
STACK_TRACE_TEMPLATE = "\nStack trace:\n*"
else:
STACK_TRACE_TEMPLATE = ""
EXPECTED_NON_EMPTY_XML = """<?xml version="1.0" encoding="UTF-8"?>
<testsuites tests="13" failures="2" disabled="2" errors="0" time="*" name="AllTests">
<testsuite name="SuccessfulTest" tests="1" failures="0" disabled="0" errors="0" time="*">
@ -56,7 +61,7 @@ EXPECTED_NON_EMPTY_XML = """<?xml version="1.0" encoding="UTF-8"?>
<testcase name="Fails" status="run" time="*" classname="FailedTest">
<failure message="Value of: 2&#x0A;Expected: 1" type=""><![CDATA[gtest_xml_output_unittest_.cc:*
Value of: 2
Expected: 1]]></failure>
Expected: 1%(stack)s]]></failure>
</testcase>
</testsuite>
<testsuite name="MixedResultTest" tests="3" failures="1" disabled="1" errors="0" time="*">
@ -64,10 +69,10 @@ Expected: 1]]></failure>
<testcase name="Fails" status="run" time="*" classname="MixedResultTest">
<failure message="Value of: 2&#x0A;Expected: 1" type=""><![CDATA[gtest_xml_output_unittest_.cc:*
Value of: 2
Expected: 1]]></failure>
Expected: 1%(stack)s]]></failure>
<failure message="Value of: 3&#x0A;Expected: 2" type=""><![CDATA[gtest_xml_output_unittest_.cc:*
Value of: 3
Expected: 2]]></failure>
Expected: 2%(stack)s]]></failure>
</testcase>
<testcase name="DISABLED_test" status="notrun" time="*" classname="MixedResultTest"/>
</testsuite>
@ -85,7 +90,7 @@ Expected: 2]]></failure>
<testcase name="ExternalUtilityThatCallsRecordIntValuedProperty" status="run" time="*" classname="NoFixtureTest" key_for_utility_int="1"/>
<testcase name="ExternalUtilityThatCallsRecordStringValuedProperty" status="run" time="*" classname="NoFixtureTest" key_for_utility_string="1"/>
</testsuite>
</testsuites>"""
</testsuites>""" % {'stack': STACK_TRACE_TEMPLATE}
EXPECTED_EMPTY_XML = """<?xml version="1.0" encoding="UTF-8"?>
@ -120,8 +125,8 @@ class GTestXMLOutputUnitTest(gtest_xml_test_utils.GTestXMLTestCase):
Confirms that Google Test produces an XML output file with the expected
default name if no name is explicitly specified.
"""
temp_dir = tempfile.mkdtemp()
output_file = os.path.join(temp_dir, GTEST_DEFAULT_OUTPUT_FILE)
output_file = os.path.join(gtest_test_utils.GetTempDir(),
GTEST_DEFAULT_OUTPUT_FILE)
gtest_prog_path = gtest_test_utils.GetTestExecutablePath(
"gtest_no_test_unittest")
try:
@ -132,7 +137,7 @@ class GTestXMLOutputUnitTest(gtest_xml_test_utils.GTestXMLTestCase):
p = gtest_test_utils.Subprocess(
[gtest_prog_path, "%s=xml" % GTEST_OUTPUT_FLAG],
working_dir=temp_dir)
working_dir=gtest_test_utils.GetTempDir())
self.assert_(p.exited)
self.assertEquals(0, p.exit_code)
self.assert_(os.path.isfile(output_file))
@ -145,8 +150,8 @@ class GTestXMLOutputUnitTest(gtest_xml_test_utils.GTestXMLTestCase):
XML document. Furthermore, the program's exit code must be
expected_exit_code.
"""
xml_path = os.path.join(tempfile.mkdtemp(), gtest_prog_name + "out.xml")
xml_path = os.path.join(gtest_test_utils.GetTempDir(),
gtest_prog_name + "out.xml")
gtest_prog_path = gtest_test_utils.GetTestExecutablePath(gtest_prog_name)
command = [gtest_prog_path, "%s=xml:%s" % (GTEST_OUTPUT_FLAG, xml_path)]

View File

@ -34,14 +34,15 @@
__author__ = 'eefacm@gmail.com (Sean Mcafee)'
import re
import unittest
from xml.dom import minidom, Node
import gtest_test_utils
GTEST_OUTPUT_FLAG = "--gtest_output"
GTEST_DEFAULT_OUTPUT_FILE = "test_detail.xml"
class GTestXMLTestCase(unittest.TestCase):
class GTestXMLTestCase(gtest_test_utils.TestCase):
"""
Base class for tests of Google Test's XML output functionality.
"""

View File

@ -48,6 +48,8 @@ class FakePath(object):
self.tree = {}
self.path_separator = os.sep
# known_paths contains either absolute or relative paths. Relative paths
# are absolutized with self.current_dir.
if known_paths:
self._AddPaths(known_paths)
@ -91,8 +93,11 @@ class FakePath(object):
return tree
def normpath(self, path):
return os.path.normpath(path)
def abspath(self, path):
return os.path.normpath(os.path.join(self.current_dir, path))
return self.normpath(os.path.join(self.current_dir, path))
def isfile(self, path):
return self.PathElement(self.abspath(path)) == 1
@ -157,7 +162,8 @@ class GetTestsToRunTest(unittest.TestCase):
'test/gtest_color_test.py']))
self.fake_configurations = ['dbg', 'opt']
self.test_runner = run_tests.TestRunner(injected_os=self.fake_os,
injected_subprocess=None)
injected_subprocess=None,
injected_script_dir='.')
def testBinaryTestsOnly(self):
"""Exercises GetTestsToRun with parameters designating binary tests only."""
@ -388,7 +394,8 @@ class GetTestsToRunTest(unittest.TestCase):
'scons/build/opt/scons/gtest_nontest.exe',
'test/']))
self.test_runner = run_tests.TestRunner(injected_os=self.fake_os,
injected_subprocess=None)
injected_subprocess=None,
injected_script_dir='.')
self.AssertResultsEqual(
self.test_runner.GetTestsToRun(
[],
@ -397,6 +404,43 @@ class GetTestsToRunTest(unittest.TestCase):
available_configurations=self.fake_configurations),
([], []))
def testWorksFromDifferentDir(self):
"""Exercises GetTestsToRun from a directory different from run_test.py's."""
# Here we simulate an test script in directory /d/ called from the
# directory /a/b/c/.
self.fake_os = FakeOs(FakePath(
current_dir=os.path.abspath('/a/b/c'),
known_paths=['/a/b/c/',
'/d/scons/build/dbg/scons/gtest_unittest',
'/d/scons/build/opt/scons/gtest_unittest',
'/d/test/gtest_color_test.py']))
self.fake_configurations = ['dbg', 'opt']
self.test_runner = run_tests.TestRunner(injected_os=self.fake_os,
injected_subprocess=None,
injected_script_dir='/d/')
# A binary test.
self.AssertResultsEqual(
self.test_runner.GetTestsToRun(
['gtest_unittest'],
'',
False,
available_configurations=self.fake_configurations),
([],
[('/d/scons/build/dbg/scons',
'/d/scons/build/dbg/scons/gtest_unittest')]))
# A Python test.
self.AssertResultsEqual(
self.test_runner.GetTestsToRun(
['gtest_color_test.py'],
'',
False,
available_configurations=self.fake_configurations),
([('/d/scons/build/dbg/scons', '/d/test/gtest_color_test.py')],
[]))
def testNonTestBinary(self):
"""Exercises GetTestsToRun with a non-test parameter."""