aboutsummaryrefslogtreecommitdiffstats
path: root/googlemock
diff options
context:
space:
mode:
Diffstat (limited to 'googlemock')
-rw-r--r--googlemock/docs/cheat_sheet.md7
-rw-r--r--googlemock/include/gmock/gmock-function-mocker.h29
-rw-r--r--googlemock/include/gmock/gmock-generated-actions.h24
-rw-r--r--googlemock/include/gmock/gmock-generated-actions.h.pump4
-rw-r--r--googlemock/include/gmock/gmock-generated-matchers.h88
-rw-r--r--googlemock/include/gmock/gmock-generated-matchers.h.pump8
-rw-r--r--googlemock/include/gmock/gmock-matchers.h26
-rw-r--r--googlemock/include/gmock/internal/gmock-internal-utils.h3
-rw-r--r--googlemock/src/gmock-spec-builders.cc6
-rw-r--r--googlemock/test/gmock-function-mocker_test.cc7
-rw-r--r--googlemock/test/gmock-matchers_test.cc108
-rw-r--r--googlemock/test/gmock-spec-builders_test.cc2
12 files changed, 237 insertions, 75 deletions
diff --git a/googlemock/docs/cheat_sheet.md b/googlemock/docs/cheat_sheet.md
index 850963af..3236e6a9 100644
--- a/googlemock/docs/cheat_sheet.md
+++ b/googlemock/docs/cheat_sheet.md
@@ -287,6 +287,7 @@ is not changed afterwards, or the meaning of your matcher will be changed.
| `FloatEq(a_float)` | `argument` is a `float` value approximately equal to `a_float`, treating two NaNs as unequal. |
| `NanSensitiveDoubleEq(a_double)` | `argument` is a `double` value approximately equal to `a_double`, treating two NaNs as equal. |
| `NanSensitiveFloatEq(a_float)` | `argument` is a `float` value approximately equal to `a_float`, treating two NaNs as equal. |
+| `IsNan()` | `argument` is any floating-point type with a NaN value. |
<!-- mdformat on -->
The above matchers use ULP-based comparison (the same as used in googletest).
@@ -325,9 +326,9 @@ The `argument` can be either a C string or a C++ string object:
`ContainsRegex()` and `MatchesRegex()` take ownership of the `RE` object. They
use the regular expression syntax defined
-[here](../../googletest/docs/advanced.md#regular-expression-syntax).
-`StrCaseEq()`, `StrCaseNe()`, `StrEq()`, and `StrNe()` work for wide strings as
-well.
+[here](../../googletest/docs/advanced.md#regular-expression-syntax). All of
+these matchers, except `ContainsRegex()` and `MatchesRegex()` work for wide
+strings as well.
#### Container Matchers
diff --git a/googlemock/include/gmock/gmock-function-mocker.h b/googlemock/include/gmock/gmock-function-mocker.h
index cc1535c8..684db139 100644
--- a/googlemock/include/gmock/gmock-function-mocker.h
+++ b/googlemock/include/gmock/gmock-function-mocker.h
@@ -39,6 +39,13 @@
#include "gmock/gmock-generated-function-mockers.h" // NOLINT
#include "gmock/internal/gmock-pp.h"
+namespace testing {
+namespace internal {
+template <typename T>
+using identity_t = T;
+} // namespace internal
+} // namespace testing
+
#define MOCK_METHOD(...) \
GMOCK_PP_VARIADIC_CALL(GMOCK_INTERNAL_MOCK_METHOD_ARG_, __VA_ARGS__)
@@ -207,10 +214,24 @@
#define GMOCK_INTERNAL_IS_CALLTYPE_HELPER_Calltype
-#define GMOCK_INTERNAL_SIGNATURE(_Ret, _Args) \
- GMOCK_PP_IF(GMOCK_PP_IS_BEGIN_PARENS(_Ret), GMOCK_PP_REMOVE_PARENS, \
- GMOCK_PP_IDENTITY) \
- (_Ret)(GMOCK_PP_FOR_EACH(GMOCK_INTERNAL_GET_TYPE, _, _Args))
+// Note: The use of `identity_t` here allows _Ret to represent return types that
+// would normally need to be specified in a different way. For example, a method
+// returning a function pointer must be written as
+//
+// fn_ptr_return_t (*method(method_args_t...))(fn_ptr_args_t...)
+//
+// But we only support placing the return type at the beginning. To handle this,
+// we wrap all calls in identity_t, so that a declaration will be expanded to
+//
+// identity_t<fn_ptr_return_t (*)(fn_ptr_args_t...)> method(method_args_t...)
+//
+// This allows us to work around the syntactic oddities of function/method
+// types.
+#define GMOCK_INTERNAL_SIGNATURE(_Ret, _Args) \
+ ::testing::internal::identity_t<GMOCK_PP_IF(GMOCK_PP_IS_BEGIN_PARENS(_Ret), \
+ GMOCK_PP_REMOVE_PARENS, \
+ GMOCK_PP_IDENTITY)(_Ret)>( \
+ GMOCK_PP_FOR_EACH(GMOCK_INTERNAL_GET_TYPE, _, _Args))
#define GMOCK_INTERNAL_GET_TYPE(_i, _, _elem) \
GMOCK_PP_COMMA_IF(_i) \
diff --git a/googlemock/include/gmock/gmock-generated-actions.h b/googlemock/include/gmock/gmock-generated-actions.h
index 981af78f..cee96dae 100644
--- a/googlemock/include/gmock/gmock-generated-actions.h
+++ b/googlemock/include/gmock/gmock-generated-actions.h
@@ -663,7 +663,7 @@ class ActionHelper {
typedef typename ::testing::internal::Function<F>::ArgumentTuple\
args_type;\
explicit gmock_Impl GMOCK_INTERNAL_INIT_##value_params {}\
- virtual return_type Perform(const args_type& args) {\
+ return_type Perform(const args_type& args) override {\
return ::testing::internal::ActionHelper<return_type, gmock_Impl>::\
Perform(this, args);\
}\
@@ -726,7 +726,7 @@ class ActionHelper {
typedef typename ::testing::internal::Function<F>::ArgumentTuple\
args_type;\
gmock_Impl() {}\
- virtual return_type Perform(const args_type& args) {\
+ return_type Perform(const args_type& args) override {\
return ::testing::internal::ActionHelper<return_type, gmock_Impl>::\
Perform(this, args);\
}\
@@ -776,7 +776,7 @@ class ActionHelper {
args_type;\
explicit gmock_Impl(p0##_type gmock_p0) : \
p0(::std::forward<p0##_type>(gmock_p0)) {}\
- virtual return_type Perform(const args_type& args) {\
+ return_type Perform(const args_type& args) override {\
return ::testing::internal::ActionHelper<return_type, gmock_Impl>::\
Perform(this, args);\
}\
@@ -832,7 +832,7 @@ class ActionHelper {
gmock_Impl(p0##_type gmock_p0, \
p1##_type gmock_p1) : p0(::std::forward<p0##_type>(gmock_p0)), \
p1(::std::forward<p1##_type>(gmock_p1)) {}\
- virtual return_type Perform(const args_type& args) {\
+ return_type Perform(const args_type& args) override {\
return ::testing::internal::ActionHelper<return_type, gmock_Impl>::\
Perform(this, args);\
}\
@@ -893,7 +893,7 @@ class ActionHelper {
p2##_type gmock_p2) : p0(::std::forward<p0##_type>(gmock_p0)), \
p1(::std::forward<p1##_type>(gmock_p1)), \
p2(::std::forward<p2##_type>(gmock_p2)) {}\
- virtual return_type Perform(const args_type& args) {\
+ return_type Perform(const args_type& args) override {\
return ::testing::internal::ActionHelper<return_type, gmock_Impl>::\
Perform(this, args);\
}\
@@ -961,7 +961,7 @@ class ActionHelper {
p1(::std::forward<p1##_type>(gmock_p1)), \
p2(::std::forward<p2##_type>(gmock_p2)), \
p3(::std::forward<p3##_type>(gmock_p3)) {}\
- virtual return_type Perform(const args_type& args) {\
+ return_type Perform(const args_type& args) override {\
return ::testing::internal::ActionHelper<return_type, gmock_Impl>::\
Perform(this, args);\
}\
@@ -1038,7 +1038,7 @@ class ActionHelper {
p2(::std::forward<p2##_type>(gmock_p2)), \
p3(::std::forward<p3##_type>(gmock_p3)), \
p4(::std::forward<p4##_type>(gmock_p4)) {}\
- virtual return_type Perform(const args_type& args) {\
+ return_type Perform(const args_type& args) override {\
return ::testing::internal::ActionHelper<return_type, gmock_Impl>::\
Perform(this, args);\
}\
@@ -1119,7 +1119,7 @@ class ActionHelper {
p3(::std::forward<p3##_type>(gmock_p3)), \
p4(::std::forward<p4##_type>(gmock_p4)), \
p5(::std::forward<p5##_type>(gmock_p5)) {}\
- virtual return_type Perform(const args_type& args) {\
+ return_type Perform(const args_type& args) override {\
return ::testing::internal::ActionHelper<return_type, gmock_Impl>::\
Perform(this, args);\
}\
@@ -1206,7 +1206,7 @@ class ActionHelper {
p4(::std::forward<p4##_type>(gmock_p4)), \
p5(::std::forward<p5##_type>(gmock_p5)), \
p6(::std::forward<p6##_type>(gmock_p6)) {}\
- virtual return_type Perform(const args_type& args) {\
+ return_type Perform(const args_type& args) override {\
return ::testing::internal::ActionHelper<return_type, gmock_Impl>::\
Perform(this, args);\
}\
@@ -1302,7 +1302,7 @@ class ActionHelper {
p5(::std::forward<p5##_type>(gmock_p5)), \
p6(::std::forward<p6##_type>(gmock_p6)), \
p7(::std::forward<p7##_type>(gmock_p7)) {}\
- virtual return_type Perform(const args_type& args) {\
+ return_type Perform(const args_type& args) override {\
return ::testing::internal::ActionHelper<return_type, gmock_Impl>::\
Perform(this, args);\
}\
@@ -1404,7 +1404,7 @@ class ActionHelper {
p6(::std::forward<p6##_type>(gmock_p6)), \
p7(::std::forward<p7##_type>(gmock_p7)), \
p8(::std::forward<p8##_type>(gmock_p8)) {}\
- virtual return_type Perform(const args_type& args) {\
+ return_type Perform(const args_type& args) override {\
return ::testing::internal::ActionHelper<return_type, gmock_Impl>::\
Perform(this, args);\
}\
@@ -1513,7 +1513,7 @@ class ActionHelper {
p7(::std::forward<p7##_type>(gmock_p7)), \
p8(::std::forward<p8##_type>(gmock_p8)), \
p9(::std::forward<p9##_type>(gmock_p9)) {}\
- virtual return_type Perform(const args_type& args) {\
+ return_type Perform(const args_type& args) override {\
return ::testing::internal::ActionHelper<return_type, gmock_Impl>::\
Perform(this, args);\
}\
diff --git a/googlemock/include/gmock/gmock-generated-actions.h.pump b/googlemock/include/gmock/gmock-generated-actions.h.pump
index 209603c5..283abcdc 100644
--- a/googlemock/include/gmock/gmock-generated-actions.h.pump
+++ b/googlemock/include/gmock/gmock-generated-actions.h.pump
@@ -395,7 +395,7 @@ $range k 0..n-1
typedef typename ::testing::internal::Function<F>::ArgumentTuple\
args_type;\
explicit gmock_Impl GMOCK_INTERNAL_INIT_##value_params {}\
- virtual return_type Perform(const args_type& args) {\
+ return_type Perform(const args_type& args) override {\
return ::testing::internal::ActionHelper<return_type, gmock_Impl>::\
Perform(this, args);\
}\
@@ -482,7 +482,7 @@ $var macro_name = [[$if i==0 [[ACTION]] $elif i==1 [[ACTION_P]]
typedef typename ::testing::internal::Function<F>::ArgumentTuple\
args_type;\
[[$if i==1 [[explicit ]]]]gmock_Impl($ctor_param_list)$inits {}\
- virtual return_type Perform(const args_type& args) {\
+ return_type Perform(const args_type& args) override {\
return ::testing::internal::ActionHelper<return_type, gmock_Impl>::\
Perform(this, args);\
}\
diff --git a/googlemock/include/gmock/gmock-generated-matchers.h b/googlemock/include/gmock/gmock-generated-matchers.h
index 690a57f1..61892380 100644
--- a/googlemock/include/gmock/gmock-generated-matchers.h
+++ b/googlemock/include/gmock/gmock-generated-matchers.h
@@ -269,13 +269,13 @@
public:\
gmock_Impl()\
{}\
- virtual bool MatchAndExplain(\
+ bool MatchAndExplain(\
GTEST_REFERENCE_TO_CONST_(arg_type) arg,\
- ::testing::MatchResultListener* result_listener) const;\
- virtual void DescribeTo(::std::ostream* gmock_os) const {\
+ ::testing::MatchResultListener* result_listener) const override;\
+ void DescribeTo(::std::ostream* gmock_os) const override {\
*gmock_os << FormatDescription(false);\
}\
- virtual void DescribeNegationTo(::std::ostream* gmock_os) const {\
+ void DescribeNegationTo(::std::ostream* gmock_os) const override {\
*gmock_os << FormatDescription(true);\
}\
private:\
@@ -318,13 +318,13 @@
public:\
explicit gmock_Impl(p0##_type gmock_p0)\
: p0(::std::move(gmock_p0)) {}\
- virtual bool MatchAndExplain(\
+ bool MatchAndExplain(\
GTEST_REFERENCE_TO_CONST_(arg_type) arg,\
- ::testing::MatchResultListener* result_listener) const;\
- virtual void DescribeTo(::std::ostream* gmock_os) const {\
+ ::testing::MatchResultListener* result_listener) const override;\
+ void DescribeTo(::std::ostream* gmock_os) const override {\
*gmock_os << FormatDescription(false);\
}\
- virtual void DescribeNegationTo(::std::ostream* gmock_os) const {\
+ void DescribeNegationTo(::std::ostream* gmock_os) const override {\
*gmock_os << FormatDescription(true);\
}\
p0##_type const p0;\
@@ -371,13 +371,13 @@
public:\
gmock_Impl(p0##_type gmock_p0, p1##_type gmock_p1)\
: p0(::std::move(gmock_p0)), p1(::std::move(gmock_p1)) {}\
- virtual bool MatchAndExplain(\
+ bool MatchAndExplain(\
GTEST_REFERENCE_TO_CONST_(arg_type) arg,\
- ::testing::MatchResultListener* result_listener) const;\
- virtual void DescribeTo(::std::ostream* gmock_os) const {\
+ ::testing::MatchResultListener* result_listener) const override;\
+ void DescribeTo(::std::ostream* gmock_os) const override {\
*gmock_os << FormatDescription(false);\
}\
- virtual void DescribeNegationTo(::std::ostream* gmock_os) const {\
+ void DescribeNegationTo(::std::ostream* gmock_os) const override {\
*gmock_os << FormatDescription(true);\
}\
p0##_type const p0;\
@@ -431,13 +431,13 @@
gmock_Impl(p0##_type gmock_p0, p1##_type gmock_p1, p2##_type gmock_p2)\
: p0(::std::move(gmock_p0)), p1(::std::move(gmock_p1)), \
p2(::std::move(gmock_p2)) {}\
- virtual bool MatchAndExplain(\
+ bool MatchAndExplain(\
GTEST_REFERENCE_TO_CONST_(arg_type) arg,\
- ::testing::MatchResultListener* result_listener) const;\
- virtual void DescribeTo(::std::ostream* gmock_os) const {\
+ ::testing::MatchResultListener* result_listener) const override;\
+ void DescribeTo(::std::ostream* gmock_os) const override {\
*gmock_os << FormatDescription(false);\
}\
- virtual void DescribeNegationTo(::std::ostream* gmock_os) const {\
+ void DescribeNegationTo(::std::ostream* gmock_os) const override {\
*gmock_os << FormatDescription(true);\
}\
p0##_type const p0;\
@@ -495,13 +495,13 @@
p3##_type gmock_p3)\
: p0(::std::move(gmock_p0)), p1(::std::move(gmock_p1)), \
p2(::std::move(gmock_p2)), p3(::std::move(gmock_p3)) {}\
- virtual bool MatchAndExplain(\
+ bool MatchAndExplain(\
GTEST_REFERENCE_TO_CONST_(arg_type) arg,\
- ::testing::MatchResultListener* result_listener) const;\
- virtual void DescribeTo(::std::ostream* gmock_os) const {\
+ ::testing::MatchResultListener* result_listener) const override;\
+ void DescribeTo(::std::ostream* gmock_os) const override {\
*gmock_os << FormatDescription(false);\
}\
- virtual void DescribeNegationTo(::std::ostream* gmock_os) const {\
+ void DescribeNegationTo(::std::ostream* gmock_os) const override {\
*gmock_os << FormatDescription(true);\
}\
p0##_type const p0;\
@@ -568,13 +568,13 @@
: p0(::std::move(gmock_p0)), p1(::std::move(gmock_p1)), \
p2(::std::move(gmock_p2)), p3(::std::move(gmock_p3)), \
p4(::std::move(gmock_p4)) {}\
- virtual bool MatchAndExplain(\
+ bool MatchAndExplain(\
GTEST_REFERENCE_TO_CONST_(arg_type) arg,\
- ::testing::MatchResultListener* result_listener) const;\
- virtual void DescribeTo(::std::ostream* gmock_os) const {\
+ ::testing::MatchResultListener* result_listener) const override;\
+ void DescribeTo(::std::ostream* gmock_os) const override {\
*gmock_os << FormatDescription(false);\
}\
- virtual void DescribeNegationTo(::std::ostream* gmock_os) const {\
+ void DescribeNegationTo(::std::ostream* gmock_os) const override {\
*gmock_os << FormatDescription(true);\
}\
p0##_type const p0;\
@@ -644,13 +644,13 @@
: p0(::std::move(gmock_p0)), p1(::std::move(gmock_p1)), \
p2(::std::move(gmock_p2)), p3(::std::move(gmock_p3)), \
p4(::std::move(gmock_p4)), p5(::std::move(gmock_p5)) {}\
- virtual bool MatchAndExplain(\
+ bool MatchAndExplain(\
GTEST_REFERENCE_TO_CONST_(arg_type) arg,\
- ::testing::MatchResultListener* result_listener) const;\
- virtual void DescribeTo(::std::ostream* gmock_os) const {\
+ ::testing::MatchResultListener* result_listener) const override;\
+ void DescribeTo(::std::ostream* gmock_os) const override {\
*gmock_os << FormatDescription(false);\
}\
- virtual void DescribeNegationTo(::std::ostream* gmock_os) const {\
+ void DescribeNegationTo(::std::ostream* gmock_os) const override {\
*gmock_os << FormatDescription(true);\
}\
p0##_type const p0;\
@@ -726,13 +726,13 @@
p2(::std::move(gmock_p2)), p3(::std::move(gmock_p3)), \
p4(::std::move(gmock_p4)), p5(::std::move(gmock_p5)), \
p6(::std::move(gmock_p6)) {}\
- virtual bool MatchAndExplain(\
+ bool MatchAndExplain(\
GTEST_REFERENCE_TO_CONST_(arg_type) arg,\
- ::testing::MatchResultListener* result_listener) const;\
- virtual void DescribeTo(::std::ostream* gmock_os) const {\
+ ::testing::MatchResultListener* result_listener) const override;\
+ void DescribeTo(::std::ostream* gmock_os) const override {\
*gmock_os << FormatDescription(false);\
}\
- virtual void DescribeNegationTo(::std::ostream* gmock_os) const {\
+ void DescribeNegationTo(::std::ostream* gmock_os) const override {\
*gmock_os << FormatDescription(true);\
}\
p0##_type const p0;\
@@ -814,13 +814,13 @@
p2(::std::move(gmock_p2)), p3(::std::move(gmock_p3)), \
p4(::std::move(gmock_p4)), p5(::std::move(gmock_p5)), \
p6(::std::move(gmock_p6)), p7(::std::move(gmock_p7)) {}\
- virtual bool MatchAndExplain(\
+ bool MatchAndExplain(\
GTEST_REFERENCE_TO_CONST_(arg_type) arg,\
- ::testing::MatchResultListener* result_listener) const;\
- virtual void DescribeTo(::std::ostream* gmock_os) const {\
+ ::testing::MatchResultListener* result_listener) const override;\
+ void DescribeTo(::std::ostream* gmock_os) const override {\
*gmock_os << FormatDescription(false);\
}\
- virtual void DescribeNegationTo(::std::ostream* gmock_os) const {\
+ void DescribeNegationTo(::std::ostream* gmock_os) const override {\
*gmock_os << FormatDescription(true);\
}\
p0##_type const p0;\
@@ -909,13 +909,13 @@
p4(::std::move(gmock_p4)), p5(::std::move(gmock_p5)), \
p6(::std::move(gmock_p6)), p7(::std::move(gmock_p7)), \
p8(::std::move(gmock_p8)) {}\
- virtual bool MatchAndExplain(\
+ bool MatchAndExplain(\
GTEST_REFERENCE_TO_CONST_(arg_type) arg,\
- ::testing::MatchResultListener* result_listener) const;\
- virtual void DescribeTo(::std::ostream* gmock_os) const {\
+ ::testing::MatchResultListener* result_listener) const override;\
+ void DescribeTo(::std::ostream* gmock_os) const override {\
*gmock_os << FormatDescription(false);\
}\
- virtual void DescribeNegationTo(::std::ostream* gmock_os) const {\
+ void DescribeNegationTo(::std::ostream* gmock_os) const override {\
*gmock_os << FormatDescription(true);\
}\
p0##_type const p0;\
@@ -1009,13 +1009,13 @@
p4(::std::move(gmock_p4)), p5(::std::move(gmock_p5)), \
p6(::std::move(gmock_p6)), p7(::std::move(gmock_p7)), \
p8(::std::move(gmock_p8)), p9(::std::move(gmock_p9)) {}\
- virtual bool MatchAndExplain(\
+ bool MatchAndExplain(\
GTEST_REFERENCE_TO_CONST_(arg_type) arg,\
- ::testing::MatchResultListener* result_listener) const;\
- virtual void DescribeTo(::std::ostream* gmock_os) const {\
+ ::testing::MatchResultListener* result_listener) const override;\
+ void DescribeTo(::std::ostream* gmock_os) const override {\
*gmock_os << FormatDescription(false);\
}\
- virtual void DescribeNegationTo(::std::ostream* gmock_os) const {\
+ void DescribeNegationTo(::std::ostream* gmock_os) const override {\
*gmock_os << FormatDescription(true);\
}\
p0##_type const p0;\
diff --git a/googlemock/include/gmock/gmock-generated-matchers.h.pump b/googlemock/include/gmock/gmock-generated-matchers.h.pump
index ae90917c..69d2ae41 100644
--- a/googlemock/include/gmock/gmock-generated-matchers.h.pump
+++ b/googlemock/include/gmock/gmock-generated-matchers.h.pump
@@ -302,13 +302,13 @@ $var param_field_decls2 = [[$for j
public:\
[[$if i==1 [[explicit ]]]]gmock_Impl($impl_ctor_param_list)\
$impl_inits {}\
- virtual bool MatchAndExplain(\
+ bool MatchAndExplain(\
GTEST_REFERENCE_TO_CONST_(arg_type) arg,\
- ::testing::MatchResultListener* result_listener) const;\
- virtual void DescribeTo(::std::ostream* gmock_os) const {\
+ ::testing::MatchResultListener* result_listener) const override;\
+ void DescribeTo(::std::ostream* gmock_os) const override {\
*gmock_os << FormatDescription(false);\
}\
- virtual void DescribeNegationTo(::std::ostream* gmock_os) const {\
+ void DescribeNegationTo(::std::ostream* gmock_os) const override {\
*gmock_os << FormatDescription(true);\
}\$param_field_decls
private:\
diff --git a/googlemock/include/gmock/gmock-matchers.h b/googlemock/include/gmock/gmock-matchers.h
index 4428ec14..be446aad 100644
--- a/googlemock/include/gmock/gmock-matchers.h
+++ b/googlemock/include/gmock/gmock-matchers.h
@@ -42,8 +42,8 @@
#ifndef GMOCK_INCLUDE_GMOCK_GMOCK_MATCHERS_H_
#define GMOCK_INCLUDE_GMOCK_GMOCK_MATCHERS_H_
-#include <math.h>
#include <algorithm>
+#include <cmath>
#include <initializer_list>
#include <iterator>
#include <limits>
@@ -54,6 +54,7 @@
#include <type_traits>
#include <utility>
#include <vector>
+
#include "gmock/internal/gmock-internal-utils.h"
#include "gmock/internal/gmock-port.h"
#include "gtest/gtest.h"
@@ -1349,6 +1350,22 @@ MakePredicateFormatterFromMatcher(M matcher) {
return PredicateFormatterFromMatcher<M>(std::move(matcher));
}
+// Implements the polymorphic IsNan() matcher, which matches any floating type
+// value that is Nan.
+class IsNanMatcher {
+ public:
+ template <typename FloatType>
+ bool MatchAndExplain(const FloatType& f,
+ MatchResultListener* /* listener */) const {
+ return (::std::isnan)(f);
+ }
+
+ void DescribeTo(::std::ostream* os) const { *os << "is NaN"; }
+ void DescribeNegationTo(::std::ostream* os) const {
+ *os << "isn't NaN";
+ }
+};
+
// Implements the polymorphic floating point equality matcher, which matches
// two float values using ULP-based approximation or, optionally, a
// user-specified epsilon. The template is meant to be instantiated with
@@ -1409,7 +1426,7 @@ class FloatingEqMatcher {
}
const FloatType diff = value - expected_;
- if (fabs(diff) <= max_abs_error_) {
+ if (::std::fabs(diff) <= max_abs_error_) {
return true;
}
@@ -3626,6 +3643,11 @@ inline internal::RefMatcher<T&> Ref(T& x) { // NOLINT
return internal::RefMatcher<T&>(x);
}
+// Creates a polymorphic matcher that matches any NaN floating point.
+inline PolymorphicMatcher<internal::IsNanMatcher> IsNan() {
+ return MakePolymorphicMatcher(internal::IsNanMatcher());
+}
+
// Creates a matcher that matches any double argument approximately
// equal to rhs, where two NANs are considered unequal.
inline internal::FloatingEqMatcher<double> DoubleEq(double rhs) {
diff --git a/googlemock/include/gmock/internal/gmock-internal-utils.h b/googlemock/include/gmock/internal/gmock-internal-utils.h
index d012e710..584afa98 100644
--- a/googlemock/include/gmock/internal/gmock-internal-utils.h
+++ b/googlemock/include/gmock/internal/gmock-internal-utils.h
@@ -490,8 +490,7 @@ struct Function<R(Args...)> {
using Result = R;
static constexpr size_t ArgumentCount = sizeof...(Args);
template <size_t I>
- using Arg = ElemFromList<I, typename MakeIndexSequence<sizeof...(Args)>::type,
- Args...>;
+ using Arg = ElemFromList<I, Args...>;
using ArgumentTuple = std::tuple<Args...>;
using ArgumentMatcherTuple = std::tuple<Matcher<Args>...>;
using MakeResultVoid = void(Args...);
diff --git a/googlemock/src/gmock-spec-builders.cc b/googlemock/src/gmock-spec-builders.cc
index f9d34345..81ea9894 100644
--- a/googlemock/src/gmock-spec-builders.cc
+++ b/googlemock/src/gmock-spec-builders.cc
@@ -36,14 +36,17 @@
#include "gmock/gmock-spec-builders.h"
#include <stdlib.h>
+
#include <iostream> // NOLINT
#include <map>
#include <memory>
#include <set>
#include <string>
#include <vector>
+
#include "gmock/gmock.h"
#include "gtest/gtest.h"
+#include "gtest/internal/gtest-port.h"
#if GTEST_OS_CYGWIN || GTEST_OS_LINUX || GTEST_OS_MAC
# include <unistd.h> // NOLINT
@@ -70,7 +73,8 @@ GTEST_API_ void LogWithLocation(testing::internal::LogSeverity severity,
const char* file, int line,
const std::string& message) {
::std::ostringstream s;
- s << file << ":" << line << ": " << message << ::std::endl;
+ s << internal::FormatFileLocation(file, line) << " " << message
+ << ::std::endl;
Log(severity, s.str(), 0);
}
diff --git a/googlemock/test/gmock-function-mocker_test.cc b/googlemock/test/gmock-function-mocker_test.cc
index fbc5d5b2..55be70a8 100644
--- a/googlemock/test/gmock-function-mocker_test.cc
+++ b/googlemock/test/gmock-function-mocker_test.cc
@@ -101,6 +101,10 @@ class FooInterface {
virtual int TypeWithComma(const std::map<int, std::string>& a_map) = 0;
virtual int TypeWithTemplatedCopyCtor(const TemplatedCopyable<int>&) = 0;
+ virtual int (*ReturnsFunctionPointer1(int))(bool) = 0;
+ using fn_ptr = int (*)(bool);
+ virtual fn_ptr ReturnsFunctionPointer2(int) = 0;
+
#if GTEST_OS_WINDOWS
STDMETHOD_(int, CTNullary)() = 0;
STDMETHOD_(bool, CTUnary)(int x) = 0;
@@ -159,6 +163,9 @@ class MockFoo : public FooInterface {
MOCK_METHOD(int, TypeWithTemplatedCopyCtor,
(const TemplatedCopyable<int>&)); // NOLINT
+ MOCK_METHOD(int (*)(bool), ReturnsFunctionPointer1, (int), ());
+ MOCK_METHOD(fn_ptr, ReturnsFunctionPointer2, (int), ());
+
#if GTEST_OS_WINDOWS
MOCK_METHOD(int, CTNullary, (), (Calltype(STDMETHODCALLTYPE)));
MOCK_METHOD(bool, CTUnary, (int), (Calltype(STDMETHODCALLTYPE)));
diff --git a/googlemock/test/gmock-matchers_test.cc b/googlemock/test/gmock-matchers_test.cc
index 03735267..b9eb894d 100644
--- a/googlemock/test/gmock-matchers_test.cc
+++ b/googlemock/test/gmock-matchers_test.cc
@@ -2054,6 +2054,114 @@ TEST(PairMatchBaseTest, WorksWithMoveOnly) {
EXPECT_TRUE(matcher.Matches(pointers));
}
+// Tests that IsNan() matches a NaN, with float.
+TEST(IsNan, FloatMatchesNan) {
+ float quiet_nan = std::numeric_limits<float>::quiet_NaN();
+ float other_nan = std::nanf("1");
+ float real_value = 1.0f;
+
+ Matcher<float> m = IsNan();
+ EXPECT_TRUE(m.Matches(quiet_nan));
+ EXPECT_TRUE(m.Matches(other_nan));
+ EXPECT_FALSE(m.Matches(real_value));
+
+ Matcher<float&> m_ref = IsNan();
+ EXPECT_TRUE(m_ref.Matches(quiet_nan));
+ EXPECT_TRUE(m_ref.Matches(other_nan));
+ EXPECT_FALSE(m_ref.Matches(real_value));
+
+ Matcher<const float&> m_cref = IsNan();
+ EXPECT_TRUE(m_cref.Matches(quiet_nan));
+ EXPECT_TRUE(m_cref.Matches(other_nan));
+ EXPECT_FALSE(m_cref.Matches(real_value));
+}
+
+// Tests that IsNan() matches a NaN, with double.
+TEST(IsNan, DoubleMatchesNan) {
+ double quiet_nan = std::numeric_limits<double>::quiet_NaN();
+ double other_nan = std::nan("1");
+ double real_value = 1.0;
+
+ Matcher<double> m = IsNan();
+ EXPECT_TRUE(m.Matches(quiet_nan));
+ EXPECT_TRUE(m.Matches(other_nan));
+ EXPECT_FALSE(m.Matches(real_value));
+
+ Matcher<double&> m_ref = IsNan();
+ EXPECT_TRUE(m_ref.Matches(quiet_nan));
+ EXPECT_TRUE(m_ref.Matches(other_nan));
+ EXPECT_FALSE(m_ref.Matches(real_value));
+
+ Matcher<const double&> m_cref = IsNan();
+ EXPECT_TRUE(m_cref.Matches(quiet_nan));
+ EXPECT_TRUE(m_cref.Matches(other_nan));
+ EXPECT_FALSE(m_cref.Matches(real_value));
+}
+
+// Tests that IsNan() matches a NaN, with long double.
+TEST(IsNan, LongDoubleMatchesNan) {
+ long double quiet_nan = std::numeric_limits<long double>::quiet_NaN();
+ long double other_nan = std::nan("1");
+ long double real_value = 1.0;
+
+ Matcher<long double> m = IsNan();
+ EXPECT_TRUE(m.Matches(quiet_nan));
+ EXPECT_TRUE(m.Matches(other_nan));
+ EXPECT_FALSE(m.Matches(real_value));
+
+ Matcher<long double&> m_ref = IsNan();
+ EXPECT_TRUE(m_ref.Matches(quiet_nan));
+ EXPECT_TRUE(m_ref.Matches(other_nan));
+ EXPECT_FALSE(m_ref.Matches(real_value));
+
+ Matcher<const long double&> m_cref = IsNan();
+ EXPECT_TRUE(m_cref.Matches(quiet_nan));
+ EXPECT_TRUE(m_cref.Matches(other_nan));
+ EXPECT_FALSE(m_cref.Matches(real_value));
+}
+
+// Tests that IsNan() works with Not.
+TEST(IsNan, NotMatchesNan) {
+ Matcher<float> mf = Not(IsNan());
+ EXPECT_FALSE(mf.Matches(std::numeric_limits<float>::quiet_NaN()));
+ EXPECT_FALSE(mf.Matches(std::nanf("1")));
+ EXPECT_TRUE(mf.Matches(1.0));
+
+ Matcher<double> md = Not(IsNan());
+ EXPECT_FALSE(md.Matches(std::numeric_limits<double>::quiet_NaN()));
+ EXPECT_FALSE(md.Matches(std::nan("1")));
+ EXPECT_TRUE(md.Matches(1.0));
+
+ Matcher<long double> mld = Not(IsNan());
+ EXPECT_FALSE(mld.Matches(std::numeric_limits<long double>::quiet_NaN()));
+ EXPECT_FALSE(mld.Matches(std::nanl("1")));
+ EXPECT_TRUE(mld.Matches(1.0));
+}
+
+// Tests that IsNan() can describe itself.
+TEST(IsNan, CanDescribeSelf) {
+ Matcher<float> mf = IsNan();
+ EXPECT_EQ("is NaN", Describe(mf));
+
+ Matcher<double> md = IsNan();
+ EXPECT_EQ("is NaN", Describe(md));
+
+ Matcher<long double> mld = IsNan();
+ EXPECT_EQ("is NaN", Describe(mld));
+}
+
+// Tests that IsNan() can describe itself with Not.
+TEST(IsNan, CanDescribeSelfWithNot) {
+ Matcher<float> mf = Not(IsNan());
+ EXPECT_EQ("isn't NaN", Describe(mf));
+
+ Matcher<double> md = Not(IsNan());
+ EXPECT_EQ("isn't NaN", Describe(md));
+
+ Matcher<long double> mld = Not(IsNan());
+ EXPECT_EQ("isn't NaN", Describe(mld));
+}
+
// Tests that FloatEq() matches a 2-tuple where
// FloatEq(first field) matches the second field.
TEST(FloatEq2Test, MatchesEqualArguments) {
diff --git a/googlemock/test/gmock-spec-builders_test.cc b/googlemock/test/gmock-spec-builders_test.cc
index 7bf5a8ad..791a2476 100644
--- a/googlemock/test/gmock-spec-builders_test.cc
+++ b/googlemock/test/gmock-spec-builders_test.cc
@@ -69,8 +69,8 @@ using testing::AtMost;
using testing::Between;
using testing::Cardinality;
using testing::CardinalityInterface;
-using testing::ContainsRegex;
using testing::Const;
+using testing::ContainsRegex;
using testing::DoAll;
using testing::DoDefault;
using testing::Eq;