Page Menu
Home
c4science
Search
Configure Global Search
Log In
Files
F98341287
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Subscribers
None
File Metadata
Details
File Info
Storage
Attached
Created
Sun, Jan 12, 06:46
Size
124 KB
Mime Type
text/x-diff
Expires
Tue, Jan 14, 06:46 (1 d, 11 h)
Engine
blob
Format
Raw Data
Handle
23564851
Attached To
R9484 sp4e-homework-lars-bertil
View Options
diff --git a/test/gmock-actions_test.cc b/test/gmock-actions_test.cc
index 1210d464..68bdadee 100644
--- a/test/gmock-actions_test.cc
+++ b/test/gmock-actions_test.cc
@@ -1,1312 +1,1256 @@
// Copyright 2007, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// 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.
//
// This file tests the built-in actions.
#include "gmock/gmock-actions.h"
#include <algorithm>
#include <iterator>
#include <string>
#include "gmock/gmock.h"
#include "gmock/internal/gmock-port.h"
#include "gtest/gtest.h"
#include "gtest/gtest-spi.h"
namespace {
using ::std::tr1::get;
using ::std::tr1::make_tuple;
using ::std::tr1::tuple;
using ::std::tr1::tuple_element;
using testing::internal::BuiltInDefaultValue;
using testing::internal::Int64;
using testing::internal::UInt64;
// This list should be kept sorted.
using testing::_;
using testing::Action;
using testing::ActionInterface;
using testing::Assign;
using testing::ByRef;
using testing::DefaultValue;
using testing::DoDefault;
using testing::IgnoreResult;
using testing::Invoke;
using testing::InvokeWithoutArgs;
using testing::MakePolymorphicAction;
using testing::Ne;
using testing::PolymorphicAction;
using testing::Return;
using testing::ReturnNull;
using testing::ReturnRef;
using testing::ReturnRefOfCopy;
using testing::SetArgPointee;
using testing::SetArgumentPointee;
#if !GTEST_OS_WINDOWS_MOBILE
using testing::SetErrnoAndReturn;
#endif
#if GTEST_HAS_PROTOBUF_
using testing::internal::TestMessage;
#endif // GTEST_HAS_PROTOBUF_
// Tests that BuiltInDefaultValue<T*>::Get() returns NULL.
TEST(BuiltInDefaultValueTest, IsNullForPointerTypes) {
EXPECT_TRUE(BuiltInDefaultValue<int*>::Get() == NULL);
EXPECT_TRUE(BuiltInDefaultValue<const char*>::Get() == NULL);
EXPECT_TRUE(BuiltInDefaultValue<void*>::Get() == NULL);
}
// Tests that BuiltInDefaultValue<T*>::Exists() return true.
TEST(BuiltInDefaultValueTest, ExistsForPointerTypes) {
EXPECT_TRUE(BuiltInDefaultValue<int*>::Exists());
EXPECT_TRUE(BuiltInDefaultValue<const char*>::Exists());
EXPECT_TRUE(BuiltInDefaultValue<void*>::Exists());
}
// Tests that BuiltInDefaultValue<T>::Get() returns 0 when T is a
// built-in numeric type.
TEST(BuiltInDefaultValueTest, IsZeroForNumericTypes) {
EXPECT_EQ(0U, BuiltInDefaultValue<unsigned char>::Get());
EXPECT_EQ(0, BuiltInDefaultValue<signed char>::Get());
EXPECT_EQ(0, BuiltInDefaultValue<char>::Get());
#if GMOCK_HAS_SIGNED_WCHAR_T_
EXPECT_EQ(0U, BuiltInDefaultValue<unsigned wchar_t>::Get());
EXPECT_EQ(0, BuiltInDefaultValue<signed wchar_t>::Get());
#endif
#if GMOCK_WCHAR_T_IS_NATIVE_
EXPECT_EQ(0, BuiltInDefaultValue<wchar_t>::Get());
#endif
EXPECT_EQ(0U, BuiltInDefaultValue<unsigned short>::Get()); // NOLINT
EXPECT_EQ(0, BuiltInDefaultValue<signed short>::Get()); // NOLINT
EXPECT_EQ(0, BuiltInDefaultValue<short>::Get()); // NOLINT
EXPECT_EQ(0U, BuiltInDefaultValue<unsigned int>::Get());
EXPECT_EQ(0, BuiltInDefaultValue<signed int>::Get());
EXPECT_EQ(0, BuiltInDefaultValue<int>::Get());
EXPECT_EQ(0U, BuiltInDefaultValue<unsigned long>::Get()); // NOLINT
EXPECT_EQ(0, BuiltInDefaultValue<signed long>::Get()); // NOLINT
EXPECT_EQ(0, BuiltInDefaultValue<long>::Get()); // NOLINT
EXPECT_EQ(0U, BuiltInDefaultValue<UInt64>::Get());
EXPECT_EQ(0, BuiltInDefaultValue<Int64>::Get());
EXPECT_EQ(0, BuiltInDefaultValue<float>::Get());
EXPECT_EQ(0, BuiltInDefaultValue<double>::Get());
}
// Tests that BuiltInDefaultValue<T>::Exists() returns true when T is a
// built-in numeric type.
TEST(BuiltInDefaultValueTest, ExistsForNumericTypes) {
EXPECT_TRUE(BuiltInDefaultValue<unsigned char>::Exists());
EXPECT_TRUE(BuiltInDefaultValue<signed char>::Exists());
EXPECT_TRUE(BuiltInDefaultValue<char>::Exists());
#if GMOCK_HAS_SIGNED_WCHAR_T_
EXPECT_TRUE(BuiltInDefaultValue<unsigned wchar_t>::Exists());
EXPECT_TRUE(BuiltInDefaultValue<signed wchar_t>::Exists());
#endif
#if GMOCK_WCHAR_T_IS_NATIVE_
EXPECT_TRUE(BuiltInDefaultValue<wchar_t>::Exists());
#endif
EXPECT_TRUE(BuiltInDefaultValue<unsigned short>::Exists()); // NOLINT
EXPECT_TRUE(BuiltInDefaultValue<signed short>::Exists()); // NOLINT
EXPECT_TRUE(BuiltInDefaultValue<short>::Exists()); // NOLINT
EXPECT_TRUE(BuiltInDefaultValue<unsigned int>::Exists());
EXPECT_TRUE(BuiltInDefaultValue<signed int>::Exists());
EXPECT_TRUE(BuiltInDefaultValue<int>::Exists());
EXPECT_TRUE(BuiltInDefaultValue<unsigned long>::Exists()); // NOLINT
EXPECT_TRUE(BuiltInDefaultValue<signed long>::Exists()); // NOLINT
EXPECT_TRUE(BuiltInDefaultValue<long>::Exists()); // NOLINT
EXPECT_TRUE(BuiltInDefaultValue<UInt64>::Exists());
EXPECT_TRUE(BuiltInDefaultValue<Int64>::Exists());
EXPECT_TRUE(BuiltInDefaultValue<float>::Exists());
EXPECT_TRUE(BuiltInDefaultValue<double>::Exists());
}
// Tests that BuiltInDefaultValue<bool>::Get() returns false.
TEST(BuiltInDefaultValueTest, IsFalseForBool) {
EXPECT_FALSE(BuiltInDefaultValue<bool>::Get());
}
// Tests that BuiltInDefaultValue<bool>::Exists() returns true.
TEST(BuiltInDefaultValueTest, BoolExists) {
EXPECT_TRUE(BuiltInDefaultValue<bool>::Exists());
}
// Tests that BuiltInDefaultValue<T>::Get() returns "" when T is a
// string type.
TEST(BuiltInDefaultValueTest, IsEmptyStringForString) {
#if GTEST_HAS_GLOBAL_STRING
EXPECT_EQ("", BuiltInDefaultValue< ::string>::Get());
#endif // GTEST_HAS_GLOBAL_STRING
EXPECT_EQ("", BuiltInDefaultValue< ::std::string>::Get());
}
// Tests that BuiltInDefaultValue<T>::Exists() returns true when T is a
// string type.
TEST(BuiltInDefaultValueTest, ExistsForString) {
#if GTEST_HAS_GLOBAL_STRING
EXPECT_TRUE(BuiltInDefaultValue< ::string>::Exists());
#endif // GTEST_HAS_GLOBAL_STRING
EXPECT_TRUE(BuiltInDefaultValue< ::std::string>::Exists());
}
// Tests that BuiltInDefaultValue<const T>::Get() returns the same
// value as BuiltInDefaultValue<T>::Get() does.
TEST(BuiltInDefaultValueTest, WorksForConstTypes) {
EXPECT_EQ("", BuiltInDefaultValue<const std::string>::Get());
EXPECT_EQ(0, BuiltInDefaultValue<const int>::Get());
EXPECT_TRUE(BuiltInDefaultValue<char* const>::Get() == NULL);
EXPECT_FALSE(BuiltInDefaultValue<const bool>::Get());
}
// Tests that BuiltInDefaultValue<T>::Get() aborts the program with
// the correct error message when T is a user-defined type.
struct UserType {
UserType() : value(0) {}
int value;
};
TEST(BuiltInDefaultValueTest, UserTypeHasNoDefault) {
EXPECT_FALSE(BuiltInDefaultValue<UserType>::Exists());
}
// Tests that BuiltInDefaultValue<T&>::Get() aborts the program.
TEST(BuiltInDefaultValueDeathTest, IsUndefinedForReferences) {
EXPECT_DEATH_IF_SUPPORTED({
BuiltInDefaultValue<int&>::Get();
}, "");
EXPECT_DEATH_IF_SUPPORTED({
BuiltInDefaultValue<const char&>::Get();
}, "");
}
TEST(BuiltInDefaultValueDeathTest, IsUndefinedForUserTypes) {
EXPECT_DEATH_IF_SUPPORTED({
BuiltInDefaultValue<UserType>::Get();
}, "");
}
// Tests that DefaultValue<T>::IsSet() is false initially.
TEST(DefaultValueTest, IsInitiallyUnset) {
EXPECT_FALSE(DefaultValue<int>::IsSet());
EXPECT_FALSE(DefaultValue<const UserType>::IsSet());
}
// Tests that DefaultValue<T> can be set and then unset.
TEST(DefaultValueTest, CanBeSetAndUnset) {
EXPECT_TRUE(DefaultValue<int>::Exists());
EXPECT_FALSE(DefaultValue<const UserType>::Exists());
DefaultValue<int>::Set(1);
DefaultValue<const UserType>::Set(UserType());
EXPECT_EQ(1, DefaultValue<int>::Get());
EXPECT_EQ(0, DefaultValue<const UserType>::Get().value);
EXPECT_TRUE(DefaultValue<int>::Exists());
EXPECT_TRUE(DefaultValue<const UserType>::Exists());
DefaultValue<int>::Clear();
DefaultValue<const UserType>::Clear();
EXPECT_FALSE(DefaultValue<int>::IsSet());
EXPECT_FALSE(DefaultValue<const UserType>::IsSet());
EXPECT_TRUE(DefaultValue<int>::Exists());
EXPECT_FALSE(DefaultValue<const UserType>::Exists());
}
// Tests that DefaultValue<T>::Get() returns the
// BuiltInDefaultValue<T>::Get() when DefaultValue<T>::IsSet() is
// false.
TEST(DefaultValueDeathTest, GetReturnsBuiltInDefaultValueWhenUnset) {
EXPECT_FALSE(DefaultValue<int>::IsSet());
EXPECT_TRUE(DefaultValue<int>::Exists());
EXPECT_FALSE(DefaultValue<UserType>::IsSet());
EXPECT_FALSE(DefaultValue<UserType>::Exists());
EXPECT_EQ(0, DefaultValue<int>::Get());
EXPECT_DEATH_IF_SUPPORTED({
DefaultValue<UserType>::Get();
}, "");
}
// Tests that DefaultValue<void>::Get() returns void.
TEST(DefaultValueTest, GetWorksForVoid) {
return DefaultValue<void>::Get();
}
// Tests using DefaultValue with a reference type.
// Tests that DefaultValue<T&>::IsSet() is false initially.
TEST(DefaultValueOfReferenceTest, IsInitiallyUnset) {
EXPECT_FALSE(DefaultValue<int&>::IsSet());
EXPECT_FALSE(DefaultValue<UserType&>::IsSet());
}
// Tests that DefaultValue<T&>::Exists is false initiallly.
TEST(DefaultValueOfReferenceTest, IsInitiallyNotExisting) {
EXPECT_FALSE(DefaultValue<int&>::Exists());
EXPECT_FALSE(DefaultValue<UserType&>::Exists());
}
// Tests that DefaultValue<T&> can be set and then unset.
TEST(DefaultValueOfReferenceTest, CanBeSetAndUnset) {
int n = 1;
DefaultValue<const int&>::Set(n);
UserType u;
DefaultValue<UserType&>::Set(u);
EXPECT_TRUE(DefaultValue<const int&>::Exists());
EXPECT_TRUE(DefaultValue<UserType&>::Exists());
EXPECT_EQ(&n, &(DefaultValue<const int&>::Get()));
EXPECT_EQ(&u, &(DefaultValue<UserType&>::Get()));
DefaultValue<const int&>::Clear();
DefaultValue<UserType&>::Clear();
EXPECT_FALSE(DefaultValue<const int&>::Exists());
EXPECT_FALSE(DefaultValue<UserType&>::Exists());
EXPECT_FALSE(DefaultValue<const int&>::IsSet());
EXPECT_FALSE(DefaultValue<UserType&>::IsSet());
}
// Tests that DefaultValue<T&>::Get() returns the
// BuiltInDefaultValue<T&>::Get() when DefaultValue<T&>::IsSet() is
// false.
TEST(DefaultValueOfReferenceDeathTest, GetReturnsBuiltInDefaultValueWhenUnset) {
EXPECT_FALSE(DefaultValue<int&>::IsSet());
EXPECT_FALSE(DefaultValue<UserType&>::IsSet());
EXPECT_DEATH_IF_SUPPORTED({
DefaultValue<int&>::Get();
}, "");
EXPECT_DEATH_IF_SUPPORTED({
DefaultValue<UserType>::Get();
}, "");
}
// Tests that ActionInterface can be implemented by defining the
// Perform method.
typedef int MyFunction(bool, int);
class MyActionImpl : public ActionInterface<MyFunction> {
public:
virtual int Perform(const tuple<bool, int>& args) {
return get<0>(args) ? get<1>(args) : 0;
}
};
TEST(ActionInterfaceTest, CanBeImplementedByDefiningPerform) {
MyActionImpl my_action_impl;
(void)my_action_impl;
}
TEST(ActionInterfaceTest, MakeAction) {
Action<MyFunction> action = MakeAction(new MyActionImpl);
// When exercising the Perform() method of Action<F>, we must pass
// it a tuple whose size and type are compatible with F's argument
// types. For example, if F is int(), then Perform() takes a
// 0-tuple; if F is void(bool, int), then Perform() takes a
// tuple<bool, int>, and so on.
EXPECT_EQ(5, action.Perform(make_tuple(true, 5)));
}
// Tests that Action<F> can be contructed from a pointer to
// ActionInterface<F>.
TEST(ActionTest, CanBeConstructedFromActionInterface) {
Action<MyFunction> action(new MyActionImpl);
}
// Tests that Action<F> delegates actual work to ActionInterface<F>.
TEST(ActionTest, DelegatesWorkToActionInterface) {
const Action<MyFunction> action(new MyActionImpl);
EXPECT_EQ(5, action.Perform(make_tuple(true, 5)));
EXPECT_EQ(0, action.Perform(make_tuple(false, 1)));
}
// Tests that Action<F> can be copied.
TEST(ActionTest, IsCopyable) {
Action<MyFunction> a1(new MyActionImpl);
Action<MyFunction> a2(a1); // Tests the copy constructor.
// a1 should continue to work after being copied from.
EXPECT_EQ(5, a1.Perform(make_tuple(true, 5)));
EXPECT_EQ(0, a1.Perform(make_tuple(false, 1)));
// a2 should work like the action it was copied from.
EXPECT_EQ(5, a2.Perform(make_tuple(true, 5)));
EXPECT_EQ(0, a2.Perform(make_tuple(false, 1)));
a2 = a1; // Tests the assignment operator.
// a1 should continue to work after being copied from.
EXPECT_EQ(5, a1.Perform(make_tuple(true, 5)));
EXPECT_EQ(0, a1.Perform(make_tuple(false, 1)));
// a2 should work like the action it was copied from.
EXPECT_EQ(5, a2.Perform(make_tuple(true, 5)));
EXPECT_EQ(0, a2.Perform(make_tuple(false, 1)));
}
// Tests that an Action<From> object can be converted to a
// compatible Action<To> object.
class IsNotZero : public ActionInterface<bool(int)> { // NOLINT
public:
virtual bool Perform(const tuple<int>& arg) {
return get<0>(arg) != 0;
}
};
#if !GTEST_OS_SYMBIAN
// Compiling this test on Nokia's Symbian compiler fails with:
// 'Result' is not a member of class 'testing::internal::Function<int>'
// (point of instantiation: '@unnamed@gmock_actions_test_cc@::
// ActionTest_CanBeConvertedToOtherActionType_Test::TestBody()')
// with no obvious fix.
TEST(ActionTest, CanBeConvertedToOtherActionType) {
const Action<bool(int)> a1(new IsNotZero); // NOLINT
const Action<int(char)> a2 = Action<int(char)>(a1); // NOLINT
EXPECT_EQ(1, a2.Perform(make_tuple('a')));
EXPECT_EQ(0, a2.Perform(make_tuple('\0')));
}
#endif // !GTEST_OS_SYMBIAN
// The following two classes are for testing MakePolymorphicAction().
// Implements a polymorphic action that returns the second of the
// arguments it receives.
class ReturnSecondArgumentAction {
public:
// We want to verify that MakePolymorphicAction() can work with a
// polymorphic action whose Perform() method template is either
// const or not. This lets us verify the non-const case.
template <typename Result, typename ArgumentTuple>
Result Perform(const ArgumentTuple& args) { return get<1>(args); }
};
// Implements a polymorphic action that can be used in a nullary
// function to return 0.
class ReturnZeroFromNullaryFunctionAction {
public:
// For testing that MakePolymorphicAction() works when the
// implementation class' Perform() method template takes only one
// template parameter.
//
// We want to verify that MakePolymorphicAction() can work with a
// polymorphic action whose Perform() method template is either
// const or not. This lets us verify the const case.
template <typename Result>
Result Perform(const tuple<>&) const { return 0; }
};
// These functions verify that MakePolymorphicAction() returns a
// PolymorphicAction<T> where T is the argument's type.
PolymorphicAction<ReturnSecondArgumentAction> ReturnSecondArgument() {
return MakePolymorphicAction(ReturnSecondArgumentAction());
}
PolymorphicAction<ReturnZeroFromNullaryFunctionAction>
ReturnZeroFromNullaryFunction() {
return MakePolymorphicAction(ReturnZeroFromNullaryFunctionAction());
}
// Tests that MakePolymorphicAction() turns a polymorphic action
// implementation class into a polymorphic action.
TEST(MakePolymorphicActionTest, ConstructsActionFromImpl) {
Action<int(bool, int, double)> a1 = ReturnSecondArgument(); // NOLINT
EXPECT_EQ(5, a1.Perform(make_tuple(false, 5, 2.0)));
}
// Tests that MakePolymorphicAction() works when the implementation
// class' Perform() method template has only one template parameter.
TEST(MakePolymorphicActionTest, WorksWhenPerformHasOneTemplateParameter) {
Action<int()> a1 = ReturnZeroFromNullaryFunction();
EXPECT_EQ(0, a1.Perform(make_tuple()));
Action<void*()> a2 = ReturnZeroFromNullaryFunction();
EXPECT_TRUE(a2.Perform(make_tuple()) == NULL);
}
// Tests that Return() works as an action for void-returning
// functions.
TEST(ReturnTest, WorksForVoid) {
const Action<void(int)> ret = Return(); // NOLINT
return ret.Perform(make_tuple(1));
}
// Tests that Return(v) returns v.
TEST(ReturnTest, ReturnsGivenValue) {
Action<int()> ret = Return(1); // NOLINT
EXPECT_EQ(1, ret.Perform(make_tuple()));
ret = Return(-5);
EXPECT_EQ(-5, ret.Perform(make_tuple()));
}
// Tests that Return("string literal") works.
TEST(ReturnTest, AcceptsStringLiteral) {
Action<const char*()> a1 = Return("Hello");
EXPECT_STREQ("Hello", a1.Perform(make_tuple()));
Action<std::string()> a2 = Return("world");
EXPECT_EQ("world", a2.Perform(make_tuple()));
}
// Tests that Return(v) is covaraint.
struct Base {
bool operator==(const Base&) { return true; }
};
struct Derived : public Base {
bool operator==(const Derived&) { return true; }
};
TEST(ReturnTest, IsCovariant) {
Base base;
Derived derived;
Action<Base*()> ret = Return(&base);
EXPECT_EQ(&base, ret.Perform(make_tuple()));
ret = Return(&derived);
EXPECT_EQ(&derived, ret.Perform(make_tuple()));
}
// Tests that the type of the value passed into Return is converted into T
// when the action is cast to Action<T(...)> rather than when the action is
// performed. See comments on testing::internal::ReturnAction in
// gmock-actions.h for more information.
class FromType {
public:
explicit FromType(bool* is_converted) : converted_(is_converted) {}
bool* converted() const { return converted_; }
private:
bool* const converted_;
GTEST_DISALLOW_ASSIGN_(FromType);
};
class ToType {
public:
// Must allow implicit conversion due to use in ImplicitCast_<T>.
ToType(const FromType& x) { *x.converted() = true; } // NOLINT
};
TEST(ReturnTest, ConvertsArgumentWhenConverted) {
bool converted = false;
FromType x(&converted);
Action<ToType()> action(Return(x));
EXPECT_TRUE(converted) << "Return must convert its argument in its own "
<< "conversion operator.";
converted = false;
action.Perform(tuple<>());
EXPECT_FALSE(converted) << "Action must NOT convert its argument "
<< "when performed.";
}
class DestinationType {};
class SourceType {
public:
// Note: a non-const typecast operator.
operator DestinationType() { return DestinationType(); }
};
TEST(ReturnTest, CanConvertArgumentUsingNonConstTypeCastOperator) {
SourceType s;
Action<DestinationType()> action(Return(s));
}
// Tests that ReturnNull() returns NULL in a pointer-returning function.
TEST(ReturnNullTest, WorksInPointerReturningFunction) {
const Action<int*()> a1 = ReturnNull();
EXPECT_TRUE(a1.Perform(make_tuple()) == NULL);
const Action<const char*(bool)> a2 = ReturnNull(); // NOLINT
EXPECT_TRUE(a2.Perform(make_tuple(true)) == NULL);
}
// Tests that ReturnRef(v) works for reference types.
TEST(ReturnRefTest, WorksForReference) {
const int n = 0;
const Action<const int&(bool)> ret = ReturnRef(n); // NOLINT
EXPECT_EQ(&n, &ret.Perform(make_tuple(true)));
}
// Tests that ReturnRef(v) is covariant.
TEST(ReturnRefTest, IsCovariant) {
Base base;
Derived derived;
Action<Base&()> a = ReturnRef(base);
EXPECT_EQ(&base, &a.Perform(make_tuple()));
a = ReturnRef(derived);
EXPECT_EQ(&derived, &a.Perform(make_tuple()));
}
// Tests that ReturnRefOfCopy(v) works for reference types.
TEST(ReturnRefOfCopyTest, WorksForReference) {
int n = 42;
const Action<const int&()> ret = ReturnRefOfCopy(n);
EXPECT_NE(&n, &ret.Perform(make_tuple()));
EXPECT_EQ(42, ret.Perform(make_tuple()));
n = 43;
EXPECT_NE(&n, &ret.Perform(make_tuple()));
EXPECT_EQ(42, ret.Perform(make_tuple()));
}
// Tests that ReturnRefOfCopy(v) is covariant.
TEST(ReturnRefOfCopyTest, IsCovariant) {
Base base;
Derived derived;
Action<Base&()> a = ReturnRefOfCopy(base);
EXPECT_NE(&base, &a.Perform(make_tuple()));
a = ReturnRefOfCopy(derived);
EXPECT_NE(&derived, &a.Perform(make_tuple()));
}
// Tests that DoDefault() does the default action for the mock method.
class MyClass {};
class MockClass {
public:
MockClass() {}
MOCK_METHOD1(IntFunc, int(bool flag)); // NOLINT
MOCK_METHOD0(Foo, MyClass());
private:
GTEST_DISALLOW_COPY_AND_ASSIGN_(MockClass);
};
// Tests that DoDefault() returns the built-in default value for the
// return type by default.
TEST(DoDefaultTest, ReturnsBuiltInDefaultValueByDefault) {
MockClass mock;
EXPECT_CALL(mock, IntFunc(_))
.WillOnce(DoDefault());
EXPECT_EQ(0, mock.IntFunc(true));
}
// Tests that DoDefault() throws (when exceptions are enabled) or aborts
// the process when there is no built-in default value for the return type.
TEST(DoDefaultDeathTest, DiesForUnknowType) {
MockClass mock;
EXPECT_CALL(mock, Foo())
.WillRepeatedly(DoDefault());
#if GTEST_HAS_EXCEPTIONS
EXPECT_ANY_THROW(mock.Foo());
#else
EXPECT_DEATH_IF_SUPPORTED({
mock.Foo();
}, "");
#endif
}
// Tests that using DoDefault() inside a composite action leads to a
// run-time error.
void VoidFunc(bool /* flag */) {}
TEST(DoDefaultDeathTest, DiesIfUsedInCompositeAction) {
MockClass mock;
EXPECT_CALL(mock, IntFunc(_))
.WillRepeatedly(DoAll(Invoke(VoidFunc),
DoDefault()));
// Ideally we should verify the error message as well. Sadly,
// EXPECT_DEATH() can only capture stderr, while Google Mock's
// errors are printed on stdout. Therefore we have to settle for
// not verifying the message.
EXPECT_DEATH_IF_SUPPORTED({
mock.IntFunc(true);
}, "");
}
// Tests that DoDefault() returns the default value set by
// DefaultValue<T>::Set() when it's not overriden by an ON_CALL().
TEST(DoDefaultTest, ReturnsUserSpecifiedPerTypeDefaultValueWhenThereIsOne) {
DefaultValue<int>::Set(1);
MockClass mock;
EXPECT_CALL(mock, IntFunc(_))
.WillOnce(DoDefault());
EXPECT_EQ(1, mock.IntFunc(false));
DefaultValue<int>::Clear();
}
// Tests that DoDefault() does the action specified by ON_CALL().
TEST(DoDefaultTest, DoesWhatOnCallSpecifies) {
MockClass mock;
ON_CALL(mock, IntFunc(_))
.WillByDefault(Return(2));
EXPECT_CALL(mock, IntFunc(_))
.WillOnce(DoDefault());
EXPECT_EQ(2, mock.IntFunc(false));
}
// Tests that using DoDefault() in ON_CALL() leads to a run-time failure.
TEST(DoDefaultTest, CannotBeUsedInOnCall) {
MockClass mock;
EXPECT_NONFATAL_FAILURE({ // NOLINT
ON_CALL(mock, IntFunc(_))
.WillByDefault(DoDefault());
}, "DoDefault() cannot be used in ON_CALL()");
}
// Tests that SetArgPointee<N>(v) sets the variable pointed to by
// the N-th (0-based) argument to v.
TEST(SetArgPointeeTest, SetsTheNthPointee) {
typedef void MyFunction(bool, int*, char*);
Action<MyFunction> a = SetArgPointee<1>(2);
int n = 0;
char ch = '\0';
a.Perform(make_tuple(true, &n, &ch));
EXPECT_EQ(2, n);
EXPECT_EQ('\0', ch);
a = SetArgPointee<2>('a');
n = 0;
ch = '\0';
a.Perform(make_tuple(true, &n, &ch));
EXPECT_EQ(0, n);
EXPECT_EQ('a', ch);
}
#if !((GTEST_GCC_VER_ && GTEST_GCC_VER_ < 40000) || GTEST_OS_SYMBIAN)
// Tests that SetArgPointee<N>() accepts a string literal.
// GCC prior to v4.0 and the Symbian compiler do not support this.
TEST(SetArgPointeeTest, AcceptsStringLiteral) {
typedef void MyFunction(std::string*, const char**);
Action<MyFunction> a = SetArgPointee<0>("hi");
std::string str;
const char* ptr = NULL;
a.Perform(make_tuple(&str, &ptr));
EXPECT_EQ("hi", str);
EXPECT_TRUE(ptr == NULL);
a = SetArgPointee<1>("world");
str = "";
a.Perform(make_tuple(&str, &ptr));
EXPECT_EQ("", str);
EXPECT_STREQ("world", ptr);
}
TEST(SetArgPointeeTest, AcceptsWideStringLiteral) {
typedef void MyFunction(const wchar_t**);
Action<MyFunction> a = SetArgPointee<0>(L"world");
const wchar_t* ptr = NULL;
a.Perform(make_tuple(&ptr));
EXPECT_STREQ(L"world", ptr);
# if GTEST_HAS_STD_WSTRING
typedef void MyStringFunction(std::wstring*);
Action<MyStringFunction> a2 = SetArgPointee<0>(L"world");
std::wstring str = L"";
a2.Perform(make_tuple(&str));
EXPECT_EQ(L"world", str);
# endif
}
#endif
// Tests that SetArgPointee<N>() accepts a char pointer.
TEST(SetArgPointeeTest, AcceptsCharPointer) {
typedef void MyFunction(bool, std::string*, const char**);
const char* const hi = "hi";
Action<MyFunction> a = SetArgPointee<1>(hi);
std::string str;
const char* ptr = NULL;
a.Perform(make_tuple(true, &str, &ptr));
EXPECT_EQ("hi", str);
EXPECT_TRUE(ptr == NULL);
char world_array[] = "world";
char* const world = world_array;
a = SetArgPointee<2>(world);
str = "";
a.Perform(make_tuple(true, &str, &ptr));
EXPECT_EQ("", str);
EXPECT_EQ(world, ptr);
}
TEST(SetArgPointeeTest, AcceptsWideCharPointer) {
typedef void MyFunction(bool, const wchar_t**);
const wchar_t* const hi = L"hi";
Action<MyFunction> a = SetArgPointee<1>(hi);
const wchar_t* ptr = NULL;
a.Perform(make_tuple(true, &ptr));
EXPECT_EQ(hi, ptr);
# if GTEST_HAS_STD_WSTRING
typedef void MyStringFunction(bool, std::wstring*);
wchar_t world_array[] = L"world";
wchar_t* const world = world_array;
Action<MyStringFunction> a2 = SetArgPointee<1>(world);
std::wstring str;
a2.Perform(make_tuple(true, &str));
EXPECT_EQ(world_array, str);
# endif
}
#if GTEST_HAS_PROTOBUF_
// Tests that SetArgPointee<N>(proto_buffer) sets the v1 protobuf
// variable pointed to by the N-th (0-based) argument to proto_buffer.
TEST(SetArgPointeeTest, SetsTheNthPointeeOfProtoBufferType) {
TestMessage* const msg = new TestMessage;
msg->set_member("yes");
TestMessage orig_msg;
orig_msg.CopyFrom(*msg);
Action<void(bool, TestMessage*)> a = SetArgPointee<1>(*msg);
// SetArgPointee<N>(proto_buffer) makes a copy of proto_buffer
// s.t. the action works even when the original proto_buffer has
// died. We ensure this behavior by deleting msg before using the
// action.
delete msg;
TestMessage dest;
EXPECT_FALSE(orig_msg.Equals(dest));
a.Perform(make_tuple(true, &dest));
EXPECT_TRUE(orig_msg.Equals(dest));
}
// Tests that SetArgPointee<N>(proto_buffer) sets the
// ::ProtocolMessage variable pointed to by the N-th (0-based)
// argument to proto_buffer.
TEST(SetArgPointeeTest, SetsTheNthPointeeOfProtoBufferBaseType) {
TestMessage* const msg = new TestMessage;
msg->set_member("yes");
TestMessage orig_msg;
orig_msg.CopyFrom(*msg);
Action<void(bool, ::ProtocolMessage*)> a = SetArgPointee<1>(*msg);
// SetArgPointee<N>(proto_buffer) makes a copy of proto_buffer
// s.t. the action works even when the original proto_buffer has
// died. We ensure this behavior by deleting msg before using the
// action.
delete msg;
TestMessage dest;
::ProtocolMessage* const dest_base = &dest;
EXPECT_FALSE(orig_msg.Equals(dest));
a.Perform(make_tuple(true, dest_base));
EXPECT_TRUE(orig_msg.Equals(dest));
}
// Tests that SetArgPointee<N>(proto2_buffer) sets the v2
// protobuf variable pointed to by the N-th (0-based) argument to
// proto2_buffer.
TEST(SetArgPointeeTest, SetsTheNthPointeeOfProto2BufferType) {
using testing::internal::FooMessage;
FooMessage* const msg = new FooMessage;
msg->set_int_field(2);
msg->set_string_field("hi");
FooMessage orig_msg;
orig_msg.CopyFrom(*msg);
Action<void(bool, FooMessage*)> a = SetArgPointee<1>(*msg);
// SetArgPointee<N>(proto2_buffer) makes a copy of
// proto2_buffer s.t. the action works even when the original
// proto2_buffer has died. We ensure this behavior by deleting msg
// before using the action.
delete msg;
FooMessage dest;
dest.set_int_field(0);
a.Perform(make_tuple(true, &dest));
EXPECT_EQ(2, dest.int_field());
EXPECT_EQ("hi", dest.string_field());
}
// Tests that SetArgPointee<N>(proto2_buffer) sets the
// proto2::Message variable pointed to by the N-th (0-based) argument
// to proto2_buffer.
TEST(SetArgPointeeTest, SetsTheNthPointeeOfProto2BufferBaseType) {
using testing::internal::FooMessage;
FooMessage* const msg = new FooMessage;
msg->set_int_field(2);
msg->set_string_field("hi");
FooMessage orig_msg;
orig_msg.CopyFrom(*msg);
Action<void(bool, ::proto2::Message*)> a = SetArgPointee<1>(*msg);
// SetArgPointee<N>(proto2_buffer) makes a copy of
// proto2_buffer s.t. the action works even when the original
// proto2_buffer has died. We ensure this behavior by deleting msg
// before using the action.
delete msg;
FooMessage dest;
dest.set_int_field(0);
::proto2::Message* const dest_base = &dest;
a.Perform(make_tuple(true, dest_base));
EXPECT_EQ(2, dest.int_field());
EXPECT_EQ("hi", dest.string_field());
}
#endif // GTEST_HAS_PROTOBUF_
// Tests that SetArgumentPointee<N>(v) sets the variable pointed to by
// the N-th (0-based) argument to v.
TEST(SetArgumentPointeeTest, SetsTheNthPointee) {
typedef void MyFunction(bool, int*, char*);
Action<MyFunction> a = SetArgumentPointee<1>(2);
int n = 0;
char ch = '\0';
a.Perform(make_tuple(true, &n, &ch));
EXPECT_EQ(2, n);
EXPECT_EQ('\0', ch);
a = SetArgumentPointee<2>('a');
n = 0;
ch = '\0';
a.Perform(make_tuple(true, &n, &ch));
EXPECT_EQ(0, n);
EXPECT_EQ('a', ch);
}
#if GTEST_HAS_PROTOBUF_
// Tests that SetArgumentPointee<N>(proto_buffer) sets the v1 protobuf
// variable pointed to by the N-th (0-based) argument to proto_buffer.
TEST(SetArgumentPointeeTest, SetsTheNthPointeeOfProtoBufferType) {
TestMessage* const msg = new TestMessage;
msg->set_member("yes");
TestMessage orig_msg;
orig_msg.CopyFrom(*msg);
Action<void(bool, TestMessage*)> a = SetArgumentPointee<1>(*msg);
// SetArgumentPointee<N>(proto_buffer) makes a copy of proto_buffer
// s.t. the action works even when the original proto_buffer has
// died. We ensure this behavior by deleting msg before using the
// action.
delete msg;
TestMessage dest;
EXPECT_FALSE(orig_msg.Equals(dest));
a.Perform(make_tuple(true, &dest));
EXPECT_TRUE(orig_msg.Equals(dest));
}
// Tests that SetArgumentPointee<N>(proto_buffer) sets the
// ::ProtocolMessage variable pointed to by the N-th (0-based)
// argument to proto_buffer.
TEST(SetArgumentPointeeTest, SetsTheNthPointeeOfProtoBufferBaseType) {
TestMessage* const msg = new TestMessage;
msg->set_member("yes");
TestMessage orig_msg;
orig_msg.CopyFrom(*msg);
Action<void(bool, ::ProtocolMessage*)> a = SetArgumentPointee<1>(*msg);
// SetArgumentPointee<N>(proto_buffer) makes a copy of proto_buffer
// s.t. the action works even when the original proto_buffer has
// died. We ensure this behavior by deleting msg before using the
// action.
delete msg;
TestMessage dest;
::ProtocolMessage* const dest_base = &dest;
EXPECT_FALSE(orig_msg.Equals(dest));
a.Perform(make_tuple(true, dest_base));
EXPECT_TRUE(orig_msg.Equals(dest));
}
// Tests that SetArgumentPointee<N>(proto2_buffer) sets the v2
// protobuf variable pointed to by the N-th (0-based) argument to
// proto2_buffer.
TEST(SetArgumentPointeeTest, SetsTheNthPointeeOfProto2BufferType) {
using testing::internal::FooMessage;
FooMessage* const msg = new FooMessage;
msg->set_int_field(2);
msg->set_string_field("hi");
FooMessage orig_msg;
orig_msg.CopyFrom(*msg);
Action<void(bool, FooMessage*)> a = SetArgumentPointee<1>(*msg);
// SetArgumentPointee<N>(proto2_buffer) makes a copy of
// proto2_buffer s.t. the action works even when the original
// proto2_buffer has died. We ensure this behavior by deleting msg
// before using the action.
delete msg;
FooMessage dest;
dest.set_int_field(0);
a.Perform(make_tuple(true, &dest));
EXPECT_EQ(2, dest.int_field());
EXPECT_EQ("hi", dest.string_field());
}
// Tests that SetArgumentPointee<N>(proto2_buffer) sets the
// proto2::Message variable pointed to by the N-th (0-based) argument
// to proto2_buffer.
TEST(SetArgumentPointeeTest, SetsTheNthPointeeOfProto2BufferBaseType) {
using testing::internal::FooMessage;
FooMessage* const msg = new FooMessage;
msg->set_int_field(2);
msg->set_string_field("hi");
FooMessage orig_msg;
orig_msg.CopyFrom(*msg);
Action<void(bool, ::proto2::Message*)> a = SetArgumentPointee<1>(*msg);
// SetArgumentPointee<N>(proto2_buffer) makes a copy of
// proto2_buffer s.t. the action works even when the original
// proto2_buffer has died. We ensure this behavior by deleting msg
// before using the action.
delete msg;
FooMessage dest;
dest.set_int_field(0);
::proto2::Message* const dest_base = &dest;
a.Perform(make_tuple(true, dest_base));
EXPECT_EQ(2, dest.int_field());
EXPECT_EQ("hi", dest.string_field());
}
#endif // GTEST_HAS_PROTOBUF_
// Sample functions and functors for testing Invoke() and etc.
int Nullary() { return 1; }
class NullaryFunctor {
public:
int operator()() { return 2; }
};
bool g_done = false;
void VoidNullary() { g_done = true; }
class VoidNullaryFunctor {
public:
void operator()() { g_done = true; }
};
-bool Unary(int x) { return x < 0; }
-
-const char* Plus1(const char* s) { return s + 1; }
-
-void VoidUnary(int /* n */) { g_done = true; }
-
-bool ByConstRef(const std::string& s) { return s == "Hi"; }
-
-const double g_double = 0;
-bool ReferencesGlobalDouble(const double& x) { return &x == &g_double; }
-
-std::string ByNonConstRef(std::string& s) { return s += "+"; } // NOLINT
-
-struct UnaryFunctor {
- int operator()(bool x) { return x ? 1 : -1; }
-};
-
-const char* Binary(const char* input, short n) { return input + n; } // NOLINT
-
-void VoidBinary(int, char) { g_done = true; }
-
-int Ternary(int x, char y, short z) { return x + y + z; } // NOLINT
-
-void VoidTernary(int, char, bool) { g_done = true; }
-
-int SumOf4(int a, int b, int c, int d) { return a + b + c + d; }
-
-void VoidFunctionWithFourArguments(char, int, float, double) { g_done = true; }
-
-int SumOf5(int a, int b, int c, int d, int e) { return a + b + c + d + e; }
-
-struct SumOf5Functor {
- int operator()(int a, int b, int c, int d, int e) {
- return a + b + c + d + e;
- }
-};
-
-int SumOf6(int a, int b, int c, int d, int e, int f) {
- return a + b + c + d + e + f;
-}
-
-struct SumOf6Functor {
- int operator()(int a, int b, int c, int d, int e, int f) {
- return a + b + c + d + e + f;
- }
-};
-
class Foo {
public:
Foo() : value_(123) {}
int Nullary() const { return value_; }
- short Unary(long x) { return static_cast<short>(value_ + x); } // NOLINT
- std::string Binary(const std::string& str, char c) const { return str + c; }
- int Ternary(int x, bool y, char z) { return value_ + x + y*z; }
- int SumOf4(int a, int b, int c, int d) const {
- return a + b + c + d + value_;
- }
- int SumOf5(int a, int b, int c, int d, int e) { return a + b + c + d + e; }
- int SumOf6(int a, int b, int c, int d, int e, int f) {
- return a + b + c + d + e + f;
- }
+
private:
int value_;
};
// Tests InvokeWithoutArgs(function).
TEST(InvokeWithoutArgsTest, Function) {
// As an action that takes one argument.
Action<int(int)> a = InvokeWithoutArgs(Nullary); // NOLINT
EXPECT_EQ(1, a.Perform(make_tuple(2)));
// As an action that takes two arguments.
Action<int(int, double)> a2 = InvokeWithoutArgs(Nullary); // NOLINT
EXPECT_EQ(1, a2.Perform(make_tuple(2, 3.5)));
// As an action that returns void.
Action<void(int)> a3 = InvokeWithoutArgs(VoidNullary); // NOLINT
g_done = false;
a3.Perform(make_tuple(1));
EXPECT_TRUE(g_done);
}
// Tests InvokeWithoutArgs(functor).
TEST(InvokeWithoutArgsTest, Functor) {
// As an action that takes no argument.
Action<int()> a = InvokeWithoutArgs(NullaryFunctor()); // NOLINT
EXPECT_EQ(2, a.Perform(make_tuple()));
// As an action that takes three arguments.
Action<int(int, double, char)> a2 = // NOLINT
InvokeWithoutArgs(NullaryFunctor());
EXPECT_EQ(2, a2.Perform(make_tuple(3, 3.5, 'a')));
// As an action that returns void.
Action<void()> a3 = InvokeWithoutArgs(VoidNullaryFunctor());
g_done = false;
a3.Perform(make_tuple());
EXPECT_TRUE(g_done);
}
// Tests InvokeWithoutArgs(obj_ptr, method).
TEST(InvokeWithoutArgsTest, Method) {
Foo foo;
Action<int(bool, char)> a = // NOLINT
InvokeWithoutArgs(&foo, &Foo::Nullary);
EXPECT_EQ(123, a.Perform(make_tuple(true, 'a')));
}
// Tests using IgnoreResult() on a polymorphic action.
TEST(IgnoreResultTest, PolymorphicAction) {
Action<void(int)> a = IgnoreResult(Return(5)); // NOLINT
a.Perform(make_tuple(1));
}
// Tests using IgnoreResult() on a monomorphic action.
int ReturnOne() {
g_done = true;
return 1;
}
TEST(IgnoreResultTest, MonomorphicAction) {
g_done = false;
Action<void()> a = IgnoreResult(Invoke(ReturnOne));
a.Perform(make_tuple());
EXPECT_TRUE(g_done);
}
// Tests using IgnoreResult() on an action that returns a class type.
MyClass ReturnMyClass(double /* x */) {
g_done = true;
return MyClass();
}
TEST(IgnoreResultTest, ActionReturningClass) {
g_done = false;
Action<void(int)> a = IgnoreResult(Invoke(ReturnMyClass)); // NOLINT
a.Perform(make_tuple(2));
EXPECT_TRUE(g_done);
}
TEST(AssignTest, Int) {
int x = 0;
Action<void(int)> a = Assign(&x, 5);
a.Perform(make_tuple(0));
EXPECT_EQ(5, x);
}
TEST(AssignTest, String) {
::std::string x;
Action<void(void)> a = Assign(&x, "Hello, world");
a.Perform(make_tuple());
EXPECT_EQ("Hello, world", x);
}
TEST(AssignTest, CompatibleTypes) {
double x = 0;
Action<void(int)> a = Assign(&x, 5);
a.Perform(make_tuple(0));
EXPECT_DOUBLE_EQ(5, x);
}
#if !GTEST_OS_WINDOWS_MOBILE
class SetErrnoAndReturnTest : public testing::Test {
protected:
virtual void SetUp() { errno = 0; }
virtual void TearDown() { errno = 0; }
};
TEST_F(SetErrnoAndReturnTest, Int) {
Action<int(void)> a = SetErrnoAndReturn(ENOTTY, -5);
EXPECT_EQ(-5, a.Perform(make_tuple()));
EXPECT_EQ(ENOTTY, errno);
}
TEST_F(SetErrnoAndReturnTest, Ptr) {
int x;
Action<int*(void)> a = SetErrnoAndReturn(ENOTTY, &x);
EXPECT_EQ(&x, a.Perform(make_tuple()));
EXPECT_EQ(ENOTTY, errno);
}
TEST_F(SetErrnoAndReturnTest, CompatibleTypes) {
Action<double()> a = SetErrnoAndReturn(EINVAL, 5);
EXPECT_DOUBLE_EQ(5.0, a.Perform(make_tuple()));
EXPECT_EQ(EINVAL, errno);
}
#endif // !GTEST_OS_WINDOWS_MOBILE
// Tests ByRef().
// Tests that ReferenceWrapper<T> is copyable.
TEST(ByRefTest, IsCopyable) {
const std::string s1 = "Hi";
const std::string s2 = "Hello";
::testing::internal::ReferenceWrapper<const std::string> ref_wrapper =
ByRef(s1);
const std::string& r1 = ref_wrapper;
EXPECT_EQ(&s1, &r1);
// Assigns a new value to ref_wrapper.
ref_wrapper = ByRef(s2);
const std::string& r2 = ref_wrapper;
EXPECT_EQ(&s2, &r2);
::testing::internal::ReferenceWrapper<const std::string> ref_wrapper1 =
ByRef(s1);
// Copies ref_wrapper1 to ref_wrapper.
ref_wrapper = ref_wrapper1;
const std::string& r3 = ref_wrapper;
EXPECT_EQ(&s1, &r3);
}
// Tests using ByRef() on a const value.
TEST(ByRefTest, ConstValue) {
const int n = 0;
// int& ref = ByRef(n); // This shouldn't compile - we have a
// negative compilation test to catch it.
const int& const_ref = ByRef(n);
EXPECT_EQ(&n, &const_ref);
}
// Tests using ByRef() on a non-const value.
TEST(ByRefTest, NonConstValue) {
int n = 0;
// ByRef(n) can be used as either an int&,
int& ref = ByRef(n);
EXPECT_EQ(&n, &ref);
// or a const int&.
const int& const_ref = ByRef(n);
EXPECT_EQ(&n, &const_ref);
}
// Tests explicitly specifying the type when using ByRef().
TEST(ByRefTest, ExplicitType) {
int n = 0;
const int& r1 = ByRef<const int>(n);
EXPECT_EQ(&n, &r1);
// ByRef<char>(n); // This shouldn't compile - we have a negative
// compilation test to catch it.
Derived d;
Derived& r2 = ByRef<Derived>(d);
EXPECT_EQ(&d, &r2);
const Derived& r3 = ByRef<const Derived>(d);
EXPECT_EQ(&d, &r3);
Base& r4 = ByRef<Base>(d);
EXPECT_EQ(&d, &r4);
const Base& r5 = ByRef<const Base>(d);
EXPECT_EQ(&d, &r5);
// The following shouldn't compile - we have a negative compilation
// test for it.
//
// Base b;
// ByRef<Derived>(b);
}
// Tests that Google Mock prints expression ByRef(x) as a reference to x.
TEST(ByRefTest, PrintsCorrectly) {
int n = 42;
::std::stringstream expected, actual;
testing::internal::UniversalPrinter<const int&>::Print(n, &expected);
testing::internal::UniversalPrint(ByRef(n), &actual);
EXPECT_EQ(expected.str(), actual.str());
}
} // Unnamed namespace
diff --git a/test/gmock-generated-actions_test.cc b/test/gmock-generated-actions_test.cc
index 436f1a2e..23f8c8b0 100644
--- a/test/gmock-generated-actions_test.cc
+++ b/test/gmock-generated-actions_test.cc
@@ -1,1212 +1,1225 @@
// Copyright 2007, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// 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.
//
// This file tests the built-in actions generated by a script.
#include "gmock/gmock-generated-actions.h"
#include <functional>
#include <sstream>
#include <string>
#include "gmock/gmock.h"
#include "gtest/gtest.h"
namespace testing {
namespace gmock_generated_actions_test {
using ::std::plus;
using ::std::string;
using ::std::tr1::get;
using ::std::tr1::make_tuple;
using ::std::tr1::tuple;
using ::std::tr1::tuple_element;
using testing::_;
using testing::Action;
using testing::ActionInterface;
using testing::ByRef;
using testing::DoAll;
using testing::Invoke;
using testing::Return;
using testing::ReturnNew;
using testing::SetArgPointee;
using testing::StaticAssertTypeEq;
using testing::Unused;
using testing::WithArgs;
// For suppressing compiler warnings on conversion possibly losing precision.
inline short Short(short n) { return n; } // NOLINT
inline char Char(char ch) { return ch; }
// Sample functions and functors for testing various actions.
int Nullary() { return 1; }
class NullaryFunctor {
public:
int operator()() { return 2; }
};
bool g_done = false;
bool Unary(int x) { return x < 0; }
const char* Plus1(const char* s) { return s + 1; }
bool ByConstRef(const string& s) { return s == "Hi"; }
const double g_double = 0;
bool ReferencesGlobalDouble(const double& x) { return &x == &g_double; }
string ByNonConstRef(string& s) { return s += "+"; } // NOLINT
struct UnaryFunctor {
int operator()(bool x) { return x ? 1 : -1; }
};
const char* Binary(const char* input, short n) { return input + n; } // NOLINT
void VoidBinary(int, char) { g_done = true; }
int Ternary(int x, char y, short z) { return x + y + z; } // NOLINT
void VoidTernary(int, char, bool) { g_done = true; }
int SumOf4(int a, int b, int c, int d) { return a + b + c + d; }
string Concat4(const char* s1, const char* s2, const char* s3,
const char* s4) {
return string(s1) + s2 + s3 + s4;
}
int SumOf5(int a, int b, int c, int d, int e) { return a + b + c + d + e; }
struct SumOf5Functor {
int operator()(int a, int b, int c, int d, int e) {
return a + b + c + d + e;
}
};
string Concat5(const char* s1, const char* s2, const char* s3,
const char* s4, const char* s5) {
return string(s1) + s2 + s3 + s4 + s5;
}
int SumOf6(int a, int b, int c, int d, int e, int f) {
return a + b + c + d + e + f;
}
struct SumOf6Functor {
int operator()(int a, int b, int c, int d, int e, int f) {
return a + b + c + d + e + f;
}
};
string Concat6(const char* s1, const char* s2, const char* s3,
const char* s4, const char* s5, const char* s6) {
return string(s1) + s2 + s3 + s4 + s5 + s6;
}
string Concat7(const char* s1, const char* s2, const char* s3,
const char* s4, const char* s5, const char* s6,
const char* s7) {
return string(s1) + s2 + s3 + s4 + s5 + s6 + s7;
}
string Concat8(const char* s1, const char* s2, const char* s3,
const char* s4, const char* s5, const char* s6,
const char* s7, const char* s8) {
return string(s1) + s2 + s3 + s4 + s5 + s6 + s7 + s8;
}
string Concat9(const char* s1, const char* s2, const char* s3,
const char* s4, const char* s5, const char* s6,
const char* s7, const char* s8, const char* s9) {
return string(s1) + s2 + s3 + s4 + s5 + s6 + s7 + s8 + s9;
}
string Concat10(const char* s1, const char* s2, const char* s3,
const char* s4, const char* s5, const char* s6,
const char* s7, const char* s8, const char* s9,
const char* s10) {
return string(s1) + s2 + s3 + s4 + s5 + s6 + s7 + s8 + s9 + s10;
}
// A helper that turns the type of a C-string literal from const
// char[N] to const char*.
inline const char* CharPtr(const char* s) { return s; }
// Tests InvokeArgument<N>(...).
// Tests using InvokeArgument with a nullary function.
TEST(InvokeArgumentTest, Function0) {
Action<int(int, int(*)())> a = InvokeArgument<1>(); // NOLINT
EXPECT_EQ(1, a.Perform(make_tuple(2, &Nullary)));
}
// Tests using InvokeArgument with a unary function.
TEST(InvokeArgumentTest, Functor1) {
Action<int(UnaryFunctor)> a = InvokeArgument<0>(true); // NOLINT
EXPECT_EQ(1, a.Perform(make_tuple(UnaryFunctor())));
}
// Tests using InvokeArgument with a 5-ary function.
TEST(InvokeArgumentTest, Function5) {
Action<int(int(*)(int, int, int, int, int))> a = // NOLINT
InvokeArgument<0>(10000, 2000, 300, 40, 5);
EXPECT_EQ(12345, a.Perform(make_tuple(&SumOf5)));
}
// Tests using InvokeArgument with a 5-ary functor.
TEST(InvokeArgumentTest, Functor5) {
Action<int(SumOf5Functor)> a = // NOLINT
InvokeArgument<0>(10000, 2000, 300, 40, 5);
EXPECT_EQ(12345, a.Perform(make_tuple(SumOf5Functor())));
}
// Tests using InvokeArgument with a 6-ary function.
TEST(InvokeArgumentTest, Function6) {
Action<int(int(*)(int, int, int, int, int, int))> a = // NOLINT
InvokeArgument<0>(100000, 20000, 3000, 400, 50, 6);
EXPECT_EQ(123456, a.Perform(make_tuple(&SumOf6)));
}
// Tests using InvokeArgument with a 6-ary functor.
TEST(InvokeArgumentTest, Functor6) {
Action<int(SumOf6Functor)> a = // NOLINT
InvokeArgument<0>(100000, 20000, 3000, 400, 50, 6);
EXPECT_EQ(123456, a.Perform(make_tuple(SumOf6Functor())));
}
// Tests using InvokeArgument with a 7-ary function.
TEST(InvokeArgumentTest, Function7) {
Action<string(string(*)(const char*, const char*, const char*,
const char*, const char*, const char*,
const char*))> a =
InvokeArgument<0>("1", "2", "3", "4", "5", "6", "7");
EXPECT_EQ("1234567", a.Perform(make_tuple(&Concat7)));
}
// Tests using InvokeArgument with a 8-ary function.
TEST(InvokeArgumentTest, Function8) {
Action<string(string(*)(const char*, const char*, const char*,
const char*, const char*, const char*,
const char*, const char*))> a =
InvokeArgument<0>("1", "2", "3", "4", "5", "6", "7", "8");
EXPECT_EQ("12345678", a.Perform(make_tuple(&Concat8)));
}
// Tests using InvokeArgument with a 9-ary function.
TEST(InvokeArgumentTest, Function9) {
Action<string(string(*)(const char*, const char*, const char*,
const char*, const char*, const char*,
const char*, const char*, const char*))> a =
InvokeArgument<0>("1", "2", "3", "4", "5", "6", "7", "8", "9");
EXPECT_EQ("123456789", a.Perform(make_tuple(&Concat9)));
}
// Tests using InvokeArgument with a 10-ary function.
TEST(InvokeArgumentTest, Function10) {
Action<string(string(*)(const char*, const char*, const char*,
const char*, const char*, const char*,
const char*, const char*, const char*,
const char*))> a =
InvokeArgument<0>("1", "2", "3", "4", "5", "6", "7", "8", "9", "0");
EXPECT_EQ("1234567890", a.Perform(make_tuple(&Concat10)));
}
// Tests using InvokeArgument with a function that takes a pointer argument.
TEST(InvokeArgumentTest, ByPointerFunction) {
Action<const char*(const char*(*)(const char* input, short n))> a = // NOLINT
InvokeArgument<0>(static_cast<const char*>("Hi"), Short(1));
EXPECT_STREQ("i", a.Perform(make_tuple(&Binary)));
}
// Tests using InvokeArgument with a function that takes a const char*
// by passing it a C-string literal.
TEST(InvokeArgumentTest, FunctionWithCStringLiteral) {
Action<const char*(const char*(*)(const char* input, short n))> a = // NOLINT
InvokeArgument<0>("Hi", Short(1));
EXPECT_STREQ("i", a.Perform(make_tuple(&Binary)));
}
// Tests using InvokeArgument with a function that takes a const reference.
TEST(InvokeArgumentTest, ByConstReferenceFunction) {
Action<bool(bool(*function)(const string& s))> a = // NOLINT
InvokeArgument<0>(string("Hi"));
// When action 'a' is constructed, it makes a copy of the temporary
// string object passed to it, so it's OK to use 'a' later, when the
// temporary object has already died.
EXPECT_TRUE(a.Perform(make_tuple(&ByConstRef)));
}
// Tests using InvokeArgument with ByRef() and a function that takes a
// const reference.
TEST(InvokeArgumentTest, ByExplicitConstReferenceFunction) {
Action<bool(bool(*)(const double& x))> a = // NOLINT
InvokeArgument<0>(ByRef(g_double));
// The above line calls ByRef() on a const value.
EXPECT_TRUE(a.Perform(make_tuple(&ReferencesGlobalDouble)));
double x = 0;
a = InvokeArgument<0>(ByRef(x)); // This calls ByRef() on a non-const.
EXPECT_FALSE(a.Perform(make_tuple(&ReferencesGlobalDouble)));
}
// Tests using WithArgs and with an action that takes 1 argument.
TEST(WithArgsTest, OneArg) {
Action<bool(double x, int n)> a = WithArgs<1>(Invoke(Unary)); // NOLINT
EXPECT_TRUE(a.Perform(make_tuple(1.5, -1)));
EXPECT_FALSE(a.Perform(make_tuple(1.5, 1)));
}
// Tests using WithArgs with an action that takes 2 arguments.
TEST(WithArgsTest, TwoArgs) {
Action<const char*(const char* s, double x, short n)> a =
WithArgs<0, 2>(Invoke(Binary));
const char s[] = "Hello";
EXPECT_EQ(s + 2, a.Perform(make_tuple(CharPtr(s), 0.5, Short(2))));
}
// Tests using WithArgs with an action that takes 3 arguments.
TEST(WithArgsTest, ThreeArgs) {
Action<int(int, double, char, short)> a = // NOLINT
WithArgs<0, 2, 3>(Invoke(Ternary));
EXPECT_EQ(123, a.Perform(make_tuple(100, 6.5, Char(20), Short(3))));
}
// Tests using WithArgs with an action that takes 4 arguments.
TEST(WithArgsTest, FourArgs) {
Action<string(const char*, const char*, double, const char*, const char*)> a =
WithArgs<4, 3, 1, 0>(Invoke(Concat4));
EXPECT_EQ("4310", a.Perform(make_tuple(CharPtr("0"), CharPtr("1"), 2.5,
CharPtr("3"), CharPtr("4"))));
}
// Tests using WithArgs with an action that takes 5 arguments.
TEST(WithArgsTest, FiveArgs) {
Action<string(const char*, const char*, const char*,
const char*, const char*)> a =
WithArgs<4, 3, 2, 1, 0>(Invoke(Concat5));
EXPECT_EQ("43210",
a.Perform(make_tuple(CharPtr("0"), CharPtr("1"), CharPtr("2"),
CharPtr("3"), CharPtr("4"))));
}
// Tests using WithArgs with an action that takes 6 arguments.
TEST(WithArgsTest, SixArgs) {
Action<string(const char*, const char*, const char*)> a =
WithArgs<0, 1, 2, 2, 1, 0>(Invoke(Concat6));
EXPECT_EQ("012210",
a.Perform(make_tuple(CharPtr("0"), CharPtr("1"), CharPtr("2"))));
}
// Tests using WithArgs with an action that takes 7 arguments.
TEST(WithArgsTest, SevenArgs) {
Action<string(const char*, const char*, const char*, const char*)> a =
WithArgs<0, 1, 2, 3, 2, 1, 0>(Invoke(Concat7));
EXPECT_EQ("0123210",
a.Perform(make_tuple(CharPtr("0"), CharPtr("1"), CharPtr("2"),
CharPtr("3"))));
}
// Tests using WithArgs with an action that takes 8 arguments.
TEST(WithArgsTest, EightArgs) {
Action<string(const char*, const char*, const char*, const char*)> a =
WithArgs<0, 1, 2, 3, 0, 1, 2, 3>(Invoke(Concat8));
EXPECT_EQ("01230123",
a.Perform(make_tuple(CharPtr("0"), CharPtr("1"), CharPtr("2"),
CharPtr("3"))));
}
// Tests using WithArgs with an action that takes 9 arguments.
TEST(WithArgsTest, NineArgs) {
Action<string(const char*, const char*, const char*, const char*)> a =
WithArgs<0, 1, 2, 3, 1, 2, 3, 2, 3>(Invoke(Concat9));
EXPECT_EQ("012312323",
a.Perform(make_tuple(CharPtr("0"), CharPtr("1"), CharPtr("2"),
CharPtr("3"))));
}
// Tests using WithArgs with an action that takes 10 arguments.
TEST(WithArgsTest, TenArgs) {
Action<string(const char*, const char*, const char*, const char*)> a =
WithArgs<0, 1, 2, 3, 2, 1, 0, 1, 2, 3>(Invoke(Concat10));
EXPECT_EQ("0123210123",
a.Perform(make_tuple(CharPtr("0"), CharPtr("1"), CharPtr("2"),
CharPtr("3"))));
}
// Tests using WithArgs with an action that is not Invoke().
class SubstractAction : public ActionInterface<int(int, int)> { // NOLINT
public:
virtual int Perform(const tuple<int, int>& args) {
return get<0>(args) - get<1>(args);
}
};
TEST(WithArgsTest, NonInvokeAction) {
Action<int(const string&, int, int)> a = // NOLINT
WithArgs<2, 1>(MakeAction(new SubstractAction));
EXPECT_EQ(8, a.Perform(make_tuple(CharPtr("hi"), 2, 10)));
}
// Tests using WithArgs to pass all original arguments in the original order.
TEST(WithArgsTest, Identity) {
Action<int(int x, char y, short z)> a = // NOLINT
WithArgs<0, 1, 2>(Invoke(Ternary));
EXPECT_EQ(123, a.Perform(make_tuple(100, Char(20), Short(3))));
}
// Tests using WithArgs with repeated arguments.
TEST(WithArgsTest, RepeatedArguments) {
Action<int(bool, int m, int n)> a = // NOLINT
WithArgs<1, 1, 1, 1>(Invoke(SumOf4));
EXPECT_EQ(4, a.Perform(make_tuple(false, 1, 10)));
}
// Tests using WithArgs with reversed argument order.
TEST(WithArgsTest, ReversedArgumentOrder) {
Action<const char*(short n, const char* input)> a = // NOLINT
WithArgs<1, 0>(Invoke(Binary));
const char s[] = "Hello";
EXPECT_EQ(s + 2, a.Perform(make_tuple(Short(2), CharPtr(s))));
}
// Tests using WithArgs with compatible, but not identical, argument types.
TEST(WithArgsTest, ArgsOfCompatibleTypes) {
Action<long(short x, char y, double z, char c)> a = // NOLINT
WithArgs<0, 1, 3>(Invoke(Ternary));
EXPECT_EQ(123, a.Perform(make_tuple(Short(100), Char(20), 5.6, Char(3))));
}
// Tests using WithArgs with an action that returns void.
TEST(WithArgsTest, VoidAction) {
Action<void(double x, char c, int n)> a = WithArgs<2, 1>(Invoke(VoidBinary));
g_done = false;
a.Perform(make_tuple(1.5, 'a', 3));
EXPECT_TRUE(g_done);
}
// Tests DoAll(a1, a2).
TEST(DoAllTest, TwoActions) {
int n = 0;
Action<int(int*)> a = DoAll(SetArgPointee<0>(1), // NOLINT
Return(2));
EXPECT_EQ(2, a.Perform(make_tuple(&n)));
EXPECT_EQ(1, n);
}
// Tests DoAll(a1, a2, a3).
TEST(DoAllTest, ThreeActions) {
int m = 0, n = 0;
Action<int(int*, int*)> a = DoAll(SetArgPointee<0>(1), // NOLINT
SetArgPointee<1>(2),
Return(3));
EXPECT_EQ(3, a.Perform(make_tuple(&m, &n)));
EXPECT_EQ(1, m);
EXPECT_EQ(2, n);
}
// Tests DoAll(a1, a2, a3, a4).
TEST(DoAllTest, FourActions) {
int m = 0, n = 0;
char ch = '\0';
Action<int(int*, int*, char*)> a = // NOLINT
DoAll(SetArgPointee<0>(1),
SetArgPointee<1>(2),
SetArgPointee<2>('a'),
Return(3));
EXPECT_EQ(3, a.Perform(make_tuple(&m, &n, &ch)));
EXPECT_EQ(1, m);
EXPECT_EQ(2, n);
EXPECT_EQ('a', ch);
}
// Tests DoAll(a1, a2, a3, a4, a5).
TEST(DoAllTest, FiveActions) {
int m = 0, n = 0;
char a = '\0', b = '\0';
Action<int(int*, int*, char*, char*)> action = // NOLINT
DoAll(SetArgPointee<0>(1),
SetArgPointee<1>(2),
SetArgPointee<2>('a'),
SetArgPointee<3>('b'),
Return(3));
EXPECT_EQ(3, action.Perform(make_tuple(&m, &n, &a, &b)));
EXPECT_EQ(1, m);
EXPECT_EQ(2, n);
EXPECT_EQ('a', a);
EXPECT_EQ('b', b);
}
// Tests DoAll(a1, a2, ..., a6).
TEST(DoAllTest, SixActions) {
int m = 0, n = 0;
char a = '\0', b = '\0', c = '\0';
Action<int(int*, int*, char*, char*, char*)> action = // NOLINT
DoAll(SetArgPointee<0>(1),
SetArgPointee<1>(2),
SetArgPointee<2>('a'),
SetArgPointee<3>('b'),
SetArgPointee<4>('c'),
Return(3));
EXPECT_EQ(3, action.Perform(make_tuple(&m, &n, &a, &b, &c)));
EXPECT_EQ(1, m);
EXPECT_EQ(2, n);
EXPECT_EQ('a', a);
EXPECT_EQ('b', b);
EXPECT_EQ('c', c);
}
// Tests DoAll(a1, a2, ..., a7).
TEST(DoAllTest, SevenActions) {
int m = 0, n = 0;
char a = '\0', b = '\0', c = '\0', d = '\0';
Action<int(int*, int*, char*, char*, char*, char*)> action = // NOLINT
DoAll(SetArgPointee<0>(1),
SetArgPointee<1>(2),
SetArgPointee<2>('a'),
SetArgPointee<3>('b'),
SetArgPointee<4>('c'),
SetArgPointee<5>('d'),
Return(3));
EXPECT_EQ(3, action.Perform(make_tuple(&m, &n, &a, &b, &c, &d)));
EXPECT_EQ(1, m);
EXPECT_EQ(2, n);
EXPECT_EQ('a', a);
EXPECT_EQ('b', b);
EXPECT_EQ('c', c);
EXPECT_EQ('d', d);
}
// Tests DoAll(a1, a2, ..., a8).
TEST(DoAllTest, EightActions) {
int m = 0, n = 0;
char a = '\0', b = '\0', c = '\0', d = '\0', e = '\0';
Action<int(int*, int*, char*, char*, char*, char*, // NOLINT
char*)> action =
DoAll(SetArgPointee<0>(1),
SetArgPointee<1>(2),
SetArgPointee<2>('a'),
SetArgPointee<3>('b'),
SetArgPointee<4>('c'),
SetArgPointee<5>('d'),
SetArgPointee<6>('e'),
Return(3));
EXPECT_EQ(3, action.Perform(make_tuple(&m, &n, &a, &b, &c, &d, &e)));
EXPECT_EQ(1, m);
EXPECT_EQ(2, n);
EXPECT_EQ('a', a);
EXPECT_EQ('b', b);
EXPECT_EQ('c', c);
EXPECT_EQ('d', d);
EXPECT_EQ('e', e);
}
// Tests DoAll(a1, a2, ..., a9).
TEST(DoAllTest, NineActions) {
int m = 0, n = 0;
char a = '\0', b = '\0', c = '\0', d = '\0', e = '\0', f = '\0';
Action<int(int*, int*, char*, char*, char*, char*, // NOLINT
char*, char*)> action =
DoAll(SetArgPointee<0>(1),
SetArgPointee<1>(2),
SetArgPointee<2>('a'),
SetArgPointee<3>('b'),
SetArgPointee<4>('c'),
SetArgPointee<5>('d'),
SetArgPointee<6>('e'),
SetArgPointee<7>('f'),
Return(3));
EXPECT_EQ(3, action.Perform(make_tuple(&m, &n, &a, &b, &c, &d, &e, &f)));
EXPECT_EQ(1, m);
EXPECT_EQ(2, n);
EXPECT_EQ('a', a);
EXPECT_EQ('b', b);
EXPECT_EQ('c', c);
EXPECT_EQ('d', d);
EXPECT_EQ('e', e);
EXPECT_EQ('f', f);
}
// Tests DoAll(a1, a2, ..., a10).
TEST(DoAllTest, TenActions) {
int m = 0, n = 0;
char a = '\0', b = '\0', c = '\0', d = '\0';
char e = '\0', f = '\0', g = '\0';
Action<int(int*, int*, char*, char*, char*, char*, // NOLINT
char*, char*, char*)> action =
DoAll(SetArgPointee<0>(1),
SetArgPointee<1>(2),
SetArgPointee<2>('a'),
SetArgPointee<3>('b'),
SetArgPointee<4>('c'),
SetArgPointee<5>('d'),
SetArgPointee<6>('e'),
SetArgPointee<7>('f'),
SetArgPointee<8>('g'),
Return(3));
EXPECT_EQ(3, action.Perform(make_tuple(&m, &n, &a, &b, &c, &d, &e, &f, &g)));
EXPECT_EQ(1, m);
EXPECT_EQ(2, n);
EXPECT_EQ('a', a);
EXPECT_EQ('b', b);
EXPECT_EQ('c', c);
EXPECT_EQ('d', d);
EXPECT_EQ('e', e);
EXPECT_EQ('f', f);
EXPECT_EQ('g', g);
}
// The ACTION*() macros trigger warning C4100 (unreferenced formal
// parameter) in MSVC with -W4. Unfortunately they cannot be fixed in
// the macro definition, as the warnings are generated when the macro
// is expanded and macro expansion cannot contain #pragma. Therefore
// we suppress them here.
#ifdef _MSC_VER
# pragma warning(push)
# pragma warning(disable:4100)
#endif
// Tests the ACTION*() macro family.
// Tests that ACTION() can define an action that doesn't reference the
// mock function arguments.
ACTION(Return5) { return 5; }
TEST(ActionMacroTest, WorksWhenNotReferencingArguments) {
Action<double()> a1 = Return5();
EXPECT_DOUBLE_EQ(5, a1.Perform(make_tuple()));
Action<int(double, bool)> a2 = Return5();
EXPECT_EQ(5, a2.Perform(make_tuple(1, true)));
}
// Tests that ACTION() can define an action that returns void.
ACTION(IncrementArg1) { (*arg1)++; }
TEST(ActionMacroTest, WorksWhenReturningVoid) {
Action<void(int, int*)> a1 = IncrementArg1();
int n = 0;
a1.Perform(make_tuple(5, &n));
EXPECT_EQ(1, n);
}
// Tests that the body of ACTION() can reference the type of the
// argument.
ACTION(IncrementArg2) {
StaticAssertTypeEq<int*, arg2_type>();
arg2_type temp = arg2;
(*temp)++;
}
TEST(ActionMacroTest, CanReferenceArgumentType) {
Action<void(int, bool, int*)> a1 = IncrementArg2();
int n = 0;
a1.Perform(make_tuple(5, false, &n));
EXPECT_EQ(1, n);
}
// Tests that the body of ACTION() can reference the argument tuple
// via args_type and args.
ACTION(Sum2) {
StaticAssertTypeEq< ::std::tr1::tuple<int, char, int*>, args_type>();
args_type args_copy = args;
return get<0>(args_copy) + get<1>(args_copy);
}
TEST(ActionMacroTest, CanReferenceArgumentTuple) {
Action<int(int, char, int*)> a1 = Sum2();
int dummy = 0;
EXPECT_EQ(11, a1.Perform(make_tuple(5, Char(6), &dummy)));
}
// Tests that the body of ACTION() can reference the mock function
// type.
int Dummy(bool flag) { return flag? 1 : 0; }
ACTION(InvokeDummy) {
StaticAssertTypeEq<int(bool), function_type>();
function_type* fp = &Dummy;
return (*fp)(true);
}
TEST(ActionMacroTest, CanReferenceMockFunctionType) {
Action<int(bool)> a1 = InvokeDummy();
EXPECT_EQ(1, a1.Perform(make_tuple(true)));
EXPECT_EQ(1, a1.Perform(make_tuple(false)));
}
// Tests that the body of ACTION() can reference the mock function's
// return type.
ACTION(InvokeDummy2) {
StaticAssertTypeEq<int, return_type>();
return_type result = Dummy(true);
return result;
}
TEST(ActionMacroTest, CanReferenceMockFunctionReturnType) {
Action<int(bool)> a1 = InvokeDummy2();
EXPECT_EQ(1, a1.Perform(make_tuple(true)));
EXPECT_EQ(1, a1.Perform(make_tuple(false)));
}
// Tests that ACTION() works for arguments passed by const reference.
ACTION(ReturnAddrOfConstBoolReferenceArg) {
StaticAssertTypeEq<const bool&, arg1_type>();
return &arg1;
}
TEST(ActionMacroTest, WorksForConstReferenceArg) {
Action<const bool*(int, const bool&)> a = ReturnAddrOfConstBoolReferenceArg();
const bool b = false;
EXPECT_EQ(&b, a.Perform(tuple<int, const bool&>(0, b)));
}
// Tests that ACTION() works for arguments passed by non-const reference.
ACTION(ReturnAddrOfIntReferenceArg) {
StaticAssertTypeEq<int&, arg0_type>();
return &arg0;
}
TEST(ActionMacroTest, WorksForNonConstReferenceArg) {
Action<int*(int&, bool, int)> a = ReturnAddrOfIntReferenceArg();
int n = 0;
EXPECT_EQ(&n, a.Perform(tuple<int&, bool, int>(n, true, 1)));
}
// Tests that ACTION() can be used in a namespace.
namespace action_test {
ACTION(Sum) { return arg0 + arg1; }
} // namespace action_test
TEST(ActionMacroTest, WorksInNamespace) {
Action<int(int, int)> a1 = action_test::Sum();
EXPECT_EQ(3, a1.Perform(make_tuple(1, 2)));
}
// Tests that the same ACTION definition works for mock functions with
// different argument numbers.
ACTION(PlusTwo) { return arg0 + 2; }
TEST(ActionMacroTest, WorksForDifferentArgumentNumbers) {
Action<int(int)> a1 = PlusTwo();
EXPECT_EQ(4, a1.Perform(make_tuple(2)));
Action<double(float, void*)> a2 = PlusTwo();
int dummy;
EXPECT_DOUBLE_EQ(6, a2.Perform(make_tuple(4.0f, &dummy)));
}
// Tests that ACTION_P can define a parameterized action.
ACTION_P(Plus, n) { return arg0 + n; }
TEST(ActionPMacroTest, DefinesParameterizedAction) {
Action<int(int m, bool t)> a1 = Plus(9);
EXPECT_EQ(10, a1.Perform(make_tuple(1, true)));
}
// Tests that the body of ACTION_P can reference the argument types
// and the parameter type.
ACTION_P(TypedPlus, n) {
arg0_type t1 = arg0;
n_type t2 = n;
return t1 + t2;
}
TEST(ActionPMacroTest, CanReferenceArgumentAndParameterTypes) {
Action<int(char m, bool t)> a1 = TypedPlus(9);
EXPECT_EQ(10, a1.Perform(make_tuple(Char(1), true)));
}
// Tests that a parameterized action can be used in any mock function
// whose type is compatible.
TEST(ActionPMacroTest, WorksInCompatibleMockFunction) {
Action<std::string(const std::string& s)> a1 = Plus("tail");
const std::string re = "re";
EXPECT_EQ("retail", a1.Perform(make_tuple(re)));
}
// Tests that we can use ACTION*() to define actions overloaded on the
// number of parameters.
ACTION(OverloadedAction) { return arg0 ? arg1 : "hello"; }
ACTION_P(OverloadedAction, default_value) {
return arg0 ? arg1 : default_value;
}
ACTION_P2(OverloadedAction, true_value, false_value) {
return arg0 ? true_value : false_value;
}
TEST(ActionMacroTest, CanDefineOverloadedActions) {
typedef Action<const char*(bool, const char*)> MyAction;
const MyAction a1 = OverloadedAction();
EXPECT_STREQ("hello", a1.Perform(make_tuple(false, CharPtr("world"))));
EXPECT_STREQ("world", a1.Perform(make_tuple(true, CharPtr("world"))));
const MyAction a2 = OverloadedAction("hi");
EXPECT_STREQ("hi", a2.Perform(make_tuple(false, CharPtr("world"))));
EXPECT_STREQ("world", a2.Perform(make_tuple(true, CharPtr("world"))));
const MyAction a3 = OverloadedAction("hi", "you");
EXPECT_STREQ("hi", a3.Perform(make_tuple(true, CharPtr("world"))));
EXPECT_STREQ("you", a3.Perform(make_tuple(false, CharPtr("world"))));
}
// Tests ACTION_Pn where n >= 3.
ACTION_P3(Plus, m, n, k) { return arg0 + m + n + k; }
TEST(ActionPnMacroTest, WorksFor3Parameters) {
Action<double(int m, bool t)> a1 = Plus(100, 20, 3.4);
EXPECT_DOUBLE_EQ(3123.4, a1.Perform(make_tuple(3000, true)));
Action<std::string(const std::string& s)> a2 = Plus("tail", "-", ">");
const std::string re = "re";
EXPECT_EQ("retail->", a2.Perform(make_tuple(re)));
}
ACTION_P4(Plus, p0, p1, p2, p3) { return arg0 + p0 + p1 + p2 + p3; }
TEST(ActionPnMacroTest, WorksFor4Parameters) {
Action<int(int)> a1 = Plus(1, 2, 3, 4);
EXPECT_EQ(10 + 1 + 2 + 3 + 4, a1.Perform(make_tuple(10)));
}
ACTION_P5(Plus, p0, p1, p2, p3, p4) { return arg0 + p0 + p1 + p2 + p3 + p4; }
TEST(ActionPnMacroTest, WorksFor5Parameters) {
Action<int(int)> a1 = Plus(1, 2, 3, 4, 5);
EXPECT_EQ(10 + 1 + 2 + 3 + 4 + 5, a1.Perform(make_tuple(10)));
}
ACTION_P6(Plus, p0, p1, p2, p3, p4, p5) {
return arg0 + p0 + p1 + p2 + p3 + p4 + p5;
}
TEST(ActionPnMacroTest, WorksFor6Parameters) {
Action<int(int)> a1 = Plus(1, 2, 3, 4, 5, 6);
EXPECT_EQ(10 + 1 + 2 + 3 + 4 + 5 + 6, a1.Perform(make_tuple(10)));
}
ACTION_P7(Plus, p0, p1, p2, p3, p4, p5, p6) {
return arg0 + p0 + p1 + p2 + p3 + p4 + p5 + p6;
}
TEST(ActionPnMacroTest, WorksFor7Parameters) {
Action<int(int)> a1 = Plus(1, 2, 3, 4, 5, 6, 7);
EXPECT_EQ(10 + 1 + 2 + 3 + 4 + 5 + 6 + 7, a1.Perform(make_tuple(10)));
}
ACTION_P8(Plus, p0, p1, p2, p3, p4, p5, p6, p7) {
return arg0 + p0 + p1 + p2 + p3 + p4 + p5 + p6 + p7;
}
TEST(ActionPnMacroTest, WorksFor8Parameters) {
Action<int(int)> a1 = Plus(1, 2, 3, 4, 5, 6, 7, 8);
EXPECT_EQ(10 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8, a1.Perform(make_tuple(10)));
}
ACTION_P9(Plus, p0, p1, p2, p3, p4, p5, p6, p7, p8) {
return arg0 + p0 + p1 + p2 + p3 + p4 + p5 + p6 + p7 + p8;
}
TEST(ActionPnMacroTest, WorksFor9Parameters) {
Action<int(int)> a1 = Plus(1, 2, 3, 4, 5, 6, 7, 8, 9);
EXPECT_EQ(10 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9, a1.Perform(make_tuple(10)));
}
ACTION_P10(Plus, p0, p1, p2, p3, p4, p5, p6, p7, p8, last_param) {
arg0_type t0 = arg0;
last_param_type t9 = last_param;
return t0 + p0 + p1 + p2 + p3 + p4 + p5 + p6 + p7 + p8 + t9;
}
TEST(ActionPnMacroTest, WorksFor10Parameters) {
Action<int(int)> a1 = Plus(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
EXPECT_EQ(10 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10,
a1.Perform(make_tuple(10)));
}
// Tests that the action body can promote the parameter types.
ACTION_P2(PadArgument, prefix, suffix) {
// The following lines promote the two parameters to desired types.
std::string prefix_str(prefix);
char suffix_char = static_cast<char>(suffix);
return prefix_str + arg0 + suffix_char;
}
TEST(ActionPnMacroTest, SimpleTypePromotion) {
Action<std::string(const char*)> no_promo =
PadArgument(std::string("foo"), 'r');
Action<std::string(const char*)> promo =
PadArgument("foo", static_cast<int>('r'));
EXPECT_EQ("foobar", no_promo.Perform(make_tuple(CharPtr("ba"))));
EXPECT_EQ("foobar", promo.Perform(make_tuple(CharPtr("ba"))));
}
// Tests that we can partially restrict parameter types using a
// straight-forward pattern.
// Defines a generic action that doesn't restrict the types of its
// parameters.
ACTION_P3(ConcatImpl, a, b, c) {
std::stringstream ss;
ss << a << b << c;
return ss.str();
}
// Next, we try to restrict that either the first parameter is a
// string, or the second parameter is an int.
// Defines a partially specialized wrapper that restricts the first
// parameter to std::string.
template <typename T1, typename T2>
// ConcatImplActionP3 is the class template ACTION_P3 uses to
// implement ConcatImpl. We shouldn't change the name as this
// pattern requires the user to use it directly.
ConcatImplActionP3<std::string, T1, T2>
Concat(const std::string& a, T1 b, T2 c) {
if (true) {
// This branch verifies that ConcatImpl() can be invoked without
// explicit template arguments.
return ConcatImpl(a, b, c);
} else {
// This branch verifies that ConcatImpl() can also be invoked with
// explicit template arguments. It doesn't really need to be
// executed as this is a compile-time verification.
return ConcatImpl<std::string, T1, T2>(a, b, c);
}
}
// Defines another partially specialized wrapper that restricts the
// second parameter to int.
template <typename T1, typename T2>
ConcatImplActionP3<T1, int, T2>
Concat(T1 a, int b, T2 c) {
return ConcatImpl(a, b, c);
}
TEST(ActionPnMacroTest, CanPartiallyRestrictParameterTypes) {
Action<const std::string()> a1 = Concat("Hello", "1", 2);
EXPECT_EQ("Hello12", a1.Perform(make_tuple()));
a1 = Concat(1, 2, 3);
EXPECT_EQ("123", a1.Perform(make_tuple()));
}
// Verifies the type of an ACTION*.
ACTION(DoFoo) {}
ACTION_P(DoFoo, p) {}
ACTION_P2(DoFoo, p0, p1) {}
TEST(ActionPnMacroTest, TypesAreCorrect) {
// DoFoo() must be assignable to a DoFooAction variable.
DoFooAction a0 = DoFoo();
// DoFoo(1) must be assignable to a DoFooActionP variable.
DoFooActionP<int> a1 = DoFoo(1);
// DoFoo(p1, ..., pk) must be assignable to a DoFooActionPk
// variable, and so on.
DoFooActionP2<int, char> a2 = DoFoo(1, '2');
PlusActionP3<int, int, char> a3 = Plus(1, 2, '3');
PlusActionP4<int, int, int, char> a4 = Plus(1, 2, 3, '4');
PlusActionP5<int, int, int, int, char> a5 = Plus(1, 2, 3, 4, '5');
PlusActionP6<int, int, int, int, int, char> a6 = Plus(1, 2, 3, 4, 5, '6');
PlusActionP7<int, int, int, int, int, int, char> a7 =
Plus(1, 2, 3, 4, 5, 6, '7');
PlusActionP8<int, int, int, int, int, int, int, char> a8 =
Plus(1, 2, 3, 4, 5, 6, 7, '8');
PlusActionP9<int, int, int, int, int, int, int, int, char> a9 =
Plus(1, 2, 3, 4, 5, 6, 7, 8, '9');
PlusActionP10<int, int, int, int, int, int, int, int, int, char> a10 =
Plus(1, 2, 3, 4, 5, 6, 7, 8, 9, '0');
+
+ // Avoid "unused variable" warnings.
+ (void)a0;
+ (void)a1;
+ (void)a2;
+ (void)a3;
+ (void)a4;
+ (void)a5;
+ (void)a6;
+ (void)a7;
+ (void)a8;
+ (void)a9;
+ (void)a10;
}
// Tests that an ACTION_P*() action can be explicitly instantiated
// with reference-typed parameters.
ACTION_P(Plus1, x) { return x; }
ACTION_P2(Plus2, x, y) { return x + y; }
ACTION_P3(Plus3, x, y, z) { return x + y + z; }
ACTION_P10(Plus10, a0, a1, a2, a3, a4, a5, a6, a7, a8, a9) {
return a0 + a1 + a2 + a3 + a4 + a5 + a6 + a7 + a8 + a9;
}
TEST(ActionPnMacroTest, CanExplicitlyInstantiateWithReferenceTypes) {
int x = 1, y = 2, z = 3;
const tuple<> empty = make_tuple();
Action<int()> a = Plus1<int&>(x);
EXPECT_EQ(1, a.Perform(empty));
a = Plus2<const int&, int&>(x, y);
EXPECT_EQ(3, a.Perform(empty));
a = Plus3<int&, const int&, int&>(x, y, z);
EXPECT_EQ(6, a.Perform(empty));
int n[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
a = Plus10<const int&, int&, const int&, int&, const int&, int&, const int&,
int&, const int&, int&>(n[0], n[1], n[2], n[3], n[4], n[5], n[6], n[7],
n[8], n[9]);
EXPECT_EQ(55, a.Perform(empty));
}
class NullaryConstructorClass {
public:
NullaryConstructorClass() : value_(123) {}
int value_;
};
// Tests using ReturnNew() with a nullary constructor.
TEST(ReturnNewTest, NoArgs) {
Action<NullaryConstructorClass*()> a = ReturnNew<NullaryConstructorClass>();
NullaryConstructorClass* c = a.Perform(make_tuple());
EXPECT_EQ(123, c->value_);
delete c;
}
class UnaryConstructorClass {
public:
explicit UnaryConstructorClass(int value) : value_(value) {}
int value_;
};
// Tests using ReturnNew() with a unary constructor.
TEST(ReturnNewTest, Unary) {
Action<UnaryConstructorClass*()> a = ReturnNew<UnaryConstructorClass>(4000);
UnaryConstructorClass* c = a.Perform(make_tuple());
EXPECT_EQ(4000, c->value_);
delete c;
}
TEST(ReturnNewTest, UnaryWorksWhenMockMethodHasArgs) {
Action<UnaryConstructorClass*(bool, int)> a =
ReturnNew<UnaryConstructorClass>(4000);
UnaryConstructorClass* c = a.Perform(make_tuple(false, 5));
EXPECT_EQ(4000, c->value_);
delete c;
}
TEST(ReturnNewTest, UnaryWorksWhenMockMethodReturnsPointerToConst) {
Action<const UnaryConstructorClass*()> a =
ReturnNew<UnaryConstructorClass>(4000);
const UnaryConstructorClass* c = a.Perform(make_tuple());
EXPECT_EQ(4000, c->value_);
delete c;
}
class TenArgConstructorClass {
public:
TenArgConstructorClass(int a1, int a2, int a3, int a4, int a5,
int a6, int a7, int a8, int a9, int a10)
: value_(a1 + a2 + a3 + a4 + a5 + a6 + a7 + a8 + a9 + a10) {
}
int value_;
};
// Tests using ReturnNew() with a 10-argument constructor.
TEST(ReturnNewTest, ConstructorThatTakes10Arguments) {
Action<TenArgConstructorClass*()> a =
ReturnNew<TenArgConstructorClass>(1000000000, 200000000, 30000000,
4000000, 500000, 60000,
7000, 800, 90, 0);
TenArgConstructorClass* c = a.Perform(make_tuple());
EXPECT_EQ(1234567890, c->value_);
delete c;
}
// Tests that ACTION_TEMPLATE works when there is no value parameter.
ACTION_TEMPLATE(CreateNew,
HAS_1_TEMPLATE_PARAMS(typename, T),
AND_0_VALUE_PARAMS()) {
return new T;
}
TEST(ActionTemplateTest, WorksWithoutValueParam) {
const Action<int*()> a = CreateNew<int>();
int* p = a.Perform(make_tuple());
delete p;
}
// Tests that ACTION_TEMPLATE works when there are value parameters.
ACTION_TEMPLATE(CreateNew,
HAS_1_TEMPLATE_PARAMS(typename, T),
AND_1_VALUE_PARAMS(a0)) {
return new T(a0);
}
TEST(ActionTemplateTest, WorksWithValueParams) {
const Action<int*()> a = CreateNew<int>(42);
int* p = a.Perform(make_tuple());
EXPECT_EQ(42, *p);
delete p;
}
// Tests that ACTION_TEMPLATE works for integral template parameters.
ACTION_TEMPLATE(MyDeleteArg,
HAS_1_TEMPLATE_PARAMS(int, k),
AND_0_VALUE_PARAMS()) {
delete std::tr1::get<k>(args);
}
// Resets a bool variable in the destructor.
class BoolResetter {
public:
explicit BoolResetter(bool* value) : value_(value) {}
~BoolResetter() { *value_ = false; }
private:
bool* value_;
};
TEST(ActionTemplateTest, WorksForIntegralTemplateParams) {
const Action<void(int*, BoolResetter*)> a = MyDeleteArg<1>();
int n = 0;
bool b = true;
BoolResetter* resetter = new BoolResetter(&b);
a.Perform(make_tuple(&n, resetter));
EXPECT_FALSE(b); // Verifies that resetter is deleted.
}
// Tests that ACTION_TEMPLATES works for template template parameters.
ACTION_TEMPLATE(ReturnSmartPointer,
HAS_1_TEMPLATE_PARAMS(template <typename Pointee> class,
Pointer),
AND_1_VALUE_PARAMS(pointee)) {
return Pointer<pointee_type>(new pointee_type(pointee));
}
TEST(ActionTemplateTest, WorksForTemplateTemplateParameters) {
using ::testing::internal::linked_ptr;
const Action<linked_ptr<int>()> a = ReturnSmartPointer<linked_ptr>(42);
linked_ptr<int> p = a.Perform(make_tuple());
EXPECT_EQ(42, *p);
}
// Tests that ACTION_TEMPLATE works for 10 template parameters.
template <typename T1, typename T2, typename T3, int k4, bool k5,
unsigned int k6, typename T7, typename T8, typename T9>
struct GiantTemplate {
public:
explicit GiantTemplate(int a_value) : value(a_value) {}
int value;
};
ACTION_TEMPLATE(ReturnGiant,
HAS_10_TEMPLATE_PARAMS(
typename, T1,
typename, T2,
typename, T3,
int, k4,
bool, k5,
unsigned int, k6,
class, T7,
class, T8,
class, T9,
template <typename T> class, T10),
AND_1_VALUE_PARAMS(value)) {
return GiantTemplate<T10<T1>, T2, T3, k4, k5, k6, T7, T8, T9>(value);
}
TEST(ActionTemplateTest, WorksFor10TemplateParameters) {
using ::testing::internal::linked_ptr;
typedef GiantTemplate<linked_ptr<int>, bool, double, 5,
true, 6, char, unsigned, int> Giant;
const Action<Giant()> a = ReturnGiant<
int, bool, double, 5, true, 6, char, unsigned, int, linked_ptr>(42);
Giant giant = a.Perform(make_tuple());
EXPECT_EQ(42, giant.value);
}
// Tests that ACTION_TEMPLATE works for 10 value parameters.
ACTION_TEMPLATE(ReturnSum,
HAS_1_TEMPLATE_PARAMS(typename, Number),
AND_10_VALUE_PARAMS(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10)) {
return static_cast<Number>(v1) + v2 + v3 + v4 + v5 + v6 + v7 + v8 + v9 + v10;
}
TEST(ActionTemplateTest, WorksFor10ValueParameters) {
const Action<int()> a = ReturnSum<int>(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
EXPECT_EQ(55, a.Perform(make_tuple()));
}
// Tests that ACTION_TEMPLATE and ACTION/ACTION_P* can be overloaded
// on the number of value parameters.
ACTION(ReturnSum) { return 0; }
ACTION_P(ReturnSum, x) { return x; }
ACTION_TEMPLATE(ReturnSum,
HAS_1_TEMPLATE_PARAMS(typename, Number),
AND_2_VALUE_PARAMS(v1, v2)) {
return static_cast<Number>(v1) + v2;
}
ACTION_TEMPLATE(ReturnSum,
HAS_1_TEMPLATE_PARAMS(typename, Number),
AND_3_VALUE_PARAMS(v1, v2, v3)) {
return static_cast<Number>(v1) + v2 + v3;
}
ACTION_TEMPLATE(ReturnSum,
HAS_2_TEMPLATE_PARAMS(typename, Number, int, k),
AND_4_VALUE_PARAMS(v1, v2, v3, v4)) {
return static_cast<Number>(v1) + v2 + v3 + v4 + k;
}
TEST(ActionTemplateTest, CanBeOverloadedOnNumberOfValueParameters) {
const Action<int()> a0 = ReturnSum();
const Action<int()> a1 = ReturnSum(1);
const Action<int()> a2 = ReturnSum<int>(1, 2);
const Action<int()> a3 = ReturnSum<int>(1, 2, 3);
const Action<int()> a4 = ReturnSum<int, 10000>(2000, 300, 40, 5);
EXPECT_EQ(0, a0.Perform(make_tuple()));
EXPECT_EQ(1, a1.Perform(make_tuple()));
EXPECT_EQ(3, a2.Perform(make_tuple()));
EXPECT_EQ(6, a3.Perform(make_tuple()));
EXPECT_EQ(12345, a4.Perform(make_tuple()));
}
#ifdef _MSC_VER
# pragma warning(pop)
#endif
} // namespace gmock_generated_actions_test
} // namespace testing
diff --git a/test/gmock-generated-matchers_test.cc b/test/gmock-generated-matchers_test.cc
index 4b7e6e05..0a750de1 100644
--- a/test/gmock-generated-matchers_test.cc
+++ b/test/gmock-generated-matchers_test.cc
@@ -1,1236 +1,1249 @@
// Copyright 2008, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Google Mock - a framework for writing C++ mock classes.
//
// This file tests the built-in matchers generated by a script.
#include "gmock/gmock-generated-matchers.h"
#include <list>
#include <map>
#include <set>
#include <sstream>
#include <string>
#include <utility>
#include <vector>
#include "gmock/gmock.h"
#include "gtest/gtest.h"
#include "gtest/gtest-spi.h"
namespace {
using std::list;
using std::map;
using std::pair;
using std::set;
using std::stringstream;
using std::vector;
using std::tr1::get;
using std::tr1::make_tuple;
using std::tr1::tuple;
using testing::_;
using testing::Args;
using testing::Contains;
using testing::ElementsAre;
using testing::ElementsAreArray;
using testing::Eq;
using testing::Ge;
using testing::Gt;
using testing::Lt;
using testing::MakeMatcher;
using testing::Matcher;
using testing::MatcherInterface;
using testing::MatchResultListener;
using testing::Ne;
using testing::Not;
using testing::Pointee;
using testing::PrintToString;
using testing::Ref;
using testing::StaticAssertTypeEq;
using testing::StrEq;
using testing::Value;
using testing::internal::ElementsAreArrayMatcher;
using testing::internal::string;
// Returns the description of the given matcher.
template <typename T>
string Describe(const Matcher<T>& m) {
stringstream ss;
m.DescribeTo(&ss);
return ss.str();
}
// Returns the description of the negation of the given matcher.
template <typename T>
string DescribeNegation(const Matcher<T>& m) {
stringstream ss;
m.DescribeNegationTo(&ss);
return ss.str();
}
// Returns the reason why x matches, or doesn't match, m.
template <typename MatcherType, typename Value>
string Explain(const MatcherType& m, const Value& x) {
stringstream ss;
m.ExplainMatchResultTo(x, &ss);
return ss.str();
}
// Tests Args<k0, ..., kn>(m).
TEST(ArgsTest, AcceptsZeroTemplateArg) {
const tuple<int, bool> t(5, true);
EXPECT_THAT(t, Args<>(Eq(tuple<>())));
EXPECT_THAT(t, Not(Args<>(Ne(tuple<>()))));
}
TEST(ArgsTest, AcceptsOneTemplateArg) {
const tuple<int, bool> t(5, true);
EXPECT_THAT(t, Args<0>(Eq(make_tuple(5))));
EXPECT_THAT(t, Args<1>(Eq(make_tuple(true))));
EXPECT_THAT(t, Not(Args<1>(Eq(make_tuple(false)))));
}
TEST(ArgsTest, AcceptsTwoTemplateArgs) {
const tuple<short, int, long> t(4, 5, 6L); // NOLINT
EXPECT_THAT(t, (Args<0, 1>(Lt())));
EXPECT_THAT(t, (Args<1, 2>(Lt())));
EXPECT_THAT(t, Not(Args<0, 2>(Gt())));
}
TEST(ArgsTest, AcceptsRepeatedTemplateArgs) {
const tuple<short, int, long> t(4, 5, 6L); // NOLINT
EXPECT_THAT(t, (Args<0, 0>(Eq())));
EXPECT_THAT(t, Not(Args<1, 1>(Ne())));
}
TEST(ArgsTest, AcceptsDecreasingTemplateArgs) {
const tuple<short, int, long> t(4, 5, 6L); // NOLINT
EXPECT_THAT(t, (Args<2, 0>(Gt())));
EXPECT_THAT(t, Not(Args<2, 1>(Lt())));
}
// The MATCHER*() macros trigger warning C4100 (unreferenced formal
// parameter) in MSVC with -W4. Unfortunately they cannot be fixed in
// the macro definition, as the warnings are generated when the macro
// is expanded and macro expansion cannot contain #pragma. Therefore
// we suppress them here.
#ifdef _MSC_VER
# pragma warning(push)
# pragma warning(disable:4100)
#endif
MATCHER(SumIsZero, "") {
return get<0>(arg) + get<1>(arg) + get<2>(arg) == 0;
}
TEST(ArgsTest, AcceptsMoreTemplateArgsThanArityOfOriginalTuple) {
EXPECT_THAT(make_tuple(-1, 2), (Args<0, 0, 1>(SumIsZero())));
EXPECT_THAT(make_tuple(1, 2), Not(Args<0, 0, 1>(SumIsZero())));
}
TEST(ArgsTest, CanBeNested) {
const tuple<short, int, long, int> t(4, 5, 6L, 6); // NOLINT
EXPECT_THAT(t, (Args<1, 2, 3>(Args<1, 2>(Eq()))));
EXPECT_THAT(t, (Args<0, 1, 3>(Args<0, 2>(Lt()))));
}
TEST(ArgsTest, CanMatchTupleByValue) {
typedef tuple<char, int, int> Tuple3;
const Matcher<Tuple3> m = Args<1, 2>(Lt());
EXPECT_TRUE(m.Matches(Tuple3('a', 1, 2)));
EXPECT_FALSE(m.Matches(Tuple3('b', 2, 2)));
}
TEST(ArgsTest, CanMatchTupleByReference) {
typedef tuple<char, char, int> Tuple3;
const Matcher<const Tuple3&> m = Args<0, 1>(Lt());
EXPECT_TRUE(m.Matches(Tuple3('a', 'b', 2)));
EXPECT_FALSE(m.Matches(Tuple3('b', 'b', 2)));
}
// Validates that arg is printed as str.
MATCHER_P(PrintsAs, str, "") {
return testing::PrintToString(arg) == str;
}
TEST(ArgsTest, AcceptsTenTemplateArgs) {
EXPECT_THAT(make_tuple(0, 1L, 2, 3L, 4, 5, 6, 7, 8, 9),
(Args<9, 8, 7, 6, 5, 4, 3, 2, 1, 0>(
PrintsAs("(9, 8, 7, 6, 5, 4, 3, 2, 1, 0)"))));
EXPECT_THAT(make_tuple(0, 1L, 2, 3L, 4, 5, 6, 7, 8, 9),
Not(Args<9, 8, 7, 6, 5, 4, 3, 2, 1, 0>(
PrintsAs("(0, 8, 7, 6, 5, 4, 3, 2, 1, 0)"))));
}
TEST(ArgsTest, DescirbesSelfCorrectly) {
const Matcher<tuple<int, bool, char> > m = Args<2, 0>(Lt());
EXPECT_EQ("are a tuple whose fields (#2, #0) are a pair where "
"the first < the second",
Describe(m));
}
TEST(ArgsTest, DescirbesNestedArgsCorrectly) {
const Matcher<const tuple<int, bool, char, int>&> m =
Args<0, 2, 3>(Args<2, 0>(Lt()));
EXPECT_EQ("are a tuple whose fields (#0, #2, #3) are a tuple "
"whose fields (#2, #0) are a pair where the first < the second",
Describe(m));
}
TEST(ArgsTest, DescribesNegationCorrectly) {
const Matcher<tuple<int, char> > m = Args<1, 0>(Gt());
EXPECT_EQ("are a tuple whose fields (#1, #0) aren't a pair "
"where the first > the second",
DescribeNegation(m));
}
TEST(ArgsTest, ExplainsMatchResultWithoutInnerExplanation) {
const Matcher<tuple<bool, int, int> > m = Args<1, 2>(Eq());
EXPECT_EQ("whose fields (#1, #2) are (42, 42)",
Explain(m, make_tuple(false, 42, 42)));
EXPECT_EQ("whose fields (#1, #2) are (42, 43)",
Explain(m, make_tuple(false, 42, 43)));
}
// For testing Args<>'s explanation.
class LessThanMatcher : public MatcherInterface<tuple<char, int> > {
public:
virtual void DescribeTo(::std::ostream* os) const {}
virtual bool MatchAndExplain(tuple<char, int> value,
MatchResultListener* listener) const {
const int diff = get<0>(value) - get<1>(value);
if (diff > 0) {
*listener << "where the first value is " << diff
<< " more than the second";
}
return diff < 0;
}
};
Matcher<tuple<char, int> > LessThan() {
return MakeMatcher(new LessThanMatcher);
}
TEST(ArgsTest, ExplainsMatchResultWithInnerExplanation) {
const Matcher<tuple<char, int, int> > m = Args<0, 2>(LessThan());
EXPECT_EQ("whose fields (#0, #2) are ('a' (97, 0x61), 42), "
"where the first value is 55 more than the second",
Explain(m, make_tuple('a', 42, 42)));
EXPECT_EQ("whose fields (#0, #2) are ('\\0', 43)",
Explain(m, make_tuple('\0', 42, 43)));
}
// For testing ExplainMatchResultTo().
class GreaterThanMatcher : public MatcherInterface<int> {
public:
explicit GreaterThanMatcher(int rhs) : rhs_(rhs) {}
virtual void DescribeTo(::std::ostream* os) const {
*os << "is greater than " << rhs_;
}
virtual bool MatchAndExplain(int lhs,
MatchResultListener* listener) const {
const int diff = lhs - rhs_;
if (diff > 0) {
*listener << "which is " << diff << " more than " << rhs_;
} else if (diff == 0) {
*listener << "which is the same as " << rhs_;
} else {
*listener << "which is " << -diff << " less than " << rhs_;
}
return lhs > rhs_;
}
private:
int rhs_;
};
Matcher<int> GreaterThan(int n) {
return MakeMatcher(new GreaterThanMatcher(n));
}
// Tests for ElementsAre().
// Evaluates to the number of elements in 'array'.
#define GMOCK_ARRAY_SIZE_(array) (sizeof(array)/sizeof(array[0]))
TEST(ElementsAreTest, CanDescribeExpectingNoElement) {
Matcher<const vector<int>&> m = ElementsAre();
EXPECT_EQ("is empty", Describe(m));
}
TEST(ElementsAreTest, CanDescribeExpectingOneElement) {
Matcher<vector<int> > m = ElementsAre(Gt(5));
EXPECT_EQ("has 1 element that is > 5", Describe(m));
}
TEST(ElementsAreTest, CanDescribeExpectingManyElements) {
Matcher<list<string> > m = ElementsAre(StrEq("one"), "two");
EXPECT_EQ("has 2 elements where\n"
"element #0 is equal to \"one\",\n"
"element #1 is equal to \"two\"", Describe(m));
}
TEST(ElementsAreTest, CanDescribeNegationOfExpectingNoElement) {
Matcher<vector<int> > m = ElementsAre();
EXPECT_EQ("isn't empty", DescribeNegation(m));
}
TEST(ElementsAreTest, CanDescribeNegationOfExpectingOneElment) {
Matcher<const list<int>& > m = ElementsAre(Gt(5));
EXPECT_EQ("doesn't have 1 element, or\n"
"element #0 isn't > 5", DescribeNegation(m));
}
TEST(ElementsAreTest, CanDescribeNegationOfExpectingManyElements) {
Matcher<const list<string>& > m = ElementsAre("one", "two");
EXPECT_EQ("doesn't have 2 elements, or\n"
"element #0 isn't equal to \"one\", or\n"
"element #1 isn't equal to \"two\"", DescribeNegation(m));
}
TEST(ElementsAreTest, DoesNotExplainTrivialMatch) {
Matcher<const list<int>& > m = ElementsAre(1, Ne(2));
list<int> test_list;
test_list.push_back(1);
test_list.push_back(3);
EXPECT_EQ("", Explain(m, test_list)); // No need to explain anything.
}
TEST(ElementsAreTest, ExplainsNonTrivialMatch) {
Matcher<const vector<int>& > m =
ElementsAre(GreaterThan(1), 0, GreaterThan(2));
const int a[] = { 10, 0, 100 };
vector<int> test_vector(a, a + GMOCK_ARRAY_SIZE_(a));
EXPECT_EQ("whose element #0 matches, which is 9 more than 1,\n"
"and whose element #2 matches, which is 98 more than 2",
Explain(m, test_vector));
}
TEST(ElementsAreTest, CanExplainMismatchWrongSize) {
Matcher<const list<int>& > m = ElementsAre(1, 3);
list<int> test_list;
// No need to explain when the container is empty.
EXPECT_EQ("", Explain(m, test_list));
test_list.push_back(1);
EXPECT_EQ("which has 1 element", Explain(m, test_list));
}
TEST(ElementsAreTest, CanExplainMismatchRightSize) {
Matcher<const vector<int>& > m = ElementsAre(1, GreaterThan(5));
vector<int> v;
v.push_back(2);
v.push_back(1);
EXPECT_EQ("whose element #0 doesn't match", Explain(m, v));
v[0] = 1;
EXPECT_EQ("whose element #1 doesn't match, which is 4 less than 5",
Explain(m, v));
}
TEST(ElementsAreTest, MatchesOneElementVector) {
vector<string> test_vector;
test_vector.push_back("test string");
EXPECT_THAT(test_vector, ElementsAre(StrEq("test string")));
}
TEST(ElementsAreTest, MatchesOneElementList) {
list<string> test_list;
test_list.push_back("test string");
EXPECT_THAT(test_list, ElementsAre("test string"));
}
TEST(ElementsAreTest, MatchesThreeElementVector) {
vector<string> test_vector;
test_vector.push_back("one");
test_vector.push_back("two");
test_vector.push_back("three");
EXPECT_THAT(test_vector, ElementsAre("one", StrEq("two"), _));
}
TEST(ElementsAreTest, MatchesOneElementEqMatcher) {
vector<int> test_vector;
test_vector.push_back(4);
EXPECT_THAT(test_vector, ElementsAre(Eq(4)));
}
TEST(ElementsAreTest, MatchesOneElementAnyMatcher) {
vector<int> test_vector;
test_vector.push_back(4);
EXPECT_THAT(test_vector, ElementsAre(_));
}
TEST(ElementsAreTest, MatchesOneElementValue) {
vector<int> test_vector;
test_vector.push_back(4);
EXPECT_THAT(test_vector, ElementsAre(4));
}
TEST(ElementsAreTest, MatchesThreeElementsMixedMatchers) {
vector<int> test_vector;
test_vector.push_back(1);
test_vector.push_back(2);
test_vector.push_back(3);
EXPECT_THAT(test_vector, ElementsAre(1, Eq(2), _));
}
TEST(ElementsAreTest, MatchesTenElementVector) {
const int a[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
vector<int> test_vector(a, a + GMOCK_ARRAY_SIZE_(a));
EXPECT_THAT(test_vector,
// The element list can contain values and/or matchers
// of different types.
ElementsAre(0, Ge(0), _, 3, 4, Ne(2), Eq(6), 7, 8, _));
}
TEST(ElementsAreTest, DoesNotMatchWrongSize) {
vector<string> test_vector;
test_vector.push_back("test string");
test_vector.push_back("test string");
Matcher<vector<string> > m = ElementsAre(StrEq("test string"));
EXPECT_FALSE(m.Matches(test_vector));
}
TEST(ElementsAreTest, DoesNotMatchWrongValue) {
vector<string> test_vector;
test_vector.push_back("other string");
Matcher<vector<string> > m = ElementsAre(StrEq("test string"));
EXPECT_FALSE(m.Matches(test_vector));
}
TEST(ElementsAreTest, DoesNotMatchWrongOrder) {
vector<string> test_vector;
test_vector.push_back("one");
test_vector.push_back("three");
test_vector.push_back("two");
Matcher<vector<string> > m = ElementsAre(
StrEq("one"), StrEq("two"), StrEq("three"));
EXPECT_FALSE(m.Matches(test_vector));
}
TEST(ElementsAreTest, WorksForNestedContainer) {
const char* strings[] = {
"Hi",
"world"
};
vector<list<char> > nested;
for (size_t i = 0; i < GMOCK_ARRAY_SIZE_(strings); i++) {
nested.push_back(list<char>(strings[i], strings[i] + strlen(strings[i])));
}
EXPECT_THAT(nested, ElementsAre(ElementsAre('H', Ne('e')),
ElementsAre('w', 'o', _, _, 'd')));
EXPECT_THAT(nested, Not(ElementsAre(ElementsAre('H', 'e'),
ElementsAre('w', 'o', _, _, 'd'))));
}
TEST(ElementsAreTest, WorksWithByRefElementMatchers) {
int a[] = { 0, 1, 2 };
vector<int> v(a, a + GMOCK_ARRAY_SIZE_(a));
EXPECT_THAT(v, ElementsAre(Ref(v[0]), Ref(v[1]), Ref(v[2])));
EXPECT_THAT(v, Not(ElementsAre(Ref(v[0]), Ref(v[1]), Ref(a[2]))));
}
TEST(ElementsAreTest, WorksWithContainerPointerUsingPointee) {
int a[] = { 0, 1, 2 };
vector<int> v(a, a + GMOCK_ARRAY_SIZE_(a));
EXPECT_THAT(&v, Pointee(ElementsAre(0, 1, _)));
EXPECT_THAT(&v, Not(Pointee(ElementsAre(0, _, 3))));
}
TEST(ElementsAreTest, WorksWithNativeArrayPassedByReference) {
int array[] = { 0, 1, 2 };
EXPECT_THAT(array, ElementsAre(0, 1, _));
EXPECT_THAT(array, Not(ElementsAre(1, _, _)));
EXPECT_THAT(array, Not(ElementsAre(0, _)));
}
class NativeArrayPassedAsPointerAndSize {
public:
NativeArrayPassedAsPointerAndSize() {}
MOCK_METHOD2(Helper, void(int* array, int size));
private:
GTEST_DISALLOW_COPY_AND_ASSIGN_(NativeArrayPassedAsPointerAndSize);
};
TEST(ElementsAreTest, WorksWithNativeArrayPassedAsPointerAndSize) {
int array[] = { 0, 1 };
::std::tr1::tuple<int*, size_t> array_as_tuple(array, 2);
EXPECT_THAT(array_as_tuple, ElementsAre(0, 1));
EXPECT_THAT(array_as_tuple, Not(ElementsAre(0)));
NativeArrayPassedAsPointerAndSize helper;
EXPECT_CALL(helper, Helper(_, _))
.With(ElementsAre(0, 1));
helper.Helper(array, 2);
}
TEST(ElementsAreTest, WorksWithTwoDimensionalNativeArray) {
const char a2[][3] = { "hi", "lo" };
EXPECT_THAT(a2, ElementsAre(ElementsAre('h', 'i', '\0'),
ElementsAre('l', 'o', '\0')));
EXPECT_THAT(a2, ElementsAre(StrEq("hi"), StrEq("lo")));
EXPECT_THAT(a2, ElementsAre(Not(ElementsAre('h', 'o', '\0')),
ElementsAre('l', 'o', '\0')));
}
TEST(ElementsAreTest, AcceptsStringLiteral) {
string array[] = { "hi", "one", "two" };
EXPECT_THAT(array, ElementsAre("hi", "one", "two"));
EXPECT_THAT(array, Not(ElementsAre("hi", "one", "too")));
}
#ifndef _MSC_VER
// The following test passes a value of type const char[] to a
// function template that expects const T&. Some versions of MSVC
// generates a compiler error C2665 for that. We believe it's a bug
// in MSVC. Therefore this test is #if-ed out for MSVC.
// Declared here with the size unknown. Defined AFTER the following test.
extern const char kHi[];
TEST(ElementsAreTest, AcceptsArrayWithUnknownSize) {
// The size of kHi is not known in this test, but ElementsAre() should
// still accept it.
string array1[] = { "hi" };
EXPECT_THAT(array1, ElementsAre(kHi));
string array2[] = { "ho" };
EXPECT_THAT(array2, Not(ElementsAre(kHi)));
}
const char kHi[] = "hi";
#endif // _MSC_VER
TEST(ElementsAreTest, MakesCopyOfArguments) {
int x = 1;
int y = 2;
// This should make a copy of x and y.
::testing::internal::ElementsAreMatcher2<int, int> polymorphic_matcher =
ElementsAre(x, y);
// Changing x and y now shouldn't affect the meaning of the above matcher.
x = y = 0;
const int array1[] = { 1, 2 };
EXPECT_THAT(array1, polymorphic_matcher);
const int array2[] = { 0, 0 };
EXPECT_THAT(array2, Not(polymorphic_matcher));
}
// Tests for ElementsAreArray(). Since ElementsAreArray() shares most
// of the implementation with ElementsAre(), we don't test it as
// thoroughly here.
TEST(ElementsAreArrayTest, CanBeCreatedWithValueArray) {
const int a[] = { 1, 2, 3 };
vector<int> test_vector(a, a + GMOCK_ARRAY_SIZE_(a));
EXPECT_THAT(test_vector, ElementsAreArray(a));
test_vector[2] = 0;
EXPECT_THAT(test_vector, Not(ElementsAreArray(a)));
}
TEST(ElementsAreArrayTest, CanBeCreatedWithArraySize) {
const char* a[] = { "one", "two", "three" };
vector<string> test_vector(a, a + GMOCK_ARRAY_SIZE_(a));
EXPECT_THAT(test_vector, ElementsAreArray(a, GMOCK_ARRAY_SIZE_(a)));
const char** p = a;
test_vector[0] = "1";
EXPECT_THAT(test_vector, Not(ElementsAreArray(p, GMOCK_ARRAY_SIZE_(a))));
}
TEST(ElementsAreArrayTest, CanBeCreatedWithoutArraySize) {
const char* a[] = { "one", "two", "three" };
vector<string> test_vector(a, a + GMOCK_ARRAY_SIZE_(a));
EXPECT_THAT(test_vector, ElementsAreArray(a));
test_vector[0] = "1";
EXPECT_THAT(test_vector, Not(ElementsAreArray(a)));
}
TEST(ElementsAreArrayTest, CanBeCreatedWithMatcherArray) {
const Matcher<string> kMatcherArray[] =
{ StrEq("one"), StrEq("two"), StrEq("three") };
vector<string> test_vector;
test_vector.push_back("one");
test_vector.push_back("two");
test_vector.push_back("three");
EXPECT_THAT(test_vector, ElementsAreArray(kMatcherArray));
test_vector.push_back("three");
EXPECT_THAT(test_vector, Not(ElementsAreArray(kMatcherArray)));
}
TEST(ElementsAreArrayTest, CanBeCreatedWithVector) {
const int a[] = { 1, 2, 3 };
vector<int> test_vector(a, a + GMOCK_ARRAY_SIZE_(a));
const vector<int> expected(a, a + GMOCK_ARRAY_SIZE_(a));
EXPECT_THAT(test_vector, ElementsAreArray(expected));
test_vector.push_back(4);
EXPECT_THAT(test_vector, Not(ElementsAreArray(expected)));
}
TEST(ElementsAreArrayTest, CanBeCreatedWithMatcherVector) {
const int a[] = { 1, 2, 3 };
const Matcher<int> kMatchers[] = { Eq(1), Eq(2), Eq(3) };
vector<int> test_vector(a, a + GMOCK_ARRAY_SIZE_(a));
const vector<Matcher<int> > expected(
kMatchers, kMatchers + GMOCK_ARRAY_SIZE_(kMatchers));
EXPECT_THAT(test_vector, ElementsAreArray(expected));
test_vector.push_back(4);
EXPECT_THAT(test_vector, Not(ElementsAreArray(expected)));
}
TEST(ElementsAreArrayTest, CanBeCreatedWithIteratorRange) {
const int a[] = { 1, 2, 3 };
const vector<int> test_vector(a, a + GMOCK_ARRAY_SIZE_(a));
const vector<int> expected(a, a + GMOCK_ARRAY_SIZE_(a));
EXPECT_THAT(test_vector, ElementsAreArray(expected.begin(), expected.end()));
// Pointers are iterators, too.
EXPECT_THAT(test_vector, ElementsAreArray(a, a + GMOCK_ARRAY_SIZE_(a)));
// The empty range of NULL pointers should also be okay.
int* const null_int = NULL;
EXPECT_THAT(test_vector, Not(ElementsAreArray(null_int, null_int)));
EXPECT_THAT((vector<int>()), ElementsAreArray(null_int, null_int));
}
// Since ElementsAre() and ElementsAreArray() share much of the
// implementation, we only do a sanity test for native arrays here.
TEST(ElementsAreArrayTest, WorksWithNativeArray) {
::std::string a[] = { "hi", "ho" };
::std::string b[] = { "hi", "ho" };
EXPECT_THAT(a, ElementsAreArray(b));
EXPECT_THAT(a, ElementsAreArray(b, 2));
EXPECT_THAT(a, Not(ElementsAreArray(b, 1)));
}
TEST(ElementsAreArrayTest, SourceLifeSpan) {
const int a[] = { 1, 2, 3 };
vector<int> test_vector(a, a + GMOCK_ARRAY_SIZE_(a));
vector<int> expect(a, a + GMOCK_ARRAY_SIZE_(a));
ElementsAreArrayMatcher<int> matcher_maker =
ElementsAreArray(expect.begin(), expect.end());
EXPECT_THAT(test_vector, matcher_maker);
// Changing in place the values that initialized matcher_maker should not
// affect matcher_maker anymore. It should have made its own copy of them.
typedef vector<int>::iterator Iter;
for (Iter it = expect.begin(); it != expect.end(); ++it) { *it += 10; }
EXPECT_THAT(test_vector, matcher_maker);
test_vector.push_back(3);
EXPECT_THAT(test_vector, Not(matcher_maker));
}
// Tests for the MATCHER*() macro family.
// Tests that a simple MATCHER() definition works.
MATCHER(IsEven, "") { return (arg % 2) == 0; }
TEST(MatcherMacroTest, Works) {
const Matcher<int> m = IsEven();
EXPECT_TRUE(m.Matches(6));
EXPECT_FALSE(m.Matches(7));
EXPECT_EQ("is even", Describe(m));
EXPECT_EQ("not (is even)", DescribeNegation(m));
EXPECT_EQ("", Explain(m, 6));
EXPECT_EQ("", Explain(m, 7));
}
// This also tests that the description string can reference 'negation'.
MATCHER(IsEven2, negation ? "is odd" : "is even") {
if ((arg % 2) == 0) {
// Verifies that we can stream to result_listener, a listener
// supplied by the MATCHER macro implicitly.
*result_listener << "OK";
return true;
} else {
*result_listener << "% 2 == " << (arg % 2);
return false;
}
}
// This also tests that the description string can reference matcher
// parameters.
MATCHER_P2(EqSumOf, x, y,
string(negation ? "doesn't equal" : "equals") + " the sum of " +
PrintToString(x) + " and " + PrintToString(y)) {
if (arg == (x + y)) {
*result_listener << "OK";
return true;
} else {
// Verifies that we can stream to the underlying stream of
// result_listener.
if (result_listener->stream() != NULL) {
*result_listener->stream() << "diff == " << (x + y - arg);
}
return false;
}
}
// Tests that the matcher description can reference 'negation' and the
// matcher parameters.
TEST(MatcherMacroTest, DescriptionCanReferenceNegationAndParameters) {
const Matcher<int> m1 = IsEven2();
EXPECT_EQ("is even", Describe(m1));
EXPECT_EQ("is odd", DescribeNegation(m1));
const Matcher<int> m2 = EqSumOf(5, 9);
EXPECT_EQ("equals the sum of 5 and 9", Describe(m2));
EXPECT_EQ("doesn't equal the sum of 5 and 9", DescribeNegation(m2));
}
// Tests explaining match result in a MATCHER* macro.
TEST(MatcherMacroTest, CanExplainMatchResult) {
const Matcher<int> m1 = IsEven2();
EXPECT_EQ("OK", Explain(m1, 4));
EXPECT_EQ("% 2 == 1", Explain(m1, 5));
const Matcher<int> m2 = EqSumOf(1, 2);
EXPECT_EQ("OK", Explain(m2, 3));
EXPECT_EQ("diff == -1", Explain(m2, 4));
}
// Tests that the body of MATCHER() can reference the type of the
// value being matched.
MATCHER(IsEmptyString, "") {
StaticAssertTypeEq< ::std::string, arg_type>();
return arg == "";
}
MATCHER(IsEmptyStringByRef, "") {
StaticAssertTypeEq<const ::std::string&, arg_type>();
return arg == "";
}
TEST(MatcherMacroTest, CanReferenceArgType) {
const Matcher< ::std::string> m1 = IsEmptyString();
EXPECT_TRUE(m1.Matches(""));
const Matcher<const ::std::string&> m2 = IsEmptyStringByRef();
EXPECT_TRUE(m2.Matches(""));
}
// Tests that MATCHER() can be used in a namespace.
namespace matcher_test {
MATCHER(IsOdd, "") { return (arg % 2) != 0; }
} // namespace matcher_test
TEST(MatcherMacroTest, WorksInNamespace) {
Matcher<int> m = matcher_test::IsOdd();
EXPECT_FALSE(m.Matches(4));
EXPECT_TRUE(m.Matches(5));
}
// Tests that Value() can be used to compose matchers.
MATCHER(IsPositiveOdd, "") {
return Value(arg, matcher_test::IsOdd()) && arg > 0;
}
TEST(MatcherMacroTest, CanBeComposedUsingValue) {
EXPECT_THAT(3, IsPositiveOdd());
EXPECT_THAT(4, Not(IsPositiveOdd()));
EXPECT_THAT(-1, Not(IsPositiveOdd()));
}
// Tests that a simple MATCHER_P() definition works.
MATCHER_P(IsGreaterThan32And, n, "") { return arg > 32 && arg > n; }
TEST(MatcherPMacroTest, Works) {
const Matcher<int> m = IsGreaterThan32And(5);
EXPECT_TRUE(m.Matches(36));
EXPECT_FALSE(m.Matches(5));
EXPECT_EQ("is greater than 32 and 5", Describe(m));
EXPECT_EQ("not (is greater than 32 and 5)", DescribeNegation(m));
EXPECT_EQ("", Explain(m, 36));
EXPECT_EQ("", Explain(m, 5));
}
// Tests that the description is calculated correctly from the matcher name.
MATCHER_P(_is_Greater_Than32and_, n, "") { return arg > 32 && arg > n; }
TEST(MatcherPMacroTest, GeneratesCorrectDescription) {
const Matcher<int> m = _is_Greater_Than32and_(5);
EXPECT_EQ("is greater than 32 and 5", Describe(m));
EXPECT_EQ("not (is greater than 32 and 5)", DescribeNegation(m));
EXPECT_EQ("", Explain(m, 36));
EXPECT_EQ("", Explain(m, 5));
}
// Tests that a MATCHER_P matcher can be explicitly instantiated with
// a reference parameter type.
class UncopyableFoo {
public:
explicit UncopyableFoo(char value) : value_(value) {}
private:
UncopyableFoo(const UncopyableFoo&);
void operator=(const UncopyableFoo&);
char value_;
};
MATCHER_P(ReferencesUncopyable, variable, "") { return &arg == &variable; }
TEST(MatcherPMacroTest, WorksWhenExplicitlyInstantiatedWithReference) {
UncopyableFoo foo1('1'), foo2('2');
const Matcher<const UncopyableFoo&> m =
ReferencesUncopyable<const UncopyableFoo&>(foo1);
EXPECT_TRUE(m.Matches(foo1));
EXPECT_FALSE(m.Matches(foo2));
// We don't want the address of the parameter printed, as most
// likely it will just annoy the user. If the address is
// interesting, the user should consider passing the parameter by
// pointer instead.
EXPECT_EQ("references uncopyable 1-byte object <31>", Describe(m));
}
// Tests that the body of MATCHER_Pn() can reference the parameter
// types.
MATCHER_P3(ParamTypesAreIntLongAndChar, foo, bar, baz, "") {
StaticAssertTypeEq<int, foo_type>();
StaticAssertTypeEq<long, bar_type>(); // NOLINT
StaticAssertTypeEq<char, baz_type>();
return arg == 0;
}
TEST(MatcherPnMacroTest, CanReferenceParamTypes) {
EXPECT_THAT(0, ParamTypesAreIntLongAndChar(10, 20L, 'a'));
}
// Tests that a MATCHER_Pn matcher can be explicitly instantiated with
// reference parameter types.
MATCHER_P2(ReferencesAnyOf, variable1, variable2, "") {
return &arg == &variable1 || &arg == &variable2;
}
TEST(MatcherPnMacroTest, WorksWhenExplicitlyInstantiatedWithReferences) {
UncopyableFoo foo1('1'), foo2('2'), foo3('3');
const Matcher<const UncopyableFoo&> m =
ReferencesAnyOf<const UncopyableFoo&, const UncopyableFoo&>(foo1, foo2);
EXPECT_TRUE(m.Matches(foo1));
EXPECT_TRUE(m.Matches(foo2));
EXPECT_FALSE(m.Matches(foo3));
}
TEST(MatcherPnMacroTest,
GeneratesCorretDescriptionWhenExplicitlyInstantiatedWithReferences) {
UncopyableFoo foo1('1'), foo2('2');
const Matcher<const UncopyableFoo&> m =
ReferencesAnyOf<const UncopyableFoo&, const UncopyableFoo&>(foo1, foo2);
// We don't want the addresses of the parameters printed, as most
// likely they will just annoy the user. If the addresses are
// interesting, the user should consider passing the parameters by
// pointers instead.
EXPECT_EQ("references any of (1-byte object <31>, 1-byte object <32>)",
Describe(m));
}
// Tests that a simple MATCHER_P2() definition works.
MATCHER_P2(IsNotInClosedRange, low, hi, "") { return arg < low || arg > hi; }
TEST(MatcherPnMacroTest, Works) {
const Matcher<const long&> m = IsNotInClosedRange(10, 20); // NOLINT
EXPECT_TRUE(m.Matches(36L));
EXPECT_FALSE(m.Matches(15L));
EXPECT_EQ("is not in closed range (10, 20)", Describe(m));
EXPECT_EQ("not (is not in closed range (10, 20))", DescribeNegation(m));
EXPECT_EQ("", Explain(m, 36L));
EXPECT_EQ("", Explain(m, 15L));
}
// Tests that MATCHER*() definitions can be overloaded on the number
// of parameters; also tests MATCHER_Pn() where n >= 3.
MATCHER(EqualsSumOf, "") { return arg == 0; }
MATCHER_P(EqualsSumOf, a, "") { return arg == a; }
MATCHER_P2(EqualsSumOf, a, b, "") { return arg == a + b; }
MATCHER_P3(EqualsSumOf, a, b, c, "") { return arg == a + b + c; }
MATCHER_P4(EqualsSumOf, a, b, c, d, "") { return arg == a + b + c + d; }
MATCHER_P5(EqualsSumOf, a, b, c, d, e, "") { return arg == a + b + c + d + e; }
MATCHER_P6(EqualsSumOf, a, b, c, d, e, f, "") {
return arg == a + b + c + d + e + f;
}
MATCHER_P7(EqualsSumOf, a, b, c, d, e, f, g, "") {
return arg == a + b + c + d + e + f + g;
}
MATCHER_P8(EqualsSumOf, a, b, c, d, e, f, g, h, "") {
return arg == a + b + c + d + e + f + g + h;
}
MATCHER_P9(EqualsSumOf, a, b, c, d, e, f, g, h, i, "") {
return arg == a + b + c + d + e + f + g + h + i;
}
MATCHER_P10(EqualsSumOf, a, b, c, d, e, f, g, h, i, j, "") {
return arg == a + b + c + d + e + f + g + h + i + j;
}
TEST(MatcherPnMacroTest, CanBeOverloadedOnNumberOfParameters) {
EXPECT_THAT(0, EqualsSumOf());
EXPECT_THAT(1, EqualsSumOf(1));
EXPECT_THAT(12, EqualsSumOf(10, 2));
EXPECT_THAT(123, EqualsSumOf(100, 20, 3));
EXPECT_THAT(1234, EqualsSumOf(1000, 200, 30, 4));
EXPECT_THAT(12345, EqualsSumOf(10000, 2000, 300, 40, 5));
EXPECT_THAT("abcdef",
EqualsSumOf(::std::string("a"), 'b', 'c', "d", "e", 'f'));
EXPECT_THAT("abcdefg",
EqualsSumOf(::std::string("a"), 'b', 'c', "d", "e", 'f', 'g'));
EXPECT_THAT("abcdefgh",
EqualsSumOf(::std::string("a"), 'b', 'c', "d", "e", 'f', 'g',
"h"));
EXPECT_THAT("abcdefghi",
EqualsSumOf(::std::string("a"), 'b', 'c', "d", "e", 'f', 'g',
"h", 'i'));
EXPECT_THAT("abcdefghij",
EqualsSumOf(::std::string("a"), 'b', 'c', "d", "e", 'f', 'g',
"h", 'i', ::std::string("j")));
EXPECT_THAT(1, Not(EqualsSumOf()));
EXPECT_THAT(-1, Not(EqualsSumOf(1)));
EXPECT_THAT(-12, Not(EqualsSumOf(10, 2)));
EXPECT_THAT(-123, Not(EqualsSumOf(100, 20, 3)));
EXPECT_THAT(-1234, Not(EqualsSumOf(1000, 200, 30, 4)));
EXPECT_THAT(-12345, Not(EqualsSumOf(10000, 2000, 300, 40, 5)));
EXPECT_THAT("abcdef ",
Not(EqualsSumOf(::std::string("a"), 'b', 'c', "d", "e", 'f')));
EXPECT_THAT("abcdefg ",
Not(EqualsSumOf(::std::string("a"), 'b', 'c', "d", "e", 'f',
'g')));
EXPECT_THAT("abcdefgh ",
Not(EqualsSumOf(::std::string("a"), 'b', 'c', "d", "e", 'f', 'g',
"h")));
EXPECT_THAT("abcdefghi ",
Not(EqualsSumOf(::std::string("a"), 'b', 'c', "d", "e", 'f', 'g',
"h", 'i')));
EXPECT_THAT("abcdefghij ",
Not(EqualsSumOf(::std::string("a"), 'b', 'c', "d", "e", 'f', 'g',
"h", 'i', ::std::string("j"))));
}
// Tests that a MATCHER_Pn() definition can be instantiated with any
// compatible parameter types.
TEST(MatcherPnMacroTest, WorksForDifferentParameterTypes) {
EXPECT_THAT(123, EqualsSumOf(100L, 20, static_cast<char>(3)));
EXPECT_THAT("abcd", EqualsSumOf(::std::string("a"), "b", 'c', "d"));
EXPECT_THAT(124, Not(EqualsSumOf(100L, 20, static_cast<char>(3))));
EXPECT_THAT("abcde", Not(EqualsSumOf(::std::string("a"), "b", 'c', "d")));
}
// Tests that the matcher body can promote the parameter types.
MATCHER_P2(EqConcat, prefix, suffix, "") {
// The following lines promote the two parameters to desired types.
std::string prefix_str(prefix);
char suffix_char = static_cast<char>(suffix);
return arg == prefix_str + suffix_char;
}
TEST(MatcherPnMacroTest, SimpleTypePromotion) {
Matcher<std::string> no_promo =
EqConcat(std::string("foo"), 't');
Matcher<const std::string&> promo =
EqConcat("foo", static_cast<int>('t'));
EXPECT_FALSE(no_promo.Matches("fool"));
EXPECT_FALSE(promo.Matches("fool"));
EXPECT_TRUE(no_promo.Matches("foot"));
EXPECT_TRUE(promo.Matches("foot"));
}
// Verifies the type of a MATCHER*.
TEST(MatcherPnMacroTest, TypesAreCorrect) {
// EqualsSumOf() must be assignable to a EqualsSumOfMatcher variable.
EqualsSumOfMatcher a0 = EqualsSumOf();
// EqualsSumOf(1) must be assignable to a EqualsSumOfMatcherP variable.
EqualsSumOfMatcherP<int> a1 = EqualsSumOf(1);
// EqualsSumOf(p1, ..., pk) must be assignable to a EqualsSumOfMatcherPk
// variable, and so on.
EqualsSumOfMatcherP2<int, char> a2 = EqualsSumOf(1, '2');
EqualsSumOfMatcherP3<int, int, char> a3 = EqualsSumOf(1, 2, '3');
EqualsSumOfMatcherP4<int, int, int, char> a4 = EqualsSumOf(1, 2, 3, '4');
EqualsSumOfMatcherP5<int, int, int, int, char> a5 =
EqualsSumOf(1, 2, 3, 4, '5');
EqualsSumOfMatcherP6<int, int, int, int, int, char> a6 =
EqualsSumOf(1, 2, 3, 4, 5, '6');
EqualsSumOfMatcherP7<int, int, int, int, int, int, char> a7 =
EqualsSumOf(1, 2, 3, 4, 5, 6, '7');
EqualsSumOfMatcherP8<int, int, int, int, int, int, int, char> a8 =
EqualsSumOf(1, 2, 3, 4, 5, 6, 7, '8');
EqualsSumOfMatcherP9<int, int, int, int, int, int, int, int, char> a9 =
EqualsSumOf(1, 2, 3, 4, 5, 6, 7, 8, '9');
EqualsSumOfMatcherP10<int, int, int, int, int, int, int, int, int, char> a10 =
EqualsSumOf(1, 2, 3, 4, 5, 6, 7, 8, 9, '0');
+
+ // Avoid "unused variable" warnings.
+ (void)a0;
+ (void)a1;
+ (void)a2;
+ (void)a3;
+ (void)a4;
+ (void)a5;
+ (void)a6;
+ (void)a7;
+ (void)a8;
+ (void)a9;
+ (void)a10;
}
// Tests that matcher-typed parameters can be used in Value() inside a
// MATCHER_Pn definition.
// Succeeds if arg matches exactly 2 of the 3 matchers.
MATCHER_P3(TwoOf, m1, m2, m3, "") {
const int count = static_cast<int>(Value(arg, m1))
+ static_cast<int>(Value(arg, m2)) + static_cast<int>(Value(arg, m3));
return count == 2;
}
TEST(MatcherPnMacroTest, CanUseMatcherTypedParameterInValue) {
EXPECT_THAT(42, TwoOf(Gt(0), Lt(50), Eq(10)));
EXPECT_THAT(0, Not(TwoOf(Gt(-1), Lt(1), Eq(0))));
}
// Tests Contains().
TEST(ContainsTest, ListMatchesWhenElementIsInContainer) {
list<int> some_list;
some_list.push_back(3);
some_list.push_back(1);
some_list.push_back(2);
EXPECT_THAT(some_list, Contains(1));
EXPECT_THAT(some_list, Contains(Gt(2.5)));
EXPECT_THAT(some_list, Contains(Eq(2.0f)));
list<string> another_list;
another_list.push_back("fee");
another_list.push_back("fie");
another_list.push_back("foe");
another_list.push_back("fum");
EXPECT_THAT(another_list, Contains(string("fee")));
}
TEST(ContainsTest, ListDoesNotMatchWhenElementIsNotInContainer) {
list<int> some_list;
some_list.push_back(3);
some_list.push_back(1);
EXPECT_THAT(some_list, Not(Contains(4)));
}
TEST(ContainsTest, SetMatchesWhenElementIsInContainer) {
set<int> some_set;
some_set.insert(3);
some_set.insert(1);
some_set.insert(2);
EXPECT_THAT(some_set, Contains(Eq(1.0)));
EXPECT_THAT(some_set, Contains(Eq(3.0f)));
EXPECT_THAT(some_set, Contains(2));
set<const char*> another_set;
another_set.insert("fee");
another_set.insert("fie");
another_set.insert("foe");
another_set.insert("fum");
EXPECT_THAT(another_set, Contains(Eq(string("fum"))));
}
TEST(ContainsTest, SetDoesNotMatchWhenElementIsNotInContainer) {
set<int> some_set;
some_set.insert(3);
some_set.insert(1);
EXPECT_THAT(some_set, Not(Contains(4)));
set<const char*> c_string_set;
c_string_set.insert("hello");
EXPECT_THAT(c_string_set, Not(Contains(string("hello").c_str())));
}
TEST(ContainsTest, ExplainsMatchResultCorrectly) {
const int a[2] = { 1, 2 };
Matcher<const int (&)[2]> m = Contains(2);
EXPECT_EQ("whose element #1 matches", Explain(m, a));
m = Contains(3);
EXPECT_EQ("", Explain(m, a));
m = Contains(GreaterThan(0));
EXPECT_EQ("whose element #0 matches, which is 1 more than 0", Explain(m, a));
m = Contains(GreaterThan(10));
EXPECT_EQ("", Explain(m, a));
}
TEST(ContainsTest, DescribesItselfCorrectly) {
Matcher<vector<int> > m = Contains(1);
EXPECT_EQ("contains at least one element that is equal to 1", Describe(m));
Matcher<vector<int> > m2 = Not(m);
EXPECT_EQ("doesn't contain any element that is equal to 1", Describe(m2));
}
TEST(ContainsTest, MapMatchesWhenElementIsInContainer) {
map<const char*, int> my_map;
const char* bar = "a string";
my_map[bar] = 2;
EXPECT_THAT(my_map, Contains(pair<const char* const, int>(bar, 2)));
map<string, int> another_map;
another_map["fee"] = 1;
another_map["fie"] = 2;
another_map["foe"] = 3;
another_map["fum"] = 4;
EXPECT_THAT(another_map, Contains(pair<const string, int>(string("fee"), 1)));
EXPECT_THAT(another_map, Contains(pair<const string, int>("fie", 2)));
}
TEST(ContainsTest, MapDoesNotMatchWhenElementIsNotInContainer) {
map<int, int> some_map;
some_map[1] = 11;
some_map[2] = 22;
EXPECT_THAT(some_map, Not(Contains(pair<const int, int>(2, 23))));
}
TEST(ContainsTest, ArrayMatchesWhenElementIsInContainer) {
const char* string_array[] = { "fee", "fie", "foe", "fum" };
EXPECT_THAT(string_array, Contains(Eq(string("fum"))));
}
TEST(ContainsTest, ArrayDoesNotMatchWhenElementIsNotInContainer) {
int int_array[] = { 1, 2, 3, 4 };
EXPECT_THAT(int_array, Not(Contains(5)));
}
TEST(ContainsTest, AcceptsMatcher) {
const int a[] = { 1, 2, 3 };
EXPECT_THAT(a, Contains(Gt(2)));
EXPECT_THAT(a, Not(Contains(Gt(4))));
}
TEST(ContainsTest, WorksForNativeArrayAsTuple) {
const int a[] = { 1, 2 };
const int* const pointer = a;
EXPECT_THAT(make_tuple(pointer, 2), Contains(1));
EXPECT_THAT(make_tuple(pointer, 2), Not(Contains(Gt(3))));
}
TEST(ContainsTest, WorksForTwoDimensionalNativeArray) {
int a[][3] = { { 1, 2, 3 }, { 4, 5, 6 } };
EXPECT_THAT(a, Contains(ElementsAre(4, 5, 6)));
EXPECT_THAT(a, Contains(Contains(5)));
EXPECT_THAT(a, Not(Contains(ElementsAre(3, 4, 5))));
EXPECT_THAT(a, Contains(Not(Contains(5))));
}
TEST(AllOfTest, HugeMatcher) {
// Verify that using AllOf with many arguments doesn't cause
// the compiler to exceed template instantiation depth limit.
EXPECT_THAT(0, testing::AllOf(_, _, _, _, _, _, _, _, _,
testing::AllOf(_, _, _, _, _, _, _, _, _, _)));
}
TEST(AnyOfTest, HugeMatcher) {
// Verify that using AnyOf with many arguments doesn't cause
// the compiler to exceed template instantiation depth limit.
EXPECT_THAT(0, testing::AnyOf(_, _, _, _, _, _, _, _, _,
testing::AnyOf(_, _, _, _, _, _, _, _, _, _)));
}
namespace adl_test {
// Verifies that the implementation of ::testing::AllOf and ::testing::AnyOf
// don't issue unqualified recursive calls. If they do, the argument dependent
// name lookup will cause AllOf/AnyOf in the 'adl_test' namespace to be found
// as a candidate and the compilation will break due to an ambiguous overload.
// The matcher must be in the same namespace as AllOf/AnyOf to make argument
// dependent lookup find those.
MATCHER(M, "") { return true; }
template <typename T1, typename T2>
bool AllOf(const T1& t1, const T2& t2) { return true; }
TEST(AllOfTest, DoesNotCallAllOfUnqualified) {
EXPECT_THAT(42, testing::AllOf(
M(), M(), M(), M(), M(), M(), M(), M(), M(), M()));
}
template <typename T1, typename T2> bool
AnyOf(const T1& t1, const T2& t2) { return true; }
TEST(AnyOfTest, DoesNotCallAnyOfUnqualified) {
EXPECT_THAT(42, testing::AnyOf(
M(), M(), M(), M(), M(), M(), M(), M(), M(), M()));
}
} // namespace adl_test
#ifdef _MSC_VER
# pragma warning(pop)
#endif
} // namespace
Event Timeline
Log In to Comment