diff options
Diffstat (limited to 'src/googletest/googlemock')
80 files changed, 45781 insertions, 0 deletions
diff --git a/src/googletest/googlemock/CMakeLists.txt b/src/googletest/googlemock/CMakeLists.txt new file mode 100644 index 000000000..3d6699a86 --- /dev/null +++ b/src/googletest/googlemock/CMakeLists.txt @@ -0,0 +1,219 @@ +######################################################################## +# Note: CMake support is community-based. The maintainers do not use CMake +# internally. +# +# CMake build script for Google Mock. +# +# To run the tests for Google Mock itself on Linux, use 'make test' or +# ctest. You can select which tests to run using 'ctest -R regex'. +# For more options, run 'ctest --help'. + +option(gmock_build_tests "Build all of Google Mock's own tests." OFF) + +# A directory to find Google Test sources. +if (EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/gtest/CMakeLists.txt") + set(gtest_dir gtest) +else() + set(gtest_dir ../googletest) +endif() + +# Defines pre_project_set_up_hermetic_build() and set_up_hermetic_build(). +include("${gtest_dir}/cmake/hermetic_build.cmake" OPTIONAL) + +if (COMMAND pre_project_set_up_hermetic_build) + # Google Test also calls hermetic setup functions from add_subdirectory, + # although its changes will not affect things at the current scope. + pre_project_set_up_hermetic_build() +endif() + +######################################################################## +# +# Project-wide settings + +# Name of the project. +# +# CMake files in this project can refer to the root source directory +# as ${gmock_SOURCE_DIR} and to the root binary directory as +# ${gmock_BINARY_DIR}. +# Language "C" is required for find_package(Threads). +if (CMAKE_VERSION VERSION_LESS 3.0) + project(gmock CXX C) +else() + cmake_policy(SET CMP0048 NEW) + project(gmock VERSION ${GOOGLETEST_VERSION} LANGUAGES CXX C) +endif() +cmake_minimum_required(VERSION 2.8.12) + +if (COMMAND set_up_hermetic_build) + set_up_hermetic_build() +endif() + +# Instructs CMake to process Google Test's CMakeLists.txt and add its +# targets to the current scope. We are placing Google Test's binary +# directory in a subdirectory of our own as VC compilation may break +# if they are the same (the default). +add_subdirectory("${gtest_dir}" "${gmock_BINARY_DIR}/${gtest_dir}") + + +# These commands only run if this is the main project +if(CMAKE_PROJECT_NAME STREQUAL "gmock" OR CMAKE_PROJECT_NAME STREQUAL "googletest-distribution") + # BUILD_SHARED_LIBS is a standard CMake variable, but we declare it here to + # make it prominent in the GUI. + option(BUILD_SHARED_LIBS "Build shared libraries (DLLs)." OFF) +else() + mark_as_advanced(gmock_build_tests) +endif() + +# Although Google Test's CMakeLists.txt calls this function, the +# changes there don't affect the current scope. Therefore we have to +# call it again here. +config_compiler_and_linker() # from ${gtest_dir}/cmake/internal_utils.cmake + +# Adds Google Mock's and Google Test's header directories to the search path. +set(gmock_build_include_dirs + "${gmock_SOURCE_DIR}/include" + "${gmock_SOURCE_DIR}" + "${gtest_SOURCE_DIR}/include" + # This directory is needed to build directly from Google Test sources. + "${gtest_SOURCE_DIR}") +include_directories(${gmock_build_include_dirs}) + +######################################################################## +# +# Defines the gmock & gmock_main libraries. User tests should link +# with one of them. + +# Google Mock libraries. We build them using more strict warnings than what +# are used for other targets, to ensure that Google Mock can be compiled by +# a user aggressive about warnings. +if (MSVC) + cxx_library(gmock + "${cxx_strict}" + "${gtest_dir}/src/gtest-all.cc" + src/gmock-all.cc) + + cxx_library(gmock_main + "${cxx_strict}" + "${gtest_dir}/src/gtest-all.cc" + src/gmock-all.cc + src/gmock_main.cc) +else() + cxx_library(gmock "${cxx_strict}" src/gmock-all.cc) + target_link_libraries(gmock PUBLIC gtest) + set_target_properties(gmock PROPERTIES VERSION ${GOOGLETEST_VERSION}) + cxx_library(gmock_main "${cxx_strict}" src/gmock_main.cc) + target_link_libraries(gmock_main PUBLIC gmock) + set_target_properties(gmock_main PROPERTIES VERSION ${GOOGLETEST_VERSION}) +endif() +# If the CMake version supports it, attach header directory information +# to the targets for when we are part of a parent build (ie being pulled +# in via add_subdirectory() rather than being a standalone build). +if (DEFINED CMAKE_VERSION AND NOT "${CMAKE_VERSION}" VERSION_LESS "2.8.11") + target_include_directories(gmock SYSTEM INTERFACE + "$<BUILD_INTERFACE:${gmock_build_include_dirs}>" + "$<INSTALL_INTERFACE:$<INSTALL_PREFIX>/${CMAKE_INSTALL_INCLUDEDIR}>") + target_include_directories(gmock_main SYSTEM INTERFACE + "$<BUILD_INTERFACE:${gmock_build_include_dirs}>" + "$<INSTALL_INTERFACE:$<INSTALL_PREFIX>/${CMAKE_INSTALL_INCLUDEDIR}>") +endif() + +######################################################################## +# +# Install rules +install_project(gmock gmock_main) + +######################################################################## +# +# Google Mock's own tests. +# +# You can skip this section if you aren't interested in testing +# Google Mock itself. +# +# The tests are not built by default. To build them, set the +# gmock_build_tests option to ON. You can do it by running ccmake +# or specifying the -Dgmock_build_tests=ON flag when running cmake. + +if (gmock_build_tests) + # This must be set in the root directory for the tests to be run by + # 'make test' or ctest. + enable_testing() + + if (MINGW OR CYGWIN) + if (CMAKE_VERSION VERSION_LESS "2.8.12") + add_compile_options("-Wa,-mbig-obj") + else() + add_definitions("-Wa,-mbig-obj") + endif() + endif() + + ############################################################ + # C++ tests built with standard compiler flags. + + cxx_test(gmock-actions_test gmock_main) + cxx_test(gmock-cardinalities_test gmock_main) + cxx_test(gmock_ex_test gmock_main) + cxx_test(gmock-function-mocker_test gmock_main) + cxx_test(gmock-generated-actions_test gmock_main) + cxx_test(gmock-internal-utils_test gmock_main) + cxx_test(gmock-matchers_test gmock_main) + cxx_test(gmock-more-actions_test gmock_main) + cxx_test(gmock-nice-strict_test gmock_main) + cxx_test(gmock-port_test gmock_main) + cxx_test(gmock-spec-builders_test gmock_main) + cxx_test(gmock_link_test gmock_main test/gmock_link2_test.cc) + cxx_test(gmock_test gmock_main) + + if (DEFINED GTEST_HAS_PTHREAD) + cxx_test(gmock_stress_test gmock) + endif() + + # gmock_all_test is commented to save time building and running tests. + # Uncomment if necessary. + # cxx_test(gmock_all_test gmock_main) + + ############################################################ + # C++ tests built with non-standard compiler flags. + + if (MSVC) + cxx_library(gmock_main_no_exception "${cxx_no_exception}" + "${gtest_dir}/src/gtest-all.cc" src/gmock-all.cc src/gmock_main.cc) + + cxx_library(gmock_main_no_rtti "${cxx_no_rtti}" + "${gtest_dir}/src/gtest-all.cc" src/gmock-all.cc src/gmock_main.cc) + + else() + cxx_library(gmock_main_no_exception "${cxx_no_exception}" src/gmock_main.cc) + target_link_libraries(gmock_main_no_exception PUBLIC gmock) + + cxx_library(gmock_main_no_rtti "${cxx_no_rtti}" src/gmock_main.cc) + target_link_libraries(gmock_main_no_rtti PUBLIC gmock) + endif() + cxx_test_with_flags(gmock-more-actions_no_exception_test "${cxx_no_exception}" + gmock_main_no_exception test/gmock-more-actions_test.cc) + + cxx_test_with_flags(gmock_no_rtti_test "${cxx_no_rtti}" + gmock_main_no_rtti test/gmock-spec-builders_test.cc) + + cxx_shared_library(shared_gmock_main "${cxx_default}" + "${gtest_dir}/src/gtest-all.cc" src/gmock-all.cc src/gmock_main.cc) + + # Tests that a binary can be built with Google Mock as a shared library. On + # some system configurations, it may not possible to run the binary without + # knowing more details about the system configurations. We do not try to run + # this binary. To get a more robust shared library coverage, configure with + # -DBUILD_SHARED_LIBS=ON. + cxx_executable_with_flags(shared_gmock_test_ "${cxx_default}" + shared_gmock_main test/gmock-spec-builders_test.cc) + set_target_properties(shared_gmock_test_ + PROPERTIES + COMPILE_DEFINITIONS "GTEST_LINKED_AS_SHARED_LIBRARY=1") + + ############################################################ + # Python tests. + + cxx_executable(gmock_leak_test_ test gmock_main) + py_test(gmock_leak_test) + + cxx_executable(gmock_output_test_ test gmock) + py_test(gmock_output_test) +endif() diff --git a/src/googletest/googlemock/CONTRIBUTORS b/src/googletest/googlemock/CONTRIBUTORS new file mode 100644 index 000000000..6e9ae362b --- /dev/null +++ b/src/googletest/googlemock/CONTRIBUTORS @@ -0,0 +1,40 @@ +# This file contains a list of people who've made non-trivial +# contribution to the Google C++ Mocking Framework project. People +# who commit code to the project are encouraged to add their names +# here. Please keep the list sorted by first names. + +Benoit Sigoure <tsuna@google.com> +Bogdan Piloca <boo@google.com> +Chandler Carruth <chandlerc@google.com> +Dave MacLachlan <dmaclach@gmail.com> +David Anderson <danderson@google.com> +Dean Sturtevant +Gene Volovich <gv@cite.com> +Hal Burch <gmock@hburch.com> +Jeffrey Yasskin <jyasskin@google.com> +Jim Keller <jimkeller@google.com> +Joe Walnes <joe@truemesh.com> +Jon Wray <jwray@google.com> +Keir Mierle <mierle@gmail.com> +Keith Ray <keith.ray@gmail.com> +Kostya Serebryany <kcc@google.com> +Lev Makhlis +Manuel Klimek <klimek@google.com> +Mario Tanev <radix@google.com> +Mark Paskin +Markus Heule <markus.heule@gmail.com> +Matthew Simmons <simmonmt@acm.org> +Mike Bland <mbland@google.com> +Neal Norwitz <nnorwitz@gmail.com> +Nermin Ozkiranartli <nermin@google.com> +Owen Carlsen <ocarlsen@google.com> +Paneendra Ba <paneendra@google.com> +Paul Menage <menage@google.com> +Piotr Kaminski <piotrk@google.com> +Russ Rufer <russ@pentad.com> +Sverre Sundsdal <sundsdal@gmail.com> +Takeshi Yoshino <tyoshino@google.com> +Vadim Berman <vadimb@google.com> +Vlad Losev <vladl@google.com> +Wolfgang Klier <wklier@google.com> +Zhanyong Wan <wan@google.com> diff --git a/src/googletest/googlemock/LICENSE b/src/googletest/googlemock/LICENSE new file mode 100644 index 000000000..1941a11f8 --- /dev/null +++ b/src/googletest/googlemock/LICENSE @@ -0,0 +1,28 @@ +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. diff --git a/src/googletest/googlemock/README.md b/src/googletest/googlemock/README.md new file mode 100644 index 000000000..daafe2842 --- /dev/null +++ b/src/googletest/googlemock/README.md @@ -0,0 +1,44 @@ +# Googletest Mocking (gMock) Framework + +### Overview + +Google's framework for writing and using C++ mock classes. It can help you +derive better designs of your system and write better tests. + +It is inspired by: + +* [jMock](http://www.jmock.org/) +* [EasyMock](http://www.easymock.org/) +* [Hamcrest](http://code.google.com/p/hamcrest/) + +It is designed with C++'s specifics in mind. + +gMock: + +- Provides a declarative syntax for defining mocks. +- Can define partial (hybrid) mocks, which are a cross of real and mock + objects. +- Handles functions of arbitrary types and overloaded functions. +- Comes with a rich set of matchers for validating function arguments. +- Uses an intuitive syntax for controlling the behavior of a mock. +- Does automatic verification of expectations (no record-and-replay needed). +- Allows arbitrary (partial) ordering constraints on function calls to be + expressed. +- Lets a user extend it by defining new matchers and actions. +- Does not use exceptions. +- Is easy to learn and use. + +Details and examples can be found here: + +* [gMock for Dummies](docs/for_dummies.md) +* [Legacy gMock FAQ](docs/gmock_faq.md) +* [gMock Cookbook](docs/cook_book.md) +* [gMock Cheat Sheet](docs/cheat_sheet.md) + +Please note that code under scripts/generator/ is from the +[cppclean project](http://code.google.com/p/cppclean/) and under the Apache +License, which is different from GoogleMock's license. + +GoogleMock is a part of +[GoogleTest C++ testing framework](http://github.com/google/googletest/) and a +subject to the same requirements. diff --git a/src/googletest/googlemock/cmake/gmock.pc.in b/src/googletest/googlemock/cmake/gmock.pc.in new file mode 100644 index 000000000..23c67b5c8 --- /dev/null +++ b/src/googletest/googlemock/cmake/gmock.pc.in @@ -0,0 +1,10 @@ +libdir=@CMAKE_INSTALL_FULL_LIBDIR@ +includedir=@CMAKE_INSTALL_FULL_INCLUDEDIR@ + +Name: gmock +Description: GoogleMock (without main() function) +Version: @PROJECT_VERSION@ +URL: https://github.com/google/googletest +Requires: gtest = @PROJECT_VERSION@ +Libs: -L${libdir} -lgmock @CMAKE_THREAD_LIBS_INIT@ +Cflags: -I${includedir} @GTEST_HAS_PTHREAD_MACRO@ diff --git a/src/googletest/googlemock/cmake/gmock_main.pc.in b/src/googletest/googlemock/cmake/gmock_main.pc.in new file mode 100644 index 000000000..66ffea7f4 --- /dev/null +++ b/src/googletest/googlemock/cmake/gmock_main.pc.in @@ -0,0 +1,10 @@ +libdir=@CMAKE_INSTALL_FULL_LIBDIR@ +includedir=@CMAKE_INSTALL_FULL_INCLUDEDIR@ + +Name: gmock_main +Description: GoogleMock (with main() function) +Version: @PROJECT_VERSION@ +URL: https://github.com/google/googletest +Requires: gmock = @PROJECT_VERSION@ +Libs: -L${libdir} -lgmock_main @CMAKE_THREAD_LIBS_INIT@ +Cflags: -I${includedir} @GTEST_HAS_PTHREAD_MACRO@ diff --git a/src/googletest/googlemock/docs/cheat_sheet.md b/src/googletest/googlemock/docs/cheat_sheet.md new file mode 100644 index 000000000..dc2428efe --- /dev/null +++ b/src/googletest/googlemock/docs/cheat_sheet.md @@ -0,0 +1,786 @@ +# gMock Cheat Sheet + +<!-- GOOGLETEST_CM0019 DO NOT DELETE --> + +<!-- GOOGLETEST_CM0035 DO NOT DELETE --> + +<!-- GOOGLETEST_CM0033 DO NOT DELETE --> + +## Defining a Mock Class + +### Mocking a Normal Class {#MockClass} + +Given + +```cpp +class Foo { + ... + virtual ~Foo(); + virtual int GetSize() const = 0; + virtual string Describe(const char* name) = 0; + virtual string Describe(int type) = 0; + virtual bool Process(Bar elem, int count) = 0; +}; +``` + +(note that `~Foo()` **must** be virtual) we can define its mock as + +```cpp +#include "gmock/gmock.h" + +class MockFoo : public Foo { + ... + MOCK_METHOD(int, GetSize, (), (const, override)); + MOCK_METHOD(string, Describe, (const char* name), (override)); + MOCK_METHOD(string, Describe, (int type), (override)); + MOCK_METHOD(bool, Process, (Bar elem, int count), (override)); +}; +``` + +To create a "nice" mock, which ignores all uninteresting calls, a "naggy" mock, +which warns on all uninteresting calls, or a "strict" mock, which treats them as +failures: + +```cpp +using ::testing::NiceMock; +using ::testing::NaggyMock; +using ::testing::StrictMock; + +NiceMock<MockFoo> nice_foo; // The type is a subclass of MockFoo. +NaggyMock<MockFoo> naggy_foo; // The type is a subclass of MockFoo. +StrictMock<MockFoo> strict_foo; // The type is a subclass of MockFoo. +``` + +**Note:** A mock object is currently naggy by default. We may make it nice by +default in the future. + +### Mocking a Class Template {#MockTemplate} + +Class templates can be mocked just like any class. + +To mock + +```cpp +template <typename Elem> +class StackInterface { + ... + virtual ~StackInterface(); + virtual int GetSize() const = 0; + virtual void Push(const Elem& x) = 0; +}; +``` + +(note that all member functions that are mocked, including `~StackInterface()` +**must** be virtual). + +```cpp +template <typename Elem> +class MockStack : public StackInterface<Elem> { + ... + MOCK_METHOD(int, GetSize, (), (const, override)); + MOCK_METHOD(void, Push, (const Elem& x), (override)); +}; +``` + +### Specifying Calling Conventions for Mock Functions + +If your mock function doesn't use the default calling convention, you can +specify it by adding `Calltype(convention)` to `MOCK_METHOD`'s 4th parameter. +For example, + +```cpp + MOCK_METHOD(bool, Foo, (int n), (Calltype(STDMETHODCALLTYPE))); + MOCK_METHOD(int, Bar, (double x, double y), + (const, Calltype(STDMETHODCALLTYPE))); +``` + +where `STDMETHODCALLTYPE` is defined by `<objbase.h>` on Windows. + +## Using Mocks in Tests {#UsingMocks} + +The typical work flow is: + +1. Import the gMock names you need to use. All gMock symbols are in the + `testing` namespace unless they are macros or otherwise noted. +2. Create the mock objects. +3. Optionally, set the default actions of the mock objects. +4. Set your expectations on the mock objects (How will they be called? What + will they do?). +5. Exercise code that uses the mock objects; if necessary, check the result + using googletest assertions. +6. When a mock object is destructed, gMock automatically verifies that all + expectations on it have been satisfied. + +Here's an example: + +```cpp +using ::testing::Return; // #1 + +TEST(BarTest, DoesThis) { + MockFoo foo; // #2 + + ON_CALL(foo, GetSize()) // #3 + .WillByDefault(Return(1)); + // ... other default actions ... + + EXPECT_CALL(foo, Describe(5)) // #4 + .Times(3) + .WillRepeatedly(Return("Category 5")); + // ... other expectations ... + + EXPECT_EQ("good", MyProductionFunction(&foo)); // #5 +} // #6 +``` + +## Setting Default Actions {#OnCall} + +gMock has a **built-in default action** for any function that returns `void`, +`bool`, a numeric value, or a pointer. In C++11, it will additionally returns +the default-constructed value, if one exists for the given type. + +To customize the default action for functions with return type *`T`*: + +```cpp +using ::testing::DefaultValue; + +// Sets the default value to be returned. T must be CopyConstructible. +DefaultValue<T>::Set(value); +// Sets a factory. Will be invoked on demand. T must be MoveConstructible. +// T MakeT(); +DefaultValue<T>::SetFactory(&MakeT); +// ... use the mocks ... +// Resets the default value. +DefaultValue<T>::Clear(); +``` + +Example usage: + +```cpp + // Sets the default action for return type std::unique_ptr<Buzz> to + // creating a new Buzz every time. + DefaultValue<std::unique_ptr<Buzz>>::SetFactory( + [] { return MakeUnique<Buzz>(AccessLevel::kInternal); }); + + // When this fires, the default action of MakeBuzz() will run, which + // will return a new Buzz object. + EXPECT_CALL(mock_buzzer_, MakeBuzz("hello")).Times(AnyNumber()); + + auto buzz1 = mock_buzzer_.MakeBuzz("hello"); + auto buzz2 = mock_buzzer_.MakeBuzz("hello"); + EXPECT_NE(nullptr, buzz1); + EXPECT_NE(nullptr, buzz2); + EXPECT_NE(buzz1, buzz2); + + // Resets the default action for return type std::unique_ptr<Buzz>, + // to avoid interfere with other tests. + DefaultValue<std::unique_ptr<Buzz>>::Clear(); +``` + +To customize the default action for a particular method of a specific mock +object, use `ON_CALL()`. `ON_CALL()` has a similar syntax to `EXPECT_CALL()`, +but it is used for setting default behaviors (when you do not require that the +mock method is called). See [here](cook_book.md#UseOnCall) for a more detailed +discussion. + +```cpp +ON_CALL(mock-object, method(matchers)) + .With(multi-argument-matcher) ? + .WillByDefault(action); +``` + +## Setting Expectations {#ExpectCall} + +`EXPECT_CALL()` sets **expectations** on a mock method (How will it be called? +What will it do?): + +```cpp +EXPECT_CALL(mock-object, method (matchers)?) + .With(multi-argument-matcher) ? + .Times(cardinality) ? + .InSequence(sequences) * + .After(expectations) * + .WillOnce(action) * + .WillRepeatedly(action) ? + .RetiresOnSaturation(); ? +``` + +For each item above, `?` means it can be used at most once, while `*` means it +can be used any number of times. + +In order to pass, `EXPECT_CALL` must be used before the calls are actually made. + +The `(matchers)` is a comma-separated list of matchers that correspond to each +of the arguments of `method`, and sets the expectation only for calls of +`method` that matches all of the matchers. + +If `(matchers)` is omitted, the expectation is the same as if the matchers were +set to anything matchers (for example, `(_, _, _, _)` for a four-arg method). + +If `Times()` is omitted, the cardinality is assumed to be: + +* `Times(1)` when there is neither `WillOnce()` nor `WillRepeatedly()`; +* `Times(n)` when there are `n` `WillOnce()`s but no `WillRepeatedly()`, where + `n` >= 1; or +* `Times(AtLeast(n))` when there are `n` `WillOnce()`s and a + `WillRepeatedly()`, where `n` >= 0. + +A method with no `EXPECT_CALL()` is free to be invoked *any number of times*, +and the default action will be taken each time. + +## Matchers {#MatcherList} + +<!-- GOOGLETEST_CM0020 DO NOT DELETE --> + +A **matcher** matches a *single* argument. You can use it inside `ON_CALL()` or +`EXPECT_CALL()`, or use it to validate a value directly using two macros: + +<!-- mdformat off(github rendering does not support multiline tables) --> +| Macro | Description | +| :----------------------------------- | :------------------------------------ | +| `EXPECT_THAT(actual_value, matcher)` | Asserts that `actual_value` matches `matcher`. | +| `ASSERT_THAT(actual_value, matcher)` | The same as `EXPECT_THAT(actual_value, matcher)`, except that it generates a **fatal** failure. | +<!-- mdformat on --> + +**Note:** Although equality matching via `EXPECT_THAT(actual_value, +expected_value)` is supported, prefer to make the comparison explicit via +`EXPECT_THAT(actual_value, Eq(expected_value))` or `EXPECT_EQ(actual_value, +expected_value)`. + +Built-in matchers (where `argument` is the function argument, e.g. +`actual_value` in the example above, or when used in the context of +`EXPECT_CALL(mock_object, method(matchers))`, the arguments of `method`) are +divided into several categories: + +### Wildcard + +Matcher | Description +:-------------------------- | :----------------------------------------------- +`_` | `argument` can be any value of the correct type. +`A<type>()` or `An<type>()` | `argument` can be any value of type `type`. + +### Generic Comparison + +<!-- mdformat off(no multiline tables) --> +| Matcher | Description | +| :--------------------- | :-------------------------------------------------- | +| `Eq(value)` or `value` | `argument == value` | +| `Ge(value)` | `argument >= value` | +| `Gt(value)` | `argument > value` | +| `Le(value)` | `argument <= value` | +| `Lt(value)` | `argument < value` | +| `Ne(value)` | `argument != value` | +| `IsFalse()` | `argument` evaluates to `false` in a Boolean context. | +| `IsTrue()` | `argument` evaluates to `true` in a Boolean context. | +| `IsNull()` | `argument` is a `NULL` pointer (raw or smart). | +| `NotNull()` | `argument` is a non-null pointer (raw or smart). | +| `Optional(m)` | `argument` is `optional<>` that contains a value matching `m`. (For testing whether an `optional<>` is set, check for equality with `nullopt`. You may need to use `Eq(nullopt)` if the inner type doesn't have `==`.)| +| `VariantWith<T>(m)` | `argument` is `variant<>` that holds the alternative of type T with a value matching `m`. | +| `Ref(variable)` | `argument` is a reference to `variable`. | +| `TypedEq<type>(value)` | `argument` has type `type` and is equal to `value`. You may need to use this instead of `Eq(value)` when the mock function is overloaded. | +<!-- mdformat on --> + +Except `Ref()`, these matchers make a *copy* of `value` in case it's modified or +destructed later. If the compiler complains that `value` doesn't have a public +copy constructor, try wrap it in `std::ref()`, e.g. +`Eq(std::ref(non_copyable_value))`. If you do that, make sure +`non_copyable_value` is not changed afterwards, or the meaning of your matcher +will be changed. + +`IsTrue` and `IsFalse` are useful when you need to use a matcher, or for types +that can be explicitly converted to Boolean, but are not implicitly converted to +Boolean. In other cases, you can use the basic +[`EXPECT_TRUE` and `EXPECT_FALSE`](../../googletest/docs/primer#basic-assertions) +assertions. + +### Floating-Point Matchers {#FpMatchers} + +<!-- mdformat off(no multiline tables) --> +| Matcher | Description | +| :------------------------------- | :--------------------------------- | +| `DoubleEq(a_double)` | `argument` is a `double` value approximately equal to `a_double`, treating two NaNs as unequal. | +| `FloatEq(a_float)` | `argument` is a `float` value approximately equal to `a_float`, treating two NaNs as unequal. | +| `NanSensitiveDoubleEq(a_double)` | `argument` is a `double` value approximately equal to `a_double`, treating two NaNs as equal. | +| `NanSensitiveFloatEq(a_float)` | `argument` is a `float` value approximately equal to `a_float`, treating two NaNs as equal. | +| `IsNan()` | `argument` is any floating-point type with a NaN value. | +<!-- mdformat on --> + +The above matchers use ULP-based comparison (the same as used in googletest). +They automatically pick a reasonable error bound based on the absolute value of +the expected value. `DoubleEq()` and `FloatEq()` conform to the IEEE standard, +which requires comparing two NaNs for equality to return false. The +`NanSensitive*` version instead treats two NaNs as equal, which is often what a +user wants. + +<!-- mdformat off(no multiline tables) --> +| Matcher | Description | +| :------------------------------------------------ | :----------------------- | +| `DoubleNear(a_double, max_abs_error)` | `argument` is a `double` value close to `a_double` (absolute error <= `max_abs_error`), treating two NaNs as unequal. | +| `FloatNear(a_float, max_abs_error)` | `argument` is a `float` value close to `a_float` (absolute error <= `max_abs_error`), treating two NaNs as unequal. | +| `NanSensitiveDoubleNear(a_double, max_abs_error)` | `argument` is a `double` value close to `a_double` (absolute error <= `max_abs_error`), treating two NaNs as equal. | +| `NanSensitiveFloatNear(a_float, max_abs_error)` | `argument` is a `float` value close to `a_float` (absolute error <= `max_abs_error`), treating two NaNs as equal. | +<!-- mdformat on --> + +### String Matchers + +The `argument` can be either a C string or a C++ string object: + +<!-- mdformat off(no multiline tables) --> +| Matcher | Description | +| :---------------------- | :------------------------------------------------- | +| `ContainsRegex(string)` | `argument` matches the given regular expression. | +| `EndsWith(suffix)` | `argument` ends with string `suffix`. | +| `HasSubstr(string)` | `argument` contains `string` as a sub-string. | +| `MatchesRegex(string)` | `argument` matches the given regular expression with the match starting at the first character and ending at the last character. | +| `StartsWith(prefix)` | `argument` starts with string `prefix`. | +| `StrCaseEq(string)` | `argument` is equal to `string`, ignoring case. | +| `StrCaseNe(string)` | `argument` is not equal to `string`, ignoring case. | +| `StrEq(string)` | `argument` is equal to `string`. | +| `StrNe(string)` | `argument` is not equal to `string`. | +<!-- mdformat on --> + +`ContainsRegex()` and `MatchesRegex()` take ownership of the `RE` object. They +use the regular expression syntax defined +[here](../../googletest/docs/advanced.md#regular-expression-syntax). All of +these matchers, except `ContainsRegex()` and `MatchesRegex()` work for wide +strings as well. + +### Container Matchers + +Most STL-style containers support `==`, so you can use `Eq(expected_container)` +or simply `expected_container` to match a container exactly. If you want to +write the elements in-line, match them more flexibly, or get more informative +messages, you can use: + +<!-- mdformat off(no multiline tables) --> +| Matcher | Description | +| :---------------------------------------- | :------------------------------- | +| `BeginEndDistanceIs(m)` | `argument` is a container whose `begin()` and `end()` iterators are separated by a number of increments matching `m`. E.g. `BeginEndDistanceIs(2)` or `BeginEndDistanceIs(Lt(2))`. For containers that define a `size()` method, `SizeIs(m)` may be more efficient. | +| `ContainerEq(container)` | The same as `Eq(container)` except that the failure message also includes which elements are in one container but not the other. | +| `Contains(e)` | `argument` contains an element that matches `e`, which can be either a value or a matcher. | +| `Each(e)` | `argument` is a container where *every* element matches `e`, which can be either a value or a matcher. | +| `ElementsAre(e0, e1, ..., en)` | `argument` has `n + 1` elements, where the *i*-th element matches `ei`, which can be a value or a matcher. | +| `ElementsAreArray({e0, e1, ..., en})`, `ElementsAreArray(a_container)`, `ElementsAreArray(begin, end)`, `ElementsAreArray(array)`, or `ElementsAreArray(array, count)` | The same as `ElementsAre()` except that the expected element values/matchers come from an initializer list, STL-style container, iterator range, or C-style array. | +| `IsEmpty()` | `argument` is an empty container (`container.empty()`). | +| `IsSubsetOf({e0, e1, ..., en})`, `IsSubsetOf(a_container)`, `IsSubsetOf(begin, end)`, `IsSubsetOf(array)`, or `IsSubsetOf(array, count)` | `argument` matches `UnorderedElementsAre(x0, x1, ..., xk)` for some subset `{x0, x1, ..., xk}` of the expected matchers. | +| `IsSupersetOf({e0, e1, ..., en})`, `IsSupersetOf(a_container)`, `IsSupersetOf(begin, end)`, `IsSupersetOf(array)`, or `IsSupersetOf(array, count)` | Some subset of `argument` matches `UnorderedElementsAre(`expected matchers`)`. | +| `Pointwise(m, container)`, `Pointwise(m, {e0, e1, ..., en})` | `argument` contains the same number of elements as in `container`, and for all i, (the i-th element in `argument`, the i-th element in `container`) match `m`, which is a matcher on 2-tuples. E.g. `Pointwise(Le(), upper_bounds)` verifies that each element in `argument` doesn't exceed the corresponding element in `upper_bounds`. See more detail below. | +| `SizeIs(m)` | `argument` is a container whose size matches `m`. E.g. `SizeIs(2)` or `SizeIs(Lt(2))`. | +| `UnorderedElementsAre(e0, e1, ..., en)` | `argument` has `n + 1` elements, and under *some* permutation of the elements, each element matches an `ei` (for a different `i`), which can be a value or a matcher. | +| `UnorderedElementsAreArray({e0, e1, ..., en})`, `UnorderedElementsAreArray(a_container)`, `UnorderedElementsAreArray(begin, end)`, `UnorderedElementsAreArray(array)`, or `UnorderedElementsAreArray(array, count)` | The same as `UnorderedElementsAre()` except that the expected element values/matchers come from an initializer list, STL-style container, iterator range, or C-style array. | +| `UnorderedPointwise(m, container)`, `UnorderedPointwise(m, {e0, e1, ..., en})` | Like `Pointwise(m, container)`, but ignores the order of elements. | +| `WhenSorted(m)` | When `argument` is sorted using the `<` operator, it matches container matcher `m`. E.g. `WhenSorted(ElementsAre(1, 2, 3))` verifies that `argument` contains elements 1, 2, and 3, ignoring order. | +| `WhenSortedBy(comparator, m)` | The same as `WhenSorted(m)`, except that the given comparator instead of `<` is used to sort `argument`. E.g. `WhenSortedBy(std::greater(), ElementsAre(3, 2, 1))`. | +<!-- mdformat on --> + +**Notes:** + +* These matchers can also match: + 1. a native array passed by reference (e.g. in `Foo(const int (&a)[5])`), + and + 2. an array passed as a pointer and a count (e.g. in `Bar(const T* buffer, + int len)` -- see [Multi-argument Matchers](#MultiArgMatchers)). +* The array being matched may be multi-dimensional (i.e. its elements can be + arrays). +* `m` in `Pointwise(m, ...)` should be a matcher for `::std::tuple<T, U>` + where `T` and `U` are the element type of the actual container and the + expected container, respectively. For example, to compare two `Foo` + containers where `Foo` doesn't support `operator==`, one might write: + + ```cpp + using ::std::get; + MATCHER(FooEq, "") { + return std::get<0>(arg).Equals(std::get<1>(arg)); + } + ... + EXPECT_THAT(actual_foos, Pointwise(FooEq(), expected_foos)); + ``` + +### Member Matchers + +<!-- mdformat off(no multiline tables) --> +| Matcher | Description | +| :------------------------------ | :----------------------------------------- | +| `Field(&class::field, m)` | `argument.field` (or `argument->field` when `argument` is a plain pointer) matches matcher `m`, where `argument` is an object of type _class_. | +| `Key(e)` | `argument.first` matches `e`, which can be either a value or a matcher. E.g. `Contains(Key(Le(5)))` can verify that a `map` contains a key `<= 5`. | +| `Pair(m1, m2)` | `argument` is an `std::pair` whose `first` field matches `m1` and `second` field matches `m2`. | +| `FieldsAre(m...)` | `argument` is a compatible object where each field matches piecewise with `m...`. A compatible object is any that supports the `std::tuple_size<Obj>`+`get<I>(obj)` protocol. In C++17 and up this also supports types compatible with structured bindings, like aggregates. | +| `Property(&class::property, m)` | `argument.property()` (or `argument->property()` when `argument` is a plain pointer) matches matcher `m`, where `argument` is an object of type _class_. | +<!-- mdformat on --> + +### Matching the Result of a Function, Functor, or Callback + +<!-- mdformat off(no multiline tables) --> +| Matcher | Description | +| :--------------- | :------------------------------------------------ | +| `ResultOf(f, m)` | `f(argument)` matches matcher `m`, where `f` is a function or functor. | +<!-- mdformat on --> + +### Pointer Matchers + +<!-- mdformat off(no multiline tables) --> +| Matcher | Description | +| :------------------------ | :---------------------------------------------- | +| `Address(m)` | the result of `std::addressof(argument)` matches `m`. | +| `Pointee(m)` | `argument` (either a smart pointer or a raw pointer) points to a value that matches matcher `m`. | +| `Pointer(m)` | `argument` (either a smart pointer or a raw pointer) contains a pointer that matches `m`. `m` will match against the raw pointer regardless of the type of `argument`. | +| `WhenDynamicCastTo<T>(m)` | when `argument` is passed through `dynamic_cast<T>()`, it matches matcher `m`. | +<!-- mdformat on --> + +<!-- GOOGLETEST_CM0026 DO NOT DELETE --> + +<!-- GOOGLETEST_CM0027 DO NOT DELETE --> + +### Multi-argument Matchers {#MultiArgMatchers} + +Technically, all matchers match a *single* value. A "multi-argument" matcher is +just one that matches a *tuple*. The following matchers can be used to match a +tuple `(x, y)`: + +Matcher | Description +:------ | :---------- +`Eq()` | `x == y` +`Ge()` | `x >= y` +`Gt()` | `x > y` +`Le()` | `x <= y` +`Lt()` | `x < y` +`Ne()` | `x != y` + +You can use the following selectors to pick a subset of the arguments (or +reorder them) to participate in the matching: + +<!-- mdformat off(no multiline tables) --> +| Matcher | Description | +| :------------------------- | :---------------------------------------------- | +| `AllArgs(m)` | Equivalent to `m`. Useful as syntactic sugar in `.With(AllArgs(m))`. | +| `Args<N1, N2, ..., Nk>(m)` | The tuple of the `k` selected (using 0-based indices) arguments matches `m`, e.g. `Args<1, 2>(Eq())`. | +<!-- mdformat on --> + +### Composite Matchers + +You can make a matcher from one or more other matchers: + +<!-- mdformat off(no multiline tables) --> +| Matcher | Description | +| :------------------------------- | :-------------------------------------- | +| `AllOf(m1, m2, ..., mn)` | `argument` matches all of the matchers `m1` to `mn`. | +| `AllOfArray({m0, m1, ..., mn})`, `AllOfArray(a_container)`, `AllOfArray(begin, end)`, `AllOfArray(array)`, or `AllOfArray(array, count)` | The same as `AllOf()` except that the matchers come from an initializer list, STL-style container, iterator range, or C-style array. | +| `AnyOf(m1, m2, ..., mn)` | `argument` matches at least one of the matchers `m1` to `mn`. | +| `AnyOfArray({m0, m1, ..., mn})`, `AnyOfArray(a_container)`, `AnyOfArray(begin, end)`, `AnyOfArray(array)`, or `AnyOfArray(array, count)` | The same as `AnyOf()` except that the matchers come from an initializer list, STL-style container, iterator range, or C-style array. | +| `Not(m)` | `argument` doesn't match matcher `m`. | +<!-- mdformat on --> + +<!-- GOOGLETEST_CM0028 DO NOT DELETE --> + +### Adapters for Matchers + +<!-- mdformat off(no multiline tables) --> +| Matcher | Description | +| :---------------------- | :------------------------------------ | +| `MatcherCast<T>(m)` | casts matcher `m` to type `Matcher<T>`. | +| `SafeMatcherCast<T>(m)` | [safely casts](cook_book.md#casting-matchers) matcher `m` to type `Matcher<T>`. | +| `Truly(predicate)` | `predicate(argument)` returns something considered by C++ to be true, where `predicate` is a function or functor. | +<!-- mdformat on --> + +`AddressSatisfies(callback)` and `Truly(callback)` take ownership of `callback`, +which must be a permanent callback. + +### Using Matchers as Predicates {#MatchersAsPredicatesCheat} + +<!-- mdformat off(no multiline tables) --> +| Matcher | Description | +| :---------------------------- | :------------------------------------------ | +| `Matches(m)(value)` | evaluates to `true` if `value` matches `m`. You can use `Matches(m)` alone as a unary functor. | +| `ExplainMatchResult(m, value, result_listener)` | evaluates to `true` if `value` matches `m`, explaining the result to `result_listener`. | +| `Value(value, m)` | evaluates to `true` if `value` matches `m`. | +<!-- mdformat on --> + +### Defining Matchers + +<!-- mdformat off(no multiline tables) --> +| Matcher | Description | +| :----------------------------------- | :------------------------------------ | +| `MATCHER(IsEven, "") { return (arg % 2) == 0; }` | Defines a matcher `IsEven()` to match an even number. | +| `MATCHER_P(IsDivisibleBy, n, "") { *result_listener << "where the remainder is " << (arg % n); return (arg % n) == 0; }` | Defines a matcher `IsDivisibleBy(n)` to match a number divisible by `n`. | +| `MATCHER_P2(IsBetween, a, b, absl::StrCat(negation ? "isn't" : "is", " between ", PrintToString(a), " and ", PrintToString(b))) { return a <= arg && arg <= b; }` | Defines a matcher `IsBetween(a, b)` to match a value in the range [`a`, `b`]. | +<!-- mdformat on --> + +**Notes:** + +1. The `MATCHER*` macros cannot be used inside a function or class. +2. The matcher body must be *purely functional* (i.e. it cannot have any side + effect, and the result must not depend on anything other than the value + being matched and the matcher parameters). +3. You can use `PrintToString(x)` to convert a value `x` of any type to a + string. + +## Actions {#ActionList} + +**Actions** specify what a mock function should do when invoked. + +### Returning a Value + +<!-- mdformat off(no multiline tables) --> +| | | +| :-------------------------------- | :-------------------------------------------- | +| `Return()` | Return from a `void` mock function. | +| `Return(value)` | Return `value`. If the type of `value` is different to the mock function's return type, `value` is converted to the latter type <i>at the time the expectation is set</i>, not when the action is executed. | +| `ReturnArg<N>()` | Return the `N`-th (0-based) argument. | +| `ReturnNew<T>(a1, ..., ak)` | Return `new T(a1, ..., ak)`; a different object is created each time. | +| `ReturnNull()` | Return a null pointer. | +| `ReturnPointee(ptr)` | Return the value pointed to by `ptr`. | +| `ReturnRef(variable)` | Return a reference to `variable`. | +| `ReturnRefOfCopy(value)` | Return a reference to a copy of `value`; the copy lives as long as the action. | +| `ReturnRoundRobin({a1, ..., ak})` | Each call will return the next `ai` in the list, starting at the beginning when the end of the list is reached. | +<!-- mdformat on --> + +### Side Effects + +<!-- mdformat off(no multiline tables) --> +| | | +| :--------------------------------- | :-------------------------------------- | +| `Assign(&variable, value)` | Assign `value` to variable. | +| `DeleteArg<N>()` | Delete the `N`-th (0-based) argument, which must be a pointer. | +| `SaveArg<N>(pointer)` | Save the `N`-th (0-based) argument to `*pointer`. | +| `SaveArgPointee<N>(pointer)` | Save the value pointed to by the `N`-th (0-based) argument to `*pointer`. | +| `SetArgReferee<N>(value)` | Assign `value` to the variable referenced by the `N`-th (0-based) argument. | +| `SetArgPointee<N>(value)` | Assign `value` to the variable pointed by the `N`-th (0-based) argument. | +| `SetArgumentPointee<N>(value)` | Same as `SetArgPointee<N>(value)`. Deprecated. Will be removed in v1.7.0. | +| `SetArrayArgument<N>(first, last)` | Copies the elements in source range [`first`, `last`) to the array pointed to by the `N`-th (0-based) argument, which can be either a pointer or an iterator. The action does not take ownership of the elements in the source range. | +| `SetErrnoAndReturn(error, value)` | Set `errno` to `error` and return `value`. | +| `Throw(exception)` | Throws the given exception, which can be any copyable value. Available since v1.1.0. | +<!-- mdformat on --> + +### Using a Function, Functor, or Lambda as an Action + +In the following, by "callable" we mean a free function, `std::function`, +functor, or lambda. + +<!-- mdformat off(no multiline tables) --> +| | | +| :---------------------------------- | :------------------------------------- | +| `f` | Invoke f with the arguments passed to the mock function, where f is a callable. | +| `Invoke(f)` | Invoke `f` with the arguments passed to the mock function, where `f` can be a global/static function or a functor. | +| `Invoke(object_pointer, &class::method)` | Invoke the method on the object with the arguments passed to the mock function. | +| `InvokeWithoutArgs(f)` | Invoke `f`, which can be a global/static function or a functor. `f` must take no arguments. | +| `InvokeWithoutArgs(object_pointer, &class::method)` | Invoke the method on the object, which takes no arguments. | +| `InvokeArgument<N>(arg1, arg2, ..., argk)` | Invoke the mock function's `N`-th (0-based) argument, which must be a function or a functor, with the `k` arguments. | +<!-- mdformat on --> + +The return value of the invoked function is used as the return value of the +action. + +When defining a callable to be used with `Invoke*()`, you can declare any unused +parameters as `Unused`: + +```cpp +using ::testing::Invoke; +double Distance(Unused, double x, double y) { return sqrt(x*x + y*y); } +... +EXPECT_CALL(mock, Foo("Hi", _, _)).WillOnce(Invoke(Distance)); +``` + +`Invoke(callback)` and `InvokeWithoutArgs(callback)` take ownership of +`callback`, which must be permanent. The type of `callback` must be a base +callback type instead of a derived one, e.g. + +```cpp + BlockingClosure* done = new BlockingClosure; + ... Invoke(done) ...; // This won't compile! + + Closure* done2 = new BlockingClosure; + ... Invoke(done2) ...; // This works. +``` + +In `InvokeArgument<N>(...)`, if an argument needs to be passed by reference, +wrap it inside `std::ref()`. For example, + +```cpp +using ::testing::InvokeArgument; +... +InvokeArgument<2>(5, string("Hi"), std::ref(foo)) +``` + +calls the mock function's #2 argument, passing to it `5` and `string("Hi")` by +value, and `foo` by reference. + +### Default Action + +<!-- mdformat off(no multiline tables) --> +| Matcher | Description | +| :------------ | :----------------------------------------------------- | +| `DoDefault()` | Do the default action (specified by `ON_CALL()` or the built-in one). | +<!-- mdformat on --> + +**Note:** due to technical reasons, `DoDefault()` cannot be used inside a +composite action - trying to do so will result in a run-time error. + +<!-- GOOGLETEST_CM0032 DO NOT DELETE --> + +### Composite Actions + +<!-- mdformat off(no multiline tables) --> +| | | +| :----------------------------- | :------------------------------------------ | +| `DoAll(a1, a2, ..., an)` | Do all actions `a1` to `an` and return the result of `an` in each invocation. The first `n - 1` sub-actions must return void and will receive a readonly view of the arguments. | +| `IgnoreResult(a)` | Perform action `a` and ignore its result. `a` must not return void. | +| `WithArg<N>(a)` | Pass the `N`-th (0-based) argument of the mock function to action `a` and perform it. | +| `WithArgs<N1, N2, ..., Nk>(a)` | Pass the selected (0-based) arguments of the mock function to action `a` and perform it. | +| `WithoutArgs(a)` | Perform action `a` without any arguments. | +<!-- mdformat on --> + +### Defining Actions + +<!-- mdformat off(no multiline tables) --> +| | | +| :--------------------------------- | :-------------------------------------- | +| `ACTION(Sum) { return arg0 + arg1; }` | Defines an action `Sum()` to return the sum of the mock function's argument #0 and #1. | +| `ACTION_P(Plus, n) { return arg0 + n; }` | Defines an action `Plus(n)` to return the sum of the mock function's argument #0 and `n`. | +| `ACTION_Pk(Foo, p1, ..., pk) { statements; }` | Defines a parameterized action `Foo(p1, ..., pk)` to execute the given `statements`. | +<!-- mdformat on --> + +The `ACTION*` macros cannot be used inside a function or class. + +## Cardinalities {#CardinalityList} + +These are used in `Times()` to specify how many times a mock function will be +called: + +<!-- mdformat off(no multiline tables) --> +| | | +| :---------------- | :----------------------------------------------------- | +| `AnyNumber()` | The function can be called any number of times. | +| `AtLeast(n)` | The call is expected at least `n` times. | +| `AtMost(n)` | The call is expected at most `n` times. | +| `Between(m, n)` | The call is expected between `m` and `n` (inclusive) times. | +| `Exactly(n) or n` | The call is expected exactly `n` times. In particular, the call should never happen when `n` is 0. | +<!-- mdformat on --> + +## Expectation Order + +By default, the expectations can be matched in *any* order. If some or all +expectations must be matched in a given order, there are two ways to specify it. +They can be used either independently or together. + +### The After Clause {#AfterClause} + +```cpp +using ::testing::Expectation; +... +Expectation init_x = EXPECT_CALL(foo, InitX()); +Expectation init_y = EXPECT_CALL(foo, InitY()); +EXPECT_CALL(foo, Bar()) + .After(init_x, init_y); +``` + +says that `Bar()` can be called only after both `InitX()` and `InitY()` have +been called. + +If you don't know how many pre-requisites an expectation has when you write it, +you can use an `ExpectationSet` to collect them: + +```cpp +using ::testing::ExpectationSet; +... +ExpectationSet all_inits; +for (int i = 0; i < element_count; i++) { + all_inits += EXPECT_CALL(foo, InitElement(i)); +} +EXPECT_CALL(foo, Bar()) + .After(all_inits); +``` + +says that `Bar()` can be called only after all elements have been initialized +(but we don't care about which elements get initialized before the others). + +Modifying an `ExpectationSet` after using it in an `.After()` doesn't affect the +meaning of the `.After()`. + +### Sequences {#UsingSequences} + +When you have a long chain of sequential expectations, it's easier to specify +the order using **sequences**, which don't require you to given each expectation +in the chain a different name. *All expected calls* in the same sequence must +occur in the order they are specified. + +```cpp +using ::testing::Return; +using ::testing::Sequence; +Sequence s1, s2; +... +EXPECT_CALL(foo, Reset()) + .InSequence(s1, s2) + .WillOnce(Return(true)); +EXPECT_CALL(foo, GetSize()) + .InSequence(s1) + .WillOnce(Return(1)); +EXPECT_CALL(foo, Describe(A<const char*>())) + .InSequence(s2) + .WillOnce(Return("dummy")); +``` + +says that `Reset()` must be called before *both* `GetSize()` *and* `Describe()`, +and the latter two can occur in any order. + +To put many expectations in a sequence conveniently: + +```cpp +using ::testing::InSequence; +{ + InSequence seq; + + EXPECT_CALL(...)...; + EXPECT_CALL(...)...; + ... + EXPECT_CALL(...)...; +} +``` + +says that all expected calls in the scope of `seq` must occur in strict order. +The name `seq` is irrelevant. + +## Verifying and Resetting a Mock + +gMock will verify the expectations on a mock object when it is destructed, or +you can do it earlier: + +```cpp +using ::testing::Mock; +... +// Verifies and removes the expectations on mock_obj; +// returns true if and only if successful. +Mock::VerifyAndClearExpectations(&mock_obj); +... +// Verifies and removes the expectations on mock_obj; +// also removes the default actions set by ON_CALL(); +// returns true if and only if successful. +Mock::VerifyAndClear(&mock_obj); +``` + +You can also tell gMock that a mock object can be leaked and doesn't need to be +verified: + +```cpp +Mock::AllowLeak(&mock_obj); +``` + +## Mock Classes + +gMock defines a convenient mock class template + +```cpp +class MockFunction<R(A1, ..., An)> { + public: + MOCK_METHOD(R, Call, (A1, ..., An)); +}; +``` + +See this [recipe](cook_book.md#using-check-points) for one application of it. + +## Flags + +<!-- mdformat off(no multiline tables) --> +| Flag | Description | +| :----------------------------- | :---------------------------------------- | +| `--gmock_catch_leaked_mocks=0` | Don't report leaked mock objects as failures. | +| `--gmock_verbose=LEVEL` | Sets the default verbosity level (`info`, `warning`, or `error`) of Google Mock messages. | +<!-- mdformat on --> diff --git a/src/googletest/googlemock/docs/community_created_documentation.md b/src/googletest/googlemock/docs/community_created_documentation.md new file mode 100644 index 000000000..dfd87f7a6 --- /dev/null +++ b/src/googletest/googlemock/docs/community_created_documentation.md @@ -0,0 +1,9 @@ +# Community-Created Documentation + +go/gunit-community-created-docs + +The following is a list, in no particular order, of links to documentation +created by the Googletest community. + +* [Googlemock Insights](https://github.com/ElectricRCAircraftGuy/eRCaGuy_dotfiles/blob/master/googletest/insights.md), + by [ElectricRCAircraftGuy](https://github.com/ElectricRCAircraftGuy) diff --git a/src/googletest/googlemock/docs/cook_book.md b/src/googletest/googlemock/docs/cook_book.md new file mode 100644 index 000000000..cd6415026 --- /dev/null +++ b/src/googletest/googlemock/docs/cook_book.md @@ -0,0 +1,4266 @@ +# gMock Cookbook + +<!-- GOOGLETEST_CM0012 DO NOT DELETE --> + +You can find recipes for using gMock here. If you haven't yet, please read +[the dummy guide](for_dummies.md) first to make sure you understand the basics. + +**Note:** gMock lives in the `testing` name space. For readability, it is +recommended to write `using ::testing::Foo;` once in your file before using the +name `Foo` defined by gMock. We omit such `using` statements in this section for +brevity, but you should do it in your own code. + +<!-- GOOGLETEST_CM0035 DO NOT DELETE --> + +## Creating Mock Classes + +Mock classes are defined as normal classes, using the `MOCK_METHOD` macro to +generate mocked methods. The macro gets 3 or 4 parameters: + +```cpp +class MyMock { + public: + MOCK_METHOD(ReturnType, MethodName, (Args...)); + MOCK_METHOD(ReturnType, MethodName, (Args...), (Specs...)); +}; +``` + +The first 3 parameters are simply the method declaration, split into 3 parts. +The 4th parameter accepts a closed list of qualifiers, which affect the +generated method: + +* **`const`** - Makes the mocked method a `const` method. Required if + overriding a `const` method. +* **`override`** - Marks the method with `override`. Recommended if overriding + a `virtual` method. +* **`noexcept`** - Marks the method with `noexcept`. Required if overriding a + `noexcept` method. +* **`Calltype(...)`** - Sets the call type for the method (e.g. to + `STDMETHODCALLTYPE`), useful in Windows. +* **`ref(...)`** - Marks the method with the reference qualification + specified. Required if overriding a method that has reference + qualifications. Eg `ref(&)` or `ref(&&)`. + +### Dealing with unprotected commas + +Unprotected commas, i.e. commas which are not surrounded by parentheses, prevent +`MOCK_METHOD` from parsing its arguments correctly: + +```cpp {.bad} +class MockFoo { + public: + MOCK_METHOD(std::pair<bool, int>, GetPair, ()); // Won't compile! + MOCK_METHOD(bool, CheckMap, (std::map<int, double>, bool)); // Won't compile! +}; +``` + +Solution 1 - wrap with parentheses: + +```cpp {.good} +class MockFoo { + public: + MOCK_METHOD((std::pair<bool, int>), GetPair, ()); + MOCK_METHOD(bool, CheckMap, ((std::map<int, double>), bool)); +}; +``` + +Note that wrapping a return or argument type with parentheses is, in general, +invalid C++. `MOCK_METHOD` removes the parentheses. + +Solution 2 - define an alias: + +```cpp {.good} +class MockFoo { + public: + using BoolAndInt = std::pair<bool, int>; + MOCK_METHOD(BoolAndInt, GetPair, ()); + using MapIntDouble = std::map<int, double>; + MOCK_METHOD(bool, CheckMap, (MapIntDouble, bool)); +}; +``` + +### Mocking Private or Protected Methods + +You must always put a mock method definition (`MOCK_METHOD`) in a `public:` +section of the mock class, regardless of the method being mocked being `public`, +`protected`, or `private` in the base class. This allows `ON_CALL` and +`EXPECT_CALL` to reference the mock function from outside of the mock class. +(Yes, C++ allows a subclass to change the access level of a virtual function in +the base class.) Example: + +```cpp +class Foo { + public: + ... + virtual bool Transform(Gadget* g) = 0; + + protected: + virtual void Resume(); + + private: + virtual int GetTimeOut(); +}; + +class MockFoo : public Foo { + public: + ... + MOCK_METHOD(bool, Transform, (Gadget* g), (override)); + + // The following must be in the public section, even though the + // methods are protected or private in the base class. + MOCK_METHOD(void, Resume, (), (override)); + MOCK_METHOD(int, GetTimeOut, (), (override)); +}; +``` + +### Mocking Overloaded Methods + +You can mock overloaded functions as usual. No special attention is required: + +```cpp +class Foo { + ... + + // Must be virtual as we'll inherit from Foo. + virtual ~Foo(); + + // Overloaded on the types and/or numbers of arguments. + virtual int Add(Element x); + virtual int Add(int times, Element x); + + // Overloaded on the const-ness of this object. + virtual Bar& GetBar(); + virtual const Bar& GetBar() const; +}; + +class MockFoo : public Foo { + ... + MOCK_METHOD(int, Add, (Element x), (override)); + MOCK_METHOD(int, Add, (int times, Element x), (override)); + + MOCK_METHOD(Bar&, GetBar, (), (override)); + MOCK_METHOD(const Bar&, GetBar, (), (const, override)); +}; +``` + +**Note:** if you don't mock all versions of the overloaded method, the compiler +will give you a warning about some methods in the base class being hidden. To +fix that, use `using` to bring them in scope: + +```cpp +class MockFoo : public Foo { + ... + using Foo::Add; + MOCK_METHOD(int, Add, (Element x), (override)); + // We don't want to mock int Add(int times, Element x); + ... +}; +``` + +### Mocking Class Templates + +You can mock class templates just like any class. + +```cpp +template <typename Elem> +class StackInterface { + ... + // Must be virtual as we'll inherit from StackInterface. + virtual ~StackInterface(); + + virtual int GetSize() const = 0; + virtual void Push(const Elem& x) = 0; +}; + +template <typename Elem> +class MockStack : public StackInterface<Elem> { + ... + MOCK_METHOD(int, GetSize, (), (override)); + MOCK_METHOD(void, Push, (const Elem& x), (override)); +}; +``` + +### Mocking Non-virtual Methods {#MockingNonVirtualMethods} + +gMock can mock non-virtual functions to be used in Hi-perf dependency +injection.<!-- GOOGLETEST_CM0017 DO NOT DELETE --> + +In this case, instead of sharing a common base class with the real class, your +mock class will be *unrelated* to the real class, but contain methods with the +same signatures. The syntax for mocking non-virtual methods is the *same* as +mocking virtual methods (just don't add `override`): + +```cpp +// A simple packet stream class. None of its members is virtual. +class ConcretePacketStream { + public: + void AppendPacket(Packet* new_packet); + const Packet* GetPacket(size_t packet_number) const; + size_t NumberOfPackets() const; + ... +}; + +// A mock packet stream class. It inherits from no other, but defines +// GetPacket() and NumberOfPackets(). +class MockPacketStream { + public: + MOCK_METHOD(const Packet*, GetPacket, (size_t packet_number), (const)); + MOCK_METHOD(size_t, NumberOfPackets, (), (const)); + ... +}; +``` + +Note that the mock class doesn't define `AppendPacket()`, unlike the real class. +That's fine as long as the test doesn't need to call it. + +Next, you need a way to say that you want to use `ConcretePacketStream` in +production code, and use `MockPacketStream` in tests. Since the functions are +not virtual and the two classes are unrelated, you must specify your choice at +*compile time* (as opposed to run time). + +One way to do it is to templatize your code that needs to use a packet stream. +More specifically, you will give your code a template type argument for the type +of the packet stream. In production, you will instantiate your template with +`ConcretePacketStream` as the type argument. In tests, you will instantiate the +same template with `MockPacketStream`. For example, you may write: + +```cpp +template <class PacketStream> +void CreateConnection(PacketStream* stream) { ... } + +template <class PacketStream> +class PacketReader { + public: + void ReadPackets(PacketStream* stream, size_t packet_num); +}; +``` + +Then you can use `CreateConnection<ConcretePacketStream>()` and +`PacketReader<ConcretePacketStream>` in production code, and use +`CreateConnection<MockPacketStream>()` and `PacketReader<MockPacketStream>` in +tests. + +```cpp + MockPacketStream mock_stream; + EXPECT_CALL(mock_stream, ...)...; + .. set more expectations on mock_stream ... + PacketReader<MockPacketStream> reader(&mock_stream); + ... exercise reader ... +``` + +### Mocking Free Functions + +It's possible to use gMock to mock a free function (i.e. a C-style function or a +static method). You just need to rewrite your code to use an interface (abstract +class). + +Instead of calling a free function (say, `OpenFile`) directly, introduce an +interface for it and have a concrete subclass that calls the free function: + +```cpp +class FileInterface { + public: + ... + virtual bool Open(const char* path, const char* mode) = 0; +}; + +class File : public FileInterface { + public: + ... + virtual bool Open(const char* path, const char* mode) { + return OpenFile(path, mode); + } +}; +``` + +Your code should talk to `FileInterface` to open a file. Now it's easy to mock +out the function. + +This may seem like a lot of hassle, but in practice you often have multiple +related functions that you can put in the same interface, so the per-function +syntactic overhead will be much lower. + +If you are concerned about the performance overhead incurred by virtual +functions, and profiling confirms your concern, you can combine this with the +recipe for [mocking non-virtual methods](#MockingNonVirtualMethods). + +### Old-Style `MOCK_METHODn` Macros + +Before the generic `MOCK_METHOD` macro +[was introduced in 2018](https://github.com/google/googletest/commit/c5f08bf91944ce1b19bcf414fa1760e69d20afc2), +mocks where created using a family of macros collectively called `MOCK_METHODn`. +These macros are still supported, though migration to the new `MOCK_METHOD` is +recommended. + +The macros in the `MOCK_METHODn` family differ from `MOCK_METHOD`: + +* The general structure is `MOCK_METHODn(MethodName, ReturnType(Args))`, + instead of `MOCK_METHOD(ReturnType, MethodName, (Args))`. +* The number `n` must equal the number of arguments. +* When mocking a const method, one must use `MOCK_CONST_METHODn`. +* When mocking a class template, the macro name must be suffixed with `_T`. +* In order to specify the call type, the macro name must be suffixed with + `_WITH_CALLTYPE`, and the call type is the first macro argument. + +Old macros and their new equivalents: + +<a name="table99"></a> +<table border="1" cellspacing="0" cellpadding="1"> +<tr> <th colspan=2> Simple </th></tr> +<tr> <td> Old </td> <td> `MOCK_METHOD1(Foo, bool(int))` </td> </tr> +<tr> <td> New </td> <td> `MOCK_METHOD(bool, Foo, (int))` </td> </tr> + +<tr> <th colspan=2> Const Method </th></tr> <tr> <td> Old </td> <td> +`MOCK_CONST_METHOD1(Foo, bool(int))` </td> </tr> <tr> <td> New </td> <td> +`MOCK_METHOD(bool, Foo, (int), (const))` </td> </tr> + +<tr> <th colspan=2> Method in a Class Template </th></tr> <tr> <td> Old </td> +<td> `MOCK_METHOD1_T(Foo, bool(int))` </td> </tr> <tr> <td> New </td> <td> +`MOCK_METHOD(bool, Foo, (int))` </td> </tr> + +<tr> <th colspan=2> Const Method in a Class Template </th></tr> <tr> <td> Old +</td> <td> `MOCK_CONST_METHOD1_T(Foo, bool(int))` </td> </tr> <tr> <td> New +</td> <td> `MOCK_METHOD(bool, Foo, (int), (const))` </td> </tr> + +<tr> <th colspan=2> Method with Call Type </th></tr> <tr> <td> Old </td> <td> +`MOCK_METHOD1_WITH_CALLTYPE(STDMETHODCALLTYPE, Foo, bool(int))` </td> </tr> <tr> +<td> New </td> <td> `MOCK_METHOD(bool, Foo, (int), +(Calltype(STDMETHODCALLTYPE)))` </td> </tr> + +<tr> <th colspan=2> Const Method with Call Type </th></tr> <tr> <td> Old</td> +<td> `MOCK_CONST_METHOD1_WITH_CALLTYPE(STDMETHODCALLTYPE, Foo, bool(int))` </td> +</tr> <tr> <td> New </td> <td> `MOCK_METHOD(bool, Foo, (int), (const, +Calltype(STDMETHODCALLTYPE)))` </td> </tr> + +<tr> <th colspan=2> Method with Call Type in a Class Template </th></tr> <tr> +<td> Old </td> <td> `MOCK_METHOD1_T_WITH_CALLTYPE(STDMETHODCALLTYPE, Foo, +bool(int))` </td> </tr> <tr> <td> New </td> <td> `MOCK_METHOD(bool, Foo, (int), +(Calltype(STDMETHODCALLTYPE)))` </td> </tr> + +<tr> <th colspan=2> Const Method with Call Type in a Class Template </th></tr> +<tr> <td> Old </td> <td> `MOCK_CONST_METHOD1_T_WITH_CALLTYPE(STDMETHODCALLTYPE, +Foo, bool(int))` </td> </tr> <tr> <td> New </td> <td> `MOCK_METHOD(bool, Foo, +(int), (const, Calltype(STDMETHODCALLTYPE)))` </td> </tr> + +</table> + +### The Nice, the Strict, and the Naggy {#NiceStrictNaggy} + +If a mock method has no `EXPECT_CALL` spec but is called, we say that it's an +"uninteresting call", and the default action (which can be specified using +`ON_CALL()`) of the method will be taken. Currently, an uninteresting call will +also by default cause gMock to print a warning. (In the future, we might remove +this warning by default.) + +However, sometimes you may want to ignore these uninteresting calls, and +sometimes you may want to treat them as errors. gMock lets you make the decision +on a per-mock-object basis. + +Suppose your test uses a mock class `MockFoo`: + +```cpp +TEST(...) { + MockFoo mock_foo; + EXPECT_CALL(mock_foo, DoThis()); + ... code that uses mock_foo ... +} +``` + +If a method of `mock_foo` other than `DoThis()` is called, you will get a +warning. However, if you rewrite your test to use `NiceMock<MockFoo>` instead, +you can suppress the warning: + +```cpp +using ::testing::NiceMock; + +TEST(...) { + NiceMock<MockFoo> mock_foo; + EXPECT_CALL(mock_foo, DoThis()); + ... code that uses mock_foo ... +} +``` + +`NiceMock<MockFoo>` is a subclass of `MockFoo`, so it can be used wherever +`MockFoo` is accepted. + +It also works if `MockFoo`'s constructor takes some arguments, as +`NiceMock<MockFoo>` "inherits" `MockFoo`'s constructors: + +```cpp +using ::testing::NiceMock; + +TEST(...) { + NiceMock<MockFoo> mock_foo(5, "hi"); // Calls MockFoo(5, "hi"). + EXPECT_CALL(mock_foo, DoThis()); + ... code that uses mock_foo ... +} +``` + +The usage of `StrictMock` is similar, except that it makes all uninteresting +calls failures: + +```cpp +using ::testing::StrictMock; + +TEST(...) { + StrictMock<MockFoo> mock_foo; + EXPECT_CALL(mock_foo, DoThis()); + ... code that uses mock_foo ... + + // The test will fail if a method of mock_foo other than DoThis() + // is called. +} +``` + +NOTE: `NiceMock` and `StrictMock` only affects *uninteresting* calls (calls of +*methods* with no expectations); they do not affect *unexpected* calls (calls of +methods with expectations, but they don't match). See +[Understanding Uninteresting vs Unexpected Calls](#uninteresting-vs-unexpected). + +There are some caveats though (sadly they are side effects of C++'s +limitations): + +1. `NiceMock<MockFoo>` and `StrictMock<MockFoo>` only work for mock methods + defined using the `MOCK_METHOD` macro **directly** in the `MockFoo` class. + If a mock method is defined in a **base class** of `MockFoo`, the "nice" or + "strict" modifier may not affect it, depending on the compiler. In + particular, nesting `NiceMock` and `StrictMock` (e.g. + `NiceMock<StrictMock<MockFoo> >`) is **not** supported. +2. `NiceMock<MockFoo>` and `StrictMock<MockFoo>` may not work correctly if the + destructor of `MockFoo` is not virtual. We would like to fix this, but it + requires cleaning up existing tests. + +Finally, you should be **very cautious** about when to use naggy or strict +mocks, as they tend to make tests more brittle and harder to maintain. When you +refactor your code without changing its externally visible behavior, ideally you +shouldn't need to update any tests. If your code interacts with a naggy mock, +however, you may start to get spammed with warnings as the result of your +change. Worse, if your code interacts with a strict mock, your tests may start +to fail and you'll be forced to fix them. Our general recommendation is to use +nice mocks (not yet the default) most of the time, use naggy mocks (the current +default) when developing or debugging tests, and use strict mocks only as the +last resort. + +### Simplifying the Interface without Breaking Existing Code {#SimplerInterfaces} + +Sometimes a method has a long list of arguments that is mostly uninteresting. +For example: + +```cpp +class LogSink { + public: + ... + virtual void send(LogSeverity severity, const char* full_filename, + const char* base_filename, int line, + const struct tm* tm_time, + const char* message, size_t message_len) = 0; +}; +``` + +This method's argument list is lengthy and hard to work with (the `message` +argument is not even 0-terminated). If we mock it as is, using the mock will be +awkward. If, however, we try to simplify this interface, we'll need to fix all +clients depending on it, which is often infeasible. + +The trick is to redispatch the method in the mock class: + +```cpp +class ScopedMockLog : public LogSink { + public: + ... + virtual void send(LogSeverity severity, const char* full_filename, + const char* base_filename, int line, const tm* tm_time, + const char* message, size_t message_len) { + // We are only interested in the log severity, full file name, and + // log message. + Log(severity, full_filename, std::string(message, message_len)); + } + + // Implements the mock method: + // + // void Log(LogSeverity severity, + // const string& file_path, + // const string& message); + MOCK_METHOD(void, Log, + (LogSeverity severity, const string& file_path, + const string& message)); +}; +``` + +By defining a new mock method with a trimmed argument list, we make the mock +class more user-friendly. + +This technique may also be applied to make overloaded methods more amenable to +mocking. For example, when overloads have been used to implement default +arguments: + +```cpp +class MockTurtleFactory : public TurtleFactory { + public: + Turtle* MakeTurtle(int length, int weight) override { ... } + Turtle* MakeTurtle(int length, int weight, int speed) override { ... } + + // the above methods delegate to this one: + MOCK_METHOD(Turtle*, DoMakeTurtle, ()); +}; +``` + +This allows tests that don't care which overload was invoked to avoid specifying +argument matchers: + +```cpp +ON_CALL(factory, DoMakeTurtle) + .WillByDefault(Return(MakeMockTurtle())); +``` + +### Alternative to Mocking Concrete Classes + +Often you may find yourself using classes that don't implement interfaces. In +order to test your code that uses such a class (let's call it `Concrete`), you +may be tempted to make the methods of `Concrete` virtual and then mock it. + +Try not to do that. + +Making a non-virtual function virtual is a big decision. It creates an extension +point where subclasses can tweak your class' behavior. This weakens your control +on the class because now it's harder to maintain the class invariants. You +should make a function virtual only when there is a valid reason for a subclass +to override it. + +Mocking concrete classes directly is problematic as it creates a tight coupling +between the class and the tests - any small change in the class may invalidate +your tests and make test maintenance a pain. + +To avoid such problems, many programmers have been practicing "coding to +interfaces": instead of talking to the `Concrete` class, your code would define +an interface and talk to it. Then you implement that interface as an adaptor on +top of `Concrete`. In tests, you can easily mock that interface to observe how +your code is doing. + +This technique incurs some overhead: + +* You pay the cost of virtual function calls (usually not a problem). +* There is more abstraction for the programmers to learn. + +However, it can also bring significant benefits in addition to better +testability: + +* `Concrete`'s API may not fit your problem domain very well, as you may not + be the only client it tries to serve. By designing your own interface, you + have a chance to tailor it to your need - you may add higher-level + functionalities, rename stuff, etc instead of just trimming the class. This + allows you to write your code (user of the interface) in a more natural way, + which means it will be more readable, more maintainable, and you'll be more + productive. +* If `Concrete`'s implementation ever has to change, you don't have to rewrite + everywhere it is used. Instead, you can absorb the change in your + implementation of the interface, and your other code and tests will be + insulated from this change. + +Some people worry that if everyone is practicing this technique, they will end +up writing lots of redundant code. This concern is totally understandable. +However, there are two reasons why it may not be the case: + +* Different projects may need to use `Concrete` in different ways, so the best + interfaces for them will be different. Therefore, each of them will have its + own domain-specific interface on top of `Concrete`, and they will not be the + same code. +* If enough projects want to use the same interface, they can always share it, + just like they have been sharing `Concrete`. You can check in the interface + and the adaptor somewhere near `Concrete` (perhaps in a `contrib` + sub-directory) and let many projects use it. + +You need to weigh the pros and cons carefully for your particular problem, but +I'd like to assure you that the Java community has been practicing this for a +long time and it's a proven effective technique applicable in a wide variety of +situations. :-) + +### Delegating Calls to a Fake {#DelegatingToFake} + +Some times you have a non-trivial fake implementation of an interface. For +example: + +```cpp +class Foo { + public: + virtual ~Foo() {} + virtual char DoThis(int n) = 0; + virtual void DoThat(const char* s, int* p) = 0; +}; + +class FakeFoo : public Foo { + public: + char DoThis(int n) override { + return (n > 0) ? '+' : + (n < 0) ? '-' : '0'; + } + + void DoThat(const char* s, int* p) override { + *p = strlen(s); + } +}; +``` + +Now you want to mock this interface such that you can set expectations on it. +However, you also want to use `FakeFoo` for the default behavior, as duplicating +it in the mock object is, well, a lot of work. + +When you define the mock class using gMock, you can have it delegate its default +action to a fake class you already have, using this pattern: + +```cpp +class MockFoo : public Foo { + public: + // Normal mock method definitions using gMock. + MOCK_METHOD(char, DoThis, (int n), (override)); + MOCK_METHOD(void, DoThat, (const char* s, int* p), (override)); + + // Delegates the default actions of the methods to a FakeFoo object. + // This must be called *before* the custom ON_CALL() statements. + void DelegateToFake() { + ON_CALL(*this, DoThis).WillByDefault([this](int n) { + return fake_.DoThis(n); + }); + ON_CALL(*this, DoThat).WillByDefault([this](const char* s, int* p) { + fake_.DoThat(s, p); + }); + } + + private: + FakeFoo fake_; // Keeps an instance of the fake in the mock. +}; +``` + +With that, you can use `MockFoo` in your tests as usual. Just remember that if +you don't explicitly set an action in an `ON_CALL()` or `EXPECT_CALL()`, the +fake will be called upon to do it.: + +```cpp +using ::testing::_; + +TEST(AbcTest, Xyz) { + MockFoo foo; + + foo.DelegateToFake(); // Enables the fake for delegation. + + // Put your ON_CALL(foo, ...)s here, if any. + + // No action specified, meaning to use the default action. + EXPECT_CALL(foo, DoThis(5)); + EXPECT_CALL(foo, DoThat(_, _)); + + int n = 0; + EXPECT_EQ('+', foo.DoThis(5)); // FakeFoo::DoThis() is invoked. + foo.DoThat("Hi", &n); // FakeFoo::DoThat() is invoked. + EXPECT_EQ(2, n); +} +``` + +**Some tips:** + +* If you want, you can still override the default action by providing your own + `ON_CALL()` or using `.WillOnce()` / `.WillRepeatedly()` in `EXPECT_CALL()`. +* In `DelegateToFake()`, you only need to delegate the methods whose fake + implementation you intend to use. + +* The general technique discussed here works for overloaded methods, but + you'll need to tell the compiler which version you mean. To disambiguate a + mock function (the one you specify inside the parentheses of `ON_CALL()`), + use [this technique](#SelectOverload); to disambiguate a fake function (the + one you place inside `Invoke()`), use a `static_cast` to specify the + function's type. For instance, if class `Foo` has methods `char DoThis(int + n)` and `bool DoThis(double x) const`, and you want to invoke the latter, + you need to write `Invoke(&fake_, static_cast<bool (FakeFoo::*)(double) + const>(&FakeFoo::DoThis))` instead of `Invoke(&fake_, &FakeFoo::DoThis)` + (The strange-looking thing inside the angled brackets of `static_cast` is + the type of a function pointer to the second `DoThis()` method.). + +* Having to mix a mock and a fake is often a sign of something gone wrong. + Perhaps you haven't got used to the interaction-based way of testing yet. Or + perhaps your interface is taking on too many roles and should be split up. + Therefore, **don't abuse this**. We would only recommend to do it as an + intermediate step when you are refactoring your code. + +Regarding the tip on mixing a mock and a fake, here's an example on why it may +be a bad sign: Suppose you have a class `System` for low-level system +operations. In particular, it does file and I/O operations. And suppose you want +to test how your code uses `System` to do I/O, and you just want the file +operations to work normally. If you mock out the entire `System` class, you'll +have to provide a fake implementation for the file operation part, which +suggests that `System` is taking on too many roles. + +Instead, you can define a `FileOps` interface and an `IOOps` interface and split +`System`'s functionalities into the two. Then you can mock `IOOps` without +mocking `FileOps`. + +### Delegating Calls to a Real Object + +When using testing doubles (mocks, fakes, stubs, and etc), sometimes their +behaviors will differ from those of the real objects. This difference could be +either intentional (as in simulating an error such that you can test the error +handling code) or unintentional. If your mocks have different behaviors than the +real objects by mistake, you could end up with code that passes the tests but +fails in production. + +You can use the *delegating-to-real* technique to ensure that your mock has the +same behavior as the real object while retaining the ability to validate calls. +This technique is very similar to the [delegating-to-fake](#DelegatingToFake) +technique, the difference being that we use a real object instead of a fake. +Here's an example: + +```cpp +using ::testing::AtLeast; + +class MockFoo : public Foo { + public: + MockFoo() { + // By default, all calls are delegated to the real object. + ON_CALL(*this, DoThis).WillByDefault([this](int n) { + return real_.DoThis(n); + }); + ON_CALL(*this, DoThat).WillByDefault([this](const char* s, int* p) { + real_.DoThat(s, p); + }); + ... + } + MOCK_METHOD(char, DoThis, ...); + MOCK_METHOD(void, DoThat, ...); + ... + private: + Foo real_; +}; + +... + MockFoo mock; + EXPECT_CALL(mock, DoThis()) + .Times(3); + EXPECT_CALL(mock, DoThat("Hi")) + .Times(AtLeast(1)); + ... use mock in test ... +``` + +With this, gMock will verify that your code made the right calls (with the right +arguments, in the right order, called the right number of times, etc), and a +real object will answer the calls (so the behavior will be the same as in +production). This gives you the best of both worlds. + +### Delegating Calls to a Parent Class + +Ideally, you should code to interfaces, whose methods are all pure virtual. In +reality, sometimes you do need to mock a virtual method that is not pure (i.e, +it already has an implementation). For example: + +```cpp +class Foo { + public: + virtual ~Foo(); + + virtual void Pure(int n) = 0; + virtual int Concrete(const char* str) { ... } +}; + +class MockFoo : public Foo { + public: + // Mocking a pure method. + MOCK_METHOD(void, Pure, (int n), (override)); + // Mocking a concrete method. Foo::Concrete() is shadowed. + MOCK_METHOD(int, Concrete, (const char* str), (override)); +}; +``` + +Sometimes you may want to call `Foo::Concrete()` instead of +`MockFoo::Concrete()`. Perhaps you want to do it as part of a stub action, or +perhaps your test doesn't need to mock `Concrete()` at all (but it would be +oh-so painful to have to define a new mock class whenever you don't need to mock +one of its methods). + +You can call `Foo::Concrete()` inside an action by: + +```cpp +... + EXPECT_CALL(foo, Concrete).WillOnce([&foo](const char* str) { + return foo.Foo::Concrete(str); + }); +``` + +or tell the mock object that you don't want to mock `Concrete()`: + +```cpp +... + ON_CALL(foo, Concrete).WillByDefault([&foo](const char* str) { + return foo.Foo::Concrete(str); + }); +``` + +(Why don't we just write `{ return foo.Concrete(str); }`? If you do that, +`MockFoo::Concrete()` will be called (and cause an infinite recursion) since +`Foo::Concrete()` is virtual. That's just how C++ works.) + +## Using Matchers + +### Matching Argument Values Exactly + +You can specify exactly which arguments a mock method is expecting: + +```cpp +using ::testing::Return; +... + EXPECT_CALL(foo, DoThis(5)) + .WillOnce(Return('a')); + EXPECT_CALL(foo, DoThat("Hello", bar)); +``` + +### Using Simple Matchers + +You can use matchers to match arguments that have a certain property: + +```cpp +using ::testing::NotNull; +using ::testing::Return; +... + EXPECT_CALL(foo, DoThis(Ge(5))) // The argument must be >= 5. + .WillOnce(Return('a')); + EXPECT_CALL(foo, DoThat("Hello", NotNull())); + // The second argument must not be NULL. +``` + +A frequently used matcher is `_`, which matches anything: + +```cpp + EXPECT_CALL(foo, DoThat(_, NotNull())); +``` +<!-- GOOGLETEST_CM0022 DO NOT DELETE --> + +### Combining Matchers {#CombiningMatchers} + +You can build complex matchers from existing ones using `AllOf()`, +`AllOfArray()`, `AnyOf()`, `AnyOfArray()` and `Not()`: + +```cpp +using ::testing::AllOf; +using ::testing::Gt; +using ::testing::HasSubstr; +using ::testing::Ne; +using ::testing::Not; +... + // The argument must be > 5 and != 10. + EXPECT_CALL(foo, DoThis(AllOf(Gt(5), + Ne(10)))); + + // The first argument must not contain sub-string "blah". + EXPECT_CALL(foo, DoThat(Not(HasSubstr("blah")), + NULL)); +``` + +Matchers are function objects, and parametrized matchers can be composed just +like any other function. However because their types can be long and rarely +provide meaningful information, it can be easier to express them with C++14 +generic lambdas to avoid specifying types. For example, + +```cpp +using ::testing::Contains; +using ::testing::Property; + +inline constexpr auto HasFoo = [](const auto& f) { + return Property(&MyClass::foo, Contains(f)); +}; +... + EXPECT_THAT(x, HasFoo("blah")); +``` + +### Casting Matchers {#SafeMatcherCast} + +gMock matchers are statically typed, meaning that the compiler can catch your +mistake if you use a matcher of the wrong type (for example, if you use `Eq(5)` +to match a `string` argument). Good for you! + +Sometimes, however, you know what you're doing and want the compiler to give you +some slack. One example is that you have a matcher for `long` and the argument +you want to match is `int`. While the two types aren't exactly the same, there +is nothing really wrong with using a `Matcher<long>` to match an `int` - after +all, we can first convert the `int` argument to a `long` losslessly before +giving it to the matcher. + +To support this need, gMock gives you the `SafeMatcherCast<T>(m)` function. It +casts a matcher `m` to type `Matcher<T>`. To ensure safety, gMock checks that +(let `U` be the type `m` accepts : + +1. Type `T` can be *implicitly* cast to type `U`; +2. When both `T` and `U` are built-in arithmetic types (`bool`, integers, and + floating-point numbers), the conversion from `T` to `U` is not lossy (in + other words, any value representable by `T` can also be represented by `U`); + and +3. When `U` is a reference, `T` must also be a reference (as the underlying + matcher may be interested in the address of the `U` value). + +The code won't compile if any of these conditions isn't met. + +Here's one example: + +```cpp +using ::testing::SafeMatcherCast; + +// A base class and a child class. +class Base { ... }; +class Derived : public Base { ... }; + +class MockFoo : public Foo { + public: + MOCK_METHOD(void, DoThis, (Derived* derived), (override)); +}; + +... + MockFoo foo; + // m is a Matcher<Base*> we got from somewhere. + EXPECT_CALL(foo, DoThis(SafeMatcherCast<Derived*>(m))); +``` + +If you find `SafeMatcherCast<T>(m)` too limiting, you can use a similar function +`MatcherCast<T>(m)`. The difference is that `MatcherCast` works as long as you +can `static_cast` type `T` to type `U`. + +`MatcherCast` essentially lets you bypass C++'s type system (`static_cast` isn't +always safe as it could throw away information, for example), so be careful not +to misuse/abuse it. + +### Selecting Between Overloaded Functions {#SelectOverload} + +If you expect an overloaded function to be called, the compiler may need some +help on which overloaded version it is. + +To disambiguate functions overloaded on the const-ness of this object, use the +`Const()` argument wrapper. + +```cpp +using ::testing::ReturnRef; + +class MockFoo : public Foo { + ... + MOCK_METHOD(Bar&, GetBar, (), (override)); + MOCK_METHOD(const Bar&, GetBar, (), (const, override)); +}; + +... + MockFoo foo; + Bar bar1, bar2; + EXPECT_CALL(foo, GetBar()) // The non-const GetBar(). + .WillOnce(ReturnRef(bar1)); + EXPECT_CALL(Const(foo), GetBar()) // The const GetBar(). + .WillOnce(ReturnRef(bar2)); +``` + +(`Const()` is defined by gMock and returns a `const` reference to its argument.) + +To disambiguate overloaded functions with the same number of arguments but +different argument types, you may need to specify the exact type of a matcher, +either by wrapping your matcher in `Matcher<type>()`, or using a matcher whose +type is fixed (`TypedEq<type>`, `An<type>()`, etc): + +```cpp +using ::testing::An; +using ::testing::Matcher; +using ::testing::TypedEq; + +class MockPrinter : public Printer { + public: + MOCK_METHOD(void, Print, (int n), (override)); + MOCK_METHOD(void, Print, (char c), (override)); +}; + +TEST(PrinterTest, Print) { + MockPrinter printer; + + EXPECT_CALL(printer, Print(An<int>())); // void Print(int); + EXPECT_CALL(printer, Print(Matcher<int>(Lt(5)))); // void Print(int); + EXPECT_CALL(printer, Print(TypedEq<char>('a'))); // void Print(char); + + printer.Print(3); + printer.Print(6); + printer.Print('a'); +} +``` + +### Performing Different Actions Based on the Arguments + +When a mock method is called, the *last* matching expectation that's still +active will be selected (think "newer overrides older"). So, you can make a +method do different things depending on its argument values like this: + +```cpp +using ::testing::_; +using ::testing::Lt; +using ::testing::Return; +... + // The default case. + EXPECT_CALL(foo, DoThis(_)) + .WillRepeatedly(Return('b')); + // The more specific case. + EXPECT_CALL(foo, DoThis(Lt(5))) + .WillRepeatedly(Return('a')); +``` + +Now, if `foo.DoThis()` is called with a value less than 5, `'a'` will be +returned; otherwise `'b'` will be returned. + +### Matching Multiple Arguments as a Whole + +Sometimes it's not enough to match the arguments individually. For example, we +may want to say that the first argument must be less than the second argument. +The `With()` clause allows us to match all arguments of a mock function as a +whole. For example, + +```cpp +using ::testing::_; +using ::testing::Ne; +using ::testing::Lt; +... + EXPECT_CALL(foo, InRange(Ne(0), _)) + .With(Lt()); +``` + +says that the first argument of `InRange()` must not be 0, and must be less than +the second argument. + +The expression inside `With()` must be a matcher of type `Matcher<std::tuple<A1, +..., An>>`, where `A1`, ..., `An` are the types of the function arguments. + +You can also write `AllArgs(m)` instead of `m` inside `.With()`. The two forms +are equivalent, but `.With(AllArgs(Lt()))` is more readable than `.With(Lt())`. + +You can use `Args<k1, ..., kn>(m)` to match the `n` selected arguments (as a +tuple) against `m`. For example, + +```cpp +using ::testing::_; +using ::testing::AllOf; +using ::testing::Args; +using ::testing::Lt; +... + EXPECT_CALL(foo, Blah) + .With(AllOf(Args<0, 1>(Lt()), Args<1, 2>(Lt()))); +``` + +says that `Blah` will be called with arguments `x`, `y`, and `z` where `x < y < +z`. Note that in this example, it wasn't necessary specify the positional +matchers. + +As a convenience and example, gMock provides some matchers for 2-tuples, +including the `Lt()` matcher above. See [here](#MultiArgMatchers) for the +complete list. + +Note that if you want to pass the arguments to a predicate of your own (e.g. +`.With(Args<0, 1>(Truly(&MyPredicate)))`), that predicate MUST be written to +take a `std::tuple` as its argument; gMock will pass the `n` selected arguments +as *one* single tuple to the predicate. + +### Using Matchers as Predicates + +Have you noticed that a matcher is just a fancy predicate that also knows how to +describe itself? Many existing algorithms take predicates as arguments (e.g. +those defined in STL's `<algorithm>` header), and it would be a shame if gMock +matchers were not allowed to participate. + +Luckily, you can use a matcher where a unary predicate functor is expected by +wrapping it inside the `Matches()` function. For example, + +```cpp +#include <algorithm> +#include <vector> + +using ::testing::Matches; +using ::testing::Ge; + +vector<int> v; +... +// How many elements in v are >= 10? +const int count = count_if(v.begin(), v.end(), Matches(Ge(10))); +``` + +Since you can build complex matchers from simpler ones easily using gMock, this +gives you a way to conveniently construct composite predicates (doing the same +using STL's `<functional>` header is just painful). For example, here's a +predicate that's satisfied by any number that is >= 0, <= 100, and != 50: + +```cpp +using testing::AllOf; +using testing::Ge; +using testing::Le; +using testing::Matches; +using testing::Ne; +... +Matches(AllOf(Ge(0), Le(100), Ne(50))) +``` + +### Using Matchers in googletest Assertions + +Since matchers are basically predicates that also know how to describe +themselves, there is a way to take advantage of them in googletest assertions. +It's called `ASSERT_THAT` and `EXPECT_THAT`: + +```cpp + ASSERT_THAT(value, matcher); // Asserts that value matches matcher. + EXPECT_THAT(value, matcher); // The non-fatal version. +``` + +For example, in a googletest test you can write: + +```cpp +#include "gmock/gmock.h" + +using ::testing::AllOf; +using ::testing::Ge; +using ::testing::Le; +using ::testing::MatchesRegex; +using ::testing::StartsWith; + +... + EXPECT_THAT(Foo(), StartsWith("Hello")); + EXPECT_THAT(Bar(), MatchesRegex("Line \\d+")); + ASSERT_THAT(Baz(), AllOf(Ge(5), Le(10))); +``` + +which (as you can probably guess) executes `Foo()`, `Bar()`, and `Baz()`, and +verifies that: + +* `Foo()` returns a string that starts with `"Hello"`. +* `Bar()` returns a string that matches regular expression `"Line \\d+"`. +* `Baz()` returns a number in the range [5, 10]. + +The nice thing about these macros is that *they read like English*. They +generate informative messages too. For example, if the first `EXPECT_THAT()` +above fails, the message will be something like: + +```cpp +Value of: Foo() + Actual: "Hi, world!" +Expected: starts with "Hello" +``` + +**Credit:** The idea of `(ASSERT|EXPECT)_THAT` was borrowed from Joe Walnes' +Hamcrest project, which adds `assertThat()` to JUnit. + +### Using Predicates as Matchers + +gMock provides a [built-in set](cheat_sheet.md#MatcherList) of matchers. In case +you find them lacking, you can use an arbitrary unary predicate function or +functor as a matcher - as long as the predicate accepts a value of the type you +want. You do this by wrapping the predicate inside the `Truly()` function, for +example: + +```cpp +using ::testing::Truly; + +int IsEven(int n) { return (n % 2) == 0 ? 1 : 0; } +... + // Bar() must be called with an even number. + EXPECT_CALL(foo, Bar(Truly(IsEven))); +``` + +Note that the predicate function / functor doesn't have to return `bool`. It +works as long as the return value can be used as the condition in in statement +`if (condition) ...`. + +<!-- GOOGLETEST_CM0023 DO NOT DELETE --> + +### Matching Arguments that Are Not Copyable + +When you do an `EXPECT_CALL(mock_obj, Foo(bar))`, gMock saves away a copy of +`bar`. When `Foo()` is called later, gMock compares the argument to `Foo()` with +the saved copy of `bar`. This way, you don't need to worry about `bar` being +modified or destroyed after the `EXPECT_CALL()` is executed. The same is true +when you use matchers like `Eq(bar)`, `Le(bar)`, and so on. + +But what if `bar` cannot be copied (i.e. has no copy constructor)? You could +define your own matcher function or callback and use it with `Truly()`, as the +previous couple of recipes have shown. Or, you may be able to get away from it +if you can guarantee that `bar` won't be changed after the `EXPECT_CALL()` is +executed. Just tell gMock that it should save a reference to `bar`, instead of a +copy of it. Here's how: + +```cpp +using ::testing::Eq; +using ::testing::Lt; +... + // Expects that Foo()'s argument == bar. + EXPECT_CALL(mock_obj, Foo(Eq(std::ref(bar)))); + + // Expects that Foo()'s argument < bar. + EXPECT_CALL(mock_obj, Foo(Lt(std::ref(bar)))); +``` + +Remember: if you do this, don't change `bar` after the `EXPECT_CALL()`, or the +result is undefined. + +### Validating a Member of an Object + +Often a mock function takes a reference to object as an argument. When matching +the argument, you may not want to compare the entire object against a fixed +object, as that may be over-specification. Instead, you may need to validate a +certain member variable or the result of a certain getter method of the object. +You can do this with `Field()` and `Property()`. More specifically, + +```cpp +Field(&Foo::bar, m) +``` + +is a matcher that matches a `Foo` object whose `bar` member variable satisfies +matcher `m`. + +```cpp +Property(&Foo::baz, m) +``` + +is a matcher that matches a `Foo` object whose `baz()` method returns a value +that satisfies matcher `m`. + +For example: + +<!-- mdformat off(github rendering does not support multiline tables) --> +| Expression | Description | +| :--------------------------- | :--------------------------------------- | +| `Field(&Foo::number, Ge(3))` | Matches `x` where `x.number >= 3`. | +| `Property(&Foo::name, StartsWith("John "))` | Matches `x` where `x.name()` starts with `"John "`. | +<!-- mdformat on --> + +Note that in `Property(&Foo::baz, ...)`, method `baz()` must take no argument +and be declared as `const`. + +BTW, `Field()` and `Property()` can also match plain pointers to objects. For +instance, + +```cpp +using ::testing::Field; +using ::testing::Ge; +... +Field(&Foo::number, Ge(3)) +``` + +matches a plain pointer `p` where `p->number >= 3`. If `p` is `NULL`, the match +will always fail regardless of the inner matcher. + +What if you want to validate more than one members at the same time? Remember +that there are [`AllOf()` and `AllOfArray()`](#CombiningMatchers). + +Finally `Field()` and `Property()` provide overloads that take the field or +property names as the first argument to include it in the error message. This +can be useful when creating combined matchers. + +```cpp +using ::testing::AllOf; +using ::testing::Field; +using ::testing::Matcher; +using ::testing::SafeMatcherCast; + +Matcher<Foo> IsFoo(const Foo& foo) { + return AllOf(Field("some_field", &Foo::some_field, foo.some_field), + Field("other_field", &Foo::other_field, foo.other_field), + Field("last_field", &Foo::last_field, foo.last_field)); +} +``` + +### Validating the Value Pointed to by a Pointer Argument + +C++ functions often take pointers as arguments. You can use matchers like +`IsNull()`, `NotNull()`, and other comparison matchers to match a pointer, but +what if you want to make sure the value *pointed to* by the pointer, instead of +the pointer itself, has a certain property? Well, you can use the `Pointee(m)` +matcher. + +`Pointee(m)` matches a pointer if and only if `m` matches the value the pointer +points to. For example: + +```cpp +using ::testing::Ge; +using ::testing::Pointee; +... + EXPECT_CALL(foo, Bar(Pointee(Ge(3)))); +``` + +expects `foo.Bar()` to be called with a pointer that points to a value greater +than or equal to 3. + +One nice thing about `Pointee()` is that it treats a `NULL` pointer as a match +failure, so you can write `Pointee(m)` instead of + +```cpp +using ::testing::AllOf; +using ::testing::NotNull; +using ::testing::Pointee; +... + AllOf(NotNull(), Pointee(m)) +``` + +without worrying that a `NULL` pointer will crash your test. + +Also, did we tell you that `Pointee()` works with both raw pointers **and** +smart pointers (`std::unique_ptr`, `std::shared_ptr`, etc)? + +What if you have a pointer to pointer? You guessed it - you can use nested +`Pointee()` to probe deeper inside the value. For example, +`Pointee(Pointee(Lt(3)))` matches a pointer that points to a pointer that points +to a number less than 3 (what a mouthful...). + +### Testing a Certain Property of an Object + +Sometimes you want to specify that an object argument has a certain property, +but there is no existing matcher that does this. If you want good error +messages, you should [define a matcher](#NewMatchers). If you want to do it +quick and dirty, you could get away with writing an ordinary function. + +Let's say you have a mock function that takes an object of type `Foo`, which has +an `int bar()` method and an `int baz()` method, and you want to constrain that +the argument's `bar()` value plus its `baz()` value is a given number. Here's +how you can define a matcher to do it: + +```cpp +using ::testing::Matcher; +using ::testing::MatcherInterface; +using ::testing::MatchResultListener; + +class BarPlusBazEqMatcher : public MatcherInterface<const Foo&> { + public: + explicit BarPlusBazEqMatcher(int expected_sum) + : expected_sum_(expected_sum) {} + + bool MatchAndExplain(const Foo& foo, + MatchResultListener* /* listener */) const override { + return (foo.bar() + foo.baz()) == expected_sum_; + } + + void DescribeTo(std::ostream* os) const override { + *os << "bar() + baz() equals " << expected_sum_; + } + + void DescribeNegationTo(std::ostream* os) const override { + *os << "bar() + baz() does not equal " << expected_sum_; + } + private: + const int expected_sum_; +}; + +Matcher<const Foo&> BarPlusBazEq(int expected_sum) { + return MakeMatcher(new BarPlusBazEqMatcher(expected_sum)); +} + +... + EXPECT_CALL(..., DoThis(BarPlusBazEq(5)))...; +``` + +### Matching Containers + +Sometimes an STL container (e.g. list, vector, map, ...) is passed to a mock +function and you may want to validate it. Since most STL containers support the +`==` operator, you can write `Eq(expected_container)` or simply +`expected_container` to match a container exactly. + +Sometimes, though, you may want to be more flexible (for example, the first +element must be an exact match, but the second element can be any positive +number, and so on). Also, containers used in tests often have a small number of +elements, and having to define the expected container out-of-line is a bit of a +hassle. + +You can use the `ElementsAre()` or `UnorderedElementsAre()` matcher in such +cases: + +```cpp +using ::testing::_; +using ::testing::ElementsAre; +using ::testing::Gt; +... + MOCK_METHOD(void, Foo, (const vector<int>& numbers), (override)); +... + EXPECT_CALL(mock, Foo(ElementsAre(1, Gt(0), _, 5))); +``` + +The above matcher says that the container must have 4 elements, which must be 1, +greater than 0, anything, and 5 respectively. + +If you instead write: + +```cpp +using ::testing::_; +using ::testing::Gt; +using ::testing::UnorderedElementsAre; +... + MOCK_METHOD(void, Foo, (const vector<int>& numbers), (override)); +... + EXPECT_CALL(mock, Foo(UnorderedElementsAre(1, Gt(0), _, 5))); +``` + +It means that the container must have 4 elements, which (under some permutation) +must be 1, greater than 0, anything, and 5 respectively. + +As an alternative you can place the arguments in a C-style array and use +`ElementsAreArray()` or `UnorderedElementsAreArray()` instead: + +```cpp +using ::testing::ElementsAreArray; +... + // ElementsAreArray accepts an array of element values. + const int expected_vector1[] = {1, 5, 2, 4, ...}; + EXPECT_CALL(mock, Foo(ElementsAreArray(expected_vector1))); + + // Or, an array of element matchers. + Matcher<int> expected_vector2[] = {1, Gt(2), _, 3, ...}; + EXPECT_CALL(mock, Foo(ElementsAreArray(expected_vector2))); +``` + +In case the array needs to be dynamically created (and therefore the array size +cannot be inferred by the compiler), you can give `ElementsAreArray()` an +additional argument to specify the array size: + +```cpp +using ::testing::ElementsAreArray; +... + int* const expected_vector3 = new int[count]; + ... fill expected_vector3 with values ... + EXPECT_CALL(mock, Foo(ElementsAreArray(expected_vector3, count))); +``` + +Use `Pair` when comparing maps or other associative containers. + +```cpp +using testing::ElementsAre; +using testing::Pair; +... + std::map<string, int> m = {{"a", 1}, {"b", 2}, {"c", 3}}; + EXPECT_THAT(m, ElementsAre(Pair("a", 1), Pair("b", 2), Pair("c", 3))); +``` + +**Tips:** + +* `ElementsAre*()` can be used to match *any* container that implements the + STL iterator pattern (i.e. it has a `const_iterator` type and supports + `begin()/end()`), not just the ones defined in STL. It will even work with + container types yet to be written - as long as they follows the above + pattern. +* You can use nested `ElementsAre*()` to match nested (multi-dimensional) + containers. +* If the container is passed by pointer instead of by reference, just write + `Pointee(ElementsAre*(...))`. +* The order of elements *matters* for `ElementsAre*()`. If you are using it + with containers whose element order are undefined (e.g. `hash_map`) you + should use `WhenSorted` around `ElementsAre`. + +### Sharing Matchers + +Under the hood, a gMock matcher object consists of a pointer to a ref-counted +implementation object. Copying matchers is allowed and very efficient, as only +the pointer is copied. When the last matcher that references the implementation +object dies, the implementation object will be deleted. + +Therefore, if you have some complex matcher that you want to use again and +again, there is no need to build it everytime. Just assign it to a matcher +variable and use that variable repeatedly! For example, + +```cpp +using ::testing::AllOf; +using ::testing::Gt; +using ::testing::Le; +using ::testing::Matcher; +... + Matcher<int> in_range = AllOf(Gt(5), Le(10)); + ... use in_range as a matcher in multiple EXPECT_CALLs ... +``` + +### Matchers must have no side-effects {#PureMatchers} + +WARNING: gMock does not guarantee when or how many times a matcher will be +invoked. Therefore, all matchers must be *purely functional*: they cannot have +any side effects, and the match result must not depend on anything other than +the matcher's parameters and the value being matched. + +This requirement must be satisfied no matter how a matcher is defined (e.g., if +it is one of the standard matchers, or a custom matcher). In particular, a +matcher can never call a mock function, as that will affect the state of the +mock object and gMock. + +## Setting Expectations + +### Knowing When to Expect {#UseOnCall} + +<!-- GOOGLETEST_CM0018 DO NOT DELETE --> + +**`ON_CALL`** is likely the *single most under-utilized construct* in gMock. + +There are basically two constructs for defining the behavior of a mock object: +`ON_CALL` and `EXPECT_CALL`. The difference? `ON_CALL` defines what happens when +a mock method is called, but <em>doesn't imply any expectation on the method +being called</em>. `EXPECT_CALL` not only defines the behavior, but also sets an +expectation that <em>the method will be called with the given arguments, for the +given number of times</em> (and *in the given order* when you specify the order +too). + +Since `EXPECT_CALL` does more, isn't it better than `ON_CALL`? Not really. Every +`EXPECT_CALL` adds a constraint on the behavior of the code under test. Having +more constraints than necessary is *baaad* - even worse than not having enough +constraints. + +This may be counter-intuitive. How could tests that verify more be worse than +tests that verify less? Isn't verification the whole point of tests? + +The answer lies in *what* a test should verify. **A good test verifies the +contract of the code.** If a test over-specifies, it doesn't leave enough +freedom to the implementation. As a result, changing the implementation without +breaking the contract (e.g. refactoring and optimization), which should be +perfectly fine to do, can break such tests. Then you have to spend time fixing +them, only to see them broken again the next time the implementation is changed. + +Keep in mind that one doesn't have to verify more than one property in one test. +In fact, **it's a good style to verify only one thing in one test.** If you do +that, a bug will likely break only one or two tests instead of dozens (which +case would you rather debug?). If you are also in the habit of giving tests +descriptive names that tell what they verify, you can often easily guess what's +wrong just from the test log itself. + +So use `ON_CALL` by default, and only use `EXPECT_CALL` when you actually intend +to verify that the call is made. For example, you may have a bunch of `ON_CALL`s +in your test fixture to set the common mock behavior shared by all tests in the +same group, and write (scarcely) different `EXPECT_CALL`s in different `TEST_F`s +to verify different aspects of the code's behavior. Compared with the style +where each `TEST` has many `EXPECT_CALL`s, this leads to tests that are more +resilient to implementational changes (and thus less likely to require +maintenance) and makes the intent of the tests more obvious (so they are easier +to maintain when you do need to maintain them). + +If you are bothered by the "Uninteresting mock function call" message printed +when a mock method without an `EXPECT_CALL` is called, you may use a `NiceMock` +instead to suppress all such messages for the mock object, or suppress the +message for specific methods by adding `EXPECT_CALL(...).Times(AnyNumber())`. DO +NOT suppress it by blindly adding an `EXPECT_CALL(...)`, or you'll have a test +that's a pain to maintain. + +### Ignoring Uninteresting Calls + +If you are not interested in how a mock method is called, just don't say +anything about it. In this case, if the method is ever called, gMock will +perform its default action to allow the test program to continue. If you are not +happy with the default action taken by gMock, you can override it using +`DefaultValue<T>::Set()` (described [here](#DefaultValue)) or `ON_CALL()`. + +Please note that once you expressed interest in a particular mock method (via +`EXPECT_CALL()`), all invocations to it must match some expectation. If this +function is called but the arguments don't match any `EXPECT_CALL()` statement, +it will be an error. + +### Disallowing Unexpected Calls + +If a mock method shouldn't be called at all, explicitly say so: + +```cpp +using ::testing::_; +... + EXPECT_CALL(foo, Bar(_)) + .Times(0); +``` + +If some calls to the method are allowed, but the rest are not, just list all the +expected calls: + +```cpp +using ::testing::AnyNumber; +using ::testing::Gt; +... + EXPECT_CALL(foo, Bar(5)); + EXPECT_CALL(foo, Bar(Gt(10))) + .Times(AnyNumber()); +``` + +A call to `foo.Bar()` that doesn't match any of the `EXPECT_CALL()` statements +will be an error. + +### Understanding Uninteresting vs Unexpected Calls {#uninteresting-vs-unexpected} + +*Uninteresting* calls and *unexpected* calls are different concepts in gMock. +*Very* different. + +A call `x.Y(...)` is **uninteresting** if there's *not even a single* +`EXPECT_CALL(x, Y(...))` set. In other words, the test isn't interested in the +`x.Y()` method at all, as evident in that the test doesn't care to say anything +about it. + +A call `x.Y(...)` is **unexpected** if there are *some* `EXPECT_CALL(x, +Y(...))`s set, but none of them matches the call. Put another way, the test is +interested in the `x.Y()` method (therefore it explicitly sets some +`EXPECT_CALL` to verify how it's called); however, the verification fails as the +test doesn't expect this particular call to happen. + +**An unexpected call is always an error,** as the code under test doesn't behave +the way the test expects it to behave. + +**By default, an uninteresting call is not an error,** as it violates no +constraint specified by the test. (gMock's philosophy is that saying nothing +means there is no constraint.) However, it leads to a warning, as it *might* +indicate a problem (e.g. the test author might have forgotten to specify a +constraint). + +In gMock, `NiceMock` and `StrictMock` can be used to make a mock class "nice" or +"strict". How does this affect uninteresting calls and unexpected calls? + +A **nice mock** suppresses uninteresting call *warnings*. It is less chatty than +the default mock, but otherwise is the same. If a test fails with a default +mock, it will also fail using a nice mock instead. And vice versa. Don't expect +making a mock nice to change the test's result. + +A **strict mock** turns uninteresting call warnings into errors. So making a +mock strict may change the test's result. + +Let's look at an example: + +```cpp +TEST(...) { + NiceMock<MockDomainRegistry> mock_registry; + EXPECT_CALL(mock_registry, GetDomainOwner("google.com")) + .WillRepeatedly(Return("Larry Page")); + + // Use mock_registry in code under test. + ... &mock_registry ... +} +``` + +The sole `EXPECT_CALL` here says that all calls to `GetDomainOwner()` must have +`"google.com"` as the argument. If `GetDomainOwner("yahoo.com")` is called, it +will be an unexpected call, and thus an error. *Having a nice mock doesn't +change the severity of an unexpected call.* + +So how do we tell gMock that `GetDomainOwner()` can be called with some other +arguments as well? The standard technique is to add a "catch all" `EXPECT_CALL`: + +```cpp + EXPECT_CALL(mock_registry, GetDomainOwner(_)) + .Times(AnyNumber()); // catches all other calls to this method. + EXPECT_CALL(mock_registry, GetDomainOwner("google.com")) + .WillRepeatedly(Return("Larry Page")); +``` + +Remember that `_` is the wildcard matcher that matches anything. With this, if +`GetDomainOwner("google.com")` is called, it will do what the second +`EXPECT_CALL` says; if it is called with a different argument, it will do what +the first `EXPECT_CALL` says. + +Note that the order of the two `EXPECT_CALL`s is important, as a newer +`EXPECT_CALL` takes precedence over an older one. + +For more on uninteresting calls, nice mocks, and strict mocks, read +["The Nice, the Strict, and the Naggy"](#NiceStrictNaggy). + +### Ignoring Uninteresting Arguments {#ParameterlessExpectations} + +If your test doesn't care about the parameters (it only cares about the number +or order of calls), you can often simply omit the parameter list: + +```cpp + // Expect foo.Bar( ... ) twice with any arguments. + EXPECT_CALL(foo, Bar).Times(2); + + // Delegate to the given method whenever the factory is invoked. + ON_CALL(foo_factory, MakeFoo) + .WillByDefault(&BuildFooForTest); +``` + +This functionality is only available when a method is not overloaded; to prevent +unexpected behavior it is a compilation error to try to set an expectation on a +method where the specific overload is ambiguous. You can work around this by +supplying a [simpler mock interface](#SimplerInterfaces) than the mocked class +provides. + +This pattern is also useful when the arguments are interesting, but match logic +is substantially complex. You can leave the argument list unspecified and use +SaveArg actions to [save the values for later verification](#SaveArgVerify). If +you do that, you can easily differentiate calling the method the wrong number of +times from calling it with the wrong arguments. + +### Expecting Ordered Calls {#OrderedCalls} + +Although an `EXPECT_CALL()` statement defined later takes precedence when gMock +tries to match a function call with an expectation, by default calls don't have +to happen in the order `EXPECT_CALL()` statements are written. For example, if +the arguments match the matchers in the second `EXPECT_CALL()`, but not those in +the first and third, then the second expectation will be used. + +If you would rather have all calls occur in the order of the expectations, put +the `EXPECT_CALL()` statements in a block where you define a variable of type +`InSequence`: + +```cpp +using ::testing::_; +using ::testing::InSequence; + + { + InSequence s; + + EXPECT_CALL(foo, DoThis(5)); + EXPECT_CALL(bar, DoThat(_)) + .Times(2); + EXPECT_CALL(foo, DoThis(6)); + } +``` + +In this example, we expect a call to `foo.DoThis(5)`, followed by two calls to +`bar.DoThat()` where the argument can be anything, which are in turn followed by +a call to `foo.DoThis(6)`. If a call occurred out-of-order, gMock will report an +error. + +### Expecting Partially Ordered Calls {#PartialOrder} + +Sometimes requiring everything to occur in a predetermined order can lead to +brittle tests. For example, we may care about `A` occurring before both `B` and +`C`, but aren't interested in the relative order of `B` and `C`. In this case, +the test should reflect our real intent, instead of being overly constraining. + +gMock allows you to impose an arbitrary DAG (directed acyclic graph) on the +calls. One way to express the DAG is to use the +[After](cheat_sheet.md#AfterClause) clause of `EXPECT_CALL`. + +Another way is via the `InSequence()` clause (not the same as the `InSequence` +class), which we borrowed from jMock 2. It's less flexible than `After()`, but +more convenient when you have long chains of sequential calls, as it doesn't +require you to come up with different names for the expectations in the chains. +Here's how it works: + +If we view `EXPECT_CALL()` statements as nodes in a graph, and add an edge from +node A to node B wherever A must occur before B, we can get a DAG. We use the +term "sequence" to mean a directed path in this DAG. Now, if we decompose the +DAG into sequences, we just need to know which sequences each `EXPECT_CALL()` +belongs to in order to be able to reconstruct the original DAG. + +So, to specify the partial order on the expectations we need to do two things: +first to define some `Sequence` objects, and then for each `EXPECT_CALL()` say +which `Sequence` objects it is part of. + +Expectations in the same sequence must occur in the order they are written. For +example, + +```cpp +using ::testing::Sequence; +... + Sequence s1, s2; + + EXPECT_CALL(foo, A()) + .InSequence(s1, s2); + EXPECT_CALL(bar, B()) + .InSequence(s1); + EXPECT_CALL(bar, C()) + .InSequence(s2); + EXPECT_CALL(foo, D()) + .InSequence(s2); +``` + +specifies the following DAG (where `s1` is `A -> B`, and `s2` is `A -> C -> D`): + +```text + +---> B + | + A ---| + | + +---> C ---> D +``` + +This means that A must occur before B and C, and C must occur before D. There's +no restriction about the order other than these. + +### Controlling When an Expectation Retires + +When a mock method is called, gMock only considers expectations that are still +active. An expectation is active when created, and becomes inactive (aka +*retires*) when a call that has to occur later has occurred. For example, in + +```cpp +using ::testing::_; +using ::testing::Sequence; +... + Sequence s1, s2; + + EXPECT_CALL(log, Log(WARNING, _, "File too large.")) // #1 + .Times(AnyNumber()) + .InSequence(s1, s2); + EXPECT_CALL(log, Log(WARNING, _, "Data set is empty.")) // #2 + .InSequence(s1); + EXPECT_CALL(log, Log(WARNING, _, "User not found.")) // #3 + .InSequence(s2); +``` + +as soon as either #2 or #3 is matched, #1 will retire. If a warning `"File too +large."` is logged after this, it will be an error. + +Note that an expectation doesn't retire automatically when it's saturated. For +example, + +```cpp +using ::testing::_; +... + EXPECT_CALL(log, Log(WARNING, _, _)); // #1 + EXPECT_CALL(log, Log(WARNING, _, "File too large.")); // #2 +``` + +says that there will be exactly one warning with the message `"File too +large."`. If the second warning contains this message too, #2 will match again +and result in an upper-bound-violated error. + +If this is not what you want, you can ask an expectation to retire as soon as it +becomes saturated: + +```cpp +using ::testing::_; +... + EXPECT_CALL(log, Log(WARNING, _, _)); // #1 + EXPECT_CALL(log, Log(WARNING, _, "File too large.")) // #2 + .RetiresOnSaturation(); +``` + +Here #2 can be used only once, so if you have two warnings with the message +`"File too large."`, the first will match #2 and the second will match #1 - +there will be no error. + +## Using Actions + +### Returning References from Mock Methods + +If a mock function's return type is a reference, you need to use `ReturnRef()` +instead of `Return()` to return a result: + +```cpp +using ::testing::ReturnRef; + +class MockFoo : public Foo { + public: + MOCK_METHOD(Bar&, GetBar, (), (override)); +}; +... + MockFoo foo; + Bar bar; + EXPECT_CALL(foo, GetBar()) + .WillOnce(ReturnRef(bar)); +... +``` + +### Returning Live Values from Mock Methods + +The `Return(x)` action saves a copy of `x` when the action is created, and +always returns the same value whenever it's executed. Sometimes you may want to +instead return the *live* value of `x` (i.e. its value at the time when the +action is *executed*.). Use either `ReturnRef()` or `ReturnPointee()` for this +purpose. + +If the mock function's return type is a reference, you can do it using +`ReturnRef(x)`, as shown in the previous recipe ("Returning References from Mock +Methods"). However, gMock doesn't let you use `ReturnRef()` in a mock function +whose return type is not a reference, as doing that usually indicates a user +error. So, what shall you do? + +Though you may be tempted, DO NOT use `std::ref()`: + +```cpp +using testing::Return; + +class MockFoo : public Foo { + public: + MOCK_METHOD(int, GetValue, (), (override)); +}; +... + int x = 0; + MockFoo foo; + EXPECT_CALL(foo, GetValue()) + .WillRepeatedly(Return(std::ref(x))); // Wrong! + x = 42; + EXPECT_EQ(42, foo.GetValue()); +``` + +Unfortunately, it doesn't work here. The above code will fail with error: + +```text +Value of: foo.GetValue() + Actual: 0 +Expected: 42 +``` + +The reason is that `Return(*value*)` converts `value` to the actual return type +of the mock function at the time when the action is *created*, not when it is +*executed*. (This behavior was chosen for the action to be safe when `value` is +a proxy object that references some temporary objects.) As a result, +`std::ref(x)` is converted to an `int` value (instead of a `const int&`) when +the expectation is set, and `Return(std::ref(x))` will always return 0. + +`ReturnPointee(pointer)` was provided to solve this problem specifically. It +returns the value pointed to by `pointer` at the time the action is *executed*: + +```cpp +using testing::ReturnPointee; +... + int x = 0; + MockFoo foo; + EXPECT_CALL(foo, GetValue()) + .WillRepeatedly(ReturnPointee(&x)); // Note the & here. + x = 42; + EXPECT_EQ(42, foo.GetValue()); // This will succeed now. +``` + +### Combining Actions + +Want to do more than one thing when a function is called? That's fine. `DoAll()` +allow you to do sequence of actions every time. Only the return value of the +last action in the sequence will be used. + +```cpp +using ::testing::_; +using ::testing::DoAll; + +class MockFoo : public Foo { + public: + MOCK_METHOD(bool, Bar, (int n), (override)); +}; +... + EXPECT_CALL(foo, Bar(_)) + .WillOnce(DoAll(action_1, + action_2, + ... + action_n)); +``` + +### Verifying Complex Arguments {#SaveArgVerify} + +If you want to verify that a method is called with a particular argument but the +match criteria is complex, it can be difficult to distinguish between +cardinality failures (calling the method the wrong number of times) and argument +match failures. Similarly, if you are matching multiple parameters, it may not +be easy to distinguishing which argument failed to match. For example: + +```cpp + // Not ideal: this could fail because of a problem with arg1 or arg2, or maybe + // just the method wasn't called. + EXPECT_CALL(foo, SendValues(_, ElementsAre(1, 4, 4, 7), EqualsProto( ... ))); +``` + +You can instead save the arguments and test them individually: + +```cpp + EXPECT_CALL(foo, SendValues) + .WillOnce(DoAll(SaveArg<1>(&actual_array), SaveArg<2>(&actual_proto))); + ... run the test + EXPECT_THAT(actual_array, ElementsAre(1, 4, 4, 7)); + EXPECT_THAT(actual_proto, EqualsProto( ... )); +``` + +### Mocking Side Effects {#MockingSideEffects} + +Sometimes a method exhibits its effect not via returning a value but via side +effects. For example, it may change some global state or modify an output +argument. To mock side effects, in general you can define your own action by +implementing `::testing::ActionInterface`. + +If all you need to do is to change an output argument, the built-in +`SetArgPointee()` action is convenient: + +```cpp +using ::testing::_; +using ::testing::SetArgPointee; + +class MockMutator : public Mutator { + public: + MOCK_METHOD(void, Mutate, (bool mutate, int* value), (override)); + ... +} +... + MockMutator mutator; + EXPECT_CALL(mutator, Mutate(true, _)) + .WillOnce(SetArgPointee<1>(5)); +``` + +In this example, when `mutator.Mutate()` is called, we will assign 5 to the +`int` variable pointed to by argument #1 (0-based). + +`SetArgPointee()` conveniently makes an internal copy of the value you pass to +it, removing the need to keep the value in scope and alive. The implication +however is that the value must have a copy constructor and assignment operator. + +If the mock method also needs to return a value as well, you can chain +`SetArgPointee()` with `Return()` using `DoAll()`, remembering to put the +`Return()` statement last: + +```cpp +using ::testing::_; +using ::testing::Return; +using ::testing::SetArgPointee; + +class MockMutator : public Mutator { + public: + ... + MOCK_METHOD(bool, MutateInt, (int* value), (override)); +} +... + MockMutator mutator; + EXPECT_CALL(mutator, MutateInt(_)) + .WillOnce(DoAll(SetArgPointee<0>(5), + Return(true))); +``` + +Note, however, that if you use the `ReturnOKWith()` method, it will override the +values provided by `SetArgPointee()` in the response parameters of your function +call. + +If the output argument is an array, use the `SetArrayArgument<N>(first, last)` +action instead. It copies the elements in source range `[first, last)` to the +array pointed to by the `N`-th (0-based) argument: + +```cpp +using ::testing::NotNull; +using ::testing::SetArrayArgument; + +class MockArrayMutator : public ArrayMutator { + public: + MOCK_METHOD(void, Mutate, (int* values, int num_values), (override)); + ... +} +... + MockArrayMutator mutator; + int values[5] = {1, 2, 3, 4, 5}; + EXPECT_CALL(mutator, Mutate(NotNull(), 5)) + .WillOnce(SetArrayArgument<0>(values, values + 5)); +``` + +This also works when the argument is an output iterator: + +```cpp +using ::testing::_; +using ::testing::SetArrayArgument; + +class MockRolodex : public Rolodex { + public: + MOCK_METHOD(void, GetNames, (std::back_insert_iterator<vector<string>>), + (override)); + ... +} +... + MockRolodex rolodex; + vector<string> names; + names.push_back("George"); + names.push_back("John"); + names.push_back("Thomas"); + EXPECT_CALL(rolodex, GetNames(_)) + .WillOnce(SetArrayArgument<0>(names.begin(), names.end())); +``` + +### Changing a Mock Object's Behavior Based on the State + +If you expect a call to change the behavior of a mock object, you can use +`::testing::InSequence` to specify different behaviors before and after the +call: + +```cpp +using ::testing::InSequence; +using ::testing::Return; + +... + { + InSequence seq; + EXPECT_CALL(my_mock, IsDirty()) + .WillRepeatedly(Return(true)); + EXPECT_CALL(my_mock, Flush()); + EXPECT_CALL(my_mock, IsDirty()) + .WillRepeatedly(Return(false)); + } + my_mock.FlushIfDirty(); +``` + +This makes `my_mock.IsDirty()` return `true` before `my_mock.Flush()` is called +and return `false` afterwards. + +If the behavior change is more complex, you can store the effects in a variable +and make a mock method get its return value from that variable: + +```cpp +using ::testing::_; +using ::testing::SaveArg; +using ::testing::Return; + +ACTION_P(ReturnPointee, p) { return *p; } +... + int previous_value = 0; + EXPECT_CALL(my_mock, GetPrevValue) + .WillRepeatedly(ReturnPointee(&previous_value)); + EXPECT_CALL(my_mock, UpdateValue) + .WillRepeatedly(SaveArg<0>(&previous_value)); + my_mock.DoSomethingToUpdateValue(); +``` + +Here `my_mock.GetPrevValue()` will always return the argument of the last +`UpdateValue()` call. + +### Setting the Default Value for a Return Type {#DefaultValue} + +If a mock method's return type is a built-in C++ type or pointer, by default it +will return 0 when invoked. Also, in C++ 11 and above, a mock method whose +return type has a default constructor will return a default-constructed value by +default. You only need to specify an action if this default value doesn't work +for you. + +Sometimes, you may want to change this default value, or you may want to specify +a default value for types gMock doesn't know about. You can do this using the +`::testing::DefaultValue` class template: + +```cpp +using ::testing::DefaultValue; + +class MockFoo : public Foo { + public: + MOCK_METHOD(Bar, CalculateBar, (), (override)); +}; + + +... + Bar default_bar; + // Sets the default return value for type Bar. + DefaultValue<Bar>::Set(default_bar); + + MockFoo foo; + + // We don't need to specify an action here, as the default + // return value works for us. + EXPECT_CALL(foo, CalculateBar()); + + foo.CalculateBar(); // This should return default_bar. + + // Unsets the default return value. + DefaultValue<Bar>::Clear(); +``` + +Please note that changing the default value for a type can make your tests hard +to understand. We recommend you to use this feature judiciously. For example, +you may want to make sure the `Set()` and `Clear()` calls are right next to the +code that uses your mock. + +### Setting the Default Actions for a Mock Method + +You've learned how to change the default value of a given type. However, this +may be too coarse for your purpose: perhaps you have two mock methods with the +same return type and you want them to have different behaviors. The `ON_CALL()` +macro allows you to customize your mock's behavior at the method level: + +```cpp +using ::testing::_; +using ::testing::AnyNumber; +using ::testing::Gt; +using ::testing::Return; +... + ON_CALL(foo, Sign(_)) + .WillByDefault(Return(-1)); + ON_CALL(foo, Sign(0)) + .WillByDefault(Return(0)); + ON_CALL(foo, Sign(Gt(0))) + .WillByDefault(Return(1)); + + EXPECT_CALL(foo, Sign(_)) + .Times(AnyNumber()); + + foo.Sign(5); // This should return 1. + foo.Sign(-9); // This should return -1. + foo.Sign(0); // This should return 0. +``` + +As you may have guessed, when there are more than one `ON_CALL()` statements, +the newer ones in the order take precedence over the older ones. In other words, +the **last** one that matches the function arguments will be used. This matching +order allows you to set up the common behavior in a mock object's constructor or +the test fixture's set-up phase and specialize the mock's behavior later. + +Note that both `ON_CALL` and `EXPECT_CALL` have the same "later statements take +precedence" rule, but they don't interact. That is, `EXPECT_CALL`s have their +own precedence order distinct from the `ON_CALL` precedence order. + +### Using Functions/Methods/Functors/Lambdas as Actions {#FunctionsAsActions} + +If the built-in actions don't suit you, you can use an existing callable +(function, `std::function`, method, functor, lambda) as an action. + +<!-- GOOGLETEST_CM0024 DO NOT DELETE --> + +```cpp +using ::testing::_; using ::testing::Invoke; + +class MockFoo : public Foo { + public: + MOCK_METHOD(int, Sum, (int x, int y), (override)); + MOCK_METHOD(bool, ComplexJob, (int x), (override)); +}; + +int CalculateSum(int x, int y) { return x + y; } +int Sum3(int x, int y, int z) { return x + y + z; } + +class Helper { + public: + bool ComplexJob(int x); +}; + +... + MockFoo foo; + Helper helper; + EXPECT_CALL(foo, Sum(_, _)) + .WillOnce(&CalculateSum) + .WillRepeatedly(Invoke(NewPermanentCallback(Sum3, 1))); + EXPECT_CALL(foo, ComplexJob(_)) + .WillOnce(Invoke(&helper, &Helper::ComplexJob)) + .WillOnce([] { return true; }) + .WillRepeatedly([](int x) { return x > 0; }); + + foo.Sum(5, 6); // Invokes CalculateSum(5, 6). + foo.Sum(2, 3); // Invokes Sum3(1, 2, 3). + foo.ComplexJob(10); // Invokes helper.ComplexJob(10). + foo.ComplexJob(-1); // Invokes the inline lambda. +``` + +The only requirement is that the type of the function, etc must be *compatible* +with the signature of the mock function, meaning that the latter's arguments (if +it takes any) can be implicitly converted to the corresponding arguments of the +former, and the former's return type can be implicitly converted to that of the +latter. So, you can invoke something whose type is *not* exactly the same as the +mock function, as long as it's safe to do so - nice, huh? + +**`Note:`{.escaped}** + +* The action takes ownership of the callback and will delete it when the + action itself is destructed. +* If the type of a callback is derived from a base callback type `C`, you need + to implicitly cast it to `C` to resolve the overloading, e.g. + + ```cpp + using ::testing::Invoke; + ... + ResultCallback<bool>* is_ok = ...; + ... Invoke(is_ok) ...; // This works. + + BlockingClosure* done = new BlockingClosure; + ... Invoke(implicit_cast<Closure*>(done)) ...; // The cast is necessary. + ``` + +### Using Functions with Extra Info as Actions + +The function or functor you call using `Invoke()` must have the same number of +arguments as the mock function you use it for. Sometimes you may have a function +that takes more arguments, and you are willing to pass in the extra arguments +yourself to fill the gap. You can do this in gMock using callbacks with +pre-bound arguments. Here's an example: + +```cpp +using ::testing::Invoke; + +class MockFoo : public Foo { + public: + MOCK_METHOD(char, DoThis, (int n), (override)); +}; + +char SignOfSum(int x, int y) { + const int sum = x + y; + return (sum > 0) ? '+' : (sum < 0) ? '-' : '0'; +} + +TEST_F(FooTest, Test) { + MockFoo foo; + + EXPECT_CALL(foo, DoThis(2)) + .WillOnce(Invoke(NewPermanentCallback(SignOfSum, 5))); + EXPECT_EQ('+', foo.DoThis(2)); // Invokes SignOfSum(5, 2). +} +``` + +### Invoking a Function/Method/Functor/Lambda/Callback Without Arguments + +`Invoke()` passes the mock function's arguments to the function, etc being +invoked such that the callee has the full context of the call to work with. If +the invoked function is not interested in some or all of the arguments, it can +simply ignore them. + +Yet, a common pattern is that a test author wants to invoke a function without +the arguments of the mock function. She could do that using a wrapper function +that throws away the arguments before invoking an underlining nullary function. +Needless to say, this can be tedious and obscures the intent of the test. + +There are two solutions to this problem. First, you can pass any callable of +zero args as an action. Alternatively, use `InvokeWithoutArgs()`, which is like +`Invoke()` except that it doesn't pass the mock function's arguments to the +callee. Here's an example of each: + +```cpp +using ::testing::_; +using ::testing::InvokeWithoutArgs; + +class MockFoo : public Foo { + public: + MOCK_METHOD(bool, ComplexJob, (int n), (override)); +}; + +bool Job1() { ... } +bool Job2(int n, char c) { ... } + +... + MockFoo foo; + EXPECT_CALL(foo, ComplexJob(_)) + .WillOnce([] { Job1(); }); + .WillOnce(InvokeWithoutArgs(NewPermanentCallback(Job2, 5, 'a'))); + + foo.ComplexJob(10); // Invokes Job1(). + foo.ComplexJob(20); // Invokes Job2(5, 'a'). +``` + +**`Note:`{.escaped}** + +* The action takes ownership of the callback and will delete it when the + action itself is destructed. +* If the type of a callback is derived from a base callback type `C`, you need + to implicitly cast it to `C` to resolve the overloading, e.g. + + ```cpp + using ::testing::InvokeWithoutArgs; + ... + ResultCallback<bool>* is_ok = ...; + ... InvokeWithoutArgs(is_ok) ...; // This works. + + BlockingClosure* done = ...; + ... InvokeWithoutArgs(implicit_cast<Closure*>(done)) ...; + // The cast is necessary. + ``` + +### Invoking an Argument of the Mock Function + +Sometimes a mock function will receive a function pointer, a functor (in other +words, a "callable") as an argument, e.g. + +```cpp +class MockFoo : public Foo { + public: + MOCK_METHOD(bool, DoThis, (int n, (ResultCallback1<bool, int>* callback)), + (override)); +}; +``` + +and you may want to invoke this callable argument: + +```cpp +using ::testing::_; +... + MockFoo foo; + EXPECT_CALL(foo, DoThis(_, _)) + .WillOnce(...); + // Will execute callback->Run(5), where callback is the + // second argument DoThis() receives. +``` + +NOTE: The section below is legacy documentation from before C++ had lambdas: + +Arghh, you need to refer to a mock function argument but C++ has no lambda +(yet), so you have to define your own action. :-( Or do you really? + +Well, gMock has an action to solve *exactly* this problem: + +```cpp +InvokeArgument<N>(arg_1, arg_2, ..., arg_m) +``` + +will invoke the `N`-th (0-based) argument the mock function receives, with +`arg_1`, `arg_2`, ..., and `arg_m`. No matter if the argument is a function +pointer, a functor, or a callback. gMock handles them all. + +With that, you could write: + +```cpp +using ::testing::_; +using ::testing::InvokeArgument; +... + EXPECT_CALL(foo, DoThis(_, _)) + .WillOnce(InvokeArgument<1>(5)); + // Will execute callback->Run(5), where callback is the + // second argument DoThis() receives. +``` + +What if the callable takes an argument by reference? No problem - just wrap it +inside `std::ref()`: + +```cpp + ... + MOCK_METHOD(bool, Bar, + ((ResultCallback2<bool, int, const Helper&>* callback)), + (override)); + ... + using ::testing::_; + using ::testing::InvokeArgument; + ... + MockFoo foo; + Helper helper; + ... + EXPECT_CALL(foo, Bar(_)) + .WillOnce(InvokeArgument<0>(5, std::ref(helper))); + // std::ref(helper) guarantees that a reference to helper, not a copy of + // it, will be passed to the callback. +``` + +What if the callable takes an argument by reference and we do **not** wrap the +argument in `std::ref()`? Then `InvokeArgument()` will *make a copy* of the +argument, and pass a *reference to the copy*, instead of a reference to the +original value, to the callable. This is especially handy when the argument is a +temporary value: + +```cpp + ... + MOCK_METHOD(bool, DoThat, (bool (*f)(const double& x, const string& s)), + (override)); + ... + using ::testing::_; + using ::testing::InvokeArgument; + ... + MockFoo foo; + ... + EXPECT_CALL(foo, DoThat(_)) + .WillOnce(InvokeArgument<0>(5.0, string("Hi"))); + // Will execute (*f)(5.0, string("Hi")), where f is the function pointer + // DoThat() receives. Note that the values 5.0 and string("Hi") are + // temporary and dead once the EXPECT_CALL() statement finishes. Yet + // it's fine to perform this action later, since a copy of the values + // are kept inside the InvokeArgument action. +``` + +### Ignoring an Action's Result + +Sometimes you have an action that returns *something*, but you need an action +that returns `void` (perhaps you want to use it in a mock function that returns +`void`, or perhaps it needs to be used in `DoAll()` and it's not the last in the +list). `IgnoreResult()` lets you do that. For example: + +```cpp +using ::testing::_; +using ::testing::DoAll; +using ::testing::IgnoreResult; +using ::testing::Return; + +int Process(const MyData& data); +string DoSomething(); + +class MockFoo : public Foo { + public: + MOCK_METHOD(void, Abc, (const MyData& data), (override)); + MOCK_METHOD(bool, Xyz, (), (override)); +}; + + ... + MockFoo foo; + EXPECT_CALL(foo, Abc(_)) + // .WillOnce(Invoke(Process)); + // The above line won't compile as Process() returns int but Abc() needs + // to return void. + .WillOnce(IgnoreResult(Process)); + EXPECT_CALL(foo, Xyz()) + .WillOnce(DoAll(IgnoreResult(DoSomething), + // Ignores the string DoSomething() returns. + Return(true))); +``` + +Note that you **cannot** use `IgnoreResult()` on an action that already returns +`void`. Doing so will lead to ugly compiler errors. + +### Selecting an Action's Arguments {#SelectingArgs} + +Say you have a mock function `Foo()` that takes seven arguments, and you have a +custom action that you want to invoke when `Foo()` is called. Trouble is, the +custom action only wants three arguments: + +```cpp +using ::testing::_; +using ::testing::Invoke; +... + MOCK_METHOD(bool, Foo, + (bool visible, const string& name, int x, int y, + (const map<pair<int, int>>), double& weight, double min_weight, + double max_wight)); +... +bool IsVisibleInQuadrant1(bool visible, int x, int y) { + return visible && x >= 0 && y >= 0; +} +... + EXPECT_CALL(mock, Foo) + .WillOnce(Invoke(IsVisibleInQuadrant1)); // Uh, won't compile. :-( +``` + +To please the compiler God, you need to define an "adaptor" that has the same +signature as `Foo()` and calls the custom action with the right arguments: + +```cpp +using ::testing::_; +using ::testing::Invoke; +... +bool MyIsVisibleInQuadrant1(bool visible, const string& name, int x, int y, + const map<pair<int, int>, double>& weight, + double min_weight, double max_wight) { + return IsVisibleInQuadrant1(visible, x, y); +} +... + EXPECT_CALL(mock, Foo) + .WillOnce(Invoke(MyIsVisibleInQuadrant1)); // Now it works. +``` + +But isn't this awkward? + +gMock provides a generic *action adaptor*, so you can spend your time minding +more important business than writing your own adaptors. Here's the syntax: + +```cpp +WithArgs<N1, N2, ..., Nk>(action) +``` + +creates an action that passes the arguments of the mock function at the given +indices (0-based) to the inner `action` and performs it. Using `WithArgs`, our +original example can be written as: + +```cpp +using ::testing::_; +using ::testing::Invoke; +using ::testing::WithArgs; +... + EXPECT_CALL(mock, Foo) + .WillOnce(WithArgs<0, 2, 3>(Invoke(IsVisibleInQuadrant1))); // No need to define your own adaptor. +``` + +For better readability, gMock also gives you: + +* `WithoutArgs(action)` when the inner `action` takes *no* argument, and +* `WithArg<N>(action)` (no `s` after `Arg`) when the inner `action` takes + *one* argument. + +As you may have realized, `InvokeWithoutArgs(...)` is just syntactic sugar for +`WithoutArgs(Invoke(...))`. + +Here are more tips: + +* The inner action used in `WithArgs` and friends does not have to be + `Invoke()` -- it can be anything. +* You can repeat an argument in the argument list if necessary, e.g. + `WithArgs<2, 3, 3, 5>(...)`. +* You can change the order of the arguments, e.g. `WithArgs<3, 2, 1>(...)`. +* The types of the selected arguments do *not* have to match the signature of + the inner action exactly. It works as long as they can be implicitly + converted to the corresponding arguments of the inner action. For example, + if the 4-th argument of the mock function is an `int` and `my_action` takes + a `double`, `WithArg<4>(my_action)` will work. + +### Ignoring Arguments in Action Functions + +The [selecting-an-action's-arguments](#SelectingArgs) recipe showed us one way +to make a mock function and an action with incompatible argument lists fit +together. The downside is that wrapping the action in `WithArgs<...>()` can get +tedious for people writing the tests. + +If you are defining a function (or method, functor, lambda, callback) to be used +with `Invoke*()`, and you are not interested in some of its arguments, an +alternative to `WithArgs` is to declare the uninteresting arguments as `Unused`. +This makes the definition less cluttered and less fragile in case the types of +the uninteresting arguments change. It could also increase the chance the action +function can be reused. For example, given + +```cpp + public: + MOCK_METHOD(double, Foo, double(const string& label, double x, double y), + (override)); + MOCK_METHOD(double, Bar, (int index, double x, double y), (override)); +``` + +instead of + +```cpp +using ::testing::_; +using ::testing::Invoke; + +double DistanceToOriginWithLabel(const string& label, double x, double y) { + return sqrt(x*x + y*y); +} +double DistanceToOriginWithIndex(int index, double x, double y) { + return sqrt(x*x + y*y); +} +... + EXPECT_CALL(mock, Foo("abc", _, _)) + .WillOnce(Invoke(DistanceToOriginWithLabel)); + EXPECT_CALL(mock, Bar(5, _, _)) + .WillOnce(Invoke(DistanceToOriginWithIndex)); +``` + +you could write + +```cpp +using ::testing::_; +using ::testing::Invoke; +using ::testing::Unused; + +double DistanceToOrigin(Unused, double x, double y) { + return sqrt(x*x + y*y); +} +... + EXPECT_CALL(mock, Foo("abc", _, _)) + .WillOnce(Invoke(DistanceToOrigin)); + EXPECT_CALL(mock, Bar(5, _, _)) + .WillOnce(Invoke(DistanceToOrigin)); +``` + +### Sharing Actions + +Just like matchers, a gMock action object consists of a pointer to a ref-counted +implementation object. Therefore copying actions is also allowed and very +efficient. When the last action that references the implementation object dies, +the implementation object will be deleted. + +If you have some complex action that you want to use again and again, you may +not have to build it from scratch everytime. If the action doesn't have an +internal state (i.e. if it always does the same thing no matter how many times +it has been called), you can assign it to an action variable and use that +variable repeatedly. For example: + +```cpp +using ::testing::Action; +using ::testing::DoAll; +using ::testing::Return; +using ::testing::SetArgPointee; +... + Action<bool(int*)> set_flag = DoAll(SetArgPointee<0>(5), + Return(true)); + ... use set_flag in .WillOnce() and .WillRepeatedly() ... +``` + +However, if the action has its own state, you may be surprised if you share the +action object. Suppose you have an action factory `IncrementCounter(init)` which +creates an action that increments and returns a counter whose initial value is +`init`, using two actions created from the same expression and using a shared +action will exhibit different behaviors. Example: + +```cpp + EXPECT_CALL(foo, DoThis()) + .WillRepeatedly(IncrementCounter(0)); + EXPECT_CALL(foo, DoThat()) + .WillRepeatedly(IncrementCounter(0)); + foo.DoThis(); // Returns 1. + foo.DoThis(); // Returns 2. + foo.DoThat(); // Returns 1 - Blah() uses a different + // counter than Bar()'s. +``` + +versus + +```cpp +using ::testing::Action; +... + Action<int()> increment = IncrementCounter(0); + EXPECT_CALL(foo, DoThis()) + .WillRepeatedly(increment); + EXPECT_CALL(foo, DoThat()) + .WillRepeatedly(increment); + foo.DoThis(); // Returns 1. + foo.DoThis(); // Returns 2. + foo.DoThat(); // Returns 3 - the counter is shared. +``` + +### Testing Asynchronous Behavior + +One oft-encountered problem with gMock is that it can be hard to test +asynchronous behavior. Suppose you had a `EventQueue` class that you wanted to +test, and you created a separate `EventDispatcher` interface so that you could +easily mock it out. However, the implementation of the class fired all the +events on a background thread, which made test timings difficult. You could just +insert `sleep()` statements and hope for the best, but that makes your test +behavior nondeterministic. A better way is to use gMock actions and +`Notification` objects to force your asynchronous test to behave synchronously. + +```cpp +using ::testing::DoAll; +using ::testing::InvokeWithoutArgs; +using ::testing::Return; + +class MockEventDispatcher : public EventDispatcher { + MOCK_METHOD(bool, DispatchEvent, (int32), (override)); +}; + +ACTION_P(Notify, notification) { + notification->Notify(); +} + +TEST(EventQueueTest, EnqueueEventTest) { + MockEventDispatcher mock_event_dispatcher; + EventQueue event_queue(&mock_event_dispatcher); + + const int32 kEventId = 321; + absl::Notification done; + EXPECT_CALL(mock_event_dispatcher, DispatchEvent(kEventId)) + .WillOnce(Notify(&done)); + + event_queue.EnqueueEvent(kEventId); + done.WaitForNotification(); +} +``` + +In the example above, we set our normal gMock expectations, but then add an +additional action to notify the `Notification` object. Now we can just call +`Notification::WaitForNotification()` in the main thread to wait for the +asynchronous call to finish. After that, our test suite is complete and we can +safely exit. + +Note: this example has a downside: namely, if the expectation is not satisfied, +our test will run forever. It will eventually time-out and fail, but it will +take longer and be slightly harder to debug. To alleviate this problem, you can +use `WaitForNotificationWithTimeout(ms)` instead of `WaitForNotification()`. + +## Misc Recipes on Using gMock + +### Mocking Methods That Use Move-Only Types + +C++11 introduced *move-only types*. A move-only-typed value can be moved from +one object to another, but cannot be copied. `std::unique_ptr<T>` is probably +the most commonly used move-only type. + +Mocking a method that takes and/or returns move-only types presents some +challenges, but nothing insurmountable. This recipe shows you how you can do it. +Note that the support for move-only method arguments was only introduced to +gMock in April 2017; in older code, you may find more complex +[workarounds](#LegacyMoveOnly) for lack of this feature. + +Let’s say we are working on a fictional project that lets one post and share +snippets called “buzzes”. Your code uses these types: + +```cpp +enum class AccessLevel { kInternal, kPublic }; + +class Buzz { + public: + explicit Buzz(AccessLevel access) { ... } + ... +}; + +class Buzzer { + public: + virtual ~Buzzer() {} + virtual std::unique_ptr<Buzz> MakeBuzz(StringPiece text) = 0; + virtual bool ShareBuzz(std::unique_ptr<Buzz> buzz, int64_t timestamp) = 0; + ... +}; +``` + +A `Buzz` object represents a snippet being posted. A class that implements the +`Buzzer` interface is capable of creating and sharing `Buzz`es. Methods in +`Buzzer` may return a `unique_ptr<Buzz>` or take a `unique_ptr<Buzz>`. Now we +need to mock `Buzzer` in our tests. + +To mock a method that accepts or returns move-only types, you just use the +familiar `MOCK_METHOD` syntax as usual: + +```cpp +class MockBuzzer : public Buzzer { + public: + MOCK_METHOD(std::unique_ptr<Buzz>, MakeBuzz, (StringPiece text), (override)); + MOCK_METHOD(bool, ShareBuzz, (std::unique_ptr<Buzz> buzz, int64_t timestamp), + (override)); +}; +``` + +Now that we have the mock class defined, we can use it in tests. In the +following code examples, we assume that we have defined a `MockBuzzer` object +named `mock_buzzer_`: + +```cpp + MockBuzzer mock_buzzer_; +``` + +First let’s see how we can set expectations on the `MakeBuzz()` method, which +returns a `unique_ptr<Buzz>`. + +As usual, if you set an expectation without an action (i.e. the `.WillOnce()` or +`.WillRepeatedly()` clause), when that expectation fires, the default action for +that method will be taken. Since `unique_ptr<>` has a default constructor that +returns a null `unique_ptr`, that’s what you’ll get if you don’t specify an +action: + +```cpp + // Use the default action. + EXPECT_CALL(mock_buzzer_, MakeBuzz("hello")); + + // Triggers the previous EXPECT_CALL. + EXPECT_EQ(nullptr, mock_buzzer_.MakeBuzz("hello")); +``` + +If you are not happy with the default action, you can tweak it as usual; see +[Setting Default Actions](#OnCall). + +If you just need to return a pre-defined move-only value, you can use the +`Return(ByMove(...))` action: + +```cpp + // When this fires, the unique_ptr<> specified by ByMove(...) will + // be returned. + EXPECT_CALL(mock_buzzer_, MakeBuzz("world")) + .WillOnce(Return(ByMove(MakeUnique<Buzz>(AccessLevel::kInternal)))); + + EXPECT_NE(nullptr, mock_buzzer_.MakeBuzz("world")); +``` + +Note that `ByMove()` is essential here - if you drop it, the code won’t compile. + +Quiz time! What do you think will happen if a `Return(ByMove(...))` action is +performed more than once (e.g. you write `... +.WillRepeatedly(Return(ByMove(...)));`)? Come think of it, after the first time +the action runs, the source value will be consumed (since it’s a move-only +value), so the next time around, there’s no value to move from -- you’ll get a +run-time error that `Return(ByMove(...))` can only be run once. + +If you need your mock method to do more than just moving a pre-defined value, +remember that you can always use a lambda or a callable object, which can do +pretty much anything you want: + +```cpp + EXPECT_CALL(mock_buzzer_, MakeBuzz("x")) + .WillRepeatedly([](StringPiece text) { + return MakeUnique<Buzz>(AccessLevel::kInternal); + }); + + EXPECT_NE(nullptr, mock_buzzer_.MakeBuzz("x")); + EXPECT_NE(nullptr, mock_buzzer_.MakeBuzz("x")); +``` + +Every time this `EXPECT_CALL` fires, a new `unique_ptr<Buzz>` will be created +and returned. You cannot do this with `Return(ByMove(...))`. + +That covers returning move-only values; but how do we work with methods +accepting move-only arguments? The answer is that they work normally, although +some actions will not compile when any of method's arguments are move-only. You +can always use `Return`, or a [lambda or functor](#FunctionsAsActions): + +```cpp + using ::testing::Unused; + + EXPECT_CALL(mock_buzzer_, ShareBuzz(NotNull(), _)).WillOnce(Return(true)); + EXPECT_TRUE(mock_buzzer_.ShareBuzz(MakeUnique<Buzz>(AccessLevel::kInternal)), + 0); + + EXPECT_CALL(mock_buzzer_, ShareBuzz(_, _)).WillOnce( + [](std::unique_ptr<Buzz> buzz, Unused) { return buzz != nullptr; }); + EXPECT_FALSE(mock_buzzer_.ShareBuzz(nullptr, 0)); +``` + +Many built-in actions (`WithArgs`, `WithoutArgs`,`DeleteArg`, `SaveArg`, ...) +could in principle support move-only arguments, but the support for this is not +implemented yet. If this is blocking you, please file a bug. + +A few actions (e.g. `DoAll`) copy their arguments internally, so they can never +work with non-copyable objects; you'll have to use functors instead. + +#### Legacy workarounds for move-only types {#LegacyMoveOnly} + +Support for move-only function arguments was only introduced to gMock in April +2017. In older code, you may encounter the following workaround for the lack of +this feature (it is no longer necessary - we're including it just for +reference): + +```cpp +class MockBuzzer : public Buzzer { + public: + MOCK_METHOD(bool, DoShareBuzz, (Buzz* buzz, Time timestamp)); + bool ShareBuzz(std::unique_ptr<Buzz> buzz, Time timestamp) override { + return DoShareBuzz(buzz.get(), timestamp); + } +}; +``` + +The trick is to delegate the `ShareBuzz()` method to a mock method (let’s call +it `DoShareBuzz()`) that does not take move-only parameters. Then, instead of +setting expectations on `ShareBuzz()`, you set them on the `DoShareBuzz()` mock +method: + +```cpp + MockBuzzer mock_buzzer_; + EXPECT_CALL(mock_buzzer_, DoShareBuzz(NotNull(), _)); + + // When one calls ShareBuzz() on the MockBuzzer like this, the call is + // forwarded to DoShareBuzz(), which is mocked. Therefore this statement + // will trigger the above EXPECT_CALL. + mock_buzzer_.ShareBuzz(MakeUnique<Buzz>(AccessLevel::kInternal), 0); +``` + +### Making the Compilation Faster + +Believe it or not, the *vast majority* of the time spent on compiling a mock +class is in generating its constructor and destructor, as they perform +non-trivial tasks (e.g. verification of the expectations). What's more, mock +methods with different signatures have different types and thus their +constructors/destructors need to be generated by the compiler separately. As a +result, if you mock many different types of methods, compiling your mock class +can get really slow. + +If you are experiencing slow compilation, you can move the definition of your +mock class' constructor and destructor out of the class body and into a `.cc` +file. This way, even if you `#include` your mock class in N files, the compiler +only needs to generate its constructor and destructor once, resulting in a much +faster compilation. + +Let's illustrate the idea using an example. Here's the definition of a mock +class before applying this recipe: + +```cpp +// File mock_foo.h. +... +class MockFoo : public Foo { + public: + // Since we don't declare the constructor or the destructor, + // the compiler will generate them in every translation unit + // where this mock class is used. + + MOCK_METHOD(int, DoThis, (), (override)); + MOCK_METHOD(bool, DoThat, (const char* str), (override)); + ... more mock methods ... +}; +``` + +After the change, it would look like: + +```cpp +// File mock_foo.h. +... +class MockFoo : public Foo { + public: + // The constructor and destructor are declared, but not defined, here. + MockFoo(); + virtual ~MockFoo(); + + MOCK_METHOD(int, DoThis, (), (override)); + MOCK_METHOD(bool, DoThat, (const char* str), (override)); + ... more mock methods ... +}; +``` + +and + +```cpp +// File mock_foo.cc. +#include "path/to/mock_foo.h" + +// The definitions may appear trivial, but the functions actually do a +// lot of things through the constructors/destructors of the member +// variables used to implement the mock methods. +MockFoo::MockFoo() {} +MockFoo::~MockFoo() {} +``` + +### Forcing a Verification + +When it's being destroyed, your friendly mock object will automatically verify +that all expectations on it have been satisfied, and will generate googletest +failures if not. This is convenient as it leaves you with one less thing to +worry about. That is, unless you are not sure if your mock object will be +destroyed. + +How could it be that your mock object won't eventually be destroyed? Well, it +might be created on the heap and owned by the code you are testing. Suppose +there's a bug in that code and it doesn't delete the mock object properly - you +could end up with a passing test when there's actually a bug. + +Using a heap checker is a good idea and can alleviate the concern, but its +implementation is not 100% reliable. So, sometimes you do want to *force* gMock +to verify a mock object before it is (hopefully) destructed. You can do this +with `Mock::VerifyAndClearExpectations(&mock_object)`: + +```cpp +TEST(MyServerTest, ProcessesRequest) { + using ::testing::Mock; + + MockFoo* const foo = new MockFoo; + EXPECT_CALL(*foo, ...)...; + // ... other expectations ... + + // server now owns foo. + MyServer server(foo); + server.ProcessRequest(...); + + // In case that server's destructor will forget to delete foo, + // this will verify the expectations anyway. + Mock::VerifyAndClearExpectations(foo); +} // server is destroyed when it goes out of scope here. +``` + +**Tip:** The `Mock::VerifyAndClearExpectations()` function returns a `bool` to +indicate whether the verification was successful (`true` for yes), so you can +wrap that function call inside a `ASSERT_TRUE()` if there is no point going +further when the verification has failed. + +### Using Check Points {#UsingCheckPoints} + +Sometimes you may want to "reset" a mock object at various check points in your +test: at each check point, you verify that all existing expectations on the mock +object have been satisfied, and then you set some new expectations on it as if +it's newly created. This allows you to work with a mock object in "phases" whose +sizes are each manageable. + +One such scenario is that in your test's `SetUp()` function, you may want to put +the object you are testing into a certain state, with the help from a mock +object. Once in the desired state, you want to clear all expectations on the +mock, such that in the `TEST_F` body you can set fresh expectations on it. + +As you may have figured out, the `Mock::VerifyAndClearExpectations()` function +we saw in the previous recipe can help you here. Or, if you are using +`ON_CALL()` to set default actions on the mock object and want to clear the +default actions as well, use `Mock::VerifyAndClear(&mock_object)` instead. This +function does what `Mock::VerifyAndClearExpectations(&mock_object)` does and +returns the same `bool`, **plus** it clears the `ON_CALL()` statements on +`mock_object` too. + +Another trick you can use to achieve the same effect is to put the expectations +in sequences and insert calls to a dummy "check-point" function at specific +places. Then you can verify that the mock function calls do happen at the right +time. For example, if you are exercising code: + +```cpp + Foo(1); + Foo(2); + Foo(3); +``` + +and want to verify that `Foo(1)` and `Foo(3)` both invoke `mock.Bar("a")`, but +`Foo(2)` doesn't invoke anything. You can write: + +```cpp +using ::testing::MockFunction; + +TEST(FooTest, InvokesBarCorrectly) { + MyMock mock; + // Class MockFunction<F> has exactly one mock method. It is named + // Call() and has type F. + MockFunction<void(string check_point_name)> check; + { + InSequence s; + + EXPECT_CALL(mock, Bar("a")); + EXPECT_CALL(check, Call("1")); + EXPECT_CALL(check, Call("2")); + EXPECT_CALL(mock, Bar("a")); + } + Foo(1); + check.Call("1"); + Foo(2); + check.Call("2"); + Foo(3); +} +``` + +The expectation spec says that the first `Bar("a")` must happen before check +point "1", the second `Bar("a")` must happen after check point "2", and nothing +should happen between the two check points. The explicit check points make it +easy to tell which `Bar("a")` is called by which call to `Foo()`. + +### Mocking Destructors + +Sometimes you want to make sure a mock object is destructed at the right time, +e.g. after `bar->A()` is called but before `bar->B()` is called. We already know +that you can specify constraints on the [order](#OrderedCalls) of mock function +calls, so all we need to do is to mock the destructor of the mock function. + +This sounds simple, except for one problem: a destructor is a special function +with special syntax and special semantics, and the `MOCK_METHOD` macro doesn't +work for it: + +```cpp +MOCK_METHOD(void, ~MockFoo, ()); // Won't compile! +``` + +The good news is that you can use a simple pattern to achieve the same effect. +First, add a mock function `Die()` to your mock class and call it in the +destructor, like this: + +```cpp +class MockFoo : public Foo { + ... + // Add the following two lines to the mock class. + MOCK_METHOD(void, Die, ()); + ~MockFoo() override { Die(); } +}; +``` + +(If the name `Die()` clashes with an existing symbol, choose another name.) Now, +we have translated the problem of testing when a `MockFoo` object dies to +testing when its `Die()` method is called: + +```cpp + MockFoo* foo = new MockFoo; + MockBar* bar = new MockBar; + ... + { + InSequence s; + + // Expects *foo to die after bar->A() and before bar->B(). + EXPECT_CALL(*bar, A()); + EXPECT_CALL(*foo, Die()); + EXPECT_CALL(*bar, B()); + } +``` + +And that's that. + +### Using gMock and Threads {#UsingThreads} + +In a **unit** test, it's best if you could isolate and test a piece of code in a +single-threaded context. That avoids race conditions and dead locks, and makes +debugging your test much easier. + +Yet most programs are multi-threaded, and sometimes to test something we need to +pound on it from more than one thread. gMock works for this purpose too. + +Remember the steps for using a mock: + +1. Create a mock object `foo`. +2. Set its default actions and expectations using `ON_CALL()` and + `EXPECT_CALL()`. +3. The code under test calls methods of `foo`. +4. Optionally, verify and reset the mock. +5. Destroy the mock yourself, or let the code under test destroy it. The + destructor will automatically verify it. + +If you follow the following simple rules, your mocks and threads can live +happily together: + +* Execute your *test code* (as opposed to the code being tested) in *one* + thread. This makes your test easy to follow. +* Obviously, you can do step #1 without locking. +* When doing step #2 and #5, make sure no other thread is accessing `foo`. + Obvious too, huh? +* #3 and #4 can be done either in one thread or in multiple threads - anyway + you want. gMock takes care of the locking, so you don't have to do any - + unless required by your test logic. + +If you violate the rules (for example, if you set expectations on a mock while +another thread is calling its methods), you get undefined behavior. That's not +fun, so don't do it. + +gMock guarantees that the action for a mock function is done in the same thread +that called the mock function. For example, in + +```cpp + EXPECT_CALL(mock, Foo(1)) + .WillOnce(action1); + EXPECT_CALL(mock, Foo(2)) + .WillOnce(action2); +``` + +if `Foo(1)` is called in thread 1 and `Foo(2)` is called in thread 2, gMock will +execute `action1` in thread 1 and `action2` in thread 2. + +gMock does *not* impose a sequence on actions performed in different threads +(doing so may create deadlocks as the actions may need to cooperate). This means +that the execution of `action1` and `action2` in the above example *may* +interleave. If this is a problem, you should add proper synchronization logic to +`action1` and `action2` to make the test thread-safe. + +Also, remember that `DefaultValue<T>` is a global resource that potentially +affects *all* living mock objects in your program. Naturally, you won't want to +mess with it from multiple threads or when there still are mocks in action. + +### Controlling How Much Information gMock Prints + +When gMock sees something that has the potential of being an error (e.g. a mock +function with no expectation is called, a.k.a. an uninteresting call, which is +allowed but perhaps you forgot to explicitly ban the call), it prints some +warning messages, including the arguments of the function, the return value, and +the stack trace. Hopefully this will remind you to take a look and see if there +is indeed a problem. + +Sometimes you are confident that your tests are correct and may not appreciate +such friendly messages. Some other times, you are debugging your tests or +learning about the behavior of the code you are testing, and wish you could +observe every mock call that happens (including argument values, the return +value, and the stack trace). Clearly, one size doesn't fit all. + +You can control how much gMock tells you using the `--gmock_verbose=LEVEL` +command-line flag, where `LEVEL` is a string with three possible values: + +* `info`: gMock will print all informational messages, warnings, and errors + (most verbose). At this setting, gMock will also log any calls to the + `ON_CALL/EXPECT_CALL` macros. It will include a stack trace in + "uninteresting call" warnings. +* `warning`: gMock will print both warnings and errors (less verbose); it will + omit the stack traces in "uninteresting call" warnings. This is the default. +* `error`: gMock will print errors only (least verbose). + +Alternatively, you can adjust the value of that flag from within your tests like +so: + +```cpp + ::testing::FLAGS_gmock_verbose = "error"; +``` + +If you find gMock printing too many stack frames with its informational or +warning messages, remember that you can control their amount with the +`--gtest_stack_trace_depth=max_depth` flag. + +Now, judiciously use the right flag to enable gMock serve you better! + +### Gaining Super Vision into Mock Calls + +You have a test using gMock. It fails: gMock tells you some expectations aren't +satisfied. However, you aren't sure why: Is there a typo somewhere in the +matchers? Did you mess up the order of the `EXPECT_CALL`s? Or is the code under +test doing something wrong? How can you find out the cause? + +Won't it be nice if you have X-ray vision and can actually see the trace of all +`EXPECT_CALL`s and mock method calls as they are made? For each call, would you +like to see its actual argument values and which `EXPECT_CALL` gMock thinks it +matches? If you still need some help to figure out who made these calls, how +about being able to see the complete stack trace at each mock call? + +You can unlock this power by running your test with the `--gmock_verbose=info` +flag. For example, given the test program: + +```cpp +#include "gmock/gmock.h" + +using testing::_; +using testing::HasSubstr; +using testing::Return; + +class MockFoo { + public: + MOCK_METHOD(void, F, (const string& x, const string& y)); +}; + +TEST(Foo, Bar) { + MockFoo mock; + EXPECT_CALL(mock, F(_, _)).WillRepeatedly(Return()); + EXPECT_CALL(mock, F("a", "b")); + EXPECT_CALL(mock, F("c", HasSubstr("d"))); + + mock.F("a", "good"); + mock.F("a", "b"); +} +``` + +if you run it with `--gmock_verbose=info`, you will see this output: + +```shell +[ RUN ] Foo.Bar + +foo_test.cc:14: EXPECT_CALL(mock, F(_, _)) invoked +Stack trace: ... + +foo_test.cc:15: EXPECT_CALL(mock, F("a", "b")) invoked +Stack trace: ... + +foo_test.cc:16: EXPECT_CALL(mock, F("c", HasSubstr("d"))) invoked +Stack trace: ... + +foo_test.cc:14: Mock function call matches EXPECT_CALL(mock, F(_, _))... + Function call: F(@0x7fff7c8dad40"a",@0x7fff7c8dad10"good") +Stack trace: ... + +foo_test.cc:15: Mock function call matches EXPECT_CALL(mock, F("a", "b"))... + Function call: F(@0x7fff7c8dada0"a",@0x7fff7c8dad70"b") +Stack trace: ... + +foo_test.cc:16: Failure +Actual function call count doesn't match EXPECT_CALL(mock, F("c", HasSubstr("d")))... + Expected: to be called once + Actual: never called - unsatisfied and active +[ FAILED ] Foo.Bar +``` + +Suppose the bug is that the `"c"` in the third `EXPECT_CALL` is a typo and +should actually be `"a"`. With the above message, you should see that the actual +`F("a", "good")` call is matched by the first `EXPECT_CALL`, not the third as +you thought. From that it should be obvious that the third `EXPECT_CALL` is +written wrong. Case solved. + +If you are interested in the mock call trace but not the stack traces, you can +combine `--gmock_verbose=info` with `--gtest_stack_trace_depth=0` on the test +command line. + +<!-- GOOGLETEST_CM0025 DO NOT DELETE --> + +### Running Tests in Emacs + +If you build and run your tests in Emacs using the `M-x google-compile` command +(as many googletest users do), the source file locations of gMock and googletest +errors will be highlighted. Just press `<Enter>` on one of them and you'll be +taken to the offending line. Or, you can just type `C-x`` to jump to the next +error. + +To make it even easier, you can add the following lines to your `~/.emacs` file: + +```text +(global-set-key "\M-m" 'google-compile) ; m is for make +(global-set-key [M-down] 'next-error) +(global-set-key [M-up] '(lambda () (interactive) (next-error -1))) +``` + +Then you can type `M-m` to start a build (if you want to run the test as well, +just make sure `foo_test.run` or `runtests` is in the build command you supply +after typing `M-m`), or `M-up`/`M-down` to move back and forth between errors. + +## Extending gMock + +### Writing New Matchers Quickly {#NewMatchers} + +WARNING: gMock does not guarantee when or how many times a matcher will be +invoked. Therefore, all matchers must be functionally pure. See +[this section](#PureMatchers) for more details. + +The `MATCHER*` family of macros can be used to define custom matchers easily. +The syntax: + +```cpp +MATCHER(name, description_string_expression) { statements; } +``` + +will define a matcher with the given name that executes the statements, which +must return a `bool` to indicate if the match succeeds. Inside the statements, +you can refer to the value being matched by `arg`, and refer to its type by +`arg_type`. + +The *description string* is a `string`-typed expression that documents what the +matcher does, and is used to generate the failure message when the match fails. +It can (and should) reference the special `bool` variable `negation`, and should +evaluate to the description of the matcher when `negation` is `false`, or that +of the matcher's negation when `negation` is `true`. + +For convenience, we allow the description string to be empty (`""`), in which +case gMock will use the sequence of words in the matcher name as the +description. + +For example: + +```cpp +MATCHER(IsDivisibleBy7, "") { return (arg % 7) == 0; } +``` + +allows you to write + +```cpp + // Expects mock_foo.Bar(n) to be called where n is divisible by 7. + EXPECT_CALL(mock_foo, Bar(IsDivisibleBy7())); +``` + +or, + +```cpp + using ::testing::Not; + ... + // Verifies that two values are divisible by 7. + EXPECT_THAT(some_expression, IsDivisibleBy7()); + EXPECT_THAT(some_other_expression, Not(IsDivisibleBy7())); +``` + +If the above assertions fail, they will print something like: + +```shell + Value of: some_expression + Expected: is divisible by 7 + Actual: 27 + ... + Value of: some_other_expression + Expected: not (is divisible by 7) + Actual: 21 +``` + +where the descriptions `"is divisible by 7"` and `"not (is divisible by 7)"` are +automatically calculated from the matcher name `IsDivisibleBy7`. + +As you may have noticed, the auto-generated descriptions (especially those for +the negation) may not be so great. You can always override them with a `string` +expression of your own: + +```cpp +MATCHER(IsDivisibleBy7, + absl::StrCat(negation ? "isn't" : "is", " divisible by 7")) { + return (arg % 7) == 0; +} +``` + +Optionally, you can stream additional information to a hidden argument named +`result_listener` to explain the match result. For example, a better definition +of `IsDivisibleBy7` is: + +```cpp +MATCHER(IsDivisibleBy7, "") { + if ((arg % 7) == 0) + return true; + + *result_listener << "the remainder is " << (arg % 7); + return false; +} +``` + +With this definition, the above assertion will give a better message: + +```shell + Value of: some_expression + Expected: is divisible by 7 + Actual: 27 (the remainder is 6) +``` + +You should let `MatchAndExplain()` print *any additional information* that can +help a user understand the match result. Note that it should explain why the +match succeeds in case of a success (unless it's obvious) - this is useful when +the matcher is used inside `Not()`. There is no need to print the argument value +itself, as gMock already prints it for you. + +NOTE: The type of the value being matched (`arg_type`) is determined by the +context in which you use the matcher and is supplied to you by the compiler, so +you don't need to worry about declaring it (nor can you). This allows the +matcher to be polymorphic. For example, `IsDivisibleBy7()` can be used to match +any type where the value of `(arg % 7) == 0` can be implicitly converted to a +`bool`. In the `Bar(IsDivisibleBy7())` example above, if method `Bar()` takes an +`int`, `arg_type` will be `int`; if it takes an `unsigned long`, `arg_type` will +be `unsigned long`; and so on. + +### Writing New Parameterized Matchers Quickly + +Sometimes you'll want to define a matcher that has parameters. For that you can +use the macro: + +```cpp +MATCHER_P(name, param_name, description_string) { statements; } +``` + +where the description string can be either `""` or a `string` expression that +references `negation` and `param_name`. + +For example: + +```cpp +MATCHER_P(HasAbsoluteValue, value, "") { return abs(arg) == value; } +``` + +will allow you to write: + +```cpp + EXPECT_THAT(Blah("a"), HasAbsoluteValue(n)); +``` + +which may lead to this message (assuming `n` is 10): + +```shell + Value of: Blah("a") + Expected: has absolute value 10 + Actual: -9 +``` + +Note that both the matcher description and its parameter are printed, making the +message human-friendly. + +In the matcher definition body, you can write `foo_type` to reference the type +of a parameter named `foo`. For example, in the body of +`MATCHER_P(HasAbsoluteValue, value)` above, you can write `value_type` to refer +to the type of `value`. + +gMock also provides `MATCHER_P2`, `MATCHER_P3`, ..., up to `MATCHER_P10` to +support multi-parameter matchers: + +```cpp +MATCHER_Pk(name, param_1, ..., param_k, description_string) { statements; } +``` + +Please note that the custom description string is for a particular *instance* of +the matcher, where the parameters have been bound to actual values. Therefore +usually you'll want the parameter values to be part of the description. gMock +lets you do that by referencing the matcher parameters in the description string +expression. + +For example, + +```cpp +using ::testing::PrintToString; +MATCHER_P2(InClosedRange, low, hi, + absl::StrFormat("%s in range [%s, %s]", negation ? "isn't" : "is", + PrintToString(low), PrintToString(hi))) { + return low <= arg && arg <= hi; +} +... +EXPECT_THAT(3, InClosedRange(4, 6)); +``` + +would generate a failure that contains the message: + +```shell + Expected: is in range [4, 6] +``` + +If you specify `""` as the description, the failure message will contain the +sequence of words in the matcher name followed by the parameter values printed +as a tuple. For example, + +```cpp + MATCHER_P2(InClosedRange, low, hi, "") { ... } + ... + EXPECT_THAT(3, InClosedRange(4, 6)); +``` + +would generate a failure that contains the text: + +```shell + Expected: in closed range (4, 6) +``` + +For the purpose of typing, you can view + +```cpp +MATCHER_Pk(Foo, p1, ..., pk, description_string) { ... } +``` + +as shorthand for + +```cpp +template <typename p1_type, ..., typename pk_type> +FooMatcherPk<p1_type, ..., pk_type> +Foo(p1_type p1, ..., pk_type pk) { ... } +``` + +When you write `Foo(v1, ..., vk)`, the compiler infers the types of the +parameters `v1`, ..., and `vk` for you. If you are not happy with the result of +the type inference, you can specify the types by explicitly instantiating the +template, as in `Foo<long, bool>(5, false)`. As said earlier, you don't get to +(or need to) specify `arg_type` as that's determined by the context in which the +matcher is used. + +You can assign the result of expression `Foo(p1, ..., pk)` to a variable of type +`FooMatcherPk<p1_type, ..., pk_type>`. This can be useful when composing +matchers. Matchers that don't have a parameter or have only one parameter have +special types: you can assign `Foo()` to a `FooMatcher`-typed variable, and +assign `Foo(p)` to a `FooMatcherP<p_type>`-typed variable. + +While you can instantiate a matcher template with reference types, passing the +parameters by pointer usually makes your code more readable. If, however, you +still want to pass a parameter by reference, be aware that in the failure +message generated by the matcher you will see the value of the referenced object +but not its address. + +You can overload matchers with different numbers of parameters: + +```cpp +MATCHER_P(Blah, a, description_string_1) { ... } +MATCHER_P2(Blah, a, b, description_string_2) { ... } +``` + +While it's tempting to always use the `MATCHER*` macros when defining a new +matcher, you should also consider implementing `MatcherInterface` or using +`MakePolymorphicMatcher()` instead (see the recipes that follow), especially if +you need to use the matcher a lot. While these approaches require more work, +they give you more control on the types of the value being matched and the +matcher parameters, which in general leads to better compiler error messages +that pay off in the long run. They also allow overloading matchers based on +parameter types (as opposed to just based on the number of parameters). + +### Writing New Monomorphic Matchers + +A matcher of argument type `T` implements `::testing::MatcherInterface<T>` and +does two things: it tests whether a value of type `T` matches the matcher, and +can describe what kind of values it matches. The latter ability is used for +generating readable error messages when expectations are violated. + +The interface looks like this: + +```cpp +class MatchResultListener { + public: + ... + // Streams x to the underlying ostream; does nothing if the ostream + // is NULL. + template <typename T> + MatchResultListener& operator<<(const T& x); + + // Returns the underlying ostream. + std::ostream* stream(); +}; + +template <typename T> +class MatcherInterface { + public: + virtual ~MatcherInterface(); + + // Returns true if and only if the matcher matches x; also explains the match + // result to 'listener'. + virtual bool MatchAndExplain(T x, MatchResultListener* listener) const = 0; + + // Describes this matcher to an ostream. + virtual void DescribeTo(std::ostream* os) const = 0; + + // Describes the negation of this matcher to an ostream. + virtual void DescribeNegationTo(std::ostream* os) const; +}; +``` + +If you need a custom matcher but `Truly()` is not a good option (for example, +you may not be happy with the way `Truly(predicate)` describes itself, or you +may want your matcher to be polymorphic as `Eq(value)` is), you can define a +matcher to do whatever you want in two steps: first implement the matcher +interface, and then define a factory function to create a matcher instance. The +second step is not strictly needed but it makes the syntax of using the matcher +nicer. + +For example, you can define a matcher to test whether an `int` is divisible by 7 +and then use it like this: + +```cpp +using ::testing::MakeMatcher; +using ::testing::Matcher; +using ::testing::MatcherInterface; +using ::testing::MatchResultListener; + +class DivisibleBy7Matcher : public MatcherInterface<int> { + public: + bool MatchAndExplain(int n, + MatchResultListener* /* listener */) const override { + return (n % 7) == 0; + } + + void DescribeTo(std::ostream* os) const override { + *os << "is divisible by 7"; + } + + void DescribeNegationTo(std::ostream* os) const override { + *os << "is not divisible by 7"; + } +}; + +Matcher<int> DivisibleBy7() { + return MakeMatcher(new DivisibleBy7Matcher); +} + +... + EXPECT_CALL(foo, Bar(DivisibleBy7())); +``` + +You may improve the matcher message by streaming additional information to the +`listener` argument in `MatchAndExplain()`: + +```cpp +class DivisibleBy7Matcher : public MatcherInterface<int> { + public: + bool MatchAndExplain(int n, + MatchResultListener* listener) const override { + const int remainder = n % 7; + if (remainder != 0) { + *listener << "the remainder is " << remainder; + } + return remainder == 0; + } + ... +}; +``` + +Then, `EXPECT_THAT(x, DivisibleBy7());` may generate a message like this: + +```shell +Value of: x +Expected: is divisible by 7 + Actual: 23 (the remainder is 2) +``` + +### Writing New Polymorphic Matchers + +You've learned how to write your own matchers in the previous recipe. Just one +problem: a matcher created using `MakeMatcher()` only works for one particular +type of arguments. If you want a *polymorphic* matcher that works with arguments +of several types (for instance, `Eq(x)` can be used to match a *`value`* as long +as `value == x` compiles -- *`value`* and `x` don't have to share the same +type), you can learn the trick from `testing/base/public/gmock-matchers.h` but +it's a bit involved. + +Fortunately, most of the time you can define a polymorphic matcher easily with +the help of `MakePolymorphicMatcher()`. Here's how you can define `NotNull()` as +an example: + +```cpp +using ::testing::MakePolymorphicMatcher; +using ::testing::MatchResultListener; +using ::testing::PolymorphicMatcher; + +class NotNullMatcher { + public: + // To implement a polymorphic matcher, first define a COPYABLE class + // that has three members MatchAndExplain(), DescribeTo(), and + // DescribeNegationTo(), like the following. + + // In this example, we want to use NotNull() with any pointer, so + // MatchAndExplain() accepts a pointer of any type as its first argument. + // In general, you can define MatchAndExplain() as an ordinary method or + // a method template, or even overload it. + template <typename T> + bool MatchAndExplain(T* p, + MatchResultListener* /* listener */) const { + return p != NULL; + } + + // Describes the property of a value matching this matcher. + void DescribeTo(std::ostream* os) const { *os << "is not NULL"; } + + // Describes the property of a value NOT matching this matcher. + void DescribeNegationTo(std::ostream* os) const { *os << "is NULL"; } +}; + +// To construct a polymorphic matcher, pass an instance of the class +// to MakePolymorphicMatcher(). Note the return type. +PolymorphicMatcher<NotNullMatcher> NotNull() { + return MakePolymorphicMatcher(NotNullMatcher()); +} + +... + + EXPECT_CALL(foo, Bar(NotNull())); // The argument must be a non-NULL pointer. +``` + +**Note:** Your polymorphic matcher class does **not** need to inherit from +`MatcherInterface` or any other class, and its methods do **not** need to be +virtual. + +Like in a monomorphic matcher, you may explain the match result by streaming +additional information to the `listener` argument in `MatchAndExplain()`. + +### Writing New Cardinalities + +A cardinality is used in `Times()` to tell gMock how many times you expect a +call to occur. It doesn't have to be exact. For example, you can say +`AtLeast(5)` or `Between(2, 4)`. + +If the [built-in set](cheat_sheet.md#CardinalityList) of cardinalities doesn't +suit you, you are free to define your own by implementing the following +interface (in namespace `testing`): + +```cpp +class CardinalityInterface { + public: + virtual ~CardinalityInterface(); + + // Returns true if and only if call_count calls will satisfy this cardinality. + virtual bool IsSatisfiedByCallCount(int call_count) const = 0; + + // Returns true if and only if call_count calls will saturate this + // cardinality. + virtual bool IsSaturatedByCallCount(int call_count) const = 0; + + // Describes self to an ostream. + virtual void DescribeTo(std::ostream* os) const = 0; +}; +``` + +For example, to specify that a call must occur even number of times, you can +write + +```cpp +using ::testing::Cardinality; +using ::testing::CardinalityInterface; +using ::testing::MakeCardinality; + +class EvenNumberCardinality : public CardinalityInterface { + public: + bool IsSatisfiedByCallCount(int call_count) const override { + return (call_count % 2) == 0; + } + + bool IsSaturatedByCallCount(int call_count) const override { + return false; + } + + void DescribeTo(std::ostream* os) const { + *os << "called even number of times"; + } +}; + +Cardinality EvenNumber() { + return MakeCardinality(new EvenNumberCardinality); +} + +... + EXPECT_CALL(foo, Bar(3)) + .Times(EvenNumber()); +``` + +### Writing New Actions Quickly {#QuickNewActions} + +If the built-in actions don't work for you, you can easily define your own one. +Just define a functor class with a (possibly templated) call operator, matching +the signature of your action. + +```cpp +struct Increment { + template <typename T> + T operator()(T* arg) { + return ++(*arg); + } +} +``` + +The same approach works with stateful functors (or any callable, really): + +``` +struct MultiplyBy { + template <typename T> + T operator()(T arg) { return arg * multiplier; } + + int multiplier; +} + +// Then use: +// EXPECT_CALL(...).WillOnce(MultiplyBy{7}); +``` + +#### Legacy macro-based Actions + +Before C++11, the functor-based actions were not supported; the old way of +writing actions was through a set of `ACTION*` macros. We suggest to avoid them +in new code; they hide a lot of logic behind the macro, potentially leading to +harder-to-understand compiler errors. Nevertheless, we cover them here for +completeness. + +By writing + +```cpp +ACTION(name) { statements; } +``` + +in a namespace scope (i.e. not inside a class or function), you will define an +action with the given name that executes the statements. The value returned by +`statements` will be used as the return value of the action. Inside the +statements, you can refer to the K-th (0-based) argument of the mock function as +`argK`. For example: + +```cpp +ACTION(IncrementArg1) { return ++(*arg1); } +``` + +allows you to write + +```cpp +... WillOnce(IncrementArg1()); +``` + +Note that you don't need to specify the types of the mock function arguments. +Rest assured that your code is type-safe though: you'll get a compiler error if +`*arg1` doesn't support the `++` operator, or if the type of `++(*arg1)` isn't +compatible with the mock function's return type. + +Another example: + +```cpp +ACTION(Foo) { + (*arg2)(5); + Blah(); + *arg1 = 0; + return arg0; +} +``` + +defines an action `Foo()` that invokes argument #2 (a function pointer) with 5, +calls function `Blah()`, sets the value pointed to by argument #1 to 0, and +returns argument #0. + +For more convenience and flexibility, you can also use the following pre-defined +symbols in the body of `ACTION`: + +`argK_type` | The type of the K-th (0-based) argument of the mock function +:-------------- | :----------------------------------------------------------- +`args` | All arguments of the mock function as a tuple +`args_type` | The type of all arguments of the mock function as a tuple +`return_type` | The return type of the mock function +`function_type` | The type of the mock function + +For example, when using an `ACTION` as a stub action for mock function: + +```cpp +int DoSomething(bool flag, int* ptr); +``` + +we have: + +Pre-defined Symbol | Is Bound To +------------------ | --------------------------------- +`arg0` | the value of `flag` +`arg0_type` | the type `bool` +`arg1` | the value of `ptr` +`arg1_type` | the type `int*` +`args` | the tuple `(flag, ptr)` +`args_type` | the type `std::tuple<bool, int*>` +`return_type` | the type `int` +`function_type` | the type `int(bool, int*)` + +#### Legacy macro-based parameterized Actions + +Sometimes you'll want to parameterize an action you define. For that we have +another macro + +```cpp +ACTION_P(name, param) { statements; } +``` + +For example, + +```cpp +ACTION_P(Add, n) { return arg0 + n; } +``` + +will allow you to write + +```cpp +// Returns argument #0 + 5. +... WillOnce(Add(5)); +``` + +For convenience, we use the term *arguments* for the values used to invoke the +mock function, and the term *parameters* for the values used to instantiate an +action. + +Note that you don't need to provide the type of the parameter either. Suppose +the parameter is named `param`, you can also use the gMock-defined symbol +`param_type` to refer to the type of the parameter as inferred by the compiler. +For example, in the body of `ACTION_P(Add, n)` above, you can write `n_type` for +the type of `n`. + +gMock also provides `ACTION_P2`, `ACTION_P3`, and etc to support multi-parameter +actions. For example, + +```cpp +ACTION_P2(ReturnDistanceTo, x, y) { + double dx = arg0 - x; + double dy = arg1 - y; + return sqrt(dx*dx + dy*dy); +} +``` + +lets you write + +```cpp +... WillOnce(ReturnDistanceTo(5.0, 26.5)); +``` + +You can view `ACTION` as a degenerated parameterized action where the number of +parameters is 0. + +You can also easily define actions overloaded on the number of parameters: + +```cpp +ACTION_P(Plus, a) { ... } +ACTION_P2(Plus, a, b) { ... } +``` + +### Restricting the Type of an Argument or Parameter in an ACTION + +For maximum brevity and reusability, the `ACTION*` macros don't ask you to +provide the types of the mock function arguments and the action parameters. +Instead, we let the compiler infer the types for us. + +Sometimes, however, we may want to be more explicit about the types. There are +several tricks to do that. For example: + +```cpp +ACTION(Foo) { + // Makes sure arg0 can be converted to int. + int n = arg0; + ... use n instead of arg0 here ... +} + +ACTION_P(Bar, param) { + // Makes sure the type of arg1 is const char*. + ::testing::StaticAssertTypeEq<const char*, arg1_type>(); + + // Makes sure param can be converted to bool. + bool flag = param; +} +``` + +where `StaticAssertTypeEq` is a compile-time assertion in googletest that +verifies two types are the same. + +### Writing New Action Templates Quickly + +Sometimes you want to give an action explicit template parameters that cannot be +inferred from its value parameters. `ACTION_TEMPLATE()` supports that and can be +viewed as an extension to `ACTION()` and `ACTION_P*()`. + +The syntax: + +```cpp +ACTION_TEMPLATE(ActionName, + HAS_m_TEMPLATE_PARAMS(kind1, name1, ..., kind_m, name_m), + AND_n_VALUE_PARAMS(p1, ..., p_n)) { statements; } +``` + +defines an action template that takes *m* explicit template parameters and *n* +value parameters, where *m* is in [1, 10] and *n* is in [0, 10]. `name_i` is the +name of the *i*-th template parameter, and `kind_i` specifies whether it's a +`typename`, an integral constant, or a template. `p_i` is the name of the *i*-th +value parameter. + +Example: + +```cpp +// DuplicateArg<k, T>(output) converts the k-th argument of the mock +// function to type T and copies it to *output. +ACTION_TEMPLATE(DuplicateArg, + // Note the comma between int and k: + HAS_2_TEMPLATE_PARAMS(int, k, typename, T), + AND_1_VALUE_PARAMS(output)) { + *output = T(std::get<k>(args)); +} +``` + +To create an instance of an action template, write: + +```cpp +ActionName<t1, ..., t_m>(v1, ..., v_n) +``` + +where the `t`s are the template arguments and the `v`s are the value arguments. +The value argument types are inferred by the compiler. For example: + +```cpp +using ::testing::_; +... + int n; + EXPECT_CALL(mock, Foo).WillOnce(DuplicateArg<1, unsigned char>(&n)); +``` + +If you want to explicitly specify the value argument types, you can provide +additional template arguments: + +```cpp +ActionName<t1, ..., t_m, u1, ..., u_k>(v1, ..., v_n) +``` + +where `u_i` is the desired type of `v_i`. + +`ACTION_TEMPLATE` and `ACTION`/`ACTION_P*` can be overloaded on the number of +value parameters, but not on the number of template parameters. Without the +restriction, the meaning of the following is unclear: + +```cpp + OverloadedAction<int, bool>(x); +``` + +Are we using a single-template-parameter action where `bool` refers to the type +of `x`, or a two-template-parameter action where the compiler is asked to infer +the type of `x`? + +### Using the ACTION Object's Type + +If you are writing a function that returns an `ACTION` object, you'll need to +know its type. The type depends on the macro used to define the action and the +parameter types. The rule is relatively simple: + +| Given Definition | Expression | Has Type | +| ----------------------------- | ------------------- | --------------------- | +| `ACTION(Foo)` | `Foo()` | `FooAction` | +| `ACTION_TEMPLATE(Foo,` | `Foo<t1, ..., | `FooAction<t1, ..., | +: `HAS_m_TEMPLATE_PARAMS(...),` : t_m>()` : t_m>` : +: `AND_0_VALUE_PARAMS())` : : : +| `ACTION_P(Bar, param)` | `Bar(int_value)` | `BarActionP<int>` | +| `ACTION_TEMPLATE(Bar,` | `Bar<t1, ..., t_m>` | `FooActionP<t1, ..., | +: `HAS_m_TEMPLATE_PARAMS(...),` : `(int_value)` : t_m, int>` : +: `AND_1_VALUE_PARAMS(p1))` : : : +| `ACTION_P2(Baz, p1, p2)` | `Baz(bool_value,` | `BazActionP2<bool, | +: : `int_value)` : int>` : +| `ACTION_TEMPLATE(Baz,` | `Baz<t1, ..., t_m>` | `FooActionP2<t1, ..., | +: `HAS_m_TEMPLATE_PARAMS(...),` : `(bool_value,` : t_m,` `bool, int>` : +: `AND_2_VALUE_PARAMS(p1, p2))` : `int_value)` : : +| ... | ... | ... | + +Note that we have to pick different suffixes (`Action`, `ActionP`, `ActionP2`, +and etc) for actions with different numbers of value parameters, or the action +definitions cannot be overloaded on the number of them. + +### Writing New Monomorphic Actions {#NewMonoActions} + +While the `ACTION*` macros are very convenient, sometimes they are +inappropriate. For example, despite the tricks shown in the previous recipes, +they don't let you directly specify the types of the mock function arguments and +the action parameters, which in general leads to unoptimized compiler error +messages that can baffle unfamiliar users. They also don't allow overloading +actions based on parameter types without jumping through some hoops. + +An alternative to the `ACTION*` macros is to implement +`::testing::ActionInterface<F>`, where `F` is the type of the mock function in +which the action will be used. For example: + +```cpp +template <typename F> +class ActionInterface { + public: + virtual ~ActionInterface(); + + // Performs the action. Result is the return type of function type + // F, and ArgumentTuple is the tuple of arguments of F. + // + + // For example, if F is int(bool, const string&), then Result would + // be int, and ArgumentTuple would be std::tuple<bool, const string&>. + virtual Result Perform(const ArgumentTuple& args) = 0; +}; +``` + +```cpp +using ::testing::_; +using ::testing::Action; +using ::testing::ActionInterface; +using ::testing::MakeAction; + +typedef int IncrementMethod(int*); + +class IncrementArgumentAction : public ActionInterface<IncrementMethod> { + public: + int Perform(const std::tuple<int*>& args) override { + int* p = std::get<0>(args); // Grabs the first argument. + return *p++; + } +}; + +Action<IncrementMethod> IncrementArgument() { + return MakeAction(new IncrementArgumentAction); +} + +... + EXPECT_CALL(foo, Baz(_)) + .WillOnce(IncrementArgument()); + + int n = 5; + foo.Baz(&n); // Should return 5 and change n to 6. +``` + +### Writing New Polymorphic Actions {#NewPolyActions} + +The previous recipe showed you how to define your own action. This is all good, +except that you need to know the type of the function in which the action will +be used. Sometimes that can be a problem. For example, if you want to use the +action in functions with *different* types (e.g. like `Return()` and +`SetArgPointee()`). + +If an action can be used in several types of mock functions, we say it's +*polymorphic*. The `MakePolymorphicAction()` function template makes it easy to +define such an action: + +```cpp +namespace testing { +template <typename Impl> +PolymorphicAction<Impl> MakePolymorphicAction(const Impl& impl); +} // namespace testing +``` + +As an example, let's define an action that returns the second argument in the +mock function's argument list. The first step is to define an implementation +class: + +```cpp +class ReturnSecondArgumentAction { + public: + template <typename Result, typename ArgumentTuple> + Result Perform(const ArgumentTuple& args) const { + // To get the i-th (0-based) argument, use std::get(args). + return std::get<1>(args); + } +}; +``` + +This implementation class does *not* need to inherit from any particular class. +What matters is that it must have a `Perform()` method template. This method +template takes the mock function's arguments as a tuple in a **single** +argument, and returns the result of the action. It can be either `const` or not, +but must be invokable with exactly one template argument, which is the result +type. In other words, you must be able to call `Perform<R>(args)` where `R` is +the mock function's return type and `args` is its arguments in a tuple. + +Next, we use `MakePolymorphicAction()` to turn an instance of the implementation +class into the polymorphic action we need. It will be convenient to have a +wrapper for this: + +```cpp +using ::testing::MakePolymorphicAction; +using ::testing::PolymorphicAction; + +PolymorphicAction<ReturnSecondArgumentAction> ReturnSecondArgument() { + return MakePolymorphicAction(ReturnSecondArgumentAction()); +} +``` + +Now, you can use this polymorphic action the same way you use the built-in ones: + +```cpp +using ::testing::_; + +class MockFoo : public Foo { + public: + MOCK_METHOD(int, DoThis, (bool flag, int n), (override)); + MOCK_METHOD(string, DoThat, (int x, const char* str1, const char* str2), + (override)); +}; + + ... + MockFoo foo; + EXPECT_CALL(foo, DoThis).WillOnce(ReturnSecondArgument()); + EXPECT_CALL(foo, DoThat).WillOnce(ReturnSecondArgument()); + ... + foo.DoThis(true, 5); // Will return 5. + foo.DoThat(1, "Hi", "Bye"); // Will return "Hi". +``` + +### Teaching gMock How to Print Your Values + +When an uninteresting or unexpected call occurs, gMock prints the argument +values and the stack trace to help you debug. Assertion macros like +`EXPECT_THAT` and `EXPECT_EQ` also print the values in question when the +assertion fails. gMock and googletest do this using googletest's user-extensible +value printer. + +This printer knows how to print built-in C++ types, native arrays, STL +containers, and any type that supports the `<<` operator. For other types, it +prints the raw bytes in the value and hopes that you the user can figure it out. +[googletest's advanced guide](../../googletest/docs/advanced.md#teaching-googletest-how-to-print-your-values) +explains how to extend the printer to do a better job at printing your +particular type than to dump the bytes. + +## Useful Mocks Created Using gMock + +<!--#include file="includes/g3_testing_LOGs.md"--> +<!--#include file="includes/g3_mock_callbacks.md"--> + +### Mock std::function {#MockFunction} + +`std::function` is a general function type introduced in C++11. It is a +preferred way of passing callbacks to new interfaces. Functions are copiable, +and are not usually passed around by pointer, which makes them tricky to mock. +But fear not - `MockFunction` can help you with that. + +`MockFunction<R(T1, ..., Tn)>` has a mock method `Call()` with the signature: + +```cpp + R Call(T1, ..., Tn); +``` + +It also has a `AsStdFunction()` method, which creates a `std::function` proxy +forwarding to Call: + +```cpp + std::function<R(T1, ..., Tn)> AsStdFunction(); +``` + +To use `MockFunction`, first create `MockFunction` object and set up +expectations on its `Call` method. Then pass proxy obtained from +`AsStdFunction()` to the code you are testing. For example: + +```cpp +TEST(FooTest, RunsCallbackWithBarArgument) { + // 1. Create a mock object. + MockFunction<int(string)> mock_function; + + // 2. Set expectations on Call() method. + EXPECT_CALL(mock_function, Call("bar")).WillOnce(Return(1)); + + // 3. Exercise code that uses std::function. + Foo(mock_function.AsStdFunction()); + // Foo's signature can be either of: + // void Foo(const std::function<int(string)>& fun); + // void Foo(std::function<int(string)> fun); + + // 4. All expectations will be verified when mock_function + // goes out of scope and is destroyed. +} +``` + +Remember that function objects created with `AsStdFunction()` are just +forwarders. If you create multiple of them, they will share the same set of +expectations. + +Although `std::function` supports unlimited number of arguments, `MockFunction` +implementation is limited to ten. If you ever hit that limit... well, your +callback has bigger problems than being mockable. :-) + +<!-- GOOGLETEST_CM0034 DO NOT DELETE --> diff --git a/src/googletest/googlemock/docs/for_dummies.md b/src/googletest/googlemock/docs/for_dummies.md new file mode 100644 index 000000000..8ba164f9a --- /dev/null +++ b/src/googletest/googlemock/docs/for_dummies.md @@ -0,0 +1,702 @@ +# gMock for Dummies {#GMockForDummies} + +<!-- GOOGLETEST_CM0013 DO NOT DELETE --> + +<!-- GOOGLETEST_CM0035 DO NOT DELETE --> + +## What Is gMock? + +When you write a prototype or test, often it's not feasible or wise to rely on +real objects entirely. A **mock object** implements the same interface as a real +object (so it can be used as one), but lets you specify at run time how it will +be used and what it should do (which methods will be called? in which order? how +many times? with what arguments? what will they return? etc). + +**Note:** It is easy to confuse the term *fake objects* with mock objects. Fakes +and mocks actually mean very different things in the Test-Driven Development +(TDD) community: + +* **Fake** objects have working implementations, but usually take some + shortcut (perhaps to make the operations less expensive), which makes them + not suitable for production. An in-memory file system would be an example of + a fake. +* **Mocks** are objects pre-programmed with *expectations*, which form a + specification of the calls they are expected to receive. + +If all this seems too abstract for you, don't worry - the most important thing +to remember is that a mock allows you to check the *interaction* between itself +and code that uses it. The difference between fakes and mocks shall become much +clearer once you start to use mocks. + +**gMock** is a library (sometimes we also call it a "framework" to make it sound +cool) for creating mock classes and using them. It does to C++ what +jMock/EasyMock does to Java (well, more or less). + +When using gMock, + +1. first, you use some simple macros to describe the interface you want to + mock, and they will expand to the implementation of your mock class; +2. next, you create some mock objects and specify its expectations and behavior + using an intuitive syntax; +3. then you exercise code that uses the mock objects. gMock will catch any + violation to the expectations as soon as it arises. + +## Why gMock? + +While mock objects help you remove unnecessary dependencies in tests and make +them fast and reliable, using mocks manually in C++ is *hard*: + +* Someone has to implement the mocks. The job is usually tedious and + error-prone. No wonder people go great distance to avoid it. +* The quality of those manually written mocks is a bit, uh, unpredictable. You + may see some really polished ones, but you may also see some that were + hacked up in a hurry and have all sorts of ad hoc restrictions. +* The knowledge you gained from using one mock doesn't transfer to the next + one. + +In contrast, Java and Python programmers have some fine mock frameworks (jMock, +EasyMock, [Mox](http://wtf/mox), etc), which automate the creation of mocks. As +a result, mocking is a proven effective technique and widely adopted practice in +those communities. Having the right tool absolutely makes the difference. + +gMock was built to help C++ programmers. It was inspired by jMock and EasyMock, +but designed with C++'s specifics in mind. It is your friend if any of the +following problems is bothering you: + +* You are stuck with a sub-optimal design and wish you had done more + prototyping before it was too late, but prototyping in C++ is by no means + "rapid". +* Your tests are slow as they depend on too many libraries or use expensive + resources (e.g. a database). +* Your tests are brittle as some resources they use are unreliable (e.g. the + network). +* You want to test how your code handles a failure (e.g. a file checksum + error), but it's not easy to cause one. +* You need to make sure that your module interacts with other modules in the + right way, but it's hard to observe the interaction; therefore you resort to + observing the side effects at the end of the action, but it's awkward at + best. +* You want to "mock out" your dependencies, except that they don't have mock + implementations yet; and, frankly, you aren't thrilled by some of those + hand-written mocks. + +We encourage you to use gMock as + +* a *design* tool, for it lets you experiment with your interface design early + and often. More iterations lead to better designs! +* a *testing* tool to cut your tests' outbound dependencies and probe the + interaction between your module and its collaborators. + +## Getting Started + +gMock is bundled with googletest. + +## A Case for Mock Turtles + +Let's look at an example. Suppose you are developing a graphics program that +relies on a [LOGO](http://en.wikipedia.org/wiki/Logo_programming_language)-like +API for drawing. How would you test that it does the right thing? Well, you can +run it and compare the screen with a golden screen snapshot, but let's admit it: +tests like this are expensive to run and fragile (What if you just upgraded to a +shiny new graphics card that has better anti-aliasing? Suddenly you have to +update all your golden images.). It would be too painful if all your tests are +like this. Fortunately, you learned about +[Dependency Injection](http://en.wikipedia.org/wiki/Dependency_injection) and know the right thing +to do: instead of having your application talk to the system API directly, wrap +the API in an interface (say, `Turtle`) and code to that interface: + +```cpp +class Turtle { + ... + virtual ~Turtle() {} + virtual void PenUp() = 0; + virtual void PenDown() = 0; + virtual void Forward(int distance) = 0; + virtual void Turn(int degrees) = 0; + virtual void GoTo(int x, int y) = 0; + virtual int GetX() const = 0; + virtual int GetY() const = 0; +}; +``` + +(Note that the destructor of `Turtle` **must** be virtual, as is the case for +**all** classes you intend to inherit from - otherwise the destructor of the +derived class will not be called when you delete an object through a base +pointer, and you'll get corrupted program states like memory leaks.) + +You can control whether the turtle's movement will leave a trace using `PenUp()` +and `PenDown()`, and control its movement using `Forward()`, `Turn()`, and +`GoTo()`. Finally, `GetX()` and `GetY()` tell you the current position of the +turtle. + +Your program will normally use a real implementation of this interface. In +tests, you can use a mock implementation instead. This allows you to easily +check what drawing primitives your program is calling, with what arguments, and +in which order. Tests written this way are much more robust (they won't break +because your new machine does anti-aliasing differently), easier to read and +maintain (the intent of a test is expressed in the code, not in some binary +images), and run *much, much faster*. + +## Writing the Mock Class + +If you are lucky, the mocks you need to use have already been implemented by +some nice people. If, however, you find yourself in the position to write a mock +class, relax - gMock turns this task into a fun game! (Well, almost.) + +### How to Define It + +Using the `Turtle` interface as example, here are the simple steps you need to +follow: + +* Derive a class `MockTurtle` from `Turtle`. +* Take a *virtual* function of `Turtle` (while it's possible to + [mock non-virtual methods using templates](cook_book.md#MockingNonVirtualMethods), + it's much more involved). +* In the `public:` section of the child class, write `MOCK_METHOD();` +* Now comes the fun part: you take the function signature, cut-and-paste it + into the macro, and add two commas - one between the return type and the + name, another between the name and the argument list. +* If you're mocking a const method, add a 4th parameter containing `(const)` + (the parentheses are required). +* Since you're overriding a virtual method, we suggest adding the `override` + keyword. For const methods the 4th parameter becomes `(const, override)`, + for non-const methods just `(override)`. This isn't mandatory. +* Repeat until all virtual functions you want to mock are done. (It goes + without saying that *all* pure virtual methods in your abstract class must + be either mocked or overridden.) + +After the process, you should have something like: + +```cpp +#include "gmock/gmock.h" // Brings in gMock. + +class MockTurtle : public Turtle { + public: + ... + MOCK_METHOD(void, PenUp, (), (override)); + MOCK_METHOD(void, PenDown, (), (override)); + MOCK_METHOD(void, Forward, (int distance), (override)); + MOCK_METHOD(void, Turn, (int degrees), (override)); + MOCK_METHOD(void, GoTo, (int x, int y), (override)); + MOCK_METHOD(int, GetX, (), (const, override)); + MOCK_METHOD(int, GetY, (), (const, override)); +}; +``` + +You don't need to define these mock methods somewhere else - the `MOCK_METHOD` +macro will generate the definitions for you. It's that simple! + +### Where to Put It + +When you define a mock class, you need to decide where to put its definition. +Some people put it in a `_test.cc`. This is fine when the interface being mocked +(say, `Foo`) is owned by the same person or team. Otherwise, when the owner of +`Foo` changes it, your test could break. (You can't really expect `Foo`'s +maintainer to fix every test that uses `Foo`, can you?) + +So, the rule of thumb is: if you need to mock `Foo` and it's owned by others, +define the mock class in `Foo`'s package (better, in a `testing` sub-package +such that you can clearly separate production code and testing utilities), put +it in a `.h` and a `cc_library`. Then everyone can reference them from their +tests. If `Foo` ever changes, there is only one copy of `MockFoo` to change, and +only tests that depend on the changed methods need to be fixed. + +Another way to do it: you can introduce a thin layer `FooAdaptor` on top of +`Foo` and code to this new interface. Since you own `FooAdaptor`, you can absorb +changes in `Foo` much more easily. While this is more work initially, carefully +choosing the adaptor interface can make your code easier to write and more +readable (a net win in the long run), as you can choose `FooAdaptor` to fit your +specific domain much better than `Foo` does. + +<!-- GOOGLETEST_CM0029 DO NOT DELETE --> + +## Using Mocks in Tests + +Once you have a mock class, using it is easy. The typical work flow is: + +1. Import the gMock names from the `testing` namespace such that you can use + them unqualified (You only have to do it once per file). Remember that + namespaces are a good idea. +2. Create some mock objects. +3. Specify your expectations on them (How many times will a method be called? + With what arguments? What should it do? etc.). +4. Exercise some code that uses the mocks; optionally, check the result using + googletest assertions. If a mock method is called more than expected or with + wrong arguments, you'll get an error immediately. +5. When a mock is destructed, gMock will automatically check whether all + expectations on it have been satisfied. + +Here's an example: + +```cpp +#include "path/to/mock-turtle.h" +#include "gmock/gmock.h" +#include "gtest/gtest.h" + +using ::testing::AtLeast; // #1 + +TEST(PainterTest, CanDrawSomething) { + MockTurtle turtle; // #2 + EXPECT_CALL(turtle, PenDown()) // #3 + .Times(AtLeast(1)); + + Painter painter(&turtle); // #4 + + EXPECT_TRUE(painter.DrawCircle(0, 0, 10)); // #5 +} +``` + +As you might have guessed, this test checks that `PenDown()` is called at least +once. If the `painter` object didn't call this method, your test will fail with +a message like this: + +```text +path/to/my_test.cc:119: Failure +Actual function call count doesn't match this expectation: +Actually: never called; +Expected: called at least once. +Stack trace: +... +``` + +**Tip 1:** If you run the test from an Emacs buffer, you can hit `<Enter>` on +the line number to jump right to the failed expectation. + +**Tip 2:** If your mock objects are never deleted, the final verification won't +happen. Therefore it's a good idea to turn on the heap checker in your tests +when you allocate mocks on the heap. You get that automatically if you use the +`gtest_main` library already. + +**Important note:** gMock requires expectations to be set **before** the mock +functions are called, otherwise the behavior is **undefined**. In particular, +you mustn't interleave `EXPECT_CALL()s` and calls to the mock functions. + +This means `EXPECT_CALL()` should be read as expecting that a call will occur +*in the future*, not that a call has occurred. Why does gMock work like that? +Well, specifying the expectation beforehand allows gMock to report a violation +as soon as it rises, when the context (stack trace, etc) is still available. +This makes debugging much easier. + +Admittedly, this test is contrived and doesn't do much. You can easily achieve +the same effect without using gMock. However, as we shall reveal soon, gMock +allows you to do *so much more* with the mocks. + +## Setting Expectations + +The key to using a mock object successfully is to set the *right expectations* +on it. If you set the expectations too strict, your test will fail as the result +of unrelated changes. If you set them too loose, bugs can slip through. You want +to do it just right such that your test can catch exactly the kind of bugs you +intend it to catch. gMock provides the necessary means for you to do it "just +right." + +### General Syntax + +In gMock we use the `EXPECT_CALL()` macro to set an expectation on a mock +method. The general syntax is: + +```cpp +EXPECT_CALL(mock_object, method(matchers)) + .Times(cardinality) + .WillOnce(action) + .WillRepeatedly(action); +``` + +The macro has two arguments: first the mock object, and then the method and its +arguments. Note that the two are separated by a comma (`,`), not a period (`.`). +(Why using a comma? The answer is that it was necessary for technical reasons.) +If the method is not overloaded, the macro can also be called without matchers: + +```cpp +EXPECT_CALL(mock_object, non-overloaded-method) + .Times(cardinality) + .WillOnce(action) + .WillRepeatedly(action); +``` + +This syntax allows the test writer to specify "called with any arguments" +without explicitly specifying the number or types of arguments. To avoid +unintended ambiguity, this syntax may only be used for methods which are not +overloaded + +Either form of the macro can be followed by some optional *clauses* that provide +more information about the expectation. We'll discuss how each clause works in +the coming sections. + +This syntax is designed to make an expectation read like English. For example, +you can probably guess that + +```cpp +using ::testing::Return; +... +EXPECT_CALL(turtle, GetX()) + .Times(5) + .WillOnce(Return(100)) + .WillOnce(Return(150)) + .WillRepeatedly(Return(200)); +``` + +says that the `turtle` object's `GetX()` method will be called five times, it +will return 100 the first time, 150 the second time, and then 200 every time. +Some people like to call this style of syntax a Domain-Specific Language (DSL). + +**Note:** Why do we use a macro to do this? Well it serves two purposes: first +it makes expectations easily identifiable (either by `gsearch` or by a human +reader), and second it allows gMock to include the source file location of a +failed expectation in messages, making debugging easier. + +### Matchers: What Arguments Do We Expect? + +When a mock function takes arguments, we may specify what arguments we are +expecting, for example: + +```cpp +// Expects the turtle to move forward by 100 units. +EXPECT_CALL(turtle, Forward(100)); +``` + +Oftentimes you do not want to be too specific. Remember that talk about tests +being too rigid? Over specification leads to brittle tests and obscures the +intent of tests. Therefore we encourage you to specify only what's necessary—no +more, no less. If you aren't interested in the value of an argument, write `_` +as the argument, which means "anything goes": + +```cpp +using ::testing::_; +... +// Expects that the turtle jumps to somewhere on the x=50 line. +EXPECT_CALL(turtle, GoTo(50, _)); +``` + +`_` is an instance of what we call **matchers**. A matcher is like a predicate +and can test whether an argument is what we'd expect. You can use a matcher +inside `EXPECT_CALL()` wherever a function argument is expected. `_` is a +convenient way of saying "any value". + +In the above examples, `100` and `50` are also matchers; implicitly, they are +the same as `Eq(100)` and `Eq(50)`, which specify that the argument must be +equal (using `operator==`) to the matcher argument. There are many +[built-in matchers](cheat_sheet.md#MatcherList) for common types (as well as +[custom matchers](cook_book.md#NewMatchers)); for example: + +```cpp +using ::testing::Ge; +... +// Expects the turtle moves forward by at least 100. +EXPECT_CALL(turtle, Forward(Ge(100))); +``` + +If you don't care about *any* arguments, rather than specify `_` for each of +them you may instead omit the parameter list: + +```cpp +// Expects the turtle to move forward. +EXPECT_CALL(turtle, Forward); +// Expects the turtle to jump somewhere. +EXPECT_CALL(turtle, GoTo); +``` + +This works for all non-overloaded methods; if a method is overloaded, you need +to help gMock resolve which overload is expected by specifying the number of +arguments and possibly also the +[types of the arguments](cook_book.md#SelectOverload). + +### Cardinalities: How Many Times Will It Be Called? + +The first clause we can specify following an `EXPECT_CALL()` is `Times()`. We +call its argument a **cardinality** as it tells *how many times* the call should +occur. It allows us to repeat an expectation many times without actually writing +it as many times. More importantly, a cardinality can be "fuzzy", just like a +matcher can be. This allows a user to express the intent of a test exactly. + +An interesting special case is when we say `Times(0)`. You may have guessed - it +means that the function shouldn't be called with the given arguments at all, and +gMock will report a googletest failure whenever the function is (wrongfully) +called. + +We've seen `AtLeast(n)` as an example of fuzzy cardinalities earlier. For the +list of built-in cardinalities you can use, see +[here](cheat_sheet.md#CardinalityList). + +The `Times()` clause can be omitted. **If you omit `Times()`, gMock will infer +the cardinality for you.** The rules are easy to remember: + +* If **neither** `WillOnce()` **nor** `WillRepeatedly()` is in the + `EXPECT_CALL()`, the inferred cardinality is `Times(1)`. +* If there are *n* `WillOnce()`'s but **no** `WillRepeatedly()`, where *n* >= + 1, the cardinality is `Times(n)`. +* If there are *n* `WillOnce()`'s and **one** `WillRepeatedly()`, where *n* >= + 0, the cardinality is `Times(AtLeast(n))`. + +**Quick quiz:** what do you think will happen if a function is expected to be +called twice but actually called four times? + +### Actions: What Should It Do? + +Remember that a mock object doesn't really have a working implementation? We as +users have to tell it what to do when a method is invoked. This is easy in +gMock. + +First, if the return type of a mock function is a built-in type or a pointer, +the function has a **default action** (a `void` function will just return, a +`bool` function will return `false`, and other functions will return 0). In +addition, in C++ 11 and above, a mock function whose return type is +default-constructible (i.e. has a default constructor) has a default action of +returning a default-constructed value. If you don't say anything, this behavior +will be used. + +Second, if a mock function doesn't have a default action, or the default action +doesn't suit you, you can specify the action to be taken each time the +expectation matches using a series of `WillOnce()` clauses followed by an +optional `WillRepeatedly()`. For example, + +```cpp +using ::testing::Return; +... +EXPECT_CALL(turtle, GetX()) + .WillOnce(Return(100)) + .WillOnce(Return(200)) + .WillOnce(Return(300)); +``` + +says that `turtle.GetX()` will be called *exactly three times* (gMock inferred +this from how many `WillOnce()` clauses we've written, since we didn't +explicitly write `Times()`), and will return 100, 200, and 300 respectively. + +```cpp +using ::testing::Return; +... +EXPECT_CALL(turtle, GetY()) + .WillOnce(Return(100)) + .WillOnce(Return(200)) + .WillRepeatedly(Return(300)); +``` + +says that `turtle.GetY()` will be called *at least twice* (gMock knows this as +we've written two `WillOnce()` clauses and a `WillRepeatedly()` while having no +explicit `Times()`), will return 100 and 200 respectively the first two times, +and 300 from the third time on. + +Of course, if you explicitly write a `Times()`, gMock will not try to infer the +cardinality itself. What if the number you specified is larger than there are +`WillOnce()` clauses? Well, after all `WillOnce()`s are used up, gMock will do +the *default* action for the function every time (unless, of course, you have a +`WillRepeatedly()`.). + +What can we do inside `WillOnce()` besides `Return()`? You can return a +reference using `ReturnRef(*variable*)`, or invoke a pre-defined function, among +[others](cook_book.md#using-actions). + +**Important note:** The `EXPECT_CALL()` statement evaluates the action clause +only once, even though the action may be performed many times. Therefore you +must be careful about side effects. The following may not do what you want: + +```cpp +using ::testing::Return; +... +int n = 100; +EXPECT_CALL(turtle, GetX()) + .Times(4) + .WillRepeatedly(Return(n++)); +``` + +Instead of returning 100, 101, 102, ..., consecutively, this mock function will +always return 100 as `n++` is only evaluated once. Similarly, `Return(new Foo)` +will create a new `Foo` object when the `EXPECT_CALL()` is executed, and will +return the same pointer every time. If you want the side effect to happen every +time, you need to define a custom action, which we'll teach in the +[cook book](http://<!-- GOOGLETEST_CM0012 DO NOT DELETE -->). + +Time for another quiz! What do you think the following means? + +```cpp +using ::testing::Return; +... +EXPECT_CALL(turtle, GetY()) + .Times(4) + .WillOnce(Return(100)); +``` + +Obviously `turtle.GetY()` is expected to be called four times. But if you think +it will return 100 every time, think twice! Remember that one `WillOnce()` +clause will be consumed each time the function is invoked and the default action +will be taken afterwards. So the right answer is that `turtle.GetY()` will +return 100 the first time, but **return 0 from the second time on**, as +returning 0 is the default action for `int` functions. + +### Using Multiple Expectations {#MultiExpectations} + +So far we've only shown examples where you have a single expectation. More +realistically, you'll specify expectations on multiple mock methods which may be +from multiple mock objects. + +By default, when a mock method is invoked, gMock will search the expectations in +the **reverse order** they are defined, and stop when an active expectation that +matches the arguments is found (you can think of it as "newer rules override +older ones."). If the matching expectation cannot take any more calls, you will +get an upper-bound-violated failure. Here's an example: + +```cpp +using ::testing::_; +... +EXPECT_CALL(turtle, Forward(_)); // #1 +EXPECT_CALL(turtle, Forward(10)) // #2 + .Times(2); +``` + +If `Forward(10)` is called three times in a row, the third time it will be an +error, as the last matching expectation (#2) has been saturated. If, however, +the third `Forward(10)` call is replaced by `Forward(20)`, then it would be OK, +as now #1 will be the matching expectation. + +**Note:** Why does gMock search for a match in the *reverse* order of the +expectations? The reason is that this allows a user to set up the default +expectations in a mock object's constructor or the test fixture's set-up phase +and then customize the mock by writing more specific expectations in the test +body. So, if you have two expectations on the same method, you want to put the +one with more specific matchers **after** the other, or the more specific rule +would be shadowed by the more general one that comes after it. + +**Tip:** It is very common to start with a catch-all expectation for a method +and `Times(AnyNumber())` (omitting arguments, or with `_` for all arguments, if +overloaded). This makes any calls to the method expected. This is not necessary +for methods that are not mentioned at all (these are "uninteresting"), but is +useful for methods that have some expectations, but for which other calls are +ok. See +[Understanding Uninteresting vs Unexpected Calls](cook_book.md#uninteresting-vs-unexpected). + +### Ordered vs Unordered Calls {#OrderedCalls} + +By default, an expectation can match a call even though an earlier expectation +hasn't been satisfied. In other words, the calls don't have to occur in the +order the expectations are specified. + +Sometimes, you may want all the expected calls to occur in a strict order. To +say this in gMock is easy: + +```cpp +using ::testing::InSequence; +... +TEST(FooTest, DrawsLineSegment) { + ... + { + InSequence seq; + + EXPECT_CALL(turtle, PenDown()); + EXPECT_CALL(turtle, Forward(100)); + EXPECT_CALL(turtle, PenUp()); + } + Foo(); +} +``` + +By creating an object of type `InSequence`, all expectations in its scope are +put into a *sequence* and have to occur *sequentially*. Since we are just +relying on the constructor and destructor of this object to do the actual work, +its name is really irrelevant. + +In this example, we test that `Foo()` calls the three expected functions in the +order as written. If a call is made out-of-order, it will be an error. + +(What if you care about the relative order of some of the calls, but not all of +them? Can you specify an arbitrary partial order? The answer is ... yes! The +details can be found [here](cook_book.md#OrderedCalls).) + +### All Expectations Are Sticky (Unless Said Otherwise) {#StickyExpectations} + +Now let's do a quick quiz to see how well you can use this mock stuff already. +How would you test that the turtle is asked to go to the origin *exactly twice* +(you want to ignore any other instructions it receives)? + +After you've come up with your answer, take a look at ours and compare notes +(solve it yourself first - don't cheat!): + +```cpp +using ::testing::_; +using ::testing::AnyNumber; +... +EXPECT_CALL(turtle, GoTo(_, _)) // #1 + .Times(AnyNumber()); +EXPECT_CALL(turtle, GoTo(0, 0)) // #2 + .Times(2); +``` + +Suppose `turtle.GoTo(0, 0)` is called three times. In the third time, gMock will +see that the arguments match expectation #2 (remember that we always pick the +last matching expectation). Now, since we said that there should be only two +such calls, gMock will report an error immediately. This is basically what we've +told you in the [Using Multiple Expectations](#MultiExpectations) section above. + +This example shows that **expectations in gMock are "sticky" by default**, in +the sense that they remain active even after we have reached their invocation +upper bounds. This is an important rule to remember, as it affects the meaning +of the spec, and is **different** to how it's done in many other mocking +frameworks (Why'd we do that? Because we think our rule makes the common cases +easier to express and understand.). + +Simple? Let's see if you've really understood it: what does the following code +say? + +```cpp +using ::testing::Return; +... +for (int i = n; i > 0; i--) { + EXPECT_CALL(turtle, GetX()) + .WillOnce(Return(10*i)); +} +``` + +If you think it says that `turtle.GetX()` will be called `n` times and will +return 10, 20, 30, ..., consecutively, think twice! The problem is that, as we +said, expectations are sticky. So, the second time `turtle.GetX()` is called, +the last (latest) `EXPECT_CALL()` statement will match, and will immediately +lead to an "upper bound violated" error - this piece of code is not very useful! + +One correct way of saying that `turtle.GetX()` will return 10, 20, 30, ..., is +to explicitly say that the expectations are *not* sticky. In other words, they +should *retire* as soon as they are saturated: + +```cpp +using ::testing::Return; +... +for (int i = n; i > 0; i--) { + EXPECT_CALL(turtle, GetX()) + .WillOnce(Return(10*i)) + .RetiresOnSaturation(); +} +``` + +And, there's a better way to do it: in this case, we expect the calls to occur +in a specific order, and we line up the actions to match the order. Since the +order is important here, we should make it explicit using a sequence: + +```cpp +using ::testing::InSequence; +using ::testing::Return; +... +{ + InSequence s; + + for (int i = 1; i <= n; i++) { + EXPECT_CALL(turtle, GetX()) + .WillOnce(Return(10*i)) + .RetiresOnSaturation(); + } +} +``` + +By the way, the other situation where an expectation may *not* be sticky is when +it's in a sequence - as soon as another expectation that comes after it in the +sequence has been used, it automatically retires (and will never be used to +match any call). + +### Uninteresting Calls + +A mock object may have many methods, and not all of them are that interesting. +For example, in some tests we may not care about how many times `GetX()` and +`GetY()` get called. + +In gMock, if you are not interested in a method, just don't say anything about +it. If a call to this method occurs, you'll see a warning in the test output, +but it won't be a failure. This is called "naggy" behavior; to change, see +[The Nice, the Strict, and the Naggy](cook_book.md#NiceStrictNaggy). diff --git a/src/googletest/googlemock/docs/gmock_faq.md b/src/googletest/googlemock/docs/gmock_faq.md new file mode 100644 index 000000000..14acae530 --- /dev/null +++ b/src/googletest/googlemock/docs/gmock_faq.md @@ -0,0 +1,398 @@ +## Legacy gMock FAQ {#GMockFaq} + +<!-- GOOGLETEST_CM0021 DO NOT DELETE --> + +<!-- GOOGLETEST_CM0035 DO NOT DELETE --> + +### When I call a method on my mock object, the method for the real object is invoked instead. What's the problem? + +In order for a method to be mocked, it must be *virtual*, unless you use the +[high-perf dependency injection technique](cook_book.md#MockingNonVirtualMethods). + +### Can I mock a variadic function? + +You cannot mock a variadic function (i.e. a function taking ellipsis (`...`) +arguments) directly in gMock. + +The problem is that in general, there is *no way* for a mock object to know how +many arguments are passed to the variadic method, and what the arguments' types +are. Only the *author of the base class* knows the protocol, and we cannot look +into his or her head. + +Therefore, to mock such a function, the *user* must teach the mock object how to +figure out the number of arguments and their types. One way to do it is to +provide overloaded versions of the function. + +Ellipsis arguments are inherited from C and not really a C++ feature. They are +unsafe to use and don't work with arguments that have constructors or +destructors. Therefore we recommend to avoid them in C++ as much as possible. + +### MSVC gives me warning C4301 or C4373 when I define a mock method with a const parameter. Why? + +If you compile this using Microsoft Visual C++ 2005 SP1: + +```cpp +class Foo { + ... + virtual void Bar(const int i) = 0; +}; + +class MockFoo : public Foo { + ... + MOCK_METHOD(void, Bar, (const int i), (override)); +}; +``` + +You may get the following warning: + +```shell +warning C4301: 'MockFoo::Bar': overriding virtual function only differs from 'Foo::Bar' by const/volatile qualifier +``` + +This is a MSVC bug. The same code compiles fine with gcc, for example. If you +use Visual C++ 2008 SP1, you would get the warning: + +```shell +warning C4373: 'MockFoo::Bar': virtual function overrides 'Foo::Bar', previous versions of the compiler did not override when parameters only differed by const/volatile qualifiers +``` + +In C++, if you *declare* a function with a `const` parameter, the `const` +modifier is ignored. Therefore, the `Foo` base class above is equivalent to: + +```cpp +class Foo { + ... + virtual void Bar(int i) = 0; // int or const int? Makes no difference. +}; +``` + +In fact, you can *declare* `Bar()` with an `int` parameter, and define it with a +`const int` parameter. The compiler will still match them up. + +Since making a parameter `const` is meaningless in the method declaration, we +recommend to remove it in both `Foo` and `MockFoo`. That should workaround the +VC bug. + +Note that we are talking about the *top-level* `const` modifier here. If the +function parameter is passed by pointer or reference, declaring the pointee or +referee as `const` is still meaningful. For example, the following two +declarations are *not* equivalent: + +```cpp +void Bar(int* p); // Neither p nor *p is const. +void Bar(const int* p); // p is not const, but *p is. +``` + +<!-- GOOGLETEST_CM0030 DO NOT DELETE --> + +### I can't figure out why gMock thinks my expectations are not satisfied. What should I do? + +You might want to run your test with `--gmock_verbose=info`. This flag lets +gMock print a trace of every mock function call it receives. By studying the +trace, you'll gain insights on why the expectations you set are not met. + +If you see the message "The mock function has no default action set, and its +return type has no default value set.", then try +[adding a default action](for_dummies.md#DefaultValue). Due to a known issue, +unexpected calls on mocks without default actions don't print out a detailed +comparison between the actual arguments and the expected arguments. + +### My program crashed and `ScopedMockLog` spit out tons of messages. Is it a gMock bug? + +gMock and `ScopedMockLog` are likely doing the right thing here. + +When a test crashes, the failure signal handler will try to log a lot of +information (the stack trace, and the address map, for example). The messages +are compounded if you have many threads with depth stacks. When `ScopedMockLog` +intercepts these messages and finds that they don't match any expectations, it +prints an error for each of them. + +You can learn to ignore the errors, or you can rewrite your expectations to make +your test more robust, for example, by adding something like: + +```cpp +using ::testing::AnyNumber; +using ::testing::Not; +... + // Ignores any log not done by us. + EXPECT_CALL(log, Log(_, Not(EndsWith("/my_file.cc")), _)) + .Times(AnyNumber()); +``` + +### How can I assert that a function is NEVER called? + +```cpp +using ::testing::_; +... + EXPECT_CALL(foo, Bar(_)) + .Times(0); +``` + +<!-- GOOGLETEST_CM0031 DO NOT DELETE --> + +### I have a failed test where gMock tells me TWICE that a particular expectation is not satisfied. Isn't this redundant? + +When gMock detects a failure, it prints relevant information (the mock function +arguments, the state of relevant expectations, and etc) to help the user debug. +If another failure is detected, gMock will do the same, including printing the +state of relevant expectations. + +Sometimes an expectation's state didn't change between two failures, and you'll +see the same description of the state twice. They are however *not* redundant, +as they refer to *different points in time*. The fact they are the same *is* +interesting information. + +### I get a heapcheck failure when using a mock object, but using a real object is fine. What can be wrong? + +Does the class (hopefully a pure interface) you are mocking have a virtual +destructor? + +Whenever you derive from a base class, make sure its destructor is virtual. +Otherwise Bad Things will happen. Consider the following code: + +```cpp +class Base { + public: + // Not virtual, but should be. + ~Base() { ... } + ... +}; + +class Derived : public Base { + public: + ... + private: + std::string value_; +}; + +... + Base* p = new Derived; + ... + delete p; // Surprise! ~Base() will be called, but ~Derived() will not + // - value_ is leaked. +``` + +By changing `~Base()` to virtual, `~Derived()` will be correctly called when +`delete p` is executed, and the heap checker will be happy. + +### The "newer expectations override older ones" rule makes writing expectations awkward. Why does gMock do that? + +When people complain about this, often they are referring to code like: + +```cpp +using ::testing::Return; +... + // foo.Bar() should be called twice, return 1 the first time, and return + // 2 the second time. However, I have to write the expectations in the + // reverse order. This sucks big time!!! + EXPECT_CALL(foo, Bar()) + .WillOnce(Return(2)) + .RetiresOnSaturation(); + EXPECT_CALL(foo, Bar()) + .WillOnce(Return(1)) + .RetiresOnSaturation(); +``` + +The problem, is that they didn't pick the **best** way to express the test's +intent. + +By default, expectations don't have to be matched in *any* particular order. If +you want them to match in a certain order, you need to be explicit. This is +gMock's (and jMock's) fundamental philosophy: it's easy to accidentally +over-specify your tests, and we want to make it harder to do so. + +There are two better ways to write the test spec. You could either put the +expectations in sequence: + +```cpp +using ::testing::Return; +... + // foo.Bar() should be called twice, return 1 the first time, and return + // 2 the second time. Using a sequence, we can write the expectations + // in their natural order. + { + InSequence s; + EXPECT_CALL(foo, Bar()) + .WillOnce(Return(1)) + .RetiresOnSaturation(); + EXPECT_CALL(foo, Bar()) + .WillOnce(Return(2)) + .RetiresOnSaturation(); + } +``` + +or you can put the sequence of actions in the same expectation: + +```cpp +using ::testing::Return; +... + // foo.Bar() should be called twice, return 1 the first time, and return + // 2 the second time. + EXPECT_CALL(foo, Bar()) + .WillOnce(Return(1)) + .WillOnce(Return(2)) + .RetiresOnSaturation(); +``` + +Back to the original questions: why does gMock search the expectations (and +`ON_CALL`s) from back to front? Because this allows a user to set up a mock's +behavior for the common case early (e.g. in the mock's constructor or the test +fixture's set-up phase) and customize it with more specific rules later. If +gMock searches from front to back, this very useful pattern won't be possible. + +### gMock prints a warning when a function without EXPECT_CALL is called, even if I have set its behavior using ON_CALL. Would it be reasonable not to show the warning in this case? + +When choosing between being neat and being safe, we lean toward the latter. So +the answer is that we think it's better to show the warning. + +Often people write `ON_CALL`s in the mock object's constructor or `SetUp()`, as +the default behavior rarely changes from test to test. Then in the test body +they set the expectations, which are often different for each test. Having an +`ON_CALL` in the set-up part of a test doesn't mean that the calls are expected. +If there's no `EXPECT_CALL` and the method is called, it's possibly an error. If +we quietly let the call go through without notifying the user, bugs may creep in +unnoticed. + +If, however, you are sure that the calls are OK, you can write + +```cpp +using ::testing::_; +... + EXPECT_CALL(foo, Bar(_)) + .WillRepeatedly(...); +``` + +instead of + +```cpp +using ::testing::_; +... + ON_CALL(foo, Bar(_)) + .WillByDefault(...); +``` + +This tells gMock that you do expect the calls and no warning should be printed. + +Also, you can control the verbosity by specifying `--gmock_verbose=error`. Other +values are `info` and `warning`. If you find the output too noisy when +debugging, just choose a less verbose level. + +### How can I delete the mock function's argument in an action? + +If your mock function takes a pointer argument and you want to delete that +argument, you can use testing::DeleteArg<N>() to delete the N'th (zero-indexed) +argument: + +```cpp +using ::testing::_; + ... + MOCK_METHOD(void, Bar, (X* x, const Y& y)); + ... + EXPECT_CALL(mock_foo_, Bar(_, _)) + .WillOnce(testing::DeleteArg<0>())); +``` + +### How can I perform an arbitrary action on a mock function's argument? + +If you find yourself needing to perform some action that's not supported by +gMock directly, remember that you can define your own actions using +[`MakeAction()`](#NewMonoActions) or +[`MakePolymorphicAction()`](#NewPolyActions), or you can write a stub function +and invoke it using [`Invoke()`](#FunctionsAsActions). + +```cpp +using ::testing::_; +using ::testing::Invoke; + ... + MOCK_METHOD(void, Bar, (X* p)); + ... + EXPECT_CALL(mock_foo_, Bar(_)) + .WillOnce(Invoke(MyAction(...))); +``` + +### My code calls a static/global function. Can I mock it? + +You can, but you need to make some changes. + +In general, if you find yourself needing to mock a static function, it's a sign +that your modules are too tightly coupled (and less flexible, less reusable, +less testable, etc). You are probably better off defining a small interface and +call the function through that interface, which then can be easily mocked. It's +a bit of work initially, but usually pays for itself quickly. + +This Google Testing Blog +[post](https://testing.googleblog.com/2008/06/defeat-static-cling.html) says it +excellently. Check it out. + +### My mock object needs to do complex stuff. It's a lot of pain to specify the actions. gMock sucks! + +I know it's not a question, but you get an answer for free any way. :-) + +With gMock, you can create mocks in C++ easily. And people might be tempted to +use them everywhere. Sometimes they work great, and sometimes you may find them, +well, a pain to use. So, what's wrong in the latter case? + +When you write a test without using mocks, you exercise the code and assert that +it returns the correct value or that the system is in an expected state. This is +sometimes called "state-based testing". + +Mocks are great for what some call "interaction-based" testing: instead of +checking the system state at the very end, mock objects verify that they are +invoked the right way and report an error as soon as it arises, giving you a +handle on the precise context in which the error was triggered. This is often +more effective and economical to do than state-based testing. + +If you are doing state-based testing and using a test double just to simulate +the real object, you are probably better off using a fake. Using a mock in this +case causes pain, as it's not a strong point for mocks to perform complex +actions. If you experience this and think that mocks suck, you are just not +using the right tool for your problem. Or, you might be trying to solve the +wrong problem. :-) + +### I got a warning "Uninteresting function call encountered - default action taken.." Should I panic? + +By all means, NO! It's just an FYI. :-) + +What it means is that you have a mock function, you haven't set any expectations +on it (by gMock's rule this means that you are not interested in calls to this +function and therefore it can be called any number of times), and it is called. +That's OK - you didn't say it's not OK to call the function! + +What if you actually meant to disallow this function to be called, but forgot to +write `EXPECT_CALL(foo, Bar()).Times(0)`? While one can argue that it's the +user's fault, gMock tries to be nice and prints you a note. + +So, when you see the message and believe that there shouldn't be any +uninteresting calls, you should investigate what's going on. To make your life +easier, gMock dumps the stack trace when an uninteresting call is encountered. +From that you can figure out which mock function it is, and how it is called. + +### I want to define a custom action. Should I use Invoke() or implement the ActionInterface interface? + +Either way is fine - you want to choose the one that's more convenient for your +circumstance. + +Usually, if your action is for a particular function type, defining it using +`Invoke()` should be easier; if your action can be used in functions of +different types (e.g. if you are defining `Return(*value*)`), +`MakePolymorphicAction()` is easiest. Sometimes you want precise control on what +types of functions the action can be used in, and implementing `ActionInterface` +is the way to go here. See the implementation of `Return()` in +`testing/base/public/gmock-actions.h` for an example. + +### I use SetArgPointee() in WillOnce(), but gcc complains about "conflicting return type specified". What does it mean? + +You got this error as gMock has no idea what value it should return when the +mock method is called. `SetArgPointee()` says what the side effect is, but +doesn't say what the return value should be. You need `DoAll()` to chain a +`SetArgPointee()` with a `Return()` that provides a value appropriate to the API +being mocked. + +See this [recipe](cook_book.md#mocking-side-effects) for more details and an +example. + +### I have a huge mock class, and Microsoft Visual C++ runs out of memory when compiling it. What can I do? + +We've noticed that when the `/clr` compiler flag is used, Visual C++ uses 5~6 +times as much memory when compiling a mock class. We suggest to avoid `/clr` +when compiling native C++ mocks. diff --git a/src/googletest/googlemock/docs/pump_manual.md b/src/googletest/googlemock/docs/pump_manual.md new file mode 100644 index 000000000..17fb370de --- /dev/null +++ b/src/googletest/googlemock/docs/pump_manual.md @@ -0,0 +1,189 @@ +<b>P</b>ump is <b>U</b>seful for <b>M</b>eta <b>P</b>rogramming. + +<!-- GOOGLETEST_CM0035 DO NOT DELETE --> + +# The Problem + +Template and macro libraries often need to define many classes, functions, or +macros that vary only (or almost only) in the number of arguments they take. +It's a lot of repetitive, mechanical, and error-prone work. + +Our experience is that it's tedious to write custom scripts, which tend to +reflect the structure of the generated code poorly and are often hard to read +and edit. For example, a small change needed in the generated code may require +some non-intuitive, non-trivial changes in the script. This is especially +painful when experimenting with the code. + +This script may be useful for generating meta code, for example a series of +macros of FOO1, FOO2, etc. Nevertheless, please make it your last resort +technique by favouring C++ template metaprogramming or variadic macros. + +# Our Solution + +Pump (for Pump is Useful for Meta Programming, Pretty Useful for Meta +Programming, or Practical Utility for Meta Programming, whichever you prefer) is +a simple meta-programming tool for C++. The idea is that a programmer writes a +`foo.pump` file which contains C++ code plus meta code that manipulates the C++ +code. The meta code can handle iterations over a range, nested iterations, local +meta variable definitions, simple arithmetic, and conditional expressions. You +can view it as a small Domain-Specific Language. The meta language is designed +to be non-intrusive (s.t. it won't confuse Emacs' C++ mode, for example) and +concise, making Pump code intuitive and easy to maintain. + +## Highlights + +* The implementation is in a single Python script and thus ultra portable: no + build or installation is needed and it works cross platforms. +* Pump tries to be smart with respect to + [Google's style guide](https://github.com/google/styleguide): it breaks long + lines (easy to have when they are generated) at acceptable places to fit + within 80 columns and indent the continuation lines correctly. +* The format is human-readable and more concise than XML. +* The format works relatively well with Emacs' C++ mode. + +## Examples + +The following Pump code (where meta keywords start with `$`, `[[` and `]]` are +meta brackets, and `$$` starts a meta comment that ends with the line): + +``` +$var n = 3 $$ Defines a meta variable n. +$range i 0..n $$ Declares the range of meta iterator i (inclusive). +$for i [[ + $$ Meta loop. +// Foo$i does blah for $i-ary predicates. +$range j 1..i +template <size_t N $for j [[, typename A$j]]> +class Foo$i { +$if i == 0 [[ + blah a; +]] $elif i <= 2 [[ + blah b; +]] $else [[ + blah c; +]] +}; + +]] +``` + +will be translated by the Pump compiler to: + +```cpp +// Foo0 does blah for 0-ary predicates. +template <size_t N> +class Foo0 { + blah a; +}; + +// Foo1 does blah for 1-ary predicates. +template <size_t N, typename A1> +class Foo1 { + blah b; +}; + +// Foo2 does blah for 2-ary predicates. +template <size_t N, typename A1, typename A2> +class Foo2 { + blah b; +}; + +// Foo3 does blah for 3-ary predicates. +template <size_t N, typename A1, typename A2, typename A3> +class Foo3 { + blah c; +}; +``` + +In another example, + +``` +$range i 1..n +Func($for i + [[a$i]]); +$$ The text between i and [[ is the separator between iterations. +``` + +will generate one of the following lines (without the comments), depending on +the value of `n`: + +```cpp +Func(); // If n is 0. +Func(a1); // If n is 1. +Func(a1 + a2); // If n is 2. +Func(a1 + a2 + a3); // If n is 3. +// And so on... +``` + +## Constructs + +We support the following meta programming constructs: + +| `$var id = exp` | Defines a named constant value. `$id` is | +: : valid until the end of the current meta : +: : lexical block. : +| :------------------------------- | :--------------------------------------- | +| `$range id exp..exp` | Sets the range of an iteration variable, | +: : which can be reused in multiple loops : +: : later. : +| `$for id sep [[ code ]]` | Iteration. The range of `id` must have | +: : been defined earlier. `$id` is valid in : +: : `code`. : +| `$($)` | Generates a single `$` character. | +| `$id` | Value of the named constant or iteration | +: : variable. : +| `$(exp)` | Value of the expression. | +| `$if exp [[ code ]] else_branch` | Conditional. | +| `[[ code ]]` | Meta lexical block. | +| `cpp_code` | Raw C++ code. | +| `$$ comment` | Meta comment. | + +**Note:** To give the user some freedom in formatting the Pump source code, Pump +ignores a new-line character if it's right after `$for foo` or next to `[[` or +`]]`. Without this rule you'll often be forced to write very long lines to get +the desired output. Therefore sometimes you may need to insert an extra new-line +in such places for a new-line to show up in your output. + +## Grammar + +```ebnf +code ::= atomic_code* +atomic_code ::= $var id = exp + | $var id = [[ code ]] + | $range id exp..exp + | $for id sep [[ code ]] + | $($) + | $id + | $(exp) + | $if exp [[ code ]] else_branch + | [[ code ]] + | cpp_code +sep ::= cpp_code | empty_string +else_branch ::= $else [[ code ]] + | $elif exp [[ code ]] else_branch + | empty_string +exp ::= simple_expression_in_Python_syntax +``` + +## Code + +You can find the source code of Pump in [scripts/pump.py](../scripts/pump.py). +It is still very unpolished and lacks automated tests, although it has been +successfully used many times. If you find a chance to use it in your project, +please let us know what you think! We also welcome help on improving Pump. + +## Real Examples + +You can find real-world applications of Pump in +[Google Test](https://github.com/google/googletest/tree/master/googletest) and +[Google Mock](https://github.com/google/googletest/tree/master/googlemock). The +source file `foo.h.pump` generates `foo.h`. + +## Tips + +* If a meta variable is followed by a letter or digit, you can separate them + using `[[]]`, which inserts an empty string. For example `Foo$j[[]]Helper` + generate `Foo1Helper` when `j` is 1. +* To avoid extra-long Pump source lines, you can break a line anywhere you + want by inserting `[[]]` followed by a new line. Since any new-line + character next to `[[` or `]]` is ignored, the generated code won't contain + this new line. diff --git a/src/googletest/googlemock/include/gmock/gmock-actions.h b/src/googletest/googlemock/include/gmock/gmock-actions.h new file mode 100644 index 000000000..fb33f7bfa --- /dev/null +++ b/src/googletest/googlemock/include/gmock/gmock-actions.h @@ -0,0 +1,1688 @@ +// 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. + + +// Google Mock - a framework for writing C++ mock classes. +// +// The ACTION* family of macros can be used in a namespace scope to +// define custom actions easily. The syntax: +// +// ACTION(name) { statements; } +// +// will define an action with the given name that executes the +// statements. The value returned by the statements will be used as +// the return value of the action. Inside the statements, you can +// refer to the K-th (0-based) argument of the mock function by +// 'argK', and refer to its type by 'argK_type'. For example: +// +// ACTION(IncrementArg1) { +// arg1_type temp = arg1; +// return ++(*temp); +// } +// +// allows you to write +// +// ...WillOnce(IncrementArg1()); +// +// You can also refer to the entire argument tuple and its type by +// 'args' and 'args_type', and refer to the mock function type and its +// return type by 'function_type' and 'return_type'. +// +// Note that you don't need to specify the types of the mock function +// arguments. However rest assured that your code is still type-safe: +// you'll get a compiler error if *arg1 doesn't support the ++ +// operator, or if the type of ++(*arg1) isn't compatible with the +// mock function's return type, for example. +// +// Sometimes you'll want to parameterize the action. For that you can use +// another macro: +// +// ACTION_P(name, param_name) { statements; } +// +// For example: +// +// ACTION_P(Add, n) { return arg0 + n; } +// +// will allow you to write: +// +// ...WillOnce(Add(5)); +// +// Note that you don't need to provide the type of the parameter +// either. If you need to reference the type of a parameter named +// 'foo', you can write 'foo_type'. For example, in the body of +// ACTION_P(Add, n) above, you can write 'n_type' to refer to the type +// of 'n'. +// +// We also provide ACTION_P2, ACTION_P3, ..., up to ACTION_P10 to support +// multi-parameter actions. +// +// For the purpose of typing, you can view +// +// ACTION_Pk(Foo, p1, ..., pk) { ... } +// +// as shorthand for +// +// template <typename p1_type, ..., typename pk_type> +// FooActionPk<p1_type, ..., pk_type> Foo(p1_type p1, ..., pk_type pk) { ... } +// +// In particular, you can provide the template type arguments +// explicitly when invoking Foo(), as in Foo<long, bool>(5, false); +// although usually you can rely on the compiler to infer the types +// for you automatically. You can assign the result of expression +// Foo(p1, ..., pk) to a variable of type FooActionPk<p1_type, ..., +// pk_type>. This can be useful when composing actions. +// +// You can also overload actions with different numbers of parameters: +// +// ACTION_P(Plus, a) { ... } +// ACTION_P2(Plus, a, b) { ... } +// +// While it's tempting to always use the ACTION* macros when defining +// a new action, you should also consider implementing ActionInterface +// or using MakePolymorphicAction() instead, especially if you need to +// use the action a lot. While these approaches require more work, +// they give you more control on the types of the mock function +// arguments and the action parameters, which in general leads to +// better compiler error messages that pay off in the long run. They +// also allow overloading actions based on parameter types (as opposed +// to just based on the number of parameters). +// +// CAVEAT: +// +// ACTION*() can only be used in a namespace scope as templates cannot be +// declared inside of a local class. +// Users can, however, define any local functors (e.g. a lambda) that +// can be used as actions. +// +// MORE INFORMATION: +// +// To learn more about using these macros, please search for 'ACTION' on +// https://github.com/google/googletest/blob/master/googlemock/docs/cook_book.md + +// GOOGLETEST_CM0002 DO NOT DELETE + +#ifndef GMOCK_INCLUDE_GMOCK_GMOCK_ACTIONS_H_ +#define GMOCK_INCLUDE_GMOCK_GMOCK_ACTIONS_H_ + +#ifndef _WIN32_WCE +# include <errno.h> +#endif + +#include <algorithm> +#include <functional> +#include <memory> +#include <string> +#include <tuple> +#include <type_traits> +#include <utility> + +#include "gmock/internal/gmock-internal-utils.h" +#include "gmock/internal/gmock-port.h" +#include "gmock/internal/gmock-pp.h" + +#ifdef _MSC_VER +# pragma warning(push) +# pragma warning(disable:4100) +#endif + +namespace testing { + +// To implement an action Foo, define: +// 1. a class FooAction that implements the ActionInterface interface, and +// 2. a factory function that creates an Action object from a +// const FooAction*. +// +// The two-level delegation design follows that of Matcher, providing +// consistency for extension developers. It also eases ownership +// management as Action objects can now be copied like plain values. + +namespace internal { + +// BuiltInDefaultValueGetter<T, true>::Get() returns a +// default-constructed T value. BuiltInDefaultValueGetter<T, +// false>::Get() crashes with an error. +// +// This primary template is used when kDefaultConstructible is true. +template <typename T, bool kDefaultConstructible> +struct BuiltInDefaultValueGetter { + static T Get() { return T(); } +}; +template <typename T> +struct BuiltInDefaultValueGetter<T, false> { + static T Get() { + Assert(false, __FILE__, __LINE__, + "Default action undefined for the function return type."); + return internal::Invalid<T>(); + // The above statement will never be reached, but is required in + // order for this function to compile. + } +}; + +// BuiltInDefaultValue<T>::Get() returns the "built-in" default value +// for type T, which is NULL when T is a raw pointer type, 0 when T is +// a numeric type, false when T is bool, or "" when T is string or +// std::string. In addition, in C++11 and above, it turns a +// default-constructed T value if T is default constructible. For any +// other type T, the built-in default T value is undefined, and the +// function will abort the process. +template <typename T> +class BuiltInDefaultValue { + public: + // This function returns true if and only if type T has a built-in default + // value. + static bool Exists() { + return ::std::is_default_constructible<T>::value; + } + + static T Get() { + return BuiltInDefaultValueGetter< + T, ::std::is_default_constructible<T>::value>::Get(); + } +}; + +// This partial specialization says that we use the same built-in +// default value for T and const T. +template <typename T> +class BuiltInDefaultValue<const T> { + public: + static bool Exists() { return BuiltInDefaultValue<T>::Exists(); } + static T Get() { return BuiltInDefaultValue<T>::Get(); } +}; + +// This partial specialization defines the default values for pointer +// types. +template <typename T> +class BuiltInDefaultValue<T*> { + public: + static bool Exists() { return true; } + static T* Get() { return nullptr; } +}; + +// The following specializations define the default values for +// specific types we care about. +#define GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(type, value) \ + template <> \ + class BuiltInDefaultValue<type> { \ + public: \ + static bool Exists() { return true; } \ + static type Get() { return value; } \ + } + +GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(void, ); // NOLINT +GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(::std::string, ""); +GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(bool, false); +GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(unsigned char, '\0'); +GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(signed char, '\0'); +GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(char, '\0'); + +// There's no need for a default action for signed wchar_t, as that +// type is the same as wchar_t for gcc, and invalid for MSVC. +// +// There's also no need for a default action for unsigned wchar_t, as +// that type is the same as unsigned int for gcc, and invalid for +// MSVC. +#if GMOCK_WCHAR_T_IS_NATIVE_ +GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(wchar_t, 0U); // NOLINT +#endif + +GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(unsigned short, 0U); // NOLINT +GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(signed short, 0); // NOLINT +GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(unsigned int, 0U); +GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(signed int, 0); +GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(unsigned long, 0UL); // NOLINT +GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(signed long, 0L); // NOLINT +GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(unsigned long long, 0); // NOLINT +GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(signed long long, 0); // NOLINT +GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(float, 0); +GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(double, 0); + +#undef GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_ + +// Simple two-arg form of std::disjunction. +template <typename P, typename Q> +using disjunction = typename ::std::conditional<P::value, P, Q>::type; + +} // namespace internal + +// When an unexpected function call is encountered, Google Mock will +// let it return a default value if the user has specified one for its +// return type, or if the return type has a built-in default value; +// otherwise Google Mock won't know what value to return and will have +// to abort the process. +// +// The DefaultValue<T> class allows a user to specify the +// default value for a type T that is both copyable and publicly +// destructible (i.e. anything that can be used as a function return +// type). The usage is: +// +// // Sets the default value for type T to be foo. +// DefaultValue<T>::Set(foo); +template <typename T> +class DefaultValue { + public: + // Sets the default value for type T; requires T to be + // copy-constructable and have a public destructor. + static void Set(T x) { + delete producer_; + producer_ = new FixedValueProducer(x); + } + + // Provides a factory function to be called to generate the default value. + // This method can be used even if T is only move-constructible, but it is not + // limited to that case. + typedef T (*FactoryFunction)(); + static void SetFactory(FactoryFunction factory) { + delete producer_; + producer_ = new FactoryValueProducer(factory); + } + + // Unsets the default value for type T. + static void Clear() { + delete producer_; + producer_ = nullptr; + } + + // Returns true if and only if the user has set the default value for type T. + static bool IsSet() { return producer_ != nullptr; } + + // Returns true if T has a default return value set by the user or there + // exists a built-in default value. + static bool Exists() { + return IsSet() || internal::BuiltInDefaultValue<T>::Exists(); + } + + // Returns the default value for type T if the user has set one; + // otherwise returns the built-in default value. Requires that Exists() + // is true, which ensures that the return value is well-defined. + static T Get() { + return producer_ == nullptr ? internal::BuiltInDefaultValue<T>::Get() + : producer_->Produce(); + } + + private: + class ValueProducer { + public: + virtual ~ValueProducer() {} + virtual T Produce() = 0; + }; + + class FixedValueProducer : public ValueProducer { + public: + explicit FixedValueProducer(T value) : value_(value) {} + T Produce() override { return value_; } + + private: + const T value_; + GTEST_DISALLOW_COPY_AND_ASSIGN_(FixedValueProducer); + }; + + class FactoryValueProducer : public ValueProducer { + public: + explicit FactoryValueProducer(FactoryFunction factory) + : factory_(factory) {} + T Produce() override { return factory_(); } + + private: + const FactoryFunction factory_; + GTEST_DISALLOW_COPY_AND_ASSIGN_(FactoryValueProducer); + }; + + static ValueProducer* producer_; +}; + +// This partial specialization allows a user to set default values for +// reference types. +template <typename T> +class DefaultValue<T&> { + public: + // Sets the default value for type T&. + static void Set(T& x) { // NOLINT + address_ = &x; + } + + // Unsets the default value for type T&. + static void Clear() { address_ = nullptr; } + + // Returns true if and only if the user has set the default value for type T&. + static bool IsSet() { return address_ != nullptr; } + + // Returns true if T has a default return value set by the user or there + // exists a built-in default value. + static bool Exists() { + return IsSet() || internal::BuiltInDefaultValue<T&>::Exists(); + } + + // Returns the default value for type T& if the user has set one; + // otherwise returns the built-in default value if there is one; + // otherwise aborts the process. + static T& Get() { + return address_ == nullptr ? internal::BuiltInDefaultValue<T&>::Get() + : *address_; + } + + private: + static T* address_; +}; + +// This specialization allows DefaultValue<void>::Get() to +// compile. +template <> +class DefaultValue<void> { + public: + static bool Exists() { return true; } + static void Get() {} +}; + +// Points to the user-set default value for type T. +template <typename T> +typename DefaultValue<T>::ValueProducer* DefaultValue<T>::producer_ = nullptr; + +// Points to the user-set default value for type T&. +template <typename T> +T* DefaultValue<T&>::address_ = nullptr; + +// Implement this interface to define an action for function type F. +template <typename F> +class ActionInterface { + public: + typedef typename internal::Function<F>::Result Result; + typedef typename internal::Function<F>::ArgumentTuple ArgumentTuple; + + ActionInterface() {} + virtual ~ActionInterface() {} + + // Performs the action. This method is not const, as in general an + // action can have side effects and be stateful. For example, a + // get-the-next-element-from-the-collection action will need to + // remember the current element. + virtual Result Perform(const ArgumentTuple& args) = 0; + + private: + GTEST_DISALLOW_COPY_AND_ASSIGN_(ActionInterface); +}; + +// An Action<F> is a copyable and IMMUTABLE (except by assignment) +// object that represents an action to be taken when a mock function +// of type F is called. The implementation of Action<T> is just a +// std::shared_ptr to const ActionInterface<T>. Don't inherit from Action! +// You can view an object implementing ActionInterface<F> as a +// concrete action (including its current state), and an Action<F> +// object as a handle to it. +template <typename F> +class Action { + // Adapter class to allow constructing Action from a legacy ActionInterface. + // New code should create Actions from functors instead. + struct ActionAdapter { + // Adapter must be copyable to satisfy std::function requirements. + ::std::shared_ptr<ActionInterface<F>> impl_; + + template <typename... Args> + typename internal::Function<F>::Result operator()(Args&&... args) { + return impl_->Perform( + ::std::forward_as_tuple(::std::forward<Args>(args)...)); + } + }; + + template <typename G> + using IsCompatibleFunctor = std::is_constructible<std::function<F>, G>; + + public: + typedef typename internal::Function<F>::Result Result; + typedef typename internal::Function<F>::ArgumentTuple ArgumentTuple; + + // Constructs a null Action. Needed for storing Action objects in + // STL containers. + Action() {} + + // Construct an Action from a specified callable. + // This cannot take std::function directly, because then Action would not be + // directly constructible from lambda (it would require two conversions). + template < + typename G, + typename = typename std::enable_if<internal::disjunction< + IsCompatibleFunctor<G>, std::is_constructible<std::function<Result()>, + G>>::value>::type> + Action(G&& fun) { // NOLINT + Init(::std::forward<G>(fun), IsCompatibleFunctor<G>()); + } + + // Constructs an Action from its implementation. + explicit Action(ActionInterface<F>* impl) + : fun_(ActionAdapter{::std::shared_ptr<ActionInterface<F>>(impl)}) {} + + // This constructor allows us to turn an Action<Func> object into an + // Action<F>, as long as F's arguments can be implicitly converted + // to Func's and Func's return type can be implicitly converted to F's. + template <typename Func> + explicit Action(const Action<Func>& action) : fun_(action.fun_) {} + + // Returns true if and only if this is the DoDefault() action. + bool IsDoDefault() const { return fun_ == nullptr; } + + // Performs the action. Note that this method is const even though + // the corresponding method in ActionInterface is not. The reason + // is that a const Action<F> means that it cannot be re-bound to + // another concrete action, not that the concrete action it binds to + // cannot change state. (Think of the difference between a const + // pointer and a pointer to const.) + Result Perform(ArgumentTuple args) const { + if (IsDoDefault()) { + internal::IllegalDoDefault(__FILE__, __LINE__); + } + return internal::Apply(fun_, ::std::move(args)); + } + + private: + template <typename G> + friend class Action; + + template <typename G> + void Init(G&& g, ::std::true_type) { + fun_ = ::std::forward<G>(g); + } + + template <typename G> + void Init(G&& g, ::std::false_type) { + fun_ = IgnoreArgs<typename ::std::decay<G>::type>{::std::forward<G>(g)}; + } + + template <typename FunctionImpl> + struct IgnoreArgs { + template <typename... Args> + Result operator()(const Args&...) const { + return function_impl(); + } + + FunctionImpl function_impl; + }; + + // fun_ is an empty function if and only if this is the DoDefault() action. + ::std::function<F> fun_; +}; + +// The PolymorphicAction class template makes it easy to implement a +// polymorphic action (i.e. an action that can be used in mock +// functions of than one type, e.g. Return()). +// +// To define a polymorphic action, a user first provides a COPYABLE +// implementation class that has a Perform() method template: +// +// class FooAction { +// public: +// template <typename Result, typename ArgumentTuple> +// Result Perform(const ArgumentTuple& args) const { +// // Processes the arguments and returns a result, using +// // std::get<N>(args) to get the N-th (0-based) argument in the tuple. +// } +// ... +// }; +// +// Then the user creates the polymorphic action using +// MakePolymorphicAction(object) where object has type FooAction. See +// the definition of Return(void) and SetArgumentPointee<N>(value) for +// complete examples. +template <typename Impl> +class PolymorphicAction { + public: + explicit PolymorphicAction(const Impl& impl) : impl_(impl) {} + + template <typename F> + operator Action<F>() const { + return Action<F>(new MonomorphicImpl<F>(impl_)); + } + + private: + template <typename F> + class MonomorphicImpl : public ActionInterface<F> { + public: + typedef typename internal::Function<F>::Result Result; + typedef typename internal::Function<F>::ArgumentTuple ArgumentTuple; + + explicit MonomorphicImpl(const Impl& impl) : impl_(impl) {} + + Result Perform(const ArgumentTuple& args) override { + return impl_.template Perform<Result>(args); + } + + private: + Impl impl_; + }; + + Impl impl_; +}; + +// Creates an Action from its implementation and returns it. The +// created Action object owns the implementation. +template <typename F> +Action<F> MakeAction(ActionInterface<F>* impl) { + return Action<F>(impl); +} + +// Creates a polymorphic action from its implementation. This is +// easier to use than the PolymorphicAction<Impl> constructor as it +// doesn't require you to explicitly write the template argument, e.g. +// +// MakePolymorphicAction(foo); +// vs +// PolymorphicAction<TypeOfFoo>(foo); +template <typename Impl> +inline PolymorphicAction<Impl> MakePolymorphicAction(const Impl& impl) { + return PolymorphicAction<Impl>(impl); +} + +namespace internal { + +// Helper struct to specialize ReturnAction to execute a move instead of a copy +// on return. Useful for move-only types, but could be used on any type. +template <typename T> +struct ByMoveWrapper { + explicit ByMoveWrapper(T value) : payload(std::move(value)) {} + T payload; +}; + +// Implements the polymorphic Return(x) action, which can be used in +// any function that returns the type of x, regardless of the argument +// types. +// +// Note: The value passed into Return must be converted into +// Function<F>::Result when this action is cast to Action<F> rather than +// when that action is performed. This is important in scenarios like +// +// MOCK_METHOD1(Method, T(U)); +// ... +// { +// Foo foo; +// X x(&foo); +// EXPECT_CALL(mock, Method(_)).WillOnce(Return(x)); +// } +// +// In the example above the variable x holds reference to foo which leaves +// scope and gets destroyed. If copying X just copies a reference to foo, +// that copy will be left with a hanging reference. If conversion to T +// makes a copy of foo, the above code is safe. To support that scenario, we +// need to make sure that the type conversion happens inside the EXPECT_CALL +// statement, and conversion of the result of Return to Action<T(U)> is a +// good place for that. +// +// The real life example of the above scenario happens when an invocation +// of gtl::Container() is passed into Return. +// +template <typename R> +class ReturnAction { + public: + // Constructs a ReturnAction object from the value to be returned. + // 'value' is passed by value instead of by const reference in order + // to allow Return("string literal") to compile. + explicit ReturnAction(R value) : value_(new R(std::move(value))) {} + + // This template type conversion operator allows Return(x) to be + // used in ANY function that returns x's type. + template <typename F> + operator Action<F>() const { // NOLINT + // Assert statement belongs here because this is the best place to verify + // conditions on F. It produces the clearest error messages + // in most compilers. + // Impl really belongs in this scope as a local class but can't + // because MSVC produces duplicate symbols in different translation units + // in this case. Until MS fixes that bug we put Impl into the class scope + // and put the typedef both here (for use in assert statement) and + // in the Impl class. But both definitions must be the same. + typedef typename Function<F>::Result Result; + GTEST_COMPILE_ASSERT_( + !std::is_reference<Result>::value, + use_ReturnRef_instead_of_Return_to_return_a_reference); + static_assert(!std::is_void<Result>::value, + "Can't use Return() on an action expected to return `void`."); + return Action<F>(new Impl<R, F>(value_)); + } + + private: + // Implements the Return(x) action for a particular function type F. + template <typename R_, typename F> + class Impl : public ActionInterface<F> { + public: + typedef typename Function<F>::Result Result; + typedef typename Function<F>::ArgumentTuple ArgumentTuple; + + // The implicit cast is necessary when Result has more than one + // single-argument constructor (e.g. Result is std::vector<int>) and R + // has a type conversion operator template. In that case, value_(value) + // won't compile as the compiler doesn't known which constructor of + // Result to call. ImplicitCast_ forces the compiler to convert R to + // Result without considering explicit constructors, thus resolving the + // ambiguity. value_ is then initialized using its copy constructor. + explicit Impl(const std::shared_ptr<R>& value) + : value_before_cast_(*value), + value_(ImplicitCast_<Result>(value_before_cast_)) {} + + Result Perform(const ArgumentTuple&) override { return value_; } + + private: + GTEST_COMPILE_ASSERT_(!std::is_reference<Result>::value, + Result_cannot_be_a_reference_type); + // We save the value before casting just in case it is being cast to a + // wrapper type. + R value_before_cast_; + Result value_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(Impl); + }; + + // Partially specialize for ByMoveWrapper. This version of ReturnAction will + // move its contents instead. + template <typename R_, typename F> + class Impl<ByMoveWrapper<R_>, F> : public ActionInterface<F> { + public: + typedef typename Function<F>::Result Result; + typedef typename Function<F>::ArgumentTuple ArgumentTuple; + + explicit Impl(const std::shared_ptr<R>& wrapper) + : performed_(false), wrapper_(wrapper) {} + + Result Perform(const ArgumentTuple&) override { + GTEST_CHECK_(!performed_) + << "A ByMove() action should only be performed once."; + performed_ = true; + return std::move(wrapper_->payload); + } + + private: + bool performed_; + const std::shared_ptr<R> wrapper_; + }; + + const std::shared_ptr<R> value_; +}; + +// Implements the ReturnNull() action. +class ReturnNullAction { + public: + // Allows ReturnNull() to be used in any pointer-returning function. In C++11 + // this is enforced by returning nullptr, and in non-C++11 by asserting a + // pointer type on compile time. + template <typename Result, typename ArgumentTuple> + static Result Perform(const ArgumentTuple&) { + return nullptr; + } +}; + +// Implements the Return() action. +class ReturnVoidAction { + public: + // Allows Return() to be used in any void-returning function. + template <typename Result, typename ArgumentTuple> + static void Perform(const ArgumentTuple&) { + static_assert(std::is_void<Result>::value, "Result should be void."); + } +}; + +// Implements the polymorphic ReturnRef(x) action, which can be used +// in any function that returns a reference to the type of x, +// regardless of the argument types. +template <typename T> +class ReturnRefAction { + public: + // Constructs a ReturnRefAction object from the reference to be returned. + explicit ReturnRefAction(T& ref) : ref_(ref) {} // NOLINT + + // This template type conversion operator allows ReturnRef(x) to be + // used in ANY function that returns a reference to x's type. + template <typename F> + operator Action<F>() const { + typedef typename Function<F>::Result Result; + // Asserts that the function return type is a reference. This + // catches the user error of using ReturnRef(x) when Return(x) + // should be used, and generates some helpful error message. + GTEST_COMPILE_ASSERT_(std::is_reference<Result>::value, + use_Return_instead_of_ReturnRef_to_return_a_value); + return Action<F>(new Impl<F>(ref_)); + } + + private: + // Implements the ReturnRef(x) action for a particular function type F. + template <typename F> + class Impl : public ActionInterface<F> { + public: + typedef typename Function<F>::Result Result; + typedef typename Function<F>::ArgumentTuple ArgumentTuple; + + explicit Impl(T& ref) : ref_(ref) {} // NOLINT + + Result Perform(const ArgumentTuple&) override { return ref_; } + + private: + T& ref_; + }; + + T& ref_; +}; + +// Implements the polymorphic ReturnRefOfCopy(x) action, which can be +// used in any function that returns a reference to the type of x, +// regardless of the argument types. +template <typename T> +class ReturnRefOfCopyAction { + public: + // Constructs a ReturnRefOfCopyAction object from the reference to + // be returned. + explicit ReturnRefOfCopyAction(const T& value) : value_(value) {} // NOLINT + + // This template type conversion operator allows ReturnRefOfCopy(x) to be + // used in ANY function that returns a reference to x's type. + template <typename F> + operator Action<F>() const { + typedef typename Function<F>::Result Result; + // Asserts that the function return type is a reference. This + // catches the user error of using ReturnRefOfCopy(x) when Return(x) + // should be used, and generates some helpful error message. + GTEST_COMPILE_ASSERT_( + std::is_reference<Result>::value, + use_Return_instead_of_ReturnRefOfCopy_to_return_a_value); + return Action<F>(new Impl<F>(value_)); + } + + private: + // Implements the ReturnRefOfCopy(x) action for a particular function type F. + template <typename F> + class Impl : public ActionInterface<F> { + public: + typedef typename Function<F>::Result Result; + typedef typename Function<F>::ArgumentTuple ArgumentTuple; + + explicit Impl(const T& value) : value_(value) {} // NOLINT + + Result Perform(const ArgumentTuple&) override { return value_; } + + private: + T value_; + }; + + const T value_; +}; + +// Implements the polymorphic ReturnRoundRobin(v) action, which can be +// used in any function that returns the element_type of v. +template <typename T> +class ReturnRoundRobinAction { + public: + explicit ReturnRoundRobinAction(std::vector<T> values) { + GTEST_CHECK_(!values.empty()) + << "ReturnRoundRobin requires at least one element."; + state_->values = std::move(values); + } + + template <typename... Args> + T operator()(Args&&...) const { + return state_->Next(); + } + + private: + struct State { + T Next() { + T ret_val = values[i++]; + if (i == values.size()) i = 0; + return ret_val; + } + + std::vector<T> values; + size_t i = 0; + }; + std::shared_ptr<State> state_ = std::make_shared<State>(); +}; + +// Implements the polymorphic DoDefault() action. +class DoDefaultAction { + public: + // This template type conversion operator allows DoDefault() to be + // used in any function. + template <typename F> + operator Action<F>() const { return Action<F>(); } // NOLINT +}; + +// Implements the Assign action to set a given pointer referent to a +// particular value. +template <typename T1, typename T2> +class AssignAction { + public: + AssignAction(T1* ptr, T2 value) : ptr_(ptr), value_(value) {} + + template <typename Result, typename ArgumentTuple> + void Perform(const ArgumentTuple& /* args */) const { + *ptr_ = value_; + } + + private: + T1* const ptr_; + const T2 value_; +}; + +#if !GTEST_OS_WINDOWS_MOBILE + +// Implements the SetErrnoAndReturn action to simulate return from +// various system calls and libc functions. +template <typename T> +class SetErrnoAndReturnAction { + public: + SetErrnoAndReturnAction(int errno_value, T result) + : errno_(errno_value), + result_(result) {} + template <typename Result, typename ArgumentTuple> + Result Perform(const ArgumentTuple& /* args */) const { + errno = errno_; + return result_; + } + + private: + const int errno_; + const T result_; +}; + +#endif // !GTEST_OS_WINDOWS_MOBILE + +// Implements the SetArgumentPointee<N>(x) action for any function +// whose N-th argument (0-based) is a pointer to x's type. +template <size_t N, typename A, typename = void> +struct SetArgumentPointeeAction { + A value; + + template <typename... Args> + void operator()(const Args&... args) const { + *::std::get<N>(std::tie(args...)) = value; + } +}; + +// Implements the Invoke(object_ptr, &Class::Method) action. +template <class Class, typename MethodPtr> +struct InvokeMethodAction { + Class* const obj_ptr; + const MethodPtr method_ptr; + + template <typename... Args> + auto operator()(Args&&... args) const + -> decltype((obj_ptr->*method_ptr)(std::forward<Args>(args)...)) { + return (obj_ptr->*method_ptr)(std::forward<Args>(args)...); + } +}; + +// Implements the InvokeWithoutArgs(f) action. The template argument +// FunctionImpl is the implementation type of f, which can be either a +// function pointer or a functor. InvokeWithoutArgs(f) can be used as an +// Action<F> as long as f's type is compatible with F. +template <typename FunctionImpl> +struct InvokeWithoutArgsAction { + FunctionImpl function_impl; + + // Allows InvokeWithoutArgs(f) to be used as any action whose type is + // compatible with f. + template <typename... Args> + auto operator()(const Args&...) -> decltype(function_impl()) { + return function_impl(); + } +}; + +// Implements the InvokeWithoutArgs(object_ptr, &Class::Method) action. +template <class Class, typename MethodPtr> +struct InvokeMethodWithoutArgsAction { + Class* const obj_ptr; + const MethodPtr method_ptr; + + using ReturnType = + decltype((std::declval<Class*>()->*std::declval<MethodPtr>())()); + + template <typename... Args> + ReturnType operator()(const Args&...) const { + return (obj_ptr->*method_ptr)(); + } +}; + +// Implements the IgnoreResult(action) action. +template <typename A> +class IgnoreResultAction { + public: + explicit IgnoreResultAction(const A& action) : action_(action) {} + + template <typename F> + operator Action<F>() const { + // Assert statement belongs here because this is the best place to verify + // conditions on F. It produces the clearest error messages + // in most compilers. + // Impl really belongs in this scope as a local class but can't + // because MSVC produces duplicate symbols in different translation units + // in this case. Until MS fixes that bug we put Impl into the class scope + // and put the typedef both here (for use in assert statement) and + // in the Impl class. But both definitions must be the same. + typedef typename internal::Function<F>::Result Result; + + // Asserts at compile time that F returns void. + static_assert(std::is_void<Result>::value, "Result type should be void."); + + return Action<F>(new Impl<F>(action_)); + } + + private: + template <typename F> + class Impl : public ActionInterface<F> { + public: + typedef typename internal::Function<F>::Result Result; + typedef typename internal::Function<F>::ArgumentTuple ArgumentTuple; + + explicit Impl(const A& action) : action_(action) {} + + void Perform(const ArgumentTuple& args) override { + // Performs the action and ignores its result. + action_.Perform(args); + } + + private: + // Type OriginalFunction is the same as F except that its return + // type is IgnoredValue. + typedef typename internal::Function<F>::MakeResultIgnoredValue + OriginalFunction; + + const Action<OriginalFunction> action_; + }; + + const A action_; +}; + +template <typename InnerAction, size_t... I> +struct WithArgsAction { + InnerAction action; + + // The inner action could be anything convertible to Action<X>. + // We use the conversion operator to detect the signature of the inner Action. + template <typename R, typename... Args> + operator Action<R(Args...)>() const { // NOLINT + using TupleType = std::tuple<Args...>; + Action<R(typename std::tuple_element<I, TupleType>::type...)> + converted(action); + + return [converted](Args... args) -> R { + return converted.Perform(std::forward_as_tuple( + std::get<I>(std::forward_as_tuple(std::forward<Args>(args)...))...)); + }; + } +}; + +template <typename... Actions> +struct DoAllAction { + private: + template <typename T> + using NonFinalType = + typename std::conditional<std::is_scalar<T>::value, T, const T&>::type; + + template <typename ActionT, size_t... I> + std::vector<ActionT> Convert(IndexSequence<I...>) const { + return {ActionT(std::get<I>(actions))...}; + } + + public: + std::tuple<Actions...> actions; + + template <typename R, typename... Args> + operator Action<R(Args...)>() const { // NOLINT + struct Op { + std::vector<Action<void(NonFinalType<Args>...)>> converted; + Action<R(Args...)> last; + R operator()(Args... args) const { + auto tuple_args = std::forward_as_tuple(std::forward<Args>(args)...); + for (auto& a : converted) { + a.Perform(tuple_args); + } + return last.Perform(std::move(tuple_args)); + } + }; + return Op{Convert<Action<void(NonFinalType<Args>...)>>( + MakeIndexSequence<sizeof...(Actions) - 1>()), + std::get<sizeof...(Actions) - 1>(actions)}; + } +}; + +template <typename T, typename... Params> +struct ReturnNewAction { + T* operator()() const { + return internal::Apply( + [](const Params&... unpacked_params) { + return new T(unpacked_params...); + }, + params); + } + std::tuple<Params...> params; +}; + +template <size_t k> +struct ReturnArgAction { + template <typename... Args> + auto operator()(const Args&... args) const -> + typename std::tuple_element<k, std::tuple<Args...>>::type { + return std::get<k>(std::tie(args...)); + } +}; + +template <size_t k, typename Ptr> +struct SaveArgAction { + Ptr pointer; + + template <typename... Args> + void operator()(const Args&... args) const { + *pointer = std::get<k>(std::tie(args...)); + } +}; + +template <size_t k, typename Ptr> +struct SaveArgPointeeAction { + Ptr pointer; + + template <typename... Args> + void operator()(const Args&... args) const { + *pointer = *std::get<k>(std::tie(args...)); + } +}; + +template <size_t k, typename T> +struct SetArgRefereeAction { + T value; + + template <typename... Args> + void operator()(Args&&... args) const { + using argk_type = + typename ::std::tuple_element<k, std::tuple<Args...>>::type; + static_assert(std::is_lvalue_reference<argk_type>::value, + "Argument must be a reference type."); + std::get<k>(std::tie(args...)) = value; + } +}; + +template <size_t k, typename I1, typename I2> +struct SetArrayArgumentAction { + I1 first; + I2 last; + + template <typename... Args> + void operator()(const Args&... args) const { + auto value = std::get<k>(std::tie(args...)); + for (auto it = first; it != last; ++it, (void)++value) { + *value = *it; + } + } +}; + +template <size_t k> +struct DeleteArgAction { + template <typename... Args> + void operator()(const Args&... args) const { + delete std::get<k>(std::tie(args...)); + } +}; + +template <typename Ptr> +struct ReturnPointeeAction { + Ptr pointer; + template <typename... Args> + auto operator()(const Args&...) const -> decltype(*pointer) { + return *pointer; + } +}; + +#if GTEST_HAS_EXCEPTIONS +template <typename T> +struct ThrowAction { + T exception; + // We use a conversion operator to adapt to any return type. + template <typename R, typename... Args> + operator Action<R(Args...)>() const { // NOLINT + T copy = exception; + return [copy](Args...) -> R { throw copy; }; + } +}; +#endif // GTEST_HAS_EXCEPTIONS + +} // namespace internal + +// An Unused object can be implicitly constructed from ANY value. +// This is handy when defining actions that ignore some or all of the +// mock function arguments. For example, given +// +// MOCK_METHOD3(Foo, double(const string& label, double x, double y)); +// MOCK_METHOD3(Bar, double(int index, double x, double y)); +// +// instead of +// +// double DistanceToOriginWithLabel(const string& label, double x, double y) { +// return sqrt(x*x + y*y); +// } +// double DistanceToOriginWithIndex(int index, double x, double y) { +// return sqrt(x*x + y*y); +// } +// ... +// EXPECT_CALL(mock, Foo("abc", _, _)) +// .WillOnce(Invoke(DistanceToOriginWithLabel)); +// EXPECT_CALL(mock, Bar(5, _, _)) +// .WillOnce(Invoke(DistanceToOriginWithIndex)); +// +// you could write +// +// // We can declare any uninteresting argument as Unused. +// double DistanceToOrigin(Unused, double x, double y) { +// return sqrt(x*x + y*y); +// } +// ... +// EXPECT_CALL(mock, Foo("abc", _, _)).WillOnce(Invoke(DistanceToOrigin)); +// EXPECT_CALL(mock, Bar(5, _, _)).WillOnce(Invoke(DistanceToOrigin)); +typedef internal::IgnoredValue Unused; + +// Creates an action that does actions a1, a2, ..., sequentially in +// each invocation. All but the last action will have a readonly view of the +// arguments. +template <typename... Action> +internal::DoAllAction<typename std::decay<Action>::type...> DoAll( + Action&&... action) { + return {std::forward_as_tuple(std::forward<Action>(action)...)}; +} + +// WithArg<k>(an_action) creates an action that passes the k-th +// (0-based) argument of the mock function to an_action and performs +// it. It adapts an action accepting one argument to one that accepts +// multiple arguments. For convenience, we also provide +// WithArgs<k>(an_action) (defined below) as a synonym. +template <size_t k, typename InnerAction> +internal::WithArgsAction<typename std::decay<InnerAction>::type, k> +WithArg(InnerAction&& action) { + return {std::forward<InnerAction>(action)}; +} + +// WithArgs<N1, N2, ..., Nk>(an_action) creates an action that passes +// the selected arguments of the mock function to an_action and +// performs it. It serves as an adaptor between actions with +// different argument lists. +template <size_t k, size_t... ks, typename InnerAction> +internal::WithArgsAction<typename std::decay<InnerAction>::type, k, ks...> +WithArgs(InnerAction&& action) { + return {std::forward<InnerAction>(action)}; +} + +// WithoutArgs(inner_action) can be used in a mock function with a +// non-empty argument list to perform inner_action, which takes no +// argument. In other words, it adapts an action accepting no +// argument to one that accepts (and ignores) arguments. +template <typename InnerAction> +internal::WithArgsAction<typename std::decay<InnerAction>::type> +WithoutArgs(InnerAction&& action) { + return {std::forward<InnerAction>(action)}; +} + +// Creates an action that returns 'value'. 'value' is passed by value +// instead of const reference - otherwise Return("string literal") +// will trigger a compiler error about using array as initializer. +template <typename R> +internal::ReturnAction<R> Return(R value) { + return internal::ReturnAction<R>(std::move(value)); +} + +// Creates an action that returns NULL. +inline PolymorphicAction<internal::ReturnNullAction> ReturnNull() { + return MakePolymorphicAction(internal::ReturnNullAction()); +} + +// Creates an action that returns from a void function. +inline PolymorphicAction<internal::ReturnVoidAction> Return() { + return MakePolymorphicAction(internal::ReturnVoidAction()); +} + +// Creates an action that returns the reference to a variable. +template <typename R> +inline internal::ReturnRefAction<R> ReturnRef(R& x) { // NOLINT + return internal::ReturnRefAction<R>(x); +} + +// Prevent using ReturnRef on reference to temporary. +template <typename R, R* = nullptr> +internal::ReturnRefAction<R> ReturnRef(R&&) = delete; + +// Creates an action that returns the reference to a copy of the +// argument. The copy is created when the action is constructed and +// lives as long as the action. +template <typename R> +inline internal::ReturnRefOfCopyAction<R> ReturnRefOfCopy(const R& x) { + return internal::ReturnRefOfCopyAction<R>(x); +} + +// Modifies the parent action (a Return() action) to perform a move of the +// argument instead of a copy. +// Return(ByMove()) actions can only be executed once and will assert this +// invariant. +template <typename R> +internal::ByMoveWrapper<R> ByMove(R x) { + return internal::ByMoveWrapper<R>(std::move(x)); +} + +// Creates an action that returns an element of `vals`. Calling this action will +// repeatedly return the next value from `vals` until it reaches the end and +// will restart from the beginning. +template <typename T> +internal::ReturnRoundRobinAction<T> ReturnRoundRobin(std::vector<T> vals) { + return internal::ReturnRoundRobinAction<T>(std::move(vals)); +} + +// Creates an action that returns an element of `vals`. Calling this action will +// repeatedly return the next value from `vals` until it reaches the end and +// will restart from the beginning. +template <typename T> +internal::ReturnRoundRobinAction<T> ReturnRoundRobin( + std::initializer_list<T> vals) { + return internal::ReturnRoundRobinAction<T>(std::vector<T>(vals)); +} + +// Creates an action that does the default action for the give mock function. +inline internal::DoDefaultAction DoDefault() { + return internal::DoDefaultAction(); +} + +// Creates an action that sets the variable pointed by the N-th +// (0-based) function argument to 'value'. +template <size_t N, typename T> +internal::SetArgumentPointeeAction<N, T> SetArgPointee(T value) { + return {std::move(value)}; +} + +// The following version is DEPRECATED. +template <size_t N, typename T> +internal::SetArgumentPointeeAction<N, T> SetArgumentPointee(T value) { + return {std::move(value)}; +} + +// Creates an action that sets a pointer referent to a given value. +template <typename T1, typename T2> +PolymorphicAction<internal::AssignAction<T1, T2> > Assign(T1* ptr, T2 val) { + return MakePolymorphicAction(internal::AssignAction<T1, T2>(ptr, val)); +} + +#if !GTEST_OS_WINDOWS_MOBILE + +// Creates an action that sets errno and returns the appropriate error. +template <typename T> +PolymorphicAction<internal::SetErrnoAndReturnAction<T> > +SetErrnoAndReturn(int errval, T result) { + return MakePolymorphicAction( + internal::SetErrnoAndReturnAction<T>(errval, result)); +} + +#endif // !GTEST_OS_WINDOWS_MOBILE + +// Various overloads for Invoke(). + +// Legacy function. +// Actions can now be implicitly constructed from callables. No need to create +// wrapper objects. +// This function exists for backwards compatibility. +template <typename FunctionImpl> +typename std::decay<FunctionImpl>::type Invoke(FunctionImpl&& function_impl) { + return std::forward<FunctionImpl>(function_impl); +} + +// Creates an action that invokes the given method on the given object +// with the mock function's arguments. +template <class Class, typename MethodPtr> +internal::InvokeMethodAction<Class, MethodPtr> Invoke(Class* obj_ptr, + MethodPtr method_ptr) { + return {obj_ptr, method_ptr}; +} + +// Creates an action that invokes 'function_impl' with no argument. +template <typename FunctionImpl> +internal::InvokeWithoutArgsAction<typename std::decay<FunctionImpl>::type> +InvokeWithoutArgs(FunctionImpl function_impl) { + return {std::move(function_impl)}; +} + +// Creates an action that invokes the given method on the given object +// with no argument. +template <class Class, typename MethodPtr> +internal::InvokeMethodWithoutArgsAction<Class, MethodPtr> InvokeWithoutArgs( + Class* obj_ptr, MethodPtr method_ptr) { + return {obj_ptr, method_ptr}; +} + +// Creates an action that performs an_action and throws away its +// result. In other words, it changes the return type of an_action to +// void. an_action MUST NOT return void, or the code won't compile. +template <typename A> +inline internal::IgnoreResultAction<A> IgnoreResult(const A& an_action) { + return internal::IgnoreResultAction<A>(an_action); +} + +// Creates a reference wrapper for the given L-value. If necessary, +// you can explicitly specify the type of the reference. For example, +// suppose 'derived' is an object of type Derived, ByRef(derived) +// would wrap a Derived&. If you want to wrap a const Base& instead, +// where Base is a base class of Derived, just write: +// +// ByRef<const Base>(derived) +// +// N.B. ByRef is redundant with std::ref, std::cref and std::reference_wrapper. +// However, it may still be used for consistency with ByMove(). +template <typename T> +inline ::std::reference_wrapper<T> ByRef(T& l_value) { // NOLINT + return ::std::reference_wrapper<T>(l_value); +} + +// The ReturnNew<T>(a1, a2, ..., a_k) action returns a pointer to a new +// instance of type T, constructed on the heap with constructor arguments +// a1, a2, ..., and a_k. The caller assumes ownership of the returned value. +template <typename T, typename... Params> +internal::ReturnNewAction<T, typename std::decay<Params>::type...> ReturnNew( + Params&&... params) { + return {std::forward_as_tuple(std::forward<Params>(params)...)}; +} + +// Action ReturnArg<k>() returns the k-th argument of the mock function. +template <size_t k> +internal::ReturnArgAction<k> ReturnArg() { + return {}; +} + +// Action SaveArg<k>(pointer) saves the k-th (0-based) argument of the +// mock function to *pointer. +template <size_t k, typename Ptr> +internal::SaveArgAction<k, Ptr> SaveArg(Ptr pointer) { + return {pointer}; +} + +// Action SaveArgPointee<k>(pointer) saves the value pointed to +// by the k-th (0-based) argument of the mock function to *pointer. +template <size_t k, typename Ptr> +internal::SaveArgPointeeAction<k, Ptr> SaveArgPointee(Ptr pointer) { + return {pointer}; +} + +// Action SetArgReferee<k>(value) assigns 'value' to the variable +// referenced by the k-th (0-based) argument of the mock function. +template <size_t k, typename T> +internal::SetArgRefereeAction<k, typename std::decay<T>::type> SetArgReferee( + T&& value) { + return {std::forward<T>(value)}; +} + +// Action SetArrayArgument<k>(first, last) copies the elements in +// source range [first, last) to the array pointed to by the k-th +// (0-based) argument, which can be either a pointer or an +// iterator. The action does not take ownership of the elements in the +// source range. +template <size_t k, typename I1, typename I2> +internal::SetArrayArgumentAction<k, I1, I2> SetArrayArgument(I1 first, + I2 last) { + return {first, last}; +} + +// Action DeleteArg<k>() deletes the k-th (0-based) argument of the mock +// function. +template <size_t k> +internal::DeleteArgAction<k> DeleteArg() { + return {}; +} + +// This action returns the value pointed to by 'pointer'. +template <typename Ptr> +internal::ReturnPointeeAction<Ptr> ReturnPointee(Ptr pointer) { + return {pointer}; +} + +// Action Throw(exception) can be used in a mock function of any type +// to throw the given exception. Any copyable value can be thrown. +#if GTEST_HAS_EXCEPTIONS +template <typename T> +internal::ThrowAction<typename std::decay<T>::type> Throw(T&& exception) { + return {std::forward<T>(exception)}; +} +#endif // GTEST_HAS_EXCEPTIONS + +namespace internal { + +// A macro from the ACTION* family (defined later in gmock-generated-actions.h) +// defines an action that can be used in a mock function. Typically, +// these actions only care about a subset of the arguments of the mock +// function. For example, if such an action only uses the second +// argument, it can be used in any mock function that takes >= 2 +// arguments where the type of the second argument is compatible. +// +// Therefore, the action implementation must be prepared to take more +// arguments than it needs. The ExcessiveArg type is used to +// represent those excessive arguments. In order to keep the compiler +// error messages tractable, we define it in the testing namespace +// instead of testing::internal. However, this is an INTERNAL TYPE +// and subject to change without notice, so a user MUST NOT USE THIS +// TYPE DIRECTLY. +struct ExcessiveArg {}; + +// Builds an implementation of an Action<> for some particular signature, using +// a class defined by an ACTION* macro. +template <typename F, typename Impl> struct ActionImpl; + +template <typename Impl> +struct ImplBase { + struct Holder { + // Allows each copy of the Action<> to get to the Impl. + explicit operator const Impl&() const { return *ptr; } + std::shared_ptr<Impl> ptr; + }; + using type = typename std::conditional<std::is_constructible<Impl>::value, + Impl, Holder>::type; +}; + +template <typename R, typename... Args, typename Impl> +struct ActionImpl<R(Args...), Impl> : ImplBase<Impl>::type { + using Base = typename ImplBase<Impl>::type; + using function_type = R(Args...); + using args_type = std::tuple<Args...>; + + ActionImpl() = default; // Only defined if appropriate for Base. + explicit ActionImpl(std::shared_ptr<Impl> impl) : Base{std::move(impl)} { } + + R operator()(Args&&... arg) const { + static constexpr size_t kMaxArgs = + sizeof...(Args) <= 10 ? sizeof...(Args) : 10; + return Apply(MakeIndexSequence<kMaxArgs>{}, + MakeIndexSequence<10 - kMaxArgs>{}, + args_type{std::forward<Args>(arg)...}); + } + + template <std::size_t... arg_id, std::size_t... excess_id> + R Apply(IndexSequence<arg_id...>, IndexSequence<excess_id...>, + const args_type& args) const { + // Impl need not be specific to the signature of action being implemented; + // only the implementing function body needs to have all of the specific + // types instantiated. Up to 10 of the args that are provided by the + // args_type get passed, followed by a dummy of unspecified type for the + // remainder up to 10 explicit args. + static const ExcessiveArg kExcessArg; + return static_cast<const Impl&>(*this).template gmock_PerformImpl< + /*function_type=*/function_type, /*return_type=*/R, + /*args_type=*/args_type, + /*argN_type=*/typename std::tuple_element<arg_id, args_type>::type...>( + /*args=*/args, std::get<arg_id>(args)..., + ((void)excess_id, kExcessArg)...); + } +}; + +// Stores a default-constructed Impl as part of the Action<>'s +// std::function<>. The Impl should be trivial to copy. +template <typename F, typename Impl> +::testing::Action<F> MakeAction() { + return ::testing::Action<F>(ActionImpl<F, Impl>()); +} + +// Stores just the one given instance of Impl. +template <typename F, typename Impl> +::testing::Action<F> MakeAction(std::shared_ptr<Impl> impl) { + return ::testing::Action<F>(ActionImpl<F, Impl>(std::move(impl))); +} + +#define GMOCK_INTERNAL_ARG_UNUSED(i, data, el) \ + , const arg##i##_type& arg##i GTEST_ATTRIBUTE_UNUSED_ +#define GMOCK_ACTION_ARG_TYPES_AND_NAMES_UNUSED_ \ + const args_type& args GTEST_ATTRIBUTE_UNUSED_ GMOCK_PP_REPEAT( \ + GMOCK_INTERNAL_ARG_UNUSED, , 10) + +#define GMOCK_INTERNAL_ARG(i, data, el) , const arg##i##_type& arg##i +#define GMOCK_ACTION_ARG_TYPES_AND_NAMES_ \ + const args_type& args GMOCK_PP_REPEAT(GMOCK_INTERNAL_ARG, , 10) + +#define GMOCK_INTERNAL_TEMPLATE_ARG(i, data, el) , typename arg##i##_type +#define GMOCK_ACTION_TEMPLATE_ARGS_NAMES_ \ + GMOCK_PP_TAIL(GMOCK_PP_REPEAT(GMOCK_INTERNAL_TEMPLATE_ARG, , 10)) + +#define GMOCK_INTERNAL_TYPENAME_PARAM(i, data, param) , typename param##_type +#define GMOCK_ACTION_TYPENAME_PARAMS_(params) \ + GMOCK_PP_TAIL(GMOCK_PP_FOR_EACH(GMOCK_INTERNAL_TYPENAME_PARAM, , params)) + +#define GMOCK_INTERNAL_TYPE_PARAM(i, data, param) , param##_type +#define GMOCK_ACTION_TYPE_PARAMS_(params) \ + GMOCK_PP_TAIL(GMOCK_PP_FOR_EACH(GMOCK_INTERNAL_TYPE_PARAM, , params)) + +#define GMOCK_INTERNAL_TYPE_GVALUE_PARAM(i, data, param) \ + , param##_type gmock_p##i +#define GMOCK_ACTION_TYPE_GVALUE_PARAMS_(params) \ + GMOCK_PP_TAIL(GMOCK_PP_FOR_EACH(GMOCK_INTERNAL_TYPE_GVALUE_PARAM, , params)) + +#define GMOCK_INTERNAL_GVALUE_PARAM(i, data, param) \ + , std::forward<param##_type>(gmock_p##i) +#define GMOCK_ACTION_GVALUE_PARAMS_(params) \ + GMOCK_PP_TAIL(GMOCK_PP_FOR_EACH(GMOCK_INTERNAL_GVALUE_PARAM, , params)) + +#define GMOCK_INTERNAL_INIT_PARAM(i, data, param) \ + , param(::std::forward<param##_type>(gmock_p##i)) +#define GMOCK_ACTION_INIT_PARAMS_(params) \ + GMOCK_PP_TAIL(GMOCK_PP_FOR_EACH(GMOCK_INTERNAL_INIT_PARAM, , params)) + +#define GMOCK_INTERNAL_FIELD_PARAM(i, data, param) param##_type param; +#define GMOCK_ACTION_FIELD_PARAMS_(params) \ + GMOCK_PP_FOR_EACH(GMOCK_INTERNAL_FIELD_PARAM, , params) + +#define GMOCK_INTERNAL_ACTION(name, full_name, params) \ + template <GMOCK_ACTION_TYPENAME_PARAMS_(params)> \ + class full_name { \ + public: \ + explicit full_name(GMOCK_ACTION_TYPE_GVALUE_PARAMS_(params)) \ + : impl_(std::make_shared<gmock_Impl>( \ + GMOCK_ACTION_GVALUE_PARAMS_(params))) { } \ + full_name(const full_name&) = default; \ + full_name(full_name&&) noexcept = default; \ + template <typename F> \ + operator ::testing::Action<F>() const { \ + return ::testing::internal::MakeAction<F>(impl_); \ + } \ + private: \ + class gmock_Impl { \ + public: \ + explicit gmock_Impl(GMOCK_ACTION_TYPE_GVALUE_PARAMS_(params)) \ + : GMOCK_ACTION_INIT_PARAMS_(params) {} \ + template <typename function_type, typename return_type, \ + typename args_type, GMOCK_ACTION_TEMPLATE_ARGS_NAMES_> \ + return_type gmock_PerformImpl(GMOCK_ACTION_ARG_TYPES_AND_NAMES_) const; \ + GMOCK_ACTION_FIELD_PARAMS_(params) \ + }; \ + std::shared_ptr<const gmock_Impl> impl_; \ + }; \ + template <GMOCK_ACTION_TYPENAME_PARAMS_(params)> \ + inline full_name<GMOCK_ACTION_TYPE_PARAMS_(params)> name( \ + GMOCK_ACTION_TYPE_GVALUE_PARAMS_(params)) { \ + return full_name<GMOCK_ACTION_TYPE_PARAMS_(params)>( \ + GMOCK_ACTION_GVALUE_PARAMS_(params)); \ + } \ + template <GMOCK_ACTION_TYPENAME_PARAMS_(params)> \ + template <typename function_type, typename return_type, typename args_type, \ + GMOCK_ACTION_TEMPLATE_ARGS_NAMES_> \ + return_type full_name<GMOCK_ACTION_TYPE_PARAMS_(params)>::gmock_Impl:: \ + gmock_PerformImpl(GMOCK_ACTION_ARG_TYPES_AND_NAMES_UNUSED_) const + +} // namespace internal + +// Similar to GMOCK_INTERNAL_ACTION, but no bound parameters are stored. +#define ACTION(name) \ + class name##Action { \ + public: \ + explicit name##Action() noexcept {} \ + name##Action(const name##Action&) noexcept {} \ + template <typename F> \ + operator ::testing::Action<F>() const { \ + return ::testing::internal::MakeAction<F, gmock_Impl>(); \ + } \ + private: \ + class gmock_Impl { \ + public: \ + template <typename function_type, typename return_type, \ + typename args_type, GMOCK_ACTION_TEMPLATE_ARGS_NAMES_> \ + return_type gmock_PerformImpl(GMOCK_ACTION_ARG_TYPES_AND_NAMES_) const; \ + }; \ + }; \ + inline name##Action name() GTEST_MUST_USE_RESULT_; \ + inline name##Action name() { return name##Action(); } \ + template <typename function_type, typename return_type, typename args_type, \ + GMOCK_ACTION_TEMPLATE_ARGS_NAMES_> \ + return_type name##Action::gmock_Impl::gmock_PerformImpl( \ + GMOCK_ACTION_ARG_TYPES_AND_NAMES_UNUSED_) const + +#define ACTION_P(name, ...) \ + GMOCK_INTERNAL_ACTION(name, name##ActionP, (__VA_ARGS__)) + +#define ACTION_P2(name, ...) \ + GMOCK_INTERNAL_ACTION(name, name##ActionP2, (__VA_ARGS__)) + +#define ACTION_P3(name, ...) \ + GMOCK_INTERNAL_ACTION(name, name##ActionP3, (__VA_ARGS__)) + +#define ACTION_P4(name, ...) \ + GMOCK_INTERNAL_ACTION(name, name##ActionP4, (__VA_ARGS__)) + +#define ACTION_P5(name, ...) \ + GMOCK_INTERNAL_ACTION(name, name##ActionP5, (__VA_ARGS__)) + +#define ACTION_P6(name, ...) \ + GMOCK_INTERNAL_ACTION(name, name##ActionP6, (__VA_ARGS__)) + +#define ACTION_P7(name, ...) \ + GMOCK_INTERNAL_ACTION(name, name##ActionP7, (__VA_ARGS__)) + +#define ACTION_P8(name, ...) \ + GMOCK_INTERNAL_ACTION(name, name##ActionP8, (__VA_ARGS__)) + +#define ACTION_P9(name, ...) \ + GMOCK_INTERNAL_ACTION(name, name##ActionP9, (__VA_ARGS__)) + +#define ACTION_P10(name, ...) \ + GMOCK_INTERNAL_ACTION(name, name##ActionP10, (__VA_ARGS__)) + +} // namespace testing + +#ifdef _MSC_VER +# pragma warning(pop) +#endif + + +#endif // GMOCK_INCLUDE_GMOCK_GMOCK_ACTIONS_H_ diff --git a/src/googletest/googlemock/include/gmock/gmock-cardinalities.h b/src/googletest/googlemock/include/gmock/gmock-cardinalities.h new file mode 100644 index 000000000..46e01e102 --- /dev/null +++ b/src/googletest/googlemock/include/gmock/gmock-cardinalities.h @@ -0,0 +1,157 @@ +// 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. + + +// Google Mock - a framework for writing C++ mock classes. +// +// This file implements some commonly used cardinalities. More +// cardinalities can be defined by the user implementing the +// CardinalityInterface interface if necessary. + +// GOOGLETEST_CM0002 DO NOT DELETE + +#ifndef GMOCK_INCLUDE_GMOCK_GMOCK_CARDINALITIES_H_ +#define GMOCK_INCLUDE_GMOCK_GMOCK_CARDINALITIES_H_ + +#include <limits.h> +#include <memory> +#include <ostream> // NOLINT +#include "gmock/internal/gmock-port.h" +#include "gtest/gtest.h" + +GTEST_DISABLE_MSC_WARNINGS_PUSH_(4251 \ +/* class A needs to have dll-interface to be used by clients of class B */) + +namespace testing { + +// To implement a cardinality Foo, define: +// 1. a class FooCardinality that implements the +// CardinalityInterface interface, and +// 2. a factory function that creates a Cardinality object from a +// const FooCardinality*. +// +// The two-level delegation design follows that of Matcher, providing +// consistency for extension developers. It also eases ownership +// management as Cardinality objects can now be copied like plain values. + +// The implementation of a cardinality. +class CardinalityInterface { + public: + virtual ~CardinalityInterface() {} + + // Conservative estimate on the lower/upper bound of the number of + // calls allowed. + virtual int ConservativeLowerBound() const { return 0; } + virtual int ConservativeUpperBound() const { return INT_MAX; } + + // Returns true if and only if call_count calls will satisfy this + // cardinality. + virtual bool IsSatisfiedByCallCount(int call_count) const = 0; + + // Returns true if and only if call_count calls will saturate this + // cardinality. + virtual bool IsSaturatedByCallCount(int call_count) const = 0; + + // Describes self to an ostream. + virtual void DescribeTo(::std::ostream* os) const = 0; +}; + +// A Cardinality is a copyable and IMMUTABLE (except by assignment) +// object that specifies how many times a mock function is expected to +// be called. The implementation of Cardinality is just a std::shared_ptr +// to const CardinalityInterface. Don't inherit from Cardinality! +class GTEST_API_ Cardinality { + public: + // Constructs a null cardinality. Needed for storing Cardinality + // objects in STL containers. + Cardinality() {} + + // Constructs a Cardinality from its implementation. + explicit Cardinality(const CardinalityInterface* impl) : impl_(impl) {} + + // Conservative estimate on the lower/upper bound of the number of + // calls allowed. + int ConservativeLowerBound() const { return impl_->ConservativeLowerBound(); } + int ConservativeUpperBound() const { return impl_->ConservativeUpperBound(); } + + // Returns true if and only if call_count calls will satisfy this + // cardinality. + bool IsSatisfiedByCallCount(int call_count) const { + return impl_->IsSatisfiedByCallCount(call_count); + } + + // Returns true if and only if call_count calls will saturate this + // cardinality. + bool IsSaturatedByCallCount(int call_count) const { + return impl_->IsSaturatedByCallCount(call_count); + } + + // Returns true if and only if call_count calls will over-saturate this + // cardinality, i.e. exceed the maximum number of allowed calls. + bool IsOverSaturatedByCallCount(int call_count) const { + return impl_->IsSaturatedByCallCount(call_count) && + !impl_->IsSatisfiedByCallCount(call_count); + } + + // Describes self to an ostream + void DescribeTo(::std::ostream* os) const { impl_->DescribeTo(os); } + + // Describes the given actual call count to an ostream. + static void DescribeActualCallCountTo(int actual_call_count, + ::std::ostream* os); + + private: + std::shared_ptr<const CardinalityInterface> impl_; +}; + +// Creates a cardinality that allows at least n calls. +GTEST_API_ Cardinality AtLeast(int n); + +// Creates a cardinality that allows at most n calls. +GTEST_API_ Cardinality AtMost(int n); + +// Creates a cardinality that allows any number of calls. +GTEST_API_ Cardinality AnyNumber(); + +// Creates a cardinality that allows between min and max calls. +GTEST_API_ Cardinality Between(int min, int max); + +// Creates a cardinality that allows exactly n calls. +GTEST_API_ Cardinality Exactly(int n); + +// Creates a cardinality from its implementation. +inline Cardinality MakeCardinality(const CardinalityInterface* c) { + return Cardinality(c); +} + +} // namespace testing + +GTEST_DISABLE_MSC_WARNINGS_POP_() // 4251 + +#endif // GMOCK_INCLUDE_GMOCK_GMOCK_CARDINALITIES_H_ diff --git a/src/googletest/googlemock/include/gmock/gmock-function-mocker.h b/src/googletest/googlemock/include/gmock/gmock-function-mocker.h new file mode 100644 index 000000000..f592d86ec --- /dev/null +++ b/src/googletest/googlemock/include/gmock/gmock-function-mocker.h @@ -0,0 +1,479 @@ +// 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. + +// Google Mock - a framework for writing C++ mock classes. +// +// This file implements MOCK_METHOD. + +// GOOGLETEST_CM0002 DO NOT DELETE + +#ifndef THIRD_PARTY_GOOGLETEST_GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_FUNCTION_MOCKER_H_ // NOLINT +#define THIRD_PARTY_GOOGLETEST_GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_FUNCTION_MOCKER_H_ // NOLINT + +#include <type_traits> // IWYU pragma: keep +#include <utility> // IWYU pragma: keep + +#include "gmock/gmock-spec-builders.h" +#include "gmock/internal/gmock-internal-utils.h" +#include "gmock/internal/gmock-pp.h" + +namespace testing { +namespace internal { +template <typename T> +using identity_t = T; + +template <typename Pattern> +struct ThisRefAdjuster { + template <typename T> + using AdjustT = typename std::conditional< + std::is_const<typename std::remove_reference<Pattern>::type>::value, + typename std::conditional<std::is_lvalue_reference<Pattern>::value, + const T&, const T&&>::type, + typename std::conditional<std::is_lvalue_reference<Pattern>::value, T&, + T&&>::type>::type; + + template <typename MockType> + static AdjustT<MockType> Adjust(const MockType& mock) { + return static_cast<AdjustT<MockType>>(const_cast<MockType&>(mock)); + } +}; + +} // namespace internal + +// The style guide prohibits "using" statements in a namespace scope +// inside a header file. However, the FunctionMocker class template +// is meant to be defined in the ::testing namespace. The following +// line is just a trick for working around a bug in MSVC 8.0, which +// cannot handle it if we define FunctionMocker in ::testing. +using internal::FunctionMocker; +} // namespace testing + +#define MOCK_METHOD(...) \ + GMOCK_PP_VARIADIC_CALL(GMOCK_INTERNAL_MOCK_METHOD_ARG_, __VA_ARGS__) + +#define GMOCK_INTERNAL_MOCK_METHOD_ARG_1(...) \ + GMOCK_INTERNAL_WRONG_ARITY(__VA_ARGS__) + +#define GMOCK_INTERNAL_MOCK_METHOD_ARG_2(...) \ + GMOCK_INTERNAL_WRONG_ARITY(__VA_ARGS__) + +#define GMOCK_INTERNAL_MOCK_METHOD_ARG_3(_Ret, _MethodName, _Args) \ + GMOCK_INTERNAL_MOCK_METHOD_ARG_4(_Ret, _MethodName, _Args, ()) + +#define GMOCK_INTERNAL_MOCK_METHOD_ARG_4(_Ret, _MethodName, _Args, _Spec) \ + GMOCK_INTERNAL_ASSERT_PARENTHESIS(_Args); \ + GMOCK_INTERNAL_ASSERT_PARENTHESIS(_Spec); \ + GMOCK_INTERNAL_ASSERT_VALID_SIGNATURE( \ + GMOCK_PP_NARG0 _Args, GMOCK_INTERNAL_SIGNATURE(_Ret, _Args)); \ + GMOCK_INTERNAL_ASSERT_VALID_SPEC(_Spec) \ + GMOCK_INTERNAL_MOCK_METHOD_IMPL( \ + GMOCK_PP_NARG0 _Args, _MethodName, GMOCK_INTERNAL_HAS_CONST(_Spec), \ + GMOCK_INTERNAL_HAS_OVERRIDE(_Spec), GMOCK_INTERNAL_HAS_FINAL(_Spec), \ + GMOCK_INTERNAL_GET_NOEXCEPT_SPEC(_Spec), \ + GMOCK_INTERNAL_GET_CALLTYPE(_Spec), GMOCK_INTERNAL_GET_REF_SPEC(_Spec), \ + (GMOCK_INTERNAL_SIGNATURE(_Ret, _Args))) + +#define GMOCK_INTERNAL_MOCK_METHOD_ARG_5(...) \ + GMOCK_INTERNAL_WRONG_ARITY(__VA_ARGS__) + +#define GMOCK_INTERNAL_MOCK_METHOD_ARG_6(...) \ + GMOCK_INTERNAL_WRONG_ARITY(__VA_ARGS__) + +#define GMOCK_INTERNAL_MOCK_METHOD_ARG_7(...) \ + GMOCK_INTERNAL_WRONG_ARITY(__VA_ARGS__) + +#define GMOCK_INTERNAL_WRONG_ARITY(...) \ + static_assert( \ + false, \ + "MOCK_METHOD must be called with 3 or 4 arguments. _Ret, " \ + "_MethodName, _Args and optionally _Spec. _Args and _Spec must be " \ + "enclosed in parentheses. If _Ret is a type with unprotected commas, " \ + "it must also be enclosed in parentheses.") + +#define GMOCK_INTERNAL_ASSERT_PARENTHESIS(_Tuple) \ + static_assert( \ + GMOCK_PP_IS_ENCLOSED_PARENS(_Tuple), \ + GMOCK_PP_STRINGIZE(_Tuple) " should be enclosed in parentheses.") + +#define GMOCK_INTERNAL_ASSERT_VALID_SIGNATURE(_N, ...) \ + static_assert( \ + std::is_function<__VA_ARGS__>::value, \ + "Signature must be a function type, maybe return type contains " \ + "unprotected comma."); \ + static_assert( \ + ::testing::tuple_size<typename ::testing::internal::Function< \ + __VA_ARGS__>::ArgumentTuple>::value == _N, \ + "This method does not take " GMOCK_PP_STRINGIZE( \ + _N) " arguments. Parenthesize all types with unprotected commas.") + +#define GMOCK_INTERNAL_ASSERT_VALID_SPEC(_Spec) \ + GMOCK_PP_FOR_EACH(GMOCK_INTERNAL_ASSERT_VALID_SPEC_ELEMENT, ~, _Spec) + +#define GMOCK_INTERNAL_MOCK_METHOD_IMPL(_N, _MethodName, _Constness, \ + _Override, _Final, _NoexceptSpec, \ + _CallType, _RefSpec, _Signature) \ + typename ::testing::internal::Function<GMOCK_PP_REMOVE_PARENS( \ + _Signature)>::Result \ + GMOCK_INTERNAL_EXPAND(_CallType) \ + _MethodName(GMOCK_PP_REPEAT(GMOCK_INTERNAL_PARAMETER, _Signature, _N)) \ + GMOCK_PP_IF(_Constness, const, ) _RefSpec _NoexceptSpec \ + GMOCK_PP_IF(_Override, override, ) GMOCK_PP_IF(_Final, final, ) { \ + GMOCK_MOCKER_(_N, _Constness, _MethodName) \ + .SetOwnerAndName(this, #_MethodName); \ + return GMOCK_MOCKER_(_N, _Constness, _MethodName) \ + .Invoke(GMOCK_PP_REPEAT(GMOCK_INTERNAL_FORWARD_ARG, _Signature, _N)); \ + } \ + ::testing::MockSpec<GMOCK_PP_REMOVE_PARENS(_Signature)> gmock_##_MethodName( \ + GMOCK_PP_REPEAT(GMOCK_INTERNAL_MATCHER_PARAMETER, _Signature, _N)) \ + GMOCK_PP_IF(_Constness, const, ) _RefSpec { \ + GMOCK_MOCKER_(_N, _Constness, _MethodName).RegisterOwner(this); \ + return GMOCK_MOCKER_(_N, _Constness, _MethodName) \ + .With(GMOCK_PP_REPEAT(GMOCK_INTERNAL_MATCHER_ARGUMENT, , _N)); \ + } \ + ::testing::MockSpec<GMOCK_PP_REMOVE_PARENS(_Signature)> gmock_##_MethodName( \ + const ::testing::internal::WithoutMatchers&, \ + GMOCK_PP_IF(_Constness, const, )::testing::internal::Function< \ + GMOCK_PP_REMOVE_PARENS(_Signature)>*) const _RefSpec _NoexceptSpec { \ + return ::testing::internal::ThisRefAdjuster<GMOCK_PP_IF( \ + _Constness, const, ) int _RefSpec>::Adjust(*this) \ + .gmock_##_MethodName(GMOCK_PP_REPEAT( \ + GMOCK_INTERNAL_A_MATCHER_ARGUMENT, _Signature, _N)); \ + } \ + mutable ::testing::FunctionMocker<GMOCK_PP_REMOVE_PARENS(_Signature)> \ + GMOCK_MOCKER_(_N, _Constness, _MethodName) + +#define GMOCK_INTERNAL_EXPAND(...) __VA_ARGS__ + +// Five Valid modifiers. +#define GMOCK_INTERNAL_HAS_CONST(_Tuple) \ + GMOCK_PP_HAS_COMMA(GMOCK_PP_FOR_EACH(GMOCK_INTERNAL_DETECT_CONST, ~, _Tuple)) + +#define GMOCK_INTERNAL_HAS_OVERRIDE(_Tuple) \ + GMOCK_PP_HAS_COMMA( \ + GMOCK_PP_FOR_EACH(GMOCK_INTERNAL_DETECT_OVERRIDE, ~, _Tuple)) + +#define GMOCK_INTERNAL_HAS_FINAL(_Tuple) \ + GMOCK_PP_HAS_COMMA(GMOCK_PP_FOR_EACH(GMOCK_INTERNAL_DETECT_FINAL, ~, _Tuple)) + +#define GMOCK_INTERNAL_GET_NOEXCEPT_SPEC(_Tuple) \ + GMOCK_PP_FOR_EACH(GMOCK_INTERNAL_NOEXCEPT_SPEC_IF_NOEXCEPT, ~, _Tuple) + +#define GMOCK_INTERNAL_NOEXCEPT_SPEC_IF_NOEXCEPT(_i, _, _elem) \ + GMOCK_PP_IF( \ + GMOCK_PP_HAS_COMMA(GMOCK_INTERNAL_DETECT_NOEXCEPT(_i, _, _elem)), \ + _elem, ) + +#define GMOCK_INTERNAL_GET_REF_SPEC(_Tuple) \ + GMOCK_PP_FOR_EACH(GMOCK_INTERNAL_REF_SPEC_IF_REF, ~, _Tuple) + +#define GMOCK_INTERNAL_REF_SPEC_IF_REF(_i, _, _elem) \ + GMOCK_PP_IF(GMOCK_PP_HAS_COMMA(GMOCK_INTERNAL_DETECT_REF(_i, _, _elem)), \ + GMOCK_PP_CAT(GMOCK_INTERNAL_UNPACK_, _elem), ) + +#define GMOCK_INTERNAL_GET_CALLTYPE(_Tuple) \ + GMOCK_PP_FOR_EACH(GMOCK_INTERNAL_GET_CALLTYPE_IMPL, ~, _Tuple) + +#define GMOCK_INTERNAL_ASSERT_VALID_SPEC_ELEMENT(_i, _, _elem) \ + static_assert( \ + (GMOCK_PP_HAS_COMMA(GMOCK_INTERNAL_DETECT_CONST(_i, _, _elem)) + \ + GMOCK_PP_HAS_COMMA(GMOCK_INTERNAL_DETECT_OVERRIDE(_i, _, _elem)) + \ + GMOCK_PP_HAS_COMMA(GMOCK_INTERNAL_DETECT_FINAL(_i, _, _elem)) + \ + GMOCK_PP_HAS_COMMA(GMOCK_INTERNAL_DETECT_NOEXCEPT(_i, _, _elem)) + \ + GMOCK_PP_HAS_COMMA(GMOCK_INTERNAL_DETECT_REF(_i, _, _elem)) + \ + GMOCK_INTERNAL_IS_CALLTYPE(_elem)) == 1, \ + GMOCK_PP_STRINGIZE( \ + _elem) " cannot be recognized as a valid specification modifier."); + +// Modifiers implementation. +#define GMOCK_INTERNAL_DETECT_CONST(_i, _, _elem) \ + GMOCK_PP_CAT(GMOCK_INTERNAL_DETECT_CONST_I_, _elem) + +#define GMOCK_INTERNAL_DETECT_CONST_I_const , + +#define GMOCK_INTERNAL_DETECT_OVERRIDE(_i, _, _elem) \ + GMOCK_PP_CAT(GMOCK_INTERNAL_DETECT_OVERRIDE_I_, _elem) + +#define GMOCK_INTERNAL_DETECT_OVERRIDE_I_override , + +#define GMOCK_INTERNAL_DETECT_FINAL(_i, _, _elem) \ + GMOCK_PP_CAT(GMOCK_INTERNAL_DETECT_FINAL_I_, _elem) + +#define GMOCK_INTERNAL_DETECT_FINAL_I_final , + +#define GMOCK_INTERNAL_DETECT_NOEXCEPT(_i, _, _elem) \ + GMOCK_PP_CAT(GMOCK_INTERNAL_DETECT_NOEXCEPT_I_, _elem) + +#define GMOCK_INTERNAL_DETECT_NOEXCEPT_I_noexcept , + +#define GMOCK_INTERNAL_DETECT_REF(_i, _, _elem) \ + GMOCK_PP_CAT(GMOCK_INTERNAL_DETECT_REF_I_, _elem) + +#define GMOCK_INTERNAL_DETECT_REF_I_ref , + +#define GMOCK_INTERNAL_UNPACK_ref(x) x + +#define GMOCK_INTERNAL_GET_CALLTYPE_IMPL(_i, _, _elem) \ + GMOCK_PP_IF(GMOCK_INTERNAL_IS_CALLTYPE(_elem), \ + GMOCK_INTERNAL_GET_VALUE_CALLTYPE, GMOCK_PP_EMPTY) \ + (_elem) + +// TODO(iserna): GMOCK_INTERNAL_IS_CALLTYPE and +// GMOCK_INTERNAL_GET_VALUE_CALLTYPE needed more expansions to work on windows +// maybe they can be simplified somehow. +#define GMOCK_INTERNAL_IS_CALLTYPE(_arg) \ + GMOCK_INTERNAL_IS_CALLTYPE_I( \ + GMOCK_PP_CAT(GMOCK_INTERNAL_IS_CALLTYPE_HELPER_, _arg)) +#define GMOCK_INTERNAL_IS_CALLTYPE_I(_arg) GMOCK_PP_IS_ENCLOSED_PARENS(_arg) + +#define GMOCK_INTERNAL_GET_VALUE_CALLTYPE(_arg) \ + GMOCK_INTERNAL_GET_VALUE_CALLTYPE_I( \ + GMOCK_PP_CAT(GMOCK_INTERNAL_IS_CALLTYPE_HELPER_, _arg)) +#define GMOCK_INTERNAL_GET_VALUE_CALLTYPE_I(_arg) \ + GMOCK_PP_IDENTITY _arg + +#define GMOCK_INTERNAL_IS_CALLTYPE_HELPER_Calltype + +// Note: The use of `identity_t` here allows _Ret to represent return types that +// would normally need to be specified in a different way. For example, a method +// returning a function pointer must be written as +// +// fn_ptr_return_t (*method(method_args_t...))(fn_ptr_args_t...) +// +// But we only support placing the return type at the beginning. To handle this, +// we wrap all calls in identity_t, so that a declaration will be expanded to +// +// identity_t<fn_ptr_return_t (*)(fn_ptr_args_t...)> method(method_args_t...) +// +// This allows us to work around the syntactic oddities of function/method +// types. +#define GMOCK_INTERNAL_SIGNATURE(_Ret, _Args) \ + ::testing::internal::identity_t<GMOCK_PP_IF(GMOCK_PP_IS_BEGIN_PARENS(_Ret), \ + GMOCK_PP_REMOVE_PARENS, \ + GMOCK_PP_IDENTITY)(_Ret)>( \ + GMOCK_PP_FOR_EACH(GMOCK_INTERNAL_GET_TYPE, _, _Args)) + +#define GMOCK_INTERNAL_GET_TYPE(_i, _, _elem) \ + GMOCK_PP_COMMA_IF(_i) \ + GMOCK_PP_IF(GMOCK_PP_IS_BEGIN_PARENS(_elem), GMOCK_PP_REMOVE_PARENS, \ + GMOCK_PP_IDENTITY) \ + (_elem) + +#define GMOCK_INTERNAL_PARAMETER(_i, _Signature, _) \ + GMOCK_PP_COMMA_IF(_i) \ + GMOCK_INTERNAL_ARG_O(_i, GMOCK_PP_REMOVE_PARENS(_Signature)) \ + gmock_a##_i + +#define GMOCK_INTERNAL_FORWARD_ARG(_i, _Signature, _) \ + GMOCK_PP_COMMA_IF(_i) \ + ::std::forward<GMOCK_INTERNAL_ARG_O( \ + _i, GMOCK_PP_REMOVE_PARENS(_Signature))>(gmock_a##_i) + +#define GMOCK_INTERNAL_MATCHER_PARAMETER(_i, _Signature, _) \ + GMOCK_PP_COMMA_IF(_i) \ + GMOCK_INTERNAL_MATCHER_O(_i, GMOCK_PP_REMOVE_PARENS(_Signature)) \ + gmock_a##_i + +#define GMOCK_INTERNAL_MATCHER_ARGUMENT(_i, _1, _2) \ + GMOCK_PP_COMMA_IF(_i) \ + gmock_a##_i + +#define GMOCK_INTERNAL_A_MATCHER_ARGUMENT(_i, _Signature, _) \ + GMOCK_PP_COMMA_IF(_i) \ + ::testing::A<GMOCK_INTERNAL_ARG_O(_i, GMOCK_PP_REMOVE_PARENS(_Signature))>() + +#define GMOCK_INTERNAL_ARG_O(_i, ...) \ + typename ::testing::internal::Function<__VA_ARGS__>::template Arg<_i>::type + +#define GMOCK_INTERNAL_MATCHER_O(_i, ...) \ + const ::testing::Matcher<typename ::testing::internal::Function< \ + __VA_ARGS__>::template Arg<_i>::type>& + +#define MOCK_METHOD0(m, ...) GMOCK_INTERNAL_MOCK_METHODN(, , m, 0, __VA_ARGS__) +#define MOCK_METHOD1(m, ...) GMOCK_INTERNAL_MOCK_METHODN(, , m, 1, __VA_ARGS__) +#define MOCK_METHOD2(m, ...) GMOCK_INTERNAL_MOCK_METHODN(, , m, 2, __VA_ARGS__) +#define MOCK_METHOD3(m, ...) GMOCK_INTERNAL_MOCK_METHODN(, , m, 3, __VA_ARGS__) +#define MOCK_METHOD4(m, ...) GMOCK_INTERNAL_MOCK_METHODN(, , m, 4, __VA_ARGS__) +#define MOCK_METHOD5(m, ...) GMOCK_INTERNAL_MOCK_METHODN(, , m, 5, __VA_ARGS__) +#define MOCK_METHOD6(m, ...) GMOCK_INTERNAL_MOCK_METHODN(, , m, 6, __VA_ARGS__) +#define MOCK_METHOD7(m, ...) GMOCK_INTERNAL_MOCK_METHODN(, , m, 7, __VA_ARGS__) +#define MOCK_METHOD8(m, ...) GMOCK_INTERNAL_MOCK_METHODN(, , m, 8, __VA_ARGS__) +#define MOCK_METHOD9(m, ...) GMOCK_INTERNAL_MOCK_METHODN(, , m, 9, __VA_ARGS__) +#define MOCK_METHOD10(m, ...) \ + GMOCK_INTERNAL_MOCK_METHODN(, , m, 10, __VA_ARGS__) + +#define MOCK_CONST_METHOD0(m, ...) \ + GMOCK_INTERNAL_MOCK_METHODN(const, , m, 0, __VA_ARGS__) +#define MOCK_CONST_METHOD1(m, ...) \ + GMOCK_INTERNAL_MOCK_METHODN(const, , m, 1, __VA_ARGS__) +#define MOCK_CONST_METHOD2(m, ...) \ + GMOCK_INTERNAL_MOCK_METHODN(const, , m, 2, __VA_ARGS__) +#define MOCK_CONST_METHOD3(m, ...) \ + GMOCK_INTERNAL_MOCK_METHODN(const, , m, 3, __VA_ARGS__) +#define MOCK_CONST_METHOD4(m, ...) \ + GMOCK_INTERNAL_MOCK_METHODN(const, , m, 4, __VA_ARGS__) +#define MOCK_CONST_METHOD5(m, ...) \ + GMOCK_INTERNAL_MOCK_METHODN(const, , m, 5, __VA_ARGS__) +#define MOCK_CONST_METHOD6(m, ...) \ + GMOCK_INTERNAL_MOCK_METHODN(const, , m, 6, __VA_ARGS__) +#define MOCK_CONST_METHOD7(m, ...) \ + GMOCK_INTERNAL_MOCK_METHODN(const, , m, 7, __VA_ARGS__) +#define MOCK_CONST_METHOD8(m, ...) \ + GMOCK_INTERNAL_MOCK_METHODN(const, , m, 8, __VA_ARGS__) +#define MOCK_CONST_METHOD9(m, ...) \ + GMOCK_INTERNAL_MOCK_METHODN(const, , m, 9, __VA_ARGS__) +#define MOCK_CONST_METHOD10(m, ...) \ + GMOCK_INTERNAL_MOCK_METHODN(const, , m, 10, __VA_ARGS__) + +#define MOCK_METHOD0_T(m, ...) MOCK_METHOD0(m, __VA_ARGS__) +#define MOCK_METHOD1_T(m, ...) MOCK_METHOD1(m, __VA_ARGS__) +#define MOCK_METHOD2_T(m, ...) MOCK_METHOD2(m, __VA_ARGS__) +#define MOCK_METHOD3_T(m, ...) MOCK_METHOD3(m, __VA_ARGS__) +#define MOCK_METHOD4_T(m, ...) MOCK_METHOD4(m, __VA_ARGS__) +#define MOCK_METHOD5_T(m, ...) MOCK_METHOD5(m, __VA_ARGS__) +#define MOCK_METHOD6_T(m, ...) MOCK_METHOD6(m, __VA_ARGS__) +#define MOCK_METHOD7_T(m, ...) MOCK_METHOD7(m, __VA_ARGS__) +#define MOCK_METHOD8_T(m, ...) MOCK_METHOD8(m, __VA_ARGS__) +#define MOCK_METHOD9_T(m, ...) MOCK_METHOD9(m, __VA_ARGS__) +#define MOCK_METHOD10_T(m, ...) MOCK_METHOD10(m, __VA_ARGS__) + +#define MOCK_CONST_METHOD0_T(m, ...) MOCK_CONST_METHOD0(m, __VA_ARGS__) +#define MOCK_CONST_METHOD1_T(m, ...) MOCK_CONST_METHOD1(m, __VA_ARGS__) +#define MOCK_CONST_METHOD2_T(m, ...) MOCK_CONST_METHOD2(m, __VA_ARGS__) +#define MOCK_CONST_METHOD3_T(m, ...) MOCK_CONST_METHOD3(m, __VA_ARGS__) +#define MOCK_CONST_METHOD4_T(m, ...) MOCK_CONST_METHOD4(m, __VA_ARGS__) +#define MOCK_CONST_METHOD5_T(m, ...) MOCK_CONST_METHOD5(m, __VA_ARGS__) +#define MOCK_CONST_METHOD6_T(m, ...) MOCK_CONST_METHOD6(m, __VA_ARGS__) +#define MOCK_CONST_METHOD7_T(m, ...) MOCK_CONST_METHOD7(m, __VA_ARGS__) +#define MOCK_CONST_METHOD8_T(m, ...) MOCK_CONST_METHOD8(m, __VA_ARGS__) +#define MOCK_CONST_METHOD9_T(m, ...) MOCK_CONST_METHOD9(m, __VA_ARGS__) +#define MOCK_CONST_METHOD10_T(m, ...) MOCK_CONST_METHOD10(m, __VA_ARGS__) + +#define MOCK_METHOD0_WITH_CALLTYPE(ct, m, ...) \ + GMOCK_INTERNAL_MOCK_METHODN(, ct, m, 0, __VA_ARGS__) +#define MOCK_METHOD1_WITH_CALLTYPE(ct, m, ...) \ + GMOCK_INTERNAL_MOCK_METHODN(, ct, m, 1, __VA_ARGS__) +#define MOCK_METHOD2_WITH_CALLTYPE(ct, m, ...) \ + GMOCK_INTERNAL_MOCK_METHODN(, ct, m, 2, __VA_ARGS__) +#define MOCK_METHOD3_WITH_CALLTYPE(ct, m, ...) \ + GMOCK_INTERNAL_MOCK_METHODN(, ct, m, 3, __VA_ARGS__) +#define MOCK_METHOD4_WITH_CALLTYPE(ct, m, ...) \ + GMOCK_INTERNAL_MOCK_METHODN(, ct, m, 4, __VA_ARGS__) +#define MOCK_METHOD5_WITH_CALLTYPE(ct, m, ...) \ + GMOCK_INTERNAL_MOCK_METHODN(, ct, m, 5, __VA_ARGS__) +#define MOCK_METHOD6_WITH_CALLTYPE(ct, m, ...) \ + GMOCK_INTERNAL_MOCK_METHODN(, ct, m, 6, __VA_ARGS__) +#define MOCK_METHOD7_WITH_CALLTYPE(ct, m, ...) \ + GMOCK_INTERNAL_MOCK_METHODN(, ct, m, 7, __VA_ARGS__) +#define MOCK_METHOD8_WITH_CALLTYPE(ct, m, ...) \ + GMOCK_INTERNAL_MOCK_METHODN(, ct, m, 8, __VA_ARGS__) +#define MOCK_METHOD9_WITH_CALLTYPE(ct, m, ...) \ + GMOCK_INTERNAL_MOCK_METHODN(, ct, m, 9, __VA_ARGS__) +#define MOCK_METHOD10_WITH_CALLTYPE(ct, m, ...) \ + GMOCK_INTERNAL_MOCK_METHODN(, ct, m, 10, __VA_ARGS__) + +#define MOCK_CONST_METHOD0_WITH_CALLTYPE(ct, m, ...) \ + GMOCK_INTERNAL_MOCK_METHODN(const, ct, m, 0, __VA_ARGS__) +#define MOCK_CONST_METHOD1_WITH_CALLTYPE(ct, m, ...) \ + GMOCK_INTERNAL_MOCK_METHODN(const, ct, m, 1, __VA_ARGS__) +#define MOCK_CONST_METHOD2_WITH_CALLTYPE(ct, m, ...) \ + GMOCK_INTERNAL_MOCK_METHODN(const, ct, m, 2, __VA_ARGS__) +#define MOCK_CONST_METHOD3_WITH_CALLTYPE(ct, m, ...) \ + GMOCK_INTERNAL_MOCK_METHODN(const, ct, m, 3, __VA_ARGS__) +#define MOCK_CONST_METHOD4_WITH_CALLTYPE(ct, m, ...) \ + GMOCK_INTERNAL_MOCK_METHODN(const, ct, m, 4, __VA_ARGS__) +#define MOCK_CONST_METHOD5_WITH_CALLTYPE(ct, m, ...) \ + GMOCK_INTERNAL_MOCK_METHODN(const, ct, m, 5, __VA_ARGS__) +#define MOCK_CONST_METHOD6_WITH_CALLTYPE(ct, m, ...) \ + GMOCK_INTERNAL_MOCK_METHODN(const, ct, m, 6, __VA_ARGS__) +#define MOCK_CONST_METHOD7_WITH_CALLTYPE(ct, m, ...) \ + GMOCK_INTERNAL_MOCK_METHODN(const, ct, m, 7, __VA_ARGS__) +#define MOCK_CONST_METHOD8_WITH_CALLTYPE(ct, m, ...) \ + GMOCK_INTERNAL_MOCK_METHODN(const, ct, m, 8, __VA_ARGS__) +#define MOCK_CONST_METHOD9_WITH_CALLTYPE(ct, m, ...) \ + GMOCK_INTERNAL_MOCK_METHODN(const, ct, m, 9, __VA_ARGS__) +#define MOCK_CONST_METHOD10_WITH_CALLTYPE(ct, m, ...) \ + GMOCK_INTERNAL_MOCK_METHODN(const, ct, m, 10, __VA_ARGS__) + +#define MOCK_METHOD0_T_WITH_CALLTYPE(ct, m, ...) \ + MOCK_METHOD0_WITH_CALLTYPE(ct, m, __VA_ARGS__) +#define MOCK_METHOD1_T_WITH_CALLTYPE(ct, m, ...) \ + MOCK_METHOD1_WITH_CALLTYPE(ct, m, __VA_ARGS__) +#define MOCK_METHOD2_T_WITH_CALLTYPE(ct, m, ...) \ + MOCK_METHOD2_WITH_CALLTYPE(ct, m, __VA_ARGS__) +#define MOCK_METHOD3_T_WITH_CALLTYPE(ct, m, ...) \ + MOCK_METHOD3_WITH_CALLTYPE(ct, m, __VA_ARGS__) +#define MOCK_METHOD4_T_WITH_CALLTYPE(ct, m, ...) \ + MOCK_METHOD4_WITH_CALLTYPE(ct, m, __VA_ARGS__) +#define MOCK_METHOD5_T_WITH_CALLTYPE(ct, m, ...) \ + MOCK_METHOD5_WITH_CALLTYPE(ct, m, __VA_ARGS__) +#define MOCK_METHOD6_T_WITH_CALLTYPE(ct, m, ...) \ + MOCK_METHOD6_WITH_CALLTYPE(ct, m, __VA_ARGS__) +#define MOCK_METHOD7_T_WITH_CALLTYPE(ct, m, ...) \ + MOCK_METHOD7_WITH_CALLTYPE(ct, m, __VA_ARGS__) +#define MOCK_METHOD8_T_WITH_CALLTYPE(ct, m, ...) \ + MOCK_METHOD8_WITH_CALLTYPE(ct, m, __VA_ARGS__) +#define MOCK_METHOD9_T_WITH_CALLTYPE(ct, m, ...) \ + MOCK_METHOD9_WITH_CALLTYPE(ct, m, __VA_ARGS__) +#define MOCK_METHOD10_T_WITH_CALLTYPE(ct, m, ...) \ + MOCK_METHOD10_WITH_CALLTYPE(ct, m, __VA_ARGS__) + +#define MOCK_CONST_METHOD0_T_WITH_CALLTYPE(ct, m, ...) \ + MOCK_CONST_METHOD0_WITH_CALLTYPE(ct, m, __VA_ARGS__) +#define MOCK_CONST_METHOD1_T_WITH_CALLTYPE(ct, m, ...) \ + MOCK_CONST_METHOD1_WITH_CALLTYPE(ct, m, __VA_ARGS__) +#define MOCK_CONST_METHOD2_T_WITH_CALLTYPE(ct, m, ...) \ + MOCK_CONST_METHOD2_WITH_CALLTYPE(ct, m, __VA_ARGS__) +#define MOCK_CONST_METHOD3_T_WITH_CALLTYPE(ct, m, ...) \ + MOCK_CONST_METHOD3_WITH_CALLTYPE(ct, m, __VA_ARGS__) +#define MOCK_CONST_METHOD4_T_WITH_CALLTYPE(ct, m, ...) \ + MOCK_CONST_METHOD4_WITH_CALLTYPE(ct, m, __VA_ARGS__) +#define MOCK_CONST_METHOD5_T_WITH_CALLTYPE(ct, m, ...) \ + MOCK_CONST_METHOD5_WITH_CALLTYPE(ct, m, __VA_ARGS__) +#define MOCK_CONST_METHOD6_T_WITH_CALLTYPE(ct, m, ...) \ + MOCK_CONST_METHOD6_WITH_CALLTYPE(ct, m, __VA_ARGS__) +#define MOCK_CONST_METHOD7_T_WITH_CALLTYPE(ct, m, ...) \ + MOCK_CONST_METHOD7_WITH_CALLTYPE(ct, m, __VA_ARGS__) +#define MOCK_CONST_METHOD8_T_WITH_CALLTYPE(ct, m, ...) \ + MOCK_CONST_METHOD8_WITH_CALLTYPE(ct, m, __VA_ARGS__) +#define MOCK_CONST_METHOD9_T_WITH_CALLTYPE(ct, m, ...) \ + MOCK_CONST_METHOD9_WITH_CALLTYPE(ct, m, __VA_ARGS__) +#define MOCK_CONST_METHOD10_T_WITH_CALLTYPE(ct, m, ...) \ + MOCK_CONST_METHOD10_WITH_CALLTYPE(ct, m, __VA_ARGS__) + +#define GMOCK_INTERNAL_MOCK_METHODN(constness, ct, Method, args_num, ...) \ + GMOCK_INTERNAL_ASSERT_VALID_SIGNATURE( \ + args_num, ::testing::internal::identity_t<__VA_ARGS__>); \ + GMOCK_INTERNAL_MOCK_METHOD_IMPL( \ + args_num, Method, GMOCK_PP_NARG0(constness), 0, 0, , ct, , \ + (::testing::internal::identity_t<__VA_ARGS__>)) + +#define GMOCK_MOCKER_(arity, constness, Method) \ + GTEST_CONCAT_TOKEN_(gmock##constness##arity##_##Method##_, __LINE__) + +#endif // THIRD_PARTY_GOOGLETEST_GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_FUNCTION_MOCKER_H_ diff --git a/src/googletest/googlemock/include/gmock/gmock-generated-actions.h b/src/googletest/googlemock/include/gmock/gmock-generated-actions.h new file mode 100644 index 000000000..62909ea08 --- /dev/null +++ b/src/googletest/googlemock/include/gmock/gmock-generated-actions.h @@ -0,0 +1,577 @@ +// This file was GENERATED by command: +// pump.py gmock-generated-actions.h.pump +// DO NOT EDIT BY HAND!!! + +// 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. + + +// Google Mock - a framework for writing C++ mock classes. +// +// This file implements some commonly used variadic actions. + +// GOOGLETEST_CM0002 DO NOT DELETE + +#ifndef GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_ACTIONS_H_ +#define GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_ACTIONS_H_ + +#include <memory> +#include <utility> + +#include "gmock/gmock-actions.h" +#include "gmock/internal/gmock-port.h" + +// Include any custom callback actions added by the local installation. +#include "gmock/internal/custom/gmock-generated-actions.h" + +// Sometimes you want to give an action explicit template parameters +// that cannot be inferred from its value parameters. ACTION() and +// ACTION_P*() don't support that. ACTION_TEMPLATE() remedies that +// and can be viewed as an extension to ACTION() and ACTION_P*(). +// +// The syntax: +// +// ACTION_TEMPLATE(ActionName, +// HAS_m_TEMPLATE_PARAMS(kind1, name1, ..., kind_m, name_m), +// AND_n_VALUE_PARAMS(p1, ..., p_n)) { statements; } +// +// defines an action template that takes m explicit template +// parameters and n value parameters. name_i is the name of the i-th +// template parameter, and kind_i specifies whether it's a typename, +// an integral constant, or a template. p_i is the name of the i-th +// value parameter. +// +// Example: +// +// // DuplicateArg<k, T>(output) converts the k-th argument of the mock +// // function to type T and copies it to *output. +// ACTION_TEMPLATE(DuplicateArg, +// HAS_2_TEMPLATE_PARAMS(int, k, typename, T), +// AND_1_VALUE_PARAMS(output)) { +// *output = T(::std::get<k>(args)); +// } +// ... +// int n; +// EXPECT_CALL(mock, Foo(_, _)) +// .WillOnce(DuplicateArg<1, unsigned char>(&n)); +// +// To create an instance of an action template, write: +// +// ActionName<t1, ..., t_m>(v1, ..., v_n) +// +// where the ts are the template arguments and the vs are the value +// arguments. The value argument types are inferred by the compiler. +// If you want to explicitly specify the value argument types, you can +// provide additional template arguments: +// +// ActionName<t1, ..., t_m, u1, ..., u_k>(v1, ..., v_n) +// +// where u_i is the desired type of v_i. +// +// ACTION_TEMPLATE and ACTION/ACTION_P* can be overloaded on the +// number of value parameters, but not on the number of template +// parameters. Without the restriction, the meaning of the following +// is unclear: +// +// OverloadedAction<int, bool>(x); +// +// Are we using a single-template-parameter action where 'bool' refers +// to the type of x, or are we using a two-template-parameter action +// where the compiler is asked to infer the type of x? +// +// Implementation notes: +// +// GMOCK_INTERNAL_*_HAS_m_TEMPLATE_PARAMS and +// GMOCK_INTERNAL_*_AND_n_VALUE_PARAMS are internal macros for +// implementing ACTION_TEMPLATE. The main trick we use is to create +// new macro invocations when expanding a macro. For example, we have +// +// #define ACTION_TEMPLATE(name, template_params, value_params) +// ... GMOCK_INTERNAL_DECL_##template_params ... +// +// which causes ACTION_TEMPLATE(..., HAS_1_TEMPLATE_PARAMS(typename, T), ...) +// to expand to +// +// ... GMOCK_INTERNAL_DECL_HAS_1_TEMPLATE_PARAMS(typename, T) ... +// +// Since GMOCK_INTERNAL_DECL_HAS_1_TEMPLATE_PARAMS is a macro, the +// preprocessor will continue to expand it to +// +// ... typename T ... +// +// This technique conforms to the C++ standard and is portable. It +// allows us to implement action templates using O(N) code, where N is +// the maximum number of template/value parameters supported. Without +// using it, we'd have to devote O(N^2) amount of code to implement all +// combinations of m and n. + +// Declares the template parameters. +#define GMOCK_INTERNAL_DECL_HAS_1_TEMPLATE_PARAMS(kind0, name0) kind0 name0 +#define GMOCK_INTERNAL_DECL_HAS_2_TEMPLATE_PARAMS(kind0, name0, kind1, \ + name1) kind0 name0, kind1 name1 +#define GMOCK_INTERNAL_DECL_HAS_3_TEMPLATE_PARAMS(kind0, name0, kind1, name1, \ + kind2, name2) kind0 name0, kind1 name1, kind2 name2 +#define GMOCK_INTERNAL_DECL_HAS_4_TEMPLATE_PARAMS(kind0, name0, kind1, name1, \ + kind2, name2, kind3, name3) kind0 name0, kind1 name1, kind2 name2, \ + kind3 name3 +#define GMOCK_INTERNAL_DECL_HAS_5_TEMPLATE_PARAMS(kind0, name0, kind1, name1, \ + kind2, name2, kind3, name3, kind4, name4) kind0 name0, kind1 name1, \ + kind2 name2, kind3 name3, kind4 name4 +#define GMOCK_INTERNAL_DECL_HAS_6_TEMPLATE_PARAMS(kind0, name0, kind1, name1, \ + kind2, name2, kind3, name3, kind4, name4, kind5, name5) kind0 name0, \ + kind1 name1, kind2 name2, kind3 name3, kind4 name4, kind5 name5 +#define GMOCK_INTERNAL_DECL_HAS_7_TEMPLATE_PARAMS(kind0, name0, kind1, name1, \ + kind2, name2, kind3, name3, kind4, name4, kind5, name5, kind6, \ + name6) kind0 name0, kind1 name1, kind2 name2, kind3 name3, kind4 name4, \ + kind5 name5, kind6 name6 +#define GMOCK_INTERNAL_DECL_HAS_8_TEMPLATE_PARAMS(kind0, name0, kind1, name1, \ + kind2, name2, kind3, name3, kind4, name4, kind5, name5, kind6, name6, \ + kind7, name7) kind0 name0, kind1 name1, kind2 name2, kind3 name3, \ + kind4 name4, kind5 name5, kind6 name6, kind7 name7 +#define GMOCK_INTERNAL_DECL_HAS_9_TEMPLATE_PARAMS(kind0, name0, kind1, name1, \ + kind2, name2, kind3, name3, kind4, name4, kind5, name5, kind6, name6, \ + kind7, name7, kind8, name8) kind0 name0, kind1 name1, kind2 name2, \ + kind3 name3, kind4 name4, kind5 name5, kind6 name6, kind7 name7, \ + kind8 name8 +#define GMOCK_INTERNAL_DECL_HAS_10_TEMPLATE_PARAMS(kind0, name0, kind1, \ + name1, kind2, name2, kind3, name3, kind4, name4, kind5, name5, kind6, \ + name6, kind7, name7, kind8, name8, kind9, name9) kind0 name0, \ + kind1 name1, kind2 name2, kind3 name3, kind4 name4, kind5 name5, \ + kind6 name6, kind7 name7, kind8 name8, kind9 name9 + +// Lists the template parameters. +#define GMOCK_INTERNAL_LIST_HAS_1_TEMPLATE_PARAMS(kind0, name0) name0 +#define GMOCK_INTERNAL_LIST_HAS_2_TEMPLATE_PARAMS(kind0, name0, kind1, \ + name1) name0, name1 +#define GMOCK_INTERNAL_LIST_HAS_3_TEMPLATE_PARAMS(kind0, name0, kind1, name1, \ + kind2, name2) name0, name1, name2 +#define GMOCK_INTERNAL_LIST_HAS_4_TEMPLATE_PARAMS(kind0, name0, kind1, name1, \ + kind2, name2, kind3, name3) name0, name1, name2, name3 +#define GMOCK_INTERNAL_LIST_HAS_5_TEMPLATE_PARAMS(kind0, name0, kind1, name1, \ + kind2, name2, kind3, name3, kind4, name4) name0, name1, name2, name3, \ + name4 +#define GMOCK_INTERNAL_LIST_HAS_6_TEMPLATE_PARAMS(kind0, name0, kind1, name1, \ + kind2, name2, kind3, name3, kind4, name4, kind5, name5) name0, name1, \ + name2, name3, name4, name5 +#define GMOCK_INTERNAL_LIST_HAS_7_TEMPLATE_PARAMS(kind0, name0, kind1, name1, \ + kind2, name2, kind3, name3, kind4, name4, kind5, name5, kind6, \ + name6) name0, name1, name2, name3, name4, name5, name6 +#define GMOCK_INTERNAL_LIST_HAS_8_TEMPLATE_PARAMS(kind0, name0, kind1, name1, \ + kind2, name2, kind3, name3, kind4, name4, kind5, name5, kind6, name6, \ + kind7, name7) name0, name1, name2, name3, name4, name5, name6, name7 +#define GMOCK_INTERNAL_LIST_HAS_9_TEMPLATE_PARAMS(kind0, name0, kind1, name1, \ + kind2, name2, kind3, name3, kind4, name4, kind5, name5, kind6, name6, \ + kind7, name7, kind8, name8) name0, name1, name2, name3, name4, name5, \ + name6, name7, name8 +#define GMOCK_INTERNAL_LIST_HAS_10_TEMPLATE_PARAMS(kind0, name0, kind1, \ + name1, kind2, name2, kind3, name3, kind4, name4, kind5, name5, kind6, \ + name6, kind7, name7, kind8, name8, kind9, name9) name0, name1, name2, \ + name3, name4, name5, name6, name7, name8, name9 + +// Declares the types of value parameters. +#define GMOCK_INTERNAL_DECL_TYPE_AND_0_VALUE_PARAMS() +#define GMOCK_INTERNAL_DECL_TYPE_AND_1_VALUE_PARAMS(p0) , typename p0##_type +#define GMOCK_INTERNAL_DECL_TYPE_AND_2_VALUE_PARAMS(p0, p1) , \ + typename p0##_type, typename p1##_type +#define GMOCK_INTERNAL_DECL_TYPE_AND_3_VALUE_PARAMS(p0, p1, p2) , \ + typename p0##_type, typename p1##_type, typename p2##_type +#define GMOCK_INTERNAL_DECL_TYPE_AND_4_VALUE_PARAMS(p0, p1, p2, p3) , \ + typename p0##_type, typename p1##_type, typename p2##_type, \ + typename p3##_type +#define GMOCK_INTERNAL_DECL_TYPE_AND_5_VALUE_PARAMS(p0, p1, p2, p3, p4) , \ + typename p0##_type, typename p1##_type, typename p2##_type, \ + typename p3##_type, typename p4##_type +#define GMOCK_INTERNAL_DECL_TYPE_AND_6_VALUE_PARAMS(p0, p1, p2, p3, p4, p5) , \ + typename p0##_type, typename p1##_type, typename p2##_type, \ + typename p3##_type, typename p4##_type, typename p5##_type +#define GMOCK_INTERNAL_DECL_TYPE_AND_7_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, \ + p6) , typename p0##_type, typename p1##_type, typename p2##_type, \ + typename p3##_type, typename p4##_type, typename p5##_type, \ + typename p6##_type +#define GMOCK_INTERNAL_DECL_TYPE_AND_8_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, \ + p6, p7) , typename p0##_type, typename p1##_type, typename p2##_type, \ + typename p3##_type, typename p4##_type, typename p5##_type, \ + typename p6##_type, typename p7##_type +#define GMOCK_INTERNAL_DECL_TYPE_AND_9_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, \ + p6, p7, p8) , typename p0##_type, typename p1##_type, typename p2##_type, \ + typename p3##_type, typename p4##_type, typename p5##_type, \ + typename p6##_type, typename p7##_type, typename p8##_type +#define GMOCK_INTERNAL_DECL_TYPE_AND_10_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, \ + p6, p7, p8, p9) , typename p0##_type, typename p1##_type, \ + typename p2##_type, typename p3##_type, typename p4##_type, \ + typename p5##_type, typename p6##_type, typename p7##_type, \ + typename p8##_type, typename p9##_type + +// Initializes the value parameters. +#define GMOCK_INTERNAL_INIT_AND_0_VALUE_PARAMS()\ + () +#define GMOCK_INTERNAL_INIT_AND_1_VALUE_PARAMS(p0)\ + (p0##_type gmock_p0) : p0(::std::move(gmock_p0)) +#define GMOCK_INTERNAL_INIT_AND_2_VALUE_PARAMS(p0, p1)\ + (p0##_type gmock_p0, p1##_type gmock_p1) : p0(::std::move(gmock_p0)), \ + p1(::std::move(gmock_p1)) +#define GMOCK_INTERNAL_INIT_AND_3_VALUE_PARAMS(p0, p1, p2)\ + (p0##_type gmock_p0, p1##_type gmock_p1, \ + p2##_type gmock_p2) : p0(::std::move(gmock_p0)), \ + p1(::std::move(gmock_p1)), p2(::std::move(gmock_p2)) +#define GMOCK_INTERNAL_INIT_AND_4_VALUE_PARAMS(p0, p1, p2, p3)\ + (p0##_type gmock_p0, p1##_type gmock_p1, p2##_type gmock_p2, \ + p3##_type gmock_p3) : p0(::std::move(gmock_p0)), \ + p1(::std::move(gmock_p1)), p2(::std::move(gmock_p2)), \ + p3(::std::move(gmock_p3)) +#define GMOCK_INTERNAL_INIT_AND_5_VALUE_PARAMS(p0, p1, p2, p3, p4)\ + (p0##_type gmock_p0, p1##_type gmock_p1, p2##_type gmock_p2, \ + p3##_type gmock_p3, p4##_type gmock_p4) : p0(::std::move(gmock_p0)), \ + p1(::std::move(gmock_p1)), p2(::std::move(gmock_p2)), \ + p3(::std::move(gmock_p3)), p4(::std::move(gmock_p4)) +#define GMOCK_INTERNAL_INIT_AND_6_VALUE_PARAMS(p0, p1, p2, p3, p4, p5)\ + (p0##_type gmock_p0, p1##_type gmock_p1, p2##_type gmock_p2, \ + p3##_type gmock_p3, p4##_type gmock_p4, \ + p5##_type gmock_p5) : p0(::std::move(gmock_p0)), \ + p1(::std::move(gmock_p1)), p2(::std::move(gmock_p2)), \ + p3(::std::move(gmock_p3)), p4(::std::move(gmock_p4)), \ + p5(::std::move(gmock_p5)) +#define GMOCK_INTERNAL_INIT_AND_7_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6)\ + (p0##_type gmock_p0, p1##_type gmock_p1, p2##_type gmock_p2, \ + p3##_type gmock_p3, p4##_type gmock_p4, p5##_type gmock_p5, \ + p6##_type gmock_p6) : p0(::std::move(gmock_p0)), \ + p1(::std::move(gmock_p1)), p2(::std::move(gmock_p2)), \ + p3(::std::move(gmock_p3)), p4(::std::move(gmock_p4)), \ + p5(::std::move(gmock_p5)), p6(::std::move(gmock_p6)) +#define GMOCK_INTERNAL_INIT_AND_8_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6, p7)\ + (p0##_type gmock_p0, p1##_type gmock_p1, p2##_type gmock_p2, \ + p3##_type gmock_p3, p4##_type gmock_p4, p5##_type gmock_p5, \ + p6##_type gmock_p6, p7##_type gmock_p7) : p0(::std::move(gmock_p0)), \ + p1(::std::move(gmock_p1)), p2(::std::move(gmock_p2)), \ + p3(::std::move(gmock_p3)), p4(::std::move(gmock_p4)), \ + p5(::std::move(gmock_p5)), p6(::std::move(gmock_p6)), \ + p7(::std::move(gmock_p7)) +#define GMOCK_INTERNAL_INIT_AND_9_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6, \ + p7, p8)\ + (p0##_type gmock_p0, p1##_type gmock_p1, p2##_type gmock_p2, \ + p3##_type gmock_p3, p4##_type gmock_p4, p5##_type gmock_p5, \ + p6##_type gmock_p6, p7##_type gmock_p7, \ + p8##_type gmock_p8) : p0(::std::move(gmock_p0)), \ + p1(::std::move(gmock_p1)), p2(::std::move(gmock_p2)), \ + p3(::std::move(gmock_p3)), p4(::std::move(gmock_p4)), \ + p5(::std::move(gmock_p5)), p6(::std::move(gmock_p6)), \ + p7(::std::move(gmock_p7)), p8(::std::move(gmock_p8)) +#define GMOCK_INTERNAL_INIT_AND_10_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6, \ + p7, p8, p9)\ + (p0##_type gmock_p0, p1##_type gmock_p1, p2##_type gmock_p2, \ + p3##_type gmock_p3, p4##_type gmock_p4, p5##_type gmock_p5, \ + p6##_type gmock_p6, p7##_type gmock_p7, p8##_type gmock_p8, \ + p9##_type gmock_p9) : p0(::std::move(gmock_p0)), \ + p1(::std::move(gmock_p1)), p2(::std::move(gmock_p2)), \ + p3(::std::move(gmock_p3)), p4(::std::move(gmock_p4)), \ + p5(::std::move(gmock_p5)), p6(::std::move(gmock_p6)), \ + p7(::std::move(gmock_p7)), p8(::std::move(gmock_p8)), \ + p9(::std::move(gmock_p9)) + +// Defines the copy constructor +#define GMOCK_INTERNAL_DEFN_COPY_AND_0_VALUE_PARAMS() \ + noexcept {} // Avoid https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82134 +#define GMOCK_INTERNAL_DEFN_COPY_AND_1_VALUE_PARAMS(...) = default; +#define GMOCK_INTERNAL_DEFN_COPY_AND_2_VALUE_PARAMS(...) = default; +#define GMOCK_INTERNAL_DEFN_COPY_AND_3_VALUE_PARAMS(...) = default; +#define GMOCK_INTERNAL_DEFN_COPY_AND_4_VALUE_PARAMS(...) = default; +#define GMOCK_INTERNAL_DEFN_COPY_AND_5_VALUE_PARAMS(...) = default; +#define GMOCK_INTERNAL_DEFN_COPY_AND_6_VALUE_PARAMS(...) = default; +#define GMOCK_INTERNAL_DEFN_COPY_AND_7_VALUE_PARAMS(...) = default; +#define GMOCK_INTERNAL_DEFN_COPY_AND_8_VALUE_PARAMS(...) = default; +#define GMOCK_INTERNAL_DEFN_COPY_AND_9_VALUE_PARAMS(...) = default; +#define GMOCK_INTERNAL_DEFN_COPY_AND_10_VALUE_PARAMS(...) = default; + +// Declares the fields for storing the value parameters. +#define GMOCK_INTERNAL_DEFN_AND_0_VALUE_PARAMS() +#define GMOCK_INTERNAL_DEFN_AND_1_VALUE_PARAMS(p0) p0##_type p0; +#define GMOCK_INTERNAL_DEFN_AND_2_VALUE_PARAMS(p0, p1) p0##_type p0; \ + p1##_type p1; +#define GMOCK_INTERNAL_DEFN_AND_3_VALUE_PARAMS(p0, p1, p2) p0##_type p0; \ + p1##_type p1; p2##_type p2; +#define GMOCK_INTERNAL_DEFN_AND_4_VALUE_PARAMS(p0, p1, p2, p3) p0##_type p0; \ + p1##_type p1; p2##_type p2; p3##_type p3; +#define GMOCK_INTERNAL_DEFN_AND_5_VALUE_PARAMS(p0, p1, p2, p3, \ + p4) p0##_type p0; p1##_type p1; p2##_type p2; p3##_type p3; p4##_type p4; +#define GMOCK_INTERNAL_DEFN_AND_6_VALUE_PARAMS(p0, p1, p2, p3, p4, \ + p5) p0##_type p0; p1##_type p1; p2##_type p2; p3##_type p3; p4##_type p4; \ + p5##_type p5; +#define GMOCK_INTERNAL_DEFN_AND_7_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, \ + p6) p0##_type p0; p1##_type p1; p2##_type p2; p3##_type p3; p4##_type p4; \ + p5##_type p5; p6##_type p6; +#define GMOCK_INTERNAL_DEFN_AND_8_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6, \ + p7) p0##_type p0; p1##_type p1; p2##_type p2; p3##_type p3; p4##_type p4; \ + p5##_type p5; p6##_type p6; p7##_type p7; +#define GMOCK_INTERNAL_DEFN_AND_9_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6, \ + p7, p8) p0##_type p0; p1##_type p1; p2##_type p2; p3##_type p3; \ + p4##_type p4; p5##_type p5; p6##_type p6; p7##_type p7; p8##_type p8; +#define GMOCK_INTERNAL_DEFN_AND_10_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6, \ + p7, p8, p9) p0##_type p0; p1##_type p1; p2##_type p2; p3##_type p3; \ + p4##_type p4; p5##_type p5; p6##_type p6; p7##_type p7; p8##_type p8; \ + p9##_type p9; + +// Lists the value parameters. +#define GMOCK_INTERNAL_LIST_AND_0_VALUE_PARAMS() +#define GMOCK_INTERNAL_LIST_AND_1_VALUE_PARAMS(p0) p0 +#define GMOCK_INTERNAL_LIST_AND_2_VALUE_PARAMS(p0, p1) p0, p1 +#define GMOCK_INTERNAL_LIST_AND_3_VALUE_PARAMS(p0, p1, p2) p0, p1, p2 +#define GMOCK_INTERNAL_LIST_AND_4_VALUE_PARAMS(p0, p1, p2, p3) p0, p1, p2, p3 +#define GMOCK_INTERNAL_LIST_AND_5_VALUE_PARAMS(p0, p1, p2, p3, p4) p0, p1, \ + p2, p3, p4 +#define GMOCK_INTERNAL_LIST_AND_6_VALUE_PARAMS(p0, p1, p2, p3, p4, p5) p0, \ + p1, p2, p3, p4, p5 +#define GMOCK_INTERNAL_LIST_AND_7_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, \ + p6) p0, p1, p2, p3, p4, p5, p6 +#define GMOCK_INTERNAL_LIST_AND_8_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6, \ + p7) p0, p1, p2, p3, p4, p5, p6, p7 +#define GMOCK_INTERNAL_LIST_AND_9_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6, \ + p7, p8) p0, p1, p2, p3, p4, p5, p6, p7, p8 +#define GMOCK_INTERNAL_LIST_AND_10_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6, \ + p7, p8, p9) p0, p1, p2, p3, p4, p5, p6, p7, p8, p9 + +// Lists the value parameter types. +#define GMOCK_INTERNAL_LIST_TYPE_AND_0_VALUE_PARAMS() +#define GMOCK_INTERNAL_LIST_TYPE_AND_1_VALUE_PARAMS(p0) , p0##_type +#define GMOCK_INTERNAL_LIST_TYPE_AND_2_VALUE_PARAMS(p0, p1) , p0##_type, \ + p1##_type +#define GMOCK_INTERNAL_LIST_TYPE_AND_3_VALUE_PARAMS(p0, p1, p2) , p0##_type, \ + p1##_type, p2##_type +#define GMOCK_INTERNAL_LIST_TYPE_AND_4_VALUE_PARAMS(p0, p1, p2, p3) , \ + p0##_type, p1##_type, p2##_type, p3##_type +#define GMOCK_INTERNAL_LIST_TYPE_AND_5_VALUE_PARAMS(p0, p1, p2, p3, p4) , \ + p0##_type, p1##_type, p2##_type, p3##_type, p4##_type +#define GMOCK_INTERNAL_LIST_TYPE_AND_6_VALUE_PARAMS(p0, p1, p2, p3, p4, p5) , \ + p0##_type, p1##_type, p2##_type, p3##_type, p4##_type, p5##_type +#define GMOCK_INTERNAL_LIST_TYPE_AND_7_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, \ + p6) , p0##_type, p1##_type, p2##_type, p3##_type, p4##_type, p5##_type, \ + p6##_type +#define GMOCK_INTERNAL_LIST_TYPE_AND_8_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, \ + p6, p7) , p0##_type, p1##_type, p2##_type, p3##_type, p4##_type, \ + p5##_type, p6##_type, p7##_type +#define GMOCK_INTERNAL_LIST_TYPE_AND_9_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, \ + p6, p7, p8) , p0##_type, p1##_type, p2##_type, p3##_type, p4##_type, \ + p5##_type, p6##_type, p7##_type, p8##_type +#define GMOCK_INTERNAL_LIST_TYPE_AND_10_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, \ + p6, p7, p8, p9) , p0##_type, p1##_type, p2##_type, p3##_type, p4##_type, \ + p5##_type, p6##_type, p7##_type, p8##_type, p9##_type + +// Declares the value parameters. +#define GMOCK_INTERNAL_DECL_AND_0_VALUE_PARAMS() +#define GMOCK_INTERNAL_DECL_AND_1_VALUE_PARAMS(p0) p0##_type p0 +#define GMOCK_INTERNAL_DECL_AND_2_VALUE_PARAMS(p0, p1) p0##_type p0, \ + p1##_type p1 +#define GMOCK_INTERNAL_DECL_AND_3_VALUE_PARAMS(p0, p1, p2) p0##_type p0, \ + p1##_type p1, p2##_type p2 +#define GMOCK_INTERNAL_DECL_AND_4_VALUE_PARAMS(p0, p1, p2, p3) p0##_type p0, \ + p1##_type p1, p2##_type p2, p3##_type p3 +#define GMOCK_INTERNAL_DECL_AND_5_VALUE_PARAMS(p0, p1, p2, p3, \ + p4) p0##_type p0, p1##_type p1, p2##_type p2, p3##_type p3, p4##_type p4 +#define GMOCK_INTERNAL_DECL_AND_6_VALUE_PARAMS(p0, p1, p2, p3, p4, \ + p5) p0##_type p0, p1##_type p1, p2##_type p2, p3##_type p3, p4##_type p4, \ + p5##_type p5 +#define GMOCK_INTERNAL_DECL_AND_7_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, \ + p6) p0##_type p0, p1##_type p1, p2##_type p2, p3##_type p3, p4##_type p4, \ + p5##_type p5, p6##_type p6 +#define GMOCK_INTERNAL_DECL_AND_8_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6, \ + p7) p0##_type p0, p1##_type p1, p2##_type p2, p3##_type p3, p4##_type p4, \ + p5##_type p5, p6##_type p6, p7##_type p7 +#define GMOCK_INTERNAL_DECL_AND_9_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6, \ + p7, p8) p0##_type p0, p1##_type p1, p2##_type p2, p3##_type p3, \ + p4##_type p4, p5##_type p5, p6##_type p6, p7##_type p7, p8##_type p8 +#define GMOCK_INTERNAL_DECL_AND_10_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6, \ + p7, p8, p9) p0##_type p0, p1##_type p1, p2##_type p2, p3##_type p3, \ + p4##_type p4, p5##_type p5, p6##_type p6, p7##_type p7, p8##_type p8, \ + p9##_type p9 + +// The suffix of the class template implementing the action template. +#define GMOCK_INTERNAL_COUNT_AND_0_VALUE_PARAMS() +#define GMOCK_INTERNAL_COUNT_AND_1_VALUE_PARAMS(p0) P +#define GMOCK_INTERNAL_COUNT_AND_2_VALUE_PARAMS(p0, p1) P2 +#define GMOCK_INTERNAL_COUNT_AND_3_VALUE_PARAMS(p0, p1, p2) P3 +#define GMOCK_INTERNAL_COUNT_AND_4_VALUE_PARAMS(p0, p1, p2, p3) P4 +#define GMOCK_INTERNAL_COUNT_AND_5_VALUE_PARAMS(p0, p1, p2, p3, p4) P5 +#define GMOCK_INTERNAL_COUNT_AND_6_VALUE_PARAMS(p0, p1, p2, p3, p4, p5) P6 +#define GMOCK_INTERNAL_COUNT_AND_7_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6) P7 +#define GMOCK_INTERNAL_COUNT_AND_8_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6, \ + p7) P8 +#define GMOCK_INTERNAL_COUNT_AND_9_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6, \ + p7, p8) P9 +#define GMOCK_INTERNAL_COUNT_AND_10_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6, \ + p7, p8, p9) P10 + +// The name of the class template implementing the action template. +#define GMOCK_ACTION_CLASS_(name, value_params)\ + GTEST_CONCAT_TOKEN_(name##Action, GMOCK_INTERNAL_COUNT_##value_params) + +#define ACTION_TEMPLATE(name, template_params, value_params) \ + template <GMOCK_INTERNAL_DECL_##template_params \ + GMOCK_INTERNAL_DECL_TYPE_##value_params> \ + class GMOCK_ACTION_CLASS_(name, value_params) { \ + public: \ + explicit GMOCK_ACTION_CLASS_(name, value_params)( \ + GMOCK_INTERNAL_DECL_##value_params) \ + GMOCK_PP_IF(GMOCK_PP_IS_EMPTY(GMOCK_INTERNAL_COUNT_##value_params), \ + = default; , \ + : impl_(std::make_shared<gmock_Impl>( \ + GMOCK_INTERNAL_LIST_##value_params)) { }) \ + GMOCK_ACTION_CLASS_(name, value_params)( \ + const GMOCK_ACTION_CLASS_(name, value_params)&) \ + GMOCK_INTERNAL_DEFN_COPY_##value_params \ + GMOCK_ACTION_CLASS_(name, value_params)( \ + GMOCK_ACTION_CLASS_(name, value_params)&&) \ + GMOCK_INTERNAL_DEFN_COPY_##value_params \ + template <typename F> \ + operator ::testing::Action<F>() const { \ + return GMOCK_PP_IF( \ + GMOCK_PP_IS_EMPTY(GMOCK_INTERNAL_COUNT_##value_params), \ + (::testing::internal::MakeAction<F, gmock_Impl>()), \ + (::testing::internal::MakeAction<F>(impl_))); \ + } \ + private: \ + class gmock_Impl { \ + public: \ + explicit gmock_Impl GMOCK_INTERNAL_INIT_##value_params {} \ + template <typename function_type, typename return_type, \ + typename args_type, GMOCK_ACTION_TEMPLATE_ARGS_NAMES_> \ + return_type gmock_PerformImpl(GMOCK_ACTION_ARG_TYPES_AND_NAMES_) const; \ + GMOCK_INTERNAL_DEFN_##value_params \ + }; \ + GMOCK_PP_IF(GMOCK_PP_IS_EMPTY(GMOCK_INTERNAL_COUNT_##value_params), \ + , std::shared_ptr<const gmock_Impl> impl_;) \ + }; \ + template <GMOCK_INTERNAL_DECL_##template_params \ + GMOCK_INTERNAL_DECL_TYPE_##value_params> \ + GMOCK_ACTION_CLASS_(name, value_params)< \ + GMOCK_INTERNAL_LIST_##template_params \ + GMOCK_INTERNAL_LIST_TYPE_##value_params> name( \ + GMOCK_INTERNAL_DECL_##value_params) GTEST_MUST_USE_RESULT_; \ + template <GMOCK_INTERNAL_DECL_##template_params \ + GMOCK_INTERNAL_DECL_TYPE_##value_params> \ + inline GMOCK_ACTION_CLASS_(name, value_params)< \ + GMOCK_INTERNAL_LIST_##template_params \ + GMOCK_INTERNAL_LIST_TYPE_##value_params> name( \ + GMOCK_INTERNAL_DECL_##value_params) { \ + return GMOCK_ACTION_CLASS_(name, value_params)< \ + GMOCK_INTERNAL_LIST_##template_params \ + GMOCK_INTERNAL_LIST_TYPE_##value_params>( \ + GMOCK_INTERNAL_LIST_##value_params); \ + } \ + template <GMOCK_INTERNAL_DECL_##template_params \ + GMOCK_INTERNAL_DECL_TYPE_##value_params> \ + template <typename function_type, typename return_type, typename args_type, \ + GMOCK_ACTION_TEMPLATE_ARGS_NAMES_> \ + return_type GMOCK_ACTION_CLASS_(name, value_params)< \ + GMOCK_INTERNAL_LIST_##template_params \ + GMOCK_INTERNAL_LIST_TYPE_##value_params>::gmock_Impl::gmock_PerformImpl( \ + GMOCK_ACTION_ARG_TYPES_AND_NAMES_UNUSED_) const + +namespace testing { + +// The ACTION*() macros trigger warning C4100 (unreferenced formal +// parameter) in MSVC with -W4. Unfortunately they cannot be fixed in +// the macro definition, as the warnings are generated when the macro +// is expanded and macro expansion cannot contain #pragma. Therefore +// we suppress them here. +#ifdef _MSC_VER +# pragma warning(push) +# pragma warning(disable:4100) +#endif + +namespace internal { + +// internal::InvokeArgument - a helper for InvokeArgument action. +// The basic overloads are provided here for generic functors. +// Overloads for other custom-callables are provided in the +// internal/custom/gmock-generated-actions.h header. +template <typename F, typename... Args> +auto InvokeArgument(F f, Args... args) -> decltype(f(args...)) { + return f(args...); +} + +template <std::size_t index, typename... Params> +struct InvokeArgumentAction { + template <typename... Args> + auto operator()(Args&&... args) const -> decltype(internal::InvokeArgument( + std::get<index>(std::forward_as_tuple(std::forward<Args>(args)...)), + std::declval<const Params&>()...)) { + internal::FlatTuple<Args&&...> args_tuple(FlatTupleConstructTag{}, + std::forward<Args>(args)...); + return params.Apply([&](const Params&... unpacked_params) { + auto&& callable = args_tuple.template Get<index>(); + return internal::InvokeArgument( + std::forward<decltype(callable)>(callable), unpacked_params...); + }); + } + + internal::FlatTuple<Params...> params; +}; + +} // namespace internal + +// The InvokeArgument<N>(a1, a2, ..., a_k) action invokes the N-th +// (0-based) argument, which must be a k-ary callable, of the mock +// function, with arguments a1, a2, ..., a_k. +// +// Notes: +// +// 1. The arguments are passed by value by default. If you need to +// pass an argument by reference, wrap it inside std::ref(). For +// example, +// +// InvokeArgument<1>(5, string("Hello"), std::ref(foo)) +// +// passes 5 and string("Hello") by value, and passes foo by +// reference. +// +// 2. If the callable takes an argument by reference but std::ref() is +// not used, it will receive the reference to a copy of the value, +// instead of the original value. For example, when the 0-th +// argument of the mock function takes a const string&, the action +// +// InvokeArgument<0>(string("Hello")) +// +// makes a copy of the temporary string("Hello") object and passes a +// reference of the copy, instead of the original temporary object, +// to the callable. This makes it easy for a user to define an +// InvokeArgument action from temporary values and have it performed +// later. +template <std::size_t index, typename... Params> +internal::InvokeArgumentAction<index, typename std::decay<Params>::type...> +InvokeArgument(Params&&... params) { + return {internal::FlatTuple<typename std::decay<Params>::type...>( + internal::FlatTupleConstructTag{}, std::forward<Params>(params)...)}; +} + +#ifdef _MSC_VER +# pragma warning(pop) +#endif + +} // namespace testing + +#endif // GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_ACTIONS_H_ diff --git a/src/googletest/googlemock/include/gmock/gmock-generated-actions.h.pump b/src/googletest/googlemock/include/gmock/gmock-generated-actions.h.pump new file mode 100644 index 000000000..982caf9c3 --- /dev/null +++ b/src/googletest/googlemock/include/gmock/gmock-generated-actions.h.pump @@ -0,0 +1,390 @@ +$$ -*- mode: c++; -*- +$$ This is a Pump source file. Please use Pump to convert it to +$$ gmock-generated-actions.h. +$$ +$var n = 10 $$ The maximum arity we support. +$$}} This meta comment fixes auto-indentation in editors. +// 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. + + +// Google Mock - a framework for writing C++ mock classes. +// +// This file implements some commonly used variadic actions. + +// GOOGLETEST_CM0002 DO NOT DELETE + +#ifndef GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_ACTIONS_H_ +#define GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_ACTIONS_H_ + +#include <memory> +#include <utility> + +#include "gmock/gmock-actions.h" +#include "gmock/internal/gmock-port.h" + +// Include any custom callback actions added by the local installation. +#include "gmock/internal/custom/gmock-generated-actions.h" + +$range i 0..n +$range k 0..n-1 + +// Sometimes you want to give an action explicit template parameters +// that cannot be inferred from its value parameters. ACTION() and +// ACTION_P*() don't support that. ACTION_TEMPLATE() remedies that +// and can be viewed as an extension to ACTION() and ACTION_P*(). +// +// The syntax: +// +// ACTION_TEMPLATE(ActionName, +// HAS_m_TEMPLATE_PARAMS(kind1, name1, ..., kind_m, name_m), +// AND_n_VALUE_PARAMS(p1, ..., p_n)) { statements; } +// +// defines an action template that takes m explicit template +// parameters and n value parameters. name_i is the name of the i-th +// template parameter, and kind_i specifies whether it's a typename, +// an integral constant, or a template. p_i is the name of the i-th +// value parameter. +// +// Example: +// +// // DuplicateArg<k, T>(output) converts the k-th argument of the mock +// // function to type T and copies it to *output. +// ACTION_TEMPLATE(DuplicateArg, +// HAS_2_TEMPLATE_PARAMS(int, k, typename, T), +// AND_1_VALUE_PARAMS(output)) { +// *output = T(::std::get<k>(args)); +// } +// ... +// int n; +// EXPECT_CALL(mock, Foo(_, _)) +// .WillOnce(DuplicateArg<1, unsigned char>(&n)); +// +// To create an instance of an action template, write: +// +// ActionName<t1, ..., t_m>(v1, ..., v_n) +// +// where the ts are the template arguments and the vs are the value +// arguments. The value argument types are inferred by the compiler. +// If you want to explicitly specify the value argument types, you can +// provide additional template arguments: +// +// ActionName<t1, ..., t_m, u1, ..., u_k>(v1, ..., v_n) +// +// where u_i is the desired type of v_i. +// +// ACTION_TEMPLATE and ACTION/ACTION_P* can be overloaded on the +// number of value parameters, but not on the number of template +// parameters. Without the restriction, the meaning of the following +// is unclear: +// +// OverloadedAction<int, bool>(x); +// +// Are we using a single-template-parameter action where 'bool' refers +// to the type of x, or are we using a two-template-parameter action +// where the compiler is asked to infer the type of x? +// +// Implementation notes: +// +// GMOCK_INTERNAL_*_HAS_m_TEMPLATE_PARAMS and +// GMOCK_INTERNAL_*_AND_n_VALUE_PARAMS are internal macros for +// implementing ACTION_TEMPLATE. The main trick we use is to create +// new macro invocations when expanding a macro. For example, we have +// +// #define ACTION_TEMPLATE(name, template_params, value_params) +// ... GMOCK_INTERNAL_DECL_##template_params ... +// +// which causes ACTION_TEMPLATE(..., HAS_1_TEMPLATE_PARAMS(typename, T), ...) +// to expand to +// +// ... GMOCK_INTERNAL_DECL_HAS_1_TEMPLATE_PARAMS(typename, T) ... +// +// Since GMOCK_INTERNAL_DECL_HAS_1_TEMPLATE_PARAMS is a macro, the +// preprocessor will continue to expand it to +// +// ... typename T ... +// +// This technique conforms to the C++ standard and is portable. It +// allows us to implement action templates using O(N) code, where N is +// the maximum number of template/value parameters supported. Without +// using it, we'd have to devote O(N^2) amount of code to implement all +// combinations of m and n. + +// Declares the template parameters. + +$range j 1..n +$for j [[ +$range m 0..j-1 +#define GMOCK_INTERNAL_DECL_HAS_$j[[]] +_TEMPLATE_PARAMS($for m, [[kind$m, name$m]]) $for m, [[kind$m name$m]] + + +]] + +// Lists the template parameters. + +$for j [[ +$range m 0..j-1 +#define GMOCK_INTERNAL_LIST_HAS_$j[[]] +_TEMPLATE_PARAMS($for m, [[kind$m, name$m]]) $for m, [[name$m]] + + +]] + +// Declares the types of value parameters. + +$for i [[ +$range j 0..i-1 +#define GMOCK_INTERNAL_DECL_TYPE_AND_$i[[]] +_VALUE_PARAMS($for j, [[p$j]]) $for j [[, typename p$j##_type]] + + +]] + +// Initializes the value parameters. + +$for i [[ +$range j 0..i-1 +#define GMOCK_INTERNAL_INIT_AND_$i[[]]_VALUE_PARAMS($for j, [[p$j]])\ + ($for j, [[p$j##_type gmock_p$j]])$if i>0 [[ : ]]$for j, [[p$j(::std::move(gmock_p$j))]] + + +]] + +// Defines the copy constructor + +$for i [[ +#define GMOCK_INTERNAL_DEFN_COPY_AND_$i[[]]_VALUE_PARAMS$if i == 0[[() \ + noexcept {} // Avoid https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82134 +]] $else [[(...) = default;]] + + +]] + +// Declares the fields for storing the value parameters. + +$for i [[ +$range j 0..i-1 +#define GMOCK_INTERNAL_DEFN_AND_$i[[]] +_VALUE_PARAMS($for j, [[p$j]]) $for j [[p$j##_type p$j; ]] + + +]] + +// Lists the value parameters. + +$for i [[ +$range j 0..i-1 +#define GMOCK_INTERNAL_LIST_AND_$i[[]] +_VALUE_PARAMS($for j, [[p$j]]) $for j, [[p$j]] + + +]] + +// Lists the value parameter types. + +$for i [[ +$range j 0..i-1 +#define GMOCK_INTERNAL_LIST_TYPE_AND_$i[[]] +_VALUE_PARAMS($for j, [[p$j]]) $for j [[, p$j##_type]] + + +]] + +// Declares the value parameters. + +$for i [[ +$range j 0..i-1 +#define GMOCK_INTERNAL_DECL_AND_$i[[]]_VALUE_PARAMS($for j, [[p$j]]) [[]] +$for j, [[p$j##_type p$j]] + + +]] + +// The suffix of the class template implementing the action template. +$for i [[ + + +$range j 0..i-1 +#define GMOCK_INTERNAL_COUNT_AND_$i[[]]_VALUE_PARAMS($for j, [[p$j]]) [[]] +$if i==1 [[P]] $elif i>=2 [[P$i]] +]] + + +// The name of the class template implementing the action template. +#define GMOCK_ACTION_CLASS_(name, value_params)\ + GTEST_CONCAT_TOKEN_(name##Action, GMOCK_INTERNAL_COUNT_##value_params) + +$range k 0..n-1 + +#define ACTION_TEMPLATE(name, template_params, value_params) \ + template <GMOCK_INTERNAL_DECL_##template_params \ + GMOCK_INTERNAL_DECL_TYPE_##value_params> \ + class GMOCK_ACTION_CLASS_(name, value_params) { \ + public: \ + explicit GMOCK_ACTION_CLASS_(name, value_params)( \ + GMOCK_INTERNAL_DECL_##value_params) \ + GMOCK_PP_IF(GMOCK_PP_IS_EMPTY(GMOCK_INTERNAL_COUNT_##value_params), \ + = default; , \ + : impl_(std::make_shared<gmock_Impl>( \ + GMOCK_INTERNAL_LIST_##value_params)) { }) \ + GMOCK_ACTION_CLASS_(name, value_params)( \ + const GMOCK_ACTION_CLASS_(name, value_params)&) \ + GMOCK_INTERNAL_DEFN_COPY_##value_params \ + GMOCK_ACTION_CLASS_(name, value_params)( \ + GMOCK_ACTION_CLASS_(name, value_params)&&) \ + GMOCK_INTERNAL_DEFN_COPY_##value_params \ + template <typename F> \ + operator ::testing::Action<F>() const { \ + return GMOCK_PP_IF( \ + GMOCK_PP_IS_EMPTY(GMOCK_INTERNAL_COUNT_##value_params), \ + (::testing::internal::MakeAction<F, gmock_Impl>()), \ + (::testing::internal::MakeAction<F>(impl_))); \ + } \ + private: \ + class gmock_Impl { \ + public: \ + explicit gmock_Impl GMOCK_INTERNAL_INIT_##value_params {} \ + template <typename function_type, typename return_type, \ + typename args_type, GMOCK_ACTION_TEMPLATE_ARGS_NAMES_> \ + return_type gmock_PerformImpl(GMOCK_ACTION_ARG_TYPES_AND_NAMES_) const; \ + GMOCK_INTERNAL_DEFN_##value_params \ + }; \ + GMOCK_PP_IF(GMOCK_PP_IS_EMPTY(GMOCK_INTERNAL_COUNT_##value_params), \ + , std::shared_ptr<const gmock_Impl> impl_;) \ + }; \ + template <GMOCK_INTERNAL_DECL_##template_params \ + GMOCK_INTERNAL_DECL_TYPE_##value_params> \ + GMOCK_ACTION_CLASS_(name, value_params)< \ + GMOCK_INTERNAL_LIST_##template_params \ + GMOCK_INTERNAL_LIST_TYPE_##value_params> name( \ + GMOCK_INTERNAL_DECL_##value_params) GTEST_MUST_USE_RESULT_; \ + template <GMOCK_INTERNAL_DECL_##template_params \ + GMOCK_INTERNAL_DECL_TYPE_##value_params> \ + inline GMOCK_ACTION_CLASS_(name, value_params)< \ + GMOCK_INTERNAL_LIST_##template_params \ + GMOCK_INTERNAL_LIST_TYPE_##value_params> name( \ + GMOCK_INTERNAL_DECL_##value_params) { \ + return GMOCK_ACTION_CLASS_(name, value_params)< \ + GMOCK_INTERNAL_LIST_##template_params \ + GMOCK_INTERNAL_LIST_TYPE_##value_params>( \ + GMOCK_INTERNAL_LIST_##value_params); \ + } \ + template <GMOCK_INTERNAL_DECL_##template_params \ + GMOCK_INTERNAL_DECL_TYPE_##value_params> \ + template <typename function_type, typename return_type, typename args_type, \ + GMOCK_ACTION_TEMPLATE_ARGS_NAMES_> \ + return_type GMOCK_ACTION_CLASS_(name, value_params)< \ + GMOCK_INTERNAL_LIST_##template_params \ + GMOCK_INTERNAL_LIST_TYPE_##value_params>::gmock_Impl::gmock_PerformImpl( \ + GMOCK_ACTION_ARG_TYPES_AND_NAMES_UNUSED_) const + +namespace testing { + +// The ACTION*() macros trigger warning C4100 (unreferenced formal +// parameter) in MSVC with -W4. Unfortunately they cannot be fixed in +// the macro definition, as the warnings are generated when the macro +// is expanded and macro expansion cannot contain #pragma. Therefore +// we suppress them here. +#ifdef _MSC_VER +# pragma warning(push) +# pragma warning(disable:4100) +#endif + +namespace internal { + +// internal::InvokeArgument - a helper for InvokeArgument action. +// The basic overloads are provided here for generic functors. +// Overloads for other custom-callables are provided in the +// internal/custom/gmock-generated-actions.h header. +template <typename F, typename... Args> +auto InvokeArgument(F f, Args... args) -> decltype(f(args...)) { + return f(args...); +} + +template <std::size_t index, typename... Params> +struct InvokeArgumentAction { + template <typename... Args> + auto operator()(Args&&... args) const -> decltype(internal::InvokeArgument( + std::get<index>(std::forward_as_tuple(std::forward<Args>(args)...)), + std::declval<const Params&>()...)) { + internal::FlatTuple<Args&&...> args_tuple(std::forward<Args>(args)...); + return params.Apply([&](const Params&... unpacked_params) { + auto&& callable = args_tuple.template Get<index>(); + return internal::InvokeArgument( + std::forward<decltype(callable)>(callable), unpacked_params...); + }); + } + + internal::FlatTuple<Params...> params; +}; + +} // namespace internal + +// The InvokeArgument<N>(a1, a2, ..., a_k) action invokes the N-th +// (0-based) argument, which must be a k-ary callable, of the mock +// function, with arguments a1, a2, ..., a_k. +// +// Notes: +// +// 1. The arguments are passed by value by default. If you need to +// pass an argument by reference, wrap it inside std::ref(). For +// example, +// +// InvokeArgument<1>(5, string("Hello"), std::ref(foo)) +// +// passes 5 and string("Hello") by value, and passes foo by +// reference. +// +// 2. If the callable takes an argument by reference but std::ref() is +// not used, it will receive the reference to a copy of the value, +// instead of the original value. For example, when the 0-th +// argument of the mock function takes a const string&, the action +// +// InvokeArgument<0>(string("Hello")) +// +// makes a copy of the temporary string("Hello") object and passes a +// reference of the copy, instead of the original temporary object, +// to the callable. This makes it easy for a user to define an +// InvokeArgument action from temporary values and have it performed +// later. +template <std::size_t index, typename... Params> +internal::InvokeArgumentAction<index, typename std::decay<Params>::type...> +InvokeArgument(Params&&... params) { + return {internal::FlatTuple<typename std::decay<Params>::type...>( + std::forward<Params>(params)...)}; +} + +#ifdef _MSC_VER +# pragma warning(pop) +#endif + +} // namespace testing + +#endif // GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_ACTIONS_H_ diff --git a/src/googletest/googlemock/include/gmock/gmock-matchers.h b/src/googletest/googlemock/include/gmock/gmock-matchers.h new file mode 100644 index 000000000..9641ed426 --- /dev/null +++ b/src/googletest/googlemock/include/gmock/gmock-matchers.h @@ -0,0 +1,5394 @@ +// 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. + + +// Google Mock - a framework for writing C++ mock classes. +// +// The MATCHER* family of macros can be used in a namespace scope to +// define custom matchers easily. +// +// Basic Usage +// =========== +// +// The syntax +// +// MATCHER(name, description_string) { statements; } +// +// defines a matcher with the given name that executes the statements, +// which must return a bool to indicate if the match succeeds. Inside +// the statements, you can refer to the value being matched by 'arg', +// and refer to its type by 'arg_type'. +// +// The description string documents what the matcher does, and is used +// to generate the failure message when the match fails. Since a +// MATCHER() is usually defined in a header file shared by multiple +// C++ source files, we require the description to be a C-string +// literal to avoid possible side effects. It can be empty, in which +// case we'll use the sequence of words in the matcher name as the +// description. +// +// For example: +// +// MATCHER(IsEven, "") { return (arg % 2) == 0; } +// +// allows you to write +// +// // Expects mock_foo.Bar(n) to be called where n is even. +// EXPECT_CALL(mock_foo, Bar(IsEven())); +// +// or, +// +// // Verifies that the value of some_expression is even. +// EXPECT_THAT(some_expression, IsEven()); +// +// If the above assertion fails, it will print something like: +// +// Value of: some_expression +// Expected: is even +// Actual: 7 +// +// where the description "is even" is automatically calculated from the +// matcher name IsEven. +// +// Argument Type +// ============= +// +// Note that the type of the value being matched (arg_type) is +// determined by the context in which you use the matcher and is +// supplied to you by the compiler, so you don't need to worry about +// declaring it (nor can you). This allows the matcher to be +// polymorphic. For example, IsEven() can be used to match any type +// where the value of "(arg % 2) == 0" can be implicitly converted to +// a bool. In the "Bar(IsEven())" example above, if method Bar() +// takes an int, 'arg_type' will be int; if it takes an unsigned long, +// 'arg_type' will be unsigned long; and so on. +// +// Parameterizing Matchers +// ======================= +// +// Sometimes you'll want to parameterize the matcher. For that you +// can use another macro: +// +// MATCHER_P(name, param_name, description_string) { statements; } +// +// For example: +// +// MATCHER_P(HasAbsoluteValue, value, "") { return abs(arg) == value; } +// +// will allow you to write: +// +// EXPECT_THAT(Blah("a"), HasAbsoluteValue(n)); +// +// which may lead to this message (assuming n is 10): +// +// Value of: Blah("a") +// Expected: has absolute value 10 +// Actual: -9 +// +// Note that both the matcher description and its parameter are +// printed, making the message human-friendly. +// +// In the matcher definition body, you can write 'foo_type' to +// reference the type of a parameter named 'foo'. For example, in the +// body of MATCHER_P(HasAbsoluteValue, value) above, you can write +// 'value_type' to refer to the type of 'value'. +// +// We also provide MATCHER_P2, MATCHER_P3, ..., up to MATCHER_P$n to +// support multi-parameter matchers. +// +// Describing Parameterized Matchers +// ================================= +// +// The last argument to MATCHER*() is a string-typed expression. The +// expression can reference all of the matcher's parameters and a +// special bool-typed variable named 'negation'. When 'negation' is +// false, the expression should evaluate to the matcher's description; +// otherwise it should evaluate to the description of the negation of +// the matcher. For example, +// +// using testing::PrintToString; +// +// MATCHER_P2(InClosedRange, low, hi, +// std::string(negation ? "is not" : "is") + " in range [" + +// PrintToString(low) + ", " + PrintToString(hi) + "]") { +// return low <= arg && arg <= hi; +// } +// ... +// EXPECT_THAT(3, InClosedRange(4, 6)); +// EXPECT_THAT(3, Not(InClosedRange(2, 4))); +// +// would generate two failures that contain the text: +// +// Expected: is in range [4, 6] +// ... +// Expected: is not in range [2, 4] +// +// If you specify "" as the description, the failure message will +// contain the sequence of words in the matcher name followed by the +// parameter values printed as a tuple. For example, +// +// MATCHER_P2(InClosedRange, low, hi, "") { ... } +// ... +// EXPECT_THAT(3, InClosedRange(4, 6)); +// EXPECT_THAT(3, Not(InClosedRange(2, 4))); +// +// would generate two failures that contain the text: +// +// Expected: in closed range (4, 6) +// ... +// Expected: not (in closed range (2, 4)) +// +// Types of Matcher Parameters +// =========================== +// +// For the purpose of typing, you can view +// +// MATCHER_Pk(Foo, p1, ..., pk, description_string) { ... } +// +// as shorthand for +// +// template <typename p1_type, ..., typename pk_type> +// FooMatcherPk<p1_type, ..., pk_type> +// Foo(p1_type p1, ..., pk_type pk) { ... } +// +// When you write Foo(v1, ..., vk), the compiler infers the types of +// the parameters v1, ..., and vk for you. If you are not happy with +// the result of the type inference, you can specify the types by +// explicitly instantiating the template, as in Foo<long, bool>(5, +// false). As said earlier, you don't get to (or need to) specify +// 'arg_type' as that's determined by the context in which the matcher +// is used. You can assign the result of expression Foo(p1, ..., pk) +// to a variable of type FooMatcherPk<p1_type, ..., pk_type>. This +// can be useful when composing matchers. +// +// While you can instantiate a matcher template with reference types, +// passing the parameters by pointer usually makes your code more +// readable. If, however, you still want to pass a parameter by +// reference, be aware that in the failure message generated by the +// matcher you will see the value of the referenced object but not its +// address. +// +// Explaining Match Results +// ======================== +// +// Sometimes the matcher description alone isn't enough to explain why +// the match has failed or succeeded. For example, when expecting a +// long string, it can be very helpful to also print the diff between +// the expected string and the actual one. To achieve that, you can +// optionally stream additional information to a special variable +// named result_listener, whose type is a pointer to class +// MatchResultListener: +// +// MATCHER_P(EqualsLongString, str, "") { +// if (arg == str) return true; +// +// *result_listener << "the difference: " +/// << DiffStrings(str, arg); +// return false; +// } +// +// Overloading Matchers +// ==================== +// +// You can overload matchers with different numbers of parameters: +// +// MATCHER_P(Blah, a, description_string1) { ... } +// MATCHER_P2(Blah, a, b, description_string2) { ... } +// +// Caveats +// ======= +// +// When defining a new matcher, you should also consider implementing +// MatcherInterface or using MakePolymorphicMatcher(). These +// approaches require more work than the MATCHER* macros, but also +// give you more control on the types of the value being matched and +// the matcher parameters, which may leads to better compiler error +// messages when the matcher is used wrong. They also allow +// overloading matchers based on parameter types (as opposed to just +// based on the number of parameters). +// +// MATCHER*() can only be used in a namespace scope as templates cannot be +// declared inside of a local class. +// +// More Information +// ================ +// +// To learn more about using these macros, please search for 'MATCHER' +// on +// https://github.com/google/googletest/blob/master/googlemock/docs/cook_book.md +// +// This file also implements some commonly used argument matchers. More +// matchers can be defined by the user implementing the +// MatcherInterface<T> interface if necessary. +// +// See googletest/include/gtest/gtest-matchers.h for the definition of class +// Matcher, class MatcherInterface, and others. + +// GOOGLETEST_CM0002 DO NOT DELETE + +#ifndef GMOCK_INCLUDE_GMOCK_GMOCK_MATCHERS_H_ +#define GMOCK_INCLUDE_GMOCK_GMOCK_MATCHERS_H_ + +#include <algorithm> +#include <cmath> +#include <initializer_list> +#include <iterator> +#include <limits> +#include <memory> +#include <ostream> // NOLINT +#include <sstream> +#include <string> +#include <type_traits> +#include <utility> +#include <vector> + +#include "gmock/internal/gmock-internal-utils.h" +#include "gmock/internal/gmock-port.h" +#include "gmock/internal/gmock-pp.h" +#include "gtest/gtest.h" + +// MSVC warning C5046 is new as of VS2017 version 15.8. +#if defined(_MSC_VER) && _MSC_VER >= 1915 +#define GMOCK_MAYBE_5046_ 5046 +#else +#define GMOCK_MAYBE_5046_ +#endif + +GTEST_DISABLE_MSC_WARNINGS_PUSH_( + 4251 GMOCK_MAYBE_5046_ /* class A needs to have dll-interface to be used by + clients of class B */ + /* Symbol involving type with internal linkage not defined */) + +namespace testing { + +// To implement a matcher Foo for type T, define: +// 1. a class FooMatcherImpl that implements the +// MatcherInterface<T> interface, and +// 2. a factory function that creates a Matcher<T> object from a +// FooMatcherImpl*. +// +// The two-level delegation design makes it possible to allow a user +// to write "v" instead of "Eq(v)" where a Matcher is expected, which +// is impossible if we pass matchers by pointers. It also eases +// ownership management as Matcher objects can now be copied like +// plain values. + +// A match result listener that stores the explanation in a string. +class StringMatchResultListener : public MatchResultListener { + public: + StringMatchResultListener() : MatchResultListener(&ss_) {} + + // Returns the explanation accumulated so far. + std::string str() const { return ss_.str(); } + + // Clears the explanation accumulated so far. + void Clear() { ss_.str(""); } + + private: + ::std::stringstream ss_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(StringMatchResultListener); +}; + +// Anything inside the 'internal' namespace IS INTERNAL IMPLEMENTATION +// and MUST NOT BE USED IN USER CODE!!! +namespace internal { + +// The MatcherCastImpl class template is a helper for implementing +// MatcherCast(). We need this helper in order to partially +// specialize the implementation of MatcherCast() (C++ allows +// class/struct templates to be partially specialized, but not +// function templates.). + +// This general version is used when MatcherCast()'s argument is a +// polymorphic matcher (i.e. something that can be converted to a +// Matcher but is not one yet; for example, Eq(value)) or a value (for +// example, "hello"). +template <typename T, typename M> +class MatcherCastImpl { + public: + static Matcher<T> Cast(const M& polymorphic_matcher_or_value) { + // M can be a polymorphic matcher, in which case we want to use + // its conversion operator to create Matcher<T>. Or it can be a value + // that should be passed to the Matcher<T>'s constructor. + // + // We can't call Matcher<T>(polymorphic_matcher_or_value) when M is a + // polymorphic matcher because it'll be ambiguous if T has an implicit + // constructor from M (this usually happens when T has an implicit + // constructor from any type). + // + // It won't work to unconditionally implict_cast + // polymorphic_matcher_or_value to Matcher<T> because it won't trigger + // a user-defined conversion from M to T if one exists (assuming M is + // a value). + return CastImpl(polymorphic_matcher_or_value, + std::is_convertible<M, Matcher<T>>{}, + std::is_convertible<M, T>{}); + } + + private: + template <bool Ignore> + static Matcher<T> CastImpl(const M& polymorphic_matcher_or_value, + std::true_type /* convertible_to_matcher */, + std::integral_constant<bool, Ignore>) { + // M is implicitly convertible to Matcher<T>, which means that either + // M is a polymorphic matcher or Matcher<T> has an implicit constructor + // from M. In both cases using the implicit conversion will produce a + // matcher. + // + // Even if T has an implicit constructor from M, it won't be called because + // creating Matcher<T> would require a chain of two user-defined conversions + // (first to create T from M and then to create Matcher<T> from T). + return polymorphic_matcher_or_value; + } + + // M can't be implicitly converted to Matcher<T>, so M isn't a polymorphic + // matcher. It's a value of a type implicitly convertible to T. Use direct + // initialization to create a matcher. + static Matcher<T> CastImpl(const M& value, + std::false_type /* convertible_to_matcher */, + std::true_type /* convertible_to_T */) { + return Matcher<T>(ImplicitCast_<T>(value)); + } + + // M can't be implicitly converted to either Matcher<T> or T. Attempt to use + // polymorphic matcher Eq(value) in this case. + // + // Note that we first attempt to perform an implicit cast on the value and + // only fall back to the polymorphic Eq() matcher afterwards because the + // latter calls bool operator==(const Lhs& lhs, const Rhs& rhs) in the end + // which might be undefined even when Rhs is implicitly convertible to Lhs + // (e.g. std::pair<const int, int> vs. std::pair<int, int>). + // + // We don't define this method inline as we need the declaration of Eq(). + static Matcher<T> CastImpl(const M& value, + std::false_type /* convertible_to_matcher */, + std::false_type /* convertible_to_T */); +}; + +// This more specialized version is used when MatcherCast()'s argument +// is already a Matcher. This only compiles when type T can be +// statically converted to type U. +template <typename T, typename U> +class MatcherCastImpl<T, Matcher<U> > { + public: + static Matcher<T> Cast(const Matcher<U>& source_matcher) { + return Matcher<T>(new Impl(source_matcher)); + } + + private: + class Impl : public MatcherInterface<T> { + public: + explicit Impl(const Matcher<U>& source_matcher) + : source_matcher_(source_matcher) {} + + // We delegate the matching logic to the source matcher. + bool MatchAndExplain(T x, MatchResultListener* listener) const override { + using FromType = typename std::remove_cv<typename std::remove_pointer< + typename std::remove_reference<T>::type>::type>::type; + using ToType = typename std::remove_cv<typename std::remove_pointer< + typename std::remove_reference<U>::type>::type>::type; + // Do not allow implicitly converting base*/& to derived*/&. + static_assert( + // Do not trigger if only one of them is a pointer. That implies a + // regular conversion and not a down_cast. + (std::is_pointer<typename std::remove_reference<T>::type>::value != + std::is_pointer<typename std::remove_reference<U>::type>::value) || + std::is_same<FromType, ToType>::value || + !std::is_base_of<FromType, ToType>::value, + "Can't implicitly convert from <base> to <derived>"); + + // Do the cast to `U` explicitly if necessary. + // Otherwise, let implicit conversions do the trick. + using CastType = + typename std::conditional<std::is_convertible<T&, const U&>::value, + T&, U>::type; + + return source_matcher_.MatchAndExplain(static_cast<CastType>(x), + listener); + } + + void DescribeTo(::std::ostream* os) const override { + source_matcher_.DescribeTo(os); + } + + void DescribeNegationTo(::std::ostream* os) const override { + source_matcher_.DescribeNegationTo(os); + } + + private: + const Matcher<U> source_matcher_; + }; +}; + +// This even more specialized version is used for efficiently casting +// a matcher to its own type. +template <typename T> +class MatcherCastImpl<T, Matcher<T> > { + public: + static Matcher<T> Cast(const Matcher<T>& matcher) { return matcher; } +}; + +// Template specialization for parameterless Matcher. +template <typename Derived> +class MatcherBaseImpl { + public: + MatcherBaseImpl() = default; + + template <typename T> + operator ::testing::Matcher<T>() const { // NOLINT(runtime/explicit) + return ::testing::Matcher<T>(new + typename Derived::template gmock_Impl<T>()); + } +}; + +// Template specialization for Matcher with parameters. +template <template <typename...> class Derived, typename... Ts> +class MatcherBaseImpl<Derived<Ts...>> { + public: + // Mark the constructor explicit for single argument T to avoid implicit + // conversions. + template <typename E = std::enable_if<sizeof...(Ts) == 1>, + typename E::type* = nullptr> + explicit MatcherBaseImpl(Ts... params) + : params_(std::forward<Ts>(params)...) {} + template <typename E = std::enable_if<sizeof...(Ts) != 1>, + typename = typename E::type> + MatcherBaseImpl(Ts... params) // NOLINT + : params_(std::forward<Ts>(params)...) {} + + template <typename F> + operator ::testing::Matcher<F>() const { // NOLINT(runtime/explicit) + return Apply<F>(MakeIndexSequence<sizeof...(Ts)>{}); + } + + private: + template <typename F, std::size_t... tuple_ids> + ::testing::Matcher<F> Apply(IndexSequence<tuple_ids...>) const { + return ::testing::Matcher<F>( + new typename Derived<Ts...>::template gmock_Impl<F>( + std::get<tuple_ids>(params_)...)); + } + + const std::tuple<Ts...> params_; +}; + +} // namespace internal + +// In order to be safe and clear, casting between different matcher +// types is done explicitly via MatcherCast<T>(m), which takes a +// matcher m and returns a Matcher<T>. It compiles only when T can be +// statically converted to the argument type of m. +template <typename T, typename M> +inline Matcher<T> MatcherCast(const M& matcher) { + return internal::MatcherCastImpl<T, M>::Cast(matcher); +} + +// This overload handles polymorphic matchers and values only since +// monomorphic matchers are handled by the next one. +template <typename T, typename M> +inline Matcher<T> SafeMatcherCast(const M& polymorphic_matcher_or_value) { + return MatcherCast<T>(polymorphic_matcher_or_value); +} + +// This overload handles monomorphic matchers. +// +// In general, if type T can be implicitly converted to type U, we can +// safely convert a Matcher<U> to a Matcher<T> (i.e. Matcher is +// contravariant): just keep a copy of the original Matcher<U>, convert the +// argument from type T to U, and then pass it to the underlying Matcher<U>. +// The only exception is when U is a reference and T is not, as the +// underlying Matcher<U> may be interested in the argument's address, which +// is not preserved in the conversion from T to U. +template <typename T, typename U> +inline Matcher<T> SafeMatcherCast(const Matcher<U>& matcher) { + // Enforce that T can be implicitly converted to U. + static_assert(std::is_convertible<const T&, const U&>::value, + "T must be implicitly convertible to U"); + // Enforce that we are not converting a non-reference type T to a reference + // type U. + GTEST_COMPILE_ASSERT_( + std::is_reference<T>::value || !std::is_reference<U>::value, + cannot_convert_non_reference_arg_to_reference); + // In case both T and U are arithmetic types, enforce that the + // conversion is not lossy. + typedef GTEST_REMOVE_REFERENCE_AND_CONST_(T) RawT; + typedef GTEST_REMOVE_REFERENCE_AND_CONST_(U) RawU; + constexpr bool kTIsOther = GMOCK_KIND_OF_(RawT) == internal::kOther; + constexpr bool kUIsOther = GMOCK_KIND_OF_(RawU) == internal::kOther; + GTEST_COMPILE_ASSERT_( + kTIsOther || kUIsOther || + (internal::LosslessArithmeticConvertible<RawT, RawU>::value), + conversion_of_arithmetic_types_must_be_lossless); + return MatcherCast<T>(matcher); +} + +// A<T>() returns a matcher that matches any value of type T. +template <typename T> +Matcher<T> A(); + +// Anything inside the 'internal' namespace IS INTERNAL IMPLEMENTATION +// and MUST NOT BE USED IN USER CODE!!! +namespace internal { + +// If the explanation is not empty, prints it to the ostream. +inline void PrintIfNotEmpty(const std::string& explanation, + ::std::ostream* os) { + if (explanation != "" && os != nullptr) { + *os << ", " << explanation; + } +} + +// Returns true if the given type name is easy to read by a human. +// This is used to decide whether printing the type of a value might +// be helpful. +inline bool IsReadableTypeName(const std::string& type_name) { + // We consider a type name readable if it's short or doesn't contain + // a template or function type. + return (type_name.length() <= 20 || + type_name.find_first_of("<(") == std::string::npos); +} + +// Matches the value against the given matcher, prints the value and explains +// the match result to the listener. Returns the match result. +// 'listener' must not be NULL. +// Value cannot be passed by const reference, because some matchers take a +// non-const argument. +template <typename Value, typename T> +bool MatchPrintAndExplain(Value& value, const Matcher<T>& matcher, + MatchResultListener* listener) { + if (!listener->IsInterested()) { + // If the listener is not interested, we do not need to construct the + // inner explanation. + return matcher.Matches(value); + } + + StringMatchResultListener inner_listener; + const bool match = matcher.MatchAndExplain(value, &inner_listener); + + UniversalPrint(value, listener->stream()); +#if GTEST_HAS_RTTI + const std::string& type_name = GetTypeName<Value>(); + if (IsReadableTypeName(type_name)) + *listener->stream() << " (of type " << type_name << ")"; +#endif + PrintIfNotEmpty(inner_listener.str(), listener->stream()); + + return match; +} + +// An internal helper class for doing compile-time loop on a tuple's +// fields. +template <size_t N> +class TuplePrefix { + public: + // TuplePrefix<N>::Matches(matcher_tuple, value_tuple) returns true + // if and only if the first N fields of matcher_tuple matches + // the first N fields of value_tuple, respectively. + template <typename MatcherTuple, typename ValueTuple> + static bool Matches(const MatcherTuple& matcher_tuple, + const ValueTuple& value_tuple) { + return TuplePrefix<N - 1>::Matches(matcher_tuple, value_tuple) && + std::get<N - 1>(matcher_tuple).Matches(std::get<N - 1>(value_tuple)); + } + + // TuplePrefix<N>::ExplainMatchFailuresTo(matchers, values, os) + // describes failures in matching the first N fields of matchers + // against the first N fields of values. If there is no failure, + // nothing will be streamed to os. + template <typename MatcherTuple, typename ValueTuple> + static void ExplainMatchFailuresTo(const MatcherTuple& matchers, + const ValueTuple& values, + ::std::ostream* os) { + // First, describes failures in the first N - 1 fields. + TuplePrefix<N - 1>::ExplainMatchFailuresTo(matchers, values, os); + + // Then describes the failure (if any) in the (N - 1)-th (0-based) + // field. + typename std::tuple_element<N - 1, MatcherTuple>::type matcher = + std::get<N - 1>(matchers); + typedef typename std::tuple_element<N - 1, ValueTuple>::type Value; + const Value& value = std::get<N - 1>(values); + StringMatchResultListener listener; + if (!matcher.MatchAndExplain(value, &listener)) { + *os << " Expected arg #" << N - 1 << ": "; + std::get<N - 1>(matchers).DescribeTo(os); + *os << "\n Actual: "; + // We remove the reference in type Value to prevent the + // universal printer from printing the address of value, which + // isn't interesting to the user most of the time. The + // matcher's MatchAndExplain() method handles the case when + // the address is interesting. + internal::UniversalPrint(value, os); + PrintIfNotEmpty(listener.str(), os); + *os << "\n"; + } + } +}; + +// The base case. +template <> +class TuplePrefix<0> { + public: + template <typename MatcherTuple, typename ValueTuple> + static bool Matches(const MatcherTuple& /* matcher_tuple */, + const ValueTuple& /* value_tuple */) { + return true; + } + + template <typename MatcherTuple, typename ValueTuple> + static void ExplainMatchFailuresTo(const MatcherTuple& /* matchers */, + const ValueTuple& /* values */, + ::std::ostream* /* os */) {} +}; + +// TupleMatches(matcher_tuple, value_tuple) returns true if and only if +// all matchers in matcher_tuple match the corresponding fields in +// value_tuple. It is a compiler error if matcher_tuple and +// value_tuple have different number of fields or incompatible field +// types. +template <typename MatcherTuple, typename ValueTuple> +bool TupleMatches(const MatcherTuple& matcher_tuple, + const ValueTuple& value_tuple) { + // Makes sure that matcher_tuple and value_tuple have the same + // number of fields. + GTEST_COMPILE_ASSERT_(std::tuple_size<MatcherTuple>::value == + std::tuple_size<ValueTuple>::value, + matcher_and_value_have_different_numbers_of_fields); + return TuplePrefix<std::tuple_size<ValueTuple>::value>::Matches(matcher_tuple, + value_tuple); +} + +// Describes failures in matching matchers against values. If there +// is no failure, nothing will be streamed to os. +template <typename MatcherTuple, typename ValueTuple> +void ExplainMatchFailureTupleTo(const MatcherTuple& matchers, + const ValueTuple& values, + ::std::ostream* os) { + TuplePrefix<std::tuple_size<MatcherTuple>::value>::ExplainMatchFailuresTo( + matchers, values, os); +} + +// TransformTupleValues and its helper. +// +// TransformTupleValuesHelper hides the internal machinery that +// TransformTupleValues uses to implement a tuple traversal. +template <typename Tuple, typename Func, typename OutIter> +class TransformTupleValuesHelper { + private: + typedef ::std::tuple_size<Tuple> TupleSize; + + public: + // For each member of tuple 't', taken in order, evaluates '*out++ = f(t)'. + // Returns the final value of 'out' in case the caller needs it. + static OutIter Run(Func f, const Tuple& t, OutIter out) { + return IterateOverTuple<Tuple, TupleSize::value>()(f, t, out); + } + + private: + template <typename Tup, size_t kRemainingSize> + struct IterateOverTuple { + OutIter operator() (Func f, const Tup& t, OutIter out) const { + *out++ = f(::std::get<TupleSize::value - kRemainingSize>(t)); + return IterateOverTuple<Tup, kRemainingSize - 1>()(f, t, out); + } + }; + template <typename Tup> + struct IterateOverTuple<Tup, 0> { + OutIter operator() (Func /* f */, const Tup& /* t */, OutIter out) const { + return out; + } + }; +}; + +// Successively invokes 'f(element)' on each element of the tuple 't', +// appending each result to the 'out' iterator. Returns the final value +// of 'out'. +template <typename Tuple, typename Func, typename OutIter> +OutIter TransformTupleValues(Func f, const Tuple& t, OutIter out) { + return TransformTupleValuesHelper<Tuple, Func, OutIter>::Run(f, t, out); +} + +// Implements A<T>(). +template <typename T> +class AnyMatcherImpl : public MatcherInterface<const T&> { + public: + bool MatchAndExplain(const T& /* x */, + MatchResultListener* /* listener */) const override { + return true; + } + void DescribeTo(::std::ostream* os) const override { *os << "is anything"; } + void DescribeNegationTo(::std::ostream* os) const override { + // This is mostly for completeness' safe, as it's not very useful + // to write Not(A<bool>()). However we cannot completely rule out + // such a possibility, and it doesn't hurt to be prepared. + *os << "never matches"; + } +}; + +// Implements _, a matcher that matches any value of any +// type. This is a polymorphic matcher, so we need a template type +// conversion operator to make it appearing as a Matcher<T> for any +// type T. +class AnythingMatcher { + public: + template <typename T> + operator Matcher<T>() const { return A<T>(); } +}; + +// Implements the polymorphic IsNull() matcher, which matches any raw or smart +// pointer that is NULL. +class IsNullMatcher { + public: + template <typename Pointer> + bool MatchAndExplain(const Pointer& p, + MatchResultListener* /* listener */) const { + return p == nullptr; + } + + void DescribeTo(::std::ostream* os) const { *os << "is NULL"; } + void DescribeNegationTo(::std::ostream* os) const { + *os << "isn't NULL"; + } +}; + +// Implements the polymorphic NotNull() matcher, which matches any raw or smart +// pointer that is not NULL. +class NotNullMatcher { + public: + template <typename Pointer> + bool MatchAndExplain(const Pointer& p, + MatchResultListener* /* listener */) const { + return p != nullptr; + } + + void DescribeTo(::std::ostream* os) const { *os << "isn't NULL"; } + void DescribeNegationTo(::std::ostream* os) const { + *os << "is NULL"; + } +}; + +// Ref(variable) matches any argument that is a reference to +// 'variable'. This matcher is polymorphic as it can match any +// super type of the type of 'variable'. +// +// The RefMatcher template class implements Ref(variable). It can +// only be instantiated with a reference type. This prevents a user +// from mistakenly using Ref(x) to match a non-reference function +// argument. For example, the following will righteously cause a +// compiler error: +// +// int n; +// Matcher<int> m1 = Ref(n); // This won't compile. +// Matcher<int&> m2 = Ref(n); // This will compile. +template <typename T> +class RefMatcher; + +template <typename T> +class RefMatcher<T&> { + // Google Mock is a generic framework and thus needs to support + // mocking any function types, including those that take non-const + // reference arguments. Therefore the template parameter T (and + // Super below) can be instantiated to either a const type or a + // non-const type. + public: + // RefMatcher() takes a T& instead of const T&, as we want the + // compiler to catch using Ref(const_value) as a matcher for a + // non-const reference. + explicit RefMatcher(T& x) : object_(x) {} // NOLINT + + template <typename Super> + operator Matcher<Super&>() const { + // By passing object_ (type T&) to Impl(), which expects a Super&, + // we make sure that Super is a super type of T. In particular, + // this catches using Ref(const_value) as a matcher for a + // non-const reference, as you cannot implicitly convert a const + // reference to a non-const reference. + return MakeMatcher(new Impl<Super>(object_)); + } + + private: + template <typename Super> + class Impl : public MatcherInterface<Super&> { + public: + explicit Impl(Super& x) : object_(x) {} // NOLINT + + // MatchAndExplain() takes a Super& (as opposed to const Super&) + // in order to match the interface MatcherInterface<Super&>. + bool MatchAndExplain(Super& x, + MatchResultListener* listener) const override { + *listener << "which is located @" << static_cast<const void*>(&x); + return &x == &object_; + } + + void DescribeTo(::std::ostream* os) const override { + *os << "references the variable "; + UniversalPrinter<Super&>::Print(object_, os); + } + + void DescribeNegationTo(::std::ostream* os) const override { + *os << "does not reference the variable "; + UniversalPrinter<Super&>::Print(object_, os); + } + + private: + const Super& object_; + }; + + T& object_; +}; + +// Polymorphic helper functions for narrow and wide string matchers. +inline bool CaseInsensitiveCStringEquals(const char* lhs, const char* rhs) { + return String::CaseInsensitiveCStringEquals(lhs, rhs); +} + +inline bool CaseInsensitiveCStringEquals(const wchar_t* lhs, + const wchar_t* rhs) { + return String::CaseInsensitiveWideCStringEquals(lhs, rhs); +} + +// String comparison for narrow or wide strings that can have embedded NUL +// characters. +template <typename StringType> +bool CaseInsensitiveStringEquals(const StringType& s1, + const StringType& s2) { + // Are the heads equal? + if (!CaseInsensitiveCStringEquals(s1.c_str(), s2.c_str())) { + return false; + } + + // Skip the equal heads. + const typename StringType::value_type nul = 0; + const size_t i1 = s1.find(nul), i2 = s2.find(nul); + + // Are we at the end of either s1 or s2? + if (i1 == StringType::npos || i2 == StringType::npos) { + return i1 == i2; + } + + // Are the tails equal? + return CaseInsensitiveStringEquals(s1.substr(i1 + 1), s2.substr(i2 + 1)); +} + +// String matchers. + +// Implements equality-based string matchers like StrEq, StrCaseNe, and etc. +template <typename StringType> +class StrEqualityMatcher { + public: + StrEqualityMatcher(StringType str, bool expect_eq, bool case_sensitive) + : string_(std::move(str)), + expect_eq_(expect_eq), + case_sensitive_(case_sensitive) {} + +#if GTEST_INTERNAL_HAS_STRING_VIEW + bool MatchAndExplain(const internal::StringView& s, + MatchResultListener* listener) const { + // This should fail to compile if StringView is used with wide + // strings. + const StringType& str = std::string(s); + return MatchAndExplain(str, listener); + } +#endif // GTEST_INTERNAL_HAS_STRING_VIEW + + // Accepts pointer types, particularly: + // const char* + // char* + // const wchar_t* + // wchar_t* + template <typename CharType> + bool MatchAndExplain(CharType* s, MatchResultListener* listener) const { + if (s == nullptr) { + return !expect_eq_; + } + return MatchAndExplain(StringType(s), listener); + } + + // Matches anything that can convert to StringType. + // + // This is a template, not just a plain function with const StringType&, + // because StringView has some interfering non-explicit constructors. + template <typename MatcheeStringType> + bool MatchAndExplain(const MatcheeStringType& s, + MatchResultListener* /* listener */) const { + const StringType s2(s); + const bool eq = case_sensitive_ ? s2 == string_ : + CaseInsensitiveStringEquals(s2, string_); + return expect_eq_ == eq; + } + + void DescribeTo(::std::ostream* os) const { + DescribeToHelper(expect_eq_, os); + } + + void DescribeNegationTo(::std::ostream* os) const { + DescribeToHelper(!expect_eq_, os); + } + + private: + void DescribeToHelper(bool expect_eq, ::std::ostream* os) const { + *os << (expect_eq ? "is " : "isn't "); + *os << "equal to "; + if (!case_sensitive_) { + *os << "(ignoring case) "; + } + UniversalPrint(string_, os); + } + + const StringType string_; + const bool expect_eq_; + const bool case_sensitive_; +}; + +// Implements the polymorphic HasSubstr(substring) matcher, which +// can be used as a Matcher<T> as long as T can be converted to a +// string. +template <typename StringType> +class HasSubstrMatcher { + public: + explicit HasSubstrMatcher(const StringType& substring) + : substring_(substring) {} + +#if GTEST_INTERNAL_HAS_STRING_VIEW + bool MatchAndExplain(const internal::StringView& s, + MatchResultListener* listener) const { + // This should fail to compile if StringView is used with wide + // strings. + const StringType& str = std::string(s); + return MatchAndExplain(str, listener); + } +#endif // GTEST_INTERNAL_HAS_STRING_VIEW + + // Accepts pointer types, particularly: + // const char* + // char* + // const wchar_t* + // wchar_t* + template <typename CharType> + bool MatchAndExplain(CharType* s, MatchResultListener* listener) const { + return s != nullptr && MatchAndExplain(StringType(s), listener); + } + + // Matches anything that can convert to StringType. + // + // This is a template, not just a plain function with const StringType&, + // because StringView has some interfering non-explicit constructors. + template <typename MatcheeStringType> + bool MatchAndExplain(const MatcheeStringType& s, + MatchResultListener* /* listener */) const { + return StringType(s).find(substring_) != StringType::npos; + } + + // Describes what this matcher matches. + void DescribeTo(::std::ostream* os) const { + *os << "has substring "; + UniversalPrint(substring_, os); + } + + void DescribeNegationTo(::std::ostream* os) const { + *os << "has no substring "; + UniversalPrint(substring_, os); + } + + private: + const StringType substring_; +}; + +// Implements the polymorphic StartsWith(substring) matcher, which +// can be used as a Matcher<T> as long as T can be converted to a +// string. +template <typename StringType> +class StartsWithMatcher { + public: + explicit StartsWithMatcher(const StringType& prefix) : prefix_(prefix) { + } + +#if GTEST_INTERNAL_HAS_STRING_VIEW + bool MatchAndExplain(const internal::StringView& s, + MatchResultListener* listener) const { + // This should fail to compile if StringView is used with wide + // strings. + const StringType& str = std::string(s); + return MatchAndExplain(str, listener); + } +#endif // GTEST_INTERNAL_HAS_STRING_VIEW + + // Accepts pointer types, particularly: + // const char* + // char* + // const wchar_t* + // wchar_t* + template <typename CharType> + bool MatchAndExplain(CharType* s, MatchResultListener* listener) const { + return s != nullptr && MatchAndExplain(StringType(s), listener); + } + + // Matches anything that can convert to StringType. + // + // This is a template, not just a plain function with const StringType&, + // because StringView has some interfering non-explicit constructors. + template <typename MatcheeStringType> + bool MatchAndExplain(const MatcheeStringType& s, + MatchResultListener* /* listener */) const { + const StringType& s2(s); + return s2.length() >= prefix_.length() && + s2.substr(0, prefix_.length()) == prefix_; + } + + void DescribeTo(::std::ostream* os) const { + *os << "starts with "; + UniversalPrint(prefix_, os); + } + + void DescribeNegationTo(::std::ostream* os) const { + *os << "doesn't start with "; + UniversalPrint(prefix_, os); + } + + private: + const StringType prefix_; +}; + +// Implements the polymorphic EndsWith(substring) matcher, which +// can be used as a Matcher<T> as long as T can be converted to a +// string. +template <typename StringType> +class EndsWithMatcher { + public: + explicit EndsWithMatcher(const StringType& suffix) : suffix_(suffix) {} + +#if GTEST_INTERNAL_HAS_STRING_VIEW + bool MatchAndExplain(const internal::StringView& s, + MatchResultListener* listener) const { + // This should fail to compile if StringView is used with wide + // strings. + const StringType& str = std::string(s); + return MatchAndExplain(str, listener); + } +#endif // GTEST_INTERNAL_HAS_STRING_VIEW + + // Accepts pointer types, particularly: + // const char* + // char* + // const wchar_t* + // wchar_t* + template <typename CharType> + bool MatchAndExplain(CharType* s, MatchResultListener* listener) const { + return s != nullptr && MatchAndExplain(StringType(s), listener); + } + + // Matches anything that can convert to StringType. + // + // This is a template, not just a plain function with const StringType&, + // because StringView has some interfering non-explicit constructors. + template <typename MatcheeStringType> + bool MatchAndExplain(const MatcheeStringType& s, + MatchResultListener* /* listener */) const { + const StringType& s2(s); + return s2.length() >= suffix_.length() && + s2.substr(s2.length() - suffix_.length()) == suffix_; + } + + void DescribeTo(::std::ostream* os) const { + *os << "ends with "; + UniversalPrint(suffix_, os); + } + + void DescribeNegationTo(::std::ostream* os) const { + *os << "doesn't end with "; + UniversalPrint(suffix_, os); + } + + private: + const StringType suffix_; +}; + +// Implements a matcher that compares the two fields of a 2-tuple +// using one of the ==, <=, <, etc, operators. The two fields being +// compared don't have to have the same type. +// +// The matcher defined here is polymorphic (for example, Eq() can be +// used to match a std::tuple<int, short>, a std::tuple<const long&, double>, +// etc). Therefore we use a template type conversion operator in the +// implementation. +template <typename D, typename Op> +class PairMatchBase { + public: + template <typename T1, typename T2> + operator Matcher<::std::tuple<T1, T2>>() const { + return Matcher<::std::tuple<T1, T2>>(new Impl<const ::std::tuple<T1, T2>&>); + } + template <typename T1, typename T2> + operator Matcher<const ::std::tuple<T1, T2>&>() const { + return MakeMatcher(new Impl<const ::std::tuple<T1, T2>&>); + } + + private: + static ::std::ostream& GetDesc(::std::ostream& os) { // NOLINT + return os << D::Desc(); + } + + template <typename Tuple> + class Impl : public MatcherInterface<Tuple> { + public: + bool MatchAndExplain(Tuple args, + MatchResultListener* /* listener */) const override { + return Op()(::std::get<0>(args), ::std::get<1>(args)); + } + void DescribeTo(::std::ostream* os) const override { + *os << "are " << GetDesc; + } + void DescribeNegationTo(::std::ostream* os) const override { + *os << "aren't " << GetDesc; + } + }; +}; + +class Eq2Matcher : public PairMatchBase<Eq2Matcher, AnyEq> { + public: + static const char* Desc() { return "an equal pair"; } +}; +class Ne2Matcher : public PairMatchBase<Ne2Matcher, AnyNe> { + public: + static const char* Desc() { return "an unequal pair"; } +}; +class Lt2Matcher : public PairMatchBase<Lt2Matcher, AnyLt> { + public: + static const char* Desc() { return "a pair where the first < the second"; } +}; +class Gt2Matcher : public PairMatchBase<Gt2Matcher, AnyGt> { + public: + static const char* Desc() { return "a pair where the first > the second"; } +}; +class Le2Matcher : public PairMatchBase<Le2Matcher, AnyLe> { + public: + static const char* Desc() { return "a pair where the first <= the second"; } +}; +class Ge2Matcher : public PairMatchBase<Ge2Matcher, AnyGe> { + public: + static const char* Desc() { return "a pair where the first >= the second"; } +}; + +// Implements the Not(...) matcher for a particular argument type T. +// We do not nest it inside the NotMatcher class template, as that +// will prevent different instantiations of NotMatcher from sharing +// the same NotMatcherImpl<T> class. +template <typename T> +class NotMatcherImpl : public MatcherInterface<const T&> { + public: + explicit NotMatcherImpl(const Matcher<T>& matcher) + : matcher_(matcher) {} + + bool MatchAndExplain(const T& x, + MatchResultListener* listener) const override { + return !matcher_.MatchAndExplain(x, listener); + } + + void DescribeTo(::std::ostream* os) const override { + matcher_.DescribeNegationTo(os); + } + + void DescribeNegationTo(::std::ostream* os) const override { + matcher_.DescribeTo(os); + } + + private: + const Matcher<T> matcher_; +}; + +// Implements the Not(m) matcher, which matches a value that doesn't +// match matcher m. +template <typename InnerMatcher> +class NotMatcher { + public: + explicit NotMatcher(InnerMatcher matcher) : matcher_(matcher) {} + + // This template type conversion operator allows Not(m) to be used + // to match any type m can match. + template <typename T> + operator Matcher<T>() const { + return Matcher<T>(new NotMatcherImpl<T>(SafeMatcherCast<T>(matcher_))); + } + + private: + InnerMatcher matcher_; +}; + +// Implements the AllOf(m1, m2) matcher for a particular argument type +// T. We do not nest it inside the BothOfMatcher class template, as +// that will prevent different instantiations of BothOfMatcher from +// sharing the same BothOfMatcherImpl<T> class. +template <typename T> +class AllOfMatcherImpl : public MatcherInterface<const T&> { + public: + explicit AllOfMatcherImpl(std::vector<Matcher<T> > matchers) + : matchers_(std::move(matchers)) {} + + void DescribeTo(::std::ostream* os) const override { + *os << "("; + for (size_t i = 0; i < matchers_.size(); ++i) { + if (i != 0) *os << ") and ("; + matchers_[i].DescribeTo(os); + } + *os << ")"; + } + + void DescribeNegationTo(::std::ostream* os) const override { + *os << "("; + for (size_t i = 0; i < matchers_.size(); ++i) { + if (i != 0) *os << ") or ("; + matchers_[i].DescribeNegationTo(os); + } + *os << ")"; + } + + bool MatchAndExplain(const T& x, + MatchResultListener* listener) const override { + // If either matcher1_ or matcher2_ doesn't match x, we only need + // to explain why one of them fails. + std::string all_match_result; + + for (size_t i = 0; i < matchers_.size(); ++i) { + StringMatchResultListener slistener; + if (matchers_[i].MatchAndExplain(x, &slistener)) { + if (all_match_result.empty()) { + all_match_result = slistener.str(); + } else { + std::string result = slistener.str(); + if (!result.empty()) { + all_match_result += ", and "; + all_match_result += result; + } + } + } else { + *listener << slistener.str(); + return false; + } + } + + // Otherwise we need to explain why *both* of them match. + *listener << all_match_result; + return true; + } + + private: + const std::vector<Matcher<T> > matchers_; +}; + +// VariadicMatcher is used for the variadic implementation of +// AllOf(m_1, m_2, ...) and AnyOf(m_1, m_2, ...). +// CombiningMatcher<T> is used to recursively combine the provided matchers +// (of type Args...). +template <template <typename T> class CombiningMatcher, typename... Args> +class VariadicMatcher { + public: + VariadicMatcher(const Args&... matchers) // NOLINT + : matchers_(matchers...) { + static_assert(sizeof...(Args) > 0, "Must have at least one matcher."); + } + + VariadicMatcher(const VariadicMatcher&) = default; + VariadicMatcher& operator=(const VariadicMatcher&) = delete; + + // This template type conversion operator allows an + // VariadicMatcher<Matcher1, Matcher2...> object to match any type that + // all of the provided matchers (Matcher1, Matcher2, ...) can match. + template <typename T> + operator Matcher<T>() const { + std::vector<Matcher<T> > values; + CreateVariadicMatcher<T>(&values, std::integral_constant<size_t, 0>()); + return Matcher<T>(new CombiningMatcher<T>(std::move(values))); + } + + private: + template <typename T, size_t I> + void CreateVariadicMatcher(std::vector<Matcher<T> >* values, + std::integral_constant<size_t, I>) const { + values->push_back(SafeMatcherCast<T>(std::get<I>(matchers_))); + CreateVariadicMatcher<T>(values, std::integral_constant<size_t, I + 1>()); + } + + template <typename T> + void CreateVariadicMatcher( + std::vector<Matcher<T> >*, + std::integral_constant<size_t, sizeof...(Args)>) const {} + + std::tuple<Args...> matchers_; +}; + +template <typename... Args> +using AllOfMatcher = VariadicMatcher<AllOfMatcherImpl, Args...>; + +// Implements the AnyOf(m1, m2) matcher for a particular argument type +// T. We do not nest it inside the AnyOfMatcher class template, as +// that will prevent different instantiations of AnyOfMatcher from +// sharing the same EitherOfMatcherImpl<T> class. +template <typename T> +class AnyOfMatcherImpl : public MatcherInterface<const T&> { + public: + explicit AnyOfMatcherImpl(std::vector<Matcher<T> > matchers) + : matchers_(std::move(matchers)) {} + + void DescribeTo(::std::ostream* os) const override { + *os << "("; + for (size_t i = 0; i < matchers_.size(); ++i) { + if (i != 0) *os << ") or ("; + matchers_[i].DescribeTo(os); + } + *os << ")"; + } + + void DescribeNegationTo(::std::ostream* os) const override { + *os << "("; + for (size_t i = 0; i < matchers_.size(); ++i) { + if (i != 0) *os << ") and ("; + matchers_[i].DescribeNegationTo(os); + } + *os << ")"; + } + + bool MatchAndExplain(const T& x, + MatchResultListener* listener) const override { + std::string no_match_result; + + // If either matcher1_ or matcher2_ matches x, we just need to + // explain why *one* of them matches. + for (size_t i = 0; i < matchers_.size(); ++i) { + StringMatchResultListener slistener; + if (matchers_[i].MatchAndExplain(x, &slistener)) { + *listener << slistener.str(); + return true; + } else { + if (no_match_result.empty()) { + no_match_result = slistener.str(); + } else { + std::string result = slistener.str(); + if (!result.empty()) { + no_match_result += ", and "; + no_match_result += result; + } + } + } + } + + // Otherwise we need to explain why *both* of them fail. + *listener << no_match_result; + return false; + } + + private: + const std::vector<Matcher<T> > matchers_; +}; + +// AnyOfMatcher is used for the variadic implementation of AnyOf(m_1, m_2, ...). +template <typename... Args> +using AnyOfMatcher = VariadicMatcher<AnyOfMatcherImpl, Args...>; + +// Wrapper for implementation of Any/AllOfArray(). +template <template <class> class MatcherImpl, typename T> +class SomeOfArrayMatcher { + public: + // Constructs the matcher from a sequence of element values or + // element matchers. + template <typename Iter> + SomeOfArrayMatcher(Iter first, Iter last) : matchers_(first, last) {} + + template <typename U> + operator Matcher<U>() const { // NOLINT + using RawU = typename std::decay<U>::type; + std::vector<Matcher<RawU>> matchers; + for (const auto& matcher : matchers_) { + matchers.push_back(MatcherCast<RawU>(matcher)); + } + return Matcher<U>(new MatcherImpl<RawU>(std::move(matchers))); + } + + private: + const ::std::vector<T> matchers_; +}; + +template <typename T> +using AllOfArrayMatcher = SomeOfArrayMatcher<AllOfMatcherImpl, T>; + +template <typename T> +using AnyOfArrayMatcher = SomeOfArrayMatcher<AnyOfMatcherImpl, T>; + +// Used for implementing Truly(pred), which turns a predicate into a +// matcher. +template <typename Predicate> +class TrulyMatcher { + public: + explicit TrulyMatcher(Predicate pred) : predicate_(pred) {} + + // This method template allows Truly(pred) to be used as a matcher + // for type T where T is the argument type of predicate 'pred'. The + // argument is passed by reference as the predicate may be + // interested in the address of the argument. + template <typename T> + bool MatchAndExplain(T& x, // NOLINT + MatchResultListener* listener) const { + // Without the if-statement, MSVC sometimes warns about converting + // a value to bool (warning 4800). + // + // We cannot write 'return !!predicate_(x);' as that doesn't work + // when predicate_(x) returns a class convertible to bool but + // having no operator!(). + if (predicate_(x)) + return true; + *listener << "didn't satisfy the given predicate"; + return false; + } + + void DescribeTo(::std::ostream* os) const { + *os << "satisfies the given predicate"; + } + + void DescribeNegationTo(::std::ostream* os) const { + *os << "doesn't satisfy the given predicate"; + } + + private: + Predicate predicate_; +}; + +// Used for implementing Matches(matcher), which turns a matcher into +// a predicate. +template <typename M> +class MatcherAsPredicate { + public: + explicit MatcherAsPredicate(M matcher) : matcher_(matcher) {} + + // This template operator() allows Matches(m) to be used as a + // predicate on type T where m is a matcher on type T. + // + // The argument x is passed by reference instead of by value, as + // some matcher may be interested in its address (e.g. as in + // Matches(Ref(n))(x)). + template <typename T> + bool operator()(const T& x) const { + // We let matcher_ commit to a particular type here instead of + // when the MatcherAsPredicate object was constructed. This + // allows us to write Matches(m) where m is a polymorphic matcher + // (e.g. Eq(5)). + // + // If we write Matcher<T>(matcher_).Matches(x) here, it won't + // compile when matcher_ has type Matcher<const T&>; if we write + // Matcher<const T&>(matcher_).Matches(x) here, it won't compile + // when matcher_ has type Matcher<T>; if we just write + // matcher_.Matches(x), it won't compile when matcher_ is + // polymorphic, e.g. Eq(5). + // + // MatcherCast<const T&>() is necessary for making the code work + // in all of the above situations. + return MatcherCast<const T&>(matcher_).Matches(x); + } + + private: + M matcher_; +}; + +// For implementing ASSERT_THAT() and EXPECT_THAT(). The template +// argument M must be a type that can be converted to a matcher. +template <typename M> +class PredicateFormatterFromMatcher { + public: + explicit PredicateFormatterFromMatcher(M m) : matcher_(std::move(m)) {} + + // This template () operator allows a PredicateFormatterFromMatcher + // object to act as a predicate-formatter suitable for using with + // Google Test's EXPECT_PRED_FORMAT1() macro. + template <typename T> + AssertionResult operator()(const char* value_text, const T& x) const { + // We convert matcher_ to a Matcher<const T&> *now* instead of + // when the PredicateFormatterFromMatcher object was constructed, + // as matcher_ may be polymorphic (e.g. NotNull()) and we won't + // know which type to instantiate it to until we actually see the + // type of x here. + // + // We write SafeMatcherCast<const T&>(matcher_) instead of + // Matcher<const T&>(matcher_), as the latter won't compile when + // matcher_ has type Matcher<T> (e.g. An<int>()). + // We don't write MatcherCast<const T&> either, as that allows + // potentially unsafe downcasting of the matcher argument. + const Matcher<const T&> matcher = SafeMatcherCast<const T&>(matcher_); + + // The expected path here is that the matcher should match (i.e. that most + // tests pass) so optimize for this case. + if (matcher.Matches(x)) { + return AssertionSuccess(); + } + + ::std::stringstream ss; + ss << "Value of: " << value_text << "\n" + << "Expected: "; + matcher.DescribeTo(&ss); + + // Rerun the matcher to "PrintAndExplain" the failure. + StringMatchResultListener listener; + if (MatchPrintAndExplain(x, matcher, &listener)) { + ss << "\n The matcher failed on the initial attempt; but passed when " + "rerun to generate the explanation."; + } + ss << "\n Actual: " << listener.str(); + return AssertionFailure() << ss.str(); + } + + private: + const M matcher_; +}; + +// A helper function for converting a matcher to a predicate-formatter +// without the user needing to explicitly write the type. This is +// used for implementing ASSERT_THAT() and EXPECT_THAT(). +// Implementation detail: 'matcher' is received by-value to force decaying. +template <typename M> +inline PredicateFormatterFromMatcher<M> +MakePredicateFormatterFromMatcher(M matcher) { + return PredicateFormatterFromMatcher<M>(std::move(matcher)); +} + +// Implements the polymorphic IsNan() matcher, which matches any floating type +// value that is Nan. +class IsNanMatcher { + public: + template <typename FloatType> + bool MatchAndExplain(const FloatType& f, + MatchResultListener* /* listener */) const { + return (::std::isnan)(f); + } + + void DescribeTo(::std::ostream* os) const { *os << "is NaN"; } + void DescribeNegationTo(::std::ostream* os) const { + *os << "isn't NaN"; + } +}; + +// Implements the polymorphic floating point equality matcher, which matches +// two float values using ULP-based approximation or, optionally, a +// user-specified epsilon. The template is meant to be instantiated with +// FloatType being either float or double. +template <typename FloatType> +class FloatingEqMatcher { + public: + // Constructor for FloatingEqMatcher. + // The matcher's input will be compared with expected. The matcher treats two + // NANs as equal if nan_eq_nan is true. Otherwise, under IEEE standards, + // equality comparisons between NANs will always return false. We specify a + // negative max_abs_error_ term to indicate that ULP-based approximation will + // be used for comparison. + FloatingEqMatcher(FloatType expected, bool nan_eq_nan) : + expected_(expected), nan_eq_nan_(nan_eq_nan), max_abs_error_(-1) { + } + + // Constructor that supports a user-specified max_abs_error that will be used + // for comparison instead of ULP-based approximation. The max absolute + // should be non-negative. + FloatingEqMatcher(FloatType expected, bool nan_eq_nan, + FloatType max_abs_error) + : expected_(expected), + nan_eq_nan_(nan_eq_nan), + max_abs_error_(max_abs_error) { + GTEST_CHECK_(max_abs_error >= 0) + << ", where max_abs_error is" << max_abs_error; + } + + // Implements floating point equality matcher as a Matcher<T>. + template <typename T> + class Impl : public MatcherInterface<T> { + public: + Impl(FloatType expected, bool nan_eq_nan, FloatType max_abs_error) + : expected_(expected), + nan_eq_nan_(nan_eq_nan), + max_abs_error_(max_abs_error) {} + + bool MatchAndExplain(T value, + MatchResultListener* listener) const override { + const FloatingPoint<FloatType> actual(value), expected(expected_); + + // Compares NaNs first, if nan_eq_nan_ is true. + if (actual.is_nan() || expected.is_nan()) { + if (actual.is_nan() && expected.is_nan()) { + return nan_eq_nan_; + } + // One is nan; the other is not nan. + return false; + } + if (HasMaxAbsError()) { + // We perform an equality check so that inf will match inf, regardless + // of error bounds. If the result of value - expected_ would result in + // overflow or if either value is inf, the default result is infinity, + // which should only match if max_abs_error_ is also infinity. + if (value == expected_) { + return true; + } + + const FloatType diff = value - expected_; + if (::std::fabs(diff) <= max_abs_error_) { + return true; + } + + if (listener->IsInterested()) { + *listener << "which is " << diff << " from " << expected_; + } + return false; + } else { + return actual.AlmostEquals(expected); + } + } + + void DescribeTo(::std::ostream* os) const override { + // os->precision() returns the previously set precision, which we + // store to restore the ostream to its original configuration + // after outputting. + const ::std::streamsize old_precision = os->precision( + ::std::numeric_limits<FloatType>::digits10 + 2); + if (FloatingPoint<FloatType>(expected_).is_nan()) { + if (nan_eq_nan_) { + *os << "is NaN"; + } else { + *os << "never matches"; + } + } else { + *os << "is approximately " << expected_; + if (HasMaxAbsError()) { + *os << " (absolute error <= " << max_abs_error_ << ")"; + } + } + os->precision(old_precision); + } + + void DescribeNegationTo(::std::ostream* os) const override { + // As before, get original precision. + const ::std::streamsize old_precision = os->precision( + ::std::numeric_limits<FloatType>::digits10 + 2); + if (FloatingPoint<FloatType>(expected_).is_nan()) { + if (nan_eq_nan_) { + *os << "isn't NaN"; + } else { + *os << "is anything"; + } + } else { + *os << "isn't approximately " << expected_; + if (HasMaxAbsError()) { + *os << " (absolute error > " << max_abs_error_ << ")"; + } + } + // Restore original precision. + os->precision(old_precision); + } + + private: + bool HasMaxAbsError() const { + return max_abs_error_ >= 0; + } + + const FloatType expected_; + const bool nan_eq_nan_; + // max_abs_error will be used for value comparison when >= 0. + const FloatType max_abs_error_; + }; + + // The following 3 type conversion operators allow FloatEq(expected) and + // NanSensitiveFloatEq(expected) to be used as a Matcher<float>, a + // Matcher<const float&>, or a Matcher<float&>, but nothing else. + operator Matcher<FloatType>() const { + return MakeMatcher( + new Impl<FloatType>(expected_, nan_eq_nan_, max_abs_error_)); + } + + operator Matcher<const FloatType&>() const { + return MakeMatcher( + new Impl<const FloatType&>(expected_, nan_eq_nan_, max_abs_error_)); + } + + operator Matcher<FloatType&>() const { + return MakeMatcher( + new Impl<FloatType&>(expected_, nan_eq_nan_, max_abs_error_)); + } + + private: + const FloatType expected_; + const bool nan_eq_nan_; + // max_abs_error will be used for value comparison when >= 0. + const FloatType max_abs_error_; +}; + +// A 2-tuple ("binary") wrapper around FloatingEqMatcher: +// FloatingEq2Matcher() matches (x, y) by matching FloatingEqMatcher(x, false) +// against y, and FloatingEq2Matcher(e) matches FloatingEqMatcher(x, false, e) +// against y. The former implements "Eq", the latter "Near". At present, there +// is no version that compares NaNs as equal. +template <typename FloatType> +class FloatingEq2Matcher { + public: + FloatingEq2Matcher() { Init(-1, false); } + + explicit FloatingEq2Matcher(bool nan_eq_nan) { Init(-1, nan_eq_nan); } + + explicit FloatingEq2Matcher(FloatType max_abs_error) { + Init(max_abs_error, false); + } + + FloatingEq2Matcher(FloatType max_abs_error, bool nan_eq_nan) { + Init(max_abs_error, nan_eq_nan); + } + + template <typename T1, typename T2> + operator Matcher<::std::tuple<T1, T2>>() const { + return MakeMatcher( + new Impl<::std::tuple<T1, T2>>(max_abs_error_, nan_eq_nan_)); + } + template <typename T1, typename T2> + operator Matcher<const ::std::tuple<T1, T2>&>() const { + return MakeMatcher( + new Impl<const ::std::tuple<T1, T2>&>(max_abs_error_, nan_eq_nan_)); + } + + private: + static ::std::ostream& GetDesc(::std::ostream& os) { // NOLINT + return os << "an almost-equal pair"; + } + + template <typename Tuple> + class Impl : public MatcherInterface<Tuple> { + public: + Impl(FloatType max_abs_error, bool nan_eq_nan) : + max_abs_error_(max_abs_error), + nan_eq_nan_(nan_eq_nan) {} + + bool MatchAndExplain(Tuple args, + MatchResultListener* listener) const override { + if (max_abs_error_ == -1) { + FloatingEqMatcher<FloatType> fm(::std::get<0>(args), nan_eq_nan_); + return static_cast<Matcher<FloatType>>(fm).MatchAndExplain( + ::std::get<1>(args), listener); + } else { + FloatingEqMatcher<FloatType> fm(::std::get<0>(args), nan_eq_nan_, + max_abs_error_); + return static_cast<Matcher<FloatType>>(fm).MatchAndExplain( + ::std::get<1>(args), listener); + } + } + void DescribeTo(::std::ostream* os) const override { + *os << "are " << GetDesc; + } + void DescribeNegationTo(::std::ostream* os) const override { + *os << "aren't " << GetDesc; + } + + private: + FloatType max_abs_error_; + const bool nan_eq_nan_; + }; + + void Init(FloatType max_abs_error_val, bool nan_eq_nan_val) { + max_abs_error_ = max_abs_error_val; + nan_eq_nan_ = nan_eq_nan_val; + } + FloatType max_abs_error_; + bool nan_eq_nan_; +}; + +// Implements the Pointee(m) matcher for matching a pointer whose +// pointee matches matcher m. The pointer can be either raw or smart. +template <typename InnerMatcher> +class PointeeMatcher { + public: + explicit PointeeMatcher(const InnerMatcher& matcher) : matcher_(matcher) {} + + // This type conversion operator template allows Pointee(m) to be + // used as a matcher for any pointer type whose pointee type is + // compatible with the inner matcher, where type Pointer can be + // either a raw pointer or a smart pointer. + // + // The reason we do this instead of relying on + // MakePolymorphicMatcher() is that the latter is not flexible + // enough for implementing the DescribeTo() method of Pointee(). + template <typename Pointer> + operator Matcher<Pointer>() const { + return Matcher<Pointer>(new Impl<const Pointer&>(matcher_)); + } + + private: + // The monomorphic implementation that works for a particular pointer type. + template <typename Pointer> + class Impl : public MatcherInterface<Pointer> { + public: + using Pointee = + typename std::pointer_traits<GTEST_REMOVE_REFERENCE_AND_CONST_( + Pointer)>::element_type; + + explicit Impl(const InnerMatcher& matcher) + : matcher_(MatcherCast<const Pointee&>(matcher)) {} + + void DescribeTo(::std::ostream* os) const override { + *os << "points to a value that "; + matcher_.DescribeTo(os); + } + + void DescribeNegationTo(::std::ostream* os) const override { + *os << "does not point to a value that "; + matcher_.DescribeTo(os); + } + + bool MatchAndExplain(Pointer pointer, + MatchResultListener* listener) const override { + if (GetRawPointer(pointer) == nullptr) return false; + + *listener << "which points to "; + return MatchPrintAndExplain(*pointer, matcher_, listener); + } + + private: + const Matcher<const Pointee&> matcher_; + }; + + const InnerMatcher matcher_; +}; + +// Implements the Pointer(m) matcher +// Implements the Pointer(m) matcher for matching a pointer that matches matcher +// m. The pointer can be either raw or smart, and will match `m` against the +// raw pointer. +template <typename InnerMatcher> +class PointerMatcher { + public: + explicit PointerMatcher(const InnerMatcher& matcher) : matcher_(matcher) {} + + // This type conversion operator template allows Pointer(m) to be + // used as a matcher for any pointer type whose pointer type is + // compatible with the inner matcher, where type PointerType can be + // either a raw pointer or a smart pointer. + // + // The reason we do this instead of relying on + // MakePolymorphicMatcher() is that the latter is not flexible + // enough for implementing the DescribeTo() method of Pointer(). + template <typename PointerType> + operator Matcher<PointerType>() const { // NOLINT + return Matcher<PointerType>(new Impl<const PointerType&>(matcher_)); + } + + private: + // The monomorphic implementation that works for a particular pointer type. + template <typename PointerType> + class Impl : public MatcherInterface<PointerType> { + public: + using Pointer = + const typename std::pointer_traits<GTEST_REMOVE_REFERENCE_AND_CONST_( + PointerType)>::element_type*; + + explicit Impl(const InnerMatcher& matcher) + : matcher_(MatcherCast<Pointer>(matcher)) {} + + void DescribeTo(::std::ostream* os) const override { + *os << "is a pointer that "; + matcher_.DescribeTo(os); + } + + void DescribeNegationTo(::std::ostream* os) const override { + *os << "is not a pointer that "; + matcher_.DescribeTo(os); + } + + bool MatchAndExplain(PointerType pointer, + MatchResultListener* listener) const override { + *listener << "which is a pointer that "; + Pointer p = GetRawPointer(pointer); + return MatchPrintAndExplain(p, matcher_, listener); + } + + private: + Matcher<Pointer> matcher_; + }; + + const InnerMatcher matcher_; +}; + +#if GTEST_HAS_RTTI +// Implements the WhenDynamicCastTo<T>(m) matcher that matches a pointer or +// reference that matches inner_matcher when dynamic_cast<T> is applied. +// The result of dynamic_cast<To> is forwarded to the inner matcher. +// If To is a pointer and the cast fails, the inner matcher will receive NULL. +// If To is a reference and the cast fails, this matcher returns false +// immediately. +template <typename To> +class WhenDynamicCastToMatcherBase { + public: + explicit WhenDynamicCastToMatcherBase(const Matcher<To>& matcher) + : matcher_(matcher) {} + + void DescribeTo(::std::ostream* os) const { + GetCastTypeDescription(os); + matcher_.DescribeTo(os); + } + + void DescribeNegationTo(::std::ostream* os) const { + GetCastTypeDescription(os); + matcher_.DescribeNegationTo(os); + } + + protected: + const Matcher<To> matcher_; + + static std::string GetToName() { + return GetTypeName<To>(); + } + + private: + static void GetCastTypeDescription(::std::ostream* os) { + *os << "when dynamic_cast to " << GetToName() << ", "; + } +}; + +// Primary template. +// To is a pointer. Cast and forward the result. +template <typename To> +class WhenDynamicCastToMatcher : public WhenDynamicCastToMatcherBase<To> { + public: + explicit WhenDynamicCastToMatcher(const Matcher<To>& matcher) + : WhenDynamicCastToMatcherBase<To>(matcher) {} + + template <typename From> + bool MatchAndExplain(From from, MatchResultListener* listener) const { + To to = dynamic_cast<To>(from); + return MatchPrintAndExplain(to, this->matcher_, listener); + } +}; + +// Specialize for references. +// In this case we return false if the dynamic_cast fails. +template <typename To> +class WhenDynamicCastToMatcher<To&> : public WhenDynamicCastToMatcherBase<To&> { + public: + explicit WhenDynamicCastToMatcher(const Matcher<To&>& matcher) + : WhenDynamicCastToMatcherBase<To&>(matcher) {} + + template <typename From> + bool MatchAndExplain(From& from, MatchResultListener* listener) const { + // We don't want an std::bad_cast here, so do the cast with pointers. + To* to = dynamic_cast<To*>(&from); + if (to == nullptr) { + *listener << "which cannot be dynamic_cast to " << this->GetToName(); + return false; + } + return MatchPrintAndExplain(*to, this->matcher_, listener); + } +}; +#endif // GTEST_HAS_RTTI + +// Implements the Field() matcher for matching a field (i.e. member +// variable) of an object. +template <typename Class, typename FieldType> +class FieldMatcher { + public: + FieldMatcher(FieldType Class::*field, + const Matcher<const FieldType&>& matcher) + : field_(field), matcher_(matcher), whose_field_("whose given field ") {} + + FieldMatcher(const std::string& field_name, FieldType Class::*field, + const Matcher<const FieldType&>& matcher) + : field_(field), + matcher_(matcher), + whose_field_("whose field `" + field_name + "` ") {} + + void DescribeTo(::std::ostream* os) const { + *os << "is an object " << whose_field_; + matcher_.DescribeTo(os); + } + + void DescribeNegationTo(::std::ostream* os) const { + *os << "is an object " << whose_field_; + matcher_.DescribeNegationTo(os); + } + + template <typename T> + bool MatchAndExplain(const T& value, MatchResultListener* listener) const { + // FIXME: The dispatch on std::is_pointer was introduced as a workaround for + // a compiler bug, and can now be removed. + return MatchAndExplainImpl( + typename std::is_pointer<typename std::remove_const<T>::type>::type(), + value, listener); + } + + private: + bool MatchAndExplainImpl(std::false_type /* is_not_pointer */, + const Class& obj, + MatchResultListener* listener) const { + *listener << whose_field_ << "is "; + return MatchPrintAndExplain(obj.*field_, matcher_, listener); + } + + bool MatchAndExplainImpl(std::true_type /* is_pointer */, const Class* p, + MatchResultListener* listener) const { + if (p == nullptr) return false; + + *listener << "which points to an object "; + // Since *p has a field, it must be a class/struct/union type and + // thus cannot be a pointer. Therefore we pass false_type() as + // the first argument. + return MatchAndExplainImpl(std::false_type(), *p, listener); + } + + const FieldType Class::*field_; + const Matcher<const FieldType&> matcher_; + + // Contains either "whose given field " if the name of the field is unknown + // or "whose field `name_of_field` " if the name is known. + const std::string whose_field_; +}; + +// Implements the Property() matcher for matching a property +// (i.e. return value of a getter method) of an object. +// +// Property is a const-qualified member function of Class returning +// PropertyType. +template <typename Class, typename PropertyType, typename Property> +class PropertyMatcher { + public: + typedef const PropertyType& RefToConstProperty; + + PropertyMatcher(Property property, const Matcher<RefToConstProperty>& matcher) + : property_(property), + matcher_(matcher), + whose_property_("whose given property ") {} + + PropertyMatcher(const std::string& property_name, Property property, + const Matcher<RefToConstProperty>& matcher) + : property_(property), + matcher_(matcher), + whose_property_("whose property `" + property_name + "` ") {} + + void DescribeTo(::std::ostream* os) const { + *os << "is an object " << whose_property_; + matcher_.DescribeTo(os); + } + + void DescribeNegationTo(::std::ostream* os) const { + *os << "is an object " << whose_property_; + matcher_.DescribeNegationTo(os); + } + + template <typename T> + bool MatchAndExplain(const T&value, MatchResultListener* listener) const { + return MatchAndExplainImpl( + typename std::is_pointer<typename std::remove_const<T>::type>::type(), + value, listener); + } + + private: + bool MatchAndExplainImpl(std::false_type /* is_not_pointer */, + const Class& obj, + MatchResultListener* listener) const { + *listener << whose_property_ << "is "; + // Cannot pass the return value (for example, int) to MatchPrintAndExplain, + // which takes a non-const reference as argument. + RefToConstProperty result = (obj.*property_)(); + return MatchPrintAndExplain(result, matcher_, listener); + } + + bool MatchAndExplainImpl(std::true_type /* is_pointer */, const Class* p, + MatchResultListener* listener) const { + if (p == nullptr) return false; + + *listener << "which points to an object "; + // Since *p has a property method, it must be a class/struct/union + // type and thus cannot be a pointer. Therefore we pass + // false_type() as the first argument. + return MatchAndExplainImpl(std::false_type(), *p, listener); + } + + Property property_; + const Matcher<RefToConstProperty> matcher_; + + // Contains either "whose given property " if the name of the property is + // unknown or "whose property `name_of_property` " if the name is known. + const std::string whose_property_; +}; + +// Type traits specifying various features of different functors for ResultOf. +// The default template specifies features for functor objects. +template <typename Functor> +struct CallableTraits { + typedef Functor StorageType; + + static void CheckIsValid(Functor /* functor */) {} + + template <typename T> + static auto Invoke(Functor f, const T& arg) -> decltype(f(arg)) { + return f(arg); + } +}; + +// Specialization for function pointers. +template <typename ArgType, typename ResType> +struct CallableTraits<ResType(*)(ArgType)> { + typedef ResType ResultType; + typedef ResType(*StorageType)(ArgType); + + static void CheckIsValid(ResType(*f)(ArgType)) { + GTEST_CHECK_(f != nullptr) + << "NULL function pointer is passed into ResultOf()."; + } + template <typename T> + static ResType Invoke(ResType(*f)(ArgType), T arg) { + return (*f)(arg); + } +}; + +// Implements the ResultOf() matcher for matching a return value of a +// unary function of an object. +template <typename Callable, typename InnerMatcher> +class ResultOfMatcher { + public: + ResultOfMatcher(Callable callable, InnerMatcher matcher) + : callable_(std::move(callable)), matcher_(std::move(matcher)) { + CallableTraits<Callable>::CheckIsValid(callable_); + } + + template <typename T> + operator Matcher<T>() const { + return Matcher<T>(new Impl<const T&>(callable_, matcher_)); + } + + private: + typedef typename CallableTraits<Callable>::StorageType CallableStorageType; + + template <typename T> + class Impl : public MatcherInterface<T> { + using ResultType = decltype(CallableTraits<Callable>::template Invoke<T>( + std::declval<CallableStorageType>(), std::declval<T>())); + + public: + template <typename M> + Impl(const CallableStorageType& callable, const M& matcher) + : callable_(callable), matcher_(MatcherCast<ResultType>(matcher)) {} + + void DescribeTo(::std::ostream* os) const override { + *os << "is mapped by the given callable to a value that "; + matcher_.DescribeTo(os); + } + + void DescribeNegationTo(::std::ostream* os) const override { + *os << "is mapped by the given callable to a value that "; + matcher_.DescribeNegationTo(os); + } + + bool MatchAndExplain(T obj, MatchResultListener* listener) const override { + *listener << "which is mapped by the given callable to "; + // Cannot pass the return value directly to MatchPrintAndExplain, which + // takes a non-const reference as argument. + // Also, specifying template argument explicitly is needed because T could + // be a non-const reference (e.g. Matcher<Uncopyable&>). + ResultType result = + CallableTraits<Callable>::template Invoke<T>(callable_, obj); + return MatchPrintAndExplain(result, matcher_, listener); + } + + private: + // Functors often define operator() as non-const method even though + // they are actually stateless. But we need to use them even when + // 'this' is a const pointer. It's the user's responsibility not to + // use stateful callables with ResultOf(), which doesn't guarantee + // how many times the callable will be invoked. + mutable CallableStorageType callable_; + const Matcher<ResultType> matcher_; + }; // class Impl + + const CallableStorageType callable_; + const InnerMatcher matcher_; +}; + +// Implements a matcher that checks the size of an STL-style container. +template <typename SizeMatcher> +class SizeIsMatcher { + public: + explicit SizeIsMatcher(const SizeMatcher& size_matcher) + : size_matcher_(size_matcher) { + } + + template <typename Container> + operator Matcher<Container>() const { + return Matcher<Container>(new Impl<const Container&>(size_matcher_)); + } + + template <typename Container> + class Impl : public MatcherInterface<Container> { + public: + using SizeType = decltype(std::declval<Container>().size()); + explicit Impl(const SizeMatcher& size_matcher) + : size_matcher_(MatcherCast<SizeType>(size_matcher)) {} + + void DescribeTo(::std::ostream* os) const override { + *os << "size "; + size_matcher_.DescribeTo(os); + } + void DescribeNegationTo(::std::ostream* os) const override { + *os << "size "; + size_matcher_.DescribeNegationTo(os); + } + + bool MatchAndExplain(Container container, + MatchResultListener* listener) const override { + SizeType size = container.size(); + StringMatchResultListener size_listener; + const bool result = size_matcher_.MatchAndExplain(size, &size_listener); + *listener + << "whose size " << size << (result ? " matches" : " doesn't match"); + PrintIfNotEmpty(size_listener.str(), listener->stream()); + return result; + } + + private: + const Matcher<SizeType> size_matcher_; + }; + + private: + const SizeMatcher size_matcher_; +}; + +// Implements a matcher that checks the begin()..end() distance of an STL-style +// container. +template <typename DistanceMatcher> +class BeginEndDistanceIsMatcher { + public: + explicit BeginEndDistanceIsMatcher(const DistanceMatcher& distance_matcher) + : distance_matcher_(distance_matcher) {} + + template <typename Container> + operator Matcher<Container>() const { + return Matcher<Container>(new Impl<const Container&>(distance_matcher_)); + } + + template <typename Container> + class Impl : public MatcherInterface<Container> { + public: + typedef internal::StlContainerView< + GTEST_REMOVE_REFERENCE_AND_CONST_(Container)> ContainerView; + typedef typename std::iterator_traits< + typename ContainerView::type::const_iterator>::difference_type + DistanceType; + explicit Impl(const DistanceMatcher& distance_matcher) + : distance_matcher_(MatcherCast<DistanceType>(distance_matcher)) {} + + void DescribeTo(::std::ostream* os) const override { + *os << "distance between begin() and end() "; + distance_matcher_.DescribeTo(os); + } + void DescribeNegationTo(::std::ostream* os) const override { + *os << "distance between begin() and end() "; + distance_matcher_.DescribeNegationTo(os); + } + + bool MatchAndExplain(Container container, + MatchResultListener* listener) const override { + using std::begin; + using std::end; + DistanceType distance = std::distance(begin(container), end(container)); + StringMatchResultListener distance_listener; + const bool result = + distance_matcher_.MatchAndExplain(distance, &distance_listener); + *listener << "whose distance between begin() and end() " << distance + << (result ? " matches" : " doesn't match"); + PrintIfNotEmpty(distance_listener.str(), listener->stream()); + return result; + } + + private: + const Matcher<DistanceType> distance_matcher_; + }; + + private: + const DistanceMatcher distance_matcher_; +}; + +// Implements an equality matcher for any STL-style container whose elements +// support ==. This matcher is like Eq(), but its failure explanations provide +// more detailed information that is useful when the container is used as a set. +// The failure message reports elements that are in one of the operands but not +// the other. The failure messages do not report duplicate or out-of-order +// elements in the containers (which don't properly matter to sets, but can +// occur if the containers are vectors or lists, for example). +// +// Uses the container's const_iterator, value_type, operator ==, +// begin(), and end(). +template <typename Container> +class ContainerEqMatcher { + public: + typedef internal::StlContainerView<Container> View; + typedef typename View::type StlContainer; + typedef typename View::const_reference StlContainerReference; + + static_assert(!std::is_const<Container>::value, + "Container type must not be const"); + static_assert(!std::is_reference<Container>::value, + "Container type must not be a reference"); + + // We make a copy of expected in case the elements in it are modified + // after this matcher is created. + explicit ContainerEqMatcher(const Container& expected) + : expected_(View::Copy(expected)) {} + + void DescribeTo(::std::ostream* os) const { + *os << "equals "; + UniversalPrint(expected_, os); + } + void DescribeNegationTo(::std::ostream* os) const { + *os << "does not equal "; + UniversalPrint(expected_, os); + } + + template <typename LhsContainer> + bool MatchAndExplain(const LhsContainer& lhs, + MatchResultListener* listener) const { + typedef internal::StlContainerView< + typename std::remove_const<LhsContainer>::type> + LhsView; + typedef typename LhsView::type LhsStlContainer; + StlContainerReference lhs_stl_container = LhsView::ConstReference(lhs); + if (lhs_stl_container == expected_) + return true; + + ::std::ostream* const os = listener->stream(); + if (os != nullptr) { + // Something is different. Check for extra values first. + bool printed_header = false; + for (typename LhsStlContainer::const_iterator it = + lhs_stl_container.begin(); + it != lhs_stl_container.end(); ++it) { + if (internal::ArrayAwareFind(expected_.begin(), expected_.end(), *it) == + expected_.end()) { + if (printed_header) { + *os << ", "; + } else { + *os << "which has these unexpected elements: "; + printed_header = true; + } + UniversalPrint(*it, os); + } + } + + // Now check for missing values. + bool printed_header2 = false; + for (typename StlContainer::const_iterator it = expected_.begin(); + it != expected_.end(); ++it) { + if (internal::ArrayAwareFind( + lhs_stl_container.begin(), lhs_stl_container.end(), *it) == + lhs_stl_container.end()) { + if (printed_header2) { + *os << ", "; + } else { + *os << (printed_header ? ",\nand" : "which") + << " doesn't have these expected elements: "; + printed_header2 = true; + } + UniversalPrint(*it, os); + } + } + } + + return false; + } + + private: + const StlContainer expected_; +}; + +// A comparator functor that uses the < operator to compare two values. +struct LessComparator { + template <typename T, typename U> + bool operator()(const T& lhs, const U& rhs) const { return lhs < rhs; } +}; + +// Implements WhenSortedBy(comparator, container_matcher). +template <typename Comparator, typename ContainerMatcher> +class WhenSortedByMatcher { + public: + WhenSortedByMatcher(const Comparator& comparator, + const ContainerMatcher& matcher) + : comparator_(comparator), matcher_(matcher) {} + + template <typename LhsContainer> + operator Matcher<LhsContainer>() const { + return MakeMatcher(new Impl<LhsContainer>(comparator_, matcher_)); + } + + template <typename LhsContainer> + class Impl : public MatcherInterface<LhsContainer> { + public: + typedef internal::StlContainerView< + GTEST_REMOVE_REFERENCE_AND_CONST_(LhsContainer)> LhsView; + typedef typename LhsView::type LhsStlContainer; + typedef typename LhsView::const_reference LhsStlContainerReference; + // Transforms std::pair<const Key, Value> into std::pair<Key, Value> + // so that we can match associative containers. + typedef typename RemoveConstFromKey< + typename LhsStlContainer::value_type>::type LhsValue; + + Impl(const Comparator& comparator, const ContainerMatcher& matcher) + : comparator_(comparator), matcher_(matcher) {} + + void DescribeTo(::std::ostream* os) const override { + *os << "(when sorted) "; + matcher_.DescribeTo(os); + } + + void DescribeNegationTo(::std::ostream* os) const override { + *os << "(when sorted) "; + matcher_.DescribeNegationTo(os); + } + + bool MatchAndExplain(LhsContainer lhs, + MatchResultListener* listener) const override { + LhsStlContainerReference lhs_stl_container = LhsView::ConstReference(lhs); + ::std::vector<LhsValue> sorted_container(lhs_stl_container.begin(), + lhs_stl_container.end()); + ::std::sort( + sorted_container.begin(), sorted_container.end(), comparator_); + + if (!listener->IsInterested()) { + // If the listener is not interested, we do not need to + // construct the inner explanation. + return matcher_.Matches(sorted_container); + } + + *listener << "which is "; + UniversalPrint(sorted_container, listener->stream()); + *listener << " when sorted"; + + StringMatchResultListener inner_listener; + const bool match = matcher_.MatchAndExplain(sorted_container, + &inner_listener); + PrintIfNotEmpty(inner_listener.str(), listener->stream()); + return match; + } + + private: + const Comparator comparator_; + const Matcher<const ::std::vector<LhsValue>&> matcher_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(Impl); + }; + + private: + const Comparator comparator_; + const ContainerMatcher matcher_; +}; + +// Implements Pointwise(tuple_matcher, rhs_container). tuple_matcher +// must be able to be safely cast to Matcher<std::tuple<const T1&, const +// T2&> >, where T1 and T2 are the types of elements in the LHS +// container and the RHS container respectively. +template <typename TupleMatcher, typename RhsContainer> +class PointwiseMatcher { + GTEST_COMPILE_ASSERT_( + !IsHashTable<GTEST_REMOVE_REFERENCE_AND_CONST_(RhsContainer)>::value, + use_UnorderedPointwise_with_hash_tables); + + public: + typedef internal::StlContainerView<RhsContainer> RhsView; + typedef typename RhsView::type RhsStlContainer; + typedef typename RhsStlContainer::value_type RhsValue; + + static_assert(!std::is_const<RhsContainer>::value, + "RhsContainer type must not be const"); + static_assert(!std::is_reference<RhsContainer>::value, + "RhsContainer type must not be a reference"); + + // Like ContainerEq, we make a copy of rhs in case the elements in + // it are modified after this matcher is created. + PointwiseMatcher(const TupleMatcher& tuple_matcher, const RhsContainer& rhs) + : tuple_matcher_(tuple_matcher), rhs_(RhsView::Copy(rhs)) {} + + template <typename LhsContainer> + operator Matcher<LhsContainer>() const { + GTEST_COMPILE_ASSERT_( + !IsHashTable<GTEST_REMOVE_REFERENCE_AND_CONST_(LhsContainer)>::value, + use_UnorderedPointwise_with_hash_tables); + + return Matcher<LhsContainer>( + new Impl<const LhsContainer&>(tuple_matcher_, rhs_)); + } + + template <typename LhsContainer> + class Impl : public MatcherInterface<LhsContainer> { + public: + typedef internal::StlContainerView< + GTEST_REMOVE_REFERENCE_AND_CONST_(LhsContainer)> LhsView; + typedef typename LhsView::type LhsStlContainer; + typedef typename LhsView::const_reference LhsStlContainerReference; + typedef typename LhsStlContainer::value_type LhsValue; + // We pass the LHS value and the RHS value to the inner matcher by + // reference, as they may be expensive to copy. We must use tuple + // instead of pair here, as a pair cannot hold references (C++ 98, + // 20.2.2 [lib.pairs]). + typedef ::std::tuple<const LhsValue&, const RhsValue&> InnerMatcherArg; + + Impl(const TupleMatcher& tuple_matcher, const RhsStlContainer& rhs) + // mono_tuple_matcher_ holds a monomorphic version of the tuple matcher. + : mono_tuple_matcher_(SafeMatcherCast<InnerMatcherArg>(tuple_matcher)), + rhs_(rhs) {} + + void DescribeTo(::std::ostream* os) const override { + *os << "contains " << rhs_.size() + << " values, where each value and its corresponding value in "; + UniversalPrinter<RhsStlContainer>::Print(rhs_, os); + *os << " "; + mono_tuple_matcher_.DescribeTo(os); + } + void DescribeNegationTo(::std::ostream* os) const override { + *os << "doesn't contain exactly " << rhs_.size() + << " values, or contains a value x at some index i" + << " where x and the i-th value of "; + UniversalPrint(rhs_, os); + *os << " "; + mono_tuple_matcher_.DescribeNegationTo(os); + } + + bool MatchAndExplain(LhsContainer lhs, + MatchResultListener* listener) const override { + LhsStlContainerReference lhs_stl_container = LhsView::ConstReference(lhs); + const size_t actual_size = lhs_stl_container.size(); + if (actual_size != rhs_.size()) { + *listener << "which contains " << actual_size << " values"; + return false; + } + + typename LhsStlContainer::const_iterator left = lhs_stl_container.begin(); + typename RhsStlContainer::const_iterator right = rhs_.begin(); + for (size_t i = 0; i != actual_size; ++i, ++left, ++right) { + if (listener->IsInterested()) { + StringMatchResultListener inner_listener; + // Create InnerMatcherArg as a temporarily object to avoid it outlives + // *left and *right. Dereference or the conversion to `const T&` may + // return temp objects, e.g for vector<bool>. + if (!mono_tuple_matcher_.MatchAndExplain( + InnerMatcherArg(ImplicitCast_<const LhsValue&>(*left), + ImplicitCast_<const RhsValue&>(*right)), + &inner_listener)) { + *listener << "where the value pair ("; + UniversalPrint(*left, listener->stream()); + *listener << ", "; + UniversalPrint(*right, listener->stream()); + *listener << ") at index #" << i << " don't match"; + PrintIfNotEmpty(inner_listener.str(), listener->stream()); + return false; + } + } else { + if (!mono_tuple_matcher_.Matches( + InnerMatcherArg(ImplicitCast_<const LhsValue&>(*left), + ImplicitCast_<const RhsValue&>(*right)))) + return false; + } + } + + return true; + } + + private: + const Matcher<InnerMatcherArg> mono_tuple_matcher_; + const RhsStlContainer rhs_; + }; + + private: + const TupleMatcher tuple_matcher_; + const RhsStlContainer rhs_; +}; + +// Holds the logic common to ContainsMatcherImpl and EachMatcherImpl. +template <typename Container> +class QuantifierMatcherImpl : public MatcherInterface<Container> { + public: + typedef GTEST_REMOVE_REFERENCE_AND_CONST_(Container) RawContainer; + typedef StlContainerView<RawContainer> View; + typedef typename View::type StlContainer; + typedef typename View::const_reference StlContainerReference; + typedef typename StlContainer::value_type Element; + + template <typename InnerMatcher> + explicit QuantifierMatcherImpl(InnerMatcher inner_matcher) + : inner_matcher_( + testing::SafeMatcherCast<const Element&>(inner_matcher)) {} + + // Checks whether: + // * All elements in the container match, if all_elements_should_match. + // * Any element in the container matches, if !all_elements_should_match. + bool MatchAndExplainImpl(bool all_elements_should_match, + Container container, + MatchResultListener* listener) const { + StlContainerReference stl_container = View::ConstReference(container); + size_t i = 0; + for (typename StlContainer::const_iterator it = stl_container.begin(); + it != stl_container.end(); ++it, ++i) { + StringMatchResultListener inner_listener; + const bool matches = inner_matcher_.MatchAndExplain(*it, &inner_listener); + + if (matches != all_elements_should_match) { + *listener << "whose element #" << i + << (matches ? " matches" : " doesn't match"); + PrintIfNotEmpty(inner_listener.str(), listener->stream()); + return !all_elements_should_match; + } + } + return all_elements_should_match; + } + + protected: + const Matcher<const Element&> inner_matcher_; +}; + +// Implements Contains(element_matcher) for the given argument type Container. +// Symmetric to EachMatcherImpl. +template <typename Container> +class ContainsMatcherImpl : public QuantifierMatcherImpl<Container> { + public: + template <typename InnerMatcher> + explicit ContainsMatcherImpl(InnerMatcher inner_matcher) + : QuantifierMatcherImpl<Container>(inner_matcher) {} + + // Describes what this matcher does. + void DescribeTo(::std::ostream* os) const override { + *os << "contains at least one element that "; + this->inner_matcher_.DescribeTo(os); + } + + void DescribeNegationTo(::std::ostream* os) const override { + *os << "doesn't contain any element that "; + this->inner_matcher_.DescribeTo(os); + } + + bool MatchAndExplain(Container container, + MatchResultListener* listener) const override { + return this->MatchAndExplainImpl(false, container, listener); + } +}; + +// Implements Each(element_matcher) for the given argument type Container. +// Symmetric to ContainsMatcherImpl. +template <typename Container> +class EachMatcherImpl : public QuantifierMatcherImpl<Container> { + public: + template <typename InnerMatcher> + explicit EachMatcherImpl(InnerMatcher inner_matcher) + : QuantifierMatcherImpl<Container>(inner_matcher) {} + + // Describes what this matcher does. + void DescribeTo(::std::ostream* os) const override { + *os << "only contains elements that "; + this->inner_matcher_.DescribeTo(os); + } + + void DescribeNegationTo(::std::ostream* os) const override { + *os << "contains some element that "; + this->inner_matcher_.DescribeNegationTo(os); + } + + bool MatchAndExplain(Container container, + MatchResultListener* listener) const override { + return this->MatchAndExplainImpl(true, container, listener); + } +}; + +// Implements polymorphic Contains(element_matcher). +template <typename M> +class ContainsMatcher { + public: + explicit ContainsMatcher(M m) : inner_matcher_(m) {} + + template <typename Container> + operator Matcher<Container>() const { + return Matcher<Container>( + new ContainsMatcherImpl<const Container&>(inner_matcher_)); + } + + private: + const M inner_matcher_; +}; + +// Implements polymorphic Each(element_matcher). +template <typename M> +class EachMatcher { + public: + explicit EachMatcher(M m) : inner_matcher_(m) {} + + template <typename Container> + operator Matcher<Container>() const { + return Matcher<Container>( + new EachMatcherImpl<const Container&>(inner_matcher_)); + } + + private: + const M inner_matcher_; +}; + +struct Rank1 {}; +struct Rank0 : Rank1 {}; + +namespace pair_getters { +using std::get; +template <typename T> +auto First(T& x, Rank1) -> decltype(get<0>(x)) { // NOLINT + return get<0>(x); +} +template <typename T> +auto First(T& x, Rank0) -> decltype((x.first)) { // NOLINT + return x.first; +} + +template <typename T> +auto Second(T& x, Rank1) -> decltype(get<1>(x)) { // NOLINT + return get<1>(x); +} +template <typename T> +auto Second(T& x, Rank0) -> decltype((x.second)) { // NOLINT + return x.second; +} +} // namespace pair_getters + +// Implements Key(inner_matcher) for the given argument pair type. +// Key(inner_matcher) matches an std::pair whose 'first' field matches +// inner_matcher. For example, Contains(Key(Ge(5))) can be used to match an +// std::map that contains at least one element whose key is >= 5. +template <typename PairType> +class KeyMatcherImpl : public MatcherInterface<PairType> { + public: + typedef GTEST_REMOVE_REFERENCE_AND_CONST_(PairType) RawPairType; + typedef typename RawPairType::first_type KeyType; + + template <typename InnerMatcher> + explicit KeyMatcherImpl(InnerMatcher inner_matcher) + : inner_matcher_( + testing::SafeMatcherCast<const KeyType&>(inner_matcher)) { + } + + // Returns true if and only if 'key_value.first' (the key) matches the inner + // matcher. + bool MatchAndExplain(PairType key_value, + MatchResultListener* listener) const override { + StringMatchResultListener inner_listener; + const bool match = inner_matcher_.MatchAndExplain( + pair_getters::First(key_value, Rank0()), &inner_listener); + const std::string explanation = inner_listener.str(); + if (explanation != "") { + *listener << "whose first field is a value " << explanation; + } + return match; + } + + // Describes what this matcher does. + void DescribeTo(::std::ostream* os) const override { + *os << "has a key that "; + inner_matcher_.DescribeTo(os); + } + + // Describes what the negation of this matcher does. + void DescribeNegationTo(::std::ostream* os) const override { + *os << "doesn't have a key that "; + inner_matcher_.DescribeTo(os); + } + + private: + const Matcher<const KeyType&> inner_matcher_; +}; + +// Implements polymorphic Key(matcher_for_key). +template <typename M> +class KeyMatcher { + public: + explicit KeyMatcher(M m) : matcher_for_key_(m) {} + + template <typename PairType> + operator Matcher<PairType>() const { + return Matcher<PairType>( + new KeyMatcherImpl<const PairType&>(matcher_for_key_)); + } + + private: + const M matcher_for_key_; +}; + +// Implements polymorphic Address(matcher_for_address). +template <typename InnerMatcher> +class AddressMatcher { + public: + explicit AddressMatcher(InnerMatcher m) : matcher_(m) {} + + template <typename Type> + operator Matcher<Type>() const { // NOLINT + return Matcher<Type>(new Impl<const Type&>(matcher_)); + } + + private: + // The monomorphic implementation that works for a particular object type. + template <typename Type> + class Impl : public MatcherInterface<Type> { + public: + using Address = const GTEST_REMOVE_REFERENCE_AND_CONST_(Type) *; + explicit Impl(const InnerMatcher& matcher) + : matcher_(MatcherCast<Address>(matcher)) {} + + void DescribeTo(::std::ostream* os) const override { + *os << "has address that "; + matcher_.DescribeTo(os); + } + + void DescribeNegationTo(::std::ostream* os) const override { + *os << "does not have address that "; + matcher_.DescribeTo(os); + } + + bool MatchAndExplain(Type object, + MatchResultListener* listener) const override { + *listener << "which has address "; + Address address = std::addressof(object); + return MatchPrintAndExplain(address, matcher_, listener); + } + + private: + const Matcher<Address> matcher_; + }; + const InnerMatcher matcher_; +}; + +// Implements Pair(first_matcher, second_matcher) for the given argument pair +// type with its two matchers. See Pair() function below. +template <typename PairType> +class PairMatcherImpl : public MatcherInterface<PairType> { + public: + typedef GTEST_REMOVE_REFERENCE_AND_CONST_(PairType) RawPairType; + typedef typename RawPairType::first_type FirstType; + typedef typename RawPairType::second_type SecondType; + + template <typename FirstMatcher, typename SecondMatcher> + PairMatcherImpl(FirstMatcher first_matcher, SecondMatcher second_matcher) + : first_matcher_( + testing::SafeMatcherCast<const FirstType&>(first_matcher)), + second_matcher_( + testing::SafeMatcherCast<const SecondType&>(second_matcher)) { + } + + // Describes what this matcher does. + void DescribeTo(::std::ostream* os) const override { + *os << "has a first field that "; + first_matcher_.DescribeTo(os); + *os << ", and has a second field that "; + second_matcher_.DescribeTo(os); + } + + // Describes what the negation of this matcher does. + void DescribeNegationTo(::std::ostream* os) const override { + *os << "has a first field that "; + first_matcher_.DescribeNegationTo(os); + *os << ", or has a second field that "; + second_matcher_.DescribeNegationTo(os); + } + + // Returns true if and only if 'a_pair.first' matches first_matcher and + // 'a_pair.second' matches second_matcher. + bool MatchAndExplain(PairType a_pair, + MatchResultListener* listener) const override { + if (!listener->IsInterested()) { + // If the listener is not interested, we don't need to construct the + // explanation. + return first_matcher_.Matches(pair_getters::First(a_pair, Rank0())) && + second_matcher_.Matches(pair_getters::Second(a_pair, Rank0())); + } + StringMatchResultListener first_inner_listener; + if (!first_matcher_.MatchAndExplain(pair_getters::First(a_pair, Rank0()), + &first_inner_listener)) { + *listener << "whose first field does not match"; + PrintIfNotEmpty(first_inner_listener.str(), listener->stream()); + return false; + } + StringMatchResultListener second_inner_listener; + if (!second_matcher_.MatchAndExplain(pair_getters::Second(a_pair, Rank0()), + &second_inner_listener)) { + *listener << "whose second field does not match"; + PrintIfNotEmpty(second_inner_listener.str(), listener->stream()); + return false; + } + ExplainSuccess(first_inner_listener.str(), second_inner_listener.str(), + listener); + return true; + } + + private: + void ExplainSuccess(const std::string& first_explanation, + const std::string& second_explanation, + MatchResultListener* listener) const { + *listener << "whose both fields match"; + if (first_explanation != "") { + *listener << ", where the first field is a value " << first_explanation; + } + if (second_explanation != "") { + *listener << ", "; + if (first_explanation != "") { + *listener << "and "; + } else { + *listener << "where "; + } + *listener << "the second field is a value " << second_explanation; + } + } + + const Matcher<const FirstType&> first_matcher_; + const Matcher<const SecondType&> second_matcher_; +}; + +// Implements polymorphic Pair(first_matcher, second_matcher). +template <typename FirstMatcher, typename SecondMatcher> +class PairMatcher { + public: + PairMatcher(FirstMatcher first_matcher, SecondMatcher second_matcher) + : first_matcher_(first_matcher), second_matcher_(second_matcher) {} + + template <typename PairType> + operator Matcher<PairType> () const { + return Matcher<PairType>( + new PairMatcherImpl<const PairType&>(first_matcher_, second_matcher_)); + } + + private: + const FirstMatcher first_matcher_; + const SecondMatcher second_matcher_; +}; + +template <typename T, size_t... I> +auto UnpackStructImpl(const T& t, IndexSequence<I...>, int) + -> decltype(std::tie(get<I>(t)...)) { + static_assert(std::tuple_size<T>::value == sizeof...(I), + "Number of arguments doesn't match the number of fields."); + return std::tie(get<I>(t)...); +} + +#if defined(__cpp_structured_bindings) && __cpp_structured_bindings >= 201606 +template <typename T> +auto UnpackStructImpl(const T& t, MakeIndexSequence<1>, char) { + const auto& [a] = t; + return std::tie(a); +} +template <typename T> +auto UnpackStructImpl(const T& t, MakeIndexSequence<2>, char) { + const auto& [a, b] = t; + return std::tie(a, b); +} +template <typename T> +auto UnpackStructImpl(const T& t, MakeIndexSequence<3>, char) { + const auto& [a, b, c] = t; + return std::tie(a, b, c); +} +template <typename T> +auto UnpackStructImpl(const T& t, MakeIndexSequence<4>, char) { + const auto& [a, b, c, d] = t; + return std::tie(a, b, c, d); +} +template <typename T> +auto UnpackStructImpl(const T& t, MakeIndexSequence<5>, char) { + const auto& [a, b, c, d, e] = t; + return std::tie(a, b, c, d, e); +} +template <typename T> +auto UnpackStructImpl(const T& t, MakeIndexSequence<6>, char) { + const auto& [a, b, c, d, e, f] = t; + return std::tie(a, b, c, d, e, f); +} +template <typename T> +auto UnpackStructImpl(const T& t, MakeIndexSequence<7>, char) { + const auto& [a, b, c, d, e, f, g] = t; + return std::tie(a, b, c, d, e, f, g); +} +template <typename T> +auto UnpackStructImpl(const T& t, MakeIndexSequence<8>, char) { + const auto& [a, b, c, d, e, f, g, h] = t; + return std::tie(a, b, c, d, e, f, g, h); +} +template <typename T> +auto UnpackStructImpl(const T& t, MakeIndexSequence<9>, char) { + const auto& [a, b, c, d, e, f, g, h, i] = t; + return std::tie(a, b, c, d, e, f, g, h, i); +} +template <typename T> +auto UnpackStructImpl(const T& t, MakeIndexSequence<10>, char) { + const auto& [a, b, c, d, e, f, g, h, i, j] = t; + return std::tie(a, b, c, d, e, f, g, h, i, j); +} +template <typename T> +auto UnpackStructImpl(const T& t, MakeIndexSequence<11>, char) { + const auto& [a, b, c, d, e, f, g, h, i, j, k] = t; + return std::tie(a, b, c, d, e, f, g, h, i, j, k); +} +template <typename T> +auto UnpackStructImpl(const T& t, MakeIndexSequence<12>, char) { + const auto& [a, b, c, d, e, f, g, h, i, j, k, l] = t; + return std::tie(a, b, c, d, e, f, g, h, i, j, k, l); +} +template <typename T> +auto UnpackStructImpl(const T& t, MakeIndexSequence<13>, char) { + const auto& [a, b, c, d, e, f, g, h, i, j, k, l, m] = t; + return std::tie(a, b, c, d, e, f, g, h, i, j, k, l, m); +} +template <typename T> +auto UnpackStructImpl(const T& t, MakeIndexSequence<14>, char) { + const auto& [a, b, c, d, e, f, g, h, i, j, k, l, m, n] = t; + return std::tie(a, b, c, d, e, f, g, h, i, j, k, l, m, n); +} +template <typename T> +auto UnpackStructImpl(const T& t, MakeIndexSequence<15>, char) { + const auto& [a, b, c, d, e, f, g, h, i, j, k, l, m, n, o] = t; + return std::tie(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o); +} +template <typename T> +auto UnpackStructImpl(const T& t, MakeIndexSequence<16>, char) { + const auto& [a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p] = t; + return std::tie(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p); +} +#endif // defined(__cpp_structured_bindings) + +template <size_t I, typename T> +auto UnpackStruct(const T& t) + -> decltype((UnpackStructImpl)(t, MakeIndexSequence<I>{}, 0)) { + return (UnpackStructImpl)(t, MakeIndexSequence<I>{}, 0); +} + +// Helper function to do comma folding in C++11. +// The array ensures left-to-right order of evaluation. +// Usage: VariadicExpand({expr...}); +template <typename T, size_t N> +void VariadicExpand(const T (&)[N]) {} + +template <typename Struct, typename StructSize> +class FieldsAreMatcherImpl; + +template <typename Struct, size_t... I> +class FieldsAreMatcherImpl<Struct, IndexSequence<I...>> + : public MatcherInterface<Struct> { + using UnpackedType = + decltype(UnpackStruct<sizeof...(I)>(std::declval<const Struct&>())); + using MatchersType = std::tuple< + Matcher<const typename std::tuple_element<I, UnpackedType>::type&>...>; + + public: + template <typename Inner> + explicit FieldsAreMatcherImpl(const Inner& matchers) + : matchers_(testing::SafeMatcherCast< + const typename std::tuple_element<I, UnpackedType>::type&>( + std::get<I>(matchers))...) {} + + void DescribeTo(::std::ostream* os) const override { + const char* separator = ""; + VariadicExpand( + {(*os << separator << "has field #" << I << " that ", + std::get<I>(matchers_).DescribeTo(os), separator = ", and ")...}); + } + + void DescribeNegationTo(::std::ostream* os) const override { + const char* separator = ""; + VariadicExpand({(*os << separator << "has field #" << I << " that ", + std::get<I>(matchers_).DescribeNegationTo(os), + separator = ", or ")...}); + } + + bool MatchAndExplain(Struct t, MatchResultListener* listener) const override { + return MatchInternal((UnpackStruct<sizeof...(I)>)(t), listener); + } + + private: + bool MatchInternal(UnpackedType tuple, MatchResultListener* listener) const { + if (!listener->IsInterested()) { + // If the listener is not interested, we don't need to construct the + // explanation. + bool good = true; + VariadicExpand({good = good && std::get<I>(matchers_).Matches( + std::get<I>(tuple))...}); + return good; + } + + size_t failed_pos = ~size_t{}; + + std::vector<StringMatchResultListener> inner_listener(sizeof...(I)); + + VariadicExpand( + {failed_pos == ~size_t{} && !std::get<I>(matchers_).MatchAndExplain( + std::get<I>(tuple), &inner_listener[I]) + ? failed_pos = I + : 0 ...}); + if (failed_pos != ~size_t{}) { + *listener << "whose field #" << failed_pos << " does not match"; + PrintIfNotEmpty(inner_listener[failed_pos].str(), listener->stream()); + return false; + } + + *listener << "whose all elements match"; + const char* separator = ", where"; + for (size_t index = 0; index < sizeof...(I); ++index) { + const std::string str = inner_listener[index].str(); + if (!str.empty()) { + *listener << separator << " field #" << index << " is a value " << str; + separator = ", and"; + } + } + + return true; + } + + MatchersType matchers_; +}; + +template <typename... Inner> +class FieldsAreMatcher { + public: + explicit FieldsAreMatcher(Inner... inner) : matchers_(std::move(inner)...) {} + + template <typename Struct> + operator Matcher<Struct>() const { // NOLINT + return Matcher<Struct>( + new FieldsAreMatcherImpl<const Struct&, IndexSequenceFor<Inner...>>( + matchers_)); + } + + private: + std::tuple<Inner...> matchers_; +}; + +// Implements ElementsAre() and ElementsAreArray(). +template <typename Container> +class ElementsAreMatcherImpl : public MatcherInterface<Container> { + public: + typedef GTEST_REMOVE_REFERENCE_AND_CONST_(Container) RawContainer; + typedef internal::StlContainerView<RawContainer> View; + typedef typename View::type StlContainer; + typedef typename View::const_reference StlContainerReference; + typedef typename StlContainer::value_type Element; + + // Constructs the matcher from a sequence of element values or + // element matchers. + template <typename InputIter> + ElementsAreMatcherImpl(InputIter first, InputIter last) { + while (first != last) { + matchers_.push_back(MatcherCast<const Element&>(*first++)); + } + } + + // Describes what this matcher does. + void DescribeTo(::std::ostream* os) const override { + if (count() == 0) { + *os << "is empty"; + } else if (count() == 1) { + *os << "has 1 element that "; + matchers_[0].DescribeTo(os); + } else { + *os << "has " << Elements(count()) << " where\n"; + for (size_t i = 0; i != count(); ++i) { + *os << "element #" << i << " "; + matchers_[i].DescribeTo(os); + if (i + 1 < count()) { + *os << ",\n"; + } + } + } + } + + // Describes what the negation of this matcher does. + void DescribeNegationTo(::std::ostream* os) const override { + if (count() == 0) { + *os << "isn't empty"; + return; + } + + *os << "doesn't have " << Elements(count()) << ", or\n"; + for (size_t i = 0; i != count(); ++i) { + *os << "element #" << i << " "; + matchers_[i].DescribeNegationTo(os); + if (i + 1 < count()) { + *os << ", or\n"; + } + } + } + + bool MatchAndExplain(Container container, + MatchResultListener* listener) const override { + // To work with stream-like "containers", we must only walk + // through the elements in one pass. + + const bool listener_interested = listener->IsInterested(); + + // explanations[i] is the explanation of the element at index i. + ::std::vector<std::string> explanations(count()); + StlContainerReference stl_container = View::ConstReference(container); + typename StlContainer::const_iterator it = stl_container.begin(); + size_t exam_pos = 0; + bool mismatch_found = false; // Have we found a mismatched element yet? + + // Go through the elements and matchers in pairs, until we reach + // the end of either the elements or the matchers, or until we find a + // mismatch. + for (; it != stl_container.end() && exam_pos != count(); ++it, ++exam_pos) { + bool match; // Does the current element match the current matcher? + if (listener_interested) { + StringMatchResultListener s; + match = matchers_[exam_pos].MatchAndExplain(*it, &s); + explanations[exam_pos] = s.str(); + } else { + match = matchers_[exam_pos].Matches(*it); + } + + if (!match) { + mismatch_found = true; + break; + } + } + // If mismatch_found is true, 'exam_pos' is the index of the mismatch. + + // Find how many elements the actual container has. We avoid + // calling size() s.t. this code works for stream-like "containers" + // that don't define size(). + size_t actual_count = exam_pos; + for (; it != stl_container.end(); ++it) { + ++actual_count; + } + + if (actual_count != count()) { + // The element count doesn't match. If the container is empty, + // there's no need to explain anything as Google Mock already + // prints the empty container. Otherwise we just need to show + // how many elements there actually are. + if (listener_interested && (actual_count != 0)) { + *listener << "which has " << Elements(actual_count); + } + return false; + } + + if (mismatch_found) { + // The element count matches, but the exam_pos-th element doesn't match. + if (listener_interested) { + *listener << "whose element #" << exam_pos << " doesn't match"; + PrintIfNotEmpty(explanations[exam_pos], listener->stream()); + } + return false; + } + + // Every element matches its expectation. We need to explain why + // (the obvious ones can be skipped). + if (listener_interested) { + bool reason_printed = false; + for (size_t i = 0; i != count(); ++i) { + const std::string& s = explanations[i]; + if (!s.empty()) { + if (reason_printed) { + *listener << ",\nand "; + } + *listener << "whose element #" << i << " matches, " << s; + reason_printed = true; + } + } + } + return true; + } + + private: + static Message Elements(size_t count) { + return Message() << count << (count == 1 ? " element" : " elements"); + } + + size_t count() const { return matchers_.size(); } + + ::std::vector<Matcher<const Element&> > matchers_; +}; + +// Connectivity matrix of (elements X matchers), in element-major order. +// Initially, there are no edges. +// Use NextGraph() to iterate over all possible edge configurations. +// Use Randomize() to generate a random edge configuration. +class GTEST_API_ MatchMatrix { + public: + MatchMatrix(size_t num_elements, size_t num_matchers) + : num_elements_(num_elements), + num_matchers_(num_matchers), + matched_(num_elements_* num_matchers_, 0) { + } + + size_t LhsSize() const { return num_elements_; } + size_t RhsSize() const { return num_matchers_; } + bool HasEdge(size_t ilhs, size_t irhs) const { + return matched_[SpaceIndex(ilhs, irhs)] == 1; + } + void SetEdge(size_t ilhs, size_t irhs, bool b) { + matched_[SpaceIndex(ilhs, irhs)] = b ? 1 : 0; + } + + // Treating the connectivity matrix as a (LhsSize()*RhsSize())-bit number, + // adds 1 to that number; returns false if incrementing the graph left it + // empty. + bool NextGraph(); + + void Randomize(); + + std::string DebugString() const; + + private: + size_t SpaceIndex(size_t ilhs, size_t irhs) const { + return ilhs * num_matchers_ + irhs; + } + + size_t num_elements_; + size_t num_matchers_; + + // Each element is a char interpreted as bool. They are stored as a + // flattened array in lhs-major order, use 'SpaceIndex()' to translate + // a (ilhs, irhs) matrix coordinate into an offset. + ::std::vector<char> matched_; +}; + +typedef ::std::pair<size_t, size_t> ElementMatcherPair; +typedef ::std::vector<ElementMatcherPair> ElementMatcherPairs; + +// Returns a maximum bipartite matching for the specified graph 'g'. +// The matching is represented as a vector of {element, matcher} pairs. +GTEST_API_ ElementMatcherPairs +FindMaxBipartiteMatching(const MatchMatrix& g); + +struct UnorderedMatcherRequire { + enum Flags { + Superset = 1 << 0, + Subset = 1 << 1, + ExactMatch = Superset | Subset, + }; +}; + +// Untyped base class for implementing UnorderedElementsAre. By +// putting logic that's not specific to the element type here, we +// reduce binary bloat and increase compilation speed. +class GTEST_API_ UnorderedElementsAreMatcherImplBase { + protected: + explicit UnorderedElementsAreMatcherImplBase( + UnorderedMatcherRequire::Flags matcher_flags) + : match_flags_(matcher_flags) {} + + // A vector of matcher describers, one for each element matcher. + // Does not own the describers (and thus can be used only when the + // element matchers are alive). + typedef ::std::vector<const MatcherDescriberInterface*> MatcherDescriberVec; + + // Describes this UnorderedElementsAre matcher. + void DescribeToImpl(::std::ostream* os) const; + + // Describes the negation of this UnorderedElementsAre matcher. + void DescribeNegationToImpl(::std::ostream* os) const; + + bool VerifyMatchMatrix(const ::std::vector<std::string>& element_printouts, + const MatchMatrix& matrix, + MatchResultListener* listener) const; + + bool FindPairing(const MatchMatrix& matrix, + MatchResultListener* listener) const; + + MatcherDescriberVec& matcher_describers() { + return matcher_describers_; + } + + static Message Elements(size_t n) { + return Message() << n << " element" << (n == 1 ? "" : "s"); + } + + UnorderedMatcherRequire::Flags match_flags() const { return match_flags_; } + + private: + UnorderedMatcherRequire::Flags match_flags_; + MatcherDescriberVec matcher_describers_; +}; + +// Implements UnorderedElementsAre, UnorderedElementsAreArray, IsSubsetOf, and +// IsSupersetOf. +template <typename Container> +class UnorderedElementsAreMatcherImpl + : public MatcherInterface<Container>, + public UnorderedElementsAreMatcherImplBase { + public: + typedef GTEST_REMOVE_REFERENCE_AND_CONST_(Container) RawContainer; + typedef internal::StlContainerView<RawContainer> View; + typedef typename View::type StlContainer; + typedef typename View::const_reference StlContainerReference; + typedef typename StlContainer::const_iterator StlContainerConstIterator; + typedef typename StlContainer::value_type Element; + + template <typename InputIter> + UnorderedElementsAreMatcherImpl(UnorderedMatcherRequire::Flags matcher_flags, + InputIter first, InputIter last) + : UnorderedElementsAreMatcherImplBase(matcher_flags) { + for (; first != last; ++first) { + matchers_.push_back(MatcherCast<const Element&>(*first)); + matcher_describers().push_back(matchers_.back().GetDescriber()); + } + } + + // Describes what this matcher does. + void DescribeTo(::std::ostream* os) const override { + return UnorderedElementsAreMatcherImplBase::DescribeToImpl(os); + } + + // Describes what the negation of this matcher does. + void DescribeNegationTo(::std::ostream* os) const override { + return UnorderedElementsAreMatcherImplBase::DescribeNegationToImpl(os); + } + + bool MatchAndExplain(Container container, + MatchResultListener* listener) const override { + StlContainerReference stl_container = View::ConstReference(container); + ::std::vector<std::string> element_printouts; + MatchMatrix matrix = + AnalyzeElements(stl_container.begin(), stl_container.end(), + &element_printouts, listener); + + if (matrix.LhsSize() == 0 && matrix.RhsSize() == 0) { + return true; + } + + if (match_flags() == UnorderedMatcherRequire::ExactMatch) { + if (matrix.LhsSize() != matrix.RhsSize()) { + // The element count doesn't match. If the container is empty, + // there's no need to explain anything as Google Mock already + // prints the empty container. Otherwise we just need to show + // how many elements there actually are. + if (matrix.LhsSize() != 0 && listener->IsInterested()) { + *listener << "which has " << Elements(matrix.LhsSize()); + } + return false; + } + } + + return VerifyMatchMatrix(element_printouts, matrix, listener) && + FindPairing(matrix, listener); + } + + private: + template <typename ElementIter> + MatchMatrix AnalyzeElements(ElementIter elem_first, ElementIter elem_last, + ::std::vector<std::string>* element_printouts, + MatchResultListener* listener) const { + element_printouts->clear(); + ::std::vector<char> did_match; + size_t num_elements = 0; + DummyMatchResultListener dummy; + for (; elem_first != elem_last; ++num_elements, ++elem_first) { + if (listener->IsInterested()) { + element_printouts->push_back(PrintToString(*elem_first)); + } + for (size_t irhs = 0; irhs != matchers_.size(); ++irhs) { + did_match.push_back( + matchers_[irhs].MatchAndExplain(*elem_first, &dummy)); + } + } + + MatchMatrix matrix(num_elements, matchers_.size()); + ::std::vector<char>::const_iterator did_match_iter = did_match.begin(); + for (size_t ilhs = 0; ilhs != num_elements; ++ilhs) { + for (size_t irhs = 0; irhs != matchers_.size(); ++irhs) { + matrix.SetEdge(ilhs, irhs, *did_match_iter++ != 0); + } + } + return matrix; + } + + ::std::vector<Matcher<const Element&> > matchers_; +}; + +// Functor for use in TransformTuple. +// Performs MatcherCast<Target> on an input argument of any type. +template <typename Target> +struct CastAndAppendTransform { + template <typename Arg> + Matcher<Target> operator()(const Arg& a) const { + return MatcherCast<Target>(a); + } +}; + +// Implements UnorderedElementsAre. +template <typename MatcherTuple> +class UnorderedElementsAreMatcher { + public: + explicit UnorderedElementsAreMatcher(const MatcherTuple& args) + : matchers_(args) {} + + template <typename Container> + operator Matcher<Container>() const { + typedef GTEST_REMOVE_REFERENCE_AND_CONST_(Container) RawContainer; + typedef typename internal::StlContainerView<RawContainer>::type View; + typedef typename View::value_type Element; + typedef ::std::vector<Matcher<const Element&> > MatcherVec; + MatcherVec matchers; + matchers.reserve(::std::tuple_size<MatcherTuple>::value); + TransformTupleValues(CastAndAppendTransform<const Element&>(), matchers_, + ::std::back_inserter(matchers)); + return Matcher<Container>( + new UnorderedElementsAreMatcherImpl<const Container&>( + UnorderedMatcherRequire::ExactMatch, matchers.begin(), + matchers.end())); + } + + private: + const MatcherTuple matchers_; +}; + +// Implements ElementsAre. +template <typename MatcherTuple> +class ElementsAreMatcher { + public: + explicit ElementsAreMatcher(const MatcherTuple& args) : matchers_(args) {} + + template <typename Container> + operator Matcher<Container>() const { + GTEST_COMPILE_ASSERT_( + !IsHashTable<GTEST_REMOVE_REFERENCE_AND_CONST_(Container)>::value || + ::std::tuple_size<MatcherTuple>::value < 2, + use_UnorderedElementsAre_with_hash_tables); + + typedef GTEST_REMOVE_REFERENCE_AND_CONST_(Container) RawContainer; + typedef typename internal::StlContainerView<RawContainer>::type View; + typedef typename View::value_type Element; + typedef ::std::vector<Matcher<const Element&> > MatcherVec; + MatcherVec matchers; + matchers.reserve(::std::tuple_size<MatcherTuple>::value); + TransformTupleValues(CastAndAppendTransform<const Element&>(), matchers_, + ::std::back_inserter(matchers)); + return Matcher<Container>(new ElementsAreMatcherImpl<const Container&>( + matchers.begin(), matchers.end())); + } + + private: + const MatcherTuple matchers_; +}; + +// Implements UnorderedElementsAreArray(), IsSubsetOf(), and IsSupersetOf(). +template <typename T> +class UnorderedElementsAreArrayMatcher { + public: + template <typename Iter> + UnorderedElementsAreArrayMatcher(UnorderedMatcherRequire::Flags match_flags, + Iter first, Iter last) + : match_flags_(match_flags), matchers_(first, last) {} + + template <typename Container> + operator Matcher<Container>() const { + return Matcher<Container>( + new UnorderedElementsAreMatcherImpl<const Container&>( + match_flags_, matchers_.begin(), matchers_.end())); + } + + private: + UnorderedMatcherRequire::Flags match_flags_; + ::std::vector<T> matchers_; +}; + +// Implements ElementsAreArray(). +template <typename T> +class ElementsAreArrayMatcher { + public: + template <typename Iter> + ElementsAreArrayMatcher(Iter first, Iter last) : matchers_(first, last) {} + + template <typename Container> + operator Matcher<Container>() const { + GTEST_COMPILE_ASSERT_( + !IsHashTable<GTEST_REMOVE_REFERENCE_AND_CONST_(Container)>::value, + use_UnorderedElementsAreArray_with_hash_tables); + + return Matcher<Container>(new ElementsAreMatcherImpl<const Container&>( + matchers_.begin(), matchers_.end())); + } + + private: + const ::std::vector<T> matchers_; +}; + +// Given a 2-tuple matcher tm of type Tuple2Matcher and a value second +// of type Second, BoundSecondMatcher<Tuple2Matcher, Second>(tm, +// second) is a polymorphic matcher that matches a value x if and only if +// tm matches tuple (x, second). Useful for implementing +// UnorderedPointwise() in terms of UnorderedElementsAreArray(). +// +// BoundSecondMatcher is copyable and assignable, as we need to put +// instances of this class in a vector when implementing +// UnorderedPointwise(). +template <typename Tuple2Matcher, typename Second> +class BoundSecondMatcher { + public: + BoundSecondMatcher(const Tuple2Matcher& tm, const Second& second) + : tuple2_matcher_(tm), second_value_(second) {} + + BoundSecondMatcher(const BoundSecondMatcher& other) = default; + + template <typename T> + operator Matcher<T>() const { + return MakeMatcher(new Impl<T>(tuple2_matcher_, second_value_)); + } + + // We have to define this for UnorderedPointwise() to compile in + // C++98 mode, as it puts BoundSecondMatcher instances in a vector, + // which requires the elements to be assignable in C++98. The + // compiler cannot generate the operator= for us, as Tuple2Matcher + // and Second may not be assignable. + // + // However, this should never be called, so the implementation just + // need to assert. + void operator=(const BoundSecondMatcher& /*rhs*/) { + GTEST_LOG_(FATAL) << "BoundSecondMatcher should never be assigned."; + } + + private: + template <typename T> + class Impl : public MatcherInterface<T> { + public: + typedef ::std::tuple<T, Second> ArgTuple; + + Impl(const Tuple2Matcher& tm, const Second& second) + : mono_tuple2_matcher_(SafeMatcherCast<const ArgTuple&>(tm)), + second_value_(second) {} + + void DescribeTo(::std::ostream* os) const override { + *os << "and "; + UniversalPrint(second_value_, os); + *os << " "; + mono_tuple2_matcher_.DescribeTo(os); + } + + bool MatchAndExplain(T x, MatchResultListener* listener) const override { + return mono_tuple2_matcher_.MatchAndExplain(ArgTuple(x, second_value_), + listener); + } + + private: + const Matcher<const ArgTuple&> mono_tuple2_matcher_; + const Second second_value_; + }; + + const Tuple2Matcher tuple2_matcher_; + const Second second_value_; +}; + +// Given a 2-tuple matcher tm and a value second, +// MatcherBindSecond(tm, second) returns a matcher that matches a +// value x if and only if tm matches tuple (x, second). Useful for +// implementing UnorderedPointwise() in terms of UnorderedElementsAreArray(). +template <typename Tuple2Matcher, typename Second> +BoundSecondMatcher<Tuple2Matcher, Second> MatcherBindSecond( + const Tuple2Matcher& tm, const Second& second) { + return BoundSecondMatcher<Tuple2Matcher, Second>(tm, second); +} + +// Returns the description for a matcher defined using the MATCHER*() +// macro where the user-supplied description string is "", if +// 'negation' is false; otherwise returns the description of the +// negation of the matcher. 'param_values' contains a list of strings +// that are the print-out of the matcher's parameters. +GTEST_API_ std::string FormatMatcherDescription(bool negation, + const char* matcher_name, + const Strings& param_values); + +// Implements a matcher that checks the value of a optional<> type variable. +template <typename ValueMatcher> +class OptionalMatcher { + public: + explicit OptionalMatcher(const ValueMatcher& value_matcher) + : value_matcher_(value_matcher) {} + + template <typename Optional> + operator Matcher<Optional>() const { + return Matcher<Optional>(new Impl<const Optional&>(value_matcher_)); + } + + template <typename Optional> + class Impl : public MatcherInterface<Optional> { + public: + typedef GTEST_REMOVE_REFERENCE_AND_CONST_(Optional) OptionalView; + typedef typename OptionalView::value_type ValueType; + explicit Impl(const ValueMatcher& value_matcher) + : value_matcher_(MatcherCast<ValueType>(value_matcher)) {} + + void DescribeTo(::std::ostream* os) const override { + *os << "value "; + value_matcher_.DescribeTo(os); + } + + void DescribeNegationTo(::std::ostream* os) const override { + *os << "value "; + value_matcher_.DescribeNegationTo(os); + } + + bool MatchAndExplain(Optional optional, + MatchResultListener* listener) const override { + if (!optional) { + *listener << "which is not engaged"; + return false; + } + const ValueType& value = *optional; + StringMatchResultListener value_listener; + const bool match = value_matcher_.MatchAndExplain(value, &value_listener); + *listener << "whose value " << PrintToString(value) + << (match ? " matches" : " doesn't match"); + PrintIfNotEmpty(value_listener.str(), listener->stream()); + return match; + } + + private: + const Matcher<ValueType> value_matcher_; + }; + + private: + const ValueMatcher value_matcher_; +}; + +namespace variant_matcher { +// Overloads to allow VariantMatcher to do proper ADL lookup. +template <typename T> +void holds_alternative() {} +template <typename T> +void get() {} + +// Implements a matcher that checks the value of a variant<> type variable. +template <typename T> +class VariantMatcher { + public: + explicit VariantMatcher(::testing::Matcher<const T&> matcher) + : matcher_(std::move(matcher)) {} + + template <typename Variant> + bool MatchAndExplain(const Variant& value, + ::testing::MatchResultListener* listener) const { + using std::get; + if (!listener->IsInterested()) { + return holds_alternative<T>(value) && matcher_.Matches(get<T>(value)); + } + + if (!holds_alternative<T>(value)) { + *listener << "whose value is not of type '" << GetTypeName() << "'"; + return false; + } + + const T& elem = get<T>(value); + StringMatchResultListener elem_listener; + const bool match = matcher_.MatchAndExplain(elem, &elem_listener); + *listener << "whose value " << PrintToString(elem) + << (match ? " matches" : " doesn't match"); + PrintIfNotEmpty(elem_listener.str(), listener->stream()); + return match; + } + + void DescribeTo(std::ostream* os) const { + *os << "is a variant<> with value of type '" << GetTypeName() + << "' and the value "; + matcher_.DescribeTo(os); + } + + void DescribeNegationTo(std::ostream* os) const { + *os << "is a variant<> with value of type other than '" << GetTypeName() + << "' or the value "; + matcher_.DescribeNegationTo(os); + } + + private: + static std::string GetTypeName() { +#if GTEST_HAS_RTTI + GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_( + return internal::GetTypeName<T>()); +#endif + return "the element type"; + } + + const ::testing::Matcher<const T&> matcher_; +}; + +} // namespace variant_matcher + +namespace any_cast_matcher { + +// Overloads to allow AnyCastMatcher to do proper ADL lookup. +template <typename T> +void any_cast() {} + +// Implements a matcher that any_casts the value. +template <typename T> +class AnyCastMatcher { + public: + explicit AnyCastMatcher(const ::testing::Matcher<const T&>& matcher) + : matcher_(matcher) {} + + template <typename AnyType> + bool MatchAndExplain(const AnyType& value, + ::testing::MatchResultListener* listener) const { + if (!listener->IsInterested()) { + const T* ptr = any_cast<T>(&value); + return ptr != nullptr && matcher_.Matches(*ptr); + } + + const T* elem = any_cast<T>(&value); + if (elem == nullptr) { + *listener << "whose value is not of type '" << GetTypeName() << "'"; + return false; + } + + StringMatchResultListener elem_listener; + const bool match = matcher_.MatchAndExplain(*elem, &elem_listener); + *listener << "whose value " << PrintToString(*elem) + << (match ? " matches" : " doesn't match"); + PrintIfNotEmpty(elem_listener.str(), listener->stream()); + return match; + } + + void DescribeTo(std::ostream* os) const { + *os << "is an 'any' type with value of type '" << GetTypeName() + << "' and the value "; + matcher_.DescribeTo(os); + } + + void DescribeNegationTo(std::ostream* os) const { + *os << "is an 'any' type with value of type other than '" << GetTypeName() + << "' or the value "; + matcher_.DescribeNegationTo(os); + } + + private: + static std::string GetTypeName() { +#if GTEST_HAS_RTTI + GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_( + return internal::GetTypeName<T>()); +#endif + return "the element type"; + } + + const ::testing::Matcher<const T&> matcher_; +}; + +} // namespace any_cast_matcher + +// Implements the Args() matcher. +template <class ArgsTuple, size_t... k> +class ArgsMatcherImpl : public MatcherInterface<ArgsTuple> { + public: + using RawArgsTuple = typename std::decay<ArgsTuple>::type; + using SelectedArgs = + std::tuple<typename std::tuple_element<k, RawArgsTuple>::type...>; + using MonomorphicInnerMatcher = Matcher<const SelectedArgs&>; + + template <typename InnerMatcher> + explicit ArgsMatcherImpl(const InnerMatcher& inner_matcher) + : inner_matcher_(SafeMatcherCast<const SelectedArgs&>(inner_matcher)) {} + + bool MatchAndExplain(ArgsTuple args, + MatchResultListener* listener) const override { + // Workaround spurious C4100 on MSVC<=15.7 when k is empty. + (void)args; + const SelectedArgs& selected_args = + std::forward_as_tuple(std::get<k>(args)...); + if (!listener->IsInterested()) return inner_matcher_.Matches(selected_args); + + PrintIndices(listener->stream()); + *listener << "are " << PrintToString(selected_args); + + StringMatchResultListener inner_listener; + const bool match = + inner_matcher_.MatchAndExplain(selected_args, &inner_listener); + PrintIfNotEmpty(inner_listener.str(), listener->stream()); + return match; + } + + void DescribeTo(::std::ostream* os) const override { + *os << "are a tuple "; + PrintIndices(os); + inner_matcher_.DescribeTo(os); + } + + void DescribeNegationTo(::std::ostream* os) const override { + *os << "are a tuple "; + PrintIndices(os); + inner_matcher_.DescribeNegationTo(os); + } + + private: + // Prints the indices of the selected fields. + static void PrintIndices(::std::ostream* os) { + *os << "whose fields ("; + const char* sep = ""; + // Workaround spurious C4189 on MSVC<=15.7 when k is empty. + (void)sep; + const char* dummy[] = {"", (*os << sep << "#" << k, sep = ", ")...}; + (void)dummy; + *os << ") "; + } + + MonomorphicInnerMatcher inner_matcher_; +}; + +template <class InnerMatcher, size_t... k> +class ArgsMatcher { + public: + explicit ArgsMatcher(InnerMatcher inner_matcher) + : inner_matcher_(std::move(inner_matcher)) {} + + template <typename ArgsTuple> + operator Matcher<ArgsTuple>() const { // NOLINT + return MakeMatcher(new ArgsMatcherImpl<ArgsTuple, k...>(inner_matcher_)); + } + + private: + InnerMatcher inner_matcher_; +}; + +} // namespace internal + +// ElementsAreArray(iterator_first, iterator_last) +// ElementsAreArray(pointer, count) +// ElementsAreArray(array) +// ElementsAreArray(container) +// ElementsAreArray({ e1, e2, ..., en }) +// +// The ElementsAreArray() functions are like ElementsAre(...), except +// that they are given a homogeneous sequence rather than taking each +// element as a function argument. The sequence can be specified as an +// array, a pointer and count, a vector, an initializer list, or an +// STL iterator range. In each of these cases, the underlying sequence +// can be either a sequence of values or a sequence of matchers. +// +// All forms of ElementsAreArray() make a copy of the input matcher sequence. + +template <typename Iter> +inline internal::ElementsAreArrayMatcher< + typename ::std::iterator_traits<Iter>::value_type> +ElementsAreArray(Iter first, Iter last) { + typedef typename ::std::iterator_traits<Iter>::value_type T; + return internal::ElementsAreArrayMatcher<T>(first, last); +} + +template <typename T> +inline internal::ElementsAreArrayMatcher<T> ElementsAreArray( + const T* pointer, size_t count) { + return ElementsAreArray(pointer, pointer + count); +} + +template <typename T, size_t N> +inline internal::ElementsAreArrayMatcher<T> ElementsAreArray( + const T (&array)[N]) { + return ElementsAreArray(array, N); +} + +template <typename Container> +inline internal::ElementsAreArrayMatcher<typename Container::value_type> +ElementsAreArray(const Container& container) { + return ElementsAreArray(container.begin(), container.end()); +} + +template <typename T> +inline internal::ElementsAreArrayMatcher<T> +ElementsAreArray(::std::initializer_list<T> xs) { + return ElementsAreArray(xs.begin(), xs.end()); +} + +// UnorderedElementsAreArray(iterator_first, iterator_last) +// UnorderedElementsAreArray(pointer, count) +// UnorderedElementsAreArray(array) +// UnorderedElementsAreArray(container) +// UnorderedElementsAreArray({ e1, e2, ..., en }) +// +// UnorderedElementsAreArray() verifies that a bijective mapping onto a +// collection of matchers exists. +// +// The matchers can be specified as an array, a pointer and count, a container, +// an initializer list, or an STL iterator range. In each of these cases, the +// underlying matchers can be either values or matchers. + +template <typename Iter> +inline internal::UnorderedElementsAreArrayMatcher< + typename ::std::iterator_traits<Iter>::value_type> +UnorderedElementsAreArray(Iter first, Iter last) { + typedef typename ::std::iterator_traits<Iter>::value_type T; + return internal::UnorderedElementsAreArrayMatcher<T>( + internal::UnorderedMatcherRequire::ExactMatch, first, last); +} + +template <typename T> +inline internal::UnorderedElementsAreArrayMatcher<T> +UnorderedElementsAreArray(const T* pointer, size_t count) { + return UnorderedElementsAreArray(pointer, pointer + count); +} + +template <typename T, size_t N> +inline internal::UnorderedElementsAreArrayMatcher<T> +UnorderedElementsAreArray(const T (&array)[N]) { + return UnorderedElementsAreArray(array, N); +} + +template <typename Container> +inline internal::UnorderedElementsAreArrayMatcher< + typename Container::value_type> +UnorderedElementsAreArray(const Container& container) { + return UnorderedElementsAreArray(container.begin(), container.end()); +} + +template <typename T> +inline internal::UnorderedElementsAreArrayMatcher<T> +UnorderedElementsAreArray(::std::initializer_list<T> xs) { + return UnorderedElementsAreArray(xs.begin(), xs.end()); +} + +// _ is a matcher that matches anything of any type. +// +// This definition is fine as: +// +// 1. The C++ standard permits using the name _ in a namespace that +// is not the global namespace or ::std. +// 2. The AnythingMatcher class has no data member or constructor, +// so it's OK to create global variables of this type. +// 3. c-style has approved of using _ in this case. +const internal::AnythingMatcher _ = {}; +// Creates a matcher that matches any value of the given type T. +template <typename T> +inline Matcher<T> A() { + return Matcher<T>(new internal::AnyMatcherImpl<T>()); +} + +// Creates a matcher that matches any value of the given type T. +template <typename T> +inline Matcher<T> An() { return A<T>(); } + +template <typename T, typename M> +Matcher<T> internal::MatcherCastImpl<T, M>::CastImpl( + const M& value, std::false_type /* convertible_to_matcher */, + std::false_type /* convertible_to_T */) { + return Eq(value); +} + +// Creates a polymorphic matcher that matches any NULL pointer. +inline PolymorphicMatcher<internal::IsNullMatcher > IsNull() { + return MakePolymorphicMatcher(internal::IsNullMatcher()); +} + +// Creates a polymorphic matcher that matches any non-NULL pointer. +// This is convenient as Not(NULL) doesn't compile (the compiler +// thinks that that expression is comparing a pointer with an integer). +inline PolymorphicMatcher<internal::NotNullMatcher > NotNull() { + return MakePolymorphicMatcher(internal::NotNullMatcher()); +} + +// Creates a polymorphic matcher that matches any argument that +// references variable x. +template <typename T> +inline internal::RefMatcher<T&> Ref(T& x) { // NOLINT + return internal::RefMatcher<T&>(x); +} + +// Creates a polymorphic matcher that matches any NaN floating point. +inline PolymorphicMatcher<internal::IsNanMatcher> IsNan() { + return MakePolymorphicMatcher(internal::IsNanMatcher()); +} + +// Creates a matcher that matches any double argument approximately +// equal to rhs, where two NANs are considered unequal. +inline internal::FloatingEqMatcher<double> DoubleEq(double rhs) { + return internal::FloatingEqMatcher<double>(rhs, false); +} + +// Creates a matcher that matches any double argument approximately +// equal to rhs, including NaN values when rhs is NaN. +inline internal::FloatingEqMatcher<double> NanSensitiveDoubleEq(double rhs) { + return internal::FloatingEqMatcher<double>(rhs, true); +} + +// Creates a matcher that matches any double argument approximately equal to +// rhs, up to the specified max absolute error bound, where two NANs are +// considered unequal. The max absolute error bound must be non-negative. +inline internal::FloatingEqMatcher<double> DoubleNear( + double rhs, double max_abs_error) { + return internal::FloatingEqMatcher<double>(rhs, false, max_abs_error); +} + +// Creates a matcher that matches any double argument approximately equal to +// rhs, up to the specified max absolute error bound, including NaN values when +// rhs is NaN. The max absolute error bound must be non-negative. +inline internal::FloatingEqMatcher<double> NanSensitiveDoubleNear( + double rhs, double max_abs_error) { + return internal::FloatingEqMatcher<double>(rhs, true, max_abs_error); +} + +// Creates a matcher that matches any float argument approximately +// equal to rhs, where two NANs are considered unequal. +inline internal::FloatingEqMatcher<float> FloatEq(float rhs) { + return internal::FloatingEqMatcher<float>(rhs, false); +} + +// Creates a matcher that matches any float argument approximately +// equal to rhs, including NaN values when rhs is NaN. +inline internal::FloatingEqMatcher<float> NanSensitiveFloatEq(float rhs) { + return internal::FloatingEqMatcher<float>(rhs, true); +} + +// Creates a matcher that matches any float argument approximately equal to +// rhs, up to the specified max absolute error bound, where two NANs are +// considered unequal. The max absolute error bound must be non-negative. +inline internal::FloatingEqMatcher<float> FloatNear( + float rhs, float max_abs_error) { + return internal::FloatingEqMatcher<float>(rhs, false, max_abs_error); +} + +// Creates a matcher that matches any float argument approximately equal to +// rhs, up to the specified max absolute error bound, including NaN values when +// rhs is NaN. The max absolute error bound must be non-negative. +inline internal::FloatingEqMatcher<float> NanSensitiveFloatNear( + float rhs, float max_abs_error) { + return internal::FloatingEqMatcher<float>(rhs, true, max_abs_error); +} + +// Creates a matcher that matches a pointer (raw or smart) that points +// to a value that matches inner_matcher. +template <typename InnerMatcher> +inline internal::PointeeMatcher<InnerMatcher> Pointee( + const InnerMatcher& inner_matcher) { + return internal::PointeeMatcher<InnerMatcher>(inner_matcher); +} + +#if GTEST_HAS_RTTI +// Creates a matcher that matches a pointer or reference that matches +// inner_matcher when dynamic_cast<To> is applied. +// The result of dynamic_cast<To> is forwarded to the inner matcher. +// If To is a pointer and the cast fails, the inner matcher will receive NULL. +// If To is a reference and the cast fails, this matcher returns false +// immediately. +template <typename To> +inline PolymorphicMatcher<internal::WhenDynamicCastToMatcher<To> > +WhenDynamicCastTo(const Matcher<To>& inner_matcher) { + return MakePolymorphicMatcher( + internal::WhenDynamicCastToMatcher<To>(inner_matcher)); +} +#endif // GTEST_HAS_RTTI + +// Creates a matcher that matches an object whose given field matches +// 'matcher'. For example, +// Field(&Foo::number, Ge(5)) +// matches a Foo object x if and only if x.number >= 5. +template <typename Class, typename FieldType, typename FieldMatcher> +inline PolymorphicMatcher< + internal::FieldMatcher<Class, FieldType> > Field( + FieldType Class::*field, const FieldMatcher& matcher) { + return MakePolymorphicMatcher( + internal::FieldMatcher<Class, FieldType>( + field, MatcherCast<const FieldType&>(matcher))); + // The call to MatcherCast() is required for supporting inner + // matchers of compatible types. For example, it allows + // Field(&Foo::bar, m) + // to compile where bar is an int32 and m is a matcher for int64. +} + +// Same as Field() but also takes the name of the field to provide better error +// messages. +template <typename Class, typename FieldType, typename FieldMatcher> +inline PolymorphicMatcher<internal::FieldMatcher<Class, FieldType> > Field( + const std::string& field_name, FieldType Class::*field, + const FieldMatcher& matcher) { + return MakePolymorphicMatcher(internal::FieldMatcher<Class, FieldType>( + field_name, field, MatcherCast<const FieldType&>(matcher))); +} + +// Creates a matcher that matches an object whose given property +// matches 'matcher'. For example, +// Property(&Foo::str, StartsWith("hi")) +// matches a Foo object x if and only if x.str() starts with "hi". +template <typename Class, typename PropertyType, typename PropertyMatcher> +inline PolymorphicMatcher<internal::PropertyMatcher< + Class, PropertyType, PropertyType (Class::*)() const> > +Property(PropertyType (Class::*property)() const, + const PropertyMatcher& matcher) { + return MakePolymorphicMatcher( + internal::PropertyMatcher<Class, PropertyType, + PropertyType (Class::*)() const>( + property, MatcherCast<const PropertyType&>(matcher))); + // The call to MatcherCast() is required for supporting inner + // matchers of compatible types. For example, it allows + // Property(&Foo::bar, m) + // to compile where bar() returns an int32 and m is a matcher for int64. +} + +// Same as Property() above, but also takes the name of the property to provide +// better error messages. +template <typename Class, typename PropertyType, typename PropertyMatcher> +inline PolymorphicMatcher<internal::PropertyMatcher< + Class, PropertyType, PropertyType (Class::*)() const> > +Property(const std::string& property_name, + PropertyType (Class::*property)() const, + const PropertyMatcher& matcher) { + return MakePolymorphicMatcher( + internal::PropertyMatcher<Class, PropertyType, + PropertyType (Class::*)() const>( + property_name, property, MatcherCast<const PropertyType&>(matcher))); +} + +// The same as above but for reference-qualified member functions. +template <typename Class, typename PropertyType, typename PropertyMatcher> +inline PolymorphicMatcher<internal::PropertyMatcher< + Class, PropertyType, PropertyType (Class::*)() const &> > +Property(PropertyType (Class::*property)() const &, + const PropertyMatcher& matcher) { + return MakePolymorphicMatcher( + internal::PropertyMatcher<Class, PropertyType, + PropertyType (Class::*)() const&>( + property, MatcherCast<const PropertyType&>(matcher))); +} + +// Three-argument form for reference-qualified member functions. +template <typename Class, typename PropertyType, typename PropertyMatcher> +inline PolymorphicMatcher<internal::PropertyMatcher< + Class, PropertyType, PropertyType (Class::*)() const &> > +Property(const std::string& property_name, + PropertyType (Class::*property)() const &, + const PropertyMatcher& matcher) { + return MakePolymorphicMatcher( + internal::PropertyMatcher<Class, PropertyType, + PropertyType (Class::*)() const&>( + property_name, property, MatcherCast<const PropertyType&>(matcher))); +} + +// Creates a matcher that matches an object if and only if the result of +// applying a callable to x matches 'matcher'. For example, +// ResultOf(f, StartsWith("hi")) +// matches a Foo object x if and only if f(x) starts with "hi". +// `callable` parameter can be a function, function pointer, or a functor. It is +// required to keep no state affecting the results of the calls on it and make +// no assumptions about how many calls will be made. Any state it keeps must be +// protected from the concurrent access. +template <typename Callable, typename InnerMatcher> +internal::ResultOfMatcher<Callable, InnerMatcher> ResultOf( + Callable callable, InnerMatcher matcher) { + return internal::ResultOfMatcher<Callable, InnerMatcher>( + std::move(callable), std::move(matcher)); +} + +// String matchers. + +// Matches a string equal to str. +template <typename T = std::string> +PolymorphicMatcher<internal::StrEqualityMatcher<std::string> > StrEq( + const internal::StringLike<T>& str) { + return MakePolymorphicMatcher( + internal::StrEqualityMatcher<std::string>(std::string(str), true, true)); +} + +// Matches a string not equal to str. +template <typename T = std::string> +PolymorphicMatcher<internal::StrEqualityMatcher<std::string> > StrNe( + const internal::StringLike<T>& str) { + return MakePolymorphicMatcher( + internal::StrEqualityMatcher<std::string>(std::string(str), false, true)); +} + +// Matches a string equal to str, ignoring case. +template <typename T = std::string> +PolymorphicMatcher<internal::StrEqualityMatcher<std::string> > StrCaseEq( + const internal::StringLike<T>& str) { + return MakePolymorphicMatcher( + internal::StrEqualityMatcher<std::string>(std::string(str), true, false)); +} + +// Matches a string not equal to str, ignoring case. +template <typename T = std::string> +PolymorphicMatcher<internal::StrEqualityMatcher<std::string> > StrCaseNe( + const internal::StringLike<T>& str) { + return MakePolymorphicMatcher(internal::StrEqualityMatcher<std::string>( + std::string(str), false, false)); +} + +// Creates a matcher that matches any string, std::string, or C string +// that contains the given substring. +template <typename T = std::string> +PolymorphicMatcher<internal::HasSubstrMatcher<std::string> > HasSubstr( + const internal::StringLike<T>& substring) { + return MakePolymorphicMatcher( + internal::HasSubstrMatcher<std::string>(std::string(substring))); +} + +// Matches a string that starts with 'prefix' (case-sensitive). +template <typename T = std::string> +PolymorphicMatcher<internal::StartsWithMatcher<std::string> > StartsWith( + const internal::StringLike<T>& prefix) { + return MakePolymorphicMatcher( + internal::StartsWithMatcher<std::string>(std::string(prefix))); +} + +// Matches a string that ends with 'suffix' (case-sensitive). +template <typename T = std::string> +PolymorphicMatcher<internal::EndsWithMatcher<std::string> > EndsWith( + const internal::StringLike<T>& suffix) { + return MakePolymorphicMatcher( + internal::EndsWithMatcher<std::string>(std::string(suffix))); +} + +#if GTEST_HAS_STD_WSTRING +// Wide string matchers. + +// Matches a string equal to str. +inline PolymorphicMatcher<internal::StrEqualityMatcher<std::wstring> > StrEq( + const std::wstring& str) { + return MakePolymorphicMatcher( + internal::StrEqualityMatcher<std::wstring>(str, true, true)); +} + +// Matches a string not equal to str. +inline PolymorphicMatcher<internal::StrEqualityMatcher<std::wstring> > StrNe( + const std::wstring& str) { + return MakePolymorphicMatcher( + internal::StrEqualityMatcher<std::wstring>(str, false, true)); +} + +// Matches a string equal to str, ignoring case. +inline PolymorphicMatcher<internal::StrEqualityMatcher<std::wstring> > +StrCaseEq(const std::wstring& str) { + return MakePolymorphicMatcher( + internal::StrEqualityMatcher<std::wstring>(str, true, false)); +} + +// Matches a string not equal to str, ignoring case. +inline PolymorphicMatcher<internal::StrEqualityMatcher<std::wstring> > +StrCaseNe(const std::wstring& str) { + return MakePolymorphicMatcher( + internal::StrEqualityMatcher<std::wstring>(str, false, false)); +} + +// Creates a matcher that matches any ::wstring, std::wstring, or C wide string +// that contains the given substring. +inline PolymorphicMatcher<internal::HasSubstrMatcher<std::wstring> > HasSubstr( + const std::wstring& substring) { + return MakePolymorphicMatcher( + internal::HasSubstrMatcher<std::wstring>(substring)); +} + +// Matches a string that starts with 'prefix' (case-sensitive). +inline PolymorphicMatcher<internal::StartsWithMatcher<std::wstring> > +StartsWith(const std::wstring& prefix) { + return MakePolymorphicMatcher( + internal::StartsWithMatcher<std::wstring>(prefix)); +} + +// Matches a string that ends with 'suffix' (case-sensitive). +inline PolymorphicMatcher<internal::EndsWithMatcher<std::wstring> > EndsWith( + const std::wstring& suffix) { + return MakePolymorphicMatcher( + internal::EndsWithMatcher<std::wstring>(suffix)); +} + +#endif // GTEST_HAS_STD_WSTRING + +// Creates a polymorphic matcher that matches a 2-tuple where the +// first field == the second field. +inline internal::Eq2Matcher Eq() { return internal::Eq2Matcher(); } + +// Creates a polymorphic matcher that matches a 2-tuple where the +// first field >= the second field. +inline internal::Ge2Matcher Ge() { return internal::Ge2Matcher(); } + +// Creates a polymorphic matcher that matches a 2-tuple where the +// first field > the second field. +inline internal::Gt2Matcher Gt() { return internal::Gt2Matcher(); } + +// Creates a polymorphic matcher that matches a 2-tuple where the +// first field <= the second field. +inline internal::Le2Matcher Le() { return internal::Le2Matcher(); } + +// Creates a polymorphic matcher that matches a 2-tuple where the +// first field < the second field. +inline internal::Lt2Matcher Lt() { return internal::Lt2Matcher(); } + +// Creates a polymorphic matcher that matches a 2-tuple where the +// first field != the second field. +inline internal::Ne2Matcher Ne() { return internal::Ne2Matcher(); } + +// Creates a polymorphic matcher that matches a 2-tuple where +// FloatEq(first field) matches the second field. +inline internal::FloatingEq2Matcher<float> FloatEq() { + return internal::FloatingEq2Matcher<float>(); +} + +// Creates a polymorphic matcher that matches a 2-tuple where +// DoubleEq(first field) matches the second field. +inline internal::FloatingEq2Matcher<double> DoubleEq() { + return internal::FloatingEq2Matcher<double>(); +} + +// Creates a polymorphic matcher that matches a 2-tuple where +// FloatEq(first field) matches the second field with NaN equality. +inline internal::FloatingEq2Matcher<float> NanSensitiveFloatEq() { + return internal::FloatingEq2Matcher<float>(true); +} + +// Creates a polymorphic matcher that matches a 2-tuple where +// DoubleEq(first field) matches the second field with NaN equality. +inline internal::FloatingEq2Matcher<double> NanSensitiveDoubleEq() { + return internal::FloatingEq2Matcher<double>(true); +} + +// Creates a polymorphic matcher that matches a 2-tuple where +// FloatNear(first field, max_abs_error) matches the second field. +inline internal::FloatingEq2Matcher<float> FloatNear(float max_abs_error) { + return internal::FloatingEq2Matcher<float>(max_abs_error); +} + +// Creates a polymorphic matcher that matches a 2-tuple where +// DoubleNear(first field, max_abs_error) matches the second field. +inline internal::FloatingEq2Matcher<double> DoubleNear(double max_abs_error) { + return internal::FloatingEq2Matcher<double>(max_abs_error); +} + +// Creates a polymorphic matcher that matches a 2-tuple where +// FloatNear(first field, max_abs_error) matches the second field with NaN +// equality. +inline internal::FloatingEq2Matcher<float> NanSensitiveFloatNear( + float max_abs_error) { + return internal::FloatingEq2Matcher<float>(max_abs_error, true); +} + +// Creates a polymorphic matcher that matches a 2-tuple where +// DoubleNear(first field, max_abs_error) matches the second field with NaN +// equality. +inline internal::FloatingEq2Matcher<double> NanSensitiveDoubleNear( + double max_abs_error) { + return internal::FloatingEq2Matcher<double>(max_abs_error, true); +} + +// Creates a matcher that matches any value of type T that m doesn't +// match. +template <typename InnerMatcher> +inline internal::NotMatcher<InnerMatcher> Not(InnerMatcher m) { + return internal::NotMatcher<InnerMatcher>(m); +} + +// Returns a matcher that matches anything that satisfies the given +// predicate. The predicate can be any unary function or functor +// whose return type can be implicitly converted to bool. +template <typename Predicate> +inline PolymorphicMatcher<internal::TrulyMatcher<Predicate> > +Truly(Predicate pred) { + return MakePolymorphicMatcher(internal::TrulyMatcher<Predicate>(pred)); +} + +// Returns a matcher that matches the container size. The container must +// support both size() and size_type which all STL-like containers provide. +// Note that the parameter 'size' can be a value of type size_type as well as +// matcher. For instance: +// EXPECT_THAT(container, SizeIs(2)); // Checks container has 2 elements. +// EXPECT_THAT(container, SizeIs(Le(2)); // Checks container has at most 2. +template <typename SizeMatcher> +inline internal::SizeIsMatcher<SizeMatcher> +SizeIs(const SizeMatcher& size_matcher) { + return internal::SizeIsMatcher<SizeMatcher>(size_matcher); +} + +// Returns a matcher that matches the distance between the container's begin() +// iterator and its end() iterator, i.e. the size of the container. This matcher +// can be used instead of SizeIs with containers such as std::forward_list which +// do not implement size(). The container must provide const_iterator (with +// valid iterator_traits), begin() and end(). +template <typename DistanceMatcher> +inline internal::BeginEndDistanceIsMatcher<DistanceMatcher> +BeginEndDistanceIs(const DistanceMatcher& distance_matcher) { + return internal::BeginEndDistanceIsMatcher<DistanceMatcher>(distance_matcher); +} + +// Returns a matcher that matches an equal container. +// This matcher behaves like Eq(), but in the event of mismatch lists the +// values that are included in one container but not the other. (Duplicate +// values and order differences are not explained.) +template <typename Container> +inline PolymorphicMatcher<internal::ContainerEqMatcher< + typename std::remove_const<Container>::type>> +ContainerEq(const Container& rhs) { + return MakePolymorphicMatcher(internal::ContainerEqMatcher<Container>(rhs)); +} + +// Returns a matcher that matches a container that, when sorted using +// the given comparator, matches container_matcher. +template <typename Comparator, typename ContainerMatcher> +inline internal::WhenSortedByMatcher<Comparator, ContainerMatcher> +WhenSortedBy(const Comparator& comparator, + const ContainerMatcher& container_matcher) { + return internal::WhenSortedByMatcher<Comparator, ContainerMatcher>( + comparator, container_matcher); +} + +// Returns a matcher that matches a container that, when sorted using +// the < operator, matches container_matcher. +template <typename ContainerMatcher> +inline internal::WhenSortedByMatcher<internal::LessComparator, ContainerMatcher> +WhenSorted(const ContainerMatcher& container_matcher) { + return + internal::WhenSortedByMatcher<internal::LessComparator, ContainerMatcher>( + internal::LessComparator(), container_matcher); +} + +// Matches an STL-style container or a native array that contains the +// same number of elements as in rhs, where its i-th element and rhs's +// i-th element (as a pair) satisfy the given pair matcher, for all i. +// TupleMatcher must be able to be safely cast to Matcher<std::tuple<const +// T1&, const T2&> >, where T1 and T2 are the types of elements in the +// LHS container and the RHS container respectively. +template <typename TupleMatcher, typename Container> +inline internal::PointwiseMatcher<TupleMatcher, + typename std::remove_const<Container>::type> +Pointwise(const TupleMatcher& tuple_matcher, const Container& rhs) { + return internal::PointwiseMatcher<TupleMatcher, Container>(tuple_matcher, + rhs); +} + + +// Supports the Pointwise(m, {a, b, c}) syntax. +template <typename TupleMatcher, typename T> +inline internal::PointwiseMatcher<TupleMatcher, std::vector<T> > Pointwise( + const TupleMatcher& tuple_matcher, std::initializer_list<T> rhs) { + return Pointwise(tuple_matcher, std::vector<T>(rhs)); +} + + +// UnorderedPointwise(pair_matcher, rhs) matches an STL-style +// container or a native array that contains the same number of +// elements as in rhs, where in some permutation of the container, its +// i-th element and rhs's i-th element (as a pair) satisfy the given +// pair matcher, for all i. Tuple2Matcher must be able to be safely +// cast to Matcher<std::tuple<const T1&, const T2&> >, where T1 and T2 are +// the types of elements in the LHS container and the RHS container +// respectively. +// +// This is like Pointwise(pair_matcher, rhs), except that the element +// order doesn't matter. +template <typename Tuple2Matcher, typename RhsContainer> +inline internal::UnorderedElementsAreArrayMatcher< + typename internal::BoundSecondMatcher< + Tuple2Matcher, + typename internal::StlContainerView< + typename std::remove_const<RhsContainer>::type>::type::value_type>> +UnorderedPointwise(const Tuple2Matcher& tuple2_matcher, + const RhsContainer& rhs_container) { + // RhsView allows the same code to handle RhsContainer being a + // STL-style container and it being a native C-style array. + typedef typename internal::StlContainerView<RhsContainer> RhsView; + typedef typename RhsView::type RhsStlContainer; + typedef typename RhsStlContainer::value_type Second; + const RhsStlContainer& rhs_stl_container = + RhsView::ConstReference(rhs_container); + + // Create a matcher for each element in rhs_container. + ::std::vector<internal::BoundSecondMatcher<Tuple2Matcher, Second> > matchers; + for (typename RhsStlContainer::const_iterator it = rhs_stl_container.begin(); + it != rhs_stl_container.end(); ++it) { + matchers.push_back( + internal::MatcherBindSecond(tuple2_matcher, *it)); + } + + // Delegate the work to UnorderedElementsAreArray(). + return UnorderedElementsAreArray(matchers); +} + + +// Supports the UnorderedPointwise(m, {a, b, c}) syntax. +template <typename Tuple2Matcher, typename T> +inline internal::UnorderedElementsAreArrayMatcher< + typename internal::BoundSecondMatcher<Tuple2Matcher, T> > +UnorderedPointwise(const Tuple2Matcher& tuple2_matcher, + std::initializer_list<T> rhs) { + return UnorderedPointwise(tuple2_matcher, std::vector<T>(rhs)); +} + + +// Matches an STL-style container or a native array that contains at +// least one element matching the given value or matcher. +// +// Examples: +// ::std::set<int> page_ids; +// page_ids.insert(3); +// page_ids.insert(1); +// EXPECT_THAT(page_ids, Contains(1)); +// EXPECT_THAT(page_ids, Contains(Gt(2))); +// EXPECT_THAT(page_ids, Not(Contains(4))); +// +// ::std::map<int, size_t> page_lengths; +// page_lengths[1] = 100; +// EXPECT_THAT(page_lengths, +// Contains(::std::pair<const int, size_t>(1, 100))); +// +// const char* user_ids[] = { "joe", "mike", "tom" }; +// EXPECT_THAT(user_ids, Contains(Eq(::std::string("tom")))); +template <typename M> +inline internal::ContainsMatcher<M> Contains(M matcher) { + return internal::ContainsMatcher<M>(matcher); +} + +// IsSupersetOf(iterator_first, iterator_last) +// IsSupersetOf(pointer, count) +// IsSupersetOf(array) +// IsSupersetOf(container) +// IsSupersetOf({e1, e2, ..., en}) +// +// IsSupersetOf() verifies that a surjective partial mapping onto a collection +// of matchers exists. In other words, a container matches +// IsSupersetOf({e1, ..., en}) if and only if there is a permutation +// {y1, ..., yn} of some of the container's elements where y1 matches e1, +// ..., and yn matches en. Obviously, the size of the container must be >= n +// in order to have a match. Examples: +// +// - {1, 2, 3} matches IsSupersetOf({Ge(3), Ne(0)}), as 3 matches Ge(3) and +// 1 matches Ne(0). +// - {1, 2} doesn't match IsSupersetOf({Eq(1), Lt(2)}), even though 1 matches +// both Eq(1) and Lt(2). The reason is that different matchers must be used +// for elements in different slots of the container. +// - {1, 1, 2} matches IsSupersetOf({Eq(1), Lt(2)}), as (the first) 1 matches +// Eq(1) and (the second) 1 matches Lt(2). +// - {1, 2, 3} matches IsSupersetOf(Gt(1), Gt(1)), as 2 matches (the first) +// Gt(1) and 3 matches (the second) Gt(1). +// +// The matchers can be specified as an array, a pointer and count, a container, +// an initializer list, or an STL iterator range. In each of these cases, the +// underlying matchers can be either values or matchers. + +template <typename Iter> +inline internal::UnorderedElementsAreArrayMatcher< + typename ::std::iterator_traits<Iter>::value_type> +IsSupersetOf(Iter first, Iter last) { + typedef typename ::std::iterator_traits<Iter>::value_type T; + return internal::UnorderedElementsAreArrayMatcher<T>( + internal::UnorderedMatcherRequire::Superset, first, last); +} + +template <typename T> +inline internal::UnorderedElementsAreArrayMatcher<T> IsSupersetOf( + const T* pointer, size_t count) { + return IsSupersetOf(pointer, pointer + count); +} + +template <typename T, size_t N> +inline internal::UnorderedElementsAreArrayMatcher<T> IsSupersetOf( + const T (&array)[N]) { + return IsSupersetOf(array, N); +} + +template <typename Container> +inline internal::UnorderedElementsAreArrayMatcher< + typename Container::value_type> +IsSupersetOf(const Container& container) { + return IsSupersetOf(container.begin(), container.end()); +} + +template <typename T> +inline internal::UnorderedElementsAreArrayMatcher<T> IsSupersetOf( + ::std::initializer_list<T> xs) { + return IsSupersetOf(xs.begin(), xs.end()); +} + +// IsSubsetOf(iterator_first, iterator_last) +// IsSubsetOf(pointer, count) +// IsSubsetOf(array) +// IsSubsetOf(container) +// IsSubsetOf({e1, e2, ..., en}) +// +// IsSubsetOf() verifies that an injective mapping onto a collection of matchers +// exists. In other words, a container matches IsSubsetOf({e1, ..., en}) if and +// only if there is a subset of matchers {m1, ..., mk} which would match the +// container using UnorderedElementsAre. Obviously, the size of the container +// must be <= n in order to have a match. Examples: +// +// - {1} matches IsSubsetOf({Gt(0), Lt(0)}), as 1 matches Gt(0). +// - {1, -1} matches IsSubsetOf({Lt(0), Gt(0)}), as 1 matches Gt(0) and -1 +// matches Lt(0). +// - {1, 2} doesn't matches IsSubsetOf({Gt(0), Lt(0)}), even though 1 and 2 both +// match Gt(0). The reason is that different matchers must be used for +// elements in different slots of the container. +// +// The matchers can be specified as an array, a pointer and count, a container, +// an initializer list, or an STL iterator range. In each of these cases, the +// underlying matchers can be either values or matchers. + +template <typename Iter> +inline internal::UnorderedElementsAreArrayMatcher< + typename ::std::iterator_traits<Iter>::value_type> +IsSubsetOf(Iter first, Iter last) { + typedef typename ::std::iterator_traits<Iter>::value_type T; + return internal::UnorderedElementsAreArrayMatcher<T>( + internal::UnorderedMatcherRequire::Subset, first, last); +} + +template <typename T> +inline internal::UnorderedElementsAreArrayMatcher<T> IsSubsetOf( + const T* pointer, size_t count) { + return IsSubsetOf(pointer, pointer + count); +} + +template <typename T, size_t N> +inline internal::UnorderedElementsAreArrayMatcher<T> IsSubsetOf( + const T (&array)[N]) { + return IsSubsetOf(array, N); +} + +template <typename Container> +inline internal::UnorderedElementsAreArrayMatcher< + typename Container::value_type> +IsSubsetOf(const Container& container) { + return IsSubsetOf(container.begin(), container.end()); +} + +template <typename T> +inline internal::UnorderedElementsAreArrayMatcher<T> IsSubsetOf( + ::std::initializer_list<T> xs) { + return IsSubsetOf(xs.begin(), xs.end()); +} + +// Matches an STL-style container or a native array that contains only +// elements matching the given value or matcher. +// +// Each(m) is semantically equivalent to Not(Contains(Not(m))). Only +// the messages are different. +// +// Examples: +// ::std::set<int> page_ids; +// // Each(m) matches an empty container, regardless of what m is. +// EXPECT_THAT(page_ids, Each(Eq(1))); +// EXPECT_THAT(page_ids, Each(Eq(77))); +// +// page_ids.insert(3); +// EXPECT_THAT(page_ids, Each(Gt(0))); +// EXPECT_THAT(page_ids, Not(Each(Gt(4)))); +// page_ids.insert(1); +// EXPECT_THAT(page_ids, Not(Each(Lt(2)))); +// +// ::std::map<int, size_t> page_lengths; +// page_lengths[1] = 100; +// page_lengths[2] = 200; +// page_lengths[3] = 300; +// EXPECT_THAT(page_lengths, Not(Each(Pair(1, 100)))); +// EXPECT_THAT(page_lengths, Each(Key(Le(3)))); +// +// const char* user_ids[] = { "joe", "mike", "tom" }; +// EXPECT_THAT(user_ids, Not(Each(Eq(::std::string("tom"))))); +template <typename M> +inline internal::EachMatcher<M> Each(M matcher) { + return internal::EachMatcher<M>(matcher); +} + +// Key(inner_matcher) matches an std::pair whose 'first' field matches +// inner_matcher. For example, Contains(Key(Ge(5))) can be used to match an +// std::map that contains at least one element whose key is >= 5. +template <typename M> +inline internal::KeyMatcher<M> Key(M inner_matcher) { + return internal::KeyMatcher<M>(inner_matcher); +} + +// Pair(first_matcher, second_matcher) matches a std::pair whose 'first' field +// matches first_matcher and whose 'second' field matches second_matcher. For +// example, EXPECT_THAT(map_type, ElementsAre(Pair(Ge(5), "foo"))) can be used +// to match a std::map<int, string> that contains exactly one element whose key +// is >= 5 and whose value equals "foo". +template <typename FirstMatcher, typename SecondMatcher> +inline internal::PairMatcher<FirstMatcher, SecondMatcher> +Pair(FirstMatcher first_matcher, SecondMatcher second_matcher) { + return internal::PairMatcher<FirstMatcher, SecondMatcher>( + first_matcher, second_matcher); +} + +namespace no_adl { +// FieldsAre(matchers...) matches piecewise the fields of compatible structs. +// These include those that support `get<I>(obj)`, and when structured bindings +// are enabled any class that supports them. +// In particular, `std::tuple`, `std::pair`, `std::array` and aggregate types. +template <typename... M> +internal::FieldsAreMatcher<typename std::decay<M>::type...> FieldsAre( + M&&... matchers) { + return internal::FieldsAreMatcher<typename std::decay<M>::type...>( + std::forward<M>(matchers)...); +} + +// Creates a matcher that matches a pointer (raw or smart) that matches +// inner_matcher. +template <typename InnerMatcher> +inline internal::PointerMatcher<InnerMatcher> Pointer( + const InnerMatcher& inner_matcher) { + return internal::PointerMatcher<InnerMatcher>(inner_matcher); +} + +// Creates a matcher that matches an object that has an address that matches +// inner_matcher. +template <typename InnerMatcher> +inline internal::AddressMatcher<InnerMatcher> Address( + const InnerMatcher& inner_matcher) { + return internal::AddressMatcher<InnerMatcher>(inner_matcher); +} +} // namespace no_adl + +// Returns a predicate that is satisfied by anything that matches the +// given matcher. +template <typename M> +inline internal::MatcherAsPredicate<M> Matches(M matcher) { + return internal::MatcherAsPredicate<M>(matcher); +} + +// Returns true if and only if the value matches the matcher. +template <typename T, typename M> +inline bool Value(const T& value, M matcher) { + return testing::Matches(matcher)(value); +} + +// Matches the value against the given matcher and explains the match +// result to listener. +template <typename T, typename M> +inline bool ExplainMatchResult( + M matcher, const T& value, MatchResultListener* listener) { + return SafeMatcherCast<const T&>(matcher).MatchAndExplain(value, listener); +} + +// Returns a string representation of the given matcher. Useful for description +// strings of matchers defined using MATCHER_P* macros that accept matchers as +// their arguments. For example: +// +// MATCHER_P(XAndYThat, matcher, +// "X that " + DescribeMatcher<int>(matcher, negation) + +// " and Y that " + DescribeMatcher<double>(matcher, negation)) { +// return ExplainMatchResult(matcher, arg.x(), result_listener) && +// ExplainMatchResult(matcher, arg.y(), result_listener); +// } +template <typename T, typename M> +std::string DescribeMatcher(const M& matcher, bool negation = false) { + ::std::stringstream ss; + Matcher<T> monomorphic_matcher = SafeMatcherCast<T>(matcher); + if (negation) { + monomorphic_matcher.DescribeNegationTo(&ss); + } else { + monomorphic_matcher.DescribeTo(&ss); + } + return ss.str(); +} + +template <typename... Args> +internal::ElementsAreMatcher< + std::tuple<typename std::decay<const Args&>::type...>> +ElementsAre(const Args&... matchers) { + return internal::ElementsAreMatcher< + std::tuple<typename std::decay<const Args&>::type...>>( + std::make_tuple(matchers...)); +} + +template <typename... Args> +internal::UnorderedElementsAreMatcher< + std::tuple<typename std::decay<const Args&>::type...>> +UnorderedElementsAre(const Args&... matchers) { + return internal::UnorderedElementsAreMatcher< + std::tuple<typename std::decay<const Args&>::type...>>( + std::make_tuple(matchers...)); +} + +// Define variadic matcher versions. +template <typename... Args> +internal::AllOfMatcher<typename std::decay<const Args&>::type...> AllOf( + const Args&... matchers) { + return internal::AllOfMatcher<typename std::decay<const Args&>::type...>( + matchers...); +} + +template <typename... Args> +internal::AnyOfMatcher<typename std::decay<const Args&>::type...> AnyOf( + const Args&... matchers) { + return internal::AnyOfMatcher<typename std::decay<const Args&>::type...>( + matchers...); +} + +// AnyOfArray(array) +// AnyOfArray(pointer, count) +// AnyOfArray(container) +// AnyOfArray({ e1, e2, ..., en }) +// AnyOfArray(iterator_first, iterator_last) +// +// AnyOfArray() verifies whether a given value matches any member of a +// collection of matchers. +// +// AllOfArray(array) +// AllOfArray(pointer, count) +// AllOfArray(container) +// AllOfArray({ e1, e2, ..., en }) +// AllOfArray(iterator_first, iterator_last) +// +// AllOfArray() verifies whether a given value matches all members of a +// collection of matchers. +// +// The matchers can be specified as an array, a pointer and count, a container, +// an initializer list, or an STL iterator range. In each of these cases, the +// underlying matchers can be either values or matchers. + +template <typename Iter> +inline internal::AnyOfArrayMatcher< + typename ::std::iterator_traits<Iter>::value_type> +AnyOfArray(Iter first, Iter last) { + return internal::AnyOfArrayMatcher< + typename ::std::iterator_traits<Iter>::value_type>(first, last); +} + +template <typename Iter> +inline internal::AllOfArrayMatcher< + typename ::std::iterator_traits<Iter>::value_type> +AllOfArray(Iter first, Iter last) { + return internal::AllOfArrayMatcher< + typename ::std::iterator_traits<Iter>::value_type>(first, last); +} + +template <typename T> +inline internal::AnyOfArrayMatcher<T> AnyOfArray(const T* ptr, size_t count) { + return AnyOfArray(ptr, ptr + count); +} + +template <typename T> +inline internal::AllOfArrayMatcher<T> AllOfArray(const T* ptr, size_t count) { + return AllOfArray(ptr, ptr + count); +} + +template <typename T, size_t N> +inline internal::AnyOfArrayMatcher<T> AnyOfArray(const T (&array)[N]) { + return AnyOfArray(array, N); +} + +template <typename T, size_t N> +inline internal::AllOfArrayMatcher<T> AllOfArray(const T (&array)[N]) { + return AllOfArray(array, N); +} + +template <typename Container> +inline internal::AnyOfArrayMatcher<typename Container::value_type> AnyOfArray( + const Container& container) { + return AnyOfArray(container.begin(), container.end()); +} + +template <typename Container> +inline internal::AllOfArrayMatcher<typename Container::value_type> AllOfArray( + const Container& container) { + return AllOfArray(container.begin(), container.end()); +} + +template <typename T> +inline internal::AnyOfArrayMatcher<T> AnyOfArray( + ::std::initializer_list<T> xs) { + return AnyOfArray(xs.begin(), xs.end()); +} + +template <typename T> +inline internal::AllOfArrayMatcher<T> AllOfArray( + ::std::initializer_list<T> xs) { + return AllOfArray(xs.begin(), xs.end()); +} + +// Args<N1, N2, ..., Nk>(a_matcher) matches a tuple if the selected +// fields of it matches a_matcher. C++ doesn't support default +// arguments for function templates, so we have to overload it. +template <size_t... k, typename InnerMatcher> +internal::ArgsMatcher<typename std::decay<InnerMatcher>::type, k...> Args( + InnerMatcher&& matcher) { + return internal::ArgsMatcher<typename std::decay<InnerMatcher>::type, k...>( + std::forward<InnerMatcher>(matcher)); +} + +// AllArgs(m) is a synonym of m. This is useful in +// +// EXPECT_CALL(foo, Bar(_, _)).With(AllArgs(Eq())); +// +// which is easier to read than +// +// EXPECT_CALL(foo, Bar(_, _)).With(Eq()); +template <typename InnerMatcher> +inline InnerMatcher AllArgs(const InnerMatcher& matcher) { return matcher; } + +// Returns a matcher that matches the value of an optional<> type variable. +// The matcher implementation only uses '!arg' and requires that the optional<> +// type has a 'value_type' member type and that '*arg' is of type 'value_type' +// and is printable using 'PrintToString'. It is compatible with +// std::optional/std::experimental::optional. +// Note that to compare an optional type variable against nullopt you should +// use Eq(nullopt) and not Eq(Optional(nullopt)). The latter implies that the +// optional value contains an optional itself. +template <typename ValueMatcher> +inline internal::OptionalMatcher<ValueMatcher> Optional( + const ValueMatcher& value_matcher) { + return internal::OptionalMatcher<ValueMatcher>(value_matcher); +} + +// Returns a matcher that matches the value of a absl::any type variable. +template <typename T> +PolymorphicMatcher<internal::any_cast_matcher::AnyCastMatcher<T> > AnyWith( + const Matcher<const T&>& matcher) { + return MakePolymorphicMatcher( + internal::any_cast_matcher::AnyCastMatcher<T>(matcher)); +} + +// Returns a matcher that matches the value of a variant<> type variable. +// The matcher implementation uses ADL to find the holds_alternative and get +// functions. +// It is compatible with std::variant. +template <typename T> +PolymorphicMatcher<internal::variant_matcher::VariantMatcher<T> > VariantWith( + const Matcher<const T&>& matcher) { + return MakePolymorphicMatcher( + internal::variant_matcher::VariantMatcher<T>(matcher)); +} + +#if GTEST_HAS_EXCEPTIONS + +// Anything inside the `internal` namespace is internal to the implementation +// and must not be used in user code! +namespace internal { + +class WithWhatMatcherImpl { + public: + WithWhatMatcherImpl(Matcher<std::string> matcher) + : matcher_(std::move(matcher)) {} + + void DescribeTo(std::ostream* os) const { + *os << "contains .what() that "; + matcher_.DescribeTo(os); + } + + void DescribeNegationTo(std::ostream* os) const { + *os << "contains .what() that does not "; + matcher_.DescribeTo(os); + } + + template <typename Err> + bool MatchAndExplain(const Err& err, MatchResultListener* listener) const { + *listener << "which contains .what() that "; + return matcher_.MatchAndExplain(err.what(), listener); + } + + private: + const Matcher<std::string> matcher_; +}; + +inline PolymorphicMatcher<WithWhatMatcherImpl> WithWhat( + Matcher<std::string> m) { + return MakePolymorphicMatcher(WithWhatMatcherImpl(std::move(m))); +} + +template <typename Err> +class ExceptionMatcherImpl { + class NeverThrown { + public: + const char* what() const noexcept { + return "this exception should never be thrown"; + } + }; + + // If the matchee raises an exception of a wrong type, we'd like to + // catch it and print its message and type. To do that, we add an additional + // catch clause: + // + // try { ... } + // catch (const Err&) { /* an expected exception */ } + // catch (const std::exception&) { /* exception of a wrong type */ } + // + // However, if the `Err` itself is `std::exception`, we'd end up with two + // identical `catch` clauses: + // + // try { ... } + // catch (const std::exception&) { /* an expected exception */ } + // catch (const std::exception&) { /* exception of a wrong type */ } + // + // This can cause a warning or an error in some compilers. To resolve + // the issue, we use a fake error type whenever `Err` is `std::exception`: + // + // try { ... } + // catch (const std::exception&) { /* an expected exception */ } + // catch (const NeverThrown&) { /* exception of a wrong type */ } + using DefaultExceptionType = typename std::conditional< + std::is_same<typename std::remove_cv< + typename std::remove_reference<Err>::type>::type, + std::exception>::value, + const NeverThrown&, const std::exception&>::type; + + public: + ExceptionMatcherImpl(Matcher<const Err&> matcher) + : matcher_(std::move(matcher)) {} + + void DescribeTo(std::ostream* os) const { + *os << "throws an exception which is a " << GetTypeName<Err>(); + *os << " which "; + matcher_.DescribeTo(os); + } + + void DescribeNegationTo(std::ostream* os) const { + *os << "throws an exception which is not a " << GetTypeName<Err>(); + *os << " which "; + matcher_.DescribeNegationTo(os); + } + + template <typename T> + bool MatchAndExplain(T&& x, MatchResultListener* listener) const { + try { + (void)(std::forward<T>(x)()); + } catch (const Err& err) { + *listener << "throws an exception which is a " << GetTypeName<Err>(); + *listener << " "; + return matcher_.MatchAndExplain(err, listener); + } catch (DefaultExceptionType err) { +#if GTEST_HAS_RTTI + *listener << "throws an exception of type " << GetTypeName(typeid(err)); + *listener << " "; +#else + *listener << "throws an std::exception-derived type "; +#endif + *listener << "with description \"" << err.what() << "\""; + return false; + } catch (...) { + *listener << "throws an exception of an unknown type"; + return false; + } + + *listener << "does not throw any exception"; + return false; + } + + private: + const Matcher<const Err&> matcher_; +}; + +} // namespace internal + +// Throws() +// Throws(exceptionMatcher) +// ThrowsMessage(messageMatcher) +// +// This matcher accepts a callable and verifies that when invoked, it throws +// an exception with the given type and properties. +// +// Examples: +// +// EXPECT_THAT( +// []() { throw std::runtime_error("message"); }, +// Throws<std::runtime_error>()); +// +// EXPECT_THAT( +// []() { throw std::runtime_error("message"); }, +// ThrowsMessage<std::runtime_error>(HasSubstr("message"))); +// +// EXPECT_THAT( +// []() { throw std::runtime_error("message"); }, +// Throws<std::runtime_error>( +// Property(&std::runtime_error::what, HasSubstr("message")))); + +template <typename Err> +PolymorphicMatcher<internal::ExceptionMatcherImpl<Err>> Throws() { + return MakePolymorphicMatcher( + internal::ExceptionMatcherImpl<Err>(A<const Err&>())); +} + +template <typename Err, typename ExceptionMatcher> +PolymorphicMatcher<internal::ExceptionMatcherImpl<Err>> Throws( + const ExceptionMatcher& exception_matcher) { + // Using matcher cast allows users to pass a matcher of a more broad type. + // For example user may want to pass Matcher<std::exception> + // to Throws<std::runtime_error>, or Matcher<int64> to Throws<int32>. + return MakePolymorphicMatcher(internal::ExceptionMatcherImpl<Err>( + SafeMatcherCast<const Err&>(exception_matcher))); +} + +template <typename Err, typename MessageMatcher> +PolymorphicMatcher<internal::ExceptionMatcherImpl<Err>> ThrowsMessage( + MessageMatcher&& message_matcher) { + static_assert(std::is_base_of<std::exception, Err>::value, + "expected an std::exception-derived type"); + return Throws<Err>(internal::WithWhat( + MatcherCast<std::string>(std::forward<MessageMatcher>(message_matcher)))); +} + +#endif // GTEST_HAS_EXCEPTIONS + +// These macros allow using matchers to check values in Google Test +// tests. ASSERT_THAT(value, matcher) and EXPECT_THAT(value, matcher) +// succeed if and only if the value matches the matcher. If the assertion +// fails, the value and the description of the matcher will be printed. +#define ASSERT_THAT(value, matcher) ASSERT_PRED_FORMAT1(\ + ::testing::internal::MakePredicateFormatterFromMatcher(matcher), value) +#define EXPECT_THAT(value, matcher) EXPECT_PRED_FORMAT1(\ + ::testing::internal::MakePredicateFormatterFromMatcher(matcher), value) + +// MATCHER* macroses itself are listed below. +#define MATCHER(name, description) \ + class name##Matcher \ + : public ::testing::internal::MatcherBaseImpl<name##Matcher> { \ + public: \ + template <typename arg_type> \ + class gmock_Impl : public ::testing::MatcherInterface<const arg_type&> { \ + public: \ + gmock_Impl() {} \ + bool MatchAndExplain( \ + const arg_type& arg, \ + ::testing::MatchResultListener* result_listener) const override; \ + void DescribeTo(::std::ostream* gmock_os) const override { \ + *gmock_os << FormatDescription(false); \ + } \ + void DescribeNegationTo(::std::ostream* gmock_os) const override { \ + *gmock_os << FormatDescription(true); \ + } \ + \ + private: \ + ::std::string FormatDescription(bool negation) const { \ + ::std::string gmock_description = (description); \ + if (!gmock_description.empty()) { \ + return gmock_description; \ + } \ + return ::testing::internal::FormatMatcherDescription(negation, #name, \ + {}); \ + } \ + }; \ + }; \ + GTEST_ATTRIBUTE_UNUSED_ inline name##Matcher name() { return {}; } \ + template <typename arg_type> \ + bool name##Matcher::gmock_Impl<arg_type>::MatchAndExplain( \ + const arg_type& arg, \ + ::testing::MatchResultListener* result_listener GTEST_ATTRIBUTE_UNUSED_) \ + const + +#define MATCHER_P(name, p0, description) \ + GMOCK_INTERNAL_MATCHER(name, name##MatcherP, description, (p0)) +#define MATCHER_P2(name, p0, p1, description) \ + GMOCK_INTERNAL_MATCHER(name, name##MatcherP2, description, (p0, p1)) +#define MATCHER_P3(name, p0, p1, p2, description) \ + GMOCK_INTERNAL_MATCHER(name, name##MatcherP3, description, (p0, p1, p2)) +#define MATCHER_P4(name, p0, p1, p2, p3, description) \ + GMOCK_INTERNAL_MATCHER(name, name##MatcherP4, description, (p0, p1, p2, p3)) +#define MATCHER_P5(name, p0, p1, p2, p3, p4, description) \ + GMOCK_INTERNAL_MATCHER(name, name##MatcherP5, description, \ + (p0, p1, p2, p3, p4)) +#define MATCHER_P6(name, p0, p1, p2, p3, p4, p5, description) \ + GMOCK_INTERNAL_MATCHER(name, name##MatcherP6, description, \ + (p0, p1, p2, p3, p4, p5)) +#define MATCHER_P7(name, p0, p1, p2, p3, p4, p5, p6, description) \ + GMOCK_INTERNAL_MATCHER(name, name##MatcherP7, description, \ + (p0, p1, p2, p3, p4, p5, p6)) +#define MATCHER_P8(name, p0, p1, p2, p3, p4, p5, p6, p7, description) \ + GMOCK_INTERNAL_MATCHER(name, name##MatcherP8, description, \ + (p0, p1, p2, p3, p4, p5, p6, p7)) +#define MATCHER_P9(name, p0, p1, p2, p3, p4, p5, p6, p7, p8, description) \ + GMOCK_INTERNAL_MATCHER(name, name##MatcherP9, description, \ + (p0, p1, p2, p3, p4, p5, p6, p7, p8)) +#define MATCHER_P10(name, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, description) \ + GMOCK_INTERNAL_MATCHER(name, name##MatcherP10, description, \ + (p0, p1, p2, p3, p4, p5, p6, p7, p8, p9)) + +#define GMOCK_INTERNAL_MATCHER(name, full_name, description, args) \ + template <GMOCK_INTERNAL_MATCHER_TEMPLATE_PARAMS(args)> \ + class full_name : public ::testing::internal::MatcherBaseImpl< \ + full_name<GMOCK_INTERNAL_MATCHER_TYPE_PARAMS(args)>> { \ + public: \ + using full_name::MatcherBaseImpl::MatcherBaseImpl; \ + template <typename arg_type> \ + class gmock_Impl : public ::testing::MatcherInterface<const arg_type&> { \ + public: \ + explicit gmock_Impl(GMOCK_INTERNAL_MATCHER_FUNCTION_ARGS(args)) \ + : GMOCK_INTERNAL_MATCHER_FORWARD_ARGS(args) {} \ + bool MatchAndExplain( \ + const arg_type& arg, \ + ::testing::MatchResultListener* result_listener) const override; \ + void DescribeTo(::std::ostream* gmock_os) const override { \ + *gmock_os << FormatDescription(false); \ + } \ + void DescribeNegationTo(::std::ostream* gmock_os) const override { \ + *gmock_os << FormatDescription(true); \ + } \ + GMOCK_INTERNAL_MATCHER_MEMBERS(args) \ + \ + private: \ + ::std::string FormatDescription(bool negation) const { \ + ::std::string gmock_description = (description); \ + if (!gmock_description.empty()) { \ + return gmock_description; \ + } \ + return ::testing::internal::FormatMatcherDescription( \ + negation, #name, \ + ::testing::internal::UniversalTersePrintTupleFieldsToStrings( \ + ::std::tuple<GMOCK_INTERNAL_MATCHER_TYPE_PARAMS(args)>( \ + GMOCK_INTERNAL_MATCHER_MEMBERS_USAGE(args)))); \ + } \ + }; \ + }; \ + template <GMOCK_INTERNAL_MATCHER_TEMPLATE_PARAMS(args)> \ + inline full_name<GMOCK_INTERNAL_MATCHER_TYPE_PARAMS(args)> name( \ + GMOCK_INTERNAL_MATCHER_FUNCTION_ARGS(args)) { \ + return full_name<GMOCK_INTERNAL_MATCHER_TYPE_PARAMS(args)>( \ + GMOCK_INTERNAL_MATCHER_ARGS_USAGE(args)); \ + } \ + template <GMOCK_INTERNAL_MATCHER_TEMPLATE_PARAMS(args)> \ + template <typename arg_type> \ + bool full_name<GMOCK_INTERNAL_MATCHER_TYPE_PARAMS(args)>::gmock_Impl< \ + arg_type>::MatchAndExplain(const arg_type& arg, \ + ::testing::MatchResultListener* \ + result_listener GTEST_ATTRIBUTE_UNUSED_) \ + const + +#define GMOCK_INTERNAL_MATCHER_TEMPLATE_PARAMS(args) \ + GMOCK_PP_TAIL( \ + GMOCK_PP_FOR_EACH(GMOCK_INTERNAL_MATCHER_TEMPLATE_PARAM, , args)) +#define GMOCK_INTERNAL_MATCHER_TEMPLATE_PARAM(i_unused, data_unused, arg) \ + , typename arg##_type + +#define GMOCK_INTERNAL_MATCHER_TYPE_PARAMS(args) \ + GMOCK_PP_TAIL(GMOCK_PP_FOR_EACH(GMOCK_INTERNAL_MATCHER_TYPE_PARAM, , args)) +#define GMOCK_INTERNAL_MATCHER_TYPE_PARAM(i_unused, data_unused, arg) \ + , arg##_type + +#define GMOCK_INTERNAL_MATCHER_FUNCTION_ARGS(args) \ + GMOCK_PP_TAIL(dummy_first GMOCK_PP_FOR_EACH( \ + GMOCK_INTERNAL_MATCHER_FUNCTION_ARG, , args)) +#define GMOCK_INTERNAL_MATCHER_FUNCTION_ARG(i, data_unused, arg) \ + , arg##_type gmock_p##i + +#define GMOCK_INTERNAL_MATCHER_FORWARD_ARGS(args) \ + GMOCK_PP_TAIL(GMOCK_PP_FOR_EACH(GMOCK_INTERNAL_MATCHER_FORWARD_ARG, , args)) +#define GMOCK_INTERNAL_MATCHER_FORWARD_ARG(i, data_unused, arg) \ + , arg(::std::forward<arg##_type>(gmock_p##i)) + +#define GMOCK_INTERNAL_MATCHER_MEMBERS(args) \ + GMOCK_PP_FOR_EACH(GMOCK_INTERNAL_MATCHER_MEMBER, , args) +#define GMOCK_INTERNAL_MATCHER_MEMBER(i_unused, data_unused, arg) \ + const arg##_type arg; + +#define GMOCK_INTERNAL_MATCHER_MEMBERS_USAGE(args) \ + GMOCK_PP_TAIL(GMOCK_PP_FOR_EACH(GMOCK_INTERNAL_MATCHER_MEMBER_USAGE, , args)) +#define GMOCK_INTERNAL_MATCHER_MEMBER_USAGE(i_unused, data_unused, arg) , arg + +#define GMOCK_INTERNAL_MATCHER_ARGS_USAGE(args) \ + GMOCK_PP_TAIL(GMOCK_PP_FOR_EACH(GMOCK_INTERNAL_MATCHER_ARG_USAGE, , args)) +#define GMOCK_INTERNAL_MATCHER_ARG_USAGE(i, data_unused, arg_unused) \ + , gmock_p##i + +// To prevent ADL on certain functions we put them on a separate namespace. +using namespace no_adl; // NOLINT + +} // namespace testing + +GTEST_DISABLE_MSC_WARNINGS_POP_() // 4251 5046 + +// Include any custom callback matchers added by the local installation. +// We must include this header at the end to make sure it can use the +// declarations from this file. +#include "gmock/internal/custom/gmock-matchers.h" + +#endif // GMOCK_INCLUDE_GMOCK_GMOCK_MATCHERS_H_ diff --git a/src/googletest/googlemock/include/gmock/gmock-more-matchers.h b/src/googletest/googlemock/include/gmock/gmock-more-matchers.h new file mode 100644 index 000000000..b306dd603 --- /dev/null +++ b/src/googletest/googlemock/include/gmock/gmock-more-matchers.h @@ -0,0 +1,92 @@ +// Copyright 2013, 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 implements some matchers that depend on gmock-matchers.h. +// +// Note that tests are implemented in gmock-matchers_test.cc rather than +// gmock-more-matchers-test.cc. + +// GOOGLETEST_CM0002 DO NOT DELETE + +#ifndef GMOCK_INCLUDE_GMOCK_MORE_MATCHERS_H_ +#define GMOCK_INCLUDE_GMOCK_MORE_MATCHERS_H_ + +#include "gmock/gmock-matchers.h" + +namespace testing { + +// Silence C4100 (unreferenced formal +// parameter) for MSVC +#ifdef _MSC_VER +# pragma warning(push) +# pragma warning(disable:4100) +#if (_MSC_VER == 1900) +// and silence C4800 (C4800: 'int *const ': forcing value +// to bool 'true' or 'false') for MSVC 14 +# pragma warning(disable:4800) + #endif +#endif + +// Defines a matcher that matches an empty container. The container must +// support both size() and empty(), which all STL-like containers provide. +MATCHER(IsEmpty, negation ? "isn't empty" : "is empty") { + if (arg.empty()) { + return true; + } + *result_listener << "whose size is " << arg.size(); + return false; +} + +// Define a matcher that matches a value that evaluates in boolean +// context to true. Useful for types that define "explicit operator +// bool" operators and so can't be compared for equality with true +// and false. +MATCHER(IsTrue, negation ? "is false" : "is true") { + return static_cast<bool>(arg); +} + +// Define a matcher that matches a value that evaluates in boolean +// context to false. Useful for types that define "explicit operator +// bool" operators and so can't be compared for equality with true +// and false. +MATCHER(IsFalse, negation ? "is true" : "is false") { + return !static_cast<bool>(arg); +} + +#ifdef _MSC_VER +# pragma warning(pop) +#endif + + +} // namespace testing + +#endif // GMOCK_INCLUDE_GMOCK_MORE_MATCHERS_H_ diff --git a/src/googletest/googlemock/include/gmock/gmock-nice-strict.h b/src/googletest/googlemock/include/gmock/gmock-nice-strict.h new file mode 100644 index 000000000..8230058da --- /dev/null +++ b/src/googletest/googlemock/include/gmock/gmock-nice-strict.h @@ -0,0 +1,262 @@ +// 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. + + +// Implements class templates NiceMock, NaggyMock, and StrictMock. +// +// Given a mock class MockFoo that is created using Google Mock, +// NiceMock<MockFoo> is a subclass of MockFoo that allows +// uninteresting calls (i.e. calls to mock methods that have no +// EXPECT_CALL specs), NaggyMock<MockFoo> is a subclass of MockFoo +// that prints a warning when an uninteresting call occurs, and +// StrictMock<MockFoo> is a subclass of MockFoo that treats all +// uninteresting calls as errors. +// +// Currently a mock is naggy by default, so MockFoo and +// NaggyMock<MockFoo> behave like the same. However, we will soon +// switch the default behavior of mocks to be nice, as that in general +// leads to more maintainable tests. When that happens, MockFoo will +// stop behaving like NaggyMock<MockFoo> and start behaving like +// NiceMock<MockFoo>. +// +// NiceMock, NaggyMock, and StrictMock "inherit" the constructors of +// their respective base class. Therefore you can write +// NiceMock<MockFoo>(5, "a") to construct a nice mock where MockFoo +// has a constructor that accepts (int, const char*), for example. +// +// A known limitation is that NiceMock<MockFoo>, NaggyMock<MockFoo>, +// and StrictMock<MockFoo> only works for mock methods defined using +// the MOCK_METHOD* family of macros DIRECTLY in the MockFoo class. +// If a mock method is defined in a base class of MockFoo, the "nice" +// or "strict" modifier may not affect it, depending on the compiler. +// In particular, nesting NiceMock, NaggyMock, and StrictMock is NOT +// supported. + +// GOOGLETEST_CM0002 DO NOT DELETE + +#ifndef GMOCK_INCLUDE_GMOCK_GMOCK_NICE_STRICT_H_ +#define GMOCK_INCLUDE_GMOCK_GMOCK_NICE_STRICT_H_ + +#include <type_traits> + +#include "gmock/gmock-spec-builders.h" +#include "gmock/internal/gmock-port.h" + +namespace testing { +template <class MockClass> +class NiceMock; +template <class MockClass> +class NaggyMock; +template <class MockClass> +class StrictMock; + +namespace internal { +template <typename T> +std::true_type StrictnessModifierProbe(const NiceMock<T>&); +template <typename T> +std::true_type StrictnessModifierProbe(const NaggyMock<T>&); +template <typename T> +std::true_type StrictnessModifierProbe(const StrictMock<T>&); +std::false_type StrictnessModifierProbe(...); + +template <typename T> +constexpr bool HasStrictnessModifier() { + return decltype(StrictnessModifierProbe(std::declval<const T&>()))::value; +} + +// Base classes that register and deregister with testing::Mock to alter the +// default behavior around uninteresting calls. Inheriting from one of these +// classes first and then MockClass ensures the MockClass constructor is run +// after registration, and that the MockClass destructor runs before +// deregistration. This guarantees that MockClass's constructor and destructor +// run with the same level of strictness as its instance methods. + +#if GTEST_OS_WINDOWS && (defined(_MSC_VER) || defined(__clang__)) +// We need to mark these classes with this declspec to ensure that +// the empty base class optimization is performed. +#define GTEST_INTERNAL_EMPTY_BASE_CLASS __declspec(empty_bases) +#else +#define GTEST_INTERNAL_EMPTY_BASE_CLASS +#endif + +template <typename Base> +class NiceMockImpl { + public: + NiceMockImpl() { ::testing::Mock::AllowUninterestingCalls(this); } + + ~NiceMockImpl() { ::testing::Mock::UnregisterCallReaction(this); } +}; + +template <typename Base> +class NaggyMockImpl { + public: + NaggyMockImpl() { ::testing::Mock::WarnUninterestingCalls(this); } + + ~NaggyMockImpl() { ::testing::Mock::UnregisterCallReaction(this); } +}; + +template <typename Base> +class StrictMockImpl { + public: + StrictMockImpl() { ::testing::Mock::FailUninterestingCalls(this); } + + ~StrictMockImpl() { ::testing::Mock::UnregisterCallReaction(this); } +}; + +} // namespace internal + +template <class MockClass> +class GTEST_INTERNAL_EMPTY_BASE_CLASS NiceMock + : private internal::NiceMockImpl<MockClass>, + public MockClass { + public: + static_assert( + !internal::HasStrictnessModifier<MockClass>(), + "Can't apply NiceMock to a class hierarchy that already has a " + "strictness modifier. See " + "https://github.com/google/googletest/blob/master/googlemock/docs/" + "cook_book.md#the-nice-the-strict-and-the-naggy-nicestrictnaggy"); + NiceMock() : MockClass() { + static_assert(sizeof(*this) == sizeof(MockClass), + "The impl subclass shouldn't introduce any padding"); + } + + // Ideally, we would inherit base class's constructors through a using + // declaration, which would preserve their visibility. However, many existing + // tests rely on the fact that current implementation reexports protected + // constructors as public. These tests would need to be cleaned up first. + + // Single argument constructor is special-cased so that it can be + // made explicit. + template <typename A> + explicit NiceMock(A&& arg) : MockClass(std::forward<A>(arg)) { + static_assert(sizeof(*this) == sizeof(MockClass), + "The impl subclass shouldn't introduce any padding"); + } + + template <typename TArg1, typename TArg2, typename... An> + NiceMock(TArg1&& arg1, TArg2&& arg2, An&&... args) + : MockClass(std::forward<TArg1>(arg1), std::forward<TArg2>(arg2), + std::forward<An>(args)...) { + static_assert(sizeof(*this) == sizeof(MockClass), + "The impl subclass shouldn't introduce any padding"); + } + + private: + GTEST_DISALLOW_COPY_AND_ASSIGN_(NiceMock); +}; + +template <class MockClass> +class GTEST_INTERNAL_EMPTY_BASE_CLASS NaggyMock + : private internal::NaggyMockImpl<MockClass>, + public MockClass { + static_assert( + !internal::HasStrictnessModifier<MockClass>(), + "Can't apply NaggyMock to a class hierarchy that already has a " + "strictness modifier. See " + "https://github.com/google/googletest/blob/master/googlemock/docs/" + "cook_book.md#the-nice-the-strict-and-the-naggy-nicestrictnaggy"); + + public: + NaggyMock() : MockClass() { + static_assert(sizeof(*this) == sizeof(MockClass), + "The impl subclass shouldn't introduce any padding"); + } + + // Ideally, we would inherit base class's constructors through a using + // declaration, which would preserve their visibility. However, many existing + // tests rely on the fact that current implementation reexports protected + // constructors as public. These tests would need to be cleaned up first. + + // Single argument constructor is special-cased so that it can be + // made explicit. + template <typename A> + explicit NaggyMock(A&& arg) : MockClass(std::forward<A>(arg)) { + static_assert(sizeof(*this) == sizeof(MockClass), + "The impl subclass shouldn't introduce any padding"); + } + + template <typename TArg1, typename TArg2, typename... An> + NaggyMock(TArg1&& arg1, TArg2&& arg2, An&&... args) + : MockClass(std::forward<TArg1>(arg1), std::forward<TArg2>(arg2), + std::forward<An>(args)...) { + static_assert(sizeof(*this) == sizeof(MockClass), + "The impl subclass shouldn't introduce any padding"); + } + + private: + GTEST_DISALLOW_COPY_AND_ASSIGN_(NaggyMock); +}; + +template <class MockClass> +class GTEST_INTERNAL_EMPTY_BASE_CLASS StrictMock + : private internal::StrictMockImpl<MockClass>, + public MockClass { + public: + static_assert( + !internal::HasStrictnessModifier<MockClass>(), + "Can't apply StrictMock to a class hierarchy that already has a " + "strictness modifier. See " + "https://github.com/google/googletest/blob/master/googlemock/docs/" + "cook_book.md#the-nice-the-strict-and-the-naggy-nicestrictnaggy"); + StrictMock() : MockClass() { + static_assert(sizeof(*this) == sizeof(MockClass), + "The impl subclass shouldn't introduce any padding"); + } + + // Ideally, we would inherit base class's constructors through a using + // declaration, which would preserve their visibility. However, many existing + // tests rely on the fact that current implementation reexports protected + // constructors as public. These tests would need to be cleaned up first. + + // Single argument constructor is special-cased so that it can be + // made explicit. + template <typename A> + explicit StrictMock(A&& arg) : MockClass(std::forward<A>(arg)) { + static_assert(sizeof(*this) == sizeof(MockClass), + "The impl subclass shouldn't introduce any padding"); + } + + template <typename TArg1, typename TArg2, typename... An> + StrictMock(TArg1&& arg1, TArg2&& arg2, An&&... args) + : MockClass(std::forward<TArg1>(arg1), std::forward<TArg2>(arg2), + std::forward<An>(args)...) { + static_assert(sizeof(*this) == sizeof(MockClass), + "The impl subclass shouldn't introduce any padding"); + } + + private: + GTEST_DISALLOW_COPY_AND_ASSIGN_(StrictMock); +}; + +#undef GTEST_INTERNAL_EMPTY_BASE_CLASS + +} // namespace testing + +#endif // GMOCK_INCLUDE_GMOCK_GMOCK_NICE_STRICT_H_ diff --git a/src/googletest/googlemock/include/gmock/gmock-spec-builders.h b/src/googletest/googlemock/include/gmock/gmock-spec-builders.h new file mode 100644 index 000000000..d42d4cb7b --- /dev/null +++ b/src/googletest/googlemock/include/gmock/gmock-spec-builders.h @@ -0,0 +1,2036 @@ +// 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. + + +// Google Mock - a framework for writing C++ mock classes. +// +// This file implements the ON_CALL() and EXPECT_CALL() macros. +// +// A user can use the ON_CALL() macro to specify the default action of +// a mock method. The syntax is: +// +// ON_CALL(mock_object, Method(argument-matchers)) +// .With(multi-argument-matcher) +// .WillByDefault(action); +// +// where the .With() clause is optional. +// +// A user can use the EXPECT_CALL() macro to specify an expectation on +// a mock method. The syntax is: +// +// EXPECT_CALL(mock_object, Method(argument-matchers)) +// .With(multi-argument-matchers) +// .Times(cardinality) +// .InSequence(sequences) +// .After(expectations) +// .WillOnce(action) +// .WillRepeatedly(action) +// .RetiresOnSaturation(); +// +// where all clauses are optional, and .InSequence()/.After()/ +// .WillOnce() can appear any number of times. + +// GOOGLETEST_CM0002 DO NOT DELETE + +#ifndef GMOCK_INCLUDE_GMOCK_GMOCK_SPEC_BUILDERS_H_ +#define GMOCK_INCLUDE_GMOCK_GMOCK_SPEC_BUILDERS_H_ + +#include <functional> +#include <map> +#include <memory> +#include <set> +#include <sstream> +#include <string> +#include <type_traits> +#include <utility> +#include <vector> +#include "gmock/gmock-actions.h" +#include "gmock/gmock-cardinalities.h" +#include "gmock/gmock-matchers.h" +#include "gmock/internal/gmock-internal-utils.h" +#include "gmock/internal/gmock-port.h" +#include "gtest/gtest.h" + +#if GTEST_HAS_EXCEPTIONS +# include <stdexcept> // NOLINT +#endif + +GTEST_DISABLE_MSC_WARNINGS_PUSH_(4251 \ +/* class A needs to have dll-interface to be used by clients of class B */) + +namespace testing { + +// An abstract handle of an expectation. +class Expectation; + +// A set of expectation handles. +class ExpectationSet; + +// Anything inside the 'internal' namespace IS INTERNAL IMPLEMENTATION +// and MUST NOT BE USED IN USER CODE!!! +namespace internal { + +// Implements a mock function. +template <typename F> class FunctionMocker; + +// Base class for expectations. +class ExpectationBase; + +// Implements an expectation. +template <typename F> class TypedExpectation; + +// Helper class for testing the Expectation class template. +class ExpectationTester; + +// Helper classes for implementing NiceMock, StrictMock, and NaggyMock. +template <typename MockClass> +class NiceMockImpl; +template <typename MockClass> +class StrictMockImpl; +template <typename MockClass> +class NaggyMockImpl; + +// Protects the mock object registry (in class Mock), all function +// mockers, and all expectations. +// +// The reason we don't use more fine-grained protection is: when a +// mock function Foo() is called, it needs to consult its expectations +// to see which one should be picked. If another thread is allowed to +// call a mock function (either Foo() or a different one) at the same +// time, it could affect the "retired" attributes of Foo()'s +// expectations when InSequence() is used, and thus affect which +// expectation gets picked. Therefore, we sequence all mock function +// calls to ensure the integrity of the mock objects' states. +GTEST_API_ GTEST_DECLARE_STATIC_MUTEX_(g_gmock_mutex); + +// Untyped base class for ActionResultHolder<R>. +class UntypedActionResultHolderBase; + +// Abstract base class of FunctionMocker. This is the +// type-agnostic part of the function mocker interface. Its pure +// virtual methods are implemented by FunctionMocker. +class GTEST_API_ UntypedFunctionMockerBase { + public: + UntypedFunctionMockerBase(); + virtual ~UntypedFunctionMockerBase(); + + // Verifies that all expectations on this mock function have been + // satisfied. Reports one or more Google Test non-fatal failures + // and returns false if not. + bool VerifyAndClearExpectationsLocked() + GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex); + + // Clears the ON_CALL()s set on this mock function. + virtual void ClearDefaultActionsLocked() + GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) = 0; + + // In all of the following Untyped* functions, it's the caller's + // responsibility to guarantee the correctness of the arguments' + // types. + + // Performs the default action with the given arguments and returns + // the action's result. The call description string will be used in + // the error message to describe the call in the case the default + // action fails. + // L = * + virtual UntypedActionResultHolderBase* UntypedPerformDefaultAction( + void* untyped_args, const std::string& call_description) const = 0; + + // Performs the given action with the given arguments and returns + // the action's result. + // L = * + virtual UntypedActionResultHolderBase* UntypedPerformAction( + const void* untyped_action, void* untyped_args) const = 0; + + // Writes a message that the call is uninteresting (i.e. neither + // explicitly expected nor explicitly unexpected) to the given + // ostream. + virtual void UntypedDescribeUninterestingCall( + const void* untyped_args, + ::std::ostream* os) const + GTEST_LOCK_EXCLUDED_(g_gmock_mutex) = 0; + + // Returns the expectation that matches the given function arguments + // (or NULL is there's no match); when a match is found, + // untyped_action is set to point to the action that should be + // performed (or NULL if the action is "do default"), and + // is_excessive is modified to indicate whether the call exceeds the + // expected number. + virtual const ExpectationBase* UntypedFindMatchingExpectation( + const void* untyped_args, + const void** untyped_action, bool* is_excessive, + ::std::ostream* what, ::std::ostream* why) + GTEST_LOCK_EXCLUDED_(g_gmock_mutex) = 0; + + // Prints the given function arguments to the ostream. + virtual void UntypedPrintArgs(const void* untyped_args, + ::std::ostream* os) const = 0; + + // Sets the mock object this mock method belongs to, and registers + // this information in the global mock registry. Will be called + // whenever an EXPECT_CALL() or ON_CALL() is executed on this mock + // method. + void RegisterOwner(const void* mock_obj) + GTEST_LOCK_EXCLUDED_(g_gmock_mutex); + + // Sets the mock object this mock method belongs to, and sets the + // name of the mock function. Will be called upon each invocation + // of this mock function. + void SetOwnerAndName(const void* mock_obj, const char* name) + GTEST_LOCK_EXCLUDED_(g_gmock_mutex); + + // Returns the mock object this mock method belongs to. Must be + // called after RegisterOwner() or SetOwnerAndName() has been + // called. + const void* MockObject() const + GTEST_LOCK_EXCLUDED_(g_gmock_mutex); + + // Returns the name of this mock method. Must be called after + // SetOwnerAndName() has been called. + const char* Name() const + GTEST_LOCK_EXCLUDED_(g_gmock_mutex); + + // Returns the result of invoking this mock function with the given + // arguments. This function can be safely called from multiple + // threads concurrently. The caller is responsible for deleting the + // result. + UntypedActionResultHolderBase* UntypedInvokeWith(void* untyped_args) + GTEST_LOCK_EXCLUDED_(g_gmock_mutex); + + protected: + typedef std::vector<const void*> UntypedOnCallSpecs; + + using UntypedExpectations = std::vector<std::shared_ptr<ExpectationBase>>; + + // Returns an Expectation object that references and co-owns exp, + // which must be an expectation on this mock function. + Expectation GetHandleOf(ExpectationBase* exp); + + // Address of the mock object this mock method belongs to. Only + // valid after this mock method has been called or + // ON_CALL/EXPECT_CALL has been invoked on it. + const void* mock_obj_; // Protected by g_gmock_mutex. + + // Name of the function being mocked. Only valid after this mock + // method has been called. + const char* name_; // Protected by g_gmock_mutex. + + // All default action specs for this function mocker. + UntypedOnCallSpecs untyped_on_call_specs_; + + // All expectations for this function mocker. + // + // It's undefined behavior to interleave expectations (EXPECT_CALLs + // or ON_CALLs) and mock function calls. Also, the order of + // expectations is important. Therefore it's a logic race condition + // to read/write untyped_expectations_ concurrently. In order for + // tools like tsan to catch concurrent read/write accesses to + // untyped_expectations, we deliberately leave accesses to it + // unprotected. + UntypedExpectations untyped_expectations_; +}; // class UntypedFunctionMockerBase + +// Untyped base class for OnCallSpec<F>. +class UntypedOnCallSpecBase { + public: + // The arguments are the location of the ON_CALL() statement. + UntypedOnCallSpecBase(const char* a_file, int a_line) + : file_(a_file), line_(a_line), last_clause_(kNone) {} + + // Where in the source file was the default action spec defined? + const char* file() const { return file_; } + int line() const { return line_; } + + protected: + // Gives each clause in the ON_CALL() statement a name. + enum Clause { + // Do not change the order of the enum members! The run-time + // syntax checking relies on it. + kNone, + kWith, + kWillByDefault + }; + + // Asserts that the ON_CALL() statement has a certain property. + void AssertSpecProperty(bool property, + const std::string& failure_message) const { + Assert(property, file_, line_, failure_message); + } + + // Expects that the ON_CALL() statement has a certain property. + void ExpectSpecProperty(bool property, + const std::string& failure_message) const { + Expect(property, file_, line_, failure_message); + } + + const char* file_; + int line_; + + // The last clause in the ON_CALL() statement as seen so far. + // Initially kNone and changes as the statement is parsed. + Clause last_clause_; +}; // class UntypedOnCallSpecBase + +// This template class implements an ON_CALL spec. +template <typename F> +class OnCallSpec : public UntypedOnCallSpecBase { + public: + typedef typename Function<F>::ArgumentTuple ArgumentTuple; + typedef typename Function<F>::ArgumentMatcherTuple ArgumentMatcherTuple; + + // Constructs an OnCallSpec object from the information inside + // the parenthesis of an ON_CALL() statement. + OnCallSpec(const char* a_file, int a_line, + const ArgumentMatcherTuple& matchers) + : UntypedOnCallSpecBase(a_file, a_line), + matchers_(matchers), + // By default, extra_matcher_ should match anything. However, + // we cannot initialize it with _ as that causes ambiguity between + // Matcher's copy and move constructor for some argument types. + extra_matcher_(A<const ArgumentTuple&>()) {} + + // Implements the .With() clause. + OnCallSpec& With(const Matcher<const ArgumentTuple&>& m) { + // Makes sure this is called at most once. + ExpectSpecProperty(last_clause_ < kWith, + ".With() cannot appear " + "more than once in an ON_CALL()."); + last_clause_ = kWith; + + extra_matcher_ = m; + return *this; + } + + // Implements the .WillByDefault() clause. + OnCallSpec& WillByDefault(const Action<F>& action) { + ExpectSpecProperty(last_clause_ < kWillByDefault, + ".WillByDefault() must appear " + "exactly once in an ON_CALL()."); + last_clause_ = kWillByDefault; + + ExpectSpecProperty(!action.IsDoDefault(), + "DoDefault() cannot be used in ON_CALL()."); + action_ = action; + return *this; + } + + // Returns true if and only if the given arguments match the matchers. + bool Matches(const ArgumentTuple& args) const { + return TupleMatches(matchers_, args) && extra_matcher_.Matches(args); + } + + // Returns the action specified by the user. + const Action<F>& GetAction() const { + AssertSpecProperty(last_clause_ == kWillByDefault, + ".WillByDefault() must appear exactly " + "once in an ON_CALL()."); + return action_; + } + + private: + // The information in statement + // + // ON_CALL(mock_object, Method(matchers)) + // .With(multi-argument-matcher) + // .WillByDefault(action); + // + // is recorded in the data members like this: + // + // source file that contains the statement => file_ + // line number of the statement => line_ + // matchers => matchers_ + // multi-argument-matcher => extra_matcher_ + // action => action_ + ArgumentMatcherTuple matchers_; + Matcher<const ArgumentTuple&> extra_matcher_; + Action<F> action_; +}; // class OnCallSpec + +// Possible reactions on uninteresting calls. +enum CallReaction { + kAllow, + kWarn, + kFail, +}; + +} // namespace internal + +// Utilities for manipulating mock objects. +class GTEST_API_ Mock { + public: + // The following public methods can be called concurrently. + + // Tells Google Mock to ignore mock_obj when checking for leaked + // mock objects. + static void AllowLeak(const void* mock_obj) + GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex); + + // Verifies and clears all expectations on the given mock object. + // If the expectations aren't satisfied, generates one or more + // Google Test non-fatal failures and returns false. + static bool VerifyAndClearExpectations(void* mock_obj) + GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex); + + // Verifies all expectations on the given mock object and clears its + // default actions and expectations. Returns true if and only if the + // verification was successful. + static bool VerifyAndClear(void* mock_obj) + GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex); + + // Returns whether the mock was created as a naggy mock (default) + static bool IsNaggy(void* mock_obj) + GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex); + // Returns whether the mock was created as a nice mock + static bool IsNice(void* mock_obj) + GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex); + // Returns whether the mock was created as a strict mock + static bool IsStrict(void* mock_obj) + GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex); + + private: + friend class internal::UntypedFunctionMockerBase; + + // Needed for a function mocker to register itself (so that we know + // how to clear a mock object). + template <typename F> + friend class internal::FunctionMocker; + + template <typename MockClass> + friend class internal::NiceMockImpl; + template <typename MockClass> + friend class internal::NaggyMockImpl; + template <typename MockClass> + friend class internal::StrictMockImpl; + + // Tells Google Mock to allow uninteresting calls on the given mock + // object. + static void AllowUninterestingCalls(const void* mock_obj) + GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex); + + // Tells Google Mock to warn the user about uninteresting calls on + // the given mock object. + static void WarnUninterestingCalls(const void* mock_obj) + GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex); + + // Tells Google Mock to fail uninteresting calls on the given mock + // object. + static void FailUninterestingCalls(const void* mock_obj) + GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex); + + // Tells Google Mock the given mock object is being destroyed and + // its entry in the call-reaction table should be removed. + static void UnregisterCallReaction(const void* mock_obj) + GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex); + + // Returns the reaction Google Mock will have on uninteresting calls + // made on the given mock object. + static internal::CallReaction GetReactionOnUninterestingCalls( + const void* mock_obj) + GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex); + + // Verifies that all expectations on the given mock object have been + // satisfied. Reports one or more Google Test non-fatal failures + // and returns false if not. + static bool VerifyAndClearExpectationsLocked(void* mock_obj) + GTEST_EXCLUSIVE_LOCK_REQUIRED_(internal::g_gmock_mutex); + + // Clears all ON_CALL()s set on the given mock object. + static void ClearDefaultActionsLocked(void* mock_obj) + GTEST_EXCLUSIVE_LOCK_REQUIRED_(internal::g_gmock_mutex); + + // Registers a mock object and a mock method it owns. + static void Register( + const void* mock_obj, + internal::UntypedFunctionMockerBase* mocker) + GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex); + + // Tells Google Mock where in the source code mock_obj is used in an + // ON_CALL or EXPECT_CALL. In case mock_obj is leaked, this + // information helps the user identify which object it is. + static void RegisterUseByOnCallOrExpectCall( + const void* mock_obj, const char* file, int line) + GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex); + + // Unregisters a mock method; removes the owning mock object from + // the registry when the last mock method associated with it has + // been unregistered. This is called only in the destructor of + // FunctionMocker. + static void UnregisterLocked(internal::UntypedFunctionMockerBase* mocker) + GTEST_EXCLUSIVE_LOCK_REQUIRED_(internal::g_gmock_mutex); +}; // class Mock + +// An abstract handle of an expectation. Useful in the .After() +// clause of EXPECT_CALL() for setting the (partial) order of +// expectations. The syntax: +// +// Expectation e1 = EXPECT_CALL(...)...; +// EXPECT_CALL(...).After(e1)...; +// +// sets two expectations where the latter can only be matched after +// the former has been satisfied. +// +// Notes: +// - This class is copyable and has value semantics. +// - Constness is shallow: a const Expectation object itself cannot +// be modified, but the mutable methods of the ExpectationBase +// object it references can be called via expectation_base(). + +class GTEST_API_ Expectation { + public: + // Constructs a null object that doesn't reference any expectation. + Expectation(); + Expectation(Expectation&&) = default; + Expectation(const Expectation&) = default; + Expectation& operator=(Expectation&&) = default; + Expectation& operator=(const Expectation&) = default; + ~Expectation(); + + // This single-argument ctor must not be explicit, in order to support the + // Expectation e = EXPECT_CALL(...); + // syntax. + // + // A TypedExpectation object stores its pre-requisites as + // Expectation objects, and needs to call the non-const Retire() + // method on the ExpectationBase objects they reference. Therefore + // Expectation must receive a *non-const* reference to the + // ExpectationBase object. + Expectation(internal::ExpectationBase& exp); // NOLINT + + // The compiler-generated copy ctor and operator= work exactly as + // intended, so we don't need to define our own. + + // Returns true if and only if rhs references the same expectation as this + // object does. + bool operator==(const Expectation& rhs) const { + return expectation_base_ == rhs.expectation_base_; + } + + bool operator!=(const Expectation& rhs) const { return !(*this == rhs); } + + private: + friend class ExpectationSet; + friend class Sequence; + friend class ::testing::internal::ExpectationBase; + friend class ::testing::internal::UntypedFunctionMockerBase; + + template <typename F> + friend class ::testing::internal::FunctionMocker; + + template <typename F> + friend class ::testing::internal::TypedExpectation; + + // This comparator is needed for putting Expectation objects into a set. + class Less { + public: + bool operator()(const Expectation& lhs, const Expectation& rhs) const { + return lhs.expectation_base_.get() < rhs.expectation_base_.get(); + } + }; + + typedef ::std::set<Expectation, Less> Set; + + Expectation( + const std::shared_ptr<internal::ExpectationBase>& expectation_base); + + // Returns the expectation this object references. + const std::shared_ptr<internal::ExpectationBase>& expectation_base() const { + return expectation_base_; + } + + // A shared_ptr that co-owns the expectation this handle references. + std::shared_ptr<internal::ExpectationBase> expectation_base_; +}; + +// A set of expectation handles. Useful in the .After() clause of +// EXPECT_CALL() for setting the (partial) order of expectations. The +// syntax: +// +// ExpectationSet es; +// es += EXPECT_CALL(...)...; +// es += EXPECT_CALL(...)...; +// EXPECT_CALL(...).After(es)...; +// +// sets three expectations where the last one can only be matched +// after the first two have both been satisfied. +// +// This class is copyable and has value semantics. +class ExpectationSet { + public: + // A bidirectional iterator that can read a const element in the set. + typedef Expectation::Set::const_iterator const_iterator; + + // An object stored in the set. This is an alias of Expectation. + typedef Expectation::Set::value_type value_type; + + // Constructs an empty set. + ExpectationSet() {} + + // This single-argument ctor must not be explicit, in order to support the + // ExpectationSet es = EXPECT_CALL(...); + // syntax. + ExpectationSet(internal::ExpectationBase& exp) { // NOLINT + *this += Expectation(exp); + } + + // This single-argument ctor implements implicit conversion from + // Expectation and thus must not be explicit. This allows either an + // Expectation or an ExpectationSet to be used in .After(). + ExpectationSet(const Expectation& e) { // NOLINT + *this += e; + } + + // The compiler-generator ctor and operator= works exactly as + // intended, so we don't need to define our own. + + // Returns true if and only if rhs contains the same set of Expectation + // objects as this does. + bool operator==(const ExpectationSet& rhs) const { + return expectations_ == rhs.expectations_; + } + + bool operator!=(const ExpectationSet& rhs) const { return !(*this == rhs); } + + // Implements the syntax + // expectation_set += EXPECT_CALL(...); + ExpectationSet& operator+=(const Expectation& e) { + expectations_.insert(e); + return *this; + } + + int size() const { return static_cast<int>(expectations_.size()); } + + const_iterator begin() const { return expectations_.begin(); } + const_iterator end() const { return expectations_.end(); } + + private: + Expectation::Set expectations_; +}; + + +// Sequence objects are used by a user to specify the relative order +// in which the expectations should match. They are copyable (we rely +// on the compiler-defined copy constructor and assignment operator). +class GTEST_API_ Sequence { + public: + // Constructs an empty sequence. + Sequence() : last_expectation_(new Expectation) {} + + // Adds an expectation to this sequence. The caller must ensure + // that no other thread is accessing this Sequence object. + void AddExpectation(const Expectation& expectation) const; + + private: + // The last expectation in this sequence. + std::shared_ptr<Expectation> last_expectation_; +}; // class Sequence + +// An object of this type causes all EXPECT_CALL() statements +// encountered in its scope to be put in an anonymous sequence. The +// work is done in the constructor and destructor. You should only +// create an InSequence object on the stack. +// +// The sole purpose for this class is to support easy definition of +// sequential expectations, e.g. +// +// { +// InSequence dummy; // The name of the object doesn't matter. +// +// // The following expectations must match in the order they appear. +// EXPECT_CALL(a, Bar())...; +// EXPECT_CALL(a, Baz())...; +// ... +// EXPECT_CALL(b, Xyz())...; +// } +// +// You can create InSequence objects in multiple threads, as long as +// they are used to affect different mock objects. The idea is that +// each thread can create and set up its own mocks as if it's the only +// thread. However, for clarity of your tests we recommend you to set +// up mocks in the main thread unless you have a good reason not to do +// so. +class GTEST_API_ InSequence { + public: + InSequence(); + ~InSequence(); + private: + bool sequence_created_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(InSequence); // NOLINT +} GTEST_ATTRIBUTE_UNUSED_; + +namespace internal { + +// Points to the implicit sequence introduced by a living InSequence +// object (if any) in the current thread or NULL. +GTEST_API_ extern ThreadLocal<Sequence*> g_gmock_implicit_sequence; + +// Base class for implementing expectations. +// +// There are two reasons for having a type-agnostic base class for +// Expectation: +// +// 1. We need to store collections of expectations of different +// types (e.g. all pre-requisites of a particular expectation, all +// expectations in a sequence). Therefore these expectation objects +// must share a common base class. +// +// 2. We can avoid binary code bloat by moving methods not depending +// on the template argument of Expectation to the base class. +// +// This class is internal and mustn't be used by user code directly. +class GTEST_API_ ExpectationBase { + public: + // source_text is the EXPECT_CALL(...) source that created this Expectation. + ExpectationBase(const char* file, int line, const std::string& source_text); + + virtual ~ExpectationBase(); + + // Where in the source file was the expectation spec defined? + const char* file() const { return file_; } + int line() const { return line_; } + const char* source_text() const { return source_text_.c_str(); } + // Returns the cardinality specified in the expectation spec. + const Cardinality& cardinality() const { return cardinality_; } + + // Describes the source file location of this expectation. + void DescribeLocationTo(::std::ostream* os) const { + *os << FormatFileLocation(file(), line()) << " "; + } + + // Describes how many times a function call matching this + // expectation has occurred. + void DescribeCallCountTo(::std::ostream* os) const + GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex); + + // If this mock method has an extra matcher (i.e. .With(matcher)), + // describes it to the ostream. + virtual void MaybeDescribeExtraMatcherTo(::std::ostream* os) = 0; + + protected: + friend class ::testing::Expectation; + friend class UntypedFunctionMockerBase; + + enum Clause { + // Don't change the order of the enum members! + kNone, + kWith, + kTimes, + kInSequence, + kAfter, + kWillOnce, + kWillRepeatedly, + kRetiresOnSaturation + }; + + typedef std::vector<const void*> UntypedActions; + + // Returns an Expectation object that references and co-owns this + // expectation. + virtual Expectation GetHandle() = 0; + + // Asserts that the EXPECT_CALL() statement has the given property. + void AssertSpecProperty(bool property, + const std::string& failure_message) const { + Assert(property, file_, line_, failure_message); + } + + // Expects that the EXPECT_CALL() statement has the given property. + void ExpectSpecProperty(bool property, + const std::string& failure_message) const { + Expect(property, file_, line_, failure_message); + } + + // Explicitly specifies the cardinality of this expectation. Used + // by the subclasses to implement the .Times() clause. + void SpecifyCardinality(const Cardinality& cardinality); + + // Returns true if and only if the user specified the cardinality + // explicitly using a .Times(). + bool cardinality_specified() const { return cardinality_specified_; } + + // Sets the cardinality of this expectation spec. + void set_cardinality(const Cardinality& a_cardinality) { + cardinality_ = a_cardinality; + } + + // The following group of methods should only be called after the + // EXPECT_CALL() statement, and only when g_gmock_mutex is held by + // the current thread. + + // Retires all pre-requisites of this expectation. + void RetireAllPreRequisites() + GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex); + + // Returns true if and only if this expectation is retired. + bool is_retired() const + GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) { + g_gmock_mutex.AssertHeld(); + return retired_; + } + + // Retires this expectation. + void Retire() + GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) { + g_gmock_mutex.AssertHeld(); + retired_ = true; + } + + // Returns true if and only if this expectation is satisfied. + bool IsSatisfied() const + GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) { + g_gmock_mutex.AssertHeld(); + return cardinality().IsSatisfiedByCallCount(call_count_); + } + + // Returns true if and only if this expectation is saturated. + bool IsSaturated() const + GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) { + g_gmock_mutex.AssertHeld(); + return cardinality().IsSaturatedByCallCount(call_count_); + } + + // Returns true if and only if this expectation is over-saturated. + bool IsOverSaturated() const + GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) { + g_gmock_mutex.AssertHeld(); + return cardinality().IsOverSaturatedByCallCount(call_count_); + } + + // Returns true if and only if all pre-requisites of this expectation are + // satisfied. + bool AllPrerequisitesAreSatisfied() const + GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex); + + // Adds unsatisfied pre-requisites of this expectation to 'result'. + void FindUnsatisfiedPrerequisites(ExpectationSet* result) const + GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex); + + // Returns the number this expectation has been invoked. + int call_count() const + GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) { + g_gmock_mutex.AssertHeld(); + return call_count_; + } + + // Increments the number this expectation has been invoked. + void IncrementCallCount() + GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) { + g_gmock_mutex.AssertHeld(); + call_count_++; + } + + // Checks the action count (i.e. the number of WillOnce() and + // WillRepeatedly() clauses) against the cardinality if this hasn't + // been done before. Prints a warning if there are too many or too + // few actions. + void CheckActionCountIfNotDone() const + GTEST_LOCK_EXCLUDED_(mutex_); + + friend class ::testing::Sequence; + friend class ::testing::internal::ExpectationTester; + + template <typename Function> + friend class TypedExpectation; + + // Implements the .Times() clause. + void UntypedTimes(const Cardinality& a_cardinality); + + // This group of fields are part of the spec and won't change after + // an EXPECT_CALL() statement finishes. + const char* file_; // The file that contains the expectation. + int line_; // The line number of the expectation. + const std::string source_text_; // The EXPECT_CALL(...) source text. + // True if and only if the cardinality is specified explicitly. + bool cardinality_specified_; + Cardinality cardinality_; // The cardinality of the expectation. + // The immediate pre-requisites (i.e. expectations that must be + // satisfied before this expectation can be matched) of this + // expectation. We use std::shared_ptr in the set because we want an + // Expectation object to be co-owned by its FunctionMocker and its + // successors. This allows multiple mock objects to be deleted at + // different times. + ExpectationSet immediate_prerequisites_; + + // This group of fields are the current state of the expectation, + // and can change as the mock function is called. + int call_count_; // How many times this expectation has been invoked. + bool retired_; // True if and only if this expectation has retired. + UntypedActions untyped_actions_; + bool extra_matcher_specified_; + bool repeated_action_specified_; // True if a WillRepeatedly() was specified. + bool retires_on_saturation_; + Clause last_clause_; + mutable bool action_count_checked_; // Under mutex_. + mutable Mutex mutex_; // Protects action_count_checked_. +}; // class ExpectationBase + +// Impements an expectation for the given function type. +template <typename F> +class TypedExpectation : public ExpectationBase { + public: + typedef typename Function<F>::ArgumentTuple ArgumentTuple; + typedef typename Function<F>::ArgumentMatcherTuple ArgumentMatcherTuple; + typedef typename Function<F>::Result Result; + + TypedExpectation(FunctionMocker<F>* owner, const char* a_file, int a_line, + const std::string& a_source_text, + const ArgumentMatcherTuple& m) + : ExpectationBase(a_file, a_line, a_source_text), + owner_(owner), + matchers_(m), + // By default, extra_matcher_ should match anything. However, + // we cannot initialize it with _ as that causes ambiguity between + // Matcher's copy and move constructor for some argument types. + extra_matcher_(A<const ArgumentTuple&>()), + repeated_action_(DoDefault()) {} + + ~TypedExpectation() override { + // Check the validity of the action count if it hasn't been done + // yet (for example, if the expectation was never used). + CheckActionCountIfNotDone(); + for (UntypedActions::const_iterator it = untyped_actions_.begin(); + it != untyped_actions_.end(); ++it) { + delete static_cast<const Action<F>*>(*it); + } + } + + // Implements the .With() clause. + TypedExpectation& With(const Matcher<const ArgumentTuple&>& m) { + if (last_clause_ == kWith) { + ExpectSpecProperty(false, + ".With() cannot appear " + "more than once in an EXPECT_CALL()."); + } else { + ExpectSpecProperty(last_clause_ < kWith, + ".With() must be the first " + "clause in an EXPECT_CALL()."); + } + last_clause_ = kWith; + + extra_matcher_ = m; + extra_matcher_specified_ = true; + return *this; + } + + // Implements the .Times() clause. + TypedExpectation& Times(const Cardinality& a_cardinality) { + ExpectationBase::UntypedTimes(a_cardinality); + return *this; + } + + // Implements the .Times() clause. + TypedExpectation& Times(int n) { + return Times(Exactly(n)); + } + + // Implements the .InSequence() clause. + TypedExpectation& InSequence(const Sequence& s) { + ExpectSpecProperty(last_clause_ <= kInSequence, + ".InSequence() cannot appear after .After()," + " .WillOnce(), .WillRepeatedly(), or " + ".RetiresOnSaturation()."); + last_clause_ = kInSequence; + + s.AddExpectation(GetHandle()); + return *this; + } + TypedExpectation& InSequence(const Sequence& s1, const Sequence& s2) { + return InSequence(s1).InSequence(s2); + } + TypedExpectation& InSequence(const Sequence& s1, const Sequence& s2, + const Sequence& s3) { + return InSequence(s1, s2).InSequence(s3); + } + TypedExpectation& InSequence(const Sequence& s1, const Sequence& s2, + const Sequence& s3, const Sequence& s4) { + return InSequence(s1, s2, s3).InSequence(s4); + } + TypedExpectation& InSequence(const Sequence& s1, const Sequence& s2, + const Sequence& s3, const Sequence& s4, + const Sequence& s5) { + return InSequence(s1, s2, s3, s4).InSequence(s5); + } + + // Implements that .After() clause. + TypedExpectation& After(const ExpectationSet& s) { + ExpectSpecProperty(last_clause_ <= kAfter, + ".After() cannot appear after .WillOnce()," + " .WillRepeatedly(), or " + ".RetiresOnSaturation()."); + last_clause_ = kAfter; + + for (ExpectationSet::const_iterator it = s.begin(); it != s.end(); ++it) { + immediate_prerequisites_ += *it; + } + return *this; + } + TypedExpectation& After(const ExpectationSet& s1, const ExpectationSet& s2) { + return After(s1).After(s2); + } + TypedExpectation& After(const ExpectationSet& s1, const ExpectationSet& s2, + const ExpectationSet& s3) { + return After(s1, s2).After(s3); + } + TypedExpectation& After(const ExpectationSet& s1, const ExpectationSet& s2, + const ExpectationSet& s3, const ExpectationSet& s4) { + return After(s1, s2, s3).After(s4); + } + TypedExpectation& After(const ExpectationSet& s1, const ExpectationSet& s2, + const ExpectationSet& s3, const ExpectationSet& s4, + const ExpectationSet& s5) { + return After(s1, s2, s3, s4).After(s5); + } + + // Implements the .WillOnce() clause. + TypedExpectation& WillOnce(const Action<F>& action) { + ExpectSpecProperty(last_clause_ <= kWillOnce, + ".WillOnce() cannot appear after " + ".WillRepeatedly() or .RetiresOnSaturation()."); + last_clause_ = kWillOnce; + + untyped_actions_.push_back(new Action<F>(action)); + if (!cardinality_specified()) { + set_cardinality(Exactly(static_cast<int>(untyped_actions_.size()))); + } + return *this; + } + + // Implements the .WillRepeatedly() clause. + TypedExpectation& WillRepeatedly(const Action<F>& action) { + if (last_clause_ == kWillRepeatedly) { + ExpectSpecProperty(false, + ".WillRepeatedly() cannot appear " + "more than once in an EXPECT_CALL()."); + } else { + ExpectSpecProperty(last_clause_ < kWillRepeatedly, + ".WillRepeatedly() cannot appear " + "after .RetiresOnSaturation()."); + } + last_clause_ = kWillRepeatedly; + repeated_action_specified_ = true; + + repeated_action_ = action; + if (!cardinality_specified()) { + set_cardinality(AtLeast(static_cast<int>(untyped_actions_.size()))); + } + + // Now that no more action clauses can be specified, we check + // whether their count makes sense. + CheckActionCountIfNotDone(); + return *this; + } + + // Implements the .RetiresOnSaturation() clause. + TypedExpectation& RetiresOnSaturation() { + ExpectSpecProperty(last_clause_ < kRetiresOnSaturation, + ".RetiresOnSaturation() cannot appear " + "more than once."); + last_clause_ = kRetiresOnSaturation; + retires_on_saturation_ = true; + + // Now that no more action clauses can be specified, we check + // whether their count makes sense. + CheckActionCountIfNotDone(); + return *this; + } + + // Returns the matchers for the arguments as specified inside the + // EXPECT_CALL() macro. + const ArgumentMatcherTuple& matchers() const { + return matchers_; + } + + // Returns the matcher specified by the .With() clause. + const Matcher<const ArgumentTuple&>& extra_matcher() const { + return extra_matcher_; + } + + // Returns the action specified by the .WillRepeatedly() clause. + const Action<F>& repeated_action() const { return repeated_action_; } + + // If this mock method has an extra matcher (i.e. .With(matcher)), + // describes it to the ostream. + void MaybeDescribeExtraMatcherTo(::std::ostream* os) override { + if (extra_matcher_specified_) { + *os << " Expected args: "; + extra_matcher_.DescribeTo(os); + *os << "\n"; + } + } + + private: + template <typename Function> + friend class FunctionMocker; + + // Returns an Expectation object that references and co-owns this + // expectation. + Expectation GetHandle() override { return owner_->GetHandleOf(this); } + + // The following methods will be called only after the EXPECT_CALL() + // statement finishes and when the current thread holds + // g_gmock_mutex. + + // Returns true if and only if this expectation matches the given arguments. + bool Matches(const ArgumentTuple& args) const + GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) { + g_gmock_mutex.AssertHeld(); + return TupleMatches(matchers_, args) && extra_matcher_.Matches(args); + } + + // Returns true if and only if this expectation should handle the given + // arguments. + bool ShouldHandleArguments(const ArgumentTuple& args) const + GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) { + g_gmock_mutex.AssertHeld(); + + // In case the action count wasn't checked when the expectation + // was defined (e.g. if this expectation has no WillRepeatedly() + // or RetiresOnSaturation() clause), we check it when the + // expectation is used for the first time. + CheckActionCountIfNotDone(); + return !is_retired() && AllPrerequisitesAreSatisfied() && Matches(args); + } + + // Describes the result of matching the arguments against this + // expectation to the given ostream. + void ExplainMatchResultTo( + const ArgumentTuple& args, + ::std::ostream* os) const + GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) { + g_gmock_mutex.AssertHeld(); + + if (is_retired()) { + *os << " Expected: the expectation is active\n" + << " Actual: it is retired\n"; + } else if (!Matches(args)) { + if (!TupleMatches(matchers_, args)) { + ExplainMatchFailureTupleTo(matchers_, args, os); + } + StringMatchResultListener listener; + if (!extra_matcher_.MatchAndExplain(args, &listener)) { + *os << " Expected args: "; + extra_matcher_.DescribeTo(os); + *os << "\n Actual: don't match"; + + internal::PrintIfNotEmpty(listener.str(), os); + *os << "\n"; + } + } else if (!AllPrerequisitesAreSatisfied()) { + *os << " Expected: all pre-requisites are satisfied\n" + << " Actual: the following immediate pre-requisites " + << "are not satisfied:\n"; + ExpectationSet unsatisfied_prereqs; + FindUnsatisfiedPrerequisites(&unsatisfied_prereqs); + int i = 0; + for (ExpectationSet::const_iterator it = unsatisfied_prereqs.begin(); + it != unsatisfied_prereqs.end(); ++it) { + it->expectation_base()->DescribeLocationTo(os); + *os << "pre-requisite #" << i++ << "\n"; + } + *os << " (end of pre-requisites)\n"; + } else { + // This line is here just for completeness' sake. It will never + // be executed as currently the ExplainMatchResultTo() function + // is called only when the mock function call does NOT match the + // expectation. + *os << "The call matches the expectation.\n"; + } + } + + // Returns the action that should be taken for the current invocation. + const Action<F>& GetCurrentAction(const FunctionMocker<F>* mocker, + const ArgumentTuple& args) const + GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) { + g_gmock_mutex.AssertHeld(); + const int count = call_count(); + Assert(count >= 1, __FILE__, __LINE__, + "call_count() is <= 0 when GetCurrentAction() is " + "called - this should never happen."); + + const int action_count = static_cast<int>(untyped_actions_.size()); + if (action_count > 0 && !repeated_action_specified_ && + count > action_count) { + // If there is at least one WillOnce() and no WillRepeatedly(), + // we warn the user when the WillOnce() clauses ran out. + ::std::stringstream ss; + DescribeLocationTo(&ss); + ss << "Actions ran out in " << source_text() << "...\n" + << "Called " << count << " times, but only " + << action_count << " WillOnce()" + << (action_count == 1 ? " is" : "s are") << " specified - "; + mocker->DescribeDefaultActionTo(args, &ss); + Log(kWarning, ss.str(), 1); + } + + return count <= action_count + ? *static_cast<const Action<F>*>( + untyped_actions_[static_cast<size_t>(count - 1)]) + : repeated_action(); + } + + // Given the arguments of a mock function call, if the call will + // over-saturate this expectation, returns the default action; + // otherwise, returns the next action in this expectation. Also + // describes *what* happened to 'what', and explains *why* Google + // Mock does it to 'why'. This method is not const as it calls + // IncrementCallCount(). A return value of NULL means the default + // action. + const Action<F>* GetActionForArguments(const FunctionMocker<F>* mocker, + const ArgumentTuple& args, + ::std::ostream* what, + ::std::ostream* why) + GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) { + g_gmock_mutex.AssertHeld(); + if (IsSaturated()) { + // We have an excessive call. + IncrementCallCount(); + *what << "Mock function called more times than expected - "; + mocker->DescribeDefaultActionTo(args, what); + DescribeCallCountTo(why); + + return nullptr; + } + + IncrementCallCount(); + RetireAllPreRequisites(); + + if (retires_on_saturation_ && IsSaturated()) { + Retire(); + } + + // Must be done after IncrementCount()! + *what << "Mock function call matches " << source_text() <<"...\n"; + return &(GetCurrentAction(mocker, args)); + } + + // All the fields below won't change once the EXPECT_CALL() + // statement finishes. + FunctionMocker<F>* const owner_; + ArgumentMatcherTuple matchers_; + Matcher<const ArgumentTuple&> extra_matcher_; + Action<F> repeated_action_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(TypedExpectation); +}; // class TypedExpectation + +// A MockSpec object is used by ON_CALL() or EXPECT_CALL() for +// specifying the default behavior of, or expectation on, a mock +// function. + +// Note: class MockSpec really belongs to the ::testing namespace. +// However if we define it in ::testing, MSVC will complain when +// classes in ::testing::internal declare it as a friend class +// template. To workaround this compiler bug, we define MockSpec in +// ::testing::internal and import it into ::testing. + +// Logs a message including file and line number information. +GTEST_API_ void LogWithLocation(testing::internal::LogSeverity severity, + const char* file, int line, + const std::string& message); + +template <typename F> +class MockSpec { + public: + typedef typename internal::Function<F>::ArgumentTuple ArgumentTuple; + typedef typename internal::Function<F>::ArgumentMatcherTuple + ArgumentMatcherTuple; + + // Constructs a MockSpec object, given the function mocker object + // that the spec is associated with. + MockSpec(internal::FunctionMocker<F>* function_mocker, + const ArgumentMatcherTuple& matchers) + : function_mocker_(function_mocker), matchers_(matchers) {} + + // Adds a new default action spec to the function mocker and returns + // the newly created spec. + internal::OnCallSpec<F>& InternalDefaultActionSetAt( + const char* file, int line, const char* obj, const char* call) { + LogWithLocation(internal::kInfo, file, line, + std::string("ON_CALL(") + obj + ", " + call + ") invoked"); + return function_mocker_->AddNewOnCallSpec(file, line, matchers_); + } + + // Adds a new expectation spec to the function mocker and returns + // the newly created spec. + internal::TypedExpectation<F>& InternalExpectedAt( + const char* file, int line, const char* obj, const char* call) { + const std::string source_text(std::string("EXPECT_CALL(") + obj + ", " + + call + ")"); + LogWithLocation(internal::kInfo, file, line, source_text + " invoked"); + return function_mocker_->AddNewExpectation( + file, line, source_text, matchers_); + } + + // This operator overload is used to swallow the superfluous parameter list + // introduced by the ON/EXPECT_CALL macros. See the macro comments for more + // explanation. + MockSpec<F>& operator()(const internal::WithoutMatchers&, void* const) { + return *this; + } + + private: + template <typename Function> + friend class internal::FunctionMocker; + + // The function mocker that owns this spec. + internal::FunctionMocker<F>* const function_mocker_; + // The argument matchers specified in the spec. + ArgumentMatcherTuple matchers_; +}; // class MockSpec + +// Wrapper type for generically holding an ordinary value or lvalue reference. +// If T is not a reference type, it must be copyable or movable. +// ReferenceOrValueWrapper<T> is movable, and will also be copyable unless +// T is a move-only value type (which means that it will always be copyable +// if the current platform does not support move semantics). +// +// The primary template defines handling for values, but function header +// comments describe the contract for the whole template (including +// specializations). +template <typename T> +class ReferenceOrValueWrapper { + public: + // Constructs a wrapper from the given value/reference. + explicit ReferenceOrValueWrapper(T value) + : value_(std::move(value)) { + } + + // Unwraps and returns the underlying value/reference, exactly as + // originally passed. The behavior of calling this more than once on + // the same object is unspecified. + T Unwrap() { return std::move(value_); } + + // Provides nondestructive access to the underlying value/reference. + // Always returns a const reference (more precisely, + // const std::add_lvalue_reference<T>::type). The behavior of calling this + // after calling Unwrap on the same object is unspecified. + const T& Peek() const { + return value_; + } + + private: + T value_; +}; + +// Specialization for lvalue reference types. See primary template +// for documentation. +template <typename T> +class ReferenceOrValueWrapper<T&> { + public: + // Workaround for debatable pass-by-reference lint warning (c-library-team + // policy precludes NOLINT in this context) + typedef T& reference; + explicit ReferenceOrValueWrapper(reference ref) + : value_ptr_(&ref) {} + T& Unwrap() { return *value_ptr_; } + const T& Peek() const { return *value_ptr_; } + + private: + T* value_ptr_; +}; + +// C++ treats the void type specially. For example, you cannot define +// a void-typed variable or pass a void value to a function. +// ActionResultHolder<T> holds a value of type T, where T must be a +// copyable type or void (T doesn't need to be default-constructable). +// It hides the syntactic difference between void and other types, and +// is used to unify the code for invoking both void-returning and +// non-void-returning mock functions. + +// Untyped base class for ActionResultHolder<T>. +class UntypedActionResultHolderBase { + public: + virtual ~UntypedActionResultHolderBase() {} + + // Prints the held value as an action's result to os. + virtual void PrintAsActionResult(::std::ostream* os) const = 0; +}; + +// This generic definition is used when T is not void. +template <typename T> +class ActionResultHolder : public UntypedActionResultHolderBase { + public: + // Returns the held value. Must not be called more than once. + T Unwrap() { + return result_.Unwrap(); + } + + // Prints the held value as an action's result to os. + void PrintAsActionResult(::std::ostream* os) const override { + *os << "\n Returns: "; + // T may be a reference type, so we don't use UniversalPrint(). + UniversalPrinter<T>::Print(result_.Peek(), os); + } + + // Performs the given mock function's default action and returns the + // result in a new-ed ActionResultHolder. + template <typename F> + static ActionResultHolder* PerformDefaultAction( + const FunctionMocker<F>* func_mocker, + typename Function<F>::ArgumentTuple&& args, + const std::string& call_description) { + return new ActionResultHolder(Wrapper(func_mocker->PerformDefaultAction( + std::move(args), call_description))); + } + + // Performs the given action and returns the result in a new-ed + // ActionResultHolder. + template <typename F> + static ActionResultHolder* PerformAction( + const Action<F>& action, typename Function<F>::ArgumentTuple&& args) { + return new ActionResultHolder( + Wrapper(action.Perform(std::move(args)))); + } + + private: + typedef ReferenceOrValueWrapper<T> Wrapper; + + explicit ActionResultHolder(Wrapper result) + : result_(std::move(result)) { + } + + Wrapper result_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(ActionResultHolder); +}; + +// Specialization for T = void. +template <> +class ActionResultHolder<void> : public UntypedActionResultHolderBase { + public: + void Unwrap() { } + + void PrintAsActionResult(::std::ostream* /* os */) const override {} + + // Performs the given mock function's default action and returns ownership + // of an empty ActionResultHolder*. + template <typename F> + static ActionResultHolder* PerformDefaultAction( + const FunctionMocker<F>* func_mocker, + typename Function<F>::ArgumentTuple&& args, + const std::string& call_description) { + func_mocker->PerformDefaultAction(std::move(args), call_description); + return new ActionResultHolder; + } + + // Performs the given action and returns ownership of an empty + // ActionResultHolder*. + template <typename F> + static ActionResultHolder* PerformAction( + const Action<F>& action, typename Function<F>::ArgumentTuple&& args) { + action.Perform(std::move(args)); + return new ActionResultHolder; + } + + private: + ActionResultHolder() {} + GTEST_DISALLOW_COPY_AND_ASSIGN_(ActionResultHolder); +}; + +template <typename F> +class FunctionMocker; + +template <typename R, typename... Args> +class FunctionMocker<R(Args...)> final : public UntypedFunctionMockerBase { + using F = R(Args...); + + public: + using Result = R; + using ArgumentTuple = std::tuple<Args...>; + using ArgumentMatcherTuple = std::tuple<Matcher<Args>...>; + + FunctionMocker() {} + + // There is no generally useful and implementable semantics of + // copying a mock object, so copying a mock is usually a user error. + // Thus we disallow copying function mockers. If the user really + // wants to copy a mock object, they should implement their own copy + // operation, for example: + // + // class MockFoo : public Foo { + // public: + // // Defines a copy constructor explicitly. + // MockFoo(const MockFoo& src) {} + // ... + // }; + FunctionMocker(const FunctionMocker&) = delete; + FunctionMocker& operator=(const FunctionMocker&) = delete; + + // The destructor verifies that all expectations on this mock + // function have been satisfied. If not, it will report Google Test + // non-fatal failures for the violations. + ~FunctionMocker() override GTEST_LOCK_EXCLUDED_(g_gmock_mutex) { + MutexLock l(&g_gmock_mutex); + VerifyAndClearExpectationsLocked(); + Mock::UnregisterLocked(this); + ClearDefaultActionsLocked(); + } + + // Returns the ON_CALL spec that matches this mock function with the + // given arguments; returns NULL if no matching ON_CALL is found. + // L = * + const OnCallSpec<F>* FindOnCallSpec( + const ArgumentTuple& args) const { + for (UntypedOnCallSpecs::const_reverse_iterator it + = untyped_on_call_specs_.rbegin(); + it != untyped_on_call_specs_.rend(); ++it) { + const OnCallSpec<F>* spec = static_cast<const OnCallSpec<F>*>(*it); + if (spec->Matches(args)) + return spec; + } + + return nullptr; + } + + // Performs the default action of this mock function on the given + // arguments and returns the result. Asserts (or throws if + // exceptions are enabled) with a helpful call descrption if there + // is no valid return value. This method doesn't depend on the + // mutable state of this object, and thus can be called concurrently + // without locking. + // L = * + Result PerformDefaultAction(ArgumentTuple&& args, + const std::string& call_description) const { + const OnCallSpec<F>* const spec = + this->FindOnCallSpec(args); + if (spec != nullptr) { + return spec->GetAction().Perform(std::move(args)); + } + const std::string message = + call_description + + "\n The mock function has no default action " + "set, and its return type has no default value set."; +#if GTEST_HAS_EXCEPTIONS + if (!DefaultValue<Result>::Exists()) { + throw std::runtime_error(message); + } +#else + Assert(DefaultValue<Result>::Exists(), "", -1, message); +#endif + return DefaultValue<Result>::Get(); + } + + // Performs the default action with the given arguments and returns + // the action's result. The call description string will be used in + // the error message to describe the call in the case the default + // action fails. The caller is responsible for deleting the result. + // L = * + UntypedActionResultHolderBase* UntypedPerformDefaultAction( + void* untyped_args, // must point to an ArgumentTuple + const std::string& call_description) const override { + ArgumentTuple* args = static_cast<ArgumentTuple*>(untyped_args); + return ResultHolder::PerformDefaultAction(this, std::move(*args), + call_description); + } + + // Performs the given action with the given arguments and returns + // the action's result. The caller is responsible for deleting the + // result. + // L = * + UntypedActionResultHolderBase* UntypedPerformAction( + const void* untyped_action, void* untyped_args) const override { + // Make a copy of the action before performing it, in case the + // action deletes the mock object (and thus deletes itself). + const Action<F> action = *static_cast<const Action<F>*>(untyped_action); + ArgumentTuple* args = static_cast<ArgumentTuple*>(untyped_args); + return ResultHolder::PerformAction(action, std::move(*args)); + } + + // Implements UntypedFunctionMockerBase::ClearDefaultActionsLocked(): + // clears the ON_CALL()s set on this mock function. + void ClearDefaultActionsLocked() override + GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) { + g_gmock_mutex.AssertHeld(); + + // Deleting our default actions may trigger other mock objects to be + // deleted, for example if an action contains a reference counted smart + // pointer to that mock object, and that is the last reference. So if we + // delete our actions within the context of the global mutex we may deadlock + // when this method is called again. Instead, make a copy of the set of + // actions to delete, clear our set within the mutex, and then delete the + // actions outside of the mutex. + UntypedOnCallSpecs specs_to_delete; + untyped_on_call_specs_.swap(specs_to_delete); + + g_gmock_mutex.Unlock(); + for (UntypedOnCallSpecs::const_iterator it = + specs_to_delete.begin(); + it != specs_to_delete.end(); ++it) { + delete static_cast<const OnCallSpec<F>*>(*it); + } + + // Lock the mutex again, since the caller expects it to be locked when we + // return. + g_gmock_mutex.Lock(); + } + + // Returns the result of invoking this mock function with the given + // arguments. This function can be safely called from multiple + // threads concurrently. + Result Invoke(Args... args) GTEST_LOCK_EXCLUDED_(g_gmock_mutex) { + ArgumentTuple tuple(std::forward<Args>(args)...); + std::unique_ptr<ResultHolder> holder(DownCast_<ResultHolder*>( + this->UntypedInvokeWith(static_cast<void*>(&tuple)))); + return holder->Unwrap(); + } + + MockSpec<F> With(Matcher<Args>... m) { + return MockSpec<F>(this, ::std::make_tuple(std::move(m)...)); + } + + protected: + template <typename Function> + friend class MockSpec; + + typedef ActionResultHolder<Result> ResultHolder; + + // Adds and returns a default action spec for this mock function. + OnCallSpec<F>& AddNewOnCallSpec( + const char* file, int line, + const ArgumentMatcherTuple& m) + GTEST_LOCK_EXCLUDED_(g_gmock_mutex) { + Mock::RegisterUseByOnCallOrExpectCall(MockObject(), file, line); + OnCallSpec<F>* const on_call_spec = new OnCallSpec<F>(file, line, m); + untyped_on_call_specs_.push_back(on_call_spec); + return *on_call_spec; + } + + // Adds and returns an expectation spec for this mock function. + TypedExpectation<F>& AddNewExpectation(const char* file, int line, + const std::string& source_text, + const ArgumentMatcherTuple& m) + GTEST_LOCK_EXCLUDED_(g_gmock_mutex) { + Mock::RegisterUseByOnCallOrExpectCall(MockObject(), file, line); + TypedExpectation<F>* const expectation = + new TypedExpectation<F>(this, file, line, source_text, m); + const std::shared_ptr<ExpectationBase> untyped_expectation(expectation); + // See the definition of untyped_expectations_ for why access to + // it is unprotected here. + untyped_expectations_.push_back(untyped_expectation); + + // Adds this expectation into the implicit sequence if there is one. + Sequence* const implicit_sequence = g_gmock_implicit_sequence.get(); + if (implicit_sequence != nullptr) { + implicit_sequence->AddExpectation(Expectation(untyped_expectation)); + } + + return *expectation; + } + + private: + template <typename Func> friend class TypedExpectation; + + // Some utilities needed for implementing UntypedInvokeWith(). + + // Describes what default action will be performed for the given + // arguments. + // L = * + void DescribeDefaultActionTo(const ArgumentTuple& args, + ::std::ostream* os) const { + const OnCallSpec<F>* const spec = FindOnCallSpec(args); + + if (spec == nullptr) { + *os << (std::is_void<Result>::value ? "returning directly.\n" + : "returning default value.\n"); + } else { + *os << "taking default action specified at:\n" + << FormatFileLocation(spec->file(), spec->line()) << "\n"; + } + } + + // Writes a message that the call is uninteresting (i.e. neither + // explicitly expected nor explicitly unexpected) to the given + // ostream. + void UntypedDescribeUninterestingCall(const void* untyped_args, + ::std::ostream* os) const override + GTEST_LOCK_EXCLUDED_(g_gmock_mutex) { + const ArgumentTuple& args = + *static_cast<const ArgumentTuple*>(untyped_args); + *os << "Uninteresting mock function call - "; + DescribeDefaultActionTo(args, os); + *os << " Function call: " << Name(); + UniversalPrint(args, os); + } + + // Returns the expectation that matches the given function arguments + // (or NULL is there's no match); when a match is found, + // untyped_action is set to point to the action that should be + // performed (or NULL if the action is "do default"), and + // is_excessive is modified to indicate whether the call exceeds the + // expected number. + // + // Critical section: We must find the matching expectation and the + // corresponding action that needs to be taken in an ATOMIC + // transaction. Otherwise another thread may call this mock + // method in the middle and mess up the state. + // + // However, performing the action has to be left out of the critical + // section. The reason is that we have no control on what the + // action does (it can invoke an arbitrary user function or even a + // mock function) and excessive locking could cause a dead lock. + const ExpectationBase* UntypedFindMatchingExpectation( + const void* untyped_args, const void** untyped_action, bool* is_excessive, + ::std::ostream* what, ::std::ostream* why) override + GTEST_LOCK_EXCLUDED_(g_gmock_mutex) { + const ArgumentTuple& args = + *static_cast<const ArgumentTuple*>(untyped_args); + MutexLock l(&g_gmock_mutex); + TypedExpectation<F>* exp = this->FindMatchingExpectationLocked(args); + if (exp == nullptr) { // A match wasn't found. + this->FormatUnexpectedCallMessageLocked(args, what, why); + return nullptr; + } + + // This line must be done before calling GetActionForArguments(), + // which will increment the call count for *exp and thus affect + // its saturation status. + *is_excessive = exp->IsSaturated(); + const Action<F>* action = exp->GetActionForArguments(this, args, what, why); + if (action != nullptr && action->IsDoDefault()) + action = nullptr; // Normalize "do default" to NULL. + *untyped_action = action; + return exp; + } + + // Prints the given function arguments to the ostream. + void UntypedPrintArgs(const void* untyped_args, + ::std::ostream* os) const override { + const ArgumentTuple& args = + *static_cast<const ArgumentTuple*>(untyped_args); + UniversalPrint(args, os); + } + + // Returns the expectation that matches the arguments, or NULL if no + // expectation matches them. + TypedExpectation<F>* FindMatchingExpectationLocked( + const ArgumentTuple& args) const + GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) { + g_gmock_mutex.AssertHeld(); + // See the definition of untyped_expectations_ for why access to + // it is unprotected here. + for (typename UntypedExpectations::const_reverse_iterator it = + untyped_expectations_.rbegin(); + it != untyped_expectations_.rend(); ++it) { + TypedExpectation<F>* const exp = + static_cast<TypedExpectation<F>*>(it->get()); + if (exp->ShouldHandleArguments(args)) { + return exp; + } + } + return nullptr; + } + + // Returns a message that the arguments don't match any expectation. + void FormatUnexpectedCallMessageLocked( + const ArgumentTuple& args, + ::std::ostream* os, + ::std::ostream* why) const + GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) { + g_gmock_mutex.AssertHeld(); + *os << "\nUnexpected mock function call - "; + DescribeDefaultActionTo(args, os); + PrintTriedExpectationsLocked(args, why); + } + + // Prints a list of expectations that have been tried against the + // current mock function call. + void PrintTriedExpectationsLocked( + const ArgumentTuple& args, + ::std::ostream* why) const + GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) { + g_gmock_mutex.AssertHeld(); + const size_t count = untyped_expectations_.size(); + *why << "Google Mock tried the following " << count << " " + << (count == 1 ? "expectation, but it didn't match" : + "expectations, but none matched") + << ":\n"; + for (size_t i = 0; i < count; i++) { + TypedExpectation<F>* const expectation = + static_cast<TypedExpectation<F>*>(untyped_expectations_[i].get()); + *why << "\n"; + expectation->DescribeLocationTo(why); + if (count > 1) { + *why << "tried expectation #" << i << ": "; + } + *why << expectation->source_text() << "...\n"; + expectation->ExplainMatchResultTo(args, why); + expectation->DescribeCallCountTo(why); + } + } +}; // class FunctionMocker + +// Reports an uninteresting call (whose description is in msg) in the +// manner specified by 'reaction'. +void ReportUninterestingCall(CallReaction reaction, const std::string& msg); + +} // namespace internal + +namespace internal { + +template <typename F> +class MockFunction; + +template <typename R, typename... Args> +class MockFunction<R(Args...)> { + public: + MockFunction(const MockFunction&) = delete; + MockFunction& operator=(const MockFunction&) = delete; + + std::function<R(Args...)> AsStdFunction() { + return [this](Args... args) -> R { + return this->Call(std::forward<Args>(args)...); + }; + } + + // Implementation detail: the expansion of the MOCK_METHOD macro. + R Call(Args... args) { + mock_.SetOwnerAndName(this, "Call"); + return mock_.Invoke(std::forward<Args>(args)...); + } + + MockSpec<R(Args...)> gmock_Call(Matcher<Args>... m) { + mock_.RegisterOwner(this); + return mock_.With(std::move(m)...); + } + + MockSpec<R(Args...)> gmock_Call(const WithoutMatchers&, R (*)(Args...)) { + return this->gmock_Call(::testing::A<Args>()...); + } + + protected: + MockFunction() = default; + ~MockFunction() = default; + + private: + FunctionMocker<R(Args...)> mock_; +}; + +/* +The SignatureOf<F> struct is a meta-function returning function signature +corresponding to the provided F argument. + +It makes use of MockFunction easier by allowing it to accept more F arguments +than just function signatures. + +Specializations provided here cover only a signature type itself and +std::function. However, if need be it can be easily extended to cover also other +types (like for example boost::function). +*/ + +template <typename F> +struct SignatureOf; + +template <typename R, typename... Args> +struct SignatureOf<R(Args...)> { + using type = R(Args...); +}; + +template <typename F> +struct SignatureOf<std::function<F>> : SignatureOf<F> {}; + +template <typename F> +using SignatureOfT = typename SignatureOf<F>::type; + +} // namespace internal + +// A MockFunction<F> type has one mock method whose type is +// internal::SignatureOfT<F>. It is useful when you just want your +// test code to emit some messages and have Google Mock verify the +// right messages are sent (and perhaps at the right times). For +// example, if you are exercising code: +// +// Foo(1); +// Foo(2); +// Foo(3); +// +// and want to verify that Foo(1) and Foo(3) both invoke +// mock.Bar("a"), but Foo(2) doesn't invoke anything, you can write: +// +// TEST(FooTest, InvokesBarCorrectly) { +// MyMock mock; +// MockFunction<void(string check_point_name)> check; +// { +// InSequence s; +// +// EXPECT_CALL(mock, Bar("a")); +// EXPECT_CALL(check, Call("1")); +// EXPECT_CALL(check, Call("2")); +// EXPECT_CALL(mock, Bar("a")); +// } +// Foo(1); +// check.Call("1"); +// Foo(2); +// check.Call("2"); +// Foo(3); +// } +// +// The expectation spec says that the first Bar("a") must happen +// before check point "1", the second Bar("a") must happen after check +// point "2", and nothing should happen between the two check +// points. The explicit check points make it easy to tell which +// Bar("a") is called by which call to Foo(). +// +// MockFunction<F> can also be used to exercise code that accepts +// std::function<internal::SignatureOfT<F>> callbacks. To do so, use +// AsStdFunction() method to create std::function proxy forwarding to +// original object's Call. Example: +// +// TEST(FooTest, RunsCallbackWithBarArgument) { +// MockFunction<int(string)> callback; +// EXPECT_CALL(callback, Call("bar")).WillOnce(Return(1)); +// Foo(callback.AsStdFunction()); +// } +// +// The internal::SignatureOfT<F> indirection allows to use other types +// than just function signature type. This is typically useful when +// providing a mock for a predefined std::function type. Example: +// +// using FilterPredicate = std::function<bool(string)>; +// void MyFilterAlgorithm(FilterPredicate predicate); +// +// TEST(FooTest, FilterPredicateAlwaysAccepts) { +// MockFunction<FilterPredicate> predicateMock; +// EXPECT_CALL(predicateMock, Call(_)).WillRepeatedly(Return(true)); +// MyFilterAlgorithm(predicateMock.AsStdFunction()); +// } +template <typename F> +class MockFunction : public internal::MockFunction<internal::SignatureOfT<F>> { + using Base = internal::MockFunction<internal::SignatureOfT<F>>; + + public: + using Base::Base; +}; + +// The style guide prohibits "using" statements in a namespace scope +// inside a header file. However, the MockSpec class template is +// meant to be defined in the ::testing namespace. The following line +// is just a trick for working around a bug in MSVC 8.0, which cannot +// handle it if we define MockSpec in ::testing. +using internal::MockSpec; + +// Const(x) is a convenient function for obtaining a const reference +// to x. This is useful for setting expectations on an overloaded +// const mock method, e.g. +// +// class MockFoo : public FooInterface { +// public: +// MOCK_METHOD0(Bar, int()); +// MOCK_CONST_METHOD0(Bar, int&()); +// }; +// +// MockFoo foo; +// // Expects a call to non-const MockFoo::Bar(). +// EXPECT_CALL(foo, Bar()); +// // Expects a call to const MockFoo::Bar(). +// EXPECT_CALL(Const(foo), Bar()); +template <typename T> +inline const T& Const(const T& x) { return x; } + +// Constructs an Expectation object that references and co-owns exp. +inline Expectation::Expectation(internal::ExpectationBase& exp) // NOLINT + : expectation_base_(exp.GetHandle().expectation_base()) {} + +} // namespace testing + +GTEST_DISABLE_MSC_WARNINGS_POP_() // 4251 + +// Implementation for ON_CALL and EXPECT_CALL macros. A separate macro is +// required to avoid compile errors when the name of the method used in call is +// a result of macro expansion. See CompilesWithMethodNameExpandedFromMacro +// tests in internal/gmock-spec-builders_test.cc for more details. +// +// This macro supports statements both with and without parameter matchers. If +// the parameter list is omitted, gMock will accept any parameters, which allows +// tests to be written that don't need to encode the number of method +// parameter. This technique may only be used for non-overloaded methods. +// +// // These are the same: +// ON_CALL(mock, NoArgsMethod()).WillByDefault(...); +// ON_CALL(mock, NoArgsMethod).WillByDefault(...); +// +// // As are these: +// ON_CALL(mock, TwoArgsMethod(_, _)).WillByDefault(...); +// ON_CALL(mock, TwoArgsMethod).WillByDefault(...); +// +// // Can also specify args if you want, of course: +// ON_CALL(mock, TwoArgsMethod(_, 45)).WillByDefault(...); +// +// // Overloads work as long as you specify parameters: +// ON_CALL(mock, OverloadedMethod(_)).WillByDefault(...); +// ON_CALL(mock, OverloadedMethod(_, _)).WillByDefault(...); +// +// // Oops! Which overload did you want? +// ON_CALL(mock, OverloadedMethod).WillByDefault(...); +// => ERROR: call to member function 'gmock_OverloadedMethod' is ambiguous +// +// How this works: The mock class uses two overloads of the gmock_Method +// expectation setter method plus an operator() overload on the MockSpec object. +// In the matcher list form, the macro expands to: +// +// // This statement: +// ON_CALL(mock, TwoArgsMethod(_, 45))... +// +// // ...expands to: +// mock.gmock_TwoArgsMethod(_, 45)(WithoutMatchers(), nullptr)... +// |-------------v---------------||------------v-------------| +// invokes first overload swallowed by operator() +// +// // ...which is essentially: +// mock.gmock_TwoArgsMethod(_, 45)... +// +// Whereas the form without a matcher list: +// +// // This statement: +// ON_CALL(mock, TwoArgsMethod)... +// +// // ...expands to: +// mock.gmock_TwoArgsMethod(WithoutMatchers(), nullptr)... +// |-----------------------v--------------------------| +// invokes second overload +// +// // ...which is essentially: +// mock.gmock_TwoArgsMethod(_, _)... +// +// The WithoutMatchers() argument is used to disambiguate overloads and to +// block the caller from accidentally invoking the second overload directly. The +// second argument is an internal type derived from the method signature. The +// failure to disambiguate two overloads of this method in the ON_CALL statement +// is how we block callers from setting expectations on overloaded methods. +#define GMOCK_ON_CALL_IMPL_(mock_expr, Setter, call) \ + ((mock_expr).gmock_##call)(::testing::internal::GetWithoutMatchers(), \ + nullptr) \ + .Setter(__FILE__, __LINE__, #mock_expr, #call) + +#define ON_CALL(obj, call) \ + GMOCK_ON_CALL_IMPL_(obj, InternalDefaultActionSetAt, call) + +#define EXPECT_CALL(obj, call) \ + GMOCK_ON_CALL_IMPL_(obj, InternalExpectedAt, call) + +#endif // GMOCK_INCLUDE_GMOCK_GMOCK_SPEC_BUILDERS_H_ diff --git a/src/googletest/googlemock/include/gmock/gmock.h b/src/googletest/googlemock/include/gmock/gmock.h new file mode 100644 index 000000000..8a4aceaee --- /dev/null +++ b/src/googletest/googlemock/include/gmock/gmock.h @@ -0,0 +1,98 @@ +// 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. + + +// Google Mock - a framework for writing C++ mock classes. +// +// This is the main header file a user should include. + +// GOOGLETEST_CM0002 DO NOT DELETE + +#ifndef GMOCK_INCLUDE_GMOCK_GMOCK_H_ +#define GMOCK_INCLUDE_GMOCK_GMOCK_H_ + +// This file implements the following syntax: +// +// ON_CALL(mock_object, Method(...)) +// .With(...) ? +// .WillByDefault(...); +// +// where With() is optional and WillByDefault() must appear exactly +// once. +// +// EXPECT_CALL(mock_object, Method(...)) +// .With(...) ? +// .Times(...) ? +// .InSequence(...) * +// .WillOnce(...) * +// .WillRepeatedly(...) ? +// .RetiresOnSaturation() ? ; +// +// where all clauses are optional and WillOnce() can be repeated. + +#include "gmock/gmock-actions.h" +#include "gmock/gmock-cardinalities.h" +#include "gmock/gmock-function-mocker.h" +#include "gmock/gmock-generated-actions.h" +#include "gmock/gmock-matchers.h" +#include "gmock/gmock-more-matchers.h" +#include "gmock/gmock-nice-strict.h" +#include "gmock/internal/gmock-internal-utils.h" + +namespace testing { + +// Declares Google Mock flags that we want a user to use programmatically. +GMOCK_DECLARE_bool_(catch_leaked_mocks); +GMOCK_DECLARE_string_(verbose); +GMOCK_DECLARE_int32_(default_mock_behavior); + +// Initializes Google Mock. This must be called before running the +// tests. In particular, it parses the command line for the flags +// that Google Mock recognizes. Whenever a Google Mock flag is seen, +// it is removed from argv, and *argc is decremented. +// +// No value is returned. Instead, the Google Mock flag variables are +// updated. +// +// Since Google Test is needed for Google Mock to work, this function +// also initializes Google Test and parses its flags, if that hasn't +// been done. +GTEST_API_ void InitGoogleMock(int* argc, char** argv); + +// This overloaded version can be used in Windows programs compiled in +// UNICODE mode. +GTEST_API_ void InitGoogleMock(int* argc, wchar_t** argv); + +// This overloaded version can be used on Arduino/embedded platforms where +// there is no argc/argv. +GTEST_API_ void InitGoogleMock(); + +} // namespace testing + +#endif // GMOCK_INCLUDE_GMOCK_GMOCK_H_ diff --git a/src/googletest/googlemock/include/gmock/internal/custom/README.md b/src/googletest/googlemock/include/gmock/internal/custom/README.md new file mode 100644 index 000000000..f6c93f616 --- /dev/null +++ b/src/googletest/googlemock/include/gmock/internal/custom/README.md @@ -0,0 +1,16 @@ +# Customization Points + +The custom directory is an injection point for custom user configurations. + +## Header `gmock-port.h` + +The following macros can be defined: + +### Flag related macros: + +* `GMOCK_DECLARE_bool_(name)` +* `GMOCK_DECLARE_int32_(name)` +* `GMOCK_DECLARE_string_(name)` +* `GMOCK_DEFINE_bool_(name, default_val, doc)` +* `GMOCK_DEFINE_int32_(name, default_val, doc)` +* `GMOCK_DEFINE_string_(name, default_val, doc)` diff --git a/src/googletest/googlemock/include/gmock/internal/custom/gmock-generated-actions.h b/src/googletest/googlemock/include/gmock/internal/custom/gmock-generated-actions.h new file mode 100644 index 000000000..92d910cf0 --- /dev/null +++ b/src/googletest/googlemock/include/gmock/internal/custom/gmock-generated-actions.h @@ -0,0 +1,10 @@ +// This file was GENERATED by command: +// pump.py gmock-generated-actions.h.pump +// DO NOT EDIT BY HAND!!! + +// GOOGLETEST_CM0002 DO NOT DELETE + +#ifndef GMOCK_INCLUDE_GMOCK_INTERNAL_CUSTOM_GMOCK_GENERATED_ACTIONS_H_ +#define GMOCK_INCLUDE_GMOCK_INTERNAL_CUSTOM_GMOCK_GENERATED_ACTIONS_H_ + +#endif // GMOCK_INCLUDE_GMOCK_INTERNAL_CUSTOM_GMOCK_GENERATED_ACTIONS_H_ diff --git a/src/googletest/googlemock/include/gmock/internal/custom/gmock-generated-actions.h.pump b/src/googletest/googlemock/include/gmock/internal/custom/gmock-generated-actions.h.pump new file mode 100644 index 000000000..67c221f14 --- /dev/null +++ b/src/googletest/googlemock/include/gmock/internal/custom/gmock-generated-actions.h.pump @@ -0,0 +1,12 @@ +$$ -*- mode: c++; -*- +$$ This is a Pump source file. Please use Pump to convert +$$ it to callback-actions.h. +$$ +$var max_callback_arity = 5 +$$}} This meta comment fixes auto-indentation in editors. + +// GOOGLETEST_CM0002 DO NOT DELETE +#ifndef GMOCK_INCLUDE_GMOCK_INTERNAL_CUSTOM_GMOCK_GENERATED_ACTIONS_H_ +#define GMOCK_INCLUDE_GMOCK_INTERNAL_CUSTOM_GMOCK_GENERATED_ACTIONS_H_ + +#endif // GMOCK_INCLUDE_GMOCK_INTERNAL_CUSTOM_GMOCK_GENERATED_ACTIONS_H_ diff --git a/src/googletest/googlemock/include/gmock/internal/custom/gmock-matchers.h b/src/googletest/googlemock/include/gmock/internal/custom/gmock-matchers.h new file mode 100644 index 000000000..14aafaabe --- /dev/null +++ b/src/googletest/googlemock/include/gmock/internal/custom/gmock-matchers.h @@ -0,0 +1,36 @@ +// Copyright 2015, 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. +// +// Injection point for custom user configurations. See README for details +// +// GOOGLETEST_CM0002 DO NOT DELETE + +#ifndef GMOCK_INCLUDE_GMOCK_INTERNAL_CUSTOM_GMOCK_MATCHERS_H_ +#define GMOCK_INCLUDE_GMOCK_INTERNAL_CUSTOM_GMOCK_MATCHERS_H_ +#endif // GMOCK_INCLUDE_GMOCK_INTERNAL_CUSTOM_GMOCK_MATCHERS_H_ diff --git a/src/googletest/googlemock/include/gmock/internal/custom/gmock-port.h b/src/googletest/googlemock/include/gmock/internal/custom/gmock-port.h new file mode 100644 index 000000000..0030fe911 --- /dev/null +++ b/src/googletest/googlemock/include/gmock/internal/custom/gmock-port.h @@ -0,0 +1,39 @@ +// Copyright 2015, 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. +// +// Injection point for custom user configurations. See README for details +// +// ** Custom implementation starts here ** + +// GOOGLETEST_CM0002 DO NOT DELETE + +#ifndef GMOCK_INCLUDE_GMOCK_INTERNAL_CUSTOM_GMOCK_PORT_H_ +#define GMOCK_INCLUDE_GMOCK_INTERNAL_CUSTOM_GMOCK_PORT_H_ + +#endif // GMOCK_INCLUDE_GMOCK_INTERNAL_CUSTOM_GMOCK_PORT_H_ diff --git a/src/googletest/googlemock/include/gmock/internal/gmock-internal-utils.h b/src/googletest/googlemock/include/gmock/internal/gmock-internal-utils.h new file mode 100644 index 000000000..200c30e41 --- /dev/null +++ b/src/googletest/googlemock/include/gmock/internal/gmock-internal-utils.h @@ -0,0 +1,459 @@ +// 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. + + +// Google Mock - a framework for writing C++ mock classes. +// +// This file defines some utilities useful for implementing Google +// Mock. They are subject to change without notice, so please DO NOT +// USE THEM IN USER CODE. + +// GOOGLETEST_CM0002 DO NOT DELETE + +#ifndef GMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_INTERNAL_UTILS_H_ +#define GMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_INTERNAL_UTILS_H_ + +#include <stdio.h> +#include <ostream> // NOLINT +#include <string> +#include <type_traits> +#include "gmock/internal/gmock-port.h" +#include "gtest/gtest.h" + +namespace testing { + +template <typename> +class Matcher; + +namespace internal { + +// Silence MSVC C4100 (unreferenced formal parameter) and +// C4805('==': unsafe mix of type 'const int' and type 'const bool') +#ifdef _MSC_VER +# pragma warning(push) +# pragma warning(disable:4100) +# pragma warning(disable:4805) +#endif + +// Joins a vector of strings as if they are fields of a tuple; returns +// the joined string. +GTEST_API_ std::string JoinAsTuple(const Strings& fields); + +// Converts an identifier name to a space-separated list of lower-case +// words. Each maximum substring of the form [A-Za-z][a-z]*|\d+ is +// treated as one word. For example, both "FooBar123" and +// "foo_bar_123" are converted to "foo bar 123". +GTEST_API_ std::string ConvertIdentifierNameToWords(const char* id_name); + +// GetRawPointer(p) returns the raw pointer underlying p when p is a +// smart pointer, or returns p itself when p is already a raw pointer. +// The following default implementation is for the smart pointer case. +template <typename Pointer> +inline const typename Pointer::element_type* GetRawPointer(const Pointer& p) { + return p.get(); +} +// This overloaded version is for the raw pointer case. +template <typename Element> +inline Element* GetRawPointer(Element* p) { return p; } + +// MSVC treats wchar_t as a native type usually, but treats it as the +// same as unsigned short when the compiler option /Zc:wchar_t- is +// specified. It defines _NATIVE_WCHAR_T_DEFINED symbol when wchar_t +// is a native type. +#if defined(_MSC_VER) && !defined(_NATIVE_WCHAR_T_DEFINED) +// wchar_t is a typedef. +#else +# define GMOCK_WCHAR_T_IS_NATIVE_ 1 +#endif + +// In what follows, we use the term "kind" to indicate whether a type +// is bool, an integer type (excluding bool), a floating-point type, +// or none of them. This categorization is useful for determining +// when a matcher argument type can be safely converted to another +// type in the implementation of SafeMatcherCast. +enum TypeKind { + kBool, kInteger, kFloatingPoint, kOther +}; + +// KindOf<T>::value is the kind of type T. +template <typename T> struct KindOf { + enum { value = kOther }; // The default kind. +}; + +// This macro declares that the kind of 'type' is 'kind'. +#define GMOCK_DECLARE_KIND_(type, kind) \ + template <> struct KindOf<type> { enum { value = kind }; } + +GMOCK_DECLARE_KIND_(bool, kBool); + +// All standard integer types. +GMOCK_DECLARE_KIND_(char, kInteger); +GMOCK_DECLARE_KIND_(signed char, kInteger); +GMOCK_DECLARE_KIND_(unsigned char, kInteger); +GMOCK_DECLARE_KIND_(short, kInteger); // NOLINT +GMOCK_DECLARE_KIND_(unsigned short, kInteger); // NOLINT +GMOCK_DECLARE_KIND_(int, kInteger); +GMOCK_DECLARE_KIND_(unsigned int, kInteger); +GMOCK_DECLARE_KIND_(long, kInteger); // NOLINT +GMOCK_DECLARE_KIND_(unsigned long, kInteger); // NOLINT +GMOCK_DECLARE_KIND_(long long, kInteger); // NOLINT +GMOCK_DECLARE_KIND_(unsigned long long, kInteger); // NOLINT + +#if GMOCK_WCHAR_T_IS_NATIVE_ +GMOCK_DECLARE_KIND_(wchar_t, kInteger); +#endif + +// All standard floating-point types. +GMOCK_DECLARE_KIND_(float, kFloatingPoint); +GMOCK_DECLARE_KIND_(double, kFloatingPoint); +GMOCK_DECLARE_KIND_(long double, kFloatingPoint); + +#undef GMOCK_DECLARE_KIND_ + +// Evaluates to the kind of 'type'. +#define GMOCK_KIND_OF_(type) \ + static_cast< ::testing::internal::TypeKind>( \ + ::testing::internal::KindOf<type>::value) + +// LosslessArithmeticConvertibleImpl<kFromKind, From, kToKind, To>::value +// is true if and only if arithmetic type From can be losslessly converted to +// arithmetic type To. +// +// It's the user's responsibility to ensure that both From and To are +// raw (i.e. has no CV modifier, is not a pointer, and is not a +// reference) built-in arithmetic types, kFromKind is the kind of +// From, and kToKind is the kind of To; the value is +// implementation-defined when the above pre-condition is violated. +template <TypeKind kFromKind, typename From, TypeKind kToKind, typename To> +using LosslessArithmeticConvertibleImpl = std::integral_constant< + bool, + // clang-format off + // Converting from bool is always lossless + (kFromKind == kBool) ? true + // Converting between any other type kinds will be lossy if the type + // kinds are not the same. + : (kFromKind != kToKind) ? false + : (kFromKind == kInteger && + // Converting between integers of different widths is allowed so long + // as the conversion does not go from signed to unsigned. + (((sizeof(From) < sizeof(To)) && + !(std::is_signed<From>::value && !std::is_signed<To>::value)) || + // Converting between integers of the same width only requires the + // two types to have the same signedness. + ((sizeof(From) == sizeof(To)) && + (std::is_signed<From>::value == std::is_signed<To>::value))) + ) ? true + // Floating point conversions are lossless if and only if `To` is at least + // as wide as `From`. + : (kFromKind == kFloatingPoint && (sizeof(From) <= sizeof(To))) ? true + : false + // clang-format on + >; + +// LosslessArithmeticConvertible<From, To>::value is true if and only if +// arithmetic type From can be losslessly converted to arithmetic type To. +// +// It's the user's responsibility to ensure that both From and To are +// raw (i.e. has no CV modifier, is not a pointer, and is not a +// reference) built-in arithmetic types; the value is +// implementation-defined when the above pre-condition is violated. +template <typename From, typename To> +using LosslessArithmeticConvertible = + LosslessArithmeticConvertibleImpl<GMOCK_KIND_OF_(From), From, + GMOCK_KIND_OF_(To), To>; + +// This interface knows how to report a Google Mock failure (either +// non-fatal or fatal). +class FailureReporterInterface { + public: + // The type of a failure (either non-fatal or fatal). + enum FailureType { + kNonfatal, kFatal + }; + + virtual ~FailureReporterInterface() {} + + // Reports a failure that occurred at the given source file location. + virtual void ReportFailure(FailureType type, const char* file, int line, + const std::string& message) = 0; +}; + +// Returns the failure reporter used by Google Mock. +GTEST_API_ FailureReporterInterface* GetFailureReporter(); + +// Asserts that condition is true; aborts the process with the given +// message if condition is false. We cannot use LOG(FATAL) or CHECK() +// as Google Mock might be used to mock the log sink itself. We +// inline this function to prevent it from showing up in the stack +// trace. +inline void Assert(bool condition, const char* file, int line, + const std::string& msg) { + if (!condition) { + GetFailureReporter()->ReportFailure(FailureReporterInterface::kFatal, + file, line, msg); + } +} +inline void Assert(bool condition, const char* file, int line) { + Assert(condition, file, line, "Assertion failed."); +} + +// Verifies that condition is true; generates a non-fatal failure if +// condition is false. +inline void Expect(bool condition, const char* file, int line, + const std::string& msg) { + if (!condition) { + GetFailureReporter()->ReportFailure(FailureReporterInterface::kNonfatal, + file, line, msg); + } +} +inline void Expect(bool condition, const char* file, int line) { + Expect(condition, file, line, "Expectation failed."); +} + +// Severity level of a log. +enum LogSeverity { + kInfo = 0, + kWarning = 1 +}; + +// Valid values for the --gmock_verbose flag. + +// All logs (informational and warnings) are printed. +const char kInfoVerbosity[] = "info"; +// Only warnings are printed. +const char kWarningVerbosity[] = "warning"; +// No logs are printed. +const char kErrorVerbosity[] = "error"; + +// Returns true if and only if a log with the given severity is visible +// according to the --gmock_verbose flag. +GTEST_API_ bool LogIsVisible(LogSeverity severity); + +// Prints the given message to stdout if and only if 'severity' >= the level +// specified by the --gmock_verbose flag. If stack_frames_to_skip >= +// 0, also prints the stack trace excluding the top +// stack_frames_to_skip frames. In opt mode, any positive +// stack_frames_to_skip is treated as 0, since we don't know which +// function calls will be inlined by the compiler and need to be +// conservative. +GTEST_API_ void Log(LogSeverity severity, const std::string& message, + int stack_frames_to_skip); + +// A marker class that is used to resolve parameterless expectations to the +// correct overload. This must not be instantiable, to prevent client code from +// accidentally resolving to the overload; for example: +// +// ON_CALL(mock, Method({}, nullptr))... +// +class WithoutMatchers { + private: + WithoutMatchers() {} + friend GTEST_API_ WithoutMatchers GetWithoutMatchers(); +}; + +// Internal use only: access the singleton instance of WithoutMatchers. +GTEST_API_ WithoutMatchers GetWithoutMatchers(); + +// Disable MSVC warnings for infinite recursion, since in this case the +// the recursion is unreachable. +#ifdef _MSC_VER +# pragma warning(push) +# pragma warning(disable:4717) +#endif + +// Invalid<T>() is usable as an expression of type T, but will terminate +// the program with an assertion failure if actually run. This is useful +// when a value of type T is needed for compilation, but the statement +// will not really be executed (or we don't care if the statement +// crashes). +template <typename T> +inline T Invalid() { + Assert(false, "", -1, "Internal error: attempt to return invalid value"); + // This statement is unreachable, and would never terminate even if it + // could be reached. It is provided only to placate compiler warnings + // about missing return statements. + return Invalid<T>(); +} + +#ifdef _MSC_VER +# pragma warning(pop) +#endif + +// Given a raw type (i.e. having no top-level reference or const +// modifier) RawContainer that's either an STL-style container or a +// native array, class StlContainerView<RawContainer> has the +// following members: +// +// - type is a type that provides an STL-style container view to +// (i.e. implements the STL container concept for) RawContainer; +// - const_reference is a type that provides a reference to a const +// RawContainer; +// - ConstReference(raw_container) returns a const reference to an STL-style +// container view to raw_container, which is a RawContainer. +// - Copy(raw_container) returns an STL-style container view of a +// copy of raw_container, which is a RawContainer. +// +// This generic version is used when RawContainer itself is already an +// STL-style container. +template <class RawContainer> +class StlContainerView { + public: + typedef RawContainer type; + typedef const type& const_reference; + + static const_reference ConstReference(const RawContainer& container) { + static_assert(!std::is_const<RawContainer>::value, + "RawContainer type must not be const"); + return container; + } + static type Copy(const RawContainer& container) { return container; } +}; + +// This specialization is used when RawContainer is a native array type. +template <typename Element, size_t N> +class StlContainerView<Element[N]> { + public: + typedef typename std::remove_const<Element>::type RawElement; + typedef internal::NativeArray<RawElement> type; + // NativeArray<T> can represent a native array either by value or by + // reference (selected by a constructor argument), so 'const type' + // can be used to reference a const native array. We cannot + // 'typedef const type& const_reference' here, as that would mean + // ConstReference() has to return a reference to a local variable. + typedef const type const_reference; + + static const_reference ConstReference(const Element (&array)[N]) { + static_assert(std::is_same<Element, RawElement>::value, + "Element type must not be const"); + return type(array, N, RelationToSourceReference()); + } + static type Copy(const Element (&array)[N]) { + return type(array, N, RelationToSourceCopy()); + } +}; + +// This specialization is used when RawContainer is a native array +// represented as a (pointer, size) tuple. +template <typename ElementPointer, typename Size> +class StlContainerView< ::std::tuple<ElementPointer, Size> > { + public: + typedef typename std::remove_const< + typename std::pointer_traits<ElementPointer>::element_type>::type + RawElement; + typedef internal::NativeArray<RawElement> type; + typedef const type const_reference; + + static const_reference ConstReference( + const ::std::tuple<ElementPointer, Size>& array) { + return type(std::get<0>(array), std::get<1>(array), + RelationToSourceReference()); + } + static type Copy(const ::std::tuple<ElementPointer, Size>& array) { + return type(std::get<0>(array), std::get<1>(array), RelationToSourceCopy()); + } +}; + +// The following specialization prevents the user from instantiating +// StlContainer with a reference type. +template <typename T> class StlContainerView<T&>; + +// A type transform to remove constness from the first part of a pair. +// Pairs like that are used as the value_type of associative containers, +// and this transform produces a similar but assignable pair. +template <typename T> +struct RemoveConstFromKey { + typedef T type; +}; + +// Partially specialized to remove constness from std::pair<const K, V>. +template <typename K, typename V> +struct RemoveConstFromKey<std::pair<const K, V> > { + typedef std::pair<K, V> type; +}; + +// Emit an assertion failure due to incorrect DoDefault() usage. Out-of-lined to +// reduce code size. +GTEST_API_ void IllegalDoDefault(const char* file, int line); + +template <typename F, typename Tuple, size_t... Idx> +auto ApplyImpl(F&& f, Tuple&& args, IndexSequence<Idx...>) -> decltype( + std::forward<F>(f)(std::get<Idx>(std::forward<Tuple>(args))...)) { + return std::forward<F>(f)(std::get<Idx>(std::forward<Tuple>(args))...); +} + +// Apply the function to a tuple of arguments. +template <typename F, typename Tuple> +auto Apply(F&& f, Tuple&& args) -> decltype( + ApplyImpl(std::forward<F>(f), std::forward<Tuple>(args), + MakeIndexSequence<std::tuple_size< + typename std::remove_reference<Tuple>::type>::value>())) { + return ApplyImpl(std::forward<F>(f), std::forward<Tuple>(args), + MakeIndexSequence<std::tuple_size< + typename std::remove_reference<Tuple>::type>::value>()); +} + +// Template struct Function<F>, where F must be a function type, contains +// the following typedefs: +// +// Result: the function's return type. +// Arg<N>: the type of the N-th argument, where N starts with 0. +// ArgumentTuple: the tuple type consisting of all parameters of F. +// ArgumentMatcherTuple: the tuple type consisting of Matchers for all +// parameters of F. +// MakeResultVoid: the function type obtained by substituting void +// for the return type of F. +// MakeResultIgnoredValue: +// the function type obtained by substituting Something +// for the return type of F. +template <typename T> +struct Function; + +template <typename R, typename... Args> +struct Function<R(Args...)> { + using Result = R; + static constexpr size_t ArgumentCount = sizeof...(Args); + template <size_t I> + using Arg = ElemFromList<I, Args...>; + using ArgumentTuple = std::tuple<Args...>; + using ArgumentMatcherTuple = std::tuple<Matcher<Args>...>; + using MakeResultVoid = void(Args...); + using MakeResultIgnoredValue = IgnoredValue(Args...); +}; + +template <typename R, typename... Args> +constexpr size_t Function<R(Args...)>::ArgumentCount; + +#ifdef _MSC_VER +# pragma warning(pop) +#endif + +} // namespace internal +} // namespace testing + +#endif // GMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_INTERNAL_UTILS_H_ diff --git a/src/googletest/googlemock/include/gmock/internal/gmock-port.h b/src/googletest/googlemock/include/gmock/internal/gmock-port.h new file mode 100644 index 000000000..70872ef39 --- /dev/null +++ b/src/googletest/googlemock/include/gmock/internal/gmock-port.h @@ -0,0 +1,87 @@ +// 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. + +// +// Low-level types and utilities for porting Google Mock to various +// platforms. All macros ending with _ and symbols defined in an +// internal namespace are subject to change without notice. Code +// outside Google Mock MUST NOT USE THEM DIRECTLY. Macros that don't +// end with _ are part of Google Mock's public API and can be used by +// code outside Google Mock. + +// GOOGLETEST_CM0002 DO NOT DELETE + +#ifndef GMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_PORT_H_ +#define GMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_PORT_H_ + +#include <assert.h> +#include <stdlib.h> +#include <cstdint> +#include <iostream> + +// Most of the utilities needed for porting Google Mock are also +// required for Google Test and are defined in gtest-port.h. +// +// Note to maintainers: to reduce code duplication, prefer adding +// portability utilities to Google Test's gtest-port.h instead of +// here, as Google Mock depends on Google Test. Only add a utility +// here if it's truly specific to Google Mock. + +#include "gtest/internal/gtest-port.h" +#include "gmock/internal/custom/gmock-port.h" + +// For MS Visual C++, check the compiler version. At least VS 2015 is +// required to compile Google Mock. +#if defined(_MSC_VER) && _MSC_VER < 1900 +# error "At least Visual C++ 2015 (14.0) is required to compile Google Mock." +#endif + +// Macro for referencing flags. This is public as we want the user to +// use this syntax to reference Google Mock flags. +#define GMOCK_FLAG(name) FLAGS_gmock_##name + +#if !defined(GMOCK_DECLARE_bool_) + +// Macros for declaring flags. +# define GMOCK_DECLARE_bool_(name) extern GTEST_API_ bool GMOCK_FLAG(name) +# define GMOCK_DECLARE_int32_(name) extern GTEST_API_ int32_t GMOCK_FLAG(name) +# define GMOCK_DECLARE_string_(name) \ + extern GTEST_API_ ::std::string GMOCK_FLAG(name) + +// Macros for defining flags. +# define GMOCK_DEFINE_bool_(name, default_val, doc) \ + GTEST_API_ bool GMOCK_FLAG(name) = (default_val) +# define GMOCK_DEFINE_int32_(name, default_val, doc) \ + GTEST_API_ int32_t GMOCK_FLAG(name) = (default_val) +# define GMOCK_DEFINE_string_(name, default_val, doc) \ + GTEST_API_ ::std::string GMOCK_FLAG(name) = (default_val) + +#endif // !defined(GMOCK_DECLARE_bool_) + +#endif // GMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_PORT_H_ diff --git a/src/googletest/googlemock/include/gmock/internal/gmock-pp.h b/src/googletest/googlemock/include/gmock/internal/gmock-pp.h new file mode 100644 index 000000000..23615c562 --- /dev/null +++ b/src/googletest/googlemock/include/gmock/internal/gmock-pp.h @@ -0,0 +1,279 @@ +#ifndef THIRD_PARTY_GOOGLETEST_GOOGLEMOCK_INCLUDE_GMOCK_PP_H_ +#define THIRD_PARTY_GOOGLETEST_GOOGLEMOCK_INCLUDE_GMOCK_PP_H_ + +// Expands and concatenates the arguments. Constructed macros reevaluate. +#define GMOCK_PP_CAT(_1, _2) GMOCK_PP_INTERNAL_CAT(_1, _2) + +// Expands and stringifies the only argument. +#define GMOCK_PP_STRINGIZE(...) GMOCK_PP_INTERNAL_STRINGIZE(__VA_ARGS__) + +// Returns empty. Given a variadic number of arguments. +#define GMOCK_PP_EMPTY(...) + +// Returns a comma. Given a variadic number of arguments. +#define GMOCK_PP_COMMA(...) , + +// Returns the only argument. +#define GMOCK_PP_IDENTITY(_1) _1 + +// Evaluates to the number of arguments after expansion. +// +// #define PAIR x, y +// +// GMOCK_PP_NARG() => 1 +// GMOCK_PP_NARG(x) => 1 +// GMOCK_PP_NARG(x, y) => 2 +// GMOCK_PP_NARG(PAIR) => 2 +// +// Requires: the number of arguments after expansion is at most 15. +#define GMOCK_PP_NARG(...) \ + GMOCK_PP_INTERNAL_16TH( \ + (__VA_ARGS__, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0)) + +// Returns 1 if the expansion of arguments has an unprotected comma. Otherwise +// returns 0. Requires no more than 15 unprotected commas. +#define GMOCK_PP_HAS_COMMA(...) \ + GMOCK_PP_INTERNAL_16TH( \ + (__VA_ARGS__, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0)) + +// Returns the first argument. +#define GMOCK_PP_HEAD(...) GMOCK_PP_INTERNAL_HEAD((__VA_ARGS__, unusedArg)) + +// Returns the tail. A variadic list of all arguments minus the first. Requires +// at least one argument. +#define GMOCK_PP_TAIL(...) GMOCK_PP_INTERNAL_TAIL((__VA_ARGS__)) + +// Calls CAT(_Macro, NARG(__VA_ARGS__))(__VA_ARGS__) +#define GMOCK_PP_VARIADIC_CALL(_Macro, ...) \ + GMOCK_PP_IDENTITY( \ + GMOCK_PP_CAT(_Macro, GMOCK_PP_NARG(__VA_ARGS__))(__VA_ARGS__)) + +// If the arguments after expansion have no tokens, evaluates to `1`. Otherwise +// evaluates to `0`. +// +// Requires: * the number of arguments after expansion is at most 15. +// * If the argument is a macro, it must be able to be called with one +// argument. +// +// Implementation details: +// +// There is one case when it generates a compile error: if the argument is macro +// that cannot be called with one argument. +// +// #define M(a, b) // it doesn't matter what it expands to +// +// // Expected: expands to `0`. +// // Actual: compile error. +// GMOCK_PP_IS_EMPTY(M) +// +// There are 4 cases tested: +// +// * __VA_ARGS__ possible expansion has no unparen'd commas. Expected 0. +// * __VA_ARGS__ possible expansion is not enclosed in parenthesis. Expected 0. +// * __VA_ARGS__ possible expansion is not a macro that ()-evaluates to a comma. +// Expected 0 +// * __VA_ARGS__ is empty, or has unparen'd commas, or is enclosed in +// parenthesis, or is a macro that ()-evaluates to comma. Expected 1. +// +// We trigger detection on '0001', i.e. on empty. +#define GMOCK_PP_IS_EMPTY(...) \ + GMOCK_PP_INTERNAL_IS_EMPTY(GMOCK_PP_HAS_COMMA(__VA_ARGS__), \ + GMOCK_PP_HAS_COMMA(GMOCK_PP_COMMA __VA_ARGS__), \ + GMOCK_PP_HAS_COMMA(__VA_ARGS__()), \ + GMOCK_PP_HAS_COMMA(GMOCK_PP_COMMA __VA_ARGS__())) + +// Evaluates to _Then if _Cond is 1 and _Else if _Cond is 0. +#define GMOCK_PP_IF(_Cond, _Then, _Else) \ + GMOCK_PP_CAT(GMOCK_PP_INTERNAL_IF_, _Cond)(_Then, _Else) + +// Similar to GMOCK_PP_IF but takes _Then and _Else in parentheses. +// +// GMOCK_PP_GENERIC_IF(1, (a, b, c), (d, e, f)) => a, b, c +// GMOCK_PP_GENERIC_IF(0, (a, b, c), (d, e, f)) => d, e, f +// +#define GMOCK_PP_GENERIC_IF(_Cond, _Then, _Else) \ + GMOCK_PP_REMOVE_PARENS(GMOCK_PP_IF(_Cond, _Then, _Else)) + +// Evaluates to the number of arguments after expansion. Identifies 'empty' as +// 0. +// +// #define PAIR x, y +// +// GMOCK_PP_NARG0() => 0 +// GMOCK_PP_NARG0(x) => 1 +// GMOCK_PP_NARG0(x, y) => 2 +// GMOCK_PP_NARG0(PAIR) => 2 +// +// Requires: * the number of arguments after expansion is at most 15. +// * If the argument is a macro, it must be able to be called with one +// argument. +#define GMOCK_PP_NARG0(...) \ + GMOCK_PP_IF(GMOCK_PP_IS_EMPTY(__VA_ARGS__), 0, GMOCK_PP_NARG(__VA_ARGS__)) + +// Expands to 1 if the first argument starts with something in parentheses, +// otherwise to 0. +#define GMOCK_PP_IS_BEGIN_PARENS(...) \ + GMOCK_PP_HEAD(GMOCK_PP_CAT(GMOCK_PP_INTERNAL_IBP_IS_VARIADIC_R_, \ + GMOCK_PP_INTERNAL_IBP_IS_VARIADIC_C __VA_ARGS__)) + +// Expands to 1 is there is only one argument and it is enclosed in parentheses. +#define GMOCK_PP_IS_ENCLOSED_PARENS(...) \ + GMOCK_PP_IF(GMOCK_PP_IS_BEGIN_PARENS(__VA_ARGS__), \ + GMOCK_PP_IS_EMPTY(GMOCK_PP_EMPTY __VA_ARGS__), 0) + +// Remove the parens, requires GMOCK_PP_IS_ENCLOSED_PARENS(args) => 1. +#define GMOCK_PP_REMOVE_PARENS(...) GMOCK_PP_INTERNAL_REMOVE_PARENS __VA_ARGS__ + +// Expands to _Macro(0, _Data, e1) _Macro(1, _Data, e2) ... _Macro(K -1, _Data, +// eK) as many of GMOCK_INTERNAL_NARG0 _Tuple. +// Requires: * |_Macro| can be called with 3 arguments. +// * |_Tuple| expansion has no more than 15 elements. +#define GMOCK_PP_FOR_EACH(_Macro, _Data, _Tuple) \ + GMOCK_PP_CAT(GMOCK_PP_INTERNAL_FOR_EACH_IMPL_, GMOCK_PP_NARG0 _Tuple) \ + (0, _Macro, _Data, _Tuple) + +// Expands to _Macro(0, _Data, ) _Macro(1, _Data, ) ... _Macro(K - 1, _Data, ) +// Empty if _K = 0. +// Requires: * |_Macro| can be called with 3 arguments. +// * |_K| literal between 0 and 15 +#define GMOCK_PP_REPEAT(_Macro, _Data, _N) \ + GMOCK_PP_CAT(GMOCK_PP_INTERNAL_FOR_EACH_IMPL_, _N) \ + (0, _Macro, _Data, GMOCK_PP_INTENRAL_EMPTY_TUPLE) + +// Increments the argument, requires the argument to be between 0 and 15. +#define GMOCK_PP_INC(_i) GMOCK_PP_CAT(GMOCK_PP_INTERNAL_INC_, _i) + +// Returns comma if _i != 0. Requires _i to be between 0 and 15. +#define GMOCK_PP_COMMA_IF(_i) GMOCK_PP_CAT(GMOCK_PP_INTERNAL_COMMA_IF_, _i) + +// Internal details follow. Do not use any of these symbols outside of this +// file or we will break your code. +#define GMOCK_PP_INTENRAL_EMPTY_TUPLE (, , , , , , , , , , , , , , , ) +#define GMOCK_PP_INTERNAL_CAT(_1, _2) _1##_2 +#define GMOCK_PP_INTERNAL_STRINGIZE(...) #__VA_ARGS__ +#define GMOCK_PP_INTERNAL_CAT_5(_1, _2, _3, _4, _5) _1##_2##_3##_4##_5 +#define GMOCK_PP_INTERNAL_IS_EMPTY(_1, _2, _3, _4) \ + GMOCK_PP_HAS_COMMA(GMOCK_PP_INTERNAL_CAT_5(GMOCK_PP_INTERNAL_IS_EMPTY_CASE_, \ + _1, _2, _3, _4)) +#define GMOCK_PP_INTERNAL_IS_EMPTY_CASE_0001 , +#define GMOCK_PP_INTERNAL_IF_1(_Then, _Else) _Then +#define GMOCK_PP_INTERNAL_IF_0(_Then, _Else) _Else + +// Because of MSVC treating a token with a comma in it as a single token when +// passed to another macro, we need to force it to evaluate it as multiple +// tokens. We do that by using a "IDENTITY(MACRO PARENTHESIZED_ARGS)" macro. We +// define one per possible macro that relies on this behavior. Note "_Args" must +// be parenthesized. +#define GMOCK_PP_INTERNAL_INTERNAL_16TH(_1, _2, _3, _4, _5, _6, _7, _8, _9, \ + _10, _11, _12, _13, _14, _15, _16, \ + ...) \ + _16 +#define GMOCK_PP_INTERNAL_16TH(_Args) \ + GMOCK_PP_IDENTITY(GMOCK_PP_INTERNAL_INTERNAL_16TH _Args) +#define GMOCK_PP_INTERNAL_INTERNAL_HEAD(_1, ...) _1 +#define GMOCK_PP_INTERNAL_HEAD(_Args) \ + GMOCK_PP_IDENTITY(GMOCK_PP_INTERNAL_INTERNAL_HEAD _Args) +#define GMOCK_PP_INTERNAL_INTERNAL_TAIL(_1, ...) __VA_ARGS__ +#define GMOCK_PP_INTERNAL_TAIL(_Args) \ + GMOCK_PP_IDENTITY(GMOCK_PP_INTERNAL_INTERNAL_TAIL _Args) + +#define GMOCK_PP_INTERNAL_IBP_IS_VARIADIC_C(...) 1 _ +#define GMOCK_PP_INTERNAL_IBP_IS_VARIADIC_R_1 1, +#define GMOCK_PP_INTERNAL_IBP_IS_VARIADIC_R_GMOCK_PP_INTERNAL_IBP_IS_VARIADIC_C \ + 0, +#define GMOCK_PP_INTERNAL_REMOVE_PARENS(...) __VA_ARGS__ +#define GMOCK_PP_INTERNAL_INC_0 1 +#define GMOCK_PP_INTERNAL_INC_1 2 +#define GMOCK_PP_INTERNAL_INC_2 3 +#define GMOCK_PP_INTERNAL_INC_3 4 +#define GMOCK_PP_INTERNAL_INC_4 5 +#define GMOCK_PP_INTERNAL_INC_5 6 +#define GMOCK_PP_INTERNAL_INC_6 7 +#define GMOCK_PP_INTERNAL_INC_7 8 +#define GMOCK_PP_INTERNAL_INC_8 9 +#define GMOCK_PP_INTERNAL_INC_9 10 +#define GMOCK_PP_INTERNAL_INC_10 11 +#define GMOCK_PP_INTERNAL_INC_11 12 +#define GMOCK_PP_INTERNAL_INC_12 13 +#define GMOCK_PP_INTERNAL_INC_13 14 +#define GMOCK_PP_INTERNAL_INC_14 15 +#define GMOCK_PP_INTERNAL_INC_15 16 +#define GMOCK_PP_INTERNAL_COMMA_IF_0 +#define GMOCK_PP_INTERNAL_COMMA_IF_1 , +#define GMOCK_PP_INTERNAL_COMMA_IF_2 , +#define GMOCK_PP_INTERNAL_COMMA_IF_3 , +#define GMOCK_PP_INTERNAL_COMMA_IF_4 , +#define GMOCK_PP_INTERNAL_COMMA_IF_5 , +#define GMOCK_PP_INTERNAL_COMMA_IF_6 , +#define GMOCK_PP_INTERNAL_COMMA_IF_7 , +#define GMOCK_PP_INTERNAL_COMMA_IF_8 , +#define GMOCK_PP_INTERNAL_COMMA_IF_9 , +#define GMOCK_PP_INTERNAL_COMMA_IF_10 , +#define GMOCK_PP_INTERNAL_COMMA_IF_11 , +#define GMOCK_PP_INTERNAL_COMMA_IF_12 , +#define GMOCK_PP_INTERNAL_COMMA_IF_13 , +#define GMOCK_PP_INTERNAL_COMMA_IF_14 , +#define GMOCK_PP_INTERNAL_COMMA_IF_15 , +#define GMOCK_PP_INTERNAL_CALL_MACRO(_Macro, _i, _Data, _element) \ + _Macro(_i, _Data, _element) +#define GMOCK_PP_INTERNAL_FOR_EACH_IMPL_0(_i, _Macro, _Data, _Tuple) +#define GMOCK_PP_INTERNAL_FOR_EACH_IMPL_1(_i, _Macro, _Data, _Tuple) \ + GMOCK_PP_INTERNAL_CALL_MACRO(_Macro, _i, _Data, GMOCK_PP_HEAD _Tuple) +#define GMOCK_PP_INTERNAL_FOR_EACH_IMPL_2(_i, _Macro, _Data, _Tuple) \ + GMOCK_PP_INTERNAL_CALL_MACRO(_Macro, _i, _Data, GMOCK_PP_HEAD _Tuple) \ + GMOCK_PP_INTERNAL_FOR_EACH_IMPL_1(GMOCK_PP_INC(_i), _Macro, _Data, \ + (GMOCK_PP_TAIL _Tuple)) +#define GMOCK_PP_INTERNAL_FOR_EACH_IMPL_3(_i, _Macro, _Data, _Tuple) \ + GMOCK_PP_INTERNAL_CALL_MACRO(_Macro, _i, _Data, GMOCK_PP_HEAD _Tuple) \ + GMOCK_PP_INTERNAL_FOR_EACH_IMPL_2(GMOCK_PP_INC(_i), _Macro, _Data, \ + (GMOCK_PP_TAIL _Tuple)) +#define GMOCK_PP_INTERNAL_FOR_EACH_IMPL_4(_i, _Macro, _Data, _Tuple) \ + GMOCK_PP_INTERNAL_CALL_MACRO(_Macro, _i, _Data, GMOCK_PP_HEAD _Tuple) \ + GMOCK_PP_INTERNAL_FOR_EACH_IMPL_3(GMOCK_PP_INC(_i), _Macro, _Data, \ + (GMOCK_PP_TAIL _Tuple)) +#define GMOCK_PP_INTERNAL_FOR_EACH_IMPL_5(_i, _Macro, _Data, _Tuple) \ + GMOCK_PP_INTERNAL_CALL_MACRO(_Macro, _i, _Data, GMOCK_PP_HEAD _Tuple) \ + GMOCK_PP_INTERNAL_FOR_EACH_IMPL_4(GMOCK_PP_INC(_i), _Macro, _Data, \ + (GMOCK_PP_TAIL _Tuple)) +#define GMOCK_PP_INTERNAL_FOR_EACH_IMPL_6(_i, _Macro, _Data, _Tuple) \ + GMOCK_PP_INTERNAL_CALL_MACRO(_Macro, _i, _Data, GMOCK_PP_HEAD _Tuple) \ + GMOCK_PP_INTERNAL_FOR_EACH_IMPL_5(GMOCK_PP_INC(_i), _Macro, _Data, \ + (GMOCK_PP_TAIL _Tuple)) +#define GMOCK_PP_INTERNAL_FOR_EACH_IMPL_7(_i, _Macro, _Data, _Tuple) \ + GMOCK_PP_INTERNAL_CALL_MACRO(_Macro, _i, _Data, GMOCK_PP_HEAD _Tuple) \ + GMOCK_PP_INTERNAL_FOR_EACH_IMPL_6(GMOCK_PP_INC(_i), _Macro, _Data, \ + (GMOCK_PP_TAIL _Tuple)) +#define GMOCK_PP_INTERNAL_FOR_EACH_IMPL_8(_i, _Macro, _Data, _Tuple) \ + GMOCK_PP_INTERNAL_CALL_MACRO(_Macro, _i, _Data, GMOCK_PP_HEAD _Tuple) \ + GMOCK_PP_INTERNAL_FOR_EACH_IMPL_7(GMOCK_PP_INC(_i), _Macro, _Data, \ + (GMOCK_PP_TAIL _Tuple)) +#define GMOCK_PP_INTERNAL_FOR_EACH_IMPL_9(_i, _Macro, _Data, _Tuple) \ + GMOCK_PP_INTERNAL_CALL_MACRO(_Macro, _i, _Data, GMOCK_PP_HEAD _Tuple) \ + GMOCK_PP_INTERNAL_FOR_EACH_IMPL_8(GMOCK_PP_INC(_i), _Macro, _Data, \ + (GMOCK_PP_TAIL _Tuple)) +#define GMOCK_PP_INTERNAL_FOR_EACH_IMPL_10(_i, _Macro, _Data, _Tuple) \ + GMOCK_PP_INTERNAL_CALL_MACRO(_Macro, _i, _Data, GMOCK_PP_HEAD _Tuple) \ + GMOCK_PP_INTERNAL_FOR_EACH_IMPL_9(GMOCK_PP_INC(_i), _Macro, _Data, \ + (GMOCK_PP_TAIL _Tuple)) +#define GMOCK_PP_INTERNAL_FOR_EACH_IMPL_11(_i, _Macro, _Data, _Tuple) \ + GMOCK_PP_INTERNAL_CALL_MACRO(_Macro, _i, _Data, GMOCK_PP_HEAD _Tuple) \ + GMOCK_PP_INTERNAL_FOR_EACH_IMPL_10(GMOCK_PP_INC(_i), _Macro, _Data, \ + (GMOCK_PP_TAIL _Tuple)) +#define GMOCK_PP_INTERNAL_FOR_EACH_IMPL_12(_i, _Macro, _Data, _Tuple) \ + GMOCK_PP_INTERNAL_CALL_MACRO(_Macro, _i, _Data, GMOCK_PP_HEAD _Tuple) \ + GMOCK_PP_INTERNAL_FOR_EACH_IMPL_11(GMOCK_PP_INC(_i), _Macro, _Data, \ + (GMOCK_PP_TAIL _Tuple)) +#define GMOCK_PP_INTERNAL_FOR_EACH_IMPL_13(_i, _Macro, _Data, _Tuple) \ + GMOCK_PP_INTERNAL_CALL_MACRO(_Macro, _i, _Data, GMOCK_PP_HEAD _Tuple) \ + GMOCK_PP_INTERNAL_FOR_EACH_IMPL_12(GMOCK_PP_INC(_i), _Macro, _Data, \ + (GMOCK_PP_TAIL _Tuple)) +#define GMOCK_PP_INTERNAL_FOR_EACH_IMPL_14(_i, _Macro, _Data, _Tuple) \ + GMOCK_PP_INTERNAL_CALL_MACRO(_Macro, _i, _Data, GMOCK_PP_HEAD _Tuple) \ + GMOCK_PP_INTERNAL_FOR_EACH_IMPL_13(GMOCK_PP_INC(_i), _Macro, _Data, \ + (GMOCK_PP_TAIL _Tuple)) +#define GMOCK_PP_INTERNAL_FOR_EACH_IMPL_15(_i, _Macro, _Data, _Tuple) \ + GMOCK_PP_INTERNAL_CALL_MACRO(_Macro, _i, _Data, GMOCK_PP_HEAD _Tuple) \ + GMOCK_PP_INTERNAL_FOR_EACH_IMPL_14(GMOCK_PP_INC(_i), _Macro, _Data, \ + (GMOCK_PP_TAIL _Tuple)) + +#endif // THIRD_PARTY_GOOGLETEST_GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_PP_H_ diff --git a/src/googletest/googlemock/scripts/README.md b/src/googletest/googlemock/scripts/README.md new file mode 100644 index 000000000..a3301e5bf --- /dev/null +++ b/src/googletest/googlemock/scripts/README.md @@ -0,0 +1,5 @@ +# Please Note: + +Files in this directory are no longer supported by the maintainers. They +represent mostly historical artifacts and supported by the community only. There +is no guarantee whatsoever that these scripts still work. diff --git a/src/googletest/googlemock/scripts/fuse_gmock_files.py b/src/googletest/googlemock/scripts/fuse_gmock_files.py new file mode 100755 index 000000000..c3ba3b833 --- /dev/null +++ b/src/googletest/googlemock/scripts/fuse_gmock_files.py @@ -0,0 +1,257 @@ +#!/usr/bin/env python +# +# Copyright 2009, 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. +"""fuse_gmock_files.py v0.1.0. + +Fuses Google Mock and Google Test source code into two .h files and a .cc file. + +SYNOPSIS + fuse_gmock_files.py [GMOCK_ROOT_DIR] OUTPUT_DIR + + Scans GMOCK_ROOT_DIR for Google Mock and Google Test source + code, assuming Google Test is in the GMOCK_ROOT_DIR/../googletest + directory, and generates three files: + OUTPUT_DIR/gtest/gtest.h, OUTPUT_DIR/gmock/gmock.h, and + OUTPUT_DIR/gmock-gtest-all.cc. Then you can build your tests + by adding OUTPUT_DIR to the include search path and linking + with OUTPUT_DIR/gmock-gtest-all.cc. These three files contain + everything you need to use Google Mock. Hence you can + "install" Google Mock by copying them to wherever you want. + + GMOCK_ROOT_DIR can be omitted and defaults to the parent + directory of the directory holding this script. + +EXAMPLES + ./fuse_gmock_files.py fused_gmock + ./fuse_gmock_files.py path/to/unpacked/gmock fused_gmock + +This tool is experimental. In particular, it assumes that there is no +conditional inclusion of Google Mock or Google Test headers. Please +report any problems to googlemock@googlegroups.com. You can read +https://github.com/google/googletest/blob/master/googlemock/docs/cook_book.md +for more +information. +""" + +from __future__ import print_function + +import os +import re +import sys + +__author__ = 'wan@google.com (Zhanyong Wan)' + +# We assume that this file is in the scripts/ directory in the Google +# Mock root directory. +DEFAULT_GMOCK_ROOT_DIR = os.path.join(os.path.dirname(__file__), '..') + +# We need to call into googletest/scripts/fuse_gtest_files.py. +sys.path.append(os.path.join(DEFAULT_GMOCK_ROOT_DIR, '../googletest/scripts')) +import fuse_gtest_files as gtest # pylint:disable=g-import-not-at-top + +# Regex for matching +# '#include "gmock/..."'. +INCLUDE_GMOCK_FILE_REGEX = re.compile(r'^\s*#\s*include\s*"(gmock/.+)"') + +# Where to find the source seed files. +GMOCK_H_SEED = 'include/gmock/gmock.h' +GMOCK_ALL_CC_SEED = 'src/gmock-all.cc' + +# Where to put the generated files. +GTEST_H_OUTPUT = 'gtest/gtest.h' +GMOCK_H_OUTPUT = 'gmock/gmock.h' +GMOCK_GTEST_ALL_CC_OUTPUT = 'gmock-gtest-all.cc' + + +def GetGTestRootDir(gmock_root): + """Returns the root directory of Google Test.""" + + return os.path.join(gmock_root, '../googletest') + + +def ValidateGMockRootDir(gmock_root): + """Makes sure gmock_root points to a valid gmock root directory. + + The function aborts the program on failure. + + Args: + gmock_root: A string with the mock root directory. + """ + + gtest.ValidateGTestRootDir(GetGTestRootDir(gmock_root)) + gtest.VerifyFileExists(gmock_root, GMOCK_H_SEED) + gtest.VerifyFileExists(gmock_root, GMOCK_ALL_CC_SEED) + + +def ValidateOutputDir(output_dir): + """Makes sure output_dir points to a valid output directory. + + The function aborts the program on failure. + + Args: + output_dir: A string representing the output directory. + """ + + gtest.VerifyOutputFile(output_dir, gtest.GTEST_H_OUTPUT) + gtest.VerifyOutputFile(output_dir, GMOCK_H_OUTPUT) + gtest.VerifyOutputFile(output_dir, GMOCK_GTEST_ALL_CC_OUTPUT) + + +def FuseGMockH(gmock_root, output_dir): + """Scans folder gmock_root to generate gmock/gmock.h in output_dir.""" + + output_file = open(os.path.join(output_dir, GMOCK_H_OUTPUT), 'w') + processed_files = set() # Holds all gmock headers we've processed. + + def ProcessFile(gmock_header_path): + """Processes the given gmock header file.""" + + # We don't process the same header twice. + if gmock_header_path in processed_files: + return + + processed_files.add(gmock_header_path) + + # Reads each line in the given gmock header. + + with open(os.path.join(gmock_root, gmock_header_path), 'r') as fh: + for line in fh: + m = INCLUDE_GMOCK_FILE_REGEX.match(line) + if m: + # '#include "gmock/..."' + # - let's process it recursively. + ProcessFile('include/' + m.group(1)) + else: + m = gtest.INCLUDE_GTEST_FILE_REGEX.match(line) + if m: + # '#include "third_party/googletest/googletest/ + # include/gtest/foo.h"'. + # We translate it to "gtest/gtest.h", regardless of what foo is, + # since all gtest headers are fused into gtest/gtest.h. + + # There is no need to #include gtest.h twice. + if gtest.GTEST_H_SEED not in processed_files: + processed_files.add(gtest.GTEST_H_SEED) + output_file.write('#include "%s"\n' % (gtest.GTEST_H_OUTPUT,)) + else: + # Otherwise we copy the line unchanged to the output file. + output_file.write(line) + + ProcessFile(GMOCK_H_SEED) + output_file.close() + + +def FuseGMockAllCcToFile(gmock_root, output_file): + """Scans folder gmock_root to fuse gmock-all.cc into output_file.""" + + processed_files = set() + + def ProcessFile(gmock_source_file): + """Processes the given gmock source file.""" + + # We don't process the same #included file twice. + if gmock_source_file in processed_files: + return + + processed_files.add(gmock_source_file) + + # Reads each line in the given gmock source file. + + with open(os.path.join(gmock_root, gmock_source_file), 'r') as fh: + for line in fh: + m = INCLUDE_GMOCK_FILE_REGEX.match(line) + if m: + # '#include "gmock/foo.h"'. + # We treat it as '#include "gmock/gmock.h"', as all other gmock + # headers are being fused into gmock.h and cannot be + # included directly. No need to #include + # "third_party/googletest/googlemock/include/gmock/gmock.h" + # more than once. + + if GMOCK_H_SEED not in processed_files: + processed_files.add(GMOCK_H_SEED) + output_file.write('#include "%s"\n' % (GMOCK_H_OUTPUT,)) + else: + m = gtest.INCLUDE_GTEST_FILE_REGEX.match(line) + if m: + # '#include "gtest/..."'. + # There is no need to #include gtest.h as it has been + # #included by gtest-all.cc. + + pass + else: + m = gtest.INCLUDE_SRC_FILE_REGEX.match(line) + if m: + # It's '#include "src/foo"' - let's process it recursively. + ProcessFile(m.group(1)) + else: + # Otherwise we copy the line unchanged to the output file. + output_file.write(line) + + ProcessFile(GMOCK_ALL_CC_SEED) + + +def FuseGMockGTestAllCc(gmock_root, output_dir): + """Scans folder gmock_root to generate gmock-gtest-all.cc in output_dir.""" + + with open(os.path.join(output_dir, GMOCK_GTEST_ALL_CC_OUTPUT), + 'w') as output_file: + # First, fuse gtest-all.cc into gmock-gtest-all.cc. + gtest.FuseGTestAllCcToFile(GetGTestRootDir(gmock_root), output_file) + # Next, append fused gmock-all.cc to gmock-gtest-all.cc. + FuseGMockAllCcToFile(gmock_root, output_file) + + +def FuseGMock(gmock_root, output_dir): + """Fuses gtest.h, gmock.h, and gmock-gtest-all.h.""" + + ValidateGMockRootDir(gmock_root) + ValidateOutputDir(output_dir) + + gtest.FuseGTestH(GetGTestRootDir(gmock_root), output_dir) + FuseGMockH(gmock_root, output_dir) + FuseGMockGTestAllCc(gmock_root, output_dir) + + +def main(): + argc = len(sys.argv) + if argc == 2: + # fuse_gmock_files.py OUTPUT_DIR + FuseGMock(DEFAULT_GMOCK_ROOT_DIR, sys.argv[1]) + elif argc == 3: + # fuse_gmock_files.py GMOCK_ROOT_DIR OUTPUT_DIR + FuseGMock(sys.argv[1], sys.argv[2]) + else: + print(__doc__) + sys.exit(1) + + +if __name__ == '__main__': + main() diff --git a/src/googletest/googlemock/scripts/generator/LICENSE b/src/googletest/googlemock/scripts/generator/LICENSE new file mode 100644 index 000000000..87ea06365 --- /dev/null +++ b/src/googletest/googlemock/scripts/generator/LICENSE @@ -0,0 +1,203 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [2007] Neal Norwitz + Portions Copyright [2007] Google Inc. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/src/googletest/googlemock/scripts/generator/README b/src/googletest/googlemock/scripts/generator/README new file mode 100644 index 000000000..01fd463dd --- /dev/null +++ b/src/googletest/googlemock/scripts/generator/README @@ -0,0 +1,34 @@ + +The Google Mock class generator is an application that is part of cppclean. +For more information about cppclean, visit http://code.google.com/p/cppclean/ + +The mock generator requires Python 2.3.5 or later. If you don't have Python +installed on your system, you will also need to install it. You can download +Python from: http://www.python.org/download/releases/ + +To use the Google Mock class generator, you need to call it +on the command line passing the header file and class for which you want +to generate a Google Mock class. + +Make sure to install the scripts somewhere in your path. Then you can +run the program. + + gmock_gen.py header-file.h [ClassName]... + +If no ClassNames are specified, all classes in the file are emitted. + +To change the indentation from the default of 2, set INDENT in +the environment. For example to use an indent of 4 spaces: + +INDENT=4 gmock_gen.py header-file.h ClassName + +This version was made from SVN revision 281 in the cppclean repository. + +Known Limitations +----------------- +Not all code will be generated properly. For example, when mocking templated +classes, the template information is lost. You will need to add the template +information manually. + +Not all permutations of using multiple pointers/references will be rendered +properly. These will also have to be fixed manually. diff --git a/src/googletest/googlemock/scripts/generator/README.cppclean b/src/googletest/googlemock/scripts/generator/README.cppclean new file mode 100644 index 000000000..65431b617 --- /dev/null +++ b/src/googletest/googlemock/scripts/generator/README.cppclean @@ -0,0 +1,115 @@ +Goal: +----- + CppClean attempts to find problems in C++ source that slow development + in large code bases, for example various forms of unused code. + Unused code can be unused functions, methods, data members, types, etc + to unnecessary #include directives. Unnecessary #includes can cause + considerable extra compiles increasing the edit-compile-run cycle. + + The project home page is: http://code.google.com/p/cppclean/ + + +Features: +--------- + * Find and print C++ language constructs: classes, methods, functions, etc. + * Find classes with virtual methods, no virtual destructor, and no bases + * Find global/static data that are potential problems when using threads + * Unnecessary forward class declarations + * Unnecessary function declarations + * Undeclared function definitions + * (planned) Find unnecessary header files #included + - No direct reference to anything in the header + - Header is unnecessary if classes were forward declared instead + * (planned) Source files that reference headers not directly #included, + ie, files that rely on a transitive #include from another header + * (planned) Unused members (private, protected, & public) methods and data + * (planned) Store AST in a SQL database so relationships can be queried + +AST is Abstract Syntax Tree, a representation of parsed source code. +http://en.wikipedia.org/wiki/Abstract_syntax_tree + + +System Requirements: +-------------------- + * Python 2.4 or later (2.3 probably works too) + * Works on Windows (untested), Mac OS X, and Unix + + +How to Run: +----------- + For all examples, it is assumed that cppclean resides in a directory called + /cppclean. + + To print warnings for classes with virtual methods, no virtual destructor and + no base classes: + + /cppclean/run.sh nonvirtual_dtors.py file1.h file2.h file3.cc ... + + To print all the functions defined in header file(s): + + /cppclean/run.sh functions.py file1.h file2.h ... + + All the commands take multiple files on the command line. Other programs + include: find_warnings, headers, methods, and types. Some other programs + are available, but used primarily for debugging. + + run.sh is a simple wrapper that sets PYTHONPATH to /cppclean and then + runs the program in /cppclean/cpp/PROGRAM.py. There is currently + no equivalent for Windows. Contributions for a run.bat file + would be greatly appreciated. + + +How to Configure: +----------------- + You can add a siteheaders.py file in /cppclean/cpp to configure where + to look for other headers (typically -I options passed to a compiler). + Currently two values are supported: _TRANSITIVE and GetIncludeDirs. + _TRANSITIVE should be set to a boolean value (True or False) indicating + whether to transitively process all header files. The default is False. + + GetIncludeDirs is a function that takes a single argument and returns + a sequence of directories to include. This can be a generator or + return a static list. + + def GetIncludeDirs(filename): + return ['/some/path/with/other/headers'] + + # Here is a more complicated example. + def GetIncludeDirs(filename): + yield '/path1' + yield os.path.join('/path2', os.path.dirname(filename)) + yield '/path3' + + +How to Test: +------------ + For all examples, it is assumed that cppclean resides in a directory called + /cppclean. The tests require + + cd /cppclean + make test + # To generate expected results after a change: + make expected + + +Current Status: +--------------- + The parser works pretty well for header files, parsing about 99% of Google's + header files. Anything which inspects structure of C++ source files should + work reasonably well. Function bodies are not transformed to an AST, + but left as tokens. Much work is still needed on finding unused header files + and storing an AST in a database. + + +Non-goals: +---------- + * Parsing all valid C++ source + * Handling invalid C++ source gracefully + * Compiling to machine code (or anything beyond an AST) + + +Contact: +-------- + If you used cppclean, I would love to hear about your experiences + cppclean@googlegroups.com. Even if you don't use cppclean, I'd like to + hear from you. :-) (You can contact me directly at: nnorwitz@gmail.com) diff --git a/src/googletest/googlemock/scripts/generator/cpp/__init__.py b/src/googletest/googlemock/scripts/generator/cpp/__init__.py new file mode 100755 index 000000000..e69de29bb --- /dev/null +++ b/src/googletest/googlemock/scripts/generator/cpp/__init__.py diff --git a/src/googletest/googlemock/scripts/generator/cpp/ast.py b/src/googletest/googlemock/scripts/generator/cpp/ast.py new file mode 100755 index 000000000..cc9f89aa5 --- /dev/null +++ b/src/googletest/googlemock/scripts/generator/cpp/ast.py @@ -0,0 +1,1772 @@ +#!/usr/bin/env python +# +# Copyright 2007 Neal Norwitz +# Portions Copyright 2007 Google Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +"""Generate an Abstract Syntax Tree (AST) for C++.""" + +# FIXME: +# * Tokens should never be exported, need to convert to Nodes +# (return types, parameters, etc.) +# * Handle static class data for templatized classes +# * Handle casts (both C++ and C-style) +# * Handle conditions and loops (if/else, switch, for, while/do) +# +# TODO much, much later: +# * Handle #define +# * exceptions + + +try: + # Python 3.x + import builtins +except ImportError: + # Python 2.x + import __builtin__ as builtins + +import sys +import traceback + +from cpp import keywords +from cpp import tokenize +from cpp import utils + + +if not hasattr(builtins, 'reversed'): + # Support Python 2.3 and earlier. + def reversed(seq): + for i in range(len(seq)-1, -1, -1): + yield seq[i] + +if not hasattr(builtins, 'next'): + # Support Python 2.5 and earlier. + def next(obj): + return obj.next() + + +VISIBILITY_PUBLIC, VISIBILITY_PROTECTED, VISIBILITY_PRIVATE = range(3) + +FUNCTION_NONE = 0x00 +FUNCTION_CONST = 0x01 +FUNCTION_VIRTUAL = 0x02 +FUNCTION_PURE_VIRTUAL = 0x04 +FUNCTION_CTOR = 0x08 +FUNCTION_DTOR = 0x10 +FUNCTION_ATTRIBUTE = 0x20 +FUNCTION_UNKNOWN_ANNOTATION = 0x40 +FUNCTION_THROW = 0x80 +FUNCTION_OVERRIDE = 0x100 + +""" +These are currently unused. Should really handle these properly at some point. + +TYPE_MODIFIER_INLINE = 0x010000 +TYPE_MODIFIER_EXTERN = 0x020000 +TYPE_MODIFIER_STATIC = 0x040000 +TYPE_MODIFIER_CONST = 0x080000 +TYPE_MODIFIER_REGISTER = 0x100000 +TYPE_MODIFIER_VOLATILE = 0x200000 +TYPE_MODIFIER_MUTABLE = 0x400000 + +TYPE_MODIFIER_MAP = { + 'inline': TYPE_MODIFIER_INLINE, + 'extern': TYPE_MODIFIER_EXTERN, + 'static': TYPE_MODIFIER_STATIC, + 'const': TYPE_MODIFIER_CONST, + 'register': TYPE_MODIFIER_REGISTER, + 'volatile': TYPE_MODIFIER_VOLATILE, + 'mutable': TYPE_MODIFIER_MUTABLE, + } +""" + +_INTERNAL_TOKEN = 'internal' +_NAMESPACE_POP = 'ns-pop' + + +# TODO(nnorwitz): use this as a singleton for templated_types, etc +# where we don't want to create a new empty dict each time. It is also const. +class _NullDict(object): + __contains__ = lambda self: False + keys = values = items = iterkeys = itervalues = iteritems = lambda self: () + + +# TODO(nnorwitz): move AST nodes into a separate module. +class Node(object): + """Base AST node.""" + + def __init__(self, start, end): + self.start = start + self.end = end + + def IsDeclaration(self): + """Returns bool if this node is a declaration.""" + return False + + def IsDefinition(self): + """Returns bool if this node is a definition.""" + return False + + def IsExportable(self): + """Returns bool if this node exportable from a header file.""" + return False + + def Requires(self, node): + """Does this AST node require the definition of the node passed in?""" + return False + + def XXX__str__(self): + return self._StringHelper(self.__class__.__name__, '') + + def _StringHelper(self, name, suffix): + if not utils.DEBUG: + return '%s(%s)' % (name, suffix) + return '%s(%d, %d, %s)' % (name, self.start, self.end, suffix) + + def __repr__(self): + return str(self) + + +class Define(Node): + def __init__(self, start, end, name, definition): + Node.__init__(self, start, end) + self.name = name + self.definition = definition + + def __str__(self): + value = '%s %s' % (self.name, self.definition) + return self._StringHelper(self.__class__.__name__, value) + + +class Include(Node): + def __init__(self, start, end, filename, system): + Node.__init__(self, start, end) + self.filename = filename + self.system = system + + def __str__(self): + fmt = '"%s"' + if self.system: + fmt = '<%s>' + return self._StringHelper(self.__class__.__name__, fmt % self.filename) + + +class Goto(Node): + def __init__(self, start, end, label): + Node.__init__(self, start, end) + self.label = label + + def __str__(self): + return self._StringHelper(self.__class__.__name__, str(self.label)) + + +class Expr(Node): + def __init__(self, start, end, expr): + Node.__init__(self, start, end) + self.expr = expr + + def Requires(self, node): + # TODO(nnorwitz): impl. + return False + + def __str__(self): + return self._StringHelper(self.__class__.__name__, str(self.expr)) + + +class Return(Expr): + pass + + +class Delete(Expr): + pass + + +class Friend(Expr): + def __init__(self, start, end, expr, namespace): + Expr.__init__(self, start, end, expr) + self.namespace = namespace[:] + + +class Using(Node): + def __init__(self, start, end, names): + Node.__init__(self, start, end) + self.names = names + + def __str__(self): + return self._StringHelper(self.__class__.__name__, str(self.names)) + + +class Parameter(Node): + def __init__(self, start, end, name, parameter_type, default): + Node.__init__(self, start, end) + self.name = name + self.type = parameter_type + self.default = default + + def Requires(self, node): + # TODO(nnorwitz): handle namespaces, etc. + return self.type.name == node.name + + def __str__(self): + name = str(self.type) + suffix = '%s %s' % (name, self.name) + if self.default: + suffix += ' = ' + ''.join([d.name for d in self.default]) + return self._StringHelper(self.__class__.__name__, suffix) + + +class _GenericDeclaration(Node): + def __init__(self, start, end, name, namespace): + Node.__init__(self, start, end) + self.name = name + self.namespace = namespace[:] + + def FullName(self): + prefix = '' + if self.namespace and self.namespace[-1]: + prefix = '::'.join(self.namespace) + '::' + return prefix + self.name + + def _TypeStringHelper(self, suffix): + if self.namespace: + names = [n or '<anonymous>' for n in self.namespace] + suffix += ' in ' + '::'.join(names) + return self._StringHelper(self.__class__.__name__, suffix) + + +# TODO(nnorwitz): merge with Parameter in some way? +class VariableDeclaration(_GenericDeclaration): + def __init__(self, start, end, name, var_type, initial_value, namespace): + _GenericDeclaration.__init__(self, start, end, name, namespace) + self.type = var_type + self.initial_value = initial_value + + def Requires(self, node): + # TODO(nnorwitz): handle namespaces, etc. + return self.type.name == node.name + + def ToString(self): + """Return a string that tries to reconstitute the variable decl.""" + suffix = '%s %s' % (self.type, self.name) + if self.initial_value: + suffix += ' = ' + self.initial_value + return suffix + + def __str__(self): + return self._StringHelper(self.__class__.__name__, self.ToString()) + + +class Typedef(_GenericDeclaration): + def __init__(self, start, end, name, alias, namespace): + _GenericDeclaration.__init__(self, start, end, name, namespace) + self.alias = alias + + def IsDefinition(self): + return True + + def IsExportable(self): + return True + + def Requires(self, node): + # TODO(nnorwitz): handle namespaces, etc. + name = node.name + for token in self.alias: + if token is not None and name == token.name: + return True + return False + + def __str__(self): + suffix = '%s, %s' % (self.name, self.alias) + return self._TypeStringHelper(suffix) + + +class _NestedType(_GenericDeclaration): + def __init__(self, start, end, name, fields, namespace): + _GenericDeclaration.__init__(self, start, end, name, namespace) + self.fields = fields + + def IsDefinition(self): + return True + + def IsExportable(self): + return True + + def __str__(self): + suffix = '%s, {%s}' % (self.name, self.fields) + return self._TypeStringHelper(suffix) + + +class Union(_NestedType): + pass + + +class Enum(_NestedType): + pass + + +class Class(_GenericDeclaration): + def __init__(self, start, end, name, bases, templated_types, body, namespace): + _GenericDeclaration.__init__(self, start, end, name, namespace) + self.bases = bases + self.body = body + self.templated_types = templated_types + + def IsDeclaration(self): + return self.bases is None and self.body is None + + def IsDefinition(self): + return not self.IsDeclaration() + + def IsExportable(self): + return not self.IsDeclaration() + + def Requires(self, node): + # TODO(nnorwitz): handle namespaces, etc. + if self.bases: + for token_list in self.bases: + # TODO(nnorwitz): bases are tokens, do name comparision. + for token in token_list: + if token.name == node.name: + return True + # TODO(nnorwitz): search in body too. + return False + + def __str__(self): + name = self.name + if self.templated_types: + name += '<%s>' % self.templated_types + suffix = '%s, %s, %s' % (name, self.bases, self.body) + return self._TypeStringHelper(suffix) + + +class Struct(Class): + pass + + +class Function(_GenericDeclaration): + def __init__(self, start, end, name, return_type, parameters, + modifiers, templated_types, body, namespace): + _GenericDeclaration.__init__(self, start, end, name, namespace) + converter = TypeConverter(namespace) + self.return_type = converter.CreateReturnType(return_type) + self.parameters = converter.ToParameters(parameters) + self.modifiers = modifiers + self.body = body + self.templated_types = templated_types + + def IsDeclaration(self): + return self.body is None + + def IsDefinition(self): + return self.body is not None + + def IsExportable(self): + if self.return_type and 'static' in self.return_type.modifiers: + return False + return None not in self.namespace + + def Requires(self, node): + if self.parameters: + # TODO(nnorwitz): parameters are tokens, do name comparision. + for p in self.parameters: + if p.name == node.name: + return True + # TODO(nnorwitz): search in body too. + return False + + def __str__(self): + # TODO(nnorwitz): add templated_types. + suffix = ('%s %s(%s), 0x%02x, %s' % + (self.return_type, self.name, self.parameters, + self.modifiers, self.body)) + return self._TypeStringHelper(suffix) + + +class Method(Function): + def __init__(self, start, end, name, in_class, return_type, parameters, + modifiers, templated_types, body, namespace): + Function.__init__(self, start, end, name, return_type, parameters, + modifiers, templated_types, body, namespace) + # TODO(nnorwitz): in_class could also be a namespace which can + # mess up finding functions properly. + self.in_class = in_class + + +class Type(_GenericDeclaration): + """Type used for any variable (eg class, primitive, struct, etc).""" + + def __init__(self, start, end, name, templated_types, modifiers, + reference, pointer, array): + """ + Args: + name: str name of main type + templated_types: [Class (Type?)] template type info between <> + modifiers: [str] type modifiers (keywords) eg, const, mutable, etc. + reference, pointer, array: bools + """ + _GenericDeclaration.__init__(self, start, end, name, []) + self.templated_types = templated_types + if not name and modifiers: + self.name = modifiers.pop() + self.modifiers = modifiers + self.reference = reference + self.pointer = pointer + self.array = array + + def __str__(self): + prefix = '' + if self.modifiers: + prefix = ' '.join(self.modifiers) + ' ' + name = str(self.name) + if self.templated_types: + name += '<%s>' % self.templated_types + suffix = prefix + name + if self.reference: + suffix += '&' + if self.pointer: + suffix += '*' + if self.array: + suffix += '[]' + return self._TypeStringHelper(suffix) + + # By definition, Is* are always False. A Type can only exist in + # some sort of variable declaration, parameter, or return value. + def IsDeclaration(self): + return False + + def IsDefinition(self): + return False + + def IsExportable(self): + return False + + +class TypeConverter(object): + + def __init__(self, namespace_stack): + self.namespace_stack = namespace_stack + + def _GetTemplateEnd(self, tokens, start): + count = 1 + end = start + while 1: + token = tokens[end] + end += 1 + if token.name == '<': + count += 1 + elif token.name == '>': + count -= 1 + if count == 0: + break + return tokens[start:end-1], end + + def ToType(self, tokens): + """Convert [Token,...] to [Class(...), ] useful for base classes. + For example, code like class Foo : public Bar<x, y> { ... }; + the "Bar<x, y>" portion gets converted to an AST. + + Returns: + [Class(...), ...] + """ + result = [] + name_tokens = [] + reference = pointer = array = False + + def AddType(templated_types): + # Partition tokens into name and modifier tokens. + names = [] + modifiers = [] + for t in name_tokens: + if keywords.IsKeyword(t.name): + modifiers.append(t.name) + else: + names.append(t.name) + name = ''.join(names) + if name_tokens: + result.append(Type(name_tokens[0].start, name_tokens[-1].end, + name, templated_types, modifiers, + reference, pointer, array)) + del name_tokens[:] + + i = 0 + end = len(tokens) + while i < end: + token = tokens[i] + if token.name == '<': + new_tokens, new_end = self._GetTemplateEnd(tokens, i+1) + AddType(self.ToType(new_tokens)) + # If there is a comma after the template, we need to consume + # that here otherwise it becomes part of the name. + i = new_end + reference = pointer = array = False + elif token.name == ',': + AddType([]) + reference = pointer = array = False + elif token.name == '*': + pointer = True + elif token.name == '&': + reference = True + elif token.name == '[': + pointer = True + elif token.name == ']': + pass + else: + name_tokens.append(token) + i += 1 + + if name_tokens: + # No '<' in the tokens, just a simple name and no template. + AddType([]) + return result + + def DeclarationToParts(self, parts, needs_name_removed): + name = None + default = [] + if needs_name_removed: + # Handle default (initial) values properly. + for i, t in enumerate(parts): + if t.name == '=': + default = parts[i+1:] + name = parts[i-1].name + if name == ']' and parts[i-2].name == '[': + name = parts[i-3].name + i -= 1 + parts = parts[:i-1] + break + else: + if parts[-1].token_type == tokenize.NAME: + name = parts.pop().name + else: + # TODO(nnorwitz): this is a hack that happens for code like + # Register(Foo<T>); where it thinks this is a function call + # but it's actually a declaration. + name = '???' + modifiers = [] + type_name = [] + other_tokens = [] + templated_types = [] + i = 0 + end = len(parts) + while i < end: + p = parts[i] + if keywords.IsKeyword(p.name): + modifiers.append(p.name) + elif p.name == '<': + templated_tokens, new_end = self._GetTemplateEnd(parts, i+1) + templated_types = self.ToType(templated_tokens) + i = new_end - 1 + # Don't add a spurious :: to data members being initialized. + next_index = i + 1 + if next_index < end and parts[next_index].name == '::': + i += 1 + elif p.name in ('[', ']', '='): + # These are handled elsewhere. + other_tokens.append(p) + elif p.name not in ('*', '&', '>'): + # Ensure that names have a space between them. + if (type_name and type_name[-1].token_type == tokenize.NAME and + p.token_type == tokenize.NAME): + type_name.append(tokenize.Token(tokenize.SYNTAX, ' ', 0, 0)) + type_name.append(p) + else: + other_tokens.append(p) + i += 1 + type_name = ''.join([t.name for t in type_name]) + return name, type_name, templated_types, modifiers, default, other_tokens + + def ToParameters(self, tokens): + if not tokens: + return [] + + result = [] + name = type_name = '' + type_modifiers = [] + pointer = reference = array = False + first_token = None + default = [] + + def AddParameter(end): + if default: + del default[0] # Remove flag. + parts = self.DeclarationToParts(type_modifiers, True) + (name, type_name, templated_types, modifiers, + unused_default, unused_other_tokens) = parts + parameter_type = Type(first_token.start, first_token.end, + type_name, templated_types, modifiers, + reference, pointer, array) + p = Parameter(first_token.start, end, name, + parameter_type, default) + result.append(p) + + template_count = 0 + brace_count = 0 + for s in tokens: + if not first_token: + first_token = s + + # Check for braces before templates, as we can have unmatched '<>' + # inside default arguments. + if s.name == '{': + brace_count += 1 + elif s.name == '}': + brace_count -= 1 + if brace_count > 0: + type_modifiers.append(s) + continue + + if s.name == '<': + template_count += 1 + elif s.name == '>': + template_count -= 1 + if template_count > 0: + type_modifiers.append(s) + continue + + if s.name == ',': + AddParameter(s.start) + name = type_name = '' + type_modifiers = [] + pointer = reference = array = False + first_token = None + default = [] + elif s.name == '*': + pointer = True + elif s.name == '&': + reference = True + elif s.name == '[': + array = True + elif s.name == ']': + pass # Just don't add to type_modifiers. + elif s.name == '=': + # Got a default value. Add any value (None) as a flag. + default.append(None) + elif default: + default.append(s) + else: + type_modifiers.append(s) + AddParameter(tokens[-1].end) + return result + + def CreateReturnType(self, return_type_seq): + if not return_type_seq: + return None + start = return_type_seq[0].start + end = return_type_seq[-1].end + _, name, templated_types, modifiers, default, other_tokens = \ + self.DeclarationToParts(return_type_seq, False) + names = [n.name for n in other_tokens] + reference = '&' in names + pointer = '*' in names + array = '[' in names + return Type(start, end, name, templated_types, modifiers, + reference, pointer, array) + + def GetTemplateIndices(self, names): + # names is a list of strings. + start = names.index('<') + end = len(names) - 1 + while end > 0: + if names[end] == '>': + break + end -= 1 + return start, end+1 + +class AstBuilder(object): + def __init__(self, token_stream, filename, in_class='', visibility=None, + namespace_stack=[]): + self.tokens = token_stream + self.filename = filename + # TODO(nnorwitz): use a better data structure (deque) for the queue. + # Switching directions of the "queue" improved perf by about 25%. + # Using a deque should be even better since we access from both sides. + self.token_queue = [] + self.namespace_stack = namespace_stack[:] + self.in_class = in_class + if in_class is None: + self.in_class_name_only = None + else: + self.in_class_name_only = in_class.split('::')[-1] + self.visibility = visibility + self.in_function = False + self.current_token = None + # Keep the state whether we are currently handling a typedef or not. + self._handling_typedef = False + + self.converter = TypeConverter(self.namespace_stack) + + def HandleError(self, msg, token): + printable_queue = list(reversed(self.token_queue[-20:])) + sys.stderr.write('Got %s in %s @ %s %s\n' % + (msg, self.filename, token, printable_queue)) + + def Generate(self): + while 1: + token = self._GetNextToken() + if not token: + break + + # Get the next token. + self.current_token = token + + # Dispatch on the next token type. + if token.token_type == _INTERNAL_TOKEN: + if token.name == _NAMESPACE_POP: + self.namespace_stack.pop() + continue + + try: + result = self._GenerateOne(token) + if result is not None: + yield result + except: + self.HandleError('exception', token) + raise + + def _CreateVariable(self, pos_token, name, type_name, type_modifiers, + ref_pointer_name_seq, templated_types, value=None): + reference = '&' in ref_pointer_name_seq + pointer = '*' in ref_pointer_name_seq + array = '[' in ref_pointer_name_seq + var_type = Type(pos_token.start, pos_token.end, type_name, + templated_types, type_modifiers, + reference, pointer, array) + return VariableDeclaration(pos_token.start, pos_token.end, + name, var_type, value, self.namespace_stack) + + def _GenerateOne(self, token): + if token.token_type == tokenize.NAME: + if (keywords.IsKeyword(token.name) and + not keywords.IsBuiltinType(token.name)): + if token.name == 'enum': + # Pop the next token and only put it back if it's not + # 'class'. This allows us to support the two-token + # 'enum class' keyword as if it were simply 'enum'. + next = self._GetNextToken() + if next.name != 'class': + self._AddBackToken(next) + + method = getattr(self, 'handle_' + token.name) + return method() + elif token.name == self.in_class_name_only: + # The token name is the same as the class, must be a ctor if + # there is a paren. Otherwise, it's the return type. + # Peek ahead to get the next token to figure out which. + next = self._GetNextToken() + self._AddBackToken(next) + if next.token_type == tokenize.SYNTAX and next.name == '(': + return self._GetMethod([token], FUNCTION_CTOR, None, True) + # Fall through--handle like any other method. + + # Handle data or function declaration/definition. + syntax = tokenize.SYNTAX + temp_tokens, last_token = \ + self._GetVarTokensUpToIgnoringTemplates(syntax, + '(', ';', '{', '[') + temp_tokens.insert(0, token) + if last_token.name == '(': + # If there is an assignment before the paren, + # this is an expression, not a method. + expr = bool([e for e in temp_tokens if e.name == '=']) + if expr: + new_temp = self._GetTokensUpTo(tokenize.SYNTAX, ';') + temp_tokens.append(last_token) + temp_tokens.extend(new_temp) + last_token = tokenize.Token(tokenize.SYNTAX, ';', 0, 0) + + if last_token.name == '[': + # Handle array, this isn't a method, unless it's an operator. + # TODO(nnorwitz): keep the size somewhere. + # unused_size = self._GetTokensUpTo(tokenize.SYNTAX, ']') + temp_tokens.append(last_token) + if temp_tokens[-2].name == 'operator': + temp_tokens.append(self._GetNextToken()) + else: + temp_tokens2, last_token = \ + self._GetVarTokensUpTo(tokenize.SYNTAX, ';') + temp_tokens.extend(temp_tokens2) + + if last_token.name == ';': + # Handle data, this isn't a method. + parts = self.converter.DeclarationToParts(temp_tokens, True) + (name, type_name, templated_types, modifiers, default, + unused_other_tokens) = parts + + t0 = temp_tokens[0] + names = [t.name for t in temp_tokens] + if templated_types: + start, end = self.converter.GetTemplateIndices(names) + names = names[:start] + names[end:] + default = ''.join([t.name for t in default]) + return self._CreateVariable(t0, name, type_name, modifiers, + names, templated_types, default) + if last_token.name == '{': + self._AddBackTokens(temp_tokens[1:]) + self._AddBackToken(last_token) + method_name = temp_tokens[0].name + method = getattr(self, 'handle_' + method_name, None) + if not method: + # Must be declaring a variable. + # TODO(nnorwitz): handle the declaration. + return None + return method() + return self._GetMethod(temp_tokens, 0, None, False) + elif token.token_type == tokenize.SYNTAX: + if token.name == '~' and self.in_class: + # Must be a dtor (probably not in method body). + token = self._GetNextToken() + # self.in_class can contain A::Name, but the dtor will only + # be Name. Make sure to compare against the right value. + if (token.token_type == tokenize.NAME and + token.name == self.in_class_name_only): + return self._GetMethod([token], FUNCTION_DTOR, None, True) + # TODO(nnorwitz): handle a lot more syntax. + elif token.token_type == tokenize.PREPROCESSOR: + # TODO(nnorwitz): handle more preprocessor directives. + # token starts with a #, so remove it and strip whitespace. + name = token.name[1:].lstrip() + if name.startswith('include'): + # Remove "include". + name = name[7:].strip() + assert name + # Handle #include \<newline> "header-on-second-line.h". + if name.startswith('\\'): + name = name[1:].strip() + assert name[0] in '<"', token + assert name[-1] in '>"', token + system = name[0] == '<' + filename = name[1:-1] + return Include(token.start, token.end, filename, system) + if name.startswith('define'): + # Remove "define". + name = name[6:].strip() + assert name + value = '' + for i, c in enumerate(name): + if c.isspace(): + value = name[i:].lstrip() + name = name[:i] + break + return Define(token.start, token.end, name, value) + if name.startswith('if') and name[2:3].isspace(): + condition = name[3:].strip() + if condition.startswith('0') or condition.startswith('(0)'): + self._SkipIf0Blocks() + return None + + def _GetTokensUpTo(self, expected_token_type, expected_token): + return self._GetVarTokensUpTo(expected_token_type, expected_token)[0] + + def _GetVarTokensUpTo(self, expected_token_type, *expected_tokens): + last_token = self._GetNextToken() + tokens = [] + while (last_token.token_type != expected_token_type or + last_token.name not in expected_tokens): + tokens.append(last_token) + last_token = self._GetNextToken() + return tokens, last_token + + # Same as _GetVarTokensUpTo, but skips over '<...>' which could contain an + # expected token. + def _GetVarTokensUpToIgnoringTemplates(self, expected_token_type, + *expected_tokens): + last_token = self._GetNextToken() + tokens = [] + nesting = 0 + while (nesting > 0 or + last_token.token_type != expected_token_type or + last_token.name not in expected_tokens): + tokens.append(last_token) + last_token = self._GetNextToken() + if last_token.name == '<': + nesting += 1 + elif last_token.name == '>': + nesting -= 1 + return tokens, last_token + + # TODO(nnorwitz): remove _IgnoreUpTo() it shouldn't be necesary. + def _IgnoreUpTo(self, token_type, token): + unused_tokens = self._GetTokensUpTo(token_type, token) + + def _SkipIf0Blocks(self): + count = 1 + while 1: + token = self._GetNextToken() + if token.token_type != tokenize.PREPROCESSOR: + continue + + name = token.name[1:].lstrip() + if name.startswith('endif'): + count -= 1 + if count == 0: + break + elif name.startswith('if'): + count += 1 + + def _GetMatchingChar(self, open_paren, close_paren, GetNextToken=None): + if GetNextToken is None: + GetNextToken = self._GetNextToken + # Assumes the current token is open_paren and we will consume + # and return up to the close_paren. + count = 1 + token = GetNextToken() + while 1: + if token.token_type == tokenize.SYNTAX: + if token.name == open_paren: + count += 1 + elif token.name == close_paren: + count -= 1 + if count == 0: + break + yield token + token = GetNextToken() + yield token + + def _GetParameters(self): + return self._GetMatchingChar('(', ')') + + def GetScope(self): + return self._GetMatchingChar('{', '}') + + def _GetNextToken(self): + if self.token_queue: + return self.token_queue.pop() + try: + return next(self.tokens) + except StopIteration: + return + + def _AddBackToken(self, token): + if token.whence == tokenize.WHENCE_STREAM: + token.whence = tokenize.WHENCE_QUEUE + self.token_queue.insert(0, token) + else: + assert token.whence == tokenize.WHENCE_QUEUE, token + self.token_queue.append(token) + + def _AddBackTokens(self, tokens): + if tokens: + if tokens[-1].whence == tokenize.WHENCE_STREAM: + for token in tokens: + token.whence = tokenize.WHENCE_QUEUE + self.token_queue[:0] = reversed(tokens) + else: + assert tokens[-1].whence == tokenize.WHENCE_QUEUE, tokens + self.token_queue.extend(reversed(tokens)) + + def GetName(self, seq=None): + """Returns ([tokens], next_token_info).""" + GetNextToken = self._GetNextToken + if seq is not None: + it = iter(seq) + GetNextToken = lambda: next(it) + next_token = GetNextToken() + tokens = [] + last_token_was_name = False + while (next_token.token_type == tokenize.NAME or + (next_token.token_type == tokenize.SYNTAX and + next_token.name in ('::', '<'))): + # Two NAMEs in a row means the identifier should terminate. + # It's probably some sort of variable declaration. + if last_token_was_name and next_token.token_type == tokenize.NAME: + break + last_token_was_name = next_token.token_type == tokenize.NAME + tokens.append(next_token) + # Handle templated names. + if next_token.name == '<': + tokens.extend(self._GetMatchingChar('<', '>', GetNextToken)) + last_token_was_name = True + next_token = GetNextToken() + return tokens, next_token + + def GetMethod(self, modifiers, templated_types): + return_type_and_name = self._GetTokensUpTo(tokenize.SYNTAX, '(') + assert len(return_type_and_name) >= 1 + return self._GetMethod(return_type_and_name, modifiers, templated_types, + False) + + def _GetMethod(self, return_type_and_name, modifiers, templated_types, + get_paren): + template_portion = None + if get_paren: + token = self._GetNextToken() + assert token.token_type == tokenize.SYNTAX, token + if token.name == '<': + # Handle templatized dtors. + template_portion = [token] + template_portion.extend(self._GetMatchingChar('<', '>')) + token = self._GetNextToken() + assert token.token_type == tokenize.SYNTAX, token + assert token.name == '(', token + + name = return_type_and_name.pop() + # Handle templatized ctors. + if name.name == '>': + index = 1 + while return_type_and_name[index].name != '<': + index += 1 + template_portion = return_type_and_name[index:] + [name] + del return_type_and_name[index:] + name = return_type_and_name.pop() + elif name.name == ']': + rt = return_type_and_name + assert rt[-1].name == '[', return_type_and_name + assert rt[-2].name == 'operator', return_type_and_name + name_seq = return_type_and_name[-2:] + del return_type_and_name[-2:] + name = tokenize.Token(tokenize.NAME, 'operator[]', + name_seq[0].start, name.end) + # Get the open paren so _GetParameters() below works. + unused_open_paren = self._GetNextToken() + + # TODO(nnorwitz): store template_portion. + return_type = return_type_and_name + indices = name + if return_type: + indices = return_type[0] + + # Force ctor for templatized ctors. + if name.name == self.in_class and not modifiers: + modifiers |= FUNCTION_CTOR + parameters = list(self._GetParameters()) + del parameters[-1] # Remove trailing ')'. + + # Handling operator() is especially weird. + if name.name == 'operator' and not parameters: + token = self._GetNextToken() + assert token.name == '(', token + parameters = list(self._GetParameters()) + del parameters[-1] # Remove trailing ')'. + + token = self._GetNextToken() + while token.token_type == tokenize.NAME: + modifier_token = token + token = self._GetNextToken() + if modifier_token.name == 'const': + modifiers |= FUNCTION_CONST + elif modifier_token.name == '__attribute__': + # TODO(nnorwitz): handle more __attribute__ details. + modifiers |= FUNCTION_ATTRIBUTE + assert token.name == '(', token + # Consume everything between the (parens). + unused_tokens = list(self._GetMatchingChar('(', ')')) + token = self._GetNextToken() + elif modifier_token.name == 'throw': + modifiers |= FUNCTION_THROW + assert token.name == '(', token + # Consume everything between the (parens). + unused_tokens = list(self._GetMatchingChar('(', ')')) + token = self._GetNextToken() + elif modifier_token.name == 'override': + modifiers |= FUNCTION_OVERRIDE + elif modifier_token.name == modifier_token.name.upper(): + # HACK(nnorwitz): assume that all upper-case names + # are some macro we aren't expanding. + modifiers |= FUNCTION_UNKNOWN_ANNOTATION + else: + self.HandleError('unexpected token', modifier_token) + + assert token.token_type == tokenize.SYNTAX, token + # Handle ctor initializers. + if token.name == ':': + # TODO(nnorwitz): anything else to handle for initializer list? + while token.name != ';' and token.name != '{': + token = self._GetNextToken() + + # Handle pointer to functions that are really data but look + # like method declarations. + if token.name == '(': + if parameters[0].name == '*': + # name contains the return type. + name = parameters.pop() + # parameters contains the name of the data. + modifiers = [p.name for p in parameters] + # Already at the ( to open the parameter list. + function_parameters = list(self._GetMatchingChar('(', ')')) + del function_parameters[-1] # Remove trailing ')'. + # TODO(nnorwitz): store the function_parameters. + token = self._GetNextToken() + assert token.token_type == tokenize.SYNTAX, token + assert token.name == ';', token + return self._CreateVariable(indices, name.name, indices.name, + modifiers, '', None) + # At this point, we got something like: + # return_type (type::*name_)(params); + # This is a data member called name_ that is a function pointer. + # With this code: void (sq_type::*field_)(string&); + # We get: name=void return_type=[] parameters=sq_type ... field_ + # TODO(nnorwitz): is return_type always empty? + # TODO(nnorwitz): this isn't even close to being correct. + # Just put in something so we don't crash and can move on. + real_name = parameters[-1] + modifiers = [p.name for p in self._GetParameters()] + del modifiers[-1] # Remove trailing ')'. + return self._CreateVariable(indices, real_name.name, indices.name, + modifiers, '', None) + + if token.name == '{': + body = list(self.GetScope()) + del body[-1] # Remove trailing '}'. + else: + body = None + if token.name == '=': + token = self._GetNextToken() + + if token.name == 'default' or token.name == 'delete': + # Ignore explicitly defaulted and deleted special members + # in C++11. + token = self._GetNextToken() + else: + # Handle pure-virtual declarations. + assert token.token_type == tokenize.CONSTANT, token + assert token.name == '0', token + modifiers |= FUNCTION_PURE_VIRTUAL + token = self._GetNextToken() + + if token.name == '[': + # TODO(nnorwitz): store tokens and improve parsing. + # template <typename T, size_t N> char (&ASH(T (&seq)[N]))[N]; + tokens = list(self._GetMatchingChar('[', ']')) + token = self._GetNextToken() + + assert token.name == ';', (token, return_type_and_name, parameters) + + # Looks like we got a method, not a function. + if len(return_type) > 2 and return_type[-1].name == '::': + return_type, in_class = \ + self._GetReturnTypeAndClassName(return_type) + return Method(indices.start, indices.end, name.name, in_class, + return_type, parameters, modifiers, templated_types, + body, self.namespace_stack) + return Function(indices.start, indices.end, name.name, return_type, + parameters, modifiers, templated_types, body, + self.namespace_stack) + + def _GetReturnTypeAndClassName(self, token_seq): + # Splitting the return type from the class name in a method + # can be tricky. For example, Return::Type::Is::Hard::To::Find(). + # Where is the return type and where is the class name? + # The heuristic used is to pull the last name as the class name. + # This includes all the templated type info. + # TODO(nnorwitz): if there is only One name like in the + # example above, punt and assume the last bit is the class name. + + # Ignore a :: prefix, if exists so we can find the first real name. + i = 0 + if token_seq[0].name == '::': + i = 1 + # Ignore a :: suffix, if exists. + end = len(token_seq) - 1 + if token_seq[end-1].name == '::': + end -= 1 + + # Make a copy of the sequence so we can append a sentinel + # value. This is required for GetName will has to have some + # terminating condition beyond the last name. + seq_copy = token_seq[i:end] + seq_copy.append(tokenize.Token(tokenize.SYNTAX, '', 0, 0)) + names = [] + while i < end: + # Iterate through the sequence parsing out each name. + new_name, next = self.GetName(seq_copy[i:]) + assert new_name, 'Got empty new_name, next=%s' % next + # We got a pointer or ref. Add it to the name. + if next and next.token_type == tokenize.SYNTAX: + new_name.append(next) + names.append(new_name) + i += len(new_name) + + # Now that we have the names, it's time to undo what we did. + + # Remove the sentinel value. + names[-1].pop() + # Flatten the token sequence for the return type. + return_type = [e for seq in names[:-1] for e in seq] + # The class name is the last name. + class_name = names[-1] + return return_type, class_name + + def handle_bool(self): + pass + + def handle_char(self): + pass + + def handle_int(self): + pass + + def handle_long(self): + pass + + def handle_short(self): + pass + + def handle_double(self): + pass + + def handle_float(self): + pass + + def handle_void(self): + pass + + def handle_wchar_t(self): + pass + + def handle_unsigned(self): + pass + + def handle_signed(self): + pass + + def _GetNestedType(self, ctor): + name = None + name_tokens, token = self.GetName() + if name_tokens: + name = ''.join([t.name for t in name_tokens]) + + # Handle forward declarations. + if token.token_type == tokenize.SYNTAX and token.name == ';': + return ctor(token.start, token.end, name, None, + self.namespace_stack) + + if token.token_type == tokenize.NAME and self._handling_typedef: + self._AddBackToken(token) + return ctor(token.start, token.end, name, None, + self.namespace_stack) + + # Must be the type declaration. + fields = list(self._GetMatchingChar('{', '}')) + del fields[-1] # Remove trailing '}'. + if token.token_type == tokenize.SYNTAX and token.name == '{': + next = self._GetNextToken() + new_type = ctor(token.start, token.end, name, fields, + self.namespace_stack) + # A name means this is an anonymous type and the name + # is the variable declaration. + if next.token_type != tokenize.NAME: + return new_type + name = new_type + token = next + + # Must be variable declaration using the type prefixed with keyword. + assert token.token_type == tokenize.NAME, token + return self._CreateVariable(token, token.name, name, [], '', None) + + def handle_struct(self): + # Special case the handling typedef/aliasing of structs here. + # It would be a pain to handle in the class code. + name_tokens, var_token = self.GetName() + if name_tokens: + next_token = self._GetNextToken() + is_syntax = (var_token.token_type == tokenize.SYNTAX and + var_token.name[0] in '*&') + is_variable = (var_token.token_type == tokenize.NAME and + next_token.name == ';') + variable = var_token + if is_syntax and not is_variable: + variable = next_token + temp = self._GetNextToken() + if temp.token_type == tokenize.SYNTAX and temp.name == '(': + # Handle methods declared to return a struct. + t0 = name_tokens[0] + struct = tokenize.Token(tokenize.NAME, 'struct', + t0.start-7, t0.start-2) + type_and_name = [struct] + type_and_name.extend(name_tokens) + type_and_name.extend((var_token, next_token)) + return self._GetMethod(type_and_name, 0, None, False) + assert temp.name == ';', (temp, name_tokens, var_token) + if is_syntax or (is_variable and not self._handling_typedef): + modifiers = ['struct'] + type_name = ''.join([t.name for t in name_tokens]) + position = name_tokens[0] + return self._CreateVariable(position, variable.name, type_name, + modifiers, var_token.name, None) + name_tokens.extend((var_token, next_token)) + self._AddBackTokens(name_tokens) + else: + self._AddBackToken(var_token) + return self._GetClass(Struct, VISIBILITY_PUBLIC, None) + + def handle_union(self): + return self._GetNestedType(Union) + + def handle_enum(self): + return self._GetNestedType(Enum) + + def handle_auto(self): + # TODO(nnorwitz): warn about using auto? Probably not since it + # will be reclaimed and useful for C++0x. + pass + + def handle_register(self): + pass + + def handle_const(self): + pass + + def handle_inline(self): + pass + + def handle_extern(self): + pass + + def handle_static(self): + pass + + def handle_virtual(self): + # What follows must be a method. + token = token2 = self._GetNextToken() + if token.name == 'inline': + # HACK(nnorwitz): handle inline dtors by ignoring 'inline'. + token2 = self._GetNextToken() + if token2.token_type == tokenize.SYNTAX and token2.name == '~': + return self.GetMethod(FUNCTION_VIRTUAL + FUNCTION_DTOR, None) + assert token.token_type == tokenize.NAME or token.name == '::', token + return_type_and_name, _ = self._GetVarTokensUpToIgnoringTemplates( + tokenize.SYNTAX, '(') # ) + return_type_and_name.insert(0, token) + if token2 is not token: + return_type_and_name.insert(1, token2) + return self._GetMethod(return_type_and_name, FUNCTION_VIRTUAL, + None, False) + + def handle_volatile(self): + pass + + def handle_mutable(self): + pass + + def handle_public(self): + assert self.in_class + self.visibility = VISIBILITY_PUBLIC + + def handle_protected(self): + assert self.in_class + self.visibility = VISIBILITY_PROTECTED + + def handle_private(self): + assert self.in_class + self.visibility = VISIBILITY_PRIVATE + + def handle_friend(self): + tokens = self._GetTokensUpTo(tokenize.SYNTAX, ';') + assert tokens + t0 = tokens[0] + return Friend(t0.start, t0.end, tokens, self.namespace_stack) + + def handle_static_cast(self): + pass + + def handle_const_cast(self): + pass + + def handle_dynamic_cast(self): + pass + + def handle_reinterpret_cast(self): + pass + + def handle_new(self): + pass + + def handle_delete(self): + tokens = self._GetTokensUpTo(tokenize.SYNTAX, ';') + assert tokens + return Delete(tokens[0].start, tokens[0].end, tokens) + + def handle_typedef(self): + token = self._GetNextToken() + if (token.token_type == tokenize.NAME and + keywords.IsKeyword(token.name)): + # Token must be struct/enum/union/class. + method = getattr(self, 'handle_' + token.name) + self._handling_typedef = True + tokens = [method()] + self._handling_typedef = False + else: + tokens = [token] + + # Get the remainder of the typedef up to the semi-colon. + tokens.extend(self._GetTokensUpTo(tokenize.SYNTAX, ';')) + + # TODO(nnorwitz): clean all this up. + assert tokens + name = tokens.pop() + indices = name + if tokens: + indices = tokens[0] + if not indices: + indices = token + if name.name == ')': + # HACK(nnorwitz): Handle pointers to functions "properly". + if (len(tokens) >= 4 and + tokens[1].name == '(' and tokens[2].name == '*'): + tokens.append(name) + name = tokens[3] + elif name.name == ']': + # HACK(nnorwitz): Handle arrays properly. + if len(tokens) >= 2: + tokens.append(name) + name = tokens[1] + new_type = tokens + if tokens and isinstance(tokens[0], tokenize.Token): + new_type = self.converter.ToType(tokens)[0] + return Typedef(indices.start, indices.end, name.name, + new_type, self.namespace_stack) + + def handle_typeid(self): + pass # Not needed yet. + + def handle_typename(self): + pass # Not needed yet. + + def _GetTemplatedTypes(self): + result = {} + tokens = list(self._GetMatchingChar('<', '>')) + len_tokens = len(tokens) - 1 # Ignore trailing '>'. + i = 0 + while i < len_tokens: + key = tokens[i].name + i += 1 + if keywords.IsKeyword(key) or key == ',': + continue + type_name = default = None + if i < len_tokens: + i += 1 + if tokens[i-1].name == '=': + assert i < len_tokens, '%s %s' % (i, tokens) + default, unused_next_token = self.GetName(tokens[i:]) + i += len(default) + else: + if tokens[i-1].name != ',': + # We got something like: Type variable. + # Re-adjust the key (variable) and type_name (Type). + key = tokens[i-1].name + type_name = tokens[i-2] + + result[key] = (type_name, default) + return result + + def handle_template(self): + token = self._GetNextToken() + assert token.token_type == tokenize.SYNTAX, token + assert token.name == '<', token + templated_types = self._GetTemplatedTypes() + # TODO(nnorwitz): for now, just ignore the template params. + token = self._GetNextToken() + if token.token_type == tokenize.NAME: + if token.name == 'class': + return self._GetClass(Class, VISIBILITY_PRIVATE, templated_types) + elif token.name == 'struct': + return self._GetClass(Struct, VISIBILITY_PUBLIC, templated_types) + elif token.name == 'friend': + return self.handle_friend() + self._AddBackToken(token) + tokens, last = self._GetVarTokensUpTo(tokenize.SYNTAX, '(', ';') + tokens.append(last) + self._AddBackTokens(tokens) + if last.name == '(': + return self.GetMethod(FUNCTION_NONE, templated_types) + # Must be a variable definition. + return None + + def handle_true(self): + pass # Nothing to do. + + def handle_false(self): + pass # Nothing to do. + + def handle_asm(self): + pass # Not needed yet. + + def handle_class(self): + return self._GetClass(Class, VISIBILITY_PRIVATE, None) + + def _GetBases(self): + # Get base classes. + bases = [] + while 1: + token = self._GetNextToken() + assert token.token_type == tokenize.NAME, token + # TODO(nnorwitz): store kind of inheritance...maybe. + if token.name not in ('public', 'protected', 'private'): + # If inheritance type is not specified, it is private. + # Just put the token back so we can form a name. + # TODO(nnorwitz): it would be good to warn about this. + self._AddBackToken(token) + else: + # Check for virtual inheritance. + token = self._GetNextToken() + if token.name != 'virtual': + self._AddBackToken(token) + else: + # TODO(nnorwitz): store that we got virtual for this base. + pass + base, next_token = self.GetName() + bases_ast = self.converter.ToType(base) + assert len(bases_ast) == 1, bases_ast + bases.append(bases_ast[0]) + assert next_token.token_type == tokenize.SYNTAX, next_token + if next_token.name == '{': + token = next_token + break + # Support multiple inheritance. + assert next_token.name == ',', next_token + return bases, token + + def _GetClass(self, class_type, visibility, templated_types): + class_name = None + class_token = self._GetNextToken() + if class_token.token_type != tokenize.NAME: + assert class_token.token_type == tokenize.SYNTAX, class_token + token = class_token + else: + # Skip any macro (e.g. storage class specifiers) after the + # 'class' keyword. + next_token = self._GetNextToken() + if next_token.token_type == tokenize.NAME: + self._AddBackToken(next_token) + else: + self._AddBackTokens([class_token, next_token]) + name_tokens, token = self.GetName() + class_name = ''.join([t.name for t in name_tokens]) + bases = None + if token.token_type == tokenize.SYNTAX: + if token.name == ';': + # Forward declaration. + return class_type(class_token.start, class_token.end, + class_name, None, templated_types, None, + self.namespace_stack) + if token.name in '*&': + # Inline forward declaration. Could be method or data. + name_token = self._GetNextToken() + next_token = self._GetNextToken() + if next_token.name == ';': + # Handle data + modifiers = ['class'] + return self._CreateVariable(class_token, name_token.name, + class_name, + modifiers, token.name, None) + else: + # Assume this is a method. + tokens = (class_token, token, name_token, next_token) + self._AddBackTokens(tokens) + return self.GetMethod(FUNCTION_NONE, None) + if token.name == ':': + bases, token = self._GetBases() + + body = None + if token.token_type == tokenize.SYNTAX and token.name == '{': + assert token.token_type == tokenize.SYNTAX, token + assert token.name == '{', token + + ast = AstBuilder(self.GetScope(), self.filename, class_name, + visibility, self.namespace_stack) + body = list(ast.Generate()) + + if not self._handling_typedef: + token = self._GetNextToken() + if token.token_type != tokenize.NAME: + assert token.token_type == tokenize.SYNTAX, token + assert token.name == ';', token + else: + new_class = class_type(class_token.start, class_token.end, + class_name, bases, None, + body, self.namespace_stack) + + modifiers = [] + return self._CreateVariable(class_token, + token.name, new_class, + modifiers, token.name, None) + else: + if not self._handling_typedef: + self.HandleError('non-typedef token', token) + self._AddBackToken(token) + + return class_type(class_token.start, class_token.end, class_name, + bases, templated_types, body, self.namespace_stack) + + def handle_namespace(self): + # Support anonymous namespaces. + name = None + name_tokens, token = self.GetName() + if name_tokens: + name = ''.join([t.name for t in name_tokens]) + self.namespace_stack.append(name) + assert token.token_type == tokenize.SYNTAX, token + # Create an internal token that denotes when the namespace is complete. + internal_token = tokenize.Token(_INTERNAL_TOKEN, _NAMESPACE_POP, + None, None) + internal_token.whence = token.whence + if token.name == '=': + # TODO(nnorwitz): handle aliasing namespaces. + name, next_token = self.GetName() + assert next_token.name == ';', next_token + self._AddBackToken(internal_token) + else: + assert token.name == '{', token + tokens = list(self.GetScope()) + # Replace the trailing } with the internal namespace pop token. + tokens[-1] = internal_token + # Handle namespace with nothing in it. + self._AddBackTokens(tokens) + return None + + def handle_using(self): + tokens = self._GetTokensUpTo(tokenize.SYNTAX, ';') + assert tokens + return Using(tokens[0].start, tokens[0].end, tokens) + + def handle_explicit(self): + assert self.in_class + # Nothing much to do. + # TODO(nnorwitz): maybe verify the method name == class name. + # This must be a ctor. + return self.GetMethod(FUNCTION_CTOR, None) + + def handle_this(self): + pass # Nothing to do. + + def handle_operator(self): + # Pull off the next token(s?) and make that part of the method name. + pass + + def handle_sizeof(self): + pass + + def handle_case(self): + pass + + def handle_switch(self): + pass + + def handle_default(self): + token = self._GetNextToken() + assert token.token_type == tokenize.SYNTAX + assert token.name == ':' + + def handle_if(self): + pass + + def handle_else(self): + pass + + def handle_return(self): + tokens = self._GetTokensUpTo(tokenize.SYNTAX, ';') + if not tokens: + return Return(self.current_token.start, self.current_token.end, None) + return Return(tokens[0].start, tokens[0].end, tokens) + + def handle_goto(self): + tokens = self._GetTokensUpTo(tokenize.SYNTAX, ';') + assert len(tokens) == 1, str(tokens) + return Goto(tokens[0].start, tokens[0].end, tokens[0].name) + + def handle_try(self): + pass # Not needed yet. + + def handle_catch(self): + pass # Not needed yet. + + def handle_throw(self): + pass # Not needed yet. + + def handle_while(self): + pass + + def handle_do(self): + pass + + def handle_for(self): + pass + + def handle_break(self): + self._IgnoreUpTo(tokenize.SYNTAX, ';') + + def handle_continue(self): + self._IgnoreUpTo(tokenize.SYNTAX, ';') + + +def BuilderFromSource(source, filename): + """Utility method that returns an AstBuilder from source code. + + Args: + source: 'C++ source code' + filename: 'file1' + + Returns: + AstBuilder + """ + return AstBuilder(tokenize.GetTokens(source), filename) + + +def PrintIndentifiers(filename, should_print): + """Prints all identifiers for a C++ source file. + + Args: + filename: 'file1' + should_print: predicate with signature: bool Function(token) + """ + source = utils.ReadFile(filename, False) + if source is None: + sys.stderr.write('Unable to find: %s\n' % filename) + return + + #print('Processing %s' % actual_filename) + builder = BuilderFromSource(source, filename) + try: + for node in builder.Generate(): + if should_print(node): + print(node.name) + except KeyboardInterrupt: + return + except: + pass + + +def PrintAllIndentifiers(filenames, should_print): + """Prints all identifiers for each C++ source file in filenames. + + Args: + filenames: ['file1', 'file2', ...] + should_print: predicate with signature: bool Function(token) + """ + for path in filenames: + PrintIndentifiers(path, should_print) + + +def main(argv): + for filename in argv[1:]: + source = utils.ReadFile(filename) + if source is None: + continue + + print('Processing %s' % filename) + builder = BuilderFromSource(source, filename) + try: + entire_ast = filter(None, builder.Generate()) + except KeyboardInterrupt: + return + except: + # Already printed a warning, print the traceback and continue. + traceback.print_exc() + else: + if utils.DEBUG: + for ast in entire_ast: + print(ast) + + +if __name__ == '__main__': + main(sys.argv) diff --git a/src/googletest/googlemock/scripts/generator/cpp/gmock_class.py b/src/googletest/googlemock/scripts/generator/cpp/gmock_class.py new file mode 100755 index 000000000..488cc1537 --- /dev/null +++ b/src/googletest/googlemock/scripts/generator/cpp/gmock_class.py @@ -0,0 +1,245 @@ +#!/usr/bin/env python +# +# Copyright 2008 Google Inc. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +"""Generate Google Mock classes from base classes. + +This program will read in a C++ source file and output the Google Mock +classes for the specified classes. If no class is specified, all +classes in the source file are emitted. + +Usage: + gmock_class.py header-file.h [ClassName]... + +Output is sent to stdout. +""" + +import os +import re +import sys + +from cpp import ast +from cpp import utils + +# Preserve compatibility with Python 2.3. +try: + _dummy = set +except NameError: + import sets + + set = sets.Set + +_VERSION = (1, 0, 1) # The version of this script. +# How many spaces to indent. Can set me with the INDENT environment variable. +_INDENT = 2 + + +def _RenderType(ast_type): + """Renders the potentially recursively templated type into a string. + + Args: + ast_type: The AST of the type. + + Returns: + Rendered string of the type. + """ + # Add modifiers like 'const'. + modifiers = '' + if ast_type.modifiers: + modifiers = ' '.join(ast_type.modifiers) + ' ' + return_type = modifiers + ast_type.name + if ast_type.templated_types: + # Collect template args. + template_args = [] + for arg in ast_type.templated_types: + rendered_arg = _RenderType(arg) + template_args.append(rendered_arg) + return_type += '<' + ', '.join(template_args) + '>' + if ast_type.pointer: + return_type += '*' + if ast_type.reference: + return_type += '&' + return return_type + + +def _GenerateArg(source): + """Strips out comments, default arguments, and redundant spaces from a single argument. + + Args: + source: A string for a single argument. + + Returns: + Rendered string of the argument. + """ + # Remove end of line comments before eliminating newlines. + arg = re.sub(r'//.*', '', source) + + # Remove c-style comments. + arg = re.sub(r'/\*.*\*/', '', arg) + + # Remove default arguments. + arg = re.sub(r'=.*', '', arg) + + # Collapse spaces and newlines into a single space. + arg = re.sub(r'\s+', ' ', arg) + return arg.strip() + + +def _EscapeForMacro(s): + """Escapes a string for use as an argument to a C++ macro.""" + paren_count = 0 + for c in s: + if c == '(': + paren_count += 1 + elif c == ')': + paren_count -= 1 + elif c == ',' and paren_count == 0: + return '(' + s + ')' + return s + + +def _GenerateMethods(output_lines, source, class_node): + function_type = ( + ast.FUNCTION_VIRTUAL | ast.FUNCTION_PURE_VIRTUAL | ast.FUNCTION_OVERRIDE) + ctor_or_dtor = ast.FUNCTION_CTOR | ast.FUNCTION_DTOR + indent = ' ' * _INDENT + + for node in class_node.body: + # We only care about virtual functions. + if (isinstance(node, ast.Function) and node.modifiers & function_type and + not node.modifiers & ctor_or_dtor): + # Pick out all the elements we need from the original function. + modifiers = 'override' + if node.modifiers & ast.FUNCTION_CONST: + modifiers = 'const, ' + modifiers + + return_type = 'void' + if node.return_type: + return_type = _EscapeForMacro(_RenderType(node.return_type)) + + args = [] + for p in node.parameters: + arg = _GenerateArg(source[p.start:p.end]) + args.append(_EscapeForMacro(arg)) + + # Create the mock method definition. + output_lines.extend([ + '%sMOCK_METHOD(%s, %s, (%s), (%s));' % + (indent, return_type, node.name, ', '.join(args), modifiers) + ]) + + +def _GenerateMocks(filename, source, ast_list, desired_class_names): + processed_class_names = set() + lines = [] + for node in ast_list: + if (isinstance(node, ast.Class) and node.body and + # desired_class_names being None means that all classes are selected. + (not desired_class_names or node.name in desired_class_names)): + class_name = node.name + parent_name = class_name + processed_class_names.add(class_name) + class_node = node + # Add namespace before the class. + if class_node.namespace: + lines.extend(['namespace %s {' % n for n in class_node.namespace]) # } + lines.append('') + + # Add template args for templated classes. + if class_node.templated_types: + # TODO(paulchang): The AST doesn't preserve template argument order, + # so we have to make up names here. + # TODO(paulchang): Handle non-type template arguments (e.g. + # template<typename T, int N>). + template_arg_count = len(class_node.templated_types.keys()) + template_args = ['T%d' % n for n in range(template_arg_count)] + template_decls = ['typename ' + arg for arg in template_args] + lines.append('template <' + ', '.join(template_decls) + '>') + parent_name += '<' + ', '.join(template_args) + '>' + + # Add the class prolog. + lines.append('class Mock%s : public %s {' # } + % (class_name, parent_name)) + lines.append('%spublic:' % (' ' * (_INDENT // 2))) + + # Add all the methods. + _GenerateMethods(lines, source, class_node) + + # Close the class. + if lines: + # If there are no virtual methods, no need for a public label. + if len(lines) == 2: + del lines[-1] + + # Only close the class if there really is a class. + lines.append('};') + lines.append('') # Add an extra newline. + + # Close the namespace. + if class_node.namespace: + for i in range(len(class_node.namespace) - 1, -1, -1): + lines.append('} // namespace %s' % class_node.namespace[i]) + lines.append('') # Add an extra newline. + + if desired_class_names: + missing_class_name_list = list(desired_class_names - processed_class_names) + if missing_class_name_list: + missing_class_name_list.sort() + sys.stderr.write('Class(es) not found in %s: %s\n' % + (filename, ', '.join(missing_class_name_list))) + elif not processed_class_names: + sys.stderr.write('No class found in %s\n' % filename) + + return lines + + +def main(argv=sys.argv): + if len(argv) < 2: + sys.stderr.write('Google Mock Class Generator v%s\n\n' % + '.'.join(map(str, _VERSION))) + sys.stderr.write(__doc__) + return 1 + + global _INDENT + try: + _INDENT = int(os.environ['INDENT']) + except KeyError: + pass + except: + sys.stderr.write('Unable to use indent of %s\n' % os.environ.get('INDENT')) + + filename = argv[1] + desired_class_names = None # None means all classes in the source file. + if len(argv) >= 3: + desired_class_names = set(argv[2:]) + source = utils.ReadFile(filename) + if source is None: + return 1 + + builder = ast.BuilderFromSource(source, filename) + try: + entire_ast = filter(None, builder.Generate()) + except KeyboardInterrupt: + return + except: + # An error message was already printed since we couldn't parse. + sys.exit(1) + else: + lines = _GenerateMocks(filename, source, entire_ast, desired_class_names) + sys.stdout.write('\n'.join(lines)) + + +if __name__ == '__main__': + main(sys.argv) diff --git a/src/googletest/googlemock/scripts/generator/cpp/gmock_class_test.py b/src/googletest/googlemock/scripts/generator/cpp/gmock_class_test.py new file mode 100755 index 000000000..527182cc3 --- /dev/null +++ b/src/googletest/googlemock/scripts/generator/cpp/gmock_class_test.py @@ -0,0 +1,552 @@ +#!/usr/bin/env python +# +# Copyright 2009 Neal Norwitz All Rights Reserved. +# Portions Copyright 2009 Google Inc. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +"""Tests for gmock.scripts.generator.cpp.gmock_class.""" + +import os +import sys +import unittest + +# Allow the cpp imports below to work when run as a standalone script. +sys.path.append(os.path.join(os.path.dirname(__file__), '..')) + +from cpp import ast +from cpp import gmock_class + + +class TestCase(unittest.TestCase): + """Helper class that adds assert methods.""" + + @staticmethod + def StripLeadingWhitespace(lines): + """Strip leading whitespace in each line in 'lines'.""" + return '\n'.join([s.lstrip() for s in lines.split('\n')]) + + def assertEqualIgnoreLeadingWhitespace(self, expected_lines, lines): + """Specialized assert that ignores the indent level.""" + self.assertEqual(expected_lines, self.StripLeadingWhitespace(lines)) + + +class GenerateMethodsTest(TestCase): + + @staticmethod + def GenerateMethodSource(cpp_source): + """Convert C++ source to Google Mock output source lines.""" + method_source_lines = [] + # <test> is a pseudo-filename, it is not read or written. + builder = ast.BuilderFromSource(cpp_source, '<test>') + ast_list = list(builder.Generate()) + gmock_class._GenerateMethods(method_source_lines, cpp_source, ast_list[0]) + return '\n'.join(method_source_lines) + + def testSimpleMethod(self): + source = """ +class Foo { + public: + virtual int Bar(); +}; +""" + self.assertEqualIgnoreLeadingWhitespace( + 'MOCK_METHOD(int, Bar, (), (override));', + self.GenerateMethodSource(source)) + + def testSimpleConstructorsAndDestructor(self): + source = """ +class Foo { + public: + Foo(); + Foo(int x); + Foo(const Foo& f); + Foo(Foo&& f); + ~Foo(); + virtual int Bar() = 0; +}; +""" + # The constructors and destructor should be ignored. + self.assertEqualIgnoreLeadingWhitespace( + 'MOCK_METHOD(int, Bar, (), (override));', + self.GenerateMethodSource(source)) + + def testVirtualDestructor(self): + source = """ +class Foo { + public: + virtual ~Foo(); + virtual int Bar() = 0; +}; +""" + # The destructor should be ignored. + self.assertEqualIgnoreLeadingWhitespace( + 'MOCK_METHOD(int, Bar, (), (override));', + self.GenerateMethodSource(source)) + + def testExplicitlyDefaultedConstructorsAndDestructor(self): + source = """ +class Foo { + public: + Foo() = default; + Foo(const Foo& f) = default; + Foo(Foo&& f) = default; + ~Foo() = default; + virtual int Bar() = 0; +}; +""" + # The constructors and destructor should be ignored. + self.assertEqualIgnoreLeadingWhitespace( + 'MOCK_METHOD(int, Bar, (), (override));', + self.GenerateMethodSource(source)) + + def testExplicitlyDeletedConstructorsAndDestructor(self): + source = """ +class Foo { + public: + Foo() = delete; + Foo(const Foo& f) = delete; + Foo(Foo&& f) = delete; + ~Foo() = delete; + virtual int Bar() = 0; +}; +""" + # The constructors and destructor should be ignored. + self.assertEqualIgnoreLeadingWhitespace( + 'MOCK_METHOD(int, Bar, (), (override));', + self.GenerateMethodSource(source)) + + def testSimpleOverrideMethod(self): + source = """ +class Foo { + public: + int Bar() override; +}; +""" + self.assertEqualIgnoreLeadingWhitespace( + 'MOCK_METHOD(int, Bar, (), (override));', + self.GenerateMethodSource(source)) + + def testSimpleConstMethod(self): + source = """ +class Foo { + public: + virtual void Bar(bool flag) const; +}; +""" + self.assertEqualIgnoreLeadingWhitespace( + 'MOCK_METHOD(void, Bar, (bool flag), (const, override));', + self.GenerateMethodSource(source)) + + def testExplicitVoid(self): + source = """ +class Foo { + public: + virtual int Bar(void); +}; +""" + self.assertEqualIgnoreLeadingWhitespace( + 'MOCK_METHOD(int, Bar, (void), (override));', + self.GenerateMethodSource(source)) + + def testStrangeNewlineInParameter(self): + source = """ +class Foo { + public: + virtual void Bar(int +a) = 0; +}; +""" + self.assertEqualIgnoreLeadingWhitespace( + 'MOCK_METHOD(void, Bar, (int a), (override));', + self.GenerateMethodSource(source)) + + def testDefaultParameters(self): + source = """ +class Foo { + public: + virtual void Bar(int a, char c = 'x') = 0; +}; +""" + self.assertEqualIgnoreLeadingWhitespace( + 'MOCK_METHOD(void, Bar, (int a, char c), (override));', + self.GenerateMethodSource(source)) + + def testMultipleDefaultParameters(self): + source = """ +class Foo { + public: + virtual void Bar( + int a = 42, + char c = 'x', + const int* const p = nullptr, + const std::string& s = "42", + char tab[] = {'4','2'}, + int const *& rp = aDefaultPointer) = 0; +}; +""" + self.assertEqualIgnoreLeadingWhitespace( + 'MOCK_METHOD(void, Bar, ' + '(int a, char c, const int* const p, const std::string& s, char tab[], int const *& rp), ' + '(override));', self.GenerateMethodSource(source)) + + def testMultipleSingleLineDefaultParameters(self): + source = """ +class Foo { + public: + virtual void Bar(int a = 42, int b = 43, int c = 44) = 0; +}; +""" + self.assertEqualIgnoreLeadingWhitespace( + 'MOCK_METHOD(void, Bar, (int a, int b, int c), (override));', + self.GenerateMethodSource(source)) + + def testConstDefaultParameter(self): + source = """ +class Test { + public: + virtual bool Bar(const int test_arg = 42) = 0; +}; +""" + self.assertEqualIgnoreLeadingWhitespace( + 'MOCK_METHOD(bool, Bar, (const int test_arg), (override));', + self.GenerateMethodSource(source)) + + def testConstRefDefaultParameter(self): + source = """ +class Test { + public: + virtual bool Bar(const std::string& test_arg = "42" ) = 0; +}; +""" + self.assertEqualIgnoreLeadingWhitespace( + 'MOCK_METHOD(bool, Bar, (const std::string& test_arg), (override));', + self.GenerateMethodSource(source)) + + def testRemovesCommentsWhenDefaultsArePresent(self): + source = """ +class Foo { + public: + virtual void Bar(int a = 42 /* a comment */, + char /* other comment */ c= 'x') = 0; +}; +""" + self.assertEqualIgnoreLeadingWhitespace( + 'MOCK_METHOD(void, Bar, (int a, char c), (override));', + self.GenerateMethodSource(source)) + + def testDoubleSlashCommentsInParameterListAreRemoved(self): + source = """ +class Foo { + public: + virtual void Bar(int a, // inline comments should be elided. + int b // inline comments should be elided. + ) const = 0; +}; +""" + self.assertEqualIgnoreLeadingWhitespace( + 'MOCK_METHOD(void, Bar, (int a, int b), (const, override));', + self.GenerateMethodSource(source)) + + def testCStyleCommentsInParameterListAreNotRemoved(self): + # NOTE(nnorwitz): I'm not sure if it's the best behavior to keep these + # comments. Also note that C style comments after the last parameter + # are still elided. + source = """ +class Foo { + public: + virtual const string& Bar(int /* keeper */, int b); +}; +""" + self.assertEqualIgnoreLeadingWhitespace( + 'MOCK_METHOD(const string&, Bar, (int, int b), (override));', + self.GenerateMethodSource(source)) + + def testArgsOfTemplateTypes(self): + source = """ +class Foo { + public: + virtual int Bar(const vector<int>& v, map<int, string>* output); +};""" + self.assertEqualIgnoreLeadingWhitespace( + 'MOCK_METHOD(int, Bar, (const vector<int>& v, (map<int, string>* output)), (override));', + self.GenerateMethodSource(source)) + + def testReturnTypeWithOneTemplateArg(self): + source = """ +class Foo { + public: + virtual vector<int>* Bar(int n); +};""" + self.assertEqualIgnoreLeadingWhitespace( + 'MOCK_METHOD(vector<int>*, Bar, (int n), (override));', + self.GenerateMethodSource(source)) + + def testReturnTypeWithManyTemplateArgs(self): + source = """ +class Foo { + public: + virtual map<int, string> Bar(); +};""" + self.assertEqualIgnoreLeadingWhitespace( + 'MOCK_METHOD((map<int, string>), Bar, (), (override));', + self.GenerateMethodSource(source)) + + def testSimpleMethodInTemplatedClass(self): + source = """ +template<class T> +class Foo { + public: + virtual int Bar(); +}; +""" + self.assertEqualIgnoreLeadingWhitespace( + 'MOCK_METHOD(int, Bar, (), (override));', + self.GenerateMethodSource(source)) + + def testPointerArgWithoutNames(self): + source = """ +class Foo { + virtual int Bar(C*); +}; +""" + self.assertEqualIgnoreLeadingWhitespace( + 'MOCK_METHOD(int, Bar, (C*), (override));', + self.GenerateMethodSource(source)) + + def testReferenceArgWithoutNames(self): + source = """ +class Foo { + virtual int Bar(C&); +}; +""" + self.assertEqualIgnoreLeadingWhitespace( + 'MOCK_METHOD(int, Bar, (C&), (override));', + self.GenerateMethodSource(source)) + + def testArrayArgWithoutNames(self): + source = """ +class Foo { + virtual int Bar(C[]); +}; +""" + self.assertEqualIgnoreLeadingWhitespace( + 'MOCK_METHOD(int, Bar, (C[]), (override));', + self.GenerateMethodSource(source)) + + +class GenerateMocksTest(TestCase): + + @staticmethod + def GenerateMocks(cpp_source): + """Convert C++ source to complete Google Mock output source.""" + # <test> is a pseudo-filename, it is not read or written. + filename = '<test>' + builder = ast.BuilderFromSource(cpp_source, filename) + ast_list = list(builder.Generate()) + lines = gmock_class._GenerateMocks(filename, cpp_source, ast_list, None) + return '\n'.join(lines) + + def testNamespaces(self): + source = """ +namespace Foo { +namespace Bar { class Forward; } +namespace Baz::Qux { + +class Test { + public: + virtual void Foo(); +}; + +} // namespace Baz::Qux +} // namespace Foo +""" + expected = """\ +namespace Foo { +namespace Baz::Qux { + +class MockTest : public Test { +public: +MOCK_METHOD(void, Foo, (), (override)); +}; + +} // namespace Baz::Qux +} // namespace Foo +""" + self.assertEqualIgnoreLeadingWhitespace(expected, + self.GenerateMocks(source)) + + def testClassWithStorageSpecifierMacro(self): + source = """ +class STORAGE_SPECIFIER Test { + public: + virtual void Foo(); +}; +""" + expected = """\ +class MockTest : public Test { +public: +MOCK_METHOD(void, Foo, (), (override)); +}; +""" + self.assertEqualIgnoreLeadingWhitespace(expected, + self.GenerateMocks(source)) + + def testTemplatedForwardDeclaration(self): + source = """ +template <class T> class Forward; // Forward declaration should be ignored. +class Test { + public: + virtual void Foo(); +}; +""" + expected = """\ +class MockTest : public Test { +public: +MOCK_METHOD(void, Foo, (), (override)); +}; +""" + self.assertEqualIgnoreLeadingWhitespace(expected, + self.GenerateMocks(source)) + + def testTemplatedClass(self): + source = """ +template <typename S, typename T> +class Test { + public: + virtual void Foo(); +}; +""" + expected = """\ +template <typename T0, typename T1> +class MockTest : public Test<T0, T1> { +public: +MOCK_METHOD(void, Foo, (), (override)); +}; +""" + self.assertEqualIgnoreLeadingWhitespace(expected, + self.GenerateMocks(source)) + + def testTemplateInATemplateTypedef(self): + source = """ +class Test { + public: + typedef std::vector<std::list<int>> FooType; + virtual void Bar(const FooType& test_arg); +}; +""" + expected = """\ +class MockTest : public Test { +public: +MOCK_METHOD(void, Bar, (const FooType& test_arg), (override)); +}; +""" + self.assertEqualIgnoreLeadingWhitespace(expected, + self.GenerateMocks(source)) + + def testTemplateInATemplateTypedefWithComma(self): + source = """ +class Test { + public: + typedef std::function<void( + const vector<std::list<int>>&, int> FooType; + virtual void Bar(const FooType& test_arg); +}; +""" + expected = """\ +class MockTest : public Test { +public: +MOCK_METHOD(void, Bar, (const FooType& test_arg), (override)); +}; +""" + self.assertEqualIgnoreLeadingWhitespace(expected, + self.GenerateMocks(source)) + + def testParenthesizedCommaInArg(self): + source = """ +class Test { + public: + virtual void Bar(std::function<void(int, int)> f); +}; +""" + expected = """\ +class MockTest : public Test { +public: +MOCK_METHOD(void, Bar, (std::function<void(int, int)> f), (override)); +}; +""" + self.assertEqualIgnoreLeadingWhitespace(expected, + self.GenerateMocks(source)) + + def testEnumType(self): + source = """ +class Test { + public: + enum Bar { + BAZ, QUX, QUUX, QUUUX + }; + virtual void Foo(); +}; +""" + expected = """\ +class MockTest : public Test { +public: +MOCK_METHOD(void, Foo, (), (override)); +}; +""" + self.assertEqualIgnoreLeadingWhitespace(expected, + self.GenerateMocks(source)) + + def testEnumClassType(self): + source = """ +class Test { + public: + enum class Bar { + BAZ, QUX, QUUX, QUUUX + }; + virtual void Foo(); +}; +""" + expected = """\ +class MockTest : public Test { +public: +MOCK_METHOD(void, Foo, (), (override)); +}; +""" + self.assertEqualIgnoreLeadingWhitespace(expected, + self.GenerateMocks(source)) + + def testStdFunction(self): + source = """ +class Test { + public: + Test(std::function<int(std::string)> foo) : foo_(foo) {} + + virtual std::function<int(std::string)> foo(); + + private: + std::function<int(std::string)> foo_; +}; +""" + expected = """\ +class MockTest : public Test { +public: +MOCK_METHOD(std::function<int (std::string)>, foo, (), (override)); +}; +""" + self.assertEqualIgnoreLeadingWhitespace(expected, + self.GenerateMocks(source)) + + +if __name__ == '__main__': + unittest.main() diff --git a/src/googletest/googlemock/scripts/generator/cpp/keywords.py b/src/googletest/googlemock/scripts/generator/cpp/keywords.py new file mode 100755 index 000000000..e4282714d --- /dev/null +++ b/src/googletest/googlemock/scripts/generator/cpp/keywords.py @@ -0,0 +1,56 @@ +#!/usr/bin/env python +# +# Copyright 2007 Neal Norwitz +# Portions Copyright 2007 Google Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +"""C++ keywords and helper utilities for determining keywords.""" + +try: + # Python 3.x + import builtins +except ImportError: + # Python 2.x + import __builtin__ as builtins + + +if not hasattr(builtins, 'set'): + # Nominal support for Python 2.3. + from sets import Set as set + + +TYPES = set('bool char int long short double float void wchar_t unsigned signed'.split()) +TYPE_MODIFIERS = set('auto register const inline extern static virtual volatile mutable'.split()) +ACCESS = set('public protected private friend'.split()) + +CASTS = set('static_cast const_cast dynamic_cast reinterpret_cast'.split()) + +OTHERS = set('true false asm class namespace using explicit this operator sizeof'.split()) +OTHER_TYPES = set('new delete typedef struct union enum typeid typename template'.split()) + +CONTROL = set('case switch default if else return goto'.split()) +EXCEPTION = set('try catch throw'.split()) +LOOP = set('while do for break continue'.split()) + +ALL = TYPES | TYPE_MODIFIERS | ACCESS | CASTS | OTHERS | OTHER_TYPES | CONTROL | EXCEPTION | LOOP + + +def IsKeyword(token): + return token in ALL + +def IsBuiltinType(token): + if token in ('virtual', 'inline'): + # These only apply to methods, they can't be types by themselves. + return False + return token in TYPES or token in TYPE_MODIFIERS diff --git a/src/googletest/googlemock/scripts/generator/cpp/tokenize.py b/src/googletest/googlemock/scripts/generator/cpp/tokenize.py new file mode 100755 index 000000000..a75edcb14 --- /dev/null +++ b/src/googletest/googlemock/scripts/generator/cpp/tokenize.py @@ -0,0 +1,284 @@ +#!/usr/bin/env python +# +# Copyright 2007 Neal Norwitz +# Portions Copyright 2007 Google Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +"""Tokenize C++ source code.""" + +try: + # Python 3.x + import builtins +except ImportError: + # Python 2.x + import __builtin__ as builtins + + +import sys + +from cpp import utils + + +if not hasattr(builtins, 'set'): + # Nominal support for Python 2.3. + from sets import Set as set + + +# Add $ as a valid identifier char since so much code uses it. +_letters = 'abcdefghijklmnopqrstuvwxyz' +VALID_IDENTIFIER_CHARS = set(_letters + _letters.upper() + '_0123456789$') +HEX_DIGITS = set('0123456789abcdefABCDEF') +INT_OR_FLOAT_DIGITS = set('01234567890eE-+') + + +# C++0x string preffixes. +_STR_PREFIXES = set(('R', 'u8', 'u8R', 'u', 'uR', 'U', 'UR', 'L', 'LR')) + + +# Token types. +UNKNOWN = 'UNKNOWN' +SYNTAX = 'SYNTAX' +CONSTANT = 'CONSTANT' +NAME = 'NAME' +PREPROCESSOR = 'PREPROCESSOR' + +# Where the token originated from. This can be used for backtracking. +# It is always set to WHENCE_STREAM in this code. +WHENCE_STREAM, WHENCE_QUEUE = range(2) + + +class Token(object): + """Data container to represent a C++ token. + + Tokens can be identifiers, syntax char(s), constants, or + pre-processor directives. + + start contains the index of the first char of the token in the source + end contains the index of the last char of the token in the source + """ + + def __init__(self, token_type, name, start, end): + self.token_type = token_type + self.name = name + self.start = start + self.end = end + self.whence = WHENCE_STREAM + + def __str__(self): + if not utils.DEBUG: + return 'Token(%r)' % self.name + return 'Token(%r, %s, %s)' % (self.name, self.start, self.end) + + __repr__ = __str__ + + +def _GetString(source, start, i): + i = source.find('"', i+1) + while source[i-1] == '\\': + # Count the trailing backslashes. + backslash_count = 1 + j = i - 2 + while source[j] == '\\': + backslash_count += 1 + j -= 1 + # When trailing backslashes are even, they escape each other. + if (backslash_count % 2) == 0: + break + i = source.find('"', i+1) + return i + 1 + + +def _GetChar(source, start, i): + # NOTE(nnorwitz): may not be quite correct, should be good enough. + i = source.find("'", i+1) + while source[i-1] == '\\': + # Need to special case '\\'. + if (i - 2) > start and source[i-2] == '\\': + break + i = source.find("'", i+1) + # Try to handle unterminated single quotes (in a #if 0 block). + if i < 0: + i = start + return i + 1 + + +def GetTokens(source): + """Returns a sequence of Tokens. + + Args: + source: string of C++ source code. + + Yields: + Token that represents the next token in the source. + """ + # Cache various valid character sets for speed. + valid_identifier_chars = VALID_IDENTIFIER_CHARS + hex_digits = HEX_DIGITS + int_or_float_digits = INT_OR_FLOAT_DIGITS + int_or_float_digits2 = int_or_float_digits | set('.') + + # Only ignore errors while in a #if 0 block. + ignore_errors = False + count_ifs = 0 + + i = 0 + end = len(source) + while i < end: + # Skip whitespace. + while i < end and source[i].isspace(): + i += 1 + if i >= end: + return + + token_type = UNKNOWN + start = i + c = source[i] + if c.isalpha() or c == '_': # Find a string token. + token_type = NAME + while source[i] in valid_identifier_chars: + i += 1 + # String and character constants can look like a name if + # they are something like L"". + if (source[i] == "'" and (i - start) == 1 and + source[start:i] in 'uUL'): + # u, U, and L are valid C++0x character preffixes. + token_type = CONSTANT + i = _GetChar(source, start, i) + elif source[i] == "'" and source[start:i] in _STR_PREFIXES: + token_type = CONSTANT + i = _GetString(source, start, i) + elif c == '/' and source[i+1] == '/': # Find // comments. + i = source.find('\n', i) + if i == -1: # Handle EOF. + i = end + continue + elif c == '/' and source[i+1] == '*': # Find /* comments. */ + i = source.find('*/', i) + 2 + continue + elif c in ':+-<>&|*=': # : or :: (plus other chars). + token_type = SYNTAX + i += 1 + new_ch = source[i] + if new_ch == c and c != '>': # Treat ">>" as two tokens. + i += 1 + elif c == '-' and new_ch == '>': + i += 1 + elif new_ch == '=': + i += 1 + elif c in '()[]{}~!?^%;/.,': # Handle single char tokens. + token_type = SYNTAX + i += 1 + if c == '.' and source[i].isdigit(): + token_type = CONSTANT + i += 1 + while source[i] in int_or_float_digits: + i += 1 + # Handle float suffixes. + for suffix in ('l', 'f'): + if suffix == source[i:i+1].lower(): + i += 1 + break + elif c.isdigit(): # Find integer. + token_type = CONSTANT + if c == '0' and source[i+1] in 'xX': + # Handle hex digits. + i += 2 + while source[i] in hex_digits: + i += 1 + else: + while source[i] in int_or_float_digits2: + i += 1 + # Handle integer (and float) suffixes. + for suffix in ('ull', 'll', 'ul', 'l', 'f', 'u'): + size = len(suffix) + if suffix == source[i:i+size].lower(): + i += size + break + elif c == '"': # Find string. + token_type = CONSTANT + i = _GetString(source, start, i) + elif c == "'": # Find char. + token_type = CONSTANT + i = _GetChar(source, start, i) + elif c == '#': # Find pre-processor command. + token_type = PREPROCESSOR + got_if = source[i:i+3] == '#if' and source[i+3:i+4].isspace() + if got_if: + count_ifs += 1 + elif source[i:i+6] == '#endif': + count_ifs -= 1 + if count_ifs == 0: + ignore_errors = False + + # TODO(nnorwitz): handle preprocessor statements (\ continuations). + while 1: + i1 = source.find('\n', i) + i2 = source.find('//', i) + i3 = source.find('/*', i) + i4 = source.find('"', i) + # NOTE(nnorwitz): doesn't handle comments in #define macros. + # Get the first important symbol (newline, comment, EOF/end). + i = min([x for x in (i1, i2, i3, i4, end) if x != -1]) + + # Handle #include "dir//foo.h" properly. + if source[i] == '"': + i = source.find('"', i+1) + 1 + assert i > 0 + continue + # Keep going if end of the line and the line ends with \. + if not (i == i1 and source[i-1] == '\\'): + if got_if: + condition = source[start+4:i].lstrip() + if (condition.startswith('0') or + condition.startswith('(0)')): + ignore_errors = True + break + i += 1 + elif c == '\\': # Handle \ in code. + # This is different from the pre-processor \ handling. + i += 1 + continue + elif ignore_errors: + # The tokenizer seems to be in pretty good shape. This + # raise is conditionally disabled so that bogus code + # in an #if 0 block can be handled. Since we will ignore + # it anyways, this is probably fine. So disable the + # exception and return the bogus char. + i += 1 + else: + sys.stderr.write('Got invalid token in %s @ %d token:%s: %r\n' % + ('?', i, c, source[i-10:i+10])) + raise RuntimeError('unexpected token') + + if i <= 0: + print('Invalid index, exiting now.') + return + yield Token(token_type, source[start:i], start, i) + + +if __name__ == '__main__': + def main(argv): + """Driver mostly for testing purposes.""" + for filename in argv[1:]: + source = utils.ReadFile(filename) + if source is None: + continue + + for token in GetTokens(source): + print('%-12s: %s' % (token.token_type, token.name)) + # print('\r%6.2f%%' % (100.0 * index / token.end),) + sys.stdout.write('\n') + + + main(sys.argv) diff --git a/src/googletest/googlemock/scripts/generator/cpp/utils.py b/src/googletest/googlemock/scripts/generator/cpp/utils.py new file mode 100755 index 000000000..6f5fc097b --- /dev/null +++ b/src/googletest/googlemock/scripts/generator/cpp/utils.py @@ -0,0 +1,37 @@ +#!/usr/bin/env python +# +# Copyright 2007 Neal Norwitz +# Portions Copyright 2007 Google Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +"""Generic utilities for C++ parsing.""" + +import sys + +# Set to True to see the start/end token indices. +DEBUG = True + + +def ReadFile(filename, print_error=True): + """Returns the contents of a file.""" + try: + fp = open(filename) + try: + return fp.read() + finally: + fp.close() + except IOError: + if print_error: + print('Error reading %s: %s' % (filename, sys.exc_info()[1])) + return None diff --git a/src/googletest/googlemock/scripts/generator/gmock_gen.py b/src/googletest/googlemock/scripts/generator/gmock_gen.py new file mode 100755 index 000000000..9d528a56d --- /dev/null +++ b/src/googletest/googlemock/scripts/generator/gmock_gen.py @@ -0,0 +1,30 @@ +#!/usr/bin/env python +# +# Copyright 2008 Google Inc. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +"""Driver for starting up Google Mock class generator.""" + + +import os +import sys + +if __name__ == '__main__': + # Add the directory of this script to the path so we can import gmock_class. + sys.path.append(os.path.dirname(__file__)) + + from cpp import gmock_class + # Fix the docstring in case they require the usage. + gmock_class.__doc__ = gmock_class.__doc__.replace('gmock_class.py', __file__) + gmock_class.main() diff --git a/src/googletest/googlemock/scripts/pump.py b/src/googletest/googlemock/scripts/pump.py new file mode 100755 index 000000000..5523a19de --- /dev/null +++ b/src/googletest/googlemock/scripts/pump.py @@ -0,0 +1,856 @@ +#!/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. + +"""pump v0.2.0 - Pretty Useful for Meta Programming. + +A tool for preprocessor meta programming. Useful for generating +repetitive boilerplate code. Especially useful for writing C++ +classes, functions, macros, and templates that need to work with +various number of arguments. + +USAGE: + pump.py SOURCE_FILE + +EXAMPLES: + pump.py foo.cc.pump + Converts foo.cc.pump to foo.cc. + +GRAMMAR: + CODE ::= ATOMIC_CODE* + ATOMIC_CODE ::= $var ID = EXPRESSION + | $var ID = [[ CODE ]] + | $range ID EXPRESSION..EXPRESSION + | $for ID SEPARATOR [[ CODE ]] + | $($) + | $ID + | $(EXPRESSION) + | $if EXPRESSION [[ CODE ]] ELSE_BRANCH + | [[ CODE ]] + | RAW_CODE + SEPARATOR ::= RAW_CODE | EMPTY + ELSE_BRANCH ::= $else [[ CODE ]] + | $elif EXPRESSION [[ CODE ]] ELSE_BRANCH + | EMPTY + EXPRESSION has Python syntax. +""" + +from __future__ import print_function + +import io +import os +import re +import sys + + +TOKEN_TABLE = [ + (re.compile(r'\$var\s+'), '$var'), + (re.compile(r'\$elif\s+'), '$elif'), + (re.compile(r'\$else\s+'), '$else'), + (re.compile(r'\$for\s+'), '$for'), + (re.compile(r'\$if\s+'), '$if'), + (re.compile(r'\$range\s+'), '$range'), + (re.compile(r'\$[_A-Za-z]\w*'), '$id'), + (re.compile(r'\$\(\$\)'), '$($)'), + (re.compile(r'\$'), '$'), + (re.compile(r'\[\[\n?'), '[['), + (re.compile(r'\]\]\n?'), ']]'), + ] + + +class Cursor: + """Represents a position (line and column) in a text file.""" + + def __init__(self, line=-1, column=-1): + self.line = line + self.column = column + + def __eq__(self, rhs): + return self.line == rhs.line and self.column == rhs.column + + def __ne__(self, rhs): + return not self == rhs + + def __lt__(self, rhs): + return self.line < rhs.line or ( + self.line == rhs.line and self.column < rhs.column) + + def __le__(self, rhs): + return self < rhs or self == rhs + + def __gt__(self, rhs): + return rhs < self + + def __ge__(self, rhs): + return rhs <= self + + def __str__(self): + if self == Eof(): + return 'EOF' + else: + return '%s(%s)' % (self.line + 1, self.column) + + def __add__(self, offset): + return Cursor(self.line, self.column + offset) + + def __sub__(self, offset): + return Cursor(self.line, self.column - offset) + + def Clone(self): + """Returns a copy of self.""" + + return Cursor(self.line, self.column) + + +# Special cursor to indicate the end-of-file. +def Eof(): + """Returns the special cursor to denote the end-of-file.""" + return Cursor(-1, -1) + + +class Token: + """Represents a token in a Pump source file.""" + + def __init__(self, start=None, end=None, value=None, token_type=None): + if start is None: + self.start = Eof() + else: + self.start = start + if end is None: + self.end = Eof() + else: + self.end = end + self.value = value + self.token_type = token_type + + def __str__(self): + return 'Token @%s: \'%s\' type=%s' % ( + self.start, self.value, self.token_type) + + def Clone(self): + """Returns a copy of self.""" + + return Token(self.start.Clone(), self.end.Clone(), self.value, + self.token_type) + + +def StartsWith(lines, pos, string): + """Returns True iff the given position in lines starts with 'string'.""" + + return lines[pos.line][pos.column:].startswith(string) + + +def FindFirstInLine(line, token_table): + best_match_start = -1 + for (regex, token_type) in token_table: + m = regex.search(line) + if m: + # We found regex in lines + if best_match_start < 0 or m.start() < best_match_start: + best_match_start = m.start() + best_match_length = m.end() - m.start() + best_match_token_type = token_type + + if best_match_start < 0: + return None + + return (best_match_start, best_match_length, best_match_token_type) + + +def FindFirst(lines, token_table, cursor): + """Finds the first occurrence of any string in strings in lines.""" + + start = cursor.Clone() + cur_line_number = cursor.line + for line in lines[start.line:]: + if cur_line_number == start.line: + line = line[start.column:] + m = FindFirstInLine(line, token_table) + if m: + # We found a regex in line. + (start_column, length, token_type) = m + if cur_line_number == start.line: + start_column += start.column + found_start = Cursor(cur_line_number, start_column) + found_end = found_start + length + return MakeToken(lines, found_start, found_end, token_type) + cur_line_number += 1 + # We failed to find str in lines + return None + + +def SubString(lines, start, end): + """Returns a substring in lines.""" + + if end == Eof(): + end = Cursor(len(lines) - 1, len(lines[-1])) + + if start >= end: + return '' + + if start.line == end.line: + return lines[start.line][start.column:end.column] + + result_lines = ([lines[start.line][start.column:]] + + lines[start.line + 1:end.line] + + [lines[end.line][:end.column]]) + return ''.join(result_lines) + + +def StripMetaComments(str): + """Strip meta comments from each line in the given string.""" + + # First, completely remove lines containing nothing but a meta + # comment, including the trailing \n. + str = re.sub(r'^\s*\$\$.*\n', '', str) + + # Then, remove meta comments from contentful lines. + return re.sub(r'\s*\$\$.*', '', str) + + +def MakeToken(lines, start, end, token_type): + """Creates a new instance of Token.""" + + return Token(start, end, SubString(lines, start, end), token_type) + + +def ParseToken(lines, pos, regex, token_type): + line = lines[pos.line][pos.column:] + m = regex.search(line) + if m and not m.start(): + return MakeToken(lines, pos, pos + m.end(), token_type) + else: + print('ERROR: %s expected at %s.' % (token_type, pos)) + sys.exit(1) + + +ID_REGEX = re.compile(r'[_A-Za-z]\w*') +EQ_REGEX = re.compile(r'=') +REST_OF_LINE_REGEX = re.compile(r'.*?(?=$|\$\$)') +OPTIONAL_WHITE_SPACES_REGEX = re.compile(r'\s*') +WHITE_SPACE_REGEX = re.compile(r'\s') +DOT_DOT_REGEX = re.compile(r'\.\.') + + +def Skip(lines, pos, regex): + line = lines[pos.line][pos.column:] + m = re.search(regex, line) + if m and not m.start(): + return pos + m.end() + else: + return pos + + +def SkipUntil(lines, pos, regex, token_type): + line = lines[pos.line][pos.column:] + m = re.search(regex, line) + if m: + return pos + m.start() + else: + print ('ERROR: %s expected on line %s after column %s.' % + (token_type, pos.line + 1, pos.column)) + sys.exit(1) + + +def ParseExpTokenInParens(lines, pos): + def ParseInParens(pos): + pos = Skip(lines, pos, OPTIONAL_WHITE_SPACES_REGEX) + pos = Skip(lines, pos, r'\(') + pos = Parse(pos) + pos = Skip(lines, pos, r'\)') + return pos + + def Parse(pos): + pos = SkipUntil(lines, pos, r'\(|\)', ')') + if SubString(lines, pos, pos + 1) == '(': + pos = Parse(pos + 1) + pos = Skip(lines, pos, r'\)') + return Parse(pos) + else: + return pos + + start = pos.Clone() + pos = ParseInParens(pos) + return MakeToken(lines, start, pos, 'exp') + + +def RStripNewLineFromToken(token): + if token.value.endswith('\n'): + return Token(token.start, token.end, token.value[:-1], token.token_type) + else: + return token + + +def TokenizeLines(lines, pos): + while True: + found = FindFirst(lines, TOKEN_TABLE, pos) + if not found: + yield MakeToken(lines, pos, Eof(), 'code') + return + + if found.start == pos: + prev_token = None + prev_token_rstripped = None + else: + prev_token = MakeToken(lines, pos, found.start, 'code') + prev_token_rstripped = RStripNewLineFromToken(prev_token) + + if found.token_type == '$var': + if prev_token_rstripped: + yield prev_token_rstripped + yield found + id_token = ParseToken(lines, found.end, ID_REGEX, 'id') + yield id_token + pos = Skip(lines, id_token.end, OPTIONAL_WHITE_SPACES_REGEX) + + eq_token = ParseToken(lines, pos, EQ_REGEX, '=') + yield eq_token + pos = Skip(lines, eq_token.end, r'\s*') + + if SubString(lines, pos, pos + 2) != '[[': + exp_token = ParseToken(lines, pos, REST_OF_LINE_REGEX, 'exp') + yield exp_token + pos = Cursor(exp_token.end.line + 1, 0) + elif found.token_type == '$for': + if prev_token_rstripped: + yield prev_token_rstripped + yield found + id_token = ParseToken(lines, found.end, ID_REGEX, 'id') + yield id_token + pos = Skip(lines, id_token.end, WHITE_SPACE_REGEX) + elif found.token_type == '$range': + if prev_token_rstripped: + yield prev_token_rstripped + yield found + id_token = ParseToken(lines, found.end, ID_REGEX, 'id') + yield id_token + pos = Skip(lines, id_token.end, OPTIONAL_WHITE_SPACES_REGEX) + + dots_pos = SkipUntil(lines, pos, DOT_DOT_REGEX, '..') + yield MakeToken(lines, pos, dots_pos, 'exp') + yield MakeToken(lines, dots_pos, dots_pos + 2, '..') + pos = dots_pos + 2 + new_pos = Cursor(pos.line + 1, 0) + yield MakeToken(lines, pos, new_pos, 'exp') + pos = new_pos + elif found.token_type == '$': + if prev_token: + yield prev_token + yield found + exp_token = ParseExpTokenInParens(lines, found.end) + yield exp_token + pos = exp_token.end + elif (found.token_type == ']]' or found.token_type == '$if' or + found.token_type == '$elif' or found.token_type == '$else'): + if prev_token_rstripped: + yield prev_token_rstripped + yield found + pos = found.end + else: + if prev_token: + yield prev_token + yield found + pos = found.end + + +def Tokenize(s): + """A generator that yields the tokens in the given string.""" + if s != '': + lines = s.splitlines(True) + for token in TokenizeLines(lines, Cursor(0, 0)): + yield token + + +class CodeNode: + def __init__(self, atomic_code_list=None): + self.atomic_code = atomic_code_list + + +class VarNode: + def __init__(self, identifier=None, atomic_code=None): + self.identifier = identifier + self.atomic_code = atomic_code + + +class RangeNode: + def __init__(self, identifier=None, exp1=None, exp2=None): + self.identifier = identifier + self.exp1 = exp1 + self.exp2 = exp2 + + +class ForNode: + def __init__(self, identifier=None, sep=None, code=None): + self.identifier = identifier + self.sep = sep + self.code = code + + +class ElseNode: + def __init__(self, else_branch=None): + self.else_branch = else_branch + + +class IfNode: + def __init__(self, exp=None, then_branch=None, else_branch=None): + self.exp = exp + self.then_branch = then_branch + self.else_branch = else_branch + + +class RawCodeNode: + def __init__(self, token=None): + self.raw_code = token + + +class LiteralDollarNode: + def __init__(self, token): + self.token = token + + +class ExpNode: + def __init__(self, token, python_exp): + self.token = token + self.python_exp = python_exp + + +def PopFront(a_list): + head = a_list[0] + a_list[:1] = [] + return head + + +def PushFront(a_list, elem): + a_list[:0] = [elem] + + +def PopToken(a_list, token_type=None): + token = PopFront(a_list) + if token_type is not None and token.token_type != token_type: + print('ERROR: %s expected at %s' % (token_type, token.start)) + print('ERROR: %s found instead' % (token,)) + sys.exit(1) + + return token + + +def PeekToken(a_list): + if not a_list: + return None + + return a_list[0] + + +def ParseExpNode(token): + python_exp = re.sub(r'([_A-Za-z]\w*)', r'self.GetValue("\1")', token.value) + return ExpNode(token, python_exp) + + +def ParseElseNode(tokens): + def Pop(token_type=None): + return PopToken(tokens, token_type) + + next = PeekToken(tokens) + if not next: + return None + if next.token_type == '$else': + Pop('$else') + Pop('[[') + code_node = ParseCodeNode(tokens) + Pop(']]') + return code_node + elif next.token_type == '$elif': + Pop('$elif') + exp = Pop('code') + Pop('[[') + code_node = ParseCodeNode(tokens) + Pop(']]') + inner_else_node = ParseElseNode(tokens) + return CodeNode([IfNode(ParseExpNode(exp), code_node, inner_else_node)]) + elif not next.value.strip(): + Pop('code') + return ParseElseNode(tokens) + else: + return None + + +def ParseAtomicCodeNode(tokens): + def Pop(token_type=None): + return PopToken(tokens, token_type) + + head = PopFront(tokens) + t = head.token_type + if t == 'code': + return RawCodeNode(head) + elif t == '$var': + id_token = Pop('id') + Pop('=') + next = PeekToken(tokens) + if next.token_type == 'exp': + exp_token = Pop() + return VarNode(id_token, ParseExpNode(exp_token)) + Pop('[[') + code_node = ParseCodeNode(tokens) + Pop(']]') + return VarNode(id_token, code_node) + elif t == '$for': + id_token = Pop('id') + next_token = PeekToken(tokens) + if next_token.token_type == 'code': + sep_token = next_token + Pop('code') + else: + sep_token = None + Pop('[[') + code_node = ParseCodeNode(tokens) + Pop(']]') + return ForNode(id_token, sep_token, code_node) + elif t == '$if': + exp_token = Pop('code') + Pop('[[') + code_node = ParseCodeNode(tokens) + Pop(']]') + else_node = ParseElseNode(tokens) + return IfNode(ParseExpNode(exp_token), code_node, else_node) + elif t == '$range': + id_token = Pop('id') + exp1_token = Pop('exp') + Pop('..') + exp2_token = Pop('exp') + return RangeNode(id_token, ParseExpNode(exp1_token), + ParseExpNode(exp2_token)) + elif t == '$id': + return ParseExpNode(Token(head.start + 1, head.end, head.value[1:], 'id')) + elif t == '$($)': + return LiteralDollarNode(head) + elif t == '$': + exp_token = Pop('exp') + return ParseExpNode(exp_token) + elif t == '[[': + code_node = ParseCodeNode(tokens) + Pop(']]') + return code_node + else: + PushFront(tokens, head) + return None + + +def ParseCodeNode(tokens): + atomic_code_list = [] + while True: + if not tokens: + break + atomic_code_node = ParseAtomicCodeNode(tokens) + if atomic_code_node: + atomic_code_list.append(atomic_code_node) + else: + break + return CodeNode(atomic_code_list) + + +def ParseToAST(pump_src_text): + """Convert the given Pump source text into an AST.""" + tokens = list(Tokenize(pump_src_text)) + code_node = ParseCodeNode(tokens) + return code_node + + +class Env: + def __init__(self): + self.variables = [] + self.ranges = [] + + def Clone(self): + clone = Env() + clone.variables = self.variables[:] + clone.ranges = self.ranges[:] + return clone + + def PushVariable(self, var, value): + # If value looks like an int, store it as an int. + try: + int_value = int(value) + if ('%s' % int_value) == value: + value = int_value + except Exception: + pass + self.variables[:0] = [(var, value)] + + def PopVariable(self): + self.variables[:1] = [] + + def PushRange(self, var, lower, upper): + self.ranges[:0] = [(var, lower, upper)] + + def PopRange(self): + self.ranges[:1] = [] + + def GetValue(self, identifier): + for (var, value) in self.variables: + if identifier == var: + return value + + print('ERROR: meta variable %s is undefined.' % (identifier,)) + sys.exit(1) + + def EvalExp(self, exp): + try: + result = eval(exp.python_exp) + except Exception as e: # pylint: disable=broad-except + print('ERROR: caught exception %s: %s' % (e.__class__.__name__, e)) + print('ERROR: failed to evaluate meta expression %s at %s' % + (exp.python_exp, exp.token.start)) + sys.exit(1) + return result + + def GetRange(self, identifier): + for (var, lower, upper) in self.ranges: + if identifier == var: + return (lower, upper) + + print('ERROR: range %s is undefined.' % (identifier,)) + sys.exit(1) + + +class Output: + def __init__(self): + self.string = '' + + def GetLastLine(self): + index = self.string.rfind('\n') + if index < 0: + return '' + + return self.string[index + 1:] + + def Append(self, s): + self.string += s + + +def RunAtomicCode(env, node, output): + if isinstance(node, VarNode): + identifier = node.identifier.value.strip() + result = Output() + RunAtomicCode(env.Clone(), node.atomic_code, result) + value = result.string + env.PushVariable(identifier, value) + elif isinstance(node, RangeNode): + identifier = node.identifier.value.strip() + lower = int(env.EvalExp(node.exp1)) + upper = int(env.EvalExp(node.exp2)) + env.PushRange(identifier, lower, upper) + elif isinstance(node, ForNode): + identifier = node.identifier.value.strip() + if node.sep is None: + sep = '' + else: + sep = node.sep.value + (lower, upper) = env.GetRange(identifier) + for i in range(lower, upper + 1): + new_env = env.Clone() + new_env.PushVariable(identifier, i) + RunCode(new_env, node.code, output) + if i != upper: + output.Append(sep) + elif isinstance(node, RawCodeNode): + output.Append(node.raw_code.value) + elif isinstance(node, IfNode): + cond = env.EvalExp(node.exp) + if cond: + RunCode(env.Clone(), node.then_branch, output) + elif node.else_branch is not None: + RunCode(env.Clone(), node.else_branch, output) + elif isinstance(node, ExpNode): + value = env.EvalExp(node) + output.Append('%s' % (value,)) + elif isinstance(node, LiteralDollarNode): + output.Append('$') + elif isinstance(node, CodeNode): + RunCode(env.Clone(), node, output) + else: + print('BAD') + print(node) + sys.exit(1) + + +def RunCode(env, code_node, output): + for atomic_code in code_node.atomic_code: + RunAtomicCode(env, atomic_code, output) + + +def IsSingleLineComment(cur_line): + return '//' in cur_line + + +def IsInPreprocessorDirective(prev_lines, cur_line): + if cur_line.lstrip().startswith('#'): + return True + return prev_lines and prev_lines[-1].endswith('\\') + + +def WrapComment(line, output): + loc = line.find('//') + before_comment = line[:loc].rstrip() + if before_comment == '': + indent = loc + else: + output.append(before_comment) + indent = len(before_comment) - len(before_comment.lstrip()) + prefix = indent*' ' + '// ' + max_len = 80 - len(prefix) + comment = line[loc + 2:].strip() + segs = [seg for seg in re.split(r'(\w+\W*)', comment) if seg != ''] + cur_line = '' + for seg in segs: + if len((cur_line + seg).rstrip()) < max_len: + cur_line += seg + else: + if cur_line.strip() != '': + output.append(prefix + cur_line.rstrip()) + cur_line = seg.lstrip() + if cur_line.strip() != '': + output.append(prefix + cur_line.strip()) + + +def WrapCode(line, line_concat, output): + indent = len(line) - len(line.lstrip()) + prefix = indent*' ' # Prefix of the current line + max_len = 80 - indent - len(line_concat) # Maximum length of the current line + new_prefix = prefix + 4*' ' # Prefix of a continuation line + new_max_len = max_len - 4 # Maximum length of a continuation line + # Prefers to wrap a line after a ',' or ';'. + segs = [seg for seg in re.split(r'([^,;]+[,;]?)', line.strip()) if seg != ''] + cur_line = '' # The current line without leading spaces. + for seg in segs: + # If the line is still too long, wrap at a space. + while cur_line == '' and len(seg.strip()) > max_len: + seg = seg.lstrip() + split_at = seg.rfind(' ', 0, max_len) + output.append(prefix + seg[:split_at].strip() + line_concat) + seg = seg[split_at + 1:] + prefix = new_prefix + max_len = new_max_len + + if len((cur_line + seg).rstrip()) < max_len: + cur_line = (cur_line + seg).lstrip() + else: + output.append(prefix + cur_line.rstrip() + line_concat) + prefix = new_prefix + max_len = new_max_len + cur_line = seg.lstrip() + if cur_line.strip() != '': + output.append(prefix + cur_line.strip()) + + +def WrapPreprocessorDirective(line, output): + WrapCode(line, ' \\', output) + + +def WrapPlainCode(line, output): + WrapCode(line, '', output) + + +def IsMultiLineIWYUPragma(line): + return re.search(r'/\* IWYU pragma: ', line) + + +def IsHeaderGuardIncludeOrOneLineIWYUPragma(line): + return (re.match(r'^#(ifndef|define|endif\s*//)\s*[\w_]+\s*$', line) or + re.match(r'^#include\s', line) or + # Don't break IWYU pragmas, either; that causes iwyu.py problems. + re.search(r'// IWYU pragma: ', line)) + + +def WrapLongLine(line, output): + line = line.rstrip() + if len(line) <= 80: + output.append(line) + elif IsSingleLineComment(line): + if IsHeaderGuardIncludeOrOneLineIWYUPragma(line): + # The style guide made an exception to allow long header guard lines, + # includes and IWYU pragmas. + output.append(line) + else: + WrapComment(line, output) + elif IsInPreprocessorDirective(output, line): + if IsHeaderGuardIncludeOrOneLineIWYUPragma(line): + # The style guide made an exception to allow long header guard lines, + # includes and IWYU pragmas. + output.append(line) + else: + WrapPreprocessorDirective(line, output) + elif IsMultiLineIWYUPragma(line): + output.append(line) + else: + WrapPlainCode(line, output) + + +def BeautifyCode(string): + lines = string.splitlines() + output = [] + for line in lines: + WrapLongLine(line, output) + output2 = [line.rstrip() for line in output] + return '\n'.join(output2) + '\n' + + +def ConvertFromPumpSource(src_text): + """Return the text generated from the given Pump source text.""" + ast = ParseToAST(StripMetaComments(src_text)) + output = Output() + RunCode(Env(), ast, output) + return BeautifyCode(output.string) + + +def main(argv): + if len(argv) == 1: + print(__doc__) + sys.exit(1) + + file_path = argv[-1] + output_str = ConvertFromPumpSource(io.open(file_path, 'r').read()) + if file_path.endswith('.pump'): + output_file_path = file_path[:-5] + else: + output_file_path = '-' + if output_file_path == '-': + print(output_str,) + else: + output_file = io.open(output_file_path, 'w') + output_file.write(u'// This file was GENERATED by command:\n') + output_file.write(u'// %s %s\n' % + (os.path.basename(__file__), os.path.basename(file_path))) + output_file.write(u'// DO NOT EDIT BY HAND!!!\n\n') + output_file.write(output_str) + output_file.close() + + +if __name__ == '__main__': + main(sys.argv) diff --git a/src/googletest/googlemock/src/gmock-all.cc b/src/googletest/googlemock/src/gmock-all.cc new file mode 100644 index 000000000..e43c9b7b4 --- /dev/null +++ b/src/googletest/googlemock/src/gmock-all.cc @@ -0,0 +1,46 @@ +// 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 C++ Mocking Framework (Google Mock) +// +// This file #includes all Google Mock implementation .cc files. The +// purpose is to allow a user to build Google Mock by compiling this +// file alone. + +// This line ensures that gmock.h can be compiled on its own, even +// when it's fused. +#include "gmock/gmock.h" + +// The following lines pull in the real gmock *.cc files. +#include "src/gmock-cardinalities.cc" +#include "src/gmock-internal-utils.cc" +#include "src/gmock-matchers.cc" +#include "src/gmock-spec-builders.cc" +#include "src/gmock.cc" diff --git a/src/googletest/googlemock/src/gmock-cardinalities.cc b/src/googletest/googlemock/src/gmock-cardinalities.cc new file mode 100644 index 000000000..7463f4383 --- /dev/null +++ b/src/googletest/googlemock/src/gmock-cardinalities.cc @@ -0,0 +1,155 @@ +// 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. + + +// Google Mock - a framework for writing C++ mock classes. +// +// This file implements cardinalities. + +#include "gmock/gmock-cardinalities.h" + +#include <limits.h> +#include <ostream> // NOLINT +#include <sstream> +#include <string> +#include "gmock/internal/gmock-internal-utils.h" +#include "gtest/gtest.h" + +namespace testing { + +namespace { + +// Implements the Between(m, n) cardinality. +class BetweenCardinalityImpl : public CardinalityInterface { + public: + BetweenCardinalityImpl(int min, int max) + : min_(min >= 0 ? min : 0), + max_(max >= min_ ? max : min_) { + std::stringstream ss; + if (min < 0) { + ss << "The invocation lower bound must be >= 0, " + << "but is actually " << min << "."; + internal::Expect(false, __FILE__, __LINE__, ss.str()); + } else if (max < 0) { + ss << "The invocation upper bound must be >= 0, " + << "but is actually " << max << "."; + internal::Expect(false, __FILE__, __LINE__, ss.str()); + } else if (min > max) { + ss << "The invocation upper bound (" << max + << ") must be >= the invocation lower bound (" << min + << ")."; + internal::Expect(false, __FILE__, __LINE__, ss.str()); + } + } + + // Conservative estimate on the lower/upper bound of the number of + // calls allowed. + int ConservativeLowerBound() const override { return min_; } + int ConservativeUpperBound() const override { return max_; } + + bool IsSatisfiedByCallCount(int call_count) const override { + return min_ <= call_count && call_count <= max_; + } + + bool IsSaturatedByCallCount(int call_count) const override { + return call_count >= max_; + } + + void DescribeTo(::std::ostream* os) const override; + + private: + const int min_; + const int max_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(BetweenCardinalityImpl); +}; + +// Formats "n times" in a human-friendly way. +inline std::string FormatTimes(int n) { + if (n == 1) { + return "once"; + } else if (n == 2) { + return "twice"; + } else { + std::stringstream ss; + ss << n << " times"; + return ss.str(); + } +} + +// Describes the Between(m, n) cardinality in human-friendly text. +void BetweenCardinalityImpl::DescribeTo(::std::ostream* os) const { + if (min_ == 0) { + if (max_ == 0) { + *os << "never called"; + } else if (max_ == INT_MAX) { + *os << "called any number of times"; + } else { + *os << "called at most " << FormatTimes(max_); + } + } else if (min_ == max_) { + *os << "called " << FormatTimes(min_); + } else if (max_ == INT_MAX) { + *os << "called at least " << FormatTimes(min_); + } else { + // 0 < min_ < max_ < INT_MAX + *os << "called between " << min_ << " and " << max_ << " times"; + } +} + +} // Unnamed namespace + +// Describes the given call count to an ostream. +void Cardinality::DescribeActualCallCountTo(int actual_call_count, + ::std::ostream* os) { + if (actual_call_count > 0) { + *os << "called " << FormatTimes(actual_call_count); + } else { + *os << "never called"; + } +} + +// Creates a cardinality that allows at least n calls. +GTEST_API_ Cardinality AtLeast(int n) { return Between(n, INT_MAX); } + +// Creates a cardinality that allows at most n calls. +GTEST_API_ Cardinality AtMost(int n) { return Between(0, n); } + +// Creates a cardinality that allows any number of calls. +GTEST_API_ Cardinality AnyNumber() { return AtLeast(0); } + +// Creates a cardinality that allows between min and max calls. +GTEST_API_ Cardinality Between(int min, int max) { + return Cardinality(new BetweenCardinalityImpl(min, max)); +} + +// Creates a cardinality that allows exactly n calls. +GTEST_API_ Cardinality Exactly(int n) { return Between(n, n); } + +} // namespace testing diff --git a/src/googletest/googlemock/src/gmock-internal-utils.cc b/src/googletest/googlemock/src/gmock-internal-utils.cc new file mode 100644 index 000000000..e5b547981 --- /dev/null +++ b/src/googletest/googlemock/src/gmock-internal-utils.cc @@ -0,0 +1,200 @@ +// 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. + + +// Google Mock - a framework for writing C++ mock classes. +// +// This file defines some utilities useful for implementing Google +// Mock. They are subject to change without notice, so please DO NOT +// USE THEM IN USER CODE. + +#include "gmock/internal/gmock-internal-utils.h" + +#include <ctype.h> +#include <ostream> // NOLINT +#include <string> +#include "gmock/gmock.h" +#include "gmock/internal/gmock-port.h" +#include "gtest/gtest.h" + +namespace testing { +namespace internal { + +// Joins a vector of strings as if they are fields of a tuple; returns +// the joined string. +GTEST_API_ std::string JoinAsTuple(const Strings& fields) { + switch (fields.size()) { + case 0: + return ""; + case 1: + return fields[0]; + default: + std::string result = "(" + fields[0]; + for (size_t i = 1; i < fields.size(); i++) { + result += ", "; + result += fields[i]; + } + result += ")"; + return result; + } +} + +// Converts an identifier name to a space-separated list of lower-case +// words. Each maximum substring of the form [A-Za-z][a-z]*|\d+ is +// treated as one word. For example, both "FooBar123" and +// "foo_bar_123" are converted to "foo bar 123". +GTEST_API_ std::string ConvertIdentifierNameToWords(const char* id_name) { + std::string result; + char prev_char = '\0'; + for (const char* p = id_name; *p != '\0'; prev_char = *(p++)) { + // We don't care about the current locale as the input is + // guaranteed to be a valid C++ identifier name. + const bool starts_new_word = IsUpper(*p) || + (!IsAlpha(prev_char) && IsLower(*p)) || + (!IsDigit(prev_char) && IsDigit(*p)); + + if (IsAlNum(*p)) { + if (starts_new_word && result != "") + result += ' '; + result += ToLower(*p); + } + } + return result; +} + +// This class reports Google Mock failures as Google Test failures. A +// user can define another class in a similar fashion if they intend to +// use Google Mock with a testing framework other than Google Test. +class GoogleTestFailureReporter : public FailureReporterInterface { + public: + void ReportFailure(FailureType type, const char* file, int line, + const std::string& message) override { + AssertHelper(type == kFatal ? + TestPartResult::kFatalFailure : + TestPartResult::kNonFatalFailure, + file, + line, + message.c_str()) = Message(); + if (type == kFatal) { + posix::Abort(); + } + } +}; + +// Returns the global failure reporter. Will create a +// GoogleTestFailureReporter and return it the first time called. +GTEST_API_ FailureReporterInterface* GetFailureReporter() { + // Points to the global failure reporter used by Google Mock. gcc + // guarantees that the following use of failure_reporter is + // thread-safe. We may need to add additional synchronization to + // protect failure_reporter if we port Google Mock to other + // compilers. + static FailureReporterInterface* const failure_reporter = + new GoogleTestFailureReporter(); + return failure_reporter; +} + +// Protects global resources (stdout in particular) used by Log(). +static GTEST_DEFINE_STATIC_MUTEX_(g_log_mutex); + +// Returns true if and only if a log with the given severity is visible +// according to the --gmock_verbose flag. +GTEST_API_ bool LogIsVisible(LogSeverity severity) { + if (GMOCK_FLAG(verbose) == kInfoVerbosity) { + // Always show the log if --gmock_verbose=info. + return true; + } else if (GMOCK_FLAG(verbose) == kErrorVerbosity) { + // Always hide it if --gmock_verbose=error. + return false; + } else { + // If --gmock_verbose is neither "info" nor "error", we treat it + // as "warning" (its default value). + return severity == kWarning; + } +} + +// Prints the given message to stdout if and only if 'severity' >= the level +// specified by the --gmock_verbose flag. If stack_frames_to_skip >= +// 0, also prints the stack trace excluding the top +// stack_frames_to_skip frames. In opt mode, any positive +// stack_frames_to_skip is treated as 0, since we don't know which +// function calls will be inlined by the compiler and need to be +// conservative. +GTEST_API_ void Log(LogSeverity severity, const std::string& message, + int stack_frames_to_skip) { + if (!LogIsVisible(severity)) + return; + + // Ensures that logs from different threads don't interleave. + MutexLock l(&g_log_mutex); + + if (severity == kWarning) { + // Prints a GMOCK WARNING marker to make the warnings easily searchable. + std::cout << "\nGMOCK WARNING:"; + } + // Pre-pends a new-line to message if it doesn't start with one. + if (message.empty() || message[0] != '\n') { + std::cout << "\n"; + } + std::cout << message; + if (stack_frames_to_skip >= 0) { +#ifdef NDEBUG + // In opt mode, we have to be conservative and skip no stack frame. + const int actual_to_skip = 0; +#else + // In dbg mode, we can do what the caller tell us to do (plus one + // for skipping this function's stack frame). + const int actual_to_skip = stack_frames_to_skip + 1; +#endif // NDEBUG + + // Appends a new-line to message if it doesn't end with one. + if (!message.empty() && *message.rbegin() != '\n') { + std::cout << "\n"; + } + std::cout << "Stack trace:\n" + << ::testing::internal::GetCurrentOsStackTraceExceptTop( + ::testing::UnitTest::GetInstance(), actual_to_skip); + } + std::cout << ::std::flush; +} + +GTEST_API_ WithoutMatchers GetWithoutMatchers() { return WithoutMatchers(); } + +GTEST_API_ void IllegalDoDefault(const char* file, int line) { + internal::Assert( + false, file, line, + "You are using DoDefault() inside a composite action like " + "DoAll() or WithArgs(). This is not supported for technical " + "reasons. Please instead spell out the default action, or " + "assign the default action to an Action variable and use " + "the variable in various places."); +} + +} // namespace internal +} // namespace testing diff --git a/src/googletest/googlemock/src/gmock-matchers.cc b/src/googletest/googlemock/src/gmock-matchers.cc new file mode 100644 index 000000000..dded437ad --- /dev/null +++ b/src/googletest/googlemock/src/gmock-matchers.cc @@ -0,0 +1,459 @@ +// 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. + + +// Google Mock - a framework for writing C++ mock classes. +// +// This file implements Matcher<const string&>, Matcher<string>, and +// utilities for defining matchers. + +#include "gmock/gmock-matchers.h" + +#include <string.h> +#include <iostream> +#include <sstream> +#include <string> + +namespace testing { +namespace internal { + +// Returns the description for a matcher defined using the MATCHER*() +// macro where the user-supplied description string is "", if +// 'negation' is false; otherwise returns the description of the +// negation of the matcher. 'param_values' contains a list of strings +// that are the print-out of the matcher's parameters. +GTEST_API_ std::string FormatMatcherDescription(bool negation, + const char* matcher_name, + const Strings& param_values) { + std::string result = ConvertIdentifierNameToWords(matcher_name); + if (param_values.size() >= 1) result += " " + JoinAsTuple(param_values); + return negation ? "not (" + result + ")" : result; +} + +// FindMaxBipartiteMatching and its helper class. +// +// Uses the well-known Ford-Fulkerson max flow method to find a maximum +// bipartite matching. Flow is considered to be from left to right. +// There is an implicit source node that is connected to all of the left +// nodes, and an implicit sink node that is connected to all of the +// right nodes. All edges have unit capacity. +// +// Neither the flow graph nor the residual flow graph are represented +// explicitly. Instead, they are implied by the information in 'graph' and +// a vector<int> called 'left_' whose elements are initialized to the +// value kUnused. This represents the initial state of the algorithm, +// where the flow graph is empty, and the residual flow graph has the +// following edges: +// - An edge from source to each left_ node +// - An edge from each right_ node to sink +// - An edge from each left_ node to each right_ node, if the +// corresponding edge exists in 'graph'. +// +// When the TryAugment() method adds a flow, it sets left_[l] = r for some +// nodes l and r. This induces the following changes: +// - The edges (source, l), (l, r), and (r, sink) are added to the +// flow graph. +// - The same three edges are removed from the residual flow graph. +// - The reverse edges (l, source), (r, l), and (sink, r) are added +// to the residual flow graph, which is a directional graph +// representing unused flow capacity. +// +// When the method augments a flow (moving left_[l] from some r1 to some +// other r2), this can be thought of as "undoing" the above steps with +// respect to r1 and "redoing" them with respect to r2. +// +// It bears repeating that the flow graph and residual flow graph are +// never represented explicitly, but can be derived by looking at the +// information in 'graph' and in left_. +// +// As an optimization, there is a second vector<int> called right_ which +// does not provide any new information. Instead, it enables more +// efficient queries about edges entering or leaving the right-side nodes +// of the flow or residual flow graphs. The following invariants are +// maintained: +// +// left[l] == kUnused or right[left[l]] == l +// right[r] == kUnused or left[right[r]] == r +// +// . [ source ] . +// . ||| . +// . ||| . +// . ||\--> left[0]=1 ---\ right[0]=-1 ----\ . +// . || | | . +// . |\---> left[1]=-1 \--> right[1]=0 ---\| . +// . | || . +// . \----> left[2]=2 ------> right[2]=2 --\|| . +// . ||| . +// . elements matchers vvv . +// . [ sink ] . +// +// See Also: +// [1] Cormen, et al (2001). "Section 26.2: The Ford-Fulkerson method". +// "Introduction to Algorithms (Second ed.)", pp. 651-664. +// [2] "Ford-Fulkerson algorithm", Wikipedia, +// 'http://en.wikipedia.org/wiki/Ford%E2%80%93Fulkerson_algorithm' +class MaxBipartiteMatchState { + public: + explicit MaxBipartiteMatchState(const MatchMatrix& graph) + : graph_(&graph), + left_(graph_->LhsSize(), kUnused), + right_(graph_->RhsSize(), kUnused) {} + + // Returns the edges of a maximal match, each in the form {left, right}. + ElementMatcherPairs Compute() { + // 'seen' is used for path finding { 0: unseen, 1: seen }. + ::std::vector<char> seen; + // Searches the residual flow graph for a path from each left node to + // the sink in the residual flow graph, and if one is found, add flow + // to the graph. It's okay to search through the left nodes once. The + // edge from the implicit source node to each previously-visited left + // node will have flow if that left node has any path to the sink + // whatsoever. Subsequent augmentations can only add flow to the + // network, and cannot take away that previous flow unit from the source. + // Since the source-to-left edge can only carry one flow unit (or, + // each element can be matched to only one matcher), there is no need + // to visit the left nodes more than once looking for augmented paths. + // The flow is known to be possible or impossible by looking at the + // node once. + for (size_t ilhs = 0; ilhs < graph_->LhsSize(); ++ilhs) { + // Reset the path-marking vector and try to find a path from + // source to sink starting at the left_[ilhs] node. + GTEST_CHECK_(left_[ilhs] == kUnused) + << "ilhs: " << ilhs << ", left_[ilhs]: " << left_[ilhs]; + // 'seen' initialized to 'graph_->RhsSize()' copies of 0. + seen.assign(graph_->RhsSize(), 0); + TryAugment(ilhs, &seen); + } + ElementMatcherPairs result; + for (size_t ilhs = 0; ilhs < left_.size(); ++ilhs) { + size_t irhs = left_[ilhs]; + if (irhs == kUnused) continue; + result.push_back(ElementMatcherPair(ilhs, irhs)); + } + return result; + } + + private: + static const size_t kUnused = static_cast<size_t>(-1); + + // Perform a depth-first search from left node ilhs to the sink. If a + // path is found, flow is added to the network by linking the left and + // right vector elements corresponding each segment of the path. + // Returns true if a path to sink was found, which means that a unit of + // flow was added to the network. The 'seen' vector elements correspond + // to right nodes and are marked to eliminate cycles from the search. + // + // Left nodes will only be explored at most once because they + // are accessible from at most one right node in the residual flow + // graph. + // + // Note that left_[ilhs] is the only element of left_ that TryAugment will + // potentially transition from kUnused to another value. Any other + // left_ element holding kUnused before TryAugment will be holding it + // when TryAugment returns. + // + bool TryAugment(size_t ilhs, ::std::vector<char>* seen) { + for (size_t irhs = 0; irhs < graph_->RhsSize(); ++irhs) { + if ((*seen)[irhs]) continue; + if (!graph_->HasEdge(ilhs, irhs)) continue; + // There's an available edge from ilhs to irhs. + (*seen)[irhs] = 1; + // Next a search is performed to determine whether + // this edge is a dead end or leads to the sink. + // + // right_[irhs] == kUnused means that there is residual flow from + // right node irhs to the sink, so we can use that to finish this + // flow path and return success. + // + // Otherwise there is residual flow to some ilhs. We push flow + // along that path and call ourselves recursively to see if this + // ultimately leads to sink. + if (right_[irhs] == kUnused || TryAugment(right_[irhs], seen)) { + // Add flow from left_[ilhs] to right_[irhs]. + left_[ilhs] = irhs; + right_[irhs] = ilhs; + return true; + } + } + return false; + } + + const MatchMatrix* graph_; // not owned + // Each element of the left_ vector represents a left hand side node + // (i.e. an element) and each element of right_ is a right hand side + // node (i.e. a matcher). The values in the left_ vector indicate + // outflow from that node to a node on the right_ side. The values + // in the right_ indicate inflow, and specify which left_ node is + // feeding that right_ node, if any. For example, left_[3] == 1 means + // there's a flow from element #3 to matcher #1. Such a flow would also + // be redundantly represented in the right_ vector as right_[1] == 3. + // Elements of left_ and right_ are either kUnused or mutually + // referent. Mutually referent means that left_[right_[i]] = i and + // right_[left_[i]] = i. + ::std::vector<size_t> left_; + ::std::vector<size_t> right_; +}; + +const size_t MaxBipartiteMatchState::kUnused; + +GTEST_API_ ElementMatcherPairs FindMaxBipartiteMatching(const MatchMatrix& g) { + return MaxBipartiteMatchState(g).Compute(); +} + +static void LogElementMatcherPairVec(const ElementMatcherPairs& pairs, + ::std::ostream* stream) { + typedef ElementMatcherPairs::const_iterator Iter; + ::std::ostream& os = *stream; + os << "{"; + const char* sep = ""; + for (Iter it = pairs.begin(); it != pairs.end(); ++it) { + os << sep << "\n (" + << "element #" << it->first << ", " + << "matcher #" << it->second << ")"; + sep = ","; + } + os << "\n}"; +} + +bool MatchMatrix::NextGraph() { + for (size_t ilhs = 0; ilhs < LhsSize(); ++ilhs) { + for (size_t irhs = 0; irhs < RhsSize(); ++irhs) { + char& b = matched_[SpaceIndex(ilhs, irhs)]; + if (!b) { + b = 1; + return true; + } + b = 0; + } + } + return false; +} + +void MatchMatrix::Randomize() { + for (size_t ilhs = 0; ilhs < LhsSize(); ++ilhs) { + for (size_t irhs = 0; irhs < RhsSize(); ++irhs) { + char& b = matched_[SpaceIndex(ilhs, irhs)]; + b = static_cast<char>(rand() & 1); // NOLINT + } + } +} + +std::string MatchMatrix::DebugString() const { + ::std::stringstream ss; + const char* sep = ""; + for (size_t i = 0; i < LhsSize(); ++i) { + ss << sep; + for (size_t j = 0; j < RhsSize(); ++j) { + ss << HasEdge(i, j); + } + sep = ";"; + } + return ss.str(); +} + +void UnorderedElementsAreMatcherImplBase::DescribeToImpl( + ::std::ostream* os) const { + switch (match_flags()) { + case UnorderedMatcherRequire::ExactMatch: + if (matcher_describers_.empty()) { + *os << "is empty"; + return; + } + if (matcher_describers_.size() == 1) { + *os << "has " << Elements(1) << " and that element "; + matcher_describers_[0]->DescribeTo(os); + return; + } + *os << "has " << Elements(matcher_describers_.size()) + << " and there exists some permutation of elements such that:\n"; + break; + case UnorderedMatcherRequire::Superset: + *os << "a surjection from elements to requirements exists such that:\n"; + break; + case UnorderedMatcherRequire::Subset: + *os << "an injection from elements to requirements exists such that:\n"; + break; + } + + const char* sep = ""; + for (size_t i = 0; i != matcher_describers_.size(); ++i) { + *os << sep; + if (match_flags() == UnorderedMatcherRequire::ExactMatch) { + *os << " - element #" << i << " "; + } else { + *os << " - an element "; + } + matcher_describers_[i]->DescribeTo(os); + if (match_flags() == UnorderedMatcherRequire::ExactMatch) { + sep = ", and\n"; + } else { + sep = "\n"; + } + } +} + +void UnorderedElementsAreMatcherImplBase::DescribeNegationToImpl( + ::std::ostream* os) const { + switch (match_flags()) { + case UnorderedMatcherRequire::ExactMatch: + if (matcher_describers_.empty()) { + *os << "isn't empty"; + return; + } + if (matcher_describers_.size() == 1) { + *os << "doesn't have " << Elements(1) << ", or has " << Elements(1) + << " that "; + matcher_describers_[0]->DescribeNegationTo(os); + return; + } + *os << "doesn't have " << Elements(matcher_describers_.size()) + << ", or there exists no permutation of elements such that:\n"; + break; + case UnorderedMatcherRequire::Superset: + *os << "no surjection from elements to requirements exists such that:\n"; + break; + case UnorderedMatcherRequire::Subset: + *os << "no injection from elements to requirements exists such that:\n"; + break; + } + const char* sep = ""; + for (size_t i = 0; i != matcher_describers_.size(); ++i) { + *os << sep; + if (match_flags() == UnorderedMatcherRequire::ExactMatch) { + *os << " - element #" << i << " "; + } else { + *os << " - an element "; + } + matcher_describers_[i]->DescribeTo(os); + if (match_flags() == UnorderedMatcherRequire::ExactMatch) { + sep = ", and\n"; + } else { + sep = "\n"; + } + } +} + +// Checks that all matchers match at least one element, and that all +// elements match at least one matcher. This enables faster matching +// and better error reporting. +// Returns false, writing an explanation to 'listener', if and only +// if the success criteria are not met. +bool UnorderedElementsAreMatcherImplBase::VerifyMatchMatrix( + const ::std::vector<std::string>& element_printouts, + const MatchMatrix& matrix, MatchResultListener* listener) const { + bool result = true; + ::std::vector<char> element_matched(matrix.LhsSize(), 0); + ::std::vector<char> matcher_matched(matrix.RhsSize(), 0); + + for (size_t ilhs = 0; ilhs < matrix.LhsSize(); ilhs++) { + for (size_t irhs = 0; irhs < matrix.RhsSize(); irhs++) { + char matched = matrix.HasEdge(ilhs, irhs); + element_matched[ilhs] |= matched; + matcher_matched[irhs] |= matched; + } + } + + if (match_flags() & UnorderedMatcherRequire::Superset) { + const char* sep = + "where the following matchers don't match any elements:\n"; + for (size_t mi = 0; mi < matcher_matched.size(); ++mi) { + if (matcher_matched[mi]) continue; + result = false; + if (listener->IsInterested()) { + *listener << sep << "matcher #" << mi << ": "; + matcher_describers_[mi]->DescribeTo(listener->stream()); + sep = ",\n"; + } + } + } + + if (match_flags() & UnorderedMatcherRequire::Subset) { + const char* sep = + "where the following elements don't match any matchers:\n"; + const char* outer_sep = ""; + if (!result) { + outer_sep = "\nand "; + } + for (size_t ei = 0; ei < element_matched.size(); ++ei) { + if (element_matched[ei]) continue; + result = false; + if (listener->IsInterested()) { + *listener << outer_sep << sep << "element #" << ei << ": " + << element_printouts[ei]; + sep = ",\n"; + outer_sep = ""; + } + } + } + return result; +} + +bool UnorderedElementsAreMatcherImplBase::FindPairing( + const MatchMatrix& matrix, MatchResultListener* listener) const { + ElementMatcherPairs matches = FindMaxBipartiteMatching(matrix); + + size_t max_flow = matches.size(); + if ((match_flags() & UnorderedMatcherRequire::Superset) && + max_flow < matrix.RhsSize()) { + if (listener->IsInterested()) { + *listener << "where no permutation of the elements can satisfy all " + "matchers, and the closest match is " + << max_flow << " of " << matrix.RhsSize() + << " matchers with the pairings:\n"; + LogElementMatcherPairVec(matches, listener->stream()); + } + return false; + } + if ((match_flags() & UnorderedMatcherRequire::Subset) && + max_flow < matrix.LhsSize()) { + if (listener->IsInterested()) { + *listener + << "where not all elements can be matched, and the closest match is " + << max_flow << " of " << matrix.RhsSize() + << " matchers with the pairings:\n"; + LogElementMatcherPairVec(matches, listener->stream()); + } + return false; + } + + if (matches.size() > 1) { + if (listener->IsInterested()) { + const char* sep = "where:\n"; + for (size_t mi = 0; mi < matches.size(); ++mi) { + *listener << sep << " - element #" << matches[mi].first + << " is matched by matcher #" << matches[mi].second; + sep = ",\n"; + } + } + } + return true; +} + +} // namespace internal +} // namespace testing diff --git a/src/googletest/googlemock/src/gmock-spec-builders.cc b/src/googletest/googlemock/src/gmock-spec-builders.cc new file mode 100644 index 000000000..05a50f67c --- /dev/null +++ b/src/googletest/googlemock/src/gmock-spec-builders.cc @@ -0,0 +1,908 @@ +// 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. + + +// Google Mock - a framework for writing C++ mock classes. +// +// This file implements the spec builder syntax (ON_CALL and +// EXPECT_CALL). + +#include "gmock/gmock-spec-builders.h" + +#include <stdlib.h> + +#include <iostream> // NOLINT +#include <map> +#include <memory> +#include <set> +#include <string> +#include <vector> + +#include "gmock/gmock.h" +#include "gtest/gtest.h" +#include "gtest/internal/gtest-port.h" + +#if GTEST_OS_CYGWIN || GTEST_OS_LINUX || GTEST_OS_MAC +# include <unistd.h> // NOLINT +#endif + +// Silence C4800 (C4800: 'int *const ': forcing value +// to bool 'true' or 'false') for MSVC 15 +#ifdef _MSC_VER +#if _MSC_VER == 1900 +# pragma warning(push) +# pragma warning(disable:4800) +#endif +#endif + +namespace testing { +namespace internal { + +// Protects the mock object registry (in class Mock), all function +// mockers, and all expectations. +GTEST_API_ GTEST_DEFINE_STATIC_MUTEX_(g_gmock_mutex); + +// Logs a message including file and line number information. +GTEST_API_ void LogWithLocation(testing::internal::LogSeverity severity, + const char* file, int line, + const std::string& message) { + ::std::ostringstream s; + s << internal::FormatFileLocation(file, line) << " " << message + << ::std::endl; + Log(severity, s.str(), 0); +} + +// Constructs an ExpectationBase object. +ExpectationBase::ExpectationBase(const char* a_file, int a_line, + const std::string& a_source_text) + : file_(a_file), + line_(a_line), + source_text_(a_source_text), + cardinality_specified_(false), + cardinality_(Exactly(1)), + call_count_(0), + retired_(false), + extra_matcher_specified_(false), + repeated_action_specified_(false), + retires_on_saturation_(false), + last_clause_(kNone), + action_count_checked_(false) {} + +// Destructs an ExpectationBase object. +ExpectationBase::~ExpectationBase() {} + +// Explicitly specifies the cardinality of this expectation. Used by +// the subclasses to implement the .Times() clause. +void ExpectationBase::SpecifyCardinality(const Cardinality& a_cardinality) { + cardinality_specified_ = true; + cardinality_ = a_cardinality; +} + +// Retires all pre-requisites of this expectation. +void ExpectationBase::RetireAllPreRequisites() + GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) { + if (is_retired()) { + // We can take this short-cut as we never retire an expectation + // until we have retired all its pre-requisites. + return; + } + + ::std::vector<ExpectationBase*> expectations(1, this); + while (!expectations.empty()) { + ExpectationBase* exp = expectations.back(); + expectations.pop_back(); + + for (ExpectationSet::const_iterator it = + exp->immediate_prerequisites_.begin(); + it != exp->immediate_prerequisites_.end(); ++it) { + ExpectationBase* next = it->expectation_base().get(); + if (!next->is_retired()) { + next->Retire(); + expectations.push_back(next); + } + } + } +} + +// Returns true if and only if all pre-requisites of this expectation +// have been satisfied. +bool ExpectationBase::AllPrerequisitesAreSatisfied() const + GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) { + g_gmock_mutex.AssertHeld(); + ::std::vector<const ExpectationBase*> expectations(1, this); + while (!expectations.empty()) { + const ExpectationBase* exp = expectations.back(); + expectations.pop_back(); + + for (ExpectationSet::const_iterator it = + exp->immediate_prerequisites_.begin(); + it != exp->immediate_prerequisites_.end(); ++it) { + const ExpectationBase* next = it->expectation_base().get(); + if (!next->IsSatisfied()) return false; + expectations.push_back(next); + } + } + return true; +} + +// Adds unsatisfied pre-requisites of this expectation to 'result'. +void ExpectationBase::FindUnsatisfiedPrerequisites(ExpectationSet* result) const + GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) { + g_gmock_mutex.AssertHeld(); + ::std::vector<const ExpectationBase*> expectations(1, this); + while (!expectations.empty()) { + const ExpectationBase* exp = expectations.back(); + expectations.pop_back(); + + for (ExpectationSet::const_iterator it = + exp->immediate_prerequisites_.begin(); + it != exp->immediate_prerequisites_.end(); ++it) { + const ExpectationBase* next = it->expectation_base().get(); + + if (next->IsSatisfied()) { + // If *it is satisfied and has a call count of 0, some of its + // pre-requisites may not be satisfied yet. + if (next->call_count_ == 0) { + expectations.push_back(next); + } + } else { + // Now that we know next is unsatisfied, we are not so interested + // in whether its pre-requisites are satisfied. Therefore we + // don't iterate into it here. + *result += *it; + } + } + } +} + +// Describes how many times a function call matching this +// expectation has occurred. +void ExpectationBase::DescribeCallCountTo(::std::ostream* os) const + GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) { + g_gmock_mutex.AssertHeld(); + + // Describes how many times the function is expected to be called. + *os << " Expected: to be "; + cardinality().DescribeTo(os); + *os << "\n Actual: "; + Cardinality::DescribeActualCallCountTo(call_count(), os); + + // Describes the state of the expectation (e.g. is it satisfied? + // is it active?). + *os << " - " << (IsOverSaturated() ? "over-saturated" : + IsSaturated() ? "saturated" : + IsSatisfied() ? "satisfied" : "unsatisfied") + << " and " + << (is_retired() ? "retired" : "active"); +} + +// Checks the action count (i.e. the number of WillOnce() and +// WillRepeatedly() clauses) against the cardinality if this hasn't +// been done before. Prints a warning if there are too many or too +// few actions. +void ExpectationBase::CheckActionCountIfNotDone() const + GTEST_LOCK_EXCLUDED_(mutex_) { + bool should_check = false; + { + MutexLock l(&mutex_); + if (!action_count_checked_) { + action_count_checked_ = true; + should_check = true; + } + } + + if (should_check) { + if (!cardinality_specified_) { + // The cardinality was inferred - no need to check the action + // count against it. + return; + } + + // The cardinality was explicitly specified. + const int action_count = static_cast<int>(untyped_actions_.size()); + const int upper_bound = cardinality().ConservativeUpperBound(); + const int lower_bound = cardinality().ConservativeLowerBound(); + bool too_many; // True if there are too many actions, or false + // if there are too few. + if (action_count > upper_bound || + (action_count == upper_bound && repeated_action_specified_)) { + too_many = true; + } else if (0 < action_count && action_count < lower_bound && + !repeated_action_specified_) { + too_many = false; + } else { + return; + } + + ::std::stringstream ss; + DescribeLocationTo(&ss); + ss << "Too " << (too_many ? "many" : "few") + << " actions specified in " << source_text() << "...\n" + << "Expected to be "; + cardinality().DescribeTo(&ss); + ss << ", but has " << (too_many ? "" : "only ") + << action_count << " WillOnce()" + << (action_count == 1 ? "" : "s"); + if (repeated_action_specified_) { + ss << " and a WillRepeatedly()"; + } + ss << "."; + Log(kWarning, ss.str(), -1); // -1 means "don't print stack trace". + } +} + +// Implements the .Times() clause. +void ExpectationBase::UntypedTimes(const Cardinality& a_cardinality) { + if (last_clause_ == kTimes) { + ExpectSpecProperty(false, + ".Times() cannot appear " + "more than once in an EXPECT_CALL()."); + } else { + ExpectSpecProperty(last_clause_ < kTimes, + ".Times() cannot appear after " + ".InSequence(), .WillOnce(), .WillRepeatedly(), " + "or .RetiresOnSaturation()."); + } + last_clause_ = kTimes; + + SpecifyCardinality(a_cardinality); +} + +// Points to the implicit sequence introduced by a living InSequence +// object (if any) in the current thread or NULL. +GTEST_API_ ThreadLocal<Sequence*> g_gmock_implicit_sequence; + +// Reports an uninteresting call (whose description is in msg) in the +// manner specified by 'reaction'. +void ReportUninterestingCall(CallReaction reaction, const std::string& msg) { + // Include a stack trace only if --gmock_verbose=info is specified. + const int stack_frames_to_skip = + GMOCK_FLAG(verbose) == kInfoVerbosity ? 3 : -1; + switch (reaction) { + case kAllow: + Log(kInfo, msg, stack_frames_to_skip); + break; + case kWarn: + Log(kWarning, + msg + + "\nNOTE: You can safely ignore the above warning unless this " + "call should not happen. Do not suppress it by blindly adding " + "an EXPECT_CALL() if you don't mean to enforce the call. " + "See " + "https://github.com/google/googletest/blob/master/googlemock/" + "docs/cook_book.md#" + "knowing-when-to-expect for details.\n", + stack_frames_to_skip); + break; + default: // FAIL + Expect(false, nullptr, -1, msg); + } +} + +UntypedFunctionMockerBase::UntypedFunctionMockerBase() + : mock_obj_(nullptr), name_("") {} + +UntypedFunctionMockerBase::~UntypedFunctionMockerBase() {} + +// Sets the mock object this mock method belongs to, and registers +// this information in the global mock registry. Will be called +// whenever an EXPECT_CALL() or ON_CALL() is executed on this mock +// method. +void UntypedFunctionMockerBase::RegisterOwner(const void* mock_obj) + GTEST_LOCK_EXCLUDED_(g_gmock_mutex) { + { + MutexLock l(&g_gmock_mutex); + mock_obj_ = mock_obj; + } + Mock::Register(mock_obj, this); +} + +// Sets the mock object this mock method belongs to, and sets the name +// of the mock function. Will be called upon each invocation of this +// mock function. +void UntypedFunctionMockerBase::SetOwnerAndName(const void* mock_obj, + const char* name) + GTEST_LOCK_EXCLUDED_(g_gmock_mutex) { + // We protect name_ under g_gmock_mutex in case this mock function + // is called from two threads concurrently. + MutexLock l(&g_gmock_mutex); + mock_obj_ = mock_obj; + name_ = name; +} + +// Returns the name of the function being mocked. Must be called +// after RegisterOwner() or SetOwnerAndName() has been called. +const void* UntypedFunctionMockerBase::MockObject() const + GTEST_LOCK_EXCLUDED_(g_gmock_mutex) { + const void* mock_obj; + { + // We protect mock_obj_ under g_gmock_mutex in case this mock + // function is called from two threads concurrently. + MutexLock l(&g_gmock_mutex); + Assert(mock_obj_ != nullptr, __FILE__, __LINE__, + "MockObject() must not be called before RegisterOwner() or " + "SetOwnerAndName() has been called."); + mock_obj = mock_obj_; + } + return mock_obj; +} + +// Returns the name of this mock method. Must be called after +// SetOwnerAndName() has been called. +const char* UntypedFunctionMockerBase::Name() const + GTEST_LOCK_EXCLUDED_(g_gmock_mutex) { + const char* name; + { + // We protect name_ under g_gmock_mutex in case this mock + // function is called from two threads concurrently. + MutexLock l(&g_gmock_mutex); + Assert(name_ != nullptr, __FILE__, __LINE__, + "Name() must not be called before SetOwnerAndName() has " + "been called."); + name = name_; + } + return name; +} + +// Calculates the result of invoking this mock function with the given +// arguments, prints it, and returns it. The caller is responsible +// for deleting the result. +UntypedActionResultHolderBase* UntypedFunctionMockerBase::UntypedInvokeWith( + void* const untyped_args) GTEST_LOCK_EXCLUDED_(g_gmock_mutex) { + // See the definition of untyped_expectations_ for why access to it + // is unprotected here. + if (untyped_expectations_.size() == 0) { + // No expectation is set on this mock method - we have an + // uninteresting call. + + // We must get Google Mock's reaction on uninteresting calls + // made on this mock object BEFORE performing the action, + // because the action may DELETE the mock object and make the + // following expression meaningless. + const CallReaction reaction = + Mock::GetReactionOnUninterestingCalls(MockObject()); + + // True if and only if we need to print this call's arguments and return + // value. This definition must be kept in sync with + // the behavior of ReportUninterestingCall(). + const bool need_to_report_uninteresting_call = + // If the user allows this uninteresting call, we print it + // only when they want informational messages. + reaction == kAllow ? LogIsVisible(kInfo) : + // If the user wants this to be a warning, we print + // it only when they want to see warnings. + reaction == kWarn + ? LogIsVisible(kWarning) + : + // Otherwise, the user wants this to be an error, and we + // should always print detailed information in the error. + true; + + if (!need_to_report_uninteresting_call) { + // Perform the action without printing the call information. + return this->UntypedPerformDefaultAction( + untyped_args, "Function call: " + std::string(Name())); + } + + // Warns about the uninteresting call. + ::std::stringstream ss; + this->UntypedDescribeUninterestingCall(untyped_args, &ss); + + // Calculates the function result. + UntypedActionResultHolderBase* const result = + this->UntypedPerformDefaultAction(untyped_args, ss.str()); + + // Prints the function result. + if (result != nullptr) result->PrintAsActionResult(&ss); + + ReportUninterestingCall(reaction, ss.str()); + return result; + } + + bool is_excessive = false; + ::std::stringstream ss; + ::std::stringstream why; + ::std::stringstream loc; + const void* untyped_action = nullptr; + + // The UntypedFindMatchingExpectation() function acquires and + // releases g_gmock_mutex. + + const ExpectationBase* const untyped_expectation = + this->UntypedFindMatchingExpectation(untyped_args, &untyped_action, + &is_excessive, &ss, &why); + const bool found = untyped_expectation != nullptr; + + // True if and only if we need to print the call's arguments + // and return value. + // This definition must be kept in sync with the uses of Expect() + // and Log() in this function. + const bool need_to_report_call = + !found || is_excessive || LogIsVisible(kInfo); + if (!need_to_report_call) { + // Perform the action without printing the call information. + return untyped_action == nullptr + ? this->UntypedPerformDefaultAction(untyped_args, "") + : this->UntypedPerformAction(untyped_action, untyped_args); + } + + ss << " Function call: " << Name(); + this->UntypedPrintArgs(untyped_args, &ss); + + // In case the action deletes a piece of the expectation, we + // generate the message beforehand. + if (found && !is_excessive) { + untyped_expectation->DescribeLocationTo(&loc); + } + + UntypedActionResultHolderBase* result = nullptr; + + auto perform_action = [&] { + return untyped_action == nullptr + ? this->UntypedPerformDefaultAction(untyped_args, ss.str()) + : this->UntypedPerformAction(untyped_action, untyped_args); + }; + auto handle_failures = [&] { + ss << "\n" << why.str(); + + if (!found) { + // No expectation matches this call - reports a failure. + Expect(false, nullptr, -1, ss.str()); + } else if (is_excessive) { + // We had an upper-bound violation and the failure message is in ss. + Expect(false, untyped_expectation->file(), untyped_expectation->line(), + ss.str()); + } else { + // We had an expected call and the matching expectation is + // described in ss. + Log(kInfo, loc.str() + ss.str(), 2); + } + }; +#if GTEST_HAS_EXCEPTIONS + try { + result = perform_action(); + } catch (...) { + handle_failures(); + throw; + } +#else + result = perform_action(); +#endif + + if (result != nullptr) result->PrintAsActionResult(&ss); + handle_failures(); + return result; +} + +// Returns an Expectation object that references and co-owns exp, +// which must be an expectation on this mock function. +Expectation UntypedFunctionMockerBase::GetHandleOf(ExpectationBase* exp) { + // See the definition of untyped_expectations_ for why access to it + // is unprotected here. + for (UntypedExpectations::const_iterator it = + untyped_expectations_.begin(); + it != untyped_expectations_.end(); ++it) { + if (it->get() == exp) { + return Expectation(*it); + } + } + + Assert(false, __FILE__, __LINE__, "Cannot find expectation."); + return Expectation(); + // The above statement is just to make the code compile, and will + // never be executed. +} + +// Verifies that all expectations on this mock function have been +// satisfied. Reports one or more Google Test non-fatal failures +// and returns false if not. +bool UntypedFunctionMockerBase::VerifyAndClearExpectationsLocked() + GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) { + g_gmock_mutex.AssertHeld(); + bool expectations_met = true; + for (UntypedExpectations::const_iterator it = + untyped_expectations_.begin(); + it != untyped_expectations_.end(); ++it) { + ExpectationBase* const untyped_expectation = it->get(); + if (untyped_expectation->IsOverSaturated()) { + // There was an upper-bound violation. Since the error was + // already reported when it occurred, there is no need to do + // anything here. + expectations_met = false; + } else if (!untyped_expectation->IsSatisfied()) { + expectations_met = false; + ::std::stringstream ss; + ss << "Actual function call count doesn't match " + << untyped_expectation->source_text() << "...\n"; + // No need to show the source file location of the expectation + // in the description, as the Expect() call that follows already + // takes care of it. + untyped_expectation->MaybeDescribeExtraMatcherTo(&ss); + untyped_expectation->DescribeCallCountTo(&ss); + Expect(false, untyped_expectation->file(), + untyped_expectation->line(), ss.str()); + } + } + + // Deleting our expectations may trigger other mock objects to be deleted, for + // example if an action contains a reference counted smart pointer to that + // mock object, and that is the last reference. So if we delete our + // expectations within the context of the global mutex we may deadlock when + // this method is called again. Instead, make a copy of the set of + // expectations to delete, clear our set within the mutex, and then clear the + // copied set outside of it. + UntypedExpectations expectations_to_delete; + untyped_expectations_.swap(expectations_to_delete); + + g_gmock_mutex.Unlock(); + expectations_to_delete.clear(); + g_gmock_mutex.Lock(); + + return expectations_met; +} + +CallReaction intToCallReaction(int mock_behavior) { + if (mock_behavior >= kAllow && mock_behavior <= kFail) { + return static_cast<internal::CallReaction>(mock_behavior); + } + return kWarn; +} + +} // namespace internal + +// Class Mock. + +namespace { + +typedef std::set<internal::UntypedFunctionMockerBase*> FunctionMockers; + +// The current state of a mock object. Such information is needed for +// detecting leaked mock objects and explicitly verifying a mock's +// expectations. +struct MockObjectState { + MockObjectState() + : first_used_file(nullptr), first_used_line(-1), leakable(false) {} + + // Where in the source file an ON_CALL or EXPECT_CALL is first + // invoked on this mock object. + const char* first_used_file; + int first_used_line; + ::std::string first_used_test_suite; + ::std::string first_used_test; + bool leakable; // true if and only if it's OK to leak the object. + FunctionMockers function_mockers; // All registered methods of the object. +}; + +// A global registry holding the state of all mock objects that are +// alive. A mock object is added to this registry the first time +// Mock::AllowLeak(), ON_CALL(), or EXPECT_CALL() is called on it. It +// is removed from the registry in the mock object's destructor. +class MockObjectRegistry { + public: + // Maps a mock object (identified by its address) to its state. + typedef std::map<const void*, MockObjectState> StateMap; + + // This destructor will be called when a program exits, after all + // tests in it have been run. By then, there should be no mock + // object alive. Therefore we report any living object as test + // failure, unless the user explicitly asked us to ignore it. + ~MockObjectRegistry() { + if (!GMOCK_FLAG(catch_leaked_mocks)) + return; + + int leaked_count = 0; + for (StateMap::const_iterator it = states_.begin(); it != states_.end(); + ++it) { + if (it->second.leakable) // The user said it's fine to leak this object. + continue; + + // FIXME: Print the type of the leaked object. + // This can help the user identify the leaked object. + std::cout << "\n"; + const MockObjectState& state = it->second; + std::cout << internal::FormatFileLocation(state.first_used_file, + state.first_used_line); + std::cout << " ERROR: this mock object"; + if (state.first_used_test != "") { + std::cout << " (used in test " << state.first_used_test_suite << "." + << state.first_used_test << ")"; + } + std::cout << " should be deleted but never is. Its address is @" + << it->first << "."; + leaked_count++; + } + if (leaked_count > 0) { + std::cout << "\nERROR: " << leaked_count << " leaked mock " + << (leaked_count == 1 ? "object" : "objects") + << " found at program exit. Expectations on a mock object are " + "verified when the object is destructed. Leaking a mock " + "means that its expectations aren't verified, which is " + "usually a test bug. If you really intend to leak a mock, " + "you can suppress this error using " + "testing::Mock::AllowLeak(mock_object), or you may use a " + "fake or stub instead of a mock.\n"; + std::cout.flush(); + ::std::cerr.flush(); + // RUN_ALL_TESTS() has already returned when this destructor is + // called. Therefore we cannot use the normal Google Test + // failure reporting mechanism. + _exit(1); // We cannot call exit() as it is not reentrant and + // may already have been called. + } + } + + StateMap& states() { return states_; } + + private: + StateMap states_; +}; + +// Protected by g_gmock_mutex. +MockObjectRegistry g_mock_object_registry; + +// Maps a mock object to the reaction Google Mock should have when an +// uninteresting method is called. Protected by g_gmock_mutex. +std::map<const void*, internal::CallReaction> g_uninteresting_call_reaction; + +// Sets the reaction Google Mock should have when an uninteresting +// method of the given mock object is called. +void SetReactionOnUninterestingCalls(const void* mock_obj, + internal::CallReaction reaction) + GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) { + internal::MutexLock l(&internal::g_gmock_mutex); + g_uninteresting_call_reaction[mock_obj] = reaction; +} + +} // namespace + +// Tells Google Mock to allow uninteresting calls on the given mock +// object. +void Mock::AllowUninterestingCalls(const void* mock_obj) + GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) { + SetReactionOnUninterestingCalls(mock_obj, internal::kAllow); +} + +// Tells Google Mock to warn the user about uninteresting calls on the +// given mock object. +void Mock::WarnUninterestingCalls(const void* mock_obj) + GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) { + SetReactionOnUninterestingCalls(mock_obj, internal::kWarn); +} + +// Tells Google Mock to fail uninteresting calls on the given mock +// object. +void Mock::FailUninterestingCalls(const void* mock_obj) + GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) { + SetReactionOnUninterestingCalls(mock_obj, internal::kFail); +} + +// Tells Google Mock the given mock object is being destroyed and its +// entry in the call-reaction table should be removed. +void Mock::UnregisterCallReaction(const void* mock_obj) + GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) { + internal::MutexLock l(&internal::g_gmock_mutex); + g_uninteresting_call_reaction.erase(mock_obj); +} + +// Returns the reaction Google Mock will have on uninteresting calls +// made on the given mock object. +internal::CallReaction Mock::GetReactionOnUninterestingCalls( + const void* mock_obj) + GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) { + internal::MutexLock l(&internal::g_gmock_mutex); + return (g_uninteresting_call_reaction.count(mock_obj) == 0) ? + internal::intToCallReaction(GMOCK_FLAG(default_mock_behavior)) : + g_uninteresting_call_reaction[mock_obj]; +} + +// Tells Google Mock to ignore mock_obj when checking for leaked mock +// objects. +void Mock::AllowLeak(const void* mock_obj) + GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) { + internal::MutexLock l(&internal::g_gmock_mutex); + g_mock_object_registry.states()[mock_obj].leakable = true; +} + +// Verifies and clears all expectations on the given mock object. If +// the expectations aren't satisfied, generates one or more Google +// Test non-fatal failures and returns false. +bool Mock::VerifyAndClearExpectations(void* mock_obj) + GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) { + internal::MutexLock l(&internal::g_gmock_mutex); + return VerifyAndClearExpectationsLocked(mock_obj); +} + +// Verifies all expectations on the given mock object and clears its +// default actions and expectations. Returns true if and only if the +// verification was successful. +bool Mock::VerifyAndClear(void* mock_obj) + GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) { + internal::MutexLock l(&internal::g_gmock_mutex); + ClearDefaultActionsLocked(mock_obj); + return VerifyAndClearExpectationsLocked(mock_obj); +} + +// Verifies and clears all expectations on the given mock object. If +// the expectations aren't satisfied, generates one or more Google +// Test non-fatal failures and returns false. +bool Mock::VerifyAndClearExpectationsLocked(void* mock_obj) + GTEST_EXCLUSIVE_LOCK_REQUIRED_(internal::g_gmock_mutex) { + internal::g_gmock_mutex.AssertHeld(); + if (g_mock_object_registry.states().count(mock_obj) == 0) { + // No EXPECT_CALL() was set on the given mock object. + return true; + } + + // Verifies and clears the expectations on each mock method in the + // given mock object. + bool expectations_met = true; + FunctionMockers& mockers = + g_mock_object_registry.states()[mock_obj].function_mockers; + for (FunctionMockers::const_iterator it = mockers.begin(); + it != mockers.end(); ++it) { + if (!(*it)->VerifyAndClearExpectationsLocked()) { + expectations_met = false; + } + } + + // We don't clear the content of mockers, as they may still be + // needed by ClearDefaultActionsLocked(). + return expectations_met; +} + +bool Mock::IsNaggy(void* mock_obj) + GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) { + return Mock::GetReactionOnUninterestingCalls(mock_obj) == internal::kWarn; +} +bool Mock::IsNice(void* mock_obj) + GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) { + return Mock::GetReactionOnUninterestingCalls(mock_obj) == internal::kAllow; +} +bool Mock::IsStrict(void* mock_obj) + GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) { + return Mock::GetReactionOnUninterestingCalls(mock_obj) == internal::kFail; +} + +// Registers a mock object and a mock method it owns. +void Mock::Register(const void* mock_obj, + internal::UntypedFunctionMockerBase* mocker) + GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) { + internal::MutexLock l(&internal::g_gmock_mutex); + g_mock_object_registry.states()[mock_obj].function_mockers.insert(mocker); +} + +// Tells Google Mock where in the source code mock_obj is used in an +// ON_CALL or EXPECT_CALL. In case mock_obj is leaked, this +// information helps the user identify which object it is. +void Mock::RegisterUseByOnCallOrExpectCall(const void* mock_obj, + const char* file, int line) + GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) { + internal::MutexLock l(&internal::g_gmock_mutex); + MockObjectState& state = g_mock_object_registry.states()[mock_obj]; + if (state.first_used_file == nullptr) { + state.first_used_file = file; + state.first_used_line = line; + const TestInfo* const test_info = + UnitTest::GetInstance()->current_test_info(); + if (test_info != nullptr) { + state.first_used_test_suite = test_info->test_suite_name(); + state.first_used_test = test_info->name(); + } + } +} + +// Unregisters a mock method; removes the owning mock object from the +// registry when the last mock method associated with it has been +// unregistered. This is called only in the destructor of +// FunctionMockerBase. +void Mock::UnregisterLocked(internal::UntypedFunctionMockerBase* mocker) + GTEST_EXCLUSIVE_LOCK_REQUIRED_(internal::g_gmock_mutex) { + internal::g_gmock_mutex.AssertHeld(); + for (MockObjectRegistry::StateMap::iterator it = + g_mock_object_registry.states().begin(); + it != g_mock_object_registry.states().end(); ++it) { + FunctionMockers& mockers = it->second.function_mockers; + if (mockers.erase(mocker) > 0) { + // mocker was in mockers and has been just removed. + if (mockers.empty()) { + g_mock_object_registry.states().erase(it); + } + return; + } + } +} + +// Clears all ON_CALL()s set on the given mock object. +void Mock::ClearDefaultActionsLocked(void* mock_obj) + GTEST_EXCLUSIVE_LOCK_REQUIRED_(internal::g_gmock_mutex) { + internal::g_gmock_mutex.AssertHeld(); + + if (g_mock_object_registry.states().count(mock_obj) == 0) { + // No ON_CALL() was set on the given mock object. + return; + } + + // Clears the default actions for each mock method in the given mock + // object. + FunctionMockers& mockers = + g_mock_object_registry.states()[mock_obj].function_mockers; + for (FunctionMockers::const_iterator it = mockers.begin(); + it != mockers.end(); ++it) { + (*it)->ClearDefaultActionsLocked(); + } + + // We don't clear the content of mockers, as they may still be + // needed by VerifyAndClearExpectationsLocked(). +} + +Expectation::Expectation() {} + +Expectation::Expectation( + const std::shared_ptr<internal::ExpectationBase>& an_expectation_base) + : expectation_base_(an_expectation_base) {} + +Expectation::~Expectation() {} + +// Adds an expectation to a sequence. +void Sequence::AddExpectation(const Expectation& expectation) const { + if (*last_expectation_ != expectation) { + if (last_expectation_->expectation_base() != nullptr) { + expectation.expectation_base()->immediate_prerequisites_ + += *last_expectation_; + } + *last_expectation_ = expectation; + } +} + +// Creates the implicit sequence if there isn't one. +InSequence::InSequence() { + if (internal::g_gmock_implicit_sequence.get() == nullptr) { + internal::g_gmock_implicit_sequence.set(new Sequence); + sequence_created_ = true; + } else { + sequence_created_ = false; + } +} + +// Deletes the implicit sequence if it was created by the constructor +// of this object. +InSequence::~InSequence() { + if (sequence_created_) { + delete internal::g_gmock_implicit_sequence.get(); + internal::g_gmock_implicit_sequence.set(nullptr); + } +} + +} // namespace testing + +#ifdef _MSC_VER +#if _MSC_VER == 1900 +# pragma warning(pop) +#endif +#endif diff --git a/src/googletest/googlemock/src/gmock.cc b/src/googletest/googlemock/src/gmock.cc new file mode 100644 index 000000000..7bcdb0ba2 --- /dev/null +++ b/src/googletest/googlemock/src/gmock.cc @@ -0,0 +1,213 @@ +// 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. + + +#include "gmock/gmock.h" +#include "gmock/internal/gmock-port.h" + +namespace testing { + +GMOCK_DEFINE_bool_(catch_leaked_mocks, true, + "true if and only if Google Mock should report leaked " + "mock objects as failures."); + +GMOCK_DEFINE_string_(verbose, internal::kWarningVerbosity, + "Controls how verbose Google Mock's output is." + " Valid values:\n" + " info - prints all messages.\n" + " warning - prints warnings and errors.\n" + " error - prints errors only."); + +GMOCK_DEFINE_int32_(default_mock_behavior, 1, + "Controls the default behavior of mocks." + " Valid values:\n" + " 0 - by default, mocks act as NiceMocks.\n" + " 1 - by default, mocks act as NaggyMocks.\n" + " 2 - by default, mocks act as StrictMocks."); + +namespace internal { + +// Parses a string as a command line flag. The string should have the +// format "--gmock_flag=value". When def_optional is true, the +// "=value" part can be omitted. +// +// Returns the value of the flag, or NULL if the parsing failed. +static const char* ParseGoogleMockFlagValue(const char* str, + const char* flag, + bool def_optional) { + // str and flag must not be NULL. + if (str == nullptr || flag == nullptr) return nullptr; + + // The flag must start with "--gmock_". + const std::string flag_str = std::string("--gmock_") + flag; + const size_t flag_len = flag_str.length(); + if (strncmp(str, flag_str.c_str(), flag_len) != 0) return nullptr; + + // Skips the flag name. + const char* flag_end = str + flag_len; + + // When def_optional is true, it's OK to not have a "=value" part. + if (def_optional && (flag_end[0] == '\0')) { + return flag_end; + } + + // If def_optional is true and there are more characters after the + // flag name, or if def_optional is false, there must be a '=' after + // the flag name. + if (flag_end[0] != '=') return nullptr; + + // Returns the string after "=". + return flag_end + 1; +} + +// Parses a string for a Google Mock bool flag, in the form of +// "--gmock_flag=value". +// +// On success, stores the value of the flag in *value, and returns +// true. On failure, returns false without changing *value. +static bool ParseGoogleMockBoolFlag(const char* str, const char* flag, + bool* value) { + // Gets the value of the flag as a string. + const char* const value_str = ParseGoogleMockFlagValue(str, flag, true); + + // Aborts if the parsing failed. + if (value_str == nullptr) return false; + + // Converts the string value to a bool. + *value = !(*value_str == '0' || *value_str == 'f' || *value_str == 'F'); + return true; +} + +// Parses a string for a Google Mock string flag, in the form of +// "--gmock_flag=value". +// +// On success, stores the value of the flag in *value, and returns +// true. On failure, returns false without changing *value. +template <typename String> +static bool ParseGoogleMockStringFlag(const char* str, const char* flag, + String* value) { + // Gets the value of the flag as a string. + const char* const value_str = ParseGoogleMockFlagValue(str, flag, false); + + // Aborts if the parsing failed. + if (value_str == nullptr) return false; + + // Sets *value to the value of the flag. + *value = value_str; + return true; +} + +static bool ParseGoogleMockIntFlag(const char* str, const char* flag, + int32_t* value) { + // Gets the value of the flag as a string. + const char* const value_str = ParseGoogleMockFlagValue(str, flag, true); + + // Aborts if the parsing failed. + if (value_str == nullptr) return false; + + // Sets *value to the value of the flag. + return ParseInt32(Message() << "The value of flag --" << flag, + value_str, value); +} + +// The internal implementation of InitGoogleMock(). +// +// The type parameter CharType can be instantiated to either char or +// wchar_t. +template <typename CharType> +void InitGoogleMockImpl(int* argc, CharType** argv) { + // Makes sure Google Test is initialized. InitGoogleTest() is + // idempotent, so it's fine if the user has already called it. + InitGoogleTest(argc, argv); + if (*argc <= 0) return; + + for (int i = 1; i != *argc; i++) { + const std::string arg_string = StreamableToString(argv[i]); + const char* const arg = arg_string.c_str(); + + // Do we see a Google Mock flag? + if (ParseGoogleMockBoolFlag(arg, "catch_leaked_mocks", + &GMOCK_FLAG(catch_leaked_mocks)) || + ParseGoogleMockStringFlag(arg, "verbose", &GMOCK_FLAG(verbose)) || + ParseGoogleMockIntFlag(arg, "default_mock_behavior", + &GMOCK_FLAG(default_mock_behavior))) { + // Yes. Shift the remainder of the argv list left by one. Note + // that argv has (*argc + 1) elements, the last one always being + // NULL. The following loop moves the trailing NULL element as + // well. + for (int j = i; j != *argc; j++) { + argv[j] = argv[j + 1]; + } + + // Decrements the argument count. + (*argc)--; + + // We also need to decrement the iterator as we just removed + // an element. + i--; + } + } +} + +} // namespace internal + +// Initializes Google Mock. This must be called before running the +// tests. In particular, it parses a command line for the flags that +// Google Mock recognizes. Whenever a Google Mock flag is seen, it is +// removed from argv, and *argc is decremented. +// +// No value is returned. Instead, the Google Mock flag variables are +// updated. +// +// Since Google Test is needed for Google Mock to work, this function +// also initializes Google Test and parses its flags, if that hasn't +// been done. +GTEST_API_ void InitGoogleMock(int* argc, char** argv) { + internal::InitGoogleMockImpl(argc, argv); +} + +// This overloaded version can be used in Windows programs compiled in +// UNICODE mode. +GTEST_API_ void InitGoogleMock(int* argc, wchar_t** argv) { + internal::InitGoogleMockImpl(argc, argv); +} + +// This overloaded version can be used on Arduino/embedded platforms where +// there is no argc/argv. +GTEST_API_ void InitGoogleMock() { + // Since Arduino doesn't have a command line, fake out the argc/argv arguments + int argc = 1; + const auto arg0 = "dummy"; + char* argv0 = const_cast<char*>(arg0); + char** argv = &argv0; + + internal::InitGoogleMockImpl(&argc, argv); +} + +} // namespace testing diff --git a/src/googletest/googlemock/src/gmock_main.cc b/src/googletest/googlemock/src/gmock_main.cc new file mode 100644 index 000000000..18c500f66 --- /dev/null +++ b/src/googletest/googlemock/src/gmock_main.cc @@ -0,0 +1,72 @@ +// 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. + + +#include <iostream> +#include "gmock/gmock.h" +#include "gtest/gtest.h" + +#if GTEST_OS_ESP8266 || GTEST_OS_ESP32 +#if GTEST_OS_ESP8266 +extern "C" { +#endif +void setup() { + // Since Google Mock depends on Google Test, InitGoogleMock() is + // also responsible for initializing Google Test. Therefore there's + // no need for calling testing::InitGoogleTest() separately. + testing::InitGoogleMock(); +} +void loop() { RUN_ALL_TESTS(); } +#if GTEST_OS_ESP8266 +} +#endif + +#else + +// MS C++ compiler/linker has a bug on Windows (not on Windows CE), which +// causes a link error when _tmain is defined in a static library and UNICODE +// is enabled. For this reason instead of _tmain, main function is used on +// Windows. See the following link to track the current status of this bug: +// https://web.archive.org/web/20170912203238/connect.microsoft.com/VisualStudio/feedback/details/394464/wmain-link-error-in-the-static-library +// // NOLINT +#if GTEST_OS_WINDOWS_MOBILE +# include <tchar.h> // NOLINT + +GTEST_API_ int _tmain(int argc, TCHAR** argv) { +#else +GTEST_API_ int main(int argc, char** argv) { +#endif // GTEST_OS_WINDOWS_MOBILE + std::cout << "Running main() from gmock_main.cc\n"; + // Since Google Mock depends on Google Test, InitGoogleMock() is + // also responsible for initializing Google Test. Therefore there's + // no need for calling testing::InitGoogleTest() separately. + testing::InitGoogleMock(&argc, argv); + return RUN_ALL_TESTS(); +} +#endif diff --git a/src/googletest/googlemock/test/BUILD.bazel b/src/googletest/googlemock/test/BUILD.bazel new file mode 100644 index 000000000..ee75f27f9 --- /dev/null +++ b/src/googletest/googlemock/test/BUILD.bazel @@ -0,0 +1,119 @@ +# Copyright 2017 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. +# +# Bazel Build for Google C++ Testing Framework(Google Test)-googlemock + +load("@rules_cc//cc:defs.bzl", "cc_binary", "cc_test") +load("@rules_python//python:defs.bzl", "py_library", "py_test") + +licenses(["notice"]) + +# Tests for GMock itself +cc_test( + name = "gmock_all_test", + size = "small", + srcs = glob(include = ["gmock-*.cc"]), + linkopts = select({ + "//:windows": [], + "//conditions:default": ["-pthread"], + }), + deps = ["//:gtest"], +) + +# Python tests +py_library( + name = "gmock_test_utils", + testonly = 1, + srcs = ["gmock_test_utils.py"], + deps = [ + "//googletest/test:gtest_test_utils", + ] +) + +cc_binary( + name = "gmock_leak_test_", + testonly = 1, + srcs = ["gmock_leak_test_.cc"], + deps = ["//:gtest_main"], +) + +py_test( + name = "gmock_leak_test", + size = "medium", + srcs = ["gmock_leak_test.py"], + data = [ + ":gmock_leak_test_", + ":gmock_test_utils", + ], + tags = [ + "no_test_msvc2015", + "no_test_msvc2017", + ], +) + +cc_test( + name = "gmock_link_test", + size = "small", + srcs = [ + "gmock_link2_test.cc", + "gmock_link_test.cc", + "gmock_link_test.h", + ], + deps = ["//:gtest_main"], +) + +cc_binary( + name = "gmock_output_test_", + srcs = ["gmock_output_test_.cc"], + deps = ["//:gtest"], +) + +py_test( + name = "gmock_output_test", + size = "medium", + srcs = ["gmock_output_test.py"], + data = [ + ":gmock_output_test_", + ":gmock_output_test_golden.txt", + ], + python_version = "PY2", + deps = [":gmock_test_utils"], + tags = [ + "no_test_msvc2015", + "no_test_msvc2017", + ], +) + +cc_test( + name = "gmock_test", + size = "small", + srcs = ["gmock_test.cc"], + deps = ["//:gtest_main"], +) diff --git a/src/googletest/googlemock/test/gmock-actions_test.cc b/src/googletest/googlemock/test/gmock-actions_test.cc new file mode 100644 index 000000000..183872847 --- /dev/null +++ b/src/googletest/googlemock/test/gmock-actions_test.cc @@ -0,0 +1,1583 @@ +// 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. + + +// Google Mock - a framework for writing C++ mock classes. +// +// This file tests the built-in actions. + +// Silence C4100 (unreferenced formal parameter) for MSVC +#ifdef _MSC_VER +# pragma warning(push) +# pragma warning(disable:4100) +#if _MSC_VER == 1900 +// and silence C4800 (C4800: 'int *const ': forcing value +// to bool 'true' or 'false') for MSVC 15 +# pragma warning(disable:4800) +#endif +#endif + +#include "gmock/gmock-actions.h" +#include <algorithm> +#include <iterator> +#include <memory> +#include <string> +#include <type_traits> +#include "gmock/gmock.h" +#include "gmock/internal/gmock-port.h" +#include "gtest/gtest.h" +#include "gtest/gtest-spi.h" + +namespace { + +using ::testing::_; +using ::testing::Action; +using ::testing::ActionInterface; +using ::testing::Assign; +using ::testing::ByMove; +using ::testing::ByRef; +using ::testing::DefaultValue; +using ::testing::DoAll; +using ::testing::DoDefault; +using ::testing::IgnoreResult; +using ::testing::Invoke; +using ::testing::InvokeWithoutArgs; +using ::testing::MakePolymorphicAction; +using ::testing::PolymorphicAction; +using ::testing::Return; +using ::testing::ReturnNew; +using ::testing::ReturnNull; +using ::testing::ReturnRef; +using ::testing::ReturnRefOfCopy; +using ::testing::ReturnRoundRobin; +using ::testing::SetArgPointee; +using ::testing::SetArgumentPointee; +using ::testing::Unused; +using ::testing::WithArgs; +using ::testing::internal::BuiltInDefaultValue; + +#if !GTEST_OS_WINDOWS_MOBILE +using ::testing::SetErrnoAndReturn; +#endif + +// Tests that BuiltInDefaultValue<T*>::Get() returns NULL. +TEST(BuiltInDefaultValueTest, IsNullForPointerTypes) { + EXPECT_TRUE(BuiltInDefaultValue<int*>::Get() == nullptr); + EXPECT_TRUE(BuiltInDefaultValue<const char*>::Get() == nullptr); + EXPECT_TRUE(BuiltInDefaultValue<void*>::Get() == nullptr); +} + +// Tests that BuiltInDefaultValue<T*>::Exists() return true. +TEST(BuiltInDefaultValueTest, ExistsForPointerTypes) { + EXPECT_TRUE(BuiltInDefaultValue<int*>::Exists()); + EXPECT_TRUE(BuiltInDefaultValue<const char*>::Exists()); + EXPECT_TRUE(BuiltInDefaultValue<void*>::Exists()); +} + +// Tests that BuiltInDefaultValue<T>::Get() returns 0 when T is a +// built-in numeric type. +TEST(BuiltInDefaultValueTest, IsZeroForNumericTypes) { + EXPECT_EQ(0U, BuiltInDefaultValue<unsigned char>::Get()); + EXPECT_EQ(0, BuiltInDefaultValue<signed char>::Get()); + EXPECT_EQ(0, BuiltInDefaultValue<char>::Get()); +#if GMOCK_WCHAR_T_IS_NATIVE_ +#if !defined(__WCHAR_UNSIGNED__) + EXPECT_EQ(0, BuiltInDefaultValue<wchar_t>::Get()); +#else + EXPECT_EQ(0U, BuiltInDefaultValue<wchar_t>::Get()); +#endif +#endif + EXPECT_EQ(0U, BuiltInDefaultValue<unsigned short>::Get()); // NOLINT + EXPECT_EQ(0, BuiltInDefaultValue<signed short>::Get()); // NOLINT + EXPECT_EQ(0, BuiltInDefaultValue<short>::Get()); // NOLINT + EXPECT_EQ(0U, BuiltInDefaultValue<unsigned int>::Get()); + EXPECT_EQ(0, BuiltInDefaultValue<signed int>::Get()); + EXPECT_EQ(0, BuiltInDefaultValue<int>::Get()); + EXPECT_EQ(0U, BuiltInDefaultValue<unsigned long>::Get()); // NOLINT + EXPECT_EQ(0, BuiltInDefaultValue<signed long>::Get()); // NOLINT + EXPECT_EQ(0, BuiltInDefaultValue<long>::Get()); // NOLINT + EXPECT_EQ(0U, BuiltInDefaultValue<unsigned long long>::Get()); // NOLINT + EXPECT_EQ(0, BuiltInDefaultValue<signed long long>::Get()); // NOLINT + EXPECT_EQ(0, BuiltInDefaultValue<long long>::Get()); // NOLINT + EXPECT_EQ(0, BuiltInDefaultValue<float>::Get()); + EXPECT_EQ(0, BuiltInDefaultValue<double>::Get()); +} + +// Tests that BuiltInDefaultValue<T>::Exists() returns true when T is a +// built-in numeric type. +TEST(BuiltInDefaultValueTest, ExistsForNumericTypes) { + EXPECT_TRUE(BuiltInDefaultValue<unsigned char>::Exists()); + EXPECT_TRUE(BuiltInDefaultValue<signed char>::Exists()); + EXPECT_TRUE(BuiltInDefaultValue<char>::Exists()); +#if GMOCK_WCHAR_T_IS_NATIVE_ + EXPECT_TRUE(BuiltInDefaultValue<wchar_t>::Exists()); +#endif + EXPECT_TRUE(BuiltInDefaultValue<unsigned short>::Exists()); // NOLINT + EXPECT_TRUE(BuiltInDefaultValue<signed short>::Exists()); // NOLINT + EXPECT_TRUE(BuiltInDefaultValue<short>::Exists()); // NOLINT + EXPECT_TRUE(BuiltInDefaultValue<unsigned int>::Exists()); + EXPECT_TRUE(BuiltInDefaultValue<signed int>::Exists()); + EXPECT_TRUE(BuiltInDefaultValue<int>::Exists()); + EXPECT_TRUE(BuiltInDefaultValue<unsigned long>::Exists()); // NOLINT + EXPECT_TRUE(BuiltInDefaultValue<signed long>::Exists()); // NOLINT + EXPECT_TRUE(BuiltInDefaultValue<long>::Exists()); // NOLINT + EXPECT_TRUE(BuiltInDefaultValue<unsigned long long>::Exists()); // NOLINT + EXPECT_TRUE(BuiltInDefaultValue<signed long long>::Exists()); // NOLINT + EXPECT_TRUE(BuiltInDefaultValue<long long>::Exists()); // NOLINT + EXPECT_TRUE(BuiltInDefaultValue<float>::Exists()); + EXPECT_TRUE(BuiltInDefaultValue<double>::Exists()); +} + +// Tests that BuiltInDefaultValue<bool>::Get() returns false. +TEST(BuiltInDefaultValueTest, IsFalseForBool) { + EXPECT_FALSE(BuiltInDefaultValue<bool>::Get()); +} + +// Tests that BuiltInDefaultValue<bool>::Exists() returns true. +TEST(BuiltInDefaultValueTest, BoolExists) { + EXPECT_TRUE(BuiltInDefaultValue<bool>::Exists()); +} + +// Tests that BuiltInDefaultValue<T>::Get() returns "" when T is a +// string type. +TEST(BuiltInDefaultValueTest, IsEmptyStringForString) { + EXPECT_EQ("", BuiltInDefaultValue< ::std::string>::Get()); +} + +// Tests that BuiltInDefaultValue<T>::Exists() returns true when T is a +// string type. +TEST(BuiltInDefaultValueTest, ExistsForString) { + EXPECT_TRUE(BuiltInDefaultValue< ::std::string>::Exists()); +} + +// Tests that BuiltInDefaultValue<const T>::Get() returns the same +// value as BuiltInDefaultValue<T>::Get() does. +TEST(BuiltInDefaultValueTest, WorksForConstTypes) { + EXPECT_EQ("", BuiltInDefaultValue<const std::string>::Get()); + EXPECT_EQ(0, BuiltInDefaultValue<const int>::Get()); + EXPECT_TRUE(BuiltInDefaultValue<char* const>::Get() == nullptr); + EXPECT_FALSE(BuiltInDefaultValue<const bool>::Get()); +} + +// A type that's default constructible. +class MyDefaultConstructible { + public: + MyDefaultConstructible() : value_(42) {} + + int value() const { return value_; } + + private: + int value_; +}; + +// A type that's not default constructible. +class MyNonDefaultConstructible { + public: + // Does not have a default ctor. + explicit MyNonDefaultConstructible(int a_value) : value_(a_value) {} + + int value() const { return value_; } + + private: + int value_; +}; + + +TEST(BuiltInDefaultValueTest, ExistsForDefaultConstructibleType) { + EXPECT_TRUE(BuiltInDefaultValue<MyDefaultConstructible>::Exists()); +} + +TEST(BuiltInDefaultValueTest, IsDefaultConstructedForDefaultConstructibleType) { + EXPECT_EQ(42, BuiltInDefaultValue<MyDefaultConstructible>::Get().value()); +} + + +TEST(BuiltInDefaultValueTest, DoesNotExistForNonDefaultConstructibleType) { + EXPECT_FALSE(BuiltInDefaultValue<MyNonDefaultConstructible>::Exists()); +} + +// Tests that BuiltInDefaultValue<T&>::Get() aborts the program. +TEST(BuiltInDefaultValueDeathTest, IsUndefinedForReferences) { + EXPECT_DEATH_IF_SUPPORTED({ + BuiltInDefaultValue<int&>::Get(); + }, ""); + EXPECT_DEATH_IF_SUPPORTED({ + BuiltInDefaultValue<const char&>::Get(); + }, ""); +} + +TEST(BuiltInDefaultValueDeathTest, IsUndefinedForNonDefaultConstructibleType) { + EXPECT_DEATH_IF_SUPPORTED({ + BuiltInDefaultValue<MyNonDefaultConstructible>::Get(); + }, ""); +} + +// Tests that DefaultValue<T>::IsSet() is false initially. +TEST(DefaultValueTest, IsInitiallyUnset) { + EXPECT_FALSE(DefaultValue<int>::IsSet()); + EXPECT_FALSE(DefaultValue<MyDefaultConstructible>::IsSet()); + EXPECT_FALSE(DefaultValue<const MyNonDefaultConstructible>::IsSet()); +} + +// Tests that DefaultValue<T> can be set and then unset. +TEST(DefaultValueTest, CanBeSetAndUnset) { + EXPECT_TRUE(DefaultValue<int>::Exists()); + EXPECT_FALSE(DefaultValue<const MyNonDefaultConstructible>::Exists()); + + DefaultValue<int>::Set(1); + DefaultValue<const MyNonDefaultConstructible>::Set( + MyNonDefaultConstructible(42)); + + EXPECT_EQ(1, DefaultValue<int>::Get()); + EXPECT_EQ(42, DefaultValue<const MyNonDefaultConstructible>::Get().value()); + + EXPECT_TRUE(DefaultValue<int>::Exists()); + EXPECT_TRUE(DefaultValue<const MyNonDefaultConstructible>::Exists()); + + DefaultValue<int>::Clear(); + DefaultValue<const MyNonDefaultConstructible>::Clear(); + + EXPECT_FALSE(DefaultValue<int>::IsSet()); + EXPECT_FALSE(DefaultValue<const MyNonDefaultConstructible>::IsSet()); + + EXPECT_TRUE(DefaultValue<int>::Exists()); + EXPECT_FALSE(DefaultValue<const MyNonDefaultConstructible>::Exists()); +} + +// Tests that DefaultValue<T>::Get() returns the +// BuiltInDefaultValue<T>::Get() when DefaultValue<T>::IsSet() is +// false. +TEST(DefaultValueDeathTest, GetReturnsBuiltInDefaultValueWhenUnset) { + EXPECT_FALSE(DefaultValue<int>::IsSet()); + EXPECT_TRUE(DefaultValue<int>::Exists()); + EXPECT_FALSE(DefaultValue<MyNonDefaultConstructible>::IsSet()); + EXPECT_FALSE(DefaultValue<MyNonDefaultConstructible>::Exists()); + + EXPECT_EQ(0, DefaultValue<int>::Get()); + + EXPECT_DEATH_IF_SUPPORTED({ + DefaultValue<MyNonDefaultConstructible>::Get(); + }, ""); +} + +TEST(DefaultValueTest, GetWorksForMoveOnlyIfSet) { + EXPECT_TRUE(DefaultValue<std::unique_ptr<int>>::Exists()); + EXPECT_TRUE(DefaultValue<std::unique_ptr<int>>::Get() == nullptr); + DefaultValue<std::unique_ptr<int>>::SetFactory([] { + return std::unique_ptr<int>(new int(42)); + }); + EXPECT_TRUE(DefaultValue<std::unique_ptr<int>>::Exists()); + std::unique_ptr<int> i = DefaultValue<std::unique_ptr<int>>::Get(); + EXPECT_EQ(42, *i); +} + +// 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<MyDefaultConstructible&>::IsSet()); + EXPECT_FALSE(DefaultValue<MyNonDefaultConstructible&>::IsSet()); +} + +// Tests that DefaultValue<T&>::Exists is false initiallly. +TEST(DefaultValueOfReferenceTest, IsInitiallyNotExisting) { + EXPECT_FALSE(DefaultValue<int&>::Exists()); + EXPECT_FALSE(DefaultValue<MyDefaultConstructible&>::Exists()); + EXPECT_FALSE(DefaultValue<MyNonDefaultConstructible&>::Exists()); +} + +// Tests that DefaultValue<T&> can be set and then unset. +TEST(DefaultValueOfReferenceTest, CanBeSetAndUnset) { + int n = 1; + DefaultValue<const int&>::Set(n); + MyNonDefaultConstructible x(42); + DefaultValue<MyNonDefaultConstructible&>::Set(x); + + EXPECT_TRUE(DefaultValue<const int&>::Exists()); + EXPECT_TRUE(DefaultValue<MyNonDefaultConstructible&>::Exists()); + + EXPECT_EQ(&n, &(DefaultValue<const int&>::Get())); + EXPECT_EQ(&x, &(DefaultValue<MyNonDefaultConstructible&>::Get())); + + DefaultValue<const int&>::Clear(); + DefaultValue<MyNonDefaultConstructible&>::Clear(); + + EXPECT_FALSE(DefaultValue<const int&>::Exists()); + EXPECT_FALSE(DefaultValue<MyNonDefaultConstructible&>::Exists()); + + EXPECT_FALSE(DefaultValue<const int&>::IsSet()); + EXPECT_FALSE(DefaultValue<MyNonDefaultConstructible&>::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<MyNonDefaultConstructible&>::IsSet()); + + EXPECT_DEATH_IF_SUPPORTED({ + DefaultValue<int&>::Get(); + }, ""); + EXPECT_DEATH_IF_SUPPORTED({ + DefaultValue<MyNonDefaultConstructible>::Get(); + }, ""); +} + +// Tests that ActionInterface can be implemented by defining the +// Perform method. + +typedef int MyGlobalFunction(bool, int); + +class MyActionImpl : public ActionInterface<MyGlobalFunction> { + public: + int Perform(const std::tuple<bool, int>& args) override { + return std::get<0>(args) ? std::get<1>(args) : 0; + } +}; + +TEST(ActionInterfaceTest, CanBeImplementedByDefiningPerform) { + MyActionImpl my_action_impl; + (void)my_action_impl; +} + +TEST(ActionInterfaceTest, MakeAction) { + Action<MyGlobalFunction> 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 + // std::tuple<bool, int>, and so on. + EXPECT_EQ(5, action.Perform(std::make_tuple(true, 5))); +} + +// Tests that Action<F> can be contructed from a pointer to +// ActionInterface<F>. +TEST(ActionTest, CanBeConstructedFromActionInterface) { + Action<MyGlobalFunction> action(new MyActionImpl); +} + +// Tests that Action<F> delegates actual work to ActionInterface<F>. +TEST(ActionTest, DelegatesWorkToActionInterface) { + const Action<MyGlobalFunction> action(new MyActionImpl); + + EXPECT_EQ(5, action.Perform(std::make_tuple(true, 5))); + EXPECT_EQ(0, action.Perform(std::make_tuple(false, 1))); +} + +// Tests that Action<F> can be copied. +TEST(ActionTest, IsCopyable) { + Action<MyGlobalFunction> a1(new MyActionImpl); + Action<MyGlobalFunction> a2(a1); // Tests the copy constructor. + + // a1 should continue to work after being copied from. + EXPECT_EQ(5, a1.Perform(std::make_tuple(true, 5))); + EXPECT_EQ(0, a1.Perform(std::make_tuple(false, 1))); + + // a2 should work like the action it was copied from. + EXPECT_EQ(5, a2.Perform(std::make_tuple(true, 5))); + EXPECT_EQ(0, a2.Perform(std::make_tuple(false, 1))); + + a2 = a1; // Tests the assignment operator. + + // a1 should continue to work after being copied from. + EXPECT_EQ(5, a1.Perform(std::make_tuple(true, 5))); + EXPECT_EQ(0, a1.Perform(std::make_tuple(false, 1))); + + // a2 should work like the action it was copied from. + EXPECT_EQ(5, a2.Perform(std::make_tuple(true, 5))); + EXPECT_EQ(0, a2.Perform(std::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: + bool Perform(const std::tuple<int>& arg) override { + return std::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(std::make_tuple('a'))); + EXPECT_EQ(0, a2.Perform(std::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 std::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 std::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(std::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(std::make_tuple())); + + Action<void*()> a2 = ReturnZeroFromNullaryFunction(); + EXPECT_TRUE(a2.Perform(std::make_tuple()) == nullptr); +} + +// Tests that Return() works as an action for void-returning +// functions. +TEST(ReturnTest, WorksForVoid) { + const Action<void(int)> ret = Return(); // NOLINT + return ret.Perform(std::make_tuple(1)); +} + +// Tests that Return(v) returns v. +TEST(ReturnTest, ReturnsGivenValue) { + Action<int()> ret = Return(1); // NOLINT + EXPECT_EQ(1, ret.Perform(std::make_tuple())); + + ret = Return(-5); + EXPECT_EQ(-5, ret.Perform(std::make_tuple())); +} + +// Tests that Return("string literal") works. +TEST(ReturnTest, AcceptsStringLiteral) { + Action<const char*()> a1 = Return("Hello"); + EXPECT_STREQ("Hello", a1.Perform(std::make_tuple())); + + Action<std::string()> a2 = Return("world"); + EXPECT_EQ("world", a2.Perform(std::make_tuple())); +} + +// Test struct which wraps a vector of integers. Used in +// 'SupportsWrapperReturnType' test. +struct IntegerVectorWrapper { + std::vector<int> * v; + IntegerVectorWrapper(std::vector<int>& _v) : v(&_v) {} // NOLINT +}; + +// Tests that Return() works when return type is a wrapper type. +TEST(ReturnTest, SupportsWrapperReturnType) { + // Initialize vector of integers. + std::vector<int> v; + for (int i = 0; i < 5; ++i) v.push_back(i); + + // Return() called with 'v' as argument. The Action will return the same data + // as 'v' (copy) but it will be wrapped in an IntegerVectorWrapper. + Action<IntegerVectorWrapper()> a = Return(v); + const std::vector<int>& result = *(a.Perform(std::make_tuple()).v); + EXPECT_THAT(result, ::testing::ElementsAre(0, 1, 2, 3, 4)); +} + +// 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(std::make_tuple())); + + ret = Return(&derived); + EXPECT_EQ(&derived, ret.Perform(std::make_tuple())); +} + +// Tests that the type of the value passed into Return is converted into T +// when the action is cast to Action<T(...)> rather than when the action is +// performed. See comments on testing::internal::ReturnAction in +// gmock-actions.h for more information. +class FromType { + public: + explicit FromType(bool* is_converted) : converted_(is_converted) {} + bool* converted() const { return converted_; } + + private: + bool* const converted_; +}; + +class ToType { + public: + // Must allow implicit conversion due to use in ImplicitCast_<T>. + ToType(const FromType& x) { *x.converted() = true; } // NOLINT +}; + +TEST(ReturnTest, ConvertsArgumentWhenConverted) { + bool converted = false; + FromType x(&converted); + Action<ToType()> action(Return(x)); + EXPECT_TRUE(converted) << "Return must convert its argument in its own " + << "conversion operator."; + converted = false; + action.Perform(std::tuple<>()); + EXPECT_FALSE(converted) << "Action must NOT convert its argument " + << "when performed."; +} + +class DestinationType {}; + +class SourceType { + public: + // Note: a non-const typecast operator. + operator DestinationType() { return DestinationType(); } +}; + +TEST(ReturnTest, CanConvertArgumentUsingNonConstTypeCastOperator) { + SourceType s; + Action<DestinationType()> action(Return(s)); +} + +// Tests that ReturnNull() returns NULL in a pointer-returning function. +TEST(ReturnNullTest, WorksInPointerReturningFunction) { + const Action<int*()> a1 = ReturnNull(); + EXPECT_TRUE(a1.Perform(std::make_tuple()) == nullptr); + + const Action<const char*(bool)> a2 = ReturnNull(); // NOLINT + EXPECT_TRUE(a2.Perform(std::make_tuple(true)) == nullptr); +} + +// Tests that ReturnNull() returns NULL for shared_ptr and unique_ptr returning +// functions. +TEST(ReturnNullTest, WorksInSmartPointerReturningFunction) { + const Action<std::unique_ptr<const int>()> a1 = ReturnNull(); + EXPECT_TRUE(a1.Perform(std::make_tuple()) == nullptr); + + const Action<std::shared_ptr<int>(std::string)> a2 = ReturnNull(); + EXPECT_TRUE(a2.Perform(std::make_tuple("foo")) == nullptr); +} + +// 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(std::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(std::make_tuple())); + + a = ReturnRef(derived); + EXPECT_EQ(&derived, &a.Perform(std::make_tuple())); +} + +template <typename T, typename = decltype(ReturnRef(std::declval<T&&>()))> +bool CanCallReturnRef(T&&) { return true; } +bool CanCallReturnRef(Unused) { return false; } + +// Tests that ReturnRef(v) is working with non-temporaries (T&) +TEST(ReturnRefTest, WorksForNonTemporary) { + int scalar_value = 123; + EXPECT_TRUE(CanCallReturnRef(scalar_value)); + + std::string non_scalar_value("ABC"); + EXPECT_TRUE(CanCallReturnRef(non_scalar_value)); + + const int const_scalar_value{321}; + EXPECT_TRUE(CanCallReturnRef(const_scalar_value)); + + const std::string const_non_scalar_value("CBA"); + EXPECT_TRUE(CanCallReturnRef(const_non_scalar_value)); +} + +// Tests that ReturnRef(v) is not working with temporaries (T&&) +TEST(ReturnRefTest, DoesNotWorkForTemporary) { + auto scalar_value = []() -> int { return 123; }; + EXPECT_FALSE(CanCallReturnRef(scalar_value())); + + auto non_scalar_value = []() -> std::string { return "ABC"; }; + EXPECT_FALSE(CanCallReturnRef(non_scalar_value())); + + // cannot use here callable returning "const scalar type", + // because such const for scalar return type is ignored + EXPECT_FALSE(CanCallReturnRef(static_cast<const int>(321))); + + auto const_non_scalar_value = []() -> const std::string { return "CBA"; }; + EXPECT_FALSE(CanCallReturnRef(const_non_scalar_value())); +} + +// Tests that ReturnRefOfCopy(v) works for reference types. +TEST(ReturnRefOfCopyTest, WorksForReference) { + int n = 42; + const Action<const int&()> ret = ReturnRefOfCopy(n); + + EXPECT_NE(&n, &ret.Perform(std::make_tuple())); + EXPECT_EQ(42, ret.Perform(std::make_tuple())); + + n = 43; + EXPECT_NE(&n, &ret.Perform(std::make_tuple())); + EXPECT_EQ(42, ret.Perform(std::make_tuple())); +} + +// Tests that ReturnRefOfCopy(v) is covariant. +TEST(ReturnRefOfCopyTest, IsCovariant) { + Base base; + Derived derived; + Action<Base&()> a = ReturnRefOfCopy(base); + EXPECT_NE(&base, &a.Perform(std::make_tuple())); + + a = ReturnRefOfCopy(derived); + EXPECT_NE(&derived, &a.Perform(std::make_tuple())); +} + +// Tests that ReturnRoundRobin(v) works with initializer lists +TEST(ReturnRoundRobinTest, WorksForInitList) { + Action<int()> ret = ReturnRoundRobin({1, 2, 3}); + + EXPECT_EQ(1, ret.Perform(std::make_tuple())); + EXPECT_EQ(2, ret.Perform(std::make_tuple())); + EXPECT_EQ(3, ret.Perform(std::make_tuple())); + EXPECT_EQ(1, ret.Perform(std::make_tuple())); + EXPECT_EQ(2, ret.Perform(std::make_tuple())); + EXPECT_EQ(3, ret.Perform(std::make_tuple())); +} + +// Tests that ReturnRoundRobin(v) works with vectors +TEST(ReturnRoundRobinTest, WorksForVector) { + std::vector<double> v = {4.4, 5.5, 6.6}; + Action<double()> ret = ReturnRoundRobin(v); + + EXPECT_EQ(4.4, ret.Perform(std::make_tuple())); + EXPECT_EQ(5.5, ret.Perform(std::make_tuple())); + EXPECT_EQ(6.6, ret.Perform(std::make_tuple())); + EXPECT_EQ(4.4, ret.Perform(std::make_tuple())); + EXPECT_EQ(5.5, ret.Perform(std::make_tuple())); + EXPECT_EQ(6.6, ret.Perform(std::make_tuple())); +} + +// Tests that DoDefault() does the default action for the mock method. + +class MockClass { + public: + MockClass() {} + + MOCK_METHOD1(IntFunc, int(bool flag)); // NOLINT + MOCK_METHOD0(Foo, MyNonDefaultConstructible()); + MOCK_METHOD0(MakeUnique, std::unique_ptr<int>()); + MOCK_METHOD0(MakeUniqueBase, std::unique_ptr<Base>()); + MOCK_METHOD0(MakeVectorUnique, std::vector<std::unique_ptr<int>>()); + MOCK_METHOD1(TakeUnique, int(std::unique_ptr<int>)); + MOCK_METHOD2(TakeUnique, + int(const std::unique_ptr<int>&, std::unique_ptr<int>)); + + private: + GTEST_DISALLOW_COPY_AND_ASSIGN_(MockClass); +}; + +// Tests that DoDefault() returns the built-in default value for the +// return type by default. +TEST(DoDefaultTest, ReturnsBuiltInDefaultValueByDefault) { + MockClass mock; + EXPECT_CALL(mock, IntFunc(_)) + .WillOnce(DoDefault()); + EXPECT_EQ(0, mock.IntFunc(true)); +} + +// Tests that DoDefault() throws (when exceptions are enabled) or aborts +// the process when there is no built-in default value for the return type. +TEST(DoDefaultDeathTest, DiesForUnknowType) { + MockClass mock; + EXPECT_CALL(mock, Foo()) + .WillRepeatedly(DoDefault()); +#if GTEST_HAS_EXCEPTIONS + EXPECT_ANY_THROW(mock.Foo()); +#else + EXPECT_DEATH_IF_SUPPORTED({ + mock.Foo(); + }, ""); +#endif +} + +// Tests that using DoDefault() inside a composite action leads to a +// run-time error. + +void VoidFunc(bool /* flag */) {} + +TEST(DoDefaultDeathTest, DiesIfUsedInCompositeAction) { + MockClass mock; + EXPECT_CALL(mock, IntFunc(_)) + .WillRepeatedly(DoAll(Invoke(VoidFunc), + DoDefault())); + + // Ideally we should verify the error message as well. Sadly, + // EXPECT_DEATH() can only capture stderr, while Google Mock's + // errors are printed on stdout. Therefore we have to settle for + // not verifying the message. + EXPECT_DEATH_IF_SUPPORTED({ + mock.IntFunc(true); + }, ""); +} + +// Tests that DoDefault() returns the default value set by +// DefaultValue<T>::Set() when it's not overriden by an ON_CALL(). +TEST(DoDefaultTest, ReturnsUserSpecifiedPerTypeDefaultValueWhenThereIsOne) { + DefaultValue<int>::Set(1); + MockClass mock; + EXPECT_CALL(mock, IntFunc(_)) + .WillOnce(DoDefault()); + EXPECT_EQ(1, mock.IntFunc(false)); + DefaultValue<int>::Clear(); +} + +// Tests that DoDefault() does the action specified by ON_CALL(). +TEST(DoDefaultTest, DoesWhatOnCallSpecifies) { + MockClass mock; + ON_CALL(mock, IntFunc(_)) + .WillByDefault(Return(2)); + EXPECT_CALL(mock, IntFunc(_)) + .WillOnce(DoDefault()); + EXPECT_EQ(2, mock.IntFunc(false)); +} + +// Tests that using DoDefault() in ON_CALL() leads to a run-time failure. +TEST(DoDefaultTest, CannotBeUsedInOnCall) { + MockClass mock; + EXPECT_NONFATAL_FAILURE({ // NOLINT + ON_CALL(mock, IntFunc(_)) + .WillByDefault(DoDefault()); + }, "DoDefault() cannot be used in ON_CALL()"); +} + +// Tests that SetArgPointee<N>(v) sets the variable pointed to by +// the N-th (0-based) argument to v. +TEST(SetArgPointeeTest, SetsTheNthPointee) { + typedef void MyFunction(bool, int*, char*); + Action<MyFunction> a = SetArgPointee<1>(2); + + int n = 0; + char ch = '\0'; + a.Perform(std::make_tuple(true, &n, &ch)); + EXPECT_EQ(2, n); + EXPECT_EQ('\0', ch); + + a = SetArgPointee<2>('a'); + n = 0; + ch = '\0'; + a.Perform(std::make_tuple(true, &n, &ch)); + EXPECT_EQ(0, n); + EXPECT_EQ('a', ch); +} + +// Tests that SetArgPointee<N>() accepts a string literal. +TEST(SetArgPointeeTest, AcceptsStringLiteral) { + typedef void MyFunction(std::string*, const char**); + Action<MyFunction> a = SetArgPointee<0>("hi"); + std::string str; + const char* ptr = nullptr; + a.Perform(std::make_tuple(&str, &ptr)); + EXPECT_EQ("hi", str); + EXPECT_TRUE(ptr == nullptr); + + a = SetArgPointee<1>("world"); + str = ""; + a.Perform(std::make_tuple(&str, &ptr)); + EXPECT_EQ("", str); + EXPECT_STREQ("world", ptr); +} + +TEST(SetArgPointeeTest, AcceptsWideStringLiteral) { + typedef void MyFunction(const wchar_t**); + Action<MyFunction> a = SetArgPointee<0>(L"world"); + const wchar_t* ptr = nullptr; + a.Perform(std::make_tuple(&ptr)); + EXPECT_STREQ(L"world", ptr); + +# if GTEST_HAS_STD_WSTRING + + typedef void MyStringFunction(std::wstring*); + Action<MyStringFunction> a2 = SetArgPointee<0>(L"world"); + std::wstring str = L""; + a2.Perform(std::make_tuple(&str)); + EXPECT_EQ(L"world", str); + +# endif +} + +// Tests that SetArgPointee<N>() accepts a char pointer. +TEST(SetArgPointeeTest, AcceptsCharPointer) { + typedef void MyFunction(bool, std::string*, const char**); + const char* const hi = "hi"; + Action<MyFunction> a = SetArgPointee<1>(hi); + std::string str; + const char* ptr = nullptr; + a.Perform(std::make_tuple(true, &str, &ptr)); + EXPECT_EQ("hi", str); + EXPECT_TRUE(ptr == nullptr); + + char world_array[] = "world"; + char* const world = world_array; + a = SetArgPointee<2>(world); + str = ""; + a.Perform(std::make_tuple(true, &str, &ptr)); + EXPECT_EQ("", str); + EXPECT_EQ(world, ptr); +} + +TEST(SetArgPointeeTest, AcceptsWideCharPointer) { + typedef void MyFunction(bool, const wchar_t**); + const wchar_t* const hi = L"hi"; + Action<MyFunction> a = SetArgPointee<1>(hi); + const wchar_t* ptr = nullptr; + a.Perform(std::make_tuple(true, &ptr)); + EXPECT_EQ(hi, ptr); + +# if GTEST_HAS_STD_WSTRING + + typedef void MyStringFunction(bool, std::wstring*); + wchar_t world_array[] = L"world"; + wchar_t* const world = world_array; + Action<MyStringFunction> a2 = SetArgPointee<1>(world); + std::wstring str; + a2.Perform(std::make_tuple(true, &str)); + EXPECT_EQ(world_array, str); +# endif +} + +// 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(std::make_tuple(true, &n, &ch)); + EXPECT_EQ(2, n); + EXPECT_EQ('\0', ch); + + a = SetArgumentPointee<2>('a'); + n = 0; + ch = '\0'; + a.Perform(std::make_tuple(true, &n, &ch)); + EXPECT_EQ(0, n); + EXPECT_EQ('a', ch); +} + +// 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; } +}; + +short Short(short n) { return n; } // NOLINT +char Char(char ch) { return ch; } + +const char* CharPtr(const char* s) { return s; } + +bool Unary(int x) { return x < 0; } + +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 + +int SumOf4(int a, int b, int c, int d) { return a + b + c + d; } + +class Foo { + public: + Foo() : value_(123) {} + + int Nullary() const { return value_; } + + 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(std::make_tuple(2))); + + // As an action that takes two arguments. + Action<int(int, double)> a2 = InvokeWithoutArgs(Nullary); // NOLINT + EXPECT_EQ(1, a2.Perform(std::make_tuple(2, 3.5))); + + // As an action that returns void. + Action<void(int)> a3 = InvokeWithoutArgs(VoidNullary); // NOLINT + g_done = false; + a3.Perform(std::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(std::make_tuple())); + + // As an action that takes three arguments. + Action<int(int, double, char)> a2 = // NOLINT + InvokeWithoutArgs(NullaryFunctor()); + EXPECT_EQ(2, a2.Perform(std::make_tuple(3, 3.5, 'a'))); + + // As an action that returns void. + Action<void()> a3 = InvokeWithoutArgs(VoidNullaryFunctor()); + g_done = false; + a3.Perform(std::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(std::make_tuple(true, 'a'))); +} + +// Tests using IgnoreResult() on a polymorphic action. +TEST(IgnoreResultTest, PolymorphicAction) { + Action<void(int)> a = IgnoreResult(Return(5)); // NOLINT + a.Perform(std::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(std::make_tuple()); + EXPECT_TRUE(g_done); +} + +// Tests using IgnoreResult() on an action that returns a class type. + +MyNonDefaultConstructible ReturnMyNonDefaultConstructible(double /* x */) { + g_done = true; + return MyNonDefaultConstructible(42); +} + +TEST(IgnoreResultTest, ActionReturningClass) { + g_done = false; + Action<void(int)> a = + IgnoreResult(Invoke(ReturnMyNonDefaultConstructible)); // NOLINT + a.Perform(std::make_tuple(2)); + EXPECT_TRUE(g_done); +} + +TEST(AssignTest, Int) { + int x = 0; + Action<void(int)> a = Assign(&x, 5); + a.Perform(std::make_tuple(0)); + EXPECT_EQ(5, x); +} + +TEST(AssignTest, String) { + ::std::string x; + Action<void(void)> a = Assign(&x, "Hello, world"); + a.Perform(std::make_tuple()); + EXPECT_EQ("Hello, world", x); +} + +TEST(AssignTest, CompatibleTypes) { + double x = 0; + Action<void(int)> a = Assign(&x, 5); + a.Perform(std::make_tuple(0)); + EXPECT_DOUBLE_EQ(5, x); +} + + +// Tests using WithArgs and with an action that takes 1 argument. +TEST(WithArgsTest, OneArg) { + Action<bool(double x, int n)> a = WithArgs<1>(Invoke(Unary)); // NOLINT + EXPECT_TRUE(a.Perform(std::make_tuple(1.5, -1))); + EXPECT_FALSE(a.Perform(std::make_tuple(1.5, 1))); +} + +// Tests using WithArgs with an action that takes 2 arguments. +TEST(WithArgsTest, TwoArgs) { + Action<const char*(const char* s, double x, short n)> a = // NOLINT + WithArgs<0, 2>(Invoke(Binary)); + const char s[] = "Hello"; + EXPECT_EQ(s + 2, a.Perform(std::make_tuple(CharPtr(s), 0.5, Short(2)))); +} + +struct ConcatAll { + std::string operator()() const { return {}; } + template <typename... I> + std::string operator()(const char* a, I... i) const { + return a + ConcatAll()(i...); + } +}; + +// Tests using WithArgs with an action that takes 10 arguments. +TEST(WithArgsTest, TenArgs) { + Action<std::string(const char*, const char*, const char*, const char*)> a = + WithArgs<0, 1, 2, 3, 2, 1, 0, 1, 2, 3>(Invoke(ConcatAll{})); + EXPECT_EQ("0123210123", + a.Perform(std::make_tuple(CharPtr("0"), CharPtr("1"), CharPtr("2"), + CharPtr("3")))); +} + +// Tests using WithArgs with an action that is not Invoke(). +class SubtractAction : public ActionInterface<int(int, int)> { + public: + int Perform(const std::tuple<int, int>& args) override { + return std::get<0>(args) - std::get<1>(args); + } +}; + +TEST(WithArgsTest, NonInvokeAction) { + Action<int(const std::string&, int, int)> a = + WithArgs<2, 1>(MakeAction(new SubtractAction)); + std::tuple<std::string, int, int> dummy = + std::make_tuple(std::string("hi"), 2, 10); + EXPECT_EQ(8, a.Perform(dummy)); +} + +// 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(std::make_tuple(100, Char(20), Short(3)))); +} + +// Tests using WithArgs with repeated arguments. +TEST(WithArgsTest, RepeatedArguments) { + Action<int(bool, int m, int n)> a = // NOLINT + WithArgs<1, 1, 1, 1>(Invoke(SumOf4)); + EXPECT_EQ(4, a.Perform(std::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(std::make_tuple(Short(2), CharPtr(s)))); +} + +// Tests using WithArgs with compatible, but not identical, argument types. +TEST(WithArgsTest, ArgsOfCompatibleTypes) { + Action<long(short x, char y, double z, char c)> a = // NOLINT + WithArgs<0, 1, 3>(Invoke(Ternary)); + EXPECT_EQ(123, + a.Perform(std::make_tuple(Short(100), Char(20), 5.6, Char(3)))); +} + +// Tests using WithArgs with an action that returns void. +TEST(WithArgsTest, VoidAction) { + Action<void(double x, char c, int n)> a = WithArgs<2, 1>(Invoke(VoidBinary)); + g_done = false; + a.Perform(std::make_tuple(1.5, 'a', 3)); + EXPECT_TRUE(g_done); +} + +TEST(WithArgsTest, ReturnReference) { + Action<int&(int&, void*)> aa = WithArgs<0>([](int& a) -> int& { return a; }); + int i = 0; + const int& res = aa.Perform(std::forward_as_tuple(i, nullptr)); + EXPECT_EQ(&i, &res); +} + +TEST(WithArgsTest, InnerActionWithConversion) { + Action<Derived*()> inner = [] { return nullptr; }; + Action<Base*(double)> a = testing::WithoutArgs(inner); + EXPECT_EQ(nullptr, a.Perform(std::make_tuple(1.1))); +} + +#if !GTEST_OS_WINDOWS_MOBILE + +class SetErrnoAndReturnTest : public testing::Test { + protected: + void SetUp() override { errno = 0; } + void TearDown() override { errno = 0; } +}; + +TEST_F(SetErrnoAndReturnTest, Int) { + Action<int(void)> a = SetErrnoAndReturn(ENOTTY, -5); + EXPECT_EQ(-5, a.Perform(std::make_tuple())); + EXPECT_EQ(ENOTTY, errno); +} + +TEST_F(SetErrnoAndReturnTest, Ptr) { + int x; + Action<int*(void)> a = SetErrnoAndReturn(ENOTTY, &x); + EXPECT_EQ(&x, a.Perform(std::make_tuple())); + EXPECT_EQ(ENOTTY, errno); +} + +TEST_F(SetErrnoAndReturnTest, CompatibleTypes) { + Action<double()> a = SetErrnoAndReturn(EINVAL, 5); + EXPECT_DOUBLE_EQ(5.0, a.Perform(std::make_tuple())); + EXPECT_EQ(EINVAL, errno); +} + +#endif // !GTEST_OS_WINDOWS_MOBILE + +// Tests ByRef(). + +// Tests that the result of ByRef() is copyable. +TEST(ByRefTest, IsCopyable) { + const std::string s1 = "Hi"; + const std::string s2 = "Hello"; + + auto ref_wrapper = ByRef(s1); + const std::string& r1 = ref_wrapper; + EXPECT_EQ(&s1, &r1); + + // Assigns a new value to ref_wrapper. + ref_wrapper = ByRef(s2); + const std::string& r2 = ref_wrapper; + EXPECT_EQ(&s2, &r2); + + auto ref_wrapper1 = ByRef(s1); + // Copies ref_wrapper1 to ref_wrapper. + ref_wrapper = ref_wrapper1; + const std::string& r3 = ref_wrapper; + EXPECT_EQ(&s1, &r3); +} + +// Tests using ByRef() on a const value. +TEST(ByRefTest, ConstValue) { + const int n = 0; + // int& ref = ByRef(n); // This shouldn't compile - we have a + // negative compilation test to catch it. + const int& const_ref = ByRef(n); + EXPECT_EQ(&n, &const_ref); +} + +// Tests using ByRef() on a non-const value. +TEST(ByRefTest, NonConstValue) { + int n = 0; + + // ByRef(n) can be used as either an int&, + int& ref = ByRef(n); + EXPECT_EQ(&n, &ref); + + // or a const int&. + const int& const_ref = ByRef(n); + EXPECT_EQ(&n, &const_ref); +} + +// Tests explicitly specifying the type when using ByRef(). +TEST(ByRefTest, ExplicitType) { + int n = 0; + const int& r1 = ByRef<const int>(n); + EXPECT_EQ(&n, &r1); + + // ByRef<char>(n); // This shouldn't compile - we have a negative + // compilation test to catch it. + + Derived d; + Derived& r2 = ByRef<Derived>(d); + EXPECT_EQ(&d, &r2); + + const Derived& r3 = ByRef<const Derived>(d); + EXPECT_EQ(&d, &r3); + + Base& r4 = ByRef<Base>(d); + EXPECT_EQ(&d, &r4); + + const Base& r5 = ByRef<const Base>(d); + EXPECT_EQ(&d, &r5); + + // The following shouldn't compile - we have a negative compilation + // test for it. + // + // Base b; + // ByRef<Derived>(b); +} + +// Tests that Google Mock prints expression ByRef(x) as a reference to x. +TEST(ByRefTest, PrintsCorrectly) { + int n = 42; + ::std::stringstream expected, actual; + testing::internal::UniversalPrinter<const int&>::Print(n, &expected); + testing::internal::UniversalPrint(ByRef(n), &actual); + EXPECT_EQ(expected.str(), actual.str()); +} + +struct UnaryConstructorClass { + explicit UnaryConstructorClass(int v) : value(v) {} + int value; +}; + +// Tests using ReturnNew() with a unary constructor. +TEST(ReturnNewTest, Unary) { + Action<UnaryConstructorClass*()> a = ReturnNew<UnaryConstructorClass>(4000); + UnaryConstructorClass* c = a.Perform(std::make_tuple()); + EXPECT_EQ(4000, c->value); + delete c; +} + +TEST(ReturnNewTest, UnaryWorksWhenMockMethodHasArgs) { + Action<UnaryConstructorClass*(bool, int)> a = + ReturnNew<UnaryConstructorClass>(4000); + UnaryConstructorClass* c = a.Perform(std::make_tuple(false, 5)); + EXPECT_EQ(4000, c->value); + delete c; +} + +TEST(ReturnNewTest, UnaryWorksWhenMockMethodReturnsPointerToConst) { + Action<const UnaryConstructorClass*()> a = + ReturnNew<UnaryConstructorClass>(4000); + const UnaryConstructorClass* c = a.Perform(std::make_tuple()); + EXPECT_EQ(4000, c->value); + delete c; +} + +class TenArgConstructorClass { + public: + TenArgConstructorClass(int a1, int a2, int a3, int a4, int a5, int a6, int a7, + int a8, int a9, int a10) + : value_(a1 + a2 + a3 + a4 + a5 + a6 + a7 + a8 + a9 + a10) {} + int value_; +}; + +// Tests using ReturnNew() with a 10-argument constructor. +TEST(ReturnNewTest, ConstructorThatTakes10Arguments) { + Action<TenArgConstructorClass*()> a = ReturnNew<TenArgConstructorClass>( + 1000000000, 200000000, 30000000, 4000000, 500000, 60000, 7000, 800, 90, + 0); + TenArgConstructorClass* c = a.Perform(std::make_tuple()); + EXPECT_EQ(1234567890, c->value_); + delete c; +} + +std::unique_ptr<int> UniquePtrSource() { + return std::unique_ptr<int>(new int(19)); +} + +std::vector<std::unique_ptr<int>> VectorUniquePtrSource() { + std::vector<std::unique_ptr<int>> out; + out.emplace_back(new int(7)); + return out; +} + +TEST(MockMethodTest, CanReturnMoveOnlyValue_Return) { + MockClass mock; + std::unique_ptr<int> i(new int(19)); + EXPECT_CALL(mock, MakeUnique()).WillOnce(Return(ByMove(std::move(i)))); + EXPECT_CALL(mock, MakeVectorUnique()) + .WillOnce(Return(ByMove(VectorUniquePtrSource()))); + Derived* d = new Derived; + EXPECT_CALL(mock, MakeUniqueBase()) + .WillOnce(Return(ByMove(std::unique_ptr<Derived>(d)))); + + std::unique_ptr<int> result1 = mock.MakeUnique(); + EXPECT_EQ(19, *result1); + + std::vector<std::unique_ptr<int>> vresult = mock.MakeVectorUnique(); + EXPECT_EQ(1u, vresult.size()); + EXPECT_NE(nullptr, vresult[0]); + EXPECT_EQ(7, *vresult[0]); + + std::unique_ptr<Base> result2 = mock.MakeUniqueBase(); + EXPECT_EQ(d, result2.get()); +} + +TEST(MockMethodTest, CanReturnMoveOnlyValue_DoAllReturn) { + testing::MockFunction<void()> mock_function; + MockClass mock; + std::unique_ptr<int> i(new int(19)); + EXPECT_CALL(mock_function, Call()); + EXPECT_CALL(mock, MakeUnique()).WillOnce(DoAll( + InvokeWithoutArgs(&mock_function, &testing::MockFunction<void()>::Call), + Return(ByMove(std::move(i))))); + + std::unique_ptr<int> result1 = mock.MakeUnique(); + EXPECT_EQ(19, *result1); +} + +TEST(MockMethodTest, CanReturnMoveOnlyValue_Invoke) { + MockClass mock; + + // Check default value + DefaultValue<std::unique_ptr<int>>::SetFactory([] { + return std::unique_ptr<int>(new int(42)); + }); + EXPECT_EQ(42, *mock.MakeUnique()); + + EXPECT_CALL(mock, MakeUnique()).WillRepeatedly(Invoke(UniquePtrSource)); + EXPECT_CALL(mock, MakeVectorUnique()) + .WillRepeatedly(Invoke(VectorUniquePtrSource)); + std::unique_ptr<int> result1 = mock.MakeUnique(); + EXPECT_EQ(19, *result1); + std::unique_ptr<int> result2 = mock.MakeUnique(); + EXPECT_EQ(19, *result2); + EXPECT_NE(result1, result2); + + std::vector<std::unique_ptr<int>> vresult = mock.MakeVectorUnique(); + EXPECT_EQ(1u, vresult.size()); + EXPECT_NE(nullptr, vresult[0]); + EXPECT_EQ(7, *vresult[0]); +} + +TEST(MockMethodTest, CanTakeMoveOnlyValue) { + MockClass mock; + auto make = [](int i) { return std::unique_ptr<int>(new int(i)); }; + + EXPECT_CALL(mock, TakeUnique(_)).WillRepeatedly([](std::unique_ptr<int> i) { + return *i; + }); + // DoAll() does not compile, since it would move from its arguments twice. + // EXPECT_CALL(mock, TakeUnique(_, _)) + // .WillRepeatedly(DoAll(Invoke([](std::unique_ptr<int> j) {}), + // Return(1))); + EXPECT_CALL(mock, TakeUnique(testing::Pointee(7))) + .WillOnce(Return(-7)) + .RetiresOnSaturation(); + EXPECT_CALL(mock, TakeUnique(testing::IsNull())) + .WillOnce(Return(-1)) + .RetiresOnSaturation(); + + EXPECT_EQ(5, mock.TakeUnique(make(5))); + EXPECT_EQ(-7, mock.TakeUnique(make(7))); + EXPECT_EQ(7, mock.TakeUnique(make(7))); + EXPECT_EQ(7, mock.TakeUnique(make(7))); + EXPECT_EQ(-1, mock.TakeUnique({})); + + // Some arguments are moved, some passed by reference. + auto lvalue = make(6); + EXPECT_CALL(mock, TakeUnique(_, _)) + .WillOnce([](const std::unique_ptr<int>& i, std::unique_ptr<int> j) { + return *i * *j; + }); + EXPECT_EQ(42, mock.TakeUnique(lvalue, make(7))); + + // The unique_ptr can be saved by the action. + std::unique_ptr<int> saved; + EXPECT_CALL(mock, TakeUnique(_)).WillOnce([&saved](std::unique_ptr<int> i) { + saved = std::move(i); + return 0; + }); + EXPECT_EQ(0, mock.TakeUnique(make(42))); + EXPECT_EQ(42, *saved); +} + + +// Tests for std::function based action. + +int Add(int val, int& ref, int* ptr) { // NOLINT + int result = val + ref + *ptr; + ref = 42; + *ptr = 43; + return result; +} + +int Deref(std::unique_ptr<int> ptr) { return *ptr; } + +struct Double { + template <typename T> + T operator()(T t) { return 2 * t; } +}; + +std::unique_ptr<int> UniqueInt(int i) { + return std::unique_ptr<int>(new int(i)); +} + +TEST(FunctorActionTest, ActionFromFunction) { + Action<int(int, int&, int*)> a = &Add; + int x = 1, y = 2, z = 3; + EXPECT_EQ(6, a.Perform(std::forward_as_tuple(x, y, &z))); + EXPECT_EQ(42, y); + EXPECT_EQ(43, z); + + Action<int(std::unique_ptr<int>)> a1 = &Deref; + EXPECT_EQ(7, a1.Perform(std::make_tuple(UniqueInt(7)))); +} + +TEST(FunctorActionTest, ActionFromLambda) { + Action<int(bool, int)> a1 = [](bool b, int i) { return b ? i : 0; }; + EXPECT_EQ(5, a1.Perform(std::make_tuple(true, 5))); + EXPECT_EQ(0, a1.Perform(std::make_tuple(false, 5))); + + std::unique_ptr<int> saved; + Action<void(std::unique_ptr<int>)> a2 = [&saved](std::unique_ptr<int> p) { + saved = std::move(p); + }; + a2.Perform(std::make_tuple(UniqueInt(5))); + EXPECT_EQ(5, *saved); +} + +TEST(FunctorActionTest, PolymorphicFunctor) { + Action<int(int)> ai = Double(); + EXPECT_EQ(2, ai.Perform(std::make_tuple(1))); + Action<double(double)> ad = Double(); // Double? Double double! + EXPECT_EQ(3.0, ad.Perform(std::make_tuple(1.5))); +} + +TEST(FunctorActionTest, TypeConversion) { + // Numeric promotions are allowed. + const Action<bool(int)> a1 = [](int i) { return i > 1; }; + const Action<int(bool)> a2 = Action<int(bool)>(a1); + EXPECT_EQ(1, a1.Perform(std::make_tuple(42))); + EXPECT_EQ(0, a2.Perform(std::make_tuple(42))); + + // Implicit constructors are allowed. + const Action<bool(std::string)> s1 = [](std::string s) { return !s.empty(); }; + const Action<int(const char*)> s2 = Action<int(const char*)>(s1); + EXPECT_EQ(0, s2.Perform(std::make_tuple(""))); + EXPECT_EQ(1, s2.Perform(std::make_tuple("hello"))); + + // Also between the lambda and the action itself. + const Action<bool(std::string)> x1 = [](Unused) { return 42; }; + const Action<bool(std::string)> x2 = [] { return 42; }; + EXPECT_TRUE(x1.Perform(std::make_tuple("hello"))); + EXPECT_TRUE(x2.Perform(std::make_tuple("hello"))); + + // Ensure decay occurs where required. + std::function<int()> f = [] { return 7; }; + Action<int(int)> d = f; + f = nullptr; + EXPECT_EQ(7, d.Perform(std::make_tuple(1))); + + // Ensure creation of an empty action succeeds. + Action<void(int)>(nullptr); +} + +TEST(FunctorActionTest, UnusedArguments) { + // Verify that users can ignore uninteresting arguments. + Action<int(int, double y, double z)> a = + [](int i, Unused, Unused) { return 2 * i; }; + std::tuple<int, double, double> dummy = std::make_tuple(3, 7.3, 9.44); + EXPECT_EQ(6, a.Perform(dummy)); +} + +// Test that basic built-in actions work with move-only arguments. +TEST(MoveOnlyArgumentsTest, ReturningActions) { + Action<int(std::unique_ptr<int>)> a = Return(1); + EXPECT_EQ(1, a.Perform(std::make_tuple(nullptr))); + + a = testing::WithoutArgs([]() { return 7; }); + EXPECT_EQ(7, a.Perform(std::make_tuple(nullptr))); + + Action<void(std::unique_ptr<int>, int*)> a2 = testing::SetArgPointee<1>(3); + int x = 0; + a2.Perform(std::make_tuple(nullptr, &x)); + EXPECT_EQ(x, 3); +} + +ACTION(ReturnArity) { + return std::tuple_size<args_type>::value; +} + +TEST(ActionMacro, LargeArity) { + EXPECT_EQ( + 1, testing::Action<int(int)>(ReturnArity()).Perform(std::make_tuple(0))); + EXPECT_EQ( + 10, + testing::Action<int(int, int, int, int, int, int, int, int, int, int)>( + ReturnArity()) + .Perform(std::make_tuple(0, 1, 2, 3, 4, 5, 6, 7, 8, 9))); + EXPECT_EQ( + 20, + testing::Action<int(int, int, int, int, int, int, int, int, int, int, int, + int, int, int, int, int, int, int, int, int)>( + ReturnArity()) + .Perform(std::make_tuple(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, + 14, 15, 16, 17, 18, 19))); +} + +} // Unnamed namespace + +#ifdef _MSC_VER +#if _MSC_VER == 1900 +# pragma warning(pop) +#endif +#endif + diff --git a/src/googletest/googlemock/test/gmock-cardinalities_test.cc b/src/googletest/googlemock/test/gmock-cardinalities_test.cc new file mode 100644 index 000000000..ca97cae24 --- /dev/null +++ b/src/googletest/googlemock/test/gmock-cardinalities_test.cc @@ -0,0 +1,429 @@ +// 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. + + +// 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: + MockFoo() {} + MOCK_METHOD0(Bar, int()); // NOLINT + + private: + GTEST_DISALLOW_COPY_AND_ASSIGN_(MockFoo); +}; + +// 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 their own cardinality by implementing +// CardinalityInterface and calling MakeCardinality(). + +class EvenCardinality : public CardinalityInterface { + public: + // Returns true if and only if call_count calls will satisfy this + // cardinality. + bool IsSatisfiedByCallCount(int call_count) const override { + return (call_count % 2 == 0); + } + + // Returns true if and only if call_count calls will saturate this + // cardinality. + bool IsSaturatedByCallCount(int /* call_count */) const override { + return false; + } + + // Describes self to an ostream. + void DescribeTo(::std::ostream* ss) const override { + *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/src/googletest/googlemock/test/gmock-function-mocker_nc.cc b/src/googletest/googlemock/test/gmock-function-mocker_nc.cc new file mode 100644 index 000000000..d38fe85ef --- /dev/null +++ b/src/googletest/googlemock/test/gmock-function-mocker_nc.cc @@ -0,0 +1,16 @@ +#include "gmock/gmock.h" + +#include <memory> +#include <string> + +#if defined(TEST_MOCK_METHOD_INVALID_CONST_SPEC) + +struct Base { + MOCK_METHOD(int, F, (), (onst)); +}; + +#else + +// Sanity check - this should compile. + +#endif diff --git a/src/googletest/googlemock/test/gmock-function-mocker_nc_test.py b/src/googletest/googlemock/test/gmock-function-mocker_nc_test.py new file mode 100644 index 000000000..8ef6e09fa --- /dev/null +++ b/src/googletest/googlemock/test/gmock-function-mocker_nc_test.py @@ -0,0 +1,43 @@ +"""Negative compilation tests for Google Mock macro MOCK_METHOD.""" + +import os +import sys + +IS_LINUX = os.name == "posix" and os.uname()[0] == "Linux" +if not IS_LINUX: + sys.stderr.write( + "WARNING: Negative compilation tests are not supported on this platform") + sys.exit(0) + +# Suppresses the 'Import not at the top of the file' lint complaint. +# pylint: disable-msg=C6204 +from google3.testing.pybase import fake_target_util +from google3.testing.pybase import googletest + +# pylint: enable-msg=C6204 + + +class GMockMethodNCTest(googletest.TestCase): + """Negative compilation tests for MOCK_METHOD.""" + + # The class body is intentionally empty. The actual test*() methods + # will be defined at run time by a call to + # DefineNegativeCompilationTests() later. + pass + + +# Defines a list of test specs, where each element is a tuple +# (test name, list of regexes for matching the compiler errors). +TEST_SPECS = [ + ("MOCK_METHOD_INVALID_CONST_SPEC", + [r"onst cannot be recognized as a valid specification modifier"]), +] + +# Define a test method in GMockNCTest for each element in TEST_SPECS. +fake_target_util.DefineNegativeCompilationTests( + GMockMethodNCTest, + "google3/third_party/googletest/googlemock/test/gmock-function-mocker_nc", + "gmock-function-mocker_nc.o", TEST_SPECS) + +if __name__ == "__main__": + googletest.main() diff --git a/src/googletest/googlemock/test/gmock-function-mocker_test.cc b/src/googletest/googlemock/test/gmock-function-mocker_test.cc new file mode 100644 index 000000000..45a524e20 --- /dev/null +++ b/src/googletest/googlemock/test/gmock-function-mocker_test.cc @@ -0,0 +1,974 @@ +// 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. + + +// Google Mock - a framework for writing C++ mock classes. +// +// This file tests the function mocker classes. +#include "gmock/gmock-function-mocker.h" + +#if 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 + +#include <functional> +#include <map> +#include <string> +#include <type_traits> + +#include "gmock/gmock.h" +#include "gtest/gtest.h" + +namespace testing { +namespace gmock_function_mocker_test { + +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::MockFunction; +using testing::Ref; +using testing::Return; +using testing::ReturnRef; +using testing::TypedEq; + +template<typename T> +class TemplatedCopyable { + public: + TemplatedCopyable() {} + + template <typename U> + TemplatedCopyable(const U& other) {} // NOLINT +}; + +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 std::string& k) = 0; + + virtual bool TakesNonConstReference(int& n) = 0; // NOLINT + virtual std::string TakesConstReference(const int& n) = 0; + virtual bool TakesConst(const int x) = 0; + + 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, std::string>& a_map) = 0; + virtual int TypeWithTemplatedCopyCtor(const TemplatedCopyable<int>&) = 0; + + virtual int (*ReturnsFunctionPointer1(int))(bool) = 0; + using fn_ptr = int (*)(bool); + virtual fn_ptr ReturnsFunctionPointer2(int) = 0; + + virtual int RefQualifiedConstRef() const& = 0; + virtual int RefQualifiedConstRefRef() const&& = 0; + virtual int RefQualifiedRef() & = 0; + virtual int RefQualifiedRefRef() && = 0; + + virtual int RefQualifiedOverloaded() const& = 0; + virtual int RefQualifiedOverloaded() const&& = 0; + virtual int RefQualifiedOverloaded() & = 0; + virtual int RefQualifiedOverloaded() && = 0; + +#if 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 std::string& k) = 0; + STDMETHOD_(char, CTConst)(int x) const = 0; +#endif // GTEST_OS_WINDOWS +}; + +// Const qualifiers on arguments were once (incorrectly) considered +// significant in determining whether two virtual functions had the same +// signature. This was fixed in Visual Studio 2008. However, the compiler +// still emits a warning that alerts about this change in behavior. +#ifdef _MSC_VER +# pragma warning(push) +# pragma warning(disable : 4373) +#endif +class MockFoo : public FooInterface { + public: + MockFoo() {} + + // Makes sure that a mock function parameter can be named. + MOCK_METHOD(void, VoidReturning, (int n)); // NOLINT + + MOCK_METHOD(int, Nullary, ()); // NOLINT + + // Makes sure that a mock function parameter can be unnamed. + MOCK_METHOD(bool, Unary, (int)); // NOLINT + MOCK_METHOD(long, Binary, (short, int)); // NOLINT + MOCK_METHOD(int, Decimal, + (bool, char, short, int, long, float, // NOLINT + double, unsigned, char*, const std::string& str), + (override)); + + MOCK_METHOD(bool, TakesNonConstReference, (int&)); // NOLINT + MOCK_METHOD(std::string, TakesConstReference, (const int&)); + MOCK_METHOD(bool, TakesConst, (const int)); // NOLINT + + // Tests that the function return type can contain unprotected comma. + MOCK_METHOD((std::map<int, std::string>), ReturnTypeWithComma, (), ()); + MOCK_METHOD((std::map<int, std::string>), ReturnTypeWithComma, (int), + (const)); // NOLINT + + MOCK_METHOD(int, OverloadedOnArgumentNumber, ()); // NOLINT + MOCK_METHOD(int, OverloadedOnArgumentNumber, (int)); // NOLINT + + MOCK_METHOD(int, OverloadedOnArgumentType, (int)); // NOLINT + MOCK_METHOD(char, OverloadedOnArgumentType, (char)); // NOLINT + + MOCK_METHOD(int, OverloadedOnConstness, (), (override)); // NOLINT + MOCK_METHOD(char, OverloadedOnConstness, (), (override, const)); // NOLINT + + MOCK_METHOD(int, TypeWithHole, (int (*)()), ()); // NOLINT + MOCK_METHOD(int, TypeWithComma, ((const std::map<int, std::string>&))); + MOCK_METHOD(int, TypeWithTemplatedCopyCtor, + (const TemplatedCopyable<int>&)); // NOLINT + + MOCK_METHOD(int (*)(bool), ReturnsFunctionPointer1, (int), ()); + MOCK_METHOD(fn_ptr, ReturnsFunctionPointer2, (int), ()); + +#if GTEST_OS_WINDOWS + MOCK_METHOD(int, CTNullary, (), (Calltype(STDMETHODCALLTYPE))); + MOCK_METHOD(bool, CTUnary, (int), (Calltype(STDMETHODCALLTYPE))); + MOCK_METHOD(int, CTDecimal, + (bool b, char c, short d, int e, long f, float g, double h, + unsigned i, char* j, const std::string& k), + (Calltype(STDMETHODCALLTYPE))); + MOCK_METHOD(char, CTConst, (int), (const, Calltype(STDMETHODCALLTYPE))); + MOCK_METHOD((std::map<int, std::string>), CTReturnTypeWithComma, (), + (Calltype(STDMETHODCALLTYPE))); +#endif // GTEST_OS_WINDOWS + + // Test reference qualified functions. + MOCK_METHOD(int, RefQualifiedConstRef, (), (const, ref(&), override)); + MOCK_METHOD(int, RefQualifiedConstRefRef, (), (const, ref(&&), override)); + MOCK_METHOD(int, RefQualifiedRef, (), (ref(&), override)); + MOCK_METHOD(int, RefQualifiedRefRef, (), (ref(&&), override)); + + MOCK_METHOD(int, RefQualifiedOverloaded, (), (const, ref(&), override)); + MOCK_METHOD(int, RefQualifiedOverloaded, (), (const, ref(&&), override)); + MOCK_METHOD(int, RefQualifiedOverloaded, (), (ref(&), override)); + MOCK_METHOD(int, RefQualifiedOverloaded, (), (ref(&&), override)); + + private: + GTEST_DISALLOW_COPY_AND_ASSIGN_(MockFoo); +}; + +class LegacyMockFoo : public FooInterface { + public: + LegacyMockFoo() {} + + // 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 std::string& str)); + + MOCK_METHOD1(TakesNonConstReference, bool(int&)); // NOLINT + MOCK_METHOD1(TakesConstReference, std::string(const int&)); + MOCK_METHOD1(TakesConst, bool(const int)); // NOLINT + + // Tests that the function return type can contain unprotected comma. + MOCK_METHOD0(ReturnTypeWithComma, std::map<int, std::string>()); + MOCK_CONST_METHOD1(ReturnTypeWithComma, + std::map<int, std::string>(int)); // NOLINT + + 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, std::string>&)); // NOLINT + MOCK_METHOD1(TypeWithTemplatedCopyCtor, + int(const TemplatedCopyable<int>&)); // NOLINT + + MOCK_METHOD1(ReturnsFunctionPointer1, int (*(int))(bool)); + MOCK_METHOD1(ReturnsFunctionPointer2, fn_ptr(int)); + +#if GTEST_OS_WINDOWS + MOCK_METHOD0_WITH_CALLTYPE(STDMETHODCALLTYPE, CTNullary, int()); + MOCK_METHOD1_WITH_CALLTYPE(STDMETHODCALLTYPE, CTUnary, bool(int)); // NOLINT + MOCK_METHOD10_WITH_CALLTYPE(STDMETHODCALLTYPE, CTDecimal, + int(bool b, char c, short d, int e, // NOLINT + long f, float g, double h, // NOLINT + unsigned i, char* j, const std::string& k)); + MOCK_CONST_METHOD1_WITH_CALLTYPE(STDMETHODCALLTYPE, CTConst, + char(int)); // NOLINT + + // Tests that the function return type can contain unprotected comma. + MOCK_METHOD0_WITH_CALLTYPE(STDMETHODCALLTYPE, CTReturnTypeWithComma, + std::map<int, std::string>()); +#endif // GTEST_OS_WINDOWS + + // We can't mock these with the old macros, but we need to define them to make + // it concrete. + int RefQualifiedConstRef() const& override { return 0; } + int RefQualifiedConstRefRef() const&& override { return 0; } + int RefQualifiedRef() & override { return 0; } + int RefQualifiedRefRef() && override { return 0; } + int RefQualifiedOverloaded() const& override { return 0; } + int RefQualifiedOverloaded() const&& override { return 0; } + int RefQualifiedOverloaded() & override { return 0; } + int RefQualifiedOverloaded() && override { return 0; } + + private: + GTEST_DISALLOW_COPY_AND_ASSIGN_(LegacyMockFoo); +}; + +#ifdef _MSC_VER +# pragma warning(pop) +#endif + +template <class T> +class FunctionMockerTest : public testing::Test { + protected: + FunctionMockerTest() : foo_(&mock_foo_) {} + + FooInterface* const foo_; + T mock_foo_; +}; +using FunctionMockerTestTypes = ::testing::Types<MockFoo, LegacyMockFoo>; +TYPED_TEST_SUITE(FunctionMockerTest, FunctionMockerTestTypes); + +// Tests mocking a void-returning function. +TYPED_TEST(FunctionMockerTest, MocksVoidFunction) { + EXPECT_CALL(this->mock_foo_, VoidReturning(Lt(100))); + this->foo_->VoidReturning(0); +} + +// Tests mocking a nullary function. +TYPED_TEST(FunctionMockerTest, MocksNullaryFunction) { + EXPECT_CALL(this->mock_foo_, Nullary()) + .WillOnce(DoDefault()) + .WillOnce(Return(1)); + + EXPECT_EQ(0, this->foo_->Nullary()); + EXPECT_EQ(1, this->foo_->Nullary()); +} + +// Tests mocking a unary function. +TYPED_TEST(FunctionMockerTest, MocksUnaryFunction) { + EXPECT_CALL(this->mock_foo_, Unary(Eq(2))).Times(2).WillOnce(Return(true)); + + EXPECT_TRUE(this->foo_->Unary(2)); + EXPECT_FALSE(this->foo_->Unary(2)); +} + +// Tests mocking a binary function. +TYPED_TEST(FunctionMockerTest, MocksBinaryFunction) { + EXPECT_CALL(this->mock_foo_, Binary(2, _)).WillOnce(Return(3)); + + EXPECT_EQ(3, this->foo_->Binary(2, 1)); +} + +// Tests mocking a decimal function. +TYPED_TEST(FunctionMockerTest, MocksDecimalFunction) { + EXPECT_CALL(this->mock_foo_, + Decimal(true, 'a', 0, 0, 1L, A<float>(), Lt(100), 5U, NULL, "hi")) + .WillOnce(Return(5)); + + EXPECT_EQ(5, this->foo_->Decimal(true, 'a', 0, 0, 1, 0, 0, 5, nullptr, "hi")); +} + +// Tests mocking a function that takes a non-const reference. +TYPED_TEST(FunctionMockerTest, MocksFunctionWithNonConstReferenceArgument) { + int a = 0; + EXPECT_CALL(this->mock_foo_, TakesNonConstReference(Ref(a))) + .WillOnce(Return(true)); + + EXPECT_TRUE(this->foo_->TakesNonConstReference(a)); +} + +// Tests mocking a function that takes a const reference. +TYPED_TEST(FunctionMockerTest, MocksFunctionWithConstReferenceArgument) { + int a = 0; + EXPECT_CALL(this->mock_foo_, TakesConstReference(Ref(a))) + .WillOnce(Return("Hello")); + + EXPECT_EQ("Hello", this->foo_->TakesConstReference(a)); +} + +// Tests mocking a function that takes a const variable. +TYPED_TEST(FunctionMockerTest, MocksFunctionWithConstArgument) { + EXPECT_CALL(this->mock_foo_, TakesConst(Lt(10))).WillOnce(DoDefault()); + + EXPECT_FALSE(this->foo_->TakesConst(5)); +} + +// Tests mocking functions overloaded on the number of arguments. +TYPED_TEST(FunctionMockerTest, MocksFunctionsOverloadedOnArgumentNumber) { + EXPECT_CALL(this->mock_foo_, OverloadedOnArgumentNumber()) + .WillOnce(Return(1)); + EXPECT_CALL(this->mock_foo_, OverloadedOnArgumentNumber(_)) + .WillOnce(Return(2)); + + EXPECT_EQ(2, this->foo_->OverloadedOnArgumentNumber(1)); + EXPECT_EQ(1, this->foo_->OverloadedOnArgumentNumber()); +} + +// Tests mocking functions overloaded on the types of argument. +TYPED_TEST(FunctionMockerTest, MocksFunctionsOverloadedOnArgumentType) { + EXPECT_CALL(this->mock_foo_, OverloadedOnArgumentType(An<int>())) + .WillOnce(Return(1)); + EXPECT_CALL(this->mock_foo_, OverloadedOnArgumentType(TypedEq<char>('a'))) + .WillOnce(Return('b')); + + EXPECT_EQ(1, this->foo_->OverloadedOnArgumentType(0)); + EXPECT_EQ('b', this->foo_->OverloadedOnArgumentType('a')); +} + +// Tests mocking functions overloaded on the const-ness of this object. +TYPED_TEST(FunctionMockerTest, MocksFunctionsOverloadedOnConstnessOfThis) { + EXPECT_CALL(this->mock_foo_, OverloadedOnConstness()); + EXPECT_CALL(Const(this->mock_foo_), OverloadedOnConstness()) + .WillOnce(Return('a')); + + EXPECT_EQ(0, this->foo_->OverloadedOnConstness()); + EXPECT_EQ('a', Const(*this->foo_).OverloadedOnConstness()); +} + +TYPED_TEST(FunctionMockerTest, MocksReturnTypeWithComma) { + const std::map<int, std::string> a_map; + EXPECT_CALL(this->mock_foo_, ReturnTypeWithComma()).WillOnce(Return(a_map)); + EXPECT_CALL(this->mock_foo_, ReturnTypeWithComma(42)).WillOnce(Return(a_map)); + + EXPECT_EQ(a_map, this->mock_foo_.ReturnTypeWithComma()); + EXPECT_EQ(a_map, this->mock_foo_.ReturnTypeWithComma(42)); +} + +TYPED_TEST(FunctionMockerTest, MocksTypeWithTemplatedCopyCtor) { + EXPECT_CALL(this->mock_foo_, TypeWithTemplatedCopyCtor(_)) + .WillOnce(Return(true)); + EXPECT_TRUE(this->foo_->TypeWithTemplatedCopyCtor(TemplatedCopyable<int>())); +} + +#if GTEST_OS_WINDOWS +// Tests mocking a nullary function with calltype. +TYPED_TEST(FunctionMockerTest, MocksNullaryFunctionWithCallType) { + EXPECT_CALL(this->mock_foo_, CTNullary()) + .WillOnce(Return(-1)) + .WillOnce(Return(0)); + + EXPECT_EQ(-1, this->foo_->CTNullary()); + EXPECT_EQ(0, this->foo_->CTNullary()); +} + +// Tests mocking a unary function with calltype. +TYPED_TEST(FunctionMockerTest, MocksUnaryFunctionWithCallType) { + EXPECT_CALL(this->mock_foo_, CTUnary(Eq(2))) + .Times(2) + .WillOnce(Return(true)) + .WillOnce(Return(false)); + + EXPECT_TRUE(this->foo_->CTUnary(2)); + EXPECT_FALSE(this->foo_->CTUnary(2)); +} + +// Tests mocking a decimal function with calltype. +TYPED_TEST(FunctionMockerTest, MocksDecimalFunctionWithCallType) { + EXPECT_CALL(this->mock_foo_, CTDecimal(true, 'a', 0, 0, 1L, A<float>(), + Lt(100), 5U, NULL, "hi")) + .WillOnce(Return(10)); + + EXPECT_EQ(10, this->foo_->CTDecimal(true, 'a', 0, 0, 1, 0, 0, 5, NULL, "hi")); +} + +// Tests mocking functions overloaded on the const-ness of this object. +TYPED_TEST(FunctionMockerTest, MocksFunctionsConstFunctionWithCallType) { + EXPECT_CALL(Const(this->mock_foo_), CTConst(_)).WillOnce(Return('a')); + + EXPECT_EQ('a', Const(*this->foo_).CTConst(0)); +} + +TYPED_TEST(FunctionMockerTest, MocksReturnTypeWithCommaAndCallType) { + const std::map<int, std::string> a_map; + EXPECT_CALL(this->mock_foo_, CTReturnTypeWithComma()).WillOnce(Return(a_map)); + + EXPECT_EQ(a_map, this->mock_foo_.CTReturnTypeWithComma()); +} + +#endif // GTEST_OS_WINDOWS + +TEST(FunctionMockerTest, RefQualified) { + MockFoo mock_foo; + + EXPECT_CALL(mock_foo, RefQualifiedConstRef).WillOnce(Return(1)); + EXPECT_CALL(std::move(mock_foo), // NOLINT + RefQualifiedConstRefRef) + .WillOnce(Return(2)); + EXPECT_CALL(mock_foo, RefQualifiedRef).WillOnce(Return(3)); + EXPECT_CALL(std::move(mock_foo), // NOLINT + RefQualifiedRefRef) + .WillOnce(Return(4)); + + EXPECT_CALL(static_cast<const MockFoo&>(mock_foo), RefQualifiedOverloaded()) + .WillOnce(Return(5)); + EXPECT_CALL(static_cast<const MockFoo&&>(mock_foo), RefQualifiedOverloaded()) + .WillOnce(Return(6)); + EXPECT_CALL(static_cast<MockFoo&>(mock_foo), RefQualifiedOverloaded()) + .WillOnce(Return(7)); + EXPECT_CALL(static_cast<MockFoo&&>(mock_foo), RefQualifiedOverloaded()) + .WillOnce(Return(8)); + + EXPECT_EQ(mock_foo.RefQualifiedConstRef(), 1); + EXPECT_EQ(std::move(mock_foo).RefQualifiedConstRefRef(), 2); // NOLINT + EXPECT_EQ(mock_foo.RefQualifiedRef(), 3); + EXPECT_EQ(std::move(mock_foo).RefQualifiedRefRef(), 4); // NOLINT + + EXPECT_EQ(std::cref(mock_foo).get().RefQualifiedOverloaded(), 5); + EXPECT_EQ(std::move(std::cref(mock_foo).get()) // NOLINT + .RefQualifiedOverloaded(), + 6); + EXPECT_EQ(mock_foo.RefQualifiedOverloaded(), 7); + EXPECT_EQ(std::move(mock_foo).RefQualifiedOverloaded(), 8); // NOLINT +} + +class MockB { + public: + MockB() {} + + MOCK_METHOD(void, DoB, ()); + + private: + GTEST_DISALLOW_COPY_AND_ASSIGN_(MockB); +}; + +class LegacyMockB { + public: + LegacyMockB() {} + + MOCK_METHOD0(DoB, void()); + + private: + GTEST_DISALLOW_COPY_AND_ASSIGN_(LegacyMockB); +}; + +template <typename T> +class ExpectCallTest : public ::testing::Test {}; +using ExpectCallTestTypes = ::testing::Types<MockB, LegacyMockB>; +TYPED_TEST_SUITE(ExpectCallTest, ExpectCallTestTypes); + +// Tests that functions with no EXPECT_CALL() rules can be called any +// number of times. +TYPED_TEST(ExpectCallTest, UnmentionedFunctionCanBeCalledAnyNumberOfTimes) { + { TypeParam b; } + + { + TypeParam b; + b.DoB(); + } + + { + TypeParam 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: + MockStack() {} + + MOCK_METHOD(void, Push, (const T& elem), ()); + MOCK_METHOD(void, Pop, (), (final)); + MOCK_METHOD(int, GetSize, (), (const, override)); + MOCK_METHOD(const T&, GetTop, (), (const)); + + // Tests that the function return type can contain unprotected comma. + MOCK_METHOD((std::map<int, int>), ReturnTypeWithComma, (), ()); + MOCK_METHOD((std::map<int, int>), ReturnTypeWithComma, (int), (const)); + + private: + GTEST_DISALLOW_COPY_AND_ASSIGN_(MockStack); +}; + +template <typename T> +class LegacyMockStack : public StackInterface<T> { + public: + LegacyMockStack() {} + + 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 the function return type can contain unprotected comma. + MOCK_METHOD0_T(ReturnTypeWithComma, std::map<int, int>()); + MOCK_CONST_METHOD1_T(ReturnTypeWithComma, std::map<int, int>(int)); // NOLINT + + private: + GTEST_DISALLOW_COPY_AND_ASSIGN_(LegacyMockStack); +}; + +template <typename T> +class TemplateMockTest : public ::testing::Test {}; +using TemplateMockTestTypes = + ::testing::Types<MockStack<int>, LegacyMockStack<int>>; +TYPED_TEST_SUITE(TemplateMockTest, TemplateMockTestTypes); + +// Tests that template mock works. +TYPED_TEST(TemplateMockTest, Works) { + TypeParam 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()); +} + +TYPED_TEST(TemplateMockTest, MethodWithCommaInReturnTypeWorks) { + TypeParam mock; + + const std::map<int, int> a_map; + EXPECT_CALL(mock, ReturnTypeWithComma()) + .WillOnce(Return(a_map)); + EXPECT_CALL(mock, ReturnTypeWithComma(1)) + .WillOnce(Return(a_map)); + + EXPECT_EQ(a_map, mock.ReturnTypeWithComma()); + EXPECT_EQ(a_map, mock.ReturnTypeWithComma(1)); +} + +#if 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: + MockStackWithCallType() {} + + MOCK_METHOD(void, Push, (const T& elem), + (Calltype(STDMETHODCALLTYPE), override)); + MOCK_METHOD(void, Pop, (), (Calltype(STDMETHODCALLTYPE), override)); + MOCK_METHOD(int, GetSize, (), (Calltype(STDMETHODCALLTYPE), override, const)); + MOCK_METHOD(const T&, GetTop, (), + (Calltype(STDMETHODCALLTYPE), override, const)); + + private: + GTEST_DISALLOW_COPY_AND_ASSIGN_(MockStackWithCallType); +}; + +template <typename T> +class LegacyMockStackWithCallType : public StackInterfaceWithCallType<T> { + public: + LegacyMockStackWithCallType() {} + + 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&()); + + private: + GTEST_DISALLOW_COPY_AND_ASSIGN_(LegacyMockStackWithCallType); +}; + +template <typename T> +class TemplateMockTestWithCallType : public ::testing::Test {}; +using TemplateMockTestWithCallTypeTypes = + ::testing::Types<MockStackWithCallType<int>, + LegacyMockStackWithCallType<int>>; +TYPED_TEST_SUITE(TemplateMockTestWithCallType, + TemplateMockTestWithCallTypeTypes); + +// Tests that template mock with calltype works. +TYPED_TEST(TemplateMockTestWithCallType, Works) { + TypeParam 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 + +#define MY_MOCK_METHODS1_ \ + MOCK_METHOD(void, Overloaded, ()); \ + MOCK_METHOD(int, Overloaded, (int), (const)); \ + MOCK_METHOD(bool, Overloaded, (bool f, int n)) + +#define LEGACY_MY_MOCK_METHODS1_ \ + MOCK_METHOD0(Overloaded, void()); \ + MOCK_CONST_METHOD1(Overloaded, int(int n)); \ + MOCK_METHOD2(Overloaded, bool(bool f, int n)) + +class MockOverloadedOnArgNumber { + public: + MockOverloadedOnArgNumber() {} + + MY_MOCK_METHODS1_; + + private: + GTEST_DISALLOW_COPY_AND_ASSIGN_(MockOverloadedOnArgNumber); +}; + +class LegacyMockOverloadedOnArgNumber { + public: + LegacyMockOverloadedOnArgNumber() {} + + LEGACY_MY_MOCK_METHODS1_; + + private: + GTEST_DISALLOW_COPY_AND_ASSIGN_(LegacyMockOverloadedOnArgNumber); +}; + +template <typename T> +class OverloadedMockMethodTest : public ::testing::Test {}; +using OverloadedMockMethodTestTypes = + ::testing::Types<MockOverloadedOnArgNumber, + LegacyMockOverloadedOnArgNumber>; +TYPED_TEST_SUITE(OverloadedMockMethodTest, OverloadedMockMethodTestTypes); + +TYPED_TEST(OverloadedMockMethodTest, CanOverloadOnArgNumberInMacroBody) { + TypeParam mock; + EXPECT_CALL(mock, Overloaded()); + EXPECT_CALL(mock, Overloaded(1)).WillOnce(Return(2)); + EXPECT_CALL(mock, Overloaded(true, 1)).WillOnce(Return(true)); + + mock.Overloaded(); + EXPECT_EQ(2, mock.Overloaded(1)); + EXPECT_TRUE(mock.Overloaded(true, 1)); +} + +#define MY_MOCK_METHODS2_ \ + MOCK_CONST_METHOD1(Overloaded, int(int n)); \ + MOCK_METHOD1(Overloaded, int(int n)) + +class MockOverloadedOnConstness { + public: + MockOverloadedOnConstness() {} + + MY_MOCK_METHODS2_; + + private: + GTEST_DISALLOW_COPY_AND_ASSIGN_(MockOverloadedOnConstness); +}; + +TEST(MockMethodOverloadedMockMethodTest, CanOverloadOnConstnessInMacroBody) { + MockOverloadedOnConstness mock; + const MockOverloadedOnConstness* const_mock = &mock; + EXPECT_CALL(mock, Overloaded(1)).WillOnce(Return(2)); + EXPECT_CALL(*const_mock, Overloaded(1)).WillOnce(Return(3)); + + EXPECT_EQ(2, mock.Overloaded(1)); + EXPECT_EQ(3, const_mock->Overloaded(1)); +} + +TEST(MockMethodMockFunctionTest, WorksForVoidNullary) { + MockFunction<void()> foo; + EXPECT_CALL(foo, Call()); + foo.Call(); +} + +TEST(MockMethodMockFunctionTest, WorksForNonVoidNullary) { + MockFunction<int()> foo; + EXPECT_CALL(foo, Call()) + .WillOnce(Return(1)) + .WillOnce(Return(2)); + EXPECT_EQ(1, foo.Call()); + EXPECT_EQ(2, foo.Call()); +} + +TEST(MockMethodMockFunctionTest, WorksForVoidUnary) { + MockFunction<void(int)> foo; + EXPECT_CALL(foo, Call(1)); + foo.Call(1); +} + +TEST(MockMethodMockFunctionTest, WorksForNonVoidBinary) { + MockFunction<int(bool, int)> foo; + EXPECT_CALL(foo, Call(false, 42)) + .WillOnce(Return(1)) + .WillOnce(Return(2)); + EXPECT_CALL(foo, Call(true, Ge(100))) + .WillOnce(Return(3)); + EXPECT_EQ(1, foo.Call(false, 42)); + EXPECT_EQ(2, foo.Call(false, 42)); + EXPECT_EQ(3, foo.Call(true, 120)); +} + +TEST(MockMethodMockFunctionTest, WorksFor10Arguments) { + MockFunction<int(bool a0, char a1, int a2, int a3, int a4, + int a5, int a6, char a7, int a8, bool a9)> foo; + EXPECT_CALL(foo, Call(_, 'a', _, _, _, _, _, _, _, _)) + .WillOnce(Return(1)) + .WillOnce(Return(2)); + EXPECT_EQ(1, foo.Call(false, 'a', 0, 0, 0, 0, 0, 'b', 0, true)); + EXPECT_EQ(2, foo.Call(true, 'a', 0, 0, 0, 0, 0, 'b', 1, false)); +} + +TEST(MockMethodMockFunctionTest, AsStdFunction) { + MockFunction<int(int)> foo; + auto call = [](const std::function<int(int)> &f, int i) { + return f(i); + }; + EXPECT_CALL(foo, Call(1)).WillOnce(Return(-1)); + EXPECT_CALL(foo, Call(2)).WillOnce(Return(-2)); + EXPECT_EQ(-1, call(foo.AsStdFunction(), 1)); + EXPECT_EQ(-2, call(foo.AsStdFunction(), 2)); +} + +TEST(MockMethodMockFunctionTest, AsStdFunctionReturnsReference) { + MockFunction<int&()> foo; + int value = 1; + EXPECT_CALL(foo, Call()).WillOnce(ReturnRef(value)); + int& ref = foo.AsStdFunction()(); + EXPECT_EQ(1, ref); + value = 2; + EXPECT_EQ(2, ref); +} + +TEST(MockMethodMockFunctionTest, AsStdFunctionWithReferenceParameter) { + MockFunction<int(int &)> foo; + auto call = [](const std::function<int(int& )> &f, int &i) { + return f(i); + }; + int i = 42; + EXPECT_CALL(foo, Call(i)).WillOnce(Return(-1)); + EXPECT_EQ(-1, call(foo.AsStdFunction(), i)); +} + +namespace { + +template <typename Expected, typename F> +static constexpr bool IsMockFunctionTemplateArgumentDeducedTo( + const MockFunction<F>&) { + return std::is_same<F, Expected>::value; +} + +} // namespace + +template <typename F> +class MockMethodMockFunctionSignatureTest : public Test {}; + +using MockMethodMockFunctionSignatureTypes = + Types<void(), int(), void(int), int(int), int(bool, int), + int(bool, char, int, int, int, int, int, char, int, bool)>; +TYPED_TEST_SUITE(MockMethodMockFunctionSignatureTest, + MockMethodMockFunctionSignatureTypes); + +TYPED_TEST(MockMethodMockFunctionSignatureTest, + IsMockFunctionTemplateArgumentDeducedForRawSignature) { + using Argument = TypeParam; + MockFunction<Argument> foo; + EXPECT_TRUE(IsMockFunctionTemplateArgumentDeducedTo<Argument>(foo)); +} + +TYPED_TEST(MockMethodMockFunctionSignatureTest, + IsMockFunctionTemplateArgumentDeducedForStdFunction) { + using Argument = std::function<TypeParam>; + MockFunction<Argument> foo; + EXPECT_TRUE(IsMockFunctionTemplateArgumentDeducedTo<Argument>(foo)); +} + +TYPED_TEST( + MockMethodMockFunctionSignatureTest, + IsMockFunctionCallMethodSignatureTheSameForRawSignatureAndStdFunction) { + using ForRawSignature = decltype(&MockFunction<TypeParam>::Call); + using ForStdFunction = + decltype(&MockFunction<std::function<TypeParam>>::Call); + EXPECT_TRUE((std::is_same<ForRawSignature, ForStdFunction>::value)); +} + +TYPED_TEST( + MockMethodMockFunctionSignatureTest, + IsMockFunctionAsStdFunctionMethodSignatureTheSameForRawSignatureAndStdFunction) { + using ForRawSignature = decltype(&MockFunction<TypeParam>::AsStdFunction); + using ForStdFunction = + decltype(&MockFunction<std::function<TypeParam>>::AsStdFunction); + EXPECT_TRUE((std::is_same<ForRawSignature, ForStdFunction>::value)); +} + +struct MockMethodSizes0 { + MOCK_METHOD(void, func, ()); +}; +struct MockMethodSizes1 { + MOCK_METHOD(void, func, (int)); +}; +struct MockMethodSizes2 { + MOCK_METHOD(void, func, (int, int)); +}; +struct MockMethodSizes3 { + MOCK_METHOD(void, func, (int, int, int)); +}; +struct MockMethodSizes4 { + MOCK_METHOD(void, func, (int, int, int, int)); +}; + +struct LegacyMockMethodSizes0 { + MOCK_METHOD0(func, void()); +}; +struct LegacyMockMethodSizes1 { + MOCK_METHOD1(func, void(int)); +}; +struct LegacyMockMethodSizes2 { + MOCK_METHOD2(func, void(int, int)); +}; +struct LegacyMockMethodSizes3 { + MOCK_METHOD3(func, void(int, int, int)); +}; +struct LegacyMockMethodSizes4 { + MOCK_METHOD4(func, void(int, int, int, int)); +}; + + +TEST(MockMethodMockFunctionTest, MockMethodSizeOverhead) { + EXPECT_EQ(sizeof(MockMethodSizes0), sizeof(MockMethodSizes1)); + EXPECT_EQ(sizeof(MockMethodSizes0), sizeof(MockMethodSizes2)); + EXPECT_EQ(sizeof(MockMethodSizes0), sizeof(MockMethodSizes3)); + EXPECT_EQ(sizeof(MockMethodSizes0), sizeof(MockMethodSizes4)); + + EXPECT_EQ(sizeof(LegacyMockMethodSizes0), sizeof(LegacyMockMethodSizes1)); + EXPECT_EQ(sizeof(LegacyMockMethodSizes0), sizeof(LegacyMockMethodSizes2)); + EXPECT_EQ(sizeof(LegacyMockMethodSizes0), sizeof(LegacyMockMethodSizes3)); + EXPECT_EQ(sizeof(LegacyMockMethodSizes0), sizeof(LegacyMockMethodSizes4)); + + EXPECT_EQ(sizeof(LegacyMockMethodSizes0), sizeof(MockMethodSizes0)); +} + +void hasTwoParams(int, int); +void MaybeThrows(); +void DoesntThrow() noexcept; +struct MockMethodNoexceptSpecifier { + MOCK_METHOD(void, func1, (), (noexcept)); + MOCK_METHOD(void, func2, (), (noexcept(true))); + MOCK_METHOD(void, func3, (), (noexcept(false))); + MOCK_METHOD(void, func4, (), (noexcept(noexcept(MaybeThrows())))); + MOCK_METHOD(void, func5, (), (noexcept(noexcept(DoesntThrow())))); + MOCK_METHOD(void, func6, (), (noexcept(noexcept(DoesntThrow())), const)); + MOCK_METHOD(void, func7, (), (const, noexcept(noexcept(DoesntThrow())))); + // Put commas in the noexcept expression + MOCK_METHOD(void, func8, (), (noexcept(noexcept(hasTwoParams(1, 2))), const)); +}; + +TEST(MockMethodMockFunctionTest, NoexceptSpecifierPreserved) { + EXPECT_TRUE(noexcept(std::declval<MockMethodNoexceptSpecifier>().func1())); + EXPECT_TRUE(noexcept(std::declval<MockMethodNoexceptSpecifier>().func2())); + EXPECT_FALSE(noexcept(std::declval<MockMethodNoexceptSpecifier>().func3())); + EXPECT_FALSE(noexcept(std::declval<MockMethodNoexceptSpecifier>().func4())); + EXPECT_TRUE(noexcept(std::declval<MockMethodNoexceptSpecifier>().func5())); + EXPECT_TRUE(noexcept(std::declval<MockMethodNoexceptSpecifier>().func6())); + EXPECT_TRUE(noexcept(std::declval<MockMethodNoexceptSpecifier>().func7())); + EXPECT_EQ(noexcept(std::declval<MockMethodNoexceptSpecifier>().func8()), + noexcept(hasTwoParams(1, 2))); +} + +} // namespace gmock_function_mocker_test +} // namespace testing diff --git a/src/googletest/googlemock/test/gmock-generated-actions_test.cc b/src/googletest/googlemock/test/gmock-generated-actions_test.cc new file mode 100644 index 000000000..649061640 --- /dev/null +++ b/src/googletest/googlemock/test/gmock-generated-actions_test.cc @@ -0,0 +1,1036 @@ +// 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. + + +// 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 <memory> +#include <sstream> +#include <string> +#include "gmock/gmock.h" +#include "gtest/gtest.h" + +namespace testing { +namespace gmock_generated_actions_test { + +using ::std::plus; +using ::std::string; +using testing::_; +using testing::Action; +using testing::ActionInterface; +using testing::ByRef; +using testing::DoAll; +using testing::Invoke; +using testing::Return; +using testing::SetArgPointee; +using testing::StaticAssertTypeEq; +using testing::Unused; + +// For suppressing compiler warnings on conversion possibly losing precision. +inline short Short(short n) { return n; } // NOLINT +inline char Char(char ch) { return ch; } + +// Sample functions and functors for testing various actions. +int Nullary() { return 1; } + +bool g_done = false; + +bool ByConstRef(const std::string& s) { return s == "Hi"; } + +const double g_double = 0; +bool ReferencesGlobalDouble(const double& x) { return &x == &g_double; } + +struct UnaryFunctor { + int operator()(bool x) { return x ? 1 : -1; } +}; + +const char* Binary(const char* input, short n) { return input + n; } // NOLINT + +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; + } +}; + +std::string Concat5(const char* s1, const char* s2, const char* s3, + const char* s4, const char* s5) { + return std::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; + } +}; + +std::string Concat6(const char* s1, const char* s2, const char* s3, + const char* s4, const char* s5, const char* s6) { + return std::string(s1) + s2 + s3 + s4 + s5 + s6; +} + +std::string Concat7(const char* s1, const char* s2, const char* s3, + const char* s4, const char* s5, const char* s6, + const char* s7) { + return std::string(s1) + s2 + s3 + s4 + s5 + s6 + s7; +} + +std::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 std::string(s1) + s2 + s3 + s4 + s5 + s6 + s7 + s8; +} + +std::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 std::string(s1) + s2 + s3 + s4 + s5 + s6 + s7 + s8 + s9; +} + +std::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 std::string(s1) + s2 + s3 + s4 + s5 + s6 + s7 + s8 + s9 + s10; +} + +// A helper that turns the type of a C-string literal from const +// char[N] to const char*. +inline const char* CharPtr(const char* s) { return s; } + +// Tests InvokeArgument<N>(...). + +// Tests using InvokeArgument with a nullary function. +TEST(InvokeArgumentTest, Function0) { + Action<int(int, int(*)())> a = InvokeArgument<1>(); // NOLINT + EXPECT_EQ(1, a.Perform(std::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(std::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(std::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(std::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(std::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(std::make_tuple(SumOf6Functor()))); +} + +// Tests using InvokeArgument with a 7-ary function. +TEST(InvokeArgumentTest, Function7) { + Action<std::string(std::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(std::make_tuple(&Concat7))); +} + +// Tests using InvokeArgument with a 8-ary function. +TEST(InvokeArgumentTest, Function8) { + Action<std::string(std::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(std::make_tuple(&Concat8))); +} + +// Tests using InvokeArgument with a 9-ary function. +TEST(InvokeArgumentTest, Function9) { + Action<std::string(std::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(std::make_tuple(&Concat9))); +} + +// Tests using InvokeArgument with a 10-ary function. +TEST(InvokeArgumentTest, Function10) { + Action<std::string(std::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(std::make_tuple(&Concat10))); +} + +// Tests using InvokeArgument with a function that takes a pointer argument. +TEST(InvokeArgumentTest, ByPointerFunction) { + Action<const char*(const char*(*)(const char* input, short n))> a = // NOLINT + InvokeArgument<0>(static_cast<const char*>("Hi"), Short(1)); + EXPECT_STREQ("i", a.Perform(std::make_tuple(&Binary))); +} + +// Tests using InvokeArgument with a function that takes a const char* +// by passing it a C-string literal. +TEST(InvokeArgumentTest, FunctionWithCStringLiteral) { + Action<const char*(const char*(*)(const char* input, short n))> a = // NOLINT + InvokeArgument<0>("Hi", Short(1)); + EXPECT_STREQ("i", a.Perform(std::make_tuple(&Binary))); +} + +// Tests using InvokeArgument with a function that takes a const reference. +TEST(InvokeArgumentTest, ByConstReferenceFunction) { + Action<bool(bool (*function)(const std::string& s))> a = // NOLINT + InvokeArgument<0>(std::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(std::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(std::make_tuple(&ReferencesGlobalDouble))); + + double x = 0; + a = InvokeArgument<0>(ByRef(x)); // This calls ByRef() on a non-const. + EXPECT_FALSE(a.Perform(std::make_tuple(&ReferencesGlobalDouble))); +} + +// Tests DoAll(a1, a2). +TEST(DoAllTest, TwoActions) { + int n = 0; + Action<int(int*)> a = DoAll(SetArgPointee<0>(1), // NOLINT + Return(2)); + EXPECT_EQ(2, a.Perform(std::make_tuple(&n))); + EXPECT_EQ(1, n); +} + +// Tests DoAll(a1, a2, a3). +TEST(DoAllTest, ThreeActions) { + int m = 0, n = 0; + Action<int(int*, int*)> a = DoAll(SetArgPointee<0>(1), // NOLINT + SetArgPointee<1>(2), + Return(3)); + EXPECT_EQ(3, a.Perform(std::make_tuple(&m, &n))); + EXPECT_EQ(1, m); + EXPECT_EQ(2, n); +} + +// Tests DoAll(a1, a2, a3, a4). +TEST(DoAllTest, FourActions) { + int m = 0, n = 0; + char ch = '\0'; + Action<int(int*, int*, char*)> a = // NOLINT + DoAll(SetArgPointee<0>(1), + SetArgPointee<1>(2), + SetArgPointee<2>('a'), + Return(3)); + EXPECT_EQ(3, a.Perform(std::make_tuple(&m, &n, &ch))); + EXPECT_EQ(1, m); + EXPECT_EQ(2, n); + EXPECT_EQ('a', ch); +} + +// Tests DoAll(a1, a2, a3, a4, a5). +TEST(DoAllTest, FiveActions) { + int m = 0, n = 0; + char a = '\0', b = '\0'; + Action<int(int*, int*, char*, char*)> action = // NOLINT + DoAll(SetArgPointee<0>(1), + SetArgPointee<1>(2), + SetArgPointee<2>('a'), + SetArgPointee<3>('b'), + Return(3)); + EXPECT_EQ(3, action.Perform(std::make_tuple(&m, &n, &a, &b))); + EXPECT_EQ(1, m); + EXPECT_EQ(2, n); + EXPECT_EQ('a', a); + EXPECT_EQ('b', b); +} + +// Tests DoAll(a1, a2, ..., a6). +TEST(DoAllTest, SixActions) { + int m = 0, n = 0; + char a = '\0', b = '\0', c = '\0'; + Action<int(int*, int*, char*, char*, char*)> action = // NOLINT + DoAll(SetArgPointee<0>(1), + SetArgPointee<1>(2), + SetArgPointee<2>('a'), + SetArgPointee<3>('b'), + SetArgPointee<4>('c'), + Return(3)); + EXPECT_EQ(3, action.Perform(std::make_tuple(&m, &n, &a, &b, &c))); + EXPECT_EQ(1, m); + EXPECT_EQ(2, n); + EXPECT_EQ('a', a); + EXPECT_EQ('b', b); + EXPECT_EQ('c', c); +} + +// Tests DoAll(a1, a2, ..., a7). +TEST(DoAllTest, SevenActions) { + int m = 0, n = 0; + char a = '\0', b = '\0', c = '\0', d = '\0'; + Action<int(int*, int*, char*, char*, char*, char*)> action = // NOLINT + DoAll(SetArgPointee<0>(1), + SetArgPointee<1>(2), + SetArgPointee<2>('a'), + SetArgPointee<3>('b'), + SetArgPointee<4>('c'), + SetArgPointee<5>('d'), + Return(3)); + EXPECT_EQ(3, action.Perform(std::make_tuple(&m, &n, &a, &b, &c, &d))); + EXPECT_EQ(1, m); + EXPECT_EQ(2, n); + EXPECT_EQ('a', a); + EXPECT_EQ('b', b); + EXPECT_EQ('c', c); + EXPECT_EQ('d', d); +} + +// Tests DoAll(a1, a2, ..., a8). +TEST(DoAllTest, EightActions) { + int m = 0, n = 0; + char a = '\0', b = '\0', c = '\0', d = '\0', e = '\0'; + Action<int(int*, int*, char*, char*, char*, char*, // NOLINT + char*)> action = + DoAll(SetArgPointee<0>(1), + SetArgPointee<1>(2), + SetArgPointee<2>('a'), + SetArgPointee<3>('b'), + SetArgPointee<4>('c'), + SetArgPointee<5>('d'), + SetArgPointee<6>('e'), + Return(3)); + EXPECT_EQ(3, action.Perform(std::make_tuple(&m, &n, &a, &b, &c, &d, &e))); + EXPECT_EQ(1, m); + EXPECT_EQ(2, n); + EXPECT_EQ('a', a); + EXPECT_EQ('b', b); + EXPECT_EQ('c', c); + EXPECT_EQ('d', d); + EXPECT_EQ('e', e); +} + +// Tests DoAll(a1, a2, ..., a9). +TEST(DoAllTest, NineActions) { + int m = 0, n = 0; + char a = '\0', b = '\0', c = '\0', d = '\0', e = '\0', f = '\0'; + Action<int(int*, int*, char*, char*, char*, char*, // NOLINT + char*, char*)> action = + DoAll(SetArgPointee<0>(1), + SetArgPointee<1>(2), + SetArgPointee<2>('a'), + SetArgPointee<3>('b'), + SetArgPointee<4>('c'), + SetArgPointee<5>('d'), + SetArgPointee<6>('e'), + SetArgPointee<7>('f'), + Return(3)); + EXPECT_EQ(3, action.Perform(std::make_tuple(&m, &n, &a, &b, &c, &d, &e, &f))); + EXPECT_EQ(1, m); + EXPECT_EQ(2, n); + EXPECT_EQ('a', a); + EXPECT_EQ('b', b); + EXPECT_EQ('c', c); + EXPECT_EQ('d', d); + EXPECT_EQ('e', e); + EXPECT_EQ('f', f); +} + +// Tests DoAll(a1, a2, ..., a10). +TEST(DoAllTest, TenActions) { + int m = 0, n = 0; + char a = '\0', b = '\0', c = '\0', d = '\0'; + char e = '\0', f = '\0', g = '\0'; + Action<int(int*, int*, char*, char*, char*, char*, // NOLINT + char*, char*, char*)> action = + DoAll(SetArgPointee<0>(1), + SetArgPointee<1>(2), + SetArgPointee<2>('a'), + SetArgPointee<3>('b'), + SetArgPointee<4>('c'), + SetArgPointee<5>('d'), + SetArgPointee<6>('e'), + SetArgPointee<7>('f'), + SetArgPointee<8>('g'), + Return(3)); + EXPECT_EQ( + 3, action.Perform(std::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); +} + +TEST(DoAllTest, NoArgs) { + bool ran_first = false; + Action<bool()> a = + DoAll([&] { ran_first = true; }, [&] { return ran_first; }); + EXPECT_TRUE(a.Perform({})); +} + +TEST(DoAllTest, MoveOnlyArgs) { + bool ran_first = false; + Action<int(std::unique_ptr<int>)> a = + DoAll(InvokeWithoutArgs([&] { ran_first = true; }), + [](std::unique_ptr<int> p) { return *p; }); + EXPECT_EQ(7, a.Perform(std::make_tuple(std::unique_ptr<int>(new int(7))))); + EXPECT_TRUE(ran_first); +} + +TEST(DoAllTest, ImplicitlyConvertsActionArguments) { + bool ran_first = false; + // Action<void(std::vector<int>)> isn't an + // Action<void(const std::vector<int>&) but can be converted. + Action<void(std::vector<int>)> first = [&] { ran_first = true; }; + Action<int(std::vector<int>)> a = + DoAll(first, [](std::vector<int> arg) { return arg.front(); }); + EXPECT_EQ(7, a.Perform(std::make_tuple(std::vector<int>{7}))); + EXPECT_TRUE(ran_first); +} + +// The ACTION*() macros trigger warning C4100 (unreferenced formal +// parameter) in MSVC with -W4. Unfortunately they cannot be fixed in +// the macro definition, as the warnings are generated when the macro +// is expanded and macro expansion cannot contain #pragma. Therefore +// we suppress them here. +// Also suppress C4503 decorated name length exceeded, name was truncated +#ifdef _MSC_VER +# pragma warning(push) +# pragma warning(disable:4100) +# pragma warning(disable:4503) +#endif +// Tests the ACTION*() macro family. + +// Tests that ACTION() can define an action that doesn't reference the +// mock function arguments. +ACTION(Return5) { return 5; } + +TEST(ActionMacroTest, WorksWhenNotReferencingArguments) { + Action<double()> a1 = Return5(); + EXPECT_DOUBLE_EQ(5, a1.Perform(std::make_tuple())); + + Action<int(double, bool)> a2 = Return5(); + EXPECT_EQ(5, a2.Perform(std::make_tuple(1, true))); +} + +// Tests that ACTION() can define an action that returns void. +ACTION(IncrementArg1) { (*arg1)++; } + +TEST(ActionMacroTest, WorksWhenReturningVoid) { + Action<void(int, int*)> a1 = IncrementArg1(); + int n = 0; + a1.Perform(std::make_tuple(5, &n)); + EXPECT_EQ(1, n); +} + +// Tests that the body of ACTION() can reference the type of the +// argument. +ACTION(IncrementArg2) { + StaticAssertTypeEq<int*, arg2_type>(); + arg2_type temp = arg2; + (*temp)++; +} + +TEST(ActionMacroTest, CanReferenceArgumentType) { + Action<void(int, bool, int*)> a1 = IncrementArg2(); + int n = 0; + a1.Perform(std::make_tuple(5, false, &n)); + EXPECT_EQ(1, n); +} + +// Tests that the body of ACTION() can reference the argument tuple +// via args_type and args. +ACTION(Sum2) { + StaticAssertTypeEq<std::tuple<int, char, int*>, args_type>(); + args_type args_copy = args; + return std::get<0>(args_copy) + std::get<1>(args_copy); +} + +TEST(ActionMacroTest, CanReferenceArgumentTuple) { + Action<int(int, char, int*)> a1 = Sum2(); + int dummy = 0; + EXPECT_EQ(11, a1.Perform(std::make_tuple(5, Char(6), &dummy))); +} + +// Tests that the body of ACTION() can reference the mock function +// type. +int Dummy(bool flag) { return flag? 1 : 0; } + +ACTION(InvokeDummy) { + StaticAssertTypeEq<int(bool), function_type>(); + function_type* fp = &Dummy; + return (*fp)(true); +} + +TEST(ActionMacroTest, CanReferenceMockFunctionType) { + Action<int(bool)> a1 = InvokeDummy(); + EXPECT_EQ(1, a1.Perform(std::make_tuple(true))); + EXPECT_EQ(1, a1.Perform(std::make_tuple(false))); +} + +// Tests that the body of ACTION() can reference the mock function's +// return type. +ACTION(InvokeDummy2) { + StaticAssertTypeEq<int, return_type>(); + return_type result = Dummy(true); + return result; +} + +TEST(ActionMacroTest, CanReferenceMockFunctionReturnType) { + Action<int(bool)> a1 = InvokeDummy2(); + EXPECT_EQ(1, a1.Perform(std::make_tuple(true))); + EXPECT_EQ(1, a1.Perform(std::make_tuple(false))); +} + +// Tests that ACTION() works for arguments passed by const reference. +ACTION(ReturnAddrOfConstBoolReferenceArg) { + StaticAssertTypeEq<const bool&, arg1_type>(); + return &arg1; +} + +TEST(ActionMacroTest, WorksForConstReferenceArg) { + Action<const bool*(int, const bool&)> a = ReturnAddrOfConstBoolReferenceArg(); + const bool b = false; + EXPECT_EQ(&b, a.Perform(std::tuple<int, const bool&>(0, b))); +} + +// Tests that ACTION() works for arguments passed by non-const reference. +ACTION(ReturnAddrOfIntReferenceArg) { + StaticAssertTypeEq<int&, arg0_type>(); + return &arg0; +} + +TEST(ActionMacroTest, WorksForNonConstReferenceArg) { + Action<int*(int&, bool, int)> a = ReturnAddrOfIntReferenceArg(); + int n = 0; + EXPECT_EQ(&n, a.Perform(std::tuple<int&, bool, int>(n, true, 1))); +} + +// Tests that ACTION() can be used in a namespace. +namespace action_test { +ACTION(Sum) { return arg0 + arg1; } +} // namespace action_test + +TEST(ActionMacroTest, WorksInNamespace) { + Action<int(int, int)> a1 = action_test::Sum(); + EXPECT_EQ(3, a1.Perform(std::make_tuple(1, 2))); +} + +// Tests that the same ACTION definition works for mock functions with +// different argument numbers. +ACTION(PlusTwo) { return arg0 + 2; } + +TEST(ActionMacroTest, WorksForDifferentArgumentNumbers) { + Action<int(int)> a1 = PlusTwo(); + EXPECT_EQ(4, a1.Perform(std::make_tuple(2))); + + Action<double(float, void*)> a2 = PlusTwo(); + int dummy; + EXPECT_DOUBLE_EQ(6, a2.Perform(std::make_tuple(4.0f, &dummy))); +} + +// Tests that ACTION_P can define a parameterized action. +ACTION_P(Plus, n) { return arg0 + n; } + +TEST(ActionPMacroTest, DefinesParameterizedAction) { + Action<int(int m, bool t)> a1 = Plus(9); + EXPECT_EQ(10, a1.Perform(std::make_tuple(1, true))); +} + +// Tests that the body of ACTION_P can reference the argument types +// and the parameter type. +ACTION_P(TypedPlus, n) { + arg0_type t1 = arg0; + n_type t2 = n; + return t1 + t2; +} + +TEST(ActionPMacroTest, CanReferenceArgumentAndParameterTypes) { + Action<int(char m, bool t)> a1 = TypedPlus(9); + EXPECT_EQ(10, a1.Perform(std::make_tuple(Char(1), true))); +} + +// Tests that a parameterized action can be used in any mock function +// whose type is compatible. +TEST(ActionPMacroTest, WorksInCompatibleMockFunction) { + Action<std::string(const std::string& s)> a1 = Plus("tail"); + const std::string re = "re"; + std::tuple<const std::string> dummy = std::make_tuple(re); + EXPECT_EQ("retail", a1.Perform(dummy)); +} + +// Tests that we can use ACTION*() to define actions overloaded on the +// number of parameters. + +ACTION(OverloadedAction) { return arg0 ? arg1 : "hello"; } + +ACTION_P(OverloadedAction, default_value) { + return arg0 ? arg1 : default_value; +} + +ACTION_P2(OverloadedAction, true_value, false_value) { + return arg0 ? true_value : false_value; +} + +TEST(ActionMacroTest, CanDefineOverloadedActions) { + typedef Action<const char*(bool, const char*)> MyAction; + + const MyAction a1 = OverloadedAction(); + EXPECT_STREQ("hello", a1.Perform(std::make_tuple(false, CharPtr("world")))); + EXPECT_STREQ("world", a1.Perform(std::make_tuple(true, CharPtr("world")))); + + const MyAction a2 = OverloadedAction("hi"); + EXPECT_STREQ("hi", a2.Perform(std::make_tuple(false, CharPtr("world")))); + EXPECT_STREQ("world", a2.Perform(std::make_tuple(true, CharPtr("world")))); + + const MyAction a3 = OverloadedAction("hi", "you"); + EXPECT_STREQ("hi", a3.Perform(std::make_tuple(true, CharPtr("world")))); + EXPECT_STREQ("you", a3.Perform(std::make_tuple(false, CharPtr("world")))); +} + +// Tests ACTION_Pn where n >= 3. + +ACTION_P3(Plus, m, n, k) { return arg0 + m + n + k; } + +TEST(ActionPnMacroTest, WorksFor3Parameters) { + Action<double(int m, bool t)> a1 = Plus(100, 20, 3.4); + EXPECT_DOUBLE_EQ(3123.4, a1.Perform(std::make_tuple(3000, true))); + + Action<std::string(const std::string& s)> a2 = Plus("tail", "-", ">"); + const std::string re = "re"; + std::tuple<const std::string> dummy = std::make_tuple(re); + EXPECT_EQ("retail->", a2.Perform(dummy)); +} + +ACTION_P4(Plus, p0, p1, p2, p3) { return arg0 + p0 + p1 + p2 + p3; } + +TEST(ActionPnMacroTest, WorksFor4Parameters) { + Action<int(int)> a1 = Plus(1, 2, 3, 4); + EXPECT_EQ(10 + 1 + 2 + 3 + 4, a1.Perform(std::make_tuple(10))); +} + +ACTION_P5(Plus, p0, p1, p2, p3, p4) { return arg0 + p0 + p1 + p2 + p3 + p4; } + +TEST(ActionPnMacroTest, WorksFor5Parameters) { + Action<int(int)> a1 = Plus(1, 2, 3, 4, 5); + EXPECT_EQ(10 + 1 + 2 + 3 + 4 + 5, a1.Perform(std::make_tuple(10))); +} + +ACTION_P6(Plus, p0, p1, p2, p3, p4, p5) { + return arg0 + p0 + p1 + p2 + p3 + p4 + p5; +} + +TEST(ActionPnMacroTest, WorksFor6Parameters) { + Action<int(int)> a1 = Plus(1, 2, 3, 4, 5, 6); + EXPECT_EQ(10 + 1 + 2 + 3 + 4 + 5 + 6, a1.Perform(std::make_tuple(10))); +} + +ACTION_P7(Plus, p0, p1, p2, p3, p4, p5, p6) { + return arg0 + p0 + p1 + p2 + p3 + p4 + p5 + p6; +} + +TEST(ActionPnMacroTest, WorksFor7Parameters) { + Action<int(int)> a1 = Plus(1, 2, 3, 4, 5, 6, 7); + EXPECT_EQ(10 + 1 + 2 + 3 + 4 + 5 + 6 + 7, a1.Perform(std::make_tuple(10))); +} + +ACTION_P8(Plus, p0, p1, p2, p3, p4, p5, p6, p7) { + return arg0 + p0 + p1 + p2 + p3 + p4 + p5 + p6 + p7; +} + +TEST(ActionPnMacroTest, WorksFor8Parameters) { + Action<int(int)> a1 = Plus(1, 2, 3, 4, 5, 6, 7, 8); + EXPECT_EQ(10 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8, + a1.Perform(std::make_tuple(10))); +} + +ACTION_P9(Plus, p0, p1, p2, p3, p4, p5, p6, p7, p8) { + return arg0 + p0 + p1 + p2 + p3 + p4 + p5 + p6 + p7 + p8; +} + +TEST(ActionPnMacroTest, WorksFor9Parameters) { + Action<int(int)> a1 = Plus(1, 2, 3, 4, 5, 6, 7, 8, 9); + EXPECT_EQ(10 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9, + a1.Perform(std::make_tuple(10))); +} + +ACTION_P10(Plus, p0, p1, p2, p3, p4, p5, p6, p7, p8, last_param) { + arg0_type t0 = arg0; + last_param_type t9 = last_param; + return t0 + p0 + p1 + p2 + p3 + p4 + p5 + p6 + p7 + p8 + t9; +} + +TEST(ActionPnMacroTest, WorksFor10Parameters) { + Action<int(int)> a1 = Plus(1, 2, 3, 4, 5, 6, 7, 8, 9, 10); + EXPECT_EQ(10 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10, + a1.Perform(std::make_tuple(10))); +} + +// Tests that the action body can promote the parameter types. + +ACTION_P2(PadArgument, prefix, suffix) { + // The following lines promote the two parameters to desired types. + std::string prefix_str(prefix); + char suffix_char = static_cast<char>(suffix); + return prefix_str + arg0 + suffix_char; +} + +TEST(ActionPnMacroTest, SimpleTypePromotion) { + Action<std::string(const char*)> no_promo = + PadArgument(std::string("foo"), 'r'); + Action<std::string(const char*)> promo = + PadArgument("foo", static_cast<int>('r')); + EXPECT_EQ("foobar", no_promo.Perform(std::make_tuple(CharPtr("ba")))); + EXPECT_EQ("foobar", promo.Perform(std::make_tuple(CharPtr("ba")))); +} + +// Tests that we can partially restrict parameter types using a +// straight-forward pattern. + +// Defines a generic action that doesn't restrict the types of its +// parameters. +ACTION_P3(ConcatImpl, a, b, c) { + std::stringstream ss; + ss << a << b << c; + return ss.str(); +} + +// Next, we try to restrict that either the first parameter is a +// string, or the second parameter is an int. + +// Defines a partially specialized wrapper that restricts the first +// parameter to std::string. +template <typename T1, typename T2> +// ConcatImplActionP3 is the class template ACTION_P3 uses to +// implement ConcatImpl. We shouldn't change the name as this +// pattern requires the user to use it directly. +ConcatImplActionP3<std::string, T1, T2> +Concat(const std::string& a, T1 b, T2 c) { + GTEST_INTENTIONAL_CONST_COND_PUSH_() + if (true) { + GTEST_INTENTIONAL_CONST_COND_POP_() + // This branch verifies that ConcatImpl() can be invoked without + // explicit template arguments. + return ConcatImpl(a, b, c); + } else { + // This branch verifies that ConcatImpl() can also be invoked with + // explicit template arguments. It doesn't really need to be + // executed as this is a compile-time verification. + return ConcatImpl<std::string, T1, T2>(a, b, c); + } +} + +// Defines another partially specialized wrapper that restricts the +// second parameter to int. +template <typename T1, typename T2> +ConcatImplActionP3<T1, int, T2> +Concat(T1 a, int b, T2 c) { + return ConcatImpl(a, b, c); +} + +TEST(ActionPnMacroTest, CanPartiallyRestrictParameterTypes) { + Action<const std::string()> a1 = Concat("Hello", "1", 2); + EXPECT_EQ("Hello12", a1.Perform(std::make_tuple())); + + a1 = Concat(1, 2, 3); + EXPECT_EQ("123", a1.Perform(std::make_tuple())); +} + +// Verifies the type of an ACTION*. + +ACTION(DoFoo) {} +ACTION_P(DoFoo, p) {} +ACTION_P2(DoFoo, p0, p1) {} + +TEST(ActionPnMacroTest, TypesAreCorrect) { + // DoFoo() must be assignable to a DoFooAction variable. + DoFooAction a0 = DoFoo(); + + // DoFoo(1) must be assignable to a DoFooActionP variable. + DoFooActionP<int> a1 = DoFoo(1); + + // DoFoo(p1, ..., pk) must be assignable to a DoFooActionPk + // variable, and so on. + DoFooActionP2<int, char> a2 = DoFoo(1, '2'); + PlusActionP3<int, int, char> a3 = Plus(1, 2, '3'); + PlusActionP4<int, int, int, char> a4 = Plus(1, 2, 3, '4'); + PlusActionP5<int, int, int, int, char> a5 = Plus(1, 2, 3, 4, '5'); + PlusActionP6<int, int, int, int, int, char> a6 = Plus(1, 2, 3, 4, 5, '6'); + PlusActionP7<int, int, int, int, int, int, char> a7 = + Plus(1, 2, 3, 4, 5, 6, '7'); + PlusActionP8<int, int, int, int, int, int, int, char> a8 = + Plus(1, 2, 3, 4, 5, 6, 7, '8'); + PlusActionP9<int, int, int, int, int, int, int, int, char> a9 = + Plus(1, 2, 3, 4, 5, 6, 7, 8, '9'); + PlusActionP10<int, int, int, int, int, int, int, int, int, char> a10 = + Plus(1, 2, 3, 4, 5, 6, 7, 8, 9, '0'); + + // Avoid "unused variable" warnings. + (void)a0; + (void)a1; + (void)a2; + (void)a3; + (void)a4; + (void)a5; + (void)a6; + (void)a7; + (void)a8; + (void)a9; + (void)a10; +} + +// Tests that an ACTION_P*() action can be explicitly instantiated +// with reference-typed parameters. + +ACTION_P(Plus1, x) { return x; } +ACTION_P2(Plus2, x, y) { return x + y; } +ACTION_P3(Plus3, x, y, z) { return x + y + z; } +ACTION_P10(Plus10, a0, a1, a2, a3, a4, a5, a6, a7, a8, a9) { + return a0 + a1 + a2 + a3 + a4 + a5 + a6 + a7 + a8 + a9; +} + +TEST(ActionPnMacroTest, CanExplicitlyInstantiateWithReferenceTypes) { + int x = 1, y = 2, z = 3; + const std::tuple<> empty = std::make_tuple(); + + Action<int()> a = Plus1<int&>(x); + EXPECT_EQ(1, a.Perform(empty)); + + a = Plus2<const int&, int&>(x, y); + EXPECT_EQ(3, a.Perform(empty)); + + a = Plus3<int&, const int&, int&>(x, y, z); + EXPECT_EQ(6, a.Perform(empty)); + + int n[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; + a = Plus10<const int&, int&, const int&, int&, const int&, int&, const int&, + int&, const int&, int&>(n[0], n[1], n[2], n[3], n[4], n[5], n[6], n[7], + n[8], n[9]); + EXPECT_EQ(55, a.Perform(empty)); +} + + +class TenArgConstructorClass { + public: + TenArgConstructorClass(int a1, int a2, int a3, int a4, int a5, + int a6, int a7, int a8, int a9, int a10) + : value_(a1 + a2 + a3 + a4 + a5 + a6 + a7 + a8 + a9 + a10) { + } + int value_; +}; + +// Tests that ACTION_TEMPLATE works when there is no value parameter. +ACTION_TEMPLATE(CreateNew, + HAS_1_TEMPLATE_PARAMS(typename, T), + AND_0_VALUE_PARAMS()) { + return new T; +} + +TEST(ActionTemplateTest, WorksWithoutValueParam) { + const Action<int*()> a = CreateNew<int>(); + int* p = a.Perform(std::make_tuple()); + delete p; +} + +// Tests that ACTION_TEMPLATE works when there are value parameters. +ACTION_TEMPLATE(CreateNew, + HAS_1_TEMPLATE_PARAMS(typename, T), + AND_1_VALUE_PARAMS(a0)) { + return new T(a0); +} + +TEST(ActionTemplateTest, WorksWithValueParams) { + const Action<int*()> a = CreateNew<int>(42); + int* p = a.Perform(std::make_tuple()); + EXPECT_EQ(42, *p); + delete p; +} + +// Tests that ACTION_TEMPLATE works for integral template parameters. +ACTION_TEMPLATE(MyDeleteArg, + HAS_1_TEMPLATE_PARAMS(int, k), + AND_0_VALUE_PARAMS()) { + delete std::get<k>(args); +} + +// Resets a bool variable in the destructor. +class BoolResetter { + public: + explicit BoolResetter(bool* value) : value_(value) {} + ~BoolResetter() { *value_ = false; } + private: + bool* value_; +}; + +TEST(ActionTemplateTest, WorksForIntegralTemplateParams) { + const Action<void(int*, BoolResetter*)> a = MyDeleteArg<1>(); + int n = 0; + bool b = true; + BoolResetter* resetter = new BoolResetter(&b); + a.Perform(std::make_tuple(&n, resetter)); + EXPECT_FALSE(b); // Verifies that resetter is deleted. +} + +// Tests that ACTION_TEMPLATES works for template template parameters. +ACTION_TEMPLATE(ReturnSmartPointer, + HAS_1_TEMPLATE_PARAMS(template <typename Pointee> class, + Pointer), + AND_1_VALUE_PARAMS(pointee)) { + return Pointer<pointee_type>(new pointee_type(pointee)); +} + +TEST(ActionTemplateTest, WorksForTemplateTemplateParameters) { + const Action<std::shared_ptr<int>()> a = + ReturnSmartPointer<std::shared_ptr>(42); + std::shared_ptr<int> p = a.Perform(std::make_tuple()); + EXPECT_EQ(42, *p); +} + +// Tests that ACTION_TEMPLATE works for 10 template parameters. +template <typename T1, typename T2, typename T3, int k4, bool k5, + unsigned int k6, typename T7, typename T8, typename T9> +struct GiantTemplate { + public: + explicit GiantTemplate(int a_value) : value(a_value) {} + int value; +}; + +ACTION_TEMPLATE(ReturnGiant, + HAS_10_TEMPLATE_PARAMS( + typename, T1, + typename, T2, + typename, T3, + int, k4, + bool, k5, + unsigned int, k6, + class, T7, + class, T8, + class, T9, + template <typename T> class, T10), + AND_1_VALUE_PARAMS(value)) { + return GiantTemplate<T10<T1>, T2, T3, k4, k5, k6, T7, T8, T9>(value); +} + +TEST(ActionTemplateTest, WorksFor10TemplateParameters) { + using Giant = GiantTemplate<std::shared_ptr<int>, bool, double, 5, true, 6, + char, unsigned, int>; + const Action<Giant()> a = ReturnGiant<int, bool, double, 5, true, 6, char, + unsigned, int, std::shared_ptr>(42); + Giant giant = a.Perform(std::make_tuple()); + EXPECT_EQ(42, giant.value); +} + +// Tests that ACTION_TEMPLATE works for 10 value parameters. +ACTION_TEMPLATE(ReturnSum, + HAS_1_TEMPLATE_PARAMS(typename, Number), + AND_10_VALUE_PARAMS(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10)) { + return static_cast<Number>(v1) + v2 + v3 + v4 + v5 + v6 + v7 + v8 + v9 + v10; +} + +TEST(ActionTemplateTest, WorksFor10ValueParameters) { + const Action<int()> a = ReturnSum<int>(1, 2, 3, 4, 5, 6, 7, 8, 9, 10); + EXPECT_EQ(55, a.Perform(std::make_tuple())); +} + +// Tests that ACTION_TEMPLATE and ACTION/ACTION_P* can be overloaded +// on the number of value parameters. + +ACTION(ReturnSum) { return 0; } + +ACTION_P(ReturnSum, x) { return x; } + +ACTION_TEMPLATE(ReturnSum, + HAS_1_TEMPLATE_PARAMS(typename, Number), + AND_2_VALUE_PARAMS(v1, v2)) { + return static_cast<Number>(v1) + v2; +} + +ACTION_TEMPLATE(ReturnSum, + HAS_1_TEMPLATE_PARAMS(typename, Number), + AND_3_VALUE_PARAMS(v1, v2, v3)) { + return static_cast<Number>(v1) + v2 + v3; +} + +ACTION_TEMPLATE(ReturnSum, + HAS_2_TEMPLATE_PARAMS(typename, Number, int, k), + AND_4_VALUE_PARAMS(v1, v2, v3, v4)) { + return static_cast<Number>(v1) + v2 + v3 + v4 + k; +} + +TEST(ActionTemplateTest, CanBeOverloadedOnNumberOfValueParameters) { + const Action<int()> a0 = ReturnSum(); + const Action<int()> a1 = ReturnSum(1); + const Action<int()> a2 = ReturnSum<int>(1, 2); + const Action<int()> a3 = ReturnSum<int>(1, 2, 3); + const Action<int()> a4 = ReturnSum<int, 10000>(2000, 300, 40, 5); + EXPECT_EQ(0, a0.Perform(std::make_tuple())); + EXPECT_EQ(1, a1.Perform(std::make_tuple())); + EXPECT_EQ(3, a2.Perform(std::make_tuple())); + EXPECT_EQ(6, a3.Perform(std::make_tuple())); + EXPECT_EQ(12345, a4.Perform(std::make_tuple())); +} + + +} // namespace gmock_generated_actions_test +} // namespace testing diff --git a/src/googletest/googlemock/test/gmock-internal-utils_test.cc b/src/googletest/googlemock/test/gmock-internal-utils_test.cc new file mode 100644 index 000000000..0d15e8f48 --- /dev/null +++ b/src/googletest/googlemock/test/gmock-internal-utils_test.cc @@ -0,0 +1,720 @@ +// 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. + + +// Google Mock - a framework for writing C++ mock classes. +// +// This file tests the internal utilities. + +#include "gmock/internal/gmock-internal-utils.h" + +#include <stdlib.h> + +#include <cstdint> +#include <map> +#include <memory> +#include <sstream> +#include <string> +#include <vector> + +#include "gmock/gmock.h" +#include "gmock/internal/gmock-port.h" +#include "gtest/gtest-spi.h" +#include "gtest/gtest.h" + +// Indicates that this translation unit is part of Google Test's +// implementation. It must come before gtest-internal-inl.h is +// included, or there will be a compiler error. This trick is to +// prevent a user from accidentally including gtest-internal-inl.h in +// their code. +#define GTEST_IMPLEMENTATION_ 1 +#include "src/gtest-internal-inl.h" +#undef GTEST_IMPLEMENTATION_ + +#if GTEST_OS_CYGWIN +# include <sys/types.h> // For ssize_t. NOLINT +#endif + +namespace proto2 { +class Message; +} // namespace proto2 + +namespace testing { +namespace internal { + +namespace { + +TEST(JoinAsTupleTest, JoinsEmptyTuple) { + EXPECT_EQ("", JoinAsTuple(Strings())); +} + +TEST(JoinAsTupleTest, JoinsOneTuple) { + const char* fields[] = {"1"}; + EXPECT_EQ("1", JoinAsTuple(Strings(fields, fields + 1))); +} + +TEST(JoinAsTupleTest, JoinsTwoTuple) { + const char* fields[] = {"1", "a"}; + EXPECT_EQ("(1, a)", JoinAsTuple(Strings(fields, fields + 2))); +} + +TEST(JoinAsTupleTest, JoinsTenTuple) { + const char* fields[] = {"1", "2", "3", "4", "5", "6", "7", "8", "9", "10"}; + EXPECT_EQ("(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)", + JoinAsTuple(Strings(fields, fields + 10))); +} + +TEST(ConvertIdentifierNameToWordsTest, WorksWhenNameContainsNoWord) { + EXPECT_EQ("", ConvertIdentifierNameToWords("")); + EXPECT_EQ("", ConvertIdentifierNameToWords("_")); + EXPECT_EQ("", ConvertIdentifierNameToWords("__")); +} + +TEST(ConvertIdentifierNameToWordsTest, WorksWhenNameContainsDigits) { + EXPECT_EQ("1", ConvertIdentifierNameToWords("_1")); + EXPECT_EQ("2", ConvertIdentifierNameToWords("2_")); + EXPECT_EQ("34", ConvertIdentifierNameToWords("_34_")); + EXPECT_EQ("34 56", ConvertIdentifierNameToWords("_34_56")); +} + +TEST(ConvertIdentifierNameToWordsTest, WorksWhenNameContainsCamelCaseWords) { + EXPECT_EQ("a big word", ConvertIdentifierNameToWords("ABigWord")); + EXPECT_EQ("foo bar", ConvertIdentifierNameToWords("FooBar")); + EXPECT_EQ("foo", ConvertIdentifierNameToWords("Foo_")); + EXPECT_EQ("foo bar", ConvertIdentifierNameToWords("_Foo_Bar_")); + EXPECT_EQ("foo and bar", ConvertIdentifierNameToWords("_Foo__And_Bar")); +} + +TEST(ConvertIdentifierNameToWordsTest, WorksWhenNameContains_SeparatedWords) { + EXPECT_EQ("foo bar", ConvertIdentifierNameToWords("foo_bar")); + EXPECT_EQ("foo", ConvertIdentifierNameToWords("_foo_")); + EXPECT_EQ("foo bar", ConvertIdentifierNameToWords("_foo_bar_")); + EXPECT_EQ("foo and bar", ConvertIdentifierNameToWords("_foo__and_bar")); +} + +TEST(ConvertIdentifierNameToWordsTest, WorksWhenNameIsMixture) { + EXPECT_EQ("foo bar 123", ConvertIdentifierNameToWords("Foo_bar123")); + EXPECT_EQ("chapter 11 section 1", + ConvertIdentifierNameToWords("_Chapter11Section_1_")); +} + +TEST(GetRawPointerTest, WorksForSmartPointers) { + const char* const raw_p1 = new const char('a'); // NOLINT + const std::unique_ptr<const char> p1(raw_p1); + EXPECT_EQ(raw_p1, GetRawPointer(p1)); + double* const raw_p2 = new double(2.5); // NOLINT + const std::shared_ptr<double> p2(raw_p2); + EXPECT_EQ(raw_p2, GetRawPointer(p2)); +} + +TEST(GetRawPointerTest, WorksForRawPointers) { + int* p = nullptr; + EXPECT_TRUE(nullptr == GetRawPointer(p)); + int n = 1; + EXPECT_EQ(&n, GetRawPointer(&n)); +} + +// Tests KindOf<T>. + +class Base {}; +class Derived : public Base {}; + +TEST(KindOfTest, Bool) { + EXPECT_EQ(kBool, GMOCK_KIND_OF_(bool)); // NOLINT +} + +TEST(KindOfTest, Integer) { + EXPECT_EQ(kInteger, GMOCK_KIND_OF_(char)); // NOLINT + EXPECT_EQ(kInteger, GMOCK_KIND_OF_(signed char)); // NOLINT + EXPECT_EQ(kInteger, GMOCK_KIND_OF_(unsigned char)); // NOLINT + EXPECT_EQ(kInteger, GMOCK_KIND_OF_(short)); // NOLINT + EXPECT_EQ(kInteger, GMOCK_KIND_OF_(unsigned short)); // NOLINT + EXPECT_EQ(kInteger, GMOCK_KIND_OF_(int)); // NOLINT + EXPECT_EQ(kInteger, GMOCK_KIND_OF_(unsigned int)); // NOLINT + EXPECT_EQ(kInteger, GMOCK_KIND_OF_(long)); // NOLINT + EXPECT_EQ(kInteger, GMOCK_KIND_OF_(unsigned long)); // NOLINT + EXPECT_EQ(kInteger, GMOCK_KIND_OF_(long long)); // NOLINT + EXPECT_EQ(kInteger, GMOCK_KIND_OF_(unsigned long long)); // NOLINT + EXPECT_EQ(kInteger, GMOCK_KIND_OF_(wchar_t)); // NOLINT + EXPECT_EQ(kInteger, GMOCK_KIND_OF_(size_t)); // NOLINT +#if GTEST_OS_LINUX || GTEST_OS_MAC || GTEST_OS_CYGWIN + // ssize_t is not defined on Windows and possibly some other OSes. + EXPECT_EQ(kInteger, GMOCK_KIND_OF_(ssize_t)); // NOLINT +#endif +} + +TEST(KindOfTest, FloatingPoint) { + EXPECT_EQ(kFloatingPoint, GMOCK_KIND_OF_(float)); // NOLINT + EXPECT_EQ(kFloatingPoint, GMOCK_KIND_OF_(double)); // NOLINT + EXPECT_EQ(kFloatingPoint, GMOCK_KIND_OF_(long double)); // NOLINT +} + +TEST(KindOfTest, Other) { + EXPECT_EQ(kOther, GMOCK_KIND_OF_(void*)); // NOLINT + EXPECT_EQ(kOther, GMOCK_KIND_OF_(char**)); // NOLINT + EXPECT_EQ(kOther, GMOCK_KIND_OF_(Base)); // NOLINT +} + +// Tests LosslessArithmeticConvertible<T, U>. + +TEST(LosslessArithmeticConvertibleTest, BoolToBool) { + EXPECT_TRUE((LosslessArithmeticConvertible<bool, bool>::value)); +} + +TEST(LosslessArithmeticConvertibleTest, BoolToInteger) { + EXPECT_TRUE((LosslessArithmeticConvertible<bool, char>::value)); + EXPECT_TRUE((LosslessArithmeticConvertible<bool, int>::value)); + EXPECT_TRUE( + (LosslessArithmeticConvertible<bool, unsigned long>::value)); // NOLINT +} + +TEST(LosslessArithmeticConvertibleTest, BoolToFloatingPoint) { + EXPECT_TRUE((LosslessArithmeticConvertible<bool, float>::value)); + EXPECT_TRUE((LosslessArithmeticConvertible<bool, double>::value)); +} + +TEST(LosslessArithmeticConvertibleTest, IntegerToBool) { + EXPECT_FALSE((LosslessArithmeticConvertible<unsigned char, bool>::value)); + EXPECT_FALSE((LosslessArithmeticConvertible<int, bool>::value)); +} + +TEST(LosslessArithmeticConvertibleTest, IntegerToInteger) { + // Unsigned => larger signed is fine. + EXPECT_TRUE((LosslessArithmeticConvertible<unsigned char, int>::value)); + + // Unsigned => larger unsigned is fine. + EXPECT_TRUE((LosslessArithmeticConvertible< + unsigned short, uint64_t>::value)); // NOLINT + + // Signed => unsigned is not fine. + EXPECT_FALSE((LosslessArithmeticConvertible< + short, uint64_t>::value)); // NOLINT + EXPECT_FALSE((LosslessArithmeticConvertible< + signed char, unsigned int>::value)); // NOLINT + + // Same size and same signedness: fine too. + EXPECT_TRUE((LosslessArithmeticConvertible< + unsigned char, unsigned char>::value)); + EXPECT_TRUE((LosslessArithmeticConvertible<int, int>::value)); + EXPECT_TRUE((LosslessArithmeticConvertible<wchar_t, wchar_t>::value)); + EXPECT_TRUE((LosslessArithmeticConvertible< + unsigned long, unsigned long>::value)); // NOLINT + + // Same size, different signedness: not fine. + EXPECT_FALSE((LosslessArithmeticConvertible< + unsigned char, signed char>::value)); + EXPECT_FALSE((LosslessArithmeticConvertible<int, unsigned int>::value)); + EXPECT_FALSE((LosslessArithmeticConvertible<uint64_t, int64_t>::value)); + + // Larger size => smaller size is not fine. + EXPECT_FALSE((LosslessArithmeticConvertible<long, char>::value)); // NOLINT + EXPECT_FALSE((LosslessArithmeticConvertible<int, signed char>::value)); + EXPECT_FALSE((LosslessArithmeticConvertible<int64_t, unsigned int>::value)); +} + +TEST(LosslessArithmeticConvertibleTest, IntegerToFloatingPoint) { + // Integers cannot be losslessly converted to floating-points, as + // the format of the latter is implementation-defined. + EXPECT_FALSE((LosslessArithmeticConvertible<char, float>::value)); + EXPECT_FALSE((LosslessArithmeticConvertible<int, double>::value)); + EXPECT_FALSE((LosslessArithmeticConvertible< + short, long double>::value)); // NOLINT +} + +TEST(LosslessArithmeticConvertibleTest, FloatingPointToBool) { + EXPECT_FALSE((LosslessArithmeticConvertible<float, bool>::value)); + EXPECT_FALSE((LosslessArithmeticConvertible<double, bool>::value)); +} + +TEST(LosslessArithmeticConvertibleTest, FloatingPointToInteger) { + EXPECT_FALSE((LosslessArithmeticConvertible<float, long>::value)); // NOLINT + EXPECT_FALSE((LosslessArithmeticConvertible<double, int64_t>::value)); + EXPECT_FALSE((LosslessArithmeticConvertible<long double, int>::value)); +} + +TEST(LosslessArithmeticConvertibleTest, FloatingPointToFloatingPoint) { + // Smaller size => larger size is fine. + EXPECT_TRUE((LosslessArithmeticConvertible<float, double>::value)); + EXPECT_TRUE((LosslessArithmeticConvertible<float, long double>::value)); + EXPECT_TRUE((LosslessArithmeticConvertible<double, long double>::value)); + + // Same size: fine. + EXPECT_TRUE((LosslessArithmeticConvertible<float, float>::value)); + EXPECT_TRUE((LosslessArithmeticConvertible<double, double>::value)); + + // Larger size => smaller size is not fine. + EXPECT_FALSE((LosslessArithmeticConvertible<double, float>::value)); + GTEST_INTENTIONAL_CONST_COND_PUSH_() + if (sizeof(double) == sizeof(long double)) { // NOLINT + GTEST_INTENTIONAL_CONST_COND_POP_() + // In some implementations (e.g. MSVC), double and long double + // have the same size. + EXPECT_TRUE((LosslessArithmeticConvertible<long double, double>::value)); + } else { + EXPECT_FALSE((LosslessArithmeticConvertible<long double, double>::value)); + } +} + +// Tests the TupleMatches() template function. + +TEST(TupleMatchesTest, WorksForSize0) { + std::tuple<> matchers; + std::tuple<> values; + + EXPECT_TRUE(TupleMatches(matchers, values)); +} + +TEST(TupleMatchesTest, WorksForSize1) { + std::tuple<Matcher<int> > matchers(Eq(1)); + std::tuple<int> values1(1), values2(2); + + EXPECT_TRUE(TupleMatches(matchers, values1)); + EXPECT_FALSE(TupleMatches(matchers, values2)); +} + +TEST(TupleMatchesTest, WorksForSize2) { + std::tuple<Matcher<int>, Matcher<char> > matchers(Eq(1), Eq('a')); + std::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) { + std::tuple<Matcher<int>, Matcher<char>, Matcher<bool>, + Matcher<long>, // NOLINT + Matcher<std::string> > + matchers(Eq(1), Eq('a'), Eq(true), Eq(2L), Eq("hi")); + std::tuple<int, char, bool, long, std::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. +} + +// Tests that Assert(false, ...) generates a fatal failure. +TEST(AssertTest, FailsFatallyOnFalse) { + EXPECT_DEATH_IF_SUPPORTED({ + Assert(false, __FILE__, __LINE__, "This should fail."); + }, ""); + + EXPECT_DEATH_IF_SUPPORTED({ + Assert(false, __FILE__, __LINE__); + }, ""); +} + +// 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"); +} + +// Tests LogIsVisible(). + +class LogIsVisibleTest : public ::testing::Test { + protected: + void SetUp() override { original_verbose_ = GMOCK_FLAG(verbose); } + + void TearDown() override { GMOCK_FLAG(verbose) = original_verbose_; } + + std::string original_verbose_; +}; + +TEST_F(LogIsVisibleTest, AlwaysReturnsTrueIfVerbosityIsInfo) { + GMOCK_FLAG(verbose) = kInfoVerbosity; + EXPECT_TRUE(LogIsVisible(kInfo)); + EXPECT_TRUE(LogIsVisible(kWarning)); +} + +TEST_F(LogIsVisibleTest, AlwaysReturnsFalseIfVerbosityIsError) { + GMOCK_FLAG(verbose) = kErrorVerbosity; + EXPECT_FALSE(LogIsVisible(kInfo)); + EXPECT_FALSE(LogIsVisible(kWarning)); +} + +TEST_F(LogIsVisibleTest, WorksWhenVerbosityIsWarning) { + GMOCK_FLAG(verbose) = kWarningVerbosity; + EXPECT_FALSE(LogIsVisible(kInfo)); + EXPECT_TRUE(LogIsVisible(kWarning)); +} + +#if GTEST_HAS_STREAM_REDIRECTION + +// Tests the Log() function. + +// Verifies that Log() behaves correctly for the given verbosity level +// and log severity. +void TestLogWithSeverity(const std::string& verbosity, LogSeverity severity, + bool should_print) { + const std::string old_flag = GMOCK_FLAG(verbose); + GMOCK_FLAG(verbose) = verbosity; + CaptureStdout(); + Log(severity, "Test log.\n", 0); + if (should_print) { + EXPECT_THAT(GetCapturedStdout().c_str(), + ContainsRegex( + severity == kWarning ? + "^\nGMOCK WARNING:\nTest log\\.\nStack trace:\n" : + "^\nTest log\\.\nStack trace:\n")); + } else { + EXPECT_STREQ("", GetCapturedStdout().c_str()); + } + 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) { + const std::string saved_flag = GMOCK_FLAG(verbose); + GMOCK_FLAG(verbose) = kInfoVerbosity; + CaptureStdout(); + Log(kInfo, "Test log.\n", -1); + EXPECT_STREQ("\nTest log.\n", GetCapturedStdout().c_str()); + GMOCK_FLAG(verbose) = saved_flag; +} + +struct MockStackTraceGetter : testing::internal::OsStackTraceGetterInterface { + std::string CurrentStackTrace(int max_depth, int skip_count) override { + return (testing::Message() << max_depth << "::" << skip_count << "\n") + .GetString(); + } + void UponLeavingGTest() override {} +}; + +// Tests that in opt mode, a positive stack_frames_to_skip argument is +// treated as 0. +TEST(LogTest, NoSkippingStackFrameInOptMode) { + MockStackTraceGetter* mock_os_stack_trace_getter = new MockStackTraceGetter; + GetUnitTestImpl()->set_os_stack_trace_getter(mock_os_stack_trace_getter); + + CaptureStdout(); + Log(kWarning, "Test log.\n", 100); + const std::string log = GetCapturedStdout(); + + std::string expected_trace = + (testing::Message() << GTEST_FLAG(stack_trace_depth) << "::").GetString(); + std::string expected_message = + "\nGMOCK WARNING:\n" + "Test log.\n" + "Stack trace:\n" + + expected_trace; + EXPECT_THAT(log, HasSubstr(expected_message)); + int skip_count = atoi(log.substr(expected_message.size()).c_str()); + +# if defined(NDEBUG) + // In opt mode, no stack frame should be skipped. + const int expected_skip_count = 0; +# else + // In dbg mode, the stack frames should be skipped. + const int expected_skip_count = 100; +# endif + + // Note that each inner implementation layer will +1 the number to remove + // itself from the trace. This means that the value is a little higher than + // expected, but close enough. + EXPECT_THAT(skip_count, + AllOf(Ge(expected_skip_count), Le(expected_skip_count + 10))); + + // Restores the default OS stack trace getter. + GetUnitTestImpl()->set_os_stack_trace_getter(nullptr); +} + +// Tests that all logs are printed when the value of the +// --gmock_verbose flag is "info". +TEST(LogTest, AllLogsArePrintedWhenVerbosityIsInfo) { + TestLogWithSeverity(kInfoVerbosity, kInfo, true); + TestLogWithSeverity(kInfoVerbosity, kWarning, true); +} + +// Tests that only warnings are printed when the value of the +// --gmock_verbose flag is "warning". +TEST(LogTest, OnlyWarningsArePrintedWhenVerbosityIsWarning) { + TestLogWithSeverity(kWarningVerbosity, kInfo, false); + TestLogWithSeverity(kWarningVerbosity, kWarning, true); +} + +// Tests that no logs are printed when the value of the +// --gmock_verbose flag is "error". +TEST(LogTest, NoLogsArePrintedWhenVerbosityIsError) { + TestLogWithSeverity(kErrorVerbosity, kInfo, false); + TestLogWithSeverity(kErrorVerbosity, kWarning, false); +} + +// Tests that only warnings are printed when the value of the +// --gmock_verbose flag is invalid. +TEST(LogTest, OnlyWarningsArePrintedWhenVerbosityIsInvalid) { + TestLogWithSeverity("invalid", kInfo, false); + TestLogWithSeverity("invalid", kWarning, true); +} + +// Verifies that Log() behaves correctly for the given verbosity level +// and log severity. +std::string GrabOutput(void(*logger)(), const char* verbosity) { + const std::string saved_flag = GMOCK_FLAG(verbose); + GMOCK_FLAG(verbose) = verbosity; + CaptureStdout(); + logger(); + GMOCK_FLAG(verbose) = saved_flag; + return GetCapturedStdout(); +} + +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(std::string(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_STREQ("", GrabOutput(ExpectCallLogger, kWarningVerbosity).c_str()); +} + +// Verifies that EXPECT_CALL doesn't log +// if the --gmock_verbose flag is set to "error". +TEST(ExpectCallTest, DoesNotLogWhenVerbosityIsError) { + EXPECT_STREQ("", GrabOutput(ExpectCallLogger, kErrorVerbosity).c_str()); +} + +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(std::string(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_STREQ("", GrabOutput(OnCallLogger, kWarningVerbosity).c_str()); +} + +// Verifies that ON_CALL doesn't log if +// the --gmock_verbose flag is set to "error". +TEST(OnCallTest, DoesNotLogWhenVerbosityIsError) { + EXPECT_STREQ("", GrabOutput(OnCallLogger, kErrorVerbosity).c_str()); +} + +void OnCallAnyArgumentLogger() { + DummyMock mock; + ON_CALL(mock, TestMethodArg(_)); +} + +// Verifies that ON_CALL prints provided _ argument. +TEST(OnCallTest, LogsAnythingArgument) { + EXPECT_THAT(std::string(GrabOutput(OnCallAnyArgumentLogger, kInfoVerbosity)), + HasSubstr("ON_CALL(mock, TestMethodArg(_)")); +} + +#endif // GTEST_HAS_STREAM_REDIRECTION + +// Tests StlContainerView. + +TEST(StlContainerViewTest, WorksForStlContainer) { + StaticAssertTypeEq<std::vector<int>, + StlContainerView<std::vector<int> >::type>(); + StaticAssertTypeEq<const std::vector<double>&, + StlContainerView<std::vector<double> >::const_reference>(); + + typedef std::vector<char> Chars; + Chars v1; + const Chars& v2(StlContainerView<Chars>::ConstReference(v1)); + EXPECT_EQ(&v1, &v2); + + v1.push_back('a'); + Chars v3 = StlContainerView<Chars>::Copy(v1); + EXPECT_THAT(v3, Eq(v3)); +} + +TEST(StlContainerViewTest, WorksForStaticNativeArray) { + StaticAssertTypeEq<NativeArray<int>, + StlContainerView<int[3]>::type>(); + StaticAssertTypeEq<NativeArray<double>, + StlContainerView<const double[4]>::type>(); + StaticAssertTypeEq<NativeArray<char[3]>, + StlContainerView<const char[2][3]>::type>(); + + StaticAssertTypeEq<const NativeArray<int>, + StlContainerView<int[2]>::const_reference>(); + + int a1[3] = { 0, 1, 2 }; + NativeArray<int> a2 = StlContainerView<int[3]>::ConstReference(a1); + EXPECT_EQ(3U, a2.size()); + EXPECT_EQ(a1, a2.begin()); + + const NativeArray<int> a3 = StlContainerView<int[3]>::Copy(a1); + ASSERT_EQ(3U, a3.size()); + EXPECT_EQ(0, a3.begin()[0]); + EXPECT_EQ(1, a3.begin()[1]); + EXPECT_EQ(2, a3.begin()[2]); + + // Makes sure a1 and a3 aren't aliases. + a1[0] = 3; + EXPECT_EQ(0, a3.begin()[0]); +} + +TEST(StlContainerViewTest, WorksForDynamicNativeArray) { + StaticAssertTypeEq<NativeArray<int>, + StlContainerView<std::tuple<const int*, size_t> >::type>(); + StaticAssertTypeEq< + NativeArray<double>, + StlContainerView<std::tuple<std::shared_ptr<double>, int> >::type>(); + + StaticAssertTypeEq< + const NativeArray<int>, + StlContainerView<std::tuple<const int*, int> >::const_reference>(); + + int a1[3] = { 0, 1, 2 }; + const int* const p1 = a1; + NativeArray<int> a2 = + StlContainerView<std::tuple<const int*, int> >::ConstReference( + std::make_tuple(p1, 3)); + EXPECT_EQ(3U, a2.size()); + EXPECT_EQ(a1, a2.begin()); + + const NativeArray<int> a3 = StlContainerView<std::tuple<int*, size_t> >::Copy( + std::make_tuple(static_cast<int*>(a1), 3)); + ASSERT_EQ(3U, a3.size()); + EXPECT_EQ(0, a3.begin()[0]); + EXPECT_EQ(1, a3.begin()[1]); + EXPECT_EQ(2, a3.begin()[2]); + + // Makes sure a1 and a3 aren't aliases. + a1[0] = 3; + EXPECT_EQ(0, a3.begin()[0]); +} + +// Tests the Function template struct. + +TEST(FunctionTest, Nullary) { + typedef Function<int()> F; // NOLINT + EXPECT_EQ(0u, F::ArgumentCount); + EXPECT_TRUE((std::is_same<int, F::Result>::value)); + EXPECT_TRUE((std::is_same<std::tuple<>, F::ArgumentTuple>::value)); + EXPECT_TRUE((std::is_same<std::tuple<>, F::ArgumentMatcherTuple>::value)); + EXPECT_TRUE((std::is_same<void(), F::MakeResultVoid>::value)); + EXPECT_TRUE((std::is_same<IgnoredValue(), F::MakeResultIgnoredValue>::value)); +} + +TEST(FunctionTest, Unary) { + typedef Function<int(bool)> F; // NOLINT + EXPECT_EQ(1u, F::ArgumentCount); + EXPECT_TRUE((std::is_same<int, F::Result>::value)); + EXPECT_TRUE((std::is_same<bool, F::Arg<0>::type>::value)); + EXPECT_TRUE((std::is_same<std::tuple<bool>, F::ArgumentTuple>::value)); + EXPECT_TRUE(( + std::is_same<std::tuple<Matcher<bool>>, F::ArgumentMatcherTuple>::value)); + EXPECT_TRUE((std::is_same<void(bool), F::MakeResultVoid>::value)); // NOLINT + EXPECT_TRUE((std::is_same<IgnoredValue(bool), // NOLINT + F::MakeResultIgnoredValue>::value)); +} + +TEST(FunctionTest, Binary) { + typedef Function<int(bool, const long&)> F; // NOLINT + EXPECT_EQ(2u, F::ArgumentCount); + EXPECT_TRUE((std::is_same<int, F::Result>::value)); + EXPECT_TRUE((std::is_same<bool, F::Arg<0>::type>::value)); + EXPECT_TRUE((std::is_same<const long&, F::Arg<1>::type>::value)); // NOLINT + EXPECT_TRUE((std::is_same<std::tuple<bool, const long&>, // NOLINT + F::ArgumentTuple>::value)); + EXPECT_TRUE( + (std::is_same<std::tuple<Matcher<bool>, Matcher<const long&>>, // NOLINT + F::ArgumentMatcherTuple>::value)); + EXPECT_TRUE((std::is_same<void(bool, const long&), // NOLINT + F::MakeResultVoid>::value)); + EXPECT_TRUE((std::is_same<IgnoredValue(bool, const long&), // NOLINT + F::MakeResultIgnoredValue>::value)); +} + +TEST(FunctionTest, LongArgumentList) { + typedef Function<char(bool, int, char*, int&, const long&)> F; // NOLINT + EXPECT_EQ(5u, F::ArgumentCount); + EXPECT_TRUE((std::is_same<char, F::Result>::value)); + EXPECT_TRUE((std::is_same<bool, F::Arg<0>::type>::value)); + EXPECT_TRUE((std::is_same<int, F::Arg<1>::type>::value)); + EXPECT_TRUE((std::is_same<char*, F::Arg<2>::type>::value)); + EXPECT_TRUE((std::is_same<int&, F::Arg<3>::type>::value)); + EXPECT_TRUE((std::is_same<const long&, F::Arg<4>::type>::value)); // NOLINT + EXPECT_TRUE( + (std::is_same<std::tuple<bool, int, char*, int&, const long&>, // NOLINT + F::ArgumentTuple>::value)); + EXPECT_TRUE( + (std::is_same< + std::tuple<Matcher<bool>, Matcher<int>, Matcher<char*>, Matcher<int&>, + Matcher<const long&>>, // NOLINT + F::ArgumentMatcherTuple>::value)); + EXPECT_TRUE( + (std::is_same<void(bool, int, char*, int&, const long&), // NOLINT + F::MakeResultVoid>::value)); + EXPECT_TRUE(( + std::is_same<IgnoredValue(bool, int, char*, int&, const long&), // NOLINT + F::MakeResultIgnoredValue>::value)); +} + +} // namespace +} // namespace internal +} // namespace testing diff --git a/src/googletest/googlemock/test/gmock-matchers_test.cc b/src/googletest/googlemock/test/gmock-matchers_test.cc new file mode 100644 index 000000000..3ac166827 --- /dev/null +++ b/src/googletest/googlemock/test/gmock-matchers_test.cc @@ -0,0 +1,8562 @@ +// 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. + + +// Google Mock - a framework for writing C++ mock classes. +// +// This file tests some commonly used argument matchers. + +// Silence warning C4244: 'initializing': conversion from 'int' to 'short', +// possible loss of data and C4100, unreferenced local parameter +#ifdef _MSC_VER +# pragma warning(push) +# pragma warning(disable:4244) +# pragma warning(disable:4100) +#endif + +#include "gmock/gmock-matchers.h" + +#include <string.h> +#include <time.h> + +#include <array> +#include <cstdint> +#include <deque> +#include <forward_list> +#include <functional> +#include <iostream> +#include <iterator> +#include <limits> +#include <list> +#include <map> +#include <memory> +#include <set> +#include <sstream> +#include <string> +#include <type_traits> +#include <unordered_map> +#include <unordered_set> +#include <utility> +#include <vector> + +#include "gmock/gmock-more-matchers.h" +#include "gmock/gmock.h" +#include "gtest/gtest-spi.h" +#include "gtest/gtest.h" + +namespace testing { +namespace gmock_matchers_test { +namespace { + +using std::greater; +using std::less; +using std::list; +using std::make_pair; +using std::map; +using std::multimap; +using std::multiset; +using std::ostream; +using std::pair; +using std::set; +using std::stringstream; +using std::vector; +using testing::internal::DummyMatchResultListener; +using testing::internal::ElementMatcherPair; +using testing::internal::ElementMatcherPairs; +using testing::internal::ElementsAreArrayMatcher; +using testing::internal::ExplainMatchFailureTupleTo; +using testing::internal::FloatingEqMatcher; +using testing::internal::FormatMatcherDescription; +using testing::internal::IsReadableTypeName; +using testing::internal::MatchMatrix; +using testing::internal::PredicateFormatterFromMatcher; +using testing::internal::RE; +using testing::internal::StreamMatchResultListener; +using testing::internal::Strings; + +// Helper for testing container-valued matchers in mock method context. It is +// important to test matchers in this context, since it requires additional type +// deduction beyond what EXPECT_THAT does, thus making it more restrictive. +struct ContainerHelper { + MOCK_METHOD1(Call, void(std::vector<std::unique_ptr<int>>)); +}; + +std::vector<std::unique_ptr<int>> MakeUniquePtrs(const std::vector<int>& ints) { + std::vector<std::unique_ptr<int>> pointers; + for (int i : ints) pointers.emplace_back(new int(i)); + return pointers; +} + +// For testing ExplainMatchResultTo(). +class GreaterThanMatcher : public MatcherInterface<int> { + public: + explicit GreaterThanMatcher(int rhs) : rhs_(rhs) {} + + void DescribeTo(ostream* os) const override { *os << "is > " << rhs_; } + + bool MatchAndExplain(int lhs, MatchResultListener* listener) const override { + const int diff = lhs - rhs_; + if (diff > 0) { + *listener << "which is " << diff << " more than " << rhs_; + } else if (diff == 0) { + *listener << "which is the same as " << rhs_; + } else { + *listener << "which is " << -diff << " less than " << rhs_; + } + + return lhs > rhs_; + } + + private: + int rhs_; +}; + +Matcher<int> GreaterThan(int n) { + return MakeMatcher(new GreaterThanMatcher(n)); +} + +std::string OfType(const std::string& type_name) { +#if GTEST_HAS_RTTI + return IsReadableTypeName(type_name) ? " (of type " + type_name + ")" : ""; +#else + return ""; +#endif +} + +// Returns the description of the given matcher. +template <typename T> +std::string Describe(const Matcher<T>& m) { + return DescribeMatcher<T>(m); +} + +// Returns the description of the negation of the given matcher. +template <typename T> +std::string DescribeNegation(const Matcher<T>& m) { + return DescribeMatcher<T>(m, true); +} + +// Returns the reason why x matches, or doesn't match, m. +template <typename MatcherType, typename Value> +std::string Explain(const MatcherType& m, const Value& x) { + StringMatchResultListener listener; + ExplainMatchResult(m, x, &listener); + return listener.str(); +} + +TEST(MonotonicMatcherTest, IsPrintable) { + stringstream ss; + ss << GreaterThan(5); + EXPECT_EQ("is > 5", ss.str()); +} + +TEST(MatchResultListenerTest, StreamingWorks) { + StringMatchResultListener listener; + listener << "hi" << 5; + EXPECT_EQ("hi5", listener.str()); + + listener.Clear(); + EXPECT_EQ("", listener.str()); + + listener << 42; + EXPECT_EQ("42", listener.str()); + + // Streaming shouldn't crash when the underlying ostream is NULL. + DummyMatchResultListener dummy; + dummy << "hi" << 5; +} + +TEST(MatchResultListenerTest, CanAccessUnderlyingStream) { + EXPECT_TRUE(DummyMatchResultListener().stream() == nullptr); + EXPECT_TRUE(StreamMatchResultListener(nullptr).stream() == nullptr); + + EXPECT_EQ(&std::cout, StreamMatchResultListener(&std::cout).stream()); +} + +TEST(MatchResultListenerTest, IsInterestedWorks) { + EXPECT_TRUE(StringMatchResultListener().IsInterested()); + EXPECT_TRUE(StreamMatchResultListener(&std::cout).IsInterested()); + + EXPECT_FALSE(DummyMatchResultListener().IsInterested()); + EXPECT_FALSE(StreamMatchResultListener(nullptr).IsInterested()); +} + +// Makes sure that the MatcherInterface<T> interface doesn't +// change. +class EvenMatcherImpl : public MatcherInterface<int> { + public: + bool MatchAndExplain(int x, + MatchResultListener* /* listener */) const override { + return x % 2 == 0; + } + + void DescribeTo(ostream* os) const override { *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. +}; + +// Makes sure that the MatcherInterface API doesn't change. +TEST(MatcherInterfaceTest, CanBeImplementedUsingPublishedAPI) { + EvenMatcherImpl m; +} + +// Tests implementing a monomorphic matcher using MatchAndExplain(). + +class NewEvenMatcherImpl : public MatcherInterface<int> { + public: + bool MatchAndExplain(int x, MatchResultListener* listener) const override { + const bool match = x % 2 == 0; + // Verifies that we can stream to a listener directly. + *listener << "value % " << 2; + if (listener->stream() != nullptr) { + // Verifies that we can stream to a listener's underlying stream + // too. + *listener->stream() << " == " << (x % 2); + } + return match; + } + + void DescribeTo(ostream* os) const override { *os << "is an even number"; } +}; + +TEST(MatcherInterfaceTest, CanBeImplementedUsingNewAPI) { + Matcher<int> m = MakeMatcher(new NewEvenMatcherImpl); + EXPECT_TRUE(m.Matches(2)); + EXPECT_FALSE(m.Matches(3)); + EXPECT_EQ("value % 2 == 0", Explain(m, 2)); + EXPECT_EQ("value % 2 == 1", Explain(m, 3)); +} + +// 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 = nullptr; + EXPECT_TRUE(m1.Matches(nullptr)); + int n = 0; + EXPECT_FALSE(m1.Matches(&n)); +} + +// Tests that matchers can be constructed from a variable that is not properly +// defined. This should be illegal, but many users rely on this accidentally. +struct Undefined { + virtual ~Undefined() = 0; + static const int kInt = 1; +}; + +TEST(MatcherTest, CanBeConstructedFromUndefinedVariable) { + Matcher<int> m1 = Undefined::kInt; + EXPECT_TRUE(m1.Matches(1)); + EXPECT_FALSE(m1.Matches(2)); +} + +// Test that a matcher parameterized with an abstract class compiles. +TEST(MatcherTest, CanAcceptAbstractClass) { Matcher<const Undefined&> m = _; } + +// 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 Matcher<T>::MatchAndExplain(). +TEST(MatcherTest, MatchAndExplain) { + Matcher<int> m = GreaterThan(0); + StringMatchResultListener listener1; + EXPECT_TRUE(m.MatchAndExplain(42, &listener1)); + EXPECT_EQ("which is 42 more than 0", listener1.str()); + + StringMatchResultListener listener2; + EXPECT_FALSE(m.MatchAndExplain(-9, &listener2)); + EXPECT_EQ("which is 9 less than 0", listener2.str()); +} + +// Tests that a C-string literal can be implicitly converted to a +// Matcher<std::string> or Matcher<const std::string&>. +TEST(StringMatcherTest, CanBeImplicitlyConstructedFromCStringLiteral) { + Matcher<std::string> m1 = "hi"; + EXPECT_TRUE(m1.Matches("hi")); + EXPECT_FALSE(m1.Matches("hello")); + + Matcher<const std::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<std::string> or Matcher<const std::string&>. +TEST(StringMatcherTest, CanBeImplicitlyConstructedFromString) { + Matcher<std::string> m1 = std::string("hi"); + EXPECT_TRUE(m1.Matches("hi")); + EXPECT_FALSE(m1.Matches("hello")); + + Matcher<const std::string&> m2 = std::string("hi"); + EXPECT_TRUE(m2.Matches("hi")); + EXPECT_FALSE(m2.Matches("hello")); +} + +#if GTEST_INTERNAL_HAS_STRING_VIEW +// Tests that a C-string literal can be implicitly converted to a +// Matcher<StringView> or Matcher<const StringView&>. +TEST(StringViewMatcherTest, CanBeImplicitlyConstructedFromCStringLiteral) { + Matcher<internal::StringView> m1 = "cats"; + EXPECT_TRUE(m1.Matches("cats")); + EXPECT_FALSE(m1.Matches("dogs")); + + Matcher<const internal::StringView&> m2 = "cats"; + EXPECT_TRUE(m2.Matches("cats")); + EXPECT_FALSE(m2.Matches("dogs")); +} + +// Tests that a std::string object can be implicitly converted to a +// Matcher<StringView> or Matcher<const StringView&>. +TEST(StringViewMatcherTest, CanBeImplicitlyConstructedFromString) { + Matcher<internal::StringView> m1 = std::string("cats"); + EXPECT_TRUE(m1.Matches("cats")); + EXPECT_FALSE(m1.Matches("dogs")); + + Matcher<const internal::StringView&> m2 = std::string("cats"); + EXPECT_TRUE(m2.Matches("cats")); + EXPECT_FALSE(m2.Matches("dogs")); +} + +// Tests that a StringView object can be implicitly converted to a +// Matcher<StringView> or Matcher<const StringView&>. +TEST(StringViewMatcherTest, CanBeImplicitlyConstructedFromStringView) { + Matcher<internal::StringView> m1 = internal::StringView("cats"); + EXPECT_TRUE(m1.Matches("cats")); + EXPECT_FALSE(m1.Matches("dogs")); + + Matcher<const internal::StringView&> m2 = internal::StringView("cats"); + EXPECT_TRUE(m2.Matches("cats")); + EXPECT_FALSE(m2.Matches("dogs")); +} +#endif // GTEST_INTERNAL_HAS_STRING_VIEW + +// Tests that a std::reference_wrapper<std::string> object can be implicitly +// converted to a Matcher<std::string> or Matcher<const std::string&> via Eq(). +TEST(StringMatcherTest, + CanBeImplicitlyConstructedFromEqReferenceWrapperString) { + std::string value = "cats"; + Matcher<std::string> m1 = Eq(std::ref(value)); + EXPECT_TRUE(m1.Matches("cats")); + EXPECT_FALSE(m1.Matches("dogs")); + + Matcher<const std::string&> m2 = Eq(std::ref(value)); + EXPECT_TRUE(m2.Matches("cats")); + EXPECT_FALSE(m2.Matches("dogs")); +} + +// 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 = nullptr; + Matcher<int> m = MakeMatcher(dummy_impl); +} + +// Tests that MakePolymorphicMatcher() can construct a polymorphic +// matcher from its implementation using the old API. +const int g_bar = 1; +class ReferencesBarOrIsZeroImpl { + public: + template <typename T> + bool MatchAndExplain(const T& x, + MatchResultListener* /* listener */) const { + const void* p = &x; + return p == &g_bar || x == 0; + } + + void DescribeTo(ostream* os) const { *os << "g_bar or zero"; } + + void DescribeNegationTo(ostream* os) const { + *os << "doesn't reference g_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, ConstructsMatcherUsingOldAPI) { + // 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(g_bar)); + EXPECT_FALSE(m1.Matches(1)); + EXPECT_EQ("g_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("g_bar or zero", Describe(m2)); +} + +// Tests implementing a polymorphic matcher using MatchAndExplain(). + +class PolymorphicIsEvenImpl { + public: + void DescribeTo(ostream* os) const { *os << "is even"; } + + void DescribeNegationTo(ostream* os) const { + *os << "is odd"; + } + + template <typename T> + bool MatchAndExplain(const T& x, MatchResultListener* listener) const { + // Verifies that we can stream to the listener directly. + *listener << "% " << 2; + if (listener->stream() != nullptr) { + // Verifies that we can stream to the listener's underlying stream + // too. + *listener->stream() << " == " << (x % 2); + } + return (x % 2) == 0; + } +}; + +PolymorphicMatcher<PolymorphicIsEvenImpl> PolymorphicIsEven() { + return MakePolymorphicMatcher(PolymorphicIsEvenImpl()); +} + +TEST(MakePolymorphicMatcherTest, ConstructsMatcherUsingNewAPI) { + // Using PolymorphicIsEven() as a Matcher<int>. + const Matcher<int> m1 = PolymorphicIsEven(); + EXPECT_TRUE(m1.Matches(42)); + EXPECT_FALSE(m1.Matches(43)); + EXPECT_EQ("is even", Describe(m1)); + + const Matcher<int> not_m1 = Not(m1); + EXPECT_EQ("is odd", Describe(not_m1)); + + EXPECT_EQ("% 2 == 0", Explain(m1, 42)); + + // Using PolymorphicIsEven() as a Matcher<char>. + const Matcher<char> m2 = PolymorphicIsEven(); + EXPECT_TRUE(m2.Matches('\x42')); + EXPECT_FALSE(m2.Matches('\x43')); + EXPECT_EQ("is even", Describe(m2)); + + const Matcher<char> not_m2 = Not(m2); + EXPECT_EQ("is odd", Describe(not_m2)); + + EXPECT_EQ("% 2 == 0", Explain(m2, '\x42')); +} + +// 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 a_value) : value_(a_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 MatcherCast<T>(m) works when m is a value of the same type as the +// value type of the Matcher. +TEST(MatcherCastTest, FromAValue) { + Matcher<int> m = MatcherCast<int>(42); + EXPECT_TRUE(m.Matches(42)); + EXPECT_FALSE(m.Matches(239)); +} + +// Tests that MatcherCast<T>(m) works when m is a value of the type implicitly +// convertible to the value type of the Matcher. +TEST(MatcherCastTest, FromAnImplicitlyConvertibleValue) { + const int kExpected = 'c'; + Matcher<int> m = MatcherCast<int>('c'); + EXPECT_TRUE(m.Matches(kExpected)); + EXPECT_FALSE(m.Matches(kExpected + 1)); +} + +struct NonImplicitlyConstructibleTypeWithOperatorEq { + friend bool operator==( + const NonImplicitlyConstructibleTypeWithOperatorEq& /* ignored */, + int rhs) { + return 42 == rhs; + } + friend bool operator==( + int lhs, + const NonImplicitlyConstructibleTypeWithOperatorEq& /* ignored */) { + return lhs == 42; + } +}; + +// Tests that MatcherCast<T>(m) works when m is a neither a matcher nor +// implicitly convertible to the value type of the Matcher, but the value type +// of the matcher has operator==() overload accepting m. +TEST(MatcherCastTest, NonImplicitlyConstructibleTypeWithOperatorEq) { + Matcher<NonImplicitlyConstructibleTypeWithOperatorEq> m1 = + MatcherCast<NonImplicitlyConstructibleTypeWithOperatorEq>(42); + EXPECT_TRUE(m1.Matches(NonImplicitlyConstructibleTypeWithOperatorEq())); + + Matcher<NonImplicitlyConstructibleTypeWithOperatorEq> m2 = + MatcherCast<NonImplicitlyConstructibleTypeWithOperatorEq>(239); + EXPECT_FALSE(m2.Matches(NonImplicitlyConstructibleTypeWithOperatorEq())); + + // When updating the following lines please also change the comment to + // namespace convertible_from_any. + Matcher<int> m3 = + MatcherCast<int>(NonImplicitlyConstructibleTypeWithOperatorEq()); + EXPECT_TRUE(m3.Matches(42)); + EXPECT_FALSE(m3.Matches(239)); +} + +// ConvertibleFromAny does not work with MSVC. resulting in +// error C2440: 'initializing': cannot convert from 'Eq' to 'M' +// No constructor could take the source type, or constructor overload +// resolution was ambiguous + +#if !defined _MSC_VER + +// The below ConvertibleFromAny struct is implicitly constructible from anything +// and when in the same namespace can interact with other tests. In particular, +// if it is in the same namespace as other tests and one removes +// NonImplicitlyConstructibleTypeWithOperatorEq::operator==(int lhs, ...); +// then the corresponding test still compiles (and it should not!) by implicitly +// converting NonImplicitlyConstructibleTypeWithOperatorEq to ConvertibleFromAny +// in m3.Matcher(). +namespace convertible_from_any { +// Implicitly convertible from any type. +struct ConvertibleFromAny { + ConvertibleFromAny(int a_value) : value(a_value) {} + template <typename T> + ConvertibleFromAny(const T& /*a_value*/) : value(-1) { + ADD_FAILURE() << "Conversion constructor called"; + } + int value; +}; + +bool operator==(const ConvertibleFromAny& a, const ConvertibleFromAny& b) { + return a.value == b.value; +} + +ostream& operator<<(ostream& os, const ConvertibleFromAny& a) { + return os << a.value; +} + +TEST(MatcherCastTest, ConversionConstructorIsUsed) { + Matcher<ConvertibleFromAny> m = MatcherCast<ConvertibleFromAny>(1); + EXPECT_TRUE(m.Matches(ConvertibleFromAny(1))); + EXPECT_FALSE(m.Matches(ConvertibleFromAny(2))); +} + +TEST(MatcherCastTest, FromConvertibleFromAny) { + Matcher<ConvertibleFromAny> m = + MatcherCast<ConvertibleFromAny>(Eq(ConvertibleFromAny(1))); + EXPECT_TRUE(m.Matches(ConvertibleFromAny(1))); + EXPECT_FALSE(m.Matches(ConvertibleFromAny(2))); +} +} // namespace convertible_from_any + +#endif // !defined _MSC_VER + +struct IntReferenceWrapper { + IntReferenceWrapper(const int& a_value) : value(&a_value) {} + const int* value; +}; + +bool operator==(const IntReferenceWrapper& a, const IntReferenceWrapper& b) { + return a.value == b.value; +} + +TEST(MatcherCastTest, ValueIsNotCopied) { + int n = 42; + Matcher<IntReferenceWrapper> m = MatcherCast<IntReferenceWrapper>(n); + // Verify that the matcher holds a reference to n, not to its temporary copy. + EXPECT_TRUE(m.Matches(n)); +} + +class Base { + public: + virtual ~Base() {} + Base() {} + private: + GTEST_DISALLOW_COPY_AND_ASSIGN_(Base); +}; + +class Derived : public Base { + public: + Derived() : Base() {} + int i; +}; + +class OtherDerived : public Base {}; + +// Tests that SafeMatcherCast<T>(m) works when m is a polymorphic matcher. +TEST(SafeMatcherCastTest, FromPolymorphicMatcher) { + Matcher<char> m2 = SafeMatcherCast<char>(Eq(32)); + EXPECT_TRUE(m2.Matches(' ')); + EXPECT_FALSE(m2.Matches('\n')); +} + +// Tests that SafeMatcherCast<T>(m) works when m is a Matcher<U> where +// T and U are arithmetic types and T can be losslessly converted to +// U. +TEST(SafeMatcherCastTest, FromLosslesslyConvertibleArithmeticType) { + Matcher<double> m1 = DoubleEq(1.0); + Matcher<float> m2 = SafeMatcherCast<float>(m1); + EXPECT_TRUE(m2.Matches(1.0f)); + EXPECT_FALSE(m2.Matches(2.0f)); + + Matcher<char> m3 = SafeMatcherCast<char>(TypedEq<int>('a')); + EXPECT_TRUE(m3.Matches('a')); + EXPECT_FALSE(m3.Matches('b')); +} + +// Tests that SafeMatcherCast<T>(m) works when m is a Matcher<U> where T and U +// are pointers or references to a derived and a base class, correspondingly. +TEST(SafeMatcherCastTest, FromBaseClass) { + Derived d, d2; + Matcher<Base*> m1 = Eq(&d); + Matcher<Derived*> m2 = SafeMatcherCast<Derived*>(m1); + EXPECT_TRUE(m2.Matches(&d)); + EXPECT_FALSE(m2.Matches(&d2)); + + Matcher<Base&> m3 = Ref(d); + Matcher<Derived&> m4 = SafeMatcherCast<Derived&>(m3); + EXPECT_TRUE(m4.Matches(d)); + EXPECT_FALSE(m4.Matches(d2)); +} + +// Tests that SafeMatcherCast<T&>(m) works when m is a Matcher<const T&>. +TEST(SafeMatcherCastTest, FromConstReferenceToReference) { + int n = 0; + Matcher<const int&> m1 = Ref(n); + Matcher<int&> m2 = SafeMatcherCast<int&>(m1); + int n1 = 0; + EXPECT_TRUE(m2.Matches(n)); + EXPECT_FALSE(m2.Matches(n1)); +} + +// Tests that MatcherCast<const T&>(m) works when m is a Matcher<T>. +TEST(SafeMatcherCastTest, FromNonReferenceToConstReference) { + Matcher<std::unique_ptr<int>> m1 = IsNull(); + Matcher<const std::unique_ptr<int>&> m2 = + SafeMatcherCast<const std::unique_ptr<int>&>(m1); + EXPECT_TRUE(m2.Matches(std::unique_ptr<int>())); + EXPECT_FALSE(m2.Matches(std::unique_ptr<int>(new int))); +} + +// Tests that SafeMatcherCast<T&>(m) works when m is a Matcher<T>. +TEST(SafeMatcherCastTest, FromNonReferenceToReference) { + Matcher<int> m1 = Eq(0); + Matcher<int&> m2 = SafeMatcherCast<int&>(m1); + int n = 0; + EXPECT_TRUE(m2.Matches(n)); + n = 1; + EXPECT_FALSE(m2.Matches(n)); +} + +// Tests that SafeMatcherCast<T>(m) works when m is a Matcher<T>. +TEST(SafeMatcherCastTest, FromSameType) { + Matcher<int> m1 = Eq(0); + Matcher<int> m2 = SafeMatcherCast<int>(m1); + EXPECT_TRUE(m2.Matches(0)); + EXPECT_FALSE(m2.Matches(1)); +} + +#if !defined _MSC_VER + +namespace convertible_from_any { +TEST(SafeMatcherCastTest, ConversionConstructorIsUsed) { + Matcher<ConvertibleFromAny> m = SafeMatcherCast<ConvertibleFromAny>(1); + EXPECT_TRUE(m.Matches(ConvertibleFromAny(1))); + EXPECT_FALSE(m.Matches(ConvertibleFromAny(2))); +} + +TEST(SafeMatcherCastTest, FromConvertibleFromAny) { + Matcher<ConvertibleFromAny> m = + SafeMatcherCast<ConvertibleFromAny>(Eq(ConvertibleFromAny(1))); + EXPECT_TRUE(m.Matches(ConvertibleFromAny(1))); + EXPECT_FALSE(m.Matches(ConvertibleFromAny(2))); +} +} // namespace convertible_from_any + +#endif // !defined _MSC_VER + +TEST(SafeMatcherCastTest, ValueIsNotCopied) { + int n = 42; + Matcher<IntReferenceWrapper> m = SafeMatcherCast<IntReferenceWrapper>(n); + // Verify that the matcher holds a reference to n, not to its temporary copy. + EXPECT_TRUE(m.Matches(n)); +} + +TEST(ExpectThat, TakesLiterals) { + EXPECT_THAT(1, 1); + EXPECT_THAT(1.0, 1.0); + EXPECT_THAT(std::string(), ""); +} + +TEST(ExpectThat, TakesFunctions) { + struct Helper { + static void Func() {} + }; + void (*func)() = Helper::Func; + EXPECT_THAT(func, Helper::Func); + EXPECT_THAT(func, &Helper::Func); +} + +// 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)); +} + +TEST(ATest, WorksForDerivedClass) { + Base base; + Derived derived; + EXPECT_THAT(&base, A<Base*>()); + // This shouldn't compile: EXPECT_THAT(&base, A<Derived*>()); + EXPECT_THAT(&derived, A<Base*>()); + EXPECT_THAT(&derived, A<Derived*>()); +} + +// 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 */) const { return true; } + // -Wunused-private-field: dummy accessor for `c_`. + char dummy_c() { return c_; } + 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 if and only if 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 reference". +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 >= 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 > 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 <= 5", Describe(m)); +} + +// Tests that Lt(v) matches anything < v. +TEST(LtTest, ImplementsLessThan) { + Matcher<const std::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 < 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("isn't equal to 5", Describe(m)); +} + +class MoveOnly { + public: + explicit MoveOnly(int i) : i_(i) {} + MoveOnly(const MoveOnly&) = delete; + MoveOnly(MoveOnly&&) = default; + MoveOnly& operator=(const MoveOnly&) = delete; + MoveOnly& operator=(MoveOnly&&) = default; + + bool operator==(const MoveOnly& other) const { return i_ == other.i_; } + bool operator!=(const MoveOnly& other) const { return i_ != other.i_; } + bool operator<(const MoveOnly& other) const { return i_ < other.i_; } + bool operator<=(const MoveOnly& other) const { return i_ <= other.i_; } + bool operator>(const MoveOnly& other) const { return i_ > other.i_; } + bool operator>=(const MoveOnly& other) const { return i_ >= other.i_; } + + private: + int i_; +}; + +struct MoveHelper { + MOCK_METHOD1(Call, void(MoveOnly)); +}; + +// Disable this test in VS 2015 (version 14), where it fails when SEH is enabled +#if defined(_MSC_VER) && (_MSC_VER < 1910) +TEST(ComparisonBaseTest, DISABLED_WorksWithMoveOnly) { +#else +TEST(ComparisonBaseTest, WorksWithMoveOnly) { +#endif + MoveOnly m{0}; + MoveHelper helper; + + EXPECT_CALL(helper, Call(Eq(ByRef(m)))); + helper.Call(MoveOnly(0)); + EXPECT_CALL(helper, Call(Ne(ByRef(m)))); + helper.Call(MoveOnly(1)); + EXPECT_CALL(helper, Call(Le(ByRef(m)))); + helper.Call(MoveOnly(0)); + EXPECT_CALL(helper, Call(Lt(ByRef(m)))); + helper.Call(MoveOnly(-1)); + EXPECT_CALL(helper, Call(Ge(ByRef(m)))); + helper.Call(MoveOnly(0)); + EXPECT_CALL(helper, Call(Gt(ByRef(m)))); + helper.Call(MoveOnly(1)); +} + +// Tests that IsNull() matches any NULL pointer of any type. +TEST(IsNullTest, MatchesNullPointer) { + Matcher<int*> m1 = IsNull(); + int* p1 = nullptr; + int n = 0; + EXPECT_TRUE(m1.Matches(p1)); + EXPECT_FALSE(m1.Matches(&n)); + + Matcher<const char*> m2 = IsNull(); + const char* p2 = nullptr; + EXPECT_TRUE(m2.Matches(p2)); + EXPECT_FALSE(m2.Matches("hi")); + + Matcher<void*> m3 = IsNull(); + void* p3 = nullptr; + EXPECT_TRUE(m3.Matches(p3)); + EXPECT_FALSE(m3.Matches(reinterpret_cast<void*>(0xbeef))); +} + +TEST(IsNullTest, StdFunction) { + const Matcher<std::function<void()>> m = IsNull(); + + EXPECT_TRUE(m.Matches(std::function<void()>())); + EXPECT_FALSE(m.Matches([]{})); +} + +// Tests that IsNull() describes itself properly. +TEST(IsNullTest, CanDescribeSelf) { + Matcher<int*> m = IsNull(); + EXPECT_EQ("is NULL", Describe(m)); + EXPECT_EQ("isn't NULL", DescribeNegation(m)); +} + +// Tests that NotNull() matches any non-NULL pointer of any type. +TEST(NotNullTest, MatchesNonNullPointer) { + Matcher<int*> m1 = NotNull(); + int* p1 = nullptr; + int n = 0; + EXPECT_FALSE(m1.Matches(p1)); + EXPECT_TRUE(m1.Matches(&n)); + + Matcher<const char*> m2 = NotNull(); + const char* p2 = nullptr; + EXPECT_FALSE(m2.Matches(p2)); + EXPECT_TRUE(m2.Matches("hi")); +} + +TEST(NotNullTest, LinkedPtr) { + const Matcher<std::shared_ptr<int>> m = NotNull(); + const std::shared_ptr<int> null_p; + const std::shared_ptr<int> non_null_p(new int); + + EXPECT_FALSE(m.Matches(null_p)); + EXPECT_TRUE(m.Matches(non_null_p)); +} + +TEST(NotNullTest, ReferenceToConstLinkedPtr) { + const Matcher<const std::shared_ptr<double>&> m = NotNull(); + const std::shared_ptr<double> null_p; + const std::shared_ptr<double> non_null_p(new double); + + EXPECT_FALSE(m.Matches(null_p)); + EXPECT_TRUE(m.Matches(non_null_p)); +} + +TEST(NotNullTest, StdFunction) { + const Matcher<std::function<void()>> m = NotNull(); + + EXPECT_TRUE(m.Matches([]{})); + EXPECT_FALSE(m.Matches(std::function<void()>())); +} + +// Tests that NotNull() describes itself properly. +TEST(NotNullTest, CanDescribeSelf) { + Matcher<int*> m = NotNull(); + EXPECT_EQ("isn't 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(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. + +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)); +} + +TEST(RefTest, ExplainsResult) { + int n = 0; + EXPECT_THAT(Explain(Matcher<const int&>(Ref(n)), n), + StartsWith("which is located @")); + + int m = 0; + EXPECT_THAT(Explain(Matcher<const int&>(Ref(n)), m), + StartsWith("which is located @")); +} + +// Tests string comparison matchers. + +template <typename T = std::string> +std::string FromStringLike(internal::StringLike<T> str) { + return std::string(str); +} + +TEST(StringLike, TestConversions) { + EXPECT_EQ("foo", FromStringLike("foo")); + EXPECT_EQ("foo", FromStringLike(std::string("foo"))); +#if GTEST_INTERNAL_HAS_STRING_VIEW + EXPECT_EQ("foo", FromStringLike(internal::StringView("foo"))); +#endif // GTEST_INTERNAL_HAS_STRING_VIEW + + // Non deducible types. + EXPECT_EQ("", FromStringLike({})); + EXPECT_EQ("foo", FromStringLike({'f', 'o', 'o'})); + const char buf[] = "foo"; + EXPECT_EQ("foo", FromStringLike({buf, buf + 3})); +} + +TEST(StrEqTest, MatchesEqualString) { + Matcher<const char*> m = StrEq(std::string("Hello")); + EXPECT_TRUE(m.Matches("Hello")); + EXPECT_FALSE(m.Matches("hello")); + EXPECT_FALSE(m.Matches(nullptr)); + + Matcher<const std::string&> m2 = StrEq("Hello"); + EXPECT_TRUE(m2.Matches("Hello")); + EXPECT_FALSE(m2.Matches("Hi")); + +#if GTEST_INTERNAL_HAS_STRING_VIEW + Matcher<const internal::StringView&> m3 = + StrEq(internal::StringView("Hello")); + EXPECT_TRUE(m3.Matches(internal::StringView("Hello"))); + EXPECT_FALSE(m3.Matches(internal::StringView("hello"))); + EXPECT_FALSE(m3.Matches(internal::StringView())); + + Matcher<const internal::StringView&> m_empty = StrEq(""); + EXPECT_TRUE(m_empty.Matches(internal::StringView(""))); + EXPECT_TRUE(m_empty.Matches(internal::StringView())); + EXPECT_FALSE(m_empty.Matches(internal::StringView("hello"))); +#endif // GTEST_INTERNAL_HAS_STRING_VIEW +} + +TEST(StrEqTest, CanDescribeSelf) { + Matcher<std::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)); + + std::string str("01204500800"); + str[3] = '\0'; + Matcher<std::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<std::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(nullptr)); + EXPECT_FALSE(m.Matches("Hello")); + + Matcher<std::string> m2 = StrNe(std::string("Hello")); + EXPECT_TRUE(m2.Matches("hello")); + EXPECT_FALSE(m2.Matches("Hello")); + +#if GTEST_INTERNAL_HAS_STRING_VIEW + Matcher<const internal::StringView> m3 = StrNe(internal::StringView("Hello")); + EXPECT_TRUE(m3.Matches(internal::StringView(""))); + EXPECT_TRUE(m3.Matches(internal::StringView())); + EXPECT_FALSE(m3.Matches(internal::StringView("Hello"))); +#endif // GTEST_INTERNAL_HAS_STRING_VIEW +} + +TEST(StrNeTest, CanDescribeSelf) { + Matcher<const char*> m = StrNe("Hi"); + EXPECT_EQ("isn't equal to \"Hi\"", Describe(m)); +} + +TEST(StrCaseEqTest, MatchesEqualStringIgnoringCase) { + Matcher<const char*> m = StrCaseEq(std::string("Hello")); + EXPECT_TRUE(m.Matches("Hello")); + EXPECT_TRUE(m.Matches("hello")); + EXPECT_FALSE(m.Matches("Hi")); + EXPECT_FALSE(m.Matches(nullptr)); + + Matcher<const std::string&> m2 = StrCaseEq("Hello"); + EXPECT_TRUE(m2.Matches("hello")); + EXPECT_FALSE(m2.Matches("Hi")); + +#if GTEST_INTERNAL_HAS_STRING_VIEW + Matcher<const internal::StringView&> m3 = + StrCaseEq(internal::StringView("Hello")); + EXPECT_TRUE(m3.Matches(internal::StringView("Hello"))); + EXPECT_TRUE(m3.Matches(internal::StringView("hello"))); + EXPECT_FALSE(m3.Matches(internal::StringView("Hi"))); + EXPECT_FALSE(m3.Matches(internal::StringView())); +#endif // GTEST_INTERNAL_HAS_STRING_VIEW +} + +TEST(StrCaseEqTest, MatchesEqualStringWith0IgnoringCase) { + std::string str1("oabocdooeoo"); + std::string str2("OABOCDOOEOO"); + Matcher<const std::string&> m0 = StrCaseEq(str1); + EXPECT_FALSE(m0.Matches(str2 + std::string(1, '\0'))); + + str1[3] = str2[3] = '\0'; + Matcher<const std::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 std::string&> m2 = StrCaseEq(str1); + str1[9] = str2[9] = '\0'; + EXPECT_FALSE(m2.Matches(str2)); + + Matcher<const std::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(std::string(str2, 0, 9))); +} + +TEST(StrCaseEqTest, CanDescribeSelf) { + Matcher<std::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(nullptr)); + EXPECT_FALSE(m.Matches("Hello")); + EXPECT_FALSE(m.Matches("hello")); + + Matcher<std::string> m2 = StrCaseNe(std::string("Hello")); + EXPECT_TRUE(m2.Matches("")); + EXPECT_FALSE(m2.Matches("Hello")); + +#if GTEST_INTERNAL_HAS_STRING_VIEW + Matcher<const internal::StringView> m3 = + StrCaseNe(internal::StringView("Hello")); + EXPECT_TRUE(m3.Matches(internal::StringView("Hi"))); + EXPECT_TRUE(m3.Matches(internal::StringView())); + EXPECT_FALSE(m3.Matches(internal::StringView("Hello"))); + EXPECT_FALSE(m3.Matches(internal::StringView("hello"))); +#endif // GTEST_INTERNAL_HAS_STRING_VIEW +} + +TEST(StrCaseNeTest, CanDescribeSelf) { + Matcher<const char*> m = StrCaseNe("Hi"); + EXPECT_EQ("isn't equal to (ignoring case) \"Hi\"", Describe(m)); +} + +// Tests that HasSubstr() works for matching string-typed values. +TEST(HasSubstrTest, WorksForStringClasses) { + const Matcher<std::string> m1 = HasSubstr("foo"); + EXPECT_TRUE(m1.Matches(std::string("I love food."))); + EXPECT_FALSE(m1.Matches(std::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"))); + + const Matcher<std::string> m_empty = HasSubstr(""); + EXPECT_TRUE(m_empty.Matches(std::string())); + EXPECT_TRUE(m_empty.Matches(std::string("not empty"))); +} + +// 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(nullptr)); + + const Matcher<const char*> m2 = HasSubstr("foo"); + EXPECT_TRUE(m2.Matches("I love food.")); + EXPECT_FALSE(m2.Matches("tofo")); + EXPECT_FALSE(m2.Matches(nullptr)); + + const Matcher<const char*> m_empty = HasSubstr(""); + EXPECT_TRUE(m_empty.Matches("not empty")); + EXPECT_TRUE(m_empty.Matches("")); + EXPECT_FALSE(m_empty.Matches(nullptr)); +} + +#if GTEST_INTERNAL_HAS_STRING_VIEW +// Tests that HasSubstr() works for matching StringView-typed values. +TEST(HasSubstrTest, WorksForStringViewClasses) { + const Matcher<internal::StringView> m1 = + HasSubstr(internal::StringView("foo")); + EXPECT_TRUE(m1.Matches(internal::StringView("I love food."))); + EXPECT_FALSE(m1.Matches(internal::StringView("tofo"))); + EXPECT_FALSE(m1.Matches(internal::StringView())); + + const Matcher<const internal::StringView&> m2 = HasSubstr("foo"); + EXPECT_TRUE(m2.Matches(internal::StringView("I love food."))); + EXPECT_FALSE(m2.Matches(internal::StringView("tofo"))); + EXPECT_FALSE(m2.Matches(internal::StringView())); + + const Matcher<const internal::StringView&> m3 = HasSubstr(""); + EXPECT_TRUE(m3.Matches(internal::StringView("foo"))); + EXPECT_TRUE(m3.Matches(internal::StringView(""))); + EXPECT_TRUE(m3.Matches(internal::StringView())); +} +#endif // GTEST_INTERNAL_HAS_STRING_VIEW + +// Tests that HasSubstr(s) describes itself properly. +TEST(HasSubstrTest, CanDescribeSelf) { + Matcher<std::string> m = HasSubstr("foo\n\""); + EXPECT_EQ("has substring \"foo\\n\\\"\"", Describe(m)); +} + +TEST(KeyTest, CanDescribeSelf) { + Matcher<const pair<std::string, int>&> m = Key("foo"); + EXPECT_EQ("has a key that is equal to \"foo\"", Describe(m)); + EXPECT_EQ("doesn't have a key that is equal to \"foo\"", DescribeNegation(m)); +} + +TEST(KeyTest, ExplainsResult) { + Matcher<pair<int, bool> > m = Key(GreaterThan(10)); + EXPECT_EQ("whose first field is a value which is 5 less than 10", + Explain(m, make_pair(5, true))); + EXPECT_EQ("whose first field is a value which is 5 more than 10", + Explain(m, make_pair(15, true))); +} + +TEST(KeyTest, MatchesCorrectly) { + pair<int, std::string> p(25, "foo"); + EXPECT_THAT(p, Key(25)); + EXPECT_THAT(p, Not(Key(42))); + EXPECT_THAT(p, Key(Ge(20))); + EXPECT_THAT(p, Not(Key(Lt(25)))); +} + +TEST(KeyTest, WorksWithMoveOnly) { + pair<std::unique_ptr<int>, std::unique_ptr<int>> p; + EXPECT_THAT(p, Key(Eq(nullptr))); +} + +template <size_t I> +struct Tag {}; + +struct PairWithGet { + int member_1; + std::string member_2; + using first_type = int; + using second_type = std::string; + + const int& GetImpl(Tag<0>) const { return member_1; } + const std::string& GetImpl(Tag<1>) const { return member_2; } +}; +template <size_t I> +auto get(const PairWithGet& value) -> decltype(value.GetImpl(Tag<I>())) { + return value.GetImpl(Tag<I>()); +} +TEST(PairTest, MatchesPairWithGetCorrectly) { + PairWithGet p{25, "foo"}; + EXPECT_THAT(p, Key(25)); + EXPECT_THAT(p, Not(Key(42))); + EXPECT_THAT(p, Key(Ge(20))); + EXPECT_THAT(p, Not(Key(Lt(25)))); + + std::vector<PairWithGet> v = {{11, "Foo"}, {29, "gMockIsBestMock"}}; + EXPECT_THAT(v, Contains(Key(29))); +} + +TEST(KeyTest, SafelyCastsInnerMatcher) { + Matcher<int> is_positive = Gt(0); + Matcher<int> is_negative = Lt(0); + pair<char, bool> p('a', true); + EXPECT_THAT(p, Key(is_positive)); + EXPECT_THAT(p, Not(Key(is_negative))); +} + +TEST(KeyTest, InsideContainsUsingMap) { + map<int, char> container; + container.insert(make_pair(1, 'a')); + container.insert(make_pair(2, 'b')); + container.insert(make_pair(4, 'c')); + EXPECT_THAT(container, Contains(Key(1))); + EXPECT_THAT(container, Not(Contains(Key(3)))); +} + +TEST(KeyTest, InsideContainsUsingMultimap) { + multimap<int, char> container; + container.insert(make_pair(1, 'a')); + container.insert(make_pair(2, 'b')); + container.insert(make_pair(4, 'c')); + + EXPECT_THAT(container, Not(Contains(Key(25)))); + container.insert(make_pair(25, 'd')); + EXPECT_THAT(container, Contains(Key(25))); + container.insert(make_pair(25, 'e')); + EXPECT_THAT(container, Contains(Key(25))); + + EXPECT_THAT(container, Contains(Key(1))); + EXPECT_THAT(container, Not(Contains(Key(3)))); +} + +TEST(PairTest, Typing) { + // Test verifies the following type conversions can be compiled. + Matcher<const pair<const char*, int>&> m1 = Pair("foo", 42); + Matcher<const pair<const char*, int> > m2 = Pair("foo", 42); + Matcher<pair<const char*, int> > m3 = Pair("foo", 42); + + Matcher<pair<int, const std::string> > m4 = Pair(25, "42"); + Matcher<pair<const std::string, int> > m5 = Pair("25", 42); +} + +TEST(PairTest, CanDescribeSelf) { + Matcher<const pair<std::string, int>&> m1 = Pair("foo", 42); + EXPECT_EQ("has a first field that is equal to \"foo\"" + ", and has a second field that is equal to 42", + Describe(m1)); + EXPECT_EQ("has a first field that isn't equal to \"foo\"" + ", or has a second field that isn't equal to 42", + DescribeNegation(m1)); + // Double and triple negation (1 or 2 times not and description of negation). + Matcher<const pair<int, int>&> m2 = Not(Pair(Not(13), 42)); + EXPECT_EQ("has a first field that isn't equal to 13" + ", and has a second field that is equal to 42", + DescribeNegation(m2)); +} + +TEST(PairTest, CanExplainMatchResultTo) { + // If neither field matches, Pair() should explain about the first + // field. + const Matcher<pair<int, int> > m = Pair(GreaterThan(0), GreaterThan(0)); + EXPECT_EQ("whose first field does not match, which is 1 less than 0", + Explain(m, make_pair(-1, -2))); + + // If the first field matches but the second doesn't, Pair() should + // explain about the second field. + EXPECT_EQ("whose second field does not match, which is 2 less than 0", + Explain(m, make_pair(1, -2))); + + // If the first field doesn't match but the second does, Pair() + // should explain about the first field. + EXPECT_EQ("whose first field does not match, which is 1 less than 0", + Explain(m, make_pair(-1, 2))); + + // If both fields match, Pair() should explain about them both. + EXPECT_EQ("whose both fields match, where the first field is a value " + "which is 1 more than 0, and the second field is a value " + "which is 2 more than 0", + Explain(m, make_pair(1, 2))); + + // If only the first match has an explanation, only this explanation should + // be printed. + const Matcher<pair<int, int> > explain_first = Pair(GreaterThan(0), 0); + EXPECT_EQ("whose both fields match, where the first field is a value " + "which is 1 more than 0", + Explain(explain_first, make_pair(1, 0))); + + // If only the second match has an explanation, only this explanation should + // be printed. + const Matcher<pair<int, int> > explain_second = Pair(0, GreaterThan(0)); + EXPECT_EQ("whose both fields match, where the second field is a value " + "which is 1 more than 0", + Explain(explain_second, make_pair(0, 1))); +} + +TEST(PairTest, MatchesCorrectly) { + pair<int, std::string> p(25, "foo"); + + // Both fields match. + EXPECT_THAT(p, Pair(25, "foo")); + EXPECT_THAT(p, Pair(Ge(20), HasSubstr("o"))); + + // 'first' doesnt' match, but 'second' matches. + EXPECT_THAT(p, Not(Pair(42, "foo"))); + EXPECT_THAT(p, Not(Pair(Lt(25), "foo"))); + + // 'first' matches, but 'second' doesn't match. + EXPECT_THAT(p, Not(Pair(25, "bar"))); + EXPECT_THAT(p, Not(Pair(25, Not("foo")))); + + // Neither field matches. + EXPECT_THAT(p, Not(Pair(13, "bar"))); + EXPECT_THAT(p, Not(Pair(Lt(13), HasSubstr("a")))); +} + +TEST(PairTest, WorksWithMoveOnly) { + pair<std::unique_ptr<int>, std::unique_ptr<int>> p; + p.second.reset(new int(7)); + EXPECT_THAT(p, Pair(Eq(nullptr), Ne(nullptr))); +} + +TEST(PairTest, SafelyCastsInnerMatchers) { + Matcher<int> is_positive = Gt(0); + Matcher<int> is_negative = Lt(0); + pair<char, bool> p('a', true); + EXPECT_THAT(p, Pair(is_positive, _)); + EXPECT_THAT(p, Not(Pair(is_negative, _))); + EXPECT_THAT(p, Pair(_, is_positive)); + EXPECT_THAT(p, Not(Pair(_, is_negative))); +} + +TEST(PairTest, InsideContainsUsingMap) { + map<int, char> container; + container.insert(make_pair(1, 'a')); + container.insert(make_pair(2, 'b')); + container.insert(make_pair(4, 'c')); + EXPECT_THAT(container, Contains(Pair(1, 'a'))); + EXPECT_THAT(container, Contains(Pair(1, _))); + EXPECT_THAT(container, Contains(Pair(_, 'a'))); + EXPECT_THAT(container, Not(Contains(Pair(3, _)))); +} + +TEST(FieldsAreTest, MatchesCorrectly) { + std::tuple<int, std::string, double> p(25, "foo", .5); + + // All fields match. + EXPECT_THAT(p, FieldsAre(25, "foo", .5)); + EXPECT_THAT(p, FieldsAre(Ge(20), HasSubstr("o"), DoubleEq(.5))); + + // Some don't match. + EXPECT_THAT(p, Not(FieldsAre(26, "foo", .5))); + EXPECT_THAT(p, Not(FieldsAre(25, "fo", .5))); + EXPECT_THAT(p, Not(FieldsAre(25, "foo", .6))); +} + +TEST(FieldsAreTest, CanDescribeSelf) { + Matcher<const pair<std::string, int>&> m1 = FieldsAre("foo", 42); + EXPECT_EQ( + "has field #0 that is equal to \"foo\"" + ", and has field #1 that is equal to 42", + Describe(m1)); + EXPECT_EQ( + "has field #0 that isn't equal to \"foo\"" + ", or has field #1 that isn't equal to 42", + DescribeNegation(m1)); +} + +TEST(FieldsAreTest, CanExplainMatchResultTo) { + // The first one that fails is the one that gives the error. + Matcher<std::tuple<int, int, int>> m = + FieldsAre(GreaterThan(0), GreaterThan(0), GreaterThan(0)); + + EXPECT_EQ("whose field #0 does not match, which is 1 less than 0", + Explain(m, std::make_tuple(-1, -2, -3))); + EXPECT_EQ("whose field #1 does not match, which is 2 less than 0", + Explain(m, std::make_tuple(1, -2, -3))); + EXPECT_EQ("whose field #2 does not match, which is 3 less than 0", + Explain(m, std::make_tuple(1, 2, -3))); + + // If they all match, we get a long explanation of success. + EXPECT_EQ( + "whose all elements match, " + "where field #0 is a value which is 1 more than 0" + ", and field #1 is a value which is 2 more than 0" + ", and field #2 is a value which is 3 more than 0", + Explain(m, std::make_tuple(1, 2, 3))); + + // Only print those that have an explanation. + m = FieldsAre(GreaterThan(0), 0, GreaterThan(0)); + EXPECT_EQ( + "whose all elements match, " + "where field #0 is a value which is 1 more than 0" + ", and field #2 is a value which is 3 more than 0", + Explain(m, std::make_tuple(1, 0, 3))); + + // If only one has an explanation, then print that one. + m = FieldsAre(0, GreaterThan(0), 0); + EXPECT_EQ( + "whose all elements match, " + "where field #1 is a value which is 1 more than 0", + Explain(m, std::make_tuple(0, 1, 0))); +} + +#if defined(__cpp_structured_bindings) && __cpp_structured_bindings >= 201606 +TEST(FieldsAreTest, StructuredBindings) { + // testing::FieldsAre can also match aggregates and such with C++17 and up. + struct MyType { + int i; + std::string str; + }; + EXPECT_THAT((MyType{17, "foo"}), FieldsAre(Eq(17), HasSubstr("oo"))); + + // Test all the supported arities. + struct MyVarType1 { + int a; + }; + EXPECT_THAT(MyVarType1{}, FieldsAre(0)); + struct MyVarType2 { + int a, b; + }; + EXPECT_THAT(MyVarType2{}, FieldsAre(0, 0)); + struct MyVarType3 { + int a, b, c; + }; + EXPECT_THAT(MyVarType3{}, FieldsAre(0, 0, 0)); + struct MyVarType4 { + int a, b, c, d; + }; + EXPECT_THAT(MyVarType4{}, FieldsAre(0, 0, 0, 0)); + struct MyVarType5 { + int a, b, c, d, e; + }; + EXPECT_THAT(MyVarType5{}, FieldsAre(0, 0, 0, 0, 0)); + struct MyVarType6 { + int a, b, c, d, e, f; + }; + EXPECT_THAT(MyVarType6{}, FieldsAre(0, 0, 0, 0, 0, 0)); + struct MyVarType7 { + int a, b, c, d, e, f, g; + }; + EXPECT_THAT(MyVarType7{}, FieldsAre(0, 0, 0, 0, 0, 0, 0)); + struct MyVarType8 { + int a, b, c, d, e, f, g, h; + }; + EXPECT_THAT(MyVarType8{}, FieldsAre(0, 0, 0, 0, 0, 0, 0, 0)); + struct MyVarType9 { + int a, b, c, d, e, f, g, h, i; + }; + EXPECT_THAT(MyVarType9{}, FieldsAre(0, 0, 0, 0, 0, 0, 0, 0, 0)); + struct MyVarType10 { + int a, b, c, d, e, f, g, h, i, j; + }; + EXPECT_THAT(MyVarType10{}, FieldsAre(0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + struct MyVarType11 { + int a, b, c, d, e, f, g, h, i, j, k; + }; + EXPECT_THAT(MyVarType11{}, FieldsAre(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + struct MyVarType12 { + int a, b, c, d, e, f, g, h, i, j, k, l; + }; + EXPECT_THAT(MyVarType12{}, FieldsAre(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + struct MyVarType13 { + int a, b, c, d, e, f, g, h, i, j, k, l, m; + }; + EXPECT_THAT(MyVarType13{}, FieldsAre(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + struct MyVarType14 { + int a, b, c, d, e, f, g, h, i, j, k, l, m, n; + }; + EXPECT_THAT(MyVarType14{}, + FieldsAre(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + struct MyVarType15 { + int a, b, c, d, e, f, g, h, i, j, k, l, m, n, o; + }; + EXPECT_THAT(MyVarType15{}, + FieldsAre(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); + struct MyVarType16 { + int a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p; + }; + EXPECT_THAT(MyVarType16{}, + FieldsAre(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)); +} +#endif + +TEST(ContainsTest, WorksWithMoveOnly) { + ContainerHelper helper; + EXPECT_CALL(helper, Call(Contains(Pointee(2)))); + helper.Call(MakeUniquePtrs({1, 2})); +} + +TEST(PairTest, UseGetInsteadOfMembers) { + PairWithGet pair{7, "ABC"}; + EXPECT_THAT(pair, Pair(7, "ABC")); + EXPECT_THAT(pair, Pair(Ge(7), HasSubstr("AB"))); + EXPECT_THAT(pair, Not(Pair(Lt(7), "ABC"))); + + std::vector<PairWithGet> v = {{11, "Foo"}, {29, "gMockIsBestMock"}}; + EXPECT_THAT(v, + ElementsAre(Pair(11, std::string("Foo")), Pair(Ge(10), Not("")))); +} + +// Tests StartsWith(s). + +TEST(StartsWithTest, MatchesStringWithGivenPrefix) { + const Matcher<const char*> m1 = StartsWith(std::string("")); + EXPECT_TRUE(m1.Matches("Hi")); + EXPECT_TRUE(m1.Matches("")); + EXPECT_FALSE(m1.Matches(nullptr)); + + const Matcher<const std::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")); + +#if GTEST_INTERNAL_HAS_STRING_VIEW + const Matcher<internal::StringView> m_empty = + StartsWith(internal::StringView("")); + EXPECT_TRUE(m_empty.Matches(internal::StringView())); + EXPECT_TRUE(m_empty.Matches(internal::StringView(""))); + EXPECT_TRUE(m_empty.Matches(internal::StringView("not empty"))); +#endif // GTEST_INTERNAL_HAS_STRING_VIEW +} + +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(nullptr)); + + const Matcher<const std::string&> m2 = EndsWith(std::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 ")); + +#if GTEST_INTERNAL_HAS_STRING_VIEW + const Matcher<const internal::StringView&> m4 = + EndsWith(internal::StringView("")); + EXPECT_TRUE(m4.Matches("Hi")); + EXPECT_TRUE(m4.Matches("")); + EXPECT_TRUE(m4.Matches(internal::StringView())); + EXPECT_TRUE(m4.Matches(internal::StringView(""))); +#endif // GTEST_INTERNAL_HAS_STRING_VIEW +} + +TEST(EndsWithTest, CanDescribeSelf) { + Matcher<const std::string> m = EndsWith("Hi"); + EXPECT_EQ("ends with \"Hi\"", Describe(m)); +} + +// 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(nullptr)); + + const Matcher<const std::string&> m2 = MatchesRegex(new RE("a.*z")); + EXPECT_TRUE(m2.Matches("azbz")); + EXPECT_FALSE(m2.Matches("az1")); + EXPECT_FALSE(m2.Matches("1az")); + +#if GTEST_INTERNAL_HAS_STRING_VIEW + const Matcher<const internal::StringView&> m3 = MatchesRegex("a.*z"); + EXPECT_TRUE(m3.Matches(internal::StringView("az"))); + EXPECT_TRUE(m3.Matches(internal::StringView("abcz"))); + EXPECT_FALSE(m3.Matches(internal::StringView("1az"))); + EXPECT_FALSE(m3.Matches(internal::StringView())); + const Matcher<const internal::StringView&> m4 = + MatchesRegex(internal::StringView("")); + EXPECT_TRUE(m4.Matches(internal::StringView(""))); + EXPECT_TRUE(m4.Matches(internal::StringView())); +#endif // GTEST_INTERNAL_HAS_STRING_VIEW +} + +TEST(MatchesRegexTest, CanDescribeSelf) { + Matcher<const std::string> m1 = MatchesRegex(std::string("Hi.*")); + EXPECT_EQ("matches regular expression \"Hi.*\"", Describe(m1)); + + Matcher<const char*> m2 = MatchesRegex(new RE("a.*")); + EXPECT_EQ("matches regular expression \"a.*\"", Describe(m2)); + +#if GTEST_INTERNAL_HAS_STRING_VIEW + Matcher<const internal::StringView> m3 = MatchesRegex(new RE("0.*")); + EXPECT_EQ("matches regular expression \"0.*\"", Describe(m3)); +#endif // GTEST_INTERNAL_HAS_STRING_VIEW +} + +// Tests ContainsRegex(). + +TEST(ContainsRegexTest, MatchesStringContainingGivenRegex) { + const Matcher<const char*> m1 = ContainsRegex(std::string("a.*z")); + EXPECT_TRUE(m1.Matches("az")); + EXPECT_TRUE(m1.Matches("0abcz1")); + EXPECT_FALSE(m1.Matches(nullptr)); + + const Matcher<const std::string&> m2 = ContainsRegex(new RE("a.*z")); + EXPECT_TRUE(m2.Matches("azbz")); + EXPECT_TRUE(m2.Matches("az1")); + EXPECT_FALSE(m2.Matches("1a")); + +#if GTEST_INTERNAL_HAS_STRING_VIEW + const Matcher<const internal::StringView&> m3 = + ContainsRegex(new RE("a.*z")); + EXPECT_TRUE(m3.Matches(internal::StringView("azbz"))); + EXPECT_TRUE(m3.Matches(internal::StringView("az1"))); + EXPECT_FALSE(m3.Matches(internal::StringView("1a"))); + EXPECT_FALSE(m3.Matches(internal::StringView())); + const Matcher<const internal::StringView&> m4 = + ContainsRegex(internal::StringView("")); + EXPECT_TRUE(m4.Matches(internal::StringView(""))); + EXPECT_TRUE(m4.Matches(internal::StringView())); +#endif // GTEST_INTERNAL_HAS_STRING_VIEW +} + +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.*")); + EXPECT_EQ("contains regular expression \"a.*\"", Describe(m2)); + +#if GTEST_INTERNAL_HAS_STRING_VIEW + Matcher<const internal::StringView> m3 = ContainsRegex(new RE("0.*")); + EXPECT_EQ("contains regular expression \"0.*\"", Describe(m3)); +#endif // GTEST_INTERNAL_HAS_STRING_VIEW +} + +// 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(nullptr)); + + 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(nullptr)); + 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("isn't 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(nullptr)); + + 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(nullptr)); + 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("isn't 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(nullptr)); + + 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(nullptr)); +} + +// 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(nullptr)); + + 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(nullptr)); + + 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 + +typedef ::std::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("are an equal pair", 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("are a pair where the first >= the second", 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("are a pair where the first > the second", 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("are a pair where the first <= the second", 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("are a pair where the first < the second", 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("are an unequal pair", Describe(m)); +} + +TEST(PairMatchBaseTest, WorksWithMoveOnly) { + using Pointers = std::tuple<std::unique_ptr<int>, std::unique_ptr<int>>; + Matcher<Pointers> matcher = Eq(); + Pointers pointers; + // Tested values don't matter; the point is that matcher does not copy the + // matched values. + EXPECT_TRUE(matcher.Matches(pointers)); +} + +// Tests that IsNan() matches a NaN, with float. +TEST(IsNan, FloatMatchesNan) { + float quiet_nan = std::numeric_limits<float>::quiet_NaN(); + float other_nan = std::nanf("1"); + float real_value = 1.0f; + + Matcher<float> m = IsNan(); + EXPECT_TRUE(m.Matches(quiet_nan)); + EXPECT_TRUE(m.Matches(other_nan)); + EXPECT_FALSE(m.Matches(real_value)); + + Matcher<float&> m_ref = IsNan(); + EXPECT_TRUE(m_ref.Matches(quiet_nan)); + EXPECT_TRUE(m_ref.Matches(other_nan)); + EXPECT_FALSE(m_ref.Matches(real_value)); + + Matcher<const float&> m_cref = IsNan(); + EXPECT_TRUE(m_cref.Matches(quiet_nan)); + EXPECT_TRUE(m_cref.Matches(other_nan)); + EXPECT_FALSE(m_cref.Matches(real_value)); +} + +// Tests that IsNan() matches a NaN, with double. +TEST(IsNan, DoubleMatchesNan) { + double quiet_nan = std::numeric_limits<double>::quiet_NaN(); + double other_nan = std::nan("1"); + double real_value = 1.0; + + Matcher<double> m = IsNan(); + EXPECT_TRUE(m.Matches(quiet_nan)); + EXPECT_TRUE(m.Matches(other_nan)); + EXPECT_FALSE(m.Matches(real_value)); + + Matcher<double&> m_ref = IsNan(); + EXPECT_TRUE(m_ref.Matches(quiet_nan)); + EXPECT_TRUE(m_ref.Matches(other_nan)); + EXPECT_FALSE(m_ref.Matches(real_value)); + + Matcher<const double&> m_cref = IsNan(); + EXPECT_TRUE(m_cref.Matches(quiet_nan)); + EXPECT_TRUE(m_cref.Matches(other_nan)); + EXPECT_FALSE(m_cref.Matches(real_value)); +} + +// Tests that IsNan() matches a NaN, with long double. +TEST(IsNan, LongDoubleMatchesNan) { + long double quiet_nan = std::numeric_limits<long double>::quiet_NaN(); + long double other_nan = std::nan("1"); + long double real_value = 1.0; + + Matcher<long double> m = IsNan(); + EXPECT_TRUE(m.Matches(quiet_nan)); + EXPECT_TRUE(m.Matches(other_nan)); + EXPECT_FALSE(m.Matches(real_value)); + + Matcher<long double&> m_ref = IsNan(); + EXPECT_TRUE(m_ref.Matches(quiet_nan)); + EXPECT_TRUE(m_ref.Matches(other_nan)); + EXPECT_FALSE(m_ref.Matches(real_value)); + + Matcher<const long double&> m_cref = IsNan(); + EXPECT_TRUE(m_cref.Matches(quiet_nan)); + EXPECT_TRUE(m_cref.Matches(other_nan)); + EXPECT_FALSE(m_cref.Matches(real_value)); +} + +// Tests that IsNan() works with Not. +TEST(IsNan, NotMatchesNan) { + Matcher<float> mf = Not(IsNan()); + EXPECT_FALSE(mf.Matches(std::numeric_limits<float>::quiet_NaN())); + EXPECT_FALSE(mf.Matches(std::nanf("1"))); + EXPECT_TRUE(mf.Matches(1.0)); + + Matcher<double> md = Not(IsNan()); + EXPECT_FALSE(md.Matches(std::numeric_limits<double>::quiet_NaN())); + EXPECT_FALSE(md.Matches(std::nan("1"))); + EXPECT_TRUE(md.Matches(1.0)); + + Matcher<long double> mld = Not(IsNan()); + EXPECT_FALSE(mld.Matches(std::numeric_limits<long double>::quiet_NaN())); + EXPECT_FALSE(mld.Matches(std::nanl("1"))); + EXPECT_TRUE(mld.Matches(1.0)); +} + +// Tests that IsNan() can describe itself. +TEST(IsNan, CanDescribeSelf) { + Matcher<float> mf = IsNan(); + EXPECT_EQ("is NaN", Describe(mf)); + + Matcher<double> md = IsNan(); + EXPECT_EQ("is NaN", Describe(md)); + + Matcher<long double> mld = IsNan(); + EXPECT_EQ("is NaN", Describe(mld)); +} + +// Tests that IsNan() can describe itself with Not. +TEST(IsNan, CanDescribeSelfWithNot) { + Matcher<float> mf = Not(IsNan()); + EXPECT_EQ("isn't NaN", Describe(mf)); + + Matcher<double> md = Not(IsNan()); + EXPECT_EQ("isn't NaN", Describe(md)); + + Matcher<long double> mld = Not(IsNan()); + EXPECT_EQ("isn't NaN", Describe(mld)); +} + +// Tests that FloatEq() matches a 2-tuple where +// FloatEq(first field) matches the second field. +TEST(FloatEq2Test, MatchesEqualArguments) { + typedef ::std::tuple<float, float> Tpl; + Matcher<const Tpl&> m = FloatEq(); + EXPECT_TRUE(m.Matches(Tpl(1.0f, 1.0f))); + EXPECT_TRUE(m.Matches(Tpl(0.3f, 0.1f + 0.1f + 0.1f))); + EXPECT_FALSE(m.Matches(Tpl(1.1f, 1.0f))); +} + +// Tests that FloatEq() describes itself properly. +TEST(FloatEq2Test, CanDescribeSelf) { + Matcher<const ::std::tuple<float, float>&> m = FloatEq(); + EXPECT_EQ("are an almost-equal pair", Describe(m)); +} + +// Tests that NanSensitiveFloatEq() matches a 2-tuple where +// NanSensitiveFloatEq(first field) matches the second field. +TEST(NanSensitiveFloatEqTest, MatchesEqualArgumentsWithNaN) { + typedef ::std::tuple<float, float> Tpl; + Matcher<const Tpl&> m = NanSensitiveFloatEq(); + EXPECT_TRUE(m.Matches(Tpl(1.0f, 1.0f))); + EXPECT_TRUE(m.Matches(Tpl(std::numeric_limits<float>::quiet_NaN(), + std::numeric_limits<float>::quiet_NaN()))); + EXPECT_FALSE(m.Matches(Tpl(1.1f, 1.0f))); + EXPECT_FALSE(m.Matches(Tpl(1.0f, std::numeric_limits<float>::quiet_NaN()))); + EXPECT_FALSE(m.Matches(Tpl(std::numeric_limits<float>::quiet_NaN(), 1.0f))); +} + +// Tests that NanSensitiveFloatEq() describes itself properly. +TEST(NanSensitiveFloatEqTest, CanDescribeSelfWithNaNs) { + Matcher<const ::std::tuple<float, float>&> m = NanSensitiveFloatEq(); + EXPECT_EQ("are an almost-equal pair", Describe(m)); +} + +// Tests that DoubleEq() matches a 2-tuple where +// DoubleEq(first field) matches the second field. +TEST(DoubleEq2Test, MatchesEqualArguments) { + typedef ::std::tuple<double, double> Tpl; + Matcher<const Tpl&> m = DoubleEq(); + EXPECT_TRUE(m.Matches(Tpl(1.0, 1.0))); + EXPECT_TRUE(m.Matches(Tpl(0.3, 0.1 + 0.1 + 0.1))); + EXPECT_FALSE(m.Matches(Tpl(1.1, 1.0))); +} + +// Tests that DoubleEq() describes itself properly. +TEST(DoubleEq2Test, CanDescribeSelf) { + Matcher<const ::std::tuple<double, double>&> m = DoubleEq(); + EXPECT_EQ("are an almost-equal pair", Describe(m)); +} + +// Tests that NanSensitiveDoubleEq() matches a 2-tuple where +// NanSensitiveDoubleEq(first field) matches the second field. +TEST(NanSensitiveDoubleEqTest, MatchesEqualArgumentsWithNaN) { + typedef ::std::tuple<double, double> Tpl; + Matcher<const Tpl&> m = NanSensitiveDoubleEq(); + EXPECT_TRUE(m.Matches(Tpl(1.0f, 1.0f))); + EXPECT_TRUE(m.Matches(Tpl(std::numeric_limits<double>::quiet_NaN(), + std::numeric_limits<double>::quiet_NaN()))); + EXPECT_FALSE(m.Matches(Tpl(1.1f, 1.0f))); + EXPECT_FALSE(m.Matches(Tpl(1.0f, std::numeric_limits<double>::quiet_NaN()))); + EXPECT_FALSE(m.Matches(Tpl(std::numeric_limits<double>::quiet_NaN(), 1.0f))); +} + +// Tests that DoubleEq() describes itself properly. +TEST(NanSensitiveDoubleEqTest, CanDescribeSelfWithNaNs) { + Matcher<const ::std::tuple<double, double>&> m = NanSensitiveDoubleEq(); + EXPECT_EQ("are an almost-equal pair", Describe(m)); +} + +// Tests that FloatEq() matches a 2-tuple where +// FloatNear(first field, max_abs_error) matches the second field. +TEST(FloatNear2Test, MatchesEqualArguments) { + typedef ::std::tuple<float, float> Tpl; + Matcher<const Tpl&> m = FloatNear(0.5f); + EXPECT_TRUE(m.Matches(Tpl(1.0f, 1.0f))); + EXPECT_TRUE(m.Matches(Tpl(1.3f, 1.0f))); + EXPECT_FALSE(m.Matches(Tpl(1.8f, 1.0f))); +} + +// Tests that FloatNear() describes itself properly. +TEST(FloatNear2Test, CanDescribeSelf) { + Matcher<const ::std::tuple<float, float>&> m = FloatNear(0.5f); + EXPECT_EQ("are an almost-equal pair", Describe(m)); +} + +// Tests that NanSensitiveFloatNear() matches a 2-tuple where +// NanSensitiveFloatNear(first field) matches the second field. +TEST(NanSensitiveFloatNearTest, MatchesNearbyArgumentsWithNaN) { + typedef ::std::tuple<float, float> Tpl; + Matcher<const Tpl&> m = NanSensitiveFloatNear(0.5f); + EXPECT_TRUE(m.Matches(Tpl(1.0f, 1.0f))); + EXPECT_TRUE(m.Matches(Tpl(1.1f, 1.0f))); + EXPECT_TRUE(m.Matches(Tpl(std::numeric_limits<float>::quiet_NaN(), + std::numeric_limits<float>::quiet_NaN()))); + EXPECT_FALSE(m.Matches(Tpl(1.6f, 1.0f))); + EXPECT_FALSE(m.Matches(Tpl(1.0f, std::numeric_limits<float>::quiet_NaN()))); + EXPECT_FALSE(m.Matches(Tpl(std::numeric_limits<float>::quiet_NaN(), 1.0f))); +} + +// Tests that NanSensitiveFloatNear() describes itself properly. +TEST(NanSensitiveFloatNearTest, CanDescribeSelfWithNaNs) { + Matcher<const ::std::tuple<float, float>&> m = NanSensitiveFloatNear(0.5f); + EXPECT_EQ("are an almost-equal pair", Describe(m)); +} + +// Tests that FloatEq() matches a 2-tuple where +// DoubleNear(first field, max_abs_error) matches the second field. +TEST(DoubleNear2Test, MatchesEqualArguments) { + typedef ::std::tuple<double, double> Tpl; + Matcher<const Tpl&> m = DoubleNear(0.5); + EXPECT_TRUE(m.Matches(Tpl(1.0, 1.0))); + EXPECT_TRUE(m.Matches(Tpl(1.3, 1.0))); + EXPECT_FALSE(m.Matches(Tpl(1.8, 1.0))); +} + +// Tests that DoubleNear() describes itself properly. +TEST(DoubleNear2Test, CanDescribeSelf) { + Matcher<const ::std::tuple<double, double>&> m = DoubleNear(0.5); + EXPECT_EQ("are an almost-equal pair", Describe(m)); +} + +// Tests that NanSensitiveDoubleNear() matches a 2-tuple where +// NanSensitiveDoubleNear(first field) matches the second field. +TEST(NanSensitiveDoubleNearTest, MatchesNearbyArgumentsWithNaN) { + typedef ::std::tuple<double, double> Tpl; + Matcher<const Tpl&> m = NanSensitiveDoubleNear(0.5f); + EXPECT_TRUE(m.Matches(Tpl(1.0f, 1.0f))); + EXPECT_TRUE(m.Matches(Tpl(1.1f, 1.0f))); + EXPECT_TRUE(m.Matches(Tpl(std::numeric_limits<double>::quiet_NaN(), + std::numeric_limits<double>::quiet_NaN()))); + EXPECT_FALSE(m.Matches(Tpl(1.6f, 1.0f))); + EXPECT_FALSE(m.Matches(Tpl(1.0f, std::numeric_limits<double>::quiet_NaN()))); + EXPECT_FALSE(m.Matches(Tpl(std::numeric_limits<double>::quiet_NaN(), 1.0f))); +} + +// Tests that NanSensitiveDoubleNear() describes itself properly. +TEST(NanSensitiveDoubleNearTest, CanDescribeSelfWithNaNs) { + Matcher<const ::std::tuple<double, double>&> m = NanSensitiveDoubleNear(0.5f); + EXPECT_EQ("are an almost-equal pair", 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("isn't equal to 5", Describe(m)); +} + +// Tests that monomorphic matchers are safely cast by the Not matcher. +TEST(NotTest, NotMatcherSafelyCastsMonomorphicMatchers) { + // greater_than_5 is a monomorphic matcher. + Matcher<int> greater_than_5 = Gt(5); + + Matcher<const int&> m = Not(greater_than_5); + Matcher<int&> m2 = Not(greater_than_5); + Matcher<int&> m3 = Not(m); +} + +// Helper to allow easy testing of AllOf matchers with num parameters. +void AllOfMatches(int num, const Matcher<int>& m) { + SCOPED_TRACE(Describe(m)); + EXPECT_TRUE(m.Matches(0)); + for (int i = 1; i <= num; ++i) { + EXPECT_FALSE(m.Matches(i)); + } + EXPECT_TRUE(m.Matches(num + 1)); +} + +// 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)); + + // The following tests for varying number of sub-matchers. Due to the way + // the sub-matchers are handled it is enough to test every sub-matcher once + // with sub-matchers using the same matcher type. Varying matcher types are + // checked for above. + AllOfMatches(2, AllOf(Ne(1), Ne(2))); + AllOfMatches(3, AllOf(Ne(1), Ne(2), Ne(3))); + AllOfMatches(4, AllOf(Ne(1), Ne(2), Ne(3), Ne(4))); + AllOfMatches(5, AllOf(Ne(1), Ne(2), Ne(3), Ne(4), Ne(5))); + AllOfMatches(6, AllOf(Ne(1), Ne(2), Ne(3), Ne(4), Ne(5), Ne(6))); + AllOfMatches(7, AllOf(Ne(1), Ne(2), Ne(3), Ne(4), Ne(5), Ne(6), Ne(7))); + AllOfMatches(8, AllOf(Ne(1), Ne(2), Ne(3), Ne(4), Ne(5), Ne(6), Ne(7), + Ne(8))); + AllOfMatches(9, AllOf(Ne(1), Ne(2), Ne(3), Ne(4), Ne(5), Ne(6), Ne(7), + Ne(8), Ne(9))); + AllOfMatches(10, AllOf(Ne(1), Ne(2), Ne(3), Ne(4), Ne(5), Ne(6), Ne(7), Ne(8), + Ne(9), Ne(10))); + AllOfMatches( + 50, AllOf(Ne(1), Ne(2), Ne(3), Ne(4), Ne(5), Ne(6), Ne(7), Ne(8), Ne(9), + Ne(10), Ne(11), Ne(12), Ne(13), Ne(14), Ne(15), Ne(16), Ne(17), + Ne(18), Ne(19), Ne(20), Ne(21), Ne(22), Ne(23), Ne(24), Ne(25), + Ne(26), Ne(27), Ne(28), Ne(29), Ne(30), Ne(31), Ne(32), Ne(33), + Ne(34), Ne(35), Ne(36), Ne(37), Ne(38), Ne(39), Ne(40), Ne(41), + Ne(42), Ne(43), Ne(44), Ne(45), Ne(46), Ne(47), Ne(48), Ne(49), + Ne(50))); +} + + +// Tests that AllOf(m1, ..., mn) describes itself properly. +TEST(AllOfTest, CanDescribeSelf) { + Matcher<int> m; + m = AllOf(Le(2), Ge(1)); + EXPECT_EQ("(is <= 2) and (is >= 1)", Describe(m)); + + m = AllOf(Gt(0), Ne(1), Ne(2)); + std::string expected_descr1 = + "(is > 0) and (isn't equal to 1) and (isn't equal to 2)"; + EXPECT_EQ(expected_descr1, Describe(m)); + + m = AllOf(Gt(0), Ne(1), Ne(2), Ne(3)); + std::string expected_descr2 = + "(is > 0) and (isn't equal to 1) and (isn't equal to 2) and (isn't equal " + "to 3)"; + EXPECT_EQ(expected_descr2, Describe(m)); + + m = AllOf(Ge(0), Lt(10), Ne(3), Ne(5), Ne(7)); + std::string expected_descr3 = + "(is >= 0) and (is < 10) and (isn't equal to 3) and (isn't equal to 5) " + "and (isn't equal to 7)"; + EXPECT_EQ(expected_descr3, Describe(m)); +} + +// Tests that AllOf(m1, ..., mn) describes its negation properly. +TEST(AllOfTest, CanDescribeNegation) { + Matcher<int> m; + m = AllOf(Le(2), Ge(1)); + std::string expected_descr4 = "(isn't <= 2) or (isn't >= 1)"; + EXPECT_EQ(expected_descr4, DescribeNegation(m)); + + m = AllOf(Gt(0), Ne(1), Ne(2)); + std::string expected_descr5 = + "(isn't > 0) or (is equal to 1) or (is equal to 2)"; + EXPECT_EQ(expected_descr5, DescribeNegation(m)); + + m = AllOf(Gt(0), Ne(1), Ne(2), Ne(3)); + std::string expected_descr6 = + "(isn't > 0) or (is equal to 1) or (is equal to 2) or (is equal to 3)"; + EXPECT_EQ(expected_descr6, DescribeNegation(m)); + + m = AllOf(Ge(0), Lt(10), Ne(3), Ne(5), Ne(7)); + std::string expected_desr7 = + "(isn't >= 0) or (isn't < 10) or (is equal to 3) or (is equal to 5) or " + "(is equal to 7)"; + EXPECT_EQ(expected_desr7, DescribeNegation(m)); + + m = AllOf(Ne(1), Ne(2), Ne(3), Ne(4), Ne(5), Ne(6), Ne(7), Ne(8), Ne(9), + Ne(10), Ne(11)); + AllOf(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11); + EXPECT_THAT(Describe(m), EndsWith("and (isn't equal to 11)")); + AllOfMatches(11, m); +} + +// Tests that monomorphic matchers are safely cast by the AllOf matcher. +TEST(AllOfTest, AllOfMatcherSafelyCastsMonomorphicMatchers) { + // greater_than_5 and less_than_10 are monomorphic matchers. + Matcher<int> greater_than_5 = Gt(5); + Matcher<int> less_than_10 = Lt(10); + + Matcher<const int&> m = AllOf(greater_than_5, less_than_10); + Matcher<int&> m2 = AllOf(greater_than_5, less_than_10); + Matcher<int&> m3 = AllOf(greater_than_5, m2); + + // Tests that BothOf works when composing itself. + Matcher<const int&> m4 = AllOf(greater_than_5, less_than_10, less_than_10); + Matcher<int&> m5 = AllOf(greater_than_5, less_than_10, less_than_10); +} + +TEST(AllOfTest, ExplainsResult) { + Matcher<int> m; + + // Successful match. Both matchers need to explain. The second + // matcher doesn't give an explanation, so only the first matcher's + // explanation is printed. + m = AllOf(GreaterThan(10), Lt(30)); + EXPECT_EQ("which is 15 more than 10", Explain(m, 25)); + + // Successful match. Both matchers need to explain. + m = AllOf(GreaterThan(10), GreaterThan(20)); + EXPECT_EQ("which is 20 more than 10, and which is 10 more than 20", + Explain(m, 30)); + + // Successful match. All matchers need to explain. The second + // matcher doesn't given an explanation. + m = AllOf(GreaterThan(10), Lt(30), GreaterThan(20)); + EXPECT_EQ("which is 15 more than 10, and which is 5 more than 20", + Explain(m, 25)); + + // Successful match. All matchers need to explain. + m = AllOf(GreaterThan(10), GreaterThan(20), GreaterThan(30)); + EXPECT_EQ("which is 30 more than 10, and which is 20 more than 20, " + "and which is 10 more than 30", + Explain(m, 40)); + + // Failed match. The first matcher, which failed, needs to + // explain. + m = AllOf(GreaterThan(10), GreaterThan(20)); + EXPECT_EQ("which is 5 less than 10", Explain(m, 5)); + + // Failed match. The second matcher, which failed, needs to + // explain. Since it doesn't given an explanation, nothing is + // printed. + m = AllOf(GreaterThan(10), Lt(30)); + EXPECT_EQ("", Explain(m, 40)); + + // Failed match. The second matcher, which failed, needs to + // explain. + m = AllOf(GreaterThan(10), GreaterThan(20)); + EXPECT_EQ("which is 5 less than 20", Explain(m, 15)); +} + +// Helper to allow easy testing of AnyOf matchers with num parameters. +static void AnyOfMatches(int num, const Matcher<int>& m) { + SCOPED_TRACE(Describe(m)); + EXPECT_FALSE(m.Matches(0)); + for (int i = 1; i <= num; ++i) { + EXPECT_TRUE(m.Matches(i)); + } + EXPECT_FALSE(m.Matches(num + 1)); +} + +static void AnyOfStringMatches(int num, const Matcher<std::string>& m) { + SCOPED_TRACE(Describe(m)); + EXPECT_FALSE(m.Matches(std::to_string(0))); + + for (int i = 1; i <= num; ++i) { + EXPECT_TRUE(m.Matches(std::to_string(i))); + } + EXPECT_FALSE(m.Matches(std::to_string(num + 1))); +} + +// 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)); + + // The following tests for varying number of sub-matchers. Due to the way + // the sub-matchers are handled it is enough to test every sub-matcher once + // with sub-matchers using the same matcher type. Varying matcher types are + // checked for above. + AnyOfMatches(2, AnyOf(1, 2)); + AnyOfMatches(3, AnyOf(1, 2, 3)); + AnyOfMatches(4, AnyOf(1, 2, 3, 4)); + AnyOfMatches(5, AnyOf(1, 2, 3, 4, 5)); + AnyOfMatches(6, AnyOf(1, 2, 3, 4, 5, 6)); + AnyOfMatches(7, AnyOf(1, 2, 3, 4, 5, 6, 7)); + AnyOfMatches(8, AnyOf(1, 2, 3, 4, 5, 6, 7, 8)); + AnyOfMatches(9, AnyOf(1, 2, 3, 4, 5, 6, 7, 8, 9)); + AnyOfMatches(10, AnyOf(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)); +} + +// Tests the variadic version of the AnyOfMatcher. +TEST(AnyOfTest, VariadicMatchesWhenAnyMatches) { + // Also make sure AnyOf is defined in the right namespace and does not depend + // on ADL. + Matcher<int> m = ::testing::AnyOf(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11); + + EXPECT_THAT(Describe(m), EndsWith("or (is equal to 11)")); + AnyOfMatches(11, m); + AnyOfMatches(50, AnyOf(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, + 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, + 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, + 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, + 41, 42, 43, 44, 45, 46, 47, 48, 49, 50)); + AnyOfStringMatches( + 50, AnyOf("1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", + "13", "14", "15", "16", "17", "18", "19", "20", "21", "22", + "23", "24", "25", "26", "27", "28", "29", "30", "31", "32", + "33", "34", "35", "36", "37", "38", "39", "40", "41", "42", + "43", "44", "45", "46", "47", "48", "49", "50")); +} + +// Tests the variadic version of the ElementsAreMatcher +TEST(ElementsAreTest, HugeMatcher) { + vector<int> test_vector{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12}; + + EXPECT_THAT(test_vector, + ElementsAre(Eq(1), Eq(2), Lt(13), Eq(4), Eq(5), Eq(6), Eq(7), + Eq(8), Eq(9), Eq(10), Gt(1), Eq(12))); +} + +// Tests the variadic version of the UnorderedElementsAreMatcher +TEST(ElementsAreTest, HugeMatcherStr) { + vector<std::string> test_vector{ + "literal_string", "", "", "", "", "", "", "", "", "", "", ""}; + + EXPECT_THAT(test_vector, UnorderedElementsAre("literal_string", _, _, _, _, _, + _, _, _, _, _, _)); +} + +// Tests the variadic version of the UnorderedElementsAreMatcher +TEST(ElementsAreTest, HugeMatcherUnordered) { + vector<int> test_vector{2, 1, 8, 5, 4, 6, 7, 3, 9, 12, 11, 10}; + + EXPECT_THAT(test_vector, UnorderedElementsAre( + Eq(2), Eq(1), Gt(7), Eq(5), Eq(4), Eq(6), Eq(7), + Eq(3), Eq(9), Eq(12), Eq(11), Ne(122))); +} + + +// Tests that AnyOf(m1, ..., mn) describes itself properly. +TEST(AnyOfTest, CanDescribeSelf) { + Matcher<int> m; + m = AnyOf(Le(1), Ge(3)); + + EXPECT_EQ("(is <= 1) or (is >= 3)", + Describe(m)); + + m = AnyOf(Lt(0), Eq(1), Eq(2)); + EXPECT_EQ("(is < 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 < 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 <= 0) or (is > 10) or (is equal to 3) or (is equal to 5) or (is " + "equal to 7)", + Describe(m)); +} + +// Tests that AnyOf(m1, ..., mn) describes its negation properly. +TEST(AnyOfTest, CanDescribeNegation) { + Matcher<int> m; + m = AnyOf(Le(1), Ge(3)); + EXPECT_EQ("(isn't <= 1) and (isn't >= 3)", + DescribeNegation(m)); + + m = AnyOf(Lt(0), Eq(1), Eq(2)); + EXPECT_EQ("(isn't < 0) and (isn't equal to 1) and (isn't equal to 2)", + DescribeNegation(m)); + + m = AnyOf(Lt(0), Eq(1), Eq(2), Eq(3)); + EXPECT_EQ( + "(isn't < 0) and (isn't equal to 1) and (isn't equal to 2) and (isn't " + "equal to 3)", + DescribeNegation(m)); + + m = AnyOf(Le(0), Gt(10), 3, 5, 7); + EXPECT_EQ( + "(isn't <= 0) and (isn't > 10) and (isn't equal to 3) and (isn't equal " + "to 5) and (isn't equal to 7)", + DescribeNegation(m)); +} + +// Tests that monomorphic matchers are safely cast by the AnyOf matcher. +TEST(AnyOfTest, AnyOfMatcherSafelyCastsMonomorphicMatchers) { + // greater_than_5 and less_than_10 are monomorphic matchers. + Matcher<int> greater_than_5 = Gt(5); + Matcher<int> less_than_10 = Lt(10); + + Matcher<const int&> m = AnyOf(greater_than_5, less_than_10); + Matcher<int&> m2 = AnyOf(greater_than_5, less_than_10); + Matcher<int&> m3 = AnyOf(greater_than_5, m2); + + // Tests that EitherOf works when composing itself. + Matcher<const int&> m4 = AnyOf(greater_than_5, less_than_10, less_than_10); + Matcher<int&> m5 = AnyOf(greater_than_5, less_than_10, less_than_10); +} + +TEST(AnyOfTest, ExplainsResult) { + Matcher<int> m; + + // Failed match. Both matchers need to explain. The second + // matcher doesn't give an explanation, so only the first matcher's + // explanation is printed. + m = AnyOf(GreaterThan(10), Lt(0)); + EXPECT_EQ("which is 5 less than 10", Explain(m, 5)); + + // Failed match. Both matchers need to explain. + m = AnyOf(GreaterThan(10), GreaterThan(20)); + EXPECT_EQ("which is 5 less than 10, and which is 15 less than 20", + Explain(m, 5)); + + // Failed match. All matchers need to explain. The second + // matcher doesn't given an explanation. + m = AnyOf(GreaterThan(10), Gt(20), GreaterThan(30)); + EXPECT_EQ("which is 5 less than 10, and which is 25 less than 30", + Explain(m, 5)); + + // Failed match. All matchers need to explain. + m = AnyOf(GreaterThan(10), GreaterThan(20), GreaterThan(30)); + EXPECT_EQ("which is 5 less than 10, and which is 15 less than 20, " + "and which is 25 less than 30", + Explain(m, 5)); + + // Successful match. The first matcher, which succeeded, needs to + // explain. + m = AnyOf(GreaterThan(10), GreaterThan(20)); + EXPECT_EQ("which is 5 more than 10", Explain(m, 15)); + + // Successful match. The second matcher, which succeeded, needs to + // explain. Since it doesn't given an explanation, nothing is + // printed. + m = AnyOf(GreaterThan(10), Lt(30)); + EXPECT_EQ("", Explain(m, 0)); + + // Successful match. The second matcher, which succeeded, needs to + // explain. + m = AnyOf(GreaterThan(30), GreaterThan(20)); + EXPECT_EQ("which is 5 more than 20", Explain(m, 25)); +} + +// 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: + int threshold_; +}; + +// For testing Truly(). +const int foo = 0; + +// This predicate returns true if and only if 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)); +} + +// A class that can be implicitly converted to bool. +class ConvertibleToBool { + public: + explicit ConvertibleToBool(int number) : number_(number) {} + operator bool() const { return number_ != 0; } + + private: + int number_; +}; + +ConvertibleToBool IsNotZero(int number) { + return ConvertibleToBool(number); +} + +// Tests that the predicate used in Truly() may return a class that's +// implicitly convertible to bool, even when the class has no +// operator!(). +TEST(TrulyTest, PredicateCanReturnAClassConvertibleToBool) { + Matcher<int> m = Truly(IsNotZero); + EXPECT_TRUE(m.Matches(1)); + EXPECT_FALSE(m.Matches(0)); +} + +// 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 Truly(predicate) provides a helpful reason when it fails. +TEST(TrulyTest, ExplainsFailures) { + StringMatchResultListener listener; + EXPECT_FALSE(ExplainMatchResult(Truly(IsPositive), -1, &listener)); + EXPECT_EQ(listener.str(), "didn't satisfy the given predicate"); +} + +// 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 Value(value, matcher). Since Value() is a simple wrapper for +// Matches(), which has been tested already, we don't spend a lot of +// effort on testing Value(). +TEST(ValueTest, WorksWithPolymorphicMatcher) { + EXPECT_TRUE(Value("hi", StartsWith("h"))); + EXPECT_FALSE(Value(5, Gt(10))); +} + +TEST(ValueTest, WorksWithMonomorphicMatcher) { + const Matcher<int> is_zero = Eq(0); + EXPECT_TRUE(Value(0, is_zero)); + EXPECT_FALSE(Value('a', is_zero)); + + int n = 0; + const Matcher<const int&> ref_n = Ref(n); + EXPECT_TRUE(Value(n, ref_n)); + EXPECT_FALSE(Value(1, ref_n)); +} + +TEST(ExplainMatchResultTest, WorksWithPolymorphicMatcher) { + StringMatchResultListener listener1; + EXPECT_TRUE(ExplainMatchResult(PolymorphicIsEven(), 42, &listener1)); + EXPECT_EQ("% 2 == 0", listener1.str()); + + StringMatchResultListener listener2; + EXPECT_FALSE(ExplainMatchResult(Ge(42), 1.5, &listener2)); + EXPECT_EQ("", listener2.str()); +} + +TEST(ExplainMatchResultTest, WorksWithMonomorphicMatcher) { + const Matcher<int> is_even = PolymorphicIsEven(); + StringMatchResultListener listener1; + EXPECT_TRUE(ExplainMatchResult(is_even, 42, &listener1)); + EXPECT_EQ("% 2 == 0", listener1.str()); + + const Matcher<const double&> is_zero = Eq(0); + StringMatchResultListener listener2; + EXPECT_FALSE(ExplainMatchResult(is_zero, 1.5, &listener2)); + EXPECT_EQ("", listener2.str()); +} + +MATCHER(ConstructNoArg, "") { return true; } +MATCHER_P(Construct1Arg, arg1, "") { return true; } +MATCHER_P2(Construct2Args, arg1, arg2, "") { return true; } + +TEST(MatcherConstruct, ExplicitVsImplicit) { + { + // No arg constructor can be constructed with empty brace. + ConstructNoArgMatcher m = {}; + (void)m; + // And with no args + ConstructNoArgMatcher m2; + (void)m2; + } + { + // The one arg constructor has an explicit constructor. + // This is to prevent the implicit conversion. + using M = Construct1ArgMatcherP<int>; + EXPECT_TRUE((std::is_constructible<M, int>::value)); + EXPECT_FALSE((std::is_convertible<int, M>::value)); + } + { + // Multiple arg matchers can be constructed with an implicit construction. + Construct2ArgsMatcherP2<int, double> m = {1, 2.2}; + (void)m; + } +} + +MATCHER_P(Really, inner_matcher, "") { + return ExplainMatchResult(inner_matcher, arg, result_listener); +} + +TEST(ExplainMatchResultTest, WorksInsideMATCHER) { + EXPECT_THAT(0, Really(Eq(0))); +} + +TEST(DescribeMatcherTest, WorksWithValue) { + EXPECT_EQ("is equal to 42", DescribeMatcher<int>(42)); + EXPECT_EQ("isn't equal to 42", DescribeMatcher<int>(42, true)); +} + +TEST(DescribeMatcherTest, WorksWithMonomorphicMatcher) { + const Matcher<int> monomorphic = Le(0); + EXPECT_EQ("is <= 0", DescribeMatcher<int>(monomorphic)); + EXPECT_EQ("isn't <= 0", DescribeMatcher<int>(monomorphic, true)); +} + +TEST(DescribeMatcherTest, WorksWithPolymorphicMatcher) { + EXPECT_EQ("is even", DescribeMatcher<int>(PolymorphicIsEven())); + EXPECT_EQ("is odd", DescribeMatcher<int>(PolymorphicIsEven(), true)); +} + +TEST(AllArgsTest, WorksForTuple) { + EXPECT_THAT(std::make_tuple(1, 2L), AllArgs(Lt())); + EXPECT_THAT(std::make_tuple(2L, 1), Not(AllArgs(Lt()))); +} + +TEST(AllArgsTest, WorksForNonTuple) { + EXPECT_THAT(42, AllArgs(Gt(0))); + EXPECT_THAT('a', Not(AllArgs(Eq('b')))); +} + +class AllArgsHelper { + public: + AllArgsHelper() {} + + MOCK_METHOD2(Helper, int(char x, int y)); + + private: + GTEST_DISALLOW_COPY_AND_ASSIGN_(AllArgsHelper); +}; + +TEST(AllArgsTest, WorksInWithClause) { + AllArgsHelper helper; + ON_CALL(helper, Helper(_, _)) + .With(AllArgs(Lt())) + .WillByDefault(Return(1)); + EXPECT_CALL(helper, Helper(_, _)); + EXPECT_CALL(helper, Helper(_, _)) + .With(AllArgs(Gt())) + .WillOnce(Return(2)); + + EXPECT_EQ(1, helper.Helper('\1', 2)); + EXPECT_EQ(2, helper.Helper('a', 1)); +} + +class OptionalMatchersHelper { + public: + OptionalMatchersHelper() {} + + MOCK_METHOD0(NoArgs, int()); + + MOCK_METHOD1(OneArg, int(int y)); + + MOCK_METHOD2(TwoArgs, int(char x, int y)); + + MOCK_METHOD1(Overloaded, int(char x)); + MOCK_METHOD2(Overloaded, int(char x, int y)); + + private: + GTEST_DISALLOW_COPY_AND_ASSIGN_(OptionalMatchersHelper); +}; + +TEST(AllArgsTest, WorksWithoutMatchers) { + OptionalMatchersHelper helper; + + ON_CALL(helper, NoArgs).WillByDefault(Return(10)); + ON_CALL(helper, OneArg).WillByDefault(Return(20)); + ON_CALL(helper, TwoArgs).WillByDefault(Return(30)); + + EXPECT_EQ(10, helper.NoArgs()); + EXPECT_EQ(20, helper.OneArg(1)); + EXPECT_EQ(30, helper.TwoArgs('\1', 2)); + + EXPECT_CALL(helper, NoArgs).Times(1); + EXPECT_CALL(helper, OneArg).WillOnce(Return(100)); + EXPECT_CALL(helper, OneArg(17)).WillOnce(Return(200)); + EXPECT_CALL(helper, TwoArgs).Times(0); + + EXPECT_EQ(10, helper.NoArgs()); + EXPECT_EQ(100, helper.OneArg(1)); + EXPECT_EQ(200, helper.OneArg(17)); +} + +// 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 unsigned short n; // NOLINT + n = 5; + + EXPECT_FATAL_FAILURE(ASSERT_THAT(n, Gt(10)), + "Value of: n\n" + "Expected: is > 10\n" + " Actual: 5" + OfType("unsigned short")); + n = 0; + EXPECT_NONFATAL_FAILURE( + EXPECT_THAT(n, AllOf(Le(7), Ge(5))), + "Value of: n\n" + "Expected: (is <= 7) and (is >= 5)\n" + " Actual: 0" + OfType("unsigned short")); +} + +// 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" + OfType("int") + ", which 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 std::string&> ends_with_ok = EndsWith("ok"); + ASSERT_THAT("book", ends_with_ok); + const std::string bad = "bad"; + EXPECT_NONFATAL_FAILURE(EXPECT_THAT(bad, ends_with_ok), + "Value of: bad\n" + "Expected: ends with \"ok\"\n" + " Actual: \"bad\""); + Matcher<int> is_greater_than_5 = Gt(5); + EXPECT_NONFATAL_FAILURE(EXPECT_THAT(5, is_greater_than_5), + "Value of: 5\n" + "Expected: is > 5\n" + " Actual: 5" + OfType("int")); +} + +// Tests floating-point matchers. +template <typename RawType> +class FloatingPointTest : public testing::Test { + protected: + typedef testing::internal::FloatingPoint<RawType> Floating; + typedef typename Floating::Bits Bits; + + FloatingPointTest() + : max_ulps_(Floating::kMaxUlps), + zero_bits_(Floating(0).bits()), + one_bits_(Floating(1).bits()), + infinity_bits_(Floating(Floating::Infinity()).bits()), + 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)), + close_to_one_(Floating::ReinterpretBits(one_bits_ + max_ulps_)), + further_from_one_(Floating::ReinterpretBits(one_bits_ + max_ulps_ + 1)), + infinity_(Floating::Infinity()), + close_to_infinity_( + Floating::ReinterpretBits(infinity_bits_ - max_ulps_)), + further_from_infinity_( + Floating::ReinterpretBits(infinity_bits_ - max_ulps_ - 1)), + max_(Floating::Max()), + 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. + + const Bits max_ulps_; + + const Bits zero_bits_; // The bits that represent 0.0. + const Bits one_bits_; // The bits that represent 1.0. + const Bits infinity_bits_; // The bits that represent +infinity. + + // Some numbers close to 0.0. + const RawType close_to_positive_zero_; + const RawType close_to_negative_zero_; + const RawType further_from_negative_zero_; + + // Some numbers close to 1.0. + const RawType close_to_one_; + const RawType further_from_one_; + + // Some numbers close to +infinity. + const RawType infinity_; + const RawType close_to_infinity_; + const RawType further_from_infinity_; + + // Maximum representable value that's not infinity. + const RawType max_; + + // Some NaNs. + const RawType nan1_; + const RawType nan2_; +}; + +// Tests floating-point matchers with fixed epsilons. +template <typename RawType> +class FloatingPointNearTest : public FloatingPointTest<RawType> { + protected: + typedef FloatingPointTest<RawType> ParentType; + + // A battery of tests for FloatingEqMatcher::Matches with a fixed epsilon. + // matcher_maker is a pointer to a function which creates a FloatingEqMatcher. + void TestNearMatches( + testing::internal::FloatingEqMatcher<RawType> + (*matcher_maker)(RawType, RawType)) { + Matcher<RawType> m1 = matcher_maker(0.0, 0.0); + EXPECT_TRUE(m1.Matches(0.0)); + EXPECT_TRUE(m1.Matches(-0.0)); + EXPECT_FALSE(m1.Matches(ParentType::close_to_positive_zero_)); + EXPECT_FALSE(m1.Matches(ParentType::close_to_negative_zero_)); + EXPECT_FALSE(m1.Matches(1.0)); + + Matcher<RawType> m2 = matcher_maker(0.0, 1.0); + EXPECT_TRUE(m2.Matches(0.0)); + EXPECT_TRUE(m2.Matches(-0.0)); + EXPECT_TRUE(m2.Matches(1.0)); + EXPECT_TRUE(m2.Matches(-1.0)); + EXPECT_FALSE(m2.Matches(ParentType::close_to_one_)); + EXPECT_FALSE(m2.Matches(-ParentType::close_to_one_)); + + // Check that inf matches inf, regardless of the of the specified max + // absolute error. + Matcher<RawType> m3 = matcher_maker(ParentType::infinity_, 0.0); + EXPECT_TRUE(m3.Matches(ParentType::infinity_)); + EXPECT_FALSE(m3.Matches(ParentType::close_to_infinity_)); + EXPECT_FALSE(m3.Matches(-ParentType::infinity_)); + + Matcher<RawType> m4 = matcher_maker(-ParentType::infinity_, 0.0); + EXPECT_TRUE(m4.Matches(-ParentType::infinity_)); + EXPECT_FALSE(m4.Matches(-ParentType::close_to_infinity_)); + EXPECT_FALSE(m4.Matches(ParentType::infinity_)); + + // Test various overflow scenarios. + Matcher<RawType> m5 = matcher_maker(ParentType::max_, ParentType::max_); + EXPECT_TRUE(m5.Matches(ParentType::max_)); + EXPECT_FALSE(m5.Matches(-ParentType::max_)); + + Matcher<RawType> m6 = matcher_maker(-ParentType::max_, ParentType::max_); + EXPECT_FALSE(m6.Matches(ParentType::max_)); + EXPECT_TRUE(m6.Matches(-ParentType::max_)); + + Matcher<RawType> m7 = matcher_maker(ParentType::max_, 0); + EXPECT_TRUE(m7.Matches(ParentType::max_)); + EXPECT_FALSE(m7.Matches(-ParentType::max_)); + + Matcher<RawType> m8 = matcher_maker(-ParentType::max_, 0); + EXPECT_FALSE(m8.Matches(ParentType::max_)); + EXPECT_TRUE(m8.Matches(-ParentType::max_)); + + // The difference between max() and -max() normally overflows to infinity, + // but it should still match if the max_abs_error is also infinity. + Matcher<RawType> m9 = matcher_maker( + ParentType::max_, ParentType::infinity_); + EXPECT_TRUE(m8.Matches(-ParentType::max_)); + + // matcher_maker can produce a Matcher<const RawType&>, which is needed in + // some cases. + Matcher<const RawType&> m10 = matcher_maker(0.0, 1.0); + EXPECT_TRUE(m10.Matches(-0.0)); + EXPECT_TRUE(m10.Matches(ParentType::close_to_positive_zero_)); + EXPECT_FALSE(m10.Matches(ParentType::close_to_one_)); + + // matcher_maker can produce a Matcher<RawType&>, which is needed in some + // cases. + Matcher<RawType&> m11 = matcher_maker(0.0, 1.0); + RawType x = 0.0; + EXPECT_TRUE(m11.Matches(x)); + x = 1.0f; + EXPECT_TRUE(m11.Matches(x)); + x = -1.0f; + EXPECT_TRUE(m11.Matches(x)); + x = 1.1f; + EXPECT_FALSE(m11.Matches(x)); + x = -1.1f; + EXPECT_FALSE(m11.Matches(x)); + } +}; + +// 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("isn't approximately 2", DescribeNegation(m1)); + + Matcher<float> m2 = FloatEq(0.5f); + EXPECT_EQ("is approximately 0.5", Describe(m2)); + EXPECT_EQ("isn't 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("isn't approximately 2", DescribeNegation(m1)); + + Matcher<float> m2 = NanSensitiveFloatEq(0.5f); + EXPECT_EQ("is approximately 0.5", Describe(m2)); + EXPECT_EQ("isn't approximately 0.5", DescribeNegation(m2)); + + Matcher<float> m3 = NanSensitiveFloatEq(nan1_); + EXPECT_EQ("is NaN", Describe(m3)); + EXPECT_EQ("isn't NaN", DescribeNegation(m3)); +} + +// Instantiate FloatingPointTest for testing floats with a user-specified +// max absolute error. +typedef FloatingPointNearTest<float> FloatNearTest; + +TEST_F(FloatNearTest, FloatNearMatches) { + TestNearMatches(&FloatNear); +} + +TEST_F(FloatNearTest, NanSensitiveFloatNearApproximatelyMatchesFloats) { + TestNearMatches(&NanSensitiveFloatNear); +} + +TEST_F(FloatNearTest, FloatNearCanDescribeSelf) { + Matcher<float> m1 = FloatNear(2.0f, 0.5f); + EXPECT_EQ("is approximately 2 (absolute error <= 0.5)", Describe(m1)); + EXPECT_EQ( + "isn't approximately 2 (absolute error > 0.5)", DescribeNegation(m1)); + + Matcher<float> m2 = FloatNear(0.5f, 0.5f); + EXPECT_EQ("is approximately 0.5 (absolute error <= 0.5)", Describe(m2)); + EXPECT_EQ( + "isn't approximately 0.5 (absolute error > 0.5)", DescribeNegation(m2)); + + Matcher<float> m3 = FloatNear(nan1_, 0.0); + EXPECT_EQ("never matches", Describe(m3)); + EXPECT_EQ("is anything", DescribeNegation(m3)); +} + +TEST_F(FloatNearTest, NanSensitiveFloatNearCanDescribeSelf) { + Matcher<float> m1 = NanSensitiveFloatNear(2.0f, 0.5f); + EXPECT_EQ("is approximately 2 (absolute error <= 0.5)", Describe(m1)); + EXPECT_EQ( + "isn't approximately 2 (absolute error > 0.5)", DescribeNegation(m1)); + + Matcher<float> m2 = NanSensitiveFloatNear(0.5f, 0.5f); + EXPECT_EQ("is approximately 0.5 (absolute error <= 0.5)", Describe(m2)); + EXPECT_EQ( + "isn't approximately 0.5 (absolute error > 0.5)", DescribeNegation(m2)); + + Matcher<float> m3 = NanSensitiveFloatNear(nan1_, 0.1f); + EXPECT_EQ("is NaN", Describe(m3)); + EXPECT_EQ("isn't NaN", DescribeNegation(m3)); +} + +TEST_F(FloatNearTest, FloatNearCannotMatchNaN) { + // FloatNear never matches NaN. + Matcher<float> m = FloatNear(ParentType::nan1_, 0.1f); + EXPECT_FALSE(m.Matches(nan1_)); + EXPECT_FALSE(m.Matches(nan2_)); + EXPECT_FALSE(m.Matches(1.0)); +} + +TEST_F(FloatNearTest, NanSensitiveFloatNearCanMatchNaN) { + // NanSensitiveFloatNear will match NaN. + Matcher<float> m = NanSensitiveFloatNear(nan1_, 0.1f); + EXPECT_TRUE(m.Matches(nan1_)); + EXPECT_TRUE(m.Matches(nan2_)); + EXPECT_FALSE(m.Matches(1.0)); +} + +// 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("isn't approximately 2", DescribeNegation(m1)); + + Matcher<double> m2 = DoubleEq(0.5); + EXPECT_EQ("is approximately 0.5", Describe(m2)); + EXPECT_EQ("isn't 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("isn't approximately 2", DescribeNegation(m1)); + + Matcher<double> m2 = NanSensitiveDoubleEq(0.5); + EXPECT_EQ("is approximately 0.5", Describe(m2)); + EXPECT_EQ("isn't approximately 0.5", DescribeNegation(m2)); + + Matcher<double> m3 = NanSensitiveDoubleEq(nan1_); + EXPECT_EQ("is NaN", Describe(m3)); + EXPECT_EQ("isn't NaN", DescribeNegation(m3)); +} + +// Instantiate FloatingPointTest for testing floats with a user-specified +// max absolute error. +typedef FloatingPointNearTest<double> DoubleNearTest; + +TEST_F(DoubleNearTest, DoubleNearMatches) { + TestNearMatches(&DoubleNear); +} + +TEST_F(DoubleNearTest, NanSensitiveDoubleNearApproximatelyMatchesDoubles) { + TestNearMatches(&NanSensitiveDoubleNear); +} + +TEST_F(DoubleNearTest, DoubleNearCanDescribeSelf) { + Matcher<double> m1 = DoubleNear(2.0, 0.5); + EXPECT_EQ("is approximately 2 (absolute error <= 0.5)", Describe(m1)); + EXPECT_EQ( + "isn't approximately 2 (absolute error > 0.5)", DescribeNegation(m1)); + + Matcher<double> m2 = DoubleNear(0.5, 0.5); + EXPECT_EQ("is approximately 0.5 (absolute error <= 0.5)", Describe(m2)); + EXPECT_EQ( + "isn't approximately 0.5 (absolute error > 0.5)", DescribeNegation(m2)); + + Matcher<double> m3 = DoubleNear(nan1_, 0.0); + EXPECT_EQ("never matches", Describe(m3)); + EXPECT_EQ("is anything", DescribeNegation(m3)); +} + +TEST_F(DoubleNearTest, ExplainsResultWhenMatchFails) { + EXPECT_EQ("", Explain(DoubleNear(2.0, 0.1), 2.05)); + EXPECT_EQ("which is 0.2 from 2", Explain(DoubleNear(2.0, 0.1), 2.2)); + EXPECT_EQ("which is -0.3 from 2", Explain(DoubleNear(2.0, 0.1), 1.7)); + + const std::string explanation = + Explain(DoubleNear(2.1, 1e-10), 2.1 + 1.2e-10); + // Different C++ implementations may print floating-point numbers + // slightly differently. + EXPECT_TRUE(explanation == "which is 1.2e-10 from 2.1" || // GCC + explanation == "which is 1.2e-010 from 2.1") // MSVC + << " where explanation is \"" << explanation << "\"."; +} + +TEST_F(DoubleNearTest, NanSensitiveDoubleNearCanDescribeSelf) { + Matcher<double> m1 = NanSensitiveDoubleNear(2.0, 0.5); + EXPECT_EQ("is approximately 2 (absolute error <= 0.5)", Describe(m1)); + EXPECT_EQ( + "isn't approximately 2 (absolute error > 0.5)", DescribeNegation(m1)); + + Matcher<double> m2 = NanSensitiveDoubleNear(0.5, 0.5); + EXPECT_EQ("is approximately 0.5 (absolute error <= 0.5)", Describe(m2)); + EXPECT_EQ( + "isn't approximately 0.5 (absolute error > 0.5)", DescribeNegation(m2)); + + Matcher<double> m3 = NanSensitiveDoubleNear(nan1_, 0.1); + EXPECT_EQ("is NaN", Describe(m3)); + EXPECT_EQ("isn't NaN", DescribeNegation(m3)); +} + +TEST_F(DoubleNearTest, DoubleNearCannotMatchNaN) { + // DoubleNear never matches NaN. + Matcher<double> m = DoubleNear(ParentType::nan1_, 0.1); + EXPECT_FALSE(m.Matches(nan1_)); + EXPECT_FALSE(m.Matches(nan2_)); + EXPECT_FALSE(m.Matches(1.0)); +} + +TEST_F(DoubleNearTest, NanSensitiveDoubleNearCanMatchNaN) { + // NanSensitiveDoubleNear will match NaN. + Matcher<double> m = NanSensitiveDoubleNear(nan1_, 0.1); + EXPECT_TRUE(m.Matches(nan1_)); + EXPECT_TRUE(m.Matches(nan2_)); + EXPECT_FALSE(m.Matches(1.0)); +} + +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(nullptr)); +} + +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(nullptr)); +} + +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(nullptr)); +} + +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 = nullptr; + EXPECT_FALSE(m.Matches(p)); +} + +TEST(PointeeTest, SmartPointer) { + const Matcher<std::unique_ptr<int>> m = Pointee(Ge(0)); + + std::unique_ptr<int> n(new int(1)); + EXPECT_TRUE(m.Matches(n)); +} + +TEST(PointeeTest, SmartPointerToConst) { + const Matcher<std::unique_ptr<const int>> m = Pointee(Ge(0)); + + // There's no implicit conversion from unique_ptr<int> to const + // unique_ptr<const int>, so we must pass a unique_ptr<const int> into the + // matcher. + std::unique_ptr<const int> n(new int(1)); + EXPECT_TRUE(m.Matches(n)); +} + +TEST(PointerTest, RawPointer) { + int n = 1; + const Matcher<int*> m = Pointer(Eq(&n)); + + EXPECT_TRUE(m.Matches(&n)); + + int* p = nullptr; + EXPECT_FALSE(m.Matches(p)); + EXPECT_FALSE(m.Matches(nullptr)); +} + +TEST(PointerTest, RawPointerToConst) { + int n = 1; + const Matcher<const int*> m = Pointer(Eq(&n)); + + EXPECT_TRUE(m.Matches(&n)); + + int* p = nullptr; + EXPECT_FALSE(m.Matches(p)); + EXPECT_FALSE(m.Matches(nullptr)); +} + +TEST(PointerTest, SmartPointer) { + std::unique_ptr<int> n(new int(10)); + int* raw_n = n.get(); + const Matcher<std::unique_ptr<int>> m = Pointer(Eq(raw_n)); + + EXPECT_TRUE(m.Matches(n)); +} + +TEST(PointerTest, SmartPointerToConst) { + std::unique_ptr<const int> n(new int(10)); + const int* raw_n = n.get(); + const Matcher<std::unique_ptr<const int>> m = Pointer(Eq(raw_n)); + + // There's no implicit conversion from unique_ptr<int> to const + // unique_ptr<const int>, so we must pass a unique_ptr<const int> into the + // matcher. + std::unique_ptr<const int> p(new int(10)); + EXPECT_FALSE(m.Matches(p)); +} + +TEST(AddressTest, NonConst) { + int n = 1; + const Matcher<int> m = Address(Eq(&n)); + + EXPECT_TRUE(m.Matches(n)); + + int other = 5; + + EXPECT_FALSE(m.Matches(other)); + + int& n_ref = n; + + EXPECT_TRUE(m.Matches(n_ref)); +} + +TEST(AddressTest, Const) { + const int n = 1; + const Matcher<int> m = Address(Eq(&n)); + + EXPECT_TRUE(m.Matches(n)); + + int other = 5; + + EXPECT_FALSE(m.Matches(other)); +} + +TEST(AddressTest, MatcherDoesntCopy) { + std::unique_ptr<int> n(new int(1)); + const Matcher<std::unique_ptr<int>> m = Address(Eq(&n)); + + EXPECT_TRUE(m.Matches(n)); +} + +TEST(AddressTest, Describe) { + Matcher<int> matcher = Address(_); + EXPECT_EQ("has address that is anything", Describe(matcher)); + EXPECT_EQ("does not have address that is anything", + DescribeNegation(matcher)); +} + +MATCHER_P(FieldIIs, inner_matcher, "") { + return ExplainMatchResult(inner_matcher, arg.i, result_listener); +} + +#if GTEST_HAS_RTTI +TEST(WhenDynamicCastToTest, SameType) { + Derived derived; + derived.i = 4; + + // Right type. A pointer is passed down. + Base* as_base_ptr = &derived; + EXPECT_THAT(as_base_ptr, WhenDynamicCastTo<Derived*>(Not(IsNull()))); + EXPECT_THAT(as_base_ptr, WhenDynamicCastTo<Derived*>(Pointee(FieldIIs(4)))); + EXPECT_THAT(as_base_ptr, + Not(WhenDynamicCastTo<Derived*>(Pointee(FieldIIs(5))))); +} + +TEST(WhenDynamicCastToTest, WrongTypes) { + Base base; + Derived derived; + OtherDerived other_derived; + + // Wrong types. NULL is passed. + EXPECT_THAT(&base, Not(WhenDynamicCastTo<Derived*>(Pointee(_)))); + EXPECT_THAT(&base, WhenDynamicCastTo<Derived*>(IsNull())); + Base* as_base_ptr = &derived; + EXPECT_THAT(as_base_ptr, Not(WhenDynamicCastTo<OtherDerived*>(Pointee(_)))); + EXPECT_THAT(as_base_ptr, WhenDynamicCastTo<OtherDerived*>(IsNull())); + as_base_ptr = &other_derived; + EXPECT_THAT(as_base_ptr, Not(WhenDynamicCastTo<Derived*>(Pointee(_)))); + EXPECT_THAT(as_base_ptr, WhenDynamicCastTo<Derived*>(IsNull())); +} + +TEST(WhenDynamicCastToTest, AlreadyNull) { + // Already NULL. + Base* as_base_ptr = nullptr; + EXPECT_THAT(as_base_ptr, WhenDynamicCastTo<Derived*>(IsNull())); +} + +struct AmbiguousCastTypes { + class VirtualDerived : public virtual Base {}; + class DerivedSub1 : public VirtualDerived {}; + class DerivedSub2 : public VirtualDerived {}; + class ManyDerivedInHierarchy : public DerivedSub1, public DerivedSub2 {}; +}; + +TEST(WhenDynamicCastToTest, AmbiguousCast) { + AmbiguousCastTypes::DerivedSub1 sub1; + AmbiguousCastTypes::ManyDerivedInHierarchy many_derived; + // Multiply derived from Base. dynamic_cast<> returns NULL. + Base* as_base_ptr = + static_cast<AmbiguousCastTypes::DerivedSub1*>(&many_derived); + EXPECT_THAT(as_base_ptr, + WhenDynamicCastTo<AmbiguousCastTypes::VirtualDerived*>(IsNull())); + as_base_ptr = &sub1; + EXPECT_THAT( + as_base_ptr, + WhenDynamicCastTo<AmbiguousCastTypes::VirtualDerived*>(Not(IsNull()))); +} + +TEST(WhenDynamicCastToTest, Describe) { + Matcher<Base*> matcher = WhenDynamicCastTo<Derived*>(Pointee(_)); + const std::string prefix = + "when dynamic_cast to " + internal::GetTypeName<Derived*>() + ", "; + EXPECT_EQ(prefix + "points to a value that is anything", Describe(matcher)); + EXPECT_EQ(prefix + "does not point to a value that is anything", + DescribeNegation(matcher)); +} + +TEST(WhenDynamicCastToTest, Explain) { + Matcher<Base*> matcher = WhenDynamicCastTo<Derived*>(Pointee(_)); + Base* null = nullptr; + EXPECT_THAT(Explain(matcher, null), HasSubstr("NULL")); + Derived derived; + EXPECT_TRUE(matcher.Matches(&derived)); + EXPECT_THAT(Explain(matcher, &derived), HasSubstr("which points to ")); + + // With references, the matcher itself can fail. Test for that one. + Matcher<const Base&> ref_matcher = WhenDynamicCastTo<const OtherDerived&>(_); + EXPECT_THAT(Explain(ref_matcher, derived), + HasSubstr("which cannot be dynamic_cast")); +} + +TEST(WhenDynamicCastToTest, GoodReference) { + Derived derived; + derived.i = 4; + Base& as_base_ref = derived; + EXPECT_THAT(as_base_ref, WhenDynamicCastTo<const Derived&>(FieldIIs(4))); + EXPECT_THAT(as_base_ref, WhenDynamicCastTo<const Derived&>(Not(FieldIIs(5)))); +} + +TEST(WhenDynamicCastToTest, BadReference) { + Derived derived; + Base& as_base_ref = derived; + EXPECT_THAT(as_base_ref, Not(WhenDynamicCastTo<const OtherDerived&>(_))); +} +#endif // GTEST_HAS_RTTI + +// Minimal const-propagating pointer. +template <typename T> +class ConstPropagatingPtr { + public: + typedef T element_type; + + ConstPropagatingPtr() : val_() {} + explicit ConstPropagatingPtr(T* t) : val_(t) {} + ConstPropagatingPtr(const ConstPropagatingPtr& other) : val_(other.val_) {} + + T* get() { return val_; } + T& operator*() { return *val_; } + // Most smart pointers return non-const T* and T& from the next methods. + const T* get() const { return val_; } + const T& operator*() const { return *val_; } + + private: + T* val_; +}; + +TEST(PointeeTest, WorksWithConstPropagatingPointers) { + const Matcher< ConstPropagatingPtr<int> > m = Pointee(Lt(5)); + int three = 3; + const ConstPropagatingPtr<int> co(&three); + ConstPropagatingPtr<int> o(&three); + EXPECT_TRUE(m.Matches(o)); + EXPECT_TRUE(m.Matches(co)); + *o = 6; + EXPECT_FALSE(m.Matches(o)); + EXPECT_FALSE(m.Matches(ConstPropagatingPtr<int>())); +} + +TEST(PointeeTest, NeverMatchesNull) { + const Matcher<const char*> m = Pointee(_); + EXPECT_FALSE(m.Matches(nullptr)); +} + +// 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(nullptr)); +} + +TEST(PointeeTest, CanDescribeSelf) { + const Matcher<int*> m = Pointee(Gt(3)); + EXPECT_EQ("points to a value that is > 3", Describe(m)); + EXPECT_EQ("does not point to a value that is > 3", + DescribeNegation(m)); +} + +TEST(PointeeTest, CanExplainMatchResult) { + const Matcher<const std::string*> m = Pointee(StartsWith("Hi")); + + EXPECT_EQ("", Explain(m, static_cast<const std::string*>(nullptr))); + + const Matcher<long*> m2 = Pointee(GreaterThan(1)); // NOLINT + long n = 3; // NOLINT + EXPECT_EQ("which points to 3" + OfType("long") + ", which is 2 more than 1", + Explain(m2, &n)); +} + +TEST(PointeeTest, AlwaysExplainsPointee) { + const Matcher<int*> m = Pointee(0); + int n = 42; + EXPECT_EQ("which points to 42" + OfType("int"), Explain(m, &n)); +} + +// An uncopyable class. +class Uncopyable { + public: + Uncopyable() : value_(-1) {} + explicit Uncopyable(int a_value) : value_(a_value) {} + + int value() const { return value_; } + void set_value(int i) { value_ = i; } + + private: + int value_; + GTEST_DISALLOW_COPY_AND_ASSIGN_(Uncopyable); +}; + +// Returns true if and only if x.value() is positive. +bool ValueIsPositive(const Uncopyable& x) { return x.value() > 0; } + +MATCHER_P(UncopyableIs, inner_matcher, "") { + return ExplainMatchResult(inner_matcher, arg.value(), result_listener); +} + +// A user-defined struct for testing Field(). +struct AStruct { + AStruct() : x(0), y(1.0), z(5), p(nullptr) {} + 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)); + Matcher<AStruct> m_with_name = Field("x", &AStruct::x, Ge(0)); + + AStruct a; + EXPECT_TRUE(m.Matches(a)); + EXPECT_TRUE(m_with_name.Matches(a)); + a.x = -1; + EXPECT_FALSE(m.Matches(a)); + EXPECT_FALSE(m_with_name.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)); + Matcher<AStruct> m_with_name = Field("y", &AStruct::y, Ge(0.0)); + EXPECT_TRUE(m.Matches(a)); + EXPECT_TRUE(m_with_name.Matches(a)); + m = Field(&AStruct::y, Le(0.0)); + m_with_name = Field("y", &AStruct::y, Le(0.0)); + EXPECT_FALSE(m.Matches(a)); + EXPECT_FALSE(m_with_name.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*>(nullptr)); + 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("is an object whose given field is >= 0", Describe(m)); + EXPECT_EQ("is an object whose given field isn't >= 0", DescribeNegation(m)); +} + +TEST(FieldTest, CanDescribeSelfWithFieldName) { + Matcher<const AStruct&> m = Field("field_name", &AStruct::x, Ge(0)); + + EXPECT_EQ("is an object whose field `field_name` is >= 0", Describe(m)); + EXPECT_EQ("is an object whose field `field_name` isn't >= 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("whose given field is 1" + OfType("int"), Explain(m, a)); + + m = Field(&AStruct::x, GreaterThan(0)); + EXPECT_EQ( + "whose given field is 1" + OfType("int") + ", which is 1 more than 0", + Explain(m, a)); +} + +TEST(FieldTest, CanExplainMatchResultWithFieldName) { + Matcher<const AStruct&> m = Field("field_name", &AStruct::x, Ge(0)); + + AStruct a; + a.x = 1; + EXPECT_EQ("whose field `field_name` is 1" + OfType("int"), Explain(m, a)); + + m = Field("field_name", &AStruct::x, GreaterThan(0)); + EXPECT_EQ("whose field `field_name` is 1" + OfType("int") + + ", which 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() works when the argument is a reference to a const pointer. +TEST(FieldForPointerTest, WorksForReferenceToConstPointer) { + Matcher<AStruct* const&> 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(nullptr)); +} + +// 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("is an object whose given field is >= 0", Describe(m)); + EXPECT_EQ("is an object whose given field isn't >= 0", DescribeNegation(m)); +} + +TEST(FieldForPointerTest, CanDescribeSelfWithFieldName) { + Matcher<const AStruct*> m = Field("field_name", &AStruct::x, Ge(0)); + + EXPECT_EQ("is an object whose field `field_name` is >= 0", Describe(m)); + EXPECT_EQ("is an object whose field `field_name` isn't >= 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*>(nullptr))); + EXPECT_EQ("which points to an object whose given field is 1" + OfType("int"), + Explain(m, &a)); + + m = Field(&AStruct::x, GreaterThan(0)); + EXPECT_EQ("which points to an object whose given field is 1" + OfType("int") + + ", which is 1 more than 0", Explain(m, &a)); +} + +TEST(FieldForPointerTest, CanExplainMatchResultWithFieldName) { + Matcher<const AStruct*> m = Field("field_name", &AStruct::x, Ge(0)); + + AStruct a; + a.x = 1; + EXPECT_EQ("", Explain(m, static_cast<const AStruct*>(nullptr))); + EXPECT_EQ( + "which points to an object whose field `field_name` is 1" + OfType("int"), + Explain(m, &a)); + + m = Field("field_name", &AStruct::x, GreaterThan(0)); + EXPECT_EQ("which points to an object whose field `field_name` is 1" + + OfType("int") + ", which 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 std::string& s() const { return s_; } + + const std::string& s_ref() const & { return s_; } + + void set_s(const std::string& new_s) { s_ = new_s; } + + // A getter that returns a reference to non-const. + double& x() const { return x_; } + + private: + int n_; + std::string s_; + + static double x_; +}; + +double AClass::x_ = 0.0; + +// A derived class for testing Property(). +class DerivedClass : public AClass { + public: + int k() const { return k_; } + 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)); + Matcher<const AClass&> m_with_name = Property("n", &AClass::n, Ge(0)); + + AClass a; + a.set_n(1); + EXPECT_TRUE(m.Matches(a)); + EXPECT_TRUE(m_with_name.Matches(a)); + + a.set_n(-1); + EXPECT_FALSE(m.Matches(a)); + EXPECT_FALSE(m_with_name.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")); + Matcher<const AClass&> m_with_name = + Property("s", &AClass::s, StartsWith("hi")); + + AClass a; + a.set_s("hill"); + EXPECT_TRUE(m.Matches(a)); + EXPECT_TRUE(m_with_name.Matches(a)); + + a.set_s("hole"); + EXPECT_FALSE(m.Matches(a)); + EXPECT_FALSE(m_with_name.Matches(a)); +} + +// Tests that Property(&Foo::property, ...) works when property() is +// ref-qualified. +TEST(PropertyTest, WorksForRefQualifiedProperty) { + Matcher<const AClass&> m = Property(&AClass::s_ref, StartsWith("hi")); + Matcher<const AClass&> m_with_name = + Property("s", &AClass::s_ref, StartsWith("hi")); + + AClass a; + a.set_s("hill"); + EXPECT_TRUE(m.Matches(a)); + EXPECT_TRUE(m_with_name.Matches(a)); + + a.set_s("hole"); + EXPECT_FALSE(m.Matches(a)); + EXPECT_FALSE(m_with_name.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))); + + Matcher<const AClass&> m_with_name = + Property("n", &AClass::n, Matcher<signed char>(Ge(0))); + + AClass a; + EXPECT_TRUE(m.Matches(a)); + EXPECT_TRUE(m_with_name.Matches(a)); + a.set_n(-1); + EXPECT_FALSE(m.Matches(a)); + EXPECT_FALSE(m_with_name.Matches(a)); +} + +// Tests that Property() can describe itself. +TEST(PropertyTest, CanDescribeSelf) { + Matcher<const AClass&> m = Property(&AClass::n, Ge(0)); + + EXPECT_EQ("is an object whose given property is >= 0", Describe(m)); + EXPECT_EQ("is an object whose given property isn't >= 0", + DescribeNegation(m)); +} + +TEST(PropertyTest, CanDescribeSelfWithPropertyName) { + Matcher<const AClass&> m = Property("fancy_name", &AClass::n, Ge(0)); + + EXPECT_EQ("is an object whose property `fancy_name` is >= 0", Describe(m)); + EXPECT_EQ("is an object whose property `fancy_name` isn't >= 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("whose given property is 1" + OfType("int"), Explain(m, a)); + + m = Property(&AClass::n, GreaterThan(0)); + EXPECT_EQ( + "whose given property is 1" + OfType("int") + ", which is 1 more than 0", + Explain(m, a)); +} + +TEST(PropertyTest, CanExplainMatchResultWithPropertyName) { + Matcher<const AClass&> m = Property("fancy_name", &AClass::n, Ge(0)); + + AClass a; + a.set_n(1); + EXPECT_EQ("whose property `fancy_name` is 1" + OfType("int"), Explain(m, a)); + + m = Property("fancy_name", &AClass::n, GreaterThan(0)); + EXPECT_EQ("whose property `fancy_name` is 1" + OfType("int") + + ", which 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() works when the argument is a reference to a +// const pointer. +TEST(PropertyForPointerTest, WorksForReferenceToConstPointer) { + Matcher<AClass* const&> 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(nullptr)); +} + +// 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("is an object whose given property is >= 0", Describe(m)); + EXPECT_EQ("is an object whose given property isn't >= 0", + DescribeNegation(m)); +} + +TEST(PropertyForPointerTest, CanDescribeSelfWithPropertyDescription) { + Matcher<const AClass*> m = Property("fancy_name", &AClass::n, Ge(0)); + + EXPECT_EQ("is an object whose property `fancy_name` is >= 0", Describe(m)); + EXPECT_EQ("is an object whose property `fancy_name` isn't >= 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*>(nullptr))); + EXPECT_EQ( + "which points to an object whose given property is 1" + OfType("int"), + Explain(m, &a)); + + m = Property(&AClass::n, GreaterThan(0)); + EXPECT_EQ("which points to an object whose given property is 1" + + OfType("int") + ", which is 1 more than 0", + Explain(m, &a)); +} + +TEST(PropertyForPointerTest, CanExplainMatchResultWithPropertyName) { + Matcher<const AClass*> m = Property("fancy_name", &AClass::n, Ge(0)); + + AClass a; + a.set_n(1); + EXPECT_EQ("", Explain(m, static_cast<const AClass*>(nullptr))); + EXPECT_EQ("which points to an object whose property `fancy_name` is 1" + + OfType("int"), + Explain(m, &a)); + + m = Property("fancy_name", &AClass::n, GreaterThan(0)); + EXPECT_EQ("which points to an object whose property `fancy_name` is 1" + + OfType("int") + ", which 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. +std::string IntToStringFunction(int input) { + return input == 1 ? "foo" : "bar"; +} + +TEST(ResultOfTest, WorksForFunctionPointers) { + Matcher<int> matcher = ResultOf(&IntToStringFunction, Eq(std::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("is mapped by the given callable to a value that " + "is equal to \"foo\"", Describe(matcher)); + EXPECT_EQ("is mapped by the given callable to a value that " + "isn't 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("which is mapped by the given callable to 90" + OfType("int"), + Explain(matcher, 36)); + + matcher = ResultOf(&IntFunction, GreaterThan(85)); + EXPECT_EQ("which is mapped by the given callable to 90" + OfType("int") + + ", which 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; } // NOLINT + +Uncopyable& RefUncopyableFunction(Uncopyable& obj) { // NOLINT + 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 std::string& StringFunction(const std::string& input) { return input; } + +TEST(ResultOfTest, WorksForReferenceToConstResults) { + std::string s = "foo"; + std::string s2 = s; + Matcher<const std::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)); +} + +// Tests that the program aborts when ResultOf is passed +// a NULL function pointer. +TEST(ResultOfDeathTest, DiesOnNullFunctionPointers) { + EXPECT_DEATH_IF_SUPPORTED( + ResultOf(static_cast<std::string (*)(int dummy)>(nullptr), + Eq(std::string("foo"))), + "NULL function pointer is passed into ResultOf\\(\\)\\."); +} + +// 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 { + std::string operator()(int input) const { + return IntToStringFunction(input); + } +}; + +TEST(ResultOfTest, WorksForFunctors) { + Matcher<int> matcher = ResultOf(Functor(), Eq(std::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 than 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)); } + std::string operator()(int *p) { return p ? "good ptr" : "null"; } +}; + +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")); +} + +TEST(ResultOfTest, WorksForPolymorphicFunctorsIgnoringResultType) { + Matcher<int*> matcher = ResultOf(PolymorphicFunctor(), "good ptr"); + + int n = 0; + EXPECT_TRUE(matcher.Matches(&n)); + EXPECT_FALSE(matcher.Matches(nullptr)); +} + +TEST(ResultOfTest, WorksForLambdas) { + Matcher<int> matcher = ResultOf( + [](int str_len) { + return std::string(static_cast<size_t>(str_len), 'x'); + }, + "xxx"); + EXPECT_TRUE(matcher.Matches(3)); + EXPECT_FALSE(matcher.Matches(1)); +} + +TEST(ResultOfTest, WorksForNonCopyableArguments) { + Matcher<std::unique_ptr<int>> matcher = ResultOf( + [](const std::unique_ptr<int>& str_len) { + return std::string(static_cast<size_t>(*str_len), 'x'); + }, + "xxx"); + EXPECT_TRUE(matcher.Matches(std::unique_ptr<int>(new int(3)))); + EXPECT_FALSE(matcher.Matches(std::unique_ptr<int>(new int(1)))); +} + +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 a_divider) : divider_(a_divider) {} + + // For testing using ExplainMatchResultTo() with polymorphic matchers. + template <typename T> + bool MatchAndExplain(const T& n, MatchResultListener* listener) const { + *listener << "which is " << (n % divider_) << " modulo " + << divider_; + return (n % divider_) == 0; + } + + void DescribeTo(ostream* os) const { + *os << "is divisible by " << divider_; + } + + void DescribeNegationTo(ostream* os) const { + *os << "is not divisible by " << divider_; + } + + void set_divider(int a_divider) { divider_ = a_divider; } + int divider() const { return divider_; } + + private: + int 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("which 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("which 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("which 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("which is 0 modulo 2, and which 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("which 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 a_value) : value_(a_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)); +} + +TEST(IsEmptyTest, ImplementsIsEmpty) { + vector<int> container; + EXPECT_THAT(container, IsEmpty()); + container.push_back(0); + EXPECT_THAT(container, Not(IsEmpty())); + container.push_back(1); + EXPECT_THAT(container, Not(IsEmpty())); +} + +TEST(IsEmptyTest, WorksWithString) { + std::string text; + EXPECT_THAT(text, IsEmpty()); + text = "foo"; + EXPECT_THAT(text, Not(IsEmpty())); + text = std::string("\0", 1); + EXPECT_THAT(text, Not(IsEmpty())); +} + +TEST(IsEmptyTest, CanDescribeSelf) { + Matcher<vector<int> > m = IsEmpty(); + EXPECT_EQ("is empty", Describe(m)); + EXPECT_EQ("isn't empty", DescribeNegation(m)); +} + +TEST(IsEmptyTest, ExplainsResult) { + Matcher<vector<int> > m = IsEmpty(); + vector<int> container; + EXPECT_EQ("", Explain(m, container)); + container.push_back(0); + EXPECT_EQ("whose size is 1", Explain(m, container)); +} + +TEST(IsEmptyTest, WorksWithMoveOnly) { + ContainerHelper helper; + EXPECT_CALL(helper, Call(IsEmpty())); + helper.Call({}); +} + +TEST(IsTrueTest, IsTrueIsFalse) { + EXPECT_THAT(true, IsTrue()); + EXPECT_THAT(false, IsFalse()); + EXPECT_THAT(true, Not(IsFalse())); + EXPECT_THAT(false, Not(IsTrue())); + EXPECT_THAT(0, Not(IsTrue())); + EXPECT_THAT(0, IsFalse()); + EXPECT_THAT(nullptr, Not(IsTrue())); + EXPECT_THAT(nullptr, IsFalse()); + EXPECT_THAT(-1, IsTrue()); + EXPECT_THAT(-1, Not(IsFalse())); + EXPECT_THAT(1, IsTrue()); + EXPECT_THAT(1, Not(IsFalse())); + EXPECT_THAT(2, IsTrue()); + EXPECT_THAT(2, Not(IsFalse())); + int a = 42; + EXPECT_THAT(a, IsTrue()); + EXPECT_THAT(a, Not(IsFalse())); + EXPECT_THAT(&a, IsTrue()); + EXPECT_THAT(&a, Not(IsFalse())); + EXPECT_THAT(false, Not(IsTrue())); + EXPECT_THAT(true, Not(IsFalse())); + EXPECT_THAT(std::true_type(), IsTrue()); + EXPECT_THAT(std::true_type(), Not(IsFalse())); + EXPECT_THAT(std::false_type(), IsFalse()); + EXPECT_THAT(std::false_type(), Not(IsTrue())); + EXPECT_THAT(nullptr, Not(IsTrue())); + EXPECT_THAT(nullptr, IsFalse()); + std::unique_ptr<int> null_unique; + std::unique_ptr<int> nonnull_unique(new int(0)); + EXPECT_THAT(null_unique, Not(IsTrue())); + EXPECT_THAT(null_unique, IsFalse()); + EXPECT_THAT(nonnull_unique, IsTrue()); + EXPECT_THAT(nonnull_unique, Not(IsFalse())); +} + +TEST(SizeIsTest, ImplementsSizeIs) { + vector<int> container; + EXPECT_THAT(container, SizeIs(0)); + EXPECT_THAT(container, Not(SizeIs(1))); + container.push_back(0); + EXPECT_THAT(container, Not(SizeIs(0))); + EXPECT_THAT(container, SizeIs(1)); + container.push_back(0); + EXPECT_THAT(container, Not(SizeIs(0))); + EXPECT_THAT(container, SizeIs(2)); +} + +TEST(SizeIsTest, WorksWithMap) { + map<std::string, int> container; + EXPECT_THAT(container, SizeIs(0)); + EXPECT_THAT(container, Not(SizeIs(1))); + container.insert(make_pair("foo", 1)); + EXPECT_THAT(container, Not(SizeIs(0))); + EXPECT_THAT(container, SizeIs(1)); + container.insert(make_pair("bar", 2)); + EXPECT_THAT(container, Not(SizeIs(0))); + EXPECT_THAT(container, SizeIs(2)); +} + +TEST(SizeIsTest, WorksWithReferences) { + vector<int> container; + Matcher<const vector<int>&> m = SizeIs(1); + EXPECT_THAT(container, Not(m)); + container.push_back(0); + EXPECT_THAT(container, m); +} + +TEST(SizeIsTest, WorksWithMoveOnly) { + ContainerHelper helper; + EXPECT_CALL(helper, Call(SizeIs(3))); + helper.Call(MakeUniquePtrs({1, 2, 3})); +} + +// SizeIs should work for any type that provides a size() member function. +// For example, a size_type member type should not need to be provided. +struct MinimalistCustomType { + int size() const { return 1; } +}; +TEST(SizeIsTest, WorksWithMinimalistCustomType) { + MinimalistCustomType container; + EXPECT_THAT(container, SizeIs(1)); + EXPECT_THAT(container, Not(SizeIs(0))); +} + +TEST(SizeIsTest, CanDescribeSelf) { + Matcher<vector<int> > m = SizeIs(2); + EXPECT_EQ("size is equal to 2", Describe(m)); + EXPECT_EQ("size isn't equal to 2", DescribeNegation(m)); +} + +TEST(SizeIsTest, ExplainsResult) { + Matcher<vector<int> > m1 = SizeIs(2); + Matcher<vector<int> > m2 = SizeIs(Lt(2u)); + Matcher<vector<int> > m3 = SizeIs(AnyOf(0, 3)); + Matcher<vector<int> > m4 = SizeIs(Gt(1u)); + vector<int> container; + EXPECT_EQ("whose size 0 doesn't match", Explain(m1, container)); + EXPECT_EQ("whose size 0 matches", Explain(m2, container)); + EXPECT_EQ("whose size 0 matches", Explain(m3, container)); + EXPECT_EQ("whose size 0 doesn't match", Explain(m4, container)); + container.push_back(0); + container.push_back(0); + EXPECT_EQ("whose size 2 matches", Explain(m1, container)); + EXPECT_EQ("whose size 2 doesn't match", Explain(m2, container)); + EXPECT_EQ("whose size 2 doesn't match", Explain(m3, container)); + EXPECT_EQ("whose size 2 matches", Explain(m4, container)); +} + +#if GTEST_HAS_TYPED_TEST +// Tests ContainerEq with different container types, and +// different element types. + +template <typename T> +class ContainerEqTest : public testing::Test {}; + +typedef testing::Types< + set<int>, + vector<size_t>, + multiset<size_t>, + list<int> > + ContainerEqTestTypes; + +TYPED_TEST_SUITE(ContainerEqTest, ContainerEqTestTypes); + +// Tests that the filled container is equal to itself. +TYPED_TEST(ContainerEqTest, EqualsSelf) { + static const int vals[] = {1, 1, 2, 3, 5, 8}; + TypeParam my_set(vals, vals + 6); + const Matcher<TypeParam> m = ContainerEq(my_set); + EXPECT_TRUE(m.Matches(my_set)); + EXPECT_EQ("", Explain(m, my_set)); +} + +// Tests that missing values are reported. +TYPED_TEST(ContainerEqTest, ValueMissing) { + static const int vals[] = {1, 1, 2, 3, 5, 8}; + static const int test_vals[] = {2, 1, 8, 5}; + TypeParam my_set(vals, vals + 6); + TypeParam test_set(test_vals, test_vals + 4); + const Matcher<TypeParam> m = ContainerEq(my_set); + EXPECT_FALSE(m.Matches(test_set)); + EXPECT_EQ("which doesn't have these expected elements: 3", + Explain(m, test_set)); +} + +// Tests that added values are reported. +TYPED_TEST(ContainerEqTest, ValueAdded) { + static const int vals[] = {1, 1, 2, 3, 5, 8}; + static const int test_vals[] = {1, 2, 3, 5, 8, 46}; + TypeParam my_set(vals, vals + 6); + TypeParam test_set(test_vals, test_vals + 6); + const Matcher<const TypeParam&> m = ContainerEq(my_set); + EXPECT_FALSE(m.Matches(test_set)); + EXPECT_EQ("which has these unexpected elements: 46", Explain(m, test_set)); +} + +// Tests that added and missing values are reported together. +TYPED_TEST(ContainerEqTest, ValueAddedAndRemoved) { + static const int vals[] = {1, 1, 2, 3, 5, 8}; + static const int test_vals[] = {1, 2, 3, 8, 46}; + TypeParam my_set(vals, vals + 6); + TypeParam test_set(test_vals, test_vals + 5); + const Matcher<TypeParam> m = ContainerEq(my_set); + EXPECT_FALSE(m.Matches(test_set)); + EXPECT_EQ("which has these unexpected elements: 46,\n" + "and doesn't have these expected elements: 5", + Explain(m, test_set)); +} + +// Tests duplicated value -- expect no explanation. +TYPED_TEST(ContainerEqTest, DuplicateDifference) { + static const int vals[] = {1, 1, 2, 3, 5, 8}; + static const int test_vals[] = {1, 2, 3, 5, 8}; + TypeParam my_set(vals, vals + 6); + TypeParam test_set(test_vals, test_vals + 5); + const Matcher<const TypeParam&> m = ContainerEq(my_set); + // Depending on the container, match may be true or false + // But in any case there should be no explanation. + EXPECT_EQ("", Explain(m, test_set)); +} +#endif // GTEST_HAS_TYPED_TEST + +// Tests that multiple missing values are reported. +// Using just vector here, so order is predictable. +TEST(ContainerEqExtraTest, MultipleValuesMissing) { + static const int vals[] = {1, 1, 2, 3, 5, 8}; + static const int test_vals[] = {2, 1, 5}; + vector<int> my_set(vals, vals + 6); + vector<int> test_set(test_vals, test_vals + 3); + const Matcher<vector<int> > m = ContainerEq(my_set); + EXPECT_FALSE(m.Matches(test_set)); + EXPECT_EQ("which doesn't have these expected elements: 3, 8", + Explain(m, test_set)); +} + +// Tests that added values are reported. +// Using just vector here, so order is predictable. +TEST(ContainerEqExtraTest, MultipleValuesAdded) { + static const int vals[] = {1, 1, 2, 3, 5, 8}; + static const int test_vals[] = {1, 2, 92, 3, 5, 8, 46}; + list<size_t> my_set(vals, vals + 6); + list<size_t> test_set(test_vals, test_vals + 7); + const Matcher<const list<size_t>&> m = ContainerEq(my_set); + EXPECT_FALSE(m.Matches(test_set)); + EXPECT_EQ("which has these unexpected elements: 92, 46", + Explain(m, test_set)); +} + +// Tests that added and missing values are reported together. +TEST(ContainerEqExtraTest, MultipleValuesAddedAndRemoved) { + static const int vals[] = {1, 1, 2, 3, 5, 8}; + static const int test_vals[] = {1, 2, 3, 92, 46}; + list<size_t> my_set(vals, vals + 6); + list<size_t> test_set(test_vals, test_vals + 5); + const Matcher<const list<size_t> > m = ContainerEq(my_set); + EXPECT_FALSE(m.Matches(test_set)); + EXPECT_EQ("which has these unexpected elements: 92, 46,\n" + "and doesn't have these expected elements: 5, 8", + Explain(m, test_set)); +} + +// Tests to see that duplicate elements are detected, +// but (as above) not reported in the explanation. +TEST(ContainerEqExtraTest, MultiSetOfIntDuplicateDifference) { + static const int vals[] = {1, 1, 2, 3, 5, 8}; + static const int test_vals[] = {1, 2, 3, 5, 8}; + vector<int> my_set(vals, vals + 6); + vector<int> test_set(test_vals, test_vals + 5); + const Matcher<vector<int> > m = ContainerEq(my_set); + EXPECT_TRUE(m.Matches(my_set)); + EXPECT_FALSE(m.Matches(test_set)); + // There is nothing to report when both sets contain all the same values. + EXPECT_EQ("", Explain(m, test_set)); +} + +// Tests that ContainerEq works for non-trivial associative containers, +// like maps. +TEST(ContainerEqExtraTest, WorksForMaps) { + map<int, std::string> my_map; + my_map[0] = "a"; + my_map[1] = "b"; + + map<int, std::string> test_map; + test_map[0] = "aa"; + test_map[1] = "b"; + + const Matcher<const map<int, std::string>&> m = ContainerEq(my_map); + EXPECT_TRUE(m.Matches(my_map)); + EXPECT_FALSE(m.Matches(test_map)); + + EXPECT_EQ("which has these unexpected elements: (0, \"aa\"),\n" + "and doesn't have these expected elements: (0, \"a\")", + Explain(m, test_map)); +} + +TEST(ContainerEqExtraTest, WorksForNativeArray) { + int a1[] = {1, 2, 3}; + int a2[] = {1, 2, 3}; + int b[] = {1, 2, 4}; + + EXPECT_THAT(a1, ContainerEq(a2)); + EXPECT_THAT(a1, Not(ContainerEq(b))); +} + +TEST(ContainerEqExtraTest, WorksForTwoDimensionalNativeArray) { + const char a1[][3] = {"hi", "lo"}; + const char a2[][3] = {"hi", "lo"}; + const char b[][3] = {"lo", "hi"}; + + // Tests using ContainerEq() in the first dimension. + EXPECT_THAT(a1, ContainerEq(a2)); + EXPECT_THAT(a1, Not(ContainerEq(b))); + + // Tests using ContainerEq() in the second dimension. + EXPECT_THAT(a1, ElementsAre(ContainerEq(a2[0]), ContainerEq(a2[1]))); + EXPECT_THAT(a1, ElementsAre(Not(ContainerEq(b[0])), ContainerEq(a2[1]))); +} + +TEST(ContainerEqExtraTest, WorksForNativeArrayAsTuple) { + const int a1[] = {1, 2, 3}; + const int a2[] = {1, 2, 3}; + const int b[] = {1, 2, 3, 4}; + + const int* const p1 = a1; + EXPECT_THAT(std::make_tuple(p1, 3), ContainerEq(a2)); + EXPECT_THAT(std::make_tuple(p1, 3), Not(ContainerEq(b))); + + const int c[] = {1, 3, 2}; + EXPECT_THAT(std::make_tuple(p1, 3), Not(ContainerEq(c))); +} + +TEST(ContainerEqExtraTest, CopiesNativeArrayParameter) { + std::string a1[][3] = { + {"hi", "hello", "ciao"}, + {"bye", "see you", "ciao"} + }; + + std::string a2[][3] = { + {"hi", "hello", "ciao"}, + {"bye", "see you", "ciao"} + }; + + const Matcher<const std::string(&)[2][3]> m = ContainerEq(a2); + EXPECT_THAT(a1, m); + + a2[0][0] = "ha"; + EXPECT_THAT(a1, m); +} + +TEST(WhenSortedByTest, WorksForEmptyContainer) { + const vector<int> numbers; + EXPECT_THAT(numbers, WhenSortedBy(less<int>(), ElementsAre())); + EXPECT_THAT(numbers, Not(WhenSortedBy(less<int>(), ElementsAre(1)))); +} + +TEST(WhenSortedByTest, WorksForNonEmptyContainer) { + vector<unsigned> numbers; + numbers.push_back(3); + numbers.push_back(1); + numbers.push_back(2); + numbers.push_back(2); + EXPECT_THAT(numbers, WhenSortedBy(greater<unsigned>(), + ElementsAre(3, 2, 2, 1))); + EXPECT_THAT(numbers, Not(WhenSortedBy(greater<unsigned>(), + ElementsAre(1, 2, 2, 3)))); +} + +TEST(WhenSortedByTest, WorksForNonVectorContainer) { + list<std::string> words; + words.push_back("say"); + words.push_back("hello"); + words.push_back("world"); + EXPECT_THAT(words, WhenSortedBy(less<std::string>(), + ElementsAre("hello", "say", "world"))); + EXPECT_THAT(words, Not(WhenSortedBy(less<std::string>(), + ElementsAre("say", "hello", "world")))); +} + +TEST(WhenSortedByTest, WorksForNativeArray) { + const int numbers[] = {1, 3, 2, 4}; + const int sorted_numbers[] = {1, 2, 3, 4}; + EXPECT_THAT(numbers, WhenSortedBy(less<int>(), ElementsAre(1, 2, 3, 4))); + EXPECT_THAT(numbers, WhenSortedBy(less<int>(), + ElementsAreArray(sorted_numbers))); + EXPECT_THAT(numbers, Not(WhenSortedBy(less<int>(), ElementsAre(1, 3, 2, 4)))); +} + +TEST(WhenSortedByTest, CanDescribeSelf) { + const Matcher<vector<int> > m = WhenSortedBy(less<int>(), ElementsAre(1, 2)); + EXPECT_EQ("(when sorted) has 2 elements where\n" + "element #0 is equal to 1,\n" + "element #1 is equal to 2", + Describe(m)); + EXPECT_EQ("(when sorted) doesn't have 2 elements, or\n" + "element #0 isn't equal to 1, or\n" + "element #1 isn't equal to 2", + DescribeNegation(m)); +} + +TEST(WhenSortedByTest, ExplainsMatchResult) { + const int a[] = {2, 1}; + EXPECT_EQ("which is { 1, 2 } when sorted, whose element #0 doesn't match", + Explain(WhenSortedBy(less<int>(), ElementsAre(2, 3)), a)); + EXPECT_EQ("which is { 1, 2 } when sorted", + Explain(WhenSortedBy(less<int>(), ElementsAre(1, 2)), a)); +} + +// WhenSorted() is a simple wrapper on WhenSortedBy(). Hence we don't +// need to test it as exhaustively as we test the latter. + +TEST(WhenSortedTest, WorksForEmptyContainer) { + const vector<int> numbers; + EXPECT_THAT(numbers, WhenSorted(ElementsAre())); + EXPECT_THAT(numbers, Not(WhenSorted(ElementsAre(1)))); +} + +TEST(WhenSortedTest, WorksForNonEmptyContainer) { + list<std::string> words; + words.push_back("3"); + words.push_back("1"); + words.push_back("2"); + words.push_back("2"); + EXPECT_THAT(words, WhenSorted(ElementsAre("1", "2", "2", "3"))); + EXPECT_THAT(words, Not(WhenSorted(ElementsAre("3", "1", "2", "2")))); +} + +TEST(WhenSortedTest, WorksForMapTypes) { + map<std::string, int> word_counts; + word_counts["and"] = 1; + word_counts["the"] = 1; + word_counts["buffalo"] = 2; + EXPECT_THAT(word_counts, + WhenSorted(ElementsAre(Pair("and", 1), Pair("buffalo", 2), + Pair("the", 1)))); + EXPECT_THAT(word_counts, + Not(WhenSorted(ElementsAre(Pair("and", 1), Pair("the", 1), + Pair("buffalo", 2))))); +} + +TEST(WhenSortedTest, WorksForMultiMapTypes) { + multimap<int, int> ifib; + ifib.insert(make_pair(8, 6)); + ifib.insert(make_pair(2, 3)); + ifib.insert(make_pair(1, 1)); + ifib.insert(make_pair(3, 4)); + ifib.insert(make_pair(1, 2)); + ifib.insert(make_pair(5, 5)); + EXPECT_THAT(ifib, WhenSorted(ElementsAre(Pair(1, 1), + Pair(1, 2), + Pair(2, 3), + Pair(3, 4), + Pair(5, 5), + Pair(8, 6)))); + EXPECT_THAT(ifib, Not(WhenSorted(ElementsAre(Pair(8, 6), + Pair(2, 3), + Pair(1, 1), + Pair(3, 4), + Pair(1, 2), + Pair(5, 5))))); +} + +TEST(WhenSortedTest, WorksForPolymorphicMatcher) { + std::deque<int> d; + d.push_back(2); + d.push_back(1); + EXPECT_THAT(d, WhenSorted(ElementsAre(1, 2))); + EXPECT_THAT(d, Not(WhenSorted(ElementsAre(2, 1)))); +} + +TEST(WhenSortedTest, WorksForVectorConstRefMatcher) { + std::deque<int> d; + d.push_back(2); + d.push_back(1); + Matcher<const std::vector<int>&> vector_match = ElementsAre(1, 2); + EXPECT_THAT(d, WhenSorted(vector_match)); + Matcher<const std::vector<int>&> not_vector_match = ElementsAre(2, 1); + EXPECT_THAT(d, Not(WhenSorted(not_vector_match))); +} + +// Deliberately bare pseudo-container. +// Offers only begin() and end() accessors, yielding InputIterator. +template <typename T> +class Streamlike { + private: + class ConstIter; + public: + typedef ConstIter const_iterator; + typedef T value_type; + + template <typename InIter> + Streamlike(InIter first, InIter last) : remainder_(first, last) {} + + const_iterator begin() const { + return const_iterator(this, remainder_.begin()); + } + const_iterator end() const { + return const_iterator(this, remainder_.end()); + } + + private: + class ConstIter : public std::iterator<std::input_iterator_tag, + value_type, + ptrdiff_t, + const value_type*, + const value_type&> { + public: + ConstIter(const Streamlike* s, + typename std::list<value_type>::iterator pos) + : s_(s), pos_(pos) {} + + const value_type& operator*() const { return *pos_; } + const value_type* operator->() const { return &*pos_; } + ConstIter& operator++() { + s_->remainder_.erase(pos_++); + return *this; + } + + // *iter++ is required to work (see std::istreambuf_iterator). + // (void)iter++ is also required to work. + class PostIncrProxy { + public: + explicit PostIncrProxy(const value_type& value) : value_(value) {} + value_type operator*() const { return value_; } + private: + value_type value_; + }; + PostIncrProxy operator++(int) { + PostIncrProxy proxy(**this); + ++(*this); + return proxy; + } + + friend bool operator==(const ConstIter& a, const ConstIter& b) { + return a.s_ == b.s_ && a.pos_ == b.pos_; + } + friend bool operator!=(const ConstIter& a, const ConstIter& b) { + return !(a == b); + } + + private: + const Streamlike* s_; + typename std::list<value_type>::iterator pos_; + }; + + friend std::ostream& operator<<(std::ostream& os, const Streamlike& s) { + os << "["; + typedef typename std::list<value_type>::const_iterator Iter; + const char* sep = ""; + for (Iter it = s.remainder_.begin(); it != s.remainder_.end(); ++it) { + os << sep << *it; + sep = ","; + } + os << "]"; + return os; + } + + mutable std::list<value_type> remainder_; // modified by iteration +}; + +TEST(StreamlikeTest, Iteration) { + const int a[5] = {2, 1, 4, 5, 3}; + Streamlike<int> s(a, a + 5); + Streamlike<int>::const_iterator it = s.begin(); + const int* ip = a; + while (it != s.end()) { + SCOPED_TRACE(ip - a); + EXPECT_EQ(*ip++, *it++); + } +} + +TEST(BeginEndDistanceIsTest, WorksWithForwardList) { + std::forward_list<int> container; + EXPECT_THAT(container, BeginEndDistanceIs(0)); + EXPECT_THAT(container, Not(BeginEndDistanceIs(1))); + container.push_front(0); + EXPECT_THAT(container, Not(BeginEndDistanceIs(0))); + EXPECT_THAT(container, BeginEndDistanceIs(1)); + container.push_front(0); + EXPECT_THAT(container, Not(BeginEndDistanceIs(0))); + EXPECT_THAT(container, BeginEndDistanceIs(2)); +} + +TEST(BeginEndDistanceIsTest, WorksWithNonStdList) { + const int a[5] = {1, 2, 3, 4, 5}; + Streamlike<int> s(a, a + 5); + EXPECT_THAT(s, BeginEndDistanceIs(5)); +} + +TEST(BeginEndDistanceIsTest, CanDescribeSelf) { + Matcher<vector<int> > m = BeginEndDistanceIs(2); + EXPECT_EQ("distance between begin() and end() is equal to 2", Describe(m)); + EXPECT_EQ("distance between begin() and end() isn't equal to 2", + DescribeNegation(m)); +} + +TEST(BeginEndDistanceIsTest, WorksWithMoveOnly) { + ContainerHelper helper; + EXPECT_CALL(helper, Call(BeginEndDistanceIs(2))); + helper.Call(MakeUniquePtrs({1, 2})); +} + +TEST(BeginEndDistanceIsTest, ExplainsResult) { + Matcher<vector<int> > m1 = BeginEndDistanceIs(2); + Matcher<vector<int> > m2 = BeginEndDistanceIs(Lt(2)); + Matcher<vector<int> > m3 = BeginEndDistanceIs(AnyOf(0, 3)); + Matcher<vector<int> > m4 = BeginEndDistanceIs(GreaterThan(1)); + vector<int> container; + EXPECT_EQ("whose distance between begin() and end() 0 doesn't match", + Explain(m1, container)); + EXPECT_EQ("whose distance between begin() and end() 0 matches", + Explain(m2, container)); + EXPECT_EQ("whose distance between begin() and end() 0 matches", + Explain(m3, container)); + EXPECT_EQ( + "whose distance between begin() and end() 0 doesn't match, which is 1 " + "less than 1", + Explain(m4, container)); + container.push_back(0); + container.push_back(0); + EXPECT_EQ("whose distance between begin() and end() 2 matches", + Explain(m1, container)); + EXPECT_EQ("whose distance between begin() and end() 2 doesn't match", + Explain(m2, container)); + EXPECT_EQ("whose distance between begin() and end() 2 doesn't match", + Explain(m3, container)); + EXPECT_EQ( + "whose distance between begin() and end() 2 matches, which is 1 more " + "than 1", + Explain(m4, container)); +} + +TEST(WhenSortedTest, WorksForStreamlike) { + // Streamlike 'container' provides only minimal iterator support. + // Its iterators are tagged with input_iterator_tag. + const int a[5] = {2, 1, 4, 5, 3}; + Streamlike<int> s(std::begin(a), std::end(a)); + EXPECT_THAT(s, WhenSorted(ElementsAre(1, 2, 3, 4, 5))); + EXPECT_THAT(s, Not(WhenSorted(ElementsAre(2, 1, 4, 5, 3)))); +} + +TEST(WhenSortedTest, WorksForVectorConstRefMatcherOnStreamlike) { + const int a[] = {2, 1, 4, 5, 3}; + Streamlike<int> s(std::begin(a), std::end(a)); + Matcher<const std::vector<int>&> vector_match = ElementsAre(1, 2, 3, 4, 5); + EXPECT_THAT(s, WhenSorted(vector_match)); + EXPECT_THAT(s, Not(WhenSorted(ElementsAre(2, 1, 4, 5, 3)))); +} + +TEST(IsSupersetOfTest, WorksForNativeArray) { + const int subset[] = {1, 4}; + const int superset[] = {1, 2, 4}; + const int disjoint[] = {1, 0, 3}; + EXPECT_THAT(subset, IsSupersetOf(subset)); + EXPECT_THAT(subset, Not(IsSupersetOf(superset))); + EXPECT_THAT(superset, IsSupersetOf(subset)); + EXPECT_THAT(subset, Not(IsSupersetOf(disjoint))); + EXPECT_THAT(disjoint, Not(IsSupersetOf(subset))); +} + +TEST(IsSupersetOfTest, WorksWithDuplicates) { + const int not_enough[] = {1, 2}; + const int enough[] = {1, 1, 2}; + const int expected[] = {1, 1}; + EXPECT_THAT(not_enough, Not(IsSupersetOf(expected))); + EXPECT_THAT(enough, IsSupersetOf(expected)); +} + +TEST(IsSupersetOfTest, WorksForEmpty) { + vector<int> numbers; + vector<int> expected; + EXPECT_THAT(numbers, IsSupersetOf(expected)); + expected.push_back(1); + EXPECT_THAT(numbers, Not(IsSupersetOf(expected))); + expected.clear(); + numbers.push_back(1); + numbers.push_back(2); + EXPECT_THAT(numbers, IsSupersetOf(expected)); + expected.push_back(1); + EXPECT_THAT(numbers, IsSupersetOf(expected)); + expected.push_back(2); + EXPECT_THAT(numbers, IsSupersetOf(expected)); + expected.push_back(3); + EXPECT_THAT(numbers, Not(IsSupersetOf(expected))); +} + +TEST(IsSupersetOfTest, WorksForStreamlike) { + const int a[5] = {1, 2, 3, 4, 5}; + Streamlike<int> s(std::begin(a), std::end(a)); + + vector<int> expected; + expected.push_back(1); + expected.push_back(2); + expected.push_back(5); + EXPECT_THAT(s, IsSupersetOf(expected)); + + expected.push_back(0); + EXPECT_THAT(s, Not(IsSupersetOf(expected))); +} + +TEST(IsSupersetOfTest, TakesStlContainer) { + const int actual[] = {3, 1, 2}; + + ::std::list<int> expected; + expected.push_back(1); + expected.push_back(3); + EXPECT_THAT(actual, IsSupersetOf(expected)); + + expected.push_back(4); + EXPECT_THAT(actual, Not(IsSupersetOf(expected))); +} + +TEST(IsSupersetOfTest, Describe) { + typedef std::vector<int> IntVec; + IntVec expected; + expected.push_back(111); + expected.push_back(222); + expected.push_back(333); + EXPECT_THAT( + Describe<IntVec>(IsSupersetOf(expected)), + Eq("a surjection from elements to requirements exists such that:\n" + " - an element is equal to 111\n" + " - an element is equal to 222\n" + " - an element is equal to 333")); +} + +TEST(IsSupersetOfTest, DescribeNegation) { + typedef std::vector<int> IntVec; + IntVec expected; + expected.push_back(111); + expected.push_back(222); + expected.push_back(333); + EXPECT_THAT( + DescribeNegation<IntVec>(IsSupersetOf(expected)), + Eq("no surjection from elements to requirements exists such that:\n" + " - an element is equal to 111\n" + " - an element is equal to 222\n" + " - an element is equal to 333")); +} + +TEST(IsSupersetOfTest, MatchAndExplain) { + std::vector<int> v; + v.push_back(2); + v.push_back(3); + std::vector<int> expected; + expected.push_back(1); + expected.push_back(2); + StringMatchResultListener listener; + ASSERT_FALSE(ExplainMatchResult(IsSupersetOf(expected), v, &listener)) + << listener.str(); + EXPECT_THAT(listener.str(), + Eq("where the following matchers don't match any elements:\n" + "matcher #0: is equal to 1")); + + v.push_back(1); + listener.Clear(); + ASSERT_TRUE(ExplainMatchResult(IsSupersetOf(expected), v, &listener)) + << listener.str(); + EXPECT_THAT(listener.str(), Eq("where:\n" + " - element #0 is matched by matcher #1,\n" + " - element #2 is matched by matcher #0")); +} + +TEST(IsSupersetOfTest, WorksForRhsInitializerList) { + const int numbers[] = {1, 3, 6, 2, 4, 5}; + EXPECT_THAT(numbers, IsSupersetOf({1, 2})); + EXPECT_THAT(numbers, Not(IsSupersetOf({3, 0}))); +} + +TEST(IsSupersetOfTest, WorksWithMoveOnly) { + ContainerHelper helper; + EXPECT_CALL(helper, Call(IsSupersetOf({Pointee(1)}))); + helper.Call(MakeUniquePtrs({1, 2})); + EXPECT_CALL(helper, Call(Not(IsSupersetOf({Pointee(1), Pointee(2)})))); + helper.Call(MakeUniquePtrs({2})); +} + +TEST(IsSubsetOfTest, WorksForNativeArray) { + const int subset[] = {1, 4}; + const int superset[] = {1, 2, 4}; + const int disjoint[] = {1, 0, 3}; + EXPECT_THAT(subset, IsSubsetOf(subset)); + EXPECT_THAT(subset, IsSubsetOf(superset)); + EXPECT_THAT(superset, Not(IsSubsetOf(subset))); + EXPECT_THAT(subset, Not(IsSubsetOf(disjoint))); + EXPECT_THAT(disjoint, Not(IsSubsetOf(subset))); +} + +TEST(IsSubsetOfTest, WorksWithDuplicates) { + const int not_enough[] = {1, 2}; + const int enough[] = {1, 1, 2}; + const int actual[] = {1, 1}; + EXPECT_THAT(actual, Not(IsSubsetOf(not_enough))); + EXPECT_THAT(actual, IsSubsetOf(enough)); +} + +TEST(IsSubsetOfTest, WorksForEmpty) { + vector<int> numbers; + vector<int> expected; + EXPECT_THAT(numbers, IsSubsetOf(expected)); + expected.push_back(1); + EXPECT_THAT(numbers, IsSubsetOf(expected)); + expected.clear(); + numbers.push_back(1); + numbers.push_back(2); + EXPECT_THAT(numbers, Not(IsSubsetOf(expected))); + expected.push_back(1); + EXPECT_THAT(numbers, Not(IsSubsetOf(expected))); + expected.push_back(2); + EXPECT_THAT(numbers, IsSubsetOf(expected)); + expected.push_back(3); + EXPECT_THAT(numbers, IsSubsetOf(expected)); +} + +TEST(IsSubsetOfTest, WorksForStreamlike) { + const int a[5] = {1, 2}; + Streamlike<int> s(std::begin(a), std::end(a)); + + vector<int> expected; + expected.push_back(1); + EXPECT_THAT(s, Not(IsSubsetOf(expected))); + expected.push_back(2); + expected.push_back(5); + EXPECT_THAT(s, IsSubsetOf(expected)); +} + +TEST(IsSubsetOfTest, TakesStlContainer) { + const int actual[] = {3, 1, 2}; + + ::std::list<int> expected; + expected.push_back(1); + expected.push_back(3); + EXPECT_THAT(actual, Not(IsSubsetOf(expected))); + + expected.push_back(2); + expected.push_back(4); + EXPECT_THAT(actual, IsSubsetOf(expected)); +} + +TEST(IsSubsetOfTest, Describe) { + typedef std::vector<int> IntVec; + IntVec expected; + expected.push_back(111); + expected.push_back(222); + expected.push_back(333); + + EXPECT_THAT( + Describe<IntVec>(IsSubsetOf(expected)), + Eq("an injection from elements to requirements exists such that:\n" + " - an element is equal to 111\n" + " - an element is equal to 222\n" + " - an element is equal to 333")); +} + +TEST(IsSubsetOfTest, DescribeNegation) { + typedef std::vector<int> IntVec; + IntVec expected; + expected.push_back(111); + expected.push_back(222); + expected.push_back(333); + EXPECT_THAT( + DescribeNegation<IntVec>(IsSubsetOf(expected)), + Eq("no injection from elements to requirements exists such that:\n" + " - an element is equal to 111\n" + " - an element is equal to 222\n" + " - an element is equal to 333")); +} + +TEST(IsSubsetOfTest, MatchAndExplain) { + std::vector<int> v; + v.push_back(2); + v.push_back(3); + std::vector<int> expected; + expected.push_back(1); + expected.push_back(2); + StringMatchResultListener listener; + ASSERT_FALSE(ExplainMatchResult(IsSubsetOf(expected), v, &listener)) + << listener.str(); + EXPECT_THAT(listener.str(), + Eq("where the following elements don't match any matchers:\n" + "element #1: 3")); + + expected.push_back(3); + listener.Clear(); + ASSERT_TRUE(ExplainMatchResult(IsSubsetOf(expected), v, &listener)) + << listener.str(); + EXPECT_THAT(listener.str(), Eq("where:\n" + " - element #0 is matched by matcher #1,\n" + " - element #1 is matched by matcher #2")); +} + +TEST(IsSubsetOfTest, WorksForRhsInitializerList) { + const int numbers[] = {1, 2, 3}; + EXPECT_THAT(numbers, IsSubsetOf({1, 2, 3, 4})); + EXPECT_THAT(numbers, Not(IsSubsetOf({1, 2}))); +} + +TEST(IsSubsetOfTest, WorksWithMoveOnly) { + ContainerHelper helper; + EXPECT_CALL(helper, Call(IsSubsetOf({Pointee(1), Pointee(2)}))); + helper.Call(MakeUniquePtrs({1})); + EXPECT_CALL(helper, Call(Not(IsSubsetOf({Pointee(1)})))); + helper.Call(MakeUniquePtrs({2})); +} + +// Tests using ElementsAre() and ElementsAreArray() with stream-like +// "containers". + +TEST(ElemensAreStreamTest, WorksForStreamlike) { + const int a[5] = {1, 2, 3, 4, 5}; + Streamlike<int> s(std::begin(a), std::end(a)); + EXPECT_THAT(s, ElementsAre(1, 2, 3, 4, 5)); + EXPECT_THAT(s, Not(ElementsAre(2, 1, 4, 5, 3))); +} + +TEST(ElemensAreArrayStreamTest, WorksForStreamlike) { + const int a[5] = {1, 2, 3, 4, 5}; + Streamlike<int> s(std::begin(a), std::end(a)); + + vector<int> expected; + expected.push_back(1); + expected.push_back(2); + expected.push_back(3); + expected.push_back(4); + expected.push_back(5); + EXPECT_THAT(s, ElementsAreArray(expected)); + + expected[3] = 0; + EXPECT_THAT(s, Not(ElementsAreArray(expected))); +} + +TEST(ElementsAreTest, WorksWithUncopyable) { + Uncopyable objs[2]; + objs[0].set_value(-3); + objs[1].set_value(1); + EXPECT_THAT(objs, ElementsAre(UncopyableIs(-3), Truly(ValueIsPositive))); +} + +TEST(ElementsAreTest, WorksWithMoveOnly) { + ContainerHelper helper; + EXPECT_CALL(helper, Call(ElementsAre(Pointee(1), Pointee(2)))); + helper.Call(MakeUniquePtrs({1, 2})); + + EXPECT_CALL(helper, Call(ElementsAreArray({Pointee(3), Pointee(4)}))); + helper.Call(MakeUniquePtrs({3, 4})); +} + +TEST(ElementsAreTest, TakesStlContainer) { + const int actual[] = {3, 1, 2}; + + ::std::list<int> expected; + expected.push_back(3); + expected.push_back(1); + expected.push_back(2); + EXPECT_THAT(actual, ElementsAreArray(expected)); + + expected.push_back(4); + EXPECT_THAT(actual, Not(ElementsAreArray(expected))); +} + +// Tests for UnorderedElementsAreArray() + +TEST(UnorderedElementsAreArrayTest, SucceedsWhenExpected) { + const int a[] = {0, 1, 2, 3, 4}; + std::vector<int> s(std::begin(a), std::end(a)); + do { + StringMatchResultListener listener; + EXPECT_TRUE(ExplainMatchResult(UnorderedElementsAreArray(a), + s, &listener)) << listener.str(); + } while (std::next_permutation(s.begin(), s.end())); +} + +TEST(UnorderedElementsAreArrayTest, VectorBool) { + const bool a[] = {0, 1, 0, 1, 1}; + const bool b[] = {1, 0, 1, 1, 0}; + std::vector<bool> expected(std::begin(a), std::end(a)); + std::vector<bool> actual(std::begin(b), std::end(b)); + StringMatchResultListener listener; + EXPECT_TRUE(ExplainMatchResult(UnorderedElementsAreArray(expected), + actual, &listener)) << listener.str(); +} + +TEST(UnorderedElementsAreArrayTest, WorksForStreamlike) { + // Streamlike 'container' provides only minimal iterator support. + // Its iterators are tagged with input_iterator_tag, and it has no + // size() or empty() methods. + const int a[5] = {2, 1, 4, 5, 3}; + Streamlike<int> s(std::begin(a), std::end(a)); + + ::std::vector<int> expected; + expected.push_back(1); + expected.push_back(2); + expected.push_back(3); + expected.push_back(4); + expected.push_back(5); + EXPECT_THAT(s, UnorderedElementsAreArray(expected)); + + expected.push_back(6); + EXPECT_THAT(s, Not(UnorderedElementsAreArray(expected))); +} + +TEST(UnorderedElementsAreArrayTest, TakesStlContainer) { + const int actual[] = {3, 1, 2}; + + ::std::list<int> expected; + expected.push_back(1); + expected.push_back(2); + expected.push_back(3); + EXPECT_THAT(actual, UnorderedElementsAreArray(expected)); + + expected.push_back(4); + EXPECT_THAT(actual, Not(UnorderedElementsAreArray(expected))); +} + + +TEST(UnorderedElementsAreArrayTest, TakesInitializerList) { + const int a[5] = {2, 1, 4, 5, 3}; + EXPECT_THAT(a, UnorderedElementsAreArray({1, 2, 3, 4, 5})); + EXPECT_THAT(a, Not(UnorderedElementsAreArray({1, 2, 3, 4, 6}))); +} + +TEST(UnorderedElementsAreArrayTest, TakesInitializerListOfCStrings) { + const std::string a[5] = {"a", "b", "c", "d", "e"}; + EXPECT_THAT(a, UnorderedElementsAreArray({"a", "b", "c", "d", "e"})); + EXPECT_THAT(a, Not(UnorderedElementsAreArray({"a", "b", "c", "d", "ef"}))); +} + +TEST(UnorderedElementsAreArrayTest, TakesInitializerListOfSameTypedMatchers) { + const int a[5] = {2, 1, 4, 5, 3}; + EXPECT_THAT(a, UnorderedElementsAreArray( + {Eq(1), Eq(2), Eq(3), Eq(4), Eq(5)})); + EXPECT_THAT(a, Not(UnorderedElementsAreArray( + {Eq(1), Eq(2), Eq(3), Eq(4), Eq(6)}))); +} + +TEST(UnorderedElementsAreArrayTest, + TakesInitializerListOfDifferentTypedMatchers) { + const int a[5] = {2, 1, 4, 5, 3}; + // The compiler cannot infer the type of the initializer list if its + // elements have different types. We must explicitly specify the + // unified element type in this case. + EXPECT_THAT(a, UnorderedElementsAreArray<Matcher<int> >( + {Eq(1), Ne(-2), Ge(3), Le(4), Eq(5)})); + EXPECT_THAT(a, Not(UnorderedElementsAreArray<Matcher<int> >( + {Eq(1), Ne(-2), Ge(3), Le(4), Eq(6)}))); +} + + +TEST(UnorderedElementsAreArrayTest, WorksWithMoveOnly) { + ContainerHelper helper; + EXPECT_CALL(helper, + Call(UnorderedElementsAreArray({Pointee(1), Pointee(2)}))); + helper.Call(MakeUniquePtrs({2, 1})); +} + +class UnorderedElementsAreTest : public testing::Test { + protected: + typedef std::vector<int> IntVec; +}; + +TEST_F(UnorderedElementsAreTest, WorksWithUncopyable) { + Uncopyable objs[2]; + objs[0].set_value(-3); + objs[1].set_value(1); + EXPECT_THAT(objs, + UnorderedElementsAre(Truly(ValueIsPositive), UncopyableIs(-3))); +} + +TEST_F(UnorderedElementsAreTest, SucceedsWhenExpected) { + const int a[] = {1, 2, 3}; + std::vector<int> s(std::begin(a), std::end(a)); + do { + StringMatchResultListener listener; + EXPECT_TRUE(ExplainMatchResult(UnorderedElementsAre(1, 2, 3), + s, &listener)) << listener.str(); + } while (std::next_permutation(s.begin(), s.end())); +} + +TEST_F(UnorderedElementsAreTest, FailsWhenAnElementMatchesNoMatcher) { + const int a[] = {1, 2, 3}; + std::vector<int> s(std::begin(a), std::end(a)); + std::vector<Matcher<int> > mv; + mv.push_back(1); + mv.push_back(2); + mv.push_back(2); + // The element with value '3' matches nothing: fail fast. + StringMatchResultListener listener; + EXPECT_FALSE(ExplainMatchResult(UnorderedElementsAreArray(mv), + s, &listener)) << listener.str(); +} + +TEST_F(UnorderedElementsAreTest, WorksForStreamlike) { + // Streamlike 'container' provides only minimal iterator support. + // Its iterators are tagged with input_iterator_tag, and it has no + // size() or empty() methods. + const int a[5] = {2, 1, 4, 5, 3}; + Streamlike<int> s(std::begin(a), std::end(a)); + + EXPECT_THAT(s, UnorderedElementsAre(1, 2, 3, 4, 5)); + EXPECT_THAT(s, Not(UnorderedElementsAre(2, 2, 3, 4, 5))); +} + +TEST_F(UnorderedElementsAreTest, WorksWithMoveOnly) { + ContainerHelper helper; + EXPECT_CALL(helper, Call(UnorderedElementsAre(Pointee(1), Pointee(2)))); + helper.Call(MakeUniquePtrs({2, 1})); +} + +// One naive implementation of the matcher runs in O(N!) time, which is too +// slow for many real-world inputs. This test shows that our matcher can match +// 100 inputs very quickly (a few milliseconds). An O(100!) is 10^158 +// iterations and obviously effectively incomputable. +// [ RUN ] UnorderedElementsAreTest.Performance +// [ OK ] UnorderedElementsAreTest.Performance (4 ms) +TEST_F(UnorderedElementsAreTest, Performance) { + std::vector<int> s; + std::vector<Matcher<int> > mv; + for (int i = 0; i < 100; ++i) { + s.push_back(i); + mv.push_back(_); + } + mv[50] = Eq(0); + StringMatchResultListener listener; + EXPECT_TRUE(ExplainMatchResult(UnorderedElementsAreArray(mv), + s, &listener)) << listener.str(); +} + +// Another variant of 'Performance' with similar expectations. +// [ RUN ] UnorderedElementsAreTest.PerformanceHalfStrict +// [ OK ] UnorderedElementsAreTest.PerformanceHalfStrict (4 ms) +TEST_F(UnorderedElementsAreTest, PerformanceHalfStrict) { + std::vector<int> s; + std::vector<Matcher<int> > mv; + for (int i = 0; i < 100; ++i) { + s.push_back(i); + if (i & 1) { + mv.push_back(_); + } else { + mv.push_back(i); + } + } + StringMatchResultListener listener; + EXPECT_TRUE(ExplainMatchResult(UnorderedElementsAreArray(mv), + s, &listener)) << listener.str(); +} + +TEST_F(UnorderedElementsAreTest, FailMessageCountWrong) { + std::vector<int> v; + v.push_back(4); + StringMatchResultListener listener; + EXPECT_FALSE(ExplainMatchResult(UnorderedElementsAre(1, 2, 3), + v, &listener)) << listener.str(); + EXPECT_THAT(listener.str(), Eq("which has 1 element")); +} + +TEST_F(UnorderedElementsAreTest, FailMessageCountWrongZero) { + std::vector<int> v; + StringMatchResultListener listener; + EXPECT_FALSE(ExplainMatchResult(UnorderedElementsAre(1, 2, 3), + v, &listener)) << listener.str(); + EXPECT_THAT(listener.str(), Eq("")); +} + +TEST_F(UnorderedElementsAreTest, FailMessageUnmatchedMatchers) { + std::vector<int> v; + v.push_back(1); + v.push_back(1); + StringMatchResultListener listener; + EXPECT_FALSE(ExplainMatchResult(UnorderedElementsAre(1, 2), + v, &listener)) << listener.str(); + EXPECT_THAT( + listener.str(), + Eq("where the following matchers don't match any elements:\n" + "matcher #1: is equal to 2")); +} + +TEST_F(UnorderedElementsAreTest, FailMessageUnmatchedElements) { + std::vector<int> v; + v.push_back(1); + v.push_back(2); + StringMatchResultListener listener; + EXPECT_FALSE(ExplainMatchResult(UnorderedElementsAre(1, 1), + v, &listener)) << listener.str(); + EXPECT_THAT( + listener.str(), + Eq("where the following elements don't match any matchers:\n" + "element #1: 2")); +} + +TEST_F(UnorderedElementsAreTest, FailMessageUnmatchedMatcherAndElement) { + std::vector<int> v; + v.push_back(2); + v.push_back(3); + StringMatchResultListener listener; + EXPECT_FALSE(ExplainMatchResult(UnorderedElementsAre(1, 2), + v, &listener)) << listener.str(); + EXPECT_THAT( + listener.str(), + Eq("where" + " the following matchers don't match any elements:\n" + "matcher #0: is equal to 1\n" + "and" + " where" + " the following elements don't match any matchers:\n" + "element #1: 3")); +} + +// Test helper for formatting element, matcher index pairs in expectations. +static std::string EMString(int element, int matcher) { + stringstream ss; + ss << "(element #" << element << ", matcher #" << matcher << ")"; + return ss.str(); +} + +TEST_F(UnorderedElementsAreTest, FailMessageImperfectMatchOnly) { + // A situation where all elements and matchers have a match + // associated with them, but the max matching is not perfect. + std::vector<std::string> v; + v.push_back("a"); + v.push_back("b"); + v.push_back("c"); + StringMatchResultListener listener; + EXPECT_FALSE(ExplainMatchResult( + UnorderedElementsAre("a", "a", AnyOf("b", "c")), v, &listener)) + << listener.str(); + + std::string prefix = + "where no permutation of the elements can satisfy all matchers, " + "and the closest match is 2 of 3 matchers with the " + "pairings:\n"; + + // We have to be a bit loose here, because there are 4 valid max matches. + EXPECT_THAT( + listener.str(), + AnyOf(prefix + "{\n " + EMString(0, 0) + + ",\n " + EMString(1, 2) + "\n}", + prefix + "{\n " + EMString(0, 1) + + ",\n " + EMString(1, 2) + "\n}", + prefix + "{\n " + EMString(0, 0) + + ",\n " + EMString(2, 2) + "\n}", + prefix + "{\n " + EMString(0, 1) + + ",\n " + EMString(2, 2) + "\n}")); +} + +TEST_F(UnorderedElementsAreTest, Describe) { + EXPECT_THAT(Describe<IntVec>(UnorderedElementsAre()), + Eq("is empty")); + EXPECT_THAT( + Describe<IntVec>(UnorderedElementsAre(345)), + Eq("has 1 element and that element is equal to 345")); + EXPECT_THAT( + Describe<IntVec>(UnorderedElementsAre(111, 222, 333)), + Eq("has 3 elements and there exists some permutation " + "of elements such that:\n" + " - element #0 is equal to 111, and\n" + " - element #1 is equal to 222, and\n" + " - element #2 is equal to 333")); +} + +TEST_F(UnorderedElementsAreTest, DescribeNegation) { + EXPECT_THAT(DescribeNegation<IntVec>(UnorderedElementsAre()), + Eq("isn't empty")); + EXPECT_THAT( + DescribeNegation<IntVec>(UnorderedElementsAre(345)), + Eq("doesn't have 1 element, or has 1 element that isn't equal to 345")); + EXPECT_THAT( + DescribeNegation<IntVec>(UnorderedElementsAre(123, 234, 345)), + Eq("doesn't have 3 elements, or there exists no permutation " + "of elements such that:\n" + " - element #0 is equal to 123, and\n" + " - element #1 is equal to 234, and\n" + " - element #2 is equal to 345")); +} + +namespace { + +// Used as a check on the more complex max flow method used in the +// real testing::internal::FindMaxBipartiteMatching. This method is +// compatible but runs in worst-case factorial time, so we only +// use it in testing for small problem sizes. +template <typename Graph> +class BacktrackingMaxBPMState { + public: + // Does not take ownership of 'g'. + explicit BacktrackingMaxBPMState(const Graph* g) : graph_(g) { } + + ElementMatcherPairs Compute() { + if (graph_->LhsSize() == 0 || graph_->RhsSize() == 0) { + return best_so_far_; + } + lhs_used_.assign(graph_->LhsSize(), kUnused); + rhs_used_.assign(graph_->RhsSize(), kUnused); + for (size_t irhs = 0; irhs < graph_->RhsSize(); ++irhs) { + matches_.clear(); + RecurseInto(irhs); + if (best_so_far_.size() == graph_->RhsSize()) + break; + } + return best_so_far_; + } + + private: + static const size_t kUnused = static_cast<size_t>(-1); + + void PushMatch(size_t lhs, size_t rhs) { + matches_.push_back(ElementMatcherPair(lhs, rhs)); + lhs_used_[lhs] = rhs; + rhs_used_[rhs] = lhs; + if (matches_.size() > best_so_far_.size()) { + best_so_far_ = matches_; + } + } + + void PopMatch() { + const ElementMatcherPair& back = matches_.back(); + lhs_used_[back.first] = kUnused; + rhs_used_[back.second] = kUnused; + matches_.pop_back(); + } + + bool RecurseInto(size_t irhs) { + if (rhs_used_[irhs] != kUnused) { + return true; + } + for (size_t ilhs = 0; ilhs < graph_->LhsSize(); ++ilhs) { + if (lhs_used_[ilhs] != kUnused) { + continue; + } + if (!graph_->HasEdge(ilhs, irhs)) { + continue; + } + PushMatch(ilhs, irhs); + if (best_so_far_.size() == graph_->RhsSize()) { + return false; + } + for (size_t mi = irhs + 1; mi < graph_->RhsSize(); ++mi) { + if (!RecurseInto(mi)) return false; + } + PopMatch(); + } + return true; + } + + const Graph* graph_; // not owned + std::vector<size_t> lhs_used_; + std::vector<size_t> rhs_used_; + ElementMatcherPairs matches_; + ElementMatcherPairs best_so_far_; +}; + +template <typename Graph> +const size_t BacktrackingMaxBPMState<Graph>::kUnused; + +} // namespace + +// Implement a simple backtracking algorithm to determine if it is possible +// to find one element per matcher, without reusing elements. +template <typename Graph> +ElementMatcherPairs +FindBacktrackingMaxBPM(const Graph& g) { + return BacktrackingMaxBPMState<Graph>(&g).Compute(); +} + +class BacktrackingBPMTest : public ::testing::Test { }; + +// Tests the MaxBipartiteMatching algorithm with square matrices. +// The single int param is the # of nodes on each of the left and right sides. +class BipartiteTest : public ::testing::TestWithParam<size_t> {}; + +// Verify all match graphs up to some moderate number of edges. +TEST_P(BipartiteTest, Exhaustive) { + size_t nodes = GetParam(); + MatchMatrix graph(nodes, nodes); + do { + ElementMatcherPairs matches = + internal::FindMaxBipartiteMatching(graph); + EXPECT_EQ(FindBacktrackingMaxBPM(graph).size(), matches.size()) + << "graph: " << graph.DebugString(); + // Check that all elements of matches are in the graph. + // Check that elements of first and second are unique. + std::vector<bool> seen_element(graph.LhsSize()); + std::vector<bool> seen_matcher(graph.RhsSize()); + SCOPED_TRACE(PrintToString(matches)); + for (size_t i = 0; i < matches.size(); ++i) { + size_t ilhs = matches[i].first; + size_t irhs = matches[i].second; + EXPECT_TRUE(graph.HasEdge(ilhs, irhs)); + EXPECT_FALSE(seen_element[ilhs]); + EXPECT_FALSE(seen_matcher[irhs]); + seen_element[ilhs] = true; + seen_matcher[irhs] = true; + } + } while (graph.NextGraph()); +} + +INSTANTIATE_TEST_SUITE_P(AllGraphs, BipartiteTest, + ::testing::Range(size_t{0}, size_t{5})); + +// Parameterized by a pair interpreted as (LhsSize, RhsSize). +class BipartiteNonSquareTest + : public ::testing::TestWithParam<std::pair<size_t, size_t> > { +}; + +TEST_F(BipartiteNonSquareTest, SimpleBacktracking) { + // ....... + // 0:-----\ : + // 1:---\ | : + // 2:---\ | : + // 3:-\ | | : + // :.......: + // 0 1 2 + MatchMatrix g(4, 3); + constexpr std::array<std::array<size_t, 2>, 4> kEdges = { + {{{0, 2}}, {{1, 1}}, {{2, 1}}, {{3, 0}}}}; + for (size_t i = 0; i < kEdges.size(); ++i) { + g.SetEdge(kEdges[i][0], kEdges[i][1], true); + } + EXPECT_THAT(FindBacktrackingMaxBPM(g), + ElementsAre(Pair(3, 0), + Pair(AnyOf(1, 2), 1), + Pair(0, 2))) << g.DebugString(); +} + +// Verify a few nonsquare matrices. +TEST_P(BipartiteNonSquareTest, Exhaustive) { + size_t nlhs = GetParam().first; + size_t nrhs = GetParam().second; + MatchMatrix graph(nlhs, nrhs); + do { + EXPECT_EQ(FindBacktrackingMaxBPM(graph).size(), + internal::FindMaxBipartiteMatching(graph).size()) + << "graph: " << graph.DebugString() + << "\nbacktracking: " + << PrintToString(FindBacktrackingMaxBPM(graph)) + << "\nmax flow: " + << PrintToString(internal::FindMaxBipartiteMatching(graph)); + } while (graph.NextGraph()); +} + +INSTANTIATE_TEST_SUITE_P(AllGraphs, BipartiteNonSquareTest, + testing::Values( + std::make_pair(1, 2), + std::make_pair(2, 1), + std::make_pair(3, 2), + std::make_pair(2, 3), + std::make_pair(4, 1), + std::make_pair(1, 4), + std::make_pair(4, 3), + std::make_pair(3, 4))); + +class BipartiteRandomTest + : public ::testing::TestWithParam<std::pair<int, int> > { +}; + +// Verifies a large sample of larger graphs. +TEST_P(BipartiteRandomTest, LargerNets) { + int nodes = GetParam().first; + int iters = GetParam().second; + MatchMatrix graph(static_cast<size_t>(nodes), static_cast<size_t>(nodes)); + + auto seed = static_cast<uint32_t>(GTEST_FLAG(random_seed)); + if (seed == 0) { + seed = static_cast<uint32_t>(time(nullptr)); + } + + for (; iters > 0; --iters, ++seed) { + srand(static_cast<unsigned int>(seed)); + graph.Randomize(); + EXPECT_EQ(FindBacktrackingMaxBPM(graph).size(), + internal::FindMaxBipartiteMatching(graph).size()) + << " graph: " << graph.DebugString() + << "\nTo reproduce the failure, rerun the test with the flag" + " --" << GTEST_FLAG_PREFIX_ << "random_seed=" << seed; + } +} + +// Test argument is a std::pair<int, int> representing (nodes, iters). +INSTANTIATE_TEST_SUITE_P(Samples, BipartiteRandomTest, + testing::Values( + std::make_pair(5, 10000), + std::make_pair(6, 5000), + std::make_pair(7, 2000), + std::make_pair(8, 500), + std::make_pair(9, 100))); + +// Tests IsReadableTypeName(). + +TEST(IsReadableTypeNameTest, ReturnsTrueForShortNames) { + EXPECT_TRUE(IsReadableTypeName("int")); + EXPECT_TRUE(IsReadableTypeName("const unsigned char*")); + EXPECT_TRUE(IsReadableTypeName("MyMap<int, void*>")); + EXPECT_TRUE(IsReadableTypeName("void (*)(int, bool)")); +} + +TEST(IsReadableTypeNameTest, ReturnsTrueForLongNonTemplateNonFunctionNames) { + EXPECT_TRUE(IsReadableTypeName("my_long_namespace::MyClassName")); + EXPECT_TRUE(IsReadableTypeName("int [5][6][7][8][9][10][11]")); + EXPECT_TRUE(IsReadableTypeName("my_namespace::MyOuterClass::MyInnerClass")); +} + +TEST(IsReadableTypeNameTest, ReturnsFalseForLongTemplateNames) { + EXPECT_FALSE( + IsReadableTypeName("basic_string<char, std::char_traits<char> >")); + EXPECT_FALSE(IsReadableTypeName("std::vector<int, std::alloc_traits<int> >")); +} + +TEST(IsReadableTypeNameTest, ReturnsFalseForLongFunctionTypeNames) { + EXPECT_FALSE(IsReadableTypeName("void (&)(int, bool, char, float)")); +} + +// Tests FormatMatcherDescription(). + +TEST(FormatMatcherDescriptionTest, WorksForEmptyDescription) { + EXPECT_EQ("is even", + FormatMatcherDescription(false, "IsEven", Strings())); + EXPECT_EQ("not (is even)", + FormatMatcherDescription(true, "IsEven", Strings())); + + const char* params[] = {"5"}; + EXPECT_EQ("equals 5", + FormatMatcherDescription(false, "Equals", + Strings(params, params + 1))); + + const char* params2[] = {"5", "8"}; + EXPECT_EQ("is in range (5, 8)", + FormatMatcherDescription(false, "IsInRange", + Strings(params2, params2 + 2))); +} + +// Tests PolymorphicMatcher::mutable_impl(). +TEST(PolymorphicMatcherTest, CanAccessMutableImpl) { + PolymorphicMatcher<DivisibleByImpl> m(DivisibleByImpl(42)); + DivisibleByImpl& impl = m.mutable_impl(); + EXPECT_EQ(42, impl.divider()); + + impl.set_divider(0); + EXPECT_EQ(0, m.mutable_impl().divider()); +} + +// Tests PolymorphicMatcher::impl(). +TEST(PolymorphicMatcherTest, CanAccessImpl) { + const PolymorphicMatcher<DivisibleByImpl> m(DivisibleByImpl(42)); + const DivisibleByImpl& impl = m.impl(); + EXPECT_EQ(42, impl.divider()); +} + +TEST(MatcherTupleTest, ExplainsMatchFailure) { + stringstream ss1; + ExplainMatchFailureTupleTo( + std::make_tuple(Matcher<char>(Eq('a')), GreaterThan(5)), + std::make_tuple('a', 10), &ss1); + EXPECT_EQ("", ss1.str()); // Successful match. + + stringstream ss2; + ExplainMatchFailureTupleTo( + std::make_tuple(GreaterThan(5), Matcher<char>(Eq('a'))), + std::make_tuple(2, 'b'), &ss2); + EXPECT_EQ(" Expected arg #0: is > 5\n" + " Actual: 2, which is 3 less than 5\n" + " Expected arg #1: is equal to 'a' (97, 0x61)\n" + " Actual: 'b' (98, 0x62)\n", + ss2.str()); // Failed match where both arguments need explanation. + + stringstream ss3; + ExplainMatchFailureTupleTo( + std::make_tuple(GreaterThan(5), Matcher<char>(Eq('a'))), + std::make_tuple(2, 'a'), &ss3); + EXPECT_EQ(" Expected arg #0: is > 5\n" + " Actual: 2, which is 3 less than 5\n", + ss3.str()); // Failed match where only one argument needs + // explanation. +} + +// Tests Each(). + +TEST(EachTest, ExplainsMatchResultCorrectly) { + set<int> a; // empty + + Matcher<set<int> > m = Each(2); + EXPECT_EQ("", Explain(m, a)); + + Matcher<const int(&)[1]> n = Each(1); // NOLINT + + const int b[1] = {1}; + EXPECT_EQ("", Explain(n, b)); + + n = Each(3); + EXPECT_EQ("whose element #0 doesn't match", Explain(n, b)); + + a.insert(1); + a.insert(2); + a.insert(3); + m = Each(GreaterThan(0)); + EXPECT_EQ("", Explain(m, a)); + + m = Each(GreaterThan(10)); + EXPECT_EQ("whose element #0 doesn't match, which is 9 less than 10", + Explain(m, a)); +} + +TEST(EachTest, DescribesItselfCorrectly) { + Matcher<vector<int> > m = Each(1); + EXPECT_EQ("only contains elements that is equal to 1", Describe(m)); + + Matcher<vector<int> > m2 = Not(m); + EXPECT_EQ("contains some element that isn't equal to 1", Describe(m2)); +} + +TEST(EachTest, MatchesVectorWhenAllElementsMatch) { + vector<int> some_vector; + EXPECT_THAT(some_vector, Each(1)); + some_vector.push_back(3); + EXPECT_THAT(some_vector, Not(Each(1))); + EXPECT_THAT(some_vector, Each(3)); + some_vector.push_back(1); + some_vector.push_back(2); + EXPECT_THAT(some_vector, Not(Each(3))); + EXPECT_THAT(some_vector, Each(Lt(3.5))); + + vector<std::string> another_vector; + another_vector.push_back("fee"); + EXPECT_THAT(another_vector, Each(std::string("fee"))); + another_vector.push_back("fie"); + another_vector.push_back("foe"); + another_vector.push_back("fum"); + EXPECT_THAT(another_vector, Not(Each(std::string("fee")))); +} + +TEST(EachTest, MatchesMapWhenAllElementsMatch) { + map<const char*, int> my_map; + const char* bar = "a string"; + my_map[bar] = 2; + EXPECT_THAT(my_map, Each(make_pair(bar, 2))); + + map<std::string, int> another_map; + EXPECT_THAT(another_map, Each(make_pair(std::string("fee"), 1))); + another_map["fee"] = 1; + EXPECT_THAT(another_map, Each(make_pair(std::string("fee"), 1))); + another_map["fie"] = 2; + another_map["foe"] = 3; + another_map["fum"] = 4; + EXPECT_THAT(another_map, Not(Each(make_pair(std::string("fee"), 1)))); + EXPECT_THAT(another_map, Not(Each(make_pair(std::string("fum"), 1)))); + EXPECT_THAT(another_map, Each(Pair(_, Gt(0)))); +} + +TEST(EachTest, AcceptsMatcher) { + const int a[] = {1, 2, 3}; + EXPECT_THAT(a, Each(Gt(0))); + EXPECT_THAT(a, Not(Each(Gt(1)))); +} + +TEST(EachTest, WorksForNativeArrayAsTuple) { + const int a[] = {1, 2}; + const int* const pointer = a; + EXPECT_THAT(std::make_tuple(pointer, 2), Each(Gt(0))); + EXPECT_THAT(std::make_tuple(pointer, 2), Not(Each(Gt(1)))); +} + +TEST(EachTest, WorksWithMoveOnly) { + ContainerHelper helper; + EXPECT_CALL(helper, Call(Each(Pointee(Gt(0))))); + helper.Call(MakeUniquePtrs({1, 2})); +} + +// For testing Pointwise(). +class IsHalfOfMatcher { + public: + template <typename T1, typename T2> + bool MatchAndExplain(const std::tuple<T1, T2>& a_pair, + MatchResultListener* listener) const { + if (std::get<0>(a_pair) == std::get<1>(a_pair) / 2) { + *listener << "where the second is " << std::get<1>(a_pair); + return true; + } else { + *listener << "where the second/2 is " << std::get<1>(a_pair) / 2; + return false; + } + } + + void DescribeTo(ostream* os) const { + *os << "are a pair where the first is half of the second"; + } + + void DescribeNegationTo(ostream* os) const { + *os << "are a pair where the first isn't half of the second"; + } +}; + +PolymorphicMatcher<IsHalfOfMatcher> IsHalfOf() { + return MakePolymorphicMatcher(IsHalfOfMatcher()); +} + +TEST(PointwiseTest, DescribesSelf) { + vector<int> rhs; + rhs.push_back(1); + rhs.push_back(2); + rhs.push_back(3); + const Matcher<const vector<int>&> m = Pointwise(IsHalfOf(), rhs); + EXPECT_EQ("contains 3 values, where each value and its corresponding value " + "in { 1, 2, 3 } are a pair where the first is half of the second", + Describe(m)); + EXPECT_EQ("doesn't contain exactly 3 values, or contains a value x at some " + "index i where x and the i-th value of { 1, 2, 3 } are a pair " + "where the first isn't half of the second", + DescribeNegation(m)); +} + +TEST(PointwiseTest, MakesCopyOfRhs) { + list<signed char> rhs; + rhs.push_back(2); + rhs.push_back(4); + + int lhs[] = {1, 2}; + const Matcher<const int (&)[2]> m = Pointwise(IsHalfOf(), rhs); + EXPECT_THAT(lhs, m); + + // Changing rhs now shouldn't affect m, which made a copy of rhs. + rhs.push_back(6); + EXPECT_THAT(lhs, m); +} + +TEST(PointwiseTest, WorksForLhsNativeArray) { + const int lhs[] = {1, 2, 3}; + vector<int> rhs; + rhs.push_back(2); + rhs.push_back(4); + rhs.push_back(6); + EXPECT_THAT(lhs, Pointwise(Lt(), rhs)); + EXPECT_THAT(lhs, Not(Pointwise(Gt(), rhs))); +} + +TEST(PointwiseTest, WorksForRhsNativeArray) { + const int rhs[] = {1, 2, 3}; + vector<int> lhs; + lhs.push_back(2); + lhs.push_back(4); + lhs.push_back(6); + EXPECT_THAT(lhs, Pointwise(Gt(), rhs)); + EXPECT_THAT(lhs, Not(Pointwise(Lt(), rhs))); +} + +// Test is effective only with sanitizers. +TEST(PointwiseTest, WorksForVectorOfBool) { + vector<bool> rhs(3, false); + rhs[1] = true; + vector<bool> lhs = rhs; + EXPECT_THAT(lhs, Pointwise(Eq(), rhs)); + rhs[0] = true; + EXPECT_THAT(lhs, Not(Pointwise(Eq(), rhs))); +} + + +TEST(PointwiseTest, WorksForRhsInitializerList) { + const vector<int> lhs{2, 4, 6}; + EXPECT_THAT(lhs, Pointwise(Gt(), {1, 2, 3})); + EXPECT_THAT(lhs, Not(Pointwise(Lt(), {3, 3, 7}))); +} + + +TEST(PointwiseTest, RejectsWrongSize) { + const double lhs[2] = {1, 2}; + const int rhs[1] = {0}; + EXPECT_THAT(lhs, Not(Pointwise(Gt(), rhs))); + EXPECT_EQ("which contains 2 values", + Explain(Pointwise(Gt(), rhs), lhs)); + + const int rhs2[3] = {0, 1, 2}; + EXPECT_THAT(lhs, Not(Pointwise(Gt(), rhs2))); +} + +TEST(PointwiseTest, RejectsWrongContent) { + const double lhs[3] = {1, 2, 3}; + const int rhs[3] = {2, 6, 4}; + EXPECT_THAT(lhs, Not(Pointwise(IsHalfOf(), rhs))); + EXPECT_EQ("where the value pair (2, 6) at index #1 don't match, " + "where the second/2 is 3", + Explain(Pointwise(IsHalfOf(), rhs), lhs)); +} + +TEST(PointwiseTest, AcceptsCorrectContent) { + const double lhs[3] = {1, 2, 3}; + const int rhs[3] = {2, 4, 6}; + EXPECT_THAT(lhs, Pointwise(IsHalfOf(), rhs)); + EXPECT_EQ("", Explain(Pointwise(IsHalfOf(), rhs), lhs)); +} + +TEST(PointwiseTest, AllowsMonomorphicInnerMatcher) { + const double lhs[3] = {1, 2, 3}; + const int rhs[3] = {2, 4, 6}; + const Matcher<std::tuple<const double&, const int&>> m1 = IsHalfOf(); + EXPECT_THAT(lhs, Pointwise(m1, rhs)); + EXPECT_EQ("", Explain(Pointwise(m1, rhs), lhs)); + + // This type works as a std::tuple<const double&, const int&> can be + // implicitly cast to std::tuple<double, int>. + const Matcher<std::tuple<double, int>> m2 = IsHalfOf(); + EXPECT_THAT(lhs, Pointwise(m2, rhs)); + EXPECT_EQ("", Explain(Pointwise(m2, rhs), lhs)); +} + +MATCHER(PointeeEquals, "Points to an equal value") { + return ExplainMatchResult(::testing::Pointee(::testing::get<1>(arg)), + ::testing::get<0>(arg), result_listener); +} + +TEST(PointwiseTest, WorksWithMoveOnly) { + ContainerHelper helper; + EXPECT_CALL(helper, Call(Pointwise(PointeeEquals(), std::vector<int>{1, 2}))); + helper.Call(MakeUniquePtrs({1, 2})); +} + +TEST(UnorderedPointwiseTest, DescribesSelf) { + vector<int> rhs; + rhs.push_back(1); + rhs.push_back(2); + rhs.push_back(3); + const Matcher<const vector<int>&> m = UnorderedPointwise(IsHalfOf(), rhs); + EXPECT_EQ( + "has 3 elements and there exists some permutation of elements such " + "that:\n" + " - element #0 and 1 are a pair where the first is half of the second, " + "and\n" + " - element #1 and 2 are a pair where the first is half of the second, " + "and\n" + " - element #2 and 3 are a pair where the first is half of the second", + Describe(m)); + EXPECT_EQ( + "doesn't have 3 elements, or there exists no permutation of elements " + "such that:\n" + " - element #0 and 1 are a pair where the first is half of the second, " + "and\n" + " - element #1 and 2 are a pair where the first is half of the second, " + "and\n" + " - element #2 and 3 are a pair where the first is half of the second", + DescribeNegation(m)); +} + +TEST(UnorderedPointwiseTest, MakesCopyOfRhs) { + list<signed char> rhs; + rhs.push_back(2); + rhs.push_back(4); + + int lhs[] = {2, 1}; + const Matcher<const int (&)[2]> m = UnorderedPointwise(IsHalfOf(), rhs); + EXPECT_THAT(lhs, m); + + // Changing rhs now shouldn't affect m, which made a copy of rhs. + rhs.push_back(6); + EXPECT_THAT(lhs, m); +} + +TEST(UnorderedPointwiseTest, WorksForLhsNativeArray) { + const int lhs[] = {1, 2, 3}; + vector<int> rhs; + rhs.push_back(4); + rhs.push_back(6); + rhs.push_back(2); + EXPECT_THAT(lhs, UnorderedPointwise(Lt(), rhs)); + EXPECT_THAT(lhs, Not(UnorderedPointwise(Gt(), rhs))); +} + +TEST(UnorderedPointwiseTest, WorksForRhsNativeArray) { + const int rhs[] = {1, 2, 3}; + vector<int> lhs; + lhs.push_back(4); + lhs.push_back(2); + lhs.push_back(6); + EXPECT_THAT(lhs, UnorderedPointwise(Gt(), rhs)); + EXPECT_THAT(lhs, Not(UnorderedPointwise(Lt(), rhs))); +} + + +TEST(UnorderedPointwiseTest, WorksForRhsInitializerList) { + const vector<int> lhs{2, 4, 6}; + EXPECT_THAT(lhs, UnorderedPointwise(Gt(), {5, 1, 3})); + EXPECT_THAT(lhs, Not(UnorderedPointwise(Lt(), {1, 1, 7}))); +} + + +TEST(UnorderedPointwiseTest, RejectsWrongSize) { + const double lhs[2] = {1, 2}; + const int rhs[1] = {0}; + EXPECT_THAT(lhs, Not(UnorderedPointwise(Gt(), rhs))); + EXPECT_EQ("which has 2 elements", + Explain(UnorderedPointwise(Gt(), rhs), lhs)); + + const int rhs2[3] = {0, 1, 2}; + EXPECT_THAT(lhs, Not(UnorderedPointwise(Gt(), rhs2))); +} + +TEST(UnorderedPointwiseTest, RejectsWrongContent) { + const double lhs[3] = {1, 2, 3}; + const int rhs[3] = {2, 6, 6}; + EXPECT_THAT(lhs, Not(UnorderedPointwise(IsHalfOf(), rhs))); + EXPECT_EQ("where the following elements don't match any matchers:\n" + "element #1: 2", + Explain(UnorderedPointwise(IsHalfOf(), rhs), lhs)); +} + +TEST(UnorderedPointwiseTest, AcceptsCorrectContentInSameOrder) { + const double lhs[3] = {1, 2, 3}; + const int rhs[3] = {2, 4, 6}; + EXPECT_THAT(lhs, UnorderedPointwise(IsHalfOf(), rhs)); +} + +TEST(UnorderedPointwiseTest, AcceptsCorrectContentInDifferentOrder) { + const double lhs[3] = {1, 2, 3}; + const int rhs[3] = {6, 4, 2}; + EXPECT_THAT(lhs, UnorderedPointwise(IsHalfOf(), rhs)); +} + +TEST(UnorderedPointwiseTest, AllowsMonomorphicInnerMatcher) { + const double lhs[3] = {1, 2, 3}; + const int rhs[3] = {4, 6, 2}; + const Matcher<std::tuple<const double&, const int&>> m1 = IsHalfOf(); + EXPECT_THAT(lhs, UnorderedPointwise(m1, rhs)); + + // This type works as a std::tuple<const double&, const int&> can be + // implicitly cast to std::tuple<double, int>. + const Matcher<std::tuple<double, int>> m2 = IsHalfOf(); + EXPECT_THAT(lhs, UnorderedPointwise(m2, rhs)); +} + +TEST(UnorderedPointwiseTest, WorksWithMoveOnly) { + ContainerHelper helper; + EXPECT_CALL(helper, Call(UnorderedPointwise(PointeeEquals(), + std::vector<int>{1, 2}))); + helper.Call(MakeUniquePtrs({2, 1})); +} + +// Sample optional type implementation with minimal requirements for use with +// Optional matcher. +template <typename T> +class SampleOptional { + public: + using value_type = T; + explicit SampleOptional(T value) + : value_(std::move(value)), has_value_(true) {} + SampleOptional() : value_(), has_value_(false) {} + operator bool() const { return has_value_; } + const T& operator*() const { return value_; } + + private: + T value_; + bool has_value_; +}; + +TEST(OptionalTest, DescribesSelf) { + const Matcher<SampleOptional<int>> m = Optional(Eq(1)); + EXPECT_EQ("value is equal to 1", Describe(m)); +} + +TEST(OptionalTest, ExplainsSelf) { + const Matcher<SampleOptional<int>> m = Optional(Eq(1)); + EXPECT_EQ("whose value 1 matches", Explain(m, SampleOptional<int>(1))); + EXPECT_EQ("whose value 2 doesn't match", Explain(m, SampleOptional<int>(2))); +} + +TEST(OptionalTest, MatchesNonEmptyOptional) { + const Matcher<SampleOptional<int>> m1 = Optional(1); + const Matcher<SampleOptional<int>> m2 = Optional(Eq(2)); + const Matcher<SampleOptional<int>> m3 = Optional(Lt(3)); + SampleOptional<int> opt(1); + EXPECT_TRUE(m1.Matches(opt)); + EXPECT_FALSE(m2.Matches(opt)); + EXPECT_TRUE(m3.Matches(opt)); +} + +TEST(OptionalTest, DoesNotMatchNullopt) { + const Matcher<SampleOptional<int>> m = Optional(1); + SampleOptional<int> empty; + EXPECT_FALSE(m.Matches(empty)); +} + +TEST(OptionalTest, WorksWithMoveOnly) { + Matcher<SampleOptional<std::unique_ptr<int>>> m = Optional(Eq(nullptr)); + EXPECT_TRUE(m.Matches(SampleOptional<std::unique_ptr<int>>(nullptr))); +} + +class SampleVariantIntString { + public: + SampleVariantIntString(int i) : i_(i), has_int_(true) {} + SampleVariantIntString(const std::string& s) : s_(s), has_int_(false) {} + + template <typename T> + friend bool holds_alternative(const SampleVariantIntString& value) { + return value.has_int_ == std::is_same<T, int>::value; + } + + template <typename T> + friend const T& get(const SampleVariantIntString& value) { + return value.get_impl(static_cast<T*>(nullptr)); + } + + private: + const int& get_impl(int*) const { return i_; } + const std::string& get_impl(std::string*) const { return s_; } + + int i_; + std::string s_; + bool has_int_; +}; + +TEST(VariantTest, DescribesSelf) { + const Matcher<SampleVariantIntString> m = VariantWith<int>(Eq(1)); + EXPECT_THAT(Describe(m), ContainsRegex("is a variant<> with value of type " + "'.*' and the value is equal to 1")); +} + +TEST(VariantTest, ExplainsSelf) { + const Matcher<SampleVariantIntString> m = VariantWith<int>(Eq(1)); + EXPECT_THAT(Explain(m, SampleVariantIntString(1)), + ContainsRegex("whose value 1")); + EXPECT_THAT(Explain(m, SampleVariantIntString("A")), + HasSubstr("whose value is not of type '")); + EXPECT_THAT(Explain(m, SampleVariantIntString(2)), + "whose value 2 doesn't match"); +} + +TEST(VariantTest, FullMatch) { + Matcher<SampleVariantIntString> m = VariantWith<int>(Eq(1)); + EXPECT_TRUE(m.Matches(SampleVariantIntString(1))); + + m = VariantWith<std::string>(Eq("1")); + EXPECT_TRUE(m.Matches(SampleVariantIntString("1"))); +} + +TEST(VariantTest, TypeDoesNotMatch) { + Matcher<SampleVariantIntString> m = VariantWith<int>(Eq(1)); + EXPECT_FALSE(m.Matches(SampleVariantIntString("1"))); + + m = VariantWith<std::string>(Eq("1")); + EXPECT_FALSE(m.Matches(SampleVariantIntString(1))); +} + +TEST(VariantTest, InnerDoesNotMatch) { + Matcher<SampleVariantIntString> m = VariantWith<int>(Eq(1)); + EXPECT_FALSE(m.Matches(SampleVariantIntString(2))); + + m = VariantWith<std::string>(Eq("1")); + EXPECT_FALSE(m.Matches(SampleVariantIntString("2"))); +} + +class SampleAnyType { + public: + explicit SampleAnyType(int i) : index_(0), i_(i) {} + explicit SampleAnyType(const std::string& s) : index_(1), s_(s) {} + + template <typename T> + friend const T* any_cast(const SampleAnyType* any) { + return any->get_impl(static_cast<T*>(nullptr)); + } + + private: + int index_; + int i_; + std::string s_; + + const int* get_impl(int*) const { return index_ == 0 ? &i_ : nullptr; } + const std::string* get_impl(std::string*) const { + return index_ == 1 ? &s_ : nullptr; + } +}; + +TEST(AnyWithTest, FullMatch) { + Matcher<SampleAnyType> m = AnyWith<int>(Eq(1)); + EXPECT_TRUE(m.Matches(SampleAnyType(1))); +} + +TEST(AnyWithTest, TestBadCastType) { + Matcher<SampleAnyType> m = AnyWith<std::string>(Eq("fail")); + EXPECT_FALSE(m.Matches(SampleAnyType(1))); +} + +TEST(AnyWithTest, TestUseInContainers) { + std::vector<SampleAnyType> a; + a.emplace_back(1); + a.emplace_back(2); + a.emplace_back(3); + EXPECT_THAT( + a, ElementsAreArray({AnyWith<int>(1), AnyWith<int>(2), AnyWith<int>(3)})); + + std::vector<SampleAnyType> b; + b.emplace_back("hello"); + b.emplace_back("merhaba"); + b.emplace_back("salut"); + EXPECT_THAT(b, ElementsAreArray({AnyWith<std::string>("hello"), + AnyWith<std::string>("merhaba"), + AnyWith<std::string>("salut")})); +} +TEST(AnyWithTest, TestCompare) { + EXPECT_THAT(SampleAnyType(1), AnyWith<int>(Gt(0))); +} + +TEST(AnyWithTest, DescribesSelf) { + const Matcher<const SampleAnyType&> m = AnyWith<int>(Eq(1)); + EXPECT_THAT(Describe(m), ContainsRegex("is an 'any' type with value of type " + "'.*' and the value is equal to 1")); +} + +TEST(AnyWithTest, ExplainsSelf) { + const Matcher<const SampleAnyType&> m = AnyWith<int>(Eq(1)); + + EXPECT_THAT(Explain(m, SampleAnyType(1)), ContainsRegex("whose value 1")); + EXPECT_THAT(Explain(m, SampleAnyType("A")), + HasSubstr("whose value is not of type '")); + EXPECT_THAT(Explain(m, SampleAnyType(2)), "whose value 2 doesn't match"); +} + +TEST(PointeeTest, WorksOnMoveOnlyType) { + std::unique_ptr<int> p(new int(3)); + EXPECT_THAT(p, Pointee(Eq(3))); + EXPECT_THAT(p, Not(Pointee(Eq(2)))); +} + +TEST(NotTest, WorksOnMoveOnlyType) { + std::unique_ptr<int> p(new int(3)); + EXPECT_THAT(p, Pointee(Eq(3))); + EXPECT_THAT(p, Not(Pointee(Eq(2)))); +} + +// Tests Args<k0, ..., kn>(m). + +TEST(ArgsTest, AcceptsZeroTemplateArg) { + const std::tuple<int, bool> t(5, true); + EXPECT_THAT(t, Args<>(Eq(std::tuple<>()))); + EXPECT_THAT(t, Not(Args<>(Ne(std::tuple<>())))); +} + +TEST(ArgsTest, AcceptsOneTemplateArg) { + const std::tuple<int, bool> t(5, true); + EXPECT_THAT(t, Args<0>(Eq(std::make_tuple(5)))); + EXPECT_THAT(t, Args<1>(Eq(std::make_tuple(true)))); + EXPECT_THAT(t, Not(Args<1>(Eq(std::make_tuple(false))))); +} + +TEST(ArgsTest, AcceptsTwoTemplateArgs) { + const std::tuple<short, int, long> t(4, 5, 6L); // NOLINT + + EXPECT_THAT(t, (Args<0, 1>(Lt()))); + EXPECT_THAT(t, (Args<1, 2>(Lt()))); + EXPECT_THAT(t, Not(Args<0, 2>(Gt()))); +} + +TEST(ArgsTest, AcceptsRepeatedTemplateArgs) { + const std::tuple<short, int, long> t(4, 5, 6L); // NOLINT + EXPECT_THAT(t, (Args<0, 0>(Eq()))); + EXPECT_THAT(t, Not(Args<1, 1>(Ne()))); +} + +TEST(ArgsTest, AcceptsDecreasingTemplateArgs) { + const std::tuple<short, int, long> t(4, 5, 6L); // NOLINT + EXPECT_THAT(t, (Args<2, 0>(Gt()))); + EXPECT_THAT(t, Not(Args<2, 1>(Lt()))); +} + +MATCHER(SumIsZero, "") { + return std::get<0>(arg) + std::get<1>(arg) + std::get<2>(arg) == 0; +} + +TEST(ArgsTest, AcceptsMoreTemplateArgsThanArityOfOriginalTuple) { + EXPECT_THAT(std::make_tuple(-1, 2), (Args<0, 0, 1>(SumIsZero()))); + EXPECT_THAT(std::make_tuple(1, 2), Not(Args<0, 0, 1>(SumIsZero()))); +} + +TEST(ArgsTest, CanBeNested) { + const std::tuple<short, int, long, int> t(4, 5, 6L, 6); // NOLINT + EXPECT_THAT(t, (Args<1, 2, 3>(Args<1, 2>(Eq())))); + EXPECT_THAT(t, (Args<0, 1, 3>(Args<0, 2>(Lt())))); +} + +TEST(ArgsTest, CanMatchTupleByValue) { + typedef std::tuple<char, int, int> Tuple3; + const Matcher<Tuple3> m = Args<1, 2>(Lt()); + EXPECT_TRUE(m.Matches(Tuple3('a', 1, 2))); + EXPECT_FALSE(m.Matches(Tuple3('b', 2, 2))); +} + +TEST(ArgsTest, CanMatchTupleByReference) { + typedef std::tuple<char, char, int> Tuple3; + const Matcher<const Tuple3&> m = Args<0, 1>(Lt()); + EXPECT_TRUE(m.Matches(Tuple3('a', 'b', 2))); + EXPECT_FALSE(m.Matches(Tuple3('b', 'b', 2))); +} + +// Validates that arg is printed as str. +MATCHER_P(PrintsAs, str, "") { + return testing::PrintToString(arg) == str; +} + +TEST(ArgsTest, AcceptsTenTemplateArgs) { + EXPECT_THAT(std::make_tuple(0, 1L, 2, 3L, 4, 5, 6, 7, 8, 9), + (Args<9, 8, 7, 6, 5, 4, 3, 2, 1, 0>( + PrintsAs("(9, 8, 7, 6, 5, 4, 3, 2, 1, 0)")))); + EXPECT_THAT(std::make_tuple(0, 1L, 2, 3L, 4, 5, 6, 7, 8, 9), + Not(Args<9, 8, 7, 6, 5, 4, 3, 2, 1, 0>( + PrintsAs("(0, 8, 7, 6, 5, 4, 3, 2, 1, 0)")))); +} + +TEST(ArgsTest, DescirbesSelfCorrectly) { + const Matcher<std::tuple<int, bool, char> > m = Args<2, 0>(Lt()); + EXPECT_EQ("are a tuple whose fields (#2, #0) are a pair where " + "the first < the second", + Describe(m)); +} + +TEST(ArgsTest, DescirbesNestedArgsCorrectly) { + const Matcher<const std::tuple<int, bool, char, int>&> m = + Args<0, 2, 3>(Args<2, 0>(Lt())); + EXPECT_EQ("are a tuple whose fields (#0, #2, #3) are a tuple " + "whose fields (#2, #0) are a pair where the first < the second", + Describe(m)); +} + +TEST(ArgsTest, DescribesNegationCorrectly) { + const Matcher<std::tuple<int, char> > m = Args<1, 0>(Gt()); + EXPECT_EQ("are a tuple whose fields (#1, #0) aren't a pair " + "where the first > the second", + DescribeNegation(m)); +} + +TEST(ArgsTest, ExplainsMatchResultWithoutInnerExplanation) { + const Matcher<std::tuple<bool, int, int> > m = Args<1, 2>(Eq()); + EXPECT_EQ("whose fields (#1, #2) are (42, 42)", + Explain(m, std::make_tuple(false, 42, 42))); + EXPECT_EQ("whose fields (#1, #2) are (42, 43)", + Explain(m, std::make_tuple(false, 42, 43))); +} + +// For testing Args<>'s explanation. +class LessThanMatcher : public MatcherInterface<std::tuple<char, int> > { + public: + void DescribeTo(::std::ostream* /*os*/) const override {} + + bool MatchAndExplain(std::tuple<char, int> value, + MatchResultListener* listener) const override { + const int diff = std::get<0>(value) - std::get<1>(value); + if (diff > 0) { + *listener << "where the first value is " << diff + << " more than the second"; + } + return diff < 0; + } +}; + +Matcher<std::tuple<char, int> > LessThan() { + return MakeMatcher(new LessThanMatcher); +} + +TEST(ArgsTest, ExplainsMatchResultWithInnerExplanation) { + const Matcher<std::tuple<char, int, int> > m = Args<0, 2>(LessThan()); + EXPECT_EQ( + "whose fields (#0, #2) are ('a' (97, 0x61), 42), " + "where the first value is 55 more than the second", + Explain(m, std::make_tuple('a', 42, 42))); + EXPECT_EQ("whose fields (#0, #2) are ('\\0', 43)", + Explain(m, std::make_tuple('\0', 42, 43))); +} + +class PredicateFormatterFromMatcherTest : public ::testing::Test { + protected: + enum Behavior { kInitialSuccess, kAlwaysFail, kFlaky }; + + // A matcher that can return different results when used multiple times on the + // same input. No real matcher should do this; but this lets us test that we + // detect such behavior and fail appropriately. + class MockMatcher : public MatcherInterface<Behavior> { + public: + bool MatchAndExplain(Behavior behavior, + MatchResultListener* listener) const override { + *listener << "[MatchAndExplain]"; + switch (behavior) { + case kInitialSuccess: + // The first call to MatchAndExplain should use a "not interested" + // listener; so this is expected to return |true|. There should be no + // subsequent calls. + return !listener->IsInterested(); + + case kAlwaysFail: + return false; + + case kFlaky: + // The first call to MatchAndExplain should use a "not interested" + // listener; so this will return |false|. Subsequent calls should have + // an "interested" listener; so this will return |true|, thus + // simulating a flaky matcher. + return listener->IsInterested(); + } + + GTEST_LOG_(FATAL) << "This should never be reached"; + return false; + } + + void DescribeTo(ostream* os) const override { *os << "[DescribeTo]"; } + + void DescribeNegationTo(ostream* os) const override { + *os << "[DescribeNegationTo]"; + } + }; + + AssertionResult RunPredicateFormatter(Behavior behavior) { + auto matcher = MakeMatcher(new MockMatcher); + PredicateFormatterFromMatcher<Matcher<Behavior>> predicate_formatter( + matcher); + return predicate_formatter("dummy-name", behavior); + } +}; + +TEST_F(PredicateFormatterFromMatcherTest, ShortCircuitOnSuccess) { + AssertionResult result = RunPredicateFormatter(kInitialSuccess); + EXPECT_TRUE(result); // Implicit cast to bool. + std::string expect; + EXPECT_EQ(expect, result.message()); +} + +TEST_F(PredicateFormatterFromMatcherTest, NoShortCircuitOnFailure) { + AssertionResult result = RunPredicateFormatter(kAlwaysFail); + EXPECT_FALSE(result); // Implicit cast to bool. + std::string expect = + "Value of: dummy-name\nExpected: [DescribeTo]\n" + " Actual: 1" + + OfType(internal::GetTypeName<Behavior>()) + ", [MatchAndExplain]"; + EXPECT_EQ(expect, result.message()); +} + +TEST_F(PredicateFormatterFromMatcherTest, DetectsFlakyShortCircuit) { + AssertionResult result = RunPredicateFormatter(kFlaky); + EXPECT_FALSE(result); // Implicit cast to bool. + std::string expect = + "Value of: dummy-name\nExpected: [DescribeTo]\n" + " The matcher failed on the initial attempt; but passed when rerun to " + "generate the explanation.\n" + " Actual: 2" + + OfType(internal::GetTypeName<Behavior>()) + ", [MatchAndExplain]"; + EXPECT_EQ(expect, result.message()); +} + +// Tests for ElementsAre(). + +TEST(ElementsAreTest, CanDescribeExpectingNoElement) { + Matcher<const vector<int>&> m = ElementsAre(); + EXPECT_EQ("is empty", Describe(m)); +} + +TEST(ElementsAreTest, CanDescribeExpectingOneElement) { + Matcher<vector<int>> m = ElementsAre(Gt(5)); + EXPECT_EQ("has 1 element that is > 5", Describe(m)); +} + +TEST(ElementsAreTest, CanDescribeExpectingManyElements) { + Matcher<list<std::string>> m = ElementsAre(StrEq("one"), "two"); + EXPECT_EQ( + "has 2 elements where\n" + "element #0 is equal to \"one\",\n" + "element #1 is equal to \"two\"", + Describe(m)); +} + +TEST(ElementsAreTest, CanDescribeNegationOfExpectingNoElement) { + Matcher<vector<int>> m = ElementsAre(); + EXPECT_EQ("isn't empty", DescribeNegation(m)); +} + +TEST(ElementsAreTest, CanDescribeNegationOfExpectingOneElment) { + Matcher<const list<int>&> m = ElementsAre(Gt(5)); + EXPECT_EQ( + "doesn't have 1 element, or\n" + "element #0 isn't > 5", + DescribeNegation(m)); +} + +TEST(ElementsAreTest, CanDescribeNegationOfExpectingManyElements) { + Matcher<const list<std::string>&> m = ElementsAre("one", "two"); + EXPECT_EQ( + "doesn't have 2 elements, or\n" + "element #0 isn't equal to \"one\", or\n" + "element #1 isn't equal to \"two\"", + DescribeNegation(m)); +} + +TEST(ElementsAreTest, DoesNotExplainTrivialMatch) { + Matcher<const list<int>&> m = ElementsAre(1, Ne(2)); + + list<int> test_list; + test_list.push_back(1); + test_list.push_back(3); + EXPECT_EQ("", Explain(m, test_list)); // No need to explain anything. +} + +TEST(ElementsAreTest, ExplainsNonTrivialMatch) { + Matcher<const vector<int>&> m = + ElementsAre(GreaterThan(1), 0, GreaterThan(2)); + + const int a[] = {10, 0, 100}; + vector<int> test_vector(std::begin(a), std::end(a)); + EXPECT_EQ( + "whose element #0 matches, which is 9 more than 1,\n" + "and whose element #2 matches, which is 98 more than 2", + Explain(m, test_vector)); +} + +TEST(ElementsAreTest, CanExplainMismatchWrongSize) { + Matcher<const list<int>&> m = ElementsAre(1, 3); + + list<int> test_list; + // No need to explain when the container is empty. + EXPECT_EQ("", Explain(m, test_list)); + + test_list.push_back(1); + EXPECT_EQ("which has 1 element", Explain(m, test_list)); +} + +TEST(ElementsAreTest, CanExplainMismatchRightSize) { + Matcher<const vector<int>&> m = ElementsAre(1, GreaterThan(5)); + + vector<int> v; + v.push_back(2); + v.push_back(1); + EXPECT_EQ("whose element #0 doesn't match", Explain(m, v)); + + v[0] = 1; + EXPECT_EQ("whose element #1 doesn't match, which is 4 less than 5", + Explain(m, v)); +} + +TEST(ElementsAreTest, MatchesOneElementVector) { + vector<std::string> test_vector; + test_vector.push_back("test string"); + + EXPECT_THAT(test_vector, ElementsAre(StrEq("test string"))); +} + +TEST(ElementsAreTest, MatchesOneElementList) { + list<std::string> test_list; + test_list.push_back("test string"); + + EXPECT_THAT(test_list, ElementsAre("test string")); +} + +TEST(ElementsAreTest, MatchesThreeElementVector) { + vector<std::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(std::begin(a), std::end(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<std::string> test_vector; + test_vector.push_back("test string"); + test_vector.push_back("test string"); + + Matcher<vector<std::string>> m = ElementsAre(StrEq("test string")); + EXPECT_FALSE(m.Matches(test_vector)); +} + +TEST(ElementsAreTest, DoesNotMatchWrongValue) { + vector<std::string> test_vector; + test_vector.push_back("other string"); + + Matcher<vector<std::string>> m = ElementsAre(StrEq("test string")); + EXPECT_FALSE(m.Matches(test_vector)); +} + +TEST(ElementsAreTest, DoesNotMatchWrongOrder) { + vector<std::string> test_vector; + test_vector.push_back("one"); + test_vector.push_back("three"); + test_vector.push_back("two"); + + Matcher<vector<std::string>> m = + ElementsAre(StrEq("one"), StrEq("two"), StrEq("three")); + EXPECT_FALSE(m.Matches(test_vector)); +} + +TEST(ElementsAreTest, WorksForNestedContainer) { + constexpr std::array<const char*, 2> strings = {{"Hi", "world"}}; + + vector<list<char>> nested; + for (const auto& s : strings) { + nested.emplace_back(s, s + strlen(s)); + } + + 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(std::begin(a), std::end(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(std::begin(a), std::end(a)); + + EXPECT_THAT(&v, Pointee(ElementsAre(0, 1, _))); + EXPECT_THAT(&v, Not(Pointee(ElementsAre(0, _, 3)))); +} + +TEST(ElementsAreTest, WorksWithNativeArrayPassedByReference) { + int array[] = {0, 1, 2}; + EXPECT_THAT(array, ElementsAre(0, 1, _)); + EXPECT_THAT(array, Not(ElementsAre(1, _, _))); + EXPECT_THAT(array, Not(ElementsAre(0, _))); +} + +class NativeArrayPassedAsPointerAndSize { + public: + NativeArrayPassedAsPointerAndSize() {} + + MOCK_METHOD(void, Helper, (int* array, int size)); + + private: + GTEST_DISALLOW_COPY_AND_ASSIGN_(NativeArrayPassedAsPointerAndSize); +}; + +TEST(ElementsAreTest, WorksWithNativeArrayPassedAsPointerAndSize) { + int array[] = {0, 1}; + ::std::tuple<int*, size_t> array_as_tuple(array, 2); + EXPECT_THAT(array_as_tuple, ElementsAre(0, 1)); + EXPECT_THAT(array_as_tuple, Not(ElementsAre(0))); + + NativeArrayPassedAsPointerAndSize helper; + EXPECT_CALL(helper, Helper(_, _)).With(ElementsAre(0, 1)); + helper.Helper(array, 2); +} + +TEST(ElementsAreTest, WorksWithTwoDimensionalNativeArray) { + const char a2[][3] = {"hi", "lo"}; + EXPECT_THAT(a2, ElementsAre(ElementsAre('h', 'i', '\0'), + ElementsAre('l', 'o', '\0'))); + EXPECT_THAT(a2, ElementsAre(StrEq("hi"), StrEq("lo"))); + EXPECT_THAT(a2, ElementsAre(Not(ElementsAre('h', 'o', '\0')), + ElementsAre('l', 'o', '\0'))); +} + +TEST(ElementsAreTest, AcceptsStringLiteral) { + std::string array[] = {"hi", "one", "two"}; + EXPECT_THAT(array, ElementsAre("hi", "one", "two")); + EXPECT_THAT(array, Not(ElementsAre("hi", "one", "too"))); +} + +// Declared here with the size unknown. Defined AFTER the following test. +extern const char kHi[]; + +TEST(ElementsAreTest, AcceptsArrayWithUnknownSize) { + // The size of kHi is not known in this test, but ElementsAre() should + // still accept it. + + std::string array1[] = {"hi"}; + EXPECT_THAT(array1, ElementsAre(kHi)); + + std::string array2[] = {"ho"}; + EXPECT_THAT(array2, Not(ElementsAre(kHi))); +} + +const char kHi[] = "hi"; + +TEST(ElementsAreTest, MakesCopyOfArguments) { + int x = 1; + int y = 2; + // This should make a copy of x and y. + ::testing::internal::ElementsAreMatcher<std::tuple<int, int>> + polymorphic_matcher = ElementsAre(x, y); + // Changing x and y now shouldn't affect the meaning of the above matcher. + x = y = 0; + const int array1[] = {1, 2}; + EXPECT_THAT(array1, polymorphic_matcher); + const int array2[] = {0, 0}; + EXPECT_THAT(array2, Not(polymorphic_matcher)); +} + +// Tests for ElementsAreArray(). Since ElementsAreArray() shares most +// of the implementation with ElementsAre(), we don't test it as +// thoroughly here. + +TEST(ElementsAreArrayTest, CanBeCreatedWithValueArray) { + const int a[] = {1, 2, 3}; + + vector<int> test_vector(std::begin(a), std::end(a)); + EXPECT_THAT(test_vector, ElementsAreArray(a)); + + test_vector[2] = 0; + EXPECT_THAT(test_vector, Not(ElementsAreArray(a))); +} + +TEST(ElementsAreArrayTest, CanBeCreatedWithArraySize) { + std::array<const char*, 3> a = {{"one", "two", "three"}}; + + vector<std::string> test_vector(std::begin(a), std::end(a)); + EXPECT_THAT(test_vector, ElementsAreArray(a.data(), a.size())); + + const char** p = a.data(); + test_vector[0] = "1"; + EXPECT_THAT(test_vector, Not(ElementsAreArray(p, a.size()))); +} + +TEST(ElementsAreArrayTest, CanBeCreatedWithoutArraySize) { + const char* a[] = {"one", "two", "three"}; + + vector<std::string> test_vector(std::begin(a), std::end(a)); + EXPECT_THAT(test_vector, ElementsAreArray(a)); + + test_vector[0] = "1"; + EXPECT_THAT(test_vector, Not(ElementsAreArray(a))); +} + +TEST(ElementsAreArrayTest, CanBeCreatedWithMatcherArray) { + const Matcher<std::string> kMatcherArray[] = {StrEq("one"), StrEq("two"), + StrEq("three")}; + + vector<std::string> test_vector; + test_vector.push_back("one"); + test_vector.push_back("two"); + test_vector.push_back("three"); + EXPECT_THAT(test_vector, ElementsAreArray(kMatcherArray)); + + test_vector.push_back("three"); + EXPECT_THAT(test_vector, Not(ElementsAreArray(kMatcherArray))); +} + +TEST(ElementsAreArrayTest, CanBeCreatedWithVector) { + const int a[] = {1, 2, 3}; + vector<int> test_vector(std::begin(a), std::end(a)); + const vector<int> expected(std::begin(a), std::end(a)); + EXPECT_THAT(test_vector, ElementsAreArray(expected)); + test_vector.push_back(4); + EXPECT_THAT(test_vector, Not(ElementsAreArray(expected))); +} + +TEST(ElementsAreArrayTest, TakesInitializerList) { + const int a[5] = {1, 2, 3, 4, 5}; + EXPECT_THAT(a, ElementsAreArray({1, 2, 3, 4, 5})); + EXPECT_THAT(a, Not(ElementsAreArray({1, 2, 3, 5, 4}))); + EXPECT_THAT(a, Not(ElementsAreArray({1, 2, 3, 4, 6}))); +} + +TEST(ElementsAreArrayTest, TakesInitializerListOfCStrings) { + const std::string a[5] = {"a", "b", "c", "d", "e"}; + EXPECT_THAT(a, ElementsAreArray({"a", "b", "c", "d", "e"})); + EXPECT_THAT(a, Not(ElementsAreArray({"a", "b", "c", "e", "d"}))); + EXPECT_THAT(a, Not(ElementsAreArray({"a", "b", "c", "d", "ef"}))); +} + +TEST(ElementsAreArrayTest, TakesInitializerListOfSameTypedMatchers) { + const int a[5] = {1, 2, 3, 4, 5}; + EXPECT_THAT(a, ElementsAreArray({Eq(1), Eq(2), Eq(3), Eq(4), Eq(5)})); + EXPECT_THAT(a, Not(ElementsAreArray({Eq(1), Eq(2), Eq(3), Eq(4), Eq(6)}))); +} + +TEST(ElementsAreArrayTest, TakesInitializerListOfDifferentTypedMatchers) { + const int a[5] = {1, 2, 3, 4, 5}; + // The compiler cannot infer the type of the initializer list if its + // elements have different types. We must explicitly specify the + // unified element type in this case. + EXPECT_THAT( + a, ElementsAreArray<Matcher<int>>({Eq(1), Ne(-2), Ge(3), Le(4), Eq(5)})); + EXPECT_THAT(a, Not(ElementsAreArray<Matcher<int>>( + {Eq(1), Ne(-2), Ge(3), Le(4), Eq(6)}))); +} + +TEST(ElementsAreArrayTest, CanBeCreatedWithMatcherVector) { + const int a[] = {1, 2, 3}; + const Matcher<int> kMatchers[] = {Eq(1), Eq(2), Eq(3)}; + vector<int> test_vector(std::begin(a), std::end(a)); + const vector<Matcher<int>> expected(std::begin(kMatchers), + std::end(kMatchers)); + EXPECT_THAT(test_vector, ElementsAreArray(expected)); + test_vector.push_back(4); + EXPECT_THAT(test_vector, Not(ElementsAreArray(expected))); +} + +TEST(ElementsAreArrayTest, CanBeCreatedWithIteratorRange) { + const int a[] = {1, 2, 3}; + const vector<int> test_vector(std::begin(a), std::end(a)); + const vector<int> expected(std::begin(a), std::end(a)); + EXPECT_THAT(test_vector, ElementsAreArray(expected.begin(), expected.end())); + // Pointers are iterators, too. + EXPECT_THAT(test_vector, ElementsAreArray(std::begin(a), std::end(a))); + // The empty range of NULL pointers should also be okay. + int* const null_int = nullptr; + EXPECT_THAT(test_vector, Not(ElementsAreArray(null_int, null_int))); + EXPECT_THAT((vector<int>()), ElementsAreArray(null_int, null_int)); +} + +// Since ElementsAre() and ElementsAreArray() share much of the +// implementation, we only do a sanity test for native arrays here. +TEST(ElementsAreArrayTest, WorksWithNativeArray) { + ::std::string a[] = {"hi", "ho"}; + ::std::string b[] = {"hi", "ho"}; + + EXPECT_THAT(a, ElementsAreArray(b)); + EXPECT_THAT(a, ElementsAreArray(b, 2)); + EXPECT_THAT(a, Not(ElementsAreArray(b, 1))); +} + +TEST(ElementsAreArrayTest, SourceLifeSpan) { + const int a[] = {1, 2, 3}; + vector<int> test_vector(std::begin(a), std::end(a)); + vector<int> expect(std::begin(a), std::end(a)); + ElementsAreArrayMatcher<int> matcher_maker = + ElementsAreArray(expect.begin(), expect.end()); + EXPECT_THAT(test_vector, matcher_maker); + // Changing in place the values that initialized matcher_maker should not + // affect matcher_maker anymore. It should have made its own copy of them. + for (int& i : expect) { + i += 10; + } + EXPECT_THAT(test_vector, matcher_maker); + test_vector.push_back(3); + EXPECT_THAT(test_vector, Not(matcher_maker)); +} + +// Tests for the MATCHER*() macro family. + +// Tests that a simple MATCHER() definition works. + +MATCHER(IsEven, "") { return (arg % 2) == 0; } + +TEST(MatcherMacroTest, Works) { + const Matcher<int> m = IsEven(); + EXPECT_TRUE(m.Matches(6)); + EXPECT_FALSE(m.Matches(7)); + + EXPECT_EQ("is even", Describe(m)); + EXPECT_EQ("not (is even)", DescribeNegation(m)); + EXPECT_EQ("", Explain(m, 6)); + EXPECT_EQ("", Explain(m, 7)); +} + +// This also tests that the description string can reference 'negation'. +MATCHER(IsEven2, negation ? "is odd" : "is even") { + if ((arg % 2) == 0) { + // Verifies that we can stream to result_listener, a listener + // supplied by the MATCHER macro implicitly. + *result_listener << "OK"; + return true; + } else { + *result_listener << "% 2 == " << (arg % 2); + return false; + } +} + +// This also tests that the description string can reference matcher +// parameters. +MATCHER_P2(EqSumOf, x, y, + std::string(negation ? "doesn't equal" : "equals") + " the sum of " + + PrintToString(x) + " and " + PrintToString(y)) { + if (arg == (x + y)) { + *result_listener << "OK"; + return true; + } else { + // Verifies that we can stream to the underlying stream of + // result_listener. + if (result_listener->stream() != nullptr) { + *result_listener->stream() << "diff == " << (x + y - arg); + } + return false; + } +} + +// Tests that the matcher description can reference 'negation' and the +// matcher parameters. +TEST(MatcherMacroTest, DescriptionCanReferenceNegationAndParameters) { + const Matcher<int> m1 = IsEven2(); + EXPECT_EQ("is even", Describe(m1)); + EXPECT_EQ("is odd", DescribeNegation(m1)); + + const Matcher<int> m2 = EqSumOf(5, 9); + EXPECT_EQ("equals the sum of 5 and 9", Describe(m2)); + EXPECT_EQ("doesn't equal the sum of 5 and 9", DescribeNegation(m2)); +} + +// Tests explaining match result in a MATCHER* macro. +TEST(MatcherMacroTest, CanExplainMatchResult) { + const Matcher<int> m1 = IsEven2(); + EXPECT_EQ("OK", Explain(m1, 4)); + EXPECT_EQ("% 2 == 1", Explain(m1, 5)); + + const Matcher<int> m2 = EqSumOf(1, 2); + EXPECT_EQ("OK", Explain(m2, 3)); + EXPECT_EQ("diff == -1", Explain(m2, 4)); +} + +// Tests that the body of MATCHER() can reference the type of the +// value being matched. + +MATCHER(IsEmptyString, "") { + StaticAssertTypeEq<::std::string, arg_type>(); + return arg.empty(); +} + +MATCHER(IsEmptyStringByRef, "") { + StaticAssertTypeEq<const ::std::string&, arg_type>(); + return arg.empty(); +} + +TEST(MatcherMacroTest, CanReferenceArgType) { + const Matcher<::std::string> m1 = IsEmptyString(); + EXPECT_TRUE(m1.Matches("")); + + const Matcher<const ::std::string&> m2 = IsEmptyStringByRef(); + EXPECT_TRUE(m2.Matches("")); +} + +// Tests that MATCHER() can be used in a namespace. + +namespace matcher_test { +MATCHER(IsOdd, "") { return (arg % 2) != 0; } +} // namespace matcher_test + +TEST(MatcherMacroTest, WorksInNamespace) { + Matcher<int> m = matcher_test::IsOdd(); + EXPECT_FALSE(m.Matches(4)); + EXPECT_TRUE(m.Matches(5)); +} + +// Tests that Value() can be used to compose matchers. +MATCHER(IsPositiveOdd, "") { + return Value(arg, matcher_test::IsOdd()) && arg > 0; +} + +TEST(MatcherMacroTest, CanBeComposedUsingValue) { + EXPECT_THAT(3, IsPositiveOdd()); + EXPECT_THAT(4, Not(IsPositiveOdd())); + EXPECT_THAT(-1, Not(IsPositiveOdd())); +} + +// Tests that a simple MATCHER_P() definition works. + +MATCHER_P(IsGreaterThan32And, n, "") { return arg > 32 && arg > n; } + +TEST(MatcherPMacroTest, Works) { + const Matcher<int> m = IsGreaterThan32And(5); + EXPECT_TRUE(m.Matches(36)); + EXPECT_FALSE(m.Matches(5)); + + EXPECT_EQ("is greater than 32 and 5", Describe(m)); + EXPECT_EQ("not (is greater than 32 and 5)", DescribeNegation(m)); + EXPECT_EQ("", Explain(m, 36)); + EXPECT_EQ("", Explain(m, 5)); +} + +// Tests that the description is calculated correctly from the matcher name. +MATCHER_P(_is_Greater_Than32and_, n, "") { return arg > 32 && arg > n; } + +TEST(MatcherPMacroTest, GeneratesCorrectDescription) { + const Matcher<int> m = _is_Greater_Than32and_(5); + + EXPECT_EQ("is greater than 32 and 5", Describe(m)); + EXPECT_EQ("not (is greater than 32 and 5)", DescribeNegation(m)); + EXPECT_EQ("", Explain(m, 36)); + EXPECT_EQ("", Explain(m, 5)); +} + +// Tests that a MATCHER_P matcher can be explicitly instantiated with +// a reference parameter type. + +class UncopyableFoo { + public: + explicit UncopyableFoo(char value) : value_(value) { (void)value_; } + + UncopyableFoo(const UncopyableFoo&) = delete; + void operator=(const UncopyableFoo&) = delete; + + private: + char value_; +}; + +MATCHER_P(ReferencesUncopyable, variable, "") { return &arg == &variable; } + +TEST(MatcherPMacroTest, WorksWhenExplicitlyInstantiatedWithReference) { + UncopyableFoo foo1('1'), foo2('2'); + const Matcher<const UncopyableFoo&> m = + ReferencesUncopyable<const UncopyableFoo&>(foo1); + + EXPECT_TRUE(m.Matches(foo1)); + EXPECT_FALSE(m.Matches(foo2)); + + // We don't want the address of the parameter printed, as most + // likely it will just annoy the user. If the address is + // interesting, the user should consider passing the parameter by + // pointer instead. + EXPECT_EQ("references uncopyable 1-byte object <31>", Describe(m)); +} + +// Tests that the body of MATCHER_Pn() can reference the parameter +// types. + +MATCHER_P3(ParamTypesAreIntLongAndChar, foo, bar, baz, "") { + StaticAssertTypeEq<int, foo_type>(); + StaticAssertTypeEq<long, bar_type>(); // NOLINT + StaticAssertTypeEq<char, baz_type>(); + return arg == 0; +} + +TEST(MatcherPnMacroTest, CanReferenceParamTypes) { + EXPECT_THAT(0, ParamTypesAreIntLongAndChar(10, 20L, 'a')); +} + +// Tests that a MATCHER_Pn matcher can be explicitly instantiated with +// reference parameter types. + +MATCHER_P2(ReferencesAnyOf, variable1, variable2, "") { + return &arg == &variable1 || &arg == &variable2; +} + +TEST(MatcherPnMacroTest, WorksWhenExplicitlyInstantiatedWithReferences) { + UncopyableFoo foo1('1'), foo2('2'), foo3('3'); + const Matcher<const UncopyableFoo&> const_m = + ReferencesAnyOf<const UncopyableFoo&, const UncopyableFoo&>(foo1, foo2); + + EXPECT_TRUE(const_m.Matches(foo1)); + EXPECT_TRUE(const_m.Matches(foo2)); + EXPECT_FALSE(const_m.Matches(foo3)); + + const Matcher<UncopyableFoo&> m = + ReferencesAnyOf<UncopyableFoo&, UncopyableFoo&>(foo1, foo2); + + EXPECT_TRUE(m.Matches(foo1)); + EXPECT_TRUE(m.Matches(foo2)); + EXPECT_FALSE(m.Matches(foo3)); +} + +TEST(MatcherPnMacroTest, + GeneratesCorretDescriptionWhenExplicitlyInstantiatedWithReferences) { + UncopyableFoo foo1('1'), foo2('2'); + const Matcher<const UncopyableFoo&> m = + ReferencesAnyOf<const UncopyableFoo&, const UncopyableFoo&>(foo1, foo2); + + // We don't want the addresses of the parameters printed, as most + // likely they will just annoy the user. If the addresses are + // interesting, the user should consider passing the parameters by + // pointers instead. + EXPECT_EQ("references any of (1-byte object <31>, 1-byte object <32>)", + Describe(m)); +} + +// Tests that a simple MATCHER_P2() definition works. + +MATCHER_P2(IsNotInClosedRange, low, hi, "") { return arg < low || arg > hi; } + +TEST(MatcherPnMacroTest, Works) { + const Matcher<const long&> m = IsNotInClosedRange(10, 20); // NOLINT + EXPECT_TRUE(m.Matches(36L)); + EXPECT_FALSE(m.Matches(15L)); + + EXPECT_EQ("is not in closed range (10, 20)", Describe(m)); + EXPECT_EQ("not (is not in closed range (10, 20))", DescribeNegation(m)); + EXPECT_EQ("", Explain(m, 36L)); + EXPECT_EQ("", Explain(m, 15L)); +} + +// Tests that MATCHER*() definitions can be overloaded on the number +// of parameters; also tests MATCHER_Pn() where n >= 3. + +MATCHER(EqualsSumOf, "") { return arg == 0; } +MATCHER_P(EqualsSumOf, a, "") { return arg == a; } +MATCHER_P2(EqualsSumOf, a, b, "") { return arg == a + b; } +MATCHER_P3(EqualsSumOf, a, b, c, "") { return arg == a + b + c; } +MATCHER_P4(EqualsSumOf, a, b, c, d, "") { return arg == a + b + c + d; } +MATCHER_P5(EqualsSumOf, a, b, c, d, e, "") { return arg == a + b + c + d + e; } +MATCHER_P6(EqualsSumOf, a, b, c, d, e, f, "") { + return arg == a + b + c + d + e + f; +} +MATCHER_P7(EqualsSumOf, a, b, c, d, e, f, g, "") { + return arg == a + b + c + d + e + f + g; +} +MATCHER_P8(EqualsSumOf, a, b, c, d, e, f, g, h, "") { + return arg == a + b + c + d + e + f + g + h; +} +MATCHER_P9(EqualsSumOf, a, b, c, d, e, f, g, h, i, "") { + return arg == a + b + c + d + e + f + g + h + i; +} +MATCHER_P10(EqualsSumOf, a, b, c, d, e, f, g, h, i, j, "") { + return arg == a + b + c + d + e + f + g + h + i + j; +} + +TEST(MatcherPnMacroTest, CanBeOverloadedOnNumberOfParameters) { + EXPECT_THAT(0, EqualsSumOf()); + EXPECT_THAT(1, EqualsSumOf(1)); + EXPECT_THAT(12, EqualsSumOf(10, 2)); + EXPECT_THAT(123, EqualsSumOf(100, 20, 3)); + EXPECT_THAT(1234, EqualsSumOf(1000, 200, 30, 4)); + EXPECT_THAT(12345, EqualsSumOf(10000, 2000, 300, 40, 5)); + EXPECT_THAT("abcdef", + EqualsSumOf(::std::string("a"), 'b', 'c', "d", "e", 'f')); + EXPECT_THAT("abcdefg", + EqualsSumOf(::std::string("a"), 'b', 'c', "d", "e", 'f', 'g')); + EXPECT_THAT("abcdefgh", EqualsSumOf(::std::string("a"), 'b', 'c', "d", "e", + 'f', 'g', "h")); + EXPECT_THAT("abcdefghi", EqualsSumOf(::std::string("a"), 'b', 'c', "d", "e", + 'f', 'g', "h", 'i')); + EXPECT_THAT("abcdefghij", + EqualsSumOf(::std::string("a"), 'b', 'c', "d", "e", 'f', 'g', "h", + 'i', ::std::string("j"))); + + EXPECT_THAT(1, Not(EqualsSumOf())); + EXPECT_THAT(-1, Not(EqualsSumOf(1))); + EXPECT_THAT(-12, Not(EqualsSumOf(10, 2))); + EXPECT_THAT(-123, Not(EqualsSumOf(100, 20, 3))); + EXPECT_THAT(-1234, Not(EqualsSumOf(1000, 200, 30, 4))); + EXPECT_THAT(-12345, Not(EqualsSumOf(10000, 2000, 300, 40, 5))); + EXPECT_THAT("abcdef ", + Not(EqualsSumOf(::std::string("a"), 'b', 'c', "d", "e", 'f'))); + EXPECT_THAT("abcdefg ", Not(EqualsSumOf(::std::string("a"), 'b', 'c', "d", + "e", 'f', 'g'))); + EXPECT_THAT("abcdefgh ", Not(EqualsSumOf(::std::string("a"), 'b', 'c', "d", + "e", 'f', 'g', "h"))); + EXPECT_THAT("abcdefghi ", Not(EqualsSumOf(::std::string("a"), 'b', 'c', "d", + "e", 'f', 'g', "h", 'i'))); + EXPECT_THAT("abcdefghij ", + Not(EqualsSumOf(::std::string("a"), 'b', 'c', "d", "e", 'f', 'g', + "h", 'i', ::std::string("j")))); +} + +// Tests that a MATCHER_Pn() definition can be instantiated with any +// compatible parameter types. +TEST(MatcherPnMacroTest, WorksForDifferentParameterTypes) { + EXPECT_THAT(123, EqualsSumOf(100L, 20, static_cast<char>(3))); + EXPECT_THAT("abcd", EqualsSumOf(::std::string("a"), "b", 'c', "d")); + + EXPECT_THAT(124, Not(EqualsSumOf(100L, 20, static_cast<char>(3)))); + EXPECT_THAT("abcde", Not(EqualsSumOf(::std::string("a"), "b", 'c', "d"))); +} + +// Tests that the matcher body can promote the parameter types. + +MATCHER_P2(EqConcat, prefix, suffix, "") { + // The following lines promote the two parameters to desired types. + std::string prefix_str(prefix); + char suffix_char = static_cast<char>(suffix); + return arg == prefix_str + suffix_char; +} + +TEST(MatcherPnMacroTest, SimpleTypePromotion) { + Matcher<std::string> no_promo = EqConcat(std::string("foo"), 't'); + Matcher<const std::string&> promo = EqConcat("foo", static_cast<int>('t')); + EXPECT_FALSE(no_promo.Matches("fool")); + EXPECT_FALSE(promo.Matches("fool")); + EXPECT_TRUE(no_promo.Matches("foot")); + EXPECT_TRUE(promo.Matches("foot")); +} + +// Verifies the type of a MATCHER*. + +TEST(MatcherPnMacroTest, TypesAreCorrect) { + // EqualsSumOf() must be assignable to a EqualsSumOfMatcher variable. + EqualsSumOfMatcher a0 = EqualsSumOf(); + + // EqualsSumOf(1) must be assignable to a EqualsSumOfMatcherP variable. + EqualsSumOfMatcherP<int> a1 = EqualsSumOf(1); + + // EqualsSumOf(p1, ..., pk) must be assignable to a EqualsSumOfMatcherPk + // variable, and so on. + EqualsSumOfMatcherP2<int, char> a2 = EqualsSumOf(1, '2'); + EqualsSumOfMatcherP3<int, int, char> a3 = EqualsSumOf(1, 2, '3'); + EqualsSumOfMatcherP4<int, int, int, char> a4 = EqualsSumOf(1, 2, 3, '4'); + EqualsSumOfMatcherP5<int, int, int, int, char> a5 = + EqualsSumOf(1, 2, 3, 4, '5'); + EqualsSumOfMatcherP6<int, int, int, int, int, char> a6 = + EqualsSumOf(1, 2, 3, 4, 5, '6'); + EqualsSumOfMatcherP7<int, int, int, int, int, int, char> a7 = + EqualsSumOf(1, 2, 3, 4, 5, 6, '7'); + EqualsSumOfMatcherP8<int, int, int, int, int, int, int, char> a8 = + EqualsSumOf(1, 2, 3, 4, 5, 6, 7, '8'); + EqualsSumOfMatcherP9<int, int, int, int, int, int, int, int, char> a9 = + EqualsSumOf(1, 2, 3, 4, 5, 6, 7, 8, '9'); + EqualsSumOfMatcherP10<int, int, int, int, int, int, int, int, int, char> a10 = + EqualsSumOf(1, 2, 3, 4, 5, 6, 7, 8, 9, '0'); + + // Avoid "unused variable" warnings. + (void)a0; + (void)a1; + (void)a2; + (void)a3; + (void)a4; + (void)a5; + (void)a6; + (void)a7; + (void)a8; + (void)a9; + (void)a10; +} + +// Tests that matcher-typed parameters can be used in Value() inside a +// MATCHER_Pn definition. + +// Succeeds if arg matches exactly 2 of the 3 matchers. +MATCHER_P3(TwoOf, m1, m2, m3, "") { + const int count = static_cast<int>(Value(arg, m1)) + + static_cast<int>(Value(arg, m2)) + + static_cast<int>(Value(arg, m3)); + return count == 2; +} + +TEST(MatcherPnMacroTest, CanUseMatcherTypedParameterInValue) { + EXPECT_THAT(42, TwoOf(Gt(0), Lt(50), Eq(10))); + EXPECT_THAT(0, Not(TwoOf(Gt(-1), Lt(1), Eq(0)))); +} + +// Tests Contains(). + +TEST(ContainsTest, ListMatchesWhenElementIsInContainer) { + list<int> some_list; + some_list.push_back(3); + some_list.push_back(1); + some_list.push_back(2); + EXPECT_THAT(some_list, Contains(1)); + EXPECT_THAT(some_list, Contains(Gt(2.5))); + EXPECT_THAT(some_list, Contains(Eq(2.0f))); + + list<std::string> another_list; + another_list.push_back("fee"); + another_list.push_back("fie"); + another_list.push_back("foe"); + another_list.push_back("fum"); + EXPECT_THAT(another_list, Contains(std::string("fee"))); +} + +TEST(ContainsTest, ListDoesNotMatchWhenElementIsNotInContainer) { + list<int> some_list; + some_list.push_back(3); + some_list.push_back(1); + EXPECT_THAT(some_list, Not(Contains(4))); +} + +TEST(ContainsTest, SetMatchesWhenElementIsInContainer) { + set<int> some_set; + some_set.insert(3); + some_set.insert(1); + some_set.insert(2); + EXPECT_THAT(some_set, Contains(Eq(1.0))); + EXPECT_THAT(some_set, Contains(Eq(3.0f))); + EXPECT_THAT(some_set, Contains(2)); + + set<std::string> another_set; + another_set.insert("fee"); + another_set.insert("fie"); + another_set.insert("foe"); + another_set.insert("fum"); + EXPECT_THAT(another_set, Contains(Eq(std::string("fum")))); +} + +TEST(ContainsTest, SetDoesNotMatchWhenElementIsNotInContainer) { + set<int> some_set; + some_set.insert(3); + some_set.insert(1); + EXPECT_THAT(some_set, Not(Contains(4))); + + set<std::string> c_string_set; + c_string_set.insert("hello"); + EXPECT_THAT(c_string_set, Not(Contains(std::string("goodbye")))); +} + +TEST(ContainsTest, ExplainsMatchResultCorrectly) { + const int a[2] = {1, 2}; + Matcher<const int(&)[2]> m = Contains(2); + EXPECT_EQ("whose element #1 matches", Explain(m, a)); + + m = Contains(3); + EXPECT_EQ("", Explain(m, a)); + + m = Contains(GreaterThan(0)); + EXPECT_EQ("whose element #0 matches, which is 1 more than 0", Explain(m, a)); + + m = Contains(GreaterThan(10)); + EXPECT_EQ("", Explain(m, a)); +} + +TEST(ContainsTest, DescribesItselfCorrectly) { + Matcher<vector<int>> m = Contains(1); + EXPECT_EQ("contains at least one element that is equal to 1", Describe(m)); + + Matcher<vector<int>> m2 = Not(m); + EXPECT_EQ("doesn't contain any element that is equal to 1", Describe(m2)); +} + +TEST(ContainsTest, MapMatchesWhenElementIsInContainer) { + map<std::string, int> my_map; + const char* bar = "a string"; + my_map[bar] = 2; + EXPECT_THAT(my_map, Contains(pair<const char* const, int>(bar, 2))); + + map<std::string, int> another_map; + another_map["fee"] = 1; + another_map["fie"] = 2; + another_map["foe"] = 3; + another_map["fum"] = 4; + EXPECT_THAT(another_map, + Contains(pair<const std::string, int>(std::string("fee"), 1))); + EXPECT_THAT(another_map, Contains(pair<const std::string, int>("fie", 2))); +} + +TEST(ContainsTest, MapDoesNotMatchWhenElementIsNotInContainer) { + map<int, int> some_map; + some_map[1] = 11; + some_map[2] = 22; + EXPECT_THAT(some_map, Not(Contains(pair<const int, int>(2, 23)))); +} + +TEST(ContainsTest, ArrayMatchesWhenElementIsInContainer) { + const char* string_array[] = {"fee", "fie", "foe", "fum"}; + EXPECT_THAT(string_array, Contains(Eq(std::string("fum")))); +} + +TEST(ContainsTest, ArrayDoesNotMatchWhenElementIsNotInContainer) { + int int_array[] = {1, 2, 3, 4}; + EXPECT_THAT(int_array, Not(Contains(5))); +} + +TEST(ContainsTest, AcceptsMatcher) { + const int a[] = {1, 2, 3}; + EXPECT_THAT(a, Contains(Gt(2))); + EXPECT_THAT(a, Not(Contains(Gt(4)))); +} + +TEST(ContainsTest, WorksForNativeArrayAsTuple) { + const int a[] = {1, 2}; + const int* const pointer = a; + EXPECT_THAT(std::make_tuple(pointer, 2), Contains(1)); + EXPECT_THAT(std::make_tuple(pointer, 2), Not(Contains(Gt(3)))); +} + +TEST(ContainsTest, WorksForTwoDimensionalNativeArray) { + int a[][3] = {{1, 2, 3}, {4, 5, 6}}; + EXPECT_THAT(a, Contains(ElementsAre(4, 5, 6))); + EXPECT_THAT(a, Contains(Contains(5))); + EXPECT_THAT(a, Not(Contains(ElementsAre(3, 4, 5)))); + EXPECT_THAT(a, Contains(Not(Contains(5)))); +} + +TEST(AllOfArrayTest, BasicForms) { + // Iterator + std::vector<int> v0{}; + std::vector<int> v1{1}; + std::vector<int> v2{2, 3}; + std::vector<int> v3{4, 4, 4}; + EXPECT_THAT(0, AllOfArray(v0.begin(), v0.end())); + EXPECT_THAT(1, AllOfArray(v1.begin(), v1.end())); + EXPECT_THAT(2, Not(AllOfArray(v1.begin(), v1.end()))); + EXPECT_THAT(3, Not(AllOfArray(v2.begin(), v2.end()))); + EXPECT_THAT(4, AllOfArray(v3.begin(), v3.end())); + // Pointer + size + int ar[6] = {1, 2, 3, 4, 4, 4}; + EXPECT_THAT(0, AllOfArray(ar, 0)); + EXPECT_THAT(1, AllOfArray(ar, 1)); + EXPECT_THAT(2, Not(AllOfArray(ar, 1))); + EXPECT_THAT(3, Not(AllOfArray(ar + 1, 3))); + EXPECT_THAT(4, AllOfArray(ar + 3, 3)); + // Array + // int ar0[0]; Not usable + int ar1[1] = {1}; + int ar2[2] = {2, 3}; + int ar3[3] = {4, 4, 4}; + // EXPECT_THAT(0, Not(AllOfArray(ar0))); // Cannot work + EXPECT_THAT(1, AllOfArray(ar1)); + EXPECT_THAT(2, Not(AllOfArray(ar1))); + EXPECT_THAT(3, Not(AllOfArray(ar2))); + EXPECT_THAT(4, AllOfArray(ar3)); + // Container + EXPECT_THAT(0, AllOfArray(v0)); + EXPECT_THAT(1, AllOfArray(v1)); + EXPECT_THAT(2, Not(AllOfArray(v1))); + EXPECT_THAT(3, Not(AllOfArray(v2))); + EXPECT_THAT(4, AllOfArray(v3)); + // Initializer + EXPECT_THAT(0, AllOfArray<int>({})); // Requires template arg. + EXPECT_THAT(1, AllOfArray({1})); + EXPECT_THAT(2, Not(AllOfArray({1}))); + EXPECT_THAT(3, Not(AllOfArray({2, 3}))); + EXPECT_THAT(4, AllOfArray({4, 4, 4})); +} + +TEST(AllOfArrayTest, Matchers) { + // vector + std::vector<Matcher<int>> matchers{Ge(1), Lt(2)}; + EXPECT_THAT(0, Not(AllOfArray(matchers))); + EXPECT_THAT(1, AllOfArray(matchers)); + EXPECT_THAT(2, Not(AllOfArray(matchers))); + // initializer_list + EXPECT_THAT(0, Not(AllOfArray({Ge(0), Ge(1)}))); + EXPECT_THAT(1, AllOfArray({Ge(0), Ge(1)})); +} + +TEST(AnyOfArrayTest, BasicForms) { + // Iterator + std::vector<int> v0{}; + std::vector<int> v1{1}; + std::vector<int> v2{2, 3}; + EXPECT_THAT(0, Not(AnyOfArray(v0.begin(), v0.end()))); + EXPECT_THAT(1, AnyOfArray(v1.begin(), v1.end())); + EXPECT_THAT(2, Not(AnyOfArray(v1.begin(), v1.end()))); + EXPECT_THAT(3, AnyOfArray(v2.begin(), v2.end())); + EXPECT_THAT(4, Not(AnyOfArray(v2.begin(), v2.end()))); + // Pointer + size + int ar[3] = {1, 2, 3}; + EXPECT_THAT(0, Not(AnyOfArray(ar, 0))); + EXPECT_THAT(1, AnyOfArray(ar, 1)); + EXPECT_THAT(2, Not(AnyOfArray(ar, 1))); + EXPECT_THAT(3, AnyOfArray(ar + 1, 2)); + EXPECT_THAT(4, Not(AnyOfArray(ar + 1, 2))); + // Array + // int ar0[0]; Not usable + int ar1[1] = {1}; + int ar2[2] = {2, 3}; + // EXPECT_THAT(0, Not(AnyOfArray(ar0))); // Cannot work + EXPECT_THAT(1, AnyOfArray(ar1)); + EXPECT_THAT(2, Not(AnyOfArray(ar1))); + EXPECT_THAT(3, AnyOfArray(ar2)); + EXPECT_THAT(4, Not(AnyOfArray(ar2))); + // Container + EXPECT_THAT(0, Not(AnyOfArray(v0))); + EXPECT_THAT(1, AnyOfArray(v1)); + EXPECT_THAT(2, Not(AnyOfArray(v1))); + EXPECT_THAT(3, AnyOfArray(v2)); + EXPECT_THAT(4, Not(AnyOfArray(v2))); + // Initializer + EXPECT_THAT(0, Not(AnyOfArray<int>({}))); // Requires template arg. + EXPECT_THAT(1, AnyOfArray({1})); + EXPECT_THAT(2, Not(AnyOfArray({1}))); + EXPECT_THAT(3, AnyOfArray({2, 3})); + EXPECT_THAT(4, Not(AnyOfArray({2, 3}))); +} + +TEST(AnyOfArrayTest, Matchers) { + // We negate test AllOfArrayTest.Matchers. + // vector + std::vector<Matcher<int>> matchers{Lt(1), Ge(2)}; + EXPECT_THAT(0, AnyOfArray(matchers)); + EXPECT_THAT(1, Not(AnyOfArray(matchers))); + EXPECT_THAT(2, AnyOfArray(matchers)); + // initializer_list + EXPECT_THAT(0, AnyOfArray({Lt(0), Lt(1)})); + EXPECT_THAT(1, Not(AllOfArray({Lt(0), Lt(1)}))); +} + +TEST(AnyOfArrayTest, ExplainsMatchResultCorrectly) { + // AnyOfArray and AllOfArry use the same underlying template-template, + // thus it is sufficient to test one here. + const std::vector<int> v0{}; + const std::vector<int> v1{1}; + const std::vector<int> v2{2, 3}; + const Matcher<int> m0 = AnyOfArray(v0); + const Matcher<int> m1 = AnyOfArray(v1); + const Matcher<int> m2 = AnyOfArray(v2); + EXPECT_EQ("", Explain(m0, 0)); + EXPECT_EQ("", Explain(m1, 1)); + EXPECT_EQ("", Explain(m1, 2)); + EXPECT_EQ("", Explain(m2, 3)); + EXPECT_EQ("", Explain(m2, 4)); + EXPECT_EQ("()", Describe(m0)); + EXPECT_EQ("(is equal to 1)", Describe(m1)); + EXPECT_EQ("(is equal to 2) or (is equal to 3)", Describe(m2)); + EXPECT_EQ("()", DescribeNegation(m0)); + EXPECT_EQ("(isn't equal to 1)", DescribeNegation(m1)); + EXPECT_EQ("(isn't equal to 2) and (isn't equal to 3)", DescribeNegation(m2)); + // Explain with matchers + const Matcher<int> g1 = AnyOfArray({GreaterThan(1)}); + const Matcher<int> g2 = AnyOfArray({GreaterThan(1), GreaterThan(2)}); + // Explains the first positiv match and all prior negative matches... + EXPECT_EQ("which is 1 less than 1", Explain(g1, 0)); + EXPECT_EQ("which is the same as 1", Explain(g1, 1)); + EXPECT_EQ("which is 1 more than 1", Explain(g1, 2)); + EXPECT_EQ("which is 1 less than 1, and which is 2 less than 2", + Explain(g2, 0)); + EXPECT_EQ("which is the same as 1, and which is 1 less than 2", + Explain(g2, 1)); + EXPECT_EQ("which is 1 more than 1", // Only the first + Explain(g2, 2)); +} + +TEST(AllOfTest, HugeMatcher) { + // Verify that using AllOf with many arguments doesn't cause + // the compiler to exceed template instantiation depth limit. + EXPECT_THAT(0, testing::AllOf(_, _, _, _, _, _, _, _, _, + testing::AllOf(_, _, _, _, _, _, _, _, _, _))); +} + +TEST(AnyOfTest, HugeMatcher) { + // Verify that using AnyOf with many arguments doesn't cause + // the compiler to exceed template instantiation depth limit. + EXPECT_THAT(0, testing::AnyOf(_, _, _, _, _, _, _, _, _, + testing::AnyOf(_, _, _, _, _, _, _, _, _, _))); +} + +namespace adl_test { + +// Verifies that the implementation of ::testing::AllOf and ::testing::AnyOf +// don't issue unqualified recursive calls. If they do, the argument dependent +// name lookup will cause AllOf/AnyOf in the 'adl_test' namespace to be found +// as a candidate and the compilation will break due to an ambiguous overload. + +// The matcher must be in the same namespace as AllOf/AnyOf to make argument +// dependent lookup find those. +MATCHER(M, "") { + (void)arg; + return true; +} + +template <typename T1, typename T2> +bool AllOf(const T1& /*t1*/, const T2& /*t2*/) { + return true; +} + +TEST(AllOfTest, DoesNotCallAllOfUnqualified) { + EXPECT_THAT(42, + testing::AllOf(M(), M(), M(), M(), M(), M(), M(), M(), M(), M())); +} + +template <typename T1, typename T2> +bool AnyOf(const T1&, const T2&) { + return true; +} + +TEST(AnyOfTest, DoesNotCallAnyOfUnqualified) { + EXPECT_THAT(42, + testing::AnyOf(M(), M(), M(), M(), M(), M(), M(), M(), M(), M())); +} + +} // namespace adl_test + +TEST(AllOfTest, WorksOnMoveOnlyType) { + std::unique_ptr<int> p(new int(3)); + EXPECT_THAT(p, AllOf(Pointee(Eq(3)), Pointee(Gt(0)), Pointee(Lt(5)))); + EXPECT_THAT(p, Not(AllOf(Pointee(Eq(3)), Pointee(Gt(0)), Pointee(Lt(3))))); +} + +TEST(AnyOfTest, WorksOnMoveOnlyType) { + std::unique_ptr<int> p(new int(3)); + EXPECT_THAT(p, AnyOf(Pointee(Eq(5)), Pointee(Lt(0)), Pointee(Lt(5)))); + EXPECT_THAT(p, Not(AnyOf(Pointee(Eq(5)), Pointee(Lt(0)), Pointee(Gt(5))))); +} + +MATCHER(IsNotNull, "") { return arg != nullptr; } + +// Verifies that a matcher defined using MATCHER() can work on +// move-only types. +TEST(MatcherMacroTest, WorksOnMoveOnlyType) { + std::unique_ptr<int> p(new int(3)); + EXPECT_THAT(p, IsNotNull()); + EXPECT_THAT(std::unique_ptr<int>(), Not(IsNotNull())); +} + +MATCHER_P(UniquePointee, pointee, "") { return *arg == pointee; } + +// Verifies that a matcher defined using MATCHER_P*() can work on +// move-only types. +TEST(MatcherPMacroTest, WorksOnMoveOnlyType) { + std::unique_ptr<int> p(new int(3)); + EXPECT_THAT(p, UniquePointee(3)); + EXPECT_THAT(p, Not(UniquePointee(2))); +} + +#if GTEST_HAS_EXCEPTIONS + +// std::function<void()> is used below for compatibility with older copies of +// GCC. Normally, a raw lambda is all that is needed. + +// Test that examples from documentation compile +TEST(ThrowsTest, Examples) { + EXPECT_THAT( + std::function<void()>([]() { throw std::runtime_error("message"); }), + Throws<std::runtime_error>()); + + EXPECT_THAT( + std::function<void()>([]() { throw std::runtime_error("message"); }), + ThrowsMessage<std::runtime_error>(HasSubstr("message"))); +} + +TEST(ThrowsTest, DoesNotGenerateDuplicateCatchClauseWarning) { + EXPECT_THAT(std::function<void()>([]() { throw std::exception(); }), + Throws<std::exception>()); +} + +TEST(ThrowsTest, CallableExecutedExactlyOnce) { + size_t a = 0; + + EXPECT_THAT(std::function<void()>([&a]() { + a++; + throw 10; + }), + Throws<int>()); + EXPECT_EQ(a, 1u); + + EXPECT_THAT(std::function<void()>([&a]() { + a++; + throw std::runtime_error("message"); + }), + Throws<std::runtime_error>()); + EXPECT_EQ(a, 2u); + + EXPECT_THAT(std::function<void()>([&a]() { + a++; + throw std::runtime_error("message"); + }), + ThrowsMessage<std::runtime_error>(HasSubstr("message"))); + EXPECT_EQ(a, 3u); + + EXPECT_THAT(std::function<void()>([&a]() { + a++; + throw std::runtime_error("message"); + }), + Throws<std::runtime_error>( + Property(&std::runtime_error::what, HasSubstr("message")))); + EXPECT_EQ(a, 4u); +} + +TEST(ThrowsTest, Describe) { + Matcher<std::function<void()>> matcher = Throws<std::runtime_error>(); + std::stringstream ss; + matcher.DescribeTo(&ss); + auto explanation = ss.str(); + EXPECT_THAT(explanation, HasSubstr("std::runtime_error")); +} + +TEST(ThrowsTest, Success) { + Matcher<std::function<void()>> matcher = Throws<std::runtime_error>(); + StringMatchResultListener listener; + EXPECT_TRUE(matcher.MatchAndExplain( + []() { throw std::runtime_error("error message"); }, &listener)); + EXPECT_THAT(listener.str(), HasSubstr("std::runtime_error")); +} + +TEST(ThrowsTest, FailWrongType) { + Matcher<std::function<void()>> matcher = Throws<std::runtime_error>(); + StringMatchResultListener listener; + EXPECT_FALSE(matcher.MatchAndExplain( + []() { throw std::logic_error("error message"); }, &listener)); + EXPECT_THAT(listener.str(), HasSubstr("std::logic_error")); + EXPECT_THAT(listener.str(), HasSubstr("\"error message\"")); +} + +TEST(ThrowsTest, FailWrongTypeNonStd) { + Matcher<std::function<void()>> matcher = Throws<std::runtime_error>(); + StringMatchResultListener listener; + EXPECT_FALSE(matcher.MatchAndExplain([]() { throw 10; }, &listener)); + EXPECT_THAT(listener.str(), + HasSubstr("throws an exception of an unknown type")); +} + +TEST(ThrowsTest, FailNoThrow) { + Matcher<std::function<void()>> matcher = Throws<std::runtime_error>(); + StringMatchResultListener listener; + EXPECT_FALSE(matcher.MatchAndExplain([]() { (void)0; }, &listener)); + EXPECT_THAT(listener.str(), HasSubstr("does not throw any exception")); +} + +class ThrowsPredicateTest + : public TestWithParam<Matcher<std::function<void()>>> {}; + +TEST_P(ThrowsPredicateTest, Describe) { + Matcher<std::function<void()>> matcher = GetParam(); + std::stringstream ss; + matcher.DescribeTo(&ss); + auto explanation = ss.str(); + EXPECT_THAT(explanation, HasSubstr("std::runtime_error")); + EXPECT_THAT(explanation, HasSubstr("error message")); +} + +TEST_P(ThrowsPredicateTest, Success) { + Matcher<std::function<void()>> matcher = GetParam(); + StringMatchResultListener listener; + EXPECT_TRUE(matcher.MatchAndExplain( + []() { throw std::runtime_error("error message"); }, &listener)); + EXPECT_THAT(listener.str(), HasSubstr("std::runtime_error")); +} + +TEST_P(ThrowsPredicateTest, FailWrongType) { + Matcher<std::function<void()>> matcher = GetParam(); + StringMatchResultListener listener; + EXPECT_FALSE(matcher.MatchAndExplain( + []() { throw std::logic_error("error message"); }, &listener)); + EXPECT_THAT(listener.str(), HasSubstr("std::logic_error")); + EXPECT_THAT(listener.str(), HasSubstr("\"error message\"")); +} + +TEST_P(ThrowsPredicateTest, FailWrongTypeNonStd) { + Matcher<std::function<void()>> matcher = GetParam(); + StringMatchResultListener listener; + EXPECT_FALSE(matcher.MatchAndExplain([]() { throw 10; }, &listener)); + EXPECT_THAT(listener.str(), + HasSubstr("throws an exception of an unknown type")); +} + +TEST_P(ThrowsPredicateTest, FailWrongMessage) { + Matcher<std::function<void()>> matcher = GetParam(); + StringMatchResultListener listener; + EXPECT_FALSE(matcher.MatchAndExplain( + []() { throw std::runtime_error("wrong message"); }, &listener)); + EXPECT_THAT(listener.str(), HasSubstr("std::runtime_error")); + EXPECT_THAT(listener.str(), Not(HasSubstr("wrong message"))); +} + +TEST_P(ThrowsPredicateTest, FailNoThrow) { + Matcher<std::function<void()>> matcher = GetParam(); + StringMatchResultListener listener; + EXPECT_FALSE(matcher.MatchAndExplain([]() {}, &listener)); + EXPECT_THAT(listener.str(), HasSubstr("does not throw any exception")); +} + +INSTANTIATE_TEST_SUITE_P( + AllMessagePredicates, ThrowsPredicateTest, + Values(Matcher<std::function<void()>>( + ThrowsMessage<std::runtime_error>(HasSubstr("error message"))))); + +// Tests that Throws<E1>(Matcher<E2>{}) compiles even when E2 != const E1&. +TEST(ThrowsPredicateCompilesTest, ExceptionMatcherAcceptsBroadType) { + { + Matcher<std::function<void()>> matcher = + ThrowsMessage<std::runtime_error>(HasSubstr("error message")); + EXPECT_TRUE( + matcher.Matches([]() { throw std::runtime_error("error message"); })); + EXPECT_FALSE( + matcher.Matches([]() { throw std::runtime_error("wrong message"); })); + } + + { + Matcher<uint64_t> inner = Eq(10); + Matcher<std::function<void()>> matcher = Throws<uint32_t>(inner); + EXPECT_TRUE(matcher.Matches([]() { throw(uint32_t) 10; })); + EXPECT_FALSE(matcher.Matches([]() { throw(uint32_t) 11; })); + } +} + +// Tests that ThrowsMessage("message") is equivalent +// to ThrowsMessage(Eq<std::string>("message")). +TEST(ThrowsPredicateCompilesTest, MessageMatcherAcceptsNonMatcher) { + Matcher<std::function<void()>> matcher = + ThrowsMessage<std::runtime_error>("error message"); + EXPECT_TRUE( + matcher.Matches([]() { throw std::runtime_error("error message"); })); + EXPECT_FALSE(matcher.Matches( + []() { throw std::runtime_error("wrong error message"); })); +} + +#endif // GTEST_HAS_EXCEPTIONS + +} // namespace +} // namespace gmock_matchers_test +} // namespace testing + +#ifdef _MSC_VER +# pragma warning(pop) +#endif diff --git a/src/googletest/googlemock/test/gmock-more-actions_test.cc b/src/googletest/googlemock/test/gmock-more-actions_test.cc new file mode 100644 index 000000000..4bcb5df6b --- /dev/null +++ b/src/googletest/googlemock/test/gmock-more-actions_test.cc @@ -0,0 +1,725 @@ +// 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. + +// Google Mock - a framework for writing C++ mock classes. +// +// This file tests the built-in actions in gmock-actions.h. + +#include <functional> +#include <memory> +#include <sstream> +#include <string> + +#include "gmock/gmock-actions.h" +#include "gmock/gmock.h" +#include "gtest/gtest-spi.h" +#include "gtest/gtest.h" + +namespace testing { +namespace gmock_more_actions_test { + +using ::std::plus; +using ::std::string; +using testing::_; +using testing::Action; +using testing::ActionInterface; +using testing::DeleteArg; +using testing::Invoke; +using testing::Return; +using testing::ReturnArg; +using testing::ReturnPointee; +using testing::SaveArg; +using testing::SaveArgPointee; +using testing::SetArgReferee; +using testing::Unused; +using testing::WithArg; +using testing::WithoutArgs; + +// For suppressing compiler warnings on conversion possibly losing precision. +inline short Short(short n) { return n; } // NOLINT +inline char Char(char ch) { return ch; } + +// Sample functions and functors for testing 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; } + +int SumOfFirst2(int a, int b, Unused, Unused) { return a + b; } + +void VoidFunctionWithFourArguments(char, int, float, double) { g_done = true; } + +std::string Concat4(const char* s1, const char* s2, const char* s3, + const char* s4) { + return std::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; + } +}; + +std::string Concat5(const char* s1, const char* s2, const char* s3, + const char* s4, const char* s5) { + return std::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; + } +}; + +std::string Concat6(const char* s1, const char* s2, const char* s3, + const char* s4, const char* s5, const char* s6) { + return std::string(s1) + s2 + s3 + s4 + s5 + s6; +} + +std::string Concat7(const char* s1, const char* s2, const char* s3, + const char* s4, const char* s5, const char* s6, + const char* s7) { + return std::string(s1) + s2 + s3 + s4 + s5 + s6 + s7; +} + +std::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 std::string(s1) + s2 + s3 + s4 + s5 + s6 + s7 + s8; +} + +std::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 std::string(s1) + s2 + s3 + s4 + s5 + s6 + s7 + s8 + s9; +} + +std::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 std::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 + + 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 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; + } + + std::string Concat7(const char* s1, const char* s2, const char* s3, + const char* s4, const char* s5, const char* s6, + const char* s7) { + return std::string(s1) + s2 + s3 + s4 + s5 + s6 + s7; + } + + std::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 std::string(s1) + s2 + s3 + s4 + s5 + s6 + s7 + s8; + } + + std::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 std::string(s1) + s2 + s3 + s4 + s5 + s6 + s7 + s8 + s9; + } + + std::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 std::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(std::make_tuple())); +} + +// Tests using Invoke() with a unary function. +TEST(InvokeTest, Unary) { + Action<bool(int)> a = Invoke(Unary); // NOLINT + EXPECT_FALSE(a.Perform(std::make_tuple(1))); + EXPECT_TRUE(a.Perform(std::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(std::make_tuple(p, Short(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(std::make_tuple(1, '\2', Short(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(std::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(std::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(std::make_tuple(100000, 20000, 3000, 400, 50, 6))); +} + +// A helper that turns the type of a C-string literal from const +// char[N] to const char*. +inline const char* CharPtr(const char* s) { return s; } + +// Tests using Invoke() with a 7-argument function. +TEST(InvokeTest, FunctionThatTakes7Arguments) { + Action<std::string(const char*, const char*, const char*, const char*, + const char*, const char*, const char*)> + a = Invoke(Concat7); + EXPECT_EQ("1234567", + a.Perform(std::make_tuple(CharPtr("1"), CharPtr("2"), CharPtr("3"), + CharPtr("4"), CharPtr("5"), CharPtr("6"), + CharPtr("7")))); +} + +// Tests using Invoke() with a 8-argument function. +TEST(InvokeTest, FunctionThatTakes8Arguments) { + Action<std::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(std::make_tuple(CharPtr("1"), CharPtr("2"), CharPtr("3"), + CharPtr("4"), CharPtr("5"), CharPtr("6"), + CharPtr("7"), CharPtr("8")))); +} + +// Tests using Invoke() with a 9-argument function. +TEST(InvokeTest, FunctionThatTakes9Arguments) { + Action<std::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(std::make_tuple( + CharPtr("1"), CharPtr("2"), CharPtr("3"), + CharPtr("4"), CharPtr("5"), CharPtr("6"), + CharPtr("7"), CharPtr("8"), CharPtr("9")))); +} + +// Tests using Invoke() with a 10-argument function. +TEST(InvokeTest, FunctionThatTakes10Arguments) { + Action<std::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(std::make_tuple(CharPtr("1"), CharPtr("2"), CharPtr("3"), + CharPtr("4"), CharPtr("5"), CharPtr("6"), + CharPtr("7"), CharPtr("8"), CharPtr("9"), + CharPtr("0")))); +} + +// Tests using Invoke() with functions with parameters declared as Unused. +TEST(InvokeTest, FunctionWithUnusedParameters) { + Action<int(int, int, double, const std::string&)> a1 = Invoke(SumOfFirst2); + std::tuple<int, int, double, std::string> dummy = + std::make_tuple(10, 2, 5.6, std::string("hi")); + EXPECT_EQ(12, a1.Perform(dummy)); + + Action<int(int, int, bool, int*)> a2 = + Invoke(SumOfFirst2); + EXPECT_EQ( + 23, a2.Perform(std::make_tuple(20, 3, true, static_cast<int*>(nullptr)))); +} + +// Tests using Invoke() with methods with parameters declared as Unused. +TEST(InvokeTest, MethodWithUnusedParameters) { + Foo foo; + Action<int(std::string, bool, int, int)> a1 = Invoke(&foo, &Foo::SumOfLast2); + EXPECT_EQ(12, a1.Perform(std::make_tuple(CharPtr("hi"), true, 10, 2))); + + Action<int(char, double, int, int)> a2 = + Invoke(&foo, &Foo::SumOfLast2); + EXPECT_EQ(23, a2.Perform(std::make_tuple('a', 2.5, 20, 3))); +} + +// Tests using Invoke() with a functor. +TEST(InvokeTest, Functor) { + Action<long(long, int)> a = Invoke(plus<long>()); // NOLINT + EXPECT_EQ(3L, a.Perform(std::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(std::make_tuple(4000, Short(300), Char(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(std::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(std::make_tuple(4000))); +} + +// Tests using Invoke() with a binary method. +TEST(InvokeMethodTest, Binary) { + Foo foo; + Action<std::string(const std::string&, char)> a = Invoke(&foo, &Foo::Binary); + std::string s("Hell"); + std::tuple<std::string, char> dummy = std::make_tuple(s, 'o'); + EXPECT_EQ("Hello", a.Perform(dummy)); +} + +// 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(std::make_tuple(1000, true, Char(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(std::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(std::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(std::make_tuple(100000, 20000, 3000, 400, 50, 6))); +} + +// Tests using Invoke() with a 7-argument method. +TEST(InvokeMethodTest, MethodThatTakes7Arguments) { + Foo foo; + Action<std::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(std::make_tuple(CharPtr("1"), CharPtr("2"), CharPtr("3"), + CharPtr("4"), CharPtr("5"), CharPtr("6"), + CharPtr("7")))); +} + +// Tests using Invoke() with a 8-argument method. +TEST(InvokeMethodTest, MethodThatTakes8Arguments) { + Foo foo; + Action<std::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(std::make_tuple(CharPtr("1"), CharPtr("2"), CharPtr("3"), + CharPtr("4"), CharPtr("5"), CharPtr("6"), + CharPtr("7"), CharPtr("8")))); +} + +// Tests using Invoke() with a 9-argument method. +TEST(InvokeMethodTest, MethodThatTakes9Arguments) { + Foo foo; + Action<std::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(std::make_tuple( + CharPtr("1"), CharPtr("2"), CharPtr("3"), + CharPtr("4"), CharPtr("5"), CharPtr("6"), + CharPtr("7"), CharPtr("8"), CharPtr("9")))); +} + +// Tests using Invoke() with a 10-argument method. +TEST(InvokeMethodTest, MethodThatTakes10Arguments) { + Foo foo; + Action<std::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(std::make_tuple(CharPtr("1"), CharPtr("2"), CharPtr("3"), + CharPtr("4"), CharPtr("5"), CharPtr("6"), + CharPtr("7"), CharPtr("8"), CharPtr("9"), + CharPtr("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(std::make_tuple(4000, Short(300), Char(20), true))); +} + +// 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(std::make_tuple(2))); +} + +// Tests using WithArg with an action that takes 1 argument. +TEST(WithArgTest, OneArg) { + Action<bool(double x, int n)> b = WithArg<1>(Invoke(Unary)); // NOLINT + EXPECT_TRUE(b.Perform(std::make_tuple(1.5, -1))); + EXPECT_FALSE(b.Perform(std::make_tuple(1.5, 1))); +} + +TEST(ReturnArgActionTest, WorksForOneArgIntArg0) { + const Action<int(int)> a = ReturnArg<0>(); + EXPECT_EQ(5, a.Perform(std::make_tuple(5))); +} + +TEST(ReturnArgActionTest, WorksForMultiArgBoolArg0) { + const Action<bool(bool, bool, bool)> a = ReturnArg<0>(); + EXPECT_TRUE(a.Perform(std::make_tuple(true, false, false))); +} + +TEST(ReturnArgActionTest, WorksForMultiArgStringArg2) { + const Action<std::string(int, int, std::string, int)> a = ReturnArg<2>(); + EXPECT_EQ("seven", a.Perform(std::make_tuple(5, 6, std::string("seven"), 8))); +} + +TEST(SaveArgActionTest, WorksForSameType) { + int result = 0; + const Action<void(int n)> a1 = SaveArg<0>(&result); + a1.Perform(std::make_tuple(5)); + EXPECT_EQ(5, result); +} + +TEST(SaveArgActionTest, WorksForCompatibleType) { + int result = 0; + const Action<void(bool, char)> a1 = SaveArg<1>(&result); + a1.Perform(std::make_tuple(true, 'a')); + EXPECT_EQ('a', result); +} + +TEST(SaveArgPointeeActionTest, WorksForSameType) { + int result = 0; + const int value = 5; + const Action<void(const int*)> a1 = SaveArgPointee<0>(&result); + a1.Perform(std::make_tuple(&value)); + EXPECT_EQ(5, result); +} + +TEST(SaveArgPointeeActionTest, WorksForCompatibleType) { + int result = 0; + char value = 'a'; + const Action<void(bool, char*)> a1 = SaveArgPointee<1>(&result); + a1.Perform(std::make_tuple(true, &value)); + EXPECT_EQ('a', result); +} + +TEST(SetArgRefereeActionTest, WorksForSameType) { + int value = 0; + const Action<void(int&)> a1 = SetArgReferee<0>(1); + a1.Perform(std::tuple<int&>(value)); + EXPECT_EQ(1, value); +} + +TEST(SetArgRefereeActionTest, WorksForCompatibleType) { + int value = 0; + const Action<void(int, int&)> a1 = SetArgReferee<1>('a'); + a1.Perform(std::tuple<int, int&>(0, value)); + EXPECT_EQ('a', value); +} + +TEST(SetArgRefereeActionTest, WorksWithExtraArguments) { + int value = 0; + const Action<void(bool, int, int&, const char*)> a1 = SetArgReferee<2>('a'); + a1.Perform(std::tuple<bool, int, int&, const char*>(true, 0, value, "hi")); + EXPECT_EQ('a', value); +} + +// A class that can be used to verify that its destructor is called: it will set +// the bool provided to the constructor to true when destroyed. +class DeletionTester { + public: + explicit DeletionTester(bool* is_deleted) + : is_deleted_(is_deleted) { + // Make sure the bit is set to false. + *is_deleted_ = false; + } + + ~DeletionTester() { + *is_deleted_ = true; + } + + private: + bool* is_deleted_; +}; + +TEST(DeleteArgActionTest, OneArg) { + bool is_deleted = false; + DeletionTester* t = new DeletionTester(&is_deleted); + const Action<void(DeletionTester*)> a1 = DeleteArg<0>(); // NOLINT + EXPECT_FALSE(is_deleted); + a1.Perform(std::make_tuple(t)); + EXPECT_TRUE(is_deleted); +} + +TEST(DeleteArgActionTest, TenArgs) { + bool is_deleted = false; + DeletionTester* t = new DeletionTester(&is_deleted); + const Action<void(bool, int, int, const char*, bool, + int, int, int, int, DeletionTester*)> a1 = DeleteArg<9>(); + EXPECT_FALSE(is_deleted); + a1.Perform(std::make_tuple(true, 5, 6, CharPtr("hi"), false, 7, 8, 9, 10, t)); + EXPECT_TRUE(is_deleted); +} + +#if GTEST_HAS_EXCEPTIONS + +TEST(ThrowActionTest, ThrowsGivenExceptionInVoidFunction) { + const Action<void(int n)> a = Throw('a'); + EXPECT_THROW(a.Perform(std::make_tuple(0)), char); +} + +class MyException {}; + +TEST(ThrowActionTest, ThrowsGivenExceptionInNonVoidFunction) { + const Action<double(char ch)> a = Throw(MyException()); + EXPECT_THROW(a.Perform(std::make_tuple('0')), MyException); +} + +TEST(ThrowActionTest, ThrowsGivenExceptionInNullaryFunction) { + const Action<double()> a = Throw(MyException()); + EXPECT_THROW(a.Perform(std::make_tuple()), MyException); +} + +class Object { + public: + virtual ~Object() {} + virtual void Func() {} +}; + +class MockObject : public Object { + public: + ~MockObject() override {} + MOCK_METHOD(void, Func, (), (override)); +}; + +TEST(ThrowActionTest, Times0) { + EXPECT_NONFATAL_FAILURE( + [] { + try { + MockObject m; + ON_CALL(m, Func()).WillByDefault([] { throw "something"; }); + EXPECT_CALL(m, Func()).Times(0); + m.Func(); + } catch (...) { + // Exception is caught but Times(0) still triggers a failure. + } + }(), + ""); +} + +#endif // GTEST_HAS_EXCEPTIONS + +// 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(std::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(std::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(std::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, int*); + char chars[] = { 97, 98, 99 }; + Action<MyFunction> a = SetArrayArgument<1>(chars, chars + 3); + + int codes[4] = { 111, 222, 333, 444 }; + int* pcodes = codes; + a.Perform(std::make_tuple(true, pcodes)); + EXPECT_EQ(97, codes[0]); + EXPECT_EQ(98, codes[1]); + EXPECT_EQ(99, codes[2]); + EXPECT_EQ(444, codes[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(std::make_tuple(true, back_inserter(s))); + EXPECT_EQ(letters, s); +} + +TEST(ReturnPointeeTest, Works) { + int n = 42; + const Action<int()> a = ReturnPointee(&n); + EXPECT_EQ(42, a.Perform(std::make_tuple())); + + n = 43; + EXPECT_EQ(43, a.Perform(std::make_tuple())); +} + +} // namespace gmock_generated_actions_test +} // namespace testing diff --git a/src/googletest/googlemock/test/gmock-nice-strict_test.cc b/src/googletest/googlemock/test/gmock-nice-strict_test.cc new file mode 100644 index 000000000..25558ebff --- /dev/null +++ b/src/googletest/googlemock/test/gmock-nice-strict_test.cc @@ -0,0 +1,539 @@ +// 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. + +#include "gmock/gmock-nice-strict.h" + +#include <string> +#include <utility> +#include "gmock/gmock.h" +#include "gtest/gtest-spi.h" +#include "gtest/gtest.h" + +// This must not be defined inside the ::testing namespace, or it will +// clash with ::testing::Mock. +class Mock { + public: + Mock() {} + + MOCK_METHOD0(DoThis, void()); + + private: + GTEST_DISALLOW_COPY_AND_ASSIGN_(Mock); +}; + +namespace testing { +namespace gmock_nice_strict_test { + +using testing::GMOCK_FLAG(verbose); +using testing::HasSubstr; +using testing::NaggyMock; +using testing::NiceMock; +using testing::StrictMock; + +#if GTEST_HAS_STREAM_REDIRECTION +using testing::internal::CaptureStdout; +using testing::internal::GetCapturedStdout; +#endif + +// Class without default constructor. +class NotDefaultConstructible { + public: + explicit NotDefaultConstructible(int) {} +}; + +class CallsMockMethodInDestructor { + public: + ~CallsMockMethodInDestructor() { OnDestroy(); } + MOCK_METHOD(void, OnDestroy, ()); +}; + +// 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: + MockFoo() {} + void Delete() { delete this; } + + MOCK_METHOD0(DoThis, void()); + MOCK_METHOD1(DoThat, int(bool flag)); + MOCK_METHOD0(ReturnNonDefaultConstructible, NotDefaultConstructible()); + + private: + GTEST_DISALLOW_COPY_AND_ASSIGN_(MockFoo); +}; + +class MockBar { + public: + explicit MockBar(const std::string& s) : str_(s) {} + + MockBar(char a1, char a2, std::string a3, std::string a4, int a5, int a6, + const std::string& a7, const std::string& a8, bool a9, bool a10) { + str_ = std::string() + a1 + a2 + a3 + a4 + static_cast<char>(a5) + + static_cast<char>(a6) + a7 + a8 + (a9 ? 'T' : 'F') + (a10 ? 'T' : 'F'); + } + + virtual ~MockBar() {} + + const std::string& str() const { return str_; } + + MOCK_METHOD0(This, int()); + MOCK_METHOD2(That, std::string(int, bool)); + + private: + std::string str_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(MockBar); +}; + + +class MockBaz { + public: + class MoveOnly { + public: + MoveOnly() = default; + + MoveOnly(const MoveOnly&) = delete; + MoveOnly& operator=(const MoveOnly&) = delete; + + MoveOnly(MoveOnly&&) = default; + MoveOnly& operator=(MoveOnly&&) = default; + }; + + MockBaz(MoveOnly) {} +}; + +#if GTEST_HAS_STREAM_REDIRECTION + +// Tests that a raw mock generates warnings for uninteresting calls. +TEST(RawMockTest, WarningForUninterestingCall) { + const std::string saved_flag = GMOCK_FLAG(verbose); + GMOCK_FLAG(verbose) = "warning"; + + MockFoo raw_foo; + + CaptureStdout(); + raw_foo.DoThis(); + raw_foo.DoThat(true); + EXPECT_THAT(GetCapturedStdout(), + HasSubstr("Uninteresting mock function call")); + + GMOCK_FLAG(verbose) = saved_flag; +} + +// Tests that a raw mock generates warnings for uninteresting calls +// that delete the mock object. +TEST(RawMockTest, WarningForUninterestingCallAfterDeath) { + const std::string saved_flag = GMOCK_FLAG(verbose); + GMOCK_FLAG(verbose) = "warning"; + + MockFoo* const raw_foo = new MockFoo; + + ON_CALL(*raw_foo, DoThis()) + .WillByDefault(Invoke(raw_foo, &MockFoo::Delete)); + + CaptureStdout(); + raw_foo->DoThis(); + EXPECT_THAT(GetCapturedStdout(), + HasSubstr("Uninteresting mock function call")); + + GMOCK_FLAG(verbose) = saved_flag; +} + +// Tests that a raw mock generates informational logs for +// uninteresting calls. +TEST(RawMockTest, InfoForUninterestingCall) { + MockFoo raw_foo; + + const std::string saved_flag = GMOCK_FLAG(verbose); + GMOCK_FLAG(verbose) = "info"; + CaptureStdout(); + raw_foo.DoThis(); + EXPECT_THAT(GetCapturedStdout(), + HasSubstr("Uninteresting mock function call")); + + GMOCK_FLAG(verbose) = saved_flag; +} + +TEST(RawMockTest, IsNaggy_IsNice_IsStrict) { + MockFoo raw_foo; + EXPECT_TRUE(Mock::IsNaggy(&raw_foo)); + EXPECT_FALSE(Mock::IsNice(&raw_foo)); + EXPECT_FALSE(Mock::IsStrict(&raw_foo)); +} + +// Tests that a nice mock generates no warning for uninteresting calls. +TEST(NiceMockTest, NoWarningForUninterestingCall) { + NiceMock<MockFoo> nice_foo; + + CaptureStdout(); + nice_foo.DoThis(); + nice_foo.DoThat(true); + EXPECT_EQ("", GetCapturedStdout()); +} + +// 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)); + + CaptureStdout(); + nice_foo->DoThis(); + EXPECT_EQ("", GetCapturedStdout()); +} + +// Tests that a nice mock generates informational logs for +// uninteresting calls. +TEST(NiceMockTest, InfoForUninterestingCall) { + NiceMock<MockFoo> nice_foo; + + const std::string saved_flag = GMOCK_FLAG(verbose); + GMOCK_FLAG(verbose) = "info"; + CaptureStdout(); + nice_foo.DoThis(); + EXPECT_THAT(GetCapturedStdout(), + HasSubstr("Uninteresting mock function call")); + + GMOCK_FLAG(verbose) = saved_flag; +} + +#endif // GTEST_HAS_STREAM_REDIRECTION + +// 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 which returns a +// not-default-constructible type throws an exception and the exception contains +// the method's name. +TEST(NiceMockTest, ThrowsExceptionForUnknownReturnTypes) { + NiceMock<MockFoo> nice_foo; +#if GTEST_HAS_EXCEPTIONS + try { + nice_foo.ReturnNonDefaultConstructible(); + FAIL(); + } catch (const std::runtime_error& ex) { + EXPECT_THAT(ex.what(), HasSubstr("ReturnNonDefaultConstructible")); + } +#else + EXPECT_DEATH_IF_SUPPORTED({ nice_foo.ReturnNonDefaultConstructible(); }, ""); +#endif +} + +// 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); +} + +TEST(NiceMockTest, AllowLeak) { + NiceMock<MockFoo>* leaked = new NiceMock<MockFoo>; + Mock::AllowLeak(leaked); + EXPECT_CALL(*leaked, DoThis()); + leaked->DoThis(); +} + +TEST(NiceMockTest, MoveOnlyConstructor) { + NiceMock<MockBaz> nice_baz(MockBaz::MoveOnly{}); +} + +// Tests that NiceMock<Mock> compiles where Mock is a user-defined +// class (as opposed to ::testing::Mock). +TEST(NiceMockTest, AcceptsClassNamedMock) { + NiceMock< ::Mock> nice; + EXPECT_CALL(nice, DoThis()); + nice.DoThis(); +} + +TEST(NiceMockTest, IsNiceInDestructor) { + { + NiceMock<CallsMockMethodInDestructor> nice_on_destroy; + // Don't add an expectation for the call before the mock goes out of scope. + } +} + +TEST(NiceMockTest, IsNaggy_IsNice_IsStrict) { + NiceMock<MockFoo> nice_foo; + EXPECT_FALSE(Mock::IsNaggy(&nice_foo)); + EXPECT_TRUE(Mock::IsNice(&nice_foo)); + EXPECT_FALSE(Mock::IsStrict(&nice_foo)); +} + +#if GTEST_HAS_STREAM_REDIRECTION + +// Tests that a naggy mock generates warnings for uninteresting calls. +TEST(NaggyMockTest, WarningForUninterestingCall) { + const std::string saved_flag = GMOCK_FLAG(verbose); + GMOCK_FLAG(verbose) = "warning"; + + NaggyMock<MockFoo> naggy_foo; + + CaptureStdout(); + naggy_foo.DoThis(); + naggy_foo.DoThat(true); + EXPECT_THAT(GetCapturedStdout(), + HasSubstr("Uninteresting mock function call")); + + GMOCK_FLAG(verbose) = saved_flag; +} + +// Tests that a naggy mock generates a warning for an uninteresting call +// that deletes the mock object. +TEST(NaggyMockTest, WarningForUninterestingCallAfterDeath) { + const std::string saved_flag = GMOCK_FLAG(verbose); + GMOCK_FLAG(verbose) = "warning"; + + NaggyMock<MockFoo>* const naggy_foo = new NaggyMock<MockFoo>; + + ON_CALL(*naggy_foo, DoThis()) + .WillByDefault(Invoke(naggy_foo, &MockFoo::Delete)); + + CaptureStdout(); + naggy_foo->DoThis(); + EXPECT_THAT(GetCapturedStdout(), + HasSubstr("Uninteresting mock function call")); + + GMOCK_FLAG(verbose) = saved_flag; +} + +#endif // GTEST_HAS_STREAM_REDIRECTION + +// Tests that a naggy mock allows expected calls. +TEST(NaggyMockTest, AllowsExpectedCall) { + NaggyMock<MockFoo> naggy_foo; + + EXPECT_CALL(naggy_foo, DoThis()); + naggy_foo.DoThis(); +} + +// Tests that an unexpected call on a naggy mock fails. +TEST(NaggyMockTest, UnexpectedCallFails) { + NaggyMock<MockFoo> naggy_foo; + + EXPECT_CALL(naggy_foo, DoThis()).Times(0); + EXPECT_NONFATAL_FAILURE(naggy_foo.DoThis(), + "called more times than expected"); +} + +// Tests that NaggyMock works with a mock class that has a non-default +// constructor. +TEST(NaggyMockTest, NonDefaultConstructor) { + NaggyMock<MockBar> naggy_bar("hi"); + EXPECT_EQ("hi", naggy_bar.str()); + + naggy_bar.This(); + naggy_bar.That(5, true); +} + +// Tests that NaggyMock works with a mock class that has a 10-ary +// non-default constructor. +TEST(NaggyMockTest, NonDefaultConstructor10) { + NaggyMock<MockBar> naggy_bar('0', '1', "2", "3", '4', '5', + "6", "7", true, false); + EXPECT_EQ("01234567TF", naggy_bar.str()); + + naggy_bar.This(); + naggy_bar.That(5, true); +} + +TEST(NaggyMockTest, AllowLeak) { + NaggyMock<MockFoo>* leaked = new NaggyMock<MockFoo>; + Mock::AllowLeak(leaked); + EXPECT_CALL(*leaked, DoThis()); + leaked->DoThis(); +} + +TEST(NaggyMockTest, MoveOnlyConstructor) { + NaggyMock<MockBaz> naggy_baz(MockBaz::MoveOnly{}); +} + +// Tests that NaggyMock<Mock> compiles where Mock is a user-defined +// class (as opposed to ::testing::Mock). +TEST(NaggyMockTest, AcceptsClassNamedMock) { + NaggyMock< ::Mock> naggy; + EXPECT_CALL(naggy, DoThis()); + naggy.DoThis(); +} + +TEST(NaggyMockTest, IsNaggyInDestructor) { + const std::string saved_flag = GMOCK_FLAG(verbose); + GMOCK_FLAG(verbose) = "warning"; + CaptureStdout(); + + { + NaggyMock<CallsMockMethodInDestructor> naggy_on_destroy; + // Don't add an expectation for the call before the mock goes out of scope. + } + + EXPECT_THAT(GetCapturedStdout(), + HasSubstr("Uninteresting mock function call")); + + GMOCK_FLAG(verbose) = saved_flag; +} + +TEST(NaggyMockTest, IsNaggy_IsNice_IsStrict) { + NaggyMock<MockFoo> naggy_foo; + EXPECT_TRUE(Mock::IsNaggy(&naggy_foo)); + EXPECT_FALSE(Mock::IsNice(&naggy_foo)); + EXPECT_FALSE(Mock::IsStrict(&naggy_foo)); +} + +// 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"); +} + +TEST(StrictMockTest, AllowLeak) { + StrictMock<MockFoo>* leaked = new StrictMock<MockFoo>; + Mock::AllowLeak(leaked); + EXPECT_CALL(*leaked, DoThis()); + leaked->DoThis(); +} + +TEST(StrictMockTest, MoveOnlyConstructor) { + StrictMock<MockBaz> strict_baz(MockBaz::MoveOnly{}); +} + +// Tests that StrictMock<Mock> compiles where Mock is a user-defined +// class (as opposed to ::testing::Mock). +TEST(StrictMockTest, AcceptsClassNamedMock) { + StrictMock< ::Mock> strict; + EXPECT_CALL(strict, DoThis()); + strict.DoThis(); +} + +TEST(StrictMockTest, IsStrictInDestructor) { + EXPECT_NONFATAL_FAILURE( + { + StrictMock<CallsMockMethodInDestructor> strict_on_destroy; + // Don't add an expectation for the call before the mock goes out of + // scope. + }, + "Uninteresting mock function call"); +} + +TEST(StrictMockTest, IsNaggy_IsNice_IsStrict) { + StrictMock<MockFoo> strict_foo; + EXPECT_FALSE(Mock::IsNaggy(&strict_foo)); + EXPECT_FALSE(Mock::IsNice(&strict_foo)); + EXPECT_TRUE(Mock::IsStrict(&strict_foo)); +} + +} // namespace gmock_nice_strict_test +} // namespace testing diff --git a/src/googletest/googlemock/test/gmock-port_test.cc b/src/googletest/googlemock/test/gmock-port_test.cc new file mode 100644 index 000000000..a2c2be248 --- /dev/null +++ b/src/googletest/googlemock/test/gmock-port_test.cc @@ -0,0 +1,42 @@ +// 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 internal cross-platform support utilities. + +#include "gmock/internal/gmock-port.h" +#include "gtest/gtest.h" + +// NOTE: if this file is left without tests for some reason, put a dummy +// test here to make references to symbols in the gtest library and avoid +// 'undefined symbol' linker errors in gmock_main: + +TEST(DummyTest, Dummy) {} diff --git a/src/googletest/googlemock/test/gmock-pp-string_test.cc b/src/googletest/googlemock/test/gmock-pp-string_test.cc new file mode 100644 index 000000000..6f66cf156 --- /dev/null +++ b/src/googletest/googlemock/test/gmock-pp-string_test.cc @@ -0,0 +1,206 @@ +// Copyright 2018, 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 internal preprocessor macro library. +#include "gmock/internal/gmock-pp.h" + +#include <string> + +#include "gmock/gmock.h" + +namespace testing { +namespace { + +// Matcher to verify that to strings are identical up to whitespace +// Not 100% correct, because it treats "AB" as equal to "A B". +::testing::Matcher<const std::string&> SameExceptSpaces(const std::string& s) { + auto remove_spaces = [](std::string to_split) { + to_split.erase(std::remove(to_split.begin(), to_split.end(), ' '), + to_split.end()); + return to_split; + }; + return ::testing::ResultOf(remove_spaces, remove_spaces(s)); +} + +// Verify that a macro expands to a given text. Ignores whitespace difference. +// In MSVC, GMOCK_PP_STRINGIZE() returns nothing, rather than "". So concatenate +// with an empty string. +#define EXPECT_EXPANSION(Result, Macro) \ + EXPECT_THAT("" GMOCK_PP_STRINGIZE(Macro), SameExceptSpaces(Result)) + +TEST(Macros, Cat) { + EXPECT_EXPANSION("14", GMOCK_PP_CAT(1, 4)); + EXPECT_EXPANSION("+=", GMOCK_PP_CAT(+, =)); +} + +TEST(Macros, Narg) { + EXPECT_EXPANSION("1", GMOCK_PP_NARG()); + EXPECT_EXPANSION("1", GMOCK_PP_NARG(x)); + EXPECT_EXPANSION("2", GMOCK_PP_NARG(x, y)); + EXPECT_EXPANSION("3", GMOCK_PP_NARG(x, y, z)); + EXPECT_EXPANSION("4", GMOCK_PP_NARG(x, y, z, w)); + + EXPECT_EXPANSION("0", GMOCK_PP_NARG0()); + EXPECT_EXPANSION("1", GMOCK_PP_NARG0(x)); + EXPECT_EXPANSION("2", GMOCK_PP_NARG0(x, y)); +} + +TEST(Macros, Comma) { + EXPECT_EXPANSION("0", GMOCK_PP_HAS_COMMA()); + EXPECT_EXPANSION("1", GMOCK_PP_HAS_COMMA(, )); + EXPECT_EXPANSION("0", GMOCK_PP_HAS_COMMA((, ))); +} + +TEST(Macros, IsEmpty) { + EXPECT_EXPANSION("1", GMOCK_PP_IS_EMPTY()); + EXPECT_EXPANSION("0", GMOCK_PP_IS_EMPTY(, )); + EXPECT_EXPANSION("0", GMOCK_PP_IS_EMPTY(a)); + EXPECT_EXPANSION("0", GMOCK_PP_IS_EMPTY(())); + +#define GMOCK_PP_INTERNAL_IS_EMPTY_TEST_1 + EXPECT_EXPANSION("1", GMOCK_PP_IS_EMPTY(GMOCK_PP_INTERNAL_IS_EMPTY_TEST_1)); +} + +TEST(Macros, If) { + EXPECT_EXPANSION("1", GMOCK_PP_IF(1, 1, 2)); + EXPECT_EXPANSION("2", GMOCK_PP_IF(0, 1, 2)); +} + +TEST(Macros, HeadTail) { + EXPECT_EXPANSION("1", GMOCK_PP_HEAD(1)); + EXPECT_EXPANSION("1", GMOCK_PP_HEAD(1, 2)); + EXPECT_EXPANSION("1", GMOCK_PP_HEAD(1, 2, 3)); + + EXPECT_EXPANSION("", GMOCK_PP_TAIL(1)); + EXPECT_EXPANSION("2", GMOCK_PP_TAIL(1, 2)); + EXPECT_EXPANSION("2", GMOCK_PP_HEAD(GMOCK_PP_TAIL(1, 2, 3))); +} + +TEST(Macros, Parentheses) { + EXPECT_EXPANSION("0", GMOCK_PP_IS_BEGIN_PARENS(sss)); + EXPECT_EXPANSION("0", GMOCK_PP_IS_BEGIN_PARENS(sss())); + EXPECT_EXPANSION("0", GMOCK_PP_IS_BEGIN_PARENS(sss() sss)); + EXPECT_EXPANSION("1", GMOCK_PP_IS_BEGIN_PARENS((sss))); + EXPECT_EXPANSION("1", GMOCK_PP_IS_BEGIN_PARENS((sss)ss)); + + EXPECT_EXPANSION("0", GMOCK_PP_IS_ENCLOSED_PARENS(sss)); + EXPECT_EXPANSION("0", GMOCK_PP_IS_ENCLOSED_PARENS(sss())); + EXPECT_EXPANSION("0", GMOCK_PP_IS_ENCLOSED_PARENS(sss() sss)); + EXPECT_EXPANSION("1", GMOCK_PP_IS_ENCLOSED_PARENS((sss))); + EXPECT_EXPANSION("0", GMOCK_PP_IS_ENCLOSED_PARENS((sss)ss)); + + EXPECT_EXPANSION("1 + 1", GMOCK_PP_REMOVE_PARENS((1 + 1))); +} + +TEST(Macros, Increment) { + EXPECT_EXPANSION("1", GMOCK_PP_INC(0)); + EXPECT_EXPANSION("2", GMOCK_PP_INC(1)); + EXPECT_EXPANSION("3", GMOCK_PP_INC(2)); + EXPECT_EXPANSION("4", GMOCK_PP_INC(3)); + EXPECT_EXPANSION("5", GMOCK_PP_INC(4)); + + EXPECT_EXPANSION("16", GMOCK_PP_INC(15)); +} + +#define JOINER_CAT(a, b) a##b +#define JOINER(_N, _Data, _Elem) JOINER_CAT(_Data, _N) = _Elem + +TEST(Macros, Repeat) { + EXPECT_EXPANSION("", GMOCK_PP_REPEAT(JOINER, X, 0)); + EXPECT_EXPANSION("X0=", GMOCK_PP_REPEAT(JOINER, X, 1)); + EXPECT_EXPANSION("X0= X1=", GMOCK_PP_REPEAT(JOINER, X, 2)); + EXPECT_EXPANSION("X0= X1= X2=", GMOCK_PP_REPEAT(JOINER, X, 3)); + EXPECT_EXPANSION("X0= X1= X2= X3=", GMOCK_PP_REPEAT(JOINER, X, 4)); + EXPECT_EXPANSION("X0= X1= X2= X3= X4=", GMOCK_PP_REPEAT(JOINER, X, 5)); + EXPECT_EXPANSION("X0= X1= X2= X3= X4= X5=", GMOCK_PP_REPEAT(JOINER, X, 6)); + EXPECT_EXPANSION("X0= X1= X2= X3= X4= X5= X6=", + GMOCK_PP_REPEAT(JOINER, X, 7)); + EXPECT_EXPANSION("X0= X1= X2= X3= X4= X5= X6= X7=", + GMOCK_PP_REPEAT(JOINER, X, 8)); + EXPECT_EXPANSION("X0= X1= X2= X3= X4= X5= X6= X7= X8=", + GMOCK_PP_REPEAT(JOINER, X, 9)); + EXPECT_EXPANSION("X0= X1= X2= X3= X4= X5= X6= X7= X8= X9=", + GMOCK_PP_REPEAT(JOINER, X, 10)); + EXPECT_EXPANSION("X0= X1= X2= X3= X4= X5= X6= X7= X8= X9= X10=", + GMOCK_PP_REPEAT(JOINER, X, 11)); + EXPECT_EXPANSION("X0= X1= X2= X3= X4= X5= X6= X7= X8= X9= X10= X11=", + GMOCK_PP_REPEAT(JOINER, X, 12)); + EXPECT_EXPANSION("X0= X1= X2= X3= X4= X5= X6= X7= X8= X9= X10= X11= X12=", + GMOCK_PP_REPEAT(JOINER, X, 13)); + EXPECT_EXPANSION( + "X0= X1= X2= X3= X4= X5= X6= X7= X8= X9= X10= X11= X12= X13=", + GMOCK_PP_REPEAT(JOINER, X, 14)); + EXPECT_EXPANSION( + "X0= X1= X2= X3= X4= X5= X6= X7= X8= X9= X10= X11= X12= X13= X14=", + GMOCK_PP_REPEAT(JOINER, X, 15)); +} +TEST(Macros, ForEach) { + EXPECT_EXPANSION("", GMOCK_PP_FOR_EACH(JOINER, X, ())); + EXPECT_EXPANSION("X0=a", GMOCK_PP_FOR_EACH(JOINER, X, (a))); + EXPECT_EXPANSION("X0=a X1=b", GMOCK_PP_FOR_EACH(JOINER, X, (a, b))); + EXPECT_EXPANSION("X0=a X1=b X2=c", GMOCK_PP_FOR_EACH(JOINER, X, (a, b, c))); + EXPECT_EXPANSION("X0=a X1=b X2=c X3=d", + GMOCK_PP_FOR_EACH(JOINER, X, (a, b, c, d))); + EXPECT_EXPANSION("X0=a X1=b X2=c X3=d X4=e", + GMOCK_PP_FOR_EACH(JOINER, X, (a, b, c, d, e))); + EXPECT_EXPANSION("X0=a X1=b X2=c X3=d X4=e X5=f", + GMOCK_PP_FOR_EACH(JOINER, X, (a, b, c, d, e, f))); + EXPECT_EXPANSION("X0=a X1=b X2=c X3=d X4=e X5=f X6=g", + GMOCK_PP_FOR_EACH(JOINER, X, (a, b, c, d, e, f, g))); + EXPECT_EXPANSION("X0=a X1=b X2=c X3=d X4=e X5=f X6=g X7=h", + GMOCK_PP_FOR_EACH(JOINER, X, (a, b, c, d, e, f, g, h))); + EXPECT_EXPANSION("X0=a X1=b X2=c X3=d X4=e X5=f X6=g X7=h X8=i", + GMOCK_PP_FOR_EACH(JOINER, X, (a, b, c, d, e, f, g, h, i))); + EXPECT_EXPANSION( + "X0=a X1=b X2=c X3=d X4=e X5=f X6=g X7=h X8=i X9=j", + GMOCK_PP_FOR_EACH(JOINER, X, (a, b, c, d, e, f, g, h, i, j))); + EXPECT_EXPANSION( + "X0=a X1=b X2=c X3=d X4=e X5=f X6=g X7=h X8=i X9=j X10=k", + GMOCK_PP_FOR_EACH(JOINER, X, (a, b, c, d, e, f, g, h, i, j, k))); + EXPECT_EXPANSION( + "X0=a X1=b X2=c X3=d X4=e X5=f X6=g X7=h X8=i X9=j X10=k X11=l", + GMOCK_PP_FOR_EACH(JOINER, X, (a, b, c, d, e, f, g, h, i, j, k, l))); + EXPECT_EXPANSION( + "X0=a X1=b X2=c X3=d X4=e X5=f X6=g X7=h X8=i X9=j X10=k X11=l X12=m", + GMOCK_PP_FOR_EACH(JOINER, X, (a, b, c, d, e, f, g, h, i, j, k, l, m))); + EXPECT_EXPANSION( + "X0=a X1=b X2=c X3=d X4=e X5=f X6=g X7=h X8=i X9=j X10=k X11=l X12=m " + "X13=n", + GMOCK_PP_FOR_EACH(JOINER, X, (a, b, c, d, e, f, g, h, i, j, k, l, m, n))); + EXPECT_EXPANSION( + "X0=a X1=b X2=c X3=d X4=e X5=f X6=g X7=h X8=i X9=j X10=k X11=l X12=m " + "X13=n X14=o", + GMOCK_PP_FOR_EACH(JOINER, X, + (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o))); +} + +} // namespace +} // namespace testing diff --git a/src/googletest/googlemock/test/gmock-pp_test.cc b/src/googletest/googlemock/test/gmock-pp_test.cc new file mode 100644 index 000000000..5d1566e38 --- /dev/null +++ b/src/googletest/googlemock/test/gmock-pp_test.cc @@ -0,0 +1,83 @@ +#include "gmock/internal/gmock-pp.h" + +// Used to test MSVC treating __VA_ARGS__ with a comma in it as one value +#define GMOCK_TEST_REPLACE_comma_WITH_COMMA_I_comma , +#define GMOCK_TEST_REPLACE_comma_WITH_COMMA(x) \ + GMOCK_PP_CAT(GMOCK_TEST_REPLACE_comma_WITH_COMMA_I_, x) + +// Static assertions. +namespace testing { +namespace internal { +namespace gmockpp { + +static_assert(GMOCK_PP_CAT(1, 4) == 14, ""); +static_assert(GMOCK_PP_INTERNAL_INTERNAL_16TH(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, + 12, 13, 14, 15, 16, 17, 18) == 16, + ""); +static_assert(GMOCK_PP_NARG() == 1, ""); +static_assert(GMOCK_PP_NARG(x) == 1, ""); +static_assert(GMOCK_PP_NARG(x, y) == 2, ""); +static_assert(GMOCK_PP_NARG(x, y, z) == 3, ""); +static_assert(GMOCK_PP_NARG(x, y, z, w) == 4, ""); +static_assert(!GMOCK_PP_HAS_COMMA(), ""); +static_assert(GMOCK_PP_HAS_COMMA(b, ), ""); +static_assert(!GMOCK_PP_HAS_COMMA((, )), ""); +static_assert(GMOCK_PP_HAS_COMMA(GMOCK_TEST_REPLACE_comma_WITH_COMMA(comma)), + ""); +static_assert( + GMOCK_PP_HAS_COMMA(GMOCK_TEST_REPLACE_comma_WITH_COMMA(comma(unrelated))), + ""); +static_assert(!GMOCK_PP_IS_EMPTY(, ), ""); +static_assert(!GMOCK_PP_IS_EMPTY(a), ""); +static_assert(!GMOCK_PP_IS_EMPTY(()), ""); +static_assert(GMOCK_PP_IF(1, 1, 2) == 1, ""); +static_assert(GMOCK_PP_IF(0, 1, 2) == 2, ""); +static_assert(GMOCK_PP_NARG0(x) == 1, ""); +static_assert(GMOCK_PP_NARG0(x, y) == 2, ""); +static_assert(GMOCK_PP_HEAD(1) == 1, ""); +static_assert(GMOCK_PP_HEAD(1, 2) == 1, ""); +static_assert(GMOCK_PP_HEAD(1, 2, 3) == 1, ""); +static_assert(GMOCK_PP_TAIL(1, 2) == 2, ""); +static_assert(GMOCK_PP_HEAD(GMOCK_PP_TAIL(1, 2, 3)) == 2, ""); +static_assert(!GMOCK_PP_IS_BEGIN_PARENS(sss), ""); +static_assert(!GMOCK_PP_IS_BEGIN_PARENS(sss()), ""); +static_assert(!GMOCK_PP_IS_BEGIN_PARENS(sss() sss), ""); +static_assert(GMOCK_PP_IS_BEGIN_PARENS((sss)), ""); +static_assert(GMOCK_PP_IS_BEGIN_PARENS((sss)ss), ""); +static_assert(!GMOCK_PP_IS_ENCLOSED_PARENS(sss), ""); +static_assert(!GMOCK_PP_IS_ENCLOSED_PARENS(sss()), ""); +static_assert(!GMOCK_PP_IS_ENCLOSED_PARENS(sss() sss), ""); +static_assert(!GMOCK_PP_IS_ENCLOSED_PARENS((sss)ss), ""); +static_assert(GMOCK_PP_REMOVE_PARENS((1 + 1)) * 2 == 3, ""); +static_assert(GMOCK_PP_INC(4) == 5, ""); + +template <class... Args> +struct Test { + static constexpr int kArgs = sizeof...(Args); +}; +#define GMOCK_PP_INTERNAL_TYPE_TEST(_i, _Data, _element) \ + GMOCK_PP_COMMA_IF(_i) _element +static_assert(Test<GMOCK_PP_FOR_EACH(GMOCK_PP_INTERNAL_TYPE_TEST, ~, + (int, float, double, char))>::kArgs == 4, + ""); +#define GMOCK_PP_INTERNAL_VAR_TEST_1(_x) 1 +#define GMOCK_PP_INTERNAL_VAR_TEST_2(_x, _y) 2 +#define GMOCK_PP_INTERNAL_VAR_TEST_3(_x, _y, _z) 3 + +#define GMOCK_PP_INTERNAL_VAR_TEST(...) \ + GMOCK_PP_VARIADIC_CALL(GMOCK_PP_INTERNAL_VAR_TEST_, __VA_ARGS__) +static_assert(GMOCK_PP_INTERNAL_VAR_TEST(x, y) == 2, ""); +static_assert(GMOCK_PP_INTERNAL_VAR_TEST(silly) == 1, ""); +static_assert(GMOCK_PP_INTERNAL_VAR_TEST(x, y, z) == 3, ""); + +// TODO(iserna): The following asserts fail in --config=lexan. +#define GMOCK_PP_INTERNAL_IS_EMPTY_TEST_1 +static_assert(GMOCK_PP_IS_EMPTY(GMOCK_PP_INTERNAL_IS_EMPTY_TEST_1), ""); +static_assert(GMOCK_PP_IS_EMPTY(), ""); +static_assert(GMOCK_PP_IS_ENCLOSED_PARENS((sss)), ""); +static_assert(GMOCK_PP_IS_EMPTY(GMOCK_PP_TAIL(1)), ""); +static_assert(GMOCK_PP_NARG0() == 0, ""); + +} // namespace gmockpp +} // namespace internal +} // namespace testing diff --git a/src/googletest/googlemock/test/gmock-spec-builders_test.cc b/src/googletest/googlemock/test/gmock-spec-builders_test.cc new file mode 100644 index 000000000..791a24768 --- /dev/null +++ b/src/googletest/googlemock/test/gmock-spec-builders_test.cc @@ -0,0 +1,2775 @@ +// 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. + + +// Google Mock - a framework for writing C++ mock classes. +// +// This file tests the spec builder syntax. + +#include "gmock/gmock-spec-builders.h" + +#include <memory> +#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" +#include "gtest/internal/gtest-port.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::ContainsRegex; +using testing::DoAll; +using testing::DoDefault; +using testing::Eq; +using testing::Expectation; +using testing::ExpectationSet; +using testing::GMOCK_FLAG(verbose); +using testing::Gt; +using testing::IgnoreResult; +using testing::InSequence; +using testing::Invoke; +using testing::InvokeWithoutArgs; +using testing::IsNotSubstring; +using testing::IsSubstring; +using testing::Lt; +using testing::Message; +using testing::Mock; +using testing::NaggyMock; +using testing::Ne; +using testing::Return; +using testing::SaveArg; +using testing::Sequence; +using testing::SetArgPointee; +using testing::internal::ExpectationTester; +using testing::internal::FormatFileLocation; +using testing::internal::kAllow; +using testing::internal::kErrorVerbosity; +using testing::internal::kFail; +using testing::internal::kInfoVerbosity; +using testing::internal::kWarn; +using testing::internal::kWarningVerbosity; + +#if GTEST_HAS_STREAM_REDIRECTION +using testing::HasSubstr; +using testing::internal::CaptureStdout; +using testing::internal::GetCapturedStdout; +#endif + +class Incomplete; + +class MockIncomplete { + public: + // This line verifies that a mock method can take a by-reference + // argument of an incomplete type. + MOCK_METHOD1(ByRefFunc, void(const Incomplete& x)); +}; + +// Tells Google Mock how to print a value of type Incomplete. +void PrintTo(const Incomplete& x, ::std::ostream* os); + +TEST(MockMethodTest, CanInstantiateWithIncompleteArgType) { + // Even though this mock class contains a mock method that takes + // by-reference an argument whose type is incomplete, we can still + // use the mock, as long as Google Mock knows how to print the + // argument. + MockIncomplete incomplete; + EXPECT_CALL(incomplete, ByRefFunc(_)) + .Times(AnyNumber()); +} + +// The definition of the printer for the argument type doesn't have to +// be visible where the mock is used. +void PrintTo(const Incomplete& /* x */, ::std::ostream* os) { + *os << "incomplete"; +} + +class Result {}; + +// A type that's not default constructible. +class NonDefaultConstructible { + public: + explicit NonDefaultConstructible(int /* dummy */) {} +}; + +class MockA { + public: + MockA() {} + + MOCK_METHOD1(DoA, void(int n)); + MOCK_METHOD1(ReturnResult, Result(int n)); + MOCK_METHOD0(ReturnNonDefaultConstructible, NonDefaultConstructible()); + MOCK_METHOD2(Binary, bool(int x, int y)); + MOCK_METHOD2(ReturnInt, int(int x, int y)); + + private: + GTEST_DISALLOW_COPY_AND_ASSIGN_(MockA); +}; + +class MockB { + public: + MockB() {} + + MOCK_CONST_METHOD0(DoB, int()); // NOLINT + MOCK_METHOD1(DoB, int(int n)); // NOLINT + + private: + GTEST_DISALLOW_COPY_AND_ASSIGN_(MockB); +}; + +class ReferenceHoldingMock { + public: + ReferenceHoldingMock() {} + + MOCK_METHOD1(AcceptReference, void(std::shared_ptr<MockA>*)); + + private: + GTEST_DISALLOW_COPY_AND_ASSIGN_(ReferenceHoldingMock); +}; + +// 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: + MockCC() {} + + MOCK_METHOD0(Method, int()); + + private: + GTEST_DISALLOW_COPY_AND_ASSIGN_(MockCC); +}; + +// 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, WithIsOptional) { + MockA a; + + ON_CALL(a, DoA(5)) + .WillByDefault(Return()); + ON_CALL(a, DoA(_)) + .With(_) + .WillByDefault(Return()); +} + +TEST(OnCallSyntaxTest, WithCanAppearAtMostOnce) { + MockA a; + + EXPECT_NONFATAL_FAILURE({ // NOLINT + ON_CALL(a, ReturnResult(_)) + .With(_) + .With(_) + .WillByDefault(Return(Result())); + }, ".With() cannot appear more than once in an ON_CALL()"); +} + +TEST(OnCallSyntaxTest, WillByDefaultIsMandatory) { + MockA a; + + EXPECT_DEATH_IF_SUPPORTED({ + ON_CALL(a, DoA(5)); + a.DoA(5); + }, ""); +} + +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, WithIsOptional) { + MockA a; + + EXPECT_CALL(a, DoA(5)) + .Times(0); + EXPECT_CALL(a, DoA(6)) + .With(_) + .Times(0); +} + +TEST(ExpectCallSyntaxTest, WithCanAppearAtMostOnce) { + MockA a; + + EXPECT_NONFATAL_FAILURE({ // NOLINT + EXPECT_CALL(a, DoA(6)) + .With(_) + .With(_); + }, ".With() cannot appear more than once in an EXPECT_CALL()"); + + a.DoA(6); +} + +TEST(ExpectCallSyntaxTest, WithMustBeFirstClause) { + MockA a; + + EXPECT_NONFATAL_FAILURE({ // NOLINT + EXPECT_CALL(a, DoA(1)) + .Times(1) + .With(_); + }, ".With() must be the first clause in an EXPECT_CALL()"); + + a.DoA(1); + + EXPECT_NONFATAL_FAILURE({ // NOLINT + EXPECT_CALL(a, DoA(2)) + .WillOnce(Return()) + .With(_); + }, ".With() 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, InSequenceMustBeBeforeAfter) { + MockA a; + Sequence s; + + Expectation e = EXPECT_CALL(a, DoA(1)) + .Times(AnyNumber()); + EXPECT_NONFATAL_FAILURE({ // NOLINT + EXPECT_CALL(a, DoA(2)) + .After(e) + .InSequence(s); + }, ".InSequence() cannot appear after "); + + a.DoA(2); +} + +TEST(ExpectCallSyntaxTest, InSequenceMustBeBeforeWillOnce) { + 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, AfterMustBeBeforeWillOnce) { + MockA a; + + Expectation e = EXPECT_CALL(a, DoA(1)); + EXPECT_NONFATAL_FAILURE({ + EXPECT_CALL(a, DoA(2)) + .WillOnce(Return()) + .After(e); + }, ".After() cannot appear after "); + + a.DoA(1); + a.DoA(2); +} + +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"); +} + +#if GTEST_HAS_STREAM_REDIRECTION + +// Tests that Google Mock doesn't print a warning when the number of +// WillOnce() is adequate. +TEST(ExpectCallSyntaxTest, DoesNotWarnOnAdequateActionCount) { + CaptureStdout(); + { + 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); + } + EXPECT_STREQ("", GetCapturedStdout().c_str()); +} + +// Tests that Google Mock warns on having too many actions in an +// expectation compared to its cardinality. +TEST(ExpectCallSyntaxTest, WarnsOnTooManyActions) { + CaptureStdout(); + { + 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 std::string output = GetCapturedStdout(); + EXPECT_PRED_FORMAT2( + IsSubstring, + "Too many actions specified in EXPECT_CALL(b, DoB())...\n" + "Expected to be never called, but has 1 WillOnce().", + output); // #1 + EXPECT_PRED_FORMAT2( + IsSubstring, + "Too many actions specified in EXPECT_CALL(b, DoB())...\n" + "Expected to be called at most once, " + "but has 2 WillOnce()s.", + output); // #2 + EXPECT_PRED_FORMAT2( + IsSubstring, + "Too many actions specified in EXPECT_CALL(b, DoB(1))...\n" + "Expected to be called once, but has 2 WillOnce()s.", + output); // #3 + EXPECT_PRED_FORMAT2( + IsSubstring, + "Too many actions specified in EXPECT_CALL(b, DoB())...\n" + "Expected to be never called, but has 0 WillOnce()s " + "and a WillRepeatedly().", + output); // #4 + EXPECT_PRED_FORMAT2( + IsSubstring, + "Too many actions specified in EXPECT_CALL(b, DoB(2))...\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)); + + CaptureStdout(); + b.DoB(); + const std::string output = GetCapturedStdout(); + EXPECT_PRED_FORMAT2( + IsSubstring, + "Too few actions specified in EXPECT_CALL(b, DoB())...\n" + "Expected to be called between 2 and 3 times, " + "but has only 1 WillOnce().", + output); + b.DoB(); +} + +TEST(ExpectCallSyntaxTest, WarningIsErrorWithFlag) { + int original_behavior = testing::GMOCK_FLAG(default_mock_behavior); + + testing::GMOCK_FLAG(default_mock_behavior) = kAllow; + CaptureStdout(); + { + MockA a; + a.DoA(0); + } + std::string output = GetCapturedStdout(); + EXPECT_TRUE(output.empty()) << output; + + testing::GMOCK_FLAG(default_mock_behavior) = kWarn; + CaptureStdout(); + { + MockA a; + a.DoA(0); + } + std::string warning_output = GetCapturedStdout(); + EXPECT_PRED_FORMAT2(IsSubstring, "GMOCK WARNING", warning_output); + EXPECT_PRED_FORMAT2(IsSubstring, "Uninteresting mock function call", + warning_output); + + testing::GMOCK_FLAG(default_mock_behavior) = kFail; + EXPECT_NONFATAL_FAILURE({ + MockA a; + a.DoA(0); + }, "Uninteresting mock function call"); + + // Out of bounds values are converted to kWarn + testing::GMOCK_FLAG(default_mock_behavior) = -1; + CaptureStdout(); + { + MockA a; + a.DoA(0); + } + warning_output = GetCapturedStdout(); + EXPECT_PRED_FORMAT2(IsSubstring, "GMOCK WARNING", warning_output); + EXPECT_PRED_FORMAT2(IsSubstring, "Uninteresting mock function call", + warning_output); + testing::GMOCK_FLAG(default_mock_behavior) = 3; + CaptureStdout(); + { + MockA a; + a.DoA(0); + } + warning_output = GetCapturedStdout(); + EXPECT_PRED_FORMAT2(IsSubstring, "GMOCK WARNING", warning_output); + EXPECT_PRED_FORMAT2(IsSubstring, "Uninteresting mock function call", + warning_output); + + testing::GMOCK_FLAG(default_mock_behavior) = original_behavior; +} + +#endif // GTEST_HAS_STREAM_REDIRECTION + +// 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 EXPECT_CALL(b, DoB(5))...\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()); +} + +// 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()); +} + +#if GTEST_HAS_STREAM_REDIRECTION + +// 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)); + + CaptureStdout(); + 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 std::string output1 = GetCapturedStdout(); + EXPECT_STREQ("", output1.c_str()); + + CaptureStdout(); + EXPECT_EQ(0, b.DoB()); + EXPECT_EQ(0, b.DoB()); + const std::string output2 = GetCapturedStdout(); + EXPECT_THAT(output2.c_str(), + HasSubstr("Actions ran out in EXPECT_CALL(b, DoB())...\n" + "Called 3 times, but only 2 WillOnce()s are specified" + " - returning default value.")); + EXPECT_THAT(output2.c_str(), + HasSubstr("Actions ran out in EXPECT_CALL(b, DoB())...\n" + "Called 4 times, but only 2 WillOnce()s are specified" + " - returning default value.")); +} + +TEST(FunctionMockerMessageTest, ReportsExpectCallLocationForExhausedActions) { + MockB b; + std::string expect_call_location = FormatFileLocation(__FILE__, __LINE__ + 1); + EXPECT_CALL(b, DoB()).Times(AnyNumber()).WillOnce(Return(1)); + + EXPECT_EQ(1, b.DoB()); + + CaptureStdout(); + EXPECT_EQ(0, b.DoB()); + const std::string output = GetCapturedStdout(); + // The warning message should contain the call location. + EXPECT_PRED_FORMAT2(IsSubstring, expect_call_location, output); +} + +TEST(FunctionMockerMessageTest, + ReportsDefaultActionLocationOfUninterestingCallsForNaggyMock) { + std::string on_call_location; + CaptureStdout(); + { + NaggyMock<MockB> b; + on_call_location = FormatFileLocation(__FILE__, __LINE__ + 1); + ON_CALL(b, DoB(_)).WillByDefault(Return(0)); + b.DoB(0); + } + EXPECT_PRED_FORMAT2(IsSubstring, on_call_location, GetCapturedStdout()); +} + +#endif // GTEST_HAS_STREAM_REDIRECTION + +// 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: EXPECT_CALL(a2, DoA(1))...\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: EXPECT_CALL(a2, DoA(3))...\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); +} + +// 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::TestPartResult::kNonFatalFailure, r.type()); + + // Verifies that the failure message contains the two unsatisfied + // pre-requisites but not the satisfied one. +#if GTEST_USES_PCRE + EXPECT_THAT(r.message(), ContainsRegex( + // 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")); +#elif GTEST_USES_POSIX_RE + EXPECT_THAT(r.message(), ContainsRegex( + // 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")); +#else + // We can only use Google Test's own simple regex. + EXPECT_THAT(r.message(), ContainsRegex( + "the following immediate pre-requisites are not satisfied:")); + EXPECT_THAT(r.message(), ContainsRegex(": pre-requisite #0")); + EXPECT_THAT(r.message(), ContainsRegex(": pre-requisite #1")); +#endif // GTEST_USES_PCRE + + b.DoB(1); + b.DoB(3); + b.DoB(4); +} + +TEST(UndefinedReturnValueTest, + ReturnValueIsMandatoryWhenNotDefaultConstructible) { + MockA a; + // FIXME: We should really verify the output message, + // but we cannot yet due to that EXPECT_DEATH only captures stderr + // while Google Mock logs to stdout. +#if GTEST_HAS_EXCEPTIONS + EXPECT_ANY_THROW(a.ReturnNonDefaultConstructible()); +#else + EXPECT_DEATH_IF_SUPPORTED(a.ReturnNonDefaultConstructible(), ""); +#endif +} + +// 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); + } +} + +// Tests that the calls must be in strict order when a complete order +// is specified. +TEST(SequenceTest, CallsMustBeInStrictOrderWhenSaidSo1) { + MockA a; + ON_CALL(a, ReturnResult(_)) + .WillByDefault(Return(Result())); + + Sequence s; + EXPECT_CALL(a, ReturnResult(1)) + .InSequence(s); + EXPECT_CALL(a, ReturnResult(2)) + .InSequence(s); + EXPECT_CALL(a, ReturnResult(3)) + .InSequence(s); + + a.ReturnResult(1); + + // May only be called after a.ReturnResult(2). + EXPECT_NONFATAL_FAILURE(a.ReturnResult(3), "Unexpected mock function call"); + + a.ReturnResult(2); + a.ReturnResult(3); +} + +// Tests that the calls must be in strict order when a complete order +// is specified. +TEST(SequenceTest, CallsMustBeInStrictOrderWhenSaidSo2) { + MockA a; + ON_CALL(a, ReturnResult(_)) + .WillByDefault(Return(Result())); + + Sequence s; + EXPECT_CALL(a, ReturnResult(1)) + .InSequence(s); + EXPECT_CALL(a, ReturnResult(2)) + .InSequence(s); + + // May only be called after a.ReturnResult(1). + EXPECT_NONFATAL_FAILURE(a.ReturnResult(2), "Unexpected mock function call"); + + a.ReturnResult(1); + a.ReturnResult(2); +} + +// Tests specifying a DAG using multiple sequences. +class PartialOrderTest : public testing::Test { + protected: + PartialOrderTest() { + ON_CALL(a_, ReturnResult(_)) + .WillByDefault(Return(Result())); + + // Specifies this partial ordering: + // + // a.ReturnResult(1) ==> + // a.ReturnResult(2) * n ==> a.ReturnResult(3) + // b.DoB() * 2 ==> + Sequence x, y; + EXPECT_CALL(a_, ReturnResult(1)) + .InSequence(x); + EXPECT_CALL(b_, DoB()) + .Times(2) + .InSequence(y); + EXPECT_CALL(a_, ReturnResult(2)) + .Times(AnyNumber()) + .InSequence(x, y); + EXPECT_CALL(a_, ReturnResult(3)) + .InSequence(x); + } + + MockA a_; + MockB b_; +}; + +TEST_F(PartialOrderTest, CallsMustConformToSpecifiedDag1) { + a_.ReturnResult(1); + b_.DoB(); + + // May only be called after the second DoB(). + EXPECT_NONFATAL_FAILURE(a_.ReturnResult(2), "Unexpected mock function call"); + + b_.DoB(); + a_.ReturnResult(3); +} + +TEST_F(PartialOrderTest, CallsMustConformToSpecifiedDag2) { + // May only be called after ReturnResult(1). + EXPECT_NONFATAL_FAILURE(a_.ReturnResult(2), "Unexpected mock function call"); + + a_.ReturnResult(1); + b_.DoB(); + b_.DoB(); + a_.ReturnResult(3); +} + +TEST_F(PartialOrderTest, CallsMustConformToSpecifiedDag3) { + // May only be called last. + EXPECT_NONFATAL_FAILURE(a_.ReturnResult(3), "Unexpected mock function call"); + + a_.ReturnResult(1); + b_.DoB(); + b_.DoB(); + a_.ReturnResult(3); +} + +TEST_F(PartialOrderTest, CallsMustConformToSpecifiedDag4) { + a_.ReturnResult(1); + b_.DoB(); + b_.DoB(); + a_.ReturnResult(3); + + // May only be called before ReturnResult(3). + EXPECT_NONFATAL_FAILURE(a_.ReturnResult(2), "Unexpected mock function call"); +} + +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 Expectation. + +TEST(ExpectationTest, ConstrutorsWork) { + MockA a; + Expectation e1; // Default ctor. + + // Ctor from various forms of EXPECT_CALL. + Expectation e2 = EXPECT_CALL(a, DoA(2)); + Expectation e3 = EXPECT_CALL(a, DoA(3)).With(_); + { + Sequence s; + Expectation e4 = EXPECT_CALL(a, DoA(4)).Times(1); + Expectation e5 = EXPECT_CALL(a, DoA(5)).InSequence(s); + } + Expectation e6 = EXPECT_CALL(a, DoA(6)).After(e2); + Expectation e7 = EXPECT_CALL(a, DoA(7)).WillOnce(Return()); + Expectation e8 = EXPECT_CALL(a, DoA(8)).WillRepeatedly(Return()); + Expectation e9 = EXPECT_CALL(a, DoA(9)).RetiresOnSaturation(); + + Expectation e10 = e2; // Copy ctor. + + EXPECT_THAT(e1, Ne(e2)); + EXPECT_THAT(e2, Eq(e10)); + + a.DoA(2); + a.DoA(3); + a.DoA(4); + a.DoA(5); + a.DoA(6); + a.DoA(7); + a.DoA(8); + a.DoA(9); +} + +TEST(ExpectationTest, AssignmentWorks) { + MockA a; + Expectation e1; + Expectation e2 = EXPECT_CALL(a, DoA(1)); + + EXPECT_THAT(e1, Ne(e2)); + + e1 = e2; + EXPECT_THAT(e1, Eq(e2)); + + a.DoA(1); +} + +// Tests ExpectationSet. + +TEST(ExpectationSetTest, MemberTypesAreCorrect) { + ::testing::StaticAssertTypeEq<Expectation, ExpectationSet::value_type>(); +} + +TEST(ExpectationSetTest, ConstructorsWork) { + MockA a; + + Expectation e1; + const Expectation e2; + ExpectationSet es1; // Default ctor. + ExpectationSet es2 = EXPECT_CALL(a, DoA(1)); // Ctor from EXPECT_CALL. + ExpectationSet es3 = e1; // Ctor from Expectation. + ExpectationSet es4(e1); // Ctor from Expectation; alternative syntax. + ExpectationSet es5 = e2; // Ctor from const Expectation. + ExpectationSet es6(e2); // Ctor from const Expectation; alternative syntax. + ExpectationSet es7 = es2; // Copy ctor. + + EXPECT_EQ(0, es1.size()); + EXPECT_EQ(1, es2.size()); + EXPECT_EQ(1, es3.size()); + EXPECT_EQ(1, es4.size()); + EXPECT_EQ(1, es5.size()); + EXPECT_EQ(1, es6.size()); + EXPECT_EQ(1, es7.size()); + + EXPECT_THAT(es3, Ne(es2)); + EXPECT_THAT(es4, Eq(es3)); + EXPECT_THAT(es5, Eq(es4)); + EXPECT_THAT(es6, Eq(es5)); + EXPECT_THAT(es7, Eq(es2)); + a.DoA(1); +} + +TEST(ExpectationSetTest, AssignmentWorks) { + ExpectationSet es1; + ExpectationSet es2 = Expectation(); + + es1 = es2; + EXPECT_EQ(1, es1.size()); + EXPECT_THAT(*(es1.begin()), Eq(Expectation())); + EXPECT_THAT(es1, Eq(es2)); +} + +TEST(ExpectationSetTest, InsertionWorks) { + ExpectationSet es1; + Expectation e1; + es1 += e1; + EXPECT_EQ(1, es1.size()); + EXPECT_THAT(*(es1.begin()), Eq(e1)); + + MockA a; + Expectation e2 = EXPECT_CALL(a, DoA(1)); + es1 += e2; + EXPECT_EQ(2, es1.size()); + + ExpectationSet::const_iterator it1 = es1.begin(); + ExpectationSet::const_iterator it2 = it1; + ++it2; + EXPECT_TRUE(*it1 == e1 || *it2 == e1); // e1 must be in the set. + EXPECT_TRUE(*it1 == e2 || *it2 == e2); // e2 must be in the set too. + a.DoA(1); +} + +TEST(ExpectationSetTest, SizeWorks) { + ExpectationSet es; + EXPECT_EQ(0, es.size()); + + es += Expectation(); + EXPECT_EQ(1, es.size()); + + MockA a; + es += EXPECT_CALL(a, DoA(1)); + EXPECT_EQ(2, es.size()); + + a.DoA(1); +} + +TEST(ExpectationSetTest, IsEnumerable) { + ExpectationSet es; + EXPECT_TRUE(es.begin() == es.end()); + + es += Expectation(); + ExpectationSet::const_iterator it = es.begin(); + EXPECT_TRUE(it != es.end()); + EXPECT_THAT(*it, Eq(Expectation())); + ++it; + EXPECT_TRUE(it== es.end()); +} + +// Tests the .After() clause. + +TEST(AfterTest, SucceedsWhenPartialOrderIsSatisfied) { + MockA a; + ExpectationSet es; + es += EXPECT_CALL(a, DoA(1)); + es += EXPECT_CALL(a, DoA(2)); + EXPECT_CALL(a, DoA(3)) + .After(es); + + a.DoA(1); + a.DoA(2); + a.DoA(3); +} + +TEST(AfterTest, SucceedsWhenTotalOrderIsSatisfied) { + MockA a; + MockB b; + // The following also verifies that const Expectation objects work + // too. Do not remove the const modifiers. + const Expectation e1 = EXPECT_CALL(a, DoA(1)); + const Expectation e2 = EXPECT_CALL(b, DoB()) + .Times(2) + .After(e1); + EXPECT_CALL(a, DoA(2)).After(e2); + + a.DoA(1); + b.DoB(); + b.DoB(); + a.DoA(2); +} + +// Calls must be in strict order when specified so using .After(). +TEST(AfterTest, CallsMustBeInStrictOrderWhenSpecifiedSo1) { + MockA a; + MockB b; + + // Define ordering: + // a.DoA(1) ==> b.DoB() ==> a.DoA(2) + Expectation e1 = EXPECT_CALL(a, DoA(1)); + Expectation e2 = EXPECT_CALL(b, DoB()) + .After(e1); + EXPECT_CALL(a, DoA(2)) + .After(e2); + + a.DoA(1); + + // May only be called after DoB(). + EXPECT_NONFATAL_FAILURE(a.DoA(2), "Unexpected mock function call"); + + b.DoB(); + a.DoA(2); +} + +// Calls must be in strict order when specified so using .After(). +TEST(AfterTest, CallsMustBeInStrictOrderWhenSpecifiedSo2) { + MockA a; + MockB b; + + // Define ordering: + // a.DoA(1) ==> b.DoB() * 2 ==> a.DoA(2) + Expectation e1 = EXPECT_CALL(a, DoA(1)); + Expectation e2 = EXPECT_CALL(b, DoB()) + .Times(2) + .After(e1); + EXPECT_CALL(a, DoA(2)) + .After(e2); + + a.DoA(1); + b.DoB(); + + // May only be called after the second DoB(). + EXPECT_NONFATAL_FAILURE(a.DoA(2), "Unexpected mock function call"); + + b.DoB(); + a.DoA(2); +} + +// Calls must satisfy the partial order when specified so. +TEST(AfterTest, CallsMustSatisfyPartialOrderWhenSpecifiedSo) { + MockA a; + ON_CALL(a, ReturnResult(_)) + .WillByDefault(Return(Result())); + + // Define ordering: + // a.DoA(1) ==> + // a.DoA(2) ==> a.ReturnResult(3) + Expectation e = EXPECT_CALL(a, DoA(1)); + const ExpectationSet es = EXPECT_CALL(a, DoA(2)); + EXPECT_CALL(a, ReturnResult(3)) + .After(e, es); + + // May only be called last. + EXPECT_NONFATAL_FAILURE(a.ReturnResult(3), "Unexpected mock function call"); + + a.DoA(2); + a.DoA(1); + a.ReturnResult(3); +} + +// Calls must satisfy the partial order when specified so. +TEST(AfterTest, CallsMustSatisfyPartialOrderWhenSpecifiedSo2) { + MockA a; + + // Define ordering: + // a.DoA(1) ==> + // a.DoA(2) ==> a.DoA(3) + Expectation e = EXPECT_CALL(a, DoA(1)); + const ExpectationSet es = EXPECT_CALL(a, DoA(2)); + EXPECT_CALL(a, DoA(3)) + .After(e, es); + + a.DoA(2); + + // May only be called last. + EXPECT_NONFATAL_FAILURE(a.DoA(3), "Unexpected mock function call"); + + a.DoA(1); + a.DoA(3); +} + +// .After() can be combined with .InSequence(). +TEST(AfterTest, CanBeUsedWithInSequence) { + MockA a; + Sequence s; + Expectation e = EXPECT_CALL(a, DoA(1)); + EXPECT_CALL(a, DoA(2)).InSequence(s); + EXPECT_CALL(a, DoA(3)) + .InSequence(s) + .After(e); + + a.DoA(1); + + // May only be after DoA(2). + EXPECT_NONFATAL_FAILURE(a.DoA(3), "Unexpected mock function call"); + + a.DoA(2); + a.DoA(3); +} + +// .After() can be called multiple times. +TEST(AfterTest, CanBeCalledManyTimes) { + MockA a; + Expectation e1 = EXPECT_CALL(a, DoA(1)); + Expectation e2 = EXPECT_CALL(a, DoA(2)); + Expectation e3 = EXPECT_CALL(a, DoA(3)); + EXPECT_CALL(a, DoA(4)) + .After(e1) + .After(e2) + .After(e3); + + a.DoA(3); + a.DoA(1); + a.DoA(2); + a.DoA(4); +} + +// .After() accepts up to 5 arguments. +TEST(AfterTest, AcceptsUpToFiveArguments) { + MockA a; + Expectation e1 = EXPECT_CALL(a, DoA(1)); + Expectation e2 = EXPECT_CALL(a, DoA(2)); + Expectation e3 = EXPECT_CALL(a, DoA(3)); + ExpectationSet es1 = EXPECT_CALL(a, DoA(4)); + ExpectationSet es2 = EXPECT_CALL(a, DoA(5)); + EXPECT_CALL(a, DoA(6)) + .After(e1, e2, e3, es1, es2); + + a.DoA(5); + a.DoA(2); + a.DoA(4); + a.DoA(1); + a.DoA(3); + a.DoA(6); +} + +// .After() allows input to contain duplicated Expectations. +TEST(AfterTest, AcceptsDuplicatedInput) { + MockA a; + ON_CALL(a, ReturnResult(_)) + .WillByDefault(Return(Result())); + + // Define ordering: + // DoA(1) ==> + // DoA(2) ==> ReturnResult(3) + Expectation e1 = EXPECT_CALL(a, DoA(1)); + Expectation e2 = EXPECT_CALL(a, DoA(2)); + ExpectationSet es; + es += e1; + es += e2; + EXPECT_CALL(a, ReturnResult(3)) + .After(e1, e2, es, e1); + + a.DoA(1); + + // May only be after DoA(2). + EXPECT_NONFATAL_FAILURE(a.ReturnResult(3), "Unexpected mock function call"); + + a.DoA(2); + a.ReturnResult(3); +} + +// An Expectation added to an ExpectationSet after it has been used in +// an .After() has no effect. +TEST(AfterTest, ChangesToExpectationSetHaveNoEffectAfterwards) { + MockA a; + ExpectationSet es1 = EXPECT_CALL(a, DoA(1)); + Expectation e2 = EXPECT_CALL(a, DoA(2)); + EXPECT_CALL(a, DoA(3)) + .After(es1); + es1 += e2; + + a.DoA(1); + a.DoA(3); + a.DoA(2); +} + +// 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 it's OK to delete a mock object itself in its action. + +// Suppresses warning on unreferenced formal parameter in MSVC with +// -W4. +#ifdef _MSC_VER +# pragma warning(push) +# pragma warning(disable:4100) +#endif + +ACTION_P(Delete, ptr) { delete ptr; } + +#ifdef _MSC_VER +# pragma warning(pop) +#endif + +TEST(DeletingMockEarlyTest, CanDeleteSelfInActionReturningVoid) { + MockA* const a = new MockA; + EXPECT_CALL(*a, DoA(_)).WillOnce(Delete(a)); + a->DoA(42); // This will cause a to be deleted. +} + +TEST(DeletingMockEarlyTest, CanDeleteSelfInActionReturningValue) { + MockA* const a = new MockA; + EXPECT_CALL(*a, ReturnResult(_)) + .WillOnce(DoAll(Delete(a), Return(Result()))); + a->ReturnResult(42); // This will cause a to be deleted. +} + +// Tests that calls that violate 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 violate 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 if and only if call_count calls will satisfy this + // cardinality. + bool IsSatisfiedByCallCount(int call_count) const override { + return call_count % 2 == 0; + } + + // Returns true if and only if call_count calls will saturate this + // cardinality. + bool IsSaturatedByCallCount(int /* call_count */) const override { + return false; + } + + // Describes self to an ostream. + void DescribeTo(::std::ostream* os) const override { + *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: + MockC() {} + + MOCK_METHOD6(VoidMethod, void(bool cond, int n, std::string s, void* p, + const Printable& x, Unprintable y)); + MOCK_METHOD0(NonVoidMethod, int()); // NOLINT + + private: + GTEST_DISALLOW_COPY_AND_ASSIGN_(MockC); +}; + +class VerboseFlagPreservingFixture : public testing::Test { + protected: + VerboseFlagPreservingFixture() + : saved_verbose_flag_(GMOCK_FLAG(verbose)) {} + + ~VerboseFlagPreservingFixture() override { + GMOCK_FLAG(verbose) = saved_verbose_flag_; + } + + private: + const std::string saved_verbose_flag_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(VerboseFlagPreservingFixture); +}; + +#if GTEST_HAS_STREAM_REDIRECTION + +// Tests that an uninteresting mock function call on a naggy mock +// generates a warning without the stack trace when +// --gmock_verbose=warning is specified. +TEST(FunctionCallMessageTest, + UninterestingCallOnNaggyMockGeneratesNoStackTraceWhenVerboseWarning) { + GMOCK_FLAG(verbose) = kWarningVerbosity; + NaggyMock<MockC> c; + CaptureStdout(); + c.VoidMethod(false, 5, "Hi", nullptr, Printable(), Unprintable()); + const std::string output = GetCapturedStdout(); + EXPECT_PRED_FORMAT2(IsSubstring, "GMOCK WARNING", output); + EXPECT_PRED_FORMAT2(IsNotSubstring, "Stack trace:", output); +} + +// Tests that an uninteresting mock function call on a naggy mock +// generates a warning containing the stack trace when +// --gmock_verbose=info is specified. +TEST(FunctionCallMessageTest, + UninterestingCallOnNaggyMockGeneratesFyiWithStackTraceWhenVerboseInfo) { + GMOCK_FLAG(verbose) = kInfoVerbosity; + NaggyMock<MockC> c; + CaptureStdout(); + c.VoidMethod(false, 5, "Hi", nullptr, Printable(), Unprintable()); + const std::string output = GetCapturedStdout(); + 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, "VoidMethod(", output); + + // Verifies that a non-void mock function's name appears in the + // stack trace. + CaptureStdout(); + c.NonVoidMethod(); + const std::string output2 = GetCapturedStdout(); + EXPECT_PRED_FORMAT2(IsSubstring, "NonVoidMethod(", output2); + +# endif // NDEBUG +} + +// Tests that an uninteresting mock function call on a naggy mock +// causes the function arguments and return value to be printed. +TEST(FunctionCallMessageTest, + UninterestingCallOnNaggyMockPrintsArgumentsAndReturnValue) { + // A non-void mock function. + NaggyMock<MockB> b; + CaptureStdout(); + b.DoB(); + const std::string output1 = GetCapturedStdout(); + EXPECT_PRED_FORMAT2( + IsSubstring, + "Uninteresting mock function call - returning default value.\n" + " Function call: DoB()\n" + " Returns: 0\n", output1.c_str()); + // Makes sure the return value is printed. + + // A void mock function. + NaggyMock<MockC> c; + CaptureStdout(); + c.VoidMethod(false, 5, "Hi", nullptr, Printable(), Unprintable()); + const std::string output2 = GetCapturedStdout(); + EXPECT_THAT(output2.c_str(), + ContainsRegex( + "Uninteresting mock function call - returning directly\\.\n" + " Function call: VoidMethod" + "\\(false, 5, \"Hi\", NULL, @.+ " + "Printable, 4-byte object <00-00 00-00>\\)")); + // A void function has no return value to print. +} + +// Tests how the --gmock_verbose flag affects Google Mock's output. + +class GMockVerboseFlagTest : public VerboseFlagPreservingFixture { + 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 std::string& output, bool should_print, + const std::string& expected_substring, + const std::string& function_name) { + if (should_print) { + EXPECT_THAT(output.c_str(), HasSubstr(expected_substring)); +# 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_THAT(output.c_str(), HasSubstr(function_name)); +# else + // Suppresses 'unused function parameter' warnings. + static_cast<void>(function_name); +# endif // NDEBUG + } else { + EXPECT_STREQ("", output.c_str()); + } + } + + // 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. + CaptureStdout(); + a.DoA(5); + VerifyOutput( + GetCapturedStdout(), + should_print, + "Mock function call matches EXPECT_CALL(a, DoA(5))...\n" + " Function call: DoA(5)\n" + "Stack trace:\n", + "DoA"); + + // A non-void-returning function. + CaptureStdout(); + a.Binary(2, 1); + VerifyOutput( + GetCapturedStdout(), + should_print, + "Mock function call matches EXPECT_CALL(a, Binary(_, 1))...\n" + " Function call: Binary(2, 1)\n" + " Returns: true\n" + "Stack trace:\n", + "Binary"); + } + + // Tests how the flag affects uninteresting calls on a naggy mock. + void TestUninterestingCallOnNaggyMock(bool should_print) { + NaggyMock<MockA> a; + const std::string note = + "NOTE: You can safely ignore the above warning unless this " + "call should not happen. Do not suppress it by blindly adding " + "an EXPECT_CALL() if you don't mean to enforce the call. " + "See " + "https://github.com/google/googletest/blob/master/googlemock/docs/" + "cook_book.md#" + "knowing-when-to-expect for details."; + + // A void-returning function. + CaptureStdout(); + a.DoA(5); + VerifyOutput( + GetCapturedStdout(), + should_print, + "\nGMOCK WARNING:\n" + "Uninteresting mock function call - returning directly.\n" + " Function call: DoA(5)\n" + + note, + "DoA"); + + // A non-void-returning function. + CaptureStdout(); + a.Binary(2, 1); + VerifyOutput( + GetCapturedStdout(), + should_print, + "\nGMOCK WARNING:\n" + "Uninteresting mock function call - returning default value.\n" + " Function call: Binary(2, 1)\n" + " Returns: false\n" + + note, + "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); + TestUninterestingCallOnNaggyMock(true); +} + +// Tests that --gmock_verbose=warning causes uninteresting calls to be +// reported. +TEST_F(GMockVerboseFlagTest, Warning) { + GMOCK_FLAG(verbose) = kWarningVerbosity; + TestExpectedCall(false); + TestUninterestingCallOnNaggyMock(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); + TestUninterestingCallOnNaggyMock(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); + TestUninterestingCallOnNaggyMock(true); +} + +#endif // GTEST_HAS_STREAM_REDIRECTION + +// A helper class that generates a failure when printed. We use it to +// ensure that Google Mock doesn't print a value (even to an internal +// buffer) when it is not supposed to do so. +class PrintMeNot {}; + +void PrintTo(PrintMeNot /* dummy */, ::std::ostream* /* os */) { + ADD_FAILURE() << "Google Mock is printing a value that shouldn't be " + << "printed even to an internal buffer."; +} + +class LogTestHelper { + public: + LogTestHelper() {} + + MOCK_METHOD1(Foo, PrintMeNot(PrintMeNot)); + + private: + GTEST_DISALLOW_COPY_AND_ASSIGN_(LogTestHelper); +}; + +class GMockLogTest : public VerboseFlagPreservingFixture { + protected: + LogTestHelper helper_; +}; + +TEST_F(GMockLogTest, DoesNotPrintGoodCallInternallyIfVerbosityIsWarning) { + GMOCK_FLAG(verbose) = kWarningVerbosity; + EXPECT_CALL(helper_, Foo(_)) + .WillOnce(Return(PrintMeNot())); + helper_.Foo(PrintMeNot()); // This is an expected call. +} + +TEST_F(GMockLogTest, DoesNotPrintGoodCallInternallyIfVerbosityIsError) { + GMOCK_FLAG(verbose) = kErrorVerbosity; + EXPECT_CALL(helper_, Foo(_)) + .WillOnce(Return(PrintMeNot())); + helper_.Foo(PrintMeNot()); // This is an expected call. +} + +TEST_F(GMockLogTest, DoesNotPrintWarningInternallyIfVerbosityIsError) { + GMOCK_FLAG(verbose) = kErrorVerbosity; + ON_CALL(helper_, Foo(_)) + .WillByDefault(Return(PrintMeNot())); + helper_.Foo(PrintMeNot()); // This should generate a warning. +} + +// Tests Mock::AllowLeak(). + +TEST(AllowLeakTest, AllowsLeakingUnusedMockObject) { + MockA* a = new MockA; + Mock::AllowLeak(a); +} + +TEST(AllowLeakTest, CanBeCalledBeforeOnCall) { + MockA* a = new MockA; + Mock::AllowLeak(a); + ON_CALL(*a, DoA(_)).WillByDefault(Return()); + a->DoA(0); +} + +TEST(AllowLeakTest, CanBeCalledAfterOnCall) { + MockA* a = new MockA; + ON_CALL(*a, DoA(_)).WillByDefault(Return()); + Mock::AllowLeak(a); +} + +TEST(AllowLeakTest, CanBeCalledBeforeExpectCall) { + MockA* a = new MockA; + Mock::AllowLeak(a); + EXPECT_CALL(*a, DoA(_)); + a->DoA(0); +} + +TEST(AllowLeakTest, CanBeCalledAfterExpectCall) { + MockA* a = new MockA; + EXPECT_CALL(*a, DoA(_)).Times(AnyNumber()); + Mock::AllowLeak(a); +} + +TEST(AllowLeakTest, WorksWhenBothOnCallAndExpectCallArePresent) { + MockA* a = new MockA; + ON_CALL(*a, DoA(_)).WillByDefault(Return()); + EXPECT_CALL(*a, DoA(_)).Times(AnyNumber()); + Mock::AllowLeak(a); +} + +// 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 = true; + 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 = true; + 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 = true; + 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)); +} + +TEST(VerifyAndClearTest, + DestroyingChainedMocksDoesNotDeadlockThroughExpectations) { + std::shared_ptr<MockA> a(new MockA); + ReferenceHoldingMock test_mock; + + // EXPECT_CALL stores a reference to a inside test_mock. + EXPECT_CALL(test_mock, AcceptReference(_)) + .WillRepeatedly(SetArgPointee<0>(a)); + + // Throw away the reference to the mock that we have in a. After this, the + // only reference to it is stored by test_mock. + a.reset(); + + // When test_mock goes out of scope, it destroys the last remaining reference + // to the mock object originally pointed to by a. This will cause the MockA + // destructor to be called from inside the ReferenceHoldingMock destructor. + // The state of all mocks is protected by a single global lock, but there + // should be no deadlock. +} + +TEST(VerifyAndClearTest, + DestroyingChainedMocksDoesNotDeadlockThroughDefaultAction) { + std::shared_ptr<MockA> a(new MockA); + ReferenceHoldingMock test_mock; + + // ON_CALL stores a reference to a inside test_mock. + ON_CALL(test_mock, AcceptReference(_)) + .WillByDefault(SetArgPointee<0>(a)); + + // Throw away the reference to the mock that we have in a. After this, the + // only reference to it is stored by test_mock. + a.reset(); + + // When test_mock goes out of scope, it destroys the last remaining reference + // to the mock object originally pointed to by a. This will cause the MockA + // destructor to be called from inside the ReferenceHoldingMock destructor. + // The state of all mocks is protected by a single global lock, but there + // should be no deadlock. +} + +// 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. +TEST(SynchronizationTest, CanCallMockMethodInAction) { + MockA a; + MockC c; + ON_CALL(a, DoA(_)) + .WillByDefault(IgnoreResult(InvokeWithoutArgs(&c, + &MockC::NonVoidMethod))); + EXPECT_CALL(a, DoA(1)); + EXPECT_CALL(a, DoA(1)) + .WillOnce(Invoke(&a, &MockA::DoA)) + .RetiresOnSaturation(); + EXPECT_CALL(c, NonVoidMethod()); + + a.DoA(1); + // This will match the second EXPECT_CALL() and trigger another a.DoA(1), + // which will in turn match the first EXPECT_CALL() and trigger a call to + // c.NonVoidMethod() that was specified by the ON_CALL() since the first + // EXPECT_CALL() did not specify an action. +} + +TEST(ParameterlessExpectationsTest, CanSetExpectationsWithoutMatchers) { + MockA a; + int do_a_arg0 = 0; + ON_CALL(a, DoA).WillByDefault(SaveArg<0>(&do_a_arg0)); + int do_a_47_arg0 = 0; + ON_CALL(a, DoA(47)).WillByDefault(SaveArg<0>(&do_a_47_arg0)); + + a.DoA(17); + EXPECT_THAT(do_a_arg0, 17); + EXPECT_THAT(do_a_47_arg0, 0); + a.DoA(47); + EXPECT_THAT(do_a_arg0, 17); + EXPECT_THAT(do_a_47_arg0, 47); + + ON_CALL(a, Binary).WillByDefault(Return(true)); + ON_CALL(a, Binary(_, 14)).WillByDefault(Return(false)); + EXPECT_THAT(a.Binary(14, 17), true); + EXPECT_THAT(a.Binary(17, 14), false); +} + +TEST(ParameterlessExpectationsTest, CanSetExpectationsForOverloadedMethods) { + MockB b; + ON_CALL(b, DoB()).WillByDefault(Return(9)); + ON_CALL(b, DoB(5)).WillByDefault(Return(11)); + + EXPECT_THAT(b.DoB(), 9); + EXPECT_THAT(b.DoB(1), 0); // default value + EXPECT_THAT(b.DoB(5), 11); +} + +struct MockWithConstMethods { + public: + MOCK_CONST_METHOD1(Foo, int(int)); + MOCK_CONST_METHOD2(Bar, int(int, const char*)); +}; + +TEST(ParameterlessExpectationsTest, CanSetExpectationsForConstMethods) { + MockWithConstMethods mock; + ON_CALL(mock, Foo).WillByDefault(Return(7)); + ON_CALL(mock, Bar).WillByDefault(Return(33)); + + EXPECT_THAT(mock.Foo(17), 7); + EXPECT_THAT(mock.Bar(27, "purple"), 33); +} + +class MockConstOverload { + public: + MOCK_METHOD1(Overloaded, int(int)); + MOCK_CONST_METHOD1(Overloaded, int(int)); +}; + +TEST(ParameterlessExpectationsTest, + CanSetExpectationsForConstOverloadedMethods) { + MockConstOverload mock; + ON_CALL(mock, Overloaded(_)).WillByDefault(Return(7)); + ON_CALL(mock, Overloaded(5)).WillByDefault(Return(9)); + ON_CALL(Const(mock), Overloaded(5)).WillByDefault(Return(11)); + ON_CALL(Const(mock), Overloaded(7)).WillByDefault(Return(13)); + + EXPECT_THAT(mock.Overloaded(1), 7); + EXPECT_THAT(mock.Overloaded(5), 9); + EXPECT_THAT(mock.Overloaded(7), 7); + + const MockConstOverload& const_mock = mock; + EXPECT_THAT(const_mock.Overloaded(1), 0); + EXPECT_THAT(const_mock.Overloaded(5), 11); + EXPECT_THAT(const_mock.Overloaded(7), 13); +} + +} // namespace + +// Allows the user to define their own main and then invoke gmock_main +// from it. This might be necessary on some platforms which require +// specific setup and teardown. +#if GMOCK_RENAME_MAIN +int gmock_main(int argc, char **argv) { +#else +int main(int argc, char **argv) { +#endif // GMOCK_RENAME_MAIN + testing::InitGoogleMock(&argc, argv); + // Ensures that the tests pass no matter what value of + // --gmock_catch_leaked_mocks and --gmock_verbose the user specifies. + testing::GMOCK_FLAG(catch_leaked_mocks) = true; + testing::GMOCK_FLAG(verbose) = testing::internal::kWarningVerbosity; + + return RUN_ALL_TESTS(); +} diff --git a/src/googletest/googlemock/test/gmock_all_test.cc b/src/googletest/googlemock/test/gmock_all_test.cc new file mode 100644 index 000000000..6187d4ad1 --- /dev/null +++ b/src/googletest/googlemock/test/gmock_all_test.cc @@ -0,0 +1,47 @@ +// Copyright 2009, 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 for Google C++ Mocking Framework (Google Mock) +// +// Some users use a build system that Google Mock doesn't support directly, +// yet they still want to build and run Google Mock's own tests. This file +// includes most such tests, making it easier for these users to maintain +// their build scripts (they just need to build this file, even though the +// below list of actual *_test.cc files might change). +#include "test/gmock-actions_test.cc" +#include "test/gmock-cardinalities_test.cc" +#include "test/gmock-generated-actions_test.cc" +#include "test/gmock-internal-utils_test.cc" +#include "test/gmock-matchers_test.cc" +#include "test/gmock-more-actions_test.cc" +#include "test/gmock-nice-strict_test.cc" +#include "test/gmock-port_test.cc" +#include "test/gmock-spec-builders_test.cc" +#include "test/gmock_test.cc" diff --git a/src/googletest/googlemock/test/gmock_ex_test.cc b/src/googletest/googlemock/test/gmock_ex_test.cc new file mode 100644 index 000000000..72eb43f74 --- /dev/null +++ b/src/googletest/googlemock/test/gmock_ex_test.cc @@ -0,0 +1,80 @@ +// Copyright 2013, 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 Google Mock's functionality that depends on exceptions. + +#include "gmock/gmock.h" +#include "gtest/gtest.h" + +#if GTEST_HAS_EXCEPTIONS +namespace { + +using testing::HasSubstr; + +using testing::internal::GoogleTestFailureException; + +// A type that cannot be default constructed. +class NonDefaultConstructible { + public: + explicit NonDefaultConstructible(int /* dummy */) {} +}; + +class MockFoo { + public: + // A mock method that returns a user-defined type. Google Mock + // doesn't know what the default value for this type is. + MOCK_METHOD0(GetNonDefaultConstructible, NonDefaultConstructible()); +}; + +TEST(DefaultValueTest, ThrowsRuntimeErrorWhenNoDefaultValue) { + MockFoo mock; + try { + // No expectation is set on this method, so Google Mock must + // return the default value. However, since Google Mock knows + // nothing about the return type, it doesn't know what to return, + // and has to throw (when exceptions are enabled) or abort + // (otherwise). + mock.GetNonDefaultConstructible(); + FAIL() << "GetNonDefaultConstructible()'s return type has no default " + << "value, so Google Mock should have thrown."; + } catch (const GoogleTestFailureException& /* unused */) { + FAIL() << "Google Test does not try to catch an exception of type " + << "GoogleTestFailureException, which is used for reporting " + << "a failure to other testing frameworks. Google Mock should " + << "not throw a GoogleTestFailureException as it will kill the " + << "entire test program instead of just the current TEST."; + } catch (const std::exception& ex) { + EXPECT_THAT(ex.what(), HasSubstr("has no default value")); + } +} + + +} // unnamed namespace +#endif diff --git a/src/googletest/googlemock/test/gmock_leak_test.py b/src/googletest/googlemock/test/gmock_leak_test.py new file mode 100755 index 000000000..7e4b1eea9 --- /dev/null +++ b/src/googletest/googlemock/test/gmock_leak_test.py @@ -0,0 +1,104 @@ +#!/usr/bin/env python +# +# Copyright 2009, 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 that leaked mock objects can be caught be Google Mock.""" + +import gmock_test_utils + +PROGRAM_PATH = gmock_test_utils.GetTestExecutablePath('gmock_leak_test_') +TEST_WITH_EXPECT_CALL = [PROGRAM_PATH, '--gtest_filter=*ExpectCall*'] +TEST_WITH_ON_CALL = [PROGRAM_PATH, '--gtest_filter=*OnCall*'] +TEST_MULTIPLE_LEAKS = [PROGRAM_PATH, '--gtest_filter=*MultipleLeaked*'] + +environ = gmock_test_utils.environ +SetEnvVar = gmock_test_utils.SetEnvVar + +# Tests in this file run a Google-Test-based test program and expect it +# to terminate prematurely. Therefore they are incompatible with +# the premature-exit-file protocol by design. Unset the +# premature-exit filepath to prevent Google Test from creating +# the file. +SetEnvVar(gmock_test_utils.PREMATURE_EXIT_FILE_ENV_VAR, None) + + +class GMockLeakTest(gmock_test_utils.TestCase): + + def testCatchesLeakedMockByDefault(self): + self.assertNotEqual( + 0, + gmock_test_utils.Subprocess(TEST_WITH_EXPECT_CALL, + env=environ).exit_code) + self.assertNotEqual( + 0, + gmock_test_utils.Subprocess(TEST_WITH_ON_CALL, + env=environ).exit_code) + + def testDoesNotCatchLeakedMockWhenDisabled(self): + self.assertEquals( + 0, + gmock_test_utils.Subprocess(TEST_WITH_EXPECT_CALL + + ['--gmock_catch_leaked_mocks=0'], + env=environ).exit_code) + self.assertEquals( + 0, + gmock_test_utils.Subprocess(TEST_WITH_ON_CALL + + ['--gmock_catch_leaked_mocks=0'], + env=environ).exit_code) + + def testCatchesLeakedMockWhenEnabled(self): + self.assertNotEqual( + 0, + gmock_test_utils.Subprocess(TEST_WITH_EXPECT_CALL + + ['--gmock_catch_leaked_mocks'], + env=environ).exit_code) + self.assertNotEqual( + 0, + gmock_test_utils.Subprocess(TEST_WITH_ON_CALL + + ['--gmock_catch_leaked_mocks'], + env=environ).exit_code) + + def testCatchesLeakedMockWhenEnabledWithExplictFlagValue(self): + self.assertNotEqual( + 0, + gmock_test_utils.Subprocess(TEST_WITH_EXPECT_CALL + + ['--gmock_catch_leaked_mocks=1'], + env=environ).exit_code) + + def testCatchesMultipleLeakedMocks(self): + self.assertNotEqual( + 0, + gmock_test_utils.Subprocess(TEST_MULTIPLE_LEAKS + + ['--gmock_catch_leaked_mocks'], + env=environ).exit_code) + + +if __name__ == '__main__': + gmock_test_utils.Main() diff --git a/src/googletest/googlemock/test/gmock_leak_test_.cc b/src/googletest/googlemock/test/gmock_leak_test_.cc new file mode 100644 index 000000000..2e095abcf --- /dev/null +++ b/src/googletest/googlemock/test/gmock_leak_test_.cc @@ -0,0 +1,99 @@ +// Copyright 2009, 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 program is for verifying that a leaked mock object can be +// caught by Google Mock's leak detector. + +#include "gmock/gmock.h" + +namespace { + +using ::testing::Return; + +class FooInterface { + public: + virtual ~FooInterface() {} + virtual void DoThis() = 0; +}; + +class MockFoo : public FooInterface { + public: + MockFoo() {} + + MOCK_METHOD0(DoThis, void()); + + private: + GTEST_DISALLOW_COPY_AND_ASSIGN_(MockFoo); +}; + +TEST(LeakTest, LeakedMockWithExpectCallCausesFailureWhenLeakCheckingIsEnabled) { + MockFoo* foo = new MockFoo; + + EXPECT_CALL(*foo, DoThis()); + foo->DoThis(); + + // In order to test the leak detector, we deliberately leak foo. + + // Makes sure Google Mock's leak detector can change the exit code + // to 1 even when the code is already exiting with 0. + exit(0); +} + +TEST(LeakTest, LeakedMockWithOnCallCausesFailureWhenLeakCheckingIsEnabled) { + MockFoo* foo = new MockFoo; + + ON_CALL(*foo, DoThis()).WillByDefault(Return()); + + // In order to test the leak detector, we deliberately leak foo. + + // Makes sure Google Mock's leak detector can change the exit code + // to 1 even when the code is already exiting with 0. + exit(0); +} + +TEST(LeakTest, CatchesMultipleLeakedMockObjects) { + MockFoo* foo1 = new MockFoo; + MockFoo* foo2 = new MockFoo; + + ON_CALL(*foo1, DoThis()).WillByDefault(Return()); + EXPECT_CALL(*foo2, DoThis()); + foo2->DoThis(); + + // In order to test the leak detector, we deliberately leak foo1 and + // foo2. + + // Makes sure Google Mock's leak detector can change the exit code + // to 1 even when the code is already exiting with 0. + exit(0); +} + +} // namespace diff --git a/src/googletest/googlemock/test/gmock_link2_test.cc b/src/googletest/googlemock/test/gmock_link2_test.cc new file mode 100644 index 000000000..d27ce1768 --- /dev/null +++ b/src/googletest/googlemock/test/gmock_link2_test.cc @@ -0,0 +1,39 @@ +// 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 is for verifying that various Google Mock constructs do not +// produce linker errors when instantiated in different translation units. +// Please see gmock_link_test.h for details. + +#define LinkTest LinkTest2 + +#include "test/gmock_link_test.h" diff --git a/src/googletest/googlemock/test/gmock_link_test.cc b/src/googletest/googlemock/test/gmock_link_test.cc new file mode 100644 index 000000000..e7c54cc23 --- /dev/null +++ b/src/googletest/googlemock/test/gmock_link_test.cc @@ -0,0 +1,39 @@ +// 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 is for verifying that various Google Mock constructs do not +// produce linker errors when instantiated in different translation units. +// Please see gmock_link_test.h for details. + +#define LinkTest LinkTest1 + +#include "test/gmock_link_test.h" diff --git a/src/googletest/googlemock/test/gmock_link_test.h b/src/googletest/googlemock/test/gmock_link_test.h new file mode 100644 index 000000000..175d2bdd1 --- /dev/null +++ b/src/googletest/googlemock/test/gmock_link_test.h @@ -0,0 +1,690 @@ +// Copyright 2009, 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 that: +// a. A header file defining a mock class can be included in multiple +// translation units without causing a link error. +// b. Actions and matchers can be instantiated with identical template +// arguments in different translation units without causing link +// errors. +// The following constructs are currently tested: +// Actions: +// Return() +// Return(value) +// ReturnNull +// ReturnRef +// Assign +// SetArgPointee +// SetArrayArgument +// SetErrnoAndReturn +// Invoke(function) +// Invoke(object, method) +// InvokeWithoutArgs(function) +// InvokeWithoutArgs(object, method) +// InvokeArgument +// WithArg +// WithArgs +// WithoutArgs +// DoAll +// DoDefault +// IgnoreResult +// Throw +// ACTION()-generated +// ACTION_P()-generated +// ACTION_P2()-generated +// Matchers: +// _ +// A +// An +// Eq +// Gt, Lt, Ge, Le, Ne +// NotNull +// Ref +// TypedEq +// DoubleEq +// FloatEq +// NanSensitiveDoubleEq +// NanSensitiveFloatEq +// ContainsRegex +// MatchesRegex +// EndsWith +// HasSubstr +// StartsWith +// StrCaseEq +// StrCaseNe +// StrEq +// StrNe +// ElementsAre +// ElementsAreArray +// ContainerEq +// Field +// Property +// ResultOf(function) +// ResultOf(callback) +// Pointee +// Truly(predicate) +// AddressSatisfies +// AllOf +// AnyOf +// Not +// MatcherCast<T> +// +// Please note: this test does not verify the functioning of these +// constructs, only that the programs using them will link successfully. +// +// Implementation note: +// This test requires identical definitions of Interface and Mock to be +// included in different translation units. We achieve this by writing +// them in this header and #including it in gmock_link_test.cc and +// gmock_link2_test.cc. Because the symbols generated by the compiler for +// those constructs must be identical in both translation units, +// definitions of Interface and Mock tests MUST be kept in the SAME +// NON-ANONYMOUS namespace in this file. The test fixture class LinkTest +// is defined as LinkTest1 in gmock_link_test.cc and as LinkTest2 in +// gmock_link2_test.cc to avoid producing linker errors. + +#ifndef GMOCK_TEST_GMOCK_LINK_TEST_H_ +#define GMOCK_TEST_GMOCK_LINK_TEST_H_ + +#include "gmock/gmock.h" + +#if !GTEST_OS_WINDOWS_MOBILE +# include <errno.h> +#endif + +#include <iostream> +#include <vector> + +#include "gtest/gtest.h" +#include "gtest/internal/gtest-port.h" + +using testing::_; +using testing::A; +using testing::Action; +using testing::AllOf; +using testing::AnyOf; +using testing::Assign; +using testing::ContainerEq; +using testing::DoAll; +using testing::DoDefault; +using testing::DoubleEq; +using testing::ElementsAre; +using testing::ElementsAreArray; +using testing::EndsWith; +using testing::Eq; +using testing::Field; +using testing::FloatEq; +using testing::Ge; +using testing::Gt; +using testing::HasSubstr; +using testing::IgnoreResult; +using testing::Invoke; +using testing::InvokeArgument; +using testing::InvokeWithoutArgs; +using testing::IsNull; +using testing::IsSubsetOf; +using testing::IsSupersetOf; +using testing::Le; +using testing::Lt; +using testing::Matcher; +using testing::MatcherCast; +using testing::NanSensitiveDoubleEq; +using testing::NanSensitiveFloatEq; +using testing::Ne; +using testing::Not; +using testing::NotNull; +using testing::Pointee; +using testing::Property; +using testing::Ref; +using testing::ResultOf; +using testing::Return; +using testing::ReturnNull; +using testing::ReturnRef; +using testing::SetArgPointee; +using testing::SetArrayArgument; +using testing::StartsWith; +using testing::StrCaseEq; +using testing::StrCaseNe; +using testing::StrEq; +using testing::StrNe; +using testing::Truly; +using testing::TypedEq; +using testing::WithArg; +using testing::WithArgs; +using testing::WithoutArgs; + +#if !GTEST_OS_WINDOWS_MOBILE +using testing::SetErrnoAndReturn; +#endif + +#if GTEST_HAS_EXCEPTIONS +using testing::Throw; +#endif + +using testing::ContainsRegex; +using testing::MatchesRegex; + +class Interface { + public: + virtual ~Interface() {} + virtual void VoidFromString(char* str) = 0; + virtual char* StringFromString(char* str) = 0; + virtual int IntFromString(char* str) = 0; + virtual int& IntRefFromString(char* str) = 0; + virtual void VoidFromFunc(void(*func)(char* str)) = 0; + virtual void VoidFromIntRef(int& n) = 0; // NOLINT + virtual void VoidFromFloat(float n) = 0; + virtual void VoidFromDouble(double n) = 0; + virtual void VoidFromVector(const std::vector<int>& v) = 0; +}; + +class Mock: public Interface { + public: + Mock() {} + + MOCK_METHOD1(VoidFromString, void(char* str)); + MOCK_METHOD1(StringFromString, char*(char* str)); + MOCK_METHOD1(IntFromString, int(char* str)); + MOCK_METHOD1(IntRefFromString, int&(char* str)); + MOCK_METHOD1(VoidFromFunc, void(void(*func)(char* str))); + MOCK_METHOD1(VoidFromIntRef, void(int& n)); // NOLINT + MOCK_METHOD1(VoidFromFloat, void(float n)); + MOCK_METHOD1(VoidFromDouble, void(double n)); + MOCK_METHOD1(VoidFromVector, void(const std::vector<int>& v)); + + private: + GTEST_DISALLOW_COPY_AND_ASSIGN_(Mock); +}; + +class InvokeHelper { + public: + static void StaticVoidFromVoid() {} + void VoidFromVoid() {} + static void StaticVoidFromString(char* /* str */) {} + void VoidFromString(char* /* str */) {} + static int StaticIntFromString(char* /* str */) { return 1; } + static bool StaticBoolFromString(const char* /* str */) { return true; } +}; + +class FieldHelper { + public: + explicit FieldHelper(int a_field) : field_(a_field) {} + int field() const { return field_; } + int field_; // NOLINT -- need external access to field_ to test + // the Field matcher. +}; + +// Tests the linkage of the ReturnVoid action. +TEST(LinkTest, TestReturnVoid) { + Mock mock; + + EXPECT_CALL(mock, VoidFromString(_)).WillOnce(Return()); + mock.VoidFromString(nullptr); +} + +// Tests the linkage of the Return action. +TEST(LinkTest, TestReturn) { + Mock mock; + char ch = 'x'; + + EXPECT_CALL(mock, StringFromString(_)).WillOnce(Return(&ch)); + mock.StringFromString(nullptr); +} + +// Tests the linkage of the ReturnNull action. +TEST(LinkTest, TestReturnNull) { + Mock mock; + + EXPECT_CALL(mock, VoidFromString(_)).WillOnce(Return()); + mock.VoidFromString(nullptr); +} + +// Tests the linkage of the ReturnRef action. +TEST(LinkTest, TestReturnRef) { + Mock mock; + int n = 42; + + EXPECT_CALL(mock, IntRefFromString(_)).WillOnce(ReturnRef(n)); + mock.IntRefFromString(nullptr); +} + +// Tests the linkage of the Assign action. +TEST(LinkTest, TestAssign) { + Mock mock; + char ch = 'x'; + + EXPECT_CALL(mock, VoidFromString(_)).WillOnce(Assign(&ch, 'y')); + mock.VoidFromString(nullptr); +} + +// Tests the linkage of the SetArgPointee action. +TEST(LinkTest, TestSetArgPointee) { + Mock mock; + char ch = 'x'; + + EXPECT_CALL(mock, VoidFromString(_)).WillOnce(SetArgPointee<0>('y')); + mock.VoidFromString(&ch); +} + +// Tests the linkage of the SetArrayArgument action. +TEST(LinkTest, TestSetArrayArgument) { + Mock mock; + char ch = 'x'; + char ch2 = 'y'; + + EXPECT_CALL(mock, VoidFromString(_)).WillOnce(SetArrayArgument<0>(&ch2, + &ch2 + 1)); + mock.VoidFromString(&ch); +} + +#if !GTEST_OS_WINDOWS_MOBILE + +// Tests the linkage of the SetErrnoAndReturn action. +TEST(LinkTest, TestSetErrnoAndReturn) { + Mock mock; + + int saved_errno = errno; + EXPECT_CALL(mock, IntFromString(_)).WillOnce(SetErrnoAndReturn(1, -1)); + mock.IntFromString(nullptr); + errno = saved_errno; +} + +#endif // !GTEST_OS_WINDOWS_MOBILE + +// Tests the linkage of the Invoke(function) and Invoke(object, method) actions. +TEST(LinkTest, TestInvoke) { + Mock mock; + InvokeHelper test_invoke_helper; + + EXPECT_CALL(mock, VoidFromString(_)) + .WillOnce(Invoke(&InvokeHelper::StaticVoidFromString)) + .WillOnce(Invoke(&test_invoke_helper, &InvokeHelper::VoidFromString)); + mock.VoidFromString(nullptr); + mock.VoidFromString(nullptr); +} + +// Tests the linkage of the InvokeWithoutArgs action. +TEST(LinkTest, TestInvokeWithoutArgs) { + Mock mock; + InvokeHelper test_invoke_helper; + + EXPECT_CALL(mock, VoidFromString(_)) + .WillOnce(InvokeWithoutArgs(&InvokeHelper::StaticVoidFromVoid)) + .WillOnce(InvokeWithoutArgs(&test_invoke_helper, + &InvokeHelper::VoidFromVoid)); + mock.VoidFromString(nullptr); + mock.VoidFromString(nullptr); +} + +// Tests the linkage of the InvokeArgument action. +TEST(LinkTest, TestInvokeArgument) { + Mock mock; + char ch = 'x'; + + EXPECT_CALL(mock, VoidFromFunc(_)).WillOnce(InvokeArgument<0>(&ch)); + mock.VoidFromFunc(InvokeHelper::StaticVoidFromString); +} + +// Tests the linkage of the WithArg action. +TEST(LinkTest, TestWithArg) { + Mock mock; + + EXPECT_CALL(mock, VoidFromString(_)) + .WillOnce(WithArg<0>(Invoke(&InvokeHelper::StaticVoidFromString))); + mock.VoidFromString(nullptr); +} + +// Tests the linkage of the WithArgs action. +TEST(LinkTest, TestWithArgs) { + Mock mock; + + EXPECT_CALL(mock, VoidFromString(_)) + .WillOnce(WithArgs<0>(Invoke(&InvokeHelper::StaticVoidFromString))); + mock.VoidFromString(nullptr); +} + +// Tests the linkage of the WithoutArgs action. +TEST(LinkTest, TestWithoutArgs) { + Mock mock; + + EXPECT_CALL(mock, VoidFromString(_)).WillOnce(WithoutArgs(Return())); + mock.VoidFromString(nullptr); +} + +// Tests the linkage of the DoAll action. +TEST(LinkTest, TestDoAll) { + Mock mock; + char ch = 'x'; + + EXPECT_CALL(mock, VoidFromString(_)) + .WillOnce(DoAll(SetArgPointee<0>('y'), Return())); + mock.VoidFromString(&ch); +} + +// Tests the linkage of the DoDefault action. +TEST(LinkTest, TestDoDefault) { + Mock mock; + char ch = 'x'; + + ON_CALL(mock, VoidFromString(_)).WillByDefault(Return()); + EXPECT_CALL(mock, VoidFromString(_)).WillOnce(DoDefault()); + mock.VoidFromString(&ch); +} + +// Tests the linkage of the IgnoreResult action. +TEST(LinkTest, TestIgnoreResult) { + Mock mock; + + EXPECT_CALL(mock, VoidFromString(_)).WillOnce(IgnoreResult(Return(42))); + mock.VoidFromString(nullptr); +} + +#if GTEST_HAS_EXCEPTIONS +// Tests the linkage of the Throw action. +TEST(LinkTest, TestThrow) { + Mock mock; + + EXPECT_CALL(mock, VoidFromString(_)).WillOnce(Throw(42)); + EXPECT_THROW(mock.VoidFromString(nullptr), int); +} +#endif // GTEST_HAS_EXCEPTIONS + +// The ACTION*() macros trigger warning C4100 (unreferenced formal +// parameter) in MSVC with -W4. Unfortunately they cannot be fixed in +// the macro definition, as the warnings are generated when the macro +// is expanded and macro expansion cannot contain #pragma. Therefore +// we suppress them here. +#ifdef _MSC_VER +# pragma warning(push) +# pragma warning(disable:4100) +#endif + +// Tests the linkage of actions created using ACTION macro. +namespace { +ACTION(Return1) { return 1; } +} + +TEST(LinkTest, TestActionMacro) { + Mock mock; + + EXPECT_CALL(mock, IntFromString(_)).WillOnce(Return1()); + mock.IntFromString(nullptr); +} + +// Tests the linkage of actions created using ACTION_P macro. +namespace { +ACTION_P(ReturnArgument, ret_value) { return ret_value; } +} + +TEST(LinkTest, TestActionPMacro) { + Mock mock; + + EXPECT_CALL(mock, IntFromString(_)).WillOnce(ReturnArgument(42)); + mock.IntFromString(nullptr); +} + +// Tests the linkage of actions created using ACTION_P2 macro. +namespace { +ACTION_P2(ReturnEqualsEitherOf, first, second) { + return arg0 == first || arg0 == second; +} +} + +#ifdef _MSC_VER +# pragma warning(pop) +#endif + +TEST(LinkTest, TestActionP2Macro) { + Mock mock; + char ch = 'x'; + + EXPECT_CALL(mock, IntFromString(_)) + .WillOnce(ReturnEqualsEitherOf("one", "two")); + mock.IntFromString(&ch); +} + +// Tests the linkage of the "_" matcher. +TEST(LinkTest, TestMatcherAnything) { + Mock mock; + + ON_CALL(mock, VoidFromString(_)).WillByDefault(Return()); +} + +// Tests the linkage of the A matcher. +TEST(LinkTest, TestMatcherA) { + Mock mock; + + ON_CALL(mock, VoidFromString(A<char*>())).WillByDefault(Return()); +} + +// Tests the linkage of the Eq and the "bare value" matcher. +TEST(LinkTest, TestMatchersEq) { + Mock mock; + const char* p = "x"; + + ON_CALL(mock, VoidFromString(Eq(p))).WillByDefault(Return()); + ON_CALL(mock, VoidFromString(const_cast<char*>("y"))) + .WillByDefault(Return()); +} + +// Tests the linkage of the Lt, Gt, Le, Ge, and Ne matchers. +TEST(LinkTest, TestMatchersRelations) { + Mock mock; + + ON_CALL(mock, VoidFromFloat(Lt(1.0f))).WillByDefault(Return()); + ON_CALL(mock, VoidFromFloat(Gt(1.0f))).WillByDefault(Return()); + ON_CALL(mock, VoidFromFloat(Le(1.0f))).WillByDefault(Return()); + ON_CALL(mock, VoidFromFloat(Ge(1.0f))).WillByDefault(Return()); + ON_CALL(mock, VoidFromFloat(Ne(1.0f))).WillByDefault(Return()); +} + +// Tests the linkage of the NotNull matcher. +TEST(LinkTest, TestMatcherNotNull) { + Mock mock; + + ON_CALL(mock, VoidFromString(NotNull())).WillByDefault(Return()); +} + +// Tests the linkage of the IsNull matcher. +TEST(LinkTest, TestMatcherIsNull) { + Mock mock; + + ON_CALL(mock, VoidFromString(IsNull())).WillByDefault(Return()); +} + +// Tests the linkage of the Ref matcher. +TEST(LinkTest, TestMatcherRef) { + Mock mock; + int a = 0; + + ON_CALL(mock, VoidFromIntRef(Ref(a))).WillByDefault(Return()); +} + +// Tests the linkage of the TypedEq matcher. +TEST(LinkTest, TestMatcherTypedEq) { + Mock mock; + long a = 0; + + ON_CALL(mock, VoidFromIntRef(TypedEq<int&>(a))).WillByDefault(Return()); +} + +// Tests the linkage of the FloatEq, DoubleEq, NanSensitiveFloatEq and +// NanSensitiveDoubleEq matchers. +TEST(LinkTest, TestMatchersFloatingPoint) { + Mock mock; + float a = 0; + + ON_CALL(mock, VoidFromFloat(FloatEq(a))).WillByDefault(Return()); + ON_CALL(mock, VoidFromDouble(DoubleEq(a))).WillByDefault(Return()); + ON_CALL(mock, VoidFromFloat(NanSensitiveFloatEq(a))).WillByDefault(Return()); + ON_CALL(mock, VoidFromDouble(NanSensitiveDoubleEq(a))) + .WillByDefault(Return()); +} + +// Tests the linkage of the ContainsRegex matcher. +TEST(LinkTest, TestMatcherContainsRegex) { + Mock mock; + + ON_CALL(mock, VoidFromString(ContainsRegex(".*"))).WillByDefault(Return()); +} + +// Tests the linkage of the MatchesRegex matcher. +TEST(LinkTest, TestMatcherMatchesRegex) { + Mock mock; + + ON_CALL(mock, VoidFromString(MatchesRegex(".*"))).WillByDefault(Return()); +} + +// Tests the linkage of the StartsWith, EndsWith, and HasSubstr matchers. +TEST(LinkTest, TestMatchersSubstrings) { + Mock mock; + + ON_CALL(mock, VoidFromString(StartsWith("a"))).WillByDefault(Return()); + ON_CALL(mock, VoidFromString(EndsWith("c"))).WillByDefault(Return()); + ON_CALL(mock, VoidFromString(HasSubstr("b"))).WillByDefault(Return()); +} + +// Tests the linkage of the StrEq, StrNe, StrCaseEq, and StrCaseNe matchers. +TEST(LinkTest, TestMatchersStringEquality) { + Mock mock; + ON_CALL(mock, VoidFromString(StrEq("a"))).WillByDefault(Return()); + ON_CALL(mock, VoidFromString(StrNe("a"))).WillByDefault(Return()); + ON_CALL(mock, VoidFromString(StrCaseEq("a"))).WillByDefault(Return()); + ON_CALL(mock, VoidFromString(StrCaseNe("a"))).WillByDefault(Return()); +} + +// Tests the linkage of the ElementsAre matcher. +TEST(LinkTest, TestMatcherElementsAre) { + Mock mock; + + ON_CALL(mock, VoidFromVector(ElementsAre('a', _))).WillByDefault(Return()); +} + +// Tests the linkage of the ElementsAreArray matcher. +TEST(LinkTest, TestMatcherElementsAreArray) { + Mock mock; + char arr[] = { 'a', 'b' }; + + ON_CALL(mock, VoidFromVector(ElementsAreArray(arr))).WillByDefault(Return()); +} + +// Tests the linkage of the IsSubsetOf matcher. +TEST(LinkTest, TestMatcherIsSubsetOf) { + Mock mock; + char arr[] = {'a', 'b'}; + + ON_CALL(mock, VoidFromVector(IsSubsetOf(arr))).WillByDefault(Return()); +} + +// Tests the linkage of the IsSupersetOf matcher. +TEST(LinkTest, TestMatcherIsSupersetOf) { + Mock mock; + char arr[] = {'a', 'b'}; + + ON_CALL(mock, VoidFromVector(IsSupersetOf(arr))).WillByDefault(Return()); +} + +// Tests the linkage of the ContainerEq matcher. +TEST(LinkTest, TestMatcherContainerEq) { + Mock mock; + std::vector<int> v; + + ON_CALL(mock, VoidFromVector(ContainerEq(v))).WillByDefault(Return()); +} + +// Tests the linkage of the Field matcher. +TEST(LinkTest, TestMatcherField) { + FieldHelper helper(0); + + Matcher<const FieldHelper&> m = Field(&FieldHelper::field_, Eq(0)); + EXPECT_TRUE(m.Matches(helper)); + + Matcher<const FieldHelper*> m2 = Field(&FieldHelper::field_, Eq(0)); + EXPECT_TRUE(m2.Matches(&helper)); +} + +// Tests the linkage of the Property matcher. +TEST(LinkTest, TestMatcherProperty) { + FieldHelper helper(0); + + Matcher<const FieldHelper&> m = Property(&FieldHelper::field, Eq(0)); + EXPECT_TRUE(m.Matches(helper)); + + Matcher<const FieldHelper*> m2 = Property(&FieldHelper::field, Eq(0)); + EXPECT_TRUE(m2.Matches(&helper)); +} + +// Tests the linkage of the ResultOf matcher. +TEST(LinkTest, TestMatcherResultOf) { + Matcher<char*> m = ResultOf(&InvokeHelper::StaticIntFromString, Eq(1)); + EXPECT_TRUE(m.Matches(nullptr)); +} + +// Tests the linkage of the ResultOf matcher. +TEST(LinkTest, TestMatcherPointee) { + int n = 1; + + Matcher<int*> m = Pointee(Eq(1)); + EXPECT_TRUE(m.Matches(&n)); +} + +// Tests the linkage of the Truly matcher. +TEST(LinkTest, TestMatcherTruly) { + Matcher<const char*> m = Truly(&InvokeHelper::StaticBoolFromString); + EXPECT_TRUE(m.Matches(nullptr)); +} + +// Tests the linkage of the AllOf matcher. +TEST(LinkTest, TestMatcherAllOf) { + Matcher<int> m = AllOf(_, Eq(1)); + EXPECT_TRUE(m.Matches(1)); +} + +// Tests the linkage of the AnyOf matcher. +TEST(LinkTest, TestMatcherAnyOf) { + Matcher<int> m = AnyOf(_, Eq(1)); + EXPECT_TRUE(m.Matches(1)); +} + +// Tests the linkage of the Not matcher. +TEST(LinkTest, TestMatcherNot) { + Matcher<int> m = Not(_); + EXPECT_FALSE(m.Matches(1)); +} + +// Tests the linkage of the MatcherCast<T>() function. +TEST(LinkTest, TestMatcherCast) { + Matcher<const char*> m = MatcherCast<const char*>(_); + EXPECT_TRUE(m.Matches(nullptr)); +} + +#endif // GMOCK_TEST_GMOCK_LINK_TEST_H_ diff --git a/src/googletest/googlemock/test/gmock_output_test.py b/src/googletest/googlemock/test/gmock_output_test.py new file mode 100755 index 000000000..25f99f2b7 --- /dev/null +++ b/src/googletest/googlemock/test/gmock_output_test.py @@ -0,0 +1,183 @@ +#!/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. + +r"""Tests the text output of Google C++ Mocking Framework. + +To update the golden file: +gmock_output_test.py --build_dir=BUILD/DIR --gengolden +where BUILD/DIR contains the built gmock_output_test_ file. +gmock_output_test.py --gengolden +gmock_output_test.py + +""" + +from io import open # pylint: disable=redefined-builtin, g-importing-member +import os +import re +import sys +import gmock_test_utils + + +# The flag for generating the golden file +GENGOLDEN_FLAG = '--gengolden' + +PROGRAM_PATH = gmock_test_utils.GetTestExecutablePath('gmock_output_test_') +COMMAND = [PROGRAM_PATH, '--gtest_stack_trace_depth=0', '--gtest_print_time=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 RemoveTestNamesOfLeakedMocks(output): + """Removes the test names of leaked mock objects from the test output.""" + + return re.sub(r'\(used in test .+\) ', '', output) + + +def GetLeakyTests(output): + """Returns a list of test names that leak mock objects.""" + + # findall() returns a list of all matches of the regex in output. + # For example, if '(used in test FooTest.Bar)' is in output, the + # list will contain 'FooTest.Bar'. + return re.findall(r'\(used in test (.+)\)', output) + + +def GetNormalizedOutputAndLeakyTests(output): + """Normalizes the output of gmock_output_test_. + + Args: + output: The test output. + + Returns: + A tuple (the normalized test output, the list of test names that have + leaked mocks). + """ + + output = ToUnixLineEnding(output) + output = RemoveReportHeaderAndFooter(output) + output = NormalizeErrorMarker(output) + output = RemoveLocations(output) + output = RemoveMemoryAddresses(output) + return (RemoveTestNamesOfLeakedMocks(output), GetLeakyTests(output)) + + +def GetShellCommandOutput(cmd): + """Runs a command in a sub-process, and returns its STDOUT in a string.""" + + return gmock_test_utils.Subprocess(cmd, capture_stderr=False).output + + +def GetNormalizedCommandOutputAndLeakyTests(cmd): + """Runs a command and returns its normalized output and a list of leaky tests. + + Args: + cmd: the shell command. + """ + + # Disables exception pop-ups on Windows. + os.environ['GTEST_CATCH_EXCEPTIONS'] = '1' + return GetNormalizedOutputAndLeakyTests(GetShellCommandOutput(cmd)) + + +class GMockOutputTest(gmock_test_utils.TestCase): + + def testOutput(self): + (output, leaky_tests) = GetNormalizedCommandOutputAndLeakyTests(COMMAND) + golden_file = open(GOLDEN_PATH, 'rb') + golden = golden_file.read().decode('utf-8') + golden_file.close() + + # The normalized output should match the golden file. + self.assertEquals(golden, output) + + # The raw output should contain 2 leaked mock object errors for + # test GMockOutputTest.CatchesLeakedMocks. + self.assertEquals(['GMockOutputTest.CatchesLeakedMocks', + 'GMockOutputTest.CatchesLeakedMocks'], + leaky_tests) + + +if __name__ == '__main__': + if sys.argv[1:] == [GENGOLDEN_FLAG]: + (output, _) = GetNormalizedCommandOutputAndLeakyTests(COMMAND) + golden_file = open(GOLDEN_PATH, 'wb') + golden_file.write(output) + golden_file.close() + # Suppress the error "googletest was imported but a call to its main() + # was never detected." + os._exit(0) + else: + gmock_test_utils.Main() diff --git a/src/googletest/googlemock/test/gmock_output_test_.cc b/src/googletest/googlemock/test/gmock_output_test_.cc new file mode 100644 index 000000000..3955c7331 --- /dev/null +++ b/src/googletest/googlemock/test/gmock_output_test_.cc @@ -0,0 +1,309 @@ +// 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 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" + +// Silence C4100 (unreferenced formal parameter) +#ifdef _MSC_VER +# pragma warning(push) +# pragma warning(disable:4100) +#endif + +using testing::_; +using testing::AnyNumber; +using testing::Ge; +using testing::InSequence; +using testing::NaggyMock; +using testing::Ref; +using testing::Return; +using testing::Sequence; +using testing::Value; + +class MockFoo { + public: + MockFoo() {} + + 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)); + + private: + GTEST_DISALLOW_COPY_AND_ASSIGN_(MockFoo); +}; + +class GMockOutputTest : public testing::Test { + protected: + NaggyMock<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, UnsatisfiedWith) { + EXPECT_CALL(foo_, Bar2(_, _)).With(Ge()); +} + +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, MismatchWith) { + EXPECT_CALL(foo_, Bar2(Ge(2), Ge(1))) + .With(Ge()); + + foo_.Bar2(2, 3); // Mismatch With() + foo_.Bar2(2, 1); +} + +TEST_F(GMockOutputTest, MismatchArgumentsAndWith) { + EXPECT_CALL(foo_, Bar2(Ge(2), Ge(1))) + .With(Ge()); + + foo_.Bar2(1, 3); // Mismatch arguments and mismatch With() + 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. +} + +TEST_F(GMockOutputTest, CatchesLeakedMocks) { + MockFoo* foo1 = new MockFoo; + MockFoo* foo2 = new MockFoo; + + // Invokes ON_CALL on foo1. + ON_CALL(*foo1, Bar(_, _, _)).WillByDefault(Return('a')); + + // Invokes EXPECT_CALL on foo2. + EXPECT_CALL(*foo2, Bar2(_, _)); + EXPECT_CALL(*foo2, Bar2(1, _)); + EXPECT_CALL(*foo2, Bar3(_, _)).Times(AnyNumber()); + foo2->Bar2(2, 1); + foo2->Bar2(1, 1); + + // Both foo1 and foo2 are deliberately leaked. +} + +MATCHER_P2(IsPair, first, second, "") { + return Value(arg.first, first) && Value(arg.second, second); +} + +TEST_F(GMockOutputTest, PrintsMatcher) { + const testing::Matcher<int> m1 = Ge(48); + EXPECT_THAT((std::pair<int, bool>(42, true)), IsPair(m1, true)); +} + +void TestCatchesLeakedMocksInAdHocTests() { + MockFoo* foo = new MockFoo; + + // Invokes EXPECT_CALL on foo. + EXPECT_CALL(*foo, Bar2(_, _)); + foo->Bar2(2, 1); + + // foo is deliberately leaked. +} + +int main(int argc, char **argv) { + testing::InitGoogleMock(&argc, argv); + // Ensures that the tests pass no matter what value of + // --gmock_catch_leaked_mocks and --gmock_verbose the user specifies. + testing::GMOCK_FLAG(catch_leaked_mocks) = true; + testing::GMOCK_FLAG(verbose) = "warning"; + + TestCatchesLeakedMocksInAdHocTests(); + return RUN_ALL_TESTS(); +} + +#ifdef _MSC_VER +# pragma warning(pop) +#endif diff --git a/src/googletest/googlemock/test/gmock_output_test_golden.txt b/src/googletest/googlemock/test/gmock_output_test_golden.txt new file mode 100644 index 000000000..755e9334a --- /dev/null +++ b/src/googletest/googlemock/test/gmock_output_test_golden.txt @@ -0,0 +1,317 @@ +[ RUN ] GMockOutputTest.ExpectedCall + +FILE:#: EXPECT_CALL(foo_, Bar2(0, _)) invoked +Stack trace: + +FILE:#: Mock function call matches EXPECT_CALL(foo_, Bar2(0, _))... + 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:#: Mock function call matches EXPECT_CALL(foo_, Bar3(0, _))... + Function call: Bar3(0, 0) +Stack trace: +[ OK ] GMockOutputTest.ExpectedCallToVoidFunction +[ RUN ] GMockOutputTest.ExplicitActionsRunOut + +GMOCK WARNING: +FILE:#: Too few actions specified in EXPECT_CALL(foo_, Bar2(_, _))... +Expected to be called twice, but has only 1 WillOnce(). +GMOCK WARNING: +FILE:#: Actions ran out in EXPECT_CALL(foo_, Bar2(_, _))... +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:#: EXPECT_CALL(foo_, Bar2(0, _))... + 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:#: EXPECT_CALL(foo_, Bar3(0, _))... + 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 +NOTE: You can safely ignore the above warning unless this call should not happen. Do not suppress it by blindly adding an EXPECT_CALL() if you don't mean to enforce the call. See https://github.com/google/googletest/blob/master/googlemock/docs/cook_book.md#knowing-when-to-expect for details. +[ OK ] GMockOutputTest.UninterestingCall +[ RUN ] GMockOutputTest.UninterestingCallToVoidFunction + +GMOCK WARNING: +Uninteresting mock function call - returning directly. + Function call: Bar3(0, 1) +NOTE: You can safely ignore the above warning unless this call should not happen. Do not suppress it by blindly adding an EXPECT_CALL() if you don't mean to enforce the call. See https://github.com/google/googletest/blob/master/googlemock/docs/cook_book.md#knowing-when-to-expect for details. +[ 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: EXPECT_CALL(foo_, Bar2(_, _))... + Expected: the expectation is active + Actual: it is retired + Expected: to be called once + Actual: called once - saturated and retired +FILE:#: tried expectation #1: EXPECT_CALL(foo_, Bar2(0, 0))... + 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: EXPECT_CALL(foo_, Bar2(0, 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: EXPECT_CALL(foo_, Bar2(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: EXPECT_CALL(foo_, Bar2(0, 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: EXPECT_CALL(foo_, Bar2(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.UnsatisfiedWith +FILE:#: Failure +Actual function call count doesn't match EXPECT_CALL(foo_, Bar2(_, _))... + Expected args: are a pair where the first >= the second + Expected: to be called once + Actual: never called - unsatisfied and active +[ FAILED ] GMockOutputTest.UnsatisfiedWith +[ RUN ] GMockOutputTest.UnsatisfiedExpectation +FILE:#: Failure +Actual function call count doesn't match EXPECT_CALL(foo_, Bar2(0, _))... + Expected: to be called twice + Actual: called once - unsatisfied and active +FILE:#: Failure +Actual function call count doesn't match EXPECT_CALL(foo_, Bar(_, _, _))... + 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:#: EXPECT_CALL(foo_, Bar(Ref(s), _, Ge(0)))... + Expected arg #0: references the variable @0x# "Hi" + Actual: "Ho", which is located @0x# + Expected arg #2: is >= 0 + Actual: -0.1 + Expected: to be called once + Actual: never called - unsatisfied and active +[ FAILED ] GMockOutputTest.MismatchArguments +[ RUN ] GMockOutputTest.MismatchWith +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:#: EXPECT_CALL(foo_, Bar2(Ge(2), Ge(1)))... + Expected args: are a pair where the first >= the second + Actual: don't match + Expected: to be called once + Actual: never called - unsatisfied and active +[ FAILED ] GMockOutputTest.MismatchWith +[ RUN ] GMockOutputTest.MismatchArgumentsAndWith +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:#: EXPECT_CALL(foo_, Bar2(Ge(2), Ge(1)))... + Expected arg #0: is >= 2 + Actual: 1 + Expected args: are a pair where the first >= the second + Actual: don't match + Expected: to be called once + Actual: never called - unsatisfied and active +[ FAILED ] GMockOutputTest.MismatchArgumentsAndWith +[ 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:#: EXPECT_CALL(foo_, Bar2(2, 2))... + 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:#: EXPECT_CALL(foo_, Bar2(2, 2))... + 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 +NOTE: You can safely ignore the above warning unless this call should not happen. Do not suppress it by blindly adding an EXPECT_CALL() if you don't mean to enforce the call. See https://github.com/google/googletest/blob/master/googlemock/docs/cook_book.md#knowing-when-to-expect for details. + +GMOCK WARNING: +Uninteresting mock function call - taking default action specified at: +FILE:#: + Function call: Bar2(1, 1) + Returns: false +NOTE: You can safely ignore the above warning unless this call should not happen. Do not suppress it by blindly adding an EXPECT_CALL() if you don't mean to enforce the call. See https://github.com/google/googletest/blob/master/googlemock/docs/cook_book.md#knowing-when-to-expect for details. +[ OK ] GMockOutputTest.UninterestingCallWithDefaultAction +[ RUN ] GMockOutputTest.ExplicitActionsRunOutWithDefaultAction + +GMOCK WARNING: +FILE:#: Too few actions specified in EXPECT_CALL(foo_, Bar2(_, _))... +Expected to be called twice, but has only 1 WillOnce(). +GMOCK WARNING: +FILE:#: Actions ran out in EXPECT_CALL(foo_, Bar2(_, _))... +Called 2 times, but only 1 WillOnce() is specified - taking default action specified at: +FILE:#: +Stack trace: +[ OK ] GMockOutputTest.ExplicitActionsRunOutWithDefaultAction +[ RUN ] GMockOutputTest.CatchesLeakedMocks +[ OK ] GMockOutputTest.CatchesLeakedMocks +[ RUN ] GMockOutputTest.PrintsMatcher +FILE:#: Failure +Value of: (std::pair<int, bool>(42, true)) +Expected: is pair (is >= 48, true) + Actual: (42, true) (of type std::pair<int, bool>) +[ FAILED ] GMockOutputTest.PrintsMatcher +[ FAILED ] GMockOutputTest.UnexpectedCall +[ FAILED ] GMockOutputTest.UnexpectedCallToVoidFunction +[ FAILED ] GMockOutputTest.ExcessiveCall +[ FAILED ] GMockOutputTest.ExcessiveCallToVoidFunction +[ FAILED ] GMockOutputTest.RetiredExpectation +[ FAILED ] GMockOutputTest.UnsatisfiedPrerequisite +[ FAILED ] GMockOutputTest.UnsatisfiedPrerequisites +[ FAILED ] GMockOutputTest.UnsatisfiedWith +[ FAILED ] GMockOutputTest.UnsatisfiedExpectation +[ FAILED ] GMockOutputTest.MismatchArguments +[ FAILED ] GMockOutputTest.MismatchWith +[ FAILED ] GMockOutputTest.MismatchArgumentsAndWith +[ FAILED ] GMockOutputTest.UnexpectedCallWithDefaultAction +[ FAILED ] GMockOutputTest.ExcessiveCallWithDefaultAction +[ FAILED ] GMockOutputTest.PrintsMatcher + + +FILE:#: ERROR: this mock object should be deleted but never is. Its address is @0x#. +FILE:#: ERROR: this mock object should be deleted but never is. Its address is @0x#. +FILE:#: ERROR: this mock object should be deleted but never is. Its address is @0x#. +ERROR: 3 leaked mock objects found at program exit. Expectations on a mock object are verified when the object is destructed. Leaking a mock means that its expectations aren't verified, which is usually a test bug. If you really intend to leak a mock, you can suppress this error using testing::Mock::AllowLeak(mock_object), or you may use a fake or stub instead of a mock. diff --git a/src/googletest/googlemock/test/gmock_stress_test.cc b/src/googletest/googlemock/test/gmock_stress_test.cc new file mode 100644 index 000000000..20725d69b --- /dev/null +++ b/src/googletest/googlemock/test/gmock_stress_test.cc @@ -0,0 +1,240 @@ +// 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. + + +// Tests that Google Mock constructs can be used in a large number of +// threads concurrently. + +#include "gmock/gmock.h" +#include "gtest/gtest.h" + +namespace testing { +namespace { + +// From gtest-port.h. +using ::testing::internal::ThreadWithParam; + +// The maximum number of test threads (not including helper threads) +// to create. +const int kMaxTestThreads = 50; + +// How many times to repeat a task in a test thread. +const int kRepeat = 50; + +class MockFoo { + public: + MOCK_METHOD1(Bar, int(int n)); // NOLINT + MOCK_METHOD2(Baz, char(const char* s1, const std::string& s2)); // NOLINT +}; + +// Helper for waiting for the given thread to finish and then deleting it. +template <typename T> +void JoinAndDelete(ThreadWithParam<T>* t) { + t->Join(); + delete t; +} + +struct Dummy {}; + + +// Tests that different mock objects can be used in their respective +// threads. This should generate no Google Test failure. +void TestConcurrentMockObjects(Dummy /* dummy */) { + // Creates a mock and does some typical operations on it. + MockFoo foo; + ON_CALL(foo, Bar(_)) + .WillByDefault(Return(1)); + ON_CALL(foo, Baz(_, _)) + .WillByDefault(Return('b')); + ON_CALL(foo, Baz(_, "you")) + .WillByDefault(Return('a')); + + EXPECT_CALL(foo, Bar(0)) + .Times(AtMost(3)); + EXPECT_CALL(foo, Baz(_, _)); + EXPECT_CALL(foo, Baz("hi", "you")) + .WillOnce(Return('z')) + .WillRepeatedly(DoDefault()); + + EXPECT_EQ(1, foo.Bar(0)); + EXPECT_EQ(1, foo.Bar(0)); + EXPECT_EQ('z', foo.Baz("hi", "you")); + EXPECT_EQ('a', foo.Baz("hi", "you")); + EXPECT_EQ('b', foo.Baz("hi", "me")); +} + +// Tests invoking methods of the same mock object in multiple threads. + +struct Helper1Param { + MockFoo* mock_foo; + int* count; +}; + +void Helper1(Helper1Param param) { + for (int i = 0; i < kRepeat; i++) { + const char ch = param.mock_foo->Baz("a", "b"); + if (ch == 'a') { + // It was an expected call. + (*param.count)++; + } else { + // It was an excessive call. + EXPECT_EQ('\0', ch); + } + + // An unexpected call. + EXPECT_EQ('\0', param.mock_foo->Baz("x", "y")) << "Expected failure."; + + // An uninteresting call. + EXPECT_EQ(1, param.mock_foo->Bar(5)); + } +} + +// This should generate 3*kRepeat + 1 failures in total. +void TestConcurrentCallsOnSameObject(Dummy /* dummy */) { + MockFoo foo; + + ON_CALL(foo, Bar(_)) + .WillByDefault(Return(1)); + EXPECT_CALL(foo, Baz(_, "b")) + .Times(kRepeat) + .WillRepeatedly(Return('a')); + EXPECT_CALL(foo, Baz(_, "c")); // Expected to be unsatisfied. + + // This chunk of code should generate kRepeat failures about + // excessive calls, and 2*kRepeat failures about unexpected calls. + int count1 = 0; + const Helper1Param param = { &foo, &count1 }; + ThreadWithParam<Helper1Param>* const t = + new ThreadWithParam<Helper1Param>(Helper1, param, nullptr); + + int count2 = 0; + const Helper1Param param2 = { &foo, &count2 }; + Helper1(param2); + JoinAndDelete(t); + + EXPECT_EQ(kRepeat, count1 + count2); + + // foo's destructor should generate one failure about unsatisfied + // expectation. +} + +// Tests using the same mock object in multiple threads when the +// expectations are partially ordered. + +void Helper2(MockFoo* foo) { + for (int i = 0; i < kRepeat; i++) { + foo->Bar(2); + foo->Bar(3); + } +} + +// This should generate no Google Test failures. +void TestPartiallyOrderedExpectationsWithThreads(Dummy /* dummy */) { + MockFoo foo; + Sequence s1, s2; + + { + InSequence dummy; + EXPECT_CALL(foo, Bar(0)); + EXPECT_CALL(foo, Bar(1)) + .InSequence(s1, s2); + } + + EXPECT_CALL(foo, Bar(2)) + .Times(2*kRepeat) + .InSequence(s1) + .RetiresOnSaturation(); + EXPECT_CALL(foo, Bar(3)) + .Times(2*kRepeat) + .InSequence(s2); + + { + InSequence dummy; + EXPECT_CALL(foo, Bar(2)) + .InSequence(s1, s2); + EXPECT_CALL(foo, Bar(4)); + } + + foo.Bar(0); + foo.Bar(1); + + ThreadWithParam<MockFoo*>* const t = + new ThreadWithParam<MockFoo*>(Helper2, &foo, nullptr); + Helper2(&foo); + JoinAndDelete(t); + + foo.Bar(2); + foo.Bar(4); +} + +// Tests using Google Mock constructs in many threads concurrently. +TEST(StressTest, CanUseGMockWithThreads) { + void (*test_routines[])(Dummy dummy) = { + &TestConcurrentMockObjects, + &TestConcurrentCallsOnSameObject, + &TestPartiallyOrderedExpectationsWithThreads, + }; + + const int kRoutines = sizeof(test_routines)/sizeof(test_routines[0]); + const int kCopiesOfEachRoutine = kMaxTestThreads / kRoutines; + const int kTestThreads = kCopiesOfEachRoutine * kRoutines; + ThreadWithParam<Dummy>* threads[kTestThreads] = {}; + for (int i = 0; i < kTestThreads; i++) { + // Creates a thread to run the test function. + threads[i] = new ThreadWithParam<Dummy>(test_routines[i % kRoutines], + Dummy(), nullptr); + GTEST_LOG_(INFO) << "Thread #" << i << " running . . ."; + } + + // At this point, we have many threads running. + for (int i = 0; i < kTestThreads; i++) { + JoinAndDelete(threads[i]); + } + + // Ensures that the correct number of failures have been reported. + const TestInfo* const info = UnitTest::GetInstance()->current_test_info(); + const TestResult& result = *info->result(); + const int kExpectedFailures = (3*kRepeat + 1)*kCopiesOfEachRoutine; + GTEST_CHECK_(kExpectedFailures == result.total_part_count()) + << "Expected " << kExpectedFailures << " failures, but got " + << result.total_part_count(); +} + +} // namespace +} // namespace testing + +int main(int argc, char **argv) { + testing::InitGoogleMock(&argc, argv); + + const int exit_code = RUN_ALL_TESTS(); // Expected to fail. + GTEST_CHECK_(exit_code != 0) << "RUN_ALL_TESTS() did not fail as expected"; + + printf("\nPASS\n"); + return 0; +} diff --git a/src/googletest/googlemock/test/gmock_test.cc b/src/googletest/googlemock/test/gmock_test.cc new file mode 100644 index 000000000..e9840a337 --- /dev/null +++ b/src/googletest/googlemock/test/gmock_test.cc @@ -0,0 +1,181 @@ +// 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 code in gmock.cc. + +#include "gmock/gmock.h" + +#include <string> +#include "gtest/gtest.h" +#include "gtest/internal/custom/gtest.h" + +#if !defined(GTEST_CUSTOM_INIT_GOOGLE_TEST_FUNCTION_) + +using testing::GMOCK_FLAG(default_mock_behavior); +using testing::GMOCK_FLAG(verbose); +using testing::InitGoogleMock; + +// 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 - 1; + InitGoogleMock(&argc, const_cast<Char**>(argv)); + ASSERT_EQ(N - 1, 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[] = {nullptr}; + + const char* new_argv[] = {nullptr}; + + TestInitGoogleMock(argv, new_argv, GMOCK_FLAG(verbose)); +} + +TEST(InitGoogleMockTest, ParsesEmptyCommandLine) { + const char* argv[] = {"foo.exe", nullptr}; + + const char* new_argv[] = {"foo.exe", nullptr}; + + TestInitGoogleMock(argv, new_argv, GMOCK_FLAG(verbose)); +} + +TEST(InitGoogleMockTest, ParsesSingleFlag) { + const char* argv[] = {"foo.exe", "--gmock_verbose=info", nullptr}; + + const char* new_argv[] = {"foo.exe", nullptr}; + + TestInitGoogleMock(argv, new_argv, "info"); +} + +TEST(InitGoogleMockTest, ParsesMultipleFlags) { + int old_default_behavior = GMOCK_FLAG(default_mock_behavior); + const wchar_t* argv[] = {L"foo.exe", L"--gmock_verbose=info", + L"--gmock_default_mock_behavior=2", nullptr}; + + const wchar_t* new_argv[] = {L"foo.exe", nullptr}; + + TestInitGoogleMock(argv, new_argv, "info"); + EXPECT_EQ(2, GMOCK_FLAG(default_mock_behavior)); + EXPECT_NE(2, old_default_behavior); + GMOCK_FLAG(default_mock_behavior) = old_default_behavior; +} + +TEST(InitGoogleMockTest, ParsesUnrecognizedFlag) { + const char* argv[] = {"foo.exe", "--non_gmock_flag=blah", nullptr}; + + const char* new_argv[] = {"foo.exe", "--non_gmock_flag=blah", nullptr}; + + TestInitGoogleMock(argv, new_argv, GMOCK_FLAG(verbose)); +} + +TEST(InitGoogleMockTest, ParsesGoogleMockFlagAndUnrecognizedFlag) { + const char* argv[] = {"foo.exe", "--non_gmock_flag=blah", + "--gmock_verbose=error", nullptr}; + + const char* new_argv[] = {"foo.exe", "--non_gmock_flag=blah", nullptr}; + + TestInitGoogleMock(argv, new_argv, "error"); +} + +TEST(WideInitGoogleMockTest, ParsesInvalidCommandLine) { + const wchar_t* argv[] = {nullptr}; + + const wchar_t* new_argv[] = {nullptr}; + + TestInitGoogleMock(argv, new_argv, GMOCK_FLAG(verbose)); +} + +TEST(WideInitGoogleMockTest, ParsesEmptyCommandLine) { + const wchar_t* argv[] = {L"foo.exe", nullptr}; + + const wchar_t* new_argv[] = {L"foo.exe", nullptr}; + + TestInitGoogleMock(argv, new_argv, GMOCK_FLAG(verbose)); +} + +TEST(WideInitGoogleMockTest, ParsesSingleFlag) { + const wchar_t* argv[] = {L"foo.exe", L"--gmock_verbose=info", nullptr}; + + const wchar_t* new_argv[] = {L"foo.exe", nullptr}; + + TestInitGoogleMock(argv, new_argv, "info"); +} + +TEST(WideInitGoogleMockTest, ParsesMultipleFlags) { + int old_default_behavior = GMOCK_FLAG(default_mock_behavior); + const wchar_t* argv[] = {L"foo.exe", L"--gmock_verbose=info", + L"--gmock_default_mock_behavior=2", nullptr}; + + const wchar_t* new_argv[] = {L"foo.exe", nullptr}; + + TestInitGoogleMock(argv, new_argv, "info"); + EXPECT_EQ(2, GMOCK_FLAG(default_mock_behavior)); + EXPECT_NE(2, old_default_behavior); + GMOCK_FLAG(default_mock_behavior) = old_default_behavior; +} + +TEST(WideInitGoogleMockTest, ParsesUnrecognizedFlag) { + const wchar_t* argv[] = {L"foo.exe", L"--non_gmock_flag=blah", nullptr}; + + const wchar_t* new_argv[] = {L"foo.exe", L"--non_gmock_flag=blah", nullptr}; + + 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", nullptr}; + + const wchar_t* new_argv[] = {L"foo.exe", L"--non_gmock_flag=blah", nullptr}; + + TestInitGoogleMock(argv, new_argv, "error"); +} + +#endif // !defined(GTEST_CUSTOM_INIT_GOOGLE_TEST_FUNCTION_) + +// Makes sure Google Mock flags can be accessed in code. +TEST(FlagTest, IsAccessibleInCode) { + bool dummy = testing::GMOCK_FLAG(catch_leaked_mocks) && + testing::GMOCK_FLAG(verbose) == ""; + (void)dummy; // Avoids the "unused local variable" warning. +} diff --git a/src/googletest/googlemock/test/gmock_test_utils.py b/src/googletest/googlemock/test/gmock_test_utils.py new file mode 100755 index 000000000..7dc4e119d --- /dev/null +++ b/src/googletest/googlemock/test/gmock_test_utils.py @@ -0,0 +1,108 @@ +# 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.""" + +import os +import sys + +# Determines path to gtest_test_utils and imports it. +SCRIPT_DIR = os.path.dirname(__file__) or '.' + +# isdir resolves symbolic links. +gtest_tests_util_dir = os.path.join(SCRIPT_DIR, '../../googletest/test') +if os.path.isdir(gtest_tests_util_dir): + GTEST_TESTS_UTIL_DIR = gtest_tests_util_dir +else: + GTEST_TESTS_UTIL_DIR = os.path.join(SCRIPT_DIR, '../../googletest/test') +sys.path.append(GTEST_TESTS_UTIL_DIR) + +# pylint: disable=C6204 +import gtest_test_utils + + +def GetSourceDir(): + """Returns the absolute path of the directory where the .py files are.""" + + return gtest_test_utils.GetSourceDir() + + +def GetTestExecutablePath(executable_name): + """Returns the absolute path of the test binary given its name. + + The function will print a message and abort the program if the resulting file + doesn't exist. + + Args: + executable_name: name of the test binary that the test script runs. + + Returns: + The absolute path of the test binary. + """ + + return gtest_test_utils.GetTestExecutablePath(executable_name) + + +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 + + +# Suppresses the "Invalid const name" lint complaint +# pylint: disable-msg=C6409 + +# Exposes utilities from gtest_test_utils. +Subprocess = gtest_test_utils.Subprocess +TestCase = gtest_test_utils.TestCase +environ = gtest_test_utils.environ +SetEnvVar = gtest_test_utils.SetEnvVar +PREMATURE_EXIT_FILE_ENV_VAR = gtest_test_utils.PREMATURE_EXIT_FILE_ENV_VAR + +# pylint: enable-msg=C6409 + + +def Main(): + """Runs the unit test.""" + + gtest_test_utils.Main() diff --git a/src/googletest/googlemock/test/pump_test.py b/src/googletest/googlemock/test/pump_test.py new file mode 100755 index 000000000..eb5a13134 --- /dev/null +++ b/src/googletest/googlemock/test/pump_test.py @@ -0,0 +1,182 @@ +#!/usr/bin/env python +# +# Copyright 2010, 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 for the Pump meta-programming tool.""" + +from google3.testing.pybase import googletest +import google3.third_party.googletest.googlemock.scripts.pump + +pump = google3.third_party.googletest.googlemock.scripts.pump +Convert = pump.ConvertFromPumpSource +StripMetaComments = pump.StripMetaComments + + +class PumpTest(googletest.TestCase): + + def testConvertsEmptyToEmpty(self): + self.assertEquals('', Convert('').strip()) + + def testConvertsPlainCodeToSame(self): + self.assertEquals('#include <stdio.h>\n', + Convert('#include <stdio.h>\n')) + + def testConvertsLongIWYUPragmaToSame(self): + long_line = '// IWYU pragma: private, include "' + (80*'a') + '.h"\n' + self.assertEquals(long_line, Convert(long_line)) + + def testConvertsIWYUPragmaWithLeadingSpaceToSame(self): + long_line = ' // IWYU pragma: private, include "' + (80*'a') + '.h"\n' + self.assertEquals(long_line, Convert(long_line)) + + def testConvertsIWYUPragmaWithSlashStarLeaderToSame(self): + long_line = '/* IWYU pragma: private, include "' + (80*'a') + '.h"\n' + self.assertEquals(long_line, Convert(long_line)) + + def testConvertsIWYUPragmaWithSlashStarAndSpacesToSame(self): + long_line = ' /* IWYU pragma: private, include "' + (80*'a') + '.h"\n' + self.assertEquals(long_line, Convert(long_line)) + + def testIgnoresMetaComment(self): + self.assertEquals('', + Convert('$$ This is a Pump meta comment.\n').strip()) + + def testSimpleVarDeclarationWorks(self): + self.assertEquals('3\n', + Convert('$var m = 3\n' + '$m\n')) + + def testVarDeclarationCanReferenceEarlierVar(self): + self.assertEquals('43 != 3;\n', + Convert('$var a = 42\n' + '$var b = a + 1\n' + '$var c = (b - a)*3\n' + '$b != $c;\n')) + + def testSimpleLoopWorks(self): + self.assertEquals('1, 2, 3, 4, 5\n', + Convert('$var n = 5\n' + '$range i 1..n\n' + '$for i, [[$i]]\n')) + + def testSimpleLoopWithCommentWorks(self): + self.assertEquals('1, 2, 3, 4, 5\n', + Convert('$var n = 5 $$ This is comment 1.\n' + '$range i 1..n $$ This is comment 2.\n' + '$for i, [[$i]]\n')) + + def testNonTrivialRangeExpressionsWork(self): + self.assertEquals('1, 2, 3, 4\n', + Convert('$var n = 5\n' + '$range i (n/n)..(n - 1)\n' + '$for i, [[$i]]\n')) + + def testLoopWithoutSeparatorWorks(self): + self.assertEquals('a + 1 + 2 + 3;\n', + Convert('$range i 1..3\n' + 'a$for i [[ + $i]];\n')) + + def testCanGenerateDollarSign(self): + self.assertEquals('$\n', Convert('$($)\n')) + + def testCanIterpolateExpressions(self): + self.assertEquals('a[2] = 3;\n', + Convert('$var i = 1\n' + 'a[$(i + 1)] = $(i*4 - 1);\n')) + + def testConditionalWithoutElseBranchWorks(self): + self.assertEquals('true\n', + Convert('$var n = 5\n' + '$if n > 0 [[true]]\n')) + + def testConditionalWithElseBranchWorks(self): + self.assertEquals('true -- really false\n', + Convert('$var n = 5\n' + '$if n > 0 [[true]]\n' + '$else [[false]] -- \n' + '$if n > 10 [[really true]]\n' + '$else [[really false]]\n')) + + def testConditionalWithCascadingElseBranchWorks(self): + self.assertEquals('a\n', + Convert('$var n = 5\n' + '$if n > 0 [[a]]\n' + '$elif n > 10 [[b]]\n' + '$else [[c]]\n')) + self.assertEquals('b\n', + Convert('$var n = 5\n' + '$if n > 10 [[a]]\n' + '$elif n > 0 [[b]]\n' + '$else [[c]]\n')) + self.assertEquals('c\n', + Convert('$var n = 5\n' + '$if n > 10 [[a]]\n' + '$elif n > 8 [[b]]\n' + '$else [[c]]\n')) + + def testNestedLexicalBlocksWork(self): + self.assertEquals('a = 5;\n', + Convert('$var n = 5\n' + 'a = [[$if n > 0 [[$n]]]];\n')) + + +class StripMetaCommentsTest(googletest.TestCase): + + def testReturnsSameStringIfItContainsNoComment(self): + self.assertEquals('', StripMetaComments('')) + self.assertEquals(' blah ', StripMetaComments(' blah ')) + self.assertEquals('A single $ is fine.', + StripMetaComments('A single $ is fine.')) + self.assertEquals('multiple\nlines', + StripMetaComments('multiple\nlines')) + + def testStripsSimpleComment(self): + self.assertEquals('yes\n', StripMetaComments('yes $$ or no?\n')) + + def testStripsSimpleCommentWithMissingNewline(self): + self.assertEquals('yes', StripMetaComments('yes $$ or no?')) + + def testStripsPureCommentLinesEntirely(self): + self.assertEquals('yes\n', + StripMetaComments('$$ a pure comment line.\n' + 'yes $$ or no?\n' + ' $$ another comment line.\n')) + + def testStripsCommentsFromMultiLineText(self): + self.assertEquals('multi-\n' + 'line\n' + 'text is fine.', + StripMetaComments('multi- $$ comment 1\n' + 'line\n' + 'text is fine. $$ comment 2')) + + +if __name__ == '__main__': + googletest.main() |