mirror of
https://github.com/google/googletest.git
synced 2025-01-21 15:11:57 +08:00
Merge branch 'master' into fix_death_test_child_mingw_wer_issue1116
This commit is contained in:
commit
5c7c365d5f
@ -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
|
||||||
|
|
||||||
|
@ -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"
|
||||||
}
|
}
|
||||||
|
@ -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
|
||||||
|
@ -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_
|
||||||
|
@ -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_
|
|
||||||
|
@ -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,
|
||||||
|
@ -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
|
||||||
|
@ -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 {
|
||||||
|
|
||||||
|
@ -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().
|
||||||
|
@ -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());
|
||||||
|
@ -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("_"));
|
||||||
|
@ -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
|
||||||
|
@ -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;
|
||||||
|
@ -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)>()); \
|
||||||
|
@ -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)>()); \
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
@ -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_
|
||||||
|
|
||||||
|
@ -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_
|
||||||
|
@ -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)])
|
||||||
|
@ -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
|
||||||
|
@ -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"
|
||||||
|
@ -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
|
||||||
|
@ -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"};
|
||||||
|
@ -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')
|
||||||
|
@ -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_'
|
||||||
|
@ -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'
|
||||||
|
@ -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':
|
||||||
|
@ -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
|
||||||
|
@ -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_')
|
||||||
|
@ -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) {
|
||||||
|
@ -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>
|
||||||
"""
|
"""
|
||||||
|
@ -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" />
|
||||||
|
@ -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
|
||||||
|
Loading…
x
Reference in New Issue
Block a user