Push several shanges:
Make single argument constructors explicit in macros. Remove NOMINMAX macro. Add macros for disabling Microsoft Visual C++ warnings. Add WhenDynamicCastTo<T> matcher. A matcher that matches a pointer that matches inner_matcher when dynamic_cast<T> is applied. Add IWYU export pragmas to the tuple include lines. Fix NativeArray to not require a copy constructor unless we ask for one. This allows ElementsAre() to support non-copyable types. Examine WINAPI_FAMILY_PARTITION macros to better distinguish windows platforms. Author: martin@martin.st From: https://codereview.appspot.com/57220043/
This commit is contained in:
parent
bd0188320d
commit
1f5fdea417
@ -1347,7 +1347,7 @@ DoAll(Action1 a1, Action2 a2, Action3 a3, Action4 a4, Action5 a5, Action6 a6,
|
||||
GMOCK_INTERNAL_DECL_TYPE_##value_params>\
|
||||
class GMOCK_ACTION_CLASS_(name, value_params) {\
|
||||
public:\
|
||||
GMOCK_ACTION_CLASS_(name, value_params)\
|
||||
explicit GMOCK_ACTION_CLASS_(name, value_params)\
|
||||
GMOCK_INTERNAL_INIT_##value_params {}\
|
||||
template <typename F>\
|
||||
class gmock_Impl : public ::testing::ActionInterface<F> {\
|
||||
@ -1455,7 +1455,7 @@ DoAll(Action1 a1, Action2 a2, Action3 a3, Action4 a4, Action5 a5, Action6 a6,
|
||||
template <typename p0##_type>\
|
||||
class name##ActionP {\
|
||||
public:\
|
||||
name##ActionP(p0##_type gmock_p0) : p0(gmock_p0) {}\
|
||||
explicit name##ActionP(p0##_type gmock_p0) : p0(gmock_p0) {}\
|
||||
template <typename F>\
|
||||
class gmock_Impl : public ::testing::ActionInterface<F> {\
|
||||
public:\
|
||||
|
@ -606,7 +606,7 @@ $range k 0..n-1
|
||||
GMOCK_INTERNAL_DECL_TYPE_##value_params>\
|
||||
class GMOCK_ACTION_CLASS_(name, value_params) {\
|
||||
public:\
|
||||
GMOCK_ACTION_CLASS_(name, value_params)\
|
||||
explicit GMOCK_ACTION_CLASS_(name, value_params)\
|
||||
GMOCK_INTERNAL_INIT_##value_params {}\
|
||||
template <typename F>\
|
||||
class gmock_Impl : public ::testing::ActionInterface<F> {\
|
||||
@ -694,7 +694,7 @@ $var macro_name = [[$if i==0 [[ACTION]] $elif i==1 [[ACTION_P]]
|
||||
#define $macro_name(name$for j [[, p$j]])\$template
|
||||
class $class_name {\
|
||||
public:\
|
||||
$class_name($ctor_param_list)$inits {}\
|
||||
[[$if i==1 [[explicit ]]]]$class_name($ctor_param_list)$inits {}\
|
||||
template <typename F>\
|
||||
class gmock_Impl : public ::testing::ActionInterface<F> {\
|
||||
public:\
|
||||
|
@ -1460,7 +1460,7 @@ AnyOf(M1 m1, M2 m2, M3 m3, M4 m4, M5 m5, M6 m6, M7 m7, M8 m8, M9 m9, M10 m10) {
|
||||
return ::testing::Matcher<arg_type>(\
|
||||
new gmock_Impl<arg_type>(p0));\
|
||||
}\
|
||||
name##MatcherP(p0##_type gmock_p0) : p0(gmock_p0) {\
|
||||
explicit name##MatcherP(p0##_type gmock_p0) : p0(gmock_p0) {\
|
||||
}\
|
||||
p0##_type p0;\
|
||||
private:\
|
||||
|
@ -653,7 +653,7 @@ $var param_field_decls2 = [[$for j
|
||||
return ::testing::Matcher<arg_type>(\
|
||||
new gmock_Impl<arg_type>($params));\
|
||||
}\
|
||||
$class_name($ctor_param_list)$inits {\
|
||||
[[$if i==1 [[explicit ]]]]$class_name($ctor_param_list)$inits {\
|
||||
}\$param_field_decls2
|
||||
private:\
|
||||
GTEST_DISALLOW_ASSIGN_($class_name);\
|
||||
|
@ -1997,6 +1997,83 @@ class PointeeMatcher {
|
||||
GTEST_DISALLOW_ASSIGN_(PointeeMatcher);
|
||||
};
|
||||
|
||||
// Implements the WhenDynamicCastTo<T>(m) matcher that matches a pointer or
|
||||
// reference that matches inner_matcher when dynamic_cast<T> is applied.
|
||||
// The result of dynamic_cast<To> is forwarded to the inner matcher.
|
||||
// If To is a pointer and the cast fails, the inner matcher will receive NULL.
|
||||
// If To is a reference and the cast fails, this matcher returns false
|
||||
// immediately.
|
||||
template <typename To>
|
||||
class WhenDynamicCastToMatcherBase {
|
||||
public:
|
||||
explicit WhenDynamicCastToMatcherBase(const Matcher<To>& matcher)
|
||||
: matcher_(matcher) {}
|
||||
|
||||
void DescribeTo(::std::ostream* os) const {
|
||||
GetCastTypeDescription(os);
|
||||
matcher_.DescribeTo(os);
|
||||
}
|
||||
|
||||
void DescribeNegationTo(::std::ostream* os) const {
|
||||
GetCastTypeDescription(os);
|
||||
matcher_.DescribeNegationTo(os);
|
||||
}
|
||||
|
||||
protected:
|
||||
const Matcher<To> matcher_;
|
||||
|
||||
static string GetToName() {
|
||||
#if GTEST_HAS_RTTI
|
||||
return GetTypeName<To>();
|
||||
#else // GTEST_HAS_RTTI
|
||||
return "the target type";
|
||||
#endif // GTEST_HAS_RTTI
|
||||
}
|
||||
|
||||
private:
|
||||
static void GetCastTypeDescription(::std::ostream* os) {
|
||||
*os << "when dynamic_cast to " << GetToName() << ", ";
|
||||
}
|
||||
|
||||
GTEST_DISALLOW_ASSIGN_(WhenDynamicCastToMatcherBase);
|
||||
};
|
||||
|
||||
// Primary template.
|
||||
// To is a pointer. Cast and forward the result.
|
||||
template <typename To>
|
||||
class WhenDynamicCastToMatcher : public WhenDynamicCastToMatcherBase<To> {
|
||||
public:
|
||||
explicit WhenDynamicCastToMatcher(const Matcher<To>& matcher)
|
||||
: WhenDynamicCastToMatcherBase<To>(matcher) {}
|
||||
|
||||
template <typename From>
|
||||
bool MatchAndExplain(From from, MatchResultListener* listener) const {
|
||||
// TODO(sbenza): Add more detail on failures. ie did the dyn_cast fail?
|
||||
To to = dynamic_cast<To>(from);
|
||||
return MatchPrintAndExplain(to, this->matcher_, listener);
|
||||
}
|
||||
};
|
||||
|
||||
// Specialize for references.
|
||||
// In this case we return false if the dynamic_cast fails.
|
||||
template <typename To>
|
||||
class WhenDynamicCastToMatcher<To&> : public WhenDynamicCastToMatcherBase<To&> {
|
||||
public:
|
||||
explicit WhenDynamicCastToMatcher(const Matcher<To&>& matcher)
|
||||
: WhenDynamicCastToMatcherBase<To&>(matcher) {}
|
||||
|
||||
template <typename From>
|
||||
bool MatchAndExplain(From& from, MatchResultListener* listener) const {
|
||||
// We don't want an std::bad_cast here, so do the cast with pointers.
|
||||
To* to = dynamic_cast<To*>(&from);
|
||||
if (to == NULL) {
|
||||
*listener << "which cannot be dynamic_cast to " << this->GetToName();
|
||||
return false;
|
||||
}
|
||||
return MatchPrintAndExplain(*to, this->matcher_, listener);
|
||||
}
|
||||
};
|
||||
|
||||
// Implements the Field() matcher for matching a field (i.e. member
|
||||
// variable) of an object.
|
||||
template <typename Class, typename FieldType>
|
||||
@ -3612,6 +3689,19 @@ inline internal::PointeeMatcher<InnerMatcher> Pointee(
|
||||
return internal::PointeeMatcher<InnerMatcher>(inner_matcher);
|
||||
}
|
||||
|
||||
// Creates a matcher that matches a pointer or reference that matches
|
||||
// inner_matcher when dynamic_cast<To> is applied.
|
||||
// The result of dynamic_cast<To> is forwarded to the inner matcher.
|
||||
// If To is a pointer and the cast fails, the inner matcher will receive NULL.
|
||||
// If To is a reference and the cast fails, this matcher returns false
|
||||
// immediately.
|
||||
template <typename To>
|
||||
inline PolymorphicMatcher<internal::WhenDynamicCastToMatcher<To> >
|
||||
WhenDynamicCastTo(const Matcher<To>& inner_matcher) {
|
||||
return MakePolymorphicMatcher(
|
||||
internal::WhenDynamicCastToMatcher<To>(inner_matcher));
|
||||
}
|
||||
|
||||
// Creates a matcher that matches an object whose given field matches
|
||||
// 'matcher'. For example,
|
||||
// Field(&Foo::number, Ge(5))
|
||||
@ -4050,3 +4140,4 @@ inline InnerMatcher AllArgs(const InnerMatcher& matcher) { return matcher; }
|
||||
} // namespace testing
|
||||
|
||||
#endif // GMOCK_INCLUDE_GMOCK_GMOCK_MATCHERS_H_
|
||||
|
||||
|
@ -447,16 +447,17 @@ class StlContainerView<Element[N]> {
|
||||
// ConstReference(const char * (&)[4])')
|
||||
// (and though the N parameter type is mismatched in the above explicit
|
||||
// conversion of it doesn't help - only the conversion of the array).
|
||||
return type(const_cast<Element*>(&array[0]), N, kReference);
|
||||
return type(const_cast<Element*>(&array[0]), N,
|
||||
RelationToSourceReference());
|
||||
#else
|
||||
return type(array, N, kReference);
|
||||
return type(array, N, RelationToSourceReference());
|
||||
#endif // GTEST_OS_SYMBIAN
|
||||
}
|
||||
static type Copy(const Element (&array)[N]) {
|
||||
#if GTEST_OS_SYMBIAN
|
||||
return type(const_cast<Element*>(&array[0]), N, kCopy);
|
||||
return type(const_cast<Element*>(&array[0]), N, RelationToSourceCopy());
|
||||
#else
|
||||
return type(array, N, kCopy);
|
||||
return type(array, N, RelationToSourceCopy());
|
||||
#endif // GTEST_OS_SYMBIAN
|
||||
}
|
||||
};
|
||||
@ -473,10 +474,10 @@ class StlContainerView< ::testing::tuple<ElementPointer, Size> > {
|
||||
|
||||
static const_reference ConstReference(
|
||||
const ::testing::tuple<ElementPointer, Size>& array) {
|
||||
return type(get<0>(array), get<1>(array), kReference);
|
||||
return type(get<0>(array), get<1>(array), RelationToSourceReference());
|
||||
}
|
||||
static type Copy(const ::testing::tuple<ElementPointer, Size>& array) {
|
||||
return type(get<0>(array), get<1>(array), kCopy);
|
||||
return type(get<0>(array), get<1>(array), RelationToSourceCopy());
|
||||
}
|
||||
};
|
||||
|
||||
@ -507,3 +508,4 @@ struct BooleanConstant {};
|
||||
} // namespace testing
|
||||
|
||||
#endif // GMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_INTERNAL_UTILS_H_
|
||||
|
||||
|
@ -900,9 +900,9 @@ template <typename T1, typename T2>
|
||||
// pattern requires the user to use it directly.
|
||||
ConcatImplActionP3<std::string, T1, T2>
|
||||
Concat(const std::string& a, T1 b, T2 c) {
|
||||
GTEST_INTENTIONAL_CONST_COND_PUSH_
|
||||
GTEST_INTENTIONAL_CONST_COND_PUSH_()
|
||||
if (true) {
|
||||
GTEST_INTENTIONAL_CONST_COND_POP_
|
||||
GTEST_INTENTIONAL_CONST_COND_POP_()
|
||||
// This branch verifies that ConcatImpl() can be invoked without
|
||||
// explicit template arguments.
|
||||
return ConcatImpl(a, b, c);
|
||||
|
@ -247,9 +247,9 @@ TEST(LosslessArithmeticConvertibleTest, FloatingPointToFloatingPoint) {
|
||||
|
||||
// Larger size => smaller size is not fine.
|
||||
EXPECT_FALSE((LosslessArithmeticConvertible<double, float>::value));
|
||||
GTEST_INTENTIONAL_CONST_COND_PUSH_
|
||||
GTEST_INTENTIONAL_CONST_COND_PUSH_()
|
||||
if (sizeof(double) == sizeof(long double)) { // NOLINT
|
||||
GTEST_INTENTIONAL_CONST_COND_POP_
|
||||
GTEST_INTENTIONAL_CONST_COND_POP_()
|
||||
// In some implementations (e.g. MSVC), double and long double
|
||||
// have the same size.
|
||||
EXPECT_TRUE((LosslessArithmeticConvertible<long double, double>::value));
|
||||
|
@ -33,10 +33,6 @@
|
||||
//
|
||||
// This file tests some commonly used argument matchers.
|
||||
|
||||
// windows.h defines macros which conflict with standard identifiers used in
|
||||
// this test. Defining this symbol prevents windows.h from doing that.
|
||||
#define NOMINMAX
|
||||
|
||||
#include "gmock/gmock-matchers.h"
|
||||
#include "gmock/gmock-more-matchers.h"
|
||||
|
||||
@ -657,8 +653,21 @@ TEST(MatcherCastTest, ValueIsNotCopied) {
|
||||
EXPECT_TRUE(m.Matches(n));
|
||||
}
|
||||
|
||||
class Base {};
|
||||
class Derived : public Base {};
|
||||
class Base {
|
||||
public:
|
||||
virtual ~Base() {}
|
||||
Base() {}
|
||||
private:
|
||||
GTEST_DISALLOW_COPY_AND_ASSIGN_(Base);
|
||||
};
|
||||
|
||||
class Derived : public Base {
|
||||
public:
|
||||
Derived() : Base() {}
|
||||
int i;
|
||||
};
|
||||
|
||||
class OtherDerived : public Base {};
|
||||
|
||||
// Tests that SafeMatcherCast<T>(m) works when m is a polymorphic matcher.
|
||||
TEST(SafeMatcherCastTest, FromPolymorphicMatcher) {
|
||||
@ -3135,6 +3144,107 @@ TEST(PointeeTest, ReferenceToNonConstRawPointer) {
|
||||
EXPECT_FALSE(m.Matches(p));
|
||||
}
|
||||
|
||||
|
||||
MATCHER_P(FieldIIs, inner_matcher, "") {
|
||||
return ExplainMatchResult(inner_matcher, arg.i, result_listener);
|
||||
}
|
||||
|
||||
TEST(WhenDynamicCastToTest, SameType) {
|
||||
Derived derived;
|
||||
derived.i = 4;
|
||||
|
||||
// Right type. A pointer is passed down.
|
||||
Base* as_base_ptr = &derived;
|
||||
EXPECT_THAT(as_base_ptr, WhenDynamicCastTo<Derived*>(Not(IsNull())));
|
||||
EXPECT_THAT(as_base_ptr, WhenDynamicCastTo<Derived*>(Pointee(FieldIIs(4))));
|
||||
EXPECT_THAT(as_base_ptr,
|
||||
Not(WhenDynamicCastTo<Derived*>(Pointee(FieldIIs(5)))));
|
||||
}
|
||||
|
||||
TEST(WhenDynamicCastToTest, WrongTypes) {
|
||||
Base base;
|
||||
Derived derived;
|
||||
OtherDerived other_derived;
|
||||
|
||||
// Wrong types. NULL is passed.
|
||||
EXPECT_THAT(&base, Not(WhenDynamicCastTo<Derived*>(Pointee(_))));
|
||||
EXPECT_THAT(&base, WhenDynamicCastTo<Derived*>(IsNull()));
|
||||
Base* as_base_ptr = &derived;
|
||||
EXPECT_THAT(as_base_ptr, Not(WhenDynamicCastTo<OtherDerived*>(Pointee(_))));
|
||||
EXPECT_THAT(as_base_ptr, WhenDynamicCastTo<OtherDerived*>(IsNull()));
|
||||
as_base_ptr = &other_derived;
|
||||
EXPECT_THAT(as_base_ptr, Not(WhenDynamicCastTo<Derived*>(Pointee(_))));
|
||||
EXPECT_THAT(as_base_ptr, WhenDynamicCastTo<Derived*>(IsNull()));
|
||||
}
|
||||
|
||||
TEST(WhenDynamicCastToTest, AlreadyNull) {
|
||||
// Already NULL.
|
||||
Base* as_base_ptr = NULL;
|
||||
EXPECT_THAT(as_base_ptr, WhenDynamicCastTo<Derived*>(IsNull()));
|
||||
}
|
||||
|
||||
struct AmbiguousCastTypes {
|
||||
class VirtualDerived : public virtual Base {};
|
||||
class DerivedSub1 : public VirtualDerived {};
|
||||
class DerivedSub2 : public VirtualDerived {};
|
||||
class ManyDerivedInHierarchy : public DerivedSub1, public DerivedSub2 {};
|
||||
};
|
||||
|
||||
TEST(WhenDynamicCastToTest, AmbiguousCast) {
|
||||
AmbiguousCastTypes::DerivedSub1 sub1;
|
||||
AmbiguousCastTypes::ManyDerivedInHierarchy many_derived;
|
||||
// Multiply derived from Base. dynamic_cast<> returns NULL.
|
||||
Base* as_base_ptr =
|
||||
static_cast<AmbiguousCastTypes::DerivedSub1*>(&many_derived);
|
||||
EXPECT_THAT(as_base_ptr,
|
||||
WhenDynamicCastTo<AmbiguousCastTypes::VirtualDerived*>(IsNull()));
|
||||
as_base_ptr = &sub1;
|
||||
EXPECT_THAT(
|
||||
as_base_ptr,
|
||||
WhenDynamicCastTo<AmbiguousCastTypes::VirtualDerived*>(Not(IsNull())));
|
||||
}
|
||||
|
||||
TEST(WhenDynamicCastToTest, Describe) {
|
||||
Matcher<Base*> matcher = WhenDynamicCastTo<Derived*>(Pointee(_));
|
||||
#if GTEST_HAS_RTTI
|
||||
const string prefix =
|
||||
"when dynamic_cast to " + internal::GetTypeName<Derived*>() + ", ";
|
||||
#else // GTEST_HAS_RTTI
|
||||
const string prefix = "when dynamic_cast, ";
|
||||
#endif // GTEST_HAS_RTTI
|
||||
EXPECT_EQ(prefix + "points to a value that is anything", Describe(matcher));
|
||||
EXPECT_EQ(prefix + "does not point to a value that is anything",
|
||||
DescribeNegation(matcher));
|
||||
}
|
||||
|
||||
TEST(WhenDynamicCastToTest, Explain) {
|
||||
Matcher<Base*> matcher = WhenDynamicCastTo<Derived*>(Pointee(_));
|
||||
Base* null = NULL;
|
||||
EXPECT_THAT(Explain(matcher, null), HasSubstr("NULL"));
|
||||
Derived derived;
|
||||
EXPECT_TRUE(matcher.Matches(&derived));
|
||||
EXPECT_THAT(Explain(matcher, &derived), HasSubstr("which points to "));
|
||||
|
||||
// With references, the matcher itself can fail. Test for that one.
|
||||
Matcher<const Base&> ref_matcher = WhenDynamicCastTo<const OtherDerived&>(_);
|
||||
EXPECT_THAT(Explain(ref_matcher, derived),
|
||||
HasSubstr("which cannot be dynamic_cast"));
|
||||
}
|
||||
|
||||
TEST(WhenDynamicCastToTest, GoodReference) {
|
||||
Derived derived;
|
||||
derived.i = 4;
|
||||
Base& as_base_ref = derived;
|
||||
EXPECT_THAT(as_base_ref, WhenDynamicCastTo<const Derived&>(FieldIIs(4)));
|
||||
EXPECT_THAT(as_base_ref, WhenDynamicCastTo<const Derived&>(Not(FieldIIs(5))));
|
||||
}
|
||||
|
||||
TEST(WhenDynamicCastToTest, BadReference) {
|
||||
Derived derived;
|
||||
Base& as_base_ref = derived;
|
||||
EXPECT_THAT(as_base_ref, Not(WhenDynamicCastTo<const OtherDerived&>(_)));
|
||||
}
|
||||
|
||||
// Minimal const-propagating pointer.
|
||||
template <typename T>
|
||||
class ConstPropagatingPtr {
|
||||
@ -3210,17 +3320,24 @@ TEST(PointeeTest, AlwaysExplainsPointee) {
|
||||
// An uncopyable class.
|
||||
class Uncopyable {
|
||||
public:
|
||||
Uncopyable() : value_(-1) {}
|
||||
explicit Uncopyable(int a_value) : value_(a_value) {}
|
||||
|
||||
int value() const { return value_; }
|
||||
void set_value(int i) { value_ = i; }
|
||||
|
||||
private:
|
||||
const int value_;
|
||||
int value_;
|
||||
GTEST_DISALLOW_COPY_AND_ASSIGN_(Uncopyable);
|
||||
};
|
||||
|
||||
// Returns true iff x.value() is positive.
|
||||
bool ValueIsPositive(const Uncopyable& x) { return x.value() > 0; }
|
||||
|
||||
MATCHER_P(UncopyableIs, inner_matcher, "") {
|
||||
return ExplainMatchResult(inner_matcher, arg.value(), result_listener);
|
||||
}
|
||||
|
||||
// A user-defined struct for testing Field().
|
||||
struct AStruct {
|
||||
AStruct() : x(0), y(1.0), z(5), p(NULL) {}
|
||||
@ -4527,6 +4644,13 @@ TEST(ElemensAreArrayStreamTest, WorksForStreamlike) {
|
||||
EXPECT_THAT(s, Not(ElementsAreArray(expected)));
|
||||
}
|
||||
|
||||
TEST(ElementsAreTest, WorksWithUncopyable) {
|
||||
Uncopyable objs[2];
|
||||
objs[0].set_value(-3);
|
||||
objs[1].set_value(1);
|
||||
EXPECT_THAT(objs, ElementsAre(UncopyableIs(-3), Truly(ValueIsPositive)));
|
||||
}
|
||||
|
||||
// Tests for UnorderedElementsAreArray()
|
||||
|
||||
TEST(UnorderedElementsAreArrayTest, SucceedsWhenExpected) {
|
||||
@ -4609,6 +4733,14 @@ class UnorderedElementsAreTest : public testing::Test {
|
||||
typedef std::vector<int> IntVec;
|
||||
};
|
||||
|
||||
TEST_F(UnorderedElementsAreTest, WorksWithUncopyable) {
|
||||
Uncopyable objs[2];
|
||||
objs[0].set_value(-3);
|
||||
objs[1].set_value(1);
|
||||
EXPECT_THAT(objs,
|
||||
UnorderedElementsAre(Truly(ValueIsPositive), UncopyableIs(-3)));
|
||||
}
|
||||
|
||||
TEST_F(UnorderedElementsAreTest, SucceedsWhenExpected) {
|
||||
const int a[] = { 1, 2, 3 };
|
||||
std::vector<int> s(a, a + GTEST_ARRAY_SIZE_(a));
|
||||
@ -5332,3 +5464,4 @@ TEST(PointwiseTest, AllowsMonomorphicInnerMatcher) {
|
||||
|
||||
} // namespace gmock_matchers_test
|
||||
} // namespace testing
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user