Unverified Commit 687964c8 authored by Conor Burgess's avatar Conor Burgess Committed by GitHub
Browse files

Merge branch 'master' into fix-argc

parents f11a8f91 02a8ca87
...@@ -30,8 +30,7 @@ ...@@ -30,8 +30,7 @@
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// Author: wan@google.com (Zhanyong Wan)
// Implements class templates NiceMock, NaggyMock, and StrictMock. // Implements class templates NiceMock, NaggyMock, and StrictMock.
// //
...@@ -51,10 +50,9 @@ ...@@ -51,10 +50,9 @@
// NiceMock<MockFoo>. // NiceMock<MockFoo>.
// //
// NiceMock, NaggyMock, and StrictMock "inherit" the constructors of // NiceMock, NaggyMock, and StrictMock "inherit" the constructors of
// their respective base class, with up-to 10 arguments. Therefore // their respective base class. Therefore you can write
// you can write NiceMock<MockFoo>(5, "a") to construct a nice mock // NiceMock<MockFoo>(5, "a") to construct a nice mock where MockFoo
// where MockFoo has a constructor that accepts (int, const char*), // has a constructor that accepts (int, const char*), for example.
// for example.
// //
// A known limitation is that NiceMock<MockFoo>, NaggyMock<MockFoo>, // A known limitation is that NiceMock<MockFoo>, NaggyMock<MockFoo>,
// and StrictMock<MockFoo> only works for mock methods defined using // and StrictMock<MockFoo> only works for mock methods defined using
...@@ -63,10 +61,8 @@ ...@@ -63,10 +61,8 @@
// or "strict" modifier may not affect it, depending on the compiler. // or "strict" modifier may not affect it, depending on the compiler.
// In particular, nesting NiceMock, NaggyMock, and StrictMock is NOT // In particular, nesting NiceMock, NaggyMock, and StrictMock is NOT
// supported. // supported.
//
// Another known limitation is that the constructors of the base mock // GOOGLETEST_CM0002 DO NOT DELETE
// cannot have arguments passed by non-const reference, which are
// banned by the Google C++ style guide anyway.
#ifndef GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_NICE_STRICT_H_ #ifndef GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_NICE_STRICT_H_
#define GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_NICE_STRICT_H_ #define GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_NICE_STRICT_H_
...@@ -79,15 +75,35 @@ namespace testing { ...@@ -79,15 +75,35 @@ namespace testing {
template <class MockClass> template <class MockClass>
class NiceMock : public MockClass { class NiceMock : public MockClass {
public: public:
// We don't factor out the constructor body to a common method, as NiceMock() : MockClass() {
// we have to avoid a possible clash with members of MockClass. ::testing::Mock::AllowUninterestingCalls(
NiceMock() { internal::ImplicitCast_<MockClass*>(this));
}
#if GTEST_LANG_CXX11
// Ideally, we would inherit base class's constructors through a using
// declaration, which would preserve their visibility. However, many existing
// tests rely on the fact that current implementation reexports protected
// constructors as public. These tests would need to be cleaned up first.
// Single argument constructor is special-cased so that it can be
// made explicit.
template <typename A>
explicit NiceMock(A&& arg) : MockClass(std::forward<A>(arg)) {
::testing::Mock::AllowUninterestingCalls( ::testing::Mock::AllowUninterestingCalls(
internal::ImplicitCast_<MockClass*>(this)); internal::ImplicitCast_<MockClass*>(this));
} }
// C++ doesn't (yet) allow inheritance of constructors, so we have template <typename A1, typename A2, typename... An>
// to define it for each arity. NiceMock(A1&& arg1, A2&& arg2, An&&... args)
: MockClass(std::forward<A1>(arg1), std::forward<A2>(arg2),
std::forward<An>(args)...) {
::testing::Mock::AllowUninterestingCalls(
internal::ImplicitCast_<MockClass*>(this));
}
#else
// C++98 doesn't have variadic templates, so we have to define one
// for each arity.
template <typename A1> template <typename A1>
explicit NiceMock(const A1& a1) : MockClass(a1) { explicit NiceMock(const A1& a1) : MockClass(a1) {
::testing::Mock::AllowUninterestingCalls( ::testing::Mock::AllowUninterestingCalls(
...@@ -163,7 +179,9 @@ class NiceMock : public MockClass { ...@@ -163,7 +179,9 @@ class NiceMock : public MockClass {
internal::ImplicitCast_<MockClass*>(this)); internal::ImplicitCast_<MockClass*>(this));
} }
virtual ~NiceMock() { #endif // GTEST_LANG_CXX11
~NiceMock() {
::testing::Mock::UnregisterCallReaction( ::testing::Mock::UnregisterCallReaction(
internal::ImplicitCast_<MockClass*>(this)); internal::ImplicitCast_<MockClass*>(this));
} }
...@@ -175,15 +193,35 @@ class NiceMock : public MockClass { ...@@ -175,15 +193,35 @@ class NiceMock : public MockClass {
template <class MockClass> template <class MockClass>
class NaggyMock : public MockClass { class NaggyMock : public MockClass {
public: public:
// We don't factor out the constructor body to a common method, as NaggyMock() : MockClass() {
// we have to avoid a possible clash with members of MockClass.
NaggyMock() {
::testing::Mock::WarnUninterestingCalls( ::testing::Mock::WarnUninterestingCalls(
internal::ImplicitCast_<MockClass*>(this)); internal::ImplicitCast_<MockClass*>(this));
} }
// C++ doesn't (yet) allow inheritance of constructors, so we have #if GTEST_LANG_CXX11
// to define it for each arity. // Ideally, we would inherit base class's constructors through a using
// declaration, which would preserve their visibility. However, many existing
// tests rely on the fact that current implementation reexports protected
// constructors as public. These tests would need to be cleaned up first.
// Single argument constructor is special-cased so that it can be
// made explicit.
template <typename A>
explicit NaggyMock(A&& arg) : MockClass(std::forward<A>(arg)) {
::testing::Mock::WarnUninterestingCalls(
internal::ImplicitCast_<MockClass*>(this));
}
template <typename A1, typename A2, typename... An>
NaggyMock(A1&& arg1, A2&& arg2, An&&... args)
: MockClass(std::forward<A1>(arg1), std::forward<A2>(arg2),
std::forward<An>(args)...) {
::testing::Mock::WarnUninterestingCalls(
internal::ImplicitCast_<MockClass*>(this));
}
#else
// C++98 doesn't have variadic templates, so we have to define one
// for each arity.
template <typename A1> template <typename A1>
explicit NaggyMock(const A1& a1) : MockClass(a1) { explicit NaggyMock(const A1& a1) : MockClass(a1) {
::testing::Mock::WarnUninterestingCalls( ::testing::Mock::WarnUninterestingCalls(
...@@ -259,7 +297,9 @@ class NaggyMock : public MockClass { ...@@ -259,7 +297,9 @@ class NaggyMock : public MockClass {
internal::ImplicitCast_<MockClass*>(this)); internal::ImplicitCast_<MockClass*>(this));
} }
virtual ~NaggyMock() { #endif // GTEST_LANG_CXX11
~NaggyMock() {
::testing::Mock::UnregisterCallReaction( ::testing::Mock::UnregisterCallReaction(
internal::ImplicitCast_<MockClass*>(this)); internal::ImplicitCast_<MockClass*>(this));
} }
...@@ -271,15 +311,35 @@ class NaggyMock : public MockClass { ...@@ -271,15 +311,35 @@ class NaggyMock : public MockClass {
template <class MockClass> template <class MockClass>
class StrictMock : public MockClass { class StrictMock : public MockClass {
public: public:
// We don't factor out the constructor body to a common method, as StrictMock() : MockClass() {
// we have to avoid a possible clash with members of MockClass.
StrictMock() {
::testing::Mock::FailUninterestingCalls( ::testing::Mock::FailUninterestingCalls(
internal::ImplicitCast_<MockClass*>(this)); internal::ImplicitCast_<MockClass*>(this));
} }
// C++ doesn't (yet) allow inheritance of constructors, so we have #if GTEST_LANG_CXX11
// to define it for each arity. // Ideally, we would inherit base class's constructors through a using
// declaration, which would preserve their visibility. However, many existing
// tests rely on the fact that current implementation reexports protected
// constructors as public. These tests would need to be cleaned up first.
// Single argument constructor is special-cased so that it can be
// made explicit.
template <typename A>
explicit StrictMock(A&& arg) : MockClass(std::forward<A>(arg)) {
::testing::Mock::FailUninterestingCalls(
internal::ImplicitCast_<MockClass*>(this));
}
template <typename A1, typename A2, typename... An>
StrictMock(A1&& arg1, A2&& arg2, An&&... args)
: MockClass(std::forward<A1>(arg1), std::forward<A2>(arg2),
std::forward<An>(args)...) {
::testing::Mock::FailUninterestingCalls(
internal::ImplicitCast_<MockClass*>(this));
}
#else
// C++98 doesn't have variadic templates, so we have to define one
// for each arity.
template <typename A1> template <typename A1>
explicit StrictMock(const A1& a1) : MockClass(a1) { explicit StrictMock(const A1& a1) : MockClass(a1) {
::testing::Mock::FailUninterestingCalls( ::testing::Mock::FailUninterestingCalls(
...@@ -355,7 +415,9 @@ class StrictMock : public MockClass { ...@@ -355,7 +415,9 @@ class StrictMock : public MockClass {
internal::ImplicitCast_<MockClass*>(this)); internal::ImplicitCast_<MockClass*>(this));
} }
virtual ~StrictMock() { #endif // GTEST_LANG_CXX11
~StrictMock() {
::testing::Mock::UnregisterCallReaction( ::testing::Mock::UnregisterCallReaction(
internal::ImplicitCast_<MockClass*>(this)); internal::ImplicitCast_<MockClass*>(this));
} }
......
$$ -*- mode: c++; -*- $$ -*- mode: c++; -*-
$$ This is a Pump source file. Please use Pump to convert it to $$ This is a Pump source file. Please use Pump to convert
$$ gmock-generated-nice-strict.h. $$ it to gmock-generated-nice-strict.h.
$$ $$
$var n = 10 $$ The maximum arity we support. $var n = 10 $$ The maximum arity we support.
// Copyright 2008, Google Inc. // Copyright 2008, Google Inc.
...@@ -31,8 +31,7 @@ $var n = 10 $$ The maximum arity we support. ...@@ -31,8 +31,7 @@ $var n = 10 $$ The maximum arity we support.
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// Author: wan@google.com (Zhanyong Wan)
// Implements class templates NiceMock, NaggyMock, and StrictMock. // Implements class templates NiceMock, NaggyMock, and StrictMock.
// //
...@@ -52,10 +51,9 @@ $var n = 10 $$ The maximum arity we support. ...@@ -52,10 +51,9 @@ $var n = 10 $$ The maximum arity we support.
// NiceMock<MockFoo>. // NiceMock<MockFoo>.
// //
// NiceMock, NaggyMock, and StrictMock "inherit" the constructors of // NiceMock, NaggyMock, and StrictMock "inherit" the constructors of
// their respective base class, with up-to $n arguments. Therefore // their respective base class. Therefore you can write
// you can write NiceMock<MockFoo>(5, "a") to construct a nice mock // NiceMock<MockFoo>(5, "a") to construct a nice mock where MockFoo
// where MockFoo has a constructor that accepts (int, const char*), // has a constructor that accepts (int, const char*), for example.
// for example.
// //
// A known limitation is that NiceMock<MockFoo>, NaggyMock<MockFoo>, // A known limitation is that NiceMock<MockFoo>, NaggyMock<MockFoo>,
// and StrictMock<MockFoo> only works for mock methods defined using // and StrictMock<MockFoo> only works for mock methods defined using
...@@ -64,10 +62,8 @@ $var n = 10 $$ The maximum arity we support. ...@@ -64,10 +62,8 @@ $var n = 10 $$ The maximum arity we support.
// or "strict" modifier may not affect it, depending on the compiler. // or "strict" modifier may not affect it, depending on the compiler.
// In particular, nesting NiceMock, NaggyMock, and StrictMock is NOT // In particular, nesting NiceMock, NaggyMock, and StrictMock is NOT
// supported. // supported.
//
// Another known limitation is that the constructors of the base mock // GOOGLETEST_CM0002 DO NOT DELETE
// cannot have arguments passed by non-const reference, which are
// banned by the Google C++ style guide anyway.
#ifndef GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_NICE_STRICT_H_ #ifndef GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_NICE_STRICT_H_
#define GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_NICE_STRICT_H_ #define GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_NICE_STRICT_H_
...@@ -91,15 +87,35 @@ $var method=[[$if kind==0 [[AllowUninterestingCalls]] ...@@ -91,15 +87,35 @@ $var method=[[$if kind==0 [[AllowUninterestingCalls]]
template <class MockClass> template <class MockClass>
class $clazz : public MockClass { class $clazz : public MockClass {
public: public:
// We don't factor out the constructor body to a common method, as $clazz() : MockClass() {
// we have to avoid a possible clash with members of MockClass.
$clazz() {
::testing::Mock::$method( ::testing::Mock::$method(
internal::ImplicitCast_<MockClass*>(this)); internal::ImplicitCast_<MockClass*>(this));
} }
// C++ doesn't (yet) allow inheritance of constructors, so we have #if GTEST_LANG_CXX11
// to define it for each arity. // Ideally, we would inherit base class's constructors through a using
// declaration, which would preserve their visibility. However, many existing
// tests rely on the fact that current implementation reexports protected
// constructors as public. These tests would need to be cleaned up first.
// Single argument constructor is special-cased so that it can be
// made explicit.
template <typename A>
explicit $clazz(A&& arg) : MockClass(std::forward<A>(arg)) {
::testing::Mock::$method(
internal::ImplicitCast_<MockClass*>(this));
}
template <typename A1, typename A2, typename... An>
$clazz(A1&& arg1, A2&& arg2, An&&... args)
: MockClass(std::forward<A1>(arg1), std::forward<A2>(arg2),
std::forward<An>(args)...) {
::testing::Mock::$method(
internal::ImplicitCast_<MockClass*>(this));
}
#else
// C++98 doesn't have variadic templates, so we have to define one
// for each arity.
template <typename A1> template <typename A1>
explicit $clazz(const A1& a1) : MockClass(a1) { explicit $clazz(const A1& a1) : MockClass(a1) {
::testing::Mock::$method( ::testing::Mock::$method(
...@@ -117,7 +133,9 @@ $range j 1..i ...@@ -117,7 +133,9 @@ $range j 1..i
]] ]]
virtual ~$clazz() { #endif // GTEST_LANG_CXX11
~$clazz() {
::testing::Mock::UnregisterCallReaction( ::testing::Mock::UnregisterCallReaction(
internal::ImplicitCast_<MockClass*>(this)); internal::ImplicitCast_<MockClass*>(this));
} }
......
...@@ -26,8 +26,7 @@ ...@@ -26,8 +26,7 @@
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// Author: wan@google.com (Zhanyong Wan)
// Google Mock - a framework for writing C++ mock classes. // Google Mock - a framework for writing C++ mock classes.
// //
...@@ -35,6 +34,8 @@ ...@@ -35,6 +34,8 @@
// matchers can be defined by the user implementing the // matchers can be defined by the user implementing the
// MatcherInterface<T> interface if necessary. // MatcherInterface<T> interface if necessary.
// GOOGLETEST_CM0002 DO NOT DELETE
#ifndef GMOCK_INCLUDE_GMOCK_GMOCK_MATCHERS_H_ #ifndef GMOCK_INCLUDE_GMOCK_GMOCK_MATCHERS_H_
#define GMOCK_INCLUDE_GMOCK_GMOCK_MATCHERS_H_ #define GMOCK_INCLUDE_GMOCK_GMOCK_MATCHERS_H_
...@@ -72,7 +73,7 @@ namespace testing { ...@@ -72,7 +73,7 @@ namespace testing {
// MatchResultListener is an abstract class. Its << operator can be // MatchResultListener is an abstract class. Its << operator can be
// used by a matcher to explain why a value matches or doesn't match. // used by a matcher to explain why a value matches or doesn't match.
// //
// TODO(wan@google.com): add method // FIXME: add method
// bool InterestedInWhy(bool result) const; // bool InterestedInWhy(bool result) const;
// to indicate whether the listener is interested in why the match // to indicate whether the listener is interested in why the match
// result is 'result'. // result is 'result'.
...@@ -179,6 +180,35 @@ class MatcherInterface : public MatcherDescriberInterface { ...@@ -179,6 +180,35 @@ class MatcherInterface : public MatcherDescriberInterface {
// virtual void DescribeNegationTo(::std::ostream* os) const; // virtual void DescribeNegationTo(::std::ostream* os) const;
}; };
namespace internal {
// Converts a MatcherInterface<T> to a MatcherInterface<const T&>.
template <typename T>
class MatcherInterfaceAdapter : public MatcherInterface<const T&> {
public:
explicit MatcherInterfaceAdapter(const MatcherInterface<T>* impl)
: impl_(impl) {}
virtual ~MatcherInterfaceAdapter() { delete impl_; }
virtual void DescribeTo(::std::ostream* os) const { impl_->DescribeTo(os); }
virtual void DescribeNegationTo(::std::ostream* os) const {
impl_->DescribeNegationTo(os);
}
virtual bool MatchAndExplain(const T& x,
MatchResultListener* listener) const {
return impl_->MatchAndExplain(x, listener);
}
private:
const MatcherInterface<T>* const impl_;
GTEST_DISALLOW_COPY_AND_ASSIGN_(MatcherInterfaceAdapter);
};
} // namespace internal
// A match result listener that stores the explanation in a string. // A match result listener that stores the explanation in a string.
class StringMatchResultListener : public MatchResultListener { class StringMatchResultListener : public MatchResultListener {
public: public:
...@@ -252,12 +282,13 @@ class MatcherBase { ...@@ -252,12 +282,13 @@ class MatcherBase {
public: public:
// Returns true iff the matcher matches x; also explains the match // Returns true iff the matcher matches x; also explains the match
// result to 'listener'. // result to 'listener'.
bool MatchAndExplain(T x, MatchResultListener* listener) const { bool MatchAndExplain(GTEST_REFERENCE_TO_CONST_(T) x,
MatchResultListener* listener) const {
return impl_->MatchAndExplain(x, listener); return impl_->MatchAndExplain(x, listener);
} }
// Returns true iff this matcher matches x. // Returns true iff this matcher matches x.
bool Matches(T x) const { bool Matches(GTEST_REFERENCE_TO_CONST_(T) x) const {
DummyMatchResultListener dummy; DummyMatchResultListener dummy;
return MatchAndExplain(x, &dummy); return MatchAndExplain(x, &dummy);
} }
...@@ -271,7 +302,8 @@ class MatcherBase { ...@@ -271,7 +302,8 @@ class MatcherBase {
} }
// Explains why x matches, or doesn't match, the matcher. // Explains why x matches, or doesn't match, the matcher.
void ExplainMatchResultTo(T x, ::std::ostream* os) const { void ExplainMatchResultTo(GTEST_REFERENCE_TO_CONST_(T) x,
::std::ostream* os) const {
StreamMatchResultListener listener(os); StreamMatchResultListener listener(os);
MatchAndExplain(x, &listener); MatchAndExplain(x, &listener);
} }
...@@ -287,9 +319,18 @@ class MatcherBase { ...@@ -287,9 +319,18 @@ class MatcherBase {
MatcherBase() {} MatcherBase() {}
// Constructs a matcher from its implementation. // Constructs a matcher from its implementation.
explicit MatcherBase(const MatcherInterface<T>* impl) explicit MatcherBase(
const MatcherInterface<GTEST_REFERENCE_TO_CONST_(T)>* impl)
: impl_(impl) {} : impl_(impl) {}
template <typename U>
explicit MatcherBase(
const MatcherInterface<U>* impl,
typename internal::EnableIf<
!internal::IsSame<U, GTEST_REFERENCE_TO_CONST_(U)>::value>::type* =
NULL)
: impl_(new internal::MatcherInterfaceAdapter<U>(impl)) {}
virtual ~MatcherBase() {} virtual ~MatcherBase() {}
private: private:
...@@ -304,7 +345,9 @@ class MatcherBase { ...@@ -304,7 +345,9 @@ class MatcherBase {
// //
// If performance becomes a problem, we should see if using // If performance becomes a problem, we should see if using
// shared_ptr helps. // shared_ptr helps.
::testing::internal::linked_ptr<const MatcherInterface<T> > impl_; ::testing::internal::linked_ptr<
const MatcherInterface<GTEST_REFERENCE_TO_CONST_(T)> >
impl_;
}; };
} // namespace internal } // namespace internal
...@@ -323,7 +366,13 @@ class Matcher : public internal::MatcherBase<T> { ...@@ -323,7 +366,13 @@ class Matcher : public internal::MatcherBase<T> {
explicit Matcher() {} // NOLINT explicit Matcher() {} // NOLINT
// Constructs a matcher from its implementation. // Constructs a matcher from its implementation.
explicit Matcher(const MatcherInterface<T>* impl) explicit Matcher(const MatcherInterface<GTEST_REFERENCE_TO_CONST_(T)>* impl)
: internal::MatcherBase<T>(impl) {}
template <typename U>
explicit Matcher(const MatcherInterface<U>* impl,
typename internal::EnableIf<!internal::IsSame<
U, GTEST_REFERENCE_TO_CONST_(U)>::value>::type* = NULL)
: internal::MatcherBase<T>(impl) {} : internal::MatcherBase<T>(impl) {}
// Implicit constructor here allows people to write // Implicit constructor here allows people to write
...@@ -332,86 +381,170 @@ class Matcher : public internal::MatcherBase<T> { ...@@ -332,86 +381,170 @@ class Matcher : public internal::MatcherBase<T> {
}; };
// The following two specializations allow the user to write str // The following two specializations allow the user to write str
// instead of Eq(str) and "foo" instead of Eq("foo") when a string // instead of Eq(str) and "foo" instead of Eq("foo") when a std::string
// matcher is expected. // matcher is expected.
template <> template <>
class GTEST_API_ Matcher<const internal::string&> class GTEST_API_ Matcher<const std::string&>
: public internal::MatcherBase<const internal::string&> { : public internal::MatcherBase<const std::string&> {
public: public:
Matcher() {} Matcher() {}
explicit Matcher(const MatcherInterface<const internal::string&>* impl) explicit Matcher(const MatcherInterface<const std::string&>* impl)
: internal::MatcherBase<const internal::string&>(impl) {} : internal::MatcherBase<const std::string&>(impl) {}
// Allows the user to write str instead of Eq(str) sometimes, where // Allows the user to write str instead of Eq(str) sometimes, where
// str is a string object. // str is a std::string object.
Matcher(const internal::string& s); // NOLINT Matcher(const std::string& s); // NOLINT
#if GTEST_HAS_GLOBAL_STRING
// Allows the user to write str instead of Eq(str) sometimes, where
// str is a ::string object.
Matcher(const ::string& s); // NOLINT
#endif // GTEST_HAS_GLOBAL_STRING
// Allows the user to write "foo" instead of Eq("foo") sometimes. // Allows the user to write "foo" instead of Eq("foo") sometimes.
Matcher(const char* s); // NOLINT Matcher(const char* s); // NOLINT
}; };
template <> template <>
class GTEST_API_ Matcher<internal::string> class GTEST_API_ Matcher<std::string>
: public internal::MatcherBase<internal::string> { : public internal::MatcherBase<std::string> {
public: public:
Matcher() {} Matcher() {}
explicit Matcher(const MatcherInterface<internal::string>* impl) explicit Matcher(const MatcherInterface<const std::string&>* impl)
: internal::MatcherBase<internal::string>(impl) {} : internal::MatcherBase<std::string>(impl) {}
explicit Matcher(const MatcherInterface<std::string>* impl)
: internal::MatcherBase<std::string>(impl) {}
// Allows the user to write str instead of Eq(str) sometimes, where // Allows the user to write str instead of Eq(str) sometimes, where
// str is a string object. // str is a string object.
Matcher(const internal::string& s); // NOLINT Matcher(const std::string& s); // NOLINT
#if GTEST_HAS_GLOBAL_STRING
// Allows the user to write str instead of Eq(str) sometimes, where
// str is a ::string object.
Matcher(const ::string& s); // NOLINT
#endif // GTEST_HAS_GLOBAL_STRING
// Allows the user to write "foo" instead of Eq("foo") sometimes. // Allows the user to write "foo" instead of Eq("foo") sometimes.
Matcher(const char* s); // NOLINT Matcher(const char* s); // NOLINT
}; };
#if GTEST_HAS_STRING_PIECE_ #if GTEST_HAS_GLOBAL_STRING
// The following two specializations allow the user to write str // The following two specializations allow the user to write str
// instead of Eq(str) and "foo" instead of Eq("foo") when a StringPiece // instead of Eq(str) and "foo" instead of Eq("foo") when a ::string
// matcher is expected. // matcher is expected.
template <> template <>
class GTEST_API_ Matcher<const StringPiece&> class GTEST_API_ Matcher<const ::string&>
: public internal::MatcherBase<const StringPiece&> { : public internal::MatcherBase<const ::string&> {
public: public:
Matcher() {} Matcher() {}
explicit Matcher(const MatcherInterface<const StringPiece&>* impl) explicit Matcher(const MatcherInterface<const ::string&>* impl)
: internal::MatcherBase<const StringPiece&>(impl) {} : internal::MatcherBase<const ::string&>(impl) {}
// Allows the user to write str instead of Eq(str) sometimes, where // Allows the user to write str instead of Eq(str) sometimes, where
// str is a string object. // str is a std::string object.
Matcher(const internal::string& s); // NOLINT Matcher(const std::string& s); // NOLINT
// Allows the user to write str instead of Eq(str) sometimes, where
// str is a ::string object.
Matcher(const ::string& s); // NOLINT
// Allows the user to write "foo" instead of Eq("foo") sometimes. // Allows the user to write "foo" instead of Eq("foo") sometimes.
Matcher(const char* s); // NOLINT Matcher(const char* s); // NOLINT
};
template <>
class GTEST_API_ Matcher< ::string>
: public internal::MatcherBase< ::string> {
public:
Matcher() {}
explicit Matcher(const MatcherInterface<const ::string&>* impl)
: internal::MatcherBase< ::string>(impl) {}
explicit Matcher(const MatcherInterface< ::string>* impl)
: internal::MatcherBase< ::string>(impl) {}
// Allows the user to write str instead of Eq(str) sometimes, where
// str is a std::string object.
Matcher(const std::string& s); // NOLINT
// Allows the user to pass StringPieces directly. // Allows the user to write str instead of Eq(str) sometimes, where
Matcher(StringPiece s); // NOLINT // str is a ::string object.
Matcher(const ::string& s); // NOLINT
// Allows the user to write "foo" instead of Eq("foo") sometimes.
Matcher(const char* s); // NOLINT
}; };
#endif // GTEST_HAS_GLOBAL_STRING
#if GTEST_HAS_ABSL
// The following two specializations allow the user to write str
// instead of Eq(str) and "foo" instead of Eq("foo") when a absl::string_view
// matcher is expected.
template <> template <>
class GTEST_API_ Matcher<StringPiece> class GTEST_API_ Matcher<const absl::string_view&>
: public internal::MatcherBase<StringPiece> { : public internal::MatcherBase<const absl::string_view&> {
public: public:
Matcher() {} Matcher() {}
explicit Matcher(const MatcherInterface<StringPiece>* impl) explicit Matcher(const MatcherInterface<const absl::string_view&>* impl)
: internal::MatcherBase<StringPiece>(impl) {} : internal::MatcherBase<const absl::string_view&>(impl) {}
// Allows the user to write str instead of Eq(str) sometimes, where // Allows the user to write str instead of Eq(str) sometimes, where
// str is a string object. // str is a std::string object.
Matcher(const internal::string& s); // NOLINT Matcher(const std::string& s); // NOLINT
#if GTEST_HAS_GLOBAL_STRING
// Allows the user to write str instead of Eq(str) sometimes, where
// str is a ::string object.
Matcher(const ::string& s); // NOLINT
#endif // GTEST_HAS_GLOBAL_STRING
// Allows the user to write "foo" instead of Eq("foo") sometimes. // Allows the user to write "foo" instead of Eq("foo") sometimes.
Matcher(const char* s); // NOLINT Matcher(const char* s); // NOLINT
// Allows the user to pass StringPieces directly. // Allows the user to pass absl::string_views directly.
Matcher(StringPiece s); // NOLINT Matcher(absl::string_view s); // NOLINT
}; };
#endif // GTEST_HAS_STRING_PIECE_
template <>
class GTEST_API_ Matcher<absl::string_view>
: public internal::MatcherBase<absl::string_view> {
public:
Matcher() {}
explicit Matcher(const MatcherInterface<const absl::string_view&>* impl)
: internal::MatcherBase<absl::string_view>(impl) {}
explicit Matcher(const MatcherInterface<absl::string_view>* impl)
: internal::MatcherBase<absl::string_view>(impl) {}
// Allows the user to write str instead of Eq(str) sometimes, where
// str is a std::string object.
Matcher(const std::string& s); // NOLINT
#if GTEST_HAS_GLOBAL_STRING
// Allows the user to write str instead of Eq(str) sometimes, where
// str is a ::string object.
Matcher(const ::string& s); // NOLINT
#endif // GTEST_HAS_GLOBAL_STRING
// Allows the user to write "foo" instead of Eq("foo") sometimes.
Matcher(const char* s); // NOLINT
// Allows the user to pass absl::string_views directly.
Matcher(absl::string_view s); // NOLINT
};
#endif // GTEST_HAS_ABSL
// Prints a matcher in a human-readable format.
template <typename T>
std::ostream& operator<<(std::ostream& os, const Matcher<T>& matcher) {
matcher.DescribeTo(&os);
return os;
}
// The PolymorphicMatcher class template makes it easy to implement a // The PolymorphicMatcher class template makes it easy to implement a
// polymorphic matcher (i.e. a matcher that can match values of more // polymorphic matcher (i.e. a matcher that can match values of more
...@@ -440,7 +573,7 @@ class PolymorphicMatcher { ...@@ -440,7 +573,7 @@ class PolymorphicMatcher {
template <typename T> template <typename T>
operator Matcher<T>() const { operator Matcher<T>() const {
return Matcher<T>(new MonomorphicImpl<T>(impl_)); return Matcher<T>(new MonomorphicImpl<GTEST_REFERENCE_TO_CONST_(T)>(impl_));
} }
private: private:
...@@ -514,7 +647,7 @@ template <typename T, typename M> ...@@ -514,7 +647,7 @@ template <typename T, typename M>
class MatcherCastImpl { class MatcherCastImpl {
public: public:
static Matcher<T> Cast(const M& polymorphic_matcher_or_value) { static Matcher<T> Cast(const M& polymorphic_matcher_or_value) {
// M can be a polymorhic matcher, in which case we want to use // M can be a polymorphic matcher, in which case we want to use
// its conversion operator to create Matcher<T>. Or it can be a value // its conversion operator to create Matcher<T>. Or it can be a value
// that should be passed to the Matcher<T>'s constructor. // that should be passed to the Matcher<T>'s constructor.
// //
...@@ -530,21 +663,18 @@ class MatcherCastImpl { ...@@ -530,21 +663,18 @@ class MatcherCastImpl {
return CastImpl( return CastImpl(
polymorphic_matcher_or_value, polymorphic_matcher_or_value,
BooleanConstant< BooleanConstant<
internal::ImplicitlyConvertible<M, Matcher<T> >::value>()); internal::ImplicitlyConvertible<M, Matcher<T> >::value>(),
BooleanConstant<
internal::ImplicitlyConvertible<M, T>::value>());
} }
private: private:
static Matcher<T> CastImpl(const M& value, BooleanConstant<false>) { template <bool Ignore>
// M can't be implicitly converted to Matcher<T>, so M isn't a polymorphic
// matcher. It must be a value then. Use direct initialization to create
// a matcher.
return Matcher<T>(ImplicitCast_<T>(value));
}
static Matcher<T> CastImpl(const M& polymorphic_matcher_or_value, static Matcher<T> CastImpl(const M& polymorphic_matcher_or_value,
BooleanConstant<true>) { BooleanConstant<true> /* convertible_to_matcher */,
BooleanConstant<Ignore>) {
// M is implicitly convertible to Matcher<T>, which means that either // M is implicitly convertible to Matcher<T>, which means that either
// M is a polymorhpic matcher or Matcher<T> has an implicit constructor // M is a polymorphic matcher or Matcher<T> has an implicit constructor
// from M. In both cases using the implicit conversion will produce a // from M. In both cases using the implicit conversion will produce a
// matcher. // matcher.
// //
...@@ -553,6 +683,29 @@ class MatcherCastImpl { ...@@ -553,6 +683,29 @@ class MatcherCastImpl {
// (first to create T from M and then to create Matcher<T> from T). // (first to create T from M and then to create Matcher<T> from T).
return polymorphic_matcher_or_value; return polymorphic_matcher_or_value;
} }
// M can't be implicitly converted to Matcher<T>, so M isn't a polymorphic
// matcher. It's a value of a type implicitly convertible to T. Use direct
// initialization to create a matcher.
static Matcher<T> CastImpl(
const M& value, BooleanConstant<false> /* convertible_to_matcher */,
BooleanConstant<true> /* convertible_to_T */) {
return Matcher<T>(ImplicitCast_<T>(value));
}
// M can't be implicitly converted to either Matcher<T> or T. Attempt to use
// polymorphic matcher Eq(value) in this case.
//
// Note that we first attempt to perform an implicit cast on the value and
// only fall back to the polymorphic Eq() matcher afterwards because the
// latter calls bool operator==(const Lhs& lhs, const Rhs& rhs) in the end
// which might be undefined even when Rhs is implicitly convertible to Lhs
// (e.g. std::pair<const int, int> vs. std::pair<int, int>).
//
// We don't define this method inline as we need the declaration of Eq().
static Matcher<T> CastImpl(
const M& value, BooleanConstant<false> /* convertible_to_matcher */,
BooleanConstant<false> /* convertible_to_T */);
}; };
// This more specialized version is used when MatcherCast()'s argument // This more specialized version is used when MatcherCast()'s argument
...@@ -573,6 +726,22 @@ class MatcherCastImpl<T, Matcher<U> > { ...@@ -573,6 +726,22 @@ class MatcherCastImpl<T, Matcher<U> > {
// We delegate the matching logic to the source matcher. // We delegate the matching logic to the source matcher.
virtual bool MatchAndExplain(T x, MatchResultListener* listener) const { virtual bool MatchAndExplain(T x, MatchResultListener* listener) const {
#if GTEST_LANG_CXX11
using FromType = typename std::remove_cv<typename std::remove_pointer<
typename std::remove_reference<T>::type>::type>::type;
using ToType = typename std::remove_cv<typename std::remove_pointer<
typename std::remove_reference<U>::type>::type>::type;
// Do not allow implicitly converting base*/& to derived*/&.
static_assert(
// Do not trigger if only one of them is a pointer. That implies a
// regular conversion and not a down_cast.
(std::is_pointer<typename std::remove_reference<T>::type>::value !=
std::is_pointer<typename std::remove_reference<U>::type>::value) ||
std::is_same<FromType, ToType>::value ||
!std::is_base_of<FromType, ToType>::value,
"Can't implicitly convert from <base> to <derived>");
#endif // GTEST_LANG_CXX11
return source_matcher_.MatchAndExplain(static_cast<U>(x), listener); return source_matcher_.MatchAndExplain(static_cast<U>(x), listener);
} }
...@@ -750,10 +919,10 @@ class TuplePrefix { ...@@ -750,10 +919,10 @@ class TuplePrefix {
typename tuple_element<N - 1, MatcherTuple>::type matcher = typename tuple_element<N - 1, MatcherTuple>::type matcher =
get<N - 1>(matchers); get<N - 1>(matchers);
typedef typename tuple_element<N - 1, ValueTuple>::type Value; typedef typename tuple_element<N - 1, ValueTuple>::type Value;
Value value = get<N - 1>(values); GTEST_REFERENCE_TO_CONST_(Value) value = get<N - 1>(values);
StringMatchResultListener listener; StringMatchResultListener listener;
if (!matcher.MatchAndExplain(value, &listener)) { if (!matcher.MatchAndExplain(value, &listener)) {
// TODO(wan): include in the message the name of the parameter // FIXME: include in the message the name of the parameter
// as used in MOCK_METHOD*() when possible. // as used in MOCK_METHOD*() when possible.
*os << " Expected arg #" << N - 1 << ": "; *os << " Expected arg #" << N - 1 << ": ";
get<N - 1>(matchers).DescribeTo(os); get<N - 1>(matchers).DescribeTo(os);
...@@ -855,10 +1024,12 @@ OutIter TransformTupleValues(Func f, const Tuple& t, OutIter out) { ...@@ -855,10 +1024,12 @@ OutIter TransformTupleValues(Func f, const Tuple& t, OutIter out) {
// Implements A<T>(). // Implements A<T>().
template <typename T> template <typename T>
class AnyMatcherImpl : public MatcherInterface<T> { class AnyMatcherImpl : public MatcherInterface<GTEST_REFERENCE_TO_CONST_(T)> {
public: public:
virtual bool MatchAndExplain( virtual bool MatchAndExplain(GTEST_REFERENCE_TO_CONST_(T) /* x */,
T /* x */, MatchResultListener* /* listener */) const { return true; } MatchResultListener* /* listener */) const {
return true;
}
virtual void DescribeTo(::std::ostream* os) const { *os << "is anything"; } virtual void DescribeTo(::std::ostream* os) const { *os << "is anything"; }
virtual void DescribeNegationTo(::std::ostream* os) const { virtual void DescribeNegationTo(::std::ostream* os) const {
// This is mostly for completeness' safe, as it's not very useful // This is mostly for completeness' safe, as it's not very useful
...@@ -1128,6 +1299,19 @@ class StrEqualityMatcher { ...@@ -1128,6 +1299,19 @@ class StrEqualityMatcher {
bool case_sensitive) bool case_sensitive)
: string_(str), expect_eq_(expect_eq), case_sensitive_(case_sensitive) {} : string_(str), expect_eq_(expect_eq), case_sensitive_(case_sensitive) {}
#if GTEST_HAS_ABSL
bool MatchAndExplain(const absl::string_view& s,
MatchResultListener* listener) const {
if (s.data() == NULL) {
return !expect_eq_;
}
// This should fail to compile if absl::string_view is used with wide
// strings.
const StringType& str = string(s);
return MatchAndExplain(str, listener);
}
#endif // GTEST_HAS_ABSL
// Accepts pointer types, particularly: // Accepts pointer types, particularly:
// const char* // const char*
// char* // char*
...@@ -1144,7 +1328,7 @@ class StrEqualityMatcher { ...@@ -1144,7 +1328,7 @@ class StrEqualityMatcher {
// Matches anything that can convert to StringType. // Matches anything that can convert to StringType.
// //
// This is a template, not just a plain function with const StringType&, // This is a template, not just a plain function with const StringType&,
// because StringPiece has some interfering non-explicit constructors. // because absl::string_view has some interfering non-explicit constructors.
template <typename MatcheeStringType> template <typename MatcheeStringType>
bool MatchAndExplain(const MatcheeStringType& s, bool MatchAndExplain(const MatcheeStringType& s,
MatchResultListener* /* listener */) const { MatchResultListener* /* listener */) const {
...@@ -1188,6 +1372,19 @@ class HasSubstrMatcher { ...@@ -1188,6 +1372,19 @@ class HasSubstrMatcher {
explicit HasSubstrMatcher(const StringType& substring) explicit HasSubstrMatcher(const StringType& substring)
: substring_(substring) {} : substring_(substring) {}
#if GTEST_HAS_ABSL
bool MatchAndExplain(const absl::string_view& s,
MatchResultListener* listener) const {
if (s.data() == NULL) {
return false;
}
// This should fail to compile if absl::string_view is used with wide
// strings.
const StringType& str = string(s);
return MatchAndExplain(str, listener);
}
#endif // GTEST_HAS_ABSL
// Accepts pointer types, particularly: // Accepts pointer types, particularly:
// const char* // const char*
// char* // char*
...@@ -1201,7 +1398,7 @@ class HasSubstrMatcher { ...@@ -1201,7 +1398,7 @@ class HasSubstrMatcher {
// Matches anything that can convert to StringType. // Matches anything that can convert to StringType.
// //
// This is a template, not just a plain function with const StringType&, // This is a template, not just a plain function with const StringType&,
// because StringPiece has some interfering non-explicit constructors. // because absl::string_view has some interfering non-explicit constructors.
template <typename MatcheeStringType> template <typename MatcheeStringType>
bool MatchAndExplain(const MatcheeStringType& s, bool MatchAndExplain(const MatcheeStringType& s,
MatchResultListener* /* listener */) const { MatchResultListener* /* listener */) const {
...@@ -1235,6 +1432,19 @@ class StartsWithMatcher { ...@@ -1235,6 +1432,19 @@ class StartsWithMatcher {
explicit StartsWithMatcher(const StringType& prefix) : prefix_(prefix) { explicit StartsWithMatcher(const StringType& prefix) : prefix_(prefix) {
} }
#if GTEST_HAS_ABSL
bool MatchAndExplain(const absl::string_view& s,
MatchResultListener* listener) const {
if (s.data() == NULL) {
return false;
}
// This should fail to compile if absl::string_view is used with wide
// strings.
const StringType& str = string(s);
return MatchAndExplain(str, listener);
}
#endif // GTEST_HAS_ABSL
// Accepts pointer types, particularly: // Accepts pointer types, particularly:
// const char* // const char*
// char* // char*
...@@ -1248,7 +1458,7 @@ class StartsWithMatcher { ...@@ -1248,7 +1458,7 @@ class StartsWithMatcher {
// Matches anything that can convert to StringType. // Matches anything that can convert to StringType.
// //
// This is a template, not just a plain function with const StringType&, // This is a template, not just a plain function with const StringType&,
// because StringPiece has some interfering non-explicit constructors. // because absl::string_view has some interfering non-explicit constructors.
template <typename MatcheeStringType> template <typename MatcheeStringType>
bool MatchAndExplain(const MatcheeStringType& s, bool MatchAndExplain(const MatcheeStringType& s,
MatchResultListener* /* listener */) const { MatchResultListener* /* listener */) const {
...@@ -1281,6 +1491,19 @@ class EndsWithMatcher { ...@@ -1281,6 +1491,19 @@ class EndsWithMatcher {
public: public:
explicit EndsWithMatcher(const StringType& suffix) : suffix_(suffix) {} explicit EndsWithMatcher(const StringType& suffix) : suffix_(suffix) {}
#if GTEST_HAS_ABSL
bool MatchAndExplain(const absl::string_view& s,
MatchResultListener* listener) const {
if (s.data() == NULL) {
return false;
}
// This should fail to compile if absl::string_view is used with wide
// strings.
const StringType& str = string(s);
return MatchAndExplain(str, listener);
}
#endif // GTEST_HAS_ABSL
// Accepts pointer types, particularly: // Accepts pointer types, particularly:
// const char* // const char*
// char* // char*
...@@ -1294,7 +1517,7 @@ class EndsWithMatcher { ...@@ -1294,7 +1517,7 @@ class EndsWithMatcher {
// Matches anything that can convert to StringType. // Matches anything that can convert to StringType.
// //
// This is a template, not just a plain function with const StringType&, // This is a template, not just a plain function with const StringType&,
// because StringPiece has some interfering non-explicit constructors. // because absl::string_view has some interfering non-explicit constructors.
template <typename MatcheeStringType> template <typename MatcheeStringType>
bool MatchAndExplain(const MatcheeStringType& s, bool MatchAndExplain(const MatcheeStringType& s,
MatchResultListener* /* listener */) const { MatchResultListener* /* listener */) const {
...@@ -1327,6 +1550,13 @@ class MatchesRegexMatcher { ...@@ -1327,6 +1550,13 @@ class MatchesRegexMatcher {
MatchesRegexMatcher(const RE* regex, bool full_match) MatchesRegexMatcher(const RE* regex, bool full_match)
: regex_(regex), full_match_(full_match) {} : regex_(regex), full_match_(full_match) {}
#if GTEST_HAS_ABSL
bool MatchAndExplain(const absl::string_view& s,
MatchResultListener* listener) const {
return s.data() && MatchAndExplain(string(s), listener);
}
#endif // GTEST_HAS_ABSL
// Accepts pointer types, particularly: // Accepts pointer types, particularly:
// const char* // const char*
// char* // char*
...@@ -1340,7 +1570,7 @@ class MatchesRegexMatcher { ...@@ -1340,7 +1570,7 @@ class MatchesRegexMatcher {
// Matches anything that can convert to std::string. // Matches anything that can convert to std::string.
// //
// This is a template, not just a plain function with const std::string&, // This is a template, not just a plain function with const std::string&,
// because StringPiece has some interfering non-explicit constructors. // because absl::string_view has some interfering non-explicit constructors.
template <class MatcheeStringType> template <class MatcheeStringType>
bool MatchAndExplain(const MatcheeStringType& s, bool MatchAndExplain(const MatcheeStringType& s,
MatchResultListener* /* listener */) const { MatchResultListener* /* listener */) const {
...@@ -1440,12 +1670,13 @@ class Ge2Matcher : public PairMatchBase<Ge2Matcher, AnyGe> { ...@@ -1440,12 +1670,13 @@ class Ge2Matcher : public PairMatchBase<Ge2Matcher, AnyGe> {
// will prevent different instantiations of NotMatcher from sharing // will prevent different instantiations of NotMatcher from sharing
// the same NotMatcherImpl<T> class. // the same NotMatcherImpl<T> class.
template <typename T> template <typename T>
class NotMatcherImpl : public MatcherInterface<T> { class NotMatcherImpl : public MatcherInterface<GTEST_REFERENCE_TO_CONST_(T)> {
public: public:
explicit NotMatcherImpl(const Matcher<T>& matcher) explicit NotMatcherImpl(const Matcher<T>& matcher)
: matcher_(matcher) {} : matcher_(matcher) {}
virtual bool MatchAndExplain(T x, MatchResultListener* listener) const { virtual bool MatchAndExplain(GTEST_REFERENCE_TO_CONST_(T) x,
MatchResultListener* listener) const {
return !matcher_.MatchAndExplain(x, listener); return !matcher_.MatchAndExplain(x, listener);
} }
...@@ -1488,117 +1719,66 @@ class NotMatcher { ...@@ -1488,117 +1719,66 @@ class NotMatcher {
// that will prevent different instantiations of BothOfMatcher from // that will prevent different instantiations of BothOfMatcher from
// sharing the same BothOfMatcherImpl<T> class. // sharing the same BothOfMatcherImpl<T> class.
template <typename T> template <typename T>
class BothOfMatcherImpl : public MatcherInterface<T> { class AllOfMatcherImpl
: public MatcherInterface<GTEST_REFERENCE_TO_CONST_(T)> {
public: public:
BothOfMatcherImpl(const Matcher<T>& matcher1, const Matcher<T>& matcher2) explicit AllOfMatcherImpl(std::vector<Matcher<T> > matchers)
: matcher1_(matcher1), matcher2_(matcher2) {} : matchers_(internal::move(matchers)) {}
virtual void DescribeTo(::std::ostream* os) const { virtual void DescribeTo(::std::ostream* os) const {
*os << "("; *os << "(";
matcher1_.DescribeTo(os); for (size_t i = 0; i < matchers_.size(); ++i) {
*os << ") and ("; if (i != 0) *os << ") and (";
matcher2_.DescribeTo(os); matchers_[i].DescribeTo(os);
}
*os << ")"; *os << ")";
} }
virtual void DescribeNegationTo(::std::ostream* os) const { virtual void DescribeNegationTo(::std::ostream* os) const {
*os << "("; *os << "(";
matcher1_.DescribeNegationTo(os); for (size_t i = 0; i < matchers_.size(); ++i) {
*os << ") or ("; if (i != 0) *os << ") or (";
matcher2_.DescribeNegationTo(os); matchers_[i].DescribeNegationTo(os);
}
*os << ")"; *os << ")";
} }
virtual bool MatchAndExplain(T x, MatchResultListener* listener) const { virtual bool MatchAndExplain(GTEST_REFERENCE_TO_CONST_(T) x,
MatchResultListener* listener) const {
// If either matcher1_ or matcher2_ doesn't match x, we only need // If either matcher1_ or matcher2_ doesn't match x, we only need
// to explain why one of them fails. // to explain why one of them fails.
StringMatchResultListener listener1; std::string all_match_result;
if (!matcher1_.MatchAndExplain(x, &listener1)) {
*listener << listener1.str();
return false;
}
StringMatchResultListener listener2; for (size_t i = 0; i < matchers_.size(); ++i) {
if (!matcher2_.MatchAndExplain(x, &listener2)) { StringMatchResultListener slistener;
*listener << listener2.str(); if (matchers_[i].MatchAndExplain(x, &slistener)) {
return false; if (all_match_result.empty()) {
all_match_result = slistener.str();
} else {
std::string result = slistener.str();
if (!result.empty()) {
all_match_result += ", and ";
all_match_result += result;
}
}
} else {
*listener << slistener.str();
return false;
}
} }
// Otherwise we need to explain why *both* of them match. // Otherwise we need to explain why *both* of them match.
const std::string s1 = listener1.str(); *listener << all_match_result;
const std::string s2 = listener2.str();
if (s1 == "") {
*listener << s2;
} else {
*listener << s1;
if (s2 != "") {
*listener << ", and " << s2;
}
}
return true; return true;
} }
private: private:
const Matcher<T> matcher1_; const std::vector<Matcher<T> > matchers_;
const Matcher<T> matcher2_;
GTEST_DISALLOW_ASSIGN_(BothOfMatcherImpl); GTEST_DISALLOW_ASSIGN_(AllOfMatcherImpl);
}; };
#if GTEST_LANG_CXX11 #if GTEST_LANG_CXX11
// MatcherList provides mechanisms for storing a variable number of matchers in
// a list structure (ListType) and creating a combining matcher from such a
// list.
// The template is defined recursively using the following template parameters:
// * kSize is the length of the MatcherList.
// * Head is the type of the first matcher of the list.
// * Tail denotes the types of the remaining matchers of the list.
template <int kSize, typename Head, typename... Tail>
struct MatcherList {
typedef MatcherList<kSize - 1, Tail...> MatcherListTail;
typedef ::std::pair<Head, typename MatcherListTail::ListType> ListType;
// BuildList stores variadic type values in a nested pair structure.
// Example:
// MatcherList<3, int, string, float>::BuildList(5, "foo", 2.0) will return
// the corresponding result of type pair<int, pair<string, float>>.
static ListType BuildList(const Head& matcher, const Tail&... tail) {
return ListType(matcher, MatcherListTail::BuildList(tail...));
}
// CreateMatcher<T> creates a Matcher<T> from a given list of matchers (built
// by BuildList()). CombiningMatcher<T> is used to combine the matchers of the
// list. CombiningMatcher<T> must implement MatcherInterface<T> and have a
// constructor taking two Matcher<T>s as input.
template <typename T, template <typename /* T */> class CombiningMatcher>
static Matcher<T> CreateMatcher(const ListType& matchers) {
return Matcher<T>(new CombiningMatcher<T>(
SafeMatcherCast<T>(matchers.first),
MatcherListTail::template CreateMatcher<T, CombiningMatcher>(
matchers.second)));
}
};
// The following defines the base case for the recursive definition of
// MatcherList.
template <typename Matcher1, typename Matcher2>
struct MatcherList<2, Matcher1, Matcher2> {
typedef ::std::pair<Matcher1, Matcher2> ListType;
static ListType BuildList(const Matcher1& matcher1,
const Matcher2& matcher2) {
return ::std::pair<Matcher1, Matcher2>(matcher1, matcher2);
}
template <typename T, template <typename /* T */> class CombiningMatcher>
static Matcher<T> CreateMatcher(const ListType& matchers) {
return Matcher<T>(new CombiningMatcher<T>(
SafeMatcherCast<T>(matchers.first),
SafeMatcherCast<T>(matchers.second)));
}
};
// VariadicMatcher is used for the variadic implementation of // VariadicMatcher is used for the variadic implementation of
// AllOf(m_1, m_2, ...) and AnyOf(m_1, m_2, ...). // AllOf(m_1, m_2, ...) and AnyOf(m_1, m_2, ...).
// CombiningMatcher<T> is used to recursively combine the provided matchers // CombiningMatcher<T> is used to recursively combine the provided matchers
...@@ -1607,27 +1787,40 @@ template <template <typename T> class CombiningMatcher, typename... Args> ...@@ -1607,27 +1787,40 @@ template <template <typename T> class CombiningMatcher, typename... Args>
class VariadicMatcher { class VariadicMatcher {
public: public:
VariadicMatcher(const Args&... matchers) // NOLINT VariadicMatcher(const Args&... matchers) // NOLINT
: matchers_(MatcherListType::BuildList(matchers...)) {} : matchers_(matchers...) {
static_assert(sizeof...(Args) > 0, "Must have at least one matcher.");
}
// This template type conversion operator allows an // This template type conversion operator allows an
// VariadicMatcher<Matcher1, Matcher2...> object to match any type that // VariadicMatcher<Matcher1, Matcher2...> object to match any type that
// all of the provided matchers (Matcher1, Matcher2, ...) can match. // all of the provided matchers (Matcher1, Matcher2, ...) can match.
template <typename T> template <typename T>
operator Matcher<T>() const { operator Matcher<T>() const {
return MatcherListType::template CreateMatcher<T, CombiningMatcher>( std::vector<Matcher<T> > values;
matchers_); CreateVariadicMatcher<T>(&values, std::integral_constant<size_t, 0>());
return Matcher<T>(new CombiningMatcher<T>(internal::move(values)));
} }
private: private:
typedef MatcherList<sizeof...(Args), Args...> MatcherListType; template <typename T, size_t I>
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>());
}
template <typename T>
void CreateVariadicMatcher(
std::vector<Matcher<T> >*,
std::integral_constant<size_t, sizeof...(Args)>) const {}
const typename MatcherListType::ListType matchers_; tuple<Args...> matchers_;
GTEST_DISALLOW_ASSIGN_(VariadicMatcher); GTEST_DISALLOW_ASSIGN_(VariadicMatcher);
}; };
template <typename... Args> template <typename... Args>
using AllOfMatcher = VariadicMatcher<BothOfMatcherImpl, Args...>; using AllOfMatcher = VariadicMatcher<AllOfMatcherImpl, Args...>;
#endif // GTEST_LANG_CXX11 #endif // GTEST_LANG_CXX11
...@@ -1644,8 +1837,10 @@ class BothOfMatcher { ...@@ -1644,8 +1837,10 @@ class BothOfMatcher {
// both Matcher1 and Matcher2 can match. // both Matcher1 and Matcher2 can match.
template <typename T> template <typename T>
operator Matcher<T>() const { operator Matcher<T>() const {
return Matcher<T>(new BothOfMatcherImpl<T>(SafeMatcherCast<T>(matcher1_), std::vector<Matcher<T> > values;
SafeMatcherCast<T>(matcher2_))); values.push_back(SafeMatcherCast<T>(matcher1_));
values.push_back(SafeMatcherCast<T>(matcher2_));
return Matcher<T>(new AllOfMatcherImpl<T>(internal::move(values)));
} }
private: private:
...@@ -1660,68 +1855,69 @@ class BothOfMatcher { ...@@ -1660,68 +1855,69 @@ class BothOfMatcher {
// that will prevent different instantiations of AnyOfMatcher from // that will prevent different instantiations of AnyOfMatcher from
// sharing the same EitherOfMatcherImpl<T> class. // sharing the same EitherOfMatcherImpl<T> class.
template <typename T> template <typename T>
class EitherOfMatcherImpl : public MatcherInterface<T> { class AnyOfMatcherImpl
: public MatcherInterface<GTEST_REFERENCE_TO_CONST_(T)> {
public: public:
EitherOfMatcherImpl(const Matcher<T>& matcher1, const Matcher<T>& matcher2) explicit AnyOfMatcherImpl(std::vector<Matcher<T> > matchers)
: matcher1_(matcher1), matcher2_(matcher2) {} : matchers_(internal::move(matchers)) {}
virtual void DescribeTo(::std::ostream* os) const { virtual void DescribeTo(::std::ostream* os) const {
*os << "("; *os << "(";
matcher1_.DescribeTo(os); for (size_t i = 0; i < matchers_.size(); ++i) {
*os << ") or ("; if (i != 0) *os << ") or (";
matcher2_.DescribeTo(os); matchers_[i].DescribeTo(os);
}
*os << ")"; *os << ")";
} }
virtual void DescribeNegationTo(::std::ostream* os) const { virtual void DescribeNegationTo(::std::ostream* os) const {
*os << "("; *os << "(";
matcher1_.DescribeNegationTo(os); for (size_t i = 0; i < matchers_.size(); ++i) {
*os << ") and ("; if (i != 0) *os << ") and (";
matcher2_.DescribeNegationTo(os); matchers_[i].DescribeNegationTo(os);
}
*os << ")"; *os << ")";
} }
virtual bool MatchAndExplain(T x, MatchResultListener* listener) const { virtual bool MatchAndExplain(GTEST_REFERENCE_TO_CONST_(T) x,
MatchResultListener* listener) const {
std::string no_match_result;
// If either matcher1_ or matcher2_ matches x, we just need to // If either matcher1_ or matcher2_ matches x, we just need to
// explain why *one* of them matches. // explain why *one* of them matches.
StringMatchResultListener listener1; for (size_t i = 0; i < matchers_.size(); ++i) {
if (matcher1_.MatchAndExplain(x, &listener1)) { StringMatchResultListener slistener;
*listener << listener1.str(); if (matchers_[i].MatchAndExplain(x, &slistener)) {
return true; *listener << slistener.str();
} return true;
} else {
StringMatchResultListener listener2; if (no_match_result.empty()) {
if (matcher2_.MatchAndExplain(x, &listener2)) { no_match_result = slistener.str();
*listener << listener2.str(); } else {
return true; std::string result = slistener.str();
if (!result.empty()) {
no_match_result += ", and ";
no_match_result += result;
}
}
}
} }
// Otherwise we need to explain why *both* of them fail. // Otherwise we need to explain why *both* of them fail.
const std::string s1 = listener1.str(); *listener << no_match_result;
const std::string s2 = listener2.str();
if (s1 == "") {
*listener << s2;
} else {
*listener << s1;
if (s2 != "") {
*listener << ", and " << s2;
}
}
return false; return false;
} }
private: private:
const Matcher<T> matcher1_; const std::vector<Matcher<T> > matchers_;
const Matcher<T> matcher2_;
GTEST_DISALLOW_ASSIGN_(EitherOfMatcherImpl); GTEST_DISALLOW_ASSIGN_(AnyOfMatcherImpl);
}; };
#if GTEST_LANG_CXX11 #if GTEST_LANG_CXX11
// AnyOfMatcher is used for the variadic implementation of AnyOf(m_1, m_2, ...). // AnyOfMatcher is used for the variadic implementation of AnyOf(m_1, m_2, ...).
template <typename... Args> template <typename... Args>
using AnyOfMatcher = VariadicMatcher<EitherOfMatcherImpl, Args...>; using AnyOfMatcher = VariadicMatcher<AnyOfMatcherImpl, Args...>;
#endif // GTEST_LANG_CXX11 #endif // GTEST_LANG_CXX11
...@@ -1739,8 +1935,10 @@ class EitherOfMatcher { ...@@ -1739,8 +1935,10 @@ class EitherOfMatcher {
// both Matcher1 and Matcher2 can match. // both Matcher1 and Matcher2 can match.
template <typename T> template <typename T>
operator Matcher<T>() const { operator Matcher<T>() const {
return Matcher<T>(new EitherOfMatcherImpl<T>( std::vector<Matcher<T> > values;
SafeMatcherCast<T>(matcher1_), SafeMatcherCast<T>(matcher2_))); values.push_back(SafeMatcherCast<T>(matcher1_));
values.push_back(SafeMatcherCast<T>(matcher2_));
return Matcher<T>(new AnyOfMatcherImpl<T>(internal::move(values)));
} }
private: private:
...@@ -2036,6 +2234,82 @@ class FloatingEqMatcher { ...@@ -2036,6 +2234,82 @@ class FloatingEqMatcher {
GTEST_DISALLOW_ASSIGN_(FloatingEqMatcher); GTEST_DISALLOW_ASSIGN_(FloatingEqMatcher);
}; };
// A 2-tuple ("binary") wrapper around FloatingEqMatcher:
// FloatingEq2Matcher() matches (x, y) by matching FloatingEqMatcher(x, false)
// against y, and FloatingEq2Matcher(e) matches FloatingEqMatcher(x, false, e)
// against y. The former implements "Eq", the latter "Near". At present, there
// is no version that compares NaNs as equal.
template <typename FloatType>
class FloatingEq2Matcher {
public:
FloatingEq2Matcher() { Init(-1, false); }
explicit FloatingEq2Matcher(bool nan_eq_nan) { Init(-1, nan_eq_nan); }
explicit FloatingEq2Matcher(FloatType max_abs_error) {
Init(max_abs_error, false);
}
FloatingEq2Matcher(FloatType max_abs_error, bool nan_eq_nan) {
Init(max_abs_error, nan_eq_nan);
}
template <typename T1, typename T2>
operator Matcher< ::testing::tuple<T1, T2> >() const {
return MakeMatcher(
new Impl< ::testing::tuple<T1, T2> >(max_abs_error_, nan_eq_nan_));
}
template <typename T1, typename T2>
operator Matcher<const ::testing::tuple<T1, T2>&>() const {
return MakeMatcher(
new Impl<const ::testing::tuple<T1, T2>&>(max_abs_error_, nan_eq_nan_));
}
private:
static ::std::ostream& GetDesc(::std::ostream& os) { // NOLINT
return os << "an almost-equal pair";
}
template <typename Tuple>
class Impl : public MatcherInterface<Tuple> {
public:
Impl(FloatType max_abs_error, bool nan_eq_nan) :
max_abs_error_(max_abs_error),
nan_eq_nan_(nan_eq_nan) {}
virtual bool MatchAndExplain(Tuple args,
MatchResultListener* listener) const {
if (max_abs_error_ == -1) {
FloatingEqMatcher<FloatType> fm(::testing::get<0>(args), nan_eq_nan_);
return static_cast<Matcher<FloatType> >(fm).MatchAndExplain(
::testing::get<1>(args), listener);
} else {
FloatingEqMatcher<FloatType> fm(::testing::get<0>(args), nan_eq_nan_,
max_abs_error_);
return static_cast<Matcher<FloatType> >(fm).MatchAndExplain(
::testing::get<1>(args), listener);
}
}
virtual void DescribeTo(::std::ostream* os) const {
*os << "are " << GetDesc;
}
virtual void DescribeNegationTo(::std::ostream* os) const {
*os << "aren't " << GetDesc;
}
private:
FloatType max_abs_error_;
const bool nan_eq_nan_;
};
void Init(FloatType max_abs_error_val, bool nan_eq_nan_val) {
max_abs_error_ = max_abs_error_val;
nan_eq_nan_ = nan_eq_nan_val;
}
FloatType max_abs_error_;
bool nan_eq_nan_;
};
// Implements the Pointee(m) matcher for matching a pointer whose // Implements the Pointee(m) matcher for matching a pointer whose
// pointee matches matcher m. The pointer can be either raw or smart. // pointee matches matcher m. The pointer can be either raw or smart.
template <typename InnerMatcher> template <typename InnerMatcher>
...@@ -2053,7 +2327,8 @@ class PointeeMatcher { ...@@ -2053,7 +2327,8 @@ class PointeeMatcher {
// enough for implementing the DescribeTo() method of Pointee(). // enough for implementing the DescribeTo() method of Pointee().
template <typename Pointer> template <typename Pointer>
operator Matcher<Pointer>() const { operator Matcher<Pointer>() const {
return MakeMatcher(new Impl<Pointer>(matcher_)); return Matcher<Pointer>(
new Impl<GTEST_REFERENCE_TO_CONST_(Pointer)>(matcher_));
} }
private: private:
...@@ -2097,6 +2372,7 @@ class PointeeMatcher { ...@@ -2097,6 +2372,7 @@ class PointeeMatcher {
GTEST_DISALLOW_ASSIGN_(PointeeMatcher); GTEST_DISALLOW_ASSIGN_(PointeeMatcher);
}; };
#if GTEST_HAS_RTTI
// Implements the WhenDynamicCastTo<T>(m) matcher that matches a pointer or // Implements the WhenDynamicCastTo<T>(m) matcher that matches a pointer or
// reference that matches inner_matcher when dynamic_cast<T> is applied. // reference that matches inner_matcher when dynamic_cast<T> is applied.
// The result of dynamic_cast<To> is forwarded to the inner matcher. // The result of dynamic_cast<To> is forwarded to the inner matcher.
...@@ -2123,11 +2399,7 @@ class WhenDynamicCastToMatcherBase { ...@@ -2123,11 +2399,7 @@ class WhenDynamicCastToMatcherBase {
const Matcher<To> matcher_; const Matcher<To> matcher_;
static std::string GetToName() { static std::string GetToName() {
#if GTEST_HAS_RTTI
return GetTypeName<To>(); return GetTypeName<To>();
#else // GTEST_HAS_RTTI
return "the target type";
#endif // GTEST_HAS_RTTI
} }
private: private:
...@@ -2148,7 +2420,7 @@ class WhenDynamicCastToMatcher : public WhenDynamicCastToMatcherBase<To> { ...@@ -2148,7 +2420,7 @@ class WhenDynamicCastToMatcher : public WhenDynamicCastToMatcherBase<To> {
template <typename From> template <typename From>
bool MatchAndExplain(From from, MatchResultListener* listener) const { bool MatchAndExplain(From from, MatchResultListener* listener) const {
// TODO(sbenza): Add more detail on failures. ie did the dyn_cast fail? // FIXME: Add more detail on failures. ie did the dyn_cast fail?
To to = dynamic_cast<To>(from); To to = dynamic_cast<To>(from);
return MatchPrintAndExplain(to, this->matcher_, listener); return MatchPrintAndExplain(to, this->matcher_, listener);
} }
...@@ -2173,6 +2445,7 @@ class WhenDynamicCastToMatcher<To&> : public WhenDynamicCastToMatcherBase<To&> { ...@@ -2173,6 +2445,7 @@ class WhenDynamicCastToMatcher<To&> : public WhenDynamicCastToMatcherBase<To&> {
return MatchPrintAndExplain(*to, this->matcher_, listener); return MatchPrintAndExplain(*to, this->matcher_, listener);
} }
}; };
#endif // GTEST_HAS_RTTI
// Implements the Field() matcher for matching a field (i.e. member // Implements the Field() matcher for matching a field (i.e. member
// variable) of an object. // variable) of an object.
...@@ -2181,15 +2454,21 @@ class FieldMatcher { ...@@ -2181,15 +2454,21 @@ class FieldMatcher {
public: public:
FieldMatcher(FieldType Class::*field, FieldMatcher(FieldType Class::*field,
const Matcher<const FieldType&>& matcher) const Matcher<const FieldType&>& matcher)
: field_(field), matcher_(matcher) {} : field_(field), matcher_(matcher), whose_field_("whose given field ") {}
FieldMatcher(const std::string& field_name, FieldType Class::*field,
const Matcher<const FieldType&>& matcher)
: field_(field),
matcher_(matcher),
whose_field_("whose field `" + field_name + "` ") {}
void DescribeTo(::std::ostream* os) const { void DescribeTo(::std::ostream* os) const {
*os << "is an object whose given field "; *os << "is an object " << whose_field_;
matcher_.DescribeTo(os); matcher_.DescribeTo(os);
} }
void DescribeNegationTo(::std::ostream* os) const { void DescribeNegationTo(::std::ostream* os) const {
*os << "is an object whose given field "; *os << "is an object " << whose_field_;
matcher_.DescribeNegationTo(os); matcher_.DescribeNegationTo(os);
} }
...@@ -2207,7 +2486,7 @@ class FieldMatcher { ...@@ -2207,7 +2486,7 @@ class FieldMatcher {
// true_type iff the Field() matcher is used to match a pointer. // true_type iff the Field() matcher is used to match a pointer.
bool MatchAndExplainImpl(false_type /* is_not_pointer */, const Class& obj, bool MatchAndExplainImpl(false_type /* is_not_pointer */, const Class& obj,
MatchResultListener* listener) const { MatchResultListener* listener) const {
*listener << "whose given field is "; *listener << whose_field_ << "is ";
return MatchPrintAndExplain(obj.*field_, matcher_, listener); return MatchPrintAndExplain(obj.*field_, matcher_, listener);
} }
...@@ -2226,6 +2505,10 @@ class FieldMatcher { ...@@ -2226,6 +2505,10 @@ class FieldMatcher {
const FieldType Class::*field_; const FieldType Class::*field_;
const Matcher<const FieldType&> matcher_; const Matcher<const FieldType&> matcher_;
// Contains either "whose given field " if the name of the field is unknown
// or "whose field `name_of_field` " if the name is known.
const std::string whose_field_;
GTEST_DISALLOW_ASSIGN_(FieldMatcher); GTEST_DISALLOW_ASSIGN_(FieldMatcher);
}; };
...@@ -2244,15 +2527,23 @@ class PropertyMatcher { ...@@ -2244,15 +2527,23 @@ class PropertyMatcher {
typedef GTEST_REFERENCE_TO_CONST_(PropertyType) RefToConstProperty; typedef GTEST_REFERENCE_TO_CONST_(PropertyType) RefToConstProperty;
PropertyMatcher(Property property, const Matcher<RefToConstProperty>& matcher) PropertyMatcher(Property property, const Matcher<RefToConstProperty>& matcher)
: property_(property), matcher_(matcher) {} : property_(property),
matcher_(matcher),
whose_property_("whose given property ") {}
PropertyMatcher(const std::string& property_name, Property property,
const Matcher<RefToConstProperty>& matcher)
: property_(property),
matcher_(matcher),
whose_property_("whose property `" + property_name + "` ") {}
void DescribeTo(::std::ostream* os) const { void DescribeTo(::std::ostream* os) const {
*os << "is an object whose given property "; *os << "is an object " << whose_property_;
matcher_.DescribeTo(os); matcher_.DescribeTo(os);
} }
void DescribeNegationTo(::std::ostream* os) const { void DescribeNegationTo(::std::ostream* os) const {
*os << "is an object whose given property "; *os << "is an object " << whose_property_;
matcher_.DescribeNegationTo(os); matcher_.DescribeNegationTo(os);
} }
...@@ -2270,7 +2561,7 @@ class PropertyMatcher { ...@@ -2270,7 +2561,7 @@ class PropertyMatcher {
// true_type iff the Property() matcher is used to match a pointer. // true_type iff the Property() matcher is used to match a pointer.
bool MatchAndExplainImpl(false_type /* is_not_pointer */, const Class& obj, bool MatchAndExplainImpl(false_type /* is_not_pointer */, const Class& obj,
MatchResultListener* listener) const { MatchResultListener* listener) const {
*listener << "whose given property is "; *listener << whose_property_ << "is ";
// Cannot pass the return value (for example, int) to MatchPrintAndExplain, // Cannot pass the return value (for example, int) to MatchPrintAndExplain,
// which takes a non-const reference as argument. // which takes a non-const reference as argument.
#if defined(_PREFAST_ ) && _MSC_VER == 1800 #if defined(_PREFAST_ ) && _MSC_VER == 1800
...@@ -2299,6 +2590,10 @@ class PropertyMatcher { ...@@ -2299,6 +2590,10 @@ class PropertyMatcher {
Property property_; Property property_;
const Matcher<RefToConstProperty> matcher_; const Matcher<RefToConstProperty> matcher_;
// Contains either "whose given property " if the name of the property is
// unknown or "whose property `name_of_property` " if the name is known.
const std::string whose_property_;
GTEST_DISALLOW_ASSIGN_(PropertyMatcher); GTEST_DISALLOW_ASSIGN_(PropertyMatcher);
}; };
...@@ -2692,6 +2987,10 @@ class WhenSortedByMatcher { ...@@ -2692,6 +2987,10 @@ class WhenSortedByMatcher {
// container and the RHS container respectively. // container and the RHS container respectively.
template <typename TupleMatcher, typename RhsContainer> template <typename TupleMatcher, typename RhsContainer>
class PointwiseMatcher { class PointwiseMatcher {
GTEST_COMPILE_ASSERT_(
!IsHashTable<GTEST_REMOVE_REFERENCE_AND_CONST_(RhsContainer)>::value,
use_UnorderedPointwise_with_hash_tables);
public: public:
typedef internal::StlContainerView<RhsContainer> RhsView; typedef internal::StlContainerView<RhsContainer> RhsView;
typedef typename RhsView::type RhsStlContainer; typedef typename RhsView::type RhsStlContainer;
...@@ -2709,6 +3008,10 @@ class PointwiseMatcher { ...@@ -2709,6 +3008,10 @@ class PointwiseMatcher {
template <typename LhsContainer> template <typename LhsContainer>
operator Matcher<LhsContainer>() const { operator Matcher<LhsContainer>() const {
GTEST_COMPILE_ASSERT_(
!IsHashTable<GTEST_REMOVE_REFERENCE_AND_CONST_(LhsContainer)>::value,
use_UnorderedPointwise_with_hash_tables);
return MakeMatcher(new Impl<LhsContainer>(tuple_matcher_, rhs_)); return MakeMatcher(new Impl<LhsContainer>(tuple_matcher_, rhs_));
} }
...@@ -2759,12 +3062,15 @@ class PointwiseMatcher { ...@@ -2759,12 +3062,15 @@ class PointwiseMatcher {
typename LhsStlContainer::const_iterator left = lhs_stl_container.begin(); typename LhsStlContainer::const_iterator left = lhs_stl_container.begin();
typename RhsStlContainer::const_iterator right = rhs_.begin(); typename RhsStlContainer::const_iterator right = rhs_.begin();
for (size_t i = 0; i != actual_size; ++i, ++left, ++right) { for (size_t i = 0; i != actual_size; ++i, ++left, ++right) {
const InnerMatcherArg value_pair(*left, *right);
if (listener->IsInterested()) { if (listener->IsInterested()) {
StringMatchResultListener inner_listener; StringMatchResultListener inner_listener;
// Create InnerMatcherArg as a temporarily object to avoid it outlives
// *left and *right. Dereference or the conversion to `const T&` may
// return temp objects, e.g for vector<bool>.
if (!mono_tuple_matcher_.MatchAndExplain( if (!mono_tuple_matcher_.MatchAndExplain(
value_pair, &inner_listener)) { InnerMatcherArg(ImplicitCast_<const LhsValue&>(*left),
ImplicitCast_<const RhsValue&>(*right)),
&inner_listener)) {
*listener << "where the value pair ("; *listener << "where the value pair (";
UniversalPrint(*left, listener->stream()); UniversalPrint(*left, listener->stream());
*listener << ", "; *listener << ", ";
...@@ -2774,7 +3080,9 @@ class PointwiseMatcher { ...@@ -2774,7 +3080,9 @@ class PointwiseMatcher {
return false; return false;
} }
} else { } else {
if (!mono_tuple_matcher_.Matches(value_pair)) if (!mono_tuple_matcher_.Matches(
InnerMatcherArg(ImplicitCast_<const LhsValue&>(*left),
ImplicitCast_<const RhsValue&>(*right))))
return false; return false;
} }
} }
...@@ -2932,6 +3240,50 @@ class EachMatcher { ...@@ -2932,6 +3240,50 @@ class EachMatcher {
GTEST_DISALLOW_ASSIGN_(EachMatcher); GTEST_DISALLOW_ASSIGN_(EachMatcher);
}; };
struct Rank1 {};
struct Rank0 : Rank1 {};
namespace pair_getters {
#if GTEST_LANG_CXX11
using std::get;
template <typename T>
auto First(T& x, Rank1) -> decltype(get<0>(x)) { // NOLINT
return get<0>(x);
}
template <typename T>
auto First(T& x, Rank0) -> decltype((x.first)) { // NOLINT
return x.first;
}
template <typename T>
auto Second(T& x, Rank1) -> decltype(get<1>(x)) { // NOLINT
return get<1>(x);
}
template <typename T>
auto Second(T& x, Rank0) -> decltype((x.second)) { // NOLINT
return x.second;
}
#else
template <typename T>
typename T::first_type& First(T& x, Rank0) { // NOLINT
return x.first;
}
template <typename T>
const typename T::first_type& First(const T& x, Rank0) {
return x.first;
}
template <typename T>
typename T::second_type& Second(T& x, Rank0) { // NOLINT
return x.second;
}
template <typename T>
const typename T::second_type& Second(const T& x, Rank0) {
return x.second;
}
#endif // GTEST_LANG_CXX11
} // namespace pair_getters
// Implements Key(inner_matcher) for the given argument pair type. // Implements Key(inner_matcher) for the given argument pair type.
// Key(inner_matcher) matches an std::pair whose 'first' field matches // Key(inner_matcher) matches an std::pair whose 'first' field matches
// inner_matcher. For example, Contains(Key(Ge(5))) can be used to match an // inner_matcher. For example, Contains(Key(Ge(5))) can be used to match an
...@@ -2952,8 +3304,8 @@ class KeyMatcherImpl : public MatcherInterface<PairType> { ...@@ -2952,8 +3304,8 @@ class KeyMatcherImpl : public MatcherInterface<PairType> {
virtual bool MatchAndExplain(PairType key_value, virtual bool MatchAndExplain(PairType key_value,
MatchResultListener* listener) const { MatchResultListener* listener) const {
StringMatchResultListener inner_listener; StringMatchResultListener inner_listener;
const bool match = inner_matcher_.MatchAndExplain(key_value.first, const bool match = inner_matcher_.MatchAndExplain(
&inner_listener); pair_getters::First(key_value, Rank0()), &inner_listener);
const std::string explanation = inner_listener.str(); const std::string explanation = inner_listener.str();
if (explanation != "") { if (explanation != "") {
*listener << "whose first field is a value " << explanation; *listener << "whose first field is a value " << explanation;
...@@ -3036,18 +3388,18 @@ class PairMatcherImpl : public MatcherInterface<PairType> { ...@@ -3036,18 +3388,18 @@ class PairMatcherImpl : public MatcherInterface<PairType> {
if (!listener->IsInterested()) { if (!listener->IsInterested()) {
// If the listener is not interested, we don't need to construct the // If the listener is not interested, we don't need to construct the
// explanation. // explanation.
return first_matcher_.Matches(a_pair.first) && return first_matcher_.Matches(pair_getters::First(a_pair, Rank0())) &&
second_matcher_.Matches(a_pair.second); second_matcher_.Matches(pair_getters::Second(a_pair, Rank0()));
} }
StringMatchResultListener first_inner_listener; StringMatchResultListener first_inner_listener;
if (!first_matcher_.MatchAndExplain(a_pair.first, if (!first_matcher_.MatchAndExplain(pair_getters::First(a_pair, Rank0()),
&first_inner_listener)) { &first_inner_listener)) {
*listener << "whose first field does not match"; *listener << "whose first field does not match";
PrintIfNotEmpty(first_inner_listener.str(), listener->stream()); PrintIfNotEmpty(first_inner_listener.str(), listener->stream());
return false; return false;
} }
StringMatchResultListener second_inner_listener; StringMatchResultListener second_inner_listener;
if (!second_matcher_.MatchAndExplain(a_pair.second, if (!second_matcher_.MatchAndExplain(pair_getters::Second(a_pair, Rank0()),
&second_inner_listener)) { &second_inner_listener)) {
*listener << "whose second field does not match"; *listener << "whose second field does not match";
PrintIfNotEmpty(second_inner_listener.str(), listener->stream()); PrintIfNotEmpty(second_inner_listener.str(), listener->stream());
...@@ -3303,14 +3655,23 @@ typedef ::std::vector<ElementMatcherPair> ElementMatcherPairs; ...@@ -3303,14 +3655,23 @@ typedef ::std::vector<ElementMatcherPair> ElementMatcherPairs;
GTEST_API_ ElementMatcherPairs GTEST_API_ ElementMatcherPairs
FindMaxBipartiteMatching(const MatchMatrix& g); FindMaxBipartiteMatching(const MatchMatrix& g);
GTEST_API_ bool FindPairing(const MatchMatrix& matrix, struct UnorderedMatcherRequire {
MatchResultListener* listener); enum Flags {
Superset = 1 << 0,
Subset = 1 << 1,
ExactMatch = Superset | Subset,
};
};
// Untyped base class for implementing UnorderedElementsAre. By // Untyped base class for implementing UnorderedElementsAre. By
// putting logic that's not specific to the element type here, we // putting logic that's not specific to the element type here, we
// reduce binary bloat and increase compilation speed. // reduce binary bloat and increase compilation speed.
class GTEST_API_ UnorderedElementsAreMatcherImplBase { class GTEST_API_ UnorderedElementsAreMatcherImplBase {
protected: protected:
explicit UnorderedElementsAreMatcherImplBase(
UnorderedMatcherRequire::Flags matcher_flags)
: match_flags_(matcher_flags) {}
// A vector of matcher describers, one for each element matcher. // A vector of matcher describers, one for each element matcher.
// Does not own the describers (and thus can be used only when the // Does not own the describers (and thus can be used only when the
// element matchers are alive). // element matchers are alive).
...@@ -3322,9 +3683,12 @@ class GTEST_API_ UnorderedElementsAreMatcherImplBase { ...@@ -3322,9 +3683,12 @@ class GTEST_API_ UnorderedElementsAreMatcherImplBase {
// Describes the negation of this UnorderedElementsAre matcher. // Describes the negation of this UnorderedElementsAre matcher.
void DescribeNegationToImpl(::std::ostream* os) const; void DescribeNegationToImpl(::std::ostream* os) const;
bool VerifyAllElementsAndMatchersAreMatched( bool VerifyMatchMatrix(const ::std::vector<std::string>& element_printouts,
const ::std::vector<std::string>& element_printouts, const MatchMatrix& matrix,
const MatchMatrix& matrix, MatchResultListener* listener) const; MatchResultListener* listener) const;
bool FindPairing(const MatchMatrix& matrix,
MatchResultListener* listener) const;
MatcherDescriberVec& matcher_describers() { MatcherDescriberVec& matcher_describers() {
return matcher_describers_; return matcher_describers_;
...@@ -3334,13 +3698,17 @@ class GTEST_API_ UnorderedElementsAreMatcherImplBase { ...@@ -3334,13 +3698,17 @@ class GTEST_API_ UnorderedElementsAreMatcherImplBase {
return Message() << n << " element" << (n == 1 ? "" : "s"); return Message() << n << " element" << (n == 1 ? "" : "s");
} }
UnorderedMatcherRequire::Flags match_flags() const { return match_flags_; }
private: private:
UnorderedMatcherRequire::Flags match_flags_;
MatcherDescriberVec matcher_describers_; MatcherDescriberVec matcher_describers_;
GTEST_DISALLOW_ASSIGN_(UnorderedElementsAreMatcherImplBase); GTEST_DISALLOW_ASSIGN_(UnorderedElementsAreMatcherImplBase);
}; };
// Implements unordered ElementsAre and unordered ElementsAreArray. // Implements UnorderedElementsAre, UnorderedElementsAreArray, IsSubsetOf, and
// IsSupersetOf.
template <typename Container> template <typename Container>
class UnorderedElementsAreMatcherImpl class UnorderedElementsAreMatcherImpl
: public MatcherInterface<Container>, : public MatcherInterface<Container>,
...@@ -3353,10 +3721,10 @@ class UnorderedElementsAreMatcherImpl ...@@ -3353,10 +3721,10 @@ class UnorderedElementsAreMatcherImpl
typedef typename StlContainer::const_iterator StlContainerConstIterator; typedef typename StlContainer::const_iterator StlContainerConstIterator;
typedef typename StlContainer::value_type Element; typedef typename StlContainer::value_type Element;
// Constructs the matcher from a sequence of element values or
// element matchers.
template <typename InputIter> template <typename InputIter>
UnorderedElementsAreMatcherImpl(InputIter first, InputIter last) { UnorderedElementsAreMatcherImpl(UnorderedMatcherRequire::Flags matcher_flags,
InputIter first, InputIter last)
: UnorderedElementsAreMatcherImplBase(matcher_flags) {
for (; first != last; ++first) { for (; first != last; ++first) {
matchers_.push_back(MatcherCast<const Element&>(*first)); matchers_.push_back(MatcherCast<const Element&>(*first));
matcher_describers().push_back(matchers_.back().GetDescriber()); matcher_describers().push_back(matchers_.back().GetDescriber());
...@@ -3377,34 +3745,32 @@ class UnorderedElementsAreMatcherImpl ...@@ -3377,34 +3745,32 @@ class UnorderedElementsAreMatcherImpl
MatchResultListener* listener) const { MatchResultListener* listener) const {
StlContainerReference stl_container = View::ConstReference(container); StlContainerReference stl_container = View::ConstReference(container);
::std::vector<std::string> element_printouts; ::std::vector<std::string> element_printouts;
MatchMatrix matrix = AnalyzeElements(stl_container.begin(), MatchMatrix matrix =
stl_container.end(), AnalyzeElements(stl_container.begin(), stl_container.end(),
&element_printouts, &element_printouts, listener);
listener);
const size_t actual_count = matrix.LhsSize(); if (matrix.LhsSize() == 0 && matrix.RhsSize() == 0) {
if (actual_count == 0 && matchers_.empty()) {
return true; return true;
} }
if (actual_count != matchers_.size()) {
// The element count doesn't match. If the container is empty, if (match_flags() == UnorderedMatcherRequire::ExactMatch) {
// there's no need to explain anything as Google Mock already if (matrix.LhsSize() != matrix.RhsSize()) {
// prints the empty container. Otherwise we just need to show // The element count doesn't match. If the container is empty,
// how many elements there actually are. // there's no need to explain anything as Google Mock already
if (actual_count != 0 && listener->IsInterested()) { // prints the empty container. Otherwise we just need to show
*listener << "which has " << Elements(actual_count); // how many elements there actually are.
if (matrix.LhsSize() != 0 && listener->IsInterested()) {
*listener << "which has " << Elements(matrix.LhsSize());
}
return false;
} }
return false;
} }
return VerifyAllElementsAndMatchersAreMatched(element_printouts, return VerifyMatchMatrix(element_printouts, matrix, listener) &&
matrix, listener) &&
FindPairing(matrix, listener); FindPairing(matrix, listener);
} }
private: private:
typedef ::std::vector<Matcher<const Element&> > MatcherVec;
template <typename ElementIter> template <typename ElementIter>
MatchMatrix AnalyzeElements(ElementIter elem_first, ElementIter elem_last, MatchMatrix AnalyzeElements(ElementIter elem_first, ElementIter elem_last,
::std::vector<std::string>* element_printouts, ::std::vector<std::string>* element_printouts,
...@@ -3431,7 +3797,7 @@ class UnorderedElementsAreMatcherImpl ...@@ -3431,7 +3797,7 @@ class UnorderedElementsAreMatcherImpl
return matrix; return matrix;
} }
MatcherVec matchers_; ::std::vector<Matcher<const Element&> > matchers_;
GTEST_DISALLOW_ASSIGN_(UnorderedElementsAreMatcherImpl); GTEST_DISALLOW_ASSIGN_(UnorderedElementsAreMatcherImpl);
}; };
...@@ -3464,7 +3830,7 @@ class UnorderedElementsAreMatcher { ...@@ -3464,7 +3830,7 @@ class UnorderedElementsAreMatcher {
TransformTupleValues(CastAndAppendTransform<const Element&>(), matchers_, TransformTupleValues(CastAndAppendTransform<const Element&>(), matchers_,
::std::back_inserter(matchers)); ::std::back_inserter(matchers));
return MakeMatcher(new UnorderedElementsAreMatcherImpl<Container>( return MakeMatcher(new UnorderedElementsAreMatcherImpl<Container>(
matchers.begin(), matchers.end())); UnorderedMatcherRequire::ExactMatch, matchers.begin(), matchers.end()));
} }
private: private:
...@@ -3480,6 +3846,11 @@ class ElementsAreMatcher { ...@@ -3480,6 +3846,11 @@ class ElementsAreMatcher {
template <typename Container> template <typename Container>
operator Matcher<Container>() const { operator Matcher<Container>() const {
GTEST_COMPILE_ASSERT_(
!IsHashTable<GTEST_REMOVE_REFERENCE_AND_CONST_(Container)>::value ||
::testing::tuple_size<MatcherTuple>::value < 2,
use_UnorderedElementsAre_with_hash_tables);
typedef GTEST_REMOVE_REFERENCE_AND_CONST_(Container) RawContainer; typedef GTEST_REMOVE_REFERENCE_AND_CONST_(Container) RawContainer;
typedef typename internal::StlContainerView<RawContainer>::type View; typedef typename internal::StlContainerView<RawContainer>::type View;
typedef typename View::value_type Element; typedef typename View::value_type Element;
...@@ -3497,24 +3868,23 @@ class ElementsAreMatcher { ...@@ -3497,24 +3868,23 @@ class ElementsAreMatcher {
GTEST_DISALLOW_ASSIGN_(ElementsAreMatcher); GTEST_DISALLOW_ASSIGN_(ElementsAreMatcher);
}; };
// Implements UnorderedElementsAreArray(). // Implements UnorderedElementsAreArray(), IsSubsetOf(), and IsSupersetOf().
template <typename T> template <typename T>
class UnorderedElementsAreArrayMatcher { class UnorderedElementsAreArrayMatcher {
public: public:
UnorderedElementsAreArrayMatcher() {}
template <typename Iter> template <typename Iter>
UnorderedElementsAreArrayMatcher(Iter first, Iter last) UnorderedElementsAreArrayMatcher(UnorderedMatcherRequire::Flags match_flags,
: matchers_(first, last) {} Iter first, Iter last)
: match_flags_(match_flags), matchers_(first, last) {}
template <typename Container> template <typename Container>
operator Matcher<Container>() const { operator Matcher<Container>() const {
return MakeMatcher( return MakeMatcher(new UnorderedElementsAreMatcherImpl<Container>(
new UnorderedElementsAreMatcherImpl<Container>(matchers_.begin(), match_flags_, matchers_.begin(), matchers_.end()));
matchers_.end()));
} }
private: private:
UnorderedMatcherRequire::Flags match_flags_;
::std::vector<T> matchers_; ::std::vector<T> matchers_;
GTEST_DISALLOW_ASSIGN_(UnorderedElementsAreArrayMatcher); GTEST_DISALLOW_ASSIGN_(UnorderedElementsAreArrayMatcher);
...@@ -3529,6 +3899,10 @@ class ElementsAreArrayMatcher { ...@@ -3529,6 +3899,10 @@ class ElementsAreArrayMatcher {
template <typename Container> template <typename Container>
operator Matcher<Container>() const { operator Matcher<Container>() const {
GTEST_COMPILE_ASSERT_(
!IsHashTable<GTEST_REMOVE_REFERENCE_AND_CONST_(Container)>::value,
use_UnorderedElementsAreArray_with_hash_tables);
return MakeMatcher(new ElementsAreMatcherImpl<Container>( return MakeMatcher(new ElementsAreMatcherImpl<Container>(
matchers_.begin(), matchers_.end())); matchers_.begin(), matchers_.end()));
} }
...@@ -3614,10 +3988,6 @@ BoundSecondMatcher<Tuple2Matcher, Second> MatcherBindSecond( ...@@ -3614,10 +3988,6 @@ BoundSecondMatcher<Tuple2Matcher, Second> MatcherBindSecond(
return BoundSecondMatcher<Tuple2Matcher, Second>(tm, second); return BoundSecondMatcher<Tuple2Matcher, Second>(tm, second);
} }
// Joins a vector of strings as if they are fields of a tuple; returns
// the joined string. This function is exported for testing.
GTEST_API_ string JoinAsTuple(const Strings& fields);
// Returns the description for a matcher defined using the MATCHER*() // Returns the description for a matcher defined using the MATCHER*()
// macro where the user-supplied description string is "", if // macro where the user-supplied description string is "", if
// 'negation' is false; otherwise returns the description of the // 'negation' is false; otherwise returns the description of the
...@@ -3627,9 +3997,185 @@ GTEST_API_ std::string FormatMatcherDescription(bool negation, ...@@ -3627,9 +3997,185 @@ GTEST_API_ std::string FormatMatcherDescription(bool negation,
const char* matcher_name, const char* matcher_name,
const Strings& param_values); const Strings& param_values);
// Implements a matcher that checks the value of a optional<> type variable.
template <typename ValueMatcher>
class OptionalMatcher {
public:
explicit OptionalMatcher(const ValueMatcher& value_matcher)
: value_matcher_(value_matcher) {}
template <typename Optional>
operator Matcher<Optional>() const {
return MakeMatcher(new Impl<Optional>(value_matcher_));
}
template <typename Optional>
class Impl : public MatcherInterface<Optional> {
public:
typedef GTEST_REMOVE_REFERENCE_AND_CONST_(Optional) OptionalView;
typedef typename OptionalView::value_type ValueType;
explicit Impl(const ValueMatcher& value_matcher)
: value_matcher_(MatcherCast<ValueType>(value_matcher)) {}
virtual void DescribeTo(::std::ostream* os) const {
*os << "value ";
value_matcher_.DescribeTo(os);
}
virtual void DescribeNegationTo(::std::ostream* os) const {
*os << "value ";
value_matcher_.DescribeNegationTo(os);
}
virtual bool MatchAndExplain(Optional optional,
MatchResultListener* listener) const {
if (!optional) {
*listener << "which is not engaged";
return false;
}
const ValueType& value = *optional;
StringMatchResultListener value_listener;
const bool match = value_matcher_.MatchAndExplain(value, &value_listener);
*listener << "whose value " << PrintToString(value)
<< (match ? " matches" : " doesn't match");
PrintIfNotEmpty(value_listener.str(), listener->stream());
return match;
}
private:
const Matcher<ValueType> value_matcher_;
GTEST_DISALLOW_ASSIGN_(Impl);
};
private:
const ValueMatcher value_matcher_;
GTEST_DISALLOW_ASSIGN_(OptionalMatcher);
};
namespace variant_matcher {
// Overloads to allow VariantMatcher to do proper ADL lookup.
template <typename T>
void holds_alternative() {}
template <typename T>
void get() {}
// Implements a matcher that checks the value of a variant<> type variable.
template <typename T>
class VariantMatcher {
public:
explicit VariantMatcher(::testing::Matcher<const T&> matcher)
: matcher_(internal::move(matcher)) {}
template <typename Variant>
bool MatchAndExplain(const Variant& value,
::testing::MatchResultListener* listener) const {
if (!listener->IsInterested()) {
return holds_alternative<T>(value) && matcher_.Matches(get<T>(value));
}
if (!holds_alternative<T>(value)) {
*listener << "whose value is not of type '" << GetTypeName() << "'";
return false;
}
const T& elem = get<T>(value);
StringMatchResultListener elem_listener;
const bool match = matcher_.MatchAndExplain(elem, &elem_listener);
*listener << "whose value " << PrintToString(elem)
<< (match ? " matches" : " doesn't match");
PrintIfNotEmpty(elem_listener.str(), listener->stream());
return match;
}
void DescribeTo(std::ostream* os) const {
*os << "is a variant<> with value of type '" << GetTypeName()
<< "' and the value ";
matcher_.DescribeTo(os);
}
void DescribeNegationTo(std::ostream* os) const {
*os << "is a variant<> with value of type other than '" << GetTypeName()
<< "' or the value ";
matcher_.DescribeNegationTo(os);
}
private:
static std::string GetTypeName() {
#if GTEST_HAS_RTTI
GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(
return internal::GetTypeName<T>());
#endif
return "the element type";
}
const ::testing::Matcher<const T&> matcher_;
};
} // namespace variant_matcher
namespace any_cast_matcher {
// Overloads to allow AnyCastMatcher to do proper ADL lookup.
template <typename T>
void any_cast() {}
// Implements a matcher that any_casts the value.
template <typename T>
class AnyCastMatcher {
public:
explicit AnyCastMatcher(const ::testing::Matcher<const T&>& matcher)
: matcher_(matcher) {}
template <typename AnyType>
bool MatchAndExplain(const AnyType& value,
::testing::MatchResultListener* listener) const {
if (!listener->IsInterested()) {
const T* ptr = any_cast<T>(&value);
return ptr != NULL && matcher_.Matches(*ptr);
}
const T* elem = any_cast<T>(&value);
if (elem == NULL) {
*listener << "whose value is not of type '" << GetTypeName() << "'";
return false;
}
StringMatchResultListener elem_listener;
const bool match = matcher_.MatchAndExplain(*elem, &elem_listener);
*listener << "whose value " << PrintToString(*elem)
<< (match ? " matches" : " doesn't match");
PrintIfNotEmpty(elem_listener.str(), listener->stream());
return match;
}
void DescribeTo(std::ostream* os) const {
*os << "is an 'any' type with value of type '" << GetTypeName()
<< "' and the value ";
matcher_.DescribeTo(os);
}
void DescribeNegationTo(std::ostream* os) const {
*os << "is an 'any' type with value of type other than '" << GetTypeName()
<< "' or the value ";
matcher_.DescribeNegationTo(os);
}
private:
static std::string GetTypeName() {
#if GTEST_HAS_RTTI
GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(
return internal::GetTypeName<T>());
#endif
return "the element type";
}
const ::testing::Matcher<const T&> matcher_;
};
} // namespace any_cast_matcher
} // namespace internal } // namespace internal
// ElementsAreArray(first, last) // ElementsAreArray(iterator_first, iterator_last)
// ElementsAreArray(pointer, count) // ElementsAreArray(pointer, count)
// ElementsAreArray(array) // ElementsAreArray(array)
// ElementsAreArray(container) // ElementsAreArray(container)
...@@ -3678,20 +4224,26 @@ ElementsAreArray(::std::initializer_list<T> xs) { ...@@ -3678,20 +4224,26 @@ ElementsAreArray(::std::initializer_list<T> xs) {
} }
#endif #endif
// UnorderedElementsAreArray(first, last) // UnorderedElementsAreArray(iterator_first, iterator_last)
// UnorderedElementsAreArray(pointer, count) // UnorderedElementsAreArray(pointer, count)
// UnorderedElementsAreArray(array) // UnorderedElementsAreArray(array)
// UnorderedElementsAreArray(container) // UnorderedElementsAreArray(container)
// UnorderedElementsAreArray({ e1, e2, ..., en }) // UnorderedElementsAreArray({ e1, e2, ..., en })
// //
// The UnorderedElementsAreArray() functions are like // UnorderedElementsAreArray() verifies that a bijective mapping onto a
// ElementsAreArray(...), but allow matching the elements in any order. // collection of matchers exists.
//
// The matchers can be specified as an array, a pointer and count, a container,
// an initializer list, or an STL iterator range. In each of these cases, the
// underlying matchers can be either values or matchers.
template <typename Iter> template <typename Iter>
inline internal::UnorderedElementsAreArrayMatcher< inline internal::UnorderedElementsAreArrayMatcher<
typename ::std::iterator_traits<Iter>::value_type> typename ::std::iterator_traits<Iter>::value_type>
UnorderedElementsAreArray(Iter first, Iter last) { UnorderedElementsAreArray(Iter first, Iter last) {
typedef typename ::std::iterator_traits<Iter>::value_type T; typedef typename ::std::iterator_traits<Iter>::value_type T;
return internal::UnorderedElementsAreArrayMatcher<T>(first, last); return internal::UnorderedElementsAreArrayMatcher<T>(
internal::UnorderedMatcherRequire::ExactMatch, first, last);
} }
template <typename T> template <typename T>
...@@ -3733,7 +4285,9 @@ UnorderedElementsAreArray(::std::initializer_list<T> xs) { ...@@ -3733,7 +4285,9 @@ UnorderedElementsAreArray(::std::initializer_list<T> xs) {
const internal::AnythingMatcher _ = {}; const internal::AnythingMatcher _ = {};
// Creates a matcher that matches any value of the given type T. // Creates a matcher that matches any value of the given type T.
template <typename T> template <typename T>
inline Matcher<T> A() { return MakeMatcher(new internal::AnyMatcherImpl<T>()); } inline Matcher<T> A() {
return Matcher<T>(new internal::AnyMatcherImpl<T>());
}
// Creates a matcher that matches any value of the given type T. // Creates a matcher that matches any value of the given type T.
template <typename T> template <typename T>
...@@ -3750,6 +4304,14 @@ inline internal::EqMatcher<T> Eq(T x) { return internal::EqMatcher<T>(x); } ...@@ -3750,6 +4304,14 @@ inline internal::EqMatcher<T> Eq(T x) { return internal::EqMatcher<T>(x); }
template <typename T> template <typename T>
Matcher<T>::Matcher(T value) { *this = Eq(value); } Matcher<T>::Matcher(T value) { *this = Eq(value); }
template <typename T, typename M>
Matcher<T> internal::MatcherCastImpl<T, M>::CastImpl(
const M& value,
internal::BooleanConstant<false> /* convertible_to_matcher */,
internal::BooleanConstant<false> /* convertible_to_T */) {
return Eq(value);
}
// Creates a monomorphic matcher that matches anything with type Lhs // Creates a monomorphic matcher that matches anything with type Lhs
// and equal to rhs. A user may need to use this instead of Eq(...) // and equal to rhs. A user may need to use this instead of Eq(...)
// in order to resolve an overloading ambiguity. // in order to resolve an overloading ambiguity.
...@@ -3878,6 +4440,7 @@ inline internal::PointeeMatcher<InnerMatcher> Pointee( ...@@ -3878,6 +4440,7 @@ inline internal::PointeeMatcher<InnerMatcher> Pointee(
return internal::PointeeMatcher<InnerMatcher>(inner_matcher); return internal::PointeeMatcher<InnerMatcher>(inner_matcher);
} }
#if GTEST_HAS_RTTI
// Creates a matcher that matches a pointer or reference that matches // Creates a matcher that matches a pointer or reference that matches
// inner_matcher when dynamic_cast<To> is applied. // inner_matcher when dynamic_cast<To> is applied.
// The result of dynamic_cast<To> is forwarded to the inner matcher. // The result of dynamic_cast<To> is forwarded to the inner matcher.
...@@ -3890,6 +4453,7 @@ WhenDynamicCastTo(const Matcher<To>& inner_matcher) { ...@@ -3890,6 +4453,7 @@ WhenDynamicCastTo(const Matcher<To>& inner_matcher) {
return MakePolymorphicMatcher( return MakePolymorphicMatcher(
internal::WhenDynamicCastToMatcher<To>(inner_matcher)); internal::WhenDynamicCastToMatcher<To>(inner_matcher));
} }
#endif // GTEST_HAS_RTTI
// Creates a matcher that matches an object whose given field matches // Creates a matcher that matches an object whose given field matches
// 'matcher'. For example, // 'matcher'. For example,
...@@ -3908,6 +4472,16 @@ inline PolymorphicMatcher< ...@@ -3908,6 +4472,16 @@ inline PolymorphicMatcher<
// to compile where bar is an int32 and m is a matcher for int64. // to compile where bar is an int32 and m is a matcher for int64.
} }
// Same as Field() but also takes the name of the field to provide better error
// messages.
template <typename Class, typename FieldType, typename FieldMatcher>
inline PolymorphicMatcher<internal::FieldMatcher<Class, FieldType> > Field(
const std::string& field_name, FieldType Class::*field,
const FieldMatcher& matcher) {
return MakePolymorphicMatcher(internal::FieldMatcher<Class, FieldType>(
field_name, field, MatcherCast<const FieldType&>(matcher)));
}
// Creates a matcher that matches an object whose given property // Creates a matcher that matches an object whose given property
// matches 'matcher'. For example, // matches 'matcher'. For example,
// Property(&Foo::str, StartsWith("hi")) // Property(&Foo::str, StartsWith("hi"))
...@@ -3928,6 +4502,21 @@ Property(PropertyType (Class::*property)() const, ...@@ -3928,6 +4502,21 @@ Property(PropertyType (Class::*property)() const,
// to compile where bar() returns an int32 and m is a matcher for int64. // to compile where bar() returns an int32 and m is a matcher for int64.
} }
// Same as Property() above, but also takes the name of the property to provide
// better error messages.
template <typename Class, typename PropertyType, typename PropertyMatcher>
inline PolymorphicMatcher<internal::PropertyMatcher<
Class, PropertyType, PropertyType (Class::*)() const> >
Property(const std::string& property_name,
PropertyType (Class::*property)() const,
const PropertyMatcher& matcher) {
return MakePolymorphicMatcher(
internal::PropertyMatcher<Class, PropertyType,
PropertyType (Class::*)() const>(
property_name, property,
MatcherCast<GTEST_REFERENCE_TO_CONST_(PropertyType)>(matcher)));
}
#if GTEST_LANG_CXX11 #if GTEST_LANG_CXX11
// The same as above but for reference-qualified member functions. // The same as above but for reference-qualified member functions.
template <typename Class, typename PropertyType, typename PropertyMatcher> template <typename Class, typename PropertyType, typename PropertyMatcher>
...@@ -3941,6 +4530,20 @@ Property(PropertyType (Class::*property)() const &, ...@@ -3941,6 +4530,20 @@ Property(PropertyType (Class::*property)() const &,
property, property,
MatcherCast<GTEST_REFERENCE_TO_CONST_(PropertyType)>(matcher))); MatcherCast<GTEST_REFERENCE_TO_CONST_(PropertyType)>(matcher)));
} }
// Three-argument form for reference-qualified member functions.
template <typename Class, typename PropertyType, typename PropertyMatcher>
inline PolymorphicMatcher<internal::PropertyMatcher<
Class, PropertyType, PropertyType (Class::*)() const &> >
Property(const std::string& property_name,
PropertyType (Class::*property)() const &,
const PropertyMatcher& matcher) {
return MakePolymorphicMatcher(
internal::PropertyMatcher<Class, PropertyType,
PropertyType (Class::*)() const &>(
property_name, property,
MatcherCast<GTEST_REFERENCE_TO_CONST_(PropertyType)>(matcher)));
}
#endif #endif
// Creates a matcher that matches an object iff the result of applying // Creates a matcher that matches an object iff the result of applying
...@@ -3956,6 +4559,7 @@ Property(PropertyType (Class::*property)() const &, ...@@ -3956,6 +4559,7 @@ Property(PropertyType (Class::*property)() const &,
// concurrent access. // concurrent access.
// * If it is a function object, it has to define type result_type. // * If it is a function object, it has to define type result_type.
// We recommend deriving your functor classes from std::unary_function. // We recommend deriving your functor classes from std::unary_function.
//
template <typename Callable, typename ResultOfMatcher> template <typename Callable, typename ResultOfMatcher>
internal::ResultOfMatcher<Callable> ResultOf( internal::ResultOfMatcher<Callable> ResultOf(
Callable callable, const ResultOfMatcher& matcher) { Callable callable, const ResultOfMatcher& matcher) {
...@@ -4046,53 +4650,53 @@ inline PolymorphicMatcher<internal::MatchesRegexMatcher> ContainsRegex( ...@@ -4046,53 +4650,53 @@ inline PolymorphicMatcher<internal::MatchesRegexMatcher> ContainsRegex(
// Wide string matchers. // Wide string matchers.
// Matches a string equal to str. // Matches a string equal to str.
inline PolymorphicMatcher<internal::StrEqualityMatcher<internal::wstring> > inline PolymorphicMatcher<internal::StrEqualityMatcher<std::wstring> > StrEq(
StrEq(const internal::wstring& str) { const std::wstring& str) {
return MakePolymorphicMatcher(internal::StrEqualityMatcher<internal::wstring>( return MakePolymorphicMatcher(
str, true, true)); internal::StrEqualityMatcher<std::wstring>(str, true, true));
} }
// Matches a string not equal to str. // Matches a string not equal to str.
inline PolymorphicMatcher<internal::StrEqualityMatcher<internal::wstring> > inline PolymorphicMatcher<internal::StrEqualityMatcher<std::wstring> > StrNe(
StrNe(const internal::wstring& str) { const std::wstring& str) {
return MakePolymorphicMatcher(internal::StrEqualityMatcher<internal::wstring>( return MakePolymorphicMatcher(
str, false, true)); internal::StrEqualityMatcher<std::wstring>(str, false, true));
} }
// Matches a string equal to str, ignoring case. // Matches a string equal to str, ignoring case.
inline PolymorphicMatcher<internal::StrEqualityMatcher<internal::wstring> > inline PolymorphicMatcher<internal::StrEqualityMatcher<std::wstring> >
StrCaseEq(const internal::wstring& str) { StrCaseEq(const std::wstring& str) {
return MakePolymorphicMatcher(internal::StrEqualityMatcher<internal::wstring>( return MakePolymorphicMatcher(
str, true, false)); internal::StrEqualityMatcher<std::wstring>(str, true, false));
} }
// Matches a string not equal to str, ignoring case. // Matches a string not equal to str, ignoring case.
inline PolymorphicMatcher<internal::StrEqualityMatcher<internal::wstring> > inline PolymorphicMatcher<internal::StrEqualityMatcher<std::wstring> >
StrCaseNe(const internal::wstring& str) { StrCaseNe(const std::wstring& str) {
return MakePolymorphicMatcher(internal::StrEqualityMatcher<internal::wstring>( return MakePolymorphicMatcher(
str, false, false)); internal::StrEqualityMatcher<std::wstring>(str, false, false));
} }
// Creates a matcher that matches any wstring, std::wstring, or C wide string // Creates a matcher that matches any ::wstring, std::wstring, or C wide string
// that contains the given substring. // that contains the given substring.
inline PolymorphicMatcher<internal::HasSubstrMatcher<internal::wstring> > inline PolymorphicMatcher<internal::HasSubstrMatcher<std::wstring> > HasSubstr(
HasSubstr(const internal::wstring& substring) { const std::wstring& substring) {
return MakePolymorphicMatcher(internal::HasSubstrMatcher<internal::wstring>( return MakePolymorphicMatcher(
substring)); internal::HasSubstrMatcher<std::wstring>(substring));
} }
// Matches a string that starts with 'prefix' (case-sensitive). // Matches a string that starts with 'prefix' (case-sensitive).
inline PolymorphicMatcher<internal::StartsWithMatcher<internal::wstring> > inline PolymorphicMatcher<internal::StartsWithMatcher<std::wstring> >
StartsWith(const internal::wstring& prefix) { StartsWith(const std::wstring& prefix) {
return MakePolymorphicMatcher(internal::StartsWithMatcher<internal::wstring>( return MakePolymorphicMatcher(
prefix)); internal::StartsWithMatcher<std::wstring>(prefix));
} }
// Matches a string that ends with 'suffix' (case-sensitive). // Matches a string that ends with 'suffix' (case-sensitive).
inline PolymorphicMatcher<internal::EndsWithMatcher<internal::wstring> > inline PolymorphicMatcher<internal::EndsWithMatcher<std::wstring> > EndsWith(
EndsWith(const internal::wstring& suffix) { const std::wstring& suffix) {
return MakePolymorphicMatcher(internal::EndsWithMatcher<internal::wstring>( return MakePolymorphicMatcher(
suffix)); internal::EndsWithMatcher<std::wstring>(suffix));
} }
#endif // GTEST_HAS_GLOBAL_WSTRING || GTEST_HAS_STD_WSTRING #endif // GTEST_HAS_GLOBAL_WSTRING || GTEST_HAS_STD_WSTRING
...@@ -4121,6 +4725,58 @@ inline internal::Lt2Matcher Lt() { return internal::Lt2Matcher(); } ...@@ -4121,6 +4725,58 @@ inline internal::Lt2Matcher Lt() { return internal::Lt2Matcher(); }
// first field != the second field. // first field != the second field.
inline internal::Ne2Matcher Ne() { return internal::Ne2Matcher(); } inline internal::Ne2Matcher Ne() { return internal::Ne2Matcher(); }
// Creates a polymorphic matcher that matches a 2-tuple where
// FloatEq(first field) matches the second field.
inline internal::FloatingEq2Matcher<float> FloatEq() {
return internal::FloatingEq2Matcher<float>();
}
// Creates a polymorphic matcher that matches a 2-tuple where
// DoubleEq(first field) matches the second field.
inline internal::FloatingEq2Matcher<double> DoubleEq() {
return internal::FloatingEq2Matcher<double>();
}
// Creates a polymorphic matcher that matches a 2-tuple where
// FloatEq(first field) matches the second field with NaN equality.
inline internal::FloatingEq2Matcher<float> NanSensitiveFloatEq() {
return internal::FloatingEq2Matcher<float>(true);
}
// Creates a polymorphic matcher that matches a 2-tuple where
// DoubleEq(first field) matches the second field with NaN equality.
inline internal::FloatingEq2Matcher<double> NanSensitiveDoubleEq() {
return internal::FloatingEq2Matcher<double>(true);
}
// Creates a polymorphic matcher that matches a 2-tuple where
// FloatNear(first field, max_abs_error) matches the second field.
inline internal::FloatingEq2Matcher<float> FloatNear(float max_abs_error) {
return internal::FloatingEq2Matcher<float>(max_abs_error);
}
// Creates a polymorphic matcher that matches a 2-tuple where
// DoubleNear(first field, max_abs_error) matches the second field.
inline internal::FloatingEq2Matcher<double> DoubleNear(double max_abs_error) {
return internal::FloatingEq2Matcher<double>(max_abs_error);
}
// Creates a polymorphic matcher that matches a 2-tuple where
// FloatNear(first field, max_abs_error) matches the second field with NaN
// equality.
inline internal::FloatingEq2Matcher<float> NanSensitiveFloatNear(
float max_abs_error) {
return internal::FloatingEq2Matcher<float>(max_abs_error, true);
}
// Creates a polymorphic matcher that matches a 2-tuple where
// DoubleNear(first field, max_abs_error) matches the second field with NaN
// equality.
inline internal::FloatingEq2Matcher<double> NanSensitiveDoubleNear(
double max_abs_error) {
return internal::FloatingEq2Matcher<double>(max_abs_error, true);
}
// Creates a matcher that matches any value of type T that m doesn't // Creates a matcher that matches any value of type T that m doesn't
// match. // match.
template <typename InnerMatcher> template <typename InnerMatcher>
...@@ -4303,6 +4959,128 @@ inline internal::ContainsMatcher<M> Contains(M matcher) { ...@@ -4303,6 +4959,128 @@ inline internal::ContainsMatcher<M> Contains(M matcher) {
return internal::ContainsMatcher<M>(matcher); return internal::ContainsMatcher<M>(matcher);
} }
// IsSupersetOf(iterator_first, iterator_last)
// IsSupersetOf(pointer, count)
// IsSupersetOf(array)
// IsSupersetOf(container)
// IsSupersetOf({e1, e2, ..., en})
//
// IsSupersetOf() verifies that a surjective partial mapping onto a collection
// of matchers exists. In other words, a container matches
// IsSupersetOf({e1, ..., en}) if and only if there is a permutation
// {y1, ..., yn} of some of the container's elements where y1 matches e1,
// ..., and yn matches en. Obviously, the size of the container must be >= n
// in order to have a match. Examples:
//
// - {1, 2, 3} matches IsSupersetOf({Ge(3), Ne(0)}), as 3 matches Ge(3) and
// 1 matches Ne(0).
// - {1, 2} doesn't match IsSupersetOf({Eq(1), Lt(2)}), even though 1 matches
// both Eq(1) and Lt(2). The reason is that different matchers must be used
// for elements in different slots of the container.
// - {1, 1, 2} matches IsSupersetOf({Eq(1), Lt(2)}), as (the first) 1 matches
// Eq(1) and (the second) 1 matches Lt(2).
// - {1, 2, 3} matches IsSupersetOf(Gt(1), Gt(1)), as 2 matches (the first)
// Gt(1) and 3 matches (the second) Gt(1).
//
// The matchers can be specified as an array, a pointer and count, a container,
// an initializer list, or an STL iterator range. In each of these cases, the
// underlying matchers can be either values or matchers.
template <typename Iter>
inline internal::UnorderedElementsAreArrayMatcher<
typename ::std::iterator_traits<Iter>::value_type>
IsSupersetOf(Iter first, Iter last) {
typedef typename ::std::iterator_traits<Iter>::value_type T;
return internal::UnorderedElementsAreArrayMatcher<T>(
internal::UnorderedMatcherRequire::Superset, first, last);
}
template <typename T>
inline internal::UnorderedElementsAreArrayMatcher<T> IsSupersetOf(
const T* pointer, size_t count) {
return IsSupersetOf(pointer, pointer + count);
}
template <typename T, size_t N>
inline internal::UnorderedElementsAreArrayMatcher<T> IsSupersetOf(
const T (&array)[N]) {
return IsSupersetOf(array, N);
}
template <typename Container>
inline internal::UnorderedElementsAreArrayMatcher<
typename Container::value_type>
IsSupersetOf(const Container& container) {
return IsSupersetOf(container.begin(), container.end());
}
#if GTEST_HAS_STD_INITIALIZER_LIST_
template <typename T>
inline internal::UnorderedElementsAreArrayMatcher<T> IsSupersetOf(
::std::initializer_list<T> xs) {
return IsSupersetOf(xs.begin(), xs.end());
}
#endif
// IsSubsetOf(iterator_first, iterator_last)
// IsSubsetOf(pointer, count)
// IsSubsetOf(array)
// IsSubsetOf(container)
// IsSubsetOf({e1, e2, ..., en})
//
// IsSubsetOf() verifies that an injective mapping onto a collection of matchers
// exists. In other words, a container matches IsSubsetOf({e1, ..., en}) if and
// only if there is a subset of matchers {m1, ..., mk} which would match the
// container using UnorderedElementsAre. Obviously, the size of the container
// must be <= n in order to have a match. Examples:
//
// - {1} matches IsSubsetOf({Gt(0), Lt(0)}), as 1 matches Gt(0).
// - {1, -1} matches IsSubsetOf({Lt(0), Gt(0)}), as 1 matches Gt(0) and -1
// matches Lt(0).
// - {1, 2} doesn't matches IsSubsetOf({Gt(0), Lt(0)}), even though 1 and 2 both
// match Gt(0). The reason is that different matchers must be used for
// elements in different slots of the container.
//
// The matchers can be specified as an array, a pointer and count, a container,
// an initializer list, or an STL iterator range. In each of these cases, the
// underlying matchers can be either values or matchers.
template <typename Iter>
inline internal::UnorderedElementsAreArrayMatcher<
typename ::std::iterator_traits<Iter>::value_type>
IsSubsetOf(Iter first, Iter last) {
typedef typename ::std::iterator_traits<Iter>::value_type T;
return internal::UnorderedElementsAreArrayMatcher<T>(
internal::UnorderedMatcherRequire::Subset, first, last);
}
template <typename T>
inline internal::UnorderedElementsAreArrayMatcher<T> IsSubsetOf(
const T* pointer, size_t count) {
return IsSubsetOf(pointer, pointer + count);
}
template <typename T, size_t N>
inline internal::UnorderedElementsAreArrayMatcher<T> IsSubsetOf(
const T (&array)[N]) {
return IsSubsetOf(array, N);
}
template <typename Container>
inline internal::UnorderedElementsAreArrayMatcher<
typename Container::value_type>
IsSubsetOf(const Container& container) {
return IsSubsetOf(container.begin(), container.end());
}
#if GTEST_HAS_STD_INITIALIZER_LIST_
template <typename T>
inline internal::UnorderedElementsAreArrayMatcher<T> IsSubsetOf(
::std::initializer_list<T> xs) {
return IsSubsetOf(xs.begin(), xs.end());
}
#endif
// Matches an STL-style container or a native array that contains only // Matches an STL-style container or a native array that contains only
// elements matching the given value or matcher. // elements matching the given value or matcher.
// //
...@@ -4376,17 +5154,60 @@ inline bool ExplainMatchResult( ...@@ -4376,17 +5154,60 @@ inline bool ExplainMatchResult(
return SafeMatcherCast<const T&>(matcher).MatchAndExplain(value, listener); return SafeMatcherCast<const T&>(matcher).MatchAndExplain(value, listener);
} }
// Returns a string representation of the given matcher. Useful for description
// strings of matchers defined using MATCHER_P* macros that accept matchers as
// their arguments. For example:
//
// MATCHER_P(XAndYThat, matcher,
// "X that " + DescribeMatcher<int>(matcher, negation) +
// " and Y that " + DescribeMatcher<double>(matcher, negation)) {
// return ExplainMatchResult(matcher, arg.x(), result_listener) &&
// ExplainMatchResult(matcher, arg.y(), result_listener);
// }
template <typename T, typename M>
std::string DescribeMatcher(const M& matcher, bool negation = false) {
::std::stringstream ss;
Matcher<T> monomorphic_matcher = SafeMatcherCast<T>(matcher);
if (negation) {
monomorphic_matcher.DescribeNegationTo(&ss);
} else {
monomorphic_matcher.DescribeTo(&ss);
}
return ss.str();
}
#if GTEST_LANG_CXX11 #if GTEST_LANG_CXX11
// Define variadic matcher versions. They are overloaded in // Define variadic matcher versions. They are overloaded in
// gmock-generated-matchers.h for the cases supported by pre C++11 compilers. // gmock-generated-matchers.h for the cases supported by pre C++11 compilers.
template <typename... Args> template <typename... Args>
inline internal::AllOfMatcher<Args...> AllOf(const Args&... matchers) { internal::AllOfMatcher<typename std::decay<const Args&>::type...> AllOf(
return internal::AllOfMatcher<Args...>(matchers...); const Args&... matchers) {
return internal::AllOfMatcher<typename std::decay<const Args&>::type...>(
matchers...);
}
template <typename... Args>
internal::AnyOfMatcher<typename std::decay<const Args&>::type...> AnyOf(
const Args&... matchers) {
return internal::AnyOfMatcher<typename std::decay<const Args&>::type...>(
matchers...);
}
template <typename... Args>
internal::ElementsAreMatcher<tuple<typename std::decay<const Args&>::type...>>
ElementsAre(const Args&... matchers) {
return internal::ElementsAreMatcher<
tuple<typename std::decay<const Args&>::type...>>(
make_tuple(matchers...));
} }
template <typename... Args> template <typename... Args>
inline internal::AnyOfMatcher<Args...> AnyOf(const Args&... matchers) { internal::UnorderedElementsAreMatcher<
return internal::AnyOfMatcher<Args...>(matchers...); tuple<typename std::decay<const Args&>::type...>>
UnorderedElementsAre(const Args&... matchers) {
return internal::UnorderedElementsAreMatcher<
tuple<typename std::decay<const Args&>::type...>>(
make_tuple(matchers...));
} }
#endif // GTEST_LANG_CXX11 #endif // GTEST_LANG_CXX11
...@@ -4401,6 +5222,39 @@ inline internal::AnyOfMatcher<Args...> AnyOf(const Args&... matchers) { ...@@ -4401,6 +5222,39 @@ inline internal::AnyOfMatcher<Args...> AnyOf(const Args&... matchers) {
template <typename InnerMatcher> template <typename InnerMatcher>
inline InnerMatcher AllArgs(const InnerMatcher& matcher) { return matcher; } inline InnerMatcher AllArgs(const InnerMatcher& matcher) { return matcher; }
// Returns a matcher that matches the value of an optional<> type variable.
// The matcher implementation only uses '!arg' and requires that the optional<>
// type has a 'value_type' member type and that '*arg' is of type 'value_type'
// and is printable using 'PrintToString'. It is compatible with
// std::optional/std::experimental::optional.
// Note that to compare an optional type variable against nullopt you should
// use Eq(nullopt) and not Optional(Eq(nullopt)). The latter implies that the
// optional value contains an optional itself.
template <typename ValueMatcher>
inline internal::OptionalMatcher<ValueMatcher> Optional(
const ValueMatcher& value_matcher) {
return internal::OptionalMatcher<ValueMatcher>(value_matcher);
}
// Returns a matcher that matches the value of a absl::any type variable.
template <typename T>
PolymorphicMatcher<internal::any_cast_matcher::AnyCastMatcher<T> > AnyWith(
const Matcher<const T&>& matcher) {
return MakePolymorphicMatcher(
internal::any_cast_matcher::AnyCastMatcher<T>(matcher));
}
// Returns a matcher that matches the value of a variant<> type variable.
// The matcher implementation uses ADL to find the holds_alternative and get
// functions.
// It is compatible with std::variant.
template <typename T>
PolymorphicMatcher<internal::variant_matcher::VariantMatcher<T> > VariantWith(
const Matcher<const T&>& matcher) {
return MakePolymorphicMatcher(
internal::variant_matcher::VariantMatcher<T>(matcher));
}
// These macros allow using matchers to check values in Google Test // These macros allow using matchers to check values in Google Test
// tests. ASSERT_THAT(value, matcher) and EXPECT_THAT(value, matcher) // tests. ASSERT_THAT(value, matcher) and EXPECT_THAT(value, matcher)
// succeed iff the value matches the matcher. If the assertion fails, // succeed iff the value matches the matcher. If the assertion fails,
...@@ -4416,4 +5270,5 @@ inline InnerMatcher AllArgs(const InnerMatcher& matcher) { return matcher; } ...@@ -4416,4 +5270,5 @@ inline InnerMatcher AllArgs(const InnerMatcher& matcher) { return matcher; }
// We must include this header at the end to make sure it can use the // We must include this header at the end to make sure it can use the
// declarations from this file. // declarations from this file.
#include "gmock/internal/custom/gmock-matchers.h" #include "gmock/internal/custom/gmock-matchers.h"
#endif // GMOCK_INCLUDE_GMOCK_GMOCK_MATCHERS_H_ #endif // GMOCK_INCLUDE_GMOCK_GMOCK_MATCHERS_H_
...@@ -26,13 +26,14 @@ ...@@ -26,13 +26,14 @@
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// Author: wan@google.com (Zhanyong Wan)
// Google Mock - a framework for writing C++ mock classes. // Google Mock - a framework for writing C++ mock classes.
// //
// This file implements some actions that depend on gmock-generated-actions.h. // This file implements some actions that depend on gmock-generated-actions.h.
// GOOGLETEST_CM0002 DO NOT DELETE
#ifndef GMOCK_INCLUDE_GMOCK_GMOCK_MORE_ACTIONS_H_ #ifndef GMOCK_INCLUDE_GMOCK_GMOCK_MORE_ACTIONS_H_
#define GMOCK_INCLUDE_GMOCK_GMOCK_MORE_ACTIONS_H_ #define GMOCK_INCLUDE_GMOCK_GMOCK_MORE_ACTIONS_H_
......
...@@ -26,8 +26,7 @@ ...@@ -26,8 +26,7 @@
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// Author: marcus.boerger@google.com (Marcus Boerger)
// Google Mock - a framework for writing C++ mock classes. // Google Mock - a framework for writing C++ mock classes.
// //
...@@ -36,13 +35,27 @@ ...@@ -36,13 +35,27 @@
// Note that tests are implemented in gmock-matchers_test.cc rather than // Note that tests are implemented in gmock-matchers_test.cc rather than
// gmock-more-matchers-test.cc. // gmock-more-matchers-test.cc.
#ifndef GMOCK_GMOCK_MORE_MATCHERS_H_ // GOOGLETEST_CM0002 DO NOT DELETE
#define GMOCK_GMOCK_MORE_MATCHERS_H_
#ifndef GMOCK_INCLUDE_GMOCK_MORE_MATCHERS_H_
#define GMOCK_INCLUDE_GMOCK_MORE_MATCHERS_H_
#include "gmock/gmock-generated-matchers.h" #include "gmock/gmock-generated-matchers.h"
namespace testing { namespace testing {
// Silence C4100 (unreferenced formal
// parameter) for MSVC
#ifdef _MSC_VER
# pragma warning(push)
# pragma warning(disable:4100)
#if (_MSC_VER == 1900)
// and silence C4800 (C4800: 'int *const ': forcing value
// to bool 'true' or 'false') for MSVC 14
# pragma warning(disable:4800)
#endif
#endif
// Defines a matcher that matches an empty container. The container must // Defines a matcher that matches an empty container. The container must
// support both size() and empty(), which all STL-like containers provide. // support both size() and empty(), which all STL-like containers provide.
MATCHER(IsEmpty, negation ? "isn't empty" : "is empty") { MATCHER(IsEmpty, negation ? "isn't empty" : "is empty") {
...@@ -69,6 +82,11 @@ MATCHER(IsFalse, negation ? "is true" : "is false") { ...@@ -69,6 +82,11 @@ MATCHER(IsFalse, negation ? "is true" : "is false") {
return !static_cast<bool>(arg); return !static_cast<bool>(arg);
} }
#ifdef _MSC_VER
# pragma warning(pop)
#endif
} // namespace testing } // namespace testing
#endif // GMOCK_GMOCK_MORE_MATCHERS_H_ #endif // GMOCK_INCLUDE_GMOCK_MORE_MATCHERS_H_
...@@ -26,8 +26,7 @@ ...@@ -26,8 +26,7 @@
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// Author: wan@google.com (Zhanyong Wan)
// Google Mock - a framework for writing C++ mock classes. // Google Mock - a framework for writing C++ mock classes.
// //
...@@ -57,6 +56,8 @@ ...@@ -57,6 +56,8 @@
// where all clauses are optional, and .InSequence()/.After()/ // where all clauses are optional, and .InSequence()/.After()/
// .WillOnce() can appear any number of times. // .WillOnce() can appear any number of times.
// GOOGLETEST_CM0002 DO NOT DELETE
#ifndef GMOCK_INCLUDE_GMOCK_GMOCK_SPEC_BUILDERS_H_ #ifndef GMOCK_INCLUDE_GMOCK_GMOCK_SPEC_BUILDERS_H_
#define GMOCK_INCLUDE_GMOCK_GMOCK_SPEC_BUILDERS_H_ #define GMOCK_INCLUDE_GMOCK_GMOCK_SPEC_BUILDERS_H_
...@@ -147,14 +148,13 @@ class GTEST_API_ UntypedFunctionMockerBase { ...@@ -147,14 +148,13 @@ class GTEST_API_ UntypedFunctionMockerBase {
// action fails. // action fails.
// L = * // L = *
virtual UntypedActionResultHolderBase* UntypedPerformDefaultAction( virtual UntypedActionResultHolderBase* UntypedPerformDefaultAction(
const void* untyped_args, const std::string& call_description) const = 0; void* untyped_args, const std::string& call_description) const = 0;
// Performs the given action with the given arguments and returns // Performs the given action with the given arguments and returns
// the action's result. // the action's result.
// L = * // L = *
virtual UntypedActionResultHolderBase* UntypedPerformAction( virtual UntypedActionResultHolderBase* UntypedPerformAction(
const void* untyped_action, const void* untyped_action, void* untyped_args) const = 0;
const void* untyped_args) const = 0;
// Writes a message that the call is uninteresting (i.e. neither // Writes a message that the call is uninteresting (i.e. neither
// explicitly expected nor explicitly unexpected) to the given // explicitly expected nor explicitly unexpected) to the given
...@@ -184,7 +184,7 @@ class GTEST_API_ UntypedFunctionMockerBase { ...@@ -184,7 +184,7 @@ class GTEST_API_ UntypedFunctionMockerBase {
// this information in the global mock registry. Will be called // this information in the global mock registry. Will be called
// whenever an EXPECT_CALL() or ON_CALL() is executed on this mock // whenever an EXPECT_CALL() or ON_CALL() is executed on this mock
// method. // method.
// TODO(wan@google.com): rename to SetAndRegisterOwner(). // FIXME: rename to SetAndRegisterOwner().
void RegisterOwner(const void* mock_obj) void RegisterOwner(const void* mock_obj)
GTEST_LOCK_EXCLUDED_(g_gmock_mutex); GTEST_LOCK_EXCLUDED_(g_gmock_mutex);
...@@ -209,9 +209,8 @@ class GTEST_API_ UntypedFunctionMockerBase { ...@@ -209,9 +209,8 @@ class GTEST_API_ UntypedFunctionMockerBase {
// arguments. This function can be safely called from multiple // arguments. This function can be safely called from multiple
// threads concurrently. The caller is responsible for deleting the // threads concurrently. The caller is responsible for deleting the
// result. // result.
UntypedActionResultHolderBase* UntypedInvokeWith( UntypedActionResultHolderBase* UntypedInvokeWith(void* untyped_args)
const void* untyped_args) GTEST_LOCK_EXCLUDED_(g_gmock_mutex);
GTEST_LOCK_EXCLUDED_(g_gmock_mutex);
protected: protected:
typedef std::vector<const void*> UntypedOnCallSpecs; typedef std::vector<const void*> UntypedOnCallSpecs;
...@@ -236,6 +235,14 @@ class GTEST_API_ UntypedFunctionMockerBase { ...@@ -236,6 +235,14 @@ class GTEST_API_ UntypedFunctionMockerBase {
UntypedOnCallSpecs untyped_on_call_specs_; UntypedOnCallSpecs untyped_on_call_specs_;
// All expectations for this function mocker. // All expectations for this function mocker.
//
// It's undefined behavior to interleave expectations (EXPECT_CALLs
// or ON_CALLs) and mock function calls. Also, the order of
// expectations is important. Therefore it's a logic race condition
// to read/write untyped_expectations_ concurrently. In order for
// tools like tsan to catch concurrent read/write accesses to
// untyped_expectations, we deliberately leave accesses to it
// unprotected.
UntypedExpectations untyped_expectations_; UntypedExpectations untyped_expectations_;
}; // class UntypedFunctionMockerBase }; // class UntypedFunctionMockerBase
...@@ -1200,7 +1207,7 @@ class TypedExpectation : public ExpectationBase { ...@@ -1200,7 +1207,7 @@ class TypedExpectation : public ExpectationBase {
mocker->DescribeDefaultActionTo(args, what); mocker->DescribeDefaultActionTo(args, what);
DescribeCallCountTo(why); DescribeCallCountTo(why);
// TODO(wan@google.com): allow the user to control whether // FIXME: allow the user to control whether
// unexpected calls should fail immediately or continue using a // unexpected calls should fail immediately or continue using a
// flag --gmock_unexpected_calls_are_fatal. // flag --gmock_unexpected_calls_are_fatal.
return NULL; return NULL;
...@@ -1252,8 +1259,9 @@ class MockSpec { ...@@ -1252,8 +1259,9 @@ class MockSpec {
// Constructs a MockSpec object, given the function mocker object // Constructs a MockSpec object, given the function mocker object
// that the spec is associated with. // that the spec is associated with.
explicit MockSpec(internal::FunctionMockerBase<F>* function_mocker) MockSpec(internal::FunctionMockerBase<F>* function_mocker,
: function_mocker_(function_mocker) {} const ArgumentMatcherTuple& matchers)
: function_mocker_(function_mocker), matchers_(matchers) {}
// Adds a new default action spec to the function mocker and returns // Adds a new default action spec to the function mocker and returns
// the newly created spec. // the newly created spec.
...@@ -1275,14 +1283,17 @@ class MockSpec { ...@@ -1275,14 +1283,17 @@ class MockSpec {
file, line, source_text, matchers_); file, line, source_text, matchers_);
} }
// This operator overload is used to swallow the superfluous parameter list
// introduced by the ON/EXPECT_CALL macros. See the macro comments for more
// explanation.
MockSpec<F>& operator()(const internal::WithoutMatchers&, void* const) {
return *this;
}
private: private:
template <typename Function> template <typename Function>
friend class internal::FunctionMocker; friend class internal::FunctionMocker;
void SetMatchers(const ArgumentMatcherTuple& matchers) {
matchers_ = matchers;
}
// The function mocker that owns this spec. // The function mocker that owns this spec.
internal::FunctionMockerBase<F>* const function_mocker_; internal::FunctionMockerBase<F>* const function_mocker_;
// The argument matchers specified in the spec. // The argument matchers specified in the spec.
...@@ -1390,19 +1401,20 @@ class ActionResultHolder : public UntypedActionResultHolderBase { ...@@ -1390,19 +1401,20 @@ class ActionResultHolder : public UntypedActionResultHolderBase {
template <typename F> template <typename F>
static ActionResultHolder* PerformDefaultAction( static ActionResultHolder* PerformDefaultAction(
const FunctionMockerBase<F>* func_mocker, const FunctionMockerBase<F>* func_mocker,
const typename Function<F>::ArgumentTuple& args, typename RvalueRef<typename Function<F>::ArgumentTuple>::type args,
const std::string& call_description) { const std::string& call_description) {
return new ActionResultHolder(Wrapper( return new ActionResultHolder(Wrapper(func_mocker->PerformDefaultAction(
func_mocker->PerformDefaultAction(args, call_description))); internal::move(args), call_description)));
} }
// Performs the given action and returns the result in a new-ed // Performs the given action and returns the result in a new-ed
// ActionResultHolder. // ActionResultHolder.
template <typename F> template <typename F>
static ActionResultHolder* static ActionResultHolder* PerformAction(
PerformAction(const Action<F>& action, const Action<F>& action,
const typename Function<F>::ArgumentTuple& args) { typename RvalueRef<typename Function<F>::ArgumentTuple>::type args) {
return new ActionResultHolder(Wrapper(action.Perform(args))); return new ActionResultHolder(
Wrapper(action.Perform(internal::move(args))));
} }
private: private:
...@@ -1430,9 +1442,9 @@ class ActionResultHolder<void> : public UntypedActionResultHolderBase { ...@@ -1430,9 +1442,9 @@ class ActionResultHolder<void> : public UntypedActionResultHolderBase {
template <typename F> template <typename F>
static ActionResultHolder* PerformDefaultAction( static ActionResultHolder* PerformDefaultAction(
const FunctionMockerBase<F>* func_mocker, const FunctionMockerBase<F>* func_mocker,
const typename Function<F>::ArgumentTuple& args, typename RvalueRef<typename Function<F>::ArgumentTuple>::type args,
const std::string& call_description) { const std::string& call_description) {
func_mocker->PerformDefaultAction(args, call_description); func_mocker->PerformDefaultAction(internal::move(args), call_description);
return new ActionResultHolder; return new ActionResultHolder;
} }
...@@ -1441,8 +1453,8 @@ class ActionResultHolder<void> : public UntypedActionResultHolderBase { ...@@ -1441,8 +1453,8 @@ class ActionResultHolder<void> : public UntypedActionResultHolderBase {
template <typename F> template <typename F>
static ActionResultHolder* PerformAction( static ActionResultHolder* PerformAction(
const Action<F>& action, const Action<F>& action,
const typename Function<F>::ArgumentTuple& args) { typename RvalueRef<typename Function<F>::ArgumentTuple>::type args) {
action.Perform(args); action.Perform(internal::move(args));
return new ActionResultHolder; return new ActionResultHolder;
} }
...@@ -1461,7 +1473,7 @@ class FunctionMockerBase : public UntypedFunctionMockerBase { ...@@ -1461,7 +1473,7 @@ class FunctionMockerBase : public UntypedFunctionMockerBase {
typedef typename Function<F>::ArgumentTuple ArgumentTuple; typedef typename Function<F>::ArgumentTuple ArgumentTuple;
typedef typename Function<F>::ArgumentMatcherTuple ArgumentMatcherTuple; typedef typename Function<F>::ArgumentMatcherTuple ArgumentMatcherTuple;
FunctionMockerBase() : current_spec_(this) {} FunctionMockerBase() {}
// The destructor verifies that all expectations on this mock // The destructor verifies that all expectations on this mock
// function have been satisfied. If not, it will report Google Test // function have been satisfied. If not, it will report Google Test
...@@ -1497,12 +1509,13 @@ class FunctionMockerBase : public UntypedFunctionMockerBase { ...@@ -1497,12 +1509,13 @@ class FunctionMockerBase : public UntypedFunctionMockerBase {
// mutable state of this object, and thus can be called concurrently // mutable state of this object, and thus can be called concurrently
// without locking. // without locking.
// L = * // L = *
Result PerformDefaultAction(const ArgumentTuple& args, Result PerformDefaultAction(
const std::string& call_description) const { typename RvalueRef<typename Function<F>::ArgumentTuple>::type args,
const std::string& call_description) const {
const OnCallSpec<F>* const spec = const OnCallSpec<F>* const spec =
this->FindOnCallSpec(args); this->FindOnCallSpec(args);
if (spec != NULL) { if (spec != NULL) {
return spec->GetAction().Perform(args); return spec->GetAction().Perform(internal::move(args));
} }
const std::string message = const std::string message =
call_description + call_description +
...@@ -1524,11 +1537,11 @@ class FunctionMockerBase : public UntypedFunctionMockerBase { ...@@ -1524,11 +1537,11 @@ class FunctionMockerBase : public UntypedFunctionMockerBase {
// action fails. The caller is responsible for deleting the result. // action fails. The caller is responsible for deleting the result.
// L = * // L = *
virtual UntypedActionResultHolderBase* UntypedPerformDefaultAction( virtual UntypedActionResultHolderBase* UntypedPerformDefaultAction(
const void* untyped_args, // must point to an ArgumentTuple void* untyped_args, // must point to an ArgumentTuple
const std::string& call_description) const { const std::string& call_description) const {
const ArgumentTuple& args = ArgumentTuple* args = static_cast<ArgumentTuple*>(untyped_args);
*static_cast<const ArgumentTuple*>(untyped_args); return ResultHolder::PerformDefaultAction(this, internal::move(*args),
return ResultHolder::PerformDefaultAction(this, args, call_description); call_description);
} }
// Performs the given action with the given arguments and returns // Performs the given action with the given arguments and returns
...@@ -1536,13 +1549,12 @@ class FunctionMockerBase : public UntypedFunctionMockerBase { ...@@ -1536,13 +1549,12 @@ class FunctionMockerBase : public UntypedFunctionMockerBase {
// result. // result.
// L = * // L = *
virtual UntypedActionResultHolderBase* UntypedPerformAction( virtual UntypedActionResultHolderBase* UntypedPerformAction(
const void* untyped_action, const void* untyped_args) const { const void* untyped_action, void* untyped_args) const {
// Make a copy of the action before performing it, in case the // Make a copy of the action before performing it, in case the
// action deletes the mock object (and thus deletes itself). // action deletes the mock object (and thus deletes itself).
const Action<F> action = *static_cast<const Action<F>*>(untyped_action); const Action<F> action = *static_cast<const Action<F>*>(untyped_action);
const ArgumentTuple& args = ArgumentTuple* args = static_cast<ArgumentTuple*>(untyped_args);
*static_cast<const ArgumentTuple*>(untyped_args); return ResultHolder::PerformAction(action, internal::move(*args));
return ResultHolder::PerformAction(action, args);
} }
// Implements UntypedFunctionMockerBase::ClearDefaultActionsLocked(): // Implements UntypedFunctionMockerBase::ClearDefaultActionsLocked():
...@@ -1582,10 +1594,14 @@ class FunctionMockerBase : public UntypedFunctionMockerBase { ...@@ -1582,10 +1594,14 @@ class FunctionMockerBase : public UntypedFunctionMockerBase {
// Returns the result of invoking this mock function with the given // Returns the result of invoking this mock function with the given
// arguments. This function can be safely called from multiple // arguments. This function can be safely called from multiple
// threads concurrently. // threads concurrently.
Result InvokeWith(const ArgumentTuple& args) Result InvokeWith(
GTEST_LOCK_EXCLUDED_(g_gmock_mutex) { typename RvalueRef<typename Function<F>::ArgumentTuple>::type args)
GTEST_LOCK_EXCLUDED_(g_gmock_mutex) {
// const_cast is required since in C++98 we still pass ArgumentTuple around
// by const& instead of rvalue reference.
void* untyped_args = const_cast<void*>(static_cast<const void*>(&args));
scoped_ptr<ResultHolder> holder( scoped_ptr<ResultHolder> holder(
DownCast_<ResultHolder*>(this->UntypedInvokeWith(&args))); DownCast_<ResultHolder*>(this->UntypedInvokeWith(untyped_args)));
return holder->Unwrap(); return holder->Unwrap();
} }
...@@ -1609,6 +1625,8 @@ class FunctionMockerBase : public UntypedFunctionMockerBase { ...@@ -1609,6 +1625,8 @@ class FunctionMockerBase : public UntypedFunctionMockerBase {
TypedExpectation<F>* const expectation = TypedExpectation<F>* const expectation =
new TypedExpectation<F>(this, file, line, source_text, m); new TypedExpectation<F>(this, file, line, source_text, m);
const linked_ptr<ExpectationBase> untyped_expectation(expectation); const linked_ptr<ExpectationBase> untyped_expectation(expectation);
// See the definition of untyped_expectations_ for why access to
// it is unprotected here.
untyped_expectations_.push_back(untyped_expectation); untyped_expectations_.push_back(untyped_expectation);
// Adds this expectation into the implicit sequence if there is one. // Adds this expectation into the implicit sequence if there is one.
...@@ -1620,10 +1638,6 @@ class FunctionMockerBase : public UntypedFunctionMockerBase { ...@@ -1620,10 +1638,6 @@ class FunctionMockerBase : public UntypedFunctionMockerBase {
return *expectation; return *expectation;
} }
// The current spec (either default action spec or expectation spec)
// being described on this function mocker.
MockSpec<F>& current_spec() { return current_spec_; }
private: private:
template <typename Func> friend class TypedExpectation; template <typename Func> friend class TypedExpectation;
...@@ -1716,6 +1730,8 @@ class FunctionMockerBase : public UntypedFunctionMockerBase { ...@@ -1716,6 +1730,8 @@ class FunctionMockerBase : public UntypedFunctionMockerBase {
const ArgumentTuple& args) const const ArgumentTuple& args) const
GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) { GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) {
g_gmock_mutex.AssertHeld(); g_gmock_mutex.AssertHeld();
// See the definition of untyped_expectations_ for why access to
// it is unprotected here.
for (typename UntypedExpectations::const_reverse_iterator it = for (typename UntypedExpectations::const_reverse_iterator it =
untyped_expectations_.rbegin(); untyped_expectations_.rbegin();
it != untyped_expectations_.rend(); ++it) { it != untyped_expectations_.rend(); ++it) {
...@@ -1766,10 +1782,6 @@ class FunctionMockerBase : public UntypedFunctionMockerBase { ...@@ -1766,10 +1782,6 @@ class FunctionMockerBase : public UntypedFunctionMockerBase {
} }
} }
// The current spec (either default action spec or expectation spec)
// being described on this function mocker.
MockSpec<F> current_spec_;
// There is no generally useful and implementable semantics of // There is no generally useful and implementable semantics of
// copying a mock object, so copying a mock is usually a user error. // copying a mock object, so copying a mock is usually a user error.
// Thus we disallow copying function mockers. If the user really // Thus we disallow copying function mockers. If the user really
...@@ -1832,17 +1844,76 @@ inline Expectation::Expectation(internal::ExpectationBase& exp) // NOLINT ...@@ -1832,17 +1844,76 @@ inline Expectation::Expectation(internal::ExpectationBase& exp) // NOLINT
} // namespace testing } // namespace testing
// A separate macro is required to avoid compile errors when the name // Implementation for ON_CALL and EXPECT_CALL macros. A separate macro is
// of the method used in call is a result of macro expansion. // required to avoid compile errors when the name of the method used in call is
// See CompilesWithMethodNameExpandedFromMacro tests in // a result of macro expansion. See CompilesWithMethodNameExpandedFromMacro
// internal/gmock-spec-builders_test.cc for more details. // tests in internal/gmock-spec-builders_test.cc for more details.
#define GMOCK_ON_CALL_IMPL_(obj, call) \ //
((obj).gmock_##call).InternalDefaultActionSetAt(__FILE__, __LINE__, \ // This macro supports statements both with and without parameter matchers. If
#obj, #call) // the parameter list is omitted, gMock will accept any parameters, which allows
#define ON_CALL(obj, call) GMOCK_ON_CALL_IMPL_(obj, call) // tests to be written that don't need to encode the number of method
// parameter. This technique may only be used for non-overloaded methods.
#define GMOCK_EXPECT_CALL_IMPL_(obj, call) \ //
((obj).gmock_##call).InternalExpectedAt(__FILE__, __LINE__, #obj, #call) // // These are the same:
#define EXPECT_CALL(obj, call) GMOCK_EXPECT_CALL_IMPL_(obj, call) // ON_CALL(mock, NoArgsMethod()).WillByDefault(...);
// ON_CALL(mock, NoArgsMethod).WillByDefault(...);
//
// // As are these:
// ON_CALL(mock, TwoArgsMethod(_, _)).WillByDefault(...);
// ON_CALL(mock, TwoArgsMethod).WillByDefault(...);
//
// // Can also specify args if you want, of course:
// ON_CALL(mock, TwoArgsMethod(_, 45)).WillByDefault(...);
//
// // Overloads work as long as you specify parameters:
// ON_CALL(mock, OverloadedMethod(_)).WillByDefault(...);
// ON_CALL(mock, OverloadedMethod(_, _)).WillByDefault(...);
//
// // Oops! Which overload did you want?
// ON_CALL(mock, OverloadedMethod).WillByDefault(...);
// => ERROR: call to member function 'gmock_OverloadedMethod' is ambiguous
//
// How this works: The mock class uses two overloads of the gmock_Method
// expectation setter method plus an operator() overload on the MockSpec object.
// In the matcher list form, the macro expands to:
//
// // This statement:
// ON_CALL(mock, TwoArgsMethod(_, 45))...
//
// // ...expands to:
// mock.gmock_TwoArgsMethod(_, 45)(WithoutMatchers(), nullptr)...
// |-------------v---------------||------------v-------------|
// invokes first overload swallowed by operator()
//
// // ...which is essentially:
// mock.gmock_TwoArgsMethod(_, 45)...
//
// Whereas the form without a matcher list:
//
// // This statement:
// ON_CALL(mock, TwoArgsMethod)...
//
// // ...expands to:
// mock.gmock_TwoArgsMethod(WithoutMatchers(), nullptr)...
// |-----------------------v--------------------------|
// invokes second overload
//
// // ...which is essentially:
// mock.gmock_TwoArgsMethod(_, _)...
//
// The WithoutMatchers() argument is used to disambiguate overloads and to
// block the caller from accidentally invoking the second overload directly. The
// second argument is an internal type derived from the method signature. The
// failure to disambiguate two overloads of this method in the ON_CALL statement
// is how we block callers from setting expectations on overloaded methods.
#define GMOCK_ON_CALL_IMPL_(mock_expr, Setter, call) \
((mock_expr).gmock_##call)(::testing::internal::GetWithoutMatchers(), NULL) \
.Setter(__FILE__, __LINE__, #mock_expr, #call)
#define ON_CALL(obj, call) \
GMOCK_ON_CALL_IMPL_(obj, InternalDefaultActionSetAt, call)
#define EXPECT_CALL(obj, call) \
GMOCK_ON_CALL_IMPL_(obj, InternalExpectedAt, call)
#endif // GMOCK_INCLUDE_GMOCK_GMOCK_SPEC_BUILDERS_H_ #endif // GMOCK_INCLUDE_GMOCK_GMOCK_SPEC_BUILDERS_H_
...@@ -26,13 +26,14 @@ ...@@ -26,13 +26,14 @@
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// Author: wan@google.com (Zhanyong Wan)
// Google Mock - a framework for writing C++ mock classes. // Google Mock - a framework for writing C++ mock classes.
// //
// This is the main header file a user should include. // This is the main header file a user should include.
// GOOGLETEST_CM0002 DO NOT DELETE
#ifndef GMOCK_INCLUDE_GMOCK_GMOCK_H_ #ifndef GMOCK_INCLUDE_GMOCK_GMOCK_H_
#define GMOCK_INCLUDE_GMOCK_GMOCK_H_ #define GMOCK_INCLUDE_GMOCK_GMOCK_H_
......
# Customization Points
The custom directory is an injection point for custom user configurations.
## Header `gmock-port.h`
The following macros can be defined:
### Flag related macros:
* `GMOCK_DECLARE_bool_(name)`
* `GMOCK_DECLARE_int32_(name)`
* `GMOCK_DECLARE_string_(name)`
* `GMOCK_DEFINE_bool_(name, default_val, doc)`
* `GMOCK_DEFINE_int32_(name, default_val, doc)`
* `GMOCK_DEFINE_string_(name, default_val, doc)`
...@@ -2,6 +2,8 @@ ...@@ -2,6 +2,8 @@
// pump.py gmock-generated-actions.h.pump // pump.py gmock-generated-actions.h.pump
// DO NOT EDIT BY HAND!!! // DO NOT EDIT BY HAND!!!
// GOOGLETEST_CM0002 DO NOT DELETE
#ifndef GMOCK_INCLUDE_GMOCK_INTERNAL_CUSTOM_GMOCK_GENERATED_ACTIONS_H_ #ifndef GMOCK_INCLUDE_GMOCK_INTERNAL_CUSTOM_GMOCK_GENERATED_ACTIONS_H_
#define GMOCK_INCLUDE_GMOCK_INTERNAL_CUSTOM_GMOCK_GENERATED_ACTIONS_H_ #define GMOCK_INCLUDE_GMOCK_INTERNAL_CUSTOM_GMOCK_GENERATED_ACTIONS_H_
......
$$ -*- mode: c++; -*- $$ -*- mode: c++; -*-
$$ This is a Pump source file (http://go/pump). Please use Pump to convert $$ This is a Pump source file. Please use Pump to convert
$$ it to callback-actions.h. $$ it to callback-actions.h.
$$ $$
$var max_callback_arity = 5 $var max_callback_arity = 5
$$}} This meta comment fixes auto-indentation in editors. $$}} This meta comment fixes auto-indentation in editors.
// GOOGLETEST_CM0002 DO NOT DELETE
#ifndef GMOCK_INCLUDE_GMOCK_INTERNAL_CUSTOM_GMOCK_GENERATED_ACTIONS_H_ #ifndef GMOCK_INCLUDE_GMOCK_INTERNAL_CUSTOM_GMOCK_GENERATED_ACTIONS_H_
#define GMOCK_INCLUDE_GMOCK_INTERNAL_CUSTOM_GMOCK_GENERATED_ACTIONS_H_ #define GMOCK_INCLUDE_GMOCK_INTERNAL_CUSTOM_GMOCK_GENERATED_ACTIONS_H_
......
...@@ -27,13 +27,10 @@ ...@@ -27,13 +27,10 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// //
// ============================================================ // Injection point for custom user configurations. See README for details
// An installation-specific extension point for gmock-matchers.h.
// ============================================================
// //
// Adds google3 callback support to CallableTraits. // GOOGLETEST_CM0002 DO NOT DELETE
//
#ifndef GMOCK_INCLUDE_GMOCK_INTERNAL_CUSTOM_CALLBACK_MATCHERS_H_
#define GMOCK_INCLUDE_GMOCK_INTERNAL_CUSTOM_CALLBACK_MATCHERS_H_
#endif // GMOCK_INCLUDE_GMOCK_INTERNAL_CUSTOM_CALLBACK_MATCHERS_H_ #ifndef GMOCK_INCLUDE_GMOCK_INTERNAL_CUSTOM_GMOCK_MATCHERS_H_
#define GMOCK_INCLUDE_GMOCK_INTERNAL_CUSTOM_GMOCK_MATCHERS_H_
#endif // GMOCK_INCLUDE_GMOCK_INTERNAL_CUSTOM_GMOCK_MATCHERS_H_
...@@ -27,19 +27,12 @@ ...@@ -27,19 +27,12 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// //
// Injection point for custom user configurations. // Injection point for custom user configurations. See README for details
// The following macros can be defined:
//
// Flag related macros:
// GMOCK_DECLARE_bool_(name)
// GMOCK_DECLARE_int32_(name)
// GMOCK_DECLARE_string_(name)
// GMOCK_DEFINE_bool_(name, default_val, doc)
// GMOCK_DEFINE_int32_(name, default_val, doc)
// GMOCK_DEFINE_string_(name, default_val, doc)
// //
// ** Custom implementation starts here ** // ** Custom implementation starts here **
// GOOGLETEST_CM0002 DO NOT DELETE
#ifndef GMOCK_INCLUDE_GMOCK_INTERNAL_CUSTOM_GMOCK_PORT_H_ #ifndef GMOCK_INCLUDE_GMOCK_INTERNAL_CUSTOM_GMOCK_PORT_H_
#define GMOCK_INCLUDE_GMOCK_INTERNAL_CUSTOM_GMOCK_PORT_H_ #define GMOCK_INCLUDE_GMOCK_INTERNAL_CUSTOM_GMOCK_PORT_H_
......
...@@ -30,14 +30,15 @@ ...@@ -30,14 +30,15 @@
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// Author: wan@google.com (Zhanyong Wan)
// Google Mock - a framework for writing C++ mock classes. // Google Mock - a framework for writing C++ mock classes.
// //
// This file contains template meta-programming utility classes needed // This file contains template meta-programming utility classes needed
// for implementing Google Mock. // for implementing Google Mock.
// GOOGLETEST_CM0002 DO NOT DELETE
#ifndef GMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_GENERATED_INTERNAL_UTILS_H_ #ifndef GMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_GENERATED_INTERNAL_UTILS_H_
#define GMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_GENERATED_INTERNAL_UTILS_H_ #define GMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_GENERATED_INTERNAL_UTILS_H_
......
...@@ -31,14 +31,15 @@ $var n = 10 $$ The maximum arity we support. ...@@ -31,14 +31,15 @@ $var n = 10 $$ The maximum arity we support.
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// Author: wan@google.com (Zhanyong Wan)
// Google Mock - a framework for writing C++ mock classes. // Google Mock - a framework for writing C++ mock classes.
// //
// This file contains template meta-programming utility classes needed // This file contains template meta-programming utility classes needed
// for implementing Google Mock. // for implementing Google Mock.
// GOOGLETEST_CM0002 DO NOT DELETE
#ifndef GMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_GENERATED_INTERNAL_UTILS_H_ #ifndef GMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_GENERATED_INTERNAL_UTILS_H_
#define GMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_GENERATED_INTERNAL_UTILS_H_ #define GMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_GENERATED_INTERNAL_UTILS_H_
......
...@@ -26,8 +26,7 @@ ...@@ -26,8 +26,7 @@
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// Author: wan@google.com (Zhanyong Wan)
// Google Mock - a framework for writing C++ mock classes. // Google Mock - a framework for writing C++ mock classes.
// //
...@@ -35,6 +34,8 @@ ...@@ -35,6 +34,8 @@
// Mock. They are subject to change without notice, so please DO NOT // Mock. They are subject to change without notice, so please DO NOT
// USE THEM IN USER CODE. // USE THEM IN USER CODE.
// GOOGLETEST_CM0002 DO NOT DELETE
#ifndef GMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_INTERNAL_UTILS_H_ #ifndef GMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_INTERNAL_UTILS_H_
#define GMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_INTERNAL_UTILS_H_ #define GMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_INTERNAL_UTILS_H_
...@@ -48,6 +49,14 @@ ...@@ -48,6 +49,14 @@
namespace testing { namespace testing {
namespace internal { namespace internal {
// Silence MSVC C4100 (unreferenced formal parameter) and
// C4805('==': unsafe mix of type 'const int' and type 'const bool')
#ifdef _MSC_VER
# pragma warning(push)
# pragma warning(disable:4100)
# pragma warning(disable:4805)
#endif
// Joins a vector of strings as if they are fields of a tuple; returns // Joins a vector of strings as if they are fields of a tuple; returns
// the joined string. // the joined string.
GTEST_API_ std::string JoinAsTuple(const Strings& fields); GTEST_API_ std::string JoinAsTuple(const Strings& fields);
...@@ -117,9 +126,11 @@ struct LinkedPtrLessThan { ...@@ -117,9 +126,11 @@ struct LinkedPtrLessThan {
// To gcc, // To gcc,
// wchar_t == signed wchar_t != unsigned wchar_t == unsigned int // wchar_t == signed wchar_t != unsigned wchar_t == unsigned int
#ifdef __GNUC__ #ifdef __GNUC__
#if !defined(__WCHAR_UNSIGNED__)
// signed/unsigned wchar_t are valid types. // signed/unsigned wchar_t are valid types.
# define GMOCK_HAS_SIGNED_WCHAR_T_ 1 # define GMOCK_HAS_SIGNED_WCHAR_T_ 1
#endif #endif
#endif
// In what follows, we use the term "kind" to indicate whether a type // In what follows, we use the term "kind" to indicate whether a type
// is bool, an integer type (excluding bool), a floating-point type, // is bool, an integer type (excluding bool), a floating-point type,
...@@ -334,7 +345,22 @@ GTEST_API_ bool LogIsVisible(LogSeverity severity); ...@@ -334,7 +345,22 @@ GTEST_API_ bool LogIsVisible(LogSeverity severity);
GTEST_API_ void Log(LogSeverity severity, const std::string& message, GTEST_API_ void Log(LogSeverity severity, const std::string& message,
int stack_frames_to_skip); int stack_frames_to_skip);
// TODO(wan@google.com): group all type utilities together. // A marker class that is used to resolve parameterless expectations to the
// correct overload. This must not be instantiable, to prevent client code from
// accidentally resolving to the overload; for example:
//
// ON_CALL(mock, Method({}, nullptr))...
//
class WithoutMatchers {
private:
WithoutMatchers() {}
friend GTEST_API_ WithoutMatchers GetWithoutMatchers();
};
// Internal use only: access the singleton instance of WithoutMatchers.
GTEST_API_ WithoutMatchers GetWithoutMatchers();
// FIXME: group all type utilities together.
// Type traits. // Type traits.
...@@ -508,7 +534,7 @@ struct BooleanConstant {}; ...@@ -508,7 +534,7 @@ struct BooleanConstant {};
// Emit an assertion failure due to incorrect DoDefault() usage. Out-of-lined to // Emit an assertion failure due to incorrect DoDefault() usage. Out-of-lined to
// reduce code size. // reduce code size.
void IllegalDoDefault(const char* file, int line); GTEST_API_ void IllegalDoDefault(const char* file, int line);
#if GTEST_LANG_CXX11 #if GTEST_LANG_CXX11
// Helper types for Apply() below. // Helper types for Apply() below.
...@@ -537,6 +563,12 @@ auto Apply(F&& f, Tuple&& args) ...@@ -537,6 +563,12 @@ auto Apply(F&& f, Tuple&& args)
make_int_pack<std::tuple_size<Tuple>::value>()); make_int_pack<std::tuple_size<Tuple>::value>());
} }
#endif #endif
#ifdef _MSC_VER
# pragma warning(pop)
#endif
} // namespace internal } // namespace internal
} // namespace testing } // namespace testing
......
...@@ -26,8 +26,7 @@ ...@@ -26,8 +26,7 @@
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// Author: vadimb@google.com (Vadim Berman)
// //
// Low-level types and utilities for porting Google Mock to various // Low-level types and utilities for porting Google Mock to various
// platforms. All macros ending with _ and symbols defined in an // platforms. All macros ending with _ and symbols defined in an
...@@ -36,6 +35,8 @@ ...@@ -36,6 +35,8 @@
// end with _ are part of Google Mock's public API and can be used by // end with _ are part of Google Mock's public API and can be used by
// code outside Google Mock. // code outside Google Mock.
// GOOGLETEST_CM0002 DO NOT DELETE
#ifndef GMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_PORT_H_ #ifndef GMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_PORT_H_
#define GMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_PORT_H_ #define GMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_PORT_H_
......
The Google Mock class generator is an application that is part of cppclean. The Google Mock class generator is an application that is part of cppclean.
For more information about cppclean, see the README.cppclean file or For more information about cppclean, visit http://code.google.com/p/cppclean/
visit http://code.google.com/p/cppclean/
cppclean requires Python 2.3.5 or later. If you don't have Python installed The mock generator requires Python 2.3.5 or later. If you don't have Python
on your system, you will also need to install it. You can download Python installed on your system, you will also need to install it. You can download
from: http://www.python.org/download/releases/ Python from: http://www.python.org/download/releases/
To use the Google Mock class generator, you need to call it To use the Google Mock class generator, you need to call it
on the command line passing the header file and class for which you want on the command line passing the header file and class for which you want
......
...@@ -242,7 +242,7 @@ class AbstractRpcServer(object): ...@@ -242,7 +242,7 @@ class AbstractRpcServer(object):
The authentication process works as follows: The authentication process works as follows:
1) We get a username and password from the user 1) We get a username and password from the user
2) We use ClientLogin to obtain an AUTH token for the user 2) We use ClientLogin to obtain an AUTH token for the user
(see http://code.google.com/apis/accounts/AuthForInstalledApps.html). (see https://developers.google.com/identity/protocols/AuthForInstalledApps).
3) We pass the auth token to /_ah/login on the server to obtain an 3) We pass the auth token to /_ah/login on the server to obtain an
authentication cookie. If login was successful, it tries to redirect authentication cookie. If login was successful, it tries to redirect
us to the URL we provided. us to the URL we provided.
...@@ -506,7 +506,7 @@ def EncodeMultipartFormData(fields, files): ...@@ -506,7 +506,7 @@ def EncodeMultipartFormData(fields, files):
(content_type, body) ready for httplib.HTTP instance. (content_type, body) ready for httplib.HTTP instance.
Source: Source:
http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/146306 https://web.archive.org/web/20160116052001/code.activestate.com/recipes/146306
""" """
BOUNDARY = '-M-A-G-I-C---B-O-U-N-D-A-R-Y-' BOUNDARY = '-M-A-G-I-C---B-O-U-N-D-A-R-Y-'
CRLF = '\r\n' CRLF = '\r\n'
...@@ -807,7 +807,7 @@ class SubversionVCS(VersionControlSystem): ...@@ -807,7 +807,7 @@ class SubversionVCS(VersionControlSystem):
# svn cat translates keywords but svn diff doesn't. As a result of this # svn cat translates keywords but svn diff doesn't. As a result of this
# behavior patching.PatchChunks() fails with a chunk mismatch error. # behavior patching.PatchChunks() fails with a chunk mismatch error.
# This part was originally written by the Review Board development team # This part was originally written by the Review Board development team
# who had the same problem (http://reviews.review-board.org/r/276/). # who had the same problem (https://reviews.reviewboard.org/r/276/).
# Mapping of keywords to known aliases # Mapping of keywords to known aliases
svn_keywords = { svn_keywords = {
# Standard keywords # Standard keywords
...@@ -860,7 +860,7 @@ class SubversionVCS(VersionControlSystem): ...@@ -860,7 +860,7 @@ class SubversionVCS(VersionControlSystem):
status_lines = status.splitlines() status_lines = status.splitlines()
# If file is in a cl, the output will begin with # If file is in a cl, the output will begin with
# "\n--- Changelist 'cl_name':\n". See # "\n--- Changelist 'cl_name':\n". See
# http://svn.collab.net/repos/svn/trunk/notes/changelist-design.txt # https://web.archive.org/web/20090918234815/svn.collab.net/repos/svn/trunk/notes/changelist-design.txt
if (len(status_lines) == 3 and if (len(status_lines) == 3 and
not status_lines[0] and not status_lines[0] and
status_lines[1].startswith("--- Changelist")): status_lines[1].startswith("--- Changelist")):
......
...@@ -26,8 +26,7 @@ ...@@ -26,8 +26,7 @@
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// Author: wan@google.com (Zhanyong Wan)
// //
// Google C++ Mocking Framework (Google Mock) // Google C++ Mocking Framework (Google Mock)
// //
......
...@@ -26,8 +26,7 @@ ...@@ -26,8 +26,7 @@
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// Author: wan@google.com (Zhanyong Wan)
// Google Mock - a framework for writing C++ mock classes. // Google Mock - a framework for writing C++ mock classes.
// //
......
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