Merge branch 'master' into fix_death_test_child_mingw_wer_issue1116

This commit is contained in:
Tanzinul Islam 2018-04-01 13:43:57 +01:00
commit 5c7c365d5f
34 changed files with 1182 additions and 392 deletions

View File

@ -40,7 +40,6 @@ matrix:
- os: osx - os: osx
compiler: gcc compiler: gcc
env: BUILD_TYPE=Debug VERBOSE=1 env: BUILD_TYPE=Debug VERBOSE=1
if: type != pull_request
- os: osx - os: osx
compiler: gcc compiler: gcc
env: BUILD_TYPE=Release VERBOSE=1 CXX_FLAGS=-std=c++11 env: BUILD_TYPE=Release VERBOSE=1 CXX_FLAGS=-std=c++11
@ -50,7 +49,6 @@ matrix:
env: BUILD_TYPE=Debug VERBOSE=1 env: BUILD_TYPE=Debug VERBOSE=1
if: type != pull_request if: type != pull_request
- os: osx - os: osx
compiler: clang
env: BUILD_TYPE=Release VERBOSE=1 CXX_FLAGS=-std=c++11 env: BUILD_TYPE=Release VERBOSE=1 CXX_FLAGS=-std=c++11
if: type != pull_request if: type != pull_request

View File

@ -87,7 +87,7 @@ test_script:
if ($env:generator -eq "MinGW Makefiles") { if ($env:generator -eq "MinGW Makefiles") {
return # No test available for MinGW return # No test available for MinGW
} }
& ctest -C $env:configuration --timeout 300 --output-on-failure & ctest -C $env:configuration --timeout 600 --output-on-failure
if ($LastExitCode -ne 0) { if ($LastExitCode -ne 0) {
throw "Exec: $ErrorMessage" throw "Exec: $ErrorMessage"
} }

View File

@ -46,9 +46,10 @@
#include "gmock/internal/gmock-internal-utils.h" #include "gmock/internal/gmock-internal-utils.h"
#include "gmock/internal/gmock-port.h" #include "gmock/internal/gmock-port.h"
#if GTEST_HAS_STD_TYPE_TRAITS_ // Defined by gtest-port.h via gmock-port.h. #if GTEST_LANG_CXX11 // Defined by gtest-port.h via gmock-port.h.
#include <functional>
#include <type_traits> #include <type_traits>
#endif #endif // GTEST_LANG_CXX11
namespace testing { namespace testing {
@ -96,7 +97,7 @@ struct BuiltInDefaultValueGetter<T, false> {
template <typename T> template <typename T>
class BuiltInDefaultValue { class BuiltInDefaultValue {
public: public:
#if GTEST_HAS_STD_TYPE_TRAITS_ #if GTEST_LANG_CXX11
// This function returns true iff type T has a built-in default value. // This function returns true iff type T has a built-in default value.
static bool Exists() { static bool Exists() {
return ::std::is_default_constructible<T>::value; return ::std::is_default_constructible<T>::value;
@ -107,7 +108,7 @@ class BuiltInDefaultValue {
T, ::std::is_default_constructible<T>::value>::Get(); T, ::std::is_default_constructible<T>::value>::Get();
} }
#else // GTEST_HAS_STD_TYPE_TRAITS_ #else // GTEST_LANG_CXX11
// This function returns true iff type T has a built-in default value. // This function returns true iff type T has a built-in default value.
static bool Exists() { static bool Exists() {
return false; return false;
@ -117,7 +118,7 @@ class BuiltInDefaultValue {
return BuiltInDefaultValueGetter<T, false>::Get(); return BuiltInDefaultValueGetter<T, false>::Get();
} }
#endif // GTEST_HAS_STD_TYPE_TRAITS_ #endif // GTEST_LANG_CXX11
}; };
// This partial specialization says that we use the same built-in // This partial specialization says that we use the same built-in

View File

@ -179,6 +179,35 @@ class MatcherInterface : public MatcherDescriberInterface {
// virtual void DescribeNegationTo(::std::ostream* os) const; // virtual void DescribeNegationTo(::std::ostream* os) const;
}; };
namespace internal {
// Converts a MatcherInterface<T> to a MatcherInterface<const T&>.
template <typename T>
class MatcherInterfaceAdapter : public MatcherInterface<const T&> {
public:
explicit MatcherInterfaceAdapter(const MatcherInterface<T>* impl)
: impl_(impl) {}
virtual ~MatcherInterfaceAdapter() { delete impl_; }
virtual void DescribeTo(::std::ostream* os) const { impl_->DescribeTo(os); }
virtual void DescribeNegationTo(::std::ostream* os) const {
impl_->DescribeNegationTo(os);
}
virtual bool MatchAndExplain(const T& x,
MatchResultListener* listener) const {
return impl_->MatchAndExplain(x, listener);
}
private:
const MatcherInterface<T>* const impl_;
GTEST_DISALLOW_COPY_AND_ASSIGN_(MatcherInterfaceAdapter);
};
} // namespace internal
// A match result listener that stores the explanation in a string. // A match result listener that stores the explanation in a string.
class StringMatchResultListener : public MatchResultListener { class StringMatchResultListener : public MatchResultListener {
public: public:
@ -252,7 +281,8 @@ class MatcherBase {
public: public:
// Returns true iff the matcher matches x; also explains the match // Returns true iff the matcher matches x; also explains the match
// result to 'listener'. // result to 'listener'.
bool MatchAndExplain(T x, MatchResultListener* listener) const { bool MatchAndExplain(GTEST_REFERENCE_TO_CONST_(T) x,
MatchResultListener* listener) const {
return impl_->MatchAndExplain(x, listener); return impl_->MatchAndExplain(x, listener);
} }
@ -290,6 +320,14 @@ class MatcherBase {
explicit MatcherBase(const MatcherInterface<T>* impl) explicit MatcherBase(const MatcherInterface<T>* impl)
: impl_(impl) {} : impl_(impl) {}
template <typename U>
explicit MatcherBase(
const MatcherInterface<U>* impl,
typename internal::EnableIf<
!internal::IsSame<U, GTEST_REFERENCE_TO_CONST_(U)>::value>::type* =
NULL)
: impl_(new internal::MatcherInterfaceAdapter<U>(impl)) {}
virtual ~MatcherBase() {} virtual ~MatcherBase() {}
private: private:
@ -323,7 +361,13 @@ class Matcher : public internal::MatcherBase<T> {
explicit Matcher() {} // NOLINT explicit Matcher() {} // NOLINT
// Constructs a matcher from its implementation. // Constructs a matcher from its implementation.
explicit Matcher(const MatcherInterface<T>* impl) explicit Matcher(const MatcherInterface<GTEST_REFERENCE_TO_CONST_(T)>* impl)
: internal::MatcherBase<T>(impl) {}
template <typename U>
explicit Matcher(const MatcherInterface<U>* impl,
typename internal::EnableIf<!internal::IsSame<
U, GTEST_REFERENCE_TO_CONST_(U)>::value>::type* = NULL)
: internal::MatcherBase<T>(impl) {} : internal::MatcherBase<T>(impl) {}
// Implicit constructor here allows people to write // Implicit constructor here allows people to write
@ -332,64 +376,79 @@ class Matcher : public internal::MatcherBase<T> {
}; };
// The following two specializations allow the user to write str // The following two specializations allow the user to write str
// instead of Eq(str) and "foo" instead of Eq("foo") when a string // instead of Eq(str) and "foo" instead of Eq("foo") when a std::string
// matcher is expected. // matcher is expected.
template <> template <>
class GTEST_API_ Matcher<const internal::string&> class GTEST_API_ Matcher<const std::string&>
: public internal::MatcherBase<const internal::string&> { : public internal::MatcherBase<const std::string&> {
public: public:
Matcher() {} Matcher() {}
explicit Matcher(const MatcherInterface<const internal::string&>* impl) explicit Matcher(const MatcherInterface<const std::string&>* impl)
: internal::MatcherBase<const internal::string&>(impl) {} : internal::MatcherBase<const std::string&>(impl) {}
// Allows the user to write str instead of Eq(str) sometimes, where // Allows the user to write str instead of Eq(str) sometimes, where
// str is a string object. // str is a std::string object.
Matcher(const internal::string& s); // NOLINT Matcher(const std::string& s); // NOLINT
#if GTEST_HAS_GLOBAL_STRING
// Allows the user to write str instead of Eq(str) sometimes, where
// str is a ::string object.
Matcher(const ::string& s); // NOLINT
#endif // GTEST_HAS_GLOBAL_STRING
// Allows the user to write "foo" instead of Eq("foo") sometimes. // Allows the user to write "foo" instead of Eq("foo") sometimes.
Matcher(const char* s); // NOLINT Matcher(const char* s); // NOLINT
}; };
template <> template <>
class GTEST_API_ Matcher<internal::string> class GTEST_API_ Matcher<std::string>
: public internal::MatcherBase<internal::string> { : public internal::MatcherBase<std::string> {
public: public:
Matcher() {} Matcher() {}
explicit Matcher(const MatcherInterface<internal::string>* impl) explicit Matcher(const MatcherInterface<std::string>* impl)
: internal::MatcherBase<internal::string>(impl) {} : internal::MatcherBase<std::string>(impl) {}
// Allows the user to write str instead of Eq(str) sometimes, where // Allows the user to write str instead of Eq(str) sometimes, where
// str is a string object. // str is a string object.
Matcher(const internal::string& s); // NOLINT Matcher(const std::string& s); // NOLINT
#if GTEST_HAS_GLOBAL_STRING
// Allows the user to write str instead of Eq(str) sometimes, where
// str is a ::string object.
Matcher(const ::string& s); // NOLINT
#endif // GTEST_HAS_GLOBAL_STRING
// Allows the user to write "foo" instead of Eq("foo") sometimes. // Allows the user to write "foo" instead of Eq("foo") sometimes.
Matcher(const char* s); // NOLINT Matcher(const char* s); // NOLINT
}; };
#if GTEST_HAS_STRING_PIECE_ #if GTEST_HAS_GLOBAL_STRING
// The following two specializations allow the user to write str // The following two specializations allow the user to write str
// instead of Eq(str) and "foo" instead of Eq("foo") when a StringPiece // instead of Eq(str) and "foo" instead of Eq("foo") when a ::string
// matcher is expected. // matcher is expected.
template <> template <>
class GTEST_API_ Matcher<const StringPiece&> class GTEST_API_ Matcher<const ::string&>
: public internal::MatcherBase<const StringPiece&> { : public internal::MatcherBase<const ::string&> {
public: public:
Matcher() {} Matcher() {}
explicit Matcher(const MatcherInterface<const StringPiece&>* impl) explicit Matcher(const MatcherInterface<const ::string&>* impl)
: internal::MatcherBase<const StringPiece&>(impl) {} : internal::MatcherBase<const ::string&>(impl) {}
// Allows the user to write str instead of Eq(str) sometimes, where // Allows the user to write str instead of Eq(str) sometimes, where
// str is a string object. // str is a std::string object.
Matcher(const internal::string& s); // NOLINT Matcher(const std::string& s); // NOLINT
// Allows the user to write str instead of Eq(str) sometimes, where
// str is a ::string object.
Matcher(const ::string& s); // NOLINT
// Allows the user to write "foo" instead of Eq("foo") sometimes. // Allows the user to write "foo" instead of Eq("foo") sometimes.
Matcher(const char* s); // NOLINT Matcher(const char* s); // NOLINT
};
// Allows the user to pass StringPieces directly.
Matcher(StringPiece s); // NOLINT
}; };
template <> template <>
@ -530,21 +589,18 @@ class MatcherCastImpl {
return CastImpl( return CastImpl(
polymorphic_matcher_or_value, polymorphic_matcher_or_value,
BooleanConstant< BooleanConstant<
internal::ImplicitlyConvertible<M, Matcher<T> >::value>()); internal::ImplicitlyConvertible<M, Matcher<T> >::value>(),
BooleanConstant<
internal::ImplicitlyConvertible<M, T>::value>());
} }
private: private:
static Matcher<T> CastImpl(const M& value, BooleanConstant<false>) { template <bool Ignore>
// M can't be implicitly converted to Matcher<T>, so M isn't a polymorphic
// matcher. It must be a value then. Use direct initialization to create
// a matcher.
return Matcher<T>(ImplicitCast_<T>(value));
}
static Matcher<T> CastImpl(const M& polymorphic_matcher_or_value, static Matcher<T> CastImpl(const M& polymorphic_matcher_or_value,
BooleanConstant<true>) { BooleanConstant<true> /* convertible_to_matcher */,
BooleanConstant<Ignore>) {
// M is implicitly convertible to Matcher<T>, which means that either // M is implicitly convertible to Matcher<T>, which means that either
// M is a polymorhpic matcher or Matcher<T> has an implicit constructor // M is a polymorphic matcher or Matcher<T> has an implicit constructor
// from M. In both cases using the implicit conversion will produce a // from M. In both cases using the implicit conversion will produce a
// matcher. // matcher.
// //
@ -553,6 +609,29 @@ class MatcherCastImpl {
// (first to create T from M and then to create Matcher<T> from T). // (first to create T from M and then to create Matcher<T> from T).
return polymorphic_matcher_or_value; return polymorphic_matcher_or_value;
} }
// M can't be implicitly converted to Matcher<T>, so M isn't a polymorphic
// matcher. It's a value of a type implicitly convertible to T. Use direct
// initialization to create a matcher.
static Matcher<T> CastImpl(
const M& value, BooleanConstant<false> /* convertible_to_matcher */,
BooleanConstant<true> /* convertible_to_T */) {
return Matcher<T>(ImplicitCast_<T>(value));
}
// M can't be implicitly converted to either Matcher<T> or T. Attempt to use
// polymorphic matcher Eq(value) in this case.
//
// Note that we first attempt to perform an implicit cast on the value and
// only fall back to the polymorphic Eq() matcher afterwards because the
// latter calls bool operator==(const Lhs& lhs, const Rhs& rhs) in the end
// which might be undefined even when Rhs is implicitly convertible to Lhs
// (e.g. std::pair<const int, int> vs. std::pair<int, int>).
//
// We don't define this method inline as we need the declaration of Eq().
static Matcher<T> CastImpl(
const M& value, BooleanConstant<false> /* convertible_to_matcher */,
BooleanConstant<false> /* convertible_to_T */);
}; };
// This more specialized version is used when MatcherCast()'s argument // This more specialized version is used when MatcherCast()'s argument
@ -573,6 +652,22 @@ class MatcherCastImpl<T, Matcher<U> > {
// We delegate the matching logic to the source matcher. // We delegate the matching logic to the source matcher.
virtual bool MatchAndExplain(T x, MatchResultListener* listener) const { virtual bool MatchAndExplain(T x, MatchResultListener* listener) const {
#if GTEST_LANG_CXX11
using FromType = typename std::remove_cv<typename std::remove_pointer<
typename std::remove_reference<T>::type>::type>::type;
using ToType = typename std::remove_cv<typename std::remove_pointer<
typename std::remove_reference<U>::type>::type>::type;
// Do not allow implicitly converting base*/& to derived*/&.
static_assert(
// Do not trigger if only one of them is a pointer. That implies a
// regular conversion and not a down_cast.
(std::is_pointer<typename std::remove_reference<T>::type>::value !=
std::is_pointer<typename std::remove_reference<U>::type>::value) ||
std::is_same<FromType, ToType>::value ||
!std::is_base_of<FromType, ToType>::value,
"Can't implicitly convert from <base> to <derived>");
#endif // GTEST_LANG_CXX11
return source_matcher_.MatchAndExplain(static_cast<U>(x), listener); return source_matcher_.MatchAndExplain(static_cast<U>(x), listener);
} }
@ -1340,7 +1435,7 @@ class MatchesRegexMatcher {
// Matches anything that can convert to std::string. // Matches anything that can convert to std::string.
// //
// This is a template, not just a plain function with const std::string&, // This is a template, not just a plain function with const std::string&,
// because StringPiece has some interfering non-explicit constructors. // because absl::string_view has some interfering non-explicit constructors.
template <class MatcheeStringType> template <class MatcheeStringType>
bool MatchAndExplain(const MatcheeStringType& s, bool MatchAndExplain(const MatcheeStringType& s,
MatchResultListener* /* listener */) const { MatchResultListener* /* listener */) const {
@ -2036,6 +2131,82 @@ class FloatingEqMatcher {
GTEST_DISALLOW_ASSIGN_(FloatingEqMatcher); GTEST_DISALLOW_ASSIGN_(FloatingEqMatcher);
}; };
// A 2-tuple ("binary") wrapper around FloatingEqMatcher:
// FloatingEq2Matcher() matches (x, y) by matching FloatingEqMatcher(x, false)
// against y, and FloatingEq2Matcher(e) matches FloatingEqMatcher(x, false, e)
// against y. The former implements "Eq", the latter "Near". At present, there
// is no version that compares NaNs as equal.
template <typename FloatType>
class FloatingEq2Matcher {
public:
FloatingEq2Matcher() { Init(-1, false); }
explicit FloatingEq2Matcher(bool nan_eq_nan) { Init(-1, nan_eq_nan); }
explicit FloatingEq2Matcher(FloatType max_abs_error) {
Init(max_abs_error, false);
}
FloatingEq2Matcher(FloatType max_abs_error, bool nan_eq_nan) {
Init(max_abs_error, nan_eq_nan);
}
template <typename T1, typename T2>
operator Matcher< ::testing::tuple<T1, T2> >() const {
return MakeMatcher(
new Impl< ::testing::tuple<T1, T2> >(max_abs_error_, nan_eq_nan_));
}
template <typename T1, typename T2>
operator Matcher<const ::testing::tuple<T1, T2>&>() const {
return MakeMatcher(
new Impl<const ::testing::tuple<T1, T2>&>(max_abs_error_, nan_eq_nan_));
}
private:
static ::std::ostream& GetDesc(::std::ostream& os) { // NOLINT
return os << "an almost-equal pair";
}
template <typename Tuple>
class Impl : public MatcherInterface<Tuple> {
public:
Impl(FloatType max_abs_error, bool nan_eq_nan) :
max_abs_error_(max_abs_error),
nan_eq_nan_(nan_eq_nan) {}
virtual bool MatchAndExplain(Tuple args,
MatchResultListener* listener) const {
if (max_abs_error_ == -1) {
FloatingEqMatcher<FloatType> fm(::testing::get<0>(args), nan_eq_nan_);
return static_cast<Matcher<FloatType> >(fm).MatchAndExplain(
::testing::get<1>(args), listener);
} else {
FloatingEqMatcher<FloatType> fm(::testing::get<0>(args), nan_eq_nan_,
max_abs_error_);
return static_cast<Matcher<FloatType> >(fm).MatchAndExplain(
::testing::get<1>(args), listener);
}
}
virtual void DescribeTo(::std::ostream* os) const {
*os << "are " << GetDesc;
}
virtual void DescribeNegationTo(::std::ostream* os) const {
*os << "aren't " << GetDesc;
}
private:
FloatType max_abs_error_;
const bool nan_eq_nan_;
};
void Init(FloatType max_abs_error_val, bool nan_eq_nan_val) {
max_abs_error_ = max_abs_error_val;
nan_eq_nan_ = nan_eq_nan_val;
}
FloatType max_abs_error_;
bool nan_eq_nan_;
};
// Implements the Pointee(m) matcher for matching a pointer whose // Implements the Pointee(m) matcher for matching a pointer whose
// pointee matches matcher m. The pointer can be either raw or smart. // pointee matches matcher m. The pointer can be either raw or smart.
template <typename InnerMatcher> template <typename InnerMatcher>
@ -2181,15 +2352,21 @@ class FieldMatcher {
public: public:
FieldMatcher(FieldType Class::*field, FieldMatcher(FieldType Class::*field,
const Matcher<const FieldType&>& matcher) const Matcher<const FieldType&>& matcher)
: field_(field), matcher_(matcher) {} : field_(field), matcher_(matcher), whose_field_("whose given field ") {}
FieldMatcher(const std::string& field_name, FieldType Class::*field,
const Matcher<const FieldType&>& matcher)
: field_(field),
matcher_(matcher),
whose_field_("whose field `" + field_name + "` ") {}
void DescribeTo(::std::ostream* os) const { void DescribeTo(::std::ostream* os) const {
*os << "is an object whose given field "; *os << "is an object " << whose_field_;
matcher_.DescribeTo(os); matcher_.DescribeTo(os);
} }
void DescribeNegationTo(::std::ostream* os) const { void DescribeNegationTo(::std::ostream* os) const {
*os << "is an object whose given field "; *os << "is an object " << whose_field_;
matcher_.DescribeNegationTo(os); matcher_.DescribeNegationTo(os);
} }
@ -2207,7 +2384,7 @@ class FieldMatcher {
// true_type iff the Field() matcher is used to match a pointer. // true_type iff the Field() matcher is used to match a pointer.
bool MatchAndExplainImpl(false_type /* is_not_pointer */, const Class& obj, bool MatchAndExplainImpl(false_type /* is_not_pointer */, const Class& obj,
MatchResultListener* listener) const { MatchResultListener* listener) const {
*listener << "whose given field is "; *listener << whose_field_ << "is ";
return MatchPrintAndExplain(obj.*field_, matcher_, listener); return MatchPrintAndExplain(obj.*field_, matcher_, listener);
} }
@ -2226,6 +2403,10 @@ class FieldMatcher {
const FieldType Class::*field_; const FieldType Class::*field_;
const Matcher<const FieldType&> matcher_; const Matcher<const FieldType&> matcher_;
// Contains either "whose given field " if the name of the field is unknown
// or "whose field `name_of_field` " if the name is known.
const std::string whose_field_;
GTEST_DISALLOW_ASSIGN_(FieldMatcher); GTEST_DISALLOW_ASSIGN_(FieldMatcher);
}; };
@ -2244,15 +2425,23 @@ class PropertyMatcher {
typedef GTEST_REFERENCE_TO_CONST_(PropertyType) RefToConstProperty; typedef GTEST_REFERENCE_TO_CONST_(PropertyType) RefToConstProperty;
PropertyMatcher(Property property, const Matcher<RefToConstProperty>& matcher) PropertyMatcher(Property property, const Matcher<RefToConstProperty>& matcher)
: property_(property), matcher_(matcher) {} : property_(property),
matcher_(matcher),
whose_property_("whose given property ") {}
PropertyMatcher(const std::string& property_name, Property property,
const Matcher<RefToConstProperty>& matcher)
: property_(property),
matcher_(matcher),
whose_property_("whose property `" + property_name + "` ") {}
void DescribeTo(::std::ostream* os) const { void DescribeTo(::std::ostream* os) const {
*os << "is an object whose given property "; *os << "is an object " << whose_property_;
matcher_.DescribeTo(os); matcher_.DescribeTo(os);
} }
void DescribeNegationTo(::std::ostream* os) const { void DescribeNegationTo(::std::ostream* os) const {
*os << "is an object whose given property "; *os << "is an object " << whose_property_;
matcher_.DescribeNegationTo(os); matcher_.DescribeNegationTo(os);
} }
@ -2270,7 +2459,7 @@ class PropertyMatcher {
// true_type iff the Property() matcher is used to match a pointer. // true_type iff the Property() matcher is used to match a pointer.
bool MatchAndExplainImpl(false_type /* is_not_pointer */, const Class& obj, bool MatchAndExplainImpl(false_type /* is_not_pointer */, const Class& obj,
MatchResultListener* listener) const { MatchResultListener* listener) const {
*listener << "whose given property is "; *listener << whose_property_ << "is ";
// Cannot pass the return value (for example, int) to MatchPrintAndExplain, // Cannot pass the return value (for example, int) to MatchPrintAndExplain,
// which takes a non-const reference as argument. // which takes a non-const reference as argument.
#if defined(_PREFAST_ ) && _MSC_VER == 1800 #if defined(_PREFAST_ ) && _MSC_VER == 1800
@ -2299,6 +2488,10 @@ class PropertyMatcher {
Property property_; Property property_;
const Matcher<RefToConstProperty> matcher_; const Matcher<RefToConstProperty> matcher_;
// Contains either "whose given property " if the name of the property is
// unknown or "whose property `name_of_property` " if the name is known.
const std::string whose_property_;
GTEST_DISALLOW_ASSIGN_(PropertyMatcher); GTEST_DISALLOW_ASSIGN_(PropertyMatcher);
}; };
@ -2692,6 +2885,10 @@ class WhenSortedByMatcher {
// container and the RHS container respectively. // container and the RHS container respectively.
template <typename TupleMatcher, typename RhsContainer> template <typename TupleMatcher, typename RhsContainer>
class PointwiseMatcher { class PointwiseMatcher {
GTEST_COMPILE_ASSERT_(
!IsHashTable<GTEST_REMOVE_REFERENCE_AND_CONST_(RhsContainer)>::value,
use_UnorderedPointwise_with_hash_tables);
public: public:
typedef internal::StlContainerView<RhsContainer> RhsView; typedef internal::StlContainerView<RhsContainer> RhsView;
typedef typename RhsView::type RhsStlContainer; typedef typename RhsView::type RhsStlContainer;
@ -2709,6 +2906,10 @@ class PointwiseMatcher {
template <typename LhsContainer> template <typename LhsContainer>
operator Matcher<LhsContainer>() const { operator Matcher<LhsContainer>() const {
GTEST_COMPILE_ASSERT_(
!IsHashTable<GTEST_REMOVE_REFERENCE_AND_CONST_(LhsContainer)>::value,
use_UnorderedPointwise_with_hash_tables);
return MakeMatcher(new Impl<LhsContainer>(tuple_matcher_, rhs_)); return MakeMatcher(new Impl<LhsContainer>(tuple_matcher_, rhs_));
} }
@ -2759,12 +2960,15 @@ class PointwiseMatcher {
typename LhsStlContainer::const_iterator left = lhs_stl_container.begin(); typename LhsStlContainer::const_iterator left = lhs_stl_container.begin();
typename RhsStlContainer::const_iterator right = rhs_.begin(); typename RhsStlContainer::const_iterator right = rhs_.begin();
for (size_t i = 0; i != actual_size; ++i, ++left, ++right) { for (size_t i = 0; i != actual_size; ++i, ++left, ++right) {
const InnerMatcherArg value_pair(*left, *right);
if (listener->IsInterested()) { if (listener->IsInterested()) {
StringMatchResultListener inner_listener; StringMatchResultListener inner_listener;
// Create InnerMatcherArg as a temporarily object to avoid it outlives
// *left and *right. Dereference or the conversion to `const T&` may
// return temp objects, e.g for vector<bool>.
if (!mono_tuple_matcher_.MatchAndExplain( if (!mono_tuple_matcher_.MatchAndExplain(
value_pair, &inner_listener)) { InnerMatcherArg(ImplicitCast_<const LhsValue&>(*left),
ImplicitCast_<const RhsValue&>(*right)),
&inner_listener)) {
*listener << "where the value pair ("; *listener << "where the value pair (";
UniversalPrint(*left, listener->stream()); UniversalPrint(*left, listener->stream());
*listener << ", "; *listener << ", ";
@ -2774,7 +2978,9 @@ class PointwiseMatcher {
return false; return false;
} }
} else { } else {
if (!mono_tuple_matcher_.Matches(value_pair)) if (!mono_tuple_matcher_.Matches(
InnerMatcherArg(ImplicitCast_<const LhsValue&>(*left),
ImplicitCast_<const RhsValue&>(*right))))
return false; return false;
} }
} }
@ -2932,6 +3138,50 @@ class EachMatcher {
GTEST_DISALLOW_ASSIGN_(EachMatcher); GTEST_DISALLOW_ASSIGN_(EachMatcher);
}; };
struct Rank1 {};
struct Rank0 : Rank1 {};
namespace pair_getters {
#if GTEST_LANG_CXX11
using std::get;
template <typename T>
auto First(T& x, Rank1) -> decltype(get<0>(x)) { // NOLINT
return get<0>(x);
}
template <typename T>
auto First(T& x, Rank0) -> decltype((x.first)) { // NOLINT
return x.first;
}
template <typename T>
auto Second(T& x, Rank1) -> decltype(get<1>(x)) { // NOLINT
return get<1>(x);
}
template <typename T>
auto Second(T& x, Rank0) -> decltype((x.second)) { // NOLINT
return x.second;
}
#else
template <typename T>
typename T::first_type& First(T& x, Rank0) { // NOLINT
return x.first;
}
template <typename T>
const typename T::first_type& First(const T& x, Rank0) {
return x.first;
}
template <typename T>
typename T::second_type& Second(T& x, Rank0) { // NOLINT
return x.second;
}
template <typename T>
const typename T::second_type& Second(const T& x, Rank0) {
return x.second;
}
#endif // GTEST_LANG_CXX11
} // namespace pair_getters
// Implements Key(inner_matcher) for the given argument pair type. // Implements Key(inner_matcher) for the given argument pair type.
// Key(inner_matcher) matches an std::pair whose 'first' field matches // Key(inner_matcher) matches an std::pair whose 'first' field matches
// inner_matcher. For example, Contains(Key(Ge(5))) can be used to match an // inner_matcher. For example, Contains(Key(Ge(5))) can be used to match an
@ -2952,8 +3202,8 @@ class KeyMatcherImpl : public MatcherInterface<PairType> {
virtual bool MatchAndExplain(PairType key_value, virtual bool MatchAndExplain(PairType key_value,
MatchResultListener* listener) const { MatchResultListener* listener) const {
StringMatchResultListener inner_listener; StringMatchResultListener inner_listener;
const bool match = inner_matcher_.MatchAndExplain(key_value.first, const bool match = inner_matcher_.MatchAndExplain(
&inner_listener); pair_getters::First(key_value, Rank0()), &inner_listener);
const std::string explanation = inner_listener.str(); const std::string explanation = inner_listener.str();
if (explanation != "") { if (explanation != "") {
*listener << "whose first field is a value " << explanation; *listener << "whose first field is a value " << explanation;
@ -3036,18 +3286,18 @@ class PairMatcherImpl : public MatcherInterface<PairType> {
if (!listener->IsInterested()) { if (!listener->IsInterested()) {
// If the listener is not interested, we don't need to construct the // If the listener is not interested, we don't need to construct the
// explanation. // explanation.
return first_matcher_.Matches(a_pair.first) && return first_matcher_.Matches(pair_getters::First(a_pair, Rank0())) &&
second_matcher_.Matches(a_pair.second); second_matcher_.Matches(pair_getters::Second(a_pair, Rank0()));
} }
StringMatchResultListener first_inner_listener; StringMatchResultListener first_inner_listener;
if (!first_matcher_.MatchAndExplain(a_pair.first, if (!first_matcher_.MatchAndExplain(pair_getters::First(a_pair, Rank0()),
&first_inner_listener)) { &first_inner_listener)) {
*listener << "whose first field does not match"; *listener << "whose first field does not match";
PrintIfNotEmpty(first_inner_listener.str(), listener->stream()); PrintIfNotEmpty(first_inner_listener.str(), listener->stream());
return false; return false;
} }
StringMatchResultListener second_inner_listener; StringMatchResultListener second_inner_listener;
if (!second_matcher_.MatchAndExplain(a_pair.second, if (!second_matcher_.MatchAndExplain(pair_getters::Second(a_pair, Rank0()),
&second_inner_listener)) { &second_inner_listener)) {
*listener << "whose second field does not match"; *listener << "whose second field does not match";
PrintIfNotEmpty(second_inner_listener.str(), listener->stream()); PrintIfNotEmpty(second_inner_listener.str(), listener->stream());
@ -3494,6 +3744,11 @@ class ElementsAreMatcher {
template <typename Container> template <typename Container>
operator Matcher<Container>() const { operator Matcher<Container>() const {
GTEST_COMPILE_ASSERT_(
!IsHashTable<GTEST_REMOVE_REFERENCE_AND_CONST_(Container)>::value ||
::testing::tuple_size<MatcherTuple>::value < 2,
use_UnorderedElementsAre_with_hash_tables);
typedef GTEST_REMOVE_REFERENCE_AND_CONST_(Container) RawContainer; typedef GTEST_REMOVE_REFERENCE_AND_CONST_(Container) RawContainer;
typedef typename internal::StlContainerView<RawContainer>::type View; typedef typename internal::StlContainerView<RawContainer>::type View;
typedef typename View::value_type Element; typedef typename View::value_type Element;
@ -3542,6 +3797,10 @@ class ElementsAreArrayMatcher {
template <typename Container> template <typename Container>
operator Matcher<Container>() const { operator Matcher<Container>() const {
GTEST_COMPILE_ASSERT_(
!IsHashTable<GTEST_REMOVE_REFERENCE_AND_CONST_(Container)>::value,
use_UnorderedElementsAreArray_with_hash_tables);
return MakeMatcher(new ElementsAreMatcherImpl<Container>( return MakeMatcher(new ElementsAreMatcherImpl<Container>(
matchers_.begin(), matchers_.end())); matchers_.begin(), matchers_.end()));
} }
@ -3636,6 +3895,61 @@ GTEST_API_ std::string FormatMatcherDescription(bool negation,
const char* matcher_name, const char* matcher_name,
const Strings& param_values); const Strings& param_values);
// Implements a matcher that checks the value of a optional<> type variable.
template <typename ValueMatcher>
class OptionalMatcher {
public:
explicit OptionalMatcher(const ValueMatcher& value_matcher)
: value_matcher_(value_matcher) {}
template <typename Optional>
operator Matcher<Optional>() const {
return MakeMatcher(new Impl<Optional>(value_matcher_));
}
template <typename Optional>
class Impl : public MatcherInterface<Optional> {
public:
typedef GTEST_REMOVE_REFERENCE_AND_CONST_(Optional) OptionalView;
typedef typename OptionalView::value_type ValueType;
explicit Impl(const ValueMatcher& value_matcher)
: value_matcher_(MatcherCast<ValueType>(value_matcher)) {}
virtual void DescribeTo(::std::ostream* os) const {
*os << "value ";
value_matcher_.DescribeTo(os);
}
virtual void DescribeNegationTo(::std::ostream* os) const {
*os << "value ";
value_matcher_.DescribeNegationTo(os);
}
virtual bool MatchAndExplain(Optional optional,
MatchResultListener* listener) const {
if (!optional) {
*listener << "which is not engaged";
return false;
}
const ValueType& value = *optional;
StringMatchResultListener value_listener;
const bool match = value_matcher_.MatchAndExplain(value, &value_listener);
*listener << "whose value " << PrintToString(value)
<< (match ? " matches" : " doesn't match");
PrintIfNotEmpty(value_listener.str(), listener->stream());
return match;
}
private:
const Matcher<ValueType> value_matcher_;
GTEST_DISALLOW_ASSIGN_(Impl);
};
private:
const ValueMatcher value_matcher_;
GTEST_DISALLOW_ASSIGN_(OptionalMatcher);
};
namespace variant_matcher { namespace variant_matcher {
// Overloads to allow VariantMatcher to do proper ADL lookup. // Overloads to allow VariantMatcher to do proper ADL lookup.
template <typename T> template <typename T>
@ -3684,7 +3998,7 @@ class VariantMatcher {
} }
private: private:
static string GetTypeName() { static std::string GetTypeName() {
#if GTEST_HAS_RTTI #if GTEST_HAS_RTTI
return internal::GetTypeName<T>(); return internal::GetTypeName<T>();
#endif #endif
@ -3696,6 +4010,65 @@ class VariantMatcher {
} // namespace variant_matcher } // namespace variant_matcher
namespace any_cast_matcher {
// Overloads to allow AnyCastMatcher to do proper ADL lookup.
template <typename T>
void any_cast() {}
// Implements a matcher that any_casts the value.
template <typename T>
class AnyCastMatcher {
public:
explicit AnyCastMatcher(const ::testing::Matcher<const T&>& matcher)
: matcher_(matcher) {}
template <typename AnyType>
bool MatchAndExplain(const AnyType& value,
::testing::MatchResultListener* listener) const {
if (!listener->IsInterested()) {
const T* ptr = any_cast<T>(&value);
return ptr != NULL && matcher_.Matches(*ptr);
}
const T* elem = any_cast<T>(&value);
if (elem == NULL) {
*listener << "whose value is not of type '" << GetTypeName() << "'";
return false;
}
StringMatchResultListener elem_listener;
const bool match = matcher_.MatchAndExplain(*elem, &elem_listener);
*listener << "whose value " << PrintToString(*elem)
<< (match ? " matches" : " doesn't match");
PrintIfNotEmpty(elem_listener.str(), listener->stream());
return match;
}
void DescribeTo(std::ostream* os) const {
*os << "is an 'any' type with value of type '" << GetTypeName()
<< "' and the value ";
matcher_.DescribeTo(os);
}
void DescribeNegationTo(std::ostream* os) const {
*os << "is an 'any' type with value of type other than '" << GetTypeName()
<< "' or the value ";
matcher_.DescribeNegationTo(os);
}
private:
static std::string GetTypeName() {
#if GTEST_HAS_RTTI
return internal::GetTypeName<T>();
#endif
return "the element type";
}
const ::testing::Matcher<const T&> matcher_;
};
} // namespace any_cast_matcher
} // namespace internal } // namespace internal
// ElementsAreArray(iterator_first, iterator_last) // ElementsAreArray(iterator_first, iterator_last)
@ -3827,6 +4200,14 @@ inline internal::EqMatcher<T> Eq(T x) { return internal::EqMatcher<T>(x); }
template <typename T> template <typename T>
Matcher<T>::Matcher(T value) { *this = Eq(value); } Matcher<T>::Matcher(T value) { *this = Eq(value); }
template <typename T, typename M>
Matcher<T> internal::MatcherCastImpl<T, M>::CastImpl(
const M& value,
internal::BooleanConstant<false> /* convertible_to_matcher */,
internal::BooleanConstant<false> /* convertible_to_T */) {
return Eq(value);
}
// Creates a monomorphic matcher that matches anything with type Lhs // Creates a monomorphic matcher that matches anything with type Lhs
// and equal to rhs. A user may need to use this instead of Eq(...) // and equal to rhs. A user may need to use this instead of Eq(...)
// in order to resolve an overloading ambiguity. // in order to resolve an overloading ambiguity.
@ -3985,6 +4366,16 @@ inline PolymorphicMatcher<
// to compile where bar is an int32 and m is a matcher for int64. // to compile where bar is an int32 and m is a matcher for int64.
} }
// Same as Field() but also takes the name of the field to provide better error
// messages.
template <typename Class, typename FieldType, typename FieldMatcher>
inline PolymorphicMatcher<internal::FieldMatcher<Class, FieldType> > Field(
const std::string& field_name, FieldType Class::*field,
const FieldMatcher& matcher) {
return MakePolymorphicMatcher(internal::FieldMatcher<Class, FieldType>(
field_name, field, MatcherCast<const FieldType&>(matcher)));
}
// Creates a matcher that matches an object whose given property // Creates a matcher that matches an object whose given property
// matches 'matcher'. For example, // matches 'matcher'. For example,
// Property(&Foo::str, StartsWith("hi")) // Property(&Foo::str, StartsWith("hi"))
@ -4005,6 +4396,21 @@ Property(PropertyType (Class::*property)() const,
// to compile where bar() returns an int32 and m is a matcher for int64. // to compile where bar() returns an int32 and m is a matcher for int64.
} }
// Same as Property() above, but also takes the name of the property to provide
// better error messages.
template <typename Class, typename PropertyType, typename PropertyMatcher>
inline PolymorphicMatcher<internal::PropertyMatcher<
Class, PropertyType, PropertyType (Class::*)() const> >
Property(const std::string& property_name,
PropertyType (Class::*property)() const,
const PropertyMatcher& matcher) {
return MakePolymorphicMatcher(
internal::PropertyMatcher<Class, PropertyType,
PropertyType (Class::*)() const>(
property_name, property,
MatcherCast<GTEST_REFERENCE_TO_CONST_(PropertyType)>(matcher)));
}
#if GTEST_LANG_CXX11 #if GTEST_LANG_CXX11
// The same as above but for reference-qualified member functions. // The same as above but for reference-qualified member functions.
template <typename Class, typename PropertyType, typename PropertyMatcher> template <typename Class, typename PropertyType, typename PropertyMatcher>
@ -4033,6 +4439,7 @@ Property(PropertyType (Class::*property)() const &,
// concurrent access. // concurrent access.
// * If it is a function object, it has to define type result_type. // * If it is a function object, it has to define type result_type.
// We recommend deriving your functor classes from std::unary_function. // We recommend deriving your functor classes from std::unary_function.
//
template <typename Callable, typename ResultOfMatcher> template <typename Callable, typename ResultOfMatcher>
internal::ResultOfMatcher<Callable> ResultOf( internal::ResultOfMatcher<Callable> ResultOf(
Callable callable, const ResultOfMatcher& matcher) { Callable callable, const ResultOfMatcher& matcher) {
@ -4123,53 +4530,53 @@ inline PolymorphicMatcher<internal::MatchesRegexMatcher> ContainsRegex(
// Wide string matchers. // Wide string matchers.
// Matches a string equal to str. // Matches a string equal to str.
inline PolymorphicMatcher<internal::StrEqualityMatcher<internal::wstring> > inline PolymorphicMatcher<internal::StrEqualityMatcher<std::wstring> > StrEq(
StrEq(const internal::wstring& str) { const std::wstring& str) {
return MakePolymorphicMatcher(internal::StrEqualityMatcher<internal::wstring>( return MakePolymorphicMatcher(
str, true, true)); internal::StrEqualityMatcher<std::wstring>(str, true, true));
} }
// Matches a string not equal to str. // Matches a string not equal to str.
inline PolymorphicMatcher<internal::StrEqualityMatcher<internal::wstring> > inline PolymorphicMatcher<internal::StrEqualityMatcher<std::wstring> > StrNe(
StrNe(const internal::wstring& str) { const std::wstring& str) {
return MakePolymorphicMatcher(internal::StrEqualityMatcher<internal::wstring>( return MakePolymorphicMatcher(
str, false, true)); internal::StrEqualityMatcher<std::wstring>(str, false, true));
} }
// Matches a string equal to str, ignoring case. // Matches a string equal to str, ignoring case.
inline PolymorphicMatcher<internal::StrEqualityMatcher<internal::wstring> > inline PolymorphicMatcher<internal::StrEqualityMatcher<std::wstring> >
StrCaseEq(const internal::wstring& str) { StrCaseEq(const std::wstring& str) {
return MakePolymorphicMatcher(internal::StrEqualityMatcher<internal::wstring>( return MakePolymorphicMatcher(
str, true, false)); internal::StrEqualityMatcher<std::wstring>(str, true, false));
} }
// Matches a string not equal to str, ignoring case. // Matches a string not equal to str, ignoring case.
inline PolymorphicMatcher<internal::StrEqualityMatcher<internal::wstring> > inline PolymorphicMatcher<internal::StrEqualityMatcher<std::wstring> >
StrCaseNe(const internal::wstring& str) { StrCaseNe(const std::wstring& str) {
return MakePolymorphicMatcher(internal::StrEqualityMatcher<internal::wstring>( return MakePolymorphicMatcher(
str, false, false)); internal::StrEqualityMatcher<std::wstring>(str, false, false));
} }
// Creates a matcher that matches any wstring, std::wstring, or C wide string // Creates a matcher that matches any ::wstring, std::wstring, or C wide string
// that contains the given substring. // that contains the given substring.
inline PolymorphicMatcher<internal::HasSubstrMatcher<internal::wstring> > inline PolymorphicMatcher<internal::HasSubstrMatcher<std::wstring> > HasSubstr(
HasSubstr(const internal::wstring& substring) { const std::wstring& substring) {
return MakePolymorphicMatcher(internal::HasSubstrMatcher<internal::wstring>( return MakePolymorphicMatcher(
substring)); internal::HasSubstrMatcher<std::wstring>(substring));
} }
// Matches a string that starts with 'prefix' (case-sensitive). // Matches a string that starts with 'prefix' (case-sensitive).
inline PolymorphicMatcher<internal::StartsWithMatcher<internal::wstring> > inline PolymorphicMatcher<internal::StartsWithMatcher<std::wstring> >
StartsWith(const internal::wstring& prefix) { StartsWith(const std::wstring& prefix) {
return MakePolymorphicMatcher(internal::StartsWithMatcher<internal::wstring>( return MakePolymorphicMatcher(
prefix)); internal::StartsWithMatcher<std::wstring>(prefix));
} }
// Matches a string that ends with 'suffix' (case-sensitive). // Matches a string that ends with 'suffix' (case-sensitive).
inline PolymorphicMatcher<internal::EndsWithMatcher<internal::wstring> > inline PolymorphicMatcher<internal::EndsWithMatcher<std::wstring> > EndsWith(
EndsWith(const internal::wstring& suffix) { const std::wstring& suffix) {
return MakePolymorphicMatcher(internal::EndsWithMatcher<internal::wstring>( return MakePolymorphicMatcher(
suffix)); internal::EndsWithMatcher<std::wstring>(suffix));
} }
#endif // GTEST_HAS_GLOBAL_WSTRING || GTEST_HAS_STD_WSTRING #endif // GTEST_HAS_GLOBAL_WSTRING || GTEST_HAS_STD_WSTRING
@ -4198,6 +4605,58 @@ inline internal::Lt2Matcher Lt() { return internal::Lt2Matcher(); }
// first field != the second field. // first field != the second field.
inline internal::Ne2Matcher Ne() { return internal::Ne2Matcher(); } inline internal::Ne2Matcher Ne() { return internal::Ne2Matcher(); }
// Creates a polymorphic matcher that matches a 2-tuple where
// FloatEq(first field) matches the second field.
inline internal::FloatingEq2Matcher<float> FloatEq() {
return internal::FloatingEq2Matcher<float>();
}
// Creates a polymorphic matcher that matches a 2-tuple where
// DoubleEq(first field) matches the second field.
inline internal::FloatingEq2Matcher<double> DoubleEq() {
return internal::FloatingEq2Matcher<double>();
}
// Creates a polymorphic matcher that matches a 2-tuple where
// FloatEq(first field) matches the second field with NaN equality.
inline internal::FloatingEq2Matcher<float> NanSensitiveFloatEq() {
return internal::FloatingEq2Matcher<float>(true);
}
// Creates a polymorphic matcher that matches a 2-tuple where
// DoubleEq(first field) matches the second field with NaN equality.
inline internal::FloatingEq2Matcher<double> NanSensitiveDoubleEq() {
return internal::FloatingEq2Matcher<double>(true);
}
// Creates a polymorphic matcher that matches a 2-tuple where
// FloatNear(first field, max_abs_error) matches the second field.
inline internal::FloatingEq2Matcher<float> FloatNear(float max_abs_error) {
return internal::FloatingEq2Matcher<float>(max_abs_error);
}
// Creates a polymorphic matcher that matches a 2-tuple where
// DoubleNear(first field, max_abs_error) matches the second field.
inline internal::FloatingEq2Matcher<double> DoubleNear(double max_abs_error) {
return internal::FloatingEq2Matcher<double>(max_abs_error);
}
// Creates a polymorphic matcher that matches a 2-tuple where
// FloatNear(first field, max_abs_error) matches the second field with NaN
// equality.
inline internal::FloatingEq2Matcher<float> NanSensitiveFloatNear(
float max_abs_error) {
return internal::FloatingEq2Matcher<float>(max_abs_error, true);
}
// Creates a polymorphic matcher that matches a 2-tuple where
// DoubleNear(first field, max_abs_error) matches the second field with NaN
// equality.
inline internal::FloatingEq2Matcher<double> NanSensitiveDoubleNear(
double max_abs_error) {
return internal::FloatingEq2Matcher<double>(max_abs_error, true);
}
// Creates a matcher that matches any value of type T that m doesn't // Creates a matcher that matches any value of type T that m doesn't
// match. // match.
template <typename InnerMatcher> template <typename InnerMatcher>
@ -4575,6 +5034,28 @@ inline bool ExplainMatchResult(
return SafeMatcherCast<const T&>(matcher).MatchAndExplain(value, listener); return SafeMatcherCast<const T&>(matcher).MatchAndExplain(value, listener);
} }
// Returns a string representation of the given matcher. Useful for description
// strings of matchers defined using MATCHER_P* macros that accept matchers as
// their arguments. For example:
//
// MATCHER_P(XAndYThat, matcher,
// "X that " + DescribeMatcher<int>(matcher, negation) +
// " and Y that " + DescribeMatcher<double>(matcher, negation)) {
// return ExplainMatchResult(matcher, arg.x(), result_listener) &&
// ExplainMatchResult(matcher, arg.y(), result_listener);
// }
template <typename T, typename M>
std::string DescribeMatcher(const M& matcher, bool negation = false) {
::std::stringstream ss;
Matcher<T> monomorphic_matcher = SafeMatcherCast<T>(matcher);
if (negation) {
monomorphic_matcher.DescribeNegationTo(&ss);
} else {
monomorphic_matcher.DescribeTo(&ss);
}
return ss.str();
}
#if GTEST_LANG_CXX11 #if GTEST_LANG_CXX11
// Define variadic matcher versions. They are overloaded in // Define variadic matcher versions. They are overloaded in
// gmock-generated-matchers.h for the cases supported by pre C++11 compilers. // gmock-generated-matchers.h for the cases supported by pre C++11 compilers.
@ -4600,6 +5081,28 @@ inline internal::AnyOfMatcher<Args...> AnyOf(const Args&... matchers) {
template <typename InnerMatcher> template <typename InnerMatcher>
inline InnerMatcher AllArgs(const InnerMatcher& matcher) { return matcher; } inline InnerMatcher AllArgs(const InnerMatcher& matcher) { return matcher; }
// Returns a matcher that matches the value of an optional<> type variable.
// The matcher implementation only uses '!arg' and requires that the optional<>
// type has a 'value_type' member type and that '*arg' is of type 'value_type'
// and is printable using 'PrintToString'. It is compatible with
// std::optional/std::experimental::optional.
// Note that to compare an optional type variable against nullopt you should
// use Eq(nullopt) and not Optional(Eq(nullopt)). The latter implies that the
// optional value contains an optional itself.
template <typename ValueMatcher>
inline internal::OptionalMatcher<ValueMatcher> Optional(
const ValueMatcher& value_matcher) {
return internal::OptionalMatcher<ValueMatcher>(value_matcher);
}
// Returns a matcher that matches the value of a absl::any type variable.
template <typename T>
PolymorphicMatcher<internal::any_cast_matcher::AnyCastMatcher<T> > AnyWith(
const Matcher<const T&>& matcher) {
return MakePolymorphicMatcher(
internal::any_cast_matcher::AnyCastMatcher<T>(matcher));
}
// Returns a matcher that matches the value of a variant<> type variable. // Returns a matcher that matches the value of a variant<> type variable.
// The matcher implementation uses ADL to find the holds_alternative and get // The matcher implementation uses ADL to find the holds_alternative and get
// functions. // functions.
@ -4626,4 +5129,5 @@ PolymorphicMatcher<internal::variant_matcher::VariantMatcher<T> > VariantWith(
// We must include this header at the end to make sure it can use the // We must include this header at the end to make sure it can use the
// declarations from this file. // declarations from this file.
#include "gmock/internal/custom/gmock-matchers.h" #include "gmock/internal/custom/gmock-matchers.h"
#endif // GMOCK_INCLUDE_GMOCK_GMOCK_MATCHERS_H_ #endif // GMOCK_INCLUDE_GMOCK_GMOCK_MATCHERS_H_

View File

@ -33,7 +33,6 @@
// //
// Adds google3 callback support to CallableTraits. // Adds google3 callback support to CallableTraits.
// //
#ifndef GMOCK_INCLUDE_GMOCK_INTERNAL_CUSTOM_CALLBACK_MATCHERS_H_ #ifndef GMOCK_INCLUDE_GMOCK_INTERNAL_CUSTOM_GMOCK_MATCHERS_H_
#define GMOCK_INCLUDE_GMOCK_INTERNAL_CUSTOM_CALLBACK_MATCHERS_H_ #define GMOCK_INCLUDE_GMOCK_INTERNAL_CUSTOM_GMOCK_MATCHERS_H_
#endif // GMOCK_INCLUDE_GMOCK_INTERNAL_CUSTOM_GMOCK_MATCHERS_H_
#endif // GMOCK_INCLUDE_GMOCK_INTERNAL_CUSTOM_CALLBACK_MATCHERS_H_

View File

@ -117,9 +117,11 @@ struct LinkedPtrLessThan {
// To gcc, // To gcc,
// wchar_t == signed wchar_t != unsigned wchar_t == unsigned int // wchar_t == signed wchar_t != unsigned wchar_t == unsigned int
#ifdef __GNUC__ #ifdef __GNUC__
#if !defined(__WCHAR_UNSIGNED__)
// signed/unsigned wchar_t are valid types. // signed/unsigned wchar_t are valid types.
# define GMOCK_HAS_SIGNED_WCHAR_T_ 1 # define GMOCK_HAS_SIGNED_WCHAR_T_ 1
#endif #endif
#endif
// In what follows, we use the term "kind" to indicate whether a type // In what follows, we use the term "kind" to indicate whether a type
// is bool, an integer type (excluding bool), a floating-point type, // is bool, an integer type (excluding bool), a floating-point type,

View File

@ -70,8 +70,8 @@ GTEST_API_ std::string JoinAsTuple(const Strings& fields) {
// words. Each maximum substring of the form [A-Za-z][a-z]*|\d+ is // words. Each maximum substring of the form [A-Za-z][a-z]*|\d+ is
// treated as one word. For example, both "FooBar123" and // treated as one word. For example, both "FooBar123" and
// "foo_bar_123" are converted to "foo bar 123". // "foo_bar_123" are converted to "foo bar 123".
GTEST_API_ string ConvertIdentifierNameToWords(const char* id_name) { GTEST_API_ std::string ConvertIdentifierNameToWords(const char* id_name) {
string result; std::string result;
char prev_char = '\0'; char prev_char = '\0';
for (const char* p = id_name; *p != '\0'; prev_char = *(p++)) { for (const char* p = id_name; *p != '\0'; prev_char = *(p++)) {
// We don't care about the current locale as the input is // We don't care about the current locale as the input is
@ -188,5 +188,15 @@ GTEST_API_ void Log(LogSeverity severity, const std::string& message,
std::cout << ::std::flush; std::cout << ::std::flush;
} }
void IllegalDoDefault(const char* file, int line) {
internal::Assert(
false, file, line,
"You are using DoDefault() inside a composite action like "
"DoAll() or WithArgs(). This is not supported for technical "
"reasons. Please instead spell out the default action, or "
"assign the default action to an Action variable and use "
"the variable in various places.");
}
} // namespace internal } // namespace internal
} // namespace testing } // namespace testing

View File

@ -44,60 +44,67 @@
namespace testing { namespace testing {
// Constructs a matcher that matches a const string& whose value is // Constructs a matcher that matches a const std::string& whose value is
// equal to s. // equal to s.
Matcher<const internal::string&>::Matcher(const internal::string& s) { Matcher<const std::string&>::Matcher(const std::string& s) { *this = Eq(s); }
*this = Eq(s);
#if GTEST_HAS_GLOBAL_STRING
// Constructs a matcher that matches a const std::string& whose value is
// equal to s.
Matcher<const std::string&>::Matcher(const ::string& s) {
*this = Eq(static_cast<std::string>(s));
}
#endif // GTEST_HAS_GLOBAL_STRING
// Constructs a matcher that matches a const std::string& whose value is
// equal to s.
Matcher<const std::string&>::Matcher(const char* s) {
*this = Eq(std::string(s));
} }
// Constructs a matcher that matches a const string& whose value is // Constructs a matcher that matches a std::string whose value is equal to
// equal to s. // s.
Matcher<const internal::string&>::Matcher(const char* s) { Matcher<std::string>::Matcher(const std::string& s) { *this = Eq(s); }
*this = Eq(internal::string(s));
#if GTEST_HAS_GLOBAL_STRING
// Constructs a matcher that matches a std::string whose value is equal to
// s.
Matcher<std::string>::Matcher(const ::string& s) {
*this = Eq(static_cast<std::string>(s));
} }
#endif // GTEST_HAS_GLOBAL_STRING
// Constructs a matcher that matches a std::string whose value is equal to
// s.
Matcher<std::string>::Matcher(const char* s) { *this = Eq(std::string(s)); }
#if GTEST_HAS_GLOBAL_STRING
// Constructs a matcher that matches a const ::string& whose value is
// equal to s.
Matcher<const ::string&>::Matcher(const std::string& s) {
*this = Eq(static_cast<::string>(s));
}
// Constructs a matcher that matches a const ::string& whose value is
// equal to s.
Matcher<const ::string&>::Matcher(const ::string& s) { *this = Eq(s); }
// Constructs a matcher that matches a const ::string& whose value is
// equal to s.
Matcher<const ::string&>::Matcher(const char* s) { *this = Eq(::string(s)); }
// Constructs a matcher that matches a ::string whose value is equal to s.
Matcher<::string>::Matcher(const std::string& s) {
*this = Eq(static_cast<::string>(s));
}
// Constructs a matcher that matches a ::string whose value is equal to s.
Matcher<::string>::Matcher(const ::string& s) { *this = Eq(s); }
// Constructs a matcher that matches a string whose value is equal to s. // Constructs a matcher that matches a string whose value is equal to s.
Matcher<internal::string>::Matcher(const internal::string& s) { *this = Eq(s); } Matcher<::string>::Matcher(const char* s) { *this = Eq(::string(s)); }
#endif // GTEST_HAS_GLOBAL_STRING
// Constructs a matcher that matches a string whose value is equal to s.
Matcher<internal::string>::Matcher(const char* s) {
*this = Eq(internal::string(s));
}
#if GTEST_HAS_STRING_PIECE_
// Constructs a matcher that matches a const StringPiece& whose value is
// equal to s.
Matcher<const StringPiece&>::Matcher(const internal::string& s) {
*this = Eq(s);
}
// Constructs a matcher that matches a const StringPiece& whose value is
// equal to s.
Matcher<const StringPiece&>::Matcher(const char* s) {
*this = Eq(internal::string(s));
}
// Constructs a matcher that matches a const StringPiece& whose value is
// equal to s.
Matcher<const StringPiece&>::Matcher(StringPiece s) {
*this = Eq(s.ToString());
}
// Constructs a matcher that matches a StringPiece whose value is equal to s.
Matcher<StringPiece>::Matcher(const internal::string& s) {
*this = Eq(s);
}
// Constructs a matcher that matches a StringPiece whose value is equal to s.
Matcher<StringPiece>::Matcher(const char* s) {
*this = Eq(internal::string(s));
}
// Constructs a matcher that matches a StringPiece whose value is equal to s.
Matcher<StringPiece>::Matcher(StringPiece s) {
*this = Eq(s.ToString());
}
#endif // GTEST_HAS_STRING_PIECE_
namespace internal { namespace internal {

View File

@ -136,8 +136,8 @@ static bool ParseGoogleMockIntFlag(const char* str, const char* flag,
if (value_str == NULL) return false; if (value_str == NULL) return false;
// Sets *value to the value of the flag. // Sets *value to the value of the flag.
*value = atoi(value_str); return ParseInt32(Message() << "The value of flag --" << flag,
return true; value_str, value);
} }
// The internal implementation of InitGoogleMock(). // The internal implementation of InitGoogleMock().

View File

@ -107,7 +107,11 @@ TEST(BuiltInDefaultValueTest, IsZeroForNumericTypes) {
EXPECT_EQ(0, BuiltInDefaultValue<signed wchar_t>::Get()); EXPECT_EQ(0, BuiltInDefaultValue<signed wchar_t>::Get());
#endif #endif
#if GMOCK_WCHAR_T_IS_NATIVE_ #if GMOCK_WCHAR_T_IS_NATIVE_
#if !defined(__WCHAR_UNSIGNED__)
EXPECT_EQ(0, BuiltInDefaultValue<wchar_t>::Get()); EXPECT_EQ(0, BuiltInDefaultValue<wchar_t>::Get());
#else
EXPECT_EQ(0U, BuiltInDefaultValue<wchar_t>::Get());
#endif
#endif #endif
EXPECT_EQ(0U, BuiltInDefaultValue<unsigned short>::Get()); // NOLINT EXPECT_EQ(0U, BuiltInDefaultValue<unsigned short>::Get()); // NOLINT
EXPECT_EQ(0, BuiltInDefaultValue<signed short>::Get()); // NOLINT EXPECT_EQ(0, BuiltInDefaultValue<signed short>::Get()); // NOLINT
@ -214,7 +218,7 @@ class MyNonDefaultConstructible {
int value_; int value_;
}; };
#if GTEST_HAS_STD_TYPE_TRAITS_ #if GTEST_LANG_CXX11
TEST(BuiltInDefaultValueTest, ExistsForDefaultConstructibleType) { TEST(BuiltInDefaultValueTest, ExistsForDefaultConstructibleType) {
EXPECT_TRUE(BuiltInDefaultValue<MyDefaultConstructible>::Exists()); EXPECT_TRUE(BuiltInDefaultValue<MyDefaultConstructible>::Exists());
@ -224,7 +228,7 @@ TEST(BuiltInDefaultValueTest, IsDefaultConstructedForDefaultConstructibleType) {
EXPECT_EQ(42, BuiltInDefaultValue<MyDefaultConstructible>::Get().value()); EXPECT_EQ(42, BuiltInDefaultValue<MyDefaultConstructible>::Get().value());
} }
#endif // GTEST_HAS_STD_TYPE_TRAITS_ #endif // GTEST_LANG_CXX11
TEST(BuiltInDefaultValueTest, DoesNotExistForNonDefaultConstructibleType) { TEST(BuiltInDefaultValueTest, DoesNotExistForNonDefaultConstructibleType) {
EXPECT_FALSE(BuiltInDefaultValue<MyNonDefaultConstructible>::Exists()); EXPECT_FALSE(BuiltInDefaultValue<MyNonDefaultConstructible>::Exists());

View File

@ -44,7 +44,15 @@
#include "gmock/internal/gmock-port.h" #include "gmock/internal/gmock-port.h"
#include "gtest/gtest.h" #include "gtest/gtest.h"
#include "gtest/gtest-spi.h" #include "gtest/gtest-spi.h"
// Indicates that this translation unit is part of Google Test's
// implementation. It must come before gtest-internal-inl.h is
// included, or there will be a compiler error. This trick is to
// prevent a user from accidentally including gtest-internal-inl.h in
// their code.
#define GTEST_IMPLEMENTATION_ 1
#include "src/gtest-internal-inl.h" #include "src/gtest-internal-inl.h"
#undef GTEST_IMPLEMENTATION_
#if GTEST_OS_CYGWIN #if GTEST_OS_CYGWIN
# include <sys/types.h> // For ssize_t. NOLINT # include <sys/types.h> // For ssize_t. NOLINT
@ -61,6 +69,26 @@ namespace internal {
namespace { namespace {
TEST(JoinAsTupleTest, JoinsEmptyTuple) {
EXPECT_EQ("", JoinAsTuple(Strings()));
}
TEST(JoinAsTupleTest, JoinsOneTuple) {
const char* fields[] = {"1"};
EXPECT_EQ("1", JoinAsTuple(Strings(fields, fields + 1)));
}
TEST(JoinAsTupleTest, JoinsTwoTuple) {
const char* fields[] = {"1", "a"};
EXPECT_EQ("(1, a)", JoinAsTuple(Strings(fields, fields + 2)));
}
TEST(JoinAsTupleTest, JoinsTenTuple) {
const char* fields[] = {"1", "2", "3", "4", "5", "6", "7", "8", "9", "10"};
EXPECT_EQ("(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)",
JoinAsTuple(Strings(fields, fields + 10)));
}
TEST(ConvertIdentifierNameToWordsTest, WorksWhenNameContainsNoWord) { TEST(ConvertIdentifierNameToWordsTest, WorksWhenNameContainsNoWord) {
EXPECT_EQ("", ConvertIdentifierNameToWords("")); EXPECT_EQ("", ConvertIdentifierNameToWords(""));
EXPECT_EQ("", ConvertIdentifierNameToWords("_")); EXPECT_EQ("", ConvertIdentifierNameToWords("_"));

View File

@ -90,8 +90,10 @@
// Field // Field
// Property // Property
// ResultOf(function) // ResultOf(function)
// ResultOf(callback)
// Pointee // Pointee
// Truly(predicate) // Truly(predicate)
// AddressSatisfies
// AllOf // AllOf
// AnyOf // AnyOf
// Not // Not

View File

@ -47,6 +47,7 @@ using testing::NaggyMock;
using testing::Ref; using testing::Ref;
using testing::Return; using testing::Return;
using testing::Sequence; using testing::Sequence;
using testing::Value;
class MockFoo { class MockFoo {
public: public:
@ -268,6 +269,10 @@ TEST_F(GMockOutputTest, CatchesLeakedMocks) {
// Both foo1 and foo2 are deliberately leaked. // Both foo1 and foo2 are deliberately leaked.
} }
MATCHER_P2(IsPair, first, second, "") {
return Value(arg.first, first) && Value(arg.second, second);
}
void TestCatchesLeakedMocksInAdHocTests() { void TestCatchesLeakedMocksInAdHocTests() {
MockFoo* foo = new MockFoo; MockFoo* foo = new MockFoo;
@ -280,7 +285,6 @@ void TestCatchesLeakedMocksInAdHocTests() {
int main(int argc, char **argv) { int main(int argc, char **argv) {
testing::InitGoogleMock(&argc, argv); testing::InitGoogleMock(&argc, argv);
// Ensures that the tests pass no matter what value of // Ensures that the tests pass no matter what value of
// --gmock_catch_leaked_mocks and --gmock_verbose the user specifies. // --gmock_catch_leaked_mocks and --gmock_verbose the user specifies.
testing::GMOCK_FLAG(catch_leaked_mocks) = true; testing::GMOCK_FLAG(catch_leaked_mocks) = true;

View File

@ -1371,8 +1371,6 @@ internal::CartesianProductHolder10<Generator1, Generator2, Generator3,
} }
# endif // GTEST_HAS_COMBINE # endif // GTEST_HAS_COMBINE
# define TEST_P(test_case_name, test_name) \ # define TEST_P(test_case_name, test_name) \
class GTEST_TEST_CLASS_NAME_(test_case_name, test_name) \ class GTEST_TEST_CLASS_NAME_(test_case_name, test_name) \
: public test_case_name { \ : public test_case_name { \
@ -1386,8 +1384,8 @@ internal::CartesianProductHolder10<Generator1, Generator2, Generator3,
#test_case_name, \ #test_case_name, \
::testing::internal::CodeLocation(\ ::testing::internal::CodeLocation(\
__FILE__, __LINE__))->AddTestPattern(\ __FILE__, __LINE__))->AddTestPattern(\
#test_case_name, \ GTEST_STRINGIFY_(test_case_name), \
#test_name, \ GTEST_STRINGIFY_(test_name), \
new ::testing::internal::TestMetaFactory< \ new ::testing::internal::TestMetaFactory< \
GTEST_TEST_CLASS_NAME_(\ GTEST_TEST_CLASS_NAME_(\
test_case_name, test_name)>()); \ test_case_name, test_name)>()); \

View File

@ -436,8 +436,6 @@ internal::CartesianProductHolder$i<$for j, [[Generator$j]]> Combine(
]] ]]
# endif // GTEST_HAS_COMBINE # endif // GTEST_HAS_COMBINE
# define TEST_P(test_case_name, test_name) \ # define TEST_P(test_case_name, test_name) \
class GTEST_TEST_CLASS_NAME_(test_case_name, test_name) \ class GTEST_TEST_CLASS_NAME_(test_case_name, test_name) \
: public test_case_name { \ : public test_case_name { \
@ -451,8 +449,8 @@ internal::CartesianProductHolder$i<$for j, [[Generator$j]]> Combine(
#test_case_name, \ #test_case_name, \
::testing::internal::CodeLocation(\ ::testing::internal::CodeLocation(\
__FILE__, __LINE__))->AddTestPattern(\ __FILE__, __LINE__))->AddTestPattern(\
#test_case_name, \ GTEST_STRINGIFY_(test_case_name), \
#test_name, \ GTEST_STRINGIFY_(test_name), \
new ::testing::internal::TestMetaFactory< \ new ::testing::internal::TestMetaFactory< \
GTEST_TEST_CLASS_NAME_(\ GTEST_TEST_CLASS_NAME_(\
test_case_name, test_name)>()); \ test_case_name, test_name)>()); \

View File

@ -509,17 +509,19 @@ void PrintTo(const T& value, ::std::ostream* os) {
// function pointers so that the `*os << p` in the object pointer overload // function pointers so that the `*os << p` in the object pointer overload
// doesn't cause that warning either. // doesn't cause that warning either.
DefaultPrintTo( DefaultPrintTo(
WrapPrinterType< WrapPrinterType <
(sizeof(IsContainerTest<T>(0)) == sizeof(IsContainer)) && !IsRecursiveContainer<T>::value (sizeof(IsContainerTest<T>(0)) == sizeof(IsContainer)) &&
? kPrintContainer : !is_pointer<T>::value !IsRecursiveContainer<T>::value
? kPrintOther ? kPrintContainer
: !is_pointer<T>::value
? kPrintOther
#if GTEST_LANG_CXX11 #if GTEST_LANG_CXX11
: std::is_function<typename std::remove_pointer<T>::type>::value : std::is_function<typename std::remove_pointer<T>::type>::value
#else #else
: !internal::ImplicitlyConvertible<T, const void*>::value : !internal::ImplicitlyConvertible<T, const void*>::value
#endif #endif
? kPrintFunctionPointer ? kPrintFunctionPointer
: kPrintPointer>(), : kPrintPointer > (),
value, os); value, os);
} }

View File

@ -217,14 +217,18 @@ GTEST_API_ bool ExitedUnsuccessfully(int exit_status);
// can be streamed. // can be streamed.
// This macro is for implementing ASSERT/EXPECT_DEBUG_DEATH when compiled in // This macro is for implementing ASSERT/EXPECT_DEBUG_DEATH when compiled in
// NDEBUG mode. In this case we need the statements to be executed, the regex is // NDEBUG mode. In this case we need the statements to be executed and the macro
// ignored, and the macro must accept a streamed message even though the message // must accept a streamed message even though the message is never printed.
// is never printed. // The regex object is not evaluated, but it is used to prevent "unused"
# define GTEST_EXECUTE_STATEMENT_(statement, regex) \ // warnings and to avoid an expression that doesn't compile in debug mode.
GTEST_AMBIGUOUS_ELSE_BLOCKER_ \ #define GTEST_EXECUTE_STATEMENT_(statement, regex) \
if (::testing::internal::AlwaysTrue()) { \ GTEST_AMBIGUOUS_ELSE_BLOCKER_ \
GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \ if (::testing::internal::AlwaysTrue()) { \
} else \ GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \
} else if (!::testing::internal::AlwaysTrue()) { \
const ::testing::internal::RE& gtest_regex = (regex); \
static_cast<void>(gtest_regex); \
} else \
::testing::Message() ::testing::Message()
// A class representing the parsed contents of the // A class representing the parsed contents of the

View File

@ -75,6 +75,9 @@
#define GTEST_CONCAT_TOKEN_(foo, bar) GTEST_CONCAT_TOKEN_IMPL_(foo, bar) #define GTEST_CONCAT_TOKEN_(foo, bar) GTEST_CONCAT_TOKEN_IMPL_(foo, bar)
#define GTEST_CONCAT_TOKEN_IMPL_(foo, bar) foo ## bar #define GTEST_CONCAT_TOKEN_IMPL_(foo, bar) foo ## bar
// Stringifies its argument.
#define GTEST_STRINGIFY_(name) #name
class ProtocolMessage; class ProtocolMessage;
namespace proto2 { class Message; } namespace proto2 { class Message; }
@ -872,8 +875,11 @@ struct IsAProtocolMessage
// a container class by checking the type of IsContainerTest<C>(0). // a container class by checking the type of IsContainerTest<C>(0).
// The value of the expression is insignificant. // The value of the expression is insignificant.
// //
// Note that we look for both C::iterator and C::const_iterator. The // In C++11 mode we check the existence of a const_iterator and that an
// reason is that C++ injects the name of a class as a member of the // iterator is properly implemented for the container.
//
// For pre-C++11 that we look for both C::iterator and C::const_iterator.
// The reason is that C++ injects the name of a class as a member of the
// class itself (e.g. you can refer to class iterator as either // class itself (e.g. you can refer to class iterator as either
// 'iterator' or 'iterator::iterator'). If we look for C::iterator // 'iterator' or 'iterator::iterator'). If we look for C::iterator
// only, for example, we would mistakenly think that a class named // only, for example, we would mistakenly think that a class named
@ -883,40 +889,94 @@ struct IsAProtocolMessage
// IsContainerTest(typename C::const_iterator*) and // IsContainerTest(typename C::const_iterator*) and
// IsContainerTest(...) doesn't work with Visual Age C++ and Sun C++. // IsContainerTest(...) doesn't work with Visual Age C++ and Sun C++.
typedef int IsContainer; typedef int IsContainer;
#if GTEST_LANG_CXX11
template <class C,
class Iterator = decltype(::std::declval<const C&>().begin()),
class = decltype(::std::declval<const C&>().end()),
class = decltype(++::std::declval<Iterator&>()),
class = decltype(*::std::declval<Iterator>()),
class = typename C::const_iterator>
IsContainer IsContainerTest(int /* dummy */) {
return 0;
}
#else
template <class C> template <class C>
IsContainer IsContainerTest(int /* dummy */, IsContainer IsContainerTest(int /* dummy */,
typename C::iterator* /* it */ = NULL, typename C::iterator* /* it */ = NULL,
typename C::const_iterator* /* const_it */ = NULL) { typename C::const_iterator* /* const_it */ = NULL) {
return 0; return 0;
} }
#endif // GTEST_LANG_CXX11
typedef char IsNotContainer; typedef char IsNotContainer;
template <class C> template <class C>
IsNotContainer IsContainerTest(long /* dummy */) { return '\0'; } IsNotContainer IsContainerTest(long /* dummy */) { return '\0'; }
template <typename C, bool = // Trait to detect whether a type T is a hash table.
sizeof(IsContainerTest<C>(0)) == sizeof(IsContainer) // The heuristic used is that the type contains an inner type `hasher` and does
> // not contain an inner type `reverse_iterator`.
// If the container is iterable in reverse, then order might actually matter.
template <typename T>
struct IsHashTable {
private:
template <typename U>
static char test(typename U::hasher*, typename U::reverse_iterator*);
template <typename U>
static int test(typename U::hasher*, ...);
template <typename U>
static char test(...);
public:
static const bool value = sizeof(test<T>(0, 0)) == sizeof(int);
};
template <typename T>
const bool IsHashTable<T>::value;
template<typename T>
struct VoidT {
typedef void value_type;
};
template <typename T, typename = void>
struct HasValueType : false_type {};
template <typename T>
struct HasValueType<T, VoidT<typename T::value_type> > : true_type {
};
template <typename C,
bool = sizeof(IsContainerTest<C>(0)) == sizeof(IsContainer),
bool = HasValueType<C>::value>
struct IsRecursiveContainerImpl; struct IsRecursiveContainerImpl;
template <typename C, bool HV>
struct IsRecursiveContainerImpl<C, false, HV> : public false_type {};
// Since the IsRecursiveContainerImpl depends on the IsContainerTest we need to
// obey the same inconsistencies as the IsContainerTest, namely check if
// something is a container is relying on only const_iterator in C++11 and
// is relying on both const_iterator and iterator otherwise
template <typename C> template <typename C>
struct IsRecursiveContainerImpl<C, false> : public false_type {}; struct IsRecursiveContainerImpl<C, true, false> : public false_type {};
template <typename C> template <typename C>
struct IsRecursiveContainerImpl<C, true> { struct IsRecursiveContainerImpl<C, true, true> {
typedef #if GTEST_LANG_CXX11
typename IteratorTraits<typename C::iterator>::value_type typedef typename IteratorTraits<typename C::const_iterator>::value_type
value_type; value_type;
#else
typedef typename IteratorTraits<typename C::iterator>::value_type value_type;
#endif
typedef is_same<value_type, C> type; typedef is_same<value_type, C> type;
}; };
// IsRecursiveContainer<Type> is a unary compile-time predicate that // IsRecursiveContainer<Type> is a unary compile-time predicate that
// evaluates whether C is a recursive container type. A recursive container // evaluates whether C is a recursive container type. A recursive container
// type is a container type whose value_type is equal to the container type // type is a container type whose value_type is equal to the container type
// itself. An example for a recursive container type is // itself. An example for a recursive container type is
// boost::filesystem::path, whose iterator has a value_type that is equal to // boost::filesystem::path, whose iterator has a value_type that is equal to
// boost::filesystem::path. // boost::filesystem::path.
template<typename C> template <typename C>
struct IsRecursiveContainer : public IsRecursiveContainerImpl<C>::type {}; struct IsRecursiveContainer : public IsRecursiveContainerImpl<C>::type {};
// EnableIf<condition>::type is void when 'Cond' is true, and // EnableIf<condition>::type is void when 'Cond' is true, and
@ -1215,4 +1275,3 @@ class GTEST_TEST_CLASS_NAME_(test_case_name, test_name) : public parent_class {\
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

@ -363,14 +363,14 @@
#if GTEST_STDLIB_CXX11 #if GTEST_STDLIB_CXX11
# define GTEST_HAS_STD_BEGIN_AND_END_ 1 # define GTEST_HAS_STD_BEGIN_AND_END_ 1
# define GTEST_HAS_STD_FORWARD_LIST_ 1 # define GTEST_HAS_STD_FORWARD_LIST_ 1
# if !defined(_MSC_VER) || (_MSC_FULL_VER >= 190023824) // works only with VS2015U2 and better # if !defined(_MSC_VER) || (_MSC_FULL_VER >= 190023824)
// works only with VS2015U2 and better
# define GTEST_HAS_STD_FUNCTION_ 1 # define GTEST_HAS_STD_FUNCTION_ 1
# endif # endif
# define GTEST_HAS_STD_INITIALIZER_LIST_ 1 # define GTEST_HAS_STD_INITIALIZER_LIST_ 1
# define GTEST_HAS_STD_MOVE_ 1 # define GTEST_HAS_STD_MOVE_ 1
# define GTEST_HAS_STD_SHARED_PTR_ 1
# define GTEST_HAS_STD_TYPE_TRAITS_ 1
# define GTEST_HAS_STD_UNIQUE_PTR_ 1 # define GTEST_HAS_STD_UNIQUE_PTR_ 1
# define GTEST_HAS_STD_SHARED_PTR_ 1
# define GTEST_HAS_UNORDERED_MAP_ 1 # define GTEST_HAS_UNORDERED_MAP_ 1
# define GTEST_HAS_UNORDERED_SET_ 1 # define GTEST_HAS_UNORDERED_SET_ 1
#endif #endif
@ -519,7 +519,7 @@ typedef struct _RTL_CRITICAL_SECTION GTEST_CRITICAL_SECTION;
# define GTEST_HAS_STD_STRING 1 # define GTEST_HAS_STD_STRING 1
#elif !GTEST_HAS_STD_STRING #elif !GTEST_HAS_STD_STRING
// The user told us that ::std::string isn't available. // The user told us that ::std::string isn't available.
# error "Google Test cannot be used where ::std::string isn't available." # error "::std::string isn't available."
#endif // !defined(GTEST_HAS_STD_STRING) #endif // !defined(GTEST_HAS_STD_STRING)
#ifndef GTEST_HAS_GLOBAL_STRING #ifndef GTEST_HAS_GLOBAL_STRING
@ -889,6 +889,12 @@ using ::std::tuple_size;
# define GTEST_ATTRIBUTE_UNUSED_ # define GTEST_ATTRIBUTE_UNUSED_
#endif #endif
#if GTEST_LANG_CXX11
# define GTEST_CXX11_EQUALS_DELETE_ = delete
#else // GTEST_LANG_CXX11
# define GTEST_CXX11_EQUALS_DELETE_
#endif // GTEST_LANG_CXX11
// Use this annotation before a function that takes a printf format string. // Use this annotation before a function that takes a printf format string.
#if (defined(__GNUC__) || defined(__clang__)) && !defined(COMPILER_ICC) #if (defined(__GNUC__) || defined(__clang__)) && !defined(COMPILER_ICC)
# if defined(__MINGW_PRINTF_FORMAT) # if defined(__MINGW_PRINTF_FORMAT)
@ -906,15 +912,16 @@ using ::std::tuple_size;
# define GTEST_ATTRIBUTE_PRINTF_(string_index, first_to_check) # define GTEST_ATTRIBUTE_PRINTF_(string_index, first_to_check)
#endif #endif
// A macro to disallow operator= // A macro to disallow operator=
// This should be used in the private: declarations for a class. // This should be used in the private: declarations for a class.
#define GTEST_DISALLOW_ASSIGN_(type)\ #define GTEST_DISALLOW_ASSIGN_(type) \
void operator=(type const &) void operator=(type const &) GTEST_CXX11_EQUALS_DELETE_
// A macro to disallow copy constructor and operator= // A macro to disallow copy constructor and operator=
// This should be used in the private: declarations for a class. // This should be used in the private: declarations for a class.
#define GTEST_DISALLOW_COPY_AND_ASSIGN_(type)\ #define GTEST_DISALLOW_COPY_AND_ASSIGN_(type) \
type(type const &);\ type(type const &) GTEST_CXX11_EQUALS_DELETE_; \
GTEST_DISALLOW_ASSIGN_(type) GTEST_DISALLOW_ASSIGN_(type)
// Tell the compiler to warn about unused return values for functions declared // Tell the compiler to warn about unused return values for functions declared
@ -975,13 +982,13 @@ using ::std::tuple_size;
# endif # endif
#elif __GNUC__ >= 4 || defined(__clang__) #elif __GNUC__ >= 4 || defined(__clang__)
# define GTEST_API_ __attribute__((visibility ("default"))) # define GTEST_API_ __attribute__((visibility ("default")))
#endif // _MSC_VER #endif // _MSC_VER
#endif // GTEST_API_ #endif // GTEST_API_
#ifndef GTEST_API_ #ifndef GTEST_API_
# define GTEST_API_ # define GTEST_API_
#endif // GTEST_API_ #endif // GTEST_API_
#ifndef GTEST_DEFAULT_DEATH_TEST_STYLE #ifndef GTEST_DEFAULT_DEATH_TEST_STYLE
# define GTEST_DEFAULT_DEATH_TEST_STYLE "fast" # define GTEST_DEFAULT_DEATH_TEST_STYLE "fast"
@ -995,10 +1002,12 @@ using ::std::tuple_size;
#endif #endif
// _LIBCPP_VERSION is defined by the libc++ library from the LLVM project. // _LIBCPP_VERSION is defined by the libc++ library from the LLVM project.
#if defined(__GLIBCXX__) || (defined(_LIBCPP_VERSION) && !defined(_MSC_VER)) #if !defined(GTEST_HAS_CXXABI_H_)
# define GTEST_HAS_CXXABI_H_ 1 # if defined(__GLIBCXX__) || (defined(_LIBCPP_VERSION) && !defined(_MSC_VER))
#else # define GTEST_HAS_CXXABI_H_ 1
# define GTEST_HAS_CXXABI_H_ 0 # else
# define GTEST_HAS_CXXABI_H_ 0
# endif
#endif #endif
// A function level attribute to disable checking for use of uninitialized // A function level attribute to disable checking for use of uninitialized
@ -1425,6 +1434,8 @@ template <typename T>
const T& move(const T& t) { const T& move(const T& t) {
return t; return t;
} }
template <typename T>
GTEST_ADD_REFERENCE_(T) forward(GTEST_ADD_REFERENCE_(T) t) { return t; }
template <typename T> template <typename T>
struct RvalueRef { struct RvalueRef {
@ -1537,14 +1548,18 @@ GTEST_API_ size_t GetFileSize(FILE* file);
GTEST_API_ std::string ReadEntireFile(FILE* file); GTEST_API_ std::string ReadEntireFile(FILE* file);
// All command line arguments. // All command line arguments.
GTEST_API_ const ::std::vector<testing::internal::string>& GetArgvs(); GTEST_API_ std::vector<std::string> GetArgvs();
#if GTEST_HAS_DEATH_TEST #if GTEST_HAS_DEATH_TEST
const ::std::vector<testing::internal::string>& GetInjectableArgvs(); std::vector<std::string> GetInjectableArgvs();
void SetInjectableArgvs(const ::std::vector<testing::internal::string>* // Deprecated: pass the args vector by value instead.
new_argvs); void SetInjectableArgvs(const std::vector<std::string>* new_argvs);
void SetInjectableArgvs(const std::vector<std::string>& new_argvs);
#if GTEST_HAS_GLOBAL_STRING
void SetInjectableArgvs(const std::vector< ::string>& new_argvs);
#endif // GTEST_HAS_GLOBAL_STRING
void ClearInjectableArgvs();
#endif // GTEST_HAS_DEATH_TEST #endif // GTEST_HAS_DEATH_TEST
@ -2325,6 +2340,7 @@ struct is_same : public false_type {};
template <typename T> template <typename T>
struct is_same<T, T> : public true_type {}; struct is_same<T, T> : public true_type {};
template <typename T> template <typename T>
struct is_pointer : public false_type {}; struct is_pointer : public false_type {};
@ -2336,6 +2352,7 @@ struct IteratorTraits {
typedef typename Iterator::value_type value_type; typedef typename Iterator::value_type value_type;
}; };
template <typename T> template <typename T>
struct IteratorTraits<T*> { struct IteratorTraits<T*> {
typedef T value_type; typedef T value_type;
@ -2631,15 +2648,15 @@ typedef TypeWithSize<8>::Int TimeInMillis; // Represents time in milliseconds.
# define GTEST_DECLARE_bool_(name) GTEST_API_ extern bool GTEST_FLAG(name) # define GTEST_DECLARE_bool_(name) GTEST_API_ extern bool GTEST_FLAG(name)
# define GTEST_DECLARE_int32_(name) \ # define GTEST_DECLARE_int32_(name) \
GTEST_API_ extern ::testing::internal::Int32 GTEST_FLAG(name) GTEST_API_ extern ::testing::internal::Int32 GTEST_FLAG(name)
#define GTEST_DECLARE_string_(name) \ # define GTEST_DECLARE_string_(name) \
GTEST_API_ extern ::std::string GTEST_FLAG(name) GTEST_API_ extern ::std::string GTEST_FLAG(name)
// Macros for defining flags. // Macros for defining flags.
#define GTEST_DEFINE_bool_(name, default_val, doc) \ # define GTEST_DEFINE_bool_(name, default_val, doc) \
GTEST_API_ bool GTEST_FLAG(name) = (default_val) GTEST_API_ bool GTEST_FLAG(name) = (default_val)
#define GTEST_DEFINE_int32_(name, default_val, doc) \ # define GTEST_DEFINE_int32_(name, default_val, doc) \
GTEST_API_ ::testing::internal::Int32 GTEST_FLAG(name) = (default_val) GTEST_API_ ::testing::internal::Int32 GTEST_FLAG(name) = (default_val)
#define GTEST_DEFINE_string_(name, default_val, doc) \ # define GTEST_DEFINE_string_(name, default_val, doc) \
GTEST_API_ ::std::string GTEST_FLAG(name) = (default_val) GTEST_API_ ::std::string GTEST_FLAG(name) = (default_val)
#endif // !defined(GTEST_DECLARE_bool_) #endif // !defined(GTEST_DECLARE_bool_)
@ -2662,10 +2679,10 @@ bool ParseInt32(const Message& src_text, const char* str, Int32* value);
// corresponding to the given Google Test flag. // corresponding to the given Google Test flag.
bool BoolFromGTestEnv(const char* flag, bool default_val); bool BoolFromGTestEnv(const char* flag, bool default_val);
GTEST_API_ Int32 Int32FromGTestEnv(const char* flag, Int32 default_val); GTEST_API_ Int32 Int32FromGTestEnv(const char* flag, Int32 default_val);
std::string StringFromGTestEnv(const char* flag, const char* default_val); std::string OutputFlagAlsoCheckEnvVar();
const char* StringFromGTestEnv(const char* flag, const char* default_val);
} // namespace internal } // namespace internal
} // namespace testing } // namespace testing
#endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PORT_H_ #endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PORT_H_

View File

@ -115,10 +115,9 @@ def HeaderPreamble(n):
#ifndef GTEST_INCLUDE_GTEST_GTEST_PRED_IMPL_H_ #ifndef GTEST_INCLUDE_GTEST_GTEST_PRED_IMPL_H_
#define GTEST_INCLUDE_GTEST_GTEST_PRED_IMPL_H_ #define GTEST_INCLUDE_GTEST_GTEST_PRED_IMPL_H_
// Makes sure this header is not included before gtest.h. #include "gtest/gtest.h"
#ifndef GTEST_INCLUDE_GTEST_GTEST_H_
# error Do not include gtest_pred_impl.h directly. Include gtest.h instead. namespace testing {
#endif // GTEST_INCLUDE_GTEST_GTEST_H_
// This header implements a family of generic predicate assertion // This header implements a family of generic predicate assertion
// macros: // macros:
@ -295,16 +294,17 @@ def HeaderPostamble():
return """ return """
} // namespace testing
#endif // GTEST_INCLUDE_GTEST_GTEST_PRED_IMPL_H_ #endif // GTEST_INCLUDE_GTEST_GTEST_PRED_IMPL_H_
""" """
def GenerateFile(path, content): def GenerateFile(path, content):
"""Given a file path and a content string, overwrites it with the """Given a file path and a content string
given content.""" overwrites it with the given content.
"""
print 'Updating file %s . . .' % path print 'Updating file %s . . .' % path
f = file(path, 'w+') f = file(path, 'w+')
print >>f, content, print >>f, content,
f.close() f.close()
@ -314,8 +314,8 @@ def GenerateFile(path, content):
def GenerateHeader(n): def GenerateHeader(n):
"""Given the maximum arity n, updates the header file that implements """Given the maximum arity n, updates the header file that implements
the predicate assertions.""" the predicate assertions.
"""
GenerateFile(HEADER, GenerateFile(HEADER,
HeaderPreamble(n) HeaderPreamble(n)
+ ''.join([ImplementationForArity(i) for i in OneTo(n)]) + ''.join([ImplementationForArity(i) for i in OneTo(n)])

View File

@ -1081,22 +1081,36 @@ std::string ReadEntireFile(FILE* file) {
} }
#if GTEST_HAS_DEATH_TEST #if GTEST_HAS_DEATH_TEST
static const std::vector<std::string>* g_injected_test_argvs = NULL; // Owned.
static const ::std::vector<testing::internal::string>* g_injected_test_argvs = std::vector<std::string> GetInjectableArgvs() {
NULL; // Owned.
void SetInjectableArgvs(const ::std::vector<testing::internal::string>* argvs) {
if (g_injected_test_argvs != argvs)
delete g_injected_test_argvs;
g_injected_test_argvs = argvs;
}
const ::std::vector<testing::internal::string>& GetInjectableArgvs() {
if (g_injected_test_argvs != NULL) { if (g_injected_test_argvs != NULL) {
return *g_injected_test_argvs; return *g_injected_test_argvs;
} }
return GetArgvs(); return GetArgvs();
} }
void SetInjectableArgvs(const std::vector<std::string>* new_argvs) {
if (g_injected_test_argvs != new_argvs) delete g_injected_test_argvs;
g_injected_test_argvs = new_argvs;
}
void SetInjectableArgvs(const std::vector<std::string>& new_argvs) {
SetInjectableArgvs(
new std::vector<std::string>(new_argvs.begin(), new_argvs.end()));
}
#if GTEST_HAS_GLOBAL_STRING
void SetInjectableArgvs(const std::vector< ::string>& new_argvs) {
SetInjectableArgvs(
new std::vector<std::string>(new_argvs.begin(), new_argvs.end()));
}
#endif // GTEST_HAS_GLOBAL_STRING
void ClearInjectableArgvs() {
delete g_injected_test_argvs;
g_injected_test_argvs = NULL;
}
#endif // GTEST_HAS_DEATH_TEST #endif // GTEST_HAS_DEATH_TEST
#if GTEST_OS_WINDOWS_MOBILE #if GTEST_OS_WINDOWS_MOBILE
@ -1171,11 +1185,12 @@ bool ParseInt32(const Message& src_text, const char* str, Int32* value) {
bool BoolFromGTestEnv(const char* flag, bool default_value) { bool BoolFromGTestEnv(const char* flag, bool default_value) {
#if defined(GTEST_GET_BOOL_FROM_ENV_) #if defined(GTEST_GET_BOOL_FROM_ENV_)
return GTEST_GET_BOOL_FROM_ENV_(flag, default_value); return GTEST_GET_BOOL_FROM_ENV_(flag, default_value);
#endif // defined(GTEST_GET_BOOL_FROM_ENV_) #else
const std::string env_var = FlagToEnvVar(flag); const std::string env_var = FlagToEnvVar(flag);
const char* const string_value = posix::GetEnv(env_var.c_str()); const char* const string_value = posix::GetEnv(env_var.c_str());
return string_value == NULL ? return string_value == NULL ?
default_value : strcmp(string_value, "0") != 0; default_value : strcmp(string_value, "0") != 0;
#endif // defined(GTEST_GET_BOOL_FROM_ENV_)
} }
// Reads and returns a 32-bit integer stored in the environment // Reads and returns a 32-bit integer stored in the environment
@ -1184,7 +1199,7 @@ bool BoolFromGTestEnv(const char* flag, bool default_value) {
Int32 Int32FromGTestEnv(const char* flag, Int32 default_value) { Int32 Int32FromGTestEnv(const char* flag, Int32 default_value) {
#if defined(GTEST_GET_INT32_FROM_ENV_) #if defined(GTEST_GET_INT32_FROM_ENV_)
return GTEST_GET_INT32_FROM_ENV_(flag, default_value); return GTEST_GET_INT32_FROM_ENV_(flag, default_value);
#endif // defined(GTEST_GET_INT32_FROM_ENV_) #else
const std::string env_var = FlagToEnvVar(flag); const std::string env_var = FlagToEnvVar(flag);
const char* const string_value = posix::GetEnv(env_var.c_str()); const char* const string_value = posix::GetEnv(env_var.c_str());
if (string_value == NULL) { if (string_value == NULL) {
@ -1202,37 +1217,36 @@ Int32 Int32FromGTestEnv(const char* flag, Int32 default_value) {
} }
return result; return result;
#endif // defined(GTEST_GET_INT32_FROM_ENV_)
}
// As a special case for the 'output' flag, if GTEST_OUTPUT is not
// set, we look for XML_OUTPUT_FILE, which is set by the Bazel build
// system. The value of XML_OUTPUT_FILE is a filename without the
// "xml:" prefix of GTEST_OUTPUT.
// Note that this is meant to be called at the call site so it does
// not check that the flag is 'output'
// In essence this checks an env variable called XML_OUTPUT_FILE
// and if it is set we prepend "xml:" to its value, if it not set we return ""
std::string OutputFlagAlsoCheckEnvVar(){
std::string default_value_for_output_flag = "";
const char* xml_output_file_env = posix::GetEnv("XML_OUTPUT_FILE");
if (NULL != xml_output_file_env) {
default_value_for_output_flag = std::string("xml:") + xml_output_file_env;
}
return default_value_for_output_flag;
} }
// Reads and returns the string environment variable corresponding to // Reads and returns the string environment variable corresponding to
// the given flag; if it's not set, returns default_value. // the given flag; if it's not set, returns default_value.
std::string StringFromGTestEnv(const char* flag, const char* default_value) { const char* StringFromGTestEnv(const char* flag, const char* default_value) {
#if defined(GTEST_GET_STRING_FROM_ENV_) #if defined(GTEST_GET_STRING_FROM_ENV_)
return GTEST_GET_STRING_FROM_ENV_(flag, default_value); return GTEST_GET_STRING_FROM_ENV_(flag, default_value);
#endif // defined(GTEST_GET_STRING_FROM_ENV_) #else
const std::string env_var = FlagToEnvVar(flag); const std::string env_var = FlagToEnvVar(flag);
const char* value = posix::GetEnv(env_var.c_str()); const char* const value = posix::GetEnv(env_var.c_str());
if (value != NULL) { return value == NULL ? default_value : value;
return value; #endif // defined(GTEST_GET_STRING_FROM_ENV_)
}
// As a special case for the 'output' flag, if GTEST_OUTPUT is not
// set, we look for XML_OUTPUT_FILE, which is set by the Bazel build
// system. The value of XML_OUTPUT_FILE is a filename without the
// "xml:" prefix of GTEST_OUTPUT.
//
// The net priority order after flag processing is thus:
// --gtest_output command line flag
// GTEST_OUTPUT environment variable
// XML_OUTPUT_FILE environment variable
// 'default_value'
if (strcmp(flag, "output") == 0) {
value = posix::GetEnv("XML_OUTPUT_FILE");
if (value != NULL) {
return std::string("xml:") + value;
}
}
return default_value;
} }
} // namespace internal } // namespace internal

View File

@ -230,9 +230,15 @@ GTEST_DEFINE_string_(
GTEST_DEFINE_bool_(list_tests, false, GTEST_DEFINE_bool_(list_tests, false,
"List all tests without running them."); "List all tests without running them.");
// The net priority order after flag processing is thus:
// --gtest_output command line flag
// GTEST_OUTPUT environment variable
// XML_OUTPUT_FILE environment variable
// ''
GTEST_DEFINE_string_( GTEST_DEFINE_string_(
output, output,
internal::StringFromGTestEnv("output", ""), internal::StringFromGTestEnv("output",
internal::OutputFlagAlsoCheckEnvVar().c_str()),
"A format (defaults to \"xml\" but can be specified to be \"json\"), " "A format (defaults to \"xml\" but can be specified to be \"json\"), "
"optionally followed by a colon and an output file name or directory. " "optionally followed by a colon and an output file name or directory. "
"A directory is indicated by a trailing pathname separator. " "A directory is indicated by a trailing pathname separator. "
@ -386,12 +392,15 @@ void AssertHelper::operator=(const Message& message) const {
GTEST_API_ GTEST_DEFINE_STATIC_MUTEX_(g_linked_ptr_mutex); GTEST_API_ GTEST_DEFINE_STATIC_MUTEX_(g_linked_ptr_mutex);
// A copy of all command line arguments. Set by InitGoogleTest(). // A copy of all command line arguments. Set by InitGoogleTest().
::std::vector<testing::internal::string> g_argvs; ::std::vector<std::string> g_argvs;
const ::std::vector<testing::internal::string>& GetArgvs() { ::std::vector<std::string> GetArgvs() {
#if defined(GTEST_CUSTOM_GET_ARGVS_) #if defined(GTEST_CUSTOM_GET_ARGVS_)
return GTEST_CUSTOM_GET_ARGVS_(); // GTEST_CUSTOM_GET_ARGVS_() may return a container of std::string or
#else // defined(GTEST_CUSTOM_GET_ARGVS_) // ::string. This code converts it to the appropriate type.
const auto& custom = GTEST_CUSTOM_GET_ARGVS_();
return ::std::vector<std::string>(custom.begin(), custom.end());
#else // defined(GTEST_CUSTOM_GET_ARGVS_)
return g_argvs; return g_argvs;
#endif // defined(GTEST_CUSTOM_GET_ARGVS_) #endif // defined(GTEST_CUSTOM_GET_ARGVS_)
} }
@ -2912,16 +2921,20 @@ static int GetBitOffset(WORD color_mask) {
static WORD GetNewColor(GTestColor color, WORD old_color_attrs) { static WORD GetNewColor(GTestColor color, WORD old_color_attrs) {
// Let's reuse the BG // Let's reuse the BG
static const WORD background_mask = BACKGROUND_BLUE | BACKGROUND_GREEN | BACKGROUND_RED | BACKGROUND_INTENSITY; static const WORD background_mask = BACKGROUND_BLUE | BACKGROUND_GREEN |
static const WORD foreground_mask = FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_INTENSITY; BACKGROUND_RED | BACKGROUND_INTENSITY;
static const WORD foreground_mask = FOREGROUND_BLUE | FOREGROUND_GREEN |
FOREGROUND_RED | FOREGROUND_INTENSITY;
const WORD existing_bg = old_color_attrs & background_mask; const WORD existing_bg = old_color_attrs & background_mask;
WORD new_color = GetColorAttribute(color) | existing_bg | FOREGROUND_INTENSITY; WORD new_color =
GetColorAttribute(color) | existing_bg | FOREGROUND_INTENSITY;
static const int bg_bitOffset = GetBitOffset(background_mask); static const int bg_bitOffset = GetBitOffset(background_mask);
static const int fg_bitOffset = GetBitOffset(foreground_mask); static const int fg_bitOffset = GetBitOffset(foreground_mask);
if (((new_color & background_mask) >> bg_bitOffset) == ((new_color & foreground_mask) >> fg_bitOffset)) { if (((new_color & background_mask) >> bg_bitOffset) ==
new_color ^= FOREGROUND_INTENSITY; //invert intensity ((new_color & foreground_mask) >> fg_bitOffset)) {
new_color ^= FOREGROUND_INTENSITY; // invert intensity
} }
return new_color; return new_color;
} }
@ -2982,7 +2995,6 @@ bool ShouldUseColor(bool stdout_is_tty) {
// cannot simply emit special characters and have the terminal change colors. // cannot simply emit special characters and have the terminal change colors.
// This routine must actually emit the characters rather than return a string // This routine must actually emit the characters rather than return a string
// that would be colored when printed, as can be done on Linux. // that would be colored when printed, as can be done on Linux.
GTEST_ATTRIBUTE_PRINTF_(2, 3)
static void ColoredPrintf(GTestColor color, const char* fmt, ...) { static void ColoredPrintf(GTestColor color, const char* fmt, ...) {
va_list args; va_list args;
va_start(args, fmt); va_start(args, fmt);
@ -3032,7 +3044,7 @@ static void ColoredPrintf(GTestColor color, const char* fmt, ...) {
va_end(args); va_end(args);
} }
// Text printed in Google Test's text output and --gunit_list_tests // Text printed in Google Test's text output and --gtest_list_tests
// output to label the type parameter and value parameter for a test. // output to label the type parameter and value parameter for a test.
static const char kTypeParamLabel[] = "TypeParam"; static const char kTypeParamLabel[] = "TypeParam";
static const char kValueParamLabel[] = "GetParam()"; static const char kValueParamLabel[] = "GetParam()";
@ -3442,6 +3454,11 @@ class XmlUnitTestResultPrinter : public EmptyTestEventListener {
// to delimit this attribute from prior attributes. // to delimit this attribute from prior attributes.
static std::string TestPropertiesAsXmlAttributes(const TestResult& result); static std::string TestPropertiesAsXmlAttributes(const TestResult& result);
// Streams an XML representation of the test properties of a TestResult
// object.
static void OutputXmlTestProperties(std::ostream* stream,
const TestResult& result);
// The output file. // The output file.
const std::string output_file_; const std::string output_file_;
@ -3653,6 +3670,10 @@ void XmlUnitTestResultPrinter::OutputXmlTestInfo(::std::ostream* stream,
const TestResult& result = *test_info.result(); const TestResult& result = *test_info.result();
const std::string kTestcase = "testcase"; const std::string kTestcase = "testcase";
if (test_info.is_in_another_shard()) {
return;
}
*stream << " <testcase"; *stream << " <testcase";
OutputXmlAttribute(stream, kTestcase, "name", test_info.name()); OutputXmlAttribute(stream, kTestcase, "name", test_info.name());
@ -3669,7 +3690,6 @@ void XmlUnitTestResultPrinter::OutputXmlTestInfo(::std::ostream* stream,
OutputXmlAttribute(stream, kTestcase, "time", OutputXmlAttribute(stream, kTestcase, "time",
FormatTimeInMillisAsSeconds(result.elapsed_time())); FormatTimeInMillisAsSeconds(result.elapsed_time()));
OutputXmlAttribute(stream, kTestcase, "classname", test_case_name); OutputXmlAttribute(stream, kTestcase, "classname", test_case_name);
*stream << TestPropertiesAsXmlAttributes(result);
int failures = 0; int failures = 0;
for (int i = 0; i < result.total_part_count(); ++i) { for (int i = 0; i < result.total_part_count(); ++i) {
@ -3691,10 +3711,15 @@ void XmlUnitTestResultPrinter::OutputXmlTestInfo(::std::ostream* stream,
} }
} }
if (failures == 0) if (failures == 0 && result.test_property_count() == 0) {
*stream << " />\n"; *stream << " />\n";
else } else {
if (failures == 0) {
*stream << ">\n";
}
OutputXmlTestProperties(stream, result);
*stream << " </testcase>\n"; *stream << " </testcase>\n";
}
} }
// Prints an XML representation of a TestCase object // Prints an XML representation of a TestCase object
@ -3749,7 +3774,6 @@ void XmlUnitTestResultPrinter::PrintXmlUnitTest(std::ostream* stream,
OutputXmlAttribute(stream, kTestsuites, "random_seed", OutputXmlAttribute(stream, kTestsuites, "random_seed",
StreamableToString(unit_test.random_seed())); StreamableToString(unit_test.random_seed()));
} }
*stream << TestPropertiesAsXmlAttributes(unit_test.ad_hoc_test_result()); *stream << TestPropertiesAsXmlAttributes(unit_test.ad_hoc_test_result());
OutputXmlAttribute(stream, kTestsuites, "name", "AllTests"); OutputXmlAttribute(stream, kTestsuites, "name", "AllTests");
@ -3775,6 +3799,26 @@ std::string XmlUnitTestResultPrinter::TestPropertiesAsXmlAttributes(
return attributes.GetString(); return attributes.GetString();
} }
void XmlUnitTestResultPrinter::OutputXmlTestProperties(
std::ostream* stream, const TestResult& result) {
const std::string kProperties = "properties";
const std::string kProperty = "property";
if (result.test_property_count() <= 0) {
return;
}
*stream << "<" << kProperties << ">\n";
for (int i = 0; i < result.test_property_count(); ++i) {
const TestProperty& property = result.GetTestProperty(i);
*stream << "<" << kProperty;
*stream << " name=\"" << EscapeXmlAttribute(property.key()) << "\"";
*stream << " value=\"" << EscapeXmlAttribute(property.value()) << "\"";
*stream << "/>\n";
}
*stream << "</" << kProperties << ">\n";
}
// End XmlUnitTestResultPrinter // End XmlUnitTestResultPrinter
@ -4210,9 +4254,10 @@ void OsStackTraceGetter::UponLeavingGTest() {}
class ScopedPrematureExitFile { class ScopedPrematureExitFile {
public: public:
explicit ScopedPrematureExitFile(const char* premature_exit_filepath) explicit ScopedPrematureExitFile(const char* premature_exit_filepath)
: premature_exit_filepath_(premature_exit_filepath) { : premature_exit_filepath_(premature_exit_filepath ?
premature_exit_filepath : "") {
// If a path to the premature-exit file is specified... // If a path to the premature-exit file is specified...
if (premature_exit_filepath != NULL && *premature_exit_filepath != '\0') { if (!premature_exit_filepath_.empty()) {
// create the file with a single "0" character in it. I/O // create the file with a single "0" character in it. I/O
// errors are ignored as there's nothing better we can do and we // errors are ignored as there's nothing better we can do and we
// don't want to fail the test because of this. // don't want to fail the test because of this.
@ -4223,13 +4268,18 @@ class ScopedPrematureExitFile {
} }
~ScopedPrematureExitFile() { ~ScopedPrematureExitFile() {
if (premature_exit_filepath_ != NULL && *premature_exit_filepath_ != '\0') { if (!premature_exit_filepath_.empty()) {
remove(premature_exit_filepath_); int retval = remove(premature_exit_filepath_.c_str());
if (retval) {
GTEST_LOG_(ERROR) << "Failed to remove premature exit filepath \""
<< premature_exit_filepath_ << "\" with error "
<< retval;
}
} }
} }
private: private:
const char* const premature_exit_filepath_; const std::string premature_exit_filepath_;
GTEST_DISALLOW_COPY_AND_ASSIGN_(ScopedPrematureExitFile); GTEST_DISALLOW_COPY_AND_ASSIGN_(ScopedPrematureExitFile);
}; };
@ -4897,13 +4947,8 @@ static void TearDownEnvironment(Environment* env) { env->TearDown(); }
// All other functions called from RunAllTests() may safely assume that // All other functions called from RunAllTests() may safely assume that
// parameterized tests are ready to be counted and run. // parameterized tests are ready to be counted and run.
bool UnitTestImpl::RunAllTests() { bool UnitTestImpl::RunAllTests() {
// Makes sure InitGoogleTest() was called. // True iff Google Test is initialized before RUN_ALL_TESTS() is called.
if (!GTestIsInitialized()) { const bool gtest_is_initialized_before_run_all_tests = GTestIsInitialized();
GTEST_LOG_(ERROR) <<
"\nThis test program did NOT call ::testing::InitGoogleTest "
"before calling RUN_ALL_TESTS(). Please fix it.";
return false;
}
// Do not run any test if the --help flag was specified. // Do not run any test if the --help flag was specified.
if (g_help_flag) if (g_help_flag)
@ -5031,6 +5076,20 @@ bool UnitTestImpl::RunAllTests() {
repeater->OnTestProgramEnd(*parent_); repeater->OnTestProgramEnd(*parent_);
if (!gtest_is_initialized_before_run_all_tests) {
ColoredPrintf(
COLOR_RED,
"\nIMPORTANT NOTICE - DO NOT IGNORE:\n"
"This test program did NOT call " GTEST_INIT_GOOGLE_TEST_NAME_
"() before calling RUN_ALL_TESTS(). This is INVALID. Soon " GTEST_NAME_
" will start to enforce the valid usage. "
"Please fix it ASAP, or IT WILL START TO FAIL.\n"); // NOLINT
#if GTEST_FOR_GOOGLE_
ColoredPrintf(COLOR_RED,
"For more details, see http://wiki/Main/ValidGUnitMain.\n");
#endif // GTEST_FOR_GOOGLE_
}
return !failed; return !failed;
} }
@ -5077,7 +5136,7 @@ bool ShouldShard(const char* total_shards_env,
<< "Invalid environment variables: you have " << "Invalid environment variables: you have "
<< kTestShardIndex << " = " << shard_index << kTestShardIndex << " = " << shard_index
<< ", but have left " << kTestTotalShards << " unset.\n"; << ", but have left " << kTestTotalShards << " unset.\n";
ColoredPrintf(COLOR_RED, "%s", msg.GetString().c_str()); ColoredPrintf(COLOR_RED, msg.GetString().c_str());
fflush(stdout); fflush(stdout);
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} else if (total_shards != -1 && shard_index == -1) { } else if (total_shards != -1 && shard_index == -1) {
@ -5085,7 +5144,7 @@ bool ShouldShard(const char* total_shards_env,
<< "Invalid environment variables: you have " << "Invalid environment variables: you have "
<< kTestTotalShards << " = " << total_shards << kTestTotalShards << " = " << total_shards
<< ", but have left " << kTestShardIndex << " unset.\n"; << ", but have left " << kTestShardIndex << " unset.\n";
ColoredPrintf(COLOR_RED, "%s", msg.GetString().c_str()); ColoredPrintf(COLOR_RED, msg.GetString().c_str());
fflush(stdout); fflush(stdout);
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} else if (shard_index < 0 || shard_index >= total_shards) { } else if (shard_index < 0 || shard_index >= total_shards) {
@ -5094,7 +5153,7 @@ bool ShouldShard(const char* total_shards_env,
<< kTestShardIndex << " < " << kTestTotalShards << kTestShardIndex << " < " << kTestTotalShards
<< ", but you have " << kTestShardIndex << "=" << shard_index << ", but you have " << kTestShardIndex << "=" << shard_index
<< ", " << kTestTotalShards << "=" << total_shards << ".\n"; << ", " << kTestTotalShards << "=" << total_shards << ".\n";
ColoredPrintf(COLOR_RED, "%s", msg.GetString().c_str()); ColoredPrintf(COLOR_RED, msg.GetString().c_str());
fflush(stdout); fflush(stdout);
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
@ -5132,8 +5191,8 @@ bool ShouldRunTestOnShard(int total_shards, int shard_index, int test_id) {
// each TestCase and TestInfo object. // each TestCase and TestInfo object.
// If shard_tests == true, further filters tests based on sharding // If shard_tests == true, further filters tests based on sharding
// variables in the environment - see // variables in the environment - see
// https://github.com/google/googletest/blob/master/googletest/docs/AdvancedGuide.md . // https://github.com/google/googletest/blob/master/googletest/docs/AdvancedGuide.md
// Returns the number of tests that should run. // . Returns the number of tests that should run.
int UnitTestImpl::FilterTests(ReactionToSharding shard_tests) { int UnitTestImpl::FilterTests(ReactionToSharding shard_tests) {
const Int32 total_shards = shard_tests == HONOR_SHARDING_PROTOCOL ? const Int32 total_shards = shard_tests == HONOR_SHARDING_PROTOCOL ?
Int32FromEnvOrDie(kTestTotalShards, -1) : -1; Int32FromEnvOrDie(kTestTotalShards, -1) : -1;
@ -5361,8 +5420,7 @@ bool SkipPrefix(const char* prefix, const char** pstr) {
// part can be omitted. // part can be omitted.
// //
// Returns the value of the flag, or NULL if the parsing failed. // Returns the value of the flag, or NULL if the parsing failed.
static const char* ParseFlagValue(const char* str, static const char* ParseFlagValue(const char* str, const char* flag,
const char* flag,
bool def_optional) { bool def_optional) {
// str and flag must not be NULL. // str and flag must not be NULL.
if (str == NULL || flag == NULL) return NULL; if (str == NULL || flag == NULL) return NULL;
@ -5433,9 +5491,8 @@ bool ParseInt32Flag(const char* str, const char* flag, Int32* value) {
// //
// On success, stores the value of the flag in *value, and returns // On success, stores the value of the flag in *value, and returns
// true. On failure, returns false without changing *value. // true. On failure, returns false without changing *value.
static bool ParseStringFlag(const char* str, template <typename String>
const char* flag, static bool ParseStringFlag(const char* str, const char* flag, String* value) {
std::string* value) {
// Gets the value of the flag as a string. // Gets the value of the flag as a string.
const char* const value_str = ParseFlagValue(str, flag, false); const char* const value_str = ParseFlagValue(str, flag, false);
@ -5535,22 +5592,22 @@ static const char kColorEncodedHelpMessage[] =
"Test Output:\n" "Test Output:\n"
" @G--" GTEST_FLAG_PREFIX_ "color=@Y(@Gyes@Y|@Gno@Y|@Gauto@Y)@D\n" " @G--" GTEST_FLAG_PREFIX_ "color=@Y(@Gyes@Y|@Gno@Y|@Gauto@Y)@D\n"
" Enable/disable colored output. The default is @Gauto@D.\n" " Enable/disable colored output. The default is @Gauto@D.\n"
" @G--" GTEST_FLAG_PREFIX_ "print_time=0@D\n" " -@G-" GTEST_FLAG_PREFIX_ "print_time=0@D\n"
" Don't print the elapsed time of each test.\n" " Don't print the elapsed time of each test.\n"
" @G--" GTEST_FLAG_PREFIX_ "output=@Y(@Gjson@Y|@Gxml@Y)[@G:@YDIRECTORY_PATH@G" " @G--" GTEST_FLAG_PREFIX_ "output=@Y(@Gjson@Y|@Gxml@Y)[@G:@YDIRECTORY_PATH@G"
GTEST_PATH_SEP_ "@Y|@G:@YFILE_PATH]@D\n" GTEST_PATH_SEP_ "@Y|@G:@YFILE_PATH]@D\n"
" Generate a JSON or XML report in the given directory or with the given\n" " Generate a JSON or XML report in the given directory or with the given\n"
" file name. @YFILE_PATH@D defaults to @Gtest_details.xml@D.\n" " file name. @YFILE_PATH@D defaults to @Gtest_details.xml@D.\n"
#if GTEST_CAN_STREAM_RESULTS_ # if GTEST_CAN_STREAM_RESULTS_
" @G--" GTEST_FLAG_PREFIX_ "stream_result_to=@YHOST@G:@YPORT@D\n" " @G--" GTEST_FLAG_PREFIX_ "stream_result_to=@YHOST@G:@YPORT@D\n"
" Stream test results to the given server.\n" " Stream test results to the given server.\n"
#endif // GTEST_CAN_STREAM_RESULTS_ # endif // GTEST_CAN_STREAM_RESULTS_
"\n" "\n"
"Assertion Behavior:\n" "Assertion Behavior:\n"
#if GTEST_HAS_DEATH_TEST && !GTEST_OS_WINDOWS # if GTEST_HAS_DEATH_TEST && !GTEST_OS_WINDOWS
" @G--" GTEST_FLAG_PREFIX_ "death_test_style=@Y(@Gfast@Y|@Gthreadsafe@Y)@D\n" " @G--" GTEST_FLAG_PREFIX_ "death_test_style=@Y(@Gfast@Y|@Gthreadsafe@Y)@D\n"
" Set the default death test style.\n" " Set the default death test style.\n"
#endif // GTEST_HAS_DEATH_TEST && !GTEST_OS_WINDOWS # endif // GTEST_HAS_DEATH_TEST && !GTEST_OS_WINDOWS
" @G--" GTEST_FLAG_PREFIX_ "break_on_failure@D\n" " @G--" GTEST_FLAG_PREFIX_ "break_on_failure@D\n"
" Turn assertion failures into debugger break-points.\n" " Turn assertion failures into debugger break-points.\n"
" @G--" GTEST_FLAG_PREFIX_ "throw_on_failure@D\n" " @G--" GTEST_FLAG_PREFIX_ "throw_on_failure@D\n"

View File

@ -848,6 +848,34 @@ TEST_P(NamingTest, TestsReportCorrectNamesAndParameters) {
INSTANTIATE_TEST_CASE_P(ZeroToFiveSequence, NamingTest, Range(0, 5)); INSTANTIATE_TEST_CASE_P(ZeroToFiveSequence, NamingTest, Range(0, 5));
// Tests that macros in test names are expanded correctly.
class MacroNamingTest : public TestWithParam<int> {};
#define PREFIX_WITH_FOO(test_name) Foo##test_name
#define PREFIX_WITH_MACRO(test_name) Macro##test_name
TEST_P(PREFIX_WITH_MACRO(NamingTest), PREFIX_WITH_FOO(SomeTestName)) {
const ::testing::TestInfo* const test_info =
::testing::UnitTest::GetInstance()->current_test_info();
EXPECT_STREQ("FortyTwo/MacroNamingTest", test_info->test_case_name());
EXPECT_STREQ("FooSomeTestName", test_info->name());
}
INSTANTIATE_TEST_CASE_P(FortyTwo, MacroNamingTest, Values(42));
// Tests the same thing for non-parametrized tests.
class MacroNamingTestNonParametrized : public ::testing::Test {};
TEST_F(PREFIX_WITH_MACRO(NamingTestNonParametrized),
PREFIX_WITH_FOO(SomeTestName)) {
const ::testing::TestInfo* const test_info =
::testing::UnitTest::GetInstance()->current_test_info();
EXPECT_STREQ("MacroNamingTestNonParametrized", test_info->test_case_name());
EXPECT_STREQ("FooSomeTestName", test_info->name());
}
// Tests that user supplied custom parameter names are working correctly. // Tests that user supplied custom parameter names are working correctly.
// Runs the test with a builtin helper method which uses PrintToString, // Runs the test with a builtin helper method which uses PrintToString,
// as well as a custom function and custom functor to ensure all possible // as well as a custom function and custom functor to ensure all possible

View File

@ -50,18 +50,13 @@
#include "gtest/gtest.h" #include "gtest/gtest.h"
// hash_map and hash_set are available under Visual C++, or on Linux.
#if GTEST_HAS_UNORDERED_MAP_ #if GTEST_HAS_UNORDERED_MAP_
# include <unordered_map> // NOLINT # include <unordered_map> // NOLINT
#elif GTEST_HAS_HASH_MAP_ #endif // GTEST_HAS_UNORDERED_MAP_
# include <hash_map> // NOLINT
#endif // GTEST_HAS_HASH_MAP_
#if GTEST_HAS_UNORDERED_SET_ #if GTEST_HAS_UNORDERED_SET_
# include <unordered_set> // NOLINT # include <unordered_set> // NOLINT
#elif GTEST_HAS_HASH_SET_ #endif // GTEST_HAS_UNORDERED_SET_
# include <hash_set> // NOLINT
#endif // GTEST_HAS_HASH_SET_
#if GTEST_HAS_STD_FORWARD_LIST_ #if GTEST_HAS_STD_FORWARD_LIST_
# include <forward_list> // NOLINT # include <forward_list> // NOLINT
@ -200,7 +195,6 @@ class PathLike {
struct iterator { struct iterator {
typedef PathLike value_type; typedef PathLike value_type;
}; };
typedef iterator const_iterator;
PathLike() {} PathLike() {}
@ -238,50 +232,6 @@ using ::testing::internal::UniversalPrinter;
using ::testing::internal::UniversalTersePrint; using ::testing::internal::UniversalTersePrint;
#if GTEST_HAS_TR1_TUPLE || GTEST_HAS_STD_TUPLE_ #if GTEST_HAS_TR1_TUPLE || GTEST_HAS_STD_TUPLE_
using ::testing::internal::UniversalTersePrintTupleFieldsToStrings; using ::testing::internal::UniversalTersePrintTupleFieldsToStrings;
#endif
using ::testing::internal::string;
// The hash_* classes are not part of the C++ standard. STLport
// defines them in namespace std. MSVC defines them in ::stdext. GCC
// defines them in ::.
#if GTEST_HAS_UNORDERED_MAP_
#define GTEST_HAS_HASH_MAP_ 1
template <class Key, class T>
using hash_map = ::std::unordered_map<Key, T>;
template <class Key, class T>
using hash_multimap = ::std::unordered_multimap<Key, T>;
#elif GTEST_HAS_HASH_MAP_
#ifdef _STLP_HASH_MAP // We got <hash_map> from STLport.
using ::std::hash_map;
using ::std::hash_multimap;
#elif _MSC_VER
using ::stdext::hash_map;
using ::stdext::hash_multimap;
#endif
#endif
#if GTEST_HAS_UNORDERED_SET_
#define GTEST_HAS_HASH_SET_ 1
template <class Key>
using hash_set = ::std::unordered_set<Key>;
template <class Key>
using hash_multiset = ::std::unordered_multiset<Key>;
#elif GTEST_HAS_HASH_SET_
#ifdef _STLP_HASH_MAP // We got <hash_map> from STLport.
using ::std::hash_map;
using ::std::hash_multimap;
#elif _MSC_VER
using ::stdext::hash_map;
using ::stdext::hash_multimap;
#endif
#endif #endif
// Prints a value to a string using the universal value printer. This // Prints a value to a string using the universal value printer. This
@ -868,16 +818,16 @@ TEST(PrintStlContainerTest, NonEmptyDeque) {
EXPECT_EQ("{ 1, 3 }", Print(non_empty)); EXPECT_EQ("{ 1, 3 }", Print(non_empty));
} }
#if GTEST_HAS_HASH_MAP_ #if GTEST_HAS_UNORDERED_MAP_
TEST(PrintStlContainerTest, OneElementHashMap) { TEST(PrintStlContainerTest, OneElementHashMap) {
hash_map<int, char> map1; ::std::unordered_map<int, char> map1;
map1[1] = 'a'; map1[1] = 'a';
EXPECT_EQ("{ (1, 'a' (97, 0x61)) }", Print(map1)); EXPECT_EQ("{ (1, 'a' (97, 0x61)) }", Print(map1));
} }
TEST(PrintStlContainerTest, HashMultiMap) { TEST(PrintStlContainerTest, HashMultiMap) {
hash_multimap<int, bool> map1; ::std::unordered_multimap<int, bool> map1;
map1.insert(make_pair(5, true)); map1.insert(make_pair(5, true));
map1.insert(make_pair(5, false)); map1.insert(make_pair(5, false));
@ -888,12 +838,12 @@ TEST(PrintStlContainerTest, HashMultiMap) {
<< " where Print(map1) returns \"" << result << "\"."; << " where Print(map1) returns \"" << result << "\".";
} }
#endif // GTEST_HAS_HASH_MAP_ #endif // GTEST_HAS_UNORDERED_MAP_
#if GTEST_HAS_HASH_SET_ #if GTEST_HAS_UNORDERED_SET_
TEST(PrintStlContainerTest, HashSet) { TEST(PrintStlContainerTest, HashSet) {
hash_set<int> set1; ::std::unordered_set<int> set1;
set1.insert(1); set1.insert(1);
EXPECT_EQ("{ 1 }", Print(set1)); EXPECT_EQ("{ 1 }", Print(set1));
} }
@ -901,7 +851,7 @@ TEST(PrintStlContainerTest, HashSet) {
TEST(PrintStlContainerTest, HashMultiSet) { TEST(PrintStlContainerTest, HashMultiSet) {
const int kSize = 5; const int kSize = 5;
int a[kSize] = { 1, 1, 2, 5, 1 }; int a[kSize] = { 1, 1, 2, 5, 1 };
hash_multiset<int> set1(a, a + kSize); ::std::unordered_multiset<int> set1(a, a + kSize);
// Elements of hash_multiset can be printed in any order. // Elements of hash_multiset can be printed in any order.
const std::string result = Print(set1); const std::string result = Print(set1);
@ -927,7 +877,7 @@ TEST(PrintStlContainerTest, HashMultiSet) {
EXPECT_TRUE(std::equal(a, a + kSize, numbers.begin())); EXPECT_TRUE(std::equal(a, a + kSize, numbers.begin()));
} }
#endif // GTEST_HAS_HASH_SET_ #endif // GTEST_HAS_UNORDERED_SET_
TEST(PrintStlContainerTest, List) { TEST(PrintStlContainerTest, List) {
const std::string a[] = {"hello", "world"}; const std::string a[] = {"hello", "world"};

View File

@ -81,13 +81,14 @@ def TestFlag(flag, test_val, default_val):
class GTestEnvVarTest(gtest_test_utils.TestCase): class GTestEnvVarTest(gtest_test_utils.TestCase):
def testEnvVarAffectsFlag(self): def testEnvVarAffectsFlag(self):
"""Tests that environment variable should affect the corresponding flag.""" """Tests that environment variable should affect the corresponding flag."""
TestFlag('break_on_failure', '1', '0') TestFlag('break_on_failure', '1', '0')
TestFlag('color', 'yes', 'auto') TestFlag('color', 'yes', 'auto')
TestFlag('filter', 'FooTest.Bar', '*') TestFlag('filter', 'FooTest.Bar', '*')
SetEnvVar('XML_OUTPUT_FILE', None) # For 'output' test SetEnvVar('XML_OUTPUT_FILE', None) # For 'output' test
TestFlag('output', 'xml:tmp/foo.xml', '') TestFlag('output', 'xml:tmp/foo.xml', '')
TestFlag('print_time', '0', '1') TestFlag('print_time', '0', '1')
TestFlag('repeat', '999', '1') TestFlag('repeat', '999', '1')
@ -99,6 +100,7 @@ class GTestEnvVarTest(gtest_test_utils.TestCase):
TestFlag('death_test_use_fork', '1', '0') TestFlag('death_test_use_fork', '1', '0')
TestFlag('stack_trace_depth', '0', '100') TestFlag('stack_trace_depth', '0', '100')
def testXmlOutputFile(self): def testXmlOutputFile(self):
"""Tests that $XML_OUTPUT_FILE affects the output flag.""" """Tests that $XML_OUTPUT_FILE affects the output flag."""
@ -107,7 +109,7 @@ class GTestEnvVarTest(gtest_test_utils.TestCase):
AssertEq('xml:tmp/bar.xml', GetFlag('output')) AssertEq('xml:tmp/bar.xml', GetFlag('output'))
def testXmlOutputFileOverride(self): def testXmlOutputFileOverride(self):
"""Tests that $XML_OUTPUT_FILE is overridden by $GTEST_OUTPUT""" """Tests that $XML_OUTPUT_FILE is overridden by $GTEST_OUTPUT."""
SetEnvVar('GTEST_OUTPUT', 'xml:tmp/foo.xml') SetEnvVar('GTEST_OUTPUT', 'xml:tmp/foo.xml')
SetEnvVar('XML_OUTPUT_FILE', 'tmp/bar.xml') SetEnvVar('XML_OUTPUT_FILE', 'tmp/bar.xml')

View File

@ -32,9 +32,8 @@
import json import json
import os import os
import gtest_test_utils
import gtest_json_test_utils import gtest_json_test_utils
import gtest_test_utils
GTEST_OUTPUT_SUBDIR = 'json_outfiles' GTEST_OUTPUT_SUBDIR = 'json_outfiles'
GTEST_OUTPUT_1_TEST = 'gtest_xml_outfile1_test_' GTEST_OUTPUT_1_TEST = 'gtest_xml_outfile1_test_'

View File

@ -37,9 +37,8 @@ import os
import re import re
import sys import sys
import gtest_test_utils
import gtest_json_test_utils import gtest_json_test_utils
import gtest_test_utils
GTEST_FILTER_FLAG = '--gtest_filter' GTEST_FILTER_FLAG = '--gtest_filter'
GTEST_LIST_TESTS_FLAG = '--gtest_list_tests' GTEST_LIST_TESTS_FLAG = '--gtest_list_tests'

View File

@ -44,7 +44,7 @@ def normalize(obj):
""" """
def _normalize(key, value): def _normalize(key, value):
if key == 'time': if key == 'time':
return re.sub(r'^\d+(\.\d+)?s$', u'*', value) return re.sub(r'^\d+(\.\d+)?s$', '*', value)
elif key == 'timestamp': elif key == 'timestamp':
return re.sub(r'^\d{4}-\d\d-\d\dT\d\d:\d\d:\d\dZ$', '*', value) return re.sub(r'^\d{4}-\d\d-\d\dT\d\d:\d\d:\d\dZ$', '*', value)
elif key == 'failure': elif key == 'failure':

View File

@ -227,7 +227,7 @@ class Subprocess:
combined in a string. combined in a string.
""" """
# The subprocess module is the preferable way of running programs # The subprocess module is the preferrable way of running programs
# since it is available and behaves consistently on all platforms, # since it is available and behaves consistently on all platforms,
# including Windows. But it is only available starting in python 2.4. # including Windows. But it is only available starting in python 2.4.
# In earlier python versions, we revert to the popen2 module, which is # In earlier python versions, we revert to the popen2 module, which is

View File

@ -33,7 +33,6 @@
__author__ = 'wan@google.com (Zhanyong Wan)' __author__ = 'wan@google.com (Zhanyong Wan)'
import os
import gtest_test_utils import gtest_test_utils
COMMAND = gtest_test_utils.GetTestExecutablePath('gtest_uninitialized_test_') COMMAND = gtest_test_utils.GetTestExecutablePath('gtest_uninitialized_test_')

View File

@ -64,6 +64,9 @@ TEST(CommandLineFlagsTest, CanBeAccessedInCodeOnceGTestHIsIncluded) {
#include <map> #include <map>
#include <vector> #include <vector>
#include <ostream> #include <ostream>
#if GTEST_LANG_CXX11
#include <unordered_set>
#endif // GTEST_LANG_CXX11
#include "gtest/gtest-spi.h" #include "gtest/gtest-spi.h"
#include "src/gtest-internal-inl.h" #include "src/gtest-internal-inl.h"
@ -258,6 +261,8 @@ using testing::internal::IsContainer;
using testing::internal::IsContainerTest; using testing::internal::IsContainerTest;
using testing::internal::IsNotContainer; using testing::internal::IsNotContainer;
using testing::internal::NativeArray; using testing::internal::NativeArray;
using testing::internal::OsStackTraceGetter;
using testing::internal::OsStackTraceGetterInterface;
using testing::internal::ParseInt32Flag; using testing::internal::ParseInt32Flag;
using testing::internal::RelationToSourceCopy; using testing::internal::RelationToSourceCopy;
using testing::internal::RelationToSourceReference; using testing::internal::RelationToSourceReference;
@ -274,6 +279,7 @@ using testing::internal::String;
using testing::internal::TestEventListenersAccessor; using testing::internal::TestEventListenersAccessor;
using testing::internal::TestResultAccessor; using testing::internal::TestResultAccessor;
using testing::internal::UInt32; using testing::internal::UInt32;
using testing::internal::UnitTestImpl;
using testing::internal::WideStringToUtf8; using testing::internal::WideStringToUtf8;
using testing::internal::edit_distance::CalculateOptimalEdits; using testing::internal::edit_distance::CalculateOptimalEdits;
using testing::internal::edit_distance::CreateUnifiedDiff; using testing::internal::edit_distance::CreateUnifiedDiff;
@ -7526,6 +7532,50 @@ TEST(IsContainerTestTest, WorksForContainer) {
sizeof(IsContainerTest<std::map<int, double> >(0))); sizeof(IsContainerTest<std::map<int, double> >(0)));
} }
#if GTEST_LANG_CXX11
struct ConstOnlyContainerWithPointerIterator {
using const_iterator = int*;
const_iterator begin() const;
const_iterator end() const;
};
struct ConstOnlyContainerWithClassIterator {
struct const_iterator {
const int& operator*() const;
const_iterator& operator++(/* pre-increment */);
};
const_iterator begin() const;
const_iterator end() const;
};
TEST(IsContainerTestTest, ConstOnlyContainer) {
EXPECT_EQ(sizeof(IsContainer),
sizeof(IsContainerTest<ConstOnlyContainerWithPointerIterator>(0)));
EXPECT_EQ(sizeof(IsContainer),
sizeof(IsContainerTest<ConstOnlyContainerWithClassIterator>(0)));
}
#endif // GTEST_LANG_CXX11
// Tests IsHashTable.
struct AHashTable {
typedef void hasher;
};
struct NotReallyAHashTable {
typedef void hasher;
typedef void reverse_iterator;
};
TEST(IsHashTable, Basic) {
EXPECT_TRUE(testing::internal::IsHashTable<AHashTable>::value);
EXPECT_FALSE(testing::internal::IsHashTable<NotReallyAHashTable>::value);
#if GTEST_LANG_CXX11
EXPECT_FALSE(testing::internal::IsHashTable<std::vector<int>>::value);
EXPECT_TRUE(testing::internal::IsHashTable<std::unordered_set<int>>::value);
#endif // GTEST_LANG_CXX11
#if GTEST_HAS_HASH_SET_
EXPECT_TRUE(testing::internal::IsHashTable<hash_set<int>>::value);
#endif // GTEST_HAS_HASH_SET_
}
// Tests ArrayEq(). // Tests ArrayEq().
TEST(ArrayEqTest, WorksForDegeneratedArrays) { TEST(ArrayEqTest, WorksForDegeneratedArrays) {

View File

@ -43,7 +43,13 @@ GTEST_OUTPUT_2_TEST = "gtest_xml_outfile2_test_"
EXPECTED_XML_1 = """<?xml version="1.0" encoding="UTF-8"?> EXPECTED_XML_1 = """<?xml version="1.0" encoding="UTF-8"?>
<testsuites tests="1" failures="0" disabled="0" errors="0" time="*" timestamp="*" name="AllTests"> <testsuites tests="1" failures="0" disabled="0" errors="0" time="*" timestamp="*" name="AllTests">
<testsuite name="PropertyOne" tests="1" failures="0" disabled="0" errors="0" time="*"> <testsuite name="PropertyOne" tests="1" failures="0" disabled="0" errors="0" time="*">
<testcase name="TestSomeProperties" status="run" time="*" classname="PropertyOne" SetUpProp="1" TestSomeProperty="1" TearDownProp="1" /> <testcase name="TestSomeProperties" status="run" time="*" classname="PropertyOne">
<properties>
<property name="SetUpProp" value="1"/>
<property name="TestSomeProperty" value="1"/>
<property name="TearDownProp" value="1"/>
</properties>
</testcase>
</testsuite> </testsuite>
</testsuites> </testsuites>
""" """
@ -51,7 +57,13 @@ EXPECTED_XML_1 = """<?xml version="1.0" encoding="UTF-8"?>
EXPECTED_XML_2 = """<?xml version="1.0" encoding="UTF-8"?> EXPECTED_XML_2 = """<?xml version="1.0" encoding="UTF-8"?>
<testsuites tests="1" failures="0" disabled="0" errors="0" time="*" timestamp="*" name="AllTests"> <testsuites tests="1" failures="0" disabled="0" errors="0" time="*" timestamp="*" name="AllTests">
<testsuite name="PropertyTwo" tests="1" failures="0" disabled="0" errors="0" time="*"> <testsuite name="PropertyTwo" tests="1" failures="0" disabled="0" errors="0" time="*">
<testcase name="TestSomeProperties" status="run" time="*" classname="PropertyTwo" SetUpProp="2" TestSomeProperty="2" TearDownProp="2" /> <testcase name="TestSomeProperties" status="run" time="*" classname="PropertyTwo">
<properties>
<property name="SetUpProp" value="2"/>
<property name="TestSomeProperty" value="2"/>
<property name="TearDownProp" value="2"/>
</properties>
</testcase>
</testsuite> </testsuite>
</testsuites> </testsuites>
""" """

View File

@ -104,15 +104,45 @@ Invalid characters in brackets []%(stack)s]]></failure>
<testcase name="DISABLED_test_not_run" status="notrun" time="*" classname="DisabledTest"/> <testcase name="DISABLED_test_not_run" status="notrun" time="*" classname="DisabledTest"/>
</testsuite> </testsuite>
<testsuite name="PropertyRecordingTest" tests="4" failures="0" disabled="0" errors="0" time="*" SetUpTestCase="yes" TearDownTestCase="aye"> <testsuite name="PropertyRecordingTest" tests="4" failures="0" disabled="0" errors="0" time="*" SetUpTestCase="yes" TearDownTestCase="aye">
<testcase name="OneProperty" status="run" time="*" classname="PropertyRecordingTest" key_1="1"/> <testcase name="OneProperty" status="run" time="*" classname="PropertyRecordingTest">
<testcase name="IntValuedProperty" status="run" time="*" classname="PropertyRecordingTest" key_int="1"/> <properties>
<testcase name="ThreeProperties" status="run" time="*" classname="PropertyRecordingTest" key_1="1" key_2="2" key_3="3"/> <property name="key_1" value="1"/>
<testcase name="TwoValuesForOneKeyUsesLastValue" status="run" time="*" classname="PropertyRecordingTest" key_1="2"/> </properties>
</testcase>
<testcase name="IntValuedProperty" status="run" time="*" classname="PropertyRecordingTest">
<properties>
<property name="key_int" value="1"/>
</properties>
</testcase>
<testcase name="ThreeProperties" status="run" time="*" classname="PropertyRecordingTest">
<properties>
<property name="key_1" value="1"/>
<property name="key_2" value="2"/>
<property name="key_3" value="3"/>
</properties>
</testcase>
<testcase name="TwoValuesForOneKeyUsesLastValue" status="run" time="*" classname="PropertyRecordingTest">
<properties>
<property name="key_1" value="2"/>
</properties>
</testcase>
</testsuite> </testsuite>
<testsuite name="NoFixtureTest" tests="3" failures="0" disabled="0" errors="0" time="*"> <testsuite name="NoFixtureTest" tests="3" failures="0" disabled="0" errors="0" time="*">
<testcase name="RecordProperty" status="run" time="*" classname="NoFixtureTest" key="1"/> <testcase name="RecordProperty" status="run" time="*" classname="NoFixtureTest">
<testcase name="ExternalUtilityThatCallsRecordIntValuedProperty" status="run" time="*" classname="NoFixtureTest" key_for_utility_int="1"/> <properties>
<testcase name="ExternalUtilityThatCallsRecordStringValuedProperty" status="run" time="*" classname="NoFixtureTest" key_for_utility_string="1"/> <property name="key" value="1"/>
</properties>
</testcase>
<testcase name="ExternalUtilityThatCallsRecordIntValuedProperty" status="run" time="*" classname="NoFixtureTest">
<properties>
<property name="key_for_utility_int" value="1"/>
</properties>
</testcase>
<testcase name="ExternalUtilityThatCallsRecordStringValuedProperty" status="run" time="*" classname="NoFixtureTest">
<properties>
<property name="key_for_utility_string" value="1"/>
</properties>
</testcase>
</testsuite> </testsuite>
<testsuite name="Single/ValueParamTest" tests="4" failures="0" disabled="0" errors="0" time="*"> <testsuite name="Single/ValueParamTest" tests="4" failures="0" disabled="0" errors="0" time="*">
<testcase name="HasValueParamAttribute/0" value_param="33" status="run" time="*" classname="Single/ValueParamTest" /> <testcase name="HasValueParamAttribute/0" value_param="33" status="run" time="*" classname="Single/ValueParamTest" />
@ -149,7 +179,11 @@ EXPECTED_SHARDED_TEST_XML = """<?xml version="1.0" encoding="UTF-8"?>
<testcase name="Succeeds" status="run" time="*" classname="SuccessfulTest"/> <testcase name="Succeeds" status="run" time="*" classname="SuccessfulTest"/>
</testsuite> </testsuite>
<testsuite name="NoFixtureTest" tests="1" failures="0" disabled="0" errors="0" time="*"> <testsuite name="NoFixtureTest" tests="1" failures="0" disabled="0" errors="0" time="*">
<testcase name="RecordProperty" status="run" time="*" classname="NoFixtureTest" key="1"/> <testcase name="RecordProperty" status="run" time="*" classname="NoFixtureTest">
<properties>
<property name="key" value="1"/>
</properties>
</testcase>
</testsuite> </testsuite>
<testsuite name="Single/ValueParamTest" tests="1" failures="0" disabled="0" errors="0" time="*"> <testsuite name="Single/ValueParamTest" tests="1" failures="0" disabled="0" errors="0" time="*">
<testcase name="AnotherTestThatHasValueParamAttribute/1" value_param="42" status="run" time="*" classname="Single/ValueParamTest" /> <testcase name="AnotherTestThatHasValueParamAttribute/1" value_param="42" status="run" time="*" classname="Single/ValueParamTest" />

View File

@ -101,19 +101,22 @@ class GTestXMLTestCase(gtest_test_utils.TestCase):
self.AssertEquivalentNodes(child, actual_children[child_id]) self.AssertEquivalentNodes(child, actual_children[child_id])
identifying_attribute = { identifying_attribute = {
'testsuites': 'name', 'testsuites': 'name',
'testsuite': 'name', 'testsuite': 'name',
'testcase': 'name', 'testcase': 'name',
'failure': 'message', 'failure': 'message',
} 'property': 'name',
}
def _GetChildren(self, element): def _GetChildren(self, element):
""" """
Fetches all of the child nodes of element, a DOM Element object. Fetches all of the child nodes of element, a DOM Element object.
Returns them as the values of a dictionary keyed by the IDs of the Returns them as the values of a dictionary keyed by the IDs of the
children. For <testsuites>, <testsuite> and <testcase> elements, the ID children. For <testsuites>, <testsuite>, <testcase>, and <property>
is the value of their "name" attribute; for <failure> elements, it is elements, the ID is the value of their "name" attribute; for <failure>
the value of the "message" attribute; CDATA sections and non-whitespace elements, it is the value of the "message" attribute; for <properties>
elements, it is the value of their parent's "name" attribute plus the
literal string "properties"; CDATA sections and non-whitespace
text nodes are concatenated into a single CDATA section with ID text nodes are concatenated into a single CDATA section with ID
"detail". An exception is raised if any element other than the above "detail". An exception is raised if any element other than the above
four is encountered, if two child elements with the same identifying four is encountered, if two child elements with the same identifying
@ -123,11 +126,17 @@ class GTestXMLTestCase(gtest_test_utils.TestCase):
children = {} children = {}
for child in element.childNodes: for child in element.childNodes:
if child.nodeType == Node.ELEMENT_NODE: if child.nodeType == Node.ELEMENT_NODE:
self.assert_(child.tagName in self.identifying_attribute, if child.tagName == 'properties':
'Encountered unknown element <%s>' % child.tagName) self.assert_(child.parentNode is not None,
childID = child.getAttribute(self.identifying_attribute[child.tagName]) 'Encountered <properties> element without a parent')
self.assert_(childID not in children) child_id = child.parentNode.getAttribute('name') + '-properties'
children[childID] = child else:
self.assert_(child.tagName in self.identifying_attribute,
'Encountered unknown element <%s>' % child.tagName)
child_id = child.getAttribute(
self.identifying_attribute[child.tagName])
self.assert_(child_id not in children)
children[child_id] = child
elif child.nodeType in [Node.TEXT_NODE, Node.CDATA_SECTION_NODE]: elif child.nodeType in [Node.TEXT_NODE, Node.CDATA_SECTION_NODE]:
if 'detail' not in children: if 'detail' not in children:
if (child.nodeType == Node.CDATA_SECTION_NODE or if (child.nodeType == Node.CDATA_SECTION_NODE or