diff options
| author | shiqian <shiqian@8415998a-534a-0410-bf83-d39667b30386> | 2008-12-10 05:08:54 +0000 | 
|---|---|---|
| committer | shiqian <shiqian@8415998a-534a-0410-bf83-d39667b30386> | 2008-12-10 05:08:54 +0000 | 
| commit | e35fdd936d133bf8a48de140a3c666897588a053 (patch) | |
| tree | 4e1dbda63ddea04bab288b1f2999896103bac4c3 /test | |
| download | googletest-e35fdd936d133bf8a48de140a3c666897588a053.tar.gz googletest-e35fdd936d133bf8a48de140a3c666897588a053.tar.bz2 googletest-e35fdd936d133bf8a48de140a3c666897588a053.zip | |
Initial drop of Google Mock.  The files are incomplete and thus may not build correctly yet.
Diffstat (limited to 'test')
| -rw-r--r-- | test/gmock-actions_test.cc | 902 | ||||
| -rw-r--r-- | test/gmock-cardinalities_test.cc | 422 | ||||
| -rw-r--r-- | test/gmock-generated-actions_test.cc | 946 | ||||
| -rw-r--r-- | test/gmock-generated-function-mockers_test.cc | 426 | ||||
| -rw-r--r-- | test/gmock-generated-internal-utils_test.cc | 127 | ||||
| -rw-r--r-- | test/gmock-generated-matchers_test.cc | 373 | ||||
| -rw-r--r-- | test/gmock-internal-utils_test.cc | 521 | ||||
| -rw-r--r-- | test/gmock-matchers_test.cc | 2629 | ||||
| -rw-r--r-- | test/gmock-nice-strict_test.cc | 228 | ||||
| -rw-r--r-- | test/gmock-port_test.cc | 95 | ||||
| -rw-r--r-- | test/gmock-printers_test.cc | 903 | ||||
| -rw-r--r-- | test/gmock-sample.cc | 32 | ||||
| -rw-r--r-- | test/gmock-sample.h | 49 | ||||
| -rw-r--r-- | test/gmock-spec-builders_test.cc | 1889 | ||||
| -rw-r--r-- | test/gmock_link_test.cc | 37 | ||||
| -rwxr-xr-x | test/gmock_output_test.py | 200 | ||||
| -rw-r--r-- | test/gmock_output_test_.cc | 241 | ||||
| -rw-r--r-- | test/gmock_output_test_golden.txt | 296 | ||||
| -rw-r--r-- | test/gmock_test.cc | 248 | ||||
| -rwxr-xr-x | test/gmock_test_utils.py | 126 | 
20 files changed, 10690 insertions, 0 deletions
| diff --git a/test/gmock-actions_test.cc b/test/gmock-actions_test.cc new file mode 100644 index 00000000..1000e306 --- /dev/null +++ b/test/gmock-actions_test.cc @@ -0,0 +1,902 @@ +// 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::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::SetArgumentPointee; +using testing::SetArrayArgument; +using testing::SetErrnoAndReturn; + +#if GMOCK_HAS_PROTOBUF_ +using testing::internal::TestMessage; +#endif  // GMOCK_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>::Get() returns 0 when T is a +// built-in numeric type. +TEST(BuiltInDefaultValueTest, IsZeroForNumericTypes) { +  EXPECT_EQ(0, BuiltInDefaultValue<unsigned char>::Get()); +  EXPECT_EQ(0, BuiltInDefaultValue<signed char>::Get()); +  EXPECT_EQ(0, BuiltInDefaultValue<char>::Get()); +#ifndef GTEST_OS_WINDOWS +  EXPECT_EQ(0, BuiltInDefaultValue<unsigned wchar_t>::Get()); +  EXPECT_EQ(0, BuiltInDefaultValue<signed wchar_t>::Get()); +#endif  // GTEST_OS_WINDOWS +  EXPECT_EQ(0, BuiltInDefaultValue<wchar_t>::Get()); +  EXPECT_EQ(0, BuiltInDefaultValue<unsigned short>::Get());  // NOLINT +  EXPECT_EQ(0, BuiltInDefaultValue<signed short>::Get());  // NOLINT +  EXPECT_EQ(0, BuiltInDefaultValue<short>::Get());  // NOLINT +  EXPECT_EQ(0, BuiltInDefaultValue<unsigned int>::Get()); +  EXPECT_EQ(0, BuiltInDefaultValue<signed int>::Get()); +  EXPECT_EQ(0, BuiltInDefaultValue<int>::Get()); +  EXPECT_EQ(0, BuiltInDefaultValue<unsigned long>::Get());  // NOLINT +  EXPECT_EQ(0, BuiltInDefaultValue<signed long>::Get());  // NOLINT +  EXPECT_EQ(0, BuiltInDefaultValue<long>::Get());  // NOLINT +  EXPECT_EQ(0, BuiltInDefaultValue<UInt64>::Get()); +  EXPECT_EQ(0, BuiltInDefaultValue<Int64>::Get()); +  EXPECT_EQ(0, BuiltInDefaultValue<float>::Get()); +  EXPECT_EQ(0, BuiltInDefaultValue<double>::Get()); +} + +// Tests that BuiltInDefaultValue<bool>::Get() returns false. +TEST(BuiltInDefaultValueTest, IsFalseForBool) { +  EXPECT_FALSE(BuiltInDefaultValue<bool>::Get()); +} + +// 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 + +#if GTEST_HAS_STD_STRING +  EXPECT_EQ("", BuiltInDefaultValue< ::std::string>::Get()); +#endif  // GTEST_HAS_STD_STRING +} + +// 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; +}; + +#ifdef GTEST_HAS_DEATH_TEST + +// Tests that BuiltInDefaultValue<T&>::Get() aborts the program. +TEST(BuiltInDefaultValueDeathTest, IsUndefinedForReferences) { +  EXPECT_DEATH({  // NOLINT +    BuiltInDefaultValue<int&>::Get(); +  }, ""); +  EXPECT_DEATH({  // NOLINT +    BuiltInDefaultValue<const char&>::Get(); +  }, ""); +} + +TEST(BuiltInDefaultValueDeathTest, IsUndefinedForUserTypes) { +  EXPECT_DEATH({  // NOLINT +    BuiltInDefaultValue<UserType>::Get(); +  }, ""); +} + +#endif  // GTEST_HAS_DEATH_TEST + +// 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) { +  DefaultValue<int>::Set(1); +  DefaultValue<const UserType>::Set(UserType()); + +  EXPECT_EQ(1, DefaultValue<int>::Get()); +  EXPECT_EQ(0, DefaultValue<const UserType>::Get().value); + +  DefaultValue<int>::Clear(); +  DefaultValue<const UserType>::Clear(); + +  EXPECT_FALSE(DefaultValue<int>::IsSet()); +  EXPECT_FALSE(DefaultValue<const UserType>::IsSet()); +} + +// 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_FALSE(DefaultValue<UserType>::IsSet()); + +  EXPECT_EQ(0, DefaultValue<int>::Get()); + +#ifdef GTEST_HAS_DEATH_TEST +  EXPECT_DEATH({  // NOLINT +    DefaultValue<UserType>::Get(); +  }, ""); +#endif  // GTEST_HAS_DEATH_TEST +} + +// 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&> can be set and then unset. +TEST(DefaultValueOfReferenceTest, CanBeSetAndUnset) { +  int n = 1; +  DefaultValue<const int&>::Set(n); +  UserType u; +  DefaultValue<UserType&>::Set(u); + +  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&>::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()); + +#ifdef GTEST_HAS_DEATH_TEST +  EXPECT_DEATH({  // NOLINT +    DefaultValue<int&>::Get(); +  }, ""); +  EXPECT_DEATH({  // NOLINT +    DefaultValue<UserType>::Get(); +  }, ""); +#endif  // GTEST_HAS_DEATH_TEST +} + +// 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; + +  EXPECT_FALSE(my_action_impl.IsDoDefault()); +} + +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; +  } +}; + +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'))); +} + +// 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 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 DoDefault() does the default action for the mock method. + +class MyClass {}; + +class MockClass { + public: +  MOCK_METHOD1(IntFunc, int(bool flag));  // NOLINT +  MOCK_METHOD0(Foo, MyClass()); +}; + +// 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)); +} + +#ifdef GTEST_HAS_DEATH_TEST + +// Tests that DoDefault() 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()); +  EXPECT_DEATH({  // NOLINT +    mock.Foo(); +  }, ""); +} + +// 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({  // NOLINT +    mock.IntFunc(true); +  }, ""); +} + +#endif  // GTEST_HAS_DEATH_TEST + +// 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 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 GMOCK_HAS_PROTOBUF_ + +// Tests that SetArgumentPointee<N>(proto_buffer) sets the variable +// pointed to by the N-th (0-based) argument to proto_buffer. +TEST(SetArgumentPointeeTest, SetsTheNthPointeeOfProtoBufferType) { +  typedef void MyFunction(bool, TestMessage*); +  TestMessage* const msg = new TestMessage; +  msg->set_member("yes"); +  TestMessage orig_msg; +  orig_msg.CopyFrom(*msg); + +  Action<MyFunction> 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>(proto2_buffer) sets the variable +// pointed to by the N-th (0-based) argument to proto2_buffer. +TEST(SetArgumentPointeeTest, SetsTheNthPointeeOfProto2BufferType) { +  using testing::internal::FooMessage; +  typedef void MyFunction(bool, FooMessage*); +  FooMessage* const msg = new FooMessage; +  msg->set_int_field(2); +  msg->set_string_field("hi"); +  FooMessage orig_msg; +  orig_msg.CopyFrom(*msg); + +  Action<MyFunction> 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()); +} + +#endif  // GMOCK_HAS_PROTOBUF_ + +// Tests that SetArrayArgument<N>(first, last) sets the elements of the array +// pointed to by the N-th (0-based) argument to values in range [first, last). +TEST(SetArrayArgumentTest, SetsTheNthArray) { +  typedef void MyFunction(bool, int*, char*); +  int numbers[] = { 1, 2, 3 }; +  Action<MyFunction> a = SetArrayArgument<1>(numbers, numbers + 3); + +  int n[4] = {}; +  int* pn = n; +  char ch[4] = {}; +  char* pch = ch; +  a.Perform(make_tuple(true, pn, pch)); +  EXPECT_EQ(1, n[0]); +  EXPECT_EQ(2, n[1]); +  EXPECT_EQ(3, n[2]); +  EXPECT_EQ(0, n[3]); +  EXPECT_EQ('\0', ch[0]); +  EXPECT_EQ('\0', ch[1]); +  EXPECT_EQ('\0', ch[2]); +  EXPECT_EQ('\0', ch[3]); + +  // Tests first and last are iterators. +  std::string letters = "abc"; +  a = SetArrayArgument<2>(letters.begin(), letters.end()); +  std::fill_n(n, 4, 0); +  std::fill_n(ch, 4, '\0'); +  a.Perform(make_tuple(true, pn, pch)); +  EXPECT_EQ(0, n[0]); +  EXPECT_EQ(0, n[1]); +  EXPECT_EQ(0, n[2]); +  EXPECT_EQ(0, n[3]); +  EXPECT_EQ('a', ch[0]); +  EXPECT_EQ('b', ch[1]); +  EXPECT_EQ('c', ch[2]); +  EXPECT_EQ('\0', ch[3]); +} + +// Tests SetArrayArgument<N>(first, last) where first == last. +TEST(SetArrayArgumentTest, SetsTheNthArrayWithEmptyRange) { +  typedef void MyFunction(bool, int*); +  int numbers[] = { 1, 2, 3 }; +  Action<MyFunction> a = SetArrayArgument<1>(numbers, numbers); + +  int n[4] = {}; +  int* pn = n; +  a.Perform(make_tuple(true, pn)); +  EXPECT_EQ(0, n[0]); +  EXPECT_EQ(0, n[1]); +  EXPECT_EQ(0, n[2]); +  EXPECT_EQ(0, n[3]); +} + +// Tests SetArrayArgument<N>(first, last) where *first is convertible +// (but not equal) to the argument type. +TEST(SetArrayArgumentTest, SetsTheNthArrayWithConvertibleType) { +  typedef void MyFunction(bool, char*); +  int codes[] = { 97, 98, 99 }; +  Action<MyFunction> a = SetArrayArgument<1>(codes, codes + 3); + +  char ch[4] = {}; +  char* pch = ch; +  a.Perform(make_tuple(true, pch)); +  EXPECT_EQ('a', ch[0]); +  EXPECT_EQ('b', ch[1]); +  EXPECT_EQ('c', ch[2]); +  EXPECT_EQ('\0', ch[3]); +} + +// Test SetArrayArgument<N>(first, last) with iterator as argument. +TEST(SetArrayArgumentTest, SetsTheNthArrayWithIteratorArgument) { +  typedef void MyFunction(bool, std::back_insert_iterator<std::string>); +  std::string letters = "abc"; +  Action<MyFunction> a = SetArrayArgument<1>(letters.begin(), letters.end()); + +  std::string s; +  a.Perform(make_tuple(true, back_inserter(s))); +  EXPECT_EQ(letters, s); +} + +// 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<short(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<short(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); +} + +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); +} + +}  // Unnamed namespace diff --git a/test/gmock-cardinalities_test.cc b/test/gmock-cardinalities_test.cc new file mode 100644 index 00000000..f3f1e106 --- /dev/null +++ b/test/gmock-cardinalities_test.cc @@ -0,0 +1,422 @@ +// 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 cardinalities. + +#include <gmock/gmock.h> +#include <gtest/gtest.h> +#include <gtest/gtest-spi.h> + +namespace { + +using std::stringstream; +using testing::AnyNumber; +using testing::AtLeast; +using testing::AtMost; +using testing::Between; +using testing::Cardinality; +using testing::CardinalityInterface; +using testing::Exactly; +using testing::IsSubstring; +using testing::MakeCardinality; + +class MockFoo { + public: +  MOCK_METHOD0(Bar, int());  // NOLINT +}; + +// Tests that Cardinality objects can be default constructed. +TEST(CardinalityTest, IsDefaultConstructable) { +  Cardinality c; +} + +// Tests that Cardinality objects are copyable. +TEST(CardinalityTest, IsCopyable) { +  // Tests the copy constructor. +  Cardinality c = Exactly(1); +  EXPECT_FALSE(c.IsSatisfiedByCallCount(0)); +  EXPECT_TRUE(c.IsSatisfiedByCallCount(1)); +  EXPECT_TRUE(c.IsSaturatedByCallCount(1)); + +  // Tests the assignment operator. +  c = Exactly(2); +  EXPECT_FALSE(c.IsSatisfiedByCallCount(1)); +  EXPECT_TRUE(c.IsSatisfiedByCallCount(2)); +  EXPECT_TRUE(c.IsSaturatedByCallCount(2)); +} + +TEST(CardinalityTest, IsOverSaturatedByCallCountWorks) { +  const Cardinality c = AtMost(5); +  EXPECT_FALSE(c.IsOverSaturatedByCallCount(4)); +  EXPECT_FALSE(c.IsOverSaturatedByCallCount(5)); +  EXPECT_TRUE(c.IsOverSaturatedByCallCount(6)); +} + +// Tests that Cardinality::DescribeActualCallCountTo() creates the +// correct description. +TEST(CardinalityTest, CanDescribeActualCallCount) { +  stringstream ss0; +  Cardinality::DescribeActualCallCountTo(0, &ss0); +  EXPECT_EQ("never called", ss0.str()); + +  stringstream ss1; +  Cardinality::DescribeActualCallCountTo(1, &ss1); +  EXPECT_EQ("called once", ss1.str()); + +  stringstream ss2; +  Cardinality::DescribeActualCallCountTo(2, &ss2); +  EXPECT_EQ("called twice", ss2.str()); + +  stringstream ss3; +  Cardinality::DescribeActualCallCountTo(3, &ss3); +  EXPECT_EQ("called 3 times", ss3.str()); +} + +// Tests AnyNumber() +TEST(AnyNumber, Works) { +  const Cardinality c = AnyNumber(); +  EXPECT_TRUE(c.IsSatisfiedByCallCount(0)); +  EXPECT_FALSE(c.IsSaturatedByCallCount(0)); + +  EXPECT_TRUE(c.IsSatisfiedByCallCount(1)); +  EXPECT_FALSE(c.IsSaturatedByCallCount(1)); + +  EXPECT_TRUE(c.IsSatisfiedByCallCount(9)); +  EXPECT_FALSE(c.IsSaturatedByCallCount(9)); + +  stringstream ss; +  c.DescribeTo(&ss); +  EXPECT_PRED_FORMAT2(IsSubstring, "called any number of times", +                      ss.str()); +} + +TEST(AnyNumberTest, HasCorrectBounds) { +  const Cardinality c = AnyNumber(); +  EXPECT_EQ(0, c.ConservativeLowerBound()); +  EXPECT_EQ(INT_MAX, c.ConservativeUpperBound()); +} + +// Tests AtLeast(n). + +TEST(AtLeastTest, OnNegativeNumber) { +  EXPECT_NONFATAL_FAILURE({  // NOLINT +    AtLeast(-1); +  }, "The invocation lower bound must be >= 0"); +} + +TEST(AtLeastTest, OnZero) { +  const Cardinality c = AtLeast(0); +  EXPECT_TRUE(c.IsSatisfiedByCallCount(0)); +  EXPECT_FALSE(c.IsSaturatedByCallCount(0)); + +  EXPECT_TRUE(c.IsSatisfiedByCallCount(1)); +  EXPECT_FALSE(c.IsSaturatedByCallCount(1)); + +  stringstream ss; +  c.DescribeTo(&ss); +  EXPECT_PRED_FORMAT2(IsSubstring, "any number of times", +                      ss.str()); +} + +TEST(AtLeastTest, OnPositiveNumber) { +  const Cardinality c = AtLeast(2); +  EXPECT_FALSE(c.IsSatisfiedByCallCount(0)); +  EXPECT_FALSE(c.IsSaturatedByCallCount(0)); + +  EXPECT_FALSE(c.IsSatisfiedByCallCount(1)); +  EXPECT_FALSE(c.IsSaturatedByCallCount(1)); + +  EXPECT_TRUE(c.IsSatisfiedByCallCount(2)); +  EXPECT_FALSE(c.IsSaturatedByCallCount(2)); + +  stringstream ss1; +  AtLeast(1).DescribeTo(&ss1); +  EXPECT_PRED_FORMAT2(IsSubstring, "at least once", +                      ss1.str()); + +  stringstream ss2; +  c.DescribeTo(&ss2); +  EXPECT_PRED_FORMAT2(IsSubstring, "at least twice", +                      ss2.str()); + +  stringstream ss3; +  AtLeast(3).DescribeTo(&ss3); +  EXPECT_PRED_FORMAT2(IsSubstring, "at least 3 times", +                      ss3.str()); +} + +TEST(AtLeastTest, HasCorrectBounds) { +  const Cardinality c = AtLeast(2); +  EXPECT_EQ(2, c.ConservativeLowerBound()); +  EXPECT_EQ(INT_MAX, c.ConservativeUpperBound()); +} + +// Tests AtMost(n). + +TEST(AtMostTest, OnNegativeNumber) { +  EXPECT_NONFATAL_FAILURE({  // NOLINT +    AtMost(-1); +  }, "The invocation upper bound must be >= 0"); +} + +TEST(AtMostTest, OnZero) { +  const Cardinality c = AtMost(0); +  EXPECT_TRUE(c.IsSatisfiedByCallCount(0)); +  EXPECT_TRUE(c.IsSaturatedByCallCount(0)); + +  EXPECT_FALSE(c.IsSatisfiedByCallCount(1)); +  EXPECT_TRUE(c.IsSaturatedByCallCount(1)); + +  stringstream ss; +  c.DescribeTo(&ss); +  EXPECT_PRED_FORMAT2(IsSubstring, "never called", +                      ss.str()); +} + +TEST(AtMostTest, OnPositiveNumber) { +  const Cardinality c = AtMost(2); +  EXPECT_TRUE(c.IsSatisfiedByCallCount(0)); +  EXPECT_FALSE(c.IsSaturatedByCallCount(0)); + +  EXPECT_TRUE(c.IsSatisfiedByCallCount(1)); +  EXPECT_FALSE(c.IsSaturatedByCallCount(1)); + +  EXPECT_TRUE(c.IsSatisfiedByCallCount(2)); +  EXPECT_TRUE(c.IsSaturatedByCallCount(2)); + +  stringstream ss1; +  AtMost(1).DescribeTo(&ss1); +  EXPECT_PRED_FORMAT2(IsSubstring, "called at most once", +                      ss1.str()); + +  stringstream ss2; +  c.DescribeTo(&ss2); +  EXPECT_PRED_FORMAT2(IsSubstring, "called at most twice", +                      ss2.str()); + +  stringstream ss3; +  AtMost(3).DescribeTo(&ss3); +  EXPECT_PRED_FORMAT2(IsSubstring, "called at most 3 times", +                      ss3.str()); +} + +TEST(AtMostTest, HasCorrectBounds) { +  const Cardinality c = AtMost(2); +  EXPECT_EQ(0, c.ConservativeLowerBound()); +  EXPECT_EQ(2, c.ConservativeUpperBound()); +} + +// Tests Between(m, n). + +TEST(BetweenTest, OnNegativeStart) { +  EXPECT_NONFATAL_FAILURE({  // NOLINT +    Between(-1, 2); +  }, "The invocation lower bound must be >= 0, but is actually -1"); +} + +TEST(BetweenTest, OnNegativeEnd) { +  EXPECT_NONFATAL_FAILURE({  // NOLINT +    Between(1, -2); +  }, "The invocation upper bound must be >= 0, but is actually -2"); +} + +TEST(BetweenTest, OnStartBiggerThanEnd) { +  EXPECT_NONFATAL_FAILURE({  // NOLINT +    Between(2, 1); +  }, "The invocation upper bound (1) must be >= " +     "the invocation lower bound (2)"); +} + +TEST(BetweenTest, OnZeroStartAndZeroEnd) { +  const Cardinality c = Between(0, 0); + +  EXPECT_TRUE(c.IsSatisfiedByCallCount(0)); +  EXPECT_TRUE(c.IsSaturatedByCallCount(0)); + +  EXPECT_FALSE(c.IsSatisfiedByCallCount(1)); +  EXPECT_TRUE(c.IsSaturatedByCallCount(1)); + +  stringstream ss; +  c.DescribeTo(&ss); +  EXPECT_PRED_FORMAT2(IsSubstring, "never called", +                      ss.str()); +} + +TEST(BetweenTest, OnZeroStartAndNonZeroEnd) { +  const Cardinality c = Between(0, 2); + +  EXPECT_TRUE(c.IsSatisfiedByCallCount(0)); +  EXPECT_FALSE(c.IsSaturatedByCallCount(0)); + +  EXPECT_TRUE(c.IsSatisfiedByCallCount(2)); +  EXPECT_TRUE(c.IsSaturatedByCallCount(2)); + +  EXPECT_FALSE(c.IsSatisfiedByCallCount(4)); +  EXPECT_TRUE(c.IsSaturatedByCallCount(4)); + +  stringstream ss; +  c.DescribeTo(&ss); +  EXPECT_PRED_FORMAT2(IsSubstring, "called at most twice", +                      ss.str()); +} + +TEST(BetweenTest, OnSameStartAndEnd) { +  const Cardinality c = Between(3, 3); + +  EXPECT_FALSE(c.IsSatisfiedByCallCount(2)); +  EXPECT_FALSE(c.IsSaturatedByCallCount(2)); + +  EXPECT_TRUE(c.IsSatisfiedByCallCount(3)); +  EXPECT_TRUE(c.IsSaturatedByCallCount(3)); + +  EXPECT_FALSE(c.IsSatisfiedByCallCount(4)); +  EXPECT_TRUE(c.IsSaturatedByCallCount(4)); + +  stringstream ss; +  c.DescribeTo(&ss); +  EXPECT_PRED_FORMAT2(IsSubstring, "called 3 times", +                      ss.str()); +} + +TEST(BetweenTest, OnDifferentStartAndEnd) { +  const Cardinality c = Between(3, 5); + +  EXPECT_FALSE(c.IsSatisfiedByCallCount(2)); +  EXPECT_FALSE(c.IsSaturatedByCallCount(2)); + +  EXPECT_TRUE(c.IsSatisfiedByCallCount(3)); +  EXPECT_FALSE(c.IsSaturatedByCallCount(3)); + +  EXPECT_TRUE(c.IsSatisfiedByCallCount(5)); +  EXPECT_TRUE(c.IsSaturatedByCallCount(5)); + +  EXPECT_FALSE(c.IsSatisfiedByCallCount(6)); +  EXPECT_TRUE(c.IsSaturatedByCallCount(6)); + +  stringstream ss; +  c.DescribeTo(&ss); +  EXPECT_PRED_FORMAT2(IsSubstring, "called between 3 and 5 times", +                      ss.str()); +} + +TEST(BetweenTest, HasCorrectBounds) { +  const Cardinality c = Between(3, 5); +  EXPECT_EQ(3, c.ConservativeLowerBound()); +  EXPECT_EQ(5, c.ConservativeUpperBound()); +} + +// Tests Exactly(n). + +TEST(ExactlyTest, OnNegativeNumber) { +  EXPECT_NONFATAL_FAILURE({  // NOLINT +    Exactly(-1); +  }, "The invocation lower bound must be >= 0"); +} + +TEST(ExactlyTest, OnZero) { +  const Cardinality c = Exactly(0); +  EXPECT_TRUE(c.IsSatisfiedByCallCount(0)); +  EXPECT_TRUE(c.IsSaturatedByCallCount(0)); + +  EXPECT_FALSE(c.IsSatisfiedByCallCount(1)); +  EXPECT_TRUE(c.IsSaturatedByCallCount(1)); + +  stringstream ss; +  c.DescribeTo(&ss); +  EXPECT_PRED_FORMAT2(IsSubstring, "never called", +                      ss.str()); +} + +TEST(ExactlyTest, OnPositiveNumber) { +  const Cardinality c = Exactly(2); +  EXPECT_FALSE(c.IsSatisfiedByCallCount(0)); +  EXPECT_FALSE(c.IsSaturatedByCallCount(0)); + +  EXPECT_TRUE(c.IsSatisfiedByCallCount(2)); +  EXPECT_TRUE(c.IsSaturatedByCallCount(2)); + +  stringstream ss1; +  Exactly(1).DescribeTo(&ss1); +  EXPECT_PRED_FORMAT2(IsSubstring, "called once", +                      ss1.str()); + +  stringstream ss2; +  c.DescribeTo(&ss2); +  EXPECT_PRED_FORMAT2(IsSubstring, "called twice", +                      ss2.str()); + +  stringstream ss3; +  Exactly(3).DescribeTo(&ss3); +  EXPECT_PRED_FORMAT2(IsSubstring, "called 3 times", +                      ss3.str()); +} + +TEST(ExactlyTest, HasCorrectBounds) { +  const Cardinality c = Exactly(3); +  EXPECT_EQ(3, c.ConservativeLowerBound()); +  EXPECT_EQ(3, c.ConservativeUpperBound()); +} + +// Tests that a user can make his own cardinality by implementing +// CardinalityInterface and calling MakeCardinality(). + +class EvenCardinality : public CardinalityInterface { + public: +  // Returns true iff call_count calls will satisfy this cardinality. +  virtual bool IsSatisfiedByCallCount(int call_count) const { +    return (call_count % 2 == 0); +  } + +  // Returns true iff call_count calls will saturate this cardinality. +  virtual bool IsSaturatedByCallCount(int call_count) const { return false; } + +  // Describes self to an ostream. +  virtual void DescribeTo(::std::ostream* ss) const { +    *ss << "called even number of times"; +  } +}; + +TEST(MakeCardinalityTest, ConstructsCardinalityFromInterface) { +  const Cardinality c = MakeCardinality(new EvenCardinality); + +  EXPECT_TRUE(c.IsSatisfiedByCallCount(2)); +  EXPECT_FALSE(c.IsSatisfiedByCallCount(3)); + +  EXPECT_FALSE(c.IsSaturatedByCallCount(10000)); + +  stringstream ss; +  c.DescribeTo(&ss); +  EXPECT_EQ("called even number of times", ss.str()); +} + +}  // Unnamed namespace diff --git a/test/gmock-generated-actions_test.cc b/test/gmock-generated-actions_test.cc new file mode 100644 index 00000000..4f2e877a --- /dev/null +++ b/test/gmock-generated-actions_test.cc @@ -0,0 +1,946 @@ +// 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 <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::InvokeArgument; +using testing::Return; +using testing::SetArgumentPointee; +using testing::Unused; +using testing::WithArg; +using testing::WithArgs; +using testing::WithoutArgs; + +// 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 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; } + +int SumOfFirst2(int a, int b, Unused, Unused) { return a + b; } + +void VoidFunctionWithFourArguments(char, int, float, double) { g_done = true; } + +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; +} + +class Foo { + public: +  Foo() : value_(123) {} + +  int Nullary() const { return value_; } + +  short Unary(long x) { return static_cast<short>(value_ + x); }  // NOLINT + +  string Binary(const 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 SumOfLast2(Unused, Unused, int a, int b) const { return a + b; } + +  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; +  } + +  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; +  } + private: +  int value_; +}; + +// Tests using Invoke() with a nullary function. +TEST(InvokeTest, Nullary) { +  Action<int()> a = Invoke(Nullary);  // NOLINT +  EXPECT_EQ(1, a.Perform(make_tuple())); +} + +// Tests using Invoke() with a unary function. +TEST(InvokeTest, Unary) { +  Action<bool(int)> a = Invoke(Unary);  // NOLINT +  EXPECT_FALSE(a.Perform(make_tuple(1))); +  EXPECT_TRUE(a.Perform(make_tuple(-1))); +} + +// Tests using Invoke() with a binary function. +TEST(InvokeTest, Binary) { +  Action<const char*(const char*, short)> a = Invoke(Binary);  // NOLINT +  const char* p = "Hello"; +  EXPECT_EQ(p + 2, a.Perform(make_tuple(p, 2))); +} + +// Tests using Invoke() with a ternary function. +TEST(InvokeTest, Ternary) { +  Action<int(int, char, short)> a = Invoke(Ternary);  // NOLINT +  EXPECT_EQ(6, a.Perform(make_tuple(1, '\2', 3))); +} + +// Tests using Invoke() with a 4-argument function. +TEST(InvokeTest, FunctionThatTakes4Arguments) { +  Action<int(int, int, int, int)> a = Invoke(SumOf4);  // NOLINT +  EXPECT_EQ(1234, a.Perform(make_tuple(1000, 200, 30, 4))); +} + +// Tests using Invoke() with a 5-argument function. +TEST(InvokeTest, FunctionThatTakes5Arguments) { +  Action<int(int, int, int, int, int)> a = Invoke(SumOf5);  // NOLINT +  EXPECT_EQ(12345, a.Perform(make_tuple(10000, 2000, 300, 40, 5))); +} + +// Tests using Invoke() with a 6-argument function. +TEST(InvokeTest, FunctionThatTakes6Arguments) { +  Action<int(int, int, int, int, int, int)> a = Invoke(SumOf6);  // NOLINT +  EXPECT_EQ(123456, a.Perform(make_tuple(100000, 20000, 3000, 400, 50, 6))); +} + +// Tests using Invoke() with a 7-argument function. +TEST(InvokeTest, FunctionThatTakes7Arguments) { +  Action<string(const char*, const char*, const char*, const char*, +                const char*, const char*, const char*)> a = +      Invoke(Concat7); +  EXPECT_EQ("1234567", +            a.Perform(make_tuple("1", "2", "3", "4", "5", "6", "7"))); +} + +// Tests using Invoke() with a 8-argument function. +TEST(InvokeTest, FunctionThatTakes8Arguments) { +  Action<string(const char*, const char*, const char*, const char*, +                const char*, const char*, const char*, const char*)> a = +      Invoke(Concat8); +  EXPECT_EQ("12345678", +            a.Perform(make_tuple("1", "2", "3", "4", "5", "6", "7", "8"))); +} + +// Tests using Invoke() with a 9-argument function. +TEST(InvokeTest, FunctionThatTakes9Arguments) { +  Action<string(const char*, const char*, const char*, const char*, +                const char*, const char*, const char*, const char*, +                const char*)> a = Invoke(Concat9); +  EXPECT_EQ("123456789", +            a.Perform(make_tuple("1", "2", "3", "4", "5", "6", "7", "8", "9"))); +} + +// Tests using Invoke() with a 10-argument function. +TEST(InvokeTest, FunctionThatTakes10Arguments) { +  Action<string(const char*, const char*, const char*, const char*, +                const char*, const char*, const char*, const char*, +                const char*, const char*)> a = Invoke(Concat10); +  EXPECT_EQ("1234567890", a.Perform(make_tuple("1", "2", "3", "4", "5", "6", +                                               "7", "8", "9", "0"))); +} + +// Tests using Invoke() with functions with parameters declared as Unused. +TEST(InvokeTest, FunctionWithUnusedParameters) { +  Action<int(int, int, double, const string&)> a1 = +      Invoke(SumOfFirst2); +  EXPECT_EQ(12, a1.Perform(make_tuple(10, 2, 5.6, "hi"))); + +  Action<int(int, int, bool, int*)> a2 = +      Invoke(SumOfFirst2); +  EXPECT_EQ(23, a2.Perform(make_tuple(20, 3, true, static_cast<int*>(NULL)))); +} + +// Tests using Invoke() with methods with parameters declared as Unused. +TEST(InvokeTest, MethodWithUnusedParameters) { +  Foo foo; +  Action<int(string, bool, int, int)> a1 = +      Invoke(&foo, &Foo::SumOfLast2); +  EXPECT_EQ(12, a1.Perform(make_tuple("hi", true, 10, 2))); + +  Action<int(char, double, int, int)> a2 = +      Invoke(&foo, &Foo::SumOfLast2); +  EXPECT_EQ(23, a2.Perform(make_tuple('a', 2.5, 20, 3))); +} + +// Tests using Invoke() with a functor. +TEST(InvokeTest, Functor) { +  Action<int(short, char)> a = Invoke(plus<short>());  // NOLINT +  EXPECT_EQ(3, a.Perform(make_tuple(1, 2))); +} + +// Tests using Invoke(f) as an action of a compatible type. +TEST(InvokeTest, FunctionWithCompatibleType) { +  Action<long(int, short, char, bool)> a = Invoke(SumOf4);  // NOLINT +  EXPECT_EQ(4321, a.Perform(make_tuple(4000, 300, 20, true))); +} + +// Tests using Invoke() with an object pointer and a method pointer. + +// Tests using Invoke() with a nullary method. +TEST(InvokeMethodTest, Nullary) { +  Foo foo; +  Action<int()> a = Invoke(&foo, &Foo::Nullary);  // NOLINT +  EXPECT_EQ(123, a.Perform(make_tuple())); +} + +// Tests using Invoke() with a unary method. +TEST(InvokeMethodTest, Unary) { +  Foo foo; +  Action<short(long)> a = Invoke(&foo, &Foo::Unary);  // NOLINT +  EXPECT_EQ(4123, a.Perform(make_tuple(4000))); +} + +// Tests using Invoke() with a binary method. +TEST(InvokeMethodTest, Binary) { +  Foo foo; +  Action<string(const string&, char)> a = Invoke(&foo, &Foo::Binary); +  string s("Hell"); +  EXPECT_EQ("Hello", a.Perform(make_tuple(s, 'o'))); +} + +// Tests using Invoke() with a ternary method. +TEST(InvokeMethodTest, Ternary) { +  Foo foo; +  Action<int(int, bool, char)> a = Invoke(&foo, &Foo::Ternary);  // NOLINT +  EXPECT_EQ(1124, a.Perform(make_tuple(1000, true, 1))); +} + +// Tests using Invoke() with a 4-argument method. +TEST(InvokeMethodTest, MethodThatTakes4Arguments) { +  Foo foo; +  Action<int(int, int, int, int)> a = Invoke(&foo, &Foo::SumOf4);  // NOLINT +  EXPECT_EQ(1357, a.Perform(make_tuple(1000, 200, 30, 4))); +} + +// Tests using Invoke() with a 5-argument method. +TEST(InvokeMethodTest, MethodThatTakes5Arguments) { +  Foo foo; +  Action<int(int, int, int, int, int)> a = Invoke(&foo, &Foo::SumOf5);  // NOLINT +  EXPECT_EQ(12345, a.Perform(make_tuple(10000, 2000, 300, 40, 5))); +} + +// Tests using Invoke() with a 6-argument method. +TEST(InvokeMethodTest, MethodThatTakes6Arguments) { +  Foo foo; +  Action<int(int, int, int, int, int, int)> a =  // NOLINT +      Invoke(&foo, &Foo::SumOf6); +  EXPECT_EQ(123456, a.Perform(make_tuple(100000, 20000, 3000, 400, 50, 6))); +} + +// Tests using Invoke() with a 7-argument method. +TEST(InvokeMethodTest, MethodThatTakes7Arguments) { +  Foo foo; +  Action<string(const char*, const char*, const char*, const char*, +                const char*, const char*, const char*)> a = +      Invoke(&foo, &Foo::Concat7); +  EXPECT_EQ("1234567", +            a.Perform(make_tuple("1", "2", "3", "4", "5", "6", "7"))); +} + +// Tests using Invoke() with a 8-argument method. +TEST(InvokeMethodTest, MethodThatTakes8Arguments) { +  Foo foo; +  Action<string(const char*, const char*, const char*, const char*, +                const char*, const char*, const char*, const char*)> a = +      Invoke(&foo, &Foo::Concat8); +  EXPECT_EQ("12345678", +            a.Perform(make_tuple("1", "2", "3", "4", "5", "6", "7", "8"))); +} + +// Tests using Invoke() with a 9-argument method. +TEST(InvokeMethodTest, MethodThatTakes9Arguments) { +  Foo foo; +  Action<string(const char*, const char*, const char*, const char*, +                const char*, const char*, const char*, const char*, +                const char*)> a = Invoke(&foo, &Foo::Concat9); +  EXPECT_EQ("123456789", +            a.Perform(make_tuple("1", "2", "3", "4", "5", "6", "7", "8", "9"))); +} + +// Tests using Invoke() with a 10-argument method. +TEST(InvokeMethodTest, MethodThatTakes10Arguments) { +  Foo foo; +  Action<string(const char*, const char*, const char*, const char*, +                const char*, const char*, const char*, const char*, +                const char*, const char*)> a = Invoke(&foo, &Foo::Concat10); +  EXPECT_EQ("1234567890", a.Perform(make_tuple("1", "2", "3", "4", "5", "6", +                                               "7", "8", "9", "0"))); +} + +// Tests using Invoke(f) as an action of a compatible type. +TEST(InvokeMethodTest, MethodWithCompatibleType) { +  Foo foo; +  Action<long(int, short, char, bool)> a =  // NOLINT +      Invoke(&foo, &Foo::SumOf4); +  EXPECT_EQ(4444, a.Perform(make_tuple(4000, 300, 20, true))); +} + +// Tests ByRef(). + +// Tests that ReferenceWrapper<T> is copyable. +TEST(ByRefTest, IsCopyable) { +  const string s1 = "Hi"; +  const string s2 = "Hello"; + +  ::testing::internal::ReferenceWrapper<const string> ref_wrapper = ByRef(s1); +  const string& r1 = ref_wrapper; +  EXPECT_EQ(&s1, &r1); + +  // Assigns a new value to ref_wrapper. +  ref_wrapper = ByRef(s2); +  const string& r2 = ref_wrapper; +  EXPECT_EQ(&s2, &r2); + +  ::testing::internal::ReferenceWrapper<const string> ref_wrapper1 = ByRef(s1); +  // Copies ref_wrapper1 to ref_wrapper. +  ref_wrapper = ref_wrapper1; +  const 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); +} + +struct Base { +  bool operator==(const Base&) { return true; } +}; + +struct Derived : public Base { +  bool operator==(const Derived&) { return true; } +}; + +// 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 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"), 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", 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 WithoutArgs with an action that takes no argument. +TEST(WithoutArgsTest, NoArg) { +  Action<int(int n)> a = WithoutArgs(Invoke(Nullary));  // NOLINT +  EXPECT_EQ(1, a.Perform(make_tuple(2))); +} + +// Tests using WithArgs and WithArg 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))); + +  // Also tests the synonym WithArg. +  Action<bool(double x, int n)> b = WithArg<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, int n)> a = +      WithArgs<0, 2>(Invoke(Binary)); +  const char s[] = "Hello"; +  EXPECT_EQ(s + 2, a.Perform(make_tuple(s, 0.5, 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, 20, 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("0", "1", 2.5, "3", "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("0", "1", "2", "3", "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("0", "1", "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("0", "1", "2", "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("0", "1", "2", "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("0", "1", "2", "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("0", "1", "2", "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("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, 20, 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(2, s))); +} + +// Tests using WithArgs with compatible, but not identical, argument types. +TEST(WithArgsTest, ArgsOfCompatibleTypes) { +  Action<long(short x, int y, double z, char c)> a =  // NOLINT +      WithArgs<0, 1, 3>(Invoke(Ternary)); +  EXPECT_EQ(123, a.Perform(make_tuple(100, 20, 5.6, 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(SetArgumentPointee<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(SetArgumentPointee<0>(1),  // NOLINT +                                    SetArgumentPointee<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(SetArgumentPointee<0>(1), +            SetArgumentPointee<1>(2), +            SetArgumentPointee<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(SetArgumentPointee<0>(1), +            SetArgumentPointee<1>(2), +            SetArgumentPointee<2>('a'), +            SetArgumentPointee<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(SetArgumentPointee<0>(1), +            SetArgumentPointee<1>(2), +            SetArgumentPointee<2>('a'), +            SetArgumentPointee<3>('b'), +            SetArgumentPointee<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(SetArgumentPointee<0>(1), +            SetArgumentPointee<1>(2), +            SetArgumentPointee<2>('a'), +            SetArgumentPointee<3>('b'), +            SetArgumentPointee<4>('c'), +            SetArgumentPointee<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(SetArgumentPointee<0>(1), +            SetArgumentPointee<1>(2), +            SetArgumentPointee<2>('a'), +            SetArgumentPointee<3>('b'), +            SetArgumentPointee<4>('c'), +            SetArgumentPointee<5>('d'), +            SetArgumentPointee<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(SetArgumentPointee<0>(1), +            SetArgumentPointee<1>(2), +            SetArgumentPointee<2>('a'), +            SetArgumentPointee<3>('b'), +            SetArgumentPointee<4>('c'), +            SetArgumentPointee<5>('d'), +            SetArgumentPointee<6>('e'), +            SetArgumentPointee<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(SetArgumentPointee<0>(1), +            SetArgumentPointee<1>(2), +            SetArgumentPointee<2>('a'), +            SetArgumentPointee<3>('b'), +            SetArgumentPointee<4>('c'), +            SetArgumentPointee<5>('d'), +            SetArgumentPointee<6>('e'), +            SetArgumentPointee<7>('f'), +            SetArgumentPointee<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); +} + +}  // namespace gmock_generated_actions_test +}  // namespace testing diff --git a/test/gmock-generated-function-mockers_test.cc b/test/gmock-generated-function-mockers_test.cc new file mode 100644 index 00000000..d8e678b2 --- /dev/null +++ b/test/gmock-generated-function-mockers_test.cc @@ -0,0 +1,426 @@ +// 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 function mocker classes. + +#include <gmock/gmock-generated-function-mockers.h> + +#include <map> +#include <string> +#include <gmock/gmock.h> +#include <gtest/gtest.h> + +#ifdef GTEST_OS_WINDOWS +// MSDN says the header file to be included for STDMETHOD is BaseTyps.h but +// we are getting compiler errors if we use basetyps.h, hence including +// objbase.h for definition of STDMETHOD. +#include <objbase.h> +#endif  // GTEST_OS_WINDOWS + +// There is a bug in MSVC (fixed in VS 2008) that prevents creating a +// mock for a function with const arguments, so we don't test such +// cases for MSVC versions older than 2008. +#if !defined(GTEST_OS_WINDOWS) || (_MSC_VER >= 1500) +#define GMOCK_ALLOWS_CONST_PARAM_FUNCTIONS +#endif  // !defined(GTEST_OS_WINDOWS) || (_MSC_VER >= 1500) + +namespace testing { +namespace gmock_generated_function_mockers_test { + +using testing::internal::string; +using testing::_; +using testing::A; +using testing::An; +using testing::AnyNumber; +using testing::Const; +using testing::DoDefault; +using testing::Eq; +using testing::Lt; +using testing::Ref; +using testing::Return; +using testing::ReturnRef; +using testing::TypedEq; + +class FooInterface { + public: +  virtual ~FooInterface() {} + +  virtual void VoidReturning(int x) = 0; + +  virtual int Nullary() = 0; +  virtual bool Unary(int x) = 0; +  virtual long Binary(short x, int y) = 0;  // NOLINT +  virtual int Decimal(bool b, char c, short d, int e, long f,  // NOLINT +                      float g, double h, unsigned i, char* j, const string& k) +      = 0; + +  virtual bool TakesNonConstReference(int& n) = 0;  // NOLINT +  virtual string TakesConstReference(const int& n) = 0; +#ifdef GMOCK_ALLOWS_CONST_PARAM_FUNCTIONS +  virtual bool TakesConst(const int x) = 0; +#endif  // GMOCK_ALLOWS_CONST_PARAM_FUNCTIONS + +  virtual int OverloadedOnArgumentNumber() = 0; +  virtual int OverloadedOnArgumentNumber(int n) = 0; + +  virtual int OverloadedOnArgumentType(int n) = 0; +  virtual char OverloadedOnArgumentType(char c) = 0; + +  virtual int OverloadedOnConstness() = 0; +  virtual char OverloadedOnConstness() const = 0; + +  virtual int TypeWithHole(int (*func)()) = 0; +  virtual int TypeWithComma(const std::map<int, string>& a_map) = 0; + +#ifdef GTEST_OS_WINDOWS +  STDMETHOD_(int, CTNullary)() = 0; +  STDMETHOD_(bool, CTUnary)(int x) = 0; +  STDMETHOD_(int, CTDecimal)(bool b, char c, short d, int e, long f,  // NOLINT +      float g, double h, unsigned i, char* j, const string& k) = 0; +  STDMETHOD_(char, CTConst)(int x) const = 0; +#endif  // GTEST_OS_WINDOWS +}; + +class MockFoo : public FooInterface { + public: +  // Makes sure that a mock function parameter can be named. +  MOCK_METHOD1(VoidReturning, void(int n));  // NOLINT + +  MOCK_METHOD0(Nullary, int());  // NOLINT + +  // Makes sure that a mock function parameter can be unnamed. +  MOCK_METHOD1(Unary, bool(int));  // NOLINT +  MOCK_METHOD2(Binary, long(short, int));  // NOLINT +  MOCK_METHOD10(Decimal, int(bool, char, short, int, long, float,  // NOLINT +                             double, unsigned, char*, const string& str)); + +  MOCK_METHOD1(TakesNonConstReference, bool(int&));  // NOLINT +  MOCK_METHOD1(TakesConstReference, string(const int&)); +#ifdef GMOCK_ALLOWS_CONST_PARAM_FUNCTIONS +  MOCK_METHOD1(TakesConst, bool(const int));  // NOLINT +#endif  // GMOCK_ALLOWS_CONST_PARAM_FUNCTIONS +  MOCK_METHOD0(OverloadedOnArgumentNumber, int());  // NOLINT +  MOCK_METHOD1(OverloadedOnArgumentNumber, int(int));  // NOLINT + +  MOCK_METHOD1(OverloadedOnArgumentType, int(int));  // NOLINT +  MOCK_METHOD1(OverloadedOnArgumentType, char(char));  // NOLINT + +  MOCK_METHOD0(OverloadedOnConstness, int());  // NOLINT +  MOCK_CONST_METHOD0(OverloadedOnConstness, char());  // NOLINT + +  MOCK_METHOD1(TypeWithHole, int(int (*)()));  // NOLINT +  MOCK_METHOD1(TypeWithComma, int(const std::map<int, string>&));  // NOLINT +#ifdef GTEST_OS_WINDOWS +  MOCK_METHOD0_WITH_CALLTYPE(STDMETHODCALLTYPE, CTNullary, int()); +  MOCK_METHOD1_WITH_CALLTYPE(STDMETHODCALLTYPE, CTUnary, bool(int)); +  MOCK_METHOD10_WITH_CALLTYPE(STDMETHODCALLTYPE, CTDecimal, int(bool b, char c, +      short d, int e, long f, float g, double h, unsigned i, char* j, +      const string& k)); +  MOCK_CONST_METHOD1_WITH_CALLTYPE(STDMETHODCALLTYPE, CTConst, char(int)); +#endif  // GTEST_OS_WINDOWS +}; + +class FunctionMockerTest : public testing::Test { + protected: +  FunctionMockerTest() : foo_(&mock_foo_) {} + +  FooInterface* const foo_; +  MockFoo mock_foo_; +}; + +// Tests mocking a void-returning function. +TEST_F(FunctionMockerTest, MocksVoidFunction) { +  EXPECT_CALL(mock_foo_, VoidReturning(Lt(100))); +  foo_->VoidReturning(0); +} + +// Tests mocking a nullary function. +TEST_F(FunctionMockerTest, MocksNullaryFunction) { +  EXPECT_CALL(mock_foo_, Nullary()) +      .WillOnce(DoDefault()) +      .WillOnce(Return(1)); + +  EXPECT_EQ(0, foo_->Nullary()); +  EXPECT_EQ(1, foo_->Nullary()); +} + +// Tests mocking a unary function. +TEST_F(FunctionMockerTest, MocksUnaryFunction) { +  EXPECT_CALL(mock_foo_, Unary(Eq(2))) +      .Times(2) +      .WillOnce(Return(true)); + +  EXPECT_TRUE(foo_->Unary(2)); +  EXPECT_FALSE(foo_->Unary(2)); +} + +// Tests mocking a binary function. +TEST_F(FunctionMockerTest, MocksBinaryFunction) { +  EXPECT_CALL(mock_foo_, Binary(2, _)) +      .WillOnce(Return(3)); + +  EXPECT_EQ(3, foo_->Binary(2, 1)); +} + +// Tests mocking a decimal function. +TEST_F(FunctionMockerTest, MocksDecimalFunction) { +  EXPECT_CALL(mock_foo_, Decimal(true, 'a', 0, 0, 1L, A<float>(), +                                 Lt(100), 5U, NULL, "hi")) +      .WillOnce(Return(5)); + +  EXPECT_EQ(5, foo_->Decimal(true, 'a', 0, 0, 1, 0, 0, 5, NULL, "hi")); +} + +// Tests mocking a function that takes a non-const reference. +TEST_F(FunctionMockerTest, MocksFunctionWithNonConstReferenceArgument) { +  int a = 0; +  EXPECT_CALL(mock_foo_, TakesNonConstReference(Ref(a))) +      .WillOnce(Return(true)); + +  EXPECT_TRUE(foo_->TakesNonConstReference(a)); +} + +// Tests mocking a function that takes a const reference. +TEST_F(FunctionMockerTest, MocksFunctionWithConstReferenceArgument) { +  int a = 0; +  EXPECT_CALL(mock_foo_, TakesConstReference(Ref(a))) +      .WillOnce(Return("Hello")); + +  EXPECT_EQ("Hello", foo_->TakesConstReference(a)); +} + +#ifdef GMOCK_ALLOWS_CONST_PARAM_FUNCTIONS +// Tests mocking a function that takes a const variable. +TEST_F(FunctionMockerTest, MocksFunctionWithConstArgument) { +  EXPECT_CALL(mock_foo_, TakesConst(Lt(10))) +      .WillOnce(DoDefault()); + +  EXPECT_FALSE(foo_->TakesConst(5)); +} +#endif  // GMOCK_ALLOWS_CONST_PARAM_FUNCTIONS + +// Tests mocking functions overloaded on the number of arguments. +TEST_F(FunctionMockerTest, MocksFunctionsOverloadedOnArgumentNumber) { +  EXPECT_CALL(mock_foo_, OverloadedOnArgumentNumber()) +      .WillOnce(Return(1)); +  EXPECT_CALL(mock_foo_, OverloadedOnArgumentNumber(_)) +      .WillOnce(Return(2)); + +  EXPECT_EQ(2, foo_->OverloadedOnArgumentNumber(1)); +  EXPECT_EQ(1, foo_->OverloadedOnArgumentNumber()); +} + +// Tests mocking functions overloaded on the types of argument. +TEST_F(FunctionMockerTest, MocksFunctionsOverloadedOnArgumentType) { +  EXPECT_CALL(mock_foo_, OverloadedOnArgumentType(An<int>())) +      .WillOnce(Return(1)); +  EXPECT_CALL(mock_foo_, OverloadedOnArgumentType(TypedEq<char>('a'))) +      .WillOnce(Return('b')); + +  EXPECT_EQ(1, foo_->OverloadedOnArgumentType(0)); +  EXPECT_EQ('b', foo_->OverloadedOnArgumentType('a')); +} + +// Tests mocking functions overloaded on the const-ness of this object. +TEST_F(FunctionMockerTest, MocksFunctionsOverloadedOnConstnessOfThis) { +  EXPECT_CALL(mock_foo_, OverloadedOnConstness()); +  EXPECT_CALL(Const(mock_foo_), OverloadedOnConstness()) +      .WillOnce(Return('a')); + +  EXPECT_EQ(0, foo_->OverloadedOnConstness()); +  EXPECT_EQ('a', Const(*foo_).OverloadedOnConstness()); +} + +#ifdef GTEST_OS_WINDOWS +// Tests mocking a nullary function with calltype. +TEST_F(FunctionMockerTest, MocksNullaryFunctionWithCallType) { +  EXPECT_CALL(mock_foo_, CTNullary()) +      .WillOnce(Return(-1)) +      .WillOnce(Return(0)); + +  EXPECT_EQ(-1, foo_->CTNullary()); +  EXPECT_EQ(0, foo_->CTNullary()); +} + +// Tests mocking a unary function with calltype. +TEST_F(FunctionMockerTest, MocksUnaryFunctionWithCallType) { +  EXPECT_CALL(mock_foo_, CTUnary(Eq(2))) +      .Times(2) +      .WillOnce(Return(true)) +      .WillOnce(Return(false)); + +  EXPECT_TRUE(foo_->CTUnary(2)); +  EXPECT_FALSE(foo_->CTUnary(2)); +} + +// Tests mocking a decimal function with calltype. +TEST_F(FunctionMockerTest, MocksDecimalFunctionWithCallType) { +  EXPECT_CALL(mock_foo_, CTDecimal(true, 'a', 0, 0, 1L, A<float>(), +                                   Lt(100), 5U, NULL, "hi")) +      .WillOnce(Return(10)); + +  EXPECT_EQ(10, foo_->CTDecimal(true, 'a', 0, 0, 1, 0, 0, 5, NULL, "hi")); +} + +// Tests mocking functions overloaded on the const-ness of this object. +TEST_F(FunctionMockerTest, MocksFunctionsConstFunctionWithCallType) { +  EXPECT_CALL(Const(mock_foo_), CTConst(_)) +      .WillOnce(Return('a')); + +  EXPECT_EQ('a', Const(*foo_).CTConst(0)); +} + +#endif  // GTEST_OS_WINDOWS + +class MockB { + public: +  MOCK_METHOD0(DoB, void()); +}; + +// Tests that functions with no EXPECT_CALL() ruls can be called any +// number of times. +TEST(ExpectCallTest, UnmentionedFunctionCanBeCalledAnyNumberOfTimes) { +  { +    MockB b; +  } + +  { +    MockB b; +    b.DoB(); +  } + +  { +    MockB b; +    b.DoB(); +    b.DoB(); +  } +} + +// Tests mocking template interfaces. + +template <typename T> +class StackInterface { + public: +  virtual ~StackInterface() {} + +  // Template parameter appears in function parameter. +  virtual void Push(const T& value) = 0; +  virtual void Pop() = 0; +  virtual int GetSize() const = 0; +  // Template parameter appears in function return type. +  virtual const T& GetTop() const = 0; +}; + +template <typename T> +class MockStack : public StackInterface<T> { + public: +  MOCK_METHOD1_T(Push, void(const T& elem)); +  MOCK_METHOD0_T(Pop, void()); +  MOCK_CONST_METHOD0_T(GetSize, int());  // NOLINT +  MOCK_CONST_METHOD0_T(GetTop, const T&()); +}; + +// Tests that template mock works. +TEST(TemplateMockTest, Works) { +  MockStack<int> mock; + +  EXPECT_CALL(mock, GetSize()) +      .WillOnce(Return(0)) +      .WillOnce(Return(1)) +      .WillOnce(Return(0)); +  EXPECT_CALL(mock, Push(_)); +  int n = 5; +  EXPECT_CALL(mock, GetTop()) +      .WillOnce(ReturnRef(n)); +  EXPECT_CALL(mock, Pop()) +      .Times(AnyNumber()); + +  EXPECT_EQ(0, mock.GetSize()); +  mock.Push(5); +  EXPECT_EQ(1, mock.GetSize()); +  EXPECT_EQ(5, mock.GetTop()); +  mock.Pop(); +  EXPECT_EQ(0, mock.GetSize()); +} + +#ifdef GTEST_OS_WINDOWS +// Tests mocking template interfaces with calltype. + +template <typename T> +class StackInterfaceWithCallType { + public: +  virtual ~StackInterfaceWithCallType() {} + +  // Template parameter appears in function parameter. +  STDMETHOD_(void, Push)(const T& value) = 0; +  STDMETHOD_(void, Pop)() = 0; +  STDMETHOD_(int, GetSize)() const = 0; +  // Template parameter appears in function return type. +  STDMETHOD_(const T&, GetTop)() const = 0; +}; + +template <typename T> +class MockStackWithCallType : public StackInterfaceWithCallType<T> { + public: +  MOCK_METHOD1_T_WITH_CALLTYPE(STDMETHODCALLTYPE, Push, void(const T& elem)); +  MOCK_METHOD0_T_WITH_CALLTYPE(STDMETHODCALLTYPE, Pop, void()); +  MOCK_CONST_METHOD0_T_WITH_CALLTYPE(STDMETHODCALLTYPE, GetSize, int()); +  MOCK_CONST_METHOD0_T_WITH_CALLTYPE(STDMETHODCALLTYPE, GetTop, const T&()); +}; + +// Tests that template mock with calltype works. +TEST(TemplateMockTestWithCallType, Works) { +  MockStackWithCallType<int> mock; + +  EXPECT_CALL(mock, GetSize()) +      .WillOnce(Return(0)) +      .WillOnce(Return(1)) +      .WillOnce(Return(0)); +  EXPECT_CALL(mock, Push(_)); +  int n = 5; +  EXPECT_CALL(mock, GetTop()) +      .WillOnce(ReturnRef(n)); +  EXPECT_CALL(mock, Pop()) +      .Times(AnyNumber()); + +  EXPECT_EQ(0, mock.GetSize()); +  mock.Push(5); +  EXPECT_EQ(1, mock.GetSize()); +  EXPECT_EQ(5, mock.GetTop()); +  mock.Pop(); +  EXPECT_EQ(0, mock.GetSize()); +} +#endif  // GTEST_OS_WINDOWS + +}  // namespace gmock_generated_function_mockers_test +}  // namespace testing diff --git a/test/gmock-generated-internal-utils_test.cc b/test/gmock-generated-internal-utils_test.cc new file mode 100644 index 00000000..13b4c5cf --- /dev/null +++ b/test/gmock-generated-internal-utils_test.cc @@ -0,0 +1,127 @@ +// 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 internal utilities. + +#include <gmock/internal/gmock-generated-internal-utils.h> +#include <gmock/internal/gmock-internal-utils.h> +#include <gtest/gtest.h> + +namespace { + +using ::std::tr1::tuple; +using ::testing::Matcher; +using ::testing::internal::CompileAssertTypesEqual; +using ::testing::internal::MatcherTuple; +using ::testing::internal::Function; +using ::testing::internal::IgnoredValue; + +// Tests the MatcherTuple template struct. + +TEST(MatcherTupleTest, ForSize0) { +  CompileAssertTypesEqual<tuple<>, MatcherTuple<tuple<> >::type>(); +} + +TEST(MatcherTupleTest, ForSize1) { +  CompileAssertTypesEqual<tuple<Matcher<int> >, +                          MatcherTuple<tuple<int> >::type>(); +} + +TEST(MatcherTupleTest, ForSize2) { +  CompileAssertTypesEqual<tuple<Matcher<int>, Matcher<char> >, +                          MatcherTuple<tuple<int, char> >::type>(); +} + +TEST(MatcherTupleTest, ForSize5) { +  CompileAssertTypesEqual<tuple<Matcher<int>, Matcher<char>, Matcher<bool>, +                                Matcher<double>, Matcher<char*> >, +                          MatcherTuple<tuple<int, char, bool, double, char*> +                                      >::type>(); +} + +// Tests the Function template struct. + +TEST(FunctionTest, Nullary) { +  typedef Function<int()> F;  // NOLINT +  CompileAssertTypesEqual<int, F::Result>(); +  CompileAssertTypesEqual<tuple<>, F::ArgumentTuple>(); +  CompileAssertTypesEqual<tuple<>, F::ArgumentMatcherTuple>(); +  CompileAssertTypesEqual<void(), F::MakeResultVoid>(); +  CompileAssertTypesEqual<IgnoredValue(), F::MakeResultIgnoredValue>(); +} + +TEST(FunctionTest, Unary) { +  typedef Function<int(bool)> F;  // NOLINT +  CompileAssertTypesEqual<int, F::Result>(); +  CompileAssertTypesEqual<bool, F::Argument1>(); +  CompileAssertTypesEqual<tuple<bool>, F::ArgumentTuple>(); +  CompileAssertTypesEqual<tuple<Matcher<bool> >, F::ArgumentMatcherTuple>(); +  CompileAssertTypesEqual<void(bool), F::MakeResultVoid>();  // NOLINT +  CompileAssertTypesEqual<IgnoredValue(bool),  // NOLINT +      F::MakeResultIgnoredValue>(); +} + +TEST(FunctionTest, Binary) { +  typedef Function<int(bool, const long&)> F;  // NOLINT +  CompileAssertTypesEqual<int, F::Result>(); +  CompileAssertTypesEqual<bool, F::Argument1>(); +  CompileAssertTypesEqual<const long&, F::Argument2>();  // NOLINT +  CompileAssertTypesEqual<tuple<bool, const long&>, F::ArgumentTuple>();  // NOLINT +  CompileAssertTypesEqual<tuple<Matcher<bool>, Matcher<const long&> >,  // NOLINT +                          F::ArgumentMatcherTuple>(); +  CompileAssertTypesEqual<void(bool, const long&), F::MakeResultVoid>();  // NOLINT +  CompileAssertTypesEqual<IgnoredValue(bool, const long&),  // NOLINT +      F::MakeResultIgnoredValue>(); +} + +TEST(FunctionTest, LongArgumentList) { +  typedef Function<char(bool, int, char*, int&, const long&)> F;  // NOLINT +  CompileAssertTypesEqual<char, F::Result>(); +  CompileAssertTypesEqual<bool, F::Argument1>(); +  CompileAssertTypesEqual<int, F::Argument2>(); +  CompileAssertTypesEqual<char*, F::Argument3>(); +  CompileAssertTypesEqual<int&, F::Argument4>(); +  CompileAssertTypesEqual<const long&, F::Argument5>();  // NOLINT +  CompileAssertTypesEqual<tuple<bool, int, char*, int&, const long&>,  // NOLINT +                          F::ArgumentTuple>(); +  CompileAssertTypesEqual<tuple<Matcher<bool>, Matcher<int>, Matcher<char*>, +                                Matcher<int&>, Matcher<const long&> >,  // NOLINT +                          F::ArgumentMatcherTuple>(); +  CompileAssertTypesEqual<void(bool, int, char*, int&, const long&),  // NOLINT +                          F::MakeResultVoid>(); +  CompileAssertTypesEqual< +      IgnoredValue(bool, int, char*, int&, const long&),  // NOLINT +      F::MakeResultIgnoredValue>(); +} + +}  // Unnamed namespace diff --git a/test/gmock-generated-matchers_test.cc b/test/gmock-generated-matchers_test.cc new file mode 100644 index 00000000..89b26caa --- /dev/null +++ b/test/gmock-generated-matchers_test.cc @@ -0,0 +1,373 @@ +// 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 <sstream> +#include <string> +#include <vector> + +#include <gmock/gmock.h> +#include <gtest/gtest.h> + +namespace { + +using std::list; +using std::stringstream; +using std::vector; +using testing::_; +using testing::ElementsAre; +using testing::ElementsAreArray; +using testing::Eq; +using testing::Ge; +using testing::Gt; +using testing::MakeMatcher; +using testing::Matcher; +using testing::MatcherInterface; +using testing::Ne; +using testing::Not; +using testing::Pointee; +using testing::Ref; +using testing::StrEq; +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(); +} + +// For testing ExplainMatchResultTo(). +class GreaterThanMatcher : public MatcherInterface<int> { + public: +  explicit GreaterThanMatcher(int rhs) : rhs_(rhs) {} + +  virtual bool Matches(int lhs) const { return lhs > rhs_; } + +  virtual void DescribeTo(::std::ostream* os) const { +    *os << "is greater than " << rhs_; +  } + +  virtual void ExplainMatchResultTo(int lhs, ::std::ostream* os) const { +    const int diff = lhs - rhs_; +    if (diff > 0) { +      *os << "is " << diff << " more than " << rhs_; +    } else if (diff == 0) { +      *os << "is the same as " << rhs_; +    } else { +      *os << "is " << -diff << " less than " << rhs_; +    } +  } + private: +  const 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 greater than 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("is not empty", DescribeNegation(m)); +} + +TEST(ElementsAreTest, CanDescribeNegationOfExpectingOneElment) { +  Matcher<const list<int>& > m = ElementsAre(Gt(5)); +  EXPECT_EQ("does not have 1 element, or\n" +            "element 0 is not greater than 5", DescribeNegation(m)); +} + +TEST(ElementsAreTest, CanDescribeNegationOfExpectingManyElements) { +  Matcher<const list<string>& > m = ElementsAre("one", "two"); +  EXPECT_EQ("does not have 2 elements, or\n" +            "element 0 is not equal to \"one\", or\n" +            "element 1 is not 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("element 0 is 9 more than 1,\n" +            "element 2 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("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("element 0 doesn't match", Explain(m, v)); + +  v[0] = 1; +  EXPECT_EQ("element 1 doesn't match (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 (int 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)))); +} + +// 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))); +} + +}  // namespace diff --git a/test/gmock-internal-utils_test.cc b/test/gmock-internal-utils_test.cc new file mode 100644 index 00000000..2a43caa9 --- /dev/null +++ b/test/gmock-internal-utils_test.cc @@ -0,0 +1,521 @@ +// 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 internal utilities. + +#include <gmock/internal/gmock-internal-utils.h> +#include <map> +#include <string> +#include <sstream> +#include <vector> +#include <gmock/gmock.h> +#include <gmock/internal/gmock-port.h> +#include <gtest/gtest.h> +#include <gtest/gtest-spi.h> + +namespace testing { +namespace internal { + +namespace { + +using ::std::tr1::tuple; + +// Tests that CompileAssertTypesEqual compiles when the type arguments are +// equal. +TEST(CompileAssertTypesEqual, CompilesWhenTypesAreEqual) { +  CompileAssertTypesEqual<void, void>(); +  CompileAssertTypesEqual<int*, int*>(); +} + +// Tests that RemoveReference does not affect non-reference types. +TEST(RemoveReferenceTest, DoesNotAffectNonReferenceType) { +  CompileAssertTypesEqual<int, RemoveReference<int>::type>(); +  CompileAssertTypesEqual<const char, RemoveReference<const char>::type>(); +} + +// Tests that RemoveReference removes reference from reference types. +TEST(RemoveReferenceTest, RemovesReference) { +  CompileAssertTypesEqual<int, RemoveReference<int&>::type>(); +  CompileAssertTypesEqual<const char, RemoveReference<const char&>::type>(); +} + +// Tests GMOCK_REMOVE_REFERENCE. + +template <typename T1, typename T2> +void TestGMockRemoveReference() { +  CompileAssertTypesEqual<T1, GMOCK_REMOVE_REFERENCE(T2)>(); +} + +TEST(RemoveReferenceTest, MacroVersion) { +  TestGMockRemoveReference<int, int>(); +  TestGMockRemoveReference<const char, const char&>(); +} + + +// Tests that RemoveConst does not affect non-const types. +TEST(RemoveConstTest, DoesNotAffectNonConstType) { +  CompileAssertTypesEqual<int, RemoveConst<int>::type>(); +  CompileAssertTypesEqual<char&, RemoveConst<char&>::type>(); +} + +// Tests that RemoveConst removes const from const types. +TEST(RemoveConstTest, RemovesConst) { +  CompileAssertTypesEqual<int, RemoveConst<const int>::type>(); +} + +// Tests GMOCK_REMOVE_CONST. + +template <typename T1, typename T2> +void TestGMockRemoveConst() { +  CompileAssertTypesEqual<T1, GMOCK_REMOVE_CONST(T2)>(); +} + +TEST(RemoveConstTest, MacroVersion) { +  TestGMockRemoveConst<int, int>(); +  TestGMockRemoveConst<double&, double&>(); +  TestGMockRemoveConst<char, const char>(); +} + +// Tests that AddReference does not affect reference types. +TEST(AddReferenceTest, DoesNotAffectReferenceType) { +  CompileAssertTypesEqual<int&, AddReference<int&>::type>(); +  CompileAssertTypesEqual<const char&, AddReference<const char&>::type>(); +} + +// Tests that AddReference adds reference to non-reference types. +TEST(AddReferenceTest, AddsReference) { +  CompileAssertTypesEqual<int&, AddReference<int>::type>(); +  CompileAssertTypesEqual<const char&, AddReference<const char>::type>(); +} + +// Tests GMOCK_ADD_REFERENCE. + +template <typename T1, typename T2> +void TestGMockAddReference() { +  CompileAssertTypesEqual<T1, GMOCK_ADD_REFERENCE(T2)>(); +} + +TEST(AddReferenceTest, MacroVersion) { +  TestGMockAddReference<int&, int>(); +  TestGMockAddReference<const char&, const char&>(); +} + +// Tests GMOCK_REFERENCE_TO_CONST. + +template <typename T1, typename T2> +void TestGMockReferenceToConst() { +  CompileAssertTypesEqual<T1, GMOCK_REFERENCE_TO_CONST(T2)>(); +} + +TEST(GMockReferenceToConstTest, Works) { +  TestGMockReferenceToConst<const char&, char>(); +  TestGMockReferenceToConst<const int&, const int>(); +  TestGMockReferenceToConst<const double&, double>(); +  TestGMockReferenceToConst<const string&, const string&>(); +} + +TEST(PointeeOfTest, WorksForSmartPointers) { +  CompileAssertTypesEqual<const char, +      PointeeOf<internal::linked_ptr<const char> >::type>(); +} + +TEST(PointeeOfTest, WorksForRawPointers) { +  CompileAssertTypesEqual<int, PointeeOf<int*>::type>(); +  CompileAssertTypesEqual<const char, PointeeOf<const char*>::type>(); +  CompileAssertTypesEqual<void, PointeeOf<void*>::type>(); +} + +TEST(GetRawPointerTest, WorksForSmartPointers) { +  const char* const raw_p4 = new const char('a');  // NOLINT +  const internal::linked_ptr<const char> p4(raw_p4); +  EXPECT_EQ(raw_p4, GetRawPointer(p4)); +} + +TEST(GetRawPointerTest, WorksForRawPointers) { +  int* p = NULL; +  EXPECT_EQ(NULL, GetRawPointer(p)); +  int n = 1; +  EXPECT_EQ(&n, GetRawPointer(&n)); +} + +class Base {}; +class Derived : public Base {}; + +// Tests that ImplicitlyConvertible<T1, T2>::value is a compile-time constant. +TEST(ImplicitlyConvertibleTest, ValueIsCompileTimeConstant) { +  GMOCK_COMPILE_ASSERT((ImplicitlyConvertible<int, int>::value), const_true); +  GMOCK_COMPILE_ASSERT((!ImplicitlyConvertible<void*, int*>::value), const_false); +} + +// Tests that ImplicitlyConvertible<T1, T2>::value is true when T1 can +// be implicitly converted to T2. +TEST(ImplicitlyConvertibleTest, ValueIsTrueWhenConvertible) { +  EXPECT_TRUE((ImplicitlyConvertible<int, double>::value)); +  EXPECT_TRUE((ImplicitlyConvertible<double, int>::value)); +  EXPECT_TRUE((ImplicitlyConvertible<int*, void*>::value)); +  EXPECT_TRUE((ImplicitlyConvertible<int*, const int*>::value)); +  EXPECT_TRUE((ImplicitlyConvertible<Derived&, const Base&>::value)); +  EXPECT_TRUE((ImplicitlyConvertible<const Base, Base>::value)); +} + +// Tests that ImplicitlyConvertible<T1, T2>::value is false when T1 +// cannot be implicitly converted to T2. +TEST(ImplicitlyConvertibleTest, ValueIsFalseWhenNotConvertible) { +  EXPECT_FALSE((ImplicitlyConvertible<double, int*>::value)); +  EXPECT_FALSE((ImplicitlyConvertible<void*, int*>::value)); +  EXPECT_FALSE((ImplicitlyConvertible<const int*, int*>::value)); +  EXPECT_FALSE((ImplicitlyConvertible<Base&, Derived&>::value)); +} + +// Tests that IsAProtocolMessage<T>::value is a compile-time constant. +TEST(IsAProtocolMessageTest, ValueIsCompileTimeConstant) { +  GMOCK_COMPILE_ASSERT(IsAProtocolMessage<ProtocolMessage>::value, const_true); +  GMOCK_COMPILE_ASSERT(!IsAProtocolMessage<int>::value, const_false); +} + +// Tests that IsAProtocolMessage<T>::value is true when T is +// ProtocolMessage or a sub-class of it. +TEST(IsAProtocolMessageTest, ValueIsTrueWhenTypeIsAProtocolMessage) { +  EXPECT_TRUE(IsAProtocolMessage<ProtocolMessage>::value); +#if GMOCK_HAS_PROTOBUF_ +  EXPECT_TRUE(IsAProtocolMessage<const TestMessage>::value); +#endif  // GMOCK_HAS_PROTOBUF_ +} + +// Tests that IsAProtocolMessage<T>::value is false when T is neither +// ProtocolMessage nor a sub-class of it. +TEST(IsAProtocolMessageTest, ValueIsFalseWhenTypeIsNotAProtocolMessage) { +  EXPECT_FALSE(IsAProtocolMessage<int>::value); +  EXPECT_FALSE(IsAProtocolMessage<const Base>::value); +} + +// Tests IsContainerTest. + +class NonContainer {}; + +TEST(IsContainerTestTest, WorksForNonContainer) { +  EXPECT_EQ(sizeof(IsNotContainer), sizeof(IsContainerTest<int>(0))); +  EXPECT_EQ(sizeof(IsNotContainer), sizeof(IsContainerTest<char[5]>(0))); +  EXPECT_EQ(sizeof(IsNotContainer), sizeof(IsContainerTest<NonContainer>(0))); +} + +TEST(IsContainerTestTest, WorksForContainer) { +  EXPECT_EQ(sizeof(IsContainer), sizeof(IsContainerTest<std::vector<bool> >(0))); +  EXPECT_EQ(sizeof(IsContainer), sizeof(IsContainerTest<std::map<int, double> >(0))); +} + +// Tests the TupleMatches() template function. + +TEST(TupleMatchesTest, WorksForSize0) { +  tuple<> matchers; +  tuple<> values; + +  EXPECT_TRUE(TupleMatches(matchers, values)); +} + +TEST(TupleMatchesTest, WorksForSize1) { +  tuple<Matcher<int> > matchers(Eq(1)); +  tuple<int> values1(1), +      values2(2); + +  EXPECT_TRUE(TupleMatches(matchers, values1)); +  EXPECT_FALSE(TupleMatches(matchers, values2)); +} + +TEST(TupleMatchesTest, WorksForSize2) { +  tuple<Matcher<int>, Matcher<char> > matchers(Eq(1), Eq('a')); +  tuple<int, char> values1(1, 'a'), +      values2(1, 'b'), +      values3(2, 'a'), +      values4(2, 'b'); + +  EXPECT_TRUE(TupleMatches(matchers, values1)); +  EXPECT_FALSE(TupleMatches(matchers, values2)); +  EXPECT_FALSE(TupleMatches(matchers, values3)); +  EXPECT_FALSE(TupleMatches(matchers, values4)); +} + +TEST(TupleMatchesTest, WorksForSize5) { +  tuple<Matcher<int>, Matcher<char>, Matcher<bool>, Matcher<long>,  // NOLINT +      Matcher<string> > +      matchers(Eq(1), Eq('a'), Eq(true), Eq(2L), Eq("hi")); +  tuple<int, char, bool, long, string>  // NOLINT +      values1(1, 'a', true, 2L, "hi"), +      values2(1, 'a', true, 2L, "hello"), +      values3(2, 'a', true, 2L, "hi"); + +  EXPECT_TRUE(TupleMatches(matchers, values1)); +  EXPECT_FALSE(TupleMatches(matchers, values2)); +  EXPECT_FALSE(TupleMatches(matchers, values3)); +} + +// Tests that Assert(true, ...) succeeds. +TEST(AssertTest, SucceedsOnTrue) { +  Assert(true, __FILE__, __LINE__, "This should succeed."); +  Assert(true, __FILE__, __LINE__);  // This should succeed too. +} + +#ifdef GTEST_HAS_DEATH_TEST + +// Tests that Assert(false, ...) generates a fatal failure. +TEST(AssertTest, FailsFatallyOnFalse) { +  EXPECT_DEATH({  // NOLINT +    Assert(false, __FILE__, __LINE__, "This should fail."); +  }, ""); + +  EXPECT_DEATH({  // NOLINT +    Assert(false, __FILE__, __LINE__); +  }, ""); +} + +#endif  // GTEST_HAS_DEATH_TEST + +// Tests that Expect(true, ...) succeeds. +TEST(ExpectTest, SucceedsOnTrue) { +  Expect(true, __FILE__, __LINE__, "This should succeed."); +  Expect(true, __FILE__, __LINE__);  // This should succeed too. +} + +// Tests that Expect(false, ...) generates a non-fatal failure. +TEST(ExpectTest, FailsNonfatallyOnFalse) { +  EXPECT_NONFATAL_FAILURE({  // NOLINT +    Expect(false, __FILE__, __LINE__, "This should fail."); +  }, "This should fail"); + +  EXPECT_NONFATAL_FAILURE({  // NOLINT +    Expect(false, __FILE__, __LINE__); +  }, "Expectation failed"); +} + +// TODO(wan@google.com): find a way to re-enable these tests. +#if 0 + +// Tests the Log() function. + +// Verifies that Log() behaves correctly for the given verbosity level +// and log severity. +void TestLogWithSeverity(const string& verbosity, LogSeverity severity, +                         bool should_print) { +  const string old_flag = GMOCK_FLAG(verbose); +  GMOCK_FLAG(verbose) = verbosity; +  CaptureTestStdout(); +  Log(severity, "Test log.\n", 0); +  if (should_print) { +    EXPECT_PRED2(RE::FullMatch, +                 GetCapturedTestStdout(), +                 severity == WARNING ? +                 "\nGMOCK WARNING:\nTest log\\.\nStack trace:\n[\\s\\S]*" : +                 "\nTest log\\.\nStack trace:\n[\\s\\S]*"); +  } else { +    EXPECT_EQ("", GetCapturedTestStdout()); +  } +  GMOCK_FLAG(verbose) = old_flag; +} + +// Tests that when the stack_frames_to_skip parameter is negative, +// Log() doesn't include the stack trace in the output. +TEST(LogTest, NoStackTraceWhenStackFramesToSkipIsNegative) { +  GMOCK_FLAG(verbose) = kInfoVerbosity; +  CaptureTestStdout(); +  Log(INFO, "Test log.\n", -1); +  EXPECT_EQ("\nTest log.\n", GetCapturedTestStdout()); +} + +// Tests that in opt mode, a positive stack_frames_to_skip argument is +// treated as 0. +TEST(LogTest, NoSkippingStackFrameInOptMode) { +  CaptureTestStdout(); +  Log(WARNING, "Test log.\n", 100); +  const string log = GetCapturedTestStdout(); +#ifdef NDEBUG +  // In opt mode, no stack frame should be skipped. +  EXPECT_THAT(log, ContainsRegex("\nGMOCK WARNING:\n" +                                 "Test log\\.\n" +                                 "Stack trace:\n" +                                 ".+")); +#else +  // In dbg mode, the stack frames should be skipped. +  EXPECT_EQ("\nGMOCK WARNING:\n" +            "Test log.\n" +            "Stack trace:\n", log); +#endif  // NDEBUG +} + +// Tests that all logs are printed when the value of the +// --gmock_verbose flag is "info". +TEST(LogTest, AllLogsArePrintedWhenVerbosityIsInfo) { +  TestLogWithSeverity(kInfoVerbosity, INFO, true); +  TestLogWithSeverity(kInfoVerbosity, WARNING, true); +} + +// Tests that only warnings are printed when the value of the +// --gmock_verbose flag is "warning". +TEST(LogTest, OnlyWarningsArePrintedWhenVerbosityIsWarning) { +  TestLogWithSeverity(kWarningVerbosity, INFO, false); +  TestLogWithSeverity(kWarningVerbosity, WARNING, true); +} + +// Tests that no logs are printed when the value of the +// --gmock_verbose flag is "error". +TEST(LogTest, NoLogsArePrintedWhenVerbosityIsError) { +  TestLogWithSeverity(kErrorVerbosity, INFO, false); +  TestLogWithSeverity(kErrorVerbosity, WARNING, false); +} + +// Tests that only warnings are printed when the value of the +// --gmock_verbose flag is invalid. +TEST(LogTest, OnlyWarningsArePrintedWhenVerbosityIsInvalid) { +  TestLogWithSeverity("invalid", INFO, false); +  TestLogWithSeverity("invalid", WARNING, true); +} + +#endif  // 0 + +TEST(TypeTraitsTest, true_type) { +  EXPECT_TRUE(true_type::value); +} + +TEST(TypeTraitsTest, false_type) { +  EXPECT_FALSE(false_type::value); +} + +TEST(TypeTraitsTest, is_reference) { +  EXPECT_FALSE(is_reference<int>::value); +  EXPECT_FALSE(is_reference<char*>::value); +  EXPECT_TRUE(is_reference<const int&>::value); +} + +TEST(TypeTraitsTest, is_pointer) { +  EXPECT_FALSE(is_pointer<int>::value); +  EXPECT_FALSE(is_pointer<char&>::value); +  EXPECT_TRUE(is_pointer<const int*>::value); +} + +TEST(TypeTraitsTest, type_equals) { +  EXPECT_FALSE((type_equals<int, const int>::value)); +  EXPECT_FALSE((type_equals<int, int&>::value)); +  EXPECT_FALSE((type_equals<int, double>::value)); +  EXPECT_TRUE((type_equals<char, char>::value)); +} + +TEST(TypeTraitsTest, remove_reference) { +  EXPECT_TRUE((type_equals<char, remove_reference<char&>::type>::value)); +  EXPECT_TRUE((type_equals<const int, +               remove_reference<const int&>::type>::value)); +  EXPECT_TRUE((type_equals<int, remove_reference<int>::type>::value)); +  EXPECT_TRUE((type_equals<double*, remove_reference<double*>::type>::value)); +} + +// TODO(wan@google.com): find a way to re-enable these tests. +#if 0 + +// Verifies that Log() behaves correctly for the given verbosity level +// and log severity. +string GrabOutput(void(*logger)(), const char* verbosity) { +  const string saved_flag = GMOCK_FLAG(verbose); +  GMOCK_FLAG(verbose) = verbosity; +  CaptureTestStdout(); +  logger(); +  GMOCK_FLAG(verbose) = saved_flag; +  return GetCapturedTestStdout(); +} + +class DummyMock { + public: +  MOCK_METHOD0(TestMethod, void()); +  MOCK_METHOD1(TestMethodArg, void(int dummy)); +}; + +void ExpectCallLogger() { +  DummyMock mock; +  EXPECT_CALL(mock, TestMethod()); +  mock.TestMethod(); +}; + +// Verifies that EXPECT_CALL logs if the --gmock_verbose flag is set to "info". +TEST(ExpectCallTest, LogsWhenVerbosityIsInfo) { +  EXPECT_THAT(GrabOutput(ExpectCallLogger, kInfoVerbosity), +              HasSubstr("EXPECT_CALL(mock, TestMethod())")); +} + +// Verifies that EXPECT_CALL doesn't log +// if the --gmock_verbose flag is set to "warning". +TEST(ExpectCallTest, DoesNotLogWhenVerbosityIsWarning) { +  EXPECT_EQ("", GrabOutput(ExpectCallLogger, kWarningVerbosity)); +} + +// Verifies that EXPECT_CALL doesn't log +// if the --gmock_verbose flag is set to "error". +TEST(ExpectCallTest,  DoesNotLogWhenVerbosityIsError) { +  EXPECT_EQ("", GrabOutput(ExpectCallLogger, kErrorVerbosity)); +} + +void OnCallLogger() { +  DummyMock mock; +  ON_CALL(mock, TestMethod()); +}; + +// Verifies that ON_CALL logs if the --gmock_verbose flag is set to "info". +TEST(OnCallTest, LogsWhenVerbosityIsInfo) { +  EXPECT_THAT(GrabOutput(OnCallLogger, kInfoVerbosity), +              HasSubstr("ON_CALL(mock, TestMethod())")); +} + +// Verifies that ON_CALL doesn't log +// if the --gmock_verbose flag is set to "warning". +TEST(OnCallTest, DoesNotLogWhenVerbosityIsWarning) { +  EXPECT_EQ("", GrabOutput(OnCallLogger, kWarningVerbosity)); +} + +// Verifies that ON_CALL doesn't log if +// the --gmock_verbose flag is set to "error". +TEST(OnCallTest, DoesNotLogWhenVerbosityIsError) { +  EXPECT_EQ("", GrabOutput(OnCallLogger, kErrorVerbosity)); +} + +void OnCallAnyArgumentLogger() { +  DummyMock mock; +  ON_CALL(mock, TestMethodArg(_)); +} + +// Verifies that ON_CALL prints provided _ argument. +TEST(OnCallTest, LogsAnythingArgument) { +  EXPECT_THAT(GrabOutput(OnCallAnyArgumentLogger, kInfoVerbosity), +              HasSubstr("ON_CALL(mock, TestMethodArg(_)")); +} + +#endif  // 0 + +}  // namespace +}  // namespace internal +}  // namespace testing diff --git a/test/gmock-matchers_test.cc b/test/gmock-matchers_test.cc new file mode 100644 index 00000000..29b038e4 --- /dev/null +++ b/test/gmock-matchers_test.cc @@ -0,0 +1,2629 @@ +// 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 some commonly used argument matchers. + +#include <gmock/gmock-matchers.h> + +#include <string.h> +#include <functional> +#include <string> +#include <sstream> +#include <gmock/gmock.h> +#include <gtest/gtest.h> +#include <gtest/gtest-spi.h> + +namespace testing { +namespace gmock_matchers_test { + +using std::stringstream; +using testing::A; +using testing::AllOf; +using testing::An; +using testing::AnyOf; +using testing::ByRef; +using testing::DoubleEq; +using testing::EndsWith; +using testing::Eq; +using testing::Field; +using testing::FloatEq; +using testing::Ge; +using testing::Gt; +using testing::HasSubstr; +using testing::Le; +using testing::Lt; +using testing::MakeMatcher; +using testing::MakePolymorphicMatcher; +using testing::Matcher; +using testing::MatcherCast; +using testing::MatcherInterface; +using testing::Matches; +using testing::NanSensitiveDoubleEq; +using testing::NanSensitiveFloatEq; +using testing::Ne; +using testing::Not; +using testing::NotNull; +using testing::Pointee; +using testing::PolymorphicMatcher; +using testing::Property; +using testing::Ref; +using testing::ResultOf; +using testing::StartsWith; +using testing::StrCaseEq; +using testing::StrCaseNe; +using testing::StrEq; +using testing::StrNe; +using testing::Truly; +using testing::TypedEq; +using testing::_; +using testing::internal::FloatingEqMatcher; +using testing::internal::String; +using testing::internal::string; + +#ifdef GMOCK_HAS_REGEX +using testing::ContainsRegex; +using testing::MatchesRegex; +using testing::internal::RE; +#endif  // GMOCK_HAS_REGEX + +// 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(); +} + +// Makes sure that the MatcherInterface<T> interface doesn't +// change. +class EvenMatcherImpl : public MatcherInterface<int> { + public: +  virtual bool Matches(int x) const { return x % 2 == 0; } + +  virtual void DescribeTo(::std::ostream* os) const { +    *os << "is an even number"; +  } + +  // We deliberately don't define DescribeNegationTo() and +  // ExplainMatchResultTo() here, to make sure the definition of these +  // two methods is optional. +}; + +TEST(MatcherInterfaceTest, CanBeImplemented) { +  EvenMatcherImpl m; +} + +// Tests default-constructing a matcher. +TEST(MatcherTest, CanBeDefaultConstructed) { +  Matcher<double> m; +} + +// Tests that Matcher<T> can be constructed from a MatcherInterface<T>*. +TEST(MatcherTest, CanBeConstructedFromMatcherInterface) { +  const MatcherInterface<int>* impl = new EvenMatcherImpl; +  Matcher<int> m(impl); +  EXPECT_TRUE(m.Matches(4)); +  EXPECT_FALSE(m.Matches(5)); +} + +// Tests that value can be used in place of Eq(value). +TEST(MatcherTest, CanBeImplicitlyConstructedFromValue) { +  Matcher<int> m1 = 5; +  EXPECT_TRUE(m1.Matches(5)); +  EXPECT_FALSE(m1.Matches(6)); +} + +// Tests that NULL can be used in place of Eq(NULL). +TEST(MatcherTest, CanBeImplicitlyConstructedFromNULL) { +  Matcher<int*> m1 = NULL; +  EXPECT_TRUE(m1.Matches(NULL)); +  int n = 0; +  EXPECT_FALSE(m1.Matches(&n)); +} + +// Tests that matchers are copyable. +TEST(MatcherTest, IsCopyable) { +  // Tests the copy constructor. +  Matcher<bool> m1 = Eq(false); +  EXPECT_TRUE(m1.Matches(false)); +  EXPECT_FALSE(m1.Matches(true)); + +  // Tests the assignment operator. +  m1 = Eq(true); +  EXPECT_TRUE(m1.Matches(true)); +  EXPECT_FALSE(m1.Matches(false)); +} + +// Tests that Matcher<T>::DescribeTo() calls +// MatcherInterface<T>::DescribeTo(). +TEST(MatcherTest, CanDescribeItself) { +  EXPECT_EQ("is an even number", +            Describe(Matcher<int>(new EvenMatcherImpl))); +} + +// Tests that a C-string literal can be implicitly converted to a +// Matcher<string> or Matcher<const string&>. +TEST(StringMatcherTest, CanBeImplicitlyConstructedFromCStringLiteral) { +  Matcher<string> m1 = "hi"; +  EXPECT_TRUE(m1.Matches("hi")); +  EXPECT_FALSE(m1.Matches("hello")); + +  Matcher<const string&> m2 = "hi"; +  EXPECT_TRUE(m2.Matches("hi")); +  EXPECT_FALSE(m2.Matches("hello")); +} + +// Tests that a string object can be implicitly converted to a +// Matcher<string> or Matcher<const string&>. +TEST(StringMatcherTest, CanBeImplicitlyConstructedFromString) { +  Matcher<string> m1 = string("hi"); +  EXPECT_TRUE(m1.Matches("hi")); +  EXPECT_FALSE(m1.Matches("hello")); + +  Matcher<const string&> m2 = string("hi"); +  EXPECT_TRUE(m2.Matches("hi")); +  EXPECT_FALSE(m2.Matches("hello")); +} + +// Tests that MakeMatcher() constructs a Matcher<T> from a +// MatcherInterface* without requiring the user to explicitly +// write the type. +TEST(MakeMatcherTest, ConstructsMatcherFromMatcherInterface) { +  const MatcherInterface<int>* dummy_impl = NULL; +  Matcher<int> m = MakeMatcher(dummy_impl); +} + +// Tests that MakePolymorphicMatcher() constructs a polymorphic +// matcher from its implementation. +const int bar = 1; +class ReferencesBarOrIsZeroImpl { + public: +  template <typename T> +  bool Matches(const T& x) const { +    const void* p = &x; +    return p == &bar || x == 0; +  } + +  void DescribeTo(::std::ostream* os) const { *os << "bar or zero"; } + +  void DescribeNegationTo(::std::ostream* os) const { +    *os << "doesn't reference bar and is not zero"; +  } +}; + +// This function verifies that MakePolymorphicMatcher() returns a +// PolymorphicMatcher<T> where T is the argument's type. +PolymorphicMatcher<ReferencesBarOrIsZeroImpl> ReferencesBarOrIsZero() { +  return MakePolymorphicMatcher(ReferencesBarOrIsZeroImpl()); +} + +TEST(MakePolymorphicMatcherTest, ConstructsMatcherFromImpl) { +  // Using a polymorphic matcher to match a reference type. +  Matcher<const int&> m1 = ReferencesBarOrIsZero(); +  EXPECT_TRUE(m1.Matches(0)); +  // Verifies that the identity of a by-reference argument is preserved. +  EXPECT_TRUE(m1.Matches(bar)); +  EXPECT_FALSE(m1.Matches(1)); +  EXPECT_EQ("bar or zero", Describe(m1)); + +  // Using a polymorphic matcher to match a value type. +  Matcher<double> m2 = ReferencesBarOrIsZero(); +  EXPECT_TRUE(m2.Matches(0.0)); +  EXPECT_FALSE(m2.Matches(0.1)); +  EXPECT_EQ("bar or zero", Describe(m2)); +} + +// Tests that MatcherCast<T>(m) works when m is a polymorphic matcher. +TEST(MatcherCastTest, FromPolymorphicMatcher) { +  Matcher<int> m = MatcherCast<int>(Eq(5)); +  EXPECT_TRUE(m.Matches(5)); +  EXPECT_FALSE(m.Matches(6)); +} + +// For testing casting matchers between compatible types. +class IntValue { + public: +  // An int can be statically (although not implicitly) cast to a +  // IntValue. +  explicit IntValue(int value) : value_(value) {} + +  int value() const { return value_; } + private: +  int value_; +}; + +// For testing casting matchers between compatible types. +bool IsPositiveIntValue(const IntValue& foo) { +  return foo.value() > 0; +} + +// Tests that MatcherCast<T>(m) works when m is a Matcher<U> where T +// can be statically converted to U. +TEST(MatcherCastTest, FromCompatibleType) { +  Matcher<double> m1 = Eq(2.0); +  Matcher<int> m2 = MatcherCast<int>(m1); +  EXPECT_TRUE(m2.Matches(2)); +  EXPECT_FALSE(m2.Matches(3)); + +  Matcher<IntValue> m3 = Truly(IsPositiveIntValue); +  Matcher<int> m4 = MatcherCast<int>(m3); +  // In the following, the arguments 1 and 0 are statically converted +  // to IntValue objects, and then tested by the IsPositiveIntValue() +  // predicate. +  EXPECT_TRUE(m4.Matches(1)); +  EXPECT_FALSE(m4.Matches(0)); +} + +// Tests that MatcherCast<T>(m) works when m is a Matcher<const T&>. +TEST(MatcherCastTest, FromConstReferenceToNonReference) { +  Matcher<const int&> m1 = Eq(0); +  Matcher<int> m2 = MatcherCast<int>(m1); +  EXPECT_TRUE(m2.Matches(0)); +  EXPECT_FALSE(m2.Matches(1)); +} + +// Tests that MatcherCast<T>(m) works when m is a Matcher<T&>. +TEST(MatcherCastTest, FromReferenceToNonReference) { +  Matcher<int&> m1 = Eq(0); +  Matcher<int> m2 = MatcherCast<int>(m1); +  EXPECT_TRUE(m2.Matches(0)); +  EXPECT_FALSE(m2.Matches(1)); +} + +// Tests that MatcherCast<const T&>(m) works when m is a Matcher<T>. +TEST(MatcherCastTest, FromNonReferenceToConstReference) { +  Matcher<int> m1 = Eq(0); +  Matcher<const int&> m2 = MatcherCast<const int&>(m1); +  EXPECT_TRUE(m2.Matches(0)); +  EXPECT_FALSE(m2.Matches(1)); +} + +// Tests that MatcherCast<T&>(m) works when m is a Matcher<T>. +TEST(MatcherCastTest, FromNonReferenceToReference) { +  Matcher<int> m1 = Eq(0); +  Matcher<int&> m2 = MatcherCast<int&>(m1); +  int n = 0; +  EXPECT_TRUE(m2.Matches(n)); +  n = 1; +  EXPECT_FALSE(m2.Matches(n)); +} + +// Tests that MatcherCast<T>(m) works when m is a Matcher<T>. +TEST(MatcherCastTest, FromSameType) { +  Matcher<int> m1 = Eq(0); +  Matcher<int> m2 = MatcherCast<int>(m1); +  EXPECT_TRUE(m2.Matches(0)); +  EXPECT_FALSE(m2.Matches(1)); +} + +// Tests that A<T>() matches any value of type T. +TEST(ATest, MatchesAnyValue) { +  // Tests a matcher for a value type. +  Matcher<double> m1 = A<double>(); +  EXPECT_TRUE(m1.Matches(91.43)); +  EXPECT_TRUE(m1.Matches(-15.32)); + +  // Tests a matcher for a reference type. +  int a = 2; +  int b = -6; +  Matcher<int&> m2 = A<int&>(); +  EXPECT_TRUE(m2.Matches(a)); +  EXPECT_TRUE(m2.Matches(b)); +} + +// Tests that A<T>() describes itself properly. +TEST(ATest, CanDescribeSelf) { +  EXPECT_EQ("is anything", Describe(A<bool>())); +} + +// Tests that An<T>() matches any value of type T. +TEST(AnTest, MatchesAnyValue) { +  // Tests a matcher for a value type. +  Matcher<int> m1 = An<int>(); +  EXPECT_TRUE(m1.Matches(9143)); +  EXPECT_TRUE(m1.Matches(-1532)); + +  // Tests a matcher for a reference type. +  int a = 2; +  int b = -6; +  Matcher<int&> m2 = An<int&>(); +  EXPECT_TRUE(m2.Matches(a)); +  EXPECT_TRUE(m2.Matches(b)); +} + +// Tests that An<T>() describes itself properly. +TEST(AnTest, CanDescribeSelf) { +  EXPECT_EQ("is anything", Describe(An<int>())); +} + +// Tests that _ can be used as a matcher for any type and matches any +// value of that type. +TEST(UnderscoreTest, MatchesAnyValue) { +  // Uses _ as a matcher for a value type. +  Matcher<int> m1 = _; +  EXPECT_TRUE(m1.Matches(123)); +  EXPECT_TRUE(m1.Matches(-242)); + +  // Uses _ as a matcher for a reference type. +  bool a = false; +  const bool b = true; +  Matcher<const bool&> m2 = _; +  EXPECT_TRUE(m2.Matches(a)); +  EXPECT_TRUE(m2.Matches(b)); +} + +// Tests that _ describes itself properly. +TEST(UnderscoreTest, CanDescribeSelf) { +  Matcher<int> m = _; +  EXPECT_EQ("is anything", Describe(m)); +} + +// Tests that Eq(x) matches any value equal to x. +TEST(EqTest, MatchesEqualValue) { +  // 2 C-strings with same content but different addresses. +  const char a1[] = "hi"; +  const char a2[] = "hi"; + +  Matcher<const char*> m1 = Eq(a1); +  EXPECT_TRUE(m1.Matches(a1)); +  EXPECT_FALSE(m1.Matches(a2)); +} + +// Tests that Eq(v) describes itself properly. + +class Unprintable { + public: +  Unprintable() : c_('a') {} + +  bool operator==(const Unprintable& rhs) { return true; } + private: +  char c_; +}; + +TEST(EqTest, CanDescribeSelf) { +  Matcher<Unprintable> m = Eq(Unprintable()); +  EXPECT_EQ("is equal to 1-byte object <61>", Describe(m)); +} + +// Tests that Eq(v) can be used to match any type that supports +// comparing with type T, where T is v's type. +TEST(EqTest, IsPolymorphic) { +  Matcher<int> m1 = Eq(1); +  EXPECT_TRUE(m1.Matches(1)); +  EXPECT_FALSE(m1.Matches(2)); + +  Matcher<char> m2 = Eq(1); +  EXPECT_TRUE(m2.Matches('\1')); +  EXPECT_FALSE(m2.Matches('a')); +} + +// Tests that TypedEq<T>(v) matches values of type T that's equal to v. +TEST(TypedEqTest, ChecksEqualityForGivenType) { +  Matcher<char> m1 = TypedEq<char>('a'); +  EXPECT_TRUE(m1.Matches('a')); +  EXPECT_FALSE(m1.Matches('b')); + +  Matcher<int> m2 = TypedEq<int>(6); +  EXPECT_TRUE(m2.Matches(6)); +  EXPECT_FALSE(m2.Matches(7)); +} + +// Tests that TypedEq(v) describes itself properly. +TEST(TypedEqTest, CanDescribeSelf) { +  EXPECT_EQ("is equal to 2", Describe(TypedEq<int>(2))); +} + +// Tests that TypedEq<T>(v) has type Matcher<T>. + +// Type<T>::IsTypeOf(v) compiles iff the type of value v is T, where T +// is a "bare" type (i.e. not in the form of const U or U&).  If v's +// type is not T, the compiler will generate a message about +// "undefined referece". +template <typename T> +struct Type { +  static bool IsTypeOf(const T& v) { return true; } + +  template <typename T2> +  static void IsTypeOf(T2 v); +}; + +TEST(TypedEqTest, HasSpecifiedType) { +  // Verfies that the type of TypedEq<T>(v) is Matcher<T>. +  Type<Matcher<int> >::IsTypeOf(TypedEq<int>(5)); +  Type<Matcher<double> >::IsTypeOf(TypedEq<double>(5)); +} + +// Tests that Ge(v) matches anything >= v. +TEST(GeTest, ImplementsGreaterThanOrEqual) { +  Matcher<int> m1 = Ge(0); +  EXPECT_TRUE(m1.Matches(1)); +  EXPECT_TRUE(m1.Matches(0)); +  EXPECT_FALSE(m1.Matches(-1)); +} + +// Tests that Ge(v) describes itself properly. +TEST(GeTest, CanDescribeSelf) { +  Matcher<int> m = Ge(5); +  EXPECT_EQ("is greater than or equal to 5", Describe(m)); +} + +// Tests that Gt(v) matches anything > v. +TEST(GtTest, ImplementsGreaterThan) { +  Matcher<double> m1 = Gt(0); +  EXPECT_TRUE(m1.Matches(1.0)); +  EXPECT_FALSE(m1.Matches(0.0)); +  EXPECT_FALSE(m1.Matches(-1.0)); +} + +// Tests that Gt(v) describes itself properly. +TEST(GtTest, CanDescribeSelf) { +  Matcher<int> m = Gt(5); +  EXPECT_EQ("is greater than 5", Describe(m)); +} + +// Tests that Le(v) matches anything <= v. +TEST(LeTest, ImplementsLessThanOrEqual) { +  Matcher<char> m1 = Le('b'); +  EXPECT_TRUE(m1.Matches('a')); +  EXPECT_TRUE(m1.Matches('b')); +  EXPECT_FALSE(m1.Matches('c')); +} + +// Tests that Le(v) describes itself properly. +TEST(LeTest, CanDescribeSelf) { +  Matcher<int> m = Le(5); +  EXPECT_EQ("is less than or equal to 5", Describe(m)); +} + +// Tests that Lt(v) matches anything < v. +TEST(LtTest, ImplementsLessThan) { +  Matcher<const string&> m1 = Lt("Hello"); +  EXPECT_TRUE(m1.Matches("Abc")); +  EXPECT_FALSE(m1.Matches("Hello")); +  EXPECT_FALSE(m1.Matches("Hello, world!")); +} + +// Tests that Lt(v) describes itself properly. +TEST(LtTest, CanDescribeSelf) { +  Matcher<int> m = Lt(5); +  EXPECT_EQ("is less than 5", Describe(m)); +} + +// Tests that Ne(v) matches anything != v. +TEST(NeTest, ImplementsNotEqual) { +  Matcher<int> m1 = Ne(0); +  EXPECT_TRUE(m1.Matches(1)); +  EXPECT_TRUE(m1.Matches(-1)); +  EXPECT_FALSE(m1.Matches(0)); +} + +// Tests that Ne(v) describes itself properly. +TEST(NeTest, CanDescribeSelf) { +  Matcher<int> m = Ne(5); +  EXPECT_EQ("is not equal to 5", Describe(m)); +} + +// Tests that NotNull() matches any non-NULL pointer of any type. +TEST(NotNullTest, MatchesNonNullPointer) { +  Matcher<int*> m1 = NotNull(); +  int* p1 = NULL; +  int n = 0; +  EXPECT_FALSE(m1.Matches(p1)); +  EXPECT_TRUE(m1.Matches(&n)); + +  Matcher<const char*> m2 = NotNull(); +  const char* p2 = NULL; +  EXPECT_FALSE(m2.Matches(p2)); +  EXPECT_TRUE(m2.Matches("hi")); +} + +// Tests that NotNull() describes itself properly. +TEST(NotNullTest, CanDescribeSelf) { +  Matcher<int*> m = NotNull(); +  EXPECT_EQ("is not NULL", Describe(m)); +} + +// Tests that Ref(variable) matches an argument that references +// 'variable'. +TEST(RefTest, MatchesSameVariable) { +  int a = 0; +  int b = 0; +  Matcher<int&> m = Ref(a); +  EXPECT_TRUE(m.Matches(a)); +  EXPECT_FALSE(m.Matches(b)); +} + +// Tests that Ref(variable) describes itself properly. +TEST(RefTest, CanDescribeSelf) { +  int n = 5; +  Matcher<int&> m = Ref(n); +  stringstream ss; +  ss << "references the variable @" << &n << " 5"; +  EXPECT_EQ(string(ss.str()), Describe(m)); +} + +// Test that Ref(non_const_varialbe) can be used as a matcher for a +// const reference. +TEST(RefTest, CanBeUsedAsMatcherForConstReference) { +  int a = 0; +  int b = 0; +  Matcher<const int&> m = Ref(a); +  EXPECT_TRUE(m.Matches(a)); +  EXPECT_FALSE(m.Matches(b)); +} + +// Tests that Ref(variable) is covariant, i.e. Ref(derived) can be +// used wherever Ref(base) can be used (Ref(derived) is a sub-type +// of Ref(base), but not vice versa. + +class Base {}; +class Derived : public Base {}; + +TEST(RefTest, IsCovariant) { +  Base base, base2; +  Derived derived; +  Matcher<const Base&> m1 = Ref(base); +  EXPECT_TRUE(m1.Matches(base)); +  EXPECT_FALSE(m1.Matches(base2)); +  EXPECT_FALSE(m1.Matches(derived)); + +  m1 = Ref(derived); +  EXPECT_TRUE(m1.Matches(derived)); +  EXPECT_FALSE(m1.Matches(base)); +  EXPECT_FALSE(m1.Matches(base2)); +} + +// Tests string comparison matchers. + +TEST(StrEqTest, MatchesEqualString) { +  Matcher<const char*> m = StrEq(string("Hello")); +  EXPECT_TRUE(m.Matches("Hello")); +  EXPECT_FALSE(m.Matches("hello")); +  EXPECT_FALSE(m.Matches(NULL)); + +  Matcher<const string&> m2 = StrEq("Hello"); +  EXPECT_TRUE(m2.Matches("Hello")); +  EXPECT_FALSE(m2.Matches("Hi")); +} + +TEST(StrEqTest, CanDescribeSelf) { +  Matcher<string> m = StrEq("Hi-\'\"\?\\\a\b\f\n\r\t\v\xD3"); +  EXPECT_EQ("is equal to \"Hi-\'\\\"\\?\\\\\\a\\b\\f\\n\\r\\t\\v\\xD3\"", +      Describe(m)); + +  string str("01204500800"); +  str[3] = '\0'; +  Matcher<string> m2 = StrEq(str); +  EXPECT_EQ("is equal to \"012\\04500800\"", Describe(m2)); +  str[0] = str[6] = str[7] = str[9] = str[10] = '\0'; +  Matcher<string> m3 = StrEq(str); +  EXPECT_EQ("is equal to \"\\012\\045\\0\\08\\0\\0\"", Describe(m3)); +} + +TEST(StrNeTest, MatchesUnequalString) { +  Matcher<const char*> m = StrNe("Hello"); +  EXPECT_TRUE(m.Matches("")); +  EXPECT_TRUE(m.Matches(NULL)); +  EXPECT_FALSE(m.Matches("Hello")); + +  Matcher<string> m2 = StrNe(string("Hello")); +  EXPECT_TRUE(m2.Matches("hello")); +  EXPECT_FALSE(m2.Matches("Hello")); +} + +TEST(StrNeTest, CanDescribeSelf) { +  Matcher<const char*> m = StrNe("Hi"); +  EXPECT_EQ("is not equal to \"Hi\"", Describe(m)); +} + +TEST(StrCaseEqTest, MatchesEqualStringIgnoringCase) { +  Matcher<const char*> m = StrCaseEq(string("Hello")); +  EXPECT_TRUE(m.Matches("Hello")); +  EXPECT_TRUE(m.Matches("hello")); +  EXPECT_FALSE(m.Matches("Hi")); +  EXPECT_FALSE(m.Matches(NULL)); + +  Matcher<const string&> m2 = StrCaseEq("Hello"); +  EXPECT_TRUE(m2.Matches("hello")); +  EXPECT_FALSE(m2.Matches("Hi")); +} + +TEST(StrCaseEqTest, MatchesEqualStringWith0IgnoringCase) { +  string str1("oabocdooeoo"); +  string str2("OABOCDOOEOO"); +  Matcher<const string&> m0 = StrCaseEq(str1); +  EXPECT_FALSE(m0.Matches(str2 + string(1, '\0'))); + +  str1[3] = str2[3] = '\0'; +  Matcher<const string&> m1 = StrCaseEq(str1); +  EXPECT_TRUE(m1.Matches(str2)); + +  str1[0] = str1[6] = str1[7] = str1[10] = '\0'; +  str2[0] = str2[6] = str2[7] = str2[10] = '\0'; +  Matcher<const string&> m2 = StrCaseEq(str1); +  str1[9] = str2[9] = '\0'; +  EXPECT_FALSE(m2.Matches(str2)); + +  Matcher<const string&> m3 = StrCaseEq(str1); +  EXPECT_TRUE(m3.Matches(str2)); + +  EXPECT_FALSE(m3.Matches(str2 + "x")); +  str2.append(1, '\0'); +  EXPECT_FALSE(m3.Matches(str2)); +  EXPECT_FALSE(m3.Matches(string(str2, 0, 9))); +} + +TEST(StrCaseEqTest, CanDescribeSelf) { +  Matcher<string> m = StrCaseEq("Hi"); +  EXPECT_EQ("is equal to (ignoring case) \"Hi\"", Describe(m)); +} + +TEST(StrCaseNeTest, MatchesUnequalStringIgnoringCase) { +  Matcher<const char*> m = StrCaseNe("Hello"); +  EXPECT_TRUE(m.Matches("Hi")); +  EXPECT_TRUE(m.Matches(NULL)); +  EXPECT_FALSE(m.Matches("Hello")); +  EXPECT_FALSE(m.Matches("hello")); + +  Matcher<string> m2 = StrCaseNe(string("Hello")); +  EXPECT_TRUE(m2.Matches("")); +  EXPECT_FALSE(m2.Matches("Hello")); +} + +TEST(StrCaseNeTest, CanDescribeSelf) { +  Matcher<const char*> m = StrCaseNe("Hi"); +  EXPECT_EQ("is not equal to (ignoring case) \"Hi\"", Describe(m)); +} + +// Tests that HasSubstr() works for matching string-typed values. +TEST(HasSubstrTest, WorksForStringClasses) { +  const Matcher<string> m1 = HasSubstr("foo"); +  EXPECT_TRUE(m1.Matches(string("I love food."))); +  EXPECT_FALSE(m1.Matches(string("tofo"))); + +  const Matcher<const std::string&> m2 = HasSubstr("foo"); +  EXPECT_TRUE(m2.Matches(std::string("I love food."))); +  EXPECT_FALSE(m2.Matches(std::string("tofo"))); +} + +// Tests that HasSubstr() works for matching C-string-typed values. +TEST(HasSubstrTest, WorksForCStrings) { +  const Matcher<char*> m1 = HasSubstr("foo"); +  EXPECT_TRUE(m1.Matches(const_cast<char*>("I love food."))); +  EXPECT_FALSE(m1.Matches(const_cast<char*>("tofo"))); +  EXPECT_FALSE(m1.Matches(NULL)); + +  const Matcher<const char*> m2 = HasSubstr("foo"); +  EXPECT_TRUE(m2.Matches("I love food.")); +  EXPECT_FALSE(m2.Matches("tofo")); +  EXPECT_FALSE(m2.Matches(NULL)); +} + +// Tests that HasSubstr(s) describes itself properly. +TEST(HasSubstrTest, CanDescribeSelf) { +  Matcher<string> m = HasSubstr("foo\n\""); +  EXPECT_EQ("has substring \"foo\\n\\\"\"", Describe(m)); +} + +// Tests StartsWith(s). + +TEST(StartsWithTest, MatchesStringWithGivenPrefix) { +  const Matcher<const char*> m1 = StartsWith(string("")); +  EXPECT_TRUE(m1.Matches("Hi")); +  EXPECT_TRUE(m1.Matches("")); +  EXPECT_FALSE(m1.Matches(NULL)); + +  const Matcher<const string&> m2 = StartsWith("Hi"); +  EXPECT_TRUE(m2.Matches("Hi")); +  EXPECT_TRUE(m2.Matches("Hi Hi!")); +  EXPECT_TRUE(m2.Matches("High")); +  EXPECT_FALSE(m2.Matches("H")); +  EXPECT_FALSE(m2.Matches(" Hi")); +} + +TEST(StartsWithTest, CanDescribeSelf) { +  Matcher<const std::string> m = StartsWith("Hi"); +  EXPECT_EQ("starts with \"Hi\"", Describe(m)); +} + +// Tests EndsWith(s). + +TEST(EndsWithTest, MatchesStringWithGivenSuffix) { +  const Matcher<const char*> m1 = EndsWith(""); +  EXPECT_TRUE(m1.Matches("Hi")); +  EXPECT_TRUE(m1.Matches("")); +  EXPECT_FALSE(m1.Matches(NULL)); + +  const Matcher<const string&> m2 = EndsWith(string("Hi")); +  EXPECT_TRUE(m2.Matches("Hi")); +  EXPECT_TRUE(m2.Matches("Wow Hi Hi")); +  EXPECT_TRUE(m2.Matches("Super Hi")); +  EXPECT_FALSE(m2.Matches("i")); +  EXPECT_FALSE(m2.Matches("Hi ")); +} + +TEST(EndsWithTest, CanDescribeSelf) { +  Matcher<const std::string> m = EndsWith("Hi"); +  EXPECT_EQ("ends with \"Hi\"", Describe(m)); +} + +#ifdef GMOCK_HAS_REGEX + +// Tests MatchesRegex(). + +TEST(MatchesRegexTest, MatchesStringMatchingGivenRegex) { +  const Matcher<const char*> m1 = MatchesRegex("a.*z"); +  EXPECT_TRUE(m1.Matches("az")); +  EXPECT_TRUE(m1.Matches("abcz")); +  EXPECT_FALSE(m1.Matches(NULL)); + +  const Matcher<const string&> m2 = MatchesRegex(new RE("a.*z")); +  EXPECT_TRUE(m2.Matches("azbz")); +  EXPECT_FALSE(m2.Matches("az1")); +  EXPECT_FALSE(m2.Matches("1az")); +} + +TEST(MatchesRegexTest, CanDescribeSelf) { +  Matcher<const std::string> m1 = MatchesRegex(string("Hi.*")); +  EXPECT_EQ("matches regular expression \"Hi.*\"", Describe(m1)); + +  Matcher<const char*> m2 = MatchesRegex(new RE("[a-z].*")); +  EXPECT_EQ("matches regular expression \"[a-z].*\"", Describe(m2)); +} + +// Tests ContainsRegex(). + +TEST(ContainsRegexTest, MatchesStringContainingGivenRegex) { +  const Matcher<const char*> m1 = ContainsRegex(string("a.*z")); +  EXPECT_TRUE(m1.Matches("az")); +  EXPECT_TRUE(m1.Matches("0abcz1")); +  EXPECT_FALSE(m1.Matches(NULL)); + +  const Matcher<const string&> m2 = ContainsRegex(new RE("a.*z")); +  EXPECT_TRUE(m2.Matches("azbz")); +  EXPECT_TRUE(m2.Matches("az1")); +  EXPECT_FALSE(m2.Matches("1a")); +} + +TEST(ContainsRegexTest, CanDescribeSelf) { +  Matcher<const std::string> m1 = ContainsRegex("Hi.*"); +  EXPECT_EQ("contains regular expression \"Hi.*\"", Describe(m1)); + +  Matcher<const char*> m2 = ContainsRegex(new RE("[a-z].*")); +  EXPECT_EQ("contains regular expression \"[a-z].*\"", Describe(m2)); +} +#endif  // GMOCK_HAS_REGEX + +// Tests for wide strings. +#if GTEST_HAS_STD_WSTRING +TEST(StdWideStrEqTest, MatchesEqual) { +  Matcher<const wchar_t*> m = StrEq(::std::wstring(L"Hello")); +  EXPECT_TRUE(m.Matches(L"Hello")); +  EXPECT_FALSE(m.Matches(L"hello")); +  EXPECT_FALSE(m.Matches(NULL)); + +  Matcher<const ::std::wstring&> m2 = StrEq(L"Hello"); +  EXPECT_TRUE(m2.Matches(L"Hello")); +  EXPECT_FALSE(m2.Matches(L"Hi")); + +  Matcher<const ::std::wstring&> m3 = StrEq(L"\xD3\x576\x8D3\xC74D"); +  EXPECT_TRUE(m3.Matches(L"\xD3\x576\x8D3\xC74D")); +  EXPECT_FALSE(m3.Matches(L"\xD3\x576\x8D3\xC74E")); + +  ::std::wstring str(L"01204500800"); +  str[3] = L'\0'; +  Matcher<const ::std::wstring&> m4 = StrEq(str); +  EXPECT_TRUE(m4.Matches(str)); +  str[0] = str[6] = str[7] = str[9] = str[10] = L'\0'; +  Matcher<const ::std::wstring&> m5 = StrEq(str); +  EXPECT_TRUE(m5.Matches(str)); +} + +TEST(StdWideStrEqTest, CanDescribeSelf) { +  Matcher< ::std::wstring> m = StrEq(L"Hi-\'\"\?\\\a\b\f\n\r\t\v"); +  EXPECT_EQ("is equal to L\"Hi-\'\\\"\\?\\\\\\a\\b\\f\\n\\r\\t\\v\"", +    Describe(m)); + +  Matcher< ::std::wstring> m2 = StrEq(L"\xD3\x576\x8D3\xC74D"); +  EXPECT_EQ("is equal to L\"\\xD3\\x576\\x8D3\\xC74D\"", +    Describe(m2)); + +  ::std::wstring str(L"01204500800"); +  str[3] = L'\0'; +  Matcher<const ::std::wstring&> m4 = StrEq(str); +  EXPECT_EQ("is equal to L\"012\\04500800\"", Describe(m4)); +  str[0] = str[6] = str[7] = str[9] = str[10] = L'\0'; +  Matcher<const ::std::wstring&> m5 = StrEq(str); +  EXPECT_EQ("is equal to L\"\\012\\045\\0\\08\\0\\0\"", Describe(m5)); +} + +TEST(StdWideStrNeTest, MatchesUnequalString) { +  Matcher<const wchar_t*> m = StrNe(L"Hello"); +  EXPECT_TRUE(m.Matches(L"")); +  EXPECT_TRUE(m.Matches(NULL)); +  EXPECT_FALSE(m.Matches(L"Hello")); + +  Matcher< ::std::wstring> m2 = StrNe(::std::wstring(L"Hello")); +  EXPECT_TRUE(m2.Matches(L"hello")); +  EXPECT_FALSE(m2.Matches(L"Hello")); +} + +TEST(StdWideStrNeTest, CanDescribeSelf) { +  Matcher<const wchar_t*> m = StrNe(L"Hi"); +  EXPECT_EQ("is not equal to L\"Hi\"", Describe(m)); +} + +TEST(StdWideStrCaseEqTest, MatchesEqualStringIgnoringCase) { +  Matcher<const wchar_t*> m = StrCaseEq(::std::wstring(L"Hello")); +  EXPECT_TRUE(m.Matches(L"Hello")); +  EXPECT_TRUE(m.Matches(L"hello")); +  EXPECT_FALSE(m.Matches(L"Hi")); +  EXPECT_FALSE(m.Matches(NULL)); + +  Matcher<const ::std::wstring&> m2 = StrCaseEq(L"Hello"); +  EXPECT_TRUE(m2.Matches(L"hello")); +  EXPECT_FALSE(m2.Matches(L"Hi")); +} + +TEST(StdWideStrCaseEqTest, MatchesEqualStringWith0IgnoringCase) { +  ::std::wstring str1(L"oabocdooeoo"); +  ::std::wstring str2(L"OABOCDOOEOO"); +  Matcher<const ::std::wstring&> m0 = StrCaseEq(str1); +  EXPECT_FALSE(m0.Matches(str2 + ::std::wstring(1, L'\0'))); + +  str1[3] = str2[3] = L'\0'; +  Matcher<const ::std::wstring&> m1 = StrCaseEq(str1); +  EXPECT_TRUE(m1.Matches(str2)); + +  str1[0] = str1[6] = str1[7] = str1[10] = L'\0'; +  str2[0] = str2[6] = str2[7] = str2[10] = L'\0'; +  Matcher<const ::std::wstring&> m2 = StrCaseEq(str1); +  str1[9] = str2[9] = L'\0'; +  EXPECT_FALSE(m2.Matches(str2)); + +  Matcher<const ::std::wstring&> m3 = StrCaseEq(str1); +  EXPECT_TRUE(m3.Matches(str2)); + +  EXPECT_FALSE(m3.Matches(str2 + L"x")); +  str2.append(1, L'\0'); +  EXPECT_FALSE(m3.Matches(str2)); +  EXPECT_FALSE(m3.Matches(::std::wstring(str2, 0, 9))); +} + +TEST(StdWideStrCaseEqTest, CanDescribeSelf) { +  Matcher< ::std::wstring> m = StrCaseEq(L"Hi"); +  EXPECT_EQ("is equal to (ignoring case) L\"Hi\"", Describe(m)); +} + +TEST(StdWideStrCaseNeTest, MatchesUnequalStringIgnoringCase) { +  Matcher<const wchar_t*> m = StrCaseNe(L"Hello"); +  EXPECT_TRUE(m.Matches(L"Hi")); +  EXPECT_TRUE(m.Matches(NULL)); +  EXPECT_FALSE(m.Matches(L"Hello")); +  EXPECT_FALSE(m.Matches(L"hello")); + +  Matcher< ::std::wstring> m2 = StrCaseNe(::std::wstring(L"Hello")); +  EXPECT_TRUE(m2.Matches(L"")); +  EXPECT_FALSE(m2.Matches(L"Hello")); +} + +TEST(StdWideStrCaseNeTest, CanDescribeSelf) { +  Matcher<const wchar_t*> m = StrCaseNe(L"Hi"); +  EXPECT_EQ("is not equal to (ignoring case) L\"Hi\"", Describe(m)); +} + +// Tests that HasSubstr() works for matching wstring-typed values. +TEST(StdWideHasSubstrTest, WorksForStringClasses) { +  const Matcher< ::std::wstring> m1 = HasSubstr(L"foo"); +  EXPECT_TRUE(m1.Matches(::std::wstring(L"I love food."))); +  EXPECT_FALSE(m1.Matches(::std::wstring(L"tofo"))); + +  const Matcher<const ::std::wstring&> m2 = HasSubstr(L"foo"); +  EXPECT_TRUE(m2.Matches(::std::wstring(L"I love food."))); +  EXPECT_FALSE(m2.Matches(::std::wstring(L"tofo"))); +} + +// Tests that HasSubstr() works for matching C-wide-string-typed values. +TEST(StdWideHasSubstrTest, WorksForCStrings) { +  const Matcher<wchar_t*> m1 = HasSubstr(L"foo"); +  EXPECT_TRUE(m1.Matches(const_cast<wchar_t*>(L"I love food."))); +  EXPECT_FALSE(m1.Matches(const_cast<wchar_t*>(L"tofo"))); +  EXPECT_FALSE(m1.Matches(NULL)); + +  const Matcher<const wchar_t*> m2 = HasSubstr(L"foo"); +  EXPECT_TRUE(m2.Matches(L"I love food.")); +  EXPECT_FALSE(m2.Matches(L"tofo")); +  EXPECT_FALSE(m2.Matches(NULL)); +} + +// Tests that HasSubstr(s) describes itself properly. +TEST(StdWideHasSubstrTest, CanDescribeSelf) { +  Matcher< ::std::wstring> m = HasSubstr(L"foo\n\""); +  EXPECT_EQ("has substring L\"foo\\n\\\"\"", Describe(m)); +} + +// Tests StartsWith(s). + +TEST(StdWideStartsWithTest, MatchesStringWithGivenPrefix) { +  const Matcher<const wchar_t*> m1 = StartsWith(::std::wstring(L"")); +  EXPECT_TRUE(m1.Matches(L"Hi")); +  EXPECT_TRUE(m1.Matches(L"")); +  EXPECT_FALSE(m1.Matches(NULL)); + +  const Matcher<const ::std::wstring&> m2 = StartsWith(L"Hi"); +  EXPECT_TRUE(m2.Matches(L"Hi")); +  EXPECT_TRUE(m2.Matches(L"Hi Hi!")); +  EXPECT_TRUE(m2.Matches(L"High")); +  EXPECT_FALSE(m2.Matches(L"H")); +  EXPECT_FALSE(m2.Matches(L" Hi")); +} + +TEST(StdWideStartsWithTest, CanDescribeSelf) { +  Matcher<const ::std::wstring> m = StartsWith(L"Hi"); +  EXPECT_EQ("starts with L\"Hi\"", Describe(m)); +} + +// Tests EndsWith(s). + +TEST(StdWideEndsWithTest, MatchesStringWithGivenSuffix) { +  const Matcher<const wchar_t*> m1 = EndsWith(L""); +  EXPECT_TRUE(m1.Matches(L"Hi")); +  EXPECT_TRUE(m1.Matches(L"")); +  EXPECT_FALSE(m1.Matches(NULL)); + +  const Matcher<const ::std::wstring&> m2 = EndsWith(::std::wstring(L"Hi")); +  EXPECT_TRUE(m2.Matches(L"Hi")); +  EXPECT_TRUE(m2.Matches(L"Wow Hi Hi")); +  EXPECT_TRUE(m2.Matches(L"Super Hi")); +  EXPECT_FALSE(m2.Matches(L"i")); +  EXPECT_FALSE(m2.Matches(L"Hi ")); +} + +TEST(StdWideEndsWithTest, CanDescribeSelf) { +  Matcher<const ::std::wstring> m = EndsWith(L"Hi"); +  EXPECT_EQ("ends with L\"Hi\"", Describe(m)); +} + +#endif  // GTEST_HAS_STD_WSTRING + +#if GTEST_HAS_GLOBAL_WSTRING +TEST(GlobalWideStrEqTest, MatchesEqual) { +  Matcher<const wchar_t*> m = StrEq(::wstring(L"Hello")); +  EXPECT_TRUE(m.Matches(L"Hello")); +  EXPECT_FALSE(m.Matches(L"hello")); +  EXPECT_FALSE(m.Matches(NULL)); + +  Matcher<const ::wstring&> m2 = StrEq(L"Hello"); +  EXPECT_TRUE(m2.Matches(L"Hello")); +  EXPECT_FALSE(m2.Matches(L"Hi")); + +  Matcher<const ::wstring&> m3 = StrEq(L"\xD3\x576\x8D3\xC74D"); +  EXPECT_TRUE(m3.Matches(L"\xD3\x576\x8D3\xC74D")); +  EXPECT_FALSE(m3.Matches(L"\xD3\x576\x8D3\xC74E")); + +  ::wstring str(L"01204500800"); +  str[3] = L'\0'; +  Matcher<const ::wstring&> m4 = StrEq(str); +  EXPECT_TRUE(m4.Matches(str)); +  str[0] = str[6] = str[7] = str[9] = str[10] = L'\0'; +  Matcher<const ::wstring&> m5 = StrEq(str); +  EXPECT_TRUE(m5.Matches(str)); +} + +TEST(GlobalWideStrEqTest, CanDescribeSelf) { +  Matcher< ::wstring> m = StrEq(L"Hi-\'\"\?\\\a\b\f\n\r\t\v"); +  EXPECT_EQ("is equal to L\"Hi-\'\\\"\\?\\\\\\a\\b\\f\\n\\r\\t\\v\"", +    Describe(m)); + +  Matcher< ::wstring> m2 = StrEq(L"\xD3\x576\x8D3\xC74D"); +  EXPECT_EQ("is equal to L\"\\xD3\\x576\\x8D3\\xC74D\"", +    Describe(m2)); + +  ::wstring str(L"01204500800"); +  str[3] = L'\0'; +  Matcher<const ::wstring&> m4 = StrEq(str); +  EXPECT_EQ("is equal to L\"012\\04500800\"", Describe(m4)); +  str[0] = str[6] = str[7] = str[9] = str[10] = L'\0'; +  Matcher<const ::wstring&> m5 = StrEq(str); +  EXPECT_EQ("is equal to L\"\\012\\045\\0\\08\\0\\0\"", Describe(m5)); +} + +TEST(GlobalWideStrNeTest, MatchesUnequalString) { +  Matcher<const wchar_t*> m = StrNe(L"Hello"); +  EXPECT_TRUE(m.Matches(L"")); +  EXPECT_TRUE(m.Matches(NULL)); +  EXPECT_FALSE(m.Matches(L"Hello")); + +  Matcher< ::wstring> m2 = StrNe(::wstring(L"Hello")); +  EXPECT_TRUE(m2.Matches(L"hello")); +  EXPECT_FALSE(m2.Matches(L"Hello")); +} + +TEST(GlobalWideStrNeTest, CanDescribeSelf) { +  Matcher<const wchar_t*> m = StrNe(L"Hi"); +  EXPECT_EQ("is not equal to L\"Hi\"", Describe(m)); +} + +TEST(GlobalWideStrCaseEqTest, MatchesEqualStringIgnoringCase) { +  Matcher<const wchar_t*> m = StrCaseEq(::wstring(L"Hello")); +  EXPECT_TRUE(m.Matches(L"Hello")); +  EXPECT_TRUE(m.Matches(L"hello")); +  EXPECT_FALSE(m.Matches(L"Hi")); +  EXPECT_FALSE(m.Matches(NULL)); + +  Matcher<const ::wstring&> m2 = StrCaseEq(L"Hello"); +  EXPECT_TRUE(m2.Matches(L"hello")); +  EXPECT_FALSE(m2.Matches(L"Hi")); +} + +TEST(GlobalWideStrCaseEqTest, MatchesEqualStringWith0IgnoringCase) { +  ::wstring str1(L"oabocdooeoo"); +  ::wstring str2(L"OABOCDOOEOO"); +  Matcher<const ::wstring&> m0 = StrCaseEq(str1); +  EXPECT_FALSE(m0.Matches(str2 + ::wstring(1, L'\0'))); + +  str1[3] = str2[3] = L'\0'; +  Matcher<const ::wstring&> m1 = StrCaseEq(str1); +  EXPECT_TRUE(m1.Matches(str2)); + +  str1[0] = str1[6] = str1[7] = str1[10] = L'\0'; +  str2[0] = str2[6] = str2[7] = str2[10] = L'\0'; +  Matcher<const ::wstring&> m2 = StrCaseEq(str1); +  str1[9] = str2[9] = L'\0'; +  EXPECT_FALSE(m2.Matches(str2)); + +  Matcher<const ::wstring&> m3 = StrCaseEq(str1); +  EXPECT_TRUE(m3.Matches(str2)); + +  EXPECT_FALSE(m3.Matches(str2 + L"x")); +  str2.append(1, L'\0'); +  EXPECT_FALSE(m3.Matches(str2)); +  EXPECT_FALSE(m3.Matches(::wstring(str2, 0, 9))); +} + +TEST(GlobalWideStrCaseEqTest, CanDescribeSelf) { +  Matcher< ::wstring> m = StrCaseEq(L"Hi"); +  EXPECT_EQ("is equal to (ignoring case) L\"Hi\"", Describe(m)); +} + +TEST(GlobalWideStrCaseNeTest, MatchesUnequalStringIgnoringCase) { +  Matcher<const wchar_t*> m = StrCaseNe(L"Hello"); +  EXPECT_TRUE(m.Matches(L"Hi")); +  EXPECT_TRUE(m.Matches(NULL)); +  EXPECT_FALSE(m.Matches(L"Hello")); +  EXPECT_FALSE(m.Matches(L"hello")); + +  Matcher< ::wstring> m2 = StrCaseNe(::wstring(L"Hello")); +  EXPECT_TRUE(m2.Matches(L"")); +  EXPECT_FALSE(m2.Matches(L"Hello")); +} + +TEST(GlobalWideStrCaseNeTest, CanDescribeSelf) { +  Matcher<const wchar_t*> m = StrCaseNe(L"Hi"); +  EXPECT_EQ("is not equal to (ignoring case) L\"Hi\"", Describe(m)); +} + +// Tests that HasSubstr() works for matching wstring-typed values. +TEST(GlobalWideHasSubstrTest, WorksForStringClasses) { +  const Matcher< ::wstring> m1 = HasSubstr(L"foo"); +  EXPECT_TRUE(m1.Matches(::wstring(L"I love food."))); +  EXPECT_FALSE(m1.Matches(::wstring(L"tofo"))); + +  const Matcher<const ::wstring&> m2 = HasSubstr(L"foo"); +  EXPECT_TRUE(m2.Matches(::wstring(L"I love food."))); +  EXPECT_FALSE(m2.Matches(::wstring(L"tofo"))); +} + +// Tests that HasSubstr() works for matching C-wide-string-typed values. +TEST(GlobalWideHasSubstrTest, WorksForCStrings) { +  const Matcher<wchar_t*> m1 = HasSubstr(L"foo"); +  EXPECT_TRUE(m1.Matches(const_cast<wchar_t*>(L"I love food."))); +  EXPECT_FALSE(m1.Matches(const_cast<wchar_t*>(L"tofo"))); +  EXPECT_FALSE(m1.Matches(NULL)); + +  const Matcher<const wchar_t*> m2 = HasSubstr(L"foo"); +  EXPECT_TRUE(m2.Matches(L"I love food.")); +  EXPECT_FALSE(m2.Matches(L"tofo")); +  EXPECT_FALSE(m2.Matches(NULL)); +} + +// Tests that HasSubstr(s) describes itself properly. +TEST(GlobalWideHasSubstrTest, CanDescribeSelf) { +  Matcher< ::wstring> m = HasSubstr(L"foo\n\""); +  EXPECT_EQ("has substring L\"foo\\n\\\"\"", Describe(m)); +} + +// Tests StartsWith(s). + +TEST(GlobalWideStartsWithTest, MatchesStringWithGivenPrefix) { +  const Matcher<const wchar_t*> m1 = StartsWith(::wstring(L"")); +  EXPECT_TRUE(m1.Matches(L"Hi")); +  EXPECT_TRUE(m1.Matches(L"")); +  EXPECT_FALSE(m1.Matches(NULL)); + +  const Matcher<const ::wstring&> m2 = StartsWith(L"Hi"); +  EXPECT_TRUE(m2.Matches(L"Hi")); +  EXPECT_TRUE(m2.Matches(L"Hi Hi!")); +  EXPECT_TRUE(m2.Matches(L"High")); +  EXPECT_FALSE(m2.Matches(L"H")); +  EXPECT_FALSE(m2.Matches(L" Hi")); +} + +TEST(GlobalWideStartsWithTest, CanDescribeSelf) { +  Matcher<const ::wstring> m = StartsWith(L"Hi"); +  EXPECT_EQ("starts with L\"Hi\"", Describe(m)); +} + +// Tests EndsWith(s). + +TEST(GlobalWideEndsWithTest, MatchesStringWithGivenSuffix) { +  const Matcher<const wchar_t*> m1 = EndsWith(L""); +  EXPECT_TRUE(m1.Matches(L"Hi")); +  EXPECT_TRUE(m1.Matches(L"")); +  EXPECT_FALSE(m1.Matches(NULL)); + +  const Matcher<const ::wstring&> m2 = EndsWith(::wstring(L"Hi")); +  EXPECT_TRUE(m2.Matches(L"Hi")); +  EXPECT_TRUE(m2.Matches(L"Wow Hi Hi")); +  EXPECT_TRUE(m2.Matches(L"Super Hi")); +  EXPECT_FALSE(m2.Matches(L"i")); +  EXPECT_FALSE(m2.Matches(L"Hi ")); +} + +TEST(GlobalWideEndsWithTest, CanDescribeSelf) { +  Matcher<const ::wstring> m = EndsWith(L"Hi"); +  EXPECT_EQ("ends with L\"Hi\"", Describe(m)); +} + +#endif  // GTEST_HAS_GLOBAL_WSTRING + + +typedef ::std::tr1::tuple<long, int> Tuple2;  // NOLINT + +// Tests that Eq() matches a 2-tuple where the first field == the +// second field. +TEST(Eq2Test, MatchesEqualArguments) { +  Matcher<const Tuple2&> m = Eq(); +  EXPECT_TRUE(m.Matches(Tuple2(5L, 5))); +  EXPECT_FALSE(m.Matches(Tuple2(5L, 6))); +} + +// Tests that Eq() describes itself properly. +TEST(Eq2Test, CanDescribeSelf) { +  Matcher<const Tuple2&> m = Eq(); +  EXPECT_EQ("argument #0 is equal to argument #1", Describe(m)); +} + +// Tests that Ge() matches a 2-tuple where the first field >= the +// second field. +TEST(Ge2Test, MatchesGreaterThanOrEqualArguments) { +  Matcher<const Tuple2&> m = Ge(); +  EXPECT_TRUE(m.Matches(Tuple2(5L, 4))); +  EXPECT_TRUE(m.Matches(Tuple2(5L, 5))); +  EXPECT_FALSE(m.Matches(Tuple2(5L, 6))); +} + +// Tests that Ge() describes itself properly. +TEST(Ge2Test, CanDescribeSelf) { +  Matcher<const Tuple2&> m = Ge(); +  EXPECT_EQ("argument #0 is greater than or equal to argument #1", +            Describe(m)); +} + +// Tests that Gt() matches a 2-tuple where the first field > the +// second field. +TEST(Gt2Test, MatchesGreaterThanArguments) { +  Matcher<const Tuple2&> m = Gt(); +  EXPECT_TRUE(m.Matches(Tuple2(5L, 4))); +  EXPECT_FALSE(m.Matches(Tuple2(5L, 5))); +  EXPECT_FALSE(m.Matches(Tuple2(5L, 6))); +} + +// Tests that Gt() describes itself properly. +TEST(Gt2Test, CanDescribeSelf) { +  Matcher<const Tuple2&> m = Gt(); +  EXPECT_EQ("argument #0 is greater than argument #1", Describe(m)); +} + +// Tests that Le() matches a 2-tuple where the first field <= the +// second field. +TEST(Le2Test, MatchesLessThanOrEqualArguments) { +  Matcher<const Tuple2&> m = Le(); +  EXPECT_TRUE(m.Matches(Tuple2(5L, 6))); +  EXPECT_TRUE(m.Matches(Tuple2(5L, 5))); +  EXPECT_FALSE(m.Matches(Tuple2(5L, 4))); +} + +// Tests that Le() describes itself properly. +TEST(Le2Test, CanDescribeSelf) { +  Matcher<const Tuple2&> m = Le(); +  EXPECT_EQ("argument #0 is less than or equal to argument #1", +            Describe(m)); +} + +// Tests that Lt() matches a 2-tuple where the first field < the +// second field. +TEST(Lt2Test, MatchesLessThanArguments) { +  Matcher<const Tuple2&> m = Lt(); +  EXPECT_TRUE(m.Matches(Tuple2(5L, 6))); +  EXPECT_FALSE(m.Matches(Tuple2(5L, 5))); +  EXPECT_FALSE(m.Matches(Tuple2(5L, 4))); +} + +// Tests that Lt() describes itself properly. +TEST(Lt2Test, CanDescribeSelf) { +  Matcher<const Tuple2&> m = Lt(); +  EXPECT_EQ("argument #0 is less than argument #1", Describe(m)); +} + +// Tests that Ne() matches a 2-tuple where the first field != the +// second field. +TEST(Ne2Test, MatchesUnequalArguments) { +  Matcher<const Tuple2&> m = Ne(); +  EXPECT_TRUE(m.Matches(Tuple2(5L, 6))); +  EXPECT_TRUE(m.Matches(Tuple2(5L, 4))); +  EXPECT_FALSE(m.Matches(Tuple2(5L, 5))); +} + +// Tests that Ne() describes itself properly. +TEST(Ne2Test, CanDescribeSelf) { +  Matcher<const Tuple2&> m = Ne(); +  EXPECT_EQ("argument #0 is not equal to argument #1", Describe(m)); +} + +// Tests that Not(m) matches any value that doesn't match m. +TEST(NotTest, NegatesMatcher) { +  Matcher<int> m; +  m = Not(Eq(2)); +  EXPECT_TRUE(m.Matches(3)); +  EXPECT_FALSE(m.Matches(2)); +} + +// Tests that Not(m) describes itself properly. +TEST(NotTest, CanDescribeSelf) { +  Matcher<int> m = Not(Eq(5)); +  EXPECT_EQ("is not equal to 5", Describe(m)); +} + +// Tests that AllOf(m1, ..., mn) matches any value that matches all of +// the given matchers. +TEST(AllOfTest, MatchesWhenAllMatch) { +  Matcher<int> m; +  m = AllOf(Le(2), Ge(1)); +  EXPECT_TRUE(m.Matches(1)); +  EXPECT_TRUE(m.Matches(2)); +  EXPECT_FALSE(m.Matches(0)); +  EXPECT_FALSE(m.Matches(3)); + +  m = AllOf(Gt(0), Ne(1), Ne(2)); +  EXPECT_TRUE(m.Matches(3)); +  EXPECT_FALSE(m.Matches(2)); +  EXPECT_FALSE(m.Matches(1)); +  EXPECT_FALSE(m.Matches(0)); + +  m = AllOf(Gt(0), Ne(1), Ne(2), Ne(3)); +  EXPECT_TRUE(m.Matches(4)); +  EXPECT_FALSE(m.Matches(3)); +  EXPECT_FALSE(m.Matches(2)); +  EXPECT_FALSE(m.Matches(1)); +  EXPECT_FALSE(m.Matches(0)); + +  m = AllOf(Ge(0), Lt(10), Ne(3), Ne(5), Ne(7)); +  EXPECT_TRUE(m.Matches(0)); +  EXPECT_TRUE(m.Matches(1)); +  EXPECT_FALSE(m.Matches(3)); +} + +// Tests that AllOf(m1, ..., mn) describes itself properly. +TEST(AllOfTest, CanDescribeSelf) { +  Matcher<int> m; +  m = AllOf(Le(2), Ge(1)); +  EXPECT_EQ("(is less than or equal to 2) and " +            "(is greater than or equal to 1)", +            Describe(m)); + +  m = AllOf(Gt(0), Ne(1), Ne(2)); +  EXPECT_EQ("(is greater than 0) and " +            "((is not equal to 1) and " +            "(is not equal to 2))", +            Describe(m)); + + +  m = AllOf(Gt(0), Ne(1), Ne(2), Ne(3)); +  EXPECT_EQ("(is greater than 0) and " +            "((is not equal to 1) and " +            "((is not equal to 2) and " +            "(is not equal to 3)))", +            Describe(m)); + + +  m = AllOf(Ge(0), Lt(10), Ne(3), Ne(5), Ne(7)); +  EXPECT_EQ("(is greater than or equal to 0) and " +            "((is less than 10) and " +            "((is not equal to 3) and " +            "((is not equal to 5) and " +            "(is not equal to 7))))", Describe(m)); +} + +// Tests that AnyOf(m1, ..., mn) matches any value that matches at +// least one of the given matchers. +TEST(AnyOfTest, MatchesWhenAnyMatches) { +  Matcher<int> m; +  m = AnyOf(Le(1), Ge(3)); +  EXPECT_TRUE(m.Matches(1)); +  EXPECT_TRUE(m.Matches(4)); +  EXPECT_FALSE(m.Matches(2)); + +  m = AnyOf(Lt(0), Eq(1), Eq(2)); +  EXPECT_TRUE(m.Matches(-1)); +  EXPECT_TRUE(m.Matches(1)); +  EXPECT_TRUE(m.Matches(2)); +  EXPECT_FALSE(m.Matches(0)); + +  m = AnyOf(Lt(0), Eq(1), Eq(2), Eq(3)); +  EXPECT_TRUE(m.Matches(-1)); +  EXPECT_TRUE(m.Matches(1)); +  EXPECT_TRUE(m.Matches(2)); +  EXPECT_TRUE(m.Matches(3)); +  EXPECT_FALSE(m.Matches(0)); + +  m = AnyOf(Le(0), Gt(10), 3, 5, 7); +  EXPECT_TRUE(m.Matches(0)); +  EXPECT_TRUE(m.Matches(11)); +  EXPECT_TRUE(m.Matches(3)); +  EXPECT_FALSE(m.Matches(2)); +} + +// Tests that AnyOf(m1, ..., mn) describes itself properly. +TEST(AnyOfTest, CanDescribeSelf) { +  Matcher<int> m; +  m = AnyOf(Le(1), Ge(3)); +  EXPECT_EQ("(is less than or equal to 1) or " +            "(is greater than or equal to 3)", +            Describe(m)); + +  m = AnyOf(Lt(0), Eq(1), Eq(2)); +  EXPECT_EQ("(is less than 0) or " +            "((is equal to 1) or (is equal to 2))", +            Describe(m)); + +  m = AnyOf(Lt(0), Eq(1), Eq(2), Eq(3)); +  EXPECT_EQ("(is less than 0) or " +            "((is equal to 1) or " +            "((is equal to 2) or " +            "(is equal to 3)))", +            Describe(m)); + +  m = AnyOf(Le(0), Gt(10), 3, 5, 7); +  EXPECT_EQ("(is less than or equal to 0) or " +            "((is greater than 10) or " +            "((is equal to 3) or " +            "((is equal to 5) or " +            "(is equal to 7))))", +            Describe(m)); +} + +// The following predicate function and predicate functor are for +// testing the Truly(predicate) matcher. + +// Returns non-zero if the input is positive.  Note that the return +// type of this function is not bool.  It's OK as Truly() accepts any +// unary function or functor whose return type can be implicitly +// converted to bool. +int IsPositive(double x) { +  return x > 0 ? 1 : 0; +} + +// This functor returns true if the input is greater than the given +// number. +class IsGreaterThan { + public: +  explicit IsGreaterThan(int threshold) : threshold_(threshold) {} + +  bool operator()(int n) const { return n > threshold_; } + private: +  const int threshold_; +}; + +// For testing Truly(). +const int foo = 0; + +// This predicate returns true iff the argument references foo and has +// a zero value. +bool ReferencesFooAndIsZero(const int& n) { +  return (&n == &foo) && (n == 0); +} + +// Tests that Truly(predicate) matches what satisfies the given +// predicate. +TEST(TrulyTest, MatchesWhatSatisfiesThePredicate) { +  Matcher<double> m = Truly(IsPositive); +  EXPECT_TRUE(m.Matches(2.0)); +  EXPECT_FALSE(m.Matches(-1.5)); +} + +// Tests that Truly(predicate_functor) works too. +TEST(TrulyTest, CanBeUsedWithFunctor) { +  Matcher<int> m = Truly(IsGreaterThan(5)); +  EXPECT_TRUE(m.Matches(6)); +  EXPECT_FALSE(m.Matches(4)); +} + +// Tests that Truly(predicate) can describe itself properly. +TEST(TrulyTest, CanDescribeSelf) { +  Matcher<double> m = Truly(IsPositive); +  EXPECT_EQ("satisfies the given predicate", +            Describe(m)); +} + +// Tests that Truly(predicate) works when the matcher takes its +// argument by reference. +TEST(TrulyTest, WorksForByRefArguments) { +  Matcher<const int&> m = Truly(ReferencesFooAndIsZero); +  EXPECT_TRUE(m.Matches(foo)); +  int n = 0; +  EXPECT_FALSE(m.Matches(n)); +} + +// Tests that Matches(m) is a predicate satisfied by whatever that +// matches matcher m. +TEST(MatchesTest, IsSatisfiedByWhatMatchesTheMatcher) { +  EXPECT_TRUE(Matches(Ge(0))(1)); +  EXPECT_FALSE(Matches(Eq('a'))('b')); +} + +// Tests that Matches(m) works when the matcher takes its argument by +// reference. +TEST(MatchesTest, WorksOnByRefArguments) { +  int m = 0, n = 0; +  EXPECT_TRUE(Matches(AllOf(Ref(n), Eq(0)))(n)); +  EXPECT_FALSE(Matches(Ref(m))(n)); +} + +// Tests that a Matcher on non-reference type can be used in +// Matches(). +TEST(MatchesTest, WorksWithMatcherOnNonRefType) { +  Matcher<int> eq5 = Eq(5); +  EXPECT_TRUE(Matches(eq5)(5)); +  EXPECT_FALSE(Matches(eq5)(2)); +} + +// Tests that ASSERT_THAT() and EXPECT_THAT() work when the value +// matches the matcher. +TEST(MatcherAssertionTest, WorksWhenMatcherIsSatisfied) { +  ASSERT_THAT(5, Ge(2)) << "This should succeed."; +  ASSERT_THAT("Foo", EndsWith("oo")); +  EXPECT_THAT(2, AllOf(Le(7), Ge(0))) << "This should succeed too."; +  EXPECT_THAT("Hello", StartsWith("Hell")); +} + +// Tests that ASSERT_THAT() and EXPECT_THAT() work when the value +// doesn't match the matcher. +TEST(MatcherAssertionTest, WorksWhenMatcherIsNotSatisfied) { +  // 'n' must be static as it is used in an EXPECT_FATAL_FAILURE(), +  // which cannot reference auto variables. +  static int n; +  n = 5; +  EXPECT_FATAL_FAILURE(ASSERT_THAT(n, Gt(10)) << "This should fail.", +                       "Value of: n\n" +                       "Expected: is greater than 10\n" +                       "  Actual: 5\n" +                       "This should fail."); +  n = 0; +  EXPECT_NONFATAL_FAILURE(EXPECT_THAT(n, AllOf(Le(7), Ge(5))), +                          "Value of: n\n" +                          "Expected: (is less than or equal to 7) and " +                          "(is greater than or equal to 5)\n" +                          "  Actual: 0"); +} + +// Tests that ASSERT_THAT() and EXPECT_THAT() work when the argument +// has a reference type. +TEST(MatcherAssertionTest, WorksForByRefArguments) { +  // We use a static variable here as EXPECT_FATAL_FAILURE() cannot +  // reference auto variables. +  static int n; +  n = 0; +  EXPECT_THAT(n, AllOf(Le(7), Ref(n))); +  EXPECT_FATAL_FAILURE(ASSERT_THAT(n, Not(Ref(n))), +                       "Value of: n\n" +                       "Expected: does not reference the variable @"); +  // Tests the "Actual" part. +  EXPECT_FATAL_FAILURE(ASSERT_THAT(n, Not(Ref(n))), +                       "Actual: 0 (is located @"); +} + +// Tests that ASSERT_THAT() and EXPECT_THAT() work when the matcher is +// monomorphic. +TEST(MatcherAssertionTest, WorksForMonomorphicMatcher) { +  Matcher<const char*> starts_with_he = StartsWith("he"); +  ASSERT_THAT("hello", starts_with_he); + +  Matcher<const string&> ends_with_ok = EndsWith("ok"); +  ASSERT_THAT("book", ends_with_ok); + +  Matcher<int> is_greater_than_5 = Gt(5); +  EXPECT_NONFATAL_FAILURE(EXPECT_THAT(5, is_greater_than_5), +                          "Value of: 5\n" +                          "Expected: is greater than 5\n" +                          "  Actual: 5"); +} + +// Tests floating-point matchers. +template <typename RawType> +class FloatingPointTest : public testing::Test { + protected: +  typedef typename testing::internal::FloatingPoint<RawType> Floating; +  typedef typename Floating::Bits Bits; + +  virtual void SetUp() { +    const size_t max_ulps = Floating::kMaxUlps; + +    // The bits that represent 0.0. +    const Bits zero_bits = Floating(0).bits(); + +    // Makes some numbers close to 0.0. +    close_to_positive_zero_ = Floating::ReinterpretBits(zero_bits + max_ulps/2); +    close_to_negative_zero_ = -Floating::ReinterpretBits( +        zero_bits + max_ulps - max_ulps/2); +    further_from_negative_zero_ = -Floating::ReinterpretBits( +        zero_bits + max_ulps + 1 - max_ulps/2); + +    // The bits that represent 1.0. +    const Bits one_bits = Floating(1).bits(); + +    // Makes some numbers close to 1.0. +    close_to_one_ = Floating::ReinterpretBits(one_bits + max_ulps); +    further_from_one_ = Floating::ReinterpretBits(one_bits + max_ulps + 1); + +    // +infinity. +    infinity_ = Floating::Infinity(); + +    // The bits that represent +infinity. +    const Bits infinity_bits = Floating(infinity_).bits(); + +    // Makes some numbers close to infinity. +    close_to_infinity_ = Floating::ReinterpretBits(infinity_bits - max_ulps); +    further_from_infinity_ = Floating::ReinterpretBits( +        infinity_bits - max_ulps - 1); + +    // Makes some NAN's. +    nan1_ = Floating::ReinterpretBits(Floating::kExponentBitMask | 1); +    nan2_ = Floating::ReinterpretBits(Floating::kExponentBitMask | 200); +  } + +  void TestSize() { +    EXPECT_EQ(sizeof(RawType), sizeof(Bits)); +  } + +  // A battery of tests for FloatingEqMatcher::Matches. +  // matcher_maker is a pointer to a function which creates a FloatingEqMatcher. +  void TestMatches( +      testing::internal::FloatingEqMatcher<RawType> (*matcher_maker)(RawType)) { +    Matcher<RawType> m1 = matcher_maker(0.0); +    EXPECT_TRUE(m1.Matches(-0.0)); +    EXPECT_TRUE(m1.Matches(close_to_positive_zero_)); +    EXPECT_TRUE(m1.Matches(close_to_negative_zero_)); +    EXPECT_FALSE(m1.Matches(1.0)); + +    Matcher<RawType> m2 = matcher_maker(close_to_positive_zero_); +    EXPECT_FALSE(m2.Matches(further_from_negative_zero_)); + +    Matcher<RawType> m3 = matcher_maker(1.0); +    EXPECT_TRUE(m3.Matches(close_to_one_)); +    EXPECT_FALSE(m3.Matches(further_from_one_)); + +    // Test commutativity: matcher_maker(0.0).Matches(1.0) was tested above. +    EXPECT_FALSE(m3.Matches(0.0)); + +    Matcher<RawType> m4 = matcher_maker(-infinity_); +    EXPECT_TRUE(m4.Matches(-close_to_infinity_)); + +    Matcher<RawType> m5 = matcher_maker(infinity_); +    EXPECT_TRUE(m5.Matches(close_to_infinity_)); + +    // This is interesting as the representations of infinity_ and nan1_ +    // are only 1 DLP apart. +    EXPECT_FALSE(m5.Matches(nan1_)); + +    // matcher_maker can produce a Matcher<const RawType&>, which is needed in +    // some cases. +    Matcher<const RawType&> m6 = matcher_maker(0.0); +    EXPECT_TRUE(m6.Matches(-0.0)); +    EXPECT_TRUE(m6.Matches(close_to_positive_zero_)); +    EXPECT_FALSE(m6.Matches(1.0)); + +    // matcher_maker can produce a Matcher<RawType&>, which is needed in some +    // cases. +    Matcher<RawType&> m7 = matcher_maker(0.0); +    RawType x = 0.0; +    EXPECT_TRUE(m7.Matches(x)); +    x = 0.01f; +    EXPECT_FALSE(m7.Matches(x)); +  } + +  // Pre-calculated numbers to be used by the tests. + +  static RawType close_to_positive_zero_; +  static RawType close_to_negative_zero_; +  static RawType further_from_negative_zero_; + +  static RawType close_to_one_; +  static RawType further_from_one_; + +  static RawType infinity_; +  static RawType close_to_infinity_; +  static RawType further_from_infinity_; + +  static RawType nan1_; +  static RawType nan2_; +}; + +template <typename RawType> +RawType FloatingPointTest<RawType>::close_to_positive_zero_; + +template <typename RawType> +RawType FloatingPointTest<RawType>::close_to_negative_zero_; + +template <typename RawType> +RawType FloatingPointTest<RawType>::further_from_negative_zero_; + +template <typename RawType> +RawType FloatingPointTest<RawType>::close_to_one_; + +template <typename RawType> +RawType FloatingPointTest<RawType>::further_from_one_; + +template <typename RawType> +RawType FloatingPointTest<RawType>::infinity_; + +template <typename RawType> +RawType FloatingPointTest<RawType>::close_to_infinity_; + +template <typename RawType> +RawType FloatingPointTest<RawType>::further_from_infinity_; + +template <typename RawType> +RawType FloatingPointTest<RawType>::nan1_; + +template <typename RawType> +RawType FloatingPointTest<RawType>::nan2_; + +// Instantiate FloatingPointTest for testing floats. +typedef FloatingPointTest<float> FloatTest; + +TEST_F(FloatTest, FloatEqApproximatelyMatchesFloats) { +  TestMatches(&FloatEq); +} + +TEST_F(FloatTest, NanSensitiveFloatEqApproximatelyMatchesFloats) { +  TestMatches(&NanSensitiveFloatEq); +} + +TEST_F(FloatTest, FloatEqCannotMatchNaN) { +  // FloatEq never matches NaN. +  Matcher<float> m = FloatEq(nan1_); +  EXPECT_FALSE(m.Matches(nan1_)); +  EXPECT_FALSE(m.Matches(nan2_)); +  EXPECT_FALSE(m.Matches(1.0)); +} + +TEST_F(FloatTest, NanSensitiveFloatEqCanMatchNaN) { +  // NanSensitiveFloatEq will match NaN. +  Matcher<float> m = NanSensitiveFloatEq(nan1_); +  EXPECT_TRUE(m.Matches(nan1_)); +  EXPECT_TRUE(m.Matches(nan2_)); +  EXPECT_FALSE(m.Matches(1.0)); +} + +TEST_F(FloatTest, FloatEqCanDescribeSelf) { +  Matcher<float> m1 = FloatEq(2.0f); +  EXPECT_EQ("is approximately 2", Describe(m1)); +  EXPECT_EQ("is not approximately 2", DescribeNegation(m1)); + +  Matcher<float> m2 = FloatEq(0.5f); +  EXPECT_EQ("is approximately 0.5", Describe(m2)); +  EXPECT_EQ("is not approximately 0.5", DescribeNegation(m2)); + +  Matcher<float> m3 = FloatEq(nan1_); +  EXPECT_EQ("never matches", Describe(m3)); +  EXPECT_EQ("is anything", DescribeNegation(m3)); +} + +TEST_F(FloatTest, NanSensitiveFloatEqCanDescribeSelf) { +  Matcher<float> m1 = NanSensitiveFloatEq(2.0f); +  EXPECT_EQ("is approximately 2", Describe(m1)); +  EXPECT_EQ("is not approximately 2", DescribeNegation(m1)); + +  Matcher<float> m2 = NanSensitiveFloatEq(0.5f); +  EXPECT_EQ("is approximately 0.5", Describe(m2)); +  EXPECT_EQ("is not approximately 0.5", DescribeNegation(m2)); + +  Matcher<float> m3 = NanSensitiveFloatEq(nan1_); +  EXPECT_EQ("is NaN", Describe(m3)); +  EXPECT_EQ("is not NaN", DescribeNegation(m3)); +} + +// Instantiate FloatingPointTest for testing doubles. +typedef FloatingPointTest<double> DoubleTest; + +TEST_F(DoubleTest, DoubleEqApproximatelyMatchesDoubles) { +  TestMatches(&DoubleEq); +} + +TEST_F(DoubleTest, NanSensitiveDoubleEqApproximatelyMatchesDoubles) { +  TestMatches(&NanSensitiveDoubleEq); +} + +TEST_F(DoubleTest, DoubleEqCannotMatchNaN) { +  // DoubleEq never matches NaN. +  Matcher<double> m = DoubleEq(nan1_); +  EXPECT_FALSE(m.Matches(nan1_)); +  EXPECT_FALSE(m.Matches(nan2_)); +  EXPECT_FALSE(m.Matches(1.0)); +} + +TEST_F(DoubleTest, NanSensitiveDoubleEqCanMatchNaN) { +  // NanSensitiveDoubleEq will match NaN. +  Matcher<double> m = NanSensitiveDoubleEq(nan1_); +  EXPECT_TRUE(m.Matches(nan1_)); +  EXPECT_TRUE(m.Matches(nan2_)); +  EXPECT_FALSE(m.Matches(1.0)); +} + +TEST_F(DoubleTest, DoubleEqCanDescribeSelf) { +  Matcher<double> m1 = DoubleEq(2.0); +  EXPECT_EQ("is approximately 2", Describe(m1)); +  EXPECT_EQ("is not approximately 2", DescribeNegation(m1)); + +  Matcher<double> m2 = DoubleEq(0.5); +  EXPECT_EQ("is approximately 0.5", Describe(m2)); +  EXPECT_EQ("is not approximately 0.5", DescribeNegation(m2)); + +  Matcher<double> m3 = DoubleEq(nan1_); +  EXPECT_EQ("never matches", Describe(m3)); +  EXPECT_EQ("is anything", DescribeNegation(m3)); +} + +TEST_F(DoubleTest, NanSensitiveDoubleEqCanDescribeSelf) { +  Matcher<double> m1 = NanSensitiveDoubleEq(2.0); +  EXPECT_EQ("is approximately 2", Describe(m1)); +  EXPECT_EQ("is not approximately 2", DescribeNegation(m1)); + +  Matcher<double> m2 = NanSensitiveDoubleEq(0.5); +  EXPECT_EQ("is approximately 0.5", Describe(m2)); +  EXPECT_EQ("is not approximately 0.5", DescribeNegation(m2)); + +  Matcher<double> m3 = NanSensitiveDoubleEq(nan1_); +  EXPECT_EQ("is NaN", Describe(m3)); +  EXPECT_EQ("is not NaN", DescribeNegation(m3)); +} + +TEST(PointeeTest, RawPointer) { +  const Matcher<int*> m = Pointee(Ge(0)); + +  int n = 1; +  EXPECT_TRUE(m.Matches(&n)); +  n = -1; +  EXPECT_FALSE(m.Matches(&n)); +  EXPECT_FALSE(m.Matches(NULL)); +} + +TEST(PointeeTest, RawPointerToConst) { +  const Matcher<const double*> m = Pointee(Ge(0)); + +  double x = 1; +  EXPECT_TRUE(m.Matches(&x)); +  x = -1; +  EXPECT_FALSE(m.Matches(&x)); +  EXPECT_FALSE(m.Matches(NULL)); +} + +TEST(PointeeTest, ReferenceToConstRawPointer) { +  const Matcher<int* const &> m = Pointee(Ge(0)); + +  int n = 1; +  EXPECT_TRUE(m.Matches(&n)); +  n = -1; +  EXPECT_FALSE(m.Matches(&n)); +  EXPECT_FALSE(m.Matches(NULL)); +} + +TEST(PointeeTest, ReferenceToNonConstRawPointer) { +  const Matcher<double* &> m = Pointee(Ge(0)); + +  double x = 1.0; +  double* p = &x; +  EXPECT_TRUE(m.Matches(p)); +  x = -1; +  EXPECT_FALSE(m.Matches(p)); +  p = NULL; +  EXPECT_FALSE(m.Matches(p)); +} + +TEST(PointeeTest, NeverMatchesNull) { +  const Matcher<const char*> m = Pointee(_); +  EXPECT_FALSE(m.Matches(NULL)); +} + +// Tests that we can write Pointee(value) instead of Pointee(Eq(value)). +TEST(PointeeTest, MatchesAgainstAValue) { +  const Matcher<int*> m = Pointee(5); + +  int n = 5; +  EXPECT_TRUE(m.Matches(&n)); +  n = -1; +  EXPECT_FALSE(m.Matches(&n)); +  EXPECT_FALSE(m.Matches(NULL)); +} + +TEST(PointeeTest, CanDescribeSelf) { +  const Matcher<int*> m = Pointee(Gt(3)); +  EXPECT_EQ("points to a value that is greater than 3", Describe(m)); +  EXPECT_EQ("does not point to a value that is greater than 3", +            DescribeNegation(m)); +} + +// For testing ExplainMatchResultTo(). +class GreaterThanMatcher : public MatcherInterface<int> { + public: +  explicit GreaterThanMatcher(int rhs) : rhs_(rhs) {} + +  virtual bool Matches(int lhs) const { return lhs > rhs_; } + +  virtual void DescribeTo(::std::ostream* os) const { +    *os << "is greater than " << rhs_; +  } + +  virtual void ExplainMatchResultTo(int lhs, ::std::ostream* os) const { +    const int diff = lhs - rhs_; +    if (diff > 0) { +      *os << "is " << diff << " more than " << rhs_; +    } else if (diff == 0) { +      *os << "is the same as " << rhs_; +    } else { +      *os << "is " << -diff << " less than " << rhs_; +    } +  } + private: +  const int rhs_; +}; + +Matcher<int> GreaterThan(int n) { +  return MakeMatcher(new GreaterThanMatcher(n)); +} + +TEST(PointeeTest, CanExplainMatchResult) { +  const Matcher<const string*> m = Pointee(StartsWith("Hi")); + +  EXPECT_EQ("", Explain(m, static_cast<const string*>(NULL))); + +  const Matcher<int*> m2 = Pointee(GreaterThan(1)); +  int n = 3; +  EXPECT_EQ("points to a value that is 2 more than 1", Explain(m2, &n)); +} + +// An uncopyable class. +class Uncopyable { + public: +  explicit Uncopyable(int value) : value_(value) {} + +  int value() const { return value_; } + private: +  const int value_; +  GTEST_DISALLOW_COPY_AND_ASSIGN_(Uncopyable); +}; + +// Returns true iff x.value() is positive. +bool ValueIsPositive(const Uncopyable& x) { return x.value() > 0; } + +// A user-defined struct for testing Field(). +struct AStruct { +  AStruct() : x(0), y(1.0), z(5), p(NULL) {} +  AStruct(const AStruct& rhs) +      : x(rhs.x), y(rhs.y), z(rhs.z.value()), p(rhs.p) {} + +  int x;           // A non-const field. +  const double y;  // A const field. +  Uncopyable z;    // An uncopyable field. +  const char* p;   // A pointer field. +}; + +// A derived struct for testing Field(). +struct DerivedStruct : public AStruct { +  char ch; +}; + +// Tests that Field(&Foo::field, ...) works when field is non-const. +TEST(FieldTest, WorksForNonConstField) { +  Matcher<AStruct> m = Field(&AStruct::x, Ge(0)); + +  AStruct a; +  EXPECT_TRUE(m.Matches(a)); +  a.x = -1; +  EXPECT_FALSE(m.Matches(a)); +} + +// Tests that Field(&Foo::field, ...) works when field is const. +TEST(FieldTest, WorksForConstField) { +  AStruct a; + +  Matcher<AStruct> m = Field(&AStruct::y, Ge(0.0)); +  EXPECT_TRUE(m.Matches(a)); +  m = Field(&AStruct::y, Le(0.0)); +  EXPECT_FALSE(m.Matches(a)); +} + +// Tests that Field(&Foo::field, ...) works when field is not copyable. +TEST(FieldTest, WorksForUncopyableField) { +  AStruct a; + +  Matcher<AStruct> m = Field(&AStruct::z, Truly(ValueIsPositive)); +  EXPECT_TRUE(m.Matches(a)); +  m = Field(&AStruct::z, Not(Truly(ValueIsPositive))); +  EXPECT_FALSE(m.Matches(a)); +} + +// Tests that Field(&Foo::field, ...) works when field is a pointer. +TEST(FieldTest, WorksForPointerField) { +  // Matching against NULL. +  Matcher<AStruct> m = Field(&AStruct::p, static_cast<const char*>(NULL)); +  AStruct a; +  EXPECT_TRUE(m.Matches(a)); +  a.p = "hi"; +  EXPECT_FALSE(m.Matches(a)); + +  // Matching a pointer that is not NULL. +  m = Field(&AStruct::p, StartsWith("hi")); +  a.p = "hill"; +  EXPECT_TRUE(m.Matches(a)); +  a.p = "hole"; +  EXPECT_FALSE(m.Matches(a)); +} + +// Tests that Field() works when the object is passed by reference. +TEST(FieldTest, WorksForByRefArgument) { +  Matcher<const AStruct&> m = Field(&AStruct::x, Ge(0)); + +  AStruct a; +  EXPECT_TRUE(m.Matches(a)); +  a.x = -1; +  EXPECT_FALSE(m.Matches(a)); +} + +// Tests that Field(&Foo::field, ...) works when the argument's type +// is a sub-type of Foo. +TEST(FieldTest, WorksForArgumentOfSubType) { +  // Note that the matcher expects DerivedStruct but we say AStruct +  // inside Field(). +  Matcher<const DerivedStruct&> m = Field(&AStruct::x, Ge(0)); + +  DerivedStruct d; +  EXPECT_TRUE(m.Matches(d)); +  d.x = -1; +  EXPECT_FALSE(m.Matches(d)); +} + +// Tests that Field(&Foo::field, m) works when field's type and m's +// argument type are compatible but not the same. +TEST(FieldTest, WorksForCompatibleMatcherType) { +  // The field is an int, but the inner matcher expects a signed char. +  Matcher<const AStruct&> m = Field(&AStruct::x, +                                    Matcher<signed char>(Ge(0))); + +  AStruct a; +  EXPECT_TRUE(m.Matches(a)); +  a.x = -1; +  EXPECT_FALSE(m.Matches(a)); +} + +// Tests that Field() can describe itself. +TEST(FieldTest, CanDescribeSelf) { +  Matcher<const AStruct&> m = Field(&AStruct::x, Ge(0)); + +  EXPECT_EQ("the given field is greater than or equal to 0", Describe(m)); +  EXPECT_EQ("the given field is not greater than or equal to 0", +            DescribeNegation(m)); +} + +// Tests that Field() can explain the match result. +TEST(FieldTest, CanExplainMatchResult) { +  Matcher<const AStruct&> m = Field(&AStruct::x, Ge(0)); + +  AStruct a; +  a.x = 1; +  EXPECT_EQ("", Explain(m, a)); + +  m = Field(&AStruct::x, GreaterThan(0)); +  EXPECT_EQ("the given field is 1 more than 0", Explain(m, a)); +} + +// Tests that Field() works when the argument is a pointer to const. +TEST(FieldForPointerTest, WorksForPointerToConst) { +  Matcher<const AStruct*> m = Field(&AStruct::x, Ge(0)); + +  AStruct a; +  EXPECT_TRUE(m.Matches(&a)); +  a.x = -1; +  EXPECT_FALSE(m.Matches(&a)); +} + +// Tests that Field() works when the argument is a pointer to non-const. +TEST(FieldForPointerTest, WorksForPointerToNonConst) { +  Matcher<AStruct*> m = Field(&AStruct::x, Ge(0)); + +  AStruct a; +  EXPECT_TRUE(m.Matches(&a)); +  a.x = -1; +  EXPECT_FALSE(m.Matches(&a)); +} + +// Tests that Field() does not match the NULL pointer. +TEST(FieldForPointerTest, DoesNotMatchNull) { +  Matcher<const AStruct*> m = Field(&AStruct::x, _); +  EXPECT_FALSE(m.Matches(NULL)); +} + +// Tests that Field(&Foo::field, ...) works when the argument's type +// is a sub-type of const Foo*. +TEST(FieldForPointerTest, WorksForArgumentOfSubType) { +  // Note that the matcher expects DerivedStruct but we say AStruct +  // inside Field(). +  Matcher<DerivedStruct*> m = Field(&AStruct::x, Ge(0)); + +  DerivedStruct d; +  EXPECT_TRUE(m.Matches(&d)); +  d.x = -1; +  EXPECT_FALSE(m.Matches(&d)); +} + +// Tests that Field() can describe itself when used to match a pointer. +TEST(FieldForPointerTest, CanDescribeSelf) { +  Matcher<const AStruct*> m = Field(&AStruct::x, Ge(0)); + +  EXPECT_EQ("the given field is greater than or equal to 0", Describe(m)); +  EXPECT_EQ("the given field is not greater than or equal to 0", +            DescribeNegation(m)); +} + +// Tests that Field() can explain the result of matching a pointer. +TEST(FieldForPointerTest, CanExplainMatchResult) { +  Matcher<const AStruct*> m = Field(&AStruct::x, Ge(0)); + +  AStruct a; +  a.x = 1; +  EXPECT_EQ("", Explain(m, static_cast<const AStruct*>(NULL))); +  EXPECT_EQ("", Explain(m, &a)); + +  m = Field(&AStruct::x, GreaterThan(0)); +  EXPECT_EQ("the given field is 1 more than 0", Explain(m, &a)); +} + +// A user-defined class for testing Property(). +class AClass { + public: +  AClass() : n_(0) {} + +  // A getter that returns a non-reference. +  int n() const { return n_; } + +  void set_n(int new_n) { n_ = new_n; } + +  // A getter that returns a reference to const. +  const string& s() const { return s_; } + +  void set_s(const string& new_s) { s_ = new_s; } + +  // A getter that returns a reference to non-const. +  double& x() const { return x_; } + private: +  int n_; +  string s_; + +  static double x_; +}; + +double AClass::x_ = 0.0; + +// A derived class for testing Property(). +class DerivedClass : public AClass { + private: +  int k_; +}; + +// Tests that Property(&Foo::property, ...) works when property() +// returns a non-reference. +TEST(PropertyTest, WorksForNonReferenceProperty) { +  Matcher<const AClass&> m = Property(&AClass::n, Ge(0)); + +  AClass a; +  a.set_n(1); +  EXPECT_TRUE(m.Matches(a)); + +  a.set_n(-1); +  EXPECT_FALSE(m.Matches(a)); +} + +// Tests that Property(&Foo::property, ...) works when property() +// returns a reference to const. +TEST(PropertyTest, WorksForReferenceToConstProperty) { +  Matcher<const AClass&> m = Property(&AClass::s, StartsWith("hi")); + +  AClass a; +  a.set_s("hill"); +  EXPECT_TRUE(m.Matches(a)); + +  a.set_s("hole"); +  EXPECT_FALSE(m.Matches(a)); +} + +// Tests that Property(&Foo::property, ...) works when property() +// returns a reference to non-const. +TEST(PropertyTest, WorksForReferenceToNonConstProperty) { +  double x = 0.0; +  AClass a; + +  Matcher<const AClass&> m = Property(&AClass::x, Ref(x)); +  EXPECT_FALSE(m.Matches(a)); + +  m = Property(&AClass::x, Not(Ref(x))); +  EXPECT_TRUE(m.Matches(a)); +} + +// Tests that Property(&Foo::property, ...) works when the argument is +// passed by value. +TEST(PropertyTest, WorksForByValueArgument) { +  Matcher<AClass> m = Property(&AClass::s, StartsWith("hi")); + +  AClass a; +  a.set_s("hill"); +  EXPECT_TRUE(m.Matches(a)); + +  a.set_s("hole"); +  EXPECT_FALSE(m.Matches(a)); +} + +// Tests that Property(&Foo::property, ...) works when the argument's +// type is a sub-type of Foo. +TEST(PropertyTest, WorksForArgumentOfSubType) { +  // The matcher expects a DerivedClass, but inside the Property() we +  // say AClass. +  Matcher<const DerivedClass&> m = Property(&AClass::n, Ge(0)); + +  DerivedClass d; +  d.set_n(1); +  EXPECT_TRUE(m.Matches(d)); + +  d.set_n(-1); +  EXPECT_FALSE(m.Matches(d)); +} + +// Tests that Property(&Foo::property, m) works when property()'s type +// and m's argument type are compatible but different. +TEST(PropertyTest, WorksForCompatibleMatcherType) { +  // n() returns an int but the inner matcher expects a signed char. +  Matcher<const AClass&> m = Property(&AClass::n, +                                      Matcher<signed char>(Ge(0))); + +  AClass a; +  EXPECT_TRUE(m.Matches(a)); +  a.set_n(-1); +  EXPECT_FALSE(m.Matches(a)); +} + +// Tests that Property() can describe itself. +TEST(PropertyTest, CanDescribeSelf) { +  Matcher<const AClass&> m = Property(&AClass::n, Ge(0)); + +  EXPECT_EQ("the given property is greater than or equal to 0", Describe(m)); +  EXPECT_EQ("the given property is not greater than or equal to 0", +            DescribeNegation(m)); +} + +// Tests that Property() can explain the match result. +TEST(PropertyTest, CanExplainMatchResult) { +  Matcher<const AClass&> m = Property(&AClass::n, Ge(0)); + +  AClass a; +  a.set_n(1); +  EXPECT_EQ("", Explain(m, a)); + +  m = Property(&AClass::n, GreaterThan(0)); +  EXPECT_EQ("the given property is 1 more than 0", Explain(m, a)); +} + +// Tests that Property() works when the argument is a pointer to const. +TEST(PropertyForPointerTest, WorksForPointerToConst) { +  Matcher<const AClass*> m = Property(&AClass::n, Ge(0)); + +  AClass a; +  a.set_n(1); +  EXPECT_TRUE(m.Matches(&a)); + +  a.set_n(-1); +  EXPECT_FALSE(m.Matches(&a)); +} + +// Tests that Property() works when the argument is a pointer to non-const. +TEST(PropertyForPointerTest, WorksForPointerToNonConst) { +  Matcher<AClass*> m = Property(&AClass::s, StartsWith("hi")); + +  AClass a; +  a.set_s("hill"); +  EXPECT_TRUE(m.Matches(&a)); + +  a.set_s("hole"); +  EXPECT_FALSE(m.Matches(&a)); +} + +// Tests that Property() does not match the NULL pointer. +TEST(PropertyForPointerTest, WorksForReferenceToNonConstProperty) { +  Matcher<const AClass*> m = Property(&AClass::x, _); +  EXPECT_FALSE(m.Matches(NULL)); +} + +// Tests that Property(&Foo::property, ...) works when the argument's +// type is a sub-type of const Foo*. +TEST(PropertyForPointerTest, WorksForArgumentOfSubType) { +  // The matcher expects a DerivedClass, but inside the Property() we +  // say AClass. +  Matcher<const DerivedClass*> m = Property(&AClass::n, Ge(0)); + +  DerivedClass d; +  d.set_n(1); +  EXPECT_TRUE(m.Matches(&d)); + +  d.set_n(-1); +  EXPECT_FALSE(m.Matches(&d)); +} + +// Tests that Property() can describe itself when used to match a pointer. +TEST(PropertyForPointerTest, CanDescribeSelf) { +  Matcher<const AClass*> m = Property(&AClass::n, Ge(0)); + +  EXPECT_EQ("the given property is greater than or equal to 0", Describe(m)); +  EXPECT_EQ("the given property is not greater than or equal to 0", +            DescribeNegation(m)); +} + +// Tests that Property() can explain the result of matching a pointer. +TEST(PropertyForPointerTest, CanExplainMatchResult) { +  Matcher<const AClass*> m = Property(&AClass::n, Ge(0)); + +  AClass a; +  a.set_n(1); +  EXPECT_EQ("", Explain(m, static_cast<const AClass*>(NULL))); +  EXPECT_EQ("", Explain(m, &a)); + +  m = Property(&AClass::n, GreaterThan(0)); +  EXPECT_EQ("the given property is 1 more than 0", Explain(m, &a)); +} + +// Tests ResultOf. + +// Tests that ResultOf(f, ...) compiles and works as expected when f is a +// function pointer. +string IntToStringFunction(int input) { return input == 1 ? "foo" : "bar"; } + +TEST(ResultOfTest, WorksForFunctionPointers) { +  Matcher<int> matcher = ResultOf(&IntToStringFunction, Eq(string("foo"))); + +  EXPECT_TRUE(matcher.Matches(1)); +  EXPECT_FALSE(matcher.Matches(2)); +} + +// Tests that ResultOf() can describe itself. +TEST(ResultOfTest, CanDescribeItself) { +  Matcher<int> matcher = ResultOf(&IntToStringFunction, StrEq("foo")); + +  EXPECT_EQ("result of the given callable is equal to \"foo\"", +            Describe(matcher)); +  EXPECT_EQ("result of the given callable is not equal to \"foo\"", +            DescribeNegation(matcher)); +} + +// Tests that ResultOf() can explain the match result. +int IntFunction(int input) { return input == 42 ? 80 : 90; } + +TEST(ResultOfTest, CanExplainMatchResult) { +  Matcher<int> matcher = ResultOf(&IntFunction, Ge(85)); +  EXPECT_EQ("", Explain(matcher, 36)); + +  matcher = ResultOf(&IntFunction, GreaterThan(85)); +  EXPECT_EQ("result of the given callable is 5 more than 85", +            Explain(matcher, 36)); +} + +// Tests that ResultOf(f, ...) compiles and works as expected when f(x) +// returns a non-reference. +TEST(ResultOfTest, WorksForNonReferenceResults) { +  Matcher<int> matcher = ResultOf(&IntFunction, Eq(80)); + +  EXPECT_TRUE(matcher.Matches(42)); +  EXPECT_FALSE(matcher.Matches(36)); +} + +// Tests that ResultOf(f, ...) compiles and works as expected when f(x) +// returns a reference to non-const. +double& DoubleFunction(double& input) { return input; } + +Uncopyable& RefUncopyableFunction(Uncopyable& obj) { +  return obj; +} + +TEST(ResultOfTest, WorksForReferenceToNonConstResults) { +  double x = 3.14; +  double x2 = x; +  Matcher<double&> matcher = ResultOf(&DoubleFunction, Ref(x)); + +  EXPECT_TRUE(matcher.Matches(x)); +  EXPECT_FALSE(matcher.Matches(x2)); + +  // Test that ResultOf works with uncopyable objects +  Uncopyable obj(0); +  Uncopyable obj2(0); +  Matcher<Uncopyable&> matcher2 = +      ResultOf(&RefUncopyableFunction, Ref(obj)); + +  EXPECT_TRUE(matcher2.Matches(obj)); +  EXPECT_FALSE(matcher2.Matches(obj2)); +} + +// Tests that ResultOf(f, ...) compiles and works as expected when f(x) +// returns a reference to const. +const string& StringFunction(const string& input) { return input; } + +TEST(ResultOfTest, WorksForReferenceToConstResults) { +  string s = "foo"; +  string s2 = s; +  Matcher<const string&> matcher = ResultOf(&StringFunction, Ref(s)); + +  EXPECT_TRUE(matcher.Matches(s)); +  EXPECT_FALSE(matcher.Matches(s2)); +} + +// Tests that ResultOf(f, m) works when f(x) and m's +// argument types are compatible but different. +TEST(ResultOfTest, WorksForCompatibleMatcherTypes) { +  // IntFunction() returns int but the inner matcher expects a signed char. +  Matcher<int> matcher = ResultOf(IntFunction, Matcher<signed char>(Ge(85))); + +  EXPECT_TRUE(matcher.Matches(36)); +  EXPECT_FALSE(matcher.Matches(42)); +} + +#ifdef GTEST_HAS_DEATH_TEST +// Tests that the program aborts when ResultOf is passed +// a NULL function pointer. +TEST(ResultOfDeathTest, DiesOnNullFunctionPointers) { +  EXPECT_DEATH( +      ResultOf(static_cast<string(*)(int)>(NULL), Eq(string("foo"))), +               "NULL function pointer is passed into ResultOf\\(\\)\\."); +} +#endif  // GTEST_HAS_DEATH_TEST + +// Tests that ResultOf(f, ...) compiles and works as expected when f is a +// function reference. +TEST(ResultOfTest, WorksForFunctionReferences) { +  Matcher<int> matcher = ResultOf(IntToStringFunction, StrEq("foo")); +  EXPECT_TRUE(matcher.Matches(1)); +  EXPECT_FALSE(matcher.Matches(2)); +} + +// Tests that ResultOf(f, ...) compiles and works as expected when f is a +// function object. +struct Functor : public ::std::unary_function<int, string> { +  result_type operator()(argument_type input) const { +    return IntToStringFunction(input); +  } +}; + +TEST(ResultOfTest, WorksForFunctors) { +  Matcher<int> matcher = ResultOf(Functor(), Eq(string("foo"))); + +  EXPECT_TRUE(matcher.Matches(1)); +  EXPECT_FALSE(matcher.Matches(2)); +} + +// Tests that ResultOf(f, ...) compiles and works as expected when f is a +// functor with more then one operator() defined. ResultOf() must work +// for each defined operator(). +struct PolymorphicFunctor { +  typedef int result_type; +  int operator()(int n) { return n; } +  int operator()(const char* s) { return static_cast<int>(strlen(s)); } +}; + +TEST(ResultOfTest, WorksForPolymorphicFunctors) { +  Matcher<int> matcher_int = ResultOf(PolymorphicFunctor(), Ge(5)); + +  EXPECT_TRUE(matcher_int.Matches(10)); +  EXPECT_FALSE(matcher_int.Matches(2)); + +  Matcher<const char*> matcher_string = ResultOf(PolymorphicFunctor(), Ge(5)); + +  EXPECT_TRUE(matcher_string.Matches("long string")); +  EXPECT_FALSE(matcher_string.Matches("shrt")); +} + +const int* ReferencingFunction(const int& n) { return &n; } + +struct ReferencingFunctor { +  typedef const int* result_type; +  result_type operator()(const int& n) { return &n; } +}; + +TEST(ResultOfTest, WorksForReferencingCallables) { +  const int n = 1; +  const int n2 = 1; +  Matcher<const int&> matcher2 = ResultOf(ReferencingFunction, Eq(&n)); +  EXPECT_TRUE(matcher2.Matches(n)); +  EXPECT_FALSE(matcher2.Matches(n2)); + +  Matcher<const int&> matcher3 = ResultOf(ReferencingFunctor(), Eq(&n)); +  EXPECT_TRUE(matcher3.Matches(n)); +  EXPECT_FALSE(matcher3.Matches(n2)); +} + + +class DivisibleByImpl { + public: +  explicit DivisibleByImpl(int divider) : divider_(divider) {} + +  template <typename T> +  bool Matches(const T& n) const { +    return (n % divider_) == 0; +  } + +  void DescribeTo(::std::ostream* os) const { +    *os << "is divisible by " << divider_; +  } + +  void DescribeNegationTo(::std::ostream* os) const { +    *os << "is not divisible by " << divider_; +  } + +  int divider() const { return divider_; } + private: +  const int divider_; +}; + +// For testing using ExplainMatchResultTo() with polymorphic matchers. +template <typename T> +void ExplainMatchResultTo(const DivisibleByImpl& impl, const T& n, +                          ::std::ostream* os) { +  *os << "is " << (n % impl.divider()) << " modulo " +      << impl.divider(); +} + +PolymorphicMatcher<DivisibleByImpl> DivisibleBy(int n) { +  return MakePolymorphicMatcher(DivisibleByImpl(n)); +} + +// Tests that when AllOf() fails, only the first failing matcher is +// asked to explain why. +TEST(ExplainMatchResultTest, AllOf_False_False) { +  const Matcher<int> m = AllOf(DivisibleBy(4), DivisibleBy(3)); +  EXPECT_EQ("is 1 modulo 4", Explain(m, 5)); +} + +// Tests that when AllOf() fails, only the first failing matcher is +// asked to explain why. +TEST(ExplainMatchResultTest, AllOf_False_True) { +  const Matcher<int> m = AllOf(DivisibleBy(4), DivisibleBy(3)); +  EXPECT_EQ("is 2 modulo 4", Explain(m, 6)); +} + +// Tests that when AllOf() fails, only the first failing matcher is +// asked to explain why. +TEST(ExplainMatchResultTest, AllOf_True_False) { +  const Matcher<int> m = AllOf(Ge(1), DivisibleBy(3)); +  EXPECT_EQ("is 2 modulo 3", Explain(m, 5)); +} + +// Tests that when AllOf() succeeds, all matchers are asked to explain +// why. +TEST(ExplainMatchResultTest, AllOf_True_True) { +  const Matcher<int> m = AllOf(DivisibleBy(2), DivisibleBy(3)); +  EXPECT_EQ("is 0 modulo 2; is 0 modulo 3", Explain(m, 6)); +} + +TEST(ExplainMatchResultTest, AllOf_True_True_2) { +  const Matcher<int> m = AllOf(Ge(2), Le(3)); +  EXPECT_EQ("", Explain(m, 2)); +} + +TEST(ExplainmatcherResultTest, MonomorphicMatcher) { +  const Matcher<int> m = GreaterThan(5); +  EXPECT_EQ("is 1 more than 5", Explain(m, 6)); +} + +// The following two tests verify that values without a public copy +// ctor can be used as arguments to matchers like Eq(), Ge(), and etc +// with the help of ByRef(). + +class NotCopyable { + public: +  explicit NotCopyable(int value) : value_(value) {} + +  int value() const { return value_; } + +  bool operator==(const NotCopyable& rhs) const { +    return value() == rhs.value(); +  } + +  bool operator>=(const NotCopyable& rhs) const { +    return value() >= rhs.value(); +  } + private: +  int value_; + +  GTEST_DISALLOW_COPY_AND_ASSIGN_(NotCopyable); +}; + +TEST(ByRefTest, AllowsNotCopyableConstValueInMatchers) { +  const NotCopyable const_value1(1); +  const Matcher<const NotCopyable&> m = Eq(ByRef(const_value1)); + +  const NotCopyable n1(1), n2(2); +  EXPECT_TRUE(m.Matches(n1)); +  EXPECT_FALSE(m.Matches(n2)); +} + +TEST(ByRefTest, AllowsNotCopyableValueInMatchers) { +  NotCopyable value2(2); +  const Matcher<NotCopyable&> m = Ge(ByRef(value2)); + +  NotCopyable n1(1), n2(2); +  EXPECT_FALSE(m.Matches(n1)); +  EXPECT_TRUE(m.Matches(n2)); +} + +}  // namespace gmock_matchers_test +}  // namespace testing diff --git a/test/gmock-nice-strict_test.cc b/test/gmock-nice-strict_test.cc new file mode 100644 index 00000000..955961c5 --- /dev/null +++ b/test/gmock-nice-strict_test.cc @@ -0,0 +1,228 @@ +// 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. +// +// Author: wan@google.com (Zhanyong Wan) + +#include <gmock/gmock-generated-nice-strict.h> + +#include <string> +#include <gmock/gmock.h> +#include <gtest/gtest.h> +#include <gtest/gtest-spi.h> + +namespace testing { +namespace gmock_nice_strict_test { + +using testing::internal::string; +using testing::GMOCK_FLAG(verbose); +using testing::HasSubstr; +using testing::NiceMock; +using testing::StrictMock; + +// Defines some mock classes needed by the tests. + +class Foo { + public: +  virtual ~Foo() {} + +  virtual void DoThis() = 0; +  virtual int DoThat(bool flag) = 0; +}; + +class MockFoo : public Foo { + public: +  void Delete() { delete this; } + +  MOCK_METHOD0(DoThis, void()); +  MOCK_METHOD1(DoThat, int(bool flag)); +}; + +class MockBar { + public: +  explicit MockBar(const string& s) : str_(s) {} + +  MockBar(char a1, char a2, string a3, string a4, int a5, int a6, +          const string& a7, const string& a8, bool a9, bool a10) { +    str_ = string() + a1 + a2 + a3 + a4 + static_cast<char>(a5) + +        static_cast<char>(a6) + a7 + a8 + (a9 ? 'T' : 'F') + (a10 ? 'T' : 'F'); +  } + +  virtual ~MockBar() {} + +  const string& str() const { return str_; } + +  MOCK_METHOD0(This, int()); +  MOCK_METHOD2(That, string(int, bool)); + + private: +  string str_; +}; + +// TODO(wan@google.com): find a way to re-enable these tests. +#if 0 + +// Tests that a nice mock generates no warning for uninteresting calls. +TEST(NiceMockTest, NoWarningForUninterestingCall) { +  NiceMock<MockFoo> nice_foo; + +  CaptureTestStdout(); +  nice_foo.DoThis(); +  nice_foo.DoThat(true); +  EXPECT_EQ("", GetCapturedTestStdout()); +} + +// Tests that a nice mock generates no warning for uninteresting calls +// that delete the mock object. +TEST(NiceMockTest, NoWarningForUninterestingCallAfterDeath) { +  NiceMock<MockFoo>* const nice_foo = new NiceMock<MockFoo>; + +  ON_CALL(*nice_foo, DoThis()) +      .WillByDefault(Invoke(nice_foo, &MockFoo::Delete)); + +  CaptureTestStdout(); +  nice_foo->DoThis(); +  EXPECT_EQ("", GetCapturedTestStdout()); +} + +// Tests that a nice mock generates informational logs for +// uninteresting calls. +TEST(NiceMockTest, InfoForUninterestingCall) { +  NiceMock<MockFoo> nice_foo; + +  GMOCK_FLAG(verbose) = "info"; +  CaptureTestStdout(); +  nice_foo.DoThis(); +  EXPECT_THAT(GetCapturedTestStdout(), +              HasSubstr("Uninteresting mock function call")); + +  CaptureTestStdout(); +  nice_foo.DoThat(true); +  EXPECT_THAT(GetCapturedTestStdout(), +              HasSubstr("Uninteresting mock function call")); +} + +#endif  // 0 + +// Tests that a nice mock allows expected calls. +TEST(NiceMockTest, AllowsExpectedCall) { +  NiceMock<MockFoo> nice_foo; + +  EXPECT_CALL(nice_foo, DoThis()); +  nice_foo.DoThis(); +} + +// Tests that an unexpected call on a nice mock fails. +TEST(NiceMockTest, UnexpectedCallFails) { +  NiceMock<MockFoo> nice_foo; + +  EXPECT_CALL(nice_foo, DoThis()).Times(0); +  EXPECT_NONFATAL_FAILURE(nice_foo.DoThis(), "called more times than expected"); +} + +// Tests that NiceMock works with a mock class that has a non-default +// constructor. +TEST(NiceMockTest, NonDefaultConstructor) { +  NiceMock<MockBar> nice_bar("hi"); +  EXPECT_EQ("hi", nice_bar.str()); + +  nice_bar.This(); +  nice_bar.That(5, true); +} + +// Tests that NiceMock works with a mock class that has a 10-ary +// non-default constructor. +TEST(NiceMockTest, NonDefaultConstructor10) { +  NiceMock<MockBar> nice_bar('a', 'b', "c", "d", 'e', 'f', +                             "g", "h", true, false); +  EXPECT_EQ("abcdefghTF", nice_bar.str()); + +  nice_bar.This(); +  nice_bar.That(5, true); +} + +// Tests that a strict mock allows expected calls. +TEST(StrictMockTest, AllowsExpectedCall) { +  StrictMock<MockFoo> strict_foo; + +  EXPECT_CALL(strict_foo, DoThis()); +  strict_foo.DoThis(); +} + +// Tests that an unexpected call on a strict mock fails. +TEST(StrictMockTest, UnexpectedCallFails) { +  StrictMock<MockFoo> strict_foo; + +  EXPECT_CALL(strict_foo, DoThis()).Times(0); +  EXPECT_NONFATAL_FAILURE(strict_foo.DoThis(), +                          "called more times than expected"); +} + +// Tests that an uninteresting call on a strict mock fails. +TEST(StrictMockTest, UninterestingCallFails) { +  StrictMock<MockFoo> strict_foo; + +  EXPECT_NONFATAL_FAILURE(strict_foo.DoThis(), +                          "Uninteresting mock function call"); +} + +// Tests that an uninteresting call on a strict mock fails, even if +// the call deletes the mock object. +TEST(StrictMockTest, UninterestingCallFailsAfterDeath) { +  StrictMock<MockFoo>* const strict_foo = new StrictMock<MockFoo>; + +  ON_CALL(*strict_foo, DoThis()) +      .WillByDefault(Invoke(strict_foo, &MockFoo::Delete)); + +  EXPECT_NONFATAL_FAILURE(strict_foo->DoThis(), +                          "Uninteresting mock function call"); +} + +// Tests that StrictMock works with a mock class that has a +// non-default constructor. +TEST(StrictMockTest, NonDefaultConstructor) { +  StrictMock<MockBar> strict_bar("hi"); +  EXPECT_EQ("hi", strict_bar.str()); + +  EXPECT_NONFATAL_FAILURE(strict_bar.That(5, true), +                          "Uninteresting mock function call"); +} + +// Tests that StrictMock works with a mock class that has a 10-ary +// non-default constructor. +TEST(StrictMockTest, NonDefaultConstructor10) { +  StrictMock<MockBar> strict_bar('a', 'b', "c", "d", 'e', 'f', +                                 "g", "h", true, false); +  EXPECT_EQ("abcdefghTF", strict_bar.str()); + +  EXPECT_NONFATAL_FAILURE(strict_bar.That(5, true), +                          "Uninteresting mock function call"); +} + +}  // namespace gmock_nice_strict_test +}  // namespace testing diff --git a/test/gmock-port_test.cc b/test/gmock-port_test.cc new file mode 100644 index 00000000..f35bc115 --- /dev/null +++ b/test/gmock-port_test.cc @@ -0,0 +1,95 @@ +// 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. +// +// Author: vladl@google.com (Vlad Losev) + +// Google Mock - a framework for writing C++ mock classes. +// +// This file tests the internal cross-platform support utilities. + +#include <gmock/internal/gmock-port.h> +#include <gtest/gtest.h> + +TEST(GmockCheckSyntaxTest, BehavesLikeASingleStatement) { +  if (false) +    GMOCK_CHECK_(false) << "This should never be executed; " +                           "It's a compilation test only."; + +  if (true) +    GMOCK_CHECK_(true); +  else +    ; + +  if (false) +    ; +  else +    GMOCK_CHECK_(true) << ""; +} + +TEST(GmockCheckSyntaxTest, WorksWithSwitch) { +  switch (0) { +    case 1: +      break; +    default: +      GMOCK_CHECK_(true); +  } + +  switch(0) +    case 0: +      GMOCK_CHECK_(true) << "Check failed in switch case"; +} + +#ifdef GTEST_HAS_DEATH_TEST + +TEST(GmockCheckDeathTest, DiesWithCorrectOutputOnFailure) { +  const bool a_false_condition = false; +  EXPECT_DEATH(GMOCK_CHECK_(a_false_condition) << "Extra info", +               // MSVC and gcc use different formats to print source +               // file locations.  Google Mock's failure messages use +               // the same format as used by the compiler, in order +               // for the IDE to recognize them.  Therefore we look +               // for different patterns here depending on the +               // compiler. +#ifdef _MSC_VER +               "gmock-port_test\\.cc\\([0-9]+\\):" +#else +               "gmock-port_test\\.cc:[0-9]+" +#endif  // _MSC_VER +               ".*a_false_condition.*Extra info"); +} + +TEST(GmockCheckDeathTest, LivesSilentlyOnSuccess) { +  EXPECT_EXIT({ +      GMOCK_CHECK_(true) << "Extra info"; +      ::std::cerr << "Success\n"; +      exit(0); }, +      ::testing::ExitedWithCode(0), "Success"); +} + +#endif  // GTEST_HAS_DEATH_TEST diff --git a/test/gmock-printers_test.cc b/test/gmock-printers_test.cc new file mode 100644 index 00000000..7457af2b --- /dev/null +++ b/test/gmock-printers_test.cc @@ -0,0 +1,903 @@ +// 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 universal value printer. + +#include <gmock/gmock-printers.h> + +#include <ctype.h> +#include <limits.h> +#include <string.h> +#include <algorithm> +#include <deque> +#include <list> +#include <map> +#include <set> +#include <sstream> +#include <string> +#include <utility> +#include <vector> +#include <gmock/gmock-matchers.h> +#include <gmock/internal/gmock-port.h> +#include <gtest/gtest.h> + +// hash_map and hash_set are available on Windows. +#ifdef GTEST_OS_WINDOWS +#define GMOCK_HAS_HASH_MAP_  // Indicates that hash_map is available. +#include <hash_map>          // NOLINT +#define GMOCK_HAS_HASH_SET_  // Indicates that hash_set is available. +#include <hash_set>          // NOLINT +#endif  // GTEST_OS_WINDOWS + +// Some user-defined types for testing the universal value printer. + +// A user-defined unprintable class template in the global namespace. +template <typename T> +class UnprintableTemplateInGlobal { + public: +  UnprintableTemplateInGlobal() : value_() {} + private: +  T value_; +}; + +// A user-defined streamable type in the global namespace. +class StreamableInGlobal { + public: +  virtual ~StreamableInGlobal() {} +}; + +inline void operator<<(::std::ostream& os, const StreamableInGlobal& x) { +  os << "StreamableInGlobal"; +} + +namespace foo { + +// A user-defined unprintable type in a user namespace. +class UnprintableInFoo { + public: +  UnprintableInFoo() : x_(0x12EF), y_(0xAB34), z_(0) {} + private: +  testing::internal::Int32 x_; +  testing::internal::Int32 y_; +  double z_; +}; + +// A user-defined printable type in a user-chosen namespace. +struct PrintableViaPrintTo { +  PrintableViaPrintTo() : value() {} +  int value; +}; + +void PrintTo(const PrintableViaPrintTo& x, ::std::ostream* os) { +  *os << "PrintableViaPrintTo: " << x.value; +} + +// A user-defined printable class template in a user-chosen namespace. +template <typename T> +class PrintableViaPrintToTemplate { + public: +  explicit PrintableViaPrintToTemplate(const T& value) : value_(value) {} + +  const T& value() const { return value_; } + private: +  T value_; +}; + +template <typename T> +void PrintTo(const PrintableViaPrintToTemplate<T>& x, ::std::ostream* os) { +  *os << "PrintableViaPrintToTemplate: " << x.value(); +} + +// A user-defined streamable class template in a user namespace. +template <typename T> +class StreamableTemplateInFoo { + public: +  StreamableTemplateInFoo() : value_() {} + +  const T& value() const { return value_; } + private: +  T value_; +}; + +template <typename T> +inline ::std::ostream& operator<<(::std::ostream& os, +                                  const StreamableTemplateInFoo<T>& x) { +  return os << "StreamableTemplateInFoo: " << x.value(); +} + +}  // namespace foo + +namespace testing { +namespace gmock_printers_test { + +using ::std::deque; +using ::std::list; +using ::std::make_pair; +using ::std::map; +using ::std::multimap; +using ::std::multiset; +using ::std::pair; +using ::std::set; +using ::std::tr1::make_tuple; +using ::std::tr1::tuple; +using ::std::vector; +using ::testing::StartsWith; +using ::testing::internal::UniversalPrinter; +using ::testing::internal::string; + +#ifdef GTEST_OS_WINDOWS +// MSVC defines the following classes in the ::stdext namespace while +// gcc defines them in the :: namespace.  Note that they are not part +// of the C++ standard. + +using ::stdext::hash_map; +using ::stdext::hash_set; +using ::stdext::hash_multimap; +using ::stdext::hash_multiset; + +#endif  // GTEST_OS_WINDOWS + +// Prints a value to a string using the universal value printer.  This +// is a helper for testing UniversalPrinter<T>::Print() for various types. +template <typename T> +string Print(const T& value) { +  ::std::stringstream ss; +  UniversalPrinter<T>::Print(value, &ss); +  return ss.str(); +} + +// Prints a value passed by reference to a string, using the universal +// value printer.  This is a helper for testing +// UniversalPrinter<T&>::Print() for various types. +template <typename T> +string PrintByRef(const T& value) { +  ::std::stringstream ss; +  UniversalPrinter<T&>::Print(value, &ss); +  return ss.str(); +} + +// Tests printing various char types. + +// char. +TEST(PrintCharTest, PlainChar) { +  EXPECT_EQ("'\\0'", Print('\0')); +  EXPECT_EQ("'\\'' (39)", Print('\'')); +  EXPECT_EQ("'\"' (34)", Print('"')); +  EXPECT_EQ("'\\?' (63)", Print('\?')); +  EXPECT_EQ("'\\\\' (92)", Print('\\')); +  EXPECT_EQ("'\\a' (7)", Print('\a')); +  EXPECT_EQ("'\\b' (8)", Print('\b')); +  EXPECT_EQ("'\\f' (12)", Print('\f')); +  EXPECT_EQ("'\\n' (10)", Print('\n')); +  EXPECT_EQ("'\\r' (13)", Print('\r')); +  EXPECT_EQ("'\\t' (9)", Print('\t')); +  EXPECT_EQ("'\\v' (11)", Print('\v')); +  EXPECT_EQ("'\\x7F' (127)", Print('\x7F')); +  EXPECT_EQ("'\\xFF' (255)", Print('\xFF')); +  EXPECT_EQ("' ' (32)", Print(' ')); +  EXPECT_EQ("'a' (97)", Print('a')); +} + +// signed char. +TEST(PrintCharTest, SignedChar) { +  EXPECT_EQ("'\\0'", Print(static_cast<signed char>('\0'))); +  EXPECT_EQ("'\\xCE' (-50)", +            Print(static_cast<signed char>(-50))); +} + +// unsigned char. +TEST(PrintCharTest, UnsignedChar) { +  EXPECT_EQ("'\\0'", Print(static_cast<unsigned char>('\0'))); +  EXPECT_EQ("'b' (98)", +            Print(static_cast<unsigned char>('b'))); +} + +// Tests printing other simple, built-in types. + +// bool. +TEST(PrintBuiltInTypeTest, Bool) { +  EXPECT_EQ("false", Print(false)); +  EXPECT_EQ("true", Print(true)); +} + +// wchar_t. +TEST(PrintBuiltInTypeTest, Wchar_t) { +  EXPECT_EQ("L'\\0'", Print(L'\0')); +  EXPECT_EQ("L'\\'' (39)", Print(L'\'')); +  EXPECT_EQ("L'\"' (34)", Print(L'"')); +  EXPECT_EQ("L'\\?' (63)", Print(L'\?')); +  EXPECT_EQ("L'\\\\' (92)", Print(L'\\')); +  EXPECT_EQ("L'\\a' (7)", Print(L'\a')); +  EXPECT_EQ("L'\\b' (8)", Print(L'\b')); +  EXPECT_EQ("L'\\f' (12)", Print(L'\f')); +  EXPECT_EQ("L'\\n' (10)", Print(L'\n')); +  EXPECT_EQ("L'\\r' (13)", Print(L'\r')); +  EXPECT_EQ("L'\\t' (9)", Print(L'\t')); +  EXPECT_EQ("L'\\v' (11)", Print(L'\v')); +  EXPECT_EQ("L'\\x7F' (127)", Print(L'\x7F')); +  EXPECT_EQ("L'\\xFF' (255)", Print(L'\xFF')); +  EXPECT_EQ("L' ' (32)", Print(L' ')); +  EXPECT_EQ("L'a' (97)", Print(L'a')); +  EXPECT_EQ("L'\\x576' (1398)", Print(L'\x576')); +  EXPECT_EQ("L'\\xC74D' (51021)", Print(L'\xC74D')); +} + +// Test that Int64 provides more storage than wchar_t. +TEST(PrintTypeSizeTest, Wchar_t) { +  EXPECT_LT(sizeof(wchar_t), sizeof(testing::internal::Int64)); +} + +// Various integer types. +TEST(PrintBuiltInTypeTest, Integer) { +  EXPECT_EQ("'\\xFF' (255)", Print(static_cast<unsigned char>(255)));  // uint8 +  EXPECT_EQ("'\\x80' (-128)", Print(static_cast<signed char>(-128)));  // int8 +  EXPECT_EQ("65535", Print(USHRT_MAX));  // uint16 +  EXPECT_EQ("-32768", Print(SHRT_MIN));  // int16 +  EXPECT_EQ("4294967295", Print(UINT_MAX));  // uint32 +  EXPECT_EQ("-2147483648", Print(INT_MIN));  // int32 +  EXPECT_EQ("18446744073709551615", +            Print(static_cast<testing::internal::UInt64>(-1)));  // uint64 +  EXPECT_EQ("-9223372036854775808", +            Print(static_cast<testing::internal::Int64>(1) << 63));  // int64 +} + +// Size types. +TEST(PrintBuiltInTypeTest, Size_t) { +  EXPECT_EQ("1", Print(sizeof('a')));  // size_t. +#ifndef GTEST_OS_WINDOWS +  // Windows has no ssize_t type. +  EXPECT_EQ("-2", Print(static_cast<ssize_t>(-2)));  // ssize_t. +#endif  // GTEST_OS_WINDOWS +} + +// Floating-points. +TEST(PrintBuiltInTypeTest, FloatingPoints) { +  EXPECT_EQ("1.5", Print(1.5f));   // float +  EXPECT_EQ("-2.5", Print(-2.5));  // double +} + +// Since ::std::stringstream::operator<<(const void *) formats the pointer +// output differently with different compilers, we have to create the expected +// output first and use it as our expectation. +static string PrintPointer(const void *p) { +  ::std::stringstream expected_result_stream; +  expected_result_stream << p; +  return expected_result_stream.str(); +} + +// Tests printing C strings. + +// const char*. +TEST(PrintCStringTest, Const) { +  const char* p = "World"; +  EXPECT_EQ(PrintPointer(p) + " pointing to \"World\"", Print(p)); +} + +// char*. +TEST(PrintCStringTest, NonConst) { +  char p[] = "Hi"; +  EXPECT_EQ(PrintPointer(p) + " pointing to \"Hi\"", +            Print(static_cast<char*>(p))); +} + +// NULL C string. +TEST(PrintCStringTest, Null) { +  const char* p = NULL; +  EXPECT_EQ("NULL", Print(p)); +} + +// Tests that C strings are escaped properly. +TEST(PrintCStringTest, EscapesProperly) { +  const char* p = "'\"\?\\\a\b\f\n\r\t\v\x7F\xFF a"; +  EXPECT_EQ(PrintPointer(p) + " pointing to \"'\\\"\\?\\\\\\a\\b\\f" +            "\\n\\r\\t\\v\\x7F\\xFF a\"", +            Print(p)); +} + + + +// MSVC compiler can be configured to define whar_t as a typedef +// of unsigned short. Defining an overload for const wchar_t* in that case +// would cause pointers to unsigned shorts be printed as wide strings, +// possibly accessing more memory than intended and causing invalid +// memory accesses. MSVC defines _NATIVE_WCHAR_T_DEFINED symbol when +// wchar_t is implemented as a native type. +#if !defined(_MSC_VER) || defined(_NATIVE_WCHAR_T_DEFINED) + +// const wchar_t*. +TEST(PrintWideCStringTest, Const) { +  const wchar_t* p = L"World"; +  EXPECT_EQ(PrintPointer(p) + " pointing to L\"World\"", Print(p)); +} + +// wchar_t*. +TEST(PrintWideCStringTest, NonConst) { +  wchar_t p[] = L"Hi"; +  EXPECT_EQ(PrintPointer(p) + " pointing to L\"Hi\"", +            Print(static_cast<wchar_t*>(p))); +} + +// NULL wide C string. +TEST(PrintWideCStringTest, Null) { +  const wchar_t* p = NULL; +  EXPECT_EQ("NULL", Print(p)); +} + +// Tests that wide C strings are escaped properly. +TEST(PrintWideCStringTest, EscapesProperly) { +  const wchar_t* p = L"'\"\?\\\a\b\f\n\r\t\v\xD3\x576\x8D3\xC74D a"; +  EXPECT_EQ(PrintPointer(p) + " pointing to L\"'\\\"\\?\\\\\\a\\b\\f" +            "\\n\\r\\t\\v\\xD3\\x576\\x8D3\\xC74D a\"", +            Print(p)); +} +#endif  // native wchar_t + +// Tests printing pointers to other char types. + +// signed char*. +TEST(PrintCharPointerTest, SignedChar) { +  signed char* p = reinterpret_cast<signed char*>(0x1234); +  EXPECT_EQ(PrintPointer(p), Print(p)); +  p = NULL; +  EXPECT_EQ("NULL", Print(p)); +} + +// const signed char*. +TEST(PrintCharPointerTest, ConstSignedChar) { +  signed char* p = reinterpret_cast<signed char*>(0x1234); +  EXPECT_EQ(PrintPointer(p), Print(p)); +  p = NULL; +  EXPECT_EQ("NULL", Print(p)); +} + +// unsigned char*. +TEST(PrintCharPointerTest, UnsignedChar) { +  unsigned char* p = reinterpret_cast<unsigned char*>(0x1234); +  EXPECT_EQ(PrintPointer(p), Print(p)); +  p = NULL; +  EXPECT_EQ("NULL", Print(p)); +} + +// const unsigned char*. +TEST(PrintCharPointerTest, ConstUnsignedChar) { +  const unsigned char* p = reinterpret_cast<const unsigned char*>(0x1234); +  EXPECT_EQ(PrintPointer(p), Print(p)); +  p = NULL; +  EXPECT_EQ("NULL", Print(p)); +} + +// Tests printing pointers to simple, built-in types. + +// bool*. +TEST(PrintPointerToBuiltInTypeTest, Bool) { +  bool* p = reinterpret_cast<bool*>(0xABCD); +  EXPECT_EQ(PrintPointer(p), Print(p)); +  p = NULL; +  EXPECT_EQ("NULL", Print(p)); +} + +// void*. +TEST(PrintPointerToBuiltInTypeTest, Void) { +  void* p = reinterpret_cast<void*>(0xABCD); +  EXPECT_EQ(PrintPointer(p), Print(p)); +  p = NULL; +  EXPECT_EQ("NULL", Print(p)); +} + +// const void*. +TEST(PrintPointerToBuiltInTypeTest, ConstVoid) { +  const void* p = reinterpret_cast<const void*>(0xABCD); +  EXPECT_EQ(PrintPointer(p), Print(p)); +  p = NULL; +  EXPECT_EQ("NULL", Print(p)); +} + +// Tests printing pointers to pointers. +TEST(PrintPointerToPointerTest, IntPointerPointer) { +  int** p = reinterpret_cast<int**>(0xABCD); +  EXPECT_EQ(PrintPointer(p), Print(p)); +  p = NULL; +  EXPECT_EQ("NULL", Print(p)); +} + +// Tests printing (non-member) function pointers. + +void MyFunction(int n) {} + +TEST(PrintPointerTest, NonMemberFunctionPointer) { +  EXPECT_EQ(PrintPointer(reinterpret_cast<const void*>(&MyFunction)), +            Print(&MyFunction)); +  int (*p)(bool) = NULL;  // NOLINT +  EXPECT_EQ("NULL", Print(p)); +} + +// Tests printing member variable pointers.  Although they are called +// pointers, they don't point to a location in the address space. +// Their representation is implementation-defined.  Thus they will be +// printed as raw bytes. + +struct Foo { + public: +  virtual ~Foo() {} +  int MyMethod(char x) { return x + 1; } +  virtual char MyVirtualMethod(int n) { return 'a'; } + +  int value; +}; + +TEST(PrintPointerTest, MemberVariablePointer) { +  EXPECT_THAT(Print(&Foo::value), +              StartsWith(Print(sizeof(&Foo::value)) + "-byte object ")); +  int (Foo::*p) = NULL;  // NOLINT +  EXPECT_THAT(Print(p), +              StartsWith(Print(sizeof(p)) + "-byte object ")); +} + +// Tests printing member function pointers.  Although they are called +// pointers, they don't point to a location in the address space. +// Their representation is implementation-defined.  Thus they will be +// printed as raw bytes. +TEST(PrintPointerTest, MemberFunctionPointer) { +  EXPECT_THAT(Print(&Foo::MyMethod), +              StartsWith(Print(sizeof(&Foo::MyMethod)) + "-byte object ")); +  EXPECT_THAT(Print(&Foo::MyVirtualMethod), +              StartsWith(Print(sizeof((&Foo::MyVirtualMethod))) +                               + "-byte object ")); +  int (Foo::*p)(char) = NULL;  // NOLINT +  EXPECT_THAT(Print(p), +              StartsWith(Print(sizeof(p)) + "-byte object ")); +} + +// Tests printing C arrays. + +// One-dimensional array. + +void ArrayHelper1(int (&a)[5]) {  // NOLINT +  EXPECT_EQ("{ 1, 2, 3, 4, 5 }", Print(a)); +} + +TEST(PrintArrayTest, OneDimensionalArray) { +  int a[5] = { 1, 2, 3, 4, 5 }; +  ArrayHelper1(a); +} + +// Two-dimensional array. + +void ArrayHelper2(int (&a)[2][5]) {  // NOLINT +  EXPECT_EQ("{ { 1, 2, 3, 4, 5 }, { 6, 7, 8, 9, 0 } }", Print(a)); +} + +TEST(PrintArrayTest, TwoDimensionalArray) { +  int a[2][5] = { +    { 1, 2, 3, 4, 5 }, +    { 6, 7, 8, 9, 0 } +  }; +  ArrayHelper2(a); +} + +// Array of const elements. + +void ArrayHelper3(const bool (&a)[1]) {  // NOLINT +  EXPECT_EQ("{ false }", Print(a)); +} + +TEST(PrintArrayTest, ConstArray) { +  const bool a[1] = { false }; +  ArrayHelper3(a); +} + +// Char array. + +void ArrayHelper4(char (&a)[3]) {  // NOLINT +  EXPECT_EQ(PrintPointer(a) + " pointing to \"Hi\"", Print(a)); +} + +TEST(PrintArrayTest, CharArray) { +  char a[3] = "Hi"; +  ArrayHelper4(a); +} + +// Const char array. + +void ArrayHelper5(const char (&a)[3]) {  // NOLINT +  EXPECT_EQ(Print(a), PrintPointer(a) + " pointing to \"Hi\""); +} + +TEST(PrintArrayTest, ConstCharArray) { +  const char a[3] = "Hi"; +  ArrayHelper5(a); +} + +// Array of objects. +TEST(PrintArrayTest, ObjectArray) { +  string a[3] = { "Hi", "Hello", "Ni hao" }; +  EXPECT_EQ("{ \"Hi\", \"Hello\", \"Ni hao\" }", Print(a)); +} + +// Array with many elements. +TEST(PrintArrayTest, BigArray) { +  int a[100] = { 1, 2, 3 }; +  EXPECT_EQ("{ 1, 2, 3, 0, 0, 0, 0, 0, ..., 0, 0, 0, 0, 0, 0, 0, 0 }", +            Print(a)); +} + +// Tests printing ::string and ::std::string. + +#if GTEST_HAS_GLOBAL_STRING +// ::string. +TEST(PrintStringTest, StringInGlobalNamespace) { +  const char s[] = "'\"\?\\\a\b\f\n\0\r\t\v\x7F\xFF a"; +  const ::string str(s, sizeof(s)); +  EXPECT_EQ("\"'\\\"\\?\\\\\\a\\b\\f\\n\\0\\r\\t\\v\\x7F\\xFF a\\0\"", +            Print(str)); +} +#endif  // GTEST_HAS_GLOBAL_STRING + +#if GTEST_HAS_STD_STRING +// ::std::string. +TEST(PrintStringTest, StringInStdNamespace) { +  const char s[] = "'\"\?\\\a\b\f\n\0\r\t\v\x7F\xFF a"; +  const ::std::string str(s, sizeof(s)); +  EXPECT_EQ("\"'\\\"\\?\\\\\\a\\b\\f\\n\\0\\r\\t\\v\\x7F\\xFF a\\0\"", +            Print(str)); +} +#endif  // GTEST_HAS_STD_STRING + +// Tests printing ::wstring and ::std::wstring. + +#if GTEST_HAS_GLOBAL_WSTRING +// ::wstring. +TEST(PrintWideStringTest, StringInGlobalNamespace) { +  const wchar_t s[] = L"'\"\?\\\a\b\f\n\0\r\t\v\xD3\x576\x8D3\xC74D a"; +  const ::wstring str(s, sizeof(s)/sizeof(wchar_t)); +  EXPECT_EQ("L\"'\\\"\\?\\\\\\a\\b\\f\\n\\0\\r\\t\\v" +            "\\xD3\\x576\\x8D3\\xC74D a\\0\"", +            Print(str)); +} +#endif  // GTEST_HAS_GLOBAL_WSTRING + +#if GTEST_HAS_STD_WSTRING +// ::std::wstring. +TEST(PrintWideStringTest, StringInStdNamespace) { +  const wchar_t s[] = L"'\"\?\\\a\b\f\n\0\r\t\v\xD3\x576\x8D3\xC74D a"; +  const ::std::wstring str(s, sizeof(s)/sizeof(wchar_t)); +  EXPECT_EQ("L\"'\\\"\\?\\\\\\a\\b\\f\\n\\0\\r\\t\\v" +            "\\xD3\\x576\\x8D3\\xC74D a\\0\"", +            Print(str)); +} +#endif  // GTEST_HAS_STD_WSTRING + +// Tests printing STL containers. + +TEST(PrintStlContainerTest, EmptyDeque) { +  deque<char> empty; +  EXPECT_EQ("{}", Print(empty)); +} + +TEST(PrintStlContainerTest, NonEmptyDeque) { +  deque<int> non_empty; +  non_empty.push_back(1); +  non_empty.push_back(3); +  EXPECT_EQ("{ 1, 3 }", Print(non_empty)); +} + +#ifdef GMOCK_HAS_HASH_MAP_ + +TEST(PrintStlContainerTest, OneElementHashMap) { +  hash_map<int, char> map1; +  map1[1] = 'a'; +  EXPECT_EQ("{ (1, 'a' (97)) }", Print(map1)); +} + +TEST(PrintStlContainerTest, HashMultiMap) { +  hash_multimap<int, bool> map1; +  map1.insert(make_pair(5, true)); +  map1.insert(make_pair(5, false)); + +  // Elements of hash_multimap can be printed in any order. +  const string result = Print(map1); +  EXPECT_TRUE(result == "{ (5, true), (5, false) }" || +              result == "{ (5, false), (5, true) }") +                  << " where Print(map1) returns \"" << result << "\"."; +} + +#endif  // GMOCK_HAS_HASH_MAP_ + +#ifdef GMOCK_HAS_HASH_SET_ + +TEST(PrintStlContainerTest, HashSet) { +  hash_set<string> set1; +  set1.insert("hello"); +  EXPECT_EQ("{ \"hello\" }", Print(set1)); +} + +TEST(PrintStlContainerTest, HashMultiSet) { +  const int kSize = 5; +  int a[kSize] = { 1, 1, 2, 5, 1 }; +  hash_multiset<int> set1(a, a + kSize); + +  // Elements of hash_multiset can be printed in any order. +  const string result = Print(set1); +  const string expected_pattern = "{ d, d, d, d, d }";  // d means a digit. + +  // Verifies the result matches the expected pattern; also extracts +  // the numbers in the result. +  ASSERT_EQ(expected_pattern.length(), result.length()); +  std::vector<int> numbers; +  for (size_t i = 0; i != result.length(); i++) { +    if (expected_pattern[i] == 'd') { +      ASSERT_TRUE(isdigit(result[i])); +      numbers.push_back(result[i] - '0'); +    } else { +      EXPECT_EQ(expected_pattern[i], result[i]) << " where result is " +                                                << result; +    } +  } + +  // Makes sure the result contains the right numbers. +  std::sort(numbers.begin(), numbers.end()); +  std::sort(a, a + kSize); +  EXPECT_TRUE(std::equal(a, a + kSize, numbers.begin())); +} + +#endif  // GMOCK_HAS_HASH_SET_ + +TEST(PrintStlContainerTest, List) { +  const char* a[] = { +    "hello", +    "world" +  }; +  const list<string> strings(a, a + 2); +  EXPECT_EQ("{ \"hello\", \"world\" }", Print(strings)); +} + +TEST(PrintStlContainerTest, Map) { +  map<int, bool> map1; +  map1[1] = true; +  map1[5] = false; +  map1[3] = true; +  EXPECT_EQ("{ (1, true), (3, true), (5, false) }", Print(map1)); +} + +TEST(PrintStlContainerTest, MultiMap) { +  multimap<bool, int> map1; +  map1.insert(make_pair(true, 0)); +  map1.insert(make_pair(true, 1)); +  map1.insert(make_pair(false, 2)); +  EXPECT_EQ("{ (false, 2), (true, 0), (true, 1) }", Print(map1)); +} + +TEST(PrintStlContainerTest, Set) { +  const unsigned int a[] = { 3, 0, 5 }; +  set<unsigned int> set1(a, a + 3); +  EXPECT_EQ("{ 0, 3, 5 }", Print(set1)); +} + +TEST(PrintStlContainerTest, MultiSet) { +  const int a[] = { 1, 1, 2, 5, 1 }; +  multiset<int> set1(a, a + 5); +  EXPECT_EQ("{ 1, 1, 1, 2, 5 }", Print(set1)); +} + +TEST(PrintStlContainerTest, Pair) { +  pair<const bool, int> p(true, 5); +  EXPECT_EQ("(true, 5)", Print(p)); +} + +TEST(PrintStlContainerTest, Vector) { +  vector<int> v; +  v.push_back(1); +  v.push_back(2); +  EXPECT_EQ("{ 1, 2 }", Print(v)); +} + +TEST(PrintStlContainerTest, LongSequence) { +  const int a[100] = { 1, 2, 3 }; +  const vector<int> v(a, a + 100); +  EXPECT_EQ("{ 1, 2, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, " +            "0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ... }", Print(v)); +} + +TEST(PrintStlContainerTest, NestedContainer) { +  const int a1[] = { 1, 2 }; +  const int a2[] = { 3, 4, 5 }; +  const list<int> l1(a1, a1 + 2); +  const list<int> l2(a2, a2 + 3); + +  vector<list<int> > v; +  v.push_back(l1); +  v.push_back(l2); +  EXPECT_EQ("{ { 1, 2 }, { 3, 4, 5 } }", Print(v)); +} + + +// Tests printing tuples. + +// Tuples of various arities. +TEST(PrintTupleTest, VariousSizes) { +  tuple<> t0; +  EXPECT_EQ("()", Print(t0)); + +  tuple<int> t1(5); +  EXPECT_EQ("(5)", Print(t1)); + +  tuple<char, bool> t2('a', true); +  EXPECT_EQ("('a' (97), true)", Print(t2)); + +  const char* const str = "8"; +  tuple<bool, char, short, testing::internal::Int32,  // NOLINT +      testing::internal::Int64, float, double, const char*, void*, string> +      t10(false, 'a', 3, 4, 5, 6.5F, 7.5, str, NULL, "10"); +  EXPECT_EQ("(false, 'a' (97), 3, 4, 5, 6.5, 7.5, " + PrintPointer(str) + +            " pointing to \"8\", NULL, \"10\")", +            Print(t10)); +} + +// Nested tuples. +TEST(PrintTupleTest, NestedTuple) { +  tuple<tuple<int, double>, char> nested(make_tuple(5, 9.5), 'a'); +  EXPECT_EQ("((5, 9.5), 'a' (97))", Print(nested)); +} + +// Tests printing user-defined unprintable types. + +// Unprintable types in the global namespace. +TEST(PrintUnprintableTypeTest, InGlobalNamespace) { +  EXPECT_EQ("1-byte object <00>", +            Print(UnprintableTemplateInGlobal<bool>())); +} + +// Unprintable types in a user namespace. +TEST(PrintUnprintableTypeTest, InUserNamespace) { +  EXPECT_EQ("16-byte object <EF12 0000 34AB 0000 0000 0000 0000 0000>", +            Print(::foo::UnprintableInFoo())); +} + +// Unprintable types are that too big to be printed completely. + +struct Big { +  Big() { memset(array, 0, sizeof(array)); } +  char array[257]; +}; + +TEST(PrintUnpritableTypeTest, BigObject) { +  EXPECT_EQ("257-byte object <0000 0000 0000 0000 0000 0000 " +            "0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 " +            "0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 " +            "0000 0000 0000 0000 0000 0000 ... 0000 0000 0000 " +            "0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 " +            "0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 " +            "0000 0000 0000 0000 0000 0000 0000 0000 00>", +            Print(Big())); +} + +// Tests printing user-defined streamable types. + +// Streamable types in the global namespace. +TEST(PrintStreamableTypeTest, InGlobalNamespace) { +  EXPECT_EQ("StreamableInGlobal", +            Print(StreamableInGlobal())); +} + +// Printable template types in a user namespace. +TEST(PrintStreamableTypeTest, TemplateTypeInUserNamespace) { +  EXPECT_EQ("StreamableTemplateInFoo: 0", +            Print(::foo::StreamableTemplateInFoo<int>())); +} + +// Tests printing user-defined types that have a PrintTo() function. +TEST(PrintPrintableTypeTest, InUserNamespace) { +  EXPECT_EQ("PrintableViaPrintTo: 0", +            Print(::foo::PrintableViaPrintTo())); +} + +// Tests printing user-defined class template that have a PrintTo() function. +TEST(PrintPrintableTypeTest, TemplateInUserNamespace) { +  EXPECT_EQ("PrintableViaPrintToTemplate: 5", +            Print(::foo::PrintableViaPrintToTemplate<int>(5))); +} + +#if GMOCK_HAS_PROTOBUF_ + +// Tests printing a protocol message. +TEST(PrintProtocolMessageTest, PrintsShortDebugString) { +  testing::internal::TestMessage msg; +  msg.set_member("yes"); +  EXPECT_EQ("<member:\"yes\">", Print(msg)); +} + +// Tests printing a proto2 message. +TEST(PrintProto2MessageTest, PrintsShortDebugString) { +  testing::internal::FooMessage msg; +  msg.set_int_field(2); +  EXPECT_PRED2(RE::FullMatch, Print(msg), +               "<int_field:\\s*2\\s*>"); +} + +#endif  // GMOCK_HAS_PROTOBUF_ + +// Tests that the universal printer prints both the address and the +// value of a reference. +TEST(PrintReferenceTest, PrintsAddressAndValue) { +  int n = 5; +  EXPECT_EQ("@" + PrintPointer(&n) + " 5", PrintByRef(n)); + +  int a[2][3] = { +    { 0, 1, 2 }, +    { 3, 4, 5 } +  }; +  EXPECT_EQ("@" + PrintPointer(a) + " { { 0, 1, 2 }, { 3, 4, 5 } }", +            PrintByRef(a)); + +  const ::foo::UnprintableInFoo x; +  EXPECT_EQ("@" + PrintPointer(&x) + " 16-byte object " +            "<EF12 0000 34AB 0000 0000 0000 0000 0000>", +            PrintByRef(x)); +} + +// Tests that the universal printer prints a function pointer passed by +// reference. +TEST(PrintReferenceTest, HandlesFunctionPointer) { +  void (*fp)(int n) = &MyFunction; +  const string fp_pointer_string = +      PrintPointer(reinterpret_cast<const void*>(&fp)); +  const string fp_string = PrintPointer(reinterpret_cast<const void*>(fp)); +  EXPECT_EQ("@" + fp_pointer_string + " " + fp_string, +            PrintByRef(fp)); +} + +// Tests that the universal printer prints a member function pointer +// passed by reference. +TEST(PrintReferenceTest, HandlesMemberFunctionPointer) { +  int (Foo::*p)(char ch) = &Foo::MyMethod; +  EXPECT_THAT(PrintByRef(p), +              StartsWith("@" + PrintPointer(reinterpret_cast<const void*>(&p)) +                         + " " + Print(sizeof(p)) + "-byte object ")); + +  char (Foo::*p2)(int n) = &Foo::MyVirtualMethod; +  EXPECT_THAT(PrintByRef(p2), +              StartsWith("@" + PrintPointer(reinterpret_cast<const void*>(&p2)) +                         + " " + Print(sizeof(p2)) + "-byte object ")); +} + +// Tests that the universal printer prints a member variable pointer +// passed by reference. +TEST(PrintReferenceTest, HandlesMemberVariablePointer) { +  int (Foo::*p) = &Foo::value;  // NOLINT +  EXPECT_THAT(PrintByRef(p), +              StartsWith("@" + PrintPointer(&p) +                         + " " + Print(sizeof(p)) + "-byte object ")); +} + +}  // namespace gmock_printers_test +}  // namespace testing diff --git a/test/gmock-sample.cc b/test/gmock-sample.cc new file mode 100644 index 00000000..44d72a10 --- /dev/null +++ b/test/gmock-sample.cc @@ -0,0 +1,32 @@ +// 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. +// +// Author: wan@google.com (Zhanyong Wan) + +#include "test/gmock-sample.h" diff --git a/test/gmock-sample.h b/test/gmock-sample.h new file mode 100644 index 00000000..2183f4f9 --- /dev/null +++ b/test/gmock-sample.h @@ -0,0 +1,49 @@ +// 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. +// +// Author: wan@google.com (Zhanyong Wan) + +#ifndef GMOCK_TEST_GMOCK_SAMPLE_H_ +#define GMOCK_TEST_GMOCK_SAMPLE_H_ + +#include <gmock/gmock.h> + +class Sample { + public: +  virtual ~Sample() {} + +  virtual bool Foo(int n) = 0; +}; + +class MockSample : public Sample { + public: +  MOCK_METHOD1(Foo, bool(int n)); +}; + +#endif  // GMOCK_TEST_GMOCK_SAMPLE_H_ diff --git a/test/gmock-spec-builders_test.cc b/test/gmock-spec-builders_test.cc new file mode 100644 index 00000000..3e27aa84 --- /dev/null +++ b/test/gmock-spec-builders_test.cc @@ -0,0 +1,1889 @@ +// 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 spec builder syntax. + +#include <gmock/gmock-spec-builders.h> + +#include <ostream>  // NOLINT +#include <sstream> +#include <string> + +#include <gmock/gmock.h> +#include <gmock/internal/gmock-port.h> +#include <gtest/gtest.h> +#include <gtest/gtest-spi.h> + +namespace testing { +namespace internal { + +// Helper class for testing the Expectation class template. +class ExpectationTester { + public: +  // Sets the call count of the given expectation to the given number. +  void SetCallCount(int n, ExpectationBase* exp) { +    exp->call_count_ = n; +  } +}; + +}  // namespace internal +}  // namespace testing + +namespace { + +using testing::_; +using testing::AnyNumber; +using testing::AtLeast; +using testing::AtMost; +using testing::Between; +using testing::Cardinality; +using testing::CardinalityInterface; +using testing::Const; +using testing::DoAll; +using testing::DoDefault; +using testing::GMOCK_FLAG(verbose); +using testing::InSequence; +using testing::Invoke; +using testing::InvokeWithoutArgs; +using testing::IsSubstring; +using testing::Lt; +using testing::Message; +using testing::Mock; +using testing::Return; +using testing::Sequence; +using testing::internal::g_gmock_mutex; +using testing::internal::kErrorVerbosity; +using testing::internal::kInfoVerbosity; +using testing::internal::kWarningVerbosity; +using testing::internal::Expectation; +using testing::internal::ExpectationTester; +using testing::internal::string; + +class Result {}; + +class MockA { + public: +  MOCK_METHOD1(DoA, void(int n));  // NOLINT +  MOCK_METHOD1(ReturnResult, Result(int n));  // NOLINT +  MOCK_METHOD2(Binary, bool(int x, int y));  // NOLINT +}; + +class MockB { + public: +  MOCK_CONST_METHOD0(DoB, int());  // NOLINT +  MOCK_METHOD1(DoB, int(int n));  // NOLINT +}; + +// Tests that EXPECT_CALL and ON_CALL compile in a presence of macro +// redefining a mock method name. This could happen, for example, when +// the tested code #includes Win32 API headers which define many APIs +// as macros, e.g. #define TextOut TextOutW. + +#define Method MethodW + +class CC { + public: +  virtual ~CC() {} +  virtual int Method() = 0; +}; +class MockCC : public CC { + public: +  MOCK_METHOD0(Method, int()); +}; + +// Tests that a method with expanded name compiles. +TEST(OnCallSyntaxTest, CompilesWithMethodNameExpandedFromMacro) { +  MockCC cc; +  ON_CALL(cc, Method()); +} + +// Tests that the method with expanded name not only compiles but runs +// and returns a correct value, too. +TEST(OnCallSyntaxTest, WorksWithMethodNameExpandedFromMacro) { +  MockCC cc; +  ON_CALL(cc, Method()).WillByDefault(Return(42)); +  EXPECT_EQ(42, cc.Method()); +} + +// Tests that a method with expanded name compiles. +TEST(ExpectCallSyntaxTest, CompilesWithMethodNameExpandedFromMacro) { +  MockCC cc; +  EXPECT_CALL(cc, Method()); +  cc.Method(); +} + +// Tests that it works, too. +TEST(ExpectCallSyntaxTest, WorksWithMethodNameExpandedFromMacro) { +  MockCC cc; +  EXPECT_CALL(cc, Method()).WillOnce(Return(42)); +  EXPECT_EQ(42, cc.Method()); +} + +#undef Method  // Done with macro redefinition tests. + +// Tests that ON_CALL evaluates its arguments exactly once as promised +// by Google Mock. +TEST(OnCallSyntaxTest, EvaluatesFirstArgumentOnce) { +  MockA a; +  MockA* pa = &a; + +  ON_CALL(*pa++, DoA(_)); +  EXPECT_EQ(&a + 1, pa); +} + +TEST(OnCallSyntaxTest, EvaluatesSecondArgumentOnce) { +  MockA a; +  int n = 0; + +  ON_CALL(a, DoA(n++)); +  EXPECT_EQ(1, n); +} + +// Tests that the syntax of ON_CALL() is enforced at run time. + +TEST(OnCallSyntaxTest, WithArgumentsIsOptional) { +  MockA a; + +  ON_CALL(a, DoA(5)) +      .WillByDefault(Return()); +  ON_CALL(a, DoA(_)) +      .WithArguments(_) +      .WillByDefault(Return()); +} + +TEST(OnCallSyntaxTest, WithArgumentsCanAppearAtMostOnce) { +  MockA a; + +  EXPECT_NONFATAL_FAILURE({  // NOLINT +    ON_CALL(a, ReturnResult(_)) +        .WithArguments(_) +        .WithArguments(_) +        .WillByDefault(Return(Result())); +  }, ".WithArguments() cannot appear more than once in an ON_CALL()"); +} + +#ifdef GTEST_HAS_DEATH_TEST + +TEST(OnCallSyntaxTest, WillByDefaultIsMandatory) { +  MockA a; + +  EXPECT_DEATH({  // NOLINT +    ON_CALL(a, DoA(5)); +    a.DoA(5); +  }, ""); +} + +#endif  // GTEST_HAS_DEATH_TEST + +TEST(OnCallSyntaxTest, WillByDefaultCanAppearAtMostOnce) { +  MockA a; + +  EXPECT_NONFATAL_FAILURE({  // NOLINT +    ON_CALL(a, DoA(5)) +        .WillByDefault(Return()) +        .WillByDefault(Return()); +  }, ".WillByDefault() must appear exactly once in an ON_CALL()"); +} + +// Tests that EXPECT_CALL evaluates its arguments exactly once as +// promised by Google Mock. +TEST(ExpectCallSyntaxTest, EvaluatesFirstArgumentOnce) { +  MockA a; +  MockA* pa = &a; + +  EXPECT_CALL(*pa++, DoA(_)); +  a.DoA(0); +  EXPECT_EQ(&a + 1, pa); +} + +TEST(ExpectCallSyntaxTest, EvaluatesSecondArgumentOnce) { +  MockA a; +  int n = 0; + +  EXPECT_CALL(a, DoA(n++)); +  a.DoA(0); +  EXPECT_EQ(1, n); +} + +// Tests that the syntax of EXPECT_CALL() is enforced at run time. + +TEST(ExpectCallSyntaxTest, WithArgumentsIsOptional) { +  MockA a; + +  EXPECT_CALL(a, DoA(5)) +      .Times(0); +  EXPECT_CALL(a, DoA(6)) +      .WithArguments(_) +      .Times(0); +} + +TEST(ExpectCallSyntaxTest, WithArgumentsCanAppearAtMostOnce) { +  MockA a; + +  EXPECT_NONFATAL_FAILURE({  // NOLINT +    EXPECT_CALL(a, DoA(6)) +        .WithArguments(_) +        .WithArguments(_); +  }, ".WithArguments() cannot appear more than once in " +     "an EXPECT_CALL()"); + +  a.DoA(6); +} + +TEST(ExpectCallSyntaxTest, WithArgumentsMustBeFirstClause) { +  MockA a; + +  EXPECT_NONFATAL_FAILURE({  // NOLINT +    EXPECT_CALL(a, DoA(1)) +        .Times(1) +        .WithArguments(_); +  }, ".WithArguments() must be the first clause in an " +     "EXPECT_CALL()"); + +  a.DoA(1); + +  EXPECT_NONFATAL_FAILURE({  // NOLINT +    EXPECT_CALL(a, DoA(2)) +        .WillOnce(Return()) +        .WithArguments(_); +  }, ".WithArguments() must be the first clause in an " +     "EXPECT_CALL()"); + +  a.DoA(2); +} + +TEST(ExpectCallSyntaxTest, TimesCanBeInferred) { +  MockA a; + +  EXPECT_CALL(a, DoA(1)) +      .WillOnce(Return()); + +  EXPECT_CALL(a, DoA(2)) +      .WillOnce(Return()) +      .WillRepeatedly(Return()); + +  a.DoA(1); +  a.DoA(2); +  a.DoA(2); +} + +TEST(ExpectCallSyntaxTest, TimesCanAppearAtMostOnce) { +  MockA a; + +  EXPECT_NONFATAL_FAILURE({  // NOLINT +    EXPECT_CALL(a, DoA(1)) +        .Times(1) +        .Times(2); +  }, ".Times() cannot appear more than once in an EXPECT_CALL()"); + +  a.DoA(1); +  a.DoA(1); +} + +TEST(ExpectCallSyntaxTest, TimesMustBeBeforeInSequence) { +  MockA a; +  Sequence s; + +  EXPECT_NONFATAL_FAILURE({  // NOLINT +    EXPECT_CALL(a, DoA(1)) +        .InSequence(s) +        .Times(1); +  }, ".Times() cannot appear after "); + +  a.DoA(1); +} + +TEST(ExpectCallSyntaxTest, InSequenceIsOptional) { +  MockA a; +  Sequence s; + +  EXPECT_CALL(a, DoA(1)); +  EXPECT_CALL(a, DoA(2)) +      .InSequence(s); + +  a.DoA(1); +  a.DoA(2); +} + +TEST(ExpectCallSyntaxTest, InSequenceCanAppearMultipleTimes) { +  MockA a; +  Sequence s1, s2; + +  EXPECT_CALL(a, DoA(1)) +      .InSequence(s1, s2) +      .InSequence(s1); + +  a.DoA(1); +} + +TEST(ExpectCallSyntaxTest, InSequenceMustBeBeforeWill) { +  MockA a; +  Sequence s; + +  EXPECT_NONFATAL_FAILURE({  // NOLINT +    EXPECT_CALL(a, DoA(1)) +        .WillOnce(Return()) +        .InSequence(s); +  }, ".InSequence() cannot appear after "); + +  a.DoA(1); +} + +TEST(ExpectCallSyntaxTest, WillIsOptional) { +  MockA a; + +  EXPECT_CALL(a, DoA(1)); +  EXPECT_CALL(a, DoA(2)) +      .WillOnce(Return()); + +  a.DoA(1); +  a.DoA(2); +} + +TEST(ExpectCallSyntaxTest, WillCanAppearMultipleTimes) { +  MockA a; + +  EXPECT_CALL(a, DoA(1)) +      .Times(AnyNumber()) +      .WillOnce(Return()) +      .WillOnce(Return()) +      .WillOnce(Return()); +} + +TEST(ExpectCallSyntaxTest, WillMustBeBeforeWillRepeatedly) { +  MockA a; + +  EXPECT_NONFATAL_FAILURE({  // NOLINT +    EXPECT_CALL(a, DoA(1)) +        .WillRepeatedly(Return()) +        .WillOnce(Return()); +  }, ".WillOnce() cannot appear after "); + +  a.DoA(1); +} + +TEST(ExpectCallSyntaxTest, WillRepeatedlyIsOptional) { +  MockA a; + +  EXPECT_CALL(a, DoA(1)) +      .WillOnce(Return()); +  EXPECT_CALL(a, DoA(2)) +      .WillOnce(Return()) +      .WillRepeatedly(Return()); + +  a.DoA(1); +  a.DoA(2); +  a.DoA(2); +} + +TEST(ExpectCallSyntaxTest, WillRepeatedlyCannotAppearMultipleTimes) { +  MockA a; + +  EXPECT_NONFATAL_FAILURE({  // NOLINT +    EXPECT_CALL(a, DoA(1)) +        .WillRepeatedly(Return()) +        .WillRepeatedly(Return()); +  }, ".WillRepeatedly() cannot appear more than once in an " +     "EXPECT_CALL()"); +} + +TEST(ExpectCallSyntaxTest, WillRepeatedlyMustBeBeforeRetiresOnSaturation) { +  MockA a; + +  EXPECT_NONFATAL_FAILURE({  // NOLINT +    EXPECT_CALL(a, DoA(1)) +        .RetiresOnSaturation() +        .WillRepeatedly(Return()); +  }, ".WillRepeatedly() cannot appear after "); +} + +TEST(ExpectCallSyntaxTest, RetiresOnSaturationIsOptional) { +  MockA a; + +  EXPECT_CALL(a, DoA(1)); +  EXPECT_CALL(a, DoA(1)) +      .RetiresOnSaturation(); + +  a.DoA(1); +  a.DoA(1); +} + +TEST(ExpectCallSyntaxTest, RetiresOnSaturationCannotAppearMultipleTimes) { +  MockA a; + +  EXPECT_NONFATAL_FAILURE({  // NOLINT +    EXPECT_CALL(a, DoA(1)) +        .RetiresOnSaturation() +        .RetiresOnSaturation(); +  }, ".RetiresOnSaturation() cannot appear more than once"); + +  a.DoA(1); +} + +TEST(ExpectCallSyntaxTest, DefaultCardinalityIsOnce) { +  { +    MockA a; +    EXPECT_CALL(a, DoA(1)); +    a.DoA(1); +  } +  EXPECT_NONFATAL_FAILURE({  // NOLINT +    MockA a; +    EXPECT_CALL(a, DoA(1)); +  }, "to be called once"); +  EXPECT_NONFATAL_FAILURE({  // NOLINT +    MockA a; +    EXPECT_CALL(a, DoA(1)); +    a.DoA(1); +    a.DoA(1); +  }, "to be called once"); +} + +// TODO(wan@google.com): find a way to re-enable these tests. +#if 0 + +// Tests that Google Mock doesn't print a warning when the number of +// WillOnce() is adequate. +TEST(ExpectCallSyntaxTest, DoesNotWarnOnAdequateActionCount) { +  CaptureTestStdout(); +  { +    MockB b; + +    // It's always fine to omit WillOnce() entirely. +    EXPECT_CALL(b, DoB()) +        .Times(0); +    EXPECT_CALL(b, DoB(1)) +        .Times(AtMost(1)); +    EXPECT_CALL(b, DoB(2)) +        .Times(1) +        .WillRepeatedly(Return(1)); + +    // It's fine for the number of WillOnce()s to equal the upper bound. +    EXPECT_CALL(b, DoB(3)) +        .Times(Between(1, 2)) +        .WillOnce(Return(1)) +        .WillOnce(Return(2)); + +    // It's fine for the number of WillOnce()s to be smaller than the +    // upper bound when there is a WillRepeatedly(). +    EXPECT_CALL(b, DoB(4)) +        .Times(AtMost(3)) +        .WillOnce(Return(1)) +        .WillRepeatedly(Return(2)); + +    // Satisfies the above expectations. +    b.DoB(2); +    b.DoB(3); +  } +  const string& output = GetCapturedTestStdout(); +  EXPECT_EQ("", output); +} + +// Tests that Google Mock warns on having too many actions in an +// expectation compared to its cardinality. +TEST(ExpectCallSyntaxTest, WarnsOnTooManyActions) { +  CaptureTestStdout(); +  { +    MockB b; + +    // Warns when the number of WillOnce()s is larger than the upper bound. +    EXPECT_CALL(b, DoB()) +        .Times(0) +        .WillOnce(Return(1));  // #1 +    EXPECT_CALL(b, DoB()) +        .Times(AtMost(1)) +        .WillOnce(Return(1)) +        .WillOnce(Return(2));  // #2 +    EXPECT_CALL(b, DoB(1)) +        .Times(1) +        .WillOnce(Return(1)) +        .WillOnce(Return(2)) +        .RetiresOnSaturation();  // #3 + +    // Warns when the number of WillOnce()s equals the upper bound and +    // there is a WillRepeatedly(). +    EXPECT_CALL(b, DoB()) +        .Times(0) +        .WillRepeatedly(Return(1));  // #4 +    EXPECT_CALL(b, DoB(2)) +        .Times(1) +        .WillOnce(Return(1)) +        .WillRepeatedly(Return(2));  // #5 + +    // Satisfies the above expectations. +    b.DoB(1); +    b.DoB(2); +  } +  const string& output = GetCapturedTestStdout(); +  EXPECT_PRED_FORMAT2(IsSubstring, +                      "Too many actions specified.\n" +                      "Expected to be never called, but has 1 WillOnce().", +                      output);  // #1 +  EXPECT_PRED_FORMAT2(IsSubstring, +                      "Too many actions specified.\n" +                      "Expected to be called at most once, " +                      "but has 2 WillOnce()s.", +                      output);  // #2 +  EXPECT_PRED_FORMAT2(IsSubstring, +                      "Too many actions specified.\n" +                      "Expected to be called once, but has 2 WillOnce()s.", +                      output);  // #3 +  EXPECT_PRED_FORMAT2(IsSubstring, +                      "Too many actions specified.\n" +                      "Expected to be never called, but has 0 WillOnce()s " +                      "and a WillRepeatedly().", +                      output);  // #4 +  EXPECT_PRED_FORMAT2(IsSubstring, +                      "Too many actions specified.\n" +                      "Expected to be called once, but has 1 WillOnce() " +                      "and a WillRepeatedly().", +                      output);  // #5 +} + +// Tests that Google Mock warns on having too few actions in an +// expectation compared to its cardinality. +TEST(ExpectCallSyntaxTest, WarnsOnTooFewActions) { +  MockB b; + +  EXPECT_CALL(b, DoB()) +      .Times(Between(2, 3)) +      .WillOnce(Return(1)); + +  CaptureTestStdout(); +  b.DoB(); +  const string& output = GetCapturedTestStdout(); +  EXPECT_PRED_FORMAT2(IsSubstring, +                      "Too few actions specified.\n" +                      "Expected to be called between 2 and 3 times, " +                      "but has only 1 WillOnce().", +                      output); +  b.DoB(); +} + +#endif  // 0 + +// Tests the semantics of ON_CALL(). + +// Tests that the built-in default action is taken when no ON_CALL() +// is specified. +TEST(OnCallTest, TakesBuiltInDefaultActionWhenNoOnCall) { +  MockB b; +  EXPECT_CALL(b, DoB()); + +  EXPECT_EQ(0, b.DoB()); +} + +// Tests that the built-in default action is taken when no ON_CALL() +// matches the invocation. +TEST(OnCallTest, TakesBuiltInDefaultActionWhenNoOnCallMatches) { +  MockB b; +  ON_CALL(b, DoB(1)) +      .WillByDefault(Return(1)); +  EXPECT_CALL(b, DoB(_)); + +  EXPECT_EQ(0, b.DoB(2)); +} + +// Tests that the last matching ON_CALL() action is taken. +TEST(OnCallTest, PicksLastMatchingOnCall) { +  MockB b; +  ON_CALL(b, DoB(_)) +      .WillByDefault(Return(3)); +  ON_CALL(b, DoB(2)) +      .WillByDefault(Return(2)); +  ON_CALL(b, DoB(1)) +      .WillByDefault(Return(1)); +  EXPECT_CALL(b, DoB(_)); + +  EXPECT_EQ(2, b.DoB(2)); +} + +// Tests the semantics of EXPECT_CALL(). + +// Tests that any call is allowed when no EXPECT_CALL() is specified. +TEST(ExpectCallTest, AllowsAnyCallWhenNoSpec) { +  MockB b; +  EXPECT_CALL(b, DoB()); +  // There is no expectation on DoB(int). + +  b.DoB(); + +  // DoB(int) can be called any number of times. +  b.DoB(1); +  b.DoB(2); +} + +// Tests that the last matching EXPECT_CALL() fires. +TEST(ExpectCallTest, PicksLastMatchingExpectCall) { +  MockB b; +  EXPECT_CALL(b, DoB(_)) +      .WillRepeatedly(Return(2)); +  EXPECT_CALL(b, DoB(1)) +      .WillRepeatedly(Return(1)); + +  EXPECT_EQ(1, b.DoB(1)); +} + +// Tests lower-bound violation. +TEST(ExpectCallTest, CatchesTooFewCalls) { +  EXPECT_NONFATAL_FAILURE({  // NOLINT +    MockB b; +    EXPECT_CALL(b, DoB(5)) +        .Times(AtLeast(2)); + +    b.DoB(5); +  }, "Actual function call count doesn't match this expectation.\n" +     "         Expected: to be called at least twice\n" +     "           Actual: called once - unsatisfied and active"); +} + +// Tests that the cardinality can be inferred when no Times(...) is +// specified. +TEST(ExpectCallTest, InfersCardinalityWhenThereIsNoWillRepeatedly) { +  { +    MockB b; +    EXPECT_CALL(b, DoB()) +        .WillOnce(Return(1)) +        .WillOnce(Return(2)); + +    EXPECT_EQ(1, b.DoB()); +    EXPECT_EQ(2, b.DoB()); +  } + +  EXPECT_NONFATAL_FAILURE({  // NOLINT +    MockB b; +    EXPECT_CALL(b, DoB()) +        .WillOnce(Return(1)) +        .WillOnce(Return(2)); + +    EXPECT_EQ(1, b.DoB()); +  }, "to be called twice"); + +  {  // NOLINT +    MockB b; +    EXPECT_CALL(b, DoB()) +        .WillOnce(Return(1)) +        .WillOnce(Return(2)); + +    EXPECT_EQ(1, b.DoB()); +    EXPECT_EQ(2, b.DoB()); +    EXPECT_NONFATAL_FAILURE(b.DoB(), "to be called twice"); +  } +} + +TEST(ExpectCallTest, InfersCardinality1WhenThereIsWillRepeatedly) { +  { +    MockB b; +    EXPECT_CALL(b, DoB()) +        .WillOnce(Return(1)) +        .WillRepeatedly(Return(2)); + +    EXPECT_EQ(1, b.DoB()); +  } + +  {  // NOLINT +    MockB b; +    EXPECT_CALL(b, DoB()) +        .WillOnce(Return(1)) +        .WillRepeatedly(Return(2)); + +    EXPECT_EQ(1, b.DoB()); +    EXPECT_EQ(2, b.DoB()); +    EXPECT_EQ(2, b.DoB()); +  } + +  EXPECT_NONFATAL_FAILURE({  // NOLINT +    MockB b; +    EXPECT_CALL(b, DoB()) +        .WillOnce(Return(1)) +        .WillRepeatedly(Return(2)); +  }, "to be called at least once"); +} + +// Tests that the n-th action is taken for the n-th matching +// invocation. +TEST(ExpectCallTest, NthMatchTakesNthAction) { +  MockB b; +  EXPECT_CALL(b, DoB()) +      .WillOnce(Return(1)) +      .WillOnce(Return(2)) +      .WillOnce(Return(3)); + +  EXPECT_EQ(1, b.DoB()); +  EXPECT_EQ(2, b.DoB()); +  EXPECT_EQ(3, b.DoB()); +} + +// TODO(wan@google.com): find a way to re-enable these tests. +#if 0 + +// Tests that the default action is taken when the WillOnce(...) list is +// exhausted and there is no WillRepeatedly(). +TEST(ExpectCallTest, TakesDefaultActionWhenWillListIsExhausted) { +  MockB b; +  EXPECT_CALL(b, DoB(_)) +      .Times(1); +  EXPECT_CALL(b, DoB()) +      .Times(AnyNumber()) +      .WillOnce(Return(1)) +      .WillOnce(Return(2)); + +  CaptureTestStdout(); +  EXPECT_EQ(0, b.DoB(1));  // Shouldn't generate a warning as the +                           // expectation has no action clause at all. +  EXPECT_EQ(1, b.DoB()); +  EXPECT_EQ(2, b.DoB()); +  const string& output1 = GetCapturedTestStdout(); +  EXPECT_EQ("", output1); + +  CaptureTestStdout(); +  EXPECT_EQ(0, b.DoB()); +  EXPECT_EQ(0, b.DoB()); +  const string& output2 = GetCapturedTestStdout(); +  EXPECT_PRED2(RE::PartialMatch, output2, +               "Actions ran out\\.\n" +               "Called 3 times, but only 2 WillOnce\\(\\)s are specified - " +               "returning default value\\."); +  EXPECT_PRED2(RE::PartialMatch, output2, +               "Actions ran out\\.\n" +               "Called 4 times, but only 2 WillOnce\\(\\)s are specified - " +               "returning default value\\."); +} + +#endif  // 0 + +// Tests that the WillRepeatedly() action is taken when the WillOnce(...) +// list is exhausted. +TEST(ExpectCallTest, TakesRepeatedActionWhenWillListIsExhausted) { +  MockB b; +  EXPECT_CALL(b, DoB()) +      .WillOnce(Return(1)) +      .WillRepeatedly(Return(2)); + +  EXPECT_EQ(1, b.DoB()); +  EXPECT_EQ(2, b.DoB()); +  EXPECT_EQ(2, b.DoB()); +} + +// Tests that an uninteresting call performs the default action. +TEST(UninterestingCallTest, DoesDefaultAction) { +  // When there is an ON_CALL() statement, the action specified by it +  // should be taken. +  MockA a; +  ON_CALL(a, Binary(_, _)) +      .WillByDefault(Return(true)); +  EXPECT_TRUE(a.Binary(1, 2)); + +  // When there is no ON_CALL(), the default value for the return type +  // should be returned. +  MockB b; +  EXPECT_EQ(0, b.DoB()); +} + +// Tests that an unexpected call performs the default action. +TEST(UnexpectedCallTest, DoesDefaultAction) { +  // When there is an ON_CALL() statement, the action specified by it +  // should be taken. +  MockA a; +  ON_CALL(a, Binary(_, _)) +      .WillByDefault(Return(true)); +  EXPECT_CALL(a, Binary(0, 0)); +  a.Binary(0, 0); +  bool result = false; +  EXPECT_NONFATAL_FAILURE(result = a.Binary(1, 2), +                          "Unexpected mock function call"); +  EXPECT_TRUE(result); + +  // When there is no ON_CALL(), the default value for the return type +  // should be returned. +  MockB b; +  EXPECT_CALL(b, DoB(0)) +      .Times(0); +  int n = -1; +  EXPECT_NONFATAL_FAILURE(n = b.DoB(1), +                          "Unexpected mock function call"); +  EXPECT_EQ(0, n); +} + +// Tests that when an unexpected void function generates the right +// failure message. +TEST(UnexpectedCallTest, GeneratesFailureForVoidFunction) { +  // First, tests the message when there is only one EXPECT_CALL(). +  MockA a1; +  EXPECT_CALL(a1, DoA(1)); +  a1.DoA(1); +  // Ideally we should match the failure message against a regex, but +  // EXPECT_NONFATAL_FAILURE doesn't support that, so we test for +  // multiple sub-strings instead. +  EXPECT_NONFATAL_FAILURE( +      a1.DoA(9), +      "Unexpected mock function call - returning directly.\n" +      "    Function call: DoA(9)\n" +      "Google Mock tried the following 1 expectation, but it didn't match:"); +  EXPECT_NONFATAL_FAILURE( +      a1.DoA(9), +      "  Expected arg #0: is equal to 1\n" +      "           Actual: 9\n" +      "         Expected: to be called once\n" +      "           Actual: called once - saturated and active"); + +  // Next, tests the message when there are more than one EXPECT_CALL(). +  MockA a2; +  EXPECT_CALL(a2, DoA(1)); +  EXPECT_CALL(a2, DoA(3)); +  a2.DoA(1); +  EXPECT_NONFATAL_FAILURE( +      a2.DoA(2), +      "Unexpected mock function call - returning directly.\n" +      "    Function call: DoA(2)\n" +      "Google Mock tried the following 2 expectations, but none matched:"); +  EXPECT_NONFATAL_FAILURE( +      a2.DoA(2), +      "tried expectation #0\n" +      "  Expected arg #0: is equal to 1\n" +      "           Actual: 2\n" +      "         Expected: to be called once\n" +      "           Actual: called once - saturated and active"); +  EXPECT_NONFATAL_FAILURE( +      a2.DoA(2), +      "tried expectation #1\n" +      "  Expected arg #0: is equal to 3\n" +      "           Actual: 2\n" +      "         Expected: to be called once\n" +      "           Actual: never called - unsatisfied and active"); +  a2.DoA(3); +} + +// Tests that an unexpected non-void function generates the right +// failure message. +TEST(UnexpectedCallTest, GeneartesFailureForNonVoidFunction) { +  MockB b1; +  EXPECT_CALL(b1, DoB(1)); +  b1.DoB(1); +  EXPECT_NONFATAL_FAILURE( +      b1.DoB(2), +      "Unexpected mock function call - returning default value.\n" +      "    Function call: DoB(2)\n" +      "          Returns: 0\n" +      "Google Mock tried the following 1 expectation, but it didn't match:"); +  EXPECT_NONFATAL_FAILURE( +      b1.DoB(2), +      "  Expected arg #0: is equal to 1\n" +      "           Actual: 2\n" +      "         Expected: to be called once\n" +      "           Actual: called once - saturated and active"); +} + +// Tests that Google Mock explains that an retired expectation doesn't +// match the call. +TEST(UnexpectedCallTest, RetiredExpectation) { +  MockB b; +  EXPECT_CALL(b, DoB(1)) +      .RetiresOnSaturation(); + +  b.DoB(1); +  EXPECT_NONFATAL_FAILURE( +      b.DoB(1), +      "         Expected: the expectation is active\n" +      "           Actual: it is retired"); +} + +// Tests that Google Mock explains that an expectation that doesn't +// match the arguments doesn't match the call. +TEST(UnexpectedCallTest, UnmatchedArguments) { +  MockB b; +  EXPECT_CALL(b, DoB(1)); + +  EXPECT_NONFATAL_FAILURE( +      b.DoB(2), +      "  Expected arg #0: is equal to 1\n" +      "           Actual: 2\n"); +  b.DoB(1); +} + +#ifdef GMOCK_HAS_REGEX + +// Tests that Google Mock explains that an expectation with +// unsatisfied pre-requisites doesn't match the call. +TEST(UnexpectedCallTest, UnsatisifiedPrerequisites) { +  Sequence s1, s2; +  MockB b; +  EXPECT_CALL(b, DoB(1)) +      .InSequence(s1); +  EXPECT_CALL(b, DoB(2)) +      .Times(AnyNumber()) +      .InSequence(s1); +  EXPECT_CALL(b, DoB(3)) +      .InSequence(s2); +  EXPECT_CALL(b, DoB(4)) +      .InSequence(s1, s2); + +  ::testing::TestPartResultArray failures; +  { +    ::testing::ScopedFakeTestPartResultReporter reporter(&failures); +    b.DoB(4); +    // Now 'failures' contains the Google Test failures generated by +    // the above statement. +  } + +  // There should be one non-fatal failure. +  ASSERT_EQ(1, failures.size()); +  const ::testing::TestPartResult& r = failures.GetTestPartResult(0); +  EXPECT_EQ(::testing::TPRT_NONFATAL_FAILURE, r.type()); + +  // Verifies that the failure message contains the two unsatisfied +  // pre-requisites but not the satisfied one. +  const char* const pattern = +#if GMOCK_USES_PCRE +      // PCRE has trouble using (.|\n) to match any character, but +      // supports the (?s) prefix for using . to match any character. +      "(?s)the following immediate pre-requisites are not satisfied:\n" +      ".*: pre-requisite #0\n" +      ".*: pre-requisite #1"; +#else +      // POSIX RE doesn't understand the (?s) prefix, but has no trouble +      // with (.|\n). +      "the following immediate pre-requisites are not satisfied:\n" +      "(.|\n)*: pre-requisite #0\n" +      "(.|\n)*: pre-requisite #1"; +#endif  // GMOCK_USES_PCRE + +  EXPECT_TRUE( +      ::testing::internal::RE::PartialMatch(r.message(), pattern)) +              << " where the message is " << r.message(); +  b.DoB(1); +  b.DoB(3); +  b.DoB(4); +} + +#endif  // GMOCK_HAS_REGEX + +// Tests that an excessive call (one whose arguments match the +// matchers but is called too many times) performs the default action. +TEST(ExcessiveCallTest, DoesDefaultAction) { +  // When there is an ON_CALL() statement, the action specified by it +  // should be taken. +  MockA a; +  ON_CALL(a, Binary(_, _)) +      .WillByDefault(Return(true)); +  EXPECT_CALL(a, Binary(0, 0)); +  a.Binary(0, 0); +  bool result = false; +  EXPECT_NONFATAL_FAILURE(result = a.Binary(0, 0), +                          "Mock function called more times than expected"); +  EXPECT_TRUE(result); + +  // When there is no ON_CALL(), the default value for the return type +  // should be returned. +  MockB b; +  EXPECT_CALL(b, DoB(0)) +      .Times(0); +  int n = -1; +  EXPECT_NONFATAL_FAILURE(n = b.DoB(0), +                          "Mock function called more times than expected"); +  EXPECT_EQ(0, n); +} + +// Tests that when a void function is called too many times, +// the failure message contains the argument values. +TEST(ExcessiveCallTest, GeneratesFailureForVoidFunction) { +  MockA a; +  EXPECT_CALL(a, DoA(_)) +      .Times(0); +  EXPECT_NONFATAL_FAILURE( +      a.DoA(9), +      "Mock function called more times than expected - returning directly.\n" +      "    Function call: DoA(9)\n" +      "         Expected: to be never called\n" +      "           Actual: called once - over-saturated and active"); +} + +// Tests that when a non-void function is called too many times, the +// failure message contains the argument values and the return value. +TEST(ExcessiveCallTest, GeneratesFailureForNonVoidFunction) { +  MockB b; +  EXPECT_CALL(b, DoB(_)); +  b.DoB(1); +  EXPECT_NONFATAL_FAILURE( +      b.DoB(2), +      "Mock function called more times than expected - " +      "returning default value.\n" +      "    Function call: DoB(2)\n" +      "          Returns: 0\n" +      "         Expected: to be called once\n" +      "           Actual: called twice - over-saturated and active"); +} + +// Tests using sequences. + +TEST(InSequenceTest, AllExpectationInScopeAreInSequence) { +  MockA a; +  { +    InSequence dummy; + +    EXPECT_CALL(a, DoA(1)); +    EXPECT_CALL(a, DoA(2)); +  } + +  EXPECT_NONFATAL_FAILURE({  // NOLINT +    a.DoA(2); +  }, "Unexpected mock function call"); + +  a.DoA(1); +  a.DoA(2); +} + +TEST(InSequenceTest, NestedInSequence) { +  MockA a; +  { +    InSequence dummy; + +    EXPECT_CALL(a, DoA(1)); +    { +      InSequence dummy2; + +      EXPECT_CALL(a, DoA(2)); +      EXPECT_CALL(a, DoA(3)); +    } +  } + +  EXPECT_NONFATAL_FAILURE({  // NOLINT +    a.DoA(1); +    a.DoA(3); +  }, "Unexpected mock function call"); + +  a.DoA(2); +  a.DoA(3); +} + +TEST(InSequenceTest, ExpectationsOutOfScopeAreNotAffected) { +  MockA a; +  { +    InSequence dummy; + +    EXPECT_CALL(a, DoA(1)); +    EXPECT_CALL(a, DoA(2)); +  } +  EXPECT_CALL(a, DoA(3)); + +  EXPECT_NONFATAL_FAILURE({  // NOLINT +    a.DoA(2); +  }, "Unexpected mock function call"); + +  a.DoA(3); +  a.DoA(1); +  a.DoA(2); +} + +// Tests that any order is allowed when no sequence is used. +TEST(SequenceTest, AnyOrderIsOkByDefault) { +  { +    MockA a; +    MockB b; + +    EXPECT_CALL(a, DoA(1)); +    EXPECT_CALL(b, DoB()) +        .Times(AnyNumber()); + +    a.DoA(1); +    b.DoB(); +  } + +  {  // NOLINT +    MockA a; +    MockB b; + +    EXPECT_CALL(a, DoA(1)); +    EXPECT_CALL(b, DoB()) +        .Times(AnyNumber()); + +    b.DoB(); +    a.DoA(1); +  } +} + +#ifdef GTEST_HAS_DEATH_TEST + +// Tests that the calls must be in strict order when a complete order +// is specified. +TEST(SequenceTest, CallsMustBeInStrictOrderWhenSaidSo) { +  MockA a; +  Sequence s; + +  EXPECT_CALL(a, ReturnResult(1)) +      .InSequence(s) +      .WillOnce(Return(Result())); + +  EXPECT_CALL(a, ReturnResult(2)) +      .InSequence(s) +      .WillOnce(Return(Result())); + +  EXPECT_CALL(a, ReturnResult(3)) +      .InSequence(s) +      .WillOnce(Return(Result())); + +  EXPECT_DEATH({  // NOLINT +    a.ReturnResult(1); +    a.ReturnResult(3); +    a.ReturnResult(2); +  }, ""); + +  EXPECT_DEATH({  // NOLINT +    a.ReturnResult(2); +    a.ReturnResult(1); +    a.ReturnResult(3); +  }, ""); + +  a.ReturnResult(1); +  a.ReturnResult(2); +  a.ReturnResult(3); +} + +// Tests specifying a DAG using multiple sequences. +TEST(SequenceTest, CallsMustConformToSpecifiedDag) { +  MockA a; +  MockB b; +  Sequence x, y; + +  EXPECT_CALL(a, ReturnResult(1)) +      .InSequence(x) +      .WillOnce(Return(Result())); + +  EXPECT_CALL(b, DoB()) +      .Times(2) +      .InSequence(y); + +  EXPECT_CALL(a, ReturnResult(2)) +      .InSequence(x, y) +      .WillRepeatedly(Return(Result())); + +  EXPECT_CALL(a, ReturnResult(3)) +      .InSequence(x) +      .WillOnce(Return(Result())); + +  EXPECT_DEATH({  // NOLINT +    a.ReturnResult(1); +    b.DoB(); +    a.ReturnResult(2); +  }, ""); + +  EXPECT_DEATH({  // NOLINT +    a.ReturnResult(2); +  }, ""); + +  EXPECT_DEATH({  // NOLINT +    a.ReturnResult(3); +  }, ""); + +  EXPECT_DEATH({  // NOLINT +    a.ReturnResult(1); +    b.DoB(); +    b.DoB(); +    a.ReturnResult(3); +    a.ReturnResult(2); +  }, ""); + +  b.DoB(); +  a.ReturnResult(1); +  b.DoB(); +  a.ReturnResult(3); +} + +#endif  // GTEST_HAS_DEATH_TEST + +TEST(SequenceTest, Retirement) { +  MockA a; +  Sequence s; + +  EXPECT_CALL(a, DoA(1)) +      .InSequence(s); +  EXPECT_CALL(a, DoA(_)) +      .InSequence(s) +      .RetiresOnSaturation(); +  EXPECT_CALL(a, DoA(1)) +      .InSequence(s); + +  a.DoA(1); +  a.DoA(2); +  a.DoA(1); +} + +// Tests that Google Mock correctly handles calls to mock functions +// after a mock object owning one of their pre-requisites has died. + +// Tests that calls that satisfy the original spec are successful. +TEST(DeletingMockEarlyTest, Success1) { +  MockB* const b1 = new MockB; +  MockA* const a = new MockA; +  MockB* const b2 = new MockB; + +  { +    InSequence dummy; +    EXPECT_CALL(*b1, DoB(_)) +        .WillOnce(Return(1)); +    EXPECT_CALL(*a, Binary(_, _)) +        .Times(AnyNumber()) +        .WillRepeatedly(Return(true)); +    EXPECT_CALL(*b2, DoB(_)) +        .Times(AnyNumber()) +        .WillRepeatedly(Return(2)); +  } + +  EXPECT_EQ(1, b1->DoB(1)); +  delete b1; +  // a's pre-requisite has died. +  EXPECT_TRUE(a->Binary(0, 1)); +  delete b2; +  // a's successor has died. +  EXPECT_TRUE(a->Binary(1, 2)); +  delete a; +} + +// Tests that calls that satisfy the original spec are successful. +TEST(DeletingMockEarlyTest, Success2) { +  MockB* const b1 = new MockB; +  MockA* const a = new MockA; +  MockB* const b2 = new MockB; + +  { +    InSequence dummy; +    EXPECT_CALL(*b1, DoB(_)) +        .WillOnce(Return(1)); +    EXPECT_CALL(*a, Binary(_, _)) +        .Times(AnyNumber()); +    EXPECT_CALL(*b2, DoB(_)) +        .Times(AnyNumber()) +        .WillRepeatedly(Return(2)); +  } + +  delete a;  // a is trivially satisfied. +  EXPECT_EQ(1, b1->DoB(1)); +  EXPECT_EQ(2, b2->DoB(2)); +  delete b1; +  delete b2; +} + +// Tests that calls that violates the original spec yield failures. +TEST(DeletingMockEarlyTest, Failure1) { +  MockB* const b1 = new MockB; +  MockA* const a = new MockA; +  MockB* const b2 = new MockB; + +  { +    InSequence dummy; +    EXPECT_CALL(*b1, DoB(_)) +        .WillOnce(Return(1)); +    EXPECT_CALL(*a, Binary(_, _)) +        .Times(AnyNumber()); +    EXPECT_CALL(*b2, DoB(_)) +        .Times(AnyNumber()) +        .WillRepeatedly(Return(2)); +  } + +  delete a;  // a is trivially satisfied. +  EXPECT_NONFATAL_FAILURE({ +    b2->DoB(2); +  }, "Unexpected mock function call"); +  EXPECT_EQ(1, b1->DoB(1)); +  delete b1; +  delete b2; +} + +// Tests that calls that violates the original spec yield failures. +TEST(DeletingMockEarlyTest, Failure2) { +  MockB* const b1 = new MockB; +  MockA* const a = new MockA; +  MockB* const b2 = new MockB; + +  { +    InSequence dummy; +    EXPECT_CALL(*b1, DoB(_)); +    EXPECT_CALL(*a, Binary(_, _)) +        .Times(AnyNumber()); +    EXPECT_CALL(*b2, DoB(_)) +        .Times(AnyNumber()); +  } + +  EXPECT_NONFATAL_FAILURE(delete b1, +                          "Actual: never called"); +  EXPECT_NONFATAL_FAILURE(a->Binary(0, 1), +                          "Unexpected mock function call"); +  EXPECT_NONFATAL_FAILURE(b2->DoB(1), +                          "Unexpected mock function call"); +  delete a; +  delete b2; +} + +class EvenNumberCardinality : public CardinalityInterface { + public: +  // Returns true iff call_count calls will satisfy this cardinality. +  virtual bool IsSatisfiedByCallCount(int call_count) const { +    return call_count % 2 == 0; +  } + +  // Returns true iff call_count calls will saturate this cardinality. +  virtual bool IsSaturatedByCallCount(int call_count) const { return false; } + +  // Describes self to an ostream. +  virtual void DescribeTo(::std::ostream* os) const { +    *os << "called even number of times"; +  } +}; + +Cardinality EvenNumber() { +  return Cardinality(new EvenNumberCardinality); +} + +TEST(ExpectationBaseTest, +     AllPrerequisitesAreSatisfiedWorksForNonMonotonicCardinality) { +  MockA* a = new MockA; +  Sequence s; + +  EXPECT_CALL(*a, DoA(1)) +      .Times(EvenNumber()) +      .InSequence(s); +  EXPECT_CALL(*a, DoA(2)) +      .Times(AnyNumber()) +      .InSequence(s); +  EXPECT_CALL(*a, DoA(3)) +      .Times(AnyNumber()); + +  a->DoA(3); +  a->DoA(1); +  EXPECT_NONFATAL_FAILURE(a->DoA(2), "Unexpected mock function call"); +  EXPECT_NONFATAL_FAILURE(delete a, "to be called even number of times"); +} + +// The following tests verify the message generated when a mock +// function is called. + +struct Printable { +}; + +inline void operator<<(::std::ostream& os, const Printable&) { +  os << "Printable"; +} + +struct Unprintable { +  Unprintable() : value(0) {} +  int value; +}; + +class MockC { + public: +  MOCK_METHOD6(VoidMethod, void(bool cond, int n, string s, void* p, +                                const Printable& x, Unprintable y)); +  MOCK_METHOD0(NonVoidMethod, int());  // NOLINT +}; + +// TODO(wan@google.com): find a way to re-enable these tests. +#if 0 + +// Tests that an uninteresting mock function call generates a warning +// containing the stack trace. +TEST(FunctionCallMessageTest, UninterestingCallGeneratesFyiWithStackTrace) { +  MockC c; +  CaptureTestStdout(); +  c.VoidMethod(false, 5, "Hi", NULL, Printable(), Unprintable()); +  const string& output = GetCapturedTestStdout(); +  EXPECT_PRED_FORMAT2(IsSubstring, "GMOCK WARNING", output); +  EXPECT_PRED_FORMAT2(IsSubstring, "Stack trace:", output); +#ifndef NDEBUG +  // We check the stack trace content in dbg-mode only, as opt-mode +  // may inline the call we are interested in seeing. + +  // Verifies that a void mock function's name appears in the stack +  // trace. +  EXPECT_PRED_FORMAT2(IsSubstring, "::MockC::VoidMethod(", output); + +  // Verifies that a non-void mock function's name appears in the +  // stack trace. +  CaptureTestStdout(); +  c.NonVoidMethod(); +  const string& output2 = GetCapturedTestStdout(); +  EXPECT_PRED_FORMAT2(IsSubstring, "::MockC::NonVoidMethod(", output2); +#endif  // NDEBUG +} + +// Tests that an uninteresting mock function call causes the function +// arguments and return value to be printed. +TEST(FunctionCallMessageTest, UninterestingCallPrintsArgumentsAndReturnValue) { +  // A non-void mock function. +  MockB b; +  CaptureTestStdout(); +  b.DoB(); +  const string& output1 = GetCapturedTestStdout(); +  EXPECT_PRED_FORMAT2( +      IsSubstring, +      "Uninteresting mock function call - returning default value.\n" +      "    Function call: DoB()\n" +      "          Returns: 0\n", output1); +  // Makes sure the return value is printed. + +  // A void mock function. +  MockC c; +  CaptureTestStdout(); +  c.VoidMethod(false, 5, "Hi", NULL, Printable(), Unprintable()); +  const string& output2 = GetCapturedTestStdout(); +  EXPECT_PRED2(RE::PartialMatch, output2, +               "Uninteresting mock function call - returning directly\\.\n" +               "    Function call: VoidMethod" +               "\\(false, 5, \"Hi\", NULL, @0x\\w+ " +               "Printable, 4-byte object <0000 0000>\\)"); +  // A void function has no return value to print. +} + +// Tests how the --gmock_verbose flag affects Google Mock's output. + +class GMockVerboseFlagTest : public testing::Test { + public: +  // Verifies that the given Google Mock output is correct.  (When +  // should_print is true, the output should match the given regex and +  // contain the given function name in the stack trace.  When it's +  // false, the output should be empty.) +  void VerifyOutput(const string& output, bool should_print, +                    const string& regex, +                    const string& function_name) { +    if (should_print) { +      EXPECT_PRED2(RE::PartialMatch, output, regex); +#ifndef NDEBUG +      // We check the stack trace content in dbg-mode only, as opt-mode +      // may inline the call we are interested in seeing. +      EXPECT_PRED_FORMAT2(IsSubstring, function_name, output); +#endif  // NDEBUG +    } else { +      EXPECT_EQ("", output); +    } +  } + +  // Tests how the flag affects expected calls. +  void TestExpectedCall(bool should_print) { +    MockA a; +    EXPECT_CALL(a, DoA(5)); +    EXPECT_CALL(a, Binary(_, 1)) +        .WillOnce(Return(true)); + +    // A void-returning function. +    CaptureTestStdout(); +    a.DoA(5); +    VerifyOutput( +        GetCapturedTestStdout(), +        should_print, +        "Expected mock function call\\.\n" +        "    Function call: DoA\\(5\\)\n" +        "Stack trace:", +        "MockA::DoA"); + +    // A non-void-returning function. +    CaptureTestStdout(); +    a.Binary(2, 1); +    VerifyOutput( +        GetCapturedTestStdout(), +        should_print, +        "Expected mock function call\\.\n" +        "    Function call: Binary\\(2, 1\\)\n" +        "          Returns: true\n" +        "Stack trace:", +        "MockA::Binary"); +  } + +  // Tests how the flag affects uninteresting calls. +  void TestUninterestingCall(bool should_print) { +    MockA a; + +    // A void-returning function. +    CaptureTestStdout(); +    a.DoA(5); +    VerifyOutput( +        GetCapturedTestStdout(), +        should_print, +        "\nGMOCK WARNING:\n" +        "Uninteresting mock function call - returning directly\\.\n" +        "    Function call: DoA\\(5\\)\n" +        "Stack trace:\n" +        "[\\s\\S]*", +        "MockA::DoA"); + +    // A non-void-returning function. +    CaptureTestStdout(); +    a.Binary(2, 1); +    VerifyOutput( +        GetCapturedTestStdout(), +        should_print, +        "\nGMOCK WARNING:\n" +        "Uninteresting mock function call - returning default value\\.\n" +        "    Function call: Binary\\(2, 1\\)\n" +        "          Returns: false\n" +        "Stack trace:\n" +        "[\\s\\S]*", +        "MockA::Binary"); +  } +}; + +// Tests that --gmock_verbose=info causes both expected and +// uninteresting calls to be reported. +TEST_F(GMockVerboseFlagTest, Info) { +  GMOCK_FLAG(verbose) = kInfoVerbosity; +  TestExpectedCall(true); +  TestUninterestingCall(true); +} + +// Tests that --gmock_verbose=warning causes uninteresting calls to be +// reported. +TEST_F(GMockVerboseFlagTest, Warning) { +  GMOCK_FLAG(verbose) = kWarningVerbosity; +  TestExpectedCall(false); +  TestUninterestingCall(true); +} + +// Tests that --gmock_verbose=warning causes neither expected nor +// uninteresting calls to be reported. +TEST_F(GMockVerboseFlagTest, Error) { +  GMOCK_FLAG(verbose) = kErrorVerbosity; +  TestExpectedCall(false); +  TestUninterestingCall(false); +} + +// Tests that --gmock_verbose=SOME_INVALID_VALUE has the same effect +// as --gmock_verbose=warning. +TEST_F(GMockVerboseFlagTest, InvalidFlagIsTreatedAsWarning) { +  GMOCK_FLAG(verbose) = "invalid";  // Treated as "warning". +  TestExpectedCall(false); +  TestUninterestingCall(true); +} + +#endif  // 0 + + +// Tests that we can verify and clear a mock object's expectations +// when none of its methods has expectations. +TEST(VerifyAndClearExpectationsTest, NoMethodHasExpectations) { +  MockB b; +  ASSERT_TRUE(Mock::VerifyAndClearExpectations(&b)); + +  // There should be no expectations on the methods now, so we can +  // freely call them. +  EXPECT_EQ(0, b.DoB()); +  EXPECT_EQ(0, b.DoB(1)); +} + +// Tests that we can verify and clear a mock object's expectations +// when some, but not all, of its methods have expectations *and* the +// verification succeeds. +TEST(VerifyAndClearExpectationsTest, SomeMethodsHaveExpectationsAndSucceed) { +  MockB b; +  EXPECT_CALL(b, DoB()) +      .WillOnce(Return(1)); +  b.DoB(); +  ASSERT_TRUE(Mock::VerifyAndClearExpectations(&b)); + +  // There should be no expectations on the methods now, so we can +  // freely call them. +  EXPECT_EQ(0, b.DoB()); +  EXPECT_EQ(0, b.DoB(1)); +} + +// Tests that we can verify and clear a mock object's expectations +// when some, but not all, of its methods have expectations *and* the +// verification fails. +TEST(VerifyAndClearExpectationsTest, SomeMethodsHaveExpectationsAndFail) { +  MockB b; +  EXPECT_CALL(b, DoB()) +      .WillOnce(Return(1)); +  bool result; +  EXPECT_NONFATAL_FAILURE(result = Mock::VerifyAndClearExpectations(&b), +                          "Actual: never called"); +  ASSERT_FALSE(result); + +  // There should be no expectations on the methods now, so we can +  // freely call them. +  EXPECT_EQ(0, b.DoB()); +  EXPECT_EQ(0, b.DoB(1)); +} + +// Tests that we can verify and clear a mock object's expectations +// when all of its methods have expectations. +TEST(VerifyAndClearExpectationsTest, AllMethodsHaveExpectations) { +  MockB b; +  EXPECT_CALL(b, DoB()) +      .WillOnce(Return(1)); +  EXPECT_CALL(b, DoB(_)) +      .WillOnce(Return(2)); +  b.DoB(); +  b.DoB(1); +  ASSERT_TRUE(Mock::VerifyAndClearExpectations(&b)); + +  // There should be no expectations on the methods now, so we can +  // freely call them. +  EXPECT_EQ(0, b.DoB()); +  EXPECT_EQ(0, b.DoB(1)); +} + +// Tests that we can verify and clear a mock object's expectations +// when a method has more than one expectation. +TEST(VerifyAndClearExpectationsTest, AMethodHasManyExpectations) { +  MockB b; +  EXPECT_CALL(b, DoB(0)) +      .WillOnce(Return(1)); +  EXPECT_CALL(b, DoB(_)) +      .WillOnce(Return(2)); +  b.DoB(1); +  bool result; +  EXPECT_NONFATAL_FAILURE(result = Mock::VerifyAndClearExpectations(&b), +                          "Actual: never called"); +  ASSERT_FALSE(result); + +  // There should be no expectations on the methods now, so we can +  // freely call them. +  EXPECT_EQ(0, b.DoB()); +  EXPECT_EQ(0, b.DoB(1)); +} + +// Tests that we can call VerifyAndClearExpectations() on the same +// mock object multiple times. +TEST(VerifyAndClearExpectationsTest, CanCallManyTimes) { +  MockB b; +  EXPECT_CALL(b, DoB()); +  b.DoB(); +  Mock::VerifyAndClearExpectations(&b); + +  EXPECT_CALL(b, DoB(_)) +      .WillOnce(Return(1)); +  b.DoB(1); +  Mock::VerifyAndClearExpectations(&b); +  Mock::VerifyAndClearExpectations(&b); + +  // There should be no expectations on the methods now, so we can +  // freely call them. +  EXPECT_EQ(0, b.DoB()); +  EXPECT_EQ(0, b.DoB(1)); +} + +// Tests that we can clear a mock object's default actions when none +// of its methods has default actions. +TEST(VerifyAndClearTest, NoMethodHasDefaultActions) { +  MockB b; +  // If this crashes or generates a failure, the test will catch it. +  Mock::VerifyAndClear(&b); +  EXPECT_EQ(0, b.DoB()); +} + +// Tests that we can clear a mock object's default actions when some, +// but not all of its methods have default actions. +TEST(VerifyAndClearTest, SomeMethodsHaveDefaultActions) { +  MockB b; +  ON_CALL(b, DoB()) +      .WillByDefault(Return(1)); + +  Mock::VerifyAndClear(&b); + +  // Verifies that the default action of int DoB() was removed. +  EXPECT_EQ(0, b.DoB()); +} + +// Tests that we can clear a mock object's default actions when all of +// its methods have default actions. +TEST(VerifyAndClearTest, AllMethodsHaveDefaultActions) { +  MockB b; +  ON_CALL(b, DoB()) +      .WillByDefault(Return(1)); +  ON_CALL(b, DoB(_)) +      .WillByDefault(Return(2)); + +  Mock::VerifyAndClear(&b); + +  // Verifies that the default action of int DoB() was removed. +  EXPECT_EQ(0, b.DoB()); + +  // Verifies that the default action of int DoB(int) was removed. +  EXPECT_EQ(0, b.DoB(0)); +} + +// Tests that we can clear a mock object's default actions when a +// method has more than one ON_CALL() set on it. +TEST(VerifyAndClearTest, AMethodHasManyDefaultActions) { +  MockB b; +  ON_CALL(b, DoB(0)) +      .WillByDefault(Return(1)); +  ON_CALL(b, DoB(_)) +      .WillByDefault(Return(2)); + +  Mock::VerifyAndClear(&b); + +  // Verifies that the default actions (there are two) of int DoB(int) +  // were removed. +  EXPECT_EQ(0, b.DoB(0)); +  EXPECT_EQ(0, b.DoB(1)); +} + +// Tests that we can call VerifyAndClear() on a mock object multiple +// times. +TEST(VerifyAndClearTest, CanCallManyTimes) { +  MockB b; +  ON_CALL(b, DoB()) +      .WillByDefault(Return(1)); +  Mock::VerifyAndClear(&b); +  Mock::VerifyAndClear(&b); + +  ON_CALL(b, DoB(_)) +      .WillByDefault(Return(1)); +  Mock::VerifyAndClear(&b); + +  EXPECT_EQ(0, b.DoB()); +  EXPECT_EQ(0, b.DoB(1)); +} + +// Tests that VerifyAndClear() works when the verification succeeds. +TEST(VerifyAndClearTest, Success) { +  MockB b; +  ON_CALL(b, DoB()) +      .WillByDefault(Return(1)); +  EXPECT_CALL(b, DoB(1)) +      .WillOnce(Return(2)); + +  b.DoB(); +  b.DoB(1); +  ASSERT_TRUE(Mock::VerifyAndClear(&b)); + +  // There should be no expectations on the methods now, so we can +  // freely call them. +  EXPECT_EQ(0, b.DoB()); +  EXPECT_EQ(0, b.DoB(1)); +} + +// Tests that VerifyAndClear() works when the verification fails. +TEST(VerifyAndClearTest, Failure) { +  MockB b; +  ON_CALL(b, DoB(_)) +      .WillByDefault(Return(1)); +  EXPECT_CALL(b, DoB()) +      .WillOnce(Return(2)); + +  b.DoB(1); +  bool result; +  EXPECT_NONFATAL_FAILURE(result = Mock::VerifyAndClear(&b), +                          "Actual: never called"); +  ASSERT_FALSE(result); + +  // There should be no expectations on the methods now, so we can +  // freely call them. +  EXPECT_EQ(0, b.DoB()); +  EXPECT_EQ(0, b.DoB(1)); +} + +// Tests that VerifyAndClear() works when the default actions and +// expectations are set on a const mock object. +TEST(VerifyAndClearTest, Const) { +  MockB b; +  ON_CALL(Const(b), DoB()) +      .WillByDefault(Return(1)); + +  EXPECT_CALL(Const(b), DoB()) +      .WillOnce(DoDefault()) +      .WillOnce(Return(2)); + +  b.DoB(); +  b.DoB(); +  ASSERT_TRUE(Mock::VerifyAndClear(&b)); + +  // There should be no expectations on the methods now, so we can +  // freely call them. +  EXPECT_EQ(0, b.DoB()); +  EXPECT_EQ(0, b.DoB(1)); +} + +// Tests that we can set default actions and expectations on a mock +// object after VerifyAndClear() has been called on it. +TEST(VerifyAndClearTest, CanSetDefaultActionsAndExpectationsAfterwards) { +  MockB b; +  ON_CALL(b, DoB()) +      .WillByDefault(Return(1)); +  EXPECT_CALL(b, DoB(_)) +      .WillOnce(Return(2)); +  b.DoB(1); + +  Mock::VerifyAndClear(&b); + +  EXPECT_CALL(b, DoB()) +      .WillOnce(Return(3)); +  ON_CALL(b, DoB(_)) +      .WillByDefault(Return(4)); + +  EXPECT_EQ(3, b.DoB()); +  EXPECT_EQ(4, b.DoB(1)); +} + +// Tests that calling VerifyAndClear() on one mock object does not +// affect other mock objects (either of the same type or not). +TEST(VerifyAndClearTest, DoesNotAffectOtherMockObjects) { +  MockA a; +  MockB b1; +  MockB b2; + +  ON_CALL(a, Binary(_, _)) +      .WillByDefault(Return(true)); +  EXPECT_CALL(a, Binary(_, _)) +      .WillOnce(DoDefault()) +      .WillOnce(Return(false)); + +  ON_CALL(b1, DoB()) +      .WillByDefault(Return(1)); +  EXPECT_CALL(b1, DoB(_)) +      .WillOnce(Return(2)); + +  ON_CALL(b2, DoB()) +      .WillByDefault(Return(3)); +  EXPECT_CALL(b2, DoB(_)); + +  b2.DoB(0); +  Mock::VerifyAndClear(&b2); + +  // Verifies that the default actions and expectations of a and b1 +  // are still in effect. +  EXPECT_TRUE(a.Binary(0, 0)); +  EXPECT_FALSE(a.Binary(0, 0)); + +  EXPECT_EQ(1, b1.DoB()); +  EXPECT_EQ(2, b1.DoB(0)); +} + +// Tests that a mock function's action can call a mock function +// (either the same function or a different one) either as an explicit +// action or as a default action without causing a dead lock.  It +// verifies that the action is not performed inside the critical +// section. + +void Helper(MockC* c) { +  c->NonVoidMethod(); +} + +}  // namespace diff --git a/test/gmock_link_test.cc b/test/gmock_link_test.cc new file mode 100644 index 00000000..8a60e8bf --- /dev/null +++ b/test/gmock_link_test.cc @@ -0,0 +1,37 @@ +// 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. +// +// Author: wan@google.com (Zhanyong Wan) + +// This file is for verifying that a header file defining a mock class +// can be included in multiple translation units without causing a +// link error.  It doesn't have to actually do anything - we are only +// checking that the test links correctly. + +#include "test/gmock-sample.h" diff --git a/test/gmock_output_test.py b/test/gmock_output_test.py new file mode 100755 index 00000000..f7f37abb --- /dev/null +++ b/test/gmock_output_test.py @@ -0,0 +1,200 @@ +#!/usr/bin/env python +# +# 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. + +"""Tests the text output of Google C++ Mocking Framework. + +SYNOPSIS +       gmock_output_test.py --gmock_build_dir=BUILD/DIR --gengolden +         # where BUILD/DIR contains the built gmock_output_test_ file. +       gmock_output_test.py --gengolden +       gmock_output_test.py +""" + +__author__ = 'wan@google.com (Zhanyong Wan)' + +import gmock_test_utils +import os +import re +import string +import sys +import unittest + + +# The flag for generating the golden file +GENGOLDEN_FLAG = '--gengolden' + +IS_WINDOWS = os.name == 'nt' + +if IS_WINDOWS: +  PROGRAM = r'..\build.dbg\gmock_output_test_.exe' +else: +  PROGRAM = 'gmock_output_test_' + +PROGRAM_PATH = os.path.join(gmock_test_utils.GetBuildDir(), PROGRAM) +COMMAND = PROGRAM_PATH + ' --gtest_stack_trace_depth=0' +GOLDEN_NAME = 'gmock_output_test_golden.txt' +GOLDEN_PATH = os.path.join(gmock_test_utils.GetSourceDir(), +                           GOLDEN_NAME) + +def ToUnixLineEnding(s): +  """Changes all Windows/Mac line endings in s to UNIX line endings.""" + +  return s.replace('\r\n', '\n').replace('\r', '\n') + + +def RemoveReportHeaderAndFooter(output): +  """Removes Google Test result report's header and footer from the output.""" + +  output = re.sub(r'.*gtest_main.*\n', '', output) +  output = re.sub(r'\[.*\d+ tests.*\n', '', output) +  output = re.sub(r'\[.* test environment .*\n', '', output) +  output = re.sub(r'\[=+\] \d+ tests .* ran.*', '', output) +  output = re.sub(r'.* FAILED TESTS\n', '', output) +  return output + + +def RemoveLocations(output): +  """Removes all file location info from a Google Test program's output. + +  Args: +       output:  the output of a Google Test program. + +  Returns: +       output with all file location info (in the form of +       'DIRECTORY/FILE_NAME:LINE_NUMBER: 'or +       'DIRECTORY\\FILE_NAME(LINE_NUMBER): ') replaced by +       'FILE:#: '. +  """ + +  return re.sub(r'.*[/\\](.+)(\:\d+|\(\d+\))\:', 'FILE:#:', output) + + +def NormalizeErrorMarker(output): +  """Normalizes the error marker, which is different on Windows vs on Linux.""" + +  return re.sub(r' error: ', ' Failure\n', output) + + +def RemoveMemoryAddresses(output): +  """Removes memory addresses from the test output.""" + +  return re.sub(r'@\w+', '@0x#', output) + + +def NormalizeOutput(output): +  """Normalizes output (the output of gmock_output_test_.exe).""" + +  output = ToUnixLineEnding(output) +  output = RemoveReportHeaderAndFooter(output) +  output = NormalizeErrorMarker(output) +  output = RemoveLocations(output) +  output = RemoveMemoryAddresses(output) +  return output + + +def IterShellCommandOutput(cmd, stdin_string=None): +  """Runs a command in a sub-process, and iterates the lines in its STDOUT. + +  Args: + +    cmd:           The shell command. +    stdin_string:  The string to be fed to the STDIN of the sub-process; +                   If None, the sub-process will inherit the STDIN +                   from the parent process. +  """ + +  # Spawns cmd in a sub-process, and gets its standard I/O file objects. +  stdin_file, stdout_file = os.popen2(cmd, 'b') + +  # If the caller didn't specify a string for STDIN, gets it from the +  # parent process. +  if stdin_string is None: +    stdin_string = sys.stdin.read() + +  # Feeds the STDIN string to the sub-process. +  stdin_file.write(stdin_string) +  stdin_file.close() + +  while True: +    line = stdout_file.readline() +    if not line:  # EOF +      stdout_file.close() +      break + +    yield line + + +def GetShellCommandOutput(cmd, stdin_string=None): +  """Runs a command in a sub-process, and returns its STDOUT in a string. + +  Args: + +    cmd:           The shell command. +    stdin_string:  The string to be fed to the STDIN of the sub-process; +                   If None, the sub-process will inherit the STDIN +                   from the parent process. +  """ + +  lines = list(IterShellCommandOutput(cmd, stdin_string)) +  return string.join(lines, '') + + +def GetCommandOutput(cmd): +  """Runs a command and returns its output with all file location +  info stripped off. + +  Args: +    cmd:  the shell command. +  """ + +  # Disables exception pop-ups on Windows. +  os.environ['GTEST_CATCH_EXCEPTIONS'] = '1' +  return NormalizeOutput(GetShellCommandOutput(cmd, '')) + + +class GMockOutputTest(unittest.TestCase): +  def testOutput(self): +    output = GetCommandOutput(COMMAND) +    golden_file = open(GOLDEN_PATH, 'rb') +    golden = golden_file.read() +    golden_file.close() + +    self.assertEquals(golden, output) + + +if __name__ == '__main__': +  if sys.argv[1:] == [GENGOLDEN_FLAG]: +    output = GetCommandOutput(COMMAND) +    golden_file = open(GOLDEN_PATH, 'wb') +    golden_file.write(output) +    golden_file.close() +  else: +    gmock_test_utils.Main() diff --git a/test/gmock_output_test_.cc b/test/gmock_output_test_.cc new file mode 100644 index 00000000..bb56b7cd --- /dev/null +++ b/test/gmock_output_test_.cc @@ -0,0 +1,241 @@ +// 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. +// +// Author: wan@google.com (Zhanyong Wan) + +// Tests Google Mock's output in various scenarios.  This ensures that +// Google Mock's messages are readable and useful. + +#include <gmock/gmock.h> + +#include <stdio.h> +#include <string> + +#include <gtest/gtest.h> + +using testing::_; +using testing::Ge; +using testing::InSequence; +using testing::Ref; +using testing::Return; +using testing::Sequence; + +class MockFoo { + public: +  MOCK_METHOD3(Bar, char(const std::string& s, int i, double x)); +  MOCK_METHOD2(Bar2, bool(int x, int y)); +  MOCK_METHOD2(Bar3, void(int x, int y)); +}; + +class GMockOutputTest : public testing::Test { + protected: +  MockFoo foo_; +}; + +TEST_F(GMockOutputTest, ExpectedCall) { +  testing::GMOCK_FLAG(verbose) = "info"; + +  EXPECT_CALL(foo_, Bar2(0, _)); +  foo_.Bar2(0, 0);  // Expected call + +  testing::GMOCK_FLAG(verbose) = "warning"; +} + +TEST_F(GMockOutputTest, ExpectedCallToVoidFunction) { +  testing::GMOCK_FLAG(verbose) = "info"; + +  EXPECT_CALL(foo_, Bar3(0, _)); +  foo_.Bar3(0, 0);  // Expected call + +  testing::GMOCK_FLAG(verbose) = "warning"; +} + +TEST_F(GMockOutputTest, ExplicitActionsRunOut) { +  EXPECT_CALL(foo_, Bar2(_, _)) +      .Times(2) +      .WillOnce(Return(false)); +  foo_.Bar2(2, 2); +  foo_.Bar2(1, 1);  // Explicit actions in EXPECT_CALL run out. +} + +TEST_F(GMockOutputTest, UnexpectedCall) { +  EXPECT_CALL(foo_, Bar2(0, _)); + +  foo_.Bar2(1, 0);  // Unexpected call +  foo_.Bar2(0, 0);  // Expected call +} + +TEST_F(GMockOutputTest, UnexpectedCallToVoidFunction) { +  EXPECT_CALL(foo_, Bar3(0, _)); + +  foo_.Bar3(1, 0);  // Unexpected call +  foo_.Bar3(0, 0);  // Expected call +} + +TEST_F(GMockOutputTest, ExcessiveCall) { +  EXPECT_CALL(foo_, Bar2(0, _)); + +  foo_.Bar2(0, 0);  // Expected call +  foo_.Bar2(0, 1);  // Excessive call +} + +TEST_F(GMockOutputTest, ExcessiveCallToVoidFunction) { +  EXPECT_CALL(foo_, Bar3(0, _)); + +  foo_.Bar3(0, 0);  // Expected call +  foo_.Bar3(0, 1);  // Excessive call +} + +TEST_F(GMockOutputTest, UninterestingCall) { +  foo_.Bar2(0, 1);  // Uninteresting call +} + +TEST_F(GMockOutputTest, UninterestingCallToVoidFunction) { +  foo_.Bar3(0, 1);  // Uninteresting call +} + +TEST_F(GMockOutputTest, RetiredExpectation) { +  EXPECT_CALL(foo_, Bar2(_, _)) +      .RetiresOnSaturation(); +  EXPECT_CALL(foo_, Bar2(0, 0)); + +  foo_.Bar2(1, 1); +  foo_.Bar2(1, 1);  // Matches a retired expectation +  foo_.Bar2(0, 0); +} + +TEST_F(GMockOutputTest, UnsatisfiedPrerequisite) { +  { +    InSequence s; +    EXPECT_CALL(foo_, Bar(_, 0, _)); +    EXPECT_CALL(foo_, Bar2(0, 0)); +    EXPECT_CALL(foo_, Bar2(1, _)); +  } + +  foo_.Bar2(1, 0);  // Has one immediate unsatisfied pre-requisite +  foo_.Bar("Hi", 0, 0); +  foo_.Bar2(0, 0); +  foo_.Bar2(1, 0); +} + +TEST_F(GMockOutputTest, UnsatisfiedPrerequisites) { +  Sequence s1, s2; + +  EXPECT_CALL(foo_, Bar(_, 0, _)) +      .InSequence(s1); +  EXPECT_CALL(foo_, Bar2(0, 0)) +      .InSequence(s2); +  EXPECT_CALL(foo_, Bar2(1, _)) +      .InSequence(s1, s2); + +  foo_.Bar2(1, 0);  // Has two immediate unsatisfied pre-requisites +  foo_.Bar("Hi", 0, 0); +  foo_.Bar2(0, 0); +  foo_.Bar2(1, 0); +} + +TEST_F(GMockOutputTest, UnsatisfiedExpectation) { +  EXPECT_CALL(foo_, Bar(_, _, _)); +  EXPECT_CALL(foo_, Bar2(0, _)) +      .Times(2); + +  foo_.Bar2(0, 1); +} + +TEST_F(GMockOutputTest, MismatchArguments) { +  const std::string s = "Hi"; +  EXPECT_CALL(foo_, Bar(Ref(s), _, Ge(0))); + +  foo_.Bar("Ho", 0, -0.1);  // Mismatch arguments +  foo_.Bar(s, 0, 0); +} + +TEST_F(GMockOutputTest, MismatchWithArguments) { +  EXPECT_CALL(foo_, Bar2(Ge(2), Ge(1))) +      .WithArguments(Ge()); + +  foo_.Bar2(2, 3);  // Mismatch WithArguments() +  foo_.Bar2(2, 1); +} + +TEST_F(GMockOutputTest, MismatchArgumentsAndWithArguments) { +  EXPECT_CALL(foo_, Bar2(Ge(2), Ge(1))) +      .WithArguments(Ge()); + +  foo_.Bar2(1, 3);  // Mismatch arguments and mismatch WithArguments() +  foo_.Bar2(2, 1); +} + +TEST_F(GMockOutputTest, UnexpectedCallWithDefaultAction) { +  ON_CALL(foo_, Bar2(_, _)) +      .WillByDefault(Return(true));   // Default action #1 +  ON_CALL(foo_, Bar2(1, _)) +      .WillByDefault(Return(false));  // Default action #2 + +  EXPECT_CALL(foo_, Bar2(2, 2)); +  foo_.Bar2(1, 0);  // Unexpected call, takes default action #2. +  foo_.Bar2(0, 0);  // Unexpected call, takes default action #1. +  foo_.Bar2(2, 2);  // Expected call. +} + +TEST_F(GMockOutputTest, ExcessiveCallWithDefaultAction) { +  ON_CALL(foo_, Bar2(_, _)) +      .WillByDefault(Return(true));   // Default action #1 +  ON_CALL(foo_, Bar2(1, _)) +      .WillByDefault(Return(false));  // Default action #2 + +  EXPECT_CALL(foo_, Bar2(2, 2)); +  EXPECT_CALL(foo_, Bar2(1, 1)); + +  foo_.Bar2(2, 2);  // Expected call. +  foo_.Bar2(2, 2);  // Excessive call, takes default action #1. +  foo_.Bar2(1, 1);  // Expected call. +  foo_.Bar2(1, 1);  // Excessive call, takes default action #2. +} + +TEST_F(GMockOutputTest, UninterestingCallWithDefaultAction) { +  ON_CALL(foo_, Bar2(_, _)) +      .WillByDefault(Return(true));   // Default action #1 +  ON_CALL(foo_, Bar2(1, _)) +      .WillByDefault(Return(false));  // Default action #2 + +  foo_.Bar2(2, 2);  // Uninteresting call, takes default action #1. +  foo_.Bar2(1, 1);  // Uninteresting call, takes default action #2. +} + +TEST_F(GMockOutputTest, ExplicitActionsRunOutWithDefaultAction) { +  ON_CALL(foo_, Bar2(_, _)) +      .WillByDefault(Return(true));   // Default action #1 + +  EXPECT_CALL(foo_, Bar2(_, _)) +      .Times(2) +      .WillOnce(Return(false)); +  foo_.Bar2(2, 2); +  foo_.Bar2(1, 1);  // Explicit actions in EXPECT_CALL run out. +} diff --git a/test/gmock_output_test_golden.txt b/test/gmock_output_test_golden.txt new file mode 100644 index 00000000..374e6659 --- /dev/null +++ b/test/gmock_output_test_golden.txt @@ -0,0 +1,296 @@ +Running main() from gmock_main.cc +[ RUN      ] GMockOutputTest.ExpectedCall + +FILE:#: EXPECT_CALL(foo_, Bar2(0, _)) invoked +Stack trace: + +FILE:#: Expected mock function call. +    Function call: Bar2(0, 0) +          Returns: false +Stack trace: +[       OK ] GMockOutputTest.ExpectedCall +[ RUN      ] GMockOutputTest.ExpectedCallToVoidFunction + +FILE:#: EXPECT_CALL(foo_, Bar3(0, _)) invoked +Stack trace: + +FILE:#: Expected mock function call. +    Function call: Bar3(0, 0) +Stack trace: +[       OK ] GMockOutputTest.ExpectedCallToVoidFunction +[ RUN      ] GMockOutputTest.ExplicitActionsRunOut + +GMOCK WARNING: +FILE:#: Too few actions specified. +Expected to be called twice, but has only 1 WillOnce(). +GMOCK WARNING: +FILE:#: Actions ran out. +Called 2 times, but only 1 WillOnce() is specified - returning default value. +Stack trace: +[       OK ] GMockOutputTest.ExplicitActionsRunOut +[ RUN      ] GMockOutputTest.UnexpectedCall +unknown file: Failure + +Unexpected mock function call - returning default value. +    Function call: Bar2(1, 0) +          Returns: false +Google Mock tried the following 1 expectation, but it didn't match: + +FILE:#:  +  Expected arg #0: is equal to 0 +           Actual: 1 +         Expected: to be called once +           Actual: never called - unsatisfied and active +[  FAILED  ] GMockOutputTest.UnexpectedCall +[ RUN      ] GMockOutputTest.UnexpectedCallToVoidFunction +unknown file: Failure + +Unexpected mock function call - returning directly. +    Function call: Bar3(1, 0) +Google Mock tried the following 1 expectation, but it didn't match: + +FILE:#:  +  Expected arg #0: is equal to 0 +           Actual: 1 +         Expected: to be called once +           Actual: never called - unsatisfied and active +[  FAILED  ] GMockOutputTest.UnexpectedCallToVoidFunction +[ RUN      ] GMockOutputTest.ExcessiveCall +FILE:#: Failure +Mock function called more times than expected - returning default value. +    Function call: Bar2(0, 1) +          Returns: false +         Expected: to be called once +           Actual: called twice - over-saturated and active +[  FAILED  ] GMockOutputTest.ExcessiveCall +[ RUN      ] GMockOutputTest.ExcessiveCallToVoidFunction +FILE:#: Failure +Mock function called more times than expected - returning directly. +    Function call: Bar3(0, 1) +         Expected: to be called once +           Actual: called twice - over-saturated and active +[  FAILED  ] GMockOutputTest.ExcessiveCallToVoidFunction +[ RUN      ] GMockOutputTest.UninterestingCall + +GMOCK WARNING: +Uninteresting mock function call - returning default value. +    Function call: Bar2(0, 1) +          Returns: false +Stack trace: +[       OK ] GMockOutputTest.UninterestingCall +[ RUN      ] GMockOutputTest.UninterestingCallToVoidFunction + +GMOCK WARNING: +Uninteresting mock function call - returning directly. +    Function call: Bar3(0, 1) +Stack trace: +[       OK ] GMockOutputTest.UninterestingCallToVoidFunction +[ RUN      ] GMockOutputTest.RetiredExpectation +unknown file: Failure + +Unexpected mock function call - returning default value. +    Function call: Bar2(1, 1) +          Returns: false +Google Mock tried the following 2 expectations, but none matched: + +FILE:#: tried expectation #0 +         Expected: the expectation is active +           Actual: it is retired +         Expected: to be called once +           Actual: called once - saturated and retired +FILE:#: tried expectation #1 +  Expected arg #0: is equal to 0 +           Actual: 1 +  Expected arg #1: is equal to 0 +           Actual: 1 +         Expected: to be called once +           Actual: never called - unsatisfied and active +[  FAILED  ] GMockOutputTest.RetiredExpectation +[ RUN      ] GMockOutputTest.UnsatisfiedPrerequisite +unknown file: Failure + +Unexpected mock function call - returning default value. +    Function call: Bar2(1, 0) +          Returns: false +Google Mock tried the following 2 expectations, but none matched: + +FILE:#: tried expectation #0 +  Expected arg #0: is equal to 0 +           Actual: 1 +         Expected: to be called once +           Actual: never called - unsatisfied and active +FILE:#: tried expectation #1 +         Expected: all pre-requisites are satisfied +           Actual: the following immediate pre-requisites are not satisfied: +FILE:#: pre-requisite #0 +                   (end of pre-requisites) +         Expected: to be called once +           Actual: never called - unsatisfied and active +[  FAILED  ] GMockOutputTest.UnsatisfiedPrerequisite +[ RUN      ] GMockOutputTest.UnsatisfiedPrerequisites +unknown file: Failure + +Unexpected mock function call - returning default value. +    Function call: Bar2(1, 0) +          Returns: false +Google Mock tried the following 2 expectations, but none matched: + +FILE:#: tried expectation #0 +  Expected arg #0: is equal to 0 +           Actual: 1 +         Expected: to be called once +           Actual: never called - unsatisfied and active +FILE:#: tried expectation #1 +         Expected: all pre-requisites are satisfied +           Actual: the following immediate pre-requisites are not satisfied: +FILE:#: pre-requisite #0 +FILE:#: pre-requisite #1 +                   (end of pre-requisites) +         Expected: to be called once +           Actual: never called - unsatisfied and active +[  FAILED  ] GMockOutputTest.UnsatisfiedPrerequisites +[ RUN      ] GMockOutputTest.UnsatisfiedExpectation +FILE:#: Failure +Actual function call count doesn't match this expectation. +         Expected: to be called twice +           Actual: called once - unsatisfied and active +FILE:#: Failure +Actual function call count doesn't match this expectation. +         Expected: to be called once +           Actual: never called - unsatisfied and active +[  FAILED  ] GMockOutputTest.UnsatisfiedExpectation +[ RUN      ] GMockOutputTest.MismatchArguments +unknown file: Failure + +Unexpected mock function call - returning default value. +    Function call: Bar(@0x# "Ho", 0, -0.1) +          Returns: '\0' +Google Mock tried the following 1 expectation, but it didn't match: + +FILE:#:  +  Expected arg #0: references the variable @0x# "Hi" +           Actual: "Ho" (is located @0x#) +  Expected arg #2: is greater than or equal to 0 +           Actual: -0.1 +         Expected: to be called once +           Actual: never called - unsatisfied and active +[  FAILED  ] GMockOutputTest.MismatchArguments +[ RUN      ] GMockOutputTest.MismatchWithArguments +unknown file: Failure + +Unexpected mock function call - returning default value. +    Function call: Bar2(2, 3) +          Returns: false +Google Mock tried the following 1 expectation, but it didn't match: + +FILE:#:  +         Expected: argument #0 is greater than or equal to argument #1 +           Actual: false +         Expected: to be called once +           Actual: never called - unsatisfied and active +[  FAILED  ] GMockOutputTest.MismatchWithArguments +[ RUN      ] GMockOutputTest.MismatchArgumentsAndWithArguments +unknown file: Failure + +Unexpected mock function call - returning default value. +    Function call: Bar2(1, 3) +          Returns: false +Google Mock tried the following 1 expectation, but it didn't match: + +FILE:#:  +  Expected arg #0: is greater than or equal to 2 +           Actual: 1 +         Expected: argument #0 is greater than or equal to argument #1 +           Actual: false +         Expected: to be called once +           Actual: never called - unsatisfied and active +[  FAILED  ] GMockOutputTest.MismatchArgumentsAndWithArguments +[ RUN      ] GMockOutputTest.UnexpectedCallWithDefaultAction +unknown file: Failure + +Unexpected mock function call - taking default action specified at: +FILE:#: +    Function call: Bar2(1, 0) +          Returns: false +Google Mock tried the following 1 expectation, but it didn't match: + +FILE:#:  +  Expected arg #0: is equal to 2 +           Actual: 1 +  Expected arg #1: is equal to 2 +           Actual: 0 +         Expected: to be called once +           Actual: never called - unsatisfied and active +unknown file: Failure + +Unexpected mock function call - taking default action specified at: +FILE:#: +    Function call: Bar2(0, 0) +          Returns: true +Google Mock tried the following 1 expectation, but it didn't match: + +FILE:#:  +  Expected arg #0: is equal to 2 +           Actual: 0 +  Expected arg #1: is equal to 2 +           Actual: 0 +         Expected: to be called once +           Actual: never called - unsatisfied and active +[  FAILED  ] GMockOutputTest.UnexpectedCallWithDefaultAction +[ RUN      ] GMockOutputTest.ExcessiveCallWithDefaultAction +FILE:#: Failure +Mock function called more times than expected - taking default action specified at: +FILE:#: +    Function call: Bar2(2, 2) +          Returns: true +         Expected: to be called once +           Actual: called twice - over-saturated and active +FILE:#: Failure +Mock function called more times than expected - taking default action specified at: +FILE:#: +    Function call: Bar2(1, 1) +          Returns: false +         Expected: to be called once +           Actual: called twice - over-saturated and active +[  FAILED  ] GMockOutputTest.ExcessiveCallWithDefaultAction +[ RUN      ] GMockOutputTest.UninterestingCallWithDefaultAction + +GMOCK WARNING: +Uninteresting mock function call - taking default action specified at: +FILE:#: +    Function call: Bar2(2, 2) +          Returns: true +Stack trace: + +GMOCK WARNING: +Uninteresting mock function call - taking default action specified at: +FILE:#: +    Function call: Bar2(1, 1) +          Returns: false +Stack trace: +[       OK ] GMockOutputTest.UninterestingCallWithDefaultAction +[ RUN      ] GMockOutputTest.ExplicitActionsRunOutWithDefaultAction + +GMOCK WARNING: +FILE:#: Too few actions specified. +Expected to be called twice, but has only 1 WillOnce(). +GMOCK WARNING: +FILE:#: Actions ran out. +Called 2 times, but only 1 WillOnce() is specified - taking default action specified at: +FILE:#: +Stack trace: +[       OK ] GMockOutputTest.ExplicitActionsRunOutWithDefaultAction +[  FAILED  ] GMockOutputTest.UnexpectedCall +[  FAILED  ] GMockOutputTest.UnexpectedCallToVoidFunction +[  FAILED  ] GMockOutputTest.ExcessiveCall +[  FAILED  ] GMockOutputTest.ExcessiveCallToVoidFunction +[  FAILED  ] GMockOutputTest.RetiredExpectation +[  FAILED  ] GMockOutputTest.UnsatisfiedPrerequisite +[  FAILED  ] GMockOutputTest.UnsatisfiedPrerequisites +[  FAILED  ] GMockOutputTest.UnsatisfiedExpectation +[  FAILED  ] GMockOutputTest.MismatchArguments +[  FAILED  ] GMockOutputTest.MismatchWithArguments +[  FAILED  ] GMockOutputTest.MismatchArgumentsAndWithArguments +[  FAILED  ] GMockOutputTest.UnexpectedCallWithDefaultAction +[  FAILED  ] GMockOutputTest.ExcessiveCallWithDefaultAction + diff --git a/test/gmock_test.cc b/test/gmock_test.cc new file mode 100644 index 00000000..63c3fe8d --- /dev/null +++ b/test/gmock_test.cc @@ -0,0 +1,248 @@ +// 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. +// +// Author: wan@google.com (Zhanyong Wan) + +// Google Mock - a framework for writing C++ mock classes. +// +// This file tests code in gmock.cc. + +#include <gmock/gmock.h> + +#include <string> +#include <gtest/gtest.h> + +using testing::GMOCK_FLAG(verbose); +using testing::InitGoogleMock; +using testing::internal::g_init_gtest_count; + +// Verifies that calling InitGoogleMock() on argv results in new_argv, +// and the gmock_verbose flag's value is set to expected_gmock_verbose. +template <typename Char, int M, int N> +void TestInitGoogleMock(const Char* (&argv)[M], const Char* (&new_argv)[N], +                        const ::std::string& expected_gmock_verbose) { +  const ::std::string old_verbose = GMOCK_FLAG(verbose); + +  int argc = M; +  InitGoogleMock(&argc, const_cast<Char**>(argv)); +  ASSERT_EQ(N, argc) << "The new argv has wrong number of elements."; + +  for (int i = 0; i < N; i++) { +    EXPECT_STREQ(new_argv[i], argv[i]); +  } + +  EXPECT_EQ(expected_gmock_verbose, GMOCK_FLAG(verbose).c_str()); +  GMOCK_FLAG(verbose) = old_verbose;  // Restores the gmock_verbose flag. +} + +TEST(InitGoogleMockTest, ParsesInvalidCommandLine) { +  const char* argv[] = { +    NULL +  }; + +  const char* new_argv[] = { +    NULL +  }; + +  TestInitGoogleMock(argv, new_argv, GMOCK_FLAG(verbose)); +} + +TEST(InitGoogleMockTest, ParsesEmptyCommandLine) { +  const char* argv[] = { +    "foo.exe", +    NULL +  }; + +  const char* new_argv[] = { +    "foo.exe", +    NULL +  }; + +  TestInitGoogleMock(argv, new_argv, GMOCK_FLAG(verbose)); +} + +TEST(InitGoogleMockTest, ParsesSingleFlag) { +  const char* argv[] = { +    "foo.exe", +    "--gmock_verbose=info", +    NULL +  }; + +  const char* new_argv[] = { +    "foo.exe", +    NULL +  }; + +  TestInitGoogleMock(argv, new_argv, "info"); +} + +TEST(InitGoogleMockTest, ParsesUnrecognizedFlag) { +  const char* argv[] = { +    "foo.exe", +    "--non_gmock_flag=blah", +    NULL +  }; + +  const char* new_argv[] = { +    "foo.exe", +    "--non_gmock_flag=blah", +    NULL +  }; + +  TestInitGoogleMock(argv, new_argv, GMOCK_FLAG(verbose)); +} + +TEST(InitGoogleMockTest, ParsesGoogleMockFlagAndUnrecognizedFlag) { +  const char* argv[] = { +    "foo.exe", +    "--non_gmock_flag=blah", +    "--gmock_verbose=error", +    NULL +  }; + +  const char* new_argv[] = { +    "foo.exe", +    "--non_gmock_flag=blah", +    NULL +  }; + +  TestInitGoogleMock(argv, new_argv, "error"); +} + +TEST(InitGoogleMockTest, CallsInitGoogleTest) { +  const int old_init_gtest_count = g_init_gtest_count; +  const char* argv[] = { +    "foo.exe", +    "--non_gmock_flag=blah", +    "--gmock_verbose=error", +    NULL +  }; + +  const char* new_argv[] = { +    "foo.exe", +    "--non_gmock_flag=blah", +    NULL +  }; + +  TestInitGoogleMock(argv, new_argv, "error"); +  EXPECT_EQ(old_init_gtest_count + 1, g_init_gtest_count); +} + +TEST(WideInitGoogleMockTest, ParsesInvalidCommandLine) { +  const wchar_t* argv[] = { +    NULL +  }; + +  const wchar_t* new_argv[] = { +    NULL +  }; + +  TestInitGoogleMock(argv, new_argv, GMOCK_FLAG(verbose)); +} + +TEST(WideInitGoogleMockTest, ParsesEmptyCommandLine) { +  const wchar_t* argv[] = { +    L"foo.exe", +    NULL +  }; + +  const wchar_t* new_argv[] = { +    L"foo.exe", +    NULL +  }; + +  TestInitGoogleMock(argv, new_argv, GMOCK_FLAG(verbose)); +} + +TEST(WideInitGoogleMockTest, ParsesSingleFlag) { +  const wchar_t* argv[] = { +    L"foo.exe", +    L"--gmock_verbose=info", +    NULL +  }; + +  const wchar_t* new_argv[] = { +    L"foo.exe", +    NULL +  }; + +  TestInitGoogleMock(argv, new_argv, "info"); +} + +TEST(WideInitGoogleMockTest, ParsesUnrecognizedFlag) { +  const wchar_t* argv[] = { +    L"foo.exe", +    L"--non_gmock_flag=blah", +    NULL +  }; + +  const wchar_t* new_argv[] = { +    L"foo.exe", +    L"--non_gmock_flag=blah", +    NULL +  }; + +  TestInitGoogleMock(argv, new_argv, GMOCK_FLAG(verbose)); +} + +TEST(WideInitGoogleMockTest, ParsesGoogleMockFlagAndUnrecognizedFlag) { +  const wchar_t* argv[] = { +    L"foo.exe", +    L"--non_gmock_flag=blah", +    L"--gmock_verbose=error", +    NULL +  }; + +  const wchar_t* new_argv[] = { +    L"foo.exe", +    L"--non_gmock_flag=blah", +    NULL +  }; + +  TestInitGoogleMock(argv, new_argv, "error"); +} + +TEST(WideInitGoogleMockTest, CallsInitGoogleTest) { +  const int old_init_gtest_count = g_init_gtest_count; +  const wchar_t* argv[] = { +    L"foo.exe", +    L"--non_gmock_flag=blah", +    L"--gmock_verbose=error", +    NULL +  }; + +  const wchar_t* new_argv[] = { +    L"foo.exe", +    L"--non_gmock_flag=blah", +    NULL +  }; + +  TestInitGoogleMock(argv, new_argv, "error"); +  EXPECT_EQ(old_init_gtest_count + 1, g_init_gtest_count); +} diff --git a/test/gmock_test_utils.py b/test/gmock_test_utils.py new file mode 100755 index 00000000..4c09e39d --- /dev/null +++ b/test/gmock_test_utils.py @@ -0,0 +1,126 @@ +#!/usr/bin/python2.4 +# +# Copyright 2006, 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. + +"""Unit test utilities for Google C++ Mocking Framework.""" + +__author__ = 'wan@google.com (Zhanyong Wan)' + +import os +import sys +import unittest + + +# Initially maps a flag to its default value.  After +# _ParseAndStripGMockFlags() is called, maps a flag to its actual +# value. +_flag_map = {'gmock_source_dir': os.path.dirname(sys.argv[0]), +             'gmock_build_dir': os.path.dirname(sys.argv[0])} +_gmock_flags_are_parsed = False + + +def _ParseAndStripGMockFlags(argv): +  """Parses and strips Google Test flags from argv.  This is idempotent.""" + +  global _gmock_flags_are_parsed +  if _gmock_flags_are_parsed: +    return + +  _gmock_flags_are_parsed = True +  for flag in _flag_map: +    # The environment variable overrides the default value. +    if flag.upper() in os.environ: +      _flag_map[flag] = os.environ[flag.upper()] + +    # The command line flag overrides the environment variable. +    i = 1  # Skips the program name. +    while i < len(argv): +      prefix = '--' + flag + '=' +      if argv[i].startswith(prefix): +        _flag_map[flag] = argv[i][len(prefix):] +        del argv[i] +        break +      else: +        # We don't increment i in case we just found a --gmock_* flag +        # and removed it from argv. +        i += 1 + + +def GetFlag(flag): +  """Returns the value of the given flag.""" + +  # In case GetFlag() is called before Main(), we always call +  # _ParseAndStripGMockFlags() here to make sure the --gmock_* flags +  # are parsed. +  _ParseAndStripGMockFlags(sys.argv) + +  return _flag_map[flag] + + +def GetSourceDir(): +  """Returns the absolute path of the directory where the .py files are.""" + +  return os.path.abspath(GetFlag('gmock_source_dir')) + + +def GetBuildDir(): +  """Returns the absolute path of the directory where the test binaries are.""" + +  return os.path.abspath(GetFlag('gmock_build_dir')) + + +def GetExitStatus(exit_code): +  """Returns the argument to exit(), or -1 if exit() wasn't called. + +  Args: +    exit_code: the result value of os.system(command). +  """ + +  if os.name == 'nt': +    # On Windows, os.WEXITSTATUS() doesn't work and os.system() returns +    # the argument to exit() directly. +    return exit_code +  else: +    # On Unix, os.WEXITSTATUS() must be used to extract the exit status +    # from the result of os.system(). +    if os.WIFEXITED(exit_code): +      return os.WEXITSTATUS(exit_code) +    else: +      return -1 + + +def Main(): +  """Runs the unit test.""" + +  # We must call _ParseAndStripGMockFlags() before calling +  # unittest.main().  Otherwise the latter will be confused by the +  # --gmock_* flags. +  _ParseAndStripGMockFlags(sys.argv) +  unittest.main() | 
