Commit 79a367eb authored by jgm's avatar jgm
Browse files

Reduced template instantiation depth for the AllOf and AnyOf matchers. Also...

Reduced template instantiation depth for the AllOf and AnyOf matchers. Also some formatting changes.
parent 9bcb5f91
......@@ -36,13 +36,13 @@
#ifndef GMOCK_INCLUDE_GMOCK_GMOCK_ACTIONS_H_
#define GMOCK_INCLUDE_GMOCK_GMOCK_ACTIONS_H_
#include <algorithm>
#include <string>
#ifndef _WIN32_WCE
# include <errno.h>
#endif
#include <algorithm>
#include <string>
#include "gmock/internal/gmock-internal-utils.h"
#include "gmock/internal/gmock-port.h"
......@@ -189,6 +189,7 @@ class DefaultValue {
return value_ == NULL ?
internal::BuiltInDefaultValue<T>::Get() : *value_;
}
private:
static const T* value_;
};
......@@ -224,6 +225,7 @@ class DefaultValue<T&> {
return address_ == NULL ?
internal::BuiltInDefaultValue<T&>::Get() : *address_;
}
private:
static T* address_;
};
......
......@@ -117,6 +117,7 @@ class GTEST_API_ Cardinality {
// Describes the given actual call count to an ostream.
static void DescribeActualCallCountTo(int actual_call_count,
::std::ostream* os);
private:
internal::linked_ptr<const CardinalityInterface> impl_;
};
......
......@@ -381,7 +381,6 @@ class CallableHelper {
A7 a7, A8 a8, A9 a9, A10 a10) {
return function(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10);
}
}; // class CallableHelper
// An INTERNAL macro for extracting the type of a tuple field. It's
......@@ -1018,16 +1017,16 @@ DoAll(Action1 a1, Action2 a2, Action3 a3, Action4 a4, Action5 a5, Action6 a6,
// An internal macro needed for implementing ACTION*().
#define GMOCK_ACTION_ARG_TYPES_AND_NAMES_UNUSED_\
const args_type& args GTEST_ATTRIBUTE_UNUSED_,\
arg0_type arg0 GTEST_ATTRIBUTE_UNUSED_,\
arg1_type arg1 GTEST_ATTRIBUTE_UNUSED_,\
arg2_type arg2 GTEST_ATTRIBUTE_UNUSED_,\
arg3_type arg3 GTEST_ATTRIBUTE_UNUSED_,\
arg4_type arg4 GTEST_ATTRIBUTE_UNUSED_,\
arg5_type arg5 GTEST_ATTRIBUTE_UNUSED_,\
arg6_type arg6 GTEST_ATTRIBUTE_UNUSED_,\
arg7_type arg7 GTEST_ATTRIBUTE_UNUSED_,\
arg8_type arg8 GTEST_ATTRIBUTE_UNUSED_,\
const args_type& args GTEST_ATTRIBUTE_UNUSED_, \
arg0_type arg0 GTEST_ATTRIBUTE_UNUSED_, \
arg1_type arg1 GTEST_ATTRIBUTE_UNUSED_, \
arg2_type arg2 GTEST_ATTRIBUTE_UNUSED_, \
arg3_type arg3 GTEST_ATTRIBUTE_UNUSED_, \
arg4_type arg4 GTEST_ATTRIBUTE_UNUSED_, \
arg5_type arg5 GTEST_ATTRIBUTE_UNUSED_, \
arg6_type arg6 GTEST_ATTRIBUTE_UNUSED_, \
arg7_type arg7 GTEST_ATTRIBUTE_UNUSED_, \
arg8_type arg8 GTEST_ATTRIBUTE_UNUSED_, \
arg9_type arg9 GTEST_ATTRIBUTE_UNUSED_
// Sometimes you want to give an action explicit template parameters
......@@ -1433,9 +1432,9 @@ DoAll(Action1 a1, Action2 a2, Action3 a3, Action4 a4, Action5 a5, Action6 a6,
template <GMOCK_INTERNAL_DECL_##template_params\
GMOCK_INTERNAL_DECL_TYPE_##value_params>\
template <typename F>\
template <typename arg0_type, typename arg1_type, typename arg2_type,\
typename arg3_type, typename arg4_type, typename arg5_type,\
typename arg6_type, typename arg7_type, typename arg8_type,\
template <typename arg0_type, typename arg1_type, typename arg2_type, \
typename arg3_type, typename arg4_type, typename arg5_type, \
typename arg6_type, typename arg7_type, typename arg8_type, \
typename arg9_type>\
typename ::testing::internal::Function<F>::Result\
GMOCK_ACTION_CLASS_(name, value_params)<\
......
......@@ -136,7 +136,6 @@ $var Ts = [[$for j, [[T$j]]]]
}
]]
}; // class CallableHelper
// An INTERNAL macro for extracting the type of a tuple field. It's
......@@ -427,7 +426,7 @@ $range k 0..n-1
// An internal macro needed for implementing ACTION*().
#define GMOCK_ACTION_ARG_TYPES_AND_NAMES_UNUSED_\
const args_type& args GTEST_ATTRIBUTE_UNUSED_
$for k [[,\
$for k [[, \
arg$k[[]]_type arg$k GTEST_ATTRIBUTE_UNUSED_]]
......@@ -657,9 +656,9 @@ $for k [[, arg$k[[]]_type arg$k]]) const;\
template <GMOCK_INTERNAL_DECL_##template_params\
GMOCK_INTERNAL_DECL_TYPE_##value_params>\
template <typename F>\
template <typename arg0_type, typename arg1_type, typename arg2_type,\
typename arg3_type, typename arg4_type, typename arg5_type,\
typename arg6_type, typename arg7_type, typename arg8_type,\
template <typename arg0_type, typename arg1_type, typename arg2_type, \
typename arg3_type, typename arg4_type, typename arg5_type, \
typename arg6_type, typename arg7_type, typename arg8_type, \
typename arg9_type>\
typename ::testing::internal::Function<F>::Result\
GMOCK_ACTION_CLASS_(name, value_params)<\
......
This diff is collapsed.
......@@ -242,6 +242,66 @@ $for j [[
]]
// A set of metafunctions for computing the result type of AllOf.
// AllOf(m1, ..., mN) returns
// AllOfResultN<decltype(m1), ..., decltype(mN)>::type.
// Although AllOf isn't defined for one argument, AllOfResult1 is defined
// to simplify the implementation.
template <typename M1>
struct AllOfResult1 {
typedef M1 type;
};
$range i 1..n
$range i 2..n
$for i [[
$range j 2..i
$var m = i/2
$range k 1..m
$range t m+1..i
template <typename M1$for j [[, typename M$j]]>
struct AllOfResult$i {
typedef BothOfMatcher<
typename AllOfResult$m<$for k, [[M$k]]>::type,
typename AllOfResult$(i-m)<$for t, [[M$t]]>::type
> type;
};
]]
// A set of metafunctions for computing the result type of AnyOf.
// AnyOf(m1, ..., mN) returns
// AnyOfResultN<decltype(m1), ..., decltype(mN)>::type.
// Although AnyOf isn't defined for one argument, AnyOfResult1 is defined
// to simplify the implementation.
template <typename M1>
struct AnyOfResult1 {
typedef M1 type;
};
$range i 1..n
$range i 2..n
$for i [[
$range j 2..i
$var m = i/2
$range k 1..m
$range t m+1..i
template <typename M1$for j [[, typename M$j]]>
struct AnyOfResult$i {
typedef EitherOfMatcher<
typename AnyOfResult$m<$for k, [[M$k]]>::type,
typename AnyOfResult$(i-m)<$for t, [[M$t]]>::type
> type;
};
]]
} // namespace internal
// Args<N1, N2, ..., Nk>(a_matcher) matches a tuple if the selected
......@@ -308,19 +368,16 @@ ElementsAreArray(const T (&array)[N]) {
$range i 2..n
$for i [[
$range j 1..i
$range k 1..i-1
template <$for j, [[typename Matcher$j]]>
inline $for k[[internal::BothOfMatcher<Matcher$k, ]]Matcher$i[[]]$for k [[> ]]
AllOf($for j, [[Matcher$j m$j]]) {
$if i == 2 [[
return internal::BothOfMatcher<Matcher1, Matcher2>(m1, m2);
]] $else [[
return ::testing::AllOf(m1, ::testing::AllOf($for k, [[m$(k + 1)]]));
]]
$var m = i/2
$range k 1..m
$range t m+1..i
template <$for j, [[typename M$j]]>
inline typename internal::AllOfResult$i<$for j, [[M$j]]>::type
AllOf($for j, [[M$j m$j]]) {
return typename internal::AllOfResult$i<$for j, [[M$j]]>::type(
$if m == 1 [[m1]] $else [[::testing::AllOf($for k, [[m$k]])]],
$if m+1 == i [[m$i]] $else [[::testing::AllOf($for t, [[m$t]])]]);
}
]]
......@@ -331,19 +388,16 @@ $if i == 2 [[
$range i 2..n
$for i [[
$range j 1..i
$range k 1..i-1
template <$for j, [[typename Matcher$j]]>
inline $for k[[internal::EitherOfMatcher<Matcher$k, ]]Matcher$i[[]]$for k [[> ]]
AnyOf($for j, [[Matcher$j m$j]]) {
$if i == 2 [[
return internal::EitherOfMatcher<Matcher1, Matcher2>(m1, m2);
]] $else [[
return ::testing::AnyOf(m1, ::testing::AnyOf($for k, [[m$(k + 1)]]));
]]
$var m = i/2
$range k 1..m
$range t m+1..i
template <$for j, [[typename M$j]]>
inline typename internal::AnyOfResult$i<$for j, [[M$j]]>::type
AnyOf($for j, [[M$j m$j]]) {
return typename internal::AnyOfResult$i<$for j, [[M$j]]>::type(
$if m == 1 [[m1]] $else [[::testing::AnyOf($for k, [[m$k]])]],
$if m+1 == i [[m$i]] $else [[::testing::AnyOf($for t, [[m$t]])]]);
}
]]
......@@ -621,7 +675,7 @@ $var param_field_decls2 = [[$for j
if (!gmock_description.empty())\
return gmock_description;\
return ::testing::internal::FormatMatcherDescription(\
negation, #name,\
negation, #name, \
::testing::internal::UniversalTersePrintTupleFieldsToStrings(\
::std::tr1::tuple<$for j, [[p$j##_type]]>($for j, [[p$j]])));\
}\
......@@ -642,7 +696,7 @@ $var param_field_decls2 = [[$for j
}\$template
template <typename arg_type>\
bool $class_name$param_types::gmock_Impl<arg_type>::MatchAndExplain(\
arg_type arg,\
arg_type arg, \
::testing::MatchResultListener* result_listener GTEST_ATTRIBUTE_UNUSED_)\
const
]]
......
......@@ -384,12 +384,119 @@ inline PolymorphicMatcher<Impl> MakePolymorphicMatcher(const Impl& impl) {
return PolymorphicMatcher<Impl>(impl);
}
// Anything inside the 'internal' namespace IS INTERNAL IMPLEMENTATION
// and MUST NOT BE USED IN USER CODE!!!
namespace internal {
// The MatcherCastImpl class template is a helper for implementing
// MatcherCast(). We need this helper in order to partially
// specialize the implementation of MatcherCast() (C++ allows
// class/struct templates to be partially specialized, but not
// function templates.).
// This general version is used when MatcherCast()'s argument is a
// polymorphic matcher (i.e. something that can be converted to a
// Matcher but is not one yet; for example, Eq(value)) or a value (for
// example, "hello").
template <typename T, typename M>
class MatcherCastImpl {
public:
static Matcher<T> Cast(M polymorphic_matcher_or_value) {
// M can be a polymorhic matcher, in which case we want to use
// its conversion operator to create Matcher<T>. Or it can be a value
// that should be passed to the Matcher<T>'s constructor.
//
// We can't call Matcher<T>(polymorphic_matcher_or_value) when M is a
// polymorphic matcher because it'll be ambiguous if T has an implicit
// constructor from M (this usually happens when T has an implicit
// constructor from any type).
//
// It won't work to unconditionally implict_cast
// polymorphic_matcher_or_value to Matcher<T> because it won't trigger
// a user-defined conversion from M to T if one exists (assuming M is
// a value).
return CastImpl(
polymorphic_matcher_or_value,
BooleanConstant<
internal::ImplicitlyConvertible<M, Matcher<T> >::value>());
}
private:
static Matcher<T> CastImpl(M value, BooleanConstant<false>) {
// 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(M polymorphic_matcher_or_value,
BooleanConstant<true>) {
// M is implicitly convertible to Matcher<T>, which means that either
// M is a polymorhpic matcher or Matcher<T> has an implicit constructor
// from M. In both cases using the implicit conversion will produce a
// matcher.
//
// Even if T has an implicit constructor from M, it won't be called because
// creating Matcher<T> would require a chain of two user-defined conversions
// (first to create T from M and then to create Matcher<T> from T).
return polymorphic_matcher_or_value;
}
};
// This more specialized version is used when MatcherCast()'s argument
// is already a Matcher. This only compiles when type T can be
// statically converted to type U.
template <typename T, typename U>
class MatcherCastImpl<T, Matcher<U> > {
public:
static Matcher<T> Cast(const Matcher<U>& source_matcher) {
return Matcher<T>(new Impl(source_matcher));
}
private:
class Impl : public MatcherInterface<T> {
public:
explicit Impl(const Matcher<U>& source_matcher)
: source_matcher_(source_matcher) {}
// We delegate the matching logic to the source matcher.
virtual bool MatchAndExplain(T x, MatchResultListener* listener) const {
return source_matcher_.MatchAndExplain(static_cast<U>(x), listener);
}
virtual void DescribeTo(::std::ostream* os) const {
source_matcher_.DescribeTo(os);
}
virtual void DescribeNegationTo(::std::ostream* os) const {
source_matcher_.DescribeNegationTo(os);
}
private:
const Matcher<U> source_matcher_;
GTEST_DISALLOW_ASSIGN_(Impl);
};
};
// This even more specialized version is used for efficiently casting
// a matcher to its own type.
template <typename T>
class MatcherCastImpl<T, Matcher<T> > {
public:
static Matcher<T> Cast(const Matcher<T>& matcher) { return matcher; }
};
} // namespace internal
// In order to be safe and clear, casting between different matcher
// types is done explicitly via MatcherCast<T>(m), which takes a
// matcher m and returns a Matcher<T>. It compiles only when T can be
// statically converted to the argument type of m.
template <typename T, typename M>
Matcher<T> MatcherCast(M m);
inline Matcher<T> MatcherCast(M matcher) {
return internal::MatcherCastImpl<T, M>::Cast(matcher);
}
// Implements SafeMatcherCast().
//
......@@ -401,11 +508,11 @@ Matcher<T> MatcherCast(M m);
template <typename T>
class SafeMatcherCastImpl {
public:
// This overload handles polymorphic matchers only since monomorphic
// matchers are handled by the next one.
// This overload handles polymorphic matchers and values only since
// monomorphic matchers are handled by the next one.
template <typename M>
static inline Matcher<T> Cast(M polymorphic_matcher) {
return Matcher<T>(polymorphic_matcher);
static inline Matcher<T> Cast(M polymorphic_matcher_or_value) {
return internal::MatcherCastImpl<T, M>::Cast(polymorphic_matcher_or_value);
}
// This overload handles monomorphic matchers.
......@@ -600,67 +707,6 @@ void ExplainMatchFailureTupleTo(const MatcherTuple& matchers,
matchers, values, os);
}
// The MatcherCastImpl class template is a helper for implementing
// MatcherCast(). We need this helper in order to partially
// specialize the implementation of MatcherCast() (C++ allows
// class/struct templates to be partially specialized, but not
// function templates.).
// This general version is used when MatcherCast()'s argument is a
// polymorphic matcher (i.e. something that can be converted to a
// Matcher but is not one yet; for example, Eq(value)).
template <typename T, typename M>
class MatcherCastImpl {
public:
static Matcher<T> Cast(M polymorphic_matcher) {
return Matcher<T>(polymorphic_matcher);
}
};
// This more specialized version is used when MatcherCast()'s argument
// is already a Matcher. This only compiles when type T can be
// statically converted to type U.
template <typename T, typename U>
class MatcherCastImpl<T, Matcher<U> > {
public:
static Matcher<T> Cast(const Matcher<U>& source_matcher) {
return Matcher<T>(new Impl(source_matcher));
}
private:
class Impl : public MatcherInterface<T> {
public:
explicit Impl(const Matcher<U>& source_matcher)
: source_matcher_(source_matcher) {}
// We delegate the matching logic to the source matcher.
virtual bool MatchAndExplain(T x, MatchResultListener* listener) const {
return source_matcher_.MatchAndExplain(static_cast<U>(x), listener);
}
virtual void DescribeTo(::std::ostream* os) const {
source_matcher_.DescribeTo(os);
}
virtual void DescribeNegationTo(::std::ostream* os) const {
source_matcher_.DescribeNegationTo(os);
}
private:
const Matcher<U> source_matcher_;
GTEST_DISALLOW_ASSIGN_(Impl);
};
};
// This even more specialized version is used for efficiently casting
// a matcher to its own type.
template <typename T>
class MatcherCastImpl<T, Matcher<T> > {
public:
static Matcher<T> Cast(const Matcher<T>& matcher) { return matcher; }
};
// Implements A<T>().
template <typename T>
class AnyMatcherImpl : public MatcherInterface<T> {
......@@ -1596,6 +1642,7 @@ class FloatingEqMatcher {
operator Matcher<FloatType&>() const {
return MakeMatcher(new Impl<FloatType&>(rhs_, nan_eq_nan_));
}
private:
const FloatType rhs_;
const bool nan_eq_nan_;
......@@ -2633,12 +2680,6 @@ GTEST_API_ string FormatMatcherDescription(bool negation,
} // namespace internal
// Implements MatcherCast().
template <typename T, typename M>
inline Matcher<T> MatcherCast(M matcher) {
return internal::MatcherCastImpl<T, M>::Cast(matcher);
}
// _ is a matcher that matches anything of any type.
//
// This definition is fine as:
......
......@@ -384,6 +384,7 @@ class GTEST_API_ Mock {
// verification was successful.
static bool VerifyAndClear(void* mock_obj)
GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex);
private:
friend class internal::UntypedFunctionMockerBase;
......
// This file was GENERATED by a script. DO NOT EDIT BY HAND!!!
// This file was GENERATED by command:
// pump.py gmock-generated-internal-utils.h.pump
// DO NOT EDIT BY HAND!!!
// Copyright 2007, Google Inc.
// All rights reserved.
......@@ -58,7 +60,7 @@ class IgnoredValue {
// deliberately omit the 'explicit' keyword in order to allow the
// conversion to be implicit.
template <typename T>
IgnoredValue(const T&) {}
IgnoredValue(const T& /* ignored */) {} // NOLINT(runtime/explicit)
};
// MatcherTuple<T>::type is a tuple type where each field is a Matcher
......
......@@ -61,7 +61,7 @@ class IgnoredValue {
// deliberately omit the 'explicit' keyword in order to allow the
// conversion to be implicit.
template <typename T>
IgnoredValue(const T&) {}
IgnoredValue(const T& /* ignored */) {} // NOLINT(runtime/explicit)
};
// MatcherTuple<T>::type is a tuple type where each field is a Matcher
......
......@@ -354,7 +354,8 @@ template <typename T> struct remove_reference<T&> { typedef T type; }; // NOLINT
// crashes).
template <typename T>
inline T Invalid() {
return *static_cast<typename remove_reference<T>::type*>(NULL);
return const_cast<typename remove_reference<T>::type&>(
*static_cast<volatile typename remove_reference<T>::type*>(NULL));
}
template <>
inline void Invalid<void>() {}
......@@ -459,6 +460,11 @@ class StlContainerView< ::std::tr1::tuple<ElementPointer, Size> > {
// StlContainer with a reference type.
template <typename T> class StlContainerView<T&>;
// Mapping from booleans to types. Similar to boost::bool_<kValue> and
// std::integral_constant<bool, kValue>.
template <bool kValue>
struct BooleanConstant {};
} // namespace internal
} // namespace testing
......
......@@ -416,7 +416,7 @@ def _NeedToUseReturnNullDiagnoser(msg):
'::operator testing::Action<Func>\(\) const.*\n' +
_GCC_FILE_LINE_RE + r'instantiated from here\n'
r'.*error: no matching function for call to \'ImplicitCast_\('
r'long int&\)')
r'(:?long )?int&\)')
clang_regex = (r'\bgmock-actions.h:.* error: no matching function for '
r'call to \'ImplicitCast_\'\r?\n'
r'(.*\n)*?' +
......
......@@ -75,7 +75,7 @@ class BetweenCardinalityImpl : public CardinalityInterface {
virtual int ConservativeUpperBound() const { return max_; }
virtual bool IsSatisfiedByCallCount(int call_count) const {
return min_ <= call_count && call_count <= max_ ;
return min_ <= call_count && call_count <= max_;
}
virtual bool IsSaturatedByCallCount(int call_count) const {
......@@ -83,6 +83,7 @@ class BetweenCardinalityImpl : public CardinalityInterface {
}
virtual void DescribeTo(::std::ostream* os) const;
private:
const int min_;
const int max_;
......
......@@ -579,6 +579,7 @@ class MockObjectRegistry {
}
StateMap& states() { return states_; }
private:
StateMap states_;
};
......
......@@ -518,7 +518,7 @@ TEST(ReturnTest, IsCovariant) {
// gmock-actions.h for more information.
class FromType {
public:
FromType(bool* is_converted) : converted_(is_converted) {}
explicit FromType(bool* is_converted) : converted_(is_converted) {}
bool* converted() const { return converted_; }
private:
......@@ -529,7 +529,8 @@ class FromType {
class ToType {
public:
ToType(const FromType& x) { *x.converted() = true; }
// Must allow implicit conversion due to use in ImplicitCast_<T>.
ToType(const FromType& x) { *x.converted() = true; } // NOLINT
};
TEST(ReturnTest, ConvertsArgumentWhenConverted) {
......@@ -541,7 +542,7 @@ TEST(ReturnTest, ConvertsArgumentWhenConverted) {
converted = false;
action.Perform(tuple<>());
EXPECT_FALSE(converted) << "Action must NOT convert its argument "
<< "when performed." ;
<< "when performed.";
}
class DestinationType {};
......@@ -1226,7 +1227,8 @@ TEST(ByRefTest, IsCopyable) {
const std::string s1 = "Hi";
const std::string s2 = "Hello";
::testing::internal::ReferenceWrapper<const std::string> ref_wrapper = ByRef(s1);
::testing::internal::ReferenceWrapper<const std::string> ref_wrapper =
ByRef(s1);
const std::string& r1 = ref_wrapper;
EXPECT_EQ(&s1, &r1);
......@@ -1235,7 +1237,8 @@ TEST(ByRefTest, IsCopyable) {
const std::string& r2 = ref_wrapper;
EXPECT_EQ(&s2, &r2);
::testing::internal::ReferenceWrapper<const std::string> ref_wrapper1 = ByRef(s1);
::testing::internal::ReferenceWrapper<const std::string> ref_wrapper1 =
ByRef(s1);
// Copies ref_wrapper1 to ref_wrapper.
ref_wrapper = ref_wrapper1;
const std::string& r3 = ref_wrapper;
......
......@@ -35,11 +35,6 @@
#include "gmock/gmock-generated-function-mockers.h"
#include <map>
#include <string>
#include "gmock/gmock.h"
#include "gtest/gtest.h"
#if GTEST_OS_WINDOWS
// MSDN says the header file to be included for STDMETHOD is BaseTyps.h but
// we are getting compiler errors if we use basetyps.h, hence including
......@@ -47,6 +42,11 @@
# include <objbase.h>
#endif // GTEST_OS_WINDOWS
#include <map>
#include <string>
#include "gmock/gmock.h"
#include "gtest/gtest.h"
// There is a bug in MSVC (fixed in VS 2008) that prevents creating a
// mock for a function with const arguments, so we don't test such
// cases for MSVC versions older than 2008.
......
......@@ -1091,6 +1091,20 @@ TEST(ContainsTest, WorksForTwoDimensionalNativeArray) {
EXPECT_THAT(a, Contains(Not(Contains(5))));
}
TEST(AllOfTest, HugeMatcher) {
// Verify that using AllOf with many arguments doesn't cause
// the compiler to exceed template instantiation depth limit.
EXPECT_THAT(0, testing::AllOf(_, _, _, _, _, _, _, _, _,
testing::AllOf(_, _, _, _, _, _, _, _, _, _)));
}
TEST(AnyOfTest, HugeMatcher) {
// Verify that using AnyOf with many arguments doesn't cause
// the compiler to exceed template instantiation depth limit.
EXPECT_THAT(0, testing::AnyOf(_, _, _, _, _, _, _, _, _,
testing::AnyOf(_, _, _, _, _, _, _, _, _, _)));
}
namespace adl_test {
// Verifies that the implementation of ::testing::AllOf and ::testing::AnyOf
......
......@@ -545,6 +545,37 @@ TEST(MatcherCastTest, FromSameType) {
EXPECT_FALSE(m2.Matches(1));
}
// Implicitly convertible form any type.
struct ConvertibleFromAny {
ConvertibleFromAny(int a_value) : value(a_value) {}
template <typename T>
ConvertibleFromAny(const T& a_value) : value(-1) {
ADD_FAILURE() << "Conversion constructor called";
}
int value;
};
bool operator==(const ConvertibleFromAny& a, const ConvertibleFromAny& b) {
return a.value == b.value;
}
ostream& operator<<(ostream& os, const ConvertibleFromAny& a) {
return os << a.value;
}
TEST(MatcherCastTest, ConversionConstructorIsUsed) {
Matcher<ConvertibleFromAny> m = MatcherCast<ConvertibleFromAny>(1);
EXPECT_TRUE(m.Matches(ConvertibleFromAny(1)));
EXPECT_FALSE(m.Matches(ConvertibleFromAny(2)));
}
TEST(MatcherCastTest, FromConvertibleFromAny) {
Matcher<ConvertibleFromAny> m =
MatcherCast<ConvertibleFromAny>(Eq(ConvertibleFromAny(1)));
EXPECT_TRUE(m.Matches(ConvertibleFromAny(1)));
EXPECT_FALSE(m.Matches(ConvertibleFromAny(2)));
}
class Base {};
class Derived : public Base {};
......@@ -620,6 +651,19 @@ TEST(SafeMatcherCastTest, FromSameType) {
EXPECT_FALSE(m2.Matches(1));
}
TEST(SafeMatcherCastTest, ConversionConstructorIsUsed) {
Matcher<ConvertibleFromAny> m = SafeMatcherCast<ConvertibleFromAny>(1);
EXPECT_TRUE(m.Matches(ConvertibleFromAny(1)));
EXPECT_FALSE(m.Matches(ConvertibleFromAny(2)));
}
TEST(SafeMatcherCastTest, FromConvertibleFromAny) {
Matcher<ConvertibleFromAny> m =
SafeMatcherCast<ConvertibleFromAny>(Eq(ConvertibleFromAny(1)));
EXPECT_TRUE(m.Matches(ConvertibleFromAny(1)));
EXPECT_FALSE(m.Matches(ConvertibleFromAny(2)));
}
// Tests that A<T>() matches any value of type T.
TEST(ATest, MatchesAnyValue) {
// Tests a matcher for a value type.
......@@ -1940,19 +1984,19 @@ TEST(AllOfTest, CanDescribeSelf) {
m = AllOf(Gt(0), Ne(1), Ne(2), Ne(3));
EXPECT_EQ("(is > 0) and "
"((isn't equal to 1) and "
EXPECT_EQ("((is > 0) and "
"(isn't equal to 1)) and "
"((isn't equal to 2) and "
"(isn't equal to 3)))",
"(isn't equal to 3))",
Describe(m));
m = AllOf(Ge(0), Lt(10), Ne(3), Ne(5), Ne(7));
EXPECT_EQ("(is >= 0) and "
"((is < 10) and "
EXPECT_EQ("((is >= 0) and "
"(is < 10)) and "
"((isn't equal to 3) and "
"((isn't equal to 5) and "
"(isn't equal to 7))))",
"(isn't equal to 7)))",
Describe(m));
}
......@@ -1972,19 +2016,19 @@ TEST(AllOfTest, CanDescribeNegation) {
m = AllOf(Gt(0), Ne(1), Ne(2), Ne(3));
EXPECT_EQ("(isn't > 0) or "
"((is equal to 1) or "
EXPECT_EQ("((isn't > 0) or "
"(is equal to 1)) or "
"((is equal to 2) or "
"(is equal to 3)))",
"(is equal to 3))",
DescribeNegation(m));
m = AllOf(Ge(0), Lt(10), Ne(3), Ne(5), Ne(7));
EXPECT_EQ("(isn't >= 0) or "
"((isn't < 10) or "
EXPECT_EQ("((isn't >= 0) or "
"(isn't < 10)) or "
"((is equal to 3) or "
"((is equal to 5) or "
"(is equal to 7))))",
"(is equal to 7)))",
DescribeNegation(m));
}
......@@ -2112,18 +2156,18 @@ TEST(AnyOfTest, CanDescribeSelf) {
Describe(m));
m = AnyOf(Lt(0), Eq(1), Eq(2), Eq(3));
EXPECT_EQ("(is < 0) or "
"((is equal to 1) or "
EXPECT_EQ("((is < 0) or "
"(is equal to 1)) or "
"((is equal to 2) or "
"(is equal to 3)))",
"(is equal to 3))",
Describe(m));
m = AnyOf(Le(0), Gt(10), 3, 5, 7);
EXPECT_EQ("(is <= 0) or "
"((is > 10) or "
EXPECT_EQ("((is <= 0) or "
"(is > 10)) or "
"((is equal to 3) or "
"((is equal to 5) or "
"(is equal to 7))))",
"(is equal to 7)))",
Describe(m));
}
......@@ -2140,18 +2184,18 @@ TEST(AnyOfTest, CanDescribeNegation) {
DescribeNegation(m));
m = AnyOf(Lt(0), Eq(1), Eq(2), Eq(3));
EXPECT_EQ("(isn't < 0) and "
"((isn't equal to 1) and "
EXPECT_EQ("((isn't < 0) and "
"(isn't equal to 1)) and "
"((isn't equal to 2) and "
"(isn't equal to 3)))",
"(isn't equal to 3))",
DescribeNegation(m));
m = AnyOf(Le(0), Gt(10), 3, 5, 7);
EXPECT_EQ("(isn't <= 0) and "
"((isn't > 10) and "
EXPECT_EQ("((isn't <= 0) and "
"(isn't > 10)) and "
"((isn't equal to 3) and "
"((isn't equal to 5) and "
"(isn't equal to 7))))",
"(isn't equal to 7)))",
DescribeNegation(m));
}
......
......@@ -225,6 +225,7 @@ class Foo {
const char* s10) {
return string(s1) + s2 + s3 + s4 + s5 + s6 + s7 + s8 + s9 + s10;
}
private:
int value_;
};
......
......@@ -195,8 +195,8 @@ class Interface {
virtual char* StringFromString(char* str) = 0;
virtual int IntFromString(char* str) = 0;
virtual int& IntRefFromString(char* str) = 0;
virtual void VoidFromFunc(void(*)(char*)) = 0;
virtual void VoidFromIntRef(int& n) = 0;
virtual void VoidFromFunc(void(*func)(char* str)) = 0;
virtual void VoidFromIntRef(int& n) = 0; // NOLINT
virtual void VoidFromFloat(float n) = 0;
virtual void VoidFromDouble(double n) = 0;
virtual void VoidFromVector(const std::vector<int>& v) = 0;
......@@ -211,7 +211,7 @@ class Mock: public Interface {
MOCK_METHOD1(IntFromString, int(char* str));
MOCK_METHOD1(IntRefFromString, int&(char* str));
MOCK_METHOD1(VoidFromFunc, void(void(*func)(char* str)));
MOCK_METHOD1(VoidFromIntRef, void(int& n));
MOCK_METHOD1(VoidFromIntRef, void(int& n)); // NOLINT
MOCK_METHOD1(VoidFromFloat, void(float n));
MOCK_METHOD1(VoidFromDouble, void(double n));
MOCK_METHOD1(VoidFromVector, void(const std::vector<int>& v));
......@@ -224,15 +224,15 @@ class InvokeHelper {
public:
static void StaticVoidFromVoid() {}
void VoidFromVoid() {}
static void StaticVoidFromString(char*) {}
void VoidFromString(char*) {}
static int StaticIntFromString(char*) { return 1; }
static bool StaticBoolFromString(const char*) { return true; }
static void StaticVoidFromString(char* /* str */) {}
void VoidFromString(char* /* str */) {}
static int StaticIntFromString(char* /* str */) { return 1; }
static bool StaticBoolFromString(const char* /* str */) { return true; }
};
class FieldHelper {
public:
FieldHelper(int a_field) : field_(a_field) {}
explicit FieldHelper(int a_field) : field_(a_field) {}
int field() const { return field_; }
int field_; // NOLINT -- need external access to field_ to test
// the Field matcher.
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment