|
|
|
@ -27,7 +27,6 @@ |
|
|
|
|
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
|
|
|
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Google Mock - a framework for writing C++ mock classes.
|
|
|
|
|
//
|
|
|
|
|
// The MATCHER* family of macros can be used in a namespace scope to
|
|
|
|
@ -394,7 +393,7 @@ class MatcherCastImpl { |
|
|
|
|
// 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> > { |
|
|
|
|
class MatcherCastImpl<T, Matcher<U>> { |
|
|
|
|
public: |
|
|
|
|
static Matcher<T> Cast(const Matcher<U>& source_matcher) { |
|
|
|
|
return Matcher<T>(new Impl(source_matcher)); |
|
|
|
@ -448,7 +447,7 @@ class MatcherCastImpl<T, Matcher<U> > { |
|
|
|
|
// This even more specialized version is used for efficiently casting
|
|
|
|
|
// a matcher to its own type.
|
|
|
|
|
template <typename T> |
|
|
|
|
class MatcherCastImpl<T, Matcher<T> > { |
|
|
|
|
class MatcherCastImpl<T, Matcher<T>> { |
|
|
|
|
public: |
|
|
|
|
static Matcher<T> Cast(const Matcher<T>& matcher) { return matcher; } |
|
|
|
|
}; |
|
|
|
@ -542,7 +541,7 @@ inline Matcher<T> SafeMatcherCast(const Matcher<U>& matcher) { |
|
|
|
|
constexpr bool kUIsOther = GMOCK_KIND_OF_(RawU) == internal::kOther; |
|
|
|
|
GTEST_COMPILE_ASSERT_( |
|
|
|
|
kTIsOther || kUIsOther || |
|
|
|
|
(internal::LosslessArithmeticConvertible<RawT, RawU>::value), |
|
|
|
|
(internal::LosslessArithmeticConvertible<RawT, RawU>::value), |
|
|
|
|
conversion_of_arithmetic_types_must_be_lossless); |
|
|
|
|
return MatcherCast<T>(matcher); |
|
|
|
|
} |
|
|
|
@ -687,8 +686,7 @@ bool TupleMatches(const MatcherTuple& matcher_tuple, |
|
|
|
|
// is no failure, nothing will be streamed to os.
|
|
|
|
|
template <typename MatcherTuple, typename ValueTuple> |
|
|
|
|
void ExplainMatchFailureTupleTo(const MatcherTuple& matchers, |
|
|
|
|
const ValueTuple& values, |
|
|
|
|
::std::ostream* os) { |
|
|
|
|
const ValueTuple& values, ::std::ostream* os) { |
|
|
|
|
TuplePrefix<std::tuple_size<MatcherTuple>::value>::ExplainMatchFailuresTo( |
|
|
|
|
matchers, values, os); |
|
|
|
|
} |
|
|
|
@ -712,14 +710,14 @@ class TransformTupleValuesHelper { |
|
|
|
|
private: |
|
|
|
|
template <typename Tup, size_t kRemainingSize> |
|
|
|
|
struct IterateOverTuple { |
|
|
|
|
OutIter operator() (Func f, const Tup& t, OutIter out) const { |
|
|
|
|
OutIter operator()(Func f, const Tup& t, OutIter out) const { |
|
|
|
|
*out++ = f(::std::get<TupleSize::value - kRemainingSize>(t)); |
|
|
|
|
return IterateOverTuple<Tup, kRemainingSize - 1>()(f, t, out); |
|
|
|
|
} |
|
|
|
|
}; |
|
|
|
|
template <typename Tup> |
|
|
|
|
struct IterateOverTuple<Tup, 0> { |
|
|
|
|
OutIter operator() (Func /* f */, const Tup& /* t */, OutIter out) const { |
|
|
|
|
OutIter operator()(Func /* f */, const Tup& /* t */, OutIter out) const { |
|
|
|
|
return out; |
|
|
|
|
} |
|
|
|
|
}; |
|
|
|
@ -765,9 +763,7 @@ class IsNullMatcher { |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void DescribeTo(::std::ostream* os) const { *os << "is NULL"; } |
|
|
|
|
void DescribeNegationTo(::std::ostream* os) const { |
|
|
|
|
*os << "isn't NULL"; |
|
|
|
|
} |
|
|
|
|
void DescribeNegationTo(::std::ostream* os) const { *os << "isn't NULL"; } |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
// Implements the polymorphic NotNull() matcher, which matches any raw or smart
|
|
|
|
@ -781,9 +777,7 @@ class NotNullMatcher { |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void DescribeTo(::std::ostream* os) const { *os << "isn't NULL"; } |
|
|
|
|
void DescribeNegationTo(::std::ostream* os) const { |
|
|
|
|
*os << "is NULL"; |
|
|
|
|
} |
|
|
|
|
void DescribeNegationTo(::std::ostream* os) const { *os << "is NULL"; } |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
// Ref(variable) matches any argument that is a reference to
|
|
|
|
@ -869,8 +863,7 @@ inline bool CaseInsensitiveCStringEquals(const wchar_t* lhs, |
|
|
|
|
// String comparison for narrow or wide strings that can have embedded NUL
|
|
|
|
|
// characters.
|
|
|
|
|
template <typename StringType> |
|
|
|
|
bool CaseInsensitiveStringEquals(const StringType& s1, |
|
|
|
|
const StringType& s2) { |
|
|
|
|
bool CaseInsensitiveStringEquals(const StringType& s1, const StringType& s2) { |
|
|
|
|
// Are the heads equal?
|
|
|
|
|
if (!CaseInsensitiveCStringEquals(s1.c_str(), s2.c_str())) { |
|
|
|
|
return false; |
|
|
|
@ -931,8 +924,8 @@ class StrEqualityMatcher { |
|
|
|
|
bool MatchAndExplain(const MatcheeStringType& s, |
|
|
|
|
MatchResultListener* /* listener */) const { |
|
|
|
|
const StringType s2(s); |
|
|
|
|
const bool eq = case_sensitive_ ? s2 == string_ : |
|
|
|
|
CaseInsensitiveStringEquals(s2, string_); |
|
|
|
|
const bool eq = case_sensitive_ ? s2 == string_ |
|
|
|
|
: CaseInsensitiveStringEquals(s2, string_); |
|
|
|
|
return expect_eq_ == eq; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -1019,8 +1012,7 @@ class HasSubstrMatcher { |
|
|
|
|
template <typename StringType> |
|
|
|
|
class StartsWithMatcher { |
|
|
|
|
public: |
|
|
|
|
explicit StartsWithMatcher(const StringType& prefix) : prefix_(prefix) { |
|
|
|
|
} |
|
|
|
|
explicit StartsWithMatcher(const StringType& prefix) : prefix_(prefix) {} |
|
|
|
|
|
|
|
|
|
#if GTEST_INTERNAL_HAS_STRING_VIEW |
|
|
|
|
bool MatchAndExplain(const internal::StringView& s, |
|
|
|
@ -1051,7 +1043,7 @@ class StartsWithMatcher { |
|
|
|
|
MatchResultListener* /* listener */) const { |
|
|
|
|
const StringType& s2(s); |
|
|
|
|
return s2.length() >= prefix_.length() && |
|
|
|
|
s2.substr(0, prefix_.length()) == prefix_; |
|
|
|
|
s2.substr(0, prefix_.length()) == prefix_; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void DescribeTo(::std::ostream* os) const { |
|
|
|
@ -1105,7 +1097,7 @@ class EndsWithMatcher { |
|
|
|
|
MatchResultListener* /* listener */) const { |
|
|
|
|
const StringType& s2(s); |
|
|
|
|
return s2.length() >= suffix_.length() && |
|
|
|
|
s2.substr(s2.length() - suffix_.length()) == suffix_; |
|
|
|
|
s2.substr(s2.length() - suffix_.length()) == suffix_; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void DescribeTo(::std::ostream* os) const { |
|
|
|
@ -1234,8 +1226,7 @@ class Ge2Matcher : public PairMatchBase<Ge2Matcher, AnyGe> { |
|
|
|
|
template <typename T> |
|
|
|
|
class NotMatcherImpl : public MatcherInterface<const T&> { |
|
|
|
|
public: |
|
|
|
|
explicit NotMatcherImpl(const Matcher<T>& matcher) |
|
|
|
|
: matcher_(matcher) {} |
|
|
|
|
explicit NotMatcherImpl(const Matcher<T>& matcher) : matcher_(matcher) {} |
|
|
|
|
|
|
|
|
|
bool MatchAndExplain(const T& x, |
|
|
|
|
MatchResultListener* listener) const override { |
|
|
|
@ -1279,7 +1270,7 @@ class NotMatcher { |
|
|
|
|
template <typename T> |
|
|
|
|
class AllOfMatcherImpl : public MatcherInterface<const T&> { |
|
|
|
|
public: |
|
|
|
|
explicit AllOfMatcherImpl(std::vector<Matcher<T> > matchers) |
|
|
|
|
explicit AllOfMatcherImpl(std::vector<Matcher<T>> matchers) |
|
|
|
|
: matchers_(std::move(matchers)) {} |
|
|
|
|
|
|
|
|
|
void DescribeTo(::std::ostream* os) const override { |
|
|
|
@ -1330,7 +1321,7 @@ class AllOfMatcherImpl : public MatcherInterface<const T&> { |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
private: |
|
|
|
|
const std::vector<Matcher<T> > matchers_; |
|
|
|
|
const std::vector<Matcher<T>> matchers_; |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
// VariadicMatcher is used for the variadic implementation of
|
|
|
|
@ -1353,14 +1344,14 @@ class VariadicMatcher { |
|
|
|
|
// all of the provided matchers (Matcher1, Matcher2, ...) can match.
|
|
|
|
|
template <typename T> |
|
|
|
|
operator Matcher<T>() const { |
|
|
|
|
std::vector<Matcher<T> > values; |
|
|
|
|
std::vector<Matcher<T>> values; |
|
|
|
|
CreateVariadicMatcher<T>(&values, std::integral_constant<size_t, 0>()); |
|
|
|
|
return Matcher<T>(new CombiningMatcher<T>(std::move(values))); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
private: |
|
|
|
|
template <typename T, size_t I> |
|
|
|
|
void CreateVariadicMatcher(std::vector<Matcher<T> >* values, |
|
|
|
|
void CreateVariadicMatcher(std::vector<Matcher<T>>* values, |
|
|
|
|
std::integral_constant<size_t, I>) const { |
|
|
|
|
values->push_back(SafeMatcherCast<T>(std::get<I>(matchers_))); |
|
|
|
|
CreateVariadicMatcher<T>(values, std::integral_constant<size_t, I + 1>()); |
|
|
|
@ -1368,7 +1359,7 @@ class VariadicMatcher { |
|
|
|
|
|
|
|
|
|
template <typename T> |
|
|
|
|
void CreateVariadicMatcher( |
|
|
|
|
std::vector<Matcher<T> >*, |
|
|
|
|
std::vector<Matcher<T>>*, |
|
|
|
|
std::integral_constant<size_t, sizeof...(Args)>) const {} |
|
|
|
|
|
|
|
|
|
std::tuple<Args...> matchers_; |
|
|
|
@ -1384,7 +1375,7 @@ using AllOfMatcher = VariadicMatcher<AllOfMatcherImpl, Args...>; |
|
|
|
|
template <typename T> |
|
|
|
|
class AnyOfMatcherImpl : public MatcherInterface<const T&> { |
|
|
|
|
public: |
|
|
|
|
explicit AnyOfMatcherImpl(std::vector<Matcher<T> > matchers) |
|
|
|
|
explicit AnyOfMatcherImpl(std::vector<Matcher<T>> matchers) |
|
|
|
|
: matchers_(std::move(matchers)) {} |
|
|
|
|
|
|
|
|
|
void DescribeTo(::std::ostream* os) const override { |
|
|
|
@ -1435,7 +1426,7 @@ class AnyOfMatcherImpl : public MatcherInterface<const T&> { |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
private: |
|
|
|
|
const std::vector<Matcher<T> > matchers_; |
|
|
|
|
const std::vector<Matcher<T>> matchers_; |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
// AnyOfMatcher is used for the variadic implementation of AnyOf(m_1, m_2, ...).
|
|
|
|
@ -1462,8 +1453,6 @@ class ConditionalMatcher { |
|
|
|
|
bool condition_; |
|
|
|
|
MatcherTrue matcher_true_; |
|
|
|
|
MatcherFalse matcher_false_; |
|
|
|
|
|
|
|
|
|
GTEST_DISALLOW_ASSIGN_(ConditionalMatcher); |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
// Wrapper for implementation of Any/AllOfArray().
|
|
|
|
@ -1515,8 +1504,7 @@ class TrulyMatcher { |
|
|
|
|
// We cannot write 'return !!predicate_(x);' as that doesn't work
|
|
|
|
|
// when predicate_(x) returns a class convertible to bool but
|
|
|
|
|
// having no operator!().
|
|
|
|
|
if (predicate_(x)) |
|
|
|
|
return true; |
|
|
|
|
if (predicate_(x)) return true; |
|
|
|
|
*listener << "didn't satisfy the given predicate"; |
|
|
|
|
return false; |
|
|
|
|
} |
|
|
|
@ -1624,8 +1612,8 @@ class PredicateFormatterFromMatcher { |
|
|
|
|
// used for implementing ASSERT_THAT() and EXPECT_THAT().
|
|
|
|
|
// Implementation detail: 'matcher' is received by-value to force decaying.
|
|
|
|
|
template <typename M> |
|
|
|
|
inline PredicateFormatterFromMatcher<M> |
|
|
|
|
MakePredicateFormatterFromMatcher(M matcher) { |
|
|
|
|
inline PredicateFormatterFromMatcher<M> MakePredicateFormatterFromMatcher( |
|
|
|
|
M matcher) { |
|
|
|
|
return PredicateFormatterFromMatcher<M>(std::move(matcher)); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -1640,9 +1628,7 @@ class IsNanMatcher { |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void DescribeTo(::std::ostream* os) const { *os << "is NaN"; } |
|
|
|
|
void DescribeNegationTo(::std::ostream* os) const { |
|
|
|
|
*os << "isn't NaN"; |
|
|
|
|
} |
|
|
|
|
void DescribeNegationTo(::std::ostream* os) const { *os << "isn't NaN"; } |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
// Implements the polymorphic floating point equality matcher, which matches
|
|
|
|
@ -1658,9 +1644,8 @@ class FloatingEqMatcher { |
|
|
|
|
// equality comparisons between NANs will always return false. We specify a
|
|
|
|
|
// negative max_abs_error_ term to indicate that ULP-based approximation will
|
|
|
|
|
// be used for comparison.
|
|
|
|
|
FloatingEqMatcher(FloatType expected, bool nan_eq_nan) : |
|
|
|
|
expected_(expected), nan_eq_nan_(nan_eq_nan), max_abs_error_(-1) { |
|
|
|
|
} |
|
|
|
|
FloatingEqMatcher(FloatType expected, bool nan_eq_nan) |
|
|
|
|
: expected_(expected), nan_eq_nan_(nan_eq_nan), max_abs_error_(-1) {} |
|
|
|
|
|
|
|
|
|
// Constructor that supports a user-specified max_abs_error that will be used
|
|
|
|
|
// for comparison instead of ULP-based approximation. The max absolute
|
|
|
|
@ -1722,8 +1707,8 @@ class FloatingEqMatcher { |
|
|
|
|
// os->precision() returns the previously set precision, which we
|
|
|
|
|
// store to restore the ostream to its original configuration
|
|
|
|
|
// after outputting.
|
|
|
|
|
const ::std::streamsize old_precision = os->precision( |
|
|
|
|
::std::numeric_limits<FloatType>::digits10 + 2); |
|
|
|
|
const ::std::streamsize old_precision = |
|
|
|
|
os->precision(::std::numeric_limits<FloatType>::digits10 + 2); |
|
|
|
|
if (FloatingPoint<FloatType>(expected_).is_nan()) { |
|
|
|
|
if (nan_eq_nan_) { |
|
|
|
|
*os << "is NaN"; |
|
|
|
@ -1741,8 +1726,8 @@ class FloatingEqMatcher { |
|
|
|
|
|
|
|
|
|
void DescribeNegationTo(::std::ostream* os) const override { |
|
|
|
|
// As before, get original precision.
|
|
|
|
|
const ::std::streamsize old_precision = os->precision( |
|
|
|
|
::std::numeric_limits<FloatType>::digits10 + 2); |
|
|
|
|
const ::std::streamsize old_precision = |
|
|
|
|
os->precision(::std::numeric_limits<FloatType>::digits10 + 2); |
|
|
|
|
if (FloatingPoint<FloatType>(expected_).is_nan()) { |
|
|
|
|
if (nan_eq_nan_) { |
|
|
|
|
*os << "isn't NaN"; |
|
|
|
@ -1760,9 +1745,7 @@ class FloatingEqMatcher { |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
private: |
|
|
|
|
bool HasMaxAbsError() const { |
|
|
|
|
return max_abs_error_ >= 0; |
|
|
|
|
} |
|
|
|
|
bool HasMaxAbsError() const { return max_abs_error_ >= 0; } |
|
|
|
|
|
|
|
|
|
const FloatType expected_; |
|
|
|
|
const bool nan_eq_nan_; |
|
|
|
@ -1834,9 +1817,8 @@ class FloatingEq2Matcher { |
|
|
|
|
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) {} |
|
|
|
|
Impl(FloatType max_abs_error, bool nan_eq_nan) |
|
|
|
|
: max_abs_error_(max_abs_error), nan_eq_nan_(nan_eq_nan) {} |
|
|
|
|
|
|
|
|
|
bool MatchAndExplain(Tuple args, |
|
|
|
|
MatchResultListener* listener) const override { |
|
|
|
@ -2012,9 +1994,7 @@ class WhenDynamicCastToMatcherBase { |
|
|
|
|
protected: |
|
|
|
|
const Matcher<To> matcher_; |
|
|
|
|
|
|
|
|
|
static std::string GetToName() { |
|
|
|
|
return GetTypeName<To>(); |
|
|
|
|
} |
|
|
|
|
static std::string GetToName() { return GetTypeName<To>(); } |
|
|
|
|
|
|
|
|
|
private: |
|
|
|
|
static void GetCastTypeDescription(::std::ostream* os) { |
|
|
|
@ -2151,7 +2131,7 @@ class PropertyMatcher { |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
template <typename T> |
|
|
|
|
bool MatchAndExplain(const T&value, MatchResultListener* listener) const { |
|
|
|
|
bool MatchAndExplain(const T& value, MatchResultListener* listener) const { |
|
|
|
|
return MatchAndExplainImpl( |
|
|
|
|
typename std::is_pointer<typename std::remove_const<T>::type>::type(), |
|
|
|
|
value, listener); |
|
|
|
@ -2203,16 +2183,16 @@ struct CallableTraits { |
|
|
|
|
|
|
|
|
|
// Specialization for function pointers.
|
|
|
|
|
template <typename ArgType, typename ResType> |
|
|
|
|
struct CallableTraits<ResType(*)(ArgType)> { |
|
|
|
|
struct CallableTraits<ResType (*)(ArgType)> { |
|
|
|
|
typedef ResType ResultType; |
|
|
|
|
typedef ResType(*StorageType)(ArgType); |
|
|
|
|
typedef ResType (*StorageType)(ArgType); |
|
|
|
|
|
|
|
|
|
static void CheckIsValid(ResType(*f)(ArgType)) { |
|
|
|
|
static void CheckIsValid(ResType (*f)(ArgType)) { |
|
|
|
|
GTEST_CHECK_(f != nullptr) |
|
|
|
|
<< "NULL function pointer is passed into ResultOf()."; |
|
|
|
|
} |
|
|
|
|
template <typename T> |
|
|
|
|
static ResType Invoke(ResType(*f)(ArgType), T arg) { |
|
|
|
|
static ResType Invoke(ResType (*f)(ArgType), T arg) { |
|
|
|
|
return (*f)(arg); |
|
|
|
|
} |
|
|
|
|
}; |
|
|
|
@ -2285,8 +2265,7 @@ template <typename SizeMatcher> |
|
|
|
|
class SizeIsMatcher { |
|
|
|
|
public: |
|
|
|
|
explicit SizeIsMatcher(const SizeMatcher& size_matcher) |
|
|
|
|
: size_matcher_(size_matcher) { |
|
|
|
|
} |
|
|
|
|
: size_matcher_(size_matcher) {} |
|
|
|
|
|
|
|
|
|
template <typename Container> |
|
|
|
|
operator Matcher<Container>() const { |
|
|
|
@ -2314,8 +2293,8 @@ class SizeIsMatcher { |
|
|
|
|
SizeType size = container.size(); |
|
|
|
|
StringMatchResultListener size_listener; |
|
|
|
|
const bool result = size_matcher_.MatchAndExplain(size, &size_listener); |
|
|
|
|
*listener |
|
|
|
|
<< "whose size " << size << (result ? " matches" : " doesn't match"); |
|
|
|
|
*listener << "whose size " << size |
|
|
|
|
<< (result ? " matches" : " doesn't match"); |
|
|
|
|
PrintIfNotEmpty(size_listener.str(), listener->stream()); |
|
|
|
|
return result; |
|
|
|
|
} |
|
|
|
@ -2344,8 +2323,9 @@ class BeginEndDistanceIsMatcher { |
|
|
|
|
template <typename Container> |
|
|
|
|
class Impl : public MatcherInterface<Container> { |
|
|
|
|
public: |
|
|
|
|
typedef internal::StlContainerView< |
|
|
|
|
GTEST_REMOVE_REFERENCE_AND_CONST_(Container)> ContainerView; |
|
|
|
|
typedef internal::StlContainerView<GTEST_REMOVE_REFERENCE_AND_CONST_( |
|
|
|
|
Container)> |
|
|
|
|
ContainerView; |
|
|
|
|
typedef typename std::iterator_traits< |
|
|
|
|
typename ContainerView::type::const_iterator>::difference_type |
|
|
|
|
DistanceType; |
|
|
|
@ -2426,15 +2406,14 @@ class ContainerEqMatcher { |
|
|
|
|
typename std::remove_const<LhsContainer>::type> |
|
|
|
|
LhsView; |
|
|
|
|
StlContainerReference lhs_stl_container = LhsView::ConstReference(lhs); |
|
|
|
|
if (lhs_stl_container == expected_) |
|
|
|
|
return true; |
|
|
|
|
if (lhs_stl_container == expected_) return true; |
|
|
|
|
|
|
|
|
|
::std::ostream* const os = listener->stream(); |
|
|
|
|
if (os != nullptr) { |
|
|
|
|
// Something is different. Check for extra values first.
|
|
|
|
|
bool printed_header = false; |
|
|
|
|
for (auto it = lhs_stl_container.begin(); |
|
|
|
|
it != lhs_stl_container.end(); ++it) { |
|
|
|
|
for (auto it = lhs_stl_container.begin(); it != lhs_stl_container.end(); |
|
|
|
|
++it) { |
|
|
|
|
if (internal::ArrayAwareFind(expected_.begin(), expected_.end(), *it) == |
|
|
|
|
expected_.end()) { |
|
|
|
|
if (printed_header) { |
|
|
|
@ -2449,11 +2428,10 @@ class ContainerEqMatcher { |
|
|
|
|
|
|
|
|
|
// Now check for missing values.
|
|
|
|
|
bool printed_header2 = false; |
|
|
|
|
for (auto it = expected_.begin(); |
|
|
|
|
it != expected_.end(); ++it) { |
|
|
|
|
if (internal::ArrayAwareFind( |
|
|
|
|
lhs_stl_container.begin(), lhs_stl_container.end(), *it) == |
|
|
|
|
lhs_stl_container.end()) { |
|
|
|
|
for (auto it = expected_.begin(); it != expected_.end(); ++it) { |
|
|
|
|
if (internal::ArrayAwareFind(lhs_stl_container.begin(), |
|
|
|
|
lhs_stl_container.end(), |
|
|
|
|
*it) == lhs_stl_container.end()) { |
|
|
|
|
if (printed_header2) { |
|
|
|
|
*os << ", "; |
|
|
|
|
} else { |
|
|
|
@ -2476,7 +2454,9 @@ class ContainerEqMatcher { |
|
|
|
|
// A comparator functor that uses the < operator to compare two values.
|
|
|
|
|
struct LessComparator { |
|
|
|
|
template <typename T, typename U> |
|
|
|
|
bool operator()(const T& lhs, const U& rhs) const { return lhs < rhs; } |
|
|
|
|
bool operator()(const T& lhs, const U& rhs) const { |
|
|
|
|
return lhs < rhs; |
|
|
|
|
} |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
// Implements WhenSortedBy(comparator, container_matcher).
|
|
|
|
@ -2495,14 +2475,16 @@ class WhenSortedByMatcher { |
|
|
|
|
template <typename LhsContainer> |
|
|
|
|
class Impl : public MatcherInterface<LhsContainer> { |
|
|
|
|
public: |
|
|
|
|
typedef internal::StlContainerView< |
|
|
|
|
GTEST_REMOVE_REFERENCE_AND_CONST_(LhsContainer)> LhsView; |
|
|
|
|
typedef internal::StlContainerView<GTEST_REMOVE_REFERENCE_AND_CONST_( |
|
|
|
|
LhsContainer)> |
|
|
|
|
LhsView; |
|
|
|
|
typedef typename LhsView::type LhsStlContainer; |
|
|
|
|
typedef typename LhsView::const_reference LhsStlContainerReference; |
|
|
|
|
// Transforms std::pair<const Key, Value> into std::pair<Key, Value>
|
|
|
|
|
// so that we can match associative containers.
|
|
|
|
|
typedef typename RemoveConstFromKey< |
|
|
|
|
typename LhsStlContainer::value_type>::type LhsValue; |
|
|
|
|
typedef |
|
|
|
|
typename RemoveConstFromKey<typename LhsStlContainer::value_type>::type |
|
|
|
|
LhsValue; |
|
|
|
|
|
|
|
|
|
Impl(const Comparator& comparator, const ContainerMatcher& matcher) |
|
|
|
|
: comparator_(comparator), matcher_(matcher) {} |
|
|
|
@ -2522,8 +2504,8 @@ class WhenSortedByMatcher { |
|
|
|
|
LhsStlContainerReference lhs_stl_container = LhsView::ConstReference(lhs); |
|
|
|
|
::std::vector<LhsValue> sorted_container(lhs_stl_container.begin(), |
|
|
|
|
lhs_stl_container.end()); |
|
|
|
|
::std::sort( |
|
|
|
|
sorted_container.begin(), sorted_container.end(), comparator_); |
|
|
|
|
::std::sort(sorted_container.begin(), sorted_container.end(), |
|
|
|
|
comparator_); |
|
|
|
|
|
|
|
|
|
if (!listener->IsInterested()) { |
|
|
|
|
// If the listener is not interested, we do not need to
|
|
|
|
@ -2536,8 +2518,8 @@ class WhenSortedByMatcher { |
|
|
|
|
*listener << " when sorted"; |
|
|
|
|
|
|
|
|
|
StringMatchResultListener inner_listener; |
|
|
|
|
const bool match = matcher_.MatchAndExplain(sorted_container, |
|
|
|
|
&inner_listener); |
|
|
|
|
const bool match = |
|
|
|
|
matcher_.MatchAndExplain(sorted_container, &inner_listener); |
|
|
|
|
PrintIfNotEmpty(inner_listener.str(), listener->stream()); |
|
|
|
|
return match; |
|
|
|
|
} |
|
|
|
@ -2592,8 +2574,9 @@ class PointwiseMatcher { |
|
|
|
|
template <typename LhsContainer> |
|
|
|
|
class Impl : public MatcherInterface<LhsContainer> { |
|
|
|
|
public: |
|
|
|
|
typedef internal::StlContainerView< |
|
|
|
|
GTEST_REMOVE_REFERENCE_AND_CONST_(LhsContainer)> LhsView; |
|
|
|
|
typedef internal::StlContainerView<GTEST_REMOVE_REFERENCE_AND_CONST_( |
|
|
|
|
LhsContainer)> |
|
|
|
|
LhsView; |
|
|
|
|
typedef typename LhsView::type LhsStlContainer; |
|
|
|
|
typedef typename LhsView::const_reference LhsStlContainerReference; |
|
|
|
|
typedef typename LhsStlContainer::value_type LhsValue; |
|
|
|
@ -2687,18 +2670,17 @@ class QuantifierMatcherImpl : public MatcherInterface<Container> { |
|
|
|
|
template <typename InnerMatcher> |
|
|
|
|
explicit QuantifierMatcherImpl(InnerMatcher inner_matcher) |
|
|
|
|
: inner_matcher_( |
|
|
|
|
testing::SafeMatcherCast<const Element&>(inner_matcher)) {} |
|
|
|
|
testing::SafeMatcherCast<const Element&>(inner_matcher)) {} |
|
|
|
|
|
|
|
|
|
// Checks whether:
|
|
|
|
|
// * All elements in the container match, if all_elements_should_match.
|
|
|
|
|
// * Any element in the container matches, if !all_elements_should_match.
|
|
|
|
|
bool MatchAndExplainImpl(bool all_elements_should_match, |
|
|
|
|
Container container, |
|
|
|
|
bool MatchAndExplainImpl(bool all_elements_should_match, Container container, |
|
|
|
|
MatchResultListener* listener) const { |
|
|
|
|
StlContainerReference stl_container = View::ConstReference(container); |
|
|
|
|
size_t i = 0; |
|
|
|
|
for (auto it = stl_container.begin(); |
|
|
|
|
it != stl_container.end(); ++it, ++i) { |
|
|
|
|
for (auto it = stl_container.begin(); it != stl_container.end(); |
|
|
|
|
++it, ++i) { |
|
|
|
|
StringMatchResultListener inner_listener; |
|
|
|
|
const bool matches = inner_matcher_.MatchAndExplain(*it, &inner_listener); |
|
|
|
|
|
|
|
|
@ -2941,8 +2923,7 @@ class KeyMatcherImpl : public MatcherInterface<PairType> { |
|
|
|
|
template <typename InnerMatcher> |
|
|
|
|
explicit KeyMatcherImpl(InnerMatcher inner_matcher) |
|
|
|
|
: inner_matcher_( |
|
|
|
|
testing::SafeMatcherCast<const KeyType&>(inner_matcher)) { |
|
|
|
|
} |
|
|
|
|
testing::SafeMatcherCast<const KeyType&>(inner_matcher)) {} |
|
|
|
|
|
|
|
|
|
// Returns true if and only if 'key_value.first' (the key) matches the inner
|
|
|
|
|
// matcher.
|
|
|
|
@ -3047,8 +3028,7 @@ class PairMatcherImpl : public MatcherInterface<PairType> { |
|
|
|
|
: first_matcher_( |
|
|
|
|
testing::SafeMatcherCast<const FirstType&>(first_matcher)), |
|
|
|
|
second_matcher_( |
|
|
|
|
testing::SafeMatcherCast<const SecondType&>(second_matcher)) { |
|
|
|
|
} |
|
|
|
|
testing::SafeMatcherCast<const SecondType&>(second_matcher)) {} |
|
|
|
|
|
|
|
|
|
// Describes what this matcher does.
|
|
|
|
|
void DescribeTo(::std::ostream* os) const override { |
|
|
|
@ -3126,7 +3106,7 @@ class PairMatcher { |
|
|
|
|
: first_matcher_(first_matcher), second_matcher_(second_matcher) {} |
|
|
|
|
|
|
|
|
|
template <typename PairType> |
|
|
|
|
operator Matcher<PairType> () const { |
|
|
|
|
operator Matcher<PairType>() const { |
|
|
|
|
return Matcher<PairType>( |
|
|
|
|
new PairMatcherImpl<const PairType&>(first_matcher_, second_matcher_)); |
|
|
|
|
} |
|
|
|
@ -3475,7 +3455,7 @@ class ElementsAreMatcherImpl : public MatcherInterface<Container> { |
|
|
|
|
|
|
|
|
|
size_t count() const { return matchers_.size(); } |
|
|
|
|
|
|
|
|
|
::std::vector<Matcher<const Element&> > matchers_; |
|
|
|
|
::std::vector<Matcher<const Element&>> matchers_; |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
// Connectivity matrix of (elements X matchers), in element-major order.
|
|
|
|
@ -3487,8 +3467,7 @@ class GTEST_API_ MatchMatrix { |
|
|
|
|
MatchMatrix(size_t num_elements, size_t num_matchers) |
|
|
|
|
: num_elements_(num_elements), |
|
|
|
|
num_matchers_(num_matchers), |
|
|
|
|
matched_(num_elements_* num_matchers_, 0) { |
|
|
|
|
} |
|
|
|
|
matched_(num_elements_ * num_matchers_, 0) {} |
|
|
|
|
|
|
|
|
|
size_t LhsSize() const { return num_elements_; } |
|
|
|
|
size_t RhsSize() const { return num_matchers_; } |
|
|
|
@ -3527,8 +3506,7 @@ typedef ::std::vector<ElementMatcherPair> ElementMatcherPairs; |
|
|
|
|
|
|
|
|
|
// Returns a maximum bipartite matching for the specified graph 'g'.
|
|
|
|
|
// The matching is represented as a vector of {element, matcher} pairs.
|
|
|
|
|
GTEST_API_ ElementMatcherPairs |
|
|
|
|
FindMaxBipartiteMatching(const MatchMatrix& g); |
|
|
|
|
GTEST_API_ ElementMatcherPairs FindMaxBipartiteMatching(const MatchMatrix& g); |
|
|
|
|
|
|
|
|
|
struct UnorderedMatcherRequire { |
|
|
|
|
enum Flags { |
|
|
|
@ -3565,9 +3543,7 @@ class GTEST_API_ UnorderedElementsAreMatcherImplBase { |
|
|
|
|
bool FindPairing(const MatchMatrix& matrix, |
|
|
|
|
MatchResultListener* listener) const; |
|
|
|
|
|
|
|
|
|
MatcherDescriberVec& matcher_describers() { |
|
|
|
|
return matcher_describers_; |
|
|
|
|
} |
|
|
|
|
MatcherDescriberVec& matcher_describers() { return matcher_describers_; } |
|
|
|
|
|
|
|
|
|
static Message Elements(size_t n) { |
|
|
|
|
return Message() << n << " element" << (n == 1 ? "" : "s"); |
|
|
|
@ -3673,7 +3649,7 @@ class UnorderedElementsAreMatcherImpl |
|
|
|
|
return matrix; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
::std::vector<Matcher<const Element&> > matchers_; |
|
|
|
|
::std::vector<Matcher<const Element&>> matchers_; |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
// Functor for use in TransformTuple.
|
|
|
|
@ -3698,7 +3674,7 @@ class UnorderedElementsAreMatcher { |
|
|
|
|
typedef GTEST_REMOVE_REFERENCE_AND_CONST_(Container) RawContainer; |
|
|
|
|
typedef typename internal::StlContainerView<RawContainer>::type View; |
|
|
|
|
typedef typename View::value_type Element; |
|
|
|
|
typedef ::std::vector<Matcher<const Element&> > MatcherVec; |
|
|
|
|
typedef ::std::vector<Matcher<const Element&>> MatcherVec; |
|
|
|
|
MatcherVec matchers; |
|
|
|
|
matchers.reserve(::std::tuple_size<MatcherTuple>::value); |
|
|
|
|
TransformTupleValues(CastAndAppendTransform<const Element&>(), matchers_, |
|
|
|
@ -3729,7 +3705,7 @@ class ElementsAreMatcher { |
|
|
|
|
typedef GTEST_REMOVE_REFERENCE_AND_CONST_(Container) RawContainer; |
|
|
|
|
typedef typename internal::StlContainerView<RawContainer>::type View; |
|
|
|
|
typedef typename View::value_type Element; |
|
|
|
|
typedef ::std::vector<Matcher<const Element&> > MatcherVec; |
|
|
|
|
typedef ::std::vector<Matcher<const Element&>> MatcherVec; |
|
|
|
|
MatcherVec matchers; |
|
|
|
|
matchers.reserve(::std::tuple_size<MatcherTuple>::value); |
|
|
|
|
TransformTupleValues(CastAndAppendTransform<const Element&>(), matchers_, |
|
|
|
@ -4189,14 +4165,14 @@ UnorderedElementsAreArray(Iter first, Iter last) { |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
template <typename T> |
|
|
|
|
inline internal::UnorderedElementsAreArrayMatcher<T> |
|
|
|
|
UnorderedElementsAreArray(const T* pointer, size_t count) { |
|
|
|
|
inline internal::UnorderedElementsAreArrayMatcher<T> UnorderedElementsAreArray( |
|
|
|
|
const T* pointer, size_t count) { |
|
|
|
|
return UnorderedElementsAreArray(pointer, pointer + count); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
template <typename T, size_t N> |
|
|
|
|
inline internal::UnorderedElementsAreArrayMatcher<T> |
|
|
|
|
UnorderedElementsAreArray(const T (&array)[N]) { |
|
|
|
|
inline internal::UnorderedElementsAreArrayMatcher<T> UnorderedElementsAreArray( |
|
|
|
|
const T (&array)[N]) { |
|
|
|
|
return UnorderedElementsAreArray(array, N); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -4208,8 +4184,8 @@ UnorderedElementsAreArray(const Container& container) { |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
template <typename T> |
|
|
|
|
inline internal::UnorderedElementsAreArrayMatcher<T> |
|
|
|
|
UnorderedElementsAreArray(::std::initializer_list<T> xs) { |
|
|
|
|
inline internal::UnorderedElementsAreArrayMatcher<T> UnorderedElementsAreArray( |
|
|
|
|
::std::initializer_list<T> xs) { |
|
|
|
|
return UnorderedElementsAreArray(xs.begin(), xs.end()); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -4243,14 +4219,14 @@ Matcher<T> internal::MatcherCastImpl<T, M>::CastImpl( |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// Creates a polymorphic matcher that matches any NULL pointer.
|
|
|
|
|
inline PolymorphicMatcher<internal::IsNullMatcher > IsNull() { |
|
|
|
|
inline PolymorphicMatcher<internal::IsNullMatcher> IsNull() { |
|
|
|
|
return MakePolymorphicMatcher(internal::IsNullMatcher()); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// Creates a polymorphic matcher that matches any non-NULL pointer.
|
|
|
|
|
// This is convenient as Not(NULL) doesn't compile (the compiler
|
|
|
|
|
// thinks that that expression is comparing a pointer with an integer).
|
|
|
|
|
inline PolymorphicMatcher<internal::NotNullMatcher > NotNull() { |
|
|
|
|
inline PolymorphicMatcher<internal::NotNullMatcher> NotNull() { |
|
|
|
|
return MakePolymorphicMatcher(internal::NotNullMatcher()); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -4281,8 +4257,8 @@ inline internal::FloatingEqMatcher<double> NanSensitiveDoubleEq(double rhs) { |
|
|
|
|
// Creates a matcher that matches any double argument approximately equal to
|
|
|
|
|
// rhs, up to the specified max absolute error bound, where two NANs are
|
|
|
|
|
// considered unequal. The max absolute error bound must be non-negative.
|
|
|
|
|
inline internal::FloatingEqMatcher<double> DoubleNear( |
|
|
|
|
double rhs, double max_abs_error) { |
|
|
|
|
inline internal::FloatingEqMatcher<double> DoubleNear(double rhs, |
|
|
|
|
double max_abs_error) { |
|
|
|
|
return internal::FloatingEqMatcher<double>(rhs, false, max_abs_error); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -4309,8 +4285,8 @@ inline internal::FloatingEqMatcher<float> NanSensitiveFloatEq(float rhs) { |
|
|
|
|
// Creates a matcher that matches any float argument approximately equal to
|
|
|
|
|
// rhs, up to the specified max absolute error bound, where two NANs are
|
|
|
|
|
// considered unequal. The max absolute error bound must be non-negative.
|
|
|
|
|
inline internal::FloatingEqMatcher<float> FloatNear( |
|
|
|
|
float rhs, float max_abs_error) { |
|
|
|
|
inline internal::FloatingEqMatcher<float> FloatNear(float rhs, |
|
|
|
|
float max_abs_error) { |
|
|
|
|
return internal::FloatingEqMatcher<float>(rhs, false, max_abs_error); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -4338,7 +4314,7 @@ inline internal::PointeeMatcher<InnerMatcher> Pointee( |
|
|
|
|
// If To is a reference and the cast fails, this matcher returns false
|
|
|
|
|
// immediately.
|
|
|
|
|
template <typename To> |
|
|
|
|
inline PolymorphicMatcher<internal::WhenDynamicCastToMatcher<To> > |
|
|
|
|
inline PolymorphicMatcher<internal::WhenDynamicCastToMatcher<To>> |
|
|
|
|
WhenDynamicCastTo(const Matcher<To>& inner_matcher) { |
|
|
|
|
return MakePolymorphicMatcher( |
|
|
|
|
internal::WhenDynamicCastToMatcher<To>(inner_matcher)); |
|
|
|
@ -4350,12 +4326,10 @@ WhenDynamicCastTo(const Matcher<To>& inner_matcher) { |
|
|
|
|
// Field(&Foo::number, Ge(5))
|
|
|
|
|
// matches a Foo object x if and only if x.number >= 5.
|
|
|
|
|
template <typename Class, typename FieldType, typename FieldMatcher> |
|
|
|
|
inline PolymorphicMatcher< |
|
|
|
|
internal::FieldMatcher<Class, FieldType> > Field( |
|
|
|
|
inline PolymorphicMatcher<internal::FieldMatcher<Class, FieldType>> Field( |
|
|
|
|
FieldType Class::*field, const FieldMatcher& matcher) { |
|
|
|
|
return MakePolymorphicMatcher( |
|
|
|
|
internal::FieldMatcher<Class, FieldType>( |
|
|
|
|
field, MatcherCast<const FieldType&>(matcher))); |
|
|
|
|
return MakePolymorphicMatcher(internal::FieldMatcher<Class, FieldType>( |
|
|
|
|
field, MatcherCast<const FieldType&>(matcher))); |
|
|
|
|
// The call to MatcherCast() is required for supporting inner
|
|
|
|
|
// matchers of compatible types. For example, it allows
|
|
|
|
|
// Field(&Foo::bar, m)
|
|
|
|
@ -4365,7 +4339,7 @@ inline PolymorphicMatcher< |
|
|
|
|
// 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( |
|
|
|
|
inline PolymorphicMatcher<internal::FieldMatcher<Class, FieldType>> Field( |
|
|
|
|
const std::string& field_name, FieldType Class::*field, |
|
|
|
|
const FieldMatcher& matcher) { |
|
|
|
|
return MakePolymorphicMatcher(internal::FieldMatcher<Class, FieldType>( |
|
|
|
@ -4378,7 +4352,7 @@ inline PolymorphicMatcher<internal::FieldMatcher<Class, FieldType> > Field( |
|
|
|
|
// matches a Foo object x if and only if x.str() starts with "hi".
|
|
|
|
|
template <typename Class, typename PropertyType, typename PropertyMatcher> |
|
|
|
|
inline PolymorphicMatcher<internal::PropertyMatcher< |
|
|
|
|
Class, PropertyType, PropertyType (Class::*)() const> > |
|
|
|
|
Class, PropertyType, PropertyType (Class::*)() const>> |
|
|
|
|
Property(PropertyType (Class::*property)() const, |
|
|
|
|
const PropertyMatcher& matcher) { |
|
|
|
|
return MakePolymorphicMatcher( |
|
|
|
@ -4395,7 +4369,7 @@ Property(PropertyType (Class::*property)() const, |
|
|
|
|
// better error messages.
|
|
|
|
|
template <typename Class, typename PropertyType, typename PropertyMatcher> |
|
|
|
|
inline PolymorphicMatcher<internal::PropertyMatcher< |
|
|
|
|
Class, PropertyType, PropertyType (Class::*)() const> > |
|
|
|
|
Class, PropertyType, PropertyType (Class::*)() const>> |
|
|
|
|
Property(const std::string& property_name, |
|
|
|
|
PropertyType (Class::*property)() const, |
|
|
|
|
const PropertyMatcher& matcher) { |
|
|
|
@ -4408,8 +4382,8 @@ Property(const std::string& property_name, |
|
|
|
|
// The same as above but for reference-qualified member functions.
|
|
|
|
|
template <typename Class, typename PropertyType, typename PropertyMatcher> |
|
|
|
|
inline PolymorphicMatcher<internal::PropertyMatcher< |
|
|
|
|
Class, PropertyType, PropertyType (Class::*)() const &> > |
|
|
|
|
Property(PropertyType (Class::*property)() const &, |
|
|
|
|
Class, PropertyType, PropertyType (Class::*)() const&>> |
|
|
|
|
Property(PropertyType (Class::*property)() const&, |
|
|
|
|
const PropertyMatcher& matcher) { |
|
|
|
|
return MakePolymorphicMatcher( |
|
|
|
|
internal::PropertyMatcher<Class, PropertyType, |
|
|
|
@ -4420,9 +4394,9 @@ Property(PropertyType (Class::*property)() const &, |
|
|
|
|
// Three-argument form for reference-qualified member functions.
|
|
|
|
|
template <typename Class, typename PropertyType, typename PropertyMatcher> |
|
|
|
|
inline PolymorphicMatcher<internal::PropertyMatcher< |
|
|
|
|
Class, PropertyType, PropertyType (Class::*)() const &> > |
|
|
|
|
Class, PropertyType, PropertyType (Class::*)() const&>> |
|
|
|
|
Property(const std::string& property_name, |
|
|
|
|
PropertyType (Class::*property)() const &, |
|
|
|
|
PropertyType (Class::*property)() const&, |
|
|
|
|
const PropertyMatcher& matcher) { |
|
|
|
|
return MakePolymorphicMatcher( |
|
|
|
|
internal::PropertyMatcher<Class, PropertyType, |
|
|
|
@ -4441,15 +4415,15 @@ Property(const std::string& property_name, |
|
|
|
|
template <typename Callable, typename InnerMatcher> |
|
|
|
|
internal::ResultOfMatcher<Callable, InnerMatcher> ResultOf( |
|
|
|
|
Callable callable, InnerMatcher matcher) { |
|
|
|
|
return internal::ResultOfMatcher<Callable, InnerMatcher>( |
|
|
|
|
std::move(callable), std::move(matcher)); |
|
|
|
|
return internal::ResultOfMatcher<Callable, InnerMatcher>(std::move(callable), |
|
|
|
|
std::move(matcher)); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// String matchers.
|
|
|
|
|
|
|
|
|
|
// Matches a string equal to str.
|
|
|
|
|
template <typename T = std::string> |
|
|
|
|
PolymorphicMatcher<internal::StrEqualityMatcher<std::string> > StrEq( |
|
|
|
|
PolymorphicMatcher<internal::StrEqualityMatcher<std::string>> StrEq( |
|
|
|
|
const internal::StringLike<T>& str) { |
|
|
|
|
return MakePolymorphicMatcher( |
|
|
|
|
internal::StrEqualityMatcher<std::string>(std::string(str), true, true)); |
|
|
|
@ -4457,7 +4431,7 @@ PolymorphicMatcher<internal::StrEqualityMatcher<std::string> > StrEq( |
|
|
|
|
|
|
|
|
|
// Matches a string not equal to str.
|
|
|
|
|
template <typename T = std::string> |
|
|
|
|
PolymorphicMatcher<internal::StrEqualityMatcher<std::string> > StrNe( |
|
|
|
|
PolymorphicMatcher<internal::StrEqualityMatcher<std::string>> StrNe( |
|
|
|
|
const internal::StringLike<T>& str) { |
|
|
|
|
return MakePolymorphicMatcher( |
|
|
|
|
internal::StrEqualityMatcher<std::string>(std::string(str), false, true)); |
|
|
|
@ -4465,7 +4439,7 @@ PolymorphicMatcher<internal::StrEqualityMatcher<std::string> > StrNe( |
|
|
|
|
|
|
|
|
|
// Matches a string equal to str, ignoring case.
|
|
|
|
|
template <typename T = std::string> |
|
|
|
|
PolymorphicMatcher<internal::StrEqualityMatcher<std::string> > StrCaseEq( |
|
|
|
|
PolymorphicMatcher<internal::StrEqualityMatcher<std::string>> StrCaseEq( |
|
|
|
|
const internal::StringLike<T>& str) { |
|
|
|
|
return MakePolymorphicMatcher( |
|
|
|
|
internal::StrEqualityMatcher<std::string>(std::string(str), true, false)); |
|
|
|
@ -4473,7 +4447,7 @@ PolymorphicMatcher<internal::StrEqualityMatcher<std::string> > StrCaseEq( |
|
|
|
|
|
|
|
|
|
// Matches a string not equal to str, ignoring case.
|
|
|
|
|
template <typename T = std::string> |
|
|
|
|
PolymorphicMatcher<internal::StrEqualityMatcher<std::string> > StrCaseNe( |
|
|
|
|
PolymorphicMatcher<internal::StrEqualityMatcher<std::string>> StrCaseNe( |
|
|
|
|
const internal::StringLike<T>& str) { |
|
|
|
|
return MakePolymorphicMatcher(internal::StrEqualityMatcher<std::string>( |
|
|
|
|
std::string(str), false, false)); |
|
|
|
@ -4482,7 +4456,7 @@ PolymorphicMatcher<internal::StrEqualityMatcher<std::string> > StrCaseNe( |
|
|
|
|
// Creates a matcher that matches any string, std::string, or C string
|
|
|
|
|
// that contains the given substring.
|
|
|
|
|
template <typename T = std::string> |
|
|
|
|
PolymorphicMatcher<internal::HasSubstrMatcher<std::string> > HasSubstr( |
|
|
|
|
PolymorphicMatcher<internal::HasSubstrMatcher<std::string>> HasSubstr( |
|
|
|
|
const internal::StringLike<T>& substring) { |
|
|
|
|
return MakePolymorphicMatcher( |
|
|
|
|
internal::HasSubstrMatcher<std::string>(std::string(substring))); |
|
|
|
@ -4490,7 +4464,7 @@ PolymorphicMatcher<internal::HasSubstrMatcher<std::string> > HasSubstr( |
|
|
|
|
|
|
|
|
|
// Matches a string that starts with 'prefix' (case-sensitive).
|
|
|
|
|
template <typename T = std::string> |
|
|
|
|
PolymorphicMatcher<internal::StartsWithMatcher<std::string> > StartsWith( |
|
|
|
|
PolymorphicMatcher<internal::StartsWithMatcher<std::string>> StartsWith( |
|
|
|
|
const internal::StringLike<T>& prefix) { |
|
|
|
|
return MakePolymorphicMatcher( |
|
|
|
|
internal::StartsWithMatcher<std::string>(std::string(prefix))); |
|
|
|
@ -4498,7 +4472,7 @@ PolymorphicMatcher<internal::StartsWithMatcher<std::string> > StartsWith( |
|
|
|
|
|
|
|
|
|
// Matches a string that ends with 'suffix' (case-sensitive).
|
|
|
|
|
template <typename T = std::string> |
|
|
|
|
PolymorphicMatcher<internal::EndsWithMatcher<std::string> > EndsWith( |
|
|
|
|
PolymorphicMatcher<internal::EndsWithMatcher<std::string>> EndsWith( |
|
|
|
|
const internal::StringLike<T>& suffix) { |
|
|
|
|
return MakePolymorphicMatcher( |
|
|
|
|
internal::EndsWithMatcher<std::string>(std::string(suffix))); |
|
|
|
@ -4508,50 +4482,50 @@ PolymorphicMatcher<internal::EndsWithMatcher<std::string> > EndsWith( |
|
|
|
|
// Wide string matchers.
|
|
|
|
|
|
|
|
|
|
// Matches a string equal to str.
|
|
|
|
|
inline PolymorphicMatcher<internal::StrEqualityMatcher<std::wstring> > StrEq( |
|
|
|
|
inline PolymorphicMatcher<internal::StrEqualityMatcher<std::wstring>> StrEq( |
|
|
|
|
const std::wstring& str) { |
|
|
|
|
return MakePolymorphicMatcher( |
|
|
|
|
internal::StrEqualityMatcher<std::wstring>(str, true, true)); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// Matches a string not equal to str.
|
|
|
|
|
inline PolymorphicMatcher<internal::StrEqualityMatcher<std::wstring> > StrNe( |
|
|
|
|
inline PolymorphicMatcher<internal::StrEqualityMatcher<std::wstring>> StrNe( |
|
|
|
|
const std::wstring& str) { |
|
|
|
|
return MakePolymorphicMatcher( |
|
|
|
|
internal::StrEqualityMatcher<std::wstring>(str, false, true)); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// Matches a string equal to str, ignoring case.
|
|
|
|
|
inline PolymorphicMatcher<internal::StrEqualityMatcher<std::wstring> > |
|
|
|
|
StrCaseEq(const std::wstring& str) { |
|
|
|
|
inline PolymorphicMatcher<internal::StrEqualityMatcher<std::wstring>> StrCaseEq( |
|
|
|
|
const std::wstring& str) { |
|
|
|
|
return MakePolymorphicMatcher( |
|
|
|
|
internal::StrEqualityMatcher<std::wstring>(str, true, false)); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// Matches a string not equal to str, ignoring case.
|
|
|
|
|
inline PolymorphicMatcher<internal::StrEqualityMatcher<std::wstring> > |
|
|
|
|
StrCaseNe(const std::wstring& str) { |
|
|
|
|
inline PolymorphicMatcher<internal::StrEqualityMatcher<std::wstring>> StrCaseNe( |
|
|
|
|
const std::wstring& str) { |
|
|
|
|
return MakePolymorphicMatcher( |
|
|
|
|
internal::StrEqualityMatcher<std::wstring>(str, false, false)); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// Creates a matcher that matches any ::wstring, std::wstring, or C wide string
|
|
|
|
|
// that contains the given substring.
|
|
|
|
|
inline PolymorphicMatcher<internal::HasSubstrMatcher<std::wstring> > HasSubstr( |
|
|
|
|
inline PolymorphicMatcher<internal::HasSubstrMatcher<std::wstring>> HasSubstr( |
|
|
|
|
const std::wstring& substring) { |
|
|
|
|
return MakePolymorphicMatcher( |
|
|
|
|
internal::HasSubstrMatcher<std::wstring>(substring)); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// Matches a string that starts with 'prefix' (case-sensitive).
|
|
|
|
|
inline PolymorphicMatcher<internal::StartsWithMatcher<std::wstring> > |
|
|
|
|
StartsWith(const std::wstring& prefix) { |
|
|
|
|
inline PolymorphicMatcher<internal::StartsWithMatcher<std::wstring>> StartsWith( |
|
|
|
|
const std::wstring& prefix) { |
|
|
|
|
return MakePolymorphicMatcher( |
|
|
|
|
internal::StartsWithMatcher<std::wstring>(prefix)); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// Matches a string that ends with 'suffix' (case-sensitive).
|
|
|
|
|
inline PolymorphicMatcher<internal::EndsWithMatcher<std::wstring> > EndsWith( |
|
|
|
|
inline PolymorphicMatcher<internal::EndsWithMatcher<std::wstring>> EndsWith( |
|
|
|
|
const std::wstring& suffix) { |
|
|
|
|
return MakePolymorphicMatcher( |
|
|
|
|
internal::EndsWithMatcher<std::wstring>(suffix)); |
|
|
|
@ -4646,8 +4620,8 @@ inline internal::NotMatcher<InnerMatcher> Not(InnerMatcher m) { |
|
|
|
|
// predicate. The predicate can be any unary function or functor
|
|
|
|
|
// whose return type can be implicitly converted to bool.
|
|
|
|
|
template <typename Predicate> |
|
|
|
|
inline PolymorphicMatcher<internal::TrulyMatcher<Predicate> > |
|
|
|
|
Truly(Predicate pred) { |
|
|
|
|
inline PolymorphicMatcher<internal::TrulyMatcher<Predicate>> Truly( |
|
|
|
|
Predicate pred) { |
|
|
|
|
return MakePolymorphicMatcher(internal::TrulyMatcher<Predicate>(pred)); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -4658,8 +4632,8 @@ Truly(Predicate pred) { |
|
|
|
|
// EXPECT_THAT(container, SizeIs(2)); // Checks container has 2 elements.
|
|
|
|
|
// EXPECT_THAT(container, SizeIs(Le(2)); // Checks container has at most 2.
|
|
|
|
|
template <typename SizeMatcher> |
|
|
|
|
inline internal::SizeIsMatcher<SizeMatcher> |
|
|
|
|
SizeIs(const SizeMatcher& size_matcher) { |
|
|
|
|
inline internal::SizeIsMatcher<SizeMatcher> SizeIs( |
|
|
|
|
const SizeMatcher& size_matcher) { |
|
|
|
|
return internal::SizeIsMatcher<SizeMatcher>(size_matcher); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -4669,8 +4643,8 @@ SizeIs(const SizeMatcher& size_matcher) { |
|
|
|
|
// do not implement size(). The container must provide const_iterator (with
|
|
|
|
|
// valid iterator_traits), begin() and end().
|
|
|
|
|
template <typename DistanceMatcher> |
|
|
|
|
inline internal::BeginEndDistanceIsMatcher<DistanceMatcher> |
|
|
|
|
BeginEndDistanceIs(const DistanceMatcher& distance_matcher) { |
|
|
|
|
inline internal::BeginEndDistanceIsMatcher<DistanceMatcher> BeginEndDistanceIs( |
|
|
|
|
const DistanceMatcher& distance_matcher) { |
|
|
|
|
return internal::BeginEndDistanceIsMatcher<DistanceMatcher>(distance_matcher); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -4679,8 +4653,8 @@ BeginEndDistanceIs(const DistanceMatcher& distance_matcher) { |
|
|
|
|
// values that are included in one container but not the other. (Duplicate
|
|
|
|
|
// values and order differences are not explained.)
|
|
|
|
|
template <typename Container> |
|
|
|
|
inline PolymorphicMatcher<internal::ContainerEqMatcher< |
|
|
|
|
typename std::remove_const<Container>::type>> |
|
|
|
|
inline PolymorphicMatcher< |
|
|
|
|
internal::ContainerEqMatcher<typename std::remove_const<Container>::type>> |
|
|
|
|
ContainerEq(const Container& rhs) { |
|
|
|
|
return MakePolymorphicMatcher(internal::ContainerEqMatcher<Container>(rhs)); |
|
|
|
|
} |
|
|
|
@ -4688,9 +4662,8 @@ ContainerEq(const Container& rhs) { |
|
|
|
|
// Returns a matcher that matches a container that, when sorted using
|
|
|
|
|
// the given comparator, matches container_matcher.
|
|
|
|
|
template <typename Comparator, typename ContainerMatcher> |
|
|
|
|
inline internal::WhenSortedByMatcher<Comparator, ContainerMatcher> |
|
|
|
|
WhenSortedBy(const Comparator& comparator, |
|
|
|
|
const ContainerMatcher& container_matcher) { |
|
|
|
|
inline internal::WhenSortedByMatcher<Comparator, ContainerMatcher> WhenSortedBy( |
|
|
|
|
const Comparator& comparator, const ContainerMatcher& container_matcher) { |
|
|
|
|
return internal::WhenSortedByMatcher<Comparator, ContainerMatcher>( |
|
|
|
|
comparator, container_matcher); |
|
|
|
|
} |
|
|
|
@ -4700,9 +4673,9 @@ WhenSortedBy(const Comparator& comparator, |
|
|
|
|
template <typename ContainerMatcher> |
|
|
|
|
inline internal::WhenSortedByMatcher<internal::LessComparator, ContainerMatcher> |
|
|
|
|
WhenSorted(const ContainerMatcher& container_matcher) { |
|
|
|
|
return |
|
|
|
|
internal::WhenSortedByMatcher<internal::LessComparator, ContainerMatcher>( |
|
|
|
|
internal::LessComparator(), container_matcher); |
|
|
|
|
return internal::WhenSortedByMatcher<internal::LessComparator, |
|
|
|
|
ContainerMatcher>( |
|
|
|
|
internal::LessComparator(), container_matcher); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// Matches an STL-style container or a native array that contains the
|
|
|
|
@ -4719,15 +4692,13 @@ Pointwise(const TupleMatcher& tuple_matcher, const Container& rhs) { |
|
|
|
|
rhs); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Supports the Pointwise(m, {a, b, c}) syntax.
|
|
|
|
|
template <typename TupleMatcher, typename T> |
|
|
|
|
inline internal::PointwiseMatcher<TupleMatcher, std::vector<T> > Pointwise( |
|
|
|
|
inline internal::PointwiseMatcher<TupleMatcher, std::vector<T>> Pointwise( |
|
|
|
|
const TupleMatcher& tuple_matcher, std::initializer_list<T> rhs) { |
|
|
|
|
return Pointwise(tuple_matcher, std::vector<T>(rhs)); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// UnorderedPointwise(pair_matcher, rhs) matches an STL-style
|
|
|
|
|
// container or a native array that contains the same number of
|
|
|
|
|
// elements as in rhs, where in some permutation of the container, its
|
|
|
|
@ -4756,22 +4727,20 @@ UnorderedPointwise(const Tuple2Matcher& tuple2_matcher, |
|
|
|
|
RhsView::ConstReference(rhs_container); |
|
|
|
|
|
|
|
|
|
// Create a matcher for each element in rhs_container.
|
|
|
|
|
::std::vector<internal::BoundSecondMatcher<Tuple2Matcher, Second> > matchers; |
|
|
|
|
for (auto it = rhs_stl_container.begin(); |
|
|
|
|
it != rhs_stl_container.end(); ++it) { |
|
|
|
|
matchers.push_back( |
|
|
|
|
internal::MatcherBindSecond(tuple2_matcher, *it)); |
|
|
|
|
::std::vector<internal::BoundSecondMatcher<Tuple2Matcher, Second>> matchers; |
|
|
|
|
for (auto it = rhs_stl_container.begin(); it != rhs_stl_container.end(); |
|
|
|
|
++it) { |
|
|
|
|
matchers.push_back(internal::MatcherBindSecond(tuple2_matcher, *it)); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// Delegate the work to UnorderedElementsAreArray().
|
|
|
|
|
return UnorderedElementsAreArray(matchers); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Supports the UnorderedPointwise(m, {a, b, c}) syntax.
|
|
|
|
|
template <typename Tuple2Matcher, typename T> |
|
|
|
|
inline internal::UnorderedElementsAreArrayMatcher< |
|
|
|
|
typename internal::BoundSecondMatcher<Tuple2Matcher, T> > |
|
|
|
|
typename internal::BoundSecondMatcher<Tuple2Matcher, T>> |
|
|
|
|
UnorderedPointwise(const Tuple2Matcher& tuple2_matcher, |
|
|
|
|
std::initializer_list<T> rhs) { |
|
|
|
|
return UnorderedPointwise(tuple2_matcher, std::vector<T>(rhs)); |
|
|
|
@ -4977,10 +4946,10 @@ inline internal::KeyMatcher<M> Key(M inner_matcher) { |
|
|
|
|
// to match a std::map<int, string> that contains exactly one element whose key
|
|
|
|
|
// is >= 5 and whose value equals "foo".
|
|
|
|
|
template <typename FirstMatcher, typename SecondMatcher> |
|
|
|
|
inline internal::PairMatcher<FirstMatcher, SecondMatcher> |
|
|
|
|
Pair(FirstMatcher first_matcher, SecondMatcher second_matcher) { |
|
|
|
|
return internal::PairMatcher<FirstMatcher, SecondMatcher>( |
|
|
|
|
first_matcher, second_matcher); |
|
|
|
|
inline internal::PairMatcher<FirstMatcher, SecondMatcher> Pair( |
|
|
|
|
FirstMatcher first_matcher, SecondMatcher second_matcher) { |
|
|
|
|
return internal::PairMatcher<FirstMatcher, SecondMatcher>(first_matcher, |
|
|
|
|
second_matcher); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
namespace no_adl { |
|
|
|
@ -5048,8 +5017,8 @@ inline bool Value(const T& value, M matcher) { |
|
|
|
|
// Matches the value against the given matcher and explains the match
|
|
|
|
|
// result to listener.
|
|
|
|
|
template <typename T, typename M> |
|
|
|
|
inline bool ExplainMatchResult( |
|
|
|
|
M matcher, const T& value, MatchResultListener* listener) { |
|
|
|
|
inline bool ExplainMatchResult(M matcher, const T& value, |
|
|
|
|
MatchResultListener* listener) { |
|
|
|
|
return SafeMatcherCast<const T&>(matcher).MatchAndExplain(value, listener); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -5208,7 +5177,9 @@ internal::ArgsMatcher<typename std::decay<InnerMatcher>::type, k...> Args( |
|
|
|
|
//
|
|
|
|
|
// EXPECT_CALL(foo, Bar(_, _)).With(Eq());
|
|
|
|
|
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<>
|
|
|
|
@ -5226,7 +5197,7 @@ inline internal::OptionalMatcher<ValueMatcher> Optional( |
|
|
|
|
|
|
|
|
|
// Returns a matcher that matches the value of a absl::any type variable.
|
|
|
|
|
template <typename T> |
|
|
|
|
PolymorphicMatcher<internal::any_cast_matcher::AnyCastMatcher<T> > AnyWith( |
|
|
|
|
PolymorphicMatcher<internal::any_cast_matcher::AnyCastMatcher<T>> AnyWith( |
|
|
|
|
const Matcher<const T&>& matcher) { |
|
|
|
|
return MakePolymorphicMatcher( |
|
|
|
|
internal::any_cast_matcher::AnyCastMatcher<T>(matcher)); |
|
|
|
@ -5237,7 +5208,7 @@ PolymorphicMatcher<internal::any_cast_matcher::AnyCastMatcher<T> > AnyWith( |
|
|
|
|
// functions.
|
|
|
|
|
// It is compatible with std::variant.
|
|
|
|
|
template <typename T> |
|
|
|
|
PolymorphicMatcher<internal::variant_matcher::VariantMatcher<T> > VariantWith( |
|
|
|
|
PolymorphicMatcher<internal::variant_matcher::VariantMatcher<T>> VariantWith( |
|
|
|
|
const Matcher<const T&>& matcher) { |
|
|
|
|
return MakePolymorphicMatcher( |
|
|
|
|
internal::variant_matcher::VariantMatcher<T>(matcher)); |
|
|
|
@ -5417,10 +5388,12 @@ PolymorphicMatcher<internal::ExceptionMatcherImpl<Err>> ThrowsMessage( |
|
|
|
|
// tests. ASSERT_THAT(value, matcher) and EXPECT_THAT(value, matcher)
|
|
|
|
|
// succeed if and only if the value matches the matcher. If the assertion
|
|
|
|
|
// fails, the value and the description of the matcher will be printed.
|
|
|
|
|
#define ASSERT_THAT(value, matcher) ASSERT_PRED_FORMAT1(\ |
|
|
|
|
::testing::internal::MakePredicateFormatterFromMatcher(matcher), value) |
|
|
|
|
#define EXPECT_THAT(value, matcher) EXPECT_PRED_FORMAT1(\ |
|
|
|
|
::testing::internal::MakePredicateFormatterFromMatcher(matcher), value) |
|
|
|
|
#define ASSERT_THAT(value, matcher) \ |
|
|
|
|
ASSERT_PRED_FORMAT1( \
|
|
|
|
|
::testing::internal::MakePredicateFormatterFromMatcher(matcher), value) |
|
|
|
|
#define EXPECT_THAT(value, matcher) \ |
|
|
|
|
EXPECT_PRED_FORMAT1( \
|
|
|
|
|
::testing::internal::MakePredicateFormatterFromMatcher(matcher), value) |
|
|
|
|
|
|
|
|
|
// MATCHER* macros itself are listed below.
|
|
|
|
|
#define MATCHER(name, description) \ |
|
|
|
|